Skip to content

Commit 2662029

Browse files
committed
ajout dun system de langue
1 parent 11bd7a3 commit 2662029

6 files changed

Lines changed: 440 additions & 3 deletions

File tree

bcasl/only_mod/app.py

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,106 @@
6666
logger = logging.getLogger(__name__)
6767

6868

69+
class LanguageManager:
70+
"""Manages application languages loaded from JSON files."""
71+
72+
def __init__(self):
73+
self.languages = {}
74+
self.current_language = "en"
75+
self.strings = {}
76+
self._load_languages()
77+
78+
def _load_languages(self):
79+
"""Load languages from JSON files in languages directory."""
80+
languages_dir = Path(__file__).parent / "languages"
81+
82+
if not languages_dir.exists():
83+
logger.warning(f"Languages directory not found: {languages_dir}")
84+
self._load_default_language()
85+
return
86+
87+
try:
88+
for lang_file in sorted(languages_dir.glob("*.json")):
89+
try:
90+
with open(lang_file, 'r', encoding='utf-8') as f:
91+
lang_data = json.load(f)
92+
lang_code = lang_data.get('code', lang_file.stem)
93+
self.languages[lang_code] = {
94+
'name': lang_data.get('name', lang_code),
95+
'native_name': lang_data.get('native_name', lang_code),
96+
'strings': lang_data.get('strings', {})
97+
}
98+
except Exception as e:
99+
logger.error(f"Failed to load language from {lang_file}: {e}")
100+
except Exception as e:
101+
logger.error(f"Error loading languages: {e}")
102+
self._load_default_language()
103+
104+
if self.languages:
105+
self.current_language = list(self.languages.keys())[0]
106+
self.strings = self.languages[self.current_language]['strings'].copy()
107+
else:
108+
self._load_default_language()
109+
110+
def _load_default_language(self):
111+
"""Load default English language as fallback."""
112+
self.languages = {
113+
"en": {
114+
"name": "English",
115+
"native_name": "English",
116+
"strings": {
117+
"app_title": "BCASL Standalone - Before Compilation Actions System Loader",
118+
"workspace_config": "Workspace Configuration",
119+
"workspace_label": "Workspace:",
120+
"no_workspace": "No workspace selected",
121+
"browse_button": "Browse...",
122+
"config_summary": "Configuration summary",
123+
"execution_log": "Execution Log:",
124+
"run_async": "Run asynchronously",
125+
"theme_label": "Theme:",
126+
"configure_plugins": "⚙️ Configure Plugins",
127+
"run_bcasl": "▶️ Run BCASL",
128+
"clear_log": "🗑️ Clear Log",
129+
"exit_button": "Exit",
130+
"ready": "Ready",
131+
"running": "Running BCASL...",
132+
"completed": "Completed",
133+
"failed": "Failed",
134+
}
135+
}
136+
}
137+
self.current_language = "en"
138+
self.strings = self.languages["en"]["strings"].copy()
139+
140+
def set_language(self, lang_code: str) -> bool:
141+
"""Set the current language."""
142+
if lang_code not in self.languages:
143+
return False
144+
self.current_language = lang_code
145+
self.strings = self.languages[lang_code]['strings'].copy()
146+
return True
147+
148+
def get_language_names(self) -> list:
149+
"""Get list of available language codes."""
150+
return list(self.languages.keys())
151+
152+
def get_language_display_names(self) -> list:
153+
"""Get list of available language display names."""
154+
return [self.languages[code]['name'] for code in self.get_language_names()]
155+
156+
def get(self, key: str, default: str = "") -> str:
157+
"""Get translated string."""
158+
return self.strings.get(key, default)
159+
160+
def format(self, key: str, **kwargs) -> str:
161+
"""Get translated string with formatting."""
162+
template = self.strings.get(key, "")
163+
try:
164+
return template.format(**kwargs)
165+
except KeyError:
166+
return template
167+
168+
69169
class ThemeManager:
70170
"""Manages application themes loaded from JSON files."""
71171

