From 80ebd75285369fba45dcc771c2d45881eed704eb Mon Sep 17 00:00:00 2001
From: Adityarup Laha <30696515+adityaruplaha@users.noreply.github.com>
Date: Sun, 30 Dec 2018 15:39:16 +0530
Subject: [PATCH] citra-qt: Add /default parsing for hotkeys. Also minor code
 cleanups.

---
 src/citra_qt/configuration/config.cpp         | 95 ++++++++-----------
 src/citra_qt/configuration/config.h           |  3 +
 src/citra_qt/configuration/configure_dialog.h |  2 +-
 .../configuration/configure_hotkeys.cpp       |  9 +-
 .../configuration/configure_hotkeys.h         |  3 +-
 .../configuration/configure_hotkeys.ui        |  9 +-
 .../configuration/configure_input.cpp         |  2 +-
 src/citra_qt/configuration/configure_input.h  |  5 +-
 src/citra_qt/hotkeys.cpp                      |  2 +-
 src/citra_qt/hotkeys.h                        |  7 +-
 .../util/sequence_dialog/sequence_dialog.cpp  |  1 +
 .../util/sequence_dialog/sequence_dialog.h    |  3 +-
 12 files changed, 67 insertions(+), 74 deletions(-)

diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp
index c12c90507..b0a6323ac 100644
--- a/src/citra_qt/configuration/config.cpp
+++ b/src/citra_qt/configuration/config.cpp
@@ -8,7 +8,6 @@
 #include <QKeySequence>
 #include <QSettings>
 #include "citra_qt/configuration/config.h"
-#include "citra_qt/ui_settings.h"
 #include "common/file_util.h"
 #include "core/hle/service/service.h"
 #include "input_common/main.h"
@@ -21,7 +20,6 @@ Config::Config() {
     FileUtil::CreateFullPath(qt_config_loc);
     qt_config =
         std::make_unique<QSettings>(QString::fromStdString(qt_config_loc), QSettings::IniFormat);
-
     Reload();
 }
 
@@ -52,6 +50,31 @@ const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> Config:
     },
 }};
 
+// This shouldn't have anything except static initializers (no functions). So
+// QKeySequnce(...).toString() is NOT ALLOWED HERE.
+// This must be in alphabetical order according to action name as it must have the same order as
+// UISetting::values.shortcuts, which is alphabetically ordered.
+const std::array<UISettings::Shortcut, 19> Config::default_hotkeys{
+    {{"Advance Frame", "Main Window", {"\\", Qt::ApplicationShortcut}},
+     {"Capture Screenshot", "Main Window", {"Ctrl+P", Qt::ApplicationShortcut}},
+     {"Continue/Pause Emulation", "Main Window", {"F4", Qt::WindowShortcut}},
+     {"Decrease Speed Limit", "Main Window", {"-", Qt::ApplicationShortcut}},
+     {"Exit Citra", "Main Window", {"Ctrl+Q", Qt::WindowShortcut}},
+     {"Exit Fullscreen", "Main Window", {"Esc", Qt::WindowShortcut}},
+     {"Fullscreen", "Main Window", {"F11", Qt::WindowShortcut}},
+     {"Increase Speed Limit", "Main Window", {"+", Qt::ApplicationShortcut}},
+     {"Load Amiibo", "Main Window", {"F2", Qt::ApplicationShortcut}},
+     {"Load File", "Main Window", {"Ctrl+O", Qt::WindowShortcut}},
+     {"Remove Amiibo", "Main Window", {"F3", Qt::ApplicationShortcut}},
+     {"Restart Emulation", "Main Window", {"F6", Qt::WindowShortcut}},
+     {"Stop Emulation", "Main Window", {"F5", Qt::WindowShortcut}},
+     {"Swap Screens", "Main Window", {"F9", Qt::WindowShortcut}},
+     {"Toggle Filter Bar", "Main Window", {"Ctrl+F", Qt::WindowShortcut}},
+     {"Toggle Frame Advancing", "Main Window", {"Ctrl+A", Qt::ApplicationShortcut}},
+     {"Toggle Screen Layout", "Main Window", {"F10", Qt::WindowShortcut}},
+     {"Toggle Speed Limit", "Main Window", {"Ctrl+Z", Qt::ApplicationShortcut}},
+     {"Toggle Status Bar", "Main Window", {"Ctrl+S", Qt::WindowShortcut}}}};
+
 void Config::ReadValues() {
     qt_config->beginGroup("Controls");
 
@@ -320,55 +343,14 @@ void Config::ReadValues() {
     qt_config->endGroup();
 
     qt_config->beginGroup("Shortcuts");
-    const std::array<UISettings::Shortcut, 19> default_hotkeys{
-        {{"Load File", "Main Window",
-          UISettings::ContextualShortcut(QKeySequence(QKeySequence::Open).toString(),
-                                         Qt::WindowShortcut)},
-         {"Exit Citra", "Main Window",
-          UISettings::ContextualShortcut("Ctrl+Q", Qt::WindowShortcut)},
-         {"Continue/Pause Emulation", "Main Window",
-          UISettings::ContextualShortcut("F4", Qt::WindowShortcut)},
-         {"Stop Emulation", "Main Window",
-          UISettings::ContextualShortcut("F5", Qt::WindowShortcut)},
-         {"Restart Emulation", "Main Window",
-          UISettings::ContextualShortcut("F6", Qt::WindowShortcut)},
-         {"Swap Screens", "Main Window", UISettings::ContextualShortcut("F9", Qt::WindowShortcut)},
-         {"Toggle Screen Layout", "Main Window",
-          UISettings::ContextualShortcut("F10", Qt::WindowShortcut)},
-         {"Toggle Filter Bar", "Main Window",
-          UISettings::ContextualShortcut("Ctrl+F", Qt::WindowShortcut)},
-         {"Toggle Status Bar", "Main Window",
-          UISettings::ContextualShortcut("Ctrl+S", Qt::WindowShortcut)},
-         {"Fullscreen", "Main Window",
-          UISettings::ContextualShortcut(QKeySequence(QKeySequence::FullScreen).toString(),
-                                         Qt::WindowShortcut)},
-         {"Exit Fullscreen", "Main Window",
-          UISettings::ContextualShortcut("Escape", Qt::WindowShortcut)},
-         {"Toggle Speed Limit", "Main Window",
-          UISettings::ContextualShortcut("Ctrl+Z", Qt::ApplicationShortcut)},
-         {"Increase Speed Limit", "Main Window",
-          UISettings::ContextualShortcut("+", Qt::ApplicationShortcut)},
-         {"Decrease Speed Limit", "Main Window",
-          UISettings::ContextualShortcut("-", Qt::ApplicationShortcut)},
-         {"Advance Frame", "Main Window",
-          UISettings::ContextualShortcut("\\", Qt::ApplicationShortcut)},
-         {"Toggle Frame Advancing", "Main Window",
-          UISettings::ContextualShortcut("Ctrl+A", Qt::ApplicationShortcut)},
-         {"Load Amiibo", "Main Window",
-          UISettings::ContextualShortcut("F2", Qt::ApplicationShortcut)},
-         {"Remove Amiibo", "Main Window",
-          UISettings::ContextualShortcut("F3", Qt::ApplicationShortcut)},
-         {"Capture Screenshot", "Main Window",
-          UISettings::ContextualShortcut("Ctrl+P", Qt::ApplicationShortcut)}}};
-
-    for (int i = 0; i < default_hotkeys.size(); i++) {
-        qt_config->beginGroup(default_hotkeys[i].group);
-        qt_config->beginGroup(default_hotkeys[i].name);
+    for (auto [name, group, shortcut] : default_hotkeys) {
+        auto [keyseq, context] = shortcut;
+        qt_config->beginGroup(group);
+        qt_config->beginGroup(name);
         UISettings::values.shortcuts.push_back(
-            {default_hotkeys[i].name, default_hotkeys[i].group,
-             UISettings::ContextualShortcut(
-                 qt_config->value("KeySeq", default_hotkeys[i].shortcut.first).toString(),
-                 qt_config->value("Context", default_hotkeys[i].shortcut.second).toInt())});
+            {name,
+             group,
+             {ReadSetting("KeySeq", keyseq).toString(), ReadSetting("Context", context).toInt()}});
         qt_config->endGroup();
         qt_config->endGroup();
     }
@@ -601,11 +583,14 @@ void Config::SaveValues() {
     qt_config->endGroup();
 
     qt_config->beginGroup("Shortcuts");
-    for (auto shortcut : UISettings::values.shortcuts) {
-        qt_config->beginGroup(shortcut.group);
-        qt_config->beginGroup(shortcut.name);
-        WriteSetting("KeySeq", shortcut.shortcut.first);
-        WriteSetting("Context", shortcut.shortcut.second);
+    // Lengths of UISettings::values.shortcuts & default_hotkeys are same.
+    // However, their ordering must also be the same.
+    for (std::size_t i = 0; i < default_hotkeys.size(); i++) {
+        auto [name, group, shortcut] = UISettings::values.shortcuts[i];
+        qt_config->beginGroup(group);
+        qt_config->beginGroup(name);
+        WriteSetting("KeySeq", shortcut.first, default_hotkeys[i].shortcut.first);
+        WriteSetting("Context", shortcut.second, default_hotkeys[i].shortcut.second);
         qt_config->endGroup();
         qt_config->endGroup();
     }
diff --git a/src/citra_qt/configuration/config.h b/src/citra_qt/configuration/config.h
index fdb161c23..70aab4f8c 100644
--- a/src/citra_qt/configuration/config.h
+++ b/src/citra_qt/configuration/config.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <string>
 #include <QVariant>
+#include "citra_qt/ui_settings.h"
 #include "core/settings.h"
 
 class QSettings;
@@ -31,6 +32,8 @@ private:
     void WriteSetting(const QString& name, const QVariant& value);
     void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
 
+    static const std::array<UISettings::Shortcut, 19> default_hotkeys;
+
     std::unique_ptr<QSettings> qt_config;
     std::string qt_config_loc;
 };
diff --git a/src/citra_qt/configuration/configure_dialog.h b/src/citra_qt/configuration/configure_dialog.h
index 5abd28543..c902bf702 100644
--- a/src/citra_qt/configuration/configure_dialog.h
+++ b/src/citra_qt/configuration/configure_dialog.h
@@ -20,9 +20,9 @@ public:
     explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry);
     ~ConfigureDialog() override;
 
+    void applyConfiguration();
     void UpdateVisibleTabs();
     void PopulateSelectionList();
-    void applyConfiguration();
 
 private slots:
     void onLanguageChanged(const QString& locale);
diff --git a/src/citra_qt/configuration/configure_hotkeys.cpp b/src/citra_qt/configuration/configure_hotkeys.cpp
index cf4ae1034..aae212b5d 100644
--- a/src/citra_qt/configuration/configure_hotkeys.cpp
+++ b/src/citra_qt/configuration/configure_hotkeys.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <QMessageBox>
+#include <QStandardItemModel>
 #include "citra_qt/configuration/configure_hotkeys.h"
 #include "citra_qt/hotkeys.h"
 #include "citra_qt/util/sequence_dialog/sequence_dialog.h"
@@ -18,7 +19,6 @@ ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
     model->setColumnCount(3);
     model->setHorizontalHeaderLabels({tr("Action"), tr("Hotkey"), tr("Context")});
 
-    ui->hotkey_list->setSelectionMode(QTreeView::SingleSelection);
     connect(ui->hotkey_list, &QTreeView::doubleClicked, this, &ConfigureHotkeys::Configure);
     ui->hotkey_list->setModel(model);
 
@@ -27,10 +27,9 @@ ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
 
     ui->hotkey_list->setColumnWidth(0, 200);
     ui->hotkey_list->resizeColumnToContents(1);
-    ui->hotkey_list->setEditTriggers(QTreeView::NoEditTriggers);
 }
 
-ConfigureHotkeys::~ConfigureHotkeys() {}
+ConfigureHotkeys::~ConfigureHotkeys() = default;
 
 void ConfigureHotkeys::EmitHotkeysChanged() {
     emit HotkeysChanged(GetUsedKeyList());
@@ -86,9 +85,7 @@ void ConfigureHotkeys::Configure(QModelIndex index) {
     if (return_code == QDialog::Rejected || key_sequence.isEmpty())
         return;
 
-    if (IsUsedKey(key_sequence) &&
-        key_sequence != QKeySequence(previous_key.toString(), QKeySequence::NativeText)) {
-        model->setData(index, previous_key);
+    if (IsUsedKey(key_sequence) && key_sequence != QKeySequence(previous_key.toString())) {
         QMessageBox::critical(this, tr("Error in inputted key"),
                               tr("You're using a key that's already bound."));
     } else {
diff --git a/src/citra_qt/configuration/configure_hotkeys.h b/src/citra_qt/configuration/configure_hotkeys.h
index 960d9d572..bd2c1542c 100644
--- a/src/citra_qt/configuration/configure_hotkeys.h
+++ b/src/citra_qt/configuration/configure_hotkeys.h
@@ -5,9 +5,7 @@
 #pragma once
 
 #include <memory>
-#include <QStandardItemModel>
 #include <QWidget>
-#include "common/param_package.h"
 #include "core/settings.h"
 
 namespace Ui {
@@ -15,6 +13,7 @@ class ConfigureHotkeys;
 }
 
 class HotkeyRegistry;
+class QStandardItemModel;
 
 class ConfigureHotkeys : public QWidget {
     Q_OBJECT
diff --git a/src/citra_qt/configuration/configure_hotkeys.ui b/src/citra_qt/configuration/configure_hotkeys.ui
index d6ca3c47b..56a2e53fa 100644
--- a/src/citra_qt/configuration/configure_hotkeys.ui
+++ b/src/citra_qt/configuration/configure_hotkeys.ui
@@ -24,7 +24,14 @@
       </widget>
      </item>
      <item>
-      <widget class="QTreeView" name="hotkey_list"/>
+      <widget class="QTreeView" name="hotkey_list">
+       <property name="editTriggers">
+        <set>QAbstractItemView::NoEditTriggers</set>
+       </property>
+       <property name="sortingEnabled">
+        <bool>false</bool>
+       </property>
+      </widget>
      </item>
     </layout>
    </item>
diff --git a/src/citra_qt/configuration/configure_input.cpp b/src/citra_qt/configuration/configure_input.cpp
index f6f90385c..da5f64271 100644
--- a/src/citra_qt/configuration/configure_input.cpp
+++ b/src/citra_qt/configuration/configure_input.cpp
@@ -295,7 +295,7 @@ QList<QKeySequence> ConfigureInput::GetUsedKeyboardKeys() {
     }
 
     // TODO(adityaruplaha): Add home button to list when we finally emulate it
-    // Button ID of home button is 14: Reffered from citra_qt/configuration/config.cpp
+    // Button ID of home button is 14: Referred from citra_qt/configuration/config.cpp
     list.removeOne(list.indexOf(QKeySequence(buttons_param[14].Get("code", 0))));
     return list;
 }
diff --git a/src/citra_qt/configuration/configure_input.h b/src/citra_qt/configuration/configure_input.h
index a122402aa..36e44d52b 100644
--- a/src/citra_qt/configuration/configure_input.h
+++ b/src/citra_qt/configuration/configure_input.h
@@ -41,15 +41,14 @@ public:
     void loadConfiguration();
     void EmitInputKeysChanged();
 
+    /// Save the current input profile index
+    void ApplyProfile();
 public slots:
     void OnHotkeysChanged(QList<QKeySequence> new_key_list);
 
 signals:
     void InputKeysChanged(QList<QKeySequence> new_key_list);
 
-    // Save the current input profile index
-    void ApplyProfile();
-
 private:
     std::unique_ptr<Ui::ConfigureInput> ui;
 
diff --git a/src/citra_qt/hotkeys.cpp b/src/citra_qt/hotkeys.cpp
index 0939bcf49..5542f6dd4 100644
--- a/src/citra_qt/hotkeys.cpp
+++ b/src/citra_qt/hotkeys.cpp
@@ -30,7 +30,7 @@ void HotkeyRegistry::LoadHotkeys() {
         Hotkey& hk = hotkey_groups[shortcut.group][shortcut.name];
         if (!shortcut.shortcut.first.isEmpty()) {
             hk.keyseq = QKeySequence::fromString(shortcut.shortcut.first, QKeySequence::NativeText);
-            hk.context = (Qt::ShortcutContext)shortcut.shortcut.second;
+            hk.context = static_cast<Qt::ShortcutContext>(shortcut.shortcut.second);
         }
         if (hk.shortcut) {
             hk.shortcut->disconnect();
diff --git a/src/citra_qt/hotkeys.h b/src/citra_qt/hotkeys.h
index e8fed0ca6..4f526dc7e 100644
--- a/src/citra_qt/hotkeys.h
+++ b/src/citra_qt/hotkeys.h
@@ -48,7 +48,7 @@ public:
     QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget);
 
     /**
-     * Returns a QKeySequence object who signal can be connected to QAction->SetShortcut.
+     * Returns a QKeySequence object whose signal can be connected to QAction::setShortcut.
      *
      * @param group  General group this hotkey belongs to (e.g. "Main Window", "Debugger").
      * @param action Name of the action (e.g. "Start Emulation", "Load Image").
@@ -57,9 +57,10 @@ public:
 
     /**
      * Returns a Qt::ShortcutContext object who can be connected to other
-     * QAction->SetShortcutContext.
+     * QAction::setShortcutContext.
      *
-     * @param group  General group this shortcutcontext belongs to (e.g. "Main Window", "Debugger").
+     * @param group  General group this shortcut context belongs to (e.g. "Main Window",
+     * "Debugger").
      * @param action Name of the action (e.g. "Start Emulation", "Load Image").
      */
     Qt::ShortcutContext GetShortcutContext(const QString& group, const QString& action);
diff --git a/src/citra_qt/util/sequence_dialog/sequence_dialog.cpp b/src/citra_qt/util/sequence_dialog/sequence_dialog.cpp
index 48e7a82a7..8eff35621 100644
--- a/src/citra_qt/util/sequence_dialog/sequence_dialog.cpp
+++ b/src/citra_qt/util/sequence_dialog/sequence_dialog.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <QDialogButtonBox>
+#include <QKeySequenceEdit>
 #include <QVBoxLayout>
 #include "citra_qt/util/sequence_dialog/sequence_dialog.h"
 
diff --git a/src/citra_qt/util/sequence_dialog/sequence_dialog.h b/src/citra_qt/util/sequence_dialog/sequence_dialog.h
index 1dca4ddf2..ba8843d92 100644
--- a/src/citra_qt/util/sequence_dialog/sequence_dialog.h
+++ b/src/citra_qt/util/sequence_dialog/sequence_dialog.h
@@ -6,7 +6,8 @@
 
 #include <memory>
 #include <QDialog>
-#include <QKeySequenceEdit>
+
+class QKeySequenceEdit;
 
 class SequenceDialog : public QDialog {
     Q_OBJECT