From 164c00283e467702254cb104b76f967f6e3f46ae Mon Sep 17 00:00:00 2001 From: Sim Date: Sun, 5 May 2024 14:37:22 +0300 Subject: [PATCH 1/7] Implemented Save Session --- doc/TODO.md | 21 ++++ src/NotepadNext/NotepadNext.pro | 8 +- src/NotepadNext/NotepadNextApplication.cpp | 7 +- src/NotepadNext/NotepadNextApplication.h | 8 +- ...sListManager.cpp => RecentListManager.cpp} | 20 ++-- ...FilesListManager.h => RecentListManager.h} | 11 +- ...uBuilder.cpp => RecentListMenuBuilder.cpp} | 17 ++- ...tMenuBuilder.h => RecentListMenuBuilder.h} | 13 ++- src/NotepadNext/SessionManager.cpp | 104 +++++++++++++----- src/NotepadNext/SessionManager.h | 13 ++- src/NotepadNext/dialogs/MainWindow.cpp | 46 ++++++-- src/NotepadNext/dialogs/MainWindow.h | 2 + src/NotepadNext/dialogs/MainWindow.ui | 29 +++++ 13 files changed, 222 insertions(+), 77 deletions(-) create mode 100644 doc/TODO.md rename src/NotepadNext/{RecentFilesListManager.cpp => RecentListManager.cpp} (71%) rename src/NotepadNext/{RecentFilesListManager.h => RecentListManager.h} (84%) rename src/NotepadNext/{RecentFilesListMenuBuilder.cpp => RecentListMenuBuilder.cpp} (74%) rename src/NotepadNext/{RecentFilesListMenuBuilder.h => RecentListMenuBuilder.h} (78%) diff --git a/doc/TODO.md b/doc/TODO.md new file mode 100644 index 000000000..435677486 --- /dev/null +++ b/doc/TODO.md @@ -0,0 +1,21 @@ +## TODO + + - Sessions + - [ ] Save/Load sessions + - [ ] Store Bookmarks + - [ ] Store Tab settings + + - Editor + - [ ] Auto Tabs/Spaces + - [ ] Temp views from commands + - [ ] Log streams + - [ ] Support for Language Server Protocol + + - Workspace dock + - [ ] New File + - [ ] New Folder + - [ ] Locate current editor inside tree + + - Other + - [ ] On Save Hooks to Lua (linters etc) + - [ ] Run command diff --git a/src/NotepadNext/NotepadNext.pro b/src/NotepadNext/NotepadNext.pro index 717d52dd1..d514c175b 100644 --- a/src/NotepadNext/NotepadNext.pro +++ b/src/NotepadNext/NotepadNext.pro @@ -91,8 +91,8 @@ SOURCES += \ QRegexSearch.cpp \ QuickFindWidget.cpp \ RangeAllocator.cpp \ - RecentFilesListManager.cpp \ - RecentFilesListMenuBuilder.cpp \ + RecentListManager.cpp \ + RecentListMenuBuilder.cpp \ RtfConverter.cpp \ SciIFaceTable.cpp \ ScintillaCommenter.cpp \ @@ -169,8 +169,8 @@ HEADERS += \ QRegexSearch.h \ QuickFindWidget.h \ RangeAllocator.h \ - RecentFilesListManager.h \ - RecentFilesListMenuBuilder.h \ + RecentListManager.h \ + RecentListMenuBuilder.h \ RtfConverter.h \ SciIFaceTable.h \ ScintillaCommenter.h \ diff --git a/src/NotepadNext/NotepadNextApplication.cpp b/src/NotepadNext/NotepadNextApplication.cpp index 3e79b55df..f28f6952f 100644 --- a/src/NotepadNext/NotepadNextApplication.cpp +++ b/src/NotepadNext/NotepadNextApplication.cpp @@ -19,7 +19,7 @@ #include "MainWindow.h" #include "NotepadNextApplication.h" -#include "RecentFilesListManager.h" +#include "RecentListManager.h" #include "EditorManager.h" #include "LuaExtension.h" #include "DebugManager.h" @@ -125,7 +125,8 @@ bool NotepadNextApplication::init() luaState = new LuaState(); - recentFilesListManager = new RecentFilesListManager(this); + recentFilesListManager = new RecentListManager(this); + recentSessionsListManager = new RecentListManager(this); editorManager = new EditorManager(settings, this); sessionManager = new SessionManager(this); @@ -517,7 +518,7 @@ MainWindow *NotepadNextApplication::createNewWindow() } } - getSessionManager()->saveSession(window); + getSessionManager()->saveDefaultSession(window); }); return window; diff --git a/src/NotepadNext/NotepadNextApplication.h b/src/NotepadNext/NotepadNextApplication.h index b4b4aee54..a757d976a 100644 --- a/src/NotepadNext/NotepadNextApplication.h +++ b/src/NotepadNext/NotepadNextApplication.h @@ -31,7 +31,7 @@ class MainWindow; class LuaState; class EditorManager; -class RecentFilesListManager; +class RecentListManager; class ScintillaNext; class SessionManager; class TranslationManager; @@ -46,7 +46,8 @@ class NotepadNextApplication : public SingleApplication bool init(); - RecentFilesListManager *getRecentFilesListManager() const { return recentFilesListManager; } + RecentListManager *getRecentFilesListManager() const { return recentFilesListManager; } + RecentListManager *getRecentSessionsListManager() const { return recentSessionsListManager; } EditorManager *getEditorManager() const { return editorManager; } SessionManager *getSessionManager() const; TranslationManager *getTranslationManager() const { return translationManager; }; @@ -80,7 +81,8 @@ private slots: void loadSettings(); EditorManager *editorManager; - RecentFilesListManager *recentFilesListManager; + RecentListManager *recentFilesListManager; + RecentListManager *recentSessionsListManager; ApplicationSettings *settings; SessionManager *sessionManager; TranslationManager *translationManager; diff --git a/src/NotepadNext/RecentFilesListManager.cpp b/src/NotepadNext/RecentListManager.cpp similarity index 71% rename from src/NotepadNext/RecentFilesListManager.cpp rename to src/NotepadNext/RecentListManager.cpp index 29759224d..080481027 100644 --- a/src/NotepadNext/RecentFilesListManager.cpp +++ b/src/NotepadNext/RecentListManager.cpp @@ -17,14 +17,14 @@ */ -#include "RecentFilesListManager.h" +#include "RecentListManager.h" -RecentFilesListManager::RecentFilesListManager(QObject *parent) : - QObject(parent) +RecentListManager::RecentListManager(QObject *parent) : + QObject(parent), limit(10) { } -void RecentFilesListManager::addFile(const QString &filePath) +void RecentListManager::addFile(const QString &filePath) { qInfo(Q_FUNC_INFO); @@ -32,37 +32,37 @@ void RecentFilesListManager::addFile(const QString &filePath) removeFile(filePath); // Set a limit on how many can be in the list - if (recentFiles.size() >= 10) { + if (recentFiles.size() >= limit) { recentFiles.removeLast(); } recentFiles.prepend(filePath); } -void RecentFilesListManager::removeFile(const QString &filePath) +void RecentListManager::removeFile(const QString &filePath) { recentFiles.removeOne(filePath); } -void RecentFilesListManager::clear() +void RecentListManager::clear() { // Clear the file list recentFiles.clear(); } -QString RecentFilesListManager::mostRecentFile() const +QString RecentListManager::mostRecentFile() const { Q_ASSERT(!recentFiles.empty()); return recentFiles.first(); } -QStringList RecentFilesListManager::fileList() const +QStringList RecentListManager::fileList() const { return recentFiles; } -void RecentFilesListManager::setFileList(const QStringList &list) +void RecentListManager::setFileList(const QStringList &list) { clear(); recentFiles.append(list); diff --git a/src/NotepadNext/RecentFilesListManager.h b/src/NotepadNext/RecentListManager.h similarity index 84% rename from src/NotepadNext/RecentFilesListManager.h rename to src/NotepadNext/RecentListManager.h index 74a40a1d7..0579c093c 100644 --- a/src/NotepadNext/RecentFilesListManager.h +++ b/src/NotepadNext/RecentListManager.h @@ -17,18 +17,18 @@ */ -#ifndef RECENTFILESLISTMANAGER_H -#define RECENTFILESLISTMANAGER_H +#ifndef RECENTLISTMANAGER_H +#define RECENTLISTMANAGER_H #include #include -class RecentFilesListManager : public QObject +class RecentListManager : public QObject { Q_OBJECT public: - explicit RecentFilesListManager(QObject *parent = Q_NULLPTR); + explicit RecentListManager(QObject *parent = Q_NULLPTR); QString mostRecentFile() const; QStringList fileList() const; @@ -43,6 +43,7 @@ public slots: private: QStringList recentFiles; + int limit; }; -#endif // RECENTFILESLISTMANAGER_H +#endif // RECENTLISTMANAGER_H diff --git a/src/NotepadNext/RecentFilesListMenuBuilder.cpp b/src/NotepadNext/RecentListMenuBuilder.cpp similarity index 74% rename from src/NotepadNext/RecentFilesListMenuBuilder.cpp rename to src/NotepadNext/RecentListMenuBuilder.cpp index a5a2d97ab..3238c1077 100644 --- a/src/NotepadNext/RecentFilesListMenuBuilder.cpp +++ b/src/NotepadNext/RecentListMenuBuilder.cpp @@ -17,29 +17,34 @@ */ -#include "RecentFilesListMenuBuilder.h" +#include "RecentListMenuBuilder.h" #include #include #include -RecentFilesListMenuBuilder::RecentFilesListMenuBuilder(RecentFilesListManager *manager) : +RecentListMenuBuilder::RecentListMenuBuilder(RecentListManager *manager, int limit) : QObject(manager), - manager(manager) + manager(manager), + limit(limit) { } -void RecentFilesListMenuBuilder::populateMenu(QMenu *menu) +void RecentListMenuBuilder::populateMenu(QMenu *menu) { int i = 0; + while (menu->actions().size() > limit) { + delete menu->actions().takeLast(); + } + QList recentFileListActions; for (const QString &file : manager->fileList()) { ++i; QAction *action = new QAction(QString("%1%2: %3").arg(i < 10 ? "&" : "").arg(i).arg(QDir::toNativeSeparators(file)), menu); action->setData(file); - connect(action, &QAction::triggered, this, &RecentFilesListMenuBuilder::recentFileActionTriggered); + connect(action, &QAction::triggered, this, &RecentListMenuBuilder::recentFileActionTriggered); recentFileListActions.append(action); } @@ -47,7 +52,7 @@ void RecentFilesListMenuBuilder::populateMenu(QMenu *menu) menu->addActions(recentFileListActions); } -void RecentFilesListMenuBuilder::recentFileActionTriggered() +void RecentListMenuBuilder::recentFileActionTriggered() { qInfo(Q_FUNC_INFO); diff --git a/src/NotepadNext/RecentFilesListMenuBuilder.h b/src/NotepadNext/RecentListMenuBuilder.h similarity index 78% rename from src/NotepadNext/RecentFilesListMenuBuilder.h rename to src/NotepadNext/RecentListMenuBuilder.h index 7112ae415..a6d6cb48b 100644 --- a/src/NotepadNext/RecentFilesListMenuBuilder.h +++ b/src/NotepadNext/RecentListMenuBuilder.h @@ -17,20 +17,20 @@ */ -#ifndef RECENTFILESLISTMENUBUILDER_H -#define RECENTFILESLISTMENUBUILDER_H +#ifndef RECENTLISTMENUBUILDER_H +#define RECENTLISTMENUBUILDER_H -#include "RecentFilesListManager.h" +#include "RecentListManager.h" #include class QMenu; -class RecentFilesListMenuBuilder : public QObject +class RecentListMenuBuilder : public QObject { Q_OBJECT public: - explicit RecentFilesListMenuBuilder(RecentFilesListManager *manager); + explicit RecentListMenuBuilder(RecentListManager *manager, int limit); void populateMenu(QMenu *menu); signals: @@ -40,7 +40,8 @@ private slots: void recentFileActionTriggered(); private: - RecentFilesListManager *manager; + RecentListManager *manager; + int limit; }; #endif // RECENTFILESLISTMENUBUILDER_H diff --git a/src/NotepadNext/SessionManager.cpp b/src/NotepadNext/SessionManager.cpp index 9249fcb27..d74e55223 100644 --- a/src/NotepadNext/SessionManager.cpp +++ b/src/NotepadNext/SessionManager.cpp @@ -28,6 +28,8 @@ #include #include +#define SETTINGS_FILE "session.ini" +#define SETTINGS_DIR ".nnsession" static QString RandomSessionFileName() { @@ -54,7 +56,7 @@ static QList QVariantListToQList(const QVariantList &variantList) { } SessionManager::SessionManager(NotepadNextApplication *app, SessionFileTypes types) - : app(app) + : app(app), useCustomSessionFolder(false) { setSessionFileTypes(types); } @@ -66,12 +68,22 @@ void SessionManager::setSessionFileTypes(SessionFileTypes types) QDir SessionManager::sessionDirectory() const { - QDir d(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + if (useCustomSessionFolder) { + QDir d(customSessionPath); + if (!d.cd(SETTINGS_DIR)) + { + qCritical("Unable to open session dir %s", d.absolutePath().toUtf8().constData()); + } + return d; + } + else { + QDir d(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - d.mkpath("session"); - d.cd("session"); + d.mkpath("session"); + d.cd("session"); - return d; + return d; + } } void SessionManager::saveIntoSessionDirectory(ScintillaNext *editor, const QString &sessionFileName) const @@ -101,17 +113,25 @@ SessionManager::SessionFileType SessionManager::determineType(ScintillaNext *edi void SessionManager::clear() const { - clearSettings(); + qInfo(Q_FUNC_INFO); + if (useCustomSessionFolder) { + QSettings *settings = new QSettings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, + QSettings::IniFormat); + clearSettings(settings); + delete settings; + } + else { + ApplicationSettings appSettings; + clearSettings(&appSettings); + } clearDirectory(); } -void SessionManager::clearSettings() const +void SessionManager::clearSettings(QSettings *settings) const { - ApplicationSettings settings;; - // Clear everything out. There can be left over entries that are no longer needed - settings.beginGroup("CurrentSession"); - settings.remove(""); + settings->beginGroup("CurrentSession"); + settings->remove(""); } void SessionManager::clearDirectory() const @@ -119,11 +139,49 @@ void SessionManager::clearDirectory() const QDir d = sessionDirectory(); for (const QString &f : d.entryList()) { - d.remove(f); + if (f != SETTINGS_FILE) { + d.remove(f); + } } } -void SessionManager::saveSession(MainWindow *window) +bool SessionManager::saveSessionTo(MainWindow *window, QString &path) +{ + useCustomSessionFolder = true; + customSessionPath = path; + SessionFileTypes tmp = fileTypes; + QDir dir(path); + dir.mkdir(SETTINGS_DIR); + if (!dir.cd(SETTINGS_DIR)) + { + return false; + } + + QSettings *settings = new QSettings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); + + settings->beginGroup("Session"); + + setSessionFileTypes(tmp | SavedFile); + saveSession(window, settings); + setSessionFileTypes(tmp); + + settings->endGroup(); + settings->sync(); + + delete settings; + return true; +} + +void SessionManager::saveDefaultSession(MainWindow *window) +{ + useCustomSessionFolder = false; + ApplicationSettings appSettings; + appSettings.beginGroup("CurrentSession"); + saveSession(window, &appSettings); + appSettings.endGroup(); +} + +void SessionManager::saveSession(MainWindow *window, QSettings* settings) { qInfo(Q_FUNC_INFO); @@ -136,27 +194,25 @@ void SessionManager::saveSession(MainWindow *window) const ScintillaNext *currentEditor = window->currentEditor(); int currentEditorIndex = 0; - ApplicationSettings settings;; - - settings.beginGroup("CurrentSession"); + ApplicationSettings appSettings; - settings.beginWriteArray("OpenedFiles"); + settings->beginWriteArray("OpenedFiles"); int index = 0; for (const auto &editor : window->editors()) { SessionFileType editorType = determineType(editor); if (fileTypes.testFlag(editorType)) { - settings.setArrayIndex(index); + settings->setArrayIndex(index); if (editorType == SessionManager::SavedFile) { - storeFileDetails(editor, settings); + storeFileDetails(editor, *settings); } else if (editorType == SessionManager::UnsavedFile) { - storeUnsavedFileDetails(editor, settings); + storeUnsavedFileDetails(editor, *settings); } else if (editorType == SessionManager::TempFile) { - storeTempFile(editor, settings); + storeTempFile(editor, *settings); } else { qWarning("Unknown SessionFileType %d", editorType); @@ -170,11 +226,9 @@ void SessionManager::saveSession(MainWindow *window) } } - settings.endArray(); - - settings.setValue("CurrentEditorIndex", currentEditorIndex); + settings->endArray(); - settings.endGroup(); + settings->setValue("CurrentEditorIndex", currentEditorIndex); } void SessionManager::loadSession(MainWindow *window) diff --git a/src/NotepadNext/SessionManager.h b/src/NotepadNext/SessionManager.h index 86c2efc03..0d1dde1be 100644 --- a/src/NotepadNext/SessionManager.h +++ b/src/NotepadNext/SessionManager.h @@ -47,19 +47,23 @@ class SessionManager void clear() const; - void saveSession(MainWindow *window); + bool saveSessionTo(MainWindow *window, QString &path); + void saveDefaultSession(MainWindow *window); void loadSession(MainWindow *window); bool willFileGetStoredInSession(ScintillaNext *editor) const; -private: QDir sessionDirectory() const; + bool isCustomSessionFolder() const { return useCustomSessionFolder; } + +private: + void saveSession(MainWindow *window, QSettings *settings); void saveIntoSessionDirectory(ScintillaNext *editor, const QString &sessionFileName) const; SessionFileType determineType(ScintillaNext *editor) const; - void clearSettings() const; + void clearSettings(QSettings *settings) const; void clearDirectory() const; void storeFileDetails(ScintillaNext *editor, QSettings &settings); @@ -76,6 +80,9 @@ class SessionManager NotepadNextApplication *app; SessionFileTypes fileTypes; + + bool useCustomSessionFolder; + QString customSessionPath; }; Q_DECLARE_OPERATORS_FOR_FLAGS(SessionManager::SessionFileTypes) diff --git a/src/NotepadNext/dialogs/MainWindow.cpp b/src/NotepadNext/dialogs/MainWindow.cpp index 38c4e7924..c7f163f9b 100644 --- a/src/NotepadNext/dialogs/MainWindow.cpp +++ b/src/NotepadNext/dialogs/MainWindow.cpp @@ -52,8 +52,8 @@ #include "ScintillaNext.h" -#include "RecentFilesListManager.h" -#include "RecentFilesListMenuBuilder.h" +#include "RecentListManager.h" +#include "RecentListMenuBuilder.h" #include "EditorManager.h" #include "LuaConsoleDock.h" @@ -179,20 +179,23 @@ MainWindow::MainWindow(NotepadNextApplication *app) : } }); - connect(ui->actionClearRecentFilesList, &QAction::triggered, app->getRecentFilesListManager(), &RecentFilesListManager::clear); + connect(ui->actionClearRecentFilesList, &QAction::triggered, app->getRecentFilesListManager(), &RecentListManager::clear); connect(ui->actionMoveToTrash, &QAction::triggered, this, &MainWindow::moveCurrentFileToTrash); - RecentFilesListMenuBuilder *recentFileListMenuBuilder = new RecentFilesListMenuBuilder(app->getRecentFilesListManager()); + // NOTE: its unfortunate that this has to be hard coded, but there's no way + // to easily determine what should or shouldn't be there + RecentListMenuBuilder *recentFileListMenuBuilder = new RecentListMenuBuilder(app->getRecentFilesListManager(), 4); connect(ui->menuRecentFiles, &QMenu::aboutToShow, this, [=]() { - // NOTE: its unfortunate that this has to be hard coded, but there's no way - // to easily determine what should or shouldn't be there - while (ui->menuRecentFiles->actions().size() > 4) { - delete ui->menuRecentFiles->actions().takeLast(); - } - recentFileListMenuBuilder->populateMenu(ui->menuRecentFiles); }); + connect(recentFileListMenuBuilder, &RecentListMenuBuilder::fileOpenRequest, this, &MainWindow::openFile); + + RecentListMenuBuilder *recentSessionsListMenuBuilder = new RecentListMenuBuilder(app->getRecentSessionsListManager(), 3); + connect(ui->menuSessions, &QMenu::aboutToShow, this, [=]() { + recentSessionsListMenuBuilder->populateMenu(ui->menuSessions); + }); + connect(recentSessionsListMenuBuilder, &RecentListMenuBuilder::fileOpenRequest, this, &MainWindow::loadSession); connect(ui->actionRestoreRecentlyClosedFile, &QAction::triggered, this, [=]() { if (app->getRecentFilesListManager()->count() > 0) { @@ -204,8 +207,6 @@ MainWindow::MainWindow(NotepadNextApplication *app) : openFileList(app->getRecentFilesListManager()->fileList()); }); - connect(recentFileListMenuBuilder, &RecentFilesListMenuBuilder::fileOpenRequest, this, &MainWindow::openFile); - QActionGroup *eolActionGroup = new QActionGroup(this); eolActionGroup->addAction(ui->actionWindows); eolActionGroup->addAction(ui->actionUnix); @@ -894,6 +895,27 @@ ScintillaNext *MainWindow::getInitialEditor() return Q_NULLPTR; } +void MainWindow::loadSession(const QString &filePath) +{ +} + +void MainWindow::on_actionSaveSession_triggered() +{ + FolderAsWorkspaceDock *fawDock = findChild(); + // TODO: if there is active session - use it + SessionManager *sessionManager = app->getSessionManager(); + QString dir = QFileDialog::getExistingDirectory(this, tr("Save Session To Folder"), fawDock->rootPath(), QFileDialog::ShowDirsOnly); + if (!dir.isEmpty()) + { + // TODO: save active session if any + app->getRecentSessionsListManager()->addFile(dir); + if (!sessionManager->saveSessionTo(this, dir)) { + qCritical("Unable to save to %s", dir.toUtf8().constData()); + QMessageBox::critical(this, "Error", tr("Unable to save to %1").arg(dir)); + } + } +} + void MainWindow::openFileList(const QStringList &fileNames) { qInfo(Q_FUNC_INFO); diff --git a/src/NotepadNext/dialogs/MainWindow.h b/src/NotepadNext/dialogs/MainWindow.h index bd73ad6a3..071fbd4f4 100644 --- a/src/NotepadNext/dialogs/MainWindow.h +++ b/src/NotepadNext/dialogs/MainWindow.h @@ -139,6 +139,8 @@ private slots: void languageMenuTriggered(); void checkForUpdatesFinished(QString url); void activateEditor(ScintillaNext *editor); + void on_actionSaveSession_triggered(); + void loadSession(const QString &filePath); private: Ui::MainWindow *ui = Q_NULLPTR; diff --git a/src/NotepadNext/dialogs/MainWindow.ui b/src/NotepadNext/dialogs/MainWindow.ui index 2fc361ed8..7533f1d12 100644 --- a/src/NotepadNext/dialogs/MainWindow.ui +++ b/src/NotepadNext/dialogs/MainWindow.ui @@ -63,6 +63,15 @@ + + + Sessions + + + + + + @@ -82,6 +91,8 @@ + + @@ -1349,6 +1360,24 @@ Alt+Shift+9 + + + Save Session + + + + + Open Session File + + + + + false + + + No Recent Sessions + + From d90fecdac739fa0f3177d177d47f1c635c0707f3 Mon Sep 17 00:00:00 2001 From: Sim Date: Sun, 5 May 2024 18:08:20 +0300 Subject: [PATCH 2/7] Old session list is saved and loaded --- src/NotepadNext/NotepadNextApplication.cpp | 9 +++++++-- src/NotepadNext/dialogs/MainWindow.cpp | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/NotepadNext/NotepadNextApplication.cpp b/src/NotepadNext/NotepadNextApplication.cpp index f28f6952f..f5873e41f 100644 --- a/src/NotepadNext/NotepadNextApplication.cpp +++ b/src/NotepadNext/NotepadNextApplication.cpp @@ -44,6 +44,9 @@ #include #endif +#define RECENT_SESSIONS_KEY "App/RecentSessionsList" +#define RECENT_FILES_KEY "App/RecentFilesList" + const SingleApplication::Options opts = SingleApplication::ExcludeAppPath | SingleApplication::ExcludeAppVersion | SingleApplication::SecondaryNotification; template <> @@ -491,12 +494,14 @@ void NotepadNextApplication::openFiles(const QStringList &files) void NotepadNextApplication::loadSettings() { - recentFilesListManager->setFileList(getSettings()->value("App/RecentFilesList").toStringList()); + recentFilesListManager->setFileList(getSettings()->value(RECENT_FILES_KEY).toStringList()); + recentSessionsListManager->setFileList(getSettings()->value(RECENT_SESSIONS_KEY).toStringList()); } void NotepadNextApplication::saveSettings() { - getSettings()->setValue("App/RecentFilesList", recentFilesListManager->fileList()); + getSettings()->setValue(RECENT_FILES_KEY, recentFilesListManager->fileList()); + getSettings()->setValue(RECENT_SESSIONS_KEY, recentSessionsListManager->fileList()); } MainWindow *NotepadNextApplication::createNewWindow() diff --git a/src/NotepadNext/dialogs/MainWindow.cpp b/src/NotepadNext/dialogs/MainWindow.cpp index c7f163f9b..e07b7ce37 100644 --- a/src/NotepadNext/dialogs/MainWindow.cpp +++ b/src/NotepadNext/dialogs/MainWindow.cpp @@ -908,11 +908,13 @@ void MainWindow::on_actionSaveSession_triggered() if (!dir.isEmpty()) { // TODO: save active session if any - app->getRecentSessionsListManager()->addFile(dir); if (!sessionManager->saveSessionTo(this, dir)) { qCritical("Unable to save to %s", dir.toUtf8().constData()); QMessageBox::critical(this, "Error", tr("Unable to save to %1").arg(dir)); } + else { + app->getRecentSessionsListManager()->addFile(dir); + } } } From 8e10ea5718b681ec46612f426d074a4594807065 Mon Sep 17 00:00:00 2001 From: Sim Date: Sun, 5 May 2024 18:27:21 +0300 Subject: [PATCH 3/7] Sessions are loaded --- doc/TODO.md | 1 + src/NotepadNext/NotepadNextApplication.cpp | 2 +- src/NotepadNext/SessionManager.cpp | 71 ++++++++++++++++------ src/NotepadNext/SessionManager.h | 6 +- src/NotepadNext/dialogs/MainWindow.cpp | 23 ++++++- src/NotepadNext/dialogs/MainWindow.h | 1 + 6 files changed, 79 insertions(+), 25 deletions(-) diff --git a/doc/TODO.md b/doc/TODO.md index 435677486..6b0440cf3 100644 --- a/doc/TODO.md +++ b/doc/TODO.md @@ -2,6 +2,7 @@ - Sessions - [ ] Save/Load sessions + - [ ] Remove tabs on session load - [ ] Store Bookmarks - [ ] Store Tab settings diff --git a/src/NotepadNext/NotepadNextApplication.cpp b/src/NotepadNext/NotepadNextApplication.cpp index f5873e41f..aad71ee65 100644 --- a/src/NotepadNext/NotepadNextApplication.cpp +++ b/src/NotepadNext/NotepadNextApplication.cpp @@ -220,7 +220,7 @@ bool NotepadNextApplication::init() if (settings->restorePreviousSession()) { qInfo("Restoring previous session"); - sessionManager->loadSession(window); + sessionManager->loadDefaultSession(window); } openFiles(parser.positionalArguments()); diff --git a/src/NotepadNext/SessionManager.cpp b/src/NotepadNext/SessionManager.cpp index d74e55223..100e56101 100644 --- a/src/NotepadNext/SessionManager.cpp +++ b/src/NotepadNext/SessionManager.cpp @@ -145,7 +145,7 @@ void SessionManager::clearDirectory() const } } -bool SessionManager::saveSessionTo(MainWindow *window, QString &path) +bool SessionManager::saveSessionTo(MainWindow *window, const QString &path) { useCustomSessionFolder = true; customSessionPath = path; @@ -231,38 +231,74 @@ void SessionManager::saveSession(MainWindow *window, QSettings* settings) settings->setValue("CurrentEditorIndex", currentEditorIndex); } -void SessionManager::loadSession(MainWindow *window) +void SessionManager::loadDefaultSession(MainWindow *window) { - qInfo(Q_FUNC_INFO); - - ApplicationSettings settings;; + ApplicationSettings settings; settings.beginGroup("CurrentSession"); + ScintillaNext *currentEditor = loadSession(window, &settings); + settings.endGroup(); + + if (currentEditor) { + window->switchToEditor(currentEditor); + } +} + +bool SessionManager::loadSessionFrom(MainWindow *window, const QString &path) +{ + SessionFileTypes tmp = fileTypes; + QDir dir(path); + if (!dir.cd(SETTINGS_DIR)) + { + return false; + } + useCustomSessionFolder = true; + customSessionPath = path; + if (!QFile::exists(dir.absolutePath() + QDir::separator() + SETTINGS_FILE)) + { + return false; + } + QSettings *settings = new QSettings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); + + settings->beginGroup("Session"); + ScintillaNext *currentEditor = loadSession(window, settings); + settings->endGroup(); + delete settings; + + if (currentEditor) { + window->switchToEditor(currentEditor); + } + return true; +} + +ScintillaNext *SessionManager::loadSession(MainWindow *window, QSettings *settings) +{ + qInfo(Q_FUNC_INFO); ScintillaNext *currentEditor = Q_NULLPTR; - const int currentEditorIndex = settings.value("CurrentEditorIndex").toInt(); - const int size = settings.beginReadArray("OpenedFiles"); + const int currentEditorIndex = settings->value("CurrentEditorIndex").toInt(); + const int size = settings->beginReadArray("OpenedFiles"); // NOTE: In theory the fileTypes should determine what is loaded, however if the session fileTypes // change from the last time it was saved then it means the settings were manually altered outside of the app, // which is non-standard behavior, so just load anything in the file for (int index = 0; index < size; ++index) { - settings.setArrayIndex(index); + settings->setArrayIndex(index); ScintillaNext *editor = Q_NULLPTR; - if (settings.contains("Type")) { - const QString type = settings.value("Type").toString(); + if (settings->contains("Type")) { + const QString type = settings->value("Type").toString(); if (type == QStringLiteral("File")) { - editor = loadFileDetails(settings); + editor = loadFileDetails(*settings); } else if (type == QStringLiteral("UnsavedFile")) { - editor = loadUnsavedFileDetails(settings); + editor = loadUnsavedFileDetails(*settings); } else if (type == QStringLiteral("Temp")) { - editor = loadTempFile(settings); + editor = loadTempFile(*settings); } else { qDebug("Unknown session entry type: %s", qUtf8Printable(type)); @@ -279,13 +315,8 @@ void SessionManager::loadSession(MainWindow *window) } } - settings.endArray(); - - settings.endGroup(); - - if (currentEditor) { - window->switchToEditor(currentEditor); - } + settings->endArray(); + return currentEditor; } bool SessionManager::willFileGetStoredInSession(ScintillaNext *editor) const diff --git a/src/NotepadNext/SessionManager.h b/src/NotepadNext/SessionManager.h index 0d1dde1be..60cf7c142 100644 --- a/src/NotepadNext/SessionManager.h +++ b/src/NotepadNext/SessionManager.h @@ -47,9 +47,10 @@ class SessionManager void clear() const; - bool saveSessionTo(MainWindow *window, QString &path); + bool saveSessionTo(MainWindow *window, const QString &path); void saveDefaultSession(MainWindow *window); - void loadSession(MainWindow *window); + void loadDefaultSession(MainWindow *window); + bool loadSessionFrom(MainWindow *window, const QString &path); bool willFileGetStoredInSession(ScintillaNext *editor) const; @@ -58,6 +59,7 @@ class SessionManager private: void saveSession(MainWindow *window, QSettings *settings); + ScintillaNext *loadSession(MainWindow *window, QSettings *settings); void saveIntoSessionDirectory(ScintillaNext *editor, const QString &sessionFileName) const; diff --git a/src/NotepadNext/dialogs/MainWindow.cpp b/src/NotepadNext/dialogs/MainWindow.cpp index e07b7ce37..0f2cebcbc 100644 --- a/src/NotepadNext/dialogs/MainWindow.cpp +++ b/src/NotepadNext/dialogs/MainWindow.cpp @@ -895,8 +895,28 @@ ScintillaNext *MainWindow::getInitialEditor() return Q_NULLPTR; } +void MainWindow::on_actionOpenSessionFile_triggered() +{ + FolderAsWorkspaceDock *fawDock = findChild(); + // TODO: if there is active session - use it + QString dir = QFileDialog::getExistingDirectory(this, tr("Load Session From Folder"), fawDock->rootPath(), QFileDialog::ShowDirsOnly); + if (!dir.isEmpty()) { + if (!app->getSessionManager()->loadSessionFrom(this, dir)) + { + qCritical("Unable to load from %s", dir.toUtf8().constData()); + QMessageBox::critical(this, "Error", tr("Unable to load from %1").arg(dir)); + } + else { + app->getRecentSessionsListManager()->addFile(dir); + } + } +} + void MainWindow::loadSession(const QString &filePath) { + if (!app->getSessionManager()->loadSessionFrom(this, filePath)) { + app->getRecentSessionsListManager()->removeFile(filePath); + } } void MainWindow::on_actionSaveSession_triggered() @@ -905,8 +925,7 @@ void MainWindow::on_actionSaveSession_triggered() // TODO: if there is active session - use it SessionManager *sessionManager = app->getSessionManager(); QString dir = QFileDialog::getExistingDirectory(this, tr("Save Session To Folder"), fawDock->rootPath(), QFileDialog::ShowDirsOnly); - if (!dir.isEmpty()) - { + if (!dir.isEmpty()) { // TODO: save active session if any if (!sessionManager->saveSessionTo(this, dir)) { qCritical("Unable to save to %s", dir.toUtf8().constData()); diff --git a/src/NotepadNext/dialogs/MainWindow.h b/src/NotepadNext/dialogs/MainWindow.h index 071fbd4f4..94a070608 100644 --- a/src/NotepadNext/dialogs/MainWindow.h +++ b/src/NotepadNext/dialogs/MainWindow.h @@ -140,6 +140,7 @@ private slots: void checkForUpdatesFinished(QString url); void activateEditor(ScintillaNext *editor); void on_actionSaveSession_triggered(); + void on_actionOpenSessionFile_triggered(); void loadSession(const QString &filePath); private: From 9184f1d5a7d7623a6fad22a328a9d79e28bbdc45 Mon Sep 17 00:00:00 2001 From: Sim Date: Mon, 6 May 2024 09:05:32 +0300 Subject: [PATCH 4/7] + Save sessions on exit + References instead of pointer to QSettings --- doc/TODO.md | 8 +-- src/NotepadNext/NotepadNextApplication.cpp | 2 +- src/NotepadNext/SessionManager.cpp | 68 ++++++++++++---------- src/NotepadNext/SessionManager.h | 7 ++- 4 files changed, 47 insertions(+), 38 deletions(-) diff --git a/doc/TODO.md b/doc/TODO.md index 6b0440cf3..705351dc0 100644 --- a/doc/TODO.md +++ b/doc/TODO.md @@ -1,10 +1,10 @@ ## TODO - Sessions - - [ ] Save/Load sessions - - [ ] Remove tabs on session load - - [ ] Store Bookmarks - - [ ] Store Tab settings + - [v] Save/Load sessions + - [ ] Remove old tabs on session load + - [v] Store Bookmarks + - [ ] Store per session settings - Editor - [ ] Auto Tabs/Spaces diff --git a/src/NotepadNext/NotepadNextApplication.cpp b/src/NotepadNext/NotepadNextApplication.cpp index aad71ee65..f89deae69 100644 --- a/src/NotepadNext/NotepadNextApplication.cpp +++ b/src/NotepadNext/NotepadNextApplication.cpp @@ -523,7 +523,7 @@ MainWindow *NotepadNextApplication::createNewWindow() } } - getSessionManager()->saveDefaultSession(window); + getSessionManager()->saveCurrentSession(window); }); return window; diff --git a/src/NotepadNext/SessionManager.cpp b/src/NotepadNext/SessionManager.cpp index 100e56101..f349262b5 100644 --- a/src/NotepadNext/SessionManager.cpp +++ b/src/NotepadNext/SessionManager.cpp @@ -157,31 +157,40 @@ bool SessionManager::saveSessionTo(MainWindow *window, const QString &path) return false; } - QSettings *settings = new QSettings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); + QSettings settings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); - settings->beginGroup("Session"); + settings.beginGroup("Session"); setSessionFileTypes(tmp | SavedFile); saveSession(window, settings); setSessionFileTypes(tmp); - settings->endGroup(); - settings->sync(); + settings.endGroup(); + settings.sync(); - delete settings; return true; } +void SessionManager::saveCurrentSession(MainWindow *window) +{ + if (useCustomSessionFolder) { + saveSessionTo(window, customSessionPath); + } + else { + saveDefaultSession(window); + } +} + void SessionManager::saveDefaultSession(MainWindow *window) { useCustomSessionFolder = false; ApplicationSettings appSettings; appSettings.beginGroup("CurrentSession"); - saveSession(window, &appSettings); + saveSession(window, appSettings); appSettings.endGroup(); } -void SessionManager::saveSession(MainWindow *window, QSettings* settings) +void SessionManager::saveSession(MainWindow *window, QSettings &settings) { qInfo(Q_FUNC_INFO); @@ -196,23 +205,23 @@ void SessionManager::saveSession(MainWindow *window, QSettings* settings) int currentEditorIndex = 0; ApplicationSettings appSettings; - settings->beginWriteArray("OpenedFiles"); + settings.beginWriteArray("OpenedFiles"); int index = 0; for (const auto &editor : window->editors()) { SessionFileType editorType = determineType(editor); if (fileTypes.testFlag(editorType)) { - settings->setArrayIndex(index); + settings.setArrayIndex(index); if (editorType == SessionManager::SavedFile) { - storeFileDetails(editor, *settings); + storeFileDetails(editor, settings); } else if (editorType == SessionManager::UnsavedFile) { - storeUnsavedFileDetails(editor, *settings); + storeUnsavedFileDetails(editor, settings); } else if (editorType == SessionManager::TempFile) { - storeTempFile(editor, *settings); + storeTempFile(editor, settings); } else { qWarning("Unknown SessionFileType %d", editorType); @@ -226,9 +235,9 @@ void SessionManager::saveSession(MainWindow *window, QSettings* settings) } } - settings->endArray(); + settings.endArray(); - settings->setValue("CurrentEditorIndex", currentEditorIndex); + settings.setValue("CurrentEditorIndex", currentEditorIndex); } void SessionManager::loadDefaultSession(MainWindow *window) @@ -236,7 +245,7 @@ void SessionManager::loadDefaultSession(MainWindow *window) ApplicationSettings settings; settings.beginGroup("CurrentSession"); - ScintillaNext *currentEditor = loadSession(window, &settings); + ScintillaNext *currentEditor = loadSession(window, settings); settings.endGroup(); if (currentEditor) { @@ -258,12 +267,11 @@ bool SessionManager::loadSessionFrom(MainWindow *window, const QString &path) { return false; } - QSettings *settings = new QSettings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); + QSettings settings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); - settings->beginGroup("Session"); + settings.beginGroup("Session"); ScintillaNext *currentEditor = loadSession(window, settings); - settings->endGroup(); - delete settings; + settings.endGroup(); if (currentEditor) { window->switchToEditor(currentEditor); @@ -271,34 +279,34 @@ bool SessionManager::loadSessionFrom(MainWindow *window, const QString &path) return true; } -ScintillaNext *SessionManager::loadSession(MainWindow *window, QSettings *settings) +ScintillaNext *SessionManager::loadSession(MainWindow *window, QSettings &settings) { qInfo(Q_FUNC_INFO); ScintillaNext *currentEditor = Q_NULLPTR; - const int currentEditorIndex = settings->value("CurrentEditorIndex").toInt(); - const int size = settings->beginReadArray("OpenedFiles"); + const int currentEditorIndex = settings.value("CurrentEditorIndex").toInt(); + const int size = settings.beginReadArray("OpenedFiles"); // NOTE: In theory the fileTypes should determine what is loaded, however if the session fileTypes // change from the last time it was saved then it means the settings were manually altered outside of the app, // which is non-standard behavior, so just load anything in the file for (int index = 0; index < size; ++index) { - settings->setArrayIndex(index); + settings.setArrayIndex(index); ScintillaNext *editor = Q_NULLPTR; - if (settings->contains("Type")) { - const QString type = settings->value("Type").toString(); + if (settings.contains("Type")) { + const QString type = settings.value("Type").toString(); if (type == QStringLiteral("File")) { - editor = loadFileDetails(*settings); + editor = loadFileDetails(settings); } else if (type == QStringLiteral("UnsavedFile")) { - editor = loadUnsavedFileDetails(*settings); + editor = loadUnsavedFileDetails(settings); } else if (type == QStringLiteral("Temp")) { - editor = loadTempFile(*settings); + editor = loadTempFile(settings); } else { qDebug("Unknown session entry type: %s", qUtf8Printable(type)); @@ -315,8 +323,8 @@ ScintillaNext *SessionManager::loadSession(MainWindow *window, QSettings *settin } } - settings->endArray(); - return currentEditor; + settings.endArray(); + return currentEditor; } bool SessionManager::willFileGetStoredInSession(ScintillaNext *editor) const diff --git a/src/NotepadNext/SessionManager.h b/src/NotepadNext/SessionManager.h index 60cf7c142..a408ac7c9 100644 --- a/src/NotepadNext/SessionManager.h +++ b/src/NotepadNext/SessionManager.h @@ -48,7 +48,7 @@ class SessionManager void clear() const; bool saveSessionTo(MainWindow *window, const QString &path); - void saveDefaultSession(MainWindow *window); + void saveCurrentSession(MainWindow *window); void loadDefaultSession(MainWindow *window); bool loadSessionFrom(MainWindow *window, const QString &path); @@ -58,8 +58,9 @@ class SessionManager bool isCustomSessionFolder() const { return useCustomSessionFolder; } private: - void saveSession(MainWindow *window, QSettings *settings); - ScintillaNext *loadSession(MainWindow *window, QSettings *settings); + void saveSession(MainWindow *window, QSettings &settings); + void saveDefaultSession(MainWindow *window); + ScintillaNext *loadSession(MainWindow *window, QSettings &settings); void saveIntoSessionDirectory(ScintillaNext *editor, const QString &sessionFileName) const; From bb15f67aef32e1b9b14652992050908d1d44c5de Mon Sep 17 00:00:00 2001 From: Sim Date: Mon, 6 May 2024 09:27:25 +0300 Subject: [PATCH 5/7] Remove old tabs on session load --- doc/TODO.md | 22 ---------------------- src/NotepadNext/SessionManager.cpp | 13 +++++++++++++ 2 files changed, 13 insertions(+), 22 deletions(-) delete mode 100644 doc/TODO.md diff --git a/doc/TODO.md b/doc/TODO.md deleted file mode 100644 index 705351dc0..000000000 --- a/doc/TODO.md +++ /dev/null @@ -1,22 +0,0 @@ -## TODO - - - Sessions - - [v] Save/Load sessions - - [ ] Remove old tabs on session load - - [v] Store Bookmarks - - [ ] Store per session settings - - - Editor - - [ ] Auto Tabs/Spaces - - [ ] Temp views from commands - - [ ] Log streams - - [ ] Support for Language Server Protocol - - - Workspace dock - - [ ] New File - - [ ] New Folder - - [ ] Locate current editor inside tree - - - Other - - [ ] On Save Hooks to Lua (linters etc) - - [ ] Run command diff --git a/src/NotepadNext/SessionManager.cpp b/src/NotepadNext/SessionManager.cpp index f349262b5..125625159 100644 --- a/src/NotepadNext/SessionManager.cpp +++ b/src/NotepadNext/SessionManager.cpp @@ -287,6 +287,19 @@ ScintillaNext *SessionManager::loadSession(MainWindow *window, QSettings &settin const int currentEditorIndex = settings.value("CurrentEditorIndex").toInt(); const int size = settings.beginReadArray("OpenedFiles"); + for (auto &editor : window->editors()) { + if (editor->isFile()) { + if (editor->isSavedToDisk()) { + editor->close(); + } + } + else { + if (!editor->modify()) { + editor->close(); + } + } + } + // NOTE: In theory the fileTypes should determine what is loaded, however if the session fileTypes // change from the last time it was saved then it means the settings were manually altered outside of the app, // which is non-standard behavior, so just load anything in the file From 890520923b5e285d7423ba64bbc28cd66b487c03 Mon Sep 17 00:00:00 2001 From: Sim Date: Wed, 8 May 2024 21:38:02 +0300 Subject: [PATCH 6/7] Save old session when loading a new one --- src/NotepadNext/dialogs/MainWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NotepadNext/dialogs/MainWindow.cpp b/src/NotepadNext/dialogs/MainWindow.cpp index 0f2cebcbc..36687090e 100644 --- a/src/NotepadNext/dialogs/MainWindow.cpp +++ b/src/NotepadNext/dialogs/MainWindow.cpp @@ -901,6 +901,7 @@ void MainWindow::on_actionOpenSessionFile_triggered() // TODO: if there is active session - use it QString dir = QFileDialog::getExistingDirectory(this, tr("Load Session From Folder"), fawDock->rootPath(), QFileDialog::ShowDirsOnly); if (!dir.isEmpty()) { + app->getSessionManager()->saveCurrentSession(this); if (!app->getSessionManager()->loadSessionFrom(this, dir)) { qCritical("Unable to load from %s", dir.toUtf8().constData()); @@ -914,6 +915,7 @@ void MainWindow::on_actionOpenSessionFile_triggered() void MainWindow::loadSession(const QString &filePath) { + app->getSessionManager()->saveCurrentSession(this); if (!app->getSessionManager()->loadSessionFrom(this, filePath)) { app->getRecentSessionsListManager()->removeFile(filePath); } From c49f13407efc46890991b0749a1610499eec6333 Mon Sep 17 00:00:00 2001 From: Sim Date: Thu, 9 May 2024 21:09:43 +0300 Subject: [PATCH 7/7] Save Folder as Workspace Root within session. --- src/NotepadNext/ApplicationSettings.cpp | 11 +++++- src/NotepadNext/ApplicationSettings.h | 34 +++++++++++++++++-- src/NotepadNext/SessionManager.cpp | 18 ++++++++-- src/NotepadNext/SessionManager.h | 9 ++++- src/NotepadNext/dialogs/MainWindow.cpp | 3 +- .../docks/FolderAsWorkspaceDock.cpp | 21 +++++++++--- src/NotepadNext/docks/FolderAsWorkspaceDock.h | 6 +++- 7 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/NotepadNext/ApplicationSettings.cpp b/src/NotepadNext/ApplicationSettings.cpp index 09feebe1d..e8bce1e81 100644 --- a/src/NotepadNext/ApplicationSettings.cpp +++ b/src/NotepadNext/ApplicationSettings.cpp @@ -32,9 +32,18 @@ ApplicationSetting name{#group "/" #name, default};\ } +Settings::Settings(QObject *parent) + : QSettings{parent} +{ +} + +Settings::Settings(const QString &path, QSettings::Format format) + : QSettings(path, format) +{ +} ApplicationSettings::ApplicationSettings(QObject *parent) - : QSettings{parent} + : Settings{parent} { } diff --git a/src/NotepadNext/ApplicationSettings.h b/src/NotepadNext/ApplicationSettings.h index a9aeee858..492383afa 100644 --- a/src/NotepadNext/ApplicationSettings.h +++ b/src/NotepadNext/ApplicationSettings.h @@ -23,6 +23,7 @@ #include #include +#include "SessionManager.h" template class ApplicationSetting @@ -36,11 +37,29 @@ class ApplicationSetting inline T getDefault() const { return mDefault; } inline const char * const key() const { return mKey; } -private: +protected: const char * const mKey; const T mDefault; }; +template +class SessionSetting : public ApplicationSetting +{ +}; + +// This macro should be used on any Qt class which uses session settings so they could be saved/reloaded +#define USE_SESSION_SETTINGS \ +public slots: \ + void onSettingsLoaded(const Settings &settings); \ + void onSettingsSaved(Settings &settings); \ +\ +protected: \ + template \ + void initSettingsListener(T *This, SessionManager *manager) \ + { \ + connect(manager, &SessionManager::onSessionSaved, This, &T::onSettingsSaved); \ + connect(manager, &SessionManager::onSessionLoaded, This, &T::onSettingsLoaded); \ + } #define DEFINE_SETTING(name, lname, type)\ public:\ @@ -51,12 +70,13 @@ Q_SIGNAL\ void lname##Changed(type lname);\ -class ApplicationSettings : public QSettings +class Settings : public QSettings { Q_OBJECT public: - explicit ApplicationSettings(QObject *parent = nullptr); + explicit Settings(QObject *parent = nullptr); + Settings(const QString &path, QSettings::Format format); public: template @@ -71,7 +91,15 @@ class ApplicationSettings : public QSettings void set(const ApplicationSetting &setting, const T &value) { setValue(QLatin1String(setting.key()), value); } +}; + +class ApplicationSettings: public Settings +{ + Q_OBJECT + public: + explicit ApplicationSettings(QObject *parent = nullptr); + DEFINE_SETTING(ShowMenuBar, showMenuBar, bool) DEFINE_SETTING(ShowToolBar, showToolBar, bool) DEFINE_SETTING(ShowTabBar, showTabBar, bool) diff --git a/src/NotepadNext/SessionManager.cpp b/src/NotepadNext/SessionManager.cpp index 125625159..da3543b49 100644 --- a/src/NotepadNext/SessionManager.cpp +++ b/src/NotepadNext/SessionManager.cpp @@ -157,15 +157,17 @@ bool SessionManager::saveSessionTo(MainWindow *window, const QString &path) return false; } - QSettings settings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); + Settings settings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); settings.beginGroup("Session"); setSessionFileTypes(tmp | SavedFile); saveSession(window, settings); setSessionFileTypes(tmp); - settings.endGroup(); + + emit onSessionSaved(settings); + settings.sync(); return true; @@ -188,6 +190,9 @@ void SessionManager::saveDefaultSession(MainWindow *window) appSettings.beginGroup("CurrentSession"); saveSession(window, appSettings); appSettings.endGroup(); + + + emit onSessionSaved(appSettings); } void SessionManager::saveSession(MainWindow *window, QSettings &settings) @@ -247,6 +252,7 @@ void SessionManager::loadDefaultSession(MainWindow *window) settings.beginGroup("CurrentSession"); ScintillaNext *currentEditor = loadSession(window, settings); settings.endGroup(); + emit onSessionLoaded(settings); if (currentEditor) { window->switchToEditor(currentEditor); @@ -267,12 +273,18 @@ bool SessionManager::loadSessionFrom(MainWindow *window, const QString &path) { return false; } - QSettings settings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); + Settings settings(sessionDirectory().absolutePath() + QDir::separator() + SETTINGS_FILE, QSettings::IniFormat); settings.beginGroup("Session"); ScintillaNext *currentEditor = loadSession(window, settings); settings.endGroup(); + settings.beginGroup("FolderAsWorkspace"); + settings.value("RootPath"); + settings.endGroup(); + + emit onSessionLoaded(settings); + if (currentEditor) { window->switchToEditor(currentEditor); } diff --git a/src/NotepadNext/SessionManager.h b/src/NotepadNext/SessionManager.h index a408ac7c9..dce9b42fc 100644 --- a/src/NotepadNext/SessionManager.h +++ b/src/NotepadNext/SessionManager.h @@ -28,9 +28,12 @@ class ScintillaNext; class MainWindow; class NotepadNextApplication; +class Settings; -class SessionManager +class SessionManager: public QObject { + Q_OBJECT + public: enum SessionFileType { None = 0, @@ -57,6 +60,10 @@ class SessionManager QDir sessionDirectory() const; bool isCustomSessionFolder() const { return useCustomSessionFolder; } +signals: + void onSessionSaved(Settings &settings); + void onSessionLoaded(Settings &settings); + private: void saveSession(MainWindow *window, QSettings &settings); void saveDefaultSession(MainWindow *window); diff --git a/src/NotepadNext/dialogs/MainWindow.cpp b/src/NotepadNext/dialogs/MainWindow.cpp index 36687090e..da290f71b 100644 --- a/src/NotepadNext/dialogs/MainWindow.cpp +++ b/src/NotepadNext/dialogs/MainWindow.cpp @@ -756,7 +756,7 @@ MainWindow::MainWindow(NotepadNextApplication *app) : hexViewerDock->toggleViewAction() }); - FolderAsWorkspaceDock *fawDock = new FolderAsWorkspaceDock(this); + FolderAsWorkspaceDock *fawDock = new FolderAsWorkspaceDock(app, this); fawDock->hide(); addDockWidget(Qt::LeftDockWidgetArea, fawDock); ui->menuView->addAction(fawDock->toggleViewAction()); @@ -917,6 +917,7 @@ void MainWindow::loadSession(const QString &filePath) { app->getSessionManager()->saveCurrentSession(this); if (!app->getSessionManager()->loadSessionFrom(this, filePath)) { + qCritical("Unable to load from %s", filePath.toUtf8().constData()); app->getRecentSessionsListManager()->removeFile(filePath); } } diff --git a/src/NotepadNext/docks/FolderAsWorkspaceDock.cpp b/src/NotepadNext/docks/FolderAsWorkspaceDock.cpp index cb8ff936e..c669e9e4c 100644 --- a/src/NotepadNext/docks/FolderAsWorkspaceDock.cpp +++ b/src/NotepadNext/docks/FolderAsWorkspaceDock.cpp @@ -18,14 +18,16 @@ #include "FolderAsWorkspaceDock.h" -#include "ApplicationSettings.h" #include "ui_FolderAsWorkspaceDock.h" +#include "ApplicationSettings.h" +#include "NotepadNextApplication.h" + #include -ApplicationSetting rootPathSetting{"FolderAsWorkspace/RootPath"}; +SessionSetting rootPathSetting{"FolderAsWorkspace/RootPath"}; -FolderAsWorkspaceDock::FolderAsWorkspaceDock(QWidget *parent) : +FolderAsWorkspaceDock::FolderAsWorkspaceDock(NotepadNextApplication* app, QWidget *parent) : QDockWidget(parent), ui(new Ui::FolderAsWorkspaceDock), model(new QFileSystemModel(this)) @@ -43,15 +45,24 @@ FolderAsWorkspaceDock::FolderAsWorkspaceDock(QWidget *parent) : } }); + initSettingsListener(this, app->getSessionManager()); + ApplicationSettings settings; setRootPath(settings.get(rootPathSetting)); } -FolderAsWorkspaceDock::~FolderAsWorkspaceDock() +void FolderAsWorkspaceDock::onSettingsSaved(Settings &settings) { - ApplicationSettings settings; settings.set(rootPathSetting, rootPath()); +} +void FolderAsWorkspaceDock::onSettingsLoaded(const Settings &settings) +{ + setRootPath(settings.get(rootPathSetting)); +} + +FolderAsWorkspaceDock::~FolderAsWorkspaceDock() +{ delete ui; } diff --git a/src/NotepadNext/docks/FolderAsWorkspaceDock.h b/src/NotepadNext/docks/FolderAsWorkspaceDock.h index 085254905..c406d8075 100644 --- a/src/NotepadNext/docks/FolderAsWorkspaceDock.h +++ b/src/NotepadNext/docks/FolderAsWorkspaceDock.h @@ -21,19 +21,23 @@ #define FOLDERASWORKSPACEDOCK_H #include +#include "ApplicationSettings.h" namespace Ui { class FolderAsWorkspaceDock; } class QFileSystemModel; +class NotepadNextApplication; class FolderAsWorkspaceDock : public QDockWidget { Q_OBJECT + USE_SESSION_SETTINGS + public: - explicit FolderAsWorkspaceDock(QWidget *parent = nullptr); + explicit FolderAsWorkspaceDock(NotepadNextApplication* app, QWidget *parent = nullptr); ~FolderAsWorkspaceDock(); void setRootPath(const QString dir);