OSDN Git Service

Add "Run" to projectexplorer context menu
authordt <qtc-committer@nokia.com>
Thu, 20 Jan 2011 17:05:58 +0000 (18:05 +0100)
committerdt <qtc-committer@nokia.com>
Fri, 21 Jan 2011 12:35:23 +0000 (13:35 +0100)
Task-Nr: QTCREATORBUG-2166

24 files changed:
src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
src/plugins/cmakeprojectmanager/cmakeprojectnodes.h
src/plugins/genericprojectmanager/genericprojectnodes.cpp
src/plugins/genericprojectmanager/genericprojectnodes.h
src/plugins/projectexplorer/projectexplorer.cpp
src/plugins/projectexplorer/projectexplorer.h
src/plugins/projectexplorer/projectexplorerconstants.h
src/plugins/projectexplorer/projectnodes.h
src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
src/plugins/qmlprojectmanager/qmlprojectnodes.h
src/plugins/qt4projectmanager/qt-desktop/qt4desktoptarget.cpp
src/plugins/qt4projectmanager/qt-desktop/qt4desktoptarget.h
src/plugins/qt4projectmanager/qt-desktop/qt4runconfiguration.h
src/plugins/qt4projectmanager/qt-desktop/qt4simulatortarget.cpp
src/plugins/qt4projectmanager/qt-desktop/qt4simulatortarget.h
src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.cpp
src/plugins/qt4projectmanager/qt-maemo/qt4maemotarget.h
src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.cpp
src/plugins/qt4projectmanager/qt-s60/qt4symbiantarget.h
src/plugins/qt4projectmanager/qt4nodes.cpp
src/plugins/qt4projectmanager/qt4nodes.h
src/plugins/qt4projectmanager/qt4projectmanagerconstants.h
src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp
src/plugins/qt4projectmanager/qt4target.h

index c84dc7b..f706f90 100644 (file)
@@ -101,3 +101,9 @@ bool CMakeProjectNode::renameFile(const ProjectExplorer::FileType fileType, cons
     Q_UNUSED(newFilePath)
     return false;
 }
+
+QList<ProjectExplorer::RunConfiguration *> CMakeProjectNode::runConfigurationsFor(Node *node)
+{
+    Q_UNUSED(node)
+    return QList<ProjectExplorer::RunConfiguration *>();
+}
index 79868eb..aea2c88 100644 (file)
@@ -63,6 +63,7 @@ public:
     virtual bool renameFile(const ProjectExplorer::FileType fileType,
                              const QString &filePath,
                              const QString &newFilePath);
+    virtual QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node);
 };
 
 } // namespace Internal
index 5ea726c..022df7b 100644 (file)
@@ -235,3 +235,9 @@ bool GenericProjectNode::renameFile(const ProjectExplorer::FileType fileType,
     Q_UNUSED(newFilePath)
     return false;
 }
+
+QList<ProjectExplorer::RunConfiguration *> GenericProjectNode::runConfigurationsFor(Node *node)
+{
+    Q_UNUSED(node)
+    return QList<ProjectExplorer::RunConfiguration *>();
+}
index 3a22e0c..3f9e74a 100644 (file)
@@ -80,6 +80,7 @@ public:
                              const QString &filePath,
                              const QString &newFilePath);
 
+    virtual QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node);
 
     void refresh();
 
index 1d01d0c..a8bb8a5 100644 (file)
@@ -180,6 +180,7 @@ struct ProjectExplorerPluginPrivate {
     QAction *m_setStartupProjectAction;
     QAction *m_projectSelectorAction;
     QAction *m_projectSelectorActionMenu;
+    QAction *m_runSubProject;
 
     Internal::ProjectWindow *m_proWindow;
     SessionManager *m_session;
@@ -428,10 +429,19 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
 
     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FIRST);
     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_BUILD);
+    msubProjectContextMenu->appendGroup(Constants::G_PROJECT_RUN);
     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_FILES);
     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_OTHER);
     msubProjectContextMenu->appendGroup(Constants::G_PROJECT_CONFIG);
 
