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