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
This commit is contained in:
Norman Feske 2023-01-10 14:35:22 +01:00 committed by Christian Helmuth
parent 88becbe29d
commit 114238c248
3 changed files with 142 additions and 10 deletions

View File

@ -35,6 +35,7 @@
#include <model/child_exit_state.h>
#include <model/file_operation_queue.h>
#include <model/settings.h>
#include <model/presets.h>
#include <view/download_status.h>
#include <view/popup_dialog.h>
#include <view/panel_dialog.h>
@ -368,21 +369,26 @@ struct Sculpt::Main : Input_event_handler,
_env, "report -> /runtime/launcher_query/listing" };
Launchers _launchers { _heap };
Presets _presets { _heap };
Signal_handler<Main> _launcher_listing_handler {
_env.ep(), *this, &Main::_handle_launcher_listing };
Signal_handler<Main> _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 <file> 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 <file> nodes */
if (dir_path == "/presets")
_presets.update_from_xml(dir); /* iterate over <file> 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);

View File

@ -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 <util/list_model.h>
#include <util/dictionary.h>
/* local includes */
#include <types.h>
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<Preset, Path>;
struct Preset : Dict::Element, List_model<Preset>::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<Preset> _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 <typename FN>
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_ */

View File

@ -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", [&] () {