diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 387031b5..ed052226 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -3469,7 +3469,7 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple pSettings->codeCompletion().height()); // Position it at the top of the next line - QPoint popupPos = mapToGlobal(rowColumnToPixels(displayXY())); + QPoint popupPos = mapToGlobal(displayCoordToPixels(displayXY())); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) QSize desktopSize = screen()->virtualSize(); if (desktopSize.height() - popupPos.y() < mCompletionPopup->height() && popupPos.y() > mCompletionPopup->height()) @@ -3599,7 +3599,7 @@ void Editor::showHeaderCompletion(bool autoComplete, bool forceShow) return; // Position it at the top of the next line - QPoint p = rowColumnToPixels(displayXY()); + QPoint p = displayCoordToPixels(displayXY()); p.setY(p.y() + textHeight() + 2); mHeaderCompletionPopup->move(mapToGlobal(p)); @@ -4372,7 +4372,7 @@ void Editor::updateFunctionTip(bool showTip) return; } // Position it at the top of the next line - QPoint p = rowColumnToPixels(displayXY()); + QPoint p = displayCoordToPixels(displayXY()); p+=QPoint(0,textHeight()+2); pMainWindow->functionTip()->move(mapToGlobal(p)); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index a584bcf7..3a40dc56 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1434,18 +1434,17 @@ QMenuBar *MainWindow::menuBar() const void MainWindow::updateStatusbarForLineCol(const Editor* e, bool clear) { if (!clear && e!=nullptr) { - int col = e->charToColumn(e->caretY(),e->caretX()); QString msg; if (e->selAvail()) { - msg = tr("Line: %1 Col: %2 Sel:%3 Lines: %4") + msg = tr("Line: %1 Char: %2 Sel:%3 Lines: %4") .arg(e->caretY()) - .arg(col) + .arg(e->caretX()) .arg(e->selText().length()) .arg(e->document()->count()); } else { - msg = tr("Line: %1 Col: %2 Lines: %3") + msg = tr("Line: %1 Char: %2 Lines: %3") .arg(e->caretY()) - .arg(col) + .arg(e->caretX()) .arg(e->document()->count()); } mFileInfoStatus->setText(msg); @@ -3233,7 +3232,7 @@ bool MainWindow::saveLastOpens() fileObj["caretX"] = editor->caretX(); fileObj["caretY"] = editor->caretY(); fileObj["topLine"] = editor->topLine(); - fileObj["leftChar"] = editor->leftChar(); + fileObj["left"] = editor->leftPos(); filesArray.append(fileObj); } rootObj["files"]=filesArray; @@ -3337,8 +3336,8 @@ void MainWindow::loadLastOpens() editor->setTopLine( fileObj["topLine"].toInt(1) ); - editor->setLeftChar( - fileObj["leftChar"].toInt(1) + editor->setLeftPos( + fileObj["left"].toInt(1) ); if (fileObj["focused"].toBool(false)) focusedEditor = editor; diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index bfbf4375..94558032 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -426,7 +426,7 @@ Editor *Project::openUnit(PProjectUnit &unit, const PProjectEditorLayout &layout editor->setCaretY(layout->caretY); editor->setCaretX(layout->caretX); editor->setTopLine(layout->topLine); - editor->setLeftChar(layout->leftChar); + editor->setLeftPos(layout->left); editor->activate(); return editor; } @@ -663,7 +663,7 @@ void Project::saveLayout() jsonLayout["caretX"]=editor->caretX(); jsonLayout["caretY"]=editor->caretY(); jsonLayout["topLine"]=editor->topLine(); - jsonLayout["leftChar"]=editor->leftChar(); + jsonLayout["left"]=editor->leftPos(); jsonLayout["isOpen"]=true; jsonLayout["focused"]=(editor==e); int order=editorOrderSet.value(editor->filename(),-1); @@ -679,7 +679,7 @@ void Project::saveLayout() jsonLayout["caretX"]=oldLayout->caretX; jsonLayout["caretY"]=oldLayout->caretY; jsonLayout["topLine"]=oldLayout->topLine; - jsonLayout["leftChar"]=oldLayout->leftChar; + jsonLayout["left"]=oldLayout->left; jsonLayout["isOpen"]=false; jsonLayout["focused"]=false; jsonLayouts.append(jsonLayout); @@ -1953,7 +1953,7 @@ QHash Project::loadLayout() PProjectEditorLayout editorLayout = std::make_shared(); editorLayout->filename=unitFilename; editorLayout->topLine=jsonLayout["topLine"].toInt(); - editorLayout->leftChar=jsonLayout["leftChar"].toInt(); + editorLayout->left=jsonLayout["left"].toInt(); editorLayout->caretX=jsonLayout["caretX"].toInt(); editorLayout->caretY=jsonLayout["caretY"].toInt(); editorLayout->order=jsonLayout["order"].toInt(-1); @@ -2183,7 +2183,7 @@ void Project::loadUnitLayout(Editor *e) e->setCaretY(layout->caretY); e->setCaretX(layout->caretX); e->setTopLine(layout->topLine); - e->setLeftChar(layout->leftChar); + e->setLeftPos(layout->left); } } diff --git a/RedPandaIDE/project.h b/RedPandaIDE/project.h index 75270a47..049dc2d8 100644 --- a/RedPandaIDE/project.h +++ b/RedPandaIDE/project.h @@ -62,7 +62,7 @@ struct ProjectModelNode { struct ProjectEditorLayout { QString filename; int topLine; - int leftChar; + int left; int caretX; int caretY; int order; diff --git a/RedPandaIDE/widgets/searchinfiledialog.cpp b/RedPandaIDE/widgets/searchinfiledialog.cpp index 6e913360..abd5ae65 100644 --- a/RedPandaIDE/widgets/searchinfiledialog.cpp +++ b/RedPandaIDE/widgets/searchinfiledialog.cpp @@ -371,7 +371,7 @@ std::shared_ptr SearchInFileDialog::batchFindInEditor(QSyn QSynedit::BufferCoord blockBeginBackup = e->blockBegin(); QSynedit::BufferCoord blockEndBackup = e->blockEnd(); int toplineBackup = e->topLine(); - int leftCharBackup = e->leftChar(); + int leftPosBackup = e->leftPos(); PSearchResultTreeItem parentItem = std::make_shared(); parentItem->filename = filename; @@ -394,7 +394,7 @@ std::shared_ptr SearchInFileDialog::batchFindInEditor(QSyn // restore e->setCaretXY(caretBackup); e->setTopLine(toplineBackup); - e->setLeftChar(leftCharBackup); + e->setLeftPos(leftPosBackup); e->setCaretAndSelection( caretBackup, blockBeginBackup, diff --git a/libs/qsynedit/qsynedit/document.cpp b/libs/qsynedit/qsynedit/document.cpp index 205345e3..9c539b51 100644 --- a/libs/qsynedit/qsynedit/document.cpp +++ b/libs/qsynedit/qsynedit/document.cpp @@ -1186,7 +1186,7 @@ int DocumentLine::glyphWidth(int i) const } else { end = mWidth+1; } - return start - end; + return end-start; } void DocumentLine::setLineText(const QString &newLineText) diff --git a/libs/qsynedit/qsynedit/painter.cpp b/libs/qsynedit/qsynedit/painter.cpp index 32bc8c5a..48c51506 100644 --- a/libs/qsynedit/qsynedit/painter.cpp +++ b/libs/qsynedit/qsynedit/painter.cpp @@ -22,7 +22,7 @@ namespace QSynedit { -QSet QSynEditPainter::operatorGlyphs { +QSet QSynEditPainter::OperatorGlyphs { "-", "+", "*", @@ -41,63 +41,43 @@ QSet QSynEditPainter::operatorGlyphs { "<", ">", "?", - ":",}; + ":", +}; -QSynEditPainter::QSynEditPainter(QSynEdit *edit, QPainter *painter, int FirstRow, int LastRow, int FirstCol, int LastCol) +QSynEditPainter::QSynEditPainter(QSynEdit *edit, QPainter *painter, int firstRow, int lastRow, int left, int right): + mEdit{edit}, + mPainter{painter}, + mFirstRow{firstRow}, + mLastRow{lastRow}, + mLeft{left}, + mRight{right} { - this->edit = edit; - this->painter = painter; - this->aFirstRow = FirstRow; - this->aLastRow = LastRow; - this->FirstCol = FirstCol; - this->LastCol = LastCol; - // if (operatorGlyphs.isEmpty()) { - // operatorGlyphs.insert("+"); - // operatorGlyphs.insert("-"); - // operatorGlyphs.insert("*"); - // operatorGlyphs.insert("/"); - // operatorGlyphs.insert("\\"); - // operatorGlyphs.insert("~"); - // operatorGlyphs.insert("!"); - // operatorGlyphs.insert("@"); - // operatorGlyphs.insert("#"); - // operatorGlyphs.insert("$"); - // operatorGlyphs.insert("%"); - // operatorGlyphs.insert("^"); - // operatorGlyphs.insert("&"); - // operatorGlyphs.insert("|"); - // operatorGlyphs.insert("="); - // operatorGlyphs.insert("<"); - // operatorGlyphs.insert(">"); - // operatorGlyphs.insert("?"); - // operatorGlyphs.insert(":"); - // } } void QSynEditPainter::paintTextLines(const QRect& clip) { - painter->fillRect(clip, edit->mBackgroundColor); - AClip = clip; - vFirstLine = edit->rowToLine(aFirstRow); - vLastLine = edit->rowToLine(aLastRow); - bCurrentLine = false; + mPainter->fillRect(clip, mEdit->mBackgroundColor); + mClip = clip; + mFirstLine = mEdit->rowToLine(mFirstRow); + mLastLine = mEdit->rowToLine(mLastRow); + mIsCurrentLine = false; // If the right edge is visible and in the invalid area, prepare to paint it. // Do this first to realize the pen when getting the dc variable. bDoRightEdge = false; - if (edit->mRightEdge > 0) { // column value - nRightEdge = edit->textOffset()+ edit->mRightEdge * edit->mCharWidth; // pixel value - if (nRightEdge >= AClip.left() &&nRightEdge <= AClip.right()) { + if (mEdit->mRightEdge > 0) { // column value + nRightEdge = mEdit->textOffset()+ mEdit->mRightEdge * mEdit->mCharWidth; // pixel value + if (nRightEdge >= mClip.left() &&nRightEdge <= mClip.right()) { bDoRightEdge = true; - QPen pen(edit->mRightEdgeColor,1); - painter->setPen(pen); + QPen pen(mEdit->mRightEdgeColor,1); + mPainter->setPen(pen); } } // Paint the visible text lines. To make this easier, compute first the // necessary information about the selected area: is there any visible // selected area, and what are its lines / columns? - if (vLastLine >= vFirstLine) { + if (mLastLine >= mFirstLine) { computeSelectionInfo(); paintLines(); } @@ -105,26 +85,26 @@ void QSynEditPainter::paintTextLines(const QRect& clip) // If anything of the two pixel space before the text area is visible, then // fill it with the component background color. - if (AClip.left() mGutterWidth + 2) { - rcToken = AClip; - rcToken.setLeft( std::max(AClip.left(), edit->mGutterWidth)); - rcToken.setRight(edit->mGutterWidth + 2); + if (mClip.left() mGutterWidth + 2) { + rcToken = mClip; + rcToken.setLeft( std::max(mClip.left(), mEdit->mGutterWidth)); + rcToken.setRight(mEdit->mGutterWidth + 2); // Paint whole left edge of the text with same color. // (value of WhiteAttribute can vary in e.g. MultiSyn) - painter->fillRect(rcToken,colEditorBG()); + mPainter->fillRect(rcToken,colEditorBG()); // Adjust the invalid area to not include this area. - AClip.setLeft(rcToken.right()); + mClip.setLeft(rcToken.right()); } // If there is anything visible below the last line, then fill this as well. - rcToken = AClip; - rcToken.setTop((aLastRow - edit->mTopLine + 1) * edit->mTextHeight); + rcToken = mClip; + rcToken.setTop((mLastRow - mEdit->mTopLine + 1) * mEdit->mTextHeight); if (rcToken.top() < rcToken.bottom()) { - painter->fillRect(rcToken,colEditorBG()); + mPainter->fillRect(rcToken,colEditorBG()); // Draw the right edge if necessary. if (bDoRightEdge) { - QPen pen(edit->mRightEdgeColor,1); - painter->setPen(pen); - painter->drawLine(nRightEdge, rcToken.top(),nRightEdge, rcToken.bottom() + 1); + QPen pen(mEdit->mRightEdgeColor,1); + mPainter->setPen(pen); + mPainter->drawLine(nRightEdge, rcToken.top(),nRightEdge, rcToken.bottom() + 1); } } @@ -134,158 +114,152 @@ void QSynEditPainter::paintTextLines(const QRect& clip) void QSynEditPainter::paintGutter(const QRect& clip) { - int cRow; QRect rcLine, rcFold; - QString s; - int vLine; - int vLineTop; int x; - AClip = clip; + mClip = clip; - painter->fillRect(AClip,edit->mGutter.color()); + mPainter->fillRect(mClip,mEdit->mGutter.color()); - rcLine=AClip; - if (edit->mGutter.showLineNumbers()) { + rcLine=mClip; + if (mEdit->mGutter.showLineNumbers()) { // prepare the rect initially - rcLine = AClip; - rcLine.setRight( std::max(rcLine.right(), edit->mGutterWidth - 2)); + rcLine = mClip; + rcLine.setRight( std::max(rcLine.right(), mEdit->mGutterWidth - 2)); rcLine.setBottom(rcLine.top()); - if (edit->mGutter.useFontStyle()) { - painter->setFont(edit->mGutter.font()); + if (mEdit->mGutter.useFontStyle()) { + mPainter->setFont(mEdit->mGutter.font()); } else { - QFont newFont = painter->font(); + QFont newFont = mPainter->font(); newFont.setBold(false); newFont.setItalic(false); newFont.setStrikeOut(false); newFont.setUnderline(false); - painter->setFont(newFont); + mPainter->setFont(newFont); } QColor textColor; - if (edit->mGutter.textColor().isValid()) { - textColor = edit->mGutter.textColor(); + if (mEdit->mGutter.textColor().isValid()) { + textColor = mEdit->mGutter.textColor(); } else { - textColor = edit->mForegroundColor; + textColor = mEdit->mForegroundColor; } // draw each line if it is not hidden by a fold - BufferCoord selectionStart = edit->blockBegin(); - BufferCoord selectionEnd = edit->blockEnd(); - for (int cRow = aFirstRow; cRow <= aLastRow; cRow++) { - vLine = edit->rowToLine(cRow); - if ((vLine > edit->mDocument->count()) && (edit->mDocument->count() > 0 )) + BufferCoord selectionStart = mEdit->blockBegin(); + BufferCoord selectionEnd = mEdit->blockEnd(); + for (int row = mFirstRow; row <= mLastRow; row++) { + int line = mEdit->rowToLine(row); + if ((line > mEdit->mDocument->count()) && (mEdit->mDocument->count() > 0 )) break; - if (edit->mGutter.activeLineTextColor().isValid()) { + if (mEdit->mGutter.activeLineTextColor().isValid()) { if ( - (edit->mCaretY==vLine) || - (edit->mActiveSelectionMode == SelectionMode::Column && vLine >= selectionStart.line && vLine <= selectionEnd.line) + (mEdit->mCaretY==line) || + (mEdit->mActiveSelectionMode == SelectionMode::Column && line >= selectionStart.line && line <= selectionEnd.line) ) - painter->setPen(edit->mGutter.activeLineTextColor()); + mPainter->setPen(mEdit->mGutter.activeLineTextColor()); else - painter->setPen(textColor); + mPainter->setPen(textColor); } else { - painter->setPen(textColor); + mPainter->setPen(textColor); } - vLineTop = (cRow - edit->mTopLine) * edit->mTextHeight; + int lineTop = (row - mEdit->mTopLine) * mEdit->mTextHeight; // next line rect - rcLine.setTop(vLineTop); - rcLine.setBottom(rcLine.top() + edit->mTextHeight); + rcLine.setTop(lineTop); + rcLine.setBottom(rcLine.top() + mEdit->mTextHeight); - s = edit->mGutter.formatLineNumber(vLine); + QString s = mEdit->mGutter.formatLineNumber(line); - edit->onGutterGetText(vLine,s); + mEdit->onGutterGetText(line,s); QRectF textRect; - textRect = painter->boundingRect(textRect, Qt::AlignLeft,s); - painter->drawText( - (edit->mGutterWidth - edit->mGutter.rightOffset() - 2) - textRect.width(), - rcLine.bottom() + ((edit->mTextHeight - int(textRect.height())) / 2 - painter->fontMetrics().descent()), + textRect = mPainter->boundingRect(textRect, Qt::AlignLeft,s); + mPainter->drawText( + (mEdit->mGutterWidth - mEdit->mGutter.rightOffset() - 2) - textRect.width(), + rcLine.bottom() + ((mEdit->mTextHeight - int(textRect.height())) / 2 - mPainter->fontMetrics().descent()), s ); } } // Draw the folding lines and squares - if (edit->mUseCodeFolding) { - for (cRow = aLastRow; cRow>=aFirstRow; cRow--) { - vLine = edit->rowToLine(cRow); - if ((vLine > edit->mDocument->count()) && (edit->mDocument->count() != 0)) + if (mEdit->mUseCodeFolding) { + for (int row = mLastRow; row>= mFirstRow; row--) { + int line = mEdit->rowToLine(row); + if ((line > mEdit->mDocument->count()) && (mEdit->mDocument->count() != 0)) continue; // Form a rectangle for the square the user can click on - rcFold.setLeft(edit->mGutterWidth - edit->mGutter.rightOffset()); - rcFold.setTop((cRow - edit->mTopLine) * edit->mTextHeight); - rcFold.setRight(rcFold.left() + edit->mGutter.rightOffset() - 4); - rcFold.setBottom(rcFold.top() + edit->mTextHeight); - - - painter->setPen(edit->mCodeFolding.folderBarLinesColor); + rcFold.setLeft(mEdit->mGutterWidth - mEdit->mGutter.rightOffset()); + rcFold.setTop(( - mEdit->mTopLine) * mEdit->mTextHeight); + rcFold.setRight(rcFold.left() + mEdit->mGutter.rightOffset() - 4); + rcFold.setBottom(rcFold.top() + mEdit->mTextHeight); + mPainter->setPen(mEdit->mCodeFolding.folderBarLinesColor); // Need to paint a line? - if (edit->foldAroundLine(vLine)) { + if (mEdit->foldAroundLine(line)) { x = rcFold.left() + (rcFold.width() / 2); - painter->drawLine(x,rcFold.top(), x, rcFold.bottom()); + mPainter->drawLine(x,rcFold.top(), x, rcFold.bottom()); } // Need to paint a line end? - if (edit->foldEndAtLine(vLine)) { + if (mEdit->foldEndAtLine(line)) { x = rcFold.left() + (rcFold.width() / 2); - painter->drawLine(x,rcFold.top(), x, rcFold.top() + rcFold.height() / 2); - painter->drawLine(x, + mPainter->drawLine(x,rcFold.top(), x, rcFold.top() + rcFold.height() / 2); + mPainter->drawLine(x, rcFold.top() + rcFold.height() / 2, rcFold.right() - 2 , rcFold.top() + rcFold.height() / 2); } // Any fold ranges beginning on this line? - PCodeFoldingRange foldRange = edit->foldStartAtLine(vLine); + PCodeFoldingRange foldRange = mEdit->foldStartAtLine(line); 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, + mPainter->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.top() + ((mEdit->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); + mPainter->setBrush(mEdit->mGutter.color()); + mPainter->setPen(mEdit->mCodeFolding.folderBarLinesColor); + mPainter->drawRect(rcFold); // Paint minus sign - painter->drawLine( + mPainter->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, + mPainter->drawLine(x, rcFold.top() + 2, x, rcFold.bottom() - 2); } } } } - for (cRow = aFirstRow; cRow <=aLastRow; cRow++) { - vLine = edit->rowToLine(cRow); - if ((vLine > edit->mDocument->count()) && (edit->mDocument->count() != 0)) + for (int row = mFirstRow; row <= mLastRow; row++) { + int line = mEdit->rowToLine(row); + if ((line > mEdit->mDocument->count()) && (mEdit->mDocument->count() != 0)) break; - edit->onGutterPaint(*painter,vLine, 0, (cRow - edit->mTopLine) * edit->mTextHeight); + mEdit->onGutterPaint(*mPainter,line, 0, ( - mEdit->mTopLine) * mEdit->mTextHeight); } } QColor QSynEditPainter::colEditorBG() { - if (edit->mActiveLineColor.isValid() && bCurrentLine) { - return edit->mActiveLineColor; + if (mEdit->mActiveLineColor.isValid() && mIsCurrentLine) { + return mEdit->mActiveLineColor; } else { - return edit->mBackgroundColor; + return mEdit->mBackgroundColor; } } @@ -297,60 +271,60 @@ void QSynEditPainter::computeSelectionInfo() // Only if selection is visible anyway. bAnySelection = true; // Get the *real* start of the selected area. - if (edit->mBlockBegin.line < edit->mBlockEnd.line) { - vStart = edit->mBlockBegin; - vEnd = edit->mBlockEnd; - } else if (edit->mBlockBegin.line > edit->mBlockEnd.line) { - vEnd = edit->mBlockBegin; - vStart = edit->mBlockEnd; - } else if (edit->mBlockBegin.ch != edit->mBlockEnd.ch) { + if (mEdit->mBlockBegin.line < mEdit->mBlockEnd.line) { + vStart = mEdit->mBlockBegin; + vEnd = mEdit->mBlockEnd; + } else if (mEdit->mBlockBegin.line > mEdit->mBlockEnd.line) { + vEnd = mEdit->mBlockBegin; + vStart = mEdit->mBlockEnd; + } else if (mEdit->mBlockBegin.ch != mEdit->mBlockEnd.ch) { // it is only on this line. - vStart.line = edit->mBlockBegin.line; + vStart.line = mEdit->mBlockBegin.line; vEnd.line = vStart.line; - if (edit->mBlockBegin.ch < edit->mBlockEnd.ch) { - vStart.ch = edit->mBlockBegin.ch; - vEnd.ch = edit->mBlockEnd.ch; + if (mEdit->mBlockBegin.ch < mEdit->mBlockEnd.ch) { + vStart.ch = mEdit->mBlockBegin.ch; + vEnd.ch = mEdit->mBlockEnd.ch; } else { - vStart.ch = edit->mBlockEnd.ch; - vEnd.ch = edit->mBlockBegin.ch; + vStart.ch = mEdit->mBlockEnd.ch; + vEnd.ch = mEdit->mBlockBegin.ch; } } else bAnySelection = false; - if (edit->mInputPreeditString.length()>0) { - if (vStart.line == edit->mCaretY && vStart.ch >=edit->mCaretX) { - vStart.ch+=edit->mInputPreeditString.length(); + if (mEdit->mInputPreeditString.length()>0) { + if (vStart.line == mEdit->mCaretY && vStart.ch >=mEdit->mCaretX) { + vStart.ch+=mEdit->mInputPreeditString.length(); } - if (vEnd.line == edit->mCaretY && vEnd.ch >edit->mCaretX) { - vEnd.ch+=edit->mInputPreeditString.length(); + if (vEnd.line == mEdit->mCaretY && vEnd.ch >mEdit->mCaretX) { + vEnd.ch+=mEdit->mInputPreeditString.length(); } } // If there is any visible selection so far, then test if there is an // intersection with the area to be painted. if (bAnySelection) { // Don't care if the selection is not visible. - bAnySelection = (vEnd.line >= vFirstLine) && (vStart.line <= vLastLine); + bAnySelection = (vEnd.line >= mFirstLine) && (vStart.line <= mLastLine); if (bAnySelection) { // Transform the selection from text space into screen space - vSelStart = edit->bufferToDisplayPos(vStart); - vSelEnd = edit->bufferToDisplayPos(vEnd); - if (edit->mInputPreeditString.length() - && vStart.line == edit->mCaretY) { - QString sLine = edit->lineText().left(edit->mCaretX-1) - + edit->mInputPreeditString - + edit->lineText().mid(edit->mCaretX-1); - vSelStart.x = edit->charToGlyphLeft(edit->mCaretY, sLine,vStart.ch); + mSelStart = mEdit->bufferToDisplayPos(vStart); + mSelEnd = mEdit->bufferToDisplayPos(vEnd); + if (mEdit->mInputPreeditString.length() + && vStart.line == mEdit->mCaretY) { + QString sLine = mEdit->lineText().left(mEdit->mCaretX-1) + + mEdit->mInputPreeditString + + mEdit->lineText().mid(mEdit->mCaretX-1); + mSelStart.x = mEdit->charToGlyphLeft(mEdit->mCaretY, sLine,vStart.ch); } - if (edit->mInputPreeditString.length() - && vEnd.line == edit->mCaretY) { - QString sLine = edit->lineText().left(edit->mCaretX-1) - + edit->mInputPreeditString - + edit->lineText().mid(edit->mCaretX-1); - vSelEnd.x = edit->charToGlyphLeft(edit->mCaretY, sLine,vEnd.ch); + if (mEdit->mInputPreeditString.length() + && vEnd.line == mEdit->mCaretY) { + QString sLine = mEdit->lineText().left(mEdit->mCaretX-1) + + mEdit->mInputPreeditString + + mEdit->lineText().mid(mEdit->mCaretX-1); + mSelEnd.x = mEdit->charToGlyphLeft(mEdit->mCaretY, sLine,vEnd.ch); } // In the column selection mode sort the begin and end of the selection, // this makes the painting code simpler. - if (edit->mActiveSelectionMode == SelectionMode::Column && vSelStart.x > vSelEnd.x) - std::swap(vSelStart.x, vSelEnd.x); + if (mEdit->mActiveSelectionMode == SelectionMode::Column && mSelStart.x > mSelEnd.x) + std::swap(mSelStart.x, mSelEnd.x); } } } @@ -359,42 +333,43 @@ void QSynEditPainter::setDrawingColors(bool selected) { if (selected) { if (colSelFG.isValid()) - painter->setPen(colSelFG); + mPainter->setPen(colSelFG); else - painter->setPen(colFG); + mPainter->setPen(colFG); if (colSelBG.isValid()) - painter->setBrush(colSelBG); + mPainter->setBrush(colSelBG); else - painter->setBrush(colBG); - painter->setBackground(edit->mBackgroundColor); + mPainter->setBrush(colBG); + mPainter->setBackground(mEdit->mBackgroundColor); } else { - painter->setPen(colFG); - painter->setBrush(colBG); - painter->setBackground(edit->mBackgroundColor); + mPainter->setPen(colFG); + mPainter->setBrush(colBG); + mPainter->setBackground(mEdit->mBackgroundColor); } } -int QSynEditPainter::columnToXValue(int col) +int QSynEditPainter::fixXValue(int xpos) { - return edit->textOffset() + (col - 1) * edit->mCharWidth; + return mEdit->textOffset() + xpos; } -void QSynEditPainter::paintToken(const QString &token, int tokenCols, int columnsBefore, - int first, int last, bool /*isSelection*/, const QFont& font, - const QFont& fontForNonAscii, bool showGlyphs) +void QSynEditPainter::paintToken( + const QString &token, int tokenWidth, int tokenLeft, + int first, int last, bool /*isSelection*/, const QFont& font, + const QFont& fontForNonAscii, bool showGlyphs) { bool startPaint; int nX; if (last >= first && rcToken.right() > rcToken.left()) { // qDebug()<<"Paint Token"<fillRect(rcTokenBack,painter->brush()); - if (first > tokenCols) { + mPainter->fillRect(rcTokenBack,mPainter->brush()); + if (first > tokenWidth) { } else { int tokenWidth=0; startPaint = false; @@ -404,34 +379,34 @@ void QSynEditPainter::paintToken(const QString &token, int tokenCols, int column int glyphStart = glyphStartCharList[i]; int glyphEnd =(i+1document()->glyphWidth(glyph, columnsBefore+tokenColLen); + int glyphWidth = mEdit->document()->glyphWidth(glyph, tokenLeft+tokenWidth); // qDebug()<=first) { - if (!startPaint && (tokenColLen+1!=first)) { - nX-= (first - tokenColLen - 1) * edit->mCharWidth; + if (tokenWidth+glyphWidth>=first) { + if (!startPaint ) { + nX-= (first - tokenWidth - 1) ; + startPaint = true; } - startPaint = true; } - if (tokenColLen+charCols > last) + if (tokenWidth+glyphWidth > last) break; //painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent()*edit->dpiFactor() , Token[i]); if (startPaint) { bool drawed = false; - if (painter->fontInfo().fixedPitch() - && edit->mOptions.testFlag(eoLigatureSupport) - && operatorGlyphs.contains(glyph)) { + if (mPainter->fontInfo().fixedPitch() + && mEdit->mOptions.testFlag(eoLigatureSupport) + && OperatorGlyphs.contains(glyph)) { QString textToPaint = glyph; while(i+1document()->glyphWidth(glyph2,0); + glyphWidth += mEdit->document()->glyphWidth(glyph2,0); textToPaint+=glyph2; } - painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent() , textToPaint); + mPainter->drawText(nX,rcToken.bottom()-mPainter->fontMetrics().descent() , textToPaint); drawed = true; } if (!drawed) { @@ -442,7 +417,7 @@ void QSynEditPainter::paintToken(const QString &token, int tokenCols, int column switch(glyph.front().unicode()) { case '\t': ch=TabGlyph; - padding=(charCols-1)/2*edit->mCharWidth; + padding=(glyphWidth-1)/2*mEdit->mCharWidth; break; case ' ': ch=SpaceGlyph; @@ -453,18 +428,18 @@ void QSynEditPainter::paintToken(const QString &token, int tokenCols, int column } else { ch=glyph; } - painter->drawText(nX+padding,rcToken.bottom()-painter->fontMetrics().descent() , ch); + mPainter->drawText(nX+padding,rcToken.bottom()-mPainter->fontMetrics().descent() , ch); } else { - painter->setFont(fontForNonAscii); - painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent() , glyph); - painter->setFont(font); + mPainter->setFont(fontForNonAscii); + mPainter->drawText(nX,rcToken.bottom()-mPainter->fontMetrics().descent() , glyph); + mPainter->setFont(font); } drawed = true; } - nX += charCols * edit->mCharWidth; + nX += glyphWidth; } - tokenColLen += charCols; + tokenWidth += glyphWidth; } } @@ -482,28 +457,28 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList) rc.setBottom(rc.bottom()-1); setDrawingColors(false); for (const PEditingArea& p:areaList) { - if (p->beginX > LastCol) + if (p->beginX > mRight) continue; - if (p->endX < FirstCol) + if (p->endX < mLeft) continue; - if (p->beginX < FirstCol) - x1 = FirstCol; + if (p->beginX < mLeft) + x1 = mLeft; else x1 = p->beginX; - if (p->endX > LastCol) - x2 = LastCol; + if (p->endX > mRight) + x2 = mRight; else x2 = p->endX; - rc.setLeft(columnToXValue(x1)); - rc.setRight(columnToXValue(x2)); - painter->setPen(p->color); - painter->setBrush(Qt::NoBrush); + rc.setLeft(fixXValue(x1)); + rc.setRight(fixXValue(x2)); + mPainter->setPen(p->color); + mPainter->setBrush(Qt::NoBrush); switch(p->type) { case EditingAreaType::eatRectangleBorder: - painter->drawRect(rc); + mPainter->drawRect(rc); break; case EditingAreaType::eatUnderLine: - painter->drawLine(rc.left(),rc.bottom(),rc.right(),rc.bottom()); + mPainter->drawLine(rc.left(),rc.bottom(),rc.right(),rc.bottom()); break; case EditingAreaType::eatWaveUnderLine: offset=3; @@ -515,7 +490,7 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList) if (t>rc.right()) t = rc.right(); offset = 3 - offset; - painter->drawLine(lastX,lastY,t,rc.bottom()-offset); + mPainter->drawLine(lastX,lastY,t,rc.bottom()-offset); lastX = t; lastY = rc.bottom()-offset; } @@ -526,112 +501,112 @@ void QSynEditPainter::paintEditAreas(const EditingAreaList &areaList) void QSynEditPainter::paintHighlightToken(bool bFillToEOL) { - bool bComplexToken; + bool isComplexToken; int nC1, nC2, nC1Sel, nC2Sel; bool bU1, bSel, bU2; int nX1, nX2; // Compute some helper variables. - nC1 = std::max(FirstCol, mTokenAccu.columnsBefore + 1); - nC2 = std::min(LastCol, mTokenAccu.columnsBefore + mTokenAccu.columns + 1); - if (bComplexLine) { - bU1 = (nC1 < nLineSelStart); - bSel = (nC1 < nLineSelEnd) && (nC2 >= nLineSelStart); - bU2 = (nC2 >= nLineSelEnd); - bComplexToken = bSel && (bU1 || bU2); + nC1 = std::max(mLeft, mTokenAccu.left); + nC2 = std::min(mRight, mTokenAccu.left + mTokenAccu.width); + if (mIsComplexLine) { + bU1 = (nC1 < mLineSelStart); + bSel = (nC1 < mLineSelEnd) && (nC2 >= mLineSelStart); + bU2 = (nC2 >= mLineSelEnd); + isComplexToken = bSel && (bU1 || bU2); } else { - bSel = bLineSelected; - bComplexToken = false; - bU1 = false; // to shut up compiler warning. - bU2 = false; // to shut up compiler warning. + bSel = mIsLineSelected; + isComplexToken = false; + bU1 = false; + bU2 = false; } // Any token chars accumulated? - if (mTokenAccu.columns > 0) { + if (mTokenAccu.width > 0) { // Initialize the colors and the font style. colBG = mTokenAccu.background; colFG = mTokenAccu.foreground; - if (bSpecialLine) { + if (mIsSpecialLine) { if (colSpFG.isValid()) colFG = colSpFG; if (colSpBG.isValid()) colBG = colSpBG; } -// if (bSpecialLine && edit->mOptions.testFlag(eoSpecialLineDefaultFg)) + // if (bSpecialLine && mEdit->mOptions.testFlag(eoSpecialLineDefaultFg)) // colFG = TokenAccu.FG; - QFont font = edit->font(); + QFont font = mEdit->font(); font.setBold(mTokenAccu.style & FontStyle::fsBold); font.setItalic(mTokenAccu.style & FontStyle::fsItalic); font.setStrikeOut(mTokenAccu.style & FontStyle::fsStrikeOut); font.setUnderline(mTokenAccu.style & FontStyle::fsUnderline); - painter->setFont(font); - QFont nonAsciiFont = edit->fontForNonAscii(); + mPainter->setFont(font); + QFont nonAsciiFont = mEdit->fontForNonAscii(); nonAsciiFont.setBold(mTokenAccu.style & FontStyle::fsBold); nonAsciiFont.setItalic(mTokenAccu.style & FontStyle::fsItalic); nonAsciiFont.setStrikeOut(mTokenAccu.style & FontStyle::fsStrikeOut); nonAsciiFont.setUnderline(mTokenAccu.style & FontStyle::fsUnderline); // Paint the chars - if (bComplexToken) { + if (isComplexToken) { // first unselected part of the token if (bU1) { setDrawingColors(false); - rcToken.setRight(columnToXValue(nLineSelStart)); + rcToken.setRight(fixXValue(mLineSelStart)); paintToken( - mTokenAccu.s,mTokenAccu.columns,mTokenAccu.columnsBefore,nC1,nLineSelStart,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); + mTokenAccu.s,mTokenAccu.width,mTokenAccu.left,nC1,mLineSelStart,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); } // selected part of the token setDrawingColors(true); - nC1Sel = std::max(nLineSelStart, nC1); - nC2Sel = std::min(nLineSelEnd, nC2); - rcToken.setRight(columnToXValue(nC2Sel)); - paintToken(mTokenAccu.s, mTokenAccu.columns, mTokenAccu.columnsBefore, nC1Sel, nC2Sel,true,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); + nC1Sel = std::max(mLineSelStart, nC1); + nC2Sel = std::min(mLineSelEnd, nC2); + rcToken.setRight(fixXValue(nC2Sel)); + paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, nC1Sel, nC2Sel,true,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); // second unselected part of the token if (bU2) { setDrawingColors(false); - rcToken.setRight(columnToXValue(nC2)); - paintToken(mTokenAccu.s, mTokenAccu.columns, mTokenAccu.columnsBefore,nLineSelEnd, nC2,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); + rcToken.setRight(fixXValue(nC2)); + paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left,mLineSelEnd, nC2,false,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); } } else { setDrawingColors(bSel); - rcToken.setRight(columnToXValue(nC2)); - paintToken(mTokenAccu.s, mTokenAccu.columns, mTokenAccu.columnsBefore, nC1, nC2,bSel,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); + rcToken.setRight(fixXValue(nC2)); + paintToken(mTokenAccu.s, mTokenAccu.width, mTokenAccu.left, nC1, nC2,bSel,font,nonAsciiFont, mTokenAccu.showSpecialGlyphs); } } // Fill the background to the end of this line if necessary. if (bFillToEOL && rcToken.left() < rcLine.right()) { - if (bSpecialLine && colSpBG.isValid()) + if (mIsSpecialLine && colSpBG.isValid()) colBG = colSpBG; else colBG = colEditorBG(); - if (bComplexLine) { - nX1 = columnToXValue(nLineSelStart); - nX2 = columnToXValue(nLineSelEnd); + if (mIsComplexLine) { + nX1 = fixXValue(mLineSelStart); + nX2 = fixXValue(mLineSelEnd); if (rcToken.left() < nX1) { setDrawingColors(false); rcToken.setRight(nX1); // if (TokenAccu.Len != 0 && TokenAccu.Style != FontStyle::fsNone) // AdjustEndRect(); - painter->fillRect(rcToken,painter->brush()); + mPainter->fillRect(rcToken,mPainter->brush()); rcToken.setLeft(nX1); } if (rcToken.left() < nX2) { setDrawingColors(true); rcToken.setRight(nX2); - painter->fillRect(rcToken,painter->brush()); + mPainter->fillRect(rcToken,mPainter->brush()); rcToken.setLeft(nX2); } if (rcToken.left() < rcLine.right()) { setDrawingColors(false); rcToken.setRight(rcLine.right()); - painter->fillRect(rcToken,painter->brush()); + mPainter->fillRect(rcToken,mPainter->brush()); } } else { - setDrawingColors(bLineSelected); + setDrawingColors(mIsLineSelected); rcToken.setRight(rcLine.right()); // if (TokenAccu.Len != 0 && TokenAccu.Style != FontStyle::fsNone) // AdjustEndRect(); - painter->fillRect(rcToken,painter->brush()); + mPainter->fillRect(rcToken,mPainter->brush()); } } } @@ -639,8 +614,9 @@ void QSynEditPainter::paintHighlightToken(bool bFillToEOL) // Store the token chars with the attributes in the TokenAccu // record. This will paint any chars already stored if there is // a (visible) change in the attributes. -void QSynEditPainter::addHighlightToken(const QString &token, int columnsBefore, - int tokenColumns, int cLine, PTokenAttribute attri, bool showGlyphs) +void QSynEditPainter::addHighlightToken(const QString &token, int tokenLeft, + int tokenWidth, int line, PTokenAttribute attri, + bool showGlyphs) { bool bCanAppend; QColor foreground, background; @@ -653,7 +629,7 @@ void QSynEditPainter::addHighlightToken(const QString &token, int columnsBefore, } else { foreground = colFG; background = colBG; - style = getFontStyles(edit->font()); + style = getFontStyles(mEdit->font()); } // if (!Background.isValid() || (edit->mActiveLineColor.isValid() && bCurrentLine)) { @@ -663,15 +639,15 @@ void QSynEditPainter::addHighlightToken(const QString &token, int columnsBefore, background = colEditorBG(); } if (!foreground.isValid()) { - foreground = edit->mForegroundColor; + foreground = mEdit->mForegroundColor; } - edit->onPreparePaintHighlightToken(cLine,edit->mSyntaxer->getTokenPos()+1, + mEdit->onPreparePaintHighlightToken(line,mEdit->mSyntaxer->getTokenPos()+1, token,attri,style,foreground,background); // Do we have to paint the old chars first, or can we just append? bCanAppend = false; - if (mTokenAccu.columns > 0 ) { + if (mTokenAccu.width > 0 ) { if (showGlyphs == mTokenAccu.showSpecialGlyphs) { // font style must be the same or token is only spaces if (mTokenAccu.style == style) { @@ -691,11 +667,11 @@ void QSynEditPainter::addHighlightToken(const QString &token, int columnsBefore, // Don't use AppendStr because it's more expensive. if (bCanAppend) { mTokenAccu.s.append(token); - mTokenAccu.columns+=tokenColumns; + mTokenAccu.width+=tokenWidth; } else { - mTokenAccu.columns = tokenColumns; + mTokenAccu.width = tokenWidth; mTokenAccu.s = token; - mTokenAccu.columnsBefore = columnsBefore; + mTokenAccu.left = tokenLeft; mTokenAccu.foreground = foreground; mTokenAccu.background = background; mTokenAccu.style = style; @@ -705,105 +681,105 @@ void QSynEditPainter::addHighlightToken(const QString &token, int columnsBefore, void QSynEditPainter::paintFoldAttributes() { - int tabSteps, lineIndent, lastNonBlank, X, Y, cRow, vLine; + int tabSteps, lineIndent, lastNonBlank, X, Y; // Paint indent guides. Use folds to determine indent value of these // Use a separate loop so we can use a custom pen // Paint indent guides using custom pen - if (edit->mCodeFolding.indentGuides || edit->mCodeFolding.fillIndents) { + if (mEdit->mCodeFolding.indentGuides || mEdit->mCodeFolding.fillIndents) { QColor paintColor; - if (edit->mCodeFolding.indentGuidesColor.isValid()) { - paintColor = edit->mCodeFolding.indentGuidesColor; + if (mEdit->mCodeFolding.indentGuidesColor.isValid()) { + paintColor = mEdit->mCodeFolding.indentGuidesColor; } else { - paintColor = edit->palette().color(QPalette::Text); + paintColor = mEdit->palette().color(QPalette::Text); } QColor gradientStart = paintColor; QColor gradientEnd = paintColor; - QPen oldPen = painter->pen(); + QPen oldPen = mPainter->pen(); // Now loop through all the lines. The indices are valid for Lines. - for (cRow = aFirstRow; cRow<=aLastRow;cRow++) { - vLine = edit->rowToLine(cRow); - if (vLine > edit->mDocument->count() && edit->mDocument->count() > 0) + for (int row = mFirstRow; row<=mLastRow;row++) { + int vLine = mEdit->rowToLine(row); + if (vLine > mEdit->mDocument->count() && mEdit->mDocument->count() > 0) break; // Set vertical coord - Y = (cRow - edit->mTopLine) * edit->mTextHeight; // limit inside clip rect - if (edit->mTextHeight % 2 == 1 && vLine % 2 == 0) { + Y = (row - mEdit->mTopLine) * mEdit->mTextHeight; // limit inside clip rect + if (mEdit->mTextHeight % 2 == 1 && vLine % 2 == 0) { Y++; } // Get next nonblank line lastNonBlank = vLine - 1; - while (lastNonBlank + 1 < edit->mDocument->count() && edit->mDocument->getLine(lastNonBlank).isEmpty()) + while (lastNonBlank + 1 < mEdit->mDocument->count() && mEdit->mDocument->getLine(lastNonBlank).isEmpty()) lastNonBlank++; - if (lastNonBlank>=edit->document()->count()) + if (lastNonBlank>=mEdit->document()->count()) continue; - lineIndent = edit->getLineIndent(edit->mDocument->getLine(lastNonBlank)); - int braceLevel = edit->mDocument->getSyntaxState(lastNonBlank).braceLevel; + lineIndent = mEdit->getLineIndent(mEdit->mDocument->getLine(lastNonBlank)); + int braceLevel = mEdit->mDocument->getSyntaxState(lastNonBlank).braceLevel; int indentLevel = braceLevel ; - if (edit->tabSize()>0) - indentLevel = lineIndent / edit->tabSize(); + if (mEdit->tabSize()>0) + indentLevel = lineIndent / mEdit->tabSize(); // Step horizontal coord //TabSteps = edit->mTabWidth; tabSteps = 0; indentLevel = 0; while (tabSteps < lineIndent) { - X = tabSteps * edit->mCharWidth + edit->textOffset() - 2; - tabSteps+=edit->tabSize(); + X = tabSteps * mEdit->mCharWidth + mEdit->textOffset() - 2; + tabSteps+=mEdit->tabSize(); indentLevel++ ; - if (edit->mSyntaxer) { - if (edit->mCodeFolding.indentGuides) { - PTokenAttribute attr = edit->mSyntaxer->symbolAttribute(); + if (mEdit->mSyntaxer) { + if (mEdit->mCodeFolding.indentGuides) { + PTokenAttribute attr = mEdit->mSyntaxer->symbolAttribute(); getBraceColorAttr(indentLevel,attr); paintColor = attr->foreground(); } - if (edit->mCodeFolding.fillIndents) { - PTokenAttribute attr = edit->mSyntaxer->symbolAttribute(); + if (mEdit->mCodeFolding.fillIndents) { + PTokenAttribute attr = mEdit->mSyntaxer->symbolAttribute(); getBraceColorAttr(indentLevel,attr); gradientStart=attr->foreground(); - attr = edit->mSyntaxer->symbolAttribute(); + attr = mEdit->mSyntaxer->symbolAttribute(); getBraceColorAttr(indentLevel+1,attr); gradientStart=attr->foreground(); } } - if (edit->mCodeFolding.fillIndents) { + if (mEdit->mCodeFolding.fillIndents) { int X1; if (tabSteps>lineIndent) - X1 = lineIndent * edit->mCharWidth + edit->textOffset() - 2; + X1 = lineIndent * mEdit->mCharWidth + mEdit->textOffset() - 2; else - X1 = tabSteps * edit->mCharWidth + edit->textOffset() - 2; + X1 = tabSteps * mEdit->mCharWidth + mEdit->textOffset() - 2; gradientStart.setAlpha(20); gradientEnd.setAlpha(10); QLinearGradient gradient(X,Y,X1,Y); gradient.setColorAt(1,gradientStart); gradient.setColorAt(0,gradientEnd); - painter->fillRect(X,Y,(X1-X),edit->mTextHeight,gradient); + mPainter->fillRect(X,Y,(X1-X),mEdit->mTextHeight,gradient); } // Move to top of vertical line - if (edit->mCodeFolding.indentGuides) { + if (mEdit->mCodeFolding.indentGuides) { QPen dottedPen(Qt::PenStyle::DashLine); dottedPen.setColor(paintColor); - painter->setPen(dottedPen); - painter->drawLine(X,Y,X,Y+edit->mTextHeight); + mPainter->setPen(dottedPen); + mPainter->drawLine(X,Y,X,Y+mEdit->mTextHeight); } } } - painter->setPen(oldPen); + mPainter->setPen(oldPen); } - if (!edit->mUseCodeFolding) + if (!mEdit->mUseCodeFolding) return; // Paint collapsed lines using changed pen - if (edit->mCodeFolding.showCollapsedLine) { - painter->setPen(edit->mCodeFolding.collapsedLineColor); - for (int i=0; i< edit->mAllFoldRanges->count();i++) { - PCodeFoldingRange range = (*edit->mAllFoldRanges)[i]; + if (mEdit->mCodeFolding.showCollapsedLine) { + mPainter->setPen(mEdit->mCodeFolding.collapsedLineColor); + for (int i=0; i< mEdit->mAllFoldRanges->count();i++) { + PCodeFoldingRange range = (*mEdit->mAllFoldRanges)[i]; if (range->collapsed && !range->parentCollapsed() && - (range->fromLine <= vLastLine) && (range->fromLine >= vFirstLine) ) { + (range->fromLine <= mLastLine) && (range->fromLine >= mFirstLine) ) { // Get starting and end points - Y = (edit->lineToRow(range->fromLine) - edit->mTopLine + 1) * edit->mTextHeight - 1; - painter->drawLine(AClip.left(),Y, AClip.right(),Y); + Y = (mEdit->lineToRow(range->fromLine) - mEdit->mTopLine + 1) * mEdit->mTextHeight - 1; + mPainter->drawLine(mClip.left(),Y, mClip.right(),Y); } } } @@ -812,23 +788,23 @@ void QSynEditPainter::paintFoldAttributes() void QSynEditPainter::getBraceColorAttr(int level, PTokenAttribute &attr) { - if (!edit->mOptions.testFlag(EditorOption::eoShowRainbowColor)) + if (!mEdit->mOptions.testFlag(EditorOption::eoShowRainbowColor)) return; if (attr->tokenType() != TokenType::Operator) return; PTokenAttribute oldAttr = attr; switch(level % 4) { case 0: - attr = edit->mRainbowAttr0; + attr = mEdit->mRainbowAttr0; break; case 1: - attr = edit->mRainbowAttr1; + attr = mEdit->mRainbowAttr1; break; case 2: - attr = edit->mRainbowAttr2; + attr = mEdit->mRainbowAttr2; break; case 3: - attr = edit->mRainbowAttr3; + attr = mEdit->mRainbowAttr3; break; } if (!attr) @@ -837,14 +813,10 @@ void QSynEditPainter::getBraceColorAttr(int level, PTokenAttribute &attr) void QSynEditPainter::paintLines() { - int cRow; // row index for the loop - int vLine; QString sLine; // the current line QString sToken; // token info - int nTokenColumnsBefore, nTokenColumnLen; + int tokenLeft, tokenWidth; PTokenAttribute attr; - int vFirstChar; - int vLastChar; EditingAreaList areaList; PCodeFoldingRange foldRange; PTokenAttribute preeditAttr; @@ -853,83 +825,75 @@ void QSynEditPainter::paintLines() // Initialize rcLine for drawing. Note that Top and Bottom are updated // inside the loop. Get only the starting point for this. - rcLine = AClip; - rcLine.setBottom((aFirstRow - edit->mTopLine) * edit->mTextHeight); - mTokenAccu.columns = 0; - mTokenAccu.columnsBefore = 0; + rcLine = mClip; + rcLine.setBottom((mFirstRow - mEdit->mTopLine) * mEdit->mTextHeight); + mTokenAccu.width = 0; + mTokenAccu.left = 0; // Now loop through all the lines. The indices are valid for Lines. - BufferCoord selectionBegin = edit->blockBegin(); - BufferCoord selectionEnd= edit->blockEnd(); - for (cRow = aFirstRow; cRow<=aLastRow; cRow++) { - vLine = edit->rowToLine(cRow); - if (vLine > edit->mDocument->count() && edit->mDocument->count() != 0) + BufferCoord selectionBegin = mEdit->blockBegin(); + BufferCoord selectionEnd= mEdit->blockEnd(); + for (int row = mFirstRow; row<=mLastRow; row++) { + int vLine = mEdit->rowToLine(row); + if (vLine > mEdit->mDocument->count() && mEdit->mDocument->count() != 0) break; // Get the line. - sLine = edit->mDocument->getLine(vLine - 1); + sLine = mEdit->lineText(vLine); // determine whether will be painted with ActiveLineColor - if (edit->mActiveSelectionMode == SelectionMode::Column) { - bCurrentLine = (vLine >= selectionBegin.line && vLine <= selectionEnd.line); + if (mEdit->mActiveSelectionMode == SelectionMode::Column) { + mIsCurrentLine = (vLine >= selectionBegin.line && vLine <= selectionEnd.line); } else { - bCurrentLine = (edit->mCaretY == vLine); + mIsCurrentLine = (mEdit->mCaretY == vLine); } - if (bCurrentLine && !edit->mInputPreeditString.isEmpty()) { - int col = edit->charToColumn(edit->mCaretY,edit->mCaretX); - int ch = edit->columnToChar(vLine,col); - sLine = sLine.left(ch-1) + edit->mInputPreeditString - + sLine.mid(ch-1); + if (mIsCurrentLine && !mEdit->mInputPreeditString.isEmpty()) { + int ch = mEdit->mDocument->charToGlyphStartChar(mEdit->mCaretY-1,mEdit->mCaretX-1); + sLine = sLine.left(ch) + mEdit->mInputPreeditString + + sLine.mid(ch); } // Initialize the text and background colors, maybe the line should // use special values for them. - colFG = edit->mForegroundColor; + colFG = mEdit->mForegroundColor; colBG = colEditorBG(); colSpFG = QColor(); colSpBG = QColor(); - bSpecialLine = edit->onGetSpecialLineColors(vLine, colSpFG, colSpBG); + mIsSpecialLine = mEdit->onGetSpecialLineColors(vLine, colSpFG, colSpBG); - colSelFG = edit->mSelectedForeground; - colSelBG = edit->mSelectedBackground; - edit->onGetEditingAreas(vLine, areaList); - // Removed word wrap support - vFirstChar = FirstCol; - vLastChar = LastCol; + colSelFG = mEdit->mSelectedForeground; + colSelBG = mEdit->mSelectedBackground; + mEdit->onGetEditingAreas(vLine, areaList); // Get the information about the line selection. Three different parts // are possible (unselected before, selected, unselected after), only // unselected or only selected means bComplexLine will be FALSE. Start // with no selection, compute based on the visible columns. - bComplexLine = false; - nLineSelStart = 0; - nLineSelEnd = 0; + mIsComplexLine = false; + mLineSelStart = 0; + mLineSelEnd = 0; // Does the selection intersect the visible area? - if (bAnySelection && (cRow >= vSelStart.row) && (cRow <= vSelEnd.row)) { + if (bAnySelection && (row >= mSelStart.row) && (row <= mSelEnd.row)) { // Default to a fully selected line. This is correct for the smLine // selection mode and a good start for the smNormal mode. - nLineSelStart = FirstCol; - nLineSelEnd = LastCol + 1; - if ((edit->mActiveSelectionMode == SelectionMode::Column) || - ((edit->mActiveSelectionMode == SelectionMode::Normal) && (cRow == vSelStart.row)) ) { - int ch = edit->columnToChar(vLine,vSelStart.x); - ch = edit->charToColumn(vLine,ch); - if (ch > LastCol) { - nLineSelStart = 0; - nLineSelEnd = 0; - } else if (ch > FirstCol) { - nLineSelStart = ch; - bComplexLine = true; + mLineSelStart = mLeft; + mLineSelEnd = mRight + 1; + if ((mEdit->mActiveSelectionMode == SelectionMode::Column) || + ((mEdit->mActiveSelectionMode == SelectionMode::Normal) && (row == mSelStart.row)) ) { + int xpos = mEdit->xposToGlyphLeft(vLine,mSelStart.x); + if (xpos > mRight) { + mLineSelStart = 0; + mLineSelEnd = 0; + } else if (xpos > mLeft) { + mLineSelStart = xpos; + mIsComplexLine = true; } } - if ( (edit->mActiveSelectionMode == SelectionMode::Column) || - ((edit->mActiveSelectionMode == SelectionMode::Normal) && (cRow == vSelEnd.row)) ) { - int ch = edit->columnToChar(vLine,vSelEnd.x); - int col = edit->charToColumn(vLine,ch); - if (colcharToColumn(vLine,ch+1); - if (col < FirstCol) { - nLineSelStart = 0; - nLineSelEnd = 0; - } else if (col < LastCol) { - nLineSelEnd = col; - bComplexLine = true; + if ( (mEdit->mActiveSelectionMode == SelectionMode::Column) || + ((mEdit->mActiveSelectionMode == SelectionMode::Normal) && (row == mSelEnd.row)) ) { + int xpos = mEdit->xposToGlyphLeft(vLine,mSelEnd.x); + if (xpos < mLeft) { + mLineSelStart = 0; + mLineSelEnd = 0; + } else if (xpos < mRight) { + mLineSelEnd = xpos; + mIsComplexLine = true; } } } //endif bAnySelection @@ -937,45 +901,43 @@ void QSynEditPainter::paintLines() // Update the rcLine rect to this line. // rcLine.setTop(rcLine.bottom()); // rcLine.setBottom(rcLine.bottom()+edit->mTextHeight); - rcLine.setTop((cRow - edit->mTopLine) * edit->mTextHeight); - rcLine.setHeight(edit->mTextHeight); + rcLine.setTop((row - mEdit->mTopLine) * mEdit->mTextHeight); + rcLine.setHeight(mEdit->mTextHeight); - bLineSelected = (!bComplexLine) && (nLineSelStart > 0); + mIsLineSelected = (!mIsComplexLine) && (mLineSelStart > 0); rcToken = rcLine; - if (!edit->mSyntaxer || !edit->mSyntaxer->enabled()) { + if (!mEdit->mSyntaxer || !mEdit->mSyntaxer->enabled()) { sToken = sLine; - if (bCurrentLine) { - nTokenColumnLen = edit->document()->lineColumns(vLine-1, sLine); + if (mIsCurrentLine) { + tokenWidth = mEdit->document()->lineWidth(vLine-1, sLine); } else { - nTokenColumnLen = edit->document()->lineColumns(vLine-1); + tokenWidth = mEdit->document()->lineWidth(vLine-1); } - if (edit->mOptions.testFlag(eoShowLineBreaks) && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) { + if (mEdit->mOptions.testFlag(eoShowLineBreaks) && (!mIsLineSelected) && (!mIsSpecialLine) && (tokenWidth <= mLeft)) { sToken = sToken + LineBreakGlyph; - nTokenColumnLen += edit->document()->glyphColumns(LineBreakGlyph,0); + tokenWidth += mEdit->document()->glyphWidth(LineBreakGlyph,0); } - if (bComplexLine) { + if (mIsComplexLine) { setDrawingColors(true); - rcToken.setLeft(std::max(rcLine.left(), columnToXValue(nLineSelStart))); - rcToken.setRight(std::min(rcLine.right(), columnToXValue(nLineSelEnd))); - paintToken(sToken, nTokenColumnLen, 0, nLineSelStart, nLineSelEnd,false,edit->font(),edit->fontForNonAscii(),false); + rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelStart))); + rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelEnd))); + paintToken(sToken, tokenWidth, 0, mLineSelStart, mLineSelEnd,false,mEdit->font(),mEdit->fontForNonAscii(),false); setDrawingColors(false); - rcToken.setLeft(std::max(rcLine.left(), columnToXValue(FirstCol))); - rcToken.setRight(std::min(rcLine.right(), columnToXValue(nLineSelStart))); - paintToken(sToken, nTokenColumnLen, 0, FirstCol, nLineSelStart,false,edit->font(),edit->fontForNonAscii(),false); - rcToken.setLeft(std::max(rcLine.left(), columnToXValue(nLineSelEnd))); - rcToken.setRight(std::min(rcLine.right(), columnToXValue(LastCol))); - paintToken(sToken, nTokenColumnLen, 0, nLineSelEnd, LastCol,true,edit->font(),edit->fontForNonAscii(),false); + rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLeft))); + rcToken.setRight(std::min(rcLine.right(), fixXValue(mLineSelStart))); + paintToken(sToken, tokenWidth, 0, mLeft, mLineSelStart,false,mEdit->font(),mEdit->fontForNonAscii(),false); + rcToken.setLeft(std::max(rcLine.left(), fixXValue(mLineSelEnd))); + rcToken.setRight(std::min(rcLine.right(), fixXValue(mRight))); + paintToken(sToken, tokenWidth, 0, mLineSelEnd, mRight,true, mEdit->font(), mEdit->fontForNonAscii(),false); } else { - setDrawingColors(bLineSelected); - paintToken(sToken, nTokenColumnLen, 0, FirstCol, LastCol,bLineSelected,edit->font(),edit->fontForNonAscii(),false); + setDrawingColors(mIsLineSelected); + paintToken(sToken, tokenWidth, 0, mLeft, mRight, mIsLineSelected,mEdit->font(),mEdit->fontForNonAscii(),false); } //Paint editingAreaBorders - if (bCurrentLine && edit->mInputPreeditString.length()>0) { + if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) { PEditingArea area = std::make_shared(); - int col = edit->charToColumn(edit->mCaretY,edit->mCaretX); - int ch = edit->columnToChar(vLine,col); - area->beginX = edit->charToColumn(vLine-1, sLine,ch); - area->endX = edit->charToColumn(vLine-1, sLine,ch + edit->mInputPreeditString.length()); + area->beginX = mEdit->charToGlyphLeft(vLine, sLine, mEdit->mCaretX); + area->endX = mEdit->charToGlyphLeft(vLine, sLine,mEdit->mCaretX + mEdit->mInputPreeditString.length()); area->type = EditingAreaType::eatUnderLine; area->color = colFG; areaList.append(area); @@ -986,27 +948,27 @@ void QSynEditPainter::paintLines() // necessary because we probably did not scan to the end of the last // line - the internal highlighter range might be wrong. if (vLine == 1) { - edit->mSyntaxer->resetState(); + mEdit->mSyntaxer->resetState(); } else { - edit->mSyntaxer->setState( - edit->mDocument->getSyntaxState(vLine-2)); + mEdit->mSyntaxer->setState( + mEdit->mDocument->getSyntaxState(vLine-2)); } - edit->mSyntaxer->setLine(sLine, vLine - 1); + mEdit->mSyntaxer->setLine(sLine, vLine - 1); // Try to concatenate as many tokens as possible to minimize the count // of ExtTextOut calls necessary. This depends on the selection state // or the line having special colors. For spaces the foreground color // is ignored as well. - mTokenAccu.columns = 0; - nTokenColumnsBefore = 0; + mTokenAccu.width = 0; + tokenLeft = 0; // Test first whether anything of this token is visible. - while (!edit->mSyntaxer->eol()) { - sToken = edit->mSyntaxer->getToken(); + while (!mEdit->mSyntaxer->eol()) { + sToken = mEdit->mSyntaxer->getToken(); // Work-around buggy highlighters which return empty tokens. if (sToken.isEmpty()) { - edit->mSyntaxer->next(); - if (edit->mSyntaxer->eol()) + mEdit->mSyntaxer->next(); + if (mEdit->mSyntaxer->eol()) break; - sToken = edit->mSyntaxer->getToken(); + sToken = mEdit->mSyntaxer->getToken(); // Maybe should also test whether GetTokenPos changed... if (sToken.isEmpty()) { //qDebug()<charToColumn(sLine,edit->mHighlighter->getTokenPos()+1)-1; - nTokenColumnLen = edit->stringColumns(sToken, nTokenColumnsBefore); - if (nTokenColumnsBefore + nTokenColumnLen >= vFirstChar) { - if (nTokenColumnsBefore + nTokenColumnLen >= vLastChar) { - if (nTokenColumnsBefore >= vLastChar) + tokenWidth = mEdit->stringWidth(sToken, tokenLeft); + if ( tokenLeft + tokenWidth >= mLeft) { + if (tokenLeft + tokenWidth >= mRight) { + if (tokenLeft >= mRight) break; //*** BREAK *** - nTokenColumnLen = vLastChar - nTokenColumnsBefore; + tokenWidth = mRight - tokenLeft; } // It's at least partially visible. Get the token attributes now. - attr = edit->mSyntaxer->getTokenAttribute(); + attr = mEdit->mSyntaxer->getTokenAttribute(); + + //rainbow parenthesis if (sToken == "[" || sToken == "(" || sToken == "{" ) { - SyntaxState rangeState = edit->mSyntaxer->getState(); + SyntaxState rangeState = mEdit->mSyntaxer->getState(); getBraceColorAttr(rangeState.bracketLevel +rangeState.braceLevel +rangeState.parenthesisLevel @@ -1036,18 +1000,19 @@ void QSynEditPainter::paintLines() || sToken == ")" || sToken == "}" ){ - SyntaxState rangeState = edit->mSyntaxer->getState(); + SyntaxState rangeState = mEdit->mSyntaxer->getState(); getBraceColorAttr(rangeState.bracketLevel +rangeState.braceLevel +rangeState.parenthesisLevel+1, attr); } - if (bCurrentLine && edit->mInputPreeditString.length()>0) { - int startPos = edit->mSyntaxer->getTokenPos()+1; - int endPos = edit->mSyntaxer->getTokenPos() + sToken.length(); + //input method + if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) { + int startPos = mEdit->mSyntaxer->getTokenPos()+1; + int endPos = mEdit->mSyntaxer->getTokenPos() + sToken.length(); //qDebug()<mCaretX<<":"<mCaretX+edit->mInputPreeditString.length(); - if (!(endPos < edit->mCaretX - || startPos >= edit->mCaretX+edit->mInputPreeditString.length())) { + if (!(endPos < mEdit->mCaretX + || startPos >= mEdit->mCaretX+mEdit->mInputPreeditString.length())) { if (!preeditAttr) { preeditAttr = attr; } else { @@ -1057,21 +1022,21 @@ void QSynEditPainter::paintLines() } bool showGlyph=false; if (attr && attr->tokenType() == TokenType::Space) { - int pos = edit->mSyntaxer->getTokenPos(); + int pos = mEdit->mSyntaxer->getTokenPos(); if (pos==0) { - showGlyph = edit->mOptions.testFlag(eoShowLeadingSpaces); + showGlyph = mEdit->mOptions.testFlag(eoShowLeadingSpaces); } else if (pos+sToken.length()==sLine.length()) { - showGlyph = edit->mOptions.testFlag(eoShowTrailingSpaces); + showGlyph = mEdit->mOptions.testFlag(eoShowTrailingSpaces); } else { - showGlyph = edit->mOptions.testFlag(eoShowInnerSpaces); + showGlyph = mEdit->mOptions.testFlag(eoShowInnerSpaces); } } - addHighlightToken(sToken, nTokenColumnsBefore - (vFirstChar - FirstCol), - nTokenColumnLen, vLine,attr, showGlyph); + addHighlightToken(sToken, tokenLeft, + tokenWidth, vLine,attr, showGlyph); } - nTokenColumnsBefore+=nTokenColumnLen; + tokenLeft+=tokenWidth; // Let the highlighter scan the next token. - edit->mSyntaxer->next(); + mEdit->mSyntaxer->next(); } // // Don't assume HL.GetTokenPos is valid after HL.GetEOL == True. // //nTokenColumnsBefore += edit->stringColumns(sToken,nTokenColumnsBefore); @@ -1091,23 +1056,24 @@ void QSynEditPainter::paintLines() // } // Paint folding - foldRange = edit->foldStartAtLine(vLine); + foldRange = mEdit->foldStartAtLine(vLine); if ((foldRange) && foldRange->collapsed) { - sFold = edit->syntaxer()->foldString(sLine); - nFold = edit->stringColumns(sFold,edit->mDocument->lineWidth(vLine-1)); - attr = edit->mSyntaxer->symbolAttribute(); - getBraceColorAttr(edit->mSyntaxer->getState().braceLevel,attr); - addHighlightToken(sFold,edit->mDocument->lineColumns(vLine-1) - (vFirstChar - FirstCol) - , nFold, vLine, attr,false); + sFold = mEdit->syntaxer()->foldString(sLine); + nFold = mEdit->stringWidth(sFold,mEdit->mDocument->lineWidth(vLine-1)); + attr = mEdit->mSyntaxer->symbolAttribute(); + getBraceColorAttr(mEdit->mSyntaxer->getState().braceLevel,attr); + addHighlightToken( + sFold, mEdit->mDocument->lineWidth(vLine-1) + , nFold, vLine, attr,false); } else { // Draw LineBreak glyph. - if (edit->mOptions.testFlag(eoShowLineBreaks) - && (!bLineSelected) - && (!bSpecialLine) - && (edit->mDocument->lineColumns(vLine-1) < vLastChar)) { + if (mEdit->mOptions.testFlag(eoShowLineBreaks) + && (!mIsLineSelected) + && (!mIsSpecialLine) + && (mEdit->mDocument->lineWidth(vLine-1) < mRight)) { addHighlightToken(LineBreakGlyph, - edit->mDocument->lineColumns(vLine-1) - (vFirstChar - FirstCol), - edit->mDocument->glyphColumns(LineBreakGlyph,0),vLine, edit->mSyntaxer->whitespaceAttribute(),false); + mEdit->mDocument->lineWidth(vLine-1), + mEdit->mDocument->glyphWidth(LineBreakGlyph,0),vLine, mEdit->mSyntaxer->whitespaceAttribute(),false); } } // Draw anything that's left in the TokenAccu record. Fill to the end @@ -1116,23 +1082,22 @@ void QSynEditPainter::paintLines() //Paint editingAreaBorders foreach (const PEditingArea& area, areaList) { - if (bCurrentLine && edit->mInputPreeditString.length()>0) { - if (area->beginX > edit->mCaretX) { - area->beginX+=edit->mInputPreeditString.length(); + if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) { + if (area->beginX > mEdit->mCaretX) { + area->beginX += mEdit->mInputPreeditString.length(); } - if (area->endX > edit->mCaretX) { - area->endX+=edit->mInputPreeditString.length(); + if (area->endX > mEdit->mCaretX) { + area->endX += mEdit->mInputPreeditString.length(); } } - area->beginX = edit->charToColumn(vLine-1, sLine, area->beginX); - area->endX = edit->charToColumn(vLine-1,sLine,area->endX); + area->beginX = mEdit->charToGlyphLeft(vLine, sLine, area->beginX); + area->endX = mEdit->charToGlyphLeft(vLine,sLine,area->endX); } - if (bCurrentLine && edit->mInputPreeditString.length()>0) { + //input method + if (mIsCurrentLine && mEdit->mInputPreeditString.length()>0) { PEditingArea area = std::make_shared(); - int col = edit->charToColumn(edit->mCaretY,edit->mCaretX); - int ch = edit->columnToChar(vLine,col); - area->beginX = edit->charToColumn(vLine-1,sLine,ch); - area->endX = edit->charToColumn(vLine-1,sLine,ch + edit->mInputPreeditString.length()); + area->beginX = mEdit->charToGlyphLeft(vLine,sLine, mEdit->mCaretX); + area->endX = mEdit->charToGlyphLeft(vLine,sLine,mEdit->mCaretX + mEdit->mInputPreeditString.length()); area->type = EditingAreaType::eatUnderLine; if (preeditAttr) { area->color = preeditAttr->foreground(); @@ -1148,10 +1113,10 @@ void QSynEditPainter::paintLines() // the flicker. Should not cost very much anyway, compared to the many // calls to ExtTextOut. if (bDoRightEdge) { - painter->setPen(edit->mRightEdgeColor); - painter->drawLine(nRightEdge, rcLine.top(),nRightEdge,rcLine.bottom()+1); + mPainter->setPen(mEdit->mRightEdgeColor); + mPainter->drawLine(nRightEdge, rcLine.top(),nRightEdge,rcLine.bottom()+1); } - bCurrentLine = false; + mIsCurrentLine = false; } } } diff --git a/libs/qsynedit/qsynedit/painter.h b/libs/qsynedit/qsynedit/painter.h index bd9fe636..0688ce0e 100644 --- a/libs/qsynedit/qsynedit/painter.h +++ b/libs/qsynedit/qsynedit/painter.h @@ -29,8 +29,8 @@ class QSynEdit; class QSynEditPainter { struct SynTokenAccu { - int columns; - int columnsBefore; + int width; + int left; QString s; QColor foreground; QColor background; @@ -39,8 +39,10 @@ class QSynEditPainter }; public: - QSynEditPainter(QSynEdit * edit,QPainter* painter,int FirstRow, int LastRow, - int FirstCol, int LastCol); + QSynEditPainter(QSynEdit * edit,QPainter* painter, + int firstRow, + int lastRow, + int left, int right); QSynEditPainter(const QSynEditPainter&)=delete; QSynEditPainter& operator=(const QSynEditPainter&)=delete; @@ -51,45 +53,45 @@ private: QColor colEditorBG(); void computeSelectionInfo(); void setDrawingColors(bool selected); - int columnToXValue(int col); - void paintToken(const QString& token, int tokenLen, int columnsBefore, + int fixXValue(int xpos); + void paintToken(const QString& token, int tokenWidth, int tokenLeft, int first, int last, bool isSelection, const QFont& font, const QFont& fontForNonAscii, bool showGlyphs); void paintEditAreas(const EditingAreaList& areaList); void paintHighlightToken(bool bFillToEOL); - void addHighlightToken(const QString& token, int columnsBefore, int tokenColumns, - int cLine, PTokenAttribute p_Attri, bool showGlyphs); + void addHighlightToken(const QString& token, int tokenLeft, int tokenWidth, + int line, PTokenAttribute p_Attri, bool showGlyphs); void paintFoldAttributes(); void getBraceColorAttr(int level, PTokenAttribute &attr); void paintLines(); private: - QSynEdit* edit; - QPainter* painter; + QSynEdit* mEdit; + QPainter* mPainter; bool bDoRightEdge; // right edge int nRightEdge; // selection info bool bAnySelection; // any selection visible? - DisplayCoord vSelStart; // start of selected area - DisplayCoord vSelEnd; // end of selected area + DisplayCoord mSelStart; // start of selected area + DisplayCoord mSelEnd; // end of selected area // info about normal and selected text and background colors - bool bSpecialLine, bLineSelected, bCurrentLine; + bool mIsSpecialLine, mIsLineSelected, mIsCurrentLine; QColor colFG, colBG; QColor colSelFG, colSelBG; QColor colSpFG, colSpBG; // info about selection of the current line - int nLineSelStart, nLineSelEnd; - bool bComplexLine; + int mLineSelStart, mLineSelEnd; + bool mIsComplexLine; // painting the background and the text QRect rcLine, rcToken; - int vFirstLine, vLastLine; + int mFirstLine, mLastLine; - QRect AClip; - int aFirstRow, aLastRow, FirstCol, LastCol; + QRect mClip; + int mFirstRow, mLastRow, mLeft, mRight; SynTokenAccu mTokenAccu; - static QSet operatorGlyphs; + static QSet OperatorGlyphs; }; } diff --git a/libs/qsynedit/qsynedit/qsynedit.cpp b/libs/qsynedit/qsynedit/qsynedit.cpp index d3749bc7..229e17ec 100644 --- a/libs/qsynedit/qsynedit/qsynedit.cpp +++ b/libs/qsynedit/qsynedit/qsynedit.cpp @@ -121,7 +121,7 @@ QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent), mWantReturns = true; mWantTabs = false; - mLeftChar = 0; + mLeftPos = 0; mTopLine = 1; mCaretX = 1; mLastCaretColumn = 1; @@ -327,13 +327,13 @@ bool QSynEdit::canRedo() const int QSynEdit::maxScrollWidth() const { - int maxLen = mDocument->longestLineWidth(); + int maxWidth = mDocument->longestLineWidth(); if (syntaxer()) - maxLen += stringWidth(syntaxer()->foldString(""),maxLen); + maxWidth += stringWidth(syntaxer()->foldString(""),maxWidth); if (mOptions.testFlag(eoScrollPastEol)) - return std::max(maxLen ,1); + return std::max(maxWidth ,1); else - return std::max(maxLen-mCharsInWindow+1, 1); + return std::max(maxWidth-viewWidth()+mCharWidth, 1); } bool QSynEdit::getTokenAttriAtRowCol(const BufferCoord &pos, QString &token, PTokenAttribute &attri) @@ -425,7 +425,8 @@ void QSynEdit::addCaretToUndo() void QSynEdit::addLeftTopToUndo() { BufferCoord p; - p.ch = leftChar(); + //todo: use buffer coord to save left pos is ugly + p.ch = leftPos(); p.line = topLine(); mUndoList->addChange(ChangeReason::LeftTop,p,p,QStringList(), mActiveSelectionMode); } @@ -643,7 +644,7 @@ bool QSynEdit::pointToCharLine(const QPoint &point, BufferCoord &coord) return false; } - coord = displayToBufferPos(pixelsToRowColumn(point.x(),point.y())); + coord = displayToBufferPos(pixelsToGlyphPos(point.x(),point.y())); return true; } @@ -716,25 +717,38 @@ void QSynEdit::invalidateGutterLines(int FirstLine, int LastLine) * @return */ -DisplayCoord QSynEdit::pixelsToNearestRowColumn(int aX, int aY) const +DisplayCoord QSynEdit::pixelsToNearestGlyphPos(int aX, int aY) const { - return { - std::max(1, (int)(mLeftChar + round((aX - mGutterWidth - 2.0) / mCharWidth))), - std::max(1, mTopLine + (aY / mTextHeight)) - }; + int xpos = std::max(0, leftPos() + aX - mGutterWidth - 2); + int row = yposToRow(aY); + int line = rowToLine(row); + if (line<1 || line > mDocument->count() ) + return DisplayCoord{-1,-1}; + if (xpos<0 || xpos>mDocument->lineWidth(line-1)) + return DisplayCoord{-1,-1}; + int glyphIndex = mDocument->xposToGlyphIndex(line-1, xpos); + xpos = mDocument->glyphStartPostion(line-1, glyphIndex); + return DisplayCoord{xpos, row}; } -DisplayCoord QSynEdit::pixelsToRowColumn(int aX, int aY) const +DisplayCoord QSynEdit::pixelsToGlyphPos(int aX, int aY) const { - int line = std::max(1, mTopLine + (aY / mTextHeight)); - int col = std::max(1, (int)(mLeftChar + (aX - mGutterWidth - 2.0) / mCharWidth)); - return DisplayCoord{col, line}; + int xpos = std::max(0, leftPos() + aX - mGutterWidth - 2); + int row = yposToRow(aY); + int line = rowToLine(row); + if (line<1 || line > mDocument->count() ) + return DisplayCoord{-1,-1}; + if (xpos<0 || xpos>mDocument->lineWidth(line-1)) + return DisplayCoord{-1,-1}; + int glyphIndex = mDocument->xposToGlyphIndex(line-1, xpos); + xpos = mDocument->glyphStartPostion(line-1, glyphIndex); + return DisplayCoord{xpos, row}; } -QPoint QSynEdit::rowColumnToPixels(const DisplayCoord &coord) const +QPoint QSynEdit::displayCoordToPixels(const DisplayCoord &coord) const { QPoint result; - result.setX((coord.x - 1) * mCharWidth + textOffset()); + result.setX(coord.x + textOffset()); result.setY((coord.row - mTopLine) * mTextHeight); return result; } @@ -748,6 +762,8 @@ QPoint QSynEdit::rowColumnToPixels(const DisplayCoord &coord) const DisplayCoord QSynEdit::bufferToDisplayPos(const BufferCoord &p) const { DisplayCoord result {p.ch,p.line}; + if (p.line<1) + return result; // Account for tabs and charColumns if (p.line-1 count()) result.x = charToGlyphLeft(p.line,p.ch); @@ -764,15 +780,17 @@ DisplayCoord QSynEdit::bufferToDisplayPos(const BufferCoord &p) const */ BufferCoord QSynEdit::displayToBufferPos(const DisplayCoord &p) const { - BufferCoord Result{p.x,p.row}; + BufferCoord result{p.x,p.row}; + if (p.row<1) + return result; // Account for code folding if (mUseCodeFolding) - Result.line = foldRowToLine(p.row); + result.line = foldRowToLine(p.row); // Account for tabs - if (Result.line <= mDocument->count() ) { - Result.ch = xposToGlyphStartChar(Result.line,p.x); + if (result.line <= mDocument->count() ) { + result.ch = xposToGlyphStartChar(result.line,p.x); } - return Result; + return result; } //ContentsCoord SynEdit::fromBufferCoord(const BufferCoord &p) const @@ -866,6 +884,20 @@ int QSynEdit::xposToGlyphStartChar(int line, const QString &s, int xpos) const return mDocument->xposToGlyphStartChar(line-1,s,xpos)+1; } +int QSynEdit::xposToGlyphLeft(int line, int xpos) const +{ + Q_ASSERT(line>=1 && line <= mDocument->count()); + int glyphIndex = mDocument->xposToGlyphIndex(line-1,xpos); + return mDocument->glyphStartPostion(line-1,glyphIndex); +} + +// int QSynEdit::xposToGlyphRight(int line, int xpos) const +// { +// Q_ASSERT(line>=1 && line <= mDocument->count()); +// int glyphIndex = mDocument->xposToGlyphIndex(line-1,xpos); +// return mDocument->glyphStartPostion(line-1,glyphIndex) + mDocument->glyphLength(line-1,glyphIndex)+1; +// } + int QSynEdit::stringWidth(const QString &line, int left) const { return mDocument->stringWidth(line, left); @@ -903,9 +935,9 @@ int QSynEdit::lineToRow(int aLine) const return bufferToDisplayPos({1, aLine}).row; } -int QSynEdit::foldRowToLine(int Row) const +int QSynEdit::foldRowToLine(int row) const { - int result = Row; + int result = row; for (int i=0;icount();i++) { PCodeFoldingRange range = (*mAllFoldRanges)[i]; if (range->collapsed && !range->parentCollapsed() && range->fromLine < result) { @@ -915,18 +947,18 @@ int QSynEdit::foldRowToLine(int Row) const return result; } -int QSynEdit::foldLineToRow(int Line) const +int QSynEdit::foldLineToRow(int line) const { - int result = Line; + int result = line; for (int i=mAllFoldRanges->count()-1;i>=0;i--) { PCodeFoldingRange range =(*mAllFoldRanges)[i]; if (range->collapsed && !range->parentCollapsed()) { // Line is found after fold - if (range->toLine < Line) + if (range->toLine < line) result -= range->linesCollapsed; // Inside fold - else if (range->fromLine < Line && Line <= range->toLine) - result -= Line - range->fromLine; + else if (range->fromLine < line && line <= range->toLine) + result -= line - range->fromLine; } } return result; @@ -942,21 +974,21 @@ void QSynEdit::setExtraKeystrokes() mKeyStrokes.setExtraKeyStrokes(); } -void QSynEdit::invalidateLine(int Line) +void QSynEdit::invalidateLine(int line) { QRect rcInval; if (mPainterLock >0) return; - if (Line<1 || (Line>mDocument->count() && - Line!=1) || !isVisible()) + if (line<1 || (line>mDocument->count() && + line!=1) || !isVisible()) return; // invalidate text area of this line if (mUseCodeFolding) - Line = foldLineToRow(Line); - if (Line >= mTopLine && Line <= mTopLine + mLinesInWindow) { + line = foldLineToRow(line); + if (line >= mTopLine && line <= mTopLine + mLinesInWindow) { rcInval = { mGutterWidth, - mTextHeight * (Line - mTopLine), + mTextHeight * (line - mTopLine), clientWidth(), mTextHeight}; if (mStateFlags.testFlag(StateFlag::sfLinesChanging)) @@ -966,14 +998,14 @@ void QSynEdit::invalidateLine(int Line) } } -void QSynEdit::invalidateLines(int FirstLine, int LastLine) +void QSynEdit::invalidateLines(int firstLine, int lastLine) { if (mPainterLock>0) return; if (!isVisible()) return; - if (FirstLine == -1 && LastLine == -1) { + if (firstLine == -1 && lastLine == -1) { QRect rcInval = clientRect(); rcInval.setLeft(rcInval.left()+mGutterWidth); if (mStateFlags.testFlag(StateFlag::sfLinesChanging)) { @@ -982,34 +1014,34 @@ void QSynEdit::invalidateLines(int FirstLine, int LastLine) invalidateRect(rcInval); } } else { - FirstLine = std::max(FirstLine, 1); - LastLine = std::max(LastLine, 1); + firstLine = std::max(firstLine, 1); + lastLine = std::max(lastLine, 1); // find the visible lines first - if (LastLine < FirstLine) - std::swap(LastLine, FirstLine); + if (lastLine < firstLine) + std::swap(lastLine, firstLine); - if (LastLine >= mDocument->count()) - LastLine = INT_MAX; // paint empty space beyond last line + if (lastLine >= mDocument->count()) + lastLine = INT_MAX; // paint empty space beyond last line if (mUseCodeFolding) { - FirstLine = lineToRow(FirstLine); + firstLine = lineToRow(firstLine); // Could avoid this conversion if (First = Last) and // (Length < CharsInWindow) but the dependency isn't worth IMO. - if (LastLine < mDocument->count()) - LastLine = lineToRow(LastLine + 1) - 1; + if (lastLine < mDocument->count()) + lastLine = lineToRow(lastLine + 1) - 1; } // mTopLine is in display coordinates, so FirstLine and LastLine must be // converted previously. - FirstLine = std::max(FirstLine, mTopLine); - LastLine = std::min(LastLine, mTopLine + mLinesInWindow); + firstLine = std::max(firstLine, mTopLine); + lastLine = std::min(lastLine, mTopLine + mLinesInWindow); // any line visible? - if (LastLine >= FirstLine) { + if (lastLine >= firstLine) { QRect rcInval = { clientLeft()+mGutterWidth, - mTextHeight * (FirstLine - mTopLine), - clientWidth(), mTextHeight * (LastLine - mTopLine + 1) + mTextHeight * (firstLine - mTopLine), + clientWidth(), mTextHeight * (lastLine - mTopLine + 1) }; if (mStateFlags.testFlag(StateFlag::sfLinesChanging)) mInvalidateRect = mInvalidateRect.united(rcInval); @@ -1202,8 +1234,8 @@ void QSynEdit::processGutterClick(QMouseEvent *event) { int x = event->pos().x(); int y = event->pos().y(); - DisplayCoord rowColumn = pixelsToNearestRowColumn(x, y); - int line = rowToLine(rowColumn.row); + int row = yposToRow(y); + int line = rowToLine(row); // Check if we clicked on a folding thing if (mUseCodeFolding) { @@ -1214,7 +1246,7 @@ void QSynEdit::processGutterClick(QMouseEvent *event) QRect rect; rect.setLeft(mGutterWidth - mGutter.rightOffset()); rect.setRight(rect.left() + mGutter.rightOffset() - 4); - rect.setTop((rowColumn.row - mTopLine) * mTextHeight); + rect.setTop((row - mTopLine) * mTextHeight); rect.setBottom(rect.top() + mTextHeight - 1); if (rect.contains(event->pos())) { if (foldRange->collapsed) @@ -1728,32 +1760,33 @@ void QSynEdit::doMouseScroll(bool isDragging) if (!buttons.testFlag(Qt::LeftButton)) return; QPoint iMousePos; - DisplayCoord C; - int X, Y; + DisplayCoord coord; iMousePos = QCursor::pos(); iMousePos = mapFromGlobal(iMousePos); - C = pixelsToNearestRowColumn(iMousePos.x(), iMousePos.y()); - C.row = minMax(C.row, 1, displayLineCount()); + coord = pixelsToNearestGlyphPos(iMousePos.x(), iMousePos.y()); + coord.row = minMax(coord.row, 1, displayLineCount()); if (mScrollDeltaX != 0) { - setLeftChar(leftChar() + mScrollDeltaX * mMouseSelectionScrollSpeed); - X = leftChar(); + int x; + setLeftPos(leftPos() + mScrollDeltaX * mMouseSelectionScrollSpeed); + x = leftPos(); if (mScrollDeltaX > 0) // scrolling right? - X+=charsInWindow(); - C.x = X; + x+=viewWidth(); + coord.x = x; } if (mScrollDeltaY != 0) { + int y; //qDebug()< 0) // scrolling down? - Y+=mLinesInWindow - 1; - C.row = minMax(Y, 1, displayLineCount()); + y+=mLinesInWindow - 1; + coord.row = minMax(y, 1, displayLineCount()); } - BufferCoord vCaret = displayToBufferPos(C); + BufferCoord vCaret = displayToBufferPos(coord); if ((caretX() != vCaret.ch) || (caretY() != vCaret.line)) { // changes to line / column in one go incPaintLock(); @@ -2469,7 +2502,7 @@ QRect QSynEdit::calculateCaretRect() const QString sLine = lineText().left(mCaretX-1) + mInputPreeditString + lineText().mid(mCaretX-1); - coord.x = charToGlyphLeft(mCaretY-1, sLine,mCaretX+mInputPreeditString.length()); + coord.x = charToGlyphLeft(mCaretY, sLine,mCaretX+mInputPreeditString.length()); } int rows=1; if (mActiveSelectionMode == SelectionMode::Column) { @@ -2478,13 +2511,13 @@ QRect QSynEdit::calculateCaretRect() const coord.row = startRow; rows = endRow-startRow+1; } - QPoint caretPos = rowColumnToPixels(coord); - int caretWidth=mCharWidth; + QPoint caretPos = displayCoordToPixels(coord); + int caretWidth = mCharWidth; if (mCaretY <= mDocument->count() && mCaretX <= mDocument->getLine(mCaretY-1).length()) { int glyphIndex = mDocument->charToGlyphIndex(mCaretY-1, mCaretX-1); - QString glyph = mDocument->glyph(mCaretY-1, glyphIndex); caretWidth = mDocument->glyphWidth(mCaretY-1, glyphIndex); } +// qDebug()<<"caret:"<count() && mCaretX <= mDocument->getLine(mCaretY-1).length()) { int glyphIndex = mDocument->charToGlyphIndex(mCaretY-1, mCaretX-1); - QString glyph = mDocument->glyph(mCaretY-1, glyphIndex); caretWidth = mDocument->glyphWidth(mCaretY-1, glyphIndex); } return QRect(caretPos.x(),caretPos.y(),caretWidth, @@ -2517,10 +2549,10 @@ void QSynEdit::computeCaret() { QPoint iMousePos = QCursor::pos(); iMousePos = mapFromGlobal(iMousePos); - int X=iMousePos.x(); - int Y=iMousePos.y(); + int x=iMousePos.x(); + int y=iMousePos.y(); - DisplayCoord vCaretNearestPos = pixelsToNearestRowColumn(X, Y); + DisplayCoord vCaretNearestPos = pixelsToNearestGlyphPos(x, y); vCaretNearestPos.row = minMax(vCaretNearestPos.row, 1, displayLineCount()); setInternalDisplayXY(vCaretNearestPos); } @@ -2969,27 +3001,27 @@ void QSynEdit::decPaintLock() } } -int QSynEdit::clientWidth() +int QSynEdit::clientWidth() const { return viewport()->size().width(); } -int QSynEdit::clientHeight() +int QSynEdit::clientHeight() const { return viewport()->size().height(); } -int QSynEdit::clientTop() +int QSynEdit::clientTop() const { return 0; } -int QSynEdit::clientLeft() +int QSynEdit::clientLeft() const { return 0; } -QRect QSynEdit::clientRect() +QRect QSynEdit::clientRect() const { return QRect(0,0, clientWidth(), clientHeight()); } @@ -3018,13 +3050,13 @@ void QSynEdit::ensureCursorPosVisibleEx(bool ForceToMiddle) decPaintLock(); }); // Make sure X is visible - int VisibleX = displayX(); - if (VisibleX < leftChar()) - setLeftChar(VisibleX); - else if (VisibleX >= mCharsInWindow + leftChar() && mCharsInWindow > 0) - setLeftChar(VisibleX - mCharsInWindow + 1); + int visibleX = displayX(); + if (visibleX < leftPos()) + setLeftPos(visibleX); + else if (visibleX >= viewWidth() + leftPos() && viewWidth()>0) + setLeftPos(visibleX - viewWidth() + 1); else - setLeftChar(leftChar()); + setLeftPos(leftPos()); // Make sure Y is visible int vCaretRow = displayY(); if (ForceToMiddle) { @@ -3107,8 +3139,8 @@ void QSynEdit::updateScrollbars() nMaxScroll = maxScrollWidth(); nMin = 1; nMax = nMaxScroll; - nPage = mCharsInWindow; - nPos = mLeftChar; + nPage = viewWidth(); + nPos = mLeftPos; horizontalScrollBar()->setMinimum(nMin); horizontalScrollBar()->setMaximum(nMax); horizontalScrollBar()->setPageStep(nPage); @@ -3727,7 +3759,7 @@ void QSynEdit::paintCaret(QPainter &painter, const QRect rcClip) int QSynEdit::textOffset() const { - return mGutterWidth + 2 - (mLeftChar-1)*mCharWidth; + return mGutterWidth + 2 - mLeftPos; } EditCommand QSynEdit::TranslateKeyCode(int key, Qt::KeyboardModifiers modifiers) @@ -3754,9 +3786,7 @@ EditCommand QSynEdit::TranslateKeyCode(int key, Qt::KeyboardModifiers modifiers) void QSynEdit::onSizeOrFontChanged(bool bFont) { - if (mCharWidth != 0) { - mCharsInWindow = std::max(clientWidth() - mGutterWidth - 2, 0) / mCharWidth; mLinesInWindow = clientHeight() / mTextHeight; bool scrollBarChangedSettings = mStateFlags.testFlag(StateFlag::sfScrollbarChanged); if (bFont) { @@ -3770,7 +3800,7 @@ void QSynEdit::onSizeOrFontChanged(bool bFont) updateScrollbars(); mStateFlags.setFlag(StateFlag::sfScrollbarChanged,scrollBarChangedSettings); //if (!mOptions.testFlag(SynEditorOption::eoScrollPastEol)) - setLeftChar(mLeftChar); + setLeftPos(mLeftPos); //if (!mOptions.testFlag(SynEditorOption::eoScrollPastEof)) setTopLine(mTopLine); } @@ -3783,7 +3813,7 @@ void QSynEdit::onChanged() void QSynEdit::onScrolled(int) { - mLeftChar = horizontalScrollBar()->value(); + mLeftPos = horizontalScrollBar()->value(); mTopLine = verticalScrollBar()->value(); invalidate(); } @@ -4051,7 +4081,7 @@ void QSynEdit::setOptions(const EditorOptions &Value) if (Value != mOptions) { //bool bSetDrag = mOptions.testFlag(eoDropFiles) != Value.testFlag(eoDropFiles); //if (!mOptions.testFlag(eoScrollPastEol)) - setLeftChar(mLeftChar); + setLeftPos(mLeftPos); //if (!mOptions.testFlag(eoScrollPastEof)) setTopLine(mTopLine); @@ -4176,7 +4206,7 @@ void QSynEdit::doUndoItem() break; case ChangeReason::LeftTop: BufferCoord p; - p.ch = leftChar(); + p.ch = leftPos(); p.line = topLine(); mRedoList->addRedo( item->changeReason(), @@ -4184,7 +4214,7 @@ void QSynEdit::doUndoItem() p, QStringList(), item->changeSelMode(), item->changeNumber()); - setLeftChar(item->changeStartPos().ch); + setLeftPos(item->changeStartPos().ch); setTopLine(item->changeStartPos().line); break; case ChangeReason::Selection: @@ -4372,7 +4402,7 @@ void QSynEdit::doRedoItem() break; case ChangeReason::LeftTop: BufferCoord p; - p.ch = leftChar(); + p.ch = leftPos(); p.line = topLine(); mUndoList->restoreChange( item->changeReason(), @@ -4380,7 +4410,7 @@ void QSynEdit::doRedoItem() p, QStringList(), item->changeSelMode(), item->changeNumber()); - setLeftChar(item->changeStartPos().ch); + setLeftPos(item->changeStartPos().ch); setTopLine(item->changeStartPos().line); break; case ChangeReason::Selection: @@ -5657,11 +5687,11 @@ void QSynEdit::executeCommand(EditCommand command, QChar ch, void *pData) break; case EditCommand::PageLeft: case EditCommand::SelPageLeft: - moveCaretHorz(-mCharsInWindow, command == EditCommand::SelPageLeft); + moveCaretHorz(-viewWidth(), command == EditCommand::SelPageLeft); break; case EditCommand::PageRight: case EditCommand::SelPageRight: - moveCaretHorz(mCharsInWindow, command == EditCommand::SelPageRight); + moveCaretHorz(viewWidth(), command == EditCommand::SelPageRight); break; case EditCommand::LineStart: case EditCommand::SelLineStart: @@ -5982,13 +6012,14 @@ void QSynEdit::updateMouseCursor(){ bool QSynEdit::isCaretVisible() { - if (mCaretY < mTopLine) + DisplayCoord caret = displayXY(); + if (caret.row < mTopLine) return false; - if (mCaretY >= mTopLine + mLinesInWindow ) + if (caret.row >= mTopLine + mLinesInWindow ) return false; - if (mCaretX < mLeftChar) + if (caret.x < mLeftPos) return false; - if (mCaretX >= mLeftChar + mCharsInWindow) + if (caret.x >= mLeftPos + viewWidth()) return false; return true; } @@ -6023,14 +6054,13 @@ void QSynEdit::paintEvent(QPaintEvent *event) painter.drawImage(rcCaret,*mContentImage,cacheRC); } else { QRect rcDraw; - int nL1, nL2, nC1, nC2; + int nL1, nL2, nX1, nX2; // Compute the invalid area in lines / columns. // columns - nC1 = mLeftChar; + nX1 = mLeftPos; if (rcClip.left() > mGutterWidth + 2 ) - nC1 += (rcClip.left() - mGutterWidth - 2 ) / mCharWidth; - nC2 = mLeftChar + - (rcClip.right() - mGutterWidth - 2 + mCharWidth - 1) / mCharWidth; + nX1 += (rcClip.left() - mGutterWidth - 2 ) ; + nX2 = mLeftPos + (rcClip.right() - mGutterWidth - 2); // lines nL1 = minMax(mTopLine + rcClip.top() / mTextHeight, mTopLine, displayLineCount()); nL2 = minMax(mTopLine + (rcClip.bottom() + mTextHeight - 1) / mTextHeight, 1, displayLineCount()); @@ -6040,7 +6070,7 @@ void QSynEdit::paintEvent(QPaintEvent *event) QPainter cachePainter(mContentImage.get()); cachePainter.setFont(font()); QSynEditPainter textPainter(this, &cachePainter, - nL1,nL2,nC1,nC2); + nL1,nL2,nX1,nX2); // First paint paint the text area if it was (partly) invalidated. if (rcClip.right() > mGutterWidth ) { rcDraw = rcClip; @@ -6175,7 +6205,7 @@ void QSynEdit::mousePressEvent(QMouseEvent *event) BufferCoord oldCaret=caretXY(); if (button == Qt::RightButton) { if (mOptions.testFlag(eoRightMouseMovesCursor) && - ( (selAvail() && ! isPointInSelection(displayToBufferPos(pixelsToRowColumn(X, Y)))) + ( (selAvail() && ! isPointInSelection(displayToBufferPos(pixelsToGlyphPos(X, Y)))) || ! selAvail())) { invalidateSelection(); //mBlockEnd=mBlockBegin; @@ -6192,7 +6222,7 @@ void QSynEdit::mousePressEvent(QMouseEvent *event) computeCaret(); mStateFlags.setFlag(StateFlag::sfWaitForDragging,false); if (bWasSel && mOptions.testFlag(eoDragDropEditing) && (X >= mGutterWidth + 2) - && (mActiveSelectionMode == SelectionMode::Normal) && isPointInSelection(displayToBufferPos(pixelsToRowColumn(X, Y))) ) { + && (mActiveSelectionMode == SelectionMode::Normal) && isPointInSelection(displayToBufferPos(pixelsToGlyphPos(X, Y))) ) { bStartDrag = true; } if (bStartDrag && !mReadOnly) { @@ -6393,7 +6423,7 @@ void QSynEdit::dragEnterEvent(QDragEnterEvent *event) mDragCaretSave = caretXY(); mDragSelBeginSave = blockBegin(); mDragSelEndSave = blockEnd(); - BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(), + BufferCoord coord = displayToBufferPos(pixelsToNearestGlyphPos(event->pos().x(), event->pos().y())); internalSetCaretXY(coord); setBlockBegin(mDragSelBeginSave); @@ -6408,7 +6438,7 @@ void QSynEdit::dropEvent(QDropEvent *event) { //mScrollTimer->stop(); - BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(), + BufferCoord coord = displayToBufferPos(pixelsToNearestGlyphPos(event->pos().x(), event->pos().y())); if ( (event->proposedAction() == Qt::DropAction::CopyAction @@ -6432,7 +6462,7 @@ void QSynEdit::dropEvent(QDropEvent *event) coord = ensureBufferCoordValid(coord); bool lastLineUsed = coord.line == mDocument->count(); int topLine = mTopLine; - int leftChar = mLeftChar; + int leftPos = mLeftPos; int line=mDocument->count()-1; QString s=mDocument->getLine(line-1); QStringList text=splitStrings(event->mimeData()->text()); @@ -6495,7 +6525,7 @@ void QSynEdit::dropEvent(QDropEvent *event) event->acceptProposedAction(); mDropped = true; setTopLine(topLine); - setLeftChar(leftChar); + setLeftPos(leftPos); internalSetCaretXY(coord); } @@ -6512,9 +6542,9 @@ void QSynEdit::dragMoveEvent(QDragMoveEvent *event) QPoint iMousePos = QCursor::pos(); iMousePos = mapFromGlobal(iMousePos); - int X=iMousePos.x(); - int Y=iMousePos.y(); - BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(X,Y)); + int x=iMousePos.x(); + int y=iMousePos.y(); + BufferCoord coord = displayToBufferPos(pixelsToNearestGlyphPos(x,y)); internalSetCaretXY(coord); setBlockBegin(mDragSelBeginSave); setBlockEnd(mDragSelEndSave); @@ -6580,11 +6610,6 @@ void QSynEdit::setGutterWidth(int Value) } } -int QSynEdit::charWidth() const -{ - return mCharWidth; -} - void QSynEdit::setUndoLimit(int size) { mUndoList->setMaxUndoActions(size); @@ -6596,11 +6621,6 @@ void QSynEdit::setUndoMemoryUsage(int size) // mUndoList->setMaxMemoryUsage(size*1024); } -int QSynEdit::charsInWindow() const -{ - return mCharsInWindow; -} - void QSynEdit::onBookMarkOptionsChanged() { invalidateGutter(); @@ -6653,7 +6673,7 @@ void QSynEdit::onLinesCleared() setCaretXY({1,1}); // scroll to start of text setTopLine(1); - setLeftChar(1); + setLeftPos(0); mStatusChanges.setFlag(StatusChange::scAll); } @@ -6902,19 +6922,19 @@ void QSynEdit::setBlockBegin(BufferCoord value) setStatusChanged(StatusChange::scSelection); } -int QSynEdit::leftChar() const +int QSynEdit::leftPos() const { - return mLeftChar; + return mLeftPos; } -void QSynEdit::setLeftChar(int Value) +void QSynEdit::setLeftPos(int value) { //int MaxVal; //QRect iTextArea; - Value = std::min(Value,maxScrollWidth()); - if (Value != mLeftChar) { - horizontalScrollBar()->setValue(Value); - setStatusChanged(StatusChange::scLeftChar); + value = std::min(value,maxScrollWidth()); + if (value != mLeftPos) { + horizontalScrollBar()->setValue(value); + setStatusChanged(StatusChange::scLeftPos); } } diff --git a/libs/qsynedit/qsynedit/qsynedit.h b/libs/qsynedit/qsynedit/qsynedit.h index 9a2a0350..1921dc8a 100644 --- a/libs/qsynedit/qsynedit/qsynedit.h +++ b/libs/qsynedit/qsynedit/qsynedit.h @@ -47,7 +47,7 @@ enum StatusChange { scAll = 0x0001, scCaretX = 0x0002, scCaretY = 0x0004, - scLeftChar = 0x0008, + scLeftPos = 0x0008, scTopLine = 0x0010, scInsertMode = 0x0020, scModifyChanged = 0x0040, @@ -161,9 +161,14 @@ public: void invalidateGutter(); void invalidateGutterLine(int aLine); void invalidateGutterLines(int FirstLine, int LastLine); - DisplayCoord pixelsToNearestRowColumn(int aX, int aY) const; - DisplayCoord pixelsToRowColumn(int aX, int aY) const; - QPoint rowColumnToPixels(const DisplayCoord& coord) const; + + int yposToRow(int y) const { + return std::max(1, mTopLine + (y / mTextHeight)); + } + + DisplayCoord pixelsToNearestGlyphPos(int aX, int aY) const; + DisplayCoord pixelsToGlyphPos(int aX, int aY) const; + QPoint displayCoordToPixels(const DisplayCoord& coord) const; DisplayCoord bufferToDisplayPos(const BufferCoord& p) const; BufferCoord displayToBufferPos(const DisplayCoord& p) const; @@ -180,16 +185,18 @@ public: //int charToColumn(const QString& s, int aChar) const; int xposToGlyphStartChar(int line, int xpos) const; int xposToGlyphStartChar(int line, const QString& s, int xpos) const; + int xposToGlyphLeft(int line, int xpos) const; + //int xposToGlyphRight(int line, int xpos) const; int stringWidth(const QString& line, int left) const; int getLineIndent(const QString& line) const; int rowToLine(int aRow) const; int lineToRow(int aLine) const; - int foldRowToLine(int Row) const; - int foldLineToRow(int Line) const; + int foldRowToLine(int row) const; + int foldLineToRow(int line) const; void setDefaultKeystrokes(); void setExtraKeystrokes(); - void invalidateLine(int Line); - void invalidateLines(int FirstLine, int LastLine); + void invalidateLine(int line); + void invalidateLines(int firstLine, int lastLine); void invalidateSelection(); void invalidateRect(const QRect& rect); void invalidate(); @@ -316,8 +323,8 @@ public: int linesInWindow() const; - int leftChar() const; - void setLeftChar(int value); + int leftPos() const; + void setLeftPos(int value); BufferCoord blockBegin() const; BufferCoord blockEnd() const; @@ -331,9 +338,13 @@ public: SelectionMode activeSelectionMode() const; void setActiveSelectionMode(const SelectionMode &Value); - int charsInWindow() const; + int charWidth() const { + return mCharWidth; + } - int charWidth() const; + int viewWidth() const{ + return clientWidth() - mGutterWidth - 2; + } void setUndoLimit(int size); void setUndoMemoryUsage(int size); @@ -354,6 +365,9 @@ public: QString displayLineText(); QString lineText() const; + QString lineText(int line) const { + return mDocument->getLine(line-1); + } void setLineText(const QString s); const PDocument& document() const; @@ -486,11 +500,11 @@ private: void incPaintLock(); void decPaintLock(); - int clientWidth(); - int clientHeight(); - int clientTop(); - int clientLeft(); - QRect clientRect(); + int clientWidth() const; + int clientHeight() const; + int clientTop() const; + int clientLeft() const; + QRect clientRect() const; void synFontChanged(); void doSetSelText(const QString& value); @@ -656,7 +670,6 @@ private: int mCaretX; int mLastCaretColumn; int mCaretY; - int mCharsInWindow; int mCharWidth; QFont mFontDummy; QFont mFontForNonAscii; @@ -667,7 +680,7 @@ private: bool mPainting; PDocument mDocument; int mLinesInWindow; - int mLeftChar; + int mLeftPos; int mPaintLock; // lock counter for internal calculations bool mReadOnly; int mRightEdge;