PegMarkdownHighlighter: fix the timer issue

This commit is contained in:
Le Tan 2018-08-10 20:46:15 +08:00
parent 4db6c1cc7b
commit b94a9489d2
4 changed files with 60 additions and 23 deletions

View File

@ -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<HighlightingStyle> &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<HighlightingStyle> &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<PegHighlighterFastResult> 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<PegParseResult> &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;
}
}
}

View File

@ -74,6 +74,13 @@ private slots:
void handleParseResult(const QSharedPointer<PegParseResult> &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;

View File

@ -1,6 +1,7 @@
#include "vlivepreviewhelper.h"
#include <QByteArray>
#include <QTimer>
#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 QVector<V
void VLivePreviewHelper::handleCursorPositionChanged()
{
if (!m_livePreviewEnabled || m_codeBlocks.isEmpty()) {
m_lastCursorBlock = -1;
return;
}
int cursorBlock = m_editor->textCursorW().block().blockNumber();
if (m_lastCursorBlock == cursorBlock) {
return;
}
m_lastCursorBlock = cursorBlock;
int left = 0, right = m_codeBlocks.size() - 1;
int mid = left;

View File

@ -250,6 +250,10 @@ private:
// Indexed by content.
QHash<QString, QSharedPointer<CodeBlockImageCacheEntry>> m_cache;
int m_lastCursorBlock;
QTimer *m_livePreviewTimer;
};
inline bool VLivePreviewHelper::isPreviewEnabled() const