Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [session] add session manager to save/restore workspace state #1003

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/common/settings/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ bool Settings::contains(const QString &group, const QString &key) const
return d->defaultData.values.value(group).contains(key);
}

QVariant Settings::value(const QString &group, const QString &key, const QVariant &defaultValue)
QVariant Settings::value(const QString &group, const QString &key, const QVariant &defaultValue) const
{
auto value = d->settingData.value(group, key, QVariant::Invalid);
if (value.isValid())
Expand All @@ -199,7 +199,7 @@ QVariant Settings::value(const QString &group, const QString &key, const QVarian
return d->defaultData.value(group, key, defaultValue);
}

QVariant Settings::defaultValue(const QString &group, const QString &key, const QVariant &defaultValue)
QVariant Settings::defaultValue(const QString &group, const QString &key, const QVariant &defaultValue) const
{
return d->defaultData.value(group, key, defaultValue);
}
Expand Down
4 changes: 2 additions & 2 deletions src/common/settings/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class Settings : public QObject
QStringList groupList() const;
QStringList keyList(const QString &group) const;
bool contains(const QString &group, const QString &key) const;
QVariant value(const QString &group, const QString &key, const QVariant &defaultValue = QVariant());
QVariant defaultValue(const QString &group, const QString &key, const QVariant &defaultValue = QVariant());
QVariant value(const QString &group, const QString &key, const QVariant &defaultValue = QVariant()) const;
QVariant defaultValue(const QString &group, const QString &key, const QVariant &defaultValue = QVariant()) const;
void setValue(const QString &group, const QString &key, const QVariant &value, bool notify = false);
void removeGroup(const QString &group);
void remove(const QString &group, const QString &key);
Expand Down
7 changes: 7 additions & 0 deletions src/common/util/eventdefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ OPI_OBJECT(workspace,
OPI_INTERFACE(expandAll)
OPI_INTERFACE(foldAll)
)
OPI_OBJECT(session,
OPI_INTERFACE(readyToSaveSession)
OPI_INTERFACE(sessionLoaded, "session")
OPI_INTERFACE(sessionCreated, "session")
OPI_INTERFACE(sessionRenamed, "oldName", "newName")
OPI_INTERFACE(sessionRemoved, "session")
)

struct AnalysedData
{
Expand Down
1 change: 0 additions & 1 deletion src/plugins/codeeditor/gui/private/tabbar_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class TabBarPrivate : public QObject
void updateBackgroundColor();
bool isModified(int index) const;
int showConfirmDialog(const QString &filePath);
void closeAllTab(const QStringList &exceptList);

public slots:
void onCurrentTabChanged(int index);
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/codeeditor/gui/private/workspacewidget_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "base/abstracteditwidget.h"
#include "common/util/eventdefinitions.h"
#include "services/window/windowservice.h"
#include "services/session/sessionservice.h"
#include "Qsci/qscicommand.h"

#include <QStackedWidget>
Expand Down Expand Up @@ -64,6 +65,8 @@ public slots:
void handleSetModifiedAutoReload(const QString &fileName, bool flag);
void handleSetComment();
void handleShowOpenedFiles();
void handleSaveSession();
void handleSessionLoaded();

public:
WorkspaceWidget *q;
Expand All @@ -78,6 +81,8 @@ public slots:
QStringList modifiedFileList;
QStringList removedFileList;
QTimer fileCheckTimer;

dpfservice::SessionService *sessionSrv { nullptr };
};

#endif // WORKSPACEWIDGET_P_H
45 changes: 18 additions & 27 deletions src/plugins/codeeditor/gui/tabbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,29 +81,6 @@ int TabBarPrivate::showConfirmDialog(const QString &filePath)
return dialog.exec();
}

void TabBarPrivate::closeAllTab(const QStringList &exceptList)
{
QStringList tabList;
for (int i = 0; i < tabBar->count(); ++i) {
auto file = tabBar->tabToolTip(i);
if (exceptList.contains(file))
continue;

if (isModified(i)) {
int ret = showConfirmDialog(file);
if (ret == 0) // save
emit q->saveFileRequested(file);
else if (ret == 2 || ret == -1) // cancel or close
return;
}

tabList << file;
}

for (const auto &tab : tabList)
q->removeTab(tab, true);
}

