From 927bb54502debaee0b9f35925f073ed80c845d05 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Tue, 3 Jul 2018 19:38:36 +0800 Subject: [PATCH] TagIndicator/TagExplorer: support Navigation mode --- src/valltagspanel.cpp | 17 +++++++++ src/valltagspanel.h | 5 +++ src/veditwindow.h | 1 + src/vmainwindow.cpp | 16 ++++++++ src/vmainwindow.h | 2 + src/vnavigationmode.h | 31 ++++++++++++++- src/vnote.cpp | 42 +++++++++++++-------- src/vnote.h | 2 +- src/vnotebookselector.cpp | 1 + src/vtabindicator.cpp | 9 +++++ src/vtabindicator.h | 2 + src/vtagexplorer.cpp | 13 +++++++ src/vtagexplorer.h | 2 + src/vtagpanel.cpp | 79 +++++++++++++++++++++++++++++++++++++++ src/vtagpanel.h | 11 +++++- 15 files changed, 214 insertions(+), 19 deletions(-) diff --git a/src/valltagspanel.cpp b/src/valltagspanel.cpp index b7ac2bed..5cb9da3b 100644 --- a/src/valltagspanel.cpp +++ b/src/valltagspanel.cpp @@ -3,6 +3,7 @@ #include #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); +} diff --git a/src/valltagspanel.h b/src/valltagspanel.h index c110bac4..31558461 100644 --- a/src/valltagspanel.h +++ b/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); diff --git a/src/veditwindow.h b/src/veditwindow.h index 14f3062a..7f582781 100644 --- a/src/veditwindow.h +++ b/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(); diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 58a72b67..b90ec8a3 100644 --- a/src/vmainwindow.cpp +++ b/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(); +} diff --git a/src/vmainwindow.h b/src/vmainwindow.h index 2cfdea1a..3ed7b70e 100644 --- a/src/vmainwindow.h +++ b/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(); diff --git a/src/vnavigationmode.h b/src/vnavigationmode.h index a1a45376..ac4d888a 100644 --- a/src/vnavigationmode.h +++ b/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 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 diff --git a/src/vnote.cpp b/src/vnote.cpp index 66635597..f2dacb5d 100644 --- a/src/vnote.cpp +++ b/src/vnote.cpp @@ -209,11 +209,12 @@ QVector &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 diff --git a/src/vnote.h b/src/vnote.h index 3f69ec22..43cc1f0b 100644 --- a/src/vnote.h +++ b/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. diff --git a/src/vnotebookselector.cpp b/src/vnotebookselector.cpp index 2732690c..7bc780ce 100644 --- a/src/vnotebookselector.cpp +++ b/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() diff --git a/src/vtabindicator.cpp b/src/vtabindicator.cpp index f7cb6987..e62ee11d 100644 --- a/src/vtabindicator.cpp +++ b/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); diff --git a/src/vtabindicator.h b/src/vtabindicator.h index d55d74e6..1c8ac381 100644 --- a/src/vtabindicator.h +++ b/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); diff --git a/src/vtagexplorer.cpp b/src/vtagexplorer.cpp index 9f5af82c..cb038ead 100644 --- a/src/vtagexplorer.cpp +++ b/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); +} diff --git a/src/vtagexplorer.h b/src/vtagexplorer.h index e2e5e03a..01d6e6d9 100644 --- a/src/vtagexplorer.h +++ b/src/vtagexplorer.h @@ -25,6 +25,8 @@ public: void saveStateAndGeometry(); + void registerNavigationTarget(); + protected: void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; diff --git a/src/vtagpanel.cpp b/src/vtagpanel.cpp index 32f12acf..130f9cda 100644 --- a/src/vtagpanel.cpp +++ b/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(); +} diff --git a/src/vtagpanel.h b/src/vtagpanel.h index cd99a941..12d530b8 100644 --- a/src/vtagpanel.h +++ b/src/vtagpanel.h @@ -2,6 +2,8 @@ #define VTAGPANEL_H #include +#include "vnavigationmode.h" + #include 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 m_labels; VButtonWithWidget *m_btn; @@ -56,5 +64,4 @@ private: const VNotebook *m_notebookOfCompleter; }; - #endif // VTAGPANEL_H