keyHandling.cc 23.3 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40
41
42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43
44
45
46
47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
49
\*===========================================================================*/

Dirk Wilden's avatar
Dirk Wilden committed
50
51
52
#include "CoreWidget.hh"

#include <OpenFlipper/BasePlugin/KeyInterface.hh>
Jan Möbius's avatar
   
Jan Möbius committed
53

Dirk Wilden's avatar
Dirk Wilden committed
54
55
56
57
58
59
60
61
62
63
64
//-----------------------------------------------------------------------------

KeyBinding CoreWidget::getKeyBinding(QObject* _plugin, int _keyIndex ){
  if (_plugin == 0)
    return coreKeys_[_keyIndex];

  for (uint i=0; i < plugins_.size(); i++){
    if (plugins_[i].plugin == _plugin)
      return plugins_[i].keys[_keyIndex];
  }

65
  emit log(LOGERR,tr("ERROR: could not get KeyBinding"));
Dirk Wilden's avatar
Dirk Wilden committed
66
67
68
  return KeyBinding();
}

Dirk Wilden's avatar
Dirk Wilden committed
69
70
71
72
73
74
75
76
77
QString CoreWidget::getRPCName(QObject* _plugin ){
  if (_plugin == 0)
    return "";

  for (uint i=0; i < plugins_.size(); i++){
    if (plugins_[i].plugin == _plugin)
      return plugins_[i].rpcName;
  }

78
  emit log(LOGERR,tr("ERROR: could not get rpcname"));
Dirk Wilden's avatar
Dirk Wilden committed
79
80
81
  return "";
}

Dirk Wilden's avatar
Dirk Wilden committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/// passes keyPressEvents to either the Core or a Plugin depending on who has registered the key
void CoreWidget::keyPressEvent(QKeyEvent* _e)
{
  std::pair< int,Qt::KeyboardModifiers > key = std::make_pair(_e->key(), _e->modifiers() );

  //iterate over all assigned keys
  KeyRange range = keys_.equal_range(key);

  KeyMap::iterator it;
  for (it=range.first; it != range.second; ++it){

    QObject* plugin = (*it).second.first;
    KeyBinding binding = getKeyBinding( plugin, (*it).second.second );

    //check if its a core Key
    if (plugin == 0){
Dirk Wilden's avatar
Dirk Wilden committed
98
99
100
101
102
103
104
105

      //the key belongs to a slot
      if (binding.slot){
        bool ok;
        emit call("core." + binding.description, ok);
        return;
      }

106
107
108
109
      // =================================================================================
      // Map event to the cores key and modifier.
      // Call the core key handler with the mapped event.
      // =================================================================================
Matthias Möller's avatar
Matthias Möller committed
110
111
      QKeyEvent mappedEvent (_e->type(),binding.key, binding.modifiers,
                             _e->text(), _e->isAutoRepeat(), _e->count() );
Dirk Wilden's avatar
Dirk Wilden committed
112

Matthias Möller's avatar
Matthias Möller committed
113
      coreKeyPressEvent(&mappedEvent);
Dirk Wilden's avatar
Dirk Wilden committed
114
115
116
117
118
119
120
121
122

      //if the key is multiUse also check other assigned keys
      if (binding.multiUse)
        continue;
      else
        return;
    }

    //it's a plugin key
Dirk Wilden's avatar
Dirk Wilden committed
123
124
125
126
127
128
129
130
131

    //the key belongs to a slot
    if (binding.slot){
      bool ok;
      emit call(getRPCName(plugin) +"."+ binding.description, ok);
      return;
    }

    //the key was specified through keyInterface
Dirk Wilden's avatar
Dirk Wilden committed
132
133
134
    KeyInterface* keyPlugin = qobject_cast< KeyInterface * >(plugin);

    if (keyPlugin){
135
136
137
138
139

      // =================================================================================
      // Map event to the plugins key and modifier.
      // Call it with the mapped event.
      // =================================================================================
Matthias Möller's avatar
Matthias Möller committed
140
141
      QKeyEvent mappedEvent(_e->type(),binding.key, binding.modifiers,
                             _e->text(), _e->isAutoRepeat(), _e->count() );
142

Matthias Möller's avatar
Matthias Möller committed
143
      keyPlugin->slotKeyEvent(&mappedEvent);
Dirk Wilden's avatar
Dirk Wilden committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    }

    //if its not a multiUse key we are ready
    if (!binding.multiUse)
      return;
  }
}

//-----------------------------------------------------------------------------

/// passes keyReleaseEvents to either the Core or a Plugin depending on who has registered the key
void CoreWidget::keyReleaseEvent(QKeyEvent* _e) {

  if (_e->isAutoRepeat()) return; //consider only "real" release events

  std::pair< int,Qt::KeyboardModifiers > key = std::make_pair(_e->key(), _e->modifiers() );

  //iterate over all assigned keys
  KeyRange range = keys_.equal_range(key);

  KeyMap::iterator it;
  for (it=range.first; it != range.second; ++it){

    QObject* plugin = (*it).second.first;
    KeyBinding binding = getKeyBinding( plugin, (*it).second.second );

    if (plugin == 0){
171
172
173
174
175

      // =================================================================================
      // Map event to the cores key and modifier.
      // Call the core key handler with the mapped event.
      // =================================================================================
Matthias Möller's avatar
Matthias Möller committed
176
177
178
      QKeyEvent mappedEvent (_e->type(),binding.key, binding.modifiers,
                             _e->text(), _e->isAutoRepeat(), _e->count() );
      coreKeyReleaseEvent(&mappedEvent);
Dirk Wilden's avatar
Dirk Wilden committed
179
180
181
182
183
184
185
186
187
188
189
190

      //if the key is multiUse also check other assigned keys
      if (binding.multiUse)
        continue;
      else
        return;
    }

    //it's a plugin key
    KeyInterface* keyPlugin = qobject_cast< KeyInterface * >(plugin);

    if (keyPlugin){
191
192
193
194
195
196

      // =================================================================================
      // Map event to the plugins key and modifier.
      // Call the plugin with the mapped event.
      // =================================================================================

Matthias Möller's avatar
Matthias Möller committed
197
198
      QKeyEvent mappedEvent (_e->type(),binding.key, binding.modifiers,
                             _e->text(), _e->isAutoRepeat(), _e->count() );
199

Matthias Möller's avatar
Matthias Möller committed
200
      keyPlugin->slotKeyReleaseEvent(&mappedEvent);
Dirk Wilden's avatar
Dirk Wilden committed
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    }

    //if its not a multiUse key we are ready
    if (!binding.multiUse)
      return;
  }
}

//-----------------------------------------------------------------------------