@@ -305,8 +405,10 @@ def __init__(self, workspace_dir: Optional[str] = None):
305405
self._config_cache = None
306406
self._last_config_load_time = 0
307407

308-
# Initialize theme manager
408+
# Initialize language and theme managers
409+
self.language_manager = LanguageManager()
309410
self.theme_manager = ThemeManager()
411+
self._load_language_preference()
310412
self._load_theme_preference()
311413

312414
self.setWindowTitle("BCASL Standalone - Before Compilation Actions System Loader")
@@ -365,14 +467,25 @@ def __init__(self, workspace_dir: Optional[str] = None):
365467
self.chk_async.setToolTip("Execute BCASL in background thread for better responsiveness")
366468
options_layout.addWidget(self.chk_async)
367469

470+
# Language selector
471+
lang_label = QLabel("Language:")
472+
self.lang_combo = QComboBox()
473+
self.lang_combo.addItems(list(self.language_manager.get_language_names()))
474+
self.lang_combo.setCurrentText(self.language_manager.current_language)
475+
self.lang_combo.currentTextChanged.connect(self._on_language_changed)
476+
self.lang_combo.setMaximumWidth(100)
477+
368478
# Theme selector
369479
theme_label = QLabel("Theme:")
370480
self.theme_combo = QComboBox()
371481
self.theme_combo.addItems(list(self.theme_manager.THEMES.keys()))
372482
self.theme_combo.setCurrentText(self.theme_manager.current_theme)
373483
self.theme_combo.currentTextChanged.connect(self._on_theme_changed)
374484
self.theme_combo.setMaximumWidth(120)
485+
375486
options_layout.addStretch()
487+
options_layout.addWidget(lang_label)
488+
options_layout.addWidget(self.lang_combo)
376489
options_layout.addWidget(theme_label)
377490
options_layout.addWidget(self.theme_combo)
378491
layout.addLayout(options_layout)
@@ -409,6 +522,28 @@ def __init__(self, workspace_dir: Optional[str] = None):
409522
if workspace_dir:
410523
self._load_config_info()
411524

525+
def _load_language_preference(self):
526+
"""Load language preference from config file."""
527+
try:
528+
config_file = Path.home() / ".bcasl_language"
529+
if config_file.exists():
530+
with open(config_file, 'r') as f:
531+
data = json.load(f)
532+
lang = data.get('language', 'en')
533+
if lang in self.language_manager.get_language_names():
534+
self.language_manager.set_language(lang)
535+
except Exception:
536+
pass
537+
538+
def _save_language_preference(self):
539+
"""Save language preference to config file."""
540+
try:
541+
config_file = Path.home() / ".bcasl_language"
542+
with open(config_file, 'w') as f:
543+
json.dump({'language': self.language_manager.current_language}, f)
544+
except Exception:
545+
pass
546+
412547
def _load_theme_preference(self):
413548
"""Load theme preference from config file."""
414549
try:
@@ -431,6 +566,13 @@ def _save_theme_preference(self):
431566
except Exception:
432567
pass
433568

569+
def _on_language_changed(self, lang_code: str):
570+
"""Handle language change."""
571+
if self.language_manager.set_language(lang_code):
572+
self._save_language_preference()
573+
# Note: Full UI translation would require updating all text elements
574+
# For now, language preference is saved for next session
575+
434576
def _on_theme_changed(self, theme_name: str):
435577
"""Handle theme change."""
436578
if self.theme_manager.set_theme(theme_name):

