work save

This commit is contained in:
Roy Qu 2024-01-20 21:08:46 +08:00
parent e78bb8db7e
commit 5953696beb
4 changed files with 135 additions and 46 deletions

View File

@ -93,6 +93,22 @@ int Document::lineColumns(int index)
return 0; return 0;
} }
int Document::lineColumns(int index, const QString &newText)
{
QMutexLocker locker(&mMutex);
if (index<0 || index >= mLines.size())
return 0;
QString lineText = mLines[index];
if (lineText==newText) {
if (mLines[index]->columns() == -1) {
return calculateLineColumns(index);
} else
return mLines[index]->columns();
} else {
return stringColumns(newText,0);
}
}
int Document::blockLevel(int index) int Document::blockLevel(int index)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
@ -479,8 +495,10 @@ void Document::setUpdateState(bool Updating)
int Document::calculateLineColumns(int Index) int Document::calculateLineColumns(int Index)
{ {
PDocumentLine line = mLines[Index]; PDocumentLine line = mLines[Index];
QList<int> glyphColumns;
line->setColumns( glyphsColumns(line->lineText(), line->glyphPositions(), 0)); int columns;
glyphColumns = calcGlyphColumns(line->lineText(), line->glyphPositions(), 0, columns);
line->setColumns(columns, glyphColumns);
return line->columns(); return line->columns();
} }
@ -836,32 +854,64 @@ int Document::stringColumns(const QString &line, int colsBefore) const
int Document::glyphsColumns(const QString& lineText, const QList<int> &glyphPositions, int colsBefore) const int Document::glyphsColumns(const QString& lineText, const QList<int> &glyphPositions, int colsBefore) const
{ {
int columns = std::max(0,colsBefore); int columns;
int start,end; calcGlyphColumns(lineText,glyphPositions,colsBefore, columns);
for (int i=0;i<glyphPositions.length();i++) { return columns - colsBefore;
start = glyphPositions[i]; }
if (i+1<glyphPositions.length()) {
end = glyphPositions[i+1]; int Document::glyphsColumns(int line, const QString &newText, int colsBefore)
} else { {
end = lineText.length(); QMutexLocker locker(&mMutex);
} if (index>=0 && index < mLines.size()) {
QString glyph = lineText.mid(start,end-start); return 0;
int glyphCols;
if (glyph.length()==1 && glyph[0].unicode()<0xFF) {
QChar ch = glyph[0];
if (ch == '\t') {
glyphCols = mTabWidth - columns % mTabWidth;
} else {
int width = mFontMetrics.horizontalAdvance(ch);
glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth));
}
} else {
int width = mNonAsciiFontMetrics.horizontalAdvance(glyph);
glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth));
}
columns+=glyphCols;
} }
return columns-colsBefore; QString lineText = mLines[line]->lineText();
if (lineText == newText) {
QList<int> glyphPositions = mLines[line]->lineText();
return glyphsColumns(lineText, glyphPositions, colsBefore);
} else {
return stringColumns(newText, colsBefore);
}
}
int Document::glyphsColumns(int line, int colsBefore)
{
QMutexLocker locker(&mMutex);
if (index>=0 && index < mLines.size()) {
return 0;
}
QString lineText = mLines[line]->lineText();
QList<int> glyphPositions = mLines[line]->lineText();
return glyphsColumns(lineText, glyphPositions, colsBefore);
}
int Document::charToColumn(const QString &lineText, int charPos) const
{
QList<int> glyphPositions = calcGlyphPositions(lineText);
return charToColumn(lineText, glyphPositions, charPos);
}
int Document::charToColumn(const QString &lineText, const QList<int> &glyphPositions, int charPos) const
{
Q_ASSERT(charPos<lineText.length() && charPos>=0);
int glyphIdx;
for (glyphIdx=0;glyphIdx<glyphPositions.length();glyphIdx++) {
if (charPos<glyphPositions[glyphIdx])
break;
}
int cols=0;
return glyphsColumns(lineText, glyphPositions.mid(0,glyphIdx-1),0);
}
int Document::columnToChar(const QString &lineText, int column) const
{
QList<int> glyphPositions = calcGlyphPositions(lineText);
return columnToChar(lineText, glyphPositions, charPos);
}
int Document::columnToChar(const QString &lineText, const QList<int> &glyphPositions, int column) const
{
} }
void Document::putTextStr(const QString &text) void Document::putTextStr(const QString &text)
@ -903,6 +953,38 @@ void Document::internalClear()
} }
} }
QList<int> Document::calcGlyphColumns(const QString &lineText, const QList<int> &glyphPositions, int colsBefore, int &totalColumns)
{
int totalColumns = std::max(0,colsBefore);
int start,end;
QList<int> glyphColumns;
for (int i=0;i<glyphPositions.length();i++) {
start = glyphPositions[i];
if (i+1<glyphPositions.length()) {
end = glyphPositions[i+1];
} else {
end = lineText.length();
}
QString glyph = lineText.mid(start,end-start);
int glyphCols;
if (glyph.length()==1 && glyph[0].unicode()<0xFF) {
QChar ch = glyph[0];
if (ch == '\t') {
glyphCols = mTabWidth - columns % mTabWidth;
} else {
int width = mFontMetrics.horizontalAdvance(ch);
glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth));
}
} else {
int width = mNonAsciiFontMetrics.horizontalAdvance(glyph);
glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth));
}
glyphColumns.append(columns);
totalColumns+=glyphCols;
}
return glyphColumns;
}
NewlineType Document::getNewlineType() NewlineType Document::getNewlineType()
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);