/// Register a key to the core or a plugin
void CoreWidget::slotRegisterKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description, bool _multiUse){

  //first check if the key is already registered by the coreWidget
  bool found = false;
  bool multi = false;
217
  QString name;
Dirk Wilden's avatar
Dirk Wilden committed
218
219
220
221
  for (uint i=0; i < coreKeys_.size(); i++)
    if (coreKeys_[i].key == _key && coreKeys_[i].modifiers == _modifiers){
      found = true;
      multi = coreKeys_[i].multiUse;
222
      name = "Core";
Dirk Wilden's avatar
Dirk Wilden committed
223
224
225
226
227
228
229
230
231
232
233
      break;
    }

  //then check if the key is already registered by a different plugin
  if (!found)
    for (uint i=0; i < plugins_.size(); i++)
      for (int k=0; k < plugins_[i].keys.count(); k++)
        if (plugins_[i].keys[k].key == _key
        && plugins_[i].keys[k].modifiers == _modifiers){
          found = true;
          multi = plugins_[i].keys[k].multiUse;
234
          name = plugins_[i].name;
Dirk Wilden's avatar
Dirk Wilden committed
235
236
237
          break;
        }

238
  if (found && !multi)
Jan Möbius's avatar
Jan Möbius committed
239
    emit log(LOGERR, tr("Key already registered by '%1'").arg( name ) );
Dirk Wilden's avatar
Dirk Wilden committed
240
241
242
243
244
245
246
247

  //check if its a key for the core
  if (sender() == this){
    KeyBinding kb;
    kb.key = _key;
    kb.modifiers = _modifiers;
    kb.description = _description;
    kb.multiUse = multi || _multiUse;
Dirk Wilden's avatar
Dirk Wilden committed
248
    kb.slot = false;
Dirk Wilden's avatar
Dirk Wilden committed
249
250

    if (multi && !_multiUse)
Jan Möbius's avatar
Jan Möbius committed
251
      emit log(LOGERR, tr("Key already registered by '%1'. Forced registration as multiUse key.").arg( name ));
Dirk Wilden's avatar
Dirk Wilden committed
252
253
254

    coreKeys_.push_back( kb );

255
256
    keys_.insert( std::make_pair( std::make_pair(_key, _modifiers) , std::make_pair ((QObject*)0, int(coreKeys_.size()-1 ) ) )) ;
    invKeys_.insert( std::make_pair( std::make_pair ((QObject*)0, int(coreKeys_.size()-1) ) , std::make_pair(_key, _modifiers) ) );
Dirk Wilden's avatar
Dirk Wilden committed
257
258
259
260
261
262
263
264
265
266
267
    return;
  }

  //find plugin
 PluginInfo* pluginInfo = 0;

  for (uint i=0; i < plugins_.size(); i++)
    if (plugins_[i].plugin == sender())
      pluginInfo = &plugins_[i];

  if (pluginInfo == 0){
268
    emit log(LOGERR, tr("Unable to register key. Plugin not found!"));
Dirk Wilden's avatar
Dirk Wilden committed
269
270
271
272
273
274
275
276
    return;
  }

  KeyBinding kb;
  kb.key = _key;
  kb.modifiers = _modifiers;
  kb.description = _description;
  kb.multiUse = multi || _multiUse;
Dirk Wilden's avatar
Dirk Wilden committed
277
  kb.slot = false;
Dirk Wilden's avatar
Dirk Wilden committed
278
279

  if (multi && !_multiUse)
Jan Möbius's avatar
Jan Möbius committed
280
    emit log(LOGERR, tr("Key already registered by '%1'. Forced registration as multiUse key.").arg( name ));
Dirk Wilden's avatar
Dirk Wilden committed
281
282
283
284
285
286
287

  pluginInfo->keys.append( kb );

  keys_.insert( std::make_pair( std::make_pair(_key, _modifiers) , std::make_pair(pluginInfo->plugin, pluginInfo->keys.size()-1) ) );
  invKeys_.insert( std::make_pair( std::make_pair(pluginInfo->plugin, pluginInfo->keys.size()-1) , std::make_pair(_key, _modifiers) ) );
}

Dirk Wilden's avatar
Dirk Wilden committed
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
///scripting slots will automatically registered to be assigned  to an invalid key(-1)
void CoreWidget::slotRegisterSlotKeyBindings(){

  //check the core slots
  for (int i=0; i < coreSlots_.count(); i++){

    //only consider functions without arguments
    if ( !coreSlots_.at(i).slotName.contains( "()" ) )
      continue;

    KeyBinding kb;
    kb.key = -1;
    kb.modifiers = 0;
    kb.description = coreSlots_.at(i).slotName;
    kb.multiUse = true;
    kb.slot = true;

    coreKeys_.push_back( kb );

307
308
    keys_.insert( std::make_pair( std::make_pair(-1, (QFlags<Qt::KeyboardModifier>)0) , std::make_pair ((QObject*)0, int(coreKeys_.size()-1) ) )) ;
    invKeys_.insert( std::make_pair( std::make_pair ((QObject*)0, int(coreKeys_.size()-1) ) , std::make_pair(-1, (QFlags<Qt::KeyboardModifier>)0) ) );
Dirk Wilden's avatar
Dirk Wilden committed
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  }

  //check all plugins
  for (uint i=0; i < plugins_.size(); i++)

    for (int j=0; j < plugins_[i].rpcFunctions.count(); j++){

      //only consider functions without arguments
      if ( !plugins_[i].rpcFunctions[j].contains( "()" )
         || plugins_[i].rpcFunctions[j] == "version()")
        continue;

      KeyBinding kb;
      kb.key = -1;
      kb.modifiers = 0;
      kb.description = plugins_[i].rpcFunctions[j];
      kb.multiUse = true;
      kb.slot = true;
Jan Möbius's avatar
   
Jan Möbius committed
327

Dirk Wilden's avatar
Dirk Wilden committed
328
      plugins_[i].keys.append( kb );
Jan Möbius's avatar
   
Jan Möbius committed
329

330
331
      keys_.insert( std::make_pair( std::make_pair(-1, (QFlags<Qt::KeyboardModifier>)0) , std::make_pair(plugins_[i].plugin, plugins_[i].keys.size()-1) ) );
      invKeys_.insert( std::make_pair( std::make_pair(plugins_[i].plugin, plugins_[i].keys.size()-1) , std::make_pair(-1, (QFlags<Qt::KeyboardModifier>)0) ) );
Dirk Wilden's avatar
Dirk Wilden committed
332
333
334
    }
}

