Tweaked the force_draw() calls, to allow headerprint() to work while
[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("There is no more space to add a sequence strip");
300
301                         BLI_remlink(ed->seqbasep, test);
302                         free_sequence(test);
303                         return;
304                 }
305                 test->machine++;
306                 calc_sequence(test);
307         }
308 }
309
310 static void deselect_all_seq(void)
311 {
312         Sequence *seq;
313         Editing *ed;
314
315         ed= G.scene->ed;
316         if(ed==0) return;
317
318         WHILE_SEQ(ed->seqbasep) {
319                 seq->flag &= SEQ_DESEL;
320         }
321         END_SEQ
322 }
323
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(0);
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("The selected file is 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 is 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         if(event==13) return SEQ_WIPE;
840         if(event==14) return SEQ_GLOW;
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("Can't apply effects to audio sequence strips"); 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 || type==13 || type==14) {  /* plugin: minimal 1 select */
876                 if(seq2==0)  {
877                         error("Need at least one selected sequence strip");
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 sequence strips");
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         /* Allocate variable structs for effects with settings */
904         if(seq->type==SEQ_WIPE){
905                 init_wipe_effect(seq);
906         }
907         else if(seq->type==SEQ_GLOW){
908                 init_glow_effect(seq);
909         }
910
911         if(seq->type==SEQ_ALPHAUNDER || seq->type==SEQ_ALPHAOVER) {
912                 seq->seq2= seq1;
913                 seq->seq1= seq2;
914         }
915         else {
916                 seq->seq1= seq1;
917                 seq->seq2= seq2;
918         }
919         seq->seq3= seq3;
920         calc_sequence(seq);
921
922         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
923         strip->len= seq->len;
924         strip->us= 1;
925         if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
926
927         return 1;
928 }
929
930 static void load_plugin_seq(char *str)          /* called from fileselect */
931 {
932         Editing *ed;
933
934         add_seq_effect(10);             /* this sets last_seq */
935
936         free_plugin_seq(last_seq->plugin);
937
938         last_seq->plugin= (PluginSeq *)add_plugin_seq(str, last_seq->name+2);
939
940         if(last_seq->plugin==0) {
941                 ed= G.scene->ed;
942                 BLI_remlink(ed->seqbasep, last_seq);
943                 free_sequence(last_seq);
944                 last_seq= 0;
945         }
946         else {
947                 last_seq->machine= MAX3(last_seq->seq1->machine, last_seq->seq2->machine, last_seq->seq3->machine);
948                 if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq);
949
950                 transform_seq('g');
951         }
952 }
953
954 void add_sequence(int type)
955 {
956         Editing *ed;
957         Sequence *seq;
958         Strip *strip;
959         Scene *sce;
960         float x, y;
961         int cfra, machine;
962         short nr, event, mval[2];
963         char *str;
964
965         if (type >= 0){
966                 /* bypass pupmenu for calls from menus (aphex) */
967                 switch(type){
968                 case SEQ_SCENE:
969                         event = 101;
970                         break;
971                 case SEQ_IMAGE:
972                         event = 1;
973                         break;
974                 case SEQ_MOVIE:
975                         event = 102;
976                         break;
977                 case SEQ_SOUND:
978                         event = 103;
979                         break;
980                 case SEQ_PLUGIN:
981                         event = 10;
982                         break;
983                 case SEQ_CROSS:
984                         event = 2;
985                         break;
986                 case SEQ_ADD:
987                         event = 4;
988                         break;
989                 case SEQ_SUB:
990                         event = 5;
991                         break;
992                 case SEQ_ALPHAOVER:
993                         event = 7;
994                         break;
995                 case SEQ_ALPHAUNDER:
996                         event = 8;
997                         break;
998                 case SEQ_GAMCROSS:
999                         event = 3;
1000                         break;
1001                 case SEQ_MUL:
1002                         event = 6;
1003                         break;
1004                 case SEQ_OVERDROP:
1005                         event = 9;
1006                         break;
1007                 case SEQ_WIPE:
1008                         event = 13;
1009                         break;
1010                 case SEQ_GLOW:
1011                         event = 14;
1012                         break;
1013                 default:
1014                         event = 0;
1015                         break;
1016                 }
1017         }
1018         else {
1019                 event= pupmenu("Add Sequence Strip%t|Images%x1|Movie%x102|Audio%x103|Scene%x101|Plugin%x10|Cross%x2|Gamma Cross%x3|Add%x4|Sub%x5|Mul%x6|Alpha Over%x7|Alpha Under%x8|Alpha Over Drop%x9|Wipe%x13|Glow%x14");
1020         }
1021
1022         if(event<1) return;
1023
1024         if(G.scene->ed==0) {
1025                 ed= G.scene->ed= MEM_callocN( sizeof(Editing), "addseq");
1026                 ed->seqbasep= &ed->seqbase;
1027         }
1028         else ed= G.scene->ed;
1029
1030         switch(event) {
1031         case 1:
1032
1033                 activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
1034                 break;
1035         case 102:
1036
1037                 activate_fileselect(FILE_SPECIAL, "Select Movie", last_imagename, add_movie_strip);
1038                 break;
1039         case 101:
1040                 /* new menu: */
1041                 IDnames_to_pupstring(&str, NULL, NULL, &G.main->scene, (ID *)G.scene, NULL);
1042
1043                 event= pupmenu_col(str, 20);
1044
1045                 if(event> -1) {
1046                         nr= 1;
1047                         sce= G.main->scene.first;
1048                         while(sce) {
1049                                 if( event==nr) break;
1050                                 nr++;
1051                                 sce= sce->id.next;
1052                         }
1053                         if(sce) {
1054
1055                                 deselect_all_seq();
1056
1057                                 /* where ? */
1058                                 getmouseco_areawin(mval);
1059                                 areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1060                                 cfra= (int)(x+0.5);
1061                                 machine= (int)(y+0.5);
1062
1063                                 seq= alloc_sequence(cfra, machine);
1064                                 seq->type= SEQ_SCENE;
1065                                 seq->scene= sce;
1066                                 seq->sfra= sce->r.sfra;
1067                                 seq->len= sce->r.efra - sce->r.sfra + 1;
1068
1069                                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
1070                                 strip->len= seq->len;
1071                                 strip->us= 1;
1072                                 if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1073
1074                                 transform_seq('g');
1075                         }
1076                 }
1077                 MEM_freeN(str);
1078
1079                 break;
1080         case 2:
1081         case 3:
1082         case 4:
1083         case 5:
1084         case 6:
1085         case 7:
1086         case 8:
1087         case 9:
1088         case 10:
1089         case 13:
1090         case 14:
1091
1092                 if(last_seq==0) error("Need at least one active sequence strip");
1093                 else if(event==10) {
1094                         activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, load_plugin_seq);
1095                 }
1096                 else {
1097                         if( add_seq_effect(event) ) transform_seq('g');
1098                 }
1099
1100                 break;
1101         case 103:
1102                 if (!last_sounddir[0]) strcpy(last_sounddir, U.sounddir);
1103                 activate_fileselect(FILE_SPECIAL, "Select Wav", last_sounddir, add_sound_strip);
1104                 break;
1105         }
1106 }
1107
1108 void change_sequence(void)
1109 {
1110         Scene *sce;
1111         short event;
1112
1113         if(last_seq==0) return;
1114
1115         if(last_seq->type & SEQ_EFFECT) {
1116                 event= pupmenu("Change Effect%t|Switch A <-> B %x1|Switch B <-> C %x10|Plugin%x11|Recalculate%x12|Cross%x2|Gamma Cross%x3|Add%x4|Sub%x5|Mul%x6|Alpha Over%x7|Alpha Under%x8|Alpha Over Drop%x9|Wipe%x13|Glow%x14");
1117                 if(event>0) {
1118                         if(event==1) {
1119                                 SWAP(Sequence *, last_seq->seq1, last_seq->seq2);
1120                         }
1121                         else if(event==10) {
1122                                 SWAP(Sequence *, last_seq->seq2, last_seq->seq3);
1123                         }
1124                         else if(event==11) {
1125                                 activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, change_plugin_seq);
1126                         }
1127                         else if(event==12);     /* recalculate: only new_stripdata */
1128                         else {
1129                                 /* to be sure, free plugin */
1130                                 free_plugin_seq(last_seq->plugin);
1131                                 last_seq->plugin= 0;
1132                                 last_seq->type= event_to_efftype(event);
1133
1134                                 switch(last_seq->type){
1135                                         case SEQ_WIPE:
1136                                                 init_wipe_effect(last_seq);
1137                                                 break;
1138                                         case SEQ_GLOW:
1139                                                 init_glow_effect(last_seq);
1140                                                 break;
1141                                 }
1142
1143                         }
1144                         new_stripdata(last_seq);
1145                         allqueue(REDRAWSEQ, 0);
1146                 }
1147         }
1148         else if(last_seq->type == SEQ_IMAGE) {
1149                 if(okee("Change images")) {
1150                         activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, reload_image_strip);
1151                 }
1152         }
1153         else if(last_seq->type == SEQ_MOVIE) {
1154                 ;
1155         }
1156         else if(last_seq->type == SEQ_SCENE) {
1157                 event= pupmenu("Change Scene%t|Update Start and End");
1158
1159                 if(event==1) {
1160                         sce= last_seq->scene;
1161
1162                         last_seq->len= sce->r.efra - sce->r.sfra + 1;
1163                         last_seq->sfra= sce->r.sfra;
1164                         new_stripdata(last_seq);
1165                         calc_sequence(last_seq);
1166
1167                         allqueue(REDRAWSEQ, 0);
1168                 }
1169         }
1170
1171 }
1172
1173 static int is_a_sequence(Sequence *test)
1174 {
1175         Sequence *seq;
1176         Editing *ed;
1177
1178         ed= G.scene->ed;
1179         if(ed==0 || test==0) return 0;
1180
1181         seq= ed->seqbasep->first;
1182         while(seq) {
1183                 if(seq==test) return 1;
1184                 seq= seq->next;
1185         }
1186
1187         return 0;
1188 }
1189
1190 static void recurs_del_seq(ListBase *lb)
1191 {
1192         Sequence *seq, *seqn;
1193
1194         seq= lb->first;
1195         while(seq) {
1196                 seqn= seq->next;
1197                 if(seq->flag & SELECT) {
1198                         if(seq->type==SEQ_SOUND && seq->sound) seq->sound->id.us--;
1199                         BLI_remlink(lb, seq);
1200                         if(seq==last_seq) last_seq= 0;
1201                         if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase);
1202                         if(seq->ipo) seq->ipo->id.us--;
1203                         free_sequence(seq);
1204                 }
1205                 seq= seqn;
1206         }
1207 }
1208
1209 void del_seq(void)
1210 {
1211         Sequence *seq, *seqn;
1212         MetaStack *ms;
1213         Editing *ed;
1214         int doit;
1215
1216         if(okee("Erase selected")==0) return;
1217
1218         ed= G.scene->ed;
1219         if(ed==0) return;
1220
1221         recurs_del_seq(ed->seqbasep);
1222
1223         /* test effects */
1224         doit= 1;
1225         while(doit) {
1226                 doit= 0;
1227                 seq= ed->seqbasep->first;
1228                 while(seq) {
1229                         seqn= seq->next;
1230                         if(seq->type & SEQ_EFFECT) {
1231                                 if( is_a_sequence(seq->seq1)==0 || is_a_sequence(seq->seq2)==0 || is_a_sequence(seq->seq3)==0 ) {
1232                                         BLI_remlink(ed->seqbasep, seq);
1233                                         if(seq==last_seq) last_seq= 0;
1234                                         free_sequence(seq);
1235                                         doit= 1;
1236                                 }
1237                         }
1238                         seq= seqn;
1239                 }
1240         }
1241
1242         /* updates lengths etc */
1243         seq= ed->seqbasep->first;
1244         while(seq) {
1245                 calc_sequence(seq);
1246                 seq= seq->next;
1247         }
1248
1249         /* free parent metas */
1250         ms= ed->metastack.last;
1251         while(ms) {
1252                 ms->parseq->strip->len= 0;              /* force new alloc */
1253                 calc_sequence(ms->parseq);
1254                 ms= ms->prev;
1255         }
1256
1257         allqueue(REDRAWSEQ, 0);
1258 }
1259
1260
1261
1262 static void recurs_dupli_seq(ListBase *old, ListBase *new)
1263 {
1264         Sequence *seq, *seqn;
1265         StripElem *se;
1266         int a;
1267
1268         seq= old->first;
1269
1270         while(seq) {
1271                 seq->newseq= 0;
1272                 if(seq->flag & SELECT) {
1273
1274                         if(seq->type==SEQ_META) {
1275                                 seqn= MEM_dupallocN(seq);
1276                                 seq->newseq= seqn;
1277                                 BLI_addtail(new, seqn);
1278
1279                                 seqn->strip= MEM_dupallocN(seq->strip);
1280
1281                                 if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1282
1283                                 seq->flag &= SEQ_DESEL;
1284                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1285
1286                                 seqn->seqbase.first= seqn->seqbase.last= 0;
1287                                 recurs_dupli_seq(&seq->seqbase, &seqn->seqbase);
1288
1289                         }
1290                         else if(seq->type == SEQ_SCENE) {
1291                                 seqn= MEM_dupallocN(seq);
1292                                 seq->newseq= seqn;
1293                                 BLI_addtail(new, seqn);
1294
1295                                 seqn->strip= MEM_dupallocN(seq->strip);
1296
1297                                 if(seq->len>0) seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1298
1299                                 seq->flag &= SEQ_DESEL;
1300                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1301                         }
1302                         else if(seq->type == SEQ_MOVIE) {
1303                                 seqn= MEM_dupallocN(seq);
1304                                 seq->newseq= seqn;
1305                                 BLI_addtail(new, seqn);
1306
1307                                 seqn->strip= MEM_dupallocN(seq->strip);
1308                                 seqn->anim= 0;
1309
1310                                 if(seqn->len>0) {
1311                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1312                                         /* copy first elem */
1313                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1314                                         se= seqn->strip->stripdata;
1315                                         a= seq->len;
1316                                         while(a--) {
1317                                                 se->ok= 1;
1318                                                 se++;
1319                                         }
1320                                 }
1321
1322                                 seq->flag &= SEQ_DESEL;
1323                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1324                         }
1325                         else if(seq->type == SEQ_SOUND) {
1326                                 seqn= MEM_dupallocN(seq);
1327                                 seq->newseq= seqn;
1328                                 BLI_addtail(new, seqn);
1329
1330                                 seqn->strip= MEM_dupallocN(seq->strip);
1331                                 seqn->anim= 0;
1332                                 seqn->sound->id.us++;
1333                                 if(seqn->ipo) seqn->ipo->id.us++;
1334
1335                                 if(seqn->len>0) {
1336                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1337                                         /* copy first elem */
1338                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1339                                         se= seqn->strip->stripdata;
1340                                         a= seq->len;
1341                                         while(a--) {
1342                                                 se->ok= 1;
1343                                                 se++;
1344                                         }
1345                                 }
1346
1347                                 seq->flag &= SEQ_DESEL;
1348                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1349                         }
1350                         else if(seq->type < SEQ_EFFECT) {
1351                                 seqn= MEM_dupallocN(seq);
1352                                 seq->newseq= seqn;
1353                                 BLI_addtail(new, seqn);
1354
1355                                 seqn->strip->us++;
1356                                 seq->flag &= SEQ_DESEL;
1357
1358                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1359                         }
1360                         else {
1361                                 if(seq->seq1->newseq) {
1362
1363                                         seqn= MEM_dupallocN(seq);
1364                                         seq->newseq= seqn;
1365                                         BLI_addtail(new, seqn);
1366
1367                                         seqn->seq1= seq->seq1->newseq;
1368                                         if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
1369                                         if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
1370
1371                                         if(seqn->ipo) seqn->ipo->id.us++;
1372
1373                                         if(seq->plugin) {
1374                                                 seqn->plugin= MEM_dupallocN(seq->plugin);
1375                                                 open_plugin_seq(seqn->plugin, seqn->name+2);
1376                                         }
1377                                         seqn->strip= MEM_dupallocN(seq->strip);
1378
1379                                         if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1380
1381                                         seq->flag &= SEQ_DESEL;
1382
1383                                         seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1384                                 }
1385                         }
1386
1387                 }
1388                 seq= seq->next;
1389         }
1390 }
1391
1392 void add_duplicate_seq(void)
1393 {
1394         Editing *ed;
1395         ListBase new;
1396
1397         ed= G.scene->ed;
1398         if(ed==0) return;
1399
1400         new.first= new.last= 0;
1401
1402         recurs_dupli_seq(ed->seqbasep, &new);
1403         addlisttolist(ed->seqbasep, &new);
1404
1405         transform_seq('g');
1406 }
1407
1408 int insert_gap(int gap, int cfra)
1409 {
1410         Sequence *seq;
1411         Editing *ed;
1412         int done=0;
1413
1414         /* all strips >= cfra are shifted */
1415         ed= G.scene->ed;
1416         if(ed==0) return 0;
1417
1418         WHILE_SEQ(ed->seqbasep) {
1419                 if(seq->startdisp >= cfra) {
1420                         seq->start+= gap;
1421                         calc_sequence(seq);
1422                         done= 1;
1423                 }
1424         }
1425         END_SEQ
1426
1427         return done;
1428 }
1429
1430 void touch_seq_files(void)
1431 {
1432         Sequence *seq;
1433         Editing *ed;
1434         char str[256];
1435
1436         /* touch all strips with movies */
1437         ed= G.scene->ed;
1438         if(ed==0) return;
1439
1440         if(okee("Touch and print selected movies")==0) return;
1441
1442         waitcursor(1);
1443
1444         WHILE_SEQ(ed->seqbasep) {
1445                 if(seq->flag & SELECT) {
1446                         if(seq->type==SEQ_MOVIE) {
1447                                 if(seq->strip && seq->strip->stripdata) {
1448                                         BLI_make_file_string(G.sce, str, seq->strip->dir, seq->strip->stripdata->name);
1449                                         BLI_touch(seq->name);
1450                                 }
1451                         }
1452
1453                 }
1454         }
1455         END_SEQ
1456
1457         waitcursor(0);
1458 }
1459
1460 void set_filter_seq(void)
1461 {
1462         Sequence *seq;
1463         Editing *ed;
1464
1465         ed= G.scene->ed;
1466         if(ed==0) return;
1467
1468         if(okee("Set FilterY")==0) return;
1469
1470         WHILE_SEQ(ed->seqbasep) {
1471                 if(seq->flag & SELECT) {
1472                         if(seq->type==SEQ_MOVIE) {
1473                                 seq->flag |= SEQ_FILTERY;
1474                         }
1475
1476                 }
1477         }
1478         END_SEQ
1479
1480 }
1481
1482
1483
1484 void no_gaps(void)
1485 {
1486         Editing *ed;
1487         int cfra, first= 0, done;
1488
1489         ed= G.scene->ed;
1490         if(ed==0) return;
1491
1492         for(cfra= CFRA; cfra<=EFRA; cfra++) {
1493                 if(first==0) {
1494                         if( evaluate_seq_frame(cfra) ) first= 1;
1495                 }
1496                 else {
1497                         done= 1;
1498                         while( evaluate_seq_frame(cfra) == 0) {
1499                                 done= insert_gap(-1, cfra);
1500                                 if(done==0) break;
1501                         }
1502                         if(done==0) break;
1503                 }
1504         }
1505         allqueue(REDRAWSEQ, 0);
1506 }
1507
1508
1509 /* ****************** META ************************* */
1510
1511 void make_meta(void)
1512 {
1513         Sequence *seq, *seqm, *next;
1514         Editing *ed;
1515         int tot;
1516
1517         ed= G.scene->ed;
1518         if(ed==0) return;
1519
1520         /* is there more than 1 select */
1521         tot= 0;
1522         seq= ed->seqbasep->first;
1523         while(seq) {
1524                 if(seq->flag & SELECT) {
1525                         tot++;
1526                         if (seq->type == SEQ_SOUND) { error("Can't make Meta Strip from audio"); return; }
1527                 }
1528                 seq= seq->next;
1529         }
1530         if(tot < 2) return;
1531
1532         if(okee("Make Meta Strip")==0) return;
1533
1534         /* test relationships */
1535         seq= ed->seqbasep->first;
1536         while(seq) {
1537                 if(seq->flag & SELECT) {
1538                         if(seq->type & SEQ_EFFECT) {
1539                                 if((seq->seq1->flag & SELECT)==0) tot= 0;
1540                                 if((seq->seq2->flag & SELECT)==0) tot= 0;
1541                                 if((seq->seq3->flag & SELECT)==0) tot= 0;
1542                         }
1543                 }
1544                 else if(seq->type & SEQ_EFFECT) {
1545                         if(seq->seq1->flag & SELECT) tot= 0;
1546                         if(seq->seq2->flag & SELECT) tot= 0;
1547                         if(seq->seq3->flag & SELECT) tot= 0;
1548                 }
1549                 if(tot==0) break;
1550                 seq= seq->next;
1551         }
1552         if(tot==0) {
1553                 error("Please select all related strips");
1554                 return;
1555         }
1556
1557         /* remove all selected from main list, and put in meta */
1558
1559         seqm= alloc_sequence(1, 1);
1560         seqm->type= SEQ_META;
1561         seqm->flag= SELECT;
1562
1563         seq= ed->seqbasep->first;
1564         while(seq) {
1565                 next= seq->next;
1566                 if(seq!=seqm && (seq->flag & SELECT)) {
1567                         BLI_remlink(ed->seqbasep, seq);
1568                         BLI_addtail(&seqm->seqbase, seq);
1569                 }
1570                 seq= next;
1571         }
1572         calc_sequence(seqm);
1573
1574         seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
1575         seqm->strip->len= seqm->len;
1576         seqm->strip->us= 1;
1577         if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata");
1578
1579         set_meta_stripdata(seqm);
1580
1581         allqueue(REDRAWSEQ, 0);
1582 }
1583
1584 void un_meta(void)
1585 {
1586         Editing *ed;
1587         Sequence *seq, *seqn;
1588         int doit;
1589
1590         ed= G.scene->ed;
1591         if(ed==0) return;
1592
1593         if(last_seq==0 || last_seq->type!=SEQ_META) return;
1594
1595         if(okee("Un Meta")==0) return;
1596
1597         addlisttolist(ed->seqbasep, &last_seq->seqbase);
1598
1599         last_seq->seqbase.first= 0;
1600         last_seq->seqbase.last= 0;
1601
1602         BLI_remlink(ed->seqbasep, last_seq);
1603         free_sequence(last_seq);
1604
1605         /* test effects */
1606         doit= 1;
1607         while(doit) {
1608                 doit= 0;
1609                 seq= ed->seqbasep->first;
1610                 while(seq) {
1611                         seqn= seq->next;
1612                         if(seq->type & SEQ_EFFECT) {
1613                                 if( is_a_sequence(seq->seq1)==0 || is_a_sequence(seq->seq2)==0 || is_a_sequence(seq->seq3)==0 ) {
1614                                         BLI_remlink(ed->seqbasep, seq);
1615                                         if(seq==last_seq) last_seq= 0;
1616                                         free_sequence(seq);
1617                                         doit= 1;
1618                                 }
1619                         }
1620                         seq= seqn;
1621                 }
1622         }
1623
1624
1625         /* test for effects and overlap */
1626         WHILE_SEQ(ed->seqbasep) {
1627                 if(seq->flag & SELECT) {
1628                         seq->flag &= ~SEQ_OVERLAP;
1629                         if( test_overlap_seq(seq) ) {
1630                                 shuffle_seq(seq);
1631                         }
1632                 }
1633         }
1634         END_SEQ;
1635
1636         allqueue(REDRAWSEQ, 0);
1637
1638 }
1639
1640 void exit_meta(void)
1641 {
1642         Sequence *seq;
1643         MetaStack *ms;
1644         Editing *ed;
1645
1646         ed= G.scene->ed;
1647         if(ed==0) return;
1648
1649         if(ed->metastack.first==0) return;
1650
1651         ms= ed->metastack.last;
1652         BLI_remlink(&ed->metastack, ms);
1653
1654         ed->seqbasep= ms->oldbasep;
1655
1656         /* recalc entire meta */
1657         set_meta_stripdata(ms->parseq);
1658
1659         /* recalc all: the meta can have effects connected to it */
1660         seq= ed->seqbasep->first;
1661         while(seq) {
1662                 calc_sequence(seq);
1663                 seq= seq->next;
1664         }
1665
1666         last_seq= ms->parseq;
1667
1668         last_seq->flag= SELECT;
1669         recurs_sel_seq(last_seq);
1670
1671         MEM_freeN(ms);
1672         allqueue(REDRAWSEQ, 0);
1673 }
1674
1675
1676 void enter_meta(void)
1677 {
1678         MetaStack *ms;
1679         Editing *ed;
1680
1681         ed= G.scene->ed;
1682         if(ed==0) return;
1683
1684         if(last_seq==0 || last_seq->type!=SEQ_META || last_seq->flag==0) {
1685                 exit_meta();
1686                 return;
1687         }
1688
1689         ms= MEM_mallocN(sizeof(MetaStack), "metastack");
1690         BLI_addtail(&ed->metastack, ms);
1691         ms->parseq= last_seq;
1692         ms->oldbasep= ed->seqbasep;
1693
1694         ed->seqbasep= &last_seq->seqbase;
1695
1696         last_seq= 0;
1697         allqueue(REDRAWSEQ, 0);
1698 }
1699
1700
1701 /* ****************** END META ************************* */
1702
1703
1704 typedef struct TransSeq {
1705         int start, machine;
1706         int startstill, endstill;
1707         int startofs, endofs;
1708 } TransSeq;
1709
1710 void transform_seq(int mode)
1711 {
1712         Sequence *seq;
1713         Editing *ed;
1714         float dx, dy, dvec[2], div;
1715         TransSeq *transmain, *ts;
1716         int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0;
1717         unsigned short event = 0;
1718         short mval[2], val, xo, yo, xn, yn;
1719         char str[32];
1720
1721         if(mode!='g') return;   /* from gesture */
1722
1723         /* which seqs are involved */
1724         ed= G.scene->ed;
1725         if(ed==0) return;
1726
1727         WHILE_SEQ(ed->seqbasep) {
1728                 if(seq->flag & SELECT) tot++;
1729         }
1730         END_SEQ
1731
1732         if(tot==0) return;
1733
1734         G.moving= 1;
1735
1736         ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
1737
1738         WHILE_SEQ(ed->seqbasep) {
1739
1740                 if(seq->flag & SELECT) {
1741
1742                         ts->start= seq->start;
1743                         ts->machine= seq->machine;
1744                         ts->startstill= seq->startstill;
1745                         ts->endstill= seq->endstill;
1746                         ts->startofs= seq->startofs;
1747                         ts->endofs= seq->endofs;
1748
1749                         ts++;
1750                 }
1751         }
1752         END_SEQ
1753
1754         getmouseco_areawin(mval);
1755         xo=xn= mval[0];
1756         yo=yn= mval[1];
1757         dvec[0]= dvec[1]= 0.0;
1758
1759         while(afbreek==0) {
1760                 getmouseco_areawin(mval);
1761                 if(mval[0]!=xo || mval[1]!=yo || firsttime) {
1762                         firsttime= 0;
1763
1764                         if(mode=='g') {
1765
1766                                 dx= mval[0]- xo;
1767                                 dy= mval[1]- yo;
1768
1769                                 div= G.v2d->mask.xmax-G.v2d->mask.xmin;
1770                                 dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
1771
1772                                 div= G.v2d->mask.ymax-G.v2d->mask.ymin;
1773                                 dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
1774
1775                                 if(G.qual & LR_SHIFTKEY) {
1776                                         if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
1777                                 }
1778
1779                                 dvec[0]+= dx;
1780                                 dvec[1]+= dy;
1781
1782                                 if(midtog) dvec[proj]= 0.0;
1783                                 ix= floor(dvec[0]+0.5);
1784                                 iy= floor(dvec[1]+0.5);
1785
1786
1787                                 ts= transmain;
1788
1789                                 WHILE_SEQ(ed->seqbasep) {
1790                                         if(seq->flag & SELECT) {
1791                                                 if(seq->flag & SEQ_LEFTSEL) {
1792                                                         if(ts->startstill) {
1793                                                                 seq->startstill= ts->startstill-ix;
1794                                                                 if(seq->startstill<0) seq->startstill= 0;
1795                                                         }
1796                                                         else if(ts->startofs) {
1797                                                                 seq->startofs= ts->startofs+ix;
1798                                                                 if(seq->startofs<0) seq->startofs= 0;
1799                                                         }
1800                                                         else {
1801                                                                 if(ix>0) {
1802                                                                         seq->startofs= ix;
1803                                                                         seq->startstill= 0;
1804                                                                 }
1805                                                                 else if (seq->type != SEQ_SOUND) {
1806                                                                         seq->startstill= -ix;
1807                                                                         seq->startofs= 0;
1808                                                                 }
1809                                                         }
1810                                                         if(seq->len <= seq->startofs+seq->endofs) {
1811                                                                 seq->startofs= seq->len-seq->endofs-1;
1812                                                         }
1813                                                 }
1814                                                 if(seq->flag & SEQ_RIGHTSEL) {
1815                                                         if(ts->endstill) {
1816                                                                 seq->endstill= ts->endstill+ix;
1817                                                                 if(seq->endstill<0) seq->endstill= 0;
1818                                                         }
1819                                                         else if(ts->endofs) {
1820                                                                 seq->endofs= ts->endofs-ix;
1821                                                                 if(seq->endofs<0) seq->endofs= 0;
1822                                                         }
1823                                                         else {
1824                                                                 if(ix<0) {
1825                                                                         seq->endofs= -ix;
1826                                                                         seq->endstill= 0;
1827                                                                 }
1828                                                                 else if (seq->type != SEQ_SOUND) {
1829                                                                         seq->endstill= ix;
1830                                                                         seq->endofs= 0;
1831                                                                 }
1832                                                         }
1833                                                         if(seq->len <= seq->startofs+seq->endofs) {
1834                                                                 seq->endofs= seq->len-seq->startofs-1;
1835                                                         }
1836                                                 }
1837                                                 if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
1838                                                         if(seq->type<SEQ_EFFECT) seq->start= ts->start+ ix;
1839
1840                                                         if(seq->depth==0) seq->machine= ts->machine+ iy;
1841
1842                                                         if(seq->machine<1) seq->machine= 1;
1843                                                         else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
1844                                                 }
1845
1846                                                 calc_sequence(seq);
1847
1848                                                 ts++;
1849                                         }
1850                                 }
1851                                 END_SEQ
1852
1853                                 sprintf(str, "X: %d   Y: %d  ", ix, iy);
1854                                 headerprint(str);
1855                         }
1856
1857                         xo= mval[0];
1858                         yo= mval[1];
1859
1860                         /* test for effect and overlap */
1861
1862                         WHILE_SEQ(ed->seqbasep) {
1863                                 if(seq->flag & SELECT) {
1864                                         seq->flag &= ~SEQ_OVERLAP;
1865                                         if( test_overlap_seq(seq) ) {
1866                                                 seq->flag |= SEQ_OVERLAP;
1867                                         }
1868                                 }
1869                                 else if(seq->type & SEQ_EFFECT) {
1870                                         if(seq->seq1->flag & SELECT) calc_sequence(seq);
1871                                         else if(seq->seq2->flag & SELECT) calc_sequence(seq);
1872                                         else if(seq->seq3->flag & SELECT) calc_sequence(seq);
1873                                 }
1874                         }
1875                         END_SEQ;
1876
1877                         force_draw(0);
1878                 }
1879                 else BIF_wait_for_statechange();
1880
1881                 while(qtest()) {
1882                         event= extern_qread(&val);
1883                         if(val) {
1884                                 switch(event) {
1885                                 case ESCKEY:
1886                                 case LEFTMOUSE:
1887                                 case SPACEKEY:
1888                                         afbreek= 1;
1889                                         break;
1890                                 case MIDDLEMOUSE:
1891                                         midtog= ~midtog;
1892                                         if(midtog) {
1893                                                 if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1;
1894                                                 else proj= 0;
1895                                                 firsttime= 1;
1896                                         }
1897                                         break;
1898                                 default:
1899                                         arrows_move_cursor(event);
1900                                 }
1901                         }
1902                         if(afbreek) break;
1903                 }
1904         }
1905
1906         if(event==ESCKEY) {
1907
1908                 ts= transmain;
1909                 WHILE_SEQ(ed->seqbasep) {
1910                         if(seq->flag & SELECT) {
1911                                 seq->start= ts->start;
1912                                 seq->machine= ts->machine;
1913                                 seq->startstill= ts->startstill;
1914                                 seq->endstill= ts->endstill;
1915                                 seq->startofs= ts->startofs;
1916                                 seq->endofs= ts->endofs;
1917
1918                                 calc_sequence(seq);
1919                                 seq->flag &= ~SEQ_OVERLAP;
1920
1921                                 ts++;
1922                         } else if(seq->type & SEQ_EFFECT) {
1923                                 if(seq->seq1->flag & SELECT) calc_sequence(seq);
1924                                 else if(seq->seq2->flag & SELECT) calc_sequence(seq);
1925                                 else if(seq->seq3->flag & SELECT) calc_sequence(seq);
1926                         }
1927
1928                 }
1929                 END_SEQ
1930         }
1931         else {
1932
1933                 /* images, effects and overlap */
1934                 WHILE_SEQ(ed->seqbasep) {
1935                         if(seq->type == SEQ_META) {
1936                                 calc_sequence(seq);
1937                                 seq->flag &= ~SEQ_OVERLAP;
1938                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
1939                         }
1940                         else if(seq->flag & SELECT) {
1941                                 calc_sequence(seq);
1942                                 seq->flag &= ~SEQ_OVERLAP;
1943                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
1944                         }
1945                         else if(seq->type & SEQ_EFFECT) calc_sequence(seq);
1946                 }
1947                 END_SEQ
1948
1949                 /* as last: */
1950                 sort_seq();
1951         }
1952
1953         G.moving= 0;
1954         MEM_freeN(transmain);
1955
1956         allqueue(REDRAWSEQ, 0);
1957 }
1958
1959
1960 void clever_numbuts_seq(void)
1961 {
1962         PluginSeq *pis;
1963         StripElem *se;
1964         VarStruct *varstr;
1965         int a;
1966
1967         if(last_seq==0) return;
1968         if(last_seq->type==SEQ_PLUGIN) {
1969                 pis= last_seq->plugin;
1970                 if(pis->vars==0) return;
1971
1972                 varstr= pis->varstr;
1973                 if(varstr) {
1974                         for(a=0; a<pis->vars; a++, varstr++) {
1975                                 add_numbut(a, varstr->type, varstr->name, varstr->min, varstr->max, &(pis->data[a]), varstr->tip);
1976                         }
1977
1978                         if( do_clever_numbuts(pis->pname, pis->vars, REDRAW) ) {
1979                                 new_stripdata(last_seq);
1980                                 free_imbuf_effect_spec(CFRA);
1981                                 allqueue(REDRAWSEQ, 0);
1982                         }
1983                 }
1984         }
1985         else if(last_seq->type==SEQ_MOVIE) {
1986
1987                 if(last_seq->mul==0.0) last_seq->mul= 1.0;
1988
1989                 add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
1990                 add_numbut(1, TOG|SHO|BIT|4, "FilterY", 0.0, 1.0, &last_seq->flag, 0);
1991                 /* warning: only a single bit-button possible: we work at copied data! */
1992                 add_numbut(2, NUM|FLO, "Mul", 0.01, 5.0, &last_seq->mul, 0);
1993
1994                 if( do_clever_numbuts("Movie", 3, REDRAW) ) {
1995                         se= last_seq->curelem;
1996
1997                         if(se && se->ibuf ) {
1998                                 IMB_freeImBuf(se->ibuf);
1999                                 se->ibuf= 0;
2000                         }
2001                         allqueue(REDRAWSEQ, 0);
2002                 }
2003         }
2004         else if(last_seq->type==SEQ_SOUND) {
2005
2006                 add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
2007                 add_numbut(1, NUM|FLO, "Gain (dB):", -96.0, 6.0, &last_seq->level, 0);
2008                 add_numbut(2, NUM|FLO, "Pan:", -1.0, 1.0, &last_seq->pan, 0);
2009                 add_numbut(3, TOG|SHO|BIT|5, "Mute", 0.0, 1.0, &last_seq->flag, 0);
2010
2011                 if( do_clever_numbuts("Audio", 4, REDRAW) ) {
2012                         se= last_seq->curelem;
2013                         allqueue(REDRAWSEQ, 0);
2014                 }
2015         }
2016         else if(last_seq->type==SEQ_META) {
2017
2018                 add_numbut(0, TEX, "Name:", 0.0, 21.0, last_seq->name+2, 0);
2019
2020                 if( do_clever_numbuts("Meta", 1, REDRAW) ) {
2021                         allqueue(REDRAWSEQ, 0);
2022                 }
2023         }
2024 }
2025
2026 void seq_snap_menu(void)
2027 {
2028         short event;
2029
2030         event= pupmenu("Snap %t|To Current Frame%x1");
2031         if(event < 1) return;
2032
2033         seq_snap(event);
2034 }
2035
2036 void seq_snap(short event)
2037 {
2038         Editing *ed;
2039         Sequence *seq;
2040
2041         ed= G.scene->ed;
2042         if(ed==0) return;
2043
2044         /* problem: contents of meta's are all shifted to the same position... */
2045
2046         /* also check metas */
2047         WHILE_SEQ(ed->seqbasep) {
2048                 if(seq->flag & SELECT) {
2049                         if(seq->type<SEQ_EFFECT) seq->start= CFRA-seq->startofs+seq->startstill;
2050                         calc_sequence(seq);
2051                 }
2052         }
2053         END_SEQ
2054
2055
2056         /* test for effects and overlap */
2057         WHILE_SEQ(ed->seqbasep) {
2058                 if(seq->flag & SELECT) {
2059                         seq->flag &= ~SEQ_OVERLAP;
2060                         if( test_overlap_seq(seq) ) {
2061                                 shuffle_seq(seq);
2062                         }
2063                 }
2064                 else if(seq->type & SEQ_EFFECT) {
2065                         if(seq->seq1->flag & SELECT) calc_sequence(seq);
2066                         else if(seq->seq2->flag & SELECT) calc_sequence(seq);
2067                         else if(seq->seq3->flag & SELECT) calc_sequence(seq);
2068                 }
2069         }
2070         END_SEQ;
2071
2072         /* as last: */
2073         sort_seq();
2074
2075         allqueue(REDRAWSEQ, 0);
2076 }
2077
2078 void borderselect_seq(void)
2079 {
2080         Sequence *seq;
2081         Editing *ed;
2082         rcti rect;
2083         rctf rectf, rq;
2084         int val;
2085         short mval[2];
2086
2087         ed= G.scene->ed;
2088         if(ed==0) return;
2089
2090         val= get_border(&rect, 3);
2091
2092         if(val) {
2093                 mval[0]= rect.xmin;
2094                 mval[1]= rect.ymin;
2095                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
2096                 mval[0]= rect.xmax;
2097                 mval[1]= rect.ymax;
2098                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
2099
2100                 seq= ed->seqbasep->first;
2101                 while(seq) {
2102
2103                         if(seq->startstill) rq.xmin= seq->start;
2104                         else rq.xmin= seq->startdisp;
2105                         rq.ymin= seq->machine+0.2;
2106                         if(seq->endstill) rq.xmax= seq->start+seq->len;
2107                         else rq.xmax= seq->enddisp;
2108                         rq.ymax= seq->machine+0.8;
2109
2110                         if(BLI_isect_rctf(&rq, &rectf, 0)) {
2111                                 if(val==LEFTMOUSE) {
2112                                         seq->flag |= SELECT;
2113                                 }
2114                                 else {
2115                                         seq->flag &= ~SELECT;
2116                                 }
2117                         }
2118
2119                         seq= seq->next;
2120                 }
2121
2122                 addqueue(curarea->win, REDRAW, 1);
2123         }
2124 }