General cleanup in sequencer:
[blender-staging.git] / source / blender / python / api2_2x / sceneSequence.c
1 /*
2  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. The Blender
8  * Foundation also sells licenses for use in proprietary software under
9  * the Blender License.  See http://www.blender.org/BL/ for information
10  * about this.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * This is a new part of Blender.
25  *
26  * Contributor(s): Campbell Barton
27  *
28  * ***** END GPL/BL DUAL LICENSE BLOCK *****
29  */
30
31 #include "sceneSequence.h" /* This must come first */
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_sequence_types.h"
36 #include "DNA_scene_types.h" /* for Base */
37
38 #include "BKE_mesh.h"
39 #include "BKE_library.h"
40 #include "BKE_global.h"
41 #include "BKE_main.h"
42 #include "BKE_scene.h"
43
44 #include "BIF_editseq.h" /* get_last_seq */
45 #include "BLI_blenlib.h"
46 #include "BSE_sequence.h"
47 #include "Ipo.h"
48 #include "blendef.h"  /* CLAMP */
49 #include "BKE_utildefines.h"
50 #include "Scene.h"
51 #include "Sound.h"
52 #include "gen_utils.h"
53
54 enum seq_consts {
55         EXPP_SEQ_ATTR_TYPE = 0,
56         EXPP_SEQ_ATTR_CHAN,
57         EXPP_SEQ_ATTR_LENGTH,
58         EXPP_SEQ_ATTR_START,
59         EXPP_SEQ_ATTR_STARTOFS,
60         EXPP_SEQ_ATTR_ENDOFS,
61         EXPP_SEQ_ATTR_STARTSTILL,
62         EXPP_SEQ_ATTR_ENDSTILL
63 };
64
65
66 /*****************************************************************************/
67 /* Python API function prototypes for the Blender module.                */
68 /*****************************************************************************/
69 /*PyObject *M_Sequence_Get( PyObject * self, PyObject * args );*/
70
71 /*****************************************************************************/
72 /* Python method structure definition for Blender.Object module:         */
73 /*****************************************************************************/
74 /*struct PyMethodDef M_Sequence_methods[] = {
75         {"Get", ( PyCFunction ) M_Sequence_Get, METH_VARARGS,
76 "(name) - return the sequence with the name 'name',\
77 returns None if notfound.\nIf 'name' is not specified, it returns a list of all sequences."},
78         {NULL, NULL, 0, NULL}
79 };*/
80
81 /*****************************************************************************/
82 /* Python BPy_Sequence methods table:                                      */
83 /*****************************************************************************/
84 static PyObject *Sequence_copy( BPy_Sequence * self );
85 static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args );
86 static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args );
87
88 static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args );
89 static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args );
90 static void intern_pos_update(Sequence * seq); 
91
92 static PyMethodDef BPy_Sequence_methods[] = {
93         /* name, method, flags, doc */
94         {"new", ( PyCFunction ) Sequence_new, METH_VARARGS,
95          "(data) - Return a new sequence."},
96         {"remove", ( PyCFunction ) Sequence_remove, METH_VARARGS,
97          "(data) - Remove a strip."},
98         {"__copy__", ( PyCFunction ) Sequence_copy, METH_NOARGS,
99          "() - Return a copy of the sequence containing the same objects."},
100         {"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS,
101          "() - Return a copy of the sequence containing the same objects."},
102         {NULL, NULL, 0, NULL}
103 };
104
105 static PyMethodDef BPy_SceneSeq_methods[] = {
106         /* name, method, flags, doc */
107         {"new", ( PyCFunction ) SceneSeq_new, METH_VARARGS,
108          "(data) - Return a new sequence."},
109         {"remove", ( PyCFunction ) SceneSeq_remove, METH_VARARGS,
110          "(data) - Remove a strip."},
111         {NULL, NULL, 0, NULL}
112 };
113
114 /* use to add a sequence to a scene or its listbase */
115 static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
116 {
117         PyObject *py_data = NULL;
118         
119         Sequence *seq;
120         int a;
121         Strip *strip;
122         StripElem *se;
123         int start, machine;
124         
125         if( !PyArg_ParseTuple( args, "Oii", &py_data, &start, &machine ) )
126                 return EXPP_ReturnPyObjError( PyExc_ValueError,
127                         "expect sequence data then 2 ints - (seqdata, start, track)" );
128         
129         seq = alloc_sequence(seqbase, start, machine); /* warning, this sets last */
130         
131         if (PyTuple_Check(py_data)) {
132                 /* Image */
133                 PyObject *list;
134                 char *name;
135                 
136                 if (!PyArg_ParseTuple( py_data, "sO!", &name, &PyList_Type, &list)) {
137                         BLI_remlink(seqbase, seq);
138                         MEM_freeN(seq);
139                         
140                         return EXPP_ReturnPyObjError( PyExc_ValueError,
141                                 "images data needs to be a tuple of a string and a list of images - (path, [filenames...])" );
142                 }
143                 
144                 seq->type= SEQ_IMAGE;
145                 
146                 seq->len = PyList_Size( list );
147                 
148                 
149                 /* strip and stripdata */
150                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
151                 strip->len= seq->len;
152                 strip->us= 1;
153                 strncpy(strip->dir, name, FILE_MAXDIR-1);
154                 strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
155
156                 for(a=0; a<seq->len; a++) {
157                         name = PyString_AsString(PyList_GetItem( list, a ));
158                         strncpy(se->name, name, FILE_MAXFILE-1);
159                         se++;
160                 }               
161                 
162         } else if (BPy_Sound_Check(py_data)) {
163                 /* sound */
164                 int totframe;
165                 bSound *sound = (( BPy_Sound * )py_data)->sound;
166                 
167                 
168                 seq->type= SEQ_RAM_SOUND;
169                 seq->sound = sound;
170                 
171                 totframe= (int) ( ((float)(sound->streamlen-1)/( (float)sce->audio.mixrate*4.0 ))* (float)sce->r.frs_sec / sce->r.frs_sec_base);
172                 
173                 sound->flags |= SOUND_FLAGS_SEQUENCE;
174                 
175                 
176                 /* strip and stripdata */
177                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
178                 strip->len= totframe;
179                 strip->us= 1;
180                 strncpy(strip->dir, sound->name, FILE_MAXDIR-1);
181                 strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
182
183                 /* name sound in first strip */
184                 strncpy(se->name, sound->name, FILE_MAXFILE-1);
185                 
186         } else if (BPy_Scene_Check(py_data)) {
187                 /* scene */
188                 Scene *sce = ((BPy_Scene *)py_data)->scene;
189                 
190                 seq->type= SEQ_SCENE;
191                 seq->scene= sce;
192                 
193                 /*seq->sfra= sce->r.sfra;*/
194                 seq->len= sce->r.efra - sce->r.sfra + 1;
195
196                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
197                 strncpy(seq->name + 2, sce->id.name + 2, 
198                         sizeof(seq->name) - 2);
199                 strip->len= seq->len;
200                 strip->us= 1;
201         } else {
202                 /* movie, pydata is a path to a movie file */
203                 char *name = PyString_AsString ( py_data );
204                 if (!name) {
205                         /* only free these 2 because other stuff isnt set */
206                         BLI_remlink(seqbase, seq);
207                         MEM_freeN(seq);
208                         
209                         return EXPP_ReturnPyObjError( PyExc_TypeError,
210                                 "expects a string for chan/bone name and an int for the frame where to put the new key" );
211                 }
212                 
213                 seq->type= SEQ_MOVIE;
214         }
215         strncpy(seq->name+2, "Untitled", 21);
216         intern_pos_update(seq);
217         return Sequence_CreatePyObject(seq, NULL, sce);
218 }
219
220 static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args )
221 {
222         return NewSeq_internal(&self->seq->seqbase, args, self->scene);
223 }
224
225 static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args )
226 {
227         return NewSeq_internal( &((Editing *)self->scene->ed)->seqbase, args, self->scene);
228 }
229
230 static void del_seq__internal(Sequence *seq)
231 {
232         if(seq->ipo) seq->ipo->id.us--;
233         
234         if(seq->type==SEQ_RAM_SOUND && seq->sound) 
235                 seq->sound->id.us--;
236         free_sequence(seq);
237 }
238
239 static void recurs_del_seq(ListBase *lb)
240 {
241         Sequence *seq, *seqn;
242
243         seq= lb->first;
244         while(seq) {
245                 seqn= seq->next;
246                 BLI_remlink(lb, seq);
247                 if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase);
248                 del_seq__internal(seq);
249                 seq= seqn;
250         }
251 }
252
253 static PyObject *RemoveSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
254 {
255         BPy_Sequence *bpy_seq = NULL;
256         
257         if( !PyArg_ParseTuple( args, "O!", &Sequence_Type, &bpy_seq ) )
258                 return EXPP_ReturnPyObjError( PyExc_ValueError,
259                         "expects a sequence object" );
260         
261         /* quick way to tell if we dont have the seq */
262         if (sce != bpy_seq->scene)
263                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
264                         "Sequence does not exist here, cannot remove" );
265         
266         recurs_del_seq(&bpy_seq->seq->seqbase);
267         del_seq__internal(bpy_seq->seq);
268         clear_last_seq(); /* just incase */
269         Py_RETURN_NONE;
270 }
271
272 static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args )
273 {
274         return RemoveSeq_internal(&self->seq->seqbase, args, self->scene);
275 }
276
277 static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args )
278 {
279         return RemoveSeq_internal( &((Editing *)self->scene->ed)->seqbase, args, self->scene);
280 }
281
282
283 static PyObject *Sequence_copy( BPy_Sequence * self )
284 {
285         printf("Sequence Copy not implimented yet!\n");
286         Py_RETURN_NONE;
287 }
288
289 /*****************************************************************************/
290 /* PythonTypeObject callback function prototypes                         */
291 /*****************************************************************************/
292 static PyObject *Sequence_repr( BPy_Sequence * obj );
293 static PyObject *SceneSeq_repr( BPy_SceneSeq * obj );
294 static int Sequence_compare( BPy_Sequence * a, BPy_Sequence * b );
295 static int SceneSeq_compare( BPy_SceneSeq * a, BPy_SceneSeq * b );
296
297 /*****************************************************************************/
298 /* Python BPy_Sequence methods:                                                  */
299 /*****************************************************************************/
300
301
302 static PyObject *Sequence_getIter( BPy_Sequence * self )
303 {
304         Sequence *iter = self->seq->seqbase.first;
305         
306         if (!self->iter) {
307                 self->iter = iter;
308                 return EXPP_incr_ret ( (PyObject *) self );
309         } else {
310                 return Sequence_CreatePyObject(self->seq, iter, self->scene);
311         }
312 }
313
314 static PyObject *SceneSeq_getIter( BPy_SceneSeq * self )
315 {
316         Sequence *iter = ((Editing *)self->scene->ed)->seqbase.first;
317         
318         if (!self->iter) {
319                 self->iter = iter;
320                 return EXPP_incr_ret ( (PyObject *) self );
321         } else {
322                 return SceneSeq_CreatePyObject(self->scene, iter);
323         }
324 }
325
326
327 /*
328  * Return next Seq
329  */
330 static PyObject *Sequence_nextIter( BPy_Sequence * self )
331 {
332         PyObject *object;
333         if( !(self->iter) ) {
334                 self->iter = NULL; /* so we can add objects again */
335                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
336                                 "iterator at end" );
337         }
338         
339         object= Sequence_CreatePyObject( self->iter, NULL, self->scene ); 
340         self->iter= self->iter->next;
341         return object;
342 }
343
344
345 /*
346  * Return next Seq
347  */
348 static PyObject *SceneSeq_nextIter( BPy_Sequence * self )
349 {
350         PyObject *object;
351         if( !(self->iter) ) {
352                 self->iter = NULL; /* so we can add objects again */
353                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
354                                 "iterator at end" );
355         }
356         
357         object= Sequence_CreatePyObject( self->iter, NULL, self->scene );
358         self->iter= self->iter->next;
359         return object;
360 }
361
362
363
364 static PyObject *Sequence_getName( BPy_Sequence * self )
365 {
366         return PyString_FromString( self->seq->name+2 );
367 }
368
369 static int Sequence_setName( BPy_Sequence * self, PyObject * value )
370 {
371         char *name = NULL;
372         
373         name = PyString_AsString ( value );
374         if( !name )
375                 return EXPP_ReturnIntError( PyExc_TypeError,
376                                               "expected string argument" );
377
378         strncpy(self->seq->name+2, name, 21);
379         return 0;
380 }
381
382
383 static PyObject *Sequence_getSound( BPy_Sequence * self )
384 {
385         if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
386                 return Sound_CreatePyObject(self->seq->sound);
387         Py_RETURN_NONE;
388 }
389
390 static PyObject *Sequence_getIpo( BPy_Sequence * self )
391 {
392         struct Ipo *ipo;
393         
394         ipo = self->seq->ipo;
395
396         if( ipo )
397                 return Ipo_CreatePyObject( ipo );
398         Py_RETURN_NONE;
399 }
400
401
402 static PyObject *SceneSeq_getActive( BPy_SceneSeq * self )
403 {
404         Sequence *last_seq = NULL, *seq;
405         Editing *ed = self->scene->ed;
406
407         if (!ed)
408                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
409                                               "scene has no sequence data to edit" );
410         
411         seq = ed->seqbasep->first;
412         
413         while (seq) {
414                 if (seq->flag & SELECT)
415                         last_seq = seq;
416                 
417                 seq = seq->next;
418         }
419         if (last_seq)
420                 return Sequence_CreatePyObject(last_seq, NULL, self->scene );
421         
422         Py_RETURN_NONE;
423 }
424
425 static PyObject *SceneSeq_getMetaStrip( BPy_SceneSeq * self )
426 {
427         Sequence *seq = NULL;
428         Editing *ed = self->scene->ed;
429         MetaStack *ms;
430         if (!ed)
431                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
432                                               "scene has no sequence data to edit" );
433         
434         ms = ed->metastack.last;
435         if (!ms)
436                 Py_RETURN_NONE;
437         
438         seq = ms->parseq;
439         return Sequence_CreatePyObject(seq, NULL, self->scene);
440 }
441
442
443 /*
444  * this should accept a Py_None argument and just delete the Ipo link
445  * (as Object_clearIpo() does)
446  */
447
448 static int Sequence_setIpo( BPy_Sequence * self, PyObject * value )
449 {
450         Ipo *ipo = NULL;
451         Ipo *oldipo;
452         ID *id;
453         
454         oldipo = self->seq->ipo;
455         
456         /* if parameter is not None, check for valid Ipo */
457
458         if ( value != Py_None ) {
459                 if ( !BPy_Ipo_Check( value ) )
460                         return EXPP_ReturnIntError( PyExc_TypeError,
461                                         "expected an Ipo object" );
462
463                 ipo = Ipo_FromPyObject( value );
464
465                 if( !ipo )
466                         return EXPP_ReturnIntError( PyExc_RuntimeError,
467                                         "null ipo!" );
468
469                 if( ipo->blocktype != ID_SEQ )
470                         return EXPP_ReturnIntError( PyExc_TypeError,
471                                         "Ipo is not a sequence data Ipo" );
472         }
473
474         /* if already linked to Ipo, delete link */
475
476         if ( oldipo ) {
477                 id = &oldipo->id;
478                 if( id->us > 0 )
479                         id->us--;
480         }
481
482         /* assign new Ipo and increment user count, or set to NULL if deleting */
483
484         self->seq->ipo = ipo;
485         if ( ipo )
486                 id_us_plus(&ipo->id);
487
488         return 0;
489 }
490
491 static PyObject *Sequence_getScene( BPy_Sequence * self )
492 {
493         struct Scene *scene;
494         
495         scene = self->seq->scene;
496
497         if( scene )
498                 return Scene_CreatePyObject( scene );
499         Py_RETURN_NONE;
500 }
501
502
503 static PyObject *Sequence_getImages( BPy_Sequence * self )
504 {
505         Strip *strip;
506         StripElem *se;
507         int i;
508         PyObject *list, *ret;
509         
510         if (self->seq->type != SEQ_IMAGE) {
511                 list = PyList_New(0);
512                 ret= Py_BuildValue( "sO", "", list);
513                 Py_DECREF(list);
514                 return ret;
515         }
516         
517                         /*return EXPP_ReturnPyObjError( PyExc_TypeError,
518                                         "Sequence is not an image type" );*/
519         
520         
521         strip = self->seq->strip;
522         se = strip->stripdata;
523         list = PyList_New(strip->len);
524         
525         for (i=0; i<strip->len; i++, se++) {
526                 PyList_SetItem( list, i, PyString_FromString(se->name) );
527         }
528         
529         ret= Py_BuildValue( "sO", strip->dir, list);
530         Py_DECREF(list);
531         return ret;
532 }
533
534
535
536 /*
537  * get floating point attributes
538  */
539 static PyObject *getIntAttr( BPy_Sequence *self, void *type )
540 {
541         int param;
542         struct Sequence *seq= self->seq;
543         
544         /*printf("%i %i %i %i %i %i %i %i %i\n", seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->startdisp, seq->enddisp, seq->depth );*/
545         switch( (int)type ) {
546         case EXPP_SEQ_ATTR_TYPE: 
547                 param = seq->type;
548                 break;
549         case EXPP_SEQ_ATTR_CHAN:
550                 param = seq->machine;
551                 break;
552         case EXPP_SEQ_ATTR_LENGTH:
553                 param = seq->len;
554                 break;
555         case EXPP_SEQ_ATTR_START:
556                 param = seq->start;
557                 break;
558         case EXPP_SEQ_ATTR_STARTOFS:
559                 param = seq->startofs;
560                 break;
561         case EXPP_SEQ_ATTR_ENDOFS:
562                 param = seq->endofs;
563                 break;
564         case EXPP_SEQ_ATTR_STARTSTILL:
565                 param = seq->startstill;
566                 break;
567         case EXPP_SEQ_ATTR_ENDSTILL:
568                 param = seq->endstill;
569                 break;
570         default:
571                 return EXPP_ReturnPyObjError( PyExc_RuntimeError, 
572                                 "undefined type in getFloatAttr" );
573         }
574
575         return PyInt_FromLong( param );
576 }
577
578 /* internal functions for recursivly updating metastrip locatons */
579 static void intern_pos_update(Sequence * seq) {
580         /* update startdisp and enddisp */
581         calc_sequence_disp(seq);
582 }
583
584 void intern_recursive_pos_update(Sequence * seq, int offset) {
585         Sequence *iterseq;
586         intern_pos_update(seq);
587         if (seq->type != SEQ_META) return;
588         
589         for (iterseq = seq->seqbase.first; iterseq; iterseq= iterseq->next) {
590                 iterseq->start -= offset;
591                 intern_recursive_pos_update(iterseq, offset);
592         }
593 }
594
595
596 static int setIntAttrClamp( BPy_Sequence *self, PyObject *value, void *type )
597 {
598         struct Sequence *seq= self->seq;
599         int number, origval=0;
600
601         if( !PyInt_Check( value ) )
602                 return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
603         
604         number = PyInt_AS_LONG( value );
605                 
606         switch( (int)type ) {
607         case EXPP_SEQ_ATTR_CHAN:
608                 CLAMP(number, 1, 1024);
609                 seq->machine = number;
610                 break;
611         case EXPP_SEQ_ATTR_START:
612                 if (self->seq->type == SEQ_EFFECT)
613                         return EXPP_ReturnIntError( PyExc_RuntimeError,
614                                 "cannot set the location of an effect directly" );
615                 CLAMP(number, -MAXFRAME, MAXFRAME);
616                 origval = seq->start;
617                 seq->start = number;
618                 break;
619         
620         case EXPP_SEQ_ATTR_STARTOFS:
621                 if (self->seq->type == SEQ_EFFECT)
622                         return EXPP_ReturnIntError( PyExc_RuntimeError,
623                                 "This property dosnt apply to an effect" );
624                 CLAMP(number, 0, seq->len - seq->endofs);
625                 seq->startofs = number;
626                 break;
627         case EXPP_SEQ_ATTR_ENDOFS:
628                 if (self->seq->type == SEQ_EFFECT)
629                         return EXPP_ReturnIntError( PyExc_RuntimeError,
630                                 "This property dosnt apply to an effect" );
631                 CLAMP(number, 0, seq->len - seq->startofs);
632                 seq->endofs = number;
633                 break;
634         case EXPP_SEQ_ATTR_STARTSTILL:
635                 if (self->seq->type == SEQ_EFFECT)
636                         return EXPP_ReturnIntError( PyExc_RuntimeError,
637                                 "This property dosnt apply to an effect" );
638                 CLAMP(number, 1, MAXFRAME);
639                 seq->startstill = number;
640                 break;
641         case EXPP_SEQ_ATTR_ENDSTILL:
642                 if (self->seq->type == SEQ_EFFECT)
643                         return EXPP_ReturnIntError( PyExc_RuntimeError,
644                                 "This property dosnt apply to an effect" );
645                 CLAMP(number, seq->startstill+1, MAXFRAME);
646                 seq->endstill = number;
647                 break;
648         case EXPP_SEQ_ATTR_LENGTH:
649                 if (self->seq->type == SEQ_EFFECT)
650                         return EXPP_ReturnIntError( PyExc_RuntimeError,
651                                 "cannot set the length of an effect directly" );
652                 CLAMP(number, 1, MAXFRAME);
653                 origval = seq->len;
654                 seq->start = number;
655                 break;
656         default:
657                 return EXPP_ReturnIntError( PyExc_RuntimeError,
658                                 "undefined type in setFloatAttrClamp" );
659         }
660         
661         intern_pos_update(seq);
662         
663         if ((int)type == EXPP_SEQ_ATTR_START && number != origval )
664                 intern_recursive_pos_update(seq, origval - seq->start);
665         
666         return 0;
667 }
668
669
670 static PyObject *getFlagAttr( BPy_Sequence *self, void *type )
671 {
672         if (self->seq->flag & (int)type)
673                 Py_RETURN_TRUE;
674         else
675                 Py_RETURN_FALSE;
676 }
677
678
679 /*
680  * set floating point attributes which require clamping
681  */
682
683 static int setFlagAttr( BPy_Sequence *self, PyObject *value, void *type )
684 {
685         int t = (int)type;
686         int param = PyObject_IsTrue( value );
687         
688         if( param == -1 )
689                 return EXPP_ReturnIntError( PyExc_TypeError,
690                                 "expected True/False or 0/1" );
691         
692         if (param)
693                 self->seq->flag |= t;
694         else {
695                 /* dont allow leftsel and rightsel when its not selected */
696                 if (t == SELECT)
697                         t = t + SEQ_LEFTSEL + SEQ_RIGHTSEL;
698                 
699                 self->seq->flag &= ~t;
700         }
701         return 0;
702 }
703
704
705 /*****************************************************************************/
706 /* Python attributes get/set structure:                                      */
707 /*****************************************************************************/
708 static PyGetSetDef BPy_Sequence_getseters[] = {
709         {"name",
710          (getter)Sequence_getName, (setter)Sequence_setName,
711          "Sequence name",
712           NULL},
713         {"ipo",
714          (getter)Sequence_getIpo, (setter)Sequence_setIpo,
715          "Sequence ipo",
716           NULL},
717
718         {"scene",
719          (getter)Sequence_getScene, (setter)NULL,
720          "Sequence scene",
721           NULL},
722         {"sound",
723          (getter)Sequence_getSound, (setter)NULL,
724          "Sequence name",
725           NULL},
726         {"images",
727          (getter)Sequence_getImages, (setter)NULL,
728          "Sequence scene",
729           NULL},
730           
731         {"type",
732          (getter)getIntAttr, (setter)NULL,
733          "",
734          (void *) EXPP_SEQ_ATTR_TYPE},
735         {"channel",
736          (getter)getIntAttr, (setter)setIntAttrClamp,
737          "",
738          (void *) EXPP_SEQ_ATTR_CHAN},
739          
740         {"length",
741          (getter)getIntAttr, (setter)setIntAttrClamp,
742          "",
743          (void *) EXPP_SEQ_ATTR_LENGTH},
744         {"start",
745          (getter)getIntAttr, (setter)setIntAttrClamp,
746          "",
747          (void *) EXPP_SEQ_ATTR_START},
748         {"startOffset",
749          (getter)getIntAttr, (setter)setIntAttrClamp,
750          "",
751          (void *) EXPP_SEQ_ATTR_STARTOFS},
752         {"endOffset",
753          (getter)getIntAttr, (setter)setIntAttrClamp,
754          "",
755          (void *) EXPP_SEQ_ATTR_ENDOFS},
756         {"startStill",
757          (getter)getIntAttr, (setter)setIntAttrClamp,
758          "",
759          (void *) EXPP_SEQ_ATTR_STARTSTILL},
760         {"endStill",
761          (getter)getIntAttr, (setter)setIntAttrClamp,
762          "",
763          (void *) EXPP_SEQ_ATTR_ENDSTILL},
764          
765         {"sel",
766          (getter)getFlagAttr, (setter)setFlagAttr,
767          "Sequence audio mute option",
768          (void *)SELECT},
769         {"selLeft",
770          (getter)getFlagAttr, (setter)setFlagAttr,
771          "",
772          (void *)SEQ_LEFTSEL},
773         {"selRight",
774          (getter)getFlagAttr, (setter)setFlagAttr,
775          "",
776          (void *)SEQ_RIGHTSEL},
777         {"filtery",
778          (getter)getFlagAttr, (setter)setFlagAttr,
779          "",
780          (void *)SEQ_FILTERY},
781         {"mute",
782          (getter)getFlagAttr, (setter)setFlagAttr,
783          "",
784          (void *)SEQ_MUTE},
785         {"premul",
786          (getter)getFlagAttr, (setter)setFlagAttr,
787          "",
788          (void *)SEQ_MAKE_PREMUL},
789         {"reversed",
790          (getter)getFlagAttr, (setter)setFlagAttr,
791          "",
792          (void *)SEQ_REVERSE_FRAMES},
793         {"ipoLocked",
794          (getter)getFlagAttr, (setter)setFlagAttr,
795          "",
796          (void *)SEQ_IPO_FRAME_LOCKED},
797         {"ipoLocked",
798          (getter)getFlagAttr, (setter)setFlagAttr,
799          "",
800          (void *)SEQ_IPO_FRAME_LOCKED},
801          
802         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
803 };
804
805 /*****************************************************************************/
806 /* Python attributes get/set structure:                                      */
807 /*****************************************************************************/
808 static PyGetSetDef BPy_SceneSeq_getseters[] = {
809         {"active",
810          (getter)SceneSeq_getActive, (setter)NULL,
811          "the active strip",
812           NULL},
813         {"metastrip",
814          (getter)SceneSeq_getMetaStrip, (setter)NULL,
815          "The currently active metastrip the user is editing",
816           NULL},
817         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
818 };
819
820 /*****************************************************************************/
821 /* Python TypeSequence structure definition:                                 */
822 /*****************************************************************************/
823 PyTypeObject Sequence_Type = {
824         PyObject_HEAD_INIT( NULL )  /* required py macro */
825         0,                          /* ob_size */
826         /*  For printing, in format "<module>.<name>" */
827         "Blender Sequence",             /* char *tp_name; */
828         sizeof( BPy_Sequence ),         /* int tp_basicsize; */
829         0,                          /* tp_itemsize;  For allocation */
830
831         /* Methods to implement standard operations */
832
833         NULL,/* destructor tp_dealloc; */
834         NULL,                       /* printfunc tp_print; */
835         NULL,                       /* getattrfunc tp_getattr; */
836         NULL,                       /* setattrfunc tp_setattr; */
837         ( cmpfunc ) Sequence_compare,   /* cmpfunc tp_compare; */
838         ( reprfunc ) Sequence_repr,     /* reprfunc tp_repr; */
839
840         /* Method suites for standard classes */
841
842         NULL,                       /* PyNumberMethods *tp_as_number; */
843         NULL,                       /* PySequenceMethods *tp_as_sequence; */
844         NULL,                       /* PyMappingMethods *tp_as_mapping; */
845
846         /* More standard operations (here for binary compatibility) */
847
848         NULL,                       /* hashfunc tp_hash; */
849         NULL,                       /* ternaryfunc tp_call; */
850         NULL,                       /* reprfunc tp_str; */
851         NULL,                       /* getattrofunc tp_getattro; */
852         NULL,                       /* setattrofunc tp_setattro; */
853
854         /* Functions to access object as input/output buffer */
855         NULL,                       /* PyBufferProcs *tp_as_buffer; */
856
857   /*** Flags to define presence of optional/expanded features ***/
858         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
859
860         NULL,                       /*  char *tp_doc;  Documentation string */
861   /*** Assigned meaning in release 2.0 ***/
862         /* call function for all accessible objects */
863         NULL,                       /* traverseproc tp_traverse; */
864
865         /* delete references to contained objects */
866         NULL,                       /* inquiry tp_clear; */
867
868   /***  Assigned meaning in release 2.1 ***/
869   /*** rich comparisons ***/
870         NULL,                       /* richcmpfunc tp_richcompare; */
871
872   /***  weak reference enabler ***/
873         0,                          /* long tp_weaklistoffset; */
874
875   /*** Added in release 2.2 ***/
876         /*   Iterators */
877         ( getiterfunc ) Sequence_getIter,           /* getiterfunc tp_iter; */
878         ( iternextfunc ) Sequence_nextIter,           /* iternextfunc tp_iternext; */
879
880   /*** Attribute descriptor and subclassing stuff ***/
881         BPy_Sequence_methods,           /* struct PyMethodDef *tp_methods; */
882         NULL,                       /* struct PyMemberDef *tp_members; */
883         BPy_Sequence_getseters,         /* struct PyGetSetDef *tp_getset; */
884         NULL,                       /* struct _typeobject *tp_base; */
885         NULL,                       /* PyObject *tp_dict; */
886         NULL,                       /* descrgetfunc tp_descr_get; */
887         NULL,                       /* descrsetfunc tp_descr_set; */
888         0,                          /* long tp_dictoffset; */
889         NULL,                       /* initproc tp_init; */
890         NULL,                       /* allocfunc tp_alloc; */
891         NULL,                       /* newfunc tp_new; */
892         /*  Low-level free-memory routine */
893         NULL,                       /* freefunc tp_free;  */
894         /* For PyObject_IS_GC */
895         NULL,                       /* inquiry tp_is_gc;  */
896         NULL,                       /* PyObject *tp_bases; */
897         /* method resolution order */
898         NULL,                       /* PyObject *tp_mro;  */
899         NULL,                       /* PyObject *tp_cache; */
900         NULL,                       /* PyObject *tp_subclasses; */
901         NULL,                       /* PyObject *tp_weaklist; */
902         NULL
903 };
904
905
906
907 /*****************************************************************************/
908 /* Python TypeSequence structure definition:                                 */
909 /*****************************************************************************/
910 PyTypeObject SceneSeq_Type = {
911         PyObject_HEAD_INIT( NULL )  /* required py macro */
912         0,                          /* ob_size */
913         /*  For printing, in format "<module>.<name>" */
914         "Blender SceneSeq",             /* char *tp_name; */
915         sizeof( BPy_Sequence ),         /* int tp_basicsize; */
916         0,                          /* tp_itemsize;  For allocation */
917
918         /* Methods to implement standard operations */
919
920         NULL,/* destructor tp_dealloc; */
921         NULL,                       /* printfunc tp_print; */
922         NULL,                       /* getattrfunc tp_getattr; */
923         NULL,                       /* setattrfunc tp_setattr; */
924         ( cmpfunc ) SceneSeq_compare,   /* cmpfunc tp_compare; */
925         ( reprfunc ) SceneSeq_repr,     /* reprfunc tp_repr; */
926
927         /* Method suites for standard classes */
928
929         NULL,                       /* PyNumberMethods *tp_as_number; */
930         NULL,                       /* PySequenceMethods *tp_as_sequence; */
931         NULL,                       /* PyMappingMethods *tp_as_mapping; */
932
933         /* More standard operations (here for binary compatibility) */
934
935         NULL,                       /* hashfunc tp_hash; */
936         NULL,                       /* ternaryfunc tp_call; */
937         NULL,                       /* reprfunc tp_str; */
938         NULL,                       /* getattrofunc tp_getattro; */
939         NULL,                       /* setattrofunc tp_setattro; */
940
941         /* Functions to access object as input/output buffer */
942         NULL,                       /* PyBufferProcs *tp_as_buffer; */
943
944   /*** Flags to define presence of optional/expanded features ***/
945         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
946
947         NULL,                       /*  char *tp_doc;  Documentation string */
948   /*** Assigned meaning in release 2.0 ***/
949         /* call function for all accessible objects */
950         NULL,                       /* traverseproc tp_traverse; */
951
952         /* delete references to contained objects */
953         NULL,                       /* inquiry tp_clear; */
954
955   /***  Assigned meaning in release 2.1 ***/
956   /*** rich comparisons ***/
957         NULL,                       /* richcmpfunc tp_richcompare; */
958
959   /***  weak reference enabler ***/
960         0,                          /* long tp_weaklistoffset; */
961
962   /*** Added in release 2.2 ***/
963         /*   Iterators */
964         ( getiterfunc ) SceneSeq_getIter,           /* getiterfunc tp_iter; */
965         ( iternextfunc ) SceneSeq_nextIter,           /* iternextfunc tp_iternext; */
966
967   /*** Attribute descriptor and subclassing stuff ***/
968         BPy_SceneSeq_methods,           /* struct PyMethodDef *tp_methods; */
969         NULL,                       /* struct PyMemberDef *tp_members; */
970         BPy_SceneSeq_getseters,         /* struct PyGetSetDef *tp_getset; */
971         NULL,                       /* struct _typeobject *tp_base; */
972         NULL,                       /* PyObject *tp_dict; */
973         NULL,                       /* descrgetfunc tp_descr_get; */
974         NULL,                       /* descrsetfunc tp_descr_set; */
975         0,                          /* long tp_dictoffset; */
976         NULL,                       /* initproc tp_init; */
977         NULL,                       /* allocfunc tp_alloc; */
978         NULL,                       /* newfunc tp_new; */
979         /*  Low-level free-memory routine */
980         NULL,                       /* freefunc tp_free;  */
981         /* For PyObject_IS_GC */
982         NULL,                       /* inquiry tp_is_gc;  */
983         NULL,                       /* PyObject *tp_bases; */
984         /* method resolution order */
985         NULL,                       /* PyObject *tp_mro;  */
986         NULL,                       /* PyObject *tp_cache; */
987         NULL,                       /* PyObject *tp_subclasses; */
988         NULL,                       /* PyObject *tp_weaklist; */
989         NULL
990 };
991
992
993 /*****************************************************************************/
994 /* Function:      M_Sequence_Get                                                */
995 /* Python equivalent:     Blender.Sequence.Get                          */
996 /*****************************************************************************/
997 /*
998 PyObject *M_Sequence_Get( PyObject * self, PyObject * args )
999 {
1000         return SceneSeq_CreatePyObject( G.scene, NULL );
1001 }
1002 */
1003
1004 /*****************************************************************************/
1005 /* Function:     initObject                                             */
1006 /*****************************************************************************/
1007 PyObject *Sequence_Init( void )
1008 {
1009         PyObject *submodule;
1010         if( PyType_Ready( &Sequence_Type ) < 0 )
1011                 return NULL;
1012         if( PyType_Ready( &SceneSeq_Type ) < 0 )
1013                 return NULL;
1014         
1015         /* NULL was M_Sequence_methods*/
1016         submodule = Py_InitModule3( "Blender.Scene.Sequence", NULL,
1017 "The Blender Sequence module\n\n\
1018 This module provides access to **Sequence Data** in Blender.\n" );
1019
1020         /*Add SUBMODULES to the module*/
1021         /*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
1022         return submodule;
1023 }
1024
1025
1026 /*****************************************************************************/
1027 /* Function:    Sequence_CreatePyObject                                  */
1028 /* Description: This function will create a new BlenObject from an existing  */
1029 /*              Object structure.                                        */
1030 /*****************************************************************************/
1031 PyObject *Sequence_CreatePyObject( struct Sequence * seq, struct Sequence * iter, struct Scene *sce)
1032 {
1033         BPy_Sequence *pyseq;
1034
1035         if( !seq )
1036                 Py_RETURN_NONE;
1037
1038         pyseq =
1039                 ( BPy_Sequence * ) PyObject_NEW( BPy_Sequence, &Sequence_Type );
1040
1041         if( pyseq == NULL ) {
1042                 return ( NULL );
1043         }
1044         pyseq->seq = seq;
1045         pyseq->iter = iter;
1046         pyseq->scene = sce;
1047         
1048         return ( ( PyObject * ) pyseq );
1049 }
1050
1051 /*****************************************************************************/
1052 /* Function:    SceneSeq_CreatePyObject                                  */
1053 /* Description: This function will create a new BlenObject from an existing  */
1054 /*              Object structure.                                        */
1055 /*****************************************************************************/
1056 PyObject *SceneSeq_CreatePyObject( struct Scene * scn, struct Sequence * iter)
1057 {
1058         BPy_SceneSeq *pysceseq;
1059
1060         if( !scn )
1061                 Py_RETURN_NONE;
1062
1063         pysceseq =
1064                 ( BPy_SceneSeq * ) PyObject_NEW( BPy_SceneSeq, &SceneSeq_Type );
1065
1066         if( pysceseq == NULL ) {
1067                 return ( NULL );
1068         }
1069         pysceseq->scene = scn;
1070         pysceseq->iter = iter;
1071         
1072         return ( ( PyObject * ) pysceseq );
1073 }
1074
1075 /*****************************************************************************/
1076 /* Function:    Sequence_FromPyObject                                    */
1077 /* Description: This function returns the Blender sequence from the given        */
1078 /*              PyObject.                                                */
1079 /*****************************************************************************/
1080 struct Sequence *Sequence_FromPyObject( PyObject * py_seq )
1081 {
1082         BPy_Sequence *blen_seq;
1083
1084         blen_seq = ( BPy_Sequence * ) py_seq;
1085         return ( blen_seq->seq );
1086 }
1087
1088 /*****************************************************************************/
1089 /* Function:    Sequence_compare                                                 */
1090 /* Description: This is a callback function for the BPy_Sequence type. It        */
1091 /*              compares two Sequence_Type objects. Only the "==" and "!="  */
1092 /*              comparisons are meaninful. Returns 0 for equality and -1 if  */
1093 /*              they don't point to the same Blender Object struct.      */
1094 /*              In Python it becomes 1 if they are equal, 0 otherwise.   */
1095 /*****************************************************************************/
1096 static int Sequence_compare( BPy_Sequence * a, BPy_Sequence * b )
1097 {
1098         Sequence *pa = a->seq, *pb = b->seq;
1099         return ( pa == pb ) ? 0 : -1;
1100 }
1101
1102 static int SceneSeq_compare( BPy_SceneSeq * a, BPy_SceneSeq * b )
1103 {
1104         
1105         Scene *pa = a->scene, *pb = b->scene;
1106         return ( pa == pb ) ? 0 : -1;
1107 }
1108
1109 /*****************************************************************************/
1110 /* Function:    Sequence_repr / SceneSeq_repr                                            */
1111 /* Description: This is a callback function for the BPy_Sequence type. It        */
1112 /*              builds a meaninful string to represent object objects.   */
1113 /*****************************************************************************/
1114 static PyObject *Sequence_repr( BPy_Sequence * self )
1115 {
1116         return PyString_FromFormat( "[Sequence Strip \"%s\"]",
1117                                         self->seq->name + 2 );
1118 }
1119 static PyObject *SceneSeq_repr( BPy_SceneSeq * self )
1120 {
1121         return PyString_FromFormat( "[Scene Sequence \"%s\"]",
1122                                 self->scene->id.name + 2 );
1123 }
1124