184 lines
7.8 KiB
Python
184 lines
7.8 KiB
Python
# target_simulator/gui/settings_window.py
|
|
|
|
"""
|
|
A Toplevel window for configuring connection settings (Serial or TFTP).
|
|
"""
|
|
|
|
import tkinter as tk
|
|
from tkinter import ttk, messagebox
|
|
from typing import Dict, Any
|
|
|
|
from core.serial_communicator import SerialCommunicator, SERIAL_PARAMS
|
|
from core.tftp_communicator import TFTPCommunicator
|
|
from target_simulator.utils.config_manager import ConfigManager
|
|
|
|
class SettingsWindow(tk.Toplevel):
|
|
"""A dialog window for connection settings."""
|
|
|
|
def __init__(self, master, config_manager: ConfigManager, current_config: Dict[str, Any]):
|
|
super().__init__(master)
|
|
self.master_view = master
|
|
self.config_manager = config_manager
|
|
|
|
self.title("Connection Settings")
|
|
self.transient(master)
|
|
self.grab_set()
|
|
self.resizable(False, False)
|
|
|
|
# --- Variables ---
|
|
self.comm_type_var = tk.StringVar(value=current_config.get("type", "serial"))
|
|
self.serial_config_vars = self._setup_serial_vars(current_config.get("serial", {}))
|
|
self.tftp_config_vars = self._setup_tftp_vars(current_config.get("tftp", {}))
|
|
|
|
# --- UI Creation ---
|
|
main_frame = ttk.Frame(self, padding="10")
|
|
main_frame.pack(fill=tk.BOTH, expand=True)
|
|
|
|
self._create_type_selector(main_frame)
|
|
|
|
# --- Configuration Frames ---
|
|
self.serial_frame = self._create_serial_frame(main_frame)
|
|
self.tftp_frame = self._create_tftp_frame(main_frame)
|
|
|
|
self._create_buttons(main_frame)
|
|
|
|
# --- Initial State ---
|
|
self._on_comm_type_change()
|
|
|
|
self.protocol("WM_DELETE_WINDOW", self.destroy)
|
|
self.wait_window(self)
|
|
|
|
def _setup_serial_vars(self, config: Dict) -> Dict[str, tk.StringVar]:
|
|
return {
|
|
"port": tk.StringVar(value=config.get("port", "")),
|
|
"baudrate": tk.StringVar(value=config.get("baudrate", "115200")),
|
|
"bytesize": tk.StringVar(value=config.get("bytesize", "8")),
|
|
"parity": tk.StringVar(value=config.get("parity", "N")),
|
|
"stopbits": tk.StringVar(value=config.get("stopbits", "1")),
|
|
}
|
|
|
|
def _setup_tftp_vars(self, config: Dict) -> Dict[str, tk.StringVar]:
|
|
return {
|
|
"ip": tk.StringVar(value=config.get("ip", "127.0.0.1")),
|
|
"port": tk.StringVar(value=config.get("port", "69")),
|
|
}
|
|
|
|
def _create_type_selector(self, parent):
|
|
frame = ttk.LabelFrame(parent, text="Communication Type", padding=10)
|
|
frame.pack(fill=tk.X, pady=(0, 10))
|
|
|
|
ttk.Radiobutton(
|
|
frame, text="Serial", variable=self.comm_type_var, value="serial", command=self._on_comm_type_change
|
|
).pack(side=tk.LEFT, padx=10)
|
|
|
|
ttk.Radiobutton(
|
|
frame, text="TFTP", variable=self.comm_type_var, value="tftp", command=self._on_comm_type_change
|
|
).pack(side=tk.LEFT, padx=10)
|
|
|
|
def _create_serial_frame(self, parent) -> ttk.Frame:
|
|
frame = ttk.LabelFrame(parent, text="Serial Port Settings", padding=10)
|
|
|
|
# Grid layout for alignment
|
|
frame.columnconfigure(1, weight=1)
|
|
|
|
# Port
|
|
ttk.Label(frame, text="Port:").grid(row=0, column=0, sticky=tk.W, pady=2)
|
|
port_combo = ttk.Combobox(frame, textvariable=self.serial_config_vars["port"], state="readonly")
|
|
port_combo.grid(row=0, column=1, sticky=tk.EW, padx=5, pady=2)
|
|
self._populate_ports(port_combo)
|
|
|
|
# Baudrate
|
|
ttk.Label(frame, text="Baud Rate:").grid(row=1, column=0, sticky=tk.W, pady=2)
|
|
baud_combo = ttk.Combobox(frame, textvariable=self.serial_config_vars["baudrate"], values=SERIAL_PARAMS['baudrates'], state="readonly")
|
|
baud_combo.grid(row=1, column=1, sticky=tk.EW, padx=5, pady=2)
|
|
|
|
# Parity
|
|
ttk.Label(frame, text="Parity:").grid(row=2, column=0, sticky=tk.W, pady=2)
|
|
parity_combo = ttk.Combobox(frame, textvariable=self.serial_config_vars["parity"], values=list(SERIAL_PARAMS['parities']), state="readonly")
|
|
parity_combo.grid(row=2, column=1, sticky=tk.EW, padx=5, pady=2)
|
|
|
|
return frame
|
|
|
|
def _create_tftp_frame(self, parent) -> ttk.Frame:
|
|
frame = ttk.LabelFrame(parent, text="TFTP Server Settings", padding=10)
|
|
frame.columnconfigure(1, weight=1)
|
|
|
|
# IP Address
|
|
ttk.Label(frame, text="Server IP:").grid(row=0, column=0, sticky=tk.W, pady=2)
|
|
ttk.Entry(frame, textvariable=self.tftp_config_vars["ip"]).grid(row=0, column=1, sticky=tk.EW, padx=5, pady=2)
|
|
|
|
# Port
|
|
ttk.Label(frame, text="Server Port:").grid(row=1, column=0, sticky=tk.W, pady=2)
|
|
ttk.Entry(frame, textvariable=self.tftp_config_vars["port"]).grid(row=1, column=1, sticky=tk.EW, padx=5, pady=2)
|
|
|
|
return frame
|
|
|
|
def _create_buttons(self, parent):
|
|
frame = ttk.Frame(parent, padding=(0, 10, 0, 0))
|
|
frame.pack(fill=tk.X)
|
|
|
|
ttk.Button(frame, text="Test Connection", command=self._on_test_connection).pack(side=tk.LEFT, padx=(0, 10))
|
|
|
|
# Right-align Save and Cancel
|
|
ttk.Button(frame, text="Cancel", command=self.destroy).pack(side=tk.RIGHT)
|
|
ttk.Button(frame, text="Save", command=self._on_save).pack(side=tk.RIGHT, padx=5)
|
|
|
|
def _on_comm_type_change(self):
|
|
"""Show/hide frames based on the selected communication type."""
|
|
selected_type = self.comm_type_var.get()
|
|
if selected_type == "serial":
|
|
self.tftp_frame.pack_forget()
|
|
self.serial_frame.pack(fill=tk.X, expand=True)
|
|
elif selected_type == "tftp":
|
|
self.serial_frame.pack_forget()
|
|
self.tftp_frame.pack(fill=tk.X, expand=True)
|
|
|
|
def _populate_ports(self, combobox: ttk.Combobox):
|
|
"""Fetches and displays available serial ports."""
|
|
available_ports = SerialCommunicator.list_available_ports()
|
|
if available_ports:
|
|
combobox['values'] = available_ports
|
|
if not self.serial_config_vars["port"].get():
|
|
self.serial_config_vars["port"].set(available_ports[0])
|
|
else:
|
|
combobox['values'] = ['No ports found']
|
|
self.serial_config_vars["port"].set('No ports found')
|
|
|
|
def _on_test_connection(self):
|
|
"""Tests the connection for the currently selected mode."""
|
|
comm_type = self.comm_type_var.get()
|
|
is_success = False
|
|
config = {}
|
|
|
|
if comm_type == "serial":
|
|
config = {key: var.get() for key, var in self.serial_config_vars.items()}
|
|
is_success = SerialCommunicator.test_connection(config)
|
|
else: # tftp
|
|
config = {key: var.get() for key, var in self.tftp_config_vars.items()}
|
|
is_success = TFTPCommunicator.test_connection(config)
|
|
|
|
if is_success:
|
|
messagebox.showinfo("Success", f"Connection test successful for {comm_type.upper()}.", parent=self)
|
|
else:
|
|
messagebox.showerror("Failure", f"Failed to connect using {comm_type.upper()} settings.", parent=self)
|
|
|
|
def _on_save(self):
|
|
"""Saves the selected settings and closes the window."""
|
|
comm_type = self.comm_type_var.get()
|
|
# Recupera la configurazione corrente
|
|
current = self.master_view.connection_config if hasattr(self.master_view, 'connection_config') else {}
|
|
serial_conf = current.get("serial", {})
|
|
tftp_conf = current.get("tftp", {})
|
|
|
|
if comm_type == "serial":
|
|
serial_conf = {key: var.get() for key, var in self.serial_config_vars.items()}
|
|
else:
|
|
tftp_conf = {key: var.get() for key, var in self.tftp_config_vars.items()}
|
|
|
|
full_config = {
|
|
"type": comm_type,
|
|
"serial": serial_conf,
|
|
"tftp": tftp_conf
|
|
}
|
|
self.master_view.update_connection_settings(full_config)
|
|
self.destroy() |