ArmarXMainWindow.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #include "ArmarXMainWindow.h"
25 #include <ArmarXGui/applications/ArmarXGui/ui_ArmarXMainWindow.h>
26 
27 #include "Widgets/ViewerWidget.h"
28 #include "Widgets/TitlebarWidget.h"
30 
31 // ArmarX
38 
39 // Qt
40 #include <QtCore/QDirIterator>
41 #include <QFileDialog>
42 #include <QLabel>
43 #include <QListView>
44 #include <QInputDialog>
45 #include <QPushButton>
46 #include <QFile>
47 #include <QLabel>
48 #include <QToolButton>
49 #include <QTimer>
50 #include <QList>
51 #include <QStringList>
52 #include <QPluginLoader>
53 #include <QDialog>
54 #include <QComboBox>
55 #include <QGridLayout>
56 #include <QStackedWidget>
57 #include <QSplitter>
58 #include <QPlainTextEdit>
59 #include <QMdiArea>
60 #include <QMutex>
61 #include <QSignalMapper>
62 #include <QSpinBox>
63 #include <QMenu>
64 #include <QActionGroup>
65 #include <QModelIndex>
66 #include <QListWidget>
67 #include <QHBoxLayout>
68 #include <QDialogButtonBox>
69 #include <QProxyStyle>
70 #include <QPainter>
71 #include <QDesktopServices>
72 #include <QHostInfo>
73 
74 #include <Inventor/nodes/SoPerspectiveCamera.h>
75 
80 
81 #include <filesystem>
82 
83 #include <QCompleter>
84 #include <QMessageBox>
85 #include <QScrollArea>
86 #include <QStringListModel>
87 #include <QUrl>
88 #include <QWidgetAction>
89 
90 #include <SimoxUtility/algorithm/string/string_tools.h>
91 
92 #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
93 #include <QtSvg/QSvgRenderer>
94 
95 #include <unistd.h>
96 #include <optional>
97 #include <sys/wait.h>
98 #include <sys/types.h>
99 #include <sstream>
100 //#include <omp.h>
101 
102 // To start ArViz Godot
103 #include <fcntl.h>
104 
105 
106 #define ARMARX_ORGANIZATION "KIT"
107 #define ARMARX_GUI_APPLICATION_NAME "ArmarX"
108 
109 #define CONFIG_LOAD_LAST_CONFIG "LoadLastConfig"
110 #define CONFIG_BLACKLISTED_TIPS "BlacklistedTips"
111 
112 namespace armarx
113 {
114  ArmarXMainWindow::ArmarXMainWindow(const armarx::ManagedIceObjectRegistryInterfacePtr& registry, const std::vector<std::string>& packages, const QString& configToLoad, bool disablePreloading) :
115  QMainWindow(NULL),
116  pluginCache(ArmarXManagerPtr::dynamicCast(registry)),
117  defaultPackageNames(packages),
118  widgetsLocked(false),
119  settingsFile(armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/" + ARMARX_GUI_APPLICATION_NAME + ".conf"),
120  mainSettings(QString(settingsFile.c_str()), QSettings::NativeFormat)
121  {
122  setStyleSheet(R"(
123  QMainWindow::separator {
124  width: 3px; /* when vertical */
125  height: 3px; /* when horizontal */
126  }
127  QMainWindow::separator:hover {
128  background: gray;
129  }
130  )");
131 
132  mainWidgets = QStringList() << "Meta.LogViewer" << "Statecharts.StatechartEditor" << "Meta.SystemStateMonitor" << "Meta.ScenarioManager" << "MemoryX.WorkingMemoryGui";
133 
134  splashscreenPrefix = "v" + QString::fromStdString(Application::GetVersion()) + " - ";
135  QPixmap pm(QString("://icons/ArmarX-Splashscreen.png"));
136  splashSceen = new QSplashScreen(pm);
137  // splashSceen->show();
138 
139  ui = new ::Ui::ArmarXMainWindow();
140  mutex3d = std::make_shared<std::recursive_mutex>();
141  ArmarXWidgetInfoPtr viewerWidgetInfo(new ArmarXWidgetInfo(ArmarXComponentWidgetController::createInstance<Viewer3DWidget>, Viewer3DWidget::GetWidgetIcon(), QIcon()));
142  pluginCache.cacheWidget(ARMARX_VIEWER_NAME, viewerWidgetInfo);
143 
145  QString username = qgetenv("USER");
146  if (username.isEmpty())
147  {
148  username = qgetenv("USERNAME");
149  }
150 
151  guiWindowBaseName = QString{ARMARX_GUI_APPLICATION_NAME};
152  setWindowTitle(guiWindowBaseName);
153  this->registry = registry;
154  setAttribute(Qt::WA_QuitOnClose);
155 
156  ui->setupUi(this);
157  setCentralWidget(NULL);
158 
159  tipDialog = new TipDialog(this);
160  tipDialog->setBlackListedStrings(mainSettings.value(CONFIG_BLACKLISTED_TIPS).toStringList());
161  ui->actionLoadLastConfig->setChecked(mainSettings.value(CONFIG_LOAD_LAST_CONFIG).toBool());
162 
163  addWidgetAction = new AddArmarXWidgetAction("", this, this);
164  connect(addWidgetAction, SIGNAL(clicked(QString, QString)), this, SLOT(createArmarXWidget(QString, QString)), Qt::UniqueConnection);
165 
166 
167  connect(ui->actionLoadPlugin, SIGNAL(triggered()), this, SLOT(pluginDialog()));
168  connect(ui->actionSave_Gui, SIGNAL(triggered()), this, SLOT(saveGuiConfig()));
169  connect(ui->actionLoad_Gui_Config, SIGNAL(triggered()), this, SLOT(loadGuiConfig()));
170  connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close()));
171  connect(ui->actionSave_Gui_as, SIGNAL(triggered()), this, SLOT(saveGuiConfigAs()));
172  connect(ui->actionFullscreen, SIGNAL(triggered()), this, SLOT(enterFullscreenMode()));
173  connect(ui->actionLock_Widgets, SIGNAL(triggered()), this, SLOT(toggleWidgetLock()));
174 
175  // EmergencyStop
176  emergencyStopWidget = EmergencyStopWidgetPtr::dynamicCast(ArmarXComponentWidgetController::createInstance<EmergencyStopWidget>());
177  this->registry->addObject(ManagedIceObjectPtr::dynamicCast(emergencyStopWidget));
178 
179  // plugins
180  QSet<QString> pluginDirs;
181 
182  for (const std::string& packageName : packages)
183  {
184  pluginDirs.insert(getLibraryPathFromPackage(packageName.c_str()));
185  }
186  loadPlugins(pluginDirs, false);
187  if (!disablePreloading)
188  {
189  pluginCache.preloadAsync(getFavoriteWidgets() + mainWidgets);
190  }
191  // instantiatePlugins();
192 
194 
195 
196  connectionStatusTimer = new QTimer(this);
197  connect(connectionStatusTimer, SIGNAL(timeout()), this, SLOT(updateStatusOfOpenWidgets()));
198  connectionStatusTimer->start(300);
199  //changeLayout(2);
200  QStringList recentlyFiles = mainSettings.value("RecentlyFiles").toStringList();
201  splashSceen->finish(this);
202 
203  guiUseCaseSelector = new GuiUseCaseSelector(this, mainSettings.value("DoNotShowUseCaseDialog").toBool(), this);
204 
205 
206 
207  if (!configToLoad.isEmpty())
208  {
209  loadGuiConfig(configToLoad);
210  }
211  else if (!mainSettings.value("DoNotShowUseCaseDialog").toBool() && guiUseCaseSelector->exec() == QDialog::Accepted)
212  {
213  QString path = guiUseCaseSelector->getSelectedConfigFilePath();
214  ARMARX_INFO << VAROUT(path);
215  if (!path.isEmpty())
216  {
217  loadGuiConfig(path, false);
218  }
219  }
220  else if (recentlyFiles.size() > 0 && mainSettings.value(CONFIG_LOAD_LAST_CONFIG).toBool())
221  {
222  //set to false in case a plugin crashes the gui
223  mainSettings.setValue(CONFIG_LOAD_LAST_CONFIG, false);
224  mainSettings.sync();
225  loadGuiConfig(recentlyFiles.first());
226  mainSettings.setValue(CONFIG_LOAD_LAST_CONFIG, ui->actionLoadLastConfig->isChecked());
227  mainSettings.sync();
228  }
229  else
230  {
231  QStringList defaultWidgets {"Meta.LogViewer"};
232  for (auto& widgetName : defaultWidgets)
233  {
234  if (existsWidget(widgetName))
235  {
236  createArmarXWidget(widgetName, widgetName);
237  }
238  }
239  }
240 
241  mainSettings.setValue("DoNotShowUseCaseDialog", guiUseCaseSelector->getDoNotShowAgain());
242  }
243 
245  {
246  delete ui;
247  connectionStatusTimer->stop();
248  mainSettings.setValue(CONFIG_BLACKLISTED_TIPS, tipDialog->getBlackListedStrings());
249  ARMARX_INFO << "~GuiWindow() ";
250  delete splashSceen;
251  }
252 
253 
254 
255  void ArmarXMainWindow::removeViewerWidget(QObject* widget)
256  {
257  ARMARX_WARNING << "Removing 3d viewer" << std::endl;
258 
259  if (!widget)
260  {
261  ARMARX_INFO << "viewerDockWidget ptr is NULL";
262  }
263 
264  removeArmarXWidget(widget);
265  }
266 
267 
268  Viewer3DWidgetPtr ArmarXMainWindow::setupViewerWidget()
269  {
270  if (listOpenWidgets.find(ARMARX_VIEWER_NAME) != listOpenWidgets.end())
271  {
272  return Viewer3DWidgetPtr::dynamicCast(listOpenWidgets.find(ARMARX_VIEWER_NAME).value().second);
273  }
274 
275  Viewer3DWidgetPtr viewer = Viewer3DWidgetPtr::dynamicCast(createArmarXWidget(ARMARX_VIEWER_NAME, ARMARX_VIEWER_NAME));
276 
277  // ensure that all drawings are protected with a mutex
278  viewer->setMutex3D(mutex3d);
279 
280  return viewer;
281  }
282 
283 
284 
285  void ArmarXMainWindow::pluginDialog()
286  {
287  QFileDialog dialog(this);
288  dialog.setFileMode(QFileDialog::ExistingFiles);
289  dialog.setNameFilter(tr("Libraries (*.dll *.so *.dylib)"));
290  QStringList fileNames;
291 
292  if (dialog.exec())
293  {
294  fileNames = dialog.selectedFiles();
295  }
296 
297  foreach (QString filePath, fileNames)
298  {
299  pluginCache.removePluginFromCache(filePath);
300  ARMARX_INFO << filePath.toStdString() << armarx::flush;
301  loadPlugin(filePath);
302  }
303  }
304 
305  void ArmarXMainWindow::loadPlugins(const QStringList& fileNames)
306  {
307  QStringList guiFiles;
308 
309  for (int i = 0; i < fileNames.size(); i++)
310  {
311  QString fileName = fileNames.at(i);
312 
313  // only try to load files ending with GuiPlugin.so and GuiPlugin.dll
314  if (!fileName.endsWith("GuiPlugin.so") && !fileName.endsWith("GuiPlugin.dll") && !fileName.endsWith("GuiPlugin.dylib"))
315  {
316  continue;
317  }
318 
319  guiFiles.push_back(fileName);
320  }
321  auto start = IceUtil::Time::now();
322  for (int i = 0; i < guiFiles.size(); i++)
323  {
324  QString fileName = guiFiles.at(i);
325  if ((IceUtil::Time::now() - start).toSeconds() >= 2)
326  {
327  splashSceen->show();
328  splashSceen->showMessage(splashscreenPrefix + fileName,
329  Qt::AlignJustify | Qt::AlignBottom);
330  qApp->processEvents();
331 
332  }
333  pluginCache.cachePlugin(fileName);
334  }
335  updateAvailableWidgetList();
336  }
337 
338  QAction* ArmarXMainWindow::addActionToToolBar(QAction* action, bool allowText)
339  {
340  QToolButton* button = new QToolButton(ui->toolBar);
341 
342  std::optional<QSize> textSize;
343  if (allowText)
344  {
345  button->setToolButtonStyle(Qt::ToolButtonStyle::ToolButtonTextBesideIcon);
346  button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
347 
348  // Get the width of the button when just showing text.
349  button->setText(action->text());
350  textSize = button->sizeHint();
351  }
352 
353  button->setDefaultAction(action);
354  if (not action->icon().isNull())
355  {
356  const QSize maxSize {256, 24};
357  const QSize iconSize = action->icon().actualSize(maxSize);
358  // Setting the action has already set the icon, so this line is unnecessary.
359  // button->setIcon(action->icon());
360  button->setIconSize(iconSize);
361  button->setFixedSize(textSize.has_value()
362  ? QSize{textSize->width() + iconSize.width(), iconSize.height()}
363  : iconSize);
364  }
365  return ui->toolBar->addWidget(button);
366  }
367 
368  QString ArmarXMainWindow::getLibraryPathFromPackage(const QString& packageName)
369  {
370  CMakePackageFinder packageFinder(packageName.toStdString());
371  std::string libPaths = packageFinder.getLibraryPaths();
372  QString dir = QString::fromStdString(libPaths);
373  dir = QDir::cleanPath(dir);
374 
375  return dir;
376  }
377 
379  {
380  auto widgetUsageHistory = mainSettings.value("WidgetUsageHistory").toList();
381  std::map<QString, int> widgetUsage;
382  for (auto& widgetName : widgetUsageHistory)
383  {
384  if (widgetUsage.count(widgetName.toString()) == 0)
385  {
386  widgetUsage[widgetName.toString()] = 1;
387  }
388  else
389  {
390  widgetUsage[widgetName.toString()] += 1;
391  }
392  }
393  std::multimap<int, QString> ranking;
394  for (auto it = widgetUsage.begin(); it != widgetUsage.end(); it++)
395  {
396  ranking.insert(std::make_pair(it->second, it->first));
397  }
398  int i = 0;
399  const int favCount = mainSettings.value("FavoriteWidgetCount", 6).toInt();
400  QStringList favoriteWidgetNames;
401  for (auto it = ranking.rbegin(); it != ranking.rend() && i < favCount ; it++)
402  {
403  auto& widgetName = it->second;
404  if (!mainWidgets.contains(widgetName))
405  {
406  favoriteWidgetNames << widgetName;
407  i++;
408  }
409  }
410  return favoriteWidgetNames;
411  }
412 
413  void ArmarXMainWindow::loadPluginsFromPackage(const QString& packageName)
414  {
415  QSet<QString> pluginDirs;
416  splashSceen->showMessage(splashscreenPrefix + packageName,
417  Qt::AlignJustify | Qt::AlignBottom);
418  qApp->processEvents();
419 
420  ARMARX_INFO << "Looking for gui plugins in package " << packageName;
421  QString dir = getLibraryPathFromPackage(packageName);
422  pluginDirs.insert(dir);
423  loadedPackages << packageName;
424  loadPlugins(pluginDirs, false);
425  }
426 
427 
428  void ArmarXMainWindow::loadPlugins(const QString& pluginDir, bool searchRecursive)
429  {
430  QSet<QString> dirs;
431  dirs.insert(pluginDir);
432  loadPlugins(dirs, searchRecursive);
433  }
434 
435 
436  void ArmarXMainWindow::loadPlugins(const QSet<QString>& pluginDirs, bool searchRecursive)
437  {
438  // only search paths ending with lib
439  QStringList filters;
440  filters << "*.so" << "*.dll" << "*.dylib";
441  QList<QDir> directoriesToCheck;
442  QStringList allFileNames;
443 
444  for (const auto& pluginDir : pluginDirs)
445  {
446  directoriesToCheck.push_back(QDir(pluginDir));
447 
448  while (directoriesToCheck.size() > 0)
449  {
450  ARMARX_VERBOSE_S << "Checking dir : " + directoriesToCheck.front().absolutePath() << std::endl;
451  splashSceen->showMessage(splashscreenPrefix + directoriesToCheck.front().absolutePath(),
452  Qt::AlignJustify | Qt::AlignBottom);
453  qApp->processEvents();
454  QDir currentPluginDir = directoriesToCheck.front();
455  directoriesToCheck.pop_front();
456  QString curPath = currentPluginDir.path();
457 
458  if (curPath.length() == 0)
459  {
460  continue;
461  }
462 
463  QStringList fileNames = currentPluginDir.entryList(filters, QDir::Files);
464 
465  for (auto& fileName : fileNames)
466  {
467  fileName = currentPluginDir.absoluteFilePath(fileName);
468  }
469 
470  allFileNames.append(fileNames);
471 
472  if (searchRecursive)
473  {
474  QDirIterator directoryIterator(currentPluginDir.absolutePath(), QStringList(), QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
475 
476  while (directoryIterator.hasNext())
477  {
478  directoryIterator.next();
479  directoriesToCheck.push_back(QDir(directoryIterator.filePath()));
480 
481  }
482  }
483 
484  }
485  }
486 
487  loadPlugins(allFileNames);
488  }
489 
490 
491 
492  bool ArmarXMainWindow::existsWidget(const QString& widgetName)
493  {
494  auto list = pluginCache.getAvailableWidgetNames();
495  return list.contains(widgetName);
496  }
497 
498  void ArmarXMainWindow::loadPlugin(QString filePath)
499  {
500  QFileInfo pathInfo(filePath);
501  QString fileName(pathInfo.fileName());
502  pluginCache.cachePlugin(filePath);
503  ARMARX_INFO << "Plugin Path: " << pathInfo.absoluteFilePath().toStdString() << armarx::flush;
504  updateAvailableWidgetList();
505  // if (!loadedPluginFilepaths.contains(pathInfo.absoluteFilePath()))
506  // {
507  // QPluginLoader loader(filePath);
508  // // ARMARX_INFO << "loader created" << armarx::flush;
509  // instantiatePlugin(loader);
510  // }
511  // else
512  // {
513  // ARMARX_INFO << "Plugin already loaded" << armarx::flush;
514  // }
515  }
516 
517 
518 
519 
520  void ArmarXMainWindow::closeEvent(QCloseEvent* event)
521  {
522  emit closeRequest();
523  event->accept();
524 
525  }
526 
527 
528 
529  void ArmarXMainWindow::closeAllWidgets()
530  {
531 
532 
533  OpenWidgetMap listOpenWidgetsTemp = listOpenWidgets;
534  OpenWidgetMap::iterator it = listOpenWidgetsTemp.begin();
535 
536  for (; it != listOpenWidgetsTemp.end() ; ++it)
537  {
538  ARMARX_INFO << "Closing widget " << it.key() << " size: " << listOpenWidgetsTemp.size();
539  QDockWidget* w = it.value().first;
540 
541  if (w)
542  {
543  if (!w->close())
544  {
545  ARMARX_WARNING << "Could not close widget!" << std::endl;
546  }
547  }
548  }
549 
550  // if (viewerDockWidget)
551  // removeViewerWidget(viewerDockWidget);
552 
553  // causes segfault during redraw of 3d scene ?!
554  //QApplication::instance()->processEvents();
555 
556  ARMARX_VERBOSE << "Closed all widgets";
557  listOpenWidgets.clear();
558 
559  this->configFilepath = "";
560  appendFileToWindowTitle(configFilepath);
561  }
562 
563  void ArmarXMainWindow::closeAllWidgetsWithDialog()
564  {
565  QMessageBox dialog(QMessageBox::Question, tr("Closing all widgets"), tr("Do you really want to close all widgets?"));
566  dialog.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
567  dialog.setDefaultButton(QMessageBox::Yes);
568 
569  if (dialog.exec() == QMessageBox::Yes)
570  {
571  closeAllWidgets();
572  }
573  }
574 
575 
576 
578  {
579 
580  QDir path(configFilepath);
581  configFilepath = path.absolutePath();
582 
583  QStringList recentlyFiles = mainSettings.value("RecentlyFiles").toStringList();
584  recentlyFiles.removeAll(configFilepath);
585  recentlyFiles.push_front(configFilepath);
586 
587  if (recentlyFiles.size() > 10)
588  {
589  recentlyFiles.pop_back();
590  }
591 
592  mainSettings.setValue("RecentlyFiles", recentlyFiles);
593  }
594 
595 
596  std::vector<std::string> ArmarXMainWindow::getDefaultPackageNames()
597  {
598  return defaultPackageNames;
599  }
600 
601 
603  {
604  if (listOpenWidgets.find(ARMARX_VIEWER_NAME) != listOpenWidgets.end())
605  {
606  return Viewer3DWidgetPtr::dynamicCast(listOpenWidgets.find(ARMARX_VIEWER_NAME).value().second);
607  }
608  else
609  {
610  return NULL;
611  }
612  }
613 
614  void ArmarXMainWindow::loadGuiConfig(QString configFilepath, bool showAsOpenGuiConfig)
615  {
616 
617  if (configFilepath.length() == 0)
618  {
619  QFileDialog dialog(this);
620  dialog.setFileMode(QFileDialog::ExistingFile);
621  dialog.setAcceptMode(QFileDialog::AcceptOpen);
622  QStringList nameFilters;
623  nameFilters << "ArmarX Gui-Files (*.armarxgui)"
624  << "All Files (*.*)";
625  dialog.setNameFilters(nameFilters);
626 
627  if (dialog.exec())
628  {
629  if (dialog.selectedFiles().size() == 0)
630  {
631  return;
632  }
633 
634  configFilepath = dialog.selectedFiles()[0];
635  }
636  else
637  {
638  ARMARX_INFO << "load config dialog canceled" << std::endl;
639  return;
640  }
641  }
642 
643 
644  closeAllWidgets();
645 
646  QDir dir(configFilepath);
647  dir.makeAbsolute();
648  configFilepath = dir.absolutePath();
649 
650  if (!QFile::exists(configFilepath))
651  {
652  ArmarXWidgetController::showMessageBox("GUI configuration file '" + configFilepath + "' does not exist.");
653  return;
654  }
655 
656  ARMARX_VERBOSE << "Loading config file: " << configFilepath;
657 
658  if (showAsOpenGuiConfig)
659  {
660  addToRecentlyOpenedFileList(configFilepath);
662  }
663 
664  QSettings settings(configFilepath, QSettings::IniFormat);
665 
666 
667  if (settings.allKeys().size() == 0)
668  {
669  ArmarXWidgetController::showMessageBox("Could not find any settings in '" + configFilepath + "'!");
670  return;
671  }
672 
673  // QStringList packagesToLoad = settings.value("loadedPackages").toStringList();
675 
676  // force deterministic loading of plugins by name
677  std::sort(packagesStd.begin(), packagesStd.end(),
678  [](const std::string& lhs, const std::string& rhs) -> bool {
679  return simox::alg::to_lower(lhs) < simox::alg::to_lower(rhs);
680  });
681 
682  QStringList packagesToLoad;
683  ARMARX_VERBOSE << "Discovered: ";
684  for(const auto& pkg : packagesStd)
685  {
686  packagesToLoad.push_back(QString::fromStdString(pkg));
687  ARMARX_VERBOSE << "- " << pkg;
688  }
689 
690  settings.setValue("loadedPackages", packagesToLoad);
691 
692  ARMARX_INFO << "Loaded packages" << packagesStd;
693 
694  foreach (QString package, packagesToLoad)
695  {
696  loadPluginsFromPackage(package);
697  }
698 
699  QStringList widgetNames = settings.value("WidgetCustomNames").toStringList();
700  foreach (QString widgetCustomName, widgetNames)
701  {
702  settings.beginGroup(widgetCustomName);
703  // if(widgetCustomName != ARMARX_VIEWER_NAME || !view3D)
704  {
705  ARMARX_INFO << "Creating widget " << settings.value("WidgetBaseName").toString() << "," << widgetCustomName;
706  ArmarXWidgetControllerPtr widget = createArmarXWidget(settings.value("WidgetBaseName").toString(), widgetCustomName, &settings);
707  // if(widgetCustomName == ARMARX_VIEWER_NAME && !view3D)
708  // view3D = Viewer3DWidgetPtr::dynamicCast(widget);
709  }
710  qApp->processEvents();
711  // widget->getWidget()->resize(settings.value("widgetWidth").toInt(), settings.value("widgetHeight").toInt());<-- not working
712  settings.endGroup();
713  }
714  auto geometryByteArray = settings.value("MainWindowGeometry").toByteArray();
715  if (geometryByteArray.size() > 0)
716  {
717  // for legacy
718  restoreGeometry(geometryByteArray);
719  }
720  else
721  {
722  QRect geometry = settings.value("MainWindowGeometry").toRect();
723  setGeometry(geometry);
724  }
725 
726  if (!restoreState(settings.value("DockWidgetsState").toByteArray()))
727  {
728  ARMARX_WARNING << "Failed to restore state";
729  }
730 
731  foreach (QString widgetCustomName, widgetNames)
732  {
733  settings.beginGroup(widgetCustomName);
734  OpenWidgetMap::iterator it = listOpenWidgets.find(widgetCustomName);
735 
736  if (it != listOpenWidgets.end())
737  {
738  it->first->resize(settings.value("widgetWidth").toInt(), settings.value("widgetHeight").toInt());
739  }
740 
741  settings.endGroup();
742  }
743  if (showAsOpenGuiConfig)
744  {
745  this->configFilepath = configFilepath;
746  appendFileToWindowTitle(configFilepath);
747  }
748  updateOpenWidgetList();
749  QFileInfo file(configFilepath);
750  statusBar()->showMessage("'" + file.fileName() + "' loaded.", 10000);
751 
752  }
753 
754 
755  void ArmarXMainWindow::saveGuiConfig()
756  {
757  if (configFilepath.length() == 0)
758  {
759  QFileDialog dialog(this);
760  dialog.setFileMode(QFileDialog::AnyFile);
761  dialog.setAcceptMode(QFileDialog::AcceptSave);
762  QStringList nameFilters;
763  nameFilters << "ArmarX Gui-Files (*.armarxgui)"
764  << "All Files (*.*)";
765  dialog.setNameFilters(nameFilters);
766 
767  if (dialog.exec())
768  {
769  if (dialog.selectedFiles().size() == 0)
770  {
771  return;
772  }
773 
774  QString file = dialog.selectedFiles()[0];
775  QFileInfo fileInfo(file);
776 
777  if (fileInfo.suffix().isEmpty())
778  {
779  file += ".armarxgui";
780  }
781 
782  configFilepath = file;
783  }
784  else
785  {
786  return;
787  }
788 
789  }
790 
791 
792  QSettings settings(configFilepath, QSettings::IniFormat);
793  settings.clear();
794  // first make all libpaths relative
795  // for (int i = 0; i < loadedPluginFilepaths.size(); ++i) {
796  // loadedPluginFilepaths[i] = QString::fromStdString(loadedPluginFilepaths[i].toStdString());
797  // }
798  settings.setValue("loadedPackages", loadedPackages);
799  settings.setValue("MainWindowGeometry", geometry());
800  settings.setValue("DockWidgetsState", saveState());
801  QStringList widgetCustomNames;
802  OpenWidgetMap::iterator it = listOpenWidgets.begin();
803 
804  for (; it != listOpenWidgets.end(); it++)
805  {
806  QString prefix = it.value().first->objectName();
807  ARMARX_VERBOSE << "Saving widget: " << prefix.toStdString();
808  settings.beginGroup(prefix);
809  ArmarXWidgetControllerPtr w = ArmarXWidgetControllerPtr::dynamicCast(it.value().second);
810 
811  if (w /*&& prefix != ARMARX_VIEWER_NAME*/)
812  {
813  settings.setValue("WidgetBaseName", w->getWidgetName());
814  settings.setValue("widgetWidth", w->getWidget()->width());
815  settings.setValue("widgetHeight", w->getWidget()->height());
816  w->saveSettings(&settings);
817  widgetCustomNames.push_back(prefix);
818  }
819  else
820  {
821  ARMARX_WARNING << "Could not cast widget: " << prefix;
822  }
823 
824  settings.endGroup();
825  }
826 
827  settings.setValue("WidgetCustomNames", widgetCustomNames);
828  ARMARX_INFO << "Saved config to " << configFilepath;
829  appendFileToWindowTitle(configFilepath);
830 
831  // update recently opened file list
832  addToRecentlyOpenedFileList(configFilepath);
834  QFileInfo file(configFilepath);
835  statusBar()->showMessage("'" + file.fileName() + "' saved.", 10000);
836 
837  }
838 
839  void ArmarXMainWindow::saveGuiConfigAs()
840  {
841  configFilepath.clear();
842  saveGuiConfig();
843  }
844 
845  void ArmarXMainWindow::appendFileToWindowTitle(const QString& filepath)
846  {
847  if (filepath.length() > 0)
848  {
849  QDir path(filepath);
850  std::filesystem::path file(filepath.toStdString());
851  path.cdUp();
852 
853  setWindowTitle(guiWindowBaseName + " - " + QString::fromStdString(file.filename().string()) + " in " + path.absolutePath());
854  }
855  else
856  {
857  setWindowTitle(guiWindowBaseName);
858  }
859  }
860 
861 
862 
863  ArmarXWidgetControllerPtr ArmarXMainWindow::createArmarXWidget(QString widgetName, QString customInstanceName, QSettings* settings)
864  {
865 
866  if (listOpenWidgets.find("Dock" + customInstanceName) != listOpenWidgets.end())
867  {
868  ARMARX_WARNING << "A Widget with that name already exists";
869  return NULL;
870  }
871 
872  // HACK: Creating an OpenGL context fails after libPointCloudViewerGuiPlugin.so is loaded.
873  // Therefore, we need to check before calling getWidgetCreator since this loads
874  // the shared object. If we do not do this here, then the following error occurs:
875  // "Can't set up a valid opengl canvas something is seriously wrong with the system"
876  if (widgetName == "VisionX.PointCloudViewer")
877  {
878  ARMARX_INFO << "Creating SoQtExaminerViewer for " << widgetName.toStdString();
879  SoQtExaminerViewer(nullptr, "", TRUE, SoQtExaminerViewer::BUILD_NONE);
880  }
881 
882  auto creator = pluginCache.getWidgetCreator(widgetName);
883 
884  if (!creator)
885  {
886  ArmarXWidgetController::showMessageBox("Could not find widget with Name: " + widgetName);
887  return NULL;
888  }
889  auto widgetUsage = mainSettings.value("WidgetUsageHistory").toList();
890  widgetUsage.push_back(widgetName);
891  if (widgetUsage.size() > widgetUsageHistoryLength)
892  {
893  widgetUsage.pop_front();
894  }
895  mainSettings.setValue("WidgetUsageHistory", widgetUsage);
896 
897 
898  ArmarXWidgetControllerPtr w = creator->createInstance();
899 
900  w->setMainWindow(this);
901  w->setInstanceName(customInstanceName);
902  w->setTipDialog(tipDialog);
903 
904  if (settings)
905  {
906  w->loadSettings(settings);
907  }
908  else if (w->getConfigDialog(this))
909  {
910 
911  ManagedIceObjectPtr comp = ManagedIceObjectPtr::dynamicCast(w->getConfigDialog().data());
912 
913  if (comp)
914  {
915  comp->__setNoDelete(true);
916  registry->addObject(comp, false);
917  }
918 
919  w->getConfigDialog()->setModal(true);
920  connect(w->getConfigDialog().data(), SIGNAL(accepted()), w.get(), SLOT(configAccepted()));
921  connect(w.get(), SIGNAL(configAccepted(ArmarXWidgetControllerPtr)), this, SLOT(addArmarXWidget(ArmarXWidgetControllerPtr)));
922  connect(w->getConfigDialog().data(), SIGNAL(rejected()), w.get(), SLOT(configRejected()));
923  connect(w.get(), SIGNAL(configRejected(ArmarXWidgetControllerPtr)), this, SLOT(addArmarXWidgetCanceled(ArmarXWidgetControllerPtr)));
924 
925  pendingWidgets.push_back(w);
926  w->getConfigDialog()->show();
927  w->getConfigDialog()->raise();
928  w->getConfigDialog()->activateWindow();
929  return w;
930  }
931 
932  // if we are loading a gui config we do not want to create the viewer widget
933  // it will be created later during the loading process
934  addArmarXWidget(w, !settings);
935  return w;
936  }
937 
938  ArmarXWidgetControllerPtr ArmarXMainWindow::addArmarXWidget(ArmarXWidgetControllerPtr newWidgetController, bool createViewerWidget)
939  {
940  for (unsigned int i = 0; i < pendingWidgets.size(); ++i)
941  {
942  if (pendingWidgets[i].get() == newWidgetController.get())
943  {
944  pendingWidgets.erase(pendingWidgets.begin() + i);
945  break;
946  }
947  }
948 
949  QString widgetName = newWidgetController->getWidgetName();
950  QString customInstanceName = newWidgetController->getInstanceName();
951 
952  if (listOpenWidgets.find(customInstanceName) != listOpenWidgets.end())
953  {
954  return NULL;
955  }
956 
957  ARMARX_VERBOSE << "Adding new widget: " << customInstanceName;
958  assert(widgetName == newWidgetController->getWidgetName());
959  ArmarXDockWidget* dockWidget = new ArmarXDockWidget(customInstanceName, newWidgetController);
960  //w->connectDestroySlot();
961  connect(dockWidget, SIGNAL(destroyed(QObject*)), this, SLOT(removeArmarXWidget(QObject*)));
962 
963  dockWidget->setArmarXWidget(newWidgetController->getWidget());
964  dockWidget->setObjectName(customInstanceName);
965  StatusDockWidgetTitleBar* customTitlebar = new StatusDockWidgetTitleBar(dockWidget, this);
966  dockWidget->setTitleBarWidget(customTitlebar);
967  customTitlebar->addCustomWidget(newWidgetController->getCustomTitlebarWidget(dockWidget));
968 
969  if (listOpenWidgets.find(dockWidget->objectName()) != listOpenWidgets.end())
970  {
971  ArmarXWidgetController::showMessageBox("A Widget with the title '" + customInstanceName + "' already exists.");
972  delete dockWidget;
973  return ArmarXWidgetControllerPtr();
974  }
975 
976  QDockWidget* biggestOpenDockWidget = getBiggestOpenWidget();
977  listOpenWidgets[customInstanceName] = qMakePair<QDockWidget*, ArmarXWidgetControllerPtr>(dockWidget, newWidgetController);
978  addDockWidget(Qt::RightDockWidgetArea, dockWidget);
979  newWidgetController->postDocking();
980 
981  QSize widgetStartSize = newWidgetController->getWidget()->size();
982  if (widgetStartSize.width() * widgetStartSize.height() >= 400 * 400)
983  if (biggestOpenDockWidget)
984  {
985  tabifyDockWidget(biggestOpenDockWidget, dockWidget);
986  }
987 
988  dockWidget->show();
989  dockWidget->raise();
990 
991  updateOpenWidgetList();
992 
993  // set it even if no 3d scene may be currently available
994  newWidgetController->setMutex3D(mutex3d);
995 
996  QApplication::instance()->processEvents(); // process events so that the widgets are completetly intialized?
997  ManagedIceObjectPtr comp = ManagedIceObjectPtr::dynamicCast(newWidgetController);
998 
999  if (comp)
1000  {
1001  registry->addObject(comp, false);
1002  ARMARX_INFO << "Waiting for widget initialization " << widgetName << armarx::flush;
1003  int timeoutMs = 30000;
1004 
1005  if (!comp->getObjectScheduler()->waitForObjectState(eManagedIceObjectInitialized, timeoutMs))
1006  {
1007  ARMARX_WARNING << "Widget " << customInstanceName << " was not connected to Ice after " << timeoutMs / 1000 << " seconds" << std::endl;
1008  }
1009  }
1010 
1011  ARMARX_INFO << "Widget initialization done for " << widgetName << armarx::flush;
1012 
1013 
1014 
1015  SoNode* node = newWidgetController->getScene();
1016 
1017  if (node)
1018  {
1019  Viewer3DWidgetPtr viewerInstance;
1020  ARMARX_INFO << "3D Scene available in widget " << widgetName << armarx::flush;
1021  OpenWidgetMap::Iterator it = listOpenWidgets.begin();
1022 
1023  for (; it != listOpenWidgets.end(); it++)
1024  {
1025  viewerInstance = Viewer3DWidgetPtr::dynamicCast(it.value().second);
1026 
1027  if (viewerInstance)
1028  {
1029  break;
1030  }
1031  }
1032 
1033  if (!viewerInstance && createViewerWidget)
1034  // if(listOpenWidgets.find(ARMARX_VIEWER_NAME) == listOpenWidgets.end())
1035  {
1036  ARMARX_INFO << "Setting up CoinQt Viewer";
1037  viewerInstance = setupViewerWidget();
1038  }
1039 
1040  SoSeparator* sep = new SoSeparator;
1041  sep->ref();
1042 
1043  SoPerspectiveCamera* camera = new SoPerspectiveCamera;
1044 
1045  sep->addChild(camera);
1046  sep->addChild(node);
1047 
1048  viewer3DMap[customInstanceName] = {sep, newWidgetController->getSceneConfigDialog()};
1049  emit updateSceneList(viewer3DMap);
1050  }
1051 
1052 
1053  return newWidgetController;
1054  }
1055 
1056  void ArmarXMainWindow::addArmarXWidgetCanceled(ArmarXWidgetControllerPtr newWidgetController)
1057  {
1058  for (unsigned int i = 0; i < pendingWidgets.size(); ++i)
1059  {
1060  if (pendingWidgets[i].get() == newWidgetController.get())
1061  {
1062  pendingWidgets.erase(pendingWidgets.begin() + i);
1063  break;
1064  }
1065  }
1066  }
1067 
1068  void ArmarXMainWindow::removeArmarXWidget(QObject* widget)
1069  {
1070  ARMARX_DEBUG << "removing widgetname: " << widget->objectName();
1071  QDockWidget* dockWidget = qobject_cast<QDockWidget*>(widget);
1072 
1073 
1074  OpenWidgetMap::iterator it = listOpenWidgets.begin();
1075 
1076  for (; it != listOpenWidgets.end(); it++)
1077  {
1078  if (widget == it.value().first)
1079  {
1080 
1081  QString widgetName;
1082 
1083  if (it.value().second)
1084  {
1085  widgetName = it.value().second->getInstanceName();
1086 
1087  }
1088  else
1089  {
1090  if (it.value().first)
1091  {
1092  widgetName = it.value().first->objectName();
1093  }
1094  }
1095 
1096 
1097  listOpenWidgets.erase(it);
1098  updateOpenWidgetList();
1099 
1100 
1101  if (viewer3DMap.contains(widgetName) /*&& view3D->cb3DViewers*/)
1102  {
1103  auto& node = viewer3DMap[widgetName].node;
1104 
1105  if (node)
1106  {
1107  node->unref();
1108  }
1109 
1110  ARMARX_DEBUG << "Removing from 3D list: " << widgetName;
1111  viewer3DMap.remove(widgetName);
1112  emit updateSceneList(viewer3DMap);
1113  }
1114 
1115  break;
1116  }
1117  }
1118 
1119  removeDockWidget(dockWidget);
1120  }
1121 
1122  QPointer<QDockWidget> ArmarXMainWindow::getBiggestOpenWidget()
1123  {
1124  OpenWidgetMap::iterator it = listOpenWidgets.begin();
1125  QPointer<QDockWidget> biggestWidget = NULL;
1126 
1127  for (; it != listOpenWidgets.end(); it++)
1128  {
1129  QDockWidget* dockWidget = it.value().first;
1130 
1131  if (!biggestWidget || dockWidget->size().width() * dockWidget->size().height() > biggestWidget->size().width() * biggestWidget->size().height())
1132  {
1133  biggestWidget = dockWidget;
1134  }
1135  }
1136 
1137  return biggestWidget;
1138  }
1139 
1140  QMenu* ArmarXMainWindow::getCategoryMenu(const std::string& categoryString, QMenu* menu, QIcon categoryIcon)
1141  {
1142  Ice::StringSeq items = simox::alg::split(categoryString, ".");
1143 
1144  if (items.size() <= 1)
1145  {
1146  return menu;
1147  }
1148 
1149  auto actions = menu->actions();
1150 
1151  for (QAction* action : actions)
1152  {
1153  if (action->text().toStdString() == *items.begin())
1154  {
1155  items.erase(items.begin(), items.begin() + 1);
1156  std::string rest = simox::alg::join(items, ".");
1157 
1158  if (!action->menu())
1159  {
1160  action->setMenu(new QMenu(QString::fromStdString(*items.begin()), this));
1161  }
1162 
1163  if (action->icon().isNull() && !categoryIcon.isNull())
1164  {
1165  action->setIcon(categoryIcon);
1166  action->setIconVisibleInMenu(true);
1167  }
1168 
1169  return getCategoryMenu(rest, action->menu(), categoryIcon);
1170  }
1171  }
1172 
1173  return menu->addMenu(QString::fromStdString(*items.begin()));
1174  }
1175 
1176  void ArmarXMainWindow::updateAvailableWidgetList()
1177  {
1178  ui->menuAdd_Widget->clear();
1179 
1180  searchField = new QLineEdit(ui->menuAdd_Widget);
1181  searchField->setToolTip("Search and add a new widget from all loaded ArmarX Gui Plugins");
1182  searchField->setMaximumWidth(250);
1183  searchField->setPlaceholderText("Widget Search");
1184 
1185  QStringList widgetNameList;
1186 
1187  ui->toolBar->clear();
1188 
1189  // EmergencyStop
1190  ui->toolBar->addWidget(emergencyStopWidget->getButtonWidget());
1191 
1192  ui->toolBar->setIconSize(QSize(256, 24));
1193 
1194  actionList.clear();
1195  for (std::pair<QString, ArmarXWidgetInfoPtr> pair : pluginCache.getAvailableWidgets())
1196  {
1197 
1198  QString fullWidgetName = pair.first;
1199  QString widgetName = pair.first;
1200  widgetName = widgetName.remove(0, widgetName.lastIndexOf(".") + 1);
1201  widgetNameList << pair.first;
1202  QIcon categoryIcon;
1203  if (pair.second)
1204  {
1205  categoryIcon = pair.second->getCategoryIcon();
1206  }
1207  else
1208  {
1209  if (QFile::exists(PluginCache::GetCategoryIconPath(pair.first)))
1210  {
1211  categoryIcon = QIcon(PluginCache::GetCategoryIconPath(pair.first));
1212  }
1213  }
1214  auto menu = getCategoryMenu(pair.first.toStdString(), ui->menuAdd_Widget, categoryIcon);
1215  AddArmarXWidgetAction* action = new AddArmarXWidgetAction(widgetName, menu, this);
1216  QIcon widgetIcon;
1217  if (pair.second)
1218  {
1219  widgetIcon = pair.second->getIcon();
1220  }
1221  else
1222  {
1223  if (QFile::exists(PluginCache::GetIconPath(pair.first)))
1224  {
1225  widgetIcon = QIcon(PluginCache::GetIconPath(pair.first));
1226  }
1227  }
1228  action->setIcon(widgetIcon);
1229  action->setIconVisibleInMenu(true);
1230 
1231  action->setData(pair.first);
1232  menu->addAction(action);
1233 
1234  if (mainWidgets.contains(fullWidgetName))
1235  {
1236  bool allowText = false;
1237  addActionToToolBar(action, allowText);
1238  }
1239  actionList[fullWidgetName] = action;
1240  connect(action, SIGNAL(triggered()), action, SLOT(addArmarXWidget()), Qt::UniqueConnection);
1241  connect(action, SIGNAL(clicked(QString, QString)), this, SLOT(createArmarXWidget(QString, QString)), Qt::UniqueConnection);
1242 
1243  }
1244 
1245  addArVizGodotIcon();
1246 
1247  AddArmarXWidgetAction* completerAction = new AddArmarXWidgetAction("", ui->menuAdd_Widget, this);
1248  InfixCompleter* completer = new InfixCompleter(widgetNameList, searchField);
1249  connect(searchField, SIGNAL(textEdited(QString)), completer, SLOT(setCompletionInfix(QString)));
1250 
1251  // connect(completer, SIGNAL(activated(QString)), completerAction, SLOT(triggered(QString)));
1252  connect(completerAction, SIGNAL(accepted()), searchField, SLOT(clear()));
1253  connect(completerAction, SIGNAL(clicked(QString, QString)), this, SLOT(createArmarXWidget(QString, QString)), Qt::UniqueConnection);
1254  searchField->setCompleter(completer);
1255 
1256  ui->toolBar->addSeparator();
1257  ui->toolBar->addWidget(searchField);
1258  QIcon icon;
1259  icon.addFile(QString::fromUtf8("://icons/edit-add.ico"), QSize(), QIcon::Normal, QIcon::Off);
1260  openWidgetButton = new QToolButton(this);
1261  openWidgetButton->setEnabled(false);
1262  openWidgetButton->setIcon(icon);
1263  openWidgetButton->setFixedSize({24, 24});
1264  openWidgetButton->setToolTip("Open selected widget");
1265  connect(openWidgetButton, SIGNAL(clicked()), this, SLOT(openWidgetButtonClicked()), Qt::UniqueConnection);
1266  ui->toolBar->addWidget(openWidgetButton);
1267  connect(searchField, SIGNAL(textChanged(QString)), this, SLOT(updateOpenWidgetButtonStatus(QString)), Qt::UniqueConnection);
1268 
1269  connect(searchField, SIGNAL(returnPressed()), this, SLOT(openWidgetButtonClicked()), Qt::UniqueConnection);
1270 
1271  {
1272  ui->toolBar->addSeparator();
1273  favoritesLabel = new QLabel("Favorites:");
1274  favoritesLabel->setToolTip(
1275  "The favorites are generated from the usage frequency over the last X widget creations."
1276  " Rightclick to change the number of displayed favorites"
1277  );
1278  ui->toolBar->addWidget(favoritesLabel);
1279  //add menu
1280  favoritesLabel->setContextMenuPolicy(Qt::CustomContextMenu);
1281  connect(favoritesLabel, SIGNAL(customContextMenuRequested(const QPoint&)),
1282  this, SLOT(onContextMenuFavoritesRequested(const QPoint&)));
1283  }
1284  updatefavoriteActions();
1285  }
1286 
1287  void ArmarXMainWindow::updateOpenWidgetList()
1288  {
1289  ui->menuWindows->clear();
1290  QAction* closeAllAction = new QAction("Close all widgets", ui->menuWindows);
1291  connect(closeAllAction, SIGNAL(triggered()), this, SLOT(closeAllWidgetsWithDialog()));
1292  ui->menuWindows->addAction(closeAllAction);
1293  ui->menuWindows->addSeparator();
1294 
1295  OpenWidgetMap::iterator it = listOpenWidgets.begin();
1296 
1297  for (; it != listOpenWidgets.end(); it++)
1298  {
1299  QDockWidget* dockWidget = it.value().first;
1300  QAction* action = new QAction(dockWidget ->objectName(), ui->menuWindows);
1301  action->setCheckable(true);
1302  action->setChecked(!dockWidget ->isHidden());
1303 
1304  connect(action, SIGNAL(toggled(bool)), dockWidget, SLOT(setVisible(bool)));
1305  // connect(object, SIGNAL(visibilityChanged(bool)), action, SLOT(setChecked(bool)));
1306  ui->menuWindows->addAction(action);
1307 
1308  }
1309  }
1310 
1311  void ArmarXMainWindow::addArVizGodotIcon()
1312  {
1313  const char* path = std::getenv("arviz_godot_DIR");
1314  if (path == nullptr)
1315  {
1316  return;
1317  }
1318 
1319  std::filesystem::path buildDirectory(path);
1320  std::filesystem::path mainDirectory = buildDirectory.parent_path();
1321 
1322  std::filesystem::path binaryPath = buildDirectory / "bin" / "arviz-godot";
1323  std::filesystem::path iconPath = mainDirectory / "source" / "arviz_godot" / "project" / "icon.png";
1324 
1325  if (not std::filesystem::exists(binaryPath) or not std::filesystem::exists(iconPath))
1326  {
1327  return;
1328  }
1329 
1330  QIcon icon(iconPath.c_str());
1331  QString name("ArViz Godot");
1332 
1333  QAction* action = new QAction(icon, name, this);
1334 
1335  bool allowText = false;
1336  addActionToToolBar(action, allowText);
1337 
1338  auto slot = [action, this, binaryPath]()
1339  {
1340  if (not std::filesystem::exists(binaryPath))
1341  {
1342  QMessageBox errorBox;
1343  errorBox.critical(nullptr, "Error", "The ArViz Godot executable is no longer available.");
1344 
1345  ARMARX_ERROR << "Failed to find ArViz Godot";
1346 
1347  return;
1348  }
1349 
1350  pid_t pid = fork();
1351 
1352  if (pid == -1)
1353  {
1354  ARMARX_ERROR << "Failed to start ArViz Godot";
1355  return;
1356  }
1357 
1358  if (pid != 0)
1359  {
1360  return;
1361  }
1362 
1363  int null = open("/dev/null", O_WRONLY);
1364  dup2(null, STDOUT_FILENO);
1365  dup2(null, STDERR_FILENO);
1366 
1367  execl(binaryPath.c_str(), "arviz-godot", nullptr);
1368  exit(-1);
1369  };
1370 
1371  connect(action, &QAction::triggered, this, slot, Qt::UniqueConnection);
1372  }
1373 
1375  {
1376  QStringList recentlyFiles = mainSettings.value("RecentlyFiles").toStringList();
1377  QMenu* menu = ui->menuRecently_Opened_Files;
1378  auto actions = menu->actions();
1379 
1380  for (QAction* action : actions)
1381  {
1382  if (!action->isCheckable() && !action->isSeparator())
1383  {
1384  menu->removeAction(action);
1385  }
1386  }
1387 
1388  foreach (QString file, recentlyFiles)
1389  {
1390  OpenRecentlyOpenedFileAction* action = new OpenRecentlyOpenedFileAction(file, menu, this);
1391 
1392  action->setCheckable(false);
1393  connect(action, SIGNAL(triggered()), action, SLOT(openFile()));
1394  menu->addAction(action);
1395  }
1396  }
1397 
1398  void ArmarXMainWindow::updateStatusOfOpenWidgets()
1399  {
1400  OpenWidgetMap::iterator it = listOpenWidgets.begin();
1401 
1402  for (; it != listOpenWidgets.end(); it++)
1403  {
1404  QDockWidget* dockWidget = it.value().first;
1405  ManagedIceObjectPtr comp = ManagedIceObjectPtr::dynamicCast(it.value().second);
1406  StatusDockWidgetTitleBar* titlebar = qobject_cast<StatusDockWidgetTitleBar*>(dockWidget->titleBarWidget());
1407 
1408  if (titlebar && comp)
1409  {
1410 
1411  ManagedIceObjectConnectivity con = comp->getConnectivity();
1412  QStringList dependencies;
1413 
1414  for (DependencyMap::iterator i = con.dependencies.begin(); i != con.dependencies.end(); i++)
1415  {
1416  ManagedIceObjectDependencyBasePtr& dep = i->second;
1417 
1418  if (!dep->getResolved() || comp->getState() == eManagedIceObjectStarted)
1419  {
1420  dependencies << QString::fromStdString(dep->getName());
1421  }
1422  }
1423 
1424  titlebar->changeStatus((ManagedIceObjectState)comp->getState(), dependencies);
1425  }
1426  }
1427  }
1428 
1429  void ArmarXMainWindow::enterFullscreenMode()
1430  {
1431  showFullScreen();
1432  ui->toolBar->hide();
1433  ui->menubar->hide();
1434  ui->statusbar->hide();
1435 
1436  // Add actions for leaving fullscreen mode
1437  leaveFullScreenActionF11 = new QAction(this);
1438  leaveFullScreenActionF11->setShortcut(Qt::Key_F11);
1439  connect(leaveFullScreenActionF11, SIGNAL(triggered()), this, SLOT(leaveFullscreenMode()));
1440  addAction(leaveFullScreenActionF11);
1441 
1442  leaveFullScreenActionEsc = new QAction(this);
1443  leaveFullScreenActionEsc->setShortcut(Qt::Key_Escape);
1444  connect(leaveFullScreenActionEsc, SIGNAL(triggered()), this, SLOT(leaveFullscreenMode()));
1445  addAction(leaveFullScreenActionEsc);
1446  }
1447 
1448  void ArmarXMainWindow::leaveFullscreenMode()
1449  {
1450  // Remove actions for leaving fullscreen mode (menu will be available again)
1451  removeAction(leaveFullScreenActionF11);
1452  leaveFullScreenActionF11 = nullptr;
1453 
1454  removeAction(leaveFullScreenActionEsc);
1455  leaveFullScreenActionEsc = nullptr;
1456 
1457  showNormal();
1458  ui->toolBar->show();
1459  ui->menubar->show();
1460  ui->statusbar->show();
1461  }
1462 
1463  void ArmarXMainWindow::toggleWidgetLock()
1464  {
1465  QList<ArmarXDockWidget*> dockWidgets = findChildren<ArmarXDockWidget*>();
1466  if (widgetsLocked)
1467  {
1468  ARMARX_INFO << "Unlocking widgets";
1469  for (auto& widget : dockWidgets)
1470  {
1471  widget->unlockWidget();
1472  }
1473  }
1474  else
1475  {
1476  ARMARX_INFO << "Locking widgets";
1477  for (auto& widget : dockWidgets)
1478  {
1479  widget->lockWidget();
1480  }
1481  }
1482 
1483  widgetsLocked = !widgetsLocked;
1484  }
1485 
1486 
1487 
1491 
1492  AddArmarXWidgetAction::AddArmarXWidgetAction(QString widgetName, QObject* parent, ArmarXMainWindow* mainGui)
1493  : QAction(widgetName, parent),
1494  mainGui(mainGui)
1495  {
1496  dialog = new WidgetNameDialog(widgetName, mainGui);
1497  connect(dialog, SIGNAL(accepted()), this, SLOT(dialogAccepted()));
1498  }
1499 
1501  {
1502  delete dialog;
1503  }
1504 
1505  void AddArmarXWidgetAction::triggered(QString widgetName)
1506  {
1507  if (widgetName.isEmpty())
1508  {
1509  QLineEdit* edit = qobject_cast<QLineEdit*>(sender());
1510  if (edit)
1511  {
1512  widgetName = edit->text();
1513  }
1514  else
1515  {
1516  return;
1517  }
1518  }
1519  ARMARX_INFO_S << "Setting action name to " << widgetName;
1520  setText(widgetName);
1521  setData(widgetName);
1522  addArmarXWidget();
1523  }
1524 
1526  {
1527  dialog->editWidgetName->setText("");// reset so that TextChanged is called for sure
1528  dialog->editWidgetName->setText(this->text());
1529 
1530  if (!dialog->checkWidgetName(this->text()))
1531  {
1532  dialog->setModal(true);
1533  dialog->show();
1534  }
1535  else
1536  {
1537  dialogAccepted();
1538  }
1539  }
1540 
1542  {
1543  emit clicked(this->data().toString(), dialog->editWidgetName->text());
1544  emit accepted();
1545  }
1546 
1547 
1549  QDockWidget(name),
1551  {
1552  scrollArea = new QScrollArea();
1553  scrollArea->setWidgetResizable(true);
1554 
1555  QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
1556  scrollArea->setSizePolicy(sizePolicy);
1557  setWidget(scrollArea);
1558 
1559  savedTitleBar = nullptr;
1560  }
1561 
1563  {
1564  // ARMARX_WARNING_S << "Deleting dockwidget: " << this->windowTitle();
1565  delete scrollArea;
1566  }
1567 
1569  {
1570  scrollArea->setWidget(widget);
1571  }
1572 
1573 
1574  void ArmarXDockWidget::closeEvent(QCloseEvent* event)
1575  {
1576  if (controller && !controller->onClose())
1577  {
1578  event->ignore();
1579  return;
1580  }
1581  else
1582  {
1583  event->accept();
1584  }
1585 
1586  emit destroyed(this); // calls removeArmarXWidget slot
1587 
1588  deleteLater();// use this function, so that pending signals are processed correctly
1589 
1590  }
1591 
1593  {
1594  ARMARX_INFO << "Locking widget: " << objectName();
1595  savedTitleBar = titleBarWidget();
1596  setTitleBarWidget(new QWidget());
1597  if (controller)
1598  {
1599  controller->onLockWidget();
1600  }
1601  }
1602 
1604  {
1605  ARMARX_INFO << "Unlocking widget: " << objectName();
1606  if (savedTitleBar != nullptr)
1607  {
1608  QWidget* old = titleBarWidget();
1609  setTitleBarWidget(savedTitleBar);
1610  savedTitleBar = nullptr;
1611  if (old)
1612  {
1613  old->deleteLater();
1614  }
1615  }
1616  if (controller)
1617  {
1618  controller->onUnlockWidget();
1619  }
1620  }
1621 
1622 
1623 
1624 
1626  QAction(text, parent),
1627  mainGui(mainGui)
1628  {
1629 
1630  }
1631 
1633  {
1634  if (mainGui)
1635  {
1636  mainGui->loadGuiConfig(text());
1637  }
1638  }
1639 
1640 
1641 
1642  void armarx::ArmarXMainWindow::on_actionClear_tip_blacklist_triggered()
1643  {
1644  tipDialog->setBlackListedStrings(QStringList());
1645  mainSettings.setValue(CONFIG_BLACKLISTED_TIPS, tipDialog->getBlackListedStrings());
1646  mainSettings.sync();
1647  ARMARX_INFO << "Blacklist cleared";
1648  }
1649 
1650  void armarx::ArmarXMainWindow::on_actionAbout_triggered()
1651  {
1652  QMessageBox::about(this, "ArmarX Graphical User Interface", QString("ArmarX is being developed at the High Performance Humanoid Technologies (H2T) lab at the Karlsruhe Institute of Technology (KIT)\nCopyright H2T, KIT, ")
1653  + QString(&__DATE__[ 7]) +
1654  + "\nVersion: " + QString::fromStdString(Application::GetVersion()));
1655  }
1656 
1657  void armarx::ArmarXMainWindow::on_actionLoadLastConfig_toggled(bool toggled)
1658  {
1659  mainSettings.setValue(CONFIG_LOAD_LAST_CONFIG, toggled);
1660  mainSettings.sync();
1661  }
1662 
1663 
1664 
1665 
1666  void armarx::ArmarXMainWindow::on_actionArmarX_Documentation_triggered()
1667  {
1668  QDesktopServices::openUrl(QUrl("http://armarx.humanoids.kit.edu/"));
1669  }
1670 
1671  void armarx::ArmarXMainWindow::on_actionOpen_Use_Case_triggered()
1672  {
1673  guiUseCaseSelector->setCancelButtonText("Cancel");
1674  if (guiUseCaseSelector->exec() == QDialog::Accepted)
1675  {
1676  QString path = guiUseCaseSelector->getSelectedConfigFilePath();
1677  ARMARX_INFO << VAROUT(path);
1678  if (!path.isEmpty())
1679  {
1680  loadGuiConfig(path, false);
1681  }
1682  }
1683  mainSettings.setValue("DoNotShowUseCaseDialog", guiUseCaseSelector->getDoNotShowAgain());
1684 
1685  }
1686 
1687  void armarx::ArmarXMainWindow::on_actionClear_plugin_cache_triggered()
1688  {
1689  pluginCache.clearCacheFile();
1690  }
1691 
1692  void ArmarXMainWindow::updateOpenWidgetButtonStatus(QString widgetName)
1693  {
1694  openWidgetButton->setEnabled(pluginCache.getAvailableWidgetNames().contains(widgetName));
1695  }
1696 
1697  void ArmarXMainWindow::openWidgetButtonClicked()
1698  {
1699  addWidgetAction->triggered(searchField->text());
1700  }
1701 
1702  void ArmarXMainWindow::onContextMenuFavoritesRequested(const QPoint& pos)
1703  {
1704  QMenu menu;
1705 
1706  auto numberOfFavIcons = new QSpinBox(&menu);
1707  numberOfFavIcons->setRange(1, 100);
1708  numberOfFavIcons->setSingleStep(1);
1709  numberOfFavIcons->setValue(mainSettings.value("FavoriteWidgetCount", 6).toInt());
1710  numberOfFavIcons->setToolTip("Max number of favorites");
1711  connect(numberOfFavIcons, SIGNAL(valueChanged(int)), this, SLOT(onNumberOfMaxFavoritesChanged(int)));
1712 
1713  QWidgetAction* action = new QWidgetAction{&menu};
1714  action->setDefaultWidget(numberOfFavIcons);
1715  menu.addAction(action);
1716  menu.exec(favoritesLabel->mapToGlobal(pos));
1717  }
1718 
1719  void ArmarXMainWindow::onNumberOfMaxFavoritesChanged(int i)
1720  {
1721  mainSettings.setValue("FavoriteWidgetCount", i);
1722  updatefavoriteActions();
1723  }
1724 
1725  void ArmarXMainWindow::updatefavoriteActions()
1726  {
1727  const auto list = getFavoriteWidgets();
1728  if (
1729  favoriteActionWidgetNames == list
1730  //&&
1731  //favoriteActions.size() == static_cast<std::size_t>(favoriteActionWidgetNames.size())
1732  )
1733  {
1734  return;
1735  }
1736  favoriteActionWidgetNames = list;
1737  for (auto* action : favoriteActions)
1738  {
1739  ui->toolBar->removeAction(action);
1740  action->deleteLater();
1741  }
1742  favoriteActions.clear();
1743  for (auto widgetName : favoriteActionWidgetNames)
1744  {
1745  if (actionList.contains(widgetName))
1746  {
1747  bool allowText = true;
1748  favoriteActions.emplace_back(addActionToToolBar(actionList[widgetName], allowText));
1749  }
1750  }
1751  }
1752 }
armarx::AddArmarXWidgetAction::triggered
void triggered(QString widgetName=QString())
Definition: ArmarXMainWindow.cpp:1505
armarx::ArmarXDockWidget::lockWidget
void lockWidget()
Definition: ArmarXMainWindow.cpp:1592
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::PluginCache::GetCategoryIconPath
static QString GetCategoryIconPath(const QString &widgetName)
Definition: PluginCache.cpp:188
armarx::ArmarXMainWindow::getFavoriteWidgets
QStringList getFavoriteWidgets()
Definition: ArmarXMainWindow.cpp:378
ARMARX_GUI_APPLICATION_NAME
#define ARMARX_GUI_APPLICATION_NAME
Definition: ArmarXMainWindow.cpp:107
armarx::PluginCache::GetIconPath
static QString GetIconPath(const QString &widgetName)
Definition: PluginCache.cpp:183
ArmarXWidgetInfo
The ArmarXWidgetInfo class.
Definition: ArmarXGuiInterface.h:42
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
armarx::ArmarXMainWindow::closeEvent
void closeEvent(QCloseEvent *event) override
emits the closeRequest signal
Definition: ArmarXMainWindow.cpp:520
armarx::ArmarXMainWindow::~ArmarXMainWindow
~ArmarXMainWindow() override
Definition: ArmarXMainWindow.cpp:244
armarx::CMakePackageFinder::FindAllArmarXSourcePackages
static std::vector< std::string > FindAllArmarXSourcePackages()
Definition: CMakePackageFinder.cpp:438
armarx::GuiUseCaseSelector::getSelectedConfigFilePath
QString getSelectedConfigFilePath() const
Definition: GuiUseCaseSelector.cpp:80
slot
std::function< void()> slot
Definition: timer.hpp:35
armarx::ArmarXMainWindow
The ArmarXMainWindow class.
Definition: ArmarXMainWindow.h:80
armarx::CMakePackageFinder
The CMakePackageFinder class provides an interface to the CMake Package finder capabilities.
Definition: CMakePackageFinder.h:53
ArmarXWidgetInfoPtr
std::shared_ptr< ArmarXWidgetInfo > ArmarXWidgetInfoPtr
Definition: ArmarXGuiInterface.h:32
InfixFilterModel.h
armarx::CMakePackageFinder::getLibraryPaths
std::string getLibraryPaths() const
Returns the library paths seperated by semi-colons.
Definition: CMakePackageFinder.h:128
armarx::ArmarXMainWindow::updateRecentlyOpenedFileList
void updateRecentlyOpenedFileList()
Definition: ArmarXMainWindow.cpp:1374
WidgetNameDialog.h
armarx::AddArmarXWidgetAction::~AddArmarXWidgetAction
~AddArmarXWidgetAction() override
Definition: ArmarXMainWindow.cpp:1500
armarx::PluginCache::preloadAsync
void preloadAsync(QStringList widgetNames, int delayMS=1000)
Definition: PluginCache.cpp:205
armarx::ArmarXMainWindow::appendFileToWindowTitle
void appendFileToWindowTitle(const QString &filepath="")
Definition: ArmarXMainWindow.cpp:845
armarx::StatusDockWidgetTitleBar::changeStatus
void changeStatus(ManagedIceObjectState state, QStringList dependencies)
Definition: TitlebarWidget.cpp:180
ARMARX_VIEWER_NAME
#define ARMARX_VIEWER_NAME
Definition: ViewerWidget.h:30
armarx::WidgetNameDialog::checkWidgetName
bool checkWidgetName(QString name)
Definition: WidgetNameDialog.cpp:63
armarx::ArmarXMainWindow::loadPlugin
void loadPlugin(QString filePath)
loads a plugin with the given file path
Definition: ArmarXMainWindow.cpp:498
armarx::ArmarXMainWindow::addToRecentlyOpenedFileList
void addToRecentlyOpenedFileList(QString configFilepath)
Definition: ArmarXMainWindow.cpp:577
IceInternal::Handle< ManagedIceObject >
armarx::ArmarXMainWindow::updateSceneList
void updateSceneList(QMap< QString, Viewer3DInfo >)
armarx::StatusDockWidgetTitleBar
The StatusDockWidgetTitleBar class.
Definition: TitlebarWidget.h:50
armarx::TipDialog
The TipDialog is a dialog to show tips/hints to the user, which are optionally only shown once.
Definition: TipDialog.h:47
armarx::ArmarXDockWidget::ArmarXDockWidget
ArmarXDockWidget(QString name, ArmarXWidgetControllerPtr controller)
Definition: ArmarXMainWindow.cpp:1548
armarx::Viewer3DWidgetPtr
IceUtil::Handle< Viewer3DWidget > Viewer3DWidgetPtr
Definition: ViewerWidget.h:139
armarx::ArmarXMainWindow::existsWidget
bool existsWidget(const QString &widgetName)
Definition: ArmarXMainWindow.cpp:492
armarx::PluginCache::cacheWidget
bool cacheWidget(QString widgetName, ArmarXWidgetInfoPtr widgetCreator)
Definition: PluginCache.cpp:100
CONFIG_LOAD_LAST_CONFIG
#define CONFIG_LOAD_LAST_CONFIG
Definition: ArmarXMainWindow.cpp:109
controller
Definition: AddOperation.h:39
ArmarXComponentWidgetController.h
ArmarXMainWindow.h
GuiUseCaseSelector.h
armarx::PluginCache::getWidgetCreator
ArmarXWidgetInfoPtr getWidgetCreator(const QString &widgetName)
Definition: PluginCache.cpp:107
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::PluginCache::removePluginFromCache
void removePluginFromCache(QString pluginPath)
Definition: PluginCache.cpp:288
armarx::ArmarXDataPath
Definition: ArmarXDataPath.h:57
armarx::PluginCache::getAvailableWidgets
WidgetCreatorMap getAvailableWidgets() const
Definition: PluginCache.cpp:148
armarx::ManagedIceObjectPtr
IceInternal::Handle< ManagedIceObject > ManagedIceObjectPtr
Definition: ArmarXFwd.h:42
armarx::ArmarXMainWindow::getLibraryPathFromPackage
QString getLibraryPathFromPackage(const QString &packageName)
Definition: ArmarXMainWindow.cpp:368
ArmarXObjectScheduler.h
InfixCompleter.h
armarx::ArmarXMainWindow::getViewerWidget
Viewer3DWidgetPtr getViewerWidget()
Provides access to a viewer widget, if existent.
Definition: ArmarXMainWindow.cpp:602
armarx::WidgetNameDialog
The WidgetNameDialog class.
Definition: WidgetNameDialog.h:42
armarx::ArmarXMainWindow::getDefaultPackageNames
std::vector< std::string > getDefaultPackageNames()
getDefaultPackageNames returns the names of all packages which are searched for plugins when the Arma...
Definition: ArmarXMainWindow.cpp:596
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
ViewerWidget.h
armarx::ArmarXDockWidget::setArmarXWidget
void setArmarXWidget(QWidget *widget)
Definition: ArmarXMainWindow.cpp:1568
armarx::ArmarXMainWindow::loadGuiConfig
void loadGuiConfig(QString configFilepath="", bool showAsOpenGuiConfig=true)
Definition: ArmarXMainWindow.cpp:614
armarx::ArmarXDockWidget::unlockWidget
void unlockWidget()
Definition: ArmarXMainWindow.cpp:1603
armarx::OpenRecentlyOpenedFileAction
Definition: ArmarXMainWindow.h:323
armarx::AddArmarXWidgetAction::AddArmarXWidgetAction
AddArmarXWidgetAction(QString widgetName, QObject *parent=0, ArmarXMainWindow *mainGui=0)
Definition: ArmarXMainWindow.cpp:1492
Component.h
GfxTL::Off
OnOff< false > Off
Definition: OnOff.h:11
armarx::ArmarXMainWindow::ArmarXMainWindow
ArmarXMainWindow(const armarx::ManagedIceObjectRegistryInterfacePtr &registry, const std::vector< std::string > &packages, const QString &configToLoad, bool disablePreloading)
Definition: ArmarXMainWindow.cpp:114
armarx::OpenRecentlyOpenedFileAction::OpenRecentlyOpenedFileAction
OpenRecentlyOpenedFileAction(QString text, QObject *parent=0, ArmarXMainWindow *mainGui=0)
Definition: ArmarXMainWindow.cpp:1625
armarx::AddArmarXWidgetAction::accepted
void accepted()
armarx::ArmarXMainWindow::closeRequest
void closeRequest()
emitted, when the main window should be closed
armarx::ArmarXWidgetController::showMessageBox
static int showMessageBox(const QString &msg)
Definition: ArmarXWidgetController.cpp:166
armarx::WidgetNameDialog::editWidgetName
QLineEdit * editWidgetName
Definition: WidgetNameDialog.h:53
CMakePackageFinder.h
No
Introduction Thank you for taking interest in our work and downloading this software This library implements the algorithm described in the paper R R R Klein Efficient RANSAC for Point Cloud Shape in Computer Graphics No
Definition: ReadMe.txt:21
TitlebarWidget.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
IceUtil::Handle< ManagedIceObjectRegistryInterface >
LogSender.h
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:27
armarx::Application::GetVersion
static std::string GetVersion()
Definition: Application.h:234
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:200
CONFIG_BLACKLISTED_TIPS
#define CONFIG_BLACKLISTED_TIPS
Definition: ArmarXMainWindow.cpp:110
TipDialog.h
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
armarx::Logging::setTag
void setTag(const LogTag &tag)
Definition: Logging.cpp:55
armarx::ArmarXWidgetControllerPtr
IceUtil::Handle< ArmarXWidgetController > ArmarXWidgetControllerPtr
Definition: ArmarXWidgetController.h:45
armarx::GuiUseCaseSelector
Definition: GuiUseCaseSelector.h:40
armarx::Viewer3DWidget::GetWidgetIcon
static QIcon GetWidgetIcon()
Definition: ViewerWidget.h:125
armarx::ArmarXMainWindow::loadPluginsFromPackage
void loadPluginsFromPackage(const QString &packageName)
Definition: ArmarXMainWindow.cpp:413
armarx::ArmarXDockWidget::~ArmarXDockWidget
~ArmarXDockWidget() override
Definition: ArmarXMainWindow.cpp:1562
armarx::AddArmarXWidgetAction
Definition: ArmarXMainWindow.h:303
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::AddArmarXWidgetAction::clicked
void clicked(QString widgetName, QString customInstanceName)
armarx::AddArmarXWidgetAction::addArmarXWidget
void addArmarXWidget()
Definition: ArmarXMainWindow.cpp:1525
armarx::PluginCache::getAvailableWidgetNames
QStringList getAvailableWidgetNames() const
Definition: PluginCache.cpp:133
ArmarXDataPath.h
armarx::OpenRecentlyOpenedFileAction::openFile
void openFile()
Definition: ArmarXMainWindow.cpp:1632
armarx::ArmarXDockWidget::closeEvent
void closeEvent(QCloseEvent *event) override
Definition: ArmarXMainWindow.cpp:1574
armarx::AddArmarXWidgetAction::dialogAccepted
void dialogAccepted()
Definition: ArmarXMainWindow.cpp:1541
armarx::GuiUseCaseSelector::getDoNotShowAgain
bool getDoNotShowAgain() const
Definition: GuiUseCaseSelector.cpp:93
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:36
GfxTL::Yes
OnOff< true > Yes
Definition: OnOff.h:12
armarx::PluginCache::cachePlugin
bool cachePlugin(const QString &pluginPath)
Definition: PluginCache.cpp:57