Browse Source

[function] Support to remove header sequence when disable it (#243)

* [function] Support to remove header sequence when disable it

spec:
In edit mode:
- when click icon to enable auto sequence, add sequence immediately
- when click icon to disable auto sequence, remove already added sequence

In preview/read mode:
- auto sequence icon should be unchecked and disabled

For readonly file, always disable the auto sequence icon.

* [bugfix] Do not let auto sequence ruin the undo history

All the header sequence auto-update should be treated as one edit action.
So that user can undo auto-update by pressing undo twice.
(One undo for the auto-update change, and one for the original header change)

* Refactor and reformat according to PR feedback
Xianzhong Wang 7 years ago
parent
commit
5eb8c4d224
4 changed files with 47 additions and 13 deletions
  1. 4 2
      src/vmainwindow.cpp
  2. 36 11
      src/vmdeditor.cpp
  3. 4 0
      src/vmdeditor.h
  4. 3 0
      src/vmdtab.cpp

+ 4 - 2
src/vmainwindow.cpp

@@ -1903,9 +1903,11 @@ void VMainWindow::updateActionsStateFromTab(const VEditTab *p_tab)
     setActionsEnabled(m_editToolBar, file && editMode);
 
     // Handle heading sequence act independently.
-    m_headingSequenceAct->setEnabled(isHeadingSequenceApplicable());
+    m_headingSequenceAct->setEnabled(editMode && file->isModifiable()
+                                     && isHeadingSequenceApplicable());
     const VMdTab *mdTab = dynamic_cast<const VMdTab *>(p_tab);
-    m_headingSequenceAct->setChecked(mdTab && mdTab->isHeadingSequenceEnabled());
+    m_headingSequenceAct->setChecked(mdTab && editMode && file->isModifiable()
+                                     && mdTab->isHeadingSequenceEnabled());
 
     // Find/Replace
     m_findReplaceAct->setEnabled(file);

+ 36 - 11
src/vmdeditor.cpp

@@ -425,7 +425,8 @@ static QString headerSequenceStr(const QVector<int> &p_sequence)
     return res;
 }
 
-static void insertSequenceToHeader(QTextBlock p_block,
+static void insertSequenceToHeader(QTextCursor& p_cursor,
+                                   QTextBlock p_block,
                                    QRegExp &p_reg,
                                    QRegExp &p_preReg,
                                    const QString &p_seq)
@@ -446,20 +447,24 @@ static void insertSequenceToHeader(QTextBlock p_block,
 
     Q_ASSERT(start <= end);
 
-    QTextCursor cursor(p_block);
-    cursor.setPosition(p_block.position() + start);
+    p_cursor.setPosition(p_block.position() + start);
     if (start != end) {
-        cursor.setPosition(p_block.position() + end, QTextCursor::KeepAnchor);
+        p_cursor.setPosition(p_block.position() + end, QTextCursor::KeepAnchor);
     }
 
     if (p_seq.isEmpty()) {
-        cursor.removeSelectedText();
+        p_cursor.removeSelectedText();
     } else {
-        cursor.insertText(p_seq + ' ');
+        p_cursor.insertText(p_seq + ' ');
     }
 }
 
-void VMdEditor::updateHeaders(const QVector<VElementRegion> &p_headerRegions)
+void VMdEditor::updateHeaderSequenceByConfigChange()
+{
+    updateHeadersHelper(m_mdHighlighter->getHeaderRegions(), true);
+}
+
+void VMdEditor::updateHeadersHelper(const QVector<VElementRegion> &p_headerRegions, bool p_configChanged)
 {
     QTextDocument *doc = document();
 
@@ -520,6 +525,14 @@ void VMdEditor::updateHeaders(const QVector<VElementRegion> &p_headerRegions)
     QVector<int> seqs(7, 0);
     QRegExp preReg(VUtils::c_headerPrefixRegExp);
     int curLevel = baseLevel - 1;
+    QTextCursor cursor = textCursorW();
+
+    int blockNo = cursor.block().blockNumber();
+    int posToBlockEnd = cursor.block().length() - cursor.positionInBlock();
+
+    if(autoSequence || p_configChanged) {
+        cursor.beginEditBlock();
+    }
     for (int i = 0; i < headers.size(); ++i) {
         VTableOfContentItem &item = headers[i];
         while (item.m_level > curLevel + 1) {
@@ -530,7 +543,7 @@ void VMdEditor::updateHeaders(const QVector<VElementRegion> &p_headerRegions)
                                                  curLevel,
                                                  -1,
                                                  m_headers.size()));
-            if (autoSequence) {
+            if (autoSequence || p_configChanged) {
                 addHeaderSequence(seqs, curLevel, headingSequenceBaseLevel);
             }
         }
@@ -538,25 +551,37 @@ void VMdEditor::updateHeaders(const QVector<VElementRegion> &p_headerRegions)
         item.m_index = m_headers.size();
         m_headers.append(item);
         curLevel = item.m_level;
-        if (autoSequence) {
+        if (autoSequence || p_configChanged) {
             addHeaderSequence(seqs, item.m_level, headingSequenceBaseLevel);
 
-            QString seqStr = headerSequenceStr(seqs);
+            QString seqStr = autoSequence ? headerSequenceStr(seqs) : "";
             if (headerSequences[i] != seqStr) {
                 // Insert correct sequence.
-                insertSequenceToHeader(doc->findBlockByNumber(headerBlockNumbers[i]),
+                insertSequenceToHeader(cursor,
+                                       doc->findBlockByNumber(headerBlockNumbers[i]),
                                        headerReg,
                                        preReg,
                                        seqStr);
             }
         }
     }
+    if (autoSequence || p_configChanged) {
+        QTextBlock block = doc->findBlockByNumber(blockNo);
+        cursor.setPosition(block.position() + block.length() - posToBlockEnd);
+        cursor.endEditBlock();
+        setTextCursorW(cursor);
+    }
 
     emit headersChanged(m_headers);
 
     updateCurrentHeader();
 }
 
+void VMdEditor::updateHeaders(const QVector<VElementRegion> &p_headerRegions)
+{
+    updateHeadersHelper(p_headerRegions, false);
+}
+
 void VMdEditor::updateCurrentHeader()
 {
     emit currentHeaderChanged(textCursor().block().blockNumber());

+ 4 - 0
src/vmdeditor.h

@@ -76,6 +76,8 @@ public:
 
     VPreviewManager *getPreviewManager() const;
 
+    void updateHeaderSequenceByConfigChange();
+
 public slots:
     bool jumpTitle(bool p_forward, int p_relativeLevel, int p_repeat) Q_DECL_OVERRIDE;
 
@@ -228,6 +230,8 @@ private slots:
     void handleCopyAsAction(QAction *p_act);
 
 private:
+    void updateHeadersHelper(const QVector<VElementRegion> &p_headerRegions, bool p_configChanged);
+
     // Update the config of VTextEdit according to global configurations.
     void updateTextEditConfig();
 

+ 3 - 0
src/vmdtab.cpp

@@ -911,6 +911,9 @@ void VMdTab::enableHeadingSequence(bool p_enabled)
     if (m_editor) {
         VEditConfig &config = m_editor->getConfig();
         config.m_enableHeadingSequence = m_enableHeadingSequence;
+        if (isEditMode()) {
+            m_editor->updateHeaderSequenceByConfigChange();
+        }
     }
 }