+    Core::ActionContainer *runMenu = Core::ICore::instance()->actionManager()->createMenu(Constants::RUNMENUCONTEXTMENU);
+    runMenu->setOnAllDisabledBehavior(Core::ActionContainer::Hide);
+    QIcon runIcon(Constants::ICON_RUN);
+    runIcon.addFile(Constants::ICON_RUN_SMALL);
+    runMenu->menu()->setIcon(runIcon);
+    runMenu->menu()->setTitle("Run");
+    msubProjectContextMenu->addMenu(runMenu, ProjectExplorer::Constants::G_PROJECT_RUN);
+
     mfolderContextMenu->appendGroup(Constants::G_FOLDER_FILES);
     mfolderContextMenu->appendGroup(Constants::G_FOLDER_OTHER);
     mfolderContextMenu->appendGroup(Constants::G_FOLDER_CONFIG);
@@ -700,8 +710,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
     cmd = am->registerAction(d->m_cleanProjectOnlyAction, Constants::CLEANPROJECTONLY, globalcontext);
 
     // run action
-    QIcon runIcon(Constants::ICON_RUN);
-    runIcon.addFile(Constants::ICON_RUN_SMALL);
     d->m_runAction = new QAction(runIcon, tr("Run"), this);
     cmd = am->registerAction(d->m_runAction, Constants::RUN, globalcontext);
     cmd->setAttribute(Core::Command::CA_UpdateText);
@@ -714,6 +722,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
     d->m_runActionContextMenu = new QAction(runIcon, tr("Run"), this);
     cmd = am->registerAction(d->m_runActionContextMenu, Constants::RUNCONTEXTMENU, projecTreeContext);
     mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
+    msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_RUN);
 
     // cancel build action
     d->m_cancelBuildAction = new QAction(tr("Cancel Build"), this);
@@ -1714,7 +1723,18 @@ void ProjectExplorerPlugin::runProject()
 
 void ProjectExplorerPlugin::runProjectContextMenu()
 {
-    runProject(d->m_currentProject, ProjectExplorer::Constants::RUNMODE);
+    ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode);
+    if (projectNode == d->m_currentProject->rootProjectNode() || !projectNode) {
+        runProject(d->m_currentProject, ProjectExplorer::Constants::RUNMODE);
+    } else {
+        QAction *act = qobject_cast<QAction *>(sender());
+        if (!act)
+            return;
+        RunConfiguration *rc = act->data().value<RunConfiguration *>();
+        if (!rc)
+            return;
+        runRunConfiguration(rc, ProjectExplorer::Constants::RUNMODE);
+    }
 }
 
 bool ProjectExplorerPlugin::hasBuildSettings(Project *pro)
@@ -1770,12 +1790,17 @@ bool ProjectExplorerPlugin::hasDeploySettings(Project *pro)
     return false;
 }
 
-void ProjectExplorerPlugin::runProject(Project *pro, QString mode)
+void ProjectExplorerPlugin::runProject(Project *pro, const QString &mode)
 {
     if (!pro)
         return;
 
-    if (!pro->activeTarget()->activeRunConfiguration()->isEnabled())
+    runRunConfiguration(pro->activeTarget()->activeRunConfiguration(), mode);
+}
+
+void ProjectExplorerPlugin::runRunConfiguration(ProjectExplorer::RunConfiguration *rc, const QString &mode)
+{
+    if (!rc->isEnabled())
         return;
 
     QStringList stepIds;
@@ -1784,6 +1809,8 @@ void ProjectExplorerPlugin::runProject(Project *pro, QString mode)
             stepIds << Constants::BUILDSTEPS_BUILD;
         stepIds << Constants::BUILDSTEPS_DEPLOY;
     }
+
+    Project *pro = rc->target()->project();
     const QList<Project *> &projects = d->m_session->projectOrder(pro);
     int queueCount = queue(projects, stepIds);
 
@@ -1793,9 +1820,9 @@ void ProjectExplorerPlugin::runProject(Project *pro, QString mode)
     if (queueCount > 0) {
         // delay running till after our queued steps were processed
         d->m_runMode = mode;
-        d->m_delayedRunConfiguration = pro->activeTarget()->activeRunConfiguration();
+        d->m_delayedRunConfiguration = rc;
     } else {
-        executeRunConfiguration(pro->activeTarget()->activeRunConfiguration(), mode);
+        executeRunConfiguration(rc, mode);
     }
     emit updateRunActions();
 }
@@ -2072,12 +2099,37 @@ void ProjectExplorerPlugin::updateContextMenuActions()
     d->m_addExistingFilesAction->setVisible(true);
     d->m_removeFileAction->setVisible(true);
     d->m_deleteFileAction->setVisible(true);
