Commit c815d456 authored by David Schulz's avatar David Schulz

TextEditor: Add option to display annotation between lines

Task-number: QTCREATORBUG-19181
Change-Id: I9b3957c678c08ca2f3ddf9cfa5ff272241547471
Reviewed-by: Marco Bubke's avatarMarco Bubke <marco.bubke@qt.io>
Reviewed-by: Eike Ziller's avatarEike Ziller <eike.ziller@qt.io>
parent c751e6af
......@@ -204,9 +204,11 @@
To specify the position where the annotations are displayed, select
\uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} >
\uicontrol Display > \uicontrol {Annotations next to lines}, and then
\uicontrol Display > \uicontrol {Line annotations}, and then
select whether to display the annotations directly next to the code,
aligned to the right of the code, or in the right margin.
aligned to the right of the code, or in the right margin. Showing annotations
between lines can be useful if there is usually not enough space to
display annotations next to the text.
If you hide the annotations by deselecting the check box, you can move the
mouse pointer over an icon to view them.
......
......@@ -40,7 +40,8 @@ enum class AnnotationAlignment
{
NextToContent,
NextToMargin,
RightSide
RightSide,
BetweenLines
};
class TEXTEDITOR_EXPORT DisplaySettings
......
......@@ -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;
}
}
......
......@@ -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>
......
......@@ -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)
......
......@@ -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);
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment