Commit 27fd8d4e authored by Daniel Teske's avatar Daniel Teske

ProjectTree: Fix context menu actions

Opening the context menu would move the focus, which then would
reset the current node/project to come from the DocumentManager.

So move the context menu handling code to the ProjectTree class
and ensure that while it is open, the corresponding ProjectTree
is considered the focused widget.

Task-number: QTCREATORBUG-13684
Change-Id: I8b3dc410f5f5bc5e9a2dd663421b22cf3f147190
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
parent 7e522c8a
...@@ -40,8 +40,9 @@ ...@@ -40,8 +40,9 @@
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <QDateTime> #include <QDateTime>
using namespace CMakeProjectManager::Internal; using namespace CMakeProjectManager::Internal;
...@@ -49,8 +50,8 @@ using namespace CMakeProjectManager::Internal; ...@@ -49,8 +50,8 @@ using namespace CMakeProjectManager::Internal;
CMakeManager::CMakeManager(CMakeSettingsPage *cmakeSettingsPage) CMakeManager::CMakeManager(CMakeSettingsPage *cmakeSettingsPage)
: m_settingsPage(cmakeSettingsPage) : m_settingsPage(cmakeSettingsPage)
{ {
ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance(); ProjectExplorer::ProjectTree *tree = ProjectExplorer::ProjectTree::instance();
connect(projectExplorer, &ProjectExplorer::ProjectExplorerPlugin::aboutToShowContextMenu, connect(tree, &ProjectExplorer::ProjectTree::aboutToShowContextMenu,
this, &CMakeManager::updateContextMenu); this, &CMakeManager::updateContextMenu);
Core::ActionContainer *mbuild = Core::ActionContainer *mbuild =
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projecttree.h>
#include <projectexplorer/selectablefilesmodel.h> #include <projectexplorer/selectablefilesmodel.h>
#include <QtPlugin> #include <QtPlugin>
...@@ -85,7 +85,7 @@ bool GenericProjectPlugin::initialize(const QStringList &, QString *errorMessage ...@@ -85,7 +85,7 @@ bool GenericProjectPlugin::initialize(const QStringList &, QString *errorMessage
connect(editFilesAction, &QAction::triggered, connect(editFilesAction, &QAction::triggered,
this, &GenericProjectPlugin::editFiles); this, &GenericProjectPlugin::editFiles);
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::aboutToShowContextMenu, connect(ProjectTree::instance(), &ProjectTree::aboutToShowContextMenu,
[this] (Project *project, Node *) { m_contextMenuProject = project; }); [this] (Project *project, Node *) { m_contextMenuProject = project; });
return true; return true;
......
...@@ -208,12 +208,7 @@ public: ...@@ -208,12 +208,7 @@ public:
void updateDeployActions(); void updateDeployActions();
void updateRunWithoutDeployMenu(); void updateRunWithoutDeployMenu();
QMenu *m_sessionContextMenu;
QMenu *m_sessionMenu; QMenu *m_sessionMenu;
QMenu *m_projectMenu;
QMenu *m_subProjectMenu;
QMenu *m_folderMenu;
QMenu *m_fileMenu;
QMenu *m_openWithMenu; QMenu *m_openWithMenu;
QMultiMap<int, QObject*> m_actionMap; QMultiMap<int, QObject*> m_actionMap;
...@@ -550,12 +545,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er ...@@ -550,12 +545,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
ActionContainer *mfileContextMenu = ActionContainer *mfileContextMenu =
ActionManager::createMenu(Constants::M_FILECONTEXT); ActionManager::createMenu(Constants::M_FILECONTEXT);
dd->m_sessionContextMenu = msessionContextMenu->menu();
dd->m_projectMenu = mprojectContextMenu->menu();
dd->m_subProjectMenu = msubProjectContextMenu->menu();
dd->m_folderMenu = mfolderContextMenu->menu();
dd->m_fileMenu = mfileContextMenu->menu();
ActionContainer *mfile = ActionContainer *mfile =
ActionManager::actionContainer(Core::Constants::M_FILE); ActionManager::actionContainer(Core::Constants::M_FILE);
ActionContainer *menubar = ActionContainer *menubar =
...@@ -1092,6 +1081,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er ...@@ -1092,6 +1081,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
connect(dd->m_deleteFileAction, SIGNAL(triggered()), this, SLOT(deleteFile())); connect(dd->m_deleteFileAction, SIGNAL(triggered()), this, SLOT(deleteFile()));
connect(dd->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile())); connect(dd->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));
connect(dd->m_setStartupProjectAction, SIGNAL(triggered()), this, SLOT(setStartupProject())); connect(dd->m_setStartupProjectAction, SIGNAL(triggered()), this, SLOT(setStartupProject()));
connect(dd->m_projectTreeCollapseAllAction, &QAction::triggered,
ProjectTree::instance(), &ProjectTree::collapseAll);
connect(this, SIGNAL(updateRunActions()), this, SLOT(slotUpdateRunActions())); connect(this, SIGNAL(updateRunActions()), this, SLOT(slotUpdateRunActions()));
connect(this, &ProjectExplorerPlugin::settingsChanged, connect(this, &ProjectExplorerPlugin::settingsChanged,
...@@ -1669,6 +1660,11 @@ QStringList ProjectExplorerPlugin::projectFileGlobs() ...@@ -1669,6 +1660,11 @@ QStringList ProjectExplorerPlugin::projectFileGlobs()
return result; return result;
} }
void ProjectExplorerPlugin::updateContextMenuActions()
{
dd->updateContextMenuActions();
}
/*! /*!
This function is connected to the ICore::coreOpened signal. If This function is connected to the ICore::coreOpened signal. If
there was no session explicitly loaded, it creates an empty new there was no session explicitly loaded, it creates an empty new
...@@ -1758,49 +1754,6 @@ void ProjectExplorerPlugin::loadSession(const QString &session) ...@@ -1758,49 +1754,6 @@ void ProjectExplorerPlugin::loadSession(const QString &session)
SessionManager::loadSession(session); SessionManager::loadSession(session);
} }
void ProjectExplorerPlugin::showContextMenu(QWidget *view, const QPoint &globalPos, Node *node)
{
QMenu *contextMenu = 0;
if (!node)
node = SessionManager::sessionNode();
if (node->nodeType() != SessionNodeType) {
Project *project = SessionManager::projectForNode(node);
emit m_instance->aboutToShowContextMenu(project, node);
switch (node->nodeType()) {
case ProjectNodeType:
if (node->parentFolderNode() == SessionManager::sessionNode())
contextMenu = dd->m_projectMenu;
else
contextMenu = dd->m_subProjectMenu;
break;
case VirtualFolderNodeType:
case FolderNodeType:
contextMenu = dd->m_folderMenu;
break;
case FileNodeType:
m_instance->populateOpenWithMenu();
contextMenu = dd->m_fileMenu;
break;
default:
qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
}
} else { // session item
emit m_instance->aboutToShowContextMenu(0, node);
contextMenu = dd->m_sessionContextMenu;
}
dd->updateContextMenuActions();
dd->m_projectTreeCollapseAllAction->disconnect(SIGNAL(triggered()));
connect(dd->m_projectTreeCollapseAllAction, SIGNAL(triggered()), view, SLOT(collapseAll()));
if (contextMenu && contextMenu->actions().count() > 0)
contextMenu->popup(globalPos);
}
void ProjectExplorerPlugin::buildStateChanged(Project * pro) void ProjectExplorerPlugin::buildStateChanged(Project * pro)
{ {
if (debug) { if (debug) {
...@@ -2857,6 +2810,8 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() ...@@ -2857,6 +2810,8 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
dd->m_removeFileAction->setVisible(!enableDelete || enableRemove); dd->m_removeFileAction->setVisible(!enableDelete || enableRemove);
dd->m_renameFileAction->setEnabled(actions.contains(Rename)); dd->m_renameFileAction->setEnabled(actions.contains(Rename));
DocumentManager::populateOpenWithMenu(dd->m_openWithMenu, ProjectTree::currentNode()->path());
} }
if (actions.contains(HidePathActions)) { if (actions.contains(HidePathActions)) {
...@@ -3111,11 +3066,6 @@ void ProjectExplorerPlugin::showRenameFileError() ...@@ -3111,11 +3066,6 @@ void ProjectExplorerPlugin::showRenameFileError()
QMessageBox::warning(ICore::mainWindow(), tr("Project Editing Failed"), dd->m_renameFileError); QMessageBox::warning(ICore::mainWindow(), tr("Project Editing Failed"), dd->m_renameFileError);
} }
void ProjectExplorerPlugin::populateOpenWithMenu()
{
DocumentManager::populateOpenWithMenu(dd->m_openWithMenu, ProjectTree::currentNode()->path());
}
void ProjectExplorerPlugin::updateSessionMenu() void ProjectExplorerPlugin::updateSessionMenu()
{ {
dd->m_sessionMenu->clear(); dd->m_sessionMenu->clear();
......
...@@ -117,11 +117,11 @@ public: ...@@ -117,11 +117,11 @@ public:
static QString directoryFor(Node *node); static QString directoryFor(Node *node);
static QStringList projectFileGlobs(); static QStringList projectFileGlobs();
static void updateContextMenuActions();
signals: signals:
void runControlStarted(ProjectExplorer::RunControl *rc); void runControlStarted(ProjectExplorer::RunControl *rc);
void runControlFinished(ProjectExplorer::RunControl *rc); void runControlFinished(ProjectExplorer::RunControl *rc);
void aboutToShowContextMenu(ProjectExplorer::Project *project,
ProjectExplorer::Node *node);
// Is emitted when a project has been added/removed, // Is emitted when a project has been added/removed,
// or the file list of a specific project has changed. // or the file list of a specific project has changed.
...@@ -163,7 +163,6 @@ private slots: ...@@ -163,7 +163,6 @@ private slots:
void closeAllProjects(); void closeAllProjects();
void newProject(); void newProject();
void showSessionManager(); void showSessionManager();
void populateOpenWithMenu();
void updateSessionMenu(); void updateSessionMenu();
void setSession(QAction *action); void setSession(QAction *action);
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "session.h" #include "session.h"
#include "project.h" #include "project.h"
#include "projectnodes.h" #include "projectnodes.h"
#include "projectexplorerconstants.h"
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <coreplugin/documentmanager.h> #include <coreplugin/documentmanager.h>
...@@ -41,6 +42,8 @@ ...@@ -41,6 +42,8 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/infobar.h> #include <coreplugin/infobar.h>
#include <coreplugin/vcsmanager.h> #include <coreplugin/vcsmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <QApplication> #include <QApplication>
#include <QTimer> #include <QTimer>
...@@ -60,7 +63,8 @@ ProjectTree::ProjectTree(QObject *parent) ...@@ -60,7 +63,8 @@ ProjectTree::ProjectTree(QObject *parent)
m_currentProject(0), m_currentProject(0),
m_resetCurrentNodeFolder(false), m_resetCurrentNodeFolder(false),
m_resetCurrentNodeFile(false), m_resetCurrentNodeFile(false),
m_resetCurrentNodeProject(false) m_resetCurrentNodeProject(false),
m_focusForContextMenu(0)
{ {
s_instance = this; s_instance = this;
...@@ -120,8 +124,10 @@ void ProjectTree::focusChanged() ...@@ -120,8 +124,10 @@ void ProjectTree::focusChanged()
void ProjectTree::updateFromFocus(bool invalidCurrentNode) void ProjectTree::updateFromFocus(bool invalidCurrentNode)
{ {
ProjectTreeWidget *focus = Utils::findOrDefault(m_projectTreeWidgets, ProjectTreeWidget *focus = m_focusForContextMenu;
&ProjectTree::hasFocus); if (!focus)
focus = Utils::findOrDefault(m_projectTreeWidgets,
&ProjectTree::hasFocus);
if (focus) if (focus)
updateFromProjectTreeWidget(focus); updateFromProjectTreeWidget(focus);
...@@ -365,6 +371,12 @@ void ProjectTree::emitNodeSortKeyChanged(Node *node) ...@@ -365,6 +371,12 @@ void ProjectTree::emitNodeSortKeyChanged(Node *node)
emit nodeSortKeyChanged(); emit nodeSortKeyChanged();
} }
void ProjectTree::collapseAll()
{
if (m_focusForContextMenu)
m_focusForContextMenu->collapseAll();
}
void ProjectTree::updateExternalFileWarning() void ProjectTree::updateExternalFileWarning()
{ {
Core::IDocument *document = qobject_cast<Core::IDocument *>(sender()); Core::IDocument *document = qobject_cast<Core::IDocument *>(sender());
...@@ -402,7 +414,56 @@ void ProjectTree::updateExternalFileWarning() ...@@ -402,7 +414,56 @@ void ProjectTree::updateExternalFileWarning()
bool ProjectTree::hasFocus(ProjectTreeWidget *widget) bool ProjectTree::hasFocus(ProjectTreeWidget *widget)
{ {
return widget && widget->focusWidget() && widget->focusWidget()->hasFocus(); return widget
&& ((widget->focusWidget() && widget->focusWidget()->hasFocus())
|| s_instance->m_focusForContextMenu == widget);
}
void ProjectTree::showContextMenu(ProjectTreeWidget *focus, const QPoint &globalPos, Node *node)
{
QMenu *contextMenu = 0;
if (!node)
node = SessionManager::sessionNode();
if (node->nodeType() != SessionNodeType) {
Project *project = SessionManager::projectForNode(node);
emit s_instance->aboutToShowContextMenu(project, node);
switch (node->nodeType()) {
case ProjectNodeType:
if (node->parentFolderNode() == SessionManager::sessionNode())
contextMenu = Core::ActionManager::actionContainer(Constants::M_PROJECTCONTEXT)->menu();
else
contextMenu = Core::ActionManager::actionContainer(Constants::M_SUBPROJECTCONTEXT)->menu();
break;
case VirtualFolderNodeType:
case FolderNodeType:
contextMenu = Core::ActionManager::actionContainer(Constants::M_FOLDERCONTEXT)->menu();
break;
case FileNodeType:
contextMenu = Core::ActionManager::actionContainer(Constants::M_FILECONTEXT)->menu();
break;
default:
qWarning("ProjectExplorerPlugin::showContextMenu - Missing handler for node type");
}
} else { // session item
emit s_instance->aboutToShowContextMenu(0, node);
contextMenu = Core::ActionManager::actionContainer(Constants::M_SESSIONCONTEXT)->menu();
}
if (contextMenu && contextMenu->actions().count() > 0) {
contextMenu->popup(globalPos);
s_instance->m_focusForContextMenu = focus;
connect(contextMenu, &QMenu::aboutToHide,
s_instance, &ProjectTree::hideContextMenu,
Qt::UniqueConnection);
}
}
void ProjectTree::hideContextMenu()
{
m_focusForContextMenu = 0;
} }
bool ProjectTree::isInNodeHierarchy(Node *n) bool ProjectTree::isInNodeHierarchy(Node *n)
......
...@@ -63,6 +63,9 @@ public: ...@@ -63,6 +63,9 @@ public:
static Project *projectForNode(Node *node); static Project *projectForNode(Node *node);
static void aboutToShutDown(); static void aboutToShutDown();
static void showContextMenu(Internal::ProjectTreeWidget *focus, const QPoint &globalPos, Node *node);
signals: signals:
void currentProjectChanged(ProjectExplorer::Project *project); void currentProjectChanged(ProjectExplorer::Project *project);
void currentNodeChanged(ProjectExplorer::Node *node, ProjectExplorer::Project *project); void currentNodeChanged(ProjectExplorer::Node *node, ProjectExplorer::Project *project);
...@@ -94,6 +97,9 @@ signals: ...@@ -94,6 +97,9 @@ signals:
void nodeSortKeyAboutToChange(Node *node); void nodeSortKeyAboutToChange(Node *node);
void nodeSortKeyChanged(); void nodeSortKeyChanged();
void aboutToShowContextMenu(ProjectExplorer::Project *project,
ProjectExplorer::Node *node);
public: // for nodes to emit signals, do not call unless you are a node public: // for nodes to emit signals, do not call unless you are a node
void emitNodeUpdated(ProjectExplorer::Node *node); void emitNodeUpdated(ProjectExplorer::Node *node);
...@@ -121,6 +127,8 @@ public: // for nodes to emit signals, do not call unless you are a node ...@@ -121,6 +127,8 @@ public: // for nodes to emit signals, do not call unless you are a node
void emitNodeSortKeyAboutToChange(Node *node); void emitNodeSortKeyAboutToChange(Node *node);
void emitNodeSortKeyChanged(Node *node); void emitNodeSortKeyChanged(Node *node);
void collapseAll();
private: private:
void focusChanged(); void focusChanged();
void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget); void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget);
...@@ -144,6 +152,7 @@ private: ...@@ -144,6 +152,7 @@ private:
bool m_resetCurrentNodeFolder; bool m_resetCurrentNodeFolder;
bool m_resetCurrentNodeFile; bool m_resetCurrentNodeFile;
bool m_resetCurrentNodeProject; bool m_resetCurrentNodeProject;
Internal::ProjectTreeWidget *m_focusForContextMenu;
Core::Context m_lastProjectContext; Core::Context m_lastProjectContext;
}; };
} }
......
...@@ -403,7 +403,7 @@ void ProjectTreeWidget::showContextMenu(const QPoint &pos) ...@@ -403,7 +403,7 @@ void ProjectTreeWidget::showContextMenu(const QPoint &pos)
{ {
QModelIndex index = m_view->indexAt(pos); QModelIndex index = m_view->indexAt(pos);
Node *node = m_model->nodeForIndex(index); Node *node = m_model->nodeForIndex(index);
ProjectExplorerPlugin::showContextMenu(this, m_view->mapToGlobal(pos), node); ProjectTree::showContextMenu(this, m_view->mapToGlobal(pos), node);
} }
void ProjectTreeWidget::handleProjectAdded(Project *project) void ProjectTreeWidget::handleProjectAdded(Project *project)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment