mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
Editor: improve trailing space highlight performance
This commit is contained in:
parent
8679ffa051
commit
24a20e60e9
@ -21,7 +21,9 @@ VEditor::VEditor(VFile *p_file, QWidget *p_editor)
|
||||
m_file(p_file),
|
||||
m_editOps(nullptr),
|
||||
m_document(nullptr),
|
||||
m_enableInputMethod(true)
|
||||
m_enableInputMethod(true),
|
||||
m_timeStamp(0),
|
||||
m_trailingSpaceSelectionTS(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -33,6 +35,7 @@ void VEditor::init()
|
||||
{
|
||||
const int labelTimerInterval = 500;
|
||||
const int extraSelectionHighlightTimer = 500;
|
||||
const int trailingSpaceUpdateTimer = 500;
|
||||
const int labelSize = 64;
|
||||
|
||||
m_document = documentW();
|
||||
@ -67,6 +70,12 @@ void VEditor::init()
|
||||
QObject::connect(m_highlightTimer, &QTimer::timeout,
|
||||
m_object, &VEditorObject::doHighlightExtraSelections);
|
||||
|
||||
m_trailingSpaceTimer = new QTimer(m_editor);
|
||||
m_trailingSpaceTimer->setSingleShot(true);
|
||||
m_trailingSpaceTimer->setInterval(trailingSpaceUpdateTimer);
|
||||
QObject::connect(m_trailingSpaceTimer, &QTimer::timeout,
|
||||
m_object, &VEditorObject::doUpdateTrailingSpaceHighlights);
|
||||
|
||||
m_extraSelections.resize((int)SelectionId::MaxSelection);
|
||||
|
||||
updateFontAndPalette();
|
||||
@ -80,18 +89,56 @@ void VEditor::labelTimerTimeout()
|
||||
m_wrapLabel->hide();
|
||||
}
|
||||
|
||||
void VEditor::updateTrailingSpaceHighlights()
|
||||
{
|
||||
if (m_trailingSpaceSelectionTS != m_timeStamp) {
|
||||
m_trailingSpaceTimer->start();
|
||||
} else {
|
||||
highlightExtraSelections(false);
|
||||
}
|
||||
}
|
||||
|
||||
void VEditor::doHighlightExtraSelections()
|
||||
{
|
||||
int nrExtra = m_extraSelections.size();
|
||||
Q_ASSERT(nrExtra == (int)SelectionId::MaxSelection);
|
||||
QList<QTextEdit::ExtraSelection> extraSelects;
|
||||
for (int i = 0; i < nrExtra; ++i) {
|
||||
if (i == (int)SelectionId::TrailingSapce) {
|
||||
filterTrailingSpace(extraSelects, m_extraSelections[i]);
|
||||
} else {
|
||||
extraSelects.append(m_extraSelections[i]);
|
||||
}
|
||||
}
|
||||
|
||||
setExtraSelectionsW(extraSelects);
|
||||
}
|
||||
|
||||
void VEditor::doUpdateTrailingSpaceHighlights()
|
||||
{
|
||||
if (!g_config->getEnableTrailingSpaceHighlight()) {
|
||||
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::TrailingSapce];
|
||||
if (!selects.isEmpty()) {
|
||||
selects.clear();
|
||||
highlightExtraSelections(true);
|
||||
}
|
||||
|
||||
m_trailingSpaceSelectionTS = m_timeStamp;
|
||||
return;
|
||||
}
|
||||
|
||||
QTextCharFormat format;
|
||||
format.setBackground(m_trailingSpaceColor);
|
||||
QString text("\\s+$");
|
||||
highlightTextAll(text,
|
||||
FindOption::RegularExpression,
|
||||
SelectionId::TrailingSapce,
|
||||
format);
|
||||
|
||||
m_trailingSpaceSelectionTS = m_timeStamp;
|
||||
highlightExtraSelections(true);
|
||||
}
|
||||
|
||||
void VEditor::updateEditConfig()
|
||||
{
|
||||
m_config.update(QFontMetrics(m_editor->font()));
|
||||
@ -109,13 +156,13 @@ void VEditor::highlightOnCursorPositionChanged()
|
||||
|
||||
QTextCursor cursor = textCursorW();
|
||||
if (lastCursor.isNull() || cursor.blockNumber() != lastCursor.blockNumber()) {
|
||||
updateTrailingSpaceHighlights();
|
||||
highlightCurrentLine();
|
||||
highlightTrailingSpace();
|
||||
} else {
|
||||
// Judge whether we have trailing space at current line.
|
||||
QString text = cursor.block().text();
|
||||
if (text.rbegin()->isSpace()) {
|
||||
highlightTrailingSpace();
|
||||
updateTrailingSpaceHighlights();
|
||||
}
|
||||
|
||||
// Handle word-wrap in one block.
|
||||
@ -129,6 +176,11 @@ void VEditor::highlightOnCursorPositionChanged()
|
||||
lastCursor = cursor;
|
||||
}
|
||||
|
||||
void VEditor::updateTimeStamp()
|
||||
{
|
||||
++m_timeStamp;
|
||||
}
|
||||
|
||||
void VEditor::highlightCurrentLine()
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::CurrentLine];
|
||||
@ -172,46 +224,25 @@ void VEditor::highlightCurrentLine()
|
||||
highlightExtraSelections(true);
|
||||
}
|
||||
|
||||
// Do not highlight trailing spaces with current cursor right behind.
|
||||
static void trailingSpaceFilter(VEditor *p_editor, QList<QTextEdit::ExtraSelection> &p_result)
|
||||
void VEditor::filterTrailingSpace(QList<QTextEdit::ExtraSelection> &p_selects,
|
||||
const QList<QTextEdit::ExtraSelection> &p_src)
|
||||
{
|
||||
QTextCursor cursor = p_editor->textCursorW();
|
||||
QTextCursor cursor = textCursorW();
|
||||
if (!cursor.atBlockEnd()) {
|
||||
p_selects.append(p_src);
|
||||
return;
|
||||
}
|
||||
|
||||
int cursorPos = cursor.position();
|
||||
for (auto it = p_result.begin(); it != p_result.end(); ++it) {
|
||||
for (auto it = p_src.begin(); it != p_src.end(); ++it) {
|
||||
if (it->cursor.selectionEnd() == cursorPos) {
|
||||
p_result.erase(it);
|
||||
|
||||
// There will be only one.
|
||||
return;
|
||||
continue;
|
||||
} else {
|
||||
p_selects.append(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VEditor::highlightTrailingSpace()
|
||||
{
|
||||
if (!g_config->getEnableTrailingSpaceHighlight()) {
|
||||
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::TrailingSapce];
|
||||
if (!selects.isEmpty()) {
|
||||
selects.clear();
|
||||
highlightExtraSelections(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QTextCharFormat format;
|
||||
format.setBackground(m_trailingSpaceColor);
|
||||
QString text("\\s+$");
|
||||
highlightTextAll(text,
|
||||
FindOption::RegularExpression,
|
||||
SelectionId::TrailingSapce,
|
||||
format,
|
||||
trailingSpaceFilter);
|
||||
}
|
||||
|
||||
void VEditor::highlightExtraSelections(bool p_now)
|
||||
{
|
||||
m_highlightTimer->stop();
|
||||
|
@ -212,6 +212,8 @@ protected:
|
||||
// Do some highlight on cursor position changed.
|
||||
void highlightOnCursorPositionChanged();
|
||||
|
||||
void updateTimeStamp();
|
||||
|
||||
// Highlight selected text.
|
||||
void highlightSelectedWord();
|
||||
|
||||
@ -246,7 +248,9 @@ protected:
|
||||
private:
|
||||
friend class VEditorObject;
|
||||
|
||||
void highlightTrailingSpace();
|
||||
// Filter out the trailing space right before cursor.
|
||||
void filterTrailingSpace(QList<QTextEdit::ExtraSelection> &p_selects,
|
||||
const QList<QTextEdit::ExtraSelection> &p_src);
|
||||
|
||||
// Trigger the timer to request highlight.
|
||||
// If @p_now is true, stop the timer and highlight immediately.
|
||||
@ -310,6 +314,9 @@ private:
|
||||
// Timer for extra selections highlight.
|
||||
QTimer *m_highlightTimer;
|
||||
|
||||
// Timer for update trailing space.
|
||||
QTimer *m_trailingSpaceTimer;
|
||||
|
||||
bool m_readyToScroll;
|
||||
bool m_mouseMoveScrolled;
|
||||
int m_oriMouseX;
|
||||
@ -318,12 +325,20 @@ private:
|
||||
// Whether enable input method.
|
||||
bool m_enableInputMethod;
|
||||
|
||||
TimeStamp m_timeStamp;
|
||||
|
||||
TimeStamp m_trailingSpaceSelectionTS;
|
||||
|
||||
// Functions for private slots.
|
||||
private:
|
||||
void labelTimerTimeout();
|
||||
|
||||
// Do the real work to highlight extra selections.
|
||||
void doHighlightExtraSelections();
|
||||
|
||||
void updateTrailingSpaceHighlights();
|
||||
|
||||
void doUpdateTrailingSpaceHighlights();
|
||||
};
|
||||
|
||||
|
||||
@ -387,6 +402,11 @@ private slots:
|
||||
m_editor->doHighlightExtraSelections();
|
||||
}
|
||||
|
||||
void doUpdateTrailingSpaceHighlights()
|
||||
{
|
||||
m_editor->doUpdateTrailingSpaceHighlights();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class VEditor;
|
||||
|
||||
|
@ -52,6 +52,14 @@ VMdEditor::VMdEditor(VFile *p_file,
|
||||
highlightOnCursorPositionChanged();
|
||||
});
|
||||
|
||||
connect(document(), &QTextDocument::contentsChange,
|
||||
this, [this](int p_position, int p_charsRemoved, int p_charsAdded) {
|
||||
Q_UNUSED(p_position);
|
||||
if (p_charsAdded > 0 || p_charsAdded > 0) {
|
||||
updateTimeStamp();
|
||||
}
|
||||
});
|
||||
|
||||
connect(this, &VTextEdit::selectionChanged,
|
||||
this, [this]() {
|
||||
highlightSelectedWord();
|
||||
|
Loading…
x
Reference in New Issue
Block a user