Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
shortcutsmodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 by the Quassel Project *
3  * devel@quassel-irc.org *
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 2 of the License, or *
8  * (at your option) version 3. *
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, write to the *
17  * Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 #include "shortcutsmodel.h"
22 
23 #include "action.h"
24 #include "actioncollection.h"
25 #include "util.h"
26 
27 ShortcutsModel::ShortcutsModel(const QHash<QString, ActionCollection *> &actionCollections, QObject *parent)
28  : QAbstractItemModel(parent),
29  _changedCount(0)
30 {
31  for (int r = 0; r < actionCollections.values().count(); r++) {
32  ActionCollection *coll = actionCollections.values().at(r);
33  Item *item = new Item();
34  item->row = r;
35  item->collection = coll;
36  for (int i = 0; i < coll->actions().count(); i++) {
37  Action *action = qobject_cast<Action *>(coll->actions().at(i));
38  if (!action)
39  continue;
40  Item *actionItem = new Item();
41  actionItem->parentItem = item;
42  actionItem->row = i;
43  actionItem->collection = coll;
44  actionItem->action = action;
45  actionItem->shortcut = action->shortcut();
46  item->actionItems.append(actionItem);
47  }
48  _categoryItems.append(item);
49  }
50 }
51 
52 
54 {
55  qDeleteAll(_categoryItems);
56 }
57 
58 
59 QModelIndex ShortcutsModel::parent(const QModelIndex &child) const
60 {
61  if (!child.isValid())
62  return QModelIndex();
63 
64  Item *item = static_cast<Item *>(child.internalPointer());
65  Q_ASSERT(item);
66 
67  if (!item->parentItem)
68  return QModelIndex();
69 
70  return createIndex(item->parentItem->row, 0, item->parentItem);
71 }
72 
73 
74 QModelIndex ShortcutsModel::index(int row, int column, const QModelIndex &parent) const
75 {
76  if (parent.isValid())
77  return createIndex(row, column, static_cast<Item *>(parent.internalPointer())->actionItems.at(row));
78 
79  // top level category item
80  return createIndex(row, column, _categoryItems.at(row));
81 }
82 
83 
84 int ShortcutsModel::columnCount(const QModelIndex &parent) const
85 {
86  return 2;
87  if (!parent.isValid())
88  return 2;
89 
90  Item *item = static_cast<Item *>(parent.internalPointer());
91  Q_ASSERT(item);
92 
93  if (!item->parentItem)
94  return 2;
95 
96  return 2;
97 }
98 
99 
100 int ShortcutsModel::rowCount(const QModelIndex &parent) const
101 {
102  if (!parent.isValid())
103  return _categoryItems.count();
104 
105  Item *item = static_cast<Item *>(parent.internalPointer());
106  Q_ASSERT(item);
107 
108  if (!item->parentItem)
109  return item->actionItems.count();
110 
111  return 0;
112 }
113 
114 
115 QVariant ShortcutsModel::headerData(int section, Qt::Orientation orientation, int role) const
116 {
117  if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
118  return QVariant();
119  switch (section) {
120  case 0:
121  return tr("Action");
122  case 1:
123  return tr("Shortcut");
124  default:
125  return QVariant();
126  }
127 }
128 
129 
130 QVariant ShortcutsModel::data(const QModelIndex &index, int role) const
131 {
132  if (!index.isValid())
133  return QVariant();
134 
135  Item *item = static_cast<Item *>(index.internalPointer());
136  Q_ASSERT(item);
137 
138  if (!item->parentItem) {
139  if (index.column() != 0)
140  return QVariant();
141  switch (role) {
142  case Qt::DisplayRole:
143  return item->collection->property("Category");
144  default:
145  return QVariant();
146  }
147  }
148 
149  Action *action = qobject_cast<Action *>(item->action);
150  Q_ASSERT(action);
151 
152  switch (role) {
153  case Qt::DisplayRole:
154  switch (index.column()) {
155  case 0:
156  return stripAcceleratorMarkers(action->text());
157  case 1:
158  return item->shortcut.toString(QKeySequence::NativeText);
159  default:
160  return QVariant();
161  }
162 
163  case Qt::DecorationRole:
164  if (index.column() == 0)
165  return action->icon();
166  return QVariant();
167 
168  case ActionRole:
169  return QVariant::fromValue<QObject *>(action);
170 
171  case DefaultShortcutRole:
172  return action->shortcut(Action::DefaultShortcut);
173  case ActiveShortcutRole:
174  return item->shortcut;
175 
176  case IsConfigurableRole:
177  return action->isShortcutConfigurable();
178 
179  default:
180  return QVariant();
181  }
182 }
183 
184 
185 bool ShortcutsModel::setData(const QModelIndex &index, const QVariant &value, int role)
186 {
187  if (role != ActiveShortcutRole)
188  return false;
189 
190  if (!index.parent().isValid())
191  return false;
192 
193  Item *item = static_cast<Item *>(index.internalPointer());
194  Q_ASSERT(item);
195 
196  QKeySequence newSeq = value.value<QKeySequence>();
197  QKeySequence oldSeq = item->shortcut;
198  QKeySequence storedSeq = item->action->shortcut(Action::ActiveShortcut);
199 
200  item->shortcut = newSeq;
201  emit dataChanged(index, index.sibling(index.row(), 1));
202 
203  if (oldSeq == storedSeq && newSeq != storedSeq) {
204  if (++_changedCount == 1)
205  emit hasChanged(true);
206  }
207  else if (oldSeq != storedSeq && newSeq == storedSeq) {
208  if (--_changedCount == 0)
209  emit hasChanged(false);
210  }
211 
212  return true;
213 }
214 
215 
217 {
218  foreach(Item *catItem, _categoryItems) {
219  foreach(Item *actItem, catItem->actionItems) {
220  actItem->shortcut = actItem->action->shortcut(Action::ActiveShortcut);
221  }
222  }
223  emit dataChanged(index(0, 1), index(rowCount()-1, 1));
224  if (_changedCount != 0) {
225  _changedCount = 0;
226  emit hasChanged(false);
227  }
228 }
229 
230 
232 {
233  foreach(Item *catItem, _categoryItems) {
234  foreach(Item *actItem, catItem->actionItems) {
235  actItem->action->setShortcut(actItem->shortcut, Action::ActiveShortcut);
236  }
237  }
238  if (_changedCount != 0) {
239  _changedCount = 0;
240  emit hasChanged(false);
241  }
242 }
243 
244 
246 {
247  for (int cat = 0; cat < rowCount(); cat++) {
248  QModelIndex catidx = index(cat, 0);
249  for (int act = 0; act < rowCount(catidx); act++) {
250  QModelIndex actidx = index(act, 1, catidx);
251  setData(actidx, actidx.data(DefaultShortcutRole), ActiveShortcutRole);
252  }
253  }
254 }