configure_hotkeys.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <QMessageBox>
  5. #include <QStandardItemModel>
  6. #include "core/settings.h"
  7. #include "ui_configure_hotkeys.h"
  8. #include "yuzu/configuration/configure_hotkeys.h"
  9. #include "yuzu/hotkeys.h"
  10. #include "yuzu/util/sequence_dialog/sequence_dialog.h"
  11. ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
  12. : QWidget(parent), ui(std::make_unique<Ui::ConfigureHotkeys>()) {
  13. ui->setupUi(this);
  14. setFocusPolicy(Qt::ClickFocus);
  15. model = new QStandardItemModel(this);
  16. model->setColumnCount(3);
  17. model->setHorizontalHeaderLabels({tr("Action"), tr("Hotkey"), tr("Context")});
  18. connect(ui->hotkey_list, &QTreeView::doubleClicked, this, &ConfigureHotkeys::Configure);
  19. ui->hotkey_list->setModel(model);
  20. // TODO(Kloen): Make context configurable as well (hiding the column for now)
  21. ui->hotkey_list->hideColumn(2);
  22. ui->hotkey_list->setColumnWidth(0, 200);
  23. ui->hotkey_list->resizeColumnToContents(1);
  24. }
  25. ConfigureHotkeys::~ConfigureHotkeys() = default;
  26. void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
  27. for (const auto& group : registry.hotkey_groups) {
  28. auto* parent_item = new QStandardItem(group.first);
  29. parent_item->setEditable(false);
  30. for (const auto& hotkey : group.second) {
  31. auto* action = new QStandardItem(hotkey.first);
  32. auto* keyseq =
  33. new QStandardItem(hotkey.second.keyseq.toString(QKeySequence::NativeText));
  34. action->setEditable(false);
  35. keyseq->setEditable(false);
  36. parent_item->appendRow({action, keyseq});
  37. }
  38. model->appendRow(parent_item);
  39. }
  40. ui->hotkey_list->expandAll();
  41. }
  42. void ConfigureHotkeys::Configure(QModelIndex index) {
  43. if (!index.parent().isValid()) {
  44. return;
  45. }
  46. index = index.sibling(index.row(), 1);
  47. auto* const model = ui->hotkey_list->model();
  48. const auto previous_key = model->data(index);
  49. SequenceDialog hotkey_dialog{this};
  50. const int return_code = hotkey_dialog.exec();
  51. const auto key_sequence = hotkey_dialog.GetSequence();
  52. if (return_code == QDialog::Rejected || key_sequence.isEmpty()) {
  53. return;
  54. }
  55. if (IsUsedKey(key_sequence) && key_sequence != QKeySequence(previous_key.toString())) {
  56. QMessageBox::warning(this, tr("Conflicting Key Sequence"),
  57. tr("The entered key sequence is already assigned to another hotkey."));
  58. } else {
  59. model->setData(index, key_sequence.toString(QKeySequence::NativeText));
  60. }
  61. }
  62. bool ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const {
  63. for (int r = 0; r < model->rowCount(); r++) {
  64. const QStandardItem* const parent = model->item(r, 0);
  65. for (int r2 = 0; r2 < parent->rowCount(); r2++) {
  66. const QStandardItem* const key_seq_item = parent->child(r2, 1);
  67. const auto key_seq_str = key_seq_item->text();
  68. const auto key_seq = QKeySequence::fromString(key_seq_str, QKeySequence::NativeText);
  69. if (key_sequence == key_seq) {
  70. return true;
  71. }
  72. }
  73. }
  74. return false;
  75. }
  76. void ConfigureHotkeys::applyConfiguration(HotkeyRegistry& registry) {
  77. for (int key_id = 0; key_id < model->rowCount(); key_id++) {
  78. const QStandardItem* parent = model->item(key_id, 0);
  79. for (int key_column_id = 0; key_column_id < parent->rowCount(); key_column_id++) {
  80. const QStandardItem* action = parent->child(key_column_id, 0);
  81. const QStandardItem* keyseq = parent->child(key_column_id, 1);
  82. for (auto& [group, sub_actions] : registry.hotkey_groups) {
  83. if (group != parent->text())
  84. continue;
  85. for (auto& [action_name, hotkey] : sub_actions) {
  86. if (action_name != action->text())
  87. continue;
  88. hotkey.keyseq = QKeySequence(keyseq->text());
  89. }
  90. }
  91. }
  92. }
  93. registry.SaveHotkeys();
  94. Settings::Apply();
  95. }
  96. void ConfigureHotkeys::retranslateUi() {
  97. ui->retranslateUi(this);
  98. }