This commit fixes two related issues:
[blender.git] / source / blender / src / editseq.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdlib.h>
34 #include <math.h>
35 #include <string.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #ifndef WIN32
42 #include <unistd.h>
43 #else
44 #include <io.h>
45 #endif
46 #include <sys/types.h>
47
48 #include "MEM_guardedalloc.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
52 #include "BLI_storage_types.h"
53
54 #include "IMB_imbuf_types.h"
55 #include "IMB_imbuf.h"
56
57 #include "DNA_ipo_types.h"
58 #include "DNA_scene_types.h"
59 #include "DNA_screen_types.h"
60 #include "DNA_space_types.h"
61 #include "DNA_sequence_types.h"
62 #include "DNA_view2d_types.h"
63 #include "DNA_userdef_types.h"
64 #include "DNA_sound_types.h"
65
66 #include "BKE_utildefines.h"
67 #include "BKE_plugin_types.h"
68 #include "BKE_global.h"
69 #include "BKE_image.h"
70 #include "BKE_library.h"
71 #include "BKE_main.h"
72 #include "BKE_scene.h"
73
74 #include "BIF_space.h"
75 #include "BIF_interface.h"
76 #include "BIF_screen.h"
77 #include "BIF_drawseq.h"
78 #include "BIF_editseq.h"
79 #include "BIF_mywindow.h"
80 #include "BIF_toolbox.h"
81 #include "BIF_writemovie.h"
82 #include "BIF_editview.h"
83 #include "BIF_scrarea.h"
84 #include "BIF_editsound.h"
85
86 #include "BSE_edit.h"
87 #include "BSE_sequence.h"
88 #include "BSE_filesel.h"
89 #include "BSE_drawipo.h"
90 #include "BSE_seqaudio.h"
91
92 #include "BDR_editobject.h"
93
94 #include "blendef.h"
95 #include "mydevice.h"
96
97 Sequence *last_seq=0;
98 char last_imagename[FILE_MAXDIR+FILE_MAXFILE]= "/";
99 char last_sounddir[FILE_MAXDIR+FILE_MAXFILE]= "";
100
101 #define SEQ_DESEL       ~(SELECT+SEQ_LEFTSEL+SEQ_RIGHTSEL)
102
103 static int test_overlap_seq(Sequence *);
104 static void shuffle_seq(Sequence *);
105
106 static void change_plugin_seq(char *str)        /* called from fileselect */
107 {
108 /*      extern Sequence *last_seq; already done few lines before !!!*/
109
110         if(last_seq && last_seq->type!=SEQ_PLUGIN) return;
111
112         free_plugin_seq(last_seq->plugin);
113
114         last_seq->plugin= (PluginSeq *)add_plugin_seq(str, last_seq->name+2);
115
116         last_seq->machine= MAX3(last_seq->seq1->machine, last_seq->seq2->machine, last_seq->seq3->machine);
117         if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq);
118         
119         BIF_undo_push("Load/change Sequencer plugin");
120 }
121
122
123 void boundbox_seq(void)
124 {
125         Sequence *seq;
126         Editing *ed;
127         float min[2], max[2];
128
129         ed= G.scene->ed;
130         if(ed==0) return;
131
132         min[0]= 0.0;
133         max[0]= EFRA+1;
134         min[1]= 0.0;
135         max[1]= 8.0;
136
137         seq= ed->seqbasep->first;
138         while(seq) {
139
140                 if( min[0] > seq->startdisp-1) min[0]= seq->startdisp-1;
141                 if( max[0] < seq->enddisp+1) max[0]= seq->enddisp+1;
142                 if( max[1] < seq->machine+2.0) max[1]= seq->machine+2.0;
143
144                 seq= seq->next;
145         }
146
147         G.v2d->tot.xmin= min[0];
148         G.v2d->tot.xmax= max[0];
149         G.v2d->tot.ymin= min[1];
150         G.v2d->tot.ymax= max[1];
151
152 }
153
154 Sequence *find_nearest_seq(int *hand)
155 {
156         Sequence *seq;
157         Editing *ed;
158         float x, y, facx, facy;
159         short mval[2];
160
161         *hand= 0;
162
163         ed= G.scene->ed;
164         if(ed==0) return 0;
165
166         getmouseco_areawin(mval);
167         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
168
169         seq= ed->seqbasep->first;
170         while(seq) {
171                 if(seq->machine == (int)y) {
172                         if(seq->startdisp<=x && seq->enddisp>=x) {
173
174                                 if(seq->type < SEQ_EFFECT) {
175                                         if( seq->handsize+seq->startdisp >=x ) {
176                                                 /* within triangle? */
177                                                 facx= (x-seq->startdisp)/seq->handsize;
178                                                 if( (y - (int)y) <0.5) {
179                                                         facy= (y - 0.2 - (int)y)/0.3;
180                                                         if( facx < facy ) *hand= 1;
181                                                 }
182                                                 else {
183                                                         facy= (y - 0.5 - (int)y)/0.3;
184                                                         if( facx+facy < 1.0 ) *hand= 1;
185                                                 }
186
187                                         }
188                                         else if( -seq->handsize+seq->enddisp <=x ) {
189                                                 /* within triangle? */
190                                                 facx= 1.0 - (seq->enddisp-x)/seq->handsize;
191                                                 if( (y - (int)y) <0.5) {
192                                                         facy= (y - 0.2 - (int)y)/0.3;
193                                                         if( facx+facy > 1.0 ) *hand= 2;
194                                                 }
195                                                 else {
196                                                         facy= (y - 0.5 - (int)y)/0.3;
197                                                         if( facx > facy ) *hand= 2;
198                                                 }
199                                         }
200                                 }
201
202                                 return seq;
203                         }
204                 }
205                 seq= seq->next;
206         }
207         return 0;
208 }
209
210 void clear_last_seq(void)
211 {
212         /* from (example) ipo: when it is changed, also do effects with same ipo */
213         Sequence *seq;
214         Editing *ed;
215         StripElem *se;
216         int a;
217
218         if(last_seq) {
219
220                 ed= G.scene->ed;
221                 if(ed==0) return;
222
223                 WHILE_SEQ(&ed->seqbase) {
224                         if(seq==last_seq || (last_seq->ipo && seq->ipo==last_seq->ipo)) {
225                                 a= seq->len;
226                                 se= seq->strip->stripdata;
227                                 if(se) {
228                                         while(a--) {
229                                                 if(se->ibuf) IMB_freeImBuf(se->ibuf);
230                                                 se->ibuf= 0;
231                                                 se->ok= 1;
232                                                 se++;
233                                         }
234                                 }
235                         }
236                 }
237                 END_SEQ
238         }
239 }
240
241 static int test_overlap_seq(Sequence *test)
242 {
243         Sequence *seq;
244         Editing *ed;
245
246         ed= G.scene->ed;
247         if(ed==0) return 0;
248
249         seq= ed->seqbasep->first;
250         while(seq) {
251                 if(seq!=test) {
252                         if(test->machine==seq->machine) {
253                                 if(test->depth==seq->depth) {
254                                         if( (test->enddisp <= seq->startdisp) || (test->startdisp >= seq->enddisp) );
255                                         else return 1;
256                                 }
257                         }
258                 }
259                 seq= seq->next;
260         }
261         return 0;
262 }
263
264 static void shuffle_seq(Sequence *test)
265 {
266         Editing *ed;
267         Sequence *seq;
268         int a, start;
269
270         ed= G.scene->ed;
271         if(ed==0) return;
272
273         /* is there more than 1 select: only shuffle y */
274         a=0;
275         seq= ed->seqbasep->first;
276         while(seq) {
277                 if(seq->flag & SELECT) a++;
278                 seq= seq->next;
279         }
280
281         if(a<2 && test->type==SEQ_IMAGE) {
282                 start= test->start;
283
284                 for(a= 1; a<50; a++) {
285                         test->start= start+a;
286                         calc_sequence(test);
287                         if( test_overlap_seq(test)==0) return;
288                         test->start= start-a;
289                         calc_sequence(test);
290                         if( test_overlap_seq(test)==0) return;
291                 }
292                 test->start= start;
293         }
294
295         test->machine++;
296         calc_sequence(test);
297         while( test_overlap_seq(test) ) {
298                 if(test->machine >= MAXSEQ) {
299                         error("There is no more space to add a sequence strip");
300
301                         BLI_remlink(ed->seqbasep, test);
302                         free_sequence(test);
303                         return;
304                 }
305                 test->machine++;
306                 calc_sequence(test);
307         }
308 }
309
310 static void deselect_all_seq(void)
311 {
312         Sequence *seq;
313         Editing *ed;
314
315         ed= G.scene->ed;
316         if(ed==0) return;
317
318         WHILE_SEQ(ed->seqbasep) {
319                 seq->flag &= SEQ_DESEL;
320         }
321         END_SEQ
322                 
323         BIF_undo_push("(De)select all Sequencer");
324 }
325
326 static void recurs_sel_seq(Sequence *seqm)
327 {
328         Sequence *seq;
329
330         seq= seqm->seqbase.first;
331         while(seq) {
332
333                 if(seqm->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL)) seq->flag &= SEQ_DESEL;
334                 else if(seqm->flag & SELECT) seq->flag |= SELECT;
335                 else seq->flag &= SEQ_DESEL;
336
337                 if(seq->seqbase.first) recurs_sel_seq(seq);
338
339                 seq= seq->next;
340         }
341 }
342
343 void swap_select_seq(void)
344 {
345         Sequence *seq;
346         Editing *ed;
347         int sel=0;
348
349         ed= G.scene->ed;
350         if(ed==0) return;
351
352         WHILE_SEQ(ed->seqbasep) {
353                 if(seq->flag & SELECT) sel= 1;
354         }
355         END_SEQ
356
357         WHILE_SEQ(ed->seqbasep) {
358                 /* always deselect all to be sure */
359                 seq->flag &= SEQ_DESEL;
360                 if(sel==0) seq->flag |= SELECT;
361         }
362         END_SEQ
363
364         allqueue(REDRAWSEQ, 0);
365         BIF_undo_push("Swap select all Sequencer");
366
367 }
368
369 void mouse_select_seq(void)
370 {
371         Sequence *seq;
372         int hand;
373
374         seq= find_nearest_seq(&hand);
375
376         if(G.qual==0) deselect_all_seq();
377
378         if(seq) {
379                 last_seq= seq;
380
381                 if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
382                         if(seq->strip) {
383                                 strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
384                         }
385                 } else
386                 if (seq->type == SEQ_SOUND) {
387                         if(seq->strip) {
388                                 strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
389                         }
390                 }
391
392                 if(G.qual==0) {
393                         seq->flag |= SELECT;
394                         if(hand==1) seq->flag |= SEQ_LEFTSEL;
395                         if(hand==2) seq->flag |= SEQ_RIGHTSEL;
396                 }
397                 else {
398                         if(seq->flag & SELECT) {
399                                 if(hand==0) seq->flag &= SEQ_DESEL;
400                                 else if(hand==1) {
401                                         if(seq->flag & SEQ_LEFTSEL) seq->flag &= ~SEQ_LEFTSEL;
402                                         else seq->flag |= SEQ_LEFTSEL;
403                                 }
404                                 else if(hand==2) {
405                                         if(seq->flag & SEQ_RIGHTSEL) seq->flag &= ~SEQ_RIGHTSEL;
406                                         else seq->flag |= SEQ_RIGHTSEL;
407                                 }
408                         }
409                         else {
410                                 seq->flag |= SELECT;
411                                 if(hand==1) seq->flag |= SEQ_LEFTSEL;
412                                 if(hand==2) seq->flag |= SEQ_RIGHTSEL;
413                         }
414                 }
415                 recurs_sel_seq(seq);
416         }
417
418         force_draw(0);
419
420         if(last_seq) allqueue(REDRAWIPO, 0);
421         BIF_undo_push("Select Sequencer");
422
423         std_rmouse_transform(transform_seq);
424 }
425
426 static Sequence *alloc_sequence(int cfra, int machine)
427 {
428         Editing *ed;
429         Sequence *seq;
430
431         ed= G.scene->ed;
432
433         seq= MEM_callocN( sizeof(Sequence), "addseq");
434         BLI_addtail(ed->seqbasep, seq);
435
436         last_seq= seq;
437
438         *( (short *)seq->name )= ID_SEQ;
439         seq->name[2]= 0;
440
441         seq->flag= SELECT;
442         seq->start= cfra;
443         seq->machine= machine;
444         seq->mul= 1.0;
445         
446         return seq;
447 }
448
449 static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int last)
450 {
451         Sequence *seq;
452         Strip *strip;
453         StripElem *se;
454         int totsel, a;
455         char name[160], rel[160];
456
457         /* are there selected files? */
458         totsel= 0;
459         for(a=0; a<sfile->totfile; a++) {
460                 if(sfile->filelist[a].flags & ACTIVE) {
461                         if( (sfile->filelist[a].type & S_IFDIR)==0 ) {
462                                 totsel++;
463                         }
464                 }
465         }
466
467         if(last) {
468                 /* if not, a file handed to us? */
469                 if(totsel==0 && sfile->file[0]) totsel= 1;
470         }
471
472         if(totsel==0) return 0;
473
474         /* make seq */
475         seq= alloc_sequence(cfra, machine);
476         seq->len= totsel;
477
478         if(totsel==1) {
479                 seq->startstill= 25;
480                 seq->endstill= 24;
481         }
482
483         calc_sequence(seq);
484         
485         if(sfile->flag & FILE_STRINGCODE) {
486                 strcpy(name, sfile->dir);
487                 strcpy(rel, G.sce);
488                 BLI_makestringcode(rel, name);
489         } else {
490                 strcpy(name, sfile->dir);
491         }
492
493         /* strip and stripdata */
494         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
495         strip->len= totsel;
496         strip->us= 1;
497         strncpy(strip->dir, name, FILE_MAXDIR-1);
498         strip->stripdata= se= MEM_callocN(totsel*sizeof(StripElem), "stripelem");
499
500         for(a=0; a<sfile->totfile; a++) {
501                 if(sfile->filelist[a].flags & ACTIVE) {
502                         if( (sfile->filelist[a].type & S_IFDIR)==0 ) {
503                                 strncpy(se->name, sfile->filelist[a].relname, FILE_MAXFILE-1);
504                                 se->ok= 1;
505                                 se++;
506                         }
507                 }
508         }
509         /* no selected file: */
510         if(totsel==1 && se==strip->stripdata) {
511                 strncpy(se->name, sfile->file, FILE_MAXFILE-1);
512                 se->ok= 1;
513         }
514
515         /* last active name */
516         strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
517
518         return seq;
519 }
520
521 static void sfile_to_mv_sequence(SpaceFile *sfile, int cfra, int machine)
522 {
523         Sequence *seq;
524         struct anim *anim;
525         Strip *strip;
526         StripElem *se;
527         int totframe, a;
528         char name[160], rel[160];
529         char str[FILE_MAXDIR+FILE_MAXFILE];
530
531         totframe= 0;
532
533         strncpy(str, sfile->dir, FILE_MAXDIR-1);
534         strncat(str, sfile->file, FILE_MAXDIR-1);
535
536         /* is it a movie? */
537         anim = openanim(str, IB_rect);
538         if(anim==0) {
539                 error("The selected file is not a movie");
540                 return;
541         }
542
543         totframe= IMB_anim_get_duration(anim);
544
545         /* make seq */
546         seq= alloc_sequence(cfra, machine);
547         seq->len= totframe;
548         seq->type= SEQ_MOVIE;
549         seq->anim= anim;
550
551         calc_sequence(seq);
552         
553         if(sfile->flag & FILE_STRINGCODE) {
554                 strcpy(name, sfile->dir);
555                 strcpy(rel, G.sce);
556                 BLI_makestringcode(rel, name);
557         } else {
558                 strcpy(name, sfile->dir);
559         }
560
561         /* strip and stripdata */
562         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
563         strip->len= totframe;
564         strip->us= 1;
565         strncpy(strip->dir, name, FILE_MAXDIR-1);
566         strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
567
568         /* name movie in first strip */
569         strncpy(se->name, sfile->file, FILE_MAXFILE-1);
570
571         for(a=1; a<=totframe; a++, se++) {
572                 se->ok= 1;
573                 se->nr= a;
574         }
575
576         /* last active name */
577         strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
578 }
579
580 static Sequence *sfile_to_snd_sequence(SpaceFile *sfile, int cfra, int machine)
581 {
582         Sequence *seq;
583         bSound *sound;
584         Strip *strip;
585         StripElem *se;
586         double totframe;
587         int a;
588         char name[160], rel[160];
589         char str[256];
590
591         totframe= 0.0;
592
593         strncpy(str, sfile->dir, FILE_MAXDIR-1);
594         strncat(str, sfile->file, FILE_MAXFILE-1);
595
596         sound= sound_new_sound(str);
597         if (!sound || sound->sample->type == SAMPLE_INVALID) {
598                 error("Unsupported audio format");
599                 return 0;
600         }
601         if (sound->sample->bits != 16) {
602                 error("Only 16 bit audio is supported");
603                 return 0;
604         }
605         sound->id.us=1;
606         sound->flags |= SOUND_FLAGS_SEQUENCE;
607         audio_makestream(sound);
608
609         totframe= (int) ( ((float)(sound->streamlen-1)/( (float)G.scene->audio.mixrate*4.0 ))* (float)G.scene->r.frs_sec);
610
611         /* make seq */
612         seq= alloc_sequence(cfra, machine);
613         seq->len= totframe;
614         seq->type= SEQ_SOUND;
615         seq->sound = sound;
616
617         calc_sequence(seq);
618         
619         if(sfile->flag & FILE_STRINGCODE) {
620                 strcpy(name, sfile->dir);
621                 strcpy(rel, G.sce);
622                 BLI_makestringcode(rel, name);
623         } else {
624                 strcpy(name, sfile->dir);
625         }
626
627         /* strip and stripdata */
628         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
629         strip->len= totframe;
630         strip->us= 1;
631         strncpy(strip->dir, name, FILE_MAXDIR-1);
632         strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
633
634         /* name sound in first strip */
635         strncpy(se->name, sfile->file, FILE_MAXFILE-1);
636
637         for(a=1; a<=totframe; a++, se++) {
638                 se->ok= 2; /* why? */
639                 se->ibuf= 0;
640                 se->nr= a;
641         }
642
643         /* last active name */
644         strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
645
646         return seq;
647 }
648
649 static void add_image_strips(char *name)
650 {
651         SpaceFile *sfile;
652         struct direntry *files;
653         float x, y;
654         int a, totfile, cfra, machine;
655         short mval[2];
656
657         deselect_all_seq();
658
659         /* restore windowmatrices */
660         areawinset(curarea->win);
661         drawseqspace(curarea, curarea->spacedata.first);
662
663         /* search sfile */
664         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
665         if(sfile==0) return;
666
667         /* where will it be */
668         getmouseco_areawin(mval);
669         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
670         cfra= (int)(x+0.5);
671         machine= (int)(y+0.5);
672
673         waitcursor(1);
674
675         /* also read contents of directories */
676         files= sfile->filelist;
677         totfile= sfile->totfile;
678         sfile->filelist= 0;
679         sfile->totfile= 0;
680
681         for(a=0; a<totfile; a++) {
682                 if(files[a].flags & ACTIVE) {
683                         if( (files[a].type & S_IFDIR) ) {
684                                 strncat(sfile->dir, files[a].relname, FILE_MAXFILE-1);
685                                 strcat(sfile->dir,"/");
686                                 read_dir(sfile);
687
688                                 /* select all */
689                                 swapselect_file(sfile);
690
691                                 if ( sfile_to_sequence(sfile, cfra, machine, 0) ) machine++;
692
693                                 parent(sfile);
694                         }
695                 }
696         }
697
698         sfile->filelist= files;
699         sfile->totfile= totfile;
700
701         /* read directory itself */
702         sfile_to_sequence(sfile, cfra, machine, 1);
703
704         waitcursor(0);
705
706         BIF_undo_push("Add image strip Sequencer");
707         transform_seq('g', 0);
708
709 }
710
711 static void add_movie_strip(char *name)
712 {
713         SpaceFile *sfile;
714         float x, y;
715         int cfra, machine;
716         short mval[2];
717
718         deselect_all_seq();
719
720         /* restore windowmatrices */
721         areawinset(curarea->win);
722         drawseqspace(curarea, curarea->spacedata.first);
723
724         /* search sfile */
725         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
726         if(sfile==0) return;
727
728         /* where will it be */
729         getmouseco_areawin(mval);
730         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
731         cfra= (int)(x+0.5);
732         machine= (int)(y+0.5);
733
734         waitcursor(1);
735
736         /* read directory itself */
737         sfile_to_mv_sequence(sfile, cfra, machine);
738
739         waitcursor(0);
740
741         BIF_undo_push("Add movie strip Sequencer");
742         transform_seq('g', 0);
743
744 }
745
746 static void add_sound_strip(char *name)
747 {
748         SpaceFile *sfile;
749         float x, y;
750         int cfra, machine;
751         short mval[2];
752
753         deselect_all_seq();
754
755         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
756         if (sfile==0) return;
757
758         /* where will it be */
759         getmouseco_areawin(mval);
760         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
761         cfra= (int)(x+0.5);
762         machine= (int)(y+0.5);
763
764         waitcursor(1);
765
766         sfile_to_snd_sequence(sfile, cfra, machine);
767
768         waitcursor(0);
769
770         BIF_undo_push("Add sound strip Sequencer");
771         transform_seq('g', 0);
772 }
773
774 #if 0
775 static void reload_sound_strip(char *name)
776 {
777         Editing *ed;
778         Sequence *seq, *seqact;
779         SpaceFile *sfile;
780
781         ed= G.scene->ed;
782
783         if(last_seq==0 || last_seq->type!=SEQ_SOUND) return;
784         seqact= last_seq;       /* last_seq changes in alloc_sequence */
785
786         /* search sfile */
787         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
788         if(sfile==0) return;
789
790         waitcursor(1);
791
792         seq = sfile_to_snd_sequence(sfile, seqact->start, seqact->machine);
793         printf("seq->type: %i\n", seq->type);
794         if(seq && seq!=seqact) {
795                 /* i'm not sure about this one, seems to work without it -- sgefant */
796                 free_strip(seqact->strip);
797
798                 seqact->strip= seq->strip;
799
800                 seqact->len= seq->len;
801                 calc_sequence(seqact);
802
803                 seq->strip= 0;
804                 free_sequence(seq);
805                 BLI_remlink(ed->seqbasep, seq);
806
807                 seq= ed->seqbasep->first;
808
809         }
810
811         waitcursor(0);
812
813         allqueue(REDRAWSEQ, 0);
814 }
815 #endif
816
817 static void reload_image_strip(char *name)
818 {
819         Editing *ed;
820         Sequence *seq, *seqact;
821         SpaceFile *sfile;
822
823         ed= G.scene->ed;
824
825         if(last_seq==0 || last_seq->type!=SEQ_IMAGE) return;
826         seqact= last_seq;       /* last_seq changes in alloc_sequence */
827
828         /* search sfile */
829         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
830         if(sfile==0) return;
831
832         waitcursor(1);
833
834         seq= sfile_to_sequence(sfile, seqact->start, seqact->machine, 1);
835         if(seq && seq!=seqact) {
836                 free_strip(seqact->strip);
837
838                 seqact->strip= seq->strip;
839
840                 seqact->len= seq->len;
841                 calc_sequence(seqact);
842
843                 seq->strip= 0;
844                 free_sequence(seq);
845                 BLI_remlink(ed->seqbasep, seq);
846
847                 seq= ed->seqbasep->first;
848                 while(seq) {
849                         if(seq->type & SEQ_EFFECT) {
850                                 /* new_stripdata is clear */
851                                 if(seq->seq1==seqact || seq->seq2==seqact || seq->seq3==seqact) {
852                                         calc_sequence(seq);
853                                         new_stripdata(seq);
854                                 }
855                         }
856                         seq= seq->next;
857                 }
858         }
859         waitcursor(0);
860
861         allqueue(REDRAWSEQ, 0);
862 }
863
864 static int event_to_efftype(int event)
865 {
866         if(event==2) return SEQ_CROSS;
867         if(event==3) return SEQ_GAMCROSS;
868         if(event==4) return SEQ_ADD;
869         if(event==5) return SEQ_SUB;
870         if(event==6) return SEQ_MUL;
871         if(event==7) return SEQ_ALPHAOVER;
872         if(event==8) return SEQ_ALPHAUNDER;
873         if(event==9) return SEQ_OVERDROP;
874         if(event==10) return SEQ_PLUGIN;
875         if(event==13) return SEQ_WIPE;
876         if(event==14) return SEQ_GLOW;
877         return 0;
878 }
879
880 static int add_seq_effect(int type)
881 {
882         Editing *ed;
883         Sequence *seq, *seq1, *seq2, *seq3;
884         Strip *strip;
885         float x, y;
886         int cfra, machine;
887         short mval[2];
888
889         if(G.scene->ed==0) return 0;
890         ed= G.scene->ed;
891
892         /* apart from last_seq there have to be 2 selected sequences */
893         seq1= seq3= 0;
894         seq2= last_seq;         /* last_seq changes with alloc_seq! */
895         seq= ed->seqbasep->first;
896         while(seq) {
897                 if(seq->flag & SELECT) {
898                         if (seq->type == SEQ_SOUND) { error("Can't apply effects to audio sequence strips"); return 0; }
899                         if(seq != seq2) {
900                                 if(seq1==0) seq1= seq;
901                                 else if(seq3==0) seq3= seq;
902                                 else {
903                                         seq1= 0;
904                                         break;
905                                 }
906                         }
907                 }
908                 seq= seq->next;
909         }
910
911         if(type==10 || type==13 || type==14) {  /* plugin: minimal 1 select */
912                 if(seq2==0)  {
913                         error("Need at least one selected sequence strip");
914                         return 0;
915                 }
916                 if(seq1==0) seq1= seq2;
917                 if(seq3==0) seq3= seq2;
918         }
919         else {
920                 if(seq1==0 || seq2==0) {
921                         error("Need 2 selected sequence strips");
922                         return 0;
923                 }
924                 if(seq3==0) seq3= seq2;
925         }
926
927         deselect_all_seq();
928
929         /* where will it be (cfra is not realy needed) */
930         getmouseco_areawin(mval);
931         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
932         cfra= (int)(x+0.5);
933         machine= (int)(y+0.5);
934
935         seq= alloc_sequence(cfra, machine);
936
937         seq->type= event_to_efftype(type);
938
939         /* Allocate variable structs for effects with settings */
940         if(seq->type==SEQ_WIPE){
941                 init_wipe_effect(seq);
942         }
943         else if(seq->type==SEQ_GLOW){
944                 init_glow_effect(seq);
945         }
946
947         if(seq->type==SEQ_ALPHAUNDER || seq->type==SEQ_ALPHAOVER) {
948                 seq->seq2= seq1;
949                 seq->seq1= seq2;
950         }
951         else {
952                 seq->seq1= seq1;
953                 seq->seq2= seq2;
954         }
955         seq->seq3= seq3;
956         calc_sequence(seq);
957
958         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
959         strip->len= seq->len;
960         strip->us= 1;
961         if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
962
963         BIF_undo_push("Add effect strip Sequencer");
964
965         return 1;
966 }
967
968 static void load_plugin_seq(char *str)          /* called from fileselect */
969 {
970         Editing *ed;
971
972         add_seq_effect(10);             /* this sets last_seq */
973
974         free_plugin_seq(last_seq->plugin);
975
976         last_seq->plugin= (PluginSeq *)add_plugin_seq(str, last_seq->name+2);
977
978         if(last_seq->plugin==0) {
979                 ed= G.scene->ed;
980                 BLI_remlink(ed->seqbasep, last_seq);
981                 free_sequence(last_seq);
982                 last_seq= 0;
983         }
984         else {
985                 last_seq->machine= MAX3(last_seq->seq1->machine, last_seq->seq2->machine, last_seq->seq3->machine);
986                 if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq);
987
988                 BIF_undo_push("Add plugin strip Sequencer");
989                 transform_seq('g', 0);
990         }
991 }
992
993 void add_sequence(int type)
994 {
995         Editing *ed;
996         Sequence *seq;
997         Strip *strip;
998         Scene *sce;
999         float x, y;
1000         int cfra, machine;
1001         short nr, event, mval[2];
1002         char *str;
1003
1004         if (type >= 0){
1005                 /* bypass pupmenu for calls from menus (aphex) */
1006                 switch(type){
1007                 case SEQ_SCENE:
1008                         event = 101;
1009                         break;
1010                 case SEQ_IMAGE:
1011                         event = 1;
1012                         break;
1013                 case SEQ_MOVIE:
1014                         event = 102;
1015                         break;
1016                 case SEQ_SOUND:
1017                         event = 103;
1018                         break;
1019                 case SEQ_PLUGIN:
1020                         event = 10;
1021                         break;
1022                 case SEQ_CROSS:
1023                         event = 2;
1024                         break;
1025                 case SEQ_ADD:
1026                         event = 4;
1027                         break;
1028                 case SEQ_SUB:
1029                         event = 5;
1030                         break;
1031                 case SEQ_ALPHAOVER:
1032                         event = 7;
1033                         break;
1034                 case SEQ_ALPHAUNDER:
1035                         event = 8;
1036                         break;
1037                 case SEQ_GAMCROSS:
1038                         event = 3;
1039                         break;
1040                 case SEQ_MUL:
1041                         event = 6;
1042                         break;
1043                 case SEQ_OVERDROP:
1044                         event = 9;
1045                         break;
1046                 case SEQ_WIPE:
1047                         event = 13;
1048                         break;
1049                 case SEQ_GLOW:
1050                         event = 14;
1051                         break;
1052                 default:
1053                         event = 0;
1054                         break;
1055                 }
1056         }
1057         else {
1058                 event= pupmenu("Add Sequence Strip%t|Images%x1|Movie%x102|Audio%x103|Scene%x101|Plugin%x10|Cross%x2|Gamma Cross%x3|Add%x4|Sub%x5|Mul%x6|Alpha Over%x7|Alpha Under%x8|Alpha Over Drop%x9|Wipe%x13|Glow%x14");
1059         }
1060
1061         if(event<1) return;
1062
1063         if(G.scene->ed==0) {
1064                 ed= G.scene->ed= MEM_callocN( sizeof(Editing), "addseq");
1065                 ed->seqbasep= &ed->seqbase;
1066         }
1067         else ed= G.scene->ed;
1068
1069         switch(event) {
1070         case 1:
1071
1072                 activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
1073                 break;
1074         case 102:
1075
1076                 activate_fileselect(FILE_SPECIAL, "Select Movie", last_imagename, add_movie_strip);
1077                 break;
1078         case 101:
1079                 /* new menu: */
1080                 IDnames_to_pupstring(&str, NULL, NULL, &G.main->scene, (ID *)G.scene, NULL);
1081
1082                 event= pupmenu_col(str, 20);
1083
1084                 if(event> -1) {
1085                         nr= 1;
1086                         sce= G.main->scene.first;
1087                         while(sce) {
1088                                 if( event==nr) break;
1089                                 nr++;
1090                                 sce= sce->id.next;
1091                         }
1092                         if(sce) {
1093
1094                                 deselect_all_seq();
1095
1096                                 /* where ? */
1097                                 getmouseco_areawin(mval);
1098                                 areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1099                                 cfra= (int)(x+0.5);
1100                                 machine= (int)(y+0.5);
1101
1102                                 seq= alloc_sequence(cfra, machine);
1103                                 seq->type= SEQ_SCENE;
1104                                 seq->scene= sce;
1105                                 seq->sfra= sce->r.sfra;
1106                                 seq->len= sce->r.efra - sce->r.sfra + 1;
1107
1108                                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
1109                                 strip->len= seq->len;
1110                                 strip->us= 1;
1111                                 if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1112
1113                                 BIF_undo_push("Add scene strip Sequencer");
1114                                 transform_seq('g', 0);
1115                         }
1116                 }
1117                 MEM_freeN(str);
1118
1119                 break;
1120         case 2:
1121         case 3:
1122         case 4:
1123         case 5:
1124         case 6:
1125         case 7:
1126         case 8:
1127         case 9:
1128         case 10:
1129         case 13:
1130         case 14:
1131
1132                 if(last_seq==0) error("Need at least one active sequence strip");
1133                 else if(event==10) {
1134                         activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, load_plugin_seq);
1135                 }
1136                 else {
1137                         if( add_seq_effect(event) ) transform_seq('g', 0);
1138                 }
1139
1140                 break;
1141         case 103:
1142                 if (!last_sounddir[0]) strncpy(last_sounddir, U.sounddir, FILE_MAXDIR-1);
1143                 activate_fileselect(FILE_SPECIAL, "Select Wav", last_sounddir, add_sound_strip);
1144                 break;
1145         }
1146 }
1147
1148 void change_sequence(void)
1149 {
1150         Scene *sce;
1151         short event;
1152
1153         if(last_seq==0) return;
1154
1155         if(last_seq->type & SEQ_EFFECT) {
1156                 event= pupmenu("Change Effect%t|Switch A <-> B %x1|Switch B <-> C %x10|Plugin%x11|Recalculate%x12|Cross%x2|Gamma Cross%x3|Add%x4|Sub%x5|Mul%x6|Alpha Over%x7|Alpha Under%x8|Alpha Over Drop%x9|Wipe%x13|Glow%x14");
1157                 if(event>0) {
1158                         if(event==1) {
1159                                 SWAP(Sequence *, last_seq->seq1, last_seq->seq2);
1160                         }
1161                         else if(event==10) {
1162                                 SWAP(Sequence *, last_seq->seq2, last_seq->seq3);
1163                         }
1164                         else if(event==11) {
1165                                 activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, change_plugin_seq);
1166                         }
1167                         else if(event==12);     /* recalculate: only new_stripdata */
1168                         else {
1169                                 /* to be sure, free plugin */
1170                                 free_plugin_seq(last_seq->plugin);
1171                                 last_seq->plugin= 0;
1172                                 last_seq->type= event_to_efftype(event);
1173
1174                                 switch(last_seq->type){
1175                                         case SEQ_WIPE:
1176                                                 init_wipe_effect(last_seq);
1177                                                 break;
1178                                         case SEQ_GLOW:
1179                                                 init_glow_effect(last_seq);
1180                                                 break;
1181                                 }
1182
1183                         }
1184                         new_stripdata(last_seq);
1185                         allqueue(REDRAWSEQ, 0);
1186                         BIF_undo_push("Change effect Sequencer");
1187                 }
1188         }
1189         else if(last_seq->type == SEQ_IMAGE) {
1190                 if(okee("Change images")) {
1191                         activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, reload_image_strip);
1192                 }
1193         }
1194         else if(last_seq->type == SEQ_MOVIE) {
1195                 ;
1196         }
1197         else if(last_seq->type == SEQ_SCENE) {
1198                 event= pupmenu("Change Scene%t|Update Start and End");
1199
1200                 if(event==1) {
1201                         sce= last_seq->scene;
1202
1203                         last_seq->len= sce->r.efra - sce->r.sfra + 1;
1204                         last_seq->sfra= sce->r.sfra;
1205                         new_stripdata(last_seq);
1206                         calc_sequence(last_seq);
1207
1208                         allqueue(REDRAWSEQ, 0);
1209                 }
1210         }
1211
1212 }
1213
1214 static int is_a_sequence(Sequence *test)
1215 {
1216         Sequence *seq;
1217         Editing *ed;
1218
1219         ed= G.scene->ed;
1220         if(ed==0 || test==0) return 0;
1221
1222         seq= ed->seqbasep->first;
1223         while(seq) {
1224                 if(seq==test) return 1;
1225                 seq= seq->next;
1226         }
1227
1228         return 0;
1229 }
1230
1231 static void recurs_del_seq(ListBase *lb)
1232 {
1233         Sequence *seq, *seqn;
1234
1235         seq= lb->first;
1236         while(seq) {
1237                 seqn= seq->next;
1238                 if(seq->flag & SELECT) {
1239                         if(seq->type==SEQ_SOUND && seq->sound) seq->sound->id.us--;
1240                         BLI_remlink(lb, seq);
1241                         if(seq==last_seq) last_seq= 0;
1242                         if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase);
1243                         if(seq->ipo) seq->ipo->id.us--;
1244                         free_sequence(seq);
1245                 }
1246                 seq= seqn;
1247         }
1248 }
1249
1250 void del_seq(void)
1251 {
1252         Sequence *seq, *seqn;
1253         MetaStack *ms;
1254         Editing *ed;
1255         int doit;
1256
1257         if(okee("Erase selected")==0) return;
1258
1259         ed= G.scene->ed;
1260         if(ed==0) return;
1261
1262         recurs_del_seq(ed->seqbasep);
1263
1264         /* test effects */
1265         doit= 1;
1266         while(doit) {
1267                 doit= 0;
1268                 seq= ed->seqbasep->first;
1269                 while(seq) {
1270                         seqn= seq->next;
1271                         if(seq->type & SEQ_EFFECT) {
1272                                 if( is_a_sequence(seq->seq1)==0 || is_a_sequence(seq->seq2)==0 || is_a_sequence(seq->seq3)==0 ) {
1273                                         BLI_remlink(ed->seqbasep, seq);
1274                                         if(seq==last_seq) last_seq= 0;
1275                                         free_sequence(seq);
1276                                         doit= 1;
1277                                 }
1278                         }
1279                         seq= seqn;
1280                 }
1281         }
1282
1283         /* updates lengths etc */
1284         seq= ed->seqbasep->first;
1285         while(seq) {
1286                 calc_sequence(seq);
1287                 seq= seq->next;
1288         }
1289
1290         /* free parent metas */
1291         ms= ed->metastack.last;
1292         while(ms) {
1293                 ms->parseq->strip->len= 0;              /* force new alloc */
1294                 calc_sequence(ms->parseq);
1295                 ms= ms->prev;
1296         }
1297
1298         BIF_undo_push("Delete from Sequencer");
1299         allqueue(REDRAWSEQ, 0);
1300 }
1301
1302
1303
1304 static void recurs_dupli_seq(ListBase *old, ListBase *new)
1305 {
1306         Sequence *seq, *seqn;
1307         StripElem *se;
1308         int a;
1309
1310         seq= old->first;
1311
1312         while(seq) {
1313                 seq->newseq= 0;
1314                 if(seq->flag & SELECT) {
1315
1316                         if(seq->type==SEQ_META) {
1317                                 seqn= MEM_dupallocN(seq);
1318                                 seq->newseq= seqn;
1319                                 BLI_addtail(new, seqn);
1320
1321                                 seqn->strip= MEM_dupallocN(seq->strip);
1322
1323                                 if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1324
1325                                 seq->flag &= SEQ_DESEL;
1326                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1327
1328                                 seqn->seqbase.first= seqn->seqbase.last= 0;
1329                                 recurs_dupli_seq(&seq->seqbase, &seqn->seqbase);
1330
1331                         }
1332                         else if(seq->type == SEQ_SCENE) {
1333                                 seqn= MEM_dupallocN(seq);
1334                                 seq->newseq= seqn;
1335                                 BLI_addtail(new, seqn);
1336
1337                                 seqn->strip= MEM_dupallocN(seq->strip);
1338
1339                                 if(seq->len>0) seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1340
1341                                 seq->flag &= SEQ_DESEL;
1342                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1343                         }
1344                         else if(seq->type == SEQ_MOVIE) {
1345                                 seqn= MEM_dupallocN(seq);
1346                                 seq->newseq= seqn;
1347                                 BLI_addtail(new, seqn);
1348
1349                                 seqn->strip= MEM_dupallocN(seq->strip);
1350                                 seqn->anim= 0;
1351
1352                                 if(seqn->len>0) {
1353                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1354                                         /* copy first elem */
1355                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1356                                         se= seqn->strip->stripdata;
1357                                         a= seq->len;
1358                                         while(a--) {
1359                                                 se->ok= 1;
1360                                                 se++;
1361                                         }
1362                                 }
1363
1364                                 seq->flag &= SEQ_DESEL;
1365                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1366                         }
1367                         else if(seq->type == SEQ_SOUND) {
1368                                 seqn= MEM_dupallocN(seq);
1369                                 seq->newseq= seqn;
1370                                 BLI_addtail(new, seqn);
1371
1372                                 seqn->strip= MEM_dupallocN(seq->strip);
1373                                 seqn->anim= 0;
1374                                 seqn->sound->id.us++;
1375                                 if(seqn->ipo) seqn->ipo->id.us++;
1376
1377                                 if(seqn->len>0) {
1378                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1379                                         /* copy first elem */
1380                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1381                                         se= seqn->strip->stripdata;
1382                                         a= seq->len;
1383                                         while(a--) {
1384                                                 se->ok= 1;
1385                                                 se++;
1386                                         }
1387                                 }
1388
1389                                 seq->flag &= SEQ_DESEL;
1390                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1391                         }
1392                         else if(seq->type < SEQ_EFFECT) {
1393                                 seqn= MEM_dupallocN(seq);
1394                                 seq->newseq= seqn;
1395                                 BLI_addtail(new, seqn);
1396
1397                                 seqn->strip->us++;
1398                                 seq->flag &= SEQ_DESEL;
1399
1400                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1401                         }
1402                         else {
1403                                 if(seq->seq1->newseq) {
1404
1405                                         seqn= MEM_dupallocN(seq);
1406                                         seq->newseq= seqn;
1407                                         BLI_addtail(new, seqn);
1408
1409                                         seqn->seq1= seq->seq1->newseq;
1410                                         if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
1411                                         if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
1412
1413                                         if(seqn->ipo) seqn->ipo->id.us++;
1414
1415                                         if(seq->plugin) {
1416                                                 seqn->plugin= MEM_dupallocN(seq->plugin);
1417                                                 open_plugin_seq(seqn->plugin, seqn->name+2);
1418                                         }
1419                                         seqn->strip= MEM_dupallocN(seq->strip);
1420
1421                                         if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1422
1423                                         seq->flag &= SEQ_DESEL;
1424
1425                                         seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1426                                 }
1427                         }
1428
1429                 }
1430                 seq= seq->next;
1431         }
1432 }
1433
1434 void add_duplicate_seq(void)
1435 {
1436         Editing *ed;
1437         ListBase new;
1438
1439         ed= G.scene->ed;
1440         if(ed==0) return;
1441
1442         new.first= new.last= 0;
1443
1444         recurs_dupli_seq(ed->seqbasep, &new);
1445         addlisttolist(ed->seqbasep, &new);
1446
1447         BIF_undo_push("Add duplicate Sequencer");
1448         transform_seq('g', 0);
1449 }
1450
1451 int insert_gap(int gap, int cfra)
1452 {
1453         Sequence *seq;
1454         Editing *ed;
1455         int done=0;
1456
1457         /* all strips >= cfra are shifted */
1458         ed= G.scene->ed;
1459         if(ed==0) return 0;
1460
1461         WHILE_SEQ(ed->seqbasep) {
1462                 if(seq->startdisp >= cfra) {
1463                         seq->start+= gap;
1464                         calc_sequence(seq);
1465                         done= 1;
1466                 }
1467         }
1468         END_SEQ
1469
1470         return done;
1471 }
1472
1473 void touch_seq_files(void)
1474 {
1475         Sequence *seq;
1476         Editing *ed;
1477         char str[256];
1478
1479         /* touch all strips with movies */
1480         ed= G.scene->ed;
1481         if(ed==0) return;
1482
1483         if(okee("Touch and print selected movies")==0) return;
1484
1485         waitcursor(1);
1486
1487         WHILE_SEQ(ed->seqbasep) {
1488                 if(seq->flag & SELECT) {
1489                         if(seq->type==SEQ_MOVIE) {
1490                                 if(seq->strip && seq->strip->stripdata) {
1491                                         BLI_make_file_string(G.sce, str, seq->strip->dir, seq->strip->stripdata->name);
1492                                         BLI_touch(seq->name);
1493                                 }
1494                         }
1495
1496                 }
1497         }
1498         END_SEQ
1499
1500         waitcursor(0);
1501 }
1502
1503 void set_filter_seq(void)
1504 {
1505         Sequence *seq;
1506         Editing *ed;
1507
1508         ed= G.scene->ed;
1509         if(ed==0) return;
1510
1511         if(okee("Set FilterY")==0) return;
1512
1513         WHILE_SEQ(ed->seqbasep) {
1514                 if(seq->flag & SELECT) {
1515                         if(seq->type==SEQ_MOVIE) {
1516                                 seq->flag |= SEQ_FILTERY;
1517                         }
1518
1519                 }
1520         }
1521         END_SEQ
1522
1523 }
1524
1525
1526
1527 void no_gaps(void)
1528 {
1529         Editing *ed;
1530         int cfra, first= 0, done;
1531
1532         ed= G.scene->ed;
1533         if(ed==0) return;
1534
1535         for(cfra= CFRA; cfra<=EFRA; cfra++) {
1536                 if(first==0) {
1537                         if( evaluate_seq_frame(cfra) ) first= 1;
1538                 }
1539                 else {
1540                         done= 1;
1541                         while( evaluate_seq_frame(cfra) == 0) {
1542                                 done= insert_gap(-1, cfra);
1543                                 if(done==0) break;
1544                         }
1545                         if(done==0) break;
1546                 }
1547         }
1548
1549         BIF_undo_push("No gaps Sequencer");
1550         allqueue(REDRAWSEQ, 0);
1551 }
1552
1553
1554 /* ****************** META ************************* */
1555
1556 void make_meta(void)
1557 {
1558         Sequence *seq, *seqm, *next;
1559         Editing *ed;
1560         int tot;
1561
1562         ed= G.scene->ed;
1563         if(ed==0) return;
1564
1565         /* is there more than 1 select */
1566         tot= 0;
1567         seq= ed->seqbasep->first;
1568         while(seq) {
1569                 if(seq->flag & SELECT) {
1570                         tot++;
1571                         if (seq->type == SEQ_SOUND) { error("Can't make Meta Strip from audio"); return; }
1572                 }
1573                 seq= seq->next;
1574         }
1575         if(tot < 2) return;
1576
1577         if(okee("Make Meta Strip")==0) return;
1578
1579         /* test relationships */
1580         seq= ed->seqbasep->first;
1581         while(seq) {
1582                 if(seq->flag & SELECT) {
1583                         if(seq->type & SEQ_EFFECT) {
1584                                 if((seq->seq1->flag & SELECT)==0) tot= 0;
1585                                 if((seq->seq2->flag & SELECT)==0) tot= 0;
1586                                 if((seq->seq3->flag & SELECT)==0) tot= 0;
1587                         }
1588                 }
1589                 else if(seq->type & SEQ_EFFECT) {
1590                         if(seq->seq1->flag & SELECT) tot= 0;
1591                         if(seq->seq2->flag & SELECT) tot= 0;
1592                         if(seq->seq3->flag & SELECT) tot= 0;
1593                 }
1594                 if(tot==0) break;
1595                 seq= seq->next;
1596         }
1597         if(tot==0) {
1598                 error("Please select all related strips");
1599                 return;
1600         }
1601
1602         /* remove all selected from main list, and put in meta */
1603
1604         seqm= alloc_sequence(1, 1);
1605         seqm->type= SEQ_META;
1606         seqm->flag= SELECT;
1607
1608         seq= ed->seqbasep->first;
1609         while(seq) {
1610                 next= seq->next;
1611                 if(seq!=seqm && (seq->flag & SELECT)) {
1612                         BLI_remlink(ed->seqbasep, seq);
1613                         BLI_addtail(&seqm->seqbase, seq);
1614                 }
1615                 seq= next;
1616         }
1617         calc_sequence(seqm);
1618
1619         seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
1620         seqm->strip->len= seqm->len;
1621         seqm->strip->us= 1;
1622         if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata");
1623
1624         set_meta_stripdata(seqm);
1625
1626         BIF_undo_push("Make Meta Sequencer");
1627         allqueue(REDRAWSEQ, 0);
1628 }
1629
1630 void un_meta(void)
1631 {
1632         Editing *ed;
1633         Sequence *seq, *seqn;
1634         int doit;
1635
1636         ed= G.scene->ed;
1637         if(ed==0) return;
1638
1639         if(last_seq==0 || last_seq->type!=SEQ_META) return;
1640
1641         if(okee("Un Meta")==0) return;
1642
1643         addlisttolist(ed->seqbasep, &last_seq->seqbase);
1644
1645         last_seq->seqbase.first= 0;
1646         last_seq->seqbase.last= 0;
1647
1648         BLI_remlink(ed->seqbasep, last_seq);
1649         free_sequence(last_seq);
1650
1651         /* test effects */
1652         doit= 1;
1653         while(doit) {
1654                 doit= 0;
1655                 seq= ed->seqbasep->first;
1656                 while(seq) {
1657                         seqn= seq->next;
1658                         if(seq->type & SEQ_EFFECT) {
1659                                 if( is_a_sequence(seq->seq1)==0 || is_a_sequence(seq->seq2)==0 || is_a_sequence(seq->seq3)==0 ) {
1660                                         BLI_remlink(ed->seqbasep, seq);
1661                                         if(seq==last_seq) last_seq= 0;
1662                                         free_sequence(seq);
1663                                         doit= 1;
1664                                 }
1665                         }
1666                         seq= seqn;
1667                 }
1668         }
1669
1670
1671         /* test for effects and overlap */
1672         WHILE_SEQ(ed->seqbasep) {
1673                 if(seq->flag & SELECT) {
1674                         seq->flag &= ~SEQ_OVERLAP;
1675                         if( test_overlap_seq(seq) ) {
1676                                 shuffle_seq(seq);
1677                         }
1678                 }
1679         }
1680         END_SEQ;
1681
1682         BIF_undo_push("Un-make Meta Sequencer");
1683         allqueue(REDRAWSEQ, 0);
1684
1685 }
1686
1687 void exit_meta(void)
1688 {
1689         Sequence *seq;
1690         MetaStack *ms;
1691         Editing *ed;
1692
1693         ed= G.scene->ed;
1694         if(ed==0) return;
1695
1696         if(ed->metastack.first==0) return;
1697
1698         ms= ed->metastack.last;
1699         BLI_remlink(&ed->metastack, ms);
1700
1701         ed->seqbasep= ms->oldbasep;
1702
1703         /* recalc entire meta */
1704         set_meta_stripdata(ms->parseq);
1705
1706         /* recalc all: the meta can have effects connected to it */
1707         seq= ed->seqbasep->first;
1708         while(seq) {
1709                 calc_sequence(seq);
1710                 seq= seq->next;
1711         }
1712
1713         last_seq= ms->parseq;
1714
1715         last_seq->flag= SELECT;
1716         recurs_sel_seq(last_seq);
1717
1718         MEM_freeN(ms);
1719         allqueue(REDRAWSEQ, 0);
1720
1721         BIF_undo_push("Exit meta strip Sequence");
1722 }
1723
1724
1725 void enter_meta(void)
1726 {
1727         MetaStack *ms;
1728         Editing *ed;
1729
1730         ed= G.scene->ed;
1731         if(ed==0) return;
1732
1733         if(last_seq==0 || last_seq->type!=SEQ_META || last_seq->flag==0) {
1734                 exit_meta();
1735                 return;
1736         }
1737
1738         ms= MEM_mallocN(sizeof(MetaStack), "metastack");
1739         BLI_addtail(&ed->metastack, ms);
1740         ms->parseq= last_seq;
1741         ms->oldbasep= ed->seqbasep;
1742
1743         ed->seqbasep= &last_seq->seqbase;
1744
1745         last_seq= 0;
1746         allqueue(REDRAWSEQ, 0);
1747         BIF_undo_push("Enter meta strip Sequence");
1748 }
1749
1750
1751 /* ****************** END META ************************* */
1752
1753
1754 typedef struct TransSeq {
1755         int start, machine;
1756         int startstill, endstill;
1757         int startofs, endofs;
1758 } TransSeq;
1759
1760 void transform_seq(int mode, int context)
1761 {
1762         Sequence *seq;
1763         Editing *ed;
1764         float dx, dy, dvec[2], div;
1765         TransSeq *transmain, *ts;
1766         int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0;
1767         unsigned short event = 0;
1768         short mval[2], val, xo, yo, xn, yn;
1769         char str[32];
1770
1771         if(mode!='g') return;   /* from gesture */
1772
1773         /* which seqs are involved */
1774         ed= G.scene->ed;
1775         if(ed==0) return;
1776
1777         WHILE_SEQ(ed->seqbasep) {
1778                 if(seq->flag & SELECT) tot++;
1779         }
1780         END_SEQ
1781
1782         if(tot==0) return;
1783
1784         G.moving= 1;
1785
1786         ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
1787
1788         WHILE_SEQ(ed->seqbasep) {
1789
1790                 if(seq->flag & SELECT) {
1791
1792                         ts->start= seq->start;
1793                         ts->machine= seq->machine;
1794                         ts->startstill= seq->startstill;
1795                         ts->endstill= seq->endstill;
1796                         ts->startofs= seq->startofs;
1797                         ts->endofs= seq->endofs;
1798
1799                         ts++;
1800                 }
1801         }
1802         END_SEQ
1803
1804         getmouseco_areawin(mval);
1805         xo=xn= mval[0];
1806         yo=yn= mval[1];
1807         dvec[0]= dvec[1]= 0.0;
1808
1809         while(afbreek==0) {
1810                 getmouseco_areawin(mval);
1811                 if(mval[0]!=xo || mval[1]!=yo || firsttime) {
1812                         firsttime= 0;
1813
1814                         if(mode=='g') {
1815
1816                                 dx= mval[0]- xo;
1817                                 dy= mval[1]- yo;
1818
1819                                 div= G.v2d->mask.xmax-G.v2d->mask.xmin;
1820                                 dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
1821
1822                                 div= G.v2d->mask.ymax-G.v2d->mask.ymin;
1823                                 dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
1824
1825                                 if(G.qual & LR_SHIFTKEY) {
1826                                         if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
1827                                 }
1828
1829                                 dvec[0]+= dx;
1830                                 dvec[1]+= dy;
1831
1832                                 if(midtog) dvec[proj]= 0.0;
1833                                 ix= floor(dvec[0]+0.5);
1834                                 iy= floor(dvec[1]+0.5);
1835
1836
1837                                 ts= transmain;
1838
1839                                 WHILE_SEQ(ed->seqbasep) {
1840                                         if(seq->flag & SELECT) {
1841                                                 if(seq->flag & SEQ_LEFTSEL) {
1842                                                         if(ts->startstill) {
1843                                                                 seq->startstill= ts->startstill-ix;
1844                                                                 if(seq->startstill<0) seq->startstill= 0;
1845                                                         }
1846                                                         else if(ts->startofs) {
1847                                                                 seq->startofs= ts->startofs+ix;
1848                                                                 if(seq->startofs<0) seq->startofs= 0;
1849                                                         }
1850                                                         else {
1851                                                                 if(ix>0) {
1852                                                                         seq->startofs= ix;
1853                                                                         seq->startstill= 0;
1854                                                                 }
1855                                                                 else if (seq->type != SEQ_SOUND) {
1856                                                                         seq->startstill= -ix;
1857                                                                         seq->startofs= 0;
1858                                                                 }
1859                                                         }
1860                                                         if(seq->len <= seq->startofs+seq->endofs) {
1861                                                                 seq->startofs= seq->len-seq->endofs-1;
1862                                                         }
1863                                                 }
1864                                                 if(seq->flag & SEQ_RIGHTSEL) {
1865                                                         if(ts->endstill) {
1866                                                                 seq->endstill= ts->endstill+ix;
1867                                                                 if(seq->endstill<0) seq->endstill= 0;
1868                                                         }
1869                                                         else if(ts->endofs) {
1870                                                                 seq->endofs= ts->endofs-ix;
1871                                                                 if(seq->endofs<0) seq->endofs= 0;
1872                                                         }
1873                                                         else {
1874                                                                 if(ix<0) {
1875                                                                         seq->endofs= -ix;
1876                                                                         seq->endstill= 0;
1877                                                                 }
1878                                                                 else if (seq->type != SEQ_SOUND) {
1879                                                                         seq->endstill= ix;
1880                                                                         seq->endofs= 0;
1881                                                                 }
1882                                                         }
1883                                                         if(seq->len <= seq->startofs+seq->endofs) {
1884                                                                 seq->endofs= seq->len-seq->startofs-1;
1885                                                         }
1886                                                 }
1887                                                 if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
1888                                                         if(seq->type<SEQ_EFFECT) seq->start= ts->start+ ix;
1889
1890                                                         if(seq->depth==0) seq->machine= ts->machine+ iy;
1891
1892                                                         if(seq->machine<1) seq->machine= 1;
1893                                                         else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
1894                                                 }
1895
1896                                                 calc_sequence(seq);
1897
1898                                                 ts++;
1899                                         }
1900                                 }
1901                                 END_SEQ
1902
1903                                 sprintf(str, "X: %d   Y: %d  ", ix, iy);
1904                                 headerprint(str);
1905                         }
1906
1907                         xo= mval[0];
1908                         yo= mval[1];
1909
1910                         /* test for effect and overlap */
1911
1912                         WHILE_SEQ(ed->seqbasep) {
1913                                 if(seq->flag & SELECT) {
1914                                         seq->flag &= ~SEQ_OVERLAP;
1915                                         if( test_overlap_seq(seq) ) {
1916                                                 seq->flag |= SEQ_OVERLAP;
1917                                         }
1918                                 }
1919                                 else if(seq->type & SEQ_EFFECT) {
1920                                         if(seq->seq1->flag & SELECT) calc_sequence(seq);
1921                                         else if(seq->seq2->flag & SELECT) calc_sequence(seq);
1922                                         else if(seq->seq3->flag & SELECT) calc_sequence(seq);
1923                                 }
1924                         }
1925                         END_SEQ;
1926
1927                         force_draw(0);
1928                 }
1929                 else BIF_wait_for_statechange();
1930
1931                 while(qtest()) {
1932                         event= extern_qread(&val);
1933                         if(val) {
1934                                 switch(event) {
1935                                 case ESCKEY:
1936                                 case LEFTMOUSE:
1937                                 case SPACEKEY:
1938                                         afbreek= 1;
1939                                         break;
1940                                 case MIDDLEMOUSE:
1941                                         midtog= ~midtog;
1942                                         if(midtog) {
1943                                                 if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1;
1944                                                 else proj= 0;
1945                                                 firsttime= 1;
1946                                         }
1947                                         break;
1948                                 default:
1949                                         arrows_move_cursor(event);
1950                                 }
1951                         }
1952                         if(afbreek) break;
1953                 }
1954         }
1955
1956         if(event==ESCKEY) {
1957
1958                 ts= transmain;
1959                 WHILE_SEQ(ed->seqbasep) {
1960                         if(seq->flag & SELECT) {
1961                                 seq->start= ts->start;
1962                                 seq->machine= ts->machine;
1963                                 seq->startstill= ts->startstill;
1964                                 seq->endstill= ts->endstill;
1965                                 seq->startofs= ts->startofs;
1966                                 seq->endofs= ts->endofs;
1967
1968                                 calc_sequence(seq);
1969                                 seq->flag &= ~SEQ_OVERLAP;
1970
1971                                 ts++;
1972                         } else if(seq->type & SEQ_EFFECT) {
1973                                 if(seq->seq1->flag & SELECT) calc_sequence(seq);
1974                                 else if(seq->seq2->flag & SELECT) calc_sequence(seq);
1975                                 else if(seq->seq3->flag & SELECT) calc_sequence(seq);
1976                         }
1977
1978                 }
1979                 END_SEQ
1980         }
1981         else {
1982
1983                 /* images, effects and overlap */
1984                 WHILE_SEQ(ed->seqbasep) {
1985                         if(seq->type == SEQ_META) {
1986                                 calc_sequence(seq);
1987                                 seq->flag &= ~SEQ_OVERLAP;
1988                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
1989                         }
1990                         else if(seq->flag & SELECT) {
1991                                 calc_sequence(seq);
1992                                 seq->flag &= ~SEQ_OVERLAP;
1993                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
1994                         }
1995                         else if(seq->type & SEQ_EFFECT) calc_sequence(seq);
1996                 }
1997                 END_SEQ
1998
1999                 /* as last: */
2000                 sort_seq();
2001         }
2002
2003         G.moving= 0;
2004         MEM_freeN(transmain);
2005
2006         BIF_undo_push("Transform Sequencer");
2007         allqueue(REDRAWSEQ, 0);
2008 }
2009
2010
2011 void clever_numbuts_seq(void)
2012 {
2013         PluginSeq *pis;
2014         StripElem *se;
2015         VarStruct *varstr;
2016         int a;
2017
2018         if(last_seq==0) return;
2019         if(last_seq->type==SEQ_PLUGIN) {
2020                 pis= last_seq->plugin;
2021                 if(pis->vars==0) return;
2022
2023                 varstr= pis->varstr;
2024                 if(varstr) {
2025                         for(a=0; a<pis->vars; a++, varstr++) {
2026                                 add_numbut(a, varstr->type, varstr->name, varstr->min, varstr->max, &(pis->data[a]), varstr->tip);
2027                         }
2028
2029                         if( do_clever_numbuts(pis->pname, pis->vars, REDRAW) ) {
2030                                 new_stripdata(last_seq);
2031                                 free_imbuf_effect_spec(CFRA);
2032                                 allqueue(REDRAWSEQ, 0);
2033                         }
2034                 }
2035         }
2036         else if(last_seq->type==SEQ_MOVIE) {
2037
2038                 if(last_seq->mul==0.0) last_seq->mul= 1.0;
2039
2040                 add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
2041                 add_numbut(1, TOG|SHO|BIT|4, "FilterY", 0.0, 1.0, &last_seq->flag, 0);
2042                 /* warning: only a single bit-button possible: we work at copied data! */
2043                 add_numbut(2, NUM|FLO, "Mul", 0.01, 5.0, &last_seq->mul, 0);
2044
2045                 if( do_clever_numbuts("Movie", 3, REDRAW) ) {
2046                         se= last_seq->curelem;
2047
2048                         if(se && se->ibuf ) {
2049                                 IMB_freeImBuf(se->ibuf);
2050                                 se->ibuf= 0;
2051                         }
2052                         allqueue(REDRAWSEQ, 0);
2053                 }
2054         }
2055         else if(last_seq->type==SEQ_SOUND) {
2056
2057                 add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
2058                 add_numbut(1, NUM|FLO, "Gain (dB):", -96.0, 6.0, &last_seq->level, 0);
2059                 add_numbut(2, NUM|FLO, "Pan:", -1.0, 1.0, &last_seq->pan, 0);
2060                 add_numbut(3, TOG|SHO|BIT|5, "Mute", 0.0, 1.0, &last_seq->flag, 0);
2061
2062                 if( do_clever_numbuts("Audio", 4, REDRAW) ) {
2063                         se= last_seq->curelem;
2064                         allqueue(REDRAWSEQ, 0);
2065                 }
2066         }
2067         else if(last_seq->type==SEQ_META) {
2068
2069                 add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
2070
2071                 if( do_clever_numbuts("Meta", 1, REDRAW) ) {
2072                         allqueue(REDRAWSEQ, 0);
2073                 }
2074         }
2075 }
2076
2077 void seq_snap_menu(void)
2078 {
2079         short event;
2080
2081         event= pupmenu("Snap %t|To Current Frame%x1");
2082         if(event < 1) return;
2083
2084         seq_snap(event);
2085 }
2086
2087 void seq_snap(short event)
2088 {
2089         Editing *ed;
2090         Sequence *seq;
2091
2092         ed= G.scene->ed;
2093         if(ed==0) return;
2094
2095         /* problem: contents of meta's are all shifted to the same position... */
2096
2097         /* also check metas */
2098         WHILE_SEQ(ed->seqbasep) {
2099                 if(seq->flag & SELECT) {
2100                         if(seq->type<SEQ_EFFECT) seq->start= CFRA-seq->startofs+seq->startstill;
2101                         calc_sequence(seq);
2102                 }
2103         }
2104         END_SEQ
2105
2106
2107         /* test for effects and overlap */
2108         WHILE_SEQ(ed->seqbasep) {
2109                 if(seq->flag & SELECT) {
2110                         seq->flag &= ~SEQ_OVERLAP;
2111                         if( test_overlap_seq(seq) ) {
2112                                 shuffle_seq(seq);
2113                         }
2114                 }
2115                 else if(seq->type & SEQ_EFFECT) {
2116                         if(seq->seq1->flag & SELECT) calc_sequence(seq);
2117                         else if(seq->seq2->flag & SELECT) calc_sequence(seq);
2118                         else if(seq->seq3->flag & SELECT) calc_sequence(seq);
2119                 }
2120         }
2121         END_SEQ;
2122
2123         /* as last: */
2124         sort_seq();
2125
2126         BIF_undo_push("Snap menu Sequencer");
2127         allqueue(REDRAWSEQ, 0);
2128 }
2129
2130 void borderselect_seq(void)
2131 {
2132         Sequence *seq;
2133         Editing *ed;
2134         rcti rect;
2135         rctf rectf, rq;
2136         int val;
2137         short mval[2];
2138
2139         ed= G.scene->ed;
2140         if(ed==0) return;
2141
2142         val= get_border(&rect, 3);
2143
2144         if(val) {
2145                 mval[0]= rect.xmin;
2146                 mval[1]= rect.ymin;
2147                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
2148                 mval[0]= rect.xmax;
2149                 mval[1]= rect.ymax;
2150                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
2151
2152                 seq= ed->seqbasep->first;
2153                 while(seq) {
2154
2155                         if(seq->startstill) rq.xmin= seq->start;
2156                         else rq.xmin= seq->startdisp;
2157                         rq.ymin= seq->machine+0.2;
2158                         if(seq->endstill) rq.xmax= seq->start+seq->len;
2159                         else rq.xmax= seq->enddisp;
2160                         rq.ymax= seq->machine+0.8;
2161
2162                         if(BLI_isect_rctf(&rq, &rectf, 0)) {
2163                                 if(val==LEFTMOUSE) {
2164                                         seq->flag |= SELECT;
2165                                 }
2166                                 else {
2167                                         seq->flag &= ~SELECT;
2168                                 }
2169                         }
2170
2171                         seq= seq->next;
2172                 }
2173
2174                 BIF_undo_push("Border select Sequencer");
2175                 addqueue(curarea->win, REDRAW, 1);
2176         }
2177 }