From e706c114a5aac79976c7e9c617d948cf0f5d8772 Mon Sep 17 00:00:00 2001
From: Chris Xiong <chirs241097@gmail.com>
Date: Mon, 12 Sep 2022 00:35:12 -0400
Subject: Implement hotkeys with QActions.

---
 mingui/mingui.cpp | 91 ++++++++++++++++++++++++++++++++-----------------------
 mingui/mingui.hpp |  4 +--
 2 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/mingui/mingui.cpp b/mingui/mingui.cpp
index 94f7e81..3e8082a 100644
--- a/mingui/mingui.cpp
+++ b/mingui/mingui.cpp
@@ -6,7 +6,9 @@
 #include <type_traits>
 
 #include <QDebug>
-#include <QKeyEvent>
+#include <QCloseEvent>
+#include <QMouseEvent>
+#include <QAction>
 #include <QString>
 #include <QScrollArea>
 #include <QListView>
@@ -69,6 +71,56 @@ MinGuiWidget::MinGuiWidget()
     lw->setItemDelegate(id);
     lw->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection);
     lw->setResizeMode(QListView::ResizeMode::Adjust);
+
+    for (size_t i = 0; i < keys.size(); ++i)
+    {
+        auto &k = keys[i];
+        QAction *a = new QAction();
+        a->setShortcut(QKeySequence(k));
+        QObject::connect(a, &QAction::triggered, [this, i](){this->mark_toggle(i);});
+        selhk.push_back(a);
+        QAction *sa = new QAction();
+        sa->setShortcut(QKeySequence(Qt::Modifier::SHIFT | k));
+        QObject::connect(sa, &QAction::triggered, [this, i](){this->mark_all_but(i);});
+        selhk.push_back(a);
+    }
+    this->addActions(selhk);
+    QAction *mall = new QAction();
+    mall->setShortcut(QKeySequence(Qt::Key::Key_X));
+    QObject::connect(mall, &QAction::triggered, [this]{this->mark_all();});
+    this->addAction(mall);
+    QAction *mnone = new QAction();
+    mnone->setShortcut(QKeySequence(Qt::Key::Key_C));
+    QObject::connect(mnone, &QAction::triggered, [this]{this->mark_none();});
+    this->addAction(mnone);
+    QAction *nxt = new QAction();
+    nxt->setShortcut(QKeySequence(Qt::Key::Key_M));
+    QObject::connect(nxt, &QAction::triggered, [this]{Q_EMIT this->next();});
+    this->addAction(nxt);
+    QAction *prv = new QAction();
+    prv->setShortcut(QKeySequence(Qt::Key::Key_Z));
+    QObject::connect(prv, &QAction::triggered, [this]{Q_EMIT this->prev();});
+    this->addAction(prv);
+    QAction *load = new QAction();
+    load->setShortcut(QKeySequence(Qt::Key::Key_N));
+    QObject::connect(load, &QAction::triggered, [this]{Q_EMIT this->load_list();});
+    this->addAction(load);
+    QAction *skip = new QAction();
+    skip->setShortcut(QKeySequence(Qt::Key::Key_B));
+    QObject::connect(skip, &QAction::triggered, [this]{
+        bool ok = false;
+        int g = QInputDialog::getInt(this, "Skip to group",
+                                     QString("Group # (1-%1)").arg(ngroups),
+                                     curgroup + 1,
+                                     1, ngroups, 1, &ok);
+        if (ok) Q_EMIT switch_group((size_t) g - 1);
+    });
+    this->addAction(skip);
+    QAction *save = new QAction();
+    save->setShortcut(QKeySequence(Qt::Modifier::SHIFT | Qt::Key::Key_Return));
+    QObject::connect(load, &QAction::triggered, [this]{Q_EMIT this->save_list();});
+    this->addAction(save);
+
     QObject::connect(lw, &QListView::clicked, [this](const QModelIndex &i) {
         auto cs = i.data(Qt::ItemDataRole::CheckStateRole).value<Qt::CheckState>();
         if (cs == Qt::CheckState::Checked)
@@ -303,43 +355,6 @@ fs::path::string_type MinGuiWidget::common_prefix(const std::vector<fs::path> &f
     return ret;
 }
 
-void MinGuiWidget::keyPressEvent(QKeyEvent *e)
-{
-    for (auto &k : keys)
-    if (e->key() == k)
-    {
-        if (e->modifiers() & Qt::KeyboardModifier::ShiftModifier)
-            this->mark_all_but(&k - &keys[0]);
-        else this->mark_toggle(&k - &keys[0]);
-    }
-    switch (e->key())
-    {
-        case Qt::Key::Key_X: this->mark_all(); break;
-        case Qt::Key::Key_C: this->mark_none(); break;
-    }
-}
-
-void MinGuiWidget::keyReleaseEvent(QKeyEvent *e)
-{
-    switch (e->key())
-    {
-        case Qt::Key::Key_M: Q_EMIT next(); break;
-        case Qt::Key::Key_Z: Q_EMIT prev(); break;
-        case Qt::Key::Key_N: load_list(); break;
-        case Qt::Key::Key_B:
-        {
-            bool ok = false;
-            int g = QInputDialog::getInt(this, "Skip to group",
-                                         QString("Group # (1-%1)").arg(ngroups),
-                                         curgroup + 1,
-                                         1, ngroups, 1, &ok);
-            if (ok) Q_EMIT switch_group((size_t) g - 1);
-        }
-        break;
-        case Qt::Key::Key_Return: if (e->modifiers() & Qt::KeyboardModifier::ShiftModifier) save_list(); break;
-    }
-}
-
 void MinGuiWidget::resizeEvent(QResizeEvent *e)
 {
     QWidget::resizeEvent(e);
diff --git a/mingui/mingui.hpp b/mingui/mingui.hpp
index aa71596..4efb534 100644
--- a/mingui/mingui.hpp
+++ b/mingui/mingui.hpp
@@ -7,6 +7,7 @@
 #include <unordered_set>
 
 #include <QWidget>
+#include <QList>
 
 class QHBoxLayout;
 class QLabel;
@@ -30,6 +31,7 @@ private:
     QStatusBar *sb;
     QScrollArea *sa;
     QListView *lw;
+    QList<QAction*> selhk;
     QStandardItemModel *im = nullptr;
     ImageItemDelegate *id = nullptr;
     std::size_t ngroups, curgroup;
@@ -45,8 +47,6 @@ private:
     std::unordered_set<fs::path> marked;
     std::vector<fs::path> current_set;
 protected:
-    void keyPressEvent(QKeyEvent *e) override;
-    void keyReleaseEvent(QKeyEvent *e) override;
     void resizeEvent(QResizeEvent *e) override;
     void closeEvent(QCloseEvent *e) override;
 public:
-- 
cgit v1.2.3