bcasl/only_mod/languages/de.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"code": "de",
3+
"name": "Deutsch",
4+
"native_name": "Deutsch",
5+
"strings": {
6+
"app_title": "BCASL Standalone - Vor-Kompilierungs-Aktionssystem-Loader",
7+
"workspace_config": "Arbeitsbereich-Konfiguration",
8+
"workspace_label": "Arbeitsbereich:",
9+
"no_workspace": "Kein Arbeitsbereich ausgewählt",
10+
"browse_button": "Durchsuchen...",
11+
"config_summary": "Konfigurationsübersicht: aktivierte Plugins, Dateimuster, etc.",
12+
"execution_log": "Ausführungsprotokoll:",
13+
"run_async": "Asynchron ausführen",
14+
"run_async_tooltip": "BCASL in einem Hintergrund-Thread ausführen für bessere Reaktionsfähigkeit",
15+
"theme_label": "Design:",
16+
"configure_plugins": "⚙️ Plugins Konfigurieren",
17+
"configure_plugins_tooltip": "Plugin-Konfigurationsdialog öffnen",
18+
"run_bcasl": "▶️ BCASL Ausführen",
19+
"run_bcasl_tooltip": "BCASL-Vor-Kompilierungs-Aktionen ausführen",
20+
"clear_log": "🗑️ Protokoll Löschen",
21+
"clear_log_tooltip": "Ausführungsprotokoll löschen",
22+
"exit_button": "Beenden",
23+
"exit_tooltip": "Anwendung schließen",
24+
"ready": "Bereit",
25+
"running": "BCASL wird ausgeführt...",
26+
"completed": "Abgeschlossen",
27+
"completed_errors": "Mit Fehlern abgeschlossen",
28+
"failed": "Fehlgeschlagen",
29+
"error": "Fehler",
30+
"warning": "Warnung",
31+
"select_workspace": "Arbeitsbereich-Verzeichnis Auswählen",
32+
"workspace_selected": "✅ Arbeitsbereich ausgewählt: {path}",
33+
"no_config": "Keine Konfiguration geladen",
34+
"plugins_enabled": "Plugins: {enabled}/{total} aktiviert",
35+
"file_patterns": "Dateimuster: {count}",
36+
"exclude_patterns": "Ausschlussmuster: {count}",
37+
"error_loading_config": "Fehler beim Laden der Konfiguration: {error}",
38+
"select_workspace_first": "Bitte wählen Sie zuerst einen Arbeitsbereich aus.",
39+
"bcasl_running": "BCASL wird bereits ausgeführt. Bitte warten Sie auf den Abschluss.",
40+
"starting_execution": "BCASL-Ausführung wird gestartet...",
41+
"execution_report": "BCASL-Ausführungsbericht:",
42+
"plugin_ok": "✅ OK",
43+
"plugin_fail": "❌ FEHLER: {error}",
44+
"execution_failed": "❌ BCASL-Ausführung fehlgeschlagen oder abgebrochen.",
45+
"error_displaying_report": "⚠️ Fehler beim Anzeigen des Berichts: {error}",
46+
"error_running_bcasl": "❌ Fehler: {error}",
47+
"config_dialog_error": "Konfigurationsdialog konnte nicht geöffnet werden: {error}"
48+
}
49+
}

