From d77a7167dbcde44ff719e6d7596d1a9bf3fd8df0 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 20 Oct 2022 17:53:09 +0200 Subject: [PATCH] ProjectExplorer: Use LRU for sorting sessions in menu Right now, upon start-up of Qt Creator, entries in the Sessions menu are sorted in reverse order of the time the corresponding files were last modified on disk, which often (but not always) corresponds to a "least recently used" order. This order is unchanged during the lifetime of the current instance of Qt Creator, and potentially changes again after the next start. As this can be confusing to users, we now ensure LRU sorting at all times. Task-number: QTCREATORBUG-28202 Change-Id: I758371ac1cb968dd3f2e4278fc5066d1e74397c6 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: Eike Ziller --- .../projectexplorer/projectexplorer.cpp | 7 +++++- src/plugins/projectexplorer/session.cpp | 22 +++++++++++++++++++ src/plugins/projectexplorer/session.h | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index c6ee39013b0..9efea4ebb0e 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -145,7 +145,9 @@ #include #include +#include #include +#include #include #include @@ -4174,7 +4176,10 @@ void ProjectExplorerPluginPrivate::updateSessionMenu() connect(ag, &QActionGroup::triggered, this, &ProjectExplorerPluginPrivate::setSession); const QString activeSession = SessionManager::activeSession(); - const QStringList sessions = SessionManager::sessions(); + QStringList sessions = SessionManager::sessions(); + std::sort(std::next(sessions.begin()), sessions.end(), [](const QString &s1, const QString &s2) { + return SessionManager::lastActiveTime(s1) > SessionManager::lastActiveTime(s2); + }); for (int i = 0; i < sessions.size(); ++i) { const QString &session = sessions[i]; diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index 2437b4389ee..07d7c73cda5 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -48,6 +48,7 @@ using namespace ProjectExplorer::Internal; namespace ProjectExplorer { const char DEFAULT_SESSION[] = "default"; +const char LAST_ACTIVE_TIMES_KEY[] = "LastActiveTimes"; /*! \class ProjectExplorer::SessionManager @@ -88,6 +89,7 @@ public: mutable QStringList m_sessions; mutable QHash m_sessionDateTimes; + QHash m_lastActiveTimes; Project *m_startupProject = nullptr; QList m_projects; @@ -119,6 +121,13 @@ SessionManager::SessionManager(QObject *parent) : QObject(parent) connect(ModeManager::instance(), &ModeManager::currentModeChanged, this, &SessionManager::saveActiveMode); + connect(ICore::instance(), &ICore::saveSettingsRequested, this, [] { + QVariantMap times; + for (auto it = d->m_lastActiveTimes.cbegin(); it != d->m_lastActiveTimes.cend(); ++it) + times.insert(it.key(), it.value()); + ICore::settings()->setValue(LAST_ACTIVE_TIMES_KEY, times); + }); + connect(EditorManager::instance(), &EditorManager::editorCreated, this, &SessionManager::configureEditor); connect(this, &SessionManager::projectAdded, @@ -776,9 +785,14 @@ QStringList SessionManager::sessions() // We are not initialized yet, so do that now const FilePaths sessionFiles = ICore::userResourcePath().dirEntries({{"*qws"}}, QDir::Time | QDir::Reversed); + const QVariantMap lastActiveTimes = ICore::settings()->value(LAST_ACTIVE_TIMES_KEY).toMap(); for (const FilePath &file : sessionFiles) { const QString &name = file.completeBaseName(); d->m_sessionDateTimes.insert(name, file.lastModified()); + const auto lastActiveTime = lastActiveTimes.find(name); + d->m_lastActiveTimes.insert(name, lastActiveTime != lastActiveTimes.end() + ? lastActiveTime->toDateTime() + : file.lastModified()); if (name != QLatin1String(DEFAULT_SESSION)) d->m_sessions << name; } @@ -792,6 +806,11 @@ QDateTime SessionManager::sessionDateTime(const QString &session) return d->m_sessionDateTimes.value(session); } +QDateTime SessionManager::lastActiveTime(const QString &session) +{ + return d->m_lastActiveTimes.value(session); +} + FilePath SessionManager::sessionNameToFileName(const QString &session) { return ICore::userResourcePath(session + ".qws"); @@ -807,6 +826,7 @@ bool SessionManager::createSession(const QString &session) return false; Q_ASSERT(d->m_sessions.size() > 0); d->m_sessions.insert(1, session); + d->m_lastActiveTimes.insert(session, QDateTime::currentDateTime()); return true; } @@ -844,6 +864,7 @@ bool SessionManager::deleteSession(const QString &session) if (!d->m_sessions.contains(session)) return false; d->m_sessions.removeOne(session); + d->m_lastActiveTimes.remove(session); emit instance()->sessionRemoved(session); QFile fi(sessionNameToFileName(session).toString()); if (fi.exists()) @@ -1115,6 +1136,7 @@ bool SessionManager::loadSession(const QString &session, bool initial) } d->m_casadeSetActive = reader.restoreValue(QLatin1String("CascadeSetActive"), false).toBool(); + d->m_lastActiveTimes.insert(session, QDateTime::currentDateTime()); emit m_instance->sessionLoaded(session); diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h index 0416274fb10..d0f7fd91d2b 100644 --- a/src/plugins/projectexplorer/session.h +++ b/src/plugins/projectexplorer/session.h @@ -41,6 +41,7 @@ public: static QString startupSession(); static QStringList sessions(); static QDateTime sessionDateTime(const QString &session); + static QDateTime lastActiveTime(const QString &session); static bool createSession(const QString &session);