src/platform/qt/ShortcutController.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "ShortcutController.h"
7
8#include <QAction>
9#include <QMenu>
10
11using namespace QGBA;
12
13ShortcutController::ShortcutController(QObject* parent)
14 : QAbstractItemModel(parent)
15{
16}
17
18QVariant ShortcutController::data(const QModelIndex& index, int role) const {
19 if (role != Qt::DisplayRole || !index.isValid()) {
20 return QVariant();
21 }
22 const QModelIndex& parent = index.parent();
23 if (parent.isValid()) {
24 const ShortcutMenu& menu = m_menus[parent.row()];
25 const ShortcutItem& item = menu.shortcuts()[index.row()];
26 switch (index.column()) {
27 case 0:
28 return item.visibleName();
29 case 1:
30 return item.action()->shortcut().toString(QKeySequence::NativeText);
31 }
32 } else if (index.column() == 0) {
33 return m_menus[index.row()].visibleName();
34 }
35 return QVariant();
36}
37
38QVariant ShortcutController::headerData(int section, Qt::Orientation orientation, int role) const {
39 if (role != Qt::DisplayRole) {
40 return QAbstractItemModel::headerData(section, orientation, role);
41 }
42 if (orientation == Qt::Horizontal) {
43 switch (section) {
44 case 0:
45 return tr("Action");
46 case 1:
47 return tr("Shortcut");
48 }
49 }
50 return section;
51}
52
53QModelIndex ShortcutController::index(int row, int column, const QModelIndex& parent) const {
54 if (!parent.isValid()) {
55 return createIndex(row, column, -1);
56 }
57 return createIndex(row, column, parent.row());
58}
59
60QModelIndex ShortcutController::parent(const QModelIndex& index) const {
61 if (!index.isValid()) {
62 return QModelIndex();
63 }
64 if (index.internalId() == -1) {
65 return QModelIndex();
66 }
67 return createIndex(index.internalId(), 0, -1);
68}
69
70int ShortcutController::columnCount(const QModelIndex& index) const {
71 return 2;
72}
73
74int ShortcutController::rowCount(const QModelIndex& index) const {
75 if (index.parent().isValid()) {
76 return 0;
77 }
78 if (index.isValid()) {
79 return m_menus[index.row()].shortcuts().count();
80 }
81 return m_menus.count();
82}
83
84void ShortcutController::addAction(QMenu* menu, QAction* action, const QString& name) {
85 ShortcutMenu* smenu = nullptr;
86 int row = 0;
87 for (auto iter = m_menus.end(); iter-- != m_menus.begin(); ++row) {
88 if (iter->menu() == menu) {
89 smenu = &(*iter);
90 break;
91 }
92 }
93 if (!smenu) {
94 return;
95 }
96 QModelIndex parent = createIndex(row, 0, -1);
97 beginInsertRows(parent, smenu->shortcuts().count(), smenu->shortcuts().count());
98 smenu->addAction(action, name);
99 endInsertRows();
100 emit dataChanged(createIndex(smenu->shortcuts().count() - 1, 0, row), createIndex(smenu->shortcuts().count() - 1, 1, row));
101}
102
103void ShortcutController::addMenu(QMenu* menu) {
104 beginInsertRows(QModelIndex(), m_menus.count(), m_menus.count());
105 m_menus.append(ShortcutMenu(menu));
106 endInsertRows();
107 emit dataChanged(createIndex(m_menus.count() - 1, 0, -1), createIndex(m_menus.count() - 1, 0, -1));
108}
109
110const QAction* ShortcutController::actionAt(const QModelIndex& index) const {
111 if (!index.isValid()) {
112 return nullptr;
113 }
114 const QModelIndex& parent = index.parent();
115 if (!parent.isValid()) {
116 return nullptr;
117 }
118 if (parent.row() > m_menus.count()) {
119 return nullptr;
120 }
121 const ShortcutMenu& menu = m_menus[parent.row()];
122 if (index.row() > menu.shortcuts().count()) {
123 return nullptr;
124 }
125 const ShortcutItem& item = menu.shortcuts()[index.row()];
126 return item.action();
127}
128
129void ShortcutController::updateKey(const QModelIndex& index, const QKeySequence& keySequence) {
130 if (!index.isValid()) {
131 return;
132 }
133 const QModelIndex& parent = index.parent();
134 if (!parent.isValid()) {
135 return;
136 }
137 ShortcutMenu& menu = m_menus[parent.row()];
138 ShortcutItem& item = menu.shortcuts()[index.row()];
139 item.action()->setShortcut(keySequence);
140 emit dataChanged(createIndex(index.row(), 0, index.internalId()), createIndex(index.row(), 1, index.internalId()));
141}
142
143ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& name)
144 : m_action(action)
145 , m_name(name)
146{
147 m_visibleName = action->text()
148 .remove(QRegExp("&(?!&)"))
149 .remove("...");
150}
151
152ShortcutController::ShortcutMenu::ShortcutMenu(QMenu* menu)
153 : m_menu(menu)
154{
155 m_visibleName = menu->title()
156 .remove(QRegExp("&(?!&)"))
157 .remove("...");
158}
159
160void ShortcutController::ShortcutMenu::addAction(QAction* action, const QString& name) {
161 m_shortcuts.append(ShortcutItem(action, name));
162}