mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge pull request #2504 from pypeclub/bugfix/OP-2347_Maya-Workdirs--Workspacemel-get-nested-down-when-switching-via-Work-Files-tool
Workfiles Tool can handle when workfile is not created directly in workdir path
This commit is contained in:
commit
7d8b36ac7d
4 changed files with 99 additions and 78 deletions
|
|
@ -218,12 +218,10 @@ def on_task_changed(*args):
|
|||
)
|
||||
|
||||
|
||||
def before_workfile_save(workfile_path):
|
||||
if not workfile_path:
|
||||
return
|
||||
|
||||
workdir = os.path.dirname(workfile_path)
|
||||
copy_workspace_mel(workdir)
|
||||
def before_workfile_save(event):
|
||||
workdir_path = event.workdir_path
|
||||
if workdir_path:
|
||||
copy_workspace_mel(workdir_path)
|
||||
|
||||
|
||||
class MayaDirmap(HostDirmap):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
from .events import (
|
||||
BaseEvent,
|
||||
BeforeWorkfileSave
|
||||
)
|
||||
|
||||
from .attribute_definitions import (
|
||||
AbtractAttrDef,
|
||||
UnknownDef,
|
||||
|
|
@ -9,6 +14,9 @@ from .attribute_definitions import (
|
|||
|
||||
|
||||
__all__ = (
|
||||
"BaseEvent",
|
||||
"BeforeWorkfileSave",
|
||||
|
||||
"AbtractAttrDef",
|
||||
"UnknownDef",
|
||||
"NumberDef",
|
||||
|
|
|
|||
51
openpype/pipeline/lib/events.py
Normal file
51
openpype/pipeline/lib/events.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
"""Events holding data about specific event."""
|
||||
|
||||
|
||||
# Inherit from 'object' for Python 2 hosts
|
||||
class BaseEvent(object):
|
||||
"""Base event object.
|
||||
|
||||
Can be used to anything because data are not much specific. Only required
|
||||
argument is topic which defines why event is happening and may be used for
|
||||
filtering.
|
||||
|
||||
Arg:
|
||||
topic (str): Identifier of event.
|
||||
data (Any): Data specific for event. Dictionary is recommended.
|
||||
"""
|
||||
_data = {}
|
||||
|
||||
def __init__(self, topic, data=None):
|
||||
self._topic = topic
|
||||
if data is None:
|
||||
data = {}
|
||||
self._data = data
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
return self._data
|
||||
|
||||
@property
|
||||
def topic(self):
|
||||
return self._topic
|
||||
|
||||
@classmethod
|
||||
def emit(cls, *args, **kwargs):
|
||||
"""Create object of event and emit.
|
||||
|
||||
Args:
|
||||
Same args as '__init__' expects which may be class specific.
|
||||
"""
|
||||
from avalon import pipeline
|
||||
|
||||
obj = cls(*args, **kwargs)
|
||||
pipeline.emit(obj.topic, [obj])
|
||||
return obj
|
||||
|
||||
|
||||
class BeforeWorkfileSave(BaseEvent):
|
||||
"""Before workfile changes event data."""
|
||||
def __init__(self, filename, workdir):
|
||||
super(BeforeWorkfileSave, self).__init__("before.workfile.save")
|
||||
self.filename = filename
|
||||
self.workdir_path = workdir
|
||||
|
|
@ -11,6 +11,7 @@ from Qt import QtWidgets, QtCore
|
|||
from avalon import io, api, pipeline
|
||||
|
||||
from openpype import style
|
||||
from openpype.pipeline.lib import BeforeWorkfileSave
|
||||
from openpype.tools.utils.lib import (
|
||||
qt_app_context
|
||||
)
|
||||
|
|
@ -367,7 +368,8 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
self.template_key = "work"
|
||||
|
||||
# This is not root but workfile directory
|
||||
self.root = None
|
||||
self._workfiles_root = None
|
||||
self._workdir_path = None
|
||||
self.host = api.registered_host()
|
||||
|
||||
# Whether to automatically select the latest modified
|
||||
|
|
@ -465,8 +467,9 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
# This way we can browse it even before we enter it.
|
||||
if self._asset_id and self._task_name and self._task_type:
|
||||
session = self._get_session()
|
||||
self.root = self.host.work_root(session)
|
||||
self.files_model.set_root(self.root)
|
||||
self._workdir_path = session["AVALON_WORKDIR"]
|
||||
self._workfiles_root = self.host.work_root(session)
|
||||
self.files_model.set_root(self._workfiles_root)
|
||||
|
||||
else:
|
||||
self.files_model.set_root(None)
|
||||
|
|
@ -590,7 +593,7 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
|
||||
window = NameWindow(
|
||||
parent=self,
|
||||
root=self.root,
|
||||
root=self._workfiles_root,
|
||||
anatomy=self.anatomy,
|
||||
template_key=self.template_key,
|
||||
session=session
|
||||
|
|
@ -605,7 +608,7 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
return
|
||||
|
||||
src = self._get_selected_filepath()
|
||||
dst = os.path.join(self.root, work_file)
|
||||
dst = os.path.join(self._workfiles_root, work_file)
|
||||
shutil.copy(src, dst)
|
||||
|
||||
self.workfile_created.emit(dst)
|
||||
|
|
@ -638,98 +641,59 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
"filter": ext_filter
|
||||
}
|
||||
if Qt.__binding__ in ("PySide", "PySide2"):
|
||||
kwargs["dir"] = self.root
|
||||
kwargs["dir"] = self._workfiles_root
|
||||
else:
|
||||
kwargs["directory"] = self.root
|
||||
kwargs["directory"] = self._workfiles_root
|
||||
|
||||
work_file = QtWidgets.QFileDialog.getOpenFileName(**kwargs)[0]
|
||||
if work_file:
|
||||
self.open_file(work_file)
|
||||
|
||||
def on_save_as_pressed(self):
|
||||
work_file = self.get_filename()
|
||||
if not work_file:
|
||||
work_filename = self.get_filename()
|
||||
if not work_filename:
|
||||
return
|
||||
|
||||
# Initialize work directory if it has not been initialized before
|
||||
if not os.path.exists(self.root):
|
||||
log.debug("Initializing Work Directory: %s", self.root)
|
||||
self.initialize_work_directory()
|
||||
if not os.path.exists(self.root):
|
||||
# Failed to initialize Work Directory
|
||||
log.error(
|
||||
"Failed to initialize Work Directory: {}".format(self.root)
|
||||
)
|
||||
return
|
||||
|
||||
file_path = os.path.join(os.path.normpath(self.root), work_file)
|
||||
|
||||
pipeline.emit("before.workfile.save", [file_path])
|
||||
|
||||
self._enter_session() # Make sure we are in the right session
|
||||
self.host.save_file(file_path)
|
||||
# Trigger before save event
|
||||
BeforeWorkfileSave.emit(work_filename, self._workdir_path)
|
||||
|
||||
# Make sure workfiles root is updated
|
||||
# - this triggers 'workio.work_root(...)' which may change value of
|
||||
# '_workfiles_root'
|
||||
self.set_asset_task(
|
||||
self._asset_id, self._task_name, self._task_type
|
||||
)
|
||||
|
||||
# Create workfiles root folder
|
||||
if not os.path.exists(self._workfiles_root):
|
||||
log.debug("Initializing Work Directory: %s", self._workfiles_root)
|
||||
os.makedirs(self._workfiles_root)
|
||||
|
||||
# Update session if context has changed
|
||||
self._enter_session()
|
||||
# Prepare full path to workfile and save it
|
||||
filepath = os.path.join(
|
||||
os.path.normpath(self._workfiles_root), work_filename
|
||||
)
|
||||
self.host.save_file(filepath)
|
||||
# Create extra folders
|
||||
create_workdir_extra_folders(
|
||||
self.root,
|
||||
self._workdir_path,
|
||||
api.Session["AVALON_APP"],
|
||||
self._task_type,
|
||||
self._task_name,
|
||||
api.Session["AVALON_PROJECT"]
|
||||
)
|
||||
pipeline.emit("after.workfile.save", [file_path])
|
||||
|
||||
self.workfile_created.emit(file_path)
|
||||
# Trigger after save events
|
||||
pipeline.emit("after.workfile.save", [filepath])
|
||||
|
||||
self.workfile_created.emit(filepath)
|
||||
# Refresh files model
|
||||
self.refresh()
|
||||
|
||||
def on_file_select(self):
|
||||
self.file_selected.emit(self._get_selected_filepath())
|
||||
|
||||
def initialize_work_directory(self):
|
||||
"""Initialize Work Directory.
|
||||
|
||||
This is used when the Work Directory does not exist yet.
|
||||
|
||||
This finds the current AVALON_APP_NAME and tries to triggers its
|
||||
`.toml` initialization step. Note that this will only be valid
|
||||
whenever `AVALON_APP_NAME` is actually set in the current session.
|
||||
|
||||
"""
|
||||
|
||||
# Inputs (from the switched session and running app)
|
||||
session = api.Session.copy()
|
||||
changes = pipeline.compute_session_changes(
|
||||
session,
|
||||
asset=self._get_asset_doc(),
|
||||
task=self._task_name,
|
||||
template_key=self.template_key
|
||||
)
|
||||
session.update(changes)
|
||||
|
||||
# Prepare documents to get workdir data
|
||||
project_doc = io.find_one({"type": "project"})
|
||||
asset_doc = io.find_one(
|
||||
{
|
||||
"type": "asset",
|
||||
"name": session["AVALON_ASSET"]
|
||||
}
|
||||
)
|
||||
task_name = session["AVALON_TASK"]
|
||||
host_name = session["AVALON_APP"]
|
||||
|
||||
# Get workdir from collected documents
|
||||
workdir = get_workdir(project_doc, asset_doc, task_name, host_name)
|
||||
# Create workdir if does not exist yet
|
||||
if not os.path.exists(workdir):
|
||||
os.makedirs(workdir)
|
||||
|
||||
# Force a full to the asset as opposed to just self.refresh() so
|
||||
# that it will actually check again whether the Work directory exists
|
||||
self.set_asset_task(self._asset_id, self._task_name, self._task_type)
|
||||
|
||||
def refresh(self):
|
||||
"""Refresh listed files for current selection in the interface"""
|
||||
self.files_model.refresh()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue