From 480648e9e567cf844188ec9264d1e1874567c08b Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Sat, 29 Apr 2023 21:47:45 +0000 Subject: [PATCH 01/26] Prepare Next Version --- ovos_gui/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 03ebedf..23532c1 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -1,6 +1,6 @@ # START_VERSION_BLOCK VERSION_MAJOR = 0 VERSION_MINOR = 0 -VERSION_BUILD = 2 +VERSION_BUILD = 3 VERSION_ALPHA = 0 # END_VERSION_BLOCK From 18788f017488f0556755ecaae8df9647c0c022e5 Mon Sep 17 00:00:00 2001 From: JarbasAi Date: Sun, 30 Apr 2023 16:53:35 +0100 Subject: [PATCH 02/26] fix/setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index e0f1dd8..d500645 100644 --- a/setup.py +++ b/setup.py @@ -69,6 +69,7 @@ def package_files(directory): url='https://github.com/OpenVoiceOS/ovos-gui', description='ovos-core gui service daemon', include_package_data=True, + packages=["ovos_gui"], package_data={"": package_files('ovos_gui/res')}, install_requires=required('requirements.txt'), entry_points={ From 4f624ae71d3ac9f02bca23124dd0bfffa33cdd12 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Sun, 30 Apr 2023 15:54:29 +0000 Subject: [PATCH 03/26] Increment Version --- CHANGELOG.md | 4 ++++ ovos_gui/version.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ac855c..f73971f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [V0.0.2](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2) (2023-04-29) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a12...V0.0.2) + ## [V0.0.2a12](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a12) (2023-04-27) [Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a11...V0.0.2a12) diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 23532c1..874672d 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 0 +VERSION_ALPHA = 1 # END_VERSION_BLOCK From 6e698465a8591f4496a7ef2e3fc86fd96633c6f8 Mon Sep 17 00:00:00 2001 From: JarbasAi Date: Mon, 1 May 2023 18:54:27 +0100 Subject: [PATCH 04/26] hotix/setup.py missing module --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d500645..39d8696 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,7 @@ def package_files(directory): url='https://github.com/OpenVoiceOS/ovos-gui', description='ovos-core gui service daemon', include_package_data=True, - packages=["ovos_gui"], + packages=["ovos_gui", "ovos_gui.interfaces"], package_data={"": package_files('ovos_gui/res')}, install_requires=required('requirements.txt'), entry_points={ From 502dec01d0055c54998280ffaa76d5f54961173f Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Mon, 1 May 2023 17:55:30 +0000 Subject: [PATCH 05/26] Increment Version --- CHANGELOG.md | 4 ++++ ovos_gui/version.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f73971f..99f1e0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [V0.0.3a1](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a1) (2023-04-30) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2...V0.0.3a1) + ## [V0.0.2](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2) (2023-04-29) [Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a12...V0.0.2) diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 874672d..bdac248 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 1 +VERSION_ALPHA = 2 # END_VERSION_BLOCK From fd50fd91f531a2d5e9c5aca4786de7705be349fb Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Fri, 9 Jun 2023 02:39:11 +0100 Subject: [PATCH 06/26] :tada: - GUI plugin (#11) Co-authored-by: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Co-authored-by: Daniel McKnight --- ovos_gui/extensions.py | 353 +-------- ovos_gui/homescreen.py | 24 +- ovos_gui/interfaces/mobile.py | 22 - ovos_gui/interfaces/smartspeaker.py | 242 ------- ovos_gui/namespace.py | 69 +- ovos_gui/res/ui/settings/SettingsModel.qml | 46 -- ovos_gui/res/ui/settings/ThemeView.qml | 187 ----- ovos_gui/res/ui/settings/about_page.qml | 177 ----- ovos_gui/res/ui/settings/code/colorUtils.js | 67 -- .../configuration_generator_display.qml | 341 --------- .../settings/configuration_groups_display.qml | 183 ----- .../configuration_ui/settingCheckBox.qml | 36 - .../configuration_ui/settingListBox.qml | 208 ------ .../configuration_ui/settingTextBox.qml | 35 - .../res/ui/settings/customize_settings.qml | 492 ------------- ovos_gui/res/ui/settings/customize_theme.qml | 629 ---------------- .../settings/delegates/BrightnessSlider.qml | 58 -- .../settings/delegates/ColorSelectPrimary.qml | 151 ---- .../delegates/ColorSelectSecondary.qml | 214 ------ .../res/ui/settings/delegates/ColorSlider.qml | 50 -- .../res/ui/settings/delegates/NameSelect.qml | 1 - .../res/ui/settings/delegates/Palette.qml | 54 -- .../ui/settings/delegates/PalettesGrid.qml | 167 ----- .../res/ui/settings/delegates/SetNameBox.qml | 179 ----- .../res/ui/settings/developer_settings.qml | 288 -------- ovos_gui/res/ui/settings/display_settings.qml | 497 ------------- ovos_gui/res/ui/settings/factory_settings.qml | 298 -------- .../res/ui/settings/homescreen_settings.qml | 185 ----- ovos_gui/res/ui/settings/images/back.png | Bin 1772 -> 0 bytes ovos_gui/res/ui/settings/images/back.svg | 10 - ovos_gui/res/ui/settings/images/display.svg | 71 -- ovos_gui/res/ui/settings/images/home.svg | 116 --- ovos_gui/res/ui/settings/images/info.svg | 122 ---- ovos_gui/res/ui/settings/images/next.svg | 62 -- ovos_gui/res/ui/settings/images/paint.svg | 117 --- ovos_gui/res/ui/settings/images/power.svg | 67 -- ovos_gui/res/ui/settings/images/restart.svg | 116 --- ovos_gui/res/ui/settings/images/settings.png | Bin 5903 -> 0 bytes ovos_gui/res/ui/settings/images/ssh.svg | 201 ------ .../res/ui/settings/images/switch-green.svg | 101 --- .../res/ui/settings/images/switch-red.svg | 100 --- ovos_gui/res/ui/settings/images/tick.svg | 99 --- ovos_gui/res/ui/settings/lupdate-generator.sh | 71 -- ovos_gui/res/ui/settings/settingspage.qml | 202 ------ ovos_gui/res/ui/settings/ssh_settings.qml | 149 ---- .../res/ui/settings/wallpaper_settings.qml | 680 ------------------ .../SmartSpeakerExtension.GuiInterface_de.qm | Bin 6138 -> 0 bytes .../SmartSpeakerExtension.GuiInterface_es.qm | Bin 5770 -> 0 bytes .../SmartSpeakerExtension.GuiInterface_fr.qm | Bin 5784 -> 0 bytes .../SmartSpeakerExtension.GuiInterface_it.qm | Bin 5007 -> 0 bytes .../SmartSpeakerExtension.GuiInterface_nl.qm | Bin 5498 -> 0 bytes .../SmartSpeakerExtension.GuiInterface_pt.qm | Bin 5648 -> 0 bytes ovos_gui/res/ui/translations/about_page_de.ts | 43 -- ovos_gui/res/ui/translations/about_page_es.ts | 43 -- ovos_gui/res/ui/translations/about_page_fr.ts | 43 -- ovos_gui/res/ui/translations/about_page_it.ts | 43 -- ovos_gui/res/ui/translations/about_page_nl.ts | 43 -- ovos_gui/res/ui/translations/about_page_pt.ts | 43 -- .../configuration_generator_display_de.ts | 22 - .../configuration_generator_display_es.ts | 22 - .../configuration_generator_display_fr.ts | 22 - .../configuration_generator_display_it.ts | 22 - .../configuration_generator_display_nl.ts | 22 - .../configuration_generator_display_pt.ts | 22 - .../configuration_groups_display_de.ts | 17 - .../configuration_groups_display_es.ts | 17 - .../configuration_groups_display_fr.ts | 17 - .../configuration_groups_display_it.ts | 17 - .../configuration_groups_display_nl.ts | 17 - .../configuration_groups_display_pt.ts | 17 - .../ui/translations/customize_settings_de.ts | 32 - .../ui/translations/customize_settings_es.ts | 32 - .../ui/translations/customize_settings_fr.ts | 32 - .../ui/translations/customize_settings_it.ts | 32 - .../ui/translations/customize_settings_nl.ts | 32 - .../ui/translations/customize_settings_pt.ts | 32 - .../res/ui/translations/customize_theme_de.ts | 58 -- .../res/ui/translations/customize_theme_es.ts | 58 -- .../res/ui/translations/customize_theme_fr.ts | 58 -- .../res/ui/translations/customize_theme_it.ts | 58 -- .../res/ui/translations/customize_theme_nl.ts | 58 -- .../res/ui/translations/customize_theme_pt.ts | 58 -- .../ui/translations/developer_settings_de.ts | 47 -- .../ui/translations/developer_settings_es.ts | 47 -- .../ui/translations/developer_settings_fr.ts | 47 -- .../ui/translations/developer_settings_it.ts | 47 -- .../ui/translations/developer_settings_nl.ts | 47 -- .../ui/translations/developer_settings_pt.ts | 47 -- .../ui/translations/display_settings_de.ts | 61 -- .../ui/translations/display_settings_es.ts | 61 -- .../ui/translations/display_settings_fr.ts | 61 -- .../ui/translations/display_settings_it.ts | 61 -- .../ui/translations/display_settings_nl.ts | 61 -- .../ui/translations/display_settings_pt.ts | 61 -- .../ui/translations/homescreen_settings_de.ts | 17 - .../ui/translations/homescreen_settings_es.ts | 17 - .../ui/translations/homescreen_settings_fr.ts | 17 - .../ui/translations/homescreen_settings_it.ts | 17 - .../ui/translations/homescreen_settings_nl.ts | 17 - .../ui/translations/homescreen_settings_pt.ts | 17 - .../res/ui/translations/lrelease-generator.sh | 14 - .../res/ui/translations/settingListBox_de.ts | 17 - .../res/ui/translations/settingListBox_es.ts | 17 - .../res/ui/translations/settingListBox_fr.ts | 17 - .../res/ui/translations/settingListBox_it.ts | 17 - .../res/ui/translations/settingListBox_nl.ts | 17 - .../res/ui/translations/settingListBox_pt.ts | 17 - .../res/ui/translations/settingspage_de.ts | 47 -- .../res/ui/translations/settingspage_es.ts | 47 -- .../res/ui/translations/settingspage_fr.ts | 47 -- .../res/ui/translations/settingspage_it.ts | 47 -- .../res/ui/translations/settingspage_nl.ts | 47 -- .../res/ui/translations/settingspage_pt.ts | 47 -- .../res/ui/translations/ssh_settings_de.ts | 32 - .../res/ui/translations/ssh_settings_es.ts | 32 - .../res/ui/translations/ssh_settings_fr.ts | 32 - .../res/ui/translations/ssh_settings_it.ts | 32 - .../res/ui/translations/ssh_settings_nl.ts | 32 - .../res/ui/translations/ssh_settings_pt.ts | 32 - ovos_gui/service.py | 5 +- requirements.txt | 7 +- setup.py | 2 +- test/unittests/test_bigscreen_extension.py | 43 -- test/unittests/test_smartspeaker_extension.py | 48 -- 124 files changed, 98 insertions(+), 9916 deletions(-) delete mode 100644 ovos_gui/interfaces/mobile.py delete mode 100644 ovos_gui/interfaces/smartspeaker.py delete mode 100644 ovos_gui/res/ui/settings/SettingsModel.qml delete mode 100644 ovos_gui/res/ui/settings/ThemeView.qml delete mode 100644 ovos_gui/res/ui/settings/about_page.qml delete mode 100644 ovos_gui/res/ui/settings/code/colorUtils.js delete mode 100644 ovos_gui/res/ui/settings/configuration_generator_display.qml delete mode 100644 ovos_gui/res/ui/settings/configuration_groups_display.qml delete mode 100644 ovos_gui/res/ui/settings/configuration_ui/settingCheckBox.qml delete mode 100644 ovos_gui/res/ui/settings/configuration_ui/settingListBox.qml delete mode 100644 ovos_gui/res/ui/settings/configuration_ui/settingTextBox.qml delete mode 100644 ovos_gui/res/ui/settings/customize_settings.qml delete mode 100644 ovos_gui/res/ui/settings/customize_theme.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/BrightnessSlider.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/ColorSelectPrimary.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/ColorSelectSecondary.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/ColorSlider.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/NameSelect.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/Palette.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/PalettesGrid.qml delete mode 100644 ovos_gui/res/ui/settings/delegates/SetNameBox.qml delete mode 100644 ovos_gui/res/ui/settings/developer_settings.qml delete mode 100644 ovos_gui/res/ui/settings/display_settings.qml delete mode 100644 ovos_gui/res/ui/settings/factory_settings.qml delete mode 100644 ovos_gui/res/ui/settings/homescreen_settings.qml delete mode 100644 ovos_gui/res/ui/settings/images/back.png delete mode 100644 ovos_gui/res/ui/settings/images/back.svg delete mode 100644 ovos_gui/res/ui/settings/images/display.svg delete mode 100644 ovos_gui/res/ui/settings/images/home.svg delete mode 100644 ovos_gui/res/ui/settings/images/info.svg delete mode 100644 ovos_gui/res/ui/settings/images/next.svg delete mode 100644 ovos_gui/res/ui/settings/images/paint.svg delete mode 100644 ovos_gui/res/ui/settings/images/power.svg delete mode 100644 ovos_gui/res/ui/settings/images/restart.svg delete mode 100644 ovos_gui/res/ui/settings/images/settings.png delete mode 100644 ovos_gui/res/ui/settings/images/ssh.svg delete mode 100644 ovos_gui/res/ui/settings/images/switch-green.svg delete mode 100644 ovos_gui/res/ui/settings/images/switch-red.svg delete mode 100644 ovos_gui/res/ui/settings/images/tick.svg delete mode 100755 ovos_gui/res/ui/settings/lupdate-generator.sh delete mode 100644 ovos_gui/res/ui/settings/settingspage.qml delete mode 100644 ovos_gui/res/ui/settings/ssh_settings.qml delete mode 100644 ovos_gui/res/ui/settings/wallpaper_settings.qml delete mode 100644 ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_de.qm delete mode 100644 ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_es.qm delete mode 100644 ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_fr.qm delete mode 100644 ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_it.qm delete mode 100644 ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_nl.qm delete mode 100644 ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_pt.qm delete mode 100644 ovos_gui/res/ui/translations/about_page_de.ts delete mode 100644 ovos_gui/res/ui/translations/about_page_es.ts delete mode 100644 ovos_gui/res/ui/translations/about_page_fr.ts delete mode 100644 ovos_gui/res/ui/translations/about_page_it.ts delete mode 100644 ovos_gui/res/ui/translations/about_page_nl.ts delete mode 100644 ovos_gui/res/ui/translations/about_page_pt.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_generator_display_de.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_generator_display_es.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_generator_display_fr.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_generator_display_it.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_generator_display_nl.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_generator_display_pt.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_groups_display_de.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_groups_display_es.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_groups_display_fr.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_groups_display_it.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_groups_display_nl.ts delete mode 100644 ovos_gui/res/ui/translations/configuration_groups_display_pt.ts delete mode 100644 ovos_gui/res/ui/translations/customize_settings_de.ts delete mode 100644 ovos_gui/res/ui/translations/customize_settings_es.ts delete mode 100644 ovos_gui/res/ui/translations/customize_settings_fr.ts delete mode 100644 ovos_gui/res/ui/translations/customize_settings_it.ts delete mode 100644 ovos_gui/res/ui/translations/customize_settings_nl.ts delete mode 100644 ovos_gui/res/ui/translations/customize_settings_pt.ts delete mode 100644 ovos_gui/res/ui/translations/customize_theme_de.ts delete mode 100644 ovos_gui/res/ui/translations/customize_theme_es.ts delete mode 100644 ovos_gui/res/ui/translations/customize_theme_fr.ts delete mode 100644 ovos_gui/res/ui/translations/customize_theme_it.ts delete mode 100644 ovos_gui/res/ui/translations/customize_theme_nl.ts delete mode 100644 ovos_gui/res/ui/translations/customize_theme_pt.ts delete mode 100644 ovos_gui/res/ui/translations/developer_settings_de.ts delete mode 100644 ovos_gui/res/ui/translations/developer_settings_es.ts delete mode 100644 ovos_gui/res/ui/translations/developer_settings_fr.ts delete mode 100644 ovos_gui/res/ui/translations/developer_settings_it.ts delete mode 100644 ovos_gui/res/ui/translations/developer_settings_nl.ts delete mode 100644 ovos_gui/res/ui/translations/developer_settings_pt.ts delete mode 100644 ovos_gui/res/ui/translations/display_settings_de.ts delete mode 100644 ovos_gui/res/ui/translations/display_settings_es.ts delete mode 100644 ovos_gui/res/ui/translations/display_settings_fr.ts delete mode 100644 ovos_gui/res/ui/translations/display_settings_it.ts delete mode 100644 ovos_gui/res/ui/translations/display_settings_nl.ts delete mode 100644 ovos_gui/res/ui/translations/display_settings_pt.ts delete mode 100644 ovos_gui/res/ui/translations/homescreen_settings_de.ts delete mode 100644 ovos_gui/res/ui/translations/homescreen_settings_es.ts delete mode 100644 ovos_gui/res/ui/translations/homescreen_settings_fr.ts delete mode 100644 ovos_gui/res/ui/translations/homescreen_settings_it.ts delete mode 100644 ovos_gui/res/ui/translations/homescreen_settings_nl.ts delete mode 100644 ovos_gui/res/ui/translations/homescreen_settings_pt.ts delete mode 100755 ovos_gui/res/ui/translations/lrelease-generator.sh delete mode 100644 ovos_gui/res/ui/translations/settingListBox_de.ts delete mode 100644 ovos_gui/res/ui/translations/settingListBox_es.ts delete mode 100644 ovos_gui/res/ui/translations/settingListBox_fr.ts delete mode 100644 ovos_gui/res/ui/translations/settingListBox_it.ts delete mode 100644 ovos_gui/res/ui/translations/settingListBox_nl.ts delete mode 100644 ovos_gui/res/ui/translations/settingListBox_pt.ts delete mode 100644 ovos_gui/res/ui/translations/settingspage_de.ts delete mode 100644 ovos_gui/res/ui/translations/settingspage_es.ts delete mode 100644 ovos_gui/res/ui/translations/settingspage_fr.ts delete mode 100644 ovos_gui/res/ui/translations/settingspage_it.ts delete mode 100644 ovos_gui/res/ui/translations/settingspage_nl.ts delete mode 100644 ovos_gui/res/ui/translations/settingspage_pt.ts delete mode 100644 ovos_gui/res/ui/translations/ssh_settings_de.ts delete mode 100644 ovos_gui/res/ui/translations/ssh_settings_es.ts delete mode 100644 ovos_gui/res/ui/translations/ssh_settings_fr.ts delete mode 100644 ovos_gui/res/ui/translations/ssh_settings_it.ts delete mode 100644 ovos_gui/res/ui/translations/ssh_settings_nl.ts delete mode 100644 ovos_gui/res/ui/translations/ssh_settings_pt.ts delete mode 100644 test/unittests/test_bigscreen_extension.py delete mode 100644 test/unittests/test_smartspeaker_extension.py diff --git a/ovos_gui/extensions.py b/ovos_gui/extensions.py index a2d098f..b23e390 100644 --- a/ovos_gui/extensions.py +++ b/ovos_gui/extensions.py @@ -1,17 +1,13 @@ -import threading - -from ovos_bus_client import Message -from ovos_backend_client.pairing import is_paired +from ovos_bus_client import Message, MessageBusClient from ovos_config.config import Configuration +from ovos_gui.namespace import NamespaceManager from ovos_utils.log import LOG - +from ovos_plugin_manager.gui import OVOSGuiFactory from ovos_gui.homescreen import HomescreenManager -from ovos_gui.interfaces.mobile import MobileExtensionGuiInterface -from ovos_gui.interfaces.smartspeaker import SmartSpeakerExtensionGuiInterface class ExtensionsManager: - def __init__(self, name, bus, gui): + def __init__(self, name: str, bus: MessageBusClient, gui: NamespaceManager): """ Constructor for the Extension Manager. The Extension Manager is responsible for managing the extensions that define additional GUI behaviours for specific platforms. @@ -27,40 +23,45 @@ def __init__(self, name, bus, gui): core_config = Configuration() enclosure_config = core_config.get("gui") or {} self.active_extension = enclosure_config.get("extension", "generic") - - # ToDo: Add Exclusive Support For "Desktop", "Mobile" Extensions - self.supported_extensions = ["smartspeaker", "bigscreen", "generic", "mobile", "plasmoid"] - - if self.active_extension.lower() not in self.supported_extensions: - self.active_extension = "generic" - - LOG.info( - f"Extensions Manager: Initializing {self.name} with active extension {self.active_extension}") + LOG.debug(f"Extensions Manager: Initializing {self.name} " + f"with active extension {self.active_extension}") self.activate_extension(self.active_extension.lower()) - def activate_extension(self, extension_id): - LOG.info(f"Extensions Manager: Activating Extension {extension_id}") - - # map extension_id to class - if extension_id == "smartspeaker": - self.extension = SmartSpeakerExtension(self.bus, self.gui) - elif extension_id == "bigscreen": - self.extension = BigscreenExtension(self.bus, self.gui) - elif extension_id == "mobile": - self.extension = MobileExtension(self.bus, self.gui) - elif extension_id == "plasmoid": - self.extension = PlasmoidExtension(self.bus, self.gui) - else: - self.extension = GenericExtension(self.bus, self.gui) - - LOG.info(f"Extensions Manager: Activated Extension {extension_id}") + def activate_extension(self, extension_id: str): + mappings = { + "smartspeaker": "ovos-gui-plugin-shell-companion", + "bigscreen": "ovos-gui-plugin-bigscreen", + "mobile": "ovos-gui-plugin-mobile", + "plasmoid": "ovos-gui-plugin-plasmoid" + } + if extension_id.lower() in mappings: + extension_id = mappings[extension_id.lower()] + + cfg = dict(Configuration().get("gui", {})) + cfg["module"] = extension_id + # LOG.info(f"Extensions Manager: Activating Extension {extension_id}") + try: + LOG.info(f"Creating GUI with config={cfg}") + self.extension = OVOSGuiFactory.create(cfg, bus=self.bus) + except: + if extension_id == "generic": + raise + LOG.exception(f"failed to load {extension_id}, " + f"falling back to 'generic'") + cfg["module"] = "generic" + self.extension = OVOSGuiFactory.create(cfg, bus=self.bus) + self.extension.bind_homescreen() + + LOG.info(f"Extensions Manager: Activated Extension {extension_id} " + f"({self.extension.__class__})") self.bus.emit( Message("extension.manager.activated", {"id": extension_id})) def signal_available(message=None): message = message or Message("") - self.bus.emit(message.forward("mycroft.gui.available", - {"permanent": self.extension.permanent})) + self.bus.emit( + message.forward("mycroft.gui.available", + {"permanent": self.extension.permanent})) if self.extension.preload_gui: signal_available() @@ -68,285 +69,3 @@ def signal_available(message=None): self.bus.on("mycroft.gui.connected", signal_available) -class SmartSpeakerExtension: - """ Smart Speaker Extension: This extension is responsible for managing the Smart Speaker - specific GUI behaviours. This extension adds support for Homescreens and Homescreen Mangement. - - Args: - bus: MessageBus instance - gui: GUI instance - preload_gui (bool): load GUI skills even if gui client not connected - permanent (bool): disable unloading of GUI skills on gui client disconnections - """ - - def __init__(self, bus, gui, preload_gui=False, permanent=True): - LOG.info("SmartSpeaker: Initializing") - - self.bus = bus - self.gui = gui - self.preload_gui = preload_gui - self.permanent = permanent - self.homescreen_manager = HomescreenManager(self.bus, self.gui) - - self.homescreen_thread = threading.Thread( - target=self.homescreen_manager.run) - self.homescreen_thread.start() - - self.device_paired = is_paired() - self.backend = "unknown" - self.gui_interface = SmartSpeakerExtensionGuiInterface( - self.bus, self.homescreen_manager) - - try: - self.bus.on("ovos.pairing.process.completed", - self.start_homescreen_process) - self.bus.on("ovos.pairing.set.backend", self.set_backend_type) - self.bus.on("mycroft.gui.screen.close", - self.handle_remove_namespace) - self.bus.on("system.display.homescreen", - self.handle_system_display_homescreen) - - except Exception as e: - LOG.error(f"SmartSpeaker: Init Bus Exception: {e}") - - def set_backend_type(self, message): - backend = message.data.get("backend", "unknown") - if not backend == "unknown": - self.backend = backend - else: - backend = self._detect_backend() - self.backend = backend - - def start_homescreen_process(self, message): - self.device_paired = is_paired() - if not self.backend == "local": - self.homescreen_manager.show_homescreen() - self.bus.emit(Message("ovos.shell.status.ok")) - else: - self.bus.emit(Message("ovos.shell.status.ok")) - - def _detect_backend(self): - config = Configuration() - server_config = config.get("server") or {} - backend_config = server_config.get("url", "") - if "https://api.mycroft.ai" in backend_config: - return "remote" - else: - return "local" - - def handle_remove_namespace(self, message): - LOG.info("Got Clear Namespace Event In Skill") - get_skill_namespace = message.data.get("skill_id", "") - if get_skill_namespace: - self.bus.emit(Message("gui.clear.namespace", - {"__from": get_skill_namespace})) - - def handle_system_display_homescreen(self, message): - self.homescreen_manager.show_homescreen() - - -class BigscreenExtension: - """ Bigscreen Platform Extension: This extension is responsible for managing the Bigscreen - specific GUI behaviours. The bigscreen extension does not support Homescreens. It includes - support for Window managment and Window behaviour. - - Args: - bus: MessageBus instance - gui: GUI instance - preload_gui (bool): load GUI skills even if gui client not connected - permanent (bool): disable unloading of GUI skills on gui client disconnections - """ - - def __init__(self, bus, gui, preload_gui=False, permanent=True): - LOG.info("Bigscreen: Initializing") - - self.bus = bus - self.gui = gui - self.permanent = permanent - self.preload_gui = preload_gui - self.interaction_without_idle = True - self.interaction_skill_id = None - - try: - self.bus.on('mycroft.gui.screen.close', self.close_window_by_event) - self.bus.on('mycroft.gui.force.screenclose', - self.close_window_by_force) - self.bus.on('gui.page.show', self.on_gui_page_show) - self.bus.on('gui.page_interaction', self.on_gui_page_interaction) - self.bus.on('gui.namespace.removed', self.close_current_window) - - except Exception as e: - LOG.error(f"Bigscreen: Init Bus Exception: {e}") - - def on_gui_page_show(self, message): - override_idle = message.data.get('__idle') - if override_idle is True: - self.interaction_without_idle = True - elif isinstance(override_idle, int) and not (override_idle, bool) and override_idle is not False: - self.interaction_without_idle = True - elif (message.data['page']): - if not isinstance(override_idle, bool) or not isinstance(override_idle, int): - self.interaction_without_idle = False - - def on_gui_page_interaction(self, message): - skill_id = message.data.get('skill_id') - self.interaction_skill_id = skill_id - - def handle_remove_namespace(self, message): - get_skill_namespace = message.data.get("skill_id", "") - LOG.info(f"Got Clear Namespace Event In Skill {get_skill_namespace}") - if get_skill_namespace: - self.bus.emit(Message("gui.clear.namespace", - {"__from": get_skill_namespace})) - - def close_current_window(self, message): - skill_id = message.data.get('skill_id') - LOG.info(f"Bigscreen: Closing Current Window For Skill {skill_id}") - self.bus.emit(Message('screen.close.idle.event', - data={"skill_idle_event_id": skill_id})) - - def close_window_by_event(self, message): - self.interaction_without_idle = False - self.bus.emit(Message('screen.close.idle.event', - data={"skill_idle_event_id": self.interaction_skill_id})) - self.handle_remove_namespace(message) - - def close_window_by_force(self, message): - skill_id = message.data.get('skill_id') - self.bus.emit(Message('screen.close.idle.event', - data={"skill_idle_event_id": skill_id})) - self.handle_remove_namespace(message) - - -class GenericExtension: - """ Generic Platform Extension: This extension is responsible for managing the generic GUI behaviours - for non specific platforms. The generic extension does optionally support Homescreen and Homescreen - Management but it needs to be exclusively enabled in the configuration file. - - Args: - bus: MessageBus instance - gui: GUI instance - preload_gui (bool): load GUI skills even if gui client not connected - permanent (bool): disable unloading of GUI skills on gui client disconnections - """ - - def __init__(self, bus, gui, preload_gui=False, permanent=False): - LOG.info("Generic: Initializing") - - self.bus = bus - self.gui = gui - self.preload_gui = preload_gui - self.permanent = permanent - core_config = Configuration() - gui_config = core_config.get("gui") or {} - generic_config = gui_config.get("generic", {}) - self.homescreen_supported = generic_config.get("homescreen_supported", False) - - if self.homescreen_supported: - self.homescreen_manager = HomescreenManager(self.bus, self.gui) - self.homescreen_thread = threading.Thread( - target=self.homescreen_manager.run) - self.homescreen_thread.start() - - try: - self.bus.on("mycroft.gui.screen.close", - self.handle_remove_namespace) - - except Exception as e: - LOG.error(f"Generic: Init Bus Exception: {e}") - - def handle_remove_namespace(self, message): - LOG.info("Got Clear Namespace Event In Skill") - get_skill_namespace = message.data.get("skill_id", "") - if get_skill_namespace: - self.bus.emit(Message("gui.clear.namespace", - {"__from": get_skill_namespace})) - - -class MobileExtension: - """ Mobile Platform Extension: This extension is responsible for managing the mobile GUI behaviours. - This extension adds support for Homescreens and Homescreen Management and global page back navigation. - - Args: - bus: MessageBus instance - gui: GUI instance - preload_gui (bool): load GUI skills even if gui client not connected - permanent (bool): disable unloading of GUI skills on gui client disconnections - """ - - def __init__(self, bus, gui, preload_gui=True, permanent=True): - LOG.info("Mobile: Initializing") - - self.bus = bus - self.gui = gui - self.preload_gui = preload_gui - self.permanent = permanent - self.homescreen_manager = HomescreenManager(self.bus, self.gui) - - self.homescreen_thread = threading.Thread( - target=self.homescreen_manager.run) - self.homescreen_thread.start() - - self.gui_interface = MobileExtensionGuiInterface( - self.bus, self.homescreen_manager) - - self.bus.on('mycroft.gui.screen.close', - self.force_idle_screen) - self.bus.on('mycroft.gui.forceHome', - self.force_home) - self.bus.on('mycroft.gui.screen.request.page.back', - self.handle_page_back) - - def force_idle_screen(self, message): - self.homescreen_manager.show_homescreen() - - def force_home(self, message): - self.homescreen_manager.show_homescreen() - - def handle_page_back(self, message): - self.gui.handle_namespace_global_back({}) - - -class PlasmoidExtension: - """ Plasmoid Platform Extension: This extension is responsible for managing the generic GUI behaviours - for non specific platforms. The generic extension does optionally support Homescreen and Homescreen - Management but it needs to be exclusively enabled in the configuration file. - - Args: - bus: MessageBus instance - gui: GUI instance - preload_gui (bool): load GUI skills even if gui client not connected - permanent (bool): disable unloading of GUI skills on gui client disconnections - """ - - def __init__(self, bus, gui, preload_gui=False, permanent=True): - LOG.info("Plasmoid: Initializing") - - self.bus = bus - self.gui = gui - self.preload_gui = preload_gui - self.permanent = permanent - core_config = Configuration() - gui_config = core_config.get("gui") or {} - generic_config = gui_config.get("plasmoid", {}) - self.homescreen_supported = generic_config.get("homescreen_supported", False) - - if self.homescreen_supported: - self.homescreen_manager = HomescreenManager(self.bus, self.gui) - self.homescreen_thread = threading.Thread( - target=self.homescreen_manager.run) - self.homescreen_thread.start() - - try: - self.bus.on("mycroft.gui.screen.close", - self.handle_remove_namespace) - - except Exception as e: - LOG.error(f"Plasmoid: Init Bus Exception: {e}") - - def handle_remove_namespace(self, message): - LOG.info("Got Clear Namespace Event In Skill") - get_skill_namespace = message.data.get("skill_id", "") - if get_skill_namespace: - self.bus.emit(Message("gui.clear.namespace", - {"__from": get_skill_namespace})) diff --git a/ovos_gui/homescreen.py b/ovos_gui/homescreen.py index 9427f26..e5ba6b3 100644 --- a/ovos_gui/homescreen.py +++ b/ovos_gui/homescreen.py @@ -1,14 +1,16 @@ -from ovos_bus_client import Message +from ovos_bus_client import Message, MessageBusClient from ovos_config.config import Configuration, LocalConf from ovos_config.locations import USER_CONFIG from ovos_utils.log import LOG from ovos_gui.namespace import NamespaceManager +from threading import Thread -class HomescreenManager: +class HomescreenManager(Thread): - def __init__(self, bus, gui): + def __init__(self, bus: MessageBusClient, gui: NamespaceManager): + super().__init__() self.bus = bus self.gui = gui self.homescreens = [] @@ -16,10 +18,8 @@ def __init__(self, bus, gui): self.bus.on('homescreen.manager.add', self.add_homescreen) self.bus.on('homescreen.manager.remove', self.remove_homescreen) self.bus.on('homescreen.manager.list', self.get_homescreens) - self.bus.on("homescreen.manager.get_active", - self.get_active_homescreen) - self.bus.on("homescreen.manager.set_active", - self.set_active_homescreen) + self.bus.on("homescreen.manager.get_active", self.get_active_homescreen) + self.bus.on("homescreen.manager.set_active", self.set_active_homescreen) self.bus.on("homescreen.manager.disable_active", self.disable_active_homescreen) self.bus.on("mycroft.mark2.register_idle", @@ -83,6 +83,7 @@ def reload_homescreens_list(self): def show_homescreen_on_add(self, homescreen_id, homescreen_class): if self.mycroft_ready == True: active_homescreen = self.get_active_homescreen() + LOG.debug(f"Requesting activation of {active_homescreen}") if active_homescreen == homescreen_id: if homescreen_class == "IdleDisplaySkill": LOG.debug( @@ -104,16 +105,19 @@ def disable_active_homescreen(self, message): def show_homescreen(self, message=None): active_homescreen = self.get_active_homescreen() + LOG.debug(f"Requesting activation of {active_homescreen}") for h in self.homescreens: if h["id"] == active_homescreen: if h["class"] == "IdleDisplaySkill": LOG.debug( - f"Homescreen Manager: Displaying Homescreen {active_homescreen}") + f"Homescreen Manager: Displaying Homescreen " + f"{active_homescreen}") self.bus.emit(Message("homescreen.manager.activate.display", { "homescreen_id": active_homescreen})) elif h["class"] == "MycroftSkill": LOG.debug( - f"Homescreen Manager: Displaying Homescreen {active_homescreen}") + f"Homescreen Manager: Displaying Homescreen " + f"{active_homescreen}") self.bus.emit(Message("{}.idle".format(active_homescreen))) def set_mycroft_ready(self, message): @@ -133,7 +137,7 @@ def register_old_style_homescreen(self, message): skill_id = message.data["id"] _homescreen_entry = {"class": super_class_name, "name": super_class_object, "id": skill_id} - LOG.debug("Homescreen Manager: Adding OLD Homescreen {skill_id}") + LOG.debug(f"Homescreen Manager: Adding OLD Homescreen {skill_id}") self.add_homescreen( Message("homescreen.manager.add", _homescreen_entry)) else: diff --git a/ovos_gui/interfaces/mobile.py b/ovos_gui/interfaces/mobile.py deleted file mode 100644 index cdd894b..0000000 --- a/ovos_gui/interfaces/mobile.py +++ /dev/null @@ -1,22 +0,0 @@ -from ovos_utils.gui import GUIInterface - - -class MobileExtensionGuiInterface(GUIInterface): - def __init__(self, bus, homescreen_manager) -> None: - super(MobileExtensionGuiInterface, self).__init__( - skill_id="MobileExtension.GuiInterface") - self.bus = bus - self.homescreen_manager = homescreen_manager - - # Initiate Bind - self.bind() - - def bind(self): - super().set_bus(self.bus) - self.register_handler("mycroft.device.show.idle", - self.handle_show_homescreen) - self.register_handler('mycroft.gui.screen.close', - self.handle_show_homescreen) - - def handle_show_homescreen(self, message): - self.homescreen_manager.show_homescreen() diff --git a/ovos_gui/interfaces/smartspeaker.py b/ovos_gui/interfaces/smartspeaker.py deleted file mode 100644 index 319a345..0000000 --- a/ovos_gui/interfaces/smartspeaker.py +++ /dev/null @@ -1,242 +0,0 @@ -import json -import platform -from os.path import exists, join - -from json_database import JsonStorage -from ovos_bus_client import Message -from ovos_utils import network_utils -from ovos_utils.fingerprinting import get_mycroft_version -from ovos_utils.gui import GUIInterface -from ovos_utils.log import LOG -from ovos_utils.xdg_utils import xdg_config_home - - -class SmartSpeakerExtensionGuiInterface(GUIInterface): - def __init__(self, bus, homescreen_manager) -> None: - super(SmartSpeakerExtensionGuiInterface, self).__init__( - skill_id="SmartSpeakerExtension.GuiInterface") - self.bus = bus - self.homescreen_manager = homescreen_manager - - # Paths to find the local display config - self.display_config_path_local = join(xdg_config_home(), "OvosDisplay.conf") - self.display_config_path_system = "/etc/xdg/OvosDisplay.conf" - self.local_display_config = JsonStorage(self.display_config_path_local) - self.about_page_data = [] - - if not exists(self.display_config_path_local): - self.handle_display_config_load() - - # Initiate Bind - self.bind() - - def bind(self): - super().set_bus(self.bus) - - self.bus.on("mycroft.device.settings", self.handle_device_settings) - self.bus.on("ovos.PHAL.dashboard.status.response", - self.update_device_dashboard_status) - - self.bus.on("ovos.phal.configuration.provider.get.response", - self.display_advanced_config_for_group) - self.bus.on("ovos.phal.configuration.provider.list.groups.response", - self.display_advanced_config_groups) - self.bus.on("smartspeaker.extension.extend.about", - self.extend_about_page_data_from_event) - - self.register_handler("mycroft.device.settings", - self.handle_device_settings) - self.register_handler( - "mycroft.device.settings.homescreen", self.handle_device_homescreen_settings) - self.register_handler("mycroft.device.settings.ssh", - self.handle_device_ssh_settings) - self.register_handler( - "mycroft.device.settings.developer", self.handle_device_developer_settings) - self.register_handler("mycroft.device.enable.dash", - self.handle_device_developer_enable_dash) - self.register_handler("mycroft.device.disable.dash", - self.handle_device_developer_disable_dash) - self.register_handler("mycroft.device.show.idle", - self.handle_show_homescreen) - self.register_handler("mycroft.device.settings.customize", - self.handle_device_customize_settings) - self.register_handler("mycroft.device.settings.create.theme", - self.handle_device_create_theme) - self.register_handler("mycroft.device.settings.about.page", - self.handle_device_about_page) - self.register_handler("mycroft.device.settings.display", - self.handle_device_display_settings) - self.register_handler("mycroft.device.settings.factory", - self.handle_device_display_factory) - - # Display settings - self.register_handler("speaker.extension.display.set.wallpaper.rotation", - self.handle_display_wallpaper_rotation_config_set) - self.register_handler("speaker.extension.display.set.auto.dim", - self.handle_display_auto_dim_config_set) - self.register_handler("speaker.extension.display.set.auto.nightmode", - self.handle_display_auto_nightmode_config_set) - - self.build_initial_about_page_data() - - def handle_device_settings(self, message): - """ Display device settings page. """ - self["state"] = "settings/settingspage" - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_device_homescreen_settings(self, message): - """ - display homescreen settings page - """ - screens = self.homescreen_manager.homescreens - self["idleScreenList"] = {"screenBlob": screens} - self["selectedScreen"] = self.homescreen_manager.get_active_homescreen() - self["state"] = "settings/homescreen_settings" - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_device_ssh_settings(self, message): - """ - display ssh settings page - """ - self["state"] = "settings/ssh_settings" - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_set_homescreen(self, message): - """ - Set the homescreen to the selected screen - """ - homescreen_id = message.data.get("homescreen_id", "") - if homescreen_id: - self.homescreen_manager.set_active_homescreen(homescreen_id) - - def handle_show_homescreen(self, message): - self.homescreen_manager.show_homescreen() - - def handle_device_developer_settings(self, message): - self['state'] = 'settings/developer_settings' - self.handle_get_dash_status() - - def handle_device_developer_enable_dash(self, message): - self.bus.emit(Message("ovos.PHAL.dashboard.enable")) - - def handle_device_developer_disable_dash(self, message): - self.bus.emit(Message("ovos.PHAL.dashboard.disable")) - - def update_device_dashboard_status(self, message): - call_check = message.data.get("status", False) - dash_security_pass = message.data.get("password", "") - dash_security_user = message.data.get("username", "") - dash_url = message.data.get("url", "") - if call_check: - self["dashboard_enabled"] = call_check - self["dashboard_url"] = dash_url - self["dashboard_user"] = dash_security_user - self["dashboard_password"] = dash_security_pass - else: - self["dashboard_enabled"] = call_check - self["dashboard_url"] = "" - self["dashboard_user"] = "" - self["dashboard_password"] = "" - - def handle_device_customize_settings(self, message): - self['state'] = 'settings/customize_settings' - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_device_create_theme(self, message): - self['state'] = 'settings/customize_theme' - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_device_display_factory(self, message): - self['state'] = 'settings/factory_settings' - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_device_display_settings(self, message): - LOG.info("Display settings") - LOG.info(self.local_display_config) - - self['state'] = 'settings/display_settings' - self['display_wallpaper_rotation'] = self.local_display_config.get("wallpaper_rotation", False) - self['display_auto_dim'] = self.local_display_config.get("auto_dim", False) - self['display_auto_nightmode'] = self.local_display_config.get("auto_nightmode", False) - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_device_about_page(self, message): - # TODO: Move `system_information` generation to util method - uname_info = platform.uname() - system_information = {"display_list": self.about_page_data} - self['state'] = 'settings/about_page' - self['system_info'] = system_information - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_display_wallpaper_rotation_config_set(self, message): - wallpaper_rotation = message.data.get("wallpaper_rotation", False) - self.local_display_config["wallpaper_rotation"] = wallpaper_rotation - self.local_display_config.store() - self.bus.emit(Message("speaker.extension.display.wallpaper.rotation.changed")) - - def handle_display_auto_dim_config_set(self, message): - auto_dim = message.data.get("auto_dim", False) - self.local_display_config["auto_dim"] = auto_dim - self.local_display_config.store() - self.bus.emit(Message("speaker.extension.display.auto.dim.changed")) - - def handle_display_auto_nightmode_config_set(self, message): - auto_nightmode = message.data.get("auto_nightmode", False) - self.local_display_config["auto_nightmode"] = auto_nightmode - self.local_display_config.store() - self.bus.emit(Message("speaker.extension.display.auto.nightmode.changed")) - - def handle_display_config_load(self): - if exists(self.display_config_path_system): - LOG.info("Loading display config from system") - with open(self.display_config_path_system, "r") as f: - writeable_conf = json.load(f) - self.local_display_config["wallpaper_rotation"] = writeable_conf["wallpaper_rotation"] - self.local_display_config["auto_dim"] = writeable_conf["auto_dim"] - self.local_display_config["auto_nightmode"] = writeable_conf["auto_nightmode"] - self.local_display_config.store() - - def display_advanced_config_for_group(self, message=None): - group_meta = message.data.get("settingsMetaData") - group_name = message.data.get("groupName") - self["groupName"] = group_name - self["groupConfigurationData"] = group_meta - self['state'] = 'settings/configuration_generator_display' - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def display_advanced_config_groups(self, message=None): - groups_list = message.data.get("groups") - self["groupList"] = groups_list - self['state'] = 'settings/configuration_groups_display' - self.show_page("SYSTEM_AdditionalSettings.qml", override_idle=True) - - def handle_get_dash_status(self): - self.bus.emit(Message("ovos.PHAL.dashboard.get.status")) - - def build_initial_about_page_data(self): - uname_info = platform.uname() - version = get_mycroft_version() or "unknown" - self.about_page_data.append({"display_key": "Kernel Version", "display_value": uname_info[2]}) - self.about_page_data.append({"display_key": "Core Version", "display_value": version}) - self.about_page_data.append({"display_key": "Python Version", "display_value": platform.python_version()}) - self.about_page_data.append({"display_key": "Local Address", "display_value": network_utils.get_ip()}) - - def check_about_page_data_contains_key(self, key): - for item in self.about_page_data: - if item["display_key"] == key: - return True - return False - - def add_about_page_data(self, key, value): - if not self.check_about_page_data_contains_key(key): - self.about_page_data.append({"display_key": key, "display_value": value}) - else: - for item in self.about_page_data: - if item["display_key"] == key: - item["display_value"] = value - break - - def extend_about_page_data_from_event(self, message=None): - extended_list = message.data.get("display_list") - for item in extended_list: - self.add_about_page_data(item["display_key"], item["display_value"]) diff --git a/ovos_gui/namespace.py b/ovos_gui/namespace.py index 5ec726f..094dfb7 100644 --- a/ovos_gui/namespace.py +++ b/ovos_gui/namespace.py @@ -39,9 +39,9 @@ code. Changes to namespaces, and their contents, are communicated to the GUI over the GUI message bus. """ -import sys + from threading import Lock, Timer -from time import time, sleep +from time import sleep from typing import List, Union from ovos_config.config import Configuration @@ -84,7 +84,7 @@ def __init__(self, name: str): self.name = name self.persistent = False self.duration = 30 - self.pages = list() + self.pages: List[GuiPage] = list() self.data = dict() self.page_number = 0 self.session_set = False @@ -196,8 +196,9 @@ def set_persistence(self, skill_type: str): self.persistent = False self.duration = 30 - def load_pages(self, pages: List[str], show_index: None): - """Maintains a list of active pages within the active namespace. + def load_pages(self, pages: List[GuiPage], show_index: int = 0): + """ + Maintains a list of active pages within the active namespace. Skills with multiple pages of data can either show all the screens at once, allowing the user to swipe back and forth among them, or @@ -206,7 +207,11 @@ def load_pages(self, pages: List[str], show_index: None): Args: pages: one or more pages to be displayed + show_index: index of page to display (default 0) """ + if show_index is None: + LOG.warning(f"Expected int show_index but got `None`. Default to 0") + show_index = 0 new_pages = list() for page in pages: @@ -216,16 +221,12 @@ def load_pages(self, pages: List[str], show_index: None): self.pages.extend(new_pages) if new_pages: self._add_pages(new_pages) - else: - page = pages[0] - if show_index: - self._activate_page(pages[show_index]) - else: - self._activate_page(pages[0]) + self._activate_page(pages[show_index]) - def _add_pages(self, new_pages: List[str]): - """Adds once or more pages to the active page list. + def _add_pages(self, new_pages: List[GuiPage]): + """ + Adds one or more pages to the active page list. Args: new_pages: pages to add to the active page list @@ -248,8 +249,9 @@ def _add_pages(self, new_pages: List[str]): ) send_message_to_gui(message) - def _activate_page(self, page: str): - """Returns focus to a page already in the active page list. + def _activate_page(self, page: GuiPage): + """ + Returns focus to a page already in the active page list. Args: page: the page that will gain focus @@ -313,12 +315,13 @@ def page_gained_focus(self, page_number): f"Page {page_number} gained focus in GUI namespace {self.name}") self._activate_page(self.pages[page_number]) - def page_update_interaction(self, page_number): + def page_update_interaction(self, page_number: int): """Update the interaction of the page_number""" LOG.info( f"Page {page_number} update interaction in GUI namespace {self.name}") - page = self.pages.index(page_number) + + page = self.pages[page_number] if not page.persistent and page.duration > 0: page.duration = page.duration / 2 @@ -331,7 +334,10 @@ def get_page_at_position(self, position: int): return self.pages.index(position) def get_active_page(self): - """Returns the currently active page from self.pages where the page attribute active is true""" + """ + Returns the currently active page from `self.pages` where the page + attribute active is true + """ for page in self.pages: if page.active: return page @@ -354,7 +360,8 @@ def global_back(self): def _validate_page_message(message: Message): - """Validates the contents of the message data for page add/remove messages. + """ + Validates the contents of the message data for page add/remove messages. Args: message: A core message bus message to add/remove one or more pages @@ -379,27 +386,30 @@ def _validate_page_message(message: Message): def _get_idle_display_config(): - """Retrieves the current value of the idle display skill configuration.""" - LOG.info("Getting Idle Skill From Config") + """ + Retrieves the current value of the idle display skill configuration. + """ config = Configuration() enclosure_config = config.get("gui") or {} idle_display_skill = enclosure_config.get("idle_display_skill") - + LOG.info(f"Got idle_display_skill from config: {idle_display_skill}") return idle_display_skill def _get_active_gui_extension(): - """Retrieves the current value of the gui extension configuration. """ - LOG.info("Getting GUI Extension From Config") + """ + Retrieves the current value of the gui extension configuration. + """ config = Configuration() enclosure_config = config.get("gui") or {} gui_extension = enclosure_config.get("extension", "generic") - + LOG.info(f"Got extension from config: {gui_extension}") return gui_extension.lower() class NamespaceManager: - """Manages the active namespace stack and the content of namespaces. + """ + Manages the active namespace stack and the content of namespaces. Attributes: core_bus: client for communicating with the core message bus @@ -580,7 +590,7 @@ def _ensure_namespace_exists(self, namespace_name: str) -> Namespace: return namespace - def _load_pages(self, pages_to_show: str, show_index: None): + def _load_pages(self, pages_to_show: List[GuiPage], show_index: None): """Loads the requested pages in the namespace. Args: @@ -651,12 +661,13 @@ def _remove_namespace_via_timer(self, namespace_name: str): self._del_namespace_in_remove_timers(namespace_name) def _remove_namespace(self, namespace_name: str): - """Removes a namespace from the active namespace stack. + """ + Removes a namespace from the active namespace stack. Args: namespace_name: namespace to remove """ - LOG.debug("Removing namespace {namespace_name}") + LOG.debug(f"Removing namespace {namespace_name}") # Remove all timers associated with the namespace if namespace_name in self.remove_namespace_timers: diff --git a/ovos_gui/res/ui/settings/SettingsModel.qml b/ovos_gui/res/ui/settings/SettingsModel.qml deleted file mode 100644 index 44937c0..0000000 --- a/ovos_gui/res/ui/settings/SettingsModel.qml +++ /dev/null @@ -1,46 +0,0 @@ -import QtQuick.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.0 -import org.kde.kirigami 2.5 as Kirigami -import Mycroft 1.0 as Mycroft - -ListModel { - id: settingsListModel - - ListElement { - settingIcon: "images/home.svg" - settingName: QT_TR_NOOP("Homescreen Settings") - settingEvent: "mycroft.device.settings.homescreen" - settingCall: "show homescreen settings" - } - ListElement { - settingIcon: "images/paint.svg" - settingName: QT_TR_NOOP("Customize") - settingEvent: "mycroft.device.settings.customize" - settingCall: "" - } - ListElement { - settingIcon: "images/display.svg" - settingName: QT_TR_NOOP("Display") - settingEvent: "mycroft.device.settings.display" - settingCall: "" - } - ListElement { - settingIcon: "images/ssh.svg" - settingName: QT_TR_NOOP("Enable SSH") - settingEvent: "mycroft.device.settings.ssh" - settingCall: "show ssh settings" - } - ListElement { - settingIcon: "images/settings.png" - settingName: QT_TR_NOOP("Developer Settings") - settingEvent: "mycroft.device.settings.developer" - settingCall: "" - } - ListElement { - settingIcon: "images/info.svg" - settingName: QT_TR_NOOP("About") - settingEvent: "mycroft.device.settings.about.page" - settingCall: "" - } -} diff --git a/ovos_gui/res/ui/settings/ThemeView.qml b/ovos_gui/res/ui/settings/ThemeView.qml deleted file mode 100644 index 98b76e6..0000000 --- a/ovos_gui/res/ui/settings/ThemeView.qml +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -ItemDelegate { - id: themeViewer - property bool darkMode: false - property var modelDataStyle: darkMode ? "dark" : "light" - property color viewPrimaryColor - property color viewSecondaryColor - property color viewTextColor - property string themeName - property bool clickEnabled: true - - background: Rectangle { - color: darkMode ? themeViewer.viewPrimaryColor : themeViewer.viewTextColor - border.color: themeViewer.viewSecondaryColor - border.width: 3 - radius: 10 - } - - Item { - id: d1itemThemeView - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - height: parent.height * 0.70 - - GridLayout { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - columns: 2 - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: darkMode ? themeViewer.viewPrimaryColor : themeViewer.viewTextColor - border.width: 2 - border.color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - - Text { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: "P" - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 40 - color: darkMode ? themeViewer.viewTextColor : themeViewer.viewPrimaryColor - font.bold: true - } - } - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: themeViewer.viewSecondaryColor - border.width: 2 - border.color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - - Text { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: "S" - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 40 - color: darkMode ? themeViewer.viewTextColor : themeViewer.viewPrimaryColor - font.bold: true - } - } - Rectangle{ - Layout.fillWidth: true - Layout.fillHeight: true - color: darkMode ? themeViewer.viewTextColor : themeViewer.viewPrimaryColor - border.width: 2 - border.color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - - Text { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: "T" - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 40 - color: darkMode ? themeViewer.viewPrimaryColor : themeViewer.viewTextColor - font.bold: true - } - } - Rectangle{ - Layout.fillWidth: true - Layout.fillHeight: true - radius: 15 - color: themeViewer.viewSecondaryColor - border.width: 2 - border.color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - - Rectangle { - color: darkMode ? themeViewer.viewPrimaryColor : themeViewer.viewTextColor - anchors.centerIn: parent - width: parent.width - 4 - height: parent.height / 4 - - Label { - anchors.centerIn: parent - fontSizeMode: Text.HorizontalFit - font.pixelSize: 32 - minimumPixelSize: 4 - font.bold: true - color: darkMode ? themeViewer.viewTextColor : themeViewer.viewPrimaryColor - text: darkMode ? "Style 1" : "Style 2" - } - } - } - } - } - - Kirigami.Separator { - id: cardSeptThemeView - anchors.top: d1itemThemeView.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: 2 - anchors.rightMargin: 2 - height: 16 - color: themeViewer.viewSecondaryColor - } - - Item { - id: d2itemThemeView - anchors.top: cardSeptThemeView.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - clip: true - - Label { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 20 - minimumPixelSize: 5 - fontSizeMode: Text.Fit - maximumLineCount: 1 - text: themeViewer.themeName - color: darkMode ? themeViewer.viewTextColor : themeViewer.viewPrimaryColor - elide: Text.ElideRight - } - } - - onClicked: { - if(clickEnabled){ - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - styleViewPopUp.setTheme(modelDataStyle) - styleViewPopUp.close() - Mycroft.MycroftController.sendRequest("ovos.theme.get", {}) - } - } -} diff --git a/ovos_gui/res/ui/settings/about_page.qml b/ovos_gui/res/ui/settings/about_page.qml deleted file mode 100644 index d3fdc51..0000000 --- a/ovos_gui/res/ui/settings/about_page.qml +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Item { - id: customizeSettingsView - anchors.fill: parent - property var systemInformation: sessionData.system_info - - function get_translated_string(entry) { - if(entry.indexOf("Kernel Version") != -1) { - return qsTr("Kernel Version") - } - if(entry.indexOf("Version") != -1) { - var e = entry.split(" ") - return e[0] + " " + qsTr("Version") - } - if(entry.indexOf("Local Address") != -1) { - return qsTr("Local Address") - } - else { - return qsTr(entry) - } - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: idleSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("About") - color: Kirigami.Theme.textColor - } - } - - Item { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - - Rectangle { - id: sysInfoHeaderBox - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Mycroft.Units.gridUnit * 4 - color: Kirigami.Theme.highlightColor - - Kirigami.Heading { - font.pixelSize: 25 - fontSizeMode: Text.Fit - minimumPixelSize: 5 - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignLeft - verticalAlignment: Text.AlignVCenter - level: 2 - wrapMode: Text.WordWrap - font.bold: true - font.weight: Font.ExtraBold - text: qsTr("System Information") - color: Kirigami.Theme.textColor - } - } - - ListView { - anchors.top: sysInfoHeaderBox.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: Mycroft.Units.gridUnit / 2 - clip: true - model: systemInformation.display_list - spacing: Mycroft.Units.gridUnit / 2 - delegate: Label { - text: "" + get_translated_string(modelData.display_key) + ": " + modelData.display_value - font.pixelSize: 25 - fontSizeMode: Text.Fit - minimumPixelSize: 5 - color: Kirigami.Theme.textColor - Layout.alignment: Qt.AlignLeft - - Component.onCompleted: { - if(modelData.display_key.indexOf("Local Address") != -1){ - if(!modelData.display_value) { - text = "" + qsTr("Local Address") + ": " + qsTr("No Active Connection") - } - } - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Device Settings") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - triggerGuiEvent("mycroft.device.settings", {}) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/code/colorUtils.js b/ovos_gui/res/ui/settings/code/colorUtils.js deleted file mode 100644 index effbaa0..0000000 --- a/ovos_gui/res/ui/settings/code/colorUtils.js +++ /dev/null @@ -1,67 +0,0 @@ -// creates color value from hue, saturation, brightness, alpha -function _hsla(h, s, b, a) { - var lightness = (2 - s)*b - var satHSL = s*b/((lightness <= 1) ? lightness : 2 - lightness) - lightness /= 2 - var c = Qt.hsla(h, satHSL, lightness, a) - colorChanged(c) - return c -} - -// create rgb value -function _rgb(rgb, a) { - var c = Qt.rgba(rgb.r, rgb.g, rgb.b, a) - colorChanged(c) - return c -} - -// creates a full color string from color value and alpha[0..1], e.g. "#FF00FF00" -function _fullColorString(clr, a) { - return "#" + ((Math.ceil(a*255) + 256).toString(16).substr(1, 2) + clr.toString().substr(1, 6)).toUpperCase() -} - -// extracts integer color channel value [0..255] from color value -function _getChannelStr(clr, channelIdx) { - return parseInt(clr.toString().substr(channelIdx*2 + 1, 2), 16) -} - -// set color from outside -function setColor(color) { - // color object - var c = Qt.tint(color, "transparent") - console.debug('set_color is called with:'+c) - // set rgb. Now it's insufficient to update hue related component. - colorPicker.colorValue = c -} - -// As defined in WCAG 2.1 -var relativeLuminance = function (R8bit, G8bit, B8bit) { - var RsRGB = R8bit / 255.0; - var GsRGB = G8bit / 255.0; - var BsRGB = B8bit / 255.0; - - var R = (RsRGB <= 0.03928) ? RsRGB / 12.92 : Math.pow((RsRGB + 0.055) / 1.055, 2.4); - var G = (GsRGB <= 0.03928) ? GsRGB / 12.92 : Math.pow((GsRGB + 0.055) / 1.055, 2.4); - var B = (BsRGB <= 0.03928) ? BsRGB / 12.92 : Math.pow((BsRGB + 0.055) / 1.055, 2.4); - - return 0.2126 * R + 0.7152 * G + 0.0722 * B; -}; - -function blackContrast(r, g, b) { - var L = relativeLuminance(r, g, b); - return (L + 0.05) / 0.05; -}; - -function whiteContrast(r, g, b) { - var L = relativeLuminance(r, g, b); - return 1.05 / (L + 0.05); -}; - -function autoTextColor(r, g, b) { - var prefer = "#ffffff" - var Cb = blackContrast(r * 255, g * 255, b * 255); - var Cw = whiteContrast(r * 255, g * 255, b * 255); - console.log(Cb, Cw) - if(Cb >= 7.0 && Cw >= 7.0) return prefer; - else return (Cb > Cw) ? '#000000' : '#ffffff' -} diff --git a/ovos_gui/res/ui/settings/configuration_generator_display.qml b/ovos_gui/res/ui/settings/configuration_generator_display.qml deleted file mode 100644 index 8430118..0000000 --- a/ovos_gui/res/ui/settings/configuration_generator_display.qml +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright 2022 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import org.kde.kirigami 2.11 as Kirigami -import QtGraphicalEffects 1.0 -import Mycroft 1.0 as Mycroft - -Item { - id: configurationLoaderView - anchors.fill: parent - property var configurationData: sessionData.groupConfigurationData - property var groupName: sessionData.groupName - property var updateFieldList: [] - - function selectSettingUpdated(modelData, key, value) { - modelData.field_value = value - var index = updateFieldList.findIndex(function(item) { - return item.field_name == modelData.field_name - }) - if (index == -1) { - updateFieldList.push(modelData) - } else { - updateFieldList[index].field_value = value - } - } - - function generate_settings_ui(mData, comp) { - console.log(mData.field_type, comp) - - if (mData.field_type == "bool") { - var newObject = Qt.createComponent("configuration_ui/settingCheckBox.qml") - var fieldDisplay = newObject.createObject(comp, {checked: mData.field_value.toString() == "true" ? 1 : 0, text: mData.field_value == "true" ? "Disable" : "Enable", "key": mData.field_name, "value": mData.field_value, "modelData": mData}); - fieldDisplay.fieldUpdated.connect(selectSettingUpdated) - } - if (mData.field_type == "str" || mData.field_type == "int" || mData.field_type == "float") { - var newObject = Qt.createComponent("configuration_ui/settingTextBox.qml") - var fieldDisplay = newObject.createObject(comp, {text: mData.field_value, "key": mData.field_name, "value": mData.field_value, "modelData": mData}); - fieldDisplay.fieldUpdated.connect(selectSettingUpdated) - } - if (mData.field_type == "list") { - var listObject = [] - for (var lst=0; lst < mData.field_value.length; lst++){ - listObject.push(mData.field_value[lst]) - } - console.log(listObject) - var newObject = Qt.createComponent("configuration_ui/settingListBox.qml") - var fieldDisplay = newObject.createObject(comp, {"value": mData.field_value, "key": mData.field_name, "modelData": mData}); - fieldDisplay.fieldUpdated.connect(selectSettingUpdated) - } - } - - function sanitize_values(mValues) { - var val_listing = [] - for (var i = 0; i < mValues.length; i++) { - if (mValues[i].includes('|')) { - var splitVals = mValues[i].split("|")[1] - val_listing.push(splitVals.toLowerCase()) - } else { - val_listing.push(mValues[i]) - } - } - return val_listing - } - - onConfigurationDataChanged: { - configDataView.update() - if(configurationData !== null){ - configDataView.model = configurationData.group_sections - configPageHeading.text = groupName.toUpperCase() + " " + qsTr("Configuration") - } - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: configPageHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.capitalization: Font.Capitalize - font.bold: true - color: Kirigami.Theme.linkColor - } - } - - Flickable { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - anchors.bottomMargin: Kirigami.Units.smallSpacing - contentHeight: scvGrid.implicitHeight - clip: true - - GridLayout { - id: scvGrid - width: parent.width - columns: scvGrid.width > 850 ? 2 : 1 - rowSpacing: Kirigami.Units.smallSpacing - - Repeater { - id: configDataView - clip: true - - delegate: Control { - id: delegateRoot - Layout.alignment: Qt.AlignTop - Layout.fillWidth: true - - background: Rectangle { - color: Qt.darker(Kirigami.Theme.backgroundColor, 2) - radius: 10 - } - - contentItem: Item { - implicitWidth: scvGrid.width > 850 ? scvGrid.width / 2 : scvGrid.width - implicitHeight: delegateLayout.implicitHeight + Kirigami.Units.largeSpacing - - ColumnLayout { - id: delegateLayout - anchors.left: parent.left - anchors.right: parent.right - spacing: Kirigami.Units.largeSpacing - - Rectangle { - id: skillNameBlock - color: Kirigami.Theme.linkColor - Layout.fillWidth: true - Layout.margins: Kirigami.Units.largeSpacing - Layout.preferredHeight: skillName.contentHeight + Kirigami.Units.smallSpacing - radius: 3 - - Kirigami.Heading { - id: skillName - elide: Text.ElideRight - font.weight: Font.DemiBold - text: modelData.section_label - width: parent.width - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - level: 2 - } - } - - Repeater { - id: sectionFieldsDisplay - model: modelData.section_fields - - delegate: GridLayout { - id: configGridBox - Layout.fillWidth: true - Layout.margins: Kirigami.Units.largeSpacing / 2 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - - columns: switch(modelData.field_type) { - case "str": - if(modelData.field_description.length > 2){ - return 1; - } else { - return 2; - } - case "bool": - if(modelData.field_description.length > 2){ - return 1; - } else { - return 2; - } - case "list": return 1; - default: return 2; - } - - Kirigami.Heading { - id: configTopFieldLabel - Layout.alignment: Qt.AlignLeft - elide: Text.ElideRight - text: modelData.field_label - Layout.fillWidth: true - wrapMode: Text.WordWrap; - font.capitalization: Font.Capitalize - textFormat: Text.AutoText - level: 3 - } - - Label { - id: configTopFieldDescription - Layout.alignment: Qt.AlignLeft - Layout.fillWidth: true - wrapMode: Text.WordWrap; - elide: Text.ElideRight - text: modelData.field_description - visible: modelData.field_description.length > 2 ? 1 : 0 - enabled: modelData.field_description.length > 2 ? 1 : 0 - font.pixelSize: configTopFieldLabel.font.pixelSize * 0.75 - } - - ButtonGroup { - id: settingGroup - } - - Component.onCompleted: { - generate_settings_ui(modelData, configGridBox) - configDataView.update() - } - } - } - } - } - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - Item { - anchors.top: areaSep.bottom - anchors.bottom: parent.bottom - width: parent.width / 2 - anchors.left: parent.left - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Back") - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("ovos.phal.configuration.provider.list.groups", {}) - } - } - } - - Item { - anchors.top: areaSep.bottom - anchors.bottom: parent.bottom - width: parent.width / 2 - anchors.right: parent.right - - RowLayout { - anchors.fill: parent - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Update Settings") - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - - Kirigami.Icon { - id: nextIcon - source: "run-build-configure" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - Layout.alignment: Qt.AlignRight - - ColorOverlay { - anchors.fill: parent - source: nextIcon - color: Kirigami.Theme.textColor - } - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("ovos.phal.configuration.provider.set", {"configuration": configurationLoaderView.updateFieldList, "group_name": configurationLoaderView.groupName}) - Mycroft.MycroftController.sendRequest("ovos.phal.configuration.provider.list.groups", {}) - } - } - } - } -} diff --git a/ovos_gui/res/ui/settings/configuration_groups_display.qml b/ovos_gui/res/ui/settings/configuration_groups_display.qml deleted file mode 100644 index 42aee52..0000000 --- a/ovos_gui/res/ui/settings/configuration_groups_display.qml +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2022 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.kirigami 2.5 as Kirigami -import Mycroft 1.0 as Mycroft -import QtGraphicalEffects 1.12 - -Item { - id: advancedConfigurationGroupsView - anchors.fill: parent - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: advancedConfigurationGroupsViewHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Advanced Configuration") - color: Kirigami.Theme.textColor - } - } - - ColumnLayout { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - anchors.bottomMargin: Kirigami.Units.largeSpacing - - Kirigami.Heading { - id: warnText - level: 3 - Layout.fillWidth: true - wrapMode: Text.WordWrap - color: Kirigami.Theme.textColor - text: " All configuration changes made here can alter the functionality of your device, some changes might also require a reboot to take affect " - } - - Item { - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.largeSpacing - } - - ListView { - Layout.fillWidth: true - Layout.fillHeight: true - clip: true - model: sessionData.groupList - boundsBehavior: Flickable.StopAtBounds - - delegate: Kirigami.AbstractListItem { - activeBackgroundColor: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.7) - contentItem: Item { - implicitWidth: delegateLayout.implicitWidth; - implicitHeight: delegateLayout.implicitHeight; - - RowLayout { - id: delegateLayout - spacing: Mycroft.Units.gridUnit / 2 - - anchors { - left: parent.left; - top: parent.top; - right: parent.right; - } - - Kirigami.Icon { - id: iconGroupHolder - source: "beamerblock" - Layout.preferredWidth: Mycroft.Units.gridUnit * 2 - Layout.preferredHeight: Mycroft.Units.gridUnit * 2 - - ColorOverlay { - anchors.fill: parent - source: iconGroupHolder - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.7) - } - } - - Kirigami.Heading { - id: connectionNameLabel - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - verticalAlignment: Text.AlignVCenter - height: paintedHeight - elide: Text.ElideRight - font.weight: Font.DemiBold - font.capitalization: Font.Capitalize - text: modelData.replace("_", " ") - textFormat: Text.PlainText - color: Kirigami.Theme.textColor - level: 2 - } - } - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("ovos.phal.configuration.provider.get", {"group": modelData}) - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Back") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings.developer", {}) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/configuration_ui/settingCheckBox.qml b/ovos_gui/res/ui/settings/configuration_ui/settingCheckBox.qml deleted file mode 100644 index cc69666..0000000 --- a/ovos_gui/res/ui/settings/configuration_ui/settingCheckBox.qml +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2022 Aditya Mehra - * - * 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.9 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.4 - -CheckBox { - property string buttonId; - property var modelData; - property var key; - property var value; - signal fieldUpdated(var modelData, string key, string value); - - onCheckedChanged: { - if(checked){ - fieldUpdated(modelData, key, "true") - } else { - fieldUpdated(modelData, key, "false") - } - } -} diff --git a/ovos_gui/res/ui/settings/configuration_ui/settingListBox.qml b/ovos_gui/res/ui/settings/configuration_ui/settingListBox.qml deleted file mode 100644 index d971ff7..0000000 --- a/ovos_gui/res/ui/settings/configuration_ui/settingListBox.qml +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2022 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import org.kde.kirigami 2.11 as Kirigami -import Mycroft 1.0 as Mycroft - -ColumnLayout { - id: listGeneratedItem - property var modelData - property var key - property var value - Layout.fillWidth: true - property bool editMode: false - signal fieldUpdated(var modelData, string key, string value); - - onValueChanged: { - fieldUpdated(modelData, key, value) - } - - function add_item_to_value(item) { - listGeneratedItem.value.push(item) - simpleListView.visible = false - simpleListView.model = [0, 0, 0] - simpleListView.enabled = false - simpleListView.enabled = true - simpleListView.visible = true - simpleListView.model = listGeneratedItem.value - } - - function remove_item_from_value(itemIndex) { - listGeneratedItem.value.pop(itemIndex) - simpleListView.visible = false - simpleListView.model = [0, 0, 0] - simpleListView.enabled = false - simpleListView.enabled = true - simpleListView.visible = true - simpleListView.model = listGeneratedItem.value - } - - Repeater { - id: simpleListView - model: listGeneratedItem.value - - delegate: Kirigami.AbstractListItem { - width: simpleListView.width - height: Mycroft.Units.gridUnit * 4 - - background: Rectangle { - color: Kirigami.Theme.backgroundColor - radius: 6 - } - - contentItem: RowLayout { - Label { - Layout.fillWidth: true - Layout.fillHeight: true - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: modelData - } - - Button { - Layout.preferredWidth: Mycroft.Units.gridUnit * 6 - Layout.fillHeight: true - visible: listGeneratedItem.editMode ? 1 : 0 - enabled: listGeneratedItem.editMode ? 1 : 0 - - background: Rectangle { - color: Kirigami.Theme.highlightColor - radius: 6 - } - - contentItem: Item { - Kirigami.Icon { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - source: "edit-delete-remove" - color: Kirigami.Theme.textColor - } - } - - onClicked: { - listGeneratedItem.remove_item_from_value(index) - } - } - } - } - } - - RowLayout { - Layout.fillWidth: true - Layout.preferredHeight: Mycroft.Units.gridUnit * 4 - - Button { - Layout.fillWidth: true - Layout.preferredHeight: Mycroft.Units.gridUnit * 3.5 - Layout.alignment: Qt.AlignVCenter - - background: Rectangle { - color: Kirigami.Theme.highlightColor - radius: 6 - } - - contentItem: Item { - Kirigami.Icon { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - source: "list-add-symbolic" - color: Kirigami.Theme.textColor - } - } - - onClicked: { - addListItemBox.privateItem = listGeneratedItem - addListItemBox.open() - } - } - - Button { - Layout.fillWidth: true - Layout.preferredHeight: Mycroft.Units.gridUnit * 3.5 - Layout.alignment: Qt.AlignVCenter - enabled: simpleListView.count > 0 ? 1 : 0 - visible: simpleListView.count > 0 ? 1 : 0 - - background: Rectangle { - color: Kirigami.Theme.highlightColor - radius: 6 - } - - contentItem: Item { - Kirigami.Icon { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - source: "document-edit" - color: Kirigami.Theme.textColor - } - } - - onClicked: { - if(!listGeneratedItem.editMode) { - listGeneratedItem.editMode = true - } else { - listGeneratedItem.editMode = false - } - } - } - } - - Popup { - id: addListItemBox - width: parent.width * 0.80 - height: Mycroft.Units.gridUnit * 8 - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - parent: configurationLoaderView - property var privateItem - - ColumnLayout { - anchors.fill: parent - - TextField { - id: addListItemTextBox - Layout.fillWidth: true - Layout.preferredHeight: Mycroft.Units.gridUnit * 4 - placeholderText: qsTr("Type here to add an item to the list") - } - - Button { - Layout.fillWidth: true - Layout.preferredHeight: Mycroft.Units.gridUnit * 2 - - background: Rectangle { - color: Kirigami.Theme.highlightColor - radius: 6 - } - - contentItem: Label { - text: qsTr("Add Item") - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - - onClicked: { - addListItemBox.privateItem.add_item_to_value(addListItemTextBox.text) - addListItemBox.close() - } - } - } - } -} diff --git a/ovos_gui/res/ui/settings/configuration_ui/settingTextBox.qml b/ovos_gui/res/ui/settings/configuration_ui/settingTextBox.qml deleted file mode 100644 index 3000a24..0000000 --- a/ovos_gui/res/ui/settings/configuration_ui/settingTextBox.qml +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2022 Aditya Mehra - * - * 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.9 -import QtQuick.Controls 2.3 -import QtQuick.Layouts 1.4 -import org.kde.kirigami 2.11 as Kirigami - -TextField { - property string buttonId; - property var modelData; - property var key; - property var value; - signal fieldUpdated(var modelData, string key, string value); - Layout.fillWidth: true - Layout.minimumHeight: Kirigami.Units.gridUnit * 2 - - onTextChanged: { - fieldUpdated(modelData, key, text) - } -} diff --git a/ovos_gui/res/ui/settings/customize_settings.qml b/ovos_gui/res/ui/settings/customize_settings.qml deleted file mode 100644 index 2b6fcce..0000000 --- a/ovos_gui/res/ui/settings/customize_settings.qml +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Item { - id: customizeSettingsView - anchors.fill: parent - property var colorSchemeModel - property var setColorScheme - - Component.onCompleted: { - OVOSPlugin.Configuration.updateSchemeList(); - colorSchemeModel = OVOSPlugin.Configuration.getSchemeList(); - colorSchemesView.model = colorSchemeModel.schemes; - setColorScheme = OVOSPlugin.Configuration.getSelectedSchemeName(); - console.log(setColorScheme); - } - - Connections { - target: OVOSPlugin.Configuration - onSchemeChanged: { - setColorScheme = OVOSPlugin.Configuration.getSelectedSchemeName(); - } - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: customizeSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Customize Settings") - color: Kirigami.Theme.textColor - } - } - - Item { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - - GridView { - id: colorSchemesView - width: parent.width - height: parent.height - cellWidth: parent.width / 3 - cellHeight: parent.height / 2 - clip: true - - delegate: ItemDelegate { - id: parentRectDelta - implicitHeight: colorSchemesView.cellHeight - (Mycroft.Units.largeSpacing * 2) - implicitWidth: colorSchemesView.cellWidth - (Mycroft.Units.largeSpacing * 2) - - background: Rectangle { - color: modelData.primaryColor - radius: 10 - } - - Item { - id: d1item - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - height: parent.height * 0.70 - - GridLayout { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - columns: 2 - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: modelData.primaryColor - border.width: 2 - border.color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - - Text { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: "P" - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 40 - color: Qt.darker(Kirigami.Theme.textColor, 1.5) - font.bold: true - } - } - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - color: modelData.secondaryColor - border.width: 2 - border.color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - - Text { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: "S" - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 40 - color: Qt.darker(Kirigami.Theme.textColor, 1.5) - font.bold: true - } - } - Rectangle{ - Layout.fillWidth: true - Layout.fillHeight: true - color: modelData.textColor - border.width: 2 - border.color: Qt.darker(Kirigami.Theme.backgroundColor, 1.5) - - Text { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: "T" - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 40 - color: Qt.darker(Kirigami.Theme.textColor, 1.5) - font.bold: true - } - } - Rectangle{ - Layout.fillWidth: true - Layout.fillHeight: true - visible: modelData.name == setColorScheme ? 1 : 0 - enabled: modelData.name == setColorScheme ? 1 : 0 - color: "transparent" - - Kirigami.Icon { - anchors.fill: parent - anchors.margins: 4 - source: Qt.resolvedUrl("images/tick.svg") - color: Kirigami.Theme.textColor - } - } - } - } - - Kirigami.Separator { - id: cardSept - anchors.top: d1item.bottom - anchors.left: parent.left - anchors.right: parent.right - height: 16 - color: modelData.secondaryColor - } - - Item { - id: d2item - anchors.top: cardSept.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - clip: true - - Label { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 20 - minimumPixelSize: 5 - fontSizeMode: Text.Fit - maximumLineCount: 1 - text: modelData.name - color: modelData.textColor - elide: Text.ElideRight - } - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - styleViewPopUp.showView(modelData.name, modelData.path, modelData.primaryColor, modelData.secondaryColor, modelData.textColor) - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - Item { - anchors.top: areaSep.bottom - anchors.bottom: parent.bottom - width: parent.width / 2 - anchors.left: parent.left - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Device Settings") - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings", {}) - } - } - } - - Item { - anchors.top: areaSep.bottom - anchors.bottom: parent.bottom - width: parent.width / 2 - anchors.right: parent.right - - RowLayout { - anchors.fill: parent - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Create Scheme") - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - - Kirigami.Icon { - id: nextIcon - source: Qt.resolvedUrl("images/next.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - Layout.alignment: Qt.AlignRight - - ColorOverlay { - anchors.fill: parent - source: nextIcon - color: Kirigami.Theme.textColor - } - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings.create.theme", {}) - } - } - } - } - - ItemDelegate { - id: styleViewPopUp - width: parent.width * 0.9 - height: parent.height * 0.9 - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - property var modelDataPath - property var modelDataName - property color primaryColor - property color secondaryColor - property color textColor - property bool opened: false - visible: opened - enabled: opened - - function open(){ - styleViewPopUp.opened = true - } - - function close(){ - styleViewPopUp.opened = false - } - - function showView(modelDataName, modelDataPath, primaryColor, secondaryColor, textColor) { - styleViewPopUp.primaryColor = primaryColor - styleViewPopUp.secondaryColor = secondaryColor - styleViewPopUp.textColor = textColor - styleViewPopUp.modelDataName = modelDataName - styleViewPopUp.modelDataPath = modelDataPath - styleViewPopUp.open() - } - - function setTheme(themeStyle) { - OVOSPlugin.Configuration.setScheme(styleViewPopUp.modelDataName, styleViewPopUp.modelDataPath, themeStyle) - styleViewPopUp.close() - } - - background: Rectangle { - color: Kirigami.Theme.backgroundColor - layer.enabled: true - layer.effect: DropShadow { - color: Kirigami.Theme.backgroundColor - transparentBorder: false - horizontalOffset: 0 - verticalOffset: 0 - spread: 0.2 - radius: 8 - samples: 16 - } - - Rectangle { - anchors.fill: parent - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - } - } - - contentItem: Item { - - Rectangle { - id: popupHeaderArea - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) - anchors.left: parent.left - anchors.right: parent.right - height: Mycroft.Units.gridUnit * 5 - radius: 4 - - Label { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 32 - font.bold: true - minimumPixelSize: 5 - fontSizeMode: Text.Fit - maximumLineCount: 1 - text: qsTr("Select Style") - color: Kirigami.Theme.textColor - elide: Text.ElideRight - } - } - - RowLayout { - anchors.top: popupHeaderArea.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: popupBottomArea.top - anchors.margins: Mycroft.Units.gridUnit / 2 - - ThemeView { - Layout.fillWidth: true - Layout.fillHeight: true - darkMode: true - viewPrimaryColor: styleViewPopUp.primaryColor - viewSecondaryColor: styleViewPopUp.secondaryColor - viewTextColor: styleViewPopUp.textColor - themeName: styleViewPopUp.modelDataName - } - - ThemeView { - Layout.fillWidth: true - Layout.fillHeight: true - darkMode: false - viewPrimaryColor: styleViewPopUp.primaryColor - viewSecondaryColor: styleViewPopUp.secondaryColor - viewTextColor: styleViewPopUp.textColor - themeName: styleViewPopUp.modelDataName - } - } - - Rectangle { - id: popupBottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 5 - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - border.color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.5) - border.width: 1 - radius: 4 - - RowLayout { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Mycroft.Units.gridUnit / 2 - - Kirigami.Icon { - id: backIconPopUp - source: "window-close-symbolic" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIconPopUp - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Cancel") - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - styleViewPopUp.close() - } - } - } - } - } -} - diff --git a/ovos_gui/res/ui/settings/customize_theme.qml b/ovos_gui/res/ui/settings/customize_theme.qml deleted file mode 100644 index 052b939..0000000 --- a/ovos_gui/res/ui/settings/customize_theme.qml +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 -import "code/colorUtils.js" as ColorUtils -import "delegates" as Delegates - -Item { - id: createThemeView - anchors.fill: parent - property color selectedPrimaryColor: Kirigami.Theme.backgroundColor - property color selectedSecondaryColor: Kirigami.Theme.highlightColor - property color selectedTextColor: Kirigami.Theme.textColor - property string selectedThemeName: qsTr("Example Scheme") - - onSelectedPrimaryColorChanged: { - selectedTextColor = ColorUtils.autoTextColor(selectedPrimaryColor.r, selectedPrimaryColor.g, selectedPrimaryColor.b) - } - - Connections { - target: Mycroft.MycroftController - - onIntentRecevied: { - if (type == "ovos.shell.gui.color.scheme.generated") { - timeoutMessageTimer.stop() - visualBusyIndicatorBox.visible = false - visualBusyIndicatorBox.enabled = false - // Go back to customize screen if there is a response - triggerGuiEvent("mycroft.device.settings.customize", {}) - } - } - } - - // Wait sometime before closing the busy BusyIndicator - // If there is no response from the phal plugin - Timer { - id: timeoutMessageTimer - running: false - interval: 12000 - repeat: false - onTriggered: { - if(visualBusyIndicatorBox.visible) { - visualBusyIndicatorBox.visible = false - visualBusyIndicatorBox.enabled = false - } - } - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: customizeSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Create Scheme") - color: Kirigami.Theme.textColor - } - } - - Item { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - - Item { - id: themeSetterArea - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: themePreviewArea.top - - GridLayout { - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: themeSetterAreaBottomLine.top - anchors.margins: Mycroft.Units.gridUnit / 2 - columns: 2 - rows: 2 - - Rectangle { - id: primaryColorSelectButton - Layout.fillWidth: true - Layout.fillHeight: true - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.5) - border.color: Kirigami.Theme.highlightColor - border.width: 1 - - Rectangle { - id: buttonPrimaryColorPreviewBox - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.margins: Mycroft.Units.gridUnit / 2 - color: createThemeView.selectedPrimaryColor - width: height - } - - Label { - anchors.left: buttonPrimaryColorPreviewBox.right - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 24 - font.bold: true - elide: Text.ElideRight - wrapMode: Text.WordWrap - text: qsTr("Select Primary Color") - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - primaryColorSelectorPopup.open() - } - } - } - Rectangle { - id: secondaryColorSelectButton - Layout.fillWidth: true - Layout.fillHeight: true - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.5) - border.color: Kirigami.Theme.highlightColor - border.width: 1 - - Rectangle { - id: buttonSecondaryColorPreviewBox - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.margins: Mycroft.Units.gridUnit / 2 - color: createThemeView.selectedSecondaryColor - width: height - } - - Label { - anchors.left: buttonSecondaryColorPreviewBox.right - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 24 - font.bold: true - elide: Text.ElideRight - wrapMode: Text.WordWrap - text: qsTr("Select Secondary Color") - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - secondaryColorSelectorPopup.open() - } - } - } - Rectangle { - id: autoTextColorButton - Layout.fillWidth: true - Layout.fillHeight: true - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.5) - border.color: Kirigami.Theme.highlightColor - border.width: 1 - - Rectangle { - id: buttonTextColorPreviewBox - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.margins: Mycroft.Units.gridUnit / 2 - color: createThemeView.selectedTextColor - width: height - } - - Label { - anchors.left: buttonTextColorPreviewBox.right - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 24 - font.bold: true - elide: Text.ElideRight - wrapMode: Text.WordWrap - text: qsTr("Auto Text Color") - } - } - Rectangle { - id: setNameButton - Layout.fillWidth: true - Layout.fillHeight: true - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.5) - border.color: Kirigami.Theme.highlightColor - border.width: 1 - - Kirigami.Icon { - id: buttonIconNameBox - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.margins: Mycroft.Units.gridUnit / 2 - width: height - source: "edit-select-text" - } - - Label { - anchors.left: buttonIconNameBox.right - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - fontSizeMode: Text.Fit - minimumPixelSize: 5 - font.pixelSize: 24 - font.bold: true - elide: Text.ElideRight - wrapMode: Text.WordWrap - text: qsTr("Set Name") - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - setNameBoxPopup.open() - } - } - } - } - - Kirigami.Separator { - id: themeSetterAreaBottomLine - anchors.bottom: parent.bottom - width: parent.width - height: 1 - color: Kirigami.Theme.highlightColor - } - } - - Item { - id: themePreviewArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: themeButtonArea.top - height: Mycroft.Units.gridUnit * 5 - - Rectangle { - id: previewButtonArea - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - border.color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.5) - border.width: 1 - radius: 4 - - RowLayout { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Mycroft.Units.gridUnit / 2 - - Kirigami.Icon { - id: previewButtonIcon - source: "actor" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: previewButtonIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Preview") - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - previewPopUpBox.open() - } - } - } - } - Item { - id: themeButtonArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 5 - - Rectangle { - id: createButtonArea - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - border.color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.5) - border.width: 1 - radius: 4 - - RowLayout { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Mycroft.Units.gridUnit / 2 - - Kirigami.Icon { - id: createButtonIcon - source: "checkmark" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: createButtonIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Create") - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("ovos.shell.gui.color.scheme.generate", {"theme_name": createThemeView.selectedThemeName, "primaryColor": createThemeView.selectedPrimaryColor, "secondaryColor": createThemeView.selectedSecondaryColor, "textColor": createThemeView.selectedTextColor}) - visualBusyIndicatorBox.visible = true - visualBusyIndicatorBox.enabled = true - timeoutMessageTimer.start() - } - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.top: areaSep.bottom - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Back") - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings.customize", {}) - } - } - } - - ItemDelegate { - id: previewPopUpBox - width: parent.width * 0.9 - height: parent.height * 0.9 - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - property bool opened: false - visible: previewPopUpBox.opened - enabled: previewPopUpBox.opened - - function open() { - previewPopUpBox.opened = true - } - - function close() { - previewPopUpBox.opened = false - } - - background: Rectangle { - color: Kirigami.Theme.backgroundColor - layer.enabled: true - layer.effect: DropShadow { - color: Kirigami.Theme.backgroundColor - transparentBorder: false - horizontalOffset: 0 - verticalOffset: 0 - spread: 0.2 - radius: 8 - samples: 16 - } - - Rectangle { - anchors.fill: parent - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - } - } - - contentItem: Item { - - Rectangle { - id: popupHeaderArea - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) - anchors.left: parent.left - anchors.right: parent.right - height: Mycroft.Units.gridUnit * 5 - radius: 4 - - Label { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 32 - font.bold: true - minimumPixelSize: 5 - fontSizeMode: Text.Fit - maximumLineCount: 1 - text: qsTr("Preview") - color: Kirigami.Theme.textColor - elide: Text.ElideRight - } - } - - RowLayout { - anchors.top: popupHeaderArea.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: popupBottomArea.top - anchors.margins: Mycroft.Units.gridUnit / 2 - - ThemeView { - Layout.fillWidth: true - Layout.fillHeight: true - darkMode: true - viewPrimaryColor: createThemeView.selectedPrimaryColor - viewSecondaryColor: createThemeView.selectedSecondaryColor - viewTextColor: createThemeView.selectedTextColor - themeName: createThemeView.selectedThemeName - clickEnabled: false - } - - ThemeView { - Layout.fillWidth: true - Layout.fillHeight: true - darkMode: false - viewPrimaryColor: createThemeView.selectedPrimaryColor - viewSecondaryColor: createThemeView.selectedSecondaryColor - viewTextColor: createThemeView.selectedTextColor - themeName: createThemeView.selectedThemeName - clickEnabled: false - } - } - - Rectangle { - id: popupBottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 5 - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - border.color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.5) - border.width: 1 - radius: 4 - - RowLayout { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Mycroft.Units.gridUnit / 2 - - Kirigami.Icon { - id: backIconPopUp - source: "window-close-symbolic" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIconPopUp - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: qsTr("Cancel") - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - previewPopUpBox.close() - } - } - } - } - } - - Delegates.ColorSelectPrimary { - id: primaryColorSelectorPopup - } - - Delegates.ColorSelectSecondary { - id: secondaryColorSelectorPopup - } - - Delegates.SetNameBox { - id: setNameBoxPopup - } - - Rectangle { - id: visualBusyIndicatorBox - visible: false - enabled: false - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.5) - anchors.fill: parent - - Mycroft.BusyIndicator { - anchors.centerIn: parent - running: visualBusyIndicatorBox.visible ? 1 : 0 - } - } -} - diff --git a/ovos_gui/res/ui/settings/delegates/BrightnessSlider.qml b/ovos_gui/res/ui/settings/delegates/BrightnessSlider.qml deleted file mode 100644 index 79f6668..0000000 --- a/ovos_gui/res/ui/settings/delegates/BrightnessSlider.qml +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami - -Slider { - id: control - from: 0.75 - to: 1.15 - live: true - stepSize: 0.1 - orientation: Qt.Vertical - value: 1 - - background: Rectangle { - x: control.leftPadding + control.availableWidth / 2 - width / 2 - y: control.topPadding - implicitWidth: 40 - implicitHeight: 200 - width: implicitWidth - height: control.availableHeight - radius: 2 - color: Kirigami.Theme.textColor - - Rectangle { - width: parent.width - height: control.visualPosition * parent.height - color: Qt.darker(Kirigami.Theme.textColor, 2.5) - radius: 2 - } - } - - handle: Rectangle { - y: control.topPadding + control.visualPosition * (control.availableHeight - height) - x: control.leftPadding + control.availableWidth / 2 - width / 2 - width: parent.width - height: 8 - color: control.pressed ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - border.color: Kirigami.Theme.highlightColor - } -} diff --git a/ovos_gui/res/ui/settings/delegates/ColorSelectPrimary.qml b/ovos_gui/res/ui/settings/delegates/ColorSelectPrimary.qml deleted file mode 100644 index 00f6554..0000000 --- a/ovos_gui/res/ui/settings/delegates/ColorSelectPrimary.qml +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Popup { - id: colorSelectPrimaryBox - width: parent.width * 0.9 - height: parent.height * 0.9 - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - dim: true - - Overlay.modeless: Rectangle { - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - } - - background: Rectangle { - color: Kirigami.Theme.backgroundColor - layer.enabled: true - layer.effect: DropShadow { - color: Kirigami.Theme.backgroundColor - transparentBorder: false - horizontalOffset: 0 - verticalOffset: 0 - spread: 0.2 - radius: 8 - samples: 16 - } - - Rectangle { - anchors.fill: parent - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - } - } - - contentItem: Item { - - Rectangle { - id: popupHeaderArea - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) - anchors.left: parent.left - anchors.right: parent.right - height: Mycroft.Units.gridUnit * 5 - radius: 4 - - Label { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 32 - font.bold: true - minimumPixelSize: 5 - fontSizeMode: Text.Fit - maximumLineCount: 1 - text: "Select Primary Color" - color: Kirigami.Theme.textColor - elide: Text.ElideRight - } - } - - Item { - anchors.top: popupHeaderArea.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: popupBottomArea.top - anchors.margins: Mycroft.Units.gridUnit / 2 - - PalettesGrid { - anchors.fill: parent - } - } - - Rectangle { - id: popupBottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 5 - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - border.color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.5) - border.width: 1 - radius: 4 - - RowLayout { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Mycroft.Units.gridUnit / 2 - - Kirigami.Icon { - id: backIconPopUp - source: "window-close-symbolic" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIconPopUp - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: "Close" - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../../snd/clicked.wav")) - colorSelectPrimaryBox.close() - } - } - } - } -} - diff --git a/ovos_gui/res/ui/settings/delegates/ColorSelectSecondary.qml b/ovos_gui/res/ui/settings/delegates/ColorSelectSecondary.qml deleted file mode 100644 index 1f77b74..0000000 --- a/ovos_gui/res/ui/settings/delegates/ColorSelectSecondary.qml +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 -import "../code/colorUtils.js" as ColorUtils - -Popup { - id: colorSelectSecondaryBox - width: parent.width * 0.9 - height: parent.height * 0.9 - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - dim: true - property color colorValue: Kirigami.Theme.highlightColor - property bool darkHue: false - property color _changingColorValue : ColorUtils._hsla(hueSlider.value, 1, 1, 1) - property color _tempColorValue: "transparent" - property var brightnessSliderValue: brightnessSlider.value - - onColorValueChanged: { - createThemeView.selectedSecondaryColor = colorValue - } - - on_ChangingColorValueChanged: { - _tempColorValue = _changingColorValue - } - - onBrightnessSliderValueChanged: { - if(brightnessSliderValue >= 1) { - darkHue: true - } else { - darkHue: false - } - } - - Overlay.modeless: Rectangle { - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - } - - background: Rectangle { - color: Kirigami.Theme.backgroundColor - layer.enabled: true - layer.effect: DropShadow { - color: Kirigami.Theme.backgroundColor - transparentBorder: false - horizontalOffset: 0 - verticalOffset: 0 - spread: 0.2 - radius: 8 - samples: 16 - } - - Rectangle { - anchors.fill: parent - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - } - } - - contentItem: Item { - - Rectangle { - id: popupHeaderArea - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) - anchors.left: parent.left - anchors.right: parent.right - height: Mycroft.Units.gridUnit * 5 - radius: 4 - - Label { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 32 - font.bold: true - minimumPixelSize: 5 - fontSizeMode: Text.Fit - maximumLineCount: 1 - text: "Select Secondary Color" - color: Kirigami.Theme.textColor - elide: Text.ElideRight - } - } - - Item { - anchors.top: popupHeaderArea.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: popupBottomArea.top - anchors.margins: Mycroft.Units.gridUnit / 2 - - RowLayout { - anchors.fill: parent - anchors.margins: 10 - - Rectangle { - Layout.preferredWidth: parent.width / 2 - Layout.fillHeight: true - color: darkHue ? Qt.lighter(_tempColorValue, brightnessSliderValue) : Qt.darker(_tempColorValue, brightnessSliderValue) - - onColorChanged: { - colorValue = color - } - } - - Item { - id: huePicker - Layout.preferredWidth: Mycroft.Units.gridUnit * 2 - Layout.fillHeight: true - Layout.topMargin: 8 - Layout.bottomMargin: 8 - - Rectangle { - anchors.fill: parent - id: colorBar - gradient: Gradient { - GradientStop { position: 1.0; color: "#FF0000" } - GradientStop { position: 0.85; color: "#FFFF00" } - GradientStop { position: 0.76; color: "#00FF00" } - GradientStop { position: 0.5; color: "#00FFFF" } - GradientStop { position: 0.33; color: "#0000FF" } - GradientStop { position: 0.16; color: "#FF00FF" } - GradientStop { position: 0.0; color: "#FF0000" } - } - } - ColorSlider { - id: hueSlider; anchors.fill: parent - } - } - - BrightnessSlider { - id: brightnessSlider - Layout.fillHeight: true - Layout.preferredWidth: Mycroft.Units.gridUnit * 2 - } - } - } - - Rectangle { - id: popupBottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 5 - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - border.color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.5) - border.width: 1 - radius: 4 - - RowLayout { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Mycroft.Units.gridUnit / 2 - - Kirigami.Icon { - id: backIconPopUp - source: "window-close-symbolic" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIconPopUp - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: "Close" - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../../snd/clicked.wav")) - colorSelectSecondaryBox.close() - } - } - } - } -} - diff --git a/ovos_gui/res/ui/settings/delegates/ColorSlider.qml b/ovos_gui/res/ui/settings/delegates/ColorSlider.qml deleted file mode 100644 index 513a253..0000000 --- a/ovos_gui/res/ui/settings/delegates/ColorSlider.qml +++ /dev/null @@ -1,50 +0,0 @@ -// Vertical "slider" control used in colorpicker -import QtQuick 2.11 - -Item { - property int cursorHeight: 7 - property real value: (1 - pickerCursor.y/height) - width: 15; height: 300 - - Item { - id: pickerCursor - width: parent.width - Rectangle { - x: -3; y: -height*0.5 - width: parent.width + 4; height: cursorHeight - border.color: "black"; border.width: 1 - color: "transparent" - Rectangle { - anchors.fill: parent; anchors.margins: 2 - border.color: "white"; border.width: 1 - color: "transparent" - } - } - } - MouseArea { - y: -Math.round(cursorHeight/2) - height: parent.height+cursorHeight - anchors.left: parent.left - anchors.right: parent.right - function handleMouse(mouse) { - if (mouse.buttons & Qt.LeftButton) { - pickerCursor.y = Math.max(0, Math.min(height, mouse.y)-cursorHeight) - } - } - onPositionChanged: { - handleMouse(mouse) - } - onPressed: handleMouse(mouse) - } - - onVisibleChanged: { - if(visible) { - pickerCursor.y = 0 - } - } - - function setValue(val) { - pickerCursor.y = height * (1 - val) - } -} - diff --git a/ovos_gui/res/ui/settings/delegates/NameSelect.qml b/ovos_gui/res/ui/settings/delegates/NameSelect.qml deleted file mode 100644 index 8d1c8b6..0000000 --- a/ovos_gui/res/ui/settings/delegates/NameSelect.qml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ovos_gui/res/ui/settings/delegates/Palette.qml b/ovos_gui/res/ui/settings/delegates/Palette.qml deleted file mode 100644 index a6db244..0000000 --- a/ovos_gui/res/ui/settings/delegates/Palette.qml +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Button { - id: control - property color target_color : "#21be2b" - property color border_color : Kirigami.Theme.textColor - property color selected_border_color : Kirigami.Theme.highlightColor - Layout.fillWidth: true - Layout.fillHeight: true - checkable: true - - onCheckedChanged: { - if(checked) { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../../snd/clicked.wav")) - } - } - - background: Rectangle { - border.color: (checked ? selected_border_color : border_color) - border.width: 4 - radius: 3 - - Rectangle { - anchors.fill: parent - anchors.margins: 4 - radius: 2 - color: target_color - } - } -} diff --git a/ovos_gui/res/ui/settings/delegates/PalettesGrid.qml b/ovos_gui/res/ui/settings/delegates/PalettesGrid.qml deleted file mode 100644 index 7e62fa7..0000000 --- a/ovos_gui/res/ui/settings/delegates/PalettesGrid.qml +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Item { - id: item - property color palettsColor : "transparent" - - onPalettsColorChanged: { - createThemeView.selectedPrimaryColor = palettsColor - } - - implicitHeight: grid.height - implicitWidth: grid.width - - GridLayout { - id: grid - columns: 4 - anchors.fill: parent - - ButtonGroup { - id: group - } - - Palette { - ButtonGroup.group: group - target_color: "#000000" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#1A1A1A" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#012010" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#200A22" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#0D0D22" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#221D1A" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#242411" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#0c1821" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#0d1701" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#280607" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#170d01" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - - Palette { - ButtonGroup.group: group - target_color: "#0c0117" - onCheckedChanged: { - if(checked) { - item.palettsColor = target_color - } - } - } - } -} diff --git a/ovos_gui/res/ui/settings/delegates/SetNameBox.qml b/ovos_gui/res/ui/settings/delegates/SetNameBox.qml deleted file mode 100644 index 6f0fd2e..0000000 --- a/ovos_gui/res/ui/settings/delegates/SetNameBox.qml +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Popup { - id: nameSelectBox - width: parent.width * 0.75 - height: parent.height * 0.75 - x: (parent.width - width) / 2 - y: (parent.height - height) / 2 - dim: true - property string nameValue - - onNameValueChanged: { - if(nameValue != "" && nameValue.length > 2 || nameValue != " " && nameValue.length > 2) { - createThemeView.selectedThemeName = nameValue[0].toUpperCase() + nameValue.slice(1) + " Scheme" - } else { - createThemeView.selectedThemeName = qsTr("Example Theme") - } - } - - Overlay.modeless: Rectangle { - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - } - - background: Rectangle { - color: Kirigami.Theme.backgroundColor - layer.enabled: true - layer.effect: DropShadow { - color: Kirigami.Theme.backgroundColor - transparentBorder: false - horizontalOffset: 0 - verticalOffset: 0 - spread: 0.2 - radius: 8 - samples: 16 - } - - Rectangle { - anchors.fill: parent - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - } - } - - contentItem: Item { - - Rectangle { - id: popupHeaderArea - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) - anchors.left: parent.left - anchors.right: parent.right - height: Mycroft.Units.gridUnit * 5 - radius: 4 - - Label { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 32 - font.bold: true - minimumPixelSize: 5 - fontSizeMode: Text.Fit - maximumLineCount: 1 - text: qsTr("Set Scheme Name") - color: Kirigami.Theme.textColor - elide: Text.ElideRight - } - } - - TextField { - id: popupMainContent - anchors.top: popupHeaderArea.bottom - anchors.bottom: popupBottomArea.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - - background: Rectangle { - color: Kirigami.Theme.backgroundColor - border.width: 1 - border.color: Kirigami.Theme.textColor - radius: 6 - - Label { - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - visible: popupMainContent.activeFocus ? 0 : 1 - text: qsTr("Unique 1 word scheme name, example: Midnight") - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - wrapMode: Text.WordWrap - } - } - palette.text: Kirigami.Theme.textColor - validator: RegExpValidator { regExp: /^([A-z])*[^\s]\1*$/ } - onTextChanged: { - nameSelectBox.nameValue = popupMainContent.text - } - } - - Rectangle { - id: popupBottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 5 - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1) - border.color: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.5) - border.width: 1 - radius: 4 - - RowLayout { - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.margins: Mycroft.Units.gridUnit / 2 - - Kirigami.Icon { - id: backIconPopUp - source: "window-close-symbolic" - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIconPopUp - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - color: Kirigami.Theme.textColor - text: "Close" - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../../snd/clicked.wav")) - nameSelectBox.close() - } - } - } - } -} - diff --git a/ovos_gui/res/ui/settings/developer_settings.qml b/ovos_gui/res/ui/settings/developer_settings.qml deleted file mode 100644 index 2369519..0000000 --- a/ovos_gui/res/ui/settings/developer_settings.qml +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.0 -import org.kde.kirigami 2.5 as Kirigami -import Mycroft 1.0 as Mycroft -import QtGraphicalEffects 1.12 - -Item { - id: developerSettingsView - anchors.fill: parent - property bool dashActive: sessionData.dashboard_enabled ? Boolean(sessionData.dashboard_enabled) : false - property bool busyVisible: false - - onDashActiveChanged: { - developerSettingsView.busyVisible = false - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: brightnessSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: "Developer Settings" - color: Kirigami.Theme.textColor - } - } - - Item { - id: viewBusyOverlay - z: 300 - anchors.top: topArea.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - visible: developerSettingsView.busyVisible - enabled: visible - - BusyIndicator { - id: viewBusyIndicator - visible: viewBusyOverlay.visible - anchors.centerIn: parent - running: viewBusyOverlay.visible - enabled: viewBusyOverlay.visible - } - } - - Flickable { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: midBottomArea.top - contentWidth: width - contentHeight: colMiddleContents.implicitHeight - clip: true - - ColumnLayout { - id: colMiddleContents - anchors.left: parent.left - anchors.right: parent.right - spacing: Kirigami.Units.smallSpacing - - Kirigami.Heading { - id: warnText - level: 3 - Layout.fillWidth: true - wrapMode: Text.WordWrap - color: Kirigami.Theme.textColor - text: "Enabling OVOS Dashboard will provide you access to control various services on this device, the OVOS Dashboard can be accessed on any device located in your LAN network" - } - - Item { - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.largeSpacing - } - - Button { - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 3 - text: "Enable Dashboard" - visible: !dashActive - enabled: visible - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.enable.dash", {}) - developerSettingsView.busyVisible = true - } - } - - Button { - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 3 - text: "Disable Dashboard" - visible: dashActive - enabled: visible - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.disable.dash", {}) - developerSettingsView.busyVisible = true - } - } - - Kirigami.Separator { - Layout.fillWidth: true - Layout.preferredHeight: 1 - visible: dashActive - enabled: visible - } - - Kirigami.Heading { - Layout.fillWidth: true - wrapMode: Text.WordWrap - level: 3 - color: Kirigami.Theme.textColor - text: "Dashboard Address: " + sessionData.dashboard_url - visible: dashActive - enabled: visible - } - - Kirigami.Heading { - Layout.fillWidth: true - wrapMode: Text.WordWrap - level: 3 - color: Kirigami.Theme.textColor - text: "Dashboard Username: " + sessionData.dashboard_user - visible: dashActive - enabled: visible - } - - Kirigami.Heading { - Layout.fillWidth: true - wrapMode: Text.WordWrap - level: 3 - color: Kirigami.Theme.textColor - text: "Dashboard Password: " + sessionData.dashboard_password - visible: dashActive - enabled: visible - } - } - } - - Item { - id: midBottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - height: Math.max(Mycroft.Units.gridUnit * 5, Kirigami.Units.iconSizes.large) - - Kirigami.Separator { - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: 1 - } - - Button { - id: advancedSettingButton - width: parent.width - height: Math.max(Mycroft.Units.gridUnit * 5, Kirigami.Units.iconSizes.large) - - background: Rectangle { - id: advancedSettingButtonBg - color: "transparent" - } - - contentItem: RowLayout { - Image { - id: iconAdvancedSettingHolder - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - source: "images/settings.png" - - ColorOverlay { - anchors.fill: parent - source: iconAdvancedSettingHolder - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.7) - } - } - - - Kirigami.Heading { - id: connectionNameLabel - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - verticalAlignment: Text.AlignVCenter - height: paintedHeight - elide: Text.ElideRight - font.weight: Font.DemiBold - text: "Advanced Settings" - textFormat: Text.PlainText - color: Kirigami.Theme.textColor - level: 2 - } - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("ovos.phal.configuration.provider.list.groups", {}) - } - - onPressed: { - advancedSettingButtonBg.color = Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.4) - } - onReleased: { - advancedSettingButtonBg.color = "transparent" - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: "Device Settings" - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings", {}) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/display_settings.qml b/ovos_gui/res/ui/settings/display_settings.qml deleted file mode 100644 index 6df1aa3..0000000 --- a/ovos_gui/res/ui/settings/display_settings.qml +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Item { - id: displaySettingsView - anchors.fill: parent - property bool wallpaper_rotation_enabled: false - property bool auto_dim_enabled: sessionData.display_auto_dim ? sessionData.display_auto_dim : 0 - property bool auto_nightmode_enabled: sessionData.display_auto_nightmode ? sessionData.display_auto_nightmode : 0 - property bool menuLabelsEnabled: false - - function getAutoRotation() { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.get.auto.rotation", {}) - } - - Component.onCompleted: { - getAutoRotation() - Mycroft.MycroftController.sendRequest("ovos.shell.get.menuLabels.status", {}) - } - - Connections { - target: Mycroft.MycroftController - onIntentRecevied: { - if (type == "ovos.shell.get.menuLabels.status.response") { - menuLabelsEnabled = data.enabled - } - if (type == "ovos.wallpaper.manager.get.auto.rotation.response") { - wallpaper_rotation_enabled = data.auto_rotation - } - } - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: idleSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Display Settings") - color: Kirigami.Theme.textColor - } - } - - ScrollBar { - id: flickAreaScrollBar - anchors.right: parent.right - width: Mycroft.Units.gridUnit - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.bottom: bottomArea.top - } - - Flickable { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: flickAreaScrollBar.left - anchors.bottom: midBottomArea.top - contentWidth: width - contentHeight: mainColLayoutDisplaySettings.implicitHeight - ScrollBar.vertical: flickAreaScrollBar - clip: true - - ColumnLayout { - id: mainColLayoutDisplaySettings - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - anchors.margins: Mycroft.Units.gridUnit / 2 - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: displaySettingItemOneLabel.implicitHeight + Mycroft.Units.gridUnit - color: Qt.lighter(Kirigami.Theme.backgroundColor, 2) - border.width: 1 - border.color: Qt.darker(Kirigami.Theme.textColor, 1.5) - radius: 6 - - ColumnLayout { - id: displaySettingItemOneLabel - anchors.left: parent.left - anchors.right: autoWallpaperRotationSwitch.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Mycroft.Units.gridUnit / 2 - - Label { - id: settingOneLabel - text: qsTr("Wallpaper Rotation") - font.pixelSize: 18 - fontSizeMode: Text.Fit - minimumPixelSize: 14 - color: Kirigami.Theme.textColor - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - - Label { - text: qsTr("Changes the wallpaper automatically") - font.pixelSize: settingOneLabel.font.pixelSize / 1.5 - color: Kirigami.Theme.textColor - wrapMode: Text.WordWrap - elide: Text.ElideRight - maximumLineCount: 1 - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - } - - Button { - id: autoWallpaperRotationSwitch - width: Mycroft.Units.gridUnit * 10 - anchors.right: parent.right - anchors.rightMargin: Mycroft.Units.gridUnit / 2 - height: parent.height - Mycroft.Units.gridUnit / 2 - anchors.verticalCenter: parent.verticalCenter - checkable: true - checked: displaySettingsView.wallpaper_rotation_enabled - text: checked ? qsTr("ON") : qsTr("OFF") - - Kirigami.Icon { - source: autoWallpaperRotationSwitch.checked ? Qt.resolvedUrl("images/switch-green.svg") : Qt.resolvedUrl("images/switch-red.svg") - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 8 - height: Kirigami.Units.iconSizes.medium - width: Kirigami.Units.iconSizes.medium - } - - onClicked: { - console.log(autoWallpaperRotationSwitch.checked) - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("speaker.extension.display.set.wallpaper.rotation", {"wallpaper_rotation": autoWallpaperRotationSwitch.checked}) - } - } - } - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: displaySettingItemTwoLabel.implicitHeight + Mycroft.Units.gridUnit - color: Qt.lighter(Kirigami.Theme.backgroundColor, 2) - border.width: 1 - border.color: Qt.darker(Kirigami.Theme.textColor, 1.5) - radius: 6 - - ColumnLayout { - id: displaySettingItemTwoLabel - anchors.left: parent.left - anchors.right: autoDimSwitch.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Mycroft.Units.gridUnit / 2 - - Label { - id: settingTwoLabel - text: qsTr("Auto Dim") - font.pixelSize: 18 - fontSizeMode: Text.Fit - minimumPixelSize: 14 - color: Kirigami.Theme.textColor - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - - Label { - text: qsTr("Dim's the display in 60 seconds") - font.pixelSize: settingTwoLabel.font.pixelSize / 1.5 - wrapMode: Text.WordWrap - elide: Text.ElideRight - color: Kirigami.Theme.textColor - maximumLineCount: 1 - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - } - - Button { - id: autoDimSwitch - width: Mycroft.Units.gridUnit * 10 - anchors.right: parent.right - anchors.rightMargin: Mycroft.Units.gridUnit / 2 - height: parent.height - Mycroft.Units.gridUnit / 2 - anchors.verticalCenter: parent.verticalCenter - checkable: true - checked: displaySettingsView.auto_dim_enabled - text: checked ? qsTr("ON") : qsTr("OFF") - - Kirigami.Icon { - source: autoDimSwitch.checked ? Qt.resolvedUrl("images/switch-green.svg") : Qt.resolvedUrl("images/switch-red.svg") - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 8 - height: Kirigami.Units.iconSizes.medium - width: Kirigami.Units.iconSizes.medium - } - - onClicked: { - console.log(autoDimSwitch.checked) - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("speaker.extension.display.set.auto.dim", {"auto_dim": autoDimSwitch.checked}) - } - } - } - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: displaySettingItemThreeLabel.implicitHeight + Mycroft.Units.gridUnit - color: Qt.lighter(Kirigami.Theme.backgroundColor, 2) - border.width: 1 - border.color: Qt.darker(Kirigami.Theme.textColor, 1.5) - radius: 6 - - ColumnLayout { - id: displaySettingItemThreeLabel - anchors.left: parent.left - anchors.right: autoNightmodeSwitch.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Mycroft.Units.gridUnit / 2 - - Label { - id: settingThreeLabel - text: qsTr("Auto Nightmode") - font.pixelSize: 18 - fontSizeMode: Text.Fit - minimumPixelSize: 14 - color: Kirigami.Theme.textColor - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - - Label { - text: qsTr("Activates nightmode on homescreen, depending on the time of the day") - font.pixelSize: settingThreeLabel.font.pixelSize / 1.5 - color: Kirigami.Theme.textColor - elide: Text.ElideRight - wrapMode: Text.WordWrap - maximumLineCount: 1 - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - } - - Button { - id: autoNightmodeSwitch - width: Mycroft.Units.gridUnit * 10 - anchors.right: parent.right - anchors.rightMargin: Mycroft.Units.gridUnit / 2 - height: parent.height - Mycroft.Units.gridUnit / 2 - anchors.verticalCenter: parent.verticalCenter - checkable: true - checked: displaySettingsView.auto_nightmode_enabled - text: checked ? qsTr("ON") : qsTr("OFF") - - Kirigami.Icon { - source: autoNightmodeSwitch.checked ? Qt.resolvedUrl("images/switch-green.svg") : Qt.resolvedUrl("images/switch-red.svg") - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 8 - height: Kirigami.Units.iconSizes.medium - width: Kirigami.Units.iconSizes.medium - } - - onClicked: { - console.log(autoNightmodeSwitch.checked) - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("speaker.extension.display.set.auto.nightmode", {"auto_nightmode": autoNightmodeSwitch.checked}) - } - } - } - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: displaySettingItemFourLabel.implicitHeight + Mycroft.Units.gridUnit - color: Qt.lighter(Kirigami.Theme.backgroundColor, 2) - border.width: 1 - border.color: Qt.darker(Kirigami.Theme.textColor, 1.5) - radius: 6 - - ColumnLayout { - id: displaySettingItemFourLabel - anchors.left: parent.left - anchors.right: displayMenuLabelsSwitch.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Mycroft.Units.gridUnit / 2 - - Label { - id: settingFourLabel - text: qsTr("Display Menu Labels") - font.pixelSize: 18 - fontSizeMode: Text.Fit - minimumPixelSize: 14 - color: Kirigami.Theme.textColor - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - - Label { - text: qsTr("Enable|Disable display of menu labels") - font.pixelSize: settingFourLabel.font.pixelSize / 1.5 - color: Kirigami.Theme.textColor - elide: Text.ElideRight - wrapMode: Text.WordWrap - maximumLineCount: 1 - Layout.fillWidth: true - Layout.fillHeight: true - Layout.alignment: Qt.AlignLeft - } - } - - Button { - id: displayMenuLabelsSwitch - width: Mycroft.Units.gridUnit * 10 - anchors.right: parent.right - anchors.rightMargin: Mycroft.Units.gridUnit / 2 - height: parent.height - Mycroft.Units.gridUnit / 2 - anchors.verticalCenter: parent.verticalCenter - checkable: true - checked: displaySettingsView.menuLabelsEnabled - text: checked ? qsTr("ON") : qsTr("OFF") - - Kirigami.Icon { - source: displayMenuLabelsSwitch.checked ? Qt.resolvedUrl("images/switch-green.svg") : Qt.resolvedUrl("images/switch-red.svg") - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 8 - height: Kirigami.Units.iconSizes.medium - width: Kirigami.Units.iconSizes.medium - } - - onClicked: { - console.log(displayMenuLabelsSwitch.checked) - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("ovos.shell.set.menuLabels", {"enabled": displayMenuLabelsSwitch.checked}) - } - } - } - } - } - - Item { - id: midBottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - height: Math.max(Mycroft.Units.gridUnit * 5, Kirigami.Units.iconSizes.large) - - Kirigami.Separator { - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: 1 - } - - Button { - id: wallpaperSettingButton - width: parent.width - height: Math.max(Mycroft.Units.gridUnit * 5, Kirigami.Units.iconSizes.large) - - background: Rectangle { - id: wallpaperSettingButtonBg - color: "transparent" - } - - contentItem: RowLayout { - Image { - id: iconWallpaperSettingHolder - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - source: "images/settings.png" - - ColorOverlay { - anchors.fill: parent - source: iconWallpaperSettingHolder - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.7) - } - } - - - Kirigami.Heading { - id: connectionNameLabel - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - verticalAlignment: Text.AlignVCenter - height: paintedHeight - elide: Text.ElideRight - font.weight: Font.DemiBold - text: "Wallpaper Settings" - textFormat: Text.PlainText - color: Kirigami.Theme.textColor - level: 2 - } - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - console.log("Sending Show Wallpaper Page Here") - triggerGuiEvent("mycroft.device.settings.wallpapers", {}) - } - - onPressed: { - wallpaperSettingButtonBg.color = Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.4) - } - onReleased: { - wallpaperSettingButtonBg.color = "transparent" - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Device Settings") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - triggerGuiEvent("mycroft.device.settings", {}) - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/factory_settings.qml b/ovos_gui/res/ui/settings/factory_settings.qml deleted file mode 100644 index d0db146..0000000 --- a/ovos_gui/res/ui/settings/factory_settings.qml +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2022 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.12 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.0 - -Item { - id: factorySettingsView - anchors.fill: parent - property bool horizontalMode: width > height ? 1 :0 - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: idleSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Factory Reset Settings") - color: Kirigami.Theme.textColor - } - } - - Flickable { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - contentWidth: width - contentHeight: factorySettingsLayout.implicitHeight - ScrollBar.vertical: ScrollBar { - width: Mycroft.Units.gridUnit - anchors.right: parent.right - } - clip: true - - GridLayout { - id: factorySettingsLayout - width: parent.width - Mycroft.Units.gridUnit * 2 - anchors.horizontalCenter: parent.horizontalCenter - columns: horizontalMode ? 2 : 1 - columnSpacing: Mycroft.Units.gridUnit / 2 - rowSpacing: Mycroft.Units.gridUnit / 2 - - Button { - text: qsTr("Wipe Cache") - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 4 - - background: Rectangle { - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: Kirigami.Theme.Button - color: Kirigami.Theme.backgroundColor - border.width: 1 - border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - radius: 6 - } - - contentItem: Label { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: qsTr("Wipe Cache") - color: Kirigami.Theme.textColor - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("system.factory.reset", {"wipe_cache": true, "wipe_data": false, "wipe_logs": false, "wipe_config": false, "reset_hardware": false}) - } - - onPressed: { - opacity = 0.5 - } - onReleased: { - opacity = 1 - } - } - - Button { - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 4 - - background: Rectangle { - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: Kirigami.Theme.Button - color: Kirigami.Theme.backgroundColor - border.width: 1 - border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - radius: 6 - } - - contentItem: Label { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: qsTr("Wipe Config") - color: Kirigami.Theme.textColor - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("system.factory.reset", {"wipe_cache": false, "wipe_data": false, "wipe_logs": false, "wipe_config": true, "reset_hardware": false}) - } - - onPressed: { - opacity = 0.5 - } - onReleased: { - opacity = 1 - } - } - - Button { - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 4 - - - background: Rectangle { - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: Kirigami.Theme.Button - color: Kirigami.Theme.backgroundColor - border.width: 1 - border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - radius: 6 - } - - contentItem: Label { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: qsTr("Wipe Data") - color: Kirigami.Theme.textColor - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("system.factory.reset", {"wipe_cache": false, "wipe_data": true, "wipe_logs": false, "wipe_config": false, "reset_hardware": false}) - } - - onPressed: { - opacity = 0.5 - } - onReleased: { - opacity = 1 - } - } - - Button { - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 4 - - background: Rectangle { - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: Kirigami.Theme.Button - color: Kirigami.Theme.backgroundColor - border.width: 1 - border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - radius: 6 - } - - contentItem: Label { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: qsTr("Wipe Logs") - color: Kirigami.Theme.textColor - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("system.factory.reset", {"wipe_cache": false, "wipe_data": false, "wipe_logs": true, "wipe_config": false, "reset_hardware": false}) - } - - onPressed: { - opacity = 0.5 - } - onReleased: { - opacity = 1 - } - } - - Button { - id: factoryResetButton - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 4 - - background: Rectangle { - Kirigami.Theme.inherit: false - Kirigami.Theme.colorSet: Kirigami.Theme.Button - color: Kirigami.Theme.backgroundColor - border.width: 1 - border.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - radius: 6 - } - - contentItem: Label { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - text: qsTr("Factory Reset") - color: Kirigami.Theme.textColor - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("system.factory.reset", {"wipe_cache": true, "wipe_data": true, "wipe_logs": true, "wipe_config": true, "reset_hardware": true}) - } - - onPressed: { - opacity = 0.5 - } - onReleased: { - opacity = 1 - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Device Settings") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings", {}) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/homescreen_settings.qml b/ovos_gui/res/ui/settings/homescreen_settings.qml deleted file mode 100644 index 0e0f327..0000000 --- a/ovos_gui/res/ui/settings/homescreen_settings.qml +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.0 -import org.kde.kirigami 2.5 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import QtGraphicalEffects 1.12 - -Item { - id: homeScreenSettingsView - anchors.fill: parent - property var modelItemList: mainLoaderView.idleScreenList - property var activeIdle: mainLoaderView.activeIdle - - ButtonGroup { - id: idleSelectionGroup - } - - onModelItemListChanged: { - listIdleFaces.model = modelItemList.screenBlob - } - - function checkIfActive(screenId){ - if(screenId == activeIdle) { - return true - } else { - return false - } - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: idleSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Homescreen Settings") - color: Kirigami.Theme.textColor - } - } - - Item { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - - ListView { - id: listIdleFaces - anchors.fill: parent - clip: true - boundsBehavior: Flickable.StopAtBounds - delegate: Kirigami.AbstractListItem { - activeBackgroundColor: Qt.rgba(1, 0, 0, 0.7) - contentItem: Item { - implicitWidth: delegateLayout.implicitWidth; - implicitHeight: delegateLayout.implicitHeight; - - ColumnLayout { - id: delegateLayout - anchors { - left: parent.left; - top: parent.top; - right: parent.right; - } - - RowLayout { - Layout.fillWidth: true - spacing: Math.round(units.gridUnit / 2) - - Kirigami.Heading { - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - height: paintedHeight - elide: Text.ElideRight - font.weight: Font.DemiBold - verticalAlignment: Text.AlignVCenter - color: Kirigami.Theme.textColor - text: modelData.name - textFormat: Text.PlainText - level: 2 - } - - Image { - id: selectedItemIcon - Layout.alignment: Qt.AlignVCenter | Qt.AlignRight - Layout.preferredHeight: units.iconSizes.medium - Layout.preferredWidth: units.iconSizes.medium - visible: checkIfActive(modelData.id) - source: "images/tick.svg" - } - } - } - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.set.idle", {"selected": modelData.id}) - } - } - - Component.onCompleted: { - listIdleFaces.count - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Device Settings") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings", {}) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/images/back.png b/ovos_gui/res/ui/settings/images/back.png deleted file mode 100644 index 6955e2e18698e6eed206f5139313e7f5068d268c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1772 zcmV>0zi%HedC$x+9UCVtO%jVz=psl(cf^E}3c5pxLSI(fgPqtiH@IcKl+_GbqN64BYKbnWx5Kl5kU4Da)-^?iHK zzJ$Q~&r4Ou0hrDt>J$Ds$VydbGLbqd5ecd~9RIFaA%p;cAr-jmgQ^Y%AcqkEsyh3h z-(wXJzK9G0P{9#ORp(NIf)#)$A_D-l<0wj17f^!Yzz+cW0%*lCl&Zc#2?{Xw(=_b~ zU_SuGF_x;nM+qEvezjWd24Ht*;MYj7jA=UT{BpTm0AK_KuE@E`;w7{&)lUd(t%RPWb+I`(q8peoLCBy$IhI_@Jtz4B-DM zBK?YTktfyzd=UvDgfo*Q*_iWCWmRp6G44x}q!8JZ>Y?*P2n`whJk(NEZHzJQEeiY) zLg-R(_z}Rs41Ou!p>%kRaaWPxhnyX8qVM!0fc{C6{2oH+mh)I6V~ksh2EWLsc>zEl z00#~Jtvi~DI$QJ8H0=RkU!I3GGx+B-QD^Y0)oND&yYj*Za1j%A2EV<%Jpr(lPwLho z{A}&tXaN5jCh8OZPX_R(Fj1fIe=ykX-^xUN!vD$u{yj|8*?E5U^K%3E_c2k2ov*6P z4c7cenW)3gSJfp3o&O9I_1XDv8o-~!M18LL3k=}TuRSKq&)9#_0RE!dX~Oa|{%0G& zf0yumPJmek@INGcpPm1p!KvOSgzppnGz0jn2;V3C+YR7P!G(Cy%{q6S07>xY`0D2RC z=PDj2@F9e7c8qaD&O;qi)rKTV4#XHqvlI2dKkJk|sXNR7eut_y#TX9~e&?%n96En+ zk|fPJ#GscK^gVF%$m5};Hn1ptj9gzmXFE-~I8 zW8}pir#t_14R-!e)t73P6_zsz&N7l-avvKylu?41YcX+I|!f`|99Y5f|Ujmw1`MQP6DSAsOk!%uYL@m z1b!u0Y9K+ohz!c^QDk|knm2~LV<16AL>f2={7!;J1`?zq(nJaTZVcxe-CZ=2sXAQ_ z0L(R#U<_0ByBy3mlHdZS>UR=60h_v*srr@SAtMPUGEKkB!VDt`u4bBkC&ArD5=>^A zekZ{#MjOMaOw;cqm|`Ts9Zb`&1lJl#FpX*YmEbZX31%`)zY<(xv@v{~Y5J95oY5qB zw)P?v%h%b#SR)DMPy)Xaj51mdUZDhjB^VAs3?{+C?05{-Q;A3rk)Z%81`;f$1U@%~ zK}1dm@RxxE?{hiuxfBEdrvhj*kYG6{flmpdh@70gdpPgo>7Q{DI9(0^^ak*UfdpT2 z5;$EB(lqS>U>CnzRL2rjtJSUmwi-yVmJ&FXpj)KHIQIiwOZ}QN#Iw4Zw(~aoozB1tWybA8N8!lAAmlb1b!v>)IfrRBGR7{ zIJ{Vt$*{~|IXEOD11W*iNua7r3?wK67)%NLO7NC}1XU3^gA(}N6TE73hnbFGs(vTI zJU*VzN$^76cNPI?Vxqp!4xa98^NUC$_W{L_;jvDP{t<*o&>iYf&X|WR3DSzro+IWz+~!6f=M;-uV5neDZzCBZa9(troREs0iaTd-G=o5 O0000 - - - diff --git a/ovos_gui/res/ui/settings/images/display.svg b/ovos_gui/res/ui/settings/images/display.svg deleted file mode 100644 index ea13f46..0000000 --- a/ovos_gui/res/ui/settings/images/display.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/ovos_gui/res/ui/settings/images/home.svg b/ovos_gui/res/ui/settings/images/home.svg deleted file mode 100644 index f7c9d4d..0000000 --- a/ovos_gui/res/ui/settings/images/home.svg +++ /dev/null @@ -1,116 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ovos_gui/res/ui/settings/images/info.svg b/ovos_gui/res/ui/settings/images/info.svg deleted file mode 100644 index 5e9ea08..0000000 --- a/ovos_gui/res/ui/settings/images/info.svg +++ /dev/null @@ -1,122 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ovos_gui/res/ui/settings/images/next.svg b/ovos_gui/res/ui/settings/images/next.svg deleted file mode 100644 index 815e33f..0000000 --- a/ovos_gui/res/ui/settings/images/next.svg +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - diff --git a/ovos_gui/res/ui/settings/images/paint.svg b/ovos_gui/res/ui/settings/images/paint.svg deleted file mode 100644 index 19881b3..0000000 --- a/ovos_gui/res/ui/settings/images/paint.svg +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ovos_gui/res/ui/settings/images/power.svg b/ovos_gui/res/ui/settings/images/power.svg deleted file mode 100644 index e5fcff6..0000000 --- a/ovos_gui/res/ui/settings/images/power.svg +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/ovos_gui/res/ui/settings/images/restart.svg b/ovos_gui/res/ui/settings/images/restart.svg deleted file mode 100644 index b1d5e94..0000000 --- a/ovos_gui/res/ui/settings/images/restart.svg +++ /dev/null @@ -1,116 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ovos_gui/res/ui/settings/images/settings.png b/ovos_gui/res/ui/settings/images/settings.png deleted file mode 100644 index c4a4d4b987fb683e1f5447dadabb092ceac1aa47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5903 zcmV+q7x3tbP)EX>4Tx04R}tkv&MmKp2MKrbE=Cr2km7b)?(q|hSPJC1vJ?|WbFz5|46k!e=jIH2ja znTSQjRC-kmyrPR{FGesbGs~Ehq&QlRuY36Teiz|ct?T|A-D<{SfKMczWrk@JZxBy! z+6L!+;t`&eLBz0#B}fpVpo{{Fuo0nMC&fa7&Z8~-1Fl~pmqM-r z7&#VDf(F_3ga5(r-dfqo2`?!a1=?R6=VJ&6>;kol<9r`GPVEHnKLb~K!(XZbGoPea z8d~@W=-CD?t{a-N2VCv|{ZEE$%C6+6C1kU}`x$*x8tA(PI@i3u)z5MI03@kb@f+aa z5E#x;_IitVcQp6y-=egK_ba=0*J^c4UA00v@9M??Vs0IvW>e!PMU00009a7bBm z000fw000fw0YWI7cmMzZ2XskIMF->y3lS+getyb2000#VNklD1!2lxSiXZ_*#RVhak{I=ws1Fz7l6*{J;*vxY#b|uSL`|aPX`&(9Gwy4G3yCor z2qY>2L=XiOH&$5%K^&H0U|{C={-{f4x^GYSz1@9#?#%S>^O+Cy?Y?#E*7;S{sZ-~i zGTIm<8E_@=ZJ;vXZS{bFEr0=?fX%?m!0*lM9ZF~s!cRzgNK(BDhn12>ms+=F5a73p z1|LZ}y41q)7XC;{+Y}w1Z;9=aXhR$r4RnmK{GpO6N(6{6_9;U7CzS{gUlgNv9#|qk ze9@%{&*)YnKzz}u2+!D~M1ZzUfby2sC}lBRt{nng2<(ruzO4nuo7sXEK!6Sfc>hCz zv%IpZfvINpYFk*RCnVi2X+xSd_9jWc%XOJ0siUNi6+Irx799&y{Zr-u;vgx@HFtnLKO+j_m;GS zVr<)31}p`70f!c-%nyJI%xqSRAb{5k#sg!5;jWq!zl>twcgdYj!181Ar zvRImeJwLn$OTv!~hXYSb>K#i00Ji~ODak2P90iP*R2k+bD?;x-7kC)xT#`{y@B(nA znJF#=nB%dtgd(Y1o>KTsvrhq%`g!wH3B`kj>2Oi&00$GpE$23Xj&UKt2f(h9Jc^F( zaUsA$pcFP$d>vp(EC}FfqR*9NQdCR<9*EO2u)?d<@g>}|tM)*Y`fJcHgzE?f+>*QsiaOvpRI?EX7j-eOhiD`|E!xM}T@^s?tH+A)v% z_mp&BEVWn-Dqu)G{_sC$4Q##`N7xb(NL2-ougRwKTOiBB9Y*l zyjN!}MPC3;!0j#`4DLMn^=k(_jArbX7*;u9FpAl?c-7pNq>!a8W`8AMgU2j zfg`=)JzM>@0B@Vw${3Sz4`4DdBBDpE297ba4_kV#?Ir2{H1Y94FkRB{7{A*9Z`~dh zo@vn|fTRJqE#v+2C}tOMnVCHlQxaSb{0?XrLGkst;E-j&8epTRAJlk%RlqDWTM@^G z=_u*_0`-KQaSomK0!5n(+r15N!R0g_$?j%`@jd<3&@hD}Se-`u`447~>S8JScha6nuYLrLR-^J7qzRlu2X2&EpF z^y&R4f(ajB=T?~aE09w4nt?IacOM}hp3?gQ*T;bXU6V~4>%!e#y9IVtr(Ug$tMtum zA}}u|)j7N%K^u~e#AV|i==H$&feHB}E-1#b)3eeYgLC*;joV-Uo0-)|{P^iW9L^W$ zT$X1eb^`9jC3Z~JC$5w97vK^zt7_tYf8M|P9DEzMP9>SmO4WHRC2zaq^@&ZZyJsb9eK0$8(Bz%Q7`a0`5 zz+_3M?k0ky1n?{1>HsBn0VYO80&hfI6$1j4S;2&_I#~U0P(AcH0TRCbm<_=5xSaYY zrX4lr-UZA55&ktgd7dH3VDVCyRAb*w8V8C!tU&1^;lI>BL1lD^ng12cc*8WW&fe;7U%%0r~+Uo#C}yWJ5e7wmru9C>Xx)5hBm zz#`9;zPu|8zuncn2qcj7Eb!mWJp?2|3jZJJg@03n@Byk8!HgTAc5{G&>tWdoFz4sF z3m;&`6nNt@?!}o7>WBd>r0|bTFZ?Dlxp(XdNB;o24@ool z>~g(+;ghg=S>fKOVo&IM794OoblB7X{f;VlfRCex4J2-Hy!nHcf)f z!0k`=(1HYa>=`wZ!I zf*}+p&21c9x|K}{JdRXb{hYC_U-*ql@XC$pY!j#D+56k!He+H>fIdl|YB$5$S+ptC zZicnKBYW}{-eJDBjp;IQYx2CE9gHOx*wXZUGl-On7mzmMgn+A9VRAS>~R_p931yw!3S>tW)NXRx`Gz-P z^U_q0pu%9^li<)x(|z+JGh3TS$(I8?;-CNme+p^|{5&q*TXH=8%$s0cfztj|RKfvY zfc;KRH|J(n(pF4?Wq*U}0>wtOtANuUcl!g$_&+oIb{@UIJ@C4>lx%K10$dWvA;ir7 z=^fDYR~ny=x&Nv86QF%(IOKfjJF2POyv!)?>W1or&w&qLfw%5~nve3U)85CX6+ZBt zJRAMG7zlq0E^zf)Gpi5m5oBhQCEW^)O_~bwL9b!XtJl8`n}a@U&fL7$k?`)Lu=Ls7 zH<$eH^#*Wd&=l-V^!`4;Wl>u$fKA@tR@{bDwfFz^xZ`DBY`mWl)+KCC(x!1h;3i!OUs{ziP+_eKwhIHMy-kkGdZA{cKaeco7%Z|93O1&d{S0xPZ&A z;Z7qd_x0lAe+e`G2exkr*^hjAqE3>O$dv?=zK8Qtib|Qg*~}h~!VuK>CCY(sBwgH) zgLm`LYnl@No4`mjJK4;h&Ln(qN~$-rX=e5fpg-^@zX4}|7%?{8e4ZKWeeZQJa7vEC zKNh$#Lc`B%z!SON9L6W`V%(W`4G8PL)$cr~IQnr1F2p&fy>>HOVP+TMwpTa%NHFY2 z0c>84ux?g5`~UaTIhtk>eiz`kWX@!gFDB%po22ucO&6a(#M59KCdVx+;a`{1*ie`e z-TK3cO>{eK|?cO<~bf!G&)LH}sot6dY4X;d`UOJV~bm z|HipLuerGaDC0tC-n5PdRM#re!ebYrzZI@d?cTT~Lyb0H#X% zddl_95ek1N?jX**knpl)K1a~x3@iWTmREs$zrlbDeWj4@H*tqv^dV`3c^Q@D&%E+0=XsDZ|;O{Rsnh)i_^&$ywGmf8flm8$-TR&!e0@ zKN+`}*`^{`y{_|?UlspRdHRlm`M(Zc!peWb`q!PMaj&DHWA}!stgMqGcyfE*LBrt~ ziz0ltPb67B3Lt>x6`vmjM_!w%`L6)_6)VB9r2CVWuRAuuqzm$MLEnum`3bzyU3%evm~*uVYg$jxTa{>*Sn46_v2(rwcR-XU$JA2bZ%al35P;UcM=D z66717p9!74tz7?7s+gFGvx7IFdjXFs$dI4FBl?mE->nz$fOkM=UuyitFSEM@&^J>9Za*)8Pj1WvN$`SYCu@48t8C-z8oI zsPNg~*U>ykes0*kf&8$vNY6O|xIbP5@GHON%|w9Yq)dsTrV^gv8EuMz^CaC69|HK( zy>w|N0_>6Wscw5QpS{Fe`W6ETU`!Z&AX)-!-C@JtXJ=VbCww+)o>#&T?+2XbJec?B737XbQ~eputX|Um zA`oCZ@G~!t#m1 z3u#yG{0WcvUQppL2X1QOySE}1el75GGy8omc7RI*kpP?-b>#nsO9A)(A5)dVGT?D9 z`BYRGN9s=Jx>@1E$A*q^P9(wbE^vyOHRXdomFTjB@4}rRerqm<1I%oPnO%&FTmLh# zmP{@`9eP0j5Gn6BEpe&flF=6!pU?Td8G8S8GPj#5gjJNMkx7GY# zz@$Qr1YR!S8-ZW=zFhSpR4oo(Sl?0U=GO~=3Tr^6nT;^B-~^?-d(7+y zxfT$}5M*X=0aqklY~MLZ4{0<=)xhkZx_^^#0xqHS@H~az1Lq`poA1l5tKiKLQ)5MC zs+SMIAI$8@Fkx3|+OZB7#Wb-%1b7U%GM@qxAu2x|n44^G`doO!(45~9NVGcwzT3t*X?XU~5K_VX<~Lyn0Kzk-&g&0?Q?hmo&PmH1m=wC4E8CJ>I(a_c$APGS<(9soxF1 z?(gA?;C|7}78j`3;w=-;!FglnD*SI2;$Vxg!J&mQ-mIGq)4%VQSbO+7d^zq=rSm;u ze}qe|UWMD$>xGN5ZJNBQgT)izorlwnHUT8$E4tubJ!V!dX*BM9;h-5q>%5WZntXeH zXaaa~amm4<`J{TSS`7cX3_kr8XMMCL9cT9Pxr6h`^|NIKynZLV zd}V&ZhjiA$y@8j*>L(!-!^^y$-IU`!39pQo5o%e+k?oQ`F zINr=IBtm#*?Dl51m55Rf;NYC z?K8JaD<(j)?^L@A82pX4CHx+TLGR(2+ocr~U>@$=y#^e7HVnF?Z3w^n5SJL+pV#Q= zHbDT-+;|u9@{sW`C2(8h!xngAI| zu;f{I=K+^{XTU}2{N*#FW<9)oRXCUP#yI+ha2`tF4xE@X))BDxaCgdS8xnp_1jtB& z`kjsd>5r576Yh|LgK)cFLw&zkJOLKmn}fnO7>>UyZ9m63PrQh;YTiU@*p%vF*S3aJ zP1}(0b0$DW5~Ro7W;Q0}{^M~$DTDrVv2Hs&e@=KO4u9|8j@!L_xUsXQmqGL|1dE+( z^}-Kg2gtNU{2}g0*=&2TV^f9i-9HVt_1VbK)WL;Yg+@9as zZVSSP@IHa*8uWSKc}a%?yA$xe@41p^yI1l#aab;u@Xb(Jp8GCvx_6Ar(YUm3D}b2+ z{rgJ-ASJwCswIz002ovPDHLkV1l_fT0Q^( diff --git a/ovos_gui/res/ui/settings/images/ssh.svg b/ovos_gui/res/ui/settings/images/ssh.svg deleted file mode 100644 index cea7e2e..0000000 --- a/ovos_gui/res/ui/settings/images/ssh.svg +++ /dev/null @@ -1,201 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ovos_gui/res/ui/settings/images/switch-green.svg b/ovos_gui/res/ui/settings/images/switch-green.svg deleted file mode 100644 index a2fd788..0000000 --- a/ovos_gui/res/ui/settings/images/switch-green.svg +++ /dev/null @@ -1,101 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ovos_gui/res/ui/settings/images/switch-red.svg b/ovos_gui/res/ui/settings/images/switch-red.svg deleted file mode 100644 index 3811643..0000000 --- a/ovos_gui/res/ui/settings/images/switch-red.svg +++ /dev/null @@ -1,100 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ovos_gui/res/ui/settings/images/tick.svg b/ovos_gui/res/ui/settings/images/tick.svg deleted file mode 100644 index a67b57a..0000000 --- a/ovos_gui/res/ui/settings/images/tick.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ovos_gui/res/ui/settings/lupdate-generator.sh b/ovos_gui/res/ui/settings/lupdate-generator.sh deleted file mode 100755 index 34bf852..0000000 --- a/ovos_gui/res/ui/settings/lupdate-generator.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/bash - -lupdate settingspage.qml -ts settingspage_de.ts -lupdate settingspage.qml -ts settingspage_es.ts -lupdate settingspage.qml -ts settingspage_fr.ts -lupdate settingspage.qml -ts settingspage_nl.ts -lupdate settingspage.qml -ts settingspage_pt.ts -lupdate settingspage.qml -ts settingspage_it.ts - -lupdate homescreen_settings.qml -ts homescreen_settings_de.ts -lupdate homescreen_settings.qml -ts homescreen_settings_es.ts -lupdate homescreen_settings.qml -ts homescreen_settings_fr.ts -lupdate homescreen_settings.qml -ts homescreen_settings_nl.ts -lupdate homescreen_settings.qml -ts homescreen_settings_pt.ts -lupdate homescreen_settings.qml -ts homescreen_settings_it.ts - -lupdate developer_settings.qml -ts developer_settings_de.ts -lupdate developer_settings.qml -ts developer_settings_es.ts -lupdate developer_settings.qml -ts developer_settings_fr.ts -lupdate developer_settings.qml -ts developer_settings_nl.ts -lupdate developer_settings.qml -ts developer_settings_pt.ts -lupdate developer_settings.qml -ts developer_settings_it.ts - -lupdate display_settings.qml -ts display_settings_de.ts -lupdate display_settings.qml -ts display_settings_es.ts -lupdate display_settings.qml -ts display_settings_fr.ts -lupdate display_settings.qml -ts display_settings_nl.ts -lupdate display_settings.qml -ts display_settings_pt.ts -lupdate display_settings.qml -ts display_settings_it.ts - -lupdate customize_settings.qml -ts customize_settings_de.ts -lupdate customize_settings.qml -ts customize_settings_es.ts -lupdate customize_settings.qml -ts customize_settings_fr.ts -lupdate customize_settings.qml -ts customize_settings_nl.ts -lupdate customize_settings.qml -ts customize_settings_pt.ts -lupdate customize_settings.qml -ts customize_settings_it.ts - -lupdate customize_theme.qml -ts customize_theme_de.ts -lupdate customize_theme.qml -ts customize_theme_es.ts -lupdate customize_theme.qml -ts customize_theme_fr.ts -lupdate customize_theme.qml -ts customize_theme_nl.ts -lupdate customize_theme.qml -ts customize_theme_pt.ts -lupdate customize_theme.qml -ts customize_theme_it.ts - -lupdate configuration_groups_display.qml -ts configuration_groups_display_de.ts -lupdate configuration_groups_display.qml -ts configuration_groups_display_es.ts -lupdate configuration_groups_display.qml -ts configuration_groups_display_fr.ts -lupdate configuration_groups_display.qml -ts configuration_groups_display_nl.ts -lupdate configuration_groups_display.qml -ts configuration_groups_display_pt.ts -lupdate configuration_groups_display.qml -ts configuration_groups_display_it.ts - -lupdate configuration_generator_display.qml -ts configuration_generator_display_de.ts -lupdate configuration_generator_display.qml -ts configuration_generator_display_es.ts -lupdate configuration_generator_display.qml -ts configuration_generator_display_fr.ts -lupdate configuration_generator_display.qml -ts configuration_generator_display_nl.ts -lupdate configuration_generator_display.qml -ts configuration_generator_display_pt.ts -lupdate configuration_generator_display.qml -ts configuration_generator_display_it.ts - -lupdate delegate/SetNameBox.qml -ts SetNameBox_de.ts -lupdate delegate/SetNameBox.qml -ts SetNameBox_es.ts -lupdate delegate/SetNameBox.qml -ts SetNameBox_fr.ts -lupdate delegate/SetNameBox.qml -ts SetNameBox_nl.ts -lupdate delegate/SetNameBox.qml -ts SetNameBox_pt.ts -lupdate delegate/SetNameBox.qml -ts SetNameBox_it.ts - -lupdate configuration_ui/settingListBox.qml -ts settingListBox_de.ts -lupdate configuration_ui/settingListBox.qml -ts settingListBox_es.ts -lupdate configuration_ui/settingListBox.qml -ts settingListBox_fr.ts -lupdate configuration_ui/settingListBox.qml -ts settingListBox_nl.ts -lupdate configuration_ui/settingListBox.qml -ts settingListBox_pt.ts -lupdate configuration_ui/settingListBox.qml -ts settingListBox_it.ts diff --git a/ovos_gui/res/ui/settings/settingspage.qml b/ovos_gui/res/ui/settings/settingspage.qml deleted file mode 100644 index 39f5f31..0000000 --- a/ovos_gui/res/ui/settings/settingspage.qml +++ /dev/null @@ -1,202 +0,0 @@ -import QtQuick.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.0 -import org.kde.plasma.core 2.0 as PlasmaCore -import org.kde.kirigami 2.5 as Kirigami -import Mycroft 1.0 as Mycroft -import QtGraphicalEffects 1.12 - -Item { - id: deviceSettingsView - anchors.fill: parent - z: 2 - - ListModel { - id: settingsListModel - - ListElement { - settingIcon: "images/home.svg" - settingName: QT_TR_NOOP("Homescreen Settings") - settingEvent: "mycroft.device.settings.homescreen" - settingCall: "show homescreen settings" - } - ListElement { - settingIcon: "images/paint.svg" - settingName: QT_TR_NOOP("Customize") - settingEvent: "mycroft.device.settings.customize" - settingCall: "" - } - ListElement { - settingIcon: "images/display.svg" - settingName: QT_TR_NOOP("Display") - settingEvent: "mycroft.device.settings.display" - settingCall: "" - } - ListElement { - settingIcon: "images/ssh.svg" - settingName: QT_TR_NOOP("Enable SSH") - settingEvent: "mycroft.device.settings.ssh" - settingCall: "show ssh settings" - } - ListElement { - settingIcon: "images/settings.png" - settingName: QT_TR_NOOP("Developer Settings") - settingEvent: "mycroft.device.settings.developer" - settingCall: "" - } - ListElement { - settingIcon: "images/restart.svg" - settingName: QT_TR_NOOP("Factory Settings") - settingEvent: "mycroft.device.settings.factory" - settingCall: "" - } - ListElement { - settingIcon: "images/info.svg" - settingName: QT_TR_NOOP("About") - settingEvent: "mycroft.device.settings.about.page" - settingCall: "" - } - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: settingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Device Settings") - color: Kirigami.Theme.textColor - } - } - - Item { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - anchors.bottomMargin: Kirigami.Units.largeSpacing - - ListView { - anchors.fill: parent - clip: true - model: settingsListModel - boundsBehavior: Flickable.StopAtBounds - delegate: Kirigami.AbstractListItem { - activeBackgroundColor: Qt.rgba(Kirigami.Theme.highlightColor.r, Kirigami.Theme.highlightColor.g, Kirigami.Theme.highlightColor.b, 0.7) - contentItem: Item { - implicitWidth: delegateLayout.implicitWidth; - implicitHeight: delegateLayout.implicitHeight; - - ColumnLayout { - id: delegateLayout - anchors { - left: parent.left; - top: parent.top; - right: parent.right; - } - - RowLayout { - Layout.fillWidth: true - spacing: Math.round(units.gridUnit / 2) - - Image { - id: iconSettingHolder - Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft - Layout.preferredHeight: units.iconSizes.medium - Layout.preferredWidth: units.iconSizes.medium - source: model.settingIcon - - ColorOverlay { - anchors.fill: parent - source: iconSettingHolder - color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.7) - } - } - - - Kirigami.Heading { - id: connectionNameLabel - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - verticalAlignment: Text.AlignVCenter - height: paintedHeight - elide: Text.ElideRight - font.weight: Font.DemiBold - text: qsTr(model.settingName) - textFormat: Text.PlainText - color: Kirigami.Theme.textColor - level: 2 - } - } - } - } - - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent(model.settingEvent, {}) - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Home") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.show.idle", {}) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/ssh_settings.qml b/ovos_gui/res/ui/settings/ssh_settings.qml deleted file mode 100644 index 69cd3c2..0000000 --- a/ovos_gui/res/ui/settings/ssh_settings.qml +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.0 -import org.kde.kirigami 2.5 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import QtGraphicalEffects 1.12 - -Item { - id: sshSettingsView - anchors.fill: parent - property bool connectionActive: false - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: brightnessSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("SSH Settings") - color: Kirigami.Theme.textColor - } - } - - Item { - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: bottomArea.top - - ColumnLayout { - anchors.left: parent.left - anchors.right: parent.right - spacing: Kirigami.Units.smallSpacing - - Kirigami.Heading { - id: warnText - level: 3 - Layout.fillWidth: true - wrapMode: Text.WordWrap - color: Kirigami.Theme.textColor - text: qsTr("By enabling SSH Mode, anyone can access, change or delete anything on this device by connecting to it via another device.") - } - - Item { - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.largeSpacing - } - - Button { - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 3 - text: qsTr("Enable SSH") - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("system.ssh.enable", {"display": false}) - } - } - - Button { - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 3 - text: qsTr("Disable SSH") - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - Mycroft.MycroftController.sendRequest("system.ssh.disable", {"display": false}) - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Device Settings") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - triggerGuiEvent("mycroft.device.settings", {}) - } - } - } -} diff --git a/ovos_gui/res/ui/settings/wallpaper_settings.qml b/ovos_gui/res/ui/settings/wallpaper_settings.qml deleted file mode 100644 index 6126026..0000000 --- a/ovos_gui/res/ui/settings/wallpaper_settings.qml +++ /dev/null @@ -1,680 +0,0 @@ -/* - * Copyright 2018 Aditya Mehra - * - * 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.Layouts 1.4 -import QtQuick 2.4 -import QtQuick.Controls 2.11 -import org.kde.kirigami 2.11 as Kirigami -import org.kde.plasma.core 2.0 as PlasmaCore -import Mycroft 1.0 as Mycroft -import OVOSPlugin 1.0 as OVOSPlugin -import QtGraphicalEffects 1.12 - -Item { - id: wallpaperSettings - anchors.fill: parent - property var currentProvider - property var currentWallpaper - property var providersModel - property var wallpapersProviderCollection - property bool providerHasCollection - property bool providerIsConfigurable - property bool wallpaperRotation: false - - Connections { - target: Mycroft.MycroftController - onIntentRecevied: { - if (type == "ovos.wallpaper.manager.get.active.provider.response") { - currentProvider = data.active_provider - } - if (type == "ovos.wallpaper.manager.get.registered.providers.response") { - var model = {"providers": data.registered_providers} - providersModel = model.providers - providersComboBox.model = providersModel - } - if (type == "ovos.wallpaper.manager.get.wallpaper.response") { - currentWallpaper = data.url - } - if (type == "ovos.wallpaper.manager.get.auto.rotation.response") { - wallpaperRotation = data.auto_rotation - } - if (type == "ovos.wallpaper.manager.get.provider.config.response") { - configureProviderPopupDialog.providerName = data.provider_name - configureProviderPopupDialog.providerConfiguration = convertConfigToArray(data.config) - } - if (type == "homescreen.wallpaper.set") { - currentWallpaper = data.url - } - if (type == "ovos.phal.wallpaper.manager.provider.registered") { - getRegisteredProviders() - } - } - } - - function getActiveProvider() { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.get.active.provider", {}) - } - - function getRegisteredProviders() { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.get.registered.providers", {}) - } - - function getCurrentWallpaper() { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.get.wallpaper", {}) - } - - function getAutoRotation() { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.get.auto.rotation", {}) - } - - function refreshProvider() { - var idx = providersComboBox.currentIndex - wallpapersProviderCollection = providersComboBox.model[idx].wallpaper_collection - providerIsConfigurable = providersComboBox.model[idx].provider_configurable - if(wallpapersProviderCollection.length > 0) { - providerHasCollection = true - } else { - providerHasCollection = false - } - wallpapersView.forceLayout() - } - - function getProviderConfig() { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.get.provider.config", {"provider_name": providersComboBox.currentValue}) - } - - function convertConfigToArray(obj) { - var result = []; - for (var key in obj) { - result.push({ "key": key, "value": obj[key].toLowerCase() }); - } - return result; - } - - function convertArrayToObject(keyValueArray) { - var result = {}; - for (var i = 0; i < keyValueArray.length; i++) { - var obj = keyValueArray[i]; - result[obj.key] = obj.value; - } - return result; - } - - Component.onCompleted: { - getActiveProvider() - getRegisteredProviders() - getCurrentWallpaper() - getAutoRotation() - } - - Item { - id: topArea - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - height: Kirigami.Units.gridUnit * 2 - - Kirigami.Heading { - id: idleSettingPageTextHeading - level: 1 - wrapMode: Text.WordWrap - anchors.centerIn: parent - font.bold: true - text: qsTr("Wallpaper Settings") - color: Kirigami.Theme.textColor - } - } - - ScrollBar { - id: flickAreaScrollBar - anchors.right: parent.right - width: Mycroft.Units.gridUnit - anchors.top: topArea.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.bottom: bottomArea.top - } - - RowLayout { - id: wallpaperProviderSelector - anchors.top: topArea.bottom - anchors.left: parent.left - anchors.right: parent.right - height: Mycroft.Units.gridUnit * 4 - - ComboBox { - id: providersComboBox - Layout.fillWidth: true - Layout.fillHeight: true - textRole: "provider_display_name" - valueRole: "provider_name" - - onModelChanged: { - refreshProvider() - } - - onCurrentValueChanged: { - refreshProvider() - } - } - - Button { - id: setProviderButton - Layout.preferredWidth: Mycroft.Units.gridUnit * 12 - Layout.fillHeight: true - enabled: providersComboBox.currentValue != currentProvider ? 1 : 0 - - background: Rectangle { - radius: 4 - color: setProviderButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - } - - contentItem: Item { - RowLayout { - anchors.centerIn: parent - Kirigami.Icon { - Layout.preferredWidth: Kirigami.Units.iconSizes.small - Layout.preferredHeight: Kirigami.Units.iconSizes.small - source: "dialog-ok" - } - Label { - color: setProviderButton.enabled ? Kirigami.Theme.textColor : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - text: qsTr("Set Provider") - } - } - } - - onClicked: { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.set.active.provider", {"provider_name": providersComboBox.currentValue}) - getActiveProvider() - getCurrentWallpaper() - refreshProvider() - } - } - - Button { - id: configureProviderButton - Layout.preferredWidth: Mycroft.Units.gridUnit * 12 - Layout.fillHeight: true - enabled: wallpaperSettings.providerIsConfigurable - - background: Rectangle { - radius: 4 - color: configureProviderButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - } - - contentItem: Item { - RowLayout { - anchors.centerIn: parent - Kirigami.Icon { - Layout.preferredWidth: Kirigami.Units.iconSizes.small - Layout.preferredHeight: Kirigami.Units.iconSizes.small - source: "configure" - } - Label { - color: configureProviderButton.enabled ? Kirigami.Theme.textColor : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - text: qsTr("Configure") - } - } - } - - onClicked: { - getProviderConfig() - configureProviderPopupDialog.open() - } - } - } - - Rectangle { - anchors.top: wallpaperProviderSelector.bottom - anchors.topMargin: Kirigami.Units.largeSpacing - anchors.left: parent.left - anchors.right: flickAreaScrollBar.left - anchors.leftMargin: Mycroft.Units.gridUnit - anchors.bottom: bottomArea.top - anchors.bottomMargin: Kirigami.Units.largeSpacing - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.7) - border.color: Kirigami.Theme.backgroundColor - border.width: 1 - radius: 4 - - Rectangle { - id: collectionNotAvailableView - anchors.centerIn: parent - width: parent.width - (Mycroft.Units.gridUnit / 2) - height: Mycroft.Units.gridUnit * 4 - color: Kirigami.Theme.backgroundColor - border.color: Kirigami.Theme.highlightColor - border.width: 1 - visible: !wallpaperSettings.providerHasCollection ? 1 : 0 - enabled: !wallpaperSettings.providerHasCollection ? 1 : 0 - radius: 4 - - Label { - id: collectionNotAvailableViewLabel - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit / 2 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - wrapMode: Text.WordWrap - color: Kirigami.Theme.textColor - text: qsTr("This provider generates new wallpapers dynamically instead of wallpaper collections.") - } - } - - GridView { - id: wallpapersView - anchors.centerIn: parent - width: parent.width - (Mycroft.Units.gridUnit / 2) - height: parent.height - (Mycroft.Units.gridUnit / 2) - ScrollBar.vertical: flickAreaScrollBar - visible: wallpaperSettings.providerHasCollection ? 1 : 0 - enabled: wallpaperSettings.providerHasCollection ? 1 : 0 - cellWidth: width / 4 - cellHeight: cellWidth - Mycroft.Units.gridUnit * 2 - clip: true - model: wallpaperSettings.wallpapersProviderCollection - delegate: ItemDelegate { - width: wallpapersView.cellWidth - height: wallpapersView.cellHeight - padding: 4 - - background: Rectangle { - color: "transparent" - } - - contentItem: Rectangle { - color: Kirigami.Theme.backgroundColor - border.color: currentWallpaper == modelData ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - border.width: 2 - - Image { - id: delegateImage - anchors.fill: parent - anchors.margins: 4 - source: Qt.resolvedUrl(modelData) - } - } - - onClicked: { - if(modelData != currentWallpaper) { - setWallpaperPopupDialog.open(modelData) - } - } - } - } - } - - Item { - id: bottomArea - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - height: Mycroft.Units.gridUnit * 6 - - Kirigami.Separator { - id: areaSep - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - color: Kirigami.Theme.highlightColor - height: 2 - } - - RowLayout { - anchors.fill: parent - - Kirigami.Icon { - id: backIcon - source: Qt.resolvedUrl("images/back.svg") - Layout.preferredHeight: Kirigami.Units.iconSizes.medium - Layout.preferredWidth: Kirigami.Units.iconSizes.medium - - ColorOverlay { - anchors.fill: parent - source: backIcon - color: Kirigami.Theme.textColor - } - } - - Kirigami.Heading { - level: 2 - wrapMode: Text.WordWrap - font.bold: true - text: qsTr("Device Settings") - color: Kirigami.Theme.textColor - verticalAlignment: Text.AlignVCenter - Layout.fillWidth: true - Layout.preferredHeight: Kirigami.Units.gridUnit * 2 - } - } - - MouseArea { - anchors.fill: parent - onClicked: { - triggerGuiEvent("mycroft.device.settings", {}) - Mycroft.SoundEffects.playClickedSound(Qt.resolvedUrl("../../snd/clicked.wav")) - } - } - } - - ItemDelegate { - id: setWallpaperPopupDialog - width: wallpaperSettings.width - height: wallpaperSettings.height - property bool opened: false - visible: setWallpaperPopupDialog.opened ? 1 : 0 - enabled: setWallpaperPopupDialog.opened ? 1 : 0 - property var imageUrl - - function open(url) { - setWallpaperPopupDialog.imageUrl = url - setWallpaperPopupDialog.opened = true - } - - function close() { - setWallpaperPopupDialog.opened = false - } - - background: Item { - - Image { - id: bgModelImage - anchors.fill: parent - anchors.margins: Mycroft.Units.gridUnit * 2 - source: Qt.resolvedUrl(setWallpaperPopupDialog.imageUrl) - smooth: true - } - - Rectangle { - anchors.fill: parent - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) - } - } - - contentItem: Item { - width: wallpaperSettings.width - height: wallpaperSettings.height - - Item { - anchors.centerIn: parent - width: parent.width / 1.5 - height: parent.height / 1.5 - - Column { - anchors.fill: parent - spacing: Mycroft.Units.gridUnit / 2 - - RowLayout { - id: warningMessageWallpaperRotation - width: parent.width - height: Mycroft.Units.gridUnit * 4 - enabled: wallpaperSettings.wallpaperRotation - visible: wallpaperSettings.wallpaperRotation - - Kirigami.Icon { - Layout.preferredWidth: Kirigami.Units.iconSizes.small - Layout.preferredHeight: Kirigami.Units.iconSizes.small - Layout.alignment: Layout.AlignVCenter - source: "state-warning" - } - - Label { - Layout.fillWidth: true - Layout.fillHeight: true - color: Kirigami.Theme.textColor - font.bold: true - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - maximumLineCount: 3 - elide: Text.ElideRight - text: qsTr("Wallpaper rotation prevents setting new wallpapers, disable wallpaper rotation and try again") - } - } - - Button { - id: setWallpaperButton - width: parent.width - height: Mycroft.Units.gridUnit * 3 - enabled: wallpaperSettings.wallpaperRotation ? 0 : 1 - - background: Rectangle { - radius: 4 - color: setWallpaperButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - } - - contentItem: Item { - RowLayout { - anchors.centerIn: parent - Kirigami.Icon { - Layout.preferredWidth: Kirigami.Units.iconSizes.small - Layout.preferredHeight: Kirigami.Units.iconSizes.small - source: "dialog-ok" - } - Label { - color: setWallpaperButton.enabled ? Kirigami.Theme.textColor : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - text: qsTr("Set Wallpaper") - } - } - } - - onClicked: { - if(currentProvider == providersComboBox.currentValue) { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.set.wallpaper", {"url": setWallpaperPopupDialog.imageUrl}) - setWallpaperPopupDialog.close() - getCurrentWallpaper() - } else { - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.set.active.provider", {"provider_name": providersComboBox.currentValue, "provider_image": setWallpaperPopupDialog.imageUrl}) - getActiveProvider() - getCurrentWallpaper() - refreshProvider() - } - } - - Keys.onReturnPressed: { - clicked() - } - - } - - Button { - id: rejectButton - width: parent.width - height: Mycroft.Units.gridUnit * 3 - - background: Rectangle { - radius: 4 - color: rejectButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - } - - contentItem: Item { - RowLayout { - anchors.centerIn: parent - Kirigami.Icon { - Layout.preferredWidth: Kirigami.Units.iconSizes.small - Layout.preferredHeight: Kirigami.Units.iconSizes.small - source: "dialog-cancel" - } - Label { - color: Kirigami.Theme.textColor - text: qsTr("Cancel") - } - } - } - - onClicked: { - setWallpaperPopupDialog.close() - } - - Keys.onReturnPressed: { - clicked() - } - } - } - } - } - } - - ItemDelegate { - id: configureProviderPopupDialog - width: wallpaperSettings.width - height: wallpaperSettings.height - property bool opened: false - visible: configureProviderPopupDialog.opened ? 1 : 0 - enabled: configureProviderPopupDialog.opened ? 1 : 0 - property var providerName - property var providerConfiguration - property var newConfiguration: [] - - function open() { - configureProviderPopupDialog.opened = true - } - - function close() { - providerConfiguration = {} - configureProviderPopupDialog.opened = false - } - - background: Rectangle { - color: Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.6) - } - - contentItem: Item { - width: wallpaperSettings.width - height: wallpaperSettings.height - - Item { - anchors.centerIn: parent - width: parent.width / 1.5 - height: parent.height / 1.5 - - Column { - anchors.fill: parent - spacing: Mycroft.Units.gridUnit / 2 - - Repeater { - model: configureProviderPopupDialog.providerConfiguration - delegate: RowLayout { - width: parent.width - height: Mycroft.Units.gridUnit * 3 - - Label { - Layout.fillWidth: true - Layout.fillHeight: true - color: Kirigami.Theme.textColor - font.capitalization: Font.AllUppercase - text: modelData.key - } - - TextField { - Layout.fillWidth: true - Layout.fillHeight: true - text: modelData.value - - onTextChanged: { - var keyExists = false - for (var i = 0; i < configureProviderPopupDialog.newConfiguration.length; i++) { - if (configureProviderPopupDialog.newConfiguration[i].key === modelData.key) { - configureProviderPopupDialog.newConfiguration[i].value = text - keyExists = true - } - } - if (!keyExists) { - configureProviderPopupDialog.newConfiguration.push({ - "key": modelData.key, - "value": text - }) - } - } - } - } - } - - Button { - id: setProviderConfigurationButton - width: parent.width - height: Mycroft.Units.gridUnit * 3 - - background: Rectangle { - radius: 4 - color: setProviderConfigurationButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - } - - contentItem: Item { - RowLayout { - anchors.centerIn: parent - Kirigami.Icon { - Layout.preferredWidth: Kirigami.Units.iconSizes.small - Layout.preferredHeight: Kirigami.Units.iconSizes.small - source: "dialog-ok" - } - Label { - color: setWallpaperButton.enabled ? Kirigami.Theme.textColor : Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.5) - text: qsTr("Apply Configuration") - } - } - } - - onClicked: { - var config = convertArrayToObject(configureProviderPopupDialog.newConfiguration) - Mycroft.MycroftController.sendRequest("ovos.wallpaper.manager.set.provider.config", - {"provider_name": configureProviderPopupDialog.providerName, "config": config}) - configureProviderPopupDialog.close() - } - - Keys.onReturnPressed: { - clicked() - } - } - - Button { - id: rejectConfigurationButton - width: parent.width - height: Mycroft.Units.gridUnit * 3 - - background: Rectangle { - radius: 4 - color: rejectConfigurationButton.activeFocus ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor - } - - contentItem: Item { - RowLayout { - anchors.centerIn: parent - Kirigami.Icon { - Layout.preferredWidth: Kirigami.Units.iconSizes.small - Layout.preferredHeight: Kirigami.Units.iconSizes.small - source: "dialog-cancel" - } - Label { - color: Kirigami.Theme.textColor - text: qsTr("Cancel") - } - } - } - - onClicked: { - configureProviderPopupDialog.close() - } - - Keys.onReturnPressed: { - clicked() - } - } - } - } - } - } -} diff --git a/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_de.qm b/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_de.qm deleted file mode 100644 index 40b5b63dc33df3949f94e69ed6fc4af7cf531b19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6138 zcmb_gU2Ggz6+VvF>$Sb!wbxF>k3%o1N&8@>28jxx2Gw4tiHYl&ZrrLBm6_eSyF2pi z%xY%V&PD=(Py{VdAwg+HtEzcuN*`JYfuNPB`ci0vs1V}kp-}ZDFBOeIh4iWXeCOWX z+1+?%Hv%h)&&=$d@1FCW-#d4_XnyF|e|z%LH$Fc1%9k#_{MNHXG-ArFl@rTELx0E3 z=ZG?YASzsfyhMp_Jb~wb)pFR@a^yKmy#HyU-0PJ8^G|@Vpk?A2Eyq(@PD(AaU(|B? znwGQA(#apZiuXv%=>>Z56CcCfSLwn>1EO)0e)A`muhZ2xKSeZp+t6C$k3?x__*ai! zfR00nXNZy?PQ3RX>vuW1copjpJe+*j z_&4Njqu>7RWBC1_sq*oE5Ty>M-g#LPjomSJ^OGsq^))RIu8tiye4>Nj9kaiH=d=GB zd+3K>!G6z72+4@``Em+}7TiMcml0Du3PIQ$g!O{^P3I&joEON+K*EZSIz+DAToe(LzB6qBk6a^UsmQ(SgFz4vB!gTQ0CPDYAJ0I9? z7gFZ5^c-o6d!^@Ft`iNkhF7-90E`6C5}8m{LP4KosM6$`TQY31WSXAzBNaNP6k^jD z#Qn^R<5WFH?_eb^6a`RmP&!OBSqeI9ErfZ#1J*whoLk*0G&PhfJ(F-ZkSj$O5056O(oYUTa|{VHr=X7N8-};woJ>f z+eTA`z(>Fi97AO&UQuX<;-}kLld!)7bi>fM(k9j6GzMhqPbhBs#@A-uG=kpvx*;nT z0q)T*wz1S^UTe$2wjEkBcMPW_O?Gmxk#pDa=edo#-$UL22Mh+tA*ze`$8lYvD*kqo zEtzM%Y^FO`YWRU$v(C#czmQyk(H-;cr*hkXd7aE9AZvjIhSA**DE`H?P28_6sRLDL?<#1a4k zqzALhkbaA8L1)4BIXo-l7mw?02%lYQ1gNW~O7`BmUQz)LU zGLEwWZVwSgH$1c~xf^TQ5xNiU5Agvd1Z@Dsg1fIk?se^KD{?kGt7dr30scMOgIoaq zHp0n4L5xN})Q(Gux?>K;PtiI|t#yT73Vm6u8#=!uiHfU}gG=*tSSP!if6kOU(st|8 z>n%)2Xa&0Y;I#^_qH1us1d0hVo4PQA7 zUz+RQ5*uU7zLeM)>}Z}$7||K8IIG#LPD7hsv3#S5Y!02$&lk5w`l28H)CuRt;U7UX zwkJWYYJdo36C6m+EG{Jh^2^0j?jt-qHc%Dxsv6`e{D%BfrHf7FcNf&UBHq1%y9&Ho z!IK@VWL(DgAkPAeM{A!rq%gCD5t~;dCt9^H9IH|dYOX1T>ximblYYsQ(peCutV_ql z0M0+4p@_h$VNqFKn?{pqooWqvy?HsWY}nhnWtXe$aB4~{6k!)rJ zjiI3#1-{<4F@B3RdKKJh=CqHvvM~FcF+5s&;L?K{yozUe8&Z2~kEP-EH|MK{Qvu7& z->zZXbpusQ7--%+q~lCs_u+9rk}KLncOvZDo?x$NTlpEcN}g$&u#GJjbUQ8LZ+B~drbs!&r%a6VY{)Tihzl8Bp4 zDunJBK6BSy@gb1F>h*B#fivszOOM9Hg@+6bz#flr-DjKJeWCB~af9%97OnMuxP7LR z$-TMBy*Y+qcsZihgoMnT3X4Mz^|4#cV=EqbRJwx_fpW!LpH~I$167*3%YbQ$Rh(g& z^-SvkvS#_gvU^TVvR-=QnZZ5xWlDcQUUSW{jFv1FfiU~)`h~U zXqZ$x`vhhkJ_W8FA&xJR@; z+>r>$Yc4m1$8?{s(tbDGH&I*;3=RDke?fx^ diff --git a/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_es.qm b/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_es.qm deleted file mode 100644 index f690c6d15e5c195f26589f657ab8896484a8ce5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5770 zcmcgwTWB0r82;02HpwR0O*d6*t?gLj1uZoetwmHwH*FKFN$6^Qkdn^soa~Oy&a5-D zX;RS_Dc*hYQc)3$)C-Crf>cmM@UF!NQ9D+w(%i8Y|dI5d`_;(E=v4$HPO(|l>7coSlA-h#P@Pdy(ZW6xpE!6POd{;wEM{q@I1*i zyNUK+v;p59r^Dy@M1AY%i*I7pCDSjHTBj*9};Ev_NClU z@m!^E{dcbepKtrle-3daf9orbKSnh8s$AEc(|4rfE8NfYiyY$Vxvl?=$-9aA-|zqQ z`84eRG_e2Uy~yYJ^iWqX^8Gx$`>YA%c~|<-BRQhf)pE@~o<90I>d|?5`t5r=5l?3( zTj)am>*Sg|mbr2fe$$6DQ_}_Hbt+SSCV_bGGKtn4!5fsKJULV#mjn_-sQ7e^7Mz;j z&3ARanyKm~(ZNq|ryQQPX_ibXQ4MeDRK)e4_@71wiQunE9#!$2hdVw#bL1%7nK3bE z7KN4?SmyZct5mk!M06*!=Ht_p~du#!nK8^?GvtNI(C%74K#)@kRo0V z!?h4%5eZl-xPd)RQMa^F!*GQc8QR5w%M6k&20#d!$9EYdLm|`EmBlrajy78K%{igv z9NQMSj1F-NO$4|)2(!|HD(B8lCT9X9e2hsy{e@z1aw&!PZwoz0JwyPmTh{3 zM(K7iP$J?f_Q@jDxU9hIP>7^*n7O5D=zcQ;mzB-t_-x=_2hDYqkX;%}3Uv0UF{j%_ zVK4!j6J38AhOSeqdQAYfEy0;zA4J3)QxT-GaOElxk~xmaVz{%#n&&$e^N^VF>P@MN z$1Q``ke&e2cLMKb_6_7*5nx#?i;8Gx?OK|~yWG>PA7ORaHixDm$QWf&L1%M~NSov% zE`gO1t2l4NPzFZ1p)oSe26U_o&>NLXe_mJ+11;|_SZ#6J8jy~qicLv{Weu1|YdZLk zj+*dQ1#QYsfTD7e8Ljz_cC(oG!9B}yxjvb&+CJATD0N$!MZU2tW<|c4LPB*~sX&vG zMzQg+j{J8jM!FxSolBXlFcnY}=61EIOzEBTdZlVXEEK^bt@cBWWc#DlR9fBBE;c)H zFgCBNVmZUj&?tHpxtqbJz-w6EHFXY6yJkgq7tT=Q?aT7z1^lg{MWJDV-_YOL4bBSa zmT_i}n*yjglM<{lec3K=;!M}(k)sFmfHtX14T*$!Q;Xm?D=x+j1^jBIxl6~4tRd!v z=549bc$3wlhJDyXa|EiRdWa=`$MF~QSpvsCsgjv+M1*2+#rctuwT zd$VSUs;~_l2>1pzCe1f1cxX1bHuMDsbFe;Ip5DEq$cZyys)y5k>&6%k%{{@!IA&Jj z&5qDbNGlGwR^y>GqyyuVjZEWR>_ZpnffAYlda_=#aLek;^^x0sYh_y9vmM3&NGJ`t zFjv;?5>RJ659*dx)uDZwj-h}L3OMOlZE#(gW{a-jE}8P>iJ&baHuvqt8=M9WmhL*q(@nhF;i#s<`kw{HW$@leA%f)BxC z`Ys*ud+;-YHi5G_S1DaTTJ14Ce}^+4Ox*|S^AS&Vg+KxH;E1&dqs%d>sXEk_XWvrr zpT-Qu_2Y3>_Pjg@G_vP|FCU9Ty&JxHp(?bpaG|S?rXw!h)=d7{0AE=hEQA#oX8T`= z`Wt6P^&8Pz1Rr_QQ;_$na~%6@wXnkDMXSS=A#$sqbg-%Le#%F-a1QFOD@QaO>mrAR sJm&dv1!<~2DCG0w(MD1*!h<+yrCv%f^`jsEe|xPNsrx~SRUIAw0@*$vtN;K2 diff --git a/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_fr.qm b/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_fr.qm deleted file mode 100644 index 51418740d73bc9948115fd6e0afa328def8ac20d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5784 zcmcIoU2GiH6+X7t>%aA`vo@gxH<=cyP>3KvL1_dL&N{(XjbnKeK&rruckb>EnVnf? zW*s{cJWwGD{ZXZsf*OR%1Eo)q5D0-()K+R~p`bogEg}ess;Y{s1|%x=1qtz;dw1^c zBr~=_MyuUBvpe^k@0|0UpSw4`WPR!N51)MO&96@W=ANftdG}c&>aY4sM-~qe_52Ap z2Z;(F5S4$4^##g2e442DVzu@?q1OJ7Df9muh$ece^v?5;a6qk@x70d(R;~FHY8`t} zt>ahGtv~xco+q^ykI-FT--WxM(nFVqL?buR8-M5Z44pfB9nnCmXRh@(qR~@*uRit= zuzf3&Jups`sb==i{s?#<%{(#tYofll)tbE~^Q)JhAdpTn8hn0m{S`qp^uf?&PYx1||8D4!pFaS(-xzxIX5bh)IV|#T z679Hq_{H!4fvEW4$guw!o_ly?^6VL+u}eq3@)U4o|1(mV`3dg-rPhh-M;`C_EBsf^ zi4yP(p2$5ne?RQloqO#UdC33g=v{wYggrmbkM|D|<-VN1^`cq){#O3f4@*SDo?45q z=AS-;c=TPHfBCz8z%x=PF89O!3AJWV7p^@Az4<>EjxH?2u5*R@=?w5bYa=+%UjT|!ZDWaX&@6aB6 z*Tl<&TtPNDT3%sVtk@M{ltmcYZY@ZXY|!o4@T1YoVP6X{SV~1gKYH$jMltH((SbfQrg@e>L%Hf)`iKjSeRM0qOxEgcq3n6+{ej4yz3s;`5 z68GW0QxytRtF)oe5!lm|`iM434xSramS`gd1X8d&hr#SNJ6adaAUNsy zmaM}mCeF~jtQ)L$kE|k?%@B+L>bb(iE6!HT?gDT;z%bShT$k!{>g*J9zE~C=uKyDO2 zrs(I_HFntDx~ivQsv@HrhzyPgFp?(=TQWFk(}u_Xb-?53s-c~a0TsN^p75-LBZGk} z{*A|6o|mE_H_8K+QCD%7T9htT6Qcpog_ceQEXm;-V@P1QcC8*ZJWCj!Yt+4l2r9l1 z?q0(ZP2pNNZtxFifJSIH@K9A=TjmY!x%GDtiu(uj-&0aqvdk zhiAGw9L7*>>uv;ZkFvDQ48wMf8}}K3Y-cqixMS$r@xA`we8*W28W)h%t;_>3+pu`s17-h~LMvc=uC zbDHA9iAhuo9>gCH#w^bA9F2VYFg9lg;URBT&gys4G3j%4zOYd_Z6M`8Y*foO6V>qf zgpX`dmh&-L)l${;0YXE#{McGk7^d{PzNGIo}TzP=g!Nr$0t;p^PtJthi9g_7U|$*+mfLygH?gA81#GWYc$IXM7|mBgtpG>Alz5FwN;muk~Cw7`QQWx8|PPMDopXJ%X4 z1YZkqA8tW-KxzZVJ${I8p2z$3Uq$k z)OMxqn-Al_xz&E;`T^*BF5cDH40|rd_dV1PJC4QY-b}&HmGKLg;m?LA;-9_TfbaiF zB*zLW9T3yR{mv3K0b`AxWL z(fMjDt51qLes44NQ--qSkVii0G)E?`ZLAs@SiSr+6HiT=CMUp5^oeOREwmBg`=&kV zl|x@mhe(hM6oo2)dQ9H2v04FE{CVNp!qN^2*E1cv9Fzt{ZK;wAusQrV0JE^Bp|(XL z0Bav`(z>Pf8ip&pvT8j=gAniGCkIR&IB97#E5&z1Wp$XX4A%qvWrL2^oA%9Vp`{$# z7Pu_0@+PVB1fX5`_(9)lQWX1L@bf@Ga%9%?MMmqlCmc7USAy?Y=-dFHsfr($abmz? z_M$IUvx|Zn*{!FKvHRDg9ecu@%(+th*rc!pE**EwFukm$&&uTKrj+#C1h6LIOSj0# zqIkedAym!a8>ttdlQI}?K1^o$Tn!9Q9LyTJUz(FOS+c2`CGeJx)YqZJ99EP`AaHrF zF|FHaVQ?yx8ri+TgRYaydL{0wF%*jf#o;O&KRMKaRis@s#kyJS@?<*a`A){16JuV! zU}XrG!*Cb*$3@_w45k+3VtdLJ(xd4qkrCC9w$U)YcZN=6pvR6~}$#n&r40i$oYzpW`D#T4P$3{kDcoD*IhqkVY^nP&ulS zr=q6+Kl#cEUyE=AnF}v+-_qb)55L^oK<9x<@jb`&Ox6NL1PNUhGbu}onK_F%aps0a z-!$x^^@*8^c5Nw}Gt8A?*aKJzA1b&kpGU*4nbF9JErN4N*G-o-H0Xl7^TTmXj53 zDXBePc2;2PJrLYDG-f{-K~i+~>E6`1qq|1&)KCe19f*#RJemO#aAe9=!cKBQjR%9qk=)#Oc#^H=vCclz)5pOAL2#xeK}yxL6e5c0B&P-2jC+heNH#ZSwdWrI{5v6~i!~-wj z`?LPqY5Hr|F-rV-4N>+_%6Z9%A&GkK=-KdM3iiCw^U(A60C%A0;Txex>hE5eK1DQmXYad@d`vWSsIS*KiG8)c zk?-DwpRVn@_$BC-e7dhV@f7aQ`s?t9zQY|~!GHJm%N+FS{;U73>APV^vH#@DY2bf2 zu>aFN@byG`xT}Y#Z(n-H1(QSr7o-n8mV-VY`|HrV=_79<9;?o#-@CUH`W(w-3th1H zXMauZ%v^OEa?_oeUAqgA^H8SzLIV1}Vh{~KfF~$LyJ(&yIWP~3;@ve?uxnm7u6i}T znyG3f*};3Sq%o@ErICZTMji<=$RZb4l1#k#u7qnVM9YlJd7~&rUV5HkmE0)YwX~Bp zz_W~^v;n3;GDJ!5l#V4$ahr5p!?vP9rpTr_rI-oDG|~Yn$qhjUrtG3-iZNYxq#LQo z7TSR)puT#(2(zGsQb+`96_km(Z)k|TdfFCaMbDU*B4=Bc#AURSmr|Y<1Aj@XD41EO z?ckdI*=%z*zvz0hA||a_+o@=Ako|NUbac*fSa%ywC20@Us1$0S*sc}l*rk^gZEMyj z)f^>krX($iOWT>z4Yz7)i;4tmDF=lunuW3@;4l?h6(4{P8ZhS#d^zm{w{!(3X|wW8 zTW0O6>YCTetn;#9tBSIQh-$E-s3Pt_ute00%hfK2N?xKAT2{GsAve!ZSsYSPj?0r~j2?kqWFsNwe{CsGve) zB01~c1b;){rEfW?RjMXRKuFq1yzElE5Tkpyg9arRVyzmDWJ(pv87kC<@{&O3VKy~~ zc6Gp=-HuVwoW*70dv&B7PNE`EEmaufWv!|6RH6#$%S#)fX(Xuz3(jrf%}JX=*A~;7 zUk@T(+pd-_HyR9uwX}IS$m()lns!w>ttD)P##LD9hR$c4bB0GFA z7!+GGcVkRzWRGwSt-wQ#14BwR#Brk%57@5PMz}YmdRjqG*DZ_}FcHkuJj}4an&VfG z9)DZHn`dENMJA&ChoU#+%9>Szf7x>jnrT)wR5+ob`SWOxbBWo;gDaJE(eb$f>A-Pl zu!rN~f;C)47V$l&hM;XUich~I`Bpc_?Gl9S3g5nf1;Vhzwo&1#mZZ*G(egKja|5${ zxvnvYROiD;OSOsyPU1u{NqfT}bnd$K*7%?&LDMms4tKBGH66d1Iqhe0D-W0toV%?j zqU`Nq#P`@m~vz(-b|&?UnYVL@ndf2^nr)#N3SC`=+Aw3%i+ zB{$CYDICbfBu={Q?R0Q#nKE2&yM0hiz6II~7W(y(&*MC)^O!Ag4F-}BeWI@ko?9vN z)vt8?r^EqO2Lr)M0Y2-^vl^-$H>%IZy^B>T%F;o7vxNrDG)owK496|!t_j8B6m9ok zN`L)47XF*UBYNCvsV6)wv8<)f{tpd*sgRW-;!@;6x?RPND=44C8)WDXvOC&rKDFg( q0kDJmeDq diff --git a/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_pt.qm b/ovos_gui/res/ui/translations/SmartSpeakerExtension.GuiInterface_pt.qm deleted file mode 100644 index b1e9ceb76aec12f60fb021af2ec844eb82669498..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5648 zcmcIoU2GiH6+VvF>-FERy*3C^hfE6yHH{*JTtrb)$zF$KRbyLT2cD=q-nsS;nVnf? zW*s{cc>p13Y4ZYsszFtwDs3OCR232e351aN3qR@uY9$f{H3A7LHHs8OUOevwGO;Z58ZwX{(F|5_+CiV{SAHaFRVRtbm`n(M4ds~Wc{B+y7xM|M5KJj%F73eMyu#k@?SSf~f0E*R3yP;7_6Jm%lp(xj*ds)jrtK^Y=J|}v1{2q3tKj|qSdW!HzEYdpdjIh9Xg4F?;kk1>kVATJxjXQ)dv5 z_8r+*9&d-7uXFi@4*1`%*7P&EJ1;?RwwRlqS%6>XbCr`R*!d%yXlMscP&bvxqXqIw zz(JUbSI5|bR}VY+Ta$P5HFHU{@zeKE0Z+TMNH#4|9j8qCoW3GK0U2cBJASwEUk&>J zyAZEs^0e&SgjlxA!YGL_wB4m3PK!YgK%$THpEe}2+{5xS7w?Ximi?LVUEvrH2tTkr zH%{0v?T5jZJS<==i*oQ@hUrZ~eUo0U!v%!G7L}=SvwWDr-C6eBMSH34OSSV$!WGzh{=8)eHOE|)B)KV; zBydby(FatTVm2*!4~@aBItLEO9L4JEaKtcDtIHj#S!NjJ+@?I)mE;N3n!w3K@IJ@8 z)q>THW7e|imW9Qkk2*Pg4SK#;uLTk4HW7l&2q{R*%7~_eov(pN7uYg~0neA~LFiTO zqhda2q@oPocDU>VU4<>@^&>z$%D}#YFC?Djil~Z>q>a)H&T=Mm%KWc!%NN#cjFgKc z)3>HLC23Rjz=3;Zz@^+{Ix=Kj^iX3o?!6`9pa>YHaMjrmFWi$5#bQ(~<=kI^I4)Wy z;=sEqU6cw?hO~m*SUvQNIk6Igb<AOmfW#ha4vv-c1lJ;oK%T6?-z%AXL-Xw4zU< zjsG77W0l{A;@`qxi7S`5{XmsDU5kV%yMM*3)*KWHP3%~yLny6WnIn}*$D(t_#}y}z zB>FcZZ<1E#ut_Ff2&oKyO{O3RTBf2FJ=EaQjBi&>fAu=C9=)!fK(e=v)U?*=x^a!O z0#(bpzBYrVBstj^MPByCrH28N%f!`QWN`NzQ>LmMu>h+yNNO{#sk{_u$pgCfwzd~} zODqe=s|i0^>X;nYb_UAw8lqw2yVh1?V8RS43!dp)tzANr>{}%EE>&b)lcnaHQfJH{ zIO6%1tfvVk-xUFwp{`3FDx#?Fi{IlMXi;@2K-<&^K#~W0WADCeTRpCJ0!XQzVHtb& zwRz*@(e5eiqa{4Szbz`^3EB+V@B|2v>QdF67l+-zgdLa*s0=z>8%1fm>{Gb!O_tcd z-`%{xV=V#=;A^0Cd5tV{vE!!5M-=!QzGe-4qV9e}^4OMl6kor)@g4WVH5oPDaRw;j z@VN^1+|;k-FgNqf*0Ug+T3r2s;o3`;uZKpmZ%BWLTk@o;Nmet zyNZVv<=!$^8MyvNyBN*K5#(bDtUE-r*cH$k-;Z^Q=4cxBjNxoFbT4aZq}?6J+X>2Ty64s(GmEnUqFa+r@zL9hSOwr2Gm+;k#(`f= zCaUS_ZW_U-Ts3%rRP1Y3@SO=J>tWiBgm?d7&T5iKrc z(MG)}sae%xGZ_AjA|`8&OSUl-P1->??ybn)c@81xpFQ|T4b`#nXk_cmR*YY-sE)km zI?Shd_iwy-faN)%SzB+LTdfJBB79U#&oE(&=^8c<`uLZ#-+?JfrfvKyPVd@;r+>#8 zLKwJnQ1e7%mexpg>A8#btv|h`t-*SATSL+Hdis&xD~QViUNY}AAf1gW5f8^u%k9jg qTM2&$_1W&mMPDi%j6co;l8IO}sgPoV$3MK4`4dItDTIDod)s#&gAIfL diff --git a/ovos_gui/res/ui/translations/about_page_de.ts b/ovos_gui/res/ui/translations/about_page_de.ts deleted file mode 100644 index 779f3b4..0000000 --- a/ovos_gui/res/ui/translations/about_page_de.ts +++ /dev/null @@ -1,43 +0,0 @@ - - - - - about_page - - - About - Über - - - - System Information - Systeminfo - - - - Kernel Version - Kernel Version - - - - Version - Version - - - - - Local Address - Lokale Adresse - - - - No Active Connection - Keine aktive Verbindung - - - - Device Settings - Geräteeinstellungen - - - diff --git a/ovos_gui/res/ui/translations/about_page_es.ts b/ovos_gui/res/ui/translations/about_page_es.ts deleted file mode 100644 index 2b78dc4..0000000 --- a/ovos_gui/res/ui/translations/about_page_es.ts +++ /dev/null @@ -1,43 +0,0 @@ - - - - - about_page - - - About - Sobre - - - - System Information - Información del sistema - - - - Kernel Version - Versión del núcleo - - - - Version - Versión - - - - - Local Address - Dirección local - - - - No Active Connection - Sin conexión activa - - - - Device Settings - Configuración de dispositivo - - - diff --git a/ovos_gui/res/ui/translations/about_page_fr.ts b/ovos_gui/res/ui/translations/about_page_fr.ts deleted file mode 100644 index 91956a9..0000000 --- a/ovos_gui/res/ui/translations/about_page_fr.ts +++ /dev/null @@ -1,43 +0,0 @@ - - - - - about_page - - - About - À propos de - - - - System Information - Informations système - - - - Kernel Version - Version du noyau - - - - Version - Version - - - - - Local Address - Adresse locale - - - - No Active Connection - Aucune connexion active - - - - Device Settings - Réglages de l'appareil - - - diff --git a/ovos_gui/res/ui/translations/about_page_it.ts b/ovos_gui/res/ui/translations/about_page_it.ts deleted file mode 100644 index cd62d6e..0000000 --- a/ovos_gui/res/ui/translations/about_page_it.ts +++ /dev/null @@ -1,43 +0,0 @@ - - - - - about_page - - - About - Di - - - - System Information - Informazioni di sistema - - - - Kernel Version - Versione kernel - - - - Version - Versione - - - - - Local Address - Indirizzo locale - - - - No Active Connection - Nessuna connessione attiva - - - - Device Settings - Impostazioni dispositivo - - - diff --git a/ovos_gui/res/ui/translations/about_page_nl.ts b/ovos_gui/res/ui/translations/about_page_nl.ts deleted file mode 100644 index fb40fec..0000000 --- a/ovos_gui/res/ui/translations/about_page_nl.ts +++ /dev/null @@ -1,43 +0,0 @@ - - - - - about_page - - - About - Over - - - - System Information - Systeeminformatie - - - - Kernel Version - Kernelversie - - - - Version - Versie - - - - - Local Address - Lokaal adres - - - - No Active Connection - Geen actieve verbinding - - - - Device Settings - Apparaat instellingen - - - diff --git a/ovos_gui/res/ui/translations/about_page_pt.ts b/ovos_gui/res/ui/translations/about_page_pt.ts deleted file mode 100644 index d9c0cd4..0000000 --- a/ovos_gui/res/ui/translations/about_page_pt.ts +++ /dev/null @@ -1,43 +0,0 @@ - - - - - about_page - - - About - Sobre - - - - System Information - Informação do sistema - - - - Kernel Version - Versão do kernel - - - - Version - Versão - - - - - Local Address - Endereço local - - - - No Active Connection - Sem conexão ativa - - - - Device Settings - Configurações do dispositivo - - - diff --git a/ovos_gui/res/ui/translations/configuration_generator_display_de.ts b/ovos_gui/res/ui/translations/configuration_generator_display_de.ts deleted file mode 100644 index 1209620..0000000 --- a/ovos_gui/res/ui/translations/configuration_generator_display_de.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - - configuration_generator_display - - - Configuration - Konfiguration - - - - Back - Zurück - - - - Update Settings - Update Einstellungen - - - diff --git a/ovos_gui/res/ui/translations/configuration_generator_display_es.ts b/ovos_gui/res/ui/translations/configuration_generator_display_es.ts deleted file mode 100644 index f9f1745..0000000 --- a/ovos_gui/res/ui/translations/configuration_generator_display_es.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - - configuration_generator_display - - - Configuration - Configuración - - - - Back - atrás - - - - Update Settings - Ajustes de actualización - - - diff --git a/ovos_gui/res/ui/translations/configuration_generator_display_fr.ts b/ovos_gui/res/ui/translations/configuration_generator_display_fr.ts deleted file mode 100644 index 4957b0a..0000000 --- a/ovos_gui/res/ui/translations/configuration_generator_display_fr.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - - configuration_generator_display - - - Configuration - Configuration - - - - Back - Retour - - - - Update Settings - Mettre à jour les paramètres - - - diff --git a/ovos_gui/res/ui/translations/configuration_generator_display_it.ts b/ovos_gui/res/ui/translations/configuration_generator_display_it.ts deleted file mode 100644 index 910f6de..0000000 --- a/ovos_gui/res/ui/translations/configuration_generator_display_it.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - - configuration_generator_display - - - Configuration - Configurazione - - - - Back - Di ritorno - - - - Update Settings - Aggiorna impostazioni - - - diff --git a/ovos_gui/res/ui/translations/configuration_generator_display_nl.ts b/ovos_gui/res/ui/translations/configuration_generator_display_nl.ts deleted file mode 100644 index 4491e71..0000000 --- a/ovos_gui/res/ui/translations/configuration_generator_display_nl.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - - configuration_generator_display - - - Configuration - Configuratie - - - - Back - Rug - - - - Update Settings - Update-instellingen - - - diff --git a/ovos_gui/res/ui/translations/configuration_generator_display_pt.ts b/ovos_gui/res/ui/translations/configuration_generator_display_pt.ts deleted file mode 100644 index 3aec04f..0000000 --- a/ovos_gui/res/ui/translations/configuration_generator_display_pt.ts +++ /dev/null @@ -1,22 +0,0 @@ - - - - - configuration_generator_display - - - Configuration - Configuração - - - - Back - De volta - - - - Update Settings - Atualizar configurações - - - diff --git a/ovos_gui/res/ui/translations/configuration_groups_display_de.ts b/ovos_gui/res/ui/translations/configuration_groups_display_de.ts deleted file mode 100644 index 9013e0a..0000000 --- a/ovos_gui/res/ui/translations/configuration_groups_display_de.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - configuration_groups_display - - - Advanced Configuration - Erweiterte Konfiguration - - - - Back - Zurück - - - diff --git a/ovos_gui/res/ui/translations/configuration_groups_display_es.ts b/ovos_gui/res/ui/translations/configuration_groups_display_es.ts deleted file mode 100644 index 7ed7ac7..0000000 --- a/ovos_gui/res/ui/translations/configuration_groups_display_es.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - configuration_groups_display - - - Advanced Configuration - Configuración avanzada - - - - Back - atrás - - - diff --git a/ovos_gui/res/ui/translations/configuration_groups_display_fr.ts b/ovos_gui/res/ui/translations/configuration_groups_display_fr.ts deleted file mode 100644 index e45fdb1..0000000 --- a/ovos_gui/res/ui/translations/configuration_groups_display_fr.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - configuration_groups_display - - - Advanced Configuration - Réglages avancés - - - - Back - Retour - - - diff --git a/ovos_gui/res/ui/translations/configuration_groups_display_it.ts b/ovos_gui/res/ui/translations/configuration_groups_display_it.ts deleted file mode 100644 index 5731cc1..0000000 --- a/ovos_gui/res/ui/translations/configuration_groups_display_it.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - configuration_groups_display - - - Advanced Configuration - Configurazione avanzata - - - - Back - Di ritorno - - - diff --git a/ovos_gui/res/ui/translations/configuration_groups_display_nl.ts b/ovos_gui/res/ui/translations/configuration_groups_display_nl.ts deleted file mode 100644 index 79d41f2..0000000 --- a/ovos_gui/res/ui/translations/configuration_groups_display_nl.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - configuration_groups_display - - - Advanced Configuration - Geavanceerde configuratie - - - - Back - Rug - - - diff --git a/ovos_gui/res/ui/translations/configuration_groups_display_pt.ts b/ovos_gui/res/ui/translations/configuration_groups_display_pt.ts deleted file mode 100644 index 36aa6d0..0000000 --- a/ovos_gui/res/ui/translations/configuration_groups_display_pt.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - configuration_groups_display - - - Advanced Configuration - Configuração avançada - - - - Back - De volta - - - diff --git a/ovos_gui/res/ui/translations/customize_settings_de.ts b/ovos_gui/res/ui/translations/customize_settings_de.ts deleted file mode 100644 index ae170dd..0000000 --- a/ovos_gui/res/ui/translations/customize_settings_de.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - customize_settings - - - Customize Settings - Einstellungen anpassen - - - - Device Settings - Geräteeinstellungen - - - - Create Scheme - Schema erstellen - - - - Select Style - Stilauswahl - - - - Cancel - Abbrechen - - - diff --git a/ovos_gui/res/ui/translations/customize_settings_es.ts b/ovos_gui/res/ui/translations/customize_settings_es.ts deleted file mode 100644 index 200eea7..0000000 --- a/ovos_gui/res/ui/translations/customize_settings_es.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - customize_settings - - - Customize Settings - Personalizar la configuración - - - - Device Settings - Configuración de dispositivo - - - - Create Scheme - Crear esquema - - - - Select Style - Seleccionar estilo - - - - Cancel - Cancelar - - - diff --git a/ovos_gui/res/ui/translations/customize_settings_fr.ts b/ovos_gui/res/ui/translations/customize_settings_fr.ts deleted file mode 100644 index 7c6443f..0000000 --- a/ovos_gui/res/ui/translations/customize_settings_fr.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - customize_settings - - - Customize Settings - Personnaliser les paramètres - - - - Device Settings - Réglages de l'appareil - - - - Create Scheme - Créer un schéma - - - - Select Style - Sélectionnez Style - - - - Cancel - Annuler - - - diff --git a/ovos_gui/res/ui/translations/customize_settings_it.ts b/ovos_gui/res/ui/translations/customize_settings_it.ts deleted file mode 100644 index 2422bdf..0000000 --- a/ovos_gui/res/ui/translations/customize_settings_it.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - customize_settings - - - Customize Settings - Personalizza le impostazioni - - - - Device Settings - Impostazioni dispositivo - - - - Create Scheme - Crea schema - - - - Select Style - Seleziona Stile - - - - Cancel - Annulla - - - diff --git a/ovos_gui/res/ui/translations/customize_settings_nl.ts b/ovos_gui/res/ui/translations/customize_settings_nl.ts deleted file mode 100644 index 046d15b..0000000 --- a/ovos_gui/res/ui/translations/customize_settings_nl.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - customize_settings - - - Customize Settings - Instellingen aanpassen - - - - Device Settings - Apparaat instellingen - - - - Create Scheme - Schema maken - - - - Select Style - Selecteer stijl - - - - Cancel - Annuleren - - - diff --git a/ovos_gui/res/ui/translations/customize_settings_pt.ts b/ovos_gui/res/ui/translations/customize_settings_pt.ts deleted file mode 100644 index a9ca5a1..0000000 --- a/ovos_gui/res/ui/translations/customize_settings_pt.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - customize_settings - - - Customize Settings - Personalizar configurações - - - - Device Settings - Configurações do dispositivo - - - - Create Scheme - Criar esquema - - - - Select Style - Selecionar estilo - - - - Cancel - Cancelar - - - diff --git a/ovos_gui/res/ui/translations/customize_theme_de.ts b/ovos_gui/res/ui/translations/customize_theme_de.ts deleted file mode 100644 index ff56825..0000000 --- a/ovos_gui/res/ui/translations/customize_theme_de.ts +++ /dev/null @@ -1,58 +0,0 @@ - - - - - customize_theme - - - Example Scheme - Beispielschema - - - - Create Scheme - Schema erstellen - - - - Select Primary Color - Wähle Primärfarbe - - - - Select Secondary Color - Wähle Sekundärfarbe - - - - Auto Text Color - Automatische Textfarbe - - - - Set Name - Name - - - - - Preview - Vorschau - - - - Create - Erstellen - - - - Back - Zurück - - - - Cancel - Abbrechen - - - diff --git a/ovos_gui/res/ui/translations/customize_theme_es.ts b/ovos_gui/res/ui/translations/customize_theme_es.ts deleted file mode 100644 index f445e39..0000000 --- a/ovos_gui/res/ui/translations/customize_theme_es.ts +++ /dev/null @@ -1,58 +0,0 @@ - - - - - customize_theme - - - Example Scheme - Esquema de ejemplo - - - - Create Scheme - Crear esquema - - - - Select Primary Color - Seleccionar color primario - - - - Select Secondary Color - Seleccionar color secundario - - - - Auto Text Color - Color de texto automático - - - - Set Name - Escoger un nombre - - - - - Preview - Avance - - - - Create - Crear - - - - Back - atrás - - - - Cancel - Cancelar - - - diff --git a/ovos_gui/res/ui/translations/customize_theme_fr.ts b/ovos_gui/res/ui/translations/customize_theme_fr.ts deleted file mode 100644 index e3914dd..0000000 --- a/ovos_gui/res/ui/translations/customize_theme_fr.ts +++ /dev/null @@ -1,58 +0,0 @@ - - - - - customize_theme - - - Example Scheme - Exemple de schéma - - - - Create Scheme - Créer un schéma - - - - Select Primary Color - Sélectionnez la couleur primaire - - - - Select Secondary Color - Sélectionnez la couleur secondaire - - - - Auto Text Color - Couleur du texte automatique - - - - Set Name - Définir le nom - - - - - Preview - Aperçu - - - - Create - Créer - - - - Back - Retour - - - - Cancel - Annuler - - - diff --git a/ovos_gui/res/ui/translations/customize_theme_it.ts b/ovos_gui/res/ui/translations/customize_theme_it.ts deleted file mode 100644 index 208b390..0000000 --- a/ovos_gui/res/ui/translations/customize_theme_it.ts +++ /dev/null @@ -1,58 +0,0 @@ - - - - - customize_theme - - - Example Scheme - Schema di esempio - - - - Create Scheme - Crea schema - - - - Select Primary Color - Seleziona Colore primario - - - - Select Secondary Color - Seleziona Colore secondario - - - - Auto Text Color - Colore testo automatico - - - - Set Name - Imposta nome - - - - - Preview - Anteprima - - - - Create - Creare - - - - Back - Di ritorno - - - - Cancel - Annulla - - - diff --git a/ovos_gui/res/ui/translations/customize_theme_nl.ts b/ovos_gui/res/ui/translations/customize_theme_nl.ts deleted file mode 100644 index 0522c54..0000000 --- a/ovos_gui/res/ui/translations/customize_theme_nl.ts +++ /dev/null @@ -1,58 +0,0 @@ - - - - - customize_theme - - - Example Scheme - Voorbeeldschema - - - - Create Scheme - Schema maken - - - - Select Primary Color - Selecteer primaire kleur - - - - Select Secondary Color - Selecteer secundaire kleur - - - - Auto Text Color - Automatische tekstkleur - - - - Set Name - Naam instellen - - - - - Preview - Voorbeeld - - - - Create - Creëren - - - - Back - Rug - - - - Cancel - Annuleren - - - diff --git a/ovos_gui/res/ui/translations/customize_theme_pt.ts b/ovos_gui/res/ui/translations/customize_theme_pt.ts deleted file mode 100644 index c08b723..0000000 --- a/ovos_gui/res/ui/translations/customize_theme_pt.ts +++ /dev/null @@ -1,58 +0,0 @@ - - - - - customize_theme - - - Example Scheme - Esquema de Exemplo - - - - Create Scheme - Criar esquema - - - - Select Primary Color - Selecione a cor primária - - - - Select Secondary Color - Selecione a cor secundária - - - - Auto Text Color - Cor do texto automático - - - - Set Name - Nome do conjunto - - - - - Preview - Visualizar - - - - Create - Crio - - - - Back - De volta - - - - Cancel - Cancelar - - - diff --git a/ovos_gui/res/ui/translations/developer_settings_de.ts b/ovos_gui/res/ui/translations/developer_settings_de.ts deleted file mode 100644 index 90b68bd..0000000 --- a/ovos_gui/res/ui/translations/developer_settings_de.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - developer_settings - - - Developer Settings - Entwicklereinstellungen - - - - Advanced Settings - Erweiterte Einstellungen - - - - Enable Dashboard - Dashboard aktivieren - - - - Disable Dashboard - Dashboard deaktivieren - - - - Dashboard Address - Dashboard Adresse - - - - Dashboard Username - Dashboard Benutzername - - - - Dashboard Password - Dashboard Passwort - - - - Device Settings - Geräteeinstellungen - - - diff --git a/ovos_gui/res/ui/translations/developer_settings_es.ts b/ovos_gui/res/ui/translations/developer_settings_es.ts deleted file mode 100644 index 0616f88..0000000 --- a/ovos_gui/res/ui/translations/developer_settings_es.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - developer_settings - - - Developer Settings - Configuración del desarrollador - - - - Advanced Settings - Ajustes avanzados - - - - Enable Dashboard - Habilitar panel - - - - Disable Dashboard - Deshabilitar panel - - - - Dashboard Address - Dirección del tablero - - - - Dashboard Username - Nombre de usuario del panel - - - - Dashboard Password - Contraseña del panel - - - - Device Settings - Configuración de dispositivo - - - diff --git a/ovos_gui/res/ui/translations/developer_settings_fr.ts b/ovos_gui/res/ui/translations/developer_settings_fr.ts deleted file mode 100644 index 0726b22..0000000 --- a/ovos_gui/res/ui/translations/developer_settings_fr.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - developer_settings - - - Developer Settings - Paramètres du développeur - - - - Advanced Settings - Réglages avancés - - - - Enable Dashboard - Activer le tableau de bord - - - - Disable Dashboard - Désactiver le tableau de bord - - - - Dashboard Address - Adresse du tableau de bord - - - - Dashboard Username - Nom d'utilisateur du tableau de bord - - - - Dashboard Password - Mot de passe du tableau de bord - - - - Device Settings - Réglages de l'appareil - - - diff --git a/ovos_gui/res/ui/translations/developer_settings_it.ts b/ovos_gui/res/ui/translations/developer_settings_it.ts deleted file mode 100644 index 5a10478..0000000 --- a/ovos_gui/res/ui/translations/developer_settings_it.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - developer_settings - - - Developer Settings - Paramètres du développeur - - - - Advanced Settings - Impostazioni avanzate - - - - Enable Dashboard - Abilita dashboard - - - - Disable Dashboard - Disabilita dashboard - - - - Dashboard Address - Indirizzo dashboard - - - - Dashboard Username - Nome utente dashboard - - - - Dashboard Password - Password dashboard - - - - Device Settings - Impostazioni dispositivo - - - diff --git a/ovos_gui/res/ui/translations/developer_settings_nl.ts b/ovos_gui/res/ui/translations/developer_settings_nl.ts deleted file mode 100644 index 9bbe476..0000000 --- a/ovos_gui/res/ui/translations/developer_settings_nl.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - developer_settings - - - Developer Settings - Ontwikkelaarsinstellingen - - - - Advanced Settings - Geavanceerde instellingen - - - - Enable Dashboard - Dashboard inschakelen - - - - Disable Dashboard - Dashboard uitschakelen - - - - Dashboard Address - Dashboardadres - - - - Dashboard Username - Dashboard-gebruikersnaam - - - - Dashboard Password - Dashboardwachtwoord - - - - Device Settings - Apparaat instellingen - - - diff --git a/ovos_gui/res/ui/translations/developer_settings_pt.ts b/ovos_gui/res/ui/translations/developer_settings_pt.ts deleted file mode 100644 index 69f5d68..0000000 --- a/ovos_gui/res/ui/translations/developer_settings_pt.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - developer_settings - - - Developer Settings - Configurações do desenvolvedor - - - - Advanced Settings - Configurações avançadas - - - - Enable Dashboard - Ativar painel - - - - Disable Dashboard - Desativar painel - - - - Dashboard Address - Endereço do painel - - - - Dashboard Username - Nome de usuário do painel - - - - Dashboard Password - Senha do painel - - - - Device Settings - Configurações do dispositivo - - - diff --git a/ovos_gui/res/ui/translations/display_settings_de.ts b/ovos_gui/res/ui/translations/display_settings_de.ts deleted file mode 100644 index 5ca29bc..0000000 --- a/ovos_gui/res/ui/translations/display_settings_de.ts +++ /dev/null @@ -1,61 +0,0 @@ - - - - - display_settings - - - Display Settings - Bildschirmeinstellungen - - - - Wallpaper Rotation - Hintergrundrotation - - - - Changes the wallpaper automatically - Ändert das Hintergrundbild automatisch - - - - - - ON - AN - - - - - - OFF - AUS - - - - Auto Dim - automatisch dimmen - - - - Dim's the display in 60 seconds - Dimme das Display in 60 Sekunden - - - - Auto Nightmode - Automatischer Nachtmodus - - - - Activates nightmode on homescreen, depending on the time of the day - Aktiviert den Nachtmodus auf dem Homescreen, abhängig von der Tageszeit - - - - Device Settings - Geräteeinstellungen - - - diff --git a/ovos_gui/res/ui/translations/display_settings_es.ts b/ovos_gui/res/ui/translations/display_settings_es.ts deleted file mode 100644 index e0f2643..0000000 --- a/ovos_gui/res/ui/translations/display_settings_es.ts +++ /dev/null @@ -1,61 +0,0 @@ - - - - - display_settings - - - Display Settings - Configuración de pantalla - - - - Wallpaper Rotation - Rotación de papel tapiz - - - - Changes the wallpaper automatically - Cambia el fondo de pantalla automáticamente - - - - - - ON - EN - - - - - - OFF - APAGADO - - - - Auto Dim - Atenuación automática - - - - Dim's the display in 60 seconds - Oscurece la pantalla en 60 segundos - - - - Auto Nightmode - Modo nocturno automático - - - - Activates nightmode on homescreen, depending on the time of the day - Activa el modo nocturno en la pantalla de inicio, según la hora del día - - - - Device Settings - Configuración de dispositivo - - - diff --git a/ovos_gui/res/ui/translations/display_settings_fr.ts b/ovos_gui/res/ui/translations/display_settings_fr.ts deleted file mode 100644 index d423ea0..0000000 --- a/ovos_gui/res/ui/translations/display_settings_fr.ts +++ /dev/null @@ -1,61 +0,0 @@ - - - - - display_settings - - - Display Settings - Paramètres d'affichage - - - - Wallpaper Rotation - Rotation du papier peint - - - - Changes the wallpaper automatically - Change automatiquement le fond d'écran - - - - - - ON - SUR - - - - - - OFF - À L'ARRÊT - - - - Auto Dim - Atténuation automatique - - - - Dim's the display in 60 seconds - Estompe l'affichage en 60 secondes - - - - Auto Nightmode - Mode nuit automatique - - - - Activates nightmode on homescreen, depending on the time of the day - Active le mode nuit sur l'écran d'accueil, en fonction de l'heure de la journée - - - - Device Settings - Réglages de l'appareil - - - diff --git a/ovos_gui/res/ui/translations/display_settings_it.ts b/ovos_gui/res/ui/translations/display_settings_it.ts deleted file mode 100644 index d759b5f..0000000 --- a/ovos_gui/res/ui/translations/display_settings_it.ts +++ /dev/null @@ -1,61 +0,0 @@ - - - - - display_settings - - - Display Settings - Impostazioni di visualizzazione - - - - Wallpaper Rotation - Rotazione dello sfondo - - - - Changes the wallpaper automatically - Cambia automaticamente lo sfondo - - - - - - ON - SU - - - - - - OFF - SPENTO - - - - Auto Dim - Oscuramento automatico - - - - Dim's the display in 60 seconds - Oscuramento automatico - - - - Auto Nightmode - Oscuramento automatico - - - - Activates nightmode on homescreen, depending on the time of the day - Attiva la modalità notturna sulla schermata iniziale, a seconda dell'ora del giorno - - - - Device Settings - Impostazioni dispositivo - - - diff --git a/ovos_gui/res/ui/translations/display_settings_nl.ts b/ovos_gui/res/ui/translations/display_settings_nl.ts deleted file mode 100644 index 6df0453..0000000 --- a/ovos_gui/res/ui/translations/display_settings_nl.ts +++ /dev/null @@ -1,61 +0,0 @@ - - - - - display_settings - - - Display Settings - Scherminstellingen - - - - Wallpaper Rotation - Achtergrondrotatie - - - - Changes the wallpaper automatically - Verandert de achtergrond automatisch - - - - - - ON - AAN - - - - - - OFF - UIT - - - - Auto Dim - Automatisch dimmen - - - - Dim's the display in 60 seconds - Dim het display in 60 seconden - - - - Auto Nightmode - Automatische nachtmodus - - - - Activates nightmode on homescreen, depending on the time of the day - Activeert de nachtmodus op het startscherm, afhankelijk van het tijdstip van de dag - - - - Device Settings - Apparaat instellingen - - - diff --git a/ovos_gui/res/ui/translations/display_settings_pt.ts b/ovos_gui/res/ui/translations/display_settings_pt.ts deleted file mode 100644 index f0e31ad..0000000 --- a/ovos_gui/res/ui/translations/display_settings_pt.ts +++ /dev/null @@ -1,61 +0,0 @@ - - - - - display_settings - - - Display Settings - Configurações do visor - - - - Wallpaper Rotation - Rotação do papel de parede - - - - Changes the wallpaper automatically - Muda o papel de parede automaticamente - - - - - - ON - SOBRE - - - - - - OFF - DESLIGADO - - - - Auto Dim - ESCURECIMENTO AUTOMÁTICO - - - - Dim's the display in 60 seconds - Escureça a tela em 60 segundos - - - - Auto Nightmode - Modo noturno automático - - - - Activates nightmode on homescreen, depending on the time of the day - Ativa o modo noturno na tela inicial, dependendo da hora do dia - - - - Device Settings - Configurações do dispositivo - - - diff --git a/ovos_gui/res/ui/translations/homescreen_settings_de.ts b/ovos_gui/res/ui/translations/homescreen_settings_de.ts deleted file mode 100644 index 4294b90..0000000 --- a/ovos_gui/res/ui/translations/homescreen_settings_de.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - homescreen_settings - - - Homescreen Settings - Einstellungen Homescreen - - - - Device Settings - Geräteeinstellungen - - - diff --git a/ovos_gui/res/ui/translations/homescreen_settings_es.ts b/ovos_gui/res/ui/translations/homescreen_settings_es.ts deleted file mode 100644 index 7fced8c..0000000 --- a/ovos_gui/res/ui/translations/homescreen_settings_es.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - homescreen_settings - - - Homescreen Settings - Configuración de la pantalla de inicio - - - - Device Settings - Configuración de dispositivo - - - diff --git a/ovos_gui/res/ui/translations/homescreen_settings_fr.ts b/ovos_gui/res/ui/translations/homescreen_settings_fr.ts deleted file mode 100644 index ada9f4f..0000000 --- a/ovos_gui/res/ui/translations/homescreen_settings_fr.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - homescreen_settings - - - Homescreen Settings - Paramètres de l'écran d'accueil - - - - Device Settings - Réglages de l'appareil - - - diff --git a/ovos_gui/res/ui/translations/homescreen_settings_it.ts b/ovos_gui/res/ui/translations/homescreen_settings_it.ts deleted file mode 100644 index 4059dbf..0000000 --- a/ovos_gui/res/ui/translations/homescreen_settings_it.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - homescreen_settings - - - Homescreen Settings - Impostazioni della schermata iniziale - - - - Device Settings - Impostazioni dispositivo - - - diff --git a/ovos_gui/res/ui/translations/homescreen_settings_nl.ts b/ovos_gui/res/ui/translations/homescreen_settings_nl.ts deleted file mode 100644 index 9c82f32..0000000 --- a/ovos_gui/res/ui/translations/homescreen_settings_nl.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - homescreen_settings - - - Homescreen Settings - Instellingen startscherm - - - - Device Settings - Apparaat instellingen - - - diff --git a/ovos_gui/res/ui/translations/homescreen_settings_pt.ts b/ovos_gui/res/ui/translations/homescreen_settings_pt.ts deleted file mode 100644 index dbf10db..0000000 --- a/ovos_gui/res/ui/translations/homescreen_settings_pt.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - homescreen_settings - - - Homescreen Settings - Configurações da tela inicial - - - - Device Settings - Configurações do dispositivo - - - diff --git a/ovos_gui/res/ui/translations/lrelease-generator.sh b/ovos_gui/res/ui/translations/lrelease-generator.sh deleted file mode 100755 index 7d15045..0000000 --- a/ovos_gui/res/ui/translations/lrelease-generator.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -lrelease about_page_de.ts settingspage_de.ts ssh_settings_de.ts homescreen_settings_de.ts configuration_generator_display_de.ts configuration_groups_display_de.ts customize_settings_de.ts customize_theme_de.ts developer_settings_de.ts display_settings_de.ts settingListBox_de.ts -qm SmartSpeakerExtension.GuiInterface_de.qm - -lrelease about_page_es.ts settingspage_es.ts ssh_settings_es.ts homescreen_settings_es.ts configuration_generator_display_es.ts configuration_groups_display_es.ts customize_settings_es.ts customize_theme_es.ts developer_settings_es.ts display_settings_es.ts settingListBox_es.ts -qm SmartSpeakerExtension.GuiInterface_es.qm - -lrelease about_page_nl.ts settingspage_nl.ts ssh_settings_nl.ts homescreen_settings_nl.ts configuration_generator_display_nl.ts configuration_groups_display_nl.ts customize_settings_nl.ts customize_theme_nl.ts developer_settings_nl.ts display_settings_nl.ts settingListBox_nl.ts -qm SmartSpeakerExtension.GuiInterface_nl.qm - -lrelease about_page_fr.ts settingspage_fr.ts ssh_settings_fr.ts homescreen_settings_fr.ts configuration_generator_display_fr.ts configuration_groups_display_fr.ts customize_settings_fr.ts customize_theme_fr.ts developer_settings_fr.ts display_settings_fr.ts settingListBox_fr.ts -qm SmartSpeakerExtension.GuiInterface_fr.qm - -lrelease about_page_pt.ts settingspage_pt.ts ssh_settings_pt.ts homescreen_settings_pt.ts configuration_generator_display_pt.ts configuration_groups_display_pt.ts customize_settings_pt.ts customize_theme_pt.ts developer_settings_pt.ts display_settings_pt.ts settingListBox_pt.ts -qm SmartSpeakerExtension.GuiInterface_pt.qm - -lrelease about_page_it.ts settingspage_it.ts ssh_settings_it.ts homescreen_settings_it.ts configuration_generator_display_it.ts configuration_groups_display_it.ts customize_settings_it.ts customize_theme_it.ts developer_settings_it.ts display_settings_it.ts settingListBox_it.ts -qm SmartSpeakerExtension.GuiInterface_it.qm - diff --git a/ovos_gui/res/ui/translations/settingListBox_de.ts b/ovos_gui/res/ui/translations/settingListBox_de.ts deleted file mode 100644 index 5c86191..0000000 --- a/ovos_gui/res/ui/translations/settingListBox_de.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - settingListBox - - - Type here to add an item to the list - Namen des Elements, das zur Liste hinzugefügt werden soll - - - - Add Item - Element hinzufügen - - - diff --git a/ovos_gui/res/ui/translations/settingListBox_es.ts b/ovos_gui/res/ui/translations/settingListBox_es.ts deleted file mode 100644 index 6321290..0000000 --- a/ovos_gui/res/ui/translations/settingListBox_es.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - settingListBox - - - Type here to add an item to the list - Escriba aquí para agregar un elemento a la lista - - - - Add Item - Añadir artículo - - - diff --git a/ovos_gui/res/ui/translations/settingListBox_fr.ts b/ovos_gui/res/ui/translations/settingListBox_fr.ts deleted file mode 100644 index 6d4237d..0000000 --- a/ovos_gui/res/ui/translations/settingListBox_fr.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - settingListBox - - - Type here to add an item to the list - Tapez ici pour ajouter un élément à la liste - - - - Add Item - Ajouter un item - - - diff --git a/ovos_gui/res/ui/translations/settingListBox_it.ts b/ovos_gui/res/ui/translations/settingListBox_it.ts deleted file mode 100644 index eb8786f..0000000 --- a/ovos_gui/res/ui/translations/settingListBox_it.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - settingListBox - - - Type here to add an item to the list - Digita qui per aggiungere un elemento all'elenco - - - - Add Item - Aggiungi articolo - - - diff --git a/ovos_gui/res/ui/translations/settingListBox_nl.ts b/ovos_gui/res/ui/translations/settingListBox_nl.ts deleted file mode 100644 index 3f05d19..0000000 --- a/ovos_gui/res/ui/translations/settingListBox_nl.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - settingListBox - - - Type here to add an item to the list - Typ hier om een ​​item aan de lijst toe te voegen - - - - Add Item - Voeg item toe - - - diff --git a/ovos_gui/res/ui/translations/settingListBox_pt.ts b/ovos_gui/res/ui/translations/settingListBox_pt.ts deleted file mode 100644 index d417ad9..0000000 --- a/ovos_gui/res/ui/translations/settingListBox_pt.ts +++ /dev/null @@ -1,17 +0,0 @@ - - - - - settingListBox - - - Type here to add an item to the list - Digite aqui para adicionar um item à lista - - - - Add Item - Adicionar Item - - - diff --git a/ovos_gui/res/ui/translations/settingspage_de.ts b/ovos_gui/res/ui/translations/settingspage_de.ts deleted file mode 100644 index e36abc5..0000000 --- a/ovos_gui/res/ui/translations/settingspage_de.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - settingspage - - - Homescreen Settings - Einstellungen Homescreen - - - - Customize - Anpassen - - - - Display - Anzeige - - - - Enable SSH - SSH aktivieren - - - - Developer Settings - Entwicklereinstellungen - - - - About - Über - - - - Device Settings - Geräteeinstellungen - - - - Home - Home - - - diff --git a/ovos_gui/res/ui/translations/settingspage_es.ts b/ovos_gui/res/ui/translations/settingspage_es.ts deleted file mode 100644 index 5380aec..0000000 --- a/ovos_gui/res/ui/translations/settingspage_es.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - settingspage - - - Homescreen Settings - Configuración de la pantalla de inicio - - - - Customize - personalizar - - - - Display - Monitor - - - - Enable SSH - Habilitar SSH - - - - Developer Settings - Configuración del desarrollador - - - - About - Sobre - - - - Device Settings - Configuración de dispositivo - - - - Home - Hogar - - - diff --git a/ovos_gui/res/ui/translations/settingspage_fr.ts b/ovos_gui/res/ui/translations/settingspage_fr.ts deleted file mode 100644 index edc17e2..0000000 --- a/ovos_gui/res/ui/translations/settingspage_fr.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - settingspage - - - Homescreen Settings - Paramètres de l'écran d'accueil - - - - Customize - Personnaliser - - - - Display - Affichage - - - - Enable SSH - Activer SSH - - - - Developer Settings - Paramètres du développeur - - - - About - À propos de - - - - Device Settings - Réglages de l'appareil - - - - Home - Maison - - - diff --git a/ovos_gui/res/ui/translations/settingspage_it.ts b/ovos_gui/res/ui/translations/settingspage_it.ts deleted file mode 100644 index e4d7f51..0000000 --- a/ovos_gui/res/ui/translations/settingspage_it.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - settingspage - - - Homescreen Settings - - - - - Customize - - - - - Display - - - - - Enable SSH - - - - - Developer Settings - - - - - About - - - - - Device Settings - - - - - Home - - - - diff --git a/ovos_gui/res/ui/translations/settingspage_nl.ts b/ovos_gui/res/ui/translations/settingspage_nl.ts deleted file mode 100644 index 1eafec9..0000000 --- a/ovos_gui/res/ui/translations/settingspage_nl.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - settingspage - - - Homescreen Settings - Instellingen startscherm - - - - Customize - Aanpassen - - - - Display - Weergave - - - - Enable SSH - SSH inschakelen - - - - Developer Settings - Ontwikkelaarsinstellingen - - - - About - Over - - - - Device Settings - Apparaat instellingen - - - - Home - Huis - - - diff --git a/ovos_gui/res/ui/translations/settingspage_pt.ts b/ovos_gui/res/ui/translations/settingspage_pt.ts deleted file mode 100644 index acdd788..0000000 --- a/ovos_gui/res/ui/translations/settingspage_pt.ts +++ /dev/null @@ -1,47 +0,0 @@ - - - - - settingspage - - - Homescreen Settings - Configurações da tela inicial - - - - Customize - Customizar - - - - Display - Exibição - - - - Enable SSH - Ativar SSH - - - - Developer Settings - Configurações do desenvolvedor - - - - About - Sobre - - - - Device Settings - Configurações do dispositivo - - - - Home - Casa - - - diff --git a/ovos_gui/res/ui/translations/ssh_settings_de.ts b/ovos_gui/res/ui/translations/ssh_settings_de.ts deleted file mode 100644 index f2bbc1a..0000000 --- a/ovos_gui/res/ui/translations/ssh_settings_de.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ssh_settings - - - SSH Settings - Einstellungen SSH - - - - By enabling SSH Mode, anyone can access, change or delete anything on this device by connecting to it via another device. - Es besteht die Möglichkeit mit aktivem SSH, das Unbefugte an Daten dieses Geräts gelangen - - - - Enable SSH - SSH aktivieren - - - - Disable SSH - SSH deaktivieren - - - - Device Settings - Geräteeinstellungen - - - diff --git a/ovos_gui/res/ui/translations/ssh_settings_es.ts b/ovos_gui/res/ui/translations/ssh_settings_es.ts deleted file mode 100644 index b8c549b..0000000 --- a/ovos_gui/res/ui/translations/ssh_settings_es.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ssh_settings - - - SSH Settings - - - - - By enabling SSH Mode, anyone can access, change or delete anything on this device by connecting to it via another device. - - - - - Enable SSH - - - - - Disable SSH - - - - - Device Settings - - - - diff --git a/ovos_gui/res/ui/translations/ssh_settings_fr.ts b/ovos_gui/res/ui/translations/ssh_settings_fr.ts deleted file mode 100644 index 6ee8fb3..0000000 --- a/ovos_gui/res/ui/translations/ssh_settings_fr.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ssh_settings - - - SSH Settings - - - - - By enabling SSH Mode, anyone can access, change or delete anything on this device by connecting to it via another device. - - - - - Enable SSH - - - - - Disable SSH - - - - - Device Settings - - - - diff --git a/ovos_gui/res/ui/translations/ssh_settings_it.ts b/ovos_gui/res/ui/translations/ssh_settings_it.ts deleted file mode 100644 index fe00e53..0000000 --- a/ovos_gui/res/ui/translations/ssh_settings_it.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ssh_settings - - - SSH Settings - - - - - By enabling SSH Mode, anyone can access, change or delete anything on this device by connecting to it via another device. - - - - - Enable SSH - - - - - Disable SSH - - - - - Device Settings - - - - diff --git a/ovos_gui/res/ui/translations/ssh_settings_nl.ts b/ovos_gui/res/ui/translations/ssh_settings_nl.ts deleted file mode 100644 index 2569dea..0000000 --- a/ovos_gui/res/ui/translations/ssh_settings_nl.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ssh_settings - - - SSH Settings - - - - - By enabling SSH Mode, anyone can access, change or delete anything on this device by connecting to it via another device. - - - - - Enable SSH - - - - - Disable SSH - - - - - Device Settings - - - - diff --git a/ovos_gui/res/ui/translations/ssh_settings_pt.ts b/ovos_gui/res/ui/translations/ssh_settings_pt.ts deleted file mode 100644 index edd544c..0000000 --- a/ovos_gui/res/ui/translations/ssh_settings_pt.ts +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ssh_settings - - - SSH Settings - - - - - By enabling SSH Mode, anyone can access, change or delete anything on this device by connecting to it via another device. - - - - - Enable SSH - - - - - Disable SSH - - - - - Device Settings - - - - diff --git a/ovos_gui/service.py b/ovos_gui/service.py index 06e83fb..8294f0c 100644 --- a/ovos_gui/service.py +++ b/ovos_gui/service.py @@ -55,9 +55,10 @@ def run(self): # if they may cause the Service to fail. self.status.set_alive() self._init_bus_client() - self.extension_manager = ExtensionsManager( - "EXTENSION_SERVICE", self.bus, self.gui) + self.extension_manager = ExtensionsManager("EXTENSION_SERVICE", + self.bus, self.gui) self.status.set_ready() + LOG.info(f"GUI Service Ready") def is_alive(self): """Respond to is_alive status request.""" diff --git a/requirements.txt b/requirements.txt index 7993955..304a9cb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ ovos-backend-client ovos-bus-client~=0.0, >=0.0.4a5 -ovos-utils~=0.0, >=0.0.31a5 -ovos-config~=0.0,>=0.0.8a3 -tornado~=6.0, >=6.0.3 \ No newline at end of file +ovos-utils~=0.0, >=0.0.34a3 +ovos-config~=0.0,>=0.0.10 +tornado~=6.0, >=6.0.3 +ovos-plugin-manager>=0.0.23 diff --git a/setup.py b/setup.py index 39d8696..d500645 100644 --- a/setup.py +++ b/setup.py @@ -69,7 +69,7 @@ def package_files(directory): url='https://github.com/OpenVoiceOS/ovos-gui', description='ovos-core gui service daemon', include_package_data=True, - packages=["ovos_gui", "ovos_gui.interfaces"], + packages=["ovos_gui"], package_data={"": package_files('ovos_gui/res')}, install_requires=required('requirements.txt'), entry_points={ diff --git a/test/unittests/test_bigscreen_extension.py b/test/unittests/test_bigscreen_extension.py deleted file mode 100644 index 8964372..0000000 --- a/test/unittests/test_bigscreen_extension.py +++ /dev/null @@ -1,43 +0,0 @@ -from unittest import TestCase, mock -from unittest.mock import patch -from ovos_gui.extensions import BigscreenExtension -from .mocks import MessageBusMock, base_config -from ovos_config import Configuration -from ovos_bus_client import Message - -PATCH_MODULE = "ovos_gui.extensions" - -# Add Unit Tests For BigscreenExtension - -class TestBigscreenExtension: - @patch.object(Configuration, 'get') - def test_bigscreen_close_current_window(self, mock_get): - config = base_config() - config.merge( - { - 'gui': { - 'extension': 'bigscreen' - } - }) - mock_get.return_value = config - bigscreen = BigscreenExtension(MessageBusMock(), MessageBusMock()) - bigscreen.close_current_window = mock.Mock() - message_data = Message("gui.namespace.removed", {'skill_id': 'foo'}) - bigscreen.close_current_window(message_data) - bigscreen.close_current_window.assert_any_call(message_data) - - @patch.object(Configuration, 'get') - def test_bigscreen_close_window_by_event(self, mock_get): - config = base_config() - config.merge( - { - 'gui': { - 'extension': 'bigscreen' - } - }) - mock_get.return_value = config - bigscreen = BigscreenExtension(MessageBusMock(), MessageBusMock()) - bigscreen.close_window_by_event = mock.Mock() - message_data = Message("mycroft.gui.screen.close", {}) - bigscreen.close_window_by_event(message_data) - bigscreen.close_window_by_event.assert_any_call(message_data) diff --git a/test/unittests/test_smartspeaker_extension.py b/test/unittests/test_smartspeaker_extension.py deleted file mode 100644 index a467a65..0000000 --- a/test/unittests/test_smartspeaker_extension.py +++ /dev/null @@ -1,48 +0,0 @@ - -from ovos_bus_client import Message - -from unittest import mock -from unittest.mock import patch - -from ovos_config import Configuration - -from ovos_gui.extensions import ExtensionsManager, SmartSpeakerExtension -from .mocks import MessageBusMock, base_config - -PATCH_MODULE = "ovos_gui.extensions" - - -# Add Unit Tests For SmartSpeakerExtension - -class TestSmartSpeakerExtension: - @patch.object(Configuration, 'get') - def test_smartspeaker_set_backend_type(self, mock_get): - config = base_config() - config.merge( - { - 'gui': { - 'extension': 'smartspeaker' - } - }) - mock_get.return_value = config - smartSpeaker = SmartSpeakerExtension(MessageBusMock(), MessageBusMock()) - smartSpeaker.set_backend_type = mock.Mock() - message_data = Message("ovos.pairing.set.backend", {'backend': 'unknown'}) - smartSpeaker.set_backend_type(message_data) - smartSpeaker.set_backend_type.assert_any_call(message_data) - - @patch.object(Configuration, 'get') - def test_smartspeaker_start_homescreen_process(self, mock_get): - config = base_config() - config.merge( - { - 'gui': { - 'extension': 'smartspeaker' - } - }) - mock_get.return_value = config - smartSpeaker = SmartSpeakerExtension(MessageBusMock(), MessageBusMock()) - smartSpeaker.start_homescreen_process = mock.Mock() - message_data = Message("ovos.pairing.process.completed", {}) - smartSpeaker.start_homescreen_process(message_data) - smartSpeaker.start_homescreen_process.assert_any_call(message_data) From 11e412a05c9ff8d887efd4b33207dfd5e1813148 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Fri, 9 Jun 2023 01:40:16 +0000 Subject: [PATCH 07/26] Increment Version --- CHANGELOG.md | 16 ++++++++++++++++ ovos_gui/version.py | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99f1e0d..e11c2ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a2...HEAD) + +**Implemented enhancements:** + +- :tada: - GUI plugin [\#11](https://github.com/OpenVoiceOS/ovos-gui/pull/11) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.3a2](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a2) (2023-05-01) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a1...V0.0.3a2) + +**Fixed bugs:** + +- interfaces/ folder not getting packaged [\#8](https://github.com/OpenVoiceOS/ovos-gui/issues/8) + ## [V0.0.3a1](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a1) (2023-04-30) [Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2...V0.0.3a1) diff --git a/ovos_gui/version.py b/ovos_gui/version.py index bdac248..6d383c1 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 2 +VERSION_ALPHA = 3 # END_VERSION_BLOCK From 926c3aa2c1059b61bed3acd535de275075e0ddc3 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:39:45 -0700 Subject: [PATCH 08/26] Minor logging and method annotation changes (#13) --- ovos_gui/bus.py | 38 ++++++++++++++++++++++++-------------- ovos_gui/namespace.py | 3 ++- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/ovos_gui/bus.py b/ovos_gui/bus.py index 637c847..921a072 100644 --- a/ovos_gui/bus.py +++ b/ovos_gui/bus.py @@ -29,6 +29,7 @@ from ovos_bus_client import Message, GUIMessage from ovos_config.config import Configuration +# from ovos_gui.namespace import NamespaceManager from ovos_utils import create_daemon from ovos_utils.log import LOG from tornado import ioloop @@ -36,11 +37,13 @@ from tornado.web import Application from tornado.websocket import WebSocketHandler -write_lock = Lock() +_write_lock = Lock() -def get_gui_websocket_config(): - """Retrieves the configuration values for establishing a GUI message bus""" +def get_gui_websocket_config() -> dict: + """ + Retrieves the configuration values for establishing a GUI message bus + """ config = Configuration() websocket_config = config["gui_websocket"] @@ -48,7 +51,10 @@ def get_gui_websocket_config(): def create_gui_service(enclosure) -> Application: - """Initiate a websocket for communicating with the GUI service.""" + """ + Initiate a websocket for communicating with the GUI service. + @param enclosure: NamespaceManager instance + """ LOG.info('Starting message bus for GUI...') websocket_config = get_gui_websocket_config() # Disable all tornado logging so mycroft loglevel isn't overridden @@ -56,6 +62,8 @@ def create_gui_service(enclosure) -> Application: routes = [(websocket_config['route'], GUIWebsocketHandler)] application = Application(routes) + # TODO: Is the NamespaceManager used by `application`, or can it be a + # GUIWebsocketHandler class variable application.enclosure = enclosure application.listen( websocket_config['base_port'], websocket_config['host'] @@ -66,8 +74,10 @@ def create_gui_service(enclosure) -> Application: return application -def send_message_to_gui(message): - """Sends the supplied message to all connected GUI clients.""" +def send_message_to_gui(message: dict): + """ + Sends the supplied message to all connected GUI clients. + """ for connection in GUIWebsocketHandler.clients: try: connection.send(message) @@ -120,10 +130,10 @@ def synchronize(self): }) namespace_pos += 1 - def on_message(self, message): - LOG.info(f"Received: {message}") + def on_message(self, message: str): + LOG.debug(f"Received: {message}") parsed_message = GUIMessage.deserialize(message) - msg = json.loads(message) + # msg = json.loads(message) if parsed_message.msg_type == "mycroft.events.triggered" and \ (parsed_message.data.get('event_name') == 'page_gained_focus' or parsed_message.data.get('event_name') == 'system.gui.user.interaction'): @@ -151,15 +161,15 @@ def on_message(self, message): msg_type = parsed_message.msg_type msg_data = parsed_message.data else: - # message not in SPEC + # message not in spec # https://github.com/MycroftAI/mycroft-gui/blob/master/transportProtocol.md - LOG.error(f"unknown GUI protocol message type, ignoring: {msg}") + LOG.error(f"unknown GUI protocol message type, ignoring: " + f"{parsed_message}") return message = Message(msg_type, msg_data, parsed_message.context) - LOG.info('Forwarding to core bus...') self.application.enclosure.core_bus.emit(message) - LOG.info('Done!') + LOG.debug('Forwarded to core bus') def write_message(self, *arg, **kwarg): """Wraps WebSocketHandler.write_message() with a lock. """ @@ -168,7 +178,7 @@ def write_message(self, *arg, **kwarg): except RuntimeError: asyncio.set_event_loop(asyncio.new_event_loop()) - with write_lock: + with _write_lock: super().write_message(*arg, **kwarg) def send(self, data): diff --git a/ovos_gui/namespace.py b/ovos_gui/namespace.py index 094dfb7..cd2830f 100644 --- a/ovos_gui/namespace.py +++ b/ovos_gui/namespace.py @@ -518,7 +518,6 @@ def handle_show_page(self, message: Message): Args: message: the message containing the page show request """ - LOG.info("Handling page show request") message_is_valid = _validate_page_message(message) if message_is_valid: namespace_name = message.data["__from"] @@ -526,6 +525,8 @@ def handle_show_page(self, message: Message): persistence = message.data["__idle"] show_index = message.data.get("index", None) + LOG.info(f"Handling page show request. pages={pages_to_show}") + pages_to_load = list() for page in pages_to_show: name = page.split('/')[-1] From 2ab68751cad96017fcf3051ce4eb0afcc8cc73d5 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Fri, 9 Jun 2023 18:40:37 +0000 Subject: [PATCH 09/26] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_gui/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e11c2ef..85e5569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a2...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a3...HEAD) + +**Merged pull requests:** + +- Minor logging and method annotation changes [\#13](https://github.com/OpenVoiceOS/ovos-gui/pull/13) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.3a3](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a3) (2023-06-09) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a2...V0.0.3a3) **Implemented enhancements:** diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 6d383c1..f458d3e 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 3 +VERSION_ALPHA = 4 # END_VERSION_BLOCK From ec2f93f9bcb50cbeff8026e11f30335bdae1445c Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Mon, 12 Jun 2023 17:04:30 -0700 Subject: [PATCH 10/26] Remove unused ovos-backend-client dependency (#14) --- .github/workflows/unit_tests.yml | 2 +- requirements.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index bce5a50..3da0a31 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -50,7 +50,7 @@ jobs: python -m pip install build wheel - name: Install repo run: | - pip install . + pip install -e . - name: Install test dependencies run: | pip install -r test/requirements.txt diff --git a/requirements.txt b/requirements.txt index 304a9cb..47b6ae9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -ovos-backend-client ovos-bus-client~=0.0, >=0.0.4a5 ovos-utils~=0.0, >=0.0.34a3 ovos-config~=0.0,>=0.0.10 From 46c171fe87feac6122450d70841f33c828e32659 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Tue, 13 Jun 2023 00:05:42 +0000 Subject: [PATCH 11/26] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_gui/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85e5569..ff68f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a3...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a4...HEAD) + +**Merged pull requests:** + +- Remove unused ovos-backend-client dependency [\#14](https://github.com/OpenVoiceOS/ovos-gui/pull/14) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.3a4](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a4) (2023-06-09) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a3...V0.0.3a4) **Merged pull requests:** diff --git a/ovos_gui/version.py b/ovos_gui/version.py index f458d3e..0d01bb4 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 4 +VERSION_ALPHA = 5 # END_VERSION_BLOCK From 100fb1f56cb6b7c82c53503c6433fb09758ba523 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:44:52 -0700 Subject: [PATCH 12/26] Unit Tests and Documentation (#15) --- .github/workflows/build_tests.yml | 4 +- .github/workflows/unit_tests.yml | 2 +- ovos_gui/bus.py | 57 ++- ovos_gui/extensions.py | 19 +- ovos_gui/homescreen.py | 228 ++++++++---- ovos_gui/namespace.py | 400 +++++++++++----------- ovos_gui/page.py | 24 +- ovos_gui/service.py | 23 +- ovos_gui/tui.py | 9 +- test/requirements.txt | 10 +- test/unittests/test_bus.py | 45 +++ test/unittests/test_extensions.py | 59 ++++ test/unittests/test_extensions_manager.py | 31 -- test/unittests/test_homescreen.py | 80 +++++ test/unittests/test_namespace.py | 224 +++++++++++- test/unittests/test_namespace_manager.py | 115 ------- test/unittests/test_page.py | 16 + test/unittests/test_service.py | 6 + test/unittests/test_tui.py | 16 + 19 files changed, 888 insertions(+), 480 deletions(-) create mode 100644 test/unittests/test_bus.py create mode 100644 test/unittests/test_extensions.py delete mode 100644 test/unittests/test_extensions_manager.py create mode 100644 test/unittests/test_homescreen.py delete mode 100644 test/unittests/test_namespace_manager.py create mode 100644 test/unittests/test_page.py create mode 100644 test/unittests/test_service.py create mode 100644 test/unittests/test_tui.py diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml index 1f51866..f204bb7 100644 --- a/.github/workflows/build_tests.yml +++ b/.github/workflows/build_tests.yml @@ -22,8 +22,8 @@ jobs: sudo apt-get update sudo apt install python3-dev swig libssl-dev libfann-dev portaudio19-dev libpulse-dev - name: Build Source Packages - run: | - python setup.py sdist + run: | + python setup.py sdist - name: Build Distribution Packages run: | python setup.py bdist_wheel diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 3da0a31..73c5fb0 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -34,7 +34,7 @@ jobs: strategy: max-parallel: 2 matrix: - python-version: [ 3.7, 3.8, 3.9] + python-version: [ 3.7, 3.8, 3.9, '3.10' ] runs-on: ubuntu-latest timeout-minutes: 15 steps: diff --git a/ovos_gui/bus.py b/ovos_gui/bus.py index 921a072..5a5f43d 100644 --- a/ovos_gui/bus.py +++ b/ovos_gui/bus.py @@ -77,6 +77,7 @@ def create_gui_service(enclosure) -> Application: def send_message_to_gui(message: dict): """ Sends the supplied message to all connected GUI clients. + @param message: dict data to send to GUI clients """ for connection in GUIWebsocketHandler.clients: try: @@ -85,8 +86,10 @@ def send_message_to_gui(message: dict): LOG.exception(repr(e)) -def determine_if_gui_connected(): - """Returns True if any clients are connected to the GUI bus.""" +def determine_if_gui_connected() -> bool: + """ + Returns True if any clients are connected to the GUI bus. + """ return len(GUIWebsocketHandler.clients) > 0 @@ -95,16 +98,24 @@ class GUIWebsocketHandler(WebSocketHandler): clients = [] def open(self): + """ + Add a new connection to `clients` and synchronize + """ GUIWebsocketHandler.clients.append(self) LOG.info('New Connection opened!') self.synchronize() def on_close(self): + """ + Remove a closed connection from `clients` + """ LOG.info('Closing {}'.format(id(self))) GUIWebsocketHandler.clients.remove(self) def synchronize(self): - """ Upload namespaces, pages and data to the last connected. """ + """ + Upload namespaces, pages and data to the last connected client. + """ namespace_pos = 0 enclosure = self.application.enclosure @@ -131,12 +142,20 @@ def synchronize(self): namespace_pos += 1 def on_message(self, message: str): - LOG.debug(f"Received: {message}") + """ + Handle a message on the GUI websocket. Deserialize the message, map + message types to valid equivalents for the core messagebus and emit + on the core messagebus. + @param message: Serialized Message + """ parsed_message = GUIMessage.deserialize(message) + LOG.debug(f"Received: {parsed_message.msg_type}|{parsed_message.data}") + # msg = json.loads(message) if parsed_message.msg_type == "mycroft.events.triggered" and \ (parsed_message.data.get('event_name') == 'page_gained_focus' or - parsed_message.data.get('event_name') == 'system.gui.user.interaction'): + parsed_message.data.get('event_name') == + 'system.gui.user.interaction'): # System event, a page was changed event_name = parsed_message.data.get('event_name') if event_name == 'page_gained_focus': @@ -144,12 +163,14 @@ def on_message(self, message: str): else: msg_type = 'gui.page_interaction' - msg_data = {'namespace': parsed_message.data['namespace'], - 'page_number': parsed_message.data['parameters'].get('number'), - 'skill_id': parsed_message.data['parameters'].get('skillId')} + msg_data = \ + {'namespace': parsed_message.data['namespace'], + 'page_number': parsed_message.data['parameters'].get('number'), + 'skill_id': parsed_message.data['parameters'].get('skillId')} elif parsed_message.msg_type == "mycroft.events.triggered": # A normal event was triggered - msg_type = f"{parsed_message.data['namespace']}.{parsed_message.data['event_name']}" + msg_type = f"{parsed_message.data['namespace']}." \ + f"{parsed_message.data['event_name']}" msg_data = parsed_message.data['parameters'] elif parsed_message.msg_type == 'mycroft.session.set': @@ -172,7 +193,9 @@ def on_message(self, message: str): LOG.debug('Forwarded to core bus') def write_message(self, *arg, **kwarg): - """Wraps WebSocketHandler.write_message() with a lock. """ + """ + Wraps WebSocketHandler.write_message() with a lock. + """ try: asyncio.get_event_loop() except RuntimeError: @@ -181,16 +204,18 @@ def write_message(self, *arg, **kwarg): with _write_lock: super().write_message(*arg, **kwarg) - def send(self, data): - """Send the given data across the socket as JSON - - Args: - data (dict): Data to transmit + def send(self, data: dict): + """ + Send the given data across the socket as JSON + @param data: Data to send to the GUI """ s = json.dumps(data) # LOG.info('Sending {}'.format(s)) self.write_message(s) def check_origin(self, origin): - """Disable origin check to make js connections work.""" + """ + Disable origin check to make js connections work. + """ + # TODO: Should this be implemented or deprecated return True diff --git a/ovos_gui/extensions.py b/ovos_gui/extensions.py index b23e390..c8ebf1d 100644 --- a/ovos_gui/extensions.py +++ b/ovos_gui/extensions.py @@ -3,18 +3,17 @@ from ovos_gui.namespace import NamespaceManager from ovos_utils.log import LOG from ovos_plugin_manager.gui import OVOSGuiFactory -from ovos_gui.homescreen import HomescreenManager class ExtensionsManager: def __init__(self, name: str, bus: MessageBusClient, gui: NamespaceManager): - """ Constructor for the Extension Manager. The Extension Manager is responsible for - managing the extensions that define additional GUI behaviours for specific platforms. - - Args: - name: Name of the extension manager - bus: MessageBus instance - gui: GUI instance + """ + Constructor for the Extension Manager. The Extension Manager is + responsible for managing the extensions that define additional GUI + behaviours for specific platforms. + @param name: Name of the extension manager + @param bus: MessageBus instance + @param gui: GUI instance """ self.name = name @@ -28,6 +27,10 @@ def __init__(self, name: str, bus: MessageBusClient, gui: NamespaceManager): self.activate_extension(self.active_extension.lower()) def activate_extension(self, extension_id: str): + """ + Activate the requested extension + @param extension_id: GUI Plugin entrypoint to activate + """ mappings = { "smartspeaker": "ovos-gui-plugin-shell-companion", "bigscreen": "ovos-gui-plugin-bigscreen", diff --git a/ovos_gui/homescreen.py b/ovos_gui/homescreen.py index e5ba6b3..ba603fb 100644 --- a/ovos_gui/homescreen.py +++ b/ovos_gui/homescreen.py @@ -1,25 +1,31 @@ +from typing import List, Optional + from ovos_bus_client import Message, MessageBusClient -from ovos_config.config import Configuration, LocalConf -from ovos_config.locations import USER_CONFIG -from ovos_utils.log import LOG +from ovos_bus_client.message import dig_for_message +from ovos_config.config import Configuration, update_mycroft_config + +from ovos_utils.log import LOG, deprecated, log_deprecation from ovos_gui.namespace import NamespaceManager from threading import Thread class HomescreenManager(Thread): - def __init__(self, bus: MessageBusClient, gui: NamespaceManager): super().__init__() self.bus = bus self.gui = gui - self.homescreens = [] + self.homescreens: List[dict] = [] self.mycroft_ready = False + # TODO: If service starts after `mycroft_ready`, + # homescreen is never shown self.bus.on('homescreen.manager.add', self.add_homescreen) self.bus.on('homescreen.manager.remove', self.remove_homescreen) self.bus.on('homescreen.manager.list', self.get_homescreens) - self.bus.on("homescreen.manager.get_active", self.get_active_homescreen) - self.bus.on("homescreen.manager.set_active", self.set_active_homescreen) + self.bus.on("homescreen.manager.get_active", + self.handle_get_active_homescreen) + self.bus.on("homescreen.manager.set_active", + self.handle_set_active_homescreen) self.bus.on("homescreen.manager.disable_active", self.disable_active_homescreen) self.bus.on("mycroft.mark2.register_idle", @@ -28,99 +34,170 @@ def __init__(self, bus: MessageBusClient, gui: NamespaceManager): self.bus.on("mycroft.ready", self.set_mycroft_ready) def run(self): - """Start the Manager after it has been constructed.""" + """ + Start the Manager after it has been constructed. + """ self.reload_homescreens_list() - def add_homescreen(self, homescreen): - # if homescreen[id] not in self.homescreens then add it - homescreen_id = homescreen.data["id"] - homescreen_class = homescreen.data["class"] - LOG.info(f"Homescreen Manager: Adding Homescreen {homescreen_id}") - # check if the list is empty - if len(self.homescreens) == 0: - self.homescreens.append(homescreen.data) + def add_homescreen(self, message: Message): + """ + Handle `homescreen.manager.add` and add the requested homescreen if it + has not yet been added. + @param message: Message containing homescreen id/class to add + """ + homescreen_id = message.data["id"] + homescreen_class = message.data["class"] + + if any((homescreen['id'] == homescreen_id + for homescreen in self.homescreens)): + LOG.info(f"Requested homescreen_id already exists: {homescreen_id}") else: - # check if id is in list of homescreen dicts in self.homescreens - for h in self.homescreens: - if homescreen_id != h["id"]: - self.homescreens.append(homescreen.data) + LOG.info(f"Homescreen Manager: Adding Homescreen {homescreen_id}") + self.homescreens.append(message.data) self.show_homescreen_on_add(homescreen_id, homescreen_class) - def remove_homescreen(self, homescreen): - homescreen_id = homescreen.data["id"] + def remove_homescreen(self, message: Message): + """ + Handle `homescreen.manager.remove` and remove the requested homescreen + if it exists + @param message: Message containing homescreen id to remove + """ + homescreen_id = message.data["id"] LOG.info(f"Homescreen Manager: Removing Homescreen {homescreen_id}") for h in self.homescreens: if homescreen_id == h["id"]: - self.homescreens.pop(h) - - def get_homescreens(self): - return self.homescreens - - def get_active_homescreen(self): - config = Configuration() - enclosure_config = config.get("gui") or {} + self.homescreens.remove(h) + + def get_homescreens(self, message: Message): + """ + Handle `homescreen.manager.list` and emit a response with loaded + homescreens. + :param message: Message requesting homescreens + """ + self.bus.emit(message.response({"homescreens": self.homescreens})) + + def handle_get_active_homescreen(self, message: Message): + """ + Handle `homescreen.manager.get_active` and emit a response with the + active homescreen + @param message: Message requesting active homescreen + """ + self.bus.emit(message.response( + {"homescreen": self.get_active_homescreen()})) + + def handle_set_active_homescreen(self, message: Message): + """ + Handle `homescreen.manager.set_active` requests to change the configured + homescreen and update configuration. + @param message: Message containing requested homescreen ID + """ + new_homescreen = message.data.get("id") + LOG.debug(f"Requested updating homescreen to: {new_homescreen}") + self.set_active_homescreen(new_homescreen) + + def get_active_homescreen(self) -> Optional[dict]: + """ + Get the active homescreen according to configuration if it is loaded + @return: Loaded homescreen with an ID matching configuration + """ + enclosure_config = Configuration().get("gui") or {} active_homescreen = enclosure_config.get("idle_display_skill") LOG.debug(f"Homescreen Manager: Active Homescreen {active_homescreen}") for h in self.homescreens: if h["id"] == active_homescreen: return active_homescreen - def set_active_homescreen(self, homescreen): - homescreen_id = homescreen.data["id"] - conf = LocalConf(USER_CONFIG) - conf["gui"] = { - "idle_display_skill": homescreen_id, - } - conf.store() - self.bus.emit(Message("configuration.patch", {"config": conf})) + def set_active_homescreen(self, homescreen_id: str): + """ + Update the configured `idle_display_skill` + @param homescreen_id: new `idle_display_skill` + """ + # TODO: Validate requested homescreen_id + if Configuration().get("gui", + {}).get("idle_display_skill") != homescreen_id: + LOG.info(f"Updating configured idle_display_skill to " + f"{homescreen_id}") + new_config = {"gui": {"idle_display_skill": homescreen_id}} + update_mycroft_config(new_config, bus=self.bus) def reload_homescreens_list(self): + """ + Emit a request for homescreens to register via the Messagebus + """ LOG.info("Homescreen Manager: Reloading Homescreen List") self.collect_old_style_homescreens() self.bus.emit(Message("homescreen.manager.reload.list")) - def show_homescreen_on_add(self, homescreen_id, homescreen_class): - if self.mycroft_ready == True: - active_homescreen = self.get_active_homescreen() - LOG.debug(f"Requesting activation of {active_homescreen}") - if active_homescreen == homescreen_id: - if homescreen_class == "IdleDisplaySkill": - LOG.debug( - f"Homescreen Manager: Displaying Homescreen {active_homescreen}") - self.bus.emit(Message("homescreen.manager.activate.display", { - "homescreen_id": active_homescreen})) - elif homescreen_class == "MycroftSkill": - LOG.debug( - f"Homescreen Manager: Displaying Homescreen {active_homescreen}") - self.bus.emit(Message("{}.idle".format(homescreen_id))) - - def disable_active_homescreen(self, message): - conf = LocalConf(USER_CONFIG) - conf["gui"] = { - "idle_display_skill": None, - } - conf.store() - self.bus.emit(Message("configuration.patch", {"config": conf})) - - def show_homescreen(self, message=None): + def show_homescreen_on_add(self, homescreen_id: str, homescreen_class: str): + """ + Check if a homescreen should be displayed immediately upon addition + @param homescreen_id: ID of added homescreen + @param homescreen_class: "class" (IdleDisplaySkill, MycroftSkill) + of homescreen + """ + if not self.mycroft_ready: + LOG.debug("Not ready yet, don't display") + return + LOG.debug(f"Checking {homescreen_id}") + if self.get_active_homescreen() != homescreen_id: + # Added homescreen isn't the configured one, do nothing + return + + if homescreen_class == "IdleDisplaySkill": + LOG.debug(f"Displaying Homescreen {homescreen_id}") + self.bus.emit(Message("homescreen.manager.activate.display", + {"homescreen_id": homescreen_id})) + elif homescreen_class == "MycroftSkill": + log_deprecation(f"Homescreen skills should register listeners for " + f"`homescreen.manager.activate.display`. " + f"`{homescreen_id}.idle` messages will be removed.", + "0.1.0") + LOG.debug(f"Displaying Homescreen {homescreen_id}") + self.bus.emit(Message(f"{homescreen_id}.idle")) + + def disable_active_homescreen(self, message: Message): + """ + Handle `homescreen.manager.disable_active` requests by configuring the + `idle_display_skill` as None. + @param message: Message requesting homescreen disable + """ + # TODO: Is this valid behavior? + if Configuration().get("gui", {}).get("idle_display_skill"): + LOG.info(f"Disabling idle_display_skill!") + new_config = {"gui": {"idle_display_skill": None}} + update_mycroft_config(new_config, bus=self.bus) + + def show_homescreen(self, message: Optional[Message] = None): + """ + Handle a request to show the homescreen. + @param message: Optional `homescreen.manager.show_active` Message + """ active_homescreen = self.get_active_homescreen() LOG.debug(f"Requesting activation of {active_homescreen}") for h in self.homescreens: - if h["id"] == active_homescreen: + if h.get("id") == active_homescreen: + LOG.debug(f"matched homescreen skill: {h}") + message = message or dig_for_message() or Message("") if h["class"] == "IdleDisplaySkill": - LOG.debug( - f"Homescreen Manager: Displaying Homescreen " - f"{active_homescreen}") - self.bus.emit(Message("homescreen.manager.activate.display", { - "homescreen_id": active_homescreen})) + LOG.debug(f"Displaying Homescreen {active_homescreen}") + self.bus.emit(message.forward( + "homescreen.manager.activate.display", + {"homescreen_id": active_homescreen})) elif h["class"] == "MycroftSkill": - LOG.debug( - f"Homescreen Manager: Displaying Homescreen " - f"{active_homescreen}") - self.bus.emit(Message("{}.idle".format(active_homescreen))) - - def set_mycroft_ready(self, message): + LOG.debug(f"Displaying Homescreen {active_homescreen}") + self.bus.emit(message.forward(f"{active_homescreen}.idle")) + else: + LOG.error(f"Requested homescreen has an invalid class: {h}") + return + LOG.warning(f"Requested {active_homescreen} not found in: " + f"{self.homescreens}") + + def set_mycroft_ready(self, message: Message): + """ + Handle `mycroft.ready` and show the homescreen + @param message: `mycroft.ready` Message + """ self.mycroft_ready = True self.show_homescreen() @@ -128,8 +205,11 @@ def set_mycroft_ready(self, message): def collect_old_style_homescreens(self): """Trigger collection of older resting screens.""" + # TODO: Deprecate in 0.1.0 self.bus.emit(Message("mycroft.mark2.collect_idle")) + @deprecated("`mycroft.mark2.collect_idle` responses are deprecated", + "0.1.0") def register_old_style_homescreen(self, message): if "name" in message.data and "id" in message.data: super_class_name = "MycroftSkill" diff --git a/ovos_gui/namespace.py b/ovos_gui/namespace.py index cd2830f..0ec8fbd 100644 --- a/ovos_gui/namespace.py +++ b/ovos_gui/namespace.py @@ -42,7 +42,7 @@ from threading import Lock, Timer from time import sleep -from typing import List, Union +from typing import List, Union, Optional from ovos_config.config import Configuration from ovos_utils.log import LOG @@ -61,6 +61,53 @@ RESERVED_KEYS = ['__from', '__idle'] +def _validate_page_message(message: Message) -> bool: + """ + Validates the contents of the message data for page add/remove messages. + + @param message: Message with request to add/remove one or more pages + from a namespace. + @returns: True if request is valid, else False + """ + valid = ( + "page" in message.data + and "__from" in message.data + and isinstance(message.data["page"], list) + ) + if not valid: + if message.msg_type == "gui.page.show": + action = "shown" + else: + action = "removed" + LOG.error(f"Page will not be {action} due to malformed data in the" + f"{message.msg_type} message") + return valid + + +def _get_idle_display_config() -> str: + """ + Retrieves the current value of the idle display skill configuration. + @returns: Configured idle_display_skill (skill_id) + """ + config = Configuration() + enclosure_config = config.get("gui") or {} + idle_display_skill = enclosure_config.get("idle_display_skill") + LOG.info(f"Got idle_display_skill from config: {idle_display_skill}") + return idle_display_skill + + +def _get_active_gui_extension() -> str: + """ + Retrieves the current value of the gui extension configuration. + @returns: Configured gui extension + """ + config = Configuration() + enclosure_config = config.get("gui") or {} + gui_extension = enclosure_config.get("extension", "generic") + LOG.info(f"Got extension from config: {gui_extension}") + return gui_extension.lower() + + class Namespace: """A grouping mechanism for related GUI pages and data. @@ -90,7 +137,9 @@ def __init__(self, name: str): self.session_set = False def add(self): - """Adds a namespace to the list of active namespaces.""" + """ + Adds this namespace to the list of active namespaces. + """ LOG.info(f"Adding \"{self.name}\" to active GUI namespaces") message = dict( type="mycroft.session.list.insert", @@ -101,7 +150,10 @@ def add(self): send_message_to_gui(message) def activate(self, position: int): - """Activates an namespace already in the list of active namespaces.""" + """ + Activate this namespace if its already in the list of active namespaces. + @param position: position to move this namespace FROM + """ LOG.info(f"Activating GUI namespace \"{self.name}\"") message = { "type": "mycroft.session.list.move", @@ -113,7 +165,11 @@ def activate(self, position: int): send_message_to_gui(message) def remove(self, position: int): - """Removes a namespace from the list of active namespaces.""" + """ + Removes this namespace from the list of active namespaces. Also clears + any session data. + @param position: position to remove this namespace FROM + """ LOG.info(f"Removing {self.name} from active GUI namespaces") # unload the data first before removing the namespace @@ -133,7 +189,8 @@ def remove(self, position: int): self.data = dict() def load_data(self, name: str, value: str): - """Adds or changes the value of a namespace data attribute. + """ + Adds or changes the value of a namespace data attribute. Args: name: The name of the attribute @@ -149,7 +206,10 @@ def load_data(self, name: str, value: str): send_message_to_gui(message) def unload_data(self, name: str): - """ Delete data from the namespace """ + """ + Delete data from the namespace + @param name: name of property to delete + """ message = dict( type="mycroft.session.delete", property=name, @@ -158,15 +218,17 @@ def unload_data(self, name: str): # LOG.info(f"Deleting data {message} from GUI namespace {self.name}") send_message_to_gui(message) - def get_position_of_last_item_in_data(self): - """ Get the position of the last item """ + def get_position_of_last_item_in_data(self) -> int: + """ + Get the position of the last item + """ return len(self.data) - 1 def set_persistence(self, skill_type: str): - """Sets the duration of the namespace's time in the active list. + """ + Sets the duration of the namespace's time in the active list. - Args: - skill_type: if skill type is idleDisplaySkill, the namespace will + @param skill_type: if skill type is idleDisplaySkill, the namespace will always persist. Otherwise, the namespace will persist based on the active page's persistence. """ @@ -205,9 +267,8 @@ def load_pages(self, pages: List[GuiPage], show_index: int = 0): the pages can be loaded one at a time. The latter is represented by a single list item, the former by multiple list items - Args: - pages: one or more pages to be displayed - show_index: index of page to display (default 0) + @param pages: list of pages to be displayed + @param show_index: index of page to display (default 0) """ if show_index is None: LOG.warning(f"Expected int show_index but got `None`. Default to 0") @@ -228,15 +289,14 @@ def _add_pages(self, new_pages: List[GuiPage]): """ Adds one or more pages to the active page list. - Args: - new_pages: pages to add to the active page list + @param new_pages: pages to add to the active page list """ LOG.info(f"Adding pages to GUI namespace {self.name}: {new_pages}") LOG.info(f"Current pages: {self.pages}") # print the attributes of the new pages for page in new_pages: - LOG.info( - f"Page: {page.url}, {page.name}, {page.persistent}, {page.duration}") + LOG.info(f"Page: {page.url}, {page.name}, {page.persistent}, " + f"{page.duration}") # Find position of new page in self.pages position = self.pages.index(new_pages[0]) @@ -253,11 +313,11 @@ def _activate_page(self, page: GuiPage): """ Returns focus to a page already in the active page list. - Args: - page: the page that will gain focus + @param page: the page that will gain focus """ LOG.info(f"Activating page {page.name} in GUI namespace {self.name}") LOG.info(f"Current pages from _activate_page: {self.pages}") + # TODO: Simplify two loops into one (with unit test) # get the index of the page in the self.pages list page_index = 0 for i, p in enumerate(self.pages): @@ -267,8 +327,8 @@ def _activate_page(self, page: GuiPage): self.page_number = page_index - # set the page active attribute to True and update the self.pages list, mark all other pages as inactive - + # set the page active attribute to True and update the self.pages list, + # mark all other pages as inactive page.active = True for p in self.pages: @@ -288,12 +348,13 @@ def _activate_page(self, page: GuiPage): send_message_to_gui(message) def remove_pages(self, positions: List[int]): - """Deletes one or more pages from the active page list. + """ + Deletes one or more pages by index from the active page list. - Args: - positions: page position to remove + @param positions: list of int page positions to remove """ LOG.info(f"Removing pages from GUI namespace {self.name}: {positions}") + positions.sort(reverse=True) for position in positions: page = self.pages.pop(position) LOG.info(f"Deleting {page} from GUI namespace {self.name}") @@ -305,21 +366,23 @@ def remove_pages(self, positions: List[int]): ) send_message_to_gui(message) - def page_gained_focus(self, page_number): - """Updates the active page in self.pages - - Args: - page_number: the page number of the page that will gain focus + def page_gained_focus(self, page_number: int): + """ + Updates the active page in `self.pages`. + @param page_number: the index of the page that will gain focus """ LOG.info( f"Page {page_number} gained focus in GUI namespace {self.name}") self._activate_page(self.pages[page_number]) def page_update_interaction(self, page_number: int): - """Update the interaction of the page_number""" + """ + Update the interaction of the page_number. + @param page_number: the index of the page to update + """ - LOG.info( - f"Page {page_number} update interaction in GUI namespace {self.name}") + LOG.info(f"Page {page_number} update interaction in GUI namespace " + f"{self.name}") page = self.pages[page_number] if not page.persistent and page.duration > 0: @@ -329,84 +392,51 @@ def page_update_interaction(self, page_number: int): self.pages[page_number] = page self.set_persistence(skill_type="genericSkill") - def get_page_at_position(self, position: int): - """Returns the position of the page in the active page list.""" - return self.pages.index(position) + def get_page_at_position(self, position: int) -> GuiPage: + """ + Returns the page at the requested position in the active page list. + Requesting a position out of range will raise an IndexError. + @param position: index of the page to get + """ + return self.pages[position] - def get_active_page(self): + def get_active_page(self) -> Optional[GuiPage]: """ Returns the currently active page from `self.pages` where the page - attribute active is true + attribute `active` is true. + @returns: Active GuiPage if any, else None """ for page in self.pages: if page.active: return page return None - def get_active_page_index(self): - # get the active page index in the self.pages list + def get_active_page_index(self) -> Optional[int]: + """ + Get the active page index in `self.pages`. + @return: index of the active page if any, else None + """ active_page = self.get_active_page() if active_page is not None: return self.pages.index(active_page) - def index_in_pages_list(self, index): - return (index < len(self.pages)) + def index_in_pages_list(self, index: int) -> bool: + """ + Check if the active index is in the pages list + @param index: index to check + @return: True if index is valid in `self.pages + """ + return 0 < index < len(self.pages) def global_back(self): - """Returns to the previous page in the active page list.""" + """ + Returns to the previous page in the active page list. + """ if self.page_number > 0: self.remove_pages([self.page_number]) self.page_gained_focus(self.page_number - 1) -def _validate_page_message(message: Message): - """ - Validates the contents of the message data for page add/remove messages. - - Args: - message: A core message bus message to add/remove one or more pages - from a namespace. - """ - valid = ( - "page" in message.data - and "__from" in message.data - and isinstance(message.data["page"], list) - ) - if not valid: - if message.msg_type == "gui.page.show": - action = "shown" - else: - action = "removed" - LOG.error( - f"Page will not be {action} due to malformed data in the" - f"{message.msg_type} message" - ) - - return valid - - -def _get_idle_display_config(): - """ - Retrieves the current value of the idle display skill configuration. - """ - config = Configuration() - enclosure_config = config.get("gui") or {} - idle_display_skill = enclosure_config.get("idle_display_skill") - LOG.info(f"Got idle_display_skill from config: {idle_display_skill}") - return idle_display_skill - - -def _get_active_gui_extension(): - """ - Retrieves the current value of the gui extension configuration. - """ - config = Configuration() - enclosure_config = config.get("gui") or {} - gui_extension = enclosure_config.get("extension", "generic") - LOG.info(f"Got extension from config: {gui_extension}") - return gui_extension.lower() - - class NamespaceManager: """ Manages the active namespace stack and the content of namespaces. @@ -432,7 +462,9 @@ def __init__(self, core_bus: MessageBusClient): self._define_message_handlers() def _define_message_handlers(self): - """Assigns methods as handlers for specified message types.""" + """ + Defines event handlers for core messagebus. + """ self.core_bus.on("gui.clear.namespace", self.handle_clear_namespace) self.core_bus.on("gui.event.send", self.handle_send_event) self.core_bus.on("gui.page.delete", self.handle_delete_page) @@ -445,10 +477,9 @@ def _define_message_handlers(self): self.handle_page_gained_focus) def handle_clear_namespace(self, message: Message): - """Handles a request to remove a namespace. - - Args: - message: the message requesting namespace removal + """ + Handles a request to remove a namespace. + @param message: the message requesting namespace removal """ try: namespace_name = message.data['__from'] @@ -462,10 +493,9 @@ def handle_clear_namespace(self, message: Message): @staticmethod def handle_send_event(message: Message): - """Handles a request to send a message to the GUI message bus. - - Args: - message: the message requesting a message to be sent to the GUI + """ + Handles a request to send a message to the GUI message bus. + @param message: the message requesting a message to be sent to the GUI message bus. """ try: @@ -480,10 +510,9 @@ def handle_send_event(message: Message): LOG.exception('Could not send event trigger') def handle_delete_page(self, message: Message): - """Handles request to remove one or more pages from a namespace. - - Args: - message: the message requesting page removal + """ + Handles request to remove one or more pages from a namespace. + @param message: the message requesting page removal """ message_is_valid = _validate_page_message(message) if message_is_valid: @@ -493,13 +522,11 @@ def handle_delete_page(self, message: Message): self._remove_pages(namespace_name, pages_to_remove) def _remove_pages(self, namespace_name: str, pages_to_remove: List[str]): - """Removes one or more pages from a namespace. - - Pages are removed from the bottom of the stack. - - Args: - namespace_name: the affected namespace - pages_to_remove: names of pages to delete + """ + Removes one or more pages from a namespace. Pages are removed from the + bottom of the stack. + @param namespace_name: the affected namespace + @param pages_to_remove: names of pages to delete """ namespace = self.loaded_namespaces.get(namespace_name) if namespace is not None and namespace in self.active_namespaces: @@ -513,10 +540,9 @@ def _remove_pages(self, namespace_name: str, pages_to_remove: List[str]): namespace.remove_pages(page_positions) def handle_show_page(self, message: Message): - """Handles a request to show one or more pages on the screen. - - Args: - message: the message containing the page show request + """ + Handles a request to show one or more pages on the screen. + @param message: the message containing the page show request """ message_is_valid = _validate_page_message(message) if message_is_valid: @@ -552,10 +578,10 @@ def handle_show_page(self, message: Message): self._update_namespace_persistence(persistence) def _activate_namespace(self, namespace_name: str): - """Instructs the GUI to load a namespace and its associated data. + """ + Instructs the GUI to load a namespace and its associated data. - Args: - namespace_name: the name of the namespace to load + @param namespace_name: the name of the namespace to load """ namespace = self._ensure_namespace_exists(namespace_name) LOG.info(f"Activating namespace: {namespace_name}") @@ -575,13 +601,10 @@ def _activate_namespace(self, namespace_name: str): self._emit_namespace_displayed_event() def _ensure_namespace_exists(self, namespace_name: str) -> Namespace: - """Retrieves the requested namespace, creating one if it doesn't exist. - - Args: - namespace_name: the name of the namespace being retrieved - - Returns: - the requested namespace + """ + Retrieves the requested namespace, creating one if it doesn't exist. + @param namespace_name: the name of the namespace being retrieved + @returns: requested namespace """ # TODO: - Update sync to match. namespace = self.loaded_namespaces.get(namespace_name) @@ -591,27 +614,25 @@ def _ensure_namespace_exists(self, namespace_name: str) -> Namespace: return namespace - def _load_pages(self, pages_to_show: List[GuiPage], show_index: None): - """Loads the requested pages in the namespace. - - Args: - pages_to_show: the pages requested to be loaded + def _load_pages(self, pages_to_show: List[GuiPage], show_index: int): + """ + Loads the requested pages in the namespace. + @param pages_to_show: list of pages to be loaded + @param show_index: index to load pages at """ active_namespace = self.active_namespaces[0] active_namespace.load_pages(pages_to_show, show_index) def _update_namespace_persistence(self, persistence: Union[bool, int]): - """Sets the persistence of the namespace being activated. - + """ + Sets the persistence of the namespace being activated. A namespace's persistence is the same as the persistence of the most recent pages added to a namespace. For example, a multi-page namespace could show the first set of pages with a persistence of True (show until removed) and the last page with a persistence of 15 seconds. This would ensure that the namespace isn't removed while the skill is showing the pages. - - Args:active_extension - persistence: length of time the namespace should be displayed + @param persistence: length of time the namespace should be displayed """ LOG.debug(f"Setting namespace persistence to {persistence}") for position, namespace in enumerate(self.active_namespaces): @@ -624,23 +645,21 @@ def _update_namespace_persistence(self, persistence: Union[bool, int]): else: namespace.set_persistence(skill_type="genericSkill") - # check if there is a scheduled remove_namespace_timer and cancel it - if namespace.persistent: - if namespace.name in self.remove_namespace_timers: - self.remove_namespace_timers[namespace.name].cancel( - ) - self._del_namespace_in_remove_timers( - namespace.name) + # check if there is a scheduled remove_namespace_timer + # and cancel it + if namespace.persistent and namespace.name in \ + self.remove_namespace_timers: + self.remove_namespace_timers[namespace.name].cancel() + self._del_namespace_in_remove_timers(namespace.name) if not namespace.persistent: LOG.info("It is being scheduled here") self._schedule_namespace_removal(namespace) def _schedule_namespace_removal(self, namespace: Namespace): - """Uses a timer thread to remove the namespace. - - Args: - namespace: the namespace to be removed + """ + Uses a timer thread to remove the namespace. + @param namespace: the namespace to be removed """ # Before removing check if there isn't already a timer for this namespace if namespace.name in self.remove_namespace_timers: @@ -651,22 +670,23 @@ def _schedule_namespace_removal(self, namespace: Namespace): self._remove_namespace_via_timer, args=(namespace.name,) ) - LOG.debug( - f"Scheduled removal of namespace {namespace.name} in duration {namespace.duration}") + LOG.debug(f"Scheduled removal of namespace {namespace.name} in " + f"duration {namespace.duration}") remove_namespace_timer.start() self.remove_namespace_timers[namespace.name] = remove_namespace_timer def _remove_namespace_via_timer(self, namespace_name: str): - """Removes a namespace and the corresponding timer instance.""" + """ + Removes a namespace and the corresponding timer instance. + @param namespace_name: name of namespace to remove + """ self._remove_namespace(namespace_name) self._del_namespace_in_remove_timers(namespace_name) def _remove_namespace(self, namespace_name: str): """ Removes a namespace from the active namespace stack. - - Args: - namespace_name: namespace to remove + @param namespace_name: name of namespace to remove """ LOG.debug(f"Removing namespace {namespace_name}") @@ -677,9 +697,10 @@ def _remove_namespace(self, namespace_name: str): namespace = self.loaded_namespaces.get(namespace_name) if namespace is not None and namespace in self.active_namespaces: - self.core_bus.emit(Message("gui.namespace.removed", data={ - "skill_id": namespace.name})) + self.core_bus.emit(Message("gui.namespace.removed", + data={"skill_id": namespace.name})) if self.active_extension == "Bigscreen": + # TODO: Define callback or event instead of arbitrary sleep # wait for window management in bigscreen extension to finish sleep(1) namespace_position = self.active_namespaces.index(namespace) @@ -689,6 +710,9 @@ def _remove_namespace(self, namespace_name: str): self._emit_namespace_displayed_event() def _emit_namespace_displayed_event(self): + """ + Emit a `gui.namespace.displayed` Message to notify core of changes. + """ if self.active_namespaces: displaying_namespace = self.active_namespaces[0] message_data = dict(skill_id=displaying_namespace.name) @@ -697,10 +721,9 @@ def _emit_namespace_displayed_event(self): ) def handle_status_request(self, message: Message): - """Handles a GUI status request by replying with the connection status. - - Args: - message: the request for status of the GUI + """ + Handles a GUI status request by replying with the connection status. + @param message: the request for status of the GUI """ gui_connected = determine_if_gui_connected() reply = message.reply( @@ -709,10 +732,9 @@ def handle_status_request(self, message: Message): self.core_bus.emit(reply) def handle_set_value(self, message: Message): - """Handles a request to set the value of namespace data attributes. - - Args: - message: the request to set attribute values + """ + Handles a request to set the value of namespace data attributes. + @param message: the request to set attribute values """ try: namespace_name = message.data['__from'] @@ -726,11 +748,10 @@ def handle_set_value(self, message: Message): self._update_namespace_data(namespace_name, message.data) def _update_namespace_data(self, namespace_name: str, data: dict): - """Updates the values of namespace data attributes, unless unchanged. - - Args: - namespace_name: the name of the namespace to update - data: the name and new value of one or more data attributes + """ + Updates the values of namespace data attributes, unless unchanged. + @param namespace_name: the name of the namespace to update + @param data: the name and new value of one or more data attributes """ namespace = self._ensure_namespace_exists(namespace_name) for key, value in data.items(): @@ -742,10 +763,9 @@ def _update_namespace_data(self, namespace_name: str, data: dict): namespace.load_data(key, value) def handle_client_connected(self, message: Message): - """Handles an event from the GUI indicating it is connected to the bus. - - Args: - message: the event sent by the GUI + """ + Handles an event from the GUI indicating it is connected to the bus. + @param message: the event sent by the GUI """ # GUI has announced presence # Announce connection, the GUI should connect on it soon @@ -753,14 +773,14 @@ def handle_client_connected(self, message: Message): LOG.info(f"GUI with ID {gui_id} connected to core message bus") websocket_config = get_gui_websocket_config() port = websocket_config["base_port"] - message = Message("mycroft.gui.port", dict(port=port, gui_id=gui_id)) + message = message.forward("mycroft.gui.port", + dict(port=port, gui_id=gui_id)) self.core_bus.emit(message) def handle_page_interaction(self, message: Message): - """Handles an event from the GUI indicating the page has been interacted with. - - Args: - message: the event sent by the GUI + """ + Handles an event from the GUI indicating a page has been interacted with. + @param message: the event sent by the GUI """ # GUI has interacted with a page # Update and increase the namespace duration and reset the remove timer @@ -777,10 +797,9 @@ def handle_page_interaction(self, message: Message): self._schedule_namespace_removal(namespace) def handle_page_gained_focus(self, message: Message): - """Handles focus events from the GUI indicating the page has gained focus. - - Args: - message: the event sent by the GUI + """ + Handles focus events from the GUI indicating the page has gained focus. + @param message: the event sent by the GUI """ namespace_name = message.data.get("skill_id") namespace_page_number = message.data.get("page_number") @@ -789,26 +808,25 @@ def handle_page_gained_focus(self, message: Message): # first check if the namespace is already active if namespace in self.active_namespaces: - # if the namespace is already active, check if the page number has changed + # if the namespace is already active, + # check if the page number has changed if namespace_page_number != namespace.page_number: namespace.page_gained_focus(namespace_page_number) - def handle_namespace_global_back(self, message: None): - """Handles global back events from the GUI. - - Args: - message: the event sent by the GUI + def handle_namespace_global_back(self, message: Optional[Message]): + """ + Handles global back events from the GUI. + @param message: the event sent by the GUI """ namespace_name = self.active_namespaces[0].name namespace = self.loaded_namespaces.get(namespace_name) if namespace in self.active_namespaces: namespace.global_back() - def _del_namespace_in_remove_timers(self, namespace_name): - """ Delete namespace from remove_namespace_timers dict. - - Args: - namespace: namespace to be deleted + def _del_namespace_in_remove_timers(self, namespace_name: str): + """ + Delete namespace from remove_namespace_timers dict. + @param namespace_name: name of namespace to be deleted """ if namespace_name in self.remove_namespace_timers: del self.remove_namespace_timers[namespace_name] diff --git a/ovos_gui/page.py b/ovos_gui/page.py index 7e46051..938ba18 100644 --- a/ovos_gui/page.py +++ b/ovos_gui/page.py @@ -2,23 +2,15 @@ class GuiPage: - """ A representation of a GUI Page - - A GuiPage represents a single GUI Display within a given namespace. A Page - has a name, a position and can have either Persistence or Duration during - which it will exist - - Attributes: - name: the name of the page that is shown in a given namespace, assigned - by the skill author - persistent: indicated weather or not the page itself should persists for a - period of time or unit the it is removed manually - duration: the duration of the page in the namespace, assigned by the skill - author if the page is not persistent - active: indicates whether the page is currently active in the namespace - """ - def __init__(self, url: str, name: str, persistent: bool, duration: int): + """ + A GuiPage represents a single GUI Display within a given namespace. + A Page can either be `persistent` or be removed after some `duration`. + @param url: URI (local or network path) of the GUI Page + @param name: Name of the page as shown in its namespace + @param persistent: If True, page is displayed indefinitely + @param duration: Number of seconds to display the page for + """ self.url = url self.name = name self.persistent = persistent diff --git a/ovos_gui/service.py b/ovos_gui/service.py index 8294f0c..8481e1a 100644 --- a/ovos_gui/service.py +++ b/ovos_gui/service.py @@ -27,8 +27,9 @@ def on_stopping(): class GUIService: - def __init__(self, alive_hook=on_alive, started_hook=on_started, ready_hook=on_ready, - error_hook=on_error, stopping_hook=on_stopping): + def __init__(self, alive_hook=on_alive, started_hook=on_started, + ready_hook=on_ready, error_hook=on_error, + stopping_hook=on_stopping): self.bus = MessageBusClient() self.extension_manager = None self.gui = NamespaceManager(self.bus) @@ -41,7 +42,9 @@ def __init__(self, alive_hook=on_alive, started_hook=on_started, ready_hook=on_r self.status.bind(self.bus) def _init_bus_client(self): - """Start the bus client daemon and wait for connection.""" + """ + Start the bus client daemon and wait for connection. + """ # Wait for connection Configuration.set_config_update_handlers(self.bus) if not self.bus.connected_event.is_set(): @@ -50,7 +53,9 @@ def _init_bus_client(self): LOG.info('Connected to messagebus') def run(self): - """Start the GUI after it has been constructed.""" + """ + Start the GUI after it has been constructed. + """ # Allow exceptions to be raised to the GUI Service # if they may cause the Service to fail. self.status.set_alive() @@ -60,10 +65,14 @@ def run(self): self.status.set_ready() LOG.info(f"GUI Service Ready") - def is_alive(self): - """Respond to is_alive status request.""" + def is_alive(self) -> bool: + """ + Respond to is_alive status request. + """ return self.status.state >= ProcessState.ALIVE def stop(self): - """Perform any GUI shutdown processes.""" + """ + Perform any GUI shutdown processes. + """ self.status.set_stopping() diff --git a/ovos_gui/tui.py b/ovos_gui/tui.py index 3a47653..5d27841 100644 --- a/ovos_gui/tui.py +++ b/ovos_gui/tui.py @@ -1,11 +1,10 @@ -from os import getpid -from os.path import basename import json + +from os.path import basename from time import sleep from pprint import pformat - from ovos_utils.log import LOG -from ovos_bus_client import GUIMessage, GUIWebsocketClient +from ovos_bus_client import GUIWebsocketClient def get_websocket(host="0.0.0.0", port=18181, route='/', ssl=False, threaded=True): @@ -173,4 +172,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/test/requirements.txt b/test/requirements.txt index 05206bb..9e40bde 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,8 +1,2 @@ -coveralls==1.8.2 -flake8==3.7.9 -pytest==5.2.4 -pytest-cov==2.8.1 -cov-core==1.15.0 -sphinx==2.2.1 -sphinx-rtd-theme==0.4.3 -ovos_plugin_manager>=0.0.23a9 \ No newline at end of file +pytest~=7.1 +pytest-cov~=4.1 \ No newline at end of file diff --git a/test/unittests/test_bus.py b/test/unittests/test_bus.py new file mode 100644 index 0000000..0ebd682 --- /dev/null +++ b/test/unittests/test_bus.py @@ -0,0 +1,45 @@ +import unittest +from unittest.mock import patch, Mock + + +class TestBus(unittest.TestCase): + @patch("ovos_gui.bus.Configuration") + def test_get_gui_websocket_config(self, configuration): + from ovos_gui.bus import get_gui_websocket_config + + mock_config = {'gui_websocket': {'host': 'test', 'port': 80}} + configuration.return_value = mock_config + + config = get_gui_websocket_config() + self.assertEqual(config, mock_config['gui_websocket']) + + configuration.return_value = dict() + with self.assertRaises(KeyError): + get_gui_websocket_config() + + def test_create_gui_service(self): + from ovos_gui.bus import create_gui_service + # TODO + + @patch("ovos_gui.bus.GUIWebsocketHandler") + def test_send_message_to_gui(self, handler): + from ovos_gui.bus import send_message_to_gui + mock_client = Mock() + handler.clients = [mock_client] + message = {"test": True} + + send_message_to_gui(message) + mock_client.send.assert_called_once_with(message) + + @patch("ovos_gui.bus.GUIWebsocketHandler") + def test_determine_if_gui_connected(self, handler): + from ovos_gui.bus import determine_if_gui_connected + mock_client = Mock() + self.assertFalse(determine_if_gui_connected()) + handler.clients = [mock_client] + self.assertTrue(determine_if_gui_connected()) + + +class TestGUIWebsocketHandler(unittest.TestCase): + from ovos_gui.bus import GUIWebsocketHandler + # TODO diff --git a/test/unittests/test_extensions.py b/test/unittests/test_extensions.py new file mode 100644 index 0000000..907ac65 --- /dev/null +++ b/test/unittests/test_extensions.py @@ -0,0 +1,59 @@ +import unittest +from unittest.mock import patch, Mock + +import ovos_gui.extensions +from ovos_utils.messagebus import FakeBus +from .mocks import base_config + +PATCH_MODULE = "ovos_gui.extensions" + +_MOCK_CONFIG = base_config() +_MOCK_CONFIG.merge( + { + 'gui': { + 'extension': 'generic', + 'generic': { + 'homescreen_supported': False + } + } + }) + + +class TestExtensionManager(unittest.TestCase): + bus = FakeBus() + name = "TestManager" + + @classmethod + @patch("ovos_gui.namespace.create_gui_service") + def setUpClass(cls, create_gui) -> None: + from ovos_gui.extensions import ExtensionsManager + from ovos_gui.namespace import NamespaceManager + + ovos_gui.extensions.Configuration = Mock(return_value=_MOCK_CONFIG) + + cls.extension_manager = ExtensionsManager(cls.name, cls.bus, + NamespaceManager(cls.bus)) + create_gui.assert_called_once_with(cls.extension_manager.gui) + + def test_00_extensions_manager_init(self): + from ovos_gui.namespace import NamespaceManager + self.assertEqual(self.extension_manager.name, self.name) + self.assertEqual(self.extension_manager.bus, self.bus) + self.assertIsInstance(self.extension_manager.gui, NamespaceManager) + self.assertEqual(self.extension_manager.gui.core_bus, self.bus) + self.assertIsInstance(self.extension_manager.active_extension, str) + + @patch("ovos_gui.extensions.OVOSGuiFactory.create") + def test_activate_extension(self, create): + mock_extension = Mock() + mock_extension.preload_gui = False + mock_extension.permanent = True + # TODO: Test preload/permanent combinations + create.return_value = mock_extension + self.extension_manager.activate_extension("smartspeaker") + create.assert_called_once() + # TODO: Check call for mapped plugin name + self.assertEqual(self.extension_manager.extension, mock_extension) + mock_extension.bind_homescreen.assert_called_once() + # TODO: Test messagebus Messages + diff --git a/test/unittests/test_extensions_manager.py b/test/unittests/test_extensions_manager.py deleted file mode 100644 index 6f1b282..0000000 --- a/test/unittests/test_extensions_manager.py +++ /dev/null @@ -1,31 +0,0 @@ -from unittest import mock -from unittest.mock import patch - -from ovos_config import Configuration - -from ovos_gui.extensions import ExtensionsManager -from .mocks import MessageBusMock, base_config - -PATCH_MODULE = "ovos_gui.extensions" - - -# Add Unit Tests For ExtensionManager - -class TestExtensionManager: - @patch.object(Configuration, 'get') - def test_extension_manager_activate(self, mock_get): - config = base_config() - config.merge( - { - 'gui': { - 'extension': 'generic', - 'generic': { - 'homescreen_supported': False - } - } - }) - mock_get.return_value = config - extension_manager = ExtensionsManager("ExtensionManager", MessageBusMock(), MessageBusMock()) - extension_manager.activate_extension = mock.Mock() - extension_manager.activate_extension("generic") - extension_manager.activate_extension.assert_any_call("generic") diff --git a/test/unittests/test_homescreen.py b/test/unittests/test_homescreen.py new file mode 100644 index 0000000..5660260 --- /dev/null +++ b/test/unittests/test_homescreen.py @@ -0,0 +1,80 @@ +import unittest +from unittest.mock import patch + +from ovos_bus_client.message import Message +from ovos_utils.messagebus import FakeBus +from ovos_gui.namespace import NamespaceManager + + +class TestHomescreenManager(unittest.TestCase): + from ovos_gui.homescreen import HomescreenManager + bus = FakeBus() + gui = NamespaceManager(bus) + homescreen_manager = HomescreenManager(bus, gui) + + def test_00_homescreen_manager_init(self): + self.assertEqual(self.homescreen_manager.bus, self.bus) + self.assertEqual(self.homescreen_manager.gui, self.gui) + self.assertFalse(self.homescreen_manager.mycroft_ready) + self.assertIsInstance(self.homescreen_manager.homescreens, list) + # TODO: Test messagebus handlers + + def test_add_homescreen(self): + # TODO + pass + + def test_remove_homescreen(self): + # TODO + pass + + def test_get_homescreen(self): + # TODO + pass + + def test_handle_get_active_homescreen(self): + # TODO + pass + + def test_handle_set_active_homescreen(self): + # TODO + pass + + @patch("ovos_gui.homescreen.Configuration") + def test_get_active_homescreen(self, config): + config.return_value = {"gui": {"idle_display_skill": "test"}} + self.assertIsNone(self.homescreen_manager.get_active_homescreen()) + # TODO: Mock `homescreens` and get a value here + + @patch("ovos_gui.homescreen.update_mycroft_config") + def test_set_active_homescreen(self, update_config): + test_id = "test_homescreen_id" + self.homescreen_manager.set_active_homescreen(test_id) + update_config.assert_called_once_with( + {"gui": {"idle_display_skill": test_id}}, + bus=self.homescreen_manager.bus) + + def test_reload_homescreens_list(self): + # TODO + pass + + def test_show_homescreen_on_add(self): + # TODO + pass + + @patch("ovos_gui.homescreen.Configuration") + @patch("ovos_gui.homescreen.update_mycroft_config") + def test_disable_active_homescreen(self, update_config, config): + config.return_value = {"gui": {"idle_display_skill": "test"}} + self.homescreen_manager.disable_active_homescreen(Message("")) + update_config.assert_called_once_with( + {"gui": {"idle_display_skill": None}}, + bus=self.homescreen_manager.bus) + + def test_show_homescreen(self): + # TODO + pass + + def test_set_mycroft_ready(self): + self.homescreen_manager.mycroft_ready = False + self.homescreen_manager.set_mycroft_ready(Message("mycroft.ready")) + self.assertTrue(self.homescreen_manager.mycroft_ready) diff --git a/test/unittests/test_namespace.py b/test/unittests/test_namespace.py index b330af3..2d016a8 100644 --- a/test/unittests/test_namespace.py +++ b/test/unittests/test_namespace.py @@ -14,16 +14,30 @@ # """Tests for the GUI namespace helper class.""" -from unittest import TestCase -from unittest import mock +from unittest import TestCase, mock -from ovos_gui.namespace import Namespace, NamespaceManager +from ovos_bus_client.message import Message +from ovos_utils.messagebus import FakeBus from ovos_gui.page import GuiPage -from .mocks import MessageBusMock +from ovos_gui.namespace import Namespace PATCH_MODULE = "ovos_gui.namespace" +class TestNamespaceFunctions(TestCase): + def test_validate_page_message(self): + from ovos_gui.namespace import _validate_page_message + # TODO + + def test_get_idle_display_config(self): + from ovos_gui.namespace import _get_idle_display_config + # TODO + + def test_get_active_gui_extension(self): + from ovos_gui.namespace import _get_active_gui_extension + # TODO + + class TestNamespace(TestCase): def setUp(self): self.namespace = Namespace("foo") @@ -81,6 +95,14 @@ def test_load_data(self): self.namespace.load_data(name="foo", value="bar") send_message_mock.assert_called_with(load_data_message) + def test_unload_data(self): + # TODO + pass + + def test_get_position_of_last_item_in_data(self): + # TODO + pass + def test_set_persistence_numeric(self): self.namespace.set_persistence("genericSkill") self.assertEqual(self.namespace.duration, 30) @@ -91,7 +113,7 @@ def test_set_persistence_boolean(self): self.assertEqual(self.namespace.duration, 0) self.assertTrue(self.namespace.persistent) - def test_load_new_pages(self): + def test_load_pages_new(self): self.namespace.pages = [GuiPage("foo", "foo.qml", True, 0), GuiPage("bar", "bar.qml", False, 30)] new_pages = [GuiPage("foobar", "foobar.qml", False, 30)] load_page_message = dict( @@ -107,7 +129,7 @@ def test_load_new_pages(self): send_message_mock.assert_called_with(load_page_message) self.assertListEqual(self.namespace.pages, self.namespace.pages) - def test_load_existing_pages(self): + def test_load_pages_existing(self): self.namespace.pages = [GuiPage("foo", "foo.qml", True, 0), GuiPage("bar", "bar.qml", False, 30)] new_pages = [GuiPage("foo", "foo.qml", True, 0)] load_page_message = dict( @@ -123,6 +145,14 @@ def test_load_existing_pages(self): send_message_mock.assert_called_with(load_page_message) self.assertListEqual(self.namespace.pages, self.namespace.pages) + def test_add_pages(self): + # TODO + pass + + def test_activate_page(self): + # TODO + pass + def test_remove_pages(self): self.namespace.pages = ["foo", "bar", "foobar"] remove_page_message = dict( @@ -136,3 +166,185 @@ def test_remove_pages(self): self.namespace.remove_pages([2]) send_message_mock.assert_called_with(remove_page_message) self.assertListEqual(["foo", "bar"], self.namespace.pages) + + def test_page_gained_focus(self): + # TODO + pass + + def test_page_update_interaction(self): + # TODO + pass + + def test_get_page_at_position(self): + # TODO + pass + + def test_get_active_page(self): + # TODO + pass + + def test_index_in_pages_list(self): + # TODO + pass + + def test_global_back(self): + # TODO + pass + + +class TestNamespaceManager(TestCase): + def setUp(self): + from ovos_gui.namespace import NamespaceManager + with mock.patch(PATCH_MODULE + ".create_gui_service"): + self.namespace_manager = NamespaceManager(FakeBus()) + + def test_handle_clear_namespace_active(self): + namespace = Namespace("foo") + namespace.remove = mock.Mock() + self.namespace_manager.loaded_namespaces = dict(foo=namespace) + self.namespace_manager.active_namespaces = [namespace] + + message = Message("gui.clear.namespace", data={"__from": "foo"}) + self.namespace_manager.handle_clear_namespace(message) + namespace.remove.assert_called_with(0) + + def test_handle_clear_namespace_inactive(self): + message = Message("gui.clear.namespace", data={"__from": "foo"}) + namespace = Namespace("foo") + namespace.remove = mock.Mock() + self.namespace_manager.handle_clear_namespace(message) + namespace.remove.assert_not_called() + + def test_handle_send_event(self): + message_data = { + "__from": "foo", "event_name": "bar", "params": "foobar" + } + message = Message("gui.clear.namespace", data=message_data) + event_triggered_message = dict( + type='mycroft.events.triggered', + namespace="foo", + event_name="bar", + data="foobar" + ) + patch_function = PATCH_MODULE + ".send_message_to_gui" + with mock.patch(patch_function) as send_message_mock: + self.namespace_manager.handle_send_event(message) + send_message_mock.assert_called_with(event_triggered_message) + + def test_handle_delete_page_active_namespace(self): + namespace = Namespace("foo") + namespace.pages = [GuiPage("bar", "bar.qml", True, 0)] + namespace.remove_pages = mock.Mock() + self.namespace_manager.loaded_namespaces = dict(foo=namespace) + self.namespace_manager.active_namespaces = [namespace] + + message_data = {"__from": "foo", "page": ["bar"]} + message = Message("gui.clear.namespace", data=message_data) + self.namespace_manager.handle_delete_page(message) + namespace.remove_pages.assert_called_with([0]) + + def test_handle_delete_page_inactive_namespace(self): + namespace = Namespace("foo") + namespace.pages = ["bar"] + namespace.remove_pages = mock.Mock() + + message_data = {"__from": "foo", "page": ["bar"]} + message = Message("gui.clear.namespace", data=message_data) + self.namespace_manager.handle_delete_page(message) + namespace.remove_pages.assert_not_called() + + def test_handle_remove_pages(self): + # TODO + pass + + def test_handle_show_page(self): + message_data = {"__from": "foo", "__idle": 10, "page": ["bar"]} + message = Message("gui.page.show", data=message_data) + patch_function = PATCH_MODULE + ".send_message_to_gui" + with mock.patch(patch_function): + self.namespace_manager._schedule_namespace_removal = mock.Mock() + self.namespace_manager.handle_show_page(message) + + self.assertEqual( + "foo", self.namespace_manager.active_namespaces[0].name + ) + self.assertTrue("foo" in self.namespace_manager.loaded_namespaces) + namespace = self.namespace_manager.loaded_namespaces["foo"] + self.assertListEqual(namespace.pages, namespace.pages) + + def test_handle_show_page_invalid_message(self): + namespace = Namespace("foo") + namespace.load_pages = mock.Mock() + + message_data = {"__from": "foo"} + message = Message("gui.page.show", data=message_data) + patch_function = PATCH_MODULE + ".send_message_to_gui" + with mock.patch(patch_function): + self.namespace_manager.handle_show_page(message) + + self.assertListEqual([], self.namespace_manager.active_namespaces) + self.assertDictEqual({}, self.namespace_manager.loaded_namespaces) + + def test_activate_namespace(self): + # TODO + pass + + def test_ensure_namespace_exists(self): + # TODO + pass + + def test_load_pages(self): + # TODO + pass + + def test_update_namespace_persistence(self): + # TODO + pass + + def test_schedule_namespace_removal(self): + # TODO + pass + + def test_remove_namespace_via_timer(self): + # TODO + pass + + def test_remove_namespace(self): + # TODO + pass + + def test_emit_namespace_displayed_event(self): + # TODO + pass + + def test_handle_status_request(self): + # TODO + pass + + def test_handle_set_value(self): + # TODO + pass + + def test_update_namespace_data(self): + # TODO + pass + + def test_handle_client_connected(self): + # TODO + pass + + def test_handle_page_interaction(self): + # TODO + pass + + def test_handle_page_gained_focus(self): + # TODO + pass + + def test_handle_namespace_global_back(self): + # TODO + pass + + def test_del_namespace_in_remove_timers(self): + # TODO + pass diff --git a/test/unittests/test_namespace_manager.py b/test/unittests/test_namespace_manager.py deleted file mode 100644 index e78965b..0000000 --- a/test/unittests/test_namespace_manager.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2022 Mycroft AI Inc. -# -# 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. -# -"""Tests for the GUI namespace manager helper class.""" - -from unittest import TestCase -from unittest import mock - -from ovos_bus_client import Message - -from ovos_gui.namespace import Namespace, NamespaceManager -from ovos_gui.page import GuiPage -from .mocks import MessageBusMock - -PATCH_MODULE = "ovos_gui.namespace" - - -class TestNamespace(TestCase): - def setUp(self): - with mock.patch(PATCH_MODULE + ".create_gui_service"): - self.namespace_manager = NamespaceManager(MessageBusMock()) - - def test_handle_clear_active_namespace(self): - namespace = Namespace("foo") - namespace.remove = mock.Mock() - self.namespace_manager.loaded_namespaces = dict(foo=namespace) - self.namespace_manager.active_namespaces = [namespace] - - message = Message("gui.clear.namespace", data={"__from": "foo"}) - self.namespace_manager.handle_clear_namespace(message) - namespace.remove.assert_called_with(0) - - def test_handle_clear_inactive_namespace(self): - message = Message("gui.clear.namespace", data={"__from": "foo"}) - namespace = Namespace("foo") - namespace.remove = mock.Mock() - self.namespace_manager.handle_clear_namespace(message) - namespace.remove.assert_not_called() - - def test_handle_send_event(self): - message_data = { - "__from": "foo", "event_name": "bar", "params": "foobar" - } - message = Message("gui.clear.namespace", data=message_data) - event_triggered_message = dict( - type='mycroft.events.triggered', - namespace="foo", - event_name="bar", - data="foobar" - ) - patch_function = PATCH_MODULE + ".send_message_to_gui" - with mock.patch(patch_function) as send_message_mock: - self.namespace_manager.handle_send_event(message) - send_message_mock.assert_called_with(event_triggered_message) - - def test_handle_delete_active_namespace_page(self): - namespace = Namespace("foo") - namespace.pages = [GuiPage("bar", "bar.qml", True, 0)] - namespace.remove_pages = mock.Mock() - self.namespace_manager.loaded_namespaces = dict(foo=namespace) - self.namespace_manager.active_namespaces = [namespace] - - message_data = {"__from": "foo", "page": ["bar"]} - message = Message("gui.clear.namespace", data=message_data) - self.namespace_manager.handle_delete_page(message) - namespace.remove_pages.assert_called_with([0]) - - def test_handle_delete_inactive_namespace_page(self): - namespace = Namespace("foo") - namespace.pages = ["bar"] - namespace.remove_pages = mock.Mock() - - message_data = {"__from": "foo", "page": ["bar"]} - message = Message("gui.clear.namespace", data=message_data) - self.namespace_manager.handle_delete_page(message) - namespace.remove_pages.assert_not_called() - - def test_handle_show_pages(self): - message_data = {"__from": "foo", "__idle": 10, "page": ["bar"]} - message = Message("gui.page.show", data=message_data) - patch_function = PATCH_MODULE + ".send_message_to_gui" - with mock.patch(patch_function): - self.namespace_manager._schedule_namespace_removal = mock.Mock() - self.namespace_manager.handle_show_page(message) - - self.assertEqual( - "foo", self.namespace_manager.active_namespaces[0].name - ) - self.assertTrue("foo" in self.namespace_manager.loaded_namespaces) - namespace = self.namespace_manager.loaded_namespaces["foo"] - self.assertListEqual(namespace.pages, namespace.pages) - - def test_handle_show_pages_invalid_message(self): - namespace = Namespace("foo") - namespace.load_pages = mock.Mock() - - message_data = {"__from": "foo"} - message = Message("gui.page.show", data=message_data) - patch_function = PATCH_MODULE + ".send_message_to_gui" - with mock.patch(patch_function): - self.namespace_manager.handle_show_page(message) - - self.assertListEqual([], self.namespace_manager.active_namespaces) - self.assertDictEqual({}, self.namespace_manager.loaded_namespaces) diff --git a/test/unittests/test_page.py b/test/unittests/test_page.py new file mode 100644 index 0000000..35d88b6 --- /dev/null +++ b/test/unittests/test_page.py @@ -0,0 +1,16 @@ +import unittest + + +class TestGuiPage(unittest.TestCase): + def test_gui_page(self): + from ovos_gui.page import GuiPage + uri = __file__ + name = "test" + persistent = True + duration = 0 + page = GuiPage(uri, name, persistent, duration) + self.assertEqual(page.url, uri) + self.assertEqual(page.name, name) + self.assertEqual(page.persistent, persistent) + self.assertEqual(page.duration, 0) + self.assertFalse(page.active) diff --git a/test/unittests/test_service.py b/test/unittests/test_service.py new file mode 100644 index 0000000..7667f5f --- /dev/null +++ b/test/unittests/test_service.py @@ -0,0 +1,6 @@ +import unittest + + +class TestGuiService(unittest.TestCase): + from ovos_gui.service import GUIService + # TODO diff --git a/test/unittests/test_tui.py b/test/unittests/test_tui.py new file mode 100644 index 0000000..fb0a827 --- /dev/null +++ b/test/unittests/test_tui.py @@ -0,0 +1,16 @@ +import unittest + + +class TestTui(unittest.TestCase): + def test_get_websocket(self): + from ovos_gui.tui import get_websocket + # TODO + + def test_bcolors(self): + from ovos_gui.tui import bcolors + # TODO + + +class TestGuiDebugger(unittest.TestCase): + from ovos_gui.tui import GUIDebugger + # TODO \ No newline at end of file From f44617392cde5f1e69821c197d96353b07afd051 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Fri, 23 Jun 2023 19:45:50 +0000 Subject: [PATCH 13/26] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_gui/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff68f6d..590033e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a4...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a5...HEAD) + +**Merged pull requests:** + +- Unit Tests and Documentation [\#15](https://github.com/OpenVoiceOS/ovos-gui/pull/15) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.3a5](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a5) (2023-06-13) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a4...V0.0.3a5) **Merged pull requests:** diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 0d01bb4..503780c 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 5 +VERSION_ALPHA = 6 # END_VERSION_BLOCK From 54e7e57f48796afcac33d5ae7eb575c5e6026f21 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Tue, 4 Jul 2023 13:21:52 -0700 Subject: [PATCH 14/26] Update dependencies to stable versions (#16) --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 47b6ae9..0a9675d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -ovos-bus-client~=0.0, >=0.0.4a5 -ovos-utils~=0.0, >=0.0.34a3 +ovos-bus-client~=0.0, >=0.0.5 +ovos-utils~=0.0, >=0.0.34 ovos-config~=0.0,>=0.0.10 tornado~=6.0, >=6.0.3 ovos-plugin-manager>=0.0.23 From 60769f0f81157510359e54a2a0d6ff332265e183 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Tue, 4 Jul 2023 20:22:50 +0000 Subject: [PATCH 15/26] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_gui/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 590033e..eecdc83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a5...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a6...HEAD) + +**Merged pull requests:** + +- Update dependencies to stable versions [\#16](https://github.com/OpenVoiceOS/ovos-gui/pull/16) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.3a6](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a6) (2023-06-23) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a5...V0.0.3a6) **Merged pull requests:** diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 503780c..c756809 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 6 +VERSION_ALPHA = 7 # END_VERSION_BLOCK From fc49193a019fa409cb7568057659e0011325dcec Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Sat, 8 Jul 2023 01:05:31 +0100 Subject: [PATCH 16/26] GUI File Server and Alternate GUI Framework Support (#9) Co-authored-by: JarbasAl Co-authored-by: Daniel McKnight --- README.md | 7 + ovos_gui/bus.py | 108 ++++-- ovos_gui/gui_file_server.py | 52 +++ ovos_gui/homescreen.py | 4 +- ovos_gui/namespace.py | 348 +++++++++++++----- ovos_gui/page.py | 90 ++++- .../res/{ui => gui/qt5}/FeatureRequest.qml | 0 .../res/{ui => gui/qt5}/RequestHandler.qml | 0 .../qt5}/SYSTEM_AdditionalSettings.qml | 0 .../qt5}/SYSTEM_AnimatedImageFrame.qml | 0 .../res/{ui => gui/qt5}/SYSTEM_HtmlFrame.qml | 0 .../res/{ui => gui/qt5}/SYSTEM_ImageFrame.qml | 0 .../res/{ui => gui/qt5}/SYSTEM_TextFrame.qml | 0 .../res/{ui => gui/qt5}/SYSTEM_UrlFrame.qml | 0 ovos_gui/res/{ui => gui/qt5}/SwipeArea.qml | 0 .../res/{ui => gui/qt5}/WebViewHtmlFrame.qml | 0 .../res/{ui => gui/qt5}/WebViewUrlFrame.qml | 0 ovos_gui/res/snd/clicked.wav | Bin 15240 -> 0 bytes test/unittests/mock_data/gui/qt5/test.qml | 1 + test/unittests/mock_data/gui/qt6/six.qml | 0 test/unittests/mock_data/gui/qt6/test.qml | 1 + test/unittests/test_bus.py | 129 ++++++- test/unittests/test_gui_file_server.py | 15 + test/unittests/test_namespace.py | 148 +++++++- test/unittests/test_page.py | 58 ++- 25 files changed, 807 insertions(+), 154 deletions(-) create mode 100644 ovos_gui/gui_file_server.py rename ovos_gui/res/{ui => gui/qt5}/FeatureRequest.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/RequestHandler.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/SYSTEM_AdditionalSettings.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/SYSTEM_AnimatedImageFrame.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/SYSTEM_HtmlFrame.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/SYSTEM_ImageFrame.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/SYSTEM_TextFrame.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/SYSTEM_UrlFrame.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/SwipeArea.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/WebViewHtmlFrame.qml (100%) rename ovos_gui/res/{ui => gui/qt5}/WebViewUrlFrame.qml (100%) delete mode 100644 ovos_gui/res/snd/clicked.wav create mode 100644 test/unittests/mock_data/gui/qt5/test.qml create mode 100644 test/unittests/mock_data/gui/qt6/six.qml create mode 100644 test/unittests/mock_data/gui/qt6/test.qml create mode 100644 test/unittests/test_gui_file_server.py diff --git a/README.md b/README.md index c6e97d2..2d5269e 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,13 @@ under mycroft.conf "generic": { "homescreen_supported": false } + + // Optional file server support for remote clients + // "gui_file_server": true, + // "file_server_port": 8000, + + // Optionally specify a default qt version for connected clients + // "default_qt_version": 5, }, // The GUI messagebus websocket. Once port is created per connected GUI diff --git a/ovos_gui/bus.py b/ovos_gui/bus.py index 5a5f43d..9604547 100644 --- a/ovos_gui/bus.py +++ b/ovos_gui/bus.py @@ -26,16 +26,18 @@ import asyncio import json from threading import Lock +from typing import List from ovos_bus_client import Message, GUIMessage from ovos_config.config import Configuration -# from ovos_gui.namespace import NamespaceManager +from ovos_gui.page import GuiPage from ovos_utils import create_daemon from ovos_utils.log import LOG from tornado import ioloop from tornado.options import parse_command_line from tornado.web import Application from tornado.websocket import WebSocketHandler +# from ovos_gui.namespace import NamespaceManager _write_lock = Lock() @@ -50,10 +52,10 @@ def get_gui_websocket_config() -> dict: return websocket_config -def create_gui_service(enclosure) -> Application: +def create_gui_service(nsmanager=None) -> Application: """ Initiate a websocket for communicating with the GUI service. - @param enclosure: NamespaceManager instance + @param nsmanager: NamespaceManager instance """ LOG.info('Starting message bus for GUI...') websocket_config = get_gui_websocket_config() @@ -61,10 +63,7 @@ def create_gui_service(enclosure) -> Application: parse_command_line(['--logging=None']) routes = [(websocket_config['route'], GUIWebsocketHandler)] - application = Application(routes) - # TODO: Is the NamespaceManager used by `application`, or can it be a - # GUIWebsocketHandler class variable - application.enclosure = enclosure + application = Application(routes, namespace_manager=nsmanager) application.listen( websocket_config['base_port'], websocket_config['host'] ) @@ -76,7 +75,8 @@ def create_gui_service(enclosure) -> Application: def send_message_to_gui(message: dict): """ - Sends the supplied message to all connected GUI clients. + Sends the supplied message to all connected GUI clients. This function does + NOT account for the GUI framework in use by each client @param message: dict data to send to GUI clients """ for connection in GUIWebsocketHandler.clients: @@ -97,6 +97,18 @@ class GUIWebsocketHandler(WebSocketHandler): """Defines the websocket pipeline between the GUI and Mycroft.""" clients = [] + def __init__(self, *args, **kwargs): + WebSocketHandler.__init__(self, *args, **kwargs) + self._framework = "qt5" + self.ns_manager = self.application.settings.get("namespace_manager") + + @property + def framework(self) -> str: + """ + Get the GUI framework used by this client + """ + return self._framework or "qt5" + def open(self): """ Add a new connection to `clients` and synchronize @@ -112,31 +124,46 @@ def on_close(self): LOG.info('Closing {}'.format(id(self))) GUIWebsocketHandler.clients.remove(self) + def get_client_pages(self, namespace): + """ + Get a list of client page URLs for the given namespace + @param namespace: Namespace to get pages for + @return: list of page URIs for this GUI Client + """ + client_pages = [] + server_url = self.ns_manager.gui_file_server.url if \ + self.ns_manager.gui_file_server else None + for page in namespace.pages: + uri = page.get_uri(self.framework, server_url) + client_pages.append(uri) + + return client_pages + def synchronize(self): """ Upload namespaces, pages and data to the last connected client. """ namespace_pos = 0 - enclosure = self.application.enclosure - for namespace in enclosure.active_namespaces: - LOG.info(f'Sync {namespace.name}') + for namespace in self.ns_manager.active_namespaces: + LOG.info(f'Sync {namespace.skill_id}') # Insert namespace self.send({"type": "mycroft.session.list.insert", "namespace": "mycroft.system.active_skills", "position": namespace_pos, - "data": [{"skill_id": namespace.name}] + "data": [{"skill_id": namespace.skill_id}] }) # Insert pages self.send({"type": "mycroft.gui.list.insert", - "namespace": namespace.name, + "namespace": namespace.skill_id, "position": 0, - "data": [{"url": p.url} for p in namespace.pages] + "data": [{"url": url} for url in + self.get_client_pages(namespace)] }) # Insert data for key, value in namespace.data.items(): self.send({"type": "mycroft.session.set", - "namespace": namespace.name, + "namespace": namespace.skill_id, "data": {key: value} }) namespace_pos += 1 @@ -148,6 +175,7 @@ def on_message(self, message: str): on the core messagebus. @param message: Serialized Message """ + LOG.debug(f"Received: {message}") parsed_message = GUIMessage.deserialize(message) LOG.debug(f"Received: {parsed_message.msg_type}|{parsed_message.data}") @@ -179,18 +207,37 @@ def on_message(self, message: str): msg_data = parsed_message.data['data'] elif parsed_message.msg_type == 'mycroft.gui.connected': # new client connected to GUI + + # NOTE: mycroft-gui clients do this directly in core bus, don't + # send it to gui bus. In those cases, framework is read from config, + # defaulting to qt5 for backwards-compat. + default_qt_version = \ + Configuration().get('gui', {}).get('default_qt_version') or 5 msg_type = parsed_message.msg_type msg_data = parsed_message.data + + framework = msg_data.get("framework") # new api + if framework is None: + # mycroft-gui api + qt = msg_data.get("qt_version") or default_qt_version + if int(qt) == 6: + framework = "qt6" + else: + framework = "qt5" + + self._framework = framework else: # message not in spec # https://github.com/MycroftAI/mycroft-gui/blob/master/transportProtocol.md LOG.error(f"unknown GUI protocol message type, ignoring: " - f"{parsed_message}") + f"{parsed_message.msg_type}") return + parsed_message.context["gui_framework"] = self.framework message = Message(msg_type, msg_data, parsed_message.context) - self.application.enclosure.core_bus.emit(message) - LOG.debug('Forwarded to core bus') + LOG.debug('Forwarding to core bus...') + self.ns_manager.core_bus.emit(message) + LOG.debug('Done!') def write_message(self, *arg, **kwarg): """ @@ -204,18 +251,37 @@ def write_message(self, *arg, **kwarg): with _write_lock: super().write_message(*arg, **kwarg) + def send_gui_pages(self, pages: List[GuiPage], namespace: str, + position: int): + """ + Send GUI pages to this client, accounting for the client-specific pages + @param pages: list of GuiPage objects to send + @param namespace: namespace to put GuiPages in + @param position: position to insert pages at + """ + server_url = self.ns_manager.gui_file_server.url if \ + self.ns_manager.gui_file_server else None + framework = self.framework + + message = { + "type": "mycroft.gui.list.insert", + "namespace": namespace, + "position": position, + "data": [{"url": page.get_uri(framework, server_url)} + for page in pages] + } + self.send(message) + def send(self, data: dict): """ Send the given data across the socket as JSON @param data: Data to send to the GUI """ s = json.dumps(data) - # LOG.info('Sending {}'.format(s)) self.write_message(s) def check_origin(self, origin): """ - Disable origin check to make js connections work. + Override origin check to make js connections work. """ - # TODO: Should this be implemented or deprecated return True diff --git a/ovos_gui/gui_file_server.py b/ovos_gui/gui_file_server.py new file mode 100644 index 0000000..50abaf4 --- /dev/null +++ b/ovos_gui/gui_file_server.py @@ -0,0 +1,52 @@ +import http.server +import os +import shutil +import socketserver +from threading import Thread, Event + +from ovos_config import Configuration +from ovos_utils.file_utils import get_temp_path +from ovos_utils.log import LOG + +_HTTP_SERVER = None + + +class GuiFileHandler(http.server.SimpleHTTPRequestHandler): + def end_headers(self) -> None: + mimetype = self.guess_type(self.path) + is_file = not self.path.endswith('/') + if is_file and any([mimetype.startswith(prefix) for + prefix in ("text/", "application/octet-stream")]): + self.send_header('Content-Type', "text/plain") + self.send_header('Content-Disposition', 'inline') + super().end_headers() + + +def start_gui_http_server(qml_path: str, port: int = None): + port = port or Configuration().get("gui", {}).get("file_server_port", 8089) + + if os.path.exists(qml_path): + shutil.rmtree(qml_path, ignore_errors=True) + os.makedirs(qml_path, exist_ok=True) + + started_event = Event() + http_daemon = Thread(target=_initialize_http_server, + args=(started_event, qml_path, port), + daemon=True) + http_daemon.start() + started_event.wait(30) + return _HTTP_SERVER + + +def _initialize_http_server(started: Event, directory: str, port: int): + global _HTTP_SERVER + os.chdir(directory) + handler = GuiFileHandler + http_server = socketserver.TCPServer(("", port), handler) + _HTTP_SERVER = http_server + _HTTP_SERVER.qml_path = directory + _HTTP_SERVER.url = \ + f"{_HTTP_SERVER.server_address[0]}:{_HTTP_SERVER.server_address[1]}" + LOG.info(f"GUI file server started: {_HTTP_SERVER.url}") + started.set() + http_server.serve_forever() diff --git a/ovos_gui/homescreen.py b/ovos_gui/homescreen.py index ba603fb..6512530 100644 --- a/ovos_gui/homescreen.py +++ b/ovos_gui/homescreen.py @@ -101,8 +101,8 @@ def get_active_homescreen(self) -> Optional[dict]: Get the active homescreen according to configuration if it is loaded @return: Loaded homescreen with an ID matching configuration """ - enclosure_config = Configuration().get("gui") or {} - active_homescreen = enclosure_config.get("idle_display_skill") + gui_config = Configuration().get("gui") or {} + active_homescreen = gui_config.get("idle_display_skill") LOG.debug(f"Homescreen Manager: Active Homescreen {active_homescreen}") for h in self.homescreens: if h["id"] == active_homescreen: diff --git a/ovos_gui/namespace.py b/ovos_gui/namespace.py index 0ec8fbd..8215297 100644 --- a/ovos_gui/namespace.py +++ b/ovos_gui/namespace.py @@ -39,22 +39,26 @@ code. Changes to namespaces, and their contents, are communicated to the GUI over the GUI message bus. """ - +import shutil +from os import makedirs +from os.path import join, dirname, isfile, exists +from threading import Event from threading import Lock, Timer from time import sleep -from typing import List, Union, Optional +from typing import List, Union, Optional, Dict +from ovos_bus_client import Message, MessageBusClient from ovos_config.config import Configuration from ovos_utils.log import LOG -from ovos_bus_client import Message, MessageBusClient from ovos_gui.bus import ( create_gui_service, determine_if_gui_connected, get_gui_websocket_config, - send_message_to_gui + send_message_to_gui, GUIWebsocketHandler ) from ovos_gui.page import GuiPage +from ovos_gui.gui_file_server import start_gui_http_server namespace_lock = Lock() @@ -117,7 +121,7 @@ class Namespace: are communicated to the GUI message bus. Attributes: - name: the name of the Namespace, generally the skill ID + skill_id: the name of the Namespace, generally the skill ID persistent: indicates whether or not the namespace persists for a period of time or until the namespace is removed. duration: if the namespace persists for a period of time, this is the @@ -126,9 +130,8 @@ class Namespace: displayed at the same time data: a key/value pair representing the data used to populate the GUI """ - - def __init__(self, name: str): - self.name = name + def __init__(self, skill_id: str): + self.skill_id = skill_id self.persistent = False self.duration = 30 self.pages: List[GuiPage] = list() @@ -140,12 +143,12 @@ def add(self): """ Adds this namespace to the list of active namespaces. """ - LOG.info(f"Adding \"{self.name}\" to active GUI namespaces") + LOG.info(f"Adding \"{self.skill_id}\" to active GUI namespaces") message = dict( type="mycroft.session.list.insert", namespace="mycroft.system.active_skills", position=0, - data=[dict(skill_id=self.name)] + data=[dict(skill_id=self.skill_id)] ) send_message_to_gui(message) @@ -154,7 +157,7 @@ def activate(self, position: int): Activate this namespace if its already in the list of active namespaces. @param position: position to move this namespace FROM """ - LOG.info(f"Activating GUI namespace \"{self.name}\"") + LOG.info(f"Activating GUI namespace \"{self.skill_id}\"") message = { "type": "mycroft.session.list.move", "namespace": "mycroft.system.active_skills", @@ -170,7 +173,7 @@ def remove(self, position: int): any session data. @param position: position to remove this namespace FROM """ - LOG.info(f"Removing {self.name} from active GUI namespaces") + LOG.info(f"Removing {self.skill_id} from active GUI namespaces") # unload the data first before removing the namespace # use the keys of the data to unload the data @@ -198,11 +201,11 @@ def load_data(self, name: str, value: str): """ message = dict( type="mycroft.session.set", - namespace=self.name, + namespace=self.skill_id, data={name: value} ) - # LOG.info(f"Setting data {message} in GUI namespace {self.name}") + # LOG.info(f"Setting data {message} in GUI namespace {self.skill_id}") send_message_to_gui(message) def unload_data(self, name: str): @@ -213,9 +216,9 @@ def unload_data(self, name: str): message = dict( type="mycroft.session.delete", property=name, - namespace=self.name + namespace=self.skill_id ) - # LOG.info(f"Deleting data {message} from GUI namespace {self.name}") + # LOG.info(f"Deleting data {message} from GUI namespace {self.skill_id}") send_message_to_gui(message) def get_position_of_last_item_in_data(self) -> int: @@ -276,7 +279,7 @@ def load_pages(self, pages: List[GuiPage], show_index: int = 0): new_pages = list() for page in pages: - if page.url not in [p.url for p in self.pages]: + if page.id not in [p.id for p in self.pages]: new_pages.append(page) self.pages.extend(new_pages) @@ -288,26 +291,15 @@ def load_pages(self, pages: List[GuiPage], show_index: int = 0): def _add_pages(self, new_pages: List[GuiPage]): """ Adds one or more pages to the active page list. - @param new_pages: pages to add to the active page list """ - LOG.info(f"Adding pages to GUI namespace {self.name}: {new_pages}") - LOG.info(f"Current pages: {self.pages}") - # print the attributes of the new pages - for page in new_pages: - LOG.info(f"Page: {page.url}, {page.name}, {page.persistent}, " - f"{page.duration}") + LOG.debug(f"namespace {self.skill_id} current pages: {self.pages}") + LOG.debug(f"new_pages={new_pages}") # Find position of new page in self.pages position = self.pages.index(new_pages[0]) - - message = dict( - type="mycroft.gui.list.insert", - namespace=self.name, - position=position, - data=[dict(url=page.url) for page in new_pages] - ) - send_message_to_gui(message) + for client in GUIWebsocketHandler.clients: + client.send_gui_pages(new_pages, self.skill_id, position) def _activate_page(self, page: GuiPage): """ @@ -315,13 +307,13 @@ def _activate_page(self, page: GuiPage): @param page: the page that will gain focus """ - LOG.info(f"Activating page {page.name} in GUI namespace {self.name}") - LOG.info(f"Current pages from _activate_page: {self.pages}") + LOG.info(f"Activating page {page.name} in GUI namespace {self.skill_id}") + LOG.debug(f"Current pages from _activate_page: {self.pages}") # TODO: Simplify two loops into one (with unit test) # get the index of the page in the self.pages list page_index = 0 for i, p in enumerate(self.pages): - if p.url == page.url: + if p.id == page.id: page_index = i break @@ -341,7 +333,7 @@ def _activate_page(self, page: GuiPage): message = dict( type="mycroft.events.triggered", - namespace=self.name, + namespace=self.skill_id, event_name="page_gained_focus", data=dict(number=page_index) ) @@ -353,14 +345,14 @@ def remove_pages(self, positions: List[int]): @param positions: list of int page positions to remove """ - LOG.info(f"Removing pages from GUI namespace {self.name}: {positions}") + LOG.info(f"Removing pages from GUI namespace {self.skill_id}: {positions}") positions.sort(reverse=True) for position in positions: page = self.pages.pop(position) - LOG.info(f"Deleting {page} from GUI namespace {self.name}") + LOG.info(f"Deleting {page} from GUI namespace {self.skill_id}") message = dict( type="mycroft.gui.list.remove", - namespace=self.name, + namespace=self.skill_id, position=position, items_number=1 ) @@ -372,7 +364,7 @@ def page_gained_focus(self, page_number: int): @param page_number: the index of the page that will gain focus """ LOG.info( - f"Page {page_number} gained focus in GUI namespace {self.name}") + f"Page {page_number} gained focus in GUI namespace {self.skill_id}") self._activate_page(self.pages[page_number]) def page_update_interaction(self, page_number: int): @@ -382,7 +374,7 @@ def page_update_interaction(self, page_number: int): """ LOG.info(f"Page {page_number} update interaction in GUI namespace " - f"{self.name}") + f"{self.skill_id}") page = self.pages[page_number] if not page.persistent and page.duration > 0: @@ -454,13 +446,35 @@ class NamespaceManager: def __init__(self, core_bus: MessageBusClient): self.core_bus = core_bus self.gui_bus = create_gui_service(self) - self.loaded_namespaces = dict() - self.active_namespaces = list() - self.remove_namespace_timers = dict() + self.loaded_namespaces: Dict[str, Namespace] = dict() + self.active_namespaces: List[Namespace] = list() + self.remove_namespace_timers: Dict[str, Timer] = dict() self.idle_display_skill = _get_idle_display_config() self.active_extension = _get_active_gui_extension() + self._system_res_dir = join(dirname(__file__), "res", "gui") + self._ready_event = Event() + self.gui_file_server = None + self.gui_file_path = None + self._connected_frameworks: List[str] = list() + self._init_gui_server() self._define_message_handlers() + @property + def _active_homescreen(self) -> str: + return Configuration().get('gui', {}).get('idle_display_skill') + + def _init_gui_server(self): + """ + Initialize a GUI HTTP file server if enabled in configuration + """ + config = Configuration().get("gui", {}) + if config.get("gui_file_server", False): + from ovos_utils.file_utils import get_temp_path + self.gui_file_path = config.get("server_path") or \ + get_temp_path("ovos_gui_file_server") + self.gui_file_server = start_gui_http_server(self.gui_file_path) + self._upload_system_resources() + def _define_message_handlers(self): """ Defines event handlers for core messagebus. @@ -469,12 +483,78 @@ def _define_message_handlers(self): self.core_bus.on("gui.event.send", self.handle_send_event) self.core_bus.on("gui.page.delete", self.handle_delete_page) self.core_bus.on("gui.page.show", self.handle_show_page) + self.core_bus.on("gui.page.upload", self.handle_receive_gui_pages) self.core_bus.on("gui.status.request", self.handle_status_request) self.core_bus.on("gui.value.set", self.handle_set_value) self.core_bus.on("mycroft.gui.connected", self.handle_client_connected) self.core_bus.on("gui.page_interaction", self.handle_page_interaction) - self.core_bus.on("gui.page_gained_focus", - self.handle_page_gained_focus) + self.core_bus.on("gui.page_gained_focus", self.handle_page_gained_focus) + self.core_bus.on("mycroft.skills.trained", self.handle_ready) + + def handle_ready(self, message): + self._ready_event.set() + self.core_bus.on("gui.volunteer_page_upload", + self.handle_gui_pages_available) + + def handle_gui_pages_available(self, message: Message): + """ + Handle a skill or plugin advertising that it has GUI pages available to + upload. If there are connected clients, request pages for each connected + GUI framework. + @param message: `gui.volunteer_page_upload` message + """ + if not self.gui_file_path: + LOG.debug("No GUI file server running") + return + + for framework in self._connected_frameworks: + skill_id = message.data.get("skill_id") + self.core_bus.emit(message.reply("gui.request_page_upload", + {'skill_id': skill_id, + 'framework': framework}, + {"source": "gui", + "destination": ["skills", + "PHAL"]})) + + def handle_receive_gui_pages(self, message: Message): + """ + Handle GUI resources from a skill or plugin. Pages are written to + `self.server_path` which is accessible via a lightweight HTTP server and + may additionally be mounted to a host path/volume in container setups. + @param message: Message containing UI resource file contents and meta + message.data: + pages: dict page_filename to encoded bytes content; + paths are relative to the `framework` directory, so a page + for framework `all` could be `qt5/subdir/file.qml` and the + equivalent page for framework `qt5` would be + `subdir/file.qml` + framework: `all` if all GUI resources are included, else the + specific GUI framework (i.e. `qt5`, `qt6`) + __from: skill_id of module uploading GUI resources + """ + for page, contents in message.data["pages"].items(): + try: + if message.data.get("framework") == "all": + # All GUI resources are uploaded + resource_base_path = join(self.gui_file_path, + message.data['__from']) + else: + resource_base_path = join(self.gui_file_path, + message.data['__from'], + message.data.get('framework') or + "qt5") + byte_contents = bytes.fromhex(contents) + file_path = join(resource_base_path, page) + LOG.debug(f"writing UI file: {file_path}") + makedirs(dirname(file_path), exist_ok=True) + with open(file_path, 'wb+') as f: + f.write(byte_contents) + except Exception as e: + LOG.exception(f"Failed to write {page}: {e}") + if message.data["__from"] == self._active_homescreen: + # Configured home screen skill just uploaded pages, show it again + self.core_bus.emit( + message.forward("homescreen.manager.show_active")) def handle_clear_namespace(self, message: Message): """ @@ -532,50 +612,94 @@ def _remove_pages(self, namespace_name: str, pages_to_remove: List[str]): if namespace is not None and namespace in self.active_namespaces: page_positions = [] for index, page in enumerate(pages_to_remove): - # if page matches namespace.pages.url: - if page == namespace.pages[index].url: + if page == namespace.pages[index].id: page_positions.append(index) page_positions.sort(reverse=True) namespace.remove_pages(page_positions) + @staticmethod + def _parse_persistence(persistence: Optional[Union[int, bool]]) -> \ + (bool, int): + """ + Parse a persistence spec into persist and duration. + @param persistence: message.data["__idle"] spec + @return: bool persistence, int duration + """ + if isinstance(persistence, float): + persistence = round(persistence) + if isinstance(persistence, bool): + return persistence, 0 + elif isinstance(persistence, int): + if persistence < 0: + raise ValueError("Requested negative persistence") + return False, persistence + else: + # Defines default behavior as displaying for 30 seconds + return False, 30 + + def _legacy_show_page(self, message: Message) -> List[GuiPage]: + """ + Backwards-compat method to handle messages without ui_directories and + page_names. + @param message: message requesting to display pages + @return: list of GuiPage objects + """ + pages_to_show = message.data["page"] + LOG.info(f"Handling legacy page show request. pages={pages_to_show}") + + pages_to_load = list() + persist, duration = self._parse_persistence(message.data["__idle"]) + for page in pages_to_show: + name = page.split('/')[-1] + # check if persistence is type of int or bool + pages_to_load.append(GuiPage(page, name, persist, duration)) + return pages_to_load + def handle_show_page(self, message: Message): """ Handles a request to show one or more pages on the screen. @param message: the message containing the page show request """ message_is_valid = _validate_page_message(message) - if message_is_valid: - namespace_name = message.data["__from"] - pages_to_show = message.data["page"] - persistence = message.data["__idle"] - show_index = message.data.get("index", None) - - LOG.info(f"Handling page show request. pages={pages_to_show}") - - pages_to_load = list() - for page in pages_to_show: - name = page.split('/')[-1] - # check if persistence is type of int or bool - if isinstance(persistence, bool): - persist = persistence - duration = 0 - - # check if persistence is type of int - elif isinstance(persistence, int): - persist = False - duration = persistence + if not message_is_valid: + LOG.error(f"invalid request: {message.data}") + return - else: - persist = False - duration = 30 + namespace_name = message.data["__from"] + page_ids_to_show = message.data.get('page_names') + page_resource_dirs = message.data.get('ui_directories') + persistence = message.data["__idle"] + show_index = message.data.get("index", None) - pages_to_load.append(GuiPage(page, name, persist, duration)) + if not page_resource_dirs and page_ids_to_show and \ + all((x.startswith("SYSTEM") for x in page_ids_to_show)): + page_resource_dirs = {"all": self._system_res_dir} - with namespace_lock: - self._activate_namespace(namespace_name) - self._load_pages(pages_to_load, show_index) - self._update_namespace_persistence(persistence) + if not all((page_ids_to_show, page_resource_dirs)): + LOG.info(f"Handling legacy page request: data={message.data}") + pages = self._legacy_show_page(message) + else: + pages = list() + persist, duration = self._parse_persistence(message.data["__idle"]) + for page in page_ids_to_show: + url = None + name = page + if isfile(page): + LOG.warning(f"Expected resource name but got file: {url}") + name = page.split('/')[-1] + url = f"file://{page}" + elif "://" in page: + LOG.warning(f"Expected resource name but got URI: {page}") + name = page.split('/')[-1] + url = page + pages.append(GuiPage(url, name, persist, duration, + page, namespace_name, page_resource_dirs)) + + with namespace_lock: + self._activate_namespace(namespace_name) + self._load_pages(pages, show_index) + self._update_namespace_persistence(persistence) def _activate_namespace(self, namespace_name: str): """ @@ -584,7 +708,7 @@ def _activate_namespace(self, namespace_name: str): @param namespace_name: the name of the namespace to load """ namespace = self._ensure_namespace_exists(namespace_name) - LOG.info(f"Activating namespace: {namespace_name}") + LOG.debug(f"Activating namespace: {namespace_name}") if namespace in self.active_namespaces: namespace_position = self.active_namespaces.index(namespace) @@ -638,19 +762,19 @@ def _update_namespace_persistence(self, persistence: Union[bool, int]): for position, namespace in enumerate(self.active_namespaces): if position: if not namespace.persistent: - self._remove_namespace(namespace.name) + self._remove_namespace(namespace.skill_id) else: - if namespace.name == self.idle_display_skill: + if namespace.skill_id == self.idle_display_skill: namespace.set_persistence(skill_type="idleDisplaySkill") else: namespace.set_persistence(skill_type="genericSkill") # check if there is a scheduled remove_namespace_timer # and cancel it - if namespace.persistent and namespace.name in \ + if namespace.persistent and namespace.skill_id in \ self.remove_namespace_timers: - self.remove_namespace_timers[namespace.name].cancel() - self._del_namespace_in_remove_timers(namespace.name) + self.remove_namespace_timers[namespace.skill_id].cancel() + self._del_namespace_in_remove_timers(namespace.skill_id) if not namespace.persistent: LOG.info("It is being scheduled here") @@ -662,18 +786,18 @@ def _schedule_namespace_removal(self, namespace: Namespace): @param namespace: the namespace to be removed """ # Before removing check if there isn't already a timer for this namespace - if namespace.name in self.remove_namespace_timers: + if namespace.skill_id in self.remove_namespace_timers: return remove_namespace_timer = Timer( namespace.duration, self._remove_namespace_via_timer, - args=(namespace.name,) + args=(namespace.skill_id,) ) - LOG.debug(f"Scheduled removal of namespace {namespace.name} in " + LOG.debug(f"Scheduled removal of namespace {namespace.skill_id} in " f"duration {namespace.duration}") remove_namespace_timer.start() - self.remove_namespace_timers[namespace.name] = remove_namespace_timer + self.remove_namespace_timers[namespace.skill_id] = remove_namespace_timer def _remove_namespace_via_timer(self, namespace_name: str): """ @@ -695,10 +819,10 @@ def _remove_namespace(self, namespace_name: str): self.remove_namespace_timers[namespace_name].cancel() self._del_namespace_in_remove_timers(namespace_name) - namespace = self.loaded_namespaces.get(namespace_name) + namespace: Namespace = self.loaded_namespaces.get(namespace_name) if namespace is not None and namespace in self.active_namespaces: self.core_bus.emit(Message("gui.namespace.removed", - data={"skill_id": namespace.name})) + data={"skill_id": namespace.skill_id})) if self.active_extension == "Bigscreen": # TODO: Define callback or event instead of arbitrary sleep # wait for window management in bigscreen extension to finish @@ -715,7 +839,7 @@ def _emit_namespace_displayed_event(self): """ if self.active_namespaces: displaying_namespace = self.active_namespaces[0] - message_data = dict(skill_id=displaying_namespace.name) + message_data = dict(skill_id=displaying_namespace.skill_id) self.core_bus.emit( Message("gui.namespace.displayed", data=message_data) ) @@ -757,7 +881,7 @@ def _update_namespace_data(self, namespace_name: str, data: dict): for key, value in data.items(): if key not in RESERVED_KEYS and namespace.data.get(key) != value: LOG.debug( - f"Setting {key} to {value} in namespace {namespace.name}") + f"Setting {key} to {value} in namespace {namespace.skill_id}") namespace.data[key] = value if namespace in self.active_namespaces: namespace.load_data(key, value) @@ -767,9 +891,18 @@ def handle_client_connected(self, message: Message): Handles an event from the GUI indicating it is connected to the bus. @param message: the event sent by the GUI """ - # GUI has announced presence - # Announce connection, the GUI should connect on it soon + # old style GUI has announced presence in core bus + # send websocket port, the GUI should connect on it soon gui_id = message.data.get("gui_id") + + framework = message.data.get("framework") # new api + if framework is None: + qt = message.data.get("qt_version", 5) # mycroft-gui api + if int(qt) == 6: + framework = "qt6" + else: + framework = "qt5" + LOG.info(f"GUI with ID {gui_id} connected to core message bus") websocket_config = get_gui_websocket_config() port = websocket_config["base_port"] @@ -777,6 +910,18 @@ def handle_client_connected(self, message: Message): dict(port=port, gui_id=gui_id)) self.core_bus.emit(message) + if self.gui_file_path: + if not self._ready_event.wait(90): + LOG.warning("Not reported ready after 90s") + if framework not in self._connected_frameworks: + self.core_bus.emit(Message("gui.request_page_upload", + {'framework': framework}, + {"source": "gui", + "destination": ["skills", "PHAL"]})) + + if framework not in self._connected_frameworks: + self._connected_frameworks.append(framework) + def handle_page_interaction(self, message: Message): """ Handles an event from the GUI indicating a page has been interacted with. @@ -791,9 +936,9 @@ def handle_page_interaction(self, message: Message): else: namespace = self.loaded_namespaces.get(namespace_name) if not namespace.persistent: - if self.remove_namespace_timers[namespace.name]: - self.remove_namespace_timers[namespace.name].cancel() - self._del_namespace_in_remove_timers(namespace.name) + if self.remove_namespace_timers[namespace.skill_id]: + self.remove_namespace_timers[namespace.skill_id].cancel() + self._del_namespace_in_remove_timers(namespace.skill_id) self._schedule_namespace_removal(namespace) def handle_page_gained_focus(self, message: Message): @@ -818,7 +963,7 @@ def handle_namespace_global_back(self, message: Optional[Message]): Handles global back events from the GUI. @param message: the event sent by the GUI """ - namespace_name = self.active_namespaces[0].name + namespace_name = self.active_namespaces[0].skill_id namespace = self.loaded_namespaces.get(namespace_name) if namespace in self.active_namespaces: namespace.global_back() @@ -830,3 +975,14 @@ def _del_namespace_in_remove_timers(self, namespace_name: str): """ if namespace_name in self.remove_namespace_timers: del self.remove_namespace_timers[namespace_name] + + def _upload_system_resources(self): + """ + Copy system GUI resources to the served file path + """ + output_path = join(self.gui_file_path, "system") + if exists(output_path): + LOG.info(f"Removing existing system resources before updating") + shutil.rmtree(output_path) + shutil.copytree(self._system_res_dir, output_path) + LOG.debug(f"Copied system resources to {self.gui_file_path}") diff --git a/ovos_gui/page.py b/ovos_gui/page.py index 938ba18..8ac35a4 100644 --- a/ovos_gui/page.py +++ b/ovos_gui/page.py @@ -1,18 +1,84 @@ +from os.path import join, isfile, dirname +from typing import Union, Optional +from dataclasses import dataclass from ovos_utils.log import LOG +@dataclass class GuiPage: - def __init__(self, url: str, name: str, persistent: bool, duration: int): + """ + A GuiPage represents a single GUI Display within a given namespace. + A Page can either be `persistent` or be removed after some `duration`. + Note that a page is generally framework-independent + @param url: URI (local or network path) of the GUI Page + @param name: Name of the page as shown in its namespace (could + @param persistent: If True, page is displayed indefinitely + @param duration: Number of seconds to display the page for + @param namespace: Skill/component identifier + @param page_id: Page identifier + (file path relative to gui_framework directory with no extension) + """ + url: Optional[str] # This param is left for backwards-compat. + name: str + persistent: bool + duration: Union[int, bool] + page_id: Optional[str] = None + namespace: Optional[str] = None + resource_dirs: Optional[dict] = None + + active: bool = False + + @property + def id(self): + """ + Get a unique identifier for this page. + """ + return self.page_id or self.url + + @staticmethod + def get_file_extension(framework: str) -> str: """ - A GuiPage represents a single GUI Display within a given namespace. - A Page can either be `persistent` or be removed after some `duration`. - @param url: URI (local or network path) of the GUI Page - @param name: Name of the page as shown in its namespace - @param persistent: If True, page is displayed indefinitely - @param duration: Number of seconds to display the page for + Get a file extension for the specified GUI framework + @param framework: string framework to get file extension for + @return: string file extension (empty string if unknown) """ - self.url = url - self.name = name - self.persistent = persistent - self.duration = duration - self.active = False + if framework in ("qt5", "qt6"): + return "qml" + return "" + + def get_uri(self, framework: str = "qt5", server_url: str = None) -> str: + """ + Get a valid URI for this Page. + @param framework: String GUI framework to get resources for + @param server_url: String server URL if available + @return: Absolute path to the requested resource + """ + if self.url: + LOG.warning(f"Static URI: {self.url}") + return self.url + + res_filename = f"{self.page_id}.{self.get_file_extension(framework)}" + res_namespace = "system" if self.page_id.startswith("SYSTEM") else \ + self.namespace + if server_url: + if "://" not in server_url: + LOG.debug(f"No schema in server_url, assuming 'http'") + server_url = f"http://{server_url}" + path = f"{server_url}/{res_namespace}/{framework}/{res_filename}" + LOG.info(f"Resolved server URI: {path}") + return path + base_path = self.resource_dirs.get(framework) + if not base_path and self.resource_dirs.get("all"): + file_path = join(self.resource_dirs.get('all'), framework, + res_filename) + else: + file_path = join(base_path, res_filename) + if isfile(file_path): + return file_path + # Check system resources + file_path = join(dirname(__file__), "res", "gui", framework) + if isfile(file_path): + return file_path + raise FileNotFoundError(f"Unable to resolve resource file for " + f"resource {res_filename} for framework " + f"{framework}") diff --git a/ovos_gui/res/ui/FeatureRequest.qml b/ovos_gui/res/gui/qt5/FeatureRequest.qml similarity index 100% rename from ovos_gui/res/ui/FeatureRequest.qml rename to ovos_gui/res/gui/qt5/FeatureRequest.qml diff --git a/ovos_gui/res/ui/RequestHandler.qml b/ovos_gui/res/gui/qt5/RequestHandler.qml similarity index 100% rename from ovos_gui/res/ui/RequestHandler.qml rename to ovos_gui/res/gui/qt5/RequestHandler.qml diff --git a/ovos_gui/res/ui/SYSTEM_AdditionalSettings.qml b/ovos_gui/res/gui/qt5/SYSTEM_AdditionalSettings.qml similarity index 100% rename from ovos_gui/res/ui/SYSTEM_AdditionalSettings.qml rename to ovos_gui/res/gui/qt5/SYSTEM_AdditionalSettings.qml diff --git a/ovos_gui/res/ui/SYSTEM_AnimatedImageFrame.qml b/ovos_gui/res/gui/qt5/SYSTEM_AnimatedImageFrame.qml similarity index 100% rename from ovos_gui/res/ui/SYSTEM_AnimatedImageFrame.qml rename to ovos_gui/res/gui/qt5/SYSTEM_AnimatedImageFrame.qml diff --git a/ovos_gui/res/ui/SYSTEM_HtmlFrame.qml b/ovos_gui/res/gui/qt5/SYSTEM_HtmlFrame.qml similarity index 100% rename from ovos_gui/res/ui/SYSTEM_HtmlFrame.qml rename to ovos_gui/res/gui/qt5/SYSTEM_HtmlFrame.qml diff --git a/ovos_gui/res/ui/SYSTEM_ImageFrame.qml b/ovos_gui/res/gui/qt5/SYSTEM_ImageFrame.qml similarity index 100% rename from ovos_gui/res/ui/SYSTEM_ImageFrame.qml rename to ovos_gui/res/gui/qt5/SYSTEM_ImageFrame.qml diff --git a/ovos_gui/res/ui/SYSTEM_TextFrame.qml b/ovos_gui/res/gui/qt5/SYSTEM_TextFrame.qml similarity index 100% rename from ovos_gui/res/ui/SYSTEM_TextFrame.qml rename to ovos_gui/res/gui/qt5/SYSTEM_TextFrame.qml diff --git a/ovos_gui/res/ui/SYSTEM_UrlFrame.qml b/ovos_gui/res/gui/qt5/SYSTEM_UrlFrame.qml similarity index 100% rename from ovos_gui/res/ui/SYSTEM_UrlFrame.qml rename to ovos_gui/res/gui/qt5/SYSTEM_UrlFrame.qml diff --git a/ovos_gui/res/ui/SwipeArea.qml b/ovos_gui/res/gui/qt5/SwipeArea.qml similarity index 100% rename from ovos_gui/res/ui/SwipeArea.qml rename to ovos_gui/res/gui/qt5/SwipeArea.qml diff --git a/ovos_gui/res/ui/WebViewHtmlFrame.qml b/ovos_gui/res/gui/qt5/WebViewHtmlFrame.qml similarity index 100% rename from ovos_gui/res/ui/WebViewHtmlFrame.qml rename to ovos_gui/res/gui/qt5/WebViewHtmlFrame.qml diff --git a/ovos_gui/res/ui/WebViewUrlFrame.qml b/ovos_gui/res/gui/qt5/WebViewUrlFrame.qml similarity index 100% rename from ovos_gui/res/ui/WebViewUrlFrame.qml rename to ovos_gui/res/gui/qt5/WebViewUrlFrame.qml diff --git a/ovos_gui/res/snd/clicked.wav b/ovos_gui/res/snd/clicked.wav deleted file mode 100644 index 91b55f6214c575c9796a890d10fa7a96586c5723..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15240 zcmXY&2Y6J)7RP7qZW2f#3894Es~}AQL8Xdh=TMc zNRD;zWn{iE*>fWN;O9O_CEFY(o z(#lb-S1T2_!BJinr~367+2?KMh;&uC(oH4HtLnCNQTOC6l_H(hLut$RhU%J>QU6F) zb(HV-qj2m^+9y{Ztx!Go_F6a4$*?N5&Dz{4sL|BjYEkp!!NBs?Sx7>d*R) zDggh0d<4(o&>XGun3E#|kh!b639sAekS4v*BM+9=JZ#0ko7wEZ*twnws(=u+F4_h zpo~M;8OSghokoP_r9eLeKKAz$nT{NbvDF-GHlAygid5sU+c&BZm!rmW?=uyyhA}=8 z`wqbeL;3xcDypV1ZxVL>kahjx^9izl9P*JtXCHRTvD9p?5?5$Xe# z0KF(R2z@$Yo9_6%FW-kS|0C}ALg!bo<;&^pT+OH(f}L2giT(-p7p_7 zO?6o+gSVQDcLAxRka0LVzOF7xEAGDv?e5rQ0D28Vwl>i0sEVO$Gc`vwP@f^oi;Oo? zMN~UgNA*!<)vL^J3_Yc0$O@S*+vKwNWVbw##d1>C$#t0|SL9ncBgYs&DiLa?+>n`! zEfcRgB~K$$1MuGvzjadi_%93p`S5E7I$V_6>bN`wR+=KqAbd0q|MXW!u+I(R$Pd0s zB43PpTOF1fYPVEk-iz3;3+ta@ZWVP2`ZtjI3i@5b_h-=YFg81e-pTSIxEh4+?bJc| zESJ)1sZ>+vnDZDcUWQK!YXltF_HB(hp8&nImLse6A;r~83Xbaw2fww03 zsunhX78=dq@jTaS$l6DhBF;*yG5BaCG`=Q2K7&Uuc)Wz}9iTIiShR866JLM8@6WLF zP*n?`#Hw!m?g>uD^Lv(xCx&y7rvSW*Kr>2B$4C3r>*|auujV7?N8B6EnhD&Wsmd@` zM$HRhwg}%VtEC|sE)x?skReCDLcX=Ci8`R_qE|rXp~F~gK8Ly6!NG6pybM%ZvHLY_ zR!l7h7kkw+YBMs=N7u3VYYuwsLH;$^aD+My-F*2Dx*Hh#89o04{wJdMkJ#i#wGUga z2me=yeOLZq&Svf}gVq9aV}E!x0^41%*F@x-r2fWdKS*QsCz$>hzwBV`4RVx`-|%Z+ zwG$kr5Ci4aGH|h!@wxb7D%cv0{k~yrt}3BcsdC6&NnON;kBEV5#NB1S?_u2v?6raK zM?m^b^}IU4ynnIBRrQoQPRuM(g`wM6?ZPkH_`V6co1wc?6<2>_yYuP|*40;ARG6B9 z?mvL%)!1?;HabeY9ERU~urLk(e#f;K-8W;a6=3yee6|RDtW%9xUmZV`SEpHb3_d6D z_d$I3H!=Pfbhn|?4&r7NG&T~0yZPLtuFCKDW(hvq3;%=o_b+U)iF>=qfjfzfovhh` zt@q)R3+Q$W`bqGK(WO+Zj#78Yk6W;A$AJFxEoL=Y ze!Rw<16+TT%Z`&zPNL5i;^}vFQnn(`QEYISc?Y0z3|W%NlV!D$M*6lC)BEMV+Qiy_ zu)zc5PLhMrxB<3a*FUIlb#qlhZ^mBJ$-Aqt*A`h$KG@B?GhkyIe9s|EqE1u^I+u0V zMPB_xoUSv&_au^Vv_n!rd5a11|f zMb_iYJI3!t>JTxo2VVcM_89W)B~Dk6TlRqOo7npv`XwV{3cgLi|K(LO;~T*GT>P<= z{beJ$==)Gy7FLJ&y$4LJK*r6CZ2%iT!TVQo)=GT81>Bre_0)CndJb9#vDI#_3*-dr z|1;!-)8vl*VCy7vui@kE$gmOqC)i{D0b85!^ETvPhg>VTERObse2^kX7(Wgk_P}=| zak`p#*nxj9;OEQmze{XAgvL!``UL9^K=&{>IfT4BiS-?PT8tjTcK6WZ3G^Nz!!@wH z9$)?podw`$F_>7u+C|XWfNneCbpXGvzz=iq)vwT51HCoSSkL^WjD3S#OPIGEEN>wf zZ6wC5FScX9?a̮w!Tm+-6+csFY=hrfcs!Q<&`&~+$JpdFW2?C)6Xy$&`}a_8%thZEV(20^ zIR$OMT*TMc$PI@>zP=rb-z z?jq*apx0J%^$}wJ8n(YeuKovk{=hCX(04I5-4ES!$Z!<9Z4BA*F*NRT&*CTxKRrY) z!LM=TA3>gnj9tOk=UJP^<;B+tb*V?W{7P0-jy4qT62 z_mkgtU^{Eiwcy}KeD()=9|SjN!R_B*WFGYAv3?Em%?Ag=(C>5XGMQ^8Jhm`@H+rlM z?Kii{?~mBKuFFXB$2e@Y1U#(UWd2h=O%;Nof;_L!p%P+$B`JinzL zkf{rh|Hk9<7l`e_=&*!%I0K!9*s?t}K{@uSs?h$D7-2T`*G_&fmg3m^Me4Cn@cT&e zMLX=*1KmdOy^;D%PE+S(ODWZz`1=UG`(mp%z)?@){xxF$1+`3~)h_W%4t2^+>X&QO z3(vx%D05dx5w$=x^Agy%TB(+*A9cpd*r+h`9PAg59U{>^C|TmlP3o;3asjTHQkGq* z89VnG>aaQTx$KgaNE={Qw)`z8{vuE|c+8bu;BLbzhcjlmjwOev}c=*iZF$Q?@YYxcm;4y^Ued*mN7MViWs;y0Jfa+4^Rj34e}@ZLnM-;9dz zq)e1gk#o2_&AI_pbGNYOEvkZxprnqf2@*b&7^xuZO|+~u?IcomBHu6a9_!lkZ&R5o zKTx4XU?n4|RHtX9hpdseWFIRl5DCr6j48-BNZLpPWH~9bK})^_E}85|0VlH;#;Q2)d`3<-?}eWx4F3%03GH z6<8%8tI_R{d@av2TABMF${nZ;kX#cf$IWDT-G%DUGK|p#*)CmVmXt@cSE=su_}vw$ z;?S(C9EQRb@T1ficn*@$QUb5O19Cp$ekXj~jQLIQ@L;g;EvTG>_uruY&o)b?G;`jQ zBT^FtMIpocvV^(MV9$;667n_%hcR-Ck;Bp)FLy)k6;$3)c=LOxJv8&B?EjyVw+s1B z>QHeHRXvb07IZGbCNIih6Lf!dGlECmf$ntE(mXMfOjjvG)XW7b&&pbvfbSBipr@%0 z#8olA52FT8QK!g^Yd~E~P}7{;P>PyhoeY%)Afdjrl%V;OXxImqNAlMSS|hRQN8tPo z^jZQwCgJIRG9Uc=>DYH(_{y9kc z4f(O98cYr?qsHUyfyj{|C5e@K>?zy8!#S$7$NnoK;J|cp|ZZi?x=VY>Vb@tO>Ysmw#;`Qn9}Yh)7R~(?wYl#9(Jf| z4oa*UD~sLU(##zuvs`1IbH%iFH%Nq8E4SPfi8d{zgS*iz42DabdrR)PYt=Bb)4dmH z8vNA%eQ>-#$@qfv^sDSjW6i6&n;9)5g56B-z?NV!f5YI8{Mo@J`M2D<{=xEmFk77p zcF|*l1I&Z`^5z%c(BRs<*8VqgB7&dhJ#gpek2gc|ub9956Wjy7#(_<_$^N~$W&IO! zx&&_K#>!3qYCYWzcb1xDwbN~>ue-Cn=Tu{_qozq8ccR-c;19OXe-Nmb-@#M}8uh94 zc8j@N{DJ%t{;&L{1E&Ig-R5p*_iguqn-e_kws$lA-}_bmPrg9jhrYLbGxJvZ5`8b_ zcg*`Ke^%bY;Hbbr+2Ia@@;v{DK!z{q`!Vo!;D&Cmdxc%_40h@{`>Fl?>a29S16%#A}P~lqTZN)2;sUJ5macsgTrK=YEwoGR1j>4aK zov?ZSoZ!pZ*ZrSnw9QXU@#YSBke*uV(a$NpQy-=8&bXg*D06InR(3-0LGA_V6zK20 zs%J-M6=<3;D5`d`7SXGUw~aZPcp@q>F}c8$g!W;Z;#R5--y%;$tylZrq zf@@+9Mcpa%VO;Mbf7R$;_m|dt+T?ee(rwk7t$QA<{BE7oQSqg&L}!%l=3P+uNO~Lp z<3_x3Dd!z&n|8;4JZX7$R^}h>Wb;&H8`HJm7N=75)TnjEDtp!zekvnZmws3{x6#A- z>3dUt$-0#Db8v}@h;Th7=DMmCcT&Av=zXIK?l(2VT7(C^PIyPBg?`i7;1n*f!YuVP z&Hcvb_3!lkV&ia8r(io%gOPxYql8 z!8Zf<{C%I%`tqCg1s-PXl3rNpdzY&$~6)%Cl3-tF=y?sv8#J zE$DqMJlXSQfv_+Y9nf>4Dy!)cT4i}#$pt+}Juu}|8NI<&bmGi9wJ$ipS%f~xdb-nJ zA8~4#)#42-^FJH>BG`&5Bwc3eT`JjW?nHYcbX97`LBZ|Lba$Y)yQ=Ihq6_K4^0|4- zd`$1-qW;1upxfz{s)4N2ht-!lSx+%l<2 zhtehgIo&Z(#(gKRwp%WDh3T8yQ2*g;6fsFUc>fNLHzw~Jw`AVB@F?{M=q#(=_0ednCV@e%+1od?@SnT=#^U?Cy8ED--^QXGOu> zuwqVSvo7#&ZfEsXV4QQ`j4+=Eo6Cd17=6kdaub7d{2g<9b z(!=Fc@IC)>H!J@Si{mxLi;H-29OJZQP`PkppnJg6|p7Yj@ zXy$bBHc`Did))?}5oWGVcTefMZYSrSsU-1%!@XQS5E|R|?G1(J{}4FN`i7{#0b~u#(~Jb!AUYw~@DlJ0ZfOJ`LY)Iy?XR zpI0CHzjN>8^$HHmdE|bO+dTM2PG|qstYLxvIWx>eUwyULH&5>7eXqvkx6%UxOH~nU zH&Dt)T+_!R8ahwHXX=QEZO&}(TK$!?Rw{VUs#n8i>dM~VRhH9AZSqvoM?DF;pKfkC zy9NDU1V;PT1e1JogUx);29xt%bnEyUnc4Zr%_Dy=c{%W@@dkcTcLRMrE!`E)hwdxh zyT%umu8M|hCo8O`Q!Ok>UG|Pv-Mx`|yY~Y<+jB%+C3pPk>7{yjm408ZHJS1tcw5E< z>q}nXq6ElpQv(s^X@6-`-=AU*`e(`Vz%ex<80M@B4tILG`#k65rl*TO>|}}YEL6XE zwyQh3p)_zx;ID-|X^%HiN}D8g-fULA%_jAYiPR}(nC>n$^%_%NT?)QwY6iNSRe_oE zd+=Sg(e0~7n>(t38LhUt9pz-OujB`fEOl3?L+%1~#9gJ@n2M^H*)CVy=`zzjB)8pq zYM)uGhDjBDU1savbRcW0wPv0>P)#*EJ(qRRr98vr7Fcr`)q{nV>(~Gqn|_a7`;gK)D3hCyutKL{!>3u z^>hT!0F!yz>5pW|`fca1zV1}z-Z^?fW6|1(*0oe+{hd0gTdAeGoBBY%pru|Px~>zYTRV?b6?BMprm1>PSKZPxSJ(6eQ~{?l6~9t%>QtGd^UMx0N$SJl<| zlBLGVO-`M>PIGI5EZy{OIjfgRVKU5*>UAP?oD6~YW!+5u#~G(?I6Gt> z@<-?|RR?F8dg!!~W4aj;c1dbF9%aBus;;C?P-!{N1BpkTYEBK+)fs{<&&lsPTGCWG zNmaK@Yn>sZz{6^%u4?V1n#DPA6xs(3K(0MTS?C=zQz!N+VEBzTg^(7LZOJB%IQ|Y<}IpmQ{ zBUeN_Gu2A{D%jtrZt0`yv0kTkp#LUi%z64b1&P>?oOu2XS7~&pCupypr{n0n^f$*$ zzUe1_n_K2%Iw*_CJ#VNl)ob+X4#-*6MHSLrIRAJ-ch*&OicV1T^cSkF?yF~#cZxfm z)ED??2VKhV^=n}CyxAj*=x|*k&Z;sxUGk+EPu(AyZ1b7%n-=t5KI8fLQ!3Cy^ihlR zeBOoZN?oLLRX_cbuHZD&?>q17!cH&U*ZEQn(i1sT{DeNmDCBLyQ*b-_eT(QE{YKsy zKn~Pc=TDVNSMmT))&sfstZK{?e>wU#;pEV(x}9^AbFE1FIWg)s{l}~7OU@{pagNnf z2`8|F^(nPM$LXWGE&5iXZxF-N`Z%8XYx8@8GO7mWZm%KnRg+;Jb4D7+>Cz#y!CW@4 z&~H0Qr1#RCe6n|B(i8ZB)8j(AA6>dlR7SfwLmf&MdzpUZC-iKGsG{V}G|oNOB6pPD zNRKs#UU{S*NrulSw&$zu^h}S@Q5z*5I#yTAHac{_(Ff}#4P_enc{+Q*W%?b9R4%7a zvFu!D=&${UPDUN_&S-j|oL-r?vG^V`*%x$-9-Bq<8tHh`$$o?+KX3v!9W5%-oBfWS zRv`(OdFD7hv%6%?#p)e;N6)f@7T|>ZF4V5#g(P|!S)BCjp!eC5UPe25Op$a)2GfU7 z^hIXS-};_D%#ZY7zCilF=$LF35B;Mf^r+6#eXC7>W+c6wTI_|h+4pMeD7^}aPtzlt zLKkl|nX(|eL1SrelIWytpy#wr>eBO^APeawZJ{4hkW-{SoH&&yyMB$l!`LZC(RnJx zNmm7SuTgYns$;>;?11lcT62e4r=+j6q;oVGPu9Y#d+0}|iE%U~zjJpy`{=rOIJ2RD^&>rvA|7PD&=q)!t`kFEf;>frBb zAoD!guoWlFuM@xTFm~2lk_gF_wsd`7z)$_5F@)}63{jVAa_CbAk^DY(xQ5R+h2{+A z$*(2+yV6HpFtPBs!%Q+mmF=%5uKQ#a@P%k02)RUd3zgQ!X-b9CUXn4xsjE}QAd zxKh0IY!yAU*>tW-;qle<(%ynsQRdt<(a_$AZm&{f97p~(Wajrc&B&qSSCLbhSDEjl zE45V4@KjnBTTSB)gemCzrrZMu1EIN&K3Hk!|BjBOkm*-CgjHF02YuSJOH>3GKS-vz zN>ttjCpJ0{(8~;fyjazVxSWb_d(t&5L?3)2eXHTvr8IV5#mQ7Fym$qh&5+yl0F&vI z2B@q!o2HXqmkdya6L8xxd_vE>C-$08FRvv%;$&m!Dz+nYY^E>zE4|WKa1*aK$lLT; z$0EbW;AA;j_g%V-Z8=eB$Vmt1DfCh2VxPC@eKsK4zr-h#=+%#c-&{$e9-9y9&T+pq zHv3(wlGCE(5nMB{(g}Qf8XB)qU!~JyokchPY2KC?hVLqZpC9NxzKxI95X;p;X9WKH zgx|k`2hP^f?lpOt9_e>64@z}eytZC572Nby3WB@*&yK&Ubu+$66wn(k|iRrAr&`sUZB_f4lyvC7+J|_ za0GpdW5`@u{lxix3K6)RwH=YK2YLsHW$F?67tdb=ZG}M0B`o_lxq=)h|G>WjtD553 z^K`hk!~Ygt;WPZ$m9xORtUbYQk%a6!q&26T?B&GN zeB%2$_N&XjS_E{C#ghYx$!u_Zhx3rhVBc+z(E8Oz6lzk!iPXzV4wtpvgUN*WeUBTi1!d+v|EY3z7&)oY;OTQJ^< zSXn0>IC;9y8%=H1Sl(HAnlr9=>`;vJk0|VS9eX{ZKF-8KkLi=U$iEAF4JF5{;f$yx zJJCbv?x(w6m{ap2(0&?Pjd;@{7Yx)zo~EiAS$jQFEQO8_OP3(4Kf@_lAKu}x8G0Ap z>^bDwsn}>KJObpE&UD^Oab7o{_IF%o(7P8+wAbRHE*+(Fz4)Lb(Z5keFK|UUa=US*YIh!^3?i#0B ztJv+nX1A}&i9#z*q;}$gw?J_d?3F~l(39xDMBHtqXWoY0c|PY3Rf(2t-l|y*x4qcz z23jv+=kI~0-PFfqogsMgW8UZK562c#iPNQ$`2Q&|!&^3RIEh4I=$#3|S|L#wdMzc= zt3zWMbx=QIEgJjU9)6H4I|Y5Wvd@*r_UDji7O}F6tiA(_{>AR0I2DZN1mQlBv=7Vd zWf!9z$Ud@GQ9HrMhu@lEq4h}rDm%p_*0Qg`ry~2~v*dxc>{S*6yV=D?;eq>PxfVQy z#Iuv#0Co3~FA5*mAqJjC<}OqiBdJ9a7`cOeQ?Xcm-tB6PPrpI`!DO3dczYLqyH1oO zfU_o?s~YAdBc})bQ;40&&}nHyXm;WpV;FDJP2w!t2TIzZ-BB#nhNucBLvI458RXVd zoY^MxwpeY(lgZHE69?(Mr7?mEDVY+nI%wU_$RwVh zEQ-q!qx;ajIXL>1x0f1`P3v~v66F)oa|5->0+4hKzvUor1uXD6JMMC_TU*Zd zHI>47Ruut371Ub%Q=b}SJ5kpMZQ@zEhq$ePB=3=7GvRUqM8Bsda0c|D8bWUP7rj<< z4&NTzod%hE!0yj@C?A}*B9Y{5+eZ>hsnD#8ZDKg1D?;o9@qZGzB%6IdKn`n& z?=Q0I&(Nv&22gO1s_HqAeU7=y$q_Zd+0)oDk1P<2&2O+XW`fyz#G1`YhtVz;jxS)V zQ`l-U*u4lnhg$A9ar!4!W)hk{1R+PjULmxrh|I@8EPFSetcMNT5C=8EM;CHd6?jBo z?bks-TQHP`rPi_XGPJIPh4nLPX zEDmkn&>_bN_IV1OBdG8%A;nfabr2lIz@;cz=@$2QpzlGvb%r&kh@4F5hGDyZvHME= zaF4%a=2%&-6El(c*Trvss;Qgo(kH0QZt<6d-Z|teAqStwR$H;?eXLiQn7D<^v+?U* zewPeo*vjngIiNP5_{hKyPvB98_2KLp_mJlVw%q}`DpM7YU>6UkvfGE`aoD0hx~Gtb z?HdKv+0#0Z(^En8-%u$|+}7Yd86l!#$!n23vpDQAUMjF$)(2Sgn2ef?w~DgA+{W{( z;FyW53j7$pH{u<#3cQ1u0Szzu)B-QO@q)Y_FzMr+)}7Eegr%*{*ZG~wd^Y=>EoF7h>|UsMh(M&j=hq0gg4iS2b=LC$piejY!ah1WwYcLp0@ zp~}lg?`%+hgN$(opV{|69%CIV*FH2k3C}D}(XXQSWybH2^^?#i6?9!ehoj85`Qj8h zC(&1W4BZ1E8$_XBQ~dcfxVP`cMxxtItm5LQSHNR4=D9>{atK*Zh@oWY-(&0w^iG12 zdtf0Qzh6VHt7O2t@J{2i5bv7%k@qCFxJ`v}A6y*e+huYaJs2F;m$LgBSbq|bMyj;f)X~@De44-xfYmChk!02VDWI(k#>k{Gp z1e@l8+&KJO85%Y4Z47lr7;qUmEm3?KBHJ;`4&c=AYOIAL3!3!Mdmp8@TMO3eE1@O z&GWfZk>@dT`=A}fCVp^|1#TW8*FAin&iypxy@&sk&@qpkk&kWt%*_kUtpV+l@GQYP zd#@6){R}p=K8j|Y3gIls9Gio4pzGq_V2F2l=ESo$I%J33knD*ep1%L@dSRjbR0)2K zq1yx=W#C&3T$N-jmbH=iAdc_xT;;)U6>JrQ9b?h0I5InY_hXF&?$u&`X>1f1@}b@D z@>t`rw<`9O$Dl0@41_T+f}QUP{z!+G!~Ro%`c?7#XZ7-P1+kHfy#KR%IAaN{v$>}N zv=jMleOH#>Mc@(3{1Tx!%0;HfAsm!}UJZ8Qs(hAWPEqET`akW8%(vA{BDxi)2VE9< zYz*7^Wx2|rO9|#%Us^s^=ThifnDs@VSA@AGxXN+AQYZ$aL+cZm8y~7yEPZPe!{tLq ztA8}|c-a9Jwk<#v5WyRh zYb2ks=okSVgN)AqdAR82qFV$s?6}q6Ad`p6#MZ45tPMj)Ydb&ww(A4P5MYjAf4grQ zaQ%frieh3#DUT7L&aa+hU&1?JIJhPOtiNcQOnaO1$kfrdYn=i=~-wRdSQ8;50C zZ}Cx{n6Un{HmM%cI}f|%;j8>m?kHjZlXS&=cz+tv_Iv92_q75QCff%|3g zVMVU0(6Cq8P%LJF1v@_retGb-H3*pM8LPpk)w3|)Be_@Z|8#4D{il=!oBLOvocwXR%5IhpJky@obi&Z zvGQ4)RA-HyZ+VtR?pWfa0OO^wTb+<>kBM8GoAR+k9vHBAFd-TiCpPz#;wsOYid>aL zxzO&L`Jvb<&6t(3IJ9idR}39Xprg%~HbyJLvl{VSfw7`oHZH8riOjcoz~*;b@0R5E z|9oO)d%{|qTeIxd!OCQVi>o%y;?{POW($|<(b5sRMuPib|16vx@GZcX{W+31=(#amC5x4`j%D} zV`l<0=ER0_bnWZEa$0mdt$1D~mb#$ecz!oklH{jSe<%WMZ>i=K8Q%4)g53 zmdQMOQexjm&JEFuK<+U3O6ch;gPkrrR7+^?3pH6dYwUAq41Dc(h3@wKOP5O1*1-=;cYb>1rmqI>2b!smEy3FPU1hQa& zUwKFqWM2)2aBb_(2-bSYgLcetd6_573_#V(UmP(VjSN;UZ-|GVyAfoEa8?D8N8oMe zx_k!VZ5YYt&j)YCuHkT5+V+2)Iw46suos#Im{$-Uw&Ey&S8XQwFPSNa0ssI2 diff --git a/test/unittests/mock_data/gui/qt5/test.qml b/test/unittests/mock_data/gui/qt5/test.qml new file mode 100644 index 0000000..75793eb --- /dev/null +++ b/test/unittests/mock_data/gui/qt5/test.qml @@ -0,0 +1 @@ +qt5 \ No newline at end of file diff --git a/test/unittests/mock_data/gui/qt6/six.qml b/test/unittests/mock_data/gui/qt6/six.qml new file mode 100644 index 0000000..e69de29 diff --git a/test/unittests/mock_data/gui/qt6/test.qml b/test/unittests/mock_data/gui/qt6/test.qml new file mode 100644 index 0000000..3a5476f --- /dev/null +++ b/test/unittests/mock_data/gui/qt6/test.qml @@ -0,0 +1 @@ +qt6 \ No newline at end of file diff --git a/test/unittests/test_bus.py b/test/unittests/test_bus.py index 0ebd682..862d8bd 100644 --- a/test/unittests/test_bus.py +++ b/test/unittests/test_bus.py @@ -1,6 +1,8 @@ import unittest from unittest.mock import patch, Mock +import ovos_gui.bus + class TestBus(unittest.TestCase): @patch("ovos_gui.bus.Configuration") @@ -17,9 +19,19 @@ def test_get_gui_websocket_config(self, configuration): with self.assertRaises(KeyError): get_gui_websocket_config() - def test_create_gui_service(self): + @patch("ovos_gui.bus.Application.listen") + @patch("ovos_gui.bus.create_daemon") + @patch("ovos_gui.bus.ioloop") + def test_create_gui_service(self, ioloop, create_daemon, listen): from ovos_gui.bus import create_gui_service - # TODO + ioloop_instance = Mock() + ioloop.IOLoop.instance.return_value = ioloop_instance + mock_nsmanager = Mock() + application = create_gui_service(mock_nsmanager) + create_daemon.assert_called_once_with(ioloop_instance.start) + listen.assert_called_once() + self.assertEqual(application.settings.get("namespace_manager"), + mock_nsmanager) @patch("ovos_gui.bus.GUIWebsocketHandler") def test_send_message_to_gui(self, handler): @@ -41,5 +53,114 @@ def test_determine_if_gui_connected(self, handler): class TestGUIWebsocketHandler(unittest.TestCase): - from ovos_gui.bus import GUIWebsocketHandler - # TODO + mock_nsmanager = Mock() + + class WebSocketMock: + def __init__(self, *args, **kwargs): + ns_manager = TestGUIWebsocketHandler.mock_nsmanager + application_mock = Mock() + application_mock.settings = {"namespace_manager": ns_manager} + self.application = application_mock + + @classmethod + def setUpClass(cls): + from ovos_gui.bus import GUIWebsocketHandler + ovos_gui.bus.WebSocketHandler = cls.WebSocketMock + cls.handler = GUIWebsocketHandler() + + def test_00_websocket_init(self): + self.assertEqual(self.handler.framework, "qt5") + self.assertEqual(self.handler.ns_manager, self.mock_nsmanager) + + def test_on_open(self): + # TODO + pass + + def test_on_close(self): + # TODO + pass + + def test_get_client_pages(self): + from ovos_gui.namespace import Namespace + test_namespace = Namespace("test") + page_1 = Mock() + page_1.get_uri.return_value = "page_1_uri" + page_2 = Mock() + page_2.get_uri.return_value = "page_2_uri" + test_namespace.pages = [page_1, page_2] + + # Test no server_url + self.handler.ns_manager.gui_file_server = None + pages = self.handler.get_client_pages(test_namespace) + page_1.get_uri.assert_called_once_with(self.handler.framework, None) + page_2.get_uri.assert_called_once_with(self.handler.framework, None) + self.assertEqual(pages, ["page_1_uri", "page_2_uri"]) + + # Test with server_url + self.handler.ns_manager.gui_file_server = Mock() + self.handler.ns_manager.gui_file_server.url = "server_url" + pages = self.handler.get_client_pages(test_namespace) + page_1.get_uri.assert_called_with(self.handler.framework, "server_url") + page_2.get_uri.assert_called_with(self.handler.framework, "server_url") + self.assertEqual(pages, ["page_1_uri", "page_2_uri"]) + + def test_synchronize(self): + # TODO + pass + + def test_on_message(self): + # TODO + pass + + def test_write_message(self): + # TODO + pass + + def test_send_gui_pages(self): + real_send = self.handler.send + self.handler.send = Mock() + test_ns = "test_namespace" + test_pos = 0 + + from ovos_gui.page import GuiPage + page_1 = GuiPage(None, "", False, False) + page_1.get_uri = Mock(return_value="page_1") + + page_2 = GuiPage(None, "", False, False) + page_2.get_uri = Mock(return_value="page_2") + + # Test no server_url + self.handler.ns_manager.gui_file_server = None + self.handler._framework = "qt5" + self.handler.send_gui_pages([page_1, page_2], test_ns, test_pos) + page_1.get_uri.assert_called_once_with("qt5", None) + page_2.get_uri.assert_called_once_with("qt5", None) + self.handler.send.assert_called_once_with( + {"type": "mycroft.gui.list.insert", + "namespace": test_ns, + "position": test_pos, + "data": [{"url": "page_1"}, {"url": "page_2"}]}) + + # Test with server_url + self.handler.ns_manager.gui_file_server = Mock() + self.handler.ns_manager.gui_file_server.url = "server_url" + self.handler._framework = "qt6" + test_pos = 3 + self.handler.send_gui_pages([page_2, page_1], test_ns, test_pos) + page_1.get_uri.assert_called_with("qt6", "server_url") + page_2.get_uri.assert_called_with("qt6", "server_url") + self.handler.send.assert_called_with( + {"type": "mycroft.gui.list.insert", + "namespace": test_ns, + "position": test_pos, + "data": [{"url": "page_2"}, {"url": "page_1"}]}) + + self.handler.send = real_send + + def test_send(self): + # TODO + pass + + def test_check_origin(self): + self.assertTrue(self.handler.check_origin("test")) + self.assertTrue(self.handler.check_origin("")) diff --git a/test/unittests/test_gui_file_server.py b/test/unittests/test_gui_file_server.py new file mode 100644 index 0000000..bfaf81b --- /dev/null +++ b/test/unittests/test_gui_file_server.py @@ -0,0 +1,15 @@ +import unittest + + +class TestGuiFileServer(unittest.TestCase): + def test_gui_file_handler(self): + from ovos_gui.gui_file_server import GuiFileHandler + # TODO + + def test_start_gui_http_server(self): + from ovos_gui.gui_file_server import start_gui_http_server + # TODO + + def test_initialize_http_server(self): + from ovos_gui.gui_file_server import _initialize_http_server + # TODO diff --git a/test/unittests/test_namespace.py b/test/unittests/test_namespace.py index 2d016a8..cdd08f3 100644 --- a/test/unittests/test_namespace.py +++ b/test/unittests/test_namespace.py @@ -13,9 +13,11 @@ # limitations under the License. # """Tests for the GUI namespace helper class.""" - +from os import makedirs +from shutil import rmtree from unittest import TestCase, mock - +from unittest.mock import Mock +from os.path import join, dirname, isdir, isfile from ovos_bus_client.message import Message from ovos_utils.messagebus import FakeBus from ovos_gui.page import GuiPage @@ -114,7 +116,8 @@ def test_set_persistence_boolean(self): self.assertTrue(self.namespace.persistent) def test_load_pages_new(self): - self.namespace.pages = [GuiPage("foo", "foo.qml", True, 0), GuiPage("bar", "bar.qml", False, 30)] + self.namespace.pages = [GuiPage("foo", "foo.qml", True, 0), + GuiPage("bar", "bar.qml", False, 30)] new_pages = [GuiPage("foobar", "foobar.qml", False, 30)] load_page_message = dict( type="mycroft.events.triggered", @@ -130,7 +133,8 @@ def test_load_pages_new(self): self.assertListEqual(self.namespace.pages, self.namespace.pages) def test_load_pages_existing(self): - self.namespace.pages = [GuiPage("foo", "foo.qml", True, 0), GuiPage("bar", "bar.qml", False, 30)] + self.namespace.pages = [GuiPage("foo", "foo.qml", True, 0), + GuiPage("bar", "bar.qml", False, 30)] new_pages = [GuiPage("foo", "foo.qml", True, 0)] load_page_message = dict( type="mycroft.events.triggered", @@ -198,6 +202,27 @@ def setUp(self): with mock.patch(PATCH_MODULE + ".create_gui_service"): self.namespace_manager = NamespaceManager(FakeBus()) + def test_init_gui_server(self): + # TODO + pass + + def test_handle_ready(self): + self.assertEqual(len(self.namespace_manager.core_bus.ee. + listeners("gui.volunteer_page_upload")), 0) + self.assertFalse(self.namespace_manager._ready_event.is_set()) + self.namespace_manager.handle_ready(Message("")) + self.assertTrue(self.namespace_manager._ready_event.wait(0.01)) + self.assertEqual(len(self.namespace_manager.core_bus.ee. + listeners("gui.volunteer_page_upload")), 1) + + def test_handle_gui_pages_available(self): + # TODO + pass + + def test_handle_receive_gui_pages(self): + # TODO + pass + def test_handle_clear_namespace_active(self): namespace = Namespace("foo") namespace.remove = mock.Mock() @@ -257,20 +282,94 @@ def test_handle_remove_pages(self): # TODO pass - def test_handle_show_page(self): - message_data = {"__from": "foo", "__idle": 10, "page": ["bar"]} - message = Message("gui.page.show", data=message_data) - patch_function = PATCH_MODULE + ".send_message_to_gui" - with mock.patch(patch_function): - self.namespace_manager._schedule_namespace_removal = mock.Mock() - self.namespace_manager.handle_show_page(message) + def test_parse_persistence(self): + self.assertEqual(self.namespace_manager._parse_persistence(True), + (True, 0)) + self.assertEqual(self.namespace_manager._parse_persistence(False), + (False, 0)) + self.assertEqual(self.namespace_manager._parse_persistence(None), + (False, 30)) + self.assertEqual(self.namespace_manager._parse_persistence(10), + (False, 10)) + self.assertEqual(self.namespace_manager._parse_persistence(1.0), + (False, 1)) + with self.assertRaises(ValueError): + self.namespace_manager._parse_persistence(-10) + + def test_legacy_show_page(self): + message = Message("gui.page.show", data={"__from": "foo", + "__idle": 10, + "page": ["bar", "test/baz"]}) + pages = self.namespace_manager._legacy_show_page(message) + self.assertEqual(pages, [GuiPage('bar', 'bar', False, 10), + GuiPage('test/baz', 'baz', False, 10)]) - self.assertEqual( - "foo", self.namespace_manager.active_namespaces[0].name - ) - self.assertTrue("foo" in self.namespace_manager.loaded_namespaces) - namespace = self.namespace_manager.loaded_namespaces["foo"] - self.assertListEqual(namespace.pages, namespace.pages) + def test_handle_show_page(self): + real_legacy_show_page = self.namespace_manager._legacy_show_page + real_activate_namespace = self.namespace_manager._activate_namespace + real_load_pages = self.namespace_manager._load_pages + real_update_persistence = self.namespace_manager._update_namespace_persistence + self.namespace_manager._legacy_show_page = Mock(return_value=["pages"]) + self.namespace_manager._activate_namespace = Mock() + self.namespace_manager._load_pages = Mock() + self.namespace_manager._update_namespace_persistence = Mock() + + # Legacy message + message = Message("gui.page.show", data={"__from": "foo", + "__idle": 10, + "page": ["bar", "test/baz"]}) + self.namespace_manager.handle_show_page(message) + self.namespace_manager._legacy_show_page.assert_called_once_with(message) + self.namespace_manager._activate_namespace.assert_called_with("foo") + self.namespace_manager._load_pages.assert_called_with(["pages"], None) + self.namespace_manager._update_namespace_persistence.\ + assert_called_with(10) + + # With resource info + ui_directories = {"gui": "/tmp/test"} + message = Message("test", {"__from": "skill", + "__idle": False, + "index": 1, + "page": ["/gui/page_1", "/gui/test/page_2"], + "page_names": ["page_1", "test/page_2"], + "ui_directories": ui_directories}) + self.namespace_manager.handle_show_page(message) + expected_page1 = GuiPage(None, "page_1", False, 0, "page_1", "skill", + ui_directories) + expected_page2 = GuiPage(None, "test/page_2", False, 0, "test/page_2", + "skill", ui_directories) + self.namespace_manager._legacy_show_page.assert_called_once() + self.namespace_manager._activate_namespace.assert_called_with("skill") + self.namespace_manager._load_pages.assert_called_with([expected_page1, + expected_page2], + 1) + self.namespace_manager._update_namespace_persistence.\ + assert_called_with(False) + + # System resources + message = Message("test", {"__from": "skill_no_res", + "__idle": True, + "index": 2, + "page": ["/gui/SYSTEM_TextFrame.qml"], + "page_names": ["SYSTEM_TextFrame"]}) + self.namespace_manager.handle_show_page(message) + expected_page = GuiPage(None, "SYSTEM_TextFrame", True, 0, + "SYSTEM_TextFrame", "skill_no_res", + {"all": self.namespace_manager._system_res_dir}) + self.namespace_manager._legacy_show_page.assert_called_once() + self.namespace_manager._activate_namespace.assert_called_with( + "skill_no_res") + self.namespace_manager._load_pages.assert_called_with([expected_page], + 2) + self.namespace_manager._update_namespace_persistence.\ + assert_called_with(True) + # TODO: Test page_names with files and URIs + + self.namespace_manager._legacy_show_page = real_legacy_show_page + self.namespace_manager._activate_namespace = real_activate_namespace + self.namespace_manager._load_pages = real_load_pages + self.namespace_manager._update_namespace_persistence = \ + real_update_persistence def test_handle_show_page_invalid_message(self): namespace = Namespace("foo") @@ -348,3 +447,18 @@ def test_handle_namespace_global_back(self): def test_del_namespace_in_remove_timers(self): # TODO pass + + def test_upload_system_resources(self): + test_dir = join(dirname(__file__), "upload_test") + makedirs(test_dir, exist_ok=True) + self.namespace_manager.gui_file_path = test_dir + self.namespace_manager._upload_system_resources() + self.assertTrue(isdir(join(test_dir, "system", "qt5"))) + self.assertTrue(isfile(join(test_dir, "system", "qt5", + "SYSTEM_TextFrame.qml"))) + # Test repeated copy doesn't raise any exception + self.namespace_manager._upload_system_resources() + self.assertTrue(isdir(join(test_dir, "system", "qt5"))) + self.assertTrue(isfile(join(test_dir, "system", "qt5", + "SYSTEM_TextFrame.qml"))) + rmtree(test_dir) diff --git a/test/unittests/test_page.py b/test/unittests/test_page.py index 35d88b6..12624de 100644 --- a/test/unittests/test_page.py +++ b/test/unittests/test_page.py @@ -1,9 +1,10 @@ import unittest +from os.path import join, dirname, isfile +from ovos_gui.page import GuiPage class TestGuiPage(unittest.TestCase): - def test_gui_page(self): - from ovos_gui.page import GuiPage + def test_gui_page_legacy(self): uri = __file__ name = "test" persistent = True @@ -14,3 +15,56 @@ def test_gui_page(self): self.assertEqual(page.persistent, persistent) self.assertEqual(page.duration, 0) self.assertFalse(page.active) + self.assertEqual(page.id, page.url) + self.assertEqual(page.get_uri(), page.url) + self.assertEqual(page.get_uri("qt6", "http://0.0.0.0:80"), page.url) + self.assertEqual(page.get_uri("qt6", "/var/www/app"), page.url) + + def test_gui_page_from_server(self): + name = "test_page" + persistent = False + duration = 60 + page_id = "test_page" + namespace = "skill.test" + + page = GuiPage(None, name, persistent, duration, page_id, namespace) + qt5 = page.get_uri(server_url="localhost:80") + self.assertEqual(qt5, + f"http://localhost:80/{namespace}/qt5/{page_id}.qml") + + qt6 = page.get_uri(server_url="https://files.local") + self.assertEqual(qt6, + f"https://files.local/{namespace}/qt5/{page_id}.qml") + + def test_gui_page_from_local_path(self): + name = "test" + persistent = True + duration = True + page_id = "test" + namespace = "skill.test" + res_dirs = {"all": join(dirname(__file__), "mock_data", "gui")} + # Modern GUI File organization + page = GuiPage(None, name, persistent, duration, page_id, namespace, + res_dirs) + qt5 = page.get_uri("qt5") + qt6 = page.get_uri("qt6") + self.assertTrue(isfile(qt5)) + self.assertTrue(isfile(qt6)) + + qt6_only_name = "six" + qt6_page = GuiPage(None, qt6_only_name, persistent, duration, + qt6_only_name, namespace, res_dirs) + with self.assertRaises(FileNotFoundError): + qt6_page.get_uri("qt5") + qt6 = qt6_page.get_uri("qt6") + self.assertTrue(isfile(qt6)) + + # Legacy GUI File organization + res_dirs = {"qt5": join(dirname(__file__), "mock_data", "gui", "qt5"), + "qt6": join(dirname(__file__), "mock_data", "gui", "qt6")} + page = GuiPage(None, name, persistent, duration, page_id, namespace, + res_dirs) + qt5 = page.get_uri("qt5") + qt6 = page.get_uri("qt6") + self.assertTrue(isfile(qt5)) + self.assertTrue(isfile(qt6)) From d65cf2aea6bb435a862a10f52d7e14424a404414 Mon Sep 17 00:00:00 2001 From: JarbasAl Date: Sat, 8 Jul 2023 00:06:33 +0000 Subject: [PATCH 17/26] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_gui/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eecdc83..12a2d0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a6...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a7...HEAD) + +**Implemented enhancements:** + +- GUI File Server and Alternate GUI Framework Support [\#9](https://github.com/OpenVoiceOS/ovos-gui/pull/9) ([JarbasAl](https://github.com/JarbasAl)) + +## [V0.0.3a7](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a7) (2023-07-04) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a6...V0.0.3a7) **Merged pull requests:** diff --git a/ovos_gui/version.py b/ovos_gui/version.py index c756809..d2c3011 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 7 +VERSION_ALPHA = 8 # END_VERSION_BLOCK From 0aba6662e1121b87c050fe40349987dc22c751f2 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Wed, 19 Jul 2023 13:23:55 -0700 Subject: [PATCH 18/26] Fix local system resource resolution (#20) * Add logging to troubleshoot resource resolution * Add logging to troubleshoot missing GUI display * Fix typo in local system GUI page resolution with unit test --- ovos_gui/bus.py | 1 + ovos_gui/namespace.py | 7 ++++++- ovos_gui/page.py | 3 ++- test/unittests/test_page.py | 6 ++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ovos_gui/bus.py b/ovos_gui/bus.py index 9604547..4450a4e 100644 --- a/ovos_gui/bus.py +++ b/ovos_gui/bus.py @@ -270,6 +270,7 @@ def send_gui_pages(self, pages: List[GuiPage], namespace: str, "data": [{"url": page.get_uri(framework, server_url)} for page in pages] } + LOG.debug(f"Showing pages: {message['data']}") self.send(message) def send(self, data: dict): diff --git a/ovos_gui/namespace.py b/ovos_gui/namespace.py index 8215297..54bff59 100644 --- a/ovos_gui/namespace.py +++ b/ovos_gui/namespace.py @@ -299,7 +299,11 @@ def _add_pages(self, new_pages: List[GuiPage]): # Find position of new page in self.pages position = self.pages.index(new_pages[0]) for client in GUIWebsocketHandler.clients: - client.send_gui_pages(new_pages, self.skill_id, position) + try: + LOG.debug(f"Updating {client.framework} client") + client.send_gui_pages(new_pages, self.skill_id, position) + except Exception as e: + LOG.exception(f"Error updating {client.framework} client: {e}") def _activate_page(self, page: GuiPage): """ @@ -507,6 +511,7 @@ def handle_gui_pages_available(self, message: Message): LOG.debug("No GUI file server running") return + LOG.debug(f"Requesting resources for {self._connected_frameworks}") for framework in self._connected_frameworks: skill_id = message.data.get("skill_id") self.core_bus.emit(message.reply("gui.request_page_upload", diff --git a/ovos_gui/page.py b/ovos_gui/page.py index 8ac35a4..9ec77ce 100644 --- a/ovos_gui/page.py +++ b/ovos_gui/page.py @@ -76,7 +76,8 @@ def get_uri(self, framework: str = "qt5", server_url: str = None) -> str: if isfile(file_path): return file_path # Check system resources - file_path = join(dirname(__file__), "res", "gui", framework) + file_path = join(dirname(__file__), "res", "gui", framework, + res_filename) if isfile(file_path): return file_path raise FileNotFoundError(f"Unable to resolve resource file for " diff --git a/test/unittests/test_page.py b/test/unittests/test_page.py index 12624de..366c923 100644 --- a/test/unittests/test_page.py +++ b/test/unittests/test_page.py @@ -59,6 +59,12 @@ def test_gui_page_from_local_path(self): qt6 = qt6_page.get_uri("qt6") self.assertTrue(isfile(qt6)) + # System page + system_page = GuiPage(None, "SYSTEM_ImageFrame", False, 30, + "SYSTEM_ImageFrame", namespace, res_dirs) + qt5 = system_page.get_uri("qt5") + self.assertTrue(isfile(qt5)) + # Legacy GUI File organization res_dirs = {"qt5": join(dirname(__file__), "mock_data", "gui", "qt5"), "qt6": join(dirname(__file__), "mock_data", "gui", "qt6")} From 4e67ee9b28648b8894df5a8572f4866ebe50bca8 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Wed, 19 Jul 2023 20:24:51 +0000 Subject: [PATCH 19/26] Increment Version --- CHANGELOG.md | 10 +++++++++- ovos_gui/version.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12a2d0e..63fcbfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,15 @@ ## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a7...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a8...HEAD) + +**Merged pull requests:** + +- Fix local system resource resolution [\#20](https://github.com/OpenVoiceOS/ovos-gui/pull/20) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.3a8](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a8) (2023-07-08) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a7...V0.0.3a8) **Implemented enhancements:** diff --git a/ovos_gui/version.py b/ovos_gui/version.py index d2c3011..3b7847f 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 8 +VERSION_ALPHA = 9 # END_VERSION_BLOCK From c56adf29c0725913a49412fda28873ed3e23eed5 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Wed, 19 Jul 2023 18:39:46 -0700 Subject: [PATCH 20/26] Update automation to current standards (#21) * Update automation to current standards * Update to shared release action * Resolve relative setup.py path test failure * Update license tests to shared action --- .github/workflows/build_tests.yml | 36 ----------- .github/workflows/dev2master.yml | 19 ------ .github/workflows/license_tests.yml | 40 +----------- .github/workflows/propose_release.yml | 32 ++++++++++ .github/workflows/publish_alpha.yml | 69 ++++----------------- .github/workflows/publish_build.yml | 87 --------------------------- .github/workflows/publish_docker.yml | 46 -------------- .github/workflows/publish_major.yml | 87 --------------------------- .github/workflows/publish_minor.yml | 87 --------------------------- .github/workflows/publish_release.yml | 11 ++++ .github/workflows/unit_tests.yml | 9 ++- scripts/bump_alpha.py | 18 ------ scripts/bump_build.py | 21 ------- scripts/bump_major.py | 27 --------- scripts/bump_minor.py | 24 -------- scripts/remove_alpha.py | 13 ---- setup.py | 1 + 17 files changed, 67 insertions(+), 560 deletions(-) delete mode 100644 .github/workflows/build_tests.yml delete mode 100644 .github/workflows/dev2master.yml create mode 100644 .github/workflows/propose_release.yml delete mode 100644 .github/workflows/publish_build.yml delete mode 100644 .github/workflows/publish_docker.yml delete mode 100644 .github/workflows/publish_major.yml delete mode 100644 .github/workflows/publish_minor.yml create mode 100644 .github/workflows/publish_release.yml delete mode 100644 scripts/bump_alpha.py delete mode 100644 scripts/bump_build.py delete mode 100644 scripts/bump_major.py delete mode 100644 scripts/bump_minor.py delete mode 100644 scripts/remove_alpha.py diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml deleted file mode 100644 index f204bb7..0000000 --- a/.github/workflows/build_tests.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Run Build Tests -on: - push: - workflow_dispatch: - -jobs: - build_tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Install System Dependencies - run: | - sudo apt-get update - sudo apt install python3-dev swig libssl-dev libfann-dev portaudio19-dev libpulse-dev - - name: Build Source Packages - run: | - python setup.py sdist - - name: Build Distribution Packages - run: | - python setup.py bdist_wheel - - name: Install tflite_runtime workaround tflit bug - run: | - pip3 install numpy - pip3 install --extra-index-url https://google-coral.github.io/py-repo/ tflite_runtime - - name: Install core repo - run: | - pip install .[audio-backend,mark1,stt,tts,skills_minimal,skills,gui,bus,all] diff --git a/.github/workflows/dev2master.yml b/.github/workflows/dev2master.yml deleted file mode 100644 index e59e57e..0000000 --- a/.github/workflows/dev2master.yml +++ /dev/null @@ -1,19 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI - -name: Push dev -> master -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - ref: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master \ No newline at end of file diff --git a/.github/workflows/license_tests.yml b/.github/workflows/license_tests.yml index 29f4063..7d0c4f6 100644 --- a/.github/workflows/license_tests.yml +++ b/.github/workflows/license_tests.yml @@ -1,44 +1,10 @@ name: Run License Tests on: push: - branches: - - master + workflow_dispatch: pull_request: branches: - - dev - workflow_dispatch: - + - master jobs: license_tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Install System Dependencies - run: | - sudo apt-get update - sudo apt install python3-dev swig libssl-dev - - name: Install core repo - run: | - pip install . - - name: Get explicit and transitive dependencies - run: | - pip freeze > requirements-all.txt - - name: Check python - id: license_check_report - uses: pilosus/action-pip-license-checker@v0.5.0 - with: - requirements: 'requirements-all.txt' - fail: 'Copyleft,Other,Error' - fails-only: true - exclude: '^(tqdm).*' - exclude-license: '^(Mozilla).*$' - - name: Print report - if: ${{ always() }} - run: echo "${{ steps.license_check_report.outputs.report }}" \ No newline at end of file + uses: neongeckocom/.github/.github/workflows/license_tests.yml@master diff --git a/.github/workflows/propose_release.yml b/.github/workflows/propose_release.yml new file mode 100644 index 0000000..97f792f --- /dev/null +++ b/.github/workflows/propose_release.yml @@ -0,0 +1,32 @@ +name: Propose Stable Release +on: + workflow_dispatch: + inputs: + release_type: + type: choice + description: Release Type + options: + - build + - minor + - major +jobs: + update_version: + uses: neongeckocom/.github/.github/workflows/propose_semver_release.yml@master + with: + release_type: ${{ inputs.release_type }} + version_file: ovos_gui/version.py + alpha_var: VERSION_ALPHA + build_var: VERSION_BUILD + minor_var: VERSION_MINOR + major_var: VERSION_MAJOR + update_changelog: True + branch: dev + + pull_changes: + needs: update_version + uses: neongeckocom/.github/.github/workflows/pull_master.yml@master + with: + pr_assignee: ${{ github.actor }} + pr_draft: false + pr_title: ${{ needs.update_version.outputs.version }} + pr_body: ${{ needs.update_version.outputs.changelog }} diff --git a/.github/workflows/publish_alpha.yml b/.github/workflows/publish_alpha.yml index 58aff4d..da7eedf 100644 --- a/.github/workflows/publish_alpha.yml +++ b/.github/workflows/publish_alpha.yml @@ -1,5 +1,4 @@ # This workflow will generate a distribution and upload it to PyPI -# This will always use the current `dev` branch code name: Publish Alpha Build ...aX on: @@ -9,67 +8,25 @@ on: paths-ignore: - 'ovos_gui/version.py' - 'test/**' - - 'examples/**' - '.github/**' - '.gitignore' - 'LICENSE' - 'CHANGELOG.md' - 'MANIFEST.in' - - 'readme.md' + - 'README.md' - 'scripts/**' workflow_dispatch: jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Increment Version - run: | - VER=$(python setup.py --version) - python scripts/bump_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - maxIssues: 50 - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Increment Version - branch: dev - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} - body: | - Changes in this Release - ${{ steps.changelog.outputs.changelog }} - draft: false - prerelease: true - commitish: dev - - name: Build Distribution Packages - run: | - python setup.py bdist_wheel - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{secrets.PYPI_TOKEN}} + publish_alpha_release: + uses: neongeckocom/.github/.github/workflows/publish_alpha_release.yml@master + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + with: + version_file: "ovos_gui/version.py" + publish_prerelease: true + update_changelog: true + alpha_var: VERSION_ALPHA + build_var: VERSION_BUILD + minor_var: VERSION_MINOR + major_var: VERSION_MAJOR \ No newline at end of file diff --git a/.github/workflows/publish_build.yml b/.github/workflows/publish_build.yml deleted file mode 100644 index d5ec10f..0000000 --- a/.github/workflows/publish_build.yml +++ /dev/null @@ -1,87 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI -# This will always use the current `dev` branch code - -name: Publish Build Release ..X -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Remove alpha (declare stable) - run: | - VER=$(python setup.py --version) - python scripts/remove_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Declare alpha stable - branch: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master - force: true - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} - body: | - Changes in this Release - ${{ steps.changelog.outputs.changelog }} - draft: false - prerelease: false - commitish: dev - - name: Build Distribution Packages - run: | - python setup.py bdist_wheel - - name: Prepare next Build version - run: echo "::set-output name=version::$(python setup.py --version)" - id: alpha - - name: Increment Version ${{ steps.alpha.outputs.version }}Alpha0 - run: | - VER=$(python setup.py --version) - python scripts/bump_build.py - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Prepare Next Version - branch: dev - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{secrets.PYPI_TOKEN}} - - name: Send message to Matrix bots channel - id: matrix-chat-message - uses: fadenb/matrix-chat-message@v0.0.6 - with: - homeserver: 'matrix.org' - token: ${{ secrets.MATRIX_TOKEN }} - channel: '!WjxEKjjINpyBRPFgxl:krbel.duckdns.org' - message: | - New ovos-config release! ${{ steps.version.outputs.version }} diff --git a/.github/workflows/publish_docker.yml b/.github/workflows/publish_docker.yml deleted file mode 100644 index bd18490..0000000 --- a/.github/workflows/publish_docker.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Publish Docker Container -on: - push: - branches: - - master - - dev - workflow_dispatch: - -env: - REGISTRY: ghcr.io - IMAGE_NAME: OpenVoiceOS/gui_messagebus - -jobs: - build_and_publish_docker: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout repository - uses: actions/checkout@v2 - with: - ref: ${{ github.ref }} - - - name: Log in to the Container registry - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata for Docker - id: meta - uses: docker/metadata-action@v2 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=branch - - name: Build and push Docker image - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc - with: - context: . - file: Dockerfile - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/.github/workflows/publish_major.yml b/.github/workflows/publish_major.yml deleted file mode 100644 index 798b1ca..0000000 --- a/.github/workflows/publish_major.yml +++ /dev/null @@ -1,87 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI -# This will always use the current `dev` branch code and push it to `master` - -name: Publish Major Release X.0.0 -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Remove alpha (declare stable) - run: | - VER=$(python setup.py --version) - python scripts/remove_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Declare alpha stable - branch: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master - force: true - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} - body: | - Changes in this Release - ${{ steps.changelog.outputs.changelog }} - draft: false - prerelease: false - commitish: master - - name: Build Distribution Packages - run: | - python setup.py bdist_wheel - - name: Prepare next Major version - run: echo "::set-output name=version::$(python setup.py --version)" - id: alpha - - name: Increment Version ${{ steps.alpha.outputs.version }}Alpha0 - run: | - VER=$(python setup.py --version) - python scripts/bump_major.py - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Prepare Next Version - branch: dev - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{secrets.PYPI_TOKEN}} - - name: Send message to Matrix bots channel - id: matrix-chat-message - uses: fadenb/matrix-chat-message@v0.0.6 - with: - homeserver: 'matrix.org' - token: ${{ secrets.MATRIX_TOKEN }} - channel: '!WjxEKjjINpyBRPFgxl:krbel.duckdns.org' - message: | - New ovos-config release! ${{ steps.version.outputs.version }} diff --git a/.github/workflows/publish_minor.yml b/.github/workflows/publish_minor.yml deleted file mode 100644 index 189dfcb..0000000 --- a/.github/workflows/publish_minor.yml +++ /dev/null @@ -1,87 +0,0 @@ -# This workflow will generate a distribution and upload it to PyPI -# This will always use the current `dev` branch code and push it to `master` - -name: Publish Minor Release .X.0 -on: - workflow_dispatch: - -jobs: - build_and_publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - ref: dev - fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository. - - name: Setup Python - uses: actions/setup-python@v1 - with: - python-version: 3.8 - - name: Install Build Tools - run: | - python -m pip install build wheel - - name: Remove alpha (declare stable) - run: | - VER=$(python setup.py --version) - python scripts/remove_alpha.py - - name: "Generate release changelog" - uses: heinrichreimer/github-changelog-generator-action@v2.3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: changelog - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Declare alpha stable - branch: dev - - name: Push dev -> master - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: master - force: true - - name: version - run: echo "::set-output name=version::$(python setup.py --version)" - id: version - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token - with: - tag_name: V${{ steps.version.outputs.version }} - release_name: Release ${{ steps.version.outputs.version }} - body: | - Changes in this Release - ${{ steps.changelog.outputs.changelog }} - draft: false - prerelease: false - commitish: master - - name: Build Distribution Packages - run: | - python setup.py bdist_wheel - - name: Prepare next Minor version - run: echo "::set-output name=version::$(python setup.py --version)" - id: alpha - - name: Increment Version ${{ steps.alpha.outputs.version }}Alpha0 - run: | - VER=$(python setup.py --version) - python scripts/bump_minor.py - - name: Commit to dev - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: Prepare Next Version - branch: dev - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@master - with: - password: ${{secrets.PYPI_TOKEN}} - - name: Send message to Matrix bots channel - id: matrix-chat-message - uses: fadenb/matrix-chat-message@v0.0.6 - with: - homeserver: 'matrix.org' - token: ${{ secrets.MATRIX_TOKEN }} - channel: '!WjxEKjjINpyBRPFgxl:krbel.duckdns.org' - message: | - New ovos-config release! ${{ steps.version.outputs.version }} diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml new file mode 100644 index 0000000..185756a --- /dev/null +++ b/.github/workflows/publish_release.yml @@ -0,0 +1,11 @@ +name: Publish Release +on: + push: + branches: + - master + +jobs: + build_and_publish_pypi_and_release: + uses: neongeckocom/.github/.github/workflows/publish_stable_release.yml@master + secrets: + PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 73c5fb0..2ef845b 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -30,11 +30,15 @@ on: workflow_dispatch: jobs: + py_build_tests: + uses: neongeckocom/.github/.github/workflows/python_build_tests.yml@master + with: + python_version: "3.8" + unit_tests: strategy: - max-parallel: 2 matrix: - python-version: [ 3.7, 3.8, 3.9, '3.10' ] + python-version: [ 3.7, 3.8, 3.9, "3.10", "3.11" ] runs-on: ubuntu-latest timeout-minutes: 15 steps: @@ -61,6 +65,7 @@ jobs: # or they will overwrite previous invocations' coverage reports # (for an example, see OVOS Skill Manager's workflow) - name: Upload coverage + if: "${{ matrix.python-version == '3.9' }}" env: CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} uses: codecov/codecov-action@v2 diff --git a/scripts/bump_alpha.py b/scripts/bump_alpha.py deleted file mode 100644 index c251007..0000000 --- a/scripts/bump_alpha.py +++ /dev/null @@ -1,18 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_gui", "version.py") -version_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - else: - print(line.rstrip('\n')) diff --git a/scripts/bump_build.py b/scripts/bump_build.py deleted file mode 100644 index 0ce48b4..0000000 --- a/scripts/bump_build.py +++ /dev/null @@ -1,21 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_gui", "version.py") -version_var_name = "VERSION_BUILD" -alpha_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - elif line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) diff --git a/scripts/bump_major.py b/scripts/bump_major.py deleted file mode 100644 index 91c840a..0000000 --- a/scripts/bump_major.py +++ /dev/null @@ -1,27 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_gui", "version.py") -version_var_name = "VERSION_MAJOR" -minor_var_name = "VERSION_MINOR" -build_var_name = "VERSION_BUILD" -alpha_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - elif line.startswith(minor_var_name): - print(f"{minor_var_name} = 0") - elif line.startswith(build_var_name): - print(f"{build_var_name} = 0") - elif line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) diff --git a/scripts/bump_minor.py b/scripts/bump_minor.py deleted file mode 100644 index 86e6539..0000000 --- a/scripts/bump_minor.py +++ /dev/null @@ -1,24 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_gui", "version.py") -version_var_name = "VERSION_MINOR" -build_var_name = "VERSION_BUILD" -alpha_var_name = "VERSION_ALPHA" - -with open(version_file, "r", encoding="utf-8") as v: - for line in v.readlines(): - if line.startswith(version_var_name): - version = int(line.split("=")[-1]) - new_version = int(version) + 1 - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(version_var_name): - print(f"{version_var_name} = {new_version}") - elif line.startswith(build_var_name): - print(f"{build_var_name} = 0") - elif line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) diff --git a/scripts/remove_alpha.py b/scripts/remove_alpha.py deleted file mode 100644 index 1fcaccc..0000000 --- a/scripts/remove_alpha.py +++ /dev/null @@ -1,13 +0,0 @@ -import fileinput -from os.path import join, dirname - - -version_file = join(dirname(dirname(__file__)), "ovos_gui", "version.py") - -alpha_var_name = "VERSION_ALPHA" - -for line in fileinput.input(version_file, inplace=True): - if line.startswith(alpha_var_name): - print(f"{alpha_var_name} = 0") - else: - print(line.rstrip('\n')) diff --git a/setup.py b/setup.py index d500645..c4fb450 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ from setuptools import setup BASEDIR = os.path.abspath(os.path.dirname(__file__)) +os.chdir(BASEDIR) # For relative `packages` spec in setup below def required(requirements_file): From 07d6d6634f04aed6c423b65613f545d5a59a0644 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Thu, 20 Jul 2023 01:40:00 +0000 Subject: [PATCH 21/26] Increment Version to 0.0.3a10 --- ovos_gui/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 3b7847f..5ad6d9a 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 9 +VERSION_ALPHA = 10 # END_VERSION_BLOCK From 4bb96f7d86db92f481ef07e6cf6219559dab3186 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Thu, 20 Jul 2023 01:40:29 +0000 Subject: [PATCH 22/26] Update Changelog --- CHANGELOG.md | 85 +++++++--------------------------------------------- 1 file changed, 10 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63fcbfc..173c3d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,16 @@ # Changelog -## [Unreleased](https://github.com/OpenVoiceOS/ovos-gui/tree/HEAD) +## [0.0.3a10](https://github.com/OpenVoiceOS/ovos-gui/tree/0.0.3a10) (2023-07-20) -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a8...HEAD) +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a9...0.0.3a10) + +**Merged pull requests:** + +- Update automation to current standards [\#21](https://github.com/OpenVoiceOS/ovos-gui/pull/21) ([NeonDaniel](https://github.com/NeonDaniel)) + +## [V0.0.3a9](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.3a9) (2023-07-19) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a8...V0.0.3a9) **Merged pull requests:** @@ -68,79 +76,6 @@ [Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2...V0.0.3a1) -## [V0.0.2](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2) (2023-04-29) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a12...V0.0.2) - -## [V0.0.2a12](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a12) (2023-04-27) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a11...V0.0.2a12) - -**Implemented enhancements:** - -- feat/ovos-gui-debugger [\#7](https://github.com/OpenVoiceOS/ovos-gui/pull/7) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.2a11](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a11) (2023-04-27) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a10...V0.0.2a11) - -**Merged pull requests:** - -- Fix missing ovos-backend-client library [\#6](https://github.com/OpenVoiceOS/ovos-gui/pull/6) ([goldyfruit](https://github.com/goldyfruit)) - -## [V0.0.2a10](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a10) (2023-04-08) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a9...V0.0.2a10) - -**Merged pull requests:** - -- mycroft-bus-client -\> ovos-bus-client [\#5](https://github.com/OpenVoiceOS/ovos-gui/pull/5) ([JarbasAl](https://github.com/JarbasAl)) - -## [V0.0.2a9](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a9) (2023-04-05) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a8...V0.0.2a9) - -## [V0.0.2a8](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a8) (2023-04-05) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a7...V0.0.2a8) - -## [V0.0.2a7](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a7) (2023-04-05) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a6...V0.0.2a7) - -## [V0.0.2a6](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a6) (2023-04-05) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a5...V0.0.2a6) - -## [V0.0.2a5](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a5) (2023-04-05) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a4...V0.0.2a5) - -## [V0.0.2a4](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a4) (2023-04-04) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a3...V0.0.2a4) - -## [V0.0.2a3](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a3) (2023-04-04) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a2...V0.0.2a3) - -## [V0.0.2a2](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a2) (2023-04-04) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.2a1...V0.0.2a2) - -## [V0.0.2a1](https://github.com/OpenVoiceOS/ovos-gui/tree/V0.0.2a1) (2023-04-04) - -[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/df12af7ee5204fdf331a0694fc1dafa2a54e2a5a...V0.0.2a1) - -**Implemented enhancements:** - -- Feat/bump ovos utils [\#3](https://github.com/OpenVoiceOS/ovos-gui/pull/3) ([JarbasAl](https://github.com/JarbasAl)) -- refactor/move\_gui\_from\_core [\#1](https://github.com/OpenVoiceOS/ovos-gui/pull/1) ([JarbasAl](https://github.com/JarbasAl)) - -**Merged pull requests:** - -- Feat/bump ovos utils [\#4](https://github.com/OpenVoiceOS/ovos-gui/pull/4) ([JarbasAl](https://github.com/JarbasAl)) - \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* From 13926b3475613c588749f644755bc2bcb4779857 Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Wed, 19 Jul 2023 18:47:59 -0700 Subject: [PATCH 23/26] Add description to setup.py to fix #21 (#22) --- setup.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/setup.py b/setup.py index c4fb450..47eefc7 100644 --- a/setup.py +++ b/setup.py @@ -63,12 +63,20 @@ def package_files(directory): return paths +def get_description(): + with open(os.path.join(BASEDIR, "README.md"), "r") as f: + long_description = f.read() + return long_description + + setup( name='ovos-gui', version=get_version(), license='Apache-2.0', url='https://github.com/OpenVoiceOS/ovos-gui', description='ovos-core gui service daemon', + long_description=get_description(), + long_description_content_type="text/markdown", include_package_data=True, packages=["ovos_gui"], package_data={"": package_files('ovos_gui/res')}, From fdfce4e16a48ea31e1d48a19b0d4f9bbe7c5a90e Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Thu, 20 Jul 2023 01:48:16 +0000 Subject: [PATCH 24/26] Increment Version to 0.0.3a11 --- ovos_gui/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 5ad6d9a..10ab25c 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 10 +VERSION_ALPHA = 11 # END_VERSION_BLOCK From 5dc08beeefa04a75c089eac91a0643086425a262 Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Thu, 20 Jul 2023 01:48:39 +0000 Subject: [PATCH 25/26] Update Changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 173c3d2..6571ad8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.0.3a11](https://github.com/OpenVoiceOS/ovos-gui/tree/0.0.3a11) (2023-07-20) + +[Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/0.0.3a10...0.0.3a11) + +**Merged pull requests:** + +- Add description to setup.py to fix \#21 [\#22](https://github.com/OpenVoiceOS/ovos-gui/pull/22) ([NeonDaniel](https://github.com/NeonDaniel)) + ## [0.0.3a10](https://github.com/OpenVoiceOS/ovos-gui/tree/0.0.3a10) (2023-07-20) [Full Changelog](https://github.com/OpenVoiceOS/ovos-gui/compare/V0.0.3a9...0.0.3a10) From 3340c6e1de2a9f1a6fcfff4d7a3cc742da3e911b Mon Sep 17 00:00:00 2001 From: NeonDaniel Date: Thu, 20 Jul 2023 03:22:07 +0000 Subject: [PATCH 26/26] Increment Version to 0.0.3 --- ovos_gui/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ovos_gui/version.py b/ovos_gui/version.py index 10ab25c..23532c1 100644 --- a/ovos_gui/version.py +++ b/ovos_gui/version.py @@ -2,5 +2,5 @@ VERSION_MAJOR = 0 VERSION_MINOR = 0 VERSION_BUILD = 3 -VERSION_ALPHA = 11 +VERSION_ALPHA = 0 # END_VERSION_BLOCK