diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index 6e6166c2ef..b7e731bbb6 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -14,7 +14,7 @@ from openpype.tools.workfile_template_build import ( WorkfileBuildPlaceholderDialog, ) -from .lib import read, imprint +from .lib import read, imprint, get_main_window PLACEHOLDER_SET = "PLACEHOLDERS_SET" @@ -173,44 +173,37 @@ class MayaPlaceholderLoadPlugin(PlaceholderPlugin, PlaceholderLoadMixin): def create_placeholder(self, placeholder_data): selection = cmds.ls(selection=True) - if not selection: - raise ValueError("Nothing is selected") if len(selection) > 1: raise ValueError("More then one item are selected") + parent = selection[0] if selection else None + placeholder_data["plugin_identifier"] = self.identifier placeholder_name = self._create_placeholder_name(placeholder_data) placeholder = cmds.spaceLocator(name=placeholder_name)[0] - # TODO: this can crash if selection can't be used - cmds.parent(placeholder, selection[0]) + if parent: + placeholder = cmds.parent(placeholder, selection[0])[0] - # get the long name of the placeholder (with the groups) - placeholder_full_name = ( - cmds.ls(selection[0], long=True)[0] - + "|" - + placeholder.replace("|", "") - ) - - imprint(placeholder_full_name, placeholder_data) + imprint(placeholder, placeholder_data) # Add helper attributes to keep placeholder info cmds.addAttr( - placeholder_full_name, + placeholder, longName="parent", hidden=True, dataType="string" ) cmds.addAttr( - placeholder_full_name, + placeholder, longName="index", hidden=True, attributeType="short", defaultValue=-1 ) - cmds.setAttr(placeholder_full_name + ".parent", "", type="string") + cmds.setAttr(placeholder + ".parent", "", type="string") def update_placeholder(self, placeholder_item, placeholder_data): node_name = placeholder_item.scene_identifier @@ -233,7 +226,7 @@ class MayaPlaceholderLoadPlugin(PlaceholderPlugin, PlaceholderLoadMixin): if placeholder_data.get("plugin_identifier") != self.identifier: continue - # TODO do data validations and maybe updgrades if are invalid + # TODO do data validations and maybe upgrades if they are invalid output.append( LoadPlaceholderItem(node_name, placeholder_data, self) ) @@ -319,8 +312,9 @@ def update_workfile_template(*args): def create_placeholder(*args): host = registered_host() builder = MayaTemplateBuilder(host) - window = WorkfileBuildPlaceholderDialog(host, builder) - window.exec_() + window = WorkfileBuildPlaceholderDialog(host, builder, + parent=get_main_window()) + window.show() def update_placeholder(*args): @@ -343,6 +337,7 @@ def update_placeholder(*args): raise ValueError("Too many selected nodes") placeholder_item = placeholder_items[0] - window = WorkfileBuildPlaceholderDialog(host, builder) + window = WorkfileBuildPlaceholderDialog(host, builder, + parent=get_main_window()) window.set_update_mode(placeholder_item) window.exec_() diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index 72d4ffb476..766fb0bc47 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -25,6 +25,7 @@ from .lib import ( select_nodes, duplicate_node, node_tempfile, + get_main_window ) PLACEHOLDER_SET = "PLACEHOLDERS_SET" @@ -963,8 +964,9 @@ def update_workfile_template(*args): def create_placeholder(*args): host = registered_host() builder = NukeTemplateBuilder(host) - window = WorkfileBuildPlaceholderDialog(host, builder) - window.exec_() + window = WorkfileBuildPlaceholderDialog(host, builder, + parent=get_main_window()) + window.show() def update_placeholder(*args): @@ -988,6 +990,7 @@ def update_placeholder(*args): raise ValueError("Too many selected nodes") placeholder_item = placeholder_items[0] - window = WorkfileBuildPlaceholderDialog(host, builder) + window = WorkfileBuildPlaceholderDialog(host, builder, + parent=get_main_window()) window.set_update_mode(placeholder_item) window.exec_() diff --git a/openpype/tools/publisher/control.py b/openpype/tools/publisher/control.py index 89c2343ef7..502e871edd 100644 --- a/openpype/tools/publisher/control.py +++ b/openpype/tools/publisher/control.py @@ -398,12 +398,22 @@ class PublishReportMaker: exception = result.get("error") if exception: fname, line_no, func, exc = exception.traceback + + # Conversion of exception into string may crash + try: + msg = str(exception) + except BaseException: + msg = ( + "Publisher Controller: ERROR" + " - Failed to get exception message" + ) + # Action result does not have 'is_validation_error' is_validation_error = result.get("is_validation_error", False) output.append({ "type": "error", "is_validation_error": is_validation_error, - "msg": str(exception), + "msg": msg, "filename": str(fname), "lineno": str(line_no), "func": str(func), diff --git a/openpype/tools/publisher/publish_report_viewer/model.py b/openpype/tools/publisher/publish_report_viewer/model.py index ff10e091b8..663a67ac70 100644 --- a/openpype/tools/publisher/publish_report_viewer/model.py +++ b/openpype/tools/publisher/publish_report_viewer/model.py @@ -45,8 +45,13 @@ class InstancesModel(QtGui.QStandardItemModel): instance_items = report_item.instance_items_by_family[family] all_removed = True for instance_item in instance_items: - item = QtGui.QStandardItem(instance_item.label) - instance_label = html_escape(instance_item.label) + src_instance_label = instance_item.label + if src_instance_label is None: + # Do not cause UI crash if label is 'None' + src_instance_label = "No label" + instance_label = html_escape(src_instance_label) + + item = QtGui.QStandardItem(src_instance_label) item.setData(instance_label, ITEM_LABEL_ROLE) item.setData(instance_item.errored, ITEM_ERRORED_ROLE) item.setData(instance_item.id, ITEM_ID_ROLE) diff --git a/openpype/tools/publisher/widgets/list_view_widgets.py b/openpype/tools/publisher/widgets/list_view_widgets.py index 557e6559c8..3370f71701 100644 --- a/openpype/tools/publisher/widgets/list_view_widgets.py +++ b/openpype/tools/publisher/widgets/list_view_widgets.py @@ -116,7 +116,12 @@ class InstanceListItemWidget(QtWidgets.QWidget): self.instance = instance - instance_label = html_escape(instance.label) + instance_label = instance.label + if instance_label is None: + # Do not cause UI crash if label is 'None' + instance_label = "No label" + + instance_label = html_escape(instance_label) subset_name_label = QtWidgets.QLabel(instance_label, self) subset_name_label.setObjectName("ListViewSubsetName") diff --git a/openpype/tools/workfile_template_build/window.py b/openpype/tools/workfile_template_build/window.py index 24d9105223..df7aedf566 100644 --- a/openpype/tools/workfile_template_build/window.py +++ b/openpype/tools/workfile_template_build/window.py @@ -220,7 +220,6 @@ class WorkfileBuildPlaceholderDialog(QtWidgets.QDialog): # TODO much better error handling try: plugin.create_placeholder(options) - self.accept() except Exception: self.log.warning("Something went wrong", exc_info=True) dialog = QtWidgets.QMessageBox(self)