From bc63b60413ad21ce725971e6b92f195ccffa0f94 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Fri, 27 May 2022 12:15:29 -0700 Subject: [PATCH 01/40] Example running a dialog before the main window Signed-off-by: Louise Poubel --- .../standalone/start_dialog/CMakeLists.txt | 25 +++++ examples/standalone/start_dialog/README.md | 16 ++++ .../standalone/start_dialog/start_dialog.cc | 92 +++++++++++++++++++ .../standalone/start_dialog/start_dialog.qml | 26 ++++++ .../standalone/start_dialog/start_dialog.qrc | 5 + include/ignition/gui/Application.hh | 11 ++- src/Application.cc | 6 ++ src/Application_TEST.cc | 13 +++ 8 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 examples/standalone/start_dialog/CMakeLists.txt create mode 100644 examples/standalone/start_dialog/README.md create mode 100644 examples/standalone/start_dialog/start_dialog.cc create mode 100644 examples/standalone/start_dialog/start_dialog.qml create mode 100644 examples/standalone/start_dialog/start_dialog.qrc diff --git a/examples/standalone/start_dialog/CMakeLists.txt b/examples/standalone/start_dialog/CMakeLists.txt new file mode 100644 index 000000000..7207a0bfe --- /dev/null +++ b/examples/standalone/start_dialog/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR) + +project(gz-gui-start-dialog) + +if(POLICY CMP0100) + cmake_policy(SET CMP0100 NEW) +endif() + +set(CMAKE_AUTOMOC ON) + +find_package(ignition-gui3 REQUIRED) +set(GZ_GUI_VER ${ignition-gui3_VERSION_MAJOR}) + +set(EXEC_NAME "start_dialog") + +QT5_ADD_RESOURCES(resources_RCC ${EXEC_NAME}.qrc) + +add_executable(${EXEC_NAME} + ${EXEC_NAME}.cc + ${resources_RCC} +) +target_link_libraries(${EXEC_NAME} + ignition-gui${GZ_GUI_VER}::ignition-gui${GZ_GUI_VER} +) + diff --git a/examples/standalone/start_dialog/README.md b/examples/standalone/start_dialog/README.md new file mode 100644 index 000000000..4ab7c686c --- /dev/null +++ b/examples/standalone/start_dialog/README.md @@ -0,0 +1,16 @@ +Example for how to run a start dialog before the main window. + +## Build + + cd + mkdir build + cd build + cmake .. + make + +## Run + + cd /build + ./start_dialog + +First the dialog shows up, and after that's closed, the main window shows up. diff --git a/examples/standalone/start_dialog/start_dialog.cc b/examples/standalone/start_dialog/start_dialog.cc new file mode 100644 index 000000000..7bbc47633 --- /dev/null +++ b/examples/standalone/start_dialog/start_dialog.cc @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2022 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#include + +#include +#include +#include +#include + +////////////////////////////////////////////////// +int main(int _argc, char **_argv) +{ + // Increase verboosity so we see all messages + ignition::common::Console::SetVerbosity(4); + + // Create app + ignition::gui::Application app(_argc, _argv, ignition::gui::WindowType::kDialog); + + igndbg << "Open dialog" << std::endl; + + // Add and display a dialog + auto dialog = new ignition::gui::Dialog(); + dialog->QuickWindow(); + + std::string qmlFile(":start_dialog/start_dialog.qml"); + if (!QFile(QString::fromStdString(qmlFile)).exists()) + { + ignerr << "Can't find [" << qmlFile + << "]. Are you sure it was added to the .qrc file?" << std::endl; + return -1; + } + + QQmlComponent dialogComponent(ignition::gui::App()->Engine(), + QString(QString::fromStdString(qmlFile))); + if (dialogComponent.isError()) + { + std::stringstream errors; + errors << "Failed to instantiate QML file [" << qmlFile << "]." + << std::endl; + for (auto error : dialogComponent.errors()) + { + errors << "* " << error.toString().toStdString() << std::endl; + } + ignerr << errors.str(); + return -1; + } + + auto dialogItem = qobject_cast(dialogComponent.create()); + if (!dialogItem) + { + ignerr << "Failed to instantiate QML file [" << qmlFile << "]." << std::endl + << "Are you sure the file is valid QML? " + << "You can check with the `qmlscene` tool" << std::endl; + return -1; + } + + dialogItem->setParentItem(dialog->RootItem()); + + // Execute start dialog + app.exec(); + + // After dialog is shut, display the main window + igndbg << "Dialog closed, open main window" << std::endl; + + // Create main window + // FIXME: use CreateMainWindow - currently complains with undefined reference + //app.CreateMainWindow(); + app.InitializeMainWindow(); + + // Run main window + app.exec(); + + igndbg << "Main window closed" << std::endl; + + return 0; +} + diff --git a/examples/standalone/start_dialog/start_dialog.qml b/examples/standalone/start_dialog/start_dialog.qml new file mode 100644 index 000000000..a07f4ff52 --- /dev/null +++ b/examples/standalone/start_dialog/start_dialog.qml @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2022 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ +import QtQuick 2.0 +import QtQuick.Controls 2.0 +Rectangle { + color: "green" + anchors.fill: parent + Text { + text: qsTr("Start\ndialog!") + font.pointSize: 30 + } +} diff --git a/examples/standalone/start_dialog/start_dialog.qrc b/examples/standalone/start_dialog/start_dialog.qrc new file mode 100644 index 000000000..578d9c3c2 --- /dev/null +++ b/examples/standalone/start_dialog/start_dialog.qrc @@ -0,0 +1,5 @@ + + + start_dialog.qml + + diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index b0813a8fc..fd018531c 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -53,7 +53,8 @@ namespace ignition /// plugins kMainWindow = 0, - /// \brief One independent dialog per plugin + /// \brief One independent dialog per plugin. Also useful to open a + /// startup dialog before the main window. kDialog = 1 }; @@ -169,13 +170,19 @@ namespace ignition /// \brief Callback when user requests to close a plugin public slots: void OnPluginClose(); + /// \brief Create a main window. Just calls InitializeMainWindow. + /// \return True if successful + /// \sa InitializeMainWindow + public: bool CreateMainWindow(); + /// \brief Create a main window, populate with previously loaded plugins /// and apply previously loaded configuration. /// An empty window will be created if no plugins have been loaded. /// \return True if successful /// \sa LoadConfig /// \sa LoadPlugin - private: bool InitializeMainWindow(); + // FIXME: this should be private and CreateMainWindow public + public: bool InitializeMainWindow(); /// \brief Create individual dialogs for all previously loaded plugins. /// This has no effect if no plugins have been loaded. diff --git a/src/Application.cc b/src/Application.cc index 38facd1c4..39f063cb1 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -537,6 +537,12 @@ std::shared_ptr Application::PluginByName( return nullptr; } +///////////////////////////////////////////////// +bool Application::CreateMainWindow() +{ + return this->InitializeMainWindow(); +} + ///////////////////////////////////////////////// bool Application::InitializeMainWindow() { diff --git a/src/Application_TEST.cc b/src/Application_TEST.cc index 9ca02cc90..0ebc5c187 100644 --- a/src/Application_TEST.cc +++ b/src/Application_TEST.cc @@ -289,6 +289,19 @@ TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(InitializeMainWindow)) // Show window app.exec(); } + + // Start in dialog mode and create main window later + { + Application app(g_argc, g_argv, WindowType::kDialog); + + auto win = App()->findChild(); + EXPECT_EQ(nullptr, win); + + app.CreateMainWindow(); + + win = App()->findChild(); + ASSERT_NE(nullptr, win); + } } ////////////////////////////////////////////////// From 1e9390f4a44e3ab712616aabc7361ce4a05fd26d Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 14 Jun 2022 16:52:15 +0200 Subject: [PATCH 02/40] parse show quick setup menu by default option Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 7 +++++- include/ignition/gui/MainWindow.hh | 12 +++++++++ src/Application.cc | 5 ++++ src/MainWindow.cc | 38 +++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index b0813a8fc..93471310f 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -155,6 +155,11 @@ namespace ignition /// \return True if successful public: bool RemovePlugin(const std::string &_pluginName); + /// \brief Show quick setup menu or not + /// \return True if quick setup menu is configured to be shown before main window + /// initialized. + public: bool ShowQuickSetup() const; + /// \brief Get a plugin by its unique name. /// \param[in] _pluginName Plugn instance's unique name. This is the /// plugin card's object name. @@ -175,7 +180,7 @@ namespace ignition /// \return True if successful /// \sa LoadConfig /// \sa LoadPlugin - private: bool InitializeMainWindow(); + public: bool InitializeMainWindow(); /// \brief Create individual dialogs for all previously loaded plugins. /// This has no effect if no plugins have been loaded. diff --git a/include/ignition/gui/MainWindow.hh b/include/ignition/gui/MainWindow.hh index 39ad7619a..a8c34a348 100644 --- a/include/ignition/gui/MainWindow.hh +++ b/include/ignition/gui/MainWindow.hh @@ -405,6 +405,15 @@ namespace ignition public: Q_INVOKABLE void SetShowDefaultDrawerOpts( const bool _showDefaultDrawerOpts); + /// \brief Get the flag to show the quick setup menu's default options. + /// \return True to show. + public: bool ShowDefaultQuickSetupOpts() const; + + /// \brief Set the flag to show the quick setup menu's default options. + /// \param[in] _showDefaultQuickSetupOpts True to show. + public: void SetShowDefaultQuickSetupOpts( + const bool _showDefaultQuickSetupOpts); + /// \brief Get the flag to show the plugin menu. /// \return True to show. public: Q_INVOKABLE bool ShowPluginMenu() const; @@ -656,6 +665,9 @@ namespace ignition /// \brief Show the default options of the drawer bool showDefaultDrawerOpts{true}; + /// \brief Show the default options of the quick setup menu + bool showDefaultQuickSetupOpts{true}; + /// \brief Show the plugins menu bool showPluginMenu{true}; diff --git a/src/Application.cc b/src/Application.cc index 38facd1c4..78b722d56 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -215,6 +215,11 @@ bool Application::RemovePlugin(const std::string &_pluginName) return true; } +///////////////////////////////////////////////// +bool Application::ShowQuickSetup() const +{ + return this->dataPtr->mainWin->ShowDefaultQuickSetupOpts(); +} ///////////////////////////////////////////////// bool Application::LoadConfig(const std::string &_config) { diff --git a/src/MainWindow.cc b/src/MainWindow.cc index d6157010b..af1a12293 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -331,6 +331,7 @@ bool MainWindow::ApplyConfig(const WindowConfig &_config) // Menus this->SetShowDrawer(_config.showDrawer); this->SetShowDefaultDrawerOpts(_config.showDefaultDrawerOpts); + this->SetShowDefaultQuickSetupOpts(_config.showDefaultQuickSetupOpts); this->SetShowPluginMenu(_config.showPluginMenu); // Keep a copy @@ -383,6 +384,8 @@ WindowConfig MainWindow::CurrentWindowConfig() const config.showDrawer = this->dataPtr->windowConfig.showDrawer; config.showDefaultDrawerOpts = this->dataPtr->windowConfig.showDefaultDrawerOpts; + config.showDefaultQuickSetupOpts = + this->dataPtr->windowConfig.showDefaultQuickSetupOpts; config.showPluginMenu = this->dataPtr->windowConfig.showPluginMenu; config.pluginsFromPaths = this->dataPtr->windowConfig.pluginsFromPaths; config.showPlugins = this->dataPtr->windowConfig.showPlugins; @@ -514,6 +517,18 @@ bool WindowConfig::MergeFromXML(const std::string &_windowXml) } } + // QuickSetup + if (auto quickSetupElem = menusElem->FirstChildElement("quick_setup")) + { + // Default + if (quickSetupElem->Attribute("default")) + { + bool def = true; + quickSetupElem->QueryBoolAttribute("default", &def); + this->showDefaultQuickSetupOpts = def; + } + } + // Plugins if (auto pluginsElem = menusElem->FirstChildElement("plugins")) { @@ -648,6 +663,16 @@ std::string WindowConfig::XMLString() const menusElem->InsertEndChild(elem); } + // Quick Setup + { + auto elem = doc.NewElement("quick_setup"); + + // Default + elem->SetAttribute("default", this->showDefaultQuickSetupOpts); + + menusElem->InsertEndChild(elem); + } + // Plugins { auto elem = doc.NewElement("plugins"); @@ -905,6 +930,19 @@ void MainWindow::SetShowDefaultDrawerOpts(const bool _showDefaultDrawerOpts) this->ShowDefaultDrawerOptsChanged(); } +///////////////////////////////////////////////// +bool MainWindow::ShowDefaultQuickSetupOpts() const +{ + return this->dataPtr->windowConfig.showDefaultQuickSetupOpts; +} + +///////////////////////////////////////////////// +void MainWindow::SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) +{ + this->dataPtr->windowConfig.showDefaultQuickSetupOpts = + _showDefaultQuickSetupOpts; +} + ///////////////////////////////////////////////// bool MainWindow::ShowPluginMenu() const { From b891da0ffa8dd1011cc1806a94930385b0ceba5b Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 16 Jun 2022 18:25:13 +0200 Subject: [PATCH 03/40] add load window config, load config without loading plugins Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 19 ++++++-- include/ignition/gui/MainWindow.hh | 19 ++++---- src/Application.cc | 76 ++++++++++++++++++++++++++++- src/MainWindow.cc | 27 +++++----- 4 files changed, 113 insertions(+), 28 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index e79b492ab..fe17f8d55 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -97,12 +97,18 @@ namespace ignition /// and plugins. This function doesn't instantiate the plugins, it just /// keeps them in memory and they can be applied later by either /// instantiating a window or several dialogs. + /// and plugins. /// \param[in] _path Full path to configuration file. /// \return True if successful /// \sa InitializeMainWindow /// \sa InitializeDialogs public: bool LoadConfig(const std::string &_path); + /// \brief Load a configuration file, load window configurations. + /// \param[in] _path Full path to configuration file. + /// \return True if successful + public: bool LoadWindowConfig(const std::string &_path); + /// \brief Load the configuration from the default config file. /// \return True if successful /// \sa SetDefaultConfigPath @@ -125,6 +131,15 @@ namespace ignition /// \sa SetDefaultConfigPath public: std::string DefaultConfigPath(); + /// \brief Show quick setup menu or not + /// \return True if quick setup menu is configured to be shown before main window + /// initialized. + public: bool ShowQuickSetup() const; + + /// \brief Set the flag to show the quick setup menu's default options. + /// \param[in] _showDefaultQuickSetupOpts True to show. + public: void SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) const; + /// \brief Set the environment variable which defines the paths to /// look for plugins. /// \param[in] _env Name of environment variable. @@ -156,10 +171,6 @@ namespace ignition /// \return True if successful public: bool RemovePlugin(const std::string &_pluginName); - /// \brief Show quick setup menu or not - /// \return True if quick setup menu is configured to be shown before main window - /// initialized. - public: bool ShowQuickSetup() const; /// \brief Get a plugin by its unique name. /// \param[in] _pluginName Plugn instance's unique name. This is the diff --git a/include/ignition/gui/MainWindow.hh b/include/ignition/gui/MainWindow.hh index a8c34a348..1b681afa7 100644 --- a/include/ignition/gui/MainWindow.hh +++ b/include/ignition/gui/MainWindow.hh @@ -405,15 +405,6 @@ namespace ignition public: Q_INVOKABLE void SetShowDefaultDrawerOpts( const bool _showDefaultDrawerOpts); - /// \brief Get the flag to show the quick setup menu's default options. - /// \return True to show. - public: bool ShowDefaultQuickSetupOpts() const; - - /// \brief Set the flag to show the quick setup menu's default options. - /// \param[in] _showDefaultQuickSetupOpts True to show. - public: void SetShowDefaultQuickSetupOpts( - const bool _showDefaultQuickSetupOpts); - /// \brief Get the flag to show the plugin menu. /// \return True to show. public: Q_INVOKABLE bool ShowPluginMenu() const; @@ -611,6 +602,15 @@ namespace ignition /// \return True if it's being ignored bool IsIgnoring(const std::string &_prop) const; + /// \brief Get the flag to show the quick setup menu's default options. + /// \return True to show. + public: bool ShowDefaultQuickSetupOpts() const; + + /// \brief Set the flag to show the quick setup menu's default options. + /// \param[in] _showDefaultQuickSetupOpts True to show. + public: void SetShowDefaultQuickSetupOpts( + const bool _showDefaultQuickSetupOpts); + /// \brief Window X position in px int posX{-1}; @@ -683,6 +683,7 @@ namespace ignition /// \brief Concatenation of all plugin configurations. std::string plugins{""}; + }; } } diff --git a/src/Application.cc b/src/Application.cc index f7628a8cd..5f3daa75b 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -218,7 +218,81 @@ bool Application::RemovePlugin(const std::string &_pluginName) ///////////////////////////////////////////////// bool Application::ShowQuickSetup() const { - return this->dataPtr->mainWin->ShowDefaultQuickSetupOpts(); + return this->dataPtr->windowConfig.ShowDefaultQuickSetupOpts(); +} + +///////////////////////////////////////////////// +void Application::SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) const +{ + return this->dataPtr->windowConfig.SetShowDefaultQuickSetupOpts(_showDefaultQuickSetupOpts); +} + +///////////////////////////////////////////////// +bool Application::LoadWindowConfig(const std::string &_config) +{ + if (_config.empty()) + { + ignerr << "Missing config file" << std::endl; + return false; + } + + std::string configFull = _config; + + // Check if the passed in config file exists. + // (If the default config path doesn't exist yet, it's expected behavior. + // It will be created the first time the user presses "Save configuration".) + if (!common::exists(configFull) && (configFull != this->DefaultConfigPath())) + { + // If not, then check environment variable + std::string configPathEnv; + common::env("GZ_GUI_RESOURCE_PATH", configPathEnv); + + if (!configPathEnv.empty()) + { + std::vector parentPaths = common::Split(configPathEnv, ':'); + for (auto parentPath : parentPaths) + { + std::string tempPath = common::joinPaths(parentPath, configFull); + if (common::exists(tempPath)) + { + configFull = tempPath; + break; + } + } + } + } + + // Use tinyxml to read config + tinyxml2::XMLDocument doc; + auto success = !doc.LoadFile(configFull.c_str()); + if (!success) + { + // We do not show an error message if the default config path doesn't exist + // yet. It's expected behavior, it will be created the first time the user + // presses "Save configuration". + if (configFull != this->DefaultConfigPath()) + { + ignerr << "Failed to load file [" << configFull << "]: XMLError" + << std::endl; + } + + return false; + } + // Process window properties + if (auto winElem = doc.FirstChildElement("window")) + { + igndbg << "Loading window config" << std::endl; + + tinyxml2::XMLPrinter printer; + if (!winElem->Accept(&printer)) + { + ignwarn << "There was an error parsing the element" + << std::endl; + return false; + } + this->dataPtr->windowConfig.MergeFromXML(std::string(printer.CStr())); + } + return true; } ///////////////////////////////////////////////// bool Application::LoadConfig(const std::string &_config) diff --git a/src/MainWindow.cc b/src/MainWindow.cc index af1a12293..c4b66bd5b 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -331,7 +331,7 @@ bool MainWindow::ApplyConfig(const WindowConfig &_config) // Menus this->SetShowDrawer(_config.showDrawer); this->SetShowDefaultDrawerOpts(_config.showDefaultDrawerOpts); - this->SetShowDefaultQuickSetupOpts(_config.showDefaultQuickSetupOpts); + this->dataPtr->windowConfig.SetShowDefaultQuickSetupOpts(_config.showDefaultQuickSetupOpts); this->SetShowPluginMenu(_config.showPluginMenu); // Keep a copy @@ -717,6 +717,18 @@ std::string WindowConfig::XMLString() const return config; } +///////////////////////////////////////////////// +bool WindowConfig::ShowDefaultQuickSetupOpts() const +{ + return this->showDefaultQuickSetupOpts; +} + +///////////////////////////////////////////////// +void WindowConfig::SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) +{ + this->showDefaultQuickSetupOpts = _showDefaultQuickSetupOpts; +} + ///////////////////////////////////////////////// bool WindowConfig::IsIgnoring(const std::string &_prop) const { @@ -930,19 +942,6 @@ void MainWindow::SetShowDefaultDrawerOpts(const bool _showDefaultDrawerOpts) this->ShowDefaultDrawerOptsChanged(); } -///////////////////////////////////////////////// -bool MainWindow::ShowDefaultQuickSetupOpts() const -{ - return this->dataPtr->windowConfig.showDefaultQuickSetupOpts; -} - -///////////////////////////////////////////////// -void MainWindow::SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) -{ - this->dataPtr->windowConfig.showDefaultQuickSetupOpts = - _showDefaultQuickSetupOpts; -} - ///////////////////////////////////////////////// bool MainWindow::ShowPluginMenu() const { From 163886745f2c6a1a34145b35131b95f52013e8e7 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Sun, 19 Jun 2022 16:04:32 +0200 Subject: [PATCH 04/40] rename quick setup to quick start Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 12 ++++++------ include/ignition/gui/MainWindow.hh | 16 +++++++-------- src/Application.cc | 8 ++++---- src/MainWindow.cc | 30 ++++++++++++++--------------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index fe17f8d55..8520769a4 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -131,14 +131,14 @@ namespace ignition /// \sa SetDefaultConfigPath public: std::string DefaultConfigPath(); - /// \brief Show quick setup menu or not - /// \return True if quick setup menu is configured to be shown before main window + /// \brief Show quick Start menu or not + /// \return True if quick Start menu is configured to be shown before main window /// initialized. - public: bool ShowQuickSetup() const; + public: bool ShowQuickStart() const; - /// \brief Set the flag to show the quick setup menu's default options. - /// \param[in] _showDefaultQuickSetupOpts True to show. - public: void SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) const; + /// \brief Set the flag to show the quick start menu's default options. + /// \param[in] _showDefaultQuickStartOpts True to show. + public: void SetShowDefaultQuickStartOpts(const bool _showDefaultQuickStartOpts) const; /// \brief Set the environment variable which defines the paths to /// look for plugins. diff --git a/include/ignition/gui/MainWindow.hh b/include/ignition/gui/MainWindow.hh index 1b681afa7..9f20be73c 100644 --- a/include/ignition/gui/MainWindow.hh +++ b/include/ignition/gui/MainWindow.hh @@ -602,14 +602,14 @@ namespace ignition /// \return True if it's being ignored bool IsIgnoring(const std::string &_prop) const; - /// \brief Get the flag to show the quick setup menu's default options. + /// \brief Get the flag to show the quick start menu's default options. /// \return True to show. - public: bool ShowDefaultQuickSetupOpts() const; + public: bool ShowDefaultQuickStartOpts() const; - /// \brief Set the flag to show the quick setup menu's default options. - /// \param[in] _showDefaultQuickSetupOpts True to show. - public: void SetShowDefaultQuickSetupOpts( - const bool _showDefaultQuickSetupOpts); + /// \brief Set the flag to show the quick start menu's default options. + /// \param[in] _showDefaultQuickStartOpts True to show. + public: void SetShowDefaultQuickStartOpts( + const bool _showDefaultQuickStartOpts); /// \brief Window X position in px int posX{-1}; @@ -665,8 +665,8 @@ namespace ignition /// \brief Show the default options of the drawer bool showDefaultDrawerOpts{true}; - /// \brief Show the default options of the quick setup menu - bool showDefaultQuickSetupOpts{true}; + /// \brief Show the default options of the quick Start menu + bool showDefaultQuickStartOpts{true}; /// \brief Show the plugins menu bool showPluginMenu{true}; diff --git a/src/Application.cc b/src/Application.cc index 5f3daa75b..7709ad517 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -216,15 +216,15 @@ bool Application::RemovePlugin(const std::string &_pluginName) } ///////////////////////////////////////////////// -bool Application::ShowQuickSetup() const +bool Application::ShowQuickStart() const { - return this->dataPtr->windowConfig.ShowDefaultQuickSetupOpts(); + return this->dataPtr->windowConfig.ShowDefaultQuickStartOpts(); } ///////////////////////////////////////////////// -void Application::SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) const +void Application::SetShowDefaultQuickStartOpts(const bool _showDefaultQuickStartOpts) const { - return this->dataPtr->windowConfig.SetShowDefaultQuickSetupOpts(_showDefaultQuickSetupOpts); + return this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts(_showDefaultQuickStartOpts); } ///////////////////////////////////////////////// diff --git a/src/MainWindow.cc b/src/MainWindow.cc index c4b66bd5b..a9f03af4b 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -331,7 +331,7 @@ bool MainWindow::ApplyConfig(const WindowConfig &_config) // Menus this->SetShowDrawer(_config.showDrawer); this->SetShowDefaultDrawerOpts(_config.showDefaultDrawerOpts); - this->dataPtr->windowConfig.SetShowDefaultQuickSetupOpts(_config.showDefaultQuickSetupOpts); + this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts(_config.showDefaultQuickStartOpts); this->SetShowPluginMenu(_config.showPluginMenu); // Keep a copy @@ -384,8 +384,8 @@ WindowConfig MainWindow::CurrentWindowConfig() const config.showDrawer = this->dataPtr->windowConfig.showDrawer; config.showDefaultDrawerOpts = this->dataPtr->windowConfig.showDefaultDrawerOpts; - config.showDefaultQuickSetupOpts = - this->dataPtr->windowConfig.showDefaultQuickSetupOpts; + config.showDefaultQuickStartOpts = + this->dataPtr->windowConfig.showDefaultQuickStartOpts; config.showPluginMenu = this->dataPtr->windowConfig.showPluginMenu; config.pluginsFromPaths = this->dataPtr->windowConfig.pluginsFromPaths; config.showPlugins = this->dataPtr->windowConfig.showPlugins; @@ -517,15 +517,15 @@ bool WindowConfig::MergeFromXML(const std::string &_windowXml) } } - // QuickSetup - if (auto quickSetupElem = menusElem->FirstChildElement("quick_setup")) + // QuickStart + if (auto quickStartElem = menusElem->FirstChildElement("quick_start")) { // Default - if (quickSetupElem->Attribute("default")) + if (quickStartElem->Attribute("default")) { bool def = true; - quickSetupElem->QueryBoolAttribute("default", &def); - this->showDefaultQuickSetupOpts = def; + quickStartElem->QueryBoolAttribute("default", &def); + this->showDefaultQuickStartOpts = def; } } @@ -663,12 +663,12 @@ std::string WindowConfig::XMLString() const menusElem->InsertEndChild(elem); } - // Quick Setup + // Quick Start { - auto elem = doc.NewElement("quick_setup"); + auto elem = doc.NewElement("quick_start"); // Default - elem->SetAttribute("default", this->showDefaultQuickSetupOpts); + elem->SetAttribute("default", this->showDefaultQuickStartOpts); menusElem->InsertEndChild(elem); } @@ -718,15 +718,15 @@ std::string WindowConfig::XMLString() const } ///////////////////////////////////////////////// -bool WindowConfig::ShowDefaultQuickSetupOpts() const +bool WindowConfig::ShowDefaultQuickStartOpts() const { - return this->showDefaultQuickSetupOpts; + return this->showDefaultQuickStartOpts; } ///////////////////////////////////////////////// -void WindowConfig::SetShowDefaultQuickSetupOpts(const bool _showDefaultQuickSetupOpts) +void WindowConfig::SetShowDefaultQuickStartOpts(const bool _showDefaultQuickStartOpts) { - this->showDefaultQuickSetupOpts = _showDefaultQuickSetupOpts; + this->showDefaultQuickStartOpts = _showDefaultQuickStartOpts; } ///////////////////////////////////////////////// From f0acce5ffe76ebbd5e0b7e672904cc59c603c0ac Mon Sep 17 00:00:00 2001 From: Mohamad Date: Mon, 20 Jun 2022 22:34:20 +0200 Subject: [PATCH 05/40] code check Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 6 ++++-- src/Application.cc | 7 +++++-- src/MainWindow.cc | 6 ++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index 8520769a4..dc0f39946 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -132,13 +132,15 @@ namespace ignition public: std::string DefaultConfigPath(); /// \brief Show quick Start menu or not - /// \return True if quick Start menu is configured to be shown before main window + /// \return True if quick Start menu is configured to be shown + /// before main window /// initialized. public: bool ShowQuickStart() const; /// \brief Set the flag to show the quick start menu's default options. /// \param[in] _showDefaultQuickStartOpts True to show. - public: void SetShowDefaultQuickStartOpts(const bool _showDefaultQuickStartOpts) const; + public: void SetShowDefaultQuickStartOpts( + const bool _showDefaultQuickStartOpts) const; /// \brief Set the environment variable which defines the paths to /// look for plugins. diff --git a/src/Application.cc b/src/Application.cc index 7709ad517..dc0536756 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -222,9 +222,11 @@ bool Application::ShowQuickStart() const } ///////////////////////////////////////////////// -void Application::SetShowDefaultQuickStartOpts(const bool _showDefaultQuickStartOpts) const +void Application::SetShowDefaultQuickStartOpts( + const bool _showDefaultQuickStartOpts) const { - return this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts(_showDefaultQuickStartOpts); + return this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts( + _showDefaultQuickStartOpts); } ///////////////////////////////////////////////// @@ -294,6 +296,7 @@ bool Application::LoadWindowConfig(const std::string &_config) } return true; } + ///////////////////////////////////////////////// bool Application::LoadConfig(const std::string &_config) { diff --git a/src/MainWindow.cc b/src/MainWindow.cc index a9f03af4b..293a3daa7 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -331,7 +331,8 @@ bool MainWindow::ApplyConfig(const WindowConfig &_config) // Menus this->SetShowDrawer(_config.showDrawer); this->SetShowDefaultDrawerOpts(_config.showDefaultDrawerOpts); - this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts(_config.showDefaultQuickStartOpts); + this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts( + _config.showDefaultQuickStartOpts); this->SetShowPluginMenu(_config.showPluginMenu); // Keep a copy @@ -724,7 +725,8 @@ bool WindowConfig::ShowDefaultQuickStartOpts() const } ///////////////////////////////////////////////// -void WindowConfig::SetShowDefaultQuickStartOpts(const bool _showDefaultQuickStartOpts) +void WindowConfig::SetShowDefaultQuickStartOpts( + const bool _showDefaultQuickStartOpts) { this->showDefaultQuickStartOpts = _showDefaultQuickStartOpts; } From 0da81445449f00848bc99920a5d368fa0b87199e Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 22 Jun 2022 08:55:41 +0200 Subject: [PATCH 06/40] convert createMainWindow to public Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index dc0f39946..d137e817c 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -199,8 +199,7 @@ namespace ignition /// \return True if successful /// \sa LoadConfig /// \sa LoadPlugin - // FIXME: this should be private and CreateMainWindow public - public: bool InitializeMainWindow(); + private: bool InitializeMainWindow(); /// \brief Create individual dialogs for all previously loaded plugins. /// This has no effect if no plugins have been loaded. From a28a25e5afa658cc0b5c985236b7cc2d2eb741f7 Mon Sep 17 00:00:00 2001 From: Louise Poubel Date: Fri, 27 May 2022 12:15:29 -0700 Subject: [PATCH 07/40] Example running a dialog before the main window Signed-off-by: Louise Poubel --- include/ignition/gui/Application.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index d137e817c..dc0f39946 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -199,7 +199,8 @@ namespace ignition /// \return True if successful /// \sa LoadConfig /// \sa LoadPlugin - private: bool InitializeMainWindow(); + // FIXME: this should be private and CreateMainWindow public + public: bool InitializeMainWindow(); /// \brief Create individual dialogs for all previously loaded plugins. /// This has no effect if no plugins have been loaded. From 0dc0221b7ae3061dd1deb1b8208600abf554bd28 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 22 Jun 2022 08:59:51 +0200 Subject: [PATCH 08/40] convert createMainWindow to public Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index dc0f39946..d137e817c 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -199,8 +199,7 @@ namespace ignition /// \return True if successful /// \sa LoadConfig /// \sa LoadPlugin - // FIXME: this should be private and CreateMainWindow public - public: bool InitializeMainWindow(); + private: bool InitializeMainWindow(); /// \brief Create individual dialogs for all previously loaded plugins. /// This has no effect if no plugins have been loaded. From 38b96e228b3ad5cc11d1c30b90784c4319fd8623 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 22 Jun 2022 09:45:18 +0200 Subject: [PATCH 09/40] add quick start test in windowConfig Signed-off-by: Mohamad --- src/MainWindow_TEST.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/MainWindow_TEST.cc b/src/MainWindow_TEST.cc index d5486d5e7..0e0fb88c0 100644 --- a/src/MainWindow_TEST.cc +++ b/src/MainWindow_TEST.cc @@ -222,6 +222,7 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(defaultValues)) EXPECT_TRUE(c.showDrawer); EXPECT_TRUE(c.showDefaultDrawerOpts); EXPECT_TRUE(c.showPluginMenu); + EXPECT_TRUE(c.showDefaultQuickStartOpts); EXPECT_TRUE(c.pluginsFromPaths); EXPECT_TRUE(c.showPlugins.empty()); EXPECT_TRUE(c.ignoredProps.empty()); @@ -236,6 +237,7 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(defaultValues)) EXPECT_NE(xml.find(""), std::string::npos); EXPECT_NE(xml.find(""), std::string::npos); } @@ -255,7 +257,8 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(mergeFromXML)) // Merge from XML c.MergeFromXML(std::string("5000")+ - "" + + "" + + "" + "size"); // Check values @@ -270,6 +273,7 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(mergeFromXML)) EXPECT_TRUE(c.showDrawer); EXPECT_TRUE(c.showDefaultDrawerOpts); EXPECT_TRUE(c.showPluginMenu); + EXPECT_FALSE(c.showDefaultQuickStartOpts); EXPECT_FALSE(c.pluginsFromPaths); EXPECT_TRUE(c.showPlugins.empty()); EXPECT_EQ(c.ignoredProps.size(), 2u); From 85c9b516c1f340c346703e82605496bd30c62a09 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 22 Jun 2022 12:25:35 +0200 Subject: [PATCH 10/40] fix quick start test case Signed-off-by: Mohamad --- src/MainWindow_TEST.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MainWindow_TEST.cc b/src/MainWindow_TEST.cc index 0e0fb88c0..496cff8e4 100644 --- a/src/MainWindow_TEST.cc +++ b/src/MainWindow_TEST.cc @@ -237,7 +237,7 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(defaultValues)) EXPECT_NE(xml.find(""), std::string::npos); EXPECT_NE(xml.find(""), std::string::npos); } @@ -257,7 +257,7 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(mergeFromXML)) // Merge from XML c.MergeFromXML(std::string("5000")+ - "" + + "" + "" + "size"); From 54b6062beb384ca17a2a1fb91872a5f7aa123720 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 22 Jun 2022 13:05:19 +0200 Subject: [PATCH 11/40] fixing cmdLine test error on linux Signed-off-by: Mohamad --- src/ign_TEST.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index cf3ba5ea7..cbfdee42c 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -84,6 +84,8 @@ class CmdLine : public ::testing::Test // See https://github.com/ignitionrobotics/ign-gui/issues/75 TEST_F(CmdLine, IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(list)) { + EXPECT_TRUE(common::exists(this->kFakeHome)); + // Clear home if it exists common::removeAll(this->kFakeHome); From 75c9feb9af6205c7e8b77f18f17d57b507817041 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 22 Jun 2022 15:24:57 +0200 Subject: [PATCH 12/40] remove fixme from quick start example Signed-off-by: Mohamad --- examples/standalone/start_dialog/start_dialog.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/standalone/start_dialog/start_dialog.cc b/examples/standalone/start_dialog/start_dialog.cc index 7bbc47633..3ef1b7d43 100644 --- a/examples/standalone/start_dialog/start_dialog.cc +++ b/examples/standalone/start_dialog/start_dialog.cc @@ -78,9 +78,7 @@ int main(int _argc, char **_argv) igndbg << "Dialog closed, open main window" << std::endl; // Create main window - // FIXME: use CreateMainWindow - currently complains with undefined reference - //app.CreateMainWindow(); - app.InitializeMainWindow(); + app.CreateMainWindow(); // Run main window app.exec(); From bbfa2e05a709f8c37e0bb7ff6d3127f122c9f154 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 23 Jun 2022 12:36:24 +0200 Subject: [PATCH 13/40] comment out cmdline list remove dir test Signed-off-by: Mohamad --- src/ign_TEST.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index cbfdee42c..e940e0cb8 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -84,12 +84,10 @@ class CmdLine : public ::testing::Test // See https://github.com/ignitionrobotics/ign-gui/issues/75 TEST_F(CmdLine, IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(list)) { - EXPECT_TRUE(common::exists(this->kFakeHome)); - // Clear home if it exists common::removeAll(this->kFakeHome); - EXPECT_FALSE(common::exists(this->kFakeHome)); + // EXPECT_FALSE(common::exists(this->kFakeHome)); std::string output = custom_exec_str("ign gui -l"); EXPECT_NE(output.find("TopicEcho"), std::string::npos) << output; From 055617f6ce49f1c6ad1d6fef1dcfc969bd51b58d Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 23 Jun 2022 16:36:00 +0200 Subject: [PATCH 14/40] add load window config test Signed-off-by: Mohamad --- src/Application_TEST.cc | 52 ++++++++++++++++++++++++++++++++++++++++- src/MainWindow_TEST.cc | 1 + 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Application_TEST.cc b/src/Application_TEST.cc index 0ebc5c187..690acf77d 100644 --- a/src/Application_TEST.cc +++ b/src/Application_TEST.cc @@ -196,6 +196,56 @@ TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadConfig)) } } +////////////////////////////////////////////////// +TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadWindowConfig)) +{ + ignition::common::Console::SetVerbosity(4); + + EXPECT_EQ(nullptr, qGuiApp); + + // Empty string + { + Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); + + EXPECT_FALSE(app.LoadWindowConfig("")); + } + + // Test config file + { + Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); + + // Add test plugin to path (referenced in config) + auto testBuildPath = std::string(PROJECT_BINARY_PATH) + "/lib/"; + app.AddPluginPath(testBuildPath); + + // Load test config file + auto testSourcePath = std::string(PROJECT_SOURCE_PATH) + "/test/"; + EXPECT_TRUE(app.LoadWindowConfig(testSourcePath + "config/test.config")); + } + + // Test environment variable and relative path + { + // Environment variable not set + Application app(g_argc, g_argv); + EXPECT_FALSE(app.LoadWindowConfig("ignore.config")); + + // Invalid path + setenv("GZ_GUI_RESOURCE_PATH", "invalidPath", 1); + EXPECT_FALSE(app.LoadWindowConfig("ignore.config")); + + // Valid path + setenv("GZ_GUI_RESOURCE_PATH", + (std::string(PROJECT_SOURCE_PATH) + "/test/config").c_str(), 1); + EXPECT_TRUE(app.LoadWindowConfig("ignore.config")); + + // Multiple paths, one valid + setenv("GZ_GUI_RESOURCE_PATH", + ("banana:" + std::string(PROJECT_SOURCE_PATH) + "/test/config" + + ":orange").c_str(), 1); + EXPECT_TRUE(app.LoadWindowConfig("ignore.config")); + } +} + ////////////////////////////////////////////////// TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadDefaultConfig)) { @@ -222,7 +272,7 @@ TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadDefaultConfig)) } ////////////////////////////////////////////////// -TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(InitializeMainWindow)) +TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(CreateMainWindow)) { ignition::common::Console::SetVerbosity(4); diff --git a/src/MainWindow_TEST.cc b/src/MainWindow_TEST.cc index 496cff8e4..9232fe21b 100644 --- a/src/MainWindow_TEST.cc +++ b/src/MainWindow_TEST.cc @@ -727,6 +727,7 @@ TEST(MainWindowTest, IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(ApplyConfig)) auto c = mainWindow->CurrentWindowConfig(); EXPECT_TRUE(c.showDrawer); EXPECT_TRUE(c.showDefaultDrawerOpts); + EXPECT_TRUE(c.showDefaultQuickStartOpts); EXPECT_TRUE(c.showPluginMenu); EXPECT_TRUE(c.pluginsFromPaths); EXPECT_TRUE(c.showPlugins.empty()); From b498ad9f7a17fa663ba72948290eb69c203e8117 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 23 Jun 2022 17:06:54 +0200 Subject: [PATCH 15/40] show quick start menu test added Signed-off-by: Mohamad --- src/Application_TEST.cc | 27 ++++----------------------- test/config/test.config | 3 +++ 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/Application_TEST.cc b/src/Application_TEST.cc index 690acf77d..a36cc7913 100644 --- a/src/Application_TEST.cc +++ b/src/Application_TEST.cc @@ -214,35 +214,16 @@ TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadWindowConfig)) { Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); - // Add test plugin to path (referenced in config) - auto testBuildPath = std::string(PROJECT_BINARY_PATH) + "/lib/"; - app.AddPluginPath(testBuildPath); - // Load test config file auto testSourcePath = std::string(PROJECT_SOURCE_PATH) + "/test/"; EXPECT_TRUE(app.LoadWindowConfig(testSourcePath + "config/test.config")); } - // Test environment variable and relative path + // Test getting default show quick start menu { - // Environment variable not set - Application app(g_argc, g_argv); - EXPECT_FALSE(app.LoadWindowConfig("ignore.config")); - - // Invalid path - setenv("GZ_GUI_RESOURCE_PATH", "invalidPath", 1); - EXPECT_FALSE(app.LoadWindowConfig("ignore.config")); - - // Valid path - setenv("GZ_GUI_RESOURCE_PATH", - (std::string(PROJECT_SOURCE_PATH) + "/test/config").c_str(), 1); - EXPECT_TRUE(app.LoadWindowConfig("ignore.config")); - - // Multiple paths, one valid - setenv("GZ_GUI_RESOURCE_PATH", - ("banana:" + std::string(PROJECT_SOURCE_PATH) + "/test/config" + - ":orange").c_str(), 1); - EXPECT_TRUE(app.LoadWindowConfig("ignore.config")); + EXPECT_TRUE(app.ShowQuickStart()); + app.SetShowDefaultQuickStartOpts(false); + EXPECT_FALSE(app.ShowQuickStart()); } } diff --git a/test/config/test.config b/test/config/test.config index dd3b76e65..b9260fabb 100644 --- a/test/config/test.config +++ b/test/config/test.config @@ -2,6 +2,9 @@ false + + + From c4b8bda9bee3487d946a32ef9b56e6ae71f661a5 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 23 Jun 2022 17:15:08 +0200 Subject: [PATCH 16/40] fix quick start test Signed-off-by: Mohamad --- src/Application_TEST.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Application_TEST.cc b/src/Application_TEST.cc index a36cc7913..5fb54fdf1 100644 --- a/src/Application_TEST.cc +++ b/src/Application_TEST.cc @@ -221,6 +221,11 @@ TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadWindowConfig)) // Test getting default show quick start menu { + Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); + + // Load test config file + auto testSourcePath = std::string(PROJECT_SOURCE_PATH) + "/test/"; + EXPECT_TRUE(app.LoadWindowConfig(testSourcePath + "config/test.config")); EXPECT_TRUE(app.ShowQuickStart()); app.SetShowDefaultQuickStartOpts(false); EXPECT_FALSE(app.ShowQuickStart()); From 29879fc894d03f281671f5fe3648709d4846f0b1 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Mon, 27 Jun 2022 20:16:16 +0200 Subject: [PATCH 17/40] allow dialogs to read and write configs Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 5 + include/ignition/gui/Dialog.hh | 38 +++++ include/ignition/gui/MainWindow.hh | 6 + src/Application.cc | 7 + src/Dialog.cc | 218 ++++++++++++++++++++++++++++ src/MainWindow.cc | 7 +- 6 files changed, 280 insertions(+), 1 deletion(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index d137e817c..18c6f330c 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -193,6 +193,11 @@ namespace ignition /// \sa InitializeMainWindow public: bool CreateMainWindow(); + // /// \brief . + // /// \return True if successful, will fail if there's no main window + // /// initialized. + // public: bool ApplyPreMainWindowConfig(bool _showQuickStartMenu const); + /// \brief Create a main window, populate with previously loaded plugins /// and apply previously loaded configuration. /// An empty window will be created if no plugins have been loaded. diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index 5da748d42..188232a96 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -19,6 +19,7 @@ #define IGNITION_GUI_DIALOG_HH_ #include +#include #include "ignition/gui/qt.h" #include "ignition/gui/Export.hh" @@ -55,6 +56,43 @@ namespace ignition /// \return Pointer to the item public: QQuickItem *RootItem() const; + /// \brief Set dilaog name + public: void SetName(const std::string &_name); + + /// \brief Store dialog default config + /// \param[in] _config XML config as string + public: void SetDefaultConfig(const std::string &_config); + + /// \brief Write dialog config + /// \param[in] _path config path + /// \param[in] _attribute XMLElement attribute name + /// \param[in] _attribute XMLElement attribute value + /// \return true if written to config file + public: bool WriteAttribute(const std::string &_path, + const std::string &_attribute, const std::string &_value = "") const; + + /// \brief Write dialog config + /// \param[in] _path config path + /// \param[in] _attribute XMLElement attribute name + /// \param[in] _value XMLElement attribute value + /// \return true if written to config file + public: bool WriteAttribute(const std::string &_path, + const std::string &_attribute, const bool _value = false) const; + + /// \brief Gets a config attribute value, if not found in config + /// \brief write the default in the config and get it. + /// \brief creates config file if it doesn't exist. + /// \param[in] _path config path + /// \param[in] _attribute attribute name + /// \return attribute value as string + public: std::string ReadAttribute(const std::string &_path, const std::string &_attribute) const; + + /// \brief Gets a config attribute value + /// \param[in] _path config path + /// \param[in] _attribute attribute name + /// \return attribute value as string + private: bool SaveConfig(const char *_config, const std::string &_path); + /// \internal /// \brief Private data pointer private: std::unique_ptr dataPtr; diff --git a/include/ignition/gui/MainWindow.hh b/include/ignition/gui/MainWindow.hh index 9f20be73c..1d83254f5 100644 --- a/include/ignition/gui/MainWindow.hh +++ b/include/ignition/gui/MainWindow.hh @@ -611,6 +611,12 @@ namespace ignition public: void SetShowDefaultQuickStartOpts( const bool _showDefaultQuickStartOpts); + // /// \brief Apply a WindowConfig to current appliaction and keep a + // /// \brief copy of it. + // /// \param[in] _config The configuration to apply. + // /// \return True if successful. + // public: bool ApplyConfig(const bool _showQuikStart); + /// \brief Window X position in px int posX{-1}; diff --git a/src/Application.cc b/src/Application.cc index dc0536756..803e2855b 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -650,6 +650,13 @@ bool Application::ApplyConfig() return this->dataPtr->mainWin->ApplyConfig(this->dataPtr->windowConfig); } +// ///////////////////////////////////////////////// +// bool Application::ApplyPreMainWindowConfig(bool _showQuickStart) +// { +// this->dataPtr->windowConfig->ApplyConfig(_showQuickStart); +// return true; +// } + ///////////////////////////////////////////////// bool Application::AddPluginsToWindow() { diff --git a/src/Dialog.cc b/src/Dialog.cc index 7463a7394..58d378d55 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -25,6 +25,12 @@ namespace ignition { class DialogPrivate { + /// \brief Dialog name in config + public: std::string name{""}; + + /// \brief default dialog config + public: std::string config{""}; + /// \brief Pointer to quick window public: QQuickWindow *quickWindow{nullptr}; }; @@ -75,3 +81,215 @@ QQuickItem *Dialog::RootItem() const return dialogItem; } +///////////////////////////////////////////////// +void Dialog::SetName(const std::string &_name) +{ + this->dataPtr->name = _name; +} + +///////////////////////////////////////////////// +bool Dialog::SaveConfig(const char *_config, const std::string &_path) +{ + // Write config file + std::ofstream out(_path.c_str(), std::ios::out); + if (!out) + { + std::string str = "Unable to open file: " + _path; + str += ".\nCheck file permissions."; + return false; + } + else + out << _config; + + return true; +} + +///////////////////////////////////////////////// +bool Dialog::WriteAttribute(const std::string &_path, + const std::string &_attribute, const std::string &_value) const +{ + if (_path.empty()) + { + ignerr << "Missing config file" << std::endl; + return false; + } + + std::string configFull = _path; + + // Use tinyxml to read config + tinyxml2::XMLDocument doc; + auto success = !doc.LoadFile(configFull.c_str()); + if (!success) + { + ignerr << "Failed to load file [" << configFull << "]: XMLError" + << std::endl; + return false; + } + + // Update attribute value for the correct dialog + for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) + { + if(dialogElem->Attribute("name") == this->dataPtr->name) + { + dialogElem->SetAttribute(_attribute.c_str(), _value.c_str()); + } + } + + // Write config file + tinyxml2::XMLPrinter printer; + doc.Print(&printer); + + std::string config = printer.CStr(); + std::ofstream out(_path.c_str(), std::ios::out); + if (!out) + { + std::string str = "Unable to open file: " + _path; + str += ".\nCheck file permissions."; + } + else + out << config; + + return true; +} + +///////////////////////////////////////////////// +bool Dialog::WriteAttribute(const std::string &_path, + const std::string &_attribute, const bool _value) const +{ + if (_path.empty()) + { + ignerr << "Missing config file" << std::endl; + return false; + } + + std::string configFull = _path; + + // Use tinyxml to read config + tinyxml2::XMLDocument doc; + auto success = !doc.LoadFile(configFull.c_str()); + if (!success) + { + ignerr << "Failed to load file [" << configFull << "]: XMLError" + << std::endl; + return false; + } + + // Update attribute value for the correct dialog + for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) + { + if(dialogElem->Attribute("name") == this->dataPtr->name) + { + dialogElem->SetAttribute(_attribute.c_str(), _value); + } + } + + // Write config file + tinyxml2::XMLPrinter printer; + doc.Print(&printer); + + std::string config = printer.CStr(); + std::ofstream out(_path.c_str(), std::ios::out); + if (!out) + { + std::string str = "Unable to open file: " + _path; + str += ".\nCheck file permissions."; + } + else + out << config; + + return true; +} + +///////////////////////////////////////////////// +void Dialog::SetDefaultConfig(const std::string &_config) +{ + this->dataPtr->config = _config; +} + +///////////////////////////////////////////////// +std::string Dialog::ReadAttribute(const std::string &_path, + const std::string &_attribute) const +{ + tinyxml2::XMLDocument doc; + std::string value {""}; + std::string config = "\n\n"; + tinyxml2::XMLPrinter defaultPrinter; + bool configExists{true}; + + // Check if the passed in config file exists. + // (If the default config path doesn't exist yet, it's expected behavior. + // It will be created the first time now.) + if (!common::exists(_path)) + { + configExists = false; + doc.Parse(this->dataPtr->config.c_str()); + // Process each dialog + for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) + { + if(dialogElem->Attribute("name") == this->dataPtr->name) + { + value = dialogElem->Attribute(_attribute.c_str()); + } + } + } + else + { + auto success = !doc.LoadFile(_path.c_str()); + if (!success) + { + return ""; + } + + // Process each dialog + for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) + { + if(dialogElem->Attribute("name") == this->dataPtr->name) + { + value = dialogElem->Attribute(_attribute.c_str()); + } + } + + // config exists but attribute not there + if (value.empty()) + { + tinyxml2::XMLDocument missingDoc; + missingDoc.Parse(this->dataPtr->config.c_str()); + + for (auto dialogElem = missingDoc.FirstChildElement("dialog"); dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) + { + if(dialogElem->Attribute("name") == this->dataPtr->name) + { + value = dialogElem->Attribute(_attribute.c_str()); + } + } + + missingDoc.Print(&defaultPrinter); + } + } + + // Write config file + tinyxml2::XMLPrinter printer; + doc.Print(&printer); + + // Don't write the xml version decleration if file exists + if (configExists){ + config = ""; + } + config += printer.CStr(); + config += defaultPrinter.CStr(); + std::ofstream out(_path.c_str(), std::ios::out); + if (!out) + { + std::string str = "Unable to open file: " + _path; + str += ".\nCheck file permissions."; + } + else + out << config; + + return value; +} diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 293a3daa7..61c31371d 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -271,7 +271,6 @@ void MainWindow::OnAddPlugin(QString _plugin) App()->LoadPlugin(plugin); } - /////////////////////////////////////////////////// bool MainWindow::ApplyConfig(const WindowConfig &_config) { @@ -737,6 +736,12 @@ bool WindowConfig::IsIgnoring(const std::string &_prop) const return this->ignoredProps.find(_prop) != this->ignoredProps.end(); } +// /////////////////////////////////////////////////// +// bool WindowConfig::ApplyConfig() +// { +// this->SetShowDefaultQuickStartOpts(_config.ShowDefaultQuickStartOpts()); +// } + ///////////////////////////////////////////////// int MainWindow::PluginCount() const { From 4e3c70537c692e63bb575a2f31d3ca9f443320da Mon Sep 17 00:00:00 2001 From: Mohamad Date: Mon, 27 Jun 2022 23:10:16 +0200 Subject: [PATCH 18/40] codecheck Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 5 ----- include/ignition/gui/Dialog.hh | 20 +++++++++++--------- include/ignition/gui/MainWindow.hh | 6 ------ src/Application.cc | 7 ------- src/Dialog.cc | 25 ++++++++++++++++--------- src/MainWindow.cc | 6 ------ 6 files changed, 27 insertions(+), 42 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index 18c6f330c..d137e817c 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -193,11 +193,6 @@ namespace ignition /// \sa InitializeMainWindow public: bool CreateMainWindow(); - // /// \brief . - // /// \return True if successful, will fail if there's no main window - // /// initialized. - // public: bool ApplyPreMainWindowConfig(bool _showQuickStartMenu const); - /// \brief Create a main window, populate with previously loaded plugins /// and apply previously loaded configuration. /// An empty window will be created if no plugins have been loaded. diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index 188232a96..f8f586a1e 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -20,6 +20,7 @@ #include #include +#include #include "ignition/gui/qt.h" #include "ignition/gui/Export.hh" @@ -66,18 +67,18 @@ namespace ignition /// \brief Write dialog config /// \param[in] _path config path /// \param[in] _attribute XMLElement attribute name - /// \param[in] _attribute XMLElement attribute value + /// \param[in] _attribute XMLElement attribute string value /// \return true if written to config file public: bool WriteAttribute(const std::string &_path, - const std::string &_attribute, const std::string &_value = "") const; + const std::string &_attribute, const std::string &_value) const; /// \brief Write dialog config /// \param[in] _path config path /// \param[in] _attribute XMLElement attribute name - /// \param[in] _value XMLElement attribute value + /// \param[in] _value XMLElement attribute boolean value /// \return true if written to config file public: bool WriteAttribute(const std::string &_path, - const std::string &_attribute, const bool _value = false) const; + const std::string &_attribute, const bool _value) const; /// \brief Gets a config attribute value, if not found in config /// \brief write the default in the config and get it. @@ -85,12 +86,13 @@ namespace ignition /// \param[in] _path config path /// \param[in] _attribute attribute name /// \return attribute value as string - public: std::string ReadAttribute(const std::string &_path, const std::string &_attribute) const; + public: std::string ReadAttribute(const std::string &_path, + const std::string &_attribute) const; - /// \brief Gets a config attribute value - /// \param[in] _path config path - /// \param[in] _attribute attribute name - /// \return attribute value as string + /// \brief Write config to path + /// \param[in] _config config as char array + /// \param[in] _path of the config + /// \return true if written private: bool SaveConfig(const char *_config, const std::string &_path); /// \internal diff --git a/include/ignition/gui/MainWindow.hh b/include/ignition/gui/MainWindow.hh index 1d83254f5..9f20be73c 100644 --- a/include/ignition/gui/MainWindow.hh +++ b/include/ignition/gui/MainWindow.hh @@ -611,12 +611,6 @@ namespace ignition public: void SetShowDefaultQuickStartOpts( const bool _showDefaultQuickStartOpts); - // /// \brief Apply a WindowConfig to current appliaction and keep a - // /// \brief copy of it. - // /// \param[in] _config The configuration to apply. - // /// \return True if successful. - // public: bool ApplyConfig(const bool _showQuikStart); - /// \brief Window X position in px int posX{-1}; diff --git a/src/Application.cc b/src/Application.cc index 803e2855b..dc0536756 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -650,13 +650,6 @@ bool Application::ApplyConfig() return this->dataPtr->mainWin->ApplyConfig(this->dataPtr->windowConfig); } -// ///////////////////////////////////////////////// -// bool Application::ApplyPreMainWindowConfig(bool _showQuickStart) -// { -// this->dataPtr->windowConfig->ApplyConfig(_showQuickStart); -// return true; -// } - ///////////////////////////////////////////////// bool Application::AddPluginsToWindow() { diff --git a/src/Dialog.cc b/src/Dialog.cc index 58d378d55..c1e8ca45b 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -127,7 +127,8 @@ bool Dialog::WriteAttribute(const std::string &_path, } // Update attribute value for the correct dialog - for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; + for (auto dialogElem = doc.FirstChildElement("dialog"); + dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) { if(dialogElem->Attribute("name") == this->dataPtr->name) @@ -176,7 +177,8 @@ bool Dialog::WriteAttribute(const std::string &_path, } // Update attribute value for the correct dialog - for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; + for (auto dialogElem = doc.FirstChildElement("dialog"); + dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) { if(dialogElem->Attribute("name") == this->dataPtr->name) @@ -226,8 +228,9 @@ std::string Dialog::ReadAttribute(const std::string &_path, configExists = false; doc.Parse(this->dataPtr->config.c_str()); // Process each dialog - for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) + for (auto dialogElem = doc.FirstChildElement("dialog"); + dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) { if(dialogElem->Attribute("name") == this->dataPtr->name) { @@ -244,8 +247,9 @@ std::string Dialog::ReadAttribute(const std::string &_path, } // Process each dialog - for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) + for (auto dialogElem = doc.FirstChildElement("dialog"); + dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) { if(dialogElem->Attribute("name") == this->dataPtr->name) { @@ -259,8 +263,9 @@ std::string Dialog::ReadAttribute(const std::string &_path, tinyxml2::XMLDocument missingDoc; missingDoc.Parse(this->dataPtr->config.c_str()); - for (auto dialogElem = missingDoc.FirstChildElement("dialog"); dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) + for (auto dialogElem = doc.FirstChildElement("dialog"); + dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) { if(dialogElem->Attribute("name") == this->dataPtr->name) { @@ -287,9 +292,11 @@ std::string Dialog::ReadAttribute(const std::string &_path, { std::string str = "Unable to open file: " + _path; str += ".\nCheck file permissions."; + igndbg << str << std::endl; + return ""; } else out << config; - + return value; } diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 61c31371d..42091e704 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -736,12 +736,6 @@ bool WindowConfig::IsIgnoring(const std::string &_prop) const return this->ignoredProps.find(_prop) != this->ignoredProps.end(); } -// /////////////////////////////////////////////////// -// bool WindowConfig::ApplyConfig() -// { -// this->SetShowDefaultQuickStartOpts(_config.ShowDefaultQuickStartOpts()); -// } - ///////////////////////////////////////////////// int MainWindow::PluginCount() const { From 3b2c8ec51302cbebb08f99bc96953bdc15178543 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 10:00:58 +0200 Subject: [PATCH 19/40] code check Signed-off-by: Mohamad --- include/ignition/gui/Dialog.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index f8f586a1e..729f39144 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -67,7 +67,7 @@ namespace ignition /// \brief Write dialog config /// \param[in] _path config path /// \param[in] _attribute XMLElement attribute name - /// \param[in] _attribute XMLElement attribute string value + /// \param[in] _value XMLElement attribute string value /// \return true if written to config file public: bool WriteAttribute(const std::string &_path, const std::string &_attribute, const std::string &_value) const; From bb08ad35dd4277a1b3e3bd342e71dd9c9ad4cd62 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 11:05:54 +0200 Subject: [PATCH 20/40] uncomment cmdline test Signed-off-by: Mohamad --- src/ign_TEST.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index e940e0cb8..cf3ba5ea7 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -87,7 +87,7 @@ TEST_F(CmdLine, IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(list)) // Clear home if it exists common::removeAll(this->kFakeHome); - // EXPECT_FALSE(common::exists(this->kFakeHome)); + EXPECT_FALSE(common::exists(this->kFakeHome)); std::string output = custom_exec_str("ign gui -l"); EXPECT_NE(output.find("TopicEcho"), std::string::npos) << output; From f6a59739b0a181b0c6956f0391345af390a70044 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 14:34:16 +0200 Subject: [PATCH 21/40] remove old write quick start config imp Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 11 -------- include/ignition/gui/MainWindow.hh | 12 --------- src/Application.cc | 14 ----------- src/Application_TEST.cc | 36 -------------------------- src/MainWindow.cc | 39 ----------------------------- 5 files changed, 112 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index d137e817c..81cf221ad 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -131,17 +131,6 @@ namespace ignition /// \sa SetDefaultConfigPath public: std::string DefaultConfigPath(); - /// \brief Show quick Start menu or not - /// \return True if quick Start menu is configured to be shown - /// before main window - /// initialized. - public: bool ShowQuickStart() const; - - /// \brief Set the flag to show the quick start menu's default options. - /// \param[in] _showDefaultQuickStartOpts True to show. - public: void SetShowDefaultQuickStartOpts( - const bool _showDefaultQuickStartOpts) const; - /// \brief Set the environment variable which defines the paths to /// look for plugins. /// \param[in] _env Name of environment variable. diff --git a/include/ignition/gui/MainWindow.hh b/include/ignition/gui/MainWindow.hh index 9f20be73c..9f3cd5e33 100644 --- a/include/ignition/gui/MainWindow.hh +++ b/include/ignition/gui/MainWindow.hh @@ -602,15 +602,6 @@ namespace ignition /// \return True if it's being ignored bool IsIgnoring(const std::string &_prop) const; - /// \brief Get the flag to show the quick start menu's default options. - /// \return True to show. - public: bool ShowDefaultQuickStartOpts() const; - - /// \brief Set the flag to show the quick start menu's default options. - /// \param[in] _showDefaultQuickStartOpts True to show. - public: void SetShowDefaultQuickStartOpts( - const bool _showDefaultQuickStartOpts); - /// \brief Window X position in px int posX{-1}; @@ -665,9 +656,6 @@ namespace ignition /// \brief Show the default options of the drawer bool showDefaultDrawerOpts{true}; - /// \brief Show the default options of the quick Start menu - bool showDefaultQuickStartOpts{true}; - /// \brief Show the plugins menu bool showPluginMenu{true}; diff --git a/src/Application.cc b/src/Application.cc index dc0536756..b581730d7 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -215,20 +215,6 @@ bool Application::RemovePlugin(const std::string &_pluginName) return true; } -///////////////////////////////////////////////// -bool Application::ShowQuickStart() const -{ - return this->dataPtr->windowConfig.ShowDefaultQuickStartOpts(); -} - -///////////////////////////////////////////////// -void Application::SetShowDefaultQuickStartOpts( - const bool _showDefaultQuickStartOpts) const -{ - return this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts( - _showDefaultQuickStartOpts); -} - ///////////////////////////////////////////////// bool Application::LoadWindowConfig(const std::string &_config) { diff --git a/src/Application_TEST.cc b/src/Application_TEST.cc index 5fb54fdf1..c0ac12728 100644 --- a/src/Application_TEST.cc +++ b/src/Application_TEST.cc @@ -196,42 +196,6 @@ TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadConfig)) } } -////////////////////////////////////////////////// -TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadWindowConfig)) -{ - ignition::common::Console::SetVerbosity(4); - - EXPECT_EQ(nullptr, qGuiApp); - - // Empty string - { - Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); - - EXPECT_FALSE(app.LoadWindowConfig("")); - } - - // Test config file - { - Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); - - // Load test config file - auto testSourcePath = std::string(PROJECT_SOURCE_PATH) + "/test/"; - EXPECT_TRUE(app.LoadWindowConfig(testSourcePath + "config/test.config")); - } - - // Test getting default show quick start menu - { - Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); - - // Load test config file - auto testSourcePath = std::string(PROJECT_SOURCE_PATH) + "/test/"; - EXPECT_TRUE(app.LoadWindowConfig(testSourcePath + "config/test.config")); - EXPECT_TRUE(app.ShowQuickStart()); - app.SetShowDefaultQuickStartOpts(false); - EXPECT_FALSE(app.ShowQuickStart()); - } -} - ////////////////////////////////////////////////// TEST(ApplicationTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(LoadDefaultConfig)) { diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 42091e704..cfe4dd9d9 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -330,8 +330,6 @@ bool MainWindow::ApplyConfig(const WindowConfig &_config) // Menus this->SetShowDrawer(_config.showDrawer); this->SetShowDefaultDrawerOpts(_config.showDefaultDrawerOpts); - this->dataPtr->windowConfig.SetShowDefaultQuickStartOpts( - _config.showDefaultQuickStartOpts); this->SetShowPluginMenu(_config.showPluginMenu); // Keep a copy @@ -384,8 +382,6 @@ WindowConfig MainWindow::CurrentWindowConfig() const config.showDrawer = this->dataPtr->windowConfig.showDrawer; config.showDefaultDrawerOpts = this->dataPtr->windowConfig.showDefaultDrawerOpts; - config.showDefaultQuickStartOpts = - this->dataPtr->windowConfig.showDefaultQuickStartOpts; config.showPluginMenu = this->dataPtr->windowConfig.showPluginMenu; config.pluginsFromPaths = this->dataPtr->windowConfig.pluginsFromPaths; config.showPlugins = this->dataPtr->windowConfig.showPlugins; @@ -517,18 +513,6 @@ bool WindowConfig::MergeFromXML(const std::string &_windowXml) } } - // QuickStart - if (auto quickStartElem = menusElem->FirstChildElement("quick_start")) - { - // Default - if (quickStartElem->Attribute("default")) - { - bool def = true; - quickStartElem->QueryBoolAttribute("default", &def); - this->showDefaultQuickStartOpts = def; - } - } - // Plugins if (auto pluginsElem = menusElem->FirstChildElement("plugins")) { @@ -663,16 +647,6 @@ std::string WindowConfig::XMLString() const menusElem->InsertEndChild(elem); } - // Quick Start - { - auto elem = doc.NewElement("quick_start"); - - // Default - elem->SetAttribute("default", this->showDefaultQuickStartOpts); - - menusElem->InsertEndChild(elem); - } - // Plugins { auto elem = doc.NewElement("plugins"); @@ -717,19 +691,6 @@ std::string WindowConfig::XMLString() const return config; } -///////////////////////////////////////////////// -bool WindowConfig::ShowDefaultQuickStartOpts() const -{ - return this->showDefaultQuickStartOpts; -} - -///////////////////////////////////////////////// -void WindowConfig::SetShowDefaultQuickStartOpts( - const bool _showDefaultQuickStartOpts) -{ - this->showDefaultQuickStartOpts = _showDefaultQuickStartOpts; -} - ///////////////////////////////////////////////// bool WindowConfig::IsIgnoring(const std::string &_prop) const { From 80a8e54e49cf5834ddbc6d12f6872918c80d0bbc Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 14:41:29 +0200 Subject: [PATCH 22/40] remove old write quick start config test Signed-off-by: Mohamad --- src/MainWindow_TEST.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/MainWindow_TEST.cc b/src/MainWindow_TEST.cc index 9232fe21b..5162fc38c 100644 --- a/src/MainWindow_TEST.cc +++ b/src/MainWindow_TEST.cc @@ -222,7 +222,6 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(defaultValues)) EXPECT_TRUE(c.showDrawer); EXPECT_TRUE(c.showDefaultDrawerOpts); EXPECT_TRUE(c.showPluginMenu); - EXPECT_TRUE(c.showDefaultQuickStartOpts); EXPECT_TRUE(c.pluginsFromPaths); EXPECT_TRUE(c.showPlugins.empty()); EXPECT_TRUE(c.ignoredProps.empty()); @@ -273,7 +272,6 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(mergeFromXML)) EXPECT_TRUE(c.showDrawer); EXPECT_TRUE(c.showDefaultDrawerOpts); EXPECT_TRUE(c.showPluginMenu); - EXPECT_FALSE(c.showDefaultQuickStartOpts); EXPECT_FALSE(c.pluginsFromPaths); EXPECT_TRUE(c.showPlugins.empty()); EXPECT_EQ(c.ignoredProps.size(), 2u); @@ -727,7 +725,6 @@ TEST(MainWindowTest, IGN_UTILS_TEST_ENABLED_ONLY_ON_LINUX(ApplyConfig)) auto c = mainWindow->CurrentWindowConfig(); EXPECT_TRUE(c.showDrawer); EXPECT_TRUE(c.showDefaultDrawerOpts); - EXPECT_TRUE(c.showDefaultQuickStartOpts); EXPECT_TRUE(c.showPluginMenu); EXPECT_TRUE(c.pluginsFromPaths); EXPECT_TRUE(c.showPlugins.empty()); From 2d6bbff6cffc2d248c88d5de5d39935db420f9ff Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 15:00:41 +0200 Subject: [PATCH 23/40] fix old quick start test Signed-off-by: Mohamad --- src/MainWindow_TEST.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/MainWindow_TEST.cc b/src/MainWindow_TEST.cc index 5162fc38c..d5486d5e7 100644 --- a/src/MainWindow_TEST.cc +++ b/src/MainWindow_TEST.cc @@ -236,7 +236,6 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(defaultValues)) EXPECT_NE(xml.find(""), std::string::npos); EXPECT_NE(xml.find(""), std::string::npos); } @@ -256,8 +255,7 @@ TEST(WindowConfigTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(mergeFromXML)) // Merge from XML c.MergeFromXML(std::string("5000")+ - "" + - "" + + "" + "size"); // Check values From b9070a1d4476eb3281c172858e6ccc4bff1bb437 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 16:11:32 +0200 Subject: [PATCH 24/40] remove old write quick start functions from application Signed-off-by: Mohamad --- include/ignition/gui/Application.hh | 5 --- src/Application.cc | 68 ----------------------------- src/MainWindow.cc | 1 + test/config/test.config | 3 -- 4 files changed, 1 insertion(+), 76 deletions(-) diff --git a/include/ignition/gui/Application.hh b/include/ignition/gui/Application.hh index 81cf221ad..0a104848b 100644 --- a/include/ignition/gui/Application.hh +++ b/include/ignition/gui/Application.hh @@ -104,11 +104,6 @@ namespace ignition /// \sa InitializeDialogs public: bool LoadConfig(const std::string &_path); - /// \brief Load a configuration file, load window configurations. - /// \param[in] _path Full path to configuration file. - /// \return True if successful - public: bool LoadWindowConfig(const std::string &_path); - /// \brief Load the configuration from the default config file. /// \return True if successful /// \sa SetDefaultConfigPath diff --git a/src/Application.cc b/src/Application.cc index b581730d7..39f063cb1 100644 --- a/src/Application.cc +++ b/src/Application.cc @@ -215,74 +215,6 @@ bool Application::RemovePlugin(const std::string &_pluginName) return true; } -///////////////////////////////////////////////// -bool Application::LoadWindowConfig(const std::string &_config) -{ - if (_config.empty()) - { - ignerr << "Missing config file" << std::endl; - return false; - } - - std::string configFull = _config; - - // Check if the passed in config file exists. - // (If the default config path doesn't exist yet, it's expected behavior. - // It will be created the first time the user presses "Save configuration".) - if (!common::exists(configFull) && (configFull != this->DefaultConfigPath())) - { - // If not, then check environment variable - std::string configPathEnv; - common::env("GZ_GUI_RESOURCE_PATH", configPathEnv); - - if (!configPathEnv.empty()) - { - std::vector parentPaths = common::Split(configPathEnv, ':'); - for (auto parentPath : parentPaths) - { - std::string tempPath = common::joinPaths(parentPath, configFull); - if (common::exists(tempPath)) - { - configFull = tempPath; - break; - } - } - } - } - - // Use tinyxml to read config - tinyxml2::XMLDocument doc; - auto success = !doc.LoadFile(configFull.c_str()); - if (!success) - { - // We do not show an error message if the default config path doesn't exist - // yet. It's expected behavior, it will be created the first time the user - // presses "Save configuration". - if (configFull != this->DefaultConfigPath()) - { - ignerr << "Failed to load file [" << configFull << "]: XMLError" - << std::endl; - } - - return false; - } - // Process window properties - if (auto winElem = doc.FirstChildElement("window")) - { - igndbg << "Loading window config" << std::endl; - - tinyxml2::XMLPrinter printer; - if (!winElem->Accept(&printer)) - { - ignwarn << "There was an error parsing the element" - << std::endl; - return false; - } - this->dataPtr->windowConfig.MergeFromXML(std::string(printer.CStr())); - } - return true; -} - ///////////////////////////////////////////////// bool Application::LoadConfig(const std::string &_config) { diff --git a/src/MainWindow.cc b/src/MainWindow.cc index cfe4dd9d9..d6157010b 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -271,6 +271,7 @@ void MainWindow::OnAddPlugin(QString _plugin) App()->LoadPlugin(plugin); } + /////////////////////////////////////////////////// bool MainWindow::ApplyConfig(const WindowConfig &_config) { diff --git a/test/config/test.config b/test/config/test.config index b9260fabb..dd3b76e65 100644 --- a/test/config/test.config +++ b/test/config/test.config @@ -2,9 +2,6 @@ false - - - From a7b1125c77f4bb199cd63117ef1ceb5750cff1e8 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 17:45:21 +0200 Subject: [PATCH 25/40] add dialog test Signed-off-by: Mohamad --- src/CMakeLists.txt | 1 + src/Dialog_TEST.cc | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/Dialog_TEST.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d1176c6e..2c3a3beeb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ set (sources set (gtest_sources Application_TEST Conversions_TEST + Dialog_TEST DragDropModel_TEST Helpers_TEST GuiEvents_TEST diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc new file mode 100644 index 000000000..8678db4f5 --- /dev/null +++ b/src/Dialog_TEST.cc @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2017 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#include + +#include + +#include +#include + +#include "test_config.h" // NOLINT(build/include) +#include "ignition/gui/Application.hh" +#include "ignition/gui/Dialog.hh" + +std::string kTestConfigFile = "/tmp/ign-gui-test.config"; // NOLINT(*) +int g_argc = 1; +char* g_argv[] = +{ + reinterpret_cast(const_cast("./Dialog_TEST")), +}; + +using namespace ignition; +using namespace gui; +using namespace std::chrono_literals; + +///////////////////////////////////////////////// +TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ReadDialogConfig)) +{ + ignition::common::Console::SetVerbosity(4); + Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); + + // Change default config path + App()->SetDefaultConfigPath(kTestConfigFile); + + auto dialog = new Dialog; + ASSERT_NE(nullptr, dialog); + + // Read dialog config + { + dialog->SetName("dialog"); + dialog->SetDefaultConfig(std::string("")); + std::string defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), + "default"); + EXPECT_TRUE(defaultValue, "true"); + } + + delete dialog; +} + +///////////////////////////////////////////////// +TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ChangeDialogConfig)) +{ + ignition::common::Console::SetVerbosity(4); + Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); + + // Change default config path + App()->SetDefaultConfigPath(kTestConfigFile); + + auto dialog = new Dialog; + ASSERT_NE(nullptr, dialog); + + // Read dialog config + { + dialog->SetName("dialog"); + dialog->SetDefaultConfig(std::string("")); + std::string defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), + "default"); + + EXPECT_TRUE(defaultValue, "true"); + dialog->WriteAttribute(app->DefaultConfigPath(), "default", + false); + defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), + "default"); + EXPECT_FALSE(defaultValue, "true"); + } + + delete dialog; +} From 48e5c22ad822aff9381f0853aa8a96937f07fec3 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 17:46:10 +0200 Subject: [PATCH 26/40] code check Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 8678db4f5..476260702 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -52,7 +52,8 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ReadDialogConfig)) // Read dialog config { dialog->SetName("dialog"); - dialog->SetDefaultConfig(std::string("")); + dialog->SetDefaultConfig(std::string( + "")); std::string defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), "default"); EXPECT_TRUE(defaultValue, "true"); @@ -76,7 +77,8 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ChangeDialogConfig)) // Read dialog config { dialog->SetName("dialog"); - dialog->SetDefaultConfig(std::string("")); + dialog->SetDefaultConfig(std::string( + "")); std::string defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), "default"); From 4bc938488438db6e903f240f7649cc83414f1cab Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 18:20:48 +0200 Subject: [PATCH 27/40] fix test Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 476260702..e8b03fa58 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -54,9 +54,9 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ReadDialogConfig)) dialog->SetName("dialog"); dialog->SetDefaultConfig(std::string( "")); - std::string defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), + std::string defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), "default"); - EXPECT_TRUE(defaultValue, "true"); + EXPECT_EQ(defaultValue, "true"); } delete dialog; @@ -79,15 +79,15 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ChangeDialogConfig)) dialog->SetName("dialog"); dialog->SetDefaultConfig(std::string( "")); - std::string defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), + std::string defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), "default"); - EXPECT_TRUE(defaultValue, "true"); + EXPECT_EQ(defaultValue, "true"); dialog->WriteAttribute(app->DefaultConfigPath(), "default", false); - defaultValue = dialog->ReadAttribute(app->DefaultConfigPath(), + defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), "default"); - EXPECT_FALSE(defaultValue, "true"); + EXPECT_EQ(defaultValue, "false"); } delete dialog; From 5031ea95f959eef6427ed1060029852839e3006e Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 18:34:28 +0200 Subject: [PATCH 28/40] fix test another compile issue Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index e8b03fa58..f576ea0b6 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -83,7 +83,7 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ChangeDialogConfig)) "default"); EXPECT_EQ(defaultValue, "true"); - dialog->WriteAttribute(app->DefaultConfigPath(), "default", + dialog->WriteAttribute(app.DefaultConfigPath(), "default", false); defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), "default"); From a0220a0e939eb9134bb9b0a1d05cf5ce191d1419 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Tue, 28 Jun 2022 19:26:03 +0200 Subject: [PATCH 29/40] remove un used function Signed-off-by: Mohamad --- src/Dialog.cc | 17 ----------------- src/Dialog_TEST.cc | 9 +++++++++ 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/Dialog.cc b/src/Dialog.cc index c1e8ca45b..3210b560a 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -87,23 +87,6 @@ void Dialog::SetName(const std::string &_name) this->dataPtr->name = _name; } -///////////////////////////////////////////////// -bool Dialog::SaveConfig(const char *_config, const std::string &_path) -{ - // Write config file - std::ofstream out(_path.c_str(), std::ios::out); - if (!out) - { - std::string str = "Unable to open file: " + _path; - str += ".\nCheck file permissions."; - return false; - } - else - out << _config; - - return true; -} - ///////////////////////////////////////////////// bool Dialog::WriteAttribute(const std::string &_path, const std::string &_attribute, const std::string &_value) const diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index f576ea0b6..93b9d9838 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -59,6 +59,15 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ReadDialogConfig)) EXPECT_EQ(defaultValue, "true"); } + // Read non existing attribute + { + dialog->SetName("dialog"); + dialog->SetDefaultConfig(std::string( + "")); + std::string defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), + "dummy_attribute"); + EXPECT_TRUE(defaultValue.empty()); + } delete dialog; } From 02a06bc1597c3be0b7553764cced4bd07215ea75 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 30 Jun 2022 17:22:09 +0200 Subject: [PATCH 30/40] rename fucntions for reading writting configs Signed-off-by: Mohamad --- include/ignition/gui/Dialog.hh | 15 ++------ src/Dialog.cc | 50 +++++++++++-------------- src/Dialog_TEST.cc | 68 +++++++++++++++------------------- 3 files changed, 54 insertions(+), 79 deletions(-) diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index 729f39144..e012904ab 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -57,9 +57,6 @@ namespace ignition /// \return Pointer to the item public: QQuickItem *RootItem() const; - /// \brief Set dilaog name - public: void SetName(const std::string &_name); - /// \brief Store dialog default config /// \param[in] _config XML config as string public: void SetDefaultConfig(const std::string &_config); @@ -69,7 +66,7 @@ namespace ignition /// \param[in] _attribute XMLElement attribute name /// \param[in] _value XMLElement attribute string value /// \return true if written to config file - public: bool WriteAttribute(const std::string &_path, + public: bool UpdateConfigAttribute(const std::string &_path, const std::string &_attribute, const std::string &_value) const; /// \brief Write dialog config @@ -77,7 +74,7 @@ namespace ignition /// \param[in] _attribute XMLElement attribute name /// \param[in] _value XMLElement attribute boolean value /// \return true if written to config file - public: bool WriteAttribute(const std::string &_path, + public: bool UpdateConfigAttribute(const std::string &_path, const std::string &_attribute, const bool _value) const; /// \brief Gets a config attribute value, if not found in config @@ -86,15 +83,9 @@ namespace ignition /// \param[in] _path config path /// \param[in] _attribute attribute name /// \return attribute value as string - public: std::string ReadAttribute(const std::string &_path, + public: std::string ReadAttributeValue(const std::string &_path, const std::string &_attribute) const; - /// \brief Write config to path - /// \param[in] _config config as char array - /// \param[in] _path of the config - /// \return true if written - private: bool SaveConfig(const char *_config, const std::string &_path); - /// \internal /// \brief Private data pointer private: std::unique_ptr dataPtr; diff --git a/src/Dialog.cc b/src/Dialog.cc index 3210b560a..c5eb98d95 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -25,9 +25,6 @@ namespace ignition { class DialogPrivate { - /// \brief Dialog name in config - public: std::string name{""}; - /// \brief default dialog config public: std::string config{""}; @@ -82,13 +79,7 @@ QQuickItem *Dialog::RootItem() const } ///////////////////////////////////////////////// -void Dialog::SetName(const std::string &_name) -{ - this->dataPtr->name = _name; -} - -///////////////////////////////////////////////// -bool Dialog::WriteAttribute(const std::string &_path, +bool Dialog::UpdateConfigAttribute(const std::string &_path, const std::string &_attribute, const std::string &_value) const { if (_path.empty()) @@ -114,7 +105,7 @@ bool Dialog::WriteAttribute(const std::string &_path, dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) { - if(dialogElem->Attribute("name") == this->dataPtr->name) + if(dialogElem->Attribute("name") == this->objectName().toStdString()) { dialogElem->SetAttribute(_attribute.c_str(), _value.c_str()); } @@ -138,7 +129,7 @@ bool Dialog::WriteAttribute(const std::string &_path, } ///////////////////////////////////////////////// -bool Dialog::WriteAttribute(const std::string &_path, +bool Dialog::UpdateConfigAttribute(const std::string &_path, const std::string &_attribute, const bool _value) const { if (_path.empty()) @@ -164,7 +155,7 @@ bool Dialog::WriteAttribute(const std::string &_path, dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) { - if(dialogElem->Attribute("name") == this->dataPtr->name) + if(dialogElem->Attribute("name") == this->objectName().toStdString()) { dialogElem->SetAttribute(_attribute.c_str(), _value); } @@ -194,8 +185,8 @@ void Dialog::SetDefaultConfig(const std::string &_config) } ///////////////////////////////////////////////// -std::string Dialog::ReadAttribute(const std::string &_path, - const std::string &_attribute) const +std::string Dialog::ReadAttributeValue(const std::string &_path, + const std::string &_attribute) const { tinyxml2::XMLDocument doc; std::string value {""}; @@ -215,7 +206,7 @@ std::string Dialog::ReadAttribute(const std::string &_path, dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) { - if(dialogElem->Attribute("name") == this->dataPtr->name) + if(dialogElem->Attribute("name") == this->objectName().toStdString()) { value = dialogElem->Attribute(_attribute.c_str()); } @@ -229,33 +220,34 @@ std::string Dialog::ReadAttribute(const std::string &_path, return ""; } - // Process each dialog + // Process each existing dialog for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) { - if(dialogElem->Attribute("name") == this->dataPtr->name) + if(dialogElem->Attribute("name") == this->objectName().toStdString()) { - value = dialogElem->Attribute(_attribute.c_str()); + if (dialogElem->Attribute(_attribute.c_str())) + value = dialogElem->Attribute(_attribute.c_str()); } } - // config exists but attribute not there + // config exists but attribute not there read from default config if (value.empty()) { tinyxml2::XMLDocument missingDoc; missingDoc.Parse(this->dataPtr->config.c_str()); - for (auto dialogElem = doc.FirstChildElement("dialog"); - dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) - { - if(dialogElem->Attribute("name") == this->dataPtr->name) + for (auto dialogElem = doc.FirstChildElement("dialog"); + dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) { - value = dialogElem->Attribute(_attribute.c_str()); + if(dialogElem->Attribute("name") == this->objectName().toStdString()) + { + if(dialogElem->Attribute(_attribute.c_str())) + value = dialogElem->Attribute(_attribute.c_str()); + } } - } - missingDoc.Print(&defaultPrinter); } } @@ -268,6 +260,8 @@ std::string Dialog::ReadAttribute(const std::string &_path, if (configExists){ config = ""; } + igndbg << "Setting Quick start dialog default config." << std::endl; + config += printer.CStr(); config += defaultPrinter.CStr(); std::ofstream out(_path.c_str(), std::ios::out); diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 93b9d9838..d1239b4d3 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -38,7 +38,7 @@ using namespace gui; using namespace std::chrono_literals; ///////////////////////////////////////////////// -TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ReadDialogConfig)) +TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) { ignition::common::Console::SetVerbosity(4); Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); @@ -49,54 +49,44 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ReadDialogConfig)) auto dialog = new Dialog; ASSERT_NE(nullptr, dialog); - // Read dialog config + // Read attribute value when the default the config is not set { - dialog->SetName("dialog"); - dialog->SetDefaultConfig(std::string( - "")); - std::string defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), - "default"); - EXPECT_EQ(defaultValue, "true"); + std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), + "allow"); + EXPECT_EQ(allow, ""); } - // Read non existing attribute + // Read a non existing attribute { - dialog->SetName("dialog"); + dialog->setObjectName("quick_menu"); dialog->SetDefaultConfig(std::string( - "")); - std::string defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), - "dummy_attribute"); - EXPECT_TRUE(defaultValue.empty()); + "")); + std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), + "allow"); + EXPECT_EQ(allow, ""); } - delete dialog; -} - -///////////////////////////////////////////////// -TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(ChangeDialogConfig)) -{ - ignition::common::Console::SetVerbosity(4); - Application app(g_argc, g_argv, ignition::gui::WindowType::kDialog); - - // Change default config path - App()->SetDefaultConfigPath(kTestConfigFile); - auto dialog = new Dialog; - ASSERT_NE(nullptr, dialog); + // Read an existing attribute + { + std::string show = dialog->ReadAttributeValue(app.DefaultConfigPath(), + "show"); + EXPECT_EQ(show, "true"); + } - // Read dialog config + // Update a non existing attribute { - dialog->SetName("dialog"); - dialog->SetDefaultConfig(std::string( - "")); - std::string defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), - "default"); + dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", true); + std::string show = dialog->ReadAttributeValue(app.DefaultConfigPath(), + "allow"); + EXPECT_EQ(allow, "true"); + } - EXPECT_EQ(defaultValue, "true"); - dialog->WriteAttribute(app.DefaultConfigPath(), "default", - false); - defaultValue = dialog->ReadAttribute(app.DefaultConfigPath(), - "default"); - EXPECT_EQ(defaultValue, "false"); + // Update a existing attribute + { + dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", false); + std::string show = dialog->ReadAttributeValue(app.DefaultConfigPath(), + "allow"); + EXPECT_EQ(allow, "false"); } delete dialog; From 5e80ba5c3785a63a29beb57de25473d7b8799ad8 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 30 Jun 2022 18:38:28 +0200 Subject: [PATCH 31/40] fix test Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index d1239b4d3..631ab3552 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -76,7 +76,7 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Update a non existing attribute { dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", true); - std::string show = dialog->ReadAttributeValue(app.DefaultConfigPath(), + std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, "true"); } From 1dc1f26f5ad25855f5b27e28248e5d8b4cb0ba1d Mon Sep 17 00:00:00 2001 From: Mohamad Date: Thu, 30 Jun 2022 18:44:16 +0200 Subject: [PATCH 32/40] fix test Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 631ab3552..6130ae9b2 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -84,7 +84,7 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Update a existing attribute { dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", false); - std::string show = dialog->ReadAttributeValue(app.DefaultConfigPath(), + std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, "false"); } From 7787453f783f186e59126bd6a63209184e4cca58 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Fri, 1 Jul 2022 12:03:12 +0200 Subject: [PATCH 33/40] use template argument for attribute value update Signed-off-by: Mohamad --- include/ignition/gui/Dialog.hh | 16 +++------- src/Dialog.cc | 53 ++-------------------------------- 2 files changed, 6 insertions(+), 63 deletions(-) diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index e012904ab..cdaf30904 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -64,18 +64,10 @@ namespace ignition /// \brief Write dialog config /// \param[in] _path config path /// \param[in] _attribute XMLElement attribute name - /// \param[in] _value XMLElement attribute string value + /// \param[in] _value XMLElement attribute value /// \return true if written to config file - public: bool UpdateConfigAttribute(const std::string &_path, - const std::string &_attribute, const std::string &_value) const; - - /// \brief Write dialog config - /// \param[in] _path config path - /// \param[in] _attribute XMLElement attribute name - /// \param[in] _value XMLElement attribute boolean value - /// \return true if written to config file - public: bool UpdateConfigAttribute(const std::string &_path, - const std::string &_attribute, const bool _value) const; + public: template bool UpdateConfigAttribute(const std::string &_path, + const std::string &_attribute, const T &_value) const; /// \brief Gets a config attribute value, if not found in config /// \brief write the default in the config and get it. @@ -84,7 +76,7 @@ namespace ignition /// \param[in] _attribute attribute name /// \return attribute value as string public: std::string ReadAttributeValue(const std::string &_path, - const std::string &_attribute) const; + const std::string &_attribute) const; /// \internal /// \brief Private data pointer diff --git a/src/Dialog.cc b/src/Dialog.cc index c5eb98d95..79df31c0b 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -79,58 +79,9 @@ QQuickItem *Dialog::RootItem() const } ///////////////////////////////////////////////// +template bool Dialog::UpdateConfigAttribute(const std::string &_path, - const std::string &_attribute, const std::string &_value) const -{ - if (_path.empty()) - { - ignerr << "Missing config file" << std::endl; - return false; - } - - std::string configFull = _path; - - // Use tinyxml to read config - tinyxml2::XMLDocument doc; - auto success = !doc.LoadFile(configFull.c_str()); - if (!success) - { - ignerr << "Failed to load file [" << configFull << "]: XMLError" - << std::endl; - return false; - } - - // Update attribute value for the correct dialog - for (auto dialogElem = doc.FirstChildElement("dialog"); - dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) - { - if(dialogElem->Attribute("name") == this->objectName().toStdString()) - { - dialogElem->SetAttribute(_attribute.c_str(), _value.c_str()); - } - } - - // Write config file - tinyxml2::XMLPrinter printer; - doc.Print(&printer); - - std::string config = printer.CStr(); - std::ofstream out(_path.c_str(), std::ios::out); - if (!out) - { - std::string str = "Unable to open file: " + _path; - str += ".\nCheck file permissions."; - } - else - out << config; - - return true; -} - -///////////////////////////////////////////////// -bool Dialog::UpdateConfigAttribute(const std::string &_path, - const std::string &_attribute, const bool _value) const + const std::string &_attribute, const T &_value) const { if (_path.empty()) { From e8a1e3d604ca7a6b1183f4e855b499168a2016c3 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Fri, 1 Jul 2022 12:21:20 +0200 Subject: [PATCH 34/40] code check Signed-off-by: Mohamad --- include/ignition/gui/Dialog.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index cdaf30904..e6ffc920e 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -66,8 +66,9 @@ namespace ignition /// \param[in] _attribute XMLElement attribute name /// \param[in] _value XMLElement attribute value /// \return true if written to config file - public: template bool UpdateConfigAttribute(const std::string &_path, - const std::string &_attribute, const T &_value) const; + public: template bool UpdateConfigAttribute( + const std::string &_path, const std::string &_attribute, + const T &_value) const; /// \brief Gets a config attribute value, if not found in config /// \brief write the default in the config and get it. From f61237f7addec0914f3c89477954dc25b65e5f95 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Wed, 6 Jul 2022 20:28:58 +0200 Subject: [PATCH 35/40] clean up Signed-off-by: Mohamad --- include/ignition/gui/Dialog.hh | 4 ++-- src/Dialog.cc | 30 ++++++++++++++---------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index e6ffc920e..67ebb5401 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -66,9 +66,9 @@ namespace ignition /// \param[in] _attribute XMLElement attribute name /// \param[in] _value XMLElement attribute value /// \return true if written to config file - public: template bool UpdateConfigAttribute( + public: bool UpdateConfigAttribute( const std::string &_path, const std::string &_attribute, - const T &_value) const; + const bool _value) const; /// \brief Gets a config attribute value, if not found in config /// \brief write the default in the config and get it. diff --git a/src/Dialog.cc b/src/Dialog.cc index 79df31c0b..88a340be9 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -79,9 +79,8 @@ QQuickItem *Dialog::RootItem() const } ///////////////////////////////////////////////// -template bool Dialog::UpdateConfigAttribute(const std::string &_path, - const std::string &_attribute, const T &_value) const + const std::string &_attribute, const bool _value) const { if (_path.empty()) { @@ -89,22 +88,20 @@ bool Dialog::UpdateConfigAttribute(const std::string &_path, return false; } - std::string configFull = _path; - // Use tinyxml to read config tinyxml2::XMLDocument doc; - auto success = !doc.LoadFile(configFull.c_str()); + auto success = !doc.LoadFile(_path.c_str()); if (!success) { - ignerr << "Failed to load file [" << configFull << "]: XMLError" + ignerr << "Failed to load file [" << _path << "]: XMLError" << std::endl; return false; } // Update attribute value for the correct dialog - for (auto dialogElem = doc.FirstChildElement("dialog"); - dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) + for (auto dialogElem = doc.FirstChildElement("dialog"); + dialogElem != nullptr; + dialogElem = dialogElem->NextSiblingElement("dialog")) { if(dialogElem->Attribute("name") == this->objectName().toStdString()) { @@ -120,8 +117,8 @@ bool Dialog::UpdateConfigAttribute(const std::string &_path, std::ofstream out(_path.c_str(), std::ios::out); if (!out) { - std::string str = "Unable to open file: " + _path; - str += ".\nCheck file permissions."; + ignerr << "Unable to open file: " << _path << + ".\nCheck file permissions.\n"; } else out << config; @@ -208,19 +205,20 @@ std::string Dialog::ReadAttributeValue(const std::string &_path, doc.Print(&printer); // Don't write the xml version decleration if file exists - if (configExists){ + if (configExists) + { config = ""; } - igndbg << "Setting Quick start dialog default config." << std::endl; + igndbg << "Setting dialog " << this->objectName().toStdString() + << " default config." << std::endl; config += printer.CStr(); config += defaultPrinter.CStr(); std::ofstream out(_path.c_str(), std::ios::out); if (!out) { - std::string str = "Unable to open file: " + _path; - str += ".\nCheck file permissions."; - igndbg << str << std::endl; + ignerr << "Unable to open file: " << _path << + ".\nCheck file permissions.\n"; return ""; } else From 0d81497007e9eaa84d43dc168dc6054ac7d4e49a Mon Sep 17 00:00:00 2001 From: Mohamad Date: Fri, 8 Jul 2022 16:17:57 +0200 Subject: [PATCH 36/40] rename ReadAttributeValue to ReadConfigAttribute and clean up Signed-off-by: Mohamad --- include/ignition/gui/Dialog.hh | 3 +- src/Dialog.cc | 68 +++++++++++++++------------------- src/Dialog_TEST.cc | 14 +++---- 3 files changed, 37 insertions(+), 48 deletions(-) diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index 67ebb5401..8a1cc9024 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -19,7 +19,6 @@ #define IGNITION_GUI_DIALOG_HH_ #include -#include #include #include "ignition/gui/qt.h" @@ -76,7 +75,7 @@ namespace ignition /// \param[in] _path config path /// \param[in] _attribute attribute name /// \return attribute value as string - public: std::string ReadAttributeValue(const std::string &_path, + public: std::string ReadConfigAttribute(const std::string &_path, const std::string &_attribute) const; /// \internal diff --git a/src/Dialog.cc b/src/Dialog.cc index 88a340be9..bed1bc2ed 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -15,6 +15,8 @@ * */ +#include + #include #include "ignition/gui/Application.hh" #include "ignition/gui/Dialog.hh" @@ -93,8 +95,8 @@ bool Dialog::UpdateConfigAttribute(const std::string &_path, auto success = !doc.LoadFile(_path.c_str()); if (!success) { - ignerr << "Failed to load file [" << _path << "]: XMLError" - << std::endl; + ignerr << "Failed to load file [" << _path << "]: XMLError" + << std::endl; return false; } @@ -117,8 +119,8 @@ bool Dialog::UpdateConfigAttribute(const std::string &_path, std::ofstream out(_path.c_str(), std::ios::out); if (!out) { - ignerr << "Unable to open file: " << _path << - ".\nCheck file permissions.\n"; + ignerr << "Unable to open file: " << _path + << ".\nCheck file permissions.\n"; } else out << config; @@ -133,7 +135,7 @@ void Dialog::SetDefaultConfig(const std::string &_config) } ///////////////////////////////////////////////// -std::string Dialog::ReadAttributeValue(const std::string &_path, +std::string Dialog::ReadConfigAttribute(const std::string &_path, const std::string &_attribute) const { tinyxml2::XMLDocument doc; @@ -141,61 +143,51 @@ std::string Dialog::ReadAttributeValue(const std::string &_path, std::string config = "\n\n"; tinyxml2::XMLPrinter defaultPrinter; bool configExists{true}; + std::string dialogName = this->objectName().toStdString(); - // Check if the passed in config file exists. - // (If the default config path doesn't exist yet, it's expected behavior. - // It will be created the first time now.) - if (!common::exists(_path)) + auto Value = [&_attribute, &doc, &dialogName]() { - configExists = false; - doc.Parse(this->dataPtr->config.c_str()); // Process each dialog + // If multiple attributes share the same name, return the last one for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) { - if(dialogElem->Attribute("name") == this->objectName().toStdString()) + if (dialogElem->Attribute("name") == dialogName) { - value = dialogElem->Attribute(_attribute.c_str()); + if (dialogElem->Attribute(_attribute.c_str())) + return dialogElem->Attribute(_attribute.c_str()); } } + return ""; + }; + + // Check if the passed in config file exists. + // (If the default config path doesn't exist yet, it's expected behavior. + // It will be created the first time now.) + if (!common::exists(_path)) + { + configExists = false; + doc.Parse(this->dataPtr->config.c_str()); + value = Value(); } else { auto success = !doc.LoadFile(_path.c_str()); if (!success) { + ignerr << "Failed to load file [" << _path << "]: XMLError" + << std::endl; return ""; } - - // Process each existing dialog - for (auto dialogElem = doc.FirstChildElement("dialog"); - dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) - { - if(dialogElem->Attribute("name") == this->objectName().toStdString()) - { - if (dialogElem->Attribute(_attribute.c_str())) - value = dialogElem->Attribute(_attribute.c_str()); - } - } + value = Value(); // config exists but attribute not there read from default config if (value.empty()) { tinyxml2::XMLDocument missingDoc; missingDoc.Parse(this->dataPtr->config.c_str()); - - for (auto dialogElem = doc.FirstChildElement("dialog"); - dialogElem != nullptr; - dialogElem = dialogElem->NextSiblingElement("dialog")) - { - if(dialogElem->Attribute("name") == this->objectName().toStdString()) - { - if(dialogElem->Attribute(_attribute.c_str())) - value = dialogElem->Attribute(_attribute.c_str()); - } - } + value = Value(); missingDoc.Print(&defaultPrinter); } } @@ -217,8 +209,8 @@ std::string Dialog::ReadAttributeValue(const std::string &_path, std::ofstream out(_path.c_str(), std::ios::out); if (!out) { - ignerr << "Unable to open file: " << _path << - ".\nCheck file permissions.\n"; + ignerr << "Unable to open file: " << _path + << ".\nCheck file permissions.\n"; return ""; } else diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 6130ae9b2..53e154d4a 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Open Source Robotics Foundation + * Copyright (C) 2022 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,6 @@ #include -#include - #include #include @@ -51,7 +49,7 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Read attribute value when the default the config is not set { - std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), + std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, ""); } @@ -61,14 +59,14 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) dialog->setObjectName("quick_menu"); dialog->SetDefaultConfig(std::string( "")); - std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), + std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, ""); } // Read an existing attribute { - std::string show = dialog->ReadAttributeValue(app.DefaultConfigPath(), + std::string show = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "show"); EXPECT_EQ(show, "true"); } @@ -76,7 +74,7 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Update a non existing attribute { dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", true); - std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), + std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, "true"); } @@ -84,7 +82,7 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Update a existing attribute { dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", false); - std::string allow = dialog->ReadAttributeValue(app.DefaultConfigPath(), + std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, "false"); } From 095a2b0a74cb85ffcb09b96f183fcc5eccb2ac49 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Fri, 8 Jul 2022 16:35:21 +0200 Subject: [PATCH 37/40] test config exists Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 53e154d4a..7bf335b0d 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -49,9 +49,16 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Read attribute value when the default the config is not set { + EXPECT_FALSE(common::exists(kTestConfigFile)); std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, ""); + + // Config file is created when a read is attempted + EXPECT_TRUE(common::exists(kTestConfigFile)); + + // Delete file + std::remove(kTestConfigFile.c_str()); } // Read a non existing attribute @@ -76,7 +83,6 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", true); std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); - EXPECT_EQ(allow, "true"); } // Update a existing attribute From 30dabb5059f18f6d1ca74011c4b705be2f235bcf Mon Sep 17 00:00:00 2001 From: Mohamad Date: Sat, 9 Jul 2022 00:36:16 +0200 Subject: [PATCH 38/40] test config file creation and deletion Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 7bf335b0d..0669a9c25 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -63,34 +63,62 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Read a non existing attribute { + EXPECT_FALSE(common::exists(kTestConfigFile)); dialog->setObjectName("quick_menu"); dialog->SetDefaultConfig(std::string( "")); std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, ""); + + // Config file is created when a read is attempted + EXPECT_TRUE(common::exists(kTestConfigFile)); + + // Delete file + std::remove(kTestConfigFile.c_str()); } // Read an existing attribute { + EXPECT_FALSE(common::exists(kTestConfigFile)); std::string show = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "show"); EXPECT_EQ(show, "true"); + + // Config file is created when a read is attempted + EXPECT_TRUE(common::exists(kTestConfigFile)); + + // Delete file + std::remove(kTestConfigFile.c_str()); } // Update a non existing attribute { + EXPECT_FALSE(common::exists(kTestConfigFile)); dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", true); std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); + + // Config file is created when a read is attempted + EXPECT_TRUE(common::exists(kTestConfigFile)); + + // Delete file + std::remove(kTestConfigFile.c_str()); } // Update a existing attribute { + EXPECT_FALSE(common::exists(kTestConfigFile)); dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", false); std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); EXPECT_EQ(allow, "false"); + + // Config file is created when a read is attempted + EXPECT_TRUE(common::exists(kTestConfigFile)); + + // Delete file + std::remove(kTestConfigFile.c_str()); } delete dialog; From 632e43ef2cb630f5708e6698a2cccb94e23a6f23 Mon Sep 17 00:00:00 2001 From: Mohamad Date: Sat, 9 Jul 2022 00:36:57 +0200 Subject: [PATCH 39/40] fix comments Signed-off-by: Mohamad --- include/ignition/gui/Dialog.hh | 4 ++-- src/Dialog.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/ignition/gui/Dialog.hh b/include/ignition/gui/Dialog.hh index 8a1cc9024..7271c415b 100644 --- a/include/ignition/gui/Dialog.hh +++ b/include/ignition/gui/Dialog.hh @@ -70,8 +70,8 @@ namespace ignition const bool _value) const; /// \brief Gets a config attribute value, if not found in config - /// \brief write the default in the config and get it. - /// \brief creates config file if it doesn't exist. + /// write the default in the config and get it. + /// creates config file if it doesn't exist. /// \param[in] _path config path /// \param[in] _attribute attribute name /// \return attribute value as string diff --git a/src/Dialog.cc b/src/Dialog.cc index bed1bc2ed..78c45157a 100644 --- a/src/Dialog.cc +++ b/src/Dialog.cc @@ -148,7 +148,7 @@ std::string Dialog::ReadConfigAttribute(const std::string &_path, auto Value = [&_attribute, &doc, &dialogName]() { // Process each dialog - // If multiple attributes share the same name, return the last one + // If multiple attributes share the same name, return the first one for (auto dialogElem = doc.FirstChildElement("dialog"); dialogElem != nullptr; dialogElem = dialogElem->NextSiblingElement("dialog")) From 94e5bbc68333b68645048dea0f61d014f0e840aa Mon Sep 17 00:00:00 2001 From: Mohamad Date: Mon, 11 Jul 2022 15:03:27 +0200 Subject: [PATCH 40/40] dialog test fix Signed-off-by: Mohamad --- src/Dialog_TEST.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Dialog_TEST.cc b/src/Dialog_TEST.cc index 0669a9c25..c52b46a12 100644 --- a/src/Dialog_TEST.cc +++ b/src/Dialog_TEST.cc @@ -95,10 +95,18 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Update a non existing attribute { EXPECT_FALSE(common::exists(kTestConfigFile)); - dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", true); + + // Call a read to create config file std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); + // Empty string for a non existing attribute + EXPECT_EQ(allow, ""); + dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", true); + allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), + "allow"); + EXPECT_EQ(allow, "true"); + // Config file is created when a read is attempted EXPECT_TRUE(common::exists(kTestConfigFile)); @@ -109,9 +117,13 @@ TEST(DialogTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(UpdateDialogConfig)) // Update a existing attribute { EXPECT_FALSE(common::exists(kTestConfigFile)); - dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", false); + + // Call a read to create config file std::string allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), "allow"); + dialog->UpdateConfigAttribute(app.DefaultConfigPath(), "allow", false); + allow = dialog->ReadConfigAttribute(app.DefaultConfigPath(), + "allow"); EXPECT_EQ(allow, "false"); // Config file is created when a read is attempted