1- # SPDX-License-Identifier: Apache-2.0
1+ # SPDX-License-Identifier: Apache-2.0
22# Copyright 2026 Ague Samuel Amen
33#
44# Licensed under the Apache License, Version 2.0 (the "License");
3535 show_language_dialog as _i18n_show_dialog ,
3636)
3737
38+ # Import des classes de gestion du workspace
39+ from Core .WorkSpaceManager .SetupWorkspace import SetupWorkspace
40+ from Core .WorkSpaceManager .WorkspaceAdvancedManipulation import WorkspaceAdvancedManipulation
41+
3842
3943def get_selected_workspace () -> Optional [str ]:
4044 """Retourne le workspace sélectionné d'une manière non bloquante et thread-safe."""
@@ -139,223 +143,26 @@ def _apply_label(tr):
139143 from .UiConnection import init_ui
140144
141145 def dragEnterEvent (self , event : QDropEvent ):
142- if event .mimeData ().hasUrls ():
143- event .acceptProposedAction ()
144- else :
145- event .ignore ()
146+ """Gère l'événement dragEnter en déléguant à WorkspaceAdvancedManipulation."""
147+ WorkspaceAdvancedManipulation .handle_drag_enter_event (self , event )
146148
147149 def dropEvent (self , event : QDropEvent ):
148- urls = event .mimeData ().urls ()
149- added = 0
150- for url in urls :
151- path = url .toLocalFile ()
152- if os .path .isdir (path ):
153- added += self .add_py_files_from_folder (path )
154- elif path .endswith (".py" ):
155- # Vérifie que le fichier est dans workspace (si défini)
156- if (
157- self .workspace_dir
158- and not os .path .commonpath ([path , self .workspace_dir ])
159- == self .workspace_dir
160- ):
161- self .log_i18n (
162- f"⚠️ Ignoré (hors workspace): { path } " ,
163- f"⚠️ Ignored (outside workspace): { path } " ,
164- )
165- continue
166- if path not in self .python_files :
167- self .python_files .append (path )
168- relative_path = (
169- os .path .relpath (path , self .workspace_dir )
170- if self .workspace_dir
171- else path
172- )
173- self .file_list .addItem (relative_path )
174- added += 1
175- self .log_i18n (
176- f"✅ { added } fichier(s) ajouté(s) via drag & drop." ,
177- f"✅ { added } file(s) added via drag & drop." ,
178- )
179- self .update_command_preview ()
150+ """Gère l'événement drop en déléguant à WorkspaceAdvancedManipulation."""
151+ WorkspaceAdvancedManipulation .handle_drop_event (self , event )
180152
181153 def add_py_files_from_folder (self , folder ):
182- from Core .ArkConfigManager import load_ark_config , should_exclude_file
183-
184- count = 0
185- excluded_count = 0
186- # Charger la configuration ARK pour les patterns d'exclusion
187- ark_config = load_ark_config (self .workspace_dir )
188- exclusion_patterns = ark_config .get ("exclusion_patterns" , [])
189-
190- for root , _ , files in os .walk (folder ):
191- for f in files :
192- if f .endswith (".py" ):
193- full_path = os .path .join (root , f )
194- if (
195- self .workspace_dir
196- and not os .path .commonpath ([full_path , self .workspace_dir ])
197- == self .workspace_dir
198- ):
199- continue
200-
201- # Vérifier les patterns d'exclusion depuis ARK_Main_Config.yml
202- if should_exclude_file (
203- full_path , self .workspace_dir , exclusion_patterns
204- ):
205- excluded_count += 1
206- continue
207-
208- if full_path not in self .python_files :
209- self .python_files .append (full_path )
210- relative_path = (
211- os .path .relpath (full_path , self .workspace_dir )
212- if self .workspace_dir
213- else full_path
214- )
215- self .file_list .addItem (relative_path )
216- count += 1
217-
218- # Afficher un message récPluginstulatif si des fichiers ont été exclus
219- if excluded_count > 0 :
220- self .log_i18n (
221- f"⏩ Exclusion appliquée : { excluded_count } fichier(s) exclu(s) selon ARK_Main_Config.yml" ,
222- f"⏩ Exclusion applied: { excluded_count } file(s) excluded according to ARK_Main_Config.yml" ,
223- )
224-
225- return count
154+ """Ajoute les fichiers Python du dossier en déléguant à SetupWorkspace."""
155+ return SetupWorkspace .add_py_files_from_folder (self , folder )
226156
227157 def select_workspace (self ):
228- folder = QFileDialog .getExistingDirectory (self , "Choisir le dossier du projet" )
158+ """Ouvre une boîte de dialogue pour sélectionner le workspace."""
159+ folder = SetupWorkspace .select_workspace (self )
229160 if folder :
230161 self .apply_workspace_selection (folder , source = "ui" )
231162
232163 def apply_workspace_selection (self , folder : str , source : str = "ui" ) -> bool :
233- try :
234- # Afficher le dialog de chargement du workspace
235- try :
236- loading_dialog = CompilationProcessDialog (
237- "Chargement de l'espace de travail" , self
238- )
239- loading_dialog .set_status ("📁 Chargement de l'espace de travail..." )
240- loading_dialog .btn_cancel .setEnabled (False )
241- loading_dialog .show ()
242- QApplication .processEvents ()
243- except Exception :
244- loading_dialog = None
245-
246- # Ensure target folder exists; auto-create if missing; never refuse
247- if not folder :
248- try :
249- self .log_i18n (
250- "⚠️ Chemin de workspace vide fourni; aucune modification appliquée (accepté)." ,
251- "⚠️ Empty workspace path provided; no changes applied (accepted)." ,
252- )
253- except Exception :
254- pass
255- try :
256- if loading_dialog :
257- loading_dialog .close ()
258- except Exception :
259- pass
260- return True
261- if not os .path .isdir (folder ):
262- try :
263- os .makedirs (folder , exist_ok = True )
264- try :
265- self .log_i18n (
266- f"📁 Dossier cré�� automatiquement: { folder } " ,
267- f"📁 Folder created automatically: { folder } " ,
268- )
269- except Exception :
270- pass
271- except Exception :
272- try :
273- self .log_i18n (
274- f"⚠️ Impossible de créer le dossier, poursuite quand même: { folder } " ,
275- f"⚠️ Unable to create folder, continuing anyway: { folder } " ,
276- )
277- except Exception :
278- pass
279- # Confirmation when Plugins requests workspace change
280- if str (source ).lower () == "plugin" :
281- # Auto-approve Plugins workspace switch; cancel running builds if any
282- try :
283- if getattr (self , "processes" , None ) and self .processes :
284- try :
285- self .log_i18n (
286- "⛔ Arrêt des compilations en cours pour changer de workspace (Plugins)." ,
287- "⛔ Stopping ongoing builds to switch workspace (Plugins)." ,
288- )
289- except Exception :
290- pass
291- try :
292- self .cancel_all_compilations ()
293- except Exception :
294- pass
295- except Exception :
296- pass
297- else :
298- # Non-Plugins requests: never refuse; cancel running builds if any
299- if getattr (self , "processes" , None ) and self .processes :
300- try :
301- self .log_i18n (
302- "⛔ Arrêt des compilations en cours pour changer de workspace (UI)." ,
303- "⛔ Stopping ongoing builds to switch workspace (UI)." ,
304- )
305- except Exception :
306- pass
307- try :
308- self .cancel_all_compilations ()
309- except Exception :
310- pass
311- self .workspace_dir = folder
312- try :
313- global _workspace_dir_cache
314- with _workspace_dir_lock :
315- _workspace_dir_cache = folder
316- except Exception :
317- pass
318- self .label_folder .setText (f"Dossier sélectionné : { folder } " )
319- self .python_files .clear ()
320- self .file_list .clear ()
321- self .add_py_files_from_folder (folder )
322- self .selected_files .clear ()
323- self .update_command_preview ()
324- try :
325- self .save_preferences ()
326- except Exception :
327- pass
328- # -- Configuration centralisée du workspace --
329- try :
330- self .venv_manager .setup_workspace (folder )
331- except Exception as e :
332- self .log_i18n (
333- f"⚠️ Erreur lors de la configuration du workspace: { e } " ,
334- f"⚠️ Error during workspace setup: { e } " ,
335- )
336-
337- # Fermer le dialog de chargement
338- try :
339- if loading_dialog :
340- loading_dialog .close ()
341- except Exception :
342- pass
343-
344- return True
345- except Exception as _e :
346- try :
347- self .log_i18n (
348- f"❌ Échec application workspace: { _e } " ,
349- f"❌ Failed to apply workspace: { _e } " ,
350- )
351- except Exception :
352- pass
353- try :
354- if loading_dialog :
355- loading_dialog .close ()
356- except Exception :
357- pass
358- return False
164+ """Applique la sélection du workspace en déléguant à SetupWorkspace."""
165+ return SetupWorkspace .apply_workspace_selection (self , folder , source )
359166
360167 def select_venv_manually (self ):
361168 self .venv_manager .select_venv_manually ()
@@ -367,106 +174,12 @@ def install_requirements_if_needed(self, path):
367174 self .venv_manager .install_requirements_if_needed (path )
368175
369176 def select_files_manually (self ):
370- if not self .workspace_dir :
371- QMessageBox .warning (
372- self ,
373- self .tr ("Attention" , "Warning" ),
374- self .tr (
375- "Veuillez d'abord sélectionner un dossier workspace." ,
376- "Please select a workspace folder first." ,
377- ),
378- )
379- return
380- files , _ = QFileDialog .getOpenFileNames (
381- self ,
382- "Sélectionner des fichiers Python" ,
383- self .workspace_dir ,
384- "Python Files (*.py)" ,
385- )
386- if files :
387- valid_files = []
388- for f in files :
389- if os .path .commonpath ([f , self .workspace_dir ]) == self .workspace_dir :
390- valid_files .append (f )
391- else :
392- QMessageBox .warning (
393- self ,
394- self .tr ("Fichier hors workspace" , "File outside workspace" ),
395- self .tr (
396- f"Le fichier { f } est en dehors du workspace et sera ignoré." ,
397- f"The file { f } is outside the workspace and will be ignored." ,
398- ),
399- )
400- if valid_files :
401- self .selected_files = valid_files
402- self .log_i18n (
403- f"✅ { len (valid_files )} fichier(s) sélectionné(s) manuellement.\n " ,
404- f"✅ { len (valid_files )} file(s) selected manually.\n " ,
405- )
406- self .update_command_preview ()
177+ """Ouvre une boîte de dialogue pour sélectionner des fichiers en déléguant à WorkspaceAdvancedManipulation."""
178+ WorkspaceAdvancedManipulation .select_files_manually (self )
407179
408180 def open_ark_config (self ):
409- """Ouvre le fichier ARK_Main_Config.yml dans l'éditeur par défaut"""
410- if not self .workspace_dir :
411- QMessageBox .warning (
412- self ,
413- self .tr ("Attention" , "Warning" ),
414- self .tr (
415- "Veuillez d'abord sélectionner un dossier workspace." ,
416- "Please select a workspace folder first." ,
417- ),
418- )
419- return
420-
421- config_path = os .path .join (self .workspace_dir , "ARK_Main_Config.yml" )
422-
423- # Créer le fichier s'il n'existe pas
424- if not os .path .exists (config_path ):
425- try :
426- from Core .ArkConfigManager import create_default_ark_config
427-
428- if create_default_ark_config (self .workspace_dir ):
429- self .log_i18n (
430- "📋 Fichier ARK_Main_Config.yml créé." ,
431- "📋 ARK_Main_Config.yml file created." ,
432- )
433- except Exception as e :
434- QMessageBox .critical (
435- self ,
436- self .tr ("Erreur" , "Error" ),
437- self .tr (
438- f"Impossible de créer ARK_Main_Config.yml: { e } " ,
439- f"Failed to create ARK_Main_Config.yml: { e } " ,
440- ),
441- )
442- return
443-
444- # Ouvrir le fichier dans l'éditeur par défaut
445- try :
446- import subprocess
447- import platform
448-
449- system = platform .system ()
450- if system == "Windows" :
451- os .startfile (config_path )
452- elif system == "Darwin" : # macOS
453- subprocess .run (["open" , config_path ])
454- else : # Linux
455- subprocess .run (["xdg-open" , config_path ])
456-
457- self .log_i18n (
458- f"📝 Ouverture de { config_path } " ,
459- f"📝 Opening { config_path } " ,
460- )
461- except Exception as e :
462- QMessageBox .warning (
463- self ,
464- self .tr ("Attention" , "Warning" ),
465- self .tr (
466- f"Impossible d'ouvrir le fichier: { e } \n Chemin: { config_path } " ,
467- f"Failed to open file: { e } \n Path: { config_path } " ,
468- ),
469- )
181+ """Ouvre le fichier ARK_Main_Config.yml dans l'éditeur par défaut en déléguant à SetupWorkspace."""
182+ SetupWorkspace .open_ark_config (self )
470183
471184 def on_main_only_changed (self ):
472185 if self .opt_main_only .isChecked ():
@@ -543,25 +256,8 @@ def add_remove_file_button(self):
543256 pass
544257
545258 def remove_selected_file (self ):
546- selected_items = self .file_list .selectedItems ()
547- for item in selected_items :
548- # Récupère le chemin relatif affiché
549- rel_path = item .text ()
550- # Construit le chemin absolu si workspace_dir défini
551- abs_path = (
552- os .path .join (self .workspace_dir , rel_path )
553- if self .workspace_dir
554- else rel_path
555- )
556- # Supprime de python_files si présent
557- if abs_path in self .python_files :
558- self .python_files .remove (abs_path )
559- # Supprime de selected_files si présent
560- if abs_path in self .selected_files :
561- self .selected_files .remove (abs_path )
562- # Supprime l'item de la liste graphique
563- self .file_list .takeItem (self .file_list .row (item ))
564- self .update_command_preview ()
259+ """Supprime les fichiers sélectionnés en déléguant à WorkspaceAdvancedManipulation."""
260+ WorkspaceAdvancedManipulation .remove_selected_file (self )
565261
566262 def show_help_dialog (self ):
567263 # Minimal help dialog with current license information
@@ -1087,3 +783,4 @@ def closeEvent(self, event):
1087783 except Exception :
1088784 pass
1089785 event .accept ()
786+
0 commit comments