diff --git a/src/bonsai/bonsai/bim/__init__.py b/src/bonsai/bonsai/bim/__init__.py index babf0e74e9..9a45e71c71 100644 --- a/src/bonsai/bonsai/bim/__init__.py +++ b/src/bonsai/bonsai/bim/__init__.py @@ -110,6 +110,7 @@ classes = [ operator.EditBlenderCollection, operator.FileAssociate, operator.FileUnassociate, + operator.OpenPath, operator.OpenUpstream, operator.OpenUri, operator.ReloadIfcFile, diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index 7e342a9122..6ccab056be 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -93,6 +93,23 @@ class OpenUri(bpy.types.Operator): return {"FINISHED"} +class OpenPath(bpy.types.Operator): + bl_idname = "bim.open_path" + bl_label = "Open Path" + path: bpy.props.StringProperty() + tooltip: bpy.props.StringProperty() + + @classmethod + def description(cls, context, properties): + if properties.tooltip: + return properties.tooltip + return f"Open path: '{properties.path}'." + + def execute(self, context): + tool.Blender.open_file_or_folder(self.path) + return {"FINISHED"} + + class CloseError(bpy.types.Operator): bl_idname = "bim.close_error" bl_label = "Close Error" diff --git a/src/bonsai/bonsai/tool/blender.py b/src/bonsai/bonsai/tool/blender.py index 2ab3a34e97..7fe6551adc 100644 --- a/src/bonsai/bonsai/tool/blender.py +++ b/src/bonsai/bonsai/tool/blender.py @@ -22,6 +22,7 @@ import bmesh import json import os import platform +import subprocess from ifcopenshell import entity_instance import ifcopenshell.api import ifcopenshell.util.element @@ -832,6 +833,15 @@ class Blender(bonsai.core.tool.Blender): operator_invoke_filepath_hotkeys_description = "Hold Shift to open the file, Alt to browse containing directory" + @classmethod + def open_file_or_folder(cls, path: str) -> None: + if platform.system() == "Windows": + os.startfile(path) + elif platform.system() == "Darwin": + subprocess.Popen(["open", path]) + else: + subprocess.Popen(["xdg-open", path]) + @classmethod def operator_invoke_filepath_hotkeys( cls, operator: bpy.types.Operator, context: bpy.types.Context, event: bpy.types.Event, filepath: Path @@ -839,18 +849,6 @@ class Blender(bonsai.core.tool.Blender): if not event.alt and not event.shift: return - import platform - import os - import subprocess - - def open_file_or_folder(path): - if platform.system() == "Windows": - os.startfile(path) - elif platform.system() == "Darwin": - subprocess.Popen(["open", path]) - else: - subprocess.Popen(["xdg-open", path]) - # resolve relative filepaths with .blend path by default if not filepath.is_absolute(): if bpy.data.filepath: @@ -866,14 +864,14 @@ class Blender(bonsai.core.tool.Blender): if not filepath.exists(): operator.report({"ERROR"}, f'Cannot open non-existing directory: "{filepath.as_posix()}"') return {"CANCELLED"} - open_file_or_folder(filepath.as_posix()) + cls.open_file_or_folder(filepath.as_posix()) return {"PASS_THROUGH"} # holding sHIFT - open file if not filepath.exists(): operator.report({"ERROR"}, f'Cannot open non-existing file: "{filepath.as_posix()}"') return {"CANCELLED"} - open_file_or_folder(filepath.as_posix()) + cls.open_file_or_folder(filepath.as_posix()) return {"PASS_THROUGH"} @classmethod