From 3ca931097d836bb1b5e49c15dd04291be2bb485d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 4 Jan 2022 10:57:21 +0100 Subject: [PATCH 1/3] source and proxy models can be changed in assets widget --- openpype/tools/utils/assets_widget.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index f310aafe89..b73aca8d63 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -582,11 +582,8 @@ class AssetsWidget(QtWidgets.QWidget): self.dbcon = dbcon # Tree View - model = AssetModel(dbcon=self.dbcon, parent=self) - proxy = RecursiveSortFilterProxyModel() - proxy.setSourceModel(model) - proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) - proxy.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive) + model = self._create_source_model() + proxy = self._create_proxy_model(model) view = AssetsView(self) view.setModel(proxy) @@ -628,7 +625,6 @@ class AssetsWidget(QtWidgets.QWidget): selection_model.selectionChanged.connect(self._on_selection_change) refresh_btn.clicked.connect(self.refresh) current_asset_btn.clicked.connect(self.set_current_session_asset) - model.refreshed.connect(self._on_model_refresh) view.doubleClicked.connect(self.double_clicked) self._current_asset_btn = current_asset_btn @@ -639,6 +635,18 @@ class AssetsWidget(QtWidgets.QWidget): self.model_selection = {} + def _create_source_model(self): + model = AssetModel(dbcon=self.dbcon, parent=self) + model.refreshed.connect(self._on_model_refresh) + return model + + def _create_proxy_model(self, source_model): + proxy = RecursiveSortFilterProxyModel() + proxy.setSourceModel(source_model) + proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) + proxy.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive) + return proxy + @property def refreshing(self): return self._model.refreshing @@ -691,6 +699,12 @@ class AssetsWidget(QtWidgets.QWidget): self._proxy.setFilterFixedString(new_text) def _on_model_refresh(self, has_item): + """This method should be triggered on model refresh. + + Default implementation register this callback in '_create_source_model' + so if you're modifying model keep in mind that this method should be + called when refresh is done. + """ self._proxy.sort(0) self._set_loading_state(loading=False, empty=not has_item) self.refreshed.emit() From 03fa4e7443fa0e4db7b8b48ba4e82c77ccba3d5f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 4 Jan 2022 10:57:59 +0100 Subject: [PATCH 2/3] got rid of 'clear' argument in refresh method of assets widget --- openpype/tools/utils/assets_widget.py | 36 ++++++++++++++++----------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index b73aca8d63..1495586b04 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -306,6 +306,8 @@ class AssetModel(QtGui.QStandardItemModel): self._items_with_color_by_id = {} self._items_by_asset_id = {} + self._last_project_name = None + @property def refreshing(self): return self._refreshing @@ -347,7 +349,7 @@ class AssetModel(QtGui.QStandardItemModel): return self.get_indexes_by_asset_ids(asset_ids) - def refresh(self, force=False, clear=False): + def refresh(self, force=False): """Refresh the data for the model. Args: @@ -360,7 +362,13 @@ class AssetModel(QtGui.QStandardItemModel): return self.stop_refresh() - if clear: + project_name = self.dbcon.Session.get("AVALON_PROJECT") + clear_model = False + if project_name != self._last_project_name: + clear_model = True + self._last_project_name = project_name + + if clear_model: self._clear_items() # Fetch documents from mongo @@ -401,11 +409,18 @@ class AssetModel(QtGui.QStandardItemModel): self._clear_items() return + self._fill_assets(self._doc_payload) + + self.refreshed.emit(bool(self._items_by_asset_id)) + + self._stop_fetch_thread() + + def _fill_assets(self, asset_docs): # Collect asset documents as needed asset_ids = set() asset_docs_by_id = {} asset_ids_by_parents = collections.defaultdict(set) - for asset_doc in self._doc_payload: + for asset_doc in asset_docs: asset_id = asset_doc["_id"] asset_data = asset_doc.get("data") or {} parent_id = asset_data.get("visualParent") @@ -511,10 +526,6 @@ class AssetModel(QtGui.QStandardItemModel): except Exception: pass - self.refreshed.emit(bool(self._items_by_asset_id)) - - self._stop_fetch_thread() - def _threaded_fetch(self): asset_docs = self._fetch_asset_docs() if not self._refreshing: @@ -652,12 +663,7 @@ class AssetsWidget(QtWidgets.QWidget): return self._model.refreshing def refresh(self): - project_name = self.dbcon.Session.get("AVALON_PROJECT") - clear_model = False - if project_name != self._last_project_name: - clear_model = True - self._last_project_name = project_name - self._refresh_model(clear_model) + self._refresh_model() def stop_refresh(self): self._model.stop_refresh() @@ -709,14 +715,14 @@ class AssetsWidget(QtWidgets.QWidget): self._set_loading_state(loading=False, empty=not has_item) self.refreshed.emit() - def _refresh_model(self, clear=False): + def _refresh_model(self): # Store selection self._set_loading_state(loading=True, empty=True) # Trigger signal before refresh is called self.refresh_triggered.emit() # Refresh model - self._model.refresh(clear=clear) + self._model.refresh() def _set_loading_state(self, loading, empty): self._view.set_loading_state(loading, empty) From e389067ed26a773b023245900d6edf84331439ad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 4 Jan 2022 10:59:57 +0100 Subject: [PATCH 3/3] tasks widget have ability to create different tasks model --- openpype/tools/utils/tasks_widget.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/openpype/tools/utils/tasks_widget.py b/openpype/tools/utils/tasks_widget.py index 419e77c780..6e6cd17ffd 100644 --- a/openpype/tools/utils/tasks_widget.py +++ b/openpype/tools/utils/tasks_widget.py @@ -194,6 +194,8 @@ class TasksWidget(QtWidgets.QWidget): task_changed = QtCore.Signal() def __init__(self, dbcon, parent=None): + self._dbcon = dbcon + super(TasksWidget, self).__init__(parent) tasks_view = DeselectableTreeView(self) @@ -204,9 +206,8 @@ class TasksWidget(QtWidgets.QWidget): header_view = tasks_view.header() header_view.setSortIndicator(0, QtCore.Qt.AscendingOrder) - tasks_model = TasksModel(dbcon) - tasks_proxy = TasksProxyModel() - tasks_proxy.setSourceModel(tasks_model) + tasks_model = self._create_source_model() + tasks_proxy = self._create_proxy_model(tasks_model) tasks_view.setModel(tasks_proxy) layout = QtWidgets.QVBoxLayout(self) @@ -222,6 +223,19 @@ class TasksWidget(QtWidgets.QWidget): self._last_selected_task_name = None + def _create_source_model(self): + """Create source model of tasks widget. + + Model must have available 'refresh' method and 'set_asset_id' to change + context of asset. + """ + return TasksModel(self._dbcon) + + def _create_proxy_model(self, source_model): + proxy = TasksProxyModel() + proxy.setSourceModel(source_model) + return proxy + def refresh(self): self._tasks_model.refresh()