all deselected statuses works as all statuses are selected

This commit is contained in:
Jakub Trllo 2024-07-09 14:34:23 +02:00
parent 89c55673ac
commit 01fa1a8c25
2 changed files with 132 additions and 66 deletions

View file

@ -1,3 +1,5 @@
from typing import List, Tuple, Optional, Iterable, Any
from qtpy import QtWidgets, QtCore, QtGui
from ayon_core.tools.utils.lib import (
@ -10,7 +12,7 @@ from ayon_core.tools.utils.constants import (
ITEM_IS_USER_TRISTATE,
)
CUSTOM_ITEM_TYPE = 0
VALUE_ITEM_TYPE = 0
STANDARD_ITEM_TYPE = 1
SEPARATOR_ITEM_TYPE = 2
@ -22,11 +24,11 @@ class CustomPaintDelegate(QtWidgets.QStyledItemDelegate):
def __init__(
self,
text_role,
short_text_role,
text_color_role,
icon_role,
item_type_role=None,
text_role: int,
short_text_role: int,
text_color_role: int,
icon_role: int,
item_type_role: Optional[int] = None,
parent=None
):
super().__init__(parent)
@ -42,7 +44,7 @@ class CustomPaintDelegate(QtWidgets.QStyledItemDelegate):
item_type = index.data(self._item_type_role)
if item_type is None:
item_type = CUSTOM_ITEM_TYPE
item_type = VALUE_ITEM_TYPE
if item_type == STANDARD_ITEM_TYPE:
super().paint(painter, option, index)
@ -290,15 +292,49 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
self._placeholder_text = placeholder
self._custom_text = None
self._all_unchecked_as_checked = True
def get_placeholder_text(self):
def all_unchecked_as_checked(self) -> bool:
return self._all_unchecked_as_checked
def set_all_unchecked_as_checked(self, value: bool):
"""Set if all unchecked items should be treated as checked.
Args:
value (bool): If True, all unchecked items will be treated
as checked.
"""
self._all_unchecked_as_checked = value
def get_placeholder_text(self) -> Optional[str]:
return self._placeholder_text
def set_placeholder_text(self, text):
def set_placeholder_text(self, text: Optional[str]):
"""Set the placeholder text.
Text shown when nothing is selected.
Args:
text (str | None): The placeholder text.
"""
if text == self._placeholder_text:
return
self._placeholder_text = text
self.repaint()
def set_custom_text(self, text):
def set_custom_text(self, text: Optional[str]):
"""Set the placeholder text.
Text always shown in combobox field.
Args:
text (str | None): The text. Use 'None' to reset to default.
"""
if text == self._custom_text:
return
self._custom_text = text
self.repaint()
@ -481,64 +517,78 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
def setItemCheckState(self, index, state):
self.setItemData(index, state, QtCore.Qt.CheckStateRole)
def set_value(self, values, role=None):
def set_value(self, values: Optional[Iterable[Any]], role: Optional[int] = None):
if role is None:
role = self._value_role
for idx in range(self.count()):
value = self.itemData(idx, role=role)
if value in values:
check_state = CHECKED_INT
else:
check_state = CHECKED_INT
if values is None or value not in values:
check_state = UNCHECKED_INT
self.setItemData(idx, check_state, QtCore.Qt.CheckStateRole)
self.repaint()
def get_value_info(
self,
role: Optional[int] = None,
propagate_all_unchecked_as_checked: bool = None
) -> List[Tuple[Any, bool]]:
"""Get the values and their checked state.
Args:
role (int | None): The role to get the values from.
If None, the default value role is used.
propagate_all_unchecked_as_checked (bool | None): If True,
all unchecked items will be treated as checked.
If None, the current value of
'propagate_all_unchecked_as_checked' is used.
Returns:
List[Tuple[Any, bool]]: The values and their checked state.
"""
if role is None:
role = self._value_role
if propagate_all_unchecked_as_checked is None:
propagate_all_unchecked_as_checked = (
self._all_unchecked_as_checked
)
items = []
all_unchecked = True
for idx in range(self.count()):
item_type = self.itemData(idx, role=self._item_type_role)
if item_type is not None and item_type != VALUE_ITEM_TYPE:
continue
state = checkstate_int_to_enum(
self.itemData(idx, role=QtCore.Qt.CheckStateRole)
)
checked = state == QtCore.Qt.Checked
if checked:
all_unchecked = False
items.append(
(self.itemData(idx, role=role), checked)
)
if propagate_all_unchecked_as_checked and all_unchecked:
items = [
(value, True)
for value, checked in items
]
return items
def get_value(self, role=None):
if role is None:
role = self._value_role
items = []
for idx in range(self.count()):
item_type = self.itemData(idx, role=self._item_type_role)
if item_type is not None and item_type != CUSTOM_ITEM_TYPE:
continue
state = checkstate_int_to_enum(
self.itemData(idx, role=QtCore.Qt.CheckStateRole)
)
if state == QtCore.Qt.Checked:
items.append(self.itemData(idx, role=role))
return items
def get_all_value_info(self, role=None):
if role is None:
role = self._value_role
items = []
for idx in range(self.count()):
item_type = self.itemData(idx, role=self._item_type_role)
if item_type is not None and item_type != CUSTOM_ITEM_TYPE:
continue
state = checkstate_int_to_enum(
self.itemData(idx, role=QtCore.Qt.CheckStateRole)
)
items.append(
(
self.itemData(idx, role=role),
state == QtCore.Qt.Checked
)
)
return items
def _get_checked_idx(self):
indexes = []
for idx in range(self.count()):
state = checkstate_int_to_enum(
self.itemData(idx, role=QtCore.Qt.CheckStateRole)
)
if state == QtCore.Qt.Checked:
indexes.append(idx)
return indexes
return [
value
for value, checked in self.get_value_info(role)
if checked
]
def wheelEvent(self, event):
event.ignore()
@ -555,6 +605,20 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
return super().keyPressEvent(event)
def _get_checked_idx(self) -> List[int]:
checked_indexes = []
for idx in range(self.count()):
item_type = self.itemData(idx, role=self._item_type_role)
if item_type is not None and item_type != VALUE_ITEM_TYPE:
continue
state = checkstate_int_to_enum(
self.itemData(idx, role=QtCore.Qt.CheckStateRole)
)
if state == QtCore.Qt.Checked:
checked_indexes.append(idx)
return checked_indexes
def _mouse_released_event_handle(
self, event, current_index, index_flags, state
):
@ -573,7 +637,6 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
return UNCHECKED_INT
return CHECKED_INT
def _key_press_event_handler(
self, event, current_index, index_flags, state
):

View file

@ -42,13 +42,16 @@ class StatusesQtModel(QtGui.QStandardItemModel):
self.refresh(None)
def get_placeholder_text(self):
return self._placeholder
def refresh(self, project_name):
# New project was selected
# status filter is reset to show all statuses
check_all = False
uncheck_all = False
if project_name != self._last_project:
self._last_project = project_name
check_all = True
uncheck_all = True
if project_name is None:
self._add_select_project_item()
@ -72,14 +75,14 @@ class StatusesQtModel(QtGui.QStandardItemModel):
if name in self._items_by_name:
is_new = False
item = self._items_by_name[name]
if check_all:
item.setCheckState(QtCore.Qt.Checked)
if uncheck_all:
item.setCheckState(QtCore.Qt.Unchecked)
items_to_remove.discard(name)
else:
is_new = True
item = QtGui.QStandardItem()
item.setData(ITEM_SUBTYPE_ROLE, STATUS_ITEM_TYPE)
item.setCheckState(QtCore.Qt.Checked)
item.setCheckState(QtCore.Qt.Unchecked)
item.setFlags(
QtCore.Qt.ItemIsEnabled
| QtCore.Qt.ItemIsSelectable
@ -148,8 +151,8 @@ class StatusesQtModel(QtGui.QStandardItemModel):
if self._empty_statuses_item is not None:
return
empty_statuses_item = QtGui.QStandardItem("No statuses..")
select_project_item = QtGui.QStandardItem("Select project..")
empty_statuses_item = QtGui.QStandardItem("No statuses...")
select_project_item = QtGui.QStandardItem("Select project...")
select_all_item = QtGui.QStandardItem("Select all")
deselect_all_item = QtGui.QStandardItem("Deselect all")
@ -291,9 +294,10 @@ class StatusesCombobox(CustomPaintMultiselectComboBox):
model=model,
parent=parent
)
self.set_placeholder_text("Statuses filter..")
self.set_placeholder_text("Statuses...")
self._model = model
self._last_project_name = None
self._fully_disabled_filter = False
controller.register_event_callback(
"selection.project.changed",
@ -310,7 +314,7 @@ class StatusesCombobox(CustomPaintMultiselectComboBox):
def _on_status_filter_change(self):
lines = ["Statuses filter"]
for item in self.get_all_value_info():
for item in self.get_value_info():
status_name, enabled = item
lines.append(f"{'' if enabled else ''} {status_name}")
@ -320,7 +324,6 @@ class StatusesCombobox(CustomPaintMultiselectComboBox):
project_name = event["project_name"]
self._last_project_name = project_name
self._model.refresh(project_name)
self._on_status_filter_change()
def _on_projects_refresh(self):
if self._last_project_name: