SXXXXXXX_GitUtility/gitutility/logic/profile_handler.py
2025-07-29 08:41:44 +02:00

147 lines
6.7 KiB
Python

# --- FILE: gitsync_tool/logic/profile_handler.py ---
import tkinter as tk
from typing import TYPE_CHECKING, List, Optional
from gitutility.config.config_manager import DEFAULT_PROFILE, ConfigManager
from gitutility.gui.main_frame import MainFrame
from gitutility.logging_setup import log_handler
# Forward reference for type hinting to avoid circular import
if TYPE_CHECKING:
from ..app import GitSvnSyncApp
class ProfileHandler:
"""
Handles all logic related to profile management, including loading, saving,
adding, and removing configuration profiles.
"""
def __init__(self, app: "GitSvnSyncApp"):
"""
Initializes the ProfileHandler.
Args:
app: The main application instance.
"""
self.app = app
self.config_manager: ConfigManager = app.config_manager
self.main_frame: MainFrame = app.main_frame
def load_profile_settings(self, profile_name: str) -> None:
"""Loads settings from a given profile into the GUI."""
func_name: str = "load_profile_settings"
log_handler.log_info(f"Loading settings for profile: '{profile_name}'", func_name=func_name)
self.main_frame.update_status_bar(f"Processing: Loading profile '{profile_name}'...")
if not profile_name or profile_name not in self.config_manager.get_profile_sections():
log_handler.log_warning(f"Profile '{profile_name}' invalid/not found.", func_name=func_name)
self.app._clear_and_disable_fields()
if profile_name:
self.main_frame.show_error("Profile Load Error", f"Profile '{profile_name}' not found.")
return
# Delegate the actual loading and GUI update to the app/main_frame
# to keep the UI logic separate from business logic as much as possible.
self.app._apply_profile_to_gui(profile_name)
def save_profile_settings(self) -> bool:
"""Gathers settings from the GUI and saves them to the current profile."""
func_name: str = "save_profile_settings"
profile_name = self.main_frame.profile_var.get()
if not profile_name:
log_handler.log_warning("Save failed: No profile selected.", func_name=func_name)
self.main_frame.update_status_bar("Save failed: No profile selected.")
return False
log_handler.log_info(f"Saving settings for profile: '{profile_name}'", func_name=func_name)
try:
settings_to_save = self.app._gather_settings_from_gui()
log_handler.log_debug(f"Settings gathered from GUI: {settings_to_save}", func_name=func_name)
for key, value in settings_to_save.items():
self.config_manager.set_profile_option(profile_name, key, value)
self.config_manager.save_config()
log_handler.log_info(f"Settings saved successfully for '{profile_name}'.", func_name=func_name)
self.main_frame.update_status_bar(f"Profile '{profile_name}' saved.")
return True
except Exception as e:
log_handler.log_exception(f"Error saving profile '{profile_name}': {e}", func_name=func_name)
self.main_frame.show_error("Save Error", f"Failed to save profile settings:\n{e}")
self.main_frame.update_status_bar(f"Error saving profile '{profile_name}'.")
return False
def add_profile(self) -> None:
"""Handles the creation of a new profile."""
func_name: str = "add_profile"
self.main_frame.update_status_bar("Adding new profile...")
name = self.main_frame.ask_new_profile_name()
if name is None:
log_handler.log_info("Add profile cancelled.", func_name=func_name)
self.main_frame.update_status_bar("Add profile cancelled.")
return
name = name.strip()
if not name:
self.main_frame.show_error("Input Error", "Profile name cannot be empty.")
return
if name in self.config_manager.get_profile_sections():
self.main_frame.show_error("Error", f"Profile '{name}' already exists.")
return
try:
defaults = self.config_manager._get_expected_keys_with_defaults()
defaults["bundle_name"] = f"{name}_repo.bundle"
defaults["bundle_name_updated"] = f"{name}_update.bundle"
self.config_manager.add_section(name)
for key, value in defaults.items():
self.config_manager.set_profile_option(name, key, str(value))
self.config_manager.save_config()
log_handler.log_info(f"Profile '{name}' added successfully.", func_name=func_name)
sections = self.config_manager.get_profile_sections()
self.main_frame.update_profile_dropdown(sections)
self.main_frame.profile_var.set(name) # This will trigger the load callback
except Exception as e:
log_handler.log_exception(f"Error adding profile '{name}': {e}", func_name=func_name)
self.main_frame.show_error("Add Error", f"Failed to add profile:\n{e}")
def remove_profile(self) -> None:
"""Handles the removal of the currently selected profile."""
func_name: str = "remove_profile"
profile = self.main_frame.profile_var.get()
if not profile:
self.main_frame.show_error("Error", "No profile selected.")
return
if profile == DEFAULT_PROFILE:
self.main_frame.show_error("Denied", f"Cannot remove default profile ('{DEFAULT_PROFILE}').")
return
if self.main_frame.ask_yes_no(
title="Confirm Remove",
message=f"Remove profile '{profile}'?\nThis cannot be undone."
):
try:
removed = self.config_manager.remove_profile_section(profile)
if removed:
self.config_manager.save_config()
log_handler.log_info(f"Profile '{profile}' removed.", func_name=func_name)
self.main_frame.update_status_bar(f"Profile '{profile}' removed.")
sections = self.config_manager.get_profile_sections()
self.main_frame.update_profile_dropdown(sections) # This will trigger load of new profile
else:
self.main_frame.show_error("Error", f"Could not remove '{profile}'.")
except Exception as e:
log_handler.log_exception(f"Error removing profile '{profile}': {e}", func_name=func_name)
self.main_frame.show_error("Error", f"Failed to remove profile:\n{e}")
else:
self.main_frame.update_status_bar("Removal cancelled.")