Просмотр исходного кода

TagIndicator/TagExplorer: support Navigation mode

Le Tan 7 лет назад
Родитель
Сommit
927bb54502

+ 17 - 0
src/valltagspanel.cpp

@@ -3,6 +3,7 @@
 #include <QtWidgets>
 
 #include "vtaglabel.h"
+#include "utils/vimnavigationforwidget.h"
 
 VAllTagsPanel::VAllTagsPanel(QWidget *p_parent)
     : QWidget(p_parent)
@@ -53,3 +54,19 @@ VTagLabel *VAllTagsPanel::addTag(const QString &p_text)
     m_list->setItemWidget(item, label);
     return label;
 }
+
+void VAllTagsPanel::showEvent(QShowEvent *p_event)
+{
+    QWidget::showEvent(p_event);
+
+    m_list->setFocus();
+}
+
+void VAllTagsPanel::keyPressEvent(QKeyEvent *p_event)
+{
+    if (VimNavigationForWidget::injectKeyPressEventForVim(m_list, p_event)) {
+        return;
+    }
+
+    QWidget::keyPressEvent(p_event);
+}

+ 5 - 0
src/valltagspanel.h

@@ -20,6 +20,11 @@ public:
 signals:
     void tagRemoved(const QString &p_text);
 
+protected:
+    void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
+
+    void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
+
 private:
     void removeItem(QListWidgetItem *p_item);
 

+ 1 - 0
src/veditwindow.h

@@ -77,6 +77,7 @@ public:
     void clearSearchedWordHighlight();
     void moveCurrentTabOneSplit(bool p_right);
     void focusNextTab(bool p_right);
+
     // Return true if the file list is shown.
     bool showOpenedFileList();
 

+ 16 - 0
src/vmainwindow.cpp

@@ -152,7 +152,13 @@ void VMainWindow::registerCaptainAndNavigationTargets()
     m_captain->registerNavigationTarget(m_dirTree);
     m_captain->registerNavigationTarget(m_fileList);
     m_captain->registerNavigationTarget(m_historyList);
+
+    m_tagExplorer->registerNavigationTarget();
+
     m_captain->registerNavigationTarget(m_editArea);
+
+    m_tabIndicator->registerNavigationTarget();
+
     m_captain->registerNavigationTarget(m_toolBox);
     m_captain->registerNavigationTarget(outline);
     m_captain->registerNavigationTarget(m_snippetList);
@@ -3291,3 +3297,13 @@ void VMainWindow::stayOnTop(bool p_enabled)
         show();
     }
 }
+
+void VMainWindow::focusEditArea() const
+{
+    QWidget *widget = m_editArea->getCurrentTab();
+    if (!widget) {
+        widget = m_editArea;
+    }
+
+    widget->setFocus();
+}

+ 2 - 0
src/vmainwindow.h

@@ -122,6 +122,8 @@ public:
     // Kick off timer to do things after start.
     void kickOffStartUpTimer(const QStringList &p_files);
 
+    void focusEditArea() const;
+
 signals:
     // Emit when editor related configurations were changed by user.
     void editorConfigUpdated();

+ 30 - 1
src/vnavigationmode.h

@@ -12,7 +12,6 @@ class QListWidgetItem;
 class QTreeWidget;
 class QTreeWidgetItem;
 
-
 // Interface class for Navigation Mode in Captain Mode.
 class VNavigationMode
 {
@@ -61,4 +60,34 @@ private:
     QList<QTreeWidgetItem *> getVisibleItems(const QTreeWidget *p_widget) const;
 };
 
+
+class VNavigationModeListWidgetWrapper : public QObject, public VNavigationMode
+{
+    Q_OBJECT
+public:
+    explicit VNavigationModeListWidgetWrapper(QListWidget *p_widget, QObject *p_parent = nullptr)
+        : QObject(p_parent),
+          m_widget(p_widget)
+    {
+    }
+
+    // Implementations for VNavigationMode.
+    void showNavigation() Q_DECL_OVERRIDE
+    {
+        VNavigationMode::showNavigation(m_widget);
+    }
+
+    bool handleKeyNavigation(int p_key, bool &p_succeed)
+    {
+        static bool secondKey = false;
+
+        return VNavigationMode::handleKeyNavigation(m_widget,
+                                                    secondKey,
+                                                    p_key,
+                                                    p_succeed);
+    }
+
+private:
+    QListWidget *m_widget;
+};
 #endif // VNAVIGATIONMODE_H

+ 27 - 15
src/vnote.cpp

@@ -209,11 +209,12 @@ QVector<VNotebook *> &VNote::getNotebooks()
     return m_notebooks;
 }
 
