Browse Source

support custom line distance height by line_distance_height config

Le Tan 8 years ago
parent
commit
36a0d1dd7e
7 changed files with 116 additions and 4 deletions
  1. 3 0
      src/resources/vnote.ini
  2. 3 0
      src/vconfigmanager.cpp
  3. 10 0
      src/vconfigmanager.h
  4. 81 1
      src/vedit.cpp
  5. 12 1
      src/vedit.h
  6. 5 1
      src/vmdedit.cpp
  7. 2 1
      src/vtextblockdata.cpp

+ 3 - 0
src/resources/vnote.ini

@@ -73,6 +73,9 @@ markdown_suffix=md:markdown:mkd
 ; Markdown highlight timer interval (milliseconds)
 markdown_highlight_interval=400
 
+; Adds specified height between lines (in pixels)
+line_distance_height=3
+
 [session]
 tools_dock_checked=true
 

+ 3 - 0
src/vconfigmanager.cpp

@@ -160,6 +160,9 @@ void VConfigManager::initialize()
 
     m_markdownHighlightInterval = getConfigFromSettings("global",
                                                         "markdown_highlight_interval").toInt();
+
+    m_lineDistanceHeight = getConfigFromSettings("global",
+                                                 "line_distance_height").toInt();
 }
 
 void VConfigManager::readPredefinedColorsFromSettings()

+ 10 - 0
src/vconfigmanager.h

@@ -223,6 +223,8 @@ public:
 
     int getMarkdownHighlightInterval() const;
 
+    int getLineDistanceHeight() const;
+
     // Return the configured key sequence of @p_operation.
     // Return empty if there is no corresponding config.
     QString getShortcutKeySequence(const QString &p_operation) const;
@@ -451,6 +453,9 @@ private:
     // Interval for HGMarkdownHighlighter highlight timer (milliseconds).
     int m_markdownHighlightInterval;
 
+    // Line distance height in pixel.
+    int m_lineDistanceHeight;
+
     // The name of the config file in each directory, obsolete.
     // Use c_dirConfigFile instead.
     static const QString c_obsoleteDirConfigFile;
@@ -1149,4 +1154,9 @@ inline int VConfigManager::getMarkdownHighlightInterval() const
     return m_markdownHighlightInterval;
 }
 
+inline int VConfigManager::getLineDistanceHeight() const
+{
+    return m_lineDistanceHeight;
+}
+
 #endif // VCONFIGMANAGER_H

+ 81 - 1
src/vedit.cpp

@@ -19,6 +19,12 @@ void VEditConfig::init(const QFontMetrics &p_metric)
 
     m_enableVimMode = g_config->getEnableVimMode();
 
+    if (g_config->getLineDistanceHeight() <= 0) {
+        m_lineDistanceHeight = 0;
+    } else {
+        m_lineDistanceHeight = g_config->getLineDistanceHeight() * VUtils::calculateScaleFactor();
+    }
+
     m_highlightWholeBlock = m_enableVimMode;
 }
 
@@ -96,6 +102,9 @@ VEdit::VEdit(VFile *p_file, QWidget *p_parent)
             this, &VEdit::updateLineNumberArea);
 
     updateLineNumberAreaMargin();
+
+    connect(document(), &QTextDocument::contentsChange,
+            this, &VEdit::updateBlockLineDistanceHeight);
 }
 
 VEdit::~VEdit()
@@ -144,6 +153,9 @@ void VEdit::saveFile()
 void VEdit::reloadFile()
 {
     setHtml(m_file->getContent());
+
+    setBlockLineDistanceHeight();
+
     setModified(false);
 }
 
@@ -1025,6 +1037,7 @@ void VEdit::lineNumberAreaPaintEvent(QPaintEvent *p_event)
     const int curBlockNumber = textCursor().block().blockNumber();
     const bool relative = g_config->getEditorLineNumber() == 2;
     const QString &fg = g_config->getEditorLineNumberFg();
+    const int lineDistanceHeight = m_config.m_lineDistanceHeight;
     painter.setPen(fg);
 
     while (block.isValid() && top <= eventBtm) {
@@ -1067,7 +1080,7 @@ void VEdit::lineNumberAreaPaintEvent(QPaintEvent *p_event)
 
         block = block.next();
         top = bottom;
-        bottom = top + (int)layout->blockBoundingRect(block).height();
+        bottom = top + (int)layout->blockBoundingRect(block).height() + lineDistanceHeight;
         ++blockNumber;
     }
 }
@@ -1264,3 +1277,70 @@ void VEdit::alterContextMenu(QMenu *p_menu, const QList<QAction *> &p_actions)
     Q_UNUSED(p_menu);
     Q_UNUSED(p_actions);
 }
