Sfoglia il codice sorgente

add shortcuts for split and workspace

Le Tan 5 anni fa
parent
commit
d40248bb06

+ 6 - 0
src/core/coreconfig.h

@@ -25,6 +25,12 @@ namespace vnotex
             OutlineDock,
             NavigationMode,
             LocateNode,
+            VerticalSplit,
+            HorizontalSplit,
+            MaximizeSplit,
+            DistributeSplits,
+            RemoveSplitAndWorkspace,
+            NewWorkspace,
             MaxShortcut
         };
         Q_ENUM(Shortcut)

+ 7 - 1
src/data/core/vnotex.json

@@ -18,7 +18,13 @@
             "NavigationDock" : "Ctrl+G, 1",
             "OutlineDock" : "Ctrl+G, 2",
             "NavigationMode" : "Ctrl+G, W",
-            "LocateNode" : "Ctrl+G, D"
+            "LocateNode" : "Ctrl+G, D",
+            "VerticalSplit" : "Ctrl+G, \\",
+            "HorizontalSplit" : "Ctrl+G, -",
+            "MaximizeSplit" : "Ctrl+G, Shift+\\",
+            "DistributeSplits" : "Ctrl+G, =",
+            "RemoveSplitAndWorkspace" : "Ctrl+G, R",
+            "NewWorkspace" : "Ctrl+G, N"
         },
         "toolbar_icon_size" : 16
     },

+ 51 - 41
src/widgets/viewarea.cpp

@@ -34,7 +34,7 @@ ViewArea::ViewArea(QWidget *p_parent)
 
     setAcceptDrops(true);
 
-    setupGlobalShortcuts();
+    setupShortcuts();
 
     connect(this, &ViewArea::viewSplitsCountChanged,
             this, &ViewArea::handleViewSplitsCountChange);
@@ -238,7 +238,7 @@ ViewSplit *ViewArea::createViewSplit(QWidget *p_parent)
             });
     connect(split, &ViewSplit::focused,
             this, [this](ViewSplit *p_split) {
-                setCurrentViewSplit(p_split);
+                setCurrentViewSplit(p_split, false);
                 checkCurrentViewWindowChange();
             });
     connect(split, &ViewSplit::currentViewWindowChanged,
@@ -285,10 +285,11 @@ void ViewArea::addFirstViewSplit()
     auto split = createViewSplit(this);
 
     m_splits.push_back(split);
-    setCurrentViewSplit(split);
 
     hideSceneWidget();
-    m_mainLayout->addWidget(m_currentSplit);
+    m_mainLayout->addWidget(split);
+
+    setCurrentViewSplit(split, false);
 
     emit viewSplitsCountChanged();
     checkCurrentViewWindowChange();
@@ -358,12 +359,12 @@ void ViewArea::removeViewSplit(ViewSplit *p_split, bool p_removeWorkspace)
     // Show scene widget and update current split.
     if (m_splits.isEmpty()) {
         Q_ASSERT(newCurrentSplit == nullptr);
-        setCurrentViewSplit(newCurrentSplit);
+        setCurrentViewSplit(newCurrentSplit, false);
         showSceneWidget();
 
         m_fileCheckTimer->stop();
     } else if (m_currentSplit == p_split) {
-        setCurrentViewSplit(newCurrentSplit);
+        setCurrentViewSplit(newCurrentSplit, true);
     }
 
     emit viewSplitsCountChanged();
@@ -385,9 +386,10 @@ void ViewArea::setCurrentViewWindow(ViewWindow *p_win)
     auto split = p_win->getViewSplit();
     Q_ASSERT(split);
 
-    setCurrentViewSplit(split);
-
     split->setCurrentViewWindow(p_win);
+
+    setCurrentViewSplit(split, false);
+
     checkCurrentViewWindowChange();
 }
 
@@ -396,7 +398,7 @@ ViewSplit *ViewArea::getCurrentViewSplit() const
     return m_currentSplit;
 }
 
