Blender 5.0 compat + STB XML import + sequence/stamps improvements
- Fix Blender 5.0 API: active_sequence_strip → active_strip, bracket property access on AddonPreferences, _RestrictContext during register() - Fix new_effect() frame_end → length for Blender 5.0 - Fix OTIO adapter kwargs (rate/ignore_timecode_mismatch only for cmx_3600) - Fix OTIO global_start_time RationalTime → int conversion - Add Import STB XML operator with movie strip import and XML patching for Storyboard Pro transitions missing <alignment> - Add Create Sequence Strip operator (select shots → create sequence) - Improve Set Stamps: channel at top, no conflict with existing strips, use raw strip names in templates - TVSHOW episode fixes: sequence loading, episode creation - Kitsu: new_asset, new_episode, admin_connect fix, gazu version pin - Fix escape warnings in file_utils regex patterns - Guard handler registration against duplicates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+11
-7
@@ -139,7 +139,7 @@ class VSETB_PT_strip(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
strip = context.active_sequence_strip
|
||||
strip = context.active_strip
|
||||
return strip and get_channel_name(strip) == 'Shots'
|
||||
|
||||
def draw(self, context):
|
||||
@@ -174,7 +174,7 @@ class VSETB_PT_sequencer(VSETB_main, Panel):
|
||||
settings = get_scene_settings()
|
||||
project = settings.active_project
|
||||
|
||||
strip = context.active_sequence_strip
|
||||
strip = context.active_strip
|
||||
channel = get_channel_name(strip)
|
||||
|
||||
col = layout.column()
|
||||
@@ -224,6 +224,7 @@ class VSETB_PT_imports(VSETB_main, Panel):
|
||||
#col.operator('vse_toolbox.import_files', text='Import', icon='IMPORT')
|
||||
col.operator('vse_toolbox.import_spreadsheet', text='Import Spreadsheet', icon='SPREADSHEET')
|
||||
col.operator("vse_toolbox.import_shots", text='Import Shots', icon="FILE_MOVIE")
|
||||
col.operator("vse_toolbox.import_stb_xml", text='Import STB XML', icon="FILE_TEXT")
|
||||
|
||||
|
||||
class VSETB_PT_presets(PresetPanel, Panel):
|
||||
@@ -264,10 +265,10 @@ class VSETB_PT_tracker(VSETB_main, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_sequence_strip
|
||||
return context.active_strip
|
||||
|
||||
def draw_header_preset(self, context):
|
||||
active_strip = context.active_sequence_strip
|
||||
active_strip = context.active_strip
|
||||
self.layout.label(text=active_strip.name)
|
||||
|
||||
def draw(self, context):
|
||||
@@ -280,7 +281,7 @@ class VSETB_PT_casting(VSETB_main, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
strip = context.active_sequence_strip
|
||||
strip = context.active_strip
|
||||
return strip and get_channel_name(strip) == 'Shots'
|
||||
|
||||
def draw(self, context):
|
||||
@@ -315,6 +316,8 @@ class VSETB_PT_casting(VSETB_main, Panel):
|
||||
col_tool.separator()
|
||||
|
||||
col_tool.operator('vse_toolbox.casting_replace', icon='ZOOM_ALL', text="")
|
||||
col_tool.separator()
|
||||
col_tool.operator('vse_toolbox.casting_create_asset', icon='PLUS', text="")
|
||||
|
||||
if strip_settings.casting:
|
||||
casting_item = strip_settings.casting[strip_settings.casting_index]
|
||||
@@ -336,7 +339,7 @@ class VSETB_PT_metadata(VSETB_main, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_sequence_strip and get_scene_settings().active_project
|
||||
return context.active_strip and get_scene_settings().active_project
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
@@ -383,7 +386,7 @@ class VSETB_PT_comments(VSETB_main, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_sequence_strip and get_scene_settings().active_project
|
||||
return context.active_strip and get_scene_settings().active_project
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -455,6 +458,7 @@ class VSETB_MT_main_menu(Menu):
|
||||
layout.operator('vse_toolbox.remove_channel', text='Remove Channel', icon='TRIA_DOWN_BAR')
|
||||
layout.separator()
|
||||
layout.operator('vse_toolbox.merge_shot_strips', text='Merge Shots')
|
||||
layout.operator('vse_toolbox.create_sequence_strip', text='Create Sequence')
|
||||
layout.operator('vse_toolbox.scene_cut_detection', text='Scene Cut Detection', icon='SCULPTMODE_HLT')
|
||||
|
||||
def draw_vse_toolbox_menu(self, context):
|
||||
|
||||
+6
-2
@@ -91,7 +91,11 @@ def load_prefs():
|
||||
continue
|
||||
setattr(tracker_pref, k, os.path.expandvars(v))
|
||||
|
||||
prefs['tracker_name'] = prefs_datas['tracker_name']
|
||||
try:
|
||||
settings = get_scene_settings()
|
||||
settings.tracker_name = prefs_datas['tracker_name']
|
||||
except AttributeError:
|
||||
pass # Scene not available yet during register()
|
||||
|
||||
|
||||
class Trackers(PropertyGroup):
|
||||
@@ -155,7 +159,7 @@ def register():
|
||||
|
||||
config_path = os.getenv('VSE_TOOLBOX_CONFIG')
|
||||
if config_path:
|
||||
prefs['config_path'] = os.path.expandvars(config_path)
|
||||
prefs.config_path = os.path.expandvars(config_path)
|
||||
|
||||
load_prefs()
|
||||
|
||||
|
||||
+25
-4
@@ -299,7 +299,28 @@ def get_episodes_items(self, context):
|
||||
|
||||
def on_episode_updated(self, context):
|
||||
settings = get_scene_settings()
|
||||
os.environ['TRACKER_EPISODE_ID'] = settings.active_episode.id
|
||||
project = settings.active_project
|
||||
episode = settings.active_episode
|
||||
|
||||
if not episode or not episode.id:
|
||||
return
|
||||
|
||||
os.environ['TRACKER_EPISODE_ID'] = episode.id
|
||||
|
||||
# Reload sequences for the selected episode (TVSHOW workflow)
|
||||
prefs = get_addon_prefs()
|
||||
tracker = prefs.tracker
|
||||
if not tracker or not project:
|
||||
return
|
||||
|
||||
project.sequences.clear()
|
||||
try:
|
||||
for seq in tracker.get_sequences(project.id, episode=episode.id):
|
||||
item = project.sequences.add()
|
||||
item.name = seq['name']
|
||||
item.id = seq['id']
|
||||
except Exception as e:
|
||||
print(f'Could not load sequences for episode {episode.name}: {e}')
|
||||
|
||||
class Project(PropertyGroup):
|
||||
id : StringProperty(default='')
|
||||
@@ -715,7 +736,7 @@ class VSETB_PGT_strip_settings(PropertyGroup):
|
||||
|
||||
@property
|
||||
def strip(self):
|
||||
sequences = bpy.context.scene.sequence_editor.sequences_all
|
||||
sequences = bpy.context.scene.sequence_editor.strips_all
|
||||
return next(s for s in sequences if s.vsetb_strip_settings == self)
|
||||
|
||||
@property
|
||||
@@ -808,7 +829,7 @@ def register():
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
bpy.types.Scene.vsetb_settings = PointerProperty(type=VSETB_PGT_scene_settings)
|
||||
bpy.types.Sequence.vsetb_strip_settings = PointerProperty(type=VSETB_PGT_strip_settings)
|
||||
bpy.types.Strip.vsetb_strip_settings = PointerProperty(type=VSETB_PGT_strip_settings)
|
||||
|
||||
#load_metadata_types()
|
||||
bpy.app.handlers.load_post.append(load_handler)
|
||||
@@ -818,7 +839,7 @@ def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
del bpy.types.Sequence.vsetb_strip_settings
|
||||
del bpy.types.Strip.vsetb_strip_settings
|
||||
del bpy.types.Scene.vsetb_settings
|
||||
|
||||
bpy.app.handlers.load_post.remove(load_handler)
|
||||
|
||||
Reference in New Issue
Block a user