Add type annotations to window.py

This commit is contained in:
Pavel Baksy 2026-01-05 11:31:59 +01:00
parent 833bcb5e6e
commit a8a372d83d

View File

@ -20,6 +20,7 @@
import gi
gi.require_version('GtkSource', '5')
from gi.repository import Adw, Gtk, GLib, Gio, GtkSource
from typing import Dict, Optional
from .models import HttpRequest, HttpResponse, HistoryEntry, RequestTab
from .http_client import HttpClient
from .history_manager import HistoryManager
@ -67,13 +68,13 @@ class RosterWindow(Adw.ApplicationWindow):
self.tab_manager = TabManager()
# Map AdwTabPage to tab data
self.page_to_widget = {} # AdwTabPage -> RequestTabWidget
self.page_to_tab = {} # AdwTabPage -> RequestTab
self.current_tab_id = None
self.page_to_widget: Dict[Adw.TabPage, RequestTabWidget] = {}
self.page_to_tab: Dict[Adw.TabPage, RequestTab] = {}
self.current_tab_id: Optional[str] = None
# Track recently updated variables for visual marking
# Format: {project_id: {var_name: timestamp}}
self.recently_updated_variables = {}
self.recently_updated_variables: Dict[str, Dict[str, str]] = {}
# Connect to tab view signals
self.tab_view.connect('close-page', self._on_tab_close_page)
@ -96,7 +97,7 @@ class RosterWindow(Adw.ApplicationWindow):
# Create first 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."""
# Check if any tabs have unsaved changes
modified_tabs = []
@ -131,13 +132,13 @@ class RosterWindow(Adw.ApplicationWindow):
# No unsaved changes, allow closing
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."""
if response == "close":
# User confirmed - close the window
self.destroy()
def _setup_custom_css(self):
def _setup_custom_css(self) -> None:
"""Setup custom CSS for UI styling."""
css_provider = Gtk.CssProvider()
css_provider.load_from_data(b"""
@ -186,12 +187,12 @@ class RosterWindow(Adw.ApplicationWindow):
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)
def _setup_tab_system(self):
def _setup_tab_system(self) -> None:
"""Set up the tab system."""
# Connect new request button
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."""
page = tab_view.get_selected_page()
if not page:
@ -202,7 +203,7 @@ class RosterWindow(Adw.ApplicationWindow):
if tab:
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."""
# Get the RequestTab and widget for this page
tab = self.page_to_tab.get(page)
@ -261,7 +262,7 @@ class RosterWindow(Adw.ApplicationWindow):
return False # Allow close
def _create_new_tab_once(self):
def _create_new_tab_once(self) -> bool:
"""Create a new tab (one-time callback)."""
# Only create if there really are no tabs
if self.tab_view.get_n_pages() == 0:
@ -269,7 +270,7 @@ class RosterWindow(Adw.ApplicationWindow):
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."""
if not self.current_tab_id:
return False
@ -299,14 +300,14 @@ class RosterWindow(Adw.ApplicationWindow):
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."""
for tab in self.tab_manager.tabs:
if tab.saved_request_id == saved_request_id:
return tab
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."""
# Check if "Name (copy)" exists
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})"
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 tab in tab manager
if not request:
@ -397,7 +398,7 @@ class RosterWindow(Adw.ApplicationWindow):
# Remove star from title
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."""
# Find the page for this tab
for page, tab in self.page_to_tab.items():
@ -405,7 +406,7 @@ class RosterWindow(Adw.ApplicationWindow):
self.tab_view.set_selected_page(page)
return
def _close_current_tab(self):
def _close_current_tab(self) -> None:
"""Close the currently active tab."""
page = self.tab_view.get_selected_page()
if page:
@ -415,7 +416,7 @@ class RosterWindow(Adw.ApplicationWindow):
"""Handle New Request button click."""
self._create_new_tab()
def _create_actions(self):
def _create_actions(self) -> None:
"""Create window-level actions."""
# New tab shortcut (Ctrl+T)
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)
# History and Project Management
def _load_history(self):
def _load_history(self) -> None:
"""Load history from file and populate list."""
# Clear existing history items
while True:
@ -748,7 +749,7 @@ class RosterWindow(Adw.ApplicationWindow):
vars_list = ', '.join(updated_vars)
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."""
toast = Adw.Toast()
toast.set_title(message)
@ -757,7 +758,7 @@ class RosterWindow(Adw.ApplicationWindow):
# Project Management Methods
def _load_projects(self):
def _load_projects(self) -> None:
"""Load and display projects."""
# Clear existing
while child := self.projects_listbox.get_first_child():