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

1""" 

2Selection Preservation Utilities for PyQt6 List Widgets 

3 

4Simple utility functions for preserving selection when updating QListWidget contents, 

5similar to the ButtonListWidget pattern used in the Textual TUI. 

6""" 

7 

8import logging 

9from typing import Callable, Any 

10from PyQt6.QtWidgets import QListWidget 

11from PyQt6.QtCore import Qt 

12 

13logger = logging.getLogger(__name__) 

14 

15 

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. 

24 

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 

35 

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) 

43 

44 # Execute the update 

45 update_func() 

46 

47 # Restore selection 

48 if current_id: 

49 restore_selection_by_id(list_widget, current_id, get_identifier_func) 

50 

51 

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. 

59 

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 

72 

73 

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. 

85 

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() 

96 

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()