Coverage for openhcs/pyqt_gui/widgets/mixins/selection_preservation_mixin.py: 0.0%
36 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
1"""
2Selection Preservation Utilities for PyQt6 List Widgets
4Simple utility functions for preserving selection when updating QListWidget contents,
5similar to the ButtonListWidget pattern used in the Textual TUI.
6"""
8import logging
9from typing import Callable, Any
10from PyQt6.QtWidgets import QListWidget
11from PyQt6.QtCore import Qt
13logger = logging.getLogger(__name__)
16def preserve_selection_during_update(
17 list_widget: QListWidget,
18 get_identifier_func: Callable[[Any], str],
19 should_preserve_func: Callable[[], bool],
20 update_func: Callable[[], None]
21):
22 """
23 Execute a list update function while preserving selection.
25 Args:
26 list_widget: The QListWidget to update
27 get_identifier_func: Function to extract unique ID from item data
28 should_preserve_func: Function that returns True if selection should be preserved
29 update_func: Function that updates the list widget contents
30 """
31 if not should_preserve_func():
32 # No preservation needed, just update
33 update_func()
34 return
36 # Save current selection
37 current_item = list_widget.currentItem()
38 current_id = None
39 if current_item:
40 item_data = current_item.data(Qt.ItemDataRole.UserRole)
41 if item_data:
42 current_id = get_identifier_func(item_data)
44 # Execute the update
45 update_func()
47 # Restore selection
48 if current_id:
49 restore_selection_by_id(list_widget, current_id, get_identifier_func)
52def restore_selection_by_id(
53 list_widget: QListWidget,
54 item_id: str,
55 get_identifier_func: Callable[[Any], str]
56):
57 """
58 Restore selection to an item by its identifier.
60 Args:
61 list_widget: The QListWidget to update
62 item_id: Identifier of the item to select
63 get_identifier_func: Function to extract unique ID from item data
64 """
65 for i in range(list_widget.count()):
66 item = list_widget.item(i)
67 item_data = item.data(Qt.ItemDataRole.UserRole)
68 if item_data and get_identifier_func(item_data) == item_id:
69 list_widget.setCurrentRow(i)
70 logger.debug(f"Restored selection to: {item_id}")
71 break
74def handle_selection_change_with_prevention(
75 list_widget: QListWidget,
76 get_selected_func: Callable,
77 get_identifier_func: Callable[[Any], str],
78 should_preserve_func: Callable[[], bool],
79 get_current_id_func: Callable[[], str],
80 on_selected_func: Callable,
81 on_cleared_func: Callable
82):
83 """
84 Handle selection changes with automatic deselection prevention.
86 Args:
87 list_widget: The QListWidget to manage
88 get_selected_func: Function that returns currently selected items
89 get_identifier_func: Function to extract unique ID from item data
90 should_preserve_func: Function that returns True if deselection should be prevented
91 get_current_id_func: Function that returns the current selection ID
92 on_selected_func: Function to call when items are selected (receives selected items)
93 on_cleared_func: Function to call when selection is cleared (no args)
94 """
95 selected_items = get_selected_func()
97 if selected_items:
98 # Normal selection
99 on_selected_func(selected_items)
100 elif should_preserve_func():
101 # Prevent deselection - re-select the current item
102 current_id = get_current_id_func()
103 if current_id:
104 restore_selection_by_id(list_widget, current_id, get_identifier_func)
105 return
106 else:
107 # Allow clearing selection
108 on_cleared_func()