Dirk Wilden's avatar
Dirk Wilden committed
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
/// add a new keyMapping (keyBindingID is the id of the keyBinding in the pluginInfo of _plugin :)
void CoreWidget::slotAddKeyMapping(int _key, Qt::KeyboardModifiers _modifiers, QObject* _plugin, int _keyBindingID){

  std::pair< int,Qt::KeyboardModifiers > keyCombi = std::make_pair(_key, _modifiers );
  std::pair< int,Qt::KeyboardModifiers > oldCombi;
  std::pair< QObject*, int > oldTarget;

  bool replace = false;

  //and check if the key is already assigned without multiUse
  KeyMap::iterator it;
  for (it=keys_.begin(); it != keys_.end(); ++it){

    int key = (*it).first.first;
    Qt::KeyboardModifiers modifiers = (*it).first.second;
    QObject* plugin = (*it).second.first;
    int bindingID = (*it).second.second;
    KeyBinding binding = getKeyBinding(plugin, bindingID);

    //check if its the keyBinding we want to map/replace
    if (plugin == _plugin && bindingID == _keyBindingID){
      replace = true;
      oldCombi = (*it).first;
      oldTarget = (*it).second;
      continue;
    }

    //check if the mapping is conflicting with other mappings
    if (_key == key && _modifiers == modifiers ){

      if (!binding.multiUse){
        if (plugin == 0)
367
          emit log(LOGERR, tr("Could not add key mapping. Key already assigned to the core."));
Dirk Wilden's avatar
Dirk Wilden committed
368
369
        else{
          BaseInterface* basePlugin = qobject_cast< BaseInterface * >(plugin);
370

Dirk Wilden's avatar
Dirk Wilden committed
371
          if (basePlugin)
Jan Möbius's avatar
Jan Möbius committed
372
            emit log(LOGERR, tr("Could not add key mapping. Key already assigned to %1").arg( basePlugin->name() ) );
Dirk Wilden's avatar
Dirk Wilden committed
373
          else
374
            emit log(LOGERR, tr("Could not add key mapping. Key already assigned to an unknown plugin."));
Dirk Wilden's avatar
Dirk Wilden committed
375
376
377
378
379
380
381
382
383
384
385
        }
        return;
      }
    }
  }

  KeyBinding keyBinding = getKeyBinding(_plugin, _keyBindingID);

  //check if new binding doesn't allow multiUse but other assignments for the key exist
  if (!keyBinding.multiUse)
    if ( (replace && keys_.count(keyCombi) > 1)  || (!replace && keys_.count(keyCombi) > 0) ){
386
      emit log(LOGERR, tr("Could not add (single usage) key mapping. Key already assigned."));
Dirk Wilden's avatar
Dirk Wilden committed
387
388
389
390
391
392
393
394
      return;
    }

  if (replace){
    keys_.erase(oldCombi);
    invKeys_.erase(oldTarget);
  }

395
396
397
398
  //now we can add the mapping
  keys_.insert   ( std::make_pair( keyCombi , std::make_pair(_plugin, _keyBindingID) ));
  invKeys_.insert( std::make_pair( std::make_pair(_plugin, _keyBindingID),  keyCombi ));

Dirk Wilden's avatar
Dirk Wilden committed
399
400
}

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
///Load key assignments from a given INI file
void CoreWidget::loadKeyBindings(INIFile& _ini){

  QVector< int > keys;
  QVector< int > modifiers;
  QStringList pluginNames;
  QVector< int > bindingIDs;

  //first load everything from INI file
  if ( !_ini.section_exists("KeyBindings") )
     return;

  int keyCount;
  if (_ini.get_entry(keyCount,"KeyBindings","KeyCount") ){

    int key;
    int mod;
    QString name;
    int binding;

    for (int i=0; i < keyCount; i++){

      if (!_ini.get_entry(key,     "KeyBindings","Key" + QString::number(i) ) ) continue;
      if (!_ini.get_entry(mod,     "KeyBindings","KeyModifiers" + QString::number(i) ) )  continue;
      if (!_ini.get_entry(name,    "KeyBindings","KeyTarget" + QString::number(i) ) )  continue;
      if (!_ini.get_entry(binding, "KeyBindings","KeyBinding" + QString::number(i) ) ) continue;

      keys.push_back( key );
      modifiers.push_back( mod );
      pluginNames.push_back( name );
      bindingIDs.push_back( binding );
    }
  }

  //add the keyMapping
  for (int i=0; i < keys.count(); i++){

    //first we need the plugin
    QObject* plugin = 0;

    if (pluginNames[i] != "Core" ){
      //search for the plugin
      for (uint i=0; i < plugins_.size(); i++)
        if (plugins_[i].rpcName == pluginNames[i] ){
          plugin = plugins_[i].plugin;
          break;
        }

      if (plugin == 0)
        continue; //because plugin was not found
    }

    slotAddKeyMapping( keys[i], (Qt::KeyboardModifiers) modifiers[i], plugin, bindingIDs[i] );
  }

}

