colour -> color, behaviour -> behavior, centre -> center, favourite -> favorite, and about twenty other pairs, applied consistently across comments, docs, error/UI copy, and a handful of QML identifiers that used the British spelling as their actual name: SystemSettings' serialiseValue/serialiseTable/normaliseGradient, Displays' normaliseModes, Wallpaper's normalisePolicy, SettingsBackup's serialiseHomeState, DateTime's ntpSynchronised property, Clipboard's _normalise helper, and ShortcutCapture's cancelled signal (with its onCancelled handler in ShortcutsPage.qml). Every call site and the two tests that assert on the literal source text (settings-ownership and settings-backup-live contracts) were updated in lockstep. Left untouched: config/dot/espanso/match/packages/misspell-en/ is a vendored third-party autocorrect dictionary -- its entries are typo corrections, not our prose, and rewriting them would fight the package's own purpose (and any future re-sync from upstream). The already-American `favorites` property (Home page pinned accessories) was never actually misspelled -- only nearby comments and error strings said "favourites" -- so no data migration was needed there. Claude-Session: https://claude.ai/code/session_01E6TJUAh41HaP25MVHWkhRZ
117 lines
4.0 KiB
QML
117 lines
4.0 KiB
QML
// Date & Time.
|
|
//
|
|
// These belong to the machine rather than to Panama, so nothing here is stored
|
|
// in Panama's settings file -- it would be a second answer to a question the
|
|
// system already answers. Timezone and network time are read from and written
|
|
// to timedatectl directly; the clock's presentation lives on Appearance,
|
|
// because that genuinely is a Panama preference.
|
|
//
|
|
// Changing the timezone or network time needs privilege. timedatectl asks
|
|
// polkit, and a canceled dialog surfaces as an error rather than as a value
|
|
// that appears to have been accepted.
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import qs.config
|
|
import qs.services
|
|
import qs.modules.clipboard
|
|
|
|
SettingsPage {
|
|
id: root
|
|
|
|
title: "Date & Time"
|
|
lede: "Timezone and network time, shared with the whole machine."
|
|
|
|
SettingsCard {
|
|
title: "Clock"
|
|
|
|
TextRow {
|
|
label: "Current time"
|
|
detail: DateTime.timezone === "" ? "Reading the system clock" : DateTime.timezone
|
|
value: Qt.formatDateTime(clock.date, Settings.use24Hour ? "ddd d MMM HH:mm" : "ddd d MMM h:mm AP")
|
|
}
|
|
SettingRow {
|
|
label: "Set automatically"
|
|
detail: DateTime.ntpEnabled
|
|
? (DateTime.ntpSynchronized ? "Synchronized with a time server" : "Waiting to synchronize")
|
|
: "The clock is set by hand"
|
|
controlWidth: 48
|
|
divider: false
|
|
|
|
SettingsToggle {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
checked: DateTime.ntpEnabled
|
|
enabled: !DateTime.busy
|
|
onToggled: value => DateTime.setNtp(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
title: "Timezone"
|
|
subtitle: "Currently " + (DateTime.timezone === "" ? "unknown" : DateTime.timezone)
|
|
+ ". Type to narrow the list."
|
|
|
|
SearchField {
|
|
id: zoneSearch
|
|
width: parent.width
|
|
placeholder: "Search timezones"
|
|
}
|
|
|
|
Repeater {
|
|
model: root.matchingZones
|
|
|
|
TextRow {
|
|
required property var modelData
|
|
required property int index
|
|
|
|
label: DateTime.cityOf(modelData)
|
|
detail: DateTime.regionOf(modelData)
|
|
value: modelData === DateTime.timezone ? "Current" : ""
|
|
controlWidth: 90
|
|
divider: index < root.matchingZones.length - 1
|
|
activatable: true
|
|
onActivated: DateTime.setTimezone(modelData)
|
|
}
|
|
}
|
|
|
|
TextRow {
|
|
visible: root.matchingZones.length === 0
|
|
label: "No timezone matches that"
|
|
detail: "Try a city or a region, such as \"Denver\" or \"Europe\""
|
|
divider: false
|
|
}
|
|
}
|
|
|
|
SettingsCard {
|
|
visible: DateTime.lastError !== ""
|
|
title: "The system did not accept that"
|
|
subtitle: DateTime.lastError
|
|
}
|
|
|
|
// Bounded so a blank search does not try to lay out six hundred rows. The
|
|
// current zone is always included, so the card never looks empty when the
|
|
// field is untouched.
|
|
readonly property var matchingZones: {
|
|
const needle = zoneSearch.text.trim().toLowerCase();
|
|
const all = DateTime.zones;
|
|
if (needle === "") {
|
|
// The zone in effect goes first. Listing a region alphabetically
|
|
// means the current setting is usually off the bottom of the card,
|
|
// which makes the list look like it does not know what is set.
|
|
const current = DateTime.timezone;
|
|
const nearby = all
|
|
.filter(zone => zone !== current && DateTime.regionOf(zone) === DateTime.regionOf(current))
|
|
.slice(0, 11);
|
|
return current === "" ? nearby : [current].concat(nearby);
|
|
}
|
|
return all.filter(zone => zone.toLowerCase().replace(/_/g, " ").indexOf(needle) >= 0).slice(0, 40);
|
|
}
|
|
|
|
SystemClock {
|
|
id: clock
|
|
precision: SystemClock.Minutes
|
|
}
|
|
}
|