reworked card view for easier maintanance of widget updates

This commit is contained in:
Jakub Trllo 2025-07-29 18:19:41 +02:00
parent d8392a2133
commit 6bc3e5130e

View file

@ -23,7 +23,7 @@ from __future__ import annotations
import re
import collections
from typing import Dict
from typing import Optional
from qtpy import QtWidgets, QtCore
@ -87,7 +87,6 @@ class BaseGroupWidget(QtWidgets.QWidget):
self._group = group_name
self._widgets_by_id = {}
self._ordered_item_ids = []
self._label_widget = label_widget
self._content_layout = layout
@ -102,48 +101,25 @@ class BaseGroupWidget(QtWidgets.QWidget):
return self._group
def get_widget_by_item_id(self, item_id):
"""Get instance widget by its id."""
def set_widgets(
self,
widgets_by_id: dict[str, QtWidgets.QWidget],
ordered_ids: list[str],
) -> None:
self._remove_all_except(set(self._widgets_by_id))
idx = 1
for item_id in ordered_ids:
widget = widgets_by_id[item_id]
self._content_layout.insertWidget(idx, widget)
self._widgets_by_id[item_id] = widget
idx += 1
return self._widgets_by_id.get(item_id)
def get_selected_item_ids(self):
"""Selected instance ids.
Returns:
Set[str]: Instance ids that are selected.
"""
return {
instance_id
for instance_id, widget in self._widgets_by_id.items()
if widget.is_selected
}
def get_selected_widgets(self):
"""Access to widgets marked as selected.
Returns:
List[InstanceCardWidget]: Instance widgets that are selected.
"""
return [
widget
for instance_id, widget in self._widgets_by_id.items()
if widget.is_selected
]
def get_ordered_widgets(self):
"""Get instance ids in order as are shown in ui.
Returns:
List[str]: Instance ids.
"""
return [
self._widgets_by_id[instance_id]
for instance_id in self._ordered_item_ids
]
def take_widgets(self, widget_ids: set[str]):
for widget_id in widget_ids:
widget = self._widgets_by_id.pop(widget_id)
index = self._content_layout.indexOf(widget)
if index >= 0:
self._content_layout.takeAt(index)
def _remove_all_except(self, item_ids):
item_ids = set(item_ids)
@ -160,149 +136,6 @@ class BaseGroupWidget(QtWidgets.QWidget):
self._content_layout.removeWidget(widget)
widget.deleteLater()
def _update_ordered_item_ids(self):
ordered_item_ids = []
for idx in range(self._content_layout.count()):
if idx > 0:
item = self._content_layout.itemAt(idx)
widget = item.widget()
if widget is not None:
ordered_item_ids.append(widget.id)
self._ordered_item_ids = ordered_item_ids
def _on_widget_selection(self, instance_id, group_id, selection_type):
self.selected.emit(instance_id, group_id, selection_type)
def set_active_toggle_enabled(self, enabled):
for widget in self._widgets_by_id.values():
if isinstance(widget, InstanceCardWidget):
widget.set_active_toggle_enabled(enabled)
class ConvertorItemsGroupWidget(BaseGroupWidget):
def update_items(self, items_by_id):
items_by_label = collections.defaultdict(list)
for item in items_by_id.values():
items_by_label[item.label].append(item)
# Remove instance widgets that are not in passed instances
self._remove_all_except(items_by_id.keys())
# Sort instances by product name
sorted_labels = list(sorted(items_by_label.keys()))
# Add new instances to widget
widget_idx = 1
for label in sorted_labels:
for item in items_by_label[label]:
if item.id in self._widgets_by_id:
widget = self._widgets_by_id[item.id]
widget.update_item(item)
else:
widget = ConvertorItemCardWidget(item, self)
widget.selected.connect(self._on_widget_selection)
widget.double_clicked.connect(self.double_clicked)
self._widgets_by_id[item.id] = widget
self._content_layout.insertWidget(widget_idx, widget)
widget_idx += 1
self._update_ordered_item_ids()
class InstanceGroupWidget(BaseGroupWidget):
"""Widget wrapping instances under group."""
active_changed = QtCore.Signal(str, str, bool)
def __init__(self, group_icons, *args, **kwargs):
super().__init__(*args, **kwargs)
self._group_icons = group_icons
def update_icons(self, group_icons):
self._group_icons = group_icons
def update_instance_values(
self,
context_info_by_id,
instance_items_by_id,
instance_ids,
parent_is_active_by_id,
):
"""Trigger update on instance widgets."""
for instance_id, widget in self._widgets_by_id.items():
if instance_ids is not None and instance_id not in instance_ids:
continue
widget.update_instance(
instance_items_by_id[instance_id],
context_info_by_id[instance_id],
parent_is_active_by_id[instance_id],
)
def update_instances(
self,
instances: list[InstanceItem],
context_info_by_id: dict[str, InstanceContextInfo],
parent_active_by_id: dict[str, bool]
):
"""Update instances for the group.
Args:
instances (list[InstanceItem]): List of instances in
CreateContext.
context_info_by_id (dict[str, InstanceContextInfo]): Instance
context info by instance id.
parent_active_by_id (dict[str, bool]): Instance has active parent.
"""
# Store instances by id and by product name
instances_by_id = {}
instances_by_product_name = collections.defaultdict(list)
for instance in instances:
instances_by_id[instance.id] = instance
product_name = instance.product_name
instances_by_product_name[product_name].append(instance)
# Remove instance widgets that are not in passed instances
self._remove_all_except(instances_by_id.keys())
# Sort instances by product name
sorted_product_names = list(sorted(instances_by_product_name.keys()))
# Add new instances to widget
widget_idx = 1
for product_names in sorted_product_names:
for instance in instances_by_product_name[product_names]:
context_info = context_info_by_id[instance.id]
parent_is_active = parent_active_by_id[instance.id]
if instance.id in self._widgets_by_id:
widget = self._widgets_by_id[instance.id]
widget.update_instance(
instance, context_info, parent_is_active
)
else:
group_icon = self._group_icons[instance.creator_identifier]
widget = InstanceCardWidget(
instance,
context_info,
parent_is_active,
group_icon,
self
)
widget.selected.connect(self._on_widget_selection)
widget.active_changed.connect(self._on_active_changed)
widget.double_clicked.connect(self.double_clicked)
self._widgets_by_id[instance.id] = widget
self._content_layout.insertWidget(widget_idx, widget)
widget_idx += 1
self._update_ordered_item_ids()
def _on_active_changed(self, instance_id, value):
self.active_changed.emit(self.group_name, instance_id, value)
class CardWidget(BaseClickableFrame):
"""Clickable card used as bigger button."""
@ -423,6 +256,10 @@ class ConvertorItemCardWidget(CardWidget):
self._icon_widget = icon_widget
self._label_widget = label_widget
def update_item(self, item):
self._id = item.id
self.identifier = item.identifier
class InstanceCardWidget(CardWidget):
"""Card widget representing instance."""
@ -433,7 +270,7 @@ class InstanceCardWidget(CardWidget):
self,
instance,
context_info,
parent_is_active: bool,
is_parent_active: bool,
group_icon,
parent: BaseGroupWidget,
):
@ -444,7 +281,7 @@ class InstanceCardWidget(CardWidget):
self._id = instance.id
self._group_identifier = instance.group_label
self._group_icon = group_icon
self._parent_is_active = parent_is_active
self._is_parent_active = is_parent_active
self._toggle_is_enabled = True
self._last_product_name = None
@ -499,18 +336,26 @@ class InstanceCardWidget(CardWidget):
self._active_checkbox = active_checkbox
self._expand_btn = expand_btn
self._update_instance_values(context_info, parent_is_active)
self._update_instance_values(context_info, is_parent_active)
def set_active_toggle_enabled(self, enabled):
def set_active_toggle_enabled(self, enabled: bool) -> None:
if self._toggle_is_enabled is enabled:
return
self._toggle_is_enabled = enabled
self._update_checkbox_state()
@property
def is_active(self):
def is_active(self) -> bool:
return self._active_checkbox.isChecked()
def is_parent_active(self) -> bool:
return self._is_parent_active
def set_parent_active(self, is_active: bool) -> None:
if self._is_parent_active is is_active:
return
self._is_parent_active = is_active
self._update_checkbox_state()
def is_checkbox_enabled(self) -> bool:
"""Checkbox can be changed by user."""
return (
@ -518,10 +363,10 @@ class InstanceCardWidget(CardWidget):
and not self.instance.is_mandatory
)
def update_instance(self, instance, context_info, parent_is_active):
def update_instance(self, instance, context_info, is_parent_active):
"""Update instance object and update UI."""
self.instance = instance
self._update_instance_values(context_info, parent_is_active)
self._update_instance_values(context_info, is_parent_active)
def _validate_context(self, context_info):
valid = context_info.is_valid
@ -560,9 +405,9 @@ class InstanceCardWidget(CardWidget):
QtCore.Qt.NoTextInteraction
)
def _update_instance_values(self, context_info, parent_is_active):
def _update_instance_values(self, context_info, is_parent_active):
"""Update instance data"""
self._parent_is_active = parent_is_active
self._is_parent_active = is_parent_active
self._update_product_name()
self._update_checkbox_state()
self._validate_context(context_info)
@ -587,7 +432,7 @@ class InstanceCardWidget(CardWidget):
def _used_parent_active(self) -> bool:
parent_enabled = True
if self.instance.parent_flags & ParentFlags.share_active:
parent_enabled = self._parent_is_active
parent_enabled = self._is_parent_active
return parent_enabled
def _set_expanded(self, expanded=None):
@ -654,11 +499,20 @@ class InstanceCardView(AbstractInstanceView):
self._content_layout = content_layout
self._content_widget = content_widget
self._context_widget = None
self._convertor_items_group = None
self._active_toggle_enabled = True
self._widgets_by_group: Dict[str, InstanceGroupWidget] = {}
self._active_toggle_enabled: bool = True
self._convertors_group: Optional[BaseGroupWidget] = None
self._convertor_widgets_by_id: dict[str, ConvertorItemCardWidget] = {}
self._convertor_ids: list[str] = []
self._group_name_by_instance_id: dict[str, str] = {}
self._instance_ids_by_group_name: dict[str, list[str]] = (
collections.defaultdict(list)
)
self._ordered_groups = []
self._group_icons = {}
self._context_widget: Optional[ContextCardWidget] = None
self._widgets_by_id: dict[str, InstanceCardWidget] = {}
self._widgets_by_group: dict[str, BaseGroupWidget] = {}
self._instance_ids_by_parent_id = collections.defaultdict(set)
@ -694,7 +548,7 @@ class InstanceCardView(AbstractInstanceView):
continue
instance_id = widget.id
is_active = widget.is_active
is_active = widget.is_active()
if value == -1:
active_state_by_id[instance_id] = not is_active
continue
@ -731,12 +585,17 @@ class InstanceCardView(AbstractInstanceView):
):
output.append(self._context_widget)
if self._convertor_items_group is not None:
output.extend(self._convertor_items_group.get_selected_widgets())
output.extend(
widget
for widget in self._convertor_widgets_by_id.values()
if widget.is_selected
)
for group_widget in self._widgets_by_group.values():
for widget in group_widget.get_selected_widgets():
output.append(widget)
output.extend(
widget
for widget in self._widgets_by_id.values()
if widget.is_selected
)
return output
def _get_selected_instance_ids(self):
@ -747,11 +606,17 @@ class InstanceCardView(AbstractInstanceView):
):
output.append(CONTEXT_ID)
if self._convertor_items_group is not None:
output.extend(self._convertor_items_group.get_selected_item_ids())
output.extend(
conv_id
for conv_id, widget in self._widgets_by_id.items()
if widget.is_selected
)
for group_widget in self._widgets_by_group.values():
output.extend(group_widget.get_selected_item_ids())
output.extend(
widget.id
for instance_id, widget in self._widgets_by_id.items()
if widget.is_selected
)
return output
def refresh(self):
@ -759,13 +624,14 @@ class InstanceCardView(AbstractInstanceView):
self._make_sure_context_widget_exists()
self._update_convertor_items_group()
self._update_convertors_group()
context_info_by_id = self._controller.get_instances_context_info()
# Prepare instances by group and identifiers by group
instances_by_group = collections.defaultdict(list)
identifiers_by_group = collections.defaultdict(set)
identifiers: set[str] = set()
instances_by_id = {}
instance_ids_by_parent_id = collections.defaultdict(set)
instance_items = self._controller.get_instance_items()
@ -775,6 +641,7 @@ class InstanceCardView(AbstractInstanceView):
identifiers_by_group[group_name].add(
instance.creator_identifier
)
identifiers.add(instance.creator_identifier)
instances_by_id[instance.id] = instance
instance_ids_by_parent_id[instance.parent_instance_id].add(
instance.id
@ -787,28 +654,67 @@ class InstanceCardView(AbstractInstanceView):
_queue = collections.deque()
_queue.append((None, True))
while _queue:
parent_id, parent_is_active = _queue.popleft()
parent_id, is_parent_active = _queue.popleft()
for instance_id in instance_ids_by_parent_id[parent_id]:
instance_item = instances_by_id[instance_id]
is_active = instance_item.is_active
if (
not parent_is_active
not is_parent_active
and instance_item.parent_flags & ParentFlags.share_active
):
is_active = False
parent_active_by_id[instance_id] = parent_is_active
parent_active_by_id[instance_id] = is_parent_active
_queue.append(
(instance_id, is_active)
)
self._instance_ids_by_parent_id = instance_ids_by_parent_id
# Remove groups that were not found in passed instances
groups_to_remove = (
set(self._widgets_by_group) - set(instances_by_group)
)
# Remove groups that were not found in apassed instances
for group_name in tuple(self._widgets_by_group.keys()):
if group_name in instances_by_group:
continue
# Sort groups
sorted_group_names = list(sorted(instances_by_group.keys()))
# Keep track of widget indexes
# - we start with 1 because Context item as at the top
widget_idx = 1
if self._convertors_group is not None:
widget_idx += 1
group_by_instance_id = {}
instance_ids_by_group_name = collections.defaultdict(list)
group_icons = {
identifier: self._controller.get_creator_icon(identifier)
for identifier in identifiers
}
for group_name in sorted_group_names:
if group_name not in self._widgets_by_group:
group_widget = BaseGroupWidget(
group_name, self._content_widget
)
group_widget.double_clicked.connect(self.double_clicked)
self._content_layout.insertWidget(widget_idx, group_widget)
self._widgets_by_group[group_name] = group_widget
widget_idx += 1
instances = instances_by_group[group_name]
for instance in instances:
group_by_instance_id[instance.id] = group_name
instance_ids_by_group_name[group_name].append(instance.id)
self._update_instances(
group_name,
instances,
context_info_by_id,
parent_active_by_id,
group_icons,
)
# Remove empty groups
for group_name in groups_to_remove:
widget = self._widgets_by_group.pop(group_name)
widget.setVisible(False)
self._content_layout.removeWidget(widget)
@ -817,63 +723,85 @@ class InstanceCardView(AbstractInstanceView):
if group_name in self._explicitly_selected_groups:
self._explicitly_selected_groups.remove(group_name)
# Sort groups
sorted_group_names = list(sorted(instances_by_group.keys()))
# Keep track of widget indexes
# - we start with 1 because Context item as at the top
widget_idx = 1
if self._convertor_items_group is not None:
widget_idx += 1
for group_name in sorted_group_names:
group_icons = {
identifier: self._controller.get_creator_icon(identifier)
for identifier in identifiers_by_group[group_name]
}
if group_name in self._widgets_by_group:
group_widget = self._widgets_by_group[group_name]
group_widget.update_icons(group_icons)
else:
group_widget = InstanceGroupWidget(
group_icons, group_name, self._content_widget
)
group_widget.active_changed.connect(self._on_active_changed)
group_widget.selected.connect(self._on_widget_selection)
group_widget.double_clicked.connect(self.double_clicked)
self._content_layout.insertWidget(widget_idx, group_widget)
self._widgets_by_group[group_name] = group_widget
widget_idx += 1
group_widget.update_instances(
instances_by_group[group_name],
context_info_by_id,
parent_active_by_id
)
group_widget.set_active_toggle_enabled(
self._active_toggle_enabled
)
self._update_ordered_group_names()
self._instance_ids_by_parent_id = instance_ids_by_parent_id
self._group_name_by_instance_id = group_by_instance_id
self._instance_ids_by_group_name = instance_ids_by_group_name
self._ordered_groups = sorted_group_names
def has_items(self) -> bool:
if self._convertor_items_group is not None:
if self._convertors_group is not None:
return True
if self._widgets_by_group:
if self._widgets_by_id:
return True
return False
def _update_ordered_group_names(self):
ordered_group_names = [CONTEXT_GROUP]
for idx in range(self._content_layout.count()):
if idx > 0:
item = self._content_layout.itemAt(idx)
group_widget = item.widget()
if group_widget is not None:
ordered_group_names.append(group_widget.group_name)
def _update_instances(
self,
group_name: str,
instances: list[InstanceItem],
context_info_by_id: dict[str, InstanceContextInfo],
parent_active_by_id: dict[str, bool],
group_icons: dict[str, str],
):
"""Update instances for the group.
self._ordered_groups = ordered_group_names
Args:
instances (list[InstanceItem]): List of instances in
CreateContext.
context_info_by_id (dict[str, InstanceContextInfo]): Instance
context info by instance id.
parent_active_by_id (dict[str, bool]): Instance has active parent.
"""
# Store instances by id and by product name
group_widget: BaseGroupWidget = self._widgets_by_group[group_name]
instances_by_id = {}
instances_by_product_name = collections.defaultdict(list)
for instance in instances:
instances_by_id[instance.id] = instance
product_name = instance.product_name
instances_by_product_name[product_name].append(instance)
to_remove_ids = set(
self._instance_ids_by_group_name[group_name]
) - set(instances_by_id)
group_widget.take_widgets(to_remove_ids)
# Sort instances by product name
sorted_product_names = list(sorted(instances_by_product_name.keys()))
# Add new instances to widget
ordered_ids = []
widgets_by_id = {}
for product_names in sorted_product_names:
for instance in instances_by_product_name[product_names]:
context_info = context_info_by_id[instance.id]
is_parent_active = parent_active_by_id[instance.id]
if instance.id in self._widgets_by_id:
widget = self._widgets_by_id[instance.id]
widget.update_instance(
instance, context_info, is_parent_active
)
else:
group_icon = group_icons[instance.creator_identifier]
widget = InstanceCardWidget(
instance,
context_info,
is_parent_active,
group_icon,
group_widget
)
widget.selected.connect(self._on_widget_selection)
widget.active_changed.connect(self._on_active_changed)
widget.double_clicked.connect(self.double_clicked)
self._widgets_by_id[instance.id] = widget
ordered_ids.append(instance.id)
widgets_by_id[instance.id] = widget
group_widget.set_widgets(widgets_by_id, ordered_ids)
return ordered_ids
def _make_sure_context_widget_exists(self):
# Create context item if is not already existing
@ -891,28 +819,65 @@ class InstanceCardView(AbstractInstanceView):
self.selection_changed.emit()
self._content_layout.insertWidget(0, widget)
def _update_convertor_items_group(self):
def _update_convertors_group(self):
convertor_items = self._controller.get_convertor_items()
if not convertor_items and self._convertor_items_group is None:
if not convertor_items and self._convertors_group is None:
return
ids_to_remove = set(self._convertor_widgets_by_id) - set(
convertor_items
)
if ids_to_remove:
self._convertors_group.take_widgets(ids_to_remove)
for conv_id in ids_to_remove:
widget = self._convertor_widgets_by_id.pop(conv_id)
widget.setVisible(False)
widget.deleteLater()
if not convertor_items:
self._convertor_items_group.setVisible(False)
self._content_layout.removeWidget(self._convertor_items_group)
self._convertor_items_group.deleteLater()
self._convertor_items_group = None
self._convertors_group.setVisible(False)
self._content_layout.removeWidget(self._convertors_group)
self._convertors_group.deleteLater()
self._convertors_group = None
self._convertor_ids = []
self._convertor_widgets_by_id = {}
return
if self._convertor_items_group is None:
group_widget = ConvertorItemsGroupWidget(
if self._convertors_group is None:
group_widget = BaseGroupWidget(
CONVERTOR_ITEM_GROUP, self._content_widget
)
group_widget.selected.connect(self._on_widget_selection)
group_widget.double_clicked.connect(self.double_clicked)
self._content_layout.insertWidget(1, group_widget)
self._convertor_items_group = group_widget
self._convertors_group = group_widget
self._convertor_items_group.update_items(convertor_items)
# TODO create convertor widgets
items_by_label = collections.defaultdict(list)
for item in convertor_items.values():
items_by_label[item.label].append(item)
# Sort instances by product name
sorted_labels = list(sorted(items_by_label.keys()))
# Add new instances to widget
convertor_ids: list[str] = []
widgets_by_id: dict[str, ConvertorItemCardWidget] = {}
for label in sorted_labels:
for item in items_by_label[label]:
convertor_ids.append(item.id)
if item.id in self._convertor_widgets_by_id:
widget = self._convertor_widgets_by_id[item.id]
widget.update_item(item)
else:
widget = ConvertorItemCardWidget(item, self)
widget.selected.connect(self._on_widget_selection)
widget.double_clicked.connect(self.double_clicked)
self._convertor_widgets_by_id[item.id] = widget
widgets_by_id[item.id] = widget
self._convertors_group.set_widgets(widgets_by_id, convertor_ids)
self._convertor_ids = convertor_ids
self._convertor_widgets_by_id = widgets_by_id
def refresh_instance_states(self, instance_ids=None):
"""Trigger update of instances on group widgets."""
@ -922,36 +887,57 @@ class InstanceCardView(AbstractInstanceView):
instance_items_by_id = self._controller.get_instance_items_by_id(
instance_ids
)
instance_ids = set(instance_items_by_id)
instance_ids: set[str] = set(instance_items_by_id)
available_ids: set[str] = set(instance_items_by_id)
discarted_ids: set[str] = set()
parent_is_active_by_id = {
instance_id: False
for instance_id in instance_ids
}
discarted_ids = set()
_queue = collections.deque()
_queue.append((None, True))
_queue.append((set(self._instance_ids_by_parent_id[None]), True))
while _queue:
parent_id, parent_is_active = _queue.pop()
for instance_id in self._instance_ids_by_parent_id[parent_id]:
if not instance_ids:
break
chilren_ids, is_parent_active = _queue.pop()
for instance_id in chilren_ids:
widget = self._widgets_by_id[instance_id]
add_children = False
if instance_id in instance_ids:
add_children = (
is_parent_active is not widget.is_parent_active()
)
if instance_id in available_ids:
available_ids.discard(instance_id)
widget.update_instance(
instance_items_by_id[instance_id],
context_info_by_id[instance_id],
is_parent_active,
)
else:
# TODO implement 'set_parent_active'
widget.set_parent_active(is_parent_active)
instance_ids.discard(instance_id)
discarted_ids.add(instance_id)
# TODO there is no way how to get current state
parent_is_active_by_id[instance_id] = parent_is_active
for widget in self._widgets_by_group.values():
widget.update_instance_values(
context_info_by_id,
instance_items_by_id,
instance_ids,
parent_is_active_by_id,
)
if not instance_ids:
break
def _on_active_changed(self, group_name, instance_id, value):
group_widget = self._widgets_by_group[group_name]
instance_widget = group_widget.get_widget_by_item_id(instance_id)
if not add_children:
continue
children_ids = self._instance_ids_by_parent_id[instance_id]
children = {
child_id
for child_id in children_ids
if child_id not in discarted_ids
}
if children:
_queue.append((children, widget.is_active()))
def _on_active_changed(self, instance_id, value):
instance_widget = self._widgets_by_id[instance_id]
active_state_by_id = {}
if not instance_widget.is_selected:
active_state_by_id[instance_id] = value
@ -973,10 +959,9 @@ class InstanceCardView(AbstractInstanceView):
else:
if group_name == CONVERTOR_ITEM_GROUP:
group_widget = self._convertor_items_group
new_widget = self._convertor_widgets_by_id[instance_id]
else:
group_widget = self._widgets_by_group[group_name]
new_widget = group_widget.get_widget_by_item_id(instance_id)
new_widget = self._widgets_by_id[instance_id]
if selection_type == SelectionTypes.clear:
self._select_item_clear(instance_id, group_name, new_widget)
@ -1021,11 +1006,21 @@ class InstanceCardView(AbstractInstanceView):
if instance_id == CONTEXT_ID:
remove_group = True
else:
has_selected_items = False
if group_name == CONVERTOR_ITEM_GROUP:
group_widget = self._convertor_items_group
for widget in self._convertor_widgets_by_id.values():
if widget.is_selected:
has_selected_items = True
break
else:
group_widget = self._widgets_by_group[group_name]
if not group_widget.get_selected_widgets():
group_ids = self._instance_ids_by_group_name[group_name]
for instance_id in group_ids:
widget = self._widgets_by_id[instance_id]
if widget.is_selected:
has_selected_items = True
break
if not has_selected_items:
remove_group = True
if remove_group:
@ -1137,10 +1132,16 @@ class InstanceCardView(AbstractInstanceView):
sorted_widgets = [self._context_widget]
else:
if name == CONVERTOR_ITEM_GROUP:
group_widget = self._convertor_items_group
sorted_widgets = [
self._convertor_widgets_by_id[conv_id]
for conv_id in self._convertor_ids
]
else:
group_widget = self._widgets_by_group[name]
sorted_widgets = group_widget.get_ordered_widgets()
instance_ids = self._instance_ids_by_group_name[name]
sorted_widgets = [
self._widgets_by_id[instance_id]
for instance_id in instance_ids
]
# Change selection based on explicit selection if start group
# was not passed yet
@ -1298,12 +1299,19 @@ class InstanceCardView(AbstractInstanceView):
is_convertor_group = group_name == CONVERTOR_ITEM_GROUP
if is_convertor_group:
group_widget = self._convertor_items_group
sorted_widgets = [
self._convertor_widgets_by_id[conv_id]
for conv_id in self._convertor_ids
]
else:
group_widget = self._widgets_by_group[group_name]
instance_ids = self._instance_ids_by_group_name[group_name]
sorted_widgets = [
self._widgets_by_id[instance_id]
for instance_id in instance_ids
]
group_selected = False
for widget in group_widget.get_ordered_widgets():
for widget in sorted_widgets:
select = False
if is_convertor_group:
is_in = widget.identifier in s_convertor_identifiers
@ -1325,5 +1333,5 @@ class InstanceCardView(AbstractInstanceView):
if self._active_toggle_enabled is enabled:
return
self._active_toggle_enabled = enabled
for group_widget in self._widgets_by_group.values():
group_widget.set_active_toggle_enabled(enabled)
for widget in self._widgets_by_id.values():
widget.set_active_toggle_enabled(enabled)