diff options
author | David Schulz <david.schulz@qt.io> | 2017-10-26 15:18:56 +0200 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2017-11-22 10:08:01 +0000 |
commit | c815d456ed10194c4a9c1bab4fc0f5db1927aef4 (patch) | |
tree | dbb6854c430a5e75d29a07b9198566d428e685fe /src/plugins/texteditor | |
parent | c751e6afa7cfa9da2a7377d0a1f40debceab1ed7 (diff) | |
download | qt-creator-c815d456ed10194c4a9c1bab4fc0f5db1927aef4.tar.gz |
TextEditor: Add option to display annotation between lines
Task-number: QTCREATORBUG-19181
Change-Id: I9b3957c678c08ca2f3ddf9cfa5ff272241547471
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/plugins/texteditor')
-rw-r--r-- | src/plugins/texteditor/displaysettings.h | 3 | ||||
-rw-r--r-- | src/plugins/texteditor/displaysettingspage.cpp | 3 | ||||
-rw-r--r-- | src/plugins/texteditor/displaysettingspage.ui | 9 | ||||
-rw-r--r-- | src/plugins/texteditor/textdocumentlayout.cpp | 8 | ||||
-rw-r--r-- | src/plugins/texteditor/textdocumentlayout.h | 7 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.cpp | 56 |
6 files changed, 68 insertions, 18 deletions
diff --git a/src/plugins/texteditor/displaysettings.h b/src/plugins/texteditor/displaysettings.h index 41cebc0c6a..73114e6538 100644 --- a/src/plugins/texteditor/displaysettings.h +++ b/src/plugins/texteditor/displaysettings.h @@ -40,7 +40,8 @@ enum class AnnotationAlignment { NextToContent, NextToMargin, - RightSide + RightSide, + BetweenLines }; class TEXTEDITOR_EXPORT DisplaySettings diff --git a/src/plugins/texteditor/displaysettingspage.cpp b/src/plugins/texteditor/displaysettingspage.cpp index 2289ba2135..07b535f59a 100644 --- a/src/plugins/texteditor/displaysettingspage.cpp +++ b/src/plugins/texteditor/displaysettingspage.cpp @@ -126,6 +126,8 @@ void DisplaySettingsPage::settingsFromUI(DisplaySettings &displaySettings, displaySettings.m_annotationAlignment = AnnotationAlignment::NextToMargin; else if (d->m_page->rightAligned->isChecked()) displaySettings.m_annotationAlignment = AnnotationAlignment::RightSide; + else if (d->m_page->betweenLines->isChecked()) + displaySettings.m_annotationAlignment = AnnotationAlignment::BetweenLines; } void DisplaySettingsPage::settingsToUI() @@ -154,6 +156,7 @@ void DisplaySettingsPage::settingsToUI() case AnnotationAlignment::NextToContent: d->m_page->leftAligned->setChecked(true); break; case AnnotationAlignment::NextToMargin: d->m_page->atMargin->setChecked(true); break; case AnnotationAlignment::RightSide: d->m_page->rightAligned->setChecked(true); break; + case AnnotationAlignment::BetweenLines: d->m_page->betweenLines->setChecked(true); break; } } diff --git a/src/plugins/texteditor/displaysettingspage.ui b/src/plugins/texteditor/displaysettingspage.ui index aa8dd2cd44..8fb605ab7e 100644 --- a/src/plugins/texteditor/displaysettingspage.ui +++ b/src/plugins/texteditor/displaysettingspage.ui @@ -187,7 +187,7 @@ <item row="2" column="0"> <widget class="QGroupBox" name="displayAnnotations"> <property name="title"> - <string>Annotations next to lines</string> + <string>Line annotations</string> </property> <property name="checkable"> <bool>true</bool> @@ -217,6 +217,13 @@ </property> </widget> </item> + <item> + <widget class="QRadioButton" name="betweenLines"> + <property name="text"> + <string>Between lines</string> + </property> + </widget> + </item> </layout> </widget> </item> diff --git a/src/plugins/texteditor/textdocumentlayout.cpp b/src/plugins/texteditor/textdocumentlayout.cpp index 454819294d..9ddb752ba5 100644 --- a/src/plugins/texteditor/textdocumentlayout.cpp +++ b/src/plugins/texteditor/textdocumentlayout.cpp @@ -634,6 +634,14 @@ void TextDocumentLayout::updateMarksBlock(const QTextBlock &block) mrk->updateBlock(block); } +QRectF TextDocumentLayout::blockBoundingRect(const QTextBlock &block) const +{ + QRectF boundingRect = QPlainTextDocumentLayout::blockBoundingRect(block); + if (TextBlockUserData *userData = testUserData(block)) + boundingRect.adjust(0, 0, 0, userData->additionalAnnotationHeight()); + return boundingRect; +} + TextDocumentLayout::FoldValidator::FoldValidator() : m_layout(0) , m_requestDocUpdate(false) diff --git a/src/plugins/texteditor/textdocumentlayout.h b/src/plugins/texteditor/textdocumentlayout.h index 737566ab18..17a3a781f6 100644 --- a/src/plugins/texteditor/textdocumentlayout.h +++ b/src/plugins/texteditor/textdocumentlayout.h @@ -126,6 +126,9 @@ public: inline int lexerState() const { return m_lexerState; } inline void setLexerState(int state) {m_lexerState = state; } + inline void setAdditionalAnnotationHeight(int annotationHeight) + { m_additionalAnnotationHeight = annotationHeight; } + inline int additionalAnnotationHeight() const { return m_additionalAnnotationHeight; } CodeFormatterData *codeFormatterData() const { return m_codeFormatterData; } void setCodeFormatterData(CodeFormatterData *data); @@ -138,6 +141,7 @@ private: uint m_lexerState : 8; uint m_foldingStartIncluded : 1; uint m_foldingEndIncluded : 1; + int m_additionalAnnotationHeight = 0; Parentheses m_parentheses; CodeFormatterData *m_codeFormatterData; }; @@ -210,7 +214,8 @@ public: void setRequiredWidth(int width); - QSizeF documentSize() const; + QSizeF documentSize() const override; + QRectF blockBoundingRect(const QTextBlock &block) const override; TextMarks documentClosing(); void documentReloaded(TextMarks marks, TextDocument *baseextDocument); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 13e5b82423..3a561f18d4 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -459,7 +459,9 @@ public: bool expanded, bool active, bool hovered) const; - void updateLineAnnotation(const PaintEventData &data, QPainter &painter); + bool updateAnnotationBounds(TextBlockUserData *blockUserData, bool annotationsVisible); + void updateLineAnnotation(const PaintEventData &data, const PaintEventBlockData &blockData, + QPainter &painter); void paintRightMarginArea(PaintEventData &data, QPainter &painter) const; void paintRightMarginLine(const PaintEventData &data, QPainter &painter) const; void paintBlockHighlight(const PaintEventData &data, QPainter &painter) const; @@ -3965,7 +3967,20 @@ QRectF TextEditorWidgetPrivate::getLastLineLineRect(const QTextBlock &block) return line.naturalTextRect().translated(contentOffset.x(), top).adjusted(0, 0, -1, -1); } +bool TextEditorWidgetPrivate::updateAnnotationBounds(TextBlockUserData *blockUserData, bool annotationsVisible) +{ + const bool additionalHeightNeeded = annotationsVisible + && m_displaySettings.m_annotationAlignment == AnnotationAlignment::BetweenLines; + const int additionalHeight = additionalHeightNeeded ? q->fontMetrics().lineSpacing() : 0; + if (blockUserData->additionalAnnotationHeight() == additionalHeight) + return false; + blockUserData->setAdditionalAnnotationHeight(additionalHeight); + q->viewport()->update(); + return true; +} + void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data, + const PaintEventBlockData &blockData, QPainter &painter) { m_annotationRects.remove(data.block.blockNumber()); @@ -3978,7 +3993,12 @@ void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data, return; TextMarks marks = blockUserData->marks(); - if (marks.isEmpty()) + + const bool annotationsVisible = Utils::anyOf(marks, [](const TextMark* mark) { + return !mark->lineAnnotation().isEmpty(); + }); + + if (updateAnnotationBounds(blockUserData, annotationsVisible) || !annotationsVisible) return; const QRectF lineRect = getLastLineLineRect(data.block); @@ -3990,27 +4010,33 @@ void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data, }); const qreal itemOffset = q->fontMetrics().lineSpacing(); - const qreal initialOffset = itemOffset * 2; + const qreal initialOffset = m_displaySettings.m_annotationAlignment == AnnotationAlignment::BetweenLines ? itemOffset / 2 : itemOffset * 2; const qreal minimalContentWidth = q->fontMetrics().width('X') * m_displaySettings.m_minimalAnnotationContent; - QRectF boundingRect(lineRect.topLeft().x(), lineRect.topLeft().y(), - q->viewport()->width() - lineRect.right(), lineRect.height()); qreal offset = initialOffset; + qreal x = 0; if (marks.isEmpty()) return; - if (m_displaySettings.m_annotationAlignment == AnnotationAlignment::NextToMargin - && data.rightMargin > lineRect.right() + offset - && q->viewport()->width() > data.rightMargin + minimalContentWidth) { + QRectF boundingRect; + if (m_displaySettings.m_annotationAlignment == AnnotationAlignment::BetweenLines) { + boundingRect = QRectF(lineRect.bottomLeft(), blockData.boundingRect.bottomRight()); + } else { + boundingRect = QRectF(lineRect.topLeft().x(), lineRect.topLeft().y(), + q->viewport()->width() - lineRect.right(), lineRect.height()); + x = lineRect.right(); + if (m_displaySettings.m_annotationAlignment == AnnotationAlignment::NextToMargin + && data.rightMargin > lineRect.right() + offset + && q->viewport()->width() > data.rightMargin + minimalContentWidth) { offset = data.rightMargin - lineRect.right(); - } else if (m_displaySettings.m_annotationAlignment != AnnotationAlignment::NextToContent) { - marks = availableMarks(marks, boundingRect, q->fontMetrics(), itemOffset); - if (boundingRect.width() > 0) - offset = qMax(boundingRect.width(), initialOffset); + } else if (m_displaySettings.m_annotationAlignment != AnnotationAlignment::NextToContent) { + marks = availableMarks(marks, boundingRect, q->fontMetrics(), itemOffset); + if (boundingRect.width() > 0) + offset = qMax(boundingRect.width(), initialOffset); + } } - qreal x = lineRect.right(); for (const TextMark *mark : marks) { - boundingRect = QRectF(x, lineRect.top(), q->viewport()->width() - x, lineRect.height()); + boundingRect = QRectF(x, boundingRect.top(), q->viewport()->width() - x, boundingRect.height()); if (boundingRect.isEmpty()) break; if (data.eventRect.intersects(boundingRect.toRect())) @@ -4715,7 +4741,7 @@ void TextEditorWidget::paintEvent(QPaintEvent *e) d->paintAdditionalVisualWhitespaces(data, painter, blockData.boundingRect.top()); d->paintReplacement(data, painter, blockData.boundingRect.top()); } - d->updateLineAnnotation(data, painter); + d->updateLineAnnotation(data, blockData, painter); data.offset.ry() += blockData.boundingRect.height(); |