From 59f58d92b8d409392fc306983eac7d27802eaa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 15 Mar 2022 18:45:28 +0100 Subject: [PATCH] Addon: add file browser buttons to file/directory path settings/properties --- addon/flamenco/gui.py | 20 +++++++++++---- addon/flamenco/operators.py | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/addon/flamenco/gui.py b/addon/flamenco/gui.py index d316ea51..6a5963d3 100644 --- a/addon/flamenco/gui.py +++ b/addon/flamenco/gui.py @@ -41,6 +41,8 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel): col.prop(context.scene, "flamenco_job_name", text="Job Name") row = col.row(align=True) row.prop(context.scene, "flamenco_job_storage", text="Job Storage") + prop = row.operator("flamenco3.explore_file_path", text="", icon="WINDOW") + prop.path = context.scene.flamenco_job_storage layout.separator() @@ -88,10 +90,19 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel): if not setting.get("visible", True): return + row = layout.row(align=True) if setting.get("editable", True): - self.draw_setting_editable(layout, propgroup, setting) + self.draw_setting_editable(row, propgroup, setting) else: - self.draw_setting_readonly(context, layout, propgroup, setting) + self.draw_setting_readonly(context, row, propgroup, setting) + + if str(setting.type) == "string" and str(setting.get("subtype", "")) in { + "dir_path", + "file_path", + "hashed_file_path", + }: + op = row.operator("flamenco3.explore_file_path", text="", icon="WINDOW") + op.path = getattr(propgroup, setting.key) def draw_setting_editable( self, @@ -99,13 +110,12 @@ class FLAMENCO_PT_job_submission(bpy.types.Panel): propgroup: JobTypePropertyGroup, setting: _AvailableJobSetting, ) -> None: - row = layout.row(align=True) - row.prop(propgroup, setting.key) + layout.prop(propgroup, setting.key) setting_eval = setting.get("eval", "") if not setting_eval: return - props = row.operator("flamenco.eval_setting", text="", icon="SCRIPTPLUGINS") + props = layout.operator("flamenco.eval_setting", text="", icon="SCRIPTPLUGINS") props.setting_key = setting.key props.setting_eval = setting_eval diff --git a/addon/flamenco/operators.py b/addon/flamenco/operators.py index f611e455..92343d98 100644 --- a/addon/flamenco/operators.py +++ b/addon/flamenco/operators.py @@ -305,10 +305,60 @@ class FLAMENCO_OT_submit_job(FlamencoOpMixin, bpy.types.Operator): return {"FINISHED"} +class FLAMENCO3_OT_explore_file_path(bpy.types.Operator): + """Opens the given path in a file explorer. + + If the path cannot be found, this operator tries to open its parent. + """ + + bl_idname = "flamenco3.explore_file_path" + bl_label = "Open in file explorer" + bl_description = __doc__.rstrip(".") + + path: bpy.props.StringProperty( + name="Path", description="Path to explore", subtype="DIR_PATH" + ) + + def execute(self, context): + import platform + import pathlib + + # Possibly open a parent of the path + to_open = pathlib.Path(self.path) + while to_open.parent != to_open: # while we're not at the root + if to_open.exists(): + break + to_open = to_open.parent + else: + self.report( + {"ERROR"}, "Unable to open %s or any of its parents." % self.path + ) + return {"CANCELLED"} + to_open = str(to_open) + + if platform.system() == "Windows": + import os + + os.startfile(to_open) + + elif platform.system() == "Darwin": + import subprocess + + subprocess.Popen(["open", to_open]) + + else: + import subprocess + + subprocess.Popen(["xdg-open", to_open]) + + return {"FINISHED"} + + classes = ( FLAMENCO_OT_fetch_job_types, FLAMENCO_OT_ping_manager, FLAMENCO_OT_eval_setting, FLAMENCO_OT_submit_job, + FLAMENCO3_OT_explore_file_path, ) register, unregister = bpy.utils.register_classes_factory(classes)