30#include <QApplication>
35#include <SimoxUtility/algorithm/string/string_tools.h>
57#define UPDATE_TIMER 500
68 qRegisterMetaType<ApplicationInstanceStatusMap>(
"ApplicationInstanceStatusMap");
69 qRegisterMetaType<FilterableTreeModelSortFilterProxyModelPtr>(
70 "FilterableTreeModelSortFilterProxyModelPtr");
72 QTimer* timer =
new QTimer(
this);
73 QObject::connect(timer, SIGNAL(timeout()),
this, SLOT(
updateStati()));
77 [&] {
fetchStati(); }, 100,
false,
"ScenarioManagerUpdateStatusTask");
80 model->setDynamicSortFilter(
true);
81 model->setSourceModel(&treemodel);
83 QObject::connect(&createScenarioView,
84 SIGNAL(created(std::string, std::string)),
88 QObject::connect(&treemodel,
89 SIGNAL(applicationsDrop(
90 QList<QPair<QString, ScenarioManager::Data_Structure::Application*>>,
95 QList<QPair<QString, ScenarioManager::Data_Structure::Application*>>,
98 QObject::connect(
this,
124 if (parent.isValid())
126 if (parent.parent().isValid())
133 executor->stopApplication(instance);
143 executor->stopApplication(app);
150 executor->stopScenario(scenario);
169 if (parent.isValid())
171 if (parent.parent().isValid())
178 instance->updateFound();
179 if (!instance->getFound())
182 "The binary `" + QString::fromStdString(instance->getExecutableAbsPath()) +
183 "` for the application " + QString::fromStdString(instance->getName()) +
184 " could not be found");
188 auto scenario = instance->getScenario();
189 executor->startApplication(instance);
201 if (!app->getFound())
203 ShowWarningDialog(
"The Binary for the Application " +
204 QString::fromStdString(app->getName()) +
205 " could not be found");
210 executor->startApplication(app);
221ScenarioListController::startScenario(
ScenarioItem* scenarioItem)
233 if (item ==
nullptr || !item->
isEnabled())
237 if (parent.isValid())
239 if (parent.parent().isValid())
249 executor->restartApplication(app);
259 catch (IceGrid::ServerStartException& ex)
261 ShowWarningDialog(
"Ice had an launching error. Please make sure your remote launch "
262 "settings are correct");
269 QList<QPair<QString, ScenarioManager::Data_Structure::Application*>> applications,
271 const QModelIndex& parent)
274 QModelIndex scenarioIndex;
276 if (parent.parent().isValid() && parent.parent().parent().isValid())
281 else if (parent.parent().isValid())
284 scenarioIndex = parent.
parent();
289 scenarioIndex = parent;
298 if (!scenario->isScenarioFileWriteable())
300 QMessageBox::critical(
302 "Adding application failed!",
303 "The scenario '" + QString::fromStdString(scenario->getName()) +
304 "' is read only. You cannot add an application to this scenario!");
308 std::vector<std::string> acceptedApps =
312 for (
const auto& pair : applications)
316 for (
const auto& package : *packages)
318 for (
const auto& pApp : *package->getApplications())
320 if (pApp->getName().compare(app->
getName()) == 0)
322 appPackage = package;
327 if (appPackage.get() ==
nullptr)
332 if (std::find(acceptedApps.begin(), acceptedApps.end(), appPackage->getName()) ==
335 const std::string dependenciesStr = simox::alg::join(acceptedApps,
", ");
338 QString message(
"You cannot drop an app from ");
339 message.append(QString::fromStdString(appPackage->getName()));
340 message.append(
" into a scenario from ");
341 message.append(QString::fromStdString(scenario->getPackage()->getName()));
342 message.append(QString::fromStdString(
". Package `" +
343 scenario->getPackage()->getName() +
344 "` depends on " + dependenciesStr));
345 box.setText(message);
351 const std::string appName = app->
getName();
353 int instanceCounter = 0;
354 std::string instanceName = pair.first.toStdString();
355 if (instanceName.empty())
359 if (instances->getName().compare(appName) == 0)
364 if (instanceCounter == 0)
370 instanceName =
"instance" + std::to_string(instanceCounter);
377 if (instances->getInstanceName().compare(instanceName) == 0)
382 if (instanceCounter > 0)
384 instanceName += std::to_string(instanceCounter);
389 std::string configPath = scenario->getPath();
390 configPath = configPath.substr(0, configPath.find_last_of(
'/'));
391 configPath.append(
"/config/");
394 configPath.append(app->
getName());
395 if (!instanceName.empty())
397 configPath.append(
".");
398 configPath.append(instanceName);
400 configPath.append(
".cfg");
402 std::ofstream out(configPath);
409 appPackage->getName(),
416 executor->loadAndSetCachedProperties(appInstance, cacheDir,
true);
417 appInstance->load(
true);
419 for (
const auto& elem : app->
getProperties()->getProperties()->getPropertiesForPrefix(
""))
421 appInstance->modifyProperty(elem.first, elem.second);
422 appInstance->setDefaultPropertyEnabled(elem.first,
true);
427 scenario->addApplication(appInstance);
429 QModelIndex subScenarioIndex =
430 findSubScenarioModelIndexByScenarioIndex(scenarioIndex, appPackage->getName());
436 if (!subScenarioIndex.isValid())
438 std::vector<ApplicationInstancePtr> list;
442 treemodel.insertRow(0, subScenarioItem, scenarioIndex);
445 findSubScenarioModelIndexByScenarioIndex(scenarioIndex, appPackage->getName());
447 treemodel.insertRow(0,
new ScenarioItem(appInstance), subScenarioIndex);
451 treemodel.insertRow(0,
new ScenarioItem(appInstance), subScenarioIndex);
461 if (item.parent().isValid() && item.parent().parent().isValid())
465 if (scenItem ==
nullptr)
476 treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
478 else if (item.parent().isValid())
482 if (scenItem ==
nullptr)
493 scenario->removeApplication(app);
496 treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
502 if (scenItem ==
nullptr)
509 const std::string file =
511 QSettings settings(QString(file.c_str()), QSettings::NativeFormat);
512 QStringList scenarios = settings.value(
"scenarios").toStringList();
513 scenarios.removeDuplicates();
514 QString toFind(QString::fromStdString(scen->getName()));
515 toFind.append(
"::Package::");
516 toFind.append(QString::fromStdString(scen->getPackage()->getName()));
517 scenarios.removeAt(scenarios.indexOf(toFind));
518 settings.setValue(
"scenarios", scenarios);
520 for (
const auto& package : *packages)
522 for (
auto it = package->getScenarios()->begin(); it != package->getScenarios()->end();
525 if (scen.get() == it->get())
527 package->getScenarios()->erase(it);
532 treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
542 if (packages->size() != 0)
544 QVector<QPair<QString, bool>> packageNames;
545 for (
const auto& package : *packages)
547 packageNames << qMakePair(QString::fromStdString(package->getName()),
548 package->isScenarioPathWritable());
550 createScenarioView.setPackages(packageNames);
551 createScenarioView.exec();
555 QMessageBox messageBox;
556 messageBox.setText(
"You have to have at least one Package open to create an Scenario");
569 for (
unsigned int i = 0; i < packages->size(); i++)
571 if (packages->at(i)->getName().compare(packageStr) == 0)
573 package = packages->at(i);
577 if (package.get() ==
nullptr)
582 if (parser.isScenarioexistent(name, package))
585 QString message(
"The Scenario " + QString::fromStdString(name) +
586 " already exists in Package " + QString::fromStdString(packageStr));
587 box.setText(message);
592 ScenarioPtr ptr = parser.createNewScenario(name, package);
593 if (ptr.get() ==
nullptr)
598 for (
const auto& p : *packages)
600 if (p->getName().compare(packageStr) == 0)
608 const std::string file =
610 QSettings settings(QString(file.c_str()), QSettings::NativeFormat);
611 QStringList scenarios = settings.value(
"scenarios").toStringList();
612 scenarios.removeDuplicates();
614 toAdd.append(QString::fromStdString(ptr->getName()));
615 toAdd.append(
"::Package::");
616 toAdd.append(QString::fromStdString(package->getName()));
617 scenarios.append(toAdd);
618 settings.setValue(
"scenarios", scenarios);
627 if (
index.column() > 0 || item ==
nullptr)
632 if (
index.parent().isValid())
634 if (
index.parent().parent().isValid())
637 appInstance->updateFound();
638 if (!appInstance->getFound())
641 message.setText(
"Could not find Application " + item->
data(0).toString() +
" at " +
642 QString::fromStdString(appInstance->getPathToExecutable()) +
".");
644 if (!appInstance->getFound())
671 for (
const auto& package : *packages)
673 auto scenarios = package->getScenarios();
674 for (
const auto& scenario : *scenarios)
676 std::map<std::string, std::vector<ApplicationInstancePtr>> packageSubtrees;
677 for (
const auto& app : *scenario->getApplications())
679 std::string packageName = app->getPackageName();
681 if (packageSubtrees.count(packageName) == 0)
683 packageSubtrees[packageName] = std::vector<ApplicationInstancePtr>();
685 packageSubtrees[packageName].push_back(app);
690 findScenario(rootItem, scenario->getName(), scenario->getPackage()->getName());
695 for (
const auto& it : packageSubtrees)
700 treemodel.insertRow(0, scenarioItem);
706 for (
int i = 0; i < scenarioItem->
childCount(); i++)
710 std::string name = subPackageItem->
data(0).toString().toStdString();
712 std::vector<ApplicationInstancePtr> currentBuildSubtree = packageSubtrees[name];
715 for (
size_t k = 0; k < currentTreeSubtree->size(); k++)
718 for (
size_t j = 0; j < currentBuildSubtree.size(); j++)
720 if (currentTreeSubtree->at(k)->getName() ==
721 currentBuildSubtree[j]->getName() &&
722 currentTreeSubtree->at(k)->getInstanceName() ==
723 currentBuildSubtree[j]->getInstanceName())
734 findSubScenarioModelIndex(scenario->getName(), name));
744ScenarioListController::findApplicationModelIndex(
747 QModelIndex subScenarioModelIndex = findSubScenarioModelIndex(
748 application->getScenario()->getName(), application->getPackageName());
749 if (!subScenarioModelIndex.isValid())
751 return QModelIndex();
754 QModelIndex appIndex = subScenarioModelIndex.model()->index(0, 0);
757 appIndex = appIndex.sibling(count, 0);
758 if (!appIndex.isValid())
760 return QModelIndex();
762 if (application->getInstanceName().empty())
764 if (application->getName() == appIndex.data().toString().toStdString())
771 if (application->getInstanceName() +
"." + application->getName() ==
772 appIndex.data().toString().toStdString())
783ScenarioListController::findSubScenarioModelIndex(std::string scenarioName, std::string packageName)
785 QModelIndex scenarioIndex = treemodel.index(0, 0);
787 bool scenarioFound =
false;
789 while (!scenarioFound)
791 scenarioIndex = scenarioIndex.sibling(count, 0);
793 if (!scenarioIndex.isValid())
795 return QModelIndex();
797 if (scenarioName == scenarioIndex.data().toString().toStdString())
799 scenarioFound =
true;
809 QModelIndex currentSubPackageIndex = scenarioIndex.model()->index(count, 0);
810 if (!currentSubPackageIndex.isValid())
812 return QModelIndex();
814 if (packageName == currentSubPackageIndex.data().toString().toStdString())
816 return currentSubPackageIndex;
821 return QModelIndex();
825ScenarioListController::findSubScenarioModelIndexByScenarioIndex(QModelIndex scenarioIndex,
826 std::string packageName)
831 QModelIndex currentSubPackageIndex = scenarioIndex.model()->index(count, 0);
832 if (packageName == currentSubPackageIndex.data().toString().toStdString())
834 return currentSubPackageIndex;
836 if (!currentSubPackageIndex.isValid())
838 return QModelIndex();
843 return QModelIndex();
848ScenarioListController::findScenario(ScenarioItem* rootItem,
850 std::string packageName)
852 for (
int i = 0; i < rootItem->
childCount(); i++)
854 if (
static_cast<ScenarioItem*
>(rootItem->
child(i))->getScenario()->getName() == name &&
855 static_cast<ScenarioItem*
>(rootItem->
child(i))
858 ->getName() == packageName)
870 std::vector<ApplicationInstancePtr> apps;
872 std::unique_lock lock(applicationInstanceMutex);
873 apps.swap(applicationInstances);
880 IceUtil::Time
start = IceUtil::Time ::now();
884 std::string status = executor->getApplicationStatus(appInst);
885 stati[appInst] = status;
888 << (IceUtil::Time::now() -
start).toMilliSecondsDouble() <<
" ms";
895 IceGrid::AdminPrx iceAdmin)
902 executor->loadAndSetCachedProperties(
904 applicationInstance->load();
908 executor->setStopStrategy(executor->getDefaultStopStrategy(), scenario);
910 if (!scenario->allApplicationsFound())
912 ShowWarningDialog(
"Not all binaries in the Scenario " +
913 QString::fromStdString(scenario->getName()) +
" could be found",
915 QString::fromStdString(scenario->getName() +
"BinariesMissing"));
918 executor->startScenario(scenario);
928 std::vector<ApplicationInstancePtr> apps;
937 apps.push_back(appInst);
943 std::unique_lock lock(applicationInstanceMutex);
944 apps.swap(applicationInstances);
951 bool changed =
false;
952 for (
auto& pair : stati)
955 bool statusChanged = pair.first->setStatus(pair.second);
956 changed |= statusChanged;
961 auto start = IceUtil::Time ::now();
964 << (IceUtil::Time::now() -
start).toMilliSecondsDouble() <<
" ms";
974 for (
const auto& package : *packages)
976 for (
const auto& scenario : *package->getScenarios())
978 if (application->getScenario()->getName() == scenario->getName())
981 executor->loadAndSetCachedProperties(application, cacheDir,
false,
false);
982 qApp->processEvents();
985 scenario->save(
false);
999ScenarioListController::ShowWarningDialog(QString message,
bool showOnce, QString messageId)
1001 static std::set<QString> dialogIds;
1005 if (dialogIds.count(messageId))
1009 dialogIds.insert(messageId);
1012 box.setText(message);
Model of the FilterableTreeView.
TreeItem representing data contained in a Scenario or an Application.
ScenarioManager::Data_Structure::ScenarioPtr getScenario()
If this item represents a Scenario, it is returned.
ScenarioManager::Data_Structure::ApplicationInstancePtr getApplicationInstance()
If this item represents an Application, it is returned.
ScenarioManager::Data_Structure::ApplicationInstanceVectorPtr getApplicationInstances()
void saveScenario(ScenarioManager::Data_Structure::ApplicationInstancePtr application)
void restart(int row, int column, QModelIndex parent)
Restarts the object in the specified location.
static bool StartScenario(ScenarioManager::Data_Structure::ScenarioPtr scenario, Exec::ExecutorPtr executor, IceGrid::AdminPrx iceAdmin)
~ScenarioListController() override
Destructor.
void updated()
Gets emitted after changes have been made to the data structure.
void applicationInstanceClicked(Data_Structure::ApplicationInstancePtr appInstance, ScenarioItem *item)
Gets emitted after an ApplicationInstance has been clicked.
void start(int row, int column, QModelIndex parent)
Starts or stops the object in the specified location.
void stop(int row, int column, QModelIndex parent)
void setIceAdmin(IceGrid::AdminPrx iceAdmin)
Set an IceAdmin for the controller.
void updateModel()
Updates the model by reloading all scenarios and applications.
void createScenario()
Shows a view that allows the user to create a new Scenario.
void scenarioClicked(Data_Structure::ScenarioPtr scenario)
Gets emitted after a Scenario has been clicked.
void addApplicationsToScenario(QList< QPair< QString, ScenarioManager::Data_Structure::Application * > > applications, int row, const QModelIndex &parent)
Adds applications to a scenario.
void fetchStati()
fetches application stati over their designated strategy.
void createdScenario(std::string name, std::string package)
Creates a new scenario in the package.
FilterableTreeModelSortFilterProxyModelPtr getTreeModel()
Returns the model used by the ScenarioListView and managed by this controller.
ScenarioListController(Data_Structure::PackageVectorPtr packages, Exec::ExecutorPtr executor, QObject *parent=0)
Constructor which sets the data structure, the executor and optionally the parent object.
void removeItem(QModelIndex item)
Removes an item from the model.
void updateStati()
Updates the statuses of all Applications and Scenarios.
void statusFetched(ApplicationInstanceStatusMap stati)
void statusUpdated()
Gets emitted after changes have been made to the States of the Applications.
void showApplication(const QModelIndex &index)
Calculates the object at the given index and signals to show it.
Class containing data about the instance of an application.
Class containing data about an application Provides methods to get and set the date contained in the ...
std::string getExecutableName()
armarx::PropertyDefinitionsPtr getProperties()
std::string getPathToExecutable()
static std::shared_ptr< StarterFactory > getFactory()
Returns the right StarterFactory for this operatin system.
static DependencyTree getDependencieTree(std::string packageName)
static std::string getCacheDir()
This class provides different methods to parse and save scenario data in XML-Files.
void appendChild(TreeItem *child)
virtual QVariant data(int column) const
TreeItem * child(int row)
static std::string GetDefaultUserConfigPath()
The user config directory of ArmarX.
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
std::shared_ptr< FilterableTreeModelSortFilterProxyModel > FilterableTreeModelSortFilterProxyModelPtr
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
std::map< ApplicationInstancePtr, std::string > ApplicationInstanceStatusMap
std::shared_ptr< Scenario > ScenarioPtr
std::shared_ptr< std::vector< ScenarioPtr > > ScenarioVectorPtr
std::shared_ptr< std::vector< ScenarioManager::Data_Structure::PackagePtr > > PackageVectorPtr
std::shared_ptr< Package > PackagePtr
std::shared_ptr< ApplicationInstance > ApplicationInstancePtr
std::shared_ptr< std::vector< ApplicationInstancePtr > > ApplicationInstanceVectorPtr
std::shared_ptr< Executor > ExecutorPtr
SimplePeriodicTask(Ts...) -> SimplePeriodicTask< std::function< void(void)> >