Show the desktop shell in Chinese under zh_CN

This commit is contained in:
ZacharyZhang-NY committed 2026-10-06 21:29:39 -04:00
1 parent e590f22de6
commit e236713d9f
55 files changed
+867 -331

No files matched your search

+6 -6
View File
@@ -176,7 +176,7 @@ Panel {
readonly property bool hasOutput: !!(volumeSink && volumeSink.audio)
readonly property bool hasInput: !!(source && source.audio)
readonly property bool anyAudible: (hasOutput && !outputMuted) || (hasInput && !inputMuted)
readonly property string toggleHint: anyAudible ? "Mute" : "Unmute"
readonly property string toggleHint: anyAudible ? I18n.tr("Mute") : I18n.tr("Unmute")
readonly property color hoverFill: bar
? Style.hoverFillFor(bar.foreground, Color.accent)
@@ -434,7 +434,7 @@ Panel {
// panel's brightnessName ladder; bands are wide enough that small
// tweaks don't rename the room you're in.
function outputVolumeName(volume, muted) {
return Model.outputVolumeName(volume, muted)
return I18n.tr(Model.outputVolumeName(volume, muted))
}
function setOutputVolume(v) {
@@ -768,7 +768,7 @@ Panel {
spacing: Style.space(2)
Text {
text: "Audio"
text: I18n.tr("Audio")
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.title
@@ -810,7 +810,7 @@ Panel {
PanelSectionHeader {
id: outputHeader
text: "OUTPUT"
text: I18n.tr("OUTPUT")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
anchors.left: parent.left
@@ -897,7 +897,7 @@ Panel {
PanelSectionHeader {
id: microphoneHeader
text: "INPUT"
text: I18n.tr("INPUT")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
anchors.left: parent.left
@@ -1000,7 +1000,7 @@ Panel {
visible: root.displayAudioStreams.length > 0
PanelSectionHeader {
text: "SOURCES"
text: I18n.tr("SOURCES")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
}
+26 -26
View File
@@ -64,19 +64,19 @@ Panel {
property int phraseIndex: 0
readonly property var activePhrases: [
"Untangling wires",
"Streaming vikings",
"Pairing mysteries",
"Herding headsets",
"Taming radios",
"Summoning speakers",
"Wrangling codecs",
"Polishing packets"
I18n.tr("Untangling wires"),
I18n.tr("Streaming vikings"),
I18n.tr("Pairing mysteries"),
I18n.tr("Herding headsets"),
I18n.tr("Taming radios"),
I18n.tr("Summoning speakers"),
I18n.tr("Wrangling codecs"),
I18n.tr("Polishing packets")
]
readonly property bool rotatingPhrases: adapter && adapter.enabled
readonly property string heroStatusText: {
if (!adapter) return "No adapter"
if (!adapter.enabled) return "Turned Off"
if (!adapter) return I18n.tr("No adapter")
if (!adapter.enabled) return I18n.tr("Turned Off")
return activePhrases[phraseIndex % activePhrases.length]
}
@@ -101,7 +101,7 @@ Panel {
// sits above the device sections so the adapter can be toggled by keyboard
// even when it is off and no device rows exist.
readonly property bool headerHasCursor: cursorActive && focusSection === "header"
readonly property string toggleHint: root.adapter && root.adapter.enabled ? "Turn Bluetooth off" : "Turn Bluetooth on"
readonly property string toggleHint: root.adapter && root.adapter.enabled ? I18n.tr("Turn Bluetooth off") : I18n.tr("Turn Bluetooth on")
readonly property color hoverFill: bar
? Style.hoverFillFor(bar.foreground, Color.accent)
@@ -183,7 +183,7 @@ Panel {
var rows = scrollRows
if (index < 0 || index >= rows.length) return ""
if (index > 0 && rows[index - 1].section === rows[index].section) return ""
return rows[index].section === "known" ? "PAIRED" : "AVAILABLE"
return rows[index].section === "known" ? I18n.tr("PAIRED") : I18n.tr("AVAILABLE")
}
function audioSinks() {
@@ -738,7 +738,7 @@ Panel {
spacing: Style.space(2)
Text {
text: "Bluetooth"
text: I18n.tr("Bluetooth")
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.title
@@ -775,7 +775,7 @@ Panel {
spacing: Style.space(10)
PanelSectionHeader {
text: "CONNECTED"
text: I18n.tr("CONNECTED")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
}
@@ -867,9 +867,9 @@ Panel {
Text {
textFormat: Text.PlainText
visible: root.connectedDevices.length === 0 && root.scrollRows.length === 0
text: !root.adapter ? "No Bluetooth adapter"
: !root.adapter.enabled ? "Turn Bluetooth on to scan"
: "Scanning for devices…"
text: !root.adapter ? I18n.tr("No Bluetooth adapter")
: !root.adapter.enabled ? I18n.tr("Turn Bluetooth on to scan")
: I18n.tr("Scanning for devices…")
color: Qt.darker(root.bar.foreground, 1.5)
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -894,9 +894,9 @@ Panel {
readonly property string action: root.pendingAction(dev ? dev.address : "")
readonly property string actionTooltip: {
if (!dev) return ""
if (isConnected) return "Disconnect"
if (isDiscovered) return "Pair"
return "Connect"
if (isConnected) return I18n.tr("Disconnect")
if (isDiscovered) return I18n.tr("Pair")
return I18n.tr("Connect")
}
readonly property bool rowSelected: root.cursorActive && root.focusSection === sectionName && root.selectedIndex === rowIndex
@@ -911,13 +911,13 @@ Panel {
readonly property string statusText: {
if (!dev) return ""
if (action === "forgetting") return "Forgetting…"
if (action === "disconnecting" || devState === 2) return "Disconnecting…"
if (action === "forgetting") return I18n.tr("Forgetting…")
if (action === "disconnecting" || devState === 2) return I18n.tr("Disconnecting…")
if (isConnected) {
if (dev.batteryAvailable) return Math.round(dev.battery * 100) + "%"
return sectionName === "connected" ? "" : "Connected"
return sectionName === "connected" ? "" : I18n.tr("Connected")
}
if (action === "connecting" || devState === 3 || dev.pairing === true) return "Connecting…"
if (action === "connecting" || devState === 3 || dev.pairing === true) return I18n.tr("Connecting…")
if (isDiscovered) return ""
return ""
}
@@ -994,7 +994,7 @@ Panel {
Text {
textFormat: Text.PlainText
text: root.deviceLabel(row.dev) || "Device"
text: root.deviceLabel(row.dev) || I18n.tr("Device")
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.body
@@ -1019,7 +1019,7 @@ Panel {
anchors.verticalCenter: parent.verticalCenter
visible: row.showForgetButton
iconText: "󰅙"
tooltipText: "Forget"
tooltipText: I18n.tr("Forget")
foreground: root.bar.foreground
hoverColor: root.bar.foreground
fontFamily: root.bar.fontFamily
+5 -3
View File
@@ -21,7 +21,7 @@ BarWidget {
: setting("format", "dddd HH:mm")
readonly property string configuredAltFormat: vertical
? setting("verticalFormatAlt", "dd\nMMM\n'W'ww\n''yy")
: setting("formatAlt", "d MMMM 'W'ww yyyy")
: setting("formatAlt", I18n.chinese ? "yyyy年M月d日 'W'ww" : "d MMMM 'W'ww yyyy")
readonly property var formatRing: Model.clockFormatRing(configuredFormat, configuredAltFormat, Model.clockFormats(vertical))
@@ -56,8 +56,10 @@ BarWidget {
root.bar.shell.updateEntryInline(root.moduleName, entry)
}
// Qt.formatDateTime is always English; a Chinese session takes day and month names from its locale.
function formatted(date) {
return Qt.formatDateTime(date, activeFormat.replace(/ww/g, Model.isoWeekLiteral(date.getFullYear(), date.getMonth(), date.getDate())))
var format = activeFormat.replace(/ww/g, Model.isoWeekLiteral(date.getFullYear(), date.getMonth(), date.getDate()))
return I18n.chinese ? Qt.locale().toString(date, format) : Qt.formatDateTime(date, format)
}
// ---- Calendar popup. Shape contract for shell.summon/hide/toggle
@@ -153,7 +155,7 @@ BarWidget {
fixedHeight: root.vertical ? root.verticalLines.length * Style.bar.iconSlot : -1
horizontalMargin: 8.75
verticalPadding: 8.75
tooltipText: "Right-click to toggle format"
tooltipText: I18n.tr("Right-click to toggle format")
onPressed: function(b) {
if (b === Qt.RightButton) root.cycleFormat()
+11 -13
View File
@@ -64,10 +64,8 @@ Panel {
// convention. Clicking the grid's "W" heading writes the choice back to
// shell.json.
readonly property int weekStart: Model.normalizedWeekStart(setting("weekStartDay", null), Qt.locale().firstDayOfWeek)
// The interface is English throughout, so day names are not taken from the
// system locale. Where the week starts still is: that is a regional
// convention rather than a translation, and it stays overridable above.
readonly property var labelLocale: Qt.locale("en_US")
// Day names follow the interface language, not the system locale; the week start above is a regional convention.
readonly property var labelLocale: I18n.chinese ? Qt.locale("zh_CN") : Qt.locale("en_US")
readonly property string nextWeekStartLabel: labelLocale.dayName(Model.toggledWeekStart(weekStart), Locale.LongFormat)
readonly property var weekdays: Model.weekdayOrder(weekStart)
readonly property var weeks: Model.monthGrid(viewYear, viewMonth, weekStart, todayKey)
@@ -315,7 +313,7 @@ Panel {
id: heroDate
textFormat: Text.PlainText
anchors.verticalCenter: parent.verticalCenter
text: Qt.formatDate(root.today, "MMMM d")
text: I18n.chinese ? root.labelLocale.toString(root.today, "M月d日") : Qt.formatDate(root.today, "MMMM d")
color: heroMouse.containsMouse
? Style.hoverStateColor(root.contentForeground, Color.accent)
: root.contentForeground
@@ -338,7 +336,7 @@ Panel {
PanelToolTip {
visible: heroMouse.containsMouse
text: "Back to today"
text: I18n.tr("Back to today")
fontFamily: root.contentFontFamily
}
}
@@ -371,7 +369,7 @@ Panel {
Text {
anchors.verticalCenter: parent.verticalCenter
text: "BORN"
text: I18n.tr("BORN")
color: Qt.darker(root.contentForeground, 1.5)
font.family: root.contentFontFamily
font.pixelSize: Style.font.bodySmall
@@ -394,7 +392,7 @@ Panel {
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 0
leftPadding: Style.space(6)
text: "LIVE TO"
text: I18n.tr("LIVE TO")
color: Qt.darker(root.contentForeground, 1.5)
font.family: root.contentFontFamily
font.pixelSize: Style.font.bodySmall
@@ -481,7 +479,7 @@ Panel {
id: lifeLabel
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
text: "LIFE"
text: I18n.tr("LIFE")
color: Qt.darker(root.contentForeground, 1.5)
font.family: root.contentFontFamily
font.pixelSize: Style.font.bodySmall
@@ -600,7 +598,7 @@ Panel {
PanelToolTip {
visible: weekStartMouse.containsMouse
text: "Start weeks on " + root.nextWeekStartLabel
text: I18n.tr("Start weeks on %1", root.nextWeekStartLabel)
fontFamily: root.contentFontFamily
}
}
@@ -723,7 +721,7 @@ Panel {
// "MAY 2026" and a "SEPTEMBER 2026".
width: Style.space(130)
horizontalAlignment: Text.AlignHCenter
text: Qt.formatDate(root.viewDate, "MMMM yyyy").toUpperCase()
text: I18n.chinese ? root.labelLocale.toString(root.viewDate, "yyyy年M月") : Qt.formatDate(root.viewDate, "MMMM yyyy").toUpperCase()
color: Qt.darker(root.contentForeground, 1.4)
font.family: root.contentFontFamily
font.pixelSize: Style.font.body
@@ -737,7 +735,7 @@ Panel {
anchors.leftMargin: -Style.space(8)
anchors.verticalCenter: parent.verticalCenter
iconText: "󰅁"
tooltipText: "Previous month"
tooltipText: I18n.tr("Previous month")
foreground: root.contentForeground
fontFamily: root.contentFontFamily
onClicked: root.moveMonth(-1)
@@ -748,7 +746,7 @@ Panel {
anchors.rightMargin: -Style.space(8)
anchors.verticalCenter: parent.verticalCenter
iconText: "󰅂"
tooltipText: "Next month"
tooltipText: I18n.tr("Next month")
foreground: root.contentForeground
fontFamily: root.contentFontFamily
onClicked: root.moveMonth(1)
@@ -117,7 +117,7 @@ Item {
}
if (!root.expectedStop && exitCode !== 0) {
root.error = root.stderrText || "Disk speed test failed"
root.error = root.stderrText || I18n.tr("Disk speed test failed")
root.phase = ""
root.running = false
return
@@ -133,10 +133,10 @@ Item {
fontFamily: Style.font.family
layerNamespace: "omarchy-disk-speedtest"
title: root.diskName
leftLabel: "READ"
rightLabel: "WRITE"
leftLabel: I18n.tr("READ")
rightLabel: I18n.tr("WRITE")
unit: "MB/s"
runAgainTooltip: "Measure again"
runAgainTooltip: I18n.tr("Measure again")
running: root.running
leftValue: root.toRate(root.readMBps)
rightValue: root.toRate(root.writeMBps)
+18 -18
View File
@@ -20,16 +20,16 @@ Panel {
property int phraseIndex: 0
readonly property var activePhrases: [
"Filing files",
"Distributing data",
"Shuffling folders",
"Boxing bytes",
"Sorting stuff",
"Syncing secrets",
"Packing packets",
"Moving memories",
"Wrangling revisions",
"Cataloging chaos"
I18n.tr("Filing files"),
I18n.tr("Distributing data"),
I18n.tr("Shuffling folders"),
I18n.tr("Boxing bytes"),
I18n.tr("Sorting stuff"),
I18n.tr("Syncing secrets"),
I18n.tr("Packing packets"),
I18n.tr("Moving memories"),
I18n.tr("Wrangling revisions"),
I18n.tr("Cataloging chaos")
]
readonly property string heroPhraseText: activePhrases[phraseIndex % activePhrases.length]
readonly property color foreground: bar ? bar.foreground : Color.foreground
@@ -37,7 +37,7 @@ Panel {
readonly property color dim: Qt.darker(foreground, 1.55)
readonly property string fontFamily: bar ? bar.fontFamily : Style.font.family
readonly property color iconColor: dropbox.authenticated && dropbox.active ? foreground : dim
readonly property string toggleHint: dropbox.active ? "Pause syncing" : "Resume syncing"
readonly property string toggleHint: dropbox.active ? I18n.tr("Pause syncing") : I18n.tr("Resume syncing")
readonly property color barIconColor: dropbox.authenticated && dropbox.active ? barForeground : Qt.darker(barForeground, 1.55)
// Only claim the header cursor when the switch is actually on screen —
// "header" stays navigable, but an absent CLI leaves nothing to highlight.
@@ -244,7 +244,7 @@ Panel {
id: hero
width: parent.width
title: "Dropbox"
meta: dropbox.active ? root.heroPhraseText : "Syncing paused"
meta: dropbox.active ? root.heroPhraseText : I18n.tr("Syncing paused")
foreground: root.foreground
fontFamily: root.fontFamily
iconOpacity: dropbox.active ? 1.0 : 0.5
@@ -304,7 +304,7 @@ Panel {
Column {
width: parent.width
spacing: Style.spacing.labelGap
InfoPair { label: "Stored"; value: Model.usageText(dropbox.usedBytes, dropbox.quotaBytes, dropbox.quotaKnown) }
InfoPair { label: I18n.tr("Stored"); value: Model.usageText(dropbox.usedBytes, dropbox.quotaBytes, dropbox.quotaKnown) }
}
}
@@ -319,7 +319,7 @@ Panel {
spacing: Style.space(10)
PanelSectionHeader {
text: "RECENT FILES"
text: I18n.tr("RECENT FILES")
foreground: root.foreground
fontFamily: root.fontFamily
}
@@ -327,7 +327,7 @@ Panel {
Text {
visible: dropbox.files.length === 0
width: parent.width
text: "No synced files found."
text: I18n.tr("No synced files found.")
color: root.dim
font.family: root.fontFamily
font.pixelSize: Style.font.body
@@ -424,7 +424,7 @@ Panel {
Text {
textFormat: Text.PlainText
Layout.fillWidth: true
text: dropbox.installed ? "Login to Dropbox" : "Dropbox CLI is not installed"
text: dropbox.installed ? I18n.tr("Login to Dropbox") : I18n.tr("Dropbox CLI is not installed")
color: root.foreground
font.family: root.fontFamily
font.pixelSize: Style.font.body
@@ -434,7 +434,7 @@ Panel {
Text {
textFormat: Text.PlainText
Layout.fillWidth: true
text: dropbox.installed ? "Start the authentication flow" : "Install Dropbox from the service menu"
text: dropbox.installed ? I18n.tr("Start the authentication flow") : I18n.tr("Install Dropbox from the service menu")
color: root.dim
font.family: root.fontFamily
font.pixelSize: Style.font.caption
@@ -457,7 +457,7 @@ Panel {
id: fileRow
property var file: null
property int rowIndex: 0
readonly property string fileName: file ? String(file.name || "Untitled") : "Untitled"
readonly property string fileName: file ? String(file.name || I18n.tr("Untitled")) : I18n.tr("Untitled")
hasCursor: root.cursorActive && root.focusSection === "files" && root.fileIndex === rowIndex
foreground: root.foreground
@@ -73,7 +73,7 @@ Column {
width: parent.width
horizontalAlignment: Text.AlignHCenter
topPadding: Style.spacing.md
text: list.citySearch.loading ? list.citySearch.loadingText : "No matches"
text: list.citySearch.loading ? list.citySearch.loadingText : I18n.tr("No matches")
color: list.citySearch.fainter
}
+1 -1
View File
@@ -300,7 +300,7 @@ Rectangle {
color: Model.mix(Color.popups.background, row.foreground, _hot ? 0.24 : 0.14)
borderSpec: Border.flat(Model.mix(Color.popups.background, row.foreground, _hot ? 0.65 : 0.35), Style.space(1))
iconText: "\u00d7"
tooltipText: "Remove"
tooltipText: I18n.tr("Remove")
foreground: row.dim
hoverColor: row.foreground
fontFamily: row.fontFamily
+1 -1
View File
@@ -17,7 +17,7 @@ Column {
property var offsetLabel: function(zoneId) { return "" }
property bool loading: false
property string buttonText: "+ Add a city"
property string placeholderText: "Search cities\u2026"
property string placeholderText: I18n.tr("Search cities…")
property string loadingText: "Loading zones\u2026"
property real fontSize: Style.font.bodySmall
property color foreground: Color.foreground
@@ -65,8 +65,8 @@ Item {
var out = []
var up = Sun.eventMark(sun.riseMinutes)
var down = Sun.eventMark(sun.setMinutes)
if (up !== null) out.push({ x: up, minutes: sun.riseMinutes, rising: true, name: "Sunrise" })
if (down !== null) out.push({ x: down, minutes: sun.setMinutes, rising: false, name: "Sunset" })
if (up !== null) out.push({ x: up, minutes: sun.riseMinutes, rising: true, name: I18n.tr("Sunrise") })
if (down !== null) out.push({ x: down, minutes: sun.setMinutes, rising: false, name: I18n.tr("Sunset") })
return out
}
+1 -1
View File
@@ -584,7 +584,7 @@ Item {
limit: 5
inlineResults: false
loading: root.jumpOptions.length === 0
buttonText: "Jump to a city"
buttonText: I18n.tr("Jump to a city")
loadingText: "Loading cities\u2026"
offsetLabel: function(zoneId) { return Model.utcOffsetLabel(root.offsets[zoneId]) }
foreground: root.foreground
+2 -2
View File
@@ -72,7 +72,7 @@ Column {
anchors.horizontalCenter: parent.horizontalCenter
spacing: Style.space(9)
TitleWord { text: "World" }
TitleWord { text: I18n.tr("World") }
Item {
id: heroIcon
@@ -150,7 +150,7 @@ Column {
}
}
TitleWord { text: "Clock" }
TitleWord { text: I18n.tr("Clock") }
}
component TitleWord: Text {
+2 -2
View File
@@ -334,7 +334,7 @@ Panel {
}
// No full stop: a period hanging off the arc reads as a speck.
readonly property string hereLine: "It's " + localTime + " here"
readonly property string hereLine: I18n.tr("It's %1 here", localTime)
+ (homeCity !== "" ? " in " + homeCity : "")
+ (scrubLabel !== "" ? " " + scrubLabel : "")
@@ -714,7 +714,7 @@ Panel {
bar: root.bar
slotSize: Style.bar.statusSlot
text: "󰇧"
tooltipText: "World clock"
tooltipText: I18n.tr("World clock")
onPressed: function(buttonCode) {
if (buttonCode === Qt.RightButton || buttonCode === Qt.MiddleButton) root.refresh()
else root.toggle()
+7 -7
View File
@@ -555,7 +555,7 @@ Panel {
spacing: Style.space(2)
Text {
text: "Display"
text: I18n.tr("Display")
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.title
@@ -569,9 +569,9 @@ Panel {
textFormat: Text.PlainText
text: {
if (root.brightnessAvailable) {
return root.brightnessName(brightnessSlider.dragging ? brightnessSlider.liveValue : root.brightnessPercent).toUpperCase()
return I18n.tr(root.brightnessName(brightnessSlider.dragging ? brightnessSlider.liveValue : root.brightnessPercent)).toUpperCase()
}
return "FIXED BRIGHTNESS"
return I18n.tr("FIXED BRIGHTNESS")
}
color: Qt.darker(root.bar.foreground, 1.4)
font.family: root.bar.fontFamily
@@ -601,7 +601,7 @@ Panel {
PanelSectionHeader {
id: brightnessHeader
text: "BRIGHTNESS"
text: I18n.tr("BRIGHTNESS")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
anchors.left: parent.left
@@ -674,7 +674,7 @@ Panel {
PanelSectionHeader {
id: textSizeHeader
text: "TEXT SIZE"
text: I18n.tr("TEXT SIZE")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
anchors.left: parent.left
@@ -746,7 +746,7 @@ Panel {
PanelSectionHeader {
id: scaleHeader
text: "SCALE"
text: I18n.tr("SCALE")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
anchors.left: parent.left
@@ -808,7 +808,7 @@ Panel {
visible: root.displays.length > 1
PanelSectionHeader {
text: "DISPLAYS"
text: I18n.tr("DISPLAYS")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
}
+67 -63
View File
@@ -56,13 +56,13 @@ Panel {
readonly property bool hasTransferStats: info.rx_bytes !== undefined
property int connectionPhraseIndex: 0
readonly property var connectionPhrases: [
"Wiring bits",
"Handling packets",
"Sorting frames",
"Hauling bytes",
"Routing crumbs",
"Counting collisions",
"Bending light",
I18n.tr("Wiring bits"),
I18n.tr("Handling packets"),
I18n.tr("Sorting frames"),
I18n.tr("Hauling bytes"),
I18n.tr("Routing crumbs"),
I18n.tr("Counting collisions"),
I18n.tr("Bending light"),
]
readonly property string connectionPhrase: connectionPhrases[connectionPhraseIndex % connectionPhrases.length]
readonly property bool networkManagerAvailable: Networking.backend === NetworkBackendType.NetworkManager
@@ -137,7 +137,7 @@ Panel {
readonly property bool qrHeaderHasCursor: cursorActive && focusSection === "header" && headerIndex === qrHeaderIndex
readonly property bool speedHeaderHasCursor: cursorActive && focusSection === "header" && headerIndex === speedHeaderIndex
readonly property bool toggleHeaderHasCursor: cursorActive && focusSection === "header" && headerIndex === toggleHeaderIndex
readonly property string toggleHint: Networking.wifiEnabled ? "Turn Wi-Fi off" : "Turn Wi-Fi on"
readonly property string toggleHint: Networking.wifiEnabled ? I18n.tr("Turn Wi-Fi off") : I18n.tr("Turn Wi-Fi on")
readonly property var dnsProviders: ["DHCP", "Cloudflare", "Google", "Custom"]
property int dnsIndex: 0
// ["2.4", "5", ...], or empty when there is nothing to choose between.
@@ -159,7 +159,10 @@ Panel {
// Under Automatic there is nothing to pick, so the pills collapse away and
// the header states the live band instead.
readonly property bool bandPillsVisible: canSelectBand && bandPinned
readonly property string bandSectionTitle: Model.bandSectionTitle(bandEffective, bandCurrent)
readonly property string bandSectionTitle: {
var title = Model.bandSectionTitle(bandEffective, bandCurrent)
return title.indexOf("WI-FI BAND: ") === 0 ? I18n.tr("WI-FI BAND: %1", title.slice(12)) : I18n.tr(title)
}
readonly property bool bandBusy: pendingBand !== ""
// The speed test needs an interface to test, so its hero action only
// appears once there is one.
@@ -279,11 +282,12 @@ Panel {
}
function bandLabel(band) {
return Model.bandLabel(band)
return I18n.tr(Model.bandLabel(band))
}
function bandTooltip(band) {
return Model.bandTooltip(band)
var tip = Model.bandTooltip(band)
return tip.indexOf("Stay on ") === 0 ? I18n.tr("Stay on %1", bandLabel(band)) : I18n.tr(tip)
}
// Single cursor model: exactly one highlighted spot across the whole
@@ -662,7 +666,7 @@ Panel {
}
function formatPingLatency(ms) {
return Model.formatPingLatency(ms, hasInternetPing)
return I18n.tr(Model.formatPingLatency(ms, hasInternetPing))
}
function formatPacketLoss(percent) {
@@ -709,7 +713,7 @@ Panel {
}
function wifiSectionTitle(index) {
return Model.wifiSectionTitle(wifiNetworks, index)
return I18n.tr(Model.wifiSectionTitle(wifiNetworks, index))
}
function wifiIconFor(strength) {
@@ -754,7 +758,7 @@ Panel {
cancelPasswordPrompt()
var connection = ""
if (info.type === "wifi") connection = info.ssid || "Wi-Fi"
else if (info.type === "ethernet") connection = "Ethernet"
else if (info.type === "ethernet") connection = I18n.tr("Ethernet")
bar.shell.summon("omarchy.speedtest", connection ? JSON.stringify({ connection: connection }) : "{}")
}
@@ -835,7 +839,7 @@ Panel {
if (!network || actionKind === "" || actionSsid !== (network.name || "")) return
actionTimeout.stop()
failureSsid = actionSsid
failureReason = networkFailureReason(reason, requiresCredentials(network.security))
failureReason = I18n.tr(networkFailureReason(reason, requiresCredentials(network.security)))
actionSsid = ""
actionKind = ""
refresh()
@@ -1062,9 +1066,9 @@ Panel {
onTriggered: {
if (!root.actionKind) return
var reason
if (root.actionKind === "connect") reason = "Timed out connecting"
else if (root.actionKind === "disconnect") reason = "Timed out disconnecting"
else reason = "Timed out forgetting"
if (root.actionKind === "connect") reason = I18n.tr("Timed out connecting")
else if (root.actionKind === "disconnect") reason = I18n.tr("Timed out disconnecting")
else reason = I18n.tr("Timed out forgetting")
root.failureSsid = root.actionSsid
root.failureReason = reason
root.actionSsid = ""
@@ -1079,8 +1083,8 @@ Panel {
bar: root.bar
text: root.icon
active: root.restricted
tooltipText: root.hasCaptivePortal ? "Sign in to this network"
: (root.restricted ? "Limited internet access" : "")
tooltipText: root.hasCaptivePortal ? I18n.tr("Sign in to this network")
: (root.restricted ? I18n.tr("Limited internet access") : "")
onPressed: function(b) {
if (root.opened) root.close()
@@ -1249,7 +1253,7 @@ Panel {
id: qrAction
visible: root.canShareWifi
iconText: "󰐲"
tooltipText: "Show QR code"
tooltipText: I18n.tr("Show QR code")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
iconSize: Style.font.subtitle * 1.5
@@ -1265,7 +1269,7 @@ Panel {
id: speedAction
visible: root.canRunSpeedTest
iconText: "󰓅"
tooltipText: "Run a speed test"
tooltipText: I18n.tr("Run a speed test")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
iconSize: Style.font.subtitle * 1.5
@@ -1316,8 +1320,8 @@ Panel {
// SSID even before route/details polling has returned anything.
if (root.kind === "wifi" && root.connectedWifiNetwork) return root.connectedWifiNetwork.name || "Wi-Fi"
if (root.info.type === "wifi") return root.info.ssid || "Wi-Fi"
if (root.info.type === "ethernet") return "Ethernet"
return root.info.iface || (root.kind === "disconnected" ? "Disconnected" : "No connection")
if (root.info.type === "ethernet") return I18n.tr("Ethernet")
return root.info.iface || (root.kind === "disconnected" ? I18n.tr("Disconnected") : I18n.tr("No connection"))
}
readonly property string detail: root.headerDetail()
@@ -1334,15 +1338,15 @@ Panel {
textFormat: Text.PlainText
width: parent.width
text: {
if (root.hasCaptivePortal) return "SIGN-IN REQUIRED"
if (root.restricted) return "LIMITED INTERNET ACCESS"
if (root.hasCaptivePortal) return I18n.tr("SIGN-IN REQUIRED")
if (root.restricted) return I18n.tr("LIMITED INTERNET ACCESS")
if (root.info.type === "wifi") {
if (root.canDisconnect) return root.connectionPhrase.toUpperCase()
if (root.kind === "disconnected") return "NOT CONNECTED"
if (root.kind === "disconnected") return I18n.tr("NOT CONNECTED")
return ""
}
if (root.info.type === "ethernet") return root.connectionPhrase.toUpperCase()
if (root.kind === "disconnected") return "NOT CONNECTED"
if (root.kind === "disconnected") return I18n.tr("NOT CONNECTED")
return ""
}
visible: text !== ""
@@ -1365,7 +1369,7 @@ Panel {
Button {
id: portalAction
width: parent.width
text: "Open Captive Portal"
text: I18n.tr("Open Captive Portal")
iconText: "󰏌"
foreground: root.bar.urgent
accent: root.bar.urgent
@@ -1384,7 +1388,7 @@ Panel {
Text {
width: parent.width
text: "Sign in or accept this network’s terms to access the internet."
text: I18n.tr("Sign in or accept this network’s terms to access the internet.")
textFormat: Text.PlainText
wrapMode: Text.WordWrap
color: root.bar.foreground
@@ -1410,38 +1414,38 @@ Panel {
// opened, once the first probe returned, shoving everything below
// them down. They now hold their place and read "--" until there is
// a sample.
InfoLabel { text: "Ping" }
InfoLabel { text: I18n.tr("Ping") }
DetailValue {
text: root.formatPingLatency(root.internetPingLatency)
color: root.internetPingPacketLoss > 0 ? root.bar.urgent : root.bar.foreground
}
InfoLabel { text: "Packet Loss" }
InfoLabel { text: I18n.tr("Packet Loss") }
DetailValue {
text: root.formatPacketLoss(root.internetPingPacketLoss)
color: root.internetPingPacketLoss > 0 ? root.bar.urgent : root.bar.foreground
}
InfoLabel { text: "Receiving" }
InfoLabel { text: I18n.tr("Receiving") }
DetailValue { text: root.hasTransferStats ? root.formatRate(root.downloadRate) : "--" }
InfoLabel { text: "Sending" }
InfoLabel { text: I18n.tr("Sending") }
DetailValue { text: root.hasTransferStats ? root.formatRate(root.uploadRate) : "--" }
InfoLabel { text: "Downloaded" }
InfoLabel { text: I18n.tr("Downloaded") }
DetailValue { text: root.hasTransferStats ? root.formatBytes(parseFloat(root.info.rx_bytes || "0")) : "--" }
InfoLabel { text: "Uploaded" }
InfoLabel { text: I18n.tr("Uploaded") }
DetailValue { text: root.hasTransferStats ? root.formatBytes(parseFloat(root.info.tx_bytes || "0")) : "--" }
InfoLabel { text: "IP Address" }
InfoLabel { text: I18n.tr("IP Address") }
DetailValue {
text: root.info.ip || "--"
copyable: !!root.info.ip
tooltipText: "Copy IP"
tooltipText: I18n.tr("Copy IP")
}
InfoLabel { text: "Gateway" }
InfoLabel { text: I18n.tr("Gateway") }
DetailValue {
text: root.info.gateway || "--"
copyable: !!root.info.gateway
tooltipText: "Copy gateway"
tooltipText: I18n.tr("Copy gateway")
}
}
}
@@ -1482,7 +1486,7 @@ Panel {
PanelSectionHeader {
id: bandAutoLabel
text: "AUTOMATIC"
text: I18n.tr("AUTOMATIC")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
anchors.verticalCenter: parent.verticalCenter
@@ -1515,8 +1519,8 @@ Panel {
PanelToolTip {
visible: bandAutoSwitch.containsMouse
text: root.bandPinned
? "Let Wi-Fi pick the band"
: "Stay on " + root.bandLabel(root.bandCurrent)
? I18n.tr("Let Wi-Fi pick the band")
: I18n.tr("Stay on %1", root.bandLabel(root.bandCurrent))
fontFamily: root.bar.fontFamily
}
}
@@ -1587,7 +1591,7 @@ Panel {
spacing: Style.space(10)
PanelSectionHeader {
text: "DNS PROVIDER"
text: I18n.tr("DNS PROVIDER")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
}
@@ -1603,7 +1607,7 @@ Panel {
DnsProviderPill {
provider: "DHCP"
index: 0
tooltipText: "Use DNS from DHCP"
tooltipText: I18n.tr("Use DNS from DHCP")
width: dnsRow.cellWidth
onClicked: root.setDns(provider)
}
@@ -1611,7 +1615,7 @@ Panel {
DnsProviderPill {
provider: "Cloudflare"
index: 1
tooltipText: "Set DNS to Cloudflare"
tooltipText: I18n.tr("Set DNS to %1", "Cloudflare")
width: dnsRow.cellWidth
onClicked: root.setDns(provider)
}
@@ -1619,7 +1623,7 @@ Panel {
DnsProviderPill {
provider: "Google"
index: 2
tooltipText: "Set DNS to Google"
tooltipText: I18n.tr("Set DNS to %1", "Google")
width: dnsRow.cellWidth
onClicked: root.setDns(provider)
}
@@ -1627,7 +1631,7 @@ Panel {
DnsProviderPill {
provider: "Custom"
index: 3
tooltipText: "Set custom DNS servers"
tooltipText: I18n.tr("Set custom DNS servers")
width: dnsRow.cellWidth
onClicked: root.setDns(provider)
}
@@ -1643,7 +1647,7 @@ Panel {
PanelSectionHeader {
visible: root.wifiStationAvailable && root.scanning
text: "SCANNING WI-FI…"
text: I18n.tr("SCANNING WI-FI…")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
}
@@ -1746,7 +1750,7 @@ Panel {
required property string provider
required property int index
text: provider
text: I18n.tr(provider)
fontSize: Style.font.bodySmall
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
@@ -1829,12 +1833,12 @@ Panel {
readonly property string statusText: {
if (!net) return ""
if (isPasswordOpen) return ""
if (isBusy && root.actionKind === "connect") return "Connecting…"
if (isBusy && root.actionKind === "disconnect") return "Disconnecting…"
if (isBusy && root.actionKind === "forget") return "Forgetting…"
if (isFailed) return root.failureReason || "Failed"
if (isConnected && root.kind === "wifi" && root.hasCaptivePortal) return "Sign-in required"
if (isConnected) return "Connected"
if (isBusy && root.actionKind === "connect") return I18n.tr("Connecting…")
if (isBusy && root.actionKind === "disconnect") return I18n.tr("Disconnecting…")
if (isBusy && root.actionKind === "forget") return I18n.tr("Forgetting…")
if (isFailed) return root.failureReason || I18n.tr("Failed")
if (isConnected && root.kind === "wifi" && root.hasCaptivePortal) return I18n.tr("Sign-in required")
if (isConnected) return I18n.tr("Connected")
return ""
}
@@ -1951,7 +1955,7 @@ Panel {
PanelToolTip {
visible: rightMouse.containsMouse || row.forgetFocused
text: "Forget network"
text: I18n.tr("Forget network")
fontFamily: root.bar.fontFamily
}
}
@@ -1967,7 +1971,7 @@ Panel {
Text {
textFormat: Text.PlainText
text: row.net ? (row.net.ssid || "Hidden") : ""
text: row.net ? (row.net.ssid || I18n.tr("Hidden")) : ""
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.body
@@ -2027,7 +2031,7 @@ Panel {
anchors.right: connectPwBtn.left
anchors.top: parent.top
anchors.rightMargin: Style.space(6)
placeholderText: "Identity (user@domain)"
placeholderText: I18n.tr("Identity (user@domain)")
font.family: Style.font.family
font.pixelSize: Style.font.body
foreground: root.bar.foreground
@@ -2053,7 +2057,7 @@ Panel {
anchors.bottomMargin: Style.spacing.rowGap / 2
anchors.rightMargin: Style.space(6)
password: true
placeholderText: "Passphrase"
placeholderText: I18n.tr("Passphrase")
font.family: Style.font.family
font.pixelSize: Style.font.body
foreground: root.bar.foreground
@@ -2086,7 +2090,7 @@ Panel {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: row.isFailed ? "Wrong password" : "Connecting..."
text: row.isFailed ? I18n.tr("Wrong password") : I18n.tr("Connecting...")
color: row.isFailed ? root.bar.urgent : root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -2103,7 +2107,7 @@ Panel {
anchors.verticalCenter: parent.verticalCenter
enabled: row.net && pwField.text.length > 0 && (!row.isEnterprise || idField.text.length > 0)
iconText: "󰄬"
tooltipText: "Connect"
tooltipText: I18n.tr("Connect")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
onClicked: row.submitCredentials()
@@ -2114,7 +2118,7 @@ Panel {
component DetailValue: InfoValue {
property bool copyable: false
property string tooltipText: "Copy to clipboard"
property string tooltipText: I18n.tr("Copy to clipboard")
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
+27 -27
View File
@@ -54,7 +54,7 @@ Panel {
function modeLabel() {
var device = UPower.displayDevice
return Model.modeLabel(device, root.discharging, upowerStates())
return I18n.tr(Model.modeLabel(device, root.discharging, upowerStates()))
}
function profileIcon(name) {
@@ -94,26 +94,26 @@ Panel {
// Cute agent-flavored phrases shown in the hero status line, rotated on a
// timer so the panel feels alive when current is flowing (either direction).
readonly property var chargingPhrases: [
"Pumping power",
"Injecting electrons",
"Pouring juice",
"Amassing watts",
"Hoarding joules",
"Sucking volts",
"Topping reserves",
"Soaking amps",
"Inhaling kilowatts"
I18n.tr("Pumping power"),
I18n.tr("Injecting electrons"),
I18n.tr("Pouring juice"),
I18n.tr("Amassing watts"),
I18n.tr("Hoarding joules"),
I18n.tr("Sucking volts"),
I18n.tr("Topping reserves"),
I18n.tr("Soaking amps"),
I18n.tr("Inhaling kilowatts")
]
readonly property var onBatteryPhrases: [
"Slurping power",
"Spending joules",
"Draining watts",
"Burning electrons",
"Sipping juice",
"Spending coulombs",
"Bleeding amps",
"Guzzling volts",
"Munching reserves"
I18n.tr("Slurping power"),
I18n.tr("Spending joules"),
I18n.tr("Draining watts"),
I18n.tr("Burning electrons"),
I18n.tr("Sipping juice"),
I18n.tr("Spending coulombs"),
I18n.tr("Bleeding amps"),
I18n.tr("Guzzling volts"),
I18n.tr("Munching reserves")
]
property int phraseIndex: 0
@@ -127,7 +127,7 @@ Panel {
readonly property bool rotatingPhrases: activePhrases.length > 0
readonly property string heroStatusText: {
if (fullyCharged) return "Fully charged"
if (fullyCharged) return I18n.tr("Fully charged")
if (rotatingPhrases) return activePhrases[phraseIndex % activePhrases.length]
return modeLabel()
}
@@ -346,7 +346,7 @@ Panel {
spacing: Style.space(2)
Text {
text: "Battery"
text: I18n.tr("Battery")
color: root.bar.foreground
font.family: root.bar.fontFamily
font.pixelSize: Style.font.title
@@ -433,20 +433,20 @@ Panel {
Column {
width: (parent.width - parent.spacing) / 2
spacing: Style.spacing.labelGap
InfoPair { label: "Battery size"; value: root.batteryInfo.size || "" }
InfoPair { label: "Charge cycles"; value: root.batteryInfo.cycles || "—" }
InfoPair { label: I18n.tr("Battery size"); value: root.batteryInfo.size || "" }
InfoPair { label: I18n.tr("Charge cycles"); value: root.batteryInfo.cycles || "—" }
}
Column {
width: (parent.width - parent.spacing) / 2
spacing: Style.spacing.labelGap
InfoPair {
label: root.chargeThresholdActive ? "Charge limit" : (root.discharging ? "Time left" : "Time to full")
label: root.chargeThresholdActive ? I18n.tr("Charge limit") : (root.discharging ? I18n.tr("Time left") : I18n.tr("Time to full"))
value: root.chargeThresholdActive ? (root.batteryInfo.threshold || "-") : (root.batteryFlowIdle ? "-" : (root.batteryInfo.time || "—"))
}
InfoPair {
label: root.chargeThresholdActive ? "Battery state" : (root.discharging ? "Discharging" : "Charging")
value: root.chargeThresholdActive ? "Holding" : (root.batteryFull ? "-" : (root.batteryInfo.rate || ""))
label: root.chargeThresholdActive ? I18n.tr("Battery state") : (root.discharging ? I18n.tr("Discharging") : I18n.tr("Charging"))
value: root.chargeThresholdActive ? I18n.tr("Holding") : (root.batteryFull ? "-" : (root.batteryInfo.rate || ""))
}
}
}
@@ -461,7 +461,7 @@ Panel {
spacing: Style.space(10)
PanelSectionHeader {
text: "POWER PROFILE"
text: I18n.tr("POWER PROFILE")
foreground: root.bar.foreground
fontFamily: root.bar.fontFamily
}
+5 -5
View File
@@ -149,7 +149,7 @@ Item {
}
if (!root.expectedStop && exitCode !== 0) {
root.error = root.stderrText || "Speed test failed"
root.error = root.stderrText || I18n.tr("Speed test failed")
root.phase = ""
root.running = false
return
@@ -177,7 +177,7 @@ Item {
onStreamFinished: {
var fields = String(text || "").trim().split("\t")
if (fields[0] === "wifi") root.connectionName = fields[1] || "Wi-Fi"
else if (fields[0] === "ethernet") root.connectionName = "Ethernet"
else if (fields[0] === "ethernet") root.connectionName = I18n.tr("Ethernet")
}
}
}
@@ -186,9 +186,9 @@ Item {
fontFamily: Style.font.family
layerNamespace: "omarchy-network-speedtest"
title: root.connectionName
leftLabel: "DOWNLOAD"
rightLabel: "UPLOAD"
runAgainTooltip: "Measure again via fast.com"
leftLabel: I18n.tr("DOWNLOAD")
rightLabel: I18n.tr("UPLOAD")
runAgainTooltip: I18n.tr("Measure again via fast.com")
running: root.running
leftValue: root.downloadValue
rightValue: root.uploadValue
+30 -30
View File
@@ -24,16 +24,16 @@ Panel {
property string mullvadQuery: ""
property int phraseIndex: 0
readonly property var activePhrases: [
"Encrypting connections",
"Sending secrets",
"Guarding wires",
"Braiding packets",
"Polishing tunnels",
"Hiding routes",
"Sealing ports",
"Sorting tailnets",
"Shuffling keys",
"Watching machines"
I18n.tr("Encrypting connections"),
I18n.tr("Sending secrets"),
I18n.tr("Guarding wires"),
I18n.tr("Braiding packets"),
I18n.tr("Polishing tunnels"),
I18n.tr("Hiding routes"),
I18n.tr("Sealing ports"),
I18n.tr("Sorting tailnets"),
I18n.tr("Shuffling keys"),
I18n.tr("Watching machines")
]
readonly property string heroPhraseText: activePhrases[phraseIndex % activePhrases.length]
@@ -52,7 +52,7 @@ Panel {
// "header" stays navigable, but an absent CLI leaves nothing to highlight.
readonly property bool headerHasCursor: cursorActive && focusSection === "header" && tailscale.installed
readonly property color iconColor: tailscale.active ? foreground : dim
readonly property string toggleHint: tailscale.active ? "Turn Tailscale off" : (tailscale.needsLogin ? "Authorize this device" : "Turn Tailscale on")
readonly property string toggleHint: tailscale.active ? I18n.tr("Turn Tailscale off") : (tailscale.needsLogin ? I18n.tr("Authorize this device") : I18n.tr("Turn Tailscale on"))
readonly property color barIconColor: tailscale.active ? barForeground : Qt.darker(barForeground, 1.55)
readonly property color hoverFill: bar ? Style.hoverFillFor(bar.foreground, Color.accent) : "transparent"
readonly property color selectedFill: bar ? Style.selectedFillFor(bar.foreground, Color.accent) : "transparent"
@@ -76,7 +76,7 @@ Panel {
var nodes = []
for (var i = 0; i < tailscale.tailnetExitNodes.length; i++) nodes.push(tailscale.tailnetExitNodes[i])
for (var j = 0; j < recentMullvadExitNodes.length; j++) nodes.push(recentMullvadExitNodes[j])
if (tailscale.mullvadRegions.length > 0) nodes.push({ id: "mullvad:add", AddMullvad: true, DisplayName: "Choose Mullvad region" })
if (tailscale.mullvadRegions.length > 0) nodes.push({ id: "mullvad:add", AddMullvad: true, DisplayName: I18n.tr("Choose Mullvad region") })
return nodes
}
@@ -132,7 +132,7 @@ Panel {
}
function mullvadRegionTitle(peer) {
if (!peer) return "Unknown"
if (!peer) return I18n.tr("Unknown")
var city = String(peer.City || "").trim()
var country = String(peer.Country || "").trim()
if (city === "" || city === "Any") return country || String(peer.DisplayName || "Unknown")
@@ -458,7 +458,7 @@ Panel {
id: hero
width: parent.width
title: tailscale.installed ? (tailscale.selfName || "Tailscale") : "Tailscale"
meta: tailscale.active ? root.heroPhraseText : "Tailscale is disconnected"
meta: tailscale.active ? root.heroPhraseText : I18n.tr("Tailscale is disconnected")
foreground: root.foreground
fontFamily: root.fontFamily
iconOpacity: tailscale.active ? 1.0 : 0.5
@@ -501,7 +501,7 @@ Panel {
textFormat: Text.PlainText
visible: tailscale.actionStatus !== "" || tailscale.lastError !== ""
width: parent.width
text: tailscale.actionStatus !== "" ? tailscale.actionStatus : tailscale.lastError
text: I18n.tr(tailscale.actionStatus !== "" ? tailscale.actionStatus : tailscale.lastError)
color: tailscale.lastError !== "" && tailscale.actionStatus === "" ? root.urgent : root.dim
font.family: root.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -520,7 +520,7 @@ Panel {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: Style.space(12)
text: "Tailscale CLI is not installed or not on PATH."
text: I18n.tr("Tailscale CLI is not installed or not on PATH.")
color: root.dim
font.family: root.fontFamily
font.pixelSize: Style.font.body
@@ -539,7 +539,7 @@ Panel {
spacing: Style.space(10)
PanelSectionHeader {
text: "CONNECTIONS"
text: I18n.tr("CONNECTIONS")
foreground: root.foreground
fontFamily: root.fontFamily
}
@@ -572,7 +572,7 @@ Panel {
spacing: Style.space(10)
PanelSectionHeader {
text: "EXIT NODES"
text: I18n.tr("EXIT NODES")
foreground: root.foreground
fontFamily: root.fontFamily
}
@@ -602,7 +602,7 @@ Panel {
id: mullvadSearch
width: parent.width
foreground: root.foreground
placeholderText: "Search regions"
placeholderText: I18n.tr("Search regions")
text: root.mullvadQuery
onTextChanged: {
root.mullvadQuery = text
@@ -638,7 +638,7 @@ Panel {
Text {
visible: root.filteredMullvadRegions.length === 0
width: parent.width
text: "No Mullvad regions found."
text: I18n.tr("No Mullvad regions found.")
color: root.dim
font.family: root.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -676,7 +676,7 @@ Panel {
spacing: Style.space(10)
PanelSectionHeader {
text: "MACHINES"
text: I18n.tr("MACHINES")
foreground: root.foreground
fontFamily: root.fontFamily
}
@@ -684,7 +684,7 @@ Panel {
Text {
visible: tailscale.installed && tailscale.active && tailscale.peers.length === 0
width: parent.width
text: "No machines found on this tailnet."
text: I18n.tr("No machines found on this tailnet.")
color: root.dim
font.family: root.fontFamily
font.pixelSize: Style.font.body
@@ -777,7 +777,7 @@ Panel {
Text {
Layout.fillWidth: true
text: "Authorize Tailscale operator"
text: I18n.tr("Authorize Tailscale operator")
color: root.foreground
font.family: root.fontFamily
font.pixelSize: Style.font.body
@@ -786,7 +786,7 @@ Panel {
Text {
Layout.fillWidth: true
text: "Allow this user to operate this Tailscale profile"
text: I18n.tr("Allow this user to operate this Tailscale profile")
color: root.dim
font.family: root.fontFamily
font.pixelSize: Style.font.caption
@@ -803,7 +803,7 @@ Panel {
property int rowIndex: 0
readonly property bool selectedAccount: account && account.selected === true
readonly property bool switchingAccount: account && tailscale.switchingAccountId === String(account.id || "")
readonly property string accountText: account ? tailscale.accountLabel(account) : "Account"
readonly property string accountText: account ? tailscale.accountLabel(account) : I18n.tr("Account")
hasCursor: root.cursorActive && root.focusSection === "accounts" && root.accountIndex === rowIndex
current: selectedAccount
@@ -867,7 +867,7 @@ Panel {
id: peerRow
property var peer: null
property int rowIndex: 0
readonly property string peerName: peer ? String(peer.DisplayName || peer.HostName || "Unknown") : "Unknown"
readonly property string peerName: peer ? String(peer.DisplayName || peer.HostName || I18n.tr("Unknown")) : I18n.tr("Unknown")
readonly property string peerIp: peer && peer.TailscaleIPs && peer.TailscaleIPs.length > 0 ? String(peer.TailscaleIPs[0]) : ""
readonly property string peerIpv6: {
if (!peer || !peer.TailscaleIPv6 || peer.TailscaleIPv6.length === 0) return ""
@@ -978,7 +978,7 @@ Panel {
id: sendButton
visible: tailscale.canSendFiles(peerRow.peer)
iconText: "󰒊"
tooltipText: "Send files"
tooltipText: I18n.tr("Send files")
foreground: root.foreground
fontFamily: root.fontFamily
Layout.alignment: Qt.AlignVCenter
@@ -1118,8 +1118,8 @@ Panel {
readonly property bool addMullvad: peer && peer.AddMullvad === true
readonly property bool activeExitNode: peer && peer.ExitNode === true
readonly property bool settingExitNode: peer && tailscale.settingExitNodeId === String(peer.id || "")
readonly property string peerName: peer ? String(peer.DisplayName || peer.HostName || "Unknown") : "Unknown"
readonly property string actionTooltip: addMullvad ? "" : (activeExitNode ? "Disconnect" : "Connect")
readonly property string peerName: peer ? String(peer.DisplayName || peer.HostName || I18n.tr("Unknown")) : I18n.tr("Unknown")
readonly property string actionTooltip: addMullvad ? "" : (activeExitNode ? I18n.tr("Disconnect") : I18n.tr("Connect"))
hasCursor: root.cursorActive && root.focusSection === "exitNodes" && root.exitNodeIndex === rowIndex
current: activeExitNode || settingExitNode || (addMullvad && root.mullvadPickerOpen)
@@ -1199,7 +1199,7 @@ Panel {
readonly property bool activeExitNode: peer && peer.ExitNode === true
readonly property bool settingExitNode: peer && tailscale.settingExitNodeId === String(peer.id || "")
readonly property bool selectedRegion: root.mullvadPickerOpen && root.mullvadRegionIndex === rowIndex
readonly property string actionTooltip: activeExitNode ? "Disconnect" : "Connect"
readonly property string actionTooltip: activeExitNode ? I18n.tr("Disconnect") : I18n.tr("Connect")
foreground: root.foreground
fill: root.hoverFill
+5 -5
View File
@@ -616,7 +616,7 @@ Panel {
id: locationField
width: Style.space(190)
enabled: !root.savingLocation
placeholderText: "Search city"
placeholderText: I18n.tr("Search city")
foreground: root.bar.foreground
font.family: root.bar.fontFamily
@@ -683,7 +683,7 @@ Panel {
Column {
spacing: Style.space(5)
Text {
text: "FEELS"
text: I18n.tr("FEELS")
color: Qt.darker(root.bar.foreground, 1.5)
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -701,7 +701,7 @@ Panel {
Column {
spacing: Style.space(5)
Text {
text: "WIND"
text: I18n.tr("WIND")
color: Qt.darker(root.bar.foreground, 1.5)
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -719,7 +719,7 @@ Panel {
Column {
spacing: Style.space(5)
Text {
text: "HUMID"
text: I18n.tr("HUMID")
color: Qt.darker(root.bar.foreground, 1.5)
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -792,7 +792,7 @@ Panel {
Text {
visible: !root.current
text: "Fetching forecast…"
text: I18n.tr("Fetching forecast…")
color: Qt.darker(root.bar.foreground, 1.5)
font.family: root.bar.fontFamily
font.pixelSize: Style.font.bodySmall
+5 -5
View File
@@ -183,7 +183,7 @@ Item {
if (exitCode !== 0 || root.qrSize === 0) {
root.qrSize = 0
root.qrRows = []
if (root.error === "") root.error = "Could not generate the Wi-Fi QR code"
if (root.error === "") root.error = I18n.tr("Could not generate the Wi-Fi QR code")
}
}
}
@@ -206,7 +206,7 @@ Item {
if (root.pwExpectedStop) return
if (!root.opened) return
if (exitCode === 0 && root.password !== "") root.passwordVisible = true
else root.passwordError = "Could not read the Wi-Fi password"
else root.passwordError = I18n.tr("Could not read the Wi-Fi password")
}
}
@@ -305,7 +305,7 @@ Item {
Text {
visible: root.loading
text: "Generating QR code…"
text: I18n.tr("Generating QR code…")
color: root.onScrimDim
font.family: root.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -328,7 +328,7 @@ Item {
Text {
visible: root.showingQr
text: "Scan to join this network"
text: I18n.tr("Scan to join this network")
color: root.onScrimDim
font.family: root.fontFamily
font.pixelSize: Style.font.bodySmall
@@ -341,7 +341,7 @@ Item {
visible: root.showingQr && root.secured
text: root.passwordError !== "" ? root.passwordError
: root.passwordVisible ? root.password
: "Show password"
: I18n.tr("Show password")
color: root.passwordError !== "" ? root.onScrimUrgent : root.onScrim
opacity: root.passwordVisible || root.passwordError !== "" ? 1 : 0.6
font.family: root.fontFamily