From 3076d01cb2baba0dc1a4e6c84e3c35d3f05897a1 Mon Sep 17 00:00:00 2001 From: "royqh1979@gmail.com" Date: Mon, 24 May 2021 18:11:07 +0800 Subject: [PATCH] * work save --- RedPandaIDE/editor.cpp | 23 +---- RedPandaIDE/qsynedit/MiscClasses.cpp | 7 +- RedPandaIDE/qsynedit/SynEdit.cpp | 93 ++++++++++------- RedPandaIDE/qsynedit/SynEdit.h | 4 +- RedPandaIDE/qsynedit/TextPainter.cpp | 146 ++++++++++++++------------- 5 files changed, 145 insertions(+), 128 deletions(-) diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 47ef2ae7..1dba7969 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -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) { diff --git a/RedPandaIDE/qsynedit/MiscClasses.cpp b/RedPandaIDE/qsynedit/MiscClasses.cpp index 2a8947b7..69c69510 100644 --- a/RedPandaIDE/qsynedit/MiscClasses.cpp +++ b/RedPandaIDE/qsynedit/MiscClasses.cpp @@ -1,15 +1,17 @@ #include "MiscClasses.h" #include "algorithm" +#include 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"< +#include 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(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 && igetString(aLine - 1); int l = s.length(); int x = 0; - for (int i=0;ifromLine>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:"< 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"<timerId(); if (event->timerId() == m_blinkTimerId) { - m_bliknStatus = 1- m_bliknStatus; - invalidateRect(QRect(0,0,1,1)); + qDebug()<<"blink"<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); } } diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index acd75287..cec7e895 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -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 diff --git a/RedPandaIDE/qsynedit/TextPainter.cpp b/RedPandaIDE/qsynedit/TextPainter.cpp index c8192bcc..2f000894 100644 --- a/RedPandaIDE/qsynedit/TextPainter.cpp +++ b/RedPandaIDE/qsynedit/TextPainter.cpp @@ -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:"<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;idrawText(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); } @@ -894,13 +902,13 @@ void SynEditTextPainter::PaintLines() nTokenColumnLen, vLine, PSynHighlighterAttribute()); } } - // Draw LineBreak glyph. - if (edit->mShowSpecChar && (!bLineSelected) && + // Draw LineBreak glyph. + if (edit->mOptions.testFlag(eoShowSpecialChars) && (!bLineSelected) && (!bSpecialLine) && (edit->mLines->lineColumns(vLine-1) < vLastChar)) { - AddHighlightToken(SynLineBreakGlyph, - edit->mLines->lineColumns(vLine-1) - (vFirstChar - FirstCol), - edit->charColumns(SynLineBreakGlyph),vLine, edit->mHighlighter->whitespaceAttribute()); - } + AddHighlightToken(SynLineBreakGlyph, + edit->mLines->lineColumns(vLine-1) - (vFirstChar - FirstCol), + edit->charColumns(SynLineBreakGlyph),vLine, edit->mHighlighter->whitespaceAttribute()); + } } // Paint folding