From d960ec7e2344ec401af2a17b451f01ede624625b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 14:52:30 +0200 Subject: [PATCH 01/22] defined family view, model and proxy model --- openpype/tools/libraryloader/app.py | 4 +- openpype/tools/loader/app.py | 4 +- openpype/tools/loader/widgets.py | 178 +++++++++++++++++----------- 3 files changed, 111 insertions(+), 75 deletions(-) diff --git a/openpype/tools/libraryloader/app.py b/openpype/tools/libraryloader/app.py index 362d05cce64..3f7979ff1c0 100644 --- a/openpype/tools/libraryloader/app.py +++ b/openpype/tools/libraryloader/app.py @@ -9,7 +9,7 @@ from openpype.tools.loader.widgets import ( ThumbnailWidget, VersionWidget, - FamilyListWidget, + FamilyListView, RepresentationWidget ) from openpype.tools.utils.widgets import AssetWidget @@ -65,7 +65,7 @@ def __init__( assets = AssetWidget( self.dbcon, multiselection=True, parent=self ) - families = FamilyListWidget( + families = FamilyListView( self.dbcon, self.family_config_cache, parent=self ) subsets = LibrarySubsetWidget( diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 381d6b25d80..4beebe43b85 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -11,7 +11,7 @@ from .widgets import ( SubsetWidget, VersionWidget, - FamilyListWidget, + FamilyListView, ThumbnailWidget, RepresentationWidget, OverlayFrame @@ -64,7 +64,7 @@ def __init__(self, parent=None): assets = AssetWidget(io, multiselection=True, parent=self) assets.set_current_asset_btn_visibility(True) - families = FamilyListWidget(io, self.family_config_cache, self) + families = FamilyListView(io, self.family_config_cache, self) subsets = SubsetWidget( io, self.groups_config, diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 39d162613a8..29531795093 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -846,36 +846,17 @@ def set_version(self, version_doc): self.data.set_version(version_doc) -class FamilyListWidget(QtWidgets.QListWidget): - """A Widget that lists all available families""" +class FamilyModel(QtGui.QStandardItemModel): + def __init__(self, dbcon, family_config_cache): + super(FamilyModel, self).__init__() - NameRole = QtCore.Qt.UserRole + 1 - active_changed = QtCore.Signal(list) - - def __init__(self, dbcon, family_config_cache, parent=None): - super(FamilyListWidget, self).__init__(parent=parent) - - self.family_config_cache = family_config_cache self.dbcon = dbcon + self.family_config_cache = family_config_cache - multi_select = QtWidgets.QAbstractItemView.ExtendedSelection - self.setSelectionMode(multi_select) - self.setAlternatingRowColors(True) - # Enable RMB menu - self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - self.customContextMenuRequested.connect(self.show_right_mouse_menu) - - self.itemChanged.connect(self._on_item_changed) + self._items_by_family = {} def refresh(self): - """Refresh the listed families. - - This gets all unique families and adds them as checkable items to - the list. - - """ - - families = [] + families = set() if self.dbcon.Session.get("AVALON_PROJECT"): result = list(self.dbcon.aggregate([ {"$match": { @@ -890,81 +871,136 @@ def refresh(self): }} ])) if result: - families = result[0]["families"] + families = set(result[0]["families"]) - # Rebuild list + root_item = self.invisibleRootItem() self.blockSignals(True) - self.clear() - for name in sorted(families): - family = self.family_config_cache.family_config(name) - if family.get("hideFilter"): + for family in tuple(self._items_by_family.keys()): + if family not in families: + item = self._items_by_family.pop(family) + root_item.removeRow(item.row()) + self.blockSignals(False) + + new_items = [] + for family in families: + if family in self._items_by_family: continue - label = family.get("label", name) - icon = family.get("icon", None) + family_config = self.family_config_cache.family_config(family) + if family_config.get("hideFilter"): + continue - # TODO: This should be more managable by the artist - # Temporarily implement support for a default state in the project - # configuration - state = family.get("state", True) - state = QtCore.Qt.Checked if state else QtCore.Qt.Unchecked + label = family_config.get("label", family) + icon = family_config.get("icon", None) - item = QtWidgets.QListWidgetItem(parent=self) - item.setText(label) - item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) - item.setData(self.NameRole, name) + if family_config.get("state", True): + state = QtCore.Qt.Checked + else: + state = QtCore.Qt.Unchecked + + item = QtGui.QStandardItem(label) + item.setFlags( + QtCore.Qt.ItemIsEnabled + | QtCore.Qt.ItemIsSelectable + | QtCore.Qt.ItemIsUserCheckable + ) item.setCheckState(state) if icon: item.setIcon(icon) - self.addItem(item) - self.blockSignals(False) + new_items.append(item) - self.active_changed.emit(self.get_filters()) + if new_items: + root_item.appendRows(new_items) - def get_filters(self): + +class FamilyListView(QtWidgets.QListView): + active_changed = QtCore.Signal(list) + + def __init__(self, dbcon, family_config_cache, parent=None): + super(FamilyListView, self).__init__(parent=parent) + + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + self.setAlternatingRowColors(True) + self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + + family_model = FamilyModel(dbcon, family_config_cache) + proxy_model = QtCore.QSortFilterProxyModel() + proxy_model.setDynamicSortFilter(True) + proxy_model.setSourceModel(family_model) + + self.setModel(proxy_model) + + family_model.dataChanged.connect(self._on_data_change) + self.customContextMenuRequested.connect(self._on_context_menu) + + self._family_model = family_model + self._proxy_model = proxy_model + + def refresh(self): + self._family_model.refresh() + + self.active_changed.emit(self.get_enabled_families()) + + def get_enabled_families(self): """Return the checked family items""" + model = self.model() + checked_families = [] + for row in range(model.rowCount()): + index = model.index(row, 0) + if index.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked: + family = index.data(QtCore.Qt.DisplayRole) + checked_families.append(family) - items = [self.item(i) for i in - range(self.count())] + return checked_families - return [item.data(self.NameRole) for item in items if - item.checkState() == QtCore.Qt.Checked] + def set_all_unchecked(self): + self._set_all_checkstate(False) - def _on_item_changed(self): - self.active_changed.emit(self.get_filters()) + def set_all_checked(self): + self._set_all_checkstate(True) + + def _set_all_checkstate(self, checked): + if checked: + state = QtCore.Qt.Checked + else: + state = QtCore.Qt.Unchecked - def _set_checkstate_all(self, state): - _state = QtCore.Qt.Checked if state is True else QtCore.Qt.Unchecked self.blockSignals(True) - for i in range(self.count()): - item = self.item(i) - item.setCheckState(_state) + + model = self._family_model + for row in range(model.rowCount()): + index = model.index(row, 0) + if index.data(QtCore.Qt.CheckStateRole) != state: + model.setData(index, state, QtCore.Qt.CheckStateRole) + self.blockSignals(False) - self.active_changed.emit(self.get_filters()) - def show_right_mouse_menu(self, pos): - """Build RMB menu under mouse at current position (within widget)""" + self.active_changed.emit(self.get_enabled_families()) - # Get mouse position - globalpos = self.viewport().mapToGlobal(pos) + def _on_data_change(self, *_args): + self.active_changed.emit(self.get_enabled_families()) + def _on_context_menu(self, pos): + """Build RMB menu under mouse at current position (within widget)""" menu = QtWidgets.QMenu(self) # Add enable all action - state_checked = QtWidgets.QAction(menu, text="Enable All") - state_checked.triggered.connect( - lambda: self._set_checkstate_all(True)) + action_check_all = QtWidgets.QAction(menu) + action_check_all.setText("Enable All") + action_check_all.triggered.connect(self.set_all_checked) # Add disable all action - state_unchecked = QtWidgets.QAction(menu, text="Disable All") - state_unchecked.triggered.connect( - lambda: self._set_checkstate_all(False)) + action_uncheck_all = QtWidgets.QAction(menu) + action_uncheck_all.setText("Disable All") + action_uncheck_all.triggered.connect(self.set_all_unchecked) - menu.addAction(state_checked) - menu.addAction(state_unchecked) + menu.addAction(action_check_all) + menu.addAction(action_uncheck_all) - menu.exec_(globalpos) + # Get mouse position + global_pos = self.viewport().mapToGlobal(pos) + menu.exec_(global_pos) class RepresentationWidget(QtWidgets.QWidget): From 767142b764194aa232a60310c969c7d42a9e1ef4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 15:04:50 +0200 Subject: [PATCH 02/22] added simpler checkstate changes with space, enter and backspace --- openpype/tools/loader/widgets.py | 63 +++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 29531795093..21018671beb 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -945,7 +945,7 @@ def refresh(self): def get_enabled_families(self): """Return the checked family items""" - model = self.model() + model = self._family_model checked_families = [] for row in range(model.rowCount()): index = model.index(row, 0) @@ -956,29 +956,54 @@ def get_enabled_families(self): return checked_families def set_all_unchecked(self): - self._set_all_checkstate(False) + self._set_checkstates(False, self._get_all_indexes()) def set_all_checked(self): - self._set_all_checkstate(True) + self._set_checkstates(True, self._get_all_indexes()) + + def _get_all_indexes(self): + indexes = [] + model = self._family_model + for row in range(model.rowCount()): + index = model.index(row, 0) + indexes.append(index) + return indexes - def _set_all_checkstate(self, checked): - if checked: + def _set_checkstates(self, checked, indexes): + if not indexes: + return + + if checked is None: + state = None + elif checked: state = QtCore.Qt.Checked else: state = QtCore.Qt.Unchecked self.blockSignals(True) - model = self._family_model - for row in range(model.rowCount()): - index = model.index(row, 0) - if index.data(QtCore.Qt.CheckStateRole) != state: - model.setData(index, state, QtCore.Qt.CheckStateRole) + for index in indexes: + index_state = index.data(QtCore.Qt.CheckStateRole) + if index_state == state: + continue + + new_state = state + if new_state is None: + if index_state == QtCore.Qt.Checked: + new_state = QtCore.Qt.Unchecked + else: + new_state = QtCore.Qt.Checked + + index.model().setData(index, new_state, QtCore.Qt.CheckStateRole) self.blockSignals(False) self.active_changed.emit(self.get_enabled_families()) + def _change_selection_state(self, checked): + indexes = self.selectionModel().selectedIndexes() + self._set_checkstates(checked, indexes) + def _on_data_change(self, *_args): self.active_changed.emit(self.get_enabled_families()) @@ -1002,6 +1027,24 @@ def _on_context_menu(self, pos): global_pos = self.viewport().mapToGlobal(pos) menu.exec_(global_pos) + def event(self, event): + if not event.type() == QtCore.QEvent.KeyPress: + pass + + elif event.key() == QtCore.Qt.Key_Space: + self._change_selection_state(None) + return True + + elif event.key() == QtCore.Qt.Key_Backspace: + self._change_selection_state(False) + return True + + elif event.key() == QtCore.Qt.Key_Return: + self._change_selection_state(True) + return True + + return super(FamilyListView, self).event(event) + class RepresentationWidget(QtWidgets.QWidget): load_started = QtCore.Signal() From ab98bf5358fc8529535481f3acf5e41a7616cdb4 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 15:23:16 +0200 Subject: [PATCH 03/22] added filtering model --- openpype/tools/loader/widgets.py | 50 +++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 21018671beb..0c61db26237 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -915,6 +915,46 @@ def refresh(self): root_item.appendRows(new_items) +class FamilyProxyFiler(QtCore.QSortFilterProxyModel): + def __init__(self, *args, **kwargs): + super(FamilyProxyFiler, self).__init__(*args, **kwargs) + + self._filtering_enabled = False + self._enabled_families = set() + + def set_enabled_families(self, families): + if self._enabled_families == families: + return + + self._enabled_families = families + if self._filtering_enabled: + self.invalidateFilter() + + def is_filter_enabled(self): + return self._filtering_enabled + + def set_filter_enabled(self, enabled=None): + if enabled is None: + enabled = not self._filtering_enabled + if self._filtering_enabled == enabled: + return + + self._filtering_enabled = enabled + self.invalidateFilter() + + def filterAcceptsRow(self, row, parent): + if not self._filtering_enabled: + return True + + if not self._enabled_families: + return False + + index = self.sourceModel().index(row, self.filterKeyColumn(), parent) + if index.data(QtCore.Qt.DisplayRole) in self._enabled_families: + return True + return False + + class FamilyListView(QtWidgets.QListView): active_changed = QtCore.Signal(list) @@ -926,7 +966,7 @@ def __init__(self, dbcon, family_config_cache, parent=None): self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) family_model = FamilyModel(dbcon, family_config_cache) - proxy_model = QtCore.QSortFilterProxyModel() + proxy_model = FamilyProxyFiler() proxy_model.setDynamicSortFilter(True) proxy_model.setSourceModel(family_model) @@ -938,6 +978,14 @@ def __init__(self, dbcon, family_config_cache, parent=None): self._family_model = family_model self._proxy_model = proxy_model + def set_enabled_families(self, families): + self._proxy_model.set_enabled_families(families) + + self.set_enabled_family_filtering(True) + + def set_enabled_family_filtering(self, enabled=None): + self._proxy_model.set_filter_enabled(enabled) + def refresh(self): self._family_model.refresh() From 7696fbd2de0ddb239f9d257da4def93478580fb2 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 16:21:43 +0200 Subject: [PATCH 04/22] pass refreshed to subset widget --- openpype/tools/loader/app.py | 17 +++++++---------- openpype/tools/loader/widgets.py | 2 ++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 4beebe43b85..5cb0bf41a9c 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -146,6 +146,7 @@ def __init__(self, parent=None): assets.view.clicked.connect(self.on_assetview_click) subsets.active_changed.connect(self.on_subsetschanged) subsets.version_changed.connect(self.on_versionschanged) + subsets.refreshed.connect(self._on_subset_refresh) subsets.load_started.connect(self._on_load_start) subsets.load_ended.connect(self._on_load_end) @@ -215,6 +216,12 @@ def _on_load_start(self): def _hide_overlay(self): self._overlay_frame.setVisible(False) + def _on_subset_refresh(self, has_item): + subsets_widget = self.data["widgets"]["subsets"] + familis_widget = self.data["widgets"]["families"] + + subsets_widget.set_loading_state(loading=False, empty=not has_item) + def _on_load_end(self): # Delay hiding as click events happened during loading should be # blocked @@ -264,8 +271,6 @@ def clear_assets_underlines(self): def _assetschanged(self): """Selected assets have changed""" - t1 = time.time() - assets_widget = self.data["widgets"]["assets"] subsets_widget = self.data["widgets"]["subsets"] subsets_model = subsets_widget.model @@ -283,14 +288,6 @@ def _assetschanged(self): empty=True ) - def on_refreshed(has_item): - empty = not has_item - subsets_widget.set_loading_state(loading=False, empty=empty) - subsets_model.refreshed.disconnect() - self.echo("Duration: %.3fs" % (time.time() - t1)) - - subsets_model.refreshed.connect(on_refreshed) - subsets_model.set_assets(asset_ids) subsets_widget.view.setColumnHidden( subsets_model.Columns.index("asset"), diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 0c61db26237..5a04cbac8f1 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -122,6 +122,7 @@ class SubsetWidget(QtWidgets.QWidget): version_changed = QtCore.Signal() # version state changed for a subset load_started = QtCore.Signal() load_ended = QtCore.Signal() + refreshed = QtCore.Signal(bool) default_widths = ( ("subset", 200), @@ -242,6 +243,7 @@ def __init__( self.filter.textChanged.connect(self.proxy.setFilterRegExp) self.filter.textChanged.connect(self.view.expandAll) + model.refreshed.connect(self.refreshed) self.model.refresh() From aad79964a621ac95ed9ae1f79118cbe814c9035c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 16:21:53 +0200 Subject: [PATCH 05/22] fixed subset projection --- openpype/tools/loader/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 253341f70d4..184d488efca 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -128,7 +128,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel): "name": 1, "parent": 1, "schema": 1, - "families": 1, + "data.families": 1, "data.subsetGroup": 1 } From 2e871a7f136055be1abadcc343d4280feed0d508 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 16:22:10 +0200 Subject: [PATCH 06/22] store subset families --- openpype/tools/loader/model.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 184d488efca..1668fc4a272 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -70,7 +70,6 @@ def reset_sync_server(self, project_name=None): class SubsetsModel(TreeModel, BaseRepresentationModel): - doc_fetched = QtCore.Signal() refreshed = QtCore.Signal(bool) @@ -354,10 +353,16 @@ def _fetch(self): }, self.subset_doc_projection ) - for subset in subset_docs: + subset_families = set() + for subset_doc in subset_docs: if self._doc_fetching_stop: return - subset_docs_by_id[subset["_id"]] = subset + + families = subset_doc.get("data", {}).get("families") + if families: + subset_families.add(families[0]) + + subset_docs_by_id[subset_doc["_id"]] = subset_doc subset_ids = list(subset_docs_by_id.keys()) _pipeline = [ @@ -428,6 +433,7 @@ def _fetch(self): self._doc_payload = { "asset_docs_by_id": asset_docs_by_id, "subset_docs_by_id": subset_docs_by_id, + "subset_families": subset_families, "last_versions_by_subset_id": last_versions_by_subset_id } From e6abb640d732f6e4e267c172a4ebc1f14aa464bf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 16:22:25 +0200 Subject: [PATCH 07/22] added ability to return families of current subsets --- openpype/tools/loader/app.py | 2 ++ openpype/tools/loader/model.py | 3 +++ openpype/tools/loader/widgets.py | 3 +++ 3 files changed, 8 insertions(+) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 5cb0bf41a9c..f36248b0c01 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -221,6 +221,8 @@ def _on_subset_refresh(self, has_item): familis_widget = self.data["widgets"]["families"] subsets_widget.set_loading_state(loading=False, empty=not has_item) + families = subsets_widget.get_subsets_families() + familis_widget.set_enabled_families(families) def _on_load_end(self): # Delay hiding as click events happened during loading should be diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 1668fc4a272..0ad8e885932 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -190,6 +190,9 @@ def set_grouping(self, state): self._grouping = state self.on_doc_fetched() + def get_subsets_families(self): + return self._doc_payload.get("subset_families") or set() + def setData(self, index, value, role=QtCore.Qt.EditRole): # Trigger additional edit when `version` column changed # because it also updates the information in other columns diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 5a04cbac8f1..22d5f8ec3a4 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -247,6 +247,9 @@ def __init__( self.model.refresh() + def get_subsets_families(self): + return self.model.get_subsets_families() + def set_family_filters(self, families): self.family_proxy.setFamiliesFilter(families) From 5c1f34a7eb4d2dd29230b407e52aeeb452b8d475 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 16:37:26 +0200 Subject: [PATCH 08/22] families filtering by asset added to library loader --- openpype/tools/libraryloader/app.py | 43 ++++++++++++++--------------- openpype/tools/loader/app.py | 11 ++++---- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/openpype/tools/libraryloader/app.py b/openpype/tools/libraryloader/app.py index 3f7979ff1c0..6dbe47301c0 100644 --- a/openpype/tools/libraryloader/app.py +++ b/openpype/tools/libraryloader/app.py @@ -151,6 +151,7 @@ def __init__( assets.view.clicked.connect(self.on_assetview_click) subsets.active_changed.connect(self.on_subsetschanged) subsets.version_changed.connect(self.on_versionschanged) + subsets.refreshed.connect(self._on_subset_refresh) self.combo_projects.currentTextChanged.connect(self.on_project_change) self.sync_server = sync_server @@ -242,6 +243,12 @@ def on_project_change(self): "Config `%s` has no function `install`" % _config.__name__ ) + subsets = self.data["widgets"]["subsets"] + representations = self.data["widgets"]["representations"] + + subsets.on_project_change(self.dbcon.Session["AVALON_PROJECT"]) + representations.on_project_change(self.dbcon.Session["AVALON_PROJECT"]) + self.family_config_cache.refresh() self.groups_config.refresh() @@ -252,12 +259,6 @@ def on_project_change(self): title = "{} - {}".format(self.tool_title, project_name) self.setWindowTitle(title) - subsets = self.data["widgets"]["subsets"] - subsets.on_project_change(self.dbcon.Session["AVALON_PROJECT"]) - - representations = self.data["widgets"]["representations"] - representations.on_project_change(self.dbcon.Session["AVALON_PROJECT"]) - @property def current_project(self): if ( @@ -288,6 +289,14 @@ def on_versionschanged(self, *args): self.echo("Fetching version..") tools_lib.schedule(self._versionschanged, 150, channel="mongo") + def _on_subset_refresh(self, has_item): + subsets_widget = self.data["widgets"]["subsets"] + families_view = self.data["widgets"]["families"] + + subsets_widget.set_loading_state(loading=False, empty=not has_item) + families = subsets_widget.get_subsets_families() + families_view.set_enabled_families(families) + def set_context(self, context, refresh=True): self.echo("Setting context: {}".format(context)) lib.schedule( @@ -312,13 +321,14 @@ def _refresh_assets(self): assert project_doc, "This is a bug" assets_widget = self.data["widgets"]["assets"] + families_view = self.data["widgets"]["families"] + families_view.set_enabled_families(set()) + families_view.refresh() + assets_widget.model.stop_fetch_thread() assets_widget.refresh() assets_widget.setFocus() - families = self.data["widgets"]["families"] - families.refresh() - def clear_assets_underlines(self): last_asset_ids = self.data["state"]["assetIds"] if not last_asset_ids: @@ -337,8 +347,6 @@ def clear_assets_underlines(self): def _assetschanged(self): """Selected assets have changed""" - t1 = time.time() - assets_widget = self.data["widgets"]["assets"] subsets_widget = self.data["widgets"]["subsets"] subsets_model = subsets_widget.model @@ -365,14 +373,6 @@ def _assetschanged(self): empty=True ) - def on_refreshed(has_item): - empty = not has_item - subsets_widget.set_loading_state(loading=False, empty=empty) - subsets_model.refreshed.disconnect() - self.echo("Duration: %.3fs" % (time.time() - t1)) - - subsets_model.refreshed.connect(on_refreshed) - subsets_model.set_assets(asset_ids) subsets_widget.view.setColumnHidden( subsets_model.Columns.index("asset"), @@ -386,9 +386,8 @@ def on_refreshed(has_item): self.data["state"]["assetIds"] = asset_ids representations = self.data["widgets"]["representations"] - representations.set_version_ids([]) # reset repre list - - self.echo("Duration: %.3fs" % (time.time() - t1)) + # reset repre list + representations.set_version_ids([]) def _subsetschanged(self): asset_ids = self.data["state"]["assetIds"] diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index f36248b0c01..cce05c1d3e8 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -218,11 +218,11 @@ def _hide_overlay(self): def _on_subset_refresh(self, has_item): subsets_widget = self.data["widgets"]["subsets"] - familis_widget = self.data["widgets"]["families"] + families_view = self.data["widgets"]["families"] subsets_widget.set_loading_state(loading=False, empty=not has_item) families = subsets_widget.get_subsets_families() - familis_widget.set_enabled_families(families) + families_view.set_enabled_families(families) def _on_load_end(self): # Delay hiding as click events happened during loading should be @@ -247,8 +247,8 @@ def _refresh(self): assets_widget.refresh() assets_widget.setFocus() - families = self.data["widgets"]["families"] - families.refresh() + families_view = self.data["widgets"]["families"] + families_view.refresh() def clear_assets_underlines(self): """Clear colors from asset data to remove colored underlines @@ -303,7 +303,8 @@ def _assetschanged(self): self.data["state"]["assetIds"] = asset_ids representations = self.data["widgets"]["representations"] - representations.set_version_ids([]) # reset repre list + # reset repre list + representations.set_version_ids([]) def _subsetschanged(self): asset_ids = self.data["state"]["assetIds"] From 0639cfa35f9a330b52aa7b5c282b38d6db2a6a0f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 16:42:52 +0200 Subject: [PATCH 09/22] fixed duplication of families --- openpype/tools/loader/widgets.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 22d5f8ec3a4..79a31a787ff 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -915,6 +915,7 @@ def refresh(self): item.setIcon(icon) new_items.append(item) + self._items_by_family[family] = item if new_items: root_item.appendRows(new_items) From 11ad2a87b7fb87e8ff4ff0d35e1675b62ca0b497 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 18:36:51 +0200 Subject: [PATCH 10/22] FamiliesFilterProxyModel does not need family config --- openpype/tools/loader/model.py | 7 +------ openpype/tools/loader/widgets.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/openpype/tools/loader/model.py b/openpype/tools/loader/model.py index 0ad8e885932..6e9c7bf2207 100644 --- a/openpype/tools/loader/model.py +++ b/openpype/tools/loader/model.py @@ -860,10 +860,9 @@ def filterAcceptsRow(self, row, parent): class FamiliesFilterProxyModel(GroupMemberFilterProxyModel): """Filters to specified families""" - def __init__(self, family_config_cache, *args, **kwargs): + def __init__(self, *args, **kwargs): super(FamiliesFilterProxyModel, self).__init__(*args, **kwargs) self._families = set() - self.family_config_cache = family_config_cache def familyFilter(self): return self._families @@ -895,10 +894,6 @@ def filterAcceptsRow(self, row=0, parent=None): if not family: return True - family_config = self.family_config_cache.family_config(family) - if family_config.get("hideFilter"): - return False - # We want to keep the families which are not in the list return family in self._families diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 79a31a787ff..6d29dee6ecb 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -159,7 +159,7 @@ def __init__( grouping=enable_grouping ) proxy = SubsetFilterProxyModel() - family_proxy = FamiliesFilterProxyModel(family_config_cache) + family_proxy = FamiliesFilterProxyModel() family_proxy.setSourceModel(proxy) subset_filter = QtWidgets.QLineEdit() From eb9b88068c656cf7ec2d73032b4b174950e33388 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 18:37:11 +0200 Subject: [PATCH 11/22] refresh family configu during refresh of family model --- openpype/tools/loader/widgets.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 6d29dee6ecb..650879ac86d 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -879,12 +879,13 @@ def refresh(self): families = set(result[0]["families"]) root_item = self.invisibleRootItem() - self.blockSignals(True) + for family in tuple(self._items_by_family.keys()): if family not in families: item = self._items_by_family.pop(family) root_item.removeRow(item.row()) - self.blockSignals(False) + + self.family_config_cache.refresh() new_items = [] for family in families: @@ -892,8 +893,6 @@ def refresh(self): continue family_config = self.family_config_cache.family_config(family) - if family_config.get("hideFilter"): - continue label = family_config.get("label", family) icon = family_config.get("icon", None) From 84cab2bcdd24f04522b1552ad429613c8c05a6d9 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 18:37:24 +0200 Subject: [PATCH 12/22] removed unused global_family_cache --- openpype/tools/utils/lib.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index e83f663b2ea..c402b1f169c 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -12,18 +12,6 @@ self._jobs = dict() -class SharedObjects: - # Variable for family cache in global context - # QUESTION is this safe? More than one tool can refresh at the same time. - family_cache = None - - -def global_family_cache(): - if SharedObjects.family_cache is None: - SharedObjects.family_cache = FamilyConfigCache(io) - return SharedObjects.family_cache - - def format_version(value, hero_version=False): """Formats integer to displayable version name""" label = "v{0:03d}".format(value) From 9433ffe049216f6f549d98ef3dcfb896831253ad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 18:37:56 +0200 Subject: [PATCH 13/22] modified family config to suit more for settings --- openpype/tools/utils/lib.py | 119 +++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 50 deletions(-) diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index c402b1f169c..db34389434a 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -5,9 +5,13 @@ from Qt import QtWidgets, QtCore, QtGui -from avalon import io, api, style +import avalon.api +from avalon import style from avalon.vendor import qtawesome +from openpype.api import get_project_settings +from openpype.lib import filter_profiles + self = sys.modules[__name__] self._jobs = dict() @@ -277,11 +281,12 @@ def preserve_selection(tree_view, column=0, role=None, current_index=True): class FamilyConfigCache: default_color = "#0091B2" _default_icon = None - _default_item = None def __init__(self, dbcon): self.dbcon = dbcon self.family_configs = {} + self._family_filters_set = False + self._require_refresh = True @classmethod def default_icon(cls): @@ -293,15 +298,29 @@ def default_icon(cls): @classmethod def default_item(cls): - if cls._default_item is None: - cls._default_item = {"icon": cls.default_icon()} - return cls._default_item + return { + "icon": cls.default_icon() + } def family_config(self, family_name): """Get value from config with fallback to default""" - return self.family_configs.get(family_name, self.default_item()) + if self._require_refresh: + self._refresh() - def refresh(self): + item = self.family_configs.get(family_name) + if not item: + item = self.default_item() + if self._family_filters_set: + item["state"] = False + return item + + def refresh(self, force=False): + self._require_refresh = True + + if force: + self._refresh() + + def _refresh(self): """Get the family configurations from the database The configuration must be stored on the project under `config`. @@ -317,62 +336,62 @@ def refresh(self): It is possible to override the default behavior and set specific families checked. For example we only want the families imagesequence and camera to be visible in the Loader. - - # This will turn every item off - api.data["familyStateDefault"] = False - - # Only allow the imagesequence and camera - api.data["familyStateToggled"] = ["imagesequence", "camera"] - """ + self._require_refresh = False + self._family_filters_set = False self.family_configs.clear() - - families = [] + # Skip if we're not in host context + if not avalon.api.registered_host(): + return # Update the icons from the project configuration project_name = self.dbcon.Session.get("AVALON_PROJECT") - if project_name: - project_doc = self.dbcon.find_one( - {"type": "project"}, - projection={"config.families": True} + asset_name = self.dbcon.Session.get("AVALON_ASSET") + task_name = self.dbcon.Session.get("AVALON_TASK") + if not all((project_name, asset_name, task_name)): + return + + matching_item = None + project_settings = get_project_settings(project_name) + profiles = ( + project_settings + ["global"] + ["tools"] + ["loader"] + ["family_filter_profiles"] + ) + if profiles: + asset_doc = self.dbcon.find_one( + {"type": "asset", "name": asset_name}, + {"data.tasks": True} ) + tasks_info = asset_doc.get("data", {}).get("tasks") or {} + task_type = tasks_info.get(task_name, {}).get("type") + profiles_filter = { + "task_types": task_type, + "hosts": os.environ["AVALON_APP"] + } + matching_item = filter_profiles(profiles, profiles_filter) - if not project_doc: - print(( - "Project \"{}\" not found!" - " Can't refresh family icons cache." - ).format(project_name)) - else: - families = project_doc["config"].get("families") or [] + families = [] + if matching_item: + families = matching_item["filter_families"] + + if not families: + return - # Check if any family state are being overwritten by the configuration - default_state = api.data.get("familiesStateDefault", True) - toggled = set(api.data.get("familiesStateToggled") or []) + self._family_filters_set = True # Replace icons with a Qt icon we can use in the user interfaces for family in families: - name = family["name"] - # Set family icon - icon = family.get("icon", None) - if icon: - family["icon"] = qtawesome.icon( - "fa.{}".format(icon), - color=self.default_color - ) - else: - family["icon"] = self.default_icon() - - # Update state - if name in toggled: - state = True - else: - state = default_state - family["state"] = state - - self.family_configs[name] = family + family_info = { + "name": family, + "icon": self.default_icon(), + "state": True + } - return self.family_configs + self.family_configs[family] = family_info class GroupsConfig: From 7ccc1bc01077bab2f1afc004cdfcf86568c0ebbd Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 18:43:07 +0200 Subject: [PATCH 14/22] added initial settings for families --- .../defaults/project_settings/global.json | 9 ++++ .../schemas/schema_global_tools.json | 42 +++++++++++++++++++ .../schemas/template_publish_families.json | 20 +++++++++ 3 files changed, 71 insertions(+) create mode 100644 openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index a53ae149144..6a61f2f5c37 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -287,6 +287,15 @@ "textures" ] } + }, + "loader": { + "family_filter_profiles": [ + { + "hosts": [], + "task_types": [], + "filter_families": [] + } + ] } }, "project_folder_structure": "{\"__project_root__\": {\"prod\": {}, \"resources\": {\"footage\": {\"plates\": {}, \"offline\": {}}, \"audio\": {}, \"art_dept\": {}}, \"editorial\": {}, \"assets[ftrack.Library]\": {\"characters[ftrack]\": {}, \"locations[ftrack]\": {}}, \"shots[ftrack.Sequence]\": {\"scripts\": {}, \"editorial[ftrack.Folder]\": {}}}}", diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_tools.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_tools.json index 245560f115d..8382bfe3f6e 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_tools.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_tools.json @@ -190,6 +190,48 @@ } } ] + }, + { + "type": "dict", + "collapsible": true, + "key": "loader", + "label": "Loader", + "children": [ + { + "type": "list", + "key": "family_filter_profiles", + "label": "Family filtering", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "hosts-enum", + "key": "hosts", + "label": "Hosts", + "multiselection": true + }, + { + "type": "task-types-enum", + "key": "task_types", + "label": "Task types" + }, + { + "type": "splitter" + }, + { + "type": "template", + "name": "template_publish_families", + "template_data": { + "key": "filter_families", + "label": "Filter families", + "multiselection": true + } + } + ] + } + } + ] } ] } diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json b/openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json new file mode 100644 index 00000000000..edec3bad3d4 --- /dev/null +++ b/openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json @@ -0,0 +1,20 @@ +[ + { + "__default_values__": { + "multiselection": true + } + }, + { + "key": "{key}", + "label": "{label}", + "multiselection": "{multiselection}", + "type": "enum", + "enum_items": [ + {"family1": "family1"}, + {"family2": "family2"}, + {"family3": "family3"}, + {"family4": "family4"}, + {"family5": "family5"} + ] + } +] From 1bbfa72b18440b52735d7c782fa79d00948fb41e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 18:57:05 +0200 Subject: [PATCH 15/22] added more suitable families --- .../schemas/template_publish_families.json | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json b/openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json index edec3bad3d4..9db1427562e 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/template_publish_families.json @@ -10,11 +10,23 @@ "multiselection": "{multiselection}", "type": "enum", "enum_items": [ - {"family1": "family1"}, - {"family2": "family2"}, - {"family3": "family3"}, - {"family4": "family4"}, - {"family5": "family5"} + {"action": "action"}, + {"animation": "animation"}, + {"audio": "audio"}, + {"camera": "camera"}, + {"editorial": "editorial"}, + {"layout": "layout"}, + {"look": "look"}, + {"mayaAscii": "mayaAscii"}, + {"model": "model"}, + {"pointcache": "pointcache"}, + {"reference": "reference"}, + {"render": "render"}, + {"review": "review"}, + {"rig": "rig"}, + {"setdress": "setdress"}, + {"workfile": "workfile"}, + {"xgen": "xgen"} ] } ] From 622dfa0d4fbbabec98f6fbb242f06629ad361c38 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 19:19:03 +0200 Subject: [PATCH 16/22] use SharedObject class for jobs --- openpype/tools/utils/lib.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index db34389434a..00f64211b81 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -12,9 +12,6 @@ from openpype.api import get_project_settings from openpype.lib import filter_profiles -self = sys.modules[__name__] -self._jobs = dict() - def format_version(value, hero_version=False): """Formats integer to displayable version name""" @@ -58,6 +55,10 @@ def defer(delay, func): return func() +class SharedObjects: + jobs = {} + + def schedule(func, time, channel="default"): """Run `func` at a later `time` in a dedicated `channel` @@ -69,7 +70,7 @@ def schedule(func, time, channel="default"): """ try: - self._jobs[channel].stop() + SharedObjects.jobs[channel].stop() except (AttributeError, KeyError, RuntimeError): pass @@ -78,7 +79,7 @@ def schedule(func, time, channel="default"): timer.timeout.connect(func) timer.start(time) - self._jobs[channel] = timer + SharedObjects.jobs[channel] = timer @contextlib.contextmanager From 424c76e3ea42a84eed6b5772ba2f52988492cefa Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 19:19:22 +0200 Subject: [PATCH 17/22] replaced default item with just using new dictionary --- openpype/tools/utils/lib.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index 00f64211b81..8454dad0e52 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -91,7 +91,6 @@ def dummy(): .. pass """ - yield @@ -297,11 +296,6 @@ def default_icon(cls): ) return cls._default_icon - @classmethod - def default_item(cls): - return { - "icon": cls.default_icon() - } def family_config(self, family_name): """Get value from config with fallback to default""" @@ -310,7 +304,9 @@ def family_config(self, family_name): item = self.family_configs.get(family_name) if not item: - item = self.default_item() + item = { + "icon": self.default_icon() + } if self._family_filters_set: item["state"] = False return item From 62b975dde29e5cbce88336b7d6be0b8705934666 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 19:26:52 +0200 Subject: [PATCH 18/22] update family filters on context change --- openpype/tools/loader/app.py | 5 ++++- openpype/tools/loader/widgets.py | 27 ++++++++++++++------------- openpype/tools/utils/lib.py | 7 +++---- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index cce05c1d3e8..18e94b74748 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -232,8 +232,11 @@ def _on_load_end(self): # ------------------------------ def on_context_task_change(self, *args, **kwargs): - # Change to context asset on context change assets_widget = self.data["widgets"]["assets"] + families_view = self.data["widgets"]["families"] + # Refresh families config + families_view.refresh() + # Change to context asset on context change assets_widget.select_assets(io.Session["AVALON_ASSET"]) def _refresh(self): diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 650879ac86d..e94942e7b7f 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -889,11 +889,7 @@ def refresh(self): new_items = [] for family in families: - if family in self._items_by_family: - continue - family_config = self.family_config_cache.family_config(family) - label = family_config.get("label", family) icon = family_config.get("icon", None) @@ -902,20 +898,25 @@ def refresh(self): else: state = QtCore.Qt.Unchecked - item = QtGui.QStandardItem(label) - item.setFlags( - QtCore.Qt.ItemIsEnabled - | QtCore.Qt.ItemIsSelectable - | QtCore.Qt.ItemIsUserCheckable - ) + if family not in self._items_by_family: + item = QtGui.QStandardItem(label) + item.setFlags( + QtCore.Qt.ItemIsEnabled + | QtCore.Qt.ItemIsSelectable + | QtCore.Qt.ItemIsUserCheckable + ) + + else: + item = self._items_by_family[label] + item.setData(QtCore.Qt.DisplayRole, label) + new_items.append(item) + self._items_by_family[family] = item + item.setCheckState(state) if icon: item.setIcon(icon) - new_items.append(item) - self._items_by_family[family] = item - if new_items: root_item.appendRows(new_items) diff --git a/openpype/tools/utils/lib.py b/openpype/tools/utils/lib.py index 8454dad0e52..d01dbbd1695 100644 --- a/openpype/tools/utils/lib.py +++ b/openpype/tools/utils/lib.py @@ -296,7 +296,6 @@ def default_icon(cls): ) return cls._default_icon - def family_config(self, family_name): """Get value from config with fallback to default""" if self._require_refresh: @@ -343,9 +342,9 @@ def _refresh(self): return # Update the icons from the project configuration - project_name = self.dbcon.Session.get("AVALON_PROJECT") - asset_name = self.dbcon.Session.get("AVALON_ASSET") - task_name = self.dbcon.Session.get("AVALON_TASK") + project_name = os.environ.get("AVALON_PROJECT") + asset_name = os.environ.get("AVALON_ASSET") + task_name = os.environ.get("AVALON_TASK") if not all((project_name, asset_name, task_name)): return From e7310036645ae00db4a556ed7ab3de6dbdcb2a8f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 19:30:00 +0200 Subject: [PATCH 19/22] fix class name --- openpype/tools/loader/__init__.py | 4 ++-- openpype/tools/loader/app.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/openpype/tools/loader/__init__.py b/openpype/tools/loader/__init__.py index c7bd6148a7c..a5fda8f018e 100644 --- a/openpype/tools/loader/__init__.py +++ b/openpype/tools/loader/__init__.py @@ -1,11 +1,11 @@ from .app import ( - LoaderWidow, + LoaderWindow, show, cli, ) __all__ = ( - "LoaderWidow", + "LoaderWindow", "show", "cli", ) diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 18e94b74748..342a00eded5 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -34,13 +34,13 @@ def on_context_task_change(*args, **kwargs): pipeline.on("taskChanged", on_context_task_change) -class LoaderWidow(QtWidgets.QDialog): +class LoaderWindow(QtWidgets.QDialog): """Asset loader interface""" tool_name = "loader" def __init__(self, parent=None): - super(LoaderWidow, self).__init__(parent) + super(LoaderWindow, self).__init__(parent) title = "Asset Loader 2.1" project_name = api.Session.get("AVALON_PROJECT") if project_name: @@ -170,11 +170,11 @@ def __init__(self, parent=None): self.resize(1300, 700) def resizeEvent(self, event): - super(LoaderWidow, self).resizeEvent(event) + super(LoaderWindow, self).resizeEvent(event) self._overlay_frame.resize(self.size()) def moveEvent(self, event): - super(LoaderWidow, self).moveEvent(event) + super(LoaderWindow, self).moveEvent(event) self._overlay_frame.move(0, 0) # ------------------------------- @@ -457,7 +457,7 @@ def closeEvent(self, event): self.setAttribute(QtCore.Qt.WA_DeleteOnClose) print("Good bye") - return super(LoaderWidow, self).closeEvent(event) + return super(LoaderWindow, self).closeEvent(event) def keyPressEvent(self, event): modifiers = event.modifiers() @@ -469,7 +469,7 @@ def keyPressEvent(self, event): self.show_grouping_dialog() return - super(LoaderWidow, self).keyPressEvent(event) + super(LoaderWindow, self).keyPressEvent(event) event.setAccepted(True) # Avoid interfering other widgets def show_grouping_dialog(self): @@ -630,7 +630,7 @@ def show(debug=False, parent=None, use_context=False): module.project = any_project["name"] with lib.application(): - window = LoaderWidow(parent) + window = LoaderWindow(parent) window.setStyleSheet(style.load_stylesheet()) window.show() From 1ca05efbaa134999e0dc3f3ed2b35e3e2feb4a8d Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Fri, 17 Sep 2021 19:34:55 +0200 Subject: [PATCH 20/22] hound fixes --- openpype/tools/libraryloader/app.py | 1 - openpype/tools/loader/app.py | 1 - openpype/tools/loader/widgets.py | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/openpype/tools/libraryloader/app.py b/openpype/tools/libraryloader/app.py index 6dbe47301c0..8080c547c9c 100644 --- a/openpype/tools/libraryloader/app.py +++ b/openpype/tools/libraryloader/app.py @@ -1,5 +1,4 @@ import sys -import time from Qt import QtWidgets, QtCore, QtGui diff --git a/openpype/tools/loader/app.py b/openpype/tools/loader/app.py index 342a00eded5..c18b6e798a2 100644 --- a/openpype/tools/loader/app.py +++ b/openpype/tools/loader/app.py @@ -1,5 +1,4 @@ import sys -import time from Qt import QtWidgets, QtCore from avalon import api, io, style, pipeline diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index e94942e7b7f..881e9c206be 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -911,7 +911,7 @@ def refresh(self): item.setData(QtCore.Qt.DisplayRole, label) new_items.append(item) self._items_by_family[family] = item - + item.setCheckState(state) if icon: From 7bb87a14a2221ad0c85ad89e263cc23bb5de90ea Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 20 Sep 2021 11:45:30 +0200 Subject: [PATCH 21/22] fixed filling of families --- openpype/tools/loader/widgets.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index 881e9c206be..d8c42250c78 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -905,12 +905,12 @@ def refresh(self): | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable ) + new_items.append(item) + self._items_by_family[family] = item else: item = self._items_by_family[label] item.setData(QtCore.Qt.DisplayRole, label) - new_items.append(item) - self._items_by_family[family] = item item.setCheckState(state) @@ -942,7 +942,7 @@ def is_filter_enabled(self): def set_filter_enabled(self, enabled=None): if enabled is None: enabled = not self._filtering_enabled - if self._filtering_enabled == enabled: + elif self._filtering_enabled == enabled: return self._filtering_enabled = enabled From d0958304fab082b270b82bbbf1bcd5c3c866c613 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 20 Sep 2021 17:48:53 +0200 Subject: [PATCH 22/22] fixed method arguments order --- openpype/tools/loader/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index d8c42250c78..6b94fc6e44d 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -910,7 +910,7 @@ def refresh(self): else: item = self._items_by_family[label] - item.setData(QtCore.Qt.DisplayRole, label) + item.setData(label, QtCore.Qt.DisplayRole) item.setCheckState(state)