View File

@ -52,11 +52,12 @@ public:
void setSyntaxState(const SyntaxState &newSyntaxState) { mSyntaxState = newSyntaxState; } void setSyntaxState(const SyntaxState &newSyntaxState) { mSyntaxState = newSyntaxState; }
private: private:
void setLineText(const QString &newLineText); void setLineText(const QString &newLineText);
void setColumns(int cols) { mColumns = cols; } void setColumns(int cols, QList<int> glyphCols) { mColumns = cols; mGlyphColumns = glyphCols; }
void invalidateColumns() { mColumns = -1; } void invalidateColumns() { mColumns = -1; mGlyphColumns.clear(); }
private: private:
QString mLineText; QString mLineText;
QList<int> mGlyphPositions; QList<int> mGlyphPositions;
QList<int> mGlyphColumns;
SyntaxState mSyntaxState; SyntaxState mSyntaxState;
int mColumns; int mColumns;
friend class Document; friend class Document;
@ -87,6 +88,7 @@ public:
int bracketLevel(int index); int bracketLevel(int index);
int braceLevel(int index); int braceLevel(int index);
int lineColumns(int index); int lineColumns(int index);
int lineColumns(int index, const QString &newText);
int blockLevel(int index); int blockLevel(int index);
int blockStarted(int index); int blockStarted(int index);
int blockEnded(int index); int blockEnded(int index);
@ -122,8 +124,13 @@ public:
void loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding); void loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding);
void saveToFile(QFile& file, const QByteArray& encoding, void saveToFile(QFile& file, const QByteArray& encoding,
const QByteArray& defaultEncoding, QByteArray& realEncoding); const QByteArray& defaultEncoding, QByteArray& realEncoding);
int stringColumns(const QString &line, int colsBefore) const; int stringColumns(const QString &lineText, int colsBefore) const;
int glyphsColumns(const QString& lineText, const QList<int> &glyphPositions, int colsBefore) const;
int charToColumn(const QString& lineText, int charPos) const;
int charToColumn(const QString& lineText, const QList<int> &glyphPositions, int charPos) const;
int columnToChar(const QString& lineText, int column) const;
int columnToChar(const QString& lineText, const QList<int> &glyphPositions, int column) const;
bool getAppendNewLineAtEOF(); bool getAppendNewLineAtEOF();
void setAppendNewLineAtEOF(bool appendNewLineAtEOF); void setAppendNewLineAtEOF(bool appendNewLineAtEOF);
@ -159,6 +166,8 @@ protected:
void putTextStr(const QString& text); void putTextStr(const QString& text);
void internalClear(); void internalClear();
private: private:
QList<int> calcGlyphColumns(const QString& lineText, const QList<int> &glyphPositions, int colsBefore, int &totalColumns);
int glyphsColumns(const QString& lineText, const QList<int> &glyphPositions, int colsBefore) const;
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file); bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
void loadUTF16BOMFile(QFile& file); void loadUTF16BOMFile(QFile& file);
void loadUTF32BOMFile(QFile& file); void loadUTF32BOMFile(QFile& file);

