154 lines
6.6 KiB
Python
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()
|
|
|