From c5e43d86d12ce51c9035159a8acd86800fdf69bc Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 31 Jan 2019 13:16:44 +0100 Subject: [PATCH] Clang: Make diagnostic tooltips consistent Fix that triggering a diagnostic tooltip from the diagnostic location/range itself (underlined text) did not show the icon on the left and the actions/toolbuttons on the right in the tooltip. Instead of showing the tooltip content itself, request the tooltip for the corresponding text mark to get the extra decoration and actions. Change-Id: I5e94aca117a761f7a798d4f4b33db6e386e54d84 Reviewed-by: David Schulz Reviewed-by: Ivan Donchevskii --- .../clangcodemodel/clangdiagnosticmanager.cpp | 52 +++---------------- .../clangcodemodel/clangdiagnosticmanager.h | 3 +- .../clangeditordocumentprocessor.cpp | 28 +++------- .../clangeditordocumentprocessor.h | 4 +- .../clangcodemodel/clanghoverhandler.cpp | 42 +++++---------- src/plugins/clangcodemodel/clangtextmark.h | 2 + .../cpptools/baseeditordocumentprocessor.cpp | 9 ---- .../cpptools/baseeditordocumentprocessor.h | 2 - src/plugins/texteditor/texteditor.cpp | 7 +++ src/plugins/texteditor/texteditor.h | 5 ++ 10 files changed, 43 insertions(+), 111 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp index 72049242dc5..8bc0b925c29 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp @@ -210,36 +210,6 @@ bool isDiagnosticAtLocation(const ClangBackEnd::DiagnosticContainer &diagnostic, return isDiagnosticRelatedToLocation(diagnostic, {cursorRange}, line, column); } -QVector -filteredDiagnosticsAtLocation(const QVector &diagnostics, - uint line, - uint column, - QTextDocument *textDocument) -{ - QVector filteredDiagnostics; - - foreach (const auto &diagnostic, diagnostics) { - if (isDiagnosticAtLocation(diagnostic, line, column, textDocument)) - filteredDiagnostics.append(diagnostic); - } - - return filteredDiagnostics; -} - -bool editorDocumentProcessorHasDiagnosticAt( - const QVector &diagnostics, - uint line, - uint column, - QTextDocument *textDocument) -{ - foreach (const auto &diagnostic, diagnostics) { - if (isDiagnosticAtLocation(diagnostic, line, column, textDocument)) - return true; - } - - return false; -} - QTextCursor cursorAtLastPositionOfLine(QTextDocument *textDocument, int lineNumber) { const QTextBlock textBlock = textDocument->findBlockByNumber(lineNumber - 1); @@ -399,24 +369,16 @@ TextEditor::RefactorMarkers ClangDiagnosticManager::takeFixItAvailableMarkers() return fixItAvailableMarkers; } -bool ClangDiagnosticManager::hasDiagnosticsAt(uint line, uint column) const +TextEditor::TextMarks ClangDiagnosticManager::diagnosticTextMarksAt(uint line, uint column) const { - QTextDocument *textDocument = m_textDocument->document(); + QList textMarks; - return editorDocumentProcessorHasDiagnosticAt(m_errorDiagnostics, line, column, textDocument) - || editorDocumentProcessorHasDiagnosticAt(m_warningDiagnostics, line, column, textDocument); -} + for (ClangTextMark *textMark : m_clangTextMarks) { + if (isDiagnosticAtLocation(textMark->diagnostic(), line, column, m_textDocument->document())) + textMarks << textMark; + } -QVector -ClangDiagnosticManager::diagnosticsAt(uint line, uint column) const -{ - QTextDocument *textDocument = m_textDocument->document(); - - QVector diagnostics; - diagnostics += filteredDiagnosticsAtLocation(m_errorDiagnostics, line, column, textDocument); - diagnostics += filteredDiagnosticsAtLocation(m_warningDiagnostics, line, column, textDocument); - - return diagnostics; + return textMarks; } void ClangDiagnosticManager::invalidateDiagnostics() diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.h b/src/plugins/clangcodemodel/clangdiagnosticmanager.h index d0c31bf68bc..2996936ed08 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.h +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.h @@ -57,8 +57,7 @@ public: QList takeExtraSelections(); TextEditor::RefactorMarkers takeFixItAvailableMarkers(); - bool hasDiagnosticsAt(uint line, uint column) const; - QVector diagnosticsAt(uint line, uint column) const; + QList diagnosticTextMarksAt(uint line, uint column) const; void invalidateDiagnostics(); void clearDiagnosticsWithFixIts(); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 8e1d06da6c6..40d7e4e63fe 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -48,7 +48,6 @@ #include #include -#include #include #include #include @@ -292,27 +291,6 @@ TextEditor::QuickFixOperations ClangEditorDocumentProcessor::extraRefactoringOpe return extractor.extract(assistInterface.fileName(), currentLine(assistInterface)); } -bool ClangEditorDocumentProcessor::hasDiagnosticsAt(uint line, uint column) const -{ - return m_diagnosticManager.hasDiagnosticsAt(line, column); -} - -void ClangEditorDocumentProcessor::addDiagnosticToolTipToLayout(uint line, - uint column, - QLayout *target) const -{ - using Internal::ClangDiagnosticWidget; - - const QVector diagnostics - = m_diagnosticManager.diagnosticsAt(line, column); - - target->addWidget( - ClangDiagnosticWidget::createWidget(diagnostics, ClangDiagnosticWidget::ToolTip)); - auto link = TextEditor::DisplaySettings::createAnnotationSettingsLink(); - target->addWidget(link); - target->setAlignment(link, Qt::AlignRight); -} - void ClangEditorDocumentProcessor::editorDocumentTimerRestarted() { m_updateBackendDocumentTimer.stop(); // Wait for the next call to run(). @@ -323,6 +301,12 @@ void ClangEditorDocumentProcessor::invalidateDiagnostics() m_diagnosticManager.invalidateDiagnostics(); } +TextEditor::TextMarks ClangEditorDocumentProcessor::diagnosticTextMarksAt(uint line, + uint column) const +{ + return m_diagnosticManager.diagnosticTextMarksAt(line, column); +} + void ClangEditorDocumentProcessor::setParserConfig( const CppTools::BaseEditorDocumentParser::Configuration &config) { diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index a7da1bb2e1c..8e0ee003d30 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -83,8 +83,8 @@ public: extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override; void invalidateDiagnostics() override; - bool hasDiagnosticsAt(uint line, uint column) const override; - void addDiagnosticToolTipToLayout(uint line, uint column, QLayout *target) const override; + + TextEditor::TextMarks diagnosticTextMarksAt(uint line, uint column) const; void editorDocumentTimerRestarted() override; diff --git a/src/plugins/clangcodemodel/clanghoverhandler.cpp b/src/plugins/clangcodemodel/clanghoverhandler.cpp index da9f974adb6..58f414d9f11 100644 --- a/src/plugins/clangcodemodel/clanghoverhandler.cpp +++ b/src/plugins/clangcodemodel/clanghoverhandler.cpp @@ -25,8 +25,9 @@ #include "clanghoverhandler.h" +#include "clangeditordocumentprocessor.h" + #include -#include #include #include #include @@ -61,32 +62,17 @@ static CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor(TextEditor return nullptr; } -static bool editorDocumentProcessorHasDiagnosticAt(TextEditorWidget *editorWidget, int pos) +static TextMarks diagnosticTextMarksAt(TextEditorWidget *editorWidget, int position) { - if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) { - int line, column; - if (Utils::Text::convertPosition(editorWidget->document(), pos, &line, &column)) - return processor->hasDiagnosticsAt(line, column); - } + const auto processor = qobject_cast( + editorDocumentProcessor(editorWidget)); + QTC_ASSERT(processor, return TextMarks()); - return false; -} + int line, column; + const bool ok = Utils::Text::convertPosition(editorWidget->document(), position, &line, &column); + QTC_ASSERT(ok, return TextMarks()); -static void processWithEditorDocumentProcessor(TextEditorWidget *editorWidget, - const QPoint &point, - int position, - const Core::HelpItem &helpItem) -{ - if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) { - int line, column; - if (Utils::Text::convertPosition(editorWidget->document(), position, &line, &column)) { - auto layout = new QVBoxLayout; - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(2); - processor->addDiagnosticToolTipToLayout(line, column, layout); - Utils::ToolTip::show(point, layout, editorWidget, qVariantFromValue(helpItem)); - } - } + return processor->diagnosticTextMarksAt(line, column); } static QFuture editorDocumentHandlesToolTipInfo( @@ -189,7 +175,7 @@ void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget, m_cursorPosition = -1; // Check for diagnostics (sync) - if (!isContextHelpRequest() && editorDocumentProcessorHasDiagnosticAt(editorWidget, pos)) { + if (!isContextHelpRequest() && !diagnosticTextMarksAt(editorWidget, pos).isEmpty()) { qCDebug(hoverLog) << "Checking for diagnostic at" << pos; setPriority(Priority_Diagnostic); m_cursorPosition = pos; @@ -275,10 +261,8 @@ void ClangHoverHandler::operateTooltip(TextEditor::TextEditorWidget *editorWidge const QPoint &point) { if (priority() == Priority_Diagnostic) { - processWithEditorDocumentProcessor(editorWidget, - point, - m_cursorPosition, - lastHelpItemIdentified()); + const TextMarks textMarks = diagnosticTextMarksAt(editorWidget, m_cursorPosition); + editorWidget->showTextMarksToolTip(point, textMarks); return; } diff --git a/src/plugins/clangcodemodel/clangtextmark.h b/src/plugins/clangcodemodel/clangtextmark.h index 1301cd200b7..00cadfb5c82 100644 --- a/src/plugins/clangcodemodel/clangtextmark.h +++ b/src/plugins/clangcodemodel/clangtextmark.h @@ -44,7 +44,9 @@ public: const RemovedFromEditorHandler &removedHandler, bool fullVisualization); + ClangBackEnd::DiagnosticContainer diagnostic() const { return m_diagnostic; } void updateIcon(bool valid = true); + private: bool addToolTipContent(QLayout *target) const override; void removedFromEditor() override; diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.cpp b/src/plugins/cpptools/baseeditordocumentprocessor.cpp index 8c869ee51f7..6bd91fc5640 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.cpp +++ b/src/plugins/cpptools/baseeditordocumentprocessor.cpp @@ -72,15 +72,6 @@ BaseEditorDocumentProcessor::extraRefactoringOperations(const TextEditor::Assist return TextEditor::QuickFixOperations(); } -bool BaseEditorDocumentProcessor::hasDiagnosticsAt(uint, uint) const -{ - return false; -} - -void BaseEditorDocumentProcessor::addDiagnosticToolTipToLayout(uint, uint, QLayout *) const -{ -} - void BaseEditorDocumentProcessor::editorDocumentTimerRestarted() { } diff --git a/src/plugins/cpptools/baseeditordocumentprocessor.h b/src/plugins/cpptools/baseeditordocumentprocessor.h index efdb29a9f8f..cf08f7b5c40 100644 --- a/src/plugins/cpptools/baseeditordocumentprocessor.h +++ b/src/plugins/cpptools/baseeditordocumentprocessor.h @@ -81,8 +81,6 @@ public: extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface); virtual void invalidateDiagnostics(); - virtual bool hasDiagnosticsAt(uint line, uint column) const; - virtual void addDiagnosticToolTipToLayout(uint line, uint column, QLayout *layout) const; virtual void editorDocumentTimerRestarted(); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index acf9072bc25..977c224dcef 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -3555,6 +3555,13 @@ QPoint TextEditorWidget::toolTipPosition(const QTextCursor &c) const return cursorPos + QPoint(d->m_extraArea->width(), HostOsInfo::isWindowsHost() ? -24 : -16); } +void TextEditorWidget::showTextMarksToolTip(const QPoint &pos, + const TextMarks &marks, + const TextMark *mainTextMark) const +{ + d->showTextMarksToolTip(pos, marks, mainTextMark); +} + void TextEditorWidgetPrivate::processTooltipRequest(const QTextCursor &c) { const QPoint toolTipPoint = q->toolTipPosition(c); diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 4eaae7b5bb8..5cf1ecbd1a3 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -59,6 +59,7 @@ class HighlightScrollBarController; namespace TextEditor { class TextDocument; +class TextMark; class BaseHoverHandler; class RefactorOverlay; struct RefactorMarker; @@ -68,6 +69,7 @@ class IAssistProvider; class ICodeStylePreferences; class CompletionAssistProvider; using RefactorMarkers = QList; +using TextMarks = QList; namespace Internal { class BaseTextEditorPrivate; @@ -274,6 +276,9 @@ public: QRegion translatedLineRegion(int lineStart, int lineEnd) const; QPoint toolTipPosition(const QTextCursor &c) const; + void showTextMarksToolTip(const QPoint &pos, + const TextMarks &marks, + const TextMark *mainTextMark = nullptr) const; void invokeAssist(AssistKind assistKind, IAssistProvider *provider = nullptr);