+    d->m_runActionContextMenu->setVisible(false);
+
+    Core::ActionContainer *runMenu = Core::ICore::instance()->actionManager()->actionContainer(Constants::RUNMENUCONTEXTMENU);
+    runMenu->menu()->clear();
 
     if (d->m_currentNode && d->m_currentNode->projectNode()) {
         QList<ProjectNode::ProjectAction> actions =
                 d->m_currentNode->projectNode()->supportedActions(d->m_currentNode);
 
+        if (ProjectNode *pn = qobject_cast<ProjectNode *>(d->m_currentNode)) {
+            if (pn == d->m_currentProject->rootProjectNode()) {
+                d->m_runActionContextMenu->setVisible(true);
+            } else {
+                QList<RunConfiguration *> runConfigs = pn->runConfigurationsFor(pn);
+                if (runConfigs.count() == 1) {
+                    d->m_runActionContextMenu->setVisible(true);
+                    d->m_runActionContextMenu->setData(QVariant::fromValue(runConfigs.first()));
+                } else if (runConfigs.count() > 1) {
+                    foreach (RunConfiguration *rc, runConfigs) {
+                        QAction *act = new QAction(runMenu->menu());
+                        act->setData(QVariant::fromValue(rc));
+                        act->setText(QString("Run %1").arg(rc->displayName()));
+                        runMenu->menu()->addAction(act);
+                        connect(act, SIGNAL(triggered()),
+                                this, SLOT(runProjectContextMenu()));
+                    }
+                }
+            }
+        }
         if (qobject_cast<FolderNode*>(d->m_currentNode)) {
+            // Also handles ProjectNode
             d->m_addNewFileAction->setEnabled(actions.contains(ProjectNode::AddNewFile));
             d->m_addNewSubprojectAction->setEnabled(d->m_currentNode->nodeType() == ProjectNodeType
                                                     && actions.contains(ProjectNode::AddSubProject));
index 61926b4..3621e97 100644 (file)
@@ -117,7 +117,8 @@ public:
     bool coreAboutToClose();
 
     bool canRun(Project *pro, const QString &runMode);
-    void runProject(Project *pro, QString mode);
+    void runProject(Project *pro, const QString &mode);
+    void runRunConfiguration(ProjectExplorer::RunConfiguration *rc, const QString &mode);
 
 signals:
     void aboutToShowContextMenu(ProjectExplorer::Project *project,
index bfca377..005f029 100644 (file)
@@ -162,6 +162,8 @@ const char * const G_FILE_OPEN          = "ProjectFile.Group.Open";
 const char * const G_FILE_OTHER         = "ProjectFile.Group.Other";
 const char * const G_FILE_CONFIG        = "ProjectFile.Group.Config";
 
+const char * const RUNMENUCONTEXTMENU   = "Project.RunMenu";
+
 // file id
 const char * const FILE_FACTORY_ID      = "ProjectExplorer.FileFactoryId";
 
index ad9005e..6acba2e 100644 (file)
 #include <QtCore/QStringList>
 #include <QtGui/QIcon>
 
+#include "runconfiguration.h"
 #include "projectexplorer_export.h"
 
+
 QT_BEGIN_NAMESPACE
 class QFileInfo;
 QT_END_NAMESPACE
@@ -174,7 +176,8 @@ public:
         // that a file was deleted
         // DeleteFile is a define on windows...
         EraseFile,
-        Rename
+        Rename,
+        HasSubProjectRunConfigurations
     };
 
     // all subFolders that are projects
@@ -209,6 +212,9 @@ public:
     // by default returns false
     virtual bool deploysFolder(const QString &folder) const;
 
+    // TODO node parameter not really needed
+    virtual QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node) = 0;
+
 
     QList<NodesWatcher*> watchers() const;
     void registerWatcher(NodesWatcher *watcher);
index da40fca..7eb79d5 100644 (file)
@@ -228,5 +228,11 @@ bool QmlProjectNode::renameFile(const ProjectExplorer::FileType /*fileType*/,
     return true;
 }
 
+QList<ProjectExplorer::RunConfiguration *> QmlProjectNode::runConfigurationsFor(Node *node)
+{
+    Q_UNUSED(node)
+    return QList<ProjectExplorer::RunConfiguration *>();
+}
+
 } // namespace Internal
 } // namespace QmlProjectManager
