wip
This commit is contained in:
@@ -15,6 +15,7 @@ from ..presets.storage_system import (
|
||||
from ..utils import bl_info
|
||||
|
||||
class TEXT_TEXTURE_OT_save_preset(Operator):
|
||||
pass
|
||||
"""Save current settings as preset"""
|
||||
bl_idname = "text_texture.save_preset"
|
||||
bl_label = "Save Preset"
|
||||
@@ -34,16 +35,19 @@ class TEXT_TEXTURE_OT_save_preset(Operator):
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
props = context.scene.text_texture_props
|
||||
|
||||
# Use provided preset name or fallback to input field
|
||||
preset_name = self.preset_name.strip() if self.preset_name else props.new_preset_name.strip()
|
||||
if not preset_name:
|
||||
pass
|
||||
self.report({'ERROR'}, "Please enter a preset name")
|
||||
return {'CANCELLED'}
|
||||
|
||||
# When overwriting from button, update the input field for consistency
|
||||
if self.preset_name and self.preset_name.strip():
|
||||
pass
|
||||
props.new_preset_name = preset_name
|
||||
|
||||
# Validate preset name characters (avoid filesystem issues)
|
||||
@@ -51,23 +55,27 @@ class TEXT_TEXTURE_OT_save_preset(Operator):
|
||||
# Allow Unicode letters, numbers, spaces, hyphens, underscores, and common accented characters
|
||||
# This pattern supports international characters like ö, ü, ñ, etc.
|
||||
if not re.match(r'^[\w\s\-]+$', preset_name, re.UNICODE):
|
||||
pass
|
||||
self.report({'ERROR'}, "Preset name contains invalid characters for filesystem compatibility")
|
||||
return {'CANCELLED'}
|
||||
|
||||
# Additional check for filesystem-unsafe characters
|
||||
invalid_chars = ['<', '>', ':', '"', '|', '?', '*', '/', '\\']
|
||||
if any(char in preset_name for char in invalid_chars):
|
||||
pass
|
||||
self.report({'ERROR'}, f"Preset name cannot contain: {' '.join(invalid_chars)}")
|
||||
return {'CANCELLED'}
|
||||
|
||||
# Check for duplicate names
|
||||
preset_file = os.path.join(get_preset_path(), f"{preset_name}.json")
|
||||
if os.path.exists(preset_file) and not self.overwrite:
|
||||
pass
|
||||
# Suggest alternative names
|
||||
base_name = preset_name
|
||||
counter = 1
|
||||
suggested_name = f"{base_name}_{counter}"
|
||||
while os.path.exists(os.path.join(get_preset_path(), f"{suggested_name}.json")):
|
||||
pass
|
||||
counter += 1
|
||||
suggested_name = f"{base_name}_{counter}"
|
||||
|
||||
@@ -75,16 +83,6 @@ class TEXT_TEXTURE_OT_save_preset(Operator):
|
||||
return {'CANCELLED'}
|
||||
|
||||
# DETAILED LOGGING: Current shader properties before saving
|
||||
print(f"[PRESET SAVE DEBUG] ==================== SAVING PRESET: '{preset_name}' ====================")
|
||||
print(f"[PRESET SAVE DEBUG] Current shader properties from props:")
|
||||
print(f"[PRESET SAVE DEBUG] disable_shadows: {props.disable_shadows}")
|
||||
print(f"[PRESET SAVE DEBUG] disable_reflections: {props.disable_reflections}")
|
||||
print(f"[PRESET SAVE DEBUG] disable_backfacing: {props.disable_backfacing}")
|
||||
print(f"[PRESET SAVE DEBUG] shader_type: {props.shader_type}")
|
||||
print(f"[PRESET SAVE DEBUG] shader_connection: {props.shader_connection}")
|
||||
print(f"[PRESET SAVE DEBUG] use_alpha: {props.use_alpha}")
|
||||
print(f"[PRESET SAVE DEBUG] emission_strength: {props.emission_strength}")
|
||||
print(f"[PRESET SAVE DEBUG] auto_assign_material: {props.auto_assign_material}")
|
||||
|
||||
preset_data = {
|
||||
'text': props.text,
|
||||
@@ -142,13 +140,10 @@ class TEXT_TEXTURE_OT_save_preset(Operator):
|
||||
}
|
||||
|
||||
# DETAILED LOGGING: Verify shader properties in preset_data
|
||||
print(f"[PRESET SAVE DEBUG] Shader properties in preset_data dictionary:")
|
||||
print(f"[PRESET SAVE DEBUG] disable_shadows: {preset_data.get('disable_shadows', 'NOT FOUND')}")
|
||||
print(f"[PRESET SAVE DEBUG] disable_reflections: {preset_data.get('disable_reflections', 'NOT FOUND')}")
|
||||
print(f"[PRESET SAVE DEBUG] disable_backfacing: {preset_data.get('disable_backfacing', 'NOT FOUND')}")
|
||||
|
||||
# Save overlay data
|
||||
for overlay in props.image_overlays:
|
||||
pass
|
||||
overlay_data = {
|
||||
'name': overlay.name,
|
||||
'image_path': overlay.image_path,
|
||||
@@ -162,25 +157,31 @@ class TEXT_TEXTURE_OT_save_preset(Operator):
|
||||
preset_data['image_overlays'].append(overlay_data)
|
||||
|
||||
try:
|
||||
pass
|
||||
# Save based on checkbox setting - single destination only
|
||||
success = save_preset_unified(preset_data, preset_name, props.save_with_blend_file)
|
||||
|
||||
if not success:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Failed to save preset '{preset_name}'")
|
||||
return {'CANCELLED'}
|
||||
|
||||
# Check if preset already exists in the collection and update it
|
||||
existing_preset = None
|
||||
for preset in props.presets:
|
||||
pass
|
||||
if preset.name == preset_name:
|
||||
pass
|
||||
existing_preset = preset
|
||||
break
|
||||
|
||||
if not existing_preset:
|
||||
pass
|
||||
preset = props.presets.add()
|
||||
preset.name = preset_name
|
||||
preset.source = 'BLEND_FILE' if props.save_with_blend_file else 'PERSISTENT_FILE'
|
||||
else:
|
||||
pass
|
||||
# Update source based on where it was saved
|
||||
existing_preset.source = 'BLEND_FILE' if props.save_with_blend_file else 'PERSISTENT_FILE'
|
||||
|
||||
@@ -188,38 +189,47 @@ class TEXT_TEXTURE_OT_save_preset(Operator):
|
||||
location = "with .blend file" if props.save_with_blend_file else "to persistent storage"
|
||||
|
||||
if self.overwrite:
|
||||
pass
|
||||
self.report({'INFO'}, f"✅ Preset '{preset_name}' updated {location}")
|
||||
else:
|
||||
pass
|
||||
self.report({'INFO'}, f"✅ Preset '{preset_name}' saved {location}")
|
||||
|
||||
except (OSError, IOError, json.JSONEncodeError) as e:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Failed to save preset: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
except Exception as e:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Unexpected error saving preset: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
pass
|
||||
# Check if preset exists and prompt for overwrite
|
||||
props = context.scene.text_texture_props
|
||||
preset_name = props.new_preset_name.strip()
|
||||
|
||||
if preset_name and preset_name != "New Preset":
|
||||
pass
|
||||
preset_file = os.path.join(get_preset_path(), f"{preset_name}.json")
|
||||
if os.path.exists(preset_file):
|
||||
pass
|
||||
return context.window_manager.invoke_confirm(self, event)
|
||||
|
||||
return self.execute(context)
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
layout = self.layout
|
||||
props = context.scene.text_texture_props
|
||||
preset_name = props.new_preset_name.strip()
|
||||
layout.label(text=f"Overwrite existing preset '{preset_name}'?")
|
||||
|
||||
class TEXT_TEXTURE_OT_save_preset_enter(Operator):
|
||||
pass
|
||||
"""Save preset when Enter key is pressed in name field"""
|
||||
bl_idname = "text_texture.save_preset_enter"
|
||||
bl_label = "Save Preset (Enter)"
|
||||
@@ -227,10 +237,12 @@ class TEXT_TEXTURE_OT_save_preset_enter(Operator):
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
# Delegate to the main save preset operator
|
||||
return bpy.ops.text_texture.save_preset('INVOKE_DEFAULT')
|
||||
|
||||
class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
pass
|
||||
"""Load preset"""
|
||||
bl_idname = "text_texture.load_preset"
|
||||
bl_label = "Load Preset"
|
||||
@@ -240,33 +252,29 @@ class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
preset_name: StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
props = context.scene.text_texture_props
|
||||
|
||||
# DEFENSIVE PROGRAMMING: Ensure presets are available before loading
|
||||
if not ensure_presets_available():
|
||||
pass
|
||||
self.report({'ERROR'}, "Failed to ensure presets are loaded - cannot load preset")
|
||||
return {'CANCELLED'}
|
||||
|
||||
# DETAILED LOGGING: Current shader properties before loading
|
||||
print(f"[PRESET LOAD DEBUG] ==================== LOADING PRESET: '{self.preset_name}' ====================")
|
||||
print(f"[PRESET LOAD DEBUG] Current shader properties BEFORE loading:")
|
||||
print(f"[PRESET LOAD DEBUG] disable_shadows: {props.disable_shadows}")
|
||||
print(f"[PRESET LOAD DEBUG] disable_reflections: {props.disable_reflections}")
|
||||
print(f"[PRESET LOAD DEBUG] disable_backfacing: {props.disable_backfacing}")
|
||||
print(f"[PRESET LOAD DEBUG] shader_type: {props.shader_type}")
|
||||
print(f"[PRESET LOAD DEBUG] shader_connection: {props.shader_connection}")
|
||||
|
||||
try:
|
||||
pass
|
||||
# Get unified preset list and find the one to load
|
||||
all_presets = get_unified_preset_list()
|
||||
|
||||
if self.preset_name not in all_presets:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Preset '{self.preset_name}' not found")
|
||||
return {'CANCELLED'}
|
||||
|
||||
preset_data, source = all_presets[self.preset_name]
|
||||
|
||||
print(f"[PRESET LOAD DEBUG] Loading preset '{self.preset_name}' from {source}")
|
||||
|
||||
props.is_updating = True
|
||||
|
||||
@@ -290,56 +298,36 @@ class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
props.prepend_append_layout = preset_data.get('prepend_append_layout', props.prepend_append_layout)
|
||||
|
||||
# DETAILED LOGGING: Shader property loading with before/after values
|
||||
print(f"[PRESET LOAD DEBUG] Loading shader properties...")
|
||||
|
||||
old_shader_type = props.shader_type
|
||||
props.shader_type = preset_data.get('shader_type', props.shader_type)
|
||||
print(f"[PRESET LOAD DEBUG] shader_type: {old_shader_type} -> {props.shader_type}")
|
||||
|
||||
old_shader_connection = props.shader_connection
|
||||
props.shader_connection = preset_data.get('shader_connection', props.shader_connection)
|
||||
print(f"[PRESET LOAD DEBUG] shader_connection: {old_shader_connection} -> {props.shader_connection}")
|
||||
|
||||
old_use_alpha = props.use_alpha
|
||||
props.use_alpha = preset_data.get('use_alpha', props.use_alpha)
|
||||
print(f"[PRESET LOAD DEBUG] use_alpha: {old_use_alpha} -> {props.use_alpha}")
|
||||
|
||||
old_emission_strength = props.emission_strength
|
||||
props.emission_strength = preset_data.get('emission_strength', props.emission_strength)
|
||||
print(f"[PRESET LOAD DEBUG] emission_strength: {old_emission_strength} -> {props.emission_strength}")
|
||||
|
||||
old_auto_assign = props.auto_assign_material
|
||||
props.auto_assign_material = preset_data.get('auto_assign_material', props.auto_assign_material)
|
||||
print(f"[PRESET LOAD DEBUG] auto_assign_material: {old_auto_assign} -> {props.auto_assign_material}")
|
||||
|
||||
# CRITICAL SHADER PROPERTIES - Most detailed logging
|
||||
print(f"[PRESET LOAD DEBUG] ==================== CRITICAL SHADER PROPERTIES ====================")
|
||||
|
||||
old_disable_shadows = props.disable_shadows
|
||||
new_disable_shadows = preset_data.get('disable_shadows', props.disable_shadows)
|
||||
props.disable_shadows = new_disable_shadows
|
||||
print(f"[PRESET LOAD DEBUG] disable_shadows:")
|
||||
print(f"[PRESET LOAD DEBUG] OLD VALUE: {old_disable_shadows} (type: {type(old_disable_shadows)})")
|
||||
print(f"[PRESET LOAD DEBUG] PRESET DATA: {preset_data.get('disable_shadows', 'NOT FOUND')} (type: {type(preset_data.get('disable_shadows', 'N/A'))})")
|
||||
print(f"[PRESET LOAD DEBUG] NEW VALUE: {props.disable_shadows} (type: {type(props.disable_shadows)})")
|
||||
|
||||
old_disable_reflections = props.disable_reflections
|
||||
new_disable_reflections = preset_data.get('disable_reflections', props.disable_reflections)
|
||||
props.disable_reflections = new_disable_reflections
|
||||
print(f"[PRESET LOAD DEBUG] disable_reflections:")
|
||||
print(f"[PRESET LOAD DEBUG] OLD VALUE: {old_disable_reflections} (type: {type(old_disable_reflections)})")
|
||||
print(f"[PRESET LOAD DEBUG] PRESET DATA: {preset_data.get('disable_reflections', 'NOT FOUND')} (type: {type(preset_data.get('disable_reflections', 'N/A'))})")
|
||||
print(f"[PRESET LOAD DEBUG] NEW VALUE: {props.disable_reflections} (type: {type(props.disable_reflections)})")
|
||||
|
||||
old_disable_backfacing = props.disable_backfacing
|
||||
new_disable_backfacing = preset_data.get('disable_backfacing', props.disable_backfacing)
|
||||
props.disable_backfacing = new_disable_backfacing
|
||||
print(f"[PRESET LOAD DEBUG] disable_backfacing:")
|
||||
print(f"[PRESET LOAD DEBUG] OLD VALUE: {old_disable_backfacing} (type: {type(old_disable_backfacing)})")
|
||||
print(f"[PRESET LOAD DEBUG] PRESET DATA: {preset_data.get('disable_backfacing', 'NOT FOUND')} (type: {type(preset_data.get('disable_backfacing', 'N/A'))})")
|
||||
print(f"[PRESET LOAD DEBUG] NEW VALUE: {props.disable_backfacing} (type: {type(props.disable_backfacing)})")
|
||||
|
||||
print(f"[PRESET LOAD DEBUG] ================================================================")
|
||||
|
||||
props.generate_normal_map = preset_data.get('generate_normal_map', props.generate_normal_map)
|
||||
props.normal_map_strength = preset_data.get('normal_map_strength', props.normal_map_strength)
|
||||
@@ -369,6 +357,7 @@ class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
props.shadow_color = preset_data.get('shadow_color', props.shadow_color)
|
||||
# Handle new shadow_spread property with backward compatibility
|
||||
if hasattr(props, 'shadow_spread'):
|
||||
pass
|
||||
props.shadow_spread = preset_data.get('shadow_spread', 1.0)
|
||||
props.enable_glow = preset_data.get('enable_glow', props.enable_glow)
|
||||
props.glow_blur = preset_data.get('glow_blur', props.glow_blur)
|
||||
@@ -389,6 +378,7 @@ class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
props.image_overlays.clear()
|
||||
overlay_data_list = preset_data.get('image_overlays', [])
|
||||
for overlay_data in overlay_data_list:
|
||||
pass
|
||||
overlay = props.image_overlays.add()
|
||||
overlay.name = overlay_data.get('name', 'Overlay')
|
||||
overlay.image_path = overlay_data.get('image_path', '')
|
||||
@@ -402,12 +392,6 @@ class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
props.is_updating = False
|
||||
|
||||
# FINAL VERIFICATION: Check what the properties actually are after loading
|
||||
print(f"[PRESET LOAD DEBUG] ==================== FINAL VERIFICATION ====================")
|
||||
print(f"[PRESET LOAD DEBUG] Properties AFTER loading preset '{self.preset_name}':")
|
||||
print(f"[PRESET LOAD DEBUG] disable_shadows: {props.disable_shadows} (type: {type(props.disable_shadows)})")
|
||||
print(f"[PRESET LOAD DEBUG] disable_reflections: {props.disable_reflections} (type: {type(props.disable_reflections)})")
|
||||
print(f"[PRESET LOAD DEBUG] disable_backfacing: {props.disable_backfacing} (type: {type(props.disable_backfacing)})")
|
||||
print(f"[PRESET LOAD DEBUG] ================================================================")
|
||||
|
||||
# Always generate preview after loading preset
|
||||
# Import preview generation function
|
||||
@@ -422,14 +406,17 @@ class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
self.report({'INFO'}, f"✅ Loaded preset '{self.preset_name}' {source_info}")
|
||||
|
||||
except (OSError, IOError) as e:
|
||||
pass
|
||||
props.is_updating = False
|
||||
self.report({'ERROR'}, f"Failed to read preset file: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
except json.JSONDecodeError as e:
|
||||
pass
|
||||
props.is_updating = False
|
||||
self.report({'ERROR'}, f"Invalid preset file format: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
except Exception as e:
|
||||
pass
|
||||
props.is_updating = False
|
||||
self.report({'ERROR'}, f"Unexpected error loading preset: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
@@ -437,6 +424,7 @@ class TEXT_TEXTURE_OT_load_preset(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
class TEXT_TEXTURE_OT_delete_preset(Operator):
|
||||
pass
|
||||
"""Delete preset"""
|
||||
bl_idname = "text_texture.delete_preset"
|
||||
bl_label = "Delete Preset"
|
||||
@@ -446,55 +434,68 @@ class TEXT_TEXTURE_OT_delete_preset(Operator):
|
||||
preset_name: StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
props = context.scene.text_texture_props
|
||||
|
||||
try:
|
||||
pass
|
||||
# Delete from both blend file and local storage
|
||||
blend_deleted = delete_blend_file_preset(self.preset_name)
|
||||
|
||||
preset_file = os.path.join(get_preset_path(), f"{self.preset_name}.json")
|
||||
local_deleted = False
|
||||
if os.path.exists(preset_file):
|
||||
pass
|
||||
os.remove(preset_file)
|
||||
local_deleted = True
|
||||
|
||||
if not blend_deleted and not local_deleted:
|
||||
pass
|
||||
self.report({'WARNING'}, f"Preset '{self.preset_name}' not found in blend file or local storage")
|
||||
|
||||
# Remove from UI list
|
||||
for i, preset in enumerate(props.presets):
|
||||
pass
|
||||
if preset.name == self.preset_name:
|
||||
pass
|
||||
props.presets.remove(i)
|
||||
break
|
||||
|
||||
delete_info = []
|
||||
if blend_deleted:
|
||||
pass
|
||||
delete_info.append("blend file")
|
||||
if local_deleted:
|
||||
pass
|
||||
delete_info.append("local storage")
|
||||
|
||||
location_text = " and ".join(delete_info) if delete_info else "nowhere (not found)"
|
||||
self.report({'INFO'}, f"🗑️ Deleted preset '{self.preset_name}' from {location_text}")
|
||||
|
||||
except (OSError, IOError) as e:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Failed to delete preset file: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
except Exception as e:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Unexpected error deleting preset: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
pass
|
||||
# Add confirmation dialog for better UX
|
||||
return context.window_manager.invoke_confirm(self, event)
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
layout = self.layout
|
||||
layout.label(text=f"Delete preset '{self.preset_name}'?")
|
||||
layout.label(text="This action cannot be undone.", icon='ERROR')
|
||||
|
||||
class TEXT_TEXTURE_OT_refresh_presets(Operator):
|
||||
pass
|
||||
"""Refresh presets from blend file and local storage"""
|
||||
bl_idname = "text_texture.refresh_presets"
|
||||
bl_label = "Refresh Presets"
|
||||
@@ -502,11 +503,14 @@ class TEXT_TEXTURE_OT_refresh_presets(Operator):
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
try:
|
||||
pass
|
||||
# Use the reliable synchronous refresh system
|
||||
success = refresh_presets_sync()
|
||||
|
||||
if success:
|
||||
pass
|
||||
props = context.scene.text_texture_props
|
||||
total_presets = len(props.presets)
|
||||
|
||||
@@ -517,21 +521,25 @@ class TEXT_TEXTURE_OT_refresh_presets(Operator):
|
||||
|
||||
self.report({'INFO'}, f"✅ Refreshed {total_presets} presets ({blend_count} blend file, {persistent_count} persistent, {local_count} local)")
|
||||
else:
|
||||
pass
|
||||
self.report({'WARNING'}, "Preset refresh completed with issues - check console for details")
|
||||
|
||||
# Force UI redraw
|
||||
for area in context.screen.areas:
|
||||
pass
|
||||
area.tag_redraw()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
except Exception as e:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Failed to refresh presets: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return {'CANCELLED'}
|
||||
|
||||
class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
pass
|
||||
"""Export all presets to a file for backup"""
|
||||
bl_idname = "text_texture.export_presets"
|
||||
bl_label = "Export Presets"
|
||||
@@ -546,7 +554,9 @@ class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
try:
|
||||
pass
|
||||
props = context.scene.text_texture_props
|
||||
|
||||
# Collect all presets from all sources
|
||||
@@ -555,6 +565,7 @@ class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
# Get blend file presets
|
||||
blend_presets = get_blend_file_presets()
|
||||
for name, data in blend_presets.items():
|
||||
pass
|
||||
all_presets[name] = {
|
||||
"data": data,
|
||||
"source": "BLEND_FILE"
|
||||
@@ -563,11 +574,15 @@ class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
# Get persistent presets
|
||||
persistent_dir = get_persistent_preset_path()
|
||||
if os.path.exists(persistent_dir):
|
||||
pass
|
||||
for filename in os.listdir(persistent_dir):
|
||||
pass
|
||||
if filename.endswith('.json'):
|
||||
pass
|
||||
preset_name = os.path.splitext(filename)[0]
|
||||
if preset_name not in all_presets: # Don't override blend file presets
|
||||
try:
|
||||
pass
|
||||
with open(os.path.join(persistent_dir, filename), 'r') as f:
|
||||
preset_data = json.load(f)
|
||||
all_presets[preset_name] = {
|
||||
@@ -575,16 +590,20 @@ class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
"source": "PERSISTENT_FILE"
|
||||
}
|
||||
except (json.JSONDecodeError, OSError) as e:
|
||||
print(f"[TTG] Error reading persistent preset {preset_name}: {e}")
|
||||
pass
|
||||
|
||||
# Get legacy presets
|
||||
legacy_dir = get_preset_path()
|
||||
if os.path.exists(legacy_dir) and legacy_dir != persistent_dir:
|
||||
pass
|
||||
for filename in os.listdir(legacy_dir):
|
||||
pass
|
||||
if filename.endswith('.json'):
|
||||
pass
|
||||
preset_name = os.path.splitext(filename)[0]
|
||||
if preset_name not in all_presets: # Don't override higher priority presets
|
||||
try:
|
||||
pass
|
||||
with open(os.path.join(legacy_dir, filename), 'r') as f:
|
||||
preset_data = json.load(f)
|
||||
all_presets[preset_name] = {
|
||||
@@ -592,9 +611,10 @@ class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
"source": "LOCAL_FILE"
|
||||
}
|
||||
except (json.JSONDecodeError, OSError) as e:
|
||||
print(f"[TTG] Error reading legacy preset {preset_name}: {e}")
|
||||
pass
|
||||
|
||||
if not all_presets:
|
||||
pass
|
||||
self.report({'WARNING'}, "No presets found to export")
|
||||
return {'CANCELLED'}
|
||||
|
||||
@@ -614,10 +634,12 @@ class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
except Exception as e:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Failed to export presets: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
pass
|
||||
# Set default filename with timestamp
|
||||
import datetime
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
@@ -627,6 +649,7 @@ class TEXT_TEXTURE_OT_export_presets(Operator):
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
class TEXT_TEXTURE_OT_import_presets(Operator):
|
||||
pass
|
||||
"""Import presets from a backup file"""
|
||||
bl_idname = "text_texture.import_presets"
|
||||
bl_label = "Import Presets"
|
||||
@@ -657,8 +680,11 @@ class TEXT_TEXTURE_OT_import_presets(Operator):
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
try:
|
||||
pass
|
||||
if not os.path.exists(self.filepath):
|
||||
pass
|
||||
self.report({'ERROR'}, "Backup file not found")
|
||||
return {'CANCELLED'}
|
||||
|
||||
@@ -670,11 +696,13 @@ class TEXT_TEXTURE_OT_import_presets(Operator):
|
||||
|
||||
# Validate format
|
||||
if "presets" not in import_data:
|
||||
pass
|
||||
self.report({'ERROR'}, "Invalid backup file format")
|
||||
return {'CANCELLED'}
|
||||
|
||||
imported_presets = import_data["presets"]
|
||||
if not imported_presets:
|
||||
pass
|
||||
self.report({'WARNING'}, "No presets found in backup file")
|
||||
return {'CANCELLED'}
|
||||
|
||||
@@ -685,8 +713,11 @@ class TEXT_TEXTURE_OT_import_presets(Operator):
|
||||
# Also check persistent storage
|
||||
persistent_dir = get_persistent_preset_path()
|
||||
if os.path.exists(persistent_dir):
|
||||
pass
|
||||
for filename in os.listdir(persistent_dir):
|
||||
pass
|
||||
if filename.endswith('.json'):
|
||||
pass
|
||||
existing_preset_names.add(os.path.splitext(filename)[0])
|
||||
|
||||
imported_count = 0
|
||||
@@ -694,29 +725,37 @@ class TEXT_TEXTURE_OT_import_presets(Operator):
|
||||
errors = []
|
||||
|
||||
for preset_name, preset_info in imported_presets.items():
|
||||
pass
|
||||
preset_data = preset_info.get("data", {})
|
||||
|
||||
# Handle conflicts
|
||||
final_name = preset_name
|
||||
if preset_name in existing_preset_names:
|
||||
pass
|
||||
if self.import_mode == 'SKIP':
|
||||
pass
|
||||
skipped_count += 1
|
||||
continue
|
||||
elif self.import_mode == 'RENAME':
|
||||
counter = 1
|
||||
base_name = preset_name
|
||||
while final_name in existing_preset_names:
|
||||
pass
|
||||
final_name = f"{base_name}_imported_{counter}"
|
||||
counter += 1
|
||||
# OVERWRITE mode uses original name
|
||||
|
||||
try:
|
||||
pass
|
||||
# Import to blend file or persistent storage based on setting
|
||||
if self.import_to_blend:
|
||||
pass
|
||||
success = save_blend_file_preset(final_name, preset_data)
|
||||
if not success:
|
||||
pass
|
||||
raise Exception("Failed to save to blend file")
|
||||
else:
|
||||
pass
|
||||
# Save to persistent storage
|
||||
persistent_file = os.path.join(get_persistent_preset_path(), f"{final_name}.json")
|
||||
with open(persistent_file, 'w') as f:
|
||||
@@ -727,50 +766,63 @@ class TEXT_TEXTURE_OT_import_presets(Operator):
|
||||
# Add to UI list if not already present
|
||||
existing_preset = None
|
||||
for preset in props.presets:
|
||||
pass
|
||||
if preset.name == final_name:
|
||||
pass
|
||||
existing_preset = preset
|
||||
break
|
||||
|
||||
if not existing_preset:
|
||||
pass
|
||||
new_preset = props.presets.add()
|
||||
new_preset.name = final_name
|
||||
new_preset.source = 'BLEND_FILE' if self.import_to_blend else 'PERSISTENT_FILE'
|
||||
else:
|
||||
pass
|
||||
existing_preset.source = 'BLEND_FILE' if self.import_to_blend else 'PERSISTENT_FILE'
|
||||
|
||||
except Exception as e:
|
||||
pass
|
||||
errors.append(f"{preset_name}: {str(e)}")
|
||||
|
||||
# Report results
|
||||
if imported_count > 0:
|
||||
pass
|
||||
storage_location = "blend file" if self.import_to_blend else "persistent storage"
|
||||
self.report({'INFO'}, f"✅ Imported {imported_count} presets to {storage_location}")
|
||||
if skipped_count > 0:
|
||||
pass
|
||||
self.report({'INFO'}, f"⏭️ Skipped {skipped_count} existing presets")
|
||||
else:
|
||||
pass
|
||||
self.report({'WARNING'}, "No presets were imported")
|
||||
|
||||
if errors:
|
||||
pass
|
||||
self.report({'WARNING'}, f"Errors importing {len(errors)} presets - check console")
|
||||
for error in errors[:5]: # Show first 5 errors
|
||||
print(f"[TTG] Import error: {error}")
|
||||
print(f"Import error: {error}")
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
except Exception as e:
|
||||
pass
|
||||
self.report({'ERROR'}, f"Failed to import presets: {str(e)}")
|
||||
return {'CANCELLED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
pass
|
||||
context.window_manager.fileselect_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
layout = self.layout
|
||||
layout.prop(self, "import_mode")
|
||||
layout.prop(self, "import_to_blend")
|
||||
|
||||
class TEXT_TEXTURE_OT_show_migration_report(Operator):
|
||||
pass
|
||||
"""Show migration report with backup and upgrade information"""
|
||||
bl_idname = "text_texture.show_migration_report"
|
||||
bl_label = "Show Migration Report"
|
||||
@@ -778,12 +830,15 @@ class TEXT_TEXTURE_OT_show_migration_report(Operator):
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
pass
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
pass
|
||||
return context.window_manager.invoke_props_dialog(self, width=400)
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
layout = self.layout
|
||||
layout.label(text="Migration Report", icon='INFO')
|
||||
layout.separator()
|
||||
|
||||
Reference in New Issue
Block a user