@@ -411,7 +411,7 @@ def __init__(self, workspace_dir: Optional[str] = None):
411411 self ._load_language_preference ()
412412 self ._load_theme_preference ()
413413
414- self .setWindowTitle (" BCASL Standalone - Before Compilation Actions System Loader" )
414+ self .setWindowTitle (self . language_manager . get ( "app_title" , " BCASL Standalone" ) )
415415 self .setGeometry (100 , 100 , 1100 , 800 )
416416 self .setMinimumSize (900 , 650 )
417417
@@ -423,32 +423,32 @@ def __init__(self, workspace_dir: Optional[str] = None):
423423 layout .setSpacing (10 )
424424
425425 # Workspace selection group
426- ws_group = QGroupBox (" Workspace Configuration" )
427- ws_layout = QHBoxLayout (ws_group )
428- ws_label = QLabel (" Workspace:" )
429- ws_label .setMinimumWidth (80 )
430- self .ws_display = QLabel (workspace_dir or " No workspace selected" )
431- self .ws_display .setToolTip (" Currently selected workspace directory" )
432- ws_btn = QPushButton (" Browse..." )
433- ws_btn .setMaximumWidth (100 )
434- ws_btn .clicked .connect (self ._select_workspace )
435- ws_layout .addWidget (ws_label )
426+ self . ws_group = QGroupBox (self . language_manager . get ( "workspace_config" , " Workspace Configuration") )
427+ ws_layout = QHBoxLayout (self . ws_group )
428+ self . ws_label = QLabel (self . language_manager . get ( "workspace_label" , " Workspace:") )
429+ self . ws_label .setMinimumWidth (80 )
430+ self .ws_display = QLabel (workspace_dir or self . language_manager . get ( "no_workspace" , " No workspace selected") )
431+ self .ws_display .setToolTip (self . language_manager . get ( "config_summary" , " Currently selected workspace directory") )
432+ self . ws_browse_btn = QPushButton (self . language_manager . get ( "browse_button" , " Browse...") )
433+ self . ws_browse_btn .setMaximumWidth (100 )
434+ self . ws_browse_btn .clicked .connect (self ._select_workspace )
435+ ws_layout .addWidget (self . ws_label )
436436 ws_layout .addWidget (self .ws_display )
437437 ws_layout .addStretch ()
438- ws_layout .addWidget (ws_btn )
439- layout .addWidget (ws_group )
438+ ws_layout .addWidget (self . ws_browse_btn )
439+ layout .addWidget (self . ws_group )
440440
441441 # Config info
442- self .config_info = QLabel (" No configuration loaded" )
443- self .config_info .setToolTip (" Configuration summary: enabled plugins, file patterns, etc." )
442+ self .config_info = QLabel (self . language_manager . get ( "no_config" , " No configuration loaded") )
443+ self .config_info .setToolTip (self . language_manager . get ( "config_summary" , " Configuration summary: enabled plugins, file patterns, etc.") )
444444 layout .addWidget (self .config_info )
445445
446446 # Log output
447- log_label = QLabel (" Execution Log:" )
447+ self . log_label = QLabel (self . language_manager . get ( "execution_log" , " Execution Log:") )
448448 log_label_font = QFont ()
449449 log_label_font .setBold (True )
450- log_label .setFont (log_label_font )
451- layout .addWidget (log_label )
450+ self . log_label .setFont (log_label_font )
451+ layout .addWidget (self . log_label )
452452 self .log = QTextEdit ()
453453 self .log .setReadOnly (True )
454454 self .log .setMinimumHeight (280 )
@@ -462,47 +462,60 @@ def __init__(self, workspace_dir: Optional[str] = None):
462462
463463 # Options and theme
464464 options_layout = QHBoxLayout ()
465- self .chk_async = QCheckBox (" Run asynchronously" )
465+ self .chk_async = QCheckBox (self . language_manager . get ( "run_async" , " Run asynchronously") )
466466 self .chk_async .setChecked (True )
467- self .chk_async .setToolTip (" Execute BCASL in background thread for better responsiveness" )
467+ self .chk_async .setToolTip (self . language_manager . get ( "run_async_tooltip" , " Execute BCASL in background thread for better responsiveness") )
468468 options_layout .addWidget (self .chk_async )
469469
470470 # Language selector
471- lang_label = QLabel (" Language:" )
471+ self . lang_label = QLabel (self . language_manager . get ( "language_label" , " Language:") )
472472 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 )
473+
474+ # Store code -> display name mapping
475+ self ._lang_codes = self .language_manager .get_language_names ()
476+ self ._lang_display_names = [
477+ self .language_manager .languages [code ]['native_name' ]
478+ for code in self ._lang_codes
479+ ]
480+
481+ # Add display names to combo
482+ self .lang_combo .addItems (self ._lang_display_names )
483+
484+ # Set current language by display name
485+ current_index = self ._lang_codes .index (self .language_manager .current_language )
486+ self .lang_combo .setCurrentIndex (current_index )
487+
488+ self .lang_combo .currentIndexChanged .connect (self ._on_language_changed )
489+ self .lang_combo .setMaximumWidth (150 )
477490
478491 # Theme selector
479- theme_label = QLabel (" Theme:" )
492+ self . theme_label = QLabel (self . language_manager . get ( "theme_label" , " Theme:") )
480493 self .theme_combo = QComboBox ()
481494 self .theme_combo .addItems (list (self .theme_manager .THEMES .keys ()))
482495 self .theme_combo .setCurrentText (self .theme_manager .current_theme )
483496 self .theme_combo .currentTextChanged .connect (self ._on_theme_changed )
484497 self .theme_combo .setMaximumWidth (120 )
485498
486499 options_layout .addStretch ()
487- options_layout .addWidget (lang_label )
500+ options_layout .addWidget (self . lang_label )
488501 options_layout .addWidget (self .lang_combo )
489- options_layout .addWidget (theme_label )
502+ options_layout .addWidget (self . theme_label )
490503 options_layout .addWidget (self .theme_combo )
491504 layout .addLayout (options_layout )
492505
493506 # Buttons
494507 btn_layout = QHBoxLayout ()
495- self .btn_config = QPushButton (" ⚙️ Configure Plugins" )
496- self .btn_config .setToolTip (" Open plugin configuration dialog" )
508+ self .btn_config = QPushButton (self . language_manager . get ( "configure_plugins" , " ⚙️ Configure Plugins") )
509+ self .btn_config .setToolTip (self . language_manager . get ( "configure_plugins_tooltip" , " Open plugin configuration dialog") )
497510 self .btn_config .clicked .connect (self ._open_config_dialog )
498- self .btn_run = QPushButton (" ▶️ Run BCASL" )
499- self .btn_run .setToolTip (" Execute BCASL pre-compilation actions" )
511+ self .btn_run = QPushButton (self . language_manager . get ( "run_bcasl" , " ▶️ Run BCASL") )
512+ self .btn_run .setToolTip (self . language_manager . get ( "run_bcasl_tooltip" , " Execute BCASL pre-compilation actions") )
500513 self .btn_run .clicked .connect (self ._run_bcasl )
501- self .btn_clear = QPushButton (" 🗑️ Clear Log" )
502- self .btn_clear .setToolTip (" Clear the execution log" )
514+ self .btn_clear = QPushButton (self . language_manager . get ( "clear_log" , " 🗑️ Clear Log") )
515+ self .btn_clear .setToolTip (self . language_manager . get ( "clear_log_tooltip" , " Clear the execution log") )
503516 self .btn_clear .clicked .connect (self .log .clear )
504- self .btn_exit = QPushButton (" Exit" )
505- self .btn_exit .setToolTip (" Close the application" )
517+ self .btn_exit = QPushButton (self . language_manager . get ( "exit_button" , " Exit") )
518+ self .btn_exit .setToolTip (self . language_manager . get ( "exit_tooltip" , " Close the application") )
506519 self .btn_exit .clicked .connect (self .close )
507520
508521 btn_layout .addWidget (self .btn_config )
@@ -513,7 +526,7 @@ def __init__(self, workspace_dir: Optional[str] = None):
513526 layout .addLayout (btn_layout )
514527
515528 # Status bar
516- self .statusBar ().showMessage (" Ready" )
529+ self .statusBar ().showMessage (self . language_manager . get ( "ready" , " Ready") )
517530
518531 # Apply theme
519532 self ._apply_theme ()
@@ -566,12 +579,21 @@ def _save_theme_preference(self):
566579 except Exception :
567580 pass
568581
569- def _on_language_changed (self , lang_code : str ):
582+ def _on_language_changed (self , index : int ):
570583 """Handle language change."""
584+ if index < 0 or index >= len (self ._lang_codes ):
585+ return
586+
587+ lang_code = self ._lang_codes [index ]
571588 if self .language_manager .set_language (lang_code ):
572589 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
590+ self ._update_ui_texts ()
591+
592+ # Update language combo display names after language change
593+ self ._lang_display_names = [
594+ self .language_manager .languages [code ]['native_name' ]
595+ for code in self ._lang_codes
596+ ]
575597
576598 def _on_theme_changed (self , theme_name : str ):
577599 """Handle theme change."""
@@ -583,24 +605,59 @@ def _apply_theme(self):
583605 """Apply current theme to the application."""
584606 stylesheet = self .theme_manager .get_stylesheet ()
585607 self .setStyleSheet (stylesheet )
608+
609+ def _update_ui_texts (self ):
610+ """Update all UI text elements with current language."""
611+ self .setWindowTitle (self .language_manager .get ("app_title" , "BCASL Standalone" ))
612+ self .ws_group .setTitle (self .language_manager .get ("workspace_config" , "Workspace Configuration" ))
613+ self .ws_label .setText (self .language_manager .get ("workspace_label" , "Workspace:" ))
614+ if not self .workspace_dir :
615+ self .ws_display .setText (self .language_manager .get ("no_workspace" , "No workspace selected" ))
616+ self .ws_display .setToolTip (self .language_manager .get ("config_summary" , "Currently selected workspace directory" ))
617+
618+ if self .config_info .text () == "No configuration loaded" or self .config_info .text ().startswith ("Aucune configuration" ):
619+ self .config_info .setText (self .language_manager .get ("no_config" , "No configuration loaded" ))
620+ self .config_info .setToolTip (self .language_manager .get ("config_summary" , "Configuration summary: enabled plugins, file patterns, etc." ))
621+
622+ self .log_label .setText (self .language_manager .get ("execution_log" , "Execution Log:" ))
623+ self .chk_async .setText (self .language_manager .get ("run_async" , "Run asynchronously" ))
624+ self .chk_async .setToolTip (self .language_manager .get ("run_async_tooltip" , "Execute BCASL in background thread for better responsiveness" ))
625+
626+ self .ws_browse_btn .setText (self .language_manager .get ("browse_button" , "Browse..." ))
627+ self .lang_label .setText (self .language_manager .get ("language_label" , "Language:" ))
628+ self .theme_label .setText (self .language_manager .get ("theme_label" , "Theme:" ))
629+
630+ self .btn_config .setText (self .language_manager .get ("configure_plugins" , "⚙️ Configure Plugins" ))
631+ self .btn_config .setToolTip (self .language_manager .get ("configure_plugins_tooltip" , "Open plugin configuration dialog" ))
632+ self .btn_run .setText (self .language_manager .get ("run_bcasl" , "▶️ Run BCASL" ))
633+ self .btn_run .setToolTip (self .language_manager .get ("run_bcasl_tooltip" , "Execute BCASL pre-compilation actions" ))
634+ self .btn_clear .setText (self .language_manager .get ("clear_log" , "🗑️ Clear Log" ))
635+ self .btn_clear .setToolTip (self .language_manager .get ("clear_log_tooltip" , "Clear the execution log" ))
636+ self .btn_exit .setText (self .language_manager .get ("exit_button" , "Exit" ))
637+ self .btn_exit .setToolTip (self .language_manager .get ("exit_tooltip" , "Close the application" ))
638+
639+ # Update status bar if showing "Ready"
640+ status_text = self .statusBar ().currentMessage ()
641+ if status_text in ["Ready" , "Prêt" ]:
642+ self .statusBar ().showMessage (self .language_manager .get ("ready" , "Ready" ))
586643
587644 def _select_workspace (self ):
588645 """Select workspace directory."""
589646 folder = QFileDialog .getExistingDirectory (
590647 self ,
591- " Select Workspace Directory" ,
648+ self . language_manager . get ( "select_workspace" , " Select Workspace Directory") ,
592649 self .workspace_dir or os .path .expanduser ("~" ),
593650 )
594651 if folder :
595652 self .workspace_dir = folder
596653 self .ws_display .setText (folder )
597654 self ._load_config_info ()
598- self .log .append (f"✅ Workspace selected: { folder } \n " )
655+ self .log .append (self . language_manager . format ( "workspace_selected" , path = folder ) + " \n " )
599656
600657 def _load_config_info (self ):
601658 """Load and display configuration info."""
602659 if not self .workspace_dir :
603- self .config_info .setText (" No workspace selected" )
660+ self .config_info .setText (self . language_manager . get ( "no_workspace" , " No workspace selected") )
604661 return
605662
606663 try :
@@ -617,44 +674,48 @@ def _load_config_info(self):
617674 exclude_patterns = cfg .get ("exclude_patterns" , [])
618675
619676 info = (
620- f"Plugins: { enabled_count } / { total_count } enabled | "
621- f"File patterns: { len (file_patterns )} | "
622- f"Exclude patterns: { len (exclude_patterns )} "
677+ f"{ self . language_manager . format ( 'plugins_enabled' , enabled = enabled_count , total = total_count ) } | "
678+ f"{ self . language_manager . format ( 'file_patterns' , count = len (file_patterns ) )} | "
679+ f"{ self . language_manager . format ( 'exclude_patterns' , count = len (exclude_patterns ) )} "
623680 )
624681 self .config_info .setText (info )
625682 except Exception as e :
626- self .config_info .setText (f"Error loading config: { e } " )
683+ self .config_info .setText (self . language_manager . format ( "error_loading_config" , error = str ( e )) )
627684
628685 def _open_config_dialog (self ):
629686 """Open plugin configuration dialog."""
630687 if not self .workspace_dir :
631688 QMessageBox .warning (
632689 self ,
633- " Warning" ,
634- " Please select a workspace first." ,
690+ self . language_manager . get ( "warning" , " Warning") ,
691+ self . language_manager . get ( "select_workspace_first" , " Please select a workspace first.") ,
635692 )
636693 return
637694 try :
638695 open_bc_loader_dialog (self )
639696 self ._load_config_info ()
640697 except Exception as e :
641- QMessageBox .critical (self , "Error" , f"Failed to open config dialog: { e } " )
698+ QMessageBox .critical (
699+ self ,
700+ self .language_manager .get ("error" , "Error" ),
701+ self .language_manager .format ("config_dialog_error" , error = str (e ))
702+ )
642703
643704 def _run_bcasl (self ):
644705 """Run BCASL."""
645706 if not self .workspace_dir :
646707 QMessageBox .warning (
647708 self ,
648- " Warning" ,
649- " Please select a workspace first." ,
709+ self . language_manager . get ( "warning" , " Warning") ,
710+ self . language_manager . get ( "select_workspace_first" , " Please select a workspace first.") ,
650711 )
651712 return
652713
653714 if self ._is_running :
654715 QMessageBox .information (
655716 self ,
656717 "Information" ,
657- " BCASL is already running. Please wait for it to complete." ,
718+ self . language_manager . get ( "bcasl_running" , " BCASL is already running. Please wait for it to complete.") ,
658719 )
659720 return
660721
@@ -663,9 +724,9 @@ def _run_bcasl(self):
663724 self .btn_config .setEnabled (False )
664725 self .progress .setVisible (True )
665726 self .progress .setMaximum (0 ) # Indeterminate progress
666- self .statusBar ().showMessage (" Running BCASL..." )
727+ self .statusBar ().showMessage (self . language_manager . get ( "running" , " Running BCASL...") )
667728 self .log .append ("\n " + "=" * 60 )
668- self .log .append (" Starting BCASL execution..." )
729+ self .log .append (self . language_manager . get ( "starting_execution" , " Starting BCASL execution...") )
669730 self .log .append ("=" * 60 + "\n " )
670731
671732 def on_done (report ):
@@ -676,25 +737,29 @@ def on_done(report):
676737 self .progress .setVisible (False )
677738
678739 if report is None :
679- self .log .append ("\n ❌ BCASL execution failed or was cancelled.\n " )
680- self .statusBar ().showMessage (" Failed" )
740+ self .log .append ("\n " + self . language_manager . get ( "execution_failed" , " ❌ BCASL execution failed or was cancelled." ) + " \n " )
741+ self .statusBar ().showMessage (self . language_manager . get ( "failed" , " Failed") )
681742 else :
682743 try :
683744 self .log .append ("\n " + "=" * 60 )
684- self .log .append (" BCASL Execution Report:" )
745+ self .log .append (self . language_manager . get ( "execution_report" , " BCASL Execution Report:") )
685746 self .log .append ("=" * 60 + "\n " )
686747 for item in report :
687- status = "✅ OK" if item .success else f"❌ FAIL: { item .error } "
748+ if item .success :
749+ status = self .language_manager .get ("plugin_ok" , "✅ OK" )
750+ else :
751+ status = self .language_manager .format ("plugin_fail" , error = item .error )
688752 self .log .append (
689753 f" { item .plugin_id } : { status } ({ item .duration_ms :.1f} ms)\n "
690754 )
691755 self .log .append ("\n " + report .summary () + "\n " )
692756 self .statusBar ().showMessage (
693- "Completed" if report .ok else "Completed with errors"
757+ self .language_manager .get ("completed" , "Completed" ) if report .ok
758+ else self .language_manager .get ("completed_errors" , "Completed with errors" )
694759 )
695760 except Exception as e :
696- self .log .append (f "\n ⚠️ Error displaying report: { e } \n " )
697- self .statusBar ().showMessage (" Completed" )
761+ self .log .append ("\n " + self . language_manager . format ( "error_displaying_report" , error = str ( e )) + " \n " )
762+ self .statusBar ().showMessage (self . language_manager . get ( "completed" , " Completed") )
698763
699764 try :
700765 if self .chk_async .isChecked ():
@@ -703,12 +768,12 @@ def on_done(report):
703768 report = run_pre_compile (self )
704769 on_done (report )
705770 except Exception as e :
706- self .log .append (f "\n ❌ Error: { e } \n " )
771+ self .log .append ("\n " + self . language_manager . format ( "error_running_bcasl" , error = str ( e )) + " \n " )
707772 self ._is_running = False
708773 self .btn_run .setEnabled (True )
709774 self .btn_config .setEnabled (True )
710775 self .progress .setVisible (False )
711- self .statusBar ().showMessage (" Error" )
776+ self .statusBar ().showMessage (self . language_manager . get ( "error" , " Error") )
712777
713778 def closeEvent (self , event ):
714779 """Handle window close."""
0 commit comments