forked from qt-creator/qt-creator
TextEditor: Make annotation position configurable
Change-Id: Ib59c9770390523e1863ac507ce43512ba679c591 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -45,6 +45,8 @@ static const char scrollBarHighlightsKey[] = "ScrollBarHighlights";
|
|||||||
static const char animateNavigationWithinFileKey[] = "AnimateNavigationWithinFile";
|
static const char animateNavigationWithinFileKey[] = "AnimateNavigationWithinFile";
|
||||||
static const char animateWithinFileTimeMaxKey[] = "AnimateWithinFileTimeMax";
|
static const char animateWithinFileTimeMaxKey[] = "AnimateWithinFileTimeMax";
|
||||||
static const char displayAnnotationsKey[] = "DisplayAnnotations";
|
static const char displayAnnotationsKey[] = "DisplayAnnotations";
|
||||||
|
static const char annotationAlignmentKey[] = "AnnotationAlignment";
|
||||||
|
static const char minimalAnnotationContentKey[] = "MinimalAnnotationContent";
|
||||||
static const char groupPostfix[] = "DisplaySettings";
|
static const char groupPostfix[] = "DisplaySettings";
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
@@ -71,6 +73,7 @@ void DisplaySettings::toSettings(const QString &category, QSettings *s) const
|
|||||||
s->setValue(QLatin1String(scrollBarHighlightsKey), m_scrollBarHighlights);
|
s->setValue(QLatin1String(scrollBarHighlightsKey), m_scrollBarHighlights);
|
||||||
s->setValue(QLatin1String(animateNavigationWithinFileKey), m_animateNavigationWithinFile);
|
s->setValue(QLatin1String(animateNavigationWithinFileKey), m_animateNavigationWithinFile);
|
||||||
s->setValue(QLatin1String(displayAnnotationsKey), m_displayAnnotations);
|
s->setValue(QLatin1String(displayAnnotationsKey), m_displayAnnotations);
|
||||||
|
s->setValue(QLatin1String(annotationAlignmentKey), static_cast<int>(m_annotationAlignment));
|
||||||
s->endGroup();
|
s->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +103,10 @@ void DisplaySettings::fromSettings(const QString &category, const QSettings *s)
|
|||||||
m_animateNavigationWithinFile = s->value(group + QLatin1String(animateNavigationWithinFileKey), m_animateNavigationWithinFile).toBool();
|
m_animateNavigationWithinFile = s->value(group + QLatin1String(animateNavigationWithinFileKey), m_animateNavigationWithinFile).toBool();
|
||||||
m_animateWithinFileTimeMax = s->value(group + QLatin1String(animateWithinFileTimeMaxKey), m_animateWithinFileTimeMax).toInt();
|
m_animateWithinFileTimeMax = s->value(group + QLatin1String(animateWithinFileTimeMaxKey), m_animateWithinFileTimeMax).toInt();
|
||||||
m_displayAnnotations = s->value(group + QLatin1String(displayAnnotationsKey), m_displayAnnotations).toBool();
|
m_displayAnnotations = s->value(group + QLatin1String(displayAnnotationsKey), m_displayAnnotations).toBool();
|
||||||
|
m_annotationAlignment = static_cast<TextEditor::AnnotationAlignment>(
|
||||||
|
s->value(group + QLatin1String(annotationAlignmentKey),
|
||||||
|
static_cast<int>(m_annotationAlignment)).toInt());
|
||||||
|
m_minimalAnnotationContent = s->value(group + QLatin1String(minimalAnnotationContentKey), m_minimalAnnotationContent).toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DisplaySettings::equals(const DisplaySettings &ds) const
|
bool DisplaySettings::equals(const DisplaySettings &ds) const
|
||||||
@@ -122,6 +129,8 @@ bool DisplaySettings::equals(const DisplaySettings &ds) const
|
|||||||
&& m_animateNavigationWithinFile == ds.m_animateNavigationWithinFile
|
&& m_animateNavigationWithinFile == ds.m_animateNavigationWithinFile
|
||||||
&& m_animateWithinFileTimeMax == ds.m_animateWithinFileTimeMax
|
&& m_animateWithinFileTimeMax == ds.m_animateWithinFileTimeMax
|
||||||
&& m_displayAnnotations == ds.m_displayAnnotations
|
&& m_displayAnnotations == ds.m_displayAnnotations
|
||||||
|
&& m_annotationAlignment == ds.m_annotationAlignment
|
||||||
|
&& m_minimalAnnotationContent == ds.m_minimalAnnotationContent
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,12 +27,21 @@
|
|||||||
|
|
||||||
#include "texteditor_global.h"
|
#include "texteditor_global.h"
|
||||||
|
|
||||||
|
#include "QMetaType"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QSettings;
|
class QSettings;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
|
|
||||||
|
enum class AnnotationAlignment
|
||||||
|
{
|
||||||
|
NextToContent,
|
||||||
|
NextToMargin,
|
||||||
|
RightSide
|
||||||
|
};
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT DisplaySettings
|
class TEXTEDITOR_EXPORT DisplaySettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -59,6 +68,8 @@ public:
|
|||||||
bool m_animateNavigationWithinFile = false;
|
bool m_animateNavigationWithinFile = false;
|
||||||
int m_animateWithinFileTimeMax = 333; // read only setting
|
int m_animateWithinFileTimeMax = 333; // read only setting
|
||||||
bool m_displayAnnotations = true;
|
bool m_displayAnnotations = true;
|
||||||
|
AnnotationAlignment m_annotationAlignment = AnnotationAlignment::RightSide;
|
||||||
|
int m_minimalAnnotationContent = 15;
|
||||||
|
|
||||||
bool equals(const DisplaySettings &ds) const;
|
bool equals(const DisplaySettings &ds) const;
|
||||||
};
|
};
|
||||||
@@ -67,3 +78,5 @@ inline bool operator==(const DisplaySettings &t1, const DisplaySettings &t2) { r
|
|||||||
inline bool operator!=(const DisplaySettings &t1, const DisplaySettings &t2) { return !t1.equals(t2); }
|
inline bool operator!=(const DisplaySettings &t1, const DisplaySettings &t2) { return !t1.equals(t2); }
|
||||||
|
|
||||||
} // namespace TextEditor
|
} // namespace TextEditor
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(TextEditor::AnnotationAlignment)
|
||||||
|
@@ -120,6 +120,12 @@ void DisplaySettingsPage::settingsFromUI(DisplaySettings &displaySettings,
|
|||||||
displaySettings.m_scrollBarHighlights = d->m_page->scrollBarHighlights->isChecked();
|
displaySettings.m_scrollBarHighlights = d->m_page->scrollBarHighlights->isChecked();
|
||||||
displaySettings.m_animateNavigationWithinFile = d->m_page->animateNavigationWithinFile->isChecked();
|
displaySettings.m_animateNavigationWithinFile = d->m_page->animateNavigationWithinFile->isChecked();
|
||||||
displaySettings.m_displayAnnotations = d->m_page->displayAnnotations->isChecked();
|
displaySettings.m_displayAnnotations = d->m_page->displayAnnotations->isChecked();
|
||||||
|
if (d->m_page->leftAligned->isChecked())
|
||||||
|
displaySettings.m_annotationAlignment = AnnotationAlignment::NextToContent;
|
||||||
|
else if (d->m_page->atMargin->isChecked())
|
||||||
|
displaySettings.m_annotationAlignment = AnnotationAlignment::NextToMargin;
|
||||||
|
else if (d->m_page->rightAligned->isChecked())
|
||||||
|
displaySettings.m_annotationAlignment = AnnotationAlignment::RightSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplaySettingsPage::settingsToUI()
|
void DisplaySettingsPage::settingsToUI()
|
||||||
@@ -144,6 +150,11 @@ void DisplaySettingsPage::settingsToUI()
|
|||||||
d->m_page->scrollBarHighlights->setChecked(displaySettings.m_scrollBarHighlights);
|
d->m_page->scrollBarHighlights->setChecked(displaySettings.m_scrollBarHighlights);
|
||||||
d->m_page->animateNavigationWithinFile->setChecked(displaySettings.m_animateNavigationWithinFile);
|
d->m_page->animateNavigationWithinFile->setChecked(displaySettings.m_animateNavigationWithinFile);
|
||||||
d->m_page->displayAnnotations->setChecked(displaySettings.m_displayAnnotations);
|
d->m_page->displayAnnotations->setChecked(displaySettings.m_displayAnnotations);
|
||||||
|
switch (displaySettings.m_annotationAlignment) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DisplaySettings &DisplaySettingsPage::displaySettings() const
|
const DisplaySettings &DisplaySettingsPage::displaySettings() const
|
||||||
|
@@ -6,11 +6,24 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>501</width>
|
<width>452</width>
|
||||||
<height>339</height>
|
<height>458</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="3" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>8</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QGroupBox" name="groupBoxText">
|
<widget class="QGroupBox" name="groupBoxText">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@@ -61,57 +74,16 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>8</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QGroupBox" name="groupBoxDisplay">
|
<widget class="QGroupBox" name="groupBoxDisplay">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Display</string>
|
<string>Display</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="4" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QCheckBox" name="highlightMatchingParentheses">
|
<widget class="QCheckBox" name="displayFileEncoding">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Highlight matching parentheses</string>
|
<string>Display file encoding</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QCheckBox" name="highlightBlocks">
|
|
||||||
<property name="text">
|
|
||||||
<string>Highlight &blocks</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QCheckBox" name="highlightCurrentLine">
|
|
||||||
<property name="text">
|
|
||||||
<string>Highlight current &line</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QCheckBox" name="displayLineNumbers">
|
|
||||||
<property name="text">
|
|
||||||
<string>Display line &numbers</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QCheckBox" name="autoFoldFirstComment">
|
|
||||||
<property name="text">
|
|
||||||
<string>Auto-fold first &comment</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -122,20 +94,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QCheckBox" name="openLinksInNextSplit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Always open links in another split</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QCheckBox" name="displayFileEncoding">
|
|
||||||
<property name="text">
|
|
||||||
<string>Display file encoding</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QCheckBox" name="centerOnScroll">
|
<widget class="QCheckBox" name="centerOnScroll">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -143,6 +101,27 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="displayLineNumbers">
|
||||||
|
<property name="text">
|
||||||
|
<string>Display line &numbers</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QCheckBox" name="highlightMatchingParentheses">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Highlight matching parentheses</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QCheckBox" name="openLinksInNextSplit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Always open links in another split</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="visualizeWhitespace">
|
<widget class="QCheckBox" name="visualizeWhitespace">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
@@ -153,6 +132,27 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QCheckBox" name="highlightCurrentLine">
|
||||||
|
<property name="text">
|
||||||
|
<string>Highlight current &line</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QCheckBox" name="autoFoldFirstComment">
|
||||||
|
<property name="text">
|
||||||
|
<string>Auto-fold first &comment</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="highlightBlocks">
|
||||||
|
<property name="text">
|
||||||
|
<string>Highlight &blocks</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="displayFoldingMarkers">
|
<widget class="QCheckBox" name="displayFoldingMarkers">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -181,10 +181,39 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
</layout>
|
||||||
<widget class="QCheckBox" name="displayAnnotations">
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="displayAnnotations">
|
||||||
|
<property name="title">
|
||||||
|
<string>Annotations next to lines</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="leftAligned">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Display annotations behind lines</string>
|
<string>Next to editor content</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="atMargin">
|
||||||
|
<property name="text">
|
||||||
|
<string>Next to right margin</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="rightAligned">
|
||||||
|
<property name="text">
|
||||||
|
<string>Aligned at right side</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -204,7 +233,6 @@
|
|||||||
<tabstop>centerOnScroll</tabstop>
|
<tabstop>centerOnScroll</tabstop>
|
||||||
<tabstop>autoFoldFirstComment</tabstop>
|
<tabstop>autoFoldFirstComment</tabstop>
|
||||||
<tabstop>scrollBarHighlights</tabstop>
|
<tabstop>scrollBarHighlights</tabstop>
|
||||||
<tabstop>displayAnnotations</tabstop>
|
|
||||||
<tabstop>highlightCurrentLine</tabstop>
|
<tabstop>highlightCurrentLine</tabstop>
|
||||||
<tabstop>highlightBlocks</tabstop>
|
<tabstop>highlightBlocks</tabstop>
|
||||||
<tabstop>animateMatchingParentheses</tabstop>
|
<tabstop>animateMatchingParentheses</tabstop>
|
||||||
|
@@ -393,7 +393,7 @@ public:
|
|||||||
bool expanded,
|
bool expanded,
|
||||||
bool active,
|
bool active,
|
||||||
bool hovered) const;
|
bool hovered) const;
|
||||||
void drawLineAnnotation(QPainter &painter, const QTextBlock &block);
|
void drawLineAnnotation(QPainter &painter, const QTextBlock &block, qreal start);
|
||||||
|
|
||||||
void toggleBlockVisible(const QTextBlock &block);
|
void toggleBlockVisible(const QTextBlock &block);
|
||||||
QRect foldBox();
|
QRect foldBox();
|
||||||
@@ -484,6 +484,7 @@ public:
|
|||||||
Id m_tabSettingsId;
|
Id m_tabSettingsId;
|
||||||
ICodeStylePreferences *m_codeStylePreferences = nullptr;
|
ICodeStylePreferences *m_codeStylePreferences = nullptr;
|
||||||
DisplaySettings m_displaySettings;
|
DisplaySettings m_displaySettings;
|
||||||
|
bool m_annotationsrRight = true;
|
||||||
MarginSettings m_marginSettings;
|
MarginSettings m_marginSettings;
|
||||||
// apply when making visible the first time, for the split case
|
// apply when making visible the first time, for the split case
|
||||||
bool m_fontSettingsNeedsApply = true;
|
bool m_fontSettingsNeedsApply = true;
|
||||||
@@ -506,6 +507,7 @@ public:
|
|||||||
const TextMark *mark;
|
const TextMark *mark;
|
||||||
};
|
};
|
||||||
QMap<int, QList<AnnotationRect>> m_annotationRects;
|
QMap<int, QList<AnnotationRect>> m_annotationRects;
|
||||||
|
QRectF getLastLineLineRect(const QTextBlock &block);
|
||||||
|
|
||||||
RefactorOverlay *m_refactorOverlay = nullptr;
|
RefactorOverlay *m_refactorOverlay = nullptr;
|
||||||
QString m_contextHelpId;
|
QString m_contextHelpId;
|
||||||
@@ -3788,7 +3790,41 @@ static QTextLayout::FormatRange createBlockCursorCharFormatRange(int pos, const
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidgetPrivate::drawLineAnnotation(QPainter &painter, const QTextBlock &block)
|
static TextMarks availableMarks(const TextMarks &marks,
|
||||||
|
QRectF &boundingRect,
|
||||||
|
const QFontMetrics &fm,
|
||||||
|
const qreal itemOffset)
|
||||||
|
{
|
||||||
|
TextMarks ret;
|
||||||
|
bool first = true;
|
||||||
|
for (TextMark *mark : marks) {
|
||||||
|
const TextMark::AnnotationRects &rects = mark->annotationRects(
|
||||||
|
boundingRect, fm, first ? 0 : itemOffset, 0);
|
||||||
|
if (rects.annotationRect.isEmpty())
|
||||||
|
break;
|
||||||
|
boundingRect.setLeft(rects.fadeOutRect.right());
|
||||||
|
ret.append(mark);
|
||||||
|
if (boundingRect.isEmpty())
|
||||||
|
break;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF TextEditorWidgetPrivate::getLastLineLineRect(const QTextBlock &block)
|
||||||
|
{
|
||||||
|
const QTextLayout *layout = block.layout();
|
||||||
|
const int lineCount = layout->lineCount();
|
||||||
|
if (lineCount < 1)
|
||||||
|
return QRectF();
|
||||||
|
const QTextLine line = layout->lineAt(lineCount - 1);
|
||||||
|
const QPointF contentOffset = q->contentOffset();
|
||||||
|
const qreal top = q->blockBoundingGeometry(block).translated(contentOffset).top();
|
||||||
|
return line.naturalTextRect().translated(contentOffset.x(), top).adjusted(0, 0, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorWidgetPrivate::drawLineAnnotation(
|
||||||
|
QPainter &painter, const QTextBlock &block, qreal rightMargin)
|
||||||
{
|
{
|
||||||
if (!m_displaySettings.m_displayAnnotations)
|
if (!m_displaySettings.m_displayAnnotations)
|
||||||
return;
|
return;
|
||||||
@@ -3801,30 +3837,44 @@ void TextEditorWidgetPrivate::drawLineAnnotation(QPainter &painter, const QTextB
|
|||||||
if (marks.isEmpty())
|
if (marks.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QTextLayout *layout = block.layout();
|
const QRectF lineRect = getLastLineLineRect(block);
|
||||||
const int lineCount = layout->lineCount();
|
if (lineRect.isNull())
|
||||||
if (lineCount < 1)
|
|
||||||
return;
|
return;
|
||||||
const QTextLine line = layout->lineAt(lineCount - 1);
|
|
||||||
const QPointF contentOffset = q->contentOffset();
|
|
||||||
const qreal top = q->blockBoundingGeometry(block).translated(contentOffset).top();
|
|
||||||
const QRectF lineRect =
|
|
||||||
line.naturalTextRect().translated(contentOffset.x(), top).adjusted(0, 0, -1, -1);
|
|
||||||
|
|
||||||
Utils::sort(marks, [](const TextMark* mark1, const TextMark* mark2){
|
Utils::sort(marks, [](const TextMark* mark1, const TextMark* mark2){
|
||||||
return mark1->priority() > mark2->priority();
|
return mark1->priority() > mark2->priority();
|
||||||
});
|
});
|
||||||
|
|
||||||
const qreal itemOffset = q->fontMetrics().lineSpacing();
|
const qreal itemOffset = q->fontMetrics().lineSpacing();
|
||||||
qreal x = lineRect.right() + itemOffset * 2;
|
const qreal initialOffset = 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;
|
||||||
|
if (marks.isEmpty())
|
||||||
|
return;
|
||||||
|
if (m_displaySettings.m_annotationAlignment == AnnotationAlignment::NextToMargin
|
||||||
|
&& rightMargin > lineRect.right() + offset
|
||||||
|
&& q->viewport()->width() > rightMargin + minimalContentWidth) {
|
||||||
|
offset = 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal x = lineRect.right();
|
||||||
for (const TextMark *mark : marks) {
|
for (const TextMark *mark : marks) {
|
||||||
QRectF annotationRect(x, lineRect.top(), q->viewport()->width() - x, lineRect.height());
|
boundingRect = QRectF(x, lineRect.top(), q->viewport()->width() - x, lineRect.height());
|
||||||
if (annotationRect.width() <= 0)
|
if (boundingRect.isEmpty())
|
||||||
break;
|
break;
|
||||||
mark->paintAnnotation(&painter, &annotationRect);
|
|
||||||
x += annotationRect.width() + itemOffset;
|
// paint annotation
|
||||||
m_annotationRects[block.blockNumber()].append({annotationRect, mark});
|
mark->paintAnnotation(painter, &boundingRect, offset, itemOffset / 2);
|
||||||
|
x = boundingRect.right();
|
||||||
|
offset = itemOffset / 2;
|
||||||
|
m_annotationRects[block.blockNumber()].append({boundingRect, mark});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4469,7 +4519,7 @@ void TextEditorWidget::paintEvent(QPaintEvent *e)
|
|||||||
painter.restore();
|
painter.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d->drawLineAnnotation(painter, block);
|
d->drawLineAnnotation(painter, block, lineX < viewportRect.width() ? lineX : 0);
|
||||||
|
|
||||||
block = nextVisibleBlock;
|
block = nextVisibleBlock;
|
||||||
top = bottom;
|
top = bottom;
|
||||||
|
@@ -121,43 +121,58 @@ void TextMark::paintIcon(QPainter *painter, const QRect &rect) const
|
|||||||
m_icon.paint(painter, rect, Qt::AlignCenter);
|
m_icon.paint(painter, rect, Qt::AlignCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextMark::paintAnnotation(QPainter *painter, QRectF *annotationRect) const
|
void TextMark::paintAnnotation(QPainter &painter, QRectF *annotationRect,
|
||||||
|
const qreal fadeInOffset, const qreal fadeOutOffset) const
|
||||||
{
|
{
|
||||||
QString text = lineAnnotation();
|
QString text = lineAnnotation();
|
||||||
if (text.isEmpty())
|
if (text.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const AnnotationRects &rects = annotationRects(*annotationRect, painter->fontMetrics());
|
const AnnotationRects &rects = annotationRects(*annotationRect, painter.fontMetrics(),
|
||||||
|
fadeInOffset, fadeOutOffset);
|
||||||
|
const QColor &markColor = m_hasColor ? Utils::creatorTheme()->color(m_color).toHsl()
|
||||||
|
: painter.pen().color();
|
||||||
|
const AnnotationColors &colors = AnnotationColors::getAnnotationColors(
|
||||||
|
markColor, painter.background().color());
|
||||||
|
|
||||||
const QColor markColor = m_hasColor ? Utils::creatorTheme()->color(m_color).toHsl()
|
painter.save();
|
||||||
: painter->pen().color();
|
QLinearGradient grad(rects.fadeInRect.topLeft(), rects.fadeInRect.topRight());
|
||||||
const AnnotationColors &colors =
|
grad.setColorAt(0.0, Qt::transparent);
|
||||||
AnnotationColors::getAnnotationColors(markColor, painter->background().color());
|
grad.setColorAt(1.0, colors.rectColor);
|
||||||
|
painter.fillRect(rects.fadeInRect, grad);
|
||||||
painter->save();
|
painter.fillRect(rects.annotationRect, colors.rectColor);
|
||||||
painter->setPen(colors.rectColor);
|
painter.setPen(colors.textColor);
|
||||||
painter->setBrush(colors.rectColor);
|
paintIcon(&painter, rects.iconRect.toAlignedRect());
|
||||||
painter->drawRect(rects.annotationRect);
|
painter.drawText(rects.textRect, Qt::AlignLeft, rects.text);
|
||||||
painter->setPen(colors.textColor);
|
if (rects.fadeOutRect.isValid()) {
|
||||||
paintIcon(painter, rects.iconRect.toAlignedRect());
|
grad = QLinearGradient(rects.fadeOutRect.topLeft(), rects.fadeOutRect.topRight());
|
||||||
painter->drawText(rects.textRect, Qt::AlignLeft, rects.text);
|
grad.setColorAt(0.0, colors.rectColor);
|
||||||
painter->restore();
|
grad.setColorAt(1.0, Qt::transparent);
|
||||||
*annotationRect = rects.annotationRect;
|
painter.fillRect(rects.fadeOutRect, grad);
|
||||||
|
}
|
||||||
|
painter.restore();
|
||||||
|
annotationRect->setRight(rects.fadeOutRect.right());
|
||||||
}
|
}
|
||||||
|
|
||||||
TextMark::AnnotationRects TextMark::annotationRects(const QRectF &boundingRect,
|
TextMark::AnnotationRects TextMark::annotationRects(const QRectF &boundingRect,
|
||||||
const QFontMetrics &fm) const
|
const QFontMetrics &fm,
|
||||||
|
const qreal fadeInOffset,
|
||||||
|
const qreal fadeOutOffset) const
|
||||||
{
|
{
|
||||||
AnnotationRects rects;
|
AnnotationRects rects;
|
||||||
rects.annotationRect = boundingRect;
|
|
||||||
rects.text = lineAnnotation();
|
rects.text = lineAnnotation();
|
||||||
|
if (rects.text.isEmpty())
|
||||||
|
return rects;
|
||||||
|
rects.fadeInRect = boundingRect;
|
||||||
|
rects.fadeInRect.setWidth(fadeInOffset);
|
||||||
|
rects.annotationRect = boundingRect;
|
||||||
|
rects.annotationRect.setLeft(rects.fadeInRect.right());
|
||||||
const bool drawIcon = !m_icon.isNull();
|
const bool drawIcon = !m_icon.isNull();
|
||||||
constexpr qreal margin = 1;
|
constexpr qreal margin = 1;
|
||||||
rects.iconRect = QRectF(boundingRect.left() + margin, boundingRect.top() + margin, 0, 0);
|
rects.iconRect = QRectF(rects.annotationRect.left(), boundingRect.top(),
|
||||||
if (drawIcon) {
|
0, boundingRect.height());
|
||||||
rects.iconRect.setHeight(boundingRect.height() - 2 * margin);
|
if (drawIcon)
|
||||||
rects.iconRect.setWidth(rects.iconRect.height() * m_widthFactor);
|
rects.iconRect.setWidth(rects.iconRect.height() * m_widthFactor);
|
||||||
}
|
|
||||||
rects.textRect = QRectF(rects.iconRect.right() + margin, boundingRect.top(),
|
rects.textRect = QRectF(rects.iconRect.right() + margin, boundingRect.top(),
|
||||||
qreal(fm.width(rects.text)), boundingRect.height());
|
qreal(fm.width(rects.text)), boundingRect.height());
|
||||||
rects.annotationRect.setRight(rects.textRect.right() + margin);
|
rects.annotationRect.setRight(rects.textRect.right() + margin);
|
||||||
@@ -165,6 +180,12 @@ TextMark::AnnotationRects TextMark::annotationRects(const QRectF &boundingRect,
|
|||||||
rects.textRect.setRight(boundingRect.right() - margin);
|
rects.textRect.setRight(boundingRect.right() - margin);
|
||||||
rects.text = fm.elidedText(rects.text, Qt::ElideRight, int(rects.textRect.width()));
|
rects.text = fm.elidedText(rects.text, Qt::ElideRight, int(rects.textRect.width()));
|
||||||
rects.annotationRect.setRight(boundingRect.right());
|
rects.annotationRect.setRight(boundingRect.right());
|
||||||
|
rects.fadeOutRect = QRectF(rects.annotationRect.topRight(),
|
||||||
|
rects.annotationRect.bottomRight());
|
||||||
|
} else {
|
||||||
|
rects.fadeOutRect = boundingRect;
|
||||||
|
rects.fadeOutRect.setLeft(rects.annotationRect.right());
|
||||||
|
rects.fadeOutRect.setWidth(fadeOutOffset);
|
||||||
}
|
}
|
||||||
return rects;
|
return rects;
|
||||||
}
|
}
|
||||||
|
@@ -64,15 +64,19 @@ public:
|
|||||||
int lineNumber() const;
|
int lineNumber() const;
|
||||||
|
|
||||||
virtual void paintIcon(QPainter *painter, const QRect &rect) const;
|
virtual void paintIcon(QPainter *painter, const QRect &rect) const;
|
||||||
virtual void paintAnnotation(QPainter *painter, QRectF *annotationRect) const;
|
virtual void paintAnnotation(QPainter &painter, QRectF *annotationRect,
|
||||||
|
const qreal fadeInOffset, const qreal fadeOutOffset) const;
|
||||||
struct AnnotationRects
|
struct AnnotationRects
|
||||||
{
|
{
|
||||||
|
QRectF fadeInRect;
|
||||||
QRectF annotationRect;
|
QRectF annotationRect;
|
||||||
QRectF iconRect;
|
QRectF iconRect;
|
||||||
QRectF textRect;
|
QRectF textRect;
|
||||||
|
QRectF fadeOutRect;
|
||||||
QString text;
|
QString text;
|
||||||
};
|
};
|
||||||
virtual AnnotationRects annotationRects(const QRectF &boundingRect, const QFontMetrics &fm) const;
|
AnnotationRects annotationRects(const QRectF &boundingRect, const QFontMetrics &fm,
|
||||||
|
const qreal fadeInOffset, const qreal fadeOutOffset) const;
|
||||||
/// called if the filename of the document changed
|
/// called if the filename of the document changed
|
||||||
virtual void updateFileName(const QString &fileName);
|
virtual void updateFileName(const QString &fileName);
|
||||||
virtual void updateLineNumber(int lineNumber);
|
virtual void updateLineNumber(int lineNumber);
|
||||||
|
Reference in New Issue
Block a user