SXXXXXXX_GitUtility/gitutility/logic/window_handler.py

154 lines
6.6 KiB
Python

# --- FILE: gitsync_tool/logic/window_handler.py ---
import os
from typing import TYPE_CHECKING, Optional, List, Dict, Any
from gitutility.gui.editors import GitignoreEditorWindow
from gitutility.gui.diff_viewer import DiffViewerWindow
from gitutility.gui.commit_detail_window import CommitDetailWindow
from gitutility.gui.diff_summary_viewer import DiffSummaryWindow
from gitutility.logging_setup import log_handler
# Forward reference for type hinting to avoid circular imports
if TYPE_CHECKING:
from ..app import GitSvnSyncApp
class WindowHandler:
"""
Handles the creation and logic for all secondary windows, dialogs,
and editors within the application.
"""
def __init__(self, app: "GitSvnSyncApp"):
"""
Initializes the WindowHandler.
Args:
app: The main application instance.
"""
self.app = app
self.master = app.master
self.main_frame = app.main_frame
self.git_commands = app.git_commands
log_handler.log_debug("WindowHandler initialized.", func_name="__init__")
def handle_open_gitignore_editor(self):
"""Opens the .gitignore editor window."""
func_name = "handle_open_gitignore_editor"
svn_path = self.app._get_and_validate_svn_path("Edit .gitignore")
if not svn_path or not self.app._is_repo_ready(svn_path):
self.main_frame.show_error("Action Failed", "Select a valid and prepared repository first.")
return
gitignore_path = os.path.join(svn_path, ".gitignore")
try:
# The on_save_success_callback points to a method in the repository_handler
GitignoreEditorWindow(
master=self.master,
gitignore_path=gitignore_path,
on_save_success_callback=self.app.repository_handler.handle_gitignore_save
)
except Exception as e:
log_handler.log_exception(f"Error opening .gitignore editor: {e}", func_name=func_name)
self.main_frame.show_error("Editor Error", f"Could not open editor:\n{e}")
def handle_open_diff_viewer(self, file_status_line: str):
"""Opens the Diff Viewer for a file from the 'changed files' list."""
func_name = "handle_open_diff_viewer"
svn_path = self.app._get_and_validate_svn_path("Open Diff Viewer")
if not svn_path:
return
relative_path = self.app._extract_path_from_status_line(file_status_line)
if not relative_path:
log_handler.log_error(f"Could not extract path from: {file_status_line}", func_name=func_name)
self.main_frame.show_error("Path Error", f"Could not parse file path from line:\n{file_status_line}")
return
status_code = file_status_line.strip('\x00').strip()[:2].strip()
if status_code == 'D':
self.main_frame.show_info("Diff Not Applicable", "Cannot diff a deleted file against the working directory.")
return
if status_code in ['??', '!!']:
self.main_frame.show_info("Diff Not Applicable", "Cannot diff an untracked or ignored file.")
return
try:
DiffViewerWindow(
master=self.master,
git_commands=self.git_commands,
repo_path=svn_path,
relative_file_path=relative_path,
ref1='WORKING_DIR',
ref2='HEAD'
)
except Exception as e:
log_handler.log_exception(f"Error opening diff viewer: {e}", func_name=func_name)
self.main_frame.show_error("Diff Viewer Error", f"Could not display diff:\n{e}")
def handle_show_commit_details(self, commit_details: Dict[str, Any]):
"""Opens the CommitDetailWindow to display commit details."""
func_name = "handle_show_commit_details"
if not isinstance(commit_details, dict) or not commit_details.get('hash_full'):
log_handler.log_error("Invalid commit details received.", func_name=func_name)
self.main_frame.show_error("Display Error", "Internal error: Invalid commit data.")
self.app._reenable_widgets_if_ready()
return
try:
CommitDetailWindow(
master=self.master,
commit_data=commit_details,
open_diff_callback=self._handle_open_commit_file_diff
)
self.main_frame.update_status_bar("Ready.")
except Exception as e:
log_handler.log_exception(f"Error opening commit detail window: {e}", func_name=func_name)
self.main_frame.show_error("Display Error", f"Could not display commit details:\n{e}")
finally:
self.app._reenable_widgets_if_ready()
def _handle_open_commit_file_diff(self, commit_hash: str, file_status: str, file_path: str, old_file_path: Optional[str] = None):
"""Callback to open diff for a file from the commit detail view."""
func_name = "_handle_open_commit_file_diff"
svn_path = self.app._get_and_validate_svn_path("Open Commit File Diff")
if not svn_path: return
ref1, ref2 = f"{commit_hash}^", commit_hash
if file_status == 'D':
self.main_frame.show_info("Diff Not Applicable", "Diff for deleted files in this view is not supported.")
return
try:
DiffViewerWindow(
master=self.master,
git_commands=self.git_commands,
repo_path=svn_path,
relative_file_path=file_path,
ref1=ref1,
ref2=ref2
)
except Exception as e:
log_handler.log_exception(f"Error opening commit file diff: {e}", func_name=func_name)
self.main_frame.show_error("Diff Viewer Error", f"Could not display file changes:\n{e}")
def handle_show_comparison_summary(self, ref1: str, ref2: str, repo_path: str, changed_files: List[str]):
"""Opens the comparison summary window."""
func_name = "handle_show_comparison_summary"
try:
DiffSummaryWindow(
master=self.master,
git_commands=self.git_commands,
repo_path=repo_path,
ref1=ref1,
ref2=ref2,
changed_files_status=changed_files,
)
self.main_frame.update_status_bar("Ready.")
except Exception as e:
log_handler.log_exception(f"Error opening diff summary: {e}", func_name=func_name)
self.main_frame.show_error("Display Error", f"Could not display comparison results:\n{e}")
finally:
self.app._reenable_widgets_if_ready()