diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 7dd4f752..49dda2d3 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -7,3 +7,15 @@ template_css_url=qrc:/resources/markdown.css current_notebook=0 tab_stop_width=4 is_expand_tab=1 +current_background_color=System + +[predefined_colors] +1\name=White +1\rgb=EEEEEE +2\name=Green +2\rgb=CCE8CF +3\name=Wheat2 +3\rgb=EED8AE +4\name=LightGrey +4\rgb=D3D3D3 +size=4 diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index d56185aa..a1f2a8a7 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -4,7 +4,6 @@ VUtils::VUtils() { - } QString VUtils::readFileFromDisk(const QString &filePath) @@ -33,3 +32,27 @@ bool VUtils::writeFileToDisk(const QString &filePath, const QString &text) qDebug() << "write file content:" << filePath; return true; } + +QRgb VUtils::QRgbFromString(const QString &str) +{ + Q_ASSERT(str.length() == 6); + QString rStr = str.left(2); + QString gStr = str.mid(2, 2); + QString bStr = str.right(2); + + qDebug() << rStr << gStr << bStr; + + bool ok, ret = true; + int red = rStr.toInt(&ok, 16); + ret = ret && ok; + int green = gStr.toInt(&ok, 16); + ret = ret && ok; + int blue = bStr.toInt(&ok, 16); + ret = ret && ok; + + if (ret) { + return qRgb(red, green, blue); + } + qWarning() << "error: fail to construct QRgb from string" << str; + return QRgb(); +} diff --git a/src/utils/vutils.h b/src/utils/vutils.h index 307019fd..be4fef65 100644 --- a/src/utils/vutils.h +++ b/src/utils/vutils.h @@ -2,6 +2,8 @@ #define VUTILS_H #include +#include +#include "vconfigmanager.h" class VUtils { @@ -10,6 +12,8 @@ public: static QString readFileFromDisk(const QString &filePath); static bool writeFileToDisk(const QString &filePath, const QString &text); + // Transform FFFFFF string to QRgb + static QRgb QRgbFromString(const QString &str); }; #endif // VUTILS_H diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 35fb2b30..65c88830 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -53,12 +53,34 @@ void VConfigManager::initialize() tabStopWidth = getConfigFromSettings("global", "tab_stop_width").toInt(); isExpandTab = getConfigFromSettings("global", "is_expand_tab").toBool(); + readPredefinedColorsFromSettings(); + curBackgroundColor = getConfigFromSettings("global", "current_background_color").toString(); + customBackgroundColor = getConfigFromSettings("global", "custom_background_color").toString(); + + updatePaletteColor(); + // Update notebooks readNotebookFromSettings(); updateMarkdownEditStyle(); } +void VConfigManager::readPredefinedColorsFromSettings() +{ + predefinedColors.clear(); + int size = defaultSettings->beginReadArray("predefined_colors"); + for (int i = 0; i < size; ++i) { + defaultSettings->setArrayIndex(i); + VColor color; + color.name = defaultSettings->value("name").toString(); + color.rgb = defaultSettings->value("rgb").toString(); + predefinedColors.append(color); + } + defaultSettings->endArray(); + qDebug() << "read" << predefinedColors.size() + << "pre-defined colors from [predefined_colors] section"; +} + void VConfigManager::readNotebookFromSettings() { notebooks.clear(); @@ -183,3 +205,29 @@ void VConfigManager::updateMarkdownEditStyle() mdEditFont = baseEditFont; parser.fetchMarkdownEditorStyles(mdEditPalette, mdEditFont); } + +void VConfigManager::updatePaletteColor() +{ + QString rgb; + if (curBackgroundColor == "Custom") { + rgb = customBackgroundColor; + } else if (curBackgroundColor == "System") { + return; + } else { + for (int i = 0; i < predefinedColors.size(); ++i) { + if (predefinedColors[i].name == curBackgroundColor) { + rgb = predefinedColors[i].rgb; + break; + } + } + } + if (rgb.isEmpty()) { + return; + } + + baseEditPalette.setColor(QPalette::Base, + QColor(VUtils::QRgbFromString(rgb))); + + // Update markdown editor palette + updateMarkdownEditStyle(); +} diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index fb30fdf2..e32f46b6 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -13,11 +13,18 @@ class QJsonObject; class QString; -enum MarkdownConverterType { +enum MarkdownConverterType +{ Hoedown = 0, Marked }; +struct VColor +{ + QString name; + QString rgb; // 'FFFFFF', ithout '#' +}; + class VConfigManager { public: @@ -48,6 +55,7 @@ public: inline QString getTemplateCssUrl() const; inline QFont getBaseEditFont() const; + inline QPalette getBaseEditPalette() const; inline int getCurNotebookIndex() const; inline void setCurNotebookIndex(int index); @@ -67,12 +75,23 @@ public: inline bool getIsExpandTab() const; inline void setIsExpandTab(bool isExpandTab); + inline const QVector &getPredefinedColors() const; + + inline const QString &getCurBackgroundColor() const; + inline void setCurBackgroundColor(const QString &colorName); + + inline const QString &getCustomBackgroundColor() const; + inline void setCustomBackgroundColor(const QString &colorRgb); + private: void updateMarkdownEditStyle(); QVariant getConfigFromSettings(const QString §ion, const QString &key); void setConfigToSettings(const QString §ion, const QString &key, const QVariant &value); void readNotebookFromSettings(); void writeNotebookToSettings(); + void readPredefinedColorsFromSettings(); + // Update baseEditPalette according to curBackgroundColor + void updatePaletteColor(); QFont baseEditFont; QPalette baseEditPalette; @@ -96,6 +115,11 @@ private: // Expand tab to @tabStopWidth spaces bool isExpandTab; + // App defined color + QVector predefinedColors; + QString curBackgroundColor; + QString customBackgroundColor; + // The name of the config file in each directory static const QString dirConfigFileName; // The name of the default configuration file @@ -142,6 +166,11 @@ inline QFont VConfigManager::getBaseEditFont() const return baseEditFont; } +inline QPalette VConfigManager::getBaseEditPalette() const +{ + return baseEditPalette; +} + inline int VConfigManager::getCurNotebookIndex() const { return curNotebookIndex; @@ -224,4 +253,41 @@ inline void VConfigManager::setIsExpandTab(bool isExpandTab) setConfigToSettings("global", "is_expand_tab", this->isExpandTab); } +inline const QVector& VConfigManager::getPredefinedColors() const +{ + return predefinedColors; +} + +inline const QString& VConfigManager::getCurBackgroundColor() const +{ + return curBackgroundColor; +} + +inline void VConfigManager::setCurBackgroundColor(const QString &colorName) +{ + if (curBackgroundColor == colorName) { + return; + } + curBackgroundColor = colorName; + setConfigToSettings("global", "current_background_color", + curBackgroundColor); + updatePaletteColor(); +} + +inline const QString& VConfigManager::getCustomBackgroundColor() const +{ + return customBackgroundColor; +} + +inline void VConfigManager::setCustomBackgroundColor(const QString &colorRgb) +{ + if (customBackgroundColor == colorRgb) { + return; + } + customBackgroundColor = colorRgb; + setConfigToSettings("global", "custom_background_color", + customBackgroundColor); + updatePaletteColor(); +} + #endif // VCONFIGMANAGER_H diff --git a/src/vedit.cpp b/src/vedit.cpp index e1bd3cd5..eeb8258d 100644 --- a/src/vedit.cpp +++ b/src/vedit.cpp @@ -10,17 +10,32 @@ VEdit::VEdit(VNoteFile *noteFile, QWidget *parent) : QTextEdit(parent), noteFile(noteFile), mdHighlighter(NULL) { if (noteFile->docType == DocType::Markdown) { - setPalette(vconfig.getMdEditPalette()); - setFont(vconfig.getMdEditFont()); setAcceptRichText(false); mdHighlighter = new HGMarkdownHighlighter(vconfig.getMdHighlightingStyles(), 500, document()); } else { - setFont(vconfig.getBaseEditFont()); setAutoFormatting(QTextEdit::AutoBulletList); } updateTabSettings(); + updateFontAndPalette(); +} + +void VEdit::updateFontAndPalette() +{ + switch (noteFile->docType) { + case DocType::Markdown: + setFont(vconfig.getMdEditFont()); + setPalette(vconfig.getMdEditPalette()); + break; + case DocType::Html: + setFont(vconfig.getBaseEditFont()); + setPalette(vconfig.getBaseEditPalette()); + break; + default: + qWarning() << "error: unknown doc type" << int(noteFile->docType); + return; + } } void VEdit::updateTabSettings() @@ -53,6 +68,7 @@ void VEdit::beginEdit() { setReadOnly(false); updateTabSettings(); + updateFontAndPalette(); switch (noteFile->docType) { case DocType::Html: setHtml(noteFile->content); diff --git a/src/vedit.h b/src/vedit.h index 86db918b..a5ebfa83 100644 --- a/src/vedit.h +++ b/src/vedit.h @@ -28,6 +28,7 @@ protected: private: void updateTabSettings(); + void updateFontAndPalette(); bool isExpandTab; QString tabSpaces; diff --git a/src/veditor.cpp b/src/veditor.cpp index 5e90889b..bee9ee08 100644 --- a/src/veditor.cpp +++ b/src/veditor.cpp @@ -56,6 +56,7 @@ void VEditor::setupUI() textBrowser = new QTextBrowser(); addWidget(textBrowser); textBrowser->setFont(vconfig.getBaseEditFont()); + textBrowser->setPalette(vconfig.getBaseEditPalette()); webPreviewer = NULL; break; default: @@ -86,6 +87,8 @@ void VEditor::showFileReadMode() switch (noteFile->docType) { case DocType::Html: textBrowser->setHtml(noteFile->content); + textBrowser->setFont(vconfig.getBaseEditFont()); + textBrowser->setPalette(vconfig.getBaseEditPalette()); setCurrentWidget(textBrowser); break; case DocType::Markdown: diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 2703937a..72251df7 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -7,6 +7,7 @@ #include "vconfigmanager.h" #include "dialog/vnewnotebookdialog.h" #include "dialog/vnotebookinfodialog.h" +#include "utils/vutils.h" extern VConfigManager vconfig; @@ -15,6 +16,7 @@ VMainWindow::VMainWindow(QWidget *parent) { // Must be called before those who uses VConfigManager vnote = new VNote(); + initPredefinedColorPixmaps(); setupUI(); initActions(); initToolBar(); @@ -205,6 +207,10 @@ void VMainWindow::initActions() eightSpaceTabAct->setData(8); connect(tabStopWidthAct, &QActionGroup::triggered, this, &VMainWindow::setTabStopWidth); + + backgroundColorAct = new QActionGroup(this); + connect(backgroundColorAct, &QActionGroup::triggered, + this, &VMainWindow::setEditorBackgroundColor); } void VMainWindow::initToolBar() @@ -253,6 +259,43 @@ void VMainWindow::initMenuBar() qWarning() << "error: unsupported tab stop width" << tabStopWidth << "in config"; } + QMenu *backgroundColorMenu = editMenu->addMenu(tr("&Background Color")); + // System background color + const QString &curBgColor = vconfig.getCurBackgroundColor(); + QAction *tmpAct = new QAction(tr("System"), backgroundColorAct); + tmpAct->setStatusTip(tr("Use system's background color configuration for editor")); + tmpAct->setCheckable(true); + tmpAct->setData("System"); + if (curBgColor == "System") { + tmpAct->setChecked(true); + } + backgroundColorMenu->addAction(tmpAct); + const QVector &bgColors = vconfig.getPredefinedColors(); + for (int i = 0; i < bgColors.size(); ++i) { + tmpAct = new QAction(bgColors[i].name, backgroundColorAct); + tmpAct->setStatusTip(tr("Set background color for editor")); + tmpAct->setCheckable(true); + tmpAct->setData(bgColors[i].name); + tmpAct->setIcon(QIcon(predefinedColorPixmaps[i])); + if (curBgColor == bgColors[i].name) { + tmpAct->setChecked(true); + } + + backgroundColorMenu->addAction(tmpAct); + } + // Custom background color + tmpAct = new QAction(tr("Custom"), backgroundColorAct); + tmpAct->setStatusTip(tr("Set customed background color for editor")); + tmpAct->setCheckable(true); + tmpAct->setData("Custom"); + if (!vconfig.getCustomBackgroundColor().isEmpty()) { + tmpAct->setIcon(QIcon(predefinedColorPixmaps.back())); + } + if (curBgColor == "Custom") { + tmpAct->setChecked(true); + } + backgroundColorMenu->addAction(tmpAct); + // Markdown Menu QMenu *converterMenu = markdownMenu->addMenu(tr("&Converter")); converterMenu->addAction(hoedownAct); @@ -485,3 +528,38 @@ void VMainWindow::setTabStopWidth(QAction *action) } vconfig.setTabStopWidth(action->data().toInt()); } + +void VMainWindow::setEditorBackgroundColor(QAction *action) +{ + if (!action) { + return; + } + // TODO: implement custom color logics + if (action->data().toString() == "Custom") { + return; + } + + vconfig.setCurBackgroundColor(action->data().toString()); +} + +void VMainWindow::initPredefinedColorPixmaps() +{ + const QVector &bgColors = vconfig.getPredefinedColors(); + predefinedColorPixmaps.clear(); + int size = 256; + for (int i = 0; i < bgColors.size(); ++i) { + // Generate QPixmap filled in this color + QColor color(VUtils::QRgbFromString(bgColors[i].rgb)); + QPixmap pixmap(size, size); + pixmap.fill(color); + predefinedColorPixmaps.append(pixmap); + } + + const QString &customBgColor = vconfig.getCustomBackgroundColor(); + if (!customBgColor.isEmpty()) { + QColor color(VUtils::QRgbFromString(customBgColor)); + QPixmap pixmap(size, size); + pixmap.fill(color); + predefinedColorPixmaps.append(pixmap); + } +} diff --git a/src/vmainwindow.h b/src/vmainwindow.h index d61f4e37..0d0b2852 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -42,6 +42,7 @@ private slots: void aboutMessage(); void changeExpandTab(bool checked); void setTabStopWidth(QAction *action); + void setEditorBackgroundColor(QAction *action); signals: void curNotebookChanged(const QString ¬ebookName); @@ -52,6 +53,7 @@ private: void initToolBar(); void initMenuBar(); bool isConflictWithExistingNotebooks(const QString &name); + void initPredefinedColorPixmaps(); // If true, comboBox changes will not trigger any signal out bool notebookComboMuted; @@ -86,6 +88,9 @@ private: QAction *twoSpaceTabAct; QAction *fourSpaceTabAct; QAction *eightSpaceTabAct; + QActionGroup *backgroundColorAct; + + QVector predefinedColorPixmaps; }; #endif // VMAINWINDOW_H