forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -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();
|
||||
|
||||
|
Reference in New Issue
Block a user