SXXXXXXX_LauncherTool/launchertool/gui/dialogs/parameter_dialog.py
2025-05-07 16:04:50 +02:00

172 lines
6.9 KiB
Python

# LauncherTool/gui/dialogs/parameter_dialogs.py
"""
Dialogs for adding and editing application parameters.
"""
import tkinter as tk
from tkinter import ttk, messagebox
import logging
from typing import Optional, Dict, Any
from ..utils_gui import GuiUtils
logger = logging.getLogger(__name__)
class BaseParameterDialog(tk.Toplevel):
"""
Base class for Add and Edit Parameter dialogs.
"""
def __init__(self, parent: tk.Widget, title: str):
super().__init__(parent)
self.transient(parent)
self.title(title)
self.parent_widget = parent
self.result: Optional[Dict[str, Any]] = None
self._parameter_types = ["string", "integer", "boolean", "float", "file", "folder"]
self._setup_widgets()
GuiUtils.center_window(self, parent)
self.protocol("WM_DELETE_WINDOW", self._on_cancel)
self.grab_set()
self.focus_set()
self.wait_window(self)
def _setup_widgets(self):
main_frame = ttk.Frame(self, padding="10")
main_frame.pack(expand=True, fill=tk.BOTH)
name_frame = ttk.Frame(main_frame)
name_frame.pack(fill=tk.X, pady=(0, 5))
ttk.Label(name_frame, text="Name:").grid(row=0, column=0, sticky=tk.W, padx=(0,5))
self.name_entry_var = tk.StringVar()
self.name_entry = ttk.Entry(name_frame, textvariable=self.name_entry_var, width=40)
self.name_entry.grid(row=0, column=1, sticky=tk.EW)
name_frame.columnconfigure(1, weight=1)
desc_frame = ttk.Frame(main_frame)
desc_frame.pack(fill=tk.X, pady=(0, 5))
ttk.Label(desc_frame, text="Description:").grid(row=0, column=0, sticky=tk.NW, padx=(0,5))
self.description_text = tk.Text(desc_frame, width=40, height=4, wrap=tk.WORD)
self.description_text.grid(row=0, column=1, sticky=tk.EW)
desc_scrollbar = ttk.Scrollbar(desc_frame, orient=tk.VERTICAL, command=self.description_text.yview)
desc_scrollbar.grid(row=0, column=2, sticky=tk.NS)
self.description_text.config(yscrollcommand=desc_scrollbar.set)
desc_frame.columnconfigure(1, weight=1)
def_val_frame = ttk.Frame(main_frame)
def_val_frame.pack(fill=tk.X, pady=(0, 5))
ttk.Label(def_val_frame, text="Default Value:").grid(row=0, column=0, sticky=tk.W, padx=(0,5))
self.default_value_entry_var = tk.StringVar()
self.default_value_entry = ttk.Entry(def_val_frame, textvariable=self.default_value_entry_var, width=40)
self.default_value_entry.grid(row=0, column=1, sticky=tk.EW)
def_val_frame.columnconfigure(1, weight=1)
type_frame = ttk.Frame(main_frame)
type_frame.pack(fill=tk.X, pady=(0, 10))
ttk.Label(type_frame, text="Type:").grid(row=0, column=0, sticky=tk.W, padx=(0,5))
self.type_combo_var = tk.StringVar()
self.type_combo = ttk.Combobox(
type_frame,
textvariable=self.type_combo_var,
values=self._parameter_types,
state="readonly",
width=38
)
self.type_combo.grid(row=0, column=1, sticky=tk.EW)
self.type_combo.set("string")
type_frame.columnconfigure(1, weight=1)
dialog_buttons_frame = ttk.Frame(main_frame)
dialog_buttons_frame.pack(fill=tk.X, pady=(10, 0))
ttk.Frame(dialog_buttons_frame).pack(side=tk.LEFT, expand=True)
self.save_button = ttk.Button(dialog_buttons_frame, text="Save", command=self._on_save)
self.save_button.pack(side=tk.LEFT, padx=(0,5))
self.cancel_button = ttk.Button(dialog_buttons_frame, text="Cancel", command=self._on_cancel)
self.cancel_button.pack(side=tk.LEFT)
def _validate_inputs(self) -> bool:
name = self.name_entry_var.get().strip()
if not name:
messagebox.showerror("Validation Error", "Parameter Name cannot be empty.", parent=self)
self.name_entry.focus_set()
return False
return True
def _on_save(self):
raise NotImplementedError("Subclasses must implement _on_save")
def _on_cancel(self):
logger.debug(f"{self.title()} cancelled or closed.")
self.result = None
self.destroy()
class AddParameterDialog(BaseParameterDialog):
"""Dialog for adding a new application parameter."""
def __init__(self, parent: tk.Widget):
super().__init__(parent, title="Add New Parameter")
def _on_save(self):
if not self._validate_inputs():
return
param_name = self.name_entry_var.get().strip()
param_description = self.description_text.get("1.0", tk.END).strip()
param_default_value = self.default_value_entry_var.get()
param_type = self.type_combo_var.get()
self.result = {
"name": param_name,
"description": param_description,
"default_value": param_default_value,
"type": param_type
}
logger.info(f"Parameter '{param_name}' data prepared for adding.")
self.destroy()
class EditParameterDialog(BaseParameterDialog):
"""Dialog for editing an existing application parameter."""
def __init__(self, parent: tk.Widget, parameter_data_to_edit: Dict[str, Any]):
self.parameter_data_to_edit = parameter_data_to_edit
super().__init__(parent, title=f"Edit Parameter: {parameter_data_to_edit.get('name', '')}")
self._load_initial_data()
def _load_initial_data(self):
if not self.parameter_data_to_edit:
logger.warning("EditParameterDialog opened without parameter data.")
self.destroy()
return
self.name_entry_var.set(self.parameter_data_to_edit.get("name", ""))
self.description_text.delete("1.0", tk.END)
self.description_text.insert("1.0", self.parameter_data_to_edit.get("description", ""))
self.default_value_entry_var.set(self.parameter_data_to_edit.get("default_value", ""))
param_type = self.parameter_data_to_edit.get("type", "string")
if param_type in self._parameter_types:
self.type_combo_var.set(param_type)
else:
logger.warning(f"Unknown parameter type '{param_type}' for '{self.name_entry_var.get()}'. Defaulting to 'string'.")
self.type_combo_var.set("string")
def _on_save(self):
if not self._validate_inputs():
return
new_param_name = self.name_entry_var.get().strip()
new_param_description = self.description_text.get("1.0", tk.END).strip()
new_param_default_value = self.default_value_entry_var.get()
new_param_type = self.type_combo_var.get()
self.result = {
"name": new_param_name,
"description": new_param_description,
"default_value": new_param_default_value,
"type": new_param_type
}
logger.info(f"Parameter '{new_param_name}' (original: '{self.parameter_data_to_edit.get('name')}') data prepared.")
self.destroy()