forked from qt-creator/qt-creator
Welcome: Show open files in summary if there are no projects
In expanded items in the session list in Welcome mode. Adapt the project display too: We showed the base name of the project file as the project "title", which is "CMakeLists.txt" for all CMake projects, and also for other projects doesn't really add interesting information over the file name that we show. If there are projects in the session, show a title "Projects" and the list of open project paths. If there are no projects, but open files, show a title "Files" and the list of open file paths. Limit the list of paths to 5 in both cases (adding "..." if there are more). Fixes: QTCREATORBUG-7660 Change-Id: I2e250c54f88932aaa95b926f60e0005da9c7a89e Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -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<void(QMap<QString, QVariant>)> &editorStatesHandler,
|
||||
const std::function<void(FileStateEntry)> &fileHandler,
|
||||
const std::function<bool(FileStateEntry)> &fileHandler,
|
||||
const std::function<void(QByteArray)> &splitterStateHandler,
|
||||
const std::function<void(QVector<QVariantHash>)> &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
|
||||
*/
|
||||
|
@@ -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);
|
||||
|
@@ -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.
|
||||
*/
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
namespace Utils {
|
||||
class FilePath;
|
||||
using FilePaths = QList<FilePath>;
|
||||
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);
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/iwizardfactory.h>
|
||||
@@ -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)| | |
|
||||
// | | | <projectName> | | | |
|
||||
// | | +------------------------------+ | | |
|
||||
// | Per project in session --+ | (ExPaddingGapS) | |(sessionScrollBarGap)| |
|
||||
// | | +------------------------------+ | | |
|
||||
// | | | <projectPath> | | | |
|
||||
// | | +------------------------------+ | | +-- Expansion
|
||||
// | | (VPaddingXxs) | | | |
|
||||
// | +------------------------------+(HPaddingXs)| | |
|
||||
// | | <Projects | Files> | | | |
|
||||
// | +------------------------------+ | | |
|
||||
// | | (ExPaddingGapS) | |(sessionScrollBarGap)| |
|
||||
// | +-- +------------------------------+ | | |
|
||||
// | | | <path> | | | |
|
||||
// | Per open project or file --+ +------------------------------+ | | +-- Expansion
|
||||
// | +-- | (VPaddingXxs) | | | |
|
||||
// +----------------------------------------------------+------------------------------+------------+ | |
|
||||
// | (VPaddingXs) | | |
|
||||
// | (VGapXs) | | |
|
||||
// +---------------------------------------+--------------+-----------------------------------------+ | |
|
||||
// +-- | <cloneButton>|<renameButton>|<deleteButton> | | |
|
||||
// | +---------------------------------------+--------------+-----------------------------------------+ | |
|
||||
@@ -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());
|
||||
}
|
||||
|
Reference in New Issue
Block a user