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 #include <OpenFlipper/BasePlugin/BaseInterface.hh>
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
86 void OptionsWidget::updateShortcut(){
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
123 void OptionsWidget::applyShortcuts(){
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
159 void OptionsWidget::restoreKeyPresets(){
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
196 void OptionsWidget::initKeyTree(){
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 }
OptionsWidget::getPluginInfo
int getPluginInfo(QString pluginName)
get the pluginInfo object corresponding to the given pluginName
Definition: keyBindings.cc:50
OptionsWidget::keyTreeDoubleClicked
void keyTreeDoubleClicked(QTreeWidgetItem *_item, int col)
doubleclick in the keyTree
Definition: keyBindings.cc:59
OptionsWidget::applyShortcuts
void applyShortcuts()
check which of the shortcuts changed and inform the core about the change
Definition: keyBindings.cc:123
BaseInterface::name
virtual QString name()=0
Return a name for the plugin.
OptionsWidget::restoreKeyPresets
void restoreKeyPresets()
restore keyBinding Presets
Definition: keyBindings.cc:159
OptionsWidget::initKeyTree
void initKeyTree()
init the TreeWidget containing the keyBindings
Definition: keyBindings.cc:196
OptionsWidget::updateShortcut
void updateShortcut()
check if the shortcut exists and add it if not
Definition: keyBindings.cc:86
BaseInterface
Interface class from which all plugins have to be created.
Definition: BaseInterface.hh:65
BaseInterface.hh
OptionsWidget::keyTreeItemChanged
void keyTreeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
keyBinding TreeWidget-Item changed
Definition: keyBindings.cc:70