diff options
Diffstat (limited to 'release/scripts/startup/bl_operators/wm.py')
-rw-r--r-- | release/scripts/startup/bl_operators/wm.py | 494 |
1 files changed, 342 insertions, 152 deletions
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index edca3a521ee..0ccdd3cf5c6 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -19,13 +19,17 @@ # <pep8 compliant> import bpy -from bpy.types import Operator +from bpy.types import ( + Operator, + OperatorFileListElement +) from bpy.props import ( BoolProperty, EnumProperty, FloatProperty, IntProperty, StringProperty, + CollectionProperty, ) from bpy.app.translations import pgettext_tip as tip_ @@ -55,6 +59,15 @@ rna_relative_prop = BoolProperty( default=False, ) +rna_space_type_prop = EnumProperty( + name="Type", + items=tuple( + (e.identifier, e.name, "", e. value) + for e in bpy.types.Space.bl_rna.properties["type"].enum_items + ), + default='EMPTY', +) + def context_path_validate(context, data_path): try: @@ -149,12 +162,12 @@ class BRUSH_OT_active_index_set(Operator): bl_idname = "brush.active_index_set" bl_label = "Set Brush Number" - mode = StringProperty( + mode: StringProperty( name="Mode", description="Paint mode to set brush for", maxlen=1024, ) - index = IntProperty( + index: IntProperty( name="Number", description="Brush number", ) @@ -186,8 +199,8 @@ class WM_OT_context_set_boolean(Operator): bl_label = "Context Set Boolean" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = BoolProperty( + data_path: rna_path_prop + value: BoolProperty( name="Value", description="Assignment value", default=True, @@ -202,13 +215,13 @@ class WM_OT_context_set_int(Operator): # same as enum bl_label = "Context Set" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = IntProperty( + data_path: rna_path_prop + value: IntProperty( name="Value", description="Assign value", default=0, ) - relative = rna_relative_prop + relative: rna_relative_prop execute = execute_context_assign @@ -219,8 +232,8 @@ class WM_OT_context_scale_float(Operator): bl_label = "Context Scale Float" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = FloatProperty( + data_path: rna_path_prop + value: FloatProperty( name="Value", description="Assign value", default=1.0, @@ -247,13 +260,13 @@ class WM_OT_context_scale_int(Operator): bl_label = "Context Scale Int" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = FloatProperty( + data_path: rna_path_prop + value: FloatProperty( name="Value", description="Assign value", default=1.0, ) - always_step = BoolProperty( + always_step: BoolProperty( name="Always Step", description="Always adjust the value by a minimum of 1 when 'value' is not 1.0", default=True, @@ -290,13 +303,13 @@ class WM_OT_context_set_float(Operator): # same as enum bl_label = "Context Set Float" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = FloatProperty( + data_path: rna_path_prop + value: FloatProperty( name="Value", description="Assignment value", default=0.0, ) - relative = rna_relative_prop + relative: rna_relative_prop execute = execute_context_assign @@ -307,8 +320,8 @@ class WM_OT_context_set_string(Operator): # same as enum bl_label = "Context Set String" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = StringProperty( + data_path: rna_path_prop + value: StringProperty( name="Value", description="Assign value", maxlen=1024, @@ -323,8 +336,8 @@ class WM_OT_context_set_enum(Operator): bl_label = "Context Set Enum" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = StringProperty( + data_path: rna_path_prop + value: StringProperty( name="Value", description="Assignment value (as a string)", maxlen=1024, @@ -339,8 +352,8 @@ class WM_OT_context_set_value(Operator): bl_label = "Context Set Value" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = StringProperty( + data_path: rna_path_prop + value: StringProperty( name="Value", description="Assignment value (as a string)", maxlen=1024, @@ -360,7 +373,7 @@ class WM_OT_context_toggle(Operator): bl_label = "Context Toggle" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop + data_path: rna_path_prop def execute(self, context): data_path = self.data_path @@ -379,13 +392,13 @@ class WM_OT_context_toggle_enum(Operator): bl_label = "Context Toggle Values" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value_1 = StringProperty( + data_path: rna_path_prop + value_1: StringProperty( name="Value", description="Toggle enum", maxlen=1024, ) - value_2 = StringProperty( + value_2: StringProperty( name="Value", description="Toggle enum", maxlen=1024, @@ -418,9 +431,9 @@ class WM_OT_context_cycle_int(Operator): bl_label = "Context Int Cycle" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - reverse = rna_reverse_prop - wrap = rna_wrap_prop + data_path: rna_path_prop + reverse: rna_reverse_prop + wrap: rna_wrap_prop def execute(self, context): data_path = self.data_path @@ -454,9 +467,9 @@ class WM_OT_context_cycle_enum(Operator): bl_label = "Context Enum Cycle" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - reverse = rna_reverse_prop - wrap = rna_wrap_prop + data_path: rna_path_prop + reverse: rna_reverse_prop + wrap: rna_wrap_prop def execute(self, context): data_path = self.data_path @@ -511,8 +524,8 @@ class WM_OT_context_cycle_array(Operator): bl_label = "Context Array Cycle" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - reverse = rna_reverse_prop + data_path: rna_path_prop + reverse: rna_reverse_prop def execute(self, context): data_path = self.data_path @@ -536,7 +549,8 @@ class WM_OT_context_menu_enum(Operator): bl_idname = "wm.context_menu_enum" bl_label = "Context Enum Menu" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop + + data_path: rna_path_prop def execute(self, context): data_path = self.data_path @@ -562,7 +576,8 @@ class WM_OT_context_pie_enum(Operator): bl_idname = "wm.context_pie_enum" bl_label = "Context Enum Pie" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop + + data_path: rna_path_prop def invoke(self, context, event): wm = context.window_manager @@ -589,12 +604,13 @@ class WM_OT_operator_pie_enum(Operator): bl_idname = "wm.operator_pie_enum" bl_label = "Operator Enum Pie" bl_options = {'UNDO', 'INTERNAL'} - data_path = StringProperty( + + data_path: StringProperty( name="Operator", description="Operator name (in python as string)", maxlen=1024, ) - prop_string = StringProperty( + prop_string: StringProperty( name="Property", description="Property name (as a string)", maxlen=1024, @@ -633,8 +649,8 @@ class WM_OT_context_set_id(Operator): bl_label = "Set Library ID" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path_prop - value = StringProperty( + data_path: rna_path_prop + value: StringProperty( name="Value", description="Assign value", maxlen=1024, @@ -684,10 +700,10 @@ class WM_OT_context_collection_boolean_set(Operator): bl_label = "Context Collection Boolean Set" bl_options = {'UNDO', 'REGISTER', 'INTERNAL'} - data_path_iter = data_path_iter - data_path_item = data_path_item + data_path_iter: data_path_iter + data_path_item: data_path_item - type = EnumProperty( + type: EnumProperty( name="Type", items=(('TOGGLE', "Toggle", ""), ('ENABLE', "Enable", ""), @@ -743,22 +759,22 @@ class WM_OT_context_modal_mouse(Operator): bl_label = "Context Modal Mouse" bl_options = {'GRAB_CURSOR', 'BLOCKING', 'UNDO', 'INTERNAL'} - data_path_iter = data_path_iter - data_path_item = data_path_item - header_text = StringProperty( + data_path_iter: data_path_iter + data_path_item: data_path_item + header_text: StringProperty( name="Header Text", description="Text to display in header during scale", ) - input_scale = FloatProperty( + input_scale: FloatProperty( description="Scale the mouse movement by this value before applying the delta", default=0.01, ) - invert = BoolProperty( + invert: BoolProperty( description="Invert the mouse input", default=False, ) - initial_x = IntProperty(options={'HIDDEN'}) + initial_x: IntProperty(options={'HIDDEN'}) def _values_store(self, context): data_path_iter = self.data_path_iter @@ -851,7 +867,7 @@ class WM_OT_url_open(Operator): bl_label = "" bl_options = {'INTERNAL'} - url = StringProperty( + url: StringProperty( name="URL", description="URL to open", ) @@ -868,7 +884,7 @@ class WM_OT_path_open(Operator): bl_label = "" bl_options = {'INTERNAL'} - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', options={'SKIP_SAVE'}, ) @@ -983,7 +999,7 @@ class WM_OT_doc_view_manual(Operator): bl_idname = "wm.doc_view_manual" bl_label = "View Manual" - doc_id = doc_id + doc_id: doc_id @staticmethod def _find_reference(rna_id, url_mapping, verbose=True): @@ -1037,7 +1053,7 @@ class WM_OT_doc_view(Operator): bl_idname = "wm.doc_view" bl_label = "View Documentation" - doc_id = doc_id + doc_id: doc_id if bpy.app.version_cycle == "release": _prefix = ("https://docs.blender.org/api/blender_python_api_current") else: @@ -1089,6 +1105,11 @@ rna_use_soft_limits = BoolProperty( name="Use Soft Limits", ) +rna_is_overridable_static = BoolProperty( + name="Is Statically Overridable", + default=False, +) + class WM_OT_properties_edit(Operator): bl_idname = "wm.properties_edit" @@ -1096,15 +1117,16 @@ class WM_OT_properties_edit(Operator): # register only because invoke_props_popup requires. bl_options = {'REGISTER', 'INTERNAL'} - data_path = rna_path - property = rna_property - value = rna_value - min = rna_min - max = rna_max - use_soft_limits = rna_use_soft_limits - soft_min = rna_min - soft_max = rna_max - description = StringProperty( + data_path: rna_path + property: rna_property + value: rna_value + min: rna_min + max: rna_max + use_soft_limits: rna_use_soft_limits + is_overridable_static: rna_is_overridable_static + soft_min: rna_min + soft_max: rna_max + description: StringProperty( name="Tooltip", ) @@ -1154,6 +1176,9 @@ class WM_OT_properties_edit(Operator): # print(exec_str) exec(exec_str) + exec_str = "item.property_overridable_static_set('[\"%s\"]', %s)" % (prop, self.is_overridable_static) + exec(exec_str) + rna_idprop_ui_prop_update(item, prop) self._last_prop[:] = [prop] @@ -1281,7 +1306,9 @@ class WM_OT_properties_edit(Operator): row.prop(self, "min") row.prop(self, "max") - layout.prop(self, "use_soft_limits") + row = layout.row() + row.prop(self, "use_soft_limits") + row.prop(self, "is_overridable_static") row = layout.row(align=True) row.enabled = self.use_soft_limits @@ -1295,7 +1322,7 @@ class WM_OT_properties_add(Operator): bl_label = "Add Property" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path + data_path: rna_path def execute(self, context): from rna_prop_ui import ( @@ -1338,7 +1365,7 @@ class WM_OT_properties_context_change(Operator): bl_label = "" bl_options = {'INTERNAL'} - context = StringProperty( + context: StringProperty( name="Context", maxlen=64, ) @@ -1354,8 +1381,8 @@ class WM_OT_properties_remove(Operator): bl_label = "Remove Property" bl_options = {'UNDO', 'INTERNAL'} - data_path = rna_path - property = rna_property + data_path: rna_path + property: rna_property def execute(self, context): from rna_prop_ui import ( @@ -1376,7 +1403,7 @@ class WM_OT_keyconfig_activate(Operator): bl_idname = "wm.keyconfig_activate" bl_label = "Activate Keyconfig" - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', ) @@ -1411,7 +1438,7 @@ class WM_OT_appconfig_activate(Operator): bl_idname = "wm.appconfig_activate" bl_label = "Activate Application Configuration" - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', ) @@ -1436,7 +1463,7 @@ class WM_OT_sysinfo(Operator): bl_idname = "wm.sysinfo" bl_label = "Save System Info" - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', options={'SKIP_SAVE'}, ) @@ -1492,54 +1519,6 @@ class WM_OT_copy_prev_settings(Operator): return {'CANCELLED'} -class WM_OT_blenderplayer_start(Operator): - """Launch the blender-player with the current blend-file""" - bl_idname = "wm.blenderplayer_start" - bl_label = "Start Game In Player" - - def execute(self, context): - import os - import sys - import subprocess - - gs = context.scene.game_settings - - # these remain the same every execution - blender_bin_path = bpy.app.binary_path - blender_bin_dir = os.path.dirname(blender_bin_path) - ext = os.path.splitext(blender_bin_path)[-1] - player_path = os.path.join(blender_bin_dir, "blenderplayer" + ext) - # done static vars - - if sys.platform == "darwin": - player_path = os.path.join(blender_bin_dir, "../../../blenderplayer.app/Contents/MacOS/blenderplayer") - - if not os.path.exists(player_path): - self.report({'ERROR'}, "Player path: %r not found" % player_path) - return {'CANCELLED'} - - filepath = bpy.data.filepath + '~' if bpy.data.is_saved else os.path.join(bpy.app.tempdir, "game.blend") - bpy.ops.wm.save_as_mainfile('EXEC_DEFAULT', filepath=filepath, copy=True) - - # start the command line call with the player path - args = [player_path] - - # handle some UI options as command line arguments - args.extend([ - "-g", "show_framerate", "=", "%d" % gs.show_framerate_profile, - "-g", "show_profile", "=", "%d" % gs.show_framerate_profile, - "-g", "show_properties", "=", "%d" % gs.show_debug_properties, - "-g", "ignore_deprecation_warnings", "=", "%d" % (not gs.use_deprecation_warnings), - ]) - - # finish the call with the path to the blend file - args.append(filepath) - - subprocess.call(args) - os.remove(filepath) - return {'FINISHED'} - - class WM_OT_keyconfig_test(Operator): """Test key-config for conflicts""" bl_idname = "wm.keyconfig_test" @@ -1562,26 +1541,26 @@ class WM_OT_keyconfig_import(Operator): bl_idname = "wm.keyconfig_import" bl_label = "Import Key Configuration..." - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', default="keymap.py", ) - filter_folder = BoolProperty( + filter_folder: BoolProperty( name="Filter folders", default=True, options={'HIDDEN'}, ) - filter_text = BoolProperty( + filter_text: BoolProperty( name="Filter text", default=True, options={'HIDDEN'}, ) - filter_python = BoolProperty( + filter_python: BoolProperty( name="Filter python", default=True, options={'HIDDEN'}, ) - keep_original = BoolProperty( + keep_original: BoolProperty( name="Keep original", description="Keep original file after copying to configuration folder", default=True, @@ -1629,26 +1608,26 @@ class WM_OT_keyconfig_export(Operator): bl_idname = "wm.keyconfig_export" bl_label = "Export Key Configuration..." - all = BoolProperty( + all: BoolProperty( name="All Keymaps", default=False, description="Write all keymaps (not just user modified)", ) - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', default="keymap.py", ) - filter_folder = BoolProperty( + filter_folder: BoolProperty( name="Filter folders", default=True, options={'HIDDEN'}, ) - filter_text = BoolProperty( + filter_text: BoolProperty( name="Filter text", default=True, options={'HIDDEN'}, ) - filter_python = BoolProperty( + filter_python: BoolProperty( name="Filter python", default=True, options={'HIDDEN'}, @@ -1665,7 +1644,7 @@ class WM_OT_keyconfig_export(Operator): wm = context.window_manager - keyconfig_utils.keyconfig_export( + keyconfig_utils.keyconfig_export_as_data( wm, wm.keyconfigs.active, self.filepath, @@ -1685,7 +1664,7 @@ class WM_OT_keymap_restore(Operator): bl_idname = "wm.keymap_restore" bl_label = "Restore Key Map(s)" - all = BoolProperty( + all: BoolProperty( name="All Keymaps", description="Restore all keymaps to default", ) @@ -1708,7 +1687,7 @@ class WM_OT_keyitem_restore(Operator): bl_idname = "wm.keyitem_restore" bl_label = "Restore Key Map Item" - item_id = IntProperty( + item_id: IntProperty( name="Item Identifier", description="Identifier of the item to remove", ) @@ -1755,7 +1734,7 @@ class WM_OT_keyitem_remove(Operator): bl_idname = "wm.keyitem_remove" bl_label = "Remove Key Map Item" - item_id = IntProperty( + item_id: IntProperty( name="Item Identifier", description="Identifier of the item to remove", ) @@ -1823,7 +1802,7 @@ class WM_OT_addon_enable(Operator): bl_idname = "wm.addon_enable" bl_label = "Enable Add-on" - module = StringProperty( + module: StringProperty( name="Module", description="Module name of the add-on to enable", ) @@ -1869,7 +1848,7 @@ class WM_OT_addon_disable(Operator): bl_idname = "wm.addon_disable" bl_label = "Disable Add-on" - module = StringProperty( + module: StringProperty( name="Module", description="Module name of the add-on to disable", ) @@ -1893,25 +1872,56 @@ class WM_OT_addon_disable(Operator): return {'FINISHED'} +class WM_OT_owner_enable(Operator): + """Enable workspace owner ID""" + bl_idname = "wm.owner_enable" + bl_label = "Enable Add-on" + + owner_id: StringProperty( + name="UI Tag", + ) + + def execute(self, context): + workspace = context.workspace + workspace.owner_ids.new(self.owner_id) + return {'FINISHED'} + + +class WM_OT_owner_disable(Operator): + """Enable workspace owner ID""" + bl_idname = "wm.owner_disable" + bl_label = "Disable UI Tag" + + owner_id: StringProperty( + name="UI Tag", + ) + + def execute(self, context): + workspace = context.workspace + owner_id = workspace.owner_ids[self.owner_id] + workspace.owner_ids.remove(owner_id) + return {'FINISHED'} + + class WM_OT_theme_install(Operator): """Load and apply a Blender XML theme file""" bl_idname = "wm.theme_install" bl_label = "Install Theme..." - overwrite = BoolProperty( + overwrite: BoolProperty( name="Overwrite", description="Remove existing theme file if exists", default=True, ) - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', ) - filter_folder = BoolProperty( + filter_folder: BoolProperty( name="Filter folders", default=True, options={'HIDDEN'}, ) - filter_glob = StringProperty( + filter_glob: StringProperty( default="*.xml", options={'HIDDEN'}, ) @@ -1975,31 +1985,31 @@ class WM_OT_addon_install(Operator): bl_idname = "wm.addon_install" bl_label = "Install Add-on from File..." - overwrite = BoolProperty( + overwrite: BoolProperty( name="Overwrite", description="Remove existing add-ons with the same ID", default=True, ) - target = EnumProperty( + target: EnumProperty( name="Target Path", items=(('DEFAULT', "Default", ""), ('PREFS', "User Prefs", "")), ) - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', ) - filter_folder = BoolProperty( + filter_folder: BoolProperty( name="Filter folders", default=True, options={'HIDDEN'}, ) - filter_python = BoolProperty( + filter_python: BoolProperty( name="Filter python", default=True, options={'HIDDEN'}, ) - filter_glob = StringProperty( + filter_glob: StringProperty( default="*.py;*.zip", options={'HIDDEN'}, ) @@ -2129,7 +2139,7 @@ class WM_OT_addon_remove(Operator): bl_idname = "wm.addon_remove" bl_label = "Remove Add-on" - module = StringProperty( + module: StringProperty( name="Module", description="Module name of the add-on to remove", ) @@ -2189,7 +2199,7 @@ class WM_OT_addon_expand(Operator): bl_label = "" bl_options = {'INTERNAL'} - module = StringProperty( + module: StringProperty( name="Module", description="Module name of the add-on to expand", ) @@ -2213,7 +2223,7 @@ class WM_OT_addon_userpref_show(Operator): bl_label = "" bl_options = {'INTERNAL'} - module = StringProperty( + module: StringProperty( name="Module", description="Module name of the add-on to expand", ) @@ -2244,21 +2254,21 @@ class WM_OT_app_template_install(Operator): bl_idname = "wm.app_template_install" bl_label = "Install Template from File..." - overwrite = BoolProperty( + overwrite: BoolProperty( name="Overwrite", description="Remove existing template with the same ID", default=True, ) - filepath = StringProperty( + filepath: StringProperty( subtype='FILE_PATH', ) - filter_folder = BoolProperty( + filter_folder: BoolProperty( name="Filter folders", default=True, options={'HIDDEN'}, ) - filter_glob = StringProperty( + filter_glob: StringProperty( default="*.zip", options={'HIDDEN'}, ) @@ -2338,6 +2348,180 @@ class WM_OT_app_template_install(Operator): return {'RUNNING_MODAL'} +class WM_OT_tool_set_by_name(Operator): + """Set the tool by name (for keymaps)""" + bl_idname = "wm.tool_set_by_name" + bl_label = "Set Tool By Name" + + name: StringProperty( + name="Text", + description="Display name of the tool", + ) + cycle: BoolProperty( + name="Cycle", + description="Cycle through tools in this group", + default=False, + options={'SKIP_SAVE'}, + ) + + space_type: rna_space_type_prop + + def execute(self, context): + from bl_ui.space_toolsystem_common import ( + activate_by_name, + activate_by_name_or_cycle, + ) + + if self.properties.is_property_set("space_type"): + space_type = self.space_type + else: + space_type = context.space_data.type + + fn = activate_by_name_or_cycle if self.cycle else activate_by_name + if fn(context, space_type, self.name): + return {'FINISHED'} + else: + self.report({'WARNING'}, f"Tool {self.name!r} not found.") + return {'CANCELLED'} + + +class WM_OT_toolbar(Operator): + bl_idname = "wm.toolbar" + bl_label = "Toolbar" + + def execute(self, context): + from bl_ui.space_toolsystem_common import ( + ToolSelectPanelHelper, + keymap_from_context, + ) + space_type = context.space_data.type + + cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) + if cls is None: + self.report({'WARNING'}, f"Toolbar not found for {space_type!r}") + return {'CANCELLED'} + + wm = context.window_manager + keymap = keymap_from_context(context, space_type) + + def draw_menu(popover, context): + layout = popover.layout + + layout.operator_context = 'INVOKE_DEFAULT' + layout.operator("wm.search_menu", text="Search Commands...", icon='VIEWZOOM') + + cls.draw_cls(layout, context, detect_layout=False, scale_y=1.0) + + wm.popover(draw_menu, ui_units_x=8, keymap=keymap) + return {'FINISHED'} + + +# Studio Light operations +class WM_OT_studiolight_install(Operator): + """Install a user defined studio light""" + bl_idname = "wm.studiolight_install" + bl_label = "Install Custom Studio Light" + + files: CollectionProperty( + name="File Path", + type=OperatorFileListElement, + ) + directory: StringProperty( + subtype='DIR_PATH', + ) + filter_folder: BoolProperty( + name="Filter folders", + default=True, + options={'HIDDEN'}, + ) + filter_glob: StringProperty( + default="*.png;*.jpg;*.hdr;*.exr", + options={'HIDDEN'}, + ) + orientation: EnumProperty( + items=( + ('MATCAP', "MatCap", ""), + ('WORLD', "World", ""), + ('CAMERA', "Camera", ""), + ) + ) + + def execute(self, context): + import traceback + import shutil + import pathlib + userpref = context.user_preferences + + filepaths = [pathlib.Path(self.directory, e.name) for e in self.files] + path_studiolights = bpy.utils.user_resource('DATAFILES') + + if not path_studiolights: + self.report({'ERROR'}, "Failed to get Studio Light path") + return {'CANCELLED'} + + path_studiolights = pathlib.Path(path_studiolights, "studiolights", self.orientation.lower()) + if not path_studiolights.exists(): + try: + path_studiolights.mkdir(parents=True, exist_ok=True) + except: + traceback.print_exc() + + for filepath in filepaths: + shutil.copy(str(filepath), str(path_studiolights)) + userpref.studio_lights.new(str(path_studiolights.joinpath(filepath.name)), self.orientation) + + # print message + msg = ( + tip_("StudioLight Installed %r into %r") % + (", ".join(str(x.name) for x in self.files), str(path_studiolights)) + ) + print(msg) + self.report({'INFO'}, msg) + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.window_manager + wm.fileselect_add(self) + return {'RUNNING_MODAL'} + + +class WM_OT_studiolight_uninstall(Operator): + bl_idname = 'wm.studiolight_uninstall' + bl_label = "Uninstall Studio Light" + index: bpy.props.IntProperty() + + def _remove_path(self, path): + if path.exists(): + path.unlink() + + def execute(self, context): + import pathlib + userpref = context.user_preferences + for studio_light in userpref.studio_lights: + if studio_light.index == self.index: + if len(studio_light.path) > 0: + self._remove_path(pathlib.Path(studio_light.path)) + if len(studio_light.path_irr_cache) > 0: + self._remove_path(pathlib.Path(studio_light.path_irr_cache)) + if len(studio_light.path_sh_cache) > 0: + self._remove_path(pathlib.Path(studio_light.path_sh_cache)) + userpref.studio_lights.remove(studio_light) + return {'FINISHED'} + return {'CANCELLED'} + + +class WM_OT_studiolight_userpref_show(Operator): + """Show light user preferences""" + bl_idname = "wm.studiolight_userpref_show" + bl_label = "" + bl_options = {'INTERNAL'} + + def execute(self, context): + context.user_preferences.active_section = 'LIGHTS' + bpy.ops.screen.userpref_show('INVOKE_DEFAULT') + return {'FINISHED'} + + classes = ( BRUSH_OT_active_index_set, WM_OT_addon_disable, @@ -2350,7 +2534,6 @@ classes = ( WM_OT_app_template_install, WM_OT_appconfig_activate, WM_OT_appconfig_default, - WM_OT_blenderplayer_start, WM_OT_context_collection_boolean_set, WM_OT_context_cycle_array, WM_OT_context_cycle_enum, @@ -2390,5 +2573,12 @@ classes = ( WM_OT_properties_remove, WM_OT_sysinfo, WM_OT_theme_install, + WM_OT_owner_disable, + WM_OT_owner_enable, WM_OT_url_open, + WM_OT_studiolight_install, + WM_OT_studiolight_uninstall, + WM_OT_studiolight_userpref_show, + WM_OT_tool_set_by_name, + WM_OT_toolbar, ) |