223 lines
8.1 KiB
Python
223 lines
8.1 KiB
Python
# --- FILE: gitsync_tool/gui/tabs/repo_tab.py ---
|
|
|
|
import tkinter as tk
|
|
from tkinter import ttk
|
|
from typing import Callable, Optional
|
|
|
|
from gitutility.gui.tooltip import Tooltip
|
|
|
|
|
|
class RepoTab(ttk.Frame):
|
|
"""
|
|
The 'Repository / Bundle' tab in the main application notebook.
|
|
This tab contains widgets for managing the local repository path, bundle
|
|
operations, and basic repository initialization.
|
|
"""
|
|
|
|
# Constants for colors
|
|
GREEN: str = "#90EE90" # LightGreen
|
|
RED: str = "#F08080" # LightCoral
|
|
|
|
def __init__(self, master: tk.Misc, **kwargs):
|
|
"""
|
|
Initializes the Repository / Bundle tab.
|
|
|
|
Args:
|
|
master: The parent widget (the ttk.Notebook).
|
|
**kwargs: Dictionary of callbacks from the main controller.
|
|
"""
|
|
super().__init__(master, padding=(10, 10))
|
|
|
|
# Store callbacks by getting them from kwargs
|
|
self.update_svn_status_callback = kwargs.get("update_svn_status_cb")
|
|
self.browse_folder_callback = kwargs.get("browse_folder_cb")
|
|
self.prepare_svn_for_git_callback = kwargs.get("prepare_svn_for_git_cb")
|
|
self.create_git_bundle_callback = kwargs.get("create_git_bundle_cb")
|
|
self.fetch_from_git_bundle_callback = kwargs.get("fetch_from_git_bundle_cb")
|
|
self.open_gitignore_editor_callback = kwargs.get("open_gitignore_editor_cb")
|
|
|
|
# Configure layout
|
|
self.columnconfigure(1, weight=1)
|
|
|
|
# Create widgets
|
|
self._create_widgets()
|
|
|
|
def _create_widgets(self) -> None:
|
|
"""Creates and arranges all widgets for this tab."""
|
|
# --- Paths and Bundle Names Frame ---
|
|
paths_frame = ttk.LabelFrame(self, text="Paths & Bundle Names", padding=(10, 5))
|
|
paths_frame.pack(pady=5, fill="x")
|
|
paths_frame.columnconfigure(1, weight=1)
|
|
|
|
# Row indices for grid
|
|
cl, ce, cb, ci = 0, 1, 2, 3
|
|
|
|
# Working Directory Path
|
|
ttk.Label(paths_frame, text="Working Directory Path:").grid(
|
|
row=0, column=cl, sticky=tk.W, padx=5, pady=3
|
|
)
|
|
self.svn_path_entry = ttk.Entry(paths_frame, width=60)
|
|
self.svn_path_entry.grid(row=0, column=ce, sticky=tk.EW, padx=5, pady=3)
|
|
self.svn_path_entry.bind(
|
|
"<FocusOut>",
|
|
lambda e: self.update_svn_status_callback(self.svn_path_entry.get()),
|
|
)
|
|
self.svn_path_entry.bind(
|
|
"<Return>",
|
|
lambda e: self.update_svn_status_callback(self.svn_path_entry.get()),
|
|
)
|
|
Tooltip(
|
|
self.svn_path_entry, "Path to the local Git repository working directory."
|
|
)
|
|
|
|
self.svn_path_browse_button = ttk.Button(
|
|
paths_frame,
|
|
text="Browse...",
|
|
width=9,
|
|
command=lambda: self.browse_folder_callback(self.svn_path_entry),
|
|
)
|
|
self.svn_path_browse_button.grid(
|
|
row=0, column=cb, sticky=tk.W, padx=(0, 5), pady=3
|
|
)
|
|
|
|
self.svn_status_indicator = tk.Label(
|
|
paths_frame,
|
|
text="",
|
|
width=2,
|
|
height=1,
|
|
relief=tk.SUNKEN,
|
|
background=self.RED,
|
|
anchor=tk.CENTER,
|
|
)
|
|
self.svn_status_indicator.grid(
|
|
row=0, column=ci, sticky=tk.E, padx=(0, 5), pady=3
|
|
)
|
|
Tooltip(
|
|
self.svn_status_indicator,
|
|
"Indicates if the path points to a valid Git repository (Green=Yes, Red=No).",
|
|
)
|
|
|
|
# Bundle Target Directory
|
|
ttk.Label(paths_frame, text="Bundle Target Directory:").grid(
|
|
row=1, column=cl, sticky=tk.W, padx=5, pady=3
|
|
)
|
|
self.usb_path_entry = ttk.Entry(paths_frame, width=60)
|
|
self.usb_path_entry.grid(row=1, column=ce, sticky=tk.EW, padx=5, pady=3)
|
|
Tooltip(
|
|
self.usb_path_entry,
|
|
"Directory where bundle files will be created or read from (e.g., USB drive).",
|
|
)
|
|
|
|
self.usb_path_browse_button = ttk.Button(
|
|
paths_frame,
|
|
text="Browse...",
|
|
width=9,
|
|
command=lambda: self.browse_folder_callback(self.usb_path_entry),
|
|
)
|
|
self.usb_path_browse_button.grid(
|
|
row=1, column=cb, sticky=tk.W, padx=(0, 5), pady=3
|
|
)
|
|
|
|
# Bundle Filenames
|
|
ttk.Label(paths_frame, text="Create Bundle Filename:").grid(
|
|
row=2, column=cl, sticky=tk.W, padx=5, pady=3
|
|
)
|
|
self.bundle_name_entry = ttk.Entry(paths_frame, width=60)
|
|
self.bundle_name_entry.grid(
|
|
row=2, column=ce, columnspan=2, sticky=tk.EW, padx=5, pady=3
|
|
)
|
|
Tooltip(
|
|
self.bundle_name_entry,
|
|
"Filename to use when creating a new bundle file (e.g., my_project.bundle).",
|
|
)
|
|
|
|
ttk.Label(paths_frame, text="Fetch Bundle Filename:").grid(
|
|
row=3, column=cl, sticky=tk.W, padx=5, pady=3
|
|
)
|
|
self.bundle_updated_name_entry = ttk.Entry(paths_frame, width=60)
|
|
self.bundle_updated_name_entry.grid(
|
|
row=3, column=ce, columnspan=2, sticky=tk.EW, padx=5, pady=3
|
|
)
|
|
Tooltip(
|
|
self.bundle_updated_name_entry,
|
|
"Filename of the bundle file to fetch updates from (e.g., update.bundle).",
|
|
)
|
|
|
|
# --- Repository Actions Frame ---
|
|
actions_frame = ttk.LabelFrame(self, text="Repository Actions", padding=(10, 5))
|
|
actions_frame.pack(pady=10, fill="x")
|
|
|
|
self.prepare_svn_button = ttk.Button(
|
|
actions_frame,
|
|
text="Prepare Repository",
|
|
command=self.prepare_svn_for_git_callback,
|
|
state=tk.DISABLED,
|
|
)
|
|
self.prepare_svn_button.pack(side=tk.LEFT, padx=(0, 5), pady=5)
|
|
Tooltip(
|
|
self.prepare_svn_button,
|
|
"Initialize Git in the selected directory and configure .gitignore (if not already a Git repo).",
|
|
)
|
|
|
|
self.create_bundle_button = ttk.Button(
|
|
actions_frame,
|
|
text="Create Bundle",
|
|
command=self.create_git_bundle_callback,
|
|
state=tk.DISABLED,
|
|
)
|
|
self.create_bundle_button.pack(side=tk.LEFT, padx=5, pady=5)
|
|
Tooltip(
|
|
self.create_bundle_button,
|
|
"Create a Git bundle file containing the entire repository history and refs.",
|
|
)
|
|
|
|
self.fetch_bundle_button = ttk.Button(
|
|
actions_frame,
|
|
text="Fetch from Bundle",
|
|
command=self.fetch_from_git_bundle_callback,
|
|
state=tk.DISABLED,
|
|
)
|
|
self.fetch_bundle_button.pack(side=tk.LEFT, padx=5, pady=5)
|
|
Tooltip(
|
|
self.fetch_bundle_button,
|
|
"Fetch updates from a bundle file and merge them, or clone if the directory is empty.",
|
|
)
|
|
|
|
self.edit_gitignore_button = ttk.Button(
|
|
actions_frame,
|
|
text="Edit .gitignore",
|
|
width=12,
|
|
command=self.open_gitignore_editor_callback,
|
|
state=tk.DISABLED,
|
|
)
|
|
self.edit_gitignore_button.pack(side=tk.LEFT, padx=5, pady=5)
|
|
Tooltip(self.edit_gitignore_button, "Open an editor for the .gitignore file.")
|
|
|
|
def update_svn_indicator(self, is_prepared: bool) -> None:
|
|
"""Updates the color and tooltip of the repository status indicator."""
|
|
color = self.GREEN if is_prepared else self.RED
|
|
tip = (
|
|
"Repository is valid and prepared (found .git)."
|
|
if is_prepared
|
|
else "Directory is not a valid/prepared Git repository."
|
|
)
|
|
if (
|
|
hasattr(self, "svn_status_indicator")
|
|
and self.svn_status_indicator.winfo_exists()
|
|
):
|
|
self.svn_status_indicator.config(background=color)
|
|
Tooltip(self.svn_status_indicator, tip)
|
|
|
|
def set_action_widgets_state(self, state: str) -> None:
|
|
"""Sets the state of all action widgets in this tab."""
|
|
widgets_to_toggle = [
|
|
self.prepare_svn_button,
|
|
self.create_bundle_button,
|
|
self.fetch_bundle_button,
|
|
self.edit_gitignore_button,
|
|
]
|
|
|
|
for widget in widgets_to_toggle:
|
|
if widget and widget.winfo_exists():
|
|
widget.config(state=state)
|