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;
|
bool pinned = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calls the "handler"s with the extracted data.
|
||||||
|
If the fileHandler returns false, the parsing is aborted.
|
||||||
|
*/
|
||||||
static void restore(
|
static void restore(
|
||||||
const QByteArray &state,
|
const QByteArray &state,
|
||||||
const std::function<void(QMap<QString, QVariant>)> &editorStatesHandler,
|
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(QByteArray)> &splitterStateHandler,
|
||||||
const std::function<void(QVector<QVariantHash>)> &windowStateHandler)
|
const std::function<void(QVector<QVariantHash>)> &windowStateHandler)
|
||||||
{
|
{
|
||||||
@@ -3668,8 +3672,8 @@ static void restore(
|
|||||||
if (isVersion5)
|
if (isVersion5)
|
||||||
stream >> file.pinned;
|
stream >> file.pinned;
|
||||||
|
|
||||||
if (fileHandler)
|
if (fileHandler && !fileHandler(file))
|
||||||
fileHandler(file);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray splitterstates;
|
QByteArray splitterstates;
|
||||||
@@ -3711,7 +3715,7 @@ void EditorManager::restoreState(const QByteArray &state)
|
|||||||
if (!file.filePath.isEmpty() && !file.displayName.isEmpty()) {
|
if (!file.filePath.isEmpty() && !file.displayName.isEmpty()) {
|
||||||
const FilePath filePath = FilePath::fromUserInput(file.filePath);
|
const FilePath filePath = FilePath::fromUserInput(file.filePath);
|
||||||
if (!filePath.exists())
|
if (!filePath.exists())
|
||||||
return;
|
return true;
|
||||||
const FilePath rfp = autoSaveName(filePath);
|
const FilePath rfp = autoSaveName(filePath);
|
||||||
if (rfp.exists() && filePath.lastModified() < rfp.lastModified()) {
|
if (rfp.exists() && filePath.lastModified() < rfp.lastModified()) {
|
||||||
if (IEditor *editor = openEditor(filePath, file.id, DoNotMakeVisible))
|
if (IEditor *editor = openEditor(filePath, file.id, DoNotMakeVisible))
|
||||||
@@ -3723,6 +3727,7 @@ void EditorManager::restoreState(const QByteArray &state)
|
|||||||
DocumentModelPrivate::setPinned(entry, file.pinned);
|
DocumentModelPrivate::setPinned(entry, file.pinned);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
const auto restoreSplitterState = [](const QByteArray &state) {
|
const auto restoreSplitterState = [](const QByteArray &state) {
|
||||||
d->m_editorAreas.first()->restoreState(state);
|
d->m_editorAreas.first()->restoreState(state);
|
||||||
@@ -3749,6 +3754,21 @@ void EditorManager::restoreState(const QByteArray &state)
|
|||||||
QApplication::restoreOverrideCursor();
|
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
|
\internal
|
||||||
*/
|
*/
|
||||||
|
@@ -99,6 +99,7 @@ public:
|
|||||||
static Qt::CaseSensitivity readFileSystemSensitivity(Utils::QtcSettings *settings);
|
static Qt::CaseSensitivity readFileSystemSensitivity(Utils::QtcSettings *settings);
|
||||||
static void writeFileSystemSensitivity(Utils::QtcSettings *settings,
|
static void writeFileSystemSensitivity(Utils::QtcSettings *settings,
|
||||||
Qt::CaseSensitivity sensitivity);
|
Qt::CaseSensitivity sensitivity);
|
||||||
|
static Utils::FilePaths openFilesForState(const QByteArray &state, int max);
|
||||||
|
|
||||||
static EditorWindow *createEditorWindow();
|
static EditorWindow *createEditorWindow();
|
||||||
static void addEditorArea(EditorArea *area);
|
static void addEditorArea(EditorArea *area);
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include "coreconstants.h"
|
#include "coreconstants.h"
|
||||||
#include "coreplugin.h"
|
#include "coreplugin.h"
|
||||||
#include "editormanager/editormanager.h"
|
#include "editormanager/editormanager.h"
|
||||||
|
#include "editormanager/editormanager_p.h"
|
||||||
#include "icore.h"
|
#include "icore.h"
|
||||||
#include "modemanager.h"
|
#include "modemanager.h"
|
||||||
#include "progressmanager/progressmanager.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.
|
Returns the last session that was opened by the user.
|
||||||
*/
|
*/
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
class FilePath;
|
class FilePath;
|
||||||
|
using FilePaths = QList<FilePath>;
|
||||||
class Key;
|
class Key;
|
||||||
} // Utils
|
} // Utils
|
||||||
|
|
||||||
@@ -71,6 +72,8 @@ public:
|
|||||||
static bool loadSession(const QString &session, bool initial = false);
|
static bool loadSession(const QString &session, bool initial = false);
|
||||||
static bool saveSession();
|
static bool saveSession();
|
||||||
|
|
||||||
|
static Utils::FilePaths openFilesForSessionName(const QString &session, int max = -1);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void startupSessionRestored();
|
void startupSessionRestored();
|
||||||
void aboutToUnloadSession(QString sessionName);
|
void aboutToUnloadSession(QString sessionName);
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
#include <coreplugin/documentmanager.h>
|
#include <coreplugin/documentmanager.h>
|
||||||
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/iwizardfactory.h>
|
#include <coreplugin/iwizardfactory.h>
|
||||||
@@ -44,6 +45,7 @@ using namespace Utils;
|
|||||||
using namespace Utils::StyleHelper::SpacingTokens;
|
using namespace Utils::StyleHelper::SpacingTokens;
|
||||||
|
|
||||||
const char PROJECT_BASE_ID[] = "Welcome.OpenRecentProject";
|
const char PROJECT_BASE_ID[] = "Welcome.OpenRecentProject";
|
||||||
|
static const qsizetype kMaxPathsDisplay = 5;
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -87,6 +89,25 @@ static bool withIcon()
|
|||||||
return s(100) > 60; // Hide icons if spacings are scaled to below 60%
|
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)
|
ProjectModel::ProjectModel(QObject *parent)
|
||||||
: QAbstractListModel(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
|
class SessionDelegate : public BaseDelegate
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@@ -335,17 +344,17 @@ public:
|
|||||||
// | |(w:6) | +------------+ +-------------+ | | | | |
|
// | |(w:6) | +------------+ +-------------+ | | | | |
|
||||||
// | | | |(VPaddingXs)| |(VPaddingXs) | | | | | |
|
// | | | |(VPaddingXs)| |(VPaddingXs) | | | | | |
|
||||||
// |------------+--------+--------+------------+--------+-------------+--------+-------+ | | --+
|
// |------------+--------+--------+------------+--------+-------------+--------+-------+ | | --+
|
||||||
// | +-- | (VPaddingXxs) | | | |
|
// | | (VPaddingXxs) | | | |
|
||||||
// | | +------------------------------+(HPaddingXs)| | |
|
// | +------------------------------+(HPaddingXs)| | |
|
||||||
// | | | <projectName> | | | |
|
// | | <Projects | Files> | | | |
|
||||||
// | | +------------------------------+ | | |
|
// | +------------------------------+ | | |
|
||||||
// | Per project in session --+ | (ExPaddingGapS) | |(sessionScrollBarGap)| |
|
// | | (ExPaddingGapS) | |(sessionScrollBarGap)| |
|
||||||
// | | +------------------------------+ | | |
|
// | +-- +------------------------------+ | | |
|
||||||
// | | | <projectPath> | | | |
|
// | | | <path> | | | |
|
||||||
// | | +------------------------------+ | | +-- Expansion
|
// | Per open project or file --+ +------------------------------+ | | +-- Expansion
|
||||||
// | +-- | (VPaddingXxs) | | | |
|
// | +-- | (VPaddingXxs) | | | |
|
||||||
// +----------------------------------------------------+------------------------------+------------+ | |
|
// +----------------------------------------------------+------------------------------+------------+ | |
|
||||||
// | (VPaddingXs) | | |
|
// | (VGapXs) | | |
|
||||||
// +---------------------------------------+--------------+-----------------------------------------+ | |
|
// +---------------------------------------+--------------+-----------------------------------------+ | |
|
||||||
// +-- | <cloneButton>|<renameButton>|<deleteButton> | | |
|
// +-- | <cloneButton>|<renameButton>|<deleteButton> | | |
|
||||||
// | +---------------------------------------+--------------+-----------------------------------------+ | |
|
// | +---------------------------------------+--------------+-----------------------------------------+ | |
|
||||||
@@ -454,47 +463,49 @@ public:
|
|||||||
|
|
||||||
int yy = hdR.bottom();
|
int yy = hdR.bottom();
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
const QFont projectNameFont = sessionProjectNameTF.font();
|
const QFont titleFont = sessionProjectNameTF.font();
|
||||||
const QFontMetrics projectNameFm(projectNameFont);
|
const QFontMetrics titleNameFm(titleFont);
|
||||||
const int projectNameLineHeight = sessionProjectNameTF.lineHeight();
|
const int titleLineHeight = sessionProjectNameTF.lineHeight();
|
||||||
const QFont projectPathFont = projectPathTF.font();
|
const QFont pathFont = projectPathTF.font();
|
||||||
const QFontMetrics projectPathFm(projectPathFont);
|
const QFontMetrics pathFm(pathFont);
|
||||||
const int projectPathLineHeight = projectPathTF.lineHeight();
|
const int pathLineHeight = projectPathTF.lineHeight();
|
||||||
const int textWidth = bgR.right() - s(HPaddingXs) - textX;
|
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);
|
QString title;
|
||||||
for (const FilePath &projectPath : projects) {
|
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);
|
yy += s(VPaddingXxs);
|
||||||
|
// title
|
||||||
{
|
{
|
||||||
painter->setFont(projectNameFont);
|
painter->setFont(titleFont);
|
||||||
painter->setPen(sessionProjectNameTF.color());
|
painter->setPen(sessionProjectNameTF.color());
|
||||||
const QRect projectNameR(textX, yy, textWidth, projectNameLineHeight);
|
const QRect titleR(textX, yy, textWidth, titleLineHeight);
|
||||||
const QString projectNameElided =
|
const QString titleElided
|
||||||
projectNameFm.elidedText(projectPath.completeBaseName(), Qt::ElideMiddle,
|
= titleNameFm.elidedText(title, Qt::ElideMiddle, textWidth);
|
||||||
textWidth);
|
painter->drawText(titleR, sessionProjectNameTF.drawTextFlags, titleElided);
|
||||||
painter->drawText(projectNameR, sessionProjectNameTF.drawTextFlags,
|
yy += titleLineHeight;
|
||||||
projectNameElided);
|
|
||||||
yy += projectNameLineHeight;
|
|
||||||
yy += s(ExPaddingGapS);
|
yy += s(ExPaddingGapS);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const QString displayPath =
|
painter->setFont(pathFont);
|
||||||
projectPath.osType() == OsTypeWindows ? projectPath.displayName()
|
|
||||||
: projectPath.withTildeHomePath();
|
|
||||||
painter->setFont(projectPathFont);
|
|
||||||
painter->setPen(projectPathTF.color());
|
painter->setPen(projectPathTF.color());
|
||||||
const QRect projectPathR(textX, yy, textWidth, projectPathLineHeight);
|
for (const QString &displayPath : pathDisplay) {
|
||||||
const QString projectPathElided =
|
const QRect pathR(textX, yy, textWidth, pathLineHeight);
|
||||||
projectPathFm.elidedText(displayPath, Qt::ElideMiddle, textWidth);
|
const QString pathElided
|
||||||
painter->drawText(projectPathR, projectPathTF.drawTextFlags,
|
= pathFm.elidedText(displayPath, Qt::ElideMiddle, textWidth);
|
||||||
projectPathElided);
|
painter->drawText(pathR, projectPathTF.drawTextFlags, pathElided);
|
||||||
yy += projectPathLineHeight;
|
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);
|
yy += s(VGapXs);
|
||||||
|
|
||||||
@@ -560,17 +571,14 @@ public:
|
|||||||
int h = headerHeight();
|
int h = headerHeight();
|
||||||
if (expanded(idx)) {
|
if (expanded(idx)) {
|
||||||
const QString sessionName = idx.data(Qt::DisplayRole).toString();
|
const QString sessionName = idx.data(Qt::DisplayRole).toString();
|
||||||
const FilePaths projects = ProjectManager::projectsForSessionName(sessionName);
|
const FilePaths paths = pathsForSession(sessionName);
|
||||||
const int projectEntryHeight =
|
const int displayPathCount = std::min(kMaxPathsDisplay + 1, paths.size());
|
||||||
s(VPaddingXxs)
|
const int contentHeight
|
||||||
+ projectNameTF.lineHeight()
|
= displayPathCount == 0
|
||||||
+ s(ExPaddingGapS)
|
? 0
|
||||||
+ projectPathTF.lineHeight()
|
: s(VPaddingXxs) + sessionProjectNameTF.lineHeight() + s(ExPaddingGapS)
|
||||||
+ s(VPaddingXxs);
|
+ displayPathCount * (projectPathTF.lineHeight() + s(VPaddingXxs));
|
||||||
h += projects.size() * projectEntryHeight
|
h += contentHeight + s(VGapXs) + actionButtonHeight() + s(VGapXs);
|
||||||
+ s(VGapXs)
|
|
||||||
+ actionButtonHeight()
|
|
||||||
+ s(VGapXs);
|
|
||||||
}
|
}
|
||||||
return QSize(-1, h + itemSpacing());
|
return QSize(-1, h + itemSpacing());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user