mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
modified save as dialog to contain note and modification from 2.x develop
This commit is contained in:
parent
675aa28eac
commit
01cf7f2cb0
1 changed files with 194 additions and 94 deletions
|
|
@ -36,92 +36,140 @@ class NameWindow(QtWidgets.QDialog):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, parent, root, session=None):
|
||||
def __init__(self, parent, root, anatomy, template_key, session=None):
|
||||
super(NameWindow, self).__init__(parent=parent)
|
||||
self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)
|
||||
|
||||
self.result = None
|
||||
self.result_note = None
|
||||
self.host = api.registered_host()
|
||||
self.root = root
|
||||
self.work_file = None
|
||||
|
||||
if session is None:
|
||||
if not session:
|
||||
# Fallback to active session
|
||||
session = api.Session
|
||||
|
||||
# Set work file data for template formatting
|
||||
project = io.find_one({
|
||||
asset_name = session["AVALON_ASSET"]
|
||||
project_doc = io.find_one({
|
||||
"type": "project"
|
||||
})
|
||||
asset_doc = io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name
|
||||
})
|
||||
self.data = {
|
||||
"project": {
|
||||
"name": project["name"],
|
||||
"code": project["data"].get("code")
|
||||
"name": project_doc["name"],
|
||||
"code": project_doc["data"].get("code")
|
||||
},
|
||||
"asset": session["AVALON_ASSET"],
|
||||
"asset": asset_name,
|
||||
"task": session["AVALON_TASK"],
|
||||
"version": 1,
|
||||
"user": getpass.getuser(),
|
||||
"comment": ""
|
||||
"comment": "",
|
||||
"ext": None,
|
||||
"note": ""
|
||||
}
|
||||
|
||||
# Define work files template
|
||||
anatomy = Anatomy(project["name"])
|
||||
self.template = anatomy.templates["work"]["file"]
|
||||
# Store project anatomy
|
||||
self.anatomy = anatomy
|
||||
self.template = anatomy.templates[template_key]["file"]
|
||||
self.template_key = template_key
|
||||
self.asset_doc = asset_doc
|
||||
|
||||
self.widgets = {
|
||||
"preview": QtWidgets.QLabel("Preview filename"),
|
||||
"comment": QtWidgets.QLineEdit(),
|
||||
"version": QtWidgets.QWidget(),
|
||||
"versionValue": QtWidgets.QSpinBox(),
|
||||
"versionCheck": QtWidgets.QCheckBox("Next Available Version"),
|
||||
"inputs": QtWidgets.QWidget(),
|
||||
"buttons": QtWidgets.QWidget(),
|
||||
"okButton": QtWidgets.QPushButton("Ok"),
|
||||
"cancelButton": QtWidgets.QPushButton("Cancel")
|
||||
}
|
||||
# Btns widget
|
||||
btns_widget = QtWidgets.QWidget(self)
|
||||
|
||||
# Build version
|
||||
self.widgets["versionValue"].setMinimum(1)
|
||||
self.widgets["versionValue"].setMaximum(9999)
|
||||
self.widgets["versionCheck"].setCheckState(QtCore.Qt.CheckState(2))
|
||||
layout = QtWidgets.QHBoxLayout(self.widgets["version"])
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.addWidget(self.widgets["versionValue"])
|
||||
layout.addWidget(self.widgets["versionCheck"])
|
||||
btn_ok = QtWidgets.QPushButton("Ok", btns_widget)
|
||||
btn_cancel = QtWidgets.QPushButton("Cancel", btns_widget)
|
||||
|
||||
# Build buttons
|
||||
layout = QtWidgets.QHBoxLayout(self.widgets["buttons"])
|
||||
layout.addWidget(self.widgets["okButton"])
|
||||
layout.addWidget(self.widgets["cancelButton"])
|
||||
btns_layout = QtWidgets.QHBoxLayout(btns_widget)
|
||||
btns_layout.addWidget(btn_ok)
|
||||
btns_layout.addWidget(btn_cancel)
|
||||
|
||||
# Inputs widget
|
||||
inputs_widget = QtWidgets.QWidget(self)
|
||||
|
||||
# Version widget
|
||||
version_widget = QtWidgets.QWidget(inputs_widget)
|
||||
|
||||
# Version number input
|
||||
version_input = QtWidgets.QSpinBox(version_widget)
|
||||
version_input.setMinimum(1)
|
||||
version_input.setMaximum(9999)
|
||||
|
||||
# Last version checkbox
|
||||
last_version_check = QtWidgets.QCheckBox(
|
||||
"Next Available Version", version_widget
|
||||
)
|
||||
last_version_check.setChecked(True)
|
||||
|
||||
version_layout = QtWidgets.QHBoxLayout(version_widget)
|
||||
version_layout.setContentsMargins(0, 0, 0, 0)
|
||||
version_layout.addWidget(version_input)
|
||||
version_layout.addWidget(last_version_check)
|
||||
|
||||
# Preview widget
|
||||
preview_label = QtWidgets.QLabel("Preview filename", inputs_widget)
|
||||
|
||||
# Comment input
|
||||
comment_input = QtWidgets.QLineEdit(inputs_widget)
|
||||
comment_input.setPlaceholderText("Will be part of filename.")
|
||||
|
||||
# Extensions combobox
|
||||
ext_combo = QtWidgets.QComboBox(inputs_widget)
|
||||
ext_combo.addItems(self.host.file_extensions())
|
||||
|
||||
# Note input
|
||||
note_input = QtWidgets.QLineEdit(inputs_widget)
|
||||
note_input.setPlaceholderText("Artist note to workfile")
|
||||
|
||||
# Build inputs
|
||||
layout = QtWidgets.QFormLayout(self.widgets["inputs"])
|
||||
layout.addRow("Version:", self.widgets["version"])
|
||||
layout.addRow("Comment:", self.widgets["comment"])
|
||||
layout.addRow("Preview:", self.widgets["preview"])
|
||||
inputs_layout = QtWidgets.QFormLayout(inputs_widget)
|
||||
inputs_layout.addRow("Version:", version_widget)
|
||||
inputs_layout.addRow("Comment:", comment_input)
|
||||
inputs_layout.addRow("Extension:", ext_combo)
|
||||
inputs_layout.addRow("Preview:", preview_label)
|
||||
inputs_layout.addRow("Note:", note_input)
|
||||
|
||||
# Build layout
|
||||
layout = QtWidgets.QVBoxLayout(self)
|
||||
layout.addWidget(self.widgets["inputs"])
|
||||
layout.addWidget(self.widgets["buttons"])
|
||||
main_layout = QtWidgets.QVBoxLayout(self)
|
||||
main_layout.addWidget(inputs_widget)
|
||||
main_layout.addWidget(btns_widget)
|
||||
|
||||
self.widgets["versionValue"].valueChanged.connect(
|
||||
self.on_version_spinbox_changed
|
||||
)
|
||||
self.widgets["versionCheck"].stateChanged.connect(
|
||||
# Singal callback registration
|
||||
version_input.valueChanged.connect(self.on_version_spinbox_changed)
|
||||
last_version_check.stateChanged.connect(
|
||||
self.on_version_checkbox_changed
|
||||
)
|
||||
self.widgets["comment"].textChanged.connect(self.on_comment_changed)
|
||||
self.widgets["okButton"].pressed.connect(self.on_ok_pressed)
|
||||
self.widgets["cancelButton"].pressed.connect(self.on_cancel_pressed)
|
||||
|
||||
comment_input.textChanged.connect(self.on_comment_changed)
|
||||
ext_combo.currentIndexChanged.connect(self.on_extension_changed)
|
||||
note_input.textChanged.connect(self.on_note_changed)
|
||||
|
||||
btn_ok.pressed.connect(self.on_ok_pressed)
|
||||
btn_cancel.pressed.connect(self.on_cancel_pressed)
|
||||
|
||||
# Allow "Enter" key to accept the save.
|
||||
self.widgets["okButton"].setDefault(True)
|
||||
btn_ok.setDefault(True)
|
||||
|
||||
# Force default focus to comment, some hosts didn't automatically
|
||||
# apply focus to this line edit (e.g. Houdini)
|
||||
self.widgets["comment"].setFocus()
|
||||
comment_input.setFocus()
|
||||
|
||||
# Store widgets
|
||||
self.btn_ok = btn_ok
|
||||
|
||||
self.version_widget = version_widget
|
||||
self.version_input = version_input
|
||||
self.last_version_check = last_version_check
|
||||
|
||||
self.preview_label = preview_label
|
||||
self.comment_input = comment_input
|
||||
self.ext_combo = ext_combo
|
||||
self.note_input = note_input
|
||||
|
||||
self.refresh()
|
||||
|
||||
|
|
@ -129,15 +177,26 @@ class NameWindow(QtWidgets.QDialog):
|
|||
self.data["version"] = value
|
||||
self.refresh()
|
||||
|
||||
def on_version_checkbox_changed(self, value):
|
||||
def on_version_checkbox_changed(self, _value):
|
||||
self.refresh()
|
||||
|
||||
def on_comment_changed(self, text):
|
||||
self.data["comment"] = text
|
||||
self.refresh()
|
||||
|
||||
def on_note_changed(self, text):
|
||||
self.data["note"] = text
|
||||
|
||||
def on_extension_changed(self):
|
||||
ext = self.ext_combo.currentText()
|
||||
if ext == self.data["ext"]:
|
||||
return
|
||||
self.data["ext"] = ext
|
||||
self.refresh()
|
||||
|
||||
def on_ok_pressed(self):
|
||||
self.result = self.work_file.replace("\\", "/")
|
||||
self.result = self.work_file
|
||||
self.result_note = self.data["note"]
|
||||
self.close()
|
||||
|
||||
def on_cancel_pressed(self):
|
||||
|
|
@ -146,42 +205,57 @@ class NameWindow(QtWidgets.QDialog):
|
|||
def get_result(self):
|
||||
return self.result
|
||||
|
||||
def get_work_file(self, template=None):
|
||||
def get_result_note(self):
|
||||
return self.result_note
|
||||
|
||||
def get_work_file(self):
|
||||
data = copy.deepcopy(self.data)
|
||||
template = template or self.template
|
||||
|
||||
# Define saving file extension
|
||||
current_file = self.host.current_file()
|
||||
if current_file:
|
||||
# Match the extension of current file
|
||||
_, extension = os.path.splitext(current_file)
|
||||
else:
|
||||
# Fall back to the first extension supported for this host.
|
||||
extension = self.host.file_extensions()[0]
|
||||
|
||||
data["ext"] = extension
|
||||
|
||||
if not data["comment"]:
|
||||
data.pop("comment", None)
|
||||
|
||||
return api.format_template_with_optional_keys(data, template)
|
||||
anatomy_filled = self.anatomy.format(data)
|
||||
return anatomy_filled[self.template_key]["file"]
|
||||
|
||||
def refresh(self):
|
||||
# Since the version can be padded with "{version:0>4}" we only search
|
||||
# for "{version".
|
||||
if "{version" not in self.template:
|
||||
# todo: hide the full row
|
||||
self.widgets["version"].setVisible(False)
|
||||
# TODO hide the full row
|
||||
self.version_widget.setVisible(False)
|
||||
|
||||
# Build comment
|
||||
if "{comment}" not in self.template:
|
||||
# todo: hide the full row
|
||||
self.widgets["comment"].setVisible(False)
|
||||
# TODO hide the full row
|
||||
self.comment_input.setVisible(False)
|
||||
|
||||
if self.widgets["versionCheck"].isChecked():
|
||||
self.widgets["versionValue"].setEnabled(False)
|
||||
extensions = self.host.file_extensions()
|
||||
extension = self.data["ext"]
|
||||
if extension is None:
|
||||
# Define saving file extension
|
||||
current_file = self.host.current_file()
|
||||
if current_file:
|
||||
# Match the extension of current file
|
||||
_, extension = os.path.splitext(current_file)
|
||||
else:
|
||||
extension = extensions[0]
|
||||
|
||||
if extension != self.data["ext"]:
|
||||
self.data["ext"] = extension
|
||||
index = self.ext_combo.findText(
|
||||
extension, QtCore.Qt.MatchFixedString
|
||||
)
|
||||
if index >= 0:
|
||||
self.ext_combo.setCurrentIndex(index)
|
||||
|
||||
if not self.last_version_check.isChecked():
|
||||
self.version_input.setEnabled(True)
|
||||
self.data["version"] = self.version_input.value()
|
||||
|
||||
work_file = self.get_work_file()
|
||||
|
||||
else:
|
||||
self.version_input.setEnabled(False)
|
||||
|
||||
extensions = self.host.file_extensions()
|
||||
data = copy.deepcopy(self.data)
|
||||
template = str(self.template)
|
||||
|
||||
|
|
@ -197,32 +271,49 @@ class NameWindow(QtWidgets.QDialog):
|
|||
else:
|
||||
version += 1
|
||||
|
||||
self.data["version"] = version
|
||||
found_valid_version = False
|
||||
# Check if next version is valid version and give a chance to try
|
||||
# next 100 versions
|
||||
for idx in range(100):
|
||||
# Store version to data
|
||||
self.data["version"] = version
|
||||
|
||||
# safety check
|
||||
path = os.path.join(self.root, self.get_work_file())
|
||||
assert not os.path.exists(path), \
|
||||
"This is a bug, file exists: %s" % path
|
||||
work_file = self.get_work_file()
|
||||
# Safety check
|
||||
path = os.path.join(self.root, work_file)
|
||||
if not os.path.exists(path):
|
||||
found_valid_version = True
|
||||
break
|
||||
|
||||
else:
|
||||
self.widgets["versionValue"].setEnabled(True)
|
||||
self.data["version"] = self.widgets["versionValue"].value()
|
||||
# Try next version
|
||||
version += 1
|
||||
# Log warning
|
||||
if idx == 0:
|
||||
log.warning((
|
||||
"BUG: Function `last_workfile_with_version` "
|
||||
"didn't return last version."
|
||||
))
|
||||
# Raise exception if even 100 version fallback didn't help
|
||||
if not found_valid_version:
|
||||
raise AssertionError(
|
||||
"This is a bug. Couldn't find valid version!"
|
||||
)
|
||||
|
||||
self.work_file = self.get_work_file()
|
||||
self.work_file = work_file
|
||||
|
||||
preview = self.widgets["preview"]
|
||||
ok = self.widgets["okButton"]
|
||||
preview.setText(
|
||||
"<font color='green'>{0}</font>".format(self.work_file)
|
||||
)
|
||||
if os.path.exists(os.path.join(self.root, self.work_file)):
|
||||
preview.setText(
|
||||
path_exists = os.path.exists(os.path.join(self.root, work_file))
|
||||
|
||||
self.btn_ok.setEnabled(not path_exists)
|
||||
|
||||
if path_exists:
|
||||
self.preview_label.setText(
|
||||
"<font color='red'>Cannot create \"{0}\" because file exists!"
|
||||
"</font>".format(self.work_file)
|
||||
"</font>".format(work_file)
|
||||
)
|
||||
ok.setEnabled(False)
|
||||
else:
|
||||
ok.setEnabled(True)
|
||||
self.preview_label.setText(
|
||||
"<font color='green'>{0}</font>".format(work_file)
|
||||
)
|
||||
|
||||
|
||||
class TasksWidget(QtWidgets.QWidget):
|
||||
|
|
@ -334,6 +425,15 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
# Setup
|
||||
self._asset = None
|
||||
self._task = None
|
||||
|
||||
# Pype's anatomy object for current project
|
||||
self.anatomy = Anatomy(io.Session["AVALON_PROJECT"])
|
||||
# Template key used to get work template from anatomy templates
|
||||
# TODO change template key based on task
|
||||
self.template_key = "work"
|
||||
|
||||
# Do not set root with Anatomy's roots because it would break host's
|
||||
# implementation of `work_root` function
|
||||
self.root = None
|
||||
self.host = api.registered_host()
|
||||
|
||||
|
|
@ -518,6 +618,8 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
window = NameWindow(
|
||||
parent=self,
|
||||
root=self.root,
|
||||
anatomy=self.anatomy,
|
||||
template_key=self.template_key,
|
||||
session=session
|
||||
)
|
||||
window.exec_()
|
||||
|
|
@ -785,7 +887,6 @@ class Window(QtWidgets.QMainWindow):
|
|||
self.widgets["tasks"].select_task(context["task"])
|
||||
|
||||
def refresh(self):
|
||||
|
||||
# Refresh asset widget
|
||||
self.widgets["assets"].refresh()
|
||||
|
||||
|
|
@ -806,7 +907,6 @@ class Window(QtWidgets.QMainWindow):
|
|||
self.widgets["tasks"].set_asset(asset)
|
||||
|
||||
def _on_task_changed(self):
|
||||
|
||||
asset = self.widgets["assets"].get_selected_assets() or None
|
||||
if asset is not None:
|
||||
asset = asset[0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue