diff --git a/src/core/iconfig.h b/src/core/iconfig.h index 263a2816a2..dc4fe2d4d9 100644 --- a/src/core/iconfig.h +++ b/src/core/iconfig.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include namespace vnotex { @@ -137,6 +139,34 @@ namespace vnotex p_obj.insert(p_key, QLatin1String(p_bytes.toBase64())); } + static QBitArray readBitArray(const QJsonObject &p_obj, + const QString &p_key) + { + auto bytes = readByteArray(p_obj, p_key); + if (bytes.isEmpty()) { + return QBitArray(); + } + + QDataStream ds(bytes); + ds.setVersion(QDataStream::Qt_5_12); + + QBitArray bits; + ds >> bits; + return bits; + } + + static void writeBitArray(QJsonObject &p_obj, + const QString &p_key, + const QBitArray &p_bits) + { + QByteArray bytes; + QDataStream ds(&bytes, QIODevice::WriteOnly); + ds.setVersion(QDataStream::Qt_5_12); + ds << p_bits; + + writeByteArray(p_obj, p_key, bytes); + } + static bool readBool(const QJsonObject &p_default, const QJsonObject &p_user, const QString &p_key) diff --git a/src/core/sessionconfig.cpp b/src/core/sessionconfig.cpp index e6b1685662..452d85d71e 100644 --- a/src/core/sessionconfig.cpp +++ b/src/core/sessionconfig.cpp @@ -199,6 +199,7 @@ QJsonObject SessionConfig::saveStateAndGeometry() const QJsonObject obj; writeByteArray(obj, QStringLiteral("main_window_state"), m_mainWindowStateGeometry.m_mainState); writeByteArray(obj, QStringLiteral("main_window_geometry"), m_mainWindowStateGeometry.m_mainGeometry); + writeBitArray(obj, QStringLiteral("docks_visibility_before_expand"), m_mainWindowStateGeometry.m_docksVisibilityBeforeExpand); return obj; } @@ -318,6 +319,7 @@ void SessionConfig::loadStateAndGeometry(const QJsonObject &p_session) const auto obj = p_session.value(QStringLiteral("state_geometry")).toObject(); m_mainWindowStateGeometry.m_mainState = readByteArray(obj, QStringLiteral("main_window_state")); m_mainWindowStateGeometry.m_mainGeometry = readByteArray(obj, QStringLiteral("main_window_geometry")); + m_mainWindowStateGeometry.m_docksVisibilityBeforeExpand = readBitArray(obj, QStringLiteral("docks_visibility_before_expand")); } QByteArray SessionConfig::getViewAreaSessionAndClear() diff --git a/src/core/sessionconfig.h b/src/core/sessionconfig.h index e8813e2ce2..603b34d719 100644 --- a/src/core/sessionconfig.h +++ b/src/core/sessionconfig.h @@ -34,11 +34,15 @@ namespace vnotex bool operator==(const MainWindowStateGeometry &p_other) const { return m_mainState == p_other.m_mainState - && m_mainGeometry == p_other.m_mainGeometry; + && m_mainGeometry == p_other.m_mainGeometry + && m_docksVisibilityBeforeExpand == p_other.m_docksVisibilityBeforeExpand; } QByteArray m_mainState; + QByteArray m_mainGeometry; + + QBitArray m_docksVisibilityBeforeExpand; }; enum OpenGL diff --git a/src/core/widgetconfig.cpp b/src/core/widgetconfig.cpp index 79a571223a..92fed2557a 100644 --- a/src/core/widgetconfig.cpp +++ b/src/core/widgetconfig.cpp @@ -4,6 +4,7 @@ using namespace vnotex; #define READINT(key) readInt(appObj, userObj, (key)) #define READBOOL(key) readBool(appObj, userObj, (key)) +#define READSTRLIST(key) readStringList(appObj, userObj, (key)) WidgetConfig::WidgetConfig(ConfigMgr *p_mgr, IConfig *p_topConfig) : IConfig(p_mgr, p_topConfig) @@ -29,6 +30,7 @@ void WidgetConfig::init(const QJsonObject &p_app, m_nodeExplorerExternalFilesVisible = READBOOL(QStringLiteral("node_explorer_external_files_visible")); m_nodeExplorerAutoImportExternalFilesEnabled = READBOOL(QStringLiteral("node_explorer_auto_import_external_files_enabled")); m_searchPanelAdvancedSettingsVisible = READBOOL(QStringLiteral("search_panel_advanced_settings_visible")); + m_mainWindowKeepDocksExpandingContentArea = READSTRLIST(QStringLiteral("main_window_keep_docks_expanding_content_area")); } QJsonObject WidgetConfig::toJson() const @@ -41,6 +43,9 @@ QJsonObject WidgetConfig::toJson() const obj[QStringLiteral("node_explorer_external_files_visible")] = m_nodeExplorerExternalFilesVisible; obj[QStringLiteral("node_explorer_auto_import_external_files_enabled")] = m_nodeExplorerAutoImportExternalFilesEnabled; obj[QStringLiteral("search_panel_advanced_settings_visible")] = m_searchPanelAdvancedSettingsVisible; + writeStringList(obj, + QStringLiteral("main_window_keep_docks_expanding_content_area"), + m_mainWindowKeepDocksExpandingContentArea); return obj; } @@ -113,3 +118,13 @@ void WidgetConfig::setSearchPanelAdvancedSettingsVisible(bool p_visible) { updateConfig(m_searchPanelAdvancedSettingsVisible, p_visible, this); } + +const QStringList &WidgetConfig::getMainWindowKeepDocksExpandingContentArea() const +{ + return m_mainWindowKeepDocksExpandingContentArea; +} + +void WidgetConfig::setMainWindowKeepDocksExpandingContentArea(const QStringList &p_docks) +{ + updateConfig(m_mainWindowKeepDocksExpandingContentArea, p_docks, this); +} diff --git a/src/core/widgetconfig.h b/src/core/widgetconfig.h index 9ede9d7a60..a31fdbfe56 100644 --- a/src/core/widgetconfig.h +++ b/src/core/widgetconfig.h @@ -39,6 +39,9 @@ namespace vnotex bool isSearchPanelAdvancedSettingsVisible() const; void setSearchPanelAdvancedSettingsVisible(bool p_visible); + const QStringList &getMainWindowKeepDocksExpandingContentArea() const; + void setMainWindowKeepDocksExpandingContentArea(const QStringList &p_docks); + private: int m_outlineAutoExpandedLevel = 6; @@ -53,6 +56,9 @@ namespace vnotex bool m_nodeExplorerAutoImportExternalFilesEnabled = true; bool m_searchPanelAdvancedSettingsVisible = true; + + // Object name of those docks that should be kept when expanding content area. + QStringList m_mainWindowKeepDocksExpandingContentArea; }; } diff --git a/src/data/core/core.qrc b/src/data/core/core.qrc index b30a489f96..554554cd27 100644 --- a/src/data/core/core.qrc +++ b/src/data/core/core.qrc @@ -16,7 +16,6 @@ icons/expand.svg icons/fullscreen.svg icons/history_explorer.svg - icons/notebook_explorer.svg icons/tag_explorer.svg icons/help.svg icons/menu.svg diff --git a/src/data/core/icons/notebook_explorer.svg b/src/data/core/icons/notebook_explorer.svg deleted file mode 100644 index f7ba80b7b0..0000000000 --- a/src/data/core/icons/notebook_explorer.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/src/data/core/vnotex.json b/src/data/core/vnotex.json index 35075f5046..cf345d4bb6 100644 --- a/src/data/core/vnotex.json +++ b/src/data/core/vnotex.json @@ -311,6 +311,8 @@ "node_explorer_recycle_bin_node_visible" : false, "node_explorer_external_files_visible" : true, "node_explorer_auto_import_external_files_enabled" : true, - "search_panel_advanced_settings_visible" : true + "search_panel_advanced_settings_visible" : true, + "//comment" : "Docks to ignore when expanding content area of main window", + "main_window_keep_docks_expanding_content_area": [] } } diff --git a/src/widgets/dialogs/settings/appearancepage.cpp b/src/widgets/dialogs/settings/appearancepage.cpp index a5f2a7c31e..16662dc400 100644 --- a/src/widgets/dialogs/settings/appearancepage.cpp +++ b/src/widgets/dialogs/settings/appearancepage.cpp @@ -3,12 +3,17 @@ #include #include #include +#include +#include #include #include #include +#include #include #include +#include +#include using namespace vnotex; @@ -45,30 +50,71 @@ void AppearancePage::setupUI() connect(m_toolBarIconSizeSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &AppearancePage::pageIsChanged); } + + { + const auto &docks = VNoteX::getInst().getMainWindow()->getDocks(); + Q_ASSERT(!docks.isEmpty()); + m_keepDocksExpandingContentArea.resize(docks.size()); + + auto layout = new QVBoxLayout(); + + for (int i = 0; i < docks.size(); ++i) { + m_keepDocksExpandingContentArea[i].first = WidgetsFactory::createCheckBox(docks[i]->windowTitle(), this); + m_keepDocksExpandingContentArea[i].second = docks[i]->objectName(); + layout->addWidget(m_keepDocksExpandingContentArea[i].first); + connect(m_keepDocksExpandingContentArea[i].first, &QCheckBox::stateChanged, + this, &AppearancePage::pageIsChanged); + } + + const QString label(tr("Keep dock widgets when expanding content area:")); + mainLayout->addRow(label, layout); + addSearchItem(label, label, m_keepDocksExpandingContentArea.first().first); + } } void AppearancePage::loadInternal() { const auto &sessionConfig = ConfigMgr::getInst().getSessionConfig(); const auto &coreConfig = ConfigMgr::getInst().getCoreConfig(); + const auto &widgetConfig = ConfigMgr::getInst().getWidgetConfig(); if (m_systemTitleBarCheckBox) { m_systemTitleBarCheckBox->setChecked(sessionConfig.getSystemTitleBarEnabled()); } m_toolBarIconSizeSpinBox->setValue(coreConfig.getToolBarIconSize()); + + { + const auto &docks = widgetConfig.getMainWindowKeepDocksExpandingContentArea(); + for (const auto &cb : m_keepDocksExpandingContentArea) { + if (docks.contains(cb.second)) { + cb.first->setChecked(true); + } + } + } } void AppearancePage::saveInternal() { auto &sessionConfig = ConfigMgr::getInst().getSessionConfig(); auto &coreConfig = ConfigMgr::getInst().getCoreConfig(); + auto &widgetConfig = ConfigMgr::getInst().getWidgetConfig(); if (m_systemTitleBarCheckBox) { sessionConfig.setSystemTitleBarEnabled(m_systemTitleBarCheckBox->isChecked()); } coreConfig.setToolBarIconSize(m_toolBarIconSizeSpinBox->value()); + + { + QStringList docks; + for (const auto &cb : m_keepDocksExpandingContentArea) { + if (cb.first->isChecked()) { + docks << cb.second; + } + } + widgetConfig.setMainWindowKeepDocksExpandingContentArea(docks); + } } QString AppearancePage::title() const diff --git a/src/widgets/dialogs/settings/appearancepage.h b/src/widgets/dialogs/settings/appearancepage.h index aaad115d3e..a0e61a751c 100644 --- a/src/widgets/dialogs/settings/appearancepage.h +++ b/src/widgets/dialogs/settings/appearancepage.h @@ -3,6 +3,9 @@ #include "settingspage.h" +#include +#include + class QCheckBox; class QSpinBox; @@ -27,6 +30,9 @@ namespace vnotex QCheckBox *m_systemTitleBarCheckBox = nullptr; QSpinBox *m_toolBarIconSizeSpinBox = nullptr; + + // . + QVector> m_keepDocksExpandingContentArea; }; } diff --git a/src/widgets/dialogs/settings/settingsdialog.cpp b/src/widgets/dialogs/settings/settingsdialog.cpp index 6695512ad6..a3dba929b1 100644 --- a/src/widgets/dialogs/settings/settingsdialog.cpp +++ b/src/widgets/dialogs/settings/settingsdialog.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -19,7 +20,7 @@ using namespace vnotex; SettingsDialog::SettingsDialog(QWidget *p_parent) - : ScrollDialog(p_parent) + : Dialog(p_parent) { setupUI(); @@ -35,8 +36,16 @@ void SettingsDialog::setupUI() setupPageExplorer(mainLayout, widget); - m_pageLayout = new QStackedLayout(); - mainLayout->addLayout(m_pageLayout, 5); + { + auto scrollArea = new QScrollArea(widget); + scrollArea->setWidgetResizable(true); + mainLayout->addWidget(scrollArea, 5); + + auto scrollWidget = new QWidget(scrollArea); + scrollArea->setWidget(scrollWidget); + + m_pageLayout = new QStackedLayout(scrollWidget); + } setDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Apply @@ -116,6 +125,7 @@ void SettingsDialog::setupPages() setChangesUnsaved(false); m_pageExplorer->setCurrentItem(m_pageExplorer->topLevelItem(0), 0, QItemSelectionModel::ClearAndSelect); + m_pageExplorer->expandAll(); m_pageLayout->setCurrentIndex(0); m_ready = true; diff --git a/src/widgets/dialogs/settings/settingsdialog.h b/src/widgets/dialogs/settings/settingsdialog.h index 9b382b348c..4cb875a00f 100644 --- a/src/widgets/dialogs/settings/settingsdialog.h +++ b/src/widgets/dialogs/settings/settingsdialog.h @@ -1,7 +1,7 @@ #ifndef SETTINGSDIALOG_H #define SETTINGSDIALOG_H -#include "../scrolldialog.h" +#include "../dialog.h" #include @@ -14,7 +14,7 @@ namespace vnotex { class SettingsPage; - class SettingsDialog : public ScrollDialog + class SettingsDialog : public Dialog { Q_OBJECT public: diff --git a/src/widgets/mainwindow.cpp b/src/widgets/mainwindow.cpp index 34b6d2ddac..4f575a427c 100644 --- a/src/widgets/mainwindow.cpp +++ b/src/widgets/mainwindow.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include "toolbox.h" #include "notebookexplorer.h" @@ -29,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -251,9 +251,9 @@ void MainWindow::setupNavigationDock() dock->setObjectName(QStringLiteral("NavigationDock.vnotex")); dock->setAllowedAreas(Qt::AllDockWidgetAreas); - setupNavigationToolBox(); - dock->setWidget(m_navigationToolBox); - dock->setFocusProxy(m_navigationToolBox); + setupNotebookExplorer(this); + dock->setWidget(m_notebookExplorer); + dock->setFocusProxy(m_notebookExplorer); addDockWidget(Qt::LeftDockWidgetArea, dock); } @@ -318,39 +318,6 @@ void MainWindow::setupLocationList() NavigationModeMgr::getInst().registerNavigationTarget(m_locationList->getNavigationModeWrapper()); } -void MainWindow::setupNavigationToolBox() -{ - m_navigationToolBox = new ToolBox(this); - m_navigationToolBox->setObjectName("NavigationToolBox.vnotex"); - - NavigationModeMgr::getInst().registerNavigationTarget(m_navigationToolBox); - - const auto &themeMgr = VNoteX::getInst().getThemeMgr(); - - // Notebook explorer. - setupNotebookExplorer(m_navigationToolBox); - m_navigationToolBox->addItem(m_notebookExplorer, - themeMgr.getIconFile("notebook_explorer.svg"), - tr("Notebooks"), - nullptr); - - /* - // History explorer. - auto historyExplorer = new QWidget(this); - m_navigationToolBox->addItem(historyExplorer, - themeMgr.getIconFile("history_explorer.svg"), - tr("History"), - nullptr); - - // Tag explorer. - auto tagExplorer = new QWidget(this); - m_navigationToolBox->addItem(tagExplorer, - themeMgr.getIconFile("tag_explorer.svg"), - tr("Tags"), - nullptr); - */ -} - void MainWindow::setupNotebookExplorer(QWidget *p_parent) { m_notebookExplorer = new NotebookExplorer(p_parent); @@ -451,6 +418,7 @@ void MainWindow::saveStateAndGeometry() SessionConfig::MainWindowStateGeometry sg; sg.m_mainState = saveState(); sg.m_mainGeometry = saveGeometry(); + sg.m_docksVisibilityBeforeExpand = m_docksVisibilityBeforeExpand; auto& sessionConfig = ConfigMgr::getInst().getSessionConfig(); sessionConfig.setMainWindowStateGeometry(sg); @@ -469,6 +437,17 @@ void MainWindow::loadStateAndGeometry(bool p_stateOnly) // Will also restore the state of dock widgets. restoreState(sg.m_mainState); } + + if (!p_stateOnly) { + m_docksVisibilityBeforeExpand = sg.m_docksVisibilityBeforeExpand; + if (m_docksVisibilityBeforeExpand.isEmpty()) { + // Init. + m_docksVisibilityBeforeExpand.resize(m_docks.size()); + for (int i = 0; i < m_docks.size(); ++i) { + m_docksVisibilityBeforeExpand.setBit(i, m_docks[i]->isVisible()); + } + } + } } void MainWindow::resetStateAndGeometry() @@ -485,35 +464,46 @@ void MainWindow::resetStateAndGeometry() void MainWindow::setContentAreaExpanded(bool p_expanded) { - static QBitArray dockStateCache(m_docks.size(), false); + const auto &keepDocks = ConfigMgr::getInst().getWidgetConfig().getMainWindowKeepDocksExpandingContentArea(); if (p_expanded) { // Store the state and hide. for (int i = 0; i < m_docks.size(); ++i) { - if (m_docks[i]->isFloating()) { - dockStateCache[i] = true; + m_docksVisibilityBeforeExpand[i] = m_docks[i]->isVisible(); + + if (m_docks[i]->isFloating() || keepDocks.contains(m_docks[i]->objectName())) { continue; } - dockStateCache[i] = m_docks[i]->isVisible(); m_docks[i]->setVisible(false); } } else { // Restore the state. + bool hasVisible = false; for (int i = 0; i < m_docks.size(); ++i) { - if (m_docks[i]->isFloating()) { + if (m_docks[i]->isFloating() || keepDocks.contains(m_docks[i]->objectName())) { continue; } - m_docks[i]->setVisible(dockStateCache[i]); + if (m_docksVisibilityBeforeExpand[i]) { + hasVisible = true; + } + + m_docks[i]->setVisible(m_docksVisibilityBeforeExpand[i]); + } + + if (!hasVisible) { + // At least make one visible. + m_docks[DockIndex::NavigationDock]->setVisible(true); } } } bool MainWindow::isContentAreaExpanded() const { + const auto &keepDocks = ConfigMgr::getInst().getWidgetConfig().getMainWindowKeepDocksExpandingContentArea(); for (auto dock : m_docks) { - if (!dock->isFloating() && dock->isVisible()) { + if (!dock->isFloating() && dock->isVisible() && !keepDocks.contains(dock->objectName())) { return false; } } diff --git a/src/widgets/mainwindow.h b/src/widgets/mainwindow.h index ae805ccbf0..691849c396 100644 --- a/src/widgets/mainwindow.h +++ b/src/widgets/mainwindow.h @@ -3,6 +3,7 @@ #include #include +#include #include "toolbarhelper.h" #include "statusbarhelper.h" @@ -102,8 +103,6 @@ namespace vnotex void setupCentralWidget(); - void setupNavigationToolBox(); - void setupOutlineViewer(); void setupNavigationDock(); @@ -184,6 +183,8 @@ namespace vnotex QLabel *m_tipsLabel = nullptr; QTimer *m_tipsTimer = nullptr; + + QBitArray m_docksVisibilityBeforeExpand; }; } // ns vnotex diff --git a/src/widgets/notebooknodeexplorer.cpp b/src/widgets/notebooknodeexplorer.cpp index b50e20f52b..870f9246b5 100644 --- a/src/widgets/notebooknodeexplorer.cpp +++ b/src/widgets/notebooknodeexplorer.cpp @@ -1168,6 +1168,7 @@ QAction *NotebookNodeExplorer::createAction(Action p_act, QObject *p_parent) act = new QAction(tr("&Expand All\t*"), p_parent); connect(act, &QAction::triggered, this, &NotebookNodeExplorer::expandCurrentNodeAll); + break; case Action::PinToQuickAccess: act = new QAction(tr("Pin To &Quick Access"), p_parent);