Developer Documentation
keyBindings.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 
45 
46 #include "optionsWidget.hh"
47 #include <QMessageBox>
48 
50 int OptionsWidget::getPluginInfo(QString pluginName){
51  for (uint i=0; i < plugins_.size(); i++)
52  if (plugins_[i].name == pluginName)
53  return i;
54 
55  return -1;
56 }
57 
59 void OptionsWidget::keyTreeDoubleClicked(QTreeWidgetItem* _item, int /*col*/){
60 
61 std::cerr << "set focus\n";
62 
63  if (_item == 0 || _item->parent() == 0 || _item->columnCount() < 7)
64  return;
65 
66  shortcutButton->setFocus(Qt::TabFocusReason);
67 }
68 
70 void OptionsWidget::keyTreeItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* /*previous*/){
71 
72  if (current == 0 || current->parent() == 0 || current->columnCount() < 7){
73  shortcutBox->setEnabled(false);
74  shortcutButton->setText("");
75  defaultShortcut->setText("");
76  }else{
77  shortcutBox->setEnabled(true);
78 
79  shortcutButton->setCurrentShortcut( current->text(4).toInt(), (Qt::KeyboardModifiers) current->text(5).toInt() );
80  defaultShortcut->setText( current->text(2) );
81  }
82 
83 }
84 
87 
88  if ( keyTree->currentItem() == 0)
89  return;
90 
91  bool myMultiUse = (bool) keyTree->currentItem()->text(6).toInt();
92  QString myNewKey = shortcutButton->text();
93 
94  //check if the shortcut already exists
95  for (int i=0; i < keyTree->topLevelItemCount(); i++)
96  for (int j=0; j < keyTree->topLevelItem(i)->childCount(); j++){
97 
98  QTreeWidgetItem* item = keyTree->topLevelItem(i)->child(j);
99  QString key = item->text(1);
100  bool multiUse = (bool) item->text(6).toInt();
101 
102  if (keyTree->currentItem() == item)
103  continue;
104 
105  if (key == myNewKey && ( !multiUse || !myMultiUse ) ){
106  QMessageBox::warning(this, tr("OpenFlipper"), tr("Could not add Shortcut. Shortcut already assigned."), QMessageBox::Ok);
107  return;
108  }
109  }
110 
111  //update the item
112  if ( keyTree->currentItem() != 0){
113  keyTree->currentItem()->setText( 1, shortcutButton->text() );
114  keyTree->currentItem()->setText( 4, QString::number( shortcutButton->key() ) );
115  keyTree->currentItem()->setText( 5, QString::number( shortcutButton->modifiers() ) );
116  }
117 
118  keyTree->setFocus(Qt::TabFocusReason);
119  keyTreeItemChanged(keyTree->currentItem(), 0);
120 }
121 
124 
125  //check all shortcuts
126  for (int i=0; i < keyTree->topLevelItemCount(); i++)
127  for (int j=0; j < keyTree->topLevelItem(i)->childCount(); j++){
128 
129  //check wether the shortcut changed
130  QTreeWidgetItem* item = keyTree->topLevelItem(i)->child(j);
131 
132  if ( item->text(1) != item->text(7) ){
133 
134  QString pluginName = item->parent()->text(0);
135 
136  QObject* plugin = 0;
137 
138  if (pluginName != "Core"){
139 
140  //get the plugin object
141  int index = getPluginInfo(pluginName);
142 
143  if (index == -1) //if pluginInfo was not found ->skip
144  continue;
145 
146  plugin = plugins_[index].plugin;
147  }
148 
149  int bindingID = item->text(3).toInt();
150  int key = item->text(4).toInt();
151 
152  Qt::KeyboardModifiers modi = (Qt::KeyboardModifiers) item->text(5).toInt();
153 
154  emit addKeyMapping(key, modi, plugin, bindingID);
155  }
156  }
157 }
158 
160 
161  //check if the shortcut already exists
162  for (int i=0; i < keyTree->topLevelItemCount(); i++)
163  for (int j=0; j < keyTree->topLevelItem(i)->childCount(); j++){
164 
165  QTreeWidgetItem* item = keyTree->topLevelItem(i)->child(j);
166  QString key = item->text(1);
167 
168  QString pluginName = item->parent()->text(0);
169  int bindingID = item->text(3).toInt();
170 
171  if (pluginName == "Core"){
172 
173  item->setText( 1, item->text(2) );
174  item->setText( 4, QString::number(coreKeys_[ bindingID ].key) );
175  item->setText( 5, QString::number(coreKeys_[ bindingID ].modifiers) );
176 
177  } else {
178 
179  //get the plugin object
180  int index = getPluginInfo(pluginName);
181 
182  if (index == -1) //if pluginInfo was not found ->skip
183  continue;
184 
185  item->setText( 1, item->text(2) );
186  item->setText( 4, QString::number(plugins_[index].keys[ bindingID ].key) );
187  item->setText( 5, QString::number(plugins_[index].keys[ bindingID ].modifiers) );
188  }
189  }
190 
191  keyTree->setFocus(Qt::TabFocusReason);
192  keyTreeItemChanged(keyTree->currentItem(), 0);
193 }
194 
197 
198  keyTree->clear();
199 
200  keyTree->setEditTriggers(QAbstractItemView::NoEditTriggers);
201 
202  keyTree->setColumnCount ( 8 );
203 
204  QStringList headerdata;
205  headerdata << "Action" << "Shortcut" << "Default" << "keyIndex" << "currentKey" << "currentModi" << "MultiUse" << "initShortcut";
206  keyTree->setHeaderLabels(headerdata);
207 
208  //fill the keyTree
209  std::map< QString, QTreeWidgetItem* > parentMap;
210 
211  InverseKeyMap::iterator it;
212  for (it=keys_.begin(); it != keys_.end(); ++it){
213 
214  QObject* plugin = (*it).first.first;
215  int bindingID = (*it).first.second;
216  int key = (*it).second.first;
217  Qt::KeyboardModifiers modifiers = (*it).second.second;
218 
219  //get plugin name
220  QString name;
221 
222  if (plugin == 0) //parent is the core
223  name = "Core";
224  else{
225 
226  BaseInterface* basePlugin = qobject_cast< BaseInterface * >(plugin);
227 
228  if (basePlugin)
229  name = basePlugin->name();
230  else{
231  //name not found so skip it
232  continue;
233  }
234  }
235 
236  //get corresponding the pluginInfo object
237  int i = -1;
238 
239  if (name != "Core"){
240  i = getPluginInfo(name);
241 
242  if (i == -1) //if pluginInfo was not found ->skip
243  continue;
244  }
245 
246  //is the toplevel item already there?
247  if ( parentMap.find(name) == parentMap.end() ){
248  parentMap[name] = new QTreeWidgetItem(keyTree, QStringList(name));
249  keyTree->addTopLevelItem( parentMap[name] );
250  }
251 
252  QTreeWidgetItem* parent = parentMap[name];
253 
254  //get the default settings
255  QString description;
256  bool multiUse;
257  int defKey;
258  Qt::KeyboardModifiers defModi;
259 
260  if (name == "Core"){
261 
262  description = coreKeys_[bindingID].description;
263  multiUse = coreKeys_[bindingID].multiUse;
264  defKey = coreKeys_[bindingID].key;
265  defModi = coreKeys_[bindingID].modifiers;
266 
267  } else {
268 
269  description = plugins_[i].keys[bindingID].description;
270  multiUse = plugins_[i].keys[bindingID].multiUse;
271  defKey = plugins_[i].keys[bindingID].key;
272  defModi = plugins_[i].keys[bindingID].modifiers;
273  }
274 
275  QStringList rows;
276 
277  //setup the strings for the shortcuts
278  QString keyString;
279 
280  if (key == -1 && modifiers == 0){
281  keyString = "unassigned";
282  }else if (key == Qt::Key_AltGr || key == Qt::Key_Alt || key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta){
283  keyString = QKeySequence( modifiers ).toString();
284  keyString = keyString.left(keyString.size()-1);
285  }else
286  keyString = QKeySequence( key + modifiers ).toString();
287 
288  QString defaultStr;
289 
290  if (defKey == -1 && defModi == 0){
291  defaultStr = "unassigned";
292  }else if (defKey == Qt::Key_AltGr || defKey == Qt::Key_Alt || defKey == Qt::Key_Control
293  || defKey == Qt::Key_Shift || defKey == Qt::Key_Meta){
294  defaultStr = QKeySequence( defModi ).toString();
295  defaultStr = defaultStr.left(defaultStr.size()-1);
296  }else
297  defaultStr = QKeySequence( defKey + defModi ).toString();
298 
299  //and add the row
300  rows << description << keyString << defaultStr << QString::number(bindingID) << QString::number(key)
301  << QString::number(modifiers) << QString::number(multiUse) << keyString;
302 
303  QTreeWidgetItem* keyItem = new QTreeWidgetItem(parent, rows);
304 
305  parent->addChild( keyItem );
306  }
307 
308 
309  keyTree->setColumnWidth(0,350);
310  keyTree->setColumnHidden(3, true);
311  keyTree->setColumnHidden(4, true);
312  keyTree->setColumnHidden(5, true);
313  keyTree->setColumnHidden(6, true);
314  keyTree->setColumnHidden(7, true);
315 }
int getPluginInfo(QString pluginName)
get the pluginInfo object corresponding to the given pluginName
Definition: keyBindings.cc:50
void keyTreeDoubleClicked(QTreeWidgetItem *_item, int col)
doubleclick in the keyTree
Definition: keyBindings.cc:59
void applyShortcuts()
check which of the shortcuts changed and inform the core about the change
Definition: keyBindings.cc:123
virtual QString name()=0
Return a name for the plugin.
void restoreKeyPresets()
restore keyBinding Presets
Definition: keyBindings.cc:159
void initKeyTree()
init the TreeWidget containing the keyBindings
Definition: keyBindings.cc:196
void updateShortcut()
check if the shortcut exists and add it if not
Definition: keyBindings.cc:86
Interface class from which all plugins have to be created.
void keyTreeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
keyBinding TreeWidget-Item changed
Definition: keyBindings.cc:70