detailedapplicationview.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 ArmarXCore::core
19  * @author Cedric Seehausen (usdnr at kit dot edu)
20  * @date 2016
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
26 
27 #include <QMenu>
28 #include <QToolButton>
29 
36 
37 #include <ArmarXGui/gui-plugins/ScenarioManager/gui/ui_detailedapplicationview.h>
38 
39 #define UPDATE_TIMER_INTERVAL 500
40 
41 using namespace ScenarioManager;
42 using namespace Data_Structure;
43 
44 template <class... T>
45 static void
46 setWatcherPaths(QFileSystemWatcher& watcher, T... paths)
47 {
48  if (not watcher.files().empty())
49  {
50  watcher.removePaths(watcher.files());
51  }
52  if (not watcher.directories().empty())
53  {
54  watcher.removePaths(watcher.directories());
55  }
56 
57  (watcher.addPath(QString::fromStdString(paths)), ...);
58 }
59 
60 // Returns {package, scenario}
61 std::pair<std::string, std::string>
62 scenarioInfoFromLink(const std::filesystem::path& linkpath)
63 {
64  auto instancePath = std::filesystem::canonical(linkpath);
65  auto scenarioFolder = instancePath.parent_path().parent_path();
66  std::string scenarioName = scenarioFolder.filename();
67  auto scenarioScx = scenarioFolder / (scenarioName + ".scx");
68  if (!std::filesystem::exists(scenarioScx))
69  {
70  return {"unknown", "unknown"};
71  }
72  auto packageName =
74 
75  if (packageName.empty())
76  {
77  return {"unknown", scenarioName};
78  }
79 
80  return {packageName, scenarioName};
81 }
82 
84  QWidget(parent),
85  ui(new Ui::DetailedApplicationView),
86  variantManager(nullptr),
87  variantFactory(nullptr),
88  statusUpdateRelevant(false),
89  lastScenarioItem(nullptr),
90  neadsUpdate(false)
91 {
92  updateTimer.setSingleShot(true);
93  QObject::connect(&updateTimer, SIGNAL(timeout()), this, SLOT(on_fileUpdate()));
94 
95 
96  QObject::connect(&fileSystemWatcher,
97  &QFileSystemWatcher::fileChanged,
98  this,
99  &DetailedApplicationView::on_fileWatcherUpdate);
100 }
101 
103 {
104  delete ui;
105 }
106 
107 void
108 DetailedApplicationView::init()
109 {
110  ui->setupUi(this);
111  variantManager = std::shared_ptr<OptionalVariantManager>(new OptionalVariantManager());
112  variantFactory = std::shared_ptr<OptionalVariantFactory>(new OptionalVariantFactory());
113 
114  ui->propertyBrowser->setFactoryForManager(variantManager.get(), variantFactory.get());
115 
116  ui->propertyBrowser->setAlternatingRowColors(true);
117  ui->propertyBrowser->setResizeMode(QtTreePropertyBrowser::ResizeMode::Interactive);
118  ui->propertyBrowser->setSplitterPosition(200);
119 
120  QObject::connect(variantManager.get(),
121  SIGNAL(valueChanged(QtProperty*, const QVariant&)),
122  this,
123  SLOT(itemChanged(QtProperty*, const QVariant&)));
124 
125  QObject::connect(variantManager.get(),
126  SIGNAL(attributeChanged(QtProperty*, const QString&, const QVariant&)),
127  this,
128  SLOT(itemAttributeChanged(QtProperty*, const QString&, const QVariant&)));
129 
130 
131  void attributeChanged(QtProperty * property, const QString& attribute, const QVariant& val);
132 
133  ui->linkedInfoLabel->setVisible(false);
134  ui->makeLocalButton->setVisible(false);
135  ui->addParameterButton->setEnabled(false);
136  //QObject::connect(variantManager.get(), SIGNAL())
137 }
138 
139 void
142 {
143  if (application.get() == nullptr)
144  {
145  return;
146  }
147  if (variantManager.get() == nullptr || variantFactory.get() == nullptr)
148  {
149  init();
150  }
151 
152  ui->dataLabel->setText(QString::fromStdString(application->getName()));
153 
154  lastAppInstance = ApplicationInstancePtr();
155  lastScenario = ScenarioPtr();
156  lastScenarioItem = nullptr;
157  statusUpdateRelevant = false;
158 
159  ui->stateLabel->setStyleSheet("QLabel { color : black; }");
160  ui->stateLabel->setText("No Status");
161 
162  ui->startButton->setEnabled(false);
163  ui->stopButton->setEnabled(false);
164  ui->restartButton->setEnabled(false);
165  ui->addParameterButton->setEnabled(false);
166  ui->addParameterButton->setMenu(nullptr);
167 
168  ui->toolButton->setEnabled(false);
169 
170  //build propertybrowser items
171  variantManager->clear();
172  static_cast<OptionalVariantFactory*>(variantFactory.get())
173  ->setElementName(QString::fromStdString(application->getName()));
174  ui->propertyBrowser->clear();
175 
176  QtProperty* appTopItem = variantManager->addProperty(QtVariantPropertyManager::groupTypeId(),
177  QLatin1String("Application"));
178 
179  appTopItem->setEnabled(false);
180 
181  QtVariantProperty* nameItem = variantManager->addProperty(QVariant::String, QString("Name"));
182  nameItem->setValue(QString::fromStdString(application->getName()));
183  appTopItem->addSubProperty(nameItem);
184 
185  QtVariantProperty* execPathItem =
186  variantManager->addProperty(QVariant::String, QString("Executable Path"));
187  execPathItem->setValue(QString::fromStdString(application->getPathToExecutable()));
188  appTopItem->addSubProperty(execPathItem);
189 
190  QtProperty* appPropertyTopItem = variantManager->addProperty(
191  QtVariantPropertyManager::groupTypeId(), QLatin1String("Default Properties"));
192  appTopItem->addSubProperty(appPropertyTopItem);
193 
194  armarx::PropertyDefinitionsPtr props = application->getProperties();
195 
196  Ice::PropertyDict dict = props->getProperties()->getPropertiesForPrefix("");
197 
198  for (auto const& property : dict)
199  {
200  QStringList valueList;
201  if (props->hasDefinition(property.first))
202  {
204  props->getDefintion<std::string>(property.first);
205  auto keys = armarx::getMapKeys(propDef.getValueMap());
206  ARMARX_INFO << VAROUT(keys);
207  for (auto& key : keys)
208  {
209  valueList << QString::fromStdString(key);
210  }
211  }
212  else
213  {
214  ARMARX_WARNING << "Could not find definition: " << property.first;
215  }
216 
217 
218  QtVariantProperty* appPropertyItem =
219  variantManager->addProperty(QVariant::String, QString::fromStdString(property.first));
220 
221  appPropertyItem->setAttribute("PossibleValues", valueList);
222 
223  appPropertyItem->setValue(QString::fromStdString(property.second));
224  appPropertyItem->setStatusTip(QString::fromStdString(props->getDescription()));
225  if (property.second.compare("<set value!>") == 0 ||
226  property.second.compare("::_NOT_SET_::") == 0)
227  {
228  //There is currently no way to change colors of any sort in qtproperty browser but if you later want to add this do it here
229  }
230  appPropertyTopItem->addSubProperty(appPropertyItem);
231  }
232 
233  ui->propertyBrowser->addProperty(appTopItem);
234  ui->propertyBrowser->setRootIsDecorated(false);
235 }
236 
237 void
239  ScenarioItem* item)
240 {
241  if (appInstance.get() == nullptr)
242  {
244  return;
245  }
246 
247  if (variantManager.get() == nullptr || variantFactory.get() == nullptr)
248  {
249  init();
250  }
251 
252  // ignore any updates due to us setting the values
253  statusUpdateRelevant = false;
254 
255  // watch the config file of this application
256  const auto appConfigFile = appInstance->getConfigPath();
257  setWatcherPaths(fileSystemWatcher, appConfigFile);
258 
259  if (appInstance->getStatus() == "Running")
260  {
261  ui->stateLabel->setStyleSheet("QLabel { color : green; }");
262  //stateLabelPallet.setColor(QPalette::WindowText, Qt::blue);
263  }
264  else if (appInstance->getStatus().compare("Stopped") == 0)
265  {
266  ui->stateLabel->setStyleSheet("QLabel { color : red; }");
267  }
268  else if (appInstance->getStatus().compare("Inactive") == 0)
269  {
270  ui->stateLabel->setStyleSheet("QLabel { color : gray; }");
271  }
272  else
273  {
274  ui->stateLabel->setStyleSheet("QLabel { color : black; }");
275  }
276 
277  bool readOnly = appInstance->isReadOnly();
278  ui->linkedInfoLabel->setVisible(readOnly);
279  ui->linkedInfoLabel->setText("Linked Application - read only");
280  ui->linkedInfoLabel->setToolTip(
281  "The application's config file is a link to another file, making it read only");
282  ui->makeLocalButton->setVisible(readOnly);
283  ui->makeLocalButton->setToolTip("Replace the linked application with a local copy");
284  ui->addParameterButton->setEnabled(!readOnly);
285 
286  std::string label = appInstance->getName();
287  if (readOnly)
288  {
289  auto [package, scenario] = scenarioInfoFromLink(appInstance->getConfigPath());
290  label += " -> " + scenario;
291  std::string tooltip;
292  if (package == "unknown")
293  {
294  tooltip = "Could not determine original scenario for config '" +
295  std::string(std::filesystem::canonical(appInstance->getConfigPath())) + "'";
296  }
297  else
298  {
299  tooltip = "Original is in " +
300  (package == "unknown" ? "unknown package" : "package " + package) +
301  ", scenario " + scenario;
302  }
303  ui->dataLabel->setToolTip(QString::fromStdString(tooltip));
304  }
305  ui->dataLabel->setText(QString::fromStdString(label));
306 
307  lastAppInstance = appInstance;
308  lastScenario = ScenarioPtr(nullptr);
309  if (item != nullptr)
310  {
311  lastScenarioItem = item;
312  }
313 
314  if (lastAppInstance->getEnabled())
315  {
316  ui->startButton->setEnabled(true);
317  ui->stopButton->setEnabled(true);
318  ui->restartButton->setEnabled(true);
319  }
320  else
321  {
322  ui->startButton->setEnabled(false);
323  ui->stopButton->setEnabled(false);
324  ui->restartButton->setEnabled(false);
325  }
326 
327  ui->addParameterButton->setMenu(nullptr);
328  ui->toolButton->setEnabled(true);
329 
330  //build propertybrowser items
331  variantManager->clear();
332  static_cast<OptionalVariantFactory*>(variantFactory.get())
333  ->setElementName(QString::fromStdString(appInstance->getName()));
334  ui->propertyBrowser->clear();
335 
336  QtProperty* appInstanceTopItem = variantManager->addProperty(
337  QtVariantPropertyManager::groupTypeId(), QLatin1String("ApplicationInstance"));
338 
339  if (!appInstance->isConfigWritable() || appInstance->isReadOnly())
340  {
341  appInstanceTopItem->setEnabled(false);
342  }
343 
344  QtVariantProperty* nameItem = variantManager->addProperty(QVariant::String, QString("Name"));
345 
346  nameItem->setValue(QString::fromStdString(appInstance->getName()));
347  appInstanceTopItem->addSubProperty(nameItem);
348 
349  QtVariantProperty* execPathItem =
350  variantManager->addProperty(QVariant::String, QString("Executable Path"));
351  execPathItem->setValue(QString::fromStdString(appInstance->getPathToExecutable()));
352  appInstanceTopItem->addSubProperty(execPathItem);
353 
354  QtVariantProperty* instanceNameItem =
355  variantManager->addProperty(QVariant::String, QString("Instance Name"));
356  instanceNameItem->setValue(QString::fromStdString(appInstance->getInstanceName()));
357  appInstanceTopItem->addSubProperty(instanceNameItem);
358 
359  QtVariantProperty* configPathItem =
360  variantManager->addProperty(QVariant::String, QString("Config Path"));
361  configPathItem->setValue(QString::fromStdString(appInstance->getConfigPath()));
362  appInstanceTopItem->addSubProperty(configPathItem);
363 
364  QtVariantProperty* pidItem =
365  variantManager->addProperty(QVariant::Int, QString("Pid (Stopped = -1)"));
366  pidItem->setValue(appInstance->getPid());
367  pidItem->setEnabled(false);
368  appInstanceTopItem->addSubProperty(pidItem);
369 
370  QtVariantProperty* enabledItem =
371  variantManager->addProperty(QVariant::Bool, QString("Enabled"));
372  enabledItem->setValue(appInstance->getEnabled());
373  appInstanceTopItem->addSubProperty(enabledItem);
374 
375  QtProperty* appPropertyTopItem = variantManager->addProperty(
376  QtVariantPropertyManager::groupTypeId(), QLatin1String("Properties"));
377  appInstanceTopItem->addSubProperty(appPropertyTopItem);
378 
379  armarx::PropertyDefinitionsPtr props = appInstance->getProperties();
380 
381  Ice::PropertyDict dict = props->getProperties()->getPropertiesForPrefix("");
382 
383  for (auto const& property : dict)
384  {
385  if (property.first != "Ice.Config")
386  {
387  QStringList valueList;
388  if (props->hasDefinition(property.first))
389  {
391  props->getDefintion<std::string>(property.first);
392  auto keys = armarx::getMapKeys(propDef.getValueMap());
393  for (auto& key : keys)
394  {
395  valueList << QString::fromStdString(key);
396  }
397  }
398  else
399  {
400  ARMARX_WARNING << "Could not find definition: " << property.first;
401  }
402 
403 
404  QtVariantProperty* appPropertyItem;
405  if (appInstance->isDefaultProperty(property.first))
406  {
407  appPropertyItem =
408  variantManager->addProperty(OptionalVariantManager::optionalProprtyTypeId(),
409  QString::fromStdString(property.first));
410 
411  appPropertyItem->setAttribute(
412  QLatin1String("enabled"),
413  QVariant(appInstance->isDefaultPropertyEnabled(property.first)));
414  }
415  else
416  {
417  appPropertyItem = variantManager->addProperty(
418  QVariant::String, QString::fromStdString(property.first));
419  }
420  appPropertyItem->setValue(QString::fromStdString(property.second));
421  appPropertyItem->setAttribute(QLatin1String("PossibleValues"), QVariant(valueList));
422 
423  try
424  {
426  auto helpString = props->getDefintion<std::string>(property.first)
427  .toString(formatter, props->getValue(property.first));
428 
429  QString result = QString::fromStdString("Current value: " + property.second +
430  "\n\n" + helpString);
431  appPropertyItem->setToolTip(result);
432  }
433  catch (armarx::LocalException&)
434  {
435  //nothing to do
436  }
437 
438  appPropertyItem->setAttribute(QLatin1String("readOnly"),
439  QVariant(appInstance->isReadOnly()));
440 
441  appPropertyTopItem->addSubProperty(appPropertyItem);
442  }
443  }
444 
445  QtProperty* appIcePropertyTopItem = variantManager->addProperty(
446  QtVariantPropertyManager::groupTypeId(), QLatin1String("Ice Deployment Properties"));
447  appInstanceTopItem->addSubProperty(appIcePropertyTopItem);
448 
449  QtVariantProperty* nodePropertyItem =
450  variantManager->addProperty(QVariant::String, "Node Name");
451  nodePropertyItem->setValue(QString::fromStdString(appInstance->getNodeName()));
452  nodePropertyItem->setToolTip(
453  "Describes on which Node the current Application should be deployed on");
454  nodePropertyItem->setAttribute(QLatin1String("readOnly"), QVariant(appInstance->isReadOnly()));
455  appIcePropertyTopItem->addSubProperty(nodePropertyItem);
456 
457  QtVariantProperty* iceAutoRestartItem =
458  variantManager->addProperty(QVariant::Bool, "Ice Auto Restart");
459  // iceAutoRestartItem->setValue(appInstance->getIceAutoRestart());
460  iceAutoRestartItem->setToolTip(
461  "Describes if Ice should automatically restart this Application");
462  iceAutoRestartItem->setAttribute("enabled", QVariant(appInstance->isReadOnly()));
463  appIcePropertyTopItem->addSubProperty(iceAutoRestartItem);
464 
465  ui->propertyBrowser->addProperty(appInstanceTopItem);
466  ui->propertyBrowser->setRootIsDecorated(false);
467 
468  // re-enable updates
469  statusUpdateRelevant = true;
470 }
471 
472 void
474 {
475  if (scenario.get() == nullptr)
476  {
478  return;
479  }
480 
481  if (variantManager.get() == nullptr || variantFactory.get() == nullptr)
482  {
483  init();
484  }
485 
486  // ignore any updates due to us setting the values
487  statusUpdateRelevant = false;
488 
489  // watch the global config file of this scenario
490  const auto scenarioGlobalConfigFile = scenario->getGlobalConfigPath();
491  setWatcherPaths(fileSystemWatcher, scenarioGlobalConfigFile);
492 
493 
494  ui->dataLabel->setText(QString::fromStdString(scenario->getName()));
495  lastScenario = scenario;
496  lastAppInstance = ApplicationInstancePtr(nullptr);
497  lastScenarioItem = nullptr;
498 
499  QAction* addVariableToScenarioAction = new QAction(this);
500  QIcon icon;
501  icon.addFile(QString::fromUtf8(":/icons/images/add.png"), QSize(), QIcon::Normal, QIcon::Off);
502  addVariableToScenarioAction->setIcon(icon);
503  addVariableToScenarioAction->setIconVisibleInMenu(true);
504  addVariableToScenarioAction->setText("Add Scenario Variable");
505  addVariableToScenarioAction->setToolTip("Add an Variable to the Scenario");
506  connect(addVariableToScenarioAction,
507  SIGNAL(triggered()),
508  this,
509  SLOT(on_addParameterButton_clicked()));
510 
511  QAction* addVariableToIceAction = new QAction(this);
512  addVariableToIceAction->setIcon(icon);
513  addVariableToIceAction->setIconVisibleInMenu(true);
514  addVariableToIceAction->setText("Add Ice Enviroment Variable");
515  addVariableToIceAction->setToolTip("Add an Ice Enviroment Variable to the Scenario");
516  connect(addVariableToIceAction, SIGNAL(triggered()), this, SLOT(on_addIceEnvButton_clicked()));
517 
518  QMenu* subMenu = new QMenu(this);
519  subMenu->addAction(addVariableToScenarioAction);
520  subMenu->addAction(addVariableToIceAction);
521 
522 
523  bool readOnly = scenario->isReadOnly();
524  ui->linkedInfoLabel->setVisible(readOnly);
525  ui->linkedInfoLabel->setText("Linked Scenario config - read only");
526  ui->linkedInfoLabel->setToolTip(
527  "The Secnario's global configuration is a link to another file, making it read only");
528  ui->makeLocalButton->setVisible(readOnly);
529  ui->makeLocalButton->setToolTip("Replace the linked global scenario configuration with a local "
530  "copy. Does not alter any applications.");
531  ui->addParameterButton->setEnabled(!readOnly);
532 
533  std::string label = scenario->getName();
534  if (readOnly)
535  {
536  auto [package, origScenario] = scenarioInfoFromLink(scenario->getGlobalConfigPath());
537  label += " -> " + origScenario;
538  std::string tooltip;
539  if (package == "unknown")
540  {
541  tooltip = "Could not determine original scenario for config '" +
542  std::string(std::filesystem::canonical(scenario->getGlobalConfigPath())) +
543  "'";
544  }
545  else
546  {
547  tooltip = "Original is in " +
548  (package == "unknown" ? "unknown package" : "package " + package) +
549  ", scenario " + origScenario;
550  }
551  ui->dataLabel->setToolTip(QString::fromStdString(tooltip));
552  }
553  ui->dataLabel->setText(QString::fromStdString(label));
554 
555  //ui->addParameterButton->setPopupMode(QToolButton::InstantPopup);
556  ui->addParameterButton->setMenu(subMenu);
557 
558 
559  if (scenario->getStatus().compare("Running") == 0)
560  {
561  ui->stateLabel->setStyleSheet("QLabel { color : green; }");
562  //stateLabelPallet.setColor(QPalette::WindowText, Qt::blue);
563  }
564  else if (scenario->getStatus().compare("Stopped") == 0)
565  {
566  ui->stateLabel->setStyleSheet("QLabel { color : red; }");
567  }
568  else if (scenario->getStatus().compare("Inactive") == 0)
569  {
570  ui->stateLabel->setStyleSheet("QLabel { color : gray; }");
571  }
572  else if (scenario->getStatus().compare("Mixed") == 0)
573  {
574  ui->stateLabel->setStyleSheet("QLabel { color : darkYellow; }");
575  }
576  else
577  {
578  ui->stateLabel->setStyleSheet("QLabel { color : black; }");
579  }
580 
581 
582  ui->stateLabel->setText(QString::fromStdString(scenario->getStatus()));
583 
584  ui->startButton->setEnabled(true);
585  ui->restartButton->setEnabled(true);
586  ui->stopButton->setEnabled(true);
587  ui->toolButton->setEnabled(true);
588 
589  //build propertybrowser items
590  variantManager->clear();
591  static_cast<OptionalVariantFactory*>(variantFactory.get())
592  ->setElementName(QString::fromStdString(scenario->getName()));
593  ui->propertyBrowser->clear();
594 
595  QtProperty* scenarioTopItem = variantManager->addProperty(
596  QtVariantPropertyManager::groupTypeId(), QLatin1String("Scenario"));
597  if (!scenario->isScenarioFileWriteable() || scenario->isReadOnly())
598  {
599  scenarioTopItem->setEnabled(false);
600  }
601 
602  QtVariantProperty* nameItem = variantManager->addProperty(QVariant::String, QString("Name"));
603  nameItem->setValue(QString::fromStdString(scenario->getName()));
604  scenarioTopItem->addSubProperty(nameItem);
605 
606  QtVariantProperty* scenarioPathItem =
607  variantManager->addProperty(QVariant::String, QString("Scenario Path"));
608  scenarioPathItem->setValue(QString::fromStdString(scenario->getPath()));
609  scenarioTopItem->addSubProperty(scenarioPathItem);
610 
611  QtVariantProperty* createdAtItem =
612  variantManager->addProperty(QVariant::String, QString("Created At"));
613  createdAtItem->setValue(QString::fromStdString(scenario->getCreationTime()));
614  scenarioTopItem->addSubProperty(createdAtItem);
615 
616  QtVariantProperty* lastChangeItem =
617  variantManager->addProperty(QVariant::String, QString("Last Change At"));
618  lastChangeItem->setValue(QString::fromStdString(scenario->getLastChangedTime()));
619  scenarioTopItem->addSubProperty(lastChangeItem);
620 
621  QtProperty* scenarioPropertyTopItem = variantManager->addProperty(
622  QtVariantPropertyManager::groupTypeId(), QLatin1String("Scenario Properties"));
623  scenarioTopItem->addSubProperty(scenarioPropertyTopItem);
624  if (!scenario->isGlobalConfigWritable())
625  {
626  scenarioPropertyTopItem->setEnabled(false);
627  }
628 
629  armarx::PropertyDefinitionsPtr props = scenario->getGlobalConfig();
630 
631  Ice::PropertyDict dict = props->getProperties()->getPropertiesForPrefix("");
632 
633  for (auto const& property : dict)
634  {
635  if (property.first != "Ice.Config")
636  {
637  QtVariantProperty* scenarioPropertyItem = variantManager->addProperty(
638  QVariant::String, QString::fromStdString(property.first));
639  scenarioPropertyItem->setValue(QString::fromStdString(property.second));
640  try
641  {
642  scenarioPropertyItem->setToolTip(QString::fromStdString(
643  props->getDefintion<std::string>(property.first).getDescription()));
644  }
645  catch (armarx::LocalException&)
646  {
647  //nothing to do
648  }
649 
650  scenarioPropertyItem->setAttribute(QLatin1String("readOnly"),
651  QVariant(scenario->isReadOnly()));
652  scenarioPropertyTopItem->addSubProperty(scenarioPropertyItem);
653  }
654  }
655 
656  ui->propertyBrowser->addProperty(scenarioTopItem);
657  ui->propertyBrowser->setRootIsDecorated(false);
658 
659  // re-enable updates
660  statusUpdateRelevant = true;
661 }
662 
663 void
665 {
666  if (variantManager.get() == nullptr || variantFactory.get() == nullptr)
667  {
668  init();
669  }
670  if (package == nullptr)
671  {
672  //build propertybrowser items
673  variantManager->clear();
674  ui->propertyBrowser->clear();
675 
676  ui->startButton->setEnabled(false);
677  ui->stopButton->setEnabled(false);
678  ui->restartButton->setEnabled(false);
679  ui->addParameterButton->setEnabled(false);
680  ui->toolButton->setEnabled(false);
681  ui->linkedInfoLabel->setVisible(false);
682  ui->makeLocalButton->setVisible(false);
683 
684  lastAppInstance = ApplicationInstancePtr(nullptr);
685  lastScenario = ScenarioPtr(nullptr);
686  statusUpdateRelevant = false;
687 
688  return;
689  }
690 
691 
692  ui->dataLabel->setText(QString::fromStdString(package->getName()));
693 
694  lastAppInstance = ApplicationInstancePtr();
695  lastScenario = ScenarioPtr();
696  lastScenarioItem = nullptr;
697 
698  statusUpdateRelevant = false;
699 
700  ui->stateLabel->setStyleSheet("QLabel { color : black; }");
701  ui->stateLabel->setText("No Status");
702 
703  ui->startButton->setEnabled(false);
704  ui->stopButton->setEnabled(false);
705  ui->restartButton->setEnabled(false);
706  ui->addParameterButton->setEnabled(false);
707  ui->addParameterButton->setMenu(nullptr);
708 
709  ui->toolButton->setEnabled(false);
710 
711  //build propertybrowser items
712  variantManager->clear();
713  static_cast<OptionalVariantFactory*>(variantFactory.get())
714  ->setElementName(QString::fromStdString(package->getName()));
715  ui->propertyBrowser->clear();
716 
717  QtProperty* packageTopItem = variantManager->addProperty(
718  QtVariantPropertyManager::groupTypeId(), QLatin1String("Package"));
719 
720  packageTopItem->setEnabled(false);
721 
722  QtVariantProperty* nameItem = variantManager->addProperty(QVariant::String, QString("Name"));
723  nameItem->setValue(QString::fromStdString(package->getName()));
724  packageTopItem->addSubProperty(nameItem);
725 
726  QtVariantProperty* packagePathItem =
727  variantManager->addProperty(QVariant::String, QString("Package Path"));
728  packagePathItem->setValue(QString::fromStdString(package->getPath()));
729  packageTopItem->addSubProperty(packagePathItem);
730 
731  ui->propertyBrowser->addProperty(packageTopItem);
732  ui->propertyBrowser->setRootIsDecorated(false);
733 }
734 
735 void
736 DetailedApplicationView::show_or_hide_property(QtProperty* prop, bool visible)
737 {
738  for (auto& item : ui->propertyBrowser->items(prop))
739  {
740  ui->propertyBrowser->setItemVisible(item, visible);
741  }
742 }
743 
744 bool
745 DetailedApplicationView::show_or_hide_subproperties(QtProperty* parent_prop, const QString& text)
746 {
747  if (parent_prop == nullptr)
748  {
749  return false;
750  }
751 
752  bool active_subproperty = false;
753  for (auto prop : parent_prop->subProperties())
754  {
755  if (prop->hasValue())
756  {
757  if (!ui->showInactiveProperties->isChecked())
758  {
759  QtVariantProperty* vprop = static_cast<QtVariantProperty*>(prop);
761  !vprop->attributeValue(QLatin1String("enabled")).toBool())
762  {
763  this->show_or_hide_property(prop, false);
764  /*active_subproperty = active_subproperty || false;*/
765  continue;
766  }
767  }
768  if (prop->propertyName().contains(text, Qt::CaseInsensitive) ||
769  prop->valueText().contains(text, Qt::CaseInsensitive) || text == "")
770  {
771  this->show_or_hide_property(prop, true);
772  active_subproperty = /*active_subproperty || */ true;
773  }
774  else
775  {
776  this->show_or_hide_property(prop, false);
777  /*active_subproperty = active_subproperty || false;*/
778  }
779  }
780  else
781  {
782  // Assuming that a property with value cannot have subproperties
783  active_subproperty = this->show_or_hide_subproperties(prop, text) || active_subproperty;
784  }
785  }
786  if (active_subproperty)
787  {
788  this->show_or_hide_property(parent_prop, true);
789  }
790  else
791  {
792  this->show_or_hide_property(parent_prop, false);
793  }
794  return active_subproperty;
795 }
796 
797 void
798 DetailedApplicationView::on_searchBar_textEdited(const QString& text)
799 {
800  for (auto prop : ui->propertyBrowser->properties())
801  {
802  this->show_or_hide_subproperties(prop, text);
803  }
804 }
805 
806 void
807 DetailedApplicationView::on_showInactiveProperties_stateChanged(int)
808 {
809  ARMARX_INFO << "Checkbox Statechanged with text " << ui->searchBar->text().toStdString();
810  this->on_searchBar_textEdited(ui->searchBar->text());
811 }
812 
813 void
814 DetailedApplicationView::on_startButton_clicked()
815 {
816  emit startButtonClicked();
817 }
818 
819 void
820 DetailedApplicationView::on_stopButton_clicked()
821 {
822  emit stopButtonClicked();
823 }
824 
825 void
826 DetailedApplicationView::on_restartButton_clicked()
827 {
828  emit restartButtonClicked();
829 }
830 
831 void
832 DetailedApplicationView::on_addParameterButton_clicked()
833 {
835 }
836 
837 void
838 DetailedApplicationView::on_toolButton_clicked()
839 {
840  emit toolButtonClicked();
841 }
842 
843 void
845 {
846  if (statusUpdateRelevant)
847  {
848  QPalette stateLabelPallet;
849  if (lastAppInstance.get() != nullptr)
850  {
851  ui->stateLabel->setText(QString::fromStdString(lastAppInstance->getStatus()));
852 
853  if (lastAppInstance->getStatus().compare("Running") == 0)
854  {
855  ui->stateLabel->setStyleSheet("QLabel { color : green; }");
856  //stateLabelPallet.setColor(QPalette::WindowText, Qt::blue);
857  }
858  else if (lastAppInstance->getStatus().compare("Stopped") == 0)
859  {
860  ui->stateLabel->setStyleSheet("QLabel { color : red; }");
861  }
862  else
863  {
864  ui->stateLabel->setStyleSheet("QLabel { color : black; }");
865  }
866  }
867  else if (lastScenario.get() != nullptr)
868  {
869  ui->stateLabel->setText(QString::fromStdString(lastScenario->getStatus()));
870 
871  if (lastScenario->getStatus().compare("Running") == 0)
872  {
873  ui->stateLabel->setStyleSheet("QLabel { color : green; }");
874  //stateLabelPallet.setColor(QPalette::WindowText, Qt::blue);
875  }
876  else if (lastScenario->getStatus().compare("Stopped") == 0)
877  {
878  ui->stateLabel->setStyleSheet("QLabel { color : red; }");
879  }
880  else if (lastScenario->getStatus().compare("Mixed") == 0)
881  {
882  ui->stateLabel->setStyleSheet("QLabel { color : darkYellow; }");
883  }
884  else
885  {
886  ui->stateLabel->setStyleSheet("QLabel { color : black; }");
887  }
888  }
889  ui->stateLabel->setAutoFillBackground(true);
890  ui->stateLabel->setPalette(stateLabelPallet);
891  }
892 }
893 
894 void
895 DetailedApplicationView::itemChanged(QtProperty* property, const QVariant& value)
896 {
897  if (statusUpdateRelevant)
898  {
899  if (lastAppInstance.get() != nullptr)
900  {
901  armarx::PropertyDefinitionsPtr props = lastAppInstance->getProperties();
902 
903  Ice::PropertiesPtr properties = props->getProperties()->clone();
904 
905  if (property->propertyName().compare("Name") == 0 ||
906  property->propertyName().compare("Executable Path") == 0 ||
907  property->propertyName().compare("Config Path") == 0 ||
908  property->propertyName().compare("Pid (Stopped = -1)") == 0 ||
909  property->propertyName().compare("Scenario Path") == 0 ||
910  property->propertyName().compare("Created At") == 0 ||
911  property->propertyName().compare("Package Path") == 0 ||
912  property->propertyName().compare("Last Change At") == 0 ||
913  property->propertyName().compare("Default Properties") == 0)
914  {
915  return;
916  }
917 
918  if (property->propertyName().compare("Instance Name") == 0 &&
919  lastAppInstance->getInstanceName().compare(value.toString().toStdString()))
920  {
921  lastAppInstance->setInstanceName(value.toString().toStdString());
922 
923  updateTimer.start(UPDATE_TIMER_INTERVAL);
924  }
925  else if (property->propertyName().compare("Instance Name") &&
926  property->propertyName() == "Enabled")
927  {
928  if (property->valueText() == "True")
929  {
930  lastAppInstance->setEnabled(true);
931  ui->startButton->setEnabled(true);
932  ui->stopButton->setEnabled(true);
933  ui->restartButton->setEnabled(true);
934  if (lastScenarioItem != nullptr)
935  {
936  lastScenarioItem->setEnabled(true);
937  }
938  }
939  else
940  {
941  lastAppInstance->setEnabled(false);
942  ui->startButton->setEnabled(false);
943  ui->stopButton->setEnabled(false);
944  ui->restartButton->setEnabled(false);
945  if (lastScenarioItem != nullptr)
946  {
947  lastScenarioItem->setEnabled(false);
948  }
949  }
950  updateTimer.start(UPDATE_TIMER_INTERVAL);
951  }
952  else if (property->propertyName().compare("Instance Name") &&
953  properties->getProperty(property->propertyName().toStdString())
954  .compare(value.toString().toStdString()))
955  {
956  lastAppInstance->modifyProperty(property->propertyName().toStdString(),
957  property->valueText().toStdString());
958  if (value.toString().compare("<set value!>") &&
959  value.toString().compare("::NOT_DEFINED::") &&
960  value.toString().compare("::_NOT_SET_::"))
961  {
962  lastAppInstance->setDefaultPropertyEnabled(
963  property->propertyName().toStdString(), true);
964  variantManager->setAttribute(property, QLatin1String("enabled"), true);
965  }
966  updateTimer.start(UPDATE_TIMER_INTERVAL);
967  }
968  //showApplicationInstance(lastAppInstance);
969  }
970  else if (lastScenario.get() != nullptr)
971  {
972  armarx::PropertyDefinitionsPtr props = lastScenario->getGlobalConfig();
973 
974  Ice::PropertiesPtr properties = props->getProperties()->clone();
975 
976  if (property->propertyName().compare("Name") == 0 ||
977  property->propertyName().compare("Scenario Path") == 0 ||
978  property->propertyName().compare("Created At") == 0 ||
979  property->propertyName().compare("Package Path") == 0 ||
980  property->propertyName().compare("Last Change At") == 0 ||
981  property->propertyName().compare("Default Properties") == 0)
982  {
983  return;
984  }
985  else if (properties->getProperty(property->propertyName().toStdString()) != "" &&
986  properties->getProperty(property->propertyName().toStdString())
987  .compare(value.toString().toStdString()))
988  {
989  lastScenario->getGlobalConfig()->defineOptionalProperty<std::string>(
990  property->propertyName().toStdString(), "::NOT_DEFINED::", "Custom Property");
991  lastScenario->getGlobalConfig()->getProperties()->setProperty(
992  property->propertyName().toStdString(), property->valueText().toStdString());
993 
994  updateTimer.start(UPDATE_TIMER_INTERVAL);
995  }
996  }
997  }
998 }
999 
1000 void
1001 DetailedApplicationView::itemAttributeChanged(QtProperty* property,
1002  const QString& attribute,
1003  const QVariant& val)
1004 {
1005  if (statusUpdateRelevant)
1006  {
1007  if (lastAppInstance.get() != nullptr && attribute.compare(QLatin1String("enabled")) == 0)
1008  {
1009  lastAppInstance->setDefaultPropertyEnabled(property->propertyName().toStdString(),
1010  val.toBool());
1011 
1012  if (!val.toBool())
1013  {
1014  OptionalVariantManager* internalManager =
1015  static_cast<OptionalVariantManager*>(property->propertyManager());
1016  armarx::PropertyDefinitionsPtr properties = lastAppInstance->getProperties();
1018  properties->getDefintion<std::string>(property->propertyName().toStdString());
1019 
1020  if (definition.isRequired())
1021  {
1022  properties->getProperties()->setProperty(property->propertyName().toStdString(),
1023  "::_NOT_SET_::");
1024  internalManager->setValue(property, "::_NOT_SET_::");
1025  }
1026  else
1027  {
1028  properties->getProperties()->setProperty(property->propertyName().toStdString(),
1029  definition.getDefaultValue());
1030  internalManager->setValue(property,
1031  QString::fromStdString(definition.getDefaultValue()));
1032  }
1033  }
1034 
1035  updateTimer.start(UPDATE_TIMER_INTERVAL);
1036  }
1037  }
1038 }
1039 
1040 void
1041 DetailedApplicationView::on_fileUpdate()
1042 {
1043  if (lastAppInstance.get() != nullptr)
1044  {
1045  //DANGER delets old config
1046  if (lastAppInstance->isConfigWritable())
1047  {
1048  lastAppInstance->resetConfigPath();
1049  lastAppInstance->save();
1050  }
1051 
1052  // we want to ignore any file changes made by us to avoid unnecessarily updating the GUI
1053  ignoreFileChanges = true;
1054  emit saveScenario(lastAppInstance);
1055  ignoreFileChanges = false;
1056  }
1057  else if (lastScenario.get() != nullptr)
1058  {
1059  if (lastScenario->isScenarioFileWriteable())
1060  {
1061  lastScenario->save();
1062  }
1063  }
1064 }
1065 
1066 void
1067 DetailedApplicationView::on_reloadButton_clicked()
1068 {
1069  if (statusUpdateRelevant)
1070  {
1071  if (lastAppInstance.get() != nullptr)
1072  {
1073  lastAppInstance->load();
1074  showApplicationInstance(lastAppInstance, nullptr);
1075  }
1076  else if (lastScenario.get() != nullptr)
1077  {
1078  lastScenario->reloadGlobalConf();
1079  showScenario(lastScenario);
1080  }
1081  }
1082 }
1083 
1084 void
1085 DetailedApplicationView::on_makeLocalButton_clicked()
1086 {
1087  if (lastAppInstance)
1088  {
1089  lastAppInstance->makeLocal();
1090  showApplicationInstance(lastAppInstance, nullptr);
1091  }
1092  else if (lastScenario)
1093  {
1094  lastScenario->makeLocalGlobalConfig();
1095  showScenario(lastScenario);
1096  }
1097 }
1098 
1099 void
1100 DetailedApplicationView::on_fileWatcherUpdate(const QString& path)
1101 {
1102  if (ignoreFileChanges)
1103  {
1104  ARMARX_VERBOSE << "Ignoring file change from: " << path.toStdString();
1105  return;
1106  }
1107 
1108  ARMARX_VERBOSE << "File changed: " << path.toStdString() << " -> reloading config";
1109 
1110  if (lastAppInstance.get() != nullptr)
1111  {
1112  lastAppInstance->load();
1113  showApplicationInstance(lastAppInstance, nullptr);
1114  }
1115  else if (lastScenario.get() != nullptr)
1116  {
1117  lastScenario->reloadGlobalConf();
1118  showScenario(lastScenario);
1119  }
1120 }
ScenarioItem
TreeItem representing data contained in a Scenario or an Application.
Definition: scenarioitem.h:38
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
ScenarioManager::Parser::XMLScenarioParser::getPackageNameFromScx
static std::string getPackageNameFromScx(const std::string &path)
Definition: XMLScenarioParser.cpp:369
algorithm.h
armarx::PropertyDefinitionBase::isRequired
bool isRequired() const
Definition: PropertyDefinitionInterface.h:75
detailedapplicationview.h
ScenarioManager::Data_Structure::ScenarioPtr
std::shared_ptr< Scenario > ScenarioPtr
Definition: Scenario.h:36
armarx::PropertyDefinition::getValueMap
PropertyValuesMap & getValueMap()
Definition: PropertyDefinition.hpp:313
QtProperty::hasValue
bool hasValue() const
Definition: qtpropertybrowser.cpp:277
DetailedApplicationView::saveScenario
void saveScenario(ScenarioManager::Data_Structure::ApplicationInstancePtr application)
QtProperty::setStatusTip
void setStatusTip(const QString &text)
Definition: qtpropertybrowser.cpp:342
ScenarioManager::Data_Structure::ApplicationPtr
std::shared_ptr< Application > ApplicationPtr
Definition: Application.h:119
DetailedApplicationView::showApplication
void showApplication(ScenarioManager::Data_Structure::ApplicationPtr application)
Show an Application.
Definition: detailedapplicationview.cpp:140
DetailedApplicationView::startButtonClicked
void startButtonClicked()
DetailedApplicationView::restartButtonClicked
void restartButtonClicked()
DetailedApplicationView::toolButtonClicked
void toolButtonClicked()
ScenarioManager::Parser::XMLScenarioParser
This class provides different methods to parse and save scenario data in XML-Files....
Definition: XMLScenarioParser.h:56
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:915
QtProperty::valueText
QString valueText() const
Definition: qtpropertybrowser.cpp:303
UPDATE_TIMER_INTERVAL
#define UPDATE_TIMER_INTERVAL
Definition: detailedapplicationview.cpp:39
QtProperty
The QtProperty class encapsulates an instance of a property.
Definition: qtpropertybrowser.h:71
ApplicationInstancePtr
std::shared_ptr< ScenarioManager::Data_Structure::ApplicationInstance > ApplicationInstancePtr
Definition: StopStrategy.h:7
PropertyDefinitionHelpFormatter.h
OptionalVariantManager
Definition: OptionalPropertyManager.h:29
IceInternal::Handle< ::Ice::Properties >
QtVariantProperty
The QtVariantProperty class is a convenience class handling QVariant based properties.
Definition: qtvariantproperty.h:55
armarx::PropertyDefinitionHelpFormatter
PropertyDefinitionHelpFormatter.
Definition: PropertyDefinitionHelpFormatter.h:40
QtProperty::propertyName
QString propertyName() const
Definition: qtpropertybrowser.cpp:247
DetailedApplicationView::updateStatus
void updateStatus()
Updates the status of the displayed item.
Definition: detailedapplicationview.cpp:844
PackageBuilder.h
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
scenarioInfoFromLink
std::pair< std::string, std::string > scenarioInfoFromLink(const std::filesystem::path &linkpath)
Definition: detailedapplicationview.cpp:62
Ui
ArmarX Headers.
Definition: ArmarXMainWindow.h:54
ScenarioManager::Data_Structure::PackagePtr
std::shared_ptr< Package > PackagePtr
Definition: Package.h:121
OptionalVariantFactory
Definition: OptionalPropertyFactory.h:29
DetailedApplicationView::~DetailedApplicationView
~DetailedApplicationView() override
Destructor.
Definition: detailedapplicationview.cpp:102
TreeItem::setEnabled
void setEnabled(bool enabled)
Definition: treeitem.cpp:84
QtVariantProperty::attributeValue
QVariant attributeValue(const QString &attribute) const
Definition: qtvariantproperty.cpp:232
XMLScenarioParser.h
QtVariantPropertyManager::groupTypeId
static int groupTypeId()
Definition: qtvariantproperty.cpp:115
DetailedApplicationView::showScenario
void showScenario(ScenarioManager::Data_Structure::ScenarioPtr scenario)
Show a Scenario.
Definition: detailedapplicationview.cpp:473
QtVariantProperty::setValue
void setValue(const QVariant &value)
Definition: qtvariantproperty.cpp:272
DetailedApplicationView::addParameterButtonClicked
void addParameterButtonClicked()
armarx::PropertyDefinition::getDefaultValue
PropertyType getDefaultValue()
Definition: PropertyDefinition.hpp:321
QtProperty::setToolTip
void setToolTip(const QString &text)
Definition: qtpropertybrowser.cpp:326
QtProperty::subProperties
QList< QtProperty * > subProperties() const
Definition: qtpropertybrowser.cpp:199
GfxTL::Off
OnOff< false > Off
Definition: OnOff.h:11
DetailedApplicationView::DetailedApplicationView
DetailedApplicationView(QWidget *parent=0)
Constructor that sets up the ui.
Definition: detailedapplicationview.cpp:83
DetailedApplicationView::showApplicationInstance
void showApplicationInstance(ScenarioManager::Data_Structure::ApplicationInstancePtr appInstance, ScenarioItem *item)
Show an ApplicationInstance.
Definition: detailedapplicationview.cpp:238
ScenarioManager
Definition: Application.cpp:166
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
PropertyDefinitionContainer.h
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
QtProperty::setEnabled
void setEnabled(bool enable)
Definition: qtpropertybrowser.cpp:392
IceUtil::Handle< class PropertyDefinitionContainer >
QtProperty::addSubProperty
void addSubProperty(QtProperty *property)
Definition: qtpropertybrowser.cpp:427
DetailedApplicationView::showPackage
void showPackage(ScenarioManager::Data_Structure::PackagePtr package)
Show a Package.
Definition: detailedapplicationview.cpp:664
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:27
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
cxxopts::String
std::string String
Definition: cxxopts.hpp:209
Logging.h
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
OptionalVariantManager::optionalProprtyTypeId
static int optionalProprtyTypeId()
Definition: OptionalPropertyManager.cpp:72
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
OptionalVariantManager::setValue
void setValue(QtProperty *property, const QVariant &val) override
Definition: OptionalPropertyManager.cpp:162
QtVariantProperty::setAttribute
void setAttribute(const QString &attribute, const QVariant &value)
Definition: qtvariantproperty.cpp:286
QtVariantProperty::propertyType
int propertyType() const
Definition: qtvariantproperty.cpp:257
DetailedApplicationView
View that shows detailed information about a Scenario, Package or Application. Shows status and param...
Definition: detailedapplicationview.h:52
armarx::PropertyDefinition
PropertyDefinition defines a property that will be available within the PropertyUser.
Definition: PropertyDefinition.h:107
DetailedApplicationView::stopButtonClicked
void stopButtonClicked()
armarx::getMapKeys
void getMapKeys(const MapType &map, OutputIteratorType it)
Definition: algorithm.h:157