diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2017-09-18 10:19:27 +0200 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2017-09-22 12:59:05 +0000 |
commit | 55a5ffc1ec0096076f4726a25c08d5902f24d46d (patch) | |
tree | a5297172a9f9d0c5a5570590b59e0c38b8471e44 /src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp | |
parent | f130de2400b8fa6bc98110b721e12e9e02a5fc09 (diff) | |
download | qt-creator-55a5ffc1ec0096076f4726a25c08d5902f24d46d.tar.gz |
C++: remove builtin FollowSymbol dependency from CppEditor
Move FollowSymbolUnderCursor to CppTools and
builtin member ownership to internal model manager.
Change-Id: I97a4f744ec1709ccc0b34fb67b58680973ef566f
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
Diffstat (limited to 'src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp')
-rw-r--r-- | src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp b/src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp new file mode 100644 index 0000000000..5711eb912c --- /dev/null +++ b/src/plugins/cpptools/cppvirtualfunctionassistprovider.cpp @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 "cppvirtualfunctionassistprovider.h" +#include "cppvirtualfunctionproposalitem.h" + +#include "cpptoolsreuse.h" +#include "functionutils.h" +#include "symbolfinder.h" +#include "typehierarchybuilder.h" + +#include <cplusplus/Icons.h> +#include <cplusplus/Overview.h> + +#include <coreplugin/actionmanager/actionmanager.h> +#include <coreplugin/actionmanager/command.h> + +#include <texteditor/codeassist/genericproposalmodel.h> +#include <texteditor/codeassist/genericproposal.h> +#include <texteditor/codeassist/genericproposalwidget.h> +#include <texteditor/codeassist/assistinterface.h> +#include <texteditor/codeassist/iassistprocessor.h> +#include <texteditor/codeassist/iassistproposal.h> +#include <texteditor/texteditorconstants.h> + +#include <utils/qtcassert.h> + +using namespace CPlusPlus; +using namespace TextEditor; + +namespace CppTools { + +/// Activate current item with the same shortcut that is configured for Follow Symbol Under Cursor. +/// This is limited to single-key shortcuts without modifiers. +class VirtualFunctionProposalWidget : public GenericProposalWidget +{ +public: + VirtualFunctionProposalWidget(bool openInSplit) + { + const char *id = openInSplit + ? TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR_IN_NEXT_SPLIT + : TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR; + if (Core::Command *command = Core::ActionManager::command(id)) + m_sequence = command->keySequence(); + } + +protected: + bool eventFilter(QObject *o, QEvent *e) override + { + if (e->type() == QEvent::ShortcutOverride && m_sequence.count() == 1) { + QKeyEvent *ke = static_cast<QKeyEvent *>(e); + const QKeySequence seq(ke->key()); + if (seq == m_sequence) { + activateCurrentProposalItem(); + e->accept(); + return true; + } + } + return GenericProposalWidget::eventFilter(o, e); + } + + void showProposal(const QString &prefix) override + { + GenericProposalModel *proposalModel = model(); + if (proposalModel && proposalModel->size() == 1) { + emit proposalItemActivated(proposalModel->proposalItem(0)); + deleteLater(); + return; + } + GenericProposalWidget::showProposal(prefix); + } + +private: + QKeySequence m_sequence; +}; + +class VirtualFunctionProposal : public GenericProposal +{ +public: + VirtualFunctionProposal(int cursorPos, + const QList<AssistProposalItemInterface *> &items, + bool openInSplit) + : GenericProposal(cursorPos, items) + , m_openInSplit(openInSplit) + { + setFragile(true); + } + + IAssistProposalWidget *createWidget() const override + { return new VirtualFunctionProposalWidget(m_openInSplit); } + +private: + bool m_openInSplit; +}; + +class VirtualFunctionAssistProcessor : public IAssistProcessor +{ +public: + VirtualFunctionAssistProcessor(const VirtualFunctionAssistProvider::Parameters ¶ms) + : m_params(params) + {} + + IAssistProposal *immediateProposal(const AssistInterface *) override + { + QTC_ASSERT(m_params.function, return 0); + + auto *hintItem = new VirtualFunctionProposalItem(TextEditorWidget::Link()); + hintItem->setText(QCoreApplication::translate("VirtualFunctionsAssistProcessor", + "...searching overrides")); + hintItem->setOrder(-1000); + + QList<AssistProposalItemInterface *> items; + items << itemFromFunction(m_params.function); + items << hintItem; + return new VirtualFunctionProposal(m_params.cursorPosition, items, m_params.openInNextSplit); + } + + IAssistProposal *perform(const AssistInterface *assistInterface) override + { + delete assistInterface; + + QTC_ASSERT(m_params.function, return 0); + QTC_ASSERT(m_params.staticClass, return 0); + QTC_ASSERT(!m_params.snapshot.isEmpty(), return 0); + + Class *functionsClass = m_finder.findMatchingClassDeclaration(m_params.function, + m_params.snapshot); + if (!functionsClass) + return 0; + + const QList<Function *> overrides = FunctionUtils::overrides( + m_params.function, functionsClass, m_params.staticClass, m_params.snapshot); + if (overrides.isEmpty()) + return 0; + + QList<AssistProposalItemInterface *> items; + foreach (Function *func, overrides) + items << itemFromFunction(func); + items.first()->setOrder(1000); // Ensure top position for function of static type + + return new VirtualFunctionProposal(m_params.cursorPosition, items, m_params.openInNextSplit); + } + +private: + Function *maybeDefinitionFor(Function *func) const + { + if (Function *definition = m_finder.findMatchingDefinition(func, m_params.snapshot)) + return definition; + return func; + } + + VirtualFunctionProposalItem *itemFromFunction(Function *func) const + { + const TextEditorWidget::Link link = CppTools::linkToSymbol(maybeDefinitionFor(func)); + QString text = m_overview.prettyName(LookupContext::fullyQualifiedName(func)); + if (func->isPureVirtual()) + text += QLatin1String(" = 0"); + + auto *item = new VirtualFunctionProposalItem(link, m_params.openInNextSplit); + item->setText(text); + item->setIcon(Icons::iconForSymbol(func)); + + return item; + } + + VirtualFunctionAssistProvider::Parameters m_params; + Overview m_overview; + mutable SymbolFinder m_finder; +}; + +VirtualFunctionAssistProvider::VirtualFunctionAssistProvider() +{ +} + +bool VirtualFunctionAssistProvider::configure(const Parameters ¶meters) +{ + m_params = parameters; + return true; +} + +IAssistProvider::RunType VirtualFunctionAssistProvider::runType() const +{ + return AsynchronousWithThread; +} + +IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const +{ + return new VirtualFunctionAssistProcessor(m_params); +} + +} // namespace CppTools |