1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-14 17:52:10 -04:00

fix(i18n): capture missing strings and add pt-BR translations (#1654)

This commit is contained in:
Bernardo Gomes
2026-02-12 17:05:44 -03:00
committed by GitHub
parent 425715e0f0
commit 7c66a34931
4 changed files with 132 additions and 84 deletions

View File

@@ -6773,6 +6773,12 @@
"reference": "Modules/Settings/DesktopWidgetBrowser.qml:459", "reference": "Modules/Settings/DesktopWidgetBrowser.qml:459",
"comment": "" "comment": ""
}, },
{
"term": "No widgets added. Click \"Add Widget\" to get started.",
"context": "No widgets added. Click \"Add Widget\" to get started.",
"reference": "Modules/Settings/DesktopWidgetsTab.qml:603",
"comment": ""
},
{ {
"term": "No widgets match your search", "term": "No widgets match your search",
"context": "No widgets match your search", "context": "No widgets match your search",

View File

@@ -1,44 +1,74 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import ast
import re import re
import json import json
from pathlib import Path from pathlib import Path
from collections import defaultdict from collections import defaultdict
def decode_string_literal(content, quote):
try:
return ast.literal_eval(f"{quote}{content}{quote}")
except (ValueError, SyntaxError):
return content
def spans_overlap(a, b):
return a[0] < b[1] and b[0] < a[1]
def extract_qstr_strings(root_dir): def extract_qstr_strings(root_dir):
translations = defaultdict(lambda: {'contexts': set(), 'occurrences': []}) translations = defaultdict(lambda: {'contexts': set(), 'occurrences': []})
qstr_pattern_double = re.compile(r'qsTr\("([^"]+)"\)') qstr_patterns = [
qstr_pattern_single = re.compile(r"qsTr\('([^']+)'\)") (re.compile(r'qsTr\(\s*"((?:\\.|[^"\\])*)"\s*\)'), '"'),
i18n_pattern_with_context_double = re.compile(r'I18n\.tr\("([^"]+)"\s*,\s*"([^"]+)"\)') (re.compile(r"qsTr\(\s*'((?:\\.|[^'\\])*)'\s*\)"), "'")
i18n_pattern_with_context_single = re.compile(r"I18n\.tr\('([^']+)'\s*,\s*'([^']+)'\)") ]
i18n_pattern_simple_double = re.compile(r'I18n\.tr\("([^"]+)"\)') i18n_context_patterns = [
i18n_pattern_simple_single = re.compile(r"I18n\.tr\('([^']+)'\)") (
re.compile(r'I18n\.tr\(\s*"((?:\\.|[^"\\])*)"\s*,\s*"((?:\\.|[^"\\])*)"\s*\)'),
'"'
),
(
re.compile(r"I18n\.tr\(\s*'((?:\\.|[^'\\])*)'\s*,\s*'((?:\\.|[^'\\])*)'\s*\)"),
"'"
)
]
i18n_simple_patterns = [
(re.compile(r'I18n\.tr\(\s*"((?:\\.|[^"\\])*)"\s*\)'), '"'),
(re.compile(r"I18n\.tr\(\s*'((?:\\.|[^'\\])*)'\s*\)"), "'")
]
for qml_file in Path(root_dir).rglob('*.qml'): for qml_file in Path(root_dir).rglob('*.qml'):
relative_path = qml_file.relative_to(root_dir) relative_path = qml_file.relative_to(root_dir)
with open(qml_file, 'r', encoding='utf-8') as f: with open(qml_file, 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1): for line_num, line in enumerate(f, 1):
qstr_matches = qstr_pattern_double.findall(line) + qstr_pattern_single.findall(line) for pattern, quote in qstr_patterns:
for match in qstr_matches: for match in pattern.finditer(line):
translations[match]['occurrences'].append({ term = decode_string_literal(match.group(1), quote)
'file': str(relative_path), translations[term]['occurrences'].append({
'line': line_num 'file': str(relative_path),
}) 'line': line_num
})
i18n_with_context = i18n_pattern_with_context_double.findall(line) + i18n_pattern_with_context_single.findall(line) context_spans = []
for term, context in i18n_with_context: for pattern, quote in i18n_context_patterns:
translations[term]['contexts'].add(context) for match in pattern.finditer(line):
translations[term]['occurrences'].append({ term = decode_string_literal(match.group(1), quote)
'file': str(relative_path), context = decode_string_literal(match.group(2), quote)
'line': line_num translations[term]['contexts'].add(context)
}) translations[term]['occurrences'].append({
'file': str(relative_path),
'line': line_num
})
context_spans.append(match.span())
has_context = i18n_pattern_with_context_double.search(line) or i18n_pattern_with_context_single.search(line) for pattern, quote in i18n_simple_patterns:
if not has_context: for match in pattern.finditer(line):
i18n_simple = i18n_pattern_simple_double.findall(line) + i18n_pattern_simple_single.findall(line) if any(spans_overlap(match.span(), span) for span in context_spans):
for match in i18n_simple: continue
translations[match]['occurrences'].append({ term = decode_string_literal(match.group(1), quote)
translations[term]['occurrences'].append({
'file': str(relative_path), 'file': str(relative_path),
'line': line_num 'line': line_num
}) })

View File

@@ -3231,6 +3231,9 @@
"No variants created. Click Add to create a new monitor widget.": { "No variants created. Click Add to create a new monitor widget.": {
"No variants created. Click Add to create a new monitor widget.": "Nenhuma variante criada. Clique Adicionar para criar um novo widget de monitor." "No variants created. Click Add to create a new monitor widget.": "Nenhuma variante criada. Clique Adicionar para criar um novo widget de monitor."
}, },
"No widgets added. Click \"Add Widget\" to get started.": {
"No widgets added. Click \"Add Widget\" to get started.": "Nenhum widget adicionado. Clique em \"Adicionar widget\" para começar."
},
"No widgets available": { "No widgets available": {
"No widgets available": "" "No widgets available": ""
}, },
@@ -3521,7 +3524,7 @@
"Make sure KDE Connect or Valent is running on your other devices": "" "Make sure KDE Connect or Valent is running on your other devices": ""
}, },
"Phone Connect no devices status | bluetooth status": { "Phone Connect no devices status | bluetooth status": {
"No devices": "" "No devices": "Nenhum dispositivo"
}, },
"Phone Connect pairing action": { "Phone Connect pairing action": {
"Device paired": "", "Device paired": "",
@@ -5297,7 +5300,7 @@
"Charging": "", "Charging": "",
"Discharging": "", "Discharging": "",
"Empty": "", "Empty": "",
"Fully Charged": "", "Fully Charged": "Totalmente carregada",
"No Battery": "", "No Battery": "",
"Pending Charge": "", "Pending Charge": "",
"Pending Discharge": "", "Pending Discharge": "",
@@ -5306,13 +5309,15 @@
"bluetooth status": { "bluetooth status": {
"Bluetooth": "", "Bluetooth": "",
"Connected Device": "", "Connected Device": "",
"Enabled": "", "Disabled": "Desativado",
"Enabled": "Ativado",
"No adapter": "", "No adapter": "",
"No adapters": "", "No adapters": "",
"No devices": "Nenhum dispositivo",
"Off": "" "Off": ""
}, },
"bluetooth status | lock screen notification mode option": { "bluetooth status | lock screen notification mode option": {
"Disabled": "" "Disabled": "Desativado"
}, },
"border color": { "border color": {
"Color": "" "Color": ""
@@ -5364,16 +5369,16 @@
"Select Wallpaper": "Selecionar Papel de Parede" "Select Wallpaper": "Selecionar Papel de Parede"
}, },
"date format option": { "date format option": {
"Custom...": "", "Custom...": "Personalizado...",
"Day Date": "", "Day Date": "Dia e data",
"Day Month Date": "", "Day Month Date": "Dia, mês e data",
"Full Day & Month": "", "Full Day & Month": "Dia completo e mês",
"Full with Year": "", "Full with Year": "Completo com ano",
"ISO Date": "", "ISO Date": "Data ISO",
"Month Date": "", "Month Date": "Mês e data",
"Numeric (D/M)": "", "Numeric (D/M)": "Numérico (D/M)",
"Numeric (M/D)": "", "Numeric (M/D)": "Numérico (M/D)",
"System Default": "" "System Default": "Padrão do sistema"
}, },
"days": { "days": {
"days": "dias" "days": "dias"
@@ -5406,8 +5411,8 @@
"dms/outputs config exists but is not included in your compositor config. Display changes won't persist.": "" "dms/outputs config exists but is not included in your compositor config. Display changes won't persist.": ""
}, },
"dock indicator style option": { "dock indicator style option": {
"Circle": "", "Circle": "Círculo",
"Line": "" "Line": "Linha"
}, },
"dock position option": { "dock position option": {
"Bottom": "", "Bottom": "",
@@ -5662,15 +5667,15 @@
"loginctl not available - lock integration requires DMS socket connection": "loginctl não disponível - integração com bloqueio requer conexão de socket DMS" "loginctl not available - lock integration requires DMS socket connection": "loginctl não disponível - integração com bloqueio requer conexão de socket DMS"
}, },
"matugen color scheme option": { "matugen color scheme option": {
"Content": "", "Content": "Conteúdo",
"Expressive": "", "Expressive": "Expressivo",
"Fidelity": "", "Fidelity": "Fidelidade",
"Fruit Salad": "", "Fruit Salad": "Salada de frutas",
"Monochrome": "", "Monochrome": "Monocromático",
"Neutral": "", "Neutral": "Neutro",
"Rainbow": "", "Rainbow": "Arco-íris",
"Tonal Spot": "", "Tonal Spot": "Ponto tonal",
"Vibrant": "" "Vibrant": "Vibrante"
}, },
"matugen error": { "matugen error": {
"matugen not found - install matugen package for dynamic theming": "" "matugen not found - install matugen package for dynamic theming": ""
@@ -5682,9 +5687,9 @@
"Matugen Missing": "" "Matugen Missing": ""
}, },
"media scroll wheel option": { "media scroll wheel option": {
"Change Song": "", "Change Song": "Trocar música",
"Change Volume": "", "Change Volume": "Alterar volume",
"Nothing": "" "Nothing": "Nada"
}, },
"minutes": { "minutes": {
"minutes": "minutos" "minutes": "minutos"
@@ -5792,9 +5797,9 @@
"Prioritize performance": "" "Prioritize performance": ""
}, },
"power profile option": { "power profile option": {
"Balanced": "", "Balanced": "Equilibrado",
"Performance": "", "Performance": "Desempenho",
"Power Saver": "" "Power Saver": "Economia de energia"
}, },
"primary color": { "primary color": {
"Primary": "" "Primary": ""
@@ -5818,14 +5823,14 @@
"Color theme from DMS registry": "" "Color theme from DMS registry": ""
}, },
"screen position option": { "screen position option": {
"Bottom Center": "", "Bottom Center": "Inferior central",
"Bottom Left": "", "Bottom Left": "Inferior esquerdo",
"Bottom Right": "", "Bottom Right": "Inferior direito",
"Left Center": "", "Left Center": "Centro esquerdo",
"Right Center": "", "Right Center": "Centro direito",
"Top Center": "", "Top Center": "Superior central",
"Top Left": "", "Top Left": "Superior esquerdo",
"Top Right": "" "Top Right": "Superior direito"
}, },
"secondary color": { "secondary color": {
"Secondary": "" "Secondary": ""
@@ -5872,10 +5877,10 @@
"Install color themes from the DMS theme registry": "" "Install color themes from the DMS theme registry": ""
}, },
"theme category option": { "theme category option": {
"Auto": "", "Auto": "Automático",
"Browse": "", "Browse": "Navegar",
"Custom": "", "Custom": "Personalizado",
"Generic": "" "Generic": "Genérico"
}, },
"theme installation confirmation": { "theme installation confirmation": {
"Install theme '%1' from the DMS registry?": "" "Install theme '%1' from the DMS registry?": ""
@@ -5924,13 +5929,13 @@
"Wallpaper Error": "" "Wallpaper Error": ""
}, },
"wallpaper fill mode": { "wallpaper fill mode": {
"Fill": "", "Fill": "Preencher",
"Fit": "", "Fit": "Ajustar",
"Pad": "", "Pad": "Centralizar",
"Stretch": "", "Stretch": "Esticar",
"Tile": "", "Tile": "Lado a lado",
"Tile H": "", "Tile H": "Lado a lado (H)",
"Tile V": "" "Tile V": "Lado a lado (V)"
}, },
"wallpaper processing error": { "wallpaper processing error": {
"Wallpaper processing failed": "" "Wallpaper processing failed": ""
@@ -5945,15 +5950,15 @@
"External Wallpaper Management": "Gerenciamento Externo de Papéis de Parede" "External Wallpaper Management": "Gerenciamento Externo de Papéis de Parede"
}, },
"wallpaper transition option": { "wallpaper transition option": {
"Disc": "", "Disc": "Disco",
"Fade": "", "Fade": "Desvanecer",
"Iris Bloom": "", "Iris Bloom": "Íris em expansão",
"None": "", "None": "Nenhum",
"Pixelate": "", "Pixelate": "Pixelizar",
"Portal": "", "Portal": "Portal",
"Random": "", "Random": "Aleatório",
"Stripes": "", "Stripes": "Listras",
"Wipe": "" "Wipe": "Deslizar"
}, },
"weather feels like temperature": { "weather feels like temperature": {
"Feels Like %1°": "" "Feels Like %1°": ""

View File

@@ -7902,6 +7902,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "No widgets added. Click \"Add Widget\" to get started.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "No widgets match your search", "term": "No widgets match your search",
"translation": "", "translation": "",