Forráskód Böngészése

support custom CSS styles

VNote will find CSS files in the "styles" folder under the config folder.
Le Tan 8 éve
szülő
commit
d0d4e1443d

+ 0 - 0
src/resources/markdown.css → src/resources/styles/default.css


+ 1 - 1
src/resources/vnote.ini

@@ -1,6 +1,6 @@
 [global]
 welcome_page_path=:/resources/welcome.html
-template_css_url=qrc:/resources/markdown.css
+template_css=default
 current_notebook=0
 tab_stop_width=4
 is_expand_tab=true

+ 99 - 3
src/vconfigmanager.cpp

@@ -10,11 +10,13 @@
 #include "utils/vutils.h"
 #include "vstyleparser.h"
 
-const QString VConfigManager::orgName = QString("tamlok");
+const QString VConfigManager::orgName = QString("vnote");
 const QString VConfigManager::appName = QString("vnote");
 const QString VConfigManager::c_version = QString("1.2");
 const QString VConfigManager::dirConfigFileName = QString(".vnote.json");
 const QString VConfigManager::defaultConfigFilePath = QString(":/resources/vnote.ini");
+const QString VConfigManager::c_styleConfigFolder = QString("styles");
+const QString VConfigManager::c_defaultCssFile = QString(":/resources/styles/default.css");
 
 VConfigManager::VConfigManager()
     : userSettings(NULL), defaultSettings(NULL)
@@ -31,11 +33,24 @@ VConfigManager::~VConfigManager()
     }
 }
 
+void VConfigManager::migrateIniFile()
+{
+    const QString originalFolder = "tamlok";
+    const QString newFolder = orgName;
+    QString configFolder = getConfigFolder();
+    QDir dir(configFolder);
+    dir.cdUp();
+    dir.rename(originalFolder, newFolder);
+}
+
 void VConfigManager::initialize()
 {
-    userSettings = new QSettings(QSettings::IniFormat, QSettings::UserScope, orgName, appName);
+    userSettings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
+                                 orgName, appName);
     defaultSettings = new QSettings(defaultConfigFilePath, QSettings::IniFormat);
 
