From b94a9489d2e522214974f8e939039a20d502a84d Mon Sep 17 00:00:00 2001 From: Le Tan Date: Fri, 10 Aug 2018 20:46:15 +0800 Subject: [PATCH] PegMarkdownHighlighter: fix the timer issue --- src/pegmarkdownhighlighter.cpp | 52 ++++++++++++++++++++-------------- src/pegmarkdownhighlighter.h | 9 ++++++ src/vlivepreviewhelper.cpp | 18 ++++++++++-- src/vlivepreviewhelper.h | 4 +++ 4 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/pegmarkdownhighlighter.cpp b/src/pegmarkdownhighlighter.cpp index 8376fc34..40e5a9b1 100644 --- a/src/pegmarkdownhighlighter.cpp +++ b/src/pegmarkdownhighlighter.cpp @@ -22,6 +22,7 @@ PegMarkdownHighlighter::PegMarkdownHighlighter(QTextDocument *p_doc, VMdEditor * m_codeBlockTimeStamp(0), m_parser(NULL), m_parserExts(pmh_EXT_NOTES | pmh_EXT_STRIKE | pmh_EXT_FRONTMATTER | pmh_EXT_MARK), + m_parseInterval(50), m_notifyHighlightComplete(false) { } @@ -38,6 +39,8 @@ void PegMarkdownHighlighter::init(const QVector &p_styles, m_parserExts |= pmh_EXT_MATH; } + m_parseInterval = p_timerInterval; + m_codeBlockFormat.setForeground(QBrush(Qt::darkYellow)); for (int index = 0; index < m_styles.size(); ++index) { switch (m_styles[index].type) { @@ -65,24 +68,18 @@ void PegMarkdownHighlighter::init(const QVector &p_styles, m_timer = new QTimer(this); m_timer->setSingleShot(true); - m_timer->setInterval(p_timerInterval); + m_timer->setInterval(m_parseInterval); connect(m_timer, &QTimer::timeout, this, &PegMarkdownHighlighter::startParse); m_fastParseTimer = new QTimer(this); m_fastParseTimer->setSingleShot(true); - m_fastParseTimer->setInterval(5); + m_fastParseTimer->setInterval(50); connect(m_fastParseTimer, &QTimer::timeout, this, [this]() { - QSharedPointer result(m_fastResult); - if (!result->matched(m_timeStamp) || m_result->matched(m_timeStamp)) { - return; - } - - for (int i = m_fastParseBlocks.first; i <= m_fastParseBlocks.second; ++i) { - QTextBlock block = m_doc->findBlockByNumber(i); - rehighlightBlock(block); - } + startFastParse(m_fastParseInfo.m_position, + m_fastParseInfo.m_charsRemoved, + m_fastParseInfo.m_charsAdded); }); m_scrollRehighlightTimer = new QTimer(this); @@ -271,16 +268,17 @@ void PegMarkdownHighlighter::handleContentsChange(int p_position, int p_charsRem ++m_timeStamp; + m_timer->stop(); + if (m_timeStamp > 2) { - startFastParse(p_position, p_charsRemoved, p_charsAdded); + m_fastParseInfo.m_position = p_position; + m_fastParseInfo.m_charsRemoved = p_charsRemoved; + m_fastParseInfo.m_charsAdded = p_charsAdded; + m_fastParseTimer->start(); } // We still need a timer to start a complete parse. - if (m_timeStamp == 2) { - m_timer->start(0); - } else { - m_timer->start(); - } + m_timer->start(m_timeStamp == 2 ? 0 : m_parseInterval); } void PegMarkdownHighlighter::startParse() @@ -338,11 +336,19 @@ void PegMarkdownHighlighter::startFastParse(int p_position, int p_charsRemoved, void PegMarkdownHighlighter::processFastParseResult(const QSharedPointer &p_result) { - m_fastParseTimer->stop(); m_fastResult.reset(new PegHighlighterFastResult(this, p_result)); + // Add additional single format blocks. updateSingleFormatBlocks(m_fastResult->m_blocksHighlights); - m_fastParseTimer->start(); + + if (!m_fastResult->matched(m_timeStamp) || m_result->matched(m_timeStamp)) { + return; + } + + for (int i = m_fastParseBlocks.first; i <= m_fastParseBlocks.second; ++i) { + QTextBlock block = m_doc->findBlockByNumber(i); + rehighlightBlock(block); + } } static bool compHLUnitStyle(const HLUnitStyle &a, const HLUnitStyle &b) @@ -759,10 +765,14 @@ void PegMarkdownHighlighter::getFastParseBlockRange(int p_position, goto goup; } - if (VEditUtils::fetchIndentation(firstBlock) == 0) { + if (VEditUtils::fetchIndentation(firstBlock) < 4) { // If previous block is empty, then we could stop now. if (VEditUtils::isEmptyBlock(preBlock)) { - break; + int preState = preBlock.userState(); + if (preState != HighlightBlockState::CodeBlockStart + && preState != HighlightBlockState::CodeBlock) { + break; + } } } diff --git a/src/pegmarkdownhighlighter.h b/src/pegmarkdownhighlighter.h index c5584389..74b50afd 100644 --- a/src/pegmarkdownhighlighter.h +++ b/src/pegmarkdownhighlighter.h @@ -74,6 +74,13 @@ private slots: void handleParseResult(const QSharedPointer &p_result); private: + struct FastParseInfo + { + int m_position; + int m_charsRemoved; + int m_charsAdded; + } m_fastParseInfo; + void startParse(); void startFastParse(int p_position, int p_charsRemoved, int p_charsAdded); @@ -189,6 +196,8 @@ private: // Timer to trigger parse. QTimer *m_timer; + int m_parseInterval; + QTimer *m_fastParseTimer; QTimer *m_scrollRehighlightTimer; diff --git a/src/vlivepreviewhelper.cpp b/src/vlivepreviewhelper.cpp index 9989fe2a..978d8df8 100644 --- a/src/vlivepreviewhelper.cpp +++ b/src/vlivepreviewhelper.cpp @@ -1,6 +1,7 @@ #include "vlivepreviewhelper.h" #include +#include #include "veditor.h" #include "vdocument.h" @@ -83,11 +84,18 @@ VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor, m_plantUMLHelper(NULL), m_lastInplacePreviewSize(0), m_timeStamp(0), - m_scaleFactor(VUtils::calculateScaleFactor()) + m_scaleFactor(VUtils::calculateScaleFactor()), + m_lastCursorBlock(-1) { - connect(m_editor->object(), &VEditorObject::cursorPositionChanged, + m_livePreviewTimer = new QTimer(this); + m_livePreviewTimer->setSingleShot(true); + m_livePreviewTimer->setInterval(100); + connect(m_livePreviewTimer, &QTimer::timeout, this, &VLivePreviewHelper::handleCursorPositionChanged); + connect(m_editor->object(), SIGNAL(cursorPositionChanged()), + m_livePreviewTimer, SLOT(start())); + m_flowchartEnabled = g_config->getEnableFlowchart(); m_mermaidEnabled = g_config->getEnableMermaid(); m_plantUMLMode = g_config->getPlantUMLMode(); @@ -206,10 +214,16 @@ void VLivePreviewHelper::updateCodeBlocks(TimeStamp p_timeStamp, const QVectortextCursorW().block().blockNumber(); + if (m_lastCursorBlock == cursorBlock) { + return; + } + + m_lastCursorBlock = cursorBlock; int left = 0, right = m_codeBlocks.size() - 1; int mid = left; diff --git a/src/vlivepreviewhelper.h b/src/vlivepreviewhelper.h index f9662204..32ae8f89 100644 --- a/src/vlivepreviewhelper.h +++ b/src/vlivepreviewhelper.h @@ -250,6 +250,10 @@ private: // Indexed by content. QHash> m_cache; + + int m_lastCursorBlock; + + QTimer *m_livePreviewTimer; }; inline bool VLivePreviewHelper::isPreviewEnabled() const