void TabBarPrivate::initConnection()
{
connect(tabBar, &DTabBar::currentChanged, this, &TabBarPrivate::onCurrentTabChanged);
Expand Down Expand Up @@ -149,12 +126,12 @@ void TabBarPrivate::showMenu(QPoint pos)
q->removeTab(file);
});
menu.addAction(tr("Close All Files"), [=]() {
closeAllTab({});
q->closeAllTab({});
});
menu.addAction(tr("Close All Files Except This"), [=]() {
auto curFile = tabBar->tabToolTip(curIndex);
QStringList exceptList { curFile };
closeAllTab(exceptList);
q->closeAllTab(exceptList);
});

menu.addSeparator();
Expand Down Expand Up @@ -248,8 +225,7 @@ void TabBar::removeTab(const QString &fileName, bool silent)
if (-1 == index)
return;

QFileInfo info(fileName);
if (!silent && info.exists() && d->isModified(index)) {
if (!silent && QFile::exists(fileName) && d->isModified(index)) {
int ret = d->showConfirmDialog(fileName);
if (ret == 0) // save
emit saveFileRequested(fileName);
Expand All @@ -263,6 +239,21 @@ void TabBar::removeTab(const QString &fileName, bool silent)
editor.switchedFile(this->currentFileName());
}

void TabBar::closeAllTab(const QStringList &exceptList, bool silent)
{
QStringList tabList;
for (int i = 0; i < d->tabBar->count(); ++i) {
auto file = d->tabBar->tabToolTip(i);
if (exceptList.contains(file))
continue;

tabList << file;
}

for (const auto &tab : tabList)
removeTab(tab, silent);
}

void TabBar::setCloseButtonVisible(bool visible)
{
d->closeBtn->setVisible(visible);
Expand Down
1 change: 1 addition & 0 deletions src/plugins/codeeditor/gui/tabbar.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class TabBar : public QWidget

void switchTab(const QString &fileName);
void removeTab(const QString &fileName, bool silent = false);
void closeAllTab(const QStringList &exceptList, bool silent = false);

void setCloseButtonVisible(bool visible);
void setSplitButtonVisible(bool visible);
Expand Down
5 changes: 5 additions & 0 deletions src/plugins/codeeditor/gui/tabwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,11 @@ void TabWidget::closeFileEditor()
closeFileEditor(editor->getFile());
}

void TabWidget::closeAllEditor()
{
d->tabBar->closeAllTab({}, true);
}

void TabWidget::switchHeaderSource()
{
auto editor = d->currentTextEditor();
Expand Down
1 change: 1 addition & 0 deletions src/plugins/codeeditor/gui/tabwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class TabWidget : public QWidget
void setFileModified(const QString &fileName, bool isModified);
void closeFileEditor(const QString &fileName);
void closeFileEditor();
void closeAllEditor();
void switchHeaderSource();
void followSymbolUnderCursor();
void findUsage();
Expand Down
45 changes: 38 additions & 7 deletions src/plugins/codeeditor/gui/workspacewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#include <QApplication>
#include <QFileDialog>

constexpr char TextEditorContext[] { "Text Editor" };
constexpr char kTextEditorContext[] { "Text Editor" };
constexpr char kOpenedFileList[] { "OpenFileList" };
constexpr char kCurrentFile[] { "CurrentFile" };

using namespace dpfservice;
DWIDGET_USE_NAMESPACE
Expand All @@ -27,6 +29,7 @@
: QObject(qq),
q(qq)
{
sessionSrv = dpfGetService(SessionService);
fileCheckTimer.setInterval(500);
fileCheckTimer.setSingleShot(true);
}
Expand Down Expand Up @@ -69,13 +72,13 @@

// add/del comment
QAction *commentAction = new QAction(tr("Add/Delete Comment"), q);
auto cmd = ActionManager::instance()->registerAction(commentAction, "TextEditor.AddAndRemoveComment", { TextEditorContext });
auto cmd = ActionManager::instance()->registerAction(commentAction, "TextEditor.AddAndRemoveComment", { kTextEditorContext });

Check warning on line 75 in src/plugins/codeeditor/gui/workspacewidget.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Local variable 'cmd' shadows outer variable

Check warning on line 75 in src/plugins/codeeditor/gui/workspacewidget.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Local variable 'cmd' shadows outer variable
cmd->setDefaultKeySequence(Qt::CTRL | Qt::Key_Slash);
connect(commentAction, &QAction::triggered, this, &WorkspaceWidgetPrivate::handleSetComment);

// show opened files
QAction *showOpenedAction = new QAction(tr("Show opened files"), q);
cmd = ActionManager::instance()->registerAction(showOpenedAction, "TextEditor.ShowOpenedFiles", { TextEditorContext });
cmd = ActionManager::instance()->registerAction(showOpenedAction, "TextEditor.ShowOpenedFiles", { kTextEditorContext });
cmd->setDefaultKeySequence(Qt::CTRL | Qt::Key_Tab);
connect(showOpenedAction, &QAction::triggered, this, &WorkspaceWidgetPrivate::handleShowOpenedFiles);

Expand Down Expand Up @@ -438,7 +441,7 @@
if (!actionText.isEmpty()) {
auto id = QString("TextEditor.%1").arg(me.valueToKey(val));
auto act = new QAction(actionText, q);
auto cmd = ActionManager::instance()->registerAction(act, id, { TextEditorContext });
auto cmd = ActionManager::instance()->registerAction(act, id, { kTextEditorContext });
if (!ksList.isEmpty())
cmd->setDefaultKeySequences(ksList);
connect(act, &QAction::triggered, this, [val, this] {
Expand Down Expand Up @@ -469,6 +472,32 @@
currentTabWidget()->handleShowOpenedFiles(q->pos().x() - q->mapFromGlobal(q->pos()).x(), q->pos().y() + q->mapToGlobal(q->pos()).y() - 100, q->size());
}

void WorkspaceWidgetPrivate::handleSaveSession()
{
sessionSrv->setValue(kOpenedFileList, q->openedFiles());
sessionSrv->setValue(kCurrentFile, q->currentFile());
}

void WorkspaceWidgetPrivate::handleSessionLoaded()
{
while (tabWidgetList.size() > 1) {
auto tabWidget = tabWidgetList.takeLast();
tabWidget->deleteLater();
}

tabWidgetList.first()->closeAllEditor();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tabWidgetList有可能为空吗

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不可能,构造的时候就会放一个进去

focusTabWidget = tabWidgetList.first();
auto symbolWidget = SymbolWidgetGenerator::instance()->symbolWidget();
symbolWidget->setEditor(nullptr);

const auto &openedFiles = sessionSrv->value(kOpenedFileList).toStringList();
const auto &currentFile = sessionSrv->value(kCurrentFile).toString();
for (const auto &file : openedFiles)
handleOpenFile("", file);
if (!currentFile.isEmpty())
handleOpenFile("", currentFile);
}

void WorkspaceWidgetPrivate::initConnection()
{
connect(&fileCheckTimer, &QTimer::timeout, this, &WorkspaceWidgetPrivate::checkFileState);
Expand All @@ -495,6 +524,8 @@
connect(EditorCallProxy::instance(), &EditorCallProxy::reqRenameSymbol, this, &WorkspaceWidgetPrivate::handleRenameSymbol);
connect(EditorCallProxy::instance(), &EditorCallProxy::reqToggleBreakpoint, this, &WorkspaceWidgetPrivate::handleToggleBreakpoint);
connect(EditorCallProxy::instance(), &EditorCallProxy::reqSetModifiedAutoReload, this, &WorkspaceWidgetPrivate::handleSetModifiedAutoReload);
connect(EditorCallProxy::instance(), &EditorCallProxy::reqSaveSession, this, &WorkspaceWidgetPrivate::handleSaveSession);
connect(EditorCallProxy::instance(), &EditorCallProxy::reqSessionLoaded, this, &WorkspaceWidgetPrivate::handleSessionLoaded);
}

void WorkspaceWidgetPrivate::connectTabWidgetSignals(TabWidget *tabWidget)
Expand Down Expand Up @@ -904,18 +935,18 @@
Q_UNUSED(old)

if (!now) {
ActionManager::instance()->removeContext({ TextEditorContext });
ActionManager::instance()->removeContext({ kTextEditorContext });
return;
}

// the `now` is TextEditor
auto tabWidget = qobject_cast<TabWidget *>(now->parentWidget());
if (!tabWidget) {
ActionManager::instance()->removeContext({ TextEditorContext });
ActionManager::instance()->removeContext({ kTextEditorContext });
return;
}

ActionManager::instance()->addContext({ TextEditorContext });
ActionManager::instance()->addContext({ kTextEditorContext });
focusTabWidget = tabWidget;
editor.switchedFile(focusTabWidget->currentFile());
auto symbolWidget = SymbolWidgetGenerator::instance()->symbolWidget();
Expand Down
Loading
Loading