31#include <QApplication>
36#include <SimoxUtility/algorithm/string/string_tools.h>
59#define UPDATE_TIMER 500
70 qRegisterMetaType<ApplicationInstanceStatusMap>(
"ApplicationInstanceStatusMap");
71 qRegisterMetaType<FilterableTreeModelSortFilterProxyModelPtr>(
72 "FilterableTreeModelSortFilterProxyModelPtr");
74 QTimer* timer =
new QTimer(
this);
75 QObject::connect(timer, SIGNAL(timeout()),
this, SLOT(
updateStati()));
79 [&] {
fetchStati(); }, 100,
false,
"ScenarioManagerUpdateStatusTask");
82 model->setDynamicSortFilter(
true);
83 model->setSourceModel(&treemodel);
85 QObject::connect(&createScenarioView,
86 SIGNAL(created(std::string, std::string)),
90 QObject::connect(&treemodel,
91 SIGNAL(applicationsDrop(
92 QList<QPair<QString, ScenarioManager::Data_Structure::Application*>>,
97 QList<QPair<QString, ScenarioManager::Data_Structure::Application*>>,
100 QObject::connect(
this,
126 if (parent.isValid())
128 if (parent.parent().isValid())
135 executor->stopApplication(instance);
145 executor->stopApplication(app);
152 executor->stopScenario(scenario);
173 if (parent.isValid())
175 if (parent.parent().isValid())
182 instance->updateFound();
183 if (!instance->getFound())
186 "The binary `" + QString::fromStdString(instance->getExecutableAbsPath()) +
187 "` for the application " + QString::fromStdString(instance->getName()) +
188 " could not be found");
192 auto scenario = instance->getScenario();
193 executor->startApplication(instance);
205 if (!app->getFound())
207 ShowWarningDialog(
"The Binary for the Application " +
208 QString::fromStdString(app->getName()) +
209 " could not be found");
214 executor->startApplication(app);
227ScenarioListController::startScenario(
ScenarioItem* scenarioItem)
239 if (item ==
nullptr || !item->
isEnabled())
243 if (parent.isValid())
245 if (parent.parent().isValid())
255 executor->restartApplication(app);
265 catch (IceGrid::ServerStartException& ex)
267 ShowWarningDialog(
"Ice had an launching error. Please make sure your remote launch "
268 "settings are correct");
277 QList<QPair<QString, ScenarioManager::Data_Structure::Application*>> applications,
279 const QModelIndex& parent)
282 QModelIndex scenarioIndex;
284 if (parent.parent().isValid() && parent.parent().parent().isValid())
289 else if (parent.parent().isValid())
292 scenarioIndex = parent.
parent();
297 scenarioIndex = parent;
306 if (!scenario->isScenarioFileWriteable())
308 QMessageBox::critical(
310 "Adding application failed!",
311 "The scenario '" + QString::fromStdString(scenario->getName()) +
312 "' is read only. You cannot add an application to this scenario!");
316 std::vector<std::string> acceptedApps =
320 for (
const auto& pair : applications)
324 for (
const auto& package : *packages)
326 for (
const auto& pApp : *package->getApplications())
328 if (pApp->getName().compare(app->
getName()) == 0)
330 appPackage = package;
335 if (appPackage.get() ==
nullptr)
340 if (std::find(acceptedApps.begin(), acceptedApps.end(), appPackage->getName()) ==
343 const std::string dependenciesStr = simox::alg::join(acceptedApps,
", ");
346 QString message(
"You cannot drop an app from ");
347 message.append(QString::fromStdString(appPackage->getName()));
348 message.append(
" into a scenario from ");
349 message.append(QString::fromStdString(scenario->getPackage()->getName()));
350 message.append(QString::fromStdString(
". Package `" +
351 scenario->getPackage()->getName() +
352 "` depends on " + dependenciesStr));
353 box.setText(message);
359 const std::string appName = app->
getName();
361 int instanceCounter = 0;
362 std::string instanceName = pair.first.toStdString();
363 if (instanceName.empty())
367 if (instances->getName().compare(appName) == 0)
372 if (instanceCounter == 0)
378 instanceName =
"instance" + std::to_string(instanceCounter);
385 if (instances->getInstanceName().compare(instanceName) == 0)
390 if (instanceCounter > 0)
392 instanceName += std::to_string(instanceCounter);
397 std::string configPath = scenario->getPath();
398 configPath = configPath.substr(0, configPath.find_last_of(
'/'));
399 configPath.append(
"/config/");
402 configPath.append(app->
getName());
403 if (!instanceName.empty())
405 configPath.append(
".");
406 configPath.append(instanceName);
408 configPath.append(
".cfg");
410 std::ofstream out(configPath);
417 appPackage->getName(),
424 executor->loadAndSetCachedProperties(appInstance, cacheDir,
true);
425 appInstance->load(
true);
427 for (
const auto& elem : app->
getProperties()->getProperties()->getPropertiesForPrefix(
""))
429 appInstance->modifyProperty(elem.first, elem.second);
430 appInstance->setDefaultPropertyEnabled(elem.first,
true);
435 scenario->addApplication(appInstance);
437 QModelIndex subScenarioIndex =
438 findSubScenarioModelIndexByScenarioIndex(scenarioIndex, appPackage->getName());
444 if (!subScenarioIndex.isValid())
446 std::vector<ApplicationInstancePtr> list;
450 treemodel.insertRow(0, subScenarioItem, scenarioIndex);
453 findSubScenarioModelIndexByScenarioIndex(scenarioIndex, appPackage->getName());
455 treemodel.insertRow(0,
new ScenarioItem(appInstance), subScenarioIndex);
459 treemodel.insertRow(0,
new ScenarioItem(appInstance), subScenarioIndex);
469 if (item.parent().isValid() && item.parent().parent().isValid())
473 if (scenItem ==
nullptr)
484 treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
486 else if (item.parent().isValid())
490 if (scenItem ==
nullptr)
501 scenario->removeApplication(app);
504 treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
510 if (scenItem ==
nullptr)
517 const std::string file =
519 QSettings settings(QString(file.c_str()), QSettings::NativeFormat);
520 QStringList scenarios = settings.value(
"scenarios").toStringList();
521 scenarios.removeDuplicates();
522 QString toFind(QString::fromStdString(scen->getName()));
523 toFind.append(
"::Package::");
524 toFind.append(QString::fromStdString(scen->getPackage()->getName()));
525 scenarios.removeAt(scenarios.indexOf(toFind));
526 settings.setValue(
"scenarios", scenarios);
528 for (
const auto& package : *packages)
530 for (
auto it = package->getScenarios()->begin(); it != package->getScenarios()->end();
533 if (scen.get() == it->get())
535 package->getScenarios()->erase(it);
540 treemodel.removeRow(model->mapToSource(item).row(), model->mapToSource(item.parent()));
550 if (packages->size() != 0)
552 QVector<QPair<QString, bool>> packageNames;
553 for (
const auto& package : *packages)
555 packageNames << qMakePair(QString::fromStdString(package->getName()),
556 package->isScenarioPathWritable());
558 createScenarioView.setPackages(packageNames);
559 createScenarioView.exec();
563 QMessageBox messageBox;
564 messageBox.setText(
"You have to have at least one Package open to create an Scenario");
577 for (
unsigned int i = 0; i < packages->size(); i++)
579 if (packages->at(i)->getName().compare(packageStr) == 0)
581 package = packages->at(i);
585 if (package.get() ==
nullptr)
590 if (parser.isScenarioexistent(name, package))
593 QString message(
"The Scenario " + QString::fromStdString(name) +
594 " already exists in Package " + QString::fromStdString(packageStr));
595 box.setText(message);
600 ScenarioPtr ptr = parser.createNewScenario(name, package);
601 if (ptr.get() ==
nullptr)
606 for (
const auto& p : *packages)
608 if (p->getName().compare(packageStr) == 0)
616 const std::string file =
618 QSettings settings(QString(file.c_str()), QSettings::NativeFormat);
619 QStringList scenarios = settings.value(
"scenarios").toStringList();
620 scenarios.removeDuplicates();
622 toAdd.append(QString::fromStdString(ptr->getName()));
623 toAdd.append(
"::Package::");
624 toAdd.append(QString::fromStdString(package->getName()));
625 scenarios.append(toAdd);
626 settings.setValue(
"scenarios", scenarios);
635 if (
index.column() > 0 || item ==
nullptr)
640 if (
index.parent().isValid())
642 if (
index.parent().parent().isValid())
645 appInstance->updateFound();
646 if (!appInstance->getFound())
649 message.setText(
"Could not find Application " + item->
data(0).toString() +
" at " +
650 QString::fromStdString(appInstance->getPathToExecutable()) +
".");
652 if (!appInstance->getFound())
679 for (
const auto& package : *packages)
681 auto scenarios = package->getScenarios();
682 for (
const auto& scenario : *scenarios)
684 std::map<std::string, std::vector<ApplicationInstancePtr>> packageSubtrees;
685 for (
const auto& app : *scenario->getApplications())
687 std::string packageName = app->getPackageName();
689 if (packageSubtrees.count(packageName) == 0)
691 packageSubtrees[packageName] = std::vector<ApplicationInstancePtr>();
693 packageSubtrees[packageName].push_back(app);
698 findScenario(rootItem, scenario->getName(), scenario->getPackage()->getName());
703 for (
const auto& it : packageSubtrees)
708 treemodel.insertRow(0, scenarioItem);
714 for (
int i = 0; i < scenarioItem->
childCount(); i++)
718 std::string name = subPackageItem->
data(0).toString().toStdString();
720 std::vector<ApplicationInstancePtr> currentBuildSubtree = packageSubtrees[name];
723 for (
size_t k = 0; k < currentTreeSubtree->size(); k++)
726 for (
size_t j = 0; j < currentBuildSubtree.size(); j++)
728 if (currentTreeSubtree->at(k)->getName() ==
729 currentBuildSubtree[j]->getName() &&
730 currentTreeSubtree->at(k)->getInstanceName() ==
731 currentBuildSubtree[j]->getInstanceName())
742 findSubScenarioModelIndex(scenario->getName(), name));
752ScenarioListController::findApplicationModelIndex(
755 QModelIndex subScenarioModelIndex = findSubScenarioModelIndex(
756 application->getScenario()->getName(), application->getPackageName());
757 if (!subScenarioModelIndex.isValid())
759 return QModelIndex();
762 QModelIndex appIndex = subScenarioModelIndex.model()->index(0, 0);
765 appIndex = appIndex.sibling(count, 0);
766 if (!appIndex.isValid())
768 return QModelIndex();
770 if (application->getInstanceName().empty())
772 if (application->getName() == appIndex.data().toString().toStdString())
779 if (application->getInstanceName() +
"." + application->getName() ==
780 appIndex.data().toString().toStdString())
791ScenarioListController::findSubScenarioModelIndex(std::string scenarioName, std::string packageName)
793 QModelIndex scenarioIndex = treemodel.index(0, 0);
795 bool scenarioFound =
false;
797 while (!scenarioFound)
799 scenarioIndex = scenarioIndex.sibling(count, 0);
801 if (!scenarioIndex.isValid())
803 return QModelIndex();
805 if (scenarioName == scenarioIndex.data().toString().toStdString())
807 scenarioFound =
true;
817 QModelIndex currentSubPackageIndex = scenarioIndex.model()->index(count, 0);
818 if (!currentSubPackageIndex.isValid())
820 return QModelIndex();
822 if (packageName == currentSubPackageIndex.data().toString().toStdString())
824 return currentSubPackageIndex;
829 return QModelIndex();
833ScenarioListController::findSubScenarioModelIndexByScenarioIndex(QModelIndex scenarioIndex,
834 std::string packageName)
839 QModelIndex currentSubPackageIndex = scenarioIndex.model()->index(count, 0, scenarioIndex);
840 if (packageName == currentSubPackageIndex.data().toString().toStdString())
842 return currentSubPackageIndex;
844 if (!currentSubPackageIndex.isValid())
846 return QModelIndex();
851 return QModelIndex();
856ScenarioListController::findScenario(ScenarioItem* rootItem,
858 std::string packageName)
860 for (
int i = 0; i < rootItem->
childCount(); i++)
862 if (
static_cast<ScenarioItem*
>(rootItem->
child(i))->getScenario()->getName() == name &&
863 static_cast<ScenarioItem*
>(rootItem->
child(i))
866 ->getName() == packageName)
878 std::vector<ApplicationInstancePtr> apps;
880 std::unique_lock lock(applicationInstanceMutex);
881 apps.swap(applicationInstances);
890 const auto now = std::chrono::steady_clock::now();
891 const bool refreshFound = now - lastFoundUpdate >= FoundUpdateInterval;
894 lastFoundUpdate = now;
898 IceUtil::Time
start = IceUtil::Time ::now();
904 appInst->updateFound();
911 stati[appInst] = executor->getApplicationStatus(appInst);
917 <<
". Leaving it unchanged.";
921 << (IceUtil::Time::now() -
start).toMilliSecondsDouble() <<
" ms";
928 IceGrid::AdminPrx iceAdmin)
934 executor->setStopStrategy(executor->getDefaultStopStrategy(), scenario);
937 if (!scenario->allApplicationsFound())
939 ShowWarningDialog(
"Not all binaries in the Scenario " +
940 QString::fromStdString(scenario->getName()) +
" could be found",
942 QString::fromStdString(scenario->getName() +
"BinariesMissing"));
949 executor->startScenario(scenario);
967 std::vector<ApplicationInstancePtr> apps;
976 apps.push_back(appInst);
982 std::unique_lock lock(applicationInstanceMutex);
983 apps.swap(applicationInstances);
990 for (
auto& pair : stati)
992 pair.first->setStatus(pair.second);
1004 auto start = IceUtil::Time ::now();
1007 << (IceUtil::Time::now() -
start).toMilliSecondsDouble() <<
" ms";
1016 for (
const auto& package : *packages)
1018 for (
const auto& scenario : *package->getScenarios())
1020 if (application->getScenario()->getName() == scenario->getName())
1023 executor->loadAndSetCachedProperties(application, cacheDir,
false,
false);
1024 qApp->processEvents();
1027 scenario->save(
false);
1041ScenarioListController::ShowWarningDialog(QString message,
bool showOnce, QString messageId)
1043 static std::set<QString> dialogIds;
1047 if (dialogIds.count(messageId))
1051 dialogIds.insert(messageId);
1054 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 refreshNow()
Rebuilds the tree straight away instead of waiting for the next status poll, so that the button of a ...
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.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
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
std::string GetHandledExceptionString()
SimplePeriodicTask(Ts...) -> SimplePeriodicTask< std::function< void(void)> >