mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
support Graphviz
This commit is contained in:
parent
11e111ed7b
commit
2206102945
@ -912,10 +912,13 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent)
|
|||||||
m_plantUMLJarEdit = new VLineEdit();
|
m_plantUMLJarEdit = new VLineEdit();
|
||||||
m_plantUMLJarEdit->setToolTip(tr("Location to the PlantUML JAR executable for local PlantUML"));
|
m_plantUMLJarEdit->setToolTip(tr("Location to the PlantUML JAR executable for local PlantUML"));
|
||||||
|
|
||||||
m_plantUMLDotEdit = new VLineEdit();
|
// Graphviz.
|
||||||
m_plantUMLDotEdit->setPlaceholderText(tr("Empty to detect automatically"));
|
m_graphvizCB = new QCheckBox(tr("Graphviz"));
|
||||||
m_plantUMLDotEdit->setToolTip(tr("Location to the GraphViz executable for local PlantUML "
|
m_graphvizCB->setToolTip(tr("Enable Graphviz for drawing graph"));
|
||||||
"(empty to let PlantUML detect it automatically)"));
|
|
||||||
|
m_graphvizDotEdit = new VLineEdit();
|
||||||
|
m_graphvizDotEdit->setPlaceholderText(tr("Empty to detect automatically"));
|
||||||
|
m_graphvizDotEdit->setToolTip(tr("Location to the GraphViz dot executable"));
|
||||||
|
|
||||||
QFormLayout *mainLayout = new QFormLayout();
|
QFormLayout *mainLayout = new QFormLayout();
|
||||||
mainLayout->addRow(tr("Note open mode:"), m_openModeCombo);
|
mainLayout->addRow(tr("Note open mode:"), m_openModeCombo);
|
||||||
@ -924,7 +927,8 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent)
|
|||||||
mainLayout->addRow(tr("PlantUML:"), m_plantUMLModeCombo);
|
mainLayout->addRow(tr("PlantUML:"), m_plantUMLModeCombo);
|
||||||
mainLayout->addRow(tr("PlantUML server:"), m_plantUMLServerEdit);
|
mainLayout->addRow(tr("PlantUML server:"), m_plantUMLServerEdit);
|
||||||
mainLayout->addRow(tr("PlantUML JAR:"), m_plantUMLJarEdit);
|
mainLayout->addRow(tr("PlantUML JAR:"), m_plantUMLJarEdit);
|
||||||
mainLayout->addRow(tr("Graphviz executable:"), m_plantUMLDotEdit);
|
mainLayout->addRow(m_graphvizCB);
|
||||||
|
mainLayout->addRow(tr("Graphviz executable:"), m_graphvizDotEdit);
|
||||||
|
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
}
|
}
|
||||||
@ -947,6 +951,10 @@ bool VMarkdownTab::loadConfiguration()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!loadGraphviz()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,6 +976,10 @@ bool VMarkdownTab::saveConfiguration()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!saveGraphviz()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,7 +1056,6 @@ bool VMarkdownTab::loadPlantUML()
|
|||||||
m_plantUMLModeCombo->setCurrentIndex(m_plantUMLModeCombo->findData(g_config->getPlantUMLMode()));
|
m_plantUMLModeCombo->setCurrentIndex(m_plantUMLModeCombo->findData(g_config->getPlantUMLMode()));
|
||||||
m_plantUMLServerEdit->setText(g_config->getPlantUMLServer());
|
m_plantUMLServerEdit->setText(g_config->getPlantUMLServer());
|
||||||
m_plantUMLJarEdit->setText(g_config->getPlantUMLJar());
|
m_plantUMLJarEdit->setText(g_config->getPlantUMLJar());
|
||||||
m_plantUMLDotEdit->setText(g_config->getPlantUMLDot());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1053,6 +1064,19 @@ bool VMarkdownTab::savePlantUML()
|
|||||||
g_config->setPlantUMLMode(m_plantUMLModeCombo->currentData().toInt());
|
g_config->setPlantUMLMode(m_plantUMLModeCombo->currentData().toInt());
|
||||||
g_config->setPlantUMLServer(m_plantUMLServerEdit->text());
|
g_config->setPlantUMLServer(m_plantUMLServerEdit->text());
|
||||||
g_config->setPlantUMLJar(m_plantUMLJarEdit->text());
|
g_config->setPlantUMLJar(m_plantUMLJarEdit->text());
|
||||||
g_config->setPlantUMLDot(m_plantUMLDotEdit->text());
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VMarkdownTab::loadGraphviz()
|
||||||
|
{
|
||||||
|
m_graphvizCB->setChecked(g_config->getEnableGraphviz());
|
||||||
|
m_graphvizDotEdit->setText(g_config->getGraphvizDot());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VMarkdownTab::saveGraphviz()
|
||||||
|
{
|
||||||
|
g_config->setEnableGraphviz(m_graphvizCB->isChecked());
|
||||||
|
g_config->setGraphvizDot(m_graphvizDotEdit->text());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,9 @@ private:
|
|||||||
bool loadPlantUML();
|
bool loadPlantUML();
|
||||||
bool savePlantUML();
|
bool savePlantUML();
|
||||||
|
|
||||||
|
bool loadGraphviz();
|
||||||
|
bool saveGraphviz();
|
||||||
|
|
||||||
// Default note open mode for markdown.
|
// Default note open mode for markdown.
|
||||||
QComboBox *m_openModeCombo;
|
QComboBox *m_openModeCombo;
|
||||||
|
|
||||||
@ -174,7 +177,10 @@ private:
|
|||||||
QComboBox *m_plantUMLModeCombo;
|
QComboBox *m_plantUMLModeCombo;
|
||||||
VLineEdit *m_plantUMLServerEdit;
|
VLineEdit *m_plantUMLServerEdit;
|
||||||
VLineEdit *m_plantUMLJarEdit;
|
VLineEdit *m_plantUMLJarEdit;
|
||||||
VLineEdit *m_plantUMLDotEdit;
|
|
||||||
|
// Graphviz.
|
||||||
|
QCheckBox *m_graphvizCB;
|
||||||
|
VLineEdit *m_graphvizDotEdit;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VSettingsDialog : public QDialog
|
class VSettingsDialog : public QDialog
|
||||||
|
@ -25,6 +25,7 @@ var updateHtml = function(html) {
|
|||||||
var codes = document.getElementsByTagName('code');
|
var codes = document.getElementsByTagName('code');
|
||||||
mermaidIdx = 0;
|
mermaidIdx = 0;
|
||||||
plantUMLIdx = 0;
|
plantUMLIdx = 0;
|
||||||
|
graphvizIdx = 0;
|
||||||
for (var i = 0; i < codes.length; ++i) {
|
for (var i = 0; i < codes.length; ++i) {
|
||||||
var code = codes[i];
|
var code = codes[i];
|
||||||
if (code.parentElement.tagName.toLowerCase() == 'pre') {
|
if (code.parentElement.tagName.toLowerCase() == 'pre') {
|
||||||
@ -59,9 +60,15 @@ var updateHtml = function(html) {
|
|||||||
renderPlantUMLOneLocal(code);
|
renderPlantUMLOneLocal(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
} else if (VEnableGraphviz
|
||||||
|
&& code.classList.contains('language-dot')) {
|
||||||
|
// Graphviz code block.
|
||||||
|
renderGraphvizOneLocal(code);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (listContainsRegex(code.classList, /language-.*/)) {
|
if (listContainsRegex(code.classList, /language-.*/)) {
|
||||||
hljs.highlightBlock(code);
|
hljs.highlightBlock(code);
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@ var updateText = function(text) {
|
|||||||
renderMermaid('lang-mermaid');
|
renderMermaid('lang-mermaid');
|
||||||
renderFlowchart(['lang-flowchart', 'lang-flow']);
|
renderFlowchart(['lang-flowchart', 'lang-flow']);
|
||||||
renderPlantUML('lang-puml');
|
renderPlantUML('lang-puml');
|
||||||
|
renderGraphviz('lang-dot');
|
||||||
addClassToCodeBlock();
|
addClassToCodeBlock();
|
||||||
renderCodeBlockLineNumber();
|
renderCodeBlockLineNumber();
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
var channelInitialized = false;
|
||||||
|
|
||||||
var content;
|
var content;
|
||||||
|
|
||||||
// Current header index in all headers.
|
// Current header index in all headers.
|
||||||
@ -45,6 +47,18 @@ if (typeof VPlantUMLServer == 'undefined') {
|
|||||||
VPlantUMLServer = 'http://www.plantuml.com/plantuml';
|
VPlantUMLServer = 'http://www.plantuml.com/plantuml';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof VPlantUMLFormat == 'undefined') {
|
||||||
|
VPlantUMLFormat = 'svg';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof VEnableGraphviz == 'undefined') {
|
||||||
|
VEnableGraphviz = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof VGraphvizFormat == 'undefined') {
|
||||||
|
VGraphvizFormat = 'svg';
|
||||||
|
}
|
||||||
|
|
||||||
// Add a caption (using alt text) under the image.
|
// Add a caption (using alt text) under the image.
|
||||||
var VImageCenterClass = 'img-center';
|
var VImageCenterClass = 'img-center';
|
||||||
var VImageCaptionClass = 'img-caption';
|
var VImageCaptionClass = 'img-caption';
|
||||||
@ -123,14 +137,7 @@ var htmlContent = function() {
|
|||||||
new QWebChannel(qt.webChannelTransport,
|
new QWebChannel(qt.webChannelTransport,
|
||||||
function(channel) {
|
function(channel) {
|
||||||
content = channel.objects.content;
|
content = channel.objects.content;
|
||||||
if (typeof updateHtml == "function") {
|
|
||||||
updateHtml(content.html);
|
|
||||||
content.htmlChanged.connect(updateHtml);
|
|
||||||
}
|
|
||||||
if (typeof updateText == "function") {
|
|
||||||
content.textChanged.connect(updateText);
|
|
||||||
content.updateText();
|
|
||||||
}
|
|
||||||
content.requestScrollToAnchor.connect(scrollToAnchor);
|
content.requestScrollToAnchor.connect(scrollToAnchor);
|
||||||
|
|
||||||
if (typeof highlightText == "function") {
|
if (typeof highlightText == "function") {
|
||||||
@ -148,6 +155,19 @@ new QWebChannel(qt.webChannelTransport,
|
|||||||
}
|
}
|
||||||
|
|
||||||
content.plantUMLResultReady.connect(handlePlantUMLResult);
|
content.plantUMLResultReady.connect(handlePlantUMLResult);
|
||||||
|
content.graphvizResultReady.connect(handleGraphvizResult);
|
||||||
|
|
||||||
|
if (typeof updateHtml == "function") {
|
||||||
|
updateHtml(content.html);
|
||||||
|
content.htmlChanged.connect(updateHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof updateText == "function") {
|
||||||
|
content.textChanged.connect(updateText);
|
||||||
|
content.updateText();
|
||||||
|
}
|
||||||
|
|
||||||
|
channelInitialized = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var VHighlightedAnchorClass = 'highlighted-anchor';
|
var VHighlightedAnchorClass = 'highlighted-anchor';
|
||||||
@ -686,6 +706,33 @@ var renderPlantUMLOneLocal = function(code) {
|
|||||||
plantUMLIdx++;
|
plantUMLIdx++;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var graphvizIdx = 0;
|
||||||
|
var graphvizCodeClass = 'graphviz_code_';
|
||||||
|
|
||||||
|
// @className, the class name of the Graghviz code block, such as 'lang-dot'.
|
||||||
|
var renderGraphviz = function(className) {
|
||||||
|
if (!VEnableGraphviz) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphvizIdx = 0;
|
||||||
|
|
||||||
|
var codes = document.getElementsByTagName('code');
|
||||||
|
for (var i = 0; i < codes.length; ++i) {
|
||||||
|
var code = codes[i];
|
||||||
|
if (code.classList.contains(className)) {
|
||||||
|
renderGraphvizOneLocal(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var renderGraphvizOneLocal = function(code) {
|
||||||
|
++asyncJobsCount;
|
||||||
|
code.classList.add(graphvizCodeClass + graphvizIdx);
|
||||||
|
content.processGraphviz(graphvizIdx, VGraphvizFormat, code.textContent);
|
||||||
|
graphvizIdx++;
|
||||||
|
};
|
||||||
|
|
||||||
var isImageBlock = function(img) {
|
var isImageBlock = function(img) {
|
||||||
var pn = img.parentNode;
|
var pn = img.parentNode;
|
||||||
return (pn.children.length == 1) && (pn.textContent == '');
|
return (pn.children.length == 1) && (pn.textContent == '');
|
||||||
@ -1260,7 +1307,8 @@ var specialCodeBlock = function(lang) {
|
|||||||
return (VEnableMathjax && lang == 'mathjax')
|
return (VEnableMathjax && lang == 'mathjax')
|
||||||
|| (VEnableMermaid && lang == 'mermaid')
|
|| (VEnableMermaid && lang == 'mermaid')
|
||||||
|| (VEnableFlowchart && (lang == 'flowchart' || lang == 'flow'))
|
|| (VEnableFlowchart && (lang == 'flowchart' || lang == 'flow'))
|
||||||
|| (VPlantUMLMode != 0 && lang == 'puml');
|
|| (VPlantUMLMode != 0 && lang == 'puml')
|
||||||
|
|| (VEnableGraphviz && lang == 'dot');
|
||||||
};
|
};
|
||||||
|
|
||||||
var handlePlantUMLResult = function(id, format, result) {
|
var handlePlantUMLResult = function(id, format, result) {
|
||||||
@ -1282,3 +1330,22 @@ var handlePlantUMLResult = function(id, format, result) {
|
|||||||
|
|
||||||
finishOneAsyncJob();
|
finishOneAsyncJob();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var handleGraphvizResult = function(id, format, result) {
|
||||||
|
var code = document.getElementsByClassName(graphvizCodeClass + id)[0];
|
||||||
|
if (code && result.length > 0) {
|
||||||
|
var obj = null;
|
||||||
|
if (format == 'svg') {
|
||||||
|
obj = document.createElement('p');
|
||||||
|
obj.innerHTML = result;
|
||||||
|
} else {
|
||||||
|
obj = document.createElement('img');
|
||||||
|
obj.src = "data:image/" + format + ";base64, " + result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var preNode = code.parentNode;
|
||||||
|
preNode.parentNode.replaceChild(obj, preNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
finishOneAsyncJob();
|
||||||
|
};
|
||||||
|
@ -60,6 +60,7 @@ var updateText = function(text) {
|
|||||||
renderMermaid('lang-mermaid');
|
renderMermaid('lang-mermaid');
|
||||||
renderFlowchart(['lang-flowchart', 'lang-flow']);
|
renderFlowchart(['lang-flowchart', 'lang-flow']);
|
||||||
renderPlantUML('lang-puml');
|
renderPlantUML('lang-puml');
|
||||||
|
renderGraphviz('lang-dot');
|
||||||
addClassToCodeBlock();
|
addClassToCodeBlock();
|
||||||
renderCodeBlockLineNumber();
|
renderCodeBlockLineNumber();
|
||||||
|
|
||||||
|
@ -49,7 +49,12 @@ var mdHasTocSection = function(markdown) {
|
|||||||
return n != -1;
|
return n != -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
var highlightCodeBlocks = function(doc, enableMermaid, enableFlowchart, enableMathJax, enablePlantUML) {
|
var highlightCodeBlocks = function(doc,
|
||||||
|
enableMermaid,
|
||||||
|
enableFlowchart,
|
||||||
|
enableMathJax,
|
||||||
|
enablePlantUML,
|
||||||
|
enableGraphviz) {
|
||||||
var codes = doc.getElementsByTagName('code');
|
var codes = doc.getElementsByTagName('code');
|
||||||
for (var i = 0; i < codes.length; ++i) {
|
for (var i = 0; i < codes.length; ++i) {
|
||||||
var code = codes[i];
|
var code = codes[i];
|
||||||
@ -68,6 +73,9 @@ var highlightCodeBlocks = function(doc, enableMermaid, enableFlowchart, enableMa
|
|||||||
} else if (enablePlantUML && code.classList.contains('language-puml')) {
|
} else if (enablePlantUML && code.classList.contains('language-puml')) {
|
||||||
// PlantUML code block.
|
// PlantUML code block.
|
||||||
continue;
|
continue;
|
||||||
|
} else if (enableGraphviz && code.classList.contains('language-dot')) {
|
||||||
|
// Graphviz code block.
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listContainsRegex(code.classList, /language-.*/)) {
|
if (listContainsRegex(code.classList, /language-.*/)) {
|
||||||
@ -89,10 +97,16 @@ var updateText = function(text) {
|
|||||||
placeholder.innerHTML = html;
|
placeholder.innerHTML = html;
|
||||||
handleToc(needToc);
|
handleToc(needToc);
|
||||||
insertImageCaption();
|
insertImageCaption();
|
||||||
highlightCodeBlocks(document, VEnableMermaid, VEnableFlowchart, VEnableMathjax, VPlantUMLMode != 0);
|
highlightCodeBlocks(document,
|
||||||
|
VEnableMermaid,
|
||||||
|
VEnableFlowchart,
|
||||||
|
VEnableMathjax,
|
||||||
|
VPlantUMLMode != 0,
|
||||||
|
VEnableGraphviz);
|
||||||
renderMermaid('language-mermaid');
|
renderMermaid('language-mermaid');
|
||||||
renderFlowchart(['language-flowchart', 'language-flow']);
|
renderFlowchart(['language-flowchart', 'language-flow']);
|
||||||
renderPlantUML('language-puml');
|
renderPlantUML('language-puml');
|
||||||
|
renderGraphviz('language-dot');
|
||||||
addClassToCodeBlock();
|
addClassToCodeBlock();
|
||||||
renderCodeBlockLineNumber();
|
renderCodeBlockLineNumber();
|
||||||
|
|
||||||
|
@ -49,6 +49,9 @@ enable_flowchart=false
|
|||||||
; 2 - local PlantUML
|
; 2 - local PlantUML
|
||||||
plantuml_mode=0
|
plantuml_mode=0
|
||||||
|
|
||||||
|
; Enable Graphviz
|
||||||
|
enable_graphviz=false
|
||||||
|
|
||||||
; -1 - calculate the factor
|
; -1 - calculate the factor
|
||||||
web_zoom_factor=-1
|
web_zoom_factor=-1
|
||||||
|
|
||||||
@ -277,8 +280,8 @@ plantuml_server=http://www.plantuml.com/plantuml
|
|||||||
; PlantUML JAR location
|
; PlantUML JAR location
|
||||||
plantuml_jar=
|
plantuml_jar=
|
||||||
|
|
||||||
; PlantUML Graphviz Dot location
|
; Graphviz Dot location
|
||||||
plantuml_dot=
|
graphviz_dot=
|
||||||
|
|
||||||
[shortcuts]
|
[shortcuts]
|
||||||
; Define shortcuts here, with each item in the form "operation=keysequence".
|
; Define shortcuts here, with each item in the form "operation=keysequence".
|
||||||
|
@ -126,7 +126,8 @@ SOURCES += main.cpp\
|
|||||||
vhelpue.cpp \
|
vhelpue.cpp \
|
||||||
vlistfolderue.cpp \
|
vlistfolderue.cpp \
|
||||||
dialog/vfixnotebookdialog.cpp \
|
dialog/vfixnotebookdialog.cpp \
|
||||||
vplantumlhelper.cpp
|
vplantumlhelper.cpp \
|
||||||
|
vgraphvizhelper.cpp
|
||||||
|
|
||||||
HEADERS += vmainwindow.h \
|
HEADERS += vmainwindow.h \
|
||||||
vdirectorytree.h \
|
vdirectorytree.h \
|
||||||
@ -243,7 +244,8 @@ HEADERS += vmainwindow.h \
|
|||||||
vhelpue.h \
|
vhelpue.h \
|
||||||
vlistfolderue.h \
|
vlistfolderue.h \
|
||||||
dialog/vfixnotebookdialog.h \
|
dialog/vfixnotebookdialog.h \
|
||||||
vplantumlhelper.h
|
vplantumlhelper.h \
|
||||||
|
vgraphvizhelper.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
vnote.qrc \
|
vnote.qrc \
|
||||||
|
@ -736,6 +736,13 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
|
|||||||
extraFile += QString("<script>var VPlantUMLFormat = '%1';</script>\n").arg(format);
|
extraFile += QString("<script>var VPlantUMLFormat = '%1';</script>\n").arg(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_config->getEnableGraphviz()) {
|
||||||
|
extraFile += "<script>var VEnableGraphviz = true;</script>\n";
|
||||||
|
|
||||||
|
QString format = p_isPDF ? "png" : "svg";
|
||||||
|
extraFile += QString("<script>var VGraphvizFormat = '%1';</script>\n").arg(format);
|
||||||
|
}
|
||||||
|
|
||||||
if (g_config->getEnableImageCaption()) {
|
if (g_config->getEnableImageCaption()) {
|
||||||
extraFile += "<script>var VEnableImageCaption = true;</script>\n";
|
extraFile += "<script>var VEnableImageCaption = true;</script>\n";
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,9 @@ void VConfigManager::initialize()
|
|||||||
m_plantUMLMode = getConfigFromSettings("global", "plantuml_mode").toInt();
|
m_plantUMLMode = getConfigFromSettings("global", "plantuml_mode").toInt();
|
||||||
m_plantUMLServer = getConfigFromSettings("web", "plantuml_server").toString();
|
m_plantUMLServer = getConfigFromSettings("web", "plantuml_server").toString();
|
||||||
m_plantUMLJar = getConfigFromSettings("web", "plantuml_jar").toString();
|
m_plantUMLJar = getConfigFromSettings("web", "plantuml_jar").toString();
|
||||||
m_plantUMLDot = getConfigFromSettings("web", "plantuml_dot").toString();
|
|
||||||
|
m_enableGraphviz = getConfigFromSettings("global", "enable_graphviz").toBool();
|
||||||
|
m_graphvizDot = getConfigFromSettings("web", "graphviz_dot").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VConfigManager::initSettings()
|
void VConfigManager::initSettings()
|
||||||
|
@ -210,6 +210,9 @@ public:
|
|||||||
bool getEnableMathjax() const;
|
bool getEnableMathjax() const;
|
||||||
void setEnableMathjax(bool p_enabled);
|
void setEnableMathjax(bool p_enabled);
|
||||||
|
|
||||||
|
bool getEnableGraphviz() const;
|
||||||
|
void setEnableGraphviz(bool p_enabled);
|
||||||
|
|
||||||
int getPlantUMLMode() const;
|
int getPlantUMLMode() const;
|
||||||
void setPlantUMLMode(int p_mode);
|
void setPlantUMLMode(int p_mode);
|
||||||
|
|
||||||
@ -469,8 +472,8 @@ public:
|
|||||||
const QString &getPlantUMLJar() const;
|
const QString &getPlantUMLJar() const;
|
||||||
void setPlantUMLJar(const QString &p_jarPath);
|
void setPlantUMLJar(const QString &p_jarPath);
|
||||||
|
|
||||||
const QString &getPlantUMLDot() const;
|
const QString &getGraphvizDot() const;
|
||||||
void setPlantUMLDot(const QString &p_dotPath);
|
void setGraphvizDot(const QString &p_dotPath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Look up a config from user and default settings.
|
// Look up a config from user and default settings.
|
||||||
@ -634,6 +637,11 @@ private:
|
|||||||
// Enable Mathjax.
|
// Enable Mathjax.
|
||||||
bool m_enableMathjax;
|
bool m_enableMathjax;
|
||||||
|
|
||||||
|
// Enable Graphviz.
|
||||||
|
bool m_enableGraphviz;
|
||||||
|
|
||||||
|
QString m_graphvizDot;
|
||||||
|
|
||||||
// Zoom factor of the QWebEngineView.
|
// Zoom factor of the QWebEngineView.
|
||||||
qreal m_webZoomFactor;
|
qreal m_webZoomFactor;
|
||||||
|
|
||||||
@ -871,8 +879,6 @@ private:
|
|||||||
|
|
||||||
QString m_plantUMLJar;
|
QString m_plantUMLJar;
|
||||||
|
|
||||||
QString m_plantUMLDot;
|
|
||||||
|
|
||||||
// The name of the config file in each directory, obsolete.
|
// The name of the config file in each directory, obsolete.
|
||||||
// Use c_dirConfigFile instead.
|
// Use c_dirConfigFile instead.
|
||||||
static const QString c_obsoleteDirConfigFile;
|
static const QString c_obsoleteDirConfigFile;
|
||||||
@ -1351,6 +1357,21 @@ inline void VConfigManager::setEnableMathjax(bool p_enabled)
|
|||||||
setConfigToSettings("global", "enable_mathjax", m_enableMathjax);
|
setConfigToSettings("global", "enable_mathjax", m_enableMathjax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool VConfigManager::getEnableGraphviz() const
|
||||||
|
{
|
||||||
|
return m_enableGraphviz;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void VConfigManager::setEnableGraphviz(bool p_enabled)
|
||||||
|
{
|
||||||
|
if (m_enableGraphviz == p_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_enableGraphviz = p_enabled;
|
||||||
|
setConfigToSettings("global", "enable_graphviz", m_enableGraphviz);
|
||||||
|
}
|
||||||
|
|
||||||
inline int VConfigManager::getPlantUMLMode() const
|
inline int VConfigManager::getPlantUMLMode() const
|
||||||
{
|
{
|
||||||
return m_plantUMLMode;
|
return m_plantUMLMode;
|
||||||
@ -2217,18 +2238,18 @@ inline void VConfigManager::setPlantUMLJar(const QString &p_jarPath)
|
|||||||
setConfigToSettings("web", "plantuml_jar", p_jarPath);
|
setConfigToSettings("web", "plantuml_jar", p_jarPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const QString &VConfigManager::getPlantUMLDot() const
|
inline const QString &VConfigManager::getGraphvizDot() const
|
||||||
{
|
{
|
||||||
return m_plantUMLDot;
|
return m_graphvizDot;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void VConfigManager::setPlantUMLDot(const QString &p_dotPath)
|
inline void VConfigManager::setGraphvizDot(const QString &p_dotPath)
|
||||||
{
|
{
|
||||||
if (m_plantUMLDot == p_dotPath) {
|
if (m_graphvizDot == p_dotPath) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_plantUMLDot = p_dotPath;
|
m_graphvizDot = p_dotPath;
|
||||||
setConfigToSettings("web", "plantuml_dot", p_dotPath);
|
setConfigToSettings("web", "graphviz_dot", p_dotPath);
|
||||||
}
|
}
|
||||||
#endif // VCONFIGMANAGER_H
|
#endif // VCONFIGMANAGER_H
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
#include "vplantumlhelper.h"
|
#include "vplantumlhelper.h"
|
||||||
|
#include "vgraphvizhelper.h"
|
||||||
|
|
||||||
VDocument::VDocument(const VFile *v_file, QObject *p_parent)
|
VDocument::VDocument(const VFile *v_file, QObject *p_parent)
|
||||||
: QObject(p_parent),
|
: QObject(p_parent),
|
||||||
m_file(v_file),
|
m_file(v_file),
|
||||||
m_readyToHighlight(false),
|
m_readyToHighlight(false),
|
||||||
m_plantUMLHelper(NULL)
|
m_plantUMLHelper(NULL),
|
||||||
|
m_graphvizHelper(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,10 +144,19 @@ void VDocument::processPlantUML(int p_id, const QString &p_format, const QString
|
|||||||
if (!m_plantUMLHelper) {
|
if (!m_plantUMLHelper) {
|
||||||
m_plantUMLHelper = new VPlantUMLHelper(this);
|
m_plantUMLHelper = new VPlantUMLHelper(this);
|
||||||
connect(m_plantUMLHelper, &VPlantUMLHelper::resultReady,
|
connect(m_plantUMLHelper, &VPlantUMLHelper::resultReady,
|
||||||
this, [this](int p_id, const QString &p_format, const QString &p_result) {
|
this, &VDocument::plantUMLResultReady);
|
||||||
emit plantUMLResultReady(p_id, p_format, p_result);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_plantUMLHelper->processAsync(p_id, p_format, p_text);
|
m_plantUMLHelper->processAsync(p_id, p_format, p_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VDocument::processGraphviz(int p_id, const QString &p_format, const QString &p_text)
|
||||||
|
{
|
||||||
|
if (!m_graphvizHelper) {
|
||||||
|
m_graphvizHelper = new VGraphvizHelper(this);
|
||||||
|
connect(m_graphvizHelper, &VGraphvizHelper::resultReady,
|
||||||
|
this, &VDocument::graphvizResultReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_graphvizHelper->processAsync(p_id, p_format, p_text);
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
class VFile;
|
class VFile;
|
||||||
class VPlantUMLHelper;
|
class VPlantUMLHelper;
|
||||||
|
class VGraphvizHelper;
|
||||||
|
|
||||||
class VDocument : public QObject
|
class VDocument : public QObject
|
||||||
{
|
{
|
||||||
@ -86,6 +87,9 @@ public slots:
|
|||||||
// Web-side call this to process PlantUML locally.
|
// Web-side call this to process PlantUML locally.
|
||||||
void processPlantUML(int p_id, const QString &p_format, const QString &p_text);
|
void processPlantUML(int p_id, const QString &p_format, const QString &p_text);
|
||||||
|
|
||||||
|
// Web-side call this to process Graphviz locally.
|
||||||
|
void processGraphviz(int p_id, const QString &p_format, const QString &p_text);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void textChanged(const QString &text);
|
void textChanged(const QString &text);
|
||||||
|
|
||||||
@ -124,6 +128,8 @@ signals:
|
|||||||
|
|
||||||
void plantUMLResultReady(int p_id, const QString &p_format, const QString &p_result);
|
void plantUMLResultReady(int p_id, const QString &p_format, const QString &p_result);
|
||||||
|
|
||||||
|
void graphvizResultReady(int p_id, const QString &p_format, const QString &p_result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_toc;
|
QString m_toc;
|
||||||
QString m_header;
|
QString m_header;
|
||||||
@ -145,6 +151,8 @@ private:
|
|||||||
VWordCountInfo m_wordCountInfo;
|
VWordCountInfo m_wordCountInfo;
|
||||||
|
|
||||||
VPlantUMLHelper *m_plantUMLHelper;
|
VPlantUMLHelper *m_plantUMLHelper;
|
||||||
|
|
||||||
|
VGraphvizHelper *m_graphvizHelper;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool VDocument::isReadyToHighlight() const
|
inline bool VDocument::isReadyToHighlight() const
|
||||||
|
@ -1012,6 +1012,7 @@ bool VEditArea::activateNextTabByCaptain(void *p_target, void *p_data)
|
|||||||
VEditWindow *win = obj->getCurrentWindow();
|
VEditWindow *win = obj->getCurrentWindow();
|
||||||
if (win) {
|
if (win) {
|
||||||
win->focusNextTab(true);
|
win->focusNextTab(true);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
83
src/vgraphvizhelper.cpp
Normal file
83
src/vgraphvizhelper.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "vgraphvizhelper.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "vconfigmanager.h"
|
||||||
|
|
||||||
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
|
#define TaskIdProperty "GraphvizTaskId"
|
||||||
|
#define TaskFormatProperty "GraphvizTaskFormat"
|
||||||
|
|
||||||
|
VGraphvizHelper::VGraphvizHelper(QObject *p_parent)
|
||||||
|
: QObject(p_parent)
|
||||||
|
{
|
||||||
|
prepareCommand(m_program, m_args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGraphvizHelper::processAsync(int p_id, const QString &p_format, const QString &p_text)
|
||||||
|
{
|
||||||
|
QProcess *process = new QProcess(this);
|
||||||
|
process->setProperty(TaskIdProperty, p_id);
|
||||||
|
process->setProperty(TaskFormatProperty, p_format);
|
||||||
|
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
|
||||||
|
this, SLOT(handleProcessFinished(int, QProcess::ExitStatus)));
|
||||||
|
|
||||||
|
QStringList args(m_args);
|
||||||
|
args << ("-T" + p_format);
|
||||||
|
|
||||||
|
qDebug() << m_program << args;
|
||||||
|
|
||||||
|
process->start(m_program, args);
|
||||||
|
process->write(p_text.toUtf8());
|
||||||
|
process->closeWriteChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGraphvizHelper::prepareCommand(QString &p_program, QStringList &p_args) const
|
||||||
|
{
|
||||||
|
const QString &dot = g_config->getGraphvizDot();
|
||||||
|
if (dot.isEmpty()) {
|
||||||
|
p_program = "dot";
|
||||||
|
} else {
|
||||||
|
p_program = dot;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_args.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VGraphvizHelper::handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_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;
|
||||||
|
bool failed = true;
|
||||||
|
if (p_exitStatus == QProcess::NormalExit) {
|
||||||
|
if (p_exitCode < 0) {
|
||||||
|
qWarning() << "Graphviz fail" << p_exitCode;
|
||||||
|
} else {
|
||||||
|
failed = false;
|
||||||
|
QByteArray outBa = process->readAllStandardOutput();
|
||||||
|
if (format == "svg") {
|
||||||
|
emit resultReady(id, format, QString::fromLocal8Bit(outBa));
|
||||||
|
} else {
|
||||||
|
emit resultReady(id, format, QString::fromLocal8Bit(outBa.toBase64()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << "fail to start Graphviz process" << p_exitCode << p_exitStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
QByteArray errBa = process->readAllStandardError();
|
||||||
|
if (!errBa.isEmpty()) {
|
||||||
|
QString errStr(QString::fromLocal8Bit(errBa));
|
||||||
|
qWarning() << "Graphviz stderr:" << errStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit resultReady(id, format, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
process->deleteLater();
|
||||||
|
}
|
30
src/vgraphvizhelper.h
Normal file
30
src/vgraphvizhelper.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef VGRAPHVIZHELPER_H
|
||||||
|
#define VGRAPHVIZHELPER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
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 prepareCommand(QString &p_cmd, QStringList &p_args) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void resultReady(int p_id, const QString &p_format, const QString &p_result);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleProcessFinished(int p_exitCode, QProcess::ExitStatus p_exitStatus);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_program;
|
||||||
|
QStringList m_args;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VGRAPHVIZHELPER_H
|
@ -44,7 +44,7 @@ void VPlantUMLHelper::prepareCommand(QString &p_program, QStringList &p_args) co
|
|||||||
int nbthread = QThread::idealThreadCount();
|
int nbthread = QThread::idealThreadCount();
|
||||||
p_args << "-nbthread" << QString::number(nbthread > 0 ? nbthread : 1);
|
p_args << "-nbthread" << QString::number(nbthread > 0 ? nbthread : 1);
|
||||||
|
|
||||||
const QString &dot = g_config->getPlantUMLDot();
|
const QString &dot = g_config->getGraphvizDot();
|
||||||
if (!dot.isEmpty()) {
|
if (!dot.isEmpty()) {
|
||||||
p_args << "-graphvizdot";
|
p_args << "-graphvizdot";
|
||||||
p_args << dot;
|
p_args << dot;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user