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