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