Adding Sequencer Tools, a (basic and beginning) collection of tools for the Sequencer.
authorBastien Montagne <montagne29@wanadoo.fr>
Mon, 21 May 2012 14:53:19 +0000 (14:53 +0000)
committerBastien Montagne <montagne29@wanadoo.fr>
Mon, 21 May 2012 14:53:19 +0000 (14:53 +0000)
Currently only contains a tool to render/export selected strips, will add more as need raises…

sequencer_tools/__init__.py [new file with mode: 0644]
sequencer_tools/export_strips.py [new file with mode: 0644]

diff --git a/sequencer_tools/__init__.py b/sequencer_tools/__init__.py
new file mode 100644 (file)
index 0000000..3d1cce2
--- /dev/null
@@ -0,0 +1,120 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+    "name": "Sequencer Tools",
+    "author": "mont29",
+    "version": (0, 0, 1),
+    "blender": (2, 6, 3),
+    "location": "Sequencer menus/UI",
+    "description": "Various Sequencer tools.",
+    "warning": "",
+    "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Sequencer/Tools",
+    "tracker_url": "projects.blender.org/tracker/index.php?func=detail&aid=31549",
+    "support": 'TESTING',
+    "category": "Sequencer"
+}
+
+
+import bpy
+
+from sequencer_tools.export_strips import SEQExportStrip
+
+
+KEYMAPS = (
+    # First, keymap identifiers (last bool is True for modal km).
+    (("Sequencer", "WINDOW", "SEQUENCE_EDITOR", False), (
+    # Then a tuple of keymap items, defined by a dict of kwargs for
+    # the km new func, and a tuple of tuples (name, val) for ops properties,
+    # if needing non-default values.
+        ({"idname": SEQExportStrip.bl_idname, "type": "P", "value": "PRESS",
+                                              "shift": True, "ctrl": True},
+         ()),
+    )),
+)
+
+
+def menu_func(self, context):
+    self.layout.operator(SEQExportStrip.bl_idname, text="Export Selected")
+
+
+def find_keymap_items(km, idname):
+    return (i for i in km.keymap_items if i.idname == idname)
+
+
+def update_keymap(activate):
+    # Add.
+    if activate:
+        kconf = bpy.context.window_manager.keyconfigs.addon
+        for km_info, km_items in KEYMAPS:
+            km_name, km_regtype, km_sptype, km_ismodal = km_info
+            kmap = [k for k in kconf.keymaps
+                    if k.name == km_name and k.region_type == km_regtype and
+                       k.space_type == km_sptype and k.is_modal == km_ismodal]
+            if kmap:
+                kmap = kmap[0]
+            else:
+                kmap = kconf.keymaps.new(km_name, region_type=km_regtype,
+                                         space_type=km_sptype,
+                                         modal=km_ismodal)
+            for kmi_kwargs, props in km_items:
+                kmi = kmap.keymap_items.new(**kmi_kwargs)
+                kmi.active = True
+                for prop, val in props:
+                    setattr(kmi.properties, prop, val)
+
+    # Remove.
+    else:
+        # XXX We must also clean up user keyconfig, else, if user has
+        #     customized one of our shortcut, this customization
+        #     remains in memory, and comes back when re-enabling the addon,
+        #     causing a sigsev... :/
+        kconfs = bpy.context.window_manager.keyconfigs
+        for kconf in (kconfs.user, kconfs.addon):
+            for km_info, km_items in KEYMAPS:
+                km_name, km_regtype, km_sptype, km_ismodal = km_info
+                kmaps = (k for k in kconf.keymaps
+                         if k.name == km_name and
+                            k.region_type == km_regtype and
+                            k.space_type == km_sptype and
+                            k.is_modal == km_ismodal)
+                for kmap in kmaps:
+                    for kmi_kwargs, props in km_items:
+                        for kmi in find_keymap_items(kmap,
+                                                     kmi_kwargs["idname"]):
+                            kmap.keymap_items.remove(kmi)
+                # XXX We won’t remove addons keymaps themselves,
+                #     other addons might also use them!
+
+
+def register():
+    bpy.utils.register_module(__name__)
+    bpy.types.SEQUENCER_MT_strip.append(menu_func)
+
+    update_keymap(True)
+
+
+def unregister():
+    bpy.utils.unregister_module(__name__)
+    bpy.types.SEQUENCER_MT_strip.remove(menu_func)
+
+    update_keymap(False)
+
+
+if __name__ == "__main__":
+    register()
diff --git a/sequencer_tools/export_strips.py b/sequencer_tools/export_strips.py
new file mode 100644 (file)
index 0000000..c46e228
--- /dev/null
@@ -0,0 +1,72 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+import bpy
+from bpy.props import StringProperty
+
+class SEQExportStrip(bpy.types.Operator):
+    """
+    Export (render) selected strips in sequencer
+    """
+    bl_idname = "sequencer.export_strips"
+    bl_label = "Export Strips"
+    filepath = StringProperty(subtype='FILE_PATH')
+
+    def execute(self, context):
+        sce = bpy.context.scene
+        back_filepath = sce.render.filepath
+        back_seq = sce.render.use_sequencer
+        back_start = sce.frame_start
+        back_end = sce.frame_end
+        hidden_seq = []
+
+        sce.render.use_sequencer = True
+        sce.render.filepath = self.filepath
+        seq = sce.sequence_editor
+        start = end = None
+        for strip in seq.sequences_all:
+            if not strip.select:
+                if not strip.mute:
+                    strip.mute = True
+                    hidden_seq.append(strip)
+                continue
+            if start is None or strip.frame_final_start < start:
+                start = strip.frame_final_start
+            if end is None or strip.frame_final_end < end:
+                end = strip.frame_final_end
+        sce.frame_start = start
+        sce.frame_end = end
+
+        # Non-blocking render!
+        bpy.ops.render.render("INVOKE_DEFAULT", animation=True)
+
+        for strip in hidden_seq:
+            strip.mute = False
+        sce.render.use_sequencer = back_seq
+        sce.render.filepath = back_filepath
+        sce.frame_start = back_start
+        sce.frame_end = back_end
+        return {"FINISHED"}
+
+    def invoke(self, context, event):
+        if not self.filepath:
+            self.filepath = bpy.context.scene.render.filepath
+        winman = context.window_manager
+        winman.fileselect_add(self)
+        return {"RUNNING_MODAL"}
+