Pārlūkot izejas kodu

SelectDialog: support shortcuts

Le Tan 4 gadi atpakaļ
vecāks
revīzija
87932751b4

+ 63 - 12
src/widgets/dialogs/selectdialog.cpp

@@ -3,12 +3,22 @@
 #include <QtWidgets>
 
 #include <utils/widgetutils.h>
+#include <utils/iconutils.h>
+#include <utils/utils.h>
+#include <core/thememgr.h>
+#include <core/vnotex.h>
 
 using namespace vnotex;
 
+const QChar SelectDialog::c_cancelShortcut = QLatin1Char('z');
+
 SelectDialog::SelectDialog(const QString &p_title, QWidget *p_parent)
     : QDialog(p_parent)
 {
+    const auto &themeMgr = VNoteX::getInst().getThemeMgr();
+    m_shortcutIconForeground = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#fg"));
+    m_shortcutIconBorder = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#border"));
+
     setupUI(p_title);
 }
 
@@ -24,12 +34,19 @@ void SelectDialog::setupUI(const QString &p_title)
     connect(m_list, &QListWidget::itemActivated,
             this, &SelectDialog::selectionChosen);
 
+    m_list->installEventFilter(this);
+
     // Add cancel item.
-    QListWidgetItem *cancelItem = new QListWidgetItem(tr("Cancel"));
-    cancelItem->setData(Qt::UserRole, CANCEL_ID);
+    {
+        const auto icon = IconUtils::drawTextIcon(c_cancelShortcut, m_shortcutIconForeground, m_shortcutIconBorder);
+        QListWidgetItem *cancelItem = new QListWidgetItem(icon, tr("Cancel"));
+        cancelItem->setData(Qt::UserRole, CANCEL_ID);
 
-    m_list->addItem(cancelItem);
-    m_list->setCurrentRow(0);
+        m_shortcuts.insert(c_cancelShortcut, cancelItem);
+
+        m_list->addItem(cancelItem);
+        m_list->setCurrentRow(0);
+    }
 
     mainLayout->addWidget(m_list);
 
@@ -40,8 +57,19 @@ void SelectDialog::addSelection(const QString &p_selectStr, int p_selectID)
 {
     Q_ASSERT(p_selectID >= 0);
 
-    QListWidgetItem *item = new QListWidgetItem(p_selectStr);
+    QChar shortcut;
+    if (m_nextShortcut < c_cancelShortcut) {
+        shortcut = m_nextShortcut;
+        m_nextShortcut = m_nextShortcut.toLatin1() + 1;
+    }
+    const auto icon = IconUtils::drawTextIcon(shortcut, m_shortcutIconForeground, m_shortcutIconBorder);
+    QListWidgetItem *item = new QListWidgetItem(icon, p_selectStr);
     item->setData(Qt::UserRole, p_selectID);
+
+    if (!shortcut.isNull()) {
+        m_shortcuts.insert(shortcut, item);
+    }
+
     m_list->insertItem(m_list->count() - 1, item);
 
     m_list->setCurrentRow(0);
@@ -92,16 +120,39 @@ void SelectDialog::keyPressEvent(QKeyEvent *p_event)
 
     // On Mac OS X, it is `Command+O` to activate an item, instead of Return.
 #if defined(Q_OS_MACOS) || defined(Q_OS_MAC)
-    int key = p_event->key();
-    if (key == Qt::Key_Return || key == Qt::Key_Enter) {
-        p_event->accept();
-        if (auto item = m_list->currentItem()) {
-            selectionChosen(item);
+    {
+        const int key = p_event->key();
+        if (key == Qt::Key_Return || key == Qt::Key_Enter) {
+            p_event->accept();
+            if (auto item = m_list->currentItem()) {
+                selectionChosen(item);
+            }
+
+            return;
         }
-
-        return;
     }
 #endif
 
     QDialog::keyPressEvent(p_event);
 }
+
+bool SelectDialog::eventFilter(QObject *p_watched, QEvent *p_event)
+{
+    if (p_watched == m_list && p_event->type() == QEvent::KeyPress) {
+        auto keyEve = static_cast<QKeyEvent *>(p_event);
+        // Handle shortcuts.
+        if (keyEve->modifiers() == Qt::NoModifier) {
+            auto keych = Utils::keyToChar(keyEve->key(), true);
+            if (keych.isLetter()) {
+                auto it = m_shortcuts.find(keych);
+                if (it != m_shortcuts.end()) {
+                    selectionChosen(it.value());
+                }
+
+                return true;
+            }
+        }
+    }
+
+    return QDialog::eventFilter(p_watched, p_event);
+}

+ 12 - 0
src/widgets/dialogs/selectdialog.h

@@ -24,6 +24,8 @@ namespace vnotex
 
         int getSelection() const;
 
+        bool eventFilter(QObject *p_watched, QEvent *p_event) Q_DECL_OVERRIDE;
+
     protected:
         void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;
 
@@ -42,6 +44,16 @@ namespace vnotex
         int m_choice = CANCEL_ID;
 
         QListWidget *m_list = nullptr;
+
+        QMap<QChar, QListWidgetItem *> m_shortcuts;
+
+        QString m_shortcutIconForeground;
+
+        QString m_shortcutIconBorder;
+
+        QChar m_nextShortcut = QLatin1Char('a');
+
+        static const QChar c_cancelShortcut;
     };
 } // ns vnotex
 

+ 5 - 6
src/widgets/quickselector.cpp

@@ -98,16 +98,15 @@ void QuickSelector::updateItemList()
 
     const auto &themeMgr = VNoteX::getInst().getThemeMgr();
 
+    const auto fg = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#fg"));
+    const auto border = themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#border"));
+
     for (int i = 0; i < m_items.size(); ++i) {
         const auto &item = m_items[i];
 
-        auto listItem = new QListWidgetItem(m_itemList);
-        auto icon = IconUtils::drawTextIcon(item.m_shortcut,
-                                            themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#fg")),
-                                            themeMgr.paletteColor(QStringLiteral("widgets#quickselector#item_icon#border")));
-        listItem->setIcon(icon);
+        const auto icon = IconUtils::drawTextIcon(item.m_shortcut, fg, border);
+        auto listItem = new QListWidgetItem(icon, item.m_name, m_itemList);
 
-        listItem->setText(item.m_name);
         listItem->setToolTip(item.m_tip);
         listItem->setData(Qt::UserRole, i);
     }

+ 1 - 1
src/widgets/viewsplit.cpp

@@ -187,7 +187,7 @@ bool ViewSplit::eventFilter(QObject *p_object, QEvent *p_event)
         }
     }
 
-    return false;
+    return QTabWidget::eventFilter(p_object, p_event);
 }
 
 void ViewSplit::setupTabBar()