+    migrateIniFile();
+
     m_editorFontSize = getConfigFromSettings("global", "editor_font_size").toInt();
     if (m_editorFontSize <= 0) {
         m_editorFontSize = 12;
@@ -44,7 +59,7 @@ void VConfigManager::initialize()
     baseEditPalette = QTextEdit().palette();
 
     welcomePagePath = getConfigFromSettings("global", "welcome_page_path").toString();
-    templateCssUrl = getConfigFromSettings("global", "template_css_url").toString();
+    m_templateCss = getConfigFromSettings("global", "template_css").toString();
     curNotebookIndex = getConfigFromSettings("global", "current_notebook").toInt();
 
     markdownExtensions = hoedown_extensions(HOEDOWN_EXT_TABLES | HOEDOWN_EXT_FENCED_CODE |
@@ -311,3 +326,84 @@ void VConfigManager::setWebZoomFactor(qreal p_factor)
     setConfigToSettings("global", "web_zoom_factor", m_webZoomFactor);
 }
 
+QString VConfigManager::getConfigFolder() const
+{
+    V_ASSERT(userSettings);
+
+    QString iniPath = userSettings->fileName();
+    return VUtils::basePathFromPath(iniPath);
+}
+
+QString VConfigManager::getStyleConfigFolder() const
+{
+    return getConfigFolder() + QDir::separator() + c_styleConfigFolder;
+}
+
+QVector<QString> VConfigManager::getCssStyles() const
+{
+    QVector<QString> res;
+    QDir dir(getStyleConfigFolder());
+    if (!dir.exists()) {
+        // Output pre-defined css styles to this folder.
+        outputDefaultCssStyle();
+    }
+
+    // Get all the .css files in the folder.
+    dir.setFilter(QDir::Files | QDir::NoSymLinks);
+    dir.setNameFilters(QStringList("*.css"));
+    QStringList files = dir.entryList();
+    res.reserve(files.size());
+    for (auto const &item : files) {
+        res.push_back(item.left(item.size() - 4));
+    }
+    return res;
+}
+
+bool VConfigManager::outputDefaultCssStyle() const
+{
+    // Make sure the styles folder exists.
+    QDir dir(getConfigFolder());
+    if (!dir.exists(c_styleConfigFolder)) {
+        if (!dir.mkdir(c_styleConfigFolder)) {
+            return false;
+        }
+    }
+    return VUtils::copyFile(c_defaultCssFile,
+                            getStyleConfigFolder() + QDir::separator() + "default.css",
+                            false);
+}
+
+QString VConfigManager::getTemplateCssUrl()
+{
+    QString cssPath = getStyleConfigFolder() + QDir::separator() + m_templateCss + ".css";
+    if (!QFile::exists(cssPath)) {
+        // Specified css not exists.
+        if (m_templateCss == "default") {
+            bool ret = outputDefaultCssStyle();
+            if (!ret) {
+                // Use embedded file.
+                cssPath = "qrc" + c_defaultCssFile;
+            }
+        } else {
+            setTemplateCss("default");
+            return getTemplateCssUrl();
+        }
+    }
+
+    qDebug() << "use template css:" << cssPath;
+    return cssPath;
+}
+
+const QString &VConfigManager::getTemplateCss() const
+{
+    return m_templateCss;
+}
+
+void VConfigManager::setTemplateCss(const QString &p_css)
+{
+    if (m_templateCss == p_css) {
+        return;
+    }
+    m_templateCss = p_css;
+    setConfigToSettings("global", "template_css", m_templateCss);
+}

+ 23 - 7
src/vconfigmanager.h

@@ -54,7 +54,10 @@ public:
 
     inline QString getWelcomePagePath() const;
 
-    inline QString getTemplateCssUrl() const;
+    QString getTemplateCssUrl();
+
+    const QString &getTemplateCss() const;
+    void setTemplateCss(const QString &p_css);
 
     inline QFont getBaseEditFont() const;
     inline QPalette getBaseEditPalette() const;
@@ -140,6 +143,15 @@ public:
     inline bool getEnableCodeBlockHighlight() const;
     inline void setEnableCodeBlockHighlight(bool p_enabled);
 
+    // Get the folder the ini file exists.
+    QString getConfigFolder() const;
+
+    // Get the folder c_styleConfigFolder in the config folder.
+    QString getStyleConfigFolder() const;
+
+    // Read all available css files in c_styleConfigFolder.
+    QVector<QString> getCssStyles() const;
+
 private:
     void updateMarkdownEditStyle();
     QVariant getConfigFromSettings(const QString &section, const QString &key);
@@ -150,6 +162,12 @@ private:
     // Update baseEditPalette according to curBackgroundColor
     void updatePaletteColor();
 
+    // Migrate ini file from tamlok/vnote.ini to vnote/vnote.ini.
+    // This is for the change of org name.
+    void migrateIniFile();
+
+    bool outputDefaultCssStyle() const;
+
     int m_editorFontSize;
     QFont baseEditFont;
     QPalette baseEditPalette;
@@ -158,7 +176,7 @@ private:
     QVector<HighlightingStyle> mdHighlightingStyles;
     QMap<QString, QTextCharFormat> m_codeBlockStyles;
     QString welcomePagePath;
-    QString templateCssUrl;
+    QString m_templateCss;
     int curNotebookIndex;
 
     // Markdown Converter
@@ -230,6 +248,9 @@ private:
     QSettings *userSettings;
     // Qsettings for @defaultConfigFileName
     QSettings *defaultSettings;
+    // The folder name of style files.
+    static const QString c_styleConfigFolder;
+    static const QString c_defaultCssFile;
 };
 
 
@@ -258,11 +279,6 @@ inline QString VConfigManager::getWelcomePagePath() const
     return welcomePagePath;
 }
 
-inline QString VConfigManager::getTemplateCssUrl() const
-{
-    return templateCssUrl;
-}
-
 inline QFont VConfigManager::getBaseEditFont() const
 {
     return baseEditFont;

+ 46 - 2
src/vmainwindow.cpp

@@ -348,8 +348,12 @@ void VMainWindow::initMarkdownMenu()
         Q_ASSERT(false);
     }
 
+    initRenderStyleMenu(markdownMenu);
+
     initRenderBackgroundMenu(markdownMenu);
 
+    markdownMenu->addSeparator();
+
     QAction *mermaidAct = new QAction(tr("&Mermaid Diagram"), this);
     mermaidAct->setToolTip(tr("Enable Mermaid for graph and diagram"));
     mermaidAct->setCheckable(true);
@@ -359,8 +363,8 @@ void VMainWindow::initMarkdownMenu()
 
     mermaidAct->setChecked(vconfig.getEnableMermaid());
 
