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;
}
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)
{
QMutexLocker locker(&mMutex);
@ -479,8 +495,10 @@ void Document::setUpdateState(bool Updating)
int Document::calculateLineColumns(int Index)
{
PDocumentLine line = mLines[Index];
line->setColumns( glyphsColumns(line->lineText(), line->glyphPositions(), 0));
QList<int> glyphColumns;
int columns;
glyphColumns = calcGlyphColumns(line->lineText(), line->glyphPositions(), 0, columns);
line->setColumns(columns, glyphColumns);
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 columns = std::max(0,colsBefore);
int start,end;
for (int i=0;i<glyphPositions.length();i++) {
start = glyphPositions[i];
if (i+1<glyphPositions.length()) {
end = glyphPositions[i+1];
int columns;
calcGlyphColumns(lineText,glyphPositions,colsBefore, columns);
return columns - colsBefore;
}
int Document::glyphsColumns(int line, const QString &newText, int colsBefore)
{
QMutexLocker locker(&mMutex);
if (index>=0 && index < mLines.size()) {
return 0;
}
QString lineText = mLines[line]->lineText();
if (lineText == newText) {
QList<int> glyphPositions = mLines[line]->lineText();
return glyphsColumns(lineText, glyphPositions, colsBefore);
} else {
end = lineText.length();
return stringColumns(newText, colsBefore);
}
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));
}
int Document::glyphsColumns(int line, int colsBefore)
{
QMutexLocker locker(&mMutex);
if (index>=0 && index < mLines.size()) {
return 0;
}
} else {
int width = mNonAsciiFontMetrics.horizontalAdvance(glyph);
glyphCols = std::max(1.0, std::ceil(width / (double)mCharWidth));
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;
}
columns+=glyphCols;
}
return columns-colsBefore;
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)
@ -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()
{
QMutexLocker locker(&mMutex);

View File

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

View File

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

View File

@ -329,7 +329,7 @@ int QSynEdit::maxScrollWidth() const
{
int maxLen = mDocument->longestLineColumns();
if (syntaxer())
maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen);
maxLen += stringColumns(syntaxer()->foldString(""),maxLen);
if (mOptions.testFlag(eoScrollPastEol))
return std::max(maxLen ,1);
else
@ -841,22 +841,20 @@ int QSynEdit::charToColumn(int aLine, int aChar) const
{
if (aLine>=1 && aLine <= mDocument->count()) {
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;
}
int QSynEdit::charToColumn(const QString &s, int aChar) const
{
int x = 0;
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;
return mDocument->charToColumn(s, aChar);
}
int QSynEdit::columnToChar(int aLine, int aColumn) const
@ -6781,7 +6779,7 @@ void QSynEdit::setBlockEnd(BufferCoord value)
} else {
int maxLen = mDocument->longestLineColumns();
if (syntaxer())
maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen);
maxLen += stringColumns(syntaxer()->foldString(""),maxLen);
value.ch = minMax(value.ch, 1, maxLen+1);
}
if (value.ch != mBlockEnd.ch || value.line != mBlockEnd.line) {
@ -6888,7 +6886,7 @@ void QSynEdit::setBlockBegin(BufferCoord value)
} else {
int maxLen = mDocument->longestLineColumns();
if (syntaxer())
maxLen = maxLen+stringColumns(syntaxer()->foldString(""),maxLen);
maxLen += stringColumns(syntaxer()->foldString(""),maxLen);
value.ch = minMax(value.ch, 1, maxLen+1);
}
if (selAvail()) {