parser: add support for warps and and no selection

when using preferences template, without_selection can be used to alert the user; if False, a toast notification will be displayed preventing the navigation.

warps can be used to run a command given a condition from another step; only supported by without_selection in the preferences template
main
Mirko Brombin 2 years ago
parent 327ddbc63f
commit 5dbb215f54

@ -14,6 +14,20 @@
"icon": "vanilla-package-symbolic",
"title": "Package Manager",
"description": "Choose one or more package managers to install",
"without_selection": {
"allowed": true,
"message": "You have chosen not to install any package manager, you will only be able to install packages using apx.\n\nGNOME Software will be disabled if you choose to enable the immutability feature later.",
"title": "No package manager selected",
"final": [
{
"if": "warp::immutability",
"type": "command",
"commands": [
"sudo apt remove -y gnome-software"
]
}
]
},
"preferences": [
{
"id": "flatpak",

@ -29,6 +29,8 @@
</child>
</object>
</child>
<child>
<object class="AdwToastOverlay" id="toasts">
<child>
<object class="AdwCarousel" id="carousel">
<property name="vexpand">True</property>
@ -40,5 +42,7 @@
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

@ -18,6 +18,7 @@ import time
from gi.repository import Gtk, Gio, GLib, Adw
from vanilla_first_setup.utils.run_async import RunAsync
from vanilla_first_setup.dialog import VanillaDialog
@Gtk.Template(resource_path='/io/github/vanilla-os/FirstSetup/gtk/layout-preferences.ui')
@ -38,7 +39,7 @@ class VanillaLayoutPreferences(Adw.Bin):
self.__build_ui()
# signals
self.btn_next.connect("clicked", self.__window.next)
self.btn_next.connect("clicked", self.__next_step)
def __build_ui(self):
self.status_page.set_icon_name(self.__step["icon"])
@ -59,10 +60,34 @@ class VanillaLayoutPreferences(Adw.Bin):
self.__register_widgets.append((item["id"], _switcher))
def __next_step(self, widget):
ws = self.__step.get("without_selection", {})
if not any([x[1].get_active() for x in self.__register_widgets]):
if not ws.get("allowed", True):
self.__window.toast("Please select at least one option.")
return
if ws.get("message", None):
dialog = VanillaDialog(
self.__window,
ws.get("title", "No selection"),
ws.get("message"),
)
dialog.show()
self.__window.next()
def get_finals(self):
ws = self.__step.get("without_selection", {})
finals = {"vars": {}, "funcs": [x for x in self.__step["final"]]}
for _id, switcher in self.__register_widgets:
finals["vars"][_id] = switcher.get_active()
if not any([x[1].get_active() for x in self.__register_widgets]) \
and ws.get("allowed", True) \
and ws.get("final", None):
finals["vars"]["_managed"] = True
finals["funcs"].extend(ws["final"])
return finals

@ -29,12 +29,22 @@ class Parser:
@staticmethod
def parse(finals):
commands = []
warps = []
all_vars = []
for final in finals:
if len(final) == 0:
continue
_vars = final["vars"]
for k, v in _vars.items():
if k in all_vars:
logger.error(
f"variable {k} is defined multiple times")
sys.exit(1)
if not v:
continue
all_vars.append(k)
for _func in final["funcs"]:
@ -42,7 +52,7 @@ class Parser:
logger.critical(f"Missing an 'if' operand in {_func}")
sys.exit(1)
if _func["if"] not in _vars:
if _func["if"] not in _vars and not _func["if"].startswith("warp::"):
logger.critical(
f"Missing a variable named '{_func['if']}' in the 'vars' section.")
sys.exit(1)
@ -52,6 +62,14 @@ class Parser:
f"Unsupported final type: {_func.get('type')}")
sys.exit(1)
if _func["if"].startswith("warp::"):
_var = _func["if"].split("::")[1]
warps.append({
"vars": [_var],
"func": [_func]
})
continue
# assume True if no condition is given
_condition = _func.get("condition", True)
@ -59,4 +77,17 @@ class Parser:
if _condition == _vars[_func["if"]]:
commands += _func["commands"]
# set-up warps if any
for warp in warps:
_vars = warp["vars"]
for var in _vars:
if var not in all_vars:
continue
for _func in warp["func"]:
_if = _func["if"].split("::")[1]
if _if in all_vars:
commands += _func["commands"]
return commands

@ -32,6 +32,7 @@ class VanillaWindow(Adw.ApplicationWindow):
carousel = Gtk.Template.Child()
btn_back = Gtk.Template.Child()
toasts = Gtk.Template.Child()
def __init__(self, **kwargs):
super().__init__(**kwargs)
@ -102,3 +103,8 @@ class VanillaWindow(Adw.ApplicationWindow):
cur_index = self.carousel.get_position()
page = self.carousel.get_nth_page(cur_index - 1)
self.carousel.scroll_to(page, True)
def toast(self, message, timeout=3):
toast = Adw.Toast.new(message)
toast.props.timeout = timeout
self.toasts.add_toast(toast)

Loading…
Cancel
Save