* work save

This commit is contained in:
royqh1979@gmail.com 2021-05-24 18:11:07 +08:00
parent aee8794305
commit 3076d01cb2
5 changed files with 145 additions and 128 deletions

View File

@ -81,26 +81,9 @@ void Editor::loadFile() {
// QString(tr("Can't Open File %1:%2")).arg(mFilename).arg(file.errorString()));
// }
this->lines()->LoadFromFile(file,mEncodingOption,mFileEncoding);
// QByteArray content=file.readAll();
// file.close();
// if (mEncodingOption == ENCODING_AUTO_DETECT) {
// mFileEncoding = GuessTextEncoding(content);
// } else {
// mFileEncoding = mEncodingOption;
// }
// if (mFileEncoding == ENCODING_UTF8) {
// this->lines()->load
// this->setText(QString::fromUtf8(content));
// } else if (mFileEncoding == ENCODING_UTF8_BOM) {
// this->setText(QString::fromUtf8(content.mid(3)));
// } else if (mFileEncoding == ENCODING_ASCII) {
// this->setText(QString::fromLatin1(content));
// } else if (mFileEncoding == ENCODING_SYSTEM_DEFAULT) {
// this->setText(QString::fromLocal8Bit(content));
// }else {
// QTextCodec*codec = QTextCodec::codecForName(mFileEncoding);
// this->setText(codec->toUnicode(content));
// }
this->setModified(false);
updateCaption();
pMainWindow->updateStatusBarForEncoding();
}
void Editor::saveFile(const QString &filename) {

View File

@ -1,15 +1,17 @@
#include "MiscClasses.h"
#include "algorithm"
#include <QDebug>
SynGutter::SynGutter(QObject *parent):
QObject(parent)
{
mFont = QFont("Courier New",9);
mFont = QFont("Courier New",10);
mColor= QColorConstants::Svg::lightgray;
mBorderColor = QColorConstants::Transparent;
mTextColor = QColorConstants::Svg::black;
mWidth = 30;
mShowLineNumbers = true;
mDigitCount = 4;
mDigitCount = 1;
mLeadingZeros = false;
mLeftOffset = 16;
mRightOffset = 2;
@ -299,6 +301,7 @@ QColor SynGutter::color() const
void SynGutter::setColor(const QColor &value)
{
if (mColor!=value) {
qDebug()<<"mColor"<<value;
mColor = value;
setChanged();
}

View File

@ -11,6 +11,7 @@
#include "Constants.h"
#include "TextPainter.h"
#include <QDebug>
#include <QPaintEvent>
SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent)
{
@ -33,12 +34,13 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent)
qDebug()<<"init SynEdit: 2";
#ifdef Q_OS_WIN
mFontDummy = QFont("Consolas",10);
mFontDummy = QFont("Consolas",12);
#elif Q_OS_LINUX
mFontDummy = QFont("terminal",14);
#else
#error "Not supported!"
#endif
mFontDummy.setStyleStrategy(QFont::PreferAntialias);
setFont(mFontDummy);
qDebug()<<"init SynEdit:3";
@ -51,9 +53,10 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent)
qDebug()<<"init SynEdit: 4";
//DoubleBuffered = false;
mActiveLineColor = QColor();
mSelectedBackground = QColor();
mSelectedForeground = QColor();
mCaretColor = QColorConstants::Red;
mActiveLineColor = QColorConstants::Svg::lightblue;
mSelectedBackground = QColorConstants::Svg::lightgray;
mSelectedForeground = palette().color(QPalette::Text);
mBookMarkOpt.connect(&mBookMarkOpt, &SynBookMarkOpt::changed, this, &SynEdit::bookMarkOptionsChanged);
// fRightEdge has to be set before FontChanged is called for the first time
@ -125,12 +128,13 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent)
mContentImage = std::make_shared<QImage>(clientWidth(),clientHeight(),QImage::Format_ARGB32);
m_blinkTimerId = 0;
m_bliknStatus = 0;
m_blinkStatus = 0;
qDebug()<<"init SynEdit: 10";
synFontChanged();
qDebug()<<"init SynEdit: done";
showCaret();
}
int SynEdit::displayLineCount()
@ -398,13 +402,16 @@ BufferCoord SynEdit::displayToBufferPos(const DisplayCoord &p)
int x = 0;
int i = 0;
while (x < p.Column) {
while (x < p.Column && i<s.length()) {
if (i < l && s[i] == '\t')
x += mTabWidth - (x % mTabWidth);
else
x += charColumns(s[i]);
i++;
}
if (i==0) {
i=1;
}
Result.Char = i;
}
return Result;
@ -416,7 +423,8 @@ int SynEdit::charToColumn(int aLine, int aChar)
QString s = mLines->getString(aLine - 1);
int l = s.length();
int x = 0;
for (int i=0;i<aChar-1;i++) {
int len = std::min(aChar - 1,s.length());
for (int i=0;i<len;i++) {
if (i<=l && s[i] == '\t')
x+=mTabWidth - (x % mTabWidth);
else
@ -464,7 +472,11 @@ int SynEdit::getLineIndent(const QString &line)
int SynEdit::rowToLine(int aRow)
{
return displayToBufferPos({1, aRow}).Line;
if (mUseCodeFolding)
return foldRowToLine(aRow);
else
return aRow;
//return displayToBufferPos({1, aRow}).Line;
}
int SynEdit::lineToRow(int aLine)
@ -644,7 +656,8 @@ int SynEdit::charColumns(QChar ch)
{
if (ch == ' ')
return 1;
return std::ceil((int)(fontMetrics().horizontalAdvance(ch) * dpiFactor()) / (double)mCharWidth);
//return std::ceil((int)(fontMetrics().horizontalAdvance(ch) * dpiFactor()) / (double)mCharWidth);
return std::ceil((int)(fontMetrics().horizontalAdvance(ch)) / (double)mCharWidth);
}
double SynEdit::dpiFactor()
@ -654,7 +667,8 @@ double SynEdit::dpiFactor()
void SynEdit::showCaret()
{
m_blinkTimerId = startTimer(100);
if (m_blinkTimerId==0)
m_blinkTimerId = startTimer(500);
}
void SynEdit::hideCaret()
@ -1067,8 +1081,8 @@ void SynEdit::recalcCharExtent()
mCharWidth = fm.horizontalAdvance("M");
}
mTextHeight += mExtraLineSpacing;
mCharWidth = mCharWidth * dpiFactor();
mTextHeight = mTextHeight * dpiFactor();
//mCharWidth = mCharWidth * dpiFactor();
//mTextHeight = mTextHeight * dpiFactor();
}
QString SynEdit::expandAtWideGlyphs(const QString &S)
@ -1355,7 +1369,7 @@ void SynEdit::doOnPaintTransientEx(SynTransientType TransientType, bool Lock)
void SynEdit::initializeCaret()
{
//todo:
//showCaret();
}
PSynEditFoldRange SynEdit::foldStartAtLine(int Line)
@ -1367,6 +1381,7 @@ PSynEditFoldRange SynEdit::foldStartAtLine(int Line)
} else if (range->fromLine>Line)
break; // sorted by line. don't bother scanning further
}
return PSynEditFoldRange();
}
QString SynEdit::substringByColumns(const QString &s, int startColumn, int &colLen)
@ -1461,8 +1476,9 @@ PSynEditFoldRange SynEdit::foldEndAtLine(int Line)
void SynEdit::paintCaret(QPainter &painter, const QRect rcClip)
{
if (m_bliknStatus!=1)
if (m_blinkStatus!=1)
return;
painter.setClipRect(rcClip);
SynEditCaretType ct;
if (this->mInserting) {
ct = mInsertCaret;
@ -1484,7 +1500,8 @@ void SynEdit::paintCaret(QPainter &painter, const QRect rcClip)
case SynEditCaretType::ctHalfBlock:
QRect rc=rcClip;
rc.setTop(rcClip.top()+rcClip.height() / 2);
painter.drawRect(rcClip);
break;
}
}
@ -1567,7 +1584,7 @@ void SynEdit::paintEvent(QPaintEvent *event)
// Now paint everything while the caret is hidden.
QPainter painter(viewport());
hideCaret();
//hideCaret();
//Get the invalidated rect.
QRect rcClip = event->rect();
DisplayCoord coord = displayXY();
@ -1584,15 +1601,14 @@ void SynEdit::paintEvent(QPaintEvent *event)
qDebug()<<"Clip rect:"<<rcClip;
auto action = finally([&,this] {
//updateCaret();
paintCaret(painter, rcCaret);
mPainting = false;
});
if (rcClip.width()==1 && rcClip.height()==1) {
if (rcCaret == rcClip) {
// only update caret
// calculate the needed invalid area for caret
painter.drawImage(rcCaret,*mContentImage);
//painter.drawImage(rcCaret,*mContentImage);
painter.drawImage(rcCaret,*mContentImage,rcCaret);
} else {
QRect rcDraw;
int nL1, nL2, nC1, nC2;
@ -1607,36 +1623,33 @@ void SynEdit::paintEvent(QPaintEvent *event)
nL1 = MinMax(mTopLine + rcClip.top() / mTextHeight, mTopLine, displayLineCount());
nL2 = MinMax(mTopLine + (rcClip.bottom() + mTextHeight - 1) / mTextHeight, 1, displayLineCount());
// QPainter cachePainter(mContentImage.get());
// SynEditTextPainter textPainter(this, &cachePainter,
// nL1,nL2,nC1,nC2);
SynEditTextPainter textPainter(this, &painter,
QPainter cachePainter(mContentImage.get());
cachePainter.setFont(font());
SynEditTextPainter textPainter(this, &cachePainter,
nL1,nL2,nC1,nC2);
// SynEditTextPainter textPainter(this, &painter,
// nL1,nL2,nC1,nC2);
// First paint paint the text area if it was (partly) invalidated.
if (rcClip.right() > mGutterWidth ) {
rcDraw = rcClip;
rcDraw.setLeft( std::max(rcDraw.left(), mGutterWidth));
textPainter.paintTextLines(rcDraw);
//paintTextLines(rcDraw, nL1, nL2, nC1, nC2);
}
// Then the gutter area if it was (partly) invalidated.
if (rcClip.left() < mGutterWidth) {
rcDraw = rcClip;
rcDraw.setRight(mGutterWidth);
//textPainter.paintGutter(rcDraw);
//paintGutter(rcDraw, nL1, nL2);
rcDraw.setRight(mGutterWidth+1);
textPainter.paintGutter(rcDraw);
}
//PluginsAfterPaint(Canvas, rcClip, nL1, nL2);
// If there is a custom paint handler call it.
//onPaint(cachePainter);
onPaint(painter);
doOnPaintTransient(SynTransientType::ttAfter);
painter.drawImage(rcClip,*mContentImage);
painter.drawImage(rcClip,*mContentImage,rcClip);
}
paintCaret(painter, rcCaret);
}
void SynEdit::resizeEvent(QResizeEvent *event)
@ -1658,9 +1671,19 @@ void SynEdit::resizeEvent(QResizeEvent *event)
void SynEdit::timerEvent(QTimerEvent *event)
{
qDebug()<<"timer"<<event->timerId();
if (event->timerId() == m_blinkTimerId) {
m_bliknStatus = 1- m_bliknStatus;
invalidateRect(QRect(0,0,1,1));
qDebug()<<"blink"<<m_blinkStatus;
m_blinkStatus = 1- m_blinkStatus;
DisplayCoord coord = displayXY();
QPoint caretPos = RowColumnToPixels(coord);
int caretWidth=mCharWidth;
if (mCaretY <= mLines->count() && mCaretX <= mLines->getString(mCaretY-1).length()) {
caretWidth = charColumns(mLines->getString(mCaretY-1)[mCaretX-1])*mCharWidth;
}
QRect rcCaret(caretPos.x(),caretPos.y(),caretWidth,
mTextHeight);
invalidateRect(rcCaret);
}
}

View File

@ -374,6 +374,7 @@ private:
PSynHighlighter mHighlighter;
QColor mSelectedForeground;
QColor mSelectedBackground;
QColor mCaretColor;
QColor mActiveLineColor;
PSynEditUndoList mUndoList;
PSynEditUndoList mRedoList;
@ -414,7 +415,6 @@ private:
PSynEdit fChainedEditor;
bool mShowSpecChar;
int mPaintTransientLock;
bool mIsScrolling;
int mPainterLock; // lock counter to prevent repaint while painting
@ -438,7 +438,7 @@ private:
//caret blink related
int m_blinkTimerId;
int m_bliknStatus;
int m_blinkStatus;
// QWidget interface

View File

@ -93,8 +93,9 @@ void SynEditTextPainter::paintGutter(const QRect& clip)
// If we have to draw the line numbers then we don't want to erase
// the background first. Do it line by line with TextRect instead
// and fill only the area after the last visible line.
painter->setClipRect(AClip);
painter->setBrush(edit->mGutter.color());
painter->setPen(Qt::NoPen);
painter->setPen(edit->mGutter.color());
rcLine=AClip;
painter->drawRect(AClip);
@ -132,78 +133,78 @@ void SynEditTextPainter::paintGutter(const QRect& clip)
textRect = painter->boundingRect(textRect, Qt::AlignLeft,s);
painter->drawText(
(edit->mGutterWidth - edit->mGutter.rightOffset() - 2) - textRect.width(),
rcLine.top() + ((edit->mTextHeight - int(textRect.height())) / 2),
rcLine.bottom() + ((edit->mTextHeight - int(textRect.height())) / 2 - painter->fontMetrics().descent()),
s
);
}
}
// Draw the folding lines and squares
if (edit->mUseCodeFolding) {
for (cRow = aFirstRow; cRow<=aLastRow; cRow++) {
vLine = edit->rowToLine(cRow);
if ((vLine > edit->mLines->count()) && (edit->mLines->count() != 0))
break;
// if (edit->mUseCodeFolding) {
// for (cRow = aFirstRow; cRow<=aLastRow; cRow++) {
// vLine = edit->rowToLine(cRow);
// if ((vLine > edit->mLines->count()) && (edit->mLines->count() != 0))
// break;
// Form a rectangle for the square the user can click on
//rcFold.Left := Gutter.RealGutterWidth(CharWidth) - Gutter.RightOffset;
rcFold.setLeft(edit->mGutterWidth - edit->mGutter.rightOffset());
rcFold.setRight(rcFold.left() + edit->mGutter.rightOffset() - 4);
rcFold.setTop((cRow - edit->mTopLine) * edit->mTextHeight);
rcFold.setBottom(rcFold.top() + edit->mTextHeight);
// // Form a rectangle for the square the user can click on
// //rcFold.Left := Gutter.RealGutterWidth(CharWidth) - Gutter.RightOffset;
// rcFold.setLeft(edit->mGutterWidth - edit->mGutter.rightOffset());
// rcFold.setRight(rcFold.left() + edit->mGutter.rightOffset() - 4);
// rcFold.setTop((cRow - edit->mTopLine) * edit->mTextHeight);
// rcFold.setBottom(rcFold.top() + edit->mTextHeight);
painter->setPen(edit->mCodeFolding.folderBarLinesColor);
// painter->setPen(edit->mCodeFolding.folderBarLinesColor);
// Need to paint a line?
if (edit->foldAroundLine(vLine)) {
x = rcFold.left() + (rcFold.width() / 2);
painter->drawLine(x,rcFold.top(), x, rcFold.bottom());
}
// // Need to paint a line?
// if (edit->foldAroundLine(vLine)) {
// x = rcFold.left() + (rcFold.width() / 2);
// painter->drawLine(x,rcFold.top(), x, rcFold.bottom());
// }
// Need to paint a line end?
if (edit->foldEndAtLine(vLine)) {
x = rcFold.left() + (rcFold.width() / 2);
painter->drawLine(x,rcFold.top(), x, rcFold.top() + rcFold.height() / 2);
painter->drawLine(x,
rcFold.top() + rcFold.height() / 2,
rcFold.right() - 2 ,
rcFold.top() + rcFold.height() / 2);
}
// Any fold ranges beginning on this line?
PSynEditFoldRange FoldRange = edit->foldStartAtLine(vLine);
if (FoldRange) {
// Draw the bottom part of a line
if (!FoldRange->collapsed) {
x = rcFold.left() + (rcFold.width() / 2);
painter->drawLine(x, rcFold.top() + rcFold.height() / 2,
x, rcFold.bottom());
}
// // Need to paint a line end?
// if (edit->foldEndAtLine(vLine)) {
// x = rcFold.left() + (rcFold.width() / 2);
// painter->drawLine(x,rcFold.top(), x, rcFold.top() + rcFold.height() / 2);
// painter->drawLine(x,
// rcFold.top() + rcFold.height() / 2,
// rcFold.right() - 2 ,
// rcFold.top() + rcFold.height() / 2);
// }
// // Any fold ranges beginning on this line?
// PSynEditFoldRange FoldRange = edit->foldStartAtLine(vLine);
// if (FoldRange) {
// // Draw the bottom part of a line
// if (!FoldRange->collapsed) {
// x = rcFold.left() + (rcFold.width() / 2);
// painter->drawLine(x, rcFold.top() + rcFold.height() / 2,
// x, rcFold.bottom());
// }
// make a square rect
inflateRect(rcFold,-2, 0);
rcFold.setTop(
rcFold.top() + ((edit->mTextHeight - rcFold.width()) / 2));
rcFold.setBottom(rcFold.top() + rcFold.width());
// // make a square rect
// inflateRect(rcFold,-2, 0);
// rcFold.setTop(
// rcFold.top() + ((edit->mTextHeight - rcFold.width()) / 2));
// rcFold.setBottom(rcFold.top() + rcFold.width());
// Paint the square the user can click on
painter->setBrush(edit->mGutter.color());
painter->setPen(edit->mCodeFolding.folderBarLinesColor);
painter->drawRect(rcFold);
// // Paint the square the user can click on
// painter->setBrush(edit->mGutter.color());
// painter->setPen(edit->mCodeFolding.folderBarLinesColor);
// painter->drawRect(rcFold);
// Paint minus sign
painter->drawLine(
rcFold.left() + 2, rcFold.top() + (rcFold.height() / 2 ),
rcFold.right() - 2, rcFold.top() + (rcFold.height() / 2 ));
// Paint vertical line of plus sign
if (FoldRange->collapsed) {
x = rcFold.left() + (rcFold.width() / 2);
painter->drawLine(x, rcFold.top() + 2,
x, rcFold.bottom() + 2);
}
}
}
}
// // Paint minus sign
// painter->drawLine(
// rcFold.left() + 2, rcFold.top() + (rcFold.height() / 2 ),
// rcFold.right() - 2, rcFold.top() + (rcFold.height() / 2 ));
// // Paint vertical line of plus sign
// if (FoldRange->collapsed) {
// x = rcFold.left() + (rcFold.width() / 2);
// painter->drawLine(x, rcFold.top() + 2,
// x, rcFold.bottom() + 2);
// }
// }
// }
// }
// // the gutter separator if visible
// if (edit->mGutter.borderStyle <> gbsNone) and (AClip.Right >= fGutterWidth - 2) then
@ -358,9 +359,14 @@ void SynEditTextPainter::PaintToken(const QString &Token, int TokenCols, int Col
if (First > TokenCols) {
} else {
qDebug()<<"token clip rect:"<<rcToken << Token;
painter->setClipRect(rcToken);
// painter->setClipRect(rcToken);
int tokenColLen=0;
startPaint = false;
QPen oldPen = painter->pen();
QPen newPen(painter->brush().color());
painter->setPen(newPen);
painter->drawRect(rcToken);
painter->setPen(oldPen);
for (int i=0;i<Token.length();i++) {
int charCols;
if (Token[i] == SynTabChar) {
@ -374,7 +380,8 @@ void SynEditTextPainter::PaintToken(const QString &Token, int TokenCols, int Col
}
startPaint = true;
}
painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent()*edit->dpiFactor() , Token[i]);
//painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent()*edit->dpiFactor() , Token[i]);
painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent() , Token[i]);
tokenColLen += charCols;
nX += charCols * edit->mCharWidth;
@ -604,7 +611,7 @@ void SynEditTextPainter::AddHighlightToken(const QString &Token, int ColumnsBefo
// background color must be the same and
((TokenAccu.BG == Background) &&
// foreground color must be the same or token is only spaces
((TokenAccu.FG == Foreground) || (TokenIsSpaces(bSpacesTest,Token,bIsSpaces) && !edit->mShowSpecChar)))) {
((TokenAccu.FG == Foreground) || (TokenIsSpaces(bSpacesTest,Token,bIsSpaces) && !edit->mOptions.testFlag(eoShowSpecialChars))))) {
bCanAppend = true;
}
}
@ -740,6 +747,7 @@ void SynEditTextPainter::PaintLines()
colFG = edit->palette().color(QPalette::Text);
colBG = colEditorBG();
bSpecialLine = edit->onGetSpecialLineColors(vLine, colFG, colBG);
if (bSpecialLine) {
// The selection colors are just swapped, like seen in Delphi.
colSelFG = colBG;
@ -796,7 +804,7 @@ void SynEditTextPainter::PaintLines()
if (!edit->mHighlighter || !edit->mHighlighter->enabled()) {
sToken = sLine;
nTokenColumnLen = edit->mLines->lineColumns(vLine-1);
if (edit->mShowSpecChar && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) {
if (edit->mOptions.testFlag(eoShowSpecialChars) && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) {
sToken = sToken + SynLineBreakGlyph;
nTokenColumnLen += edit->charColumns(SynLineBreakGlyph);
}
@ -895,7 +903,7 @@ void SynEditTextPainter::PaintLines()
}
}
// Draw LineBreak glyph.
if (edit->mShowSpecChar && (!bLineSelected) &&
if (edit->mOptions.testFlag(eoShowSpecialChars) && (!bLineSelected) &&
(!bSpecialLine) && (edit->mLines->lineColumns(vLine-1) < vLastChar)) {
AddHighlightToken(SynLineBreakGlyph,
edit->mLines->lineColumns(vLine-1) - (vFirstChar - FirstCol),