View File

@ -899,9 +899,9 @@ void QSynEditPainter::paintLines()
if (!edit->mSyntaxer || !edit->mSyntaxer->enabled()) { if (!edit->mSyntaxer || !edit->mSyntaxer->enabled()) {
sToken = sLine; sToken = sLine;
if (bCurrentLine) { if (bCurrentLine) {
nTokenColumnLen = edit->stringColumns(sLine,0); nTokenColumnLen = edit->lineColumns(vLine-1, sLine,0);
} else { } else {
nTokenColumnLen = edit->mDocument->lineColumns(vLine-1); nTokenColumnLen = edit->lineColumns(vLine-1);
} }
if (edit->mOptions.testFlag(eoShowLineBreaks) && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) { if (edit->mOptions.testFlag(eoShowLineBreaks) && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) {
sToken = sToken + LineBreakGlyph; sToken = sToken + LineBreakGlyph;

View File

@ -329,7 +329,7 @@ int QSynEdit::maxScrollWidth() const
{ {
int maxLen = mDocument->longestLineColumns(); int maxLen = mDocument->longestLineColumns();
if (syntaxer()) if (syntaxer())
maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen); maxLen += stringColumns(syntaxer()->foldString(""),maxLen);
if (mOptions.testFlag(eoScrollPastEol)) if (mOptions.testFlag(eoScrollPastEol))
return std::max(maxLen ,1); return std::max(maxLen ,1);
else else
@ -841,22 +841,20 @@ int QSynEdit::charToColumn(int aLine, int aChar) const
{ {
if (aLine>=1 && aLine <= mDocument->count()) { if (aLine>=1 && aLine <= mDocument->count()) {
QString s = getDisplayStringAtLine(aLine); QString s = getDisplayStringAtLine(aLine);
return charToColumn(s,aChar); QString s2 = mDocument->getLine(line-1);
if (s!=s2)
return mDocument->charToColumn(s, aChar);
else {
QList<int> glyphPositions = mDocument->getGlyphPositions(line-1);
return mDocument->charToColumn(s, glyphPositions, aChar);
}
} }
return aChar; return aChar;
} }
int QSynEdit::charToColumn(const QString &s, int aChar) const int QSynEdit::charToColumn(const QString &s, int aChar) const
{ {
int x = 0; return mDocument->charToColumn(s, aChar);
int len = std::min(aChar-1,s.length());
for (int i=0;i<len;i++) {
if (s[i] == '\t')
x+=tabWidth() - (x % tabWidth());
else
x+=charColumns(s[i]);
}
return x+1;
} }
int QSynEdit::columnToChar(int aLine, int aColumn) const int QSynEdit::columnToChar(int aLine, int aColumn) const
@ -6781,7 +6779,7 @@ void QSynEdit::setBlockEnd(BufferCoord value)
} else { } else {
int maxLen = mDocument->longestLineColumns(); int maxLen = mDocument->longestLineColumns();
if (syntaxer()) if (syntaxer())
maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen); maxLen += stringColumns(syntaxer()->foldString(""),maxLen);
value.ch = minMax(value.ch, 1, maxLen+1); value.ch = minMax(value.ch, 1, maxLen+1);
} }
if (value.ch != mBlockEnd.ch || value.line != mBlockEnd.line) { if (value.ch != mBlockEnd.ch || value.line != mBlockEnd.line) {
@ -6888,7 +6886,7 @@ void QSynEdit::setBlockBegin(BufferCoord value)
} else { } else {
int maxLen = mDocument->longestLineColumns(); int maxLen = mDocument->longestLineColumns();
if (syntaxer()) if (syntaxer())
maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen); maxLen += stringColumns(syntaxer()->foldString(""),maxLen);
value.ch = minMax(value.ch, 1, maxLen+1); value.ch = minMax(value.ch, 1, maxLen+1);
} }
if (selAvail()) { if (selAvail()) {