diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 7e4314c05bf4eeff66d787fb98141689039e7940..9fe55f05a81dc23b26fada04985a79f8635ab3cc 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1580,14 +1580,13 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e) Core::ActionContainer *mcontext = am->actionContainer(Constants::M_CONTEXT); QMenu *contextMenu = mcontext->menu(); - CppQuickFixCollector *quickFixCollector = CppPlugin::instance()->quickFixCollector(); + QMenu *quickFixMenu = new QMenu("&Refactor", menu); + quickFixMenu->addAction(am->command(Constants::RENAME_SYMBOL_UNDER_CURSOR)->action()); + CppQuickFixCollector *quickFixCollector = CppPlugin::instance()->quickFixCollector(); QSignalMapper mapper; connect(&mapper, SIGNAL(mapped(int)), this, SLOT(performQuickFix(int))); - QMenu *quickFixMenu = new QMenu("&Refactor", menu); - quickFixMenu->addAction(am->command(Constants::RENAME_SYMBOL_UNDER_CURSOR)->action()); - if (! isOutdated()) { if (quickFixCollector->startCompletion(editableInterface()) != -1) { m_quickFixes = quickFixCollector->quickFixes(); diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index 9ea7c681742d7cd2d8f899c265a961e110c131a4..63822c0b4e3446905f40b8596eb7b33499987cba 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -32,8 +32,9 @@ #include "qmljshighlighter.h" #include "qmljseditorplugin.h" #include "qmljsmodelmanager.h" -#include "qmloutlinemodel.h" #include "qmljseditorcodeformatter.h" +#include "qmljsquickfix.h" +#include "qmloutlinemodel.h" #include <qmljs/qmljsbind.h> #include <qmljs/qmljscheck.h> @@ -66,6 +67,7 @@ #include <utils/uncommentselection.h> #include <QtCore/QFileInfo> +#include <QtCore/QSignalMapper> #include <QtCore/QTimer> #include <QtGui/QMenu> @@ -1451,28 +1453,61 @@ void QmlJSTextEditor::showContextPane() } } +void QmlJSTextEditor::performQuickFix(int index) +{ + TextEditor::QuickFixOperation::Ptr op = m_quickFixes.at(index); + op->perform(); +} + void QmlJSTextEditor::contextMenuEvent(QContextMenuEvent *e) { QMenu *menu = new QMenu(); - if (Core::ActionContainer *mcontext = Core::ICore::instance()->actionManager()->actionContainer(QmlJSEditor::Constants::M_CONTEXT)) { - QMenu *contextMenu = mcontext->menu(); - foreach (QAction *action, contextMenu->actions()) - menu->addAction(action); - } + QMenu *refactoringMenu = new QMenu(tr("Refactoring"), menu); + // Conditionally add the rename-id action: const QString id = wordUnderCursor(); const QList<AST::SourceLocation> &locations = m_semanticInfo.idLocations.value(id); if (! locations.isEmpty()) { - menu->addSeparator(); - QAction *a = menu->addAction(tr("Rename id '%1'...").arg(id)); + QAction *a = refactoringMenu->addAction(tr("Rename id '%1'...").arg(id)); connect(a, SIGNAL(triggered()), this, SLOT(renameIdUnderCursor())); } + // Add other refactoring actions: + QmlJSQuickFixCollector *quickFixCollector = QmlJSEditorPlugin::instance()->quickFixCollector(); + QSignalMapper mapper; + connect(&mapper, SIGNAL(mapped(int)), this, SLOT(performQuickFix(int))); + + if (! isOutdated()) { + if (quickFixCollector->startCompletion(editableInterface()) != -1) { + m_quickFixes = quickFixCollector->quickFixes(); + + for (int index = 0; index < m_quickFixes.size(); ++index) { + TextEditor::QuickFixOperation::Ptr op = m_quickFixes.at(index); + QAction *action = refactoringMenu->addAction(op->description()); + mapper.setMapping(action, index); + connect(action, SIGNAL(triggered()), &mapper, SLOT(map())); + } + } + } + + refactoringMenu->setEnabled(!refactoringMenu->isEmpty()); + + if (Core::ActionContainer *mcontext = Core::ICore::instance()->actionManager()->actionContainer(QmlJSEditor::Constants::M_CONTEXT)) { + QMenu *contextMenu = mcontext->menu(); + foreach (QAction *action, contextMenu->actions()) { + menu->addAction(action); + if (action->objectName() == QmlJSEditor::Constants::M_REFACTORING_MENU_INSERTION_POINT) + menu->addMenu(refactoringMenu); + } + } + appendStandardContextMenuActions(menu); menu->exec(e->globalPos()); menu->deleteLater(); + quickFixCollector->cleanup(); + m_quickFixes.clear(); } bool QmlJSTextEditor::event(QEvent *e) diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h index 5c1dd65b3018695f94aebca91dd5d7d487e45590..1d7d57b82c91e9120d9a00d45aed6bdd62287583 100644 --- a/src/plugins/qmljseditor/qmljseditor.h +++ b/src/plugins/qmljseditor/qmljseditor.h @@ -36,6 +36,7 @@ #include <qmljs/qmljsscanner.h> #include <qmljs/qmljsinterpreter.h> #include <texteditor/basetexteditor.h> +#include <texteditor/quickfix.h> #include <QtCore/QWaitCondition> #include <QtCore/QModelIndex> @@ -275,6 +276,8 @@ private slots: void onCursorPositionChanged(); void onRefactorMarkerClicked(const TextEditor::Internal::RefactorMarker &marker); + void performQuickFix(int index); + protected: void contextMenuEvent(QContextMenuEvent *e); bool event(QEvent *e); @@ -323,6 +326,8 @@ private: SemanticHighlighter *m_semanticHighlighter; SemanticInfo m_semanticInfo; + QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes; + QmlJS::IContextPane *m_contextPane; int m_oldCursorPosition; bool m_updateSelectedElements; diff --git a/src/plugins/qmljseditor/qmljseditorconstants.h b/src/plugins/qmljseditor/qmljseditorconstants.h index f4dedba223f76e3edfdca564fb41fde3dd6edaa4..e6f19b6112be47ef1775379e84940b345f4216f7 100644 --- a/src/plugins/qmljseditor/qmljseditorconstants.h +++ b/src/plugins/qmljseditor/qmljseditorconstants.h @@ -37,6 +37,11 @@ namespace Constants { // menus const char * const M_CONTEXT = "QML JS Editor.ContextMenu"; +const char * const M_TOOLS_QML = "QmlJSEditor.Tools.Menu"; + +const char * const SEPARATOR1 = "QmlJSEditor.Separator1"; +const char * const SEPARATOR2 = "QmlJSEditor.Separator2"; +const char * const M_REFACTORING_MENU_INSERTION_POINT = "QmlJSEditor.RefactorGroup"; const char * const RUN_SEP = "QmlJSEditor.Run.Separator"; const char * const C_QMLJSEDITOR_ID = "QMLProjectManager.QMLJSEditor"; diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp index 727522dc0a17a423a2d98d26f0770d6166e9861a..c10784d5fe4ad0c8e79589ef0bfe62d65b60b85e 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.cpp +++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp @@ -107,6 +107,18 @@ QmlJSEditorPlugin::~QmlJSEditorPlugin() m_instance = 0; } +/*! Copied from cppplugin.cpp */ +static inline +Core::Command *createSeparator(Core::ActionManager *am, + QObject *parent, + Core::Context &context, + const char *id) +{ + QAction *separator = new QAction(parent); + separator->setSeparator(true); + return am->registerAction(separator, Core::Id(id), context); +} + bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *error_message) { Core::ICore *core = Core::ICore::instance(); @@ -137,6 +149,11 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e Core::ActionManager *am = core->actionManager(); Core::ActionContainer *contextMenu = am->createMenu(QmlJSEditor::Constants::M_CONTEXT); + Core::ActionContainer *qmlToolsMenu = am->createMenu(Core::Id(Constants::M_TOOLS_QML)); + QMenu *menu = qmlToolsMenu->menu(); + menu->setTitle(tr("QML")); //: QML sub-menu in the Tools menu + menu->setEnabled(true); + am->actionContainer(Core::Constants::M_TOOLS)->addMenu(qmlToolsMenu); Core::Command *cmd; QAction *followSymbolUnderCursorAction = new QAction(tr("Follow Symbol Under Cursor"), this); @@ -144,12 +161,23 @@ bool QmlJSEditorPlugin::initialize(const QStringList & /*arguments*/, QString *e cmd->setDefaultKeySequence(QKeySequence(Qt::Key_F2)); connect(followSymbolUnderCursorAction, SIGNAL(triggered()), this, SLOT(followSymbolUnderCursor())); contextMenu->addAction(cmd); + qmlToolsMenu->addAction(cmd); QAction *showQuickToolbar = new QAction(tr("Show Qt Quick Toolbar"), this); cmd = am->registerAction(showQuickToolbar, Constants::SHOW_QT_QUICK_HELPER, context); cmd->setDefaultKeySequence(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Space)); connect(showQuickToolbar, SIGNAL(triggered()), this, SLOT(showContextPane())); contextMenu->addAction(cmd); + qmlToolsMenu->addAction(cmd); + + // Insert marker for "Refactoring" menu: + Core::Context globalContext(Core::Constants::C_GLOBAL); + Core::Command *sep = createSeparator(am, this, globalContext, + Constants::SEPARATOR1); + sep->action()->setObjectName(Constants::M_REFACTORING_MENU_INSERTION_POINT); + contextMenu->addAction(sep); + contextMenu->addAction(createSeparator(am, this, globalContext, + Constants::SEPARATOR2)); cmd = am->command(TextEditor::Constants::AUTO_INDENT_SELECTION); contextMenu->addAction(cmd);