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 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
51 
52 #include "optionsWidget.hh"
53 
55 int OptionsWidget::getPluginInfo(QString pluginName){
56  for (uint i=0; i < plugins_.size(); i++)
57  if (plugins_[i].name == pluginName)
58  return i;
59 
60  return -1;
61 }
62 
64 void OptionsWidget::keyTreeDoubleClicked(QTreeWidgetItem* _item, int /*col*/){
65 
66 std::cerr << "set focus\n";
67 
68  if (_item == 0 || _item->parent() == 0 || _item->columnCount() < 7)
69  return;
70 
71  shortcutButton->setFocus(Qt::TabFocusReason);
72 }
73 
75 void OptionsWidget::keyTreeItemChanged( QTreeWidgetItem* current, QTreeWidgetItem* /*previous*/){
76 
77  if (current == 0 || current->parent() == 0 || current->columnCount() < 7){
78  shortcutBox->setEnabled(false);
79  shortcutButton->setText("");
80  defaultShortcut->setText("");
81  }else{
82  shortcutBox->setEnabled(true);
83 
84  shortcutButton->setCurrentShortcut( current->text(4).toInt(), (Qt::KeyboardModifiers) current->text(5).toInt() );
85  defaultShortcut->setText( current->text(2) );
86  }
87 
88 }
89 
92 
93  if ( keyTree->currentItem() == 0)
94  return;
95 
96  bool myMultiUse = (bool) keyTree->currentItem()->text(6).toInt();
97  QString myNewKey = shortcutButton->text();
98 
99  //check if the shortcut already exists
100  for (int i=0; i < keyTree->topLevelItemCount(); i++)
101  for (int j=0; j < keyTree->topLevelItem(i)->childCount(); j++){
102 
103  QTreeWidgetItem* item = keyTree->topLevelItem(i)->child(j);
104  QString key = item->text(1);
105  bool multiUse = (bool) item->text(6).toInt();
106 
107  if (keyTree->currentItem() == item)
108  continue;
109 
110  if (key == myNewKey && ( !multiUse || !myMultiUse ) ){
111  QMessageBox::warning(this, tr("OpenFlipper"), tr("Could not add Shortcut. Shortcut already assigned."), QMessageBox::Ok);
112  return;
113  }
114  }
115 
116  //update the item
117  if ( keyTree->currentItem() != 0){
118  keyTree->currentItem()->setText( 1, shortcutButton->text() );
119  keyTree->currentItem()->setText( 4, QString::number( shortcutButton->key() ) );
120  keyTree->currentItem()->setText( 5, QString::number( shortcutButton->modifiers() ) );
121  }
122 
123  keyTree->setFocus(Qt::TabFocusReason);
124  keyTreeItemChanged(keyTree->currentItem(), 0);
125 }
126 
129 
130  //check all shortcuts
131  for (int i=0; i < keyTree->topLevelItemCount(); i++)
132  for (int j=0; j < keyTree->topLevelItem(i)->childCount(); j++){
133 
134  //check wether the shortcut changed
135  QTreeWidgetItem* item = keyTree->topLevelItem(i)->child(j);
136 
137  if ( item->text(1) != item->text(7) ){
138 
139  QString pluginName = item->parent()->text(0);
140 
141  QObject* plugin = 0;
142 
143  if (pluginName != "Core"){
144 
145  //get the plugin object
146  int index = getPluginInfo(pluginName);
147 
148  if (index == -1) //if pluginInfo was not found ->skip
149  continue;
150 
151  plugin = plugins_[index].plugin;
152  }
153 
154  int bindingID = item->text(3).toInt();
155  int key = item->text(4).toInt();
156 
157  Qt::KeyboardModifiers modi = (Qt::KeyboardModifiers) item->text(5).toInt();
158 
159  emit addKeyMapping(key, modi, plugin, bindingID);
160  }
161  }
162 }
163 
165 
166  //check if the shortcut already exists
167  for (int i=0; i < keyTree->topLevelItemCount(); i++)
168  for (int j=0; j < keyTree->topLevelItem(i)->childCount(); j++){
169 
170  QTreeWidgetItem* item = keyTree->topLevelItem(i)->child(j);
171  QString key = item->text(1);
172 
173  QString pluginName = item->parent()->text(0);
174  int bindingID = item->text(3).toInt();
175 
176  if (pluginName == "Core"){
177 
178  item->setText( 1, item->text(2) );
179  item->setText( 4, QString::number(coreKeys_[ bindingID ].key) );
180  item->setText( 5, QString::number(coreKeys_[ bindingID ].modifiers) );
181 
182  } else {
183 
184  //get the plugin object
185  int index = getPluginInfo(pluginName);
186 
187  if (index == -1) //if pluginInfo was not found ->skip
188  continue;
189 
190  item->setText( 1, item->text(2) );
191  item->setText( 4, QString::number(plugins_[index].keys[ bindingID ].key) );
192  item->setText( 5, QString::number(plugins_[index].keys[ bindingID ].modifiers) );
193  }
194  }
195 
196  keyTree->setFocus(Qt::TabFocusReason);
197  keyTreeItemChanged(keyTree->currentItem(), 0);
198 }
199 
202 
203  keyTree->clear();
204 
205  keyTree->setEditTriggers(QAbstractItemView::NoEditTriggers);
206 
207  keyTree->setColumnCount ( 8 );
208 
209  QStringList headerdata;
210  headerdata << "Action" << "Shortcut" << "Default" << "keyIndex" << "currentKey" << "currentModi" << "MultiUse" << "initShortcut";
211  keyTree->setHeaderLabels(headerdata);
212 
213  //fill the keyTree
214  std::map< QString, QTreeWidgetItem* > parentMap;
215 
216  InverseKeyMap::iterator it;
217  for (it=keys_.begin(); it != keys_.end(); ++it){
218 
219  QObject* plugin = (*it).first.first;
220  int bindingID = (*it).first.second;
221  int key = (*it).second.first;
222  Qt::KeyboardModifiers modifiers = (*it).second.second;
223 
224  //get plugin name
225  QString name;
226 
227  if (plugin == 0) //parent is the core
228  name = "Core";
229  else{
230 
231  BaseInterface* basePlugin = qobject_cast< BaseInterface * >(plugin);
232 
233  if (basePlugin)
234  name = basePlugin->name();
235  else{
236  //name not found so skip it
237  continue;
238  }
239  }
240 
241  //get corresponding the pluginInfo object
242  int i = -1;
243 
244  if (name != "Core"){
245  i = getPluginInfo(name);
246 
247  if (i == -1) //if pluginInfo was not found ->skip
248  continue;
249  }
250 
251  //is the toplevel item already there?
252  if ( parentMap.find(name) == parentMap.end() ){
253  parentMap[name] = new QTreeWidgetItem(keyTree, QStringList(name));
254  keyTree->addTopLevelItem( parentMap[name] );
255  }
256 
257  QTreeWidgetItem* parent = parentMap[name];
258 
259  //get the default settings
260  QString description;
261  bool multiUse;
262  int defKey;
263  Qt::KeyboardModifiers defModi;
264 
265  if (name == "Core"){
266 
267  description = coreKeys_[bindingID].description;
268  multiUse = coreKeys_[bindingID].multiUse;
269  defKey = coreKeys_[bindingID].key;
270  defModi = coreKeys_[bindingID].modifiers;
271 
272  } else {
273 
274  description = plugins_[i].keys[bindingID].description;
275  multiUse = plugins_[i].keys[bindingID].multiUse;
276  defKey = plugins_[i].keys[bindingID].key;
277  defModi = plugins_[i].keys[bindingID].modifiers;
278  }
279 
280  QStringList rows;
281 
282  //setup the strings for the shortcuts
283  QString keyString;
284 
285  if (key == -1 && modifiers == 0){
286  keyString = "unassigned";
287  }else if (key == Qt::Key_AltGr || key == Qt::Key_Alt || key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Meta){
288  keyString = QKeySequence( modifiers ).toString();
289  keyString = keyString.left(keyString.size()-1);
290  }else
291  keyString = QKeySequence( key + modifiers ).toString();
292 
293  QString defaultStr;
294 
295  if (defKey == -1 && defModi == 0){
296  defaultStr = "unassigned";
297  }else if (defKey == Qt::Key_AltGr || defKey == Qt::Key_Alt || defKey == Qt::Key_Control
298  || defKey == Qt::Key_Shift || defKey == Qt::Key_Meta){
299  defaultStr = QKeySequence( defModi ).toString();
300  defaultStr = defaultStr.left(defaultStr.size()-1);
301  }else
302  defaultStr = QKeySequence( defKey + defModi ).toString();
303 
304  //and add the row
305  rows << description << keyString << defaultStr << QString::number(bindingID) << QString::number(key)
306  << QString::number(modifiers) << QString::number(multiUse) << keyString;
307 
308  QTreeWidgetItem* keyItem = new QTreeWidgetItem(parent, rows);
309 
310  parent->addChild( keyItem );
311  }
312 
313 
314  keyTree->setColumnWidth(0,350);
315  keyTree->setColumnHidden(3, true);
316  keyTree->setColumnHidden(4, true);
317  keyTree->setColumnHidden(5, true);
318  keyTree->setColumnHidden(6, true);
319  keyTree->setColumnHidden(7, true);
320 }
void initKeyTree()
init the TreeWidget containing the keyBindings
Definition: keyBindings.cc:201
void applyShortcuts()
check which of the shortcuts changed and inform the core about the change
Definition: keyBindings.cc:128
Interface class from which all plugins have to be created.
void restoreKeyPresets()
restore keyBinding Presets
Definition: keyBindings.cc:164
virtual QString name()=0
Return a name for the plugin.
void keyTreeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
keyBinding TreeWidget-Item changed
Definition: keyBindings.cc:75
int getPluginInfo(QString pluginName)
get the pluginInfo object corresponding to the given pluginName
Definition: keyBindings.cc:55
void updateShortcut()
check if the shortcut exists and add it if not
Definition: keyBindings.cc:91
void keyTreeDoubleClicked(QTreeWidgetItem *_item, int col)
doubleclick in the keyTree
Definition: keyBindings.cc:64