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