bcasl/only_mod/languages/en.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"code": "en",
3+
"name": "English",
4+
"native_name": "English",
5+
"strings": {
6+
"app_title": "BCASL Standalone - Before Compilation Actions System Loader",
7+
"workspace_config": "Workspace Configuration",
8+
"workspace_label": "Workspace:",
9+
"no_workspace": "No workspace selected",
10+
"browse_button": "Browse...",
11+
"config_summary": "Configuration summary: enabled plugins, file patterns, etc.",
12+
"execution_log": "Execution Log:",
13+
"run_async": "Run asynchronously",
14+
"run_async_tooltip": "Execute BCASL in background thread for better responsiveness",
15+
"theme_label": "Theme:",
16+
"configure_plugins": "⚙️ Configure Plugins",
17+
"configure_plugins_tooltip": "Open plugin configuration dialog",
18+
"run_bcasl": "▶️ Run BCASL",
19+
"run_bcasl_tooltip": "Execute BCASL pre-compilation actions",
20+
"clear_log": "🗑️ Clear Log",
21+
"clear_log_tooltip": "Clear the execution log",
22+
"exit_button": "Exit",
23+
"exit_tooltip": "Close the application",
24+
"ready": "Ready",
25+
"running": "Running BCASL...",
26+
"completed": "Completed",
27+
"completed_errors": "Completed with errors",
28+
"failed": "Failed",
29+
"error": "Error",
30+
"warning": "Warning",
31+
"select_workspace": "Select Workspace Directory",
32+
"workspace_selected": "✅ Workspace selected: {path}",
33+
"no_config": "No configuration loaded",
34+
"plugins_enabled": "Plugins: {enabled}/{total} enabled",
35+
"file_patterns": "File patterns: {count}",
36+
"exclude_patterns": "Exclude patterns: {count}",
37+
"error_loading_config": "Error loading config: {error}",
38+
"select_workspace_first": "Please select a workspace first.",
39+
"bcasl_running": "BCASL is already running. Please wait for it to complete.",
40+
"starting_execution": "Starting BCASL execution...",
41+
"execution_report": "BCASL Execution Report:",
42+
"plugin_ok": "✅ OK",
43+
"plugin_fail": "❌ FAIL: {error}",
44+
"execution_failed": "❌ BCASL execution failed or was cancelled.",
45+
"error_displaying_report": "⚠️ Error displaying report: {error}",
46+
"error_running_bcasl": "❌ Error: {error}",
47+
"config_dialog_error": "Failed to open config dialog: {error}"
48+
}
49+
}

bcasl/only_mod/languages/es.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"code": "es",
3+
"name": "Español",
4+
"native_name": "Español",
5+
"strings": {
6+
"app_title": "BCASL Independiente - Sistema de Carga de Acciones de Precompilación",
7+
"workspace_config": "Configuración del Espacio de Trabajo",
8+
"workspace_label": "Espacio de trabajo:",
9+
"no_workspace": "Ningún espacio de trabajo seleccionado",
10+
"browse_button": "Examinar...",
11+
"config_summary": "Resumen de configuración: complementos habilitados, patrones de archivo, etc.",
12+
"execution_log": "Registro de Ejecución:",
13+
"run_async": "Ejecutar de forma asincrónica",
14+
"run_async_tooltip": "Ejecutar BCASL en un hilo de fondo para mejor capacidad de respuesta",
15+
"theme_label": "Tema:",
16+
"configure_plugins": "⚙️ Configurar Complementos",
17+
"configure_plugins_tooltip": "Abrir el diálogo de configuración de complementos",
18+
"run_bcasl": "▶️ Ejecutar BCASL",
19+
"run_bcasl_tooltip": "Ejecutar acciones de precompilación BCASL",
20+
"clear_log": "🗑️ Borrar Registro",
21+
"clear_log_tooltip": "Borrar el registro de ejecución",
22+
"exit_button": "Salir",
23+
"exit_tooltip": "Cerrar la aplicación",
24+
"ready": "Listo",
25+
"running": "Ejecutando BCASL...",
26+
"completed": "Completado",
27+
"completed_errors": "Completado con errores",
28+
"failed": "Falló",
29+
"error": "Error",
30+
"warning": "Advertencia",
31+
"select_workspace": "Seleccionar Directorio del Espacio de Trabajo",
32+
"workspace_selected": "✅ Espacio de trabajo seleccionado: {path}",
33+
"no_config": "Ninguna configuración cargada",
34+
"plugins_enabled": "Complementos: {enabled}/{total} habilitados",
35+
"file_patterns": "Patrones de archivo: {count}",
36+
"exclude_patterns": "Patrones de exclusión: {count}",
37+
"error_loading_config": "Error al cargar la configuración: {error}",
38+
"select_workspace_first": "Por favor, seleccione primero un espacio de trabajo.",
39+
"bcasl_running": "BCASL ya se está ejecutando. Por favor, espere a que se complete.",
40+
"starting_execution": "Iniciando ejecución de BCASL...",
41+
"execution_report": "Informe de Ejecución BCASL:",
42+
"plugin_ok": "✅ OK",
43+
"plugin_fail": "❌ FALLO: {error}",
44+
"execution_failed": "❌ La ejecución de BCASL falló o fue cancelada.",
45+
"error_displaying_report": "⚠️ Error al mostrar el informe: {error}",
46+
"error_running_bcasl": "❌ Error: {error}",
47+
"config_dialog_error": "No se pudo abrir el diálogo de configuración: {error}"
48+
}
49+
}

