SXXXXXXX_ProfileAnalyzer/profileanalyzer/gui/launch_manager_window.py
VALLONGOL e766172c47 Chore: Stop tracking files based on .gitignore update.
Untracked files matching the following rules:
- Rule "!.vscode/launch.json": 1 file
- Rule "*.prof": 6 files
2025-06-23 14:07:01 +02:00

215 lines
9.8 KiB
Python

# profileAnalyzer/gui/launch_manager_window.py
"""
GUI Window for managing and executing launch profiles.
"""
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
from typing import Optional
from ..core.core import LaunchProfile
from ..core.profile_manager import LaunchProfileManager
class LaunchManagerWindow(tk.Toplevel):
"""A Toplevel window for managing and running profiling launch profiles."""
def __init__(self, master, profile_manager: LaunchProfileManager):
super().__init__(master)
self.profile_manager = profile_manager
self.selected_profile_to_run: Optional[LaunchProfile] = None
self._init_window()
self._init_vars()
self._create_widgets()
self._populate_profile_list()
self.protocol("WM_DELETE_WINDOW", self._on_close)
self._toggle_view() # Set initial view state
def _init_window(self):
self.title("Launch Profile Manager")
self.geometry("900x400")
self.transient(self.master)
self.grab_set()
def _init_vars(self):
self.profile_name_var = tk.StringVar()
self.target_path_var = tk.StringVar()
self.module_name_var = tk.StringVar()
self.script_args_var = tk.StringVar()
self.run_as_module_var = tk.BooleanVar()
self.selected_listbox_item = None
self.run_as_module_var.trace_add("write", self._toggle_view)
def _create_widgets(self):
main_frame = ttk.Frame(self, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)
main_frame.rowconfigure(0, weight=1)
main_frame.columnconfigure(1, weight=3) # Detail frame expands more
# --- Left and Middle Frames ---
list_action_frame = ttk.Frame(main_frame)
list_action_frame.grid(row=0, column=0, sticky="ns", padx=(0, 10))
list_action_frame.rowconfigure(0, weight=1)
list_frame = ttk.LabelFrame(list_action_frame, text="Profiles")
list_frame.pack(fill=tk.BOTH, expand=True)
list_frame.rowconfigure(0, weight=1)
list_frame.columnconfigure(0, weight=1)
self.profile_listbox = tk.Listbox(list_frame, exportselection=False)
self.profile_listbox.grid(row=0, column=0, sticky="nsew")
self.profile_listbox.bind("<<ListboxSelect>>", self._on_profile_select)
list_scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=self.profile_listbox.yview)
list_scrollbar.grid(row=0, column=1, sticky="ns")
self.profile_listbox.config(yscrollcommand=list_scrollbar.set)
action_btn_frame = ttk.Frame(list_action_frame)
action_btn_frame.pack(fill=tk.X, pady=5)
ttk.Button(action_btn_frame, text="New", command=self._on_new).pack(side=tk.LEFT, expand=True, fill=tk.X)
ttk.Button(action_btn_frame, text="Delete", command=self._on_delete).pack(side=tk.LEFT, expand=True, fill=tk.X)
# --- Right Frame: Profile Details ---
self.detail_frame = ttk.LabelFrame(main_frame, text="Profile Details")
self.detail_frame.grid(row=0, column=1, sticky="nsew")
self.detail_frame.columnconfigure(1, weight=1)
# --- Common Details (Name, Module Checkbox) ---
name_frame = ttk.Frame(self.detail_frame)
name_frame.grid(row=0, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
name_frame.columnconfigure(0, weight=1)
ttk.Label(name_frame, text="Profile Name:").pack(side=tk.LEFT)
ttk.Entry(name_frame, textvariable=self.profile_name_var).pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
ttk.Checkbutton(name_frame, text="Run as Module", variable=self.run_as_module_var).pack(side=tk.LEFT, padx=5)
# --- Dynamic View Frames ---
self.script_frame = ttk.Frame(self.detail_frame)
self.script_frame.grid(row=1, column=0, columnspan=2, sticky="ew")
self.script_frame.columnconfigure(1, weight=1)
self.module_frame = ttk.Frame(self.detail_frame)
self.module_frame.grid(row=1, column=0, columnspan=2, sticky="ew")
self.module_frame.columnconfigure(1, weight=1)
# --- Widgets for Script Mode ---
ttk.Label(self.script_frame, text="Script Path:").grid(row=0, column=0, sticky="w", padx=5, pady=5)
ttk.Entry(self.script_frame, textvariable=self.target_path_var).grid(row=0, column=1, sticky="ew", padx=5)
ttk.Button(self.script_frame, text="...", width=3, command=self._browse_script).grid(row=0, column=2, padx=5)
# --- Widgets for Module Mode ---
ttk.Label(self.module_frame, text="Project Root Folder:").grid(row=0, column=0, sticky="w", padx=5, pady=5)
ttk.Entry(self.module_frame, textvariable=self.target_path_var).grid(row=0, column=1, sticky="ew", padx=5)
ttk.Button(self.module_frame, text="...", width=3, command=self._browse_folder).grid(row=0, column=2, padx=5)
ttk.Label(self.module_frame, text="Module Name:").grid(row=1, column=0, sticky="w", padx=5, pady=5)
ttk.Entry(self.module_frame, textvariable=self.module_name_var).grid(row=1, column=1, sticky="ew", padx=5)
# --- Common Arguments and Save Button ---
args_frame = ttk.Frame(self.detail_frame)
args_frame.grid(row=2, column=0, columnspan=2, sticky="ew", padx=5, pady=5)
args_frame.columnconfigure(1, weight=1)
ttk.Label(args_frame, text="Arguments:").grid(row=0, column=0, sticky="w")
ttk.Entry(args_frame, textvariable=self.script_args_var).grid(row=0, column=1, sticky="ew", padx=5)
ttk.Button(self.detail_frame, text="Save Changes", command=self._on_save).grid(row=3, column=1, sticky="e", padx=5, pady=10)
bottom_frame = ttk.Frame(main_frame)
bottom_frame.grid(row=1, column=0, columnspan=2, sticky="ew", pady=(10, 0))
self.run_button = ttk.Button(bottom_frame, text="Run & Profile Selected", command=self._on_run_profile, state=tk.DISABLED)
self.run_button.pack(side=tk.RIGHT)
def _toggle_view(self, *args):
if self.run_as_module_var.get():
self.script_frame.grid_remove()
self.module_frame.grid()
else:
self.module_frame.grid_remove()
self.script_frame.grid()
def _populate_profile_list(self):
self.profile_listbox.delete(0, tk.END)
for profile in self.profile_manager.get_profiles():
self.profile_listbox.insert(tk.END, profile.name)
def _on_profile_select(self, event=None):
selection_indices = self.profile_listbox.curselection()
if not selection_indices:
self.selected_listbox_item = None
self.run_button.config(state=tk.DISABLED)
return
self.selected_listbox_item = self.profile_listbox.get(selection_indices[0])
profile = self.profile_manager.get_profile_by_name(self.selected_listbox_item)
if profile:
self.profile_name_var.set(profile.name)
self.target_path_var.set(profile.target_path)
self.module_name_var.set(profile.module_name)
self.script_args_var.set(profile.script_args)
self.run_as_module_var.set(profile.run_as_module)
self.run_button.config(state=tk.NORMAL)
def _on_new(self):
self.profile_listbox.selection_clear(0, tk.END)
self.selected_listbox_item = None
self.profile_name_var.set("New Profile")
self.target_path_var.set("")
self.module_name_var.set("")
self.script_args_var.set("")
self.run_as_module_var.set(False)
self.run_button.config(state=tk.DISABLED)
def _on_save(self):
new_name = self.profile_name_var.get().strip()
if not new_name:
messagebox.showerror("Error", "Profile Name cannot be empty.", parent=self)
return
new_profile = LaunchProfile(
name=new_name,
run_as_module=self.run_as_module_var.get(),
target_path=self.target_path_var.get().strip(),
module_name=self.module_name_var.get().strip(),
script_args=self.script_args_var.get().strip()
)
if self.selected_listbox_item and self.selected_listbox_item != new_name:
if not self.profile_manager.update_profile(self.selected_listbox_item, new_profile):
messagebox.showerror("Error", f"Could not rename profile. A profile with the name '{new_name}' might already exist.", parent=self)
else:
self.selected_listbox_item = new_name
elif self.selected_listbox_item:
self.profile_manager.update_profile(self.selected_listbox_item, new_profile)
else:
if not self.profile_manager.add_profile(new_profile):
messagebox.showerror("Error", f"A profile with the name '{new_name}' already exists.", parent=self)
self._populate_profile_list()
def _on_delete(self):
if not self.selected_listbox_item: return
if messagebox.askyesno("Confirm Delete", f"Delete '{self.selected_listbox_item}'?", parent=self):
self.profile_manager.delete_profile(self.selected_listbox_item)
self._populate_profile_list()
self._on_new()
def _browse_script(self):
filepath = filedialog.askopenfilename(title="Select Python Script", filetypes=[("Python files", "*.py"), ("All files", "*.*")])
if filepath: self.target_path_var.set(filepath)
def _browse_folder(self):
folder_path = filedialog.askdirectory(title="Select Project Root Folder")
if folder_path: self.target_path_var.set(folder_path)
def _on_run_profile(self):
if not self.selected_listbox_item: return
self.selected_profile_to_run = self.profile_manager.get_profile_by_name(self.selected_listbox_item)
self.destroy()
def _on_close(self):
self.selected_profile_to_run = None
self.destroy()