dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
shortcutsettings.cpp
Go to the documentation of this file.
1 
14 /*
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 3 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  * for more details.
24  *
25  * You should have received a copy of the GNU General Public License along
26  * with this program; if not, see <http://www.gnu.org/licenses/>
27  *
28  * Additional note on redistribution: The copyright and license notices above
29  * must be maintained in each individual source file that is a derivative work
30  * of this source file; otherwise redistribution is prohibited.
31  */
32 
33 #include "shortcutsettings.h"
34 #include "ui_shortcutsettings.h"
35 #include "actionmanager_p.h"
36 #include "actionmanager/command.h"
37 #include "command_p.h"
38 #include "commandsfile.h"
39 #include "coreconstants.h"
40 #include "icore.h"
41 #include "uniqueidmanager.h"
43 
44 #include <QKeyEvent>
45 #include <QShortcut>
46 #include <QHeaderView>
47 #include <QtDebug>
48 
50 
51 using namespace Core;
52 using namespace Core::Internal;
53 
55  : IOptionsPage(parent)
56 {
57 }
58 
59 ShortcutSettings::~ShortcutSettings()
60 {
61 }
62 
63 // IOptionsPage
64 
65 QString ShortcutSettings::id() const
66 {
67  return QLatin1String("Keyboard");
68 }
69 
70 QString ShortcutSettings::trName() const
71 {
72  return tr("Keyboard");
73 }
74 
76 {
77  return QLatin1String("Environment");
78 }
79 
81 {
82  return tr("Environment");
83 }
84 
85 QWidget *ShortcutSettings::createPage(QWidget *parent)
86 {
87  m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
88 
89  m_page = new Ui_ShortcutSettings();
90  QWidget *w = new QWidget(parent);
91  m_page->setupUi(w);
92 
93  m_page->resetButton->setIcon(QIcon(Constants::ICON_RESET));
94  m_page->shortcutEdit->installEventFilter(this);
95 
96  connect(m_page->resetButton, SIGNAL(clicked()), this, SLOT(resetKeySequence()));
97  connect(m_page->removeButton, SIGNAL(clicked()), this, SLOT(removeKeySequence()));
98  connect(m_page->defaultButton, SIGNAL(clicked()), this, SLOT(defaultAction()));
99 
100  initialize();
101 
102  m_page->commandList->sortByColumn(0, Qt::AscendingOrder);
103 
104  connect(m_page->filterEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
105  connect(m_page->commandList, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
106  this, SLOT(commandChanged(QTreeWidgetItem *)));
107  connect(m_page->shortcutEdit, SIGNAL(textChanged(QString)), this, SLOT(keyChanged()));
108 
109  new Utils::TreeWidgetColumnStretcher(m_page->commandList, 1);
110 
111  commandChanged(nullptr);
112 
113  return w;
114 }
115 
117 {
118  foreach (ShortcutItem *item, m_scitems)
119  item->m_cmd->setKeySequence(item->m_key);
120 }
121 
123 {
124  qDeleteAll(m_scitems);
125  m_scitems.clear();
126 
127  delete m_page;
128 }
129 
130 bool ShortcutSettings::eventFilter(QObject *o, QEvent *e)
131 {
132  Q_UNUSED(o)
133 
134  if (e->type() == QEvent::KeyPress) {
135  QKeyEvent *k = static_cast<QKeyEvent *>(e);
136  handleKeyEvent(k);
137  return true;
138  }
139 
140  if (e->type() == QEvent::Shortcut || e->type() == QEvent::ShortcutOverride
141  || e->type() == QEvent::KeyRelease)
142  return true;
143 
144  return false;
145 }
146 
147 void ShortcutSettings::commandChanged(QTreeWidgetItem *current)
148 {
149  if (!current || !current->data(0, Qt::UserRole).isValid()) {
150  m_page->shortcutEdit->setText("");
151  m_page->seqGrp->setEnabled(false);
152  return;
153  }
154  m_page->seqGrp->setEnabled(true);
155  ShortcutItem *scitem = current->data(0, Qt::UserRole).value<ShortcutItem *>();
156  setKeySequence(scitem->m_key);
157 }
158 
159 void ShortcutSettings::filterChanged(const QString &f)
160 {
161  for (int i = 0; i < m_page->commandList->topLevelItemCount(); ++i) {
162  QTreeWidgetItem *item = m_page->commandList->topLevelItem(i);
163  item->setHidden(filter(f, item));
164  }
165 }
166 
167 void ShortcutSettings::keyChanged()
168 {
169  QTreeWidgetItem *current = m_page->commandList->currentItem();
170  if (current && current->data(0, Qt::UserRole).isValid()) {
171  ShortcutItem *scitem = current->data(0, Qt::UserRole).value<ShortcutItem *>();
172  scitem->m_key = QKeySequence(m_key[0], m_key[1], m_key[2], m_key[3]);
173  current->setText(2, scitem->m_key.toString());
174  }
175 }
176 
177 void ShortcutSettings::setKeySequence(const QKeySequence &key)
178 {
179  m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
180  m_keyNum = key.count();
181  for (int i = 0; i < m_keyNum; ++i) {
182  m_key[i] = key[i];
183  }
184  m_page->shortcutEdit->setText(key.toString());
185 }
186 
187 bool ShortcutSettings::filter(const QString &f, const QTreeWidgetItem *item)
188 {
189  if (item->childCount() == 0) {
190  if (f.isEmpty())
191  return false;
192  for (int i = 0; i < item->columnCount(); ++i) {
193  if (item->text(i).contains(f, Qt::CaseInsensitive))
194  return false;
195  }
196  return true;
197  }
198 
199  bool found = false;
200  for (int i = 0; i < item->childCount(); ++i) {
201  QTreeWidgetItem *citem = item->child(i);
202  if (filter(f, citem)) {
203  citem->setHidden(true);
204  } else {
205  citem->setHidden(false);
206  found = true;
207  }
208  }
209  return !found;
210 }
211 
212 void ShortcutSettings::resetKeySequence()
213 {
214  QTreeWidgetItem *current = m_page->commandList->currentItem();
215  if (current && current->data(0, Qt::UserRole).isValid()) {
216  ShortcutItem *scitem = current->data(0, Qt::UserRole).value<ShortcutItem *>();
217  setKeySequence(scitem->m_cmd->defaultKeySequence());
218  }
219 }
220 
221 void ShortcutSettings::removeKeySequence()
222 {
223  m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
224  m_page->shortcutEdit->clear();
225 }
226 
227 void ShortcutSettings::defaultAction()
228 {
229  foreach (ShortcutItem *item, m_scitems) {
230  item->m_key = item->m_cmd->defaultKeySequence();
231  item->m_item->setText(2, item->m_key.toString());
232  if (item->m_item == m_page->commandList->currentItem())
233  commandChanged(item->m_item);
234  }
235 }
236 
237 void ShortcutSettings::initialize()
238 {
240  UniqueIDManager *uidm = UniqueIDManager::instance();
241 
242  foreach (Command *c, m_am->commands()) {
243  if (c->hasAttribute(Command::CA_NonConfigureable))
244  continue;
245  if (c->action() && c->action()->isSeparator())
246  continue;
247 
248  QTreeWidgetItem *item = nullptr;
249  ShortcutItem *s = new ShortcutItem;
250  m_scitems << s;
251  item = new QTreeWidgetItem(m_page->commandList);
252  s->m_cmd = c;
253  s->m_item = item;
254 
255  item->setText(0, uidm->stringForUniqueIdentifier(c->id()));
256 
257  if (c->action()) {
258  QString text = c->hasAttribute(Command::CA_UpdateText) && !c->defaultText().isNull()
259  ? c->defaultText()
260  : c->action()->text();
261  text.remove(QRegExp("&(?!&)"));
262  s->m_key = c->action()->shortcut();
263  item->setText(1, text);
264  } else {
265  s->m_key = c->shortcut()->key();
266  item->setText(1, c->shortcut()->whatsThis());
267  }
268 
269  item->setText(2, s->m_key.toString());
270  item->setData(0, Qt::UserRole, qVariantFromValue(s));
271  }
272 }
273 
274 void ShortcutSettings::handleKeyEvent(QKeyEvent *e)
275 {
276  int nextKey = e->key();
277  if (m_keyNum > 3 || nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift
278  || nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt)
279  return;
280 
281  nextKey |= translateModifiers(e->modifiers(), e->text());
282  switch (m_keyNum) {
283  case 0:
284  m_key[0] = nextKey;
285  break;
286  case 1:
287  m_key[1] = nextKey;
288  break;
289  case 2:
290  m_key[2] = nextKey;
291  break;
292  case 3:
293  m_key[3] = nextKey;
294  break;
295  default:
296  break;
297  }
298  m_keyNum++;
299  QKeySequence ks(m_key[0], m_key[1], m_key[2], m_key[3]);
300  m_page->shortcutEdit->setText(ks.toString());
301  e->accept();
302 }
303 
304 int ShortcutSettings::translateModifiers(Qt::KeyboardModifiers state, const QString &text)
305 {
306  int result = 0;
307  // The shift modifier only counts when it is not used to type a symbol
308  // that is only reachable using the shift key anyway
309  if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint()
310  || text.at(0).isLetter() || text.at(0).isSpace()))
311  result |= Qt::SHIFT;
312  if (state & Qt::ControlModifier)
313  result |= Qt::CTRL;
314  if (state & Qt::MetaModifier)
315  result |= Qt::META;
316  if (state & Qt::AltModifier)
317  result |= Qt::ALT;
318  return result;
319 }
bool eventFilter(QObject *o, QEvent *e)
static UniqueIDManager * instance()
const char *const ICON_RESET
for i
Definition: OPPlots.m:140
static ActionManagerPrivate * instance()
virtual void setKeySequence(const QKeySequence &key)=0
virtual QKeySequence defaultKeySequence() const =0
The IOptionsPage is an interface for providing options pages.
Definition: ioptionspage.h:42
Q_DECLARE_METATYPE(Core::Internal::ShortcutItem *) using namespace Core
QList< CommandPrivate * > commands() const
QWidget * createPage(QWidget *parent)
e
Definition: OPPlots.m:99