///Store current key assignments to a given INI file
void CoreWidget::saveKeyBindings(INIFile& _ini){

  QVector< int > keys;
  QVector< int > modifiers;
  QStringList pluginNames;
  QVector< int > bindingIDs;

  //first get all keys with custom assignments
  KeyMap::iterator it;
  for (it=keys_.begin(); it != keys_.end(); ++it){

    int key = (*it).first.first;
    Qt::KeyboardModifiers mod = (*it).first.second;
    QObject* plugin = (*it).second.first;
    int bindingID = (*it).second.second;
    KeyBinding binding = getKeyBinding(plugin, bindingID);

    //check if current key assignment and original assignment differ
    if (key != binding.key || mod != binding.modifiers){

      //get the pluginName
      QString name;

      if (plugin == 0)
        name = "Core";
      else
        name = getRPCName(plugin);

      //store key assignment
      keys.push_back( key );
      modifiers.push_back( mod );
      pluginNames.push_back( name );
      bindingIDs.push_back( bindingID );
    }
  }

  //finally store everything to INI file
  _ini.add_entry("KeyBindings","KeyCount", keys.count());

  for (int i=0; i < keys.count(); i++){

    _ini.add_entry("KeyBindings","Key" + QString::number(i)         , keys[i] );
    _ini.add_entry("KeyBindings","KeyModifiers" + QString::number(i), modifiers[i] );
    _ini.add_entry("KeyBindings","KeyTarget" + QString::number(i)   , pluginNames[i] );
    _ini.add_entry("KeyBindings","KeyBinding" + QString::number(i)  , bindingIDs[i] );
  }
}

