update max line width in background

This commit is contained in:
Roy Qu 2024-05-07 14:41:04 +08:00
parent 8faa2c0aa6
commit 8fef396baa
5 changed files with 253 additions and 121 deletions

View File

@ -25,27 +25,24 @@
#include <QMessageBox> #include <QMessageBox>
#include <cmath> #include <cmath>
#include "qt_utils/charsetinfo.h" #include "qt_utils/charsetinfo.h"
#include <QDateTime>
#include <QDebug> #include <QDebug>
namespace QSynedit { namespace QSynedit {
Document::Document(const QFont& font, QObject *parent): Document::Document(const QFont& font, QObject *parent):
QObject{parent}, QObject{parent},
mFontMetrics{font},
mTabSize{4},
mForceMonospace{false},
mSetLineWidthLockCount{0}, mSetLineWidthLockCount{0},
mMaxLineChangedInSetLinesWidth{false}, mMaxLineChangedInSetLinesWidth{false},
mMutex{} mMutex{},
mGlyphCalculator{font}
{ {
mAppendNewLineAtEOF = true; mAppendNewLineAtEOF = true;
mNewlineType = NewlineType::Windows; mNewlineType = NewlineType::Windows;
mIndexOfLongestLine = -1; mIndexOfLongestLine = -1;
mUpdateCount = 0; mUpdateCount = 0;
mCharWidth = mFontMetrics.horizontalAdvance("M"); mUpdateDocumentLineWidthFunc = std::bind(&GlyphCalculator::calcLineWidth,
mSpaceWidth = mFontMetrics.horizontalAdvance(" "); &mGlyphCalculator,
mUpdateDocumentLineWidthFunc = std::bind(&Document::calcLineWidth,
this,
std::placeholders::_1, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_2,
std::placeholders::_3); std::placeholders::_3);
@ -95,6 +92,22 @@ int Document::lineWidth(int line)
return 0; return 0;
} }
void Document::updateLineWidth(int line)
{
QMutexLocker locker(&mMutex);
if (line>=0 && line < mLines.size()) {
if (mLines[line]->mWidth<0) {
int width;
QList<int> glyphPositions = mGlyphCalculator.calcLineWidth(
mLines[line]->lineText(),
mLines[line]->glyphStartCharList(),
width);
setLineWidth(line, width,glyphPositions);
mLines[line]->mIsTempWidth = true;
}
}
}
int Document::lineWidth(int line, const QString &newText) int Document::lineWidth(int line, const QString &newText)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
@ -104,7 +117,7 @@ int Document::lineWidth(int line, const QString &newText)
if (lineText==newText) { if (lineText==newText) {
return mLines[line]->width(); return mLines[line]->width();
} else { } else {
return stringWidth(newText,0); return mGlyphCalculator.stringWidth(newText,0);
} }
} }
@ -571,40 +584,22 @@ void Document::saveUTF32File(QFile &file, QTextCodec* codec)
file.write(codec->fromUnicode(text)); file.write(codec->fromUnicode(text));
} }
bool Document::forceMonospace() const void Document::setTabSize(int newTabSize)
{ {
return mForceMonospace; if (tabSize()!=newTabSize) {
mGlyphCalculator.setTabSize(newTabSize);
invalidateAllLineWidth();
}
} }
void Document::setForceMonospace(bool newForceMonospace) void Document::setForceMonospace(bool newForceMonospace)
{ {
int oldValue = mForceMonospace; int oldValue = forceMonospace();
mForceMonospace = newForceMonospace; mGlyphCalculator.setForceMonospace(newForceMonospace);
if (oldValue != mForceMonospace) if (oldValue != newForceMonospace)
invalidateAllLineWidth(); invalidateAllLineWidth();
} }
const QFontMetrics &Document::fontMetrics() const
{
return mFontMetrics;
}
void Document::setFont(const QFont &newFont)
{
mFontMetrics = QFontMetrics(newFont);
mCharWidth = mFontMetrics.horizontalAdvance("M");
mSpaceWidth = mFontMetrics.horizontalAdvance(" ");
invalidateAllLineWidth();
}
void Document::setTabSize(int newTabSize)
{
if (mTabSize!=newTabSize) {
mTabSize = newTabSize;
invalidateAllLineWidth();
}
}
void Document::loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding) void Document::loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
@ -888,7 +883,7 @@ QList<int> calcGlyphStartCharList(const QString &text)
return glyphStartCharList; return glyphStartCharList;
} }
int Document::stringWidth(const QString &str, int left) const int GlyphCalculator::stringWidth(const QString &str, int left) const
{ {
QList<int> glyphStartCharList = calcGlyphStartCharList(str); QList<int> glyphStartCharList = calcGlyphStartCharList(str);
int right; int right;
@ -896,7 +891,7 @@ int Document::stringWidth(const QString &str, int left) const
return right - left; return right - left;
} }
int Document::stringWidth(const QString &str, int left, const QFontMetrics &fontMetrics) int GlyphCalculator::stringWidth(const QString &str, int left, const QFontMetrics &fontMetrics)
{ {
QList<int> glyphStartCharList = calcGlyphStartCharList(str); QList<int> glyphStartCharList = calcGlyphStartCharList(str);
int right; int right;
@ -944,11 +939,6 @@ int Document::glyphWidth(int line, int glyphIdx)
return mLines[line]->glyphWidth(glyphIdx); return mLines[line]->glyphWidth(glyphIdx);
} }
int Document::glyphWidth(const QString &glyph, int left) const
{
return glyphWidth(glyph,left,mFontMetrics,mForceMonospace);
}
int Document::charToGlyphIndex(int line, int charIdx) int Document::charToGlyphIndex(int line, int charIdx)
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
@ -974,12 +964,7 @@ int Document::charToGlyphIndex(const QString& str, QList<int> glyphStartCharList
// return glyphStartCharList.length()-1; // return glyphStartCharList.length()-1;
} }
QList<int> Document::calcLineWidth(const QString &lineText, const QList<int> &glyphStartCharList, int &width) QList<int> GlyphCalculator::calcGlyphPositionList(const QString &lineText, const QList<int> &glyphStartCharList, const QFontMetrics &fontMetrics, int left, int &right) const
{
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
}
QList<int> Document::calcGlyphPositionList(const QString &lineText, const QList<int> &glyphStartCharList, const QFontMetrics &fontMetrics, int left, int &right) const
{ {
right = std::max(0,left); right = std::max(0,left);
int start,end; int start,end;
@ -1050,7 +1035,7 @@ int Document::charToGlyphStartPosition(int line, const QString newStr, int charP
QList<int> glyphStartCharList = calcGlyphStartCharList(newStr); QList<int> glyphStartCharList = calcGlyphStartCharList(newStr);
int glyphIdx = charToGlyphIndex(newStr, glyphStartCharList, charPos); int glyphIdx = charToGlyphIndex(newStr, glyphStartCharList, charPos);
int width; int width;
QList<int> glyphStartPositionList = calcGlyphPositionList(newStr, width); QList<int> glyphStartPositionList = mGlyphCalculator.calcGlyphPositionList(newStr, width);
if (glyphIdx<glyphStartCharList.length()) if (glyphIdx<glyphStartCharList.length())
return glyphStartPositionList[glyphIdx]; return glyphStartPositionList[glyphIdx];
else else
@ -1069,7 +1054,7 @@ int Document::xposToGlyphStartChar(int line, const QString newStr, int xpos)
glyphPositionList = mLines[line]->glyphStartPositionList(); glyphPositionList = mLines[line]->glyphStartPositionList();
width = mLines[line]->width(); width = mLines[line]->width();
} else { } else {
glyphPositionList = calcGlyphPositionList(mLines[line]->lineText(), width); glyphPositionList = mGlyphCalculator.calcGlyphPositionList(mLines[line]->lineText(), width);
} }
int glyphIdx = xposToGlyphIndex(width, glyphPositionList, xpos); int glyphIdx = xposToGlyphIndex(width, glyphPositionList, xpos);
return mLines[line]->glyphStartChar(glyphIdx); return mLines[line]->glyphStartChar(glyphIdx);
@ -1206,7 +1191,8 @@ void Document::updateMaxLineWidthChanged()
if (mSetLineWidthLockCount>0) { if (mSetLineWidthLockCount>0) {
mMaxLineChangedInSetLinesWidth = true; mMaxLineChangedInSetLinesWidth = true;
} else { } else {
updateMaxLineWidthAndNotify(); //updateMaxLineWidthAndNotify();
emit maxLineWidthChanged();
} }
} }
@ -1227,15 +1213,7 @@ void Document::updateMaxLineWidthAndNotify()
emit maxLineWidthChanged(); emit maxLineWidthChanged();
} }
QList<int> Document::calcGlyphPositionList(const QString &lineText, const QList<int> &glyphStartCharList, int left, int &right) const QList<int> GlyphCalculator::calcGlyphPositionList(const QString &lineText, int &width) const
{
return calcGlyphPositionList(lineText, glyphStartCharList,
mFontMetrics,
left,right);
}
QList<int> Document::calcGlyphPositionList(const QString &lineText, int &width) const
{ {
QList<int> glyphStartCharList = calcGlyphStartCharList(lineText); QList<int> glyphStartCharList = calcGlyphStartCharList(lineText);
return calcGlyphPositionList(lineText,glyphStartCharList,0,width); return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
@ -1290,13 +1268,20 @@ void Document::invalidateAllLineWidth()
line->invalidateWidth(); line->invalidateWidth();
} }
mIndexOfLongestLine = -1; mIndexOfLongestLine = -1;
FindMaxLineWidthThread *thread = new FindMaxLineWidthThread(mLines, mGlyphCalculator);
connect(thread, &FindMaxLineWidthThread::maxWidthLineFound,
this, &Document::maxWidthLineFound);
connect(thread, &QThread::finished,
thread, &QThread::deleteLater);
thread->start();
} }
DocumentLine::DocumentLine(DocumentLine::UpdateWidthFunc updateWidthFunc): DocumentLine::DocumentLine(DocumentLine::UpdateWidthFunc updateWidthFunc):
mSyntaxState{}, mSyntaxState{},
mWidth{-1}, mWidth{-1},
mIsTempWidth{true}, mIsTempWidth{true},
mUpdateWidthFunc{updateWidthFunc} mUpdateWidthFunc{updateWidthFunc},
mTimestamp{QDateTime::currentMSecsSinceEpoch()}
{ {
} }
@ -1339,6 +1324,7 @@ int DocumentLine::width()
void DocumentLine::setLineText(const QString &newLineText) void DocumentLine::setLineText(const QString &newLineText)
{ {
mTimestamp = QDateTime::currentMSecsSinceEpoch();
mLineText = newLineText; mLineText = newLineText;
mGlyphStartCharList = calcGlyphStartCharList(newLineText); mGlyphStartCharList = calcGlyphStartCharList(newLineText);
invalidateWidth(); invalidateWidth();
@ -1697,7 +1683,7 @@ int searchForSegmentIdx(const QList<int> &segList, int minVal, int maxVal, int v
return -1; return -1;
} }
int Document::updateGlyphStartPositionList( int GlyphCalculator::updateGlyphStartPositionList(
const QString &lineText, const QString &lineText,
const QList<int> &glyphStartCharList, int startChar, int endChar, const QList<int> &glyphStartCharList, int startChar, int endChar,
const QFontMetrics &fontMetrics, const QFontMetrics &fontMetrics,
@ -1724,7 +1710,7 @@ int Document::updateGlyphStartPositionList(
return right-left; return right-left;
} }
int Document::glyphWidth(const QString &glyph, int left, const QFontMetrics &fontMetrics, bool forceMonospace) const int GlyphCalculator::glyphWidth(const QString &glyph, int left, const QFontMetrics &fontMetrics, bool forceMonospace) const
{ {
int glyphWidth; int glyphWidth;
if (glyph.length()==0) if (glyph.length()==0)
@ -1769,4 +1755,45 @@ int segmentIntervalStart(const QList<int> &segList, int minVal, int maxVal, int
return segList[idx]; return segList[idx];
} }
GlyphCalculator::GlyphCalculator(const QFont &font):
mFontMetrics{font},
mTabSize{4},
mForceMonospace{false}
{
mCharWidth = mFontMetrics.horizontalAdvance("M");
mSpaceWidth = mFontMetrics.horizontalAdvance(" ");
}
void GlyphCalculator::setFont(const QFont &newFont)
{
mFontMetrics = QFontMetrics(newFont);
mCharWidth = mFontMetrics.horizontalAdvance("M");
mSpaceWidth = mFontMetrics.horizontalAdvance(" ");
}
FindMaxLineWidthThread::FindMaxLineWidthThread(const DocumentLines &lines, const GlyphCalculator &glyphCalculator, QObject *parent):
QThread(parent),
mLines{lines},
mGlyphCalculator{glyphCalculator}
{
}
void FindMaxLineWidthThread::run()
{
int maxWidth = 0;
int maxWidthLine = -1;
for (int i=0;i<mLines.size();i++) {
int width = mLines[i]->mWidth;
if ( width < 0 )
width = mGlyphCalculator.stringWidth(mLines[i]->lineText(),0);
if (width > maxWidth) {
maxWidth = width;
maxWidthLine = i;
}
}
if (maxWidthLine >= 0)
emit maxWidthLineFound(maxWidthLine);
}
} }

View File

@ -36,6 +36,7 @@ QList<int> calcGlyphStartCharList(const QString &text);
void expandGlyphStartCharList(const QString& strAdded, int oldStrLen, QList<int> &glyphStartCharList); void expandGlyphStartCharList(const QString& strAdded, int oldStrLen, QList<int> &glyphStartCharList);
class Document; class Document;
class FindMaxLineWidthThread;
using SearchConfirmAroundProc = std::function<bool ()>; using SearchConfirmAroundProc = std::function<bool ()>;
/** /**
@ -178,8 +179,9 @@ private:
int mWidth; int mWidth;
bool mIsTempWidth; bool mIsTempWidth;
UpdateWidthFunc mUpdateWidthFunc; UpdateWidthFunc mUpdateWidthFunc;
qint64 mTimestamp;
friend class Document; friend class Document;
friend class FindMaxLineWidthThread;
}; };
typedef std::shared_ptr<DocumentLine> PDocumentLine; typedef std::shared_ptr<DocumentLine> PDocumentLine;
@ -195,6 +197,105 @@ public:
explicit BinaryFileError (const QString& reason); explicit BinaryFileError (const QString& reason);
}; };
class GlyphCalculator {
public:
explicit GlyphCalculator(const QFont& font);
int tabSize() const {
return mTabSize;
}
void setTabSize(int newTabSize) { mTabSize = newTabSize; }
int tabWidth() const {
return mTabSize * spaceWidth();
}
int spaceWidth() const {
if (mForceMonospace)
return mCharWidth;
return mSpaceWidth;
}
bool forceMonospace() const { return mForceMonospace; }
void setForceMonospace(bool newForceMonospace) { mForceMonospace = newForceMonospace; }
const QFontMetrics &fontMetrics() const { return mFontMetrics; }
void setFont(const QFont &newFont);
int glyphWidth(const QString& glyph, int left,
const QFontMetrics &fontMetrics,
bool forceMonospace) const;
int glyphWidth(const QString &glyph, int left) const{
return glyphWidth(glyph,left,mFontMetrics,mForceMonospace);
}
QList<int> calcGlyphPositionList(const QString& lineText, const QList<int> &glyphStartCharList,
const QFontMetrics &fontMetrics,
int left, int &right) const;
QList<int> calcGlyphPositionList(const QString& lineText, const QList<int> &glyphStartCharList, int left, int &right) const {
return calcGlyphPositionList(lineText, glyphStartCharList,
mFontMetrics,
left,right);
}
/**
* @brief calculate display width of a string
*
* 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 left start x pos of the string
* @return width of the string, don't including colsBefore
*/
int stringWidth(const QString &str, int left) const;
int stringWidth(const QString &str, int left, const QFontMetrics &fontMetrics);
QList<int> calcLineWidth(const QString& lineText, const QList<int> &glyphStartCharList, int &width) {
return calcGlyphPositionList(lineText,glyphStartCharList,0,width);
}
QList<int> calcGlyphPositionList(const QString& lineText, int &width) const;
int updateGlyphStartPositionList(
const QString& lineText,
const QList<int> &glyphStartCharList,
int startChar, int endChar,
const QFontMetrics &fontMetrics,
QList<int> &glyphStartPositionList,
int left, int &right, int &startGlyph, int &endGlyph) const;
private:
QFontMetrics mFontMetrics;
int mTabSize;
int mCharWidth;
int mSpaceWidth;
bool mForceMonospace;
};
class FindMaxLineWidthThread: public QThread {
Q_OBJECT
public:
explicit FindMaxLineWidthThread(
const DocumentLines &lines,
const GlyphCalculator& glyphCalculator,
QObject* parent=nullptr);
FindMaxLineWidthThread(const FindMaxLineWidthThread&) = delete;
signals:
void maxWidthLineFound(int line);
private:
DocumentLines mLines;
GlyphCalculator mGlyphCalculator;
// QThread interface
protected:
void run() override;
};
/** /**
* @brief The Document class * @brief The Document class
* *
@ -248,6 +349,8 @@ public:
* @return * @return
*/ */
int lineWidth(int line); int lineWidth(int line);
void updateLineWidth(int line);
/** /**
* @brief get width of the specified text / line * @brief get width of the specified text / line
@ -425,20 +528,12 @@ public:
QString glyph(int line, int glyphIdx); QString glyph(int line, int glyphIdx);
QString glyphAt(int line, int charPos); QString glyphAt(int line, int charPos);
int stringWidth(const QString &str, int left) const {
return mGlyphCalculator.stringWidth(str, left);
}
int charToGlyphStartChar(int line, int charPos); int charToGlyphStartChar(int line, int charPos);
//int columnToGlyphStartColumn(int line, int charPos); //int columnToGlyphStartColumn(int line, int charPos);
/**
* @brief calculate display width of a string
*
* 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 left start x pos of the string
* @return width of the string, don't including colsBefore
*/
int stringWidth(const QString &str, int left) const;
int stringWidth(const QString &str, int left, const QFontMetrics &fontMetrics);
int glyphCount(int line); int glyphCount(int line);
/** /**
@ -485,7 +580,9 @@ public:
*/ */
int glyphWidth(int line, int glyphIdx); int glyphWidth(int line, int glyphIdx);
int glyphWidth(const QString &glyph, int left) const; int glyphWidth(const QString &glyph, int left) const {
return mGlyphCalculator.glyphWidth(glyph,left);
}
/** /**
* @brief get index of the glyph represented by the specified char * @brief get index of the glyph represented by the specified char
@ -514,14 +611,6 @@ public:
int charToGlyphStartPosition(int line, const QString newStr, int charPos); int charToGlyphStartPosition(int line, const QString newStr, int charPos);
int xposToGlyphStartChar(int line, const QString newStr, int xpos); int xposToGlyphStartChar(int line, const QString newStr, int xpos);
int updateGlyphStartPositionList(
const QString& lineText,
const QList<int> &glyphStartCharList,
int startChar, int endChar,
const QFontMetrics &fontMetrics,
QList<int> &glyphStartPositionList,
int left, int &right, int &startGlyph, int &endGlyph) const;
bool getAppendNewLineAtEOF(); bool getAppendNewLineAtEOF();
void setAppendNewLineAtEOF(bool appendNewLineAtEOF); void setAppendNewLineAtEOF(bool appendNewLineAtEOF);
@ -530,26 +619,21 @@ public:
bool empty(); bool empty();
int tabSize() const { int tabSize() const { return mGlyphCalculator.tabSize(); }
return mTabSize;
}
int tabWidth() const { int tabWidth() const { return mGlyphCalculator.tabWidth(); }
return mTabSize * spaceWidth();
}
int spaceWidth() const { int spaceWidth() const { return mGlyphCalculator.spaceWidth(); }
if (mForceMonospace)
return mCharWidth;
return mSpaceWidth;
}
void setTabSize(int newTabSize); void setTabSize(int newTabSize);
const QFontMetrics &fontMetrics() const; const QFontMetrics &fontMetrics() const { return mGlyphCalculator.fontMetrics(); }
void setFont(const QFont &newFont); void setFont(const QFont &newFont) {
mGlyphCalculator.setFont(newFont);
invalidateAllLineWidth();
}
bool forceMonospace() const; bool forceMonospace() const { return mGlyphCalculator.forceMonospace(); }
void setForceMonospace(bool newForceMonospace); void setForceMonospace(bool newForceMonospace);
public slots: public slots:
@ -563,6 +647,7 @@ signals:
void inserted(int startLine, int count); void inserted(int startLine, int count);
void putted(int line); void putted(int line);
void maxLineWidthChanged(); void maxLineWidthChanged();
void lineWidthUpdateNeeded(int line);
protected: protected:
QString getTextStr() const; QString getTextStr() const;
void setUpdateState(bool Updating); void setUpdateState(bool Updating);
@ -570,6 +655,9 @@ protected:
void addItem(const QString& s); void addItem(const QString& s);
void putTextStr(const QString& text); void putTextStr(const QString& text);
void internalClear(); void internalClear();
void maxWidthLineFound(int line) {
emit lineWidthUpdateNeeded(line);
}
private: private:
bool lineWidthValid(int line); bool lineWidthValid(int line);
void beginSetLinesWidth(); void beginSetLinesWidth();
@ -578,18 +666,8 @@ private:
void updateMaxLineWidthChanged(); void updateMaxLineWidthChanged();
void updateMaxLineWidthAndNotify(); void updateMaxLineWidthAndNotify();
int glyphWidth(const QString& glyph, int left,
const QFontMetrics &fontMetrics,
bool forceMonospace) const;
int xposToGlyphIndex(int strWidth, QList<int> glyphPositionList, int xpos) const; int xposToGlyphIndex(int strWidth, QList<int> glyphPositionList, int xpos) const;
int charToGlyphIndex(const QString& str, QList<int> glyphStartCharList, int charPos) const; int charToGlyphIndex(const QString& str, QList<int> glyphStartCharList, int charPos) const;
QList<int> calcLineWidth(const QString& lineText, const QList<int> &glyphStartCharList, int &width);
QList<int> calcGlyphPositionList(const QString& lineText, const QList<int> &glyphStartCharList,
const QFontMetrics &fontMetrics,
int left, int &right) const;
QList<int> calcGlyphPositionList(const QString& lineText, const QList<int> &glyphStartCharList, int left, int &right) const;
QList<int> calcGlyphPositionList(const QString& lineText, int &width) const;
QList<int> getGlyphStartCharList(int line, const QString &lineText); QList<int> getGlyphStartCharList(int line, const QString &lineText);
QList<int> getGlyphStartCharList(int line); QList<int> getGlyphStartCharList(int line);
QList<int> getGlyphStartPositionList(int line); QList<int> getGlyphStartPositionList(int line);
@ -605,24 +683,17 @@ private:
DocumentLine::UpdateWidthFunc mUpdateDocumentLineWidthFunc; DocumentLine::UpdateWidthFunc mUpdateDocumentLineWidthFunc;
//SynEdit* mEdit;
QFontMetrics mFontMetrics;
int mTabSize;
int mCharWidth;
int mSpaceWidth;
//int mCount;
//int mCapacity;
NewlineType mNewlineType; NewlineType mNewlineType;
bool mAppendNewLineAtEOF; bool mAppendNewLineAtEOF;
int mIndexOfLongestLine; int mIndexOfLongestLine;
int mUpdateCount; int mUpdateCount;
bool mForceMonospace;
int mSetLineWidthLockCount; int mSetLineWidthLockCount;
bool mMaxLineChangedInSetLinesWidth; bool mMaxLineChangedInSetLinesWidth;
QRecursiveMutex mMutex; QRecursiveMutex mMutex;
GlyphCalculator mGlyphCalculator;
friend class QSynEditPainter; friend class QSynEditPainter;
}; };

View File

@ -750,7 +750,6 @@ void QSynEditPainter::addHighlightToken(
} }
if (mIsSpecialLine) { if (mIsSpecialLine) {
QColor oldForeground = foreground;
if (mSpecialLineForeground.isValid()) if (mSpecialLineForeground.isValid())
foreground = mSpecialLineForeground; foreground = mSpecialLineForeground;
if (mSpecialLineBackground.isValid()) if (mSpecialLineBackground.isValid())
@ -788,7 +787,7 @@ void QSynEditPainter::addHighlightToken(
} }
//calculate width of the token ( and update it's glyph start positions ) //calculate width of the token ( and update it's glyph start positions )
if (calcGlyphPosition) { if (calcGlyphPosition) {
tokenWidth = mEdit->mDocument->updateGlyphStartPositionList( tokenWidth = mEdit->mDocument->mGlyphCalculator.updateGlyphStartPositionList(
lineText, lineText,
glyphStartCharList, glyphStartCharList,
tokenStartChar, tokenStartChar,

View File

@ -44,6 +44,20 @@
#define UPDATE_HORIZONTAL_SCROLLBAR_EVENT ((QEvent::Type)(QEvent::User+1)) #define UPDATE_HORIZONTAL_SCROLLBAR_EVENT ((QEvent::Type)(QEvent::User+1))
#define UPDATE_VERTICAL_SCROLLBAR_EVENT ((QEvent::Type)(QEvent::User+2)) #define UPDATE_VERTICAL_SCROLLBAR_EVENT ((QEvent::Type)(QEvent::User+2))
#define UPDATE_LINE_WIDTH_EVENT ((QEvent::Type)(QEvent::User+3))
class UpdateLineWidthEvent: public QEvent{
public:
explicit UpdateLineWidthEvent(int line):
QEvent{UPDATE_LINE_WIDTH_EVENT},
mLine{line}
{
}
int line() const { return mLine; }
private:
int mLine;
};
namespace QSynedit { namespace QSynedit {
QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent), QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent),
@ -77,6 +91,7 @@ QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent),
connect(mDocument.get(), &Document::cleared, this, &QSynEdit::updateVScrollbar); connect(mDocument.get(), &Document::cleared, this, &QSynEdit::updateVScrollbar);
connect(mDocument.get(), &Document::deleted, this, &QSynEdit::updateVScrollbar); connect(mDocument.get(), &Document::deleted, this, &QSynEdit::updateVScrollbar);
connect(mDocument.get(), &Document::inserted, this, &QSynEdit::updateVScrollbar); connect(mDocument.get(), &Document::inserted, this, &QSynEdit::updateVScrollbar);
connect(mDocument.get(), &Document::lineWidthUpdateNeeded, this, &QSynEdit::onLineWidthUpdateNeeded);
mGutterWidth = 0; mGutterWidth = 0;
@ -1755,6 +1770,12 @@ void QSynEdit::onMaxLineWidthChanged()
updateHScrollBarLater(); updateHScrollBarLater();
} }
void QSynEdit::onLineWidthUpdateNeeded(int line)
{
UpdateLineWidthEvent * event = new UpdateLineWidthEvent(line);
qApp->postEvent(this,event);
}
void QSynEdit::updateHScrollBarLater() void QSynEdit::updateHScrollBarLater()
{ {
QEvent * event = new QEvent(UPDATE_HORIZONTAL_SCROLLBAR_EVENT); QEvent * event = new QEvent(UPDATE_HORIZONTAL_SCROLLBAR_EVENT);
@ -3143,6 +3164,11 @@ void QSynEdit::doUpdateVScrollbar()
verticalScrollBar()->setSingleStep(mTextHeight); verticalScrollBar()->setSingleStep(mTextHeight);
} }
void QSynEdit::doUpdateLineWidth(int line)
{
mDocument->updateLineWidth(line);
}
void QSynEdit::updateCaret() void QSynEdit::updateCaret()
{ {
@ -5979,10 +6005,17 @@ bool QSynEdit::event(QEvent *event)
{ {
switch(event->type()) { switch(event->type()) {
case UPDATE_HORIZONTAL_SCROLLBAR_EVENT: case UPDATE_HORIZONTAL_SCROLLBAR_EVENT:
event->setAccepted(true);
doUpdateHScrollbar(); doUpdateHScrollbar();
break; break;
case UPDATE_LINE_WIDTH_EVENT: {
event->setAccepted(true);
UpdateLineWidthEvent* updateEvent = dynamic_cast<UpdateLineWidthEvent *>(event);
doUpdateLineWidth(updateEvent->line());
}
break;
case QEvent::KeyPress:{ case QEvent::KeyPress:{
QKeyEvent* keyEvent = static_cast<QKeyEvent *>(event); QKeyEvent* keyEvent = dynamic_cast<QKeyEvent *>(event);
if(keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab) if(keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab)
{ {
// process tab key presse event // process tab key presse event

View File

@ -525,6 +525,7 @@ private:
void doUpdateHScrollbar(); void doUpdateHScrollbar();
void updateVScrollbar(); void updateVScrollbar();
void doUpdateVScrollbar(); void doUpdateVScrollbar();
void doUpdateLineWidth(int line);
void updateCaret(); void updateCaret();
void recalcCharExtent(); void recalcCharExtent();
QString expandAtWideGlyphs(const QString& S); QString expandAtWideGlyphs(const QString& S);
@ -645,6 +646,7 @@ private:
private slots: private slots:
void onMaxLineWidthChanged(); void onMaxLineWidthChanged();
void onLineWidthUpdateNeeded(int line);
void updateHScrollBarLater(); void updateHScrollBarLater();
void onBookMarkOptionsChanged(); void onBookMarkOptionsChanged();
void onGutterChanged(); void onGutterChanged();