-void ViewArea::setCurrentViewSplit(ViewSplit *p_split)
+void ViewArea::setCurrentViewSplit(ViewSplit *p_split, bool p_focus)
 {
     Q_ASSERT(!p_split || m_splits.contains(p_split));
     if (p_split == m_currentSplit) {
@@ -410,6 +412,9 @@ void ViewArea::setCurrentViewSplit(ViewSplit *p_split)
     m_currentSplit = p_split;
     if (m_currentSplit) {
         m_currentSplit->setActive(true);
+        if (p_focus) {
+            m_currentSplit->focus();
+        }
     }
 }
 
@@ -506,7 +511,7 @@ void ViewArea::splitViewSplit(ViewSplit *p_split, SplitType p_type)
     }
 
     m_splits.push_back(newSplit);
-    setCurrentViewSplit(newSplit);
+    setCurrentViewSplit(newSplit, true);
 
     // Let Qt decide the size of splitter first.
     QCoreApplication::sendPostedEvents();
@@ -653,19 +658,20 @@ void ViewArea::newWorkspaceInViewSplit(ViewSplit *p_split)
     m_workspaces.push_back(workspace);
 
     p_split->setWorkspace(workspace);
+    setCurrentViewSplit(p_split, true);
 }
 
 bool ViewArea::removeWorkspaceInViewSplit(ViewSplit *p_split, bool p_insertNew)
 {
     // Close all the ViewWindows.
-    setCurrentViewSplit(p_split);
-    bool stopped = !p_split->forEachViewWindow([this](ViewWindow *p_win) {
-                bool ret = closeViewWindow(p_win, false, false);
-                // User cancels closing this ViewWindow, thus cancals closing the ViewSplit.
-                return ret;
+    setCurrentViewSplit(p_split, true);
+    auto wins = getAllViewWindows(p_split, [](ViewWindow *) {
+                return true;
             });
-    if (stopped) {
-        return false;
+    for (const auto win : wins) {
+        if (!closeViewWindow(win, false, false)) {
+            return false;
+        }
     }
 
     Q_ASSERT(p_split->getViewWindowCount() == 0);
@@ -723,7 +729,7 @@ void ViewArea::handleViewSplitsCountChange()
     }
 }
 
-void ViewArea::forEachViewWindow(const std::function<bool(ViewWindow *)> &p_func)
+void ViewArea::forEachViewWindow(const ViewSplit::ViewWindowSelector &p_func)
 {
     for (auto split : m_splits) {
         if (!split->forEachViewWindow(p_func)) {
@@ -750,7 +756,7 @@ bool ViewArea::close(bool p_force)
            });
 }
 
-void ViewArea::setupGlobalShortcuts()
+void ViewArea::setupShortcuts()
 {
     const auto &coreConfig = ConfigMgr::getInst().getCoreConfig();
 
@@ -810,7 +816,7 @@ void ViewArea::checkCurrentViewWindowChange()
     emit currentViewWindowChanged();
 }
 
-bool ViewArea::closeIf(bool p_force, const std::function<bool(ViewWindow *)> &p_func)
+bool ViewArea::closeIf(bool p_force, const ViewSplit::ViewWindowSelector &p_func)
 {
     // Go through all hidden workspace. Use current split to show the workspace.
     if (m_workspaces.size() > m_splits.size()) {
@@ -835,18 +841,14 @@ bool ViewArea::closeIf(bool p_force, const std::function<bool(ViewWindow *)> &p_
             m_currentSplit->setWorkspace(ws);
 
             // Go through this split.
-            bool stopped = !m_currentSplit->forEachViewWindow([this, p_force, p_func](ViewWindow *p_win) {
-                    if (p_func(p_win)) {
-                        // Do not remove the split even if it is empty.
-                        bool ret = closeViewWindow(p_win, p_force, false);
-                        return ret;
-                    }
-                    return true;
-                });
-
-            if (stopped) {
-                // User cancels the close of one ViewWindow. No need to restore the workspace.
-                return false;
+            auto wins = getAllViewWindows(m_currentSplit, p_func);
+            for (const auto win : wins) {
+                // Do not remove the split even if it is empty.
+                bool ret = closeViewWindow(win, p_force, false);
+                if (!ret) {
+                    // User cancels the close of one ViewWindow. No need to restore the workspace.
+                    return false;
+                }
             }
 
             // Remove this workspace.
@@ -869,12 +871,8 @@ bool ViewArea::closeIf(bool p_force, const std::function<bool(ViewWindow *)> &p_
             emptySplits.push_back(split);
             continue;
         }
-        split->forEachViewWindow([p_func, &wins](ViewWindow *p_win) {
-                if (p_func(p_win)) {
-                    wins.push_back(p_win);
-                }
-                return true;
-            });
+
+        wins.append(getAllViewWindows(split, p_func));
     }
 
     if (!emptySplits.isEmpty()) {
@@ -901,9 +899,9 @@ bool ViewArea::closeIf(bool p_force, const std::function<bool(ViewWindow *)> &p_
 
 void ViewArea::focus()
 {
-    auto win = getCurrentViewWindow();
-    if (win) {
-        win->setFocus();
+    auto split = getCurrentViewSplit();
+    if (split) {
+        split->focus();
     }
 }
 
@@ -972,3 +970,15 @@ void ViewArea::dropEvent(QDropEvent *p_event)
 
     QWidget::dropEvent(p_event);
 }
+
+QVector<ViewWindow *> ViewArea::getAllViewWindows(ViewSplit *p_split, const ViewSplit::ViewWindowSelector &p_func)
+{
+    QVector<ViewWindow *> wins;
+    p_split->forEachViewWindow([p_func, &wins](ViewWindow *p_win) {
+            if (p_func(p_win)) {
+                wins.push_back(p_win);
+            }
+            return true;
+        });
+    return wins;
+}

+ 6 - 4
src/widgets/viewarea.h

@@ -157,7 +157,7 @@ namespace vnotex
         void setCurrentViewWindow(ViewWindow *p_win);
 
         ViewSplit *getCurrentViewSplit() const;
-        void setCurrentViewSplit(ViewSplit *p_split);
+        void setCurrentViewSplit(ViewSplit *p_split, bool p_focus);
 
         QSharedPointer<ViewWorkspace> createWorkspace();
 
@@ -182,18 +182,20 @@ namespace vnotex
 
         // Iterate through all ViewWindows including both ViewSplits and Workspaces.
         // Should NOT use this function to close ViewWindow.
-        void forEachViewWindow(const std::function<bool(ViewWindow *)> &p_func);
+        void forEachViewWindow(const ViewSplit::ViewWindowSelector &p_func);
 
-        void setupGlobalShortcuts();
+        void setupShortcuts();
 
         // Close all ViewWindows related to @p_node.
         bool close(Node *p_node, bool p_force);
 
         // Go through all ViewWindows and judge whether to close it by @p_func.
-        bool closeIf(bool p_force, const std::function<bool(ViewWindow *)> &p_func);
+        bool closeIf(bool p_force, const ViewSplit::ViewWindowSelector &p_func);
 
         void checkCurrentViewWindowChange();
 
+        QVector<ViewWindow *> getAllViewWindows(ViewSplit *p_split, const ViewSplit::ViewWindowSelector &p_func);
+
         QLayout *m_mainLayout = nullptr;
 
         QWidget *m_sceneWidget = nullptr;

+ 97 - 5
src/widgets/viewsplit.cpp

@@ -9,6 +9,7 @@
 #include <QTabBar>
 #include <QMimeData>
 #include <QFileInfo>
+#include <QShortcut>
 
 #include "viewwindow.h"
 #include "viewarea.h"
@@ -49,6 +50,8 @@ ViewSplit::ViewSplit(const QVector<QSharedPointer<ViewWorkspace>> &p_allWorkspac
 
     setupUI();
 
+    setupShortcuts();
+
     setWorkspace(p_workspace);
 }
 
@@ -95,6 +98,8 @@ void ViewSplit::focusCurrentViewWindow()
     auto win = getCurrentViewWindow();
     if (win) {
         win->setFocus();
+    } else {
+        setFocus();
     }
 }
 
@@ -409,6 +414,8 @@ void ViewSplit::updateWindowList(QMenu *p_menu)
 
 void ViewSplit::updateMenu(QMenu *p_menu)
 {
+    const auto &coreConfig = ConfigMgr::getInst().getCoreConfig();
+
     p_menu->clear();
 
     const auto &themeMgr = VNoteX::getInst().getThemeMgr();
@@ -445,10 +452,14 @@ void ViewSplit::updateMenu(QMenu *p_menu)
         }
 
         p_menu->addSeparator();
-        p_menu->addAction(tr("New Workspace"),
-                          [this]() {
-                              emit newWorkspaceRequested(this);
-                          });
+
+        {
+            auto act = p_menu->addAction(tr("New Workspace"),
+                                         [this]() {
+                                             emit newWorkspaceRequested(this);
+                                         });
+            WidgetUtils::addActionShortcutText(act, coreConfig.getShortcut(CoreConfig::NewWorkspace));
+        }
 
         p_menu->addAction(tr("Remove Workspace"),
                           [this]() {
@@ -465,6 +476,7 @@ void ViewSplit::updateMenu(QMenu *p_menu)
                                      [this]() {
                                          emit verticalSplitRequested(this);
                                      });
+        WidgetUtils::addActionShortcutText(act, coreConfig.getShortcut(CoreConfig::VerticalSplit));
 
         icon = themeMgr.getIconFile(QStringLiteral("horizontal_split.svg"));
         act = p_menu->addAction(IconUtils::fetchIconWithDisabledState(icon),
@@ -472,16 +484,19 @@ void ViewSplit::updateMenu(QMenu *p_menu)
                                 [this]() {
                                     emit horizontalSplitRequested(this);
                                 });
+        WidgetUtils::addActionShortcutText(act, coreConfig.getShortcut(CoreConfig::HorizontalSplit));
 
         act = p_menu->addAction(tr("Maximize Split"),
                                 [this]() {
                                     emit maximizeSplitRequested(this);
                                 });
+        WidgetUtils::addActionShortcutText(act, coreConfig.getShortcut(CoreConfig::MaximizeSplit));
 
         act = p_menu->addAction(tr("Distribute Splits"),
                                 [this]() {
                                     emit distributeSplitsRequested();
                                 });
+        WidgetUtils::addActionShortcutText(act, coreConfig.getShortcut(CoreConfig::DistributeSplits));
 
         act = p_menu->addAction(tr("Remove Split"),
                                 [this]() {
@@ -492,6 +507,7 @@ void ViewSplit::updateMenu(QMenu *p_menu)
                                 [this]() {
                                     emit removeSplitAndWorkspaceRequested(this);
                                 });
+        WidgetUtils::addActionShortcutText(act, coreConfig.getShortcut(CoreConfig::RemoveSplitAndWorkspace));
     }
 }
 
@@ -588,7 +604,7 @@ void ViewSplit::mousePressEvent(QMouseEvent *p_event)
     emit focused(this);
 }
 
-bool ViewSplit::forEachViewWindow(const std::function<bool(ViewWindow *)> &p_func)
+bool ViewSplit::forEachViewWindow(const ViewWindowSelector &p_func)
 {
     int cnt = getViewWindowCount();
     for (int i = 0; i < cnt; ++i) {
@@ -640,3 +656,79 @@ void ViewSplit::dropEvent(QDropEvent *p_event)
 
     QTabWidget::dropEvent(p_event);
 }
+
+void ViewSplit::setupShortcuts()
+{
+    const auto &coreConfig = ConfigMgr::getInst().getCoreConfig();
+
+    // NewWorkspace.
+    {
+        auto shortcut = WidgetUtils::createShortcut(coreConfig.getShortcut(CoreConfig::NewWorkspace), this, Qt::WidgetWithChildrenShortcut);
+        if (shortcut) {
+            connect(shortcut, &QShortcut::activated,
+                    this, [this]() {
+                        emit newWorkspaceRequested(this);
+                    });
+        }
+    }
+
+    // VerticalSplit.
+    {
+        auto shortcut = WidgetUtils::createShortcut(coreConfig.getShortcut(CoreConfig::VerticalSplit), this, Qt::WidgetWithChildrenShortcut);
+        if (shortcut) {
+            connect(shortcut, &QShortcut::activated,
+                    this, [this]() {
+                        emit verticalSplitRequested(this);
+                    });
+        }
+    }
+
+    // HorizontalSplit.
+    {
+        auto shortcut = WidgetUtils::createShortcut(coreConfig.getShortcut(CoreConfig::HorizontalSplit), this, Qt::WidgetWithChildrenShortcut);
+        if (shortcut) {
+            connect(shortcut, &QShortcut::activated,
+                    this, [this]() {
+                        emit horizontalSplitRequested(this);
+                    });
+        }
+    }
+
+    // MaximizeSplit.
+    {
+        auto shortcut = WidgetUtils::createShortcut(coreConfig.getShortcut(CoreConfig::MaximizeSplit), this, Qt::WidgetWithChildrenShortcut);
+        if (shortcut) {
+            connect(shortcut, &QShortcut::activated,
+                    this, [this]() {
+                        emit maximizeSplitRequested(this);
+                    });
+        }
+    }
+
+    // DistributeSplits.
+    {
+        auto shortcut = WidgetUtils::createShortcut(coreConfig.getShortcut(CoreConfig::DistributeSplits), this, Qt::WidgetWithChildrenShortcut);
+        if (shortcut) {
+            connect(shortcut, &QShortcut::activated,
+                    this, [this]() {
+                        emit distributeSplitsRequested();
+                    });
+        }
+    }
+
+    // RemoveSplitAndWorkspace.
+    {
+        auto shortcut = WidgetUtils::createShortcut(coreConfig.getShortcut(CoreConfig::RemoveSplitAndWorkspace), this, Qt::WidgetWithChildrenShortcut);
+        if (shortcut) {
+            connect(shortcut, &QShortcut::activated,
+                    this, [this]() {
+                        emit removeSplitAndWorkspaceRequested(this);
+                    });
+        }
+    }
+}
+
+void ViewSplit::focus()
+{
+    focusCurrentViewWindow();
+}

+ 7 - 1
src/widgets/viewsplit.h

@@ -20,6 +20,8 @@ namespace vnotex
     {
         Q_OBJECT
     public:
+        typedef std::function<bool(ViewWindow *)> ViewWindowSelector;
+
         struct ViewWindowNavigationModeInfo
         {
             // Top left position of the ViewWindow relative to the view split.
@@ -54,10 +56,12 @@ namespace vnotex
 
         // @p_func: return true if going well, return false to stop the iteration.
         // Return false if there is a break.
-        bool forEachViewWindow(const std::function<bool(ViewWindow *)> &p_func);
+        bool forEachViewWindow(const ViewWindowSelector &p_func);
 
         QVector<ViewWindowNavigationModeInfo> getNavigationModeInfo() const;
 
+        void focus();
+
     signals:
         void viewWindowCloseRequested(ViewWindow *p_win);
 
@@ -102,6 +106,8 @@ namespace vnotex
 
         void setupTabBar();
 
+        void setupShortcuts();
+
         ViewWindow *getViewWindow(int p_idx) const;
 
         void updateAndTakeCurrentWorkspace();