diff --git a/src/core/sessionconfig.cpp b/src/core/sessionconfig.cpp index dd841a9f..9d21201e 100644 --- a/src/core/sessionconfig.cpp +++ b/src/core/sessionconfig.cpp @@ -66,6 +66,8 @@ void SessionConfig::init() m_searchOption.fromJson(sessionJobj[QStringLiteral("search_option")].toObject()); m_viewAreaSession = readByteArray(sessionJobj, QStringLiteral("viewarea_session")); + + m_notebookExplorerSession = readByteArray(sessionJobj, QStringLiteral("notebook_explorer_session")); } void SessionConfig::loadCore(const QJsonObject &p_session) @@ -183,6 +185,7 @@ QJsonObject SessionConfig::toJson() const obj[QStringLiteral("export_option")] = m_exportOption.toJson(); obj[QStringLiteral("search_option")] = m_searchOption.toJson(); writeByteArray(obj, QStringLiteral("viewarea_session"), m_viewAreaSession); + writeByteArray(obj, QStringLiteral("notebook_explorer_session"), m_notebookExplorerSession); return obj; } @@ -323,3 +326,15 @@ void SessionConfig::setViewAreaSession(const QByteArray &p_bytes) { updateConfigWithoutCheck(m_viewAreaSession, p_bytes, this); } + +QByteArray SessionConfig::getNotebookExplorerSessionAndClear() +{ + QByteArray bytes; + m_notebookExplorerSession.swap(bytes); + return bytes; +} + +void SessionConfig::setNotebookExplorerSession(const QByteArray &p_bytes) +{ + updateConfigWithoutCheck(m_notebookExplorerSession, p_bytes, this); +} diff --git a/src/core/sessionconfig.h b/src/core/sessionconfig.h index b7402a9e..b7a892c4 100644 --- a/src/core/sessionconfig.h +++ b/src/core/sessionconfig.h @@ -92,7 +92,10 @@ namespace vnotex void setSearchOption(const SearchOption &p_option); QByteArray getViewAreaSessionAndClear(); - void setViewAreaSession(const QByteArray &p_obj); + void setViewAreaSession(const QByteArray &p_bytes); + + QByteArray getNotebookExplorerSessionAndClear(); + void setNotebookExplorerSession(const QByteArray &p_bytes); private: void loadCore(const QJsonObject &p_session); @@ -134,6 +137,8 @@ namespace vnotex SearchOption m_searchOption; QByteArray m_viewAreaSession; + + QByteArray m_notebookExplorerSession; }; } // ns vnotex diff --git a/src/widgets/notebookexplorer.cpp b/src/widgets/notebookexplorer.cpp index f33b6191..957ffc92 100644 --- a/src/widgets/notebookexplorer.cpp +++ b/src/widgets/notebookexplorer.cpp @@ -40,6 +40,19 @@ NotebookExplorer::NotebookExplorer(QWidget *p_parent) : QFrame(p_parent) { setupUI(); + + auto mainWindow = VNoteX::getInst().getMainWindow(); + connect(mainWindow, &MainWindow::mainWindowClosed, + this, [this](const QSharedPointer &p_event) { + if (p_event->m_handled) { + return; + } + + saveSession(); + }); + + connect(mainWindow, &MainWindow::mainWindowStarted, + this, &NotebookExplorer::loadSession); } void NotebookExplorer::setupUI() @@ -169,6 +182,8 @@ void NotebookExplorer::reloadNotebook(const Notebook *p_notebook) void NotebookExplorer::setCurrentNotebook(const QSharedPointer &p_notebook) { + updateSession(); + m_currentNotebook = p_notebook; ID id = p_notebook ? p_notebook->getId() : static_cast(Notebook::InvalidId); @@ -176,6 +191,8 @@ void NotebookExplorer::setCurrentNotebook(const QSharedPointer &p_note m_nodeExplorer->setNotebook(p_notebook); + recoverSession(); + emit updateTitleBarMenuActions(); } @@ -414,3 +431,62 @@ void NotebookExplorer::setupViewMenu(QMenu *p_menu) m_nodeExplorer->setViewOrder(order); }); } + +void NotebookExplorer::saveSession() +{ + updateSession(); + + auto &sessionConfig = ConfigMgr::getInst().getSessionConfig(); + sessionConfig.setNotebookExplorerSession(m_session.serialize()); +} + +void NotebookExplorer::loadSession() +{ + auto &sessionConfig = ConfigMgr::getInst().getSessionConfig(); + m_session = NotebookExplorerSession::deserialize(sessionConfig.getNotebookExplorerSessionAndClear()); + + m_sessionLoaded = true; + + recoverSession(); +} + +void NotebookExplorer::updateSession() +{ + if (!m_sessionLoaded || !m_currentNotebook) { + return; + } + + auto& nbSession = m_session.m_notebooks[m_currentNotebook->getRootFolderPath()]; + nbSession.m_recovered = true; + + auto node = currentExploredNode(); + if (node) { + nbSession.m_currentNodePath = node->fetchPath(); + } else { + nbSession.m_currentNodePath.clear(); + } +} + +void NotebookExplorer::recoverSession() +{ + if (!m_sessionLoaded || !m_currentNotebook) { + return; + } + + auto it = m_session.m_notebooks.find(m_currentNotebook->getRootFolderPath()); + if (it != m_session.m_notebooks.end()) { + qDebug() << it.value().m_recovered << it.value().m_currentNodePath; + + if (it.value().m_recovered || it.value().m_currentNodePath.isEmpty()) { + return; + } + + it.value().m_recovered = true; + + auto node = m_currentNotebook->loadNodeByPath(it.value().m_currentNodePath); + qDebug() << "node" << node; + if (node) { + m_nodeExplorer->setCurrentNode(node.data()); + } + } +} diff --git a/src/widgets/notebookexplorer.h b/src/widgets/notebookexplorer.h index 1b6b761e..61f047eb 100644 --- a/src/widgets/notebookexplorer.h +++ b/src/widgets/notebookexplorer.h @@ -4,7 +4,9 @@ #include #include -#include "global.h" +#include + +#include "notebookexplorersession.h" class QMenu; @@ -68,11 +70,23 @@ namespace vnotex void setupViewMenu(QMenu *p_menu); + void saveSession(); + + void loadSession(); + + void updateSession(); + + void recoverSession(); + NotebookSelector *m_selector = nullptr; NotebookNodeExplorer *m_nodeExplorer = nullptr; QSharedPointer m_currentNotebook; + + NotebookExplorerSession m_session; + + bool m_sessionLoaded = false; }; } // ns vnotex diff --git a/src/widgets/notebookexplorersession.cpp b/src/widgets/notebookexplorersession.cpp new file mode 100644 index 00000000..7c1cf16f --- /dev/null +++ b/src/widgets/notebookexplorersession.cpp @@ -0,0 +1,41 @@ +#include "notebookexplorersession.h" + +using namespace vnotex; + +QDataStream &::vnotex::operator<<(QDataStream &p_ds, const NotebookSession &p_session) +{ + p_ds << p_session.m_currentNodePath; + return p_ds; +} + +QDataStream &::vnotex::operator>>(QDataStream &p_ds, NotebookSession &p_session) +{ + p_ds >> p_session.m_currentNodePath; + return p_ds; +} + +QByteArray NotebookExplorerSession::serialize() const +{ + QByteArray data; + QDataStream outs(&data, QIODevice::WriteOnly); + outs.setVersion(QDataStream::Qt_5_12); + + outs << m_notebooks; + + return data; +} + +NotebookExplorerSession NotebookExplorerSession::deserialize(const QByteArray &p_data) +{ + NotebookExplorerSession session; + if (p_data.isEmpty()) { + return session; + } + + QDataStream ins(p_data); + ins.setVersion(QDataStream::Qt_5_12); + + ins >> session.m_notebooks; + + return session; +} diff --git a/src/widgets/notebookexplorersession.h b/src/widgets/notebookexplorersession.h new file mode 100644 index 00000000..83fa4ac3 --- /dev/null +++ b/src/widgets/notebookexplorersession.h @@ -0,0 +1,32 @@ +#ifndef NOTEBOOKEXPLORERSESSION_H +#define NOTEBOOKEXPLORERSESSION_H + +#include +#include + +namespace vnotex +{ + struct NotebookSession + { + // Used to judge whether this session has been recovered. + bool m_recovered = false; + + QString m_currentNodePath; + }; + + class NotebookExplorerSession + { + public: + QByteArray serialize() const; + + static NotebookExplorerSession deserialize(const QByteArray &p_data); + + // Notebook's path to its session. + QHash m_notebooks; + }; + + extern QDataStream &operator<<(QDataStream &p_ds, const NotebookSession &p_session); + extern QDataStream &operator>>(QDataStream &p_ds, NotebookSession &p_session); +} + +#endif // NOTEBOOKEXPLORERSESSION_H diff --git a/src/widgets/viewsplit.cpp b/src/widgets/viewsplit.cpp index cf1e3c98..faa3cf03 100644 --- a/src/widgets/viewsplit.cpp +++ b/src/widgets/viewsplit.cpp @@ -415,8 +415,7 @@ void ViewSplit::updateWindowList(QMenu *p_menu) for (int i = 0; i < cnt; ++i) { auto window = getViewWindow(i); - auto act = new QAction(window->getIcon(), - window->getName(), + auto act = new QAction(window->getName(), m_windowListActionGroup); act->setToolTip(window->getTitle()); act->setData(i); diff --git a/src/widgets/viewwindow.cpp b/src/widgets/viewwindow.cpp index 34691b4b..45f5ed63 100644 --- a/src/widgets/viewwindow.cpp +++ b/src/widgets/viewwindow.cpp @@ -178,13 +178,16 @@ void ViewWindow::detachFromBuffer(bool p_quiet) } } -const QIcon &ViewWindow::getIcon() const +QIcon ViewWindow::getIcon() const { + /* if (m_buffer) { return m_buffer->isModified() ? s_modifiedIcon : s_savedIcon; } else { return s_savedIcon; } + */ + return QIcon(); } QString ViewWindow::getName() const diff --git a/src/widgets/viewwindow.h b/src/widgets/viewwindow.h index 12cdafb9..8fda5806 100644 --- a/src/widgets/viewwindow.h +++ b/src/widgets/viewwindow.h @@ -43,7 +43,7 @@ namespace vnotex // User request to open the buffer attached to this ViewWindow again. virtual void openTwice(const QSharedPointer &p_paras) = 0; - virtual const QIcon &getIcon() const; + virtual QIcon getIcon() const; virtual QString getName() const; diff --git a/src/widgets/widgets.pri b/src/widgets/widgets.pri index 46923601..f0da8f2c 100644 --- a/src/widgets/widgets.pri +++ b/src/widgets/widgets.pri @@ -47,6 +47,7 @@ SOURCES += \ $$PWD/mainwindow.cpp \ $$PWD/markdownviewwindow.cpp \ $$PWD/navigationmodemgr.cpp \ + $$PWD/notebookexplorersession.cpp \ $$PWD/outlinepopup.cpp \ $$PWD/outlineprovider.cpp \ $$PWD/outlineviewer.cpp \ @@ -140,6 +141,7 @@ HEADERS += \ $$PWD/markdownviewwindow.h \ $$PWD/navigationmodemgr.h \ $$PWD/navigationmodewrapper.h \ + $$PWD/notebookexplorersession.h \ $$PWD/outlinepopup.h \ $$PWD/outlineprovider.h \ $$PWD/outlineviewer.h \