Skip to content

The window's QML files

This page is written by tools/qml-docs.py from the files' own comments, at each build of this website: a description is corrected in its .qml file, never here. How the window is made: API reference.

Reading a QML file

QML is Qt's language for interfaces. A .qml file describes one type of object: its root object (Button { … }) and the objects inside it. The file's name is the type's name: RailButton.qml makes a RailButton, which another file uses as RailButton { … }. A type has everything its root object's type has: a RailButton is a Qt Button, with a few properties of its own. Each file below says what it is based on, with a link to Qt's page for Qt's types.

  • required property: what whoever makes the object must give it. Most of Sioul's types ask for theme (colours, sizes and spacing, Theme), and many for sioul, the Rust object behind the window (Sioul, in crates/sioul-app/src/backend.rs; its functions are in the Rust reference), or window (the main window, main).
  • property: a value that can be set from outside, or read. readonly property: one that is only read, worked out from others (a binding, which follows them when they change). property alias: another object's property, reached through this one. A value is shown when it is short; … stands for a longer one.
  • signal: what the object tells whoever made it; that one answers with a handler named after it (signal chosen is answered by onChosen: …).
  • function: what other objects may call.
  • Inline component (component Name: Type { … }): a small type used inside its file only.

Only what each file's root object declares is listed. What is deeper (a delegate, a nested object) is in the file, linked under each name. The files belong to the QML module com.aurelienpierre.sioul, built by crates/sioul-app/build.rs; qml-desktop/ holds what only computers have (the system tray), qml/android/ the phone's versions of two pages.

The window

Sioul's main window and what frames every page: the places on the left, the title bar and edges Sioul draws on a computer, the system tray, the theme, the covers of a pause or of quiet time.

main

crates/sioul-app/qml/main.qml · based on SioulWindow

Sioul's window: on the left, a narrow column of icons (RailButton.qml): "New" for anything, the places where your things live, then, apart at the bottom, the accounts, the settings and one button that refreshes everything; their names beside them when Settings ▸ Display says so or the button at the title bar's left end (F9), else said when the pointer rests on one. One quiet status line (StatusLine.qml), where "Undo" waits ten seconds after anything is moved, deleted or sent: on a computer, it is the window's own title bar, at the top, with the window's buttons where the system puts them (TitleBar.qml); on a phone, it is at the bottom. No badges, no counts in the title, no red; the system's dark mode is followed. Everything works from the keyboard: Tab, Enter, Escape, Ctrl+1 to Ctrl+9 and Ctrl+0 (the places by the list), Ctrl+N (new), Ctrl+Z, F5 (refresh), F9 (the places' names or their icons only). Whatever links lead to (a task, a message, a note, an event, a contact) opens where it lives. On a phone, or in a window as narrow, the places are pulled over the pages from the left (☰) with their names, the pages take the whole width, and Android's Back puts the places away, then goes back to the Porch.

Properties

  • property int page: 0
  • readonly property bool phoneGrab: …: The documentation's pictures (SIOUL_GRAB_STEPS=demo) are a landscape screen; with SIOUL_GRAB_PHONE (or SIOUL_GRAB_STEPS=phone), a phone's: 412 by 891, its layout.
  • readonly property bool demoGrab: …
  • readonly property bool ownTitleBar: …: On a computer, Sioul draws its own title bar (TitleBar.qml): the status line at the top, the window's buttons where the system puts them; the system draws none. A phone's screen has none, nor have a phone's pictures.
  • property int shownAs: Window.Maximized: How the window was shown before it went to the tray: shown again so.
  • property int beforeFullScreen: Window.Maximized: What full screen (F11) goes back to.
  • property bool quitting: false: Quitting for good (the tray's menu, Ctrl+Q): the close goes through.
  • readonly property bool trayHolds: …: The system tray holds Sioul (qml-desktop/Tray.qml): closing the window hides it there.
  • readonly property var statusLine: …: The status line (StatusLine.qml): in the title bar on a computer, at the bottom on a phone.
  • readonly property var namesButton: …: The button that shows the places' names or keeps their icons only: at the title bar's left end on a computer, else at the places' foot.
  • property var drafts: []: The writing windows open, one per draft.
  • readonly property var sioulLocale: Qt.locale(sioul.text("qt-locale")): Month and day names in Sioul's language, not the system's.
  • readonly property bool compact: window.width < 720: A phone, or a window as narrow: the places pulled over the pages from the left.
  • property bool placesOpen: false
  • property bool placesMade: false: The places made the first time they show, then kept (Places.qml): a phone's drawer at its first ☰; the column beside the pages at once.
  • readonly property bool placesNamed: …: Their names beside their icons, or their icons only: the button at the title bar's left end (at their foot where the status line is at the bottom), F9, or Settings ▸ Display, one setting; wherever they are beside the pages.
  • readonly property bool railShown: !window.compact: The places beside the pages: a window wide enough; never hidden.
  • property var menuAt: null: Where a long press opened a menu, for the menu to come there (SioulMenu.qml): a touch screen has no cursor to place it at. Forgotten after a moment.
  • readonly property var pageNames: …: Each page's name, by its place in the pages' stack.
  • property var made: …: Each page is made when it is first shown, then kept: the window opens with the Porch alone, and a page asked for (a link, "New") is made before it is used, as the page is set first.
  • readonly property var pageFiles: …: Each page's file, read the first time it is made (setSource, for their required properties): what it imports (maps, PDFs, sites, sounds) is loaded then, not as the window opens. Android has its own Sites page.
  • readonly property var porchPage: porchPageLoader.item
  • readonly property var tasksPage: tasksPageLoader.item
  • readonly property var mailPage: mailPageLoader.item
  • readonly property var sitesPage: sitesPageLoader.item
  • readonly property var agendaPage: agendaPageLoader.item
  • readonly property var contactsPage: contactsPageLoader.item
  • readonly property var notesPage: notesPageLoader.item
  • readonly property var projectsPage: projectsPageLoader.item
  • readonly property var timePage: timePageLoader.item
  • readonly property var budgetsPage: budgetsPageLoader.item
  • readonly property var healthPage: healthPageLoader.item
  • readonly property var accountsPage: accountsPageLoader.item
  • readonly property var parametersPage: parametersPageLoader.item
  • readonly property var papersPage: papersPageLoader.item
  • readonly property var textsPage: textsPageLoader.item: texts: the Texts page, a computer's only (a phone has its own SMS app).
  • readonly property var shownPage: …: The page in view; on a phone, a page showing one thing it opened (a message, a task) says so (canGoBack) and closes it (back()).
  • readonly property bool canGoBack: …
  • readonly property var moment: …: Work time or quiet time: {quiet, reason, until, line, hours}.
  • property bool drawn: false: The start timed (on Android, and with SIOUL_TIMING): the first frame drawn.
  • property alias now: clock.now
  • property alias today: clock.today
  • property string lastDone: "": The task just done, and the status line that said so.
  • property string lastDoneSaid: ""
  • readonly property var howWasItPopup: howWasItForm.item
  • property Component composer: null: The window to write in (ComposeWindow.qml): read the first time a draft opens.
  • readonly property var routinePlayer: routinePlayerLoader.item
  • readonly property var focusWindow: focusWindowLoader.item
  • readonly property var offer: …: What the status line offers now: {kind, date, line, button}, kind "" for nothing.
  • readonly property var pauses: …: The two pauses (docs/pauses.md): Free time's choices and today's end of work.
  • property string freeSaid: "": The end of work said once, back from free time: "Keep my usual end" shows beside it.

Functions

  • function hideToTray(): Hidden in the tray, Sioul going on behind; said once, the first time.
  • function bringBack(): Shown again as it was (from the tray), and brought forward. visible first: declared above, it went false with hide(), and visibility set against it warned "Conflicting properties 'visible' and 'visibility'".
  • function toggleShown(): The tray's click: hidden when the window is in front, else brought back.
  • function quitSioul(): Quit for good: the tray's menu, Ctrl+Q.
  • function toggleFullScreen(): F11: full screen, or back to how it was.
  • function toggleMaximized(): The title bar's double click and its button (TitleBar.qml): maximized, or back to its size; from full screen, back to how it was.
  • function makePages()
  • function compose(kind, key): Starts a draft ("new", "reply", "reply-all", "forward") and opens its window.
  • function writeTo(recipients): "Write" from a contact: a new message to them.
  • function openContact(key): A sender's contact, from a message.
  • function newContactWith(number): A new contact with a number filled in: a call's line on a computer's Porch (CallsSection.qml).
  • function openTask(uid)
  • function openNote(path)
  • function makeEvent(title, note, link): A new event made from a message or a task, the link kept.
  • function addLinked(kind, source): Something new tied to source ({uri, kind, key, title, start, name, address}): made, then opened where it lives. A task opens as a new task's full form, its title and its tie given: made once its title is.
  • function newThing(kind): Something new from the "New" menu: opened where that kind lives.
  • function howWasIt(uid): How a task just done was: its ratings as felt, if you want to say (HowWasIt.qml, made the first time).
  • function contractFromMail(subject, from): A mail kept as a contract: the Budgets page, the form started from it.
  • function newFilterFrom(conditions): The search's "Make it a filter…" (MailSearch.qml): a new mail filter with its conditions ({conditions, match}, as the filters write them), last in the list, its editor open in Mail ▸ ⚙ to choose what it does.
  • function linkFrom(source, kind): "Link to…": the picker, for source.
  • function showNewMenu(): Something new, of any kind, under the New button.
  • function togglePlaces(byKeys): The places' names shown beside their icons, or their icons only (the button at the title bar's left end, or at their foot where the status line is at the bottom; F9; the setting of Settings ▸ Display). On a phone, or in a window as narrow, the drawer pulled out or put away instead. The keyboard's focus on the places or on the button stays on the button, with a ring when it came by the keyboard (byKeys).
  • function sayRailTip(button, shown, ms): The places' names and keys, at the right of the button under the pointer, reached by the keyboard or held by a finger (RailButton.qml): one tip for them all, made the first time one is asked for. Half a second on hover; at once, for ms milliseconds, after a long press.
  • function askDose(key): A dose marked late, or due while Sioul was closed: when it was taken (DoseTaken.qml, made the first time); the pages showing doses read them again.
  • function askNeed(key): A meal's, a nap's or the night's question (later, at another time, not today), or "" to note where you stopped alone (Interruption.qml, made the first time); the pages showing them read again.
  • function openThing(item): Whatever a link leads to, opened where it lives.
  • function openSite(id): A site of the Sites page, opened.
  • function openProject(id): A project's page.
  • function showTasksOf(id, mode): A project's tasks, as a board, a list or a calendar.
  • function openDraft(id): A draft's window; brought forward when it is already open.
  • function copy(text): Copies text the way Qt Quick allows it: through a hidden text field.
  • function reachesTab(): var: Settings ▸ What reaches you, once made (ReachesTab.qml): for the pictures' steps.
  • function wordsTab(): var: Settings ▸ Words (WordsTab.qml), once its tab was shown: the demo steps open its lines.
  • function openPersonSheet(key, addresses): How someone reaches you (PersonSheet.qml, made the first time): a contact's card by its file or UID, or a sender's addresses (a JSON array).
  • function openTexts(id): texts: the Texts page (TextsPage.qml), at a conversation by its id when one is given; a phone has its own SMS app, where the conversation opens.
  • function showParameters(key): Settings, at one of them: the hours, from the Porch.
  • function loadTray(): The system tray, on a computer, once the window shows (onFrameSwapped); never while taking the documentation's pictures. Plasma's tray menu is made of widgets: Sioul runs as a widgets application there (cpp/application.cpp).
  • function playRoutine(routine)
  • function setFreeTime(on): Free time on or off: on, the line on where you stopped when a session stopped (GP3); off, the end of work said once, with its key (GP11, GP16).
  • function freeMenu(): Free time's menu, a right click or a long press on its button: back, the usual end kept, nothing at all; nothing opens when none applies (StatusLine.qml).
  • function reviewDay(kind): "work" or "night": the review's sheet.
  • function showClosing(closing): The work day closed from the sheet: the Tasks page's screen says where everything went, over the page shown (the Tasks page made if it was not).

Clock

crates/sioul-app/qml/Clock.qml · based on QtObject

Now, for the whole window (main.qml): one clock that the line at now in the day views, today's marks and the pages that read again as time passes all follow. now is the minute (Unix seconds at its turn), today the day ("2026-10-06"); each changes only when it turns, today first, so that a page reading again at the minute sees the new day. One timer, set again at each minute's turn from the wall clock: a timer counts only while the computer runs (asleep, it waits), and Qt counts a Timer on its animation clock, so the time is read at each turn, never counted. Read again at once when the window or the app comes back (read). Held while paused (a phone that put Sioul away), read again as soon as it is not.

Properties

  • property var source: () => Date.now(): The time it reads, in milliseconds since 1970: the system's, unless a test gives its own.
  • property bool paused: false
  • property real now: Math.floor(Date.now() / 60000) * 60: The system's time as it is made, its source's once made, then at each turn.
  • property string today: clock.dayOf(new Date())
  • property real turnedAt: 0: The last minute said turned (minutes since 1970).
  • readonly property Timer turn: …

Signals

  • signal turned: Each minute's turn, paused or not: the backend's minute rides on it.

Functions

  • function dayOf(d): "2026-10-06": a day as the pages and the views write it.
  • function read(): The time read again: what changed is said, nothing else.
  • function arm(): To the next minute's turn, a little after it: set again at each turn, so that a turn come early or late (the computer woken) is not carried on.

PauseCover

crates/sioul-app/qml/PauseCover.qml · based on Rectangle

The pause's screen (docs/pauses.md, P11–P17): over Sioul's whole window, Sioul's content only (on a phone the system stays free: calls, other apps, emergency dialling). A few literal lines about Sioul, never about you; your own list of what helps, folded; your line and the breathing guide if you set them; the emergency number and the crisis line of your country, one tap each; one button to come back, nothing asked. Nothing moves unless you start it: no count, no countdown, no question. Coming back, the same calm ground says it in a few words, with the one offer, then goes.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property bool trial: false: A try-out from the setup: the screen as it will be, nothing held.
  • property var back: null: After "Come back": the return's words ({title, day, tomorrow, lighten, go}), else null.
  • property var screen: …: Read again each time the cover shows: the setup may have changed.
  • property bool listOpen: false
  • property bool numbersOpen: false
  • property bool lightened: false
  • property alias guideRunning: guide.running: The breathing guide moving (its button, a tap on it).

Signals

  • signal coming: "Come back" pressed: the cover stays for the return's words.
  • signal done: The try-out ended, or the return was read.

Functions

  • function reload()
  • function comeBack(): Back from the pause: the return's words, the same ground under them.

Places

crates/sioul-app/qml/Places.qml · based on Item

