enable xml preset save/load, replace install/export themes with these.
This commit is contained in:
@@ -408,7 +408,7 @@ def smpte_from_frame(frame, fps=None, fps_base=None):
|
|||||||
return smpte_from_seconds((frame * fps_base) / fps, fps)
|
return smpte_from_seconds((frame * fps_base) / fps, fps)
|
||||||
|
|
||||||
|
|
||||||
def preset_find(name, preset_path, display_name=False):
|
def preset_find(name, preset_path, display_name=False, ext=".py"):
|
||||||
if not name:
|
if not name:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -417,11 +417,11 @@ def preset_find(name, preset_path, display_name=False):
|
|||||||
if display_name:
|
if display_name:
|
||||||
filename = ""
|
filename = ""
|
||||||
for fn in _os.listdir(directory):
|
for fn in _os.listdir(directory):
|
||||||
if fn.endswith(".py") and name == _bpy.path.display_name(fn):
|
if fn.endswith(ext) and name == _bpy.path.display_name(fn):
|
||||||
filename = fn
|
filename = fn
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
filename = name + ".py"
|
filename = name + ext
|
||||||
|
|
||||||
if filename:
|
if filename:
|
||||||
filepath = _os.path.join(directory, filename)
|
filepath = _os.path.join(directory, filename)
|
||||||
|
|||||||
@@ -307,9 +307,21 @@ def xml2rna(root_xml,
|
|||||||
#
|
#
|
||||||
# This roughly matches the operator 'bpy.ops.script.python_file_run'
|
# This roughly matches the operator 'bpy.ops.script.python_file_run'
|
||||||
|
|
||||||
|
def _get_context_val(context, path):
|
||||||
|
path_full = "context." + path
|
||||||
|
try:
|
||||||
|
value = eval(path_full)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
print("Error: %r could not be found" % path_full)
|
||||||
|
|
||||||
|
value = Ellipsis
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
def xml_file_run(context, filepath, rna_map):
|
def xml_file_run(context, filepath, rna_map):
|
||||||
|
|
||||||
import rna_xml
|
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|
||||||
xml_nodes = xml.dom.minidom.parse(filepath)
|
xml_nodes = xml.dom.minidom.parse(filepath)
|
||||||
@@ -321,17 +333,24 @@ def xml_file_run(context, filepath, rna_map):
|
|||||||
# TODO, error check
|
# TODO, error check
|
||||||
xml_node = bpy_xml.getElementsByTagName(xml_tag)[0]
|
xml_node = bpy_xml.getElementsByTagName(xml_tag)[0]
|
||||||
|
|
||||||
# now get
|
value = _get_context_val(context, rna_path)
|
||||||
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:
|
if value is not Ellipsis and value is not None:
|
||||||
print("Loading XML: %r" % rna_path_full)
|
print(" loading XML: %r" % rna_path)
|
||||||
rna_xml.xml2rna(xml_node, root_rna=value)
|
xml2rna(xml_node, root_rna=value)
|
||||||
|
|
||||||
|
|
||||||
|
def xml_file_write(context, filepath, rna_map):
|
||||||
|
|
||||||
|
file = open(filepath, 'w', encoding='utf-8')
|
||||||
|
fw = file.write
|
||||||
|
|
||||||
|
fw("<bpy>\n")
|
||||||
|
|
||||||
|
for rna_path, xml_tag in rna_map:
|
||||||
|
# xml_tag is ignored, we get this from the rna
|
||||||
|
value = _get_context_val(context, rna_path)
|
||||||
|
rna2xml(fw, root_rna=value, method='ATTR')
|
||||||
|
|
||||||
|
fw("</bpy>\n")
|
||||||
|
file.close()
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ class AddPresetBase():
|
|||||||
|
|
||||||
preset_menu_class = getattr(bpy.types, self.preset_menu)
|
preset_menu_class = getattr(bpy.types, self.preset_menu)
|
||||||
|
|
||||||
|
is_xml = getattr(preset_menu_class, "preset_type", None) == 'XML'
|
||||||
|
|
||||||
|
if is_xml:
|
||||||
|
ext = ".xml"
|
||||||
|
else:
|
||||||
|
ext = ".py"
|
||||||
|
|
||||||
if not self.remove_active:
|
if not self.remove_active:
|
||||||
name = self.name.strip()
|
name = self.name.strip()
|
||||||
if not name:
|
if not name:
|
||||||
@@ -71,32 +78,40 @@ class AddPresetBase():
|
|||||||
self.report({'WARNING'}, "Failed to create presets path")
|
self.report({'WARNING'}, "Failed to create presets path")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
filepath = os.path.join(target_path, filename) + ".py"
|
filepath = os.path.join(target_path, filename) + ext
|
||||||
|
|
||||||
if hasattr(self, "add"):
|
if hasattr(self, "add"):
|
||||||
self.add(context, filepath)
|
self.add(context, filepath)
|
||||||
else:
|
else:
|
||||||
print("Writing Preset: %r" % filepath)
|
print("Writing Preset: %r" % filepath)
|
||||||
file_preset = open(filepath, 'w')
|
|
||||||
file_preset.write("import bpy\n")
|
|
||||||
|
|
||||||
if hasattr(self, "preset_defines"):
|
if is_xml:
|
||||||
for rna_path in self.preset_defines:
|
import rna_xml
|
||||||
exec(rna_path)
|
rna_xml.xml_file_write(context,
|
||||||
file_preset.write("%s\n" % rna_path)
|
filepath,
|
||||||
file_preset.write("\n")
|
preset_menu_class.preset_xml_map)
|
||||||
|
else:
|
||||||
|
file_preset = open(filepath, 'w')
|
||||||
|
file_preset.write("import bpy\n")
|
||||||
|
|
||||||
for rna_path in self.preset_values:
|
if hasattr(self, "preset_defines"):
|
||||||
value = eval(rna_path)
|
for rna_path in self.preset_defines:
|
||||||
# convert thin wrapped sequences to simple lists to repr()
|
exec(rna_path)
|
||||||
try:
|
file_preset.write("%s\n" % rna_path)
|
||||||
value = value[:]
|
file_preset.write("\n")
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
file_preset.write("%s = %r\n" % (rna_path, value))
|
for rna_path in self.preset_values:
|
||||||
|
value = eval(rna_path)
|
||||||
|
# convert thin wrapped sequences
|
||||||
|
# to simple lists to repr()
|
||||||
|
try:
|
||||||
|
value = value[:]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
file_preset.close()
|
file_preset.write("%s = %r\n" % (rna_path, value))
|
||||||
|
|
||||||
|
file_preset.close()
|
||||||
|
|
||||||
preset_menu_class.bl_label = bpy.path.display_name(filename)
|
preset_menu_class.bl_label = bpy.path.display_name(filename)
|
||||||
|
|
||||||
@@ -104,12 +119,15 @@ class AddPresetBase():
|
|||||||
preset_active = preset_menu_class.bl_label
|
preset_active = preset_menu_class.bl_label
|
||||||
|
|
||||||
# fairly sloppy but convenient.
|
# fairly sloppy but convenient.
|
||||||
filepath = bpy.utils.preset_find(preset_active, self.preset_subdir)
|
filepath = bpy.utils.preset_find(preset_active,
|
||||||
|
self.preset_subdir,
|
||||||
|
ext=ext)
|
||||||
|
|
||||||
if not filepath:
|
if not filepath:
|
||||||
filepath = bpy.utils.preset_find(preset_active,
|
filepath = bpy.utils.preset_find(preset_active,
|
||||||
self.preset_subdir,
|
self.preset_subdir,
|
||||||
display_name=True)
|
display_name=True,
|
||||||
|
ext=ext)
|
||||||
|
|
||||||
if not filepath:
|
if not filepath:
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
@@ -397,6 +415,14 @@ class AddPresetTrackingSettings(AddPresetBase, Operator):
|
|||||||
preset_subdir = "tracking_settings"
|
preset_subdir = "tracking_settings"
|
||||||
|
|
||||||
|
|
||||||
|
class AddPresetInterfaceTheme(AddPresetBase, Operator):
|
||||||
|
'''Add a theme preset'''
|
||||||
|
bl_idname = "wm.interface_theme_preset_add"
|
||||||
|
bl_label = "Add Tracking Settings Preset"
|
||||||
|
preset_menu = "USERPREF_MT_interface_theme_presets"
|
||||||
|
preset_subdir = "interface_theme"
|
||||||
|
|
||||||
|
|
||||||
class AddPresetKeyconfig(AddPresetBase, Operator):
|
class AddPresetKeyconfig(AddPresetBase, Operator):
|
||||||
'''Add a Keyconfig Preset'''
|
'''Add a Keyconfig Preset'''
|
||||||
bl_idname = "wm.keyconfig_preset_add"
|
bl_idname = "wm.keyconfig_preset_add"
|
||||||
|
|||||||
@@ -1769,61 +1769,3 @@ class WM_OT_addon_expand(Operator):
|
|||||||
info["show_expanded"] = not info["show_expanded"]
|
info["show_expanded"] = not info["show_expanded"]
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
|
||||||
# Theme IO
|
|
||||||
from bpy_extras.io_utils import (ImportHelper,
|
|
||||||
ExportHelper,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_theme_import(Operator, ImportHelper):
|
|
||||||
bl_idname = "wm.theme_import"
|
|
||||||
bl_label = "Import Theme"
|
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
|
||||||
|
|
||||||
filename_ext = ".xml"
|
|
||||||
filter_glob = StringProperty(default="*.xml", options={'HIDDEN'})
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
import rna_xml
|
|
||||||
import xml.dom.minidom
|
|
||||||
|
|
||||||
filepath = self.filepath
|
|
||||||
|
|
||||||
xml_nodes = xml.dom.minidom.parse(filepath)
|
|
||||||
theme_xml = xml_nodes.getElementsByTagName("Theme")[0]
|
|
||||||
|
|
||||||
# XXX, why always 0?, allow many?
|
|
||||||
theme = context.user_preferences.themes[0]
|
|
||||||
|
|
||||||
rna_xml.xml2rna(theme_xml,
|
|
||||||
root_rna=theme,
|
|
||||||
)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_theme_export(Operator, ExportHelper):
|
|
||||||
bl_idname = "wm.theme_export"
|
|
||||||
bl_label = "Export Theme"
|
|
||||||
|
|
||||||
filename_ext = ".xml"
|
|
||||||
filter_glob = StringProperty(default="*.xml", options={'HIDDEN'})
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
import rna_xml
|
|
||||||
|
|
||||||
filepath = self.filepath
|
|
||||||
file = open(filepath, 'w', encoding='utf-8')
|
|
||||||
|
|
||||||
# XXX, why always 0?, allow many?
|
|
||||||
theme = context.user_preferences.themes[0]
|
|
||||||
|
|
||||||
rna_xml.rna2xml(file.write,
|
|
||||||
root_rna=theme,
|
|
||||||
method='ATTR',
|
|
||||||
root_node="bpy"
|
|
||||||
)
|
|
||||||
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|||||||
@@ -96,10 +96,12 @@ class USERPREF_HT_header(Header):
|
|||||||
layout.menu("USERPREF_MT_addons_dev_guides")
|
layout.menu("USERPREF_MT_addons_dev_guides")
|
||||||
elif userpref.active_section == 'THEMES':
|
elif userpref.active_section == 'THEMES':
|
||||||
layout.operator("ui.reset_default_theme")
|
layout.operator("ui.reset_default_theme")
|
||||||
layout.operator("wm.theme_import")
|
|
||||||
layout.operator("wm.theme_export")
|
|
||||||
|
|
||||||
|
layout.label(text="Presets:")
|
||||||
layout.menu("USERPREF_MT_interface_theme_presets", text=bpy.types.USERPREF_MT_interface_theme_presets.bl_label)
|
layout.menu("USERPREF_MT_interface_theme_presets", text=bpy.types.USERPREF_MT_interface_theme_presets.bl_label)
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("wm.interface_theme_preset_add", text="", icon='ZOOMIN')
|
||||||
|
row.operator("wm.interface_theme_preset_add", text="", icon='ZOOMOUT').remove_active = True
|
||||||
|
|
||||||
|
|
||||||
class USERPREF_PT_tabs(Panel):
|
class USERPREF_PT_tabs(Panel):
|
||||||
|
|||||||
Reference in New Issue
Block a user