diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-01-12 12:29:43 +0100 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-01-16 15:32:15 +0000 |
commit | 76c25bcd6a97dda3921e8bc487e1c61f10938ad2 (patch) | |
tree | 7854480970b5290d9c3f225942c7780d355a2247 /src/plugins/clangcodemodel | |
parent | 7872ddde4cbaba2c6e5f55f1d05184ba33ba326b (diff) | |
download | qt-creator-76c25bcd6a97dda3921e8bc487e1c61f10938ad2.tar.gz |
Clang: Provide tooltips
This includes also the query data for the help system (F1) for an
identifier under cursor.
Regressions (libclang changes necessary):
- Function signatures do not contain default values.
- Aliases are not resolved for/at:
- template types
- qualified name of a type
Fixes/Improvements:
- Resolve "auto"
- On a template type, show also the template parameter.
- For a typedef like
typedef long long superlong;
the tooltip was "long long superlong", which was confusing.
Now, "long long" is shown.
New:
- Show first or \brief paragraph of a documentation comment.
- Show size of a class at definition.
- Show size of a field member in class definition.
Task-number: QTCREATORBUG-11259
Change-Id: Ie1a07930d0e882015d07dc43e35bb81a685cdeb8
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Diffstat (limited to 'src/plugins/clangcodemodel')
13 files changed, 421 insertions, 6 deletions
diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp index 5650479312..1abd6982ed 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.cpp +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.cpp @@ -392,6 +392,15 @@ QFuture<CppTools::CursorInfo> BackendCommunicator::requestLocalReferences( return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument); } +QFuture<CppTools::ToolTipInfo> BackendCommunicator::requestToolTip( + const FileContainer &fileContainer, quint32 line, quint32 column) +{ + const RequestToolTipMessage message(fileContainer, line, column); + m_sender->requestToolTip(message); + + return m_receiver.addExpectedToolTipMessage(message.ticketNumber()); +} + QFuture<CppTools::SymbolInfo> BackendCommunicator::requestFollowSymbol( const FileContainer &curFileContainer, quint32 line, diff --git a/src/plugins/clangcodemodel/clangbackendcommunicator.h b/src/plugins/clangcodemodel/clangbackendcommunicator.h index bd7494a6c2..b3cb166a39 100644 --- a/src/plugins/clangcodemodel/clangbackendcommunicator.h +++ b/src/plugins/clangcodemodel/clangbackendcommunicator.h @@ -82,6 +82,9 @@ public: quint32 line, quint32 column, QTextDocument *textDocument); + QFuture<CppTools::ToolTipInfo> requestToolTip(const FileContainer &fileContainer, + quint32 line, + quint32 column); QFuture<CppTools::SymbolInfo> requestFollowSymbol(const FileContainer &curFileContainer, quint32 line, quint32 column); diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp index 8d5ec92d00..f2606d74cc 100644 --- a/src/plugins/clangcodemodel/clangbackendreceiver.cpp +++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp @@ -128,6 +128,18 @@ QFuture<CppTools::SymbolInfo> BackendReceiver::addExpectedRequestFollowSymbolMes return futureInterface.future(); } +QFuture<CppTools::ToolTipInfo> BackendReceiver::addExpectedToolTipMessage(quint64 ticket) +{ + QTC_CHECK(!m_toolTipsTable.contains(ticket)); + + QFutureInterface<CppTools::ToolTipInfo> futureInterface; + futureInterface.reportStarted(); + + m_toolTipsTable.insert(ticket, futureInterface); + + return futureInterface.future(); +} + bool BackendReceiver::isExpectingCodeCompletedMessage() const { return !m_assistProcessorsTable.isEmpty(); @@ -272,6 +284,72 @@ void BackendReceiver::references(const ReferencesMessage &message) futureInterface.reportFinished(); } +static TextEditor::HelpItem::Category toHelpItemCategory(ToolTipInfo::QdocCategory category) +{ + switch (category) { + case ToolTipInfo::Unknown: + return TextEditor::HelpItem::Unknown; + case ToolTipInfo::ClassOrNamespace: + return TextEditor::HelpItem::ClassOrNamespace; + case ToolTipInfo::Enum: + return TextEditor::HelpItem::Enum; + case ToolTipInfo::Typedef: + return TextEditor::HelpItem::Typedef; + case ToolTipInfo::Macro: + return TextEditor::HelpItem::Macro; + case ToolTipInfo::Brief: + return TextEditor::HelpItem::Brief; + case ToolTipInfo::Function: + return TextEditor::HelpItem::Function; + } + + return TextEditor::HelpItem::Unknown; +} + +static QStringList toStringList(const Utf8StringVector &utf8StringVector) +{ + QStringList list; + list.reserve(utf8StringVector.size()); + + for (const Utf8String &utf8String : utf8StringVector) + list << utf8String.toString(); + + return list; +} + +static CppTools::ToolTipInfo toToolTipInfo(const ToolTipMessage &message) +{ + CppTools::ToolTipInfo info; + + const ToolTipInfo backendInfo = message.toolTipInfo(); + + info.text = backendInfo.text(); + info.briefComment = backendInfo.briefComment(); + + info.qDocIdCandidates = toStringList(backendInfo.qdocIdCandidates()); + info.qDocMark = backendInfo.qdocMark(); + info.qDocCategory = toHelpItemCategory(backendInfo.qdocCategory()); + + info.sizeInBytes = backendInfo.sizeInBytes(); + + return info; +} + +void BackendReceiver::tooltip(const ToolTipMessage &message) +{ + qCDebugIpc() << "ToolTipMessage" << message.toolTipInfo().text(); + + const quint64 ticket = message.ticketNumber(); + QFutureInterface<CppTools::ToolTipInfo> futureInterface = m_toolTipsTable.take(ticket); + QTC_CHECK(futureInterface != QFutureInterface<CppTools::ToolTipInfo>()); + + if (futureInterface.isCanceled()) + return; // A new request was issued making this one outdated. + + futureInterface.reportResult(toToolTipInfo(message)); + futureInterface.reportFinished(); +} + void BackendReceiver::followSymbol(const ClangBackEnd::FollowSymbolMessage &message) { qCDebugIpc() << "FollowSymbolMessage with" diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.h b/src/plugins/clangcodemodel/clangbackendreceiver.h index d7a966eae9..921150a52d 100644 --- a/src/plugins/clangcodemodel/clangbackendreceiver.h +++ b/src/plugins/clangcodemodel/clangbackendreceiver.h @@ -27,6 +27,7 @@ #include <cpptools/cppcursorinfo.h> #include <cpptools/cppsymbolinfo.h> +#include <cpptools/baseeditordocumentprocessor.h> #include <clangsupport/clangcodemodelclientinterface.h> @@ -59,6 +60,7 @@ public: const CppTools::SemanticInfo::LocalUseMap &localUses = CppTools::SemanticInfo::LocalUseMap()); QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket); + QFuture<CppTools::ToolTipInfo> addExpectedToolTipMessage(quint64 ticket); bool isExpectingCodeCompletedMessage() const; void reset(); @@ -70,6 +72,7 @@ private: void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &message) override; void references(const ClangBackEnd::ReferencesMessage &message) override; + void tooltip(const ClangBackEnd::ToolTipMessage &message) override; void followSymbol(const ClangBackEnd::FollowSymbolMessage &message) override; private: @@ -89,7 +92,7 @@ private: CppTools::SemanticInfo::LocalUseMap localUses; }; QHash<quint64, ReferencesEntry> m_referencesTable; - + QHash<quint64, QFutureInterface<CppTools::ToolTipInfo>> m_toolTipsTable; QHash<quint64, QFutureInterface<CppTools::SymbolInfo>> m_followTable; }; diff --git a/src/plugins/clangcodemodel/clangbackendsender.cpp b/src/plugins/clangcodemodel/clangbackendsender.cpp index 089377083f..f6f8aea1cf 100644 --- a/src/plugins/clangcodemodel/clangbackendsender.cpp +++ b/src/plugins/clangcodemodel/clangbackendsender.cpp @@ -120,6 +120,13 @@ void BackendSender::requestReferences(const RequestReferencesMessage &message) m_connection->serverProxy().requestReferences(message); } +void BackendSender::requestToolTip(const RequestToolTipMessage &message) +{ + QTC_CHECK(m_connection->isConnected()); + qCDebug(ipcLog) << ">>>" << message; + m_connection->serverProxy().requestToolTip(message); +} + void BackendSender::requestFollowSymbol(const RequestFollowSymbolMessage &message) { QTC_CHECK(m_connection->isConnected()); diff --git a/src/plugins/clangcodemodel/clangbackendsender.h b/src/plugins/clangcodemodel/clangbackendsender.h index ca9238ae65..f01326a4dc 100644 --- a/src/plugins/clangcodemodel/clangbackendsender.h +++ b/src/plugins/clangcodemodel/clangbackendsender.h @@ -48,6 +48,7 @@ public: void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; void requestDocumentAnnotations(const ClangBackEnd::RequestDocumentAnnotationsMessage &message) override; void requestReferences(const ClangBackEnd::RequestReferencesMessage &message) override; + void requestToolTip(const ClangBackEnd::RequestToolTipMessage &message) override; void requestFollowSymbol(const ClangBackEnd::RequestFollowSymbolMessage &message) override; void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) override; diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index 9136db5db5..0e444a350e 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -30,6 +30,7 @@ SOURCES += \ clangfixitoperationsextractor.cpp \ clangfollowsymbol.cpp \ clangfunctionhintmodel.cpp \ + clanghoverhandler.cpp \ clangtokeninfosreporter.cpp \ clangmodelmanagersupport.cpp \ clangpreprocessorassistproposalitem.cpp \ @@ -66,6 +67,7 @@ HEADERS += \ clangfixitoperationsextractor.h \ clangfollowsymbol.h \ clangfunctionhintmodel.h \ + clanghoverhandler.h \ clangisdiagnosticrelatedtolocation.h \ clangmodelmanagersupport.h \ clangpreprocessorassistproposalitem.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index cc81025925..90105b86d3 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -80,6 +80,8 @@ QtcPlugin { "clangfollowsymbol.h", "clangfunctionhintmodel.cpp", "clangfunctionhintmodel.h", + "clanghoverhandler.cpp", + "clanghoverhandler.h", "clangtokeninfosreporter.cpp", "clangtokeninfosreporter.h", "clangisdiagnosticrelatedtolocation.h", diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 6eb98b2c92..a282350f24 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -375,6 +375,15 @@ ClangEditorDocumentProcessor::requestFollowSymbol(int line, int column) static_cast<quint32>(column)); } +QFuture<CppTools::ToolTipInfo> ClangEditorDocumentProcessor::toolTipInfo(const QByteArray &codecName, + int line, + int column) +{ + return m_communicator.requestToolTip(simpleFileContainer(codecName), + static_cast<quint32>(line), + static_cast<quint32>(column)); +} + ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const { return fileContainerWithArguments(m_projectPart.data()); @@ -480,13 +489,19 @@ ClangEditorDocumentProcessor::creatorForHeaderErrorDiagnosticWidget( }; } -ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer() const +ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer( + const QByteArray &codecName) const { Utf8String projectPartId; if (m_projectPart) projectPartId = m_projectPart->id(); - return ClangBackEnd::FileContainer(filePath(), projectPartId, Utf8String(), false, revision()); + return ClangBackEnd::FileContainer(filePath(), + projectPartId, + Utf8String(), + false, + revision(), + Utf8String::fromByteArray(codecName)); } static CppTools::ProjectPart projectPartForLanguageOption(CppTools::ProjectPart *projectPart) diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index 2bb7ca0463..67745b582c 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -88,6 +88,9 @@ public: QFuture<CppTools::CursorInfo> cursorInfo(const CppTools::CursorInfoParams ¶ms) override; QFuture<CppTools::CursorInfo> requestLocalReferences(const QTextCursor &cursor) override; QFuture<CppTools::SymbolInfo> requestFollowSymbol(int line, int column) override; + QFuture<CppTools::ToolTipInfo> toolTipInfo(const QByteArray &codecName, + int line, + int column) override; ClangBackEnd::FileContainer fileContainerWithArguments() const; @@ -106,7 +109,7 @@ private: void requestDocumentAnnotations(const QString &projectpartId); HeaderErrorDiagnosticWidgetCreator creatorForHeaderErrorDiagnosticWidget( const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic); - ClangBackEnd::FileContainer simpleFileContainer() const; + ClangBackEnd::FileContainer simpleFileContainer(const QByteArray &codecName = QByteArray()) const; ClangBackEnd::FileContainer fileContainerWithArguments(CppTools::ProjectPart *projectPart) const; ClangBackEnd::FileContainer fileContainerWithArgumentsAndDocumentContent( CppTools::ProjectPart *projectPart) const; diff --git a/src/plugins/clangcodemodel/clanghoverhandler.cpp b/src/plugins/clangcodemodel/clanghoverhandler.cpp new file mode 100644 index 0000000000..6610b555c2 --- /dev/null +++ b/src/plugins/clangcodemodel/clanghoverhandler.cpp @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "clanghoverhandler.h" + +#include <coreplugin/helpmanager.h> +#include <cpptools/baseeditordocumentprocessor.h> +#include <cpptools/cppmodelmanager.h> +#include <cpptools/editordocumenthandle.h> +#include <texteditor/texteditor.h> + +#include <utils/qtcassert.h> +#include <utils/textutils.h> +#include <utils/tooltip/tooltip.h> + +#include <QFutureWatcher> +#include <QLoggingCategory> +#include <QTextCodec> +#include <QVBoxLayout> + +Q_LOGGING_CATEGORY(hoverLog, "qtc.clangcodemodel.hover"); + +using namespace TextEditor; + +namespace ClangCodeModel { +namespace Internal { + +static CppTools::BaseEditorDocumentProcessor *editorDocumentProcessor(TextEditorWidget *editorWidget) +{ + const QString filePath = editorWidget->textDocument()->filePath().toString(); + auto cppModelManager = CppTools::CppModelManager::instance(); + CppTools::CppEditorDocumentHandle *editorHandle = cppModelManager->cppEditorDocument(filePath); + + if (editorHandle) + return editorHandle->processor(); + + return 0; +} + +static bool editorDocumentProcessorHasDiagnosticAt(TextEditorWidget *editorWidget, int pos) +{ + if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) { + int line, column; + if (Utils::Text::convertPosition(editorWidget->document(), pos, &line, &column)) + return processor->hasDiagnosticsAt(line, column); + } + + return false; +} + +static void processWithEditorDocumentProcessor(TextEditorWidget *editorWidget, + const QPoint &point, + int position, + const QString &helpId) +{ + 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, helpId); + } + } +} + +static QFuture<CppTools::ToolTipInfo> editorDocumentHandlesToolTipInfo( + TextEditorWidget *editorWidget, int pos) +{ + const QByteArray textCodecName = editorWidget->textDocument()->codec()->name(); + if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) { + int line, column; + if (Utils::Text::convertPosition(editorWidget->document(), pos, &line, &column)) + return processor->toolTipInfo(textCodecName, line, column + 1); + } + + return QFuture<CppTools::ToolTipInfo>(); +} + +ClangHoverHandler::ClangHoverHandler() +{ + setIsAsyncHandler(true); +} + +ClangHoverHandler::~ClangHoverHandler() +{ + cancelAsyncCheck(); +} + +void ClangHoverHandler::identifyMatchAsync(TextEditorWidget *editorWidget, + int pos, + BaseHoverHandler::ReportPriority report) +{ + // Reset + m_futureWatcher.reset(); + m_cursorPosition = -1; + + // Check for diagnostics (sync) + if (editorDocumentProcessorHasDiagnosticAt(editorWidget, pos)) { + qCDebug(hoverLog) << "Checking for diagnostic at" << pos; + setPriority(Priority_Diagnostic); + m_cursorPosition = pos; + report(priority()); + return; + } + + // Check for tooltips (async) + QFuture<CppTools::ToolTipInfo> future = editorDocumentHandlesToolTipInfo(editorWidget, pos); + if (QTC_GUARD(future.isRunning())) { + qCDebug(hoverLog) << "Requesting tooltip info at" << pos; + m_reportPriority = report; + m_futureWatcher.reset(new QFutureWatcher<CppTools::ToolTipInfo>()); + QObject::connect(m_futureWatcher.data(), &QFutureWatcherBase::finished, [this]() { + processToolTipInfo(m_futureWatcher->result()); + }); + m_futureWatcher->setFuture(future); + return; + } + + report(Priority_None); // Ops, something went wrong. +} + +void ClangHoverHandler::cancelAsyncCheck() +{ + if (m_futureWatcher) + m_futureWatcher->cancel(); +} + +#define RETURN_TEXT_FOR_CASE(enumValue) case TextEditor::HelpItem::enumValue: return #enumValue +static const char *helpItemCategoryAsString(TextEditor::HelpItem::Category category) +{ + switch (category) { + RETURN_TEXT_FOR_CASE(Unknown); + RETURN_TEXT_FOR_CASE(ClassOrNamespace); + RETURN_TEXT_FOR_CASE(Enum); + RETURN_TEXT_FOR_CASE(Typedef); + RETURN_TEXT_FOR_CASE(Macro); + RETURN_TEXT_FOR_CASE(Brief); + RETURN_TEXT_FOR_CASE(Function); + RETURN_TEXT_FOR_CASE(QmlComponent); + RETURN_TEXT_FOR_CASE(QmlProperty); + RETURN_TEXT_FOR_CASE(QMakeVariableOfFunction); + } + + return "UnhandledHelpItemCategory"; +} +#undef RETURN_TEXT_FOR_CASE + +void ClangHoverHandler::processToolTipInfo(const CppTools::ToolTipInfo &info) +{ + qCDebug(hoverLog) << "Processing tooltip info" << info.text; + + QString text = info.text; + if (!info.briefComment.isEmpty()) + text.append("\n\n" + info.briefComment); + + for (const QString &qdocIdCandidate : info.qDocIdCandidates) { + qCDebug(hoverLog) << "Querying help manager with" + << qdocIdCandidate + << info.qDocMark + << helpItemCategoryAsString(info.qDocCategory); + const QMap<QString, QUrl> helpLinks = Core::HelpManager::linksForIdentifier(qdocIdCandidate); + if (!helpLinks.isEmpty()) { + qCDebug(hoverLog) << " Match!"; + setLastHelpItemIdentified( + HelpItem(qdocIdCandidate, info.qDocMark, info.qDocCategory, helpLinks)); + break; + } + } + + if (!info.sizeInBytes.isEmpty()) + text.append(tr("\n\n%1 bytes").arg(info.sizeInBytes)); + + setToolTip(text); + m_reportPriority(priority()); +} + +void ClangHoverHandler::decorateToolTip() +{ + if (priority() == Priority_Diagnostic) + return; + + if (Qt::mightBeRichText(toolTip())) + setToolTip(toolTip().toHtmlEscaped()); + + const HelpItem &help = lastHelpItemIdentified(); + if (help.isValid()) { + const QString text = CppTools::CppHoverHandler::tooltipTextForHelpItem(help); + if (!text.isEmpty()) + setToolTip(text); + } +} + +void ClangHoverHandler::operateTooltip(TextEditor::TextEditorWidget *editorWidget, + const QPoint &point) +{ + if (priority() == Priority_Diagnostic) { + const HelpItem helpItem = lastHelpItemIdentified(); + const QString helpId = helpItem.isValid() ? helpItem.helpId() : QString(); + processWithEditorDocumentProcessor(editorWidget, point, m_cursorPosition, helpId); + return; + } + + // Priority_Tooltip / Priority_Help + BaseHoverHandler::operateTooltip(editorWidget, point); +} + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clanghoverhandler.h b/src/plugins/clangcodemodel/clanghoverhandler.h new file mode 100644 index 0000000000..85b7999f94 --- /dev/null +++ b/src/plugins/clangcodemodel/clanghoverhandler.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <cpptools/baseeditordocumentprocessor.h> +#include <cpptools/cpphoverhandler.h> +#include <texteditor/basehoverhandler.h> + +namespace ClangCodeModel { +namespace Internal { + +class ClangHoverHandler : public TextEditor::BaseHoverHandler +{ + Q_DECLARE_TR_FUNCTIONS(ClangHoverHandler) + +public: + ClangHoverHandler(); + ~ClangHoverHandler() override; + + void identifyMatchAsync(TextEditor::TextEditorWidget *editorWidget, + int pos, + ReportPriority report) override; + void decorateToolTip() override; + void operateTooltip(TextEditor::TextEditorWidget *editorWidget, const QPoint &point) override; + +private: + void cancelAsyncCheck() override; + void processToolTipInfo(const CppTools::ToolTipInfo &info); + +private: + int m_cursorPosition = -1; + QScopedPointer<QFutureWatcher<CppTools::ToolTipInfo>> m_futureWatcher; + ReportPriority m_reportPriority; +}; + +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 9271975dfd..9495e6d5eb 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -29,11 +29,11 @@ #include "clangeditordocumentprocessor.h" #include "clangutils.h" #include "clangfollowsymbol.h" +#include "clanghoverhandler.h" #include "clangrefactoringengine.h" #include <coreplugin/editormanager/editormanager.h> #include <cpptools/cppfollowsymbolundercursor.h> -#include <cpptools/cpphoverhandler.h> #include <cpptools/cppmodelmanager.h> #include <cpptools/editordocumenthandle.h> #include <cpptools/projectinfo.h> @@ -114,7 +114,7 @@ CppTools::CppCompletionAssistProvider *ModelManagerSupportClang::completionAssis TextEditor::BaseHoverHandler *ModelManagerSupportClang::createHoverHandler() { - return new CppTools::CppHoverHandler; + return new Internal::ClangHoverHandler; } CppTools::FollowSymbolInterface &ModelManagerSupportClang::followSymbolInterface() |