src/dialogs/shortcutsmodel.cpp

changeset 1433
bd3a9e237ef5
equal deleted inserted replaced
1432:4cc687851fbb 1433:bd3a9e237ef5
1 /*
2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 - 2018 Teemu Piippo
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <QKeySequenceEdit>
20 #include <QSettings>
21 #include "mainwindow.h"
22 #include "widgets/extendedkeysequenceeditor.h"
23 #include "shortcutsmodel.h"
24
25 /*
26 * Constructs a new shortcuts model.
27 * Actions are acquired from the provided mainwindow.
28 */
29 ShortcutsModel::ShortcutsModel(MainWindow* parent)
30 {
31 for (QAction* action : parent->findChildren<QAction*>())
32 {
33 if (not action->objectName().isEmpty())
34 shortcuts.append({action, action->shortcut(), parent->defaultShortcut(action)});
35 }
36 }
37
38 /*
39 * Returns the amount of shortcuts.
40 */
41 int ShortcutsModel::rowCount(const QModelIndex &) const
42 {
43 return shortcuts.size();
44 }
45
46 /*
47 * Returns the amount of columns.
48 */
49 int ShortcutsModel::columnCount(const QModelIndex &) const
50 {
51 return 2;
52 }
53
54 /*
55 * Returns various shortcut data.
56 */
57 QVariant ShortcutsModel::data(const QModelIndex &index, int role) const
58 {
59 if (not isValidIndex(index))
60 return {};
61
62 Item const& entry = shortcuts[index.row()];
63
64 switch (role)
65 {
66 case Qt::DisplayRole:
67 switch (index.column())
68 {
69 case ActionColumn:
70 return entry.action->text().replace("&", "");
71
72 case KeySequenceColumn:
73 return entry.sequence.toString(QKeySequence::NativeText);
74
75 default:
76 return "";
77 }
78
79 case Qt::DecorationRole:
80 if (index.column() == ActionColumn)
81 return entry.action->icon();
82 else
83 return {};
84
85 case Qt::EditRole:
86 switch (index.column())
87 {
88 case KeySequenceColumn:
89 return QVariant::fromValue(entry.sequence);
90
91 default:
92 return {};
93 }
94
95 case DefaultKeySequenceRole:
96 return entry.defaultSequence;
97
98 default:
99 return {};
100 }
101 }
102
103 /*
104 * Reimplementation of QAbstractItemModel::flags that supplies the editable flag
105 * for the key sequence cells.
106 */
107 Qt::ItemFlags ShortcutsModel::flags(const QModelIndex& index) const
108 {
109 Qt::ItemFlags flags = QAbstractItemModel::flags(index);
110
111 if (index.column() == KeySequenceColumn)
112 flags |= Qt::ItemIsEditable;
113
114 return flags;
115 }
116
117 /*
118 * Returns whether or not the specified row is valid.
119 */
120 bool ShortcutsModel::isValidRow(int row) const
121 {
122 return row >= 0 and row < shortcuts.size();
123 }
124
125 /*
126 * Returns whether or not the specified model index is valid.
127 */
128 bool ShortcutsModel::isValidIndex(const QModelIndex &index) const
129 {
130 return index.column() >= 0 and index.column() < 2 and isValidRow(index.row());
131 }
132
133 /*
134 * Provides an interface for changing the key sequence.
135 */
136 bool ShortcutsModel::setData(const QModelIndex &index, const QVariant &value, int role)
137 {
138 if (isValidIndex(index) and index.column() == KeySequenceColumn and role == Qt::EditRole)
139 {
140 shortcuts[index.row()].sequence = value.value<QKeySequence>();
141 return true;
142 }
143 else
144 {
145 return false;
146 }
147 }
148
149 /*
150 * Saves shortcuts to the settings object and updates the actions.
151 */
152 void ShortcutsModel::saveChanges()
153 {
154 for (Item& shortcut : shortcuts)
155 {
156 shortcut.action->setShortcut(shortcut.sequence);
157 QString const key = "shortcut_" + shortcut.action->objectName();
158
159 if (shortcut.defaultSequence != shortcut.sequence)
160 settingsObject().setValue(key, shortcut.sequence);
161 else
162 settingsObject().remove(key);
163 }
164 }
165
166 /*
167 * Returns an index.
168 */
169 QModelIndex ShortcutsModel::index(int row, int column, const QModelIndex& parent) const
170 {
171 ignore(parent);
172 return createIndex(row, column);
173 }
174
175 /*
176 * Returns nothing, because the shortcuts model does not use parents.
177 */
178 QModelIndex ShortcutsModel::parent(const QModelIndex &child) const
179 {
180 ignore(child);
181 return {};
182 }
183
184 /*
185 * Returns headers.
186 */
187 QVariant ShortcutsModel::headerData(int section, Qt::Orientation orientation, int role) const
188 {
189 if (role == Qt::DisplayRole and orientation == Qt::Horizontal)
190 {
191 switch (section)
192 {
193 case ActionColumn:
194 return "Action";
195
196 case KeySequenceColumn:
197 return "Shortcut";
198
199 default:
200 return "";
201 }
202 }
203 else
204 {
205 return {};
206 }
207 }
208
209 /*
210 * Constructs a new key sequence delegate.
211 */
212 KeySequenceDelegate::KeySequenceDelegate(QObject *parent) :
213 QStyledItemDelegate {parent} {}
214
215 /*
216 * Creates a key sequence editor.
217 */
218 QWidget *KeySequenceDelegate::createEditor(
219 QWidget *parent,
220 const QStyleOptionViewItem &option,
221 const QModelIndex &index) const
222 {
223 ignore(option, index);
224 const QVariant variant = index.model()->data(index, ShortcutsModel::DefaultKeySequenceRole);
225 const QKeySequence defaultSequence = variant.value<QKeySequence>();
226 ExtendedKeySequenceEditor* editor = new ExtendedKeySequenceEditor {{}, defaultSequence, parent};
227 return editor;
228 }
229
230 /*
231 * Sets the initial key sequence used in the key sequence editor.
232 */
233 void KeySequenceDelegate::setEditorData(QWidget *widget, const QModelIndex &index) const
234 {
235 QKeySequence sequence = index.model()->data(index, Qt::EditRole).value<QKeySequence>();
236 ExtendedKeySequenceEditor* editor = static_cast<ExtendedKeySequenceEditor*>(widget);
237 editor->setKeySequence(sequence);
238 }
239
240 /*
241 * Updates the shortcuts model when the key sequence has been accepted by the user.
242 */
243 void KeySequenceDelegate::setModelData(
244 QWidget *widget,
245 QAbstractItemModel *model,
246 const QModelIndex &index) const
247 {
248 ExtendedKeySequenceEditor* editor = static_cast<ExtendedKeySequenceEditor*>(widget);
249 model->setData(index, editor->keySequence(), Qt::EditRole);
250 }
251
252 /*
253 * Updates editor geometry.
254 */
255 void KeySequenceDelegate::updateEditorGeometry(
256 QWidget *editor,
257 const QStyleOptionViewItem &option,
258 const QModelIndex &index) const
259 {
260 ignore(index);
261 editor->setGeometry(option.rect);
262 }

mercurial