The places, on the left of the window (main.qml): New, then the places where your things live, then, apart at the bottom, closing the work day or the day (at any hour), the accounts, the settings and one button that refreshes everything; at its foot, level with the status line where that line is at the bottom, the button that shows their names or keeps their icons only (F9; on a computer, at the title bar's left end). One icon each (RailButton.qml), their names beside them when named; scrolled when the window is too short for them all. Made the first time they show: a phone's drawer is not made before ☰ is pressed.

Required properties (whoever makes it must give them)

  • required property var window
  • required property var theme
  • required property var sioul
  • required property bool named: Names beside the icons: in a phone's drawer, else as Settings ▸ Display says.

Properties

  • readonly property int row: …: A row: a finger's on a phone or a touch screen, a pointer's elsewhere.
  • readonly property int inset: column.named ? 8 : 6: The buttons' margin on each side.
  • readonly property alias addButton: newButton: What the window reaches: New (its menu comes under it), the button that shows the names or keeps the icons (the keyboard's focus stays on it), the places.
  • readonly property alias namesButton: namesToggle
  • readonly property alias list: placesList
  • readonly property alias repeater: placesRepeater

RailButton

crates/sioul-app/qml/RailButton.qml · based on Button

One button of the places (Places.qml; at the title bar's left end, TitleBar.qml, the one that shows their names): its icon, and its name beside it where names are shown (a phone's drawer; Settings ▸ Display ▸ "Show the places' names beside their icons"). Its name and its key are said when the pointer rests on it, when the keyboard reaches it, at a long press on a touch screen (which then opens nothing), and to screen readers. The place shown is marked quietly: a soft tint of the accent, its icon in the accent, a short bar on its left; the keyboard's focus by a ring. Light, as it is made with the window: an icon read on a thread, one line of text, empty unless names are shown; the places' tip is one for the whole window (main.qml's sayRailTip).

Required properties (whoever makes it must give them)

  • required property var theme: The window's colours, sizes and fonts (Theme.qml).
  • required property string iconName: Its icon, by its freedesktop name.
  • required property string name: What it is, in words: said in its tip and to screen readers, shown when named.

Properties

  • property string keys: "": Its key ("Ctrl+2", "F9"), said with its name; "" for none.
  • property bool named: false: Its name shown beside its icon.
  • property string after: "": Written after its name when it is shown: " ▾" for a menu.
  • property bool place: false: A place: checked for screen readers while it is the one shown.
  • property bool current: false: The place shown: marked, and checked.
  • property bool filled: false: New: filled with the accent, the window's one such button.
  • property string tip: …: What its tip says: its name, and its key.
  • property var sayTip: null: Where its tip is said: the window's function (button, shown, milliseconds), at the right of the places; else Qt's own tip, above it.
  • property bool held: false: A long press on a touch screen said its name: letting go opens nothing.
  • readonly property alias glyph: glyph: Its icon, for the window to turn (the sync's button while it syncs, Places.qml).

Signals

  • signal chosen: Clicked, or Space or Enter, unless a long press only said its name.

Functions

  • function showTip(shown, ms): Its tip shown or hidden for ms milliseconds: by the window when it says the places' tips (sayTip), else by Qt.

RestCover

crates/sioul-app/qml/RestCover.qml · based on Rectangle

A page that waits (quiet time, or while you sleep): one line over it, what may still be done then (a thought noted for later), and the page itself if you ask (docs/areas.md).

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).
  • required property string line: The one line said over the page ("Sleep: nothing disturbs until 07:00.").

Properties

  • default property alias content: more.data: Shown under the line: a field to note a thought for later, say.

Signals

  • signal shown: "Show anyway" was pressed: the page is shown all the same.

SioulWindow

crates/sioul-app/qml/SioulWindow.qml · based on ApplicationWindow

A window of Sioul: the theme's colours given to Qt's controls, the same in every window (the main one, writing, focus, portals).

Required properties (whoever makes it must give them)

  • required property var theme: The window's colours, sizes and fonts (Theme.qml). Its colours are given to Qt's controls in the window.

Theme

crates/sioul-app/qml/Theme.qml · based on QtObject

The colours, spacing and reading type of every window: muted, with even steps of lightness, no pure white or black, no red for lateness (docs/design.md, "Keyboard and senses"). Light or dark follows the desktop.

Each pair that is drawn together keeps its contrast: text on surfaces, light text on the accent, text on the hover tint and on the selection. Qt's Basic style draws a hovered list entry in highlightedText on light, and selected text in highlightedText on highlight: both are given colours that read on each other here (SioulWindow.qml).

Properties

  • property bool dark: false: Dark or light: the desktop's, unless forced (for the window's images).
  • readonly property color background: dark ? "#1e1f1c" : "#f5f2ec"
  • readonly property color surface: dark ? "#272824" : "#fbfaf7"
  • readonly property color text: dark ? "#e6e2da" : "#2d2a26"
  • readonly property color muted: dark ? "#a8a297" : "#6b655c"
  • readonly property color line: dark ? "#3b3b36" : "#e2dccf"
  • readonly property color button: dark ? "#34352f" : "#ebe5d9"
  • readonly property color hover: dark ? "#3a3b35" : "#e5ded1": Under the pointer, or chosen in a list: text keeps its own colour on it.
  • readonly property color pressed: dark ? "#55574f" : "#c9bfac": A pressed or toggled tool button, a scroll bar's handle: one step past the line.
  • readonly property color selection: dark ? "#5d8471" : "#5f8572": Selected text and keyboard focus rings: a mid tone, readable under text and around buttons.
  • readonly property color accent: dark ? "#93b5a2" : "#4c6b5c"
  • readonly property color accentText: dark ? "#1e1f1c" : "#fbfaf7"
  • readonly property color warm: dark ? "#d4a56c" : "#8f6330"
  • readonly property color forged: dark ? "#d38e70" : "#97573a"
  • readonly property color focus: dark ? "#c9d9cf" : "#2f4a3d"
  • property bool compact: false: A phone held upright: narrower margins and spacing (main.qml says when).
  • property bool touch: false: Fingers rather than a mouse (a phone, or the runner's phone size): what is tapped is kept a fingertip wide (CostTiles.qml).
  • readonly property int gap: compact ? 10 : 16
  • readonly property int radius: 6
  • property string readingFamily: "": Long text (notes, mail, a task's notes): the family, size and spacing chosen in "Aa".
  • property int readingSize: 16
  • property real readingSpacing: 1.5: Line height, as a multiple of the font's (1.5 reads more easily than Qt's 1.0).
  • readonly property var kindIcons: …: Each kind of thing by its icon, wherever things are listed.
  • readonly property var chartColors: …: The projects in the Time page's bars: calm, and apart from each other.
  • readonly property var taskKindIcons: …: Each kind of task by its icon.
  • readonly property string mono: …: Fixed-width type: "monospace" names a font on Linux only; Windows and macOS have their own.

Functions

  • function sideWidth(available): A side panel's width (a page's settings, Health's): all of a phone's; on a computer, two fifths of the window and a little more, from 520 to 760 pixels, the page beside it keeping 240 at least.
  • function spaced(html): Rich text with its lines spaced: Qt's text documents take line-height from a style sheet.
  • function plain(text): Words from a message, a site or a server, where Qt guesses HTML from a "<" and has no textFormat to say otherwise (buttons, menu lines, tooltips, dialog titles): a word joiner after each "<" keeps them plain. Else a name holding <img src=…> loads an image from the network, or crashes a button. A Label takes textFormat: Text.PlainText instead.
  • function escaped(text): Words put into rich text on purpose (a link): escaped, so that they stay words.
  • function fileUrl(path): A file's path as a file:// address, each part escaped: "#", "?" or "%" in a name stay in it; a Windows path ("C:\…") becomes file:///C:/…, a network folder ("\\server\share") file://server/share, as the backend's file_url writes them and its local_path reads them back.
  • function localPath(url): A folder chosen in a dialog (a file:// address) as a path: on Windows "file:///C:/Users" is "C:/Users", not "/C:/Users", and "file://server/share" a network folder, "//server/share". On Android, the phone's own storage as its documents provider names it ("content://com.android.externalstorage.documents/tree/primary%3ADocuments%2FSioul": "primary" the phone, "home" its Documents, else a card's volume; "raw:" a path as is). "" for a folder that is no folder of this device: a cloud's own provider, which Sioul does not read.

TitleBar

crates/sioul-app/qml/TitleBar.qml · based on Rectangle

The window's own title bar, on a computer (main.qml): the status line (StatusLine.qml) across the whole width, at the top, where the system's title bar only took room. At its left end, over the places, the button that shows their names or keeps their icons only (F9); the window's buttons, minimize, maximize or restore, and close, on the side and in the order the system puts them (desktop.rs). Its empty space, the sentence included, moves the window when dragged and maximizes or restores it at a double click; the window's edges resize it (WindowEdges.qml). While a pause covers the window, only the window's buttons stay, and the bar to move it.

Required properties (whoever makes it must give them)

  • required property var window
  • required property var sioul
  • required property var theme

Properties

  • readonly property var buttons: …: The window's buttons on each side, in order: {left, right}, each "minimize", "maximize" or "close", where the system puts them (desktop.rs); in the documentation's pictures, minimize, maximize and close on the right, wherever they are taken.
  • property bool covered: false: A pause covers the window (PauseCover.qml).
  • property real placesWidth: 56: The places' width beside the pages, which the names' button spans when no window button is on the left: the status line starts where the pages do.
  • readonly property int inset: bar.window.placesNamed ? 8 : 6: The places' buttons' margin on each side (Places.qml's inset).
  • readonly property alias statusLine: line
  • readonly property alias namesButton: namesToggle

Inline components (used inside this file)

  • component WindowButton: ToolButton: One of the window's buttons: its icon, its name said on hover and to screen readers; reached by Tab, never taking the focus from what you write in at a click. As tall as the bar: maximized, the last one reaches the screen's corner.

Tray

crates/sioul-app/qml-desktop/Tray.qml · based on Platform.SystemTrayIcon

Sioul in the system tray, on a desktop (main.qml): a click shows the window or hides it, Sioul going on behind it (reminders, medicines, mail at its hours, the sharing); its menu shows or hides the window, or quits. Without a tray (available false: GNOME without its extension, a bare window manager), closing the window quits, as before. Plasma's tray menu is made of widgets: on a computer Sioul is a widgets application (cpp/application.cpp), and this is loaded once the window shows (main.qml's loadTray). Kept out of qml/: the phone's build reads that folder for the modules to carry, and this one would bring Qt Widgets along for a tray Android has not (build.rs).

Required properties (whoever makes it must give them)

  • required property var window
  • required property var sioul

WindowEdges

crates/sioul-app/qml/WindowEdges.qml · based on Item

The window's edges, on a computer where Sioul draws its own title bar (main.qml, TitleBar.qml): pressed and dragged, an edge or a corner resizes the window as the system's borders would, the system doing the resizing (snapping, tiling); the pointer takes the resizing shape there. Six pixels inside each edge, the corners sixteen along each; nothing while the window is maximized or full screen, which have no edge to pull.

Required properties (whoever makes it must give them)

  • required property var window

Properties

  • readonly property int grip: 6: How far in from each edge a press resizes, and how far along each edge a corner reaches.
  • readonly property int corner: 16

Inline components (used inside this file)

  • component Edge: MouseArea: One edge, its corners at its ends.

The status line and its applets

The line along the window's edge (at its top on a computer, at its bottom on a phone): what just happened, what now is, and the small switches beside it.

CallsApplet

crates/sioul-app/qml/CallsApplet.qml · based on LineButton

"Let every call through" (docs/android.md, "Calls"): a switch for the status line, a button of the line (LineButton.qml), shown on every device while a phone of yours screens calls, for when you expect a call. One click lets every call ring on that phone for an hour; a click while it is on screens calls again; a right click or a long press chooses until when. Its words say until when; no colour but the accent while it is on. Self-contained: the status line places it (main.qml), beside do-not-disturb's switch.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var moment: The status line's moment (backend.rs's mode_json), its calls part (calls.rs's moment).

Properties

  • readonly property var calls: …
  • readonly property bool on: applet.calls.through === true

Functions

  • function tipText(): string
  • function openMenu()

DndApplet

crates/sioul-app/qml/DndApplet.qml · based on LineButton

Do-not-disturb's switch, in the status line beside the sounds (docs/do-not-disturb.md), a button of the line (LineButton.qml): one click turns it on until you turn it off, on every device, or off; a right click or a long press says until when, and where it holds. Its words say where it holds ("on every device", "here only") and why; no colour but the accent while it is on. Apart from the pauses' buttons, at the line's end, so that the two are never taken for one another. Both ways: turned off in this device's own system, unheard, it says so, muted, with "Silence this device again"; off while the system still silences this device, it says so, with Android's page; the last "off" made in a system is named in its tip.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var moment: The status line's moment (main.qml), its dnd part (everywhere.rs's moment).

Properties

  • readonly property var dnd: …
  • readonly property bool on: applet.dnd.on === true
  • readonly property bool hereOff: …: On elsewhere, turned off in this device's own system and left so (both ways).
  • readonly property var offers: …: The buttons beside what this device's own system holds: Android's page.

Functions

  • function tipText(): string
  • function openMenu(): Until when, and where it holds: at a right click or a long press.

HowWasIt

crates/sioul-app/qml/HowWasIt.qml · based on Popup

"How was it?", from the status line just after a task is done: its four costs and its gain as tiles, what was foreseen a thin mark on each (FeltRatings.qml). Over the window, never in its way: not modal, closed by Escape or a click elsewhere; nothing is kept unless a tile is tapped.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string uid: ""
  • property string title: ""
  • property var forecast: ({})
  • property var kept: null

Functions

  • function ask(uid): The task's ratings, read now (it was just written as done).
  • function keep(values): Kept as felt, and only that: what else the task says is left as it is on disk.

LineButton

crates/sioul-app/qml/LineButton.qml · based on ToolButton

A button of the status line (StatusLine.qml), its applets' too: its icon, and its words beside it where there is room; compact (a phone, a window as narrow), its icon alone, as wide as the icon and an even margin on each side. Its name is said to screen readers, when the pointer rests on it, and at a long press on a touch screen, which then does nothing else (unless tipOnHold is false: there, as for do-not-disturb and Free time, a long press opens a menu). Flat: a tint under the pointer, the accent's while it is on, a ring for the keyboard's focus; Undo, which waits ten seconds, is drawn as a button at rest too (raised).

Required properties (whoever makes it must give them)

  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property bool compact: false: Its icon alone.
  • property string name: button.text: What it is, in words: said to screen readers, and its tip unless tip says more.
  • property string tip: button.name: Its tip, when the pointer rests on it: its name, unless more is said.
  • property bool switchedOn: false: On (Free time, do-not-disturb): its icon in the accent, the accent's tint under it.
  • property bool raised: false: Drawn as a button at rest too.
  • property color textColor: button.theme.text: Its words' colour.
  • property bool menuOpen: false: Its own menu or pop-up is open: no tip over it.
  • property bool tipOnHold: true: A long press says its name; false where a long press opens a menu.
  • property bool saying: false: Its name said after a long press, for three seconds.
  • property bool held: false: A long press said its name, or opened its menu: letting go does nothing.

Signals

  • signal chosen: Clicked, or Space or Enter, unless a long press said its name or opened its menu.

NoisePlayer

crates/sioul-app/qml/NoisePlayer.qml · based on Item

The sounds' player, in a file of its own (SoundsApplet.qml): Qt Multimedia and its decoders are loaded the first time a sound plays, not each time the window opens. A sound fades in as it starts and out as it stops, over five seconds; the volume slider meanwhile changes it at once.

Properties

  • readonly property alias level: output.volume: The output's volume as it is now, mid-fade too (for the tests).
  • readonly property bool fadingOut: fade.running && fade.to === 0: Fading out, before the sound stops.

Functions

  • function play(url, volume): url played in a loop, faded in from silence to volume.
  • function setVolume(volume): The slider moved: the volume at once, a fade in under way ended there; never while the sound fades out to stop.
  • function fadeOut(): Faded to silence; the sound itself stops with stop.
  • function stop()
  • function fadeTo(volume)

SoundsApplet

crates/sioul-app/qml/SoundsApplet.qml · based on LineButton

Sounds, in the status line, a button of the line (LineButton.qml): noise for focus (white, pink, brown), nature to rest by (waves, rain, wind in the trees, crickets, a distant storm), all made here, and your own recordings (the notes' sounds folder). One at a time, looping, fading in and out; never on by itself.

Required properties (whoever makes it must give them)

  • required property var sioul

Properties

  • property bool below: false: Its pop-up under it, the line at the window's top (a computer's title bar); else above it.
  • property string playing: ""
  • property string playingTitle: ""
  • property var calm: []
  • property real loudness: 0.5
  • readonly property var noise: player.item: The player once loaded (NoisePlayer.qml), as a plain value: naming its type here would load Qt Multimedia with the window.

Functions

  • function play(url, title)
  • function stop(): Faded out, then stopped.

StatusLine

crates/sioul-app/qml/StatusLine.qml · based on Item

The status line (main.qml): one sentence about what happened last, with "Undo" for ten seconds after anything is moved, deleted or sent; what now is (quiet time, work kept late) and, behind a click, the way back, never suggested; the work day or the day offered to close at its time; the keys; do-not-disturb, the sounds and the weather; at its end, Free time and Pause, always in the same place. On a computer, it is the window's title bar, at the top (TitleBar.qml); on a phone, it is at the bottom. Narrow (a phone, a window as narrow), every button is its icon alone (LineButton.qml), its name said to screen readers and at a long press, and the sentence takes the rest of the line; cut short, a tap or a long press shows it whole, as the pointer resting on it does.

Required properties (whoever makes it must give them)

  • required property var window: The main window (main.qml), which opens what is asked of it. The moment it says is the window's.
  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property bool atTop: false: At the window's top: the pop-ups of its buttons open under it.
  • readonly property bool compact: line.window.compact: Icons alone: a phone, a window as narrow.
  • readonly property var moment: line.window.moment: Work time or quiet time, the day to close, the two pauses (main.qml).
  • readonly property var offer: line.window.offer: What is offered to close at its time: the work day, or the day ({kind, date, line, button}).
  • readonly property var pauses: line.window.pauses: What Free time and the pauses offer now: whether there is nothing, the usual end, the moved end, whether it can be kept.
  • readonly property string sentence: …: What it says: what just happened (Undo's line while it waits). Narrow, when nothing did, the day to close at its time, else what now is, whose button is then its icon.
  • readonly property alias weatherApplet: weatherApplet: For the documentation's pictures (main.qml's grabber).
  • readonly property alias modeMenu: modeMenu: The moment's menu (made the first time), for the window's pictures.

Functions

  • function openModeMenu(): The moment's menu: from its line, or Free time's right click or long press.
  • function freeMenu(): Free time's menu: back, the usual end kept, nothing at all; nothing opens when none applies.
  • function sayWhole(): The sentence whole, for three seconds: a tap on it cut short (and the pictures').

WeatherApplet

crates/sioul-app/qml/WeatherApplet.qml · based on LineButton

The weather in the status line, in one colour, a button of the line (LineButton.qml): now, then hour by hour for the next two hours, each as an icon and a temperature (now alone when the window is narrow), the line's room kept for the rest; a tip says what they are. On a click, the next four hours, then the parts of the days to come, and where the data comes from. Without a place, a quiet icon that offers to choose one.

Required properties (whoever makes it must give them)

  • required property var sioul

Properties

  • property bool below: false: Its pop-up under it, the line at the window's top (a computer's title bar); else above it.
  • readonly property var shown: …
  • readonly property var now: …
  • readonly property var hours: …: The next two hours beside now, when the window has room for them (a title bar shares its width with the window's buttons); the rest on a click.
  • property bool choosing: false
  • readonly property var places: …

Functions

  • function openForecast(): For the window's images: the forecast open, then as an image.
  • function grab(path)
  • function openPopup()

Pages

One for each place of the window.

AccountsPage

crates/sioul-app/qml/AccountsPage.qml · based on Item

Accounts, in three tabs. Yours: one card per address, each of its services (mail, calendars and contacts, Google) with its server, what its watcher last said, a switch to turn it off (kept, neither synced nor shown), and, for mail, what it is for, its shield, its rank, how far back and how often, your name and signature; "What this server offers" asks the server what else it has (mail beside calendars, a Nextcloud's apps). Adding one: mail (address, then the server found, then the password, tested before anything is kept), contacts and calendars on a CalDAV/CardDAV server, or Google (signed in on Google's page). Encryption: your keys. Who may reach you, and when, is Settings ▸ What reaches you's (ReachesTab.qml). Sites are not accounts: they are on the Sites page.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • readonly property var accounts: …
  • readonly property var found: …
  • readonly property var scouted: …
  • property string removing: ""
  • readonly property var identities: …: One card per address: its services together.
  • property var securityKeys: ({ cards: [] }): Your security keys, read again when keys change; what the setup says now; the key a lookup is for ("" for the one the setup read).
  • property var keySetup: …
  • property string lookingFor: ""
  • property string publishing: "": The key "Send it to keys.openpgp.org" is about, once its sentence is shown.
  • property var keys: ({ keys: [], without_key: [] }): Your OpenPGP keys and others', read again when they change.
  • property bool othersShown: false
  • property string importing: ""
  • property string lastForm: "mail": Which form a message from the backend is about: "mail", "dav" or "google".
  • property string againId: "": The mail form signs this account in again (Google's mail), rather than adding one.
  • property bool davServerShown: false
  • property bool googleStepsShown: false
  • readonly property bool googleBuiltIn: page.sioul.googleBuiltIn(): Sioul's own Google key in this build, and whether you would rather use yours.
  • property bool ownGoogleKey: false

Signals

  • signal passphraseWanted: The key's passphrase field, in its tab, takes the focus.

Functions

  • function openFirstSettings(): For the window's images: your accounts in view, or another tab.
  • function showTab(index)
  • function showGoogle(): The Google panel, its steps unfolded (for captures).
  • function addMailFor(address): Adding the mail of an address whose calendars are here, with another password: the form, filled.
  • function addDavFor(address)
  • function googleMailAgain(account): A mail account signed in with Google, signed in again (or given an app password instead): the mail form, its address, Google's two ways.
  • function askPassword(account): An account's password, given on this device (AccountPassword.qml): made the first time.
  • function lookFor(ident)
  • function askToSend(ident): "Send it to keys.openpgp.org": first what goes public, in a sentence; sent on "Send it" only.

Inline components (used inside this file)

  • component ServiceBlock: ColumnLayout: One service of an address: its server, its switch, what its watcher said; for mail, its own settings in full.

AgendaPage

crates/sioul-app/qml/AgendaPage.qml · based on Item

The agenda: what comes, from today, as a calm list of days; the week and the month one switch away. Nothing is late or overdue: the past is not shown unless you go back to it. An event opens on the right with its time and place; notes, repetition and guests are folded. Deleting waits ten seconds with "Undo"; a repeating event asks whether it is this time or all.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • readonly property var locale: Qt.locale(page.sioul.text("qt-locale")): Month and day names in Sioul's language, not the system's.
  • property string agendaText: "": Read while shown: a page out of sight keeps what it showed, and reads again when it comes back; results landing meanwhile cost nothing.
  • readonly property var shown: …
  • property string wanted: "": An event asked for by a link, outside the days shown: its days are read first.
  • property string mode: "agenda": "agenda", "day", "week", "month".
  • readonly property bool narrow: page.width < 600: A narrow screen (a phone): the title under the arrows, events on two lines.
  • readonly property var modes: ["agenda", "day", "week", "month"]
  • property var opened: null
  • property var reminder: ({}): When the open event is reminded, and its own choice (docs/reminders.md): {line, remind, writable}.
  • readonly property var reminds: …
  • property var menuTarget: null: The event the menu or the deletion asks about.
  • readonly property bool canGoBack: page.opened !== null: On a phone, the event open takes the page; Back closes it (main.qml).
  • property bool moreShown: false
  • readonly property var source: …: The open event, as what new things are tied to.
  • property date anchor: new Date()
  • property bool followsToday: true: Shown from today: the page follows the days as they turn.
  • property real readAt: 0: Read again at each five minutes' turn of the window's clock while shown, when shown again, when the app comes back (the clock jumps) and when the day turns: events over leave the list, what another device or the server changed comes in, the days shown from today follow midnight.
  • property string readOn: ""

Functions

  • function takeShown()
  • function showWanted(): Its details, when it is in the days shown.
  • function readReminder()
  • function back()
  • function today()
  • function iso(d)
  • function startOf(day, mode): The first day a mode shows around day: the day itself, its Monday, the Monday before the 1st.
  • function length(mode)
  • function readAgain()
  • function load()
  • function move(steps)
  • function title()
  • function newEvent(day): A new event on day: "2026-10-05", a date, or nothing for the day shown.
  • function fillEvent(text, from, to, how): For the window's tests.
  • function saveEvent()
  • function showEventRatings(): For the window's pictures: the event form's costs and gain in view.
  • function makeFrom(text, note, link): A new event made from something else: a message, a task.
  • function openEvent(key): An event by its file, from a link: its details, as from the agenda; outside the days shown, its days are shown first. Its form ("Edit") only when it cannot be found.

BudgetsPage

crates/sioul-app/qml/BudgetsPage.qml · based on Item

Budgets and reserves at a glance, itemized: each figure on its own line, the verdict apart with its icon. Then the mail about money, newest first: what is counted, what is the same payment told twice, and what waits for you.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string budgetsText: "": Read while shown: a page out of sight keeps what it showed, and reads again when it comes back; results landing meanwhile cost nothing.
  • readonly property var view: …
  • property string openId: "": A budget opened: its ledger and its balance.
  • property bool detailMade: false: The budget's detail, made the first time one opens.
  • readonly property var contracts: contractsLoader.item
  • readonly property var bank: bankLoader.item

Functions

  • function takeShown()
  • function startNew(): A movement added by hand, from "New".
  • function bankNow(): The sections below the first screen, made after it, without holding the window (a phone took over a second for the page); made at once when asked.
  • function contractsNow()
  • function showBank(): The bank accounts in view: for the window's images.
  • function openContract(id): A contract shown, or started from a mail.
  • function startContract(prefill)
  • function openFirst()
  • function moodColor(mood)
  • function moodIcon(mood)
  • function kindIcon(kind)

ContactsPage

crates/sioul-app/qml/ContactsPage.qml · based on Item

Contacts, names first: the list is names with one line under each, of one category when chosen; a contact opens on the right with its categories, its addresses and numbers, "Write" and "Call" next to each; the rest (postal addresses, birthday, notes, web sites) folded under "More". Editing happens in place; deleting waits ten seconds with "Undo". "Duplicates" opens in the place of a card. Right click on a name for what is not in view.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string contactsText: "": Read while shown: a page out of sight keeps what it showed, and reads again when it comes back; results landing meanwhile cost nothing.
  • readonly property var shown: …
  • property string openKey: ""
  • property var person: null
  • readonly property var source: …: The contact open, as what new things are tied to.
  • property bool editing: false
  • property bool duplicatesShown: false: The duplicates, in the place of a card: made the first time they are looked at.
  • property bool duplicatesMade: false
  • readonly property bool canGoBack: …: On a phone, the contact open (or its form, or the duplicates) takes the page; Back leaves the form as Cancel does, then closes what is open (main.qml).
  • property bool moreShown: false
  • property string problem: ""
  • readonly property var noMail: …: Their list, who they are to you and why (personOf): {who, from, choice ("" when their categories decide), said, own [an address or a number of theirs with a list of its own], choices [{value, label}]}.
  • property var mail: page.noMail
  • property bool cardMade: false: The card and the form are made when first needed: a list of names alone on a phone, most of the time.
  • property bool formMade: false
  • property bool mapShown: false: The map instead of the list: every contact placed, a pin opening its card.
  • property var places: …
  • readonly property var personPin: …: The open contact's first address, when placed.

Functions

  • function takeShown()
  • function back()
  • function moveTo(book, confirmed): Into another address book: asked first when it would not keep everything.
  • function open(key)
  • function readMail()
  • function labelText(label): What an address or a number is for ("work", "cell"), in your language; a kind the card writes and Sioul does not know ("other", "car") as written.
  • function formNow(): The contact form, made now if it was not.
  • function escaped(text): A card's text inside rich text: shown as written, never read as markup.
  • function addNumber(number): For the window's tests: the open contact gets another number, and is saved.
  • function openFirst(): The first contact, for the window's images.
  • function showDuplicates(): The duplicates in the place of a card, the card closed.
  • function duplicatesNow(): The duplicates' view, made now if it was not (the window's tests).
  • function startNew(number): A new card; number filled in when given (a call's line on the Porch, on a computer).
  • function reloadPlaces()

HealthPage

crates/sioul-app/qml/HealthPage.qml · based on Item

Health: the day at a glance, or its week (docs/health.md, "The page"). A day: its meals, naps, night and doses down the hours, and beside them (under them on a phone) the same as a list, the day's events and planned steps faded behind, for context. Each block is a tap away from what can change it, that day only: a quarter of an hour later, another time, other times, not that day, taken out; and one can be added for that day alone. The week: seven columns, the same blocks and the same taps, to fix ahead a day that will differ. Today's doses say whether they are marked taken, and the doubt when another device may know: never "not taken". The medicines and the prescriptions are the page's content, after the day: under its list, or in a column of their own on a wide window, which the week keeps too (MedicinesSection.qml); their forms open from there. What is set once (the usual meals and night, the pauses, where the errands go) is behind the ⚙. Nothing counts what was not done.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var shown: …: The page's view (health::page): the week of the day shown, and what only today says.
  • property var medicines: []: The medicines, the prescriptions and the week's days, taken from the view only when they change: the view comes again each minute, and their rows and timelines stay as they are.
  • property var prescriptions: []
  • property var weekDays: []
  • property string mode: "day": "day" or "week"; the week made the first time it is asked for.
  • property bool weekMade: false
  • property string wanted: page.iso(new Date()): The day asked for ("2026-10-07"); the day shown is the view's, once it has it.
  • property var day: null
  • property bool followsToday: true: Shown from today: the page follows the days as they turn.
  • property string hovered: "": A block or a dose under the pointer, or chosen ("date|key"): its row and its block light up together.
  • property string chosen: ""
  • property string reveal: "": A row to bring into view, chosen in the timeline (its key).
  • property bool menuOpen: false: A block's menu open (the window's pictures take it).
  • property bool readable: false: The timeline opened readable by a long press, a block a finger can take (HealthTimeline.qml): on a phone it takes the page, the list behind it, until "Done" or Back.
  • property bool professionalOpen: false: What a doctor or a pharmacist is shown, open over the window (ShowMedicines.qml).
  • readonly property bool canGoBack: page.readable || page.professionalOpen: Back closes it first, then folds the readable timeline.
  • readonly property bool narrow: page.width < 760: A phone, or a window as narrow: the list under the day, the header on two lines.
  • readonly property bool wide: page.width >= 1400: A window wide enough for a third column: the medicines and prescriptions beside the day (and the week); else under the day's list.
  • readonly property int sideWidth: …
  • readonly property var locale: Qt.locale(page.sioul.text("qt-locale"))
  • readonly property bool onToday: …
  • readonly property bool earlierAllowed: …

Signals

  • signal revealed
  • signal medicinesWanted: The medicines and the prescriptions brought into view: under the day's list, scrolled to; in their own column, already there (the window's pictures).

Functions

  • function back()
  • function showReadable(on): For the window's pictures: opened readable, as a long press opens it.
  • function iso(d)
  • function showNeeds(): Where the usual meals, naps and night are set: the settings, opened there (the Porch's card, Settings ▸ Hours, the window's pictures).
  • function showWeek(): The week, or the day, in view; the settings, for their picture (the window's pictures).
  • function showDay()
  • function settingsPanel()
  • function closeSettings()
  • function showMedicines()
  • function showMenu(key): A block of the day shown: its menu, or its form ("move", "times"); what is open; all closed.
  • function showChange(key, mode)
  • function openPopup()
  • function closePopups()
  • function editMedicine(medicine): A medicine or a prescription, new (null) or changed: its form, made the first time. The prescriptions it can come with as they are now: the view coming again each minute leaves an open form alone.
  • function editPrescription(prescription)
  • function showProfessional(id): A prescription's medicines (its id), or all those taken now (""), read-only over the whole window, for a doctor or a pharmacist.
  • function professionalView(): The view, for the window's pictures; closed.
  • function closeProfessional()
  • function fetched(id): Fetched at the pharmacy today: the next visit is counted from today.
  • function reload(): The week of the day asked for, made again off the window's thread (healthView).
  • function takeView()
  • function pick(): The day asked for, once the view has its week; until then the one shown stays. The same as before, it stays as it is: its timeline and its rows are not made again each minute for nothing.
  • function goTo(date)
  • function earliest(): Past days are as they were: a week back at most.
  • function move(steps): A day, or a week, earlier or later.
  • function setMode(mode)
  • function title()
  • function change(date, key, action, more): A day's block changed, that day only (health::change_need): the page and the plan follow.
  • function rowOf(segment): A block's day and row: those of the week shown, else (a night ending the week's first morning, the week before's) what the timeline knows.
  • function openMenu(day, item, under): What can change a block that day: under under (its ⋯), else where the pointer or the finger is (window.menuAt). Nothing for a past one, nor a dose; but a night begun on a past day and not over (after midnight), its alarm at waking alone, which the core takes until it rings (alarm_open).
  • function tapped(segment, at): A block or a dose tapped in the timeline: chosen, its row shown; in the week, a block's menu at once, a dose's day opened.
  • function held(segment, at)
  • function follow(): Another day when the clock turns past midnight, if the page showed today.

Inline components (used inside this file)

  • component ModeSwitch: Row: Day, Week.
  • component SettingsGear: ToolButton: The page's settings: what is set once (SettingsButton's look).
  • component Medicines: MedicinesSection: The medicines and the prescriptions, as the page lists them; their forms are the page's.

MailPage

crates/sioul-app/qml/MailPage.qml · based on Item

The mail client, for when you choose to look: the accounts and their folders on the left, the main ones in view and the others folded; a folder's last two weeks in the middle, without previews, a small dot for the unread; a message on the right, the folders folding away while you read. No counts, no badges. Right click on a message for what is not in view. "More…" beside the search opens the search by conditions in the folders' place (MailSearch.qml): its results in the same list, dragged onto folders as any.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string mailAccountsText: "": Read while shown: a page out of sight keeps what it showed, and reads again when it comes back; results landing meanwhile cost nothing.
  • readonly property var accounts: …
  • property string mailFolderText: ""
  • readonly property var shown: …
  • property string draftsText: ""
  • readonly property var drafts: …
  • property string account: ""
  • property string folder: ""
  • property bool draftsShown: false: Sioul's own drafts, instead of a folder.
  • property bool all: false
  • property string query: ""
  • property string openKey: "": The message being read, by its file, and its row.
  • property bool readerMade: false: Whether a message was opened since the page was made: its reader is made then.
  • property bool foldersShown: false: On a phone, one at a time: the folders (asked for), the list, the message; Back goes the other way (main.qml).
  • readonly property bool allResting: …: Every account resting (quiet time) and none chosen: no list, the line saying so.
  • readonly property bool canGoBack: …
  • readonly property bool searchBelow: …: The search on a line of its own, under the folder's name: on a phone, and beside an open message, where the list's column is narrow; on one line there, "Plus de critères…" and "Temps réel" pushed the row under the reader, the name and the dates cut.
  • readonly property var opened: findItem(page.openKey)
  • property var unfolded: ({}): Accounts unfolded by hand; the first one is unfolded at first.
  • property var moreShown: ({})
  • property var selected: ({}): Messages chosen with Ctrl or Shift: acted on together, or dragged onto a folder.
  • property int anchorIndex: -1
  • readonly property var selectedKeys: Object.keys(page.selected)
  • property var threadsOpen: ({}): Conversations unfolded, by their first message.
  • property bool dragging: false: Messages being dragged onto a folder.
  • property var dragKeys: []
  • property bool searchOpen: false: The search by conditions: open (its column in the folders' place, what it finds in the list), made once asked for; on a phone, its fields or its results, one at a time.
  • property bool searchMade: false
  • property bool searchFormShown: false
  • property string searchText: ""
  • readonly property var found: …
  • readonly property var listItems: …: The list's rows: the folder's, or what the search found.
  • readonly property string listRole: …: What the rows are in: a folder's purpose ("trash"…); none for a search's, each row its own.
  • property string bringing: "": A message being brought from its server, opened once here.
  • property bool choosing: false: A selection begun from a row's menu (on a touch screen, a long press): a tap then chooses, as Ctrl+click does.
  • property string moveFromAccount: "": Where "Move to…" leaves out: the folder its messages are in, when they share one.
  • property string moveFromFolder: ""
  • property bool fromLink: false: A message opened from a link: it stays open whatever folder is shown.

Functions

  • function takeShown()
  • function back()
  • function rowShown(item)
  • function clickRow(index, key, modifiers): A click: alone, it opens the message; with Ctrl (or once a selection was begun from a row's menu), it adds it to the selection or takes it out; with Shift, everything from the last one clicked. A message the search found on its server only is brought here first.
  • function beginChoosing(key): A row's menu, "Select": the selection begins with it; then a tap chooses.
  • function clearSelection()
  • function selectAll()
  • function startDrag(key): What a drag carries: the selection when the row is in it, else the row alone.
  • function endDrag()
  • function dropOn(account, folder)
  • function askMove(keys): "Move to…" for keys: the folder they are in left out of the choices, when they share one.
  • function chooseFirst(n): For the window's pictures: the first n rows chosen, as a long press, "Select", then a tap would.
  • function holdOver(keys, role): For the window's pictures: messages held over the first folder of a purpose ("archive"), as a drag holds them; never let go there.
  • function letGo(): The drag held for a picture ends without a drop: nothing moves.
  • function closeMove()
  • function findNamed(item, prefix)
  • function selectBySubjects(words): For the window's tests: messages chosen by words of their subjects, as Ctrl+click would.
  • function moveSelection(account, folder)
  • function unfoldConversations()
  • function actOnSelection(action)
  • function sameMessage(a, b): A message keeps the start of its file name when reading or flagging it renames it; one seen on its server only is known by its whole key.
  • function findItem(key)
  • function openSearch(): The search opens in the folders' place, with what the quick search held.
  • function searchWith(conditions, any): The same, its conditions given (the window's pictures): [{field, test, value, until}].
  • function closeSearch(): "Clear": the folder again.
  • function runSearch(now): A condition changed: the mail here at once, after a short pause in typing.
  • function openFolder(account, folder)
  • function isUnfolded(index, id): The first account open, unless you chose; in quiet time, the first of yours.
  • function say(line): What went wrong, in the status line; nothing when all went well.
  • function toggle(map, id, value)
  • function openMessage(key)
  • function openSubject(text): A message by its subject, for the window's tests.
  • function openFirst(): The first message of the folder, for the window's images.
  • function showAttachments(): The message open with its attachments unfolded and in view, for the window's images.
  • function openSettings(open): The page's settings, open or not, scrolled to one of them, and their picture: for the window's images.
  • function scrollSettings(key)
  • function grabSettings(path)

Inline components (used inside this file)

  • component SearchField: TextField: The folder's search: in the title's row, or under it on a phone.
  • component MoreButton: Button: The search by conditions: a word, not an icon, its tip saying what it offers.

NotesPage

crates/sioul-app/qml/NotesPage.qml · based on Item

Notes: your folder of Markdown files, read as Obsidian reads a vault. Search first, folders folded: no filing asked. A note opens read, its links followed with a click, wherever they lead (another note, a task, a message); editing is one switch away. On the side: what is tied to it, and its unticked lines, each one click from becoming a task.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • readonly property bool narrow: page.width < 640: A narrow screen (a phone): what is tied to a note goes under it.
  • property string notesText: "": Read while shown: a page out of sight keeps what it showed, and reads again when it comes back; results landing meanwhile cost nothing.
  • readonly property var shown: …
  • property string path: ""
  • property var note: null
  • readonly property var source: …: The note open, as what new things are tied to.
  • property bool editing: false
  • property bool dirty: false
  • property bool newer: false: A newer version of the note open came through the sharing while you typed in it: said, never put over your text.
  • readonly property bool canGoBack: page.note !== null: On a phone, the note open takes the page; Back keeps it (saved) and closes it (main.qml).
  • readonly property string kind: page.note ? page.note.kind : "text": A picture, a PDF, a sound: read or played, never edited here.
  • property var openFolders: ({})
  • property bool recentOpen: page.sioul.viewFlag("notes-recent"): What changed lately: folded until opened, as you left it.
  • property string query: ""
  • property string pending: "": A memo just recorded, opened once the notes are read again.
  • readonly property var rows: …: What the left column lists: when searching, what was found; else what changed lately, then every note, as one list or as a tree of folders.

Functions

  • function takeShown()
  • function back()
  • function tree(): Folders first, then the notes in them, each folder folded until opened.
  • function open(path)
  • function fitted(html, room): Pictures in a note: never wider than the column, their line not spaced.
  • function toggleFolder(row): A folder folded or unfolded: the list stays where it was; unfolded, its notes come into view, its own line kept on screen.
  • function unfold(path): A folder of the tree opened, for the window's images.
  • function scrollList(pixels): The list scrolled down by pixels (for the window's images).
  • function typeAtEnd(words): Words typed at the end of the note being edited, for the window's images.
  • function startNew(): The note changed last, for the window's images. A new note: its name asked first.
  • function openFirst()
  • function reload()
  • function save()
  • function resolve(href): "../plan.md#october" from "admin/letters.md" → "plan.md".
  • function follow(href): A link of the note: another note, something of Sioul, a file of the notes folder by its place from this note, or a page elsewhere. Elsewhere is web pages, addresses, numbers and this computer's own files only: a link in a note made from a mail must not reach a shared folder (file://server/…, smb:) nor start a program through one of the system's protocols.

PapersPage

crates/sioul-app/qml/PapersPage.qml · based on Item

The papers wallet: the papers asked again and again, by family (identity, health, home, money, warranties), each with where it stands in words (valid until, time to renew, older than what is usually asked), its file one click away, its renewal planned as a task. No red, no count.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var shown: …
  • property string problem: ""
  • readonly property bool narrow: page.width < 560: A narrow screen (a phone): a paper's buttons under it.
  • property string wanted: "": The paper to show once the page is read: its id.
  • property alias dialog: paperDialog

Functions

  • function reload()
  • function startNew(): A new paper, from nothing.
  • function startFrom(file, title, kind): A paper made from a file kept (an attachment): what it is, asked.
  • function open(id): A paper of the wallet, its form open.

ParametersPage

crates/sioul-app/qml/ParametersPage.qml · based on Item

What belongs to Sioul as a whole rather than to one page: language and colours, working hours and days off, what reaches you and when (ReachesTab.qml), the words Sioul looks for (WordsTab.qml), reminders, the pauses, on a phone what sets it up (PhoneSetup.qml), your folder and sharing, invoices. Each setting says in a sentence what it changes and is saved at once.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var rows: []
  • property string problem: ""
  • readonly property var share: shareLoader.item: The sharing panel, made the first time its tab is shown, then kept.
  • property bool shareMade: page.section === "files"
  • readonly property var sections: …: One tab at a time: how it looks, the hours, what reaches you, the words, reminders, the pauses; on a phone, what sets it up; your folder and sharing, invoices; what AI agents may use (each project closed to them until opened).
  • property string section: "look"
  • readonly property var shown: …: What reaches you and the words draw their own rows (ReachesTab.qml, WordsTab.qml): none listed here.
  • property string reachesAsked: "": A view of What reaches you asked for before its tab was made: shown once it is.
  • property string wordsAsked: "": A list of the words asked for ("words.voicemail.operators") before its tab was made: its line opened once it is.

Signals

  • signal tryPause: The pause's screen tried from its setup (main.qml shows it, nothing held).

Functions

  • function reload()
  • function save(key, value, shown): shown: the value the row showed: a list's change is set over the files as they are now.
  • function scrollBy(part): Further down by a part of the page.
  • function showReaches(key): What reaches you at one of its views ("attention.dnd"), times ("attention.pause") or channels ("attention.calls"); the older screens' keys lead there too ("notify", "dnd.people", "calls").
  • function showWords(): The line holding a list of the words, opened.
  • function showAsked()
  • function showSetting(key): One setting in view: where the Porch sends you for the hours. Once the page is laid out, which takes a moment after it shows.
  • function toEnd(): Sharing, at the end of the files' tab.

PorchPage

crates/sioul-app/qml/PorchPage.qml · based on Item

The Porch: verified codes on top, whatever the time; then, inside an admin window, a few sentences and the lanes; outside, only when it opens. A message opens on the right, in the Reader.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string porchText: "": Read while shown: a page out of sight keeps what it showed, and reads again when it comes back; results landing meanwhile cost nothing.
  • readonly property var view: …
  • property var helpShown: ({}): Lanes whose "?" is open, by key.
  • property var siteNotices: …: What sites notified, kept for the Porch.
  • readonly property var doses: …: The doses (docs/health.md, "On the Porch"), made off the window's thread (missedView, health::missed): today's from their time on, not marked yet, reminded or not; and those due while Sioul was closed, asked about. Whatever the hours: doses are not mail.
  • readonly property var dueDoses: page.doses.due || []
  • readonly property var missedDoses: page.doses.closed || []
  • property string openKey: "": The message being read, by its file; it stays open across refreshes.
  • readonly property var opened: findItem(openKey)
  • readonly property bool canGoBack: page.openKey !== "": On a phone, the message open takes the page; Back closes it (main.qml).
  • property string cardKey: "": A message tapped on the phone's home screen card (homecard.rs, main.qml's "card-mail"): opened here, in the Reader, once the Porch is read; in Mail, by its file, when the Porch no longer shows it (filed, moved).
  • property var unfolded: ({}): Lanes folded or unfolded by hand, by key; the others keep their default.

Functions

  • function takeShown()
  • function reloadDoses()
  • function back()
  • function openMessage(key)
  • function lookForCard()
  • function sameMessage(a, b): A message keeps the start of its file name when reading or flagging it renames it.
  • function findItem(key)
  • function openSettings(open): How mail is sorted, every lane: for the window's images.
  • function grabSettings(path)
  • function openSpam(word): A message Sioul's own spam filter put a word beside ("" any), opened with why it is here unfolded: for the window's images.
  • function showReasons()
  • function scrollToLane(key): A lane at the top of the list (the window's images).
  • function openFirst(): The first message of the first lane, for the window's images.
  • function openLane(key): A lane opened, as its title opens it (the window's images).
  • function isFolded(lane)
  • function toggle(lane)
  • function trustIcon(level)
  • function toggleHelp(key)
  • function countWords(n): A small number in words ("three"), as the translations write them, digits beyond twelve: no counts that read as badges (docs/design.md).
  • function laneIcon(key)

ProjectsPage

crates/sioul-app/qml/ProjectsPage.qml · based on Item

Projects, the umbrella over everything else. On the left, each with its open tasks and the time left to bill; on the right, the one open: what is coming, then what happened, on one line of time; its tasks one click away as a board, a list or a calendar; its time and its invoices.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var rows: []
  • property bool routesShown: false: The mail that belongs to the one open: its routes, folded until asked.
  • property var routes: []
  • property bool anyway: false: Quiet time: only your own projects, unless you ask for the others; while you sleep, none.
  • readonly property bool resting: page.window.moment.quiet && !page.anyway
  • readonly property bool rest: …
  • readonly property var listed: …
  • property string openId: ""
  • readonly property bool canGoBack: page.openId !== "": On a phone, the project open takes the page; Back closes it (main.qml).
  • property var shown: null
  • property string problem: ""
  • property bool invoicesElsewhere: false: Invoices are numbered on another computer: offered here, on purpose.

Functions

  • function back()
  • function reload()
  • function saveRoutes(key, value, shown): A setting of the project's own (its routes, whether AI agents may read it), saved at once. shown: the routes the row showed: the change is set over the file as it is now.
  • function open(id)
  • function startNew(): A new project: its form.
  • function editOpen(): The open project's form (its Edit button); returns the form.
  • function openFirst()
  • function money(value): An amount as the core says amounts: digits in your language's way, the currency where it puts it ("€62.50", "62,50 €"), cents only when there are some.
  • function makeInvoice(): The invoice of the hours not billed yet, printed where invoices go, then shown.
  • function printInvoice(made)

SitesPage

crates/sioul-app/qml/SitesPage.qml · based on Item

Sites kept in Sioul: secure mailboxes, chats, a dating site. Pinned on the left, one open on the right, logged in once: the profile keeps cookies and the files sites download to show themselves. Their notifications are always accepted, then wait for the Porch, unless the site is in real time; calls and video work (microphone, camera, sharing the screen). A site can be silenced; a chat's real time is one tick away, always in view. Logins come from Bitwarden when you ask.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var sites: []
  • property string openId: ""
  • property bool narrow: page.sioul.viewFlag("sites-narrow"): The column of sites folded to their icons, as you left it.
  • property alias bitwardenUnlock: unlock: For the window's images: Bitwarden's dialog, the page it asks a key from, the chooser.
  • property alias bitwardenKeyView: unlock.keyView
  • property alias loginChooser: chooser
  • property alias addSiteDialog: adding
  • property alias addSiteFind: find.text
  • property string afterUnlock: "fill": What follows Bitwarden's unlocking: the login filled ("fill") or chosen ("choose").
  • property var visited: ({}): Sites opened this session stay loaded: going back to one does not reload it.
  • property string problem: ""
  • property var siteViews: ({}): Each site's view, once made, by its id.
  • readonly property int closeWait: 2000: How long a page may take to close: Chromium itself gives one that does not answer half a second for its beforeunload, as much for its unload.
  • property var leaving: ({}): The sites taken out of Sioul whose pages are closing, by id: their views go once closed.
  • property var popups: []: The pop-ups open (openPopup): their pages are closed with the sites'.
  • readonly property var webauthnFix: …: In every page, before its own scripts: Qt 6.10–6.11 never answers PublicKeyCredential.getClientCapabilities(), and sites asking for a security key wait for it forever (QTBUG-149575); without it they ask the key directly. Injection point 2: DocumentCreation; world 0: the page's.
  • readonly property string callsScript: page.sioul.callsScript(): Calls take the camera, microphone and speaker you chose, by their names (the browser's own ids are each site's), and change them during a call (src/calls.js, docs/sites.md). The names go only to sites allowed a microphone or a camera, which can read them from their browser anyway; inside the script they stay out of the page's reach. A change comes to the pages open as an event ("sioul-devices"), in every frame.
  • readonly property string callToken: …: A secret of this run, which marks what the calls script says in the console: a page cannot write in its name. Qt's JavaScript draws Math.random from QRandomGenerator::global(), seeded by the system.
  • property bool chatsCovered: page.sioul.chatsCovered(): Chats covered: their daily time used (Health page), until it comes back.
  • readonly property var colourSettings: …: colour: Settings ▸ Display's two lines, for every site and pop-up: the screen's own colours, and calmer colours (cpp/screencolours.cpp, docs/colour.md).
  • readonly property var opened: …
  • property string menuId: "": The site the site menu acts on: the open one (⋮), or one right-clicked in the list.
  • readonly property var menuSite: …
  • readonly property int menuIndex: …
  • readonly property var kinds: …: What a site is, as it behaves (sioul_core::sites::TYPES); your categories come on top.
  • readonly property var kindIcons: …
  • property string areaFilter: "": The list filtered, each way at once: what a site is for, its type, one of your categories; "" for any.
  • property string kindFilter: ""
  • property string categoryFilter: ""
  • readonly property var categories: …: The categories your sites have, by name.
  • readonly property string filterWords: …
  • property var presetTree: []: The usual sites, as a menu: countries, their groups, the sites.
  • property alias presetsMenu: presetsMenu
  • property alias siteMenu: siteMenu
  • property alias devicesDialog: devicesDialog
  • property alias callPanel: callPanel
  • property alias filterMenu: filterMenu
  • property bool byCategory: page.sioul.viewFlag("sites-by-category"): The list by category, or in your own order, as you left it.
  • property bool laterShown: false: The sites for other hours (docs/areas.md), shown when asked.
  • readonly property var rows: …: The column's rows: the sites for these hours, then one line folding the others; each category named once when sorted by it.
  • readonly property int openedIndex: …
  • property var callDevices: …: The camera, microphone and speaker calls use, by their names: given to the pages of sites allowed a device (webFixesFor, for the pages to come), and to every frame of those open now, pop-ups too: calls in progress change at once.
  • property var calls: ({}): The sites with a call now, by id: how many of their pages and frames have one (src/calls.js says "call" and "end"); a pop-up counts its own (callCount), gone with it. The call button shows then.
  • readonly property string fillScript: …: Sets the password field and the name field before it, as typing would.
  • property WebEngineProfile profile: null
  • readonly property bool profileWanted: page.sites.some(s => page.alive(s))
  • property MediaDevices mediaDevices: null: The devices of calls: the system's list of cameras, microphones and speakers, the same on every computer; "The system's own" when unsaid. A device chosen but not plugged in now stays named, at the end of its list. Known from a site's first call, or from the first look at the list: Qt Multimedia, started for it, loads FFmpeg, makes a graphics context of its own and reaches the sound server (some 60 MB in all, in the sandbox without a graphics card where it was measured).
  • readonly property var filterLines: …: What the list shows: what a site is for, its type, one of your categories. One list of lines: a Repeater's lines land out of order in a menu once their model changes.

Signals

  • signal sitesClosed(): Sioul quitting: every page closed (closeAll), for the program to end (cpp/webengine.cpp).

Functions

  • function devicesFor(site)
  • function webFixesFor(site): A page's scripts, for a site (null: a page of no site, the vault's).
  • function openPopup(request, site): A sign-in window, a call window: each in a window of its own, on the sites' profile, so it stays tied to the page that opened it (a sign-in answers it there). It may use what the site that opened it may, kept as it was then: not the switches of the site in front at the time.
  • function closeAll(): Sioul quits: every site's page closed as a browser closes its tabs, before Qt WebEngine shuts down. Its beforeunload, pagehide and unload run: some sites keep their login only in the open page and write it back to their storage then (Discord takes its token out of localStorage once loaded, and puts it back as the page goes); a page destroyed without them loses it, and the site asks to log in again. The pop-ups' pages too. Returns how many are still closing; sitesClosed says when none is (cpp/webengine.cpp waits for it, two seconds at most).
  • function popupOpen(popup): A pop-up not gone yet (one gone reads as null, or as nothing).
  • function showPresets()
  • function showFilters()
  • function pinAll(rows): Usual sites pinned: one, or a whole group; those already here stay as they are.
  • function reload()
  • function keepViews()
  • function dropView(id): A site taken out of Sioul: its page closed first, as a browser closes a tab (its login stays in the profile, whole), then its view goes.
  • function keepPermissions(): Notifications granted to every site before it asks, and kept: Sioul takes them and gathers them itself, so a site never asks again. A microphone, camera or screen once allowed is forgotten when its switch is off.
  • function setCallDevice(which, name)
  • function everyFrame(view, script): A script run in each frame of a view, in the page's world: a call may be in a frame of another site (an embedded room), which the view's own runJavaScript never reaches.
  • function calling(id)
  • function heard(site, message, popup): What a page's console says: the calls script's lines carry this run's token; a device it could not open is said in the line above the site, with the name Sioul has, never words from the page. popup: the pop-up it comes from, or none.
  • function open(id)
  • function hostOf(url): "https://app.element.io/#/room" → "app.element.io".
  • function siteOf(origin): The site a notification comes from: the same host, or the same domain.
  • function alive(site)
  • function viewOf(id)
  • function fillLogin(): The login Bitwarden keeps for the open site, written into its form: the only one at once, unless another was chosen there last; else chosen in the chooser, found by site and by user name.
  • function chooseLogin(): Any login of the vault, chosen in the list.
  • function vaultOpen(then): Whether the vault is open; else its dialog, then then ("fill" or "choose").
  • function fillChosen(item): One login of the vault, by its id, written into the open site's form.
  • function fillWith(view, user, password, code): Values through JSON, so nothing in them can change the script.
  • function makeProfile(): The profile, from its prototype, complete once made (it lives with the page); no view exists before it.
  • function knowDevices()
  • function filterOf(what)
  • function setFilter(what, value)
  • function shareScreen(request, site): Sharing a screen in a call, from a site's page or its call window: you choose which, or none; only where the site's switch allows it.
  • function shareChosen(screen, index): What a call shares, chosen: a screen (screen) or a window, by its place in the list.

TasksPage

crates/sioul-app/qml/TasksPage.qml · based on Item

Tasks. "Now" first: the one next step, picked by the plan, with why, and the one after it; nothing else unless asked. The list, the board and the timeline are one switch away. A line at the top takes a new task in one sentence; "New task" beside it opens the full form, as New ▸ A task and Add ▾ ▸ A task do. Nothing is overdue: a date asked is time left; a day that passed moves the task forward instead (docs/tasks.md).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string tasksText: "": Read while shown: a page out of sight keeps what it showed, and reads again when it comes back; results landing meanwhile cost nothing.
  • readonly property var shown: …
  • readonly property var panel: panelLoader.item: For the window's images: the task open.
  • property bool panelMade: false: The task's panel, made the first time a task opens (a form of many fields), then kept.
  • property bool making: false: A new task's form open in the panel, not made yet.
  • readonly property bool panelOpen: page.opened !== "" || page.making: The panel shows: a task, or a new one's form.
  • property alias routines: routinesDialog
  • property string mode: "now": "now", "day", "list", "board", "timeline".
  • property var made: ({ now: true }): The views made so far: each the first time it is shown; "now" not while the rest cover hides it.
  • property bool nowMade: false
  • property string opened: ""
  • readonly property bool canGoBack: page.panelOpen: On a phone, the task open (or a new one's form) takes the page; Back closes it (main.qml).
  • property string twoOffered: "": "I dread it", "It is boring": two minutes offered for this task, until it changes.
  • property bool othersShown: false
  • property bool startedShown: false
  • property bool doneShown: false
  • property bool joyShown: false
  • property string by: "project"
  • property bool showDone: false
  • property string query: ""
  • property string projectFilter: ""
  • readonly property bool narrow: page.width < 640: A narrow screen (a phone): the board's columns one under the other.
  • readonly property real listLeast: 480: The open task's width beside the list, with no cap of its own (docs/qt-quick.md, "An editing card's width"): its natural width (its fields at a readable line, its tiles side by side) while the list keeps listLeast pixels, where its rows still hold on one line (the day's weather and its three choices, in French), or half the room in a narrower window. On a phone the list is hidden and the panel takes the whole width.
  • readonly property real panelWidth: …
  • readonly property int halfFlow: …
  • readonly property string kindFilter: …: One kind, one category; "" for all. Kept between sessions, as the choices above.
  • readonly property string categoryFilter: …
  • property bool restored: false
  • property bool anyway: false: Asleep: no tasks, unless you ask; the next visit asks again.
  • readonly property bool rest: …
  • property var dragging: null: A card dragged on the board, and where.
  • property point dragPoint: Qt.point(0, 0)

Functions

  • function takeShown()
  • function back()
  • function open(uid)
  • function closePanel(): The panel closed; a new task's form with a title typed makes the task first.
  • function startNew(source): A new task: the panel's full form, its title first; from source (a card's Add ▾ ▸ A task), its title and its tie given. Asleep, the page shows anyway, as its own button does.
  • function leaveForm(): A new task's form left: a title typed makes the task, as leaving its field does.
  • function showProject(id, mode): One project's tasks, from its page.
  • function apply()
  • function tick(task)
  • function focusOn(uid, minutes)
  • function stopForToday(): "Done for today": the end of the work day's review first (DayReview.qml, docs/reviews.md); its "Close the work day" closes the day as this button always did, then showClosing says where everything went.
  • function showClosing(closing): The day closed: the screen after it says where everything went.
  • function grabStop(path): For the window's tests.
  • function openSettings(open): For the window's tests: the settings, open or closed, and as an image.
  • function grabSettings(path)
  • function closeStop(): For the window's tests: the screen closed.
  • function openDetails(uid): A task's form with its folded fields shown (for captures): a task opens on its details.
  • function openFirst()
  • function showPanelDetails(): For the window's pictures: the open task's form, its folded fields shown.

TextsPage

crates/sioul-app/qml/TextsPage.qml · based on Item

Texts (« SMS »), on a computer (docs/texts.md): a page of the window, laid out as Mail is. Your phone's texts, read there and carried sealed by the sharing's part "Texts", and those you write here for your phone to send. On the left, the conversations, newest first, people by your address books' names, their last words, when, and "a draft waits" where an AI agent left one; over them, the search through every text's words. On the right, the conversation chosen, as a thread: the whole history in time order, each day said once, yours on the right and theirs on the left, quietly; a multimedia message's pictures shown and its other media opened or saved (each kept sealed here; the copies opened for the page deleted when it goes out of sight); a text deleted on your phone said so; what became of each text you sent, in words, never in red: waiting for your phone, sent at, delivered at (only when your carrier says so), not sent and why, expired, may not have been sent; and "Send again", which makes a new text. Under it, an AI agent's drafts, then writing, with how many texts it takes. Never sent from here: short numbers, several people at once, pictures. In a narrow window, one at a time, as Mail: the list, then the conversation, and Back. A phone has its own SMS app: no page there (main.qml).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string listedText: "": texts.rs's view, as its text: compared before it is taken, so a list that did not change keeps its place. {can, phone: {id, name, shared, said}, conversations, said, never, empty}.
  • readonly property var listed: …
  • readonly property var rows: page.listed.conversations || []
  • property string openId: "": The conversation open, by its id ("+33199001234"), and texts.rs's conversation for it: {id, title, messages, drafts, can_write, group}.
  • property string talkText: ""
  • readonly property var talk: …
  • readonly property var messages: …
  • property string query: "": The search through the texts' words, and what was said of the last action.
  • property string said: ""
  • property var counted: ({ parts: 0, said: "" })
  • property bool atEnd: true: The thread held at its end while its rows take their heights, until you scroll back.
  • property bool keyed: false: The list moved through with the keyboard: its ring shows; a click hides it.
  • readonly property bool canGoBack: page.openId !== "": In a narrow window, one at a time: the list, the conversation; Back goes the other way (main.qml).

Functions

  • function back()
  • function act(verb, args)
  • function reload(): Read while shown, as Mail. What did not change keeps its place; a thread read to its end stays at its end as a new text comes.
  • function select(id): A conversation opened: from the list, the Porch's Text back, a person's sheet (window.openTexts). Its newest text in view.
  • function close(): Back to the list alone.
  • function search(words): The search through the texts' words (also the window's pictures).
  • function useDraft(index): An AI agent's draft (the conversation's drafts, by its place): its words in the box, the draft taken away; sending stays the Send button's.
  • function save(part): A media file opened for the page, saved where you choose.
  • function showNotSetUp(): For the window's pictures: the page as it is before texts are read on this computer.
  • function scrollBack(): The thread a screen further back (the window's pictures, PageUp).

Inline components (used inside this file)

  • component SearchField: TextField: The search through the texts' words: in the title's row, or under it in a narrow window.

TimePage

crates/sioul-app/qml/TimePage.qml · based on Item

Time spent: a week, a month or a year, as bars stacked by project, the hours of each project and what is left to bill, then each stretch of time, newest first. Time is noted by hand here too; a click changes any stretch not billed (its start, its end, what, its task), its menu takes it out.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string period: "week": "week", "month", "year".
  • property date anchor: new Date()
  • property string project: ""
  • property var shown: null
  • property var projects: []
  • property string problem: ""
  • readonly property var periods: ["week", "month", "year"]
  • property bool anyway: false: Quiet time: time noted for work waits behind a word, unless you ask.
  • readonly property bool resting: page.window.moment.quiet && !page.anyway
  • readonly property bool narrow: page.width < 600: A narrow screen (a phone): the title and the choices under the arrows, each stretch of time on two lines.
  • property alias changing: timeDialog: For the window's tests: the first stretch, being changed.

Functions

  • function changeFirst()
  • function iso(d)
  • function startNew(): Time spent, noted by hand.
  • function reload()
  • function move(steps)
  • function colour(index)
  • function barTip(bar): A bar's day (or month, over a year) in your language, and its length as the core writes lengths: "45 min", "2 h", "2 h 05" (timereport::duration).

Inline components (used inside this file)

  • component PeriodChoice: PlainComboBox: The period and the project shown: beside the title, or under it on a phone.
  • component ProjectChoice: PlainComboBox

Parts of pages

The sections, rows, cards, timelines and forms that pages are made of.

AttentionGrid

crates/sioul-app/qml/AttentionGrid.qml · based on ColumnLayout

The matrix of what reaches you, or a part of it (Settings ▸ What reaches you, ReachesTab.qml; the matrix is sioul_core::attention): the rows down, in their groups (a channel's people, or Sioul's own kinds), the seven times and the two layers across, a mark in each cell (LevelMark.qml). A press on a mark opens its choices in words; a fixed mark, greyed, says why; a cell changed from As Sioul does now carries a dot. On a screen too narrow for a row, its name stands above its marks, and the times' names stand upright when even they are too wide (a phone shows lists instead: ReachesTab.qml). Each choice is saved at once, the row whole ("attention.<row>").

Required properties (whoever makes it must give them)

  • required property var setting: The setting it shows, as the core gives it, its matrix in grid: {columns, marks, rows}.
  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string prefix: "attention.": Where a row is saved: "attention." and its id ("attention.mail.safe").
  • readonly property bool anyFixed: …: The legend's "fixed" mark: shown only where a row has a fixed cell.
  • readonly property var matrix: …: The matrix shown: its times and layers across (columns), its marks, its rows.
  • readonly property var columns: grid.matrix.columns: The seven times and the two layers, across: each its id and its name.
  • readonly property var rows: grid.matrix.rows: The rows down, in their groups: each its name, its help, its cells and the choices they offer.
  • readonly property real cell: 36: A mark's cell, as narrow as a finger allows.
  • readonly property var flatWidths: …: Each time's name across, as wide as it is; the kinds' names as wide as the widest.
  • readonly property real flatWidth: …: The width of every column with its time's name lying across.
  • readonly property real nameWidth: …: The width of the widest row's name, 60 pixels at least.
  • readonly property bool beside: …: The kinds' names beside their marks when both fit; else above them.
  • readonly property bool upright: …: The times' names upright when even they do not fit across.
  • readonly property var widths: …: Each column's width: a mark's cell when the names stand upright, else its name's.
  • readonly property real tallest: …: The height the times' names need standing upright: the longest of them.
  • readonly property var scroller: …: The page's own scrolling (Settings' ScrollView): the times' names are kept in sight while the rows scroll under them (kept).
  • readonly property real scrolled: …: How far the page has scrolled past the grid's top, in the grid's own terms; 0 while its first line shows. Read again as the page scrolls.
  • property var openRow: null: The cell whose choices are open.
  • property var openCell: null: The cell whose choices are open, in openRow; null when none is.
  • readonly property var lines: …: What the open cell's choices say: its row and time, the row's help, then each choice it offers, or why it is fixed.
  • readonly property var legendMarks: …: What each mark shown in these rows says, and no other: at once on the Always through row is ★, said apart.

Signals

  • signal save(string key, var value, var shown): A row's words, nine of them, the one chosen changed. shown: the row's words as it showed them, so that only the cell changed is set.

Functions

  • function open(row, cell, item): A cell's choices opened under item, its mark.
  • function choose(value): The open cell's row, with this value in that cell: saved whole.
  • function openAt(rowId, columnId): A cell's choices opened by its row's and column's ids, and closed: for the documentation's pictures (main.qml's steps "attention").
  • function closeChoices(): The cell's choices closed.

Inline components (used inside this file)

  • component Heads: RowLayout: The times across, turned upright on a narrow screen: once above the rows, and again over them while the page scrolls past it.

BalanceChart

crates/sioul-app/qml/BalanceChart.qml · based on Canvas

A budget's balance over time: what happened as a line, what is planned as the same line, dotted; the target as a quiet dashed line, zero as a thin one.

Required properties (whoever makes it must give them)

  • required property var theme

Properties

  • property var points: []
  • property real low: 0
  • property real high: 0
  • property real target: 0

BankSection

crates/sioul-app/qml/BankSection.qml · based on ColumnLayout

Where the money is, on the Budgets page (docs/accounting.md, "Bank accounts"): each bank account (a current account, PayPal, Stripe) with its exports taken in, its balance, the budgets it fills, what tops it up, and its movements, each saying where it went and why, changed by hand when the rules got it wrong. Then the watch: in words what passed and what did not, the week's payments, and the balance carried forward a month as a plain line (zero marked, no red).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …
  • property string said: ""
  • property bool saidWell: true
  • property string importing: "": The account an export is being taken in for; "" for one named by the export.
  • property var unfolded: ({}): The accounts whose movements are unfolded.
  • readonly property var kindIcons: …
  • readonly property bool narrow: section.width < 560: A narrow screen (a phone): an account's buttons under its name, a movement's budget under it.
  • property alias accountDialog: accountDialog
  • property alias rulesDialog: rulesDialog
  • property alias reserveDialog: reserveDialog

Functions

  • function reload()
  • function say(problem)
  • function toggle(id)
  • function unfold(id): The account's movements open: for the window's images.

BudgetDetail

crates/sioul-app/qml/BudgetDetail.qml · based on ColumnLayout

A budget opened: how its period goes at its pace, its balance as a line (days, weeks, months or years; what is planned dotted), and its ledger: every movement of the period, newest first. Movements are added by hand here, once or recurring.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string budget: ""
  • property string step: "day"
  • property date anchor: new Date()
  • property var shown: null
  • readonly property var steps: ["day", "week", "month", "year"]
  • readonly property bool narrow: detail.width < 560: A narrow screen (a phone): the title under the arrows, each date under its line.
  • readonly property string inOut: …

Signals

  • signal back

Functions

  • function iso(d)
  • function reload()
  • function move(steps): A month or a year away, on the same day or on that month's last: from 31 October, back is 30 September, never 1 October again.

CallsSection

crates/sioul-app/qml/CallsSection.qml · based on ColumnLayout

The calls your phones declined, on the Porch of every device (docs/porch.md, "Calls declined"; docs/android.md, "Calls"): each shown at the times its caller may reach you, by phone or in writing; never counted, no badge. Who, when, on which phone when not this one, a later call that rang, the doubt said plainly ("They may have left a message"), and what you may do: text back or call back (the phone's own apps, or on a computer the system's app for such links, KDE Connect handing them to your phone; else copy the number: nothing is sent by Sioul), listen to the voicemail your operator mailed, and "Seen", which takes a line away on every device, with ten seconds to undo; the rest in the line's menu (⋮, a right click, a long press, the Menu key or Shift+F10): add to your contacts (Android's form on a phone, Sioul's on a computer), block, see how they reach you, why it went to voicemail.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var shown: …: calls.rs's view: {lines: [{ids, text, number, dial, known, hidden, doubt, message: {text, path, sound}, why, again}], phone, links: {tel, sms}}.
  • property string said: ""
  • property string playing: "": The voicemail being played: its line's first id, and its sound's address.
  • property string playingUrl: ""
  • property var whyShown: ({}): Lines whose "Why?" is open, by their first id.
  • property real undoAt: 0: The last Seen pressed here (its time), undone within ten seconds.
  • readonly property bool onPhone: section.shown.phone === true
  • readonly property bool canCall: …
  • readonly property bool canText: …
  • readonly property bool narrow: …: A phone held upright: the buttons' icons alone, as on every page there (their words on hover and for readers).

Functions

  • function reload()
  • function act(verb, args)

CaptureField

crates/sioul-app/qml/CaptureField.qml · based on ColumnLayout

One line, one task: "Call the CAF tomorrow ~15m #housing {30/10}". What the line says besides the title shows as chips while typing, so nothing is misread silently; Enter makes the task, Escape empties the line.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does. The core reads the line there (capture).
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string parentUid: "": Made as a step of this task, when set.
  • property string list: "": The list new tasks go into: "account/id"; empty: the usual one.
  • property bool step: false: A line of steps: nothing is made until the task they are steps of is.
  • property string placeholder: capture.sioul.text("task-capture-hint"): What the line says while empty: an example of a line.
  • readonly property var parsed: …: What the line says, read by the core as it is typed (capture): the chips shown, and the task's fields.

Signals

  • signal added(string uid): A task was made from the line, by its UID.

Functions

  • function focusLine(): The keyboard's focus given to the line.

ColourEffect

crates/sioul-app/qml/ColourEffect.qml · based on ShaderEffect

colour: a site's picture in the screen's own colours, and calmer when asked (docs/colour.md). A WebEngineView's layer.effect, while ScreenColours.active(Screen.name) says its tables change something: each pixel is looked up in the two tables ScreenColours made for the screen the window is on (cpp/screencolours.cpp, colour.rs), by shaders/colour.frag.

Properties

  • property var source: The picture, given by the layer.
  • readonly property Image cube: cubeImage: The tables, as textures (shaders/colour.frag): the cube, 33 tiles of 33 × 33 side by side, and the curve.
  • readonly property Image curve: curveImage: The tone curve's table, as a texture: 1,024 entries.
  • readonly property real tableSize: ScreenColours.cubeSize: The cube's entries on each side, for the shader's lookup (ScreenColours.cubeSize).

CommandText

crates/sioul-app/qml/CommandText.qml · based on ColumnLayout

A line Sioul says that may hold commands to run by hand, each written in backticks in its words (sudo apt install pcscd): its words as text, and each command on a line of its own, in a read-only field that selects (keyboard and mouse) with Copy beside it. Words after a command lose the separators that joined them to it (", ", "; "). A line without a command reads as a plain label.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does. The Copy buttons' words come from there.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string text: "": The line, its commands in backticks.
  • property color color: said.theme.text: The words' colour; the commands keep the fields' own.
  • property int pixelSize: 0: The words' size; 0 for a label's own.
  • property bool commands: true: Backticks read as commands; off, the line is words alone, as written.
  • readonly property var parts: …: Its parts in order: {command, text}.

ContactDuplicates

crates/sioul-app/qml/ContactDuplicates.qml · based on Panel

Duplicates in the contacts, looked for when this view opens: the cards that hold a number or an address twice, each ticked, cleaned with one click; then the pairs of cards that may be one person, one at a time, merged, kept apart or left for later; and what was done lately, each with Undo. How many is said in words; nothing changes without a click.

Required properties (whoever makes it must give them)

  • required property var sioul

Properties

  • property bool compact: false: One column, on a phone: the two cards of a pair one under the other.
  • property string answer: ""
  • readonly property var found: …
  • property bool looking: false
  • property string problem: ""
  • property var unticked: ({}): Cards left unticked, by file: kept as they are.
  • property var passed: ({}): Pairs passed over this time ("Later"), by their two files.
  • readonly property var pairs: …
  • readonly property var pair: …
  • property string kept: "first": Whose name is kept: "first" or "second".

Signals

  • signal openContact(string key)
  • signal closeAsked

Functions

  • function look()
  • function ticked()
  • function clean()
  • function merge()
  • function notSame()
  • function later()
  • function undoLast(): The newest of what was done, undone (the window's tests).
  • function setTicked(key, on)

ContactForm

crates/sioul-app/qml/ContactForm.qml · based on ColumnLayout

A contact's form: the name, addresses and numbers in view, each with what it is for; the organisation; its categories, chosen among those in use or typed; then, folded, postal addresses, the birthday, notes and web sites. edit() gives what the backend saves.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property bool moreShown: false
  • readonly property var labels: ["", "work", "home", "cell"]
  • property var known: []: The categories the cards have (the page's list), to choose from.
  • property var chosen: []: This contact's categories, as edited.
  • readonly property var others: form.known.filter(k => !form.has(k)): Those in use it does not have yet, to choose from.

Functions

  • function folded(name): Categories compare as the sender lists compare them: case and accents aside.
  • function has(name)
  • function plus(list, name): The categories with one more: the spelling already in use when there is one.
  • function addCategory(name)
  • function load(person)
  • function rows(model)
  • function edit()

ContactMap

crates/sioul-app/qml/ContactMap.qml · based on MapView

OpenStreetMap, with a pin for each place given; a click on a pin says whose it is. Tiles come from the server set in the Contacts settings (OpenStreetMap's by default), asked by name, sparingly, and kept by Qt's cache; Qt's own lookup of map providers is turned off.

Required properties (whoever makes it must give them)

  • required property var theme

Properties

  • property string tiles: "https://tile.openstreetmap.org/": "https://tile.openstreetmap.org/".
  • property var pins: []: [{ key, name, address, lat, lon }].
  • property string chosen: ""

Signals

  • signal pinClicked(string key)

Functions

  • function fit(): Every pin in view: the map centred on them, as close as they allow.

ContractsSection

crates/sioul-app/qml/ContractsSection.qml · based on ColumnLayout

Contracts and subscriptions, on the Budgets page: what you are bound to, each with when it renews and the last day to stop it, in words; the recurring payments that have no contract yet, one click from being one; stopping one: its own cancel page, or the letter drafted. No offers.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var shown: …
  • property string problem: ""
  • property alias dialog: contractDialog

Functions

  • function reload()
  • function start(prefill): A contract to say, from a mail or a payment.
  • function open(id)

DayReviewLine

crates/sioul-app/qml/DayReviewLine.qml · based on ColumnLayout

Under a day on the Health page (docs/reviews.md): how the day went, in the words said then, and its notes; today, in the evening and during the night, "Close the day", which opens its review (DayReview.qml). Read only for the days before. Nothing at all when nothing was said: no gap, no mark.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string date: "": The day shown ("2026-10-06").
  • property var shown: null: reviews::line: said, words, memos, close, button.

Functions

  • function reload()

DayView

crates/sioul-app/qml/DayView.qml · based on ColumnLayout

Today, seen: your hours by what they are for, the events at their times, the steps the plan gives today in hours of their kind, a pause between them; a line where now is. The step under way is marked, the next one outlined. A layout to look at, never a schedule to keep: a step that runs over only moves the next ones (dayview.rs). Each card is as tall as its text with air around it: the hours stretch for that, and the day scrolls, opened at the current hour. Nothing is drawn over anything else: two events at once sit side by side. Time for you is kept quietly, twice a day, and the free time kept for steps running long is shown as such; why today holds what it holds is said above, in words (docs/capacity.md).

A step is moved by hand to another time today (docs/tasks.md, "The day, seen", "Pinned to a time"): dragged, it is pinned there, its time block (an event in your calendar) made or moved, its own dates as you set them, and the day is laid again around it; "Let the plan place it" (its menu) takes its block away and gives it back to the plan. A meal or a nap moves as on the Health page, that day's change; an event, when the day knows it can be written, as in the agenda. Where it would go is drawn, with its times; let go, it is changed, and "Undo" waits in the status line. With a mouse, press and drag; with a finger, a long press picks it up (a plain swipe scrolls). One set of handlers for the whole day (TimeDrag.qml).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var day: null: The page's day: {from, to, now, hours: [{start, end, kind}], blocks: [{start, end, kind, title, key, energy, location, column, columns, part, pinned, note}], all_day, more, said}. Kinds: "event", "task", "meal", "nap", "margin", "done", "gain" (time for you), "slack" (kept free).
  • property real now: Date.now() / 1000: Now on the clock (Unix seconds): the window's clock (main.qml), moved at each minute's turn and when the app comes back. It moves the line and marks the block under way; nothing is laid again for it.
  • readonly property var blocks: dayView.day ? dayView.day.blocks : []
  • readonly property var hours: …
  • readonly property int current: …: The block under way, and the next one; margins around them are neither.
  • readonly property int next: …
  • property real relaid: 0: When it was last laid again (Unix seconds, the clock's).
  • readonly property int padding: 8: Air inside a card, above and below its text.
  • readonly property real cardHeight: …: A card's least height: one line of its text, and its air.
  • readonly property real perMinute: …: The whole day in the height when it fits; else as much as the tightest card needs to hold its line before the next one starts (a quarter of an hour at least: a step is never shorter), and the day scrolls.
  • readonly property var kinds: …: The kinds of hours today has, for the legend.
  • property real anchoredHour: -1: The hour the view was last opened at.
  • property var grab: null: A block taken by the hand: {block, part, pressSeconds}; where the pointer is now.
  • property point pointer: Qt.point(0, 0)
  • property var landed: null: Let go: drawn where it goes until the day comes back laid again.

Signals

  • signal relay: Laid again from now at each five minutes' turn while shown, when shown again, and as soon as the app comes back (the clock jumps): steps are laid from the next five minutes, and what another device marked done or noted comes in through the sharing.
  • signal openTask(string uid)
  • signal openEvent(string key)

Functions

  • function relayNow()
  • function at(seconds)
  • function time(seconds)
  • function kindColor(kind)
  • function roomOf(block): Minutes from a block's start to the next one's (side by side ones aside), or to the day's end: the room its card has.
  • function heightOf(index): A block's height: as long as it lasts, a little air before the next; a short one as tall as its text, within the room before the next.
  • function partOf(block): "1/2": a long step cut by a break, its part among all.
  • function secondsAt(y): The time at y in the day's content, Unix seconds.
  • function cardOf(index): A block's card, as drawn: {x, y, width, height} in the day's content.
  • function ownerOf(block): What a block moves with: itself; for a margin, its step's card (the same part) or its event (the one it is around); null for a margin of nothing.
  • function stepOf(block): The step a block belongs to: its card, or null.
  • function midnight(): Midnight tonight, Unix seconds: a time given stays on today.
  • function movable(block): What a hand can move: a step (by its card or its margins); a meal or a nap not over; an event in a calendar that can be written, wholly today (by its card or its margins).
  • function blockAt(p): What lies at p (the day's content): {block, index, part: "body", or "bottom" for a meal's, a nap's or an event's end (8 px at least)}; else null.
  • function target(grab, p): Where the block taken would go, by whole five minutes, today: {start, end}, Unix seconds.
  • function take(thing, p)
  • function local(seconds): "2026-10-06T14:30", "14:30": a time given, a time on the clock.
  • function drop(p)
  • function saveEvent(onlyThis): A repeating event let go: this time alone, or every time.
  • function showNow(always): The current hour at the top, the hours before it a scroll away; again when the hour turns, never under your hand otherwise.

DoubtLine

crates/sioul-app/qml/DoubtLine.qml · based on ColumnLayout

Under a dose not answered here: why Sioul cannot tell whether it was taken (never "not taken"), or the answers your devices gave that differ; and for each device the doubt names, "This device is off" (docs/health.md, "Knowing"): said off, it is not counted until it says anything newer. It never answers the dose for you. Warm, never red.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string doubt: "": The sentence; "" when the dose is known.
  • property var offs: []: [{id, label}]: a button each.

Signals

  • signal saidOff(): A device said off: the page reads the doses again.

EventRow

crates/sioul-app/qml/EventRow.qml · based on ItemDelegate

One event in a day: its calendar's colour, its time, its title and place. A cancelled one is struck through; a tentative one is in grey.

Required properties (whoever makes it must give them)

  • required property var event
  • required property var theme

Properties

  • property bool compact: false
  • property bool selected: false

Signals

  • signal open
  • signal menu

FeltRatings

crates/sioul-app/qml/FeltRatings.qml · based on ColumnLayout

How a task was, once done, if you want to say (docs/research/capacity-budget.md, criteria 6 and 7: rated after, the gap to the forecast learned): the four costs and the gain as tiles (CostTiles.qml), what was foreseen a thin mark on each gauge. Only what you tap is kept as felt; the rest stays unsaid, never copied from the forecast (it would bring its bias back: dread is foreseen higher than it is felt). Never asked twice, never counted, never praised.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var forecast: ({}): What was foreseen: {cognitive, emotional, anxiety, body, gain}, each 0 to 10 or null.
  • property var kept: null: What was felt today, as kept so far; null before.
  • readonly property var names: …: The four costs and the gain, by their names in a task's record.
  • readonly property bool said: …: Whether anything was said of how it was.
  • readonly property alias tiles: tiles: The tiles themselves (for the tests).
  • readonly property real naturalWidth: tiles.naturalWidth: Its natural width, the tiles' (CostTiles.qml).

Signals

  • signal given(var values): Today's five values to keep: the one just given, the others as kept so far.

Functions

  • function felt(name): What was said of one of them: 0 to 10, or null when unsaid.
  • function give(name, value): One of them said (a tile tapped): kept as felt, the others as they were.

GoogleMail

crates/sioul-app/qml/GoogleMail.qml · based on ColumnLayout

Google's mail (Gmail, Google Workspace) in the mail form: Google refuses the account's password there, so this form never asks for it. Two ways: an app password made at Google (the default without a key of your own), or "Sign in with Google" on Google's page, in the system's browser, with a key of your own (Google gives its mail's scope to no key of Sioul's yet). Made the first time an address turns out to be Google's (AccountsPage.qml). docs/google.md, "Mail".

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string address: "": The address, and what was found for it (backend's FoundView).
  • property var found: null
  • property string againId: "": An account signed in again: its id; empty when adding one.
  • property bool stepsShown: false
  • property bool ownKey: false
  • readonly property bool keyKept: …
  • readonly property bool builtIn: form.sioul.googleBuiltIn()
  • readonly property string chosen: signInWay.checked ? "google" : "app": "app" or "google": the way ticked (its default set by reset).
  • readonly property bool phone: Qt.platform.os === "android"
  • property string problem: "": An app password given to an account signed in again: what its server said.

Signals

  • signal started: Something was asked of the backend: the page shows its answer under this form.
  • signal done: An account signed in again took an app password instead.

Functions

  • function reset(): A new address: its fields emptied, and the way ticked by default: Google's page when a key of yours is kept here (or the account signs in again), else an app password.

HealthTimeline

crates/sioul-app/qml/HealthTimeline.qml · based on ColumnLayout

Meals, naps, the night and the doses down the hours: one column for a day, seven for its week (docs/health.md, "The page"). Each column has three lanes: the day's events and planned steps, faded, for context only; the times kept free, getting ready, winding down and coming back lighter than the time itself; the doses, a dot each (hollow when due, filled when taken, warm when another device may know: never "not taken"). The hours are the same every day, so that nothing moves from one day to the next. A quiet line marks now. A tap on a block chooses it (its row in the list lights up, and the other way round) and offers what can change it.

A block is moved by hand, on its own day (docs/health.md, "Moved by hand"): dragged whole, it keeps its length; by its bottom edge, a meal or a nap changes its length; the night's top edge is bedtime, its bottom edge waking (in the next morning's column). What it would become is drawn where it would go, with its times; let go, it is that day's change, as "Move to…" makes it, and "Undo" waits in the status line. A day past, or a block over, stays as it was. With a mouse, press and drag; with a finger, a long press picks it up (a plain swipe scrolls). A timeline too thin to take with a finger (a phone's) asks to be opened readable at the long press (readableAsked), and the block under the finger, if there is no doubt which, comes with it. One set of handlers for the whole timeline (TimeDrag.qml): the blocks carry none.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var days: []: The page's days (health::DayView): one, or the seven of a week.
  • property int fromMinute: 7 * 60: The hours shown, in minutes from midnight: the same for each day.
  • property int toMinute: 22 * 60
  • property string lit: "": A block lit by the pointer or chosen, as "date|key": its row lights up too.
  • property string chosen: ""
  • property bool titles: false: The days' titles above their columns (the week).
  • property bool readable: false: Opened readable, a block a finger can take: the page says (a phone's long press).
  • readonly property int readableHour: 56
  • readonly property int gutter: 46
  • readonly property int hours: …
  • readonly property real hourHeight: …: As tall as the room allows, the whole day in view; never thinner than a line of small text.
  • readonly property real columnWidth: …
  • readonly property bool wide: timeline.columnWidth >= 160: A wide column: names in the blocks, the doses' names beside their dots.
  • property real now: Date.now() / 1000: Now on the clock (Unix seconds) and today ("2026-10-06"): the window's clock (main.qml), moved at each minute's turn and when the app comes back. Only the line follows it, and today's marks when the day turns.
  • property string today: …
  • readonly property int minuteNow: …: Now in minutes from midnight, for its line.
  • readonly property int todayIndex: …: Today's column among the days shown; -1 when today is not shown.
  • readonly property bool thin: …: Too thin to take a block with a finger: a long press asks for the readable scale.
  • readonly property real edgeZone: timeline.readable ? 14 : 8: An edge's grab zone, in pixels: at least 8, more for a finger.
  • readonly property int topRoom: 8: Room above the first hour, for its label.
  • property var grab: null: A block taken by the hand: {segment, part, column, pressMinute}, and how far it went, in minutes.
  • property real shift: 0
  • property var landed: null: Let go: what it became stays drawn until the page has it (or a moment passes).
  • property var anchor: null: Opened readable at a long press: the minute under the finger stays under it.

Signals

  • signal hover(string id): The pointer over a block, or off it ("").
  • signal tapped(var segment, point at): A block or a dose tapped (segment as the view gives it), where.
  • signal menu(var segment, point at): A block's menu asked for: right click, or a long press let go where it was.
  • signal openDay(string date): A day's title tapped (the week): that day, shown.
  • signal readableAsked: A long press on a timeline too thin to drag in: open it readable, at that minute.
  • signal readableDone: The readable scale closed ("Done").

Functions

  • function yOf(minute)
  • function minuteAt(y): The minute at y in the timeline's content (not clamped).
  • function kindColor(kind): Each kind its colour, calm and apart (the theme's chart colours, no red).
  • function tint(color, alpha)
  • function clock(minute): "12:45" for minutes from a column's midnight (the day before's, or the next's, on the clock).
  • function lanes(index): A column's lanes, as its delegate lays them: context, kept times, doses.
  • function shown(segment)
  • function topOf(segment): A block's top and bottom in the content, as drawn.
  • function bottomOf(segment)
  • function editable(segment): What a hand can change: a meal, a nap or a night not over, on a day not past.
  • function hasTop(segment): Its ends this column holds: a meal's or a nap's bottom (its length); the night's top (bedtime) where it starts, its bottom (waking) where it ends.
  • function hasBottom(segment)
  • function thingAt(p): What lies at p (the content's coordinates): {segment, part, column}, part "body", "top", "bottom" (an edge's grab zone) or "dose"; else null.
  • function pickNear(p): Under a finger on a thin timeline: the block it is on, else the only one within 20 px; when two lie as close (a meal right after the night's end), none: the readable scale opens, and the next long press chooses.
  • function take(thing, p)
  • function span(grab, shift): Where the block taken would go, shift minutes on, by whole five minutes, within the hours shown and the day's rules: {start, end} in its column's minutes, not cut at midnight.
  • function detailOf(segment, to): What the ghost says under its times: a night's bedtime, when a meal is eaten.
  • function edit(grab, to): What the day is asked (health::drag_need), for the block taken gone to to.
  • function drop()
  • function showNow(): The hour now in view when the day does not fit (a short window).
  • function keepAnchor()

LettersSection

crates/sioul-app/qml/LettersSection.qml · based on ColumnLayout

Paper letters, in the Porch's window: each scan read, as a card. Who sent it, what it is, how much, by when (legal delays counted into a date); a task for that date, its appointment in the agenda, its scan one click away; done, it is filed with its project. Letters wait outside like mail.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var shown: …
  • property string problem: ""

Functions

  • function reload()

LevelMark

crates/sioul-app/qml/LevelMark.qml · based on Item

A level's mark (docs/attention.md, §1.8): ● at once (★ on the Always through row: whatever their list), ◑ shown, not told, ◐ when its event falls then, ◎ at the gathered times, ○ later, – not at all, = as their own list, ☆ through do-not-disturb at their own times. Drawn, not a font's glyph: the same on every system. Always beside words (the grid's legend, a cell's sentence), never alone.

Properties

  • property string value: "": The level it marks: "now", "quiet" (shown, not told), "event", "gathered", "later", "never", "as" (as their own list), "through" (docs/attention.md).
  • property bool always: false: On the Always through row: at once is a star.
  • property color tint: "black": Its colour.
  • property color hole: "white": The page's colour, to hollow the star of ☆.
  • readonly property bool star: …: Drawn as a star: at once on the Always through row, or through do-not-disturb.
  • readonly property bool ring: …: Drawn hollow: later, at the gathered times, when its event falls, or shown without a word.

MailFilters

crates/sioul-app/qml/MailFilters.qml · based on ColumnLayout

The mail filters, under "Filters" in Mail ▸ ⚙ (crates/sioul-app/src/filters.rs, docs/client.md, "Filters"): one list for every address, each filter in words, narrowed to one address when you choose one; its editor opens in place, one condition and one action at first, the rest when asked for, each field once its kind is chosen; every change saved at once, as every setting. "Try it" counts what a filter takes in the inboxes now; "Run them on the inboxes…" says first what would change, then waits ten seconds with Undo. On a phone, the same in one column.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string about: "": What filters are, in a sentence: the setting's own (settings.rs), said first.
  • property var shown: …: filters.rs's View: {filters, accounts, folders, form}.
  • property string narrowed: "": The address the list is narrowed to; "" for all of them.
  • property int editing: -1: The filter open in the editor, by its place in the list; -1 for none.
  • property var draft: null: That filter as the editor changes it, saved at each change.
  • property string draftSaid: "": Its sentence and what keeps it from running, said as it changes.
  • property string draftProblem: ""
  • property string draftOnly: ""
  • property string problem: "": What went wrong writing the list, else "".
  • property var deleted: null: The filter last deleted and its place, for "Undo".
  • property var found: null: What "Try it" (kind "try") or the preview (kind "preview") found; looking meanwhile.
  • property bool looking: false
  • property string note: "": Under the editor of a filter a search made: what of the search a filter does not read.
  • property Item editorItem: null: The editor's frame, while one is open: shown whole in the panel when a search opens it.
  • readonly property var locale: …
  • readonly property bool narrow: filters.width < 460

Functions

  • function read(): The list read again; a filter a search just made (open), opened in the editor.
  • function reveal(item): An item shown whole (the editor open, a preview's result), its top under the panel's top when it does not fit: the panel's own scrolling.
  • function tryIt(): "Try it": what the filter open takes in the inboxes now.
  • function preview(): "Run them on the inboxes…": what would change, said first.
  • function write(list, again): The list written, in its order, from the one shown: its change set over the filters as they are now; read again when again (its sentences said anew).
  • function copy(value)
  • function shownHere(filter)
  • function fieldOf(id)
  • function testOf(fieldId, testId)
  • function saveDraft(rebuilt): The draft saved into its place, its sentence said anew; rebuilt: the editor's parts follow (a part added, taken away, of another kind).
  • function open(index)
  • function close()
  • function add(): A new filter: one condition and one action, to be filled; on the address the list is narrowed to.
  • function remove(index)
  • function bringBack()
  • function neighbour(index, by): The filter next to it in the list shown (narrowed to an address, the next of that address), -1 for none.
  • function move(index, by): Asked earlier or later: in the place of the filter above or below it, as shown.
  • function toggle(index, on)
  • function setField(at, fieldId): A condition's field chosen: its usual test, and a value of its kind.
  • function setTest(at, testId)
  • function folderNote(name): Who has a folder: its addresses, as the filter's addresses see it.

MailSearch

crates/sioul-app/qml/MailSearch.qml · based on ScrollView

The search by conditions, in the folders' place (MailPage): plain fields, one condition at first, more when asked. The conditions are the mail filters' own (a field, a test, a value; all of them or any), so a search can become a filter as it is. The list beside shows what they find and the reader beside it, so one goes back and forth; the sentence over the list says what is searched. "Clear" returns to the folder.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property bool compact: false: On a phone the column is a page of its own: its results are one tap away.
  • property var words: null: What the fields offer, in your language (mailSearchFields): read when the search opens.
  • property bool any: false
  • property bool filterOffered: false: The window can take a search to the filters' editor: "Make it a filter…" shows.

Signals

  • signal changed(bool now): A condition changed: the page searches (now: Enter was pressed).
  • signal clearRequested
  • signal showRequested
  • signal filterRequested(string conditions): "Make it a filter…": the conditions, as the filters write them.

Functions

  • function json(): The conditions as JSON, as the filters write them: {conditions, match}.
  • function start(text): Opened: one condition, anywhere, with what the quick search held.
  • function startWith(conditions, any): For the window's pictures: conditions given whole, [{field, test, value, until}].
  • function fieldOf(id)
  • function testOf(field, id)
  • function kindOf(field, test): What a value is, under a field and a test: "nothing", "text", "date", "dates", "size", "kind", "who", and the search's own "account", "folder", "mark".
  • function firstValue(kind): A value to start with, for a kind of value.
  • function setField(index, field)
  • function setTest(index, test)
  • function setValue(index, key, value, now)
  • function add()
  • function remove(index)

MedicinesSection

crates/sioul-app/qml/MedicinesSection.qml · based on ColumnLayout

The medicines and the prescriptions, on the Health page: content, as tasks are, not settings. Each medicine: its name and dose, its times ("08:00 · 20:00"; each take with its amount when they differ, "08:00 · 1 tablet, 20:00 · 2 tablets"; every few days or hours in words), until when; paused or past its last day, quieter. Each prescription: who wrote it, the next visit to the pharmacy and the day to renew it by, in words, the medicines it covers, and "Fetched today". Add and Edit open their forms, the page's (HealthPage.qml). Today's doses, and whether they were taken, are in the day's list, not here.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var medicines: []: As the page's view gives them (health::medicine_rows, prescription_rows).
  • property var prescriptions: []

Signals

  • signal openMedicine(var medicine): A form to open: a medicine's, a prescription's (null: a new one).
  • signal openPrescription(var prescription)
  • signal fetched(string id): A prescription's medicines fetched at the pharmacy today.
  • signal showProfessional(string id): Shown read-only to a doctor or a pharmacist: a prescription's (its id), or all taken now ("").

Inline components (used inside this file)

  • component Heading: RowLayout: A group's name, and the button that adds to it.

PdfView

crates/sioul-app/qml/PdfView.qml · based on PdfMultiPageView

A PDF of the notes folder, read in place: pages one under the other, its links followed, its text selectable. Loaded only when a PDF opens.

Required properties (whoever makes it must give them)

  • required property url source

PhoneMessagesSection

crates/sioul-app/qml/PhoneMessagesSection.qml · based on ColumnLayout

"From your phone", on a computer's Porch (docs/porch.md, "From your phone"; docs/android.md, "Messages on your computers"): the messages your phone's notifications brought, for the apps you chose there, once the phone let them through and while their sender may reach you; never counted, no badge, never a notification here. One line per conversation and part of the day: who, when, the words (or "a picture", or only who and when); a code said, never shown. What you may do: text back or call back (the system's app for such links, KDE Connect handing them to your phone; else copy the number: nothing is sent by Sioul), and "Seen", which takes the line away on every device, with ten seconds to undo, and never touches the phone's notification; the rest in the line's menu (⋮, a right click, a long press, the Menu key or Shift+F10): how they reach you, add to your contacts, block.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var shown: …: phonemsgs.rs's view: {lines: [{ids, head, said: [{time, from, text}], note, number, dial, known, texted, code}], links: {tel, sms}}.
  • property string said: ""
  • property real undoAt: 0: The last Seen pressed here (its time), undone within ten seconds.
  • readonly property bool canCall: …
  • readonly property bool canText: …
  • readonly property bool narrow: …

Functions

  • function act(verb, args)
  • function reload()
  • function answered(answer)

ReachesTab

crates/sioul-app/qml/ReachesTab.qml · based on ColumnLayout

Settings ▸ What reaches you (« Ce qui vous joint »; docs/attention.md): one place for when each thing reaches you. On top, the moment now in sentences and where you started from (the presets; one press back). Then five views: By time, a card per time in words, Change… opening that time's rows; By person, the channels' grids (Mail, Calls, Messages) with your lists under them; Sioul's own, the kinds' grid; Exceptions, Always through and each conversation, app or site with a choice of its own; Do not disturb, what turns it on, what it holds, what each device does. On a phone, never the whole grid: cards, then one time's rows, or one row's times, each value in words. The words come from the window's reachesView (reaches.rs); a change is saved at once, its row whole (reachesSet).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var rows: Settings' rows: this tab's own switches (section "attention").

Properties

  • property var shown: …
  • property string view: "time": "time", "person", "own", "exceptions", "dnd".
  • property string time: "": By time: the time whose rows are open; "" for the cards.
  • property string channel: "mail": By person: the channel shown.
  • property string rowOpen: "": On a phone (By person, Sioul's own): the row whose times are open; "" for the list.
  • property string problem: ""
  • property string presetAsked: "": A preset pressed while your own changes stand: asked first.
  • property var lists: []: Who is on which list (Settings' "senders"), read when By person is first shown.
  • readonly property bool narrow: tab.width > 0 && tab.width < 560
  • readonly property bool detail: …: On a phone, a time's rows or a row's values open: the moment and the presets, which are the whole matrix's, give them the screen.
  • readonly property var gridRows: …: The rows that act here, as the grid has them.
  • readonly property var channelRows: …
  • readonly property var ownRows: …
  • readonly property var openCard: …
  • readonly property var openRowData: …
  • readonly property var channelShown: …
  • readonly property bool rowShown: tab.narrow && tab.openRowData !== null: On a phone, one row's times open: that alone, under the view's buttons.

Signals

  • signal save(string key, var value, var shown): A switch changed (Settings saves it, then reads its rows again).
  • signal toTop: Another view, time or row shown: the page scrolled back to its top.

Functions

  • function reload()
  • function setting(key)
  • function choose(row, column, value): A row with one cell changed, saved whole.
  • function saveRow(id, words, shown): shown: the row's words as it showed them: only the cells changed are set.
  • function preset(id, direct): A preset over your own changes is asked first, but from "Back to As Sioul does now" (direct).
  • function show(view, detail): A view, and in it a time, a channel or a row: from a link elsewhere ("attention.pause", "attention.calls"), or the pictures' steps.
  • function readLists()
  • function openCell(rowId, columnId): A cell's choices in words, opened by its row's and column's ids: for the pictures.
  • function closeChoices()
  • function findGrid(item)
  • function findNamed(item, name): A shown item under this one, by its objectName.
  • function valueWords(row, value): A value in the row's own words ("Shown, not told", "Voicemail, listed later").

Inline components (used inside this file)

  • component Heading: Label
  • component Said: Label
  • component Note: Label
  • component ValueLine: AbstractButton: A row's line: its name, its mark and its value in words, a dot when changed; a press opens its choices (fixed: why).
  • component RowList: ColumnLayout: A list of rows (a phone's By person and Sioul's own): each opens its times.
  • component RowValues: ColumnLayout: A row's nine values, on a phone: its times, then its two layers.

Reader

crates/sioul-app/qml/Reader.qml · based on Panel

One message, read: what you can do with it on top (reply, forward, file it away), then who wrote to whom apart from the text, its attachments folded, its text with quoted messages and repeated headers set off. Everything else is in the "…" menu. Moving, deleting and junking happen at once, with "Undo" in the status line for ten seconds; nothing asks "are you sure?".

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var window: The main window (main.qml), which opens what is asked of it. Drafts, tasks and notes made from the message open there.

Properties

  • property string key: "": The message, by its file; empty when none is open.
  • property var item: null: Its entry in the list: trust, and on the Porch the reasons and the screener.
  • property var reading: null: The message as the backend read it (readMessage): its headers, text, attachments and what it is tied to; null while none is read.
  • property bool opening: false: The message is being read off the window's thread (readMessage): the pane says so meanwhile.
  • readonly property bool showing: …: Something to show: the message, or that it is opening.
  • property var invite: null: The invitation the message carries, if any.
  • property string senderContact: "": The sender's contact, by file; empty when the sender is not one.
  • readonly property var announces: …: The site this message announces ("a new item in your secure mailbox"), when it is one of yours.
  • readonly property var source: …: The message, as what new things are tied to.
  • property bool unread: false: Read and flagged, as last done here: the server follows.
  • property bool flagged: false: Flagged, as last done here: the server follows.
  • property bool reasonsShown: false: Why it is in its lane on the Porch, unfolded.
  • property bool attachmentsShown: false: Attachments stay folded until asked for.
  • property bool historyShown: false: The quoted history of an HTML message, folded.
  • property string hoveredLink: "": The link under the pointer, said in full before anyone clicks it.
  • property bool revealed: false: What the message is tied to (tasks made from it, notes), read when it opens. A message set aside as hostile shows nothing of itself until you choose to read it.
  • readonly property bool gated: …: Set aside as hostile and not yet asked for: nothing of it shows.
  • readonly property string role: …: Its folder's purpose ("inbox", "trash", "junk", "archive", "all"…), for the actions that fit there.
  • readonly property bool compact: …: Narrow: the actions show their icons only, their names on hover, as soon as their names would not fit in the row (French ones are longer). Narrower still (a phone): "junk" goes in the menu under ⋮.
  • readonly property bool tight: …: Too narrow for every action's icon: "Junk" goes into the "…" menu.

Signals

  • signal closeRequested: The message is done with here (filed away, deleted, Escape): its page closes the reader.

Functions

  • function actionsWidth(width): The row's width, each action as wide as width says. "Junk" counts whether it shows or not: it hides when the row is too narrow.
  • function trustColor(level): The colour of a sender's check: the accent when verified, the forged colour when forged, else muted.
  • function trustIcon(level): The icon of a sender's check, by its level.
  • function withLinks(html): Links in the theme's colour: rich text would draw them pure blue, unreadable on a dark theme.
  • function follow(link): A link of the message is followed only to the web or to an address, and only once its address shows below: under the pointer, or after a first tap. An address is written to here, in Sioul, without what the link would fill in.
  • function linkHost(link): Where a link goes: its host, after any "name@" put before it to mislead.
  • function showAttachments(): The attachments unfolded, and the reading scrolled to its end, where they are (the window's images).
  • function attachmentIcon(kind): An attachment's icon, by its kind.
  • function act(action, target): Filed away, the message leaves the list: the reader closes on it.

RelatedList

crates/sioul-app/qml/RelatedList.qml · based on ColumnLayout

What the thing open is tied to, both ways: its notes, the mail it came from, what it waits for and frees, the people, the project. One row each, with how it is tied; a click opens it where it lives, a right click can undo the tie. Read again whenever a tie is made or undone.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does. The ties are read there (related).
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string uri: "": The thing open, by its address.
  • property var leaveOut: []: Ties shown elsewhere on the card, by how they read ("Step of"…).
  • property string title: "": Its heading; "" for none.
  • property var items: []: The ties shown: each {uri, how, title, …}, those of the kinds left out (leaveOut) taken out.

Signals

  • signal openThing(var item): A tie clicked: the thing it names, to open where it lives.

Functions

  • function reload(): The ties read again, for uri.

SecurityKeyBand

crates/sioul-app/qml/SecurityKeyBand.qml · based on Rectangle

Your security key, asked where you are: a band at the bottom of the writing window when a message is signed at Send, or under the Reader's line when you open an encrypted message with it. What it says comes from Sioul (securitykey.rs): plug the key in (Sioul goes on as soon as it comes), its PIN in a password field with the tries left when some were lost, "Touch your security key" while it blinks, and what went wrong in plain words with what to do: Try again, Let GnuPG release it. No red, no pop-up; the PIN's field is emptied as soon as it is given.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string context: "": Whose band this is: a draft's id, or a message's key.
  • property string purpose: "sign": "sign" in the writing window, "open" in the Reader.
  • property var said: band.quiet: What Sioul says now: {state, line, tries, warm, action}.
  • readonly property var quiet: …: What the band says when nothing is asked: nothing.
  • readonly property bool active: …: Something is asked or said: the band shows.
  • readonly property bool signing: band.purpose === "sign": For a signature at Send (else, to open an encrypted message).

Signals

  • signal go(string pin): Go on, with the PIN typed ("" for the one Sioul holds).
  • signal unsigned: "Send unsigned", in the writing window.
  • signal done: Signed and scheduled, or opened.

Functions

  • function start(): Sioul asks the key: what it says comes back in the band.
  • function say(line): Shows what Sioul said before anything was asked (an expired key).
  • function reset(): Back to nothing asked, the PIN's field emptied.
  • function submit(): The PIN typed, given to Sioul; nothing when the field is empty.
  • function notNow(): Not now: what was asked is let go, the band emptied.
  • function release(): GnuPG asked to let go of the key, which it holds; then Sioul goes on, or says why not.

SpamFilter

crates/sioul-app/qml/SpamFilter.qml · based on ColumnLayout

Sioul's own spam filter, under its settings in Settings ▸ Mail (crates/sioul-app/src/spam.rs, docs/spam-filter.md): the table in use and where it comes from, with what it measured; on a computer, "Train now", the training's progress with "Stop", what the last training found, and what the corpus and the outside material hold, and whether it trains again by itself, once a week, plugged in and idle (only on the computer that made the table in use: greyed on the others, which say which one does). A phone never trains: it says where its table comes from, another device's, brought sealed by the sharing.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …: spam.rs's Status: {trains, table, measured, refused, running, stopping, progress, fraction, ended, by_itself, by_itself_here, by_itself_line, last, corpus, outside}.
  • property string about: "": What it is, in a sentence: the setting's own (settings.rs), said first.
  • property string problem: "": Why "Train now" did not start, else "".

Functions

  • function read(text)

StoppedCard

crates/sioul-app/qml/StoppedCard.qml · based on Panel

Where you stopped: the line left when something interrupted you (a pause, a meal, the night, a timer stopped), shown again until you say it is done, with the task it was about (docs/tasks.md, "Where you stopped").

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var window: The main window (main.qml), which opens what is asked of it. The line's task opens there.

Properties

  • property var stopped: null: The line kept, as the backend gives it: its words (text), when, and the task it was about (task, title); null when none waits.

Functions

  • function reload(): The line read again from the backend.

TakesEditor

crates/sioul-app/qml/TakesEditor.qml · based on ColumnLayout

A medicine's takes at set times each day, as rows (MedicineDialog.qml, PrescriptionDialog.qml): each its time, picked (TimeField.qml), and its own amount, only when it differs from the medicine's dose ("2 tablets" at 20:00, the dose "1 tablet" at the others); Add a take adds a row, each row can be taken out. The amounts and the times are read when the form saves (takes()): no take, two at one time, are said then (health::apply_medicine).

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string usual: "": The medicine's dose, what a take with no amount of its own is given: its field's hint.

Signals

  • signal edited: A take changed, added or taken out by hand (not when load fills the rows).

Functions

  • function takes(): The takes now, [{time, amount}], in the rows' order.
  • function load(takes): Rows for takes ([{time, amount}]); one at 08:00 when there are none.
  • function add(): A new take at a usual time not taken yet: morning, evening, noon, then the hours between.

TaskPanel

crates/sioul-app/qml/TaskPanel.qml · based on Panel

One task, open on the right: its details first (its title, what to do with it now: start, done, not now; its steps, what it waits for and frees, its fields in words, its notes, everything tied to it), then "Edit" turns them into its form: every field, its dates, length, costs and gain, project and notes. Each change is saved as it is made: only the lines that changed are written. A task done asks, quietly, "How was it?".

A new task opens here too, every field unfolded, its title first (startNew): the fields are kept in the form until the title is given (Enter, or leaving the field: another field, Close, Escape, Back); the task is made then, with all of them, and the panel goes on as any task's. Left with no title, nothing is made.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var window

Properties

  • property string uid: ""
  • property var detail: null
  • property bool moreShown: false
  • property var projects: []: The projects a task can belong to: [{id, title}].
  • property var kinds: []: The kinds of task, as you named them: {id, label}.
  • property var categories: []: Every tag in use, to choose one again.
  • property bool making: false: A new task's form, not made yet: its title to give first.
  • property bool editing: false: A task's form, its fields open to change ("Edit" on its details).
  • property bool feltShown: false: "How was it?" unfolded, on a task done.
  • property string madeUid: "": The task just made from the form: its form stays until it is read back.
  • property bool unsaved: false: Fields changed after the making, before the reading: saved once it is read.
  • readonly property var card: panel.detail ? panel.detail.card : null
  • readonly property bool fresh: …: The form of a task not read yet: new, or just made (newTaskForm, no card).
  • readonly property bool canEdit: …
  • readonly property bool form: …: The form shows (a new task, one just made, or "Edit"); else its details.
  • readonly property bool done: …
  • readonly property var costs: …: The four costs; the gain apart.
  • readonly property var limited: …: What its list does not keep (Google Tasks): greyed, never hidden.
  • readonly property int nextGap: …: The gap the next wait added takes, in minutes (the form's "Then wait"): 0, none.
  • readonly property real naturalWidth: …: Its natural width, which the page gives it beside the list (TasksPage.qml): its fields at about 70 characters of the body font, a readable line, or its tiles side by side, whichever is wider; no cap of its own (docs/qt-quick.md, "An editing card's width").
  • readonly property alias costTiles: ratingsTop: The costs' tiles (for the window's tests and pictures).
  • readonly property var marginMinutes: [0, 5, 10, 15, 20, 30, 45, 60, 90, 120]

Signals

  • signal closed
  • signal focusRequested(string uid, int minutes)
  • signal made(string uid): A new task made from the form, once its title was given.

Functions

  • function keeps(field)
  • function reload()
  • function startNew(source): A new task's form: blank, or what Add ▾ makes from source (a card's {uri, key, start}: its title, its tie). Returns what went wrong, else "".
  • function make(): The title given: the task made from the form, in the list chosen. The panel then goes on as any task's (the page opens it: made).
  • function leave(): The form left (closed, another task opened): a title typed makes the task, as leaving its field does; the panel does not go on with it.
  • function confirmTitle(text): For the window's tests: the title typed (or the one given kept), then confirmed.
  • function showRatings(): For the window's pictures: the costs and the gain in view.
  • function rate(name, value): For the window's tests: a rating given as by hand.
  • function askDoAt(): For the window's tests: "Do at…" opened; then a time given there, as by hand ("2026-10-06T16:00", minutes): it says what went wrong, else "".
  • function pinAt(at, minutes)
  • function rebind(): The fields whose own editing undoes their binding, bound again to the task shown.
  • function hold(edit, more): The form's own copy changed: a task not made yet, or not read yet. What is typed in the title stays typed.
  • function chooseList(id): A new task's list, chosen before it is made: what that list keeps, greyed or not.
  • function waitFor(other, otherTitle, wait, gap): What it waits for, in the form of a task not read yet; with a gap in minutes, written in the task waited for once this one is (work.rs, write_gaps).
  • function gapWords(minutes): A wait's gap in words, as the details say it (taskview.rs, gap_words): "two weeks after it".
  • function moveTo(list, confirmed): Into another list: asked first when it would not keep everything.
  • function change(field, value): Saves the form with one field changed; a task not made or not read yet keeps it in its form.
  • function changeMargin(side, minutes): The time kept before or after it, saved.
  • function rating(name): A cost or the gain, 0 to 10; null when unsaid.
  • function changeRating(name, value)
  • function changeRatings(values): Several at once ("Looks right": what was felt before, for what was unsaid), in one save.
  • function level(): What it takes, from its ratings once a cost is said (the plan's rule, docs/tasks.md): light up to 3, the usual from 4 to 6, heavy from 7; it gives back with a gain of 5 or more and no cost above 3. "" when no cost is said: then it is chosen.
  • function dayText(text): A day as words: "Thursday 8 October".
  • function facts(): Its fields in words, for its details: only what is said; the date asked, the length and what it waits for are said above, as the plan words them.
  • function today(): Today, as the backend dates what is felt: "2026-10-06".
  • function feltToday(): Today's "How was it?" as kept so far; null when none today (an older turn's stays out).
  • function keepFelt(values): How it was, kept as felt (only that, read from the file itself: what else the task says is left as it is on disk).
  • function minutesText(m)
  • function addStep()

TaskRow

crates/sioul-app/qml/TaskRow.qml · based on ItemDelegate

One task: a circle to tick, its title, and below, quietly, what matters about it: the date asked as time left, how long it takes, what it waits for. Nothing is red; a date within a week is in a warmer tone. The same task looks the same everywhere: in the list, on the board, in a panel.

Required properties (whoever makes it must give them)

  • required property var task: The task as the core's views give it (taskview): its uid, title, status and the words of its details.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var sioul: null: For the circle's name, said by screen readers in words.
  • property bool selected: false: Its details are open in the panel: the row is highlighted.
  • property bool compact: false: Tighter, its words on one line: on the board, on a phone.
  • property int depth: 0: Indent for steps, in levels.
  • readonly property bool done: …: Done or dropped: its circle filled, its title quieter.
  • readonly property var details: …: The words under its title that say something: the date asked, the length, the steps, what it waits for, where you stopped.

Signals

  • signal open(string uid): A click: its details asked, by its UID.
  • signal tick(string uid): Its circle ticked: done, or open again.
  • signal menu(var task): A right click or a long press: its menu asked.

TaskTimeline

crates/sioul-app/qml/TaskTimeline.qml · based on ColumnLayout

The timeline (a Gantt chart): each open task on the days the plan gives it, from today on the left. Days without room for tasks are shaded; the date asked is a small diamond, never a red line; a task whose plan ends after its date has a warmer edge. A bigger task is a thin bar over its steps. Nothing here is a deadline in your face: it is the plan, on demand.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var timeline

Properties

  • property string opened: ""
  • property string today: …: Today ("2026-10-06"): the window's clock (main.qml). The plan starts on the day it was made; past midnight, today's line moves to its own day before the plan is made again.
  • readonly property int todayIndex: …
  • readonly property int dayWidth: …: Narrower days when that shows the whole plan, never under 20 pixels.
  • readonly property int rowHeight: 30
  • readonly property int titleWidth: …: The titles' column: narrower on a phone, for the days.
  • readonly property var days: …
  • readonly property var rows: …

Signals

  • signal open(string uid)
  • signal menu(var task): Right click, or a long press on a touch screen: the task's menu (its details, Add ▾, Link to…).

TimeField

crates/sioul-app/qml/TimeField.qml · based on RowLayout

A time of day, picked rather than typed: its hour and its minute, each a short list (every five minutes, and the minute set when it falls between). The keyboard reaches both: Tab, then the arrows, or the list opened with Space. "08:00" in, "08:00" out (time, edited).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string time: "08:00": "08:00".
  • readonly property int hour: …
  • readonly property int minute: …
  • readonly property var hours: …
  • readonly property var minutes: …: Every five minutes, and the minute set when it is between two.

Signals

  • signal edited: Picked by hand (not when time is set from outside).

Functions

  • function pad(n)
  • function pick(h, m)

WeekPlanning

crates/sioul-app/qml/WeekPlanning.qml · based on ColumnLayout

The week as a planning: seven days side by side, the hours down, each event where and as long as it happens, side by side with what overlaps it. Whole days sit in a band on top. Only the hours given to work, your admin or free time are shown, and those of any event outside them: not the night. They fill the height, and grow past it, scrolled, until each event's title reads whole in its card: on a phone's week the cards are narrow and their titles take several lines (up to zoomMost an hour; past it, the shortest end their title with "…"). A quiet line marks now. A double click on an empty hour makes an event there.

An event is moved by hand (docs/client.md, "Calendars"): dragged, it keeps its length, to another time, and in the week to another day; by its bottom edge, its end changes. Where it would go is drawn, with its times; let go, it is written and sent as its form writes it, and "Undo" waits in the status line. A repeating one asks first: only this time, or every time. One in a calendar that can only be read stays where it is; whole days stay in their band. With a mouse, press and drag; with a finger, a long press picks it up (a plain swipe scrolls). One set of handlers for the whole planning (TimeDrag.qml): the events carry none.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var days
  • required property var locale

Properties

  • property var opened: null: The event open on the right, to show it chosen.
  • readonly property bool narrow: planning.width < 600: A phone's width: the hours' column narrower, so the days get the room.
  • readonly property int gutter: planning.narrow ? 40 : 52
  • readonly property var range: …: The hours shown, in minutes from midnight, whole hours: those given to something (docs/areas.md), else the usual day from its start to 22:00; widened to every event of the days shown.
  • readonly property int hoursShown: …
  • readonly property real dayWidth: …
  • readonly property real titleLine: …: The cards' type, measured: the lines a title takes at its card's width.
  • readonly property real timeLine: …
  • readonly property int cardPadding: 4: Above and under a card's text; a card is never less than one line of title.
  • readonly property real cardLeast: …
  • readonly property real zoomMost: 160: An hour at most this tall: past it, the shortest cards end their title with "…".
  • readonly property real legibleHour: …: How tall an hour must be for every card to show its whole title: the tallest that one of them asks, by its title's lines over its length. A title on one line asks nothing: a card's least height holds it.
  • readonly property real hourHeight: …: As tall as the window allows, never thinner than a line of text; taller, scrolled, when a card would cut its title, up to zoomMost.
  • property real now: Date.now() / 1000: Now on the clock (Unix seconds) and today ("2026-10-06"): the window's clock (main.qml), moved at each minute's turn and when the app comes back. Only the line follows it, and today's marks when the day turns.
  • property string today: …
  • readonly property int minuteNow: …: Now in minutes from midnight, for its line.
  • readonly property int todayIndex: …: Today's column among the days shown; -1 when today is not shown.
  • property var grab: null: An event taken by the hand: {event, column, part, pressMinute}; where the pointer is now.
  • property point pointer: Qt.point(0, 0)
  • property var landed: null: Let go, or waiting for "only this time / every time": drawn where it goes until the days come back.

Signals

  • signal open(var event)
  • signal menu(var event)
  • signal newAt(string day, int hour)

Functions

  • function textWidthOf(event): The width a card gives its text: its slot among what overlaps it, less its colour bar and margins (block below).
  • function linesOf(text, width): The lines text takes at width, as a card's title wraps it: words to a line while they fit, a word longer than the line broken where it must.
  • function yOf(minute): Where a minute of the day sits.
  • function minuteAt(y): The minute at y in the hours' content (not clamped).
  • function chosen(event)
  • function scrollToStart(): When the hours do not all fit: on today, an hour before now; else the first.
  • function blockOf(event, column): An event's block, as its column draws it: {x, y, width, height} in the hours' content.
  • function endsHere(event, day): Its end in this day's column, not cut at midnight: its bottom edge is its end.
  • function movable(event)
  • function columnAt(x)
  • function eventAt(p): What lies at p (the hours' content): {event, column, part: "body" or "bottom" (its bottom edge's grab zone, 8 px at least)}; else null.
  • function target(grab, p): Where the event taken would go: {start, end} in Unix seconds, and the column it shows in.
  • function clock(seconds)
  • function said(grab, to): "09:00–10:30"; on another day, its day first: "Tue 6, 09:00–10:30".
  • function take(thing, p)
  • function drop(p)
  • function save(onlyThis): The event let go written: that time alone, or every time.

WordsTab

crates/sioul-app/qml/WordsTab.qml · based on ColumnLayout

Settings ▸ Words (« Mots »; docs/words.md): the words Sioul recognises things by. On top, the languages read and the countries whose names are read, ticked. Then one line for each thing recognised, in four groups (mail; money and papers; the phone; tasks and a public address), each with how many words it holds and how many you changed; a line opens its own page, on a computer as on a phone (never a fold that pushes the list down): what its words do, its lists as word rows (SettingRow.qml: chips with ×, a field to add one), "Back to the defaults". The rows come from Settings (settings::words_rows, section "words"): each line's note (words.about.<line>, its group's name in unit), then its lists (words.<list>); a change is saved at once, written as its difference from the packs.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var rows: Settings' rows of this tab (section "words").

Properties

  • property string open: "": The line whose page is open ("codes", "voicemail"…); "" for the list of lines.
  • readonly property var ticked: …
  • readonly property var notes: …
  • readonly property var openNote: …
  • readonly property var openRows: …: The open line's lists: the rows of its group, its note aside.

Signals

  • signal save(string key, var value, var shown): A list changed, or a line taken back (Settings saves it, then reads its rows again). shown: the value the row showed (changeSetting).
  • signal toTop: A line opened or closed: the page scrolled back to its top.

Functions

  • function show(key): The line holding a list ("words.voicemail.operators"), opened: where another page sends you.

Settings

The settings panels, their rows, and the set-up shown under some settings.

AppNotesSetup

crates/sioul-app/qml/AppNotesSetup.qml · based on ColumnLayout

Other apps' notifications, on a phone (docs/android.md, "Notifications from other apps"), in two parts (part). This phone ("phone"): what Sioul does with other apps' notifications and what it never does; Android's notification access and its two steps for an app installed from a file; holding on or off; the gathered times; what rang before Sioul held it, each with Android's page to make it silent. What reaches you ▸ Exceptions ("lists"): each app and conversation by time, a row of the matrix of what reaches you (AttentionGrid.qml: as usual, at once, gathered or held at each time), then each app, conversation and site seen, with its choice. On a computer, one sentence: this is the phone's; in Exceptions, the rows by time set on the phone, by name, changed here as there.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var shown: …: appnotes.rs's setup: {android, access, restricted, contacts, hold, times, heard, rang, apps, conversations, sites, grid, more}.
  • property string part: "all": "phone" (this phone's setup), "lists" (each app, conversation, site), or "all".
  • readonly property bool phonePart: …: This phone's part shown: on a phone, with part "phone" or "all".
  • readonly property bool listsPart: …: The lists' part shown: on a phone, with part "lists" or "all".
  • readonly property bool computerPart: …: A computer, in Exceptions: the rows by time set on the phone, when there are some.
  • readonly property bool byTime: setup.listsPart || setup.computerPart: The rows by time shown: the lists' part, or a computer's rows set on the phone.

Functions

  • function reload(): What is shown read again from the backend (appNotesSetup).
  • function act(verb, args): A change asked of the backend (appNotesChange): verb and its arguments; its answer shown.

CallsSetup

crates/sioul-app/qml/CallsSetup.qml · based on ColumnLayout

Settings ▸ This phone ▸ Calls (docs/android.md, "Calls"): what Sioul does with calls, what it never does, what always rings; then this phone: Sioul as Android's "Caller ID & spam app" (Android 10 and later, asked in Android's own dialog), reading the contacts, where a declined call goes (the operator's voicemail, read with the codes the phone app dials), and what Sioul leaves to Android (texts, its own blocked numbers). Who rings when is What reaches you's (By person ▸ Calls; Exceptions ▸ Always through).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …: calls.rs's setup: {android, state: {api, available, held, contacts, table, emergency_at}, moment}.
  • readonly property var phone: setup.shown.state || ({})
  • readonly property bool held: setup.phone.held === true
  • readonly property bool available: setup.phone.available === true
  • readonly property bool tooOld: …

Functions

  • function reload()
  • function act(verb, args)

Inline components (used inside this file)

  • component Heading: Label
  • component Said: Label
  • component Note: Label

DndSetup

crates/sioul-app/qml/DndSetup.qml · based on ColumnLayout

Do-not-disturb's parts (docs/do-not-disturb.md), each where it belongs (part): what this device's system lets Sioul do, with the pages it needs (What reaches you ▸ Do not disturb; This phone); the Always through list, the same on every device (What reaches you ▸ Exceptions); on a phone, who on it is starred (Sioul never stars anyone: it opens their contact), and Sioul kept in step in the background (This phone).

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var shown: …: everywhere.rs's setup: {here: {on, line, lines, consent, offers}, gnome, people, problem, said, android, stars, steps}.
  • property var editing: null: The person being written by hand, or changed: its id ("" new), or none.
  • property var found: []: The people found by the search for Always through, to add.
  • property string none: "": What the search says when it found nobody; "" otherwise.
  • property string part: "all": Which parts: "device" (this device's system), "list" (Always through), "phone" (this device's system, the stars and the background), or "all".
  • readonly property bool deviceShown: …: This device's part shown: part "device", "phone" or "all".
  • readonly property bool listShown: …: The Always through list shown: part "list" or "all".
  • readonly property bool phoneShown: …: A phone's own parts shown (its stars, the background): on a phone, part "phone" or "all".

Functions

  • function reload(): What is shown read again from the backend (dndSetup).
  • function edit(person): Someone to write by hand ("" new) or to change: the fields filled anew.
  • function act(verb, args): A change asked of the backend (dndChange): verb and its arguments; its answer shown.

HealthSettings

crates/sioul-app/qml/HealthSettings.qml · based on Popup

The Health page's settings (its ⚙), set once or rarely, made the first time they open: where the pharmacy and renewal errands go, the usual meals, naps and night, the pause to move, the limit on chats. The medicines and the prescriptions are the page's content, changed there (MedicinesSection.qml), as is a day that differs, that day only. On the right of the window, all of a phone's; Escape or a click outside closes it.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …: As the backend gives it (health::settings_view).
  • property bool toNeeds: false: Opened where the usual meals, naps and night are set (the Porch's "Set my night", Settings ▸ Hours): scrolled there once open, and kept there a moment while the rows above it are laid out, then left to the hand.

Signals

  • signal changed: Something changed that the page shows (the usual meals, naps and night): it reads its days again.

Functions

  • function reload()
  • function saved(): A setting changed.
  • function setting(key, value)
  • function showNeeds()
  • function scrollToNeeds()
  • function showEnd(): The panel's end brought into view: the night's last rows, the pause to move and the limit on chats (the window's pictures).

NeedsSection

crates/sioul-app/qml/NeedsSection.qml · based on ColumnLayout

The usual meals, naps and night, set first, in the Health page's settings: times kept free of tasks, the work planned around them (docs/health.md, "Meals, rest and sleep"). Each block named as you like, on the weekdays you choose, its notices on or off; a day that differs is changed on the page itself, that day only. Nothing about eating or sleeping is recorded here, and nothing is said when one passes.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …: {needs, usual, gaps, wake}, as the backend gives it.
  • property string problem: ""
  • readonly property bool narrow: section.width < 560: A narrow screen: each block's numbers under its name.

Signals

  • signal changed: Saved: the page's days follow.

Functions

  • function reload()
  • function edit(change): The settings changed by change (on a copy), saved, and read again.
  • function clock(text): "08:30" as typed, or nothing when it is no time.

Inline components (used inside this file)

  • component LabeledTime: RowLayout: A time, typed: saved once it reads as one.
  • component LabeledMinutes: RowLayout: Minutes, chosen.
  • component BlockEditor: Panel: One meal or nap: its name, its time and minutes, its weekdays, its notices.

PauseSetup

crates/sioul-app/qml/PauseSetup.qml · based on ColumnLayout

The pauses' setup, under their settings (Settings ▸ Pauses, docs/pauses.md): a try-out of the pause's screen, which holds nothing; the last pause forgotten. What this device's do-not-disturb can do, with the system's pages it needs, is What reaches you ▸ Do not disturb's and This phone's (DndSetup.qml); shown here only when deviceShown.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var report: …: {on, line, consent, offers: [{key, label}], gnome, forgettable}, read when shown.
  • property bool deviceShown: true: What this device's do-not-disturb can do, said here too.

Signals

  • signal tried: The pause's screen as it will be, nothing held.

Functions

  • function reload()

PhoneMessagesSetup

crates/sioul-app/qml/PhoneMessagesSetup.qml · based on ColumnLayout

Settings ▸ This phone ▸ On your computers (« Sur vos ordinateurs »), on a phone (docs/android.md, "Messages on your computers"): what this phone's notifications send to your computers' Porch, sealed through your sharing. The part's switch (off until you turn it on, here and on each computer that should show them), what never leaves the phone, then each app seen lately: not on your computers, who and when, or the words too. The SMS app sends its words unless you say otherwise; every other app sends nothing until you choose it. Nothing here touches what reaches you on the phone.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …: phonemsgs.rs's setup: {android, sharing, part: a SettingRow's row, apps: [rows]}.
  • property string said: ""

Functions

  • function act(verb, args)

PhoneSetup

crates/sioul-app/qml/PhoneSetup.qml · based on ColumnLayout

Settings ▸ This phone (« Ce téléphone »), on a phone: what sets this phone up, nothing that decides when (that is What reaches you). Call screening (Sioul as Android's caller ID & spam app, the contacts, where a declined call goes, texts; CallsSetup.qml); other apps' notifications (the access in two steps, holding, the apps that rang before Sioul held them; AppNotesSetup.qml); what they send to your computers (PhoneMessagesSetup.qml); Do Not Disturb's access and its modes, who of your Always through people is starred here, keeping in step in the background, the battery (DndSetup.qml); exact alarms and Sioul's own notifications.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property bool exact: true: Whether Android lets Sioul set exact alarms (reaches.rs, view).

Inline components (used inside this file)

  • component Heading: Label

SettingRow

crates/sioul-app/qml/SettingRow.qml · based on ColumnLayout

One setting: its name, the control that changes it, and a sentence on what it does. Used in a page's settings panel and inside a Porch lane's "?". Each kind's control is made for a setting of that kind only (a Loader each): with every kind's controls in each row, hidden, the Porch's settings panel alone took some 18 MB, and each page has its panel.

Required properties (whoever makes it must give them)

  • required property var setting: The setting, as the core describes it (settings::Setting): its key, kind, name, words, value and choices.
  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • readonly property var weekdays: …: The days of a week, in the order the office hours and windows are listed.

Signals

  • signal save(string key, var value, var shown): shown: the value the row showed, what its change is set over the files from (changeSetting), so that what another device added meanwhile stays.

Functions

  • function same(a, b): Whether two values are the same, compared as JSON.

SettingsButton

crates/sioul-app/qml/SettingsButton.qml · based on ToolButton

The small button that opens a page's settings, at the end of its first row; "Aa" opens how long text reads.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string view: "": The page whose settings it opens: "tasks", "mail", "agenda"… (the core's settings::for_view).
  • property bool reading: false: "Aa": the reading settings, wherever long text is.

Functions

  • function show(open): Its settings panel opened (made the first time), or closed.
  • function scrollTo(key): For the window's images: the panel scrolled to one of its settings.
  • function grab(path): For the window's images: the panel floats over the page, out of its picture.

SettingsPanel

crates/sioul-app/qml/SettingsPanel.qml · based on Popup

The settings of one page, on the right of it: each with what it changes, in a sentence. A change is saved at once, into the configuration file, its comments kept. Escape or a click outside closes it.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string view: "": "porch", "mail", "agenda", "tasks", "notes", "reading", "contacts", "time", "general".
  • property var rows: []
  • property string problem: ""

Functions

  • function reload()
  • function scrollTo(key): A setting at the top of the panel, its group's title above it (the window's images).
  • function save(key, value, shown): shown: the value the row showed: a list's change is set over the files as they are now.

SharePanel

crates/sioul-app/qml/SharePanel.qml · based on ColumnLayout

Sharing with your other computers, on the Parameters page: what travels and how, the folder a sync carries, a passphrase typed once on each computer (twice on the first), then where things stand; what travels from this device, part by part; the versions kept before other devices' changes, to put back.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var status: …
  • readonly property var backup: panel.status.backup || ({}): The other devices' files fetched from the server too: {shown, line, on, given, found}.
  • property string problem: ""
  • property string asking: "": Notes or papers about to be switched on: what would travel, said first.
  • property string estimate: ""
  • property bool showHistory: false: The versions kept, shown on demand: part → file → versions; one being put back, said first.
  • property var history: []
  • property string openFile: ""
  • property var confirming: null
  • property bool puttingBack: false
  • property bool byServer: false: How this device reaches the folder: through a folder a sync app carries, or Sioul keeping it in step with a Nextcloud itself, no sync app (docs/database.md, "Kept in step by Sioul itself"); started off the window's thread.
  • property bool starting: false
  • property bool sending: false: "Send everything again" pressed, its answer not read yet, and what it said before.
  • property string againBefore: ""
  • property bool stopping: false: "Stop sharing" pressed: what stops and what stays, said first.
  • readonly property bool android: Qt.platform.os === "android": Android: no folder dialog (it hands out content:// addresses, not paths); the path typed, or one of the folders your other devices share through.
  • property bool filesAccess: true
  • property var candidates: []

Functions

  • function sendAgain(): "Send everything again", off the window's thread: what it did is read a few seconds later.
  • function listHistory()
  • function reload()
  • function choose(folder): A folder typed or picked: what it holds is said at once.
  • function browse(): On Android, Sioul's own browser (FolderBrowser.qml): the system's picker refuses the phone's storage. It opens in Documents, where Murena's eDrive keeps what it syncs.

TextsSetup

crates/sioul-app/qml/TextsSetup.qml · based on ColumnLayout

Settings ▸ This phone ▸ Texts (« SMS »), on a phone (docs/texts.md): what Sioul does with the phone's texts once you allow it, each permission with the sentence that says why, Android's question for them, and the sharing's part "Texts" (off until you turn it on, here and on each computer that should read or write them); what the phone holds and how much has gone to your computers, read again while the import runs; the largest media file brought there. Sioul never asks to be the SMS app: the phone's messages app stays their record.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …: texts.rs's setup: {android, state: {read, receive, send, phone_state, sms_app, sims}, on, sharing, progress, importing, cap, said}.
  • readonly property var allowed: setup.shown.state || ({})
  • readonly property bool all: …

Functions

  • function act(verb, args)

Inline components (used inside this file)

  • component Line: Label

Dialogs and pop-ups

Forms and questions shown over a page.

AccountPassword

crates/sioul-app/qml/AccountPassword.qml · based on Dialog

An account's password, given on this device: an account come from another device arrives without one, since passwords never travel. Typed, or taken from your Bitwarden vault, found by the name the account logs in with (its address, unless it names another) as the user name; tested with the account's server before this device's keyring keeps it.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var account: null: The account, as the Accounts page has it: id, address, host, login.
  • property string problem: ""
  • property string note: ""
  • property string vault: "missing": Bitwarden: "missing" (no account set), "locked" or "unlocked".
  • readonly property bool google: …: Google's mail (Gmail, Google Workspace): an app password, never the account's own.

Functions

  • function ask(account)
  • function site(): The account's server, as a site: the vault's logins for it come first.
  • function login(): The name the account logs in with: its own, else its address.
  • function fromVault(): The vault opened first when it is locked; then its logins, found by the account's login as the user name.
  • function take(item): A login chosen in the vault: its password tested and kept at once.
  • function keep()

BankAccountDialog

crates/sioul-app/qml/BankAccountDialog.qml · based on Dialog

A bank account (docs/accounting.md, "Bank accounts"): its name and kind (a bank, PayPal, Stripe), the budgets it fills (the first takes what nothing else places), the balance kept on it at least, and the reserves that top it up, in their order. Taking one out keeps its movements in sioul-bank.toml.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var budgets: []
  • property var reserves: []
  • property string accountId: ""
  • property string problem: ""
  • property bool removing: false
  • readonly property var kinds: ["bank", "paypal", "stripe", "other"]
  • property var fills: []: In their order: the first budget takes what nothing else places; the first reserve tops up first.
  • property var toppedUpBy: []

Signals

  • signal done

Functions

  • function edit(account): account is a card of the bank view, or null for a new one.
  • function amount(text): An amount as typed, "1 500,50 €": its number, 0 when nothing is typed, NaN when it is no number (never a silent 0).
  • function toggled(list, id, on): Ticked: added at the end; unticked: taken out.
  • function earlier(list, id): One place earlier in its list.
  • function save()

BankRulesDialog

crates/sioul-app/qml/BankRulesDialog.qml · based on Dialog

Where a bank account's movements go (docs/accounting.md, "Bank accounts"): a movement whose label holds one of a rule's words goes where the rule says, a budget, a reserve (money moved with a savings account), or another of your accounts (in no budget). The first rule that holds wins; each is saved as soon as it is changed.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var budgets: []
  • property var reserves: []
  • property var accounts: []
  • property var account: null: The bank account's card, from the bank view.
  • property string problem: ""
  • readonly property var directions: ["", "debit", "credit"]
  • readonly property var places: …: Where a movement can go, for every rule.

Signals

  • signal changed

Functions

  • function show(account)
  • function refresh(accounts): The card again, once the rules were written.
  • function words(text)
  • function save(rule, wordsText, direction, to, everywhere): rule: the rule as shown (named by its id, or its place while it holds the same); null for a new one.

BudgetDialog

crates/sioul-app/qml/BudgetDialog.qml · based on Dialog

A budget: its name, its period, the balance to reach by the end of each period, and what it is for: work, your admin, leisure, any of them together (docs/areas.md), which says the hours it is in view. Taking one out keeps its lines in the file.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string budgetId: "": The budget changed, by its id; "" for a new one.
  • property string problem: "": What went wrong when saving, in words; "" for nothing.
  • property bool removing: false: "Take it out" pressed once: the next press takes it out.
  • readonly property var periods: ["month", "year"]: The periods offered, in their order.
  • property string area: "": "work", "admin+leisure"…; "" when none is ticked: your admin.

Signals

  • signal saved(string id): Saved: the budget's id.
  • signal removed: The budget was taken out.

Functions

  • function edit(id, shown): shown is the budget's page, or null for a new one.
  • function amount(text): An amount as typed, "1 234,50 €" or "−650": its number, 0 when nothing is typed, NaN when it is no number (never a silent 0).
  • function save(): The form saved: its amount read first (said when unreadable), then the budget kept by the backend.

ConfirmDialog

crates/sioul-app/qml/ConfirmDialog.qml · based on Dialog

Asked once, before something that cannot be undone: what happens, in a sentence, and the action named by what it does. "Cancel" is the default.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string sentence: "": What happens, in a sentence.
  • property string action: "": The button that does it, named by what it does ("Delete for good").
  • property bool commands: false: The sentence holds commands in backticks, Sioul's own (how to install an antivirus): each shown to copy (CommandText.qml). Off unless asked: a name from a message is never taken for a command.

Signals

  • signal confirmed: The action was chosen.

Functions

  • function ask(heading, sentence, action, commands): Asks, then calls confirmed if the action is chosen. The heading and the sentence may name what came in a message (an attachment): plain text.

ContractDialog

crates/sioul-app/qml/ContractDialog.qml · based on Dialog

A contract, new or changed: what it is, with whom, your number with them, the payment that pays it, when it renews and the notice it needs, how to stop it, what it covers. The notice proposed is the one usually asked for its kind; yours is what your contract says.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var kinds: []: {id, label, notice}.
  • property var presets: []: {id, title}: the recurring payments to tie it to.
  • property string contractId: ""
  • property string problem: ""
  • property bool noticeTouched: false: The notice was written by hand: a kind chosen after does not change it.

Signals

  • signal saved

Functions

  • function begin(start)
  • function edit(contract)
  • function fill(c)

DayReview

crates/sioul-app/qml/DayReview.qml · based on Dialog

The end of the work day, or of the whole day before sleep (docs/reviews.md). First, in words, how the day started and what the plan did with it; for the night, the end of work as said then, tomorrow's first step and what the day asked and gave, never a number. Then how the day felt, its mix, a note in Markdown: each answer optional, and closing without any is as plain as with. "Close the work day" closes it as "Done for today" always did, and the screen after it says where everything went; "Not now" changes nothing. The notes of the last days, folded, in the words said then: no count, no streak, no calendar. Made the first time it is asked for (main.qml).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var view: null: The sheet's view (reviews::view): kind, date, title, lines, balance, the answers given, back.
  • property string felt: "": The answers being given: "" for none.
  • property string mix: ""
  • property bool previewing: false
  • property bool backShown: false

Functions

  • function show(kind): "work" or "night": the sheet for it, with the answers already given, or those being given when it was left with "Not now" the same day.
  • function closeIt(): Kept; the work day closed as "Done for today" closes it, its screen after.
  • function write(text): For the window's pictures: a note written, the sheet as an image.
  • function grab(path)

DoneDialog

crates/sioul-app/qml/DoneDialog.qml · based on Dialog

After "Done for today": the day is already closed ("Undo" waits in the status line). Read in ten seconds: where work went and when it comes back, what got done if anything, the first step, what still gets through. No count of what was not done, no question, no judgement (docs/tasks.md).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var closing: null
  • property string firstStep: ""
  • property bool changing: false
  • property bool deadlineLeft: false

Functions

  • function show(closing)
  • function keepStep()
  • function grab(path): For the window's tests: the dialog as an image, its frame included.

DoseTaken

crates/sioul-app/qml/DoseTaken.qml · based on Dialog

A dose marked more than half an hour past its time, or due while Sioul was closed: when it was taken (now, unless you say), or that it was not. For a medicine taken every few hours, the next dose comes that many hours after the time said: the hours between two doses are kept.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string key: ""
  • property var info: null
  • property string problem: ""

Signals

  • signal answered: Answered, taken or not: the pages showing doses read them again.

Functions

  • function ask(key)
  • function taken()

EventDialog

crates/sioul-app/qml/EventDialog.qml · based on Dialog

An event's form: the title, whole days or hours, when, where; folded underneath, notes, how it repeats, the time kept before and after it (getting there, getting ready, coming back), when it is reminded (as usual, not this one, or so long before: docs/reminders.md), what it costs and gives back (four costs and a gain as tiles, 0 to 10, unsaid until said: CostTiles.qml), and the calendar when there are several. Opened from an event's details ("Edit"), or new.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string key: "": The event's file; empty for a new one.
  • property var calendars: []
  • property bool moreShown: false
  • property string problem: ""
  • property var links: []: What a new event is made from: links it carries ("mid:…", "sioul:task/…").
  • readonly property var repeats: …
  • readonly property var marginMinutes: [0, 5, 10, 15, 20, 30, 45, 60, 90, 120]
  • property var around: ({ before: 0, after: 0 }): Minutes before and after; the four costs and the gain, 0 to 10 or unsaid (null).
  • property var demands: …
  • property string remind: "": Its reminder before it: "" as usual, "none", or minutes ("15"); and the choices offered.
  • property var reminds: []

Signals

  • signal saved

Functions

  • function pad(n)
  • function minutesText(m)
  • function rate(name, value): A cost or the gain, 0 to 10, or null when unsaid; kept until Save.
  • function rating(name)
  • function edit(key, day, hour): Opens on an event, or on a new one on day ("2026-10-05"), at hour or the next full hour.
  • function makeFrom(text, note, link, day): A new event made from something: its title and notes given, the link kept.
  • function showRatings(): For the window's pictures: the costs and the gain in view.
  • function fill(text, from, to, how): For the window's tests: as if typed, then saved.
  • function save()
  • function form()

FolderBrowser

crates/sioul-app/qml/FolderBrowser.qml · based on Dialog

A folder chosen in Sioul itself, on Android: the system's picker refuses the phone's storage (Murena's, among others) and gives addresses, not paths. The phone's folders are read through "All files access"; one your other devices already share through says so.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var shown: …: The folder shown: its path, its parent's, its folders, and whether it can be read.
  • property bool access: true: Whether Android gives Sioul "All files access": without it, the phone's folders cannot be read.

Signals

  • signal chosen(string path): A folder chosen, by its path.

Functions

  • function begin(path): Opens in path, else in the phone's storage.
  • function go(path): The folder at path shown, its list scrolled back to the top.

Interruption

crates/sioul-app/qml/Interruption.qml · based on Dialog

Something interrupts you: a meal's, a nap's or the night's notice, or you stop of your own accord. For a meal, a nap or the night, today only: a few minutes later (as often as you like), at another time, or not today, without a word asked. Always: one line on where you stopped, shown again when you are back (StoppedCard.qml). Nothing comes again because of it.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string key: "": A block of today ("meal:1"), or "" to note where you stopped alone.
  • property var block: null: Its row, as needsToday() gives it.
  • property string problem: ""

Signals

  • signal changed: The block moved or skipped: the pages showing it read again.

Functions

  • function ask(key)
  • function keepLine(): The line kept when it changed; an empty one is "done" only when typed so.
  • function move(minutes, time)
  • function skip()

LineDialog

crates/sioul-app/qml/LineDialog.qml · based on Dialog

A line of a budget changed in place: its label, amount and date. Its links, its budget and the comment saying where it came from stay.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property string uri: ""
  • property string shown: "": The line as its row showed it (day, value, label): found again by it in the file, which may have changed meanwhile (budget.rs, SeenLine).
  • property string problem: ""

Signals

  • signal changed

Functions

  • function begin(line)
  • function save(): Written into the file when the amount is one; else said here, the form kept open.

LinkPicker

crates/sioul-app/qml/LinkPicker.qml · based on Dialog

"Link to…": finds anything, by a few words of its title, of one kind or all, and ties it to the thing open. What is already tied says so.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var source: null
  • property string kind: ""
  • property var found: []
  • readonly property var kinds: …

Functions

  • function show(source, kind): kind: what to look among first ("task", "event", "project"…), else all.
  • function search()
  • function type(text): For the window's tests: as if typed, and its picture (the dialog floats outside the page's).
  • function grab(path)
  • function chooseFirst()
  • function choose(item)

LoginChooser

crates/sioul-app/qml/LoginChooser.qml · based on Dialog

Which of the vault's logins to take, found by two fields, each optional, both matching when both are filled: Site (the logins' sites, else their names; never their user names) and User name (the user name only). Opened for a site, Site holds its domain, or that of the login chosen there last; for a mail account, User name holds the name it logs in with (its address, unless it names another). Names, user names and sites only here: a password leaves the vault for the one login chosen. A login made for another domain than the page's says which.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string url: "": The address the logins are for: a site's page, or a mail account's server.
  • property bool warnElsewhere: true: A login made for another domain than the page's said in the warm colour, so a look-alike site shows; not for a mail account, whose server is seldom where its provider's login is kept (imap.gmail.com, accounts.google.com).
  • property var shown: …: What the last search found, and what it asked.
  • property int waiting: 0: A large vault is searched off the window's thread: the search waited for (its ticket, else 0, and what it asked), and whether Enter came first.
  • property var waitingFor: ({ site: "", user: "" }): What the fields held when the search waited for: an answer for older fields is not shown.
  • property bool takeWhenFound: false: Enter was pressed while the search waited: its first login is taken once found.
  • property alias site: siteField.text: For the window's tests: what the fields hold.
  • property alias user: userField.text: For the window's tests: what the User name field holds.
  • property string takeText: …: What taking a login does: "Fill" in a site, "Use" for an account's password.

Signals

  • signal chosen(string item): A login taken, by its id in the vault.

Functions

  • function begin(url): Opened for a site's page: Site holds its domain, or the domain of the login chosen there last (one made for another site: a sign-in with Google).
  • function beginForAccount(server, login): Opened for a mail account: User name holds the name it logs in with (its address, unless the account names another: AccountPassword.qml); Site the domain of the login chosen for it last, else nothing: a mail server's domain is seldom where its provider's login is kept (imap.gmail.com and accounts.google.com, mail.ecloud.global and murena.io), and with both fields matching it would hide the very login looked for. The server's own logins still come first.
  • function first(url): What the vault suggests for an address: its domain, and the login chosen there last.
  • function start(url, site, user): Opened for url, the fields holding site and user, searched at once.
  • function search(): The search, for what the fields hold now: answered at once, or for a large vault later (bitwardenFound).
  • function show(answer, site, user): A search's answer shown: the logins found, how many more, or why none.
  • function take(index): The login at index taken: the chooser closes and says which (chosen).
  • function takeCurrent(): Enter: the login in the list's highlight, the first unless moved; what was typed last searched first, should the pause not have come yet, and its first login taken once found.
  • function move(by): The highlight moved by by logins, within the list.

Inline components (used inside this file)

  • component EmptiableField: TextField: A field with a button at its end that empties it, as PasswordField's eye sits in its field; not a Tab stop: Tab goes from one field to the other.

MedicineDialog

crates/sioul-app/qml/MedicineDialog.qml · based on Dialog

A medicine, new or changed, from the Health page: its name (its brand, or your word for it), its generic name (INN) and strength, optional, for a doctor or a pharmacist; its dose, when it is taken (at set times each day, its takes as rows, each its time and its own amount when it differs: TakesEditor.qml; every few days; every few hours), until when, the prescription it comes with, paused for now; taken out after one question. Made the first time it opens (HealthPage.qml).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var prescriptions: []: The prescriptions it can come with, {id, title}, as they were when it opened: not bound to the page's view, which a minute's change would give again and the list's choice with it.
  • property string medicineId: ""
  • property string problem: ""
  • readonly property var everies: ["day", "days", "hours"]
  • readonly property var dateLocale: Qt.locale(form.sioul.text("qt-locale"))

Signals

  • signal saved: Saved or taken out: the page reads its medicines again.

Functions

  • function edit(medicine, prescriptions): medicine as the page lists it, null for a new one; the prescriptions it can come with.
  • function save()

MoveDialog

crates/sioul-app/qml/MoveDialog.qml · based on Dialog

Where messages go: every account with its folders, one button each, the folder they are in left out. Another account's folder takes a copy, and the original leaves its own once the copy is there.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string fromAccount: "": The account and folder the messages are in, left out of the choices.
  • property string fromFolder: "": The folder the messages are in, on fromAccount.
  • property var accounts: []: Every account with its folders, as the Mail page has them: where messages may go.

Signals

  • signal chosen(string account, string folder): A folder chosen: the account's id and the folder's name on its server.

MovementDialog

crates/sioul-app/qml/MovementDialog.qml · based on Dialog

A movement added by hand to a budget: once (a date), or recurring (each month or year, on a day). Positive is money in, negative money out.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string budget: "": The budget it goes into, by its id.
  • property var budgets: []: Started from "New": the budget is chosen here, among {id, title}.
  • property bool choosing: false: The budget is chosen in the form (started from "New"), among budgets.
  • property bool recurring: false: Each month or year rather than once.
  • property string problem: "": What went wrong when saving, in words; "" for nothing.

Signals

  • signal saved: The movement was added.

Functions

  • function today(): Today, as 2026-10-05.
  • function choose(): From "New": which budget first.
  • function begin(budget): The form emptied and opened for budget.
  • function save(): The form saved: the amount read as typed, then the movement kept by the backend; what went wrong said in the form, which stays open.

NeedDayForm

crates/sioul-app/qml/NeedDayForm.qml · based on Dialog

One day's meal, nap or night, for that day only (docs/health.md): moved to another time, its times changed (from, to; a meal's minutes to get it ready, a nap's to come back, the night's bedtime), or one added for that day alone, a meal or a rest, named as you like. The usual ones stay as they are, in the page's settings. Nothing about food is asked.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string mode: "times": "move", "times" or "add".
  • property var day: null: The day (health::DayView) and its row (DayItem); none for "add".
  • property var item: null
  • property string kind: "meal": "meal" or "nap": the kind of the one added.
  • property string problem: ""
  • readonly property bool night: …
  • readonly property string shownKind: …

Signals

  • signal saved: Saved: the page reads its days again.

Functions

  • function edit(mode, day, item)
  • function clock(text): "8:5" as typed, "08:05" as kept; "" when it reads as no time.
  • function save()

PaperDialog

crates/sioul-app/qml/PaperDialog.qml · based on Dialog

A paper of the wallet, new or changed: what it is, its file, from when and until when it holds, whose it is. A file from elsewhere is copied into the wallet's folder when saved; an end is proposed from the issue for a passport, an identity card or a warranty.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var kinds: []: The kinds: {id, label}.
  • property string paperId: ""
  • property string problem: ""
  • property string file: "": Its file: a path, or a file:// address just chosen.

Signals

  • signal saved

Functions

  • function begin(file, title, kind): A new paper, perhaps from a file (an attachment kept, a scan).
  • function edit(paper): A paper of the wallet, changed.

PersonSheet

crates/sioul-app/qml/PersonSheet.qml · based on Dialog

How someone reaches you (« Comment Camille vous joint »; docs/attention.md), from a contact's card, a message's sender or a call's line on the Porch: their list and why ("Safe, as the category Friends says"), the list chosen for them, Always through, what each channel does with them at each time, in sentences, and their calls of the month (docs/porch.md). Blocked and Always through exclude each other: choosing one takes them off the other, and the sheet says so. No times of their own: a person has a list and Always through, the rest is the lists' (What reaches you ▸ By person).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string key: "": A card's file or UID, or "" for a sender known by their addresses alone.
  • property string addresses: "": A sender's addresses, a JSON array; "" for a card.
  • property var shown: …: reaches.rs's person: {title, name, who, said, choice, choices, own, always, always_help, lines, note, calls_title, calls, texts_title, texts}.

Signals

  • signal changed: Their list or Always through changed: the page that opened the sheet reads them again.
  • signal textsAsked(string id): texts: their conversation asked for (main.qml opens the Texts page).

Functions

  • function ask(key, addresses): The sheet of someone: a card ("" addresses), or a sender's addresses ("" key).
  • function reload()
  • function change(verb, value)

PrescriptionDialog

crates/sioul-app/qml/PrescriptionDialog.qml · based on Dialog

A prescription, new or changed, from the Health page: what it is for, who wrote it, until when it is valid, how many days the pharmacy gives at a time and when it was last fetched (its errands come from these), a note; then its medicines as rows: each its name, its generic name (INN) and strength (beside it on a computer; folded under it on a phone, a tap away), its dose and its takes, each take its time and its own amount when it differs (TakesEditor.qml). Add a medicine adds a row; a row taken out takes its medicine out on saving, said in the row with "Keep it" until then. A medicine taken every few days or hours says when, its schedule changed in its own form. Saved whole, or not at all (health::apply_prescription). The prescription itself taken out after one question, its medicines kept. Made the first time it opens (HealthPage.qml).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string prescriptionId: ""
  • property string problem: ""
  • property bool focusNew: false: A row just added: its name field takes the focus once it is made.
  • readonly property var dateLocale: Qt.locale(form.sioul.text("qt-locale"))

Signals

  • signal saved: Saved or taken out: the page reads its prescriptions again.

Functions

  • function edit(prescription): prescription as the page lists it, with its medicines; null for a new one.
  • function addMedicine(): A row for a new medicine, at set times each day, its name to type.
  • function save(): The rows as the form gives them (health::PrescribedEdit): each row writes what is typed into the list as it is typed.

ProjectDialog

crates/sioul-app/qml/ProjectDialog.qml · based on Dialog

A project: its name, and for work done for someone, who it is for, what an hour costs and which budget its invoices are expected in; whether AI agents may read it and add to it (closed until opened, docs/ai.md).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string projectId: ""
  • property string problem: ""
  • readonly property var budgets: …
  • readonly property var statuses: ["open", "waiting", "closed"]

Signals

  • signal saved(string id)
  • signal removed

Functions

  • function edit(id, page): page is the project's page, or null for a new one.
  • function amount(text): An amount as typed, "62,50 €": its number, 0 when nothing is typed (the invoices' rate then), NaN when it is no number (never a silent 0).
  • function save()

ReserveDialog

crates/sioul-app/qml/ReserveDialog.qml · based on Dialog

A reserve, a savings account (docs/accounting.md, "Reserves"): its name, its balance on a day, the floor it is never planned below, and how many days money asked from it takes to arrive (a Livret A at once, an assurance vie in about ten).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property string reserveId: ""
  • property string problem: ""

Signals

  • signal done

Functions

  • function edit(reserve): reserve is one of the bank view's reserves, or null for a new one.
  • function amount(text): An amount as typed, "12 345,67 €" or "−650": its number, 0 when nothing is typed, NaN when it is no number (never a silent 0).
  • function save()

RoutinesDialog

crates/sioul-app/qml/RoutinesDialog.qml · based on Dialog

The routines: the admin window's, made from what is there now, then yours; each played, changed or taken out; a new one written one step a line.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var list: []
  • property var editing: null: The routine being written: its id ("" for a new one); null while listing.
  • property string problem: ""

Signals

  • signal play(var routine)

Functions

  • function show()
  • function edit(routine)

ShowMedicines

crates/sioul-app/qml/ShowMedicines.qml · based on Popup

"Show to a doctor or pharmacist": a prescription's medicines, or all those taken now, over the whole window, read-only, to hold out across a counter (health::for_professional). Large type, one medicine a block: its generic name and strength first, then its brand name, its takes with their amounts, how long it has been taken, who prescribed it. Nothing to tap by mistake: one button, Close; Escape and Back close it too (HealthPage.qml).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var shown: …: The view (ForProfessional): {title, about, medicines, empty}.

Functions

  • function show(json)

TimeDialog

crates/sioul-app/qml/TimeDialog.qml · based on Dialog

Time noted by hand (a meeting, a call, work done away from the timer), or any stretch changed once noted, the timer's too: its task, its project, its day, from when to when, a word on what it was.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var projects: []: "The task's own project" (time-own-project), then the open projects, and the one asked for even when closed: the choices.
  • property var tasks: []: "No task", then the open tasks (and the stretch's own).
  • property string problem: "": What went wrong when saving, in words; "" for nothing.
  • property string replacing: "": The stretch being changed, by its key; "" for a new one.

Signals

  • signal saved: The stretch was kept.

Functions

  • function minuteOf(text): "09:30" → minutes of the day; -1 when it is no time.
  • function lengthOf(fromText, toText): From one time to the other, past midnight when it ends before it begins.
  • function length(): How long the stretch typed lasts, in minutes (lengthOf).
  • function clock(minutes): Minutes of the day as "09:30".
  • function today(): Today, as 2026-10-05.
  • function change(entry): A stretch noted before, by the timer or by hand: its day, from, to, task, project, word.
  • function begin(project, task): The form opened for a new stretch, in project and on task when given.
  • function save(): The form saved: the stretch kept by the backend, in the project and on the task chosen; what went wrong said in the form, which stays open.

TimeExport

crates/sioul-app/qml/TimeExport.qml · based on Dialog

A project's billable time over a stretch of days, as a spreadsheet: what was done, how many hours, at what rate, for how much, and the total. This week, last week, this month, last month, everything, or from one day to another.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var projects: []: The projects that can be chosen: {id, title}.
  • readonly property var ranges: …
  • property string problem: ""

Functions

  • function iso(d)
  • function bounds(range): The first and last day of a range, around today.
  • function begin(project)

VaultUnlock

crates/sioul-app/qml/VaultUnlock.qml · based on Dialog

Bitwarden, opened once for the session: by the master password (dropped once used), with a second step or a new device's code when asked, or by your security key alone. A security key is asked from Bitwarden's own page, held unseen in this dialog, where one can be (the Sites page gives it, with Qt WebEngine): its PIN comes in Sioul's own dialog, above this one. On Android, the steps without a key: an app's code, an e-mail's, a YubiKey's, a recovery code. Bitwarden's server is asked off the window's thread (sites.rs, bitwarden_later): the dialog says it waits, and the window stays free meanwhile.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property Component keyComponent: null: What asks a security key, where one can be asked: Bitwarden's page held unseen (the Sites page gives one, with Qt WebEngine); none on Android.
  • property bool keyReady: true: The key's page can be made now (the Sites page's web profile is ready).
  • readonly property bool keyCapable: unlock.keyComponent !== null: A security key can be asked here: something to hold Bitwarden's page was given.
  • property alias keyView: keyView: Bitwarden's page held unseen while a security key is asked, for the window's tests.
  • property int provider: -1: -1: the password only; else the step asked (0 app, 1 e-mail, 3 YubiKey OTP, 7 security key, 8 recovery, 100 new device).
  • property var offered: []: The second steps the account offers, by Bitwarden's numbers.
  • property var key: null: The security key's step, when the account has one: {page, script}.
  • property var keyAsk: null: The key being asked: {mode: "factor" or "passkey", page, script}; else null.
  • property bool sent: false: The e-mail code was sent for this try.
  • property bool passkeyFirst: false: The security key alone opened the vault last time: proposed first.
  • property string problem: "": What went wrong, in words; "" for nothing.
  • property string note: "": What was done that you should know ("A code was sent…"); "" for nothing.
  • readonly property var order: [7, 3, 0, 1, 8]: The steps Sioul can take, in the order Bitwarden's apps propose them: a security key, a YubiKey's code, an app, e-mail; a recovery code only when chosen.
  • property int waiting: 0: Bitwarden's server asked: the ticket waited for (0: none), and what its answer does.
  • property var then: null: What the answer of the call waited for does, once it comes.
  • readonly property bool busy: unlock.waiting !== 0: A call to Bitwarden's server is waited for: the buttons wait too.

Signals

  • signal unlocked: The vault is open: what asked for it goes on.

Functions

  • function ask(ticket, done): A call to Bitwarden's server begun (its ticket): done takes its answer once it comes.
  • function begin(): The dialog opened afresh: every field and step forgotten, the security key proposed first when it opened the vault last.
  • function usePasskey(): The security key alone: no master password.
  • function askKey(mode, ask): The key asked: Bitwarden's page loaded unseen below, the key asked there at once. A new page each time: each ask is a fresh one.
  • function keyAnswered(mode, result): What the key answered: the vault opened with it, or why not.
  • function choose(provider): A step chosen: e-mail sends its code now, once; the security key is asked at once.
  • function sendCode(): Bitwarden asked to send the code by e-mail.
  • function tryIt(): The vault opened with what was typed: the password, the step chosen and its code.
  • function answer(answer): What Bitwarden answered: open, a second step to take, a new device's code, or why not.

WebAuthDialog

crates/sioul-app/qml/WebAuthDialog.qml · based on Dialog

A security key, asked for by a site (WebAuthn): which of its accounts, its PIN (entered, set, or changed when the key asks), touching it again, and in plain words why it failed, with Retry. After Qt's own example (Quick Nano Browser's WebAuthDialog). A plain touch shows nothing here: the key blinks and the page waits for it (Qt 6.11). On Windows, Windows' own dialog takes all of it.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var request: null
  • readonly property int step: …
  • readonly property var pin: …
  • readonly property var failures: …
  • readonly property var pinErrors: …
  • property string account: ""

Functions

  • function show(request)
  • function go()

Sioul's menus, all made from SioulMenu.

AddMenu

crates/sioul-app/qml/AddMenu.qml · based on SioulMenu

Something new, tied to the thing it is made from: a task, an event, a note, a message; a contact from a message's sender. One menu for every kind of thing, so a card keeps one button however many kinds there are.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var window: The main window (main.qml), which opens what is asked of it. What is made opens there, ready to fill.

Properties

  • property var source: null: What the new thing is tied to: {uri, kind, key, title, start, name, address}.
  • readonly property string from: …: The kind of thing it is made from ("mail", "event", "task"…), "" for none.

Functions

  • function offers(kind): Whether something new of kind is offered from that thing.

NewMenu

crates/sioul-app/qml/NewMenu.qml · based on SioulMenu

Something new, of any kind, from anywhere: a message, a task, an event, a contact, a note, a budget movement, time spent, a project. One button and one key (Ctrl+N) for all of them; each opens where that kind lives.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var window

Properties

  • readonly property var kinds: …: [kind, words, icon].

PresetGroupMenu

crates/sioul-app/qml/PresetGroupMenu.qml · based on SioulMenu

One group of usual sites (a country's offices, its banks…): all of them pinned at once, or one (docs/sites.md, "Presets").

Required properties (whoever makes it must give them)

  • required property var sioul

Properties

  • property var group: ({ name: "", sites: [] }): {"name", "sites": [row]}; a row says whether it is already "kept".

Signals

  • signal pin(var rows)

PresetPlaceMenu

crates/sioul-app/qml/PresetPlaceMenu.qml · based on SioulMenu

A country's usual sites, or a state's: "All of them" first, then its groups; a place with a single group lists its sites at once (docs/sites.md, "Presets"). A country's states or provinces are added after, by the page.

Required properties (whoever makes it must give them)

  • required property var sioul

Properties

  • property var place: ({ name: "", groups: [] }): {"name", "groups": [{"name", "sites"}]}.
  • readonly property var everything: …: The sites of its own groups, not its states'.
  • readonly property bool single: placeMenu.place.groups.length === 1

Signals

  • signal pin(var rows)

SioulMenu

crates/sioul-app/qml/SioulMenu.qml · based on Menu

Every menu of Sioul: as wide as its widest line, so that no label is cut; never narrower than a menu usually is, never wider than the window. Kept inside the window, never taller than it: a longer list scrolls (the wheel, a drag, the keys), its bar showing there is more.

Functions

  • function sioulWindow(): var: Sioul's window, with its own properties (not only a window's).

Other windows

Windows of their own, beside the main one.

ComposeWindow

crates/sioul-app/qml/ComposeWindow.qml · based on SioulWindow

Writing a message, in Markdown. In view: to whom, the subject, the text, "Attach" and "Send". Cc and Bcc are folded, the sending account shows only when you have several. Everything is saved as you type, so closing the window loses nothing: the draft waits in Drafts. "Send" waits ten seconds with "Undo" in the main window before the message leaves. A message your security key signs is signed here first, at Send, with its PIN and maybe a touch (SecurityKeyBand.qml); the ten seconds come after.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property string draftId

Properties

  • property bool phoneSize: false: The window's pictures at a phone's size (main.qml's phoneGrab): 412 × 891, as the main window.
  • property var draft: …
  • property bool previewing: false
  • property bool copiesShown: …
  • property string note: "": "Saved at 14:02", or what stops sending.
  • property bool problem: false
  • property bool leaving: false: Sent or discarded: the main window says it, with "Undo".
  • property var protection: …: What OpenPGP allows: signing with your key, encrypting to every recipient's.
  • readonly property bool expired: …: The security key that signs for this address has an expired certificate.
  • property string attaching: …: "Attaching 2 files…" while files shared from another application are copied (outside.rs).
  • readonly property string said: …: Under the text: files still coming, until they are there, unless something stops sending; else the last save or what stops sending; else how to write in Markdown.
  • readonly property string keysMissing: …: Whose keys are missing to encrypt: "No key for …".
  • readonly property bool narrow: …: Too narrow for the buttons under the text in one row with a little of the note beside them (a phone): the note goes on a line of its own, the buttons on two rows, Delete and Send on the right of the second. Every button is a fixed width in a layout: in one row they would widen the whole window's column past the screen, the fields and the text with it.

Signals

  • signal finished(string id)

Functions

  • function edit(): What is written, as the backend saves it.
  • function save()
  • function readProtection(): Recipients changed, or keys were found: what can be signed and encrypted, again.
  • function reloadAttachments(): Attachments changed: read them again, the text stays as typed.
  • function attach(urls)
  • function send()
  • function discard()
  • function grab(path): For the window's images: the writing window as it opens.
  • function prefill(recipients): "Write" from a contact: the address already there.
  • function setSigned(on): For the window's pictures: as if "Sign" were ticked.
  • function fill(recipients, title, text): For the window's tests: as if typed.

FocusWindow

crates/sioul-app/qml/FocusWindow.qml · based on SioulWindow

The focus session: a small window that stays on top while you work in another one (a form, a letter). A soft disc drains as the time chosen passes, in a neutral colour; there is no ticking and no sound. Two minutes before the end, the disc and a line say it is time to find a stopping point. At the end, nothing rings: "Keep going" or "Stop here, it counts". Stopping offers one line, "next time, start by…", kept with the task (docs/tasks.md: time made visible, transitions as steps, a breadcrumb to come back to).

Required properties (whoever makes it must give them)

  • required property var sioul

Properties

  • property var session: null: The session, as the core keeps it (focusSession), parsed.
  • property real now: Date.now() / 1000
  • property bool stopping: false
  • readonly property bool openEnded: …
  • readonly property real elapsed: …
  • readonly property real remaining: …
  • readonly property bool paused: …
  • readonly property bool closing: …
  • readonly property bool over: …
  • readonly property real left: …: A slow fill, then a drain: the share of the time chosen still left.
  • property bool quitting: false: The application is quitting: the session stays on disk, the window goes.
  • property int moveEvery: 0: The pause to move: minutes of focus between two (Health page), 0 when off; the focus counted at the last offer; offered now; taken now.
  • property real movedAt: 0
  • property bool moving: false
  • property bool breaking: false
  • property real sessionStart: 0
  • property alias face: face: What the window shows, for the window's images.

Signals

  • signal closeDay(): Stopped here, and the day closed: the main window says where everything went.

Functions

  • function minutes(seconds)
  • function line()
  • function stop(done)
  • function checkMove(): Time to move: asked, never imposed. The session goes on until you pause it: something urgent may come first, and a pause missed must not stop the time counted. Unanswered, it stays asked; "Not now" asks again later.
  • function takeBreak(): Paused for it: a line on where you stopped, for when you are back.
  • function notNow()
  • function backFromMoving()

RoutinePlayer

crates/sioul-app/qml/RoutinePlayer.qml · based on SioulWindow

A routine played: a small window on top, one step at a time, its time draining in a neutral colour, the next one said before it comes, the whole routine as a row of dots. When a step's time is up, the routine moves on by itself if it was asked to; else it waits, saying so, never ringing. Done, skip, five more minutes, pause, stop: none of them is counted.

Required properties (whoever makes it must give them)

  • required property var sioul

Properties

  • property var routine: null: {id, title, auto, step: [{title, minutes, open}]}; null when none plays.
  • property int index: 0
  • property real stepStart: 0
  • property real extra: 0
  • property real pausedAt: 0
  • property real pausedFor: 0
  • property real now: Date.now()
  • readonly property var steps: …
  • readonly property var step: …
  • readonly property bool finished: …
  • readonly property bool paused: player.pausedAt > 0
  • readonly property real elapsed: …
  • readonly property real length: …: At least a second: a step written "0 min" would share its time by zero.
  • readonly property real remaining: player.length - player.elapsed
  • readonly property bool over: …
  • property alias face: face: What the window shows, for the window's images.

Signals

  • signal openThing(string what): What a step opens: "porch", "sioul:task/<UID>".

Functions

  • function play(routine)
  • function begin(index)
  • function pause()
  • function stop()

SitePopup

crates/sioul-app/qml/SitePopup.qml · based on SioulWindow

A site's pop-up (a sign-in, a call): a window of its own for each, on the sites' profile, so it stays tied to the page that opened it and a sign-in answers it there. Closed, it goes: its page closed first, as a browser closes a tab (its beforeunload, pagehide and unload run), the window gone at once all the same.

Required properties (whoever makes it must give them)

  • required property WebEngineProfile profile
  • required property var webFixes

Properties

  • property var site: null: The site that opened it, as it was then: what a call's window may use.
  • property alias view: popupView
  • property int closeWait: 2000: How long its page may take to close (SitesPage.qml).
  • property bool pageClosed: false: Its page closed: by closePage, or by itself (a sign-in done).
  • property var whenClosed: []: Who waits for its page to close.
  • property int callCount: 0: Its pages and frames with a call now (SitesPage.qml, heard).

Signals

  • signal webAuthAsked(var request)
  • signal popupAsked(var request)
  • signal screenAsked(var request): A call shares a screen: you choose which, or none, in Sioul's dialog. Unanswered, Qt WebEngine would share the whole first screen by itself.
  • signal consoleSaid(string message): A line of its page's console: the calls script's are read by SitesPage.qml (heard).

Functions

  • function closePage(done): Its page closed as a browser closes a tab, then done, at most closeWait later.
  • function pageGone()
  • function leave(): Its window closed already: it goes; else it closes now (a sign-in done), and goes.

Controls

Small pieces used across the pages: fields, buttons, a card, an icon, a player.

ActionButton

crates/sioul-app/qml/ActionButton.qml · based on Button

An action on a message: its icon and its name; narrow, the icon alone, its name said on hover and to screen readers.

Required properties (whoever makes it must give them)

  • required property var theme: The window's colours, sizes and fonts (Theme.qml).
  • required property string iconName: Its icon, by its freedesktop name.

Properties

  • property string label: "": Its name: beside the icon, or, compact, said on hover and to screen readers.
  • property bool compact: false: Narrow: its icon alone.
  • readonly property real wideWidth: …: Its width with its name beside its icon, whatever it shows now: what a row of actions needs to show their names (the Reader's compact).
  • readonly property real narrowWidth: …: Its width as its icon alone.

AddressField

crates/sioul-app/qml/AddressField.qml · based on TextField

An address field that completes from the contacts: what is typed after the last comma is looked up by name and address; Up and Down go through the suggestions, Enter or Tab takes one, Escape leaves them.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme

Properties

  • property var suggestions: []

Signals

  • signal picked: A suggestion was taken: the text changed without typing.

Functions

  • function choose(index)

AudioPlayer

crates/sioul-app/qml/AudioPlayer.qml · based on ColumnLayout

A sound of the notes folder, an audio memo most often: play, pause, where it is, how long it lasts. No autoplay. Loaded only when a sound opens.

Required properties (whoever makes it must give them)

  • required property url source: The sound's address (a file:// address of the notes folder).
  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Functions

  • function clock(ms): ms milliseconds as minutes and seconds, "3:07".

Avatar

crates/sioul-app/qml/Avatar.qml · based on Item

A person's picture, in a soft frame; their initials while it loads, or when the card has none. No shader: it shows the same on every graphics card.

Required properties (whoever makes it must give them)

  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property string source: "": The picture's address; "" for the initials alone.
  • property string name: "": Whose: their initials are made from it (two at most).
  • property int size: 40: Its side, in pixels.
  • readonly property string initials: …: A word's first letter as a whole character: an emoji or a rare letter is two UTF-16 halves.
  • readonly property int corner: Math.round(avatar.size / 5): How round its corners are: a fifth of its side.

CostTiles

crates/sioul-app/qml/CostTiles.qml · based on ColumnLayout

What a task or an event costs, and what it gives back (docs/capacity.md, "The form"): four tiles, thinking, feelings, worry, body and senses, two by two, then "Gives back" under them. Each tile holds its name, its number, a gauge (a small cell for 0, then ten cells for 1 to 10), the word of its band on Borg's CR10 scale (moderate, hard…) and a concrete question in small print. Feelings are asked about through what stirs them, for whoever finds them hard to name.

A tap on a cell gives that value; a tap on the value given clears it: unsaid again, which is not 0. With the focus on a tile, a digit gives 0 to 9, + or = gives 10, the arrows step by one (given when the key comes up), Delete or Backspace clears.

Faint values (proposed): what was felt after the same task, else after tasks of its kind (FeltIndex, sioul-core's capacity.rs). They show on unsaid tiles only and are never given by themselves: "Looks right" takes them all, a tap sets one tile instead. "How was it?" (felt) has none: the forecast is a thin mark on each gauge there, never copied into the answer.

Two columns, or one: under narrow, and on a touch screen (theme.touch) wherever two columns would make a cell narrower than a fingertip (fingerCell). A narrower gauge still works: a tap picks the nearest cell.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var values: ({}): What is said: {cognitive, emotional, anxiety, body, gain}, each 0 to 10, null or missing when unsaid.
  • property var proposed: ({}): Faint values from before, the same shape (a task's proposed); ({}) for none.
  • property string proposedFrom: "": Where the faint values come from: "item" (this task), "kind" (tasks of its kind), "both".
  • property bool felt: false: "How was it?": the forecast as thin marks, the gain asked in the past, no faint values.
  • property var forecast: ({}): What was foreseen, the same shape as values: thin marks on the gauges, with felt.
  • property real narrow: 360: One column under this width, whatever the device.
  • readonly property real fingerCell: 30: A cell a fingertip hits among its neighbours (Android asks 48 dp for a lone target; cells side by side, tapped one at a time, do with less).
  • readonly property real mouseCell: 14: The narrowest cell a mouse hits without care, with the word beside the gauge.
  • readonly property real comfortCell: 16: A cell at the tiles' natural width.
  • readonly property bool touch: tiles.theme.touch === true: A touch screen: cells as wide as a fingertip needs.
  • readonly property real gap: 8: The room between two tiles, in pixels.
  • readonly property real pad: 10: The room inside a tile, around what it holds.
  • readonly property var costs: …: The four costs, by their names in a task's record.
  • readonly property var names: …: The four costs and the gain, in the order the tiles show them.
  • readonly property var costWords: …: The band words, after Borg's CR10: a word at fixed numbers, a number between two takes the word below it (docs/capacity.md, "The form").
  • readonly property var costBands: [0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 6]: The band of each value of a cost, 0 to 10: which of costWords it takes.
  • readonly property var gainWords: …: The gain's band words, as the costs have theirs (tile-gain-…).
  • readonly property var gainBands: [0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5]: The band of each value of the gain, 0 to 10: which of gainWords it takes.
  • readonly property real wordRoom: …: The widest word, for the gauges beside it to line up from tile to tile.
  • readonly property real tileInside: …: A tile's inside, in one column or two.
  • readonly property bool beside: …: The word beside the gauge where the cells keep their size, else above it, beside the number.
  • readonly property real gaugeWidth: …: Every gauge as wide, the gain's too, so that their cells line up.
  • readonly property int columns: …: The tiles two by two, or one under the other when the width (or a fingertip's cells) asks for it.
  • readonly property bool offered: …: Whether a faint value waits on an unsaid tile.
  • readonly property real naturalWidth: …: Its natural width: two tiles side by side, each gauge's cells at comfortCell with the word beside. A card is as wide as this, or as its text at a readable length, whichever is wider (a layout's own implicitWidth follows its children, so this one has a name of its own).

Signals

  • signal edited(string name, var value): A value given by hand: 0 to 10, or null (unsaid again).
  • signal taken(var values): "Looks right": the faint values of the unsaid tiles, {name: value}.

Functions

  • function cellOf(width): The width of a cell for 1 to 10 in a gauge width wide: the 0 cell is 0.6 of one, and ten gaps of 2 pixels part them.
  • function said(name): What a tile says: 0 to 10, or null when unsaid.
  • function faint(name): A faint value, rounded (a median may fall between two); null when none or in "How was it?".
  • function foreseen(name): What was foreseen for a tile, with felt: 0 to 10, or null.
  • function word(name, value): A tile's band word for value, or "unsaid".
  • function title(name): A tile's name, in your language.
  • function ask(name): A tile's question in small print, in your language.
  • function take(): "Looks right": every faint value of an unsaid tile, given at once.
  • function tile(name): A tile by its name, for the tests.

Inline components (used inside this file)

  • component Tile: Rectangle: One cost, or the gain: its name and number, its gauge and word, its question.

DateField

crates/sioul-app/qml/DateField.qml · based on Item

A date, typed as 2026-10-05 or picked from a month: the calendar button opens the month, a click on a day closes it.

Required properties (whoever makes it must give them)

  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property var sioul: null: The window's words, for the month arrows' names; without them, the month alone.
  • property var locale: Qt.locale(): Month and day names in Sioul's language.
  • property string date: "": "2026-10-05".
  • property string pickLabel: "": The calendar button's name, said on hover and to screen readers.
  • property int shownYear: 2026: The month shown by the picker (month 0 is January).
  • property int shownMonth: 0: The month the picker shows, 0 for January, in shownYear.

Signals

  • signal edited: The date was typed or picked: the form saves it.

Functions

  • function pad(n): A number on two digits, "05".
  • function iso(d): A date as 2026-10-05.
  • function arrowName(step): A month arrow's name, for a screen reader and its tip: "Previous month: September 2026" (step -1), "Next month: November 2026" (+1).

Icon

crates/sioul-app/qml/Icon.qml · based on IconImage

A desktop icon, by its freedesktop name, in its own colours. Decorative, unless it has a tip: then hovering it says what it stands for, and screen readers read the tip.

Required properties (whoever makes it must give them)

  • required property string iconName: The icon, by its freedesktop name ("mail-reply-sender").

Properties

  • property int size: 18: Its side, in pixels.
  • property string tip: "": Said on hover, when set: what the icon stands for, in words.

LabeledRows

crates/sioul-app/qml/LabeledRows.qml · based on ColumnLayout

Values with what each is for ("work", "home", "cell"): one row each, a way to take one off, and one to add another.

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var labels
  • required property ListModel model
  • required property string addText

Properties

  • property bool multiline: false

Later

crates/sioul-app/qml/Later.qml · based on Loader

A form made the first time it is asked for, not with its page: a page holding a dozen forms would build them all as it opens (on a phone, most of a second). now() gives it, made; close() closes it if it was.

Functions

  • function now(): The form, made the first time it is asked for.
  • function close(): The form closed, if it was ever made.

MemoRecorder

crates/sioul-app/qml/MemoRecorder.qml · based on Item

An audio memo, recorded into the notes folder as Opus: it starts when loaded and ends with stop(), then opens as a note, to tie to anything. Loaded only while recording, so the microphone is never open otherwise. The system is asked for the microphone first (macOS asks you once; Linux has nothing to ask): refused, nothing is recorded and refused says so.

Required properties (whoever makes it must give them)

  • required property url location

Properties

  • property int seconds: 0
  • property bool started: false

Signals

  • signal finished(url location)
  • signal failed(string problem)
  • signal refused

Functions

  • function stop()
  • function begin(): Without a place in the notes folder, nothing is recorded ("" said as the problem): Qt would pick a folder of its own, where the memo is never found.

Panel

crates/sioul-app/qml/Panel.qml · based on Pane

A card: a soft surface with a thin border. With accent, a firmer border, for the one thing that cannot wait (a code).

Required properties (whoever makes it must give them)

  • required property var theme: The window's colours, sizes and fonts (Theme.qml).

Properties

  • property bool accent: false: A firmer border, in the accent: the one thing that cannot wait.

PasswordField

crates/sioul-app/qml/PasswordField.qml · based on TextField

A password, a passphrase, a key: hidden by default, shown while you ask (the eye at its end, reached with Tab too), for whoever needs to see what they type. Paramètres ▸ "Show passwords as you type" shows them from the start.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does. The choice to show passwords as you type is read there.

Properties

  • property bool shown: field.sioul.viewFlag("passwords-shown"): What is typed shown as it is; hidden by default, unless Paramètres says to show passwords.

PlainComboBox

crates/sioul-app/qml/PlainComboBox.qml · based on ComboBox

A ComboBox whose list shows its choices as they are written. Basic's own list draws each choice on a button, and a button reads "&" as the mark of its shortcut key: "R&D" showed "RD", "Tom & Jerry" lost its "&" (the review of 5 October 2026). Each "&" is doubled for the list alone ("&&" is one); the closed box is a text field, which shows the text as it is. Every ComboBox of the window is one of these; one that brings its own delegate doubles the "&" itself (TaskPanel's list of task lists).

ThingActions

crates/sioul-app/qml/ThingActions.qml · based on RowLayout

The two buttons every card ends with: something new tied to it, or a tie to something that exists. Right click in a list offers the same.

Required properties (whoever makes it must give them)

  • required property var sioul: Sioul's backend (backend.rs): its words in your language and what it does.
  • required property var theme: The window's colours, sizes and fonts (Theme.qml).
  • required property var window: The main window (main.qml), which opens what is asked of it. Its "Link to…" chooser ties the thing open to another.

Properties

  • property var source: null: The thing open: {uri, kind, key, title, start, name, address}.

TimeDrag

crates/sioul-app/qml/TimeDrag.qml · based on Item

What a hand does on a vertical timeline, said once for the three of them (Health's day and week, the agenda's day and week, the Tasks page's day): one set of handlers over the whole timeline, which finds nothing itself and asks its timeline what lies under the pointer. A timeline opens no slower for its blocks: none of them carries a handler of its own.

With a mouse or a touchpad: a press and a drag moves (started, moved, released); a click is a tap; a right click asks for the menu. With a finger: a plain swipe scrolls the timeline, as before; a long press is held, and the timeline says whether it picks something up (pickUp): then the finger drags it, the timeline holding still, and lifting the finger without moving asks for the menu, as a long press always did. Dragging near the top or the bottom of the view scrolls it. Nothing moves but under the hand: the timeline draws where the thing would go, and changes it only when it is let go.

Required properties (whoever makes it must give them)

  • required property Flickable flick: The timeline's view: still while a finger drags, scrolled at its edges.

Properties

  • property int cursorShape: Qt.ArrowCursor: The pointer's look where it hovers, and while it drags (the timeline says).
  • property int dragCursor: Qt.ClosedHandCursor: The pointer's look while it drags.
  • property real holdSeconds: 0.45: A finger held this long picks up (seconds); it goes once moved this far (pixels).
  • property real threshold: 10: A press goes once moved this far, in pixels.
  • readonly property bool dragging: area.going: Picked up by a finger, or dragged with a mouse.
  • readonly property bool holding: area.armed: A finger held: the timeline picked something up and the finger has it.
  • property bool armed: false: A finger's long press picked something up (pickUp).
  • property bool going: false: A drag under way.
  • property bool menuOnRelease: false: Let go without moving after pickUp(true): the menu is asked.
  • property point pressed: Qt.point(0, 0): Where the press began, in the timeline.
  • property point pressedScene: Qt.point(0, 0): Where the press began, on the screen.
  • property point lastScene: Qt.point(0, 0): Where the pointer was last, on the screen: the view may scroll under a still hand.

Signals

  • signal hovered(point position): The pointer over the timeline, in this item's coordinates; off it: (-1, -1).
  • signal tapped(point position, point scenePosition): A tap or a click, where it was in the timeline and on the screen.
  • signal doubleTapped(point position): A double click or a double tap.
  • signal menuAsked(point position, point scenePosition): A right click; a long press let go without moving, after pickUp(true).
  • signal held(point position, point scenePosition): A finger held still: call pickUp to take what is under it.
  • signal started(point position): A drag begins at position (where it was pressed), goes on, ends.
  • signal moved(point position): Where a drag is now, in the timeline.
  • signal released(point position): A drag let go: the timeline changes the thing now.
  • signal canceled: Picked up or dragged, then not dropped (a long press let go in place, the grab taken away): nothing changes.

Functions

  • function pickUp(menuOnRelease): A finger's long press took something: the finger drags it now. With menuOnRelease, let go without moving it asks for the menu.
  • function finish(position, dropped): The hand let go: dropped where it is, or nothing (a long press let go in place, a grab taken away).
  • function follow(scene): The pointer at scene, on the screen: the drag goes there, and the view scrolls near its top or bottom.

WrapCheckBox

crates/sioul-app/qml/WrapCheckBox.qml · based on CheckBox

A check box whose sentence wraps. In a layout, an item that does not fill the width keeps its own width, and the layout is then at least that wide: one long sentence (in French, on a phone) laid a whole settings panel wider than the screen. Give it Layout.fillWidth (or a width) where it sits.

On Android

The phone's versions of two files, in qml/android/. Android has no Qt WebEngine and no Qt PDF: the phone's build takes these in place of the files of the same names (crates/sioul-app/build.rs).

PdfView (Android)

crates/sioul-app/qml/android/PdfView.qml · based on Item

A PDF of the notes folder, on Android: Qt PDF has no Android version, so nothing is shown here; the page's "Open with…" hands the PDF to the reader Android has for it. Same name and same property as qml/PdfView.qml.

Required properties (whoever makes it must give them)

  • required property url source

SitesPage (Android)

crates/sioul-app/qml/android/SitesPage.qml · based on Item

The Sites page on Android. Qt WebEngine, which keeps sites inside Sioul on a computer (qml/SitesPage.qml), has no Android version: your sites are listed here, and each opens in the browser. Same name and same calls as the computer's page, as far as the window uses them (open).

Required properties (whoever makes it must give them)

  • required property var sioul
  • required property var theme
  • required property var window

Properties

  • property var sites: []

Functions

  • function reload()
  • function open(id): A site asked for, by a link or from the Porch: in the browser.