Project Tree: Delay syncing with editor when using the context menu

When "Synchronize with Editor" is enabled, every focus change in the
application causes the current node in the project tree to be reset to
the one corresponding to the current document. In order to still be able
to use the context menu, there is a flag in the project tree suppressing
this behavior for as long as the context menu is open. However, some
actions offered by the context menu open an additional dialog, and it is
confusing to users if the current node changes at this point.
We therefore extend abovementioned hack so that the suppression of
automatic syncing is extended for the lifetime of the function called
from the context menu.

Fixes: QTCREATORBUG-24699
Change-Id: I209150aee76e534a966efc4d0afe5261d6dcd521
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-09-28 10:44:09 +02:00
parent 84bbab1c97
commit a5026d7a2f
3 changed files with 33 additions and 1 deletions

View File

@@ -1712,6 +1712,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
connect(dd->m_filePropertiesAction, &QAction::triggered, this, []() { connect(dd->m_filePropertiesAction, &QAction::triggered, this, []() {
const Node *currentNode = ProjectTree::currentNode(); const Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode && currentNode->asFileNode(), return); QTC_ASSERT(currentNode && currentNode->asFileNode(), return);
ProjectTree::CurrentNodeKeeper nodeKeeper;
DocumentManager::showFilePropertiesDialog(currentNode->filePath()); DocumentManager::showFilePropertiesDialog(currentNode->filePath());
}); });
connect(dd->m_removeFileAction, &QAction::triggered, connect(dd->m_removeFileAction, &QAction::triggered,
@@ -3618,6 +3619,8 @@ void ProjectExplorerPluginPrivate::removeFile()
const Node *currentNode = ProjectTree::currentNode(); const Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode && currentNode->asFileNode(), return); QTC_ASSERT(currentNode && currentNode->asFileNode(), return);
ProjectTree::CurrentNodeKeeper nodeKeeper;
const Utils::FilePath filePath = currentNode->filePath(); const Utils::FilePath filePath = currentNode->filePath();
using NodeAndPath = QPair<const Node *, Utils::FilePath>; using NodeAndPath = QPair<const Node *, Utils::FilePath>;
QList<NodeAndPath> filesToRemove{qMakePair(currentNode, currentNode->filePath())}; QList<NodeAndPath> filesToRemove{qMakePair(currentNode, currentNode->filePath())};
@@ -3685,6 +3688,8 @@ void ProjectExplorerPluginPrivate::duplicateFile()
Node *currentNode = ProjectTree::currentNode(); Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode && currentNode->asFileNode(), return); QTC_ASSERT(currentNode && currentNode->asFileNode(), return);
ProjectTree::CurrentNodeKeeper nodeKeeper;
FileNode *fileNode = currentNode->asFileNode(); FileNode *fileNode = currentNode->asFileNode();
QString filePath = currentNode->filePath().toString(); QString filePath = currentNode->filePath().toString();
QFileInfo sourceFileInfo(filePath); QFileInfo sourceFileInfo(filePath);
@@ -3725,6 +3730,8 @@ void ProjectExplorerPluginPrivate::deleteFile()
Node *currentNode = ProjectTree::currentNode(); Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode && currentNode->asFileNode(), return); QTC_ASSERT(currentNode && currentNode->asFileNode(), return);
ProjectTree::CurrentNodeKeeper nodeKeeper;
FileNode *fileNode = currentNode->asFileNode(); FileNode *fileNode = currentNode->asFileNode();
QString filePath = currentNode->filePath().toString(); QString filePath = currentNode->filePath().toString();

View File

@@ -490,7 +490,23 @@ const QList<Node *> ProjectTree::siblingsWithSameBaseName(const Node *fileNode)
void ProjectTree::hideContextMenu() void ProjectTree::hideContextMenu()
{ {
if (m_keepCurrentNodeRequests == 0)
m_focusForContextMenu = nullptr; m_focusForContextMenu = nullptr;
} }
ProjectTree::CurrentNodeKeeper::CurrentNodeKeeper()
: m_active(ProjectTree::instance()->m_focusForContextMenu)
{
if (m_active)
++ProjectTree::instance()->m_keepCurrentNodeRequests;
}
ProjectTree::CurrentNodeKeeper::~CurrentNodeKeeper()
{
if (m_active && --ProjectTree::instance()->m_keepCurrentNodeRequests == 0) {
ProjectTree::instance()->m_focusForContextMenu = nullptr;
ProjectTree::instance()->update();
}
}
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -60,6 +60,14 @@ public:
static Node *currentNode(); static Node *currentNode();
static Utils::FilePath currentFilePath(); static Utils::FilePath currentFilePath();
class CurrentNodeKeeper {
public:
CurrentNodeKeeper();
~CurrentNodeKeeper();
private:
const bool m_active = false;
};
// Integration with ProjectTreeWidget // Integration with ProjectTreeWidget
static void registerWidget(Internal::ProjectTreeWidget *widget); static void registerWidget(Internal::ProjectTreeWidget *widget);
static void unregisterWidget(Internal::ProjectTreeWidget *widget); static void unregisterWidget(Internal::ProjectTreeWidget *widget);
@@ -131,6 +139,7 @@ private:
Node *m_currentNode = nullptr; Node *m_currentNode = nullptr;
Project *m_currentProject = nullptr; Project *m_currentProject = nullptr;
Internal::ProjectTreeWidget *m_focusForContextMenu = nullptr; Internal::ProjectTreeWidget *m_focusForContextMenu = nullptr;
int m_keepCurrentNodeRequests = 0;
Core::Context m_lastProjectContext; Core::Context m_lastProjectContext;
}; };