-    QAction *mathjaxAct = new QAction(tr("Math&jax"), this);
-    mathjaxAct->setToolTip(tr("Enable Mathjax for math support in Markdown"));
+    QAction *mathjaxAct = new QAction(tr("Math&Jax"), this);
+    mathjaxAct->setToolTip(tr("Enable MathJax for math support in Markdown"));
     mathjaxAct->setCheckable(true);
     connect(mathjaxAct, &QAction::triggered,
             this, &VMainWindow::enableMathjax);
@@ -767,6 +771,37 @@ void VMainWindow::initRenderBackgroundMenu(QMenu *menu)
     }
 }
 
+void VMainWindow::initRenderStyleMenu(QMenu *p_menu)
+{
+    QMenu *styleMenu = p_menu->addMenu(tr("Rendering &Style"));
+    styleMenu->setToolTipsVisible(true);
+
+    QActionGroup *styleAct = new QActionGroup(this);
+    connect(styleAct, &QActionGroup::triggered,
+            this, &VMainWindow::setRenderStyle);
+
+    bool foundCurrentCss = false;
+    QVector<QString> styles = vconfig.getCssStyles();
+    for (auto const &style : styles) {
+        QAction *act = new QAction(style, styleAct);
+        act->setToolTip(tr("Set as the CSS style for Markdown rendering"));
+        act->setCheckable(true);
+        act->setData(style);
+
+        if (vconfig.getTemplateCss() == style) {
+            act->setChecked(true);
+            foundCurrentCss = true;
+        }
+    }
+
+    if (!foundCurrentCss && styles.isEmpty()) {
+        delete styleAct;
+        return;
+    }
+
+    styleMenu->addActions(styleAct->actions());
+}
+
 void VMainWindow::initEditorBackgroundMenu(QMenu *menu)
 {
     QMenu *backgroundColorMenu = menu->addMenu(tr("&Background Color"));
@@ -810,6 +845,15 @@ void VMainWindow::setRenderBackgroundColor(QAction *action)
     vnote->updateTemplate();
 }
 
+void VMainWindow::setRenderStyle(QAction *p_action)
+{
+    if (!p_action) {
+        return;
+    }
+    vconfig.setTemplateCss(p_action->data().toString());
+    vnote->updateTemplate();
+}
+
 void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file,
                                                        bool p_editMode)
 {

+ 2 - 0
src/vmainwindow.h

@@ -52,6 +52,7 @@ private slots:
     void setTabStopWidth(QAction *action);
     void setEditorBackgroundColor(QAction *action);
     void setRenderBackgroundColor(QAction *action);
+    void setRenderStyle(QAction *p_action);
     void changeHighlightCursorLine(bool p_checked);
     void changeHighlightSelectedWord(bool p_checked);
     void changeHighlightSearchedWord(bool p_checked);
@@ -97,6 +98,7 @@ private:
     void initAvatar();
     void initPredefinedColorPixmaps();
     void initRenderBackgroundMenu(QMenu *menu);
+    void initRenderStyleMenu(QMenu *p_menu);
     void initEditorBackgroundMenu(QMenu *menu);
     void changeSplitterView(int nrPanel);
     void updateWindowTitle(const QString &str);

+ 1 - 1
src/vnote.cpp

@@ -157,7 +157,7 @@ void VNote::updateTemplate()
     }
     QString cssStyle;
     if (!rgb.isEmpty()) {
-        cssStyle = "body { background-color: #" + rgb + "; }";
+        cssStyle = "body { background-color: #" + rgb + " !important; }";
     }
     QString styleHolder("<!-- BACKGROUND_PLACE_HOLDER -->");
     QString cssHolder("CSS_PLACE_HOLDER");

+ 1 - 1
src/vnote.qrc

@@ -2,7 +2,6 @@
     <qresource prefix="/">
         <file>resources/welcome.html</file>
         <file>resources/qwebchannel.js</file>
-        <file>resources/markdown.css</file>
         <file>utils/marked/marked.min.js</file>
         <file>utils/highlightjs/highlight.pack.js</file>
         <file>utils/highlightjs/styles/androidstudio.css</file>
@@ -99,5 +98,6 @@
         <file>resources/icons/float.svg</file>
         <file>resources/docs/shortcuts_en.md</file>
         <file>resources/docs/shortcuts_zh.md</file>
+        <file>resources/styles/default.css</file>
     </qresource>
 </RCC>