import tkinter as tk from tkinter import ttk from datetime import datetime import typing from shared_libs.common_tools import IconManager if typing.TYPE_CHECKING: from tkinter import Event class LogWindow(ttk.Frame): """A Tkinter frame that provides a scrollable text widget for logging messages.""" def __init__(self, parent: tk.Misc, copy: str = "Copy") -> None: """ Initializes the LogWindow widget. Args: parent: The parent widget. copy: The text label for the 'Copy' context menu item. """ super().__init__(parent) self.icon_manager = IconManager() log_container = tk.Frame(self) # Let the main app control padding via the grid options log_container.pack(fill="both", expand=True, padx=0, pady=0) self.log_text: tk.Text = tk.Text( log_container, wrap=tk.WORD, font=("Consolas", 9), bg="#1e1e1e", fg="#d4d4d4", insertbackground="white", selectbackground="#264f78", height=10 # Give it a default height ) log_scrollbar = ttk.Scrollbar( log_container, orient="vertical", command=self.log_text.yview ) self.log_text.configure(yscrollcommand=log_scrollbar.set) self.log_text.pack(side="left", fill="both", expand=True) log_scrollbar.pack(side="right", fill="y") self.context_menu: tk.Menu = tk.Menu(self, tearoff=0) self.context_menu.add_command( label=copy, command=self.copy_text, image=self.icon_manager.get_icon('copy'), compound='left') self.log_text.bind("", self.show_context_menu) def log_message(self, message: str) -> None: """ Adds a timestamped message to the log view. Args: message: The message string to add. """ timestamp = datetime.now().strftime("%H:%M:%S") log_entry = f"[{timestamp}] {message}\n" self.log_text.insert(tk.END, log_entry) self.log_text.see(tk.END) self.log_text.update() def show_text_menu(self, event: 'Event') -> None: """ Displays the context menu at the event's coordinates. (Note: This seems to be a remnant, show_context_menu is used). Args: event: The tkinter event that triggered the menu. """ try: self.context_menu.tk_popup(event.x_root, event.y_root) finally: self.context_menu.grab_release() def copy_text(self) -> None: """Copies the currently selected text in the log widget to the clipboard.""" try: selected_text = self.log_text.selection_get() self.clipboard_clear() self.clipboard_append(selected_text) except tk.TclError: # No Text selected pass def show_context_menu(self, event: 'Event') -> None: """ Shows the right-click context menu. Args: event: The tkinter Button-3 event. """ try: self.context_menu.tk_popup(event.x_root, event.y_root) finally: self.context_menu.grab_release()