index 52d3ef0..b371e06 100644 (file)
@@ -81,6 +81,7 @@ public:
     virtual bool renameFile(const ProjectExplorer::FileType fileType,
                              const QString &filePath,
                              const QString &newFilePath);
+    virtual QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node);
 
 
     void refresh();
index f4b8e47..af3f92c 100644 (file)
@@ -90,3 +90,13 @@ void Qt4DesktopTarget::createApplicationProFiles()
         addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(this));
     }
 }
+
+QList<ProjectExplorer::RunConfiguration *> Qt4DesktopTarget::runConfigurationsForNode(ProjectExplorer::Node *n)
+{
+    QList<ProjectExplorer::RunConfiguration *> result;
+    foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations())
+        if (Qt4RunConfiguration *qt4c = qobject_cast<Qt4RunConfiguration *>(rc))
+            if (qt4c->proFilePath() == n->path())
+                result << rc;
+    return result;
+}
index 68ef63c..00ad5a5 100644 (file)
@@ -50,6 +50,7 @@ public:
     ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
 
     void createApplicationProFiles();
+    QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n);
 
     static QString defaultDisplayName();
 
index 182521b..1d4afd4 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <QtCore/QStringList>
 #include <QtGui/QWidget>
+#include <QtCore/QMetaType>
 
 QT_BEGIN_NAMESPACE
 class QCheckBox;
index c15df4c..9cff547 100644 (file)
@@ -94,3 +94,13 @@ void Qt4SimulatorTarget::createApplicationProFiles()
         addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(this));
     }
 }
+
+QList<ProjectExplorer::RunConfiguration *> Qt4SimulatorTarget::runConfigurationsForNode(ProjectExplorer::Node *n)
+{
+    QList<ProjectExplorer::RunConfiguration *> result;
+    foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations())
+        if (Qt4RunConfiguration *qt4c = qobject_cast<Qt4RunConfiguration *>(rc))
+            if (qt4c->proFilePath() == n->path())
+                result << rc;
+    return result;
+}
index c9b6858..83dff2a 100644 (file)
@@ -50,6 +50,7 @@ public:
     ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
 
     void createApplicationProFiles();
+    QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n);
 
     static QString defaultDisplayName();
 
index 946b445..09a4f26 100644 (file)
@@ -116,6 +116,16 @@ void AbstractQt4MaemoTarget::createApplicationProFiles()
     }
 }
 
+QList<ProjectExplorer::RunConfiguration *> AbstractQt4MaemoTarget::runConfigurationsForNode(ProjectExplorer::Node *n)
+{
+    QList<ProjectExplorer::RunConfiguration *> result;
+    foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations())
+        if (MaemoRunConfiguration *mrc = qobject_cast<MaemoRunConfiguration *>(rc))
+            if (mrc->proFilePath() == n->path())
+                result << rc;
+    return result;
+}
+
 QString AbstractQt4MaemoTarget::projectVersion(QString *error) const
 {
     QSharedPointer<QFile> changeLog = openFile(changeLogFilePath(),
index 4ce6f3b..af5a382 100644 (file)
@@ -56,6 +56,7 @@ public:
     ProjectExplorer::DeployConfigurationFactory *deployConfigurationFactory() const;
     QString defaultBuildDirectory() const;
     void createApplicationProFiles();
+    QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n);
 
     QString debianDirPath() const;
     QStringList debianFiles() const;
index 2687dd1..a66d07f 100644 (file)
@@ -157,6 +157,23 @@ void Qt4SymbianTarget::createApplicationProFiles()
     }
 }
 
+QList<ProjectExplorer::RunConfiguration *> Qt4SymbianTarget::runConfigurationsForNode(ProjectExplorer::Node *n)
+{
+    QList<ProjectExplorer::RunConfiguration *> result;
+    foreach (ProjectExplorer::RunConfiguration *rc, runConfigurations()) {
+        if (id() == QLatin1String(Constants::S60_EMULATOR_TARGET_ID)) {
+            if (S60EmulatorRunConfiguration * s60rc = qobject_cast<S60EmulatorRunConfiguration *>(rc))
+                if (s60rc->proFilePath() == n->path())
+                    result << rc;
+        } else if (id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID)) {
+            if (S60DeviceRunConfiguration *s60rc = qobject_cast<S60DeviceRunConfiguration *>(rc))
+                if (s60rc->proFilePath() == n->path())
+                    result << rc;
+        }
+    }
+    return result;
+}
+
 bool Qt4SymbianTarget::isSymbianConnectionAvailable(QString &tooltipText)
 {
     const S60DeployConfiguration *s60DeployConf = qobject_cast<S60DeployConfiguration *>(activeDeployConfiguration());
index e4a2c92..cf88165 100644 (file)
@@ -56,6 +56,7 @@ public:
     QString defaultBuildDirectory() const;
 
     void createApplicationProFiles();
+    virtual QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n);
 
     static QString defaultDisplayName(const QString &id);
     static QIcon iconForId(const QString &id);
