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
41using namespace ScenarioManager;
42using namespace Data_Structure;
43
44template <class... T>
45static void
46setWatcherPaths(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}
61std::pair<std::string, std::string>
62scenarioInfoFromLink(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),
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
106
107void
108DetailedApplicationView::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
139void
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
237void
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
472void
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
663void
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
735void
736DetailedApplicationView::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
744bool
745DetailedApplicationView::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
797void
798DetailedApplicationView::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
806void
807DetailedApplicationView::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
813void
814DetailedApplicationView::on_startButton_clicked()
815{
816 emit startButtonClicked();
817}
818
819void
820DetailedApplicationView::on_stopButton_clicked()
821{
822 emit stopButtonClicked();
823}
824
825void
826DetailedApplicationView::on_restartButton_clicked()
827{
829}
830
831void
832DetailedApplicationView::on_addParameterButton_clicked()
833{
835}
836
837void
838DetailedApplicationView::on_toolButton_clicked()
839{
840 emit toolButtonClicked();
841}
842
843void
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
894void
895DetailedApplicationView::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
1000void
1001DetailedApplicationView::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();
1017 armarx::PropertyDefinition<std::string> definition =
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
1040void
1041DetailedApplicationView::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
1066void
1067DetailedApplicationView::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
1084void
1085DetailedApplicationView::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
1099void
1100DetailedApplicationView::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}
#define VAROUT(x)
void saveScenario(ScenarioManager::Data_Structure::ApplicationInstancePtr application)
void showApplicationInstance(ScenarioManager::Data_Structure::ApplicationInstancePtr appInstance, ScenarioItem *item)
Show an ApplicationInstance.
void showPackage(ScenarioManager::Data_Structure::PackagePtr package)
Show a Package.
void updateStatus()
Updates the status of the displayed item.
void showApplication(ScenarioManager::Data_Structure::ApplicationPtr application)
Show an Application.
void showScenario(ScenarioManager::Data_Structure::ScenarioPtr scenario)
Show a Scenario.
~DetailedApplicationView() override
Destructor.
DetailedApplicationView(QWidget *parent=0)
Constructor that sets up the ui.
void setElementName(const QString &name)
void setValue(QtProperty *property, const QVariant &val) override
The QtProperty class encapsulates an instance of a property.
QString propertyName() const
QString valueText() const
QList< QtProperty * > subProperties() const
void setToolTip(const QString &text)
void setEnabled(bool enable)
void setStatusTip(const QString &text)
bool hasValue() const
void addSubProperty(QtProperty *property)
The QtVariantProperty class is a convenience class handling QVariant based properties.
void setAttribute(const QString &attribute, const QVariant &value)
QVariant attributeValue(const QString &attribute) const
void setValue(const QVariant &value)
TreeItem representing data contained in a Scenario or an Application.
This class provides different methods to parse and save scenario data in XML-Files.
static std::string getPackageNameFromScx(const std::string &path)
PropertyDefinition defines a property that will be available within the PropertyUser.
PropertyValuesMap & getValueMap()
#define UPDATE_TIMER_INTERVAL
std::pair< std::string, std::string > scenarioInfoFromLink(const std::filesystem::path &linkpath)
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
::IceInternal::Handle<::Ice::Properties > PropertiesPtr
std::shared_ptr< Scenario > ScenarioPtr
Definition Scenario.h:35
std::shared_ptr< Application > ApplicationPtr
std::shared_ptr< Package > PackagePtr
Definition Package.h:122
std::shared_ptr< ApplicationInstance > ApplicationInstancePtr
ArmarX Headers.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void getMapKeys(const MapType &map, OutputIteratorType it)
Definition algorithm.h:173
std::shared_ptr< Value > value()
Definition cxxopts.hpp:855