-QString VNote::getNavigationLabelStyle(const QString &p_str) const
+QString VNote::getNavigationLabelStyle(const QString &p_str, bool p_small) const
 {
     static int lastLen = -1;
     static int pxWidth = 24;
-    const int fontPt = 15;
+    static int pxHeight = 24;
+    const int fontPt = p_small ? 12 : 15;
 
     QString fontFamily = getMonospacedFont();
 
@@ -222,25 +223,36 @@ QString VNote::getNavigationLabelStyle(const QString &p_str) const
         font.setBold(true);
         QFontMetrics fm(font);
         pxWidth = fm.width(p_str);
+        pxHeight = fm.capHeight() + 5;
         lastLen = p_str.size();
     }
 
     QColor bg(g_palette->color("navigation_label_bg"));
     bg.setAlpha(200);
 
-    return QString("background-color: %1;"
-                   "color: %2;"
-                   "font-size: %3pt;"
-                   "font: bold;"
-                   "font-family: %4;"
-                   "border-radius: 3px;"
-                   "min-width: %5px;"
-                   "max-width: %5px;")
-                   .arg(bg.name(QColor::HexArgb))
-                   .arg(g_palette->color("navigation_label_fg"))
-                   .arg(fontPt)
-                   .arg(fontFamily)
-                   .arg(pxWidth);
+    QString style = QString("background-color: %1;"
+                            "color: %2;"
+                            "font-size: %3pt;"
+                            "font: bold;"
+                            "font-family: %4;"
+                            "border-radius: 3px;"
+                            "min-width: %5px;"
+                            "max-width: %5px;")
+                           .arg(bg.name(QColor::HexArgb))
+                           .arg(g_palette->color("navigation_label_fg"))
+                           .arg(fontPt)
+                           .arg(fontFamily)
+                           .arg(pxWidth);
+
+    if (p_small) {
+        style += QString("margin: 0px;"
+                         "padding: 0px;"
+                         "min-height: %1px;"
+                         "max-height: %1px;")
+                        .arg(pxHeight);
+    }
+
+    return style;
 }
 
 const QString &VNote::getMonospacedFont() const

+ 1 - 1
src/vnote.h

@@ -81,7 +81,7 @@ public:
     static const QString c_markdownGuideDocFile;
 
     // Get the label style in Navigation mode.
-    QString getNavigationLabelStyle(const QString &p_str) const;
+    QString getNavigationLabelStyle(const QString &p_str, bool p_small = false) const;
 
     // Given the path of a file, first try to open it as note file,
     // then try to open it as orphan file.

+ 1 - 0
src/vnotebookselector.cpp

@@ -575,6 +575,7 @@ void VNotebookSelector::showNavigation()
     m_naviLabel = new QLabel(m_majorKey, this);
     m_naviLabel->setStyleSheet(g_vnote->getNavigationLabelStyle(m_majorKey));
     m_naviLabel->show();
+    m_naviLabel->move(rect().topRight() - QPoint(m_naviLabel->width() + 2, 2));
 }
 
 void VNotebookSelector::hideNavigation()

+ 9 - 0
src/vtabindicator.cpp

@@ -9,6 +9,10 @@
 #include "utils/vutils.h"
 #include "vtagpanel.h"
 #include "vnotefile.h"
+#include "vmainwindow.h"
+#include "vcaptain.h"
+
+extern VMainWindow *g_mainWin;
 
 VWordCountPanel::VWordCountPanel(QWidget *p_parent)
     : QWidget(p_parent)
@@ -99,6 +103,11 @@ VTabIndicator::VTabIndicator(QWidget *p_parent)
     setupUI();
 }
 
+void VTabIndicator::registerNavigationTarget()
+{
+    g_mainWin->getCaptain()->registerNavigationTarget(m_tagPanel);
+}
+
 void VTabIndicator::setupUI()
 {
     m_tagPanel = new VTagPanel(this);

+ 2 - 0
src/vtabindicator.h

@@ -47,6 +47,8 @@ public:
     // Update indicator.
     void update(const VEditTabInfo &p_info);
 
+    void registerNavigationTarget();
+
 private slots:
     void updateWordCountInfo(QWidget *p_widget);
 

+ 13 - 0
src/vtagexplorer.cpp

@@ -13,6 +13,8 @@
 #include "vhistorylist.h"
 #include "vnotefile.h"
 #include "utils/vutils.h"
+#include "vnavigationmode.h"
+#include "vcaptain.h"
 
 extern VMainWindow *g_mainWin;
 
@@ -496,3 +498,14 @@ void VTagExplorer::promptToRemoveEmptyTag(const QString &p_tag)
     m_notebook->removeTag(p_tag);
     updateContent();
 }
+
+void VTagExplorer::registerNavigationTarget()
+{
+    setupUI();
+
+    VNavigationModeListWidgetWrapper *tagWrapper = new VNavigationModeListWidgetWrapper(m_tagList, this);
+    g_mainWin->getCaptain()->registerNavigationTarget(tagWrapper);
+
+    VNavigationModeListWidgetWrapper *fileWrapper = new VNavigationModeListWidgetWrapper(m_fileList, this);
+    g_mainWin->getCaptain()->registerNavigationTarget(fileWrapper);
+}

+ 2 - 0
src/vtagexplorer.h

@@ -25,6 +25,8 @@ public:
 
     void saveStateAndGeometry();
 
+    void registerNavigationTarget();
+
 protected:
     void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
 

+ 79 - 0
src/vtagpanel.cpp

@@ -9,11 +9,14 @@
 #include "vtaglabel.h"
 #include "vlineedit.h"
 #include "vmainwindow.h"
+#include "vnote.h"
 
 extern VPalette *g_palette;
 
 extern VMainWindow *g_mainWin;
 
+extern VNote *g_vnote;
+
 #define MAX_DISPLAY_LABEL 3
 
 VTagPanel::VTagPanel(QWidget *parent)
@@ -210,3 +213,79 @@ void VTagPanel::updateCompleter()
     m_tagsModel->setStringList(m_notebookOfCompleter ? m_notebookOfCompleter->getTags()
                                                      : QStringList());
 }
+
+void VTagPanel::showNavigation()
+{
+    if (!isVisible() || !m_file) {
+        return;
+    }
+
+    // View all tags.
+    if (isAllTagsPanelAvailable()) {
+        QChar key('a');
+        m_keyMap[key] = m_btn;
+
+        QString str = QString(m_majorKey) + key;
+        QLabel *label = new QLabel(str, this);
+        qDebug() << g_vnote->getNavigationLabelStyle(str, true);
+        label->setStyleSheet(g_vnote->getNavigationLabelStyle(str, true));
+        label->move(m_btn->geometry().topLeft());
+        label->show();
+        m_naviLabels.append(label);
+    }
+
+    // Add tag edit.
+    {
+        QChar key('b');
+        m_keyMap[key] = m_tagEdit;
+
+        QString str = QString(m_majorKey) + key;
+        QLabel *label = new QLabel(str, this);
+        label->setStyleSheet(g_vnote->getNavigationLabelStyle(str, true));
+        label->move(m_tagEdit->geometry().topLeft());
+        label->show();
+        m_naviLabels.append(label);
+    }
+}
+
+bool VTagPanel::handleKeyNavigation(int p_key, bool &p_succeed)
+{
+    static bool secondKey = false;
+    bool ret = false;
+    p_succeed = false;
+    QChar keyChar = VUtils::keyToChar(p_key);
+    if (secondKey && !keyChar.isNull()) {
+        secondKey = false;
+        p_succeed = true;
+        auto it = m_keyMap.find(keyChar);
+        if (it != m_keyMap.end()) {
+            ret = true;
+
+            if (*it == m_btn) {
+                // Show all tags panel.
+                // To avoid focus in VCaptain after hiding the menu.
+                g_mainWin->focusEditArea();
+                m_btn->showPopupWidget();
+            } else {
+                m_tagEdit->setFocus();
+            }
+        }
+    } else if (keyChar == m_majorKey) {
+        // Major key pressed.
+        // Need second key if m_keyMap is not empty.
+        if (m_keyMap.isEmpty()) {
+            p_succeed = true;
+        } else {
+            secondKey = true;
+        }
+
+        ret = true;
+    }
+
+    return ret;
+}
+
+bool VTagPanel::isAllTagsPanelAvailable() const
+{
+    return m_btn->isVisible();
+}

+ 9 - 2
src/vtagpanel.h

@@ -2,6 +2,8 @@
 #define VTAGPANEL_H
 
 #include <QWidget>
+#include "vnavigationmode.h"
+
 #include <QVector>
 
 class VTagLabel;
@@ -12,7 +14,7 @@ class VLineEdit;
 class QStringListModel;
 class VNotebook;
 
-class VTagPanel : public QWidget
+class VTagPanel : public QWidget, public VNavigationMode
 {
     Q_OBJECT
 public:
@@ -20,6 +22,10 @@ public:
 
     void updateTags(VNoteFile *p_file);
 
+    // Implementations for VNavigationMode.
+    void showNavigation() Q_DECL_OVERRIDE;
+    bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
+
 protected:
     bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE;
 
@@ -41,6 +47,8 @@ private:
 
     void updateCompleter();
 
+    bool isAllTagsPanelAvailable() const;
+
     QVector<VTagLabel *> m_labels;
 
     VButtonWithWidget *m_btn;
@@ -56,5 +64,4 @@ private:
 
     const VNotebook *m_notebookOfCompleter;
 };
-
 #endif // VTAGPANEL_H