Browse Source

allow to keep docks when expanding content area

Le Tan 4 năm trước cách đây
mục cha
commit
9ada45ea4b

+ 30 - 0
src/core/iconfig.h

@@ -4,6 +4,8 @@
 #include <QSharedPointer>
 #include <QJsonObject>
 #include <QJsonArray>
+#include <QBitArray>
+#include <QDataStream>
 
 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)

+ 2 - 0
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()

+ 5 - 1
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

+ 15 - 0
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);
+}

+ 6 - 0
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;
     };
 }
 

+ 0 - 1
src/data/core/core.qrc

@@ -16,7 +16,6 @@
         <file>icons/expand.svg</file>
         <file>icons/fullscreen.svg</file>
         <file>icons/history_explorer.svg</file>
-        <file>icons/notebook_explorer.svg</file>
         <file>icons/tag_explorer.svg</file>
         <file>icons/help.svg</file>
         <file>icons/menu.svg</file>

+ 0 - 8
src/data/core/icons/notebook_explorer.svg

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
-	 width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
-<path style="fill:#000000" d="M464,64v416H80c-17.672,0-32-14.313-32-32s14.328-32,32-32h352V0H80C44.656,0,16,28.656,16,64v384c0,35.344,28.656,64,64,64
-	h416V64H464z M80,128V96V32h320v352H80V128z M336,96H144V64h192V96z M272,160H144v-32h128V160z M208,224h-64v-32h64V224z"/>
-</svg>

+ 3 - 1
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": []
     }
 }

+ 46 - 0
src/widgets/dialogs/settings/appearancepage.cpp

@@ -3,12 +3,17 @@
 #include <QCheckBox>
 #include <QFormLayout>
 #include <QSpinBox>
+#include <QVBoxLayout>
+#include <QDockWidget>
 
 #include <widgets/widgetsfactory.h>
 #include <core/sessionconfig.h>
 #include <core/coreconfig.h>
+#include <core/widgetconfig.h>
 #include <core/configmgr.h>
 #include <utils/widgetutils.h>
+#include <widgets/mainwindow.h>
+#include <core/vnotex.h>
 
 using namespace vnotex;
 
@@ -45,30 +50,71 @@ void AppearancePage::setupUI()
         connect(m_toolBarIconSizeSpinBox, QOverload<int>::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

+ 6 - 0
src/widgets/dialogs/settings/appearancepage.h

@@ -3,6 +3,9 @@
 
 #include "settingspage.h"
 
+#include <QVector>
+#include <QPair>
+
 class QCheckBox;
 class QSpinBox;
 
@@ -27,6 +30,9 @@ namespace vnotex
         QCheckBox *m_systemTitleBarCheckBox = nullptr;
 
         QSpinBox *m_toolBarIconSizeSpinBox = nullptr;
+
+        // <CheckBox, ObjectName>.
+        QVector<QPair<QCheckBox *, QString>> m_keepDocksExpandingContentArea;
     };
 }
 

+ 13 - 3
src/widgets/dialogs/settings/settingsdialog.cpp

@@ -3,6 +3,7 @@
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QStackedLayout>
+#include <QScrollArea>
 
 #include <widgets/treewidget.h>
 #include <widgets/lineedit.h>
@@ -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;

+ 2 - 2
src/widgets/dialogs/settings/settingsdialog.h

@@ -1,7 +1,7 @@
 #ifndef SETTINGSDIALOG_H
 #define SETTINGSDIALOG_H
 
-#include "../scrolldialog.h"
+#include "../dialog.h"
 
 #include <functional>
 
@@ -14,7 +14,7 @@ namespace vnotex
 {
     class SettingsPage;
 
-    class SettingsDialog : public ScrollDialog
+    class SettingsDialog : public Dialog
     {
         Q_OBJECT
     public:

+ 34 - 44
src/widgets/mainwindow.cpp

@@ -18,7 +18,6 @@
 #include <QSystemTrayIcon>
 #include <QWindowStateChangeEvent>
 #include <QTimer>
-#include <QBitArray>
 
 #include "toolbox.h"
 #include "notebookexplorer.h"
@@ -29,6 +28,7 @@
 #include <core/configmgr.h>
 #include <core/sessionconfig.h>
 #include <core/coreconfig.h>
+#include <core/widgetconfig.h>
 #include <core/events.h>
 #include <core/fileopenparameters.h>
 #include <widgets/dialogs/exportdialog.h>
@@ -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;
         }
     }

+ 3 - 2
src/widgets/mainwindow.h

@@ -3,6 +3,7 @@
 
 #include <QMainWindow>
 #include <QSharedPointer>
+#include <QBitArray>
 
 #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
 

+ 1 - 0
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);