507
/// if a keyPressEvent belongs to the core this functions is called
Jan Möbius's avatar
Jan Möbius committed
508
void CoreWidget::registerCoreKeys() {
509
510

  //register keys for coreWidget
Jan Möbius's avatar
Jan Möbius committed
511
512
  connect(this , SIGNAL( registerKey(int, Qt::KeyboardModifiers, QString, bool) ),
          this , SLOT(slotRegisterKey(int, Qt::KeyboardModifiers, QString, bool)) );
513

Jan Möbius's avatar
Jan Möbius committed
514
  emit registerKey(Qt::Key_Print  , Qt::NoModifier, "Create Snapshot");
515
516
517
  emit registerKey(Qt::Key_Escape , Qt::NoModifier, "Switch to last action mode ( Move,Picking,Light or Info Mode)");
  emit registerKey(Qt::Key_Space  , Qt::NoModifier, "Toggle between multiview and single view");

518
519
  emit registerKey(Qt::Key_S      , Qt::ControlModifier, "Save Object");
  emit registerKey(Qt::Key_O      , Qt::ControlModifier, "Open Object");
Jan Möbius's avatar
Jan Möbius committed
520
521
522
  emit registerKey(Qt::Key_L      , Qt::ControlModifier, "Show/Hide Logger");
  emit registerKey(Qt::Key_T      , Qt::ControlModifier, "Show/Hide Toolbox");
  emit registerKey(Qt::Key_F      , Qt::ControlModifier, "Toggle Fullscreen");
523
  emit registerKey(Qt::Key_B      , Qt::ControlModifier, "Show/Hide StatusBar");
524
  emit registerKey(Qt::Key_N      , Qt::ControlModifier, "Show/Hide ToolBar");
525
  emit registerKey(Qt::Key_M      , Qt::ControlModifier, "Show/Hide MenuBar");
526

527

528
529
530
  if ( OpenFlipper::Options::isLinux() ) {
    emit registerKey(Qt::Key_Meta , Qt::MetaModifier, "Use Navigation mode while key is pressed");
    emit registerKey(Qt::Key_Meta , Qt::NoModifier, "Use Navigation mode while key is pressed");
Matthias Möller's avatar
Matthias Möller committed
531
532
533
534
    emit registerKey(Qt::Key_Super_L , Qt::NoModifier, "Use Navigation mode while key is pressed");
    emit registerKey(Qt::Key_Super_L , Qt::MetaModifier, "Use Navigation mode while key is pressed");
    emit registerKey(Qt::Key_Super_R , Qt::NoModifier, "Use Navigation mode while key is pressed");
    emit registerKey(Qt::Key_Super_R , Qt::MetaModifier, "Use Navigation mode while key is pressed");
535
  } else {
536
537
    emit registerKey(Qt::Key_Alt  , Qt::AltModifier, "Use Navigation mode while key is pressed");
    emit registerKey(Qt::Key_Alt  , Qt::NoModifier, "Use Navigation mode while key is pressed");
538
539
  }

Dirk Wilden's avatar
Dirk Wilden committed
540
541
  emit registerKey(Qt::Key_Shift  , Qt::ShiftModifier, "Apply context menu action to all Viewers", true);
  emit registerKey(Qt::Key_Shift  , Qt::NoModifier, "Apply context menu action to all Viewers", true);
542
543
  
  
544
545
546
547
  emit registerKey(Qt::Key_A      , Qt::NoModifier, "First Person view strafe left");
  emit registerKey(Qt::Key_D      , Qt::NoModifier, "First Person view strafe right");
  emit registerKey(Qt::Key_W      , Qt::NoModifier, "First Person view move forward");
  emit registerKey(Qt::Key_S      , Qt::NoModifier, "First Person view move back");
548
  
549
550
}

Dirk Wilden's avatar
Dirk Wilden committed
551
552
/// if a keyPressEvent belongs to the core this functions is called
void CoreWidget::coreKeyPressEvent  (QKeyEvent* _e){
Jan Möbius's avatar
Jan Möbius committed
553
  //emit log(LOGERR,"Key Press");
Matthias Möller's avatar
Matthias Möller committed
554
555
  if ( (( _e->key() == Qt::Key_Meta ) || (_e->key() == Qt::Key_Super_L) || (_e->key() == Qt::Key_Super_R))
      && OpenFlipper::Options::isLinux() ) {
Jan Möbius's avatar
   
Jan Möbius committed
556

Matthias Möller's avatar
Matthias Möller committed
557
558
559
560
561
    if ( lastActionMode() == actionMode()) {
      if (actionMode() == Viewer::PickingMode)
        setActionMode( Viewer::ExamineMode );
      else
        setActionMode( Viewer::PickingMode );
562
    }
Matthias Möller's avatar
Matthias Möller committed
563
564
    else
      setActionMode(lastActionMode());
565
566
567
  }

  if ( ( _e->key() == Qt::Key_Alt ) && ! OpenFlipper::Options::isLinux() ) {
Matthias Möller's avatar
Matthias Möller committed
568
569
570
571
572
573
    //emit log(LOGERR,"Switch to examine mode");
    if ( lastActionMode() == actionMode()) {
      if (actionMode() == Viewer::PickingMode)
        setActionMode( Viewer::ExamineMode );
      else
        setActionMode( Viewer::PickingMode );
574
    }
Matthias Möller's avatar
Matthias Möller committed
575
576
    else
      setActionMode(lastActionMode());
577
578
579
  }


Jan Möbius's avatar
Jan Möbius committed
580
  if (_e->modifiers() & Qt::ControlModifier ) {
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
581
    switch (_e->key()) {
582
583
584
585
      case Qt::Key_B :
          toggleStatusBar();
        return;

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
586
587
588
      case Qt::Key_F :
          toggleFullscreen();
        return;
Dirk Wilden's avatar
Dirk Wilden committed
589

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
590
591
592
      case Qt::Key_L :
          toggleLogger();
        return;
Dirk Wilden's avatar
Dirk Wilden committed
593

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
594
595
596
      case Qt::Key_T :
          toggleToolbox();
        return;
Dirk Wilden's avatar
Dirk Wilden committed
597

598
      case Qt::Key_M :
599
        toggleMenuBar();
600
601
        return;

602
      case Qt::Key_N:
603
          toggleToolBar();
604
605
        return;

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
606
607
      case Qt::Key_O :
        loadMenu();
608
        return;
Dirk Wilden's avatar
Dirk Wilden committed
609

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
610
611
612
613
614
      case Qt::Key_S :
        saveMenu();
      default:
        return;
    }
615

Dirk Wilden's avatar
Dirk Wilden committed
616
617
  }

Jan Möbius's avatar
Jan Möbius committed
618
  switch (_e->key()) {
619
    
Jan Möbius's avatar
Jan Möbius committed
620
    case Qt::Key_Escape:
621
        setActionMode( lastActionMode() );
Jan Möbius's avatar
Jan Möbius committed
622
      break;
Dirk Wilden's avatar
Dirk Wilden committed
623

Jan Möbius's avatar
Jan Möbius committed
624
625
626
627
    case Qt::Key_Print:
      std::cerr << "Todo : On Print Screen, create a snapshot for all viewers" << std::endl;
      break;

628
    case Qt::Key_Space:
629
      nextViewerLayout();
Dirk Wilden's avatar
Dirk Wilden committed
630
      break;
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
      
    case Qt::Key_A:
      strafeLeft();
      break;
      
    case Qt::Key_D:
      strafeRight();
      break;
      
    case Qt::Key_W:
      moveForward();
      break;      

    case Qt::Key_S:
      moveBack();
      break;      
      
Dirk Wilden's avatar
Dirk Wilden committed
648
649
    case Qt::Key_Shift :
      shiftPressed_ = true;
650
651
      break;

Jan Möbius's avatar
Jan Möbius committed
652
    default:
Dirk Wilden's avatar
Dirk Wilden committed
653
      shiftPressed_ = false;
Jan Möbius's avatar
Jan Möbius committed
654
      return;
Dirk Wilden's avatar
Dirk Wilden committed
655
656
657
658
  }
}

/// if a keyReleaseEvent belongs to the core this functions is called
Dirk Wilden's avatar
Dirk Wilden committed
659
void CoreWidget::coreKeyReleaseEvent(QKeyEvent* _e){
Dirk Wilden's avatar
Dirk Wilden committed
660

Matthias Möller's avatar
Matthias Möller committed
661
662
  if ( (( _e->key() == Qt::Key_Meta ) || (_e->key() == Qt::Key_Super_L) || (_e->key() == Qt::Key_Super_R))
      && OpenFlipper::Options::isLinux() ) {
663
664
665
      setActionMode( lastActionMode() );
  }

Jan Möbius's avatar
Jan Möbius committed
666
  //emit log(LOGERR,"Key release");
Jan Möbius's avatar
   
Jan Möbius committed
667
668

  if ( ( _e->key() == Qt::Key_Alt ) && !OpenFlipper::Options::isLinux() ) {
669
670
671
672
      setActionMode( lastActionMode() );
  }


Dirk Wilden's avatar
Dirk Wilden committed
673
674
675
676
677
678
679
  switch (_e->key()) {
    case Qt::Key_Shift :
      shiftPressed_ = false;
      break;
    default:
      return;
  }
Dirk Wilden's avatar
Dirk Wilden committed
680
}