Browse Source

magic-word: support overriding magic words

- Add %dt%, %note%, and %no%;
- Support overriding magic words with simple literal value;
Le Tan 8 years ago
parent
commit
93ba677116

+ 5 - 1
src/dialog/vnewfiledialog.cpp

@@ -258,7 +258,11 @@ bool VNewFileDialog::isTemplateUsed() const
 
 QString VNewFileDialog::getTemplate() const
 {
-    return g_mwMgr->evaluate(m_template);
+    QString name = m_nameEdit->getEvaluatedText();
+    QHash<QString, QString> overriddenTable;
+    overriddenTable.insert("note", name);
+    overriddenTable.insert("no", QFileInfo(name).completeBaseName());
+    return g_mwMgr->evaluate(m_template, overriddenTable);
 }
 
 void VNewFileDialog::tryToSelectLastTemplate()

+ 67 - 4
src/utils/vmetawordmanager.cpp

@@ -4,11 +4,15 @@
 #include <QWidget>
 #include <QApplication>
 #include <QToolTip>
+#include <QFileInfo>
 
 #include "vconfigmanager.h"
+#include "vmainwindow.h"
 
 extern VConfigManager *g_config;
 
+extern VMainWindow *g_mainWin;
+
 
 // Used as the function template for some date/time related meta words.
 static QString formattedDateTime(const VMetaWord *p_metaWord,
@@ -238,6 +242,37 @@ void VMetaWordManager::init()
                 "datetime",
                 QString("%1date%1 %1time%1").arg(c_delimiter));
 
+    // %dt%.
+    addMetaWord(MetaWordType::Compound,
+                "dt",
+                QString("%1da%1-%1time%1").arg(c_delimiter));
+
+    // %note%.
+    addMetaWord(MetaWordType::FunctionBased,
+                "note",
+                tr("name of current note"),
+                [](const VMetaWord *) {
+                    const VFile *file = g_mainWin->getCurrentFile();
+                    if (file) {
+                        return file->getName();
+                    }
+
+                    return QString();
+                });
+
+    // %no%.
+    addMetaWord(MetaWordType::FunctionBased,
+                "no",
+                tr("complete base name of current note"),
+                [](const VMetaWord *) {
+                    const VFile *file = g_mainWin->getCurrentFile();
+                    if (file) {
+                        return QFileInfo(file->getName()).completeBaseName();
+                    }
+
+                    return QString();
+                });
+
     // Custom meta words.
     initCustomMetaWords();
 
@@ -258,7 +293,8 @@ void VMetaWordManager::initCustomMetaWords()
     }
 }
 
-QString VMetaWordManager::evaluate(const QString &p_text) const
+QString VMetaWordManager::evaluate(const QString &p_text,
+                                   const QHash<QString, QString> &p_overriddenWords) const
 {
     if (p_text.isEmpty()) {
         return p_text;
@@ -267,6 +303,9 @@ QString VMetaWordManager::evaluate(const QString &p_text) const
     // Update datetime for later parse.
     const_cast<VMetaWordManager *>(this)->m_dateTime = QDateTime::currentDateTime();
 
+    // Update overriden table.
+    const_cast<VMetaWordManager *>(this)->m_overriddenWords = p_overriddenWords;
+
     // Treat the text as a Compound meta word.
     const QString tmpWord("vnote_tmp_metaword");
     Q_ASSERT(!contains(tmpWord));
@@ -276,11 +315,17 @@ QString VMetaWordManager::evaluate(const QString &p_text) const
                        p_text,
                        nullptr,
                        true);
+
+    QString val;
     if (metaWord.isValid()) {
-        return metaWord.evaluate();
+        val = metaWord.evaluate();
     } else {
-        return p_text;
+        val = p_text;
     }
+
+    const_cast<VMetaWordManager *>(this)->m_overriddenWords.clear();
+
+    return val;
 }
 
 bool VMetaWordManager::contains(const QString &p_word) const
@@ -320,6 +365,18 @@ void VMetaWordManager::addMetaWord(MetaWordType p_type,
     }
 }
 
