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 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <QDateTime>
using namespace CMakeProjectManager::Internal;
......@@ -49,8 +50,8 @@ using namespace CMakeProjectManager::Internal;
CMakeManager::CMakeManager(CMakeSettingsPage *cmakeSettingsPage)
: m_settingsPage(cmakeSettingsPage)
{
ProjectExplorer::ProjectExplorerPlugin *projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
connect(projectExplorer, &ProjectExplorer::ProjectExplorerPlugin::aboutToShowContextMenu,
ProjectExplorer::ProjectTree *tree = ProjectExplorer::ProjectTree::instance();
connect(tree, &ProjectExplorer::ProjectTree::aboutToShowContextMenu,
this, &CMakeManager::updateContextMenu);
Core::ActionContainer *mbuild =
......
......@@ -44,7 +44,7 @@
#include <coreplugin/actionmanager/actioncontainer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/selectablefilesmodel.h>
#include <QtPlugin>
......@@ -85,7 +85,7 @@ bool GenericProjectPlugin::initialize(const QStringList &, QString *errorMessage
connect(editFilesAction, &QAction::triggered,
this, &GenericProjectPlugin::editFiles);
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::aboutToShowContextMenu,
connect(ProjectTree::instance(), &ProjectTree::aboutToShowContextMenu,
[this] (Project *project, Node *) { m_contextMenuProject = project; });
return true;
......
......@@ -208,12 +208,7 @@ public:
void updateDeployActions();
void updateRunWithoutDeployMenu();
QMenu *m_sessionContextMenu;
QMenu *m_sessionMenu;
QMenu *m_projectMenu;
QMenu *m_subProjectMenu;
QMenu *m_folderMenu;
QMenu *m_fileMenu;
QMenu *m_openWithMenu;
QMultiMap<int, QObject*> m_actionMap;
......@@ -550,12 +545,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
ActionContainer *mfileContextMenu =
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 =
ActionManager::actionContainer(Core::Constants::M_FILE);
ActionContainer *menubar =
......@@ -1092,6 +1081,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
connect(dd->m_deleteFileAction, SIGNAL(triggered()), this, SLOT(deleteFile()));
connect(dd->m_renameFileAction, SIGNAL(triggered()), this, SLOT(renameFile()));
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, &ProjectExplorerPlugin::settingsChanged,
......@@ -1669,6 +1660,11 @@ QStringList ProjectExplorerPlugin::projectFileGlobs()
return result;
}
void ProjectExplorerPlugin::updateContextMenuActions()
{
dd->updateContextMenuActions();
}
/*!
This function is connected to the ICore::coreOpened signal. If
there was no session explicitly loaded, it creates an empty new
......@@ -1758,49 +1754,6 @@ void ProjectExplorerPlugin::loadSession(const QString &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)
{
if (debug) {
......@@ -2857,6 +2810,8 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
dd->m_removeFileAction->setVisible(!enableDelete || enableRemove);
dd->m_renameFileAction->setEnabled(actions.contains(Rename));
DocumentManager::populateOpenWithMenu(dd->m_openWithMenu, ProjectTree::currentNode()->path());
}
if (actions.contains(HidePathActions)) {
......@@ -3111,11 +3066,6 @@ void ProjectExplorerPlugin::showRenameFileError()
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()
{
dd->m_sessionMenu->clear();
......
......@@ -117,11 +117,11 @@ public:
static QString directoryFor(Node *node);
static QStringList projectFileGlobs();
static void updateContextMenuActions();
signals:
void runControlStarted(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,
// or the file list of a specific project has changed.
......@@ -163,7 +163,6 @@ private slots:
void closeAllProjects();
void newProject();
void showSessionManager();
void populateOpenWithMenu();
void updateSessionMenu();
void setSession(QAction *action);
......
......@@ -33,6 +33,7 @@
#include "session.h"
#include "project.h"
#include "projectnodes.h"
#include "projectexplorerconstants.h"
#include <utils/algorithm.h>
#include <coreplugin/documentmanager.h>
......@@ -41,6 +42,8 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/infobar.h>
#include <coreplugin/vcsmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <QApplication>
#include <QTimer>
......@@ -60,7 +63,8 @@ ProjectTree::ProjectTree(QObject *parent)
m_currentProject(0),
m_resetCurrentNodeFolder(false),
m_resetCurrentNodeFile(false),
m_resetCurrentNodeProject(false)
m_resetCurrentNodeProject(false),
m_focusForContextMenu(0)
{
s_instance = this;
......@@ -120,7 +124,9 @@ void ProjectTree::focusChanged()
void ProjectTree::updateFromFocus(bool invalidCurrentNode)
{
ProjectTreeWidget *focus = Utils::findOrDefault(m_projectTreeWidgets,
ProjectTreeWidget *focus = m_focusForContextMenu;
if (!focus)
focus = Utils::findOrDefault(m_projectTreeWidgets,
&ProjectTree::hasFocus);
if (focus)
......@@ -365,6 +371,12 @@ void ProjectTree::emitNodeSortKeyChanged(Node *node)
emit nodeSortKeyChanged();
}
void ProjectTree::collapseAll()
{
if (m_focusForContextMenu)
m_focusForContextMenu->collapseAll();
}
void ProjectTree::updateExternalFileWarning()
{
Core::IDocument *document = qobject_cast<Core::IDocument *>(sender());
......@@ -402,7 +414,56 @@ void ProjectTree::updateExternalFileWarning()
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)
......
......@@ -63,6 +63,9 @@ public:
static Project *projectForNode(Node *node);
static void aboutToShutDown();
static void showContextMenu(Internal::ProjectTreeWidget *focus, const QPoint &globalPos, Node *node);
signals:
void currentProjectChanged(ProjectExplorer::Project *project);
void currentNodeChanged(ProjectExplorer::Node *node, ProjectExplorer::Project *project);
......@@ -94,6 +97,9 @@ signals:
void nodeSortKeyAboutToChange(Node *node);
void nodeSortKeyChanged();
void aboutToShowContextMenu(ProjectExplorer::Project *project,
ProjectExplorer::Node *node);
public: // for nodes to emit signals, do not call unless you are a node
void emitNodeUpdated(ProjectExplorer::Node *node);
......@@ -121,6 +127,8 @@ public: // for nodes to emit signals, do not call unless you are a node
void emitNodeSortKeyAboutToChange(Node *node);
void emitNodeSortKeyChanged(Node *node);
void collapseAll();
private:
void focusChanged();
void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget);
......@@ -144,6 +152,7 @@ private:
bool m_resetCurrentNodeFolder;
bool m_resetCurrentNodeFile;
bool m_resetCurrentNodeProject;
Internal::ProjectTreeWidget *m_focusForContextMenu;
Core::Context m_lastProjectContext;
};
}
......
......@@ -403,7 +403,7 @@ void ProjectTreeWidget::showContextMenu(const QPoint &pos)
{
QModelIndex index = m_view->indexAt(pos);
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)
......
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