From e3a692a1a4f810ddd487b6773d04e05a8679048e Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 26 Sep 2017 17:19:00 +0200 Subject: [PATCH] File System view: Fix that projects could be duplicated It is not possible to use the display name as an ID, because that can change (and to propagate that change we use the ID). Remove the display name from the ID, use a separate sort property, and sort by this property + display name. Task-number: QTCREATORBUG-18972 Change-Id: I27017473842931defa3a123ce9f41cc8e8ba1a61 Reviewed-by: Tobias Hunger --- .../foldernavigationwidget.cpp | 40 ++++++++++++++----- .../projectexplorer/foldernavigationwidget.h | 1 + src/plugins/projectexplorer/session.cpp | 10 +++-- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp index 10ed90d4e0a..9d29ead1a11 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.cpp +++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp @@ -56,6 +56,7 @@ const int PATH_ROLE = Qt::UserRole; const int ID_ROLE = Qt::UserRole + 1; +const int SORT_ROLE = Qt::UserRole + 2; const char PROJECTSDIRECTORYROOT_ID[] = "A.Projects"; @@ -170,21 +171,38 @@ void FolderNavigationWidget::toggleAutoSynchronization() setAutoSynchronization(!m_autoSync); } +static bool itemLessThan(QComboBox *combo, + int index, + const FolderNavigationWidgetFactory::RootDirectory &directory) +{ + return combo->itemData(index, SORT_ROLE).toInt() < directory.sortValue + || (combo->itemData(index, SORT_ROLE).toInt() == directory.sortValue + && combo->itemData(index, Qt::DisplayRole).toString() < directory.displayName); +} + void FolderNavigationWidget::insertRootDirectory( const FolderNavigationWidgetFactory::RootDirectory &directory) { - // insert sorted + // Find existing. Do not remove yet, to not mess up the current selection. + int previousIndex = 0; + while (previousIndex < m_rootSelector->count() + && m_rootSelector->itemData(previousIndex, ID_ROLE).toString() != directory.id) + ++previousIndex; + // Insert sorted. int index = 0; - while (index < m_rootSelector->count() - && m_rootSelector->itemData(index, ID_ROLE).toString() < directory.id) + while (index < m_rootSelector->count() && itemLessThan(m_rootSelector, index, directory)) ++index; - if (m_rootSelector->itemData(index, ID_ROLE).toString() != directory.id) - m_rootSelector->insertItem(index, directory.displayName); + m_rootSelector->insertItem(index, directory.displayName); + if (index <= previousIndex) // item was inserted, update previousIndex + ++previousIndex; m_rootSelector->setItemData(index, qVariantFromValue(directory.path), PATH_ROLE); m_rootSelector->setItemData(index, directory.id, ID_ROLE); + m_rootSelector->setItemData(index, directory.sortValue, SORT_ROLE); m_rootSelector->setItemData(index, directory.path.toUserOutput(), Qt::ToolTipRole); - if (m_rootSelector->currentIndex() == index) - setRootDirectory(directory.path); + if (m_rootSelector->currentIndex() == previousIndex) + m_rootSelector->setCurrentIndex(index); + if (previousIndex < m_rootSelector->count()) + m_rootSelector->removeItem(previousIndex); if (m_autoSync) // we might find a better root for current selection now setCurrentEditor(Core::EditorManager::currentEditor()); } @@ -357,9 +375,12 @@ FolderNavigationWidgetFactory::FolderNavigationWidgetFactory() setPriority(400); setId("File System"); setActivationSequence(QKeySequence(Core::UseMacShortcuts ? tr("Meta+Y") : tr("Alt+Y"))); - insertRootDirectory( - {QLatin1String("A.Computer"), FolderNavigationWidget::tr("Computer"), Utils::FileName()}); + insertRootDirectory({QLatin1String("A.Computer"), + 0 /*sortValue*/, + FolderNavigationWidget::tr("Computer"), + Utils::FileName()}); insertRootDirectory({QLatin1String("A.Home"), + 10 /*sortValue*/, FolderNavigationWidget::tr("Home"), Utils::FileName::fromString(QDir::homePath())}); updateProjectsDirectoryRoot(); @@ -440,6 +461,7 @@ int FolderNavigationWidgetFactory::rootIndex(const QString &id) void FolderNavigationWidgetFactory::updateProjectsDirectoryRoot() { insertRootDirectory({QLatin1String(PROJECTSDIRECTORYROOT_ID), + 20 /*sortValue*/, FolderNavigationWidget::tr("Projects"), Core::DocumentManager::projectsDirectory()}); } diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h index 06c91c17185..11e2bbc9ec8 100644 --- a/src/plugins/projectexplorer/foldernavigationwidget.h +++ b/src/plugins/projectexplorer/foldernavigationwidget.h @@ -53,6 +53,7 @@ class FolderNavigationWidgetFactory : public Core::INavigationWidgetFactory public: struct RootDirectory { QString id; + int sortValue; QString displayName; Utils::FileName path; }; diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index cd66c88caea..6d7a4ef7641 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -120,9 +120,11 @@ static SessionManagerPrivate *d = nullptr; static QString projectFolderId(Project *pro) { - return "P." + pro->displayName() + "." + pro->projectFilePath().toString(); + return pro->projectFilePath().toString(); } +const int PROJECT_SORT_VALUE = 100; + SessionManager::SessionManager(QObject *parent) : QObject(parent) { m_instance = this; @@ -392,8 +394,10 @@ void SessionManager::addProject(Project *pro) emit m_instance->projectAdded(pro); const auto updateFolderNavigation = [pro] { - FolderNavigationWidgetFactory::insertRootDirectory( - {projectFolderId(pro), pro->displayName(), pro->projectFilePath().parentDir()}); + FolderNavigationWidgetFactory::insertRootDirectory({projectFolderId(pro), + PROJECT_SORT_VALUE, + pro->displayName(), + pro->projectFilePath().parentDir()}); }; updateFolderNavigation(); configureEditors(pro);