ScenarioManagerWidgetController.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package ScenarioManager::gui-plugins::ScenarioManagerWidgetController
17 * @author [Cedric Seehausen] ( [usdnr@student.kit.edu] )
18 * @date 2016
19 * @copyright http://www.gnu.org/licenses/gpl.txt
20 * GNU General Public License
21 */
22
24
25#include <QCoreApplication>
26#include <QMetaType>
27#include <QProgressDialog>
28#include <QToolBar>
29#include <QToolTip>
30
31#include <SimoxUtility/algorithm/string/string_tools.h>
32
36
38
40
41using namespace armarx;
42using namespace ScenarioManager;
43using namespace Exec;
44using namespace Controller;
45using namespace Data_Structure;
46using namespace Parser;
47
49 packages(new std::vector<PackagePtr>()),
50 executor(new Executor(
51 stopStrategyFactory.getStopStrategy(StopperFactory::getFactory()->getPidStopper()),
52 StarterFactory::getFactory()->getStarter())),
53 applicationController(packages, executor),
54 detailedApplicationController(executor),
55 scenarioListController(packages, executor),
56 settingsController(packages, executor),
57 openScenarioController(packages, executor),
58 settingsFile(armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/ScenarioManager.conf")
59{
60 widget.setupUi(getWidget());
61 editModeAction = new QAction("Edit Mode", this);
62
63 QSettings q_settings(QString(settingsFile.c_str()), QSettings::NativeFormat);
64 bool editModeState = q_settings.value("editMode", false).toBool();
65 editMode(editModeState);
66}
67
71
72bool
73ScenarioManagerWidgetController::isPackageAutoDiscoveryEnabled()
74{
75 const std::string autodiscoverPropertyName = "AutodiscoverPackages";
76
77 if (hasProperty(autodiscoverPropertyName))
78 {
79 return getProperty<bool>(autodiscoverPropertyName).getValue();
80 }
81
82 ARMARX_INFO << autodiscoverPropertyName + " property not found";
83
84 return true; // Property not available. Default: use autodiscovery
85}
86
87void
88ScenarioManagerWidgetController::autoDiscoverArmarXPackages()
89{
90 QSettings autosettings(QString(settingsFile.c_str()), QSettings::NativeFormat);
91
92
94 std::sort(packagesStd.begin(),
95 packagesStd.end(),
96 [](const std::string& lhs, const std::string& rhs) -> bool
97 { return simox::alg::to_lower(lhs) < simox::alg::to_lower(rhs); });
98
99 QStringList packages;
100 ARMARX_INFO << "Discovered the following ArmarX packages: ";
101 for (const auto& pkg : packagesStd)
102 {
103 packages.push_back(QString::fromStdString(pkg));
104 ARMARX_INFO << "- " << pkg;
105 }
106
107 autosettings.setValue("packages", packages);
108}
109
110void
112{
113 QSettings autosettings(QString(settingsFile.c_str()), QSettings::NativeFormat);
114 QStringList scenarios = settings->value("scenarios", QStringList()).toStringList();
115 scenarios.removeDuplicates();
116 if (not scenarios.empty())
117 {
118 autosettings.setValue("scenarios", scenarios);
119 }
120 QStringList packages = settings->value("packages", QStringList()).toStringList();
121 packages.removeDuplicates();
122 if (not packages.empty())
123 {
124 autosettings.setValue("packages", packages);
125 }
126}
127
128void
130{
131 QSettings autosettings(QString(settingsFile.c_str()), QSettings::NativeFormat);
132 auto scenarios = autosettings.value("scenarios", QStringList()).toStringList();
133 auto packages = autosettings.value("packages", QStringList()).toStringList();
134 scenarios.removeDuplicates();
135 packages.removeDuplicates();
136 settings->setValue("scenarios", scenarios);
137 settings->setValue("packages", packages);
138}
139
140void
142{
143 QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection);
144}
145
146void
147ScenarioManagerWidgetController::init()
148{
149 scenarioListController.setIceAdmin(
150 getArmarXManager()->getIceManager()->getIceGridSession()->getAdmin());
151 detailedApplicationController.setIceAdmin(
152 getArmarXManager()->getIceManager()->getIceGridSession()->getAdmin());
153 detailedApplicationController.setDetailedApplicationView(widget.detailedApplicationView);
154
155 QObject::connect(widget.scenarioView,
156 SIGNAL(createScenario()),
157 &scenarioListController,
158 SLOT(createScenario()));
159
160 QObject::connect(
161 widget.scenarioView, SIGNAL(createScenario()), widget.applicationDatabase, SLOT(show()));
162
163 QObject::connect(widget.scenarioView,
164 SIGNAL(removeItem(QModelIndex)),
165 &scenarioListController,
166 SLOT(removeItem(QModelIndex)));
167
168 QObject::connect(widget.scenarioView,
169 SIGNAL(itemClicked(QModelIndex)),
170 &scenarioListController,
171 SLOT(showApplication(QModelIndex)));
172
173 QObject::connect(widget.scenarioView,
174 SIGNAL(startApplication(int, int, QModelIndex)),
175 &scenarioListController,
176 SLOT(start(int, int, QModelIndex)));
177
178 QObject::connect(widget.scenarioView,
179 SIGNAL(stopApplication(int, int, QModelIndex)),
180 &scenarioListController,
181 SLOT(stop(int, int, QModelIndex)));
182
183 QObject::connect(widget.scenarioView,
184 SIGNAL(restartApplication(int, int, QModelIndex)),
185 &scenarioListController,
186 SLOT(restart(int, int, QModelIndex)));
187
188 QObject::connect(&settingsController, SIGNAL(packageRemoved()), this, SLOT(updateModels()));
189
190 QObject::connect(&settingsController,
191 SIGNAL(packageAdded(std::string)),
192 this,
193 SLOT(reparsePackage(std::string)));
194
195 QObject::connect(&scenarioListController, SIGNAL(updated()), this, SLOT(updateModels()));
196
197 QObject::connect(
198 &scenarioListController,
199 SIGNAL(applicationInstanceClicked(Data_Structure::ApplicationInstancePtr, ScenarioItem*)),
200 &detailedApplicationController,
201 SLOT(showApplicationInstance(Data_Structure::ApplicationInstancePtr, ScenarioItem*)));
202
203 QObject::connect(&scenarioListController,
204 SIGNAL(scenarioClicked(Data_Structure::ScenarioPtr)),
205 &detailedApplicationController,
206 SLOT(showScenario(Data_Structure::ScenarioPtr)));
207
208 QObject::connect(&scenarioListController,
209 SIGNAL(statusUpdated()),
210 widget.detailedApplicationView,
211 SLOT(updateStatus()));
212
213 QObject::connect(widget.applicationDatabase,
214 SIGNAL(openSettings()),
215 &settingsController,
216 SLOT(showSettings()));
217
218 QObject::connect(widget.applicationDatabase,
219 SIGNAL(itemClicked(QModelIndex)),
220 &applicationController,
221 SLOT(on_itemClicked(QModelIndex)));
222
223 QObject::connect(&applicationController,
224 SIGNAL(applicationClicked(Data_Structure::ApplicationPtr)),
225 &detailedApplicationController,
226 SLOT(showApplication(Data_Structure::ApplicationPtr)));
227
228 QObject::connect(&applicationController,
229 SIGNAL(packageClicked(Data_Structure::PackagePtr)),
230 &detailedApplicationController,
231 SLOT(showPackage(Data_Structure::PackagePtr)));
232
233 QObject::connect(&openScenarioController, SIGNAL(updated()), this, SLOT(updateModels()));
234
235 QObject::connect(widget.scenarioView,
236 SIGNAL(showOpenDialog()),
237 &openScenarioController,
238 SLOT(showOpenScenarioView()));
239
240 QObject::connect(widget.detailedApplicationView,
241 SIGNAL(startButtonClicked()),
242 &detailedApplicationController,
243 SLOT(start()));
244
245 QObject::connect(widget.detailedApplicationView,
246 SIGNAL(stopButtonClicked()),
247 &detailedApplicationController,
248 SLOT(stop()));
249
250 QObject::connect(widget.detailedApplicationView,
251 SIGNAL(restartButtonClicked()),
252 &detailedApplicationController,
253 SLOT(save()));
254
255 QObject::connect(widget.detailedApplicationView,
256 SIGNAL(toolButtonClicked()),
257 &detailedApplicationController,
258 SLOT(showInStandardEditor()));
259
260 QObject::connect(widget.detailedApplicationView,
261 SIGNAL(addParameterButtonClicked()),
262 &detailedApplicationController,
263 SLOT(showPropertyAddView()));
264
265 QObject::connect(widget.detailedApplicationView,
266 SIGNAL(addIceEnvButtonClicked()),
267 &detailedApplicationController,
268 SLOT(showIceEnvVariableAddView()));
269
270
271 QObject::connect(widget.detailedApplicationView,
272 SIGNAL(applicationEnabledChange(bool)),
273 &scenarioListController,
274 SLOT(updateModel()));
275
276 QObject::connect(&openScenarioController,
277 SIGNAL(showPackageDialog()),
278 &settingsController,
279 SLOT(showPackageAdderView()));
280
281 QObject::connect(widget.detailedApplicationView,
283 &scenarioListController,
285
286 QObject::connect(&applicationController,
287 SIGNAL(modelUpdated(FilterableTreeModelSortFilterProxyModelPtr)),
288 widget.applicationDatabase,
290
291 if (isPackageAutoDiscoveryEnabled())
292 {
293 ARMARX_IMPORTANT << "ArmarX package autodiscovery enabled.";
294 autoDiscoverArmarXPackages();
295 }
296
297 widget.scenarioView->setModel(scenarioListController.getTreeModel());
298
299 connect(editModeAction, SIGNAL(toggled(bool)), this, SLOT(editMode(bool)));
300
301 editModeAction->setCheckable(true);
302 editModeAction->setToolTip(
303 "If toggled the application database and the application property view will be shown.");
304
305 QSettings settings(QString(settingsFile.c_str()), QSettings::NativeFormat);
306 QStringList packages = settings.value("packages").toStringList();
307 packages.removeDuplicates();
308
309 if (packages.empty())
310 {
312 if (application.get() != nullptr)
313 {
314 for (const auto& package : application->getArmarXPackageNames())
315 {
316 packages << QString::fromStdString(package);
317 }
318 }
319 settings.setValue("packages", packages);
320 }
321
322 bool editModeState = settings.value("editMode", false).toBool();
323 editModeAction->setChecked(editModeState);
324 editMode(editModeState);
325
326 settingsController.init();
327
329}
330
331QPointer<QWidget>
333{
334 if (customToolbar)
335 {
336 if (parent != customToolbar->parent())
337 {
338 customToolbar->setParent(parent);
339 }
340
341 return customToolbar.data();
342 }
343
344 customToolbar = new QToolBar(parent);
345 customToolbar->setIconSize(QSize(16, 16));
346 customToolbar->addAction(
347 QIcon(":/icons/configure-3.png"), "Configure", &settingsController, SLOT(showSettings()));
348 QToolTip::showText(customToolbar->mapToGlobal(QPoint(0, 0)),
349 "Additional Packages can be opened in the settings");
350 customToolbar->addAction(editModeAction);
351 {
352 QAction* killallAction = new QAction("Kill All", this);
353 customToolbar->addAction(killallAction);
354 killallAction->setToolTip(
355 "Kill all armarx applications except guis on this pc (executes 'armarx killAll')");
356 connect(killallAction,
357 &QAction::triggered,
358 [] { [[maybe_unused]] auto result = std::system("armarx killAll"); });
359 }
360 return customToolbar.data();
361}
362
363void
367
368void
370{
371 scenarioListController.stopUpdateTask();
372}
373
374void
376{
377 QSettings settings(QString(settingsFile.c_str()), QSettings::NativeFormat);
378 QStringList packages = settings.value("packages").toStringList();
379 packages.removeDuplicates();
380
381 QProgressDialog progress("Loading scenarios from " + QString::number(packages.size()) +
382 " packages ...",
383 "",
384 0,
385 packages.size(),
386 getWidget());
387 progress.setWindowModality(Qt::WindowModal);
388
389 PackageBuilder parser;
390 bool didNotFindSomePackages = false;
391 for (int i = 0; i < packages.size(); i++)
392 {
393 std::string name = packages.at(i).toStdString();
394 progress.setLabelText(QString("Loading scenarios from package ") + name.c_str());
395 progress.setValue(i + 1);
396 qApp->processEvents();
397
398 QStringList openedScenarios = settings.value("scenarios").toStringList();
399 // remove duplicates
400 openedScenarios = openedScenarios.toSet().values();
401
402 StringList openedList;
403 for (const QString& it : openedScenarios)
404 {
405 openedList.push_back(it.toStdString());
406 }
407
408 PackagePtr package = parser.parsePackage(name, openedList);
409 if (package == nullptr)
410 {
411 didNotFindSomePackages = true;
412 continue;
413 }
414
415 this->packages->push_back(package);
416 }
417
418 if (didNotFindSomePackages)
419 {
420 std::stringstream ss;
421 ss << "To remove unavailable packages, "
422 << "open the configuration (wrench icon at the top of the ScenarioManager), "
423 << "switch to the 'Cache Settings' tab, "
424 << "and press 'Close unavailable packages'. Cheers!";
425 ARMARX_INFO << ss.str();
426 }
427
428 updateModels();
429}
430
431void
433{
434 PackageBuilder parser;
435 PackagePtr package = parser.parsePackage(name, StringList());
436
437 this->packages->push_back(package);
438
439 updateModels();
440}
441
442void
444{
445 settingsController.updateModel();
446 openScenarioController.updateModel();
447 scenarioListController.updateModel();
448 applicationController.updatePackages();
449 widget.detailedApplicationView->updateStatus();
450
451 //widget.applicationDatabase->setModel(applicationController.getModel());
452 //widget.scenarioView->setModel(scenarioListController.getTreeModel());
453}
454
455void
457{
458 QSettings settings(QString(settingsFile.c_str()), QSettings::NativeFormat);
459 settings.setValue("editMode", edit);
460 widget.detailedApplicationView->setVisible(edit);
461 widget.applicationDatabase->setVisible(edit);
462}
TreeItem representing data contained in a Scenario or an Application.
void setDetailedApplicationView(DetailedApplicationView *ptr)
Sets the view this controller manages.
void setIceAdmin(IceGrid::AdminPrx iceAdmin)
Set an IceAdmin for the controller.
void setIceAdmin(IceGrid::AdminPrx iceAdmin)
Set an IceAdmin for the controller.
FilterableTreeModelSortFilterProxyModelPtr getTreeModel()
Returns the model used by the ScenarioListView and managed by this controller.
Starts, stops and restarts applications and scenarios.
Definition Executor.h:55
Abstract base class for factory classes that create ApplicationStarter.
Abstract base class for factory classes that create ApplicationStopper.
static ApplicationPtr getInstance()
Retrieve shared pointer to the application object.
The ArmarXDataPath class provides static methods to handle ArmarX data directories.
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
static std::vector< std::string > FindAllArmarXSourcePackages()
Property< PropertyType > getProperty(const std::string &name)
IceManagerPtr getIceManager() const
Returns the IceManager.
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
bool hasProperty(const std::string &name)
~ScenarioManagerWidgetController() override
Controller destructor.
QPointer< QWidget > getCustomTitlebarWidget(QWidget *parent) override
getTitleToolbar returns a pointer to the a toolbar widget of this controller.
std::shared_ptr< FilterableTreeModelSortFilterProxyModel > FilterableTreeModelSortFilterProxyModelPtr
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
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
std::vector< std::string > StringList
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< Application > ApplicationPtr
Definition Application.h:93