+
+void VEdit::setBlockLineDistanceHeight()
+{
+    if (m_config.m_lineDistanceHeight <= 0) {
+        return;
+    }
+
+    bool modified = isModified();
+    QTextCursor cursor = textCursor();
+    int anchorPos = cursor.selectionStart();
+    int cursorPos = cursor.selectionEnd();
+
+    QTextBlockFormat fmt = cursor.blockFormat();
+    fmt.setLineHeight(m_config.m_lineDistanceHeight,
+                      QTextBlockFormat::LineDistanceHeight);
+    cursor.select(QTextCursor::Document);
+    cursor.mergeBlockFormat(fmt);
+
+    cursor.setPosition(anchorPos);
+    cursor.setPosition(cursorPos, QTextCursor::KeepAnchor);
+
+    setTextCursor(cursor);
+
+    setModified(modified);
+}
+
+void VEdit::updateBlockLineDistanceHeight(int p_pos,
+                                          int p_charsRemoved,
+                                          int p_charsAdded)
+{
+    if ((p_charsRemoved == 0 && p_charsAdded == 0)
+        || m_config.m_lineDistanceHeight <= 0) {
+        return;
+    }
+
+    QTextDocument *doc = document();
+    QTextBlock block = doc->findBlock(p_pos);
+    QTextBlock lastBlock = doc->findBlock(p_pos + p_charsRemoved + p_charsAdded);
+    QTextCursor cursor(block);
+    bool changed = false;
+    while (block.isValid()) {
+        cursor.setPosition(block.position());
+        QTextBlockFormat fmt = cursor.blockFormat();
+        if (fmt.lineHeightType() != QTextBlockFormat::LineDistanceHeight
+            || fmt.lineHeight() != m_config.m_lineDistanceHeight) {
+            fmt.setLineHeight(m_config.m_lineDistanceHeight,
+                              QTextBlockFormat::LineDistanceHeight);
+            if (!changed) {
+                changed = true;
+                cursor.joinPreviousEditBlock();
+            }
+
+            cursor.mergeBlockFormat(fmt);
+            qDebug() << "merge block format line distance" << block.blockNumber();
+        }
+
+        if (block == lastBlock) {
+            break;
+        }
+
+        block = block.next();
+    }
+
+    if (changed) {
+        cursor.endEditBlock();
+    }
+}

+ 12 - 1
src/vedit.h

@@ -37,7 +37,8 @@ public:
     VEditConfig() : m_tabStopWidth(0),
                     m_tabSpaces("\t"),
                     m_enableVimMode(false),
-                    m_highlightWholeBlock(false)
+                    m_highlightWholeBlock(false),
+                    m_lineDistanceHeight(0)
     {}
 
     void init(const QFontMetrics &p_metric);
@@ -60,6 +61,9 @@ public:
 
     // Whether highlight a visual line or a whole block.
     bool m_highlightWholeBlock;
+
+    // Line distance height in pixels.
+    int m_lineDistanceHeight;
 };
 
 class LineNumberArea;
@@ -184,6 +188,10 @@ private slots:
 
     void updateLineNumberArea();
 
+    // According to the document change, try to set the block line distance height
+    // if affected blocks are not set.
+    void updateBlockLineDistanceHeight(int p_pos, int p_charsRemoved, int p_charsAdded);
+
 protected:
     QPointer<VFile> m_file;
     VEditOperations *m_editOps;
@@ -206,6 +214,9 @@ protected:
     // Called in contextMenuEvent() to modify the context menu.
     virtual void alterContextMenu(QMenu *p_menu, const QList<QAction *> &p_actions);
 
+    // Set all the blocks' line height.
+    void setBlockLineDistanceHeight();
+
 private:
     QLabel *m_wrapLabel;
     QTimer *m_labelTimer;

+ 5 - 1
src/vmdedit.cpp

@@ -106,8 +106,12 @@ void VMdEdit::saveFile()
 void VMdEdit::reloadFile()
 {
     const QString &content = m_file->getContent();
-    V_ASSERT(content.indexOf(QChar::ObjectReplacementCharacter) == -1);
+    Q_ASSERT(content.indexOf(QChar::ObjectReplacementCharacter) == -1);
+
     setPlainText(content);
+
+    setBlockLineDistanceHeight();
+
     setModified(false);
 }
 

+ 2 - 1
src/vtextblockdata.cpp

@@ -1,7 +1,8 @@
 #include "vtextblockdata.h"
 
 VTextBlockData::VTextBlockData()
-    : QTextBlockUserData(), m_containsPreviewImage(false)
+    : QTextBlockUserData(),
+      m_containsPreviewImage(false)
 {
 }