+bool VMetaWordManager::findOverriddenValue(const QString &p_word,
+                                           QString &p_value) const
+{
+    auto it = m_overriddenWords.find(p_word);
+    if (it != m_overriddenWords.end()) {
+        p_value = it.value();
+        return true;
+    }
+
+    return false;
+}
+
 VMetaWord::VMetaWord(const VMetaWordManager *p_manager,
                      MetaWordType p_type,
                      const QString &p_word,
@@ -398,7 +455,13 @@ bool VMetaWord::isValid() const
 QString VMetaWord::evaluate() const
 {
     Q_ASSERT(m_valid);
-    qDebug() << "evaluate meta word" << m_word;
+
+    // Check overridden table first.
+    QString overriddenVal;
+    if (m_manager->findOverriddenValue(m_word, overriddenVal)) {
+        return overriddenVal;
+    }
+
     switch (m_type) {
     case MetaWordType::Simple:
         return m_definition;

+ 12 - 1
src/utils/vmetawordmanager.h

@@ -8,6 +8,7 @@
 #include <QVector>
 #include <QHash>
 #include <QDateTime>
+#include <QHash>
 
 
 enum class MetaWordType
@@ -163,7 +164,9 @@ public:
     void init();
 
     // Expand meta words in @p_text and return the expanded text.
-    QString evaluate(const QString &p_text) const;
+    // @p_overriddenWords: a table containing overridden meta words.
+    QString evaluate(const QString &p_text,
+                     const QHash<QString, QString> &p_overriddenWords = QHash<QString, QString>()) const;
 
     const VMetaWord *findMetaWord(const QString &p_word) const;
 
@@ -173,6 +176,10 @@ public:
 
     const QHash<QString, VMetaWord> &getAllMetaWords() const;
 
+    // Find @p_word in the overridden table.
+    // Return true if found and set @p_value to the overridden value.
+    bool findOverriddenValue(const QString &p_word, QString &p_value) const;
+
     // % by default.
     static const QChar c_delimiter;
 
@@ -190,6 +197,10 @@ private:
     // Used for data/time related evaluate.
     // Will be updated before each evaluation.
     QDateTime m_dateTime;
+
+    // Overridden table containing meta words with their designated value.
+    // Will be updated before each evaluation and clear after the evaluation.
+    QHash<QString, QString> m_overriddenWords;
 };
 
 inline const QDateTime &VMetaWordManager::getDateTime() const

+ 0 - 3
src/vcaptain.cpp

@@ -3,15 +3,12 @@
 #include <QDebug>
 #include <QShortcut>
 #include "vcaptain.h"
-#include "vmainwindow.h"
 #include "veditarea.h"
 #include "vedittab.h"
 #include "vfilelist.h"
 #include "vnavigationmode.h"
 #include "vconfigmanager.h"
 
-extern VMainWindow *g_mainWin;
-
 extern VConfigManager *g_config;
 
 VCaptain::VCaptain(QWidget *p_parent)

+ 8 - 2
src/vmainwindow.h

@@ -52,9 +52,8 @@ class VMainWindow : public QMainWindow
     Q_OBJECT
 
 public:
-    friend class VCaptain;
-
     VMainWindow(VSingleInstanceGuard *p_guard, QWidget *p_parent = 0);
+
     const QVector<QPair<QString, QString> > &getPalette() const;
 
     // Returns true if the location succeeds.
@@ -86,6 +85,8 @@ public:
     // Prompt user for new notebook if there is no notebook.
     void promptNewNotebookIfEmpty();
 
+    VFile *getCurrentFile() const;
+
 signals:
     // Emit when editor related configurations were changed by user.
     void editorConfigUpdated();
@@ -390,4 +391,9 @@ inline VCaptain *VMainWindow::getCaptain() const
     return m_captain;
 }
 
+inline VFile *VMainWindow::getCurrentFile() const
+{
+    return m_curFile;
+}
+
 #endif // VMAINWINDOW_H