Add API in texteditor to let plugins contribute extra selections.

Some plugins use extra selections to provide additional editor annotations: code coverage, spelling
mistake... This was possible for C++ editor in previous version, using
CppModelManagerInterface::setExtraDiagnostics(), but this API has been removed.

This commits adds alternative API directly in the editor, allowing to pass a Core::Id instead of
the enum value.

Change-Id: I3040bd144d6fe0876d861dd28e832729bd5d6602
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
Francois Ferrand
2014-10-21 17:50:10 +02:00
committed by hjk
parent 8eb08db536
commit a645f78cd6
2 changed files with 49 additions and 24 deletions

View File

@@ -391,7 +391,8 @@ public:
void highlightSearchResults(const QTextBlock &block, TextEditorOverlay *overlay); void highlightSearchResults(const QTextBlock &block, TextEditorOverlay *overlay);
QTimer m_delayedUpdateTimer; QTimer m_delayedUpdateTimer;
QList<QTextEdit::ExtraSelection> m_extraSelections[TextEditorWidget::NExtraSelectionKinds]; void setExtraSelections(int kind, const QList<QTextEdit::ExtraSelection> &selections);
QHash<int, QList<QTextEdit::ExtraSelection>> m_extraSelections;
// block selection mode // block selection mode
bool m_inBlockSelectionMode; bool m_inBlockSelectionMode;
@@ -521,6 +522,8 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent)
m_cursorPositionLabelAction = m_toolBar->addWidget(m_cursorPositionLabel); m_cursorPositionLabelAction = m_toolBar->addWidget(m_cursorPositionLabel);
m_fileEncodingLabelAction = m_toolBar->addWidget(m_fileEncodingLabel); m_fileEncodingLabelAction = m_toolBar->addWidget(m_fileEncodingLabel);
m_extraSelections.reserve(TextEditorWidget::NExtraSelectionKinds);
} }
} // namespace Internal } // namespace Internal
@@ -2542,8 +2545,8 @@ void TextEditorWidgetPrivate::documentAboutToBeReloaded()
// remove extra selections (loads of QTextCursor objects) // remove extra selections (loads of QTextCursor objects)
for (int i = 0; i < TextEditorWidget::NExtraSelectionKinds; ++i) m_extraSelections.clear();
m_extraSelections[i].clear(); m_extraSelections.reserve(TextEditorWidget::NExtraSelectionKinds);
q->QPlainTextEdit::setExtraSelections(QList<QTextEdit::ExtraSelection>()); q->QPlainTextEdit::setExtraSelections(QList<QTextEdit::ExtraSelection>());
// clear all overlays // clear all overlays
@@ -5815,53 +5818,73 @@ void TextEditorWidget::deleteStartOfWordCamelCase()
setTextCursor(c); setTextCursor(c);
} }
void TextEditorWidget::setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections) // kind can be either a value from the ExtraSelectionKind enum, or an unique Core::Id identifier.
void TextEditorWidgetPrivate::setExtraSelections(int kind, const QList<QTextEdit::ExtraSelection> &selections)
{ {
if (selections.isEmpty() && d->m_extraSelections[kind].isEmpty()) if (selections.isEmpty() && m_extraSelections[kind].isEmpty())
return; return;
d->m_extraSelections[kind] = selections; m_extraSelections[kind] = selections;
if (kind == CodeSemanticsSelection) { if (kind == TextEditorWidget::CodeSemanticsSelection) {
d->m_overlay->clear(); m_overlay->clear();
foreach (const QTextEdit::ExtraSelection &selection, d->m_extraSelections[kind]) { foreach (const QTextEdit::ExtraSelection &selection, m_extraSelections[kind]) {
d->m_overlay->addOverlaySelection(selection.cursor, m_overlay->addOverlaySelection(selection.cursor,
selection.format.background().color(), selection.format.background().color(),
selection.format.background().color(), selection.format.background().color(),
TextEditorOverlay::LockSize); TextEditorOverlay::LockSize);
} }
d->m_overlay->setVisible(!d->m_overlay->isEmpty()); m_overlay->setVisible(!m_overlay->isEmpty());
} else if (kind == SnippetPlaceholderSelection) { } else if (kind == TextEditorWidget::SnippetPlaceholderSelection) {
d->m_snippetOverlay->mangle(); m_snippetOverlay->mangle();
d->m_snippetOverlay->clear(); m_snippetOverlay->clear();
foreach (const QTextEdit::ExtraSelection &selection, d->m_extraSelections[kind]) { foreach (const QTextEdit::ExtraSelection &selection, m_extraSelections[kind]) {
d->m_snippetOverlay->addOverlaySelection(selection.cursor, m_snippetOverlay->addOverlaySelection(selection.cursor,
selection.format.background().color(), selection.format.background().color(),
selection.format.background().color(), selection.format.background().color(),
TextEditorOverlay::ExpandBegin); TextEditorOverlay::ExpandBegin);
} }
d->m_snippetOverlay->mapEquivalentSelections(); m_snippetOverlay->mapEquivalentSelections();
d->m_snippetOverlay->setVisible(!d->m_snippetOverlay->isEmpty()); m_snippetOverlay->setVisible(!m_snippetOverlay->isEmpty());
} else { } else {
QList<QTextEdit::ExtraSelection> all; QList<QTextEdit::ExtraSelection> all;
for (int i = 0; i < NExtraSelectionKinds; ++i) { for (auto i = m_extraSelections.constBegin(); i != m_extraSelections.constEnd(); ++i) {
if (i == CodeSemanticsSelection || i == SnippetPlaceholderSelection) if (i.key() == TextEditorWidget::CodeSemanticsSelection
|| i.key() == TextEditorWidget::SnippetPlaceholderSelection)
continue; continue;
all += d->m_extraSelections[i]; all += i.value();
} }
QPlainTextEdit::setExtraSelections(all); q->QPlainTextEdit::setExtraSelections(all);
} }
} }
void TextEditorWidget::setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections)
{
d->setExtraSelections(kind, selections);
}
QList<QTextEdit::ExtraSelection> TextEditorWidget::extraSelections(ExtraSelectionKind kind) const QList<QTextEdit::ExtraSelection> TextEditorWidget::extraSelections(ExtraSelectionKind kind) const
{ {
return d->m_extraSelections[kind]; return d->m_extraSelections[kind];
} }
void TextEditorWidget::setExtraSelections(Core::Id kind, const QList<QTextEdit::ExtraSelection> &selections)
{
// Private Core:Id identifiers from the 0-1000 range cannot be used here, they conflict with ExtraSelectionKind
QTC_ASSERT(kind.uniqueIdentifier() >= NExtraSelectionKinds, return);
d->setExtraSelections(kind.uniqueIdentifier(), selections);
}
QList<QTextEdit::ExtraSelection> TextEditorWidget::extraSelections(Core::Id kind) const
{
// Private Core:Id identifiers from the 0-1000 range cannot be used here, they conflict with ExtraSelectionKind
QTC_ASSERT(kind.uniqueIdentifier() >= NExtraSelectionKinds, return QList<QTextEdit::ExtraSelection>());
return d->m_extraSelections[kind.uniqueIdentifier()];
}
QString TextEditorWidget::extraSelectionTooltip(int pos) const QString TextEditorWidget::extraSelectionTooltip(int pos) const
{ {
QList<QTextEdit::ExtraSelection> all; QList<QTextEdit::ExtraSelection> all;
for (int i = 0; i < NExtraSelectionKinds; ++i) { foreach (const QList<QTextEdit::ExtraSelection> &sel, d->m_extraSelections) {
const QList<QTextEdit::ExtraSelection> &sel = d->m_extraSelections[i];
for (int j = 0; j < sel.size(); ++j) { for (int j = 0; j < sel.size(); ++j) {
const QTextEdit::ExtraSelection &s = sel.at(j); const QTextEdit::ExtraSelection &s = sel.at(j);
if (s.cursor.selectionStart() <= pos if (s.cursor.selectionStart() <= pos

View File

@@ -357,6 +357,8 @@ public:
}; };
void setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections); void setExtraSelections(ExtraSelectionKind kind, const QList<QTextEdit::ExtraSelection> &selections);
QList<QTextEdit::ExtraSelection> extraSelections(ExtraSelectionKind kind) const; QList<QTextEdit::ExtraSelection> extraSelections(ExtraSelectionKind kind) const;
void setExtraSelections(Core::Id kind, const QList<QTextEdit::ExtraSelection> &selections);
QList<QTextEdit::ExtraSelection> extraSelections(Core::Id kind) const;
QString extraSelectionTooltip(int pos) const; QString extraSelectionTooltip(int pos) const;
RefactorMarkers refactorMarkers() const; RefactorMarkers refactorMarkers() const;