Editor: Allow to hide annotations for a group of text marks

The hiding is not persistent, so on the next Qt Creator start all
annotations are visible again. This is meant to quickly get rid of
annotations if there are to many irrelevant of a specific kind.

Change-Id: I4862e56e0f5624f30aadda26efc9dea672ab1f57
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2023-01-09 13:14:39 +01:00
parent 6415eef6af
commit baa1e3c2e1
26 changed files with 159 additions and 47 deletions

View File

@@ -3,13 +3,14 @@
#include "testeditormark.h"
#include "autotesttr.h"
#include "testresultspane.h"
namespace Autotest {
namespace Internal {
TestEditorMark::TestEditorMark(QPersistentModelIndex item, const Utils::FilePath &file, int line)
: TextEditor::TextMark(file, line, Utils::Id(Constants::TASK_MARK_ID)),
: TextEditor::TextMark(file, line, {Tr::tr("Auto Test"), Utils::Id(Constants::TASK_MARK_ID)}),
m_item(item)
{
}

View File

@@ -16,7 +16,7 @@ using namespace Utils;
namespace Bookmarks::Internal {
Bookmark::Bookmark(int lineNumber, BookmarkManager *manager) :
TextMark(FilePath(), lineNumber, Constants::BOOKMARKS_TEXT_MARK_CATEGORY),
TextMark(FilePath(), lineNumber, {Tr::tr("Bookmark"), Constants::BOOKMARKS_TEXT_MARK_CATEGORY}),
m_manager(manager)
{
setColor(Theme::Bookmarks_TextMarkColor);

View File

@@ -271,9 +271,12 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
const Diagnostic &diagnostic,
bool isProjectFile,
ClangdClient *client)
: TextEditor::TextMark(filePath, int(diagnostic.range().start().line() + 1), client->id())
: TextEditor::TextMark(filePath,
int(diagnostic.range().start().line() + 1),
{client->name(), client->id()})
, m_lspDiagnostic(diagnostic)
, m_diagnostic(convertDiagnostic(ClangdDiagnostic(diagnostic), filePath, client->hostPathMapper()))
, m_diagnostic(
convertDiagnostic(ClangdDiagnostic(diagnostic), filePath, client->hostPathMapper()))
, m_client(client)
{
setSettingsPage(CppEditor::Constants::CPP_CLANGD_SETTINGS_ID);

View File

@@ -4,6 +4,7 @@
#include "diagnosticmark.h"
#include "clangtoolsconstants.h"
#include "clangtoolstr.h"
#include "clangtoolsutils.h"
#include "diagnosticconfigswidget.h"
@@ -18,7 +19,7 @@ namespace Internal {
DiagnosticMark::DiagnosticMark(const Diagnostic &diagnostic)
: TextEditor::TextMark(diagnostic.location.filePath,
diagnostic.location.line,
Utils::Id(Constants::DIAGNOSTIC_MARK_ID))
{Tr::tr("Clang Tools"), Utils::Id(Constants::DIAGNOSTIC_MARK_ID)})
, m_diagnostic(diagnostic)
{
setSettingsPage(Constants::SETTINGS_PAGE_ID);

View File

@@ -70,7 +70,7 @@ Diagnostics DocumentClangToolRunner::diagnosticsAtLine(int lineNumber) const
Diagnostics diagnostics;
if (auto textDocument = qobject_cast<TextEditor::TextDocument *>(m_document)) {
for (auto mark : textDocument->marksAt(lineNumber)) {
if (mark->category() == Constants::DIAGNOSTIC_MARK_ID)
if (mark->category().id == Constants::DIAGNOSTIC_MARK_ID)
diagnostics << static_cast<DiagnosticMark *>(mark)->diagnostic();
}
}

View File

@@ -131,7 +131,7 @@ class CocoTextMark : public TextEditor::TextMark
{
public:
CocoTextMark(const FilePath &fileName, const CocoDiagnostic &diag, const Id &clientId)
: TextEditor::TextMark(fileName, diag.range().start().line() + 1, clientId)
: TextEditor::TextMark(fileName, diag.range().start().line() + 1, {"Coco", clientId})
, m_severity(diag.cocoSeverity())
{
setLineAnnotation(diag.message());

View File

@@ -4,6 +4,7 @@
#include "cppcheckconstants.h"
#include "cppcheckdiagnostic.h"
#include "cppchecktextmark.h"
#include "cppchecktr.h"
#include <utils/stringutils.h>
#include <utils/utilsicons.h>
@@ -44,11 +45,13 @@ static Visual getVisual(Diagnostic::Severity type)
return visuals.value(type, {Color::IconsInfoColor, Priority::LowPriority, Icons::INFO.icon()});
}
CppcheckTextMark::CppcheckTextMark (const Diagnostic &diagnostic)
: TextMark(diagnostic.fileName, diagnostic.lineNumber, Id(Constants::TEXTMARK_CATEGORY_ID)),
m_severity(diagnostic.severity),
m_checkId(diagnostic.checkId),
m_message(diagnostic.message)
CppcheckTextMark::CppcheckTextMark(const Diagnostic &diagnostic)
: TextEditor::TextMark(diagnostic.fileName,
diagnostic.lineNumber,
{Tr::tr("Cppcheck"), Utils::Id(Constants::TEXTMARK_CATEGORY_ID)})
, m_severity(diagnostic.severity)
, m_checkId(diagnostic.checkId)
, m_message(diagnostic.message)
{
const Visual visual = getVisual(diagnostic.severity);
setPriority(visual.priority);

View File

@@ -11,6 +11,7 @@
#include "cppmodelmanager.h"
#include "cppeditorconstants.h"
#include "cppeditorplugin.h"
#include "cppeditortr.h"
#include "cpphighlighter.h"
#include "cppquickfixassistant.h"
@@ -503,7 +504,7 @@ void CppEditorDocument::onDiagnosticsChanged(const QString &fileName, const QStr
[&category, &diagnostic](TextMark *existing) {
return (diagnostic.line() == existing->lineNumber()
&& diagnostic.text() == existing->lineAnnotation()
&& category == existing->category());
&& category == existing->category().id);
});
if (it != std::end(removedMarks)) {
@@ -511,7 +512,9 @@ void CppEditorDocument::onDiagnosticsChanged(const QString &fileName, const QStr
continue;
}
auto mark = new TextMark(filePath(), diagnostic.line(), category);
auto mark = new TextMark(filePath(),
diagnostic.line(),
{Tr::tr("C++ Code Model"), category});
mark->setLineAnnotation(diagnostic.text());
mark->setToolTip(diagnostic.text());
@@ -526,7 +529,7 @@ void CppEditorDocument::onDiagnosticsChanged(const QString &fileName, const QStr
}
for (auto it = removedMarks.begin(); it != removedMarks.end(); ++it) {
if ((*it)->category() == category) {
if ((*it)->category().id == category) {
removeMark(*it);
delete *it;
}

View File

@@ -68,7 +68,10 @@ class BreakpointMarker : public TextEditor::TextMark
{
public:
BreakpointMarker(const Breakpoint &bp, const FilePath &fileName, int lineNumber)
: TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY_BREAKPOINT), m_bp(bp)
: TextMark(fileName,
lineNumber,
{Tr::tr("Breakpoint"), Constants::TEXT_MARK_CATEGORY_BREAKPOINT})
, m_bp(bp)
{
setColor(Theme::Debugger_Breakpoint_TextMarkColor);
setDefaultToolTip(Tr::tr("Breakpoint"));
@@ -126,7 +129,10 @@ class GlobalBreakpointMarker : public TextEditor::TextMark
{
public:
GlobalBreakpointMarker(GlobalBreakpoint gbp, const FilePath &fileName, int lineNumber)
: TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY_BREAKPOINT), m_gbp(gbp)
: TextMark(fileName,
lineNumber,
{Tr::tr("Breakpoint"), Constants::TEXT_MARK_CATEGORY_BREAKPOINT})
, m_gbp(gbp)
{
setDefaultToolTip(Tr::tr("Breakpoint"));
setPriority(TextEditor::TextMark::NormalPriority);

View File

@@ -151,9 +151,9 @@ Location::Location(const StackFrame &frame, bool marker)
m_from = frame.module;
}
LocationMark::LocationMark(DebuggerEngine *engine, const FilePath &file, int line)
: TextMark(file, line, Constants::TEXT_MARK_CATEGORY_LOCATION), m_engine(engine)
: TextMark(file, line, {Tr::tr("Debugger Location"), Constants::TEXT_MARK_CATEGORY_LOCATION})
, m_engine(engine)
{
setPriority(TextMark::HighPriority);
setIsLocationMarker(true);

View File

@@ -7,6 +7,7 @@
#include "debuggeractions.h"
#include "debuggerengine.h"
#include "debuggerinternalconstants.h"
#include "debuggertr.h"
#include "disassemblerlines.h"
#include "sourceutils.h"
@@ -42,7 +43,10 @@ class DisassemblerBreakpointMarker : public TextMark
{
public:
DisassemblerBreakpointMarker(const Breakpoint &bp, int lineNumber)
: TextMark(Utils::FilePath(), lineNumber, Constants::TEXT_MARK_CATEGORY_BREAKPOINT), m_bp(bp)
: TextMark(Utils::FilePath(),
lineNumber,
{Tr::tr("Breakpoint"), Constants::TEXT_MARK_CATEGORY_BREAKPOINT})
, m_bp(bp)
{
setIcon(bp->icon());
setPriority(TextMark::NormalPriority);

View File

@@ -6,6 +6,7 @@
#include "debuggerengine.h"
#include "debuggericons.h"
#include "debuggerinternalconstants.h"
#include "debuggertr.h"
#include "stackhandler.h"
#include <coreplugin/editormanager/editormanager.h>
@@ -114,8 +115,10 @@ void SourceAgent::updateLocationMarker()
if (d->engine->stackHandler()->currentFrame().file == Utils::FilePath::fromString(d->path)) {
int lineNumber = d->engine->stackHandler()->currentFrame().line;
d->locationMark = new TextMark(Utils::FilePath(), lineNumber,
Constants::TEXT_MARK_CATEGORY_LOCATION);
d->locationMark = new TextMark(Utils::FilePath(),
lineNumber,
{Tr::tr("Debugger Location"),
Constants::TEXT_MARK_CATEGORY_LOCATION});
d->locationMark->setIcon(Icons::LOCATION.icon());
d->locationMark->setPriority(TextMark::HighPriority);

View File

@@ -5,6 +5,7 @@
#include "debuggerinternalconstants.h"
#include "debuggerengine.h"
#include "debuggertr.h"
#include "disassemblerlines.h"
#include "watchdata.h"
#include "watchutils.h"
@@ -333,7 +334,9 @@ class DebuggerValueMark : public TextEditor::TextMark
{
public:
DebuggerValueMark(const FilePath &fileName, int lineNumber, const QString &value)
: TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY_VALUE)
: TextMark(fileName,
lineNumber,
{Tr::tr("Debugger Value"), Constants::TEXT_MARK_CATEGORY_VALUE})
{
setPriority(TextEditor::TextMark::HighPriority);
setToolTipProvider([] { return QString(); });

View File

@@ -195,7 +195,9 @@ class BlameMark : public TextEditor::TextMark
{
public:
BlameMark(const FilePath &fileName, int lineNumber, const CommitInfo &info)
: TextEditor::TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY_BLAME)
: TextEditor::TextMark(fileName,
lineNumber,
{Tr::tr("Git Blame"), Constants::TEXT_MARK_CATEGORY_BLAME})
{
const QString text = info.shortAuthor + " " + info.authorTime.toString("yyyy-MM-dd");

View File

@@ -30,8 +30,10 @@ namespace LanguageClient {
class TextMark : public TextEditor::TextMark
{
public:
TextMark(const FilePath &fileName, const Diagnostic &diag, const Id &clientId)
: TextEditor::TextMark(fileName, diag.range().start().line() + 1, clientId)
TextMark(const FilePath &fileName, const Diagnostic &diag, const Client *client)
: TextEditor::TextMark(fileName,
diag.range().start().line() + 1,
{client->name(), client->id()})
{
setLineAnnotation(diag.message());
setToolTip(diag.message());
@@ -121,7 +123,7 @@ TextEditor::TextMark *DiagnosticManager::createTextMark(const FilePath &filePath
{
static const auto icon = QIcon::fromTheme("edit-copy", Utils::Icons::COPY.icon());
static const QString tooltip = tr("Copy to Clipboard");
auto mark = new TextMark(filePath, diagnostic, m_client->id());
auto mark = new TextMark(filePath, diagnostic, m_client);
mark->setActionsProvider([text = diagnostic.message()] {
QAction *action = new QAction();
action->setIcon(icon);

View File

@@ -1061,8 +1061,11 @@ TextEditor::BaseTextEditor *jsonEditor()
widget->setCodeFoldingSupported(false);
QObject::connect(document, &TextDocument::contentsChanged, widget, [document](){
const Utils::Id jsonMarkId("LanguageClient.JsonTextMarkId");
qDeleteAll(
Utils::filtered(document->marks(), Utils::equal(&TextMark::category, jsonMarkId)));
const TextMarks marks = document->marks();
for (TextMark *mark : marks) {
if (mark->category().id == jsonMarkId)
delete mark;
}
const QString content = document->plainText().trimmed();
if (content.isEmpty())
return;
@@ -1074,7 +1077,9 @@ TextEditor::BaseTextEditor *jsonEditor()
= Utils::Text::convertPosition(document->document(), error.offset);
if (!lineColumn.has_value())
return;
auto mark = new TextMark(Utils::FilePath(), lineColumn->line, jsonMarkId);
auto mark = new TextMark(Utils::FilePath(),
lineColumn->line,
{Tr::tr("JSON Error"), jsonMarkId});
mark->setLineAnnotation(error.errorString());
mark->setColor(Utils::Theme::CodeModel_Error_TextMarkColor);
mark->setIcon(Utils::Icons::CODEMODEL_ERROR.icon());

View File

@@ -3,6 +3,7 @@
#include "taskhub.h"
#include "projectexplorerconstants.h"
#include "projectexplorertr.h"
#include <coreplugin/coreicons.h>
#include <coreplugin/ioutputpane.h>
@@ -25,15 +26,15 @@ const char TASK_MARK_ERROR[] = "Task.Mark.Error";
static TaskHub *m_instance = nullptr;
QVector<Utils::Id> TaskHub::m_registeredCategories;
static Utils::Id categoryForType(Task::TaskType type)
static TextEditor::TextMarkCategory categoryForType(Task::TaskType type)
{
switch (type) {
case Task::Error:
return TASK_MARK_ERROR;
return {Tr::tr("Taskhub Error", TASK_MARK_ERROR)};
case Task::Warning:
return TASK_MARK_WARNING;
return {Tr::tr("Taskhub Warning"), TASK_MARK_WARNING};
default:
return Utils::Id();
return {};
}
}

View File

@@ -33,9 +33,10 @@ static bool isWarning(QmlJS::Severity::Enum kind)
return false;
}
static Utils::Id cartegoryForSeverity(QmlJS::Severity::Enum kind)
static TextMarkCategory cartegoryForSeverity(QmlJS::Severity::Enum kind)
{
return isWarning(kind) ? QMLJS_WARNING : QMLJS_ERROR;
return isWarning(kind) ? TextMarkCategory{"QML Warning", QMLJS_WARNING}
: TextMarkCategory{"QML Error", QMLJS_ERROR};
}
QmlJSTextMark::QmlJSTextMark(const FilePath &fileName,

View File

@@ -6,6 +6,7 @@
#include "qmlprofilerconstants.h"
#include "qmlprofilerviewmanager.h"
#include "qmlprofilerstatisticsview.h"
#include "qmlprofilertr.h"
#include <QLabel>
#include <QLayout>
@@ -18,7 +19,7 @@ namespace Internal {
QmlProfilerTextMark::QmlProfilerTextMark(QmlProfilerViewManager *viewManager, int typeId,
const FilePath &fileName, int lineNumber)
: TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY)
: TextMark(fileName, lineNumber, {Tr::tr("QML Profiler"), Constants::TEXT_MARK_CATEGORY})
, m_viewManager(viewManager)
{
addTypeId(typeId);

View File

@@ -87,7 +87,7 @@ class SquishLocationMark : public TextEditor::TextMark
{
public:
SquishLocationMark(const FilePath &filePath, int line)
: TextEditor::TextMark(filePath, line, Id("Squish.LocationMark"))
: TextEditor::TextMark(filePath, line, {Tr::tr("Squish"), Id("Squish.LocationMark")})
{
setIsLocationMarker(true);
setIcon(Debugger::Icons::LOCATION.icon());

View File

@@ -1065,6 +1065,47 @@ void TextDocument::removeMarkFromMarksCache(TextMark *mark)
documentLayout->requestExtraAreaUpdate();
}
static QSet<Id> &hiddenMarksIds()
{
static QSet<Id> ids;
return ids;
}
void TextDocument::temporaryHideMarksAnnotation(const Utils::Id &category)
{
hiddenMarksIds().insert(category);
const QList<IDocument *> documents = DocumentModel::openedDocuments();
for (auto document : documents) {
if (auto textDocument = qobject_cast<TextDocument*>(document)) {
const TextMarks marks = textDocument->marks();
for (const auto mark : marks) {
if (mark->category().id == category)
mark->updateMarker();
}
}
}
}
void TextDocument::showMarksAnnotation(const Utils::Id &category)
{
hiddenMarksIds().remove(category);
const QList<IDocument *> documents = DocumentModel::openedDocuments();
for (auto document : documents) {
if (auto textDocument = qobject_cast<TextDocument*>(document)) {
const TextMarks marks = textDocument->marks();
for (const auto mark : marks) {
if (mark->category().id == category)
mark->updateMarker();
}
}
}
}
bool TextDocument::marksAnnotationHidden(const Utils::Id &category)
{
return hiddenMarksIds().contains(category);
}
void TextDocument::removeMark(TextMark *mark)
{
QTextBlock block = d->m_document.findBlockByNumber(mark->lineNumber() - 1);

View File

@@ -95,6 +95,9 @@ public:
void updateMark(TextMark *mark);
void moveMark(TextMark *mark, int previousLine);
void removeMarkFromMarksCache(TextMark *mark);
static void temporaryHideMarksAnnotation(const Utils::Id &category);
static void showMarksAnnotation(const Utils::Id &category);
static bool marksAnnotationHidden(const Utils::Id &category);
// IDocument implementation.
bool save(QString *errorString, const Utils::FilePath &filePath, bool autoSave) override;

View File

@@ -4043,8 +4043,9 @@ void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data,
if (!blockUserData)
return;
TextMarks marks = Utils::filtered(blockUserData->marks(), [](const TextMark* mark){
return !mark->lineAnnotation().isEmpty() && mark->isVisible();
TextMarks marks = Utils::filtered(blockUserData->marks(), [](const TextMark *mark) {
return !mark->lineAnnotation().isEmpty() && mark->isVisible()
&& !TextDocument::marksAnnotationHidden(mark->category().id);
});
const bool annotationsVisible = !marks.isEmpty();
@@ -6603,7 +6604,7 @@ void TextEditorWidgetPrivate::addSearchResultsToScrollBar(const QVector<SearchRe
Highlight markToHighlight(TextMark *mark, int lineNumber)
{
return Highlight(mark->category(),
return Highlight(mark->category().id,
lineNumber,
mark->color().value_or(Utils::Theme::TextColorNormal),
textMarkPrioToScrollBarPrio(mark->priority()));

View File

@@ -7,6 +7,7 @@
#include "textdocument.h"
#include "texteditor.h"
#include "texteditorplugin.h"
#include "texteditortr.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/documentmanager.h>
@@ -62,7 +63,7 @@ private:
TextMarkRegistry *m_instance = nullptr;
TextMark::TextMark(const FilePath &fileName, int lineNumber, Id category)
TextMark::TextMark(const FilePath &fileName, int lineNumber, TextMarkCategory category)
: m_fileName(fileName)
, m_lineNumber(lineNumber)
, m_visible(true)
@@ -278,6 +279,23 @@ void TextMark::addToToolTipLayout(QGridLayout *target) const
QList<QAction *> actions{m_actions.begin(), m_actions.end()};
if (m_actionsProvider)
actions = m_actionsProvider();
if (m_category.id.isValid() && !m_lineAnnotation.isEmpty()) {
auto visibilityAction = new QAction;
const bool isHidden = TextDocument::marksAnnotationHidden(m_category.id);
visibilityAction->setIcon(Utils::Icons::EYE_OPEN_TOOLBAR.icon());
const QString tooltip = (isHidden ? Tr::tr("Show inline annotations for %1")
: Tr::tr("Tempoary hide inline annotations for %1"))
.arg(m_category.displayName);
visibilityAction->setToolTip(tooltip);
auto callback = [id = m_category.id, isHidden] {
if (isHidden)
TextDocument::showMarksAnnotation(id);
else
TextDocument::temporaryHideMarksAnnotation(id);
};
QObject::connect(visibilityAction, &QAction::triggered, Core::ICore::instance(), callback);
actions.append(visibilityAction);
}
if (m_settingsPage.isValid()) {
auto settingsAction = new QAction;
settingsAction->setIcon(Utils::Icons::SETTINGS_TOOLBAR.icon());

View File

@@ -28,13 +28,20 @@ namespace TextEditor {
class TextDocument;
class TextMarkCategory
{
public:
QString displayName;
Utils::Id id;
};
class TEXTEDITOR_EXPORT TextMark
{
Q_DECLARE_TR_FUNCTIONS(TextEditor::TextMark)
public:
TextMark(const Utils::FilePath &fileName,
int lineNumber,
Utils::Id category);
TextMarkCategory category);
TextMark() = delete;
virtual ~TextMark();
@@ -89,7 +96,7 @@ public:
void setPriority(Priority prioriy);
bool isVisible() const;
void setVisible(bool isVisible);
Utils::Id category() const { return m_category; }
TextMarkCategory category() const { return m_category; }
std::optional<Utils::Theme::Color> color() const;
void setColor(const Utils::Theme::Color &color);
@@ -129,7 +136,7 @@ private:
std::function<QIcon()> m_iconProvider;
std::optional<Utils::Theme::Color> m_color;
bool m_visible = false;
Utils::Id m_category;
TextMarkCategory m_category;
QString m_lineAnnotation;
QString m_toolTip;
std::function<QString()> m_toolTipProvider;

View File

@@ -23,8 +23,11 @@ using namespace Valgrind::Callgrind;
namespace Constants { const char CALLGRIND_TEXT_MARK_CATEGORY[] = "Callgrind.Textmark"; }
CallgrindTextMark::CallgrindTextMark(const QPersistentModelIndex &index,
const FilePath &fileName, int lineNumber)
: TextEditor::TextMark(fileName, lineNumber, Constants::CALLGRIND_TEXT_MARK_CATEGORY)
const FilePath &fileName,
int lineNumber)
: TextEditor::TextMark(fileName,
lineNumber,
{Tr::tr("Callgrind"), Constants::CALLGRIND_TEXT_MARK_CATEGORY})
, m_modelIndex(index)
{
setPriority(TextEditor::TextMark::HighPriority);