diff --git a/src/dialog/vdirinfodialog.h b/src/dialog/vdirinfodialog.h index 5078b9cc..7e477e57 100644 --- a/src/dialog/vdirinfodialog.h +++ b/src/dialog/vdirinfodialog.h @@ -36,7 +36,7 @@ private: QString title; QString info; - VDirectory *m_parentDirectory; const VDirectory *m_directory; + VDirectory *m_parentDirectory; }; #endif // VDIRINFODIALOG_H diff --git a/src/dialog/vnewfiledialog.cpp b/src/dialog/vnewfiledialog.cpp index 69009ff7..5b52fffc 100644 --- a/src/dialog/vnewfiledialog.cpp +++ b/src/dialog/vnewfiledialog.cpp @@ -43,7 +43,7 @@ void VNewFileDialog::setupUI() QFormLayout *topLayout = new QFormLayout(); topLayout->addRow(nameLabel, nameEdit); - topLayout->addRow("", m_insertTitleCB); + topLayout->addWidget(m_insertTitleCB); m_warnLabel = new QLabel(); m_warnLabel->setWordWrap(true); diff --git a/src/dialog/vsettingsdialog.cpp b/src/dialog/vsettingsdialog.cpp index 188e614d..efedb7b6 100644 --- a/src/dialog/vsettingsdialog.cpp +++ b/src/dialog/vsettingsdialog.cpp @@ -171,7 +171,7 @@ VGeneralTab::VGeneralTab(QWidget *p_parent) langLabel->setToolTip(m_langCombo->toolTip()); // System tray checkbox. - m_systemTray = new QCheckBox(this); + m_systemTray = new QCheckBox(tr("System tray"), this); m_systemTray->setToolTip(tr("Minimized to the system tray after closing VNote" " (not supported in macOS)")); #if defined(Q_OS_MACOS) || defined(Q_OS_MAC) @@ -179,12 +179,9 @@ VGeneralTab::VGeneralTab(QWidget *p_parent) m_systemTray->setEnabled(false); #endif - QLabel *trayLabel = new QLabel(tr("System tray:"), this); - trayLabel->setToolTip(m_systemTray->toolTip()); - QFormLayout *optionLayout = new QFormLayout(); optionLayout->addRow(langLabel, m_langCombo); - optionLayout->addRow(trayLabel, m_systemTray); + optionLayout->addRow(m_systemTray); QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addLayout(optionLayout); @@ -271,24 +268,6 @@ VReadEditTab::VReadEditTab(QWidget *p_parent) m_readBox = new QGroupBox(tr("Read Mode (For Markdown Only)")); m_editBox = new QGroupBox(tr("Edit Mode")); - // Web Zoom Factor. - m_customWebZoom = new QCheckBox(tr("Custom Web zoom factor"), this); - m_customWebZoom->setToolTip(tr("Set the zoom factor of the Web page when reading")); - connect(m_customWebZoom, &QCheckBox::stateChanged, - this, &VReadEditTab::customWebZoomChanged); - m_webZoomFactorSpin = new QDoubleSpinBox(this); - m_webZoomFactorSpin->setMaximum(c_webZoomFactorMax); - m_webZoomFactorSpin->setMinimum(c_webZoomFactorMin); - m_webZoomFactorSpin->setSingleStep(0.25); - QHBoxLayout *zoomFactorLayout = new QHBoxLayout(); - zoomFactorLayout->addWidget(m_customWebZoom); - zoomFactorLayout->addWidget(m_webZoomFactorSpin); - - QFormLayout *readLayout = new QFormLayout(); - readLayout->addRow(zoomFactorLayout); - - m_readBox->setLayout(readLayout); - QVBoxLayout *mainLayout = new QVBoxLayout(); mainLayout->addWidget(m_readBox); mainLayout->addWidget(m_editBox); @@ -297,55 +276,14 @@ VReadEditTab::VReadEditTab(QWidget *p_parent) bool VReadEditTab::loadConfiguration() { - if (!loadWebZoomFactor()) { - return false; - } - return true; } bool VReadEditTab::saveConfiguration() { - if (!saveWebZoomFactor()) { - return false; - } - return true; } -bool VReadEditTab::loadWebZoomFactor() -{ - qreal factor = g_config->getWebZoomFactor(); - bool customFactor = g_config->isCustomWebZoomFactor(); - if (customFactor) { - if (factor < c_webZoomFactorMin || factor > c_webZoomFactorMax) { - factor = 1; - } - m_customWebZoom->setChecked(true); - m_webZoomFactorSpin->setValue(factor); - } else { - m_customWebZoom->setChecked(false); - m_webZoomFactorSpin->setValue(factor); - m_webZoomFactorSpin->setEnabled(false); - } - return true; -} - -bool VReadEditTab::saveWebZoomFactor() -{ - if (m_customWebZoom->isChecked()) { - g_config->setWebZoomFactor(m_webZoomFactorSpin->value()); - } else { - g_config->setWebZoomFactor(-1); - } - return true; -} - -void VReadEditTab::customWebZoomChanged(int p_state) -{ - m_webZoomFactorSpin->setEnabled(p_state == Qt::Checked); -} - VNoteManagementTab::VNoteManagementTab(QWidget *p_parent) : QWidget(p_parent) { @@ -509,15 +447,40 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent) openModeLabel->setToolTip(m_openModeCombo->toolTip()); // Heading sequence. - m_headingSequence = new QCheckBox(); + m_headingSequence = new QCheckBox(tr("Heading sequence")); m_headingSequence->setToolTip(tr("Enable auto sequence for all headings (in the form like 1.2.3.4.)")); - QLabel *headingSequenceLabel = new QLabel(tr("Heading sequence:")); - headingSequenceLabel->setToolTip(m_headingSequence->toolTip()); + // Web Zoom Factor. + m_customWebZoom = new QCheckBox(tr("Custom Web zoom factor"), this); + m_customWebZoom->setToolTip(tr("Set the zoom factor of the Web page when reading")); + connect(m_customWebZoom, &QCheckBox::stateChanged, + this, [this](int p_state){ + this->m_webZoomFactorSpin->setEnabled(p_state == Qt::Checked); + }); + + m_webZoomFactorSpin = new QDoubleSpinBox(this); + m_webZoomFactorSpin->setMaximum(c_webZoomFactorMax); + m_webZoomFactorSpin->setMinimum(c_webZoomFactorMin); + m_webZoomFactorSpin->setSingleStep(0.25); + QHBoxLayout *zoomFactorLayout = new QHBoxLayout(); + zoomFactorLayout->addWidget(m_customWebZoom); + zoomFactorLayout->addWidget(m_webZoomFactorSpin); + + // Color column. + m_colorColumnEdit = new QLineEdit(); + m_colorColumnEdit->setToolTip(tr("Specify the screen column in fenced code block " + "which will be highlighted")); + QValidator *validator = new QRegExpValidator(QRegExp("\\d+"), this); + m_colorColumnEdit->setValidator(validator); + + QLabel *colorColumnLabel = new QLabel(tr("Color column:")); + colorColumnLabel->setToolTip(m_colorColumnEdit->toolTip()); QFormLayout *mainLayout = new QFormLayout(); mainLayout->addRow(openModeLabel, m_openModeCombo); - mainLayout->addRow(headingSequenceLabel, m_headingSequence); + mainLayout->addRow(m_headingSequence); + mainLayout->addRow(zoomFactorLayout); + mainLayout->addRow(colorColumnLabel, m_colorColumnEdit); setLayout(mainLayout); } @@ -532,6 +495,14 @@ bool VMarkdownTab::loadConfiguration() return false; } + if (!loadWebZoomFactor()) { + return false; + } + + if (!loadColorColumn()) { + return false; + } + return true; } @@ -545,6 +516,14 @@ bool VMarkdownTab::saveConfiguration() return false; } + if (!saveWebZoomFactor()) { + return false; + } + + if (!saveColorColumn()) { + return false; + } + return true; } @@ -583,3 +562,52 @@ bool VMarkdownTab::saveHeadingSequence() g_config->setEnableHeadingSequence(m_headingSequence->isChecked()); return true; } + +bool VMarkdownTab::loadWebZoomFactor() +{ + qreal factor = g_config->getWebZoomFactor(); + bool customFactor = g_config->isCustomWebZoomFactor(); + if (customFactor) { + if (factor < c_webZoomFactorMin || factor > c_webZoomFactorMax) { + factor = 1; + } + m_customWebZoom->setChecked(true); + m_webZoomFactorSpin->setValue(factor); + } else { + m_customWebZoom->setChecked(false); + m_webZoomFactorSpin->setValue(factor); + m_webZoomFactorSpin->setEnabled(false); + } + + return true; +} + +bool VMarkdownTab::saveWebZoomFactor() +{ + if (m_customWebZoom->isChecked()) { + g_config->setWebZoomFactor(m_webZoomFactorSpin->value()); + } else { + g_config->setWebZoomFactor(-1); + } + + return true; +} + +bool VMarkdownTab::loadColorColumn() +{ + int colorColumn = g_config->getColorColumn(); + m_colorColumnEdit->setText(QString::number(colorColumn <= 0 ? 0 : colorColumn)); + return true; +} + +bool VMarkdownTab::saveColorColumn() +{ + bool ok = false; + int colorColumn = m_colorColumnEdit->text().toInt(&ok); + if (ok && colorColumn >= 0) { + g_config->setColorColumn(colorColumn); + } + + return true; +} + diff --git a/src/dialog/vsettingsdialog.h b/src/dialog/vsettingsdialog.h index c0ac1bd5..0783e7ba 100644 --- a/src/dialog/vsettingsdialog.h +++ b/src/dialog/vsettingsdialog.h @@ -48,17 +48,6 @@ public: QGroupBox *m_readBox; QGroupBox *m_editBox; - - // Web zoom factor. - QCheckBox *m_customWebZoom; - QDoubleSpinBox *m_webZoomFactorSpin; - -private slots: - void customWebZoomChanged(int p_state); - -private: - bool loadWebZoomFactor(); - bool saveWebZoomFactor(); }; class VNoteManagementTab : public QWidget @@ -106,12 +95,25 @@ public: // Whether enable heading sequence. QCheckBox *m_headingSequence; + // Web zoom factor. + QCheckBox *m_customWebZoom; + QDoubleSpinBox *m_webZoomFactorSpin; + + // Color column in code block. + QLineEdit *m_colorColumnEdit; + private: bool loadOpenMode(); bool saveOpenMode(); bool loadHeadingSequence(); bool saveHeadingSequence(); + + bool loadWebZoomFactor(); + bool saveWebZoomFactor(); + + bool loadColorColumn(); + bool saveColorColumn(); }; class VSettingsDialog : public QDialog diff --git a/src/hgmarkdownhighlighter.cpp b/src/hgmarkdownhighlighter.cpp index 298223db..3079e570 100644 --- a/src/hgmarkdownhighlighter.cpp +++ b/src/hgmarkdownhighlighter.cpp @@ -48,6 +48,10 @@ HGMarkdownHighlighter::HGMarkdownHighlighter(const QVector &s } } + m_colorColumnFormat = codeBlockFormat; + m_colorColumnFormat.setForeground(QColor(g_config->getEditorColorColumnFg())); + m_colorColumnFormat.setBackground(QColor(g_config->getEditorColorColumnBg())); + resizeBuffer(initCapacity); document = parent; @@ -184,6 +188,8 @@ void HGMarkdownHighlighter::highlightBlock(const QString &text) } } + highlightCodeBlockColorColumn(text); + exit: highlightChanged(); } @@ -402,6 +408,20 @@ void HGMarkdownHighlighter::highlightCodeBlock(const QString &text) setFormat(index, length, codeBlockFormat); } +void HGMarkdownHighlighter::highlightCodeBlockColorColumn(const QString &p_text) +{ + int cc = g_config->getColorColumn(); + if (cc <= 0 || currentBlockState() != HighlightBlockState::CodeBlock) { + return; + } + + if (p_text.size() < cc) { + return; + } + + setFormat(cc - 1, 1, m_colorColumnFormat); +} + void HGMarkdownHighlighter::highlightLinkWithSpacesInURL(const QString &p_text) { if (currentBlockState() == HighlightBlockState::CodeBlock) { diff --git a/src/hgmarkdownhighlighter.h b/src/hgmarkdownhighlighter.h index 99f6b5dd..53940b65 100644 --- a/src/hgmarkdownhighlighter.h +++ b/src/hgmarkdownhighlighter.h @@ -163,6 +163,7 @@ private: QTextCharFormat codeBlockFormat; QTextCharFormat m_linkFormat; QTextCharFormat m_imageFormat; + QTextCharFormat m_colorColumnFormat; QTextDocument *document; QVector highlightingStyles; @@ -241,6 +242,9 @@ private: // Set the user data of currentBlock(). void updateBlockUserData(int p_blockNum, const QString &p_text); + + // Highlight color column in code block. + void highlightCodeBlockColorColumn(const QString &p_text); }; inline const QMap &HGMarkdownHighlighter::getPotentialPreviewBlocks() const diff --git a/src/resources/styles/default.mdhl b/src/resources/styles/default.mdhl index 5a6da914..89387a73 100644 --- a/src/resources/styles/default.mdhl +++ b/src/resources/styles/default.mdhl @@ -18,14 +18,17 @@ trailing-space: a8a8a8 # [VNote] Style for line number line-number-background: bdbdbd line-number-foreground: 424242 -# [VNote] style for selected word highlight +# [VNote] Style for selected word highlight selected-word-background: dfdf00 -# [VNote] style for searched word highlight +# [VNote] Style for searched word highlight searched-word-background: 4db6ac -# [VNote] style for searched word under cursor highlight +# [VNote] Style for searched word under cursor highlight searched-word-cursor-background: 66bb6a -# [VNote] style for incremental searched word highlight +# [VNote] Style for incremental searched word highlight incremental-searched-word-background: ce93d8 +# [VNote] Style for color column in fenced code block +color-column-background: dd0000 +color-column-foreground: ffff00 editor-selection foreground: eeeeee diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 03e0a214..1a5c98a6 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -86,6 +86,10 @@ note_open_mode=0 ; Whether auto generate heading sequence enable_heading_sequence=false +; Style the xth column in fenced code block +; 0 - no color column +color_column=0 + [session] tools_dock_checked=true diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index f88be7ad..3c0b6f5e 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -177,6 +177,8 @@ void VConfigManager::initialize() m_enableHeadingSequence = getConfigFromSettings("global", "enable_heading_sequence").toBool(); + + m_colorColumn = getConfigFromSettings("global", "color_column").toInt(); } void VConfigManager::readPredefinedColorsFromSettings() @@ -369,6 +371,8 @@ void VConfigManager::updateMarkdownEditStyle() static const QString defaultIncrementalSearchedWordBg = "#CE93D8"; static const QString defaultLineNumberBg = "#BDBDBD"; static const QString defaultLineNumberFg = "#424242"; + static const QString defaultColorColumnBg = "#DD0000"; + static const QString defaultColorColumnFg = "#FFFF00"; // Read style file .mdhl QString file(getEditorStyleUrl()); @@ -431,6 +435,8 @@ void VConfigManager::updateMarkdownEditStyle() m_editorIncrementalSearchedWordBg = defaultIncrementalSearchedWordBg; m_editorLineNumberBg = defaultLineNumberBg; m_editorLineNumberFg = defaultLineNumberFg; + m_editorColorColumnBg = defaultColorColumnBg; + m_editorColorColumnFg = defaultColorColumnFg; auto editorIt = styles.find("editor"); if (editorIt != styles.end()) { auto it = editorIt->find("trailing-space"); @@ -467,6 +473,16 @@ void VConfigManager::updateMarkdownEditStyle() if (it != editorIt->end()) { m_editorIncrementalSearchedWordBg = "#" + *it; } + + it = editorIt->find("color-column-background"); + if (it != editorIt->end()) { + m_editorColorColumnBg = "#" + *it; + } + + it = editorIt->find("color-column-foreground"); + if (it != editorIt->end()) { + m_editorColorColumnFg = "#" + *it; + } } } diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 87ebdf01..b333df10 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -235,6 +235,12 @@ public: bool getEnableHeadingSequence() const; void setEnableHeadingSequence(bool p_enabled); + int getColorColumn() const; + void setColorColumn(int p_column); + + const QString &getEditorColorColumnBg() const; + const QString &getEditorColorColumnFg() const; + // Return the configured key sequence of @p_operation. // Return empty if there is no corresponding config. QString getShortcutKeySequence(const QString &p_operation) const; @@ -475,6 +481,15 @@ private: // Whether auto genearte heading sequence. bool m_enableHeadingSequence; + // The column to style in code block. + int m_colorColumn; + + // The background color of the color column. + QString m_editorColorColumnBg; + + // The foreground color of the color column. + QString m_editorColorColumnFg; + // The name of the config file in each directory, obsolete. // Use c_dirConfigFile instead. static const QString c_obsoleteDirConfigFile; @@ -1226,4 +1241,29 @@ inline void VConfigManager::setEnableHeadingSequence(bool p_enabled) m_enableHeadingSequence); } +inline int VConfigManager::getColorColumn() const +{ + return m_colorColumn; +} + +inline void VConfigManager::setColorColumn(int p_column) +{ + if (m_colorColumn == p_column) { + return; + } + + m_colorColumn = p_column; + setConfigToSettings("global", "color_column", m_colorColumn); +} + +inline const QString &VConfigManager::getEditorColorColumnBg() const +{ + return m_editorColorColumnBg; +} + +inline const QString &VConfigManager::getEditorColorColumnFg() const +{ + return m_editorColorColumnFg; +} + #endif // VCONFIGMANAGER_H diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index ba58247d..c20c3046 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -730,20 +730,35 @@ void VMainWindow::initFileMenu() fileMenu->addAction(settingsAct); + QAction *editConfigAct = new QAction(tr("Edit Configuration File"), this); + editConfigAct->setToolTip(tr("View and edit configuration file of VNote (vnote.ini)")); + connect(editConfigAct, &QAction::triggered, + this, [this](){ +#if defined(Q_OS_MACOS) || defined(Q_OS_MAC) + // On macOS, it seems that we could not open that ini file directly. + QUrl url = QUrl::fromLocalFile(g_config->getConfigFolder()); +#else + QUrl url = QUrl::fromLocalFile(g_config->getConfigFilePath()); +#endif + QDesktopServices::openUrl(url); + }); + + fileMenu->addAction(editConfigAct); + QAction *customShortcutAct = new QAction(tr("Custom Shortcuts"), this); customShortcutAct->setToolTip(tr("Custom some standard shortcuts")); connect(customShortcutAct, &QAction::triggered, this, [this](){ int ret = VUtils::showMessage(QMessageBox::Information, - tr("Custom Shortcuts"), - tr("VNote supports customing some standard shorcuts by " - "editing user's configuration file (vnote.ini). Please " - "reference the shortcuts help documentation for more " - "information."), - tr("Click \"OK\" to custom shortcuts."), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok, - this); + tr("Custom Shortcuts"), + tr("VNote supports customing some standard shorcuts by " + "editing user's configuration file (vnote.ini). Please " + "reference the shortcuts help documentation for more " + "information."), + tr("Click \"OK\" to custom shortcuts."), + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Ok, + this); if (ret == QMessageBox::Ok) { #if defined(Q_OS_MACOS) || defined(Q_OS_MAC) diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp index 9970a89a..e0f1b989 100644 --- a/src/vmdedit.cpp +++ b/src/vmdedit.cpp @@ -355,7 +355,7 @@ static QString headerSequenceStr(const QVector &p_sequence) return res; } -static void insertSequenceToHeader(QTextBlock &p_block, +static void insertSequenceToHeader(QTextBlock p_block, QRegExp &p_reg, QRegExp &p_preReg, const QString &p_seq) diff --git a/src/vstyleparser.cpp b/src/vstyleparser.cpp index c15c40fb..5dce82f9 100644 --- a/src/vstyleparser.cpp +++ b/src/vstyleparser.cpp @@ -234,7 +234,8 @@ void VStyleParser::fetchMarkdownEditorStyles(QPalette &palette, QFont &font, } // Get custom styles: - // trailing-space, line-number-background, line-number-foreground + // trailing-space, line-number-background, line-number-foreground, + // color-column-background, color-column-foreground case pmh_attr_type_other: { QString attrName(editorStyles->name);