bcasl/only_mod/languages/fr.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"code": "fr",
3+
"name": "Français",
4+
"native_name": "Français",
5+
"strings": {
6+
"app_title": "BCASL Autonome - Système de Chargement des Actions de Pré-Compilation",
7+
"workspace_config": "Configuration de l'Espace de Travail",
8+
"workspace_label": "Espace de travail:",
9+
"no_workspace": "Aucun espace de travail sélectionné",
10+
"browse_button": "Parcourir...",
11+
"config_summary": "Résumé de la configuration: plugins activés, motifs de fichiers, etc.",
12+
"execution_log": "Journal d'Exécution:",
13+
"run_async": "Exécuter de manière asynchrone",
14+
"run_async_tooltip": "Exécuter BCASL dans un thread d'arrière-plan pour une meilleure réactivité",
15+
"theme_label": "Thème:",
16+
"configure_plugins": "⚙️ Configurer les Plugins",
17+
"configure_plugins_tooltip": "Ouvrir la boîte de dialogue de configuration des plugins",
18+
"run_bcasl": "▶️ Exécuter BCASL",
19+
"run_bcasl_tooltip": "Exécuter les actions de pré-compilation BCASL",
20+
"clear_log": "🗑️ Effacer le Journal",
21+
"clear_log_tooltip": "Effacer le journal d'exécution",
22+
"exit_button": "Quitter",
23+
"exit_tooltip": "Fermer l'application",
24+
"ready": "Prêt",
25+
"running": "Exécution de BCASL...",
26+
"completed": "Terminé",
27+
"completed_errors": "Terminé avec des erreurs",
28+
"failed": "Échoué",
29+
"error": "Erreur",
30+
"warning": "Avertissement",
31+
"select_workspace": "Sélectionner le Répertoire de l'Espace de Travail",
32+
"workspace_selected": "✅ Espace de travail sélectionné: {path}",
33+
"no_config": "Aucune configuration chargée",
34+
"plugins_enabled": "Plugins: {enabled}/{total} activés",
35+
"file_patterns": "Motifs de fichiers: {count}",
36+
"exclude_patterns": "Motifs d'exclusion: {count}",
37+
"error_loading_config": "Erreur lors du chargement de la configuration: {error}",
38+
"select_workspace_first": "Veuillez d'abord sélectionner un espace de travail.",
39+
"bcasl_running": "BCASL est déjà en cours d'exécution. Veuillez attendre qu'il se termine.",
40+
"starting_execution": "Démarrage de l'exécution de BCASL...",
41+
"execution_report": "Rapport d'Exécution BCASL:",
42+
"plugin_ok": "✅ OK",
43+
"plugin_fail": "❌ ÉCHEC: {error}",
44+
"execution_failed": "❌ L'exécution de BCASL a échoué ou a été annulée.",
45+
"error_displaying_report": "⚠️ Erreur lors de l'affichage du rapport: {error}",
46+
"error_running_bcasl": "❌ Erreur: {error}",
47+
"config_dialog_error": "Impossible d'ouvrir la boîte de dialogue de configuration: {error}"
48+
}
49+
}

0 commit comments

Comments
 (0)