From aa17ec785c5aa183ac4127da85960c766d139ed5 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 23 Feb 2024 12:41:13 +0800 Subject: [PATCH] work save --- RedPandaIDE/editor.cpp | 10 +- libs/qsynedit/qsynedit/document.cpp | 274 ++++++------- libs/qsynedit/qsynedit/document.h | 149 +++---- .../qsynedit/formatter/cppformatter.cpp | 4 +- libs/qsynedit/qsynedit/painter.cpp | 54 +-- libs/qsynedit/qsynedit/qsynedit.cpp | 387 +++++++++--------- libs/qsynedit/qsynedit/qsynedit.h | 17 +- libs/qsynedit/qsynedit/types.h | 4 +- 8 files changed, 448 insertions(+), 451 deletions(-) diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 22315ea4..387031b5 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -1567,7 +1567,7 @@ void Editor::copyAsHTML() if (!selAvail()) { doSelectLine(); } - QSynedit::HTMLExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding()); + QSynedit::HTMLExporter exporter(tabSize(), pCharsetInfoManager->getDefaultSystemEncoding()); exporter.setTitle(QFileInfo(mFilename).fileName()); exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground()); @@ -3310,7 +3310,7 @@ void Editor::print() return; } - QSynedit::QtSupportedHtmlExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding()); + QSynedit::QtSupportedHtmlExporter exporter(tabSize(), pCharsetInfoManager->getDefaultSystemEncoding()); exporter.setTitle(QFileInfo(mFilename).fileName()); exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground()); @@ -3346,7 +3346,7 @@ void Editor::print() void Editor::exportAsRTF(const QString &rtfFilename) { - QSynedit::RTFExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding()); + QSynedit::RTFExporter exporter(tabSize(), pCharsetInfoManager->getDefaultSystemEncoding()); exporter.setTitle(extractFileName(rtfFilename)); exporter.setUseBackground(pSettings->editor().copyRTFUseBackground()); exporter.setFont(font()); @@ -3370,7 +3370,7 @@ void Editor::exportAsRTF(const QString &rtfFilename) void Editor::exportAsHTML(const QString &htmlFilename) { - QSynedit::HTMLExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding()); + QSynedit::HTMLExporter exporter(tabSize(), pCharsetInfoManager->getDefaultSystemEncoding()); exporter.setTitle(extractFileName(htmlFilename)); exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground()); exporter.setFont(font()); @@ -5267,7 +5267,7 @@ void Editor::applySettings() && syntaxer() && syntaxer()->supportBraceLevel()); setOptions(options); - setTabWidth(pSettings->editor().tabWidth()); + setTabSize(pSettings->editor().tabWidth()); setInsertCaret(pSettings->editor().caretForInsert()); setOverwriteCaret(pSettings->editor().caretForOverwrite()); setCaretUseTextColor(pSettings->editor().caretUseTextColor()); diff --git a/libs/qsynedit/qsynedit/document.cpp b/libs/qsynedit/qsynedit/document.cpp index f9032030..205345e3 100644 --- a/libs/qsynedit/qsynedit/document.cpp +++ b/libs/qsynedit/qsynedit/document.cpp @@ -34,7 +34,7 @@ Document::Document(const QFont& font, const QFont& nonAsciiFont, QObject *parent QObject(parent), mFontMetrics(font), mNonAsciiFontMetrics(nonAsciiFont), - mTabWidth(4), + mTabSize(4), #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) mMutex() #else @@ -81,31 +81,31 @@ int Document::braceLevel(int line) return 0; } -int Document::lineColumns(int line) +int Document::lineWidth(int line) { QMutexLocker locker(&mMutex); if (line>=0 && line < mLines.size()) { - if (mLines[line]->columns() == -1) { - return calculateLineColumns(line); + if (mLines[line]->width() == -1) { + return calculateLineWidth(line); } else - return mLines[line]->columns(); + return mLines[line]->width(); } else return 0; } -int Document::lineColumns(int line, const QString &newText) +int Document::lineWidth(int line, const QString &newText) { QMutexLocker locker(&mMutex); if (line<0 || line >= mLines.size()) return 0; QString lineText = mLines[line]->lineText(); if (lineText==newText) { - if (mLines[line]->columns() == -1) { - return calculateLineColumns(line); + if (mLines[line]->width() == -1) { + return calculateLineWidth(line); } else - return mLines[line]->columns(); + return mLines[line]->width(); } else { - return stringColumns(newText,0); + return stringWidth(newText,0); } } @@ -139,14 +139,14 @@ int Document::blockEnded(int line) return 0; } -int Document::longestLineColumns() { +int Document::longestLineWidth() { QMutexLocker locker(&mMutex); if (mIndexOfLongestLine < 0) { int MaxLen = -1; mIndexOfLongestLine = -1; if (mLines.count() > 0 ) { for (int i=0;i MaxLen) { MaxLen = len; mIndexOfLongestLine = i; @@ -155,7 +155,7 @@ int Document::longestLineColumns() { } } if (mIndexOfLongestLine >= 0) - return mLines[mIndexOfLongestLine]->columns(); + return mLines[mIndexOfLongestLine]->width(); else return 0; } @@ -243,14 +243,14 @@ int Document::getLineGlyphsCount(int line) return mLines[line]->glyphsCount(); } -QList Document::getGlyphPositions(int index) -{ - QMutexLocker locker(&mMutex); - if (index<0 || index>=mLines.count()) { - return QList{}; - } - return mLines[index]->glyphPositions(); -} +// QList Document::getGlyphPositions(int index) +// { +// QMutexLocker locker(&mMutex); +// if (index<0 || index>=mLines.count()) { +// return QList{}; +// } +// return mLines[index]->glyphStartCharList(); +// } int Document::count() { @@ -467,14 +467,14 @@ void Document::putLine(int index, const QString &s, bool notify) { listIndexOutOfBounds(index); } beginUpdate(); - int oldColumns = mLines[index]->columns(); + int oldColumns = mLines[index]->width(); mLines[index]->setLineText( s ); - calculateLineColumns(index); - if (mIndexOfLongestLine == index && oldColumns>mLines[index]->columns() ) + calculateLineWidth(index); + if (mIndexOfLongestLine == index && oldColumns>mLines[index]->width() ) mIndexOfLongestLine = -1; else if (mIndexOfLongestLine>=0 && mIndexOfLongestLinecolumns() > mLines[mIndexOfLongestLine]->columns()) + && mLines[index]->width() > mLines[mIndexOfLongestLine]->width()) mIndexOfLongestLine = index; if (notify) emit putted(index,1); @@ -490,14 +490,14 @@ void Document::setUpdateState(bool Updating) emit changed(); } -int Document::calculateLineColumns(int Index) +int Document::calculateLineWidth(int line) { - PDocumentLine line = mLines[Index]; - QList glyphColumns; - int columns; - glyphColumns = calcGlyphColumns(line->lineText(), line->glyphPositions(), 0, columns); - line->setColumns(columns, glyphColumns); - return line->columns(); + PDocumentLine documentLine = mLines[line]; + QList glyphPositionList; + int width; + glyphPositionList = calcGlyphPositionList(documentLine->lineText(), documentLine->glyphStartCharList(), 0, width); + documentLine->setWidth(width, glyphPositionList); + return documentLine->width(); } void Document::insertLines(int index, int numLines) @@ -606,13 +606,14 @@ void Document::setFontMetrics(const QFont &newFont, const QFont& newNonAsciiFont mFontMetrics = QFontMetrics(newFont); mCharWidth = mFontMetrics.horizontalAdvance("M"); mNonAsciiFontMetrics = QFontMetrics(newNonAsciiFont); + invalidateAllLineWidth(); } -void Document::setTabWidth(int newTabWidth) +void Document::setTabSize(int newTabSize) { - if (mTabWidth!=newTabWidth) { - mTabWidth = newTabWidth; - invalidateAllLineColumns(); + if (mTabSize!=newTabSize) { + mTabSize = newTabSize; + invalidateAllLineWidth(); } } @@ -832,17 +833,17 @@ QString Document::glyph(int line, int glyphIdx) QString Document::glyphAt(int line, int charPos) { QMutexLocker locker(&mMutex); - QList glyphPositions = mLines[line]->glyphPositions(); - int glyphIdx = charToGlyphIndex(glyphPositions, charPos); + QList glyphStartCharList = mLines[line]->glyphStartCharList(); + int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); return mLines[line]->glyph(glyphIdx); } int Document::charToGlyphStartChar(int line, int charPos) { QMutexLocker locker(&mMutex); - QList glyphPositions = mLines[line]->glyphPositions(); - int glyphIdx = charToGlyphIndex(glyphPositions, charPos); - return mLines[line]->glyphStart(glyphIdx); + QList glyphStartCharList = mLines[line]->glyphStartCharList(); + int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); + return mLines[line]->glyphStartChar(glyphIdx); } // int Document::columnToGlyphStartColumn(int line, int charPos) @@ -853,9 +854,9 @@ int Document::charToGlyphStartChar(int line, int charPos) // return mLines[line]->glyphStartColumn(glyphIdx); // } -QList calcGlyphPositions(const QString &text) +QList calcGlyphStartCharList(const QString &text) { - QList glyphPositions; + QList glyphStartCharList; //parse mGlyphs int i=0; bool consecutive = false; @@ -864,47 +865,49 @@ QList calcGlyphPositions(const QString &text) if (ch.isHighSurrogate() && i+1=0xE0100 && ucs4 <= 0xE01EF) { //variation selector } else { if (!consecutive) - glyphPositions.append(i); + glyphStartCharList.append(i); consecutive = false; } i+=2; continue; } else if (ch.unicode() == 0x200D) { consecutive = true; - } else if (ch.combiningClass()!=0 && !glyphPositions.isEmpty()) { + } else if (ch.combiningClass()!=0 && !glyphStartCharList.isEmpty()) { //a Combining character } else if (ch.unicode()>=0xFE00 && ch.unicode()<=0xFE0F) { //variation selector } else { //qDebug("%x %d", ch.unicode(), ch.combiningClass()); if (!consecutive) - glyphPositions.append(i); + glyphStartCharList.append(i); consecutive = false; } i++; } - //qDebug()< glyphPositions = calcGlyphPositions(str); - int totalColumns; - calcGlyphColumns(str,glyphPositions,colsBefore, totalColumns); - return totalColumns - colsBefore; + QList glyphStartCharList = calcGlyphStartCharList(str); + int right; + calcGlyphPositionList(str, glyphStartCharList, left, right); + return right - left; } -int Document::glyphStart(int line, int glyphIdx) +int Document::glyphStartChar(int line, int glyphIdx) { QMutexLocker locker(&mMutex); - return mLines[line]->glyphStart(glyphIdx); + return mLines[line]->glyphStartChar(glyphIdx); } int Document::glyphLength(int line, int glyphIdx) @@ -913,120 +916,115 @@ int Document::glyphLength(int line, int glyphIdx) return mLines[line]->glyphLength(glyphIdx); } -int Document::glyphStartColumn(int line, int glyphIdx) +int Document::glyphStartPostion(int line, int glyphIdx) { QMutexLocker locker(&mMutex); - return mLines[line]->glyphStartColumn(glyphIdx); + return mLines[line]->glyphStartPosition(glyphIdx); } -int Document::glyphColumns(int line, int glyphIdx) +int Document::glyphWidth(int line, int glyphIdx) { QMutexLocker locker(&mMutex); - return mLines[line]->glyphColumns(glyphIdx); + return mLines[line]->glyphWidth(glyphIdx); } -int Document::glyphColumns(const QString &glyph, int colsBefore) const +int Document::glyphWidth(const QString &glyph, int left) const { - int glyphCols; + int glyphWidth; if (glyph.length()==1 && glyph[0].unicode()<0xFF) { QChar ch = glyph[0]; if (ch == '\t') { - glyphCols = mTabWidth - colsBefore % mTabWidth; + glyphWidth = tabWidth() - left % tabWidth(); } else { - int width = mFontMetrics.horizontalAdvance(ch); - glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth)); + glyphWidth = mFontMetrics.horizontalAdvance(ch); //qDebug()<0 && (modular <= (mCharWidth/5)) ) - glyphCols--; + glyphWidth = mNonAsciiFontMetrics.horizontalAdvance(glyph); //qDebug()< glyphPositions = mLines[line]->glyphPositions(); - return charToGlyphIndex(glyphPositions, charIdx); + QList glyphStartCharList = mLines[line]->glyphStartCharList(); + return charToGlyphIndex(glyphStartCharList, charIdx); } -int Document::charToGlyphIndex(QList glyphPositions, int charIdx) const +int Document::charToGlyphIndex(QList glyphStartCharList, int charIdx) const { Q_ASSERT(charIdx>=0); - for (int i=0;icharIdx) { + for (int i=0;icharIdx) { Q_ASSERT(i-1>=0); return i-1; } } - Q_ASSERT(glyphPositions.length()-1>=0); - return glyphPositions.length()-1; + Q_ASSERT(glyphStartCharList.length()-1>=0); + return glyphStartCharList.length()-1; } -int Document::columnToGlyphIndex(int line, int column) +int Document::xposToGlyphIndex(int line, int xpos) { QMutexLocker locker(&mMutex); - QList glyphColumnsList = mLines[line]->glyphColumnsList(); - return columnToGlyphIndex(glyphColumnsList,column); + QList glyphPositionList = mLines[line]->glyphPositionList(); + return xposToGlyphIndex(glyphPositionList, xpos); } -int Document::columnToGlyphIndex(QList glyphColumnsList, int column) const +int Document::xposToGlyphIndex(QList glyphPositionList, int xpos) const { - Q_ASSERT(column>=1); - for (int i=0;icolumn) { + Q_ASSERT(xpos>=0); + for (int i=0;ixpos) { Q_ASSERT(i-1>=0); return i-1; } } - Q_ASSERT(glyphColumnsList.length()-1>=0); - return glyphColumnsList.length()-1; + Q_ASSERT(glyphPositionList.length()-1>=0); + return glyphPositionList.length()-1; } -int Document::charToColumn(int line, int charPos) +int Document::charToGlyphStartPosition(int line, int charPos) { QMutexLocker locker(&mMutex); - QList glyphPositions = mLines[line]->glyphPositions(); - int glyphIdx = charToGlyphIndex(glyphPositions, charPos); - return mLines[line]->glyphStartColumn(glyphIdx); + QList glyphStartCharList = mLines[line]->glyphStartCharList(); + int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); + return mLines[line]->glyphStartPosition(glyphIdx); } -int Document::columnToChar(int line, int column) +int Document::xposToGlyphStartChar(int line, int xpos) { QMutexLocker locker(&mMutex); - QList glyphColumnsList = mLines[line]->glyphColumnsList(); - int glyphIdx = columnToGlyphIndex(glyphColumnsList, column); - return mLines[line]->glyphStart(glyphIdx); + QList glyphPositionList = mLines[line]->glyphPositionList(); + int glyphIdx = xposToGlyphIndex(glyphPositionList, xpos); + return mLines[line]->glyphStartChar(glyphIdx); } -int Document::charToColumn(int line, const QString newStr, int charPos) +int Document::charToGlyphStartPosition(int line, const QString newStr, int charPos) { QMutexLocker locker(&mMutex); - QList glyphPositions; + QList glyphStartCharList; if (mLines[line]->lineText() == newStr) - glyphPositions = mLines[line]->glyphPositions(); + glyphStartCharList = mLines[line]->glyphStartCharList(); else - glyphPositions = calcGlyphPositions(newStr); - int glyphIdx = charToGlyphIndex(glyphPositions, charPos); - return mLines[line]->glyphStartColumn(glyphIdx); + glyphStartCharList = calcGlyphStartCharList(newStr); + int glyphIdx = charToGlyphIndex(glyphStartCharList, charPos); + return mLines[line]->glyphStartPosition(glyphIdx); } -int Document::columnToChar(int line, const QString newStr, int column) +int Document::xposToGlyphStartChar(int line, const QString newStr, int xpos) { QMutexLocker locker(&mMutex); - QList glyphColumnsList; + QList glyphPositionList; if (mLines[line]->lineText() == newStr) - glyphColumnsList = mLines[line]->glyphColumnsList(); + glyphPositionList = mLines[line]->glyphPositionList(); else { - glyphColumnsList = calcGlyphColumns(mLines[line]->lineText()); + glyphPositionList = calcGlyphPositionList(mLines[line]->lineText()); } - int glyphIdx = columnToGlyphIndex(glyphColumnsList, column); - return mLines[line]->glyphStart(glyphIdx); + int glyphIdx = xposToGlyphIndex(glyphPositionList, xpos); + return mLines[line]->glyphStartChar(glyphIdx); } // int Document::charToColumn(int line, int charPos) @@ -1104,31 +1102,31 @@ void Document::internalClear() } } -QList Document::calcGlyphColumns(const QString &lineText, const QList &glyphPositions, int colsBefore, int &totalColumns) const +QList Document::calcGlyphPositionList(const QString &lineText, const QList &glyphStartCharList, int left, int &right) const { - totalColumns = std::max(0,colsBefore); + right = std::max(0,left); int start,end; - QList glyphColumnsList; - for (int i=0;i glyphPostionList; + for (int i=0;i Document::calcGlyphColumns(const QString &lineText) const +QList Document::calcGlyphPositionList(const QString &lineText) const { - QList glyphPositions = calcGlyphPositions(lineText); - int totalColumns; - return calcGlyphColumns(lineText,glyphPositions,0,totalColumns); + QList glyphStartCharList = calcGlyphStartCharList(lineText); + int right; + return calcGlyphPositionList(lineText,glyphStartCharList,0,right); } NewlineType Document::getNewlineType() @@ -1149,44 +1147,44 @@ bool Document::empty() return mLines.count()==0; } -void Document::invalidateAllLineColumns() +void Document::invalidateAllLineWidth() { QMutexLocker locker(&mMutex); mIndexOfLongestLine = -1; for (PDocumentLine& line:mLines) { - line->invalidateColumns(); + line->invalidateWidth(); } } DocumentLine::DocumentLine(): mSyntaxState{}, - mColumns{-1} + mWidth{-1} { } int DocumentLine::glyphLength(int i) const { - Q_ASSERT(i>=0 && i=0 && i=0); - Q_ASSERT(i>=0 && i=0); + Q_ASSERT(i>=0 && i calcGlyphPositions(const QString &text); +QList calcGlyphStartCharList(const QString &text); class Document; @@ -63,23 +63,24 @@ private: * @return the glyphs count */ int glyphsCount() const { - return mGlyphPositions.length(); + return mGlyphStartCharList.length(); } /** * @brief get list of start index of the glyphs in the line text - * @return start positions of the glyph. + * @return start indice of the glyph. */ - const QList& glyphPositions() const { - return mGlyphPositions; + const QList& glyphStartCharList() const { + return mGlyphStartCharList; } /** - * @brief get list of start column of the glyphs in the line text - * @return start positions of the glyph. + * @brief get list of start position of the glyphs in the line text + * @return start positions of the glyph (in pixel) */ - const QList& glyphColumnsList() const { - return mGlyphColumns; + const QList& glyphPositionList() const { + Q_ASSERT(mWidth>=0); + return mGlyphPositionList; } /** @@ -87,11 +88,11 @@ private: * @param i index of the glyph in the line (starting from 0) * @return char index in the line text (start from 0) */ - int glyphStart(int i) const { + int glyphStartChar(int i) const { Q_ASSERT(i>=0); - if (i>=mGlyphPositions.length()) + if (i>=mGlyphStartCharList.length()) return mLineText.length(); - return mGlyphPositions[i]; + return mGlyphStartCharList[i]; } /** @@ -107,28 +108,28 @@ private: * @return the chars representing the specified glyph */ QString glyph(int i) const { - return mLineText.mid(glyphStart(i),glyphLength(i)); + return mLineText.mid(glyphStartChar(i),glyphLength(i)); } /** - * @brief get start column of the specified glyph. + * @brief get start position of the specified glyph. * @param i index of the glyph in the line (starting from 0) - * @return the column in the displayed line (start from 1) + * @return start position in the line (pixel) */ - int glyphStartColumn(int i) const { - Q_ASSERT(mColumns>=0); + int glyphStartPosition(int i) const { + Q_ASSERT(mWidth>=0); Q_ASSERT(i>=0); - if (i>mGlyphColumns.length()) - return mColumns+1; - return mGlyphColumns[i]; + if (i>mGlyphPositionList.length()) + return mWidth+1; + return mGlyphPositionList[i]; } /** - * @brief get width (in columns) of the specified glyph. + * @brief get width (pixels) of the specified glyph. * @param i index of the glyph of the line (starting from 0) * @return */ - int glyphColumns(int i) const; + int glyphWidth(int i) const; /** * @brief get the line text @@ -137,10 +138,10 @@ private: const QString& lineText() const { return mLineText; } /** - * @brief get the width (in columns) of the line text - * @return the width (in columns) + * @brief get the width (pixel) of the line text + * @return the width (in width) */ - int columns() const { return mColumns; } + int width() const { return mWidth; } /** * @brief get the state of the syntax highlighter after this line is parsed @@ -154,27 +155,27 @@ private: void setSyntaxState(const SyntaxState &newSyntaxState) { mSyntaxState = newSyntaxState; } void setLineText(const QString &newLineText); - void setColumns(int cols, QList glyphCols) { mColumns = cols; mGlyphColumns = glyphCols; } - void invalidateColumns() { mColumns = -1; mGlyphColumns.clear(); } + void setWidth(int width, QList glyphPositionList) { mWidth = width; mGlyphPositionList = glyphPositionList; } + void invalidateWidth() { mWidth = -1; mGlyphPositionList.clear(); } private: QString mLineText; /* the unicode code points of the text */ /** * @brief Start positions of glyphs in mLineText * * A glyph may be defined by more than one code points. - * Each lement of mGlyphPositions (position) is the start index + * Each lement of mGlyphStartCharList (position) is the start index * of the code points in the mLineText. */ - QList mGlyphPositions; + QList mGlyphStartCharList; /** * @brief start columns of the glyphs * * A glyph may occupy more than one columns in the screen. - * Each elements of mGlyphColumns is the columns occupied by the glyph. + * Each elements of mGlyphPositionList is the columns occupied by the glyph. * The width of a glyph is affected by the font used to display, * so it must be recalculated each time the font is changed. */ - QList mGlyphColumns; + QList mGlyphPositionList; /** * @brief state of the syntax highlighter after this line is parsed * @@ -183,12 +184,12 @@ private: */ SyntaxState mSyntaxState; /** - * @brief total width (in columns) of the line text + * @brief total width (pixel) of the line text * * The width of glyphs is affected by the font used to display, * so it must be recalculated each time the font is changed. */ - int mColumns; + int mWidth; friend class Document; }; @@ -251,17 +252,17 @@ public: int braceLevel(int line); /** - * @brief get width (in columns) of the specified line + * @brief get width of the specified line * * It's thread safe * * @param line line index (starts frome 0) * @return */ - int lineColumns(int line); + int lineWidth(int line); /** - * @brief get width (in columns) of the specified text / line + * @brief get width of the specified text / line * * It's thread safe. * If the new text is the same as the line text, it just @@ -273,7 +274,7 @@ public: * @param newText the new text * @return */ - int lineColumns(int line, const QString &newText); + int lineWidth(int line, const QString &newText); /** * @brief get block (indent) level of the specified line @@ -306,7 +307,7 @@ public: * * @return */ - int longestLineColumns(); + int longestLineWidth(); /** * @brief get line break of the current document @@ -355,16 +356,16 @@ public: */ int getLineGlyphsCount(int line); - /** - * @brief get position list of the glyphs on the specified line. - * - * It's thread safe. - * Each element of the list is the index of the starting char in the line text. - * - * @param line line index (starts frome 0) - * @return - */ - QList getGlyphPositions(int index); + // /** + // * @brief get position list of the glyphs on the specified line. + // * + // * It's thread safe. + // * Each element of the list is the index of the starting char in the line text. + // * + // * @param line line index (starts frome 0) + // * @return + // */ + // QList getGlyphPositions(int index); /** * @brief get count of lines in the document @@ -439,15 +440,15 @@ public: int charToGlyphStartChar(int line, int charPos); //int columnToGlyphStartColumn(int line, int charPos); /** - * @brief calculate display width (in columns) of a string + * @brief calculate display width of a string * - * The string may contains tab char, whose width depends on the tab size and it's position + * The string may contains the tab char, whose width depends on the tab size and it's position * * @param str the string to be displayed - * @param colsBefore columns before the string + * @param left start x pos of the string * @return width of the string, don't including colsBefore */ - int stringColumns(const QString &str, int colsBefore) const; + int stringWidth(const QString &str, int left) const; /** * @brief get start index of the chars representing the specified glyph in the specified line. @@ -458,7 +459,7 @@ public: * @param glyphIdx index of the glyph in the line (starting from 0) * @return char index in the line text (start from 0) */ - int glyphStart(int line, int glyphIdx); + int glyphStartChar(int line, int glyphIdx); /** * @brief get count of the chars representing the specified glyph in the specified line. @@ -480,7 +481,7 @@ public: * @param glyphIdx index of the glyph in the line (starting from 0) * @return the column (starting from 1) */ - int glyphStartColumn(int line, int glyphIdx); + int glyphStartPostion(int line, int glyphIdx); /** * @brief get width (in columns) of the specified glyph in the specified line. @@ -491,9 +492,9 @@ public: * @param glyphIdx index of the glyph in the line (starting from 0) * @return */ - int glyphColumns(int line, int glyphIdx); + int glyphWidth(int line, int glyphIdx); - int glyphColumns(const QString &s, int colsBefore) const; + int glyphWidth(const QString &glyph, int left) const; /** * @brief get index of the glyph represented by the specified char @@ -505,7 +506,7 @@ public: * @return glyph index in the line (starting from 0) */ int charToGlyphIndex(int line, int charPos); - int charToGlyphIndex(QList glyphPositions, int charPos) const; + int charToGlyphIndex(QList glyphStartCharList, int charPos) const; /** * @brief get index of the glyph displayed on the specified column @@ -516,13 +517,13 @@ public: * @param column the column (starting from 1) * @return glyph index in the line (starting from 0) */ - int columnToGlyphIndex(int line, int column); - int columnToGlyphIndex(QList glyphColumnsList, int column) const; + int xposToGlyphIndex(int line, int xpos); + int xposToGlyphIndex(QList glyphColumnsList, int xpos) const; - int charToColumn(int line, int charPos); - int columnToChar(int line, int column); - int charToColumn(int line, const QString newStr, int charPos); - int columnToChar(int line, const QString newStr, int column); + int charToGlyphStartPosition(int line, int charPos); + int xposToGlyphStartChar(int line, int xpos); + int charToGlyphStartPosition(int line, const QString newStr, int charPos); + int xposToGlyphStartChar(int line, const QString newStr, int xpos); bool getAppendNewLineAtEOF(); void setAppendNewLineAtEOF(bool appendNewLineAtEOF); @@ -532,16 +533,21 @@ public: bool empty(); - int tabWidth() const { - return mTabWidth; + int tabSize() const { + return mTabSize; } - void setTabWidth(int newTabWidth); + + int tabWidth() const { + return mTabSize * mCharWidth; + } + + void setTabSize(int newTabSize); const QFontMetrics &fontMetrics() const; void setFontMetrics(const QFont &newFont, const QFont& newNonAsciiFont); public slots: - void invalidateAllLineColumns(); + void invalidateAllLineWidth(); signals: void changed(); @@ -558,8 +564,9 @@ protected: void putTextStr(const QString& text); void internalClear(); private: - QList calcGlyphColumns(const QString& lineText, const QList &glyphPositions, int colsBefore, int &totalColumns) const; - QList calcGlyphColumns(const QString& lineText) const; + int calculateLineWidth(int line); + QList calcGlyphPositionList(const QString& lineText, const QList &glyphStartCharList, int left, int &right) const; + QList calcGlyphPositionList(const QString& lineText) const; bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file); void loadUTF16BOMFile(QFile& file); void loadUTF32BOMFile(QFile& file); @@ -573,7 +580,7 @@ private: QFontMetrics mFontMetrics; QFontMetrics mNonAsciiFontMetrics; - int mTabWidth; + int mTabSize; int mCharWidth; //int mCount; //int mCapacity; @@ -586,8 +593,6 @@ private: #else QMutex mMutex; #endif - - int calculateLineColumns(int Index); }; enum class ChangeReason { diff --git a/libs/qsynedit/qsynedit/formatter/cppformatter.cpp b/libs/qsynedit/qsynedit/formatter/cppformatter.cpp index 3ad02e2e..296c3efa 100644 --- a/libs/qsynedit/qsynedit/formatter/cppformatter.cpp +++ b/libs/qsynedit/qsynedit/formatter/cppformatter.cpp @@ -108,12 +108,12 @@ namespace QSynedit { indentSpaces = editor->leftSpaces(editor->document()->getLine(matchingIndents.line)); } else if (rangeAfterFirstToken.indents.count()>=2){ IndentInfo info = rangeAfterFirstToken.indents[rangeAfterFirstToken.indents.count()-2]; - indentSpaces = editor->leftSpaces(editor->document()->getLine(info.line))+editor->tabWidth(); + indentSpaces = editor->leftSpaces(editor->document()->getLine(info.line))+editor->tabSize(); } else indentSpaces = 0; } else if (rangePreceeding.getLastIndentType()!=IndentType::None) { IndentInfo matchingIndents = rangePreceeding.getLastIndent(); - indentSpaces = editor->leftSpaces(editor->document()->getLine(matchingIndents.line))+editor->tabWidth(); + indentSpaces = editor->leftSpaces(editor->document()->getLine(matchingIndents.line))+editor->tabSize(); } else { indentSpaces = 0; } diff --git a/libs/qsynedit/qsynedit/painter.cpp b/libs/qsynedit/qsynedit/painter.cpp index 79276e00..32bc8c5a 100644 --- a/libs/qsynedit/qsynedit/painter.cpp +++ b/libs/qsynedit/qsynedit/painter.cpp @@ -338,19 +338,19 @@ void QSynEditPainter::computeSelectionInfo() QString sLine = edit->lineText().left(edit->mCaretX-1) + edit->mInputPreeditString + edit->lineText().mid(edit->mCaretX-1); - vSelStart.Column = edit->charToColumn(edit->mCaretY-1, sLine,vStart.ch); + vSelStart.x = edit->charToGlyphLeft(edit->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.Column = edit->charToColumn(edit->mCaretY-1, sLine,vEnd.ch); + vSelEnd.x = edit->charToGlyphLeft(edit->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.Column > vSelEnd.Column) - std::swap(vSelStart.Column, vSelEnd.Column); + if (edit->mActiveSelectionMode == SelectionMode::Column && vSelStart.x > vSelEnd.x) + std::swap(vSelStart.x, vSelEnd.x); } } } @@ -396,17 +396,17 @@ void QSynEditPainter::paintToken(const QString &token, int tokenCols, int column painter->fillRect(rcTokenBack,painter->brush()); if (first > tokenCols) { } else { - int tokenColLen=0; + int tokenWidth=0; startPaint = false; - QList glyphPositions = calcGlyphPositions(token); - qDebug()<<"painting:"< glyphStartCharList = calcGlyphStartCharList(token); +// qDebug()<<"painting:"<document()->glyphColumns(glyph, columnsBefore+tokenColLen); - qDebug()<=first) { + int glyghWidth = edit->document()->glyphWidth(glyph, columnsBefore+tokenColLen); +// qDebug()<=first) { if (!startPaint && (tokenColLen+1!=first)) { nX-= (first - tokenColLen - 1) * edit->mCharWidth; } @@ -422,13 +422,13 @@ void QSynEditPainter::paintToken(const QString &token, int tokenCols, int column && operatorGlyphs.contains(glyph)) { QString textToPaint = glyph; while(i+1document()->glyphColumns(glyph2,0); + charCols += edit->document()->glyphWidth(glyph2,0); textToPaint+=glyph2; } painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent() , textToPaint); @@ -739,8 +739,8 @@ void QSynEditPainter::paintFoldAttributes() lineIndent = edit->getLineIndent(edit->mDocument->getLine(lastNonBlank)); int braceLevel = edit->mDocument->getSyntaxState(lastNonBlank).braceLevel; int indentLevel = braceLevel ; - if (edit->tabWidth()>0) - indentLevel = lineIndent / edit->tabWidth(); + if (edit->tabSize()>0) + indentLevel = lineIndent / edit->tabSize(); // Step horizontal coord //TabSteps = edit->mTabWidth; tabSteps = 0; @@ -748,7 +748,7 @@ void QSynEditPainter::paintFoldAttributes() while (tabSteps < lineIndent) { X = tabSteps * edit->mCharWidth + edit->textOffset() - 2; - tabSteps+=edit->tabWidth(); + tabSteps+=edit->tabSize(); indentLevel++ ; if (edit->mSyntaxer) { if (edit->mCodeFolding.indentGuides) { @@ -901,14 +901,14 @@ void QSynEditPainter::paintLines() nLineSelStart = 0; nLineSelEnd = 0; // Does the selection intersect the visible area? - if (bAnySelection && (cRow >= vSelStart.Row) && (cRow <= vSelEnd.Row)) { + if (bAnySelection && (cRow >= vSelStart.row) && (cRow <= vSelEnd.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.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; @@ -919,10 +919,10 @@ void QSynEditPainter::paintLines() } } if ( (edit->mActiveSelectionMode == SelectionMode::Column) || - ((edit->mActiveSelectionMode == SelectionMode::Normal) && (cRow == vSelEnd.Row)) ) { - int ch = edit->columnToChar(vLine,vSelEnd.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; @@ -1094,7 +1094,7 @@ void QSynEditPainter::paintLines() foldRange = edit->foldStartAtLine(vLine); if ((foldRange) && foldRange->collapsed) { sFold = edit->syntaxer()->foldString(sLine); - nFold = edit->stringColumns(sFold,edit->mDocument->lineColumns(vLine-1)); + 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) @@ -1106,7 +1106,7 @@ void QSynEditPainter::paintLines() && (!bSpecialLine) && (edit->mDocument->lineColumns(vLine-1) < vLastChar)) { addHighlightToken(LineBreakGlyph, - edit->mDocument->lineColumns(vLine-1) - (vFirstChar - FirstCol), + edit->mDocument->lineColumns(vLine-1) - (vFirstChar - FirstCol), edit->mDocument->glyphColumns(LineBreakGlyph,0),vLine, edit->mSyntaxer->whitespaceAttribute(),false); } } diff --git a/libs/qsynedit/qsynedit/qsynedit.cpp b/libs/qsynedit/qsynedit/qsynedit.cpp index 516698ef..d3749bc7 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 = 1; + mLeftChar = 0; mTopLine = 1; mCaretX = 1; mLastCaretColumn = 1; @@ -178,12 +178,12 @@ DisplayCoord QSynEdit::displayXY() const int QSynEdit::displayX() const { - return displayXY().Column; + return displayXY().x; } int QSynEdit::displayY() const { - return displayXY().Row; + return displayXY().row; } BufferCoord QSynEdit::caretXY() const @@ -327,9 +327,9 @@ bool QSynEdit::canRedo() const int QSynEdit::maxScrollWidth() const { - int maxLen = mDocument->longestLineColumns(); + int maxLen = mDocument->longestLineWidth(); if (syntaxer()) - maxLen += stringColumns(syntaxer()->foldString(""),maxLen); + maxLen += stringWidth(syntaxer()->foldString(""),maxLen); if (mOptions.testFlag(eoScrollPastEol)) return std::max(maxLen ,1); else @@ -734,8 +734,8 @@ DisplayCoord QSynEdit::pixelsToRowColumn(int aX, int aY) const QPoint QSynEdit::rowColumnToPixels(const DisplayCoord &coord) const { QPoint result; - result.setX((coord.Column - 1) * mCharWidth + textOffset()); - result.setY((coord.Row - mTopLine) * mTextHeight); + result.setX((coord.x - 1) * mCharWidth + textOffset()); + result.setY((coord.row - mTopLine) * mTextHeight); return result; } @@ -750,10 +750,10 @@ DisplayCoord QSynEdit::bufferToDisplayPos(const BufferCoord &p) const DisplayCoord result {p.ch,p.line}; // Account for tabs and charColumns if (p.line-1 count()) - result.Column = charToColumn(p.line,p.ch); + result.x = charToGlyphLeft(p.line,p.ch); // Account for code folding if (mUseCodeFolding) - result.Row = foldLineToRow(result.Row); + result.row = foldLineToRow(result.row); return result; } @@ -764,13 +764,13 @@ DisplayCoord QSynEdit::bufferToDisplayPos(const BufferCoord &p) const */ BufferCoord QSynEdit::displayToBufferPos(const DisplayCoord &p) const { - BufferCoord Result{p.Column,p.Row}; + BufferCoord Result{p.x,p.row}; // 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 = columnToChar(Result.line,p.Column); + Result.ch = xposToGlyphStartChar(Result.line,p.x); } return Result; } @@ -815,7 +815,7 @@ int QSynEdit::leftSpaces(const QString &line) const if (mOptions.testFlag(eoAutoIndent)) { for (QChar ch:line) { if (ch == '\t') { - result += tabWidth() - (result % tabWidth()); + result += tabSize() - (result % tabSize()); } else if (ch == ' ') { result ++; } else { @@ -828,28 +828,24 @@ int QSynEdit::leftSpaces(const QString &line) const QString QSynEdit::GetLeftSpacing(int charCount, bool wantTabs) const { - if (wantTabs && !mOptions.testFlag(eoTabsToSpaces) && tabWidth()>0) { - return QString(charCount / tabWidth(),'\t') + QString(charCount % tabWidth(),' '); + if (wantTabs && !mOptions.testFlag(eoTabsToSpaces) && tabSize()>0) { + return QString(charCount / tabSize(),'\t') + QString(charCount % tabSize(),' '); } else { return QString(charCount,' '); } } -int QSynEdit::charToColumn(int aLine, int aChar) const +int QSynEdit::charToGlyphLeft(int line, int charPos) const { - if (aLine>=1 && aLine <= mDocument->count()) { - QString s = getDisplayStringAtLine(aLine); - return mDocument->charToColumn(aLine-1, s, aChar-1); - } - return aChar; + Q_ASSERT(line>=1 && line <= mDocument->count()); + QString s = getDisplayStringAtLine(line); + return mDocument->charToGlyphStartPosition(line-1, s, charPos-1); } -int QSynEdit::charToColumn(int aLine, const QString &s, int aChar) const +int QSynEdit::charToGlyphLeft(int line, const QString &s, int charPos) const { - if (aLine>=1 && aLine <= mDocument->count()) { - return mDocument->charToColumn(aLine-1, s, aChar-1); - } - return aChar; + Q_ASSERT(line>=1 && line <= mDocument->count()); + return mDocument->charToGlyphStartPosition(line-1, s, charPos-1); } // int QSynEdit::charToColumn(const QString &s, int aChar) const @@ -857,27 +853,22 @@ int QSynEdit::charToColumn(int aLine, const QString &s, int aChar) const // return mDocument->charToColumn(s, aChar); // } -int QSynEdit::columnToChar(int aLine, int aColumn) const +int QSynEdit::xposToGlyphStartChar(int line, int xpos) const { - //Q_ASSERT( (aLine <= mDocument->count()) && (aLine >= 1)); - if (aLine <= mDocument->count()) { - QString s = getDisplayStringAtLine(aLine); - return mDocument->columnToChar(aLine-1,s,aColumn)+1; - } - return aColumn; + Q_ASSERT(line>=1 && line <= mDocument->count()); + QString s = getDisplayStringAtLine(line); + return mDocument->xposToGlyphStartChar(line-1,s,xpos)+1; } -int QSynEdit::columnToChar(int aLine, const QString &s, int aColumn) const +int QSynEdit::xposToGlyphStartChar(int line, const QString &s, int xpos) const { - if (aLine <= mDocument->count()) { - return mDocument->columnToChar(aLine-1,s,aColumn)+1; - } - return aColumn; + Q_ASSERT(line>=1 && line <= mDocument->count()); + return mDocument->xposToGlyphStartChar(line-1,s,xpos)+1; } -int QSynEdit::stringColumns(const QString &line, int colsBefore) const +int QSynEdit::stringWidth(const QString &line, int left) const { - return mDocument->stringColumns(line,colsBefore); + return mDocument->stringWidth(line, left); } int QSynEdit::getLineIndent(const QString &line) const @@ -886,7 +877,7 @@ int QSynEdit::getLineIndent(const QString &line) const for (QChar ch:line) { switch(ch.unicode()) { case '\t': - indents+=tabWidth(); + indents+=tabSize(); break; case ' ': indents+=1; @@ -909,7 +900,7 @@ int QSynEdit::rowToLine(int aRow) const int QSynEdit::lineToRow(int aLine) const { - return bufferToDisplayPos({1, aLine}).Row; + return bufferToDisplayPos({1, aLine}).row; } int QSynEdit::foldRowToLine(int Row) const @@ -1069,7 +1060,7 @@ bool QSynEdit::selAvail() const if (mBlockBegin.line != mBlockEnd.line) { DisplayCoord coordBegin = bufferToDisplayPos(mBlockBegin); DisplayCoord coordEnd = bufferToDisplayPos(mBlockEnd); - return coordBegin.Column!=coordEnd.Column; + return coordBegin.x!=coordEnd.x; } else return true; } @@ -1086,7 +1077,7 @@ bool QSynEdit::colSelAvail() const return true; DisplayCoord coordBegin = bufferToDisplayPos(mBlockBegin); DisplayCoord coordEnd = bufferToDisplayPos(mBlockEnd); - return coordBegin.Column!=coordEnd.Column; + return coordBegin.x!=coordEnd.x; } QString QSynEdit::wordAtCursor() @@ -1212,7 +1203,7 @@ 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 line = rowToLine(rowColumn.row); // Check if we clicked on a folding thing if (mUseCodeFolding) { @@ -1223,7 +1214,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((rowColumn.row - mTopLine) * mTextHeight); rect.setBottom(rect.top() + mTextHeight - 1); if (rect.contains(event->pos())) { if (foldRange->collapsed) @@ -1743,13 +1734,13 @@ void QSynEdit::doMouseScroll(bool isDragging) iMousePos = QCursor::pos(); iMousePos = mapFromGlobal(iMousePos); C = pixelsToNearestRowColumn(iMousePos.x(), iMousePos.y()); - C.Row = minMax(C.Row, 1, displayLineCount()); + C.row = minMax(C.row, 1, displayLineCount()); if (mScrollDeltaX != 0) { setLeftChar(leftChar() + mScrollDeltaX * mMouseSelectionScrollSpeed); X = leftChar(); if (mScrollDeltaX > 0) // scrolling right? X+=charsInWindow(); - C.Column = X; + C.x = X; } if (mScrollDeltaY != 0) { //qDebug()< 0) // scrolling down? Y+=mLinesInWindow - 1; - C.Row = minMax(Y, 1, displayLineCount()); + C.row = minMax(Y, 1, displayLineCount()); } BufferCoord vCaret = displayToBufferPos(C); if ((caretX() != vCaret.ch) || (caretY() != vCaret.line)) { @@ -1866,18 +1857,19 @@ void QSynEdit::doDeleteLastChar() } } else { // delete text before the caret - int caretColumn = charToColumn(mCaretY,mCaretX); + // int startChar = charTo + // int caretXPos = charToGlyph(mCaretY,mCaretX); int SpaceCount1 = leftSpaces(Temp); int SpaceCount2 = 0; int newCaretX; - if (SpaceCount1 == caretColumn - 1) { + if (SpaceCount1 == mCaretX - 1) { //how much till the next tab column - int BackCounter = (caretColumn - 1) % tabWidth(); + int BackCounter = (mCaretX - 1) % tabSize(); if (BackCounter == 0) - BackCounter = tabWidth(); - SpaceCount2 = std::max(0,SpaceCount1 - tabWidth()); - newCaretX = columnToChar(mCaretY,SpaceCount2+1); + BackCounter = tabSize(); + SpaceCount2 = std::max(0,SpaceCount1 - tabSize()); + newCaretX = xposToGlyphStartChar(mCaretY,SpaceCount2+1); helper.append(Temp.mid(newCaretX - 1, mCaretX - newCaretX)); Temp.remove(newCaretX-1,mCaretX - newCaretX); properSetLine(mCaretY - 1, Temp); @@ -2366,8 +2358,8 @@ void QSynEdit::doTabKey() } QString Spaces; if (mOptions.testFlag(eoTabsToSpaces)) { - int cols = charToColumn(mCaretY,mCaretX); - int i = tabWidth() - (cols) % tabWidth(); + int left = charToGlyphLeft(mCaretY,mCaretX); + int i = std::ceil( (tabWidth() - (left) % tabWidth() ) / (float) tabSize()); Spaces = QString(i,' '); } else { Spaces = '\t'; @@ -2400,12 +2392,12 @@ void QSynEdit::doShiftTabKey() if (s[s.length()-1] == '\t') { NewX= mCaretX-1; } else { - int colsBefore = charToColumn(mCaretY,mCaretX)-1; - int spacesToRemove = colsBefore % tabWidth(); + int spacesBefore = leftSpaces(lineText()); + int spacesToRemove = spacesBefore % tabSize(); if (spacesToRemove == 0) - spacesToRemove = tabWidth(); - if (spacesToRemove > colsBefore ) - spacesToRemove = colsBefore; + spacesToRemove = tabSize(); + if (spacesToRemove > spacesBefore ) + spacesToRemove = spacesBefore; NewX = mCaretX; while (spacesToRemove > 0 && s[NewX-2] == ' ' ) { NewX--; @@ -2452,16 +2444,16 @@ bool QSynEdit::canDoBlockIndent() } } if (mActiveSelectionMode == SelectionMode::Column) { - int startCol = charToColumn(BB.line,BB.ch); - int endCol = charToColumn(BE.line,BE.ch); + int startPos = charToGlyphLeft(BB.line,BB.ch); + int endPos = charToGlyphLeft(BE.line,BE.ch); for (int i = BB.line; i<=BE.line;i++) { QString line = mDocument->getLine(i-1); - int startChar = columnToChar(i,startCol); + int startChar = xposToGlyphStartChar(i,startPos); QString s = line.mid(0,startChar-1); if (!s.trimmed().isEmpty()) return false; - int endChar = columnToChar(i,endCol); + int endChar = xposToGlyphStartChar(i,endPos); s=line.mid(endChar-1); if (!s.trimmed().isEmpty()) return false; @@ -2477,21 +2469,21 @@ QRect QSynEdit::calculateCaretRect() const QString sLine = lineText().left(mCaretX-1) + mInputPreeditString + lineText().mid(mCaretX-1); - coord.Column = charToColumn(mCaretY-1, sLine,mCaretX+mInputPreeditString.length()); + coord.x = charToGlyphLeft(mCaretY-1, sLine,mCaretX+mInputPreeditString.length()); } int rows=1; if (mActiveSelectionMode == SelectionMode::Column) { int startRow = lineToRow(std::min(blockBegin().line, blockEnd().line)); int endRow = lineToRow(std::max(blockBegin().line, blockEnd().line)); - coord.Row = startRow; + coord.row = startRow; rows = endRow-startRow+1; } QPoint caretPos = rowColumnToPixels(coord); int caretWidth=mCharWidth; if (mCaretY <= mDocument->count() && mCaretX <= mDocument->getLine(mCaretY-1).length()) { - QString glyph = mDocument->glyphAt(mCaretY-1, mCaretX-1); - int colsBefore = mDocument->charToColumn(mCaretY-1, mCaretX-1)-1; - caretWidth = mDocument->glyphColumns(glyph,colsBefore)*mCharWidth; + int glyphIndex = mDocument->charToGlyphIndex(mCaretY-1, mCaretX-1); + QString glyph = mDocument->glyph(mCaretY-1, glyphIndex); + caretWidth = mDocument->glyphWidth(mCaretY-1, glyphIndex); } if (mActiveSelectionMode == SelectionMode::Column) { return QRect(caretPos.x(),caretPos.y(),caretWidth, @@ -2508,9 +2500,9 @@ QRect QSynEdit::calculateInputCaretRect() const QPoint caretPos = rowColumnToPixels(coord); int caretWidth=mCharWidth; if (mCaretY <= mDocument->count() && mCaretX <= mDocument->getLine(mCaretY-1).length()) { - QString glyph = mDocument->glyphAt(mCaretY-1, mCaretX-1); - int colsBefore = mDocument->charToColumn(mCaretY-1, mCaretX-1)-1; - caretWidth = mDocument->glyphColumns(glyph,colsBefore)*mCharWidth; + 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, mTextHeight); @@ -2529,7 +2521,7 @@ void QSynEdit::computeCaret() int Y=iMousePos.y(); DisplayCoord vCaretNearestPos = pixelsToNearestRowColumn(X, Y); - vCaretNearestPos.Row = minMax(vCaretNearestPos.Row, 1, displayLineCount()); + vCaretNearestPos.row = minMax(vCaretNearestPos.row, 1, displayLineCount()); setInternalDisplayXY(vCaretNearestPos); } @@ -2606,12 +2598,12 @@ void QSynEdit::doBlockIndent() } else { e = BE.line; if (mOptions.testFlag(EditorOption::eoTabsToSpaces)) - x = caretX() + tabWidth(); + x = caretX() + tabSize(); else x = caretX() + 1; } if (mOptions.testFlag(eoTabsToSpaces)) { - spaces = QString(tabWidth(),' ') ; + spaces = QString(tabSize(),' ') ; } else { spaces = "\t"; } @@ -2693,7 +2685,7 @@ void QSynEdit::doBlockUnindent() if (line[0]!=' ' && line[0]!='\t') continue; int charsToDelete = 0; - while (charsToDelete < tabWidth() && + while (charsToDelete < tabSize() && charsToDelete < line.length() && line[charsToDelete] == ' ') charsToDelete++; @@ -4037,10 +4029,10 @@ void QSynEdit::setCaretColor(const QColor &caretColor) mCaretColor = caretColor; } -void QSynEdit::setTabWidth(int newTabWidth) +void QSynEdit::setTabSize(int newTabSize) { - if (newTabWidth!=tabWidth()) { - mDocument->setTabWidth(newTabWidth); + if (newTabSize!=tabSize()) { + mDocument->setTabSize(newTabSize); invalidate(); } } @@ -4503,68 +4495,68 @@ QString QSynEdit::selText() const if (!selAvail()) { return ""; } else { - int ColFrom = blockBegin().ch; - int First = blockBegin().line - 1; - // - int ColTo = blockEnd().ch; - int Last = blockEnd().line - 1; + int firstLine = blockBegin().line - 1; + int lastLine = blockEnd().line - 1; switch(mActiveSelectionMode) { case SelectionMode::Normal:{ + int charFrom = blockBegin().ch; + int charTo = blockEnd().ch; PCodeFoldingRange foldRange = foldStartAtLine(blockEnd().line); - QString s = mDocument->getLine(Last); - if ((foldRange) && foldRange->collapsed && ColTo>s.length()) { + QString s = mDocument->getLine(lastLine); + if ((foldRange) && foldRange->collapsed && charTo>s.length()) { s=s+syntaxer()->foldString(s); - if (ColTo>s.length()) { - Last = foldRange->toLine-1; - ColTo = mDocument->getLine(Last).length()+1; + if (charTo>s.length()) { + lastLine = foldRange->toLine-1; + charTo = mDocument->getLine(lastLine).length()+1; } } - if (First == Last) - return mDocument->getLine(First).mid(ColFrom-1, ColTo - ColFrom); + if (firstLine == lastLine) + return mDocument->getLine(firstLine).mid(charFrom-1, charTo - charFrom); else { - QString result = mDocument->getLine(First).mid(ColFrom-1); + QString result = mDocument->getLine(firstLine).mid(charFrom-1); result+= lineBreak(); - for (int i = First + 1; i<=Last - 1; i++) { + for (int i = firstLine + 1; i<=lastLine - 1; i++) { result += mDocument->getLine(i); result+=lineBreak(); } - result += mDocument->getLine(Last).leftRef(ColTo-1); + result += mDocument->getLine(lastLine).leftRef(charTo-1); return result; } } case SelectionMode::Column: { - First = blockBegin().line; - ColFrom = charToColumn(blockBegin().line, blockBegin().ch); - Last = blockEnd().line; - ColTo = charToColumn(blockEnd().line, blockEnd().ch); - if (ColFrom > ColTo) - std::swap(ColFrom, ColTo); - if (First>Last) - std::swap(First,Last); - QString result; - for (int i = First; i <= Last; i++) { - int l = columnToChar(i,ColFrom); - int r = columnToChar(i,ColTo-1)+1; - QString s = mDocument->getLine(i-1); - result += s.mid(l-1,r-l); - if (i xTo) + std::swap(xFrom, xTo); + if (firstLine>lastLine) + std::swap(firstLine,lastLine); + QString result; + for (int i = firstLine; i <= lastLine; i++) { + int l = xposToGlyphStartChar(i,xFrom); + int r = xposToGlyphStartChar(i,xTo)+1; + QString s = mDocument->getLine(i-1); + result += s.mid(l-1,r-l); + if (igetLine(i); result+=lineBreak(); } - result += mDocument->getLine(Last); - if (Last < mDocument->count() - 1) + result += mDocument->getLine(lastLine); + if (lastLine < mDocument->count() - 1) result+=lineBreak(); return result; } @@ -4582,58 +4574,59 @@ QStringList QSynEdit::getContent(BufferCoord startPos, BufferCoord endPos, Selec if (startPos>endPos) { std::swap(startPos,endPos); } - int ColFrom = startPos.ch; - int First = startPos.line - 1; - // - int ColTo = endPos.ch; - int Last = endPos.line - 1; + int firstLine = startPos.line - 1; + int lastLine = endPos.line - 1; switch(mode) { case SelectionMode::Normal:{ + int chFrom = startPos.ch; + int chTo = startPos.ch; PCodeFoldingRange foldRange = foldStartAtLine(endPos.line); - QString s = mDocument->getLine(Last); - if ((foldRange) && foldRange->collapsed && ColTo>s.length()) { + QString s = mDocument->getLine(lastLine); + if ((foldRange) && foldRange->collapsed && chTo>s.length()) { s=s+syntaxer()->foldString(s); - if (ColTo>s.length()) { - Last = foldRange->toLine-1; - ColTo = mDocument->getLine(Last).length()+1; + if (chTo>s.length()) { + lastLine = foldRange->toLine-1; + chTo = mDocument->getLine(lastLine).length()+1; } } - } - if (First == Last) { - result.append(mDocument->getLine(First).mid(ColFrom-1, ColTo - ColFrom)); + if (firstLine == lastLine) { + result.append(mDocument->getLine(firstLine).mid(chFrom-1, chTo - chFrom)); } else { - result.append(mDocument->getLine(First).mid(ColFrom-1)); - for (int i = First + 1; i<=Last - 1; i++) { + result.append(mDocument->getLine(firstLine).mid(chFrom-1)); + for (int i = firstLine + 1; i<=lastLine - 1; i++) { result.append(mDocument->getLine(i)); } - result.append(mDocument->getLine(Last).left(ColTo-1)); + result.append(mDocument->getLine(lastLine).left(chTo-1)); } + } + break; + case SelectionMode::Column: { + int xFrom, xTo; + firstLine = blockBegin().line; + xFrom = charToGlyphLeft(blockBegin().line, blockBegin().ch); + lastLine = blockEnd().line; + xTo = charToGlyphLeft(blockEnd().line, blockEnd().ch); + if (xFrom > xTo) + std::swap(xFrom, xTo); + if (firstLine>lastLine) + std::swap(firstLine,lastLine); + for (int i = firstLine; i <= lastLine; i++) { + int l = xposToGlyphStartChar(i,xFrom); + int r = xposToGlyphStartChar(i,xTo-1)+1; + QString s = mDocument->getLine(i-1); + result.append(s.mid(l-1,r-l)); + } + } break; - case SelectionMode::Column: - First = blockBegin().line; - ColFrom = charToColumn(blockBegin().line, blockBegin().ch); - Last = blockEnd().line; - ColTo = charToColumn(blockEnd().line, blockEnd().ch); - if (ColFrom > ColTo) - std::swap(ColFrom, ColTo); - if (First>Last) - std::swap(First,Last); - for (int i = First; i <= Last; i++) { - int l = columnToChar(i,ColFrom); - int r = columnToChar(i,ColTo-1)+1; - QString s = mDocument->getLine(i-1); - result.append(s.mid(l-1,r-l)); - } - break; case SelectionMode::Line: // If block selection includes LastLine, // line break code(s) of the last line will not be added. - for (int i= First; i<=Last - 1;i++) { + for (int i= firstLine; i<=lastLine - 1;i++) { result.append(mDocument->getLine(i)); } - result.append(mDocument->getLine(Last)); - if (Last < mDocument->count() - 1) + result.append(mDocument->getLine(lastLine)); + if (lastLine < mDocument->count() - 1) result.append(""); break; } @@ -4803,21 +4796,21 @@ void QSynEdit::moveCaretVert(int deltaY, bool isSelection) else ptDst = bufferToDisplayPos(blockEnd()); } - ptDst.Row+=deltaY; + ptDst.row+=deltaY; if (deltaY >= 0) { - if (rowToLine(ptDst.Row) > mDocument->count()) { - ptDst.Row = std::max(1, displayLineCount()); + if (rowToLine(ptDst.row) > mDocument->count()) { + ptDst.row = std::max(1, displayLineCount()); } } else { - if (ptDst.Row < 1) { - ptDst.Row = 1; + if (ptDst.row < 1) { + ptDst.row = 1; } } - if (ptO.Row != ptDst.Row) { + if (ptO.row != ptDst.row) { if (mOptions.testFlag(eoKeepCaretX)) - ptDst.Column = mLastCaretColumn; + ptDst.x = mLastCaretColumn; } if (mOptions.testFlag(eoAltSetsColumnMode) && (mActiveSelectionMode != SelectionMode::Line)) { @@ -4828,8 +4821,8 @@ void QSynEdit::moveCaretVert(int deltaY, bool isSelection) } BufferCoord vDstLineChar; - if (ptDst.Row == ptO.Row && isSelection && deltaY!=0) { - if (ptDst.Row==1) { + if (ptDst.row == ptO.row && isSelection && deltaY!=0) { + if (ptDst.row==1) { vDstLineChar.ch=1; vDstLineChar.line=1; } else { @@ -4840,8 +4833,8 @@ void QSynEdit::moveCaretVert(int deltaY, bool isSelection) vDstLineChar = displayToBufferPos(ptDst); if (mActiveSelectionMode==SelectionMode::Column) { - int cols=mDocument->lineColumns(vDstLineChar.line-1); - if (cols+1lineWidth(vDstLineChar.line-1); + if (w+1 ColTo) - std::swap(ColFrom, ColTo); - if (First > Last) - std::swap(First,Last); + int firstLine = startPos.line - 1; + int xFrom = charToGlyphLeft(startPos.line, startPos.ch); + int lastLine = endPos.line - 1; + int xTo = charToGlyphLeft(endPos.line, endPos.ch); + if (xFrom > xTo) + std::swap(xFrom, xTo); + if (firstLine > lastLine) + std::swap(firstLine,lastLine); QString result; - for (int i = First; i <= Last; i++) { - int l = columnToChar(i+1,ColFrom); - int r = columnToChar(i+1,ColTo-1)+1; + for (int i = firstLine; i <= lastLine; i++) { + int l = xposToGlyphStartChar(i+1,xFrom); + int r = xposToGlyphStartChar(i+1,xTo-1)+1; QString s = mDocument->getLine(i); s.remove(l-1,r-l); properSetLine(i,s); } // Lines never get deleted completely, so keep caret at end. - startPos.ch = columnToChar(startPos.line,ColFrom); - endPos.ch = columnToChar(endPos.line, ColFrom); + startPos.ch = xposToGlyphStartChar(startPos.line,xFrom); + endPos.ch = xposToGlyphStartChar(endPos.line, xFrom); internalSetCaretXY(startPos); setBlockBegin(startPos); setBlockEnd(endPos); @@ -5504,7 +5497,7 @@ int QSynEdit::doInsertTextByColumnMode(const QStringList& text, int startLine, i BufferCoord lineBreakPos; int result = 0; DisplayCoord insertCoord = bufferToDisplayPos(caretXY()); - int insertCol = insertCoord.Column; + int insertXPos = insertCoord.x; line = startLine; if (!mUndoing) { beginEditing(); @@ -5515,7 +5508,7 @@ int QSynEdit::doInsertTextByColumnMode(const QStringList& text, int startLine, i int insertPos = 0; if (line > mDocument->count()) { result++; - tempString = QString(insertCol - 1,' ') + str; + tempString = QString(insertXPos - 1,' ') + str; mDocument->addLine(""); if (!mUndoing) { result++; @@ -5528,12 +5521,12 @@ int QSynEdit::doInsertTextByColumnMode(const QStringList& text, int startLine, i } } else { tempString = mDocument->getLine(line - 1); - len = mDocument->lineColumns(line-1); - if (len < insertCol) { + len = mDocument->lineWidth(line-1); + if (len < insertXPos) { insertPos = tempString.length()+1; - tempString = tempString + QString(insertCol - len - 1,' ') + str; + tempString = tempString + QString(insertXPos - len - 1,' ') + str; } else { - insertPos = columnToChar(line,insertCol); + insertPos = xposToGlyphStartChar(line,insertXPos); tempString.insert(insertPos-1,str); } } @@ -6622,9 +6615,9 @@ void QSynEdit::onLinesChanged() if (mActiveSelectionMode == SelectionMode::Column) { BufferCoord oldBlockStart = blockBegin(); BufferCoord oldBlockEnd = blockEnd(); - int colEnd = charToColumn(mCaretY,mCaretX); - oldBlockStart.ch = columnToChar(oldBlockStart.line,colEnd); - oldBlockEnd.ch = columnToChar(oldBlockEnd.line,colEnd); + int xEnd = charToGlyphLeft(mCaretY,mCaretX); + oldBlockStart.ch = xposToGlyphStartChar(oldBlockStart.line,xEnd); + oldBlockEnd.ch = xposToGlyphStartChar(oldBlockEnd.line,xEnd); setBlockBegin(oldBlockStart); setBlockEnd(oldBlockEnd); } else { @@ -6774,9 +6767,9 @@ void QSynEdit::setBlockEnd(BufferCoord value) else value.ch = 1; } else { - int maxLen = mDocument->longestLineColumns(); + int maxLen = mDocument->longestLineWidth(); if (syntaxer()) - maxLen += stringColumns(syntaxer()->foldString(""),maxLen); + maxLen += stringWidth(syntaxer()->foldString(""),maxLen); value.ch = minMax(value.ch, 1, maxLen+1); } if (value.ch != mBlockEnd.ch || value.line != mBlockEnd.line) { @@ -6881,9 +6874,9 @@ void QSynEdit::setBlockBegin(BufferCoord value) else value.ch = 1; } else { - int maxLen = mDocument->longestLineColumns(); + int maxLen = mDocument->longestLineWidth(); if (syntaxer()) - maxLen += stringColumns(syntaxer()->foldString(""),maxLen); + maxLen += stringWidth(syntaxer()->foldString(""),maxLen); value.ch = minMax(value.ch, 1, maxLen+1); } if (selAvail()) { diff --git a/libs/qsynedit/qsynedit/qsynedit.h b/libs/qsynedit/qsynedit/qsynedit.h index 80b5e29c..9a2a0350 100644 --- a/libs/qsynedit/qsynedit/qsynedit.h +++ b/libs/qsynedit/qsynedit/qsynedit.h @@ -175,12 +175,12 @@ public: int leftSpaces(const QString& line) const; QString GetLeftSpacing(int charCount,bool wantTabs) const; - int charToColumn(int aLine, int aChar) const; - int charToColumn(int aLine, const QString& s, int aChar) const; + int charToGlyphLeft(int line, int charPos) const; + int charToGlyphLeft(int line, const QString& s, int charPos) const; //int charToColumn(const QString& s, int aChar) const; - int columnToChar(int aLine, int aColumn) const; - int columnToChar(int aLine, const QString& s, int aColumn) const; - int stringColumns(const QString& line, int colsBefore) const; + int xposToGlyphStartChar(int line, int xpos) const; + int xposToGlyphStartChar(int line, const QString& s, 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; @@ -317,7 +317,7 @@ public: int linesInWindow() const; int leftChar() const; - void setLeftChar(int Value); + void setLeftChar(int value); BufferCoord blockBegin() const; BufferCoord blockEnd() const; @@ -368,8 +368,9 @@ public: EditorOptions getOptions() const; void setOptions(const EditorOptions &Value); - int tabWidth() const { return mDocument->tabWidth(); } - void setTabWidth(int tabWidth); + int tabSize() const { return mDocument->tabSize(); } + void setTabSize(int tabSize); + int tabWidth() const { return mDocument->tabWidth(); } QColor caretColor() const; void setCaretColor(const QColor &caretColor); diff --git a/libs/qsynedit/qsynedit/types.h b/libs/qsynedit/qsynedit/types.h index 422dcbcb..a403659b 100644 --- a/libs/qsynedit/qsynedit/types.h +++ b/libs/qsynedit/qsynedit/types.h @@ -52,8 +52,8 @@ struct BufferCoord { }; struct DisplayCoord { - int Column; - int Row; + int x; + int row; }; enum FontStyle {