From 36a0d1dd7e1b4357718d443b1e635b993da91d9a Mon Sep 17 00:00:00 2001 From: Le Tan Date: Mon, 4 Sep 2017 19:33:49 +0800 Subject: [PATCH] support custom line distance height by line_distance_height config --- src/resources/vnote.ini | 3 ++ src/vconfigmanager.cpp | 3 ++ src/vconfigmanager.h | 10 +++++ src/vedit.cpp | 82 ++++++++++++++++++++++++++++++++++++++++- src/vedit.h | 13 ++++++- src/vmdedit.cpp | 6 ++- src/vtextblockdata.cpp | 3 +- 7 files changed, 116 insertions(+), 4 deletions(-) diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index 0fa10486..69ad0237 100644 --- a/src/resources/vnote.ini +++ b/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 diff --git a/src/vconfigmanager.cpp b/src/vconfigmanager.cpp index e04d0202..7e85d740 100644 --- a/src/vconfigmanager.cpp +++ b/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() diff --git a/src/vconfigmanager.h b/src/vconfigmanager.h index 7c8c9dff..de0571f8 100644 --- a/src/vconfigmanager.h +++ b/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 diff --git a/src/vedit.cpp b/src/vedit.cpp index a44c04ab..202a7b58 100644 --- a/src/vedit.cpp +++ b/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 &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(); + } +} diff --git a/src/vedit.h b/src/vedit.h index b3639719..cf2406d8 100644 --- a/src/vedit.h +++ b/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 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 &p_actions); + // Set all the blocks' line height. + void setBlockLineDistanceHeight(); + private: QLabel *m_wrapLabel; QTimer *m_labelTimer; diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp index 505d98a2..59e88d7c 100644 --- a/src/vmdedit.cpp +++ b/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); } diff --git a/src/vtextblockdata.cpp b/src/vtextblockdata.cpp index 21fcfed7..a0438bda 100644 --- a/src/vtextblockdata.cpp +++ b/src/vtextblockdata.cpp @@ -1,7 +1,8 @@ #include "vtextblockdata.h" VTextBlockData::VTextBlockData() - : QTextBlockUserData(), m_containsPreviewImage(false) + : QTextBlockUserData(), + m_containsPreviewImage(false) { }