From b40e05fcd134e5b9d5aac7ba9e5f45e4e9733607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 2 Jul 2021 10:40:19 +0200 Subject: Assets: Open Blend File operator Add operator 'Open Blend File' to the Asset Browser. This operator: - starts a new Blender process, - opens the blend file containing the asset, - monitors the new Blender process, and when it stops, - reloads the assets to show any changes made. --- release/scripts/startup/bl_operators/assets.py | 83 ++++++++++++++++++++++ release/scripts/startup/bl_ui/space_filebrowser.py | 6 ++ 2 files changed, 89 insertions(+) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_operators/assets.py b/release/scripts/startup/bl_operators/assets.py index 48f07a03773..d2655784afd 100644 --- a/release/scripts/startup/bl_operators/assets.py +++ b/release/scripts/startup/bl_operators/assets.py @@ -18,7 +18,9 @@ # from __future__ import annotations +from pathlib import Path +import bpy from bpy.types import Operator from bpy_extras.asset_utils import ( @@ -72,7 +74,88 @@ class ASSET_OT_tag_remove(Operator): return {'FINISHED'} +class ASSET_OT_open_containing_blend_file(Operator): + """Open the blend file that contains the active asset""" + + bl_idname = "asset.open_containing_blend_file" + bl_label = "Open Blend File" + bl_options = {'REGISTER'} + + _process = None # Optional[subprocess.Popen] + + @classmethod + def poll(cls, context): + asset_file_handle = getattr(context, 'asset_file_handle', None) + asset_library = getattr(context, 'asset_library', None) + + if not asset_library: + cls.poll_message_set("No asset library selected") + return False + if not asset_file_handle: + cls.poll_message_set("No asset selected") + return False + if asset_file_handle.local_id: + cls.poll_message_set("Selected asset is contained in the current file") + return False + return True + + def execute(self, context): + asset_file_handle = context.asset_file_handle + asset_library = context.asset_library + + if asset_file_handle.local_id: + self.report({'WARNING'}, "This asset is stored in the current blend file") + return {'CANCELLED'} + + asset_lib_path = bpy.types.AssetHandle.get_full_library_path(asset_file_handle, asset_library) + self.open_in_new_blender(asset_lib_path) + + wm = context.window_manager + self._timer = wm.event_timer_add(0.1, window=context.window) + wm.modal_handler_add(self) + + return {'RUNNING_MODAL'} + + def modal(self, context, event): + if event.type != 'TIMER': + return {'PASS_THROUGH'} + + if self._process is None: + self.report({'ERROR'}, "Unable to find any running process") + self.cancel(context) + return {'CANCELLED'} + + returncode = self._process.poll() + if returncode is None: + # Process is still running. + return {'RUNNING_MODAL'} + + if returncode: + self.report({'WARNING'}, "Blender subprocess exited with error code %d" % returncode) + + # TODO(Sybren): Replace this with a generic "reload assets" operator + # that can run outside of the Asset Browser context. + if bpy.ops.file.refresh.poll(): + bpy.ops.file.refresh() + if bpy.ops.asset.list_refresh.poll(): + bpy.ops.asset.list_refresh() + + self.cancel(context) + return {'FINISHED'} + + def cancel(self, context): + wm = context.window_manager + wm.event_timer_remove(self._timer) + + def open_in_new_blender(self, filepath): + import subprocess + + cli_args = [bpy.app.binary_path, str(filepath)] + self._process = subprocess.Popen(cli_args) + + classes = ( ASSET_OT_tag_add, ASSET_OT_tag_remove, + ASSET_OT_open_containing_blend_file, ) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 96855cb4a07..8ca93d2406c 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -552,6 +552,10 @@ class FILEBROWSER_MT_context_menu(Menu): sub.operator_context = 'EXEC_DEFAULT' sub.operator("file.delete", text="Delete") + active_asset = asset_utils.SpaceAssetInfo.get_active_asset(context) + if active_asset: + layout.operator("asset.open_containing_blend_file") + layout.separator() sub = layout.row() @@ -613,6 +617,8 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel): row = col.row() row.label(text=asset_lib_path) + row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS') + class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel): bl_label = "Preview" -- cgit v1.2.3