diff --git a/source/ArmarXGui/applications/ArmarXGui/ArmarXGuiApp.cpp b/source/ArmarXGui/applications/ArmarXGui/ArmarXGuiApp.cpp index 22c7dfcc50d83787f7ff8c330458f6b9e2509b35..1a2a1ea2306628f1be634f4dda0532e8d10c42a3 100644 --- a/source/ArmarXGui/applications/ArmarXGui/ArmarXGuiApp.cpp +++ b/source/ArmarXGui/applications/ArmarXGui/ArmarXGuiApp.cpp @@ -38,6 +38,8 @@ #include <ArmarXCore/core/time/DateTime.h> #include <ArmarXCore/util/CPPUtility/trace.h> +#include <SimoxUtility/algorithm/string.h> + namespace armarx { @@ -97,6 +99,7 @@ namespace armarx } + int ArmarXGuiApp::exec(const ArmarXManagerPtr& armarXManager) { // init SoDB and Qt, SoQt::init also creates an application object @@ -107,7 +110,7 @@ namespace armarx (void)coin_setenv("COIN_SEPARATE_DIFFUSE_TRANSPARENCY_OVERRIDE", "1", TRUE); { - std::vector<std::string> packageNames = getDefaultPackageNames(); + const std::vector<std::string> packageNames = getArmarXPackageNames(); QString configToLoad; if (getProperty<std::string>("GuiConfigFile").isSet()) { @@ -126,7 +129,7 @@ namespace armarx { if (!iter->empty()) { - std::cout << "Loading plugin: " << iter->c_str() << std::endl; + ARMARX_VERBOSE << "Loading plugin: " << iter->c_str() << std::endl; mainWindow->loadPlugin(iter->c_str()); } } diff --git a/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp b/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp index b5084aeb3a52e08108e57f1c5d046709222c72bd..4e20a9efc82f357a3ce0759334a38206ef024c20 100644 --- a/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp +++ b/source/ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.cpp @@ -447,7 +447,7 @@ namespace armarx while (directoriesToCheck.size() > 0) { - ARMARX_INFO_S << "Checking dir : " + directoriesToCheck.front().absolutePath() << std::endl; + ARMARX_VERBOSE_S << "Checking dir : " + directoriesToCheck.front().absolutePath() << std::endl; splashSceen->showMessage(splashscreenPrefix + directoriesToCheck.front().absolutePath(), Qt::AlignJustify | Qt::AlignBottom); qApp->processEvents(); @@ -670,7 +670,27 @@ namespace armarx return; } - QStringList packagesToLoad = settings.value("loadedPackages").toStringList(); + // QStringList packagesToLoad = settings.value("loadedPackages").toStringList(); + auto packagesStd = CMakePackageFinder::FindAllArmarXSourcePackages(); + + // force deterministic loading of plugins by name + std::sort(packagesStd.begin(), packagesStd.end(), + [](const std::string& lhs, const std::string& rhs) -> bool { + return simox::alg::to_lower(lhs) < simox::alg::to_lower(rhs); + }); + + QStringList packagesToLoad; + ARMARX_VERBOSE << "Discovered: "; + for(const auto& pkg : packagesStd) + { + packagesToLoad.push_back(QString::fromStdString(pkg)); + ARMARX_VERBOSE << "- " << pkg; + } + + settings.setValue("loadedPackages", packagesToLoad); + + ARMARX_INFO << "Loaded packages" << packagesStd; + foreach (QString package, packagesToLoad) { loadPluginsFromPackage(package); diff --git a/source/ArmarXGui/applications/ArmarXGui/Widgets/GuiUseCaseSelector.cpp b/source/ArmarXGui/applications/ArmarXGui/Widgets/GuiUseCaseSelector.cpp index 61c90b15215dc58a344a38be23f13b261ca5ec07..6b77b8c8bd56abc26e160e6e4b80f9e7204475a9 100644 --- a/source/ArmarXGui/applications/ArmarXGui/Widgets/GuiUseCaseSelector.cpp +++ b/source/ArmarXGui/applications/ArmarXGui/Widgets/GuiUseCaseSelector.cpp @@ -102,7 +102,7 @@ namespace armarx void GuiUseCaseSelector::addDefaultConfig(QString configPath, QString packageName) { - ARMARX_INFO_S << "Adding " << configPath; + ARMARX_VERBOSE_S << "Adding " << configPath; QSettings s(configPath, QSettings::IniFormat); UseCaseSelectorItem* item = new UseCaseSelectorItem(s.value("ConfigTitle").toString(), s.value("ConfigDescription").toString(), diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.cpp b/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.cpp index 66b5d55ed8eebe6b6bc3de4446dcedabedc0d172..2b85b2bf325bd6008f97f725065c027cbb5ce210 100644 --- a/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.cpp +++ b/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.cpp @@ -35,6 +35,7 @@ #include <ArmarXGui/applications/ArmarXGui/ArmarXMainWindow.h> #include "gui/namelocationview.h" +#include <SimoxUtility/algorithm/string/string_tools.h> using namespace armarx; using namespace ScenarioManager; @@ -67,19 +68,52 @@ ScenarioManagerWidgetController::~ScenarioManagerWidgetController() { } +bool ScenarioManagerWidgetController::isPackageAutoDiscoveryEnabled() +{ + if(hasProperty("AutodiscoverPackages")) + { + return getProperty<bool>("AutodiscoverPackages").getValue(); + } + ARMARX_WARNING << "AutodiscoverPackages property not found"; + + return false; // Property not available. Default: don't use autodiscovery +} + + +void ScenarioManagerWidgetController::autoDiscoverArmarXPackages() +{ + QSettings autosettings(QString(settingsFile.c_str()), QSettings::NativeFormat); + + + auto packagesStd = CMakePackageFinder::FindAllArmarXSourcePackages(); + std::sort(packagesStd.begin(), packagesStd.end(), + [](const std::string& lhs, const std::string& rhs) -> bool { + return simox::alg::to_lower(lhs) < simox::alg::to_lower(rhs); + }); + + QStringList packages; + ARMARX_INFO << "Discovered the following ArmarX packages: "; + for(const auto& pkg : packagesStd) + { + packages.push_back(QString::fromStdString(pkg)); + ARMARX_INFO << "- " << pkg; + } + + autosettings.setValue("packages", packages); +} void ScenarioManagerWidgetController::loadSettings(QSettings* settings) { QSettings autosettings(QString(settingsFile.c_str()), QSettings::NativeFormat); QStringList scenarios = settings->value("scenarios", QStringList()).toStringList(); scenarios.removeDuplicates(); - if (scenarios.size() > 0) + if (not scenarios.empty()) { autosettings.setValue("scenarios", scenarios); } QStringList packages = settings->value("packages", QStringList()).toStringList(); packages.removeDuplicates(); - if (packages.size() > 0) + if (not packages.empty()) { autosettings.setValue("packages", packages); } @@ -97,8 +131,8 @@ ScenarioManagerWidgetController::saveSettings(QSettings* settings) settings->setValue("packages", packages); } -void -ScenarioManagerWidgetController::onInitComponent() + +void ScenarioManagerWidgetController::onInitComponent() { QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); } @@ -248,6 +282,12 @@ ScenarioManagerWidgetController::init() widget.applicationDatabase, SLOT(setModel(FilterableTreeModelSortFilterProxyModelPtr))); + if(isPackageAutoDiscoveryEnabled()) + { + ARMARX_IMPORTANT << "ArmarX package autodiscovery enabled."; + autoDiscoverArmarXPackages(); + } + widget.scenarioView->setModel(scenarioListController.getTreeModel()); connect(editModeAction, SIGNAL(toggled(bool)), this, SLOT(editMode(bool))); @@ -260,13 +300,12 @@ ScenarioManagerWidgetController::init() QStringList packages = settings.value("packages").toStringList(); packages.removeDuplicates(); - if (packages.size() == 0) + if (packages.empty()) { - //armarx::ArmarXMainWindow* mainWindow = static_cast<ArmarXMainWindow*>(); armarx::ApplicationPtr application = Application::getInstance(); if (application.get() != nullptr) { - for (auto package : application->getDefaultPackageNames()) + for (const auto& package : application->getArmarXPackageNames()) { packages << QString::fromStdString(package); } diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.h b/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.h index d423d3ba934cce561d7ef8ed28d4f17abfcec873..29473c4f62ce972b05a1ca64ede2db6820a56520 100644 --- a/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.h +++ b/source/ArmarXGui/gui-plugins/ScenarioManager/ScenarioManagerWidgetController.h @@ -144,6 +144,9 @@ namespace armarx QAction* editModeAction; QSettings settings; QPointer<QToolBar> customToolbar; + + void autoDiscoverArmarXPackages(); + const std::string settingsFile; // ArmarXWidgetController interface public: @@ -154,6 +157,9 @@ namespace armarx { return QIcon(":icons/ArmarX_Play_Store.svg"); } + + private: + bool isPackageAutoDiscoveryEnabled(); + }; } - diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.cpp b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.cpp index 8c1fc45ec936416244bd44b92d793b70ecbb7316..efabdad1152ab3fd41198de141d7411f6d977d98 100644 --- a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.cpp +++ b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.cpp @@ -37,6 +37,8 @@ ApplicationDatabaseView::ApplicationDatabaseView(QWidget* parent) : ui->setupUi(this); ui->treeView->setModel(model.get()); + + ui->treeView->header()->setSortIndicator(0, Qt::SortOrder::AscendingOrder); ui->treeView->setSortingEnabled(true); ui->treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -56,6 +58,8 @@ void ApplicationDatabaseView::setModel(FilterableTreeModelSortFilterProxyModelPt { this->model = model; + model->setSortCaseSensitivity(Qt::CaseInsensitive); + ui->treeView->setModel(model.get()); ui->treeView->setColumnWidth(0, 200); ui->treeView->expandAll(); @@ -78,4 +82,3 @@ std::mutex& ApplicationDatabaseView::getMutex() { return mutex; } - diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.h b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.h index 25720df8a369d682bc4cd5b65cf574a20fc2134b..ba359a387af6726b0eefaff3597c69e581567419 100644 --- a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.h +++ b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/applicationdatabaseview.h @@ -80,4 +80,3 @@ private: std::mutex mutex; }; - diff --git a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/filterabletreemodelsortfilterproxymodel.h b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/filterabletreemodelsortfilterproxymodel.h index f1e62a4f7e50fcf22107be899de8e221c16ededb..71558f40a3d53d72bb644625cd1b52ec1b7f6c0d 100644 --- a/source/ArmarXGui/gui-plugins/ScenarioManager/gui/filterabletreemodelsortfilterproxymodel.h +++ b/source/ArmarXGui/gui-plugins/ScenarioManager/gui/filterabletreemodelsortfilterproxymodel.h @@ -63,4 +63,3 @@ public: }; using FilterableTreeModelSortFilterProxyModelPtr = std::shared_ptr<FilterableTreeModelSortFilterProxyModel>; - diff --git a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/StatechartEditorController.cpp b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/StatechartEditorController.cpp index 9a828da8cf44d4eb433b16454976665295b91e50..dd6163d8c8ab2114c9ab2fe6b638e7e8ec7e55dc 100644 --- a/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/StatechartEditorController.cpp +++ b/source/ArmarXGui/gui-plugins/StatechartEditorPlugin/StatechartEditorController.cpp @@ -168,7 +168,7 @@ namespace armarx if (!profiles) { profiles = StatechartProfiles::ReadProfileFiles( - Application::getInstance()->getDefaultPackageNames()); + Application::getInstance()->getArmarXPackageNames()); } if (settings->contains("selectedProfile")) @@ -909,7 +909,7 @@ armarx::StatechartEditorController::getConfigDialog(QWidget* parent) if (!dialog) { profiles = StatechartProfiles::ReadProfileFiles( - Application::getInstance()->getDefaultPackageNames()); + Application::getInstance()->getArmarXPackageNames()); dialog = new StatechartEditorConfigDialog(profiles, parent); } diff --git a/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.cpp b/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.cpp index d732f062ca844e34bb661bf183d8279926e29dc0..0d8355238521f13eafce4e2eb887bb8f78909862 100644 --- a/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.cpp +++ b/source/ArmarXGui/libraries/ArmarXGuiBase/PluginCache.cpp @@ -233,7 +233,7 @@ namespace armarx if (!data.pluginLoader && !pluginPath.isEmpty()) { auto pluginLoader = QSharedPointer<QPluginLoader>(new QPluginLoader(pluginPath)); - ARMARX_INFO_S << "Loading plugin " << pluginPath; + ARMARX_VERBOSE_S << "Loading plugin " << pluginPath; pluginLoader->load(); // data.pluginLoader->load(); break; @@ -336,7 +336,7 @@ namespace armarx QSharedPointer<QPluginLoader> loader(new QPluginLoader(pluginPath)); auto widgets = loadPlugin(loader); copyResourcesToCache(); - ARMARX_INFO_S << "Writing plugin " << pluginPath << " to cache"; + ARMARX_VERBOSE_S << "Writing plugin " << pluginPath << " to cache"; std::unique_lock lock(cacheMutex); QMap<QString, QVariant> widgetMap = s.value("widgets").toMap(); QDateTime time = QFileInfo(pluginPath).lastModified(); @@ -403,7 +403,7 @@ namespace armarx WidgetCreatorMap PluginCache::loadPlugin(QSharedPointer<QPluginLoader> loader) { WidgetCreatorMap result; - ARMARX_INFO_S << "Loading plugin " << loader->fileName(); + ARMARX_VERBOSE_S << "Loading plugin " << loader->fileName(); QObject* plugin = loader->instance(); // calls load if (plugin)