Add type annotations to window.py

This commit is contained in:
vesp 2026-01-05 11:31:59 +01:00
parent 29bab2aa07
commit 30872b4697

View File

@ -20,6 +20,7 @@
import gi import gi
gi.require_version('GtkSource', '5') gi.require_version('GtkSource', '5')
from gi.repository import Adw, Gtk, GLib, Gio, GtkSource from gi.repository import Adw, Gtk, GLib, Gio, GtkSource
from typing import Dict, Optional
from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab
from .http_client import HttpClient from .http_client import HttpClient
from .history_manager import HistoryManager from .history_manager import HistoryManager
@ -67,13 +68,13 @@ class RosterWindow(Adw.ApplicationWindow):
self.tab_manager = TabManager() self.tab_manager = TabManager()
# Map AdwTabPage to tab data # Map AdwTabPage to tab data
self.page_to_widget = {} # AdwTabPage -> RequestTabWidget self.page_to_widget: Dict[Adw.TabPage, RequestTabWidget] = {}
self.page_to_tab = {} # AdwTabPage -> RequestTab self.page_to_tab: Dict[Adw.TabPage, RequestTab] = {}
self.current_tab_id = None self.current_tab_id: Optional[str] = None
# Track recently updated variables for visual marking # Track recently updated variables for visual marking
# Format: {project_id: {var_name: timestamp}} # Format: {project_id: {var_name: timestamp}}
self.recently_updated_variables = {} self.recently_updated_variables: Dict[str, Dict[str, str]] = {}
# Connect to tab view signals # Connect to tab view signals
self.tab_view.connect('close-page', self._on_tab_close_page) self.tab_view.connect('close-page', self._on_tab_close_page)
@ -96,7 +97,7 @@ class RosterWindow(Adw.ApplicationWindow):
# Create first tab # Create first tab
self._create_new_tab() self._create_new_tab()
def _on_close_request(self, window): def _on_close_request(self, window) -> bool:
"""Handle window close request - warn if there are unsaved changes.""" """Handle window close request - warn if there are unsaved changes."""
# Check if any tabs have unsaved changes # Check if any tabs have unsaved changes
modified_tabs = [] modified_tabs = []
@ -131,13 +132,13 @@ class RosterWindow(Adw.ApplicationWindow):
# No unsaved changes, allow closing # No unsaved changes, allow closing
return False return False
def _on_close_app_dialog_response(self, dialog, response): def _on_close_app_dialog_response(self, dialog, response) -> None:
"""Handle close application dialog response.""" """Handle close application dialog response."""
if response == "close": if response == "close":
# User confirmed - close the window # User confirmed - close the window
self.destroy() self.destroy()
def _setup_custom_css(self): def _setup_custom_css(self) -> None:
"""Setup custom CSS for UI styling.""" """Setup custom CSS for UI styling."""
css_provider = Gtk.CssProvider() css_provider = Gtk.CssProvider()
css_provider.load_from_data(b""" css_provider.load_from_data(b"""
@ -186,12 +187,12 @@ class RosterWindow(Adw.ApplicationWindow):
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
) )
def _setup_tab_system(self): def _setup_tab_system(self) -> None:
"""Set up the tab system.""" """Set up the tab system."""
# Connect new request button # Connect new request button
self.new_request_button.connect("clicked", self._on_new_request_clicked) self.new_request_button.connect("clicked", self._on_new_request_clicked)
def _on_tab_selected(self, tab_view, param): def _on_tab_selected(self, tab_view, param) -> None:
"""Handle tab selection change.""" """Handle tab selection change."""
page = tab_view.get_selected_page() page = tab_view.get_selected_page()
if not page: if not page:
@ -202,7 +203,7 @@ class RosterWindow(Adw.ApplicationWindow):
if tab: if tab:
self.current_tab_id = tab.id self.current_tab_id = tab.id
def _on_tab_close_page(self, tab_view, page): def _on_tab_close_page(self, tab_view, page) -> bool:
"""Handle tab close request.""" """Handle tab close request."""
# Get the RequestTab and widget for this page # Get the RequestTab and widget for this page
tab = self.page_to_tab.get(page) tab = self.page_to_tab.get(page)
@ -261,7 +262,7 @@ class RosterWindow(Adw.ApplicationWindow):
return False # Allow close return False # Allow close
def _create_new_tab_once(self): def _create_new_tab_once(self) -> bool:
"""Create a new tab (one-time callback).""" """Create a new tab (one-time callback)."""
# Only create if there really are no tabs # Only create if there really are no tabs
if self.tab_view.get_n_pages() == 0: if self.tab_view.get_n_pages() == 0:
@ -269,7 +270,7 @@ class RosterWindow(Adw.ApplicationWindow):
return False # Don't repeat return False # Don't repeat
def _is_empty_new_request_tab(self): def _is_empty_new_request_tab(self) -> bool:
"""Check if current tab is an empty 'New Request' tab.""" """Check if current tab is an empty 'New Request' tab."""
if not self.current_tab_id: if not self.current_tab_id:
return False return False
@ -299,14 +300,14 @@ class RosterWindow(Adw.ApplicationWindow):
return is_empty return is_empty
def _find_tab_by_saved_request_id(self, saved_request_id): def _find_tab_by_saved_request_id(self, saved_request_id) -> Optional[RequestTab]:
"""Find a tab by its saved_request_id. Returns None if not found.""" """Find a tab by its saved_request_id. Returns None if not found."""
for tab in self.tab_manager.tabs: for tab in self.tab_manager.tabs:
if tab.saved_request_id == saved_request_id: if tab.saved_request_id == saved_request_id:
return tab return tab
return None return None
def _generate_copy_name(self, base_name): def _generate_copy_name(self, base_name: str) -> str:
"""Generate a unique copy name like 'ReqA (copy)', 'ReqA (copy 2)', etc.""" """Generate a unique copy name like 'ReqA (copy)', 'ReqA (copy 2)', etc."""
# Check if "Name (copy)" exists # Check if "Name (copy)" exists
existing_names = {tab.name for tab in self.tab_manager.tabs} existing_names = {tab.name for tab in self.tab_manager.tabs}
@ -323,7 +324,7 @@ class RosterWindow(Adw.ApplicationWindow):
return f"{base_name} (copy {counter})" return f"{base_name} (copy {counter})"
def _create_new_tab(self, name="New Request", request=None, saved_request_id=None, response=None, def _create_new_tab(self, name="New Request", request=None, saved_request_id=None, response=None,
project_id=None, selected_environment_id=None, scripts=None): project_id=None, selected_environment_id=None, scripts=None) -> str:
"""Create a new tab with RequestTabWidget.""" """Create a new tab with RequestTabWidget."""
# Create tab in tab manager # Create tab in tab manager
if not request: if not request:
@ -397,7 +398,7 @@ class RosterWindow(Adw.ApplicationWindow):
# Remove star from title # Remove star from title
page.set_title(tab.name) page.set_title(tab.name)
def _switch_to_tab(self, tab_id): def _switch_to_tab(self, tab_id: str) -> None:
"""Switch to a tab by its ID.""" """Switch to a tab by its ID."""
# Find the page for this tab # Find the page for this tab
for page, tab in self.page_to_tab.items(): for page, tab in self.page_to_tab.items():
@ -405,7 +406,7 @@ class RosterWindow(Adw.ApplicationWindow):
self.tab_view.set_selected_page(page) self.tab_view.set_selected_page(page)
return return
def _close_current_tab(self): def _close_current_tab(self) -> None:
"""Close the currently active tab.""" """Close the currently active tab."""
page = self.tab_view.get_selected_page() page = self.tab_view.get_selected_page()
if page: if page:
@ -415,7 +416,7 @@ class RosterWindow(Adw.ApplicationWindow):
"""Handle New Request button click.""" """Handle New Request button click."""
self._create_new_tab() self._create_new_tab()
def _create_actions(self): def _create_actions(self) -> None:
"""Create window-level actions.""" """Create window-level actions."""
# New tab shortcut (Ctrl+T) # New tab shortcut (Ctrl+T)
action = Gio.SimpleAction.new("new-tab", None) action = Gio.SimpleAction.new("new-tab", None)
@ -561,7 +562,7 @@ class RosterWindow(Adw.ApplicationWindow):
self.http_client.execute_request_async(substituted_request, callback, None) self.http_client.execute_request_async(substituted_request, callback, None)
# History and Project Management # History and Project Management
def _load_history(self): def _load_history(self) -> None:
"""Load history from file and populate list.""" """Load history from file and populate list."""
# Clear existing history items # Clear existing history items
while True: while True:
@ -748,7 +749,7 @@ class RosterWindow(Adw.ApplicationWindow):
vars_list = ', '.join(updated_vars) vars_list = ', '.join(updated_vars)
self._show_toast(f"Updated {len(updated_vars)} variable(s) in {env_name}: {vars_list}") self._show_toast(f"Updated {len(updated_vars)} variable(s) in {env_name}: {vars_list}")
def _show_toast(self, message): def _show_toast(self, message: str) -> None:
"""Show a toast notification.""" """Show a toast notification."""
toast = Adw.Toast() toast = Adw.Toast()
toast.set_title(message) toast.set_title(message)
@ -757,7 +758,7 @@ class RosterWindow(Adw.ApplicationWindow):
# Project Management Methods # Project Management Methods
def _load_projects(self): def _load_projects(self) -> None:
"""Load and display projects.""" """Load and display projects."""
# Clear existing # Clear existing
while child := self.projects_listbox.get_first_child(): while child := self.projects_listbox.get_first_child():