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