fix status filtering after refresh

This commit is contained in:
Jakub Trllo 2024-07-10 12:53:22 +02:00
parent ee7c340b77
commit 88d6a848d3
3 changed files with 81 additions and 38 deletions

View file

@ -1,4 +1,7 @@
import numbers
import uuid
from typing import Dict, Set
from qtpy import QtWidgets, QtCore, QtGui
from ayon_core.tools.utils.lib import format_version
@ -74,7 +77,7 @@ class VersionsFilterModel(QtCore.QSortFilterProxyModel):
class VersionComboBox(QtWidgets.QComboBox):
value_changed = QtCore.Signal(str)
value_changed = QtCore.Signal()
def __init__(self, product_id, parent):
super().__init__(parent)
@ -105,6 +108,11 @@ class VersionComboBox(QtWidgets.QComboBox):
if self.currentIndex() != 0:
self.setCurrentIndex(0)
def all_versions_filtered_out(self):
if self._items_by_id:
return self.count() == 0
return False
def update_versions(self, version_items, current_version_id):
self.blockSignals(True)
version_items = list(version_items)
@ -129,7 +137,13 @@ class VersionComboBox(QtWidgets.QComboBox):
if value == self._current_id:
return
self._current_id = value
self.value_changed.emit(self._product_id)
self.value_changed.emit()
class EditorInfo:
def __init__(self, widget):
self.widget = widget
self.added = False
class VersionDelegate(QtWidgets.QStyledItemDelegate):
@ -139,7 +153,8 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._editor_by_product_id = {}
self._editor_by_id: Dict[str, EditorInfo] = {}
self._statuses_filter = None
def displayText(self, value, locale):
@ -149,8 +164,8 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
def set_statuses_filter(self, status_names):
self._statuses_filter = set(status_names)
for widget in self._editor_by_product_id.values():
widget.set_statuses_filter(status_names)
for info in self._editor_by_id.values():
info.widget.set_statuses_filter(status_names)
def paint(self, painter, option, index):
fg_color = index.data(QtCore.Qt.ForegroundRole)
@ -209,27 +224,21 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
if not product_id:
return
item_id = uuid.uuid4().hex
editor = VersionComboBox(product_id, parent)
self._editor_by_product_id[product_id] = editor
editor.value_changed.connect(self._on_editor_change)
editor.set_statuses_filter(self._statuses_filter)
editor.setProperty("itemId", item_id)
def on_destroy(obj):
self._on_destroy(product_id)
self._editor_by_id[item_id] = EditorInfo(editor)
editor.destroyed.connect(on_destroy)
def editor_changed():
self._on_editor_change(item_id)
editor.value_changed.connect(editor_changed)
editor.destroyed.connect(self._on_destroy)
return editor
def _on_editor_change(self, product_id):
editor = self._editor_by_product_id[product_id]
# Update model data
self.commitData.emit(editor)
def _on_destroy(self, product_id):
self._editor_by_product_id.pop(product_id, None)
def setEditorData(self, editor, index):
editor.clear()
@ -237,6 +246,10 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
versions = index.data(VERSION_NAME_EDIT_ROLE) or []
version_id = index.data(VERSION_ID_ROLE)
editor.update_versions(versions, version_id)
editor.set_statuses_filter(self._statuses_filter)
item_id = editor.property("itemId")
self._editor_by_id[item_id].added = True
def setModelData(self, editor, model, index):
"""Apply the integer version back in the model"""
@ -244,6 +257,18 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
version_id = editor.itemData(editor.currentIndex())
model.setData(index, version_id, VERSION_NAME_EDIT_ROLE)
def _on_editor_change(self, item_id):
info = self._editor_by_id.get(item_id)
if info is None or not info.added:
return
editor = info.widget
self.commitData.emit(editor)
def _on_destroy(self, obj):
item_id = obj.property("itemId")
self._editor_by_id.pop(item_id, None)
class LoadedInSceneDelegate(QtWidgets.QStyledItemDelegate):
"""Delegate for Loaded in Scene state columns.

View file

@ -351,11 +351,10 @@ class ProductsModel(QtGui.QStandardItemModel):
representation count by version id.
sync_availability_by_version_id (Optional[str, Tuple[int, int]]):
Mapping of sync availability by version id.
"""
"""
model_item.setData(version_item.version_id, VERSION_ID_ROLE)
model_item.setData(version_item.version, VERSION_NAME_ROLE)
model_item.setData(version_item.version_id, VERSION_ID_ROLE)
model_item.setData(version_item.is_hero, VERSION_HERO_ROLE)
model_item.setData(
version_item.published_time, VERSION_PUBLISH_TIME_ROLE
@ -398,11 +397,11 @@ class ProductsModel(QtGui.QStandardItemModel):
remote_site_icon,
repre_count_by_version_id,
sync_availability_by_version_id,
last_version_by_product_id,
):
model_item = self._items_by_id.get(product_item.product_id)
versions = list(product_item.version_items.values())
versions.sort()
last_version = versions[-1]
last_version = last_version_by_product_id[product_item.product_id]
statuses = {
version_item.status
for version_item in product_item.version_items.values()
@ -443,7 +442,7 @@ class ProductsModel(QtGui.QStandardItemModel):
def get_last_project_name(self):
return self._last_project_name
def refresh(self, project_name, folder_ids):
def refresh(self, project_name, folder_ids, status_names):
self._clear()
self._last_project_name = project_name
@ -473,16 +472,27 @@ class ProductsModel(QtGui.QStandardItemModel):
product_item.product_id: product_item
for product_item in product_items
}
last_version_id_by_product_id = {}
last_version_by_product_id = {}
for product_item in product_items:
versions = list(product_item.version_items.values())
versions.sort()
last_version = versions[-1]
last_version_id_by_product_id[product_item.product_id] = (
last_version.version_id
all_versions = list(product_item.version_items.values())
all_versions.sort()
versions = [
version_item
for version_item in all_versions
if status_names is None or version_item.status in status_names
]
if versions:
last_version = versions[-1]
else:
last_version = all_versions[-1]
last_version_by_product_id[product_item.product_id] = (
last_version
)
version_ids = set(last_version_id_by_product_id.values())
version_ids = {
version_item.version_id
for version_item in last_version_by_product_id.values()
}
repre_count_by_version_id = self._controller.get_versions_representation_count(
project_name, version_ids
)
@ -559,6 +569,7 @@ class ProductsModel(QtGui.QStandardItemModel):
remote_site_icon,
repre_count_by_version_id,
sync_availability_by_version_id,
last_version_by_product_id,
)
new_items.append(item)
@ -581,6 +592,7 @@ class ProductsModel(QtGui.QStandardItemModel):
remote_site_icon,
repre_count_by_version_id,
sync_availability_by_version_id,
last_version_by_product_id,
)
new_merged_items.append(item)
merged_product_types.add(product_item.product_type)

View file

@ -34,12 +34,17 @@ from .actions_utils import show_actions_menu
class ProductsProxyModel(RecursiveSortFilterProxyModel):
def __init__(self, parent=None):
super(ProductsProxyModel, self).__init__(parent)
super().__init__(parent)
self._product_type_filters = {}
self._statuses_filter = None
self._ascending_sort = True
def get_statuses_filter(self):
if self._statuses_filter is None:
return None
return set(self._statuses_filter)
def set_product_type_filters(self, product_type_filters):
self._product_type_filters = product_type_filters
self.invalidateFilter()
@ -97,13 +102,13 @@ class ProductsProxyModel(RecursiveSortFilterProxyModel):
if not self._ascending_sort:
output = not output
return output
return super(ProductsProxyModel, self).lessThan(left, right)
return super().lessThan(left, right)
def sort(self, column, order=None):
if order is None:
order = QtCore.Qt.AscendingOrder
self._ascending_sort = order == QtCore.Qt.AscendingOrder
super(ProductsProxyModel, self).sort(column, order)
super().sort(column, order)
class ProductsWidget(QtWidgets.QWidget):
@ -245,8 +250,8 @@ class ProductsWidget(QtWidgets.QWidget):
status_names (list[str]): The list of status names.
"""
self._products_proxy_model.set_statuses_filter(status_names)
self._version_delegate.set_statuses_filter(status_names)
self._products_proxy_model.set_statuses_filter(status_names)
def set_product_type_filter(self, product_type_filters):
"""
@ -314,7 +319,8 @@ class ProductsWidget(QtWidgets.QWidget):
def _refresh_model(self):
self._products_model.refresh(
self._selected_project_name,
self._selected_folder_ids
self._selected_folder_ids,
self._products_proxy_model.get_statuses_filter()
)
def _on_context_menu(self, point):