From 2bfed74851b44dfbb8de03694b487f99763247de Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Wed, 24 Sep 2025 14:24:21 +0200 Subject: [PATCH] i18n: even more integration autoformat --- Assets/Translations/en.json | 27 +++++- Bin/check-i18n.sh | 65 +++++++++++++++ Bin/i18n-check.sh | 79 +++++------------- Modules/Bar/WiFi/WiFiPanel.qml | 4 +- Modules/Bar/Widgets/KeyboardLayout.qml | 4 +- Modules/Bar/Widgets/Microphone.qml | 4 +- Modules/Bar/Widgets/PowerProfile.qml | 4 +- Modules/Bar/Widgets/SystemMonitor.qml | 8 +- Modules/Bar/Widgets/Volume.qml | 4 +- Modules/ControlCenter/Cards/MediaCard.qml | 2 +- .../ControlCenter/Cards/PowerProfilesCard.qml | 12 ++- Modules/ControlCenter/Cards/ProfileCard.qml | 4 +- Modules/LockScreen/LockScreen.qml | 4 +- Modules/Notification/Notification.qml | 2 +- .../Settings/Bar/BarWidgetSettingsDialog.qml | 4 +- .../Bar/WidgetSettings/BatterySettings.qml | 24 +++--- .../Bar/WidgetSettings/BrightnessSettings.qml | 24 +++--- .../WidgetSettings/KeyboardLayoutSettings.qml | 24 +++--- .../Bar/WidgetSettings/MediaMiniSettings.qml | 24 +++--- .../Bar/WidgetSettings/MicrophoneSettings.qml | 24 +++--- .../Bar/WidgetSettings/VolumeSettings.qml | 24 +++--- .../Bar/WidgetSettings/WorkspaceSettings.qml | 24 +++--- Modules/Settings/Tabs/AudioTab.qml | 83 ++++++++----------- Modules/Settings/Tabs/BarTab.qml | 6 +- Modules/Settings/Tabs/DisplayTab.qml | 10 ++- Modules/Settings/Tabs/DockTab.qml | 6 +- Modules/Settings/Tabs/LocationTab.qml | 5 +- Modules/Settings/Tabs/NotificationsTab.qml | 6 +- Modules/Settings/Tabs/ScreenRecorderTab.qml | 17 ++-- Services/GitHubService.qml | 6 +- Services/IdleInhibitorService.qml | 2 +- Services/KeyboardLayoutService.qml | 2 +- Widgets/NFilePicker.qml | 4 +- Widgets/NInputAction.qml | 2 +- Widgets/NSearchableComboBox.qml | 2 +- 35 files changed, 301 insertions(+), 245 deletions(-) create mode 100644 Bin/check-i18n.sh diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 004d5278..896e72d4 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -970,7 +970,9 @@ "previous-media": "Previous media", "pause": "Pause", "play": "Play", - "next-media": "Next media" + "next-media": "Next media", + "power-profile": "'{profile}' power profile", + "keyboard-layout": "{layout} keyboard layout" }, "clock": { "tooltip": "Open calendar" @@ -992,7 +994,11 @@ "clock-horizontal": "HH:mm ddd, MMM dd", "clock-vertical": "HH mm dd MM", "search-wallpapers": "Type to filter wallpapers...", - "search-launcher": "Search entries... or use > for commands" + "search-launcher": "Search entries... or use > for commands", + "search": "Search...", + "select": "Select", + "cancel": "Cancel", + "test": "Test" }, "options": { "display-mode": { @@ -1059,6 +1065,23 @@ "clipboard": "Clipboard history", "calculator": "Calculator" }, + "system": { + "uptime": "System uptime: {uptime}", + "welcome-back": "Welcome back, {user}!", + "monitor-description": "{model} ({width}x{height})", + "scaling-percentage": "{percentage}%", + "location-display": "{name} ({coordinates})", + "signal-strength": "{signal}%", + "cpu-temperature": "{temp}°C", + "disk-usage": "{percent}%", + "widget-settings-title": "{widget} Settings", + "unknown-app": "Unknown App", + "no-media-player-detected": "No media player detected", + "user-requested": "User requested", + "unknown": "Unknown", + "unknown-version": "Unknown", + "unknown-layout": "Unknown" + }, "lock-screen": { "secure-terminal": "SECURE TERMINAL", "unlock-command": "sudo unlock-session", diff --git a/Bin/check-i18n.sh b/Bin/check-i18n.sh new file mode 100644 index 00000000..77372b79 --- /dev/null +++ b/Bin/check-i18n.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Comprehensive i18n checker for Noctalia Shell +# Finds hardcoded strings that should be internationalized + +check_file() { + local file="$1" + + # Check for hardcoded strings in common properties + # Includes: label, text, title, description, tooltip, tooltipText, placeholder, placeholderText + local property_issues=$(grep -n -E '(label|text|title|description|tooltip|tooltipText|placeholder|placeholderText):\s*"[^"]{3,}"' "$file" | grep -v 'I18n.tr') + + # Check for hardcoded strings in dialog titles and button texts + local dialog_issues=$(grep -n -E '(dialog\.|Dialog\.|title:|buttonText:)\s*"[^"]{3,}"' "$file" | grep -v 'I18n.tr') + + # Check for hardcoded strings in model name properties (for combo boxes) + local model_issues=$(grep -n -E 'name:\s*"[^"]{3,}"' "$file" | grep -v 'I18n.tr') + + # Check for hardcoded strings in common UI text patterns + local ui_issues=$(grep -n -E '"[^"]*\b(click|open|close|enable|disable|show|hide|settings|cancel|apply|ok|save|load|start|stop|play|pause|next|previous|volume|brightness|wifi|bluetooth|notification|wallpaper|profile|power|session|menu|panel|dialog|button|toggle|slider|checkbox|radio|combo|input|search|filter|sort|refresh|update|delete|remove|add|create|edit|modify|copy|paste|cut|undo|redo|help|about|info|warning|error|success|failed|loading|connecting|connected|disconnected|scanning|pairing|recording|playing|paused|stopped|muted|unmuted|enabled|disabled|on|off|yes|no|true|false)\b[^"]*"' "$file" | grep -v 'I18n.tr' | grep -v '//' | grep -v '/*') + + # Combine all issues + local all_issues="$property_issues" + if [[ -n "$dialog_issues" ]]; then + all_issues="$all_issues"$'\n'"$dialog_issues" + fi + if [[ -n "$model_issues" ]]; then + all_issues="$all_issues"$'\n'"$model_issues" + fi + if [[ -n "$ui_issues" ]]; then + all_issues="$all_issues"$'\n'"$ui_issues" + fi + + # Remove empty lines and duplicates + all_issues=$(echo "$all_issues" | grep -v '^$' | sort -u) + + if [[ -n "$all_issues" ]]; then + echo "$file" + echo "$all_issues" | while IFS= read -r line; do + echo " $line" + done + echo + fi +} + +echo "Comprehensive i18n Checker" +echo "=========================" +echo "Scanning QML files for hardcoded strings..." +echo + +found_issues=false + +while IFS= read -r -d '' file; do + if check_file "$file" | grep -q .; then + check_file "$file" + found_issues=true + fi +done < <(find . -name "*.qml" -not -path "./Assets/*" -print0) + +if [[ "$found_issues" == false ]]; then + echo "No hardcoded strings found! All strings appear to be internationalized." +else + echo "Note: Review each match manually - some may be false positives" + echo "(property names, IDs, technical values, comments shouldn't be translated)" +fi diff --git a/Bin/i18n-check.sh b/Bin/i18n-check.sh index 96f5cc45..553370d6 100755 --- a/Bin/i18n-check.sh +++ b/Bin/i18n-check.sh @@ -1,62 +1,27 @@ #!/bin/bash -# Noctalia Shell i18n Checker -# Scans for hardcoded strings that need internationalization +# Comprehensive i18n checker for QML files +# Finds hardcoded strings in various QML properties -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' - -echo -e "${BLUE}Noctalia Shell i18n Checker${NC}" -echo -e "${BLUE}===========================${NC}" - -files_with_issues=0 - -# Check a single file -check_file() { - local file="$1" - local issues=$(grep -n -E '(label|text|title|description|tooltip|placeholder):\s*"[^"]{3,}"' "$file" | grep -v 'I18n.tr') +find . -name "*.qml" -type f | while read -r file; do + # Skip if file doesn't exist or is not readable + [[ ! -r "$file" ]] && continue - if [[ -n "$issues" ]]; then - echo -e "${YELLOW}$file${NC}" - echo "$issues" | sed 's/^/ /' - echo "" - return 1 + # Check for hardcoded strings in common properties + # Matches: property: "text with letters" but excludes I18n.tr calls + issues=$(grep -n -E '(label|text|title|description|placeholder|tooltipText|tooltip):\s*"[^"]*[a-zA-Z][^"]*"' "$file" | grep -v 'I18n\.tr') + + # Also check for template literals with hardcoded text + template_issues=$(grep -n -E '(label|text|title|description|placeholder|tooltipText|tooltip):\s*`[^`]*[a-zA-Z][^`]*`' "$file" | grep -v 'I18n\.tr') + + # Check for property assignments with hardcoded strings + property_issues=$(grep -n -E 'property\s+string\s+\w+:\s*"[^"]*[a-zA-Z][^"]*"' "$file" | grep -v 'I18n\.tr') + + if [[ -n "$issues" || -n "$template_issues" || -n "$property_issues" ]]; then + echo "$file" + [[ -n "$issues" ]] && echo "$issues" + [[ -n "$template_issues" ]] && echo "$template_issues" + [[ -n "$property_issues" ]] && echo "$property_issues" + echo fi - return 0 -} - -echo "Scanning QML files..." -echo "" - -# Find and check QML files -qml_files=$(find . -name "*.qml" -type f \ - ! -path "./Assets/*" \ - ! -path "./Bin/*" \ - ! -path "./Shaders/*" \ - ! -path "./Helpers/*" \ - ! -path "./.git/*") - -total_files=$(echo "$qml_files" | wc -l) - -for file in $qml_files; do - if ! check_file "$file"; then - ((files_with_issues++)) - fi -done - -# Summary -echo -e "${BLUE}Summary${NC}" -echo -e "${BLUE}=======${NC}" -echo -e "Files scanned: $total_files" -echo -e "Files needing i18n: $files_with_issues" - -if [[ $files_with_issues -eq 0 ]]; then - echo -e "${GREEN}All files use I18n.tr() properly!${NC}" -else - echo -e "${YELLOW}$files_with_issues files have potential hardcoded strings${NC}" -fi \ No newline at end of file +done \ No newline at end of file diff --git a/Modules/Bar/WiFi/WiFiPanel.qml b/Modules/Bar/WiFi/WiFiPanel.qml index 0590c795..ebb8a0b7 100644 --- a/Modules/Bar/WiFi/WiFiPanel.qml +++ b/Modules/Bar/WiFi/WiFiPanel.qml @@ -263,7 +263,9 @@ NPanel { spacing: Style.marginXS * scaling NText { - text: `${modelData.signal}%` + text: I18n.tr("system.signal-strength", { + "signal": modelData.signal + }) font.pointSize: Style.fontSizeXXS * scaling color: Color.mOnSurfaceVariant } diff --git a/Modules/Bar/Widgets/KeyboardLayout.qml b/Modules/Bar/Widgets/KeyboardLayout.qml index 38f27d82..ec83b71e 100644 --- a/Modules/Bar/Widgets/KeyboardLayout.qml +++ b/Modules/Bar/Widgets/KeyboardLayout.qml @@ -48,7 +48,9 @@ Item { icon: "keyboard" autoHide: false // Important to be false so we can hover as long as we want text: currentLayout.toUpperCase() - tooltipText: `${currentLayout.toUpperCase()} keyboard layout` + tooltipText: I18n.tr("tooltips.keyboard-layout", { + "layout": currentLayout.toUpperCase() + }) forceOpen: root.displayMode === "forceOpen" forceClose: root.displayMode === "alwaysHide" onClicked: { diff --git a/Modules/Bar/Widgets/Microphone.qml b/Modules/Bar/Widgets/Microphone.qml index 71b756d6..548670c4 100644 --- a/Modules/Bar/Widgets/Microphone.qml +++ b/Modules/Bar/Widgets/Microphone.qml @@ -97,7 +97,9 @@ Item { suffix: "%" forceOpen: displayMode === "alwaysShow" forceClose: displayMode === "alwaysHide" - tooltipText: I18n.tr("tooltips.microphone-volume-at", {"volume": Math.round(AudioService.inputVolume * 100)}) + tooltipText: I18n.tr("tooltips.microphone-volume-at", { + "volume": Math.round(AudioService.inputVolume * 100) + }) onWheel: function (delta) { wheelAccumulator += delta diff --git a/Modules/Bar/Widgets/PowerProfile.qml b/Modules/Bar/Widgets/PowerProfile.qml index adc09e8e..691c72ca 100644 --- a/Modules/Bar/Widgets/PowerProfile.qml +++ b/Modules/Bar/Widgets/PowerProfile.qml @@ -16,7 +16,9 @@ NIconButton { visible: PowerProfileService.available icon: PowerProfileService.getIcon() - tooltipText: `'${PowerProfileService.getName()}' power profile` + tooltipText: I18n.tr("tooltips.power-profile", { + "profile": PowerProfileService.getName() + }) compact: (Settings.data.bar.density === "compact") colorBg: (PowerProfileService.profile === PowerProfile.Balanced) ? (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent) : Color.mPrimary colorFg: (PowerProfileService.profile === PowerProfile.Balanced) ? Color.mOnSurface : Color.mOnPrimary diff --git a/Modules/Bar/Widgets/SystemMonitor.qml b/Modules/Bar/Widgets/SystemMonitor.qml index 9bd1d1fb..2c14b242 100644 --- a/Modules/Bar/Widgets/SystemMonitor.qml +++ b/Modules/Bar/Widgets/SystemMonitor.qml @@ -120,7 +120,9 @@ Rectangle { columnSpacing: Style.marginXXS * scaling NText { - text: `${SystemStatService.cpuTemp}°C` + text: I18n.tr("system.cpu-temperature", { + "temp": SystemStatService.cpuTemp + }) font.family: Settings.data.ui.fontFixed font.pointSize: textSize font.weight: Style.fontWeightMedium @@ -283,7 +285,9 @@ Rectangle { columnSpacing: isVertical ? (Style.marginXXS * scaling) : (Style.marginXS * scaling) NText { - text: `${SystemStatService.diskPercent}%` + text: I18n.tr("system.disk-usage", { + "percent": SystemStatService.diskPercent + }) font.family: Settings.data.ui.fontFixed font.pointSize: textSize font.weight: Style.fontWeightMedium diff --git a/Modules/Bar/Widgets/Volume.qml b/Modules/Bar/Widgets/Volume.qml index 0d65b4b2..c58233e5 100644 --- a/Modules/Bar/Widgets/Volume.qml +++ b/Modules/Bar/Widgets/Volume.qml @@ -83,7 +83,9 @@ Item { suffix: "%" forceOpen: displayMode === "alwaysShow" forceClose: displayMode === "alwaysHide" - tooltipText: I18n.tr("tooltips.volume-at", {"volume": Math.round(AudioService.volume * 100)}) + tooltipText: I18n.tr("tooltips.volume-at", { + "volume": Math.round(AudioService.volume * 100) + }) onWheel: function (delta) { wheelAccumulator += delta diff --git a/Modules/ControlCenter/Cards/MediaCard.qml b/Modules/ControlCenter/Cards/MediaCard.qml index bed4ce83..032eb106 100644 --- a/Modules/ControlCenter/Cards/MediaCard.qml +++ b/Modules/ControlCenter/Cards/MediaCard.qml @@ -34,7 +34,7 @@ NBox { } // NText { - // text: "No media player detected" + // text: I18n.tr("system.no-media-player-detected") // color: Color.mOnSurfaceVariant // Layout.alignment: Qt.AlignHCenter // } diff --git a/Modules/ControlCenter/Cards/PowerProfilesCard.qml b/Modules/ControlCenter/Cards/PowerProfilesCard.qml index 09cfe286..d93b26ba 100644 --- a/Modules/ControlCenter/Cards/PowerProfilesCard.qml +++ b/Modules/ControlCenter/Cards/PowerProfilesCard.qml @@ -26,7 +26,9 @@ NBox { // Performance NIconButton { icon: PowerProfileService.getIcon(PowerProfile.Performance) - tooltipText: I18n.tr("tooltips.set-power-profile", {"profile": PowerProfileService.getName(PowerProfile.Performance)}) + tooltipText: I18n.tr("tooltips.set-power-profile", { + "profile": PowerProfileService.getName(PowerProfile.Performance) + }) enabled: hasPP opacity: enabled ? Style.opacityFull : Style.opacityMedium colorBg: (enabled && PowerProfileService.profile === PowerProfile.Performance) ? Color.mPrimary : Color.mSurfaceVariant @@ -36,7 +38,9 @@ NBox { // Balanced NIconButton { icon: PowerProfileService.getIcon(PowerProfile.Balanced) - tooltipText: I18n.tr("tooltips.set-power-profile", {"profile": PowerProfileService.getName(PowerProfile.Balanced)}) + tooltipText: I18n.tr("tooltips.set-power-profile", { + "profile": PowerProfileService.getName(PowerProfile.Balanced) + }) enabled: hasPP opacity: enabled ? Style.opacityFull : Style.opacityMedium colorBg: (enabled && PowerProfileService.profile === PowerProfile.Balanced) ? Color.mPrimary : Color.mSurfaceVariant @@ -46,7 +50,9 @@ NBox { // Eco NIconButton { icon: PowerProfileService.getIcon(PowerProfile.PowerSaver) - tooltipText: I18n.tr("tooltips.set-power-profile", {"profile": PowerProfileService.getName(PowerProfile.PowerSaver)}) + tooltipText: I18n.tr("tooltips.set-power-profile", { + "profile": PowerProfileService.getName(PowerProfile.PowerSaver) + }) enabled: hasPP opacity: enabled ? Style.opacityFull : Style.opacityMedium colorBg: (enabled && PowerProfileService.profile === PowerProfile.PowerSaver) ? Color.mPrimary : Color.mSurfaceVariant diff --git a/Modules/ControlCenter/Cards/ProfileCard.qml b/Modules/ControlCenter/Cards/ProfileCard.qml index 1d3e35d0..effd69fc 100644 --- a/Modules/ControlCenter/Cards/ProfileCard.qml +++ b/Modules/ControlCenter/Cards/ProfileCard.qml @@ -42,7 +42,9 @@ NBox { font.capitalization: Font.Capitalize } NText { - text: `System uptime: ${uptimeText}` + text: I18n.tr("system.uptime", { + "uptime": uptimeText + }) font.pointSize: Style.fontSizeS * scaling color: Color.mOnSurfaceVariant } diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 89611629..a1b0622c 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -455,7 +455,9 @@ Loader { font.family: Settings.data.ui.fontFixed font.pointSize: Style.fontSizeL * scaling property int currentIndex: 0 - property string fullText: "Welcome back, " + Quickshell.env("USER") + "!" + property string fullText: I18n.tr("system.welcome-back", { + "user": Quickshell.env("USER") + }) Timer { interval: Style.animationFast diff --git a/Modules/Notification/Notification.qml b/Modules/Notification/Notification.qml index 12405c96..4cf82f73 100644 --- a/Modules/Notification/Notification.qml +++ b/Modules/Notification/Notification.qml @@ -282,7 +282,7 @@ Variants { } NText { - text: `${model.appName || "Unknown App"} · ${Time.formatRelativeTime(model.timestamp)}` + text: `${model.appName || I18n.tr("system.unknown-app")} · ${Time.formatRelativeTime(model.timestamp)}` color: Color.mSecondary font.pointSize: Style.fontSizeXS * scaling } diff --git a/Modules/Settings/Bar/BarWidgetSettingsDialog.qml b/Modules/Settings/Bar/BarWidgetSettingsDialog.qml index 72981f85..09165a07 100644 --- a/Modules/Settings/Bar/BarWidgetSettingsDialog.qml +++ b/Modules/Settings/Bar/BarWidgetSettingsDialog.qml @@ -63,7 +63,9 @@ Popup { Layout.fillWidth: true NText { - text: `${widgetSettings.widgetId} Settings` + text: I18n.tr("system.widget-settings-title", { + "widget": widgetSettings.widgetId + }) font.pointSize: Style.fontSizeL * scaling font.weight: Style.fontWeightBold color: Color.mPrimary diff --git a/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml b/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml index acb14169..addf7ff8 100644 --- a/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml @@ -28,20 +28,16 @@ ColumnLayout { label: I18n.tr("bar.widget-settings.battery.display-mode.label") description: I18n.tr("bar.widget-settings.battery.display-mode.description") minimumWidth: 134 * scaling - model: [ - { - key: "onhover", - name: I18n.tr("options.display-mode.on-hover") - }, - { - key: "alwaysShow", - name: I18n.tr("options.display-mode.always-show") - }, - { - key: "alwaysHide", - name: I18n.tr("options.display-mode.always-hide") - } - ] + model: [{ + "key": "onhover", + "name": I18n.tr("options.display-mode.on-hover") + }, { + "key": "alwaysShow", + "name": I18n.tr("options.display-mode.always-show") + }, { + "key": "alwaysHide", + "name": I18n.tr("options.display-mode.always-hide") + }] currentKey: root.valueDisplayMode onSelected: key => root.valueDisplayMode = key } diff --git a/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml b/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml index 9d5070e3..c21d7aae 100644 --- a/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml @@ -26,20 +26,16 @@ ColumnLayout { label: I18n.tr("bar.widget-settings.brightness.display-mode.label") description: I18n.tr("bar.widget-settings.brightness.display-mode.description") minimumWidth: 134 * scaling - model: [ - { - key: "onhover", - name: I18n.tr("options.display-mode.on-hover") - }, - { - key: "alwaysShow", - name: I18n.tr("options.display-mode.always-show") - }, - { - key: "alwaysHide", - name: I18n.tr("options.display-mode.always-hide") - } - ] + model: [{ + "key": "onhover", + "name": I18n.tr("options.display-mode.on-hover") + }, { + "key": "alwaysShow", + "name": I18n.tr("options.display-mode.always-show") + }, { + "key": "alwaysHide", + "name": I18n.tr("options.display-mode.always-hide") + }] currentKey: valueDisplayMode onSelected: key => valueDisplayMode = key } diff --git a/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml b/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml index 9350e9b7..d3551044 100644 --- a/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml @@ -26,20 +26,16 @@ ColumnLayout { label: I18n.tr("bar.widget-settings.keyboard-layout.display-mode.label") description: I18n.tr("bar.widget-settings.keyboard-layout.display-mode.description") minimumWidth: 134 * scaling - model: [ - { - key: "onhover", - name: I18n.tr("options.display-mode.on-hover") - }, - { - key: "forceOpen", - name: I18n.tr("options.display-mode.force-open") - }, - { - key: "alwaysHide", - name: I18n.tr("options.display-mode.always-hide") - } - ] + model: [{ + "key": "onhover", + "name": I18n.tr("options.display-mode.on-hover") + }, { + "key": "forceOpen", + "name": I18n.tr("options.display-mode.force-open") + }, { + "key": "alwaysHide", + "name": I18n.tr("options.display-mode.always-hide") + }] currentKey: valueDisplayMode onSelected: key => valueDisplayMode = key } diff --git a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml index daeaf5a6..b357fa12 100644 --- a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml @@ -41,20 +41,16 @@ ColumnLayout { NComboBox { visible: valueShowVisualizer label: I18n.tr("bar.widget-settings.media-mini.visualizer-type") - model: [ - { - key: "linear", - name: I18n.tr("options.visualizer-types.linear") - }, - { - key: "mirrored", - name: I18n.tr("options.visualizer-types.mirrored") - }, - { - key: "wave", - name: I18n.tr("options.visualizer-types.wave") - } - ] + model: [{ + "key": "linear", + "name": I18n.tr("options.visualizer-types.linear") + }, { + "key": "mirrored", + "name": I18n.tr("options.visualizer-types.mirrored") + }, { + "key": "wave", + "name": I18n.tr("options.visualizer-types.wave") + }] currentKey: valueVisualizerType onSelected: key => valueVisualizerType = key minimumWidth: 200 * scaling diff --git a/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml b/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml index d7071022..5091474d 100644 --- a/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml @@ -26,20 +26,16 @@ ColumnLayout { label: I18n.tr("bar.widget-settings.microphone.display-mode.label") description: I18n.tr("bar.widget-settings.microphone.display-mode.description") minimumWidth: 134 * scaling - model: [ - { - key: "onhover", - name: I18n.tr("options.display-mode.on-hover") - }, - { - key: "alwaysShow", - name: I18n.tr("options.display-mode.always-show") - }, - { - key: "alwaysHide", - name: I18n.tr("options.display-mode.always-hide") - } - ] + model: [{ + "key": "onhover", + "name": I18n.tr("options.display-mode.on-hover") + }, { + "key": "alwaysShow", + "name": I18n.tr("options.display-mode.always-show") + }, { + "key": "alwaysHide", + "name": I18n.tr("options.display-mode.always-hide") + }] currentKey: valueDisplayMode onSelected: key => valueDisplayMode = key } diff --git a/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml b/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml index 987bedbb..2781f4a6 100644 --- a/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml @@ -26,20 +26,16 @@ ColumnLayout { label: I18n.tr("bar.widget-settings.volume.display-mode.label") description: I18n.tr("bar.widget-settings.volume.display-mode.description") minimumWidth: 134 * scaling - model: [ - { - key: "onhover", - name: I18n.tr("options.display-mode.on-hover") - }, - { - key: "alwaysShow", - name: I18n.tr("options.display-mode.always-show") - }, - { - key: "alwaysHide", - name: I18n.tr("options.display-mode.always-hide") - } - ] + model: [{ + "key": "onhover", + "name": I18n.tr("options.display-mode.on-hover") + }, { + "key": "alwaysShow", + "name": I18n.tr("options.display-mode.always-show") + }, { + "key": "alwaysHide", + "name": I18n.tr("options.display-mode.always-hide") + }] currentKey: valueDisplayMode onSelected: key => valueDisplayMode = key } diff --git a/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml b/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml index 3c8ce794..27c4b057 100644 --- a/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml +++ b/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml @@ -24,20 +24,16 @@ ColumnLayout { id: labelModeCombo label: I18n.tr("bar.widget-settings.workspace.label-mode") - model: [ - { - key: "none", - name: I18n.tr("options.workspace-labels.none") - }, - { - key: "index", - name: I18n.tr("options.workspace-labels.index") - }, - { - key: "name", - name: I18n.tr("options.workspace-labels.name") - } - ] + model: [{ + "key": "none", + "name": I18n.tr("options.workspace-labels.none") + }, { + "key": "index", + "name": I18n.tr("options.workspace-labels.index") + }, { + "key": "name", + "name": I18n.tr("options.workspace-labels.name") + }] currentKey: widgetData.labelMode || widgetMetadata.labelMode onSelected: key => labelModeCombo.currentKey = key minimumWidth: 200 * scaling diff --git a/Modules/Settings/Tabs/AudioTab.qml b/Modules/Settings/Tabs/AudioTab.qml index bd02fbd2..5fcdca24 100644 --- a/Modules/Settings/Tabs/AudioTab.qml +++ b/Modules/Settings/Tabs/AudioTab.qml @@ -326,24 +326,19 @@ ColumnLayout { id: audioVisualizerCombo label: I18n.tr("settings.audio.media.visualizer-type.label") description: I18n.tr("settings.audio.media.visualizer-type.description") - model: [ - { - key: "none", - name: I18n.tr("options.visualizer-types.none") - }, - { - key: "linear", - name: I18n.tr("options.visualizer-types.linear") - }, - { - key: "mirrored", - name: I18n.tr("options.visualizer-types.mirrored") - }, - { - key: "wave", - name: I18n.tr("options.visualizer-types.wave") - } - ] + model: [{ + "key": "none", + "name": I18n.tr("options.visualizer-types.none") + }, { + "key": "linear", + "name": I18n.tr("options.visualizer-types.linear") + }, { + "key": "mirrored", + "name": I18n.tr("options.visualizer-types.mirrored") + }, { + "key": "wave", + "name": I18n.tr("options.visualizer-types.wave") + }] currentKey: Settings.data.audio.visualizerType onSelected: key => Settings.data.audio.visualizerType = key } @@ -351,36 +346,28 @@ ColumnLayout { NComboBox { label: I18n.tr("settings.audio.media.frame-rate.label") description: I18n.tr("settings.audio.media.frame-rate.description") - model: [ - { - key: "30", - name: I18n.tr("options.frame-rates.30-fps") - }, - { - key: "60", - name: I18n.tr("options.frame-rates.60-fps") - }, - { - key: "100", - name: I18n.tr("options.frame-rates.100-fps") - }, - { - key: "120", - name: I18n.tr("options.frame-rates.120-fps") - }, - { - key: "144", - name: I18n.tr("options.frame-rates.144-fps") - }, - { - key: "165", - name: I18n.tr("options.frame-rates.165-fps") - }, - { - key: "240", - name: I18n.tr("options.frame-rates.240-fps") - } - ] + model: [{ + "key": "30", + "name": I18n.tr("options.frame-rates.30-fps") + }, { + "key": "60", + "name": I18n.tr("options.frame-rates.60-fps") + }, { + "key": "100", + "name": I18n.tr("options.frame-rates.100-fps") + }, { + "key": "120", + "name": I18n.tr("options.frame-rates.120-fps") + }, { + "key": "144", + "name": I18n.tr("options.frame-rates.144-fps") + }, { + "key": "165", + "name": I18n.tr("options.frame-rates.165-fps") + }, { + "key": "240", + "name": I18n.tr("options.frame-rates.240-fps") + }] currentKey: Settings.data.audio.cavaFrameRate onSelected: key => Settings.data.audio.cavaFrameRate = key } diff --git a/Modules/Settings/Tabs/BarTab.qml b/Modules/Settings/Tabs/BarTab.qml index 4743edab..17407631 100644 --- a/Modules/Settings/Tabs/BarTab.qml +++ b/Modules/Settings/Tabs/BarTab.qml @@ -277,7 +277,11 @@ ColumnLayout { delegate: NCheckbox { Layout.fillWidth: true label: modelData.name || "Unknown" - description: `${modelData.model} (${modelData.width}x${modelData.height})` + description: I18n.tr("system.monitor-description", { + "model": modelData.model, + "width": modelData.width, + "height": modelData.height + }) checked: (Settings.data.bar.monitors || []).indexOf(modelData.name) !== -1 onToggled: checked => { if (checked) { diff --git a/Modules/Settings/Tabs/DisplayTab.qml b/Modules/Settings/Tabs/DisplayTab.qml index a8a24e66..2146f825 100644 --- a/Modules/Settings/Tabs/DisplayTab.qml +++ b/Modules/Settings/Tabs/DisplayTab.qml @@ -90,7 +90,11 @@ ColumnLayout { NLabel { label: modelData.name || "Unknown" - description: `${modelData.model} (${modelData.width}x${modelData.height})` + description: I18n.tr("system.monitor-description", { + "model": modelData.model, + "width": modelData.width, + "height": modelData.height + }) } // Scale @@ -114,7 +118,9 @@ ColumnLayout { stepSize: 0.01 value: localScaling onPressedChanged: (pressed, value) => ScalingService.setScreenScale(modelData, value) - text: `${Math.round(localScaling * 100)}%` + text: I18n.tr("system.scaling-percentage", { + "percentage": Math.round(localScaling * 100) + }) Layout.fillWidth: true } diff --git a/Modules/Settings/Tabs/DockTab.qml b/Modules/Settings/Tabs/DockTab.qml index edb8679a..c3b1d559 100644 --- a/Modules/Settings/Tabs/DockTab.qml +++ b/Modules/Settings/Tabs/DockTab.qml @@ -101,7 +101,11 @@ ColumnLayout { delegate: NCheckbox { Layout.fillWidth: true label: modelData.name || "Unknown" - description: `${modelData.model} (${modelData.width}x${modelData.height})` + description: I18n.tr("system.monitor-description", { + "model": modelData.model, + "width": modelData.width, + "height": modelData.height + }) checked: (Settings.data.dock.monitors || []).indexOf(modelData.name) !== -1 onToggled: checked => { if (checked) { diff --git a/Modules/Settings/Tabs/LocationTab.qml b/Modules/Settings/Tabs/LocationTab.qml index 2e286dc4..eafa3902 100644 --- a/Modules/Settings/Tabs/LocationTab.qml +++ b/Modules/Settings/Tabs/LocationTab.qml @@ -42,7 +42,10 @@ ColumnLayout { NText { visible: LocationService.coordinatesReady - text: `${LocationService.stableName} (${LocationService.displayCoordinates})` + text: I18n.tr("system.location-display", { + "name": LocationService.stableName, + "coordinates": LocationService.displayCoordinates + }) font.pointSize: Style.fontSizeS * scaling color: Color.mOnSurfaceVariant verticalAlignment: Text.AlignVCenter diff --git a/Modules/Settings/Tabs/NotificationsTab.qml b/Modules/Settings/Tabs/NotificationsTab.qml index fab5d0d6..85a2375e 100644 --- a/Modules/Settings/Tabs/NotificationsTab.qml +++ b/Modules/Settings/Tabs/NotificationsTab.qml @@ -151,7 +151,11 @@ ColumnLayout { delegate: NCheckbox { Layout.fillWidth: true label: modelData.name || "Unknown" - description: `${modelData.model} (${modelData.width}x${modelData.height})` + description: I18n.tr("system.monitor-description", { + "model": modelData.model, + "width": modelData.width, + "height": modelData.height + }) checked: (Settings.data.notifications.monitors || []).indexOf(modelData.name) !== -1 onToggled: checked => { if (checked) { diff --git a/Modules/Settings/Tabs/ScreenRecorderTab.qml b/Modules/Settings/Tabs/ScreenRecorderTab.qml index 3d464439..d3f77e67 100644 --- a/Modules/Settings/Tabs/ScreenRecorderTab.qml +++ b/Modules/Settings/Tabs/ScreenRecorderTab.qml @@ -61,16 +61,13 @@ ColumnLayout { NComboBox { label: I18n.tr("settings.screen-recorder.video.video-source.label") description: I18n.tr("settings.screen-recorder.video.video-source.description") - model: [ - { - key: "portal", - name: I18n.tr("options.screen-recording.sources.portal") - }, - { - key: "screen", - name: I18n.tr("options.screen-recording.sources.screen") - } - ] + model: [{ + "key": "portal", + "name": I18n.tr("options.screen-recording.sources.portal") + }, { + "key": "screen", + "name": I18n.tr("options.screen-recording.sources.screen") + }] currentKey: Settings.data.screenRecorder.videoSource onSelected: key => Settings.data.screenRecorder.videoSource = key } diff --git a/Services/GitHubService.qml b/Services/GitHubService.qml index 1c5583fc..93982df9 100644 --- a/Services/GitHubService.qml +++ b/Services/GitHubService.qml @@ -16,7 +16,7 @@ Singleton { readonly property alias data: adapter // Used to access via GitHubService.data.xxx.yyy // Public properties for easy access - property string latestVersion: "Unknown" + property string latestVersion: I18n.tr("system.unknown-version") property var contributors: [] FileView { @@ -43,7 +43,7 @@ Singleton { JsonAdapter { id: adapter - property string version: "Unknown" + property string version: I18n.tr("system.unknown-version") property var contributors: [] property real timestamp: 0 } @@ -97,7 +97,7 @@ Singleton { // -------------------------------- function resetCache() { - data.version = "Unknown" + data.version = I18n.tr("system.unknown-version") data.contributors = [] data.timestamp = 0 diff --git a/Services/IdleInhibitorService.qml b/Services/IdleInhibitorService.qml index 3f5e3c4c..c804226e 100644 --- a/Services/IdleInhibitorService.qml +++ b/Services/IdleInhibitorService.qml @@ -10,7 +10,7 @@ Singleton { id: root property bool isInhibited: false - property string reason: "User requested" + property string reason: I18n.tr("system.user-requested") property var activeInhibitors: [] // Different inhibitor strategies diff --git a/Services/KeyboardLayoutService.qml b/Services/KeyboardLayoutService.qml index fc500e2a..3006d121 100644 --- a/Services/KeyboardLayoutService.qml +++ b/Services/KeyboardLayoutService.qml @@ -9,7 +9,7 @@ import qs.Services Singleton { id: root - property string currentLayout: "Unknown" + property string currentLayout: I18n.tr("system.unknown-layout") property int updateInterval: 1000 // Update every second // Timer to periodically update the layout diff --git a/Widgets/NFilePicker.qml b/Widgets/NFilePicker.qml index f5fb2336..608fde9f 100644 --- a/Widgets/NFilePicker.qml +++ b/Widgets/NFilePicker.qml @@ -15,8 +15,8 @@ Item { property string pickerType: "file" // "file" or "folder" property var nameFilters: ["All files (*)"] // e.g., ["Image files (*.png *.jpg)", "Text files (*.txt)"] property string title: pickerType === "folder" ? "Select Folder" : "Select File" - property string acceptLabel: "Select" - property string rejectLabel: "Cancel" + property string acceptLabel: I18n.tr("placeholders.select") + property string rejectLabel: I18n.tr("placeholders.cancel") // State properties property bool isOpen: false diff --git a/Widgets/NInputAction.qml b/Widgets/NInputAction.qml index abe03961..d689d304 100644 --- a/Widgets/NInputAction.qml +++ b/Widgets/NInputAction.qml @@ -13,7 +13,7 @@ RowLayout { property string description: "" property string placeholderText: "" property string text: "" - property string actionButtonText: "Test" + property string actionButtonText: I18n.tr("placeholders.test") property string actionButtonIcon: "media-play" property bool actionButtonEnabled: text !== "" diff --git a/Widgets/NSearchableComboBox.qml b/Widgets/NSearchableComboBox.qml index 27fb2a0d..be3f5e75 100644 --- a/Widgets/NSearchableComboBox.qml +++ b/Widgets/NSearchableComboBox.qml @@ -19,7 +19,7 @@ RowLayout { } property string currentKey: "" property string placeholder: "" - property string searchPlaceholder: "Search..." + property string searchPlaceholder: I18n.tr("placeholders.search") readonly property real preferredHeight: Style.baseWidgetSize * 1.1 * scaling