work save: support don't force fix-width

This commit is contained in:
Roy Qu 2024-02-23 17:51:38 +08:00
parent aa17ec785c
commit 3eadbafe25
10 changed files with 639 additions and 640 deletions

View File

@ -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));

View File

@ -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;

View File

@ -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<QString, PProjectEditorLayout> Project::loadLayout()
PProjectEditorLayout editorLayout = std::make_shared<ProjectEditorLayout>();
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);
}
}

View File

@ -62,7 +62,7 @@ struct ProjectModelNode {
struct ProjectEditorLayout {
QString filename;
int topLine;
int leftChar;
int left;
int caretX;
int caretY;
int order;

View File

@ -371,7 +371,7 @@ std::shared_ptr<SearchResultTreeItem> 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<SearchResultTreeItem>();
parentItem->filename = filename;
@ -394,7 +394,7 @@ std::shared_ptr<SearchResultTreeItem> SearchInFileDialog::batchFindInEditor(QSyn
// restore
e->setCaretXY(caretBackup);
e->setTopLine(toplineBackup);
e->setLeftChar(leftCharBackup);
e->setLeftPos(leftPosBackup);
e->setCaretAndSelection(
caretBackup,
blockBeginBackup,

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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<QString> operatorGlyphs;
static QSet<QString> OperatorGlyphs;
};
}

View File

@ -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 <mDocument->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;i<mAllFoldRanges->count();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()<<mScrollDeltaY;
if (QApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier))
setTopLine(mTopLine + mScrollDeltaY * mLinesInWindow);
else
setTopLine(mTopLine + mScrollDeltaY * mMouseSelectionScrollSpeed);
Y = mTopLine;
y = mTopLine;
if (mScrollDeltaY > 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:"<<mCaretX<<mCaretY<<caretWidth;
if (mActiveSelectionMode == SelectionMode::Column) {
return QRect(caretPos.x(),caretPos.y(),caretWidth,
mTextHeight*(rows));
@ -2497,11 +2530,10 @@ QRect QSynEdit::calculateCaretRect() const
QRect QSynEdit::calculateInputCaretRect() const
{
DisplayCoord coord = displayXY();
QPoint caretPos = rowColumnToPixels(coord);
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);
}
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);
}
}

View File

@ -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;