diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index a5b86b917b2..92d2533c2c1 100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -94,7 +94,7 @@ def display_name(name): name_base = name_base.replace("_", " ") if name_base.islower(): - return name_base.capitalize() + return name_base.lower().title() else: return name_base diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index e72d26c92c5..32ec5125825 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -472,3 +472,20 @@ def addon_reset_all(): elif is_loaded: print("\taddon_reset_all unloading", mod_name) addon_disable(mod_name) + +def preset_find(name, preset_path, display_name=False): + for directory in preset_paths(preset_path): + + if display_name: + filename = "" + for fn in _os.listdir(directory): + if fn.endswith(".py") and name == _bpy.path.display_name(fn): + filename = fn + break + else: + filename = name + ".py" + + if filename: + filepath = _os.path.join(directory, filename) + if _os.path.exists(filepath): + return filepath\ diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index 0364496dd44..80309b0d91e 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -761,7 +761,6 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): props.filepath = filepath if operator == "script.execute_preset": props.menu_idname = self.bl_idname - props.preset_name = preset_name def draw_preset(self, context): """Define these on the subclass diff --git a/release/scripts/op/presets.py b/release/scripts/op/presets.py index fc2f41d2cf5..f28db3b1522 100644 --- a/release/scripts/op/presets.py +++ b/release/scripts/op/presets.py @@ -31,45 +31,75 @@ class AddPresetBase(): # bl_label = "Add a Python Preset" name = bpy.props.StringProperty(name="Name", description="Name of the preset, used to make the path name", maxlen=64, default="") + remove_active = bpy.props.BoolProperty(default=False, options={'HIDDEN'}) def _as_filename(self, name): # could reuse for other presets for char in " !@#$%^&*(){}:\";'[]<>,./?": - name = name.replace('.', '_') - return name.lower() + name = name.replace(char, '_') + return name.lower().strip() def execute(self, context): + import os + preset_menu_class = getattr(bpy.types, self.preset_menu) - if not self.name: - return {'FINISHED'} + if not self.remove_active: + + if not self.name: + return {'FINISHED'} - filename = self._as_filename(self.name) + ".py" + filename = self._as_filename(self.name) + ".py" + + target_path = bpy.utils.preset_paths(self.preset_subdir)[0] # we need some way to tell the user and system preset path - target_path = bpy.utils.preset_paths(self.preset_subdir)[0] # we need some way to tell the user and system preset path + filepath = os.path.join(target_path, filename) + if getattr(self, "save_keyconfig", False): + bpy.ops.wm.keyconfig_export(filepath=filepath, kc_name=self.name) + file_preset = open(filepath, 'a') + file_preset.write("wm.keyconfigs.active = kc\n\n") + else: + file_preset = open(filepath, 'w') + file_preset.write("import bpy\n") + + for rna_path in self.preset_values: + value = eval(rna_path) + file_preset.write("%s = %s\n" % (rna_path, repr(value))) + + file_preset.close() + + preset_menu_class.bl_label = bpy.path.display_name(self.name) - filepath = os.path.join(target_path, filename) - if getattr(self, "save_keyconfig", False): - bpy.ops.wm.keyconfig_export(filepath=filepath, kc_name=self.name) - file_preset = open(filepath, 'a') - file_preset.write("wm.keyconfigs.active = kc\n\n") else: - file_preset = open(filepath, 'w') - file_preset.write("import bpy\n") + preset_active = preset_menu_class.bl_label - for rna_path in self.preset_values: - value = eval(rna_path) - file_preset.write("%s = %s\n" % (rna_path, repr(value))) + # fairly sloppy but convenient. + filepath = bpy.utils.preset_find(preset_active, self.preset_subdir) + if not filepath: + filepath = bpy.utils.preset_find(preset_active, self.preset_subdir, display_name=True) - file_preset.close() + if not filepath: + return {'CANCELLED'} + + try: + os.remove(filepath) + except: + import traceback + traceback.print_exc() + + # XXX, stupid! + preset_menu_class.bl_label = bpy.path.display_name(self.preset_menu.replace("_MT_", " ").lower()) return {'FINISHED'} def invoke(self, context, event): - wm = context.window_manager - #crashes, TODO - fix - #return wm.invoke_props_popup(self, event) + if not self.remove_active: + wm = context.window_manager + #crashes, TODO - fix + #return wm.invoke_props_popup(self, event) - wm.invoke_props_popup(self, event) - return {'RUNNING_MODAL'} + wm.invoke_props_popup(self, event) + return {'RUNNING_MODAL'} + else: + return self.execute(context) class ExecutePreset(bpy.types.Operator): @@ -78,16 +108,18 @@ class ExecutePreset(bpy.types.Operator): bl_label = "Execute a Python Preset" filepath = bpy.props.StringProperty(name="Path", description="Path of the Python file to execute", maxlen=512, default="") - preset_name = bpy.props.StringProperty(name="Preset Name", description="Name of the Preset being executed", default="") menu_idname = bpy.props.StringProperty(name="Menu ID Name", description="ID name of the menu this was called from", default="") def execute(self, context): + from os.path import basename + filepath = self.filepath + # change the menu title to the most recently chosen option preset_class = getattr(bpy.types, self.menu_idname) - preset_class.bl_label = self.preset_name + preset_class.bl_label = bpy.path.display_name(basename(filepath)) # execute the preset using script.python_file_run - bpy.ops.script.python_file_run(filepath=self.filepath) + bpy.ops.script.python_file_run(filepath=filepath) return {'FINISHED'} @@ -95,7 +127,7 @@ class AddPresetRender(AddPresetBase, bpy.types.Operator): '''Add a Render Preset''' bl_idname = "render.preset_add" bl_label = "Add Render Preset" - name = AddPresetBase.name + preset_menu = "RENDER_MT_presets" preset_values = [ "bpy.context.scene.render.field_order", @@ -117,7 +149,7 @@ class AddPresetSSS(AddPresetBase, bpy.types.Operator): '''Add a Subsurface Scattering Preset''' bl_idname = "material.sss_preset_add" bl_label = "Add SSS Preset" - name = AddPresetBase.name + preset_menu = "MATERIAL_MT_sss_presets" preset_values = [ "bpy.context.material.subsurface_scattering.back", @@ -142,7 +174,7 @@ class AddPresetCloth(AddPresetBase, bpy.types.Operator): '''Add a Cloth Preset''' bl_idname = "cloth.preset_add" bl_label = "Add Cloth Preset" - name = AddPresetBase.name + preset_menu = "CLOTH_MT_presets" preset_values = [ "bpy.context.cloth.settings.air_damping", @@ -160,7 +192,7 @@ class AddPresetSunSky(AddPresetBase, bpy.types.Operator): '''Add a Sky & Atmosphere Preset''' bl_idname = "lamp.sunsky_preset_add" bl_label = "Add Sunsky Preset" - name = AddPresetBase.name + preset_menu = "LAMP_MT_sunsky_presets" preset_values = [ "bpy.context.object.data.sky.atmosphere_extinction", @@ -185,7 +217,7 @@ class AddPresetInteraction(AddPresetBase, bpy.types.Operator): '''Add an Application Interaction Preset''' bl_idname = "wm.interaction_preset_add" bl_label = "Add Interaction Preset" - name = AddPresetBase.name + preset_menu = "USERPREF_MT_interaction_presets" save_keyconfig = True preset_values = [ diff --git a/release/scripts/ui/properties_data_lamp.py b/release/scripts/ui/properties_data_lamp.py index 228a70d1b48..72e95989b06 100644 --- a/release/scripts/ui/properties_data_lamp.py +++ b/release/scripts/ui/properties_data_lamp.py @@ -134,6 +134,7 @@ class DATA_PT_sunsky(DataButtonsPanel, bpy.types.Panel): row.prop(lamp, "use_sky") row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label) row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMIN") + row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMOUT").remove_active = True row = layout.row() row.active = lamp.use_sky or lamp.use_atmosphere diff --git a/release/scripts/ui/properties_material.py b/release/scripts/ui/properties_material.py index 37284847dd1..82a52214b69 100644 --- a/release/scripts/ui/properties_material.py +++ b/release/scripts/ui/properties_material.py @@ -448,6 +448,7 @@ class MATERIAL_PT_sss(MaterialButtonsPanel, bpy.types.Panel): sub = row.row(align=True).split(percentage=0.75) sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label) sub.operator("material.sss_preset_add", text="", icon="ZOOMIN") + sub.operator("material.sss_preset_add", text="", icon="ZOOMOUT").remove_active = True split = layout.split() diff --git a/release/scripts/ui/properties_physics_cloth.py b/release/scripts/ui/properties_physics_cloth.py index 2e50babfcfd..26670438b3f 100644 --- a/release/scripts/ui/properties_physics_cloth.py +++ b/release/scripts/ui/properties_physics_cloth.py @@ -87,6 +87,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, bpy.types.Panel): sub = col.row(align=True) sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label) sub.operator("cloth.preset_add", text="", icon="ZOOMIN") + sub.operator("cloth.preset_add", text="", icon="ZOOMOUT").remove_active = True col.label(text="Quality:") col.prop(cloth, "quality", text="Steps", slider=True) diff --git a/release/scripts/ui/properties_render.py b/release/scripts/ui/properties_render.py index 4fb893f2beb..ee6bb8da2e6 100644 --- a/release/scripts/ui/properties_render.py +++ b/release/scripts/ui/properties_render.py @@ -515,7 +515,7 @@ class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel): row = layout.row(align=True) row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label) row.operator("render.preset_add", text="", icon="ZOOMIN") - + row.operator("render.preset_add", text="", icon="ZOOMOUT").remove_active = True split = layout.split() col = split.column() diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 0b4c33c4438..5cb760790df 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -727,6 +727,7 @@ class USERPREF_PT_input(InputKeyMapPanel): subrow = sub.row(align=True) subrow.menu("USERPREF_MT_interaction_presets", text=bpy.types.USERPREF_MT_interaction_presets.bl_label) subrow.operator("wm.interaction_preset_add", text="", icon='ZOOMIN') + subrow.operator("wm.interaction_preset_add", text="", icon='ZOOMOUT').remove_active = True sub.separator() sub.label(text="Mouse:")