# SPDX-License-Identifier: GPL-2.0-or-later import bpy import importlib import re import vse_toolbox from bpy_extras.io_utils import ImportHelper from bpy.props import ( CollectionProperty, BoolProperty, EnumProperty, IntProperty, StringProperty, ) from bpy.types import ( Operator, ) from pathlib import Path from vse_toolbox.sequencer_utils import ( get_shot_sequence, get_strips, import_edl, rename_strips, render_strips, set_channels, ) from vse_toolbox.bl_utils import get_addon_prefs, get_settings from vse_toolbox.file_utils import install_module, norm_str class VSETB_OT_export_csv(Operator): bl_idname = "sequencer.export_csv" bl_label = "Set Scene" bl_description = "Set Scene for Breakdown" bl_options = {"REGISTER", "UNDO"} @classmethod def poll(cls, context): return True def execute(self, context): self.report({'ERROR'}, f'Export not implemented yet.') return {"CANCELLED"} class VSETB_OT_import(Operator): bl_idname = "sequencer.import" bl_label = "Set Scene" bl_description = "Set Scene for Breakdown" bl_options = {"REGISTER", "UNDO"} directory : StringProperty(subtype='DIR_PATH') filepath: StringProperty( name="File Path", description="Filepath used for importing the file", maxlen=1024, subtype='FILE_PATH', ) files : CollectionProperty(type=bpy.types.OperatorFileListElement) filter_glob: StringProperty( default='*.edl;*.mov;*.wav', options={'HIDDEN'} ) @classmethod def poll(cls, context): return True def invoke(self, context, event): context.window_manager.fileselect_add(self) return {'RUNNING_MODAL'} def execute(self, context): otio = install_module('opentimelineio') for filepath in self.files: filepath = Path(self.directory, filepath.name) if filepath.suffix == '.edl': edl = import_edl(filepath, adapter="cmx_3600") print('edl: ', edl) return {"CANCELLED"} class VSETB_OT_load_projects(Operator): bl_idname = "vse_toolbox.load_projects" bl_label = "Load Projects" bl_description = "Load Projects" bl_options = {"REGISTER", "UNDO"} @classmethod def poll(cls, context): return True def execute(self, context): settings = get_settings() prefs = get_addon_prefs() tracker = prefs.tracker settings.projects.clear() tracker.connect() for project_data in tracker.get_projects(): project = settings.projects.add() project.name = project_data['name'] project.id = project_data['id'] for episode_data in tracker.get_episodes(project_data): episode = project.episodes.add() episode.name = episode_data['name'] episode.id = episode_data['id'] return {'FINISHED'} class VSETB_OT_new_episode(Operator): bl_idname = "vse_toolbox.new_episode" bl_label = "New Epispde" bl_description = "Add new Episode to Project" bl_options = {"REGISTER", "UNDO"} episode_name : StringProperty(name="Episode Name", default="") @classmethod def poll(cls, context): return True def invoke(self, context, event): scn = context.scene settings = get_settings() return context.window_manager.invoke_props_dialog(self) def execute(self, context): settings = get_settings() prefs = get_addon_prefs() tracker = prefs.tracker episode_name = settings.episode_template.format(index=int(self.episode_name)) print(self.episode_name) print('episode_name: ', episode_name) episode = tracker.get_episode(episode_name) if episode: self.report({'ERROR'}, f'Episode {episode_name} already exists') return {"CANCELLED"} tracker.new_episode(episode_name) # tracker.get_episodes tracker.update_project() self.report({'INFO'}, f'Episode {episode_name} successfully created') return {'FINISHED'} class VSETB_OT_reload_addon(Operator): bl_idname = "vse_toolbox.reload_addon" bl_options = {"UNDO"} bl_label = 'Reload VSE ToolBox Addon' bl_description = 'Reload The VSE ToolBox Addon' def execute(self, context): print('Execute reload') vse_toolbox.unregister() importlib.reload(vse_toolbox) vse_toolbox.register() return {'FINISHED'} class VSETB_OT_rename(Operator): bl_idname = "sequencer.strips_rename" bl_label = "Rename Strips" bl_description = "Rename Strips" bl_options = {"REGISTER", "UNDO"} template : StringProperty(name="Strip Template Name", default="") increment : IntProperty(name="Name Increment", default=0) channel_name : StringProperty(name="Channel Name", default="") selected_only : BoolProperty(name="Selected Only", default=False) start_number : IntProperty(name="Start Number", default=0, min=0) by_sequence : BoolProperty( name="Reset By Sequence", description="Reset Start Number for each sequence", default=False ) @classmethod def poll(cls, context): return True def invoke(self, context, event): scn = context.scene settings = get_settings() return context.window_manager.invoke_props_dialog(self) def draw(self, context): scn = context.scene settings = get_settings() col = self.layout col.use_property_split = True col.prop(self, 'template') col.prop(self, 'start_number') if self.channel_name == 'Shots': col.prop(self, 'by_sequence') col.prop(self, 'selected_only') def execute(self, context): scn = context.scene strips = get_strips(channel=self.channel_name, selected_only=self.selected_only) rename_strips( strips, self.template, increment=self.increment, start_number=self.start_number, by_sequence=self.by_sequence ) return {"FINISHED"} class VSETB_OT_render(Operator): bl_idname = "sequencer.strips_render" bl_label = "Render Shots Strips" bl_description = "Render Shots Strips" bl_options = {"REGISTER", "UNDO"} selected_only : BoolProperty(name="Selected Only", default=False) @classmethod def poll(cls, context): return True def invoke(self, context, event): scn = context.scene settings = get_settings() return context.window_manager.invoke_props_dialog(self) def draw(self, context): scn = context.scene settings = get_settings() col = self.layout col.use_property_split = True col.use_property_decorate = False col.prop(settings, 'channels', text='Channel') col.prop(self, 'selected_only') def execute(self, context): scn = context.scene strips = get_strips(channel=self.channel_name, selected_only=self.selected_only) render_strips(strips) return {"FINISHED"} class VSETB_OT_set_scene(Operator): bl_idname = "scene.set_scene" bl_label = "Set Scene" bl_description = "Set Scene for Breakdown" bl_options = {"REGISTER", "UNDO"} @classmethod def poll(cls, context): return True def execute(self, context): scn = context.scene set_channels() movie = get_strips(channel='Movie') if movie: movie = movie[0] movie.transform.scale_x = movie.transform.scale_y = 1 elem = movie.strip_elem_from_frame(scn.frame_current) scn.render.resolution_x = elem.orig_width scn.render.resolution_y = elem.orig_height else: self.report({'INFO'}, f'Cannot set Resolution. No Movie Found.') return {"FINISHED"} classes=( VSETB_OT_export_csv, VSETB_OT_import, VSETB_OT_load_projects, VSETB_OT_new_episode, VSETB_OT_reload_addon, VSETB_OT_rename, VSETB_OT_render, VSETB_OT_set_scene, ) def register(): for cls in classes: bpy.utils.register_class(cls) def unregister(): for cls in reversed(classes): bpy.utils.unregister_class(cls)