diff --git a/src/resources/export_template.html b/src/resources/export_template.html
index b4858078..1e1b6a00 100644
--- a/src/resources/export_template.html
+++ b/src/resources/export_template.html
@@ -3,7 +3,7 @@
+
diff --git a/src/resources/themes/v_moonlight/v_moonlight.css b/src/resources/themes/v_moonlight/v_moonlight.css
index fbe2dc2b..b2ae00c6 100644
--- a/src/resources/themes/v_moonlight/v_moonlight.css
+++ b/src/resources/themes/v_moonlight/v_moonlight.css
@@ -171,6 +171,7 @@ div.mermaid-diagram {
}
div.flowchart-diagram {
+ padding: 0px 5px 0px 5px;
margin: 16px 0px 16px 0px;
width: fit-content;
overflow: hidden;
@@ -179,6 +180,7 @@ div.flowchart-diagram {
}
div.plantuml-diagram {
+ padding: 5px 5px 0px 5px;
margin: 16px 0px 16px 0px;
width: fit-content;
overflow: hidden;
diff --git a/src/resources/themes/v_native/v_native.css b/src/resources/themes/v_native/v_native.css
index e6384320..2d53807d 100644
--- a/src/resources/themes/v_native/v_native.css
+++ b/src/resources/themes/v_native/v_native.css
@@ -174,12 +174,14 @@ div.mermaid-diagram {
}
div.flowchart-diagram {
+ padding: 0px 5px 0px 5px;
margin: 16px 0px 16px 0px;
width: fit-content;
overflow: hidden;
}
div.plantuml-diagram {
+ padding: 5px 5px 0px 5px;
margin: 16px 0px 16px 0px;
width: fit-content;
overflow: hidden;
diff --git a/src/resources/themes/v_pure/v_pure.css b/src/resources/themes/v_pure/v_pure.css
index b414fb90..1e4574d6 100644
--- a/src/resources/themes/v_pure/v_pure.css
+++ b/src/resources/themes/v_pure/v_pure.css
@@ -175,12 +175,14 @@ div.mermaid-diagram {
}
div.flowchart-diagram {
+ padding: 0px 5px 0px 5px;
margin: 16px 0px 16px 0px;
width: fit-content;
overflow: hidden;
}
div.plantuml-diagram {
+ padding: 5px 5px 0px 5px;
margin: 16px 0px 16px 0px;
width: fit-content;
overflow: hidden;
diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini
index 60e3567f..61fbed10 100644
--- a/src/resources/vnote.ini
+++ b/src/resources/vnote.ini
@@ -38,7 +38,7 @@ markdown_converter=2
enable_mermaid=false
; Enable MathJax
-enable_mathjax=true
+enable_mathjax=false
; Enable Flowchart.js
enable_flowchart=false
diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp
index 8520c9f1..144b0c44 100644
--- a/src/utils/vutils.cpp
+++ b/src/utils/vutils.cpp
@@ -818,19 +818,31 @@ QString VUtils::generateExportHtmlTemplate(const QString &p_renderBg, bool p_inc
QString VUtils::generateMathJaxPreviewTemplate()
{
QString templ = VNote::generateMathJaxPreviewTemplate();
- QString mj = g_config->getMathjaxJavascript();
- // Chante MathJax to be rendered as SVG.
- QRegExp reg("(Mathjax\\.js\\?config=)\\S+", Qt::CaseInsensitive);
- // mj.replace(reg, QString("\\1%1").arg("TeX-MML-AM_SVG"));
-
- templ.replace(HtmlHolder::c_JSHolder, mj);
+ templ.replace(HtmlHolder::c_JSHolder, g_config->getMathjaxJavascript());
QString extraFile;
+
+ QString mathjaxScale = QString::number((int)(100 * VUtils::calculateScaleFactor()));
+
+ /*
+ // Mermaid.
+ extraFile += "getMermaidCssStyleUrl() + "\"/>\n" +
+ "\n";
+ */
+
+ // Flowchart.
+ extraFile += "\n" +
+ "\n";
+
+ // MathJax.
extraFile += "\n";
diff --git a/src/vconstants.h b/src/vconstants.h
index 69315849..c9c36baa 100644
--- a/src/vconstants.h
+++ b/src/vconstants.h
@@ -4,6 +4,8 @@
#include
#include
+typedef unsigned long long TimeStamp;
+
// Html: rich text file;
// Markdown: Markdown text file;
// List: Infinite list file like WorkFlowy;
@@ -38,7 +40,7 @@ namespace HtmlHolder
static const QString c_JSHolder = "JS_PLACE_HOLDER";
static const QString c_cssHolder = "CSS_PLACE_HOLDER";
static const QString c_codeBlockCssHolder = "HIGHLIGHTJS_CSS_PLACE_HOLDER";
- static const QString c_globalStyleHolder = "/* BACKGROUND_PLACE_HOLDER */";
+ static const QString c_globalStyleHolder = "/* STYLE_GLOBAL_PLACE_HOLDER */";
static const QString c_extraHolder = "";
static const QString c_bodyHolder = "";
static const QString c_headHolder = "";
diff --git a/src/vdocument.cpp b/src/vdocument.cpp
index ef0e3b14..af5df365 100644
--- a/src/vdocument.cpp
+++ b/src/vdocument.cpp
@@ -147,7 +147,7 @@ void VDocument::processPlantUML(int p_id, const QString &p_format, const QString
this, &VDocument::plantUMLResultReady);
}
- m_plantUMLHelper->processAsync(p_id, p_format, p_text);
+ m_plantUMLHelper->processAsync(p_id, 0, p_format, p_text);
}
void VDocument::processGraphviz(int p_id, const QString &p_format, const QString &p_text)
@@ -158,7 +158,7 @@ void VDocument::processGraphviz(int p_id, const QString &p_format, const QString
this, &VDocument::graphvizResultReady);
}
- m_graphvizHelper->processAsync(p_id, p_format, p_text);
+ m_graphvizHelper->processAsync(p_id, 0, p_format, p_text);
}
void VDocument::setPreviewEnabled(bool p_enabled)
diff --git a/src/vdocument.h b/src/vdocument.h
index 651a0805..e60a273e 100644
--- a/src/vdocument.h
+++ b/src/vdocument.h
@@ -142,9 +142,15 @@ signals:
void wordCountInfoUpdated();
- void plantUMLResultReady(int p_id, const QString &p_format, const QString &p_result);
+ void plantUMLResultReady(int p_id,
+ unsigned long long p_timeStamp,
+ const QString &p_format,
+ const QString &p_result);
- void graphvizResultReady(int p_id, const QString &p_format, const QString &p_result);
+ void graphvizResultReady(int p_id,
+ unsigned long long p_timeStamp,
+ const QString &p_format,
+ const QString &p_result);
void requestPreviewEnabled(bool p_enabled);
diff --git a/src/vgraphvizhelper.cpp b/src/vgraphvizhelper.cpp
index a26bc4b7..f8272372 100644
--- a/src/vgraphvizhelper.cpp
+++ b/src/vgraphvizhelper.cpp
@@ -9,6 +9,7 @@ extern VConfigManager *g_config;
#define TaskIdProperty "GraphvizTaskId"
#define TaskFormatProperty "GraphvizTaskFormat"
+#define TaskTimeStampProperty "GraphvizTaskTimeStamp"
VGraphvizHelper::VGraphvizHelper(QObject *p_parent)
: QObject(p_parent)
@@ -16,10 +17,11 @@ VGraphvizHelper::VGraphvizHelper(QObject *p_parent)
prepareCommand(m_program, m_args);
}
-void VGraphvizHelper::processAsync(int p_id, const QString &p_format, const QString &p_text)
+void VGraphvizHelper::processAsync(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_text)
{
QProcess *process = new QProcess(this);
process->setProperty(TaskIdProperty, p_id);
+ process->setProperty(TaskTimeStampProperty, p_timeStamp);
process->setProperty(TaskFormatProperty, p_format);
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(handleProcessFinished(int, QProcess::ExitStatus)));
@@ -51,7 +53,8 @@ void VGraphvizHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus
QProcess *process = static_cast(sender());
int id = process->property(TaskIdProperty).toInt();
QString format = process->property(TaskFormatProperty).toString();
- qDebug() << "process finished" << id << format << p_exitCode << p_exitStatus;
+ TimeStamp timeStamp = process->property(TaskTimeStampProperty).toULongLong();
+ qDebug() << "process finished" << id << timeStamp << format << p_exitCode << p_exitStatus;
bool failed = true;
if (p_exitStatus == QProcess::NormalExit) {
if (p_exitCode < 0) {
@@ -60,9 +63,9 @@ void VGraphvizHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus
failed = false;
QByteArray outBa = process->readAllStandardOutput();
if (format == "svg") {
- emit resultReady(id, format, QString::fromLocal8Bit(outBa));
+ emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa));
} else {
- emit resultReady(id, format, QString::fromLocal8Bit(outBa.toBase64()));
+ emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa.toBase64()));
}
}
} else {
@@ -76,7 +79,7 @@ void VGraphvizHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus
qWarning() << "Graphviz stderr:" << errStr;
}
- emit resultReady(id, format, "");
+ emit resultReady(id, timeStamp, format, "");
}
process->deleteLater();
diff --git a/src/vgraphvizhelper.h b/src/vgraphvizhelper.h
index ac49c12c..ae2b2bf8 100644
--- a/src/vgraphvizhelper.h
+++ b/src/vgraphvizhelper.h
@@ -6,18 +6,20 @@
#include
#include
+#include "vconstants.h"
+
class VGraphvizHelper : public QObject
{
Q_OBJECT
public:
explicit VGraphvizHelper(QObject *p_parent = nullptr);
- void processAsync(int p_id, const QString &p_format, const QString &p_text);
+ void processAsync(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_text);
void prepareCommand(QString &p_cmd, QStringList &p_args) const;
signals:
- void resultReady(int p_id, const QString &p_format, const QString &p_result);
+ void resultReady(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_result);
private slots:
void handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_exitStatus);
diff --git a/src/vlivepreviewhelper.cpp b/src/vlivepreviewhelper.cpp
index 15488c37..b71c4a6b 100644
--- a/src/vlivepreviewhelper.cpp
+++ b/src/vlivepreviewhelper.cpp
@@ -42,6 +42,7 @@ CodeBlockPreviewInfo::CodeBlockPreviewInfo(const VCodeBlock &p_cb)
void CodeBlockPreviewInfo::clearImageData()
{
m_imgData.clear();
+ m_imgDataBa.clear();
m_inplacePreview.clear();
}
@@ -64,7 +65,6 @@ void CodeBlockPreviewInfo::updateNonContent(const QTextDocument *p_doc,
}
}
-// Update inplace preview according to m_imgData.
void CodeBlockPreviewInfo::updateInplacePreview(const VEditor *p_editor,
const QTextDocument *p_doc)
{
@@ -100,12 +100,12 @@ VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor,
m_livePreviewEnabled(false),
m_inplacePreviewEnabled(false),
m_graphvizHelper(NULL),
- m_plantUMLHelper(NULL)
+ m_plantUMLHelper(NULL),
+ m_lastInplacePreviewSize(0),
+ m_timeStamp(0)
{
connect(m_editor->object(), &VEditorObject::cursorPositionChanged,
this, &VLivePreviewHelper::handleCursorPositionChanged);
- connect(m_document, &VDocument::codeBlockPreviewReady,
- this, &VLivePreviewHelper::webAsyncResultReady);
m_flowchartEnabled = g_config->getEnableFlowchart();
m_mermaidEnabled = g_config->getEnableMermaid();
@@ -117,6 +117,9 @@ VLivePreviewHelper::VLivePreviewHelper(VEditor *p_editor,
m_mathJaxID = m_mathJaxHelper->registerIdentifier();
connect(m_mathJaxHelper, &VMathJaxPreviewHelper::mathjaxPreviewResultReady,
this, &VLivePreviewHelper::mathjaxPreviewResultReady);
+ connect(m_mathJaxHelper, &VMathJaxPreviewHelper::diagramPreviewResultReady,
+ // The same handle logics.
+ this, &VLivePreviewHelper::mathjaxPreviewResultReady);
}
bool VLivePreviewHelper::isPreviewLang(const QString &p_lang) const
@@ -134,6 +137,8 @@ void VLivePreviewHelper::updateCodeBlocks(const QVector &p_codeBlock
return;
}
+ ++m_timeStamp;
+
int lastIndex = m_cbIndex;
m_cbIndex = -1;
int cursorBlock = m_editor->textCursorW().block().blockNumber();
@@ -239,6 +244,7 @@ void VLivePreviewHelper::updateLivePreview()
if (!cb.hasImageData()) {
m_graphvizHelper->processAsync(m_cbIndex | LANG_PREFIX_GRAPHVIZ | TYPE_LIVE_PREVIEW,
+ m_timeStamp,
"svg",
removeFence(vcb.m_text));
} else {
@@ -253,6 +259,7 @@ void VLivePreviewHelper::updateLivePreview()
if (!cb.hasImageData()) {
m_plantUMLHelper->processAsync(m_cbIndex | LANG_PREFIX_PLANTUML | TYPE_LIVE_PREVIEW,
+ m_timeStamp,
"svg",
removeFence(vcb.m_text));
} else {
@@ -292,13 +299,20 @@ void VLivePreviewHelper::setInplacePreviewEnabled(bool p_enabled)
for (auto & cb : m_codeBlocks) {
cb.clearImageData();
}
+
+ updateInplacePreview();
}
}
void VLivePreviewHelper::localAsyncResultReady(int p_id,
+ TimeStamp p_timeStamp,
const QString &p_format,
const QString &p_result)
{
+ if (p_timeStamp != m_timeStamp) {
+ return;
+ }
+
Q_UNUSED(p_format);
Q_ASSERT(p_format == "svg");
int idx = p_id & INDEX_MASK;
@@ -354,6 +368,7 @@ void VLivePreviewHelper::processForInplacePreview(int p_idx)
updateInplacePreview();
} else {
m_graphvizHelper->processAsync(p_idx | LANG_PREFIX_GRAPHVIZ | TYPE_INPLACE_PREVIEW,
+ m_timeStamp,
"svg",
removeFence(vcb.m_text));
}
@@ -369,43 +384,66 @@ void VLivePreviewHelper::processForInplacePreview(int p_idx)
updateInplacePreview();
} else {
m_plantUMLHelper->processAsync(p_idx | LANG_PREFIX_PLANTUML | TYPE_INPLACE_PREVIEW,
+ m_timeStamp,
"svg",
removeFence(vcb.m_text));
}
} else if (vcb.m_lang == "flow"
|| vcb.m_lang == "flowchart") {
- m_document->previewCodeBlock(p_idx,
- vcb.m_lang,
- removeFence(vcb.m_text),
- false);
+ m_mathJaxHelper->previewDiagram(m_mathJaxID,
+ p_idx,
+ m_timeStamp,
+ vcb.m_lang,
+ removeFence(vcb.m_text));
} else if (vcb.m_lang == "mathjax") {
m_mathJaxHelper->previewMathJax(m_mathJaxID,
p_idx,
+ m_timeStamp,
removeFence(vcb.m_text));
}
}
void VLivePreviewHelper::updateInplacePreview()
{
+ QSet blocks;
QVector > images;
for (int i = 0; i < m_codeBlocks.size(); ++i) {
CodeBlockPreviewInfo &cb = m_codeBlocks[i];
if (cb.inplacePreviewReady()) {
// Generate the image.
+ bool valid = false;
if (cb.hasImageData()) {
cb.inplacePreview()->m_image.loadFromData(cb.imageData().toUtf8(),
cb.imageFormat().toLocal8Bit().data());
images.append(cb.inplacePreview());
+ valid = true;
} else if (cb.hasImageDataBa()) {
cb.inplacePreview()->m_image.loadFromData(cb.imageDataBa(),
cb.imageFormat().toLocal8Bit().data());
images.append(cb.inplacePreview());
+ valid = true;
}
+
+ if (!valid) {
+ blocks.insert(cb.inplacePreview()->m_blockNumber);
+ }
+ } else {
+ blocks.insert(cb.codeBlock().m_endBlock);
}
}
+ if (images.isEmpty() && m_lastInplacePreviewSize == 0) {
+ return;
+ }
+
emit inplacePreviewCodeBlockUpdated(images);
+ m_lastInplacePreviewSize = images.size();
+
+ if (!blocks.isEmpty()) {
+ emit checkBlocksForObsoletePreview(blocks.toList());
+ }
+
// Clear image.
for (int i = 0; i < m_codeBlocks.size(); ++i) {
CodeBlockPreviewInfo &cb = m_codeBlocks[i];
@@ -416,28 +454,18 @@ void VLivePreviewHelper::updateInplacePreview()
}
}
-void VLivePreviewHelper::webAsyncResultReady(int p_id,
- const QString &p_lang,
- const QString &p_result)
-{
- Q_UNUSED(p_lang);
- if (p_id >= m_codeBlocks.size() || p_result.isEmpty()) {
- return;
- }
-
- CodeBlockPreviewInfo &cb = m_codeBlocks[p_id];
- cb.setImageData(QStringLiteral("svg"), p_result);
- cb.updateInplacePreview(m_editor, m_doc);
- updateInplacePreview();
-}
-
void VLivePreviewHelper::mathjaxPreviewResultReady(int p_identitifer,
int p_id,
+ TimeStamp p_timeStamp,
const QString &p_format,
const QByteArray &p_data)
{
- if (p_identitifer != m_mathJaxID
- || (p_id >= m_codeBlocks.size() || p_data.isEmpty())) {
+ if (p_identitifer != m_mathJaxID || p_timeStamp != m_timeStamp) {
+ return;
+ }
+
+ if (p_id >= m_codeBlocks.size() || p_data.isEmpty()) {
+ updateInplacePreview();
return;
}
diff --git a/src/vlivepreviewhelper.h b/src/vlivepreviewhelper.h
index 3c609c68..f26b8445 100644
--- a/src/vlivepreviewhelper.h
+++ b/src/vlivepreviewhelper.h
@@ -6,6 +6,7 @@
#include "hgmarkdownhighlighter.h"
#include "vpreviewmanager.h"
+#include "vconstants.h"
class VEditor;
class VDocument;
@@ -133,18 +134,19 @@ public:
public slots:
void updateCodeBlocks(const QVector &p_codeBlocks);
- void webAsyncResultReady(int p_id, const QString &p_lang, const QString &p_result);
-
signals:
void inplacePreviewCodeBlockUpdated(const QVector > &p_images);
+ void checkBlocksForObsoletePreview(const QList &p_blocks);
+
private slots:
void handleCursorPositionChanged();
- void localAsyncResultReady(int p_id, const QString &p_format, const QString &p_result);
+ void localAsyncResultReady(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_result);
void mathjaxPreviewResultReady(int p_identitifer,
int p_id,
+ TimeStamp p_timeStamp,
const QString &p_format,
const QByteArray &p_data);
@@ -187,6 +189,10 @@ private:
// Identification for VMathJaxPreviewHelper.
int m_mathJaxID;
+
+ int m_lastInplacePreviewSize;
+
+ TimeStamp m_timeStamp;
};
inline bool VLivePreviewHelper::isPreviewEnabled() const
diff --git a/src/vmathjaxpreviewhelper.cpp b/src/vmathjaxpreviewhelper.cpp
index 3ac4307e..6fd9ead9 100644
--- a/src/vmathjaxpreviewhelper.cpp
+++ b/src/vmathjaxpreviewhelper.cpp
@@ -24,6 +24,7 @@ VMathJaxPreviewHelper::~VMathJaxPreviewHelper()
void VMathJaxPreviewHelper::doInit()
{
Q_ASSERT(!m_initialized);
+ m_initialized = true;
m_webView = new QWebEngineView(m_parentWidget);
connect(m_webView, &QWebEngineView::loadFinished,
@@ -36,9 +37,23 @@ void VMathJaxPreviewHelper::doInit()
m_webDoc = new VMathJaxWebDocument(m_webView);
connect(m_webDoc, &VMathJaxWebDocument::mathjaxPreviewResultReady,
- this, [this](int p_identifier, int p_id, const QString &p_format, const QString &p_data) {
+ this, [this](int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_format,
+ const QString &p_data) {
QByteArray ba = QByteArray::fromBase64(p_data.toUtf8());
- emit mathjaxPreviewResultReady(p_identifier, p_id, p_format, ba);
+ emit mathjaxPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, ba);
+ });
+
+ connect(m_webDoc, &VMathJaxWebDocument::diagramPreviewResultReady,
+ this, [this](int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_format,
+ const QString &p_data) {
+ QByteArray ba = QByteArray::fromBase64(p_data.toUtf8());
+ emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, ba);
});
QWebChannel *channel = new QWebChannel(m_webView);
@@ -50,15 +65,25 @@ void VMathJaxPreviewHelper::doInit()
while (!m_webReady) {
VUtils::sleepWait(100);
}
-
- m_initialized = true;
}
void VMathJaxPreviewHelper::previewMathJax(int p_identifier,
int p_id,
+ TimeStamp p_timeStamp,
const QString &p_text)
{
init();
- m_webDoc->previewMathJax(p_identifier, p_id, p_text);
+ m_webDoc->previewMathJax(p_identifier, p_id, p_timeStamp, p_text);
+}
+
+void VMathJaxPreviewHelper::previewDiagram(int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_lang,
+ const QString &p_text)
+{
+ init();
+
+ m_webDoc->previewDiagram(p_identifier, p_id, p_timeStamp, p_lang, p_text);
}
diff --git a/src/vmathjaxpreviewhelper.h b/src/vmathjaxpreviewhelper.h
index 60345653..0d798906 100644
--- a/src/vmathjaxpreviewhelper.h
+++ b/src/vmathjaxpreviewhelper.h
@@ -3,6 +3,8 @@
#include
+#include "vconstants.h"
+
class QWebEngineView;
class VMathJaxWebDocument;
class QWidget;
@@ -18,15 +20,33 @@ public:
// Get an ID for identification.
int registerIdentifier();
- // Preview @p_text and return SVG data asynchronously.
+ // Preview @p_text and return PNG data asynchronously.
// @p_identifier: identifier the caller registered;
// @p_id: internal id for each caller;
// @p_text: raw text of the MathJax script.
- void previewMathJax(int p_identifier, int p_id, const QString &p_text);
+ void previewMathJax(int p_identifier, int p_id, TimeStamp p_timeStamp, const QString &p_text);
+
+ // Preview @p_text and return PNG data asynchronously.
+ // @p_identifier: identifier the caller registered;
+ // @p_id: internal id for each caller;
+ // @p_lang: language of the diagram;
+ // @p_text: raw text of the script.
+ void previewDiagram(int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_lang,
+ const QString &p_text);
signals:
void mathjaxPreviewResultReady(int p_identifier,
int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_format,
+ const QByteArray &p_data);
+
+ void diagramPreviewResultReady(int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
const QString &p_format,
const QByteArray &p_data);
diff --git a/src/vmathjaxwebdocument.cpp b/src/vmathjaxwebdocument.cpp
index a5599c15..63b4314b 100644
--- a/src/vmathjaxwebdocument.cpp
+++ b/src/vmathjaxwebdocument.cpp
@@ -9,15 +9,39 @@ VMathJaxWebDocument::VMathJaxWebDocument(QObject *p_parent)
void VMathJaxWebDocument::previewMathJax(int p_identifier,
int p_id,
+ TimeStamp p_timeStamp,
const QString &p_text)
{
- emit requestPreviewMathJax(p_identifier, p_id, p_text);
+ emit requestPreviewMathJax(p_identifier, p_id, p_timeStamp, p_text);
}
void VMathJaxWebDocument::mathjaxResultReady(int p_identifier,
int p_id,
+ unsigned long long p_timeStamp,
const QString &p_format,
const QString &p_data)
{
- emit mathjaxPreviewResultReady(p_identifier, p_id, p_format, p_data);
+ emit mathjaxPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, p_data);
+}
+
+void VMathJaxWebDocument::diagramResultReady(int p_identifier,
+ int p_id,
+ unsigned long long p_timeStamp,
+ const QString &p_format,
+ const QString &p_data)
+{
+ emit diagramPreviewResultReady(p_identifier, p_id, p_timeStamp, p_format, p_data);
+}
+
+void VMathJaxWebDocument::previewDiagram(int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_lang,
+ const QString &p_text)
+{
+ emit requestPreviewDiagram(p_identifier,
+ p_id,
+ p_timeStamp,
+ p_lang,
+ p_text);
}
diff --git a/src/vmathjaxwebdocument.h b/src/vmathjaxwebdocument.h
index 687933ca..66995dd6 100644
--- a/src/vmathjaxwebdocument.h
+++ b/src/vmathjaxwebdocument.h
@@ -3,27 +3,58 @@
#include
+#include "vconstants.h"
+
class VMathJaxWebDocument : public QObject
{
Q_OBJECT
public:
explicit VMathJaxWebDocument(QObject *p_parent = nullptr);
- void previewMathJax(int p_identifier, int p_id, const QString &p_text);
+ void previewMathJax(int p_identifier, int p_id, TimeStamp p_timeStamp, const QString &p_text);
+
+ void previewDiagram(int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_lang,
+ const QString &p_text);
public slots:
// Will be called in the HTML side
void mathjaxResultReady(int p_identifier,
int p_id,
+ unsigned long long p_timeStamp,
+ const QString &p_format,
+ const QString &p_data);
+
+ void diagramResultReady(int p_identifier,
+ int p_id,
+ unsigned long long p_timeStamp,
const QString &p_format,
const QString &p_data);
signals:
- void requestPreviewMathJax(int p_identifier, int p_id, const QString &p_text);
+ void requestPreviewMathJax(int p_identifier,
+ int p_id,
+ unsigned long long p_timeStamp,
+ const QString &p_text);
+
+ void requestPreviewDiagram(int p_identifier,
+ int p_id,
+ unsigned long long p_timeStamp,
+ const QString &p_lang,
+ const QString &p_text);
void mathjaxPreviewResultReady(int p_identifier,
int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_format,
+ const QString &p_data);
+
+ void diagramPreviewResultReady(int p_identifier,
+ int p_id,
+ TimeStamp p_timeStamp,
const QString &p_format,
const QString &p_data);
};
diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp
index 07583f3b..330bf1fc 100644
--- a/src/vmdtab.cpp
+++ b/src/vmdtab.cpp
@@ -523,6 +523,8 @@ void VMdTab::setupMarkdownEditor()
m_livePreviewHelper, &VLivePreviewHelper::setInplacePreviewEnabled);
connect(m_livePreviewHelper, &VLivePreviewHelper::inplacePreviewCodeBlockUpdated,
m_editor->getPreviewManager(), &VPreviewManager::updateCodeBlocks);
+ connect(m_livePreviewHelper, &VLivePreviewHelper::checkBlocksForObsoletePreview,
+ m_editor->getPreviewManager(), &VPreviewManager::checkBlocksForObsoletePreview);
m_livePreviewHelper->setInplacePreviewEnabled(m_editor->getPreviewManager()->isPreviewEnabled());
}
diff --git a/src/vnote.cpp b/src/vnote.cpp
index 50ee0df3..0232a4d4 100644
--- a/src/vnote.cpp
+++ b/src/vnote.cpp
@@ -174,7 +174,17 @@ QString VNote::generateMathJaxPreviewTemplate()
const QString c_templatePath(":/resources/mathjax_preview_template.html");
QString templ = VUtils::readFileFromDisk(c_templatePath);
g_palette->fillStyle(templ);
+
+ QString cssStyle;
+ cssStyle += "div.flowchart-diagram { margin: 0px !important; "
+ " padding: 0px 5px 0px 5px !important; }\n"
+ "div.mermaid-diagram { margin: 0px !important; "
+ " padding: 0px 5px 0px 5px !important; }\n";
+
+ templ.replace(HtmlHolder::c_globalStyleHolder, cssStyle);
+
templ.replace(HtmlHolder::c_cssHolder, g_config->getCssStyleUrl());
+
return templ;
}
diff --git a/src/vnotebook.cpp b/src/vnotebook.cpp
index 95310130..c7b4a1be 100644
--- a/src/vnotebook.cpp
+++ b/src/vnotebook.cpp
@@ -182,6 +182,8 @@ VNotebook *VNotebook::createNotebook(const QString &p_name,
if (!nb->writeToConfig()) {
delete nb;
return NULL;
+ } else {
+ nb->m_valid = true;
}
return nb;
diff --git a/src/vplantumlhelper.cpp b/src/vplantumlhelper.cpp
index 9b2e1104..3904526a 100644
--- a/src/vplantumlhelper.cpp
+++ b/src/vplantumlhelper.cpp
@@ -9,6 +9,7 @@ extern VConfigManager *g_config;
#define TaskIdProperty "PlantUMLTaskId"
#define TaskFormatProperty "PlantUMLTaskFormat"
+#define TaskTimeStampProperty "PlantUMLTaskTimeStamp"
VPlantUMLHelper::VPlantUMLHelper(QObject *p_parent)
: QObject(p_parent)
@@ -16,10 +17,14 @@ VPlantUMLHelper::VPlantUMLHelper(QObject *p_parent)
prepareCommand(m_program, m_args);
}
-void VPlantUMLHelper::processAsync(int p_id, const QString &p_format, const QString &p_text)
+void VPlantUMLHelper::processAsync(int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_format,
+ const QString &p_text)
{
QProcess *process = new QProcess(this);
process->setProperty(TaskIdProperty, p_id);
+ process->setProperty(TaskTimeStampProperty, p_timeStamp);
process->setProperty(TaskFormatProperty, p_format);
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(handleProcessFinished(int, QProcess::ExitStatus)));
@@ -58,7 +63,8 @@ void VPlantUMLHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus
QProcess *process = static_cast(sender());
int id = process->property(TaskIdProperty).toInt();
QString format = process->property(TaskFormatProperty).toString();
- qDebug() << "process finished" << id << format << p_exitCode << p_exitStatus;
+ TimeStamp timeStamp = process->property(TaskTimeStampProperty).toULongLong();
+ qDebug() << "process finished" << id << timeStamp << format << p_exitCode << p_exitStatus;
bool failed = true;
if (p_exitStatus == QProcess::NormalExit) {
if (p_exitCode < 0) {
@@ -67,9 +73,9 @@ void VPlantUMLHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus
failed = false;
QByteArray outBa = process->readAllStandardOutput();
if (format == "svg") {
- emit resultReady(id, format, QString::fromLocal8Bit(outBa));
+ emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa));
} else {
- emit resultReady(id, format, QString::fromLocal8Bit(outBa.toBase64()));
+ emit resultReady(id, timeStamp, format, QString::fromLocal8Bit(outBa.toBase64()));
}
}
} else {
@@ -83,7 +89,7 @@ void VPlantUMLHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus
qWarning() << "PlantUML stderr:" << errStr;
}
- emit resultReady(id, format, "");
+ emit resultReady(id, timeStamp, format, "");
}
process->deleteLater();
diff --git a/src/vplantumlhelper.h b/src/vplantumlhelper.h
index fa733c5f..b4dd3219 100644
--- a/src/vplantumlhelper.h
+++ b/src/vplantumlhelper.h
@@ -6,18 +6,23 @@
#include
#include
+#include "vconstants.h"
+
class VPlantUMLHelper : public QObject
{
Q_OBJECT
public:
explicit VPlantUMLHelper(QObject *p_parent = nullptr);
- void processAsync(int p_id, const QString &p_format, const QString &p_text);
+ void processAsync(int p_id,
+ TimeStamp p_timeStamp,
+ const QString &p_format,
+ const QString &p_text);
void prepareCommand(QString &p_cmd, QStringList &p_args) const;
signals:
- void resultReady(int p_id, const QString &p_format, const QString &p_result);
+ void resultReady(int p_id, TimeStamp p_timeStamp, const QString &p_format, const QString &p_result);
private slots:
void handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_exitStatus);
diff --git a/src/vpreviewmanager.cpp b/src/vpreviewmanager.cpp
index 3c74c617..a8b300da 100644
--- a/src/vpreviewmanager.cpp
+++ b/src/vpreviewmanager.cpp
@@ -473,3 +473,40 @@ void VPreviewManager::updateCodeBlocks(const QVector &p_blocks)
+{
+ if (p_blocks.isEmpty()) {
+ return;
+ }
+
+ QSet affectedBlocks;
+ for (auto i : p_blocks) {
+ QTextBlock block = m_document->findBlockByNumber(i);
+ if (!block.isValid()) {
+ continue;
+ }
+
+ VTextBlockData *blockData = dynamic_cast(block.userData());
+ if (!blockData) {
+ continue;
+ }
+
+ if (blockData->getPreviews().isEmpty()) {
+ continue;
+ }
+
+ for (int i = 0; i < (int)PreviewSource::MaxNumberOfSources; ++i) {
+ if (blockData->getPreviews().isEmpty()) {
+ break;
+ }
+
+ PreviewSource ps = static_cast(i);
+ if (blockData->clearObsoletePreview(timeStamp(ps), ps)) {
+ affectedBlocks.insert(i);
+ }
+ }
+ }
+
+ m_editor->relayout(affectedBlocks);
+}
diff --git a/src/vpreviewmanager.h b/src/vpreviewmanager.h
index 3e7d4808..d7a5e959 100644
--- a/src/vpreviewmanager.h
+++ b/src/vpreviewmanager.h
@@ -67,6 +67,10 @@ public:
bool isPreviewEnabled() const;
+ // Check @p_blocks to see if there is any obsolete preview and clear them
+ // if there is any.
+ void checkBlocksForObsoletePreview(const QList &p_blocks);
+
// Calculate the block margin (prefix spaces) in pixels.
static int calculateBlockMargin(const QTextBlock &p_block, int p_tabStopWidth);
diff --git a/src/vtextblockdata.cpp b/src/vtextblockdata.cpp
index 1dcb5344..430834b2 100644
--- a/src/vtextblockdata.cpp
+++ b/src/vtextblockdata.cpp
@@ -89,9 +89,8 @@ bool VTextBlockData::clearObsoletePreview(long long p_timeStamp, PreviewSource p
bool deleted = false;
for (auto it = m_previews.begin(); it != m_previews.end();) {
VPreviewInfo *ele = *it;
-
if (ele->m_source == p_source
- && ele->m_timeStamp < p_timeStamp) {
+ && ele->m_timeStamp != p_timeStamp) {
// Remove it.
qDebug() << "clear obsolete preview" << ele->m_imageInfo.toString();
delete ele;