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 <david.schulz@qt.io>
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Nikolai Kosjar
2019-01-31 13:16:44 +01:00
parent 1a58a30685
commit c5e43d86d1
10 changed files with 43 additions and 111 deletions

View File

@@ -210,36 +210,6 @@ bool isDiagnosticAtLocation(const ClangBackEnd::DiagnosticContainer &diagnostic,
return isDiagnosticRelatedToLocation(diagnostic, {cursorRange}, line, column); return isDiagnosticRelatedToLocation(diagnostic, {cursorRange}, line, column);
} }
QVector<ClangBackEnd::DiagnosticContainer>
filteredDiagnosticsAtLocation(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
uint line,
uint column,
QTextDocument *textDocument)
{
QVector<ClangBackEnd::DiagnosticContainer> filteredDiagnostics;
foreach (const auto &diagnostic, diagnostics) {
if (isDiagnosticAtLocation(diagnostic, line, column, textDocument))
filteredDiagnostics.append(diagnostic);
}
return filteredDiagnostics;
}
bool editorDocumentProcessorHasDiagnosticAt(
const QVector<ClangBackEnd::DiagnosticContainer> &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) QTextCursor cursorAtLastPositionOfLine(QTextDocument *textDocument, int lineNumber)
{ {
const QTextBlock textBlock = textDocument->findBlockByNumber(lineNumber - 1); const QTextBlock textBlock = textDocument->findBlockByNumber(lineNumber - 1);
@@ -399,24 +369,16 @@ TextEditor::RefactorMarkers ClangDiagnosticManager::takeFixItAvailableMarkers()
return fixItAvailableMarkers; 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<TextEditor::TextMark *> textMarks;
return editorDocumentProcessorHasDiagnosticAt(m_errorDiagnostics, line, column, textDocument) for (ClangTextMark *textMark : m_clangTextMarks) {
|| editorDocumentProcessorHasDiagnosticAt(m_warningDiagnostics, line, column, textDocument); if (isDiagnosticAtLocation(textMark->diagnostic(), line, column, m_textDocument->document()))
} textMarks << textMark;
}
QVector<ClangBackEnd::DiagnosticContainer> return textMarks;
ClangDiagnosticManager::diagnosticsAt(uint line, uint column) const
{
QTextDocument *textDocument = m_textDocument->document();
QVector<ClangBackEnd::DiagnosticContainer> diagnostics;
diagnostics += filteredDiagnosticsAtLocation(m_errorDiagnostics, line, column, textDocument);
diagnostics += filteredDiagnosticsAtLocation(m_warningDiagnostics, line, column, textDocument);
return diagnostics;
} }
void ClangDiagnosticManager::invalidateDiagnostics() void ClangDiagnosticManager::invalidateDiagnostics()

View File

@@ -57,8 +57,7 @@ public:
QList<QTextEdit::ExtraSelection> takeExtraSelections(); QList<QTextEdit::ExtraSelection> takeExtraSelections();
TextEditor::RefactorMarkers takeFixItAvailableMarkers(); TextEditor::RefactorMarkers takeFixItAvailableMarkers();
bool hasDiagnosticsAt(uint line, uint column) const; QList<TextEditor::TextMark *> diagnosticTextMarksAt(uint line, uint column) const;
QVector<ClangBackEnd::DiagnosticContainer> diagnosticsAt(uint line, uint column) const;
void invalidateDiagnostics(); void invalidateDiagnostics();
void clearDiagnosticsWithFixIts(); void clearDiagnosticsWithFixIts();

View File

