diff --git a/src/dialog/vsettingsdialog.cpp b/src/dialog/vsettingsdialog.cpp index efedb7b6..4caa4add 100644 --- a/src/dialog/vsettingsdialog.cpp +++ b/src/dialog/vsettingsdialog.cpp @@ -51,6 +51,8 @@ VSettingsDialog::VSettingsDialog(QWidget *p_parent) m_tabs->setCurrentWidget(m_tabs->widget(idx)); }); + m_tabList->setCurrentRow(0); + loadConfiguration(); } @@ -449,19 +451,34 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent) // Heading sequence. 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.)")); + m_headingSequenceCombo = new QComboBox(); + m_headingSequenceCombo->setToolTip(tr("Base level to start heading sequence")); + m_headingSequenceCombo->addItem(tr("1"), 1); + m_headingSequenceCombo->addItem(tr("2"), 2); + m_headingSequenceCombo->addItem(tr("3"), 3); + m_headingSequenceCombo->addItem(tr("4"), 4); + m_headingSequenceCombo->addItem(tr("5"), 5); + m_headingSequenceCombo->addItem(tr("6"), 6); + m_headingSequenceCombo->setEnabled(false); + connect(m_headingSequence, &QCheckBox::stateChanged, + this, [this](int p_state){ + this->m_headingSequenceCombo->setEnabled(p_state == Qt::Checked); + }); + QHBoxLayout *headingSequenceLayout = new QHBoxLayout(); + headingSequenceLayout->addWidget(m_headingSequence); + headingSequenceLayout->addWidget(m_headingSequenceCombo); // 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); + connect(m_customWebZoom, &QCheckBox::stateChanged, + this, [this](int p_state){ + this->m_webZoomFactorSpin->setEnabled(p_state == Qt::Checked); + }); QHBoxLayout *zoomFactorLayout = new QHBoxLayout(); zoomFactorLayout->addWidget(m_customWebZoom); zoomFactorLayout->addWidget(m_webZoomFactorSpin); @@ -478,7 +495,7 @@ VMarkdownTab::VMarkdownTab(QWidget *p_parent) QFormLayout *mainLayout = new QFormLayout(); mainLayout->addRow(openModeLabel, m_openModeCombo); - mainLayout->addRow(m_headingSequence); + mainLayout->addRow(headingSequenceLayout); mainLayout->addRow(zoomFactorLayout); mainLayout->addRow(colorColumnLabel, m_colorColumnEdit); @@ -553,13 +570,20 @@ bool VMarkdownTab::saveOpenMode() bool VMarkdownTab::loadHeadingSequence() { bool enabled = g_config->getEnableHeadingSequence(); + int level = g_config->getHeadingSequenceBaseLevel(); + if (level < 1 || level > 6) { + level = 1; + } + m_headingSequence->setChecked(enabled); + m_headingSequenceCombo->setCurrentIndex(level - 1); return true; } bool VMarkdownTab::saveHeadingSequence() { g_config->setEnableHeadingSequence(m_headingSequence->isChecked()); + g_config->setHeadingSequenceBaseLevel(m_headingSequenceCombo->currentData().toInt()); return true; } diff --git a/src/dialog/vsettingsdialog.h b/src/dialog/vsettingsdialog.h index 0783e7ba..6dbf7c30 100644 --- a/src/dialog/vsettingsdialog.h +++ b/src/dialog/vsettingsdialog.h @@ -94,6 +94,7 @@ public: // Whether enable heading sequence. QCheckBox *m_headingSequence; + QComboBox *m_headingSequenceCombo; // Web zoom factor. QCheckBox *m_customWebZoom; diff --git a/src/hgmarkdownhighlighter.h b/src/hgmarkdownhighlighter.h index 2ab29ce9..5e28ecff 100644 --- a/src/hgmarkdownhighlighter.h +++ b/src/hgmarkdownhighlighter.h @@ -122,6 +122,8 @@ public: const QMap &getPotentialPreviewBlocks() const; + const QVector &getHeaderRegions() const; + signals: void highlightCompleted(); @@ -239,4 +241,9 @@ inline const QMap &HGMarkdownHighlighter::getPotentialPreviewBlocks() return m_potentialPreviewBlocks; } +inline const QVector &HGMarkdownHighlighter::getHeaderRegions() const +{ + return m_headerRegions; +} + #endif diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 52defeb4..5b621825 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -86,6 +86,9 @@ note_open_mode=0 ; Whether auto generate heading sequence enable_heading_sequence=false +; Heading sequence base level +heading_sequence_base_level=1 + ; Style the xth column in fenced code block ; 0 - no color column color_column=0 diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index 780868c1..a16be28a 100644 --- a/src/vconfigmanager.cpp +++ b/src/vconfigmanager.cpp @@ -178,6 +178,9 @@ void VConfigManager::initialize() m_enableHeadingSequence = getConfigFromSettings("global", "enable_heading_sequence").toBool(); + m_headingSequenceBaseLevel = getConfigFromSettings("global", + "heading_sequence_base_level").toInt(); + m_colorColumn = getConfigFromSettings("global", "color_column").toInt(); m_enableCodeBlockLineNumber = getConfigFromSettings("global", diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index f0e26b83..bd384695 100644 --- a/src/vconfigmanager.h +++ b/src/vconfigmanager.h @@ -235,6 +235,9 @@ public: bool getEnableHeadingSequence() const; void setEnableHeadingSequence(bool p_enabled); + int getHeadingSequenceBaseLevel() const; + void setHeadingSequenceBaseLevel(int p_level); + int getColorColumn() const; void setColorColumn(int p_column); @@ -486,6 +489,9 @@ private: // Whether auto genearte heading sequence. bool m_enableHeadingSequence; + // Heading sequence base level. + int m_headingSequenceBaseLevel; + // The column to style in code block. int m_colorColumn; @@ -1252,6 +1258,23 @@ inline void VConfigManager::setEnableHeadingSequence(bool p_enabled) m_enableHeadingSequence); } +inline int VConfigManager::getHeadingSequenceBaseLevel() const +{ + return m_headingSequenceBaseLevel; +} + +inline void VConfigManager::setHeadingSequenceBaseLevel(int p_level) +{ + if (m_headingSequenceBaseLevel == p_level) { + return; + } + + m_headingSequenceBaseLevel = p_level; + setConfigToSettings("global", + "heading_sequence_base_level", + m_headingSequenceBaseLevel); +} + inline int VConfigManager::getColorColumn() const { return m_colorColumn; diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp index e0f1b989..262e0966 100644 --- a/src/vmdedit.cpp +++ b/src/vmdedit.cpp @@ -109,7 +109,7 @@ void VMdEdit::beginEdit() setReadOnly(false); } - m_mdHighlighter->updateHighlight(); + updateOutline(m_mdHighlighter->getHeaderRegions()); } void VMdEdit::endEdit() @@ -330,9 +330,14 @@ void VMdEdit::updateCurHeader() emit curHeaderChanged(VAnchor(m_file, "", m_headers[idx].lineNumber, m_headers[idx].index)); } -static void addHeaderSequence(QVector &p_sequence, int p_level) +static void addHeaderSequence(QVector &p_sequence, int p_level, int p_baseLevel) { Q_ASSERT(p_level >= 1 && p_level < p_sequence.size()); + if (p_level < p_baseLevel) { + p_sequence.fill(0); + return; + } + ++p_sequence[p_level]; for (int i = p_level + 1; i < p_sequence.size(); ++i) { p_sequence[i] = 0; @@ -382,7 +387,11 @@ static void insertSequenceToHeader(QTextBlock p_block, cursor.setPosition(p_block.position() + end, QTextCursor::KeepAnchor); } - cursor.insertText(p_seq + ' '); + if (p_seq.isEmpty()) { + cursor.removeSelectedText(); + } else { + cursor.insertText(p_seq + ' '); + } } void VMdEdit::updateOutline(const QVector &p_headerRegions) @@ -434,6 +443,11 @@ void VMdEdit::updateOutline(const QVector &p_headerRegions) m_headers.clear(); bool autoSequence = g_config->getEnableHeadingSequence() && !isReadOnly(); + int headingSequenceBaseLevel = g_config->getHeadingSequenceBaseLevel(); + if (headingSequenceBaseLevel < 1 || headingSequenceBaseLevel > 6) { + headingSequenceBaseLevel = 1; + } + QVector seqs(7, 0); QRegExp preReg(VUtils::c_headerPrefixRegExp); int curLevel = baseLevel - 1; @@ -445,7 +459,7 @@ void VMdEdit::updateOutline(const QVector &p_headerRegions) // Insert empty level which is an invalid header. m_headers.append(VHeader(curLevel, c_emptyHeaderName, "", -1, m_headers.size())); if (autoSequence) { - addHeaderSequence(seqs, curLevel); + addHeaderSequence(seqs, curLevel, headingSequenceBaseLevel); } } @@ -453,7 +467,7 @@ void VMdEdit::updateOutline(const QVector &p_headerRegions) m_headers.append(item); curLevel = item.level; if (autoSequence) { - addHeaderSequence(seqs, item.level); + addHeaderSequence(seqs, item.level, headingSequenceBaseLevel); QString seqStr = headerSequenceStr(seqs); if (headerSequences[i] != seqStr) { @@ -768,5 +782,7 @@ void VMdEdit::finishOneAsyncJob(int p_idx) setModified(false); m_freshEdit = false; emit statusChanged(); + + updateOutline(m_mdHighlighter->getHeaderRegions()); } }