mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support Mermaid and Flowchart.js preview
Mermaid preview is disabled for some issues.
This commit is contained in:
parent
8239abec2a
commit
10e2bba7f6
@ -3,7 +3,7 @@
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
/* BACKGROUND_PLACE_HOLDER */
|
||||
/* STYLE_GLOBAL_PLACE_HOLDER */
|
||||
</style>
|
||||
|
||||
<style type="text/css">
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
/* BACKGROUND_PLACE_HOLDER */
|
||||
/* STYLE_GLOBAL_PLACE_HOLDER */
|
||||
</style>
|
||||
|
||||
<style type="text/css">
|
||||
|
@ -1328,7 +1328,7 @@ var specialCodeBlock = function(lang) {
|
||||
|| (VEnableGraphviz && lang == 'dot');
|
||||
};
|
||||
|
||||
var handlePlantUMLResult = function(id, format, result) {
|
||||
var handlePlantUMLResult = function(id, timeStamp, format, result) {
|
||||
var code = document.getElementsByClassName(plantUMLCodeClass + id)[0];
|
||||
if (code && result.length > 0) {
|
||||
var obj = null;
|
||||
@ -1348,7 +1348,7 @@ var handlePlantUMLResult = function(id, format, result) {
|
||||
finishOneAsyncJob();
|
||||
};
|
||||
|
||||
var handleGraphvizResult = function(id, format, result) {
|
||||
var handleGraphvizResult = function(id, timeStamp, format, result) {
|
||||
var code = document.getElementsByClassName(graphvizCodeClass + id)[0];
|
||||
if (code && result.length > 0) {
|
||||
var obj = null;
|
||||
|
@ -4,22 +4,25 @@ var contentDiv = document.getElementById('content-div');
|
||||
|
||||
var content;
|
||||
|
||||
var VMermaidDivClass = 'mermaid-diagram';
|
||||
var VFlowchartDivClass = 'flowchart-diagram';
|
||||
|
||||
new QWebChannel(qt.webChannelTransport,
|
||||
function(channel) {
|
||||
content = channel.objects.content;
|
||||
|
||||
content.requestPreviewMathJax.connect(previewMathJax);
|
||||
content.requestPreviewDiagram.connect(previewDiagram);
|
||||
|
||||
channelInitialized = true;
|
||||
});
|
||||
|
||||
var previewMathJax = function(identifier, id, text) {
|
||||
var previewMathJax = function(identifier, id, timeStamp, text) {
|
||||
if (text.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var p = document.createElement('p');
|
||||
p.id = identifier + '_' + id;
|
||||
p.textContent = text;
|
||||
contentDiv.appendChild(p);
|
||||
|
||||
@ -27,7 +30,7 @@ var previewMathJax = function(identifier, id, text) {
|
||||
MathJax.Hub.Queue(["Typeset",
|
||||
MathJax.Hub,
|
||||
p,
|
||||
postProcessMathJax.bind(undefined, identifier, id, p)]);
|
||||
postProcessMathJax.bind(undefined, identifier, id, timeStamp, p)]);
|
||||
} catch (err) {
|
||||
console.log("err: " + err);
|
||||
contentDiv.removeChild(p);
|
||||
@ -35,14 +38,119 @@ var previewMathJax = function(identifier, id, text) {
|
||||
}
|
||||
};
|
||||
|
||||
var postProcessMathJax = function(identifier, id, container) {
|
||||
var postProcessMathJax = function(identifier, id, timeStamp, container) {
|
||||
domtoimage.toPng(container, { height: container.clientHeight * 1.5 }).then(function (dataUrl) {
|
||||
var png = dataUrl.substring(dataUrl.indexOf(',') + 1);
|
||||
content.mathjaxResultReady(identifier, id, 'png', png);
|
||||
content.mathjaxResultReady(identifier, id, timeStamp, 'png', png);
|
||||
|
||||
contentDiv.removeChild(container);
|
||||
delete container;
|
||||
}).catch(function (err) {
|
||||
console.log("err: " + err);
|
||||
contentDiv.removeChild(container);
|
||||
delete container;
|
||||
});
|
||||
};
|
||||
|
||||
var mermaidParserErr = false;
|
||||
var mermaidIdx = 0;
|
||||
|
||||
var flowchartIdx = 0;
|
||||
|
||||
if (typeof mermaidAPI != "undefined") {
|
||||
mermaidAPI.parseError = function(err, hash) {
|
||||
mermaidParserErr = true;
|
||||
|
||||
// Clean the container element, or mermaidAPI won't render the graph with
|
||||
// the same id.
|
||||
var errGraph = document.getElementById('mermaid-diagram-' + mermaidIdx);
|
||||
if (errGraph) {
|
||||
var parentNode = errGraph.parentElement;
|
||||
parentNode.outerHTML = '';
|
||||
delete parentNode;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var previewDiagram = function(identifier, id, timeStamp, lang, text) {
|
||||
if (text.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var div = null;
|
||||
if (lang == 'flow' || lang == 'flowchart') {
|
||||
flowchartIdx++;
|
||||
try {
|
||||
var graph = flowchart.parse(text);
|
||||
} catch (err) {
|
||||
console.log("err: " + err);
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', '');
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof graph == "undefined") {
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', '');
|
||||
return;
|
||||
}
|
||||
|
||||
div = document.createElement('div');
|
||||
div.id = 'flowchart-diagram-' + flowchartIdx;
|
||||
div.classList.add(VFlowchartDivClass);
|
||||
|
||||
contentDiv.appendChild(div);
|
||||
|
||||
// Draw on it after adding it to page.
|
||||
try {
|
||||
graph.drawSVG(div.id);
|
||||
} catch (err) {
|
||||
console.log("err: " + err);
|
||||
contentDiv.removeChild(div);
|
||||
delete div;
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', '');
|
||||
return;
|
||||
}
|
||||
} else if (lang == 'mermaid') {
|
||||
mermaidParserErr = false;
|
||||
mermaidIdx++;
|
||||
try {
|
||||
// Do not increment mermaidIdx here.
|
||||
var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx,
|
||||
text,
|
||||
function(){});
|
||||
} catch (err) {
|
||||
console.log("err: " + err);
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', '');
|
||||
return;
|
||||
}
|
||||
|
||||
if (mermaidParserErr || typeof graph == "undefined") {
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', '');
|
||||
return;
|
||||
}
|
||||
|
||||
div = document.createElement('div');
|
||||
div.classList.add(VMermaidDivClass);
|
||||
div.innerHTML = graph;
|
||||
contentDiv.appendChild(div);
|
||||
}
|
||||
|
||||
if (!div) {
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', '');
|
||||
return;
|
||||
}
|
||||
|
||||
// For Flowchart.js, we need to add addtitional height. Since Mermaid is not
|
||||
// supported now, we just add it simply here.
|
||||
domtoimage.toPng(div, { height: div.clientHeight + 30 }).then(function (dataUrl) {
|
||||
var png = dataUrl.substring(dataUrl.indexOf(',') + 1);
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', png);
|
||||
|
||||
contentDiv.removeChild(div);
|
||||
delete div;
|
||||
}).catch(function (err) {
|
||||
console.log("err: " + err);
|
||||
contentDiv.removeChild(div);
|
||||
content.diagramResultReady(identifier, id, timeStamp, 'png', '');
|
||||
delete div;
|
||||
});
|
||||
};
|
||||
|
@ -2,6 +2,10 @@
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
/* STYLE_GLOBAL_PLACE_HOLDER */
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="CSS_PLACE_HOLDER">
|
||||
<script src="qrc:/resources/qwebchannel.js"></script>
|
||||
<!-- EXTRA_PLACE_HOLDER -->
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -38,7 +38,7 @@ markdown_converter=2
|
||||
enable_mermaid=false
|
||||
|
||||
; Enable MathJax
|
||||
enable_mathjax=true
|
||||
enable_mathjax=false
|
||||
|
||||
; Enable Flowchart.js
|
||||
enable_flowchart=false
|
||||
|
@ -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 += "<link rel=\"stylesheet\" type=\"text/css\" href=\"" + g_config->getMermaidCssStyleUrl() + "\"/>\n" +
|
||||
"<script src=\"qrc" + VNote::c_mermaidApiJsFile + "\"></script>\n";
|
||||
*/
|
||||
|
||||
// Flowchart.
|
||||
extraFile += "<script src=\"qrc" + VNote::c_raphaelJsFile + "\"></script>\n" +
|
||||
"<script src=\"qrc" + VNote::c_flowchartJsFile + "\"></script>\n";
|
||||
|
||||
// MathJax.
|
||||
extraFile += "<script type=\"text/x-mathjax-config\">"
|
||||
"MathJax.Hub.Config({\n"
|
||||
" tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']],\n"
|
||||
"processEscapes: true,\n"
|
||||
"processClass: \"tex2jax_process|language-mathjax|lang-mathjax\"},\n"
|
||||
" \"HTML-CSS\": {\n"
|
||||
" scale: " + mathjaxScale + "\n"
|
||||
" },\n"
|
||||
" showProcessingMessages: false,\n"
|
||||
" messageStyle: \"none\"});\n"
|
||||
"</script>\n";
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
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 = "<!-- EXTRA_PLACE_HOLDER -->";
|
||||
static const QString c_bodyHolder = "<!-- BODY_PLACE_HOLDER -->";
|
||||
static const QString c_headHolder = "<!-- HEAD_PLACE_HOLDER -->";
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<QProcess *>(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();
|
||||
|
@ -6,18 +6,20 @@
|
||||
#include <QStringList>
|
||||
#include <QProcess>
|
||||
|
||||
#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);
|
||||
|
@ -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<VCodeBlock> &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,
|
||||
m_mathJaxHelper->previewDiagram(m_mathJaxID,
|
||||
p_idx,
|
||||
m_timeStamp,
|
||||
vcb.m_lang,
|
||||
removeFence(vcb.m_text),
|
||||
false);
|
||||
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<int> blocks;
|
||||
QVector<QSharedPointer<VImageToPreview> > 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;
|
||||
}
|
||||
|
||||
|
@ -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<VCodeBlock> &p_codeBlocks);
|
||||
|
||||
void webAsyncResultReady(int p_id, const QString &p_lang, const QString &p_result);
|
||||
|
||||
signals:
|
||||
void inplacePreviewCodeBlockUpdated(const QVector<QSharedPointer<VImageToPreview> > &p_images);
|
||||
|
||||
void checkBlocksForObsoletePreview(const QList<int> &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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -3,27 +3,58 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#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);
|
||||
};
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<QProcess *>(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();
|
||||
|
@ -6,18 +6,23 @@
|
||||
#include <QStringList>
|
||||
#include <QProcess>
|
||||
|
||||
#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);
|
||||
|
@ -473,3 +473,40 @@ void VPreviewManager::updateCodeBlocks(const QVector<QSharedPointer<VImageToPrev
|
||||
|
||||
clearObsoleteImages(ts, PreviewSource::CodeBlock);
|
||||
}
|
||||
|
||||
void VPreviewManager::checkBlocksForObsoletePreview(const QList<int> &p_blocks)
|
||||
{
|
||||
if (p_blocks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QSet<int> affectedBlocks;
|
||||
for (auto i : p_blocks) {
|
||||
QTextBlock block = m_document->findBlockByNumber(i);
|
||||
if (!block.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VTextBlockData *blockData = dynamic_cast<VTextBlockData *>(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<PreviewSource>(i);
|
||||
if (blockData->clearObsoletePreview(timeStamp(ps), ps)) {
|
||||
affectedBlocks.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_editor->relayout(affectedBlocks);
|
||||
}
|
||||
|
@ -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<int> &p_blocks);
|
||||
|
||||
// Calculate the block margin (prefix spaces) in pixels.
|
||||
static int calculateBlockMargin(const QTextBlock &p_block, int p_tabStopWidth);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user