mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge pull request #3649 from BigRoy/loader_show_containers_in_scene
This commit is contained in:
commit
be79e8b786
3 changed files with 129 additions and 55 deletions
28
openpype/tools/loader/delegates.py
Normal file
28
openpype/tools/loader/delegates.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
from Qt import QtWidgets, QtGui, QtCore
|
||||
|
||||
|
||||
class LoadedInSceneDelegate(QtWidgets.QStyledItemDelegate):
|
||||
"""Delegate for Loaded in Scene state columns.
|
||||
|
||||
Shows "yes" or "no" for True or False values
|
||||
Colorizes green or dark grey based on True or False values
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LoadedInSceneDelegate, self).__init__(*args, **kwargs)
|
||||
self._colors = {
|
||||
True: QtGui.QColor(80, 170, 80),
|
||||
False: QtGui.QColor(90, 90, 90)
|
||||
}
|
||||
|
||||
def displayText(self, value, locale):
|
||||
return "yes" if value else "no"
|
||||
|
||||
def initStyleOption(self, option, index):
|
||||
super(LoadedInSceneDelegate, self).initStyleOption(option, index)
|
||||
|
||||
# Colorize based on value
|
||||
value = index.data(QtCore.Qt.DisplayRole)
|
||||
color = self._colors[bool(value)]
|
||||
option.palette.setBrush(QtGui.QPalette.Text, color)
|
||||
|
|
@ -17,6 +17,7 @@ from openpype.client import (
|
|||
get_representations
|
||||
)
|
||||
from openpype.pipeline import (
|
||||
registered_host,
|
||||
HeroVersionType,
|
||||
schema,
|
||||
)
|
||||
|
|
@ -24,6 +25,7 @@ from openpype.pipeline import (
|
|||
from openpype.style import get_default_entity_icon_color
|
||||
from openpype.tools.utils.models import TreeModel, Item
|
||||
from openpype.tools.utils import lib
|
||||
from openpype.host import ILoadHost
|
||||
|
||||
from openpype.modules import ModulesManager
|
||||
from openpype.tools.utils.constants import (
|
||||
|
|
@ -136,6 +138,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
"duration",
|
||||
"handles",
|
||||
"step",
|
||||
"loaded_in_scene",
|
||||
"repre_info"
|
||||
]
|
||||
|
||||
|
|
@ -150,6 +153,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
"duration": "Duration",
|
||||
"handles": "Handles",
|
||||
"step": "Step",
|
||||
"loaded_in_scene": "In scene",
|
||||
"repre_info": "Availability"
|
||||
}
|
||||
|
||||
|
|
@ -231,8 +235,14 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
self._doc_fetching_stop = False
|
||||
self._doc_payload = {}
|
||||
|
||||
self.doc_fetched.connect(self._on_doc_fetched)
|
||||
self._host = registered_host()
|
||||
self._loaded_representation_ids = set()
|
||||
|
||||
# Refresh loaded scene containers only every 3 seconds at most
|
||||
self._host_loaded_refresh_timeout = 3
|
||||
self._host_loaded_refresh_time = 0
|
||||
|
||||
self.doc_fetched.connect(self._on_doc_fetched)
|
||||
self.refresh()
|
||||
|
||||
def get_item_by_id(self, item_id):
|
||||
|
|
@ -474,6 +484,27 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
|
||||
last_versions_by_subset_id[subset_id] = hero_version
|
||||
|
||||
# Check loaded subsets
|
||||
loaded_subset_ids = set()
|
||||
ids = self._loaded_representation_ids
|
||||
if ids:
|
||||
if self._doc_fetching_stop:
|
||||
return
|
||||
|
||||
# Get subset ids from loaded representations in workfile
|
||||
# todo: optimize with aggregation query to distinct subset id
|
||||
representations = get_representations(project_name,
|
||||
representation_ids=ids,
|
||||
fields=["parent"])
|
||||
version_ids = set(repre["parent"] for repre in representations)
|
||||
versions = get_versions(project_name,
|
||||
version_ids=version_ids,
|
||||
fields=["parent"])
|
||||
loaded_subset_ids = set(version["parent"] for version in versions)
|
||||
|
||||
if self._doc_fetching_stop:
|
||||
return
|
||||
|
||||
repre_info_by_version_id = {}
|
||||
if self.sync_server.enabled:
|
||||
versions_by_id = {}
|
||||
|
|
@ -501,7 +532,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
"subset_docs_by_id": subset_docs_by_id,
|
||||
"subset_families": subset_families,
|
||||
"last_versions_by_subset_id": last_versions_by_subset_id,
|
||||
"repre_info_by_version_id": repre_info_by_version_id
|
||||
"repre_info_by_version_id": repre_info_by_version_id,
|
||||
"subsets_loaded_by_id": loaded_subset_ids
|
||||
}
|
||||
|
||||
self.doc_fetched.emit()
|
||||
|
|
@ -533,6 +565,20 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
self.doc_fetched.emit()
|
||||
return
|
||||
|
||||
# Collect scene container representations to compare loaded state
|
||||
# This runs in the main thread because it involves the host DCC
|
||||
if self._host:
|
||||
time_since_refresh = time.time() - self._host_loaded_refresh_time
|
||||
if time_since_refresh > self._host_loaded_refresh_timeout:
|
||||
if isinstance(self._host, ILoadHost):
|
||||
containers = self._host.get_containers()
|
||||
else:
|
||||
containers = self._host.ls()
|
||||
|
||||
repre_ids = {con.get("representation") for con in containers}
|
||||
self._loaded_representation_ids = repre_ids
|
||||
self._host_loaded_refresh_time = time.time()
|
||||
|
||||
self.fetch_subset_and_version()
|
||||
|
||||
def _on_doc_fetched(self):
|
||||
|
|
@ -554,6 +600,10 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
"repre_info_by_version_id"
|
||||
)
|
||||
|
||||
subsets_loaded_by_id = self._doc_payload.get(
|
||||
"subsets_loaded_by_id"
|
||||
)
|
||||
|
||||
if (
|
||||
asset_docs_by_id is None
|
||||
or subset_docs_by_id is None
|
||||
|
|
@ -568,7 +618,8 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
asset_docs_by_id,
|
||||
subset_docs_by_id,
|
||||
last_versions_by_subset_id,
|
||||
repre_info_by_version_id
|
||||
repre_info_by_version_id,
|
||||
subsets_loaded_by_id
|
||||
)
|
||||
self.endResetModel()
|
||||
self.refreshed.emit(True)
|
||||
|
|
@ -596,8 +647,12 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
return merge_group
|
||||
|
||||
def _fill_subset_items(
|
||||
self, asset_docs_by_id, subset_docs_by_id, last_versions_by_subset_id,
|
||||
repre_info_by_version_id
|
||||
self,
|
||||
asset_docs_by_id,
|
||||
subset_docs_by_id,
|
||||
last_versions_by_subset_id,
|
||||
repre_info_by_version_id,
|
||||
subsets_loaded_by_id
|
||||
):
|
||||
_groups_tuple = self.groups_config.split_subsets_for_groups(
|
||||
subset_docs_by_id.values(), self._grouping
|
||||
|
|
@ -621,6 +676,35 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
"index": self.index(group_item.row(), 0)
|
||||
}
|
||||
|
||||
def _add_subset_item(subset_doc, parent_item, parent_index):
|
||||
last_version = last_versions_by_subset_id.get(
|
||||
subset_doc["_id"]
|
||||
)
|
||||
# do not show subset without version
|
||||
if not last_version:
|
||||
return
|
||||
|
||||
data = copy.deepcopy(subset_doc)
|
||||
data["subset"] = subset_doc["name"]
|
||||
|
||||
asset_id = subset_doc["parent"]
|
||||
data["asset"] = asset_docs_by_id[asset_id]["name"]
|
||||
|
||||
data["last_version"] = last_version
|
||||
data["loaded_in_scene"] = subset_doc["_id"] in subsets_loaded_by_id
|
||||
|
||||
# Sync server data
|
||||
data.update(
|
||||
self._get_last_repre_info(repre_info_by_version_id,
|
||||
last_version["_id"]))
|
||||
|
||||
item = Item()
|
||||
item.update(data)
|
||||
self.add_child(item, parent_item)
|
||||
|
||||
index = self.index(item.row(), 0, parent_index)
|
||||
self.set_version(index, last_version)
|
||||
|
||||
subset_counter = 0
|
||||
for group_name, subset_docs_by_name in subset_docs_by_group.items():
|
||||
parent_item = group_item_by_name[group_name]["item"]
|
||||
|
|
@ -643,31 +727,9 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
_parent_index = parent_index
|
||||
|
||||
for subset_doc in subset_docs:
|
||||
asset_id = subset_doc["parent"]
|
||||
|
||||
data = copy.deepcopy(subset_doc)
|
||||
data["subset"] = subset_name
|
||||
data["asset"] = asset_docs_by_id[asset_id]["name"]
|
||||
|
||||
last_version = last_versions_by_subset_id.get(
|
||||
subset_doc["_id"]
|
||||
)
|
||||
data["last_version"] = last_version
|
||||
|
||||
# do not show subset without version
|
||||
if not last_version:
|
||||
continue
|
||||
|
||||
data.update(
|
||||
self._get_last_repre_info(repre_info_by_version_id,
|
||||
last_version["_id"]))
|
||||
|
||||
item = Item()
|
||||
item.update(data)
|
||||
self.add_child(item, _parent_item)
|
||||
|
||||
index = self.index(item.row(), 0, _parent_index)
|
||||
self.set_version(index, last_version)
|
||||
_add_subset_item(subset_doc,
|
||||
parent_item=_parent_item,
|
||||
parent_index=_parent_index)
|
||||
|
||||
for subset_name in sorted(subset_docs_without_group.keys()):
|
||||
subset_docs = subset_docs_without_group[subset_name]
|
||||
|
|
@ -682,31 +744,9 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
subset_counter += 1
|
||||
|
||||
for subset_doc in subset_docs:
|
||||
asset_id = subset_doc["parent"]
|
||||
|
||||
data = copy.deepcopy(subset_doc)
|
||||
data["subset"] = subset_name
|
||||
data["asset"] = asset_docs_by_id[asset_id]["name"]
|
||||
|
||||
last_version = last_versions_by_subset_id.get(
|
||||
subset_doc["_id"]
|
||||
)
|
||||
data["last_version"] = last_version
|
||||
|
||||
# do not show subset without version
|
||||
if not last_version:
|
||||
continue
|
||||
|
||||
data.update(
|
||||
self._get_last_repre_info(repre_info_by_version_id,
|
||||
last_version["_id"]))
|
||||
|
||||
item = Item()
|
||||
item.update(data)
|
||||
self.add_child(item, parent_item)
|
||||
|
||||
index = self.index(item.row(), 0, parent_index)
|
||||
self.set_version(index, last_version)
|
||||
_add_subset_item(subset_doc,
|
||||
parent_item=parent_item,
|
||||
parent_index=parent_index)
|
||||
|
||||
def data(self, index, role):
|
||||
if not index.isValid():
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ from .model import (
|
|||
ITEM_ID_ROLE
|
||||
)
|
||||
from . import lib
|
||||
from .delegates import LoadedInSceneDelegate
|
||||
|
||||
from openpype.tools.utils.constants import (
|
||||
LOCAL_PROVIDER_ROLE,
|
||||
|
|
@ -169,6 +170,7 @@ class SubsetWidget(QtWidgets.QWidget):
|
|||
("duration", 60),
|
||||
("handles", 55),
|
||||
("step", 10),
|
||||
("loaded_in_scene", 25),
|
||||
("repre_info", 65)
|
||||
)
|
||||
|
||||
|
|
@ -234,6 +236,10 @@ class SubsetWidget(QtWidgets.QWidget):
|
|||
column = model.Columns.index("repre_info")
|
||||
view.setItemDelegateForColumn(column, avail_delegate)
|
||||
|
||||
loaded_in_scene_delegate = LoadedInSceneDelegate(view)
|
||||
column = model.Columns.index("loaded_in_scene")
|
||||
view.setItemDelegateForColumn(column, loaded_in_scene_delegate)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.addLayout(top_bar_layout)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue