1414# limitations under the License.
1515
1616"""
17- BcaslOnlyMod GUI - Interface Graphique pour les Plugins BCASL
17+ BcaslOnlyMod GUI for BCASL plugins.
1818
19- Interface complète pour exécuter et configurer les plugins BCASL
20- indépendamment de l'application principale PyCompiler ARK.
21-
22- Fournit une interface utilisateur moderne permettant de:
23- - Découvrir et lister les plugins BCASL disponibles
24- - Activer/désactiver les plugins
25- - Réordonner l'exécution des plugins
26- - Exécuter les plugins de pré-compilation
27- - Afficher les rapports d'exécution
19+ This module exposes a standalone interface to discover, configure, and run
20+ BCASL plugins outside of the main PyCompiler ARK application.
2821"""
2922
3023from __future__ import annotations
8477
8578
8679def tr (en_text : str , fr_text : str ) -> str :
87- """Fonction de traduction simple pour BcaslOnlyMod.
80+ """Simple translation helper for BcaslOnlyMod.
8881
89- Utilise la variable globale _CURRENT_LANGUAGE pour déterminer la langue .
82+ The global ` _CURRENT_LANGUAGE` controls the selected language .
9083 """
9184 return fr_text if _CURRENT_LANGUAGE == "fr" else en_text
9285
@@ -96,7 +89,7 @@ def tr(en_text: str, fr_text: str) -> str:
9689
9790
9891class BcaslExecutionThread (QThread ):
99- """Thread pour exécuter les plugins BCASL sans bloquer l'UI ."""
92+ """Run BCASL plugins in a background thread to keep UI responsive ."""
10093
10194 progress = Signal (int , int ) # current, total
10295 log_message = Signal (str )
@@ -123,7 +116,7 @@ def __init__(
123116 self .venv_path = venv_path
124117
125118 def run (self ):
126- """Exécute les plugins BCASL dans un thread séparé ."""
119+ """Execute BCASL plugins in a dedicated worker thread ."""
127120 try :
128121 # Log du venv utilisé
129122 if self .venv_path :
@@ -183,14 +176,9 @@ def run(self):
183176
184177class BcaslStandaloneGui (QMainWindow ):
185178 """
186- Interface graphique principale pour gérer les plugins BCASL.
187-
188- Cette classe fournit une interface utilisateur complète pour:
189- - Lister les plugins BCASL disponibles avec leurs métadonnées
190- - Activer/désactiver les plugins individuellement
191- - Réordonner l'exécution des plugins
192- - Exécuter les plugins de pré-compilation
193- - Afficher les rapports d'exécution détaillés
179+ Main standalone window used to manage BCASL plugins.
180+
181+ It supports plugin discovery, activation, ordering, and execution reports.
194182 """
195183
196184 def __init__ (
@@ -200,12 +188,12 @@ def __init__(
200188 theme : str = "dark" ,
201189 ):
202190 """
203- Initialise l'interface Bcasl Standalone GUI.
191+ Initialize the Bcasl standalone GUI.
204192
205193 Args:
206- workspace_dir: Chemin du workspace (optionnel)
207- language: Code de langue ('en' ou 'fr')
208- theme: Nom du thème (' light' ou ' dark')
194+ workspace_dir: Optional workspace path.
195+ language: UI language code (`en` or `fr`).
196+ theme: Theme name (` light` or ` dark`).
209197 """
210198 super ().__init__ ()
211199
@@ -246,7 +234,7 @@ def __init__(
246234 self ._center_window ()
247235
248236 def _load_config (self ):
249- """Charge la configuration BCASL du workspace."""
237+ """Load BCASL configuration from the current workspace."""
250238 from bcasl .Loader import _load_workspace_config
251239
252240 self .config : Dict [str , Any ] = {}
@@ -274,7 +262,7 @@ def _load_config(self):
274262 self ._log (f"⚠️ Impossible d'initialiser le gestionnaire de venv: { e } " )
275263
276264 def _detect_venv (self ):
277- """Détecte automatiquement le meilleur venv disponible ."""
265+ """Auto-detect the best virtual environment for the workspace ."""
278266 if not self .venv_manager or not self .workspace_dir :
279267 return
280268
@@ -289,7 +277,7 @@ def _detect_venv(self):
289277 self ._log (f"⚠️ Erreur détection venv: { e } " )
290278
291279 def _setup_ui (self ):
292- """Configure l'interface utilisateur ."""
280+ """Build and wire the standalone BCASL interface ."""
293281 # Widget central
294282 central_widget = QWidget ()
295283 self .setCentralWidget (central_widget )
@@ -663,7 +651,7 @@ def _setup_ui(self):
663651 main_splitter .setSizes ([500 , 200 ])
664652
665653 def _center_window (self ):
666- """Centre la fenêtre sur l'écran ."""
654+ """Center the window on the primary screen ."""
667655 try :
668656 screen_geometry = QApplication .primaryScreen ().geometry ()
669657 x = (screen_geometry .width () - self .width ()) // 2
@@ -673,7 +661,7 @@ def _center_window(self):
673661 pass
674662
675663 def _select_workspace (self ):
676- """Ouvre une boîte de dialogue pour sélectionner le workspace."""
664+ """Open a dialog to select a workspace directory ."""
677665 current_path = self .workspace_dir or ""
678666
679667 folder = QFileDialog .getExistingDirectory (
@@ -700,7 +688,7 @@ def _select_workspace(self):
700688 self .statusBar .showMessage (tr ("Workspace updated" , "Workspace mis à jour" ))
701689
702690 def _clear_workspace (self ):
703- """Efface la sélection du workspace ."""
691+ """Clear workspace selection and refresh plugin data ."""
704692 self .workspace_dir = None
705693 self .workspace_path_edit .clear ()
706694 self .workspace_path_edit .setPlaceholderText (
@@ -716,7 +704,7 @@ def _clear_workspace(self):
716704 self .statusBar .showMessage (tr ("Workspace cleared" , "Workspace effacé" ))
717705
718706 def _select_venv (self ):
719- """Ouvre une boîte de dialogue pour sélectionner le venv ."""
707+ """Open a dialog to select a virtual environment folder ."""
720708 if not self .venv_manager :
721709 QMessageBox .warning (
722710 self ,
@@ -772,7 +760,7 @@ def _select_venv(self):
772760 )
773761
774762 def _autodetect_venv (self ):
775- """Auto-détecte le meilleur venv disponible ."""
763+ """Run explicit virtual environment auto-detection ."""
776764 if not self .venv_manager :
777765 QMessageBox .warning (
778766 self ,
@@ -838,7 +826,7 @@ def _autodetect_venv(self):
838826 )
839827
840828 def _clear_venv (self ):
841- """Efface la sélection du venv ."""
829+ """Clear the currently selected virtual environment ."""
842830 self .venv_path = None
843831 self .venv_path_edit .clear ()
844832 self .venv_path_edit .setPlaceholderText (
@@ -860,16 +848,13 @@ def _clear_venv(self):
860848 )
861849
862850 def _is_valid (self , widget ) -> bool :
863- """Vérifie si un widget Qt est toujours valide.
864-
865- Contrairement à hasattr(), cette méthode vérifie si l'objet C++
866- sous-jacent n'a pas été détruit.
851+ """Return whether a Qt widget still has a valid underlying C++ object.
867852
868853 Args:
869- widget: Le widget Qt à vérifier
854+ widget: Qt widget to validate.
870855
871856 Returns:
872- True si le widget est valide, False sinon
857+ ` True` when widget is valid, otherwise `False`.
873858 """
874859 if widget is None :
875860 return False
@@ -911,7 +896,7 @@ def _filter_plugins_list(self, text: str) -> None:
911896 pass
912897
913898 def _apply_language (self , lang_code : str ):
914- """Applique la langue de l'interface ."""
899+ """Apply interface language and translated labels ."""
915900 global _CURRENT_LANGUAGE
916901 self .language = lang_code
917902 _CURRENT_LANGUAGE = lang_code
@@ -925,7 +910,7 @@ def _apply_language(self, lang_code: str):
925910 pass # Ignorer si le widget a été supprimé
926911
927912 def _discover_plugins (self ):
928- """Découvre et affiche les plugins BCASL disponibles ."""
913+ """Discover available BCASL plugins and refresh the list UI ."""
929914 # Vérifier que les widgets sont initialisés et valides
930915 if not self ._is_valid (self .plugins_list ):
931916 return
@@ -996,7 +981,7 @@ def _discover_plugins(self):
996981 self ._sync_plugin_tabs ()
997982
998983 def _add_plugin_item (self , plugin_id : str , meta : Dict [str , Any ]):
999- """Ajoute un plugin à la liste ."""
984+ """Add one plugin row into the list widget ."""
1000985 name = meta .get ("name" , plugin_id )
1001986 version = meta .get ("version" , "" )
1002987 description = meta .get ("description" , "" )
@@ -1247,7 +1232,7 @@ def _save_config(self) -> None:
12471232 pass
12481233
12491234 def _on_global_toggle (self , checked : bool ):
1250- """Gère l'activation/désactivation globale de BCASL ."""
1235+ """Handle global BCASL enable or disable action ."""
12511236 # Vérifier que la liste des plugins est valide
12521237 if not self ._is_valid (self .plugins_list ):
12531238 return
@@ -1282,7 +1267,7 @@ def _on_global_toggle(self, checked: bool):
12821267 pass
12831268
12841269 def _move_plugin_up (self ):
1285- """Déplace le plugin sélectionné vers le haut ."""
1270+ """Move selected plugin one row up ."""
12861271 # Vérifier que la liste des plugins est valide
12871272 if not self ._is_valid (self .plugins_list ):
12881273 return
@@ -1299,7 +1284,7 @@ def _move_plugin_up(self):
12991284 pass # Widget supprimé
13001285
13011286 def _move_plugin_down (self ):
1302- """Déplace le plugin sélectionné vers le bas ."""
1287+ """Move selected plugin one row down ."""
13031288 # Vérifier que la liste des plugins est valide
13041289 if not self ._is_valid (self .plugins_list ):
13051290 return
@@ -1316,7 +1301,7 @@ def _move_plugin_down(self):
13161301 pass # Widget supprimé
13171302
13181303 def _get_plugin_order (self ) -> List [str ]:
1319- """Récupère l'ordre actuel des plugins ."""
1304+ """Return current plugin execution order from the list UI ."""
13201305 # Vérifier que la liste des plugins est valide
13211306 if not self ._is_valid (self .plugins_list ):
13221307 return []
@@ -1333,7 +1318,7 @@ def _get_plugin_order(self) -> List[str]:
13331318 return order
13341319
13351320 def _get_enabled_plugins (self ) -> Dict [str , bool ]:
1336- """Récupère l'état d'activation des plugins ."""
1321+ """Return enabled state for each plugin in the list UI ."""
13371322 # Vérifier que la liste des plugins est valide
13381323 if not self ._is_valid (self .plugins_list ):
13391324 return {}
@@ -1350,7 +1335,7 @@ def _get_enabled_plugins(self) -> Dict[str, bool]:
13501335 return enabled
13511336
13521337 def _run_plugins (self ):
1353- """Exécute les plugins BCASL ."""
1338+ """Run BCASL plugins with current UI configuration ."""
13541339 if not self .workspace_dir :
13551340 QMessageBox .warning (
13561341 self ,
@@ -1482,7 +1467,7 @@ def _run_plugins(self):
14821467 self .execution_thread .start ()
14831468
14841469 def _cancel_execution (self ):
1485- """Annule l'exécution des plugins ."""
1470+ """Cancel plugin execution when a worker thread is active ."""
14861471 if self .execution_thread and self .execution_thread .isRunning ():
14871472 self ._log (tr ("Cancelling execution..." , "Annulation de l'exécution..." ))
14881473 self .execution_thread .terminate ()
@@ -1491,14 +1476,14 @@ def _cancel_execution(self):
14911476 self ._on_execution_finished (None , cancelled = True )
14921477
14931478 def _on_progress (self , current : int , total : int ):
1494- """Met à jour la progression ."""
1479+ """Update execution progress bar values ."""
14951480 self .progress_bar .setRange (0 , total )
14961481 self .progress_bar .setValue (current )
14971482
14981483 def _on_execution_finished (
14991484 self , report : Optional [ExecutionReport ], cancelled : bool = False
15001485 ):
1501- """Appelé lorsque l'exécution est terminée ."""
1486+ """Finalize UI state once plugin execution is complete ."""
15021487 # Réactiver les contrôles
15031488 self .btn_run .setEnabled (True )
15041489 self .btn_cancel .setEnabled (False )
@@ -1550,7 +1535,7 @@ def _on_execution_finished(
15501535 self ._log ("=" * 50 )
15511536
15521537 def _on_execution_error (self , error : str ):
1553- """Gère les erreurs d'exécution ."""
1538+ """Handle plugin execution errors ."""
15541539 self ._log (f"⚠️ { tr ('Error:' , 'Erreur :' )} { error } " )
15551540 self .statusBar .showMessage (tr ("Error" , "Erreur" ))
15561541
@@ -1565,15 +1550,15 @@ def _on_execution_error(self, error: str):
15651550 self .progress_bar .setVisible (False )
15661551
15671552 def _clear_log (self ):
1568- """Efface le log."""
1553+ """Clear the execution log pane ."""
15691554 if self ._is_valid (self .log_text ):
15701555 try :
15711556 self .log_text .clear ()
15721557 except (RuntimeError , AttributeError ):
15731558 pass # Ignorer si le widget a été supprimé
15741559
15751560 def _log (self , message : str ):
1576- """Ajoute un message au log."""
1561+ """Append a timestamped line to the execution log."""
15771562 try :
15781563 from pycompiler_ark import onlymod_log
15791564
@@ -1599,15 +1584,15 @@ def launch_bcasl_gui(
15991584 language : str = "en" ,
16001585 theme : str = "dark" ,
16011586) -> int :
1602- """Lance l'application Bcasl Standalone GUI.
1587+ """Launch the Bcasl standalone GUI.
16031588
16041589 Args:
1605- workspace_dir: Chemin du workspace (optionnel)
1606- language: Code de langue ('en' ou 'fr')
1607- theme: Nom du thème (' light' ou ' dark')
1590+ workspace_dir: Optional workspace path.
1591+ language: UI language code (`en` or `fr`).
1592+ theme: Theme name (` light` or ` dark`).
16081593
16091594 Returns:
1610- Code de retour de l'application
1595+ Application exit code.
16111596 """
16121597 app = QApplication (sys .argv )
16131598 app .setApplicationName ("PyCompiler ARK BCASL" )
0 commit comments