mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
fixed change of context on existing instances
This commit is contained in:
parent
4044feb988
commit
de2f48ff54
7 changed files with 159 additions and 248 deletions
|
|
@ -12,6 +12,7 @@ from abc import ABCMeta, abstractmethod
|
|||
import six
|
||||
import arrow
|
||||
import pyblish.api
|
||||
import ayon_api
|
||||
|
||||
from ayon_core.client import (
|
||||
get_asset_by_name,
|
||||
|
|
@ -70,17 +71,17 @@ class AssetDocsCache:
|
|||
|
||||
def __init__(self, controller):
|
||||
self._controller = controller
|
||||
self._full_asset_docs_by_name = {}
|
||||
self._asset_docs_by_path = {}
|
||||
|
||||
def reset(self):
|
||||
self._full_asset_docs_by_name = {}
|
||||
self._asset_docs_by_path = {}
|
||||
|
||||
def get_full_asset_by_name(self, asset_name):
|
||||
if asset_name not in self._full_asset_docs_by_name:
|
||||
def get_asset_doc_by_folder_path(self, folder_path):
|
||||
if folder_path not in self._asset_docs_by_path:
|
||||
project_name = self._controller.project_name
|
||||
full_asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
self._full_asset_docs_by_name[asset_name] = full_asset_doc
|
||||
return copy.deepcopy(self._full_asset_docs_by_name[asset_name])
|
||||
asset_doc = get_asset_by_name(project_name, folder_path)
|
||||
self._asset_docs_by_path[folder_path] = asset_doc
|
||||
return copy.deepcopy(self._asset_docs_by_path[folder_path])
|
||||
|
||||
|
||||
class PublishReportMaker:
|
||||
|
|
@ -951,13 +952,13 @@ class AbstractPublisherController(object):
|
|||
|
||||
@property
|
||||
@abstractmethod
|
||||
def current_asset_name(self):
|
||||
"""Current context asset name.
|
||||
def current_folder_path(self):
|
||||
"""Current context folder path.
|
||||
|
||||
Returns:
|
||||
Union[str, None]: Name of asset.
|
||||
"""
|
||||
Union[str, None]: Folder path.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
@property
|
||||
|
|
@ -1021,7 +1022,7 @@ class AbstractPublisherController(object):
|
|||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_existing_product_names(self, asset_name):
|
||||
def get_existing_product_names(self, folder_path):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
|
@ -1665,7 +1666,7 @@ class PublisherController(BasePublisherController):
|
|||
return self._create_context.get_current_project_name()
|
||||
|
||||
@property
|
||||
def current_asset_name(self):
|
||||
def current_folder_path(self):
|
||||
"""Current context asset name defined by host.
|
||||
|
||||
Returns:
|
||||
|
|
@ -1727,6 +1728,8 @@ class PublisherController(BasePublisherController):
|
|||
|
||||
# Publisher custom method
|
||||
def get_folder_id_from_path(self, folder_path):
|
||||
if not folder_path:
|
||||
return None
|
||||
folder_item = self._hierarchy_model.get_folder_item_by_path(
|
||||
self.project_name, folder_path
|
||||
)
|
||||
|
|
@ -1734,6 +1737,34 @@ class PublisherController(BasePublisherController):
|
|||
return folder_item.entity_id
|
||||
return None
|
||||
|
||||
def get_task_names_by_folder_paths(self, folder_paths):
|
||||
# TODO implement model and cache values
|
||||
if not folder_paths:
|
||||
return {}
|
||||
folder_items = self._hierarchy_model.get_folder_items_by_paths(
|
||||
self.project_name, folder_paths
|
||||
)
|
||||
folder_paths_by_id = {
|
||||
folder_item.entity_id: folder_item.path
|
||||
for folder_item in folder_items.values()
|
||||
if folder_item
|
||||
}
|
||||
tasks = ayon_api.get_tasks(
|
||||
self.project_name,
|
||||
folder_ids=set(folder_paths_by_id),
|
||||
fields=["name", "folderId"]
|
||||
)
|
||||
output = {
|
||||
folder_path: set()
|
||||
for folder_path in folder_paths
|
||||
}
|
||||
for task in tasks:
|
||||
folder_path = folder_paths_by_id.get(task["folderId"])
|
||||
if folder_path:
|
||||
output[folder_path].add(task["name"])
|
||||
|
||||
return output
|
||||
|
||||
def are_folder_paths_valid(self, folder_paths):
|
||||
if not folder_paths:
|
||||
return True
|
||||
|
|
@ -1761,10 +1792,12 @@ class PublisherController(BasePublisherController):
|
|||
|
||||
return context_title
|
||||
|
||||
def get_existing_product_names(self, asset_name):
|
||||
def get_existing_product_names(self, folder_path):
|
||||
if not folder_path:
|
||||
return None
|
||||
project_name = self.project_name
|
||||
folder_item = self._hierarchy_model.get_folder_item_by_path(
|
||||
project_name, asset_name
|
||||
project_name, folder_path
|
||||
)
|
||||
if not folder_item:
|
||||
return None
|
||||
|
|
@ -2006,7 +2039,7 @@ class PublisherController(BasePublisherController):
|
|||
creator_identifier,
|
||||
variant,
|
||||
task_name,
|
||||
asset_name,
|
||||
folder_path,
|
||||
instance_id=None
|
||||
):
|
||||
"""Get product name based on passed data.
|
||||
|
|
@ -2016,14 +2049,16 @@ class PublisherController(BasePublisherController):
|
|||
responsible for product name creation.
|
||||
variant (str): Variant value from user's input.
|
||||
task_name (str): Name of task for which is instance created.
|
||||
asset_name (str): Name of asset for which is instance created.
|
||||
folder_path (str): Folder path for which is instance created.
|
||||
instance_id (Union[str, None]): Existing instance id when product
|
||||
name is updated.
|
||||
"""
|
||||
|
||||
creator = self._creators[creator_identifier]
|
||||
project_name = self.project_name
|
||||
asset_doc = self._asset_docs_cache.get_full_asset_by_name(asset_name)
|
||||
asset_doc = self._asset_docs_cache.get_asset_doc_by_folder_path(
|
||||
folder_path
|
||||
)
|
||||
instance = None
|
||||
if instance_id:
|
||||
instance = self.instances[instance_id]
|
||||
|
|
|
|||
|
|
@ -212,13 +212,13 @@ class QtRemotePublishController(BasePublisherController):
|
|||
pass
|
||||
|
||||
@abstractproperty
|
||||
def current_asset_name(self):
|
||||
"""Current context asset name from client.
|
||||
def current_folder_path(self):
|
||||
"""Current context folder path from host.
|
||||
|
||||
Returns:
|
||||
Union[str, None]: Name of asset.
|
||||
"""
|
||||
Union[str, None]: Folder path.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractproperty
|
||||
|
|
@ -254,7 +254,7 @@ class QtRemotePublishController(BasePublisherController):
|
|||
def get_asset_hierarchy(self):
|
||||
pass
|
||||
|
||||
def get_existing_product_names(self, asset_name):
|
||||
def get_existing_product_names(self, folder_path):
|
||||
pass
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -1,142 +1,48 @@
|
|||
import collections
|
||||
|
||||
from qtpy import QtWidgets, QtCore, QtGui
|
||||
|
||||
from ayon_core.tools.utils.assets_widget import (
|
||||
get_asset_icon,
|
||||
)
|
||||
from ayon_core.tools.utils import (
|
||||
PlaceholderLineEdit,
|
||||
RecursiveSortFilterProxyModel,
|
||||
)
|
||||
from ayon_core.lib.events import QueuedEventSystem
|
||||
from ayon_core.tools.ayon_utils.widgets import FoldersWidget
|
||||
from ayon_core.tools.utils import PlaceholderLineEdit
|
||||
|
||||
class AssetsHierarchyModel(QtGui.QStandardItemModel):
|
||||
"""Assets hierarchy model.
|
||||
|
||||
For selecting asset for which an instance should be created.
|
||||
|
||||
Uses controller to load asset hierarchy. All asset documents are stored by
|
||||
their parents.
|
||||
"""
|
||||
|
||||
class FoldersDialogController:
|
||||
def __init__(self, controller):
|
||||
super(AssetsHierarchyModel, self).__init__()
|
||||
self._event_system = QueuedEventSystem()
|
||||
self._controller = controller
|
||||
|
||||
self._items_by_name = {}
|
||||
self._items_by_path = {}
|
||||
self._items_by_asset_id = {}
|
||||
@property
|
||||
def event_system(self):
|
||||
return self._event_system
|
||||
|
||||
def reset(self):
|
||||
self.clear()
|
||||
def emit_event(self, topic, data=None, source=None):
|
||||
"""Use implemented event system to trigger event."""
|
||||
|
||||
self._items_by_name = {}
|
||||
self._items_by_path = {}
|
||||
self._items_by_asset_id = {}
|
||||
# assets_by_parent_id = self._controller.get_asset_hierarchy()
|
||||
assets_by_parent_id = {}
|
||||
if data is None:
|
||||
data = {}
|
||||
self.event_system.emit(topic, data, source)
|
||||
|
||||
items_by_name = {}
|
||||
items_by_path = {}
|
||||
items_by_asset_id = {}
|
||||
_queue = collections.deque()
|
||||
_queue.append((self.invisibleRootItem(), None, None))
|
||||
while _queue:
|
||||
parent_item, parent_id, parent_path = _queue.popleft()
|
||||
children = assets_by_parent_id.get(parent_id)
|
||||
if not children:
|
||||
continue
|
||||
def register_event_callback(self, topic, callback):
|
||||
self.event_system.add_callback(topic, callback)
|
||||
|
||||
children_by_name = {
|
||||
child["name"]: child
|
||||
for child in children
|
||||
}
|
||||
items = []
|
||||
for name in sorted(children_by_name.keys()):
|
||||
child = children_by_name[name]
|
||||
child_id = child["_id"]
|
||||
if parent_path:
|
||||
child_path = "{}/{}".format(parent_path, name)
|
||||
else:
|
||||
child_path = "/{}".format(name)
|
||||
def get_folder_items(self, project_name, sender=None):
|
||||
return self._controller.get_folder_items(project_name, sender)
|
||||
|
||||
has_children = bool(assets_by_parent_id.get(child_id))
|
||||
icon = get_asset_icon(child, has_children)
|
||||
|
||||
item = QtGui.QStandardItem(name)
|
||||
item.setFlags(
|
||||
QtCore.Qt.ItemIsEnabled
|
||||
| QtCore.Qt.ItemIsSelectable
|
||||
)
|
||||
item.setData(icon, QtCore.Qt.DecorationRole)
|
||||
item.setData(child_id, ASSET_ID_ROLE)
|
||||
item.setData(name, ASSET_NAME_ROLE)
|
||||
item.setData(child_path, ASSET_PATH_ROLE)
|
||||
|
||||
items_by_name[name] = item
|
||||
items_by_path[child_path] = item
|
||||
items_by_asset_id[child_id] = item
|
||||
items.append(item)
|
||||
_queue.append((item, child_id, child_path))
|
||||
|
||||
parent_item.appendRows(items)
|
||||
|
||||
self._items_by_name = items_by_name
|
||||
self._items_by_path = items_by_path
|
||||
self._items_by_asset_id = items_by_asset_id
|
||||
|
||||
def get_index_by_asset_id(self, asset_id):
|
||||
item = self._items_by_asset_id.get(asset_id)
|
||||
if item is not None:
|
||||
return item.index()
|
||||
return QtCore.QModelIndex()
|
||||
|
||||
def get_index_by_asset_name(self, asset_name):
|
||||
item = self._items_by_path.get(asset_name)
|
||||
if item is None:
|
||||
item = self._items_by_name.get(asset_name)
|
||||
|
||||
if item is None:
|
||||
return QtCore.QModelIndex()
|
||||
return item.index()
|
||||
|
||||
def name_is_valid(self, item_name):
|
||||
return item_name in self._items_by_path
|
||||
|
||||
|
||||
class AssetDialogView(QtWidgets.QTreeView):
|
||||
double_clicked = QtCore.Signal(QtCore.QModelIndex)
|
||||
|
||||
def mouseDoubleClickEvent(self, event):
|
||||
index = self.indexAt(event.pos())
|
||||
if index.isValid():
|
||||
self.double_clicked.emit(index)
|
||||
event.accept()
|
||||
def set_selected_folder(self, folder_id):
|
||||
pass
|
||||
|
||||
|
||||
class AssetsDialog(QtWidgets.QDialog):
|
||||
"""Dialog to select asset for a context of instance."""
|
||||
"""Dialog to select folder for a context of instance."""
|
||||
|
||||
def __init__(self, controller, parent):
|
||||
super(AssetsDialog, self).__init__(parent)
|
||||
self.setWindowTitle("Select asset")
|
||||
|
||||
model = AssetsHierarchyModel(controller)
|
||||
proxy_model = RecursiveSortFilterProxyModel()
|
||||
proxy_model.setSourceModel(model)
|
||||
proxy_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
|
||||
self.setWindowTitle("Select folder")
|
||||
|
||||
filter_input = PlaceholderLineEdit(self)
|
||||
filter_input.setPlaceholderText("Filter folders..")
|
||||
|
||||
asset_view = AssetDialogView(self)
|
||||
asset_view.setModel(proxy_model)
|
||||
asset_view.setHeaderHidden(True)
|
||||
asset_view.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||
asset_view.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||
asset_view.setAlternatingRowColors(True)
|
||||
asset_view.setSelectionBehavior(QtWidgets.QTreeView.SelectRows)
|
||||
asset_view.setAllColumnsShowFocus(True)
|
||||
folders_controller = FoldersDialogController(controller)
|
||||
folders_widget = FoldersWidget(folders_controller, self)
|
||||
|
||||
ok_btn = QtWidgets.QPushButton("OK", self)
|
||||
cancel_btn = QtWidgets.QPushButton("Cancel", self)
|
||||
|
|
@ -148,28 +54,26 @@ class AssetsDialog(QtWidgets.QDialog):
|
|||
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout.addWidget(filter_input, 0)
|
||||
layout.addWidget(asset_view, 1)
|
||||
layout.addWidget(folders_widget, 1)
|
||||
layout.addLayout(btns_layout, 0)
|
||||
|
||||
controller.event_system.add_callback(
|
||||
"controller.reset.finished", self._on_controller_reset
|
||||
)
|
||||
|
||||
asset_view.double_clicked.connect(self._on_ok_clicked)
|
||||
folders_widget.double_clicked.connect(self._on_ok_clicked)
|
||||
filter_input.textChanged.connect(self._on_filter_change)
|
||||
ok_btn.clicked.connect(self._on_ok_clicked)
|
||||
cancel_btn.clicked.connect(self._on_cancel_clicked)
|
||||
|
||||
self._controller = controller
|
||||
self._filter_input = filter_input
|
||||
self._ok_btn = ok_btn
|
||||
self._cancel_btn = cancel_btn
|
||||
|
||||
self._model = model
|
||||
self._proxy_model = proxy_model
|
||||
self._folders_widget = folders_widget
|
||||
|
||||
self._asset_view = asset_view
|
||||
|
||||
self._selected_asset = None
|
||||
self._selected_folder_path = None
|
||||
# Soft refresh is enabled
|
||||
# - reset will happen at all cost if soft reset is enabled
|
||||
# - adds ability to call reset on multiple places without repeating
|
||||
|
|
@ -194,7 +98,7 @@ class AssetsDialog(QtWidgets.QDialog):
|
|||
self._soft_reset_enabled = True
|
||||
|
||||
def showEvent(self, event):
|
||||
"""Refresh asset model on show."""
|
||||
"""Refresh folders widget on show."""
|
||||
super(AssetsDialog, self).showEvent(event)
|
||||
if self._first_show:
|
||||
self._first_show = False
|
||||
|
|
@ -203,76 +107,44 @@ class AssetsDialog(QtWidgets.QDialog):
|
|||
self.reset(False)
|
||||
|
||||
def reset(self, force=True):
|
||||
"""Reset asset model."""
|
||||
"""Reset widget."""
|
||||
if not force and not self._soft_reset_enabled:
|
||||
return
|
||||
|
||||
if self._soft_reset_enabled:
|
||||
self._soft_reset_enabled = False
|
||||
|
||||
self._model.reset()
|
||||
|
||||
def name_is_valid(self, name):
|
||||
"""Is asset name valid.
|
||||
|
||||
Args:
|
||||
name(str): Asset name that should be checked.
|
||||
"""
|
||||
# Make sure we're reset
|
||||
self.reset(False)
|
||||
# Valid the name by model
|
||||
return self._model.name_is_valid(name)
|
||||
self._folders_widget.set_project_name(self._controller.project_name)
|
||||
|
||||
def _on_filter_change(self, text):
|
||||
"""Trigger change of filter of assets."""
|
||||
self._proxy_model.setFilterFixedString(text)
|
||||
"""Trigger change of filter of folders."""
|
||||
self._folders_widget.set_name_filter(text)
|
||||
|
||||
def _on_cancel_clicked(self):
|
||||
self.done(0)
|
||||
|
||||
def _on_ok_clicked(self):
|
||||
index = self._asset_view.currentIndex()
|
||||
asset_name = None
|
||||
if index.isValid():
|
||||
asset_name = index.data(ASSET_PATH_ROLE)
|
||||
self._selected_asset = asset_name
|
||||
self._selected_folder_path = (
|
||||
self._folders_widget.get_selected_folder_path()
|
||||
)
|
||||
self.done(1)
|
||||
|
||||
def set_selected_assets(self, asset_names):
|
||||
"""Change preselected asset before showing the dialog.
|
||||
def set_selected_folders(self, folder_paths):
|
||||
"""Change preselected folder before showing the dialog.
|
||||
|
||||
This also resets model and clean filter.
|
||||
"""
|
||||
self.reset(False)
|
||||
self._asset_view.collapseAll()
|
||||
self._filter_input.setText("")
|
||||
|
||||
indexes = []
|
||||
for asset_name in asset_names:
|
||||
index = self._model.get_index_by_asset_name(asset_name)
|
||||
if index.isValid():
|
||||
indexes.append(index)
|
||||
folder_id = None
|
||||
for folder_path in folder_paths:
|
||||
folder_id = self._controller.get_folder_id_from_path(folder_path)
|
||||
if folder_id:
|
||||
break
|
||||
if folder_id:
|
||||
self._folders_widget.set_selected_folder(folder_id)
|
||||
|
||||
if not indexes:
|
||||
return
|
||||
|
||||
index_deque = collections.deque()
|
||||
for index in indexes:
|
||||
index_deque.append(index)
|
||||
|
||||
all_indexes = []
|
||||
while index_deque:
|
||||
index = index_deque.popleft()
|
||||
all_indexes.append(index)
|
||||
|
||||
parent_index = index.parent()
|
||||
if parent_index.isValid():
|
||||
index_deque.append(parent_index)
|
||||
|
||||
for index in all_indexes:
|
||||
proxy_index = self._proxy_model.mapFromSource(index)
|
||||
self._asset_view.expand(proxy_index)
|
||||
|
||||
def get_selected_asset(self):
|
||||
"""Get selected asset name."""
|
||||
return self._selected_asset
|
||||
def get_selected_folder_path(self):
|
||||
"""Get selected folder path."""
|
||||
return self._selected_folder_path
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ class CreateContextWidget(QtWidgets.QWidget):
|
|||
|
||||
def update_current_context_btn(self):
|
||||
# Hide set current asset if there is no one
|
||||
folder_path = self._controller.current_asset_name
|
||||
folder_path = self._controller.current_folder_path
|
||||
self._current_context_btn.setVisible(bool(folder_path))
|
||||
|
||||
def set_selected_context(self, folder_id, task_name):
|
||||
|
|
@ -252,7 +252,7 @@ class CreateContextWidget(QtWidgets.QWidget):
|
|||
folder_id = self._last_folder_id
|
||||
task_name = self._last_selected_task_name
|
||||
if folder_id is None:
|
||||
folder_path = self._controller.current_asset_name
|
||||
folder_path = self._controller.current_folder_path
|
||||
folder_id = self._controller.get_folder_id_from_path(folder_path)
|
||||
task_name = self._controller.current_task_name
|
||||
self._hierarchy_controller.set_selected_project(
|
||||
|
|
@ -273,7 +273,7 @@ class CreateContextWidget(QtWidgets.QWidget):
|
|||
self.task_changed.emit()
|
||||
|
||||
def _on_current_context_click(self):
|
||||
folder_path = self._controller.current_asset_name
|
||||
folder_path = self._controller.current_folder_path
|
||||
task_name = self._controller.current_task_name
|
||||
folder_id = self._controller.get_folder_id_from_path(folder_path)
|
||||
self._hierarchy_controller.set_expected_selection(
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
|
||||
self._controller = controller
|
||||
|
||||
self._asset_name = None
|
||||
self._folder_path = None
|
||||
self._product_names = None
|
||||
self._selected_creator = None
|
||||
|
||||
|
|
@ -314,8 +314,8 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
self._use_current_context = True
|
||||
|
||||
@property
|
||||
def current_asset_name(self):
|
||||
return self._controller.current_asset_name
|
||||
def current_folder_path(self):
|
||||
return self._controller.current_folder_path
|
||||
|
||||
@property
|
||||
def current_task_name(self):
|
||||
|
|
@ -324,13 +324,13 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
def _context_change_is_enabled(self):
|
||||
return self._context_widget.is_enabled()
|
||||
|
||||
def _get_asset_name(self):
|
||||
def _get_folder_path(self):
|
||||
folder_path = None
|
||||
if self._context_change_is_enabled():
|
||||
folder_path = self._context_widget.get_selected_folder_path()
|
||||
|
||||
if folder_path is None:
|
||||
folder_path = self.current_asset_name
|
||||
folder_path = self.current_folder_path
|
||||
return folder_path or None
|
||||
|
||||
def _get_folder_id(self):
|
||||
|
|
@ -364,12 +364,12 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
self._use_current_context = True
|
||||
|
||||
def refresh(self):
|
||||
current_folder_path = self._controller.current_asset_name
|
||||
current_folder_path = self._controller.current_folder_path
|
||||
current_task_name = self._controller.current_task_name
|
||||
|
||||
# Get context before refresh to keep selection of asset and
|
||||
# task widgets
|
||||
folder_path = self._get_asset_name()
|
||||
folder_path = self._get_folder_path()
|
||||
task_name = self._get_task_name()
|
||||
|
||||
# Replace by current context if last loaded context was
|
||||
|
|
@ -427,7 +427,7 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
|
||||
if (
|
||||
self._context_change_is_enabled()
|
||||
and self._get_asset_name() is None
|
||||
and self._get_folder_path() is None
|
||||
):
|
||||
# QUESTION how to handle invalid asset?
|
||||
prereq_available = False
|
||||
|
|
@ -449,23 +449,25 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
self._on_variant_change()
|
||||
|
||||
def _refresh_product_name(self):
|
||||
asset_name = self._get_asset_name()
|
||||
folder_path = self._get_folder_path()
|
||||
|
||||
# Skip if asset did not change
|
||||
if self._asset_name and self._asset_name == asset_name:
|
||||
if self._folder_path and self._folder_path == folder_path:
|
||||
return
|
||||
|
||||
# Make sure `_asset_name` and `_product_names` variables are reset
|
||||
self._asset_name = asset_name
|
||||
# Make sure `_folder_path` and `_product_names` variables are reset
|
||||
self._folder_path = folder_path
|
||||
self._product_names = None
|
||||
if asset_name is None:
|
||||
if folder_path is None:
|
||||
return
|
||||
|
||||
product_names = self._controller.get_existing_product_names(asset_name)
|
||||
product_names = self._controller.get_existing_product_names(
|
||||
folder_path
|
||||
)
|
||||
|
||||
self._product_names = product_names
|
||||
if product_names is None:
|
||||
self.product_name_input.setText("< Asset is not set >")
|
||||
self.product_name_input.setText("< Folder is not set >")
|
||||
|
||||
def _refresh_creators(self):
|
||||
# Refresh creators and add their product types to list
|
||||
|
|
@ -664,13 +666,13 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
self.product_name_input.setText("< Valid variant >")
|
||||
return
|
||||
|
||||
asset_name = self._get_asset_name()
|
||||
folder_path = self._get_folder_path()
|
||||
task_name = self._get_task_name()
|
||||
creator_idenfier = self._selected_creator.identifier
|
||||
# Calculate product name with Creator plugin
|
||||
try:
|
||||
product_name = self._controller.get_product_name(
|
||||
creator_idenfier, variant_value, task_name, asset_name
|
||||
creator_idenfier, variant_value, task_name, folder_path
|
||||
)
|
||||
except TaskNotSetError:
|
||||
self._create_btn.setEnabled(False)
|
||||
|
|
@ -777,11 +779,11 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
variant = self.variant_input.text()
|
||||
# Care about product name only if context change is enabled
|
||||
product_name = None
|
||||
asset_name = None
|
||||
folder_path = None
|
||||
task_name = None
|
||||
if self._context_change_is_enabled():
|
||||
product_name = self.product_name_input.text()
|
||||
asset_name = self._get_asset_name()
|
||||
folder_path = self._get_folder_path()
|
||||
task_name = self._get_task_name()
|
||||
|
||||
pre_create_data = self._pre_create_widget.current_value()
|
||||
|
|
@ -793,7 +795,7 @@ class CreateWidget(QtWidgets.QWidget):
|
|||
# Where to define these data?
|
||||
# - what data show be stored?
|
||||
instance_data = {
|
||||
"folderPath": asset_name,
|
||||
"folderPath": folder_path,
|
||||
"task": task_name,
|
||||
"variant": variant,
|
||||
"productType": product_type
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ TASK_ORDER_ROLE = QtCore.Qt.UserRole + 3
|
|||
class TasksModel(QtGui.QStandardItemModel):
|
||||
"""Tasks model.
|
||||
|
||||
Task model must have set context of asset documents.
|
||||
Task model must have set context of folder paths.
|
||||
|
||||
Items in model are based on 0-infinite asset documents. Always contain
|
||||
an interserction of context asset tasks. When no assets are in context
|
||||
them model is empty if 2 or more are in context assets that don't have
|
||||
Items in model are based on 0-infinite folders. Always contain
|
||||
an interserction of context folder tasks. When no folders are in context
|
||||
them model is empty if 2 or more are in context folders that don't have
|
||||
tasks with same names then model is empty too.
|
||||
|
||||
Args:
|
||||
|
|
@ -27,21 +27,21 @@ class TasksModel(QtGui.QStandardItemModel):
|
|||
self._allow_empty_task = allow_empty_task
|
||||
self._controller = controller
|
||||
self._items_by_name = {}
|
||||
self._asset_names = []
|
||||
self._task_names_by_asset_name = {}
|
||||
self._folder_paths = []
|
||||
self._task_names_by_folder_path = {}
|
||||
|
||||
def set_asset_names(self, asset_names):
|
||||
def set_folder_paths(self, folder_paths):
|
||||
"""Set assets context."""
|
||||
self._asset_names = asset_names
|
||||
self._folder_paths = folder_paths
|
||||
self.reset()
|
||||
|
||||
@staticmethod
|
||||
def get_intersection_of_tasks(task_names_by_asset_name):
|
||||
def get_intersection_of_tasks(task_names_by_folder_path):
|
||||
"""Calculate intersection of task names from passed data.
|
||||
|
||||
Example:
|
||||
```
|
||||
# Passed `task_names_by_asset_name`
|
||||
# Passed `task_names_by_folder_path`
|
||||
{
|
||||
"asset_1": ["compositing", "animation"],
|
||||
"asset_2": ["compositing", "editorial"]
|
||||
|
|
@ -54,10 +54,10 @@ class TasksModel(QtGui.QStandardItemModel):
|
|||
```
|
||||
|
||||
Args:
|
||||
task_names_by_asset_name (dict): Task names in iterable by parent.
|
||||
task_names_by_folder_path (dict): Task names in iterable by parent.
|
||||
"""
|
||||
tasks = None
|
||||
for task_names in task_names_by_asset_name.values():
|
||||
for task_names in task_names_by_folder_path.values():
|
||||
if tasks is None:
|
||||
tasks = set(task_names)
|
||||
else:
|
||||
|
|
@ -67,41 +67,43 @@ class TasksModel(QtGui.QStandardItemModel):
|
|||
break
|
||||
return tasks or set()
|
||||
|
||||
def is_task_name_valid(self, asset_name, task_name):
|
||||
"""Is task name available for asset.
|
||||
def is_task_name_valid(self, folder_path, task_name):
|
||||
"""Is task name available for folder.
|
||||
|
||||
Args:
|
||||
asset_name (str): Name of asset where should look for task.
|
||||
task_name (str): Name of task which should be available in asset's
|
||||
folder_path (str): Name of asset where should look for task.
|
||||
task_name (str): Name of task which should be available in folder
|
||||
tasks.
|
||||
"""
|
||||
if asset_name not in self._task_names_by_asset_name:
|
||||
if folder_path not in self._task_names_by_folder_path:
|
||||
return False
|
||||
|
||||
if self._allow_empty_task and not task_name:
|
||||
return True
|
||||
|
||||
task_names = self._task_names_by_asset_name[asset_name]
|
||||
task_names = self._task_names_by_folder_path[folder_path]
|
||||
if task_name in task_names:
|
||||
return True
|
||||
return False
|
||||
|
||||
def reset(self):
|
||||
"""Update model by current context."""
|
||||
if not self._asset_names:
|
||||
if not self._folder_paths:
|
||||
self._items_by_name = {}
|
||||
self._task_names_by_asset_name = {}
|
||||
self._task_names_by_folder_path = {}
|
||||
self.clear()
|
||||
return
|
||||
|
||||
task_names_by_asset_name = (
|
||||
self._controller.get_task_names_by_asset_names(self._asset_names)
|
||||
task_names_by_folder_path = (
|
||||
self._controller.get_task_names_by_folder_paths(
|
||||
self._folder_paths
|
||||
)
|
||||
)
|
||||
|
||||
self._task_names_by_asset_name = task_names_by_asset_name
|
||||
self._task_names_by_folder_path = task_names_by_folder_path
|
||||
|
||||
new_task_names = self.get_intersection_of_tasks(
|
||||
task_names_by_asset_name
|
||||
task_names_by_folder_path
|
||||
)
|
||||
if self._allow_empty_task:
|
||||
new_task_names.add("")
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ class AssetsField(BaseClickableFrame):
|
|||
if not result:
|
||||
return
|
||||
|
||||
asset_name = self._dialog.get_selected_asset()
|
||||
asset_name = self._dialog.get_selected_folder_path()
|
||||
if asset_name is None:
|
||||
return
|
||||
|
||||
|
|
@ -495,7 +495,7 @@ class AssetsField(BaseClickableFrame):
|
|||
self.value_changed.emit()
|
||||
|
||||
def _mouse_release_callback(self):
|
||||
self._dialog.set_selected_assets(self._selected_items)
|
||||
self._dialog.set_selected_folders(self._selected_items)
|
||||
self._dialog.open()
|
||||
|
||||
def set_multiselection_text(self, text):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue