Developer Documentation
optionsWidget.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 
45 
46 #include <OpenFlipper/ACGHelper/DrawModeConverter.hh>
47 #include <OpenFlipper/INIFile/INIFile.hh>
50 #include <ACG/GL/ShaderCache.hh>
51 
52 #include "optionsWidget.hh"
53 #include <QColorDialog>
54 #include <QOpenGLContext>
55 #include <QMessageBox>
56 
57 OptionsWidget::OptionsWidget(std::vector<PluginInfo>& _plugins, std::vector<KeyBinding>& _core, InverseKeyMap& _invKeys, QWidget *parent)
58  : QWidget(parent),
59  plugins_(_plugins),
60  coreKeys_(_core),
61  keys_(_invKeys),
62  progressDialog_(NULL),
63  restartRequired_(false),
64  exitOnClose_(false)
65 {
66  setupUi(this);
67 
68  connect(okButton,SIGNAL(clicked()),this,SLOT(slotOk()));
69  connect(applyButton,SIGNAL(clicked()),this,SLOT(slotApply()));
70  connect(cancelButton,SIGNAL(clicked()),this,SLOT(slotCancel()));
71  connect(checkUpdateButton,SIGNAL(clicked()),this,SLOT(slotCheckUpdates()));
72  connect(updateButton,SIGNAL(clicked()),this,SLOT(slotGetUpdates()));
73  updateButton->setEnabled(false);
74 
75  // Files
76  connect(pbReloadShaders,SIGNAL(clicked()),this,SLOT(slotReloadShaders()));
77 
78  // OpenGL versions
79  VersionComboBox->clear();
80  VersionComboBox->addItem("4.6",QVariant::fromValue(QPair<int, int>(4,6)));
81  VersionComboBox->addItem("4.5",QVariant::fromValue(QPair<int, int>(4,5)));
82  VersionComboBox->addItem("4.4",QVariant::fromValue(QPair<int, int>(4,4)));
83  VersionComboBox->addItem("4.3",QVariant::fromValue(QPair<int, int>(4,3)));
84  VersionComboBox->addItem("4.2",QVariant::fromValue(QPair<int, int>(4,2)));
85  VersionComboBox->addItem("4.1",QVariant::fromValue(QPair<int, int>(4,1)));
86  VersionComboBox->addItem("4.0",QVariant::fromValue(QPair<int, int>(4,0)));
87  VersionComboBox->addItem("3.3",QVariant::fromValue(QPair<int, int>(3,3)));
88  VersionComboBox->addItem("3.2",QVariant::fromValue(QPair<int, int>(3,2)));
89  VersionComboBox->addItem("3.1",QVariant::fromValue(QPair<int, int>(3,1)));
90  VersionComboBox->addItem("3.0",QVariant::fromValue(QPair<int, int>(3,0)));
91  VersionComboBox->addItem("2.1",QVariant::fromValue(QPair<int, int>(2,1)));
92  VersionComboBox->addItem("2.0",QVariant::fromValue(QPair<int, int>(2,0)));
93  VersionComboBox->addItem("1.5",QVariant::fromValue(QPair<int, int>(1,5)));
94  VersionComboBox->addItem("1.4",QVariant::fromValue(QPair<int, int>(1,4)));
95  VersionComboBox->addItem("1.3",QVariant::fromValue(QPair<int, int>(1,3)));
96  VersionComboBox->addItem("1.2",QVariant::fromValue(QPair<int, int>(1,2)));
97  VersionComboBox->addItem("1.1",QVariant::fromValue(QPair<int, int>(1,1)));
98  VersionComboBox->addItem("1.0",QVariant::fromValue(QPair<int, int>(1,0)));
99 
100  // Viewer Settings
101  connect( restrictFPS, SIGNAL(toggled(bool)), FPS, SLOT(setEnabled(bool)) );
102  connect( viewerList, SIGNAL(currentRowChanged(int)), this, SLOT(updateViewerSettings(int)) );
103  connect( availDrawModes, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(viewerSettingsChanged(QListWidgetItem*)) );
104  connect( projectionBox, SIGNAL(currentIndexChanged(int)), this, SLOT(viewerSettingsChanged(int)));
105  connect( directionBox, SIGNAL(currentIndexChanged(int)), this, SLOT(viewerSettingsChanged(int)));
106  connect( lockRotationBox, SIGNAL(stateChanged(int)), this, SLOT(viewerSettingsChanged(int)));
107 
108  // Switch stacked widget of stereo settings
109  connect(stereoOpengl, SIGNAL(clicked()),
110  this, SLOT(switchStackedWidget()));
111  connect(stereoAnaglyph, SIGNAL(clicked()),
112  this, SLOT(switchStackedWidget()));
113  connect(stereoCustomAnaglyph, SIGNAL(clicked()),
114  this, SLOT(switchStackedWidget()));
115 
116  connect(focalDistance, SIGNAL(sliderReleased()),
117  this, SLOT(slotPreviewStereoSettings()));
118  connect(eyeDistance, SIGNAL(editingFinished()),
119  this, SLOT(slotPreviewStereoSettings()));
120 
121  ACG::SceneGraph::DrawModes::ModeFlagSet mode(2);
122  for (uint i=1; i < 22; i++) {
123  std::vector< QString > dm = drawModeToDescriptions( ACG::SceneGraph::DrawModes::DrawMode(mode) );
124 
125  if ( !dm.empty() && dm[0].trimmed() != ""){
126  QListWidgetItem* item = new QListWidgetItem(dm[0]);
127 
128  item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
129 
130  item->setCheckState(Qt::Unchecked);
131 
132  availDrawModes->addItem( item );
133  }
134 
135  mode = mode<<1;
136  }
137 
138  defaultProjectionMode_.resize(4);
139  defaultViewingDirections_.resize(4);
140  defaultRotationLocks_.resize(4);
141 
142  for ( int i=0; i < PluginFunctions::viewers(); i++ ){
143  viewerList->addItem("Viewer " + QString::number(i+1) );
144  defaultDrawModes_.push_back( ACG::SceneGraph::DrawModes::DEFAULT );
145  }
146 
147  pluginOptionsLayout = new QVBoxLayout;
148  pluginOptions->setLayout( pluginOptionsLayout );
149 
150  networkMan_ = new QNetworkAccessManager(this);
151 
152  // http specific connections
153  connect(networkMan_, SIGNAL(finished(QNetworkReply *)),
154  this, SLOT(httpRequestFinished(QNetworkReply *)));
155  connect(networkMan_,SIGNAL(authenticationRequired(QNetworkReply* , QAuthenticator *)),
156  this,SLOT(authentication(QNetworkReply *, QAuthenticator*)));
157 
158  //colordialog
159  connect(backgroundButton, SIGNAL(clicked()), this, SLOT(getBackgroundColor()) );
160  connect(defaultColorButton, SIGNAL(clicked()), this, SLOT(getDefaultColor()) );
161 
162  // Clear settings and ini buttons
163  connect(clearSettingsButton, SIGNAL(clicked()), this, SLOT(slotClearSettings()));
164  connect(clearINIButton, SIGNAL(clicked()), this, SLOT(slotClearINI()));
165 
166  // Disable update tab if app store compliant build
167  #ifdef OPENFLIPPER_BUILD_APP_STORE_COMPLIANT
168  //tabWidget->setTabEnabled(tabWidget->count()-1,false);
169  tabWidget->removeTab(tabWidget->count()-1);
170  #endif
171 }
172 
174  QColor newColor = QColorDialog::getColor ( OpenFlipperSettings().value("Core/Gui/glViewer/defaultBackgroundColor").value<QColor>() );
175 
176  backgroundColor_ = newColor;
177 
178  QPixmap color(16,16);
179  color.fill( newColor );
180  backgroundButton->setIcon( QIcon(color) );
181 }
182 
183 void OptionsWidget::getDefaultColor(){
184  QColor newColor = QColorDialog::getColor ( OpenFlipper::Options::defaultColor() );
185 
186  OpenFlipper::Options::defaultColor( newColor) ;
187 
188  QPixmap color(16,16);
189  color.fill( OpenFlipper::Options::defaultColor() );
190  defaultColorButton->setIcon( QIcon(color) );
191 }
192 
193 void OptionsWidget::viewerSettingsChanged(QListWidgetItem* /*_item*/){
195 };
196 
197 void OptionsWidget::viewerSettingsChanged(int /*_index*/){
198 
199  if ( !updatingViewerSettings_ ){
200  //viewer defaults
201  std::vector< QString > mode;
202 
203  for (int i=0; i < availDrawModes->count(); i++)
204  if (availDrawModes->item(i)->checkState() == Qt::Checked)
205  mode.push_back( availDrawModes->item(i)->text() );
206 
207  defaultDrawModes_[ viewerList->currentRow() ] = descriptionsToDrawMode(mode);
208  defaultProjectionMode_[ viewerList->currentRow() ] = projectionBox->currentIndex() ;
209  defaultViewingDirections_[ viewerList->currentRow() ] = directionBox->currentIndex();
210  defaultRotationLocks_[ viewerList->currentRow() ] = lockRotationBox->isChecked();
211 
212  if ( lockRotationBox->isChecked() )
213  std::cerr << "locked" << std::endl;
214  else
215  std::cerr << "unlocked" << std::endl;
216  }
217 };
218 
220 
221  // Show right stacked widget of stereo settings
222  if (stereoCustomAnaglyph->isChecked()) {
223  stackedWidget->setCurrentIndex(0);
224  customAnaGlyphSettings->setVisible(true);
225  } else {
226  stackedWidget->setCurrentIndex(0);
227  customAnaGlyphSettings->setVisible(false);
228  }
229 
230  // Preview new settings
232 }
233 
234 void OptionsWidget::slotTranslationIndexChanged(int /*_index*/) {
235  restartRequired_ = true;
236 }
237 
239 
240  updatingViewerSettings_ = true;
241 
242  for (int i = 0 ; i < availDrawModes->count(); ++i )
243  availDrawModes->item( i )->setCheckState(Qt::Unchecked) ;
244 
245  //Check the drawModes from StandardDrawMode
246  std::vector< QString > dm = drawModeToDescriptions( defaultDrawModes_[_row] );
247 
248  for (uint i=0; i < dm.size(); i++){
249  if ( !dm.empty() ) {
250  QList< QListWidgetItem* > found = availDrawModes->findItems(dm[i],Qt::MatchExactly);
251  for(int k=0; k < found.count(); k++)
252  (found[k])->setCheckState(Qt::Checked);
253  }
254  }
255 
256  if ( defaultProjectionMode_[_row] )
257  projectionBox->setCurrentIndex( 1 );
258  else
259  projectionBox->setCurrentIndex( 0 );
260 
261  directionBox->setCurrentIndex( defaultViewingDirections_[_row] );
262 
263  lockRotationBox->setChecked( defaultRotationLocks_[_row] );
264 
265  updatingViewerSettings_ = false;
266 }
267 
268 void OptionsWidget::showEvent ( QShowEvent * /*event*/ ) {
269 
270  //general
271  fullscreen->setChecked( OpenFlipperSettings().value("Core/Gui/fullscreen",false).toBool() );
272  splash->setChecked( OpenFlipperSettings().value("Core/Gui/splash",true).toBool() );
273  toolbox->setChecked( !OpenFlipperSettings().value("Core/Gui/ToolBoxes/hidden",false).toBool() );
274 
275  iconSmall->setChecked(false);
276  iconNormal->setChecked(false);
277  iconDefault->setChecked(false);
278 
279  switch ( OpenFlipperSettings().value("Core/Toolbar/iconSize",0).toInt() ){
280  case 1 : iconSmall->setChecked(true); break;
281  case 2 : iconNormal->setChecked(true); break;
282  default : iconDefault->setChecked(true); break;
283  }
284 
285  loggerHidden->setChecked( OpenFlipper::Options::loggerState() == OpenFlipper::Options::Hidden);
286  loggerNormal->setChecked( OpenFlipper::Options::loggerState() == OpenFlipper::Options::Normal);
287  loggerInScene->setChecked( OpenFlipper::Options::loggerState() == OpenFlipper::Options::InScene);
288  enableLogFile->setChecked( OpenFlipperSettings().value("Core/Log/logFileEnabled",true).toBool() );
289 
290  //OpenGL
291  samples_spinBox->setValue(OpenFlipper::Options::samples());
292  QPalette warning = samplesWarning->palette();
293  samplesWarning->setText(QString::number(QOpenGLContext::currentContext()->format().samples()));
294  if(OpenFlipper::Options::samples() != QOpenGLContext::currentContext()->format().samples())
295  warning.setColor(samplesWarning->foregroundRole(),Qt::red);
296  else
297  warning.setColor(samplesWarning->foregroundRole(),Qt::black);
298  samplesWarning->setPalette(warning);
299 
300  stereoCheckBox->setChecked(OpenFlipper::Options::glStereoRequested());
301  QPalette stereoWarn = stereoWarning->palette();
302  QString stereoValue;
303  QOpenGLContext::currentContext()->format().stereo() ? stereoValue = "true" : stereoValue = "false";
304  stereoWarning->setText(stereoValue);
305  QOpenGLContext::currentContext()->format().stereo() == OpenFlipper::Options::glStereoRequested() ?
306  stereoWarn.setColor(stereoWarning->foregroundRole(), Qt::black) :
307  stereoWarn.setColor(stereoWarning->foregroundRole(), Qt::red);
308  stereoWarning->setPalette(stereoWarn);
309 
310  VersionComboBox->setCurrentIndex( VersionComboBox->findData(QVariant::fromValue(OpenFlipper::Options::glVersion())));
311  QPalette version = versionWarning->palette();
312  versionWarning->setText(QString("%1.%2").arg(QOpenGLContext::currentContext()->format().version().first)
313  .arg(QOpenGLContext::currentContext()->format().version().second));
314  if(OpenFlipper::Options::glVersion() != QOpenGLContext::currentContext()->format().version())
315  version.setColor(versionWarning->foregroundRole(),Qt::red);
316  else
317  version.setColor(versionWarning->foregroundRole(),Qt::black);
318  versionWarning->setPalette(version);
319 
320  QPalette profile = profileWarning->palette();
321  profileComboBox->setCurrentIndex(OpenFlipper::Options::coreProfile()?0:1);
322  if(QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile)
323  profileWarning->setText("Core");
324  if(QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CompatibilityProfile)
325  profileWarning->setText("Compatibility");
326  if(QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::NoProfile)
327  profileWarning->setText("None");
328  if(OpenFlipper::Options::coreProfile() && QOpenGLContext::currentContext()->format().profile() != QSurfaceFormat::CoreProfile)
329  profile.setColor(profileWarning->foregroundRole(),Qt::red);
330  else
331  profile.setColor(profileWarning->foregroundRole(),Qt::black);
332  profileWarning->setPalette(profile);
333 
334  //Files
335  logFile->setText( OpenFlipperSettings().value("Core/Log/logFile").toString() );
336  maxRecentBox->setValue( OpenFlipperSettings().value("Core/File/MaxRecent",15).toInt() );
337  rbReloadShaders->setChecked(OpenFlipperSettings().value("Core/File/ReloadShaders",false).toBool()) ;
338  leShaderOutputDir->setText(OpenFlipperSettings().value("Core/File/ShaderOutputDir","").toString());
339  allTarget->setChecked( OpenFlipperSettings().value("Core/File/AllTarget",false).toBool() );
340 
341 
342  // UI settings
343  toolBoxOrientation->setCurrentIndex((OpenFlipperSettings().value("Core/Gui/ToolBoxes/ToolBoxOnTheRight",true).toBool() ? 0 : 1));
344 
345  pickToolbarInScene->setChecked(OpenFlipperSettings().value("Core/Gui/ToolBars/PickToolbarInScene",true).toBool());
346 
347  //stereo
348 
349  // Grey out OpenGL stereo mode option if not available
350  if(!OpenFlipper::Options::glStereo()) {
351  stereoOpengl->setDisabled(true);
352  } else {
353  stereoOpengl->setChecked(OpenFlipper::Options::stereoMode() == OpenFlipper::Options::OpenGL);
354  }
355 
356  stereoAnaglyph->setChecked (OpenFlipper::Options::stereoMode() == OpenFlipper::Options::AnaglyphRedCyan);
357  stereoCustomAnaglyph->setChecked (OpenFlipper::Options::stereoMode() == OpenFlipper::Options::AnaglyphCustom);
358 
359  eyeDistance->setValue ( OpenFlipperSettings().value("Core/Stereo/EyeDistance").toDouble() );
360  focalDistance->setValue ( OpenFlipperSettings().value("Core/Stereo/FocalDistance").toDouble() * 1000);
361 
362  // Show right stacked widget
363  customAnaGlyphSettings->setVisible(false);
364 
365  stackedWidget->setCurrentIndex(0);
366 
367  if (stereoCustomAnaglyph->isChecked())
368  customAnaGlyphSettings->setVisible(true);
369 
370  std::vector<float> mat = OpenFlipper::Options::anaglyphLeftEyeColorMatrix ();
371  lcm0->setValue (mat[0]);
372  lcm1->setValue (mat[1]);
373  lcm2->setValue (mat[2]);
374  lcm3->setValue (mat[3]);
375  lcm4->setValue (mat[4]);
376  lcm5->setValue (mat[5]);
377  lcm6->setValue (mat[6]);
378  lcm7->setValue (mat[7]);
379  lcm8->setValue (mat[8]);
380 
381  mat = OpenFlipper::Options::anaglyphRightEyeColorMatrix ();
382  rcm0->setValue (mat[0]);
383  rcm1->setValue (mat[1]);
384  rcm2->setValue (mat[2]);
385  rcm3->setValue (mat[3]);
386  rcm4->setValue (mat[4]);
387  rcm5->setValue (mat[5]);
388  rcm6->setValue (mat[6]);
389  rcm7->setValue (mat[7]);
390  rcm8->setValue (mat[8]);
391 
392  noMousePick->setChecked ( !OpenFlipperSettings().value("Core/Gui/glViewer/stereoMousePick",true).toBool() );
393  nativeMouse->setChecked ( OpenFlipperSettings().value("Core/Gui/glViewer/nativeMouse",false).toBool() );
394 
395  // plugin options
396  initPluginOptions();
397 
398  // updates
399  updateUser->setText( OpenFlipperSettings().value("Core/Update/UserName","anonymous").toString() );
400  updatePass->setText( OpenFlipperSettings().value("Core/Update/Pass","anonymous").toString() );
401  updateURL->setText( OpenFlipperSettings().value("Core/Update/URL","http://").toString() );
402 
403  // debugging
404  slotDebugging->setChecked(OpenFlipper::Options::doSlotDebugging());
405 
406  //keyBindings
407  initKeyTree();
408 
409  keyTree->disconnect(); //to be sure..disconnect every slot
410 
411  connect(keyTree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
412  this, SLOT(keyTreeItemChanged( QTreeWidgetItem*, QTreeWidgetItem*)) );
413 
414  connect(keyTree, SIGNAL(itemDoubleClicked (QTreeWidgetItem*, int)),
415  this, SLOT(keyTreeDoubleClicked( QTreeWidgetItem*, int)) );
416 
417 
418  connect(shortcutButton, SIGNAL(keyChanged()), this, SLOT(updateShortcut()) );
419  connect(presetsButton, SIGNAL(clicked()), this, SLOT(restoreKeyPresets()) );
420 
421 
422  //Init Viewer Settings
423  wZoomFactor->setValue( OpenFlipperSettings().value("Core/Mouse/Wheel/ZoomFactor").toDouble() );
424  wZoomFactorShift->setValue( OpenFlipperSettings().value("Core/Mouse/Wheel/ZoomFactorShift").toDouble() );
425  invertMouseWheelBox->setChecked( OpenFlipperSettings().value("Core/Mouse/Wheel/Invert").toBool() );
426 
427  wheelBox->setChecked( OpenFlipperSettings().value("Core/Gui/glViewer/showControlWheels").toBool() );
428 
429  // Projection settings
430  fieldOfView->setValue(OpenFlipperSettings().value("Core/Projection/FOVY", 45.0).toDouble() );
431 
432  restrictFPS->setChecked( OpenFlipperSettings().value("Core/Gui/glViewer/restrictFrameRate",false).toBool() );
433  FPS->setValue( OpenFlipperSettings().value("Core/Gui/glViewer/maxFrameRate",35).toInt() );
434 
435  minimalSceneSize->setValue( OpenFlipperSettings().value("Core/Gui/glViewer/minimalSceneSize",0.1).toDouble());
436 
437  QPixmap color(16,16);
438  color.fill( OpenFlipperSettings().value("Core/Gui/glViewer/defaultBackgroundColor").value<QColor>() );
439  backgroundColor_ = OpenFlipperSettings().value("Core/Gui/glViewer/defaultBackgroundColor").value<QColor>();
440  backgroundButton->setIcon( QIcon(color) );
441 
442  color.fill( OpenFlipper::Options::defaultColor() );
443  defaultColorButton->setIcon( QIcon(color) );
444 
445  randomDefaultColor->setChecked( OpenFlipper::Options::randomDefaultColor() );
446 
447  viewerList->setCurrentRow(0);
448 
449  for ( int i=0; i < PluginFunctions::viewers(); i++ ){
450  defaultDrawModes_[i] = OpenFlipper::Options::defaultDrawMode(i);
451  defaultProjectionMode_[i] = OpenFlipper::Options::defaultPerspectiveProjectionMode(i);
452  defaultViewingDirections_[i] = OpenFlipper::Options::defaultViewingDirection(i);
453  defaultRotationLocks_[i] = OpenFlipper::Options::defaultLockRotation(i);
454  }
455 
457 
458  viewerLayout->setCurrentIndex( OpenFlipper::Options::defaultViewerLayout() );
459 
460  if (OpenFlipperSettings().value("Core/Language/Translation","en_US").toString() == "en_US")
461  translation->setCurrentIndex(0);
462  else if (OpenFlipperSettings().value("Core/Language/Translation","en_US").toString() == "de_DE")
463  translation->setCurrentIndex(1);
464  else
465  translation->setCurrentIndex(2);
466 
467  // Listen to changes...
468  connect(translation, SIGNAL(currentIndexChanged(int)), this, SLOT(slotTranslationIndexChanged(int)));
469 
471 
472 }
473 
475 
476  updatedPlugins_.clear();
477 
478  QString fileName = QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() +
479  ".OpenFlipper" + OpenFlipper::Options::dirSeparator() + "Versions.ini" ;
480 
481  INIFile ini;
482 
483  ini.connect(fileName,false);
484 
485  QString systemString = "";
486 
487  if ( OpenFlipper::Options::isWindows() ) {
488  systemString = "VersionWindows";
489  } else if (OpenFlipper::Options::isLinux()) {
490  systemString = "VersionLinux";
491  } else {
492  std::cerr << "Unsupported platform for update" << std::endl;
493  return;
494  }
495 
496  updateList->clear();
497  updateList->setRowCount( int(1 + plugins_.size()) );
498  updateList->setColumnCount(3);
499 
500  QStringList header;
501 
502  header << "Component" << "current Version" << "latest Version" ;
503  updateList->setHorizontalHeaderLabels(header);
504 
505  QBrush currentBrush(Qt::white);
506 
507  QTableWidgetItem * newItem = 0;
508 
509  QString coreVersion;
510 
511  if ( ini.is_connected() && ini.get_entry(coreVersion, "Core" , systemString ) ) {
512 
513  // Newer Version available
514  if ( isNewer(OpenFlipper::Options::coreVersion(),coreVersion) ) {
515  currentBrush.setColor(Qt::red);
516  updatedPlugins_ << "Core";
517  } else if ( isNewer(coreVersion , OpenFlipper::Options::coreVersion()) )
518  currentBrush.setColor(Qt::blue);
519  else
520  currentBrush.setColor(Qt::green);
521 
522  newItem = new QTableWidgetItem( coreVersion );
523 
524  } else {
525 
526  // No local Information available
527  currentBrush.setColor(Qt::yellow);
528 
529  newItem = new QTableWidgetItem( "Not Available" );
530  }
531 
532  newItem->setBackground(currentBrush);
533  updateList->setItem(0, 2, newItem);
534 
535  newItem = new QTableWidgetItem( OpenFlipper::Options::coreVersion() );
536  newItem->setBackground(currentBrush);
537  updateList->setItem(0, 1, newItem);
538 
539  newItem = new QTableWidgetItem( "Core" );
540  newItem->setBackground(currentBrush);
541  updateList->setItem(0, 0, newItem);
542 
543 
544  for ( uint i = 0 ; i < plugins_.size(); ++i ) {
545  QString latestVersion;
546 
547  if ( ini.is_connected() && ini.get_entry(latestVersion, plugins_[i].name , systemString ) ) {
548 
549 
550  // Newer Version available
551  if ( isNewer(plugins_[i].version,latestVersion) ) {
552  currentBrush.setColor(Qt::red);
553  QFileInfo pluginFile(plugins_[i].path );
554  updatedPlugins_ << pluginFile.fileName();
555  } else if ( isNewer(latestVersion,plugins_[i].version) )
556  currentBrush.setColor(Qt::blue);
557  else
558  currentBrush.setColor(Qt::green);
559 
560  newItem = new QTableWidgetItem( latestVersion );
561 
562  } else {
563 
564  // No local Information available
565  currentBrush.setColor(Qt::yellow);
566 
567  newItem = new QTableWidgetItem( "Not Available" );
568  }
569 
570  newItem->setBackground(currentBrush);
571  updateList->setItem( i + 1 , 2, newItem);
572 
573  newItem = new QTableWidgetItem( plugins_[i].version );
574  newItem->setBackground(currentBrush);
575  updateList->setItem( i + 1 , 1, newItem);
576 
577  newItem = new QTableWidgetItem( plugins_[i].name );
578  newItem->setBackground(currentBrush);
579  updateList->setItem( i + 1 , 0, newItem);
580  }
581 
582  updateList->resizeColumnsToContents();
583 
584  updateButton->setEnabled(!updatedPlugins_.empty());
585 
586 }
587 
588 void OptionsWidget::initPluginOptions(){
589 
590  pluginList->disconnect();
591 
592  connect(pluginList, SIGNAL( currentTextChanged(const QString&) ), this, SLOT( slotShowPluginOptions(const QString&) ) );
593 
594  //init list of plugins
595  pluginList->clear();
596 
597  for ( uint i = 0 ; i < plugins_.size(); ++i )
598  if (plugins_[i].optionsWidget != 0){
599 
600  pluginList->addItem( plugins_[i].name );
601  }
602 
603  if ( pluginList->count() > 0)
604  pluginList->setCurrentRow(0);
605 }
606 
607 void OptionsWidget::slotShowPluginOptions(const QString& _pluginName ){
608 
609  //remove old children
610  for (int i = 0; i < pluginOptionsLayout->count(); ++i){
611  QWidget* w = pluginOptionsLayout->itemAt(i)->widget();
612 
613  if (w != 0)
614  w->setParent(0);
615 
616  pluginOptionsLayout->removeItem( pluginOptionsLayout->itemAt(i) );
617  }
618 
619  //find the new optionsWidget
620  for ( uint i = 0 ; i < plugins_.size(); ++i )
621  if (plugins_[i].optionsWidget != 0 && plugins_[i].name == _pluginName){
622 
623  pluginOptionsLayout->addWidget( plugins_[i].optionsWidget );
624  pluginOptionsLayout->addStretch();
625  return;
626  }
627 }
628 
630 
631  //general
632  OpenFlipperSettings().setValue("Core/Gui/fullscreen",fullscreen->isChecked());
633  OpenFlipperSettings().setValue("Core/Gui/splash",splash->isChecked());
634  OpenFlipperSettings().setValue("Core/Gui/ToolBoxes/hidden",!toolbox->isChecked());
635 
636  if (loggerHidden->isChecked())
637  OpenFlipper::Options::loggerState( OpenFlipper::Options::Hidden );
638  else if (loggerInScene->isChecked())
639  OpenFlipper::Options::loggerState( OpenFlipper::Options::InScene );
640  else
641  OpenFlipper::Options::loggerState( OpenFlipper::Options::Normal );
642 
643  OpenFlipperSettings().setValue("Core/Log/logFileEnabled",enableLogFile->isChecked());
644  OpenFlipperSettings().setValue("Core/Log/logFile",logFile->text());
645 
646  //OpenGL settings
647  OpenFlipperSettings().setValue("Core/OpenGL/Samples",samples_spinBox->value());
648  OpenFlipper::Options::glVersion(VersionComboBox->currentData().value<QPair<int,int>>());
649  OpenFlipper::Options::coreProfile(profileComboBox->currentIndex() == 0);
650  OpenFlipper::Options::glStereo(stereoCheckBox->isChecked());
651 
652  //Paths settings
653  OpenFlipperSettings().setValue("Core/File/MaxRecent",maxRecentBox->value() ) ;
654  OpenFlipperSettings().setValue("Core/File/ReloadShaders",rbReloadShaders->isChecked() ) ;
655  ACG::ShaderCache::getInstance()->setTimeCheck(rbReloadShaders->isChecked());
656  OpenFlipperSettings().setValue("Core/File/ShaderOutputDir",leShaderOutputDir->text() ) ;
657  ACG::ShaderCache::getInstance()->setDebugOutputDir(leShaderOutputDir->text().toUtf8());
658 
659  OpenFlipperSettings().setValue("Core/File/AllTarget",allTarget->isChecked());
660 
661 
662  // Toolbox orientation
663  OpenFlipperSettings().setValue("Core/Gui/ToolBoxes/ToolBoxOnTheRight", (toolBoxOrientation->currentIndex() == 0));
664 
665  // Render picking toolbar into scene
666  if ( OpenFlipperSettings().value("Core/Gui/ToolBars/PickToolbarInScene",true).toBool() != pickToolbarInScene->isChecked() ) {
667  OpenFlipperSettings().setValue("Core/Gui/ToolBars/PickToolbarInScene", pickToolbarInScene->isChecked());
668  restartRequired_ = true;
669  }
670 
671  if ( iconDefault->isChecked() )
672  OpenFlipperSettings().setValue("Core/Toolbar/iconSize", 0);
673  else if ( iconSmall->isChecked() )
674  OpenFlipperSettings().setValue("Core/Toolbar/iconSize", 1);
675  else if ( iconNormal->isChecked() )
676  OpenFlipperSettings().setValue("Core/Toolbar/iconSize", 2);
677 
678  //viewer
679  OpenFlipperSettings().setValue("Core/Mouse/Wheel/ZoomFactor", wZoomFactor->value());
680  OpenFlipperSettings().setValue("Core/Mouse/Wheel/ZoomFactorShift", wZoomFactorShift->value());
681  OpenFlipperSettings().setValue("Core/Mouse/Wheel/Invert", invertMouseWheelBox->isChecked());
682 
683  // Projection settings
684  OpenFlipperSettings().setValue("Core/Projection/FOVY", fieldOfView->value());
685  OpenFlipperSettings().setValue("Core/Gui/glViewer/minimalSceneSize",minimalSceneSize->value());
686 
687  OpenFlipperSettings().setValue("Core/Gui/glViewer/showControlWheels", wheelBox->isChecked() );
688 
689  OpenFlipperSettings().setValue("Core/Gui/glViewer/restrictFrameRate", restrictFPS->isChecked());
690  OpenFlipperSettings().setValue("Core/Gui/glViewer/maxFrameRate", FPS->value() );
691 
692  OpenFlipper::Options::randomDefaultColor( randomDefaultColor->isChecked() );
693 
694  //stereo
695  if (stereoCustomAnaglyph->isChecked ())
696  OpenFlipper::Options::stereoMode(OpenFlipper::Options::AnaglyphCustom);
697  else if (stereoAnaglyph->isChecked ())
698  OpenFlipper::Options::stereoMode(OpenFlipper::Options::AnaglyphRedCyan);
699  else
700  OpenFlipper::Options::stereoMode(OpenFlipper::Options::OpenGL);
701 
702  OpenFlipperSettings().setValue("Core/Stereo/EyeDistance",eyeDistance->value ());
703  OpenFlipperSettings().setValue("Core/Stereo/FocalDistance",double(focalDistance->value() / 1000.0));
704 
705  std::vector<float> mat (9, 0);
706  mat[0] = lcm0->value ();
707  mat[1] = lcm1->value ();
708  mat[2] = lcm2->value ();
709  mat[3] = lcm3->value ();
710  mat[4] = lcm4->value ();
711  mat[5] = lcm5->value ();
712  mat[6] = lcm6->value ();
713  mat[7] = lcm7->value ();
714  mat[8] = lcm8->value ();
715 
716  OpenFlipper::Options::anaglyphLeftEyeColorMatrix (mat);
717 
718  mat[0] = rcm0->value ();
719  mat[1] = rcm1->value ();
720  mat[2] = rcm2->value ();
721  mat[3] = rcm3->value ();
722  mat[4] = rcm4->value ();
723  mat[5] = rcm5->value ();
724  mat[6] = rcm6->value ();
725  mat[7] = rcm7->value ();
726  mat[8] = rcm8->value ();
727 
728  OpenFlipper::Options::anaglyphRightEyeColorMatrix (mat);
729 
730  OpenFlipperSettings().setValue("Core/Gui/glViewer/stereoMousePick",!noMousePick->isChecked ());
731  OpenFlipperSettings().setValue("Core/Gui/glViewer/nativeMouse",nativeMouse->isChecked ());
732 
733  // updates
734  OpenFlipperSettings().setValue("Core/Update/UserName", updateUser->text());
735  OpenFlipperSettings().setValue("Core/Update/Pass",updatePass->text());
736  OpenFlipperSettings().setValue("Core/Update/URL",updateURL->text());
737 
738  // Debugging
739  OpenFlipper::Options::doSlotDebugging(slotDebugging->isChecked());
740 
741  //viewer defaults
742  for (int i=0; i < PluginFunctions::viewers(); i++){
743  OpenFlipper::Options::defaultDrawMode( defaultDrawModes_[i], i );
744  OpenFlipper::Options::defaultPerspectiveProjectionMode( defaultProjectionMode_[i], i );
745  OpenFlipper::Options::defaultViewingDirection( defaultViewingDirections_[i], i );
746  OpenFlipper::Options::defaultLockRotation( defaultRotationLocks_[i], i );
747  }
748 
749  OpenFlipper::Options::defaultViewerLayout( viewerLayout->currentIndex() );
750 
751  // Restrict fps if desired
752  if(restrictFPS->isChecked()) {
753  OpenFlipperSettings().setValue("Core/Gui/glViewer/restrictFrameRate", true);
754  OpenFlipperSettings().setValue("Core/Gui/glViewer/maxFrameRate",FPS->value());
755  } else {
756  OpenFlipperSettings().setValue("Core/Gui/glViewer/restrictFrameRate", false);
757  }
758 
759  // Set background color
760  OpenFlipperSettings().setValue("Core/Gui/glViewer/defaultBackgroundColor", backgroundColor_);
761 
762  for ( uint i = 0 ; i < OpenFlipper::Options::examinerWidgets(); ++i )
763  PluginFunctions::viewerProperties(i).backgroundColor(ACG::Vec4f(((double) backgroundColor_.redF()),
764  ((double) backgroundColor_.greenF()),
765  ((double) backgroundColor_.blueF()),
766  1.0));
767 
768  switch ( translation->currentIndex() ){
769  case 0 : OpenFlipperSettings().setValue("Core/Language/Translation","en_US"); break;
770  case 1 : OpenFlipperSettings().setValue("Core/Language/Translation","de_DE"); break;
771  default: OpenFlipperSettings().setValue("Core/Language/Translation","locale"); break;
772  }
773 
774  // Show warning message that restart is required if language or in scene toolbar has been changed...
775  if(restartRequired_) {
776  int restart = QMessageBox::information(this, tr("Restart required!"),
777  tr("The changes will take effect after next restart. Do you want to close OpenFlipper now?"),
778  QMessageBox::Yes | QMessageBox::No);
779 
780  if(restart == QMessageBox::Yes) exitOnClose_ = true;
781  }
782 
783  applyShortcuts();
784 
785  emit applyOptions();
786  emit saveOptions();
787 
788  // Make sure all settings are written before we quit!
789  OpenFlipperSettings().sync();
790 
791  // Close OpenFlipper if demanded
792  if(exitOnClose_) QCoreApplication::quit();
793 }
794 
796  slotApply();
797  hide();
798 }
799 
801  hide();
802 }
803 
805 
806  // http://www.graphics.rwth-aachen.de/restricted/OpenFlipper-SIL/
807 
808  downloadType = VERSIONS_FILE;
809  QString ServerMainURL = updateURL->text();
810  if ( !ServerMainURL.endsWith("/") )
811  ServerMainURL += "/";
812 
813  ServerMainURL += "Versions.ini";
814 
815  startDownload(ServerMainURL);
816 }
817 
819  std::cerr << "Not implemented yet: Get updates" << std::endl;
820  QString url = updateURL->text();
821 
822  if ( !url.endsWith("/") )
823  url += "/";
824 
825 
826  pluginPath_.clear();
827  pluginPath_ = "Plugins/";
828 
829  if ( OpenFlipper::Options::isWindows() ) {
830  pluginPath_ += "Windows/";
831  } else if ( OpenFlipper::Options::isLinux() ) {
832  pluginPath_ += "Linux/";
833  } else {
834  std::cerr << "Unknown operating system type, aborting update" << std::endl;
835  return;
836  }
837 
838  if ( OpenFlipper::Options::is64bit() ) {
839  pluginPath_ += "64/";
840  } else if ( OpenFlipper::Options::is32bit() ) {
841  pluginPath_ += "32/";
842  } else {
843  std::cerr << "Unknown architecture type, aborting update" << std::endl;
844  return;
845  }
846 
847  pluginPath_ += "Release/";
848 
849  if ( !updatedPlugins_.empty() && updatedPlugins_[0] == "Core" ) {
850  std::cerr << "Core update not supported!" << std::endl;
851  return;
852  }
853 
854  if ( !updatedPlugins_.empty() ) {
856  std::cerr << "Downloading " << (url + pluginPath_ + currentUpdateName_).toStdString() << std::endl;
857  updatedPlugins_.pop_front();
858 
859  downloadType = PLUGIN;
860 
862  }
863 
864 }
865 
866 void OptionsWidget::updateComponent() {
867  std::cerr << "Todo : Update component" << std::endl;
868 
869 
870 
871  QString sourceName = QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() +
872  ".OpenFlipper" + OpenFlipper::Options::dirSeparator() + currentUpdateName_ ;
873 
874  QString targetName = OpenFlipper::Options::applicationDirStr() + "/" + pluginPath_ + currentUpdateName_;
875 
876  QFileInfo sourceFileInfo(sourceName);
877  QFileInfo targetFileInfo(targetName);
878 
879  std::cerr << sourceName.toStdString() << std::endl;
880  std::cerr << targetName.toStdString() << std::endl;
881 
882  if ( ! sourceFileInfo.exists() ) {
883  statusLabel->setText(tr("Download failed!"));
884  slotGetUpdates();
885  return;
886  } else {
887  if ( ! targetFileInfo.exists() ) {
888  statusLabel->setText(tr("plugin target does not exist"));
889  slotGetUpdates();
890  return;
891  }
892 
893  statusLabel->setText(tr("Installing new file"));
894 
895  // Remove the old plugin
896  QFile targetFile(targetName);
897  targetFile.remove();
898 
899  // copy new to old
900  QFile::copy(sourceName,targetName);
901 
902  // remove downloaded file
903  QFile sourceFile(sourceName);
904  sourceFile.remove();
905 
906  statusLabel->setText(tr("updated ") + currentUpdateName_);
907  }
908 
909  slotGetUpdates();
910 }
911 
912 bool OptionsWidget::isNewer(QString _current, QString _latest) {
913 
914  QStringList latestVersionParts = _latest.split('.');
915  QStringList currentVersionParts = _current.split('.');
916 
917  bool newer = false;
918 
919  for ( int i = 0 ; i < latestVersionParts.size(); ++i ) {
920 
921  if ( i+1 > currentVersionParts.size() ) {
922  // Versions are identical up to now. But latest version has additional version => updated
923  newer = true;
924  break;
925  }
926 
927  bool ok = false;
928  double latest = latestVersionParts[i].toInt(&ok);
929  double current = currentVersionParts[i].toInt(&ok);
930 
931  if ( !ok )
932  std::cerr << "Error when parsing version strings!" << std::endl;
933 
934  if ( latest > current ) {
935  newer = true;
936  break;
937  }
938  }
939 
940  return newer;
941 
942 }
943 
945 
946  QString fileName = QDir::home().absolutePath() + OpenFlipper::Options::dirSeparator() +
947  ".OpenFlipper" + OpenFlipper::Options::dirSeparator() + "Versions.ini" ;
948 
949  INIFile ini;
950  if ( ! ini.connect(fileName,false) ) {
951  std::cerr << "Failed to connect to Versions ini file" << std::endl;
952  return;
953  }
954 
955  statusLabel->setText(tr("Checking for new versions"));
956 
957  bool newerVersionsAvailable = false;
958 
959  QString systemString = "";
960  if ( OpenFlipper::Options::isWindows() ) {
961  systemString = "VersionWindows";
962  } else if (OpenFlipper::Options::isLinux()) {
963  systemString = "VersionLinux";
964  } else {
965  std::cerr << "Unsupported platform for update" << std::endl;
966  return;
967  }
968 
969  QString coreVersion;
970 
971  if ( ini.get_entry(coreVersion, "Core" , systemString )) {
972  if ( isNewer( OpenFlipper::Options::coreVersion(), coreVersion ) ) {
973  newerVersionsAvailable = true;
974  }
975  }
976 
977  for ( uint i = 0 ; i < plugins_.size(); ++i ) {
978  QString latestVersion;
979  if ( ini.get_entry(latestVersion, plugins_[i].name , systemString )) {
980  if ( isNewer( plugins_[i].version, latestVersion ) )
981  newerVersionsAvailable = true;
982  }
983  }
984 
985  if ( newerVersionsAvailable ) {
986  statusLabel->setText(tr("Updates found"));
987  } else {
988  statusLabel->setText(tr("No updates found"));
989  }
990 
991  ini.disconnect();
992 
994 }
995 
997 
998  if (stereoCustomAnaglyph->isChecked ())
999  OpenFlipper::Options::stereoMode(OpenFlipper::Options::AnaglyphCustom);
1000  else if (stereoAnaglyph->isChecked ())
1001  OpenFlipper::Options::stereoMode(OpenFlipper::Options::AnaglyphRedCyan);
1002  else
1003  OpenFlipper::Options::stereoMode(OpenFlipper::Options::OpenGL);
1004 
1005  OpenFlipperSettings().setValue("Core/Stereo/EyeDistance", eyeDistance->value());
1006  OpenFlipperSettings().setValue("Core/Stereo/FocalDistance", double(focalDistance->value() / 1000.0));
1007 
1008 
1009  // Update all views
1010  emit applyOptions();
1011 }
1012 
1014 
1015  OpenFlipperSettings().clear();
1016 }
1017 
1019 
1020  QMessageBox::information(this, tr("Restart required!"),
1021  tr("The changes will take effect after next restart."));
1022 
1023  OpenFlipper::Options::deleteIniFile(true);
1024 }
1025 
1027 {
1029 }
QStringList updatedPlugins_
void disconnect()
Remove connection of this object to a file.
Definition: INIFile.cc:122
void slotCancel()
Only hide widget.
void setDebugOutputDir(const char *_outputDir)
Enable debug output of generated shaders to specified directory.
Definition: ShaderCache.cc:604
bool is_connected() const
Check if object is connected to file.
Definition: INIFile.hh:117
void slotClearSettings()
Clear all OpenFlipper settings.
void slotReloadShaders()
Clear the Shader Cache.
void keyTreeDoubleClicked(QTreeWidgetItem *_item, int col)
doubleclick in the keyTree
Definition: keyBindings.cc:59
void setTimeCheck(bool _on)
enable or disable checking of the time step of each file
Definition: ShaderCache.hh:171
void slotOk()
call slotApply and hide widget
void applyShortcuts()
check which of the shortcuts changed and inform the core about the change
Definition: keyBindings.cc:123
bool get_entry(QString &_val, const QString &_section, const QString &_key) const
Access to a string entry.
Definition: INIFile.cc:433
void updateVersionsTable()
Redraws the version table.
void compareVersions()
Compares the versions from the downloaded Versions file with the current versions.
void slotCheckUpdates()
Checks for updates.
DrawMode DEFAULT
use the default (global) draw mode and not the node&#39;s own.
Definition: DrawModes.cc:72
int viewers()
Get the number of viewers.
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
Definition: ShaderCache.cc:84
void switchStackedWidget()
Switch between the stacked widgets of the stereo settings.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void slotPreviewStereoSettings(int _tmpParam=0)
void slotClearINI()
Clear OpenFlipper INI.
void startDownload(QString _url)
Starts the download of the given file.
Definition: downloader.cc:52
void clearCache()
Delete all cached shaders.
Definition: ShaderCache.cc:597
void slotApply()
Update Options and tell others about changed Options.
ACG::Vec4f backgroundColor()
Get current background color.
bool isNewer(QString _current, QString _latest)
Compares two version strings and returns if a newer Version is available.
void getBackgroundColor()
open a dialog to determine the color
void slotGetUpdates()
Download updates.
void viewerSettingsChanged(QListWidgetItem *_item)
remember user changes to viewer properties
void authentication(QNetworkReply *_reply, QAuthenticator *_authenticator)
authentication
Definition: downloader.cc:104
QString pluginPath_
void restoreKeyPresets()
restore keyBinding Presets
Definition: keyBindings.cc:159
Class for the handling of simple configuration files.
Definition: INIFile.hh:99
bool connect(const QString &name, const bool create)
Connect INIFile object with given filename.
Definition: INIFile.cc:70
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void updateViewerSettings(int _row)
update the dialog if the selected viewer changes
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
void keyTreeItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
keyBinding TreeWidget-Item changed
Definition: keyBindings.cc:70
QString currentUpdateName_