// Copyright (C) 2026 Danilo M. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. import QtQuick import "../.." import "../qtmaildir" // sb-builder's GUI config on this desktop. The GUI watches the file, so a // save applies to a running sb-builder at once. Module { name: "sbb-desktop" label: "Desktop" // nf-fa-desktop, present in Inconsolata Nerd Font. icon: "\uf108" settings: true group: "SB Builder" dirty: Sbb.desktop.dirty keywords: ["sb-builder", "slackbuild", "ssh", "refresh", "notifications", "libvirt", "publish", "nvchecker", "repository"] readonly property var fields: [ ["remote", "target", "Target"], ["remote", "ssh_options", "ssh options"], ["refresh", "dashboard", "Dashboard refresh"], ["refresh", "jobs", "Jobs refresh"], ["notify", "enabled", "Notifications"], ["vm", "libvirt_uri", "libvirt URI"], ["vm", "control", "VM control"], ["vm", "domain", "Domain"], ["vm", "autostart", "Start the VM"], ["builds", "publish", "Publish"], ["hints", "nvchecker_keyfile", "nvchecker keyfile"], ["repository", "path", "Repository"]] searchItems: fields.map(f => ({ text: f[2], key: f[0] + "/" + f[1] })) function refresh() { Sbb.refresh(); } page: Component { Page { title: "SB Builder: desktop" actions: Component { SaveBar { dirty: Sbb.desktop.dirty; valid: Sbb.desktop.valid; error: Sbb.desktop.error onSave: Sbb.saveDesktop(); onDiscard: Sbb.desktop.discard() } } Column { id: col width: parent.width spacing: 6 readonly property var st: Sbb.desktop Text { width: col.width wrapMode: Text.Wrap text: Sbb.path + ". A running sb-builder rereads it on save." color: Theme.subtext font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } } Heading { text: "Build VM connection" } Setting { store: col.st; section: "remote"; key: "target"; label: "Target" placeholder: col.st.placeholder("remote", "target"); hint: "Any ssh destination: a host alias or user@host." } Setting { store: col.st; section: "remote"; key: "ssh_options"; label: "ssh options" hint: "Extra ssh arguments, separated by spaces: -p 2222." } Heading { text: "Refresh" } Setting { store: col.st; section: "refresh"; key: "dashboard"; label: "Dashboard refresh" placeholder: col.st.placeholder("refresh", "dashboard"); kind: "int"; min: 1; max: 3600 hint: "Seconds, while the Dashboard tab is visible." } Setting { store: col.st; section: "refresh"; key: "jobs"; label: "Jobs refresh" placeholder: col.st.placeholder("refresh", "jobs"); kind: "int"; min: 1; max: 3600 hint: "Seconds; doubles up to 30 while the VM is down." } Heading { text: "Notifications" } BoolSetting { store: col.st; section: "notify"; key: "enabled"; label: "Notifications"; fallback: true } Repeater { model: col.st.fallback("notify", "events") delegate: Item { id: ev required property string modelData objectName: "notify/events/" + modelData width: col.width height: 34 Text { id: evLabel anchors { left: parent.left; leftMargin: 16; verticalCenter: parent.verticalCenter } width: 144 text: ev.modelData color: Theme.subtext font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 } } Switch { anchors { left: evLabel.right; leftMargin: 8; verticalCenter: parent.verticalCenter } checked: col.st.value("notify", "events").includes(ev.modelData) onToggled: { const all = col.st.fallback("notify", "events"); const on = col.st.value("notify", "events").filter(e => e !== ev.modelData); if (checked) on.push(ev.modelData); col.st.put("notify", "events", all.filter(e => on.includes(e))); } } } } Heading { text: "VM control" } Setting { store: col.st; section: "vm"; key: "libvirt_uri"; label: "libvirt URI" placeholder: col.st.placeholder("vm", "libvirt_uri") } Item { objectName: "vm/control" width: col.width height: 34 Text { id: ctlLabel anchors { left: parent.left; verticalCenter: parent.verticalCenter } width: 160 text: "VM control" color: Theme.subtext font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 } } Switch { anchors { left: ctlLabel.right; leftMargin: 8; verticalCenter: parent.verticalCenter } // "" is how sb-builder spells no VM control; an // emptied field means the default instead. checked: col.st.value("vm", "domain") !== "" onToggled: col.st.put("vm", "domain", checked ? null : "") } } Setting { store: col.st; section: "vm"; key: "domain"; label: "Domain" visible: col.st.value("vm", "domain") !== "" placeholder: col.st.placeholder("vm", "domain"); hint: "The VM's libvirt domain." } BoolSetting { store: col.st; section: "vm"; key: "autostart"; label: "Start the VM"; fallback: false hint: "without asking when it is off" } Heading { text: "Builds and hints" } BoolSetting { store: col.st; section: "builds"; key: "publish"; label: "Publish"; fallback: true hint: "the initial state of the publish box next to Run it" } Setting { store: col.st; section: "hints"; key: "nvchecker_keyfile"; label: "nvchecker keyfile" placeholder: col.st.placeholder("hints", "nvchecker_keyfile") hint: "A GitHub token for nvchecker; optional." } Setting { store: col.st; section: "repository"; key: "path"; label: "Repository" placeholder: col.st.placeholder("repository", "path") hint: "Local mount of slackrepo's package repository, for the Repository tab." } } } } }