diff --git a/addon/__init__.py b/addon/__init__.py index 093ea78..03dd66a 100644 --- a/addon/__init__.py +++ b/addon/__init__.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . import bpy -from .classes.ots import CustomTemplatesPreferences, TemplateItem, OT_SelectTemplatePopup, OT_AddTemplatePopup, OT_AddTemplateItem, OT_RemoveTemplateItem, OT_MoveDownTemplateItem, OT_MoveUpTemplateItem, OT_OpenAddonPreferences +from .classes.ots import CustomTemplatesPreferences, TemplateItem, OT_ExportTemplates, OT_ImportTemplates, CUSTOM_MT_Export_Menu, OT_SelectTemplatePopup, OT_AddTemplatePopup, OT_AddTemplateItem, OT_RemoveTemplateItem, OT_MoveDownTemplateItem, OT_MoveUpTemplateItem, OT_OpenAddonPreferences bl_info = { "id": "custom_templates", @@ -49,6 +49,9 @@ def draw_file_default_operators(self, context): # Manage Template layout.operator("custom_templates.open_preferences", text="Manage templates") + # Import/Export + layout.menu("custom_templates.export_menu", text="Import/Export") + layout.separator() # Select new custom template layout.operator("custom_templates.select_template_popup", text="Select new custom template") @@ -58,6 +61,9 @@ def draw_file_default_operators(self, context): text="Use current as new template") classes = [TemplateItem, + OT_ExportTemplates, + OT_ImportTemplates, + CUSTOM_MT_Export_Menu, OT_MoveUpTemplateItem, OT_MoveDownTemplateItem, OT_AddTemplateItem, diff --git a/addon/classes/ots.py b/addon/classes/ots.py index e23a770..9640546 100644 --- a/addon/classes/ots.py +++ b/addon/classes/ots.py @@ -1,5 +1,6 @@ from .. import __package__ as base_package import bpy +import json from bpy.types import Operator, PropertyGroup, AddonPreferences from bpy.props import StringProperty, CollectionProperty, IntProperty @@ -30,8 +31,11 @@ class CustomTemplatesPreferences(AddonPreferences): self, "projects", self, "active_template_index") col = row.column(align=True) + col.menu("custom_templates.export_menu", icon='DOWNARROW_HLT', text="") + col.separator() col.operator("custom_templates.add", icon='ADD', text="") col.operator("custom_templates.remove", icon='REMOVE', text="") + col.separator() col.operator("custom_templates.move_up", icon='TRIA_UP', text="") col.operator("custom_templates.move_down", icon='TRIA_DOWN', text="") @@ -39,6 +43,62 @@ class CustomTemplatesPreferences(AddonPreferences): project = self.projects[self.active_template_index] layout.prop(project, "name") layout.prop(project, "path") + +class CUSTOM_MT_Export_Menu(bpy.types.Menu): + bl_idname = "custom_templates.export_menu" + bl_label = "Import/Export custom templates" + bl_description = "Allows you to save al load your custom templates (using json format)" + + def draw(self, context): + layout = self.layout + layout.operator("custom_templates.export_templates", text="Export templates") + layout.operator("custom_templates.import_templates", text="Import templates") + +class OT_ExportTemplates(bpy.types.Operator): + bl_idname = "custom_templates.export_templates" + bl_label = "Export custom templates" + bl_description = "Export the current list of templates to JSON file" + + filepath: StringProperty(subtype="FILE_PATH", description="Select the path for the exported file", default="custom_templates.json") + + def execute(self, context): + prefs = context.preferences.addons[base_package].preferences + with open(self.filepath, 'w') as f: + projects = [{"name": project.name, "path": project.path} for project in prefs.projects] + json.dump(projects, f, indent=4) + + self.report({'INFO'}, f"Templates exported to {self.filepath}") + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + +class OT_ImportTemplates(bpy.types.Operator): + bl_idname = "custom_templates.import_templates" + bl_label = "Import custom templates" + bl_description = "Import a list of templates from JSON file (note that this will override the current templates list)" + + filepath: StringProperty(subtype="FILE_PATH", description="Select the .json file to load") + + def execute(self, context): + prefs = context.preferences.addons[base_package].preferences + + with open(self.filepath, 'r') as f: + projects = json.load(f) + + prefs.projects.clear() + for project in projects: + item = prefs.projects.add() + item.name = project["name"] + item.path = project["path"] + + self.report({'INFO'}, f"Projects imported from {self.filepath}") + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} # Templates list oeprators class OT_AddTemplateItem(Operator):