@@ -48,7 +48,6 @@
#include <cpptools/cppworkingcopy.h> #include <cpptools/cppworkingcopy.h>
#include <cpptools/editordocumenthandle.h> #include <cpptools/editordocumenthandle.h>
#include <texteditor/displaysettings.h>
#include <texteditor/fontsettings.h> #include <texteditor/fontsettings.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <texteditor/texteditorconstants.h> #include <texteditor/texteditorconstants.h>
@@ -292,27 +291,6 @@ TextEditor::QuickFixOperations ClangEditorDocumentProcessor::extraRefactoringOpe
return extractor.extract(assistInterface.fileName(), currentLine(assistInterface)); 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<ClangBackEnd::DiagnosticContainer> 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() void ClangEditorDocumentProcessor::editorDocumentTimerRestarted()
{ {
m_updateBackendDocumentTimer.stop(); // Wait for the next call to run(). m_updateBackendDocumentTimer.stop(); // Wait for the next call to run().
@@ -323,6 +301,12 @@ void ClangEditorDocumentProcessor::invalidateDiagnostics()
m_diagnosticManager.invalidateDiagnostics(); m_diagnosticManager.invalidateDiagnostics();
} }
TextEditor::TextMarks ClangEditorDocumentProcessor::diagnosticTextMarksAt(uint line,
uint column) const
{
return m_diagnosticManager.diagnosticTextMarksAt(line, column);
}
void ClangEditorDocumentProcessor::setParserConfig( void ClangEditorDocumentProcessor::setParserConfig(
const CppTools::BaseEditorDocumentParser::Configuration &config) const CppTools::BaseEditorDocumentParser::Configuration &config)
{ {

View File

@@ -83,8 +83,8 @@ public:
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override; extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override;
void invalidateDiagnostics() 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; void editorDocumentTimerRestarted() override;

View File

@@ -25,8 +25,9 @@
#include "clanghoverhandler.h" #include "clanghoverhandler.h"
#include "clangeditordocumentprocessor.h"
#include <coreplugin/helpmanager.h> #include <coreplugin/helpmanager.h>
#include <cpptools/baseeditordocumentprocessor.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsreuse.h> #include <cpptools/cpptoolsreuse.h>
#include <cpptools/editordocumenthandle.h> #include <cpptools/editordocumenthandle.h>
@@ -61,32 +62,17 @@ static CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor(TextEditor
return nullptr; return nullptr;
} }
static bool editorDocumentProcessorHasDiagnosticAt(TextEditorWidget *editorWidget, int pos) static TextMarks diagnosticTextMarksAt(TextEditorWidget *editorWidget, int position)
{ {
if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) { const auto processor = qobject_cast<ClangEditorDocumentProcessor *>(
int line, column; editorDocumentProcessor(editorWidget));
if (Utils::Text::convertPosition(editorWidget->document(), pos, &line, &column)) QTC_ASSERT(processor, return TextMarks());
return processor->hasDiagnosticsAt(line, column);
}
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, return processor->diagnosticTextMarksAt(line, column);
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));
}
}
} }
static QFuture<CppTools::ToolTipInfo> editorDocumentHandlesToolTipInfo( static QFuture<CppTools::ToolTipInfo> editorDocumentHandlesToolTipInfo(
@@ -189,7 +175,7 @@ void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
m_cursorPosition = -1; m_cursorPosition = -1;
// Check for diagnostics (sync) // Check for diagnostics (sync)
if (!isContextHelpRequest() && editorDocumentProcessorHasDiagnosticAt(editorWidget, pos)) { if (!isContextHelpRequest() && !diagnosticTextMarksAt(editorWidget, pos).isEmpty()) {
qCDebug(hoverLog) << "Checking for diagnostic at" << pos; qCDebug(hoverLog) << "Checking for diagnostic at" << pos;
setPriority(Priority_Diagnostic); setPriority(Priority_Diagnostic);
m_cursorPosition = pos; m_cursorPosition = pos;
@@ -275,10 +261,8 @@ void ClangHoverHandler::operateTooltip(TextEditor::TextEditorWidget *editorWidge
const QPoint &point) const QPoint &point)
{ {
if (priority() == Priority_Diagnostic) { if (priority() == Priority_Diagnostic) {
processWithEditorDocumentProcessor(editorWidget, const TextMarks textMarks = diagnosticTextMarksAt(editorWidget, m_cursorPosition);
point, editorWidget->showTextMarksToolTip(point, textMarks);
m_cursorPosition,
lastHelpItemIdentified());
return; return;
} }

View File

@@ -44,7 +44,9 @@ public:
const RemovedFromEditorHandler &removedHandler, const RemovedFromEditorHandler &removedHandler,
bool fullVisualization); bool fullVisualization);
ClangBackEnd::DiagnosticContainer diagnostic() const { return m_diagnostic; }
void updateIcon(bool valid = true); void updateIcon(bool valid = true);
private: private:
bool addToolTipContent(QLayout *target) const override; bool addToolTipContent(QLayout *target) const override;
void removedFromEditor() override; void removedFromEditor() override;

View File

@@ -72,15 +72,6 @@ BaseEditorDocumentProcessor::extraRefactoringOperations(const TextEditor::Assist
return TextEditor::QuickFixOperations(); return TextEditor::QuickFixOperations();
} }
bool BaseEditorDocumentProcessor::hasDiagnosticsAt(uint, uint) const
{
return false;
}
void BaseEditorDocumentProcessor::addDiagnosticToolTipToLayout(uint, uint, QLayout *) const
{
}
void BaseEditorDocumentProcessor::editorDocumentTimerRestarted() void BaseEditorDocumentProcessor::editorDocumentTimerRestarted()
{ {
} }

View File

@@ -81,8 +81,6 @@ public:
extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface); extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface);
virtual void invalidateDiagnostics(); virtual void invalidateDiagnostics();
virtual bool hasDiagnosticsAt(uint line, uint column) const;
virtual void addDiagnosticToolTipToLayout(uint line, uint column, QLayout *layout) const;
virtual void editorDocumentTimerRestarted(); virtual void editorDocumentTimerRestarted();

View File

@@ -3555,6 +3555,13 @@ QPoint TextEditorWidget::toolTipPosition(const QTextCursor &c) const
return cursorPos + QPoint(d->m_extraArea->width(), HostOsInfo::isWindowsHost() ? -24 : -16); 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) void TextEditorWidgetPrivate::processTooltipRequest(const QTextCursor &c)
{ {
const QPoint toolTipPoint = q->toolTipPosition(c); const QPoint toolTipPoint = q->toolTipPosition(c);

View File

@@ -59,6 +59,7 @@ class HighlightScrollBarController;
namespace TextEditor { namespace TextEditor {
class TextDocument; class TextDocument;
class TextMark;
class BaseHoverHandler; class BaseHoverHandler;
class RefactorOverlay; class RefactorOverlay;
struct RefactorMarker; struct RefactorMarker;
@@ -68,6 +69,7 @@ class IAssistProvider;
class ICodeStylePreferences; class ICodeStylePreferences;
class CompletionAssistProvider; class CompletionAssistProvider;
using RefactorMarkers = QList<RefactorMarker>; using RefactorMarkers = QList<RefactorMarker>;
using TextMarks = QList<TextMark *>;
namespace Internal { namespace Internal {
class BaseTextEditorPrivate; class BaseTextEditorPrivate;
@@ -274,6 +276,9 @@ public:
QRegion translatedLineRegion(int lineStart, int lineEnd) const; QRegion translatedLineRegion(int lineStart, int lineEnd) const;
QPoint toolTipPosition(const QTextCursor &c) 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); void invokeAssist(AssistKind assistKind, IAssistProvider *provider = nullptr);