diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 08c559105b2..5de0bcec80b 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -3639,10 +3639,14 @@ public: bool pinned = false; }; +/* + Calls the "handler"s with the extracted data. + If the fileHandler returns false, the parsing is aborted. +*/ static void restore( const QByteArray &state, const std::function)> &editorStatesHandler, - const std::function &fileHandler, + const std::function &fileHandler, const std::function &splitterStateHandler, const std::function)> &windowStateHandler) { @@ -3668,8 +3672,8 @@ static void restore( if (isVersion5) stream >> file.pinned; - if (fileHandler) - fileHandler(file); + if (fileHandler && !fileHandler(file)) + return; } QByteArray splitterstates; @@ -3711,7 +3715,7 @@ void EditorManager::restoreState(const QByteArray &state) if (!file.filePath.isEmpty() && !file.displayName.isEmpty()) { const FilePath filePath = FilePath::fromUserInput(file.filePath); if (!filePath.exists()) - return; + return true; const FilePath rfp = autoSaveName(filePath); if (rfp.exists() && filePath.lastModified() < rfp.lastModified()) { if (IEditor *editor = openEditor(filePath, file.id, DoNotMakeVisible)) @@ -3723,6 +3727,7 @@ void EditorManager::restoreState(const QByteArray &state) DocumentModelPrivate::setPinned(entry, file.pinned); } } + return true; }; const auto restoreSplitterState = [](const QByteArray &state) { d->m_editorAreas.first()->restoreState(state); @@ -3749,6 +3754,21 @@ void EditorManager::restoreState(const QByteArray &state) QApplication::restoreOverrideCursor(); } +FilePaths EditorManagerPrivate::openFilesForState(const QByteArray &state, int max) +{ + FilePaths result; + restore( + state, + {}, + [&result, max](const FileStateEntry &entry) { + result << FilePath::fromUserInput(entry.filePath); + return max < 0 || result.size() <= max; + }, + {}, + {}); + return result; +} + /*! \internal */ diff --git a/src/plugins/coreplugin/editormanager/editormanager_p.h b/src/plugins/coreplugin/editormanager/editormanager_p.h index 1eb7d248916..3d95b22df03 100644 --- a/src/plugins/coreplugin/editormanager/editormanager_p.h +++ b/src/plugins/coreplugin/editormanager/editormanager_p.h @@ -99,6 +99,7 @@ public: static Qt::CaseSensitivity readFileSystemSensitivity(Utils::QtcSettings *settings); static void writeFileSystemSensitivity(Utils::QtcSettings *settings, Qt::CaseSensitivity sensitivity); + static Utils::FilePaths openFilesForState(const QByteArray &state, int max); static EditorWindow *createEditorWindow(); static void addEditorArea(EditorArea *area); diff --git a/src/plugins/coreplugin/session.cpp b/src/plugins/coreplugin/session.cpp index 4cb088b3ff7..f3b8c5813a9 100644 --- a/src/plugins/coreplugin/session.cpp +++ b/src/plugins/coreplugin/session.cpp @@ -10,6 +10,7 @@ #include "coreconstants.h" #include "coreplugin.h" #include "editormanager/editormanager.h" +#include "editormanager/editormanager_p.h" #include "icore.h" #include "modemanager.h" #include "progressmanager/progressmanager.h" @@ -556,6 +557,18 @@ void SessionManagerPrivate::restoreEditors() } } +FilePaths SessionManager::openFilesForSessionName(const QString &session, int max) +{ + const FilePath fileName = sessionNameToFileName(session); + PersistentSettingsReader reader; + if (fileName.exists()) { + if (!reader.load(fileName)) + return {}; + } + return Internal::EditorManagerPrivate::openFilesForState( + QByteArray::fromBase64(reader.restoreValue("EditorSettings").toByteArray()), max); +} + /*! Returns the last session that was opened by the user. */ diff --git a/src/plugins/coreplugin/session.h b/src/plugins/coreplugin/session.h index ef51228b018..6c0bef6d954 100644 --- a/src/plugins/coreplugin/session.h +++ b/src/plugins/coreplugin/session.h @@ -12,6 +12,7 @@ namespace Utils { class FilePath; +using FilePaths = QList; class Key; } // Utils @@ -71,6 +72,8 @@ public: static bool loadSession(const QString &session, bool initial = false); static bool saveSession(); + static Utils::FilePaths openFilesForSessionName(const QString &session, int max = -1); + signals: void startupSessionRestored(); void aboutToUnloadSession(QString sessionName); diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index c007372cf4a..d5871d1a135 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ using namespace Utils; using namespace Utils::StyleHelper::SpacingTokens; const char PROJECT_BASE_ID[] = "Welcome.OpenRecentProject"; +static const qsizetype kMaxPathsDisplay = 5; namespace ProjectExplorer { namespace Internal { @@ -87,6 +89,25 @@ static bool withIcon() return s(100) > 60; // Hide icons if spacings are scaled to below 60% } +static FilePaths pathsForSession(const QString &session, QString *title = nullptr) +{ + const FilePaths projects = ProjectManager::projectsForSessionName(session); + if (projects.size()) { + if (title) { + //: title in expanded session items in welcome mode + *title = Tr::tr("Projects"); + } + return projects; + } + const FilePaths allPaths = SessionManager::openFilesForSessionName( + session, kMaxPathsDisplay + 1 /* +1 so we know if there are more */); + if (title) { + //: title in expanded session items in welcome mode + *title = Tr::tr("Files"); + } + return allPaths; +} + ProjectModel::ProjectModel(QObject *parent) : QAbstractListModel(parent) { @@ -272,18 +293,6 @@ protected: } }; -static FilePaths pathsForSessionName(const QString &session) -{ - const FilePath fileName = SessionManager::sessionNameToFileName(session); - PersistentSettingsReader reader; - if (fileName.exists()) { - if (!reader.load(fileName)) - return {}; - } - // qDebug() << reader.restoreValue("EditorSettings").toByteArray(); - return {}; -} - class SessionDelegate : public BaseDelegate { protected: @@ -335,17 +344,17 @@ public: // | |(w:6) | +------------+ +-------------+ | | | | | // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | // |------------+--------+--------+------------+--------+-------------+--------+-------+ | | --+ - // | +-- | (VPaddingXxs) | | | | - // | | +------------------------------+(HPaddingXs)| | | - // | | | | | | | - // | | +------------------------------+ | | | - // | Per project in session --+ | (ExPaddingGapS) | |(sessionScrollBarGap)| | - // | | +------------------------------+ | | | - // | | | | | | | - // | | +------------------------------+ | | +-- Expansion + // | | (VPaddingXxs) | | | | + // | +------------------------------+(HPaddingXs)| | | + // | | | | | | + // | +------------------------------+ | | | + // | | (ExPaddingGapS) | |(sessionScrollBarGap)| | + // | +-- +------------------------------+ | | | + // | | | | | | | + // | Per open project or file --+ +------------------------------+ | | +-- Expansion // | +-- | (VPaddingXxs) | | | | // +----------------------------------------------------+------------------------------+------------+ | | - // | (VPaddingXs) | | | + // | (VGapXs) | | | // +---------------------------------------+--------------+-----------------------------------------+ | | // +-- | || | | | // | +---------------------------------------+--------------+-----------------------------------------+ | | @@ -454,47 +463,49 @@ public: int yy = hdR.bottom(); if (expanded) { - const QFont projectNameFont = sessionProjectNameTF.font(); - const QFontMetrics projectNameFm(projectNameFont); - const int projectNameLineHeight = sessionProjectNameTF.lineHeight(); - const QFont projectPathFont = projectPathTF.font(); - const QFontMetrics projectPathFm(projectPathFont); - const int projectPathLineHeight = projectPathTF.lineHeight(); + const QFont titleFont = sessionProjectNameTF.font(); + const QFontMetrics titleNameFm(titleFont); + const int titleLineHeight = sessionProjectNameTF.lineHeight(); + const QFont pathFont = projectPathTF.font(); + const QFontMetrics pathFm(pathFont); + const int pathLineHeight = projectPathTF.lineHeight(); const int textWidth = bgR.right() - s(HPaddingXs) - textX; + const auto getDisplayPath = [](const FilePath &p) { + return p.osType() == OsTypeWindows ? p.displayName() : p.withTildeHomePath(); + }; - const FilePaths projects = ProjectManager::projectsForSessionName(sessionName); - for (const FilePath &projectPath : projects) { + QString title; + const FilePaths allPaths = pathsForSession(sessionName, &title); + const qsizetype count = allPaths.size(); + const FilePaths paths = allPaths.first(std::min(kMaxPathsDisplay, count)); + const QStringList pathDisplay = Utils::transform(paths, getDisplayPath) + + (count > kMaxPathsDisplay ? QStringList("...") + : QStringList()); + if (pathDisplay.size()) { yy += s(VPaddingXxs); + // title { - painter->setFont(projectNameFont); + painter->setFont(titleFont); painter->setPen(sessionProjectNameTF.color()); - const QRect projectNameR(textX, yy, textWidth, projectNameLineHeight); - const QString projectNameElided = - projectNameFm.elidedText(projectPath.completeBaseName(), Qt::ElideMiddle, - textWidth); - painter->drawText(projectNameR, sessionProjectNameTF.drawTextFlags, - projectNameElided); - yy += projectNameLineHeight; + const QRect titleR(textX, yy, textWidth, titleLineHeight); + const QString titleElided + = titleNameFm.elidedText(title, Qt::ElideMiddle, textWidth); + painter->drawText(titleR, sessionProjectNameTF.drawTextFlags, titleElided); + yy += titleLineHeight; yy += s(ExPaddingGapS); } { - const QString displayPath = - projectPath.osType() == OsTypeWindows ? projectPath.displayName() - : projectPath.withTildeHomePath(); - painter->setFont(projectPathFont); + painter->setFont(pathFont); painter->setPen(projectPathTF.color()); - const QRect projectPathR(textX, yy, textWidth, projectPathLineHeight); - const QString projectPathElided = - projectPathFm.elidedText(displayPath, Qt::ElideMiddle, textWidth); - painter->drawText(projectPathR, projectPathTF.drawTextFlags, - projectPathElided); - yy += projectPathLineHeight; + for (const QString &displayPath : pathDisplay) { + const QRect pathR(textX, yy, textWidth, pathLineHeight); + const QString pathElided + = pathFm.elidedText(displayPath, Qt::ElideMiddle, textWidth); + painter->drawText(pathR, projectPathTF.drawTextFlags, pathElided); + yy += pathLineHeight; + yy += s(VPaddingXxs); + } } - yy += s(VPaddingXxs); - } - if (projects.isEmpty()) { - // check if there are files to show instead - const FilePaths paths = pathsForSessionName(sessionName); } yy += s(VGapXs); @@ -560,17 +571,14 @@ public: int h = headerHeight(); if (expanded(idx)) { const QString sessionName = idx.data(Qt::DisplayRole).toString(); - const FilePaths projects = ProjectManager::projectsForSessionName(sessionName); - const int projectEntryHeight = - s(VPaddingXxs) - + projectNameTF.lineHeight() - + s(ExPaddingGapS) - + projectPathTF.lineHeight() - + s(VPaddingXxs); - h += projects.size() * projectEntryHeight - + s(VGapXs) - + actionButtonHeight() - + s(VGapXs); + const FilePaths paths = pathsForSession(sessionName); + const int displayPathCount = std::min(kMaxPathsDisplay + 1, paths.size()); + const int contentHeight + = displayPathCount == 0 + ? 0 + : s(VPaddingXxs) + sessionProjectNameTF.lineHeight() + s(ExPaddingGapS) + + displayPathCount * (projectPathTF.lineHeight() + s(VPaddingXxs)); + h += contentHeight + s(VGapXs) + actionButtonHeight() + s(VGapXs); } return QSize(-1, h + itemSpacing()); }