From 114238c248496e0ddf46275b0b86f84343d3c9bb Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 10 Jan 2023 14:35:22 +0100 Subject: [PATCH] sculpt_manager: query presets This patch queries the files at config/presets/ in addition to config/launcher using the existing launcher_query component. Issue #4731 --- repos/gems/src/app/sculpt_manager/main.cc | 26 ++-- .../src/app/sculpt_manager/model/presets.h | 121 ++++++++++++++++++ .../sculpt_manager/runtime/launcher_query.cc | 5 + 3 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 repos/gems/src/app/sculpt_manager/model/presets.h diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc index 172631b683..deadc26dad 100644 --- a/repos/gems/src/app/sculpt_manager/main.cc +++ b/repos/gems/src/app/sculpt_manager/main.cc @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -368,21 +369,26 @@ struct Sculpt::Main : Input_event_handler, _env, "report -> /runtime/launcher_query/listing" }; Launchers _launchers { _heap }; + Presets _presets { _heap }; - Signal_handler
_launcher_listing_handler { - _env.ep(), *this, &Main::_handle_launcher_listing }; + Signal_handler
_launcher_and_preset_listing_handler { + _env.ep(), *this, &Main::_handle_launcher_and_preset_listing }; - void _handle_launcher_listing() + void _handle_launcher_and_preset_listing() { _launcher_listing_rom.update(); - Xml_node listing = _launcher_listing_rom.xml(); - if (listing.has_sub_node("dir")) { - Xml_node dir = listing.sub_node("dir"); + Xml_node const listing = _launcher_listing_rom.xml(); + listing.for_each_sub_node("dir", [&] (Xml_node const &dir) { - /* let 'update_from_xml' iterate over nodes */ - _launchers.update_from_xml(dir); - } + Path const dir_path = dir.attribute_value("path", Path()); + + if (dir_path == "/launcher") + _launchers.update_from_xml(dir); /* iterate over nodes */ + + if (dir_path == "/presets") + _presets.update_from_xml(dir); /* iterate over nodes */ + }); _popup_menu_view.generate(); _deploy._handle_managed_deploy(); @@ -1235,7 +1241,7 @@ struct Sculpt::Main : Input_event_handler, _pci_devices .sigh(_pci_devices_handler); _window_list .sigh(_window_list_handler); _decorator_margins .sigh(_decorator_margins_handler); - _launcher_listing_rom.sigh(_launcher_listing_handler); + _launcher_listing_rom.sigh(_launcher_and_preset_listing_handler); _blueprint_rom .sigh(_blueprint_handler); _editor_saved_rom .sigh(_editor_saved_handler); _clicked_rom .sigh(_clicked_handler); diff --git a/repos/gems/src/app/sculpt_manager/model/presets.h b/repos/gems/src/app/sculpt_manager/model/presets.h new file mode 100644 index 0000000000..d5ccbd4f48 --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/model/presets.h @@ -0,0 +1,121 @@ +/* + * \brief Cached information about available deploy presets + * \author Norman Feske + * \date 2022-01-11 + */ + +/* + * Copyright (C) 2023 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _MODEL__PRESETS_H_ +#define _MODEL__PRESETS_H_ + +/* Genode includes */ +#include +#include + +/* local includes */ +#include + +namespace Sculpt { class Presets; } + + +class Sculpt::Presets : public Noncopyable +{ + public: + + struct Info : Noncopyable + { + using Name = String<64>; + using Text = String<128>; + + Name const name; + Text const text; + + static Text _info_text(Xml_node const &node) + { + Text result { }; + node.with_optional_sub_node("config", [&] (Xml_node const &config) { + result = config.attribute_value("info", Text()); }); + return result; + } + + Info(Xml_node const &node) + : + name(node.attribute_value("name", Path())), + text(_info_text(node)) + { } + }; + + private: + + Allocator &_alloc; + + unsigned _count = 0; + + struct Preset; + + using Dict = Dictionary; + + struct Preset : Dict::Element, List_model::Element + { + Info const info; + + bool matches(Xml_node const &node) const + { + return node.attribute_value("name", Path()) == name; + } + + static bool type_matches(Xml_node const &node) + { + return node.has_type("file"); + } + + Preset(Dict &dict, Xml_node const &node) + : + Dict::Element(dict, node.attribute_value("name", Path())), + info(node) + { } + }; + + Dict _sorted { }; + + List_model _presets { }; + + public: + + Presets(Allocator &alloc) : _alloc(alloc) { } + + void update_from_xml(Xml_node const &presets) + { + update_list_model_from_xml(_presets, presets, + + /* create */ + [&] (Xml_node const &node) -> Preset & { + return *new (_alloc) Preset(_sorted, node); }, + + /* destroy */ + [&] (Preset &e) { destroy(_alloc, &e); }, + + /* update */ + [&] (Preset &, Xml_node) { } + ); + + _count = 0; + _presets.for_each([&] (Preset const &) { _count++; }); + } + + template + void for_each(FN const &fn) const + { + _sorted.for_each([&] (Preset const &preset) { fn(preset.info); }); + } + + bool available() const { return _count > 0; }; +}; + +#endif /* _MODEL__PRESETS_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/runtime/launcher_query.cc b/repos/gems/src/app/sculpt_manager/runtime/launcher_query.cc index 867e6314f7..16ec80401a 100644 --- a/repos/gems/src/app/sculpt_manager/runtime/launcher_query.cc +++ b/repos/gems/src/app/sculpt_manager/runtime/launcher_query.cc @@ -30,6 +30,11 @@ void Sculpt::gen_launcher_query_start_content(Xml_generator &xml) xml.attribute("path", "/launcher"); xml.attribute("content", "yes"); }); + + xml.node("query", [&] () { + xml.attribute("path", "/presets"); + xml.attribute("content", "yes"); + }); }); xml.node("route", [&] () {