diff options
author | David Schulz <[email protected]> | 2025-04-01 10:27:32 +0200 |
---|---|---|
committer | David Schulz <[email protected]> | 2025-07-03 07:25:02 +0000 |
commit | 05bf976421de539ab103521248addbe0d1733ca8 (patch) | |
tree | 96ddaed2e397efda224100c627e3226d2fd5dab9 | |
parent | a551b8da9cfeb560eb8d82e56a25a1d9a6596562 (diff) |
Iterating over all blocks is not cheap for huge documents. And the
saveState function is called multiple times per edit to save the cursor
position in the history.
Change-Id: I48c516347ecd458f2210010844f9cf8f7c34682c
Reviewed-by: Christian Stenger <[email protected]>
-rw-r--r-- | src/plugins/texteditor/texteditor.cpp | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index ab2415880d8..b27ee67a8fe 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -836,6 +836,7 @@ public: void transformSelection(TransformationMethod method); void slotUpdateExtraAreaWidth(std::optional<int> width = {}); + void slotUpdateBlockCount(); void slotUpdateRequest(const QRect &r, int dy); void slotUpdateBlockNotify(const QTextBlock &); void updateTabStops(); @@ -850,6 +851,7 @@ public: void setupScrollBar(); void highlightSearchResultsInScrollBar(); void scheduleUpdateHighlightScrollBar(); + void slotFoldChanged(const int blockNumber, bool folded); void updateHighlightScrollBarNow(); struct SearchResult { int start; @@ -953,6 +955,7 @@ public: TextEditorOverlay *m_selectionHighlightOverlay = nullptr; bool snippetCheckCursor(const QTextCursor &cursor); void snippetTabOrBacktab(bool forward); + QSet<int> m_foldedBlockCache; struct AnnotationRect { @@ -1275,7 +1278,8 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) connect(&m_codeAssistant, &CodeAssistant::finished, q, &TextEditorWidget::assistFinished); - connect(q, &PlainTextEdit::blockCountChanged, this, [this] { slotUpdateExtraAreaWidth(); }); + connect(q, &PlainTextEdit::blockCountChanged, + this, &TextEditorWidgetPrivate::slotUpdateBlockCount); connect(q, &PlainTextEdit::modificationChanged, m_extraArea, QOverload<>::of(&QWidget::update)); @@ -1546,6 +1550,11 @@ void TextEditorWidgetPrivate::setDocument(const QSharedPointer<TextDocument> &do m_extraArea, QOverload<>::of(&QWidget::update)); + m_documentConnections << connect(documentLayout, + &TextDocumentLayout::foldChanged, + this, + &TextEditorWidgetPrivate::slotFoldChanged); + m_documentConnections << connect(q, &TextEditorWidget::requestBlockUpdate, documentLayout, @@ -3755,19 +3764,7 @@ QByteArray TextEditorWidget::saveState() const convertPosition(textCursor().position(), &line, &column); stream << line; stream << column; - - // store code folding state - QList<int> foldedBlocks; - QTextBlock block = document()->firstBlock(); - while (block.isValid()) { - if (TextBlockUserData::isFolded(block)) { - int number = block.blockNumber(); - foldedBlocks += number; - } - block = block.next(); - } - stream << foldedBlocks; - + stream << d->m_foldedBlockCache; stream << firstVisibleBlockNumber(); stream << lastVisibleBlockNumber(); @@ -3817,7 +3814,7 @@ void TextEditorWidget::restoreState(const QByteArray &state) stream >> columnVal; if (version >= 1) { - QList<int> collapsedBlocks; + QSet<int> collapsedBlocks; stream >> collapsedBlocks; auto foldingRestore = [this, collapsedBlocks] { QTextDocument *doc = document(); @@ -6612,6 +6609,18 @@ void TextEditorWidgetPrivate::slotUpdateExtraAreaWidth(std::optional<int> width) q->setViewportMargins(margins); } +void TextEditorWidgetPrivate::slotUpdateBlockCount() +{ + slotUpdateExtraAreaWidth(); + m_foldedBlockCache.clear(); + QTextBlock block = q->document()->firstBlock(); + while (block.isValid()) { + if (TextBlockUserData::isFolded(block)) + m_foldedBlockCache += block.blockNumber(); + block = block.next(); + } +} + struct Internal::ExtraAreaPaintEventData { ExtraAreaPaintEventData(const TextEditorWidget *editor, TextEditorWidgetPrivate *d) @@ -8278,6 +8287,14 @@ void TextEditorWidgetPrivate::scheduleUpdateHighlightScrollBar() Qt::QueuedConnection); } +void TextEditorWidgetPrivate::slotFoldChanged(const int blockNumber, bool folded) +{ + if (folded) + m_foldedBlockCache.insert(blockNumber); + else + m_foldedBlockCache.remove(blockNumber); +} + Highlight::Priority textMarkPrioToScrollBarPrio(const TextMark::Priority &prio) { switch (prio) { |