177 lines
7.6 KiB
Python
177 lines
7.6 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) |