index a07f7c0..af9aff2 100644 (file)
@@ -760,6 +760,11 @@ bool Qt4PriFileNode::deploysFolder(const QString &folder) const
     return false;
 }
 
+QList<ProjectExplorer::RunConfiguration *> Qt4PriFileNode::runConfigurationsFor(Node *node)
+{
+    return m_project->activeTarget()->runConfigurationsForNode(node);
+}
+
 QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions(Node *node) const
 {
     QList<ProjectAction> actions;
@@ -811,6 +816,9 @@ QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions(Node *node) c
     if (fileNode && fileNode->fileType() != ProjectExplorer::ProjectFileType)
         actions << Rename;
 
+    if (!m_project->activeTarget()->runConfigurationsForNode(node).isEmpty())
+        actions << HasSubProjectRunConfigurations;
+
     return actions;
 }
 
index f760a9d..fe73c35 100644 (file)
@@ -37,6 +37,7 @@
 #include <coreplugin/ifile.h>
 #include <projectexplorer/projectnodes.h>
 #include <projectexplorer/project.h>
+#include <projectexplorer/runconfiguration.h>
 
 #include <QtCore/QHash>
 #include <QtCore/QStringList>
@@ -164,6 +165,7 @@ public:
     void folderChanged(const QString &changedFolder);
 
     bool deploysFolder(const QString &folder) const;
+    QList<ProjectExplorer::RunConfiguration *> runConfigurationsFor(Node *node);
 
 protected:
     void clear();
@@ -310,6 +312,7 @@ public:
     bool validParse() const;
 
     bool hasBuildTargets(Qt4ProjectType projectType) const;
+
 public slots:
     void asyncUpdate();
 
index d22549a..8a39b1f 100644 (file)
@@ -68,6 +68,8 @@ const char * const RUNQMAKECONTEXTMENU = "Qt4Builder.RunQMakeContextMenu";
 const char * const BUILDSUBDIR         = "Qt4Builder.BuildSubDir";
 const char * const REBUILDSUBDIR       = "Qt4Builder.RebuildSubDir";
 const char * const CLEANSUBDIR         = "Qt4Builder.CleanSubDir";
+const char * const RUNSUBDIR           = "Qt4Builder.RunSubDir";
+const char * const RUNMENUSUBDIR       = "Qt4Builder.RunMenuSubDir";
 const char * const ADDLIBRARY          = "Qt4.AddLibrary";
 const char * const JUMP_TO_FILE        = "Qt4.JumpToFile";
 const char * const SEPARATOR           = "Qt4.Separator";
index 7ed77f5..5008639 100644 (file)
@@ -85,6 +85,7 @@
 #endif
 
 #include <QtCore/QtPlugin>
+#include <QtGui/QMenu>
 
 using namespace Qt4ProjectManager::Internal;
 using namespace Qt4ProjectManager;
index 926a871..955621d 100644 (file)
@@ -36,7 +36,9 @@
 
 #include "qt4buildconfiguration.h"
 #include "qtversionmanager.h"
+
 #include <projectexplorer/target.h>
+#include <projectexplorer/projectnodes.h>
 
 namespace Qt4ProjectManager {
 
@@ -81,6 +83,8 @@ public:
     virtual QList<ProjectExplorer::ToolChainType> filterToolChainTypes(const QList<ProjectExplorer::ToolChainType> &candidates) const;
     virtual ProjectExplorer::ToolChainType preferredToolChainType(const QList<ProjectExplorer::ToolChainType> &candidates) const;
     virtual QString defaultBuildDirectory() const;
+
+    virtual QList<ProjectExplorer::RunConfiguration *> runConfigurationsForNode(ProjectExplorer::Node *n) = 0;
 signals:
     void buildDirectoryInitialized();
     /// emitted if the build configuration changed in a way that