diff --git a/client/ayon_core/tools/launcher/ui/actions_widget.py b/client/ayon_core/tools/launcher/ui/actions_widget.py index d03aceb009..2ffce13292 100644 --- a/client/ayon_core/tools/launcher/ui/actions_widget.py +++ b/client/ayon_core/tools/launcher/ui/actions_widget.py @@ -290,6 +290,34 @@ class ActionDelegate(QtWidgets.QStyledItemDelegate): painter.drawPixmap(extender_x, extender_y, pix) +class ActionsProxyModel(QtCore.QSortFilterProxyModel): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive) + + def lessThan(self, left, right): + # Sort by action order and then by label + left_value = left.data(ACTION_SORT_ROLE) + right_value = right.data(ACTION_SORT_ROLE) + + # Values are same -> use super sorting + if left_value == right_value: + # Default behavior is using DisplayRole + return super().lessThan(left, right) + + # Validate 'None' values + if right_value is None: + return True + if left_value is None: + return False + # Sort values and handle incompatible types + try: + return left_value < right_value + except TypeError: + return True + + class ActionsWidget(QtWidgets.QWidget): def __init__(self, controller, parent): super(ActionsWidget, self).__init__(parent) @@ -316,10 +344,7 @@ class ActionsWidget(QtWidgets.QWidget): model = ActionsQtModel(controller) - proxy_model = QtCore.QSortFilterProxyModel() - proxy_model.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive) - proxy_model.setSortRole(ACTION_SORT_ROLE) - + proxy_model = ActionsProxyModel() proxy_model.setSourceModel(model) view.setModel(proxy_model) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index f0a36d4740..749077d2a8 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -47,7 +47,7 @@ plugin_for = ["ayon_server"] """ CLIENT_VERSION_CONTENT = '''# -*- coding: utf-8 -*- -"""Package declaring AYON core addon version.""" +"""Package declaring AYON addon '{}' version.""" __version__ = "{}" ''' @@ -183,6 +183,7 @@ def create_addon_zip( def prepare_client_code( + addon_name: str, addon_dir: Path, addon_output_dir: Path, addon_version: str @@ -211,7 +212,9 @@ def prepare_client_code( version_path = subpath / "version.py" if version_path.exists(): with open(version_path, "w") as stream: - stream.write(CLIENT_VERSION_CONTENT.format(addon_version)) + stream.write( + CLIENT_VERSION_CONTENT.format(addon_name, addon_version) + ) zip_filepath = private_dir / "client.zip" with ZipFileLongPaths(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf: @@ -262,7 +265,9 @@ def create_addon_package( server_dir, addon_output_dir / "server", dirs_exist_ok=True ) - prepare_client_code(addon_dir, addon_output_dir, addon_version) + prepare_client_code( + package.name, addon_dir, addon_output_dir, addon_version + ) if create_zip: create_addon_zip( diff --git a/server_addon/houdini/client/ayon_houdini/plugins/publish/collect_local_render_instances.py b/server_addon/houdini/client/ayon_houdini/plugins/publish/collect_local_render_instances.py index 0b3eab725d..efc029373b 100644 --- a/server_addon/houdini/client/ayon_houdini/plugins/publish/collect_local_render_instances.py +++ b/server_addon/houdini/client/ayon_houdini/plugins/publish/collect_local_render_instances.py @@ -134,6 +134,6 @@ class CollectLocalRenderInstances(pyblish.api.InstancePlugin): ] }) - # Remove original render instance - # I can't remove it here as I still need it to trigger the render. - # context.remove(instance) + # Skip integrating original render instance. + # We are not removing it because it's used to trigger the render. + instance.data["integrate"] = False