Browse Source

support Graphviz

Le Tan 7 years ago
parent
commit
2206102945

+ 31 - 7
src/dialog/vsettingsdialog.cpp

@@ -912,10 +912,13 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent)
     m_plantUMLJarEdit = new VLineEdit();
     m_plantUMLJarEdit->setToolTip(tr("Location to the PlantUML JAR executable for local PlantUML"));
 
-    m_plantUMLDotEdit = new VLineEdit();
-    m_plantUMLDotEdit->setPlaceholderText(tr("Empty to detect automatically"));
-    m_plantUMLDotEdit->setToolTip(tr("Location to the GraphViz executable for local PlantUML "
-                                     "(empty to let PlantUML detect it automatically)"));
+    // Graphviz.
+    m_graphvizCB = new QCheckBox(tr("Graphviz"));
+    m_graphvizCB->setToolTip(tr("Enable Graphviz for drawing graph"));
+
+    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();
     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 server:"), m_plantUMLServerEdit);
     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);
 }
@@ -947,6 +951,10 @@ bool VMarkdownTab::loadConfiguration()
         return false;
     }
 
+    if (!loadGraphviz()) {
+        return false;
+    }
+
     return true;
 }
 
@@ -968,6 +976,10 @@ bool VMarkdownTab::saveConfiguration()
         return false;
     }
 
+    if (!saveGraphviz()) {
+        return false;
+    }
+
     return true;
 }
 
@@ -1044,7 +1056,6 @@ bool VMarkdownTab::loadPlantUML()
     m_plantUMLModeCombo->setCurrentIndex(m_plantUMLModeCombo->findData(g_config->getPlantUMLMode()));
     m_plantUMLServerEdit->setText(g_config->getPlantUMLServer());
     m_plantUMLJarEdit->setText(g_config->getPlantUMLJar());
-    m_plantUMLDotEdit->setText(g_config->getPlantUMLDot());
     return true;
 }
 
@@ -1053,6 +1064,19 @@ bool VMarkdownTab::savePlantUML()
     g_config->setPlantUMLMode(m_plantUMLModeCombo->currentData().toInt());
     g_config->setPlantUMLServer(m_plantUMLServerEdit->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;
 }

+ 7 - 1
src/dialog/vsettingsdialog.h

@@ -160,6 +160,9 @@ private:
     bool loadPlantUML();
     bool savePlantUML();
 
+    bool loadGraphviz();
+    bool saveGraphviz();
+
     // Default note open mode for markdown.
     QComboBox *m_openModeCombo;
 
@@ -174,7 +177,10 @@ private:
     QComboBox *m_plantUMLModeCombo;
     VLineEdit *m_plantUMLServerEdit;
     VLineEdit *m_plantUMLJarEdit;
-    VLineEdit *m_plantUMLDotEdit;
+
+    // Graphviz.
+    QCheckBox *m_graphvizCB;
+    VLineEdit *m_graphvizDotEdit;
 };
 
 class VSettingsDialog : public QDialog

+ 7 - 0
src/resources/hoedown.js

@@ -25,6 +25,7 @@ var updateHtml = function(html) {
     var codes = document.getElementsByTagName('code');
     mermaidIdx = 0;
     plantUMLIdx = 0;
+    graphvizIdx = 0;
     for (var i = 0; i < codes.length; ++i) {
         var code = codes[i];
         if (code.parentElement.tagName.toLowerCase() == 'pre') {
@@ -59,9 +60,15 @@ var updateHtml = function(html) {
                     renderPlantUMLOneLocal(code);
                 }
 
+                continue;
+            } else if (VEnableGraphviz
+                       && code.classList.contains('language-dot')) {
+                // Graphviz code block.
+                renderGraphvizOneLocal(code);
                 continue;
             }
 
+
             if (listContainsRegex(code.classList, /language-.*/)) {
                 hljs.highlightBlock(code);
             }

+ 1 - 0
src/resources/markdown-it.js

@@ -116,6 +116,7 @@ var updateText = function(text) {
     renderMermaid('lang-mermaid');
     renderFlowchart(['lang-flowchart', 'lang-flow']);
     renderPlantUML('lang-puml');
+    renderGraphviz('lang-dot');
     addClassToCodeBlock();
     renderCodeBlockLineNumber();
 

+ 76 - 9
src/resources/markdown_template.js

@@ -1,3 +1,5 @@
+var channelInitialized = false;
+
 var content;
 
 // Current header index in all headers.
@@ -45,6 +47,18 @@ if (typeof VPlantUMLServer == 'undefined') {
     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.
 var VImageCenterClass = 'img-center';
 var VImageCaptionClass = 'img-caption';
@@ -123,14 +137,7 @@ var htmlContent = function() {
 new QWebChannel(qt.webChannelTransport,
     function(channel) {
         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);
 
         if (typeof highlightText == "function") {
@@ -148,6 +155,19 @@ new QWebChannel(qt.webChannelTransport,
         }
 
         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';
@@ -686,6 +706,33 @@ var renderPlantUMLOneLocal = function(code) {
     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 pn = img.parentNode;
     return (pn.children.length == 1) && (pn.textContent == '');
@@ -1260,7 +1307,8 @@ var specialCodeBlock = function(lang) {
     return (VEnableMathjax && lang == 'mathjax')
            || (VEnableMermaid && lang == 'mermaid')
            || (VEnableFlowchart && (lang == 'flowchart' || lang == 'flow'))
-           || (VPlantUMLMode != 0 && lang == 'puml');
+           || (VPlantUMLMode != 0 && lang == 'puml')
+           || (VEnableGraphviz && lang == 'dot');
 };
 
 var handlePlantUMLResult = function(id, format, result) {
@@ -1282,3 +1330,22 @@ var handlePlantUMLResult = function(id, format, result) {
 
     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();
+};

+ 1 - 0
src/resources/marked.js

@@ -60,6 +60,7 @@ var updateText = function(text) {
     renderMermaid('lang-mermaid');
     renderFlowchart(['lang-flowchart', 'lang-flow']);
     renderPlantUML('lang-puml');
+    renderGraphviz('lang-dot');
     addClassToCodeBlock();
     renderCodeBlockLineNumber();
 

+ 16 - 2
src/resources/showdown.js

@@ -49,7 +49,12 @@ var mdHasTocSection = function(markdown) {
     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');
     for (var i = 0; i < codes.length; ++i) {
         var code = codes[i];
@@ -68,6 +73,9 @@ var highlightCodeBlocks = function(doc, enableMermaid, enableFlowchart, enableMa
             } else if (enablePlantUML && code.classList.contains('language-puml')) {
                 // PlantUML code block.
                 continue;
+            } else if (enableGraphviz && code.classList.contains('language-dot')) {
+                // Graphviz code block.
+                continue;
             }
 
             if (listContainsRegex(code.classList, /language-.*/)) {
@@ -89,10 +97,16 @@ var updateText = function(text) {
     placeholder.innerHTML = html;
     handleToc(needToc);
     insertImageCaption();
-    highlightCodeBlocks(document, VEnableMermaid, VEnableFlowchart, VEnableMathjax, VPlantUMLMode != 0);
+    highlightCodeBlocks(document,
+                        VEnableMermaid,
+                        VEnableFlowchart,
+                        VEnableMathjax,
+                        VPlantUMLMode != 0,
+                        VEnableGraphviz);
     renderMermaid('language-mermaid');
     renderFlowchart(['language-flowchart', 'language-flow']);
     renderPlantUML('language-puml');
+    renderGraphviz('language-dot');
     addClassToCodeBlock();
     renderCodeBlockLineNumber();
 

+ 5 - 2
src/resources/vnote.ini

@@ -49,6 +49,9 @@ enable_flowchart=false
 ; 2 - local PlantUML
 plantuml_mode=0
 
+; Enable Graphviz
+enable_graphviz=false
+
 ; -1 - calculate the factor
 web_zoom_factor=-1
 
@@ -277,8 +280,8 @@ plantuml_server=http://www.plantuml.com/plantuml
 ; PlantUML JAR location
 plantuml_jar=
 
-; PlantUML Graphviz Dot location
-plantuml_dot=
+; Graphviz Dot location
+graphviz_dot=
 
 [shortcuts]
 ; Define shortcuts here, with each item in the form "operation=keysequence".

+ 4 - 2
src/src.pro

@@ -126,7 +126,8 @@ SOURCES += main.cpp\
     vhelpue.cpp \
     vlistfolderue.cpp \
     dialog/vfixnotebookdialog.cpp \
-    vplantumlhelper.cpp
+    vplantumlhelper.cpp \
+    vgraphvizhelper.cpp
 
 HEADERS  += vmainwindow.h \
     vdirectorytree.h \
@@ -243,7 +244,8 @@ HEADERS  += vmainwindow.h \
     vhelpue.h \
     vlistfolderue.h \
     dialog/vfixnotebookdialog.h \
-    vplantumlhelper.h
+    vplantumlhelper.h \
+    vgraphvizhelper.h
 
 RESOURCES += \
     vnote.qrc \

+ 7 - 0
src/utils/vutils.cpp

@@ -736,6 +736,13 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
         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()) {
         extraFile += "<script>var VEnableImageCaption = true;</script>\n";
     }

+ 3 - 1
src/vconfigmanager.cpp

@@ -288,7 +288,9 @@ void VConfigManager::initialize()
     m_plantUMLMode = getConfigFromSettings("global", "plantuml_mode").toInt();
     m_plantUMLServer = getConfigFromSettings("web", "plantuml_server").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()

+ 31 - 10
src/vconfigmanager.h

@@ -210,6 +210,9 @@ public:
     bool getEnableMathjax() const;
     void setEnableMathjax(bool p_enabled);
 
+    bool getEnableGraphviz() const;
+    void setEnableGraphviz(bool p_enabled);
+
     int getPlantUMLMode() const;
     void setPlantUMLMode(int p_mode);
 
@@ -469,8 +472,8 @@ public:
     const QString &getPlantUMLJar() const;
     void setPlantUMLJar(const QString &p_jarPath);
 
-    const QString &getPlantUMLDot() const;
-    void setPlantUMLDot(const QString &p_dotPath);
+    const QString &getGraphvizDot() const;
+    void setGraphvizDot(const QString &p_dotPath);
 
 private:
     // Look up a config from user and default settings.
@@ -634,6 +637,11 @@ private:
     // Enable Mathjax.
     bool m_enableMathjax;
 
+    // Enable Graphviz.
+    bool m_enableGraphviz;
+
+    QString m_graphvizDot;
+
     // Zoom factor of the QWebEngineView.
     qreal m_webZoomFactor;
 
@@ -871,8 +879,6 @@ private:
 
     QString m_plantUMLJar;
 
-    QString m_plantUMLDot;
-
     // The name of the config file in each directory, obsolete.
     // Use c_dirConfigFile instead.
     static const QString c_obsoleteDirConfigFile;
@@ -1351,6 +1357,21 @@ inline void VConfigManager::setEnableMathjax(bool p_enabled)
     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
 {
     return m_plantUMLMode;
@@ -2217,18 +2238,18 @@ inline void VConfigManager::setPlantUMLJar(const QString &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;
     }
 
-    m_plantUMLDot = p_dotPath;
-    setConfigToSettings("web", "plantuml_dot", p_dotPath);
+    m_graphvizDot = p_dotPath;
+    setConfigToSettings("web", "graphviz_dot", p_dotPath);
 }
 #endif // VCONFIGMANAGER_H

+ 15 - 4
src/vdocument.cpp

@@ -4,12 +4,14 @@
 
 #include "vfile.h"
 #include "vplantumlhelper.h"
+#include "vgraphvizhelper.h"
 
 VDocument::VDocument(const VFile *v_file, QObject *p_parent)
     : QObject(p_parent),
       m_file(v_file),
       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) {
         m_plantUMLHelper = new VPlantUMLHelper(this);
         connect(m_plantUMLHelper, &VPlantUMLHelper::resultReady,
-                this, [this](int p_id, const QString &p_format, const QString &p_result) {
-                    emit plantUMLResultReady(p_id, p_format, p_result);
-                });
+                this, &VDocument::plantUMLResultReady);
     }
 
     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 - 0
src/vdocument.h

@@ -8,6 +8,7 @@
 
 class VFile;
 class VPlantUMLHelper;
+class VGraphvizHelper;
 
 class VDocument : public QObject
 {
@@ -86,6 +87,9 @@ public slots:
     // Web-side call this to process PlantUML locally.
     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:
     void textChanged(const QString &text);
 
@@ -124,6 +128,8 @@ signals:
 
     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:
     QString m_toc;
     QString m_header;
@@ -145,6 +151,8 @@ private:
     VWordCountInfo m_wordCountInfo;
 
     VPlantUMLHelper *m_plantUMLHelper;
+
+    VGraphvizHelper *m_graphvizHelper;
 };
 
 inline bool VDocument::isReadyToHighlight() const

+ 1 - 0
src/veditarea.cpp

@@ -1012,6 +1012,7 @@ bool VEditArea::activateNextTabByCaptain(void *p_target, void *p_data)
     VEditWindow *win = obj->getCurrentWindow();
     if (win) {
         win->focusNextTab(true);
+        return false;
     }
 
     return true;

+ 83 - 0
src/vgraphvizhelper.cpp

@@ -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 - 0
src/vgraphvizhelper.h

@@ -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

+ 1 - 1
src/vplantumlhelper.cpp

@@ -44,7 +44,7 @@ void VPlantUMLHelper::prepareCommand(QString &p_program, QStringList &p_args) co
     int nbthread = QThread::idealThreadCount();
     p_args << "-nbthread" << QString::number(nbthread > 0 ? nbthread : 1);
 
-    const QString &dot = g_config->getPlantUMLDot();
+    const QString &dot = g_config->getGraphvizDot();
     if (!dot.isEmpty()) {
         p_args << "-graphvizdot";
         p_args << dot;