From 057d6e881575a0415c7cec7778d5e8f89e8f9110 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jan 2012 15:08:12 +0000 Subject: [PATCH] initial support for XML presets, these have the advantage... - missing attributes are ignored and don't error out like they would on a script when the API changes. - don't run code (secure to run from untrusted sources). use xml presets for themes. --- release/scripts/modules/rna_xml.py | 37 +++++++++++++++++++ .../scripts/startup/bl_operators/presets.py | 16 +++++++- release/scripts/startup/bl_operators/wm.py | 1 + .../scripts/startup/bl_ui/space_userpref.py | 11 ++++++ 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py index 1a0cf4bab9d..2b53ddcd941 100644 --- a/release/scripts/modules/rna_xml.py +++ b/release/scripts/modules/rna_xml.py @@ -298,3 +298,40 @@ def xml2rna(root_xml, pass rna2xml_node(root_xml, root_rna) + + + +# ----------------------------------------------------------------------------- +# Utility function used by presets. +# The idea is you can run a preset like a script with a few args. +# +# This roughly matches the operator 'bpy.ops.script.python_file_run' + +def xml_file_run(context, filepath, rna_map): + + import rna_xml + import xml.dom.minidom + + xml_nodes = xml.dom.minidom.parse(filepath) + bpy_xml = xml_nodes.getElementsByTagName("bpy")[0] + + for rna_path, xml_tag in rna_map: + + # first get xml + # TODO, error check + xml_node = bpy_xml.getElementsByTagName(xml_tag)[0] + + # now get + rna_path_full = "context." + rna_path + try: + value = eval(rna_path_full) + except: + import traceback + traceback.print_exc() + print("Error: %r could not be found" % rna_path_full) + + value = Ellipsis + + if value is not Ellipsis and value is not None: + print("Loading XML: %r" % rna_path_full) + rna_xml.xml2rna(xml_node, root_rna=value) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 308c46ca416..f4524c328c1 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -158,15 +158,27 @@ class ExecutePreset(Operator): ) def execute(self, context): - from os.path import basename + from os.path import basename, splitext 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 = bpy.path.display_name(basename(filepath)) + ext = splitext(filepath)[1].lower() + # execute the preset using script.python_file_run - bpy.ops.script.python_file_run(filepath=filepath) + if ext == ".py": + bpy.ops.script.python_file_run(filepath=filepath) + elif ext == ".xml": + import rna_xml + rna_xml.xml_file_run(context, + filepath, + preset_class.preset_xml_map) + else: + self.report({'ERROR'}, "unknown filetype: %r" % ext) + return {'CANCELLED '} + return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 11326377a79..8dbcbc4447e 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1823,6 +1823,7 @@ class WM_OT_theme_export(Operator, ExportHelper): rna_xml.rna2xml(file.write, root_rna=theme, method='ATTR', + root_node="bpy" ) return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 544fc92e8a4..5e95e02f1f4 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -99,6 +99,8 @@ class USERPREF_HT_header(Header): layout.operator("wm.theme_import") layout.operator("wm.theme_export") + layout.menu("USERPREF_MT_interface_theme_presets", text=bpy.types.USERPREF_MT_interface_theme_presets.bl_label) + class USERPREF_PT_tabs(Panel): bl_label = "" @@ -491,6 +493,15 @@ class USERPREF_PT_system(Panel): row.prop(system, "use_translate_tooltips", text="Tooltips") +class USERPREF_MT_interface_theme_presets(Menu): + bl_label = "Presets" + preset_subdir = "interface_theme" + preset_operator = "script.execute_preset" + preset_type = 'XML' + preset_xml_map = (("user_preferences.themes[0]", "Theme"), ) + draw = Menu.draw_preset + + class USERPREF_PT_theme(Panel): bl_space_type = 'USER_PREFERENCES' bl_label = "Themes"