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