968d1965ef479db6b543e9574870479ea60e0885
[blender-staging.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_curve_types.h"
59 #include "DNA_scene_types.h"
60 #include "DNA_screen_types.h"
61 #include "DNA_space_types.h"
62 #include "DNA_sequence_types.h"
63 #include "DNA_view2d_types.h"
64 #include "DNA_userdef_types.h"
65 #include "DNA_sound_types.h"
66
67 #include "BKE_utildefines.h"
68 #include "BKE_plugin_types.h"
69 #include "BKE_global.h"
70 #include "BKE_image.h"
71 #include "BKE_library.h"
72 #include "BKE_main.h"
73 #include "BKE_scene.h"
74
75 #include "BIF_space.h"
76 #include "BIF_interface.h"
77 #include "BIF_screen.h"
78 #include "BIF_drawseq.h"
79 #include "BIF_editseq.h"
80 #include "BIF_mywindow.h"
81 #include "BIF_toolbox.h"
82 #include "BIF_writemovie.h"
83 #include "BIF_editview.h"
84 #include "BIF_scrarea.h"
85 #include "BIF_editsound.h"
86
87 #include "BSE_edit.h"
88 #include "BSE_sequence.h"
89 #include "BSE_seqeffects.h"
90 #include "BSE_filesel.h"
91 #include "BSE_drawipo.h"
92 #include "BSE_seqaudio.h"
93
94 #include "BDR_editobject.h"
95
96 #include "blendef.h"
97 #include "mydevice.h"
98
99 static Sequence *_last_seq=0;
100 static int _last_seq_init=0;
101
102 #ifdef WIN32
103 char last_imagename[FILE_MAXDIR+FILE_MAXFILE]= "c:\\";
104 #else
105 char last_imagename[FILE_MAXDIR+FILE_MAXFILE]= "/";
106 #endif
107
108 char last_sounddir[FILE_MAXDIR+FILE_MAXFILE]= "";
109
110 #define SEQ_DESEL       ~(SELECT+SEQ_LEFTSEL+SEQ_RIGHTSEL)
111
112 static int test_overlap_seq(Sequence *);
113 static void shuffle_seq(Sequence *);
114
115 Sequence *get_last_seq()
116 {
117         if(!_last_seq_init) {
118                 Editing *ed;
119                 Sequence *seq;
120
121                 ed= G.scene->ed;
122                 if(!ed) return NULL;
123
124                 for(seq= ed->seqbasep->first; seq; seq=seq->next)
125                         if(seq->flag & SELECT)
126                                 _last_seq= seq;
127
128                 _last_seq_init = 1;
129         }
130
131         return _last_seq;
132 }
133
134 void set_last_seq(Sequence *seq)
135 {
136         _last_seq = seq;
137         _last_seq_init = 1;
138 }
139
140 void clear_last_seq()
141 {
142         _last_seq = NULL;
143         _last_seq_init = 0;
144 }
145
146 static void change_plugin_seq(char *str)        /* called from fileselect */
147 {
148         struct SeqEffectHandle sh;
149         Sequence *last_seq= get_last_seq();
150
151         if(last_seq && last_seq->type != SEQ_PLUGIN) return;
152
153         sh = get_sequence_effect(last_seq);
154         sh.free(last_seq);
155         sh.init_plugin(last_seq, str);
156
157         last_seq->machine = MAX3(last_seq->seq1->machine, 
158                                  last_seq->seq2->machine, 
159                                  last_seq->seq3->machine);
160
161         if( test_overlap_seq(last_seq) ) shuffle_seq(last_seq);
162         
163         BIF_undo_push("Load/change Sequencer plugin");
164 }
165
166
167 void boundbox_seq(void)
168 {
169         Sequence *seq;
170         Editing *ed;
171         float min[2], max[2];
172
173         ed= G.scene->ed;
174         if(ed==0) return;
175
176         min[0]= 0.0;
177         max[0]= EFRA+1;
178         min[1]= 0.0;
179         max[1]= 8.0;
180
181         seq= ed->seqbasep->first;
182         while(seq) {
183
184                 if( min[0] > seq->startdisp-1) min[0]= seq->startdisp-1;
185                 if( max[0] < seq->enddisp+1) max[0]= seq->enddisp+1;
186                 if( max[1] < seq->machine+2.0) max[1]= seq->machine+2.0;
187
188                 seq= seq->next;
189         }
190
191         G.v2d->tot.xmin= min[0];
192         G.v2d->tot.xmax= max[0];
193         G.v2d->tot.ymin= min[1];
194         G.v2d->tot.ymax= max[1];
195
196 }
197
198 int sequence_is_free_transformable(Sequence * seq)
199 {
200         return seq->type < SEQ_EFFECT
201                 || (get_sequence_effect_num_inputs(seq->type) == 0);
202 }
203
204 Sequence *find_nearest_seq(int *hand)
205 {
206         Sequence *seq;
207         Editing *ed;
208         float x, y;
209         short mval[2];
210         float pixelx;
211         float handsize;
212         float minhandle, maxhandle;
213         View2D *v2d = G.v2d;
214         *hand= 0;
215
216         ed= G.scene->ed;
217         if(ed==0) return 0;
218         
219         pixelx = (v2d->cur.xmax - v2d->cur.xmin)/(v2d->mask.xmax - v2d->mask.xmin);
220
221         getmouseco_areawin(mval);
222         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
223         
224         seq= ed->seqbasep->first;
225         
226         while(seq) {
227                 /* clamp handles to defined size in pixel space */
228                 handsize = seq->handsize;
229                 minhandle = 7;
230                 maxhandle = 28;
231                 CLAMP(handsize, minhandle*pixelx, maxhandle*pixelx);
232                 
233                 if(seq->machine == (int)y) {
234                         /* check for both normal strips, and strips that have been flipped horizontally */
235                         if( ((seq->startdisp < seq->enddisp) && (seq->startdisp<=x && seq->enddisp>=x)) ||
236                                 ((seq->startdisp > seq->enddisp) && (seq->startdisp>=x && seq->enddisp<=x)) )
237                         {
238                                 if(sequence_is_free_transformable(seq)) {
239                                         if( handsize+seq->startdisp >=x )
240                                                 *hand= 1;
241                                         else if( -handsize+seq->enddisp <=x )
242                                                 *hand= 2;
243                                 }
244                                 return seq;
245                         }
246                 }
247                 seq= seq->next;
248         }
249         return 0;
250 }
251
252 void update_seq_ipo_rect(Sequence * seq)
253 {
254         float start;
255         float end;
256
257         if (!seq || !seq->ipo) {
258                 return;
259         }
260         start =  -5.0;
261         end   =  105.0;
262
263         /* Adjust IPO window to sequence and 
264            avoid annoying snap-back to startframe 
265            when Lock Time is on */
266         if (G.v2d->flag & V2D_VIEWLOCK) {
267                 if ((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) {
268                         start = -5.0 + seq->startdisp;
269                         end = 5.0 + seq->enddisp;
270                 } else {
271                         start = (float)G.scene->r.sfra - 0.1;
272                         end = G.scene->r.efra;
273                 }
274         }
275
276         seq->ipo->cur.xmin= start;
277         seq->ipo->cur.xmax= end;
278 }
279
280 void update_seq_icu_rects(Sequence * seq)
281 {
282         IpoCurve *icu= NULL;
283         struct SeqEffectHandle sh;
284
285         if (!seq || !seq->ipo) {
286                 return;
287         }
288
289         if(!(seq->type & SEQ_EFFECT)) {
290                 return;
291         }
292
293         sh = get_sequence_effect(seq);
294
295         for(icu= seq->ipo->curve.first; icu; icu= icu->next) {
296                 sh.store_icu_yrange(seq, icu->adrcode, &icu->ymin, &icu->ymax);
297         }
298 }
299
300 static int test_overlap_seq(Sequence *test)
301 {
302         Sequence *seq;
303         Editing *ed;
304
305         ed= G.scene->ed;
306         if(ed==0) return 0;
307
308         seq= ed->seqbasep->first;
309         while(seq) {
310                 if(seq!=test) {
311                         if(test->machine==seq->machine) {
312                                 if(test->depth==seq->depth) {
313                                         if( (test->enddisp <= seq->startdisp) || (test->startdisp >= seq->enddisp) );
314                                         else return 1;
315                                 }
316                         }
317                 }
318                 seq= seq->next;
319         }
320         return 0;
321 }
322
323 static void shuffle_seq(Sequence *test)
324 {
325         Editing *ed;
326         Sequence *seq;
327         int a, start;
328
329         ed= G.scene->ed;
330         if(ed==0) return;
331
332         /* is there more than 1 select: only shuffle y */
333         a=0;
334         seq= ed->seqbasep->first;
335         while(seq) {
336                 if(seq->flag & SELECT) a++;
337                 seq= seq->next;
338         }
339
340         if(a<2 && test->type==SEQ_IMAGE) {
341                 start= test->start;
342
343                 for(a= 1; a<50; a++) {
344                         test->start= start+a;
345                         calc_sequence(test);
346                         if( test_overlap_seq(test)==0) return;
347                         test->start= start-a;
348                         calc_sequence(test);
349                         if( test_overlap_seq(test)==0) return;
350                 }
351                 test->start= start;
352         }
353
354         test->machine++;
355         calc_sequence(test);
356         while( test_overlap_seq(test) ) {
357                 if(test->machine >= MAXSEQ) {
358                         error("There is no more space to add a sequence strip");
359
360                         BLI_remlink(ed->seqbasep, test);
361                         free_sequence(test);
362                         return;
363                 }
364                 test->machine++;
365                 calc_sequence(test);
366         }
367 }
368
369 static int seq_is_parent(Sequence *par, Sequence *seq)
370 {
371         return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq));
372 }
373
374 static int seq_is_predecessor(Sequence *pred, Sequence *seq)
375 {
376         if(pred == seq) return 0;
377         else if(seq_is_parent(pred, seq)) return 1;
378         else if(pred->seq1 && seq_is_predecessor(pred->seq1, seq)) return 1;
379         else if(pred->seq2 && seq_is_predecessor(pred->seq2, seq)) return 1;
380         else if(pred->seq3 && seq_is_predecessor(pred->seq3, seq)) return 1;
381
382         return 0;
383 }
384
385 static void deselect_all_seq(void)
386 {
387         Sequence *seq;
388         Editing *ed;
389
390         ed= G.scene->ed;
391         if(ed==0) return;
392
393         WHILE_SEQ(ed->seqbasep) {
394                 seq->flag &= SEQ_DESEL;
395         }
396         END_SEQ
397                 
398         BIF_undo_push("(De)select all Sequencer");
399 }
400
401 static void recurs_sel_seq(Sequence *seqm)
402 {
403         Sequence *seq;
404
405         seq= seqm->seqbase.first;
406         while(seq) {
407
408                 if(seqm->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL)) seq->flag &= SEQ_DESEL;
409                 else if(seqm->flag & SELECT) seq->flag |= SELECT;
410                 else seq->flag &= SEQ_DESEL;
411
412                 if(seq->seqbase.first) recurs_sel_seq(seq);
413
414                 seq= seq->next;
415         }
416 }
417
418 void swap_select_seq(void)
419 {
420         Sequence *seq;
421         Editing *ed;
422         int sel=0;
423
424         ed= G.scene->ed;
425         if(ed==0) return;
426
427         WHILE_SEQ(ed->seqbasep) {
428                 if(seq->flag & SELECT) sel= 1;
429         }
430         END_SEQ
431
432         WHILE_SEQ(ed->seqbasep) {
433                 /* always deselect all to be sure */
434                 seq->flag &= SEQ_DESEL;
435                 if(sel==0) seq->flag |= SELECT;
436         }
437         END_SEQ
438
439         allqueue(REDRAWSEQ, 0);
440         BIF_undo_push("Swap select all Sequencer");
441
442 }
443
444 void mouse_select_seq(void)
445 {
446         Sequence *seq;
447         int hand;
448
449         seq= find_nearest_seq(&hand);
450
451         if(!(G.qual & LR_SHIFTKEY)) deselect_all_seq();
452
453         if(seq) {
454                 set_last_seq(seq);
455
456                 if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) {
457                         if(seq->strip) {
458                                 strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
459                         }
460                 } else
461                 if (seq->type == SEQ_HD_SOUND || seq->type == SEQ_RAM_SOUND) {
462                         if(seq->strip) {
463                                 strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
464                         }
465                 }
466
467                 if((G.qual & LR_SHIFTKEY) && (seq->flag & SELECT)) {
468                         if(hand==0) seq->flag &= SEQ_DESEL;
469                         else if(hand==1) {
470                                 if(seq->flag & SEQ_LEFTSEL) 
471                                         seq->flag &= ~SEQ_LEFTSEL;
472                                 else seq->flag |= SEQ_LEFTSEL;
473                         }
474                         else if(hand==2) {
475                                 if(seq->flag & SEQ_RIGHTSEL) 
476                                         seq->flag &= ~SEQ_RIGHTSEL;
477                                 else seq->flag |= SEQ_RIGHTSEL;
478                         }
479                 }
480                 else {
481                         seq->flag |= SELECT;
482                         if(hand==1) seq->flag |= SEQ_LEFTSEL;
483                         if(hand==2) seq->flag |= SEQ_RIGHTSEL;
484                 }
485                 recurs_sel_seq(seq);
486         }
487
488         force_draw(0);
489
490         if(get_last_seq()) allqueue(REDRAWIPO, 0);
491         BIF_undo_push("Select Sequencer");
492
493         std_rmouse_transform(transform_seq);
494 }
495
496
497 Sequence *alloc_sequence(ListBase *lb, int cfra, int machine)
498 {
499         Sequence *seq;
500
501         /*ed= G.scene->ed;*/
502
503         seq= MEM_callocN( sizeof(Sequence), "addseq");
504         BLI_addtail(lb, seq);
505
506         set_last_seq(seq);
507
508         *( (short *)seq->name )= ID_SEQ;
509         seq->name[2]= 0;
510
511         seq->flag= SELECT;
512         seq->start= cfra;
513         seq->machine= machine;
514         seq->mul= 1.0;
515         
516         return seq;
517 }
518
519 static Sequence *sfile_to_sequence(SpaceFile *sfile, int cfra, int machine, int last)
520 {
521         Sequence *seq;
522         Strip *strip;
523         StripElem *se;
524         int totsel, a;
525         char name[160], rel[160];
526
527         /* are there selected files? */
528         totsel= 0;
529         for(a=0; a<sfile->totfile; a++) {
530                 if(sfile->filelist[a].flags & ACTIVE) {
531                         if( (sfile->filelist[a].type & S_IFDIR)==0 ) {
532                                 totsel++;
533                         }
534                 }
535         }
536
537         if(last) {
538                 /* if not, a file handed to us? */
539                 if(totsel==0 && sfile->file[0]) totsel= 1;
540         }
541
542         if(totsel==0) return 0;
543
544         /* make seq */
545         seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
546         seq->len= totsel;
547
548         if(totsel==1) {
549                 seq->startstill= 25;
550                 seq->endstill= 24;
551         }
552
553         calc_sequence(seq);
554         
555         if(sfile->flag & FILE_STRINGCODE) {
556                 strcpy(name, sfile->dir);
557                 strcpy(rel, G.sce);
558                 BLI_makestringcode(rel, name);
559         } else {
560                 strcpy(name, sfile->dir);
561         }
562
563         /* strip and stripdata */
564         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
565         strip->len= totsel;
566         strip->us= 1;
567         strncpy(strip->dir, name, FILE_MAXDIR-1);
568         strip->stripdata= se= MEM_callocN(totsel*sizeof(StripElem), "stripelem");
569
570         for(a=0; a<sfile->totfile; a++) {
571                 if(sfile->filelist[a].flags & ACTIVE) {
572                         if( (sfile->filelist[a].type & S_IFDIR)==0 ) {
573                                 strncpy(se->name, sfile->filelist[a].relname, FILE_MAXFILE-1);
574                                 se->ok= 1;
575                                 se++;
576                         }
577                 }
578         }
579         /* no selected file: */
580         if(totsel==1 && se==strip->stripdata) {
581                 strncpy(se->name, sfile->file, FILE_MAXFILE-1);
582                 se->ok= 1;
583         }
584
585         /* last active name */
586         strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
587
588         return seq;
589 }
590
591
592 static int sfile_to_mv_sequence_load(SpaceFile *sfile, int cfra, 
593                                      int machine, int index )
594 {
595         Sequence *seq;
596         struct anim *anim;
597         Strip *strip;
598         StripElem *se;
599         int totframe, a;
600         char name[160], rel[160];
601         char str[FILE_MAXDIR+FILE_MAXFILE];
602
603         totframe= 0;
604
605         strncpy(str, sfile->dir, FILE_MAXDIR-1);
606         if(index<0)
607                 strncat(str, sfile->file, FILE_MAXDIR-1);
608         else
609                 strncat(str, sfile->filelist[index].relname, FILE_MAXDIR-1);
610
611         /* is it a movie? */
612         anim = openanim(str, IB_rect);
613         if(anim==0) {
614                 error("The selected file is not a movie or "
615                       "FFMPEG-support not compiled in!");
616                 return(cfra);
617         }
618         
619         totframe= IMB_anim_get_duration(anim);
620
621         /* make seq */
622         seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
623         seq->len= totframe;
624         seq->type= SEQ_MOVIE;
625         seq->anim= anim;
626         seq->anim_preseek = IMB_anim_get_preseek(anim);
627
628         calc_sequence(seq);
629         
630         if(sfile->flag & FILE_STRINGCODE) {
631                 strcpy(name, sfile->dir);
632                 strcpy(rel, G.sce);
633                 BLI_makestringcode(rel, name);
634         } else {
635                 strcpy(name, sfile->dir);
636         }
637
638         /* strip and stripdata */
639         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
640         strip->len= totframe;
641         strip->us= 1;
642         strncpy(strip->dir, name, FILE_MAXDIR-1);
643         strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
644
645         /* name movie in first strip */
646         if(index<0)
647                 strncpy(se->name, sfile->file, FILE_MAXFILE-1);
648         else
649                 strncpy(se->name, sfile->filelist[index].relname, FILE_MAXFILE-1);
650
651         for(a=1; a<=totframe; a++, se++) {
652                 se->ok= 1;
653                 se->nr= a;
654         }
655
656         /* last active name */
657         strncpy(last_imagename, seq->strip->dir, FILE_MAXDIR-1);
658         return(cfra+totframe);
659 }
660
661 static void sfile_to_mv_sequence(SpaceFile *sfile, int cfra, int machine)
662 {
663         int a, totsel;
664
665         totsel= 0;
666         for(a= 0; a<sfile->totfile; a++) {
667                 if(sfile->filelist[a].flags & ACTIVE) {
668                         if ((sfile->filelist[a].type & S_IFDIR)==0) {
669                                 totsel++;
670                         }
671                 }
672         }
673
674         if((totsel==0) && (sfile->file[0])) {
675                 cfra= sfile_to_mv_sequence_load(sfile, cfra, machine, -1);
676                 return;
677         }
678
679         if(totsel==0) return;
680
681         /* ok. check all the select file, and load it. */
682         for(a= 0; a<sfile->totfile; a++) {
683                 if(sfile->filelist[a].flags & ACTIVE) {
684                         if ((sfile->filelist[a].type & S_IFDIR)==0) {
685                                 /* load and update current frame. */
686                                 cfra= sfile_to_mv_sequence_load(sfile, cfra, machine, a);
687                         }
688                 }
689         }
690 }
691
692 static Sequence *sfile_to_ramsnd_sequence(SpaceFile *sfile, 
693                                           int cfra, int machine)
694 {
695         Sequence *seq;
696         bSound *sound;
697         Strip *strip;
698         StripElem *se;
699         double totframe;
700         int a;
701         char name[160], rel[160];
702         char str[256];
703
704         totframe= 0.0;
705
706         strncpy(str, sfile->dir, FILE_MAXDIR-1);
707         strncat(str, sfile->file, FILE_MAXFILE-1);
708
709         sound= sound_new_sound(str);
710         if (!sound || sound->sample->type == SAMPLE_INVALID) {
711                 error("Unsupported audio format");
712                 return 0;
713         }
714         if (sound->sample->bits != 16) {
715                 error("Only 16 bit audio is supported");
716                 return 0;
717         }
718         sound->id.us=1;
719         sound->flags |= SOUND_FLAGS_SEQUENCE;
720         audio_makestream(sound);
721
722         totframe= (int) ( ((float)(sound->streamlen-1)/( (float)G.scene->audio.mixrate*4.0 ))* (float)G.scene->r.frs_sec);
723
724         /* make seq */
725         seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
726         seq->len= totframe;
727         seq->type= SEQ_RAM_SOUND;
728         seq->sound = sound;
729
730         calc_sequence(seq);
731         
732         if(sfile->flag & FILE_STRINGCODE) {
733                 strcpy(name, sfile->dir);
734                 strcpy(rel, G.sce);
735                 BLI_makestringcode(rel, name);
736         } else {
737                 strcpy(name, sfile->dir);
738         }
739
740         /* strip and stripdata */
741         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
742         strip->len= totframe;
743         strip->us= 1;
744         strncpy(strip->dir, name, FILE_MAXDIR-1);
745         strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
746
747         /* name sound in first strip */
748         strncpy(se->name, sfile->file, FILE_MAXFILE-1);
749
750         for(a=1; a<=totframe; a++, se++) {
751                 se->ok= 2; /* why? */
752                 se->ibuf= 0;
753                 se->nr= a;
754         }
755
756         /* last active name */
757         strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
758
759         return seq;
760 }
761
762 static int sfile_to_hdsnd_sequence_load(SpaceFile *sfile, int cfra, 
763                                         int machine, int index)
764 {
765         Sequence *seq;
766         struct hdaudio *hdaudio;
767         Strip *strip;
768         StripElem *se;
769         int totframe, a;
770         char name[160], rel[160];
771         char str[FILE_MAXDIR+FILE_MAXFILE];
772
773         totframe= 0;
774
775         strncpy(str, sfile->dir, FILE_MAXDIR-1);
776         if(index<0)
777                 strncat(str, sfile->file, FILE_MAXDIR-1);
778         else
779                 strncat(str, sfile->filelist[index].relname, FILE_MAXDIR-1);
780
781         /* is it a sound file? */
782         hdaudio = sound_open_hdaudio(str);
783         if(hdaudio==0) {
784                 error("The selected file is not a sound file or "
785                       "FFMPEG-support not compiled in!");
786                 return(cfra);
787         }
788
789         totframe= sound_hdaudio_get_duration(hdaudio, G.scene->r.frs_sec);
790
791         /* make seq */
792         seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
793         seq->len= totframe;
794         seq->type= SEQ_HD_SOUND;
795         seq->hdaudio= hdaudio;
796
797         calc_sequence(seq);
798         
799         if(sfile->flag & FILE_STRINGCODE) {
800                 strcpy(name, sfile->dir);
801                 strcpy(rel, G.sce);
802                 BLI_makestringcode(rel, name);
803         } else {
804                 strcpy(name, sfile->dir);
805         }
806
807         /* strip and stripdata */
808         seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
809         strip->len= totframe;
810         strip->us= 1;
811         strncpy(strip->dir, name, FILE_MAXDIR-1);
812         strip->stripdata= se= MEM_callocN(totframe*sizeof(StripElem), "stripelem");
813
814         /* name movie in first strip */
815         if(index<0)
816                 strncpy(se->name, sfile->file, FILE_MAXFILE-1);
817         else
818                 strncpy(se->name, sfile->filelist[index].relname, FILE_MAXFILE-1);
819
820         for(a=1; a<=totframe; a++, se++) {
821                 se->ok= 2;
822                 se->ibuf = 0;
823                 se->nr= a;
824         }
825
826         /* last active name */
827         strncpy(last_sounddir, seq->strip->dir, FILE_MAXDIR-1);
828         return(cfra+totframe);
829 }
830
831 static void sfile_to_hdsnd_sequence(SpaceFile *sfile, int cfra, int machine)
832 {
833         int totsel, a;
834
835         totsel= 0;
836         for(a= 0; a<sfile->totfile; a++) {
837                 if(sfile->filelist[a].flags & ACTIVE) {
838                         if((sfile->filelist[a].type & S_IFDIR)==0) {
839                                 totsel++;
840                         }
841                 }
842         }
843
844         if((totsel==0) && (sfile->file[0])) {
845                 cfra= sfile_to_hdsnd_sequence_load(sfile, cfra, machine, -1);
846                 return;
847         }
848
849         if(totsel==0) return;
850
851         /* ok, check all the select file, and load it. */
852         for(a= 0; a<sfile->totfile; a++) {
853                 if(sfile->filelist[a].flags & ACTIVE) {
854                         if((sfile->filelist[a].type & S_IFDIR)==0) {
855                                 /* load and update current frame. */
856                                 cfra= sfile_to_hdsnd_sequence_load(sfile, cfra, machine, a);
857                         }
858                 }
859         }
860 }
861
862
863 static void add_image_strips(char *name)
864 {
865         SpaceFile *sfile;
866         struct direntry *files;
867         float x, y;
868         int a, totfile, cfra, machine;
869         short mval[2];
870
871         deselect_all_seq();
872
873         /* restore windowmatrices */
874         areawinset(curarea->win);
875         drawseqspace(curarea, curarea->spacedata.first);
876
877         /* search sfile */
878         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
879         if(sfile==0) return;
880
881         /* where will it be */
882         getmouseco_areawin(mval);
883         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
884         cfra= (int)(x+0.5);
885         machine= (int)(y+0.5);
886
887         waitcursor(1);
888
889         /* also read contents of directories */
890         files= sfile->filelist;
891         totfile= sfile->totfile;
892         sfile->filelist= 0;
893         sfile->totfile= 0;
894
895         for(a=0; a<totfile; a++) {
896                 if(files[a].flags & ACTIVE) {
897                         if( (files[a].type & S_IFDIR) ) {
898                                 strncat(sfile->dir, files[a].relname, FILE_MAXFILE-1);
899                                 strcat(sfile->dir,"/");
900                                 read_dir(sfile);
901
902                                 /* select all */
903                                 swapselect_file(sfile);
904
905                                 if ( sfile_to_sequence(sfile, cfra, machine, 0) ) machine++;
906
907                                 parent(sfile);
908                         }
909                 }
910         }
911
912         sfile->filelist= files;
913         sfile->totfile= totfile;
914
915         /* read directory itself */
916         sfile_to_sequence(sfile, cfra, machine, 1);
917
918         waitcursor(0);
919
920         BIF_undo_push("Add image strip Sequencer");
921         transform_seq('g', 0);
922
923 }
924
925 static void add_movie_strip(char *name)
926 {
927         SpaceFile *sfile;
928         float x, y;
929         int cfra, machine;
930         short mval[2];
931
932         deselect_all_seq();
933
934         /* restore windowmatrices */
935         areawinset(curarea->win);
936         drawseqspace(curarea, curarea->spacedata.first);
937
938         /* search sfile */
939         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
940         if(sfile==0) return;
941
942         /* where will it be */
943         getmouseco_areawin(mval);
944         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
945         cfra= (int)(x+0.5);
946         machine= (int)(y+0.5);
947
948         waitcursor(1);
949
950         /* read directory itself */
951         sfile_to_mv_sequence(sfile, cfra, machine);
952
953         waitcursor(0);
954
955         BIF_undo_push("Add movie strip Sequencer");
956         transform_seq('g', 0);
957
958 }
959
960 static void add_movie_and_hdaudio_strip(char *name)
961 {
962         SpaceFile *sfile;
963         float x, y;
964         int cfra, machine;
965         short mval[2];
966
967         deselect_all_seq();
968
969         /* restore windowmatrices */
970         areawinset(curarea->win);
971         drawseqspace(curarea, curarea->spacedata.first);
972
973         /* search sfile */
974         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
975         if(sfile==0) return;
976
977         /* where will it be */
978         getmouseco_areawin(mval);
979         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
980         cfra= (int)(x+0.5);
981         machine= (int)(y+0.5);
982
983         waitcursor(1);
984
985         /* read directory itself */
986         sfile_to_hdsnd_sequence(sfile, cfra, machine);
987         sfile_to_mv_sequence(sfile, cfra, machine);
988
989         waitcursor(0);
990
991         BIF_undo_push("Add movie and HD-audio strip Sequencer");
992         transform_seq('g', 0);
993
994 }
995
996 static void add_sound_strip_ram(char *name)
997 {
998         SpaceFile *sfile;
999         float x, y;
1000         int cfra, machine;
1001         short mval[2];
1002
1003         deselect_all_seq();
1004
1005         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
1006         if (sfile==0) return;
1007
1008         /* where will it be */
1009         getmouseco_areawin(mval);
1010         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1011         cfra= (int)(x+0.5);
1012         machine= (int)(y+0.5);
1013
1014         waitcursor(1);
1015
1016         sfile_to_ramsnd_sequence(sfile, cfra, machine);
1017
1018         waitcursor(0);
1019
1020         BIF_undo_push("Add ram sound strip Sequencer");
1021         transform_seq('g', 0);
1022 }
1023
1024 static void add_sound_strip_hd(char *name)
1025 {
1026         SpaceFile *sfile;
1027         float x, y;
1028         int cfra, machine;
1029         short mval[2];
1030
1031         deselect_all_seq();
1032
1033         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
1034         if (sfile==0) return;
1035
1036         /* where will it be */
1037         getmouseco_areawin(mval);
1038         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1039         cfra= (int)(x+0.5);
1040         machine= (int)(y+0.5);
1041
1042         waitcursor(1);
1043
1044         sfile_to_hdsnd_sequence(sfile, cfra, machine);
1045
1046         waitcursor(0);
1047
1048         BIF_undo_push("Add hd sound strip Sequencer");
1049         transform_seq('g', 0);
1050 }
1051
1052 #if 0
1053 static void reload_sound_strip(char *name)
1054 {
1055         Editing *ed;
1056         Sequence *seq, *seqact;
1057         SpaceFile *sfile;
1058         Sequence *last_seq= get_last_seq();
1059
1060         ed= G.scene->ed;
1061
1062         if(last_seq==0 || last_seq->type!=SEQ_SOUND) return;
1063         seqact= last_seq;       /* last_seq changes in alloc_sequence */
1064
1065         /* search sfile */
1066         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
1067         if(sfile==0) return;
1068
1069         waitcursor(1);
1070
1071         seq = sfile_to_snd_sequence(sfile, seqact->start, seqact->machine);
1072         printf("seq->type: %i\n", seq->type);
1073         if(seq && seq!=seqact) {
1074                 /* i'm not sure about this one, seems to work without it -- sgefant */
1075                 free_strip(seqact->strip);
1076
1077                 seqact->strip= seq->strip;
1078
1079                 seqact->len= seq->len;
1080                 calc_sequence(seqact);
1081
1082                 seq->strip= 0;
1083                 free_sequence(seq);
1084                 BLI_remlink(ed->seqbasep, seq);
1085
1086                 seq= ed->seqbasep->first;
1087
1088         }
1089
1090         waitcursor(0);
1091
1092         allqueue(REDRAWSEQ, 0);
1093 }
1094 #endif
1095
1096 static void reload_image_strip(char *name)
1097 {
1098         Editing *ed;
1099         Sequence *seq, *seqact;
1100         SpaceFile *sfile;
1101         Sequence *last_seq= get_last_seq();
1102
1103         ed= G.scene->ed;
1104
1105         if(last_seq==0 || last_seq->type!=SEQ_IMAGE) return;
1106         seqact= last_seq;       /* last_seq changes in alloc_sequence */
1107
1108         /* search sfile */
1109         sfile= scrarea_find_space_of_type(curarea, SPACE_FILE);
1110         if(sfile==0) return;
1111
1112         waitcursor(1);
1113
1114         seq= sfile_to_sequence(sfile, seqact->start, seqact->machine, 1);
1115         if(seq && seq!=seqact) {
1116                 free_strip(seqact->strip);
1117
1118                 seqact->strip= seq->strip;
1119
1120                 seqact->len= seq->len;
1121                 calc_sequence(seqact);
1122
1123                 seq->strip= 0;
1124                 free_sequence(seq);
1125                 BLI_remlink(ed->seqbasep, seq);
1126
1127                 update_changed_seq_and_deps(seqact, 1, 1);
1128         }
1129         waitcursor(0);
1130
1131         allqueue(REDRAWSEQ, 0);
1132 }
1133
1134 static int event_to_efftype(int event)
1135 {
1136         if(event==2) return SEQ_CROSS;
1137         if(event==3) return SEQ_GAMCROSS;
1138         if(event==4) return SEQ_ADD;
1139         if(event==5) return SEQ_SUB;
1140         if(event==6) return SEQ_MUL;
1141         if(event==7) return SEQ_ALPHAOVER;
1142         if(event==8) return SEQ_ALPHAUNDER;
1143         if(event==9) return SEQ_OVERDROP;
1144         if(event==10) return SEQ_PLUGIN;
1145         if(event==13) return SEQ_WIPE;
1146         if(event==14) return SEQ_GLOW;
1147         if(event==15) return SEQ_TRANSFORM;
1148         if(event==16) return SEQ_COLOR;
1149         if(event==17) return SEQ_SPEED;
1150         return 0;
1151 }
1152
1153 static int seq_effect_find_selected(Editing *ed, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3)
1154 {
1155         Sequence *seq1= 0, *seq2= 0, *seq3= 0, *seq;
1156         
1157         if (!activeseq)
1158                 seq2= get_last_seq();
1159
1160         for(seq=ed->seqbasep->first; seq; seq=seq->next) {
1161                 if(seq->flag & SELECT) {
1162                         if (seq->type == SEQ_RAM_SOUND
1163                             || seq->type == SEQ_HD_SOUND) { 
1164                                 error("Can't apply effects to "
1165                                       "audio sequence strips");
1166                                 return 0;
1167                         }
1168                         if((seq != activeseq) && (seq != seq2)) {
1169                                 if(seq2==0) seq2= seq;
1170                                 else if(seq1==0) seq1= seq;
1171                                 else if(seq3==0) seq3= seq;
1172                                 else {
1173                                        error("Can't apply effect to more than 3 sequence strips");
1174                                        return 0;
1175                                 }
1176                         }
1177                 }
1178         }
1179        
1180         /* make sequence selection a little bit more intuitive
1181            for 3 strips: the last-strip should be sequence3 */
1182         if (seq3 != 0 && seq2 != 0) {
1183                 Sequence *tmp = seq2;
1184                 seq2 = seq3;
1185                 seq3 = tmp;
1186         }
1187         
1188
1189         switch(get_sequence_effect_num_inputs(type)) {
1190         case 0:
1191                 seq1 = seq2 = seq3 = 0;
1192                 break;
1193         case 1:
1194                 if(seq2==0)  {
1195                         error("Need at least one selected sequence strip");
1196                         return 0;
1197                 }
1198                 if(seq1==0) seq1= seq2;
1199                 if(seq3==0) seq3= seq2;
1200         case 2:
1201                 if(seq1==0 || seq2==0) {
1202                         error("Need 2 selected sequence strips");
1203                         return 0;
1204                 }
1205                 if(seq3==0) seq3= seq2;
1206         }
1207
1208         *selseq1= seq1;
1209         *selseq2= seq2;
1210         *selseq3= seq3;
1211
1212         return 1;
1213 }
1214
1215 static int add_seq_effect(int type, char *str)
1216 {
1217         Editing *ed;
1218         Sequence *newseq, *seq1, *seq2, *seq3;
1219         Strip *strip;
1220         float x, y;
1221         int cfra, machine;
1222         short mval[2];
1223         struct SeqEffectHandle sh;
1224
1225         if(G.scene->ed==0) return 0;
1226         ed= G.scene->ed;
1227
1228         if(!seq_effect_find_selected(ed, NULL, event_to_efftype(type), &seq1, &seq2, &seq3))
1229                 return 0;
1230
1231         deselect_all_seq();
1232
1233         /* where will it be (cfra is not realy needed) */
1234         getmouseco_areawin(mval);
1235         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1236         cfra= (int)(x+0.5);
1237         machine= (int)(y+0.5);
1238
1239         /* allocate and initialize */
1240         newseq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
1241         newseq->type= event_to_efftype(type);
1242
1243         sh = get_sequence_effect(newseq);
1244
1245         newseq->seq1= seq1;
1246         newseq->seq2= seq2;
1247         newseq->seq3= seq3;
1248
1249         sh.init(newseq);
1250
1251         if (!seq1) {
1252                 newseq->len= 1;
1253                 newseq->startstill= 25;
1254                 newseq->endstill= 24;
1255         }
1256
1257         calc_sequence(newseq);
1258
1259         newseq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
1260         strip->len= newseq->len;
1261         strip->us= 1;
1262         if(newseq->len>0)
1263                 strip->stripdata= MEM_callocN(newseq->len*sizeof(StripElem), "stripelem");
1264
1265         /* initialize plugin */
1266         if(newseq->type == SEQ_PLUGIN) {
1267                 sh.init_plugin(newseq, str);
1268
1269                 if(newseq->plugin==0) {
1270                         BLI_remlink(ed->seqbasep, newseq);
1271                         free_sequence(newseq);
1272                         set_last_seq(NULL);
1273                         return 0;
1274                 }
1275         }
1276
1277         /* set find a free spot to but the strip */
1278         if (newseq->seq1) {
1279                 newseq->machine= MAX3(newseq->seq1->machine, 
1280                                       newseq->seq2->machine,
1281                                       newseq->seq3->machine);
1282         }
1283         if(test_overlap_seq(newseq)) shuffle_seq(newseq);
1284
1285         update_changed_seq_and_deps(newseq, 1, 1);
1286
1287         /* push undo and go into grab mode */
1288         if(newseq->type == SEQ_PLUGIN) {
1289                 BIF_undo_push("Add plugin strip Sequencer");
1290         } else {
1291                 BIF_undo_push("Add effect strip Sequencer");
1292         }
1293
1294         transform_seq('g', 0);
1295
1296         return 1;
1297 }
1298
1299 static void load_plugin_seq(char *str)          /* called from fileselect */
1300 {
1301         add_seq_effect(10, str);
1302 }
1303
1304 void add_sequence(int type)
1305 {
1306         Editing *ed;
1307         Sequence *seq;
1308         Strip *strip;
1309         Scene *sce;
1310         float x, y;
1311         int cfra, machine;
1312         short nr, event, mval[2];
1313         char *str;
1314
1315         if (type >= 0){
1316                 /* bypass pupmenu for calls from menus (aphex) */
1317                 switch(type){
1318                 case SEQ_SCENE:
1319                         event = 101;
1320                         break;
1321                 case SEQ_IMAGE:
1322                         event = 1;
1323                         break;
1324                 case SEQ_MOVIE:
1325                         event = 102;
1326                         break;
1327                 case SEQ_RAM_SOUND:
1328                         event = 103;
1329                         break;
1330                 case SEQ_HD_SOUND:
1331                         event = 104;
1332                         break;
1333                 case SEQ_MOVIE_AND_HD_SOUND:
1334                         event = 105;
1335                         break;
1336                 case SEQ_PLUGIN:
1337                         event = 10;
1338                         break;
1339                 case SEQ_CROSS:
1340                         event = 2;
1341                         break;
1342                 case SEQ_ADD:
1343                         event = 4;
1344                         break;
1345                 case SEQ_SUB:
1346                         event = 5;
1347                         break;
1348                 case SEQ_ALPHAOVER:
1349                         event = 7;
1350                         break;
1351                 case SEQ_ALPHAUNDER:
1352                         event = 8;
1353                         break;
1354                 case SEQ_GAMCROSS:
1355                         event = 3;
1356                         break;
1357                 case SEQ_MUL:
1358                         event = 6;
1359                         break;
1360                 case SEQ_OVERDROP:
1361                         event = 9;
1362                         break;
1363                 case SEQ_WIPE:
1364                         event = 13;
1365                         break;
1366                 case SEQ_GLOW:
1367                         event = 14;
1368                         break;
1369                 case SEQ_TRANSFORM:
1370                         event = 15;
1371                         break;
1372                 case SEQ_COLOR:
1373                         event = 16;
1374                         break;
1375                 case SEQ_SPEED:
1376                         event = 17;
1377                         break;
1378                 default:
1379                         event = 0;
1380                         break;
1381                 }
1382         }
1383         else {
1384                 event= pupmenu("Add Sequence Strip%t"
1385                                "|Images%x1"
1386                                "|Movie%x102"
1387 #ifdef WITH_FFMPEG
1388                                    "|Movie + Audio (HD)%x105"
1389                                "|Audio (RAM)%x103"
1390                                "|Audio (HD)%x104"
1391 #else
1392                                    "|Audio (Wav)%x103"
1393 #endif
1394                                "|Scene%x101"
1395                                "|Plugin%x10"
1396                                "|Cross%x2"
1397                                "|Gamma Cross%x3"
1398                                "|Add%x4"
1399                                "|Sub%x5"
1400                                "|Mul%x6"
1401                                "|Alpha Over%x7"
1402                                "|Alpha Under%x8"
1403                                "|Alpha Over Drop%x9"
1404                                "|Wipe%x13"
1405                                "|Glow%x14"
1406                                "|Transforms%x15"
1407                                "|Color Generator%x16"
1408                                "|Speed Control%x17");
1409         }
1410
1411         if(event<1) return;
1412
1413         if(G.scene->ed==0) {
1414                 ed= G.scene->ed= MEM_callocN( sizeof(Editing), "addseq");
1415                 ed->seqbasep= &ed->seqbase;
1416         }
1417         else ed= G.scene->ed;
1418
1419         switch(event) {
1420         case 1:
1421
1422                 activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
1423                 break;
1424         case 105:
1425                 activate_fileselect(FILE_SPECIAL, "Select Movie+Audio", last_imagename, add_movie_and_hdaudio_strip);
1426                 break;
1427         case 102:
1428
1429                 activate_fileselect(FILE_SPECIAL, "Select Movie", last_imagename, add_movie_strip);
1430                 break;
1431         case 101:
1432                 /* new menu: */
1433                 IDnames_to_pupstring(&str, NULL, NULL, &G.main->scene, (ID *)G.scene, NULL);
1434
1435                 event= pupmenu_col(str, 20);
1436
1437                 if(event> -1) {
1438                         nr= 1;
1439                         sce= G.main->scene.first;
1440                         while(sce) {
1441                                 if( event==nr) break;
1442                                 nr++;
1443                                 sce= sce->id.next;
1444                         }
1445                         if(sce) {
1446
1447                                 deselect_all_seq();
1448
1449                                 /* where ? */
1450                                 getmouseco_areawin(mval);
1451                                 areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1452                                 cfra= (int)(x+0.5);
1453                                 machine= (int)(y+0.5);
1454
1455                                 seq= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, cfra, machine);
1456                                 seq->type= SEQ_SCENE;
1457                                 seq->scene= sce;
1458                                 seq->sfra= sce->r.sfra;
1459                                 seq->len= sce->r.efra - sce->r.sfra + 1;
1460
1461                                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
1462                                 strncpy(seq->name + 2, sce->id.name + 2, 
1463                                         sizeof(seq->name) - 2);
1464                                 strip->len= seq->len;
1465                                 strip->us= 1;
1466                                 if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1467
1468                                 BIF_undo_push("Add scene strip Sequencer");
1469                                 transform_seq('g', 0);
1470                         }
1471                 }
1472                 MEM_freeN(str);
1473
1474                 break;
1475         case 2:
1476         case 3:
1477         case 4:
1478         case 5:
1479         case 6:
1480         case 7:
1481         case 8:
1482         case 9:
1483         case 10:
1484         case 13:
1485         case 14:
1486         case 15:
1487         case 16:
1488         case 17:
1489                 if(get_last_seq()==0 && 
1490                    get_sequence_effect_num_inputs( event_to_efftype(event))> 0)
1491                         error("Need at least one active sequence strip");
1492                 else if(event==10)
1493                         activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, load_plugin_seq);
1494                 else
1495                         add_seq_effect(event, NULL);
1496
1497                 break;
1498         case 103:
1499                 if (!last_sounddir[0]) strncpy(last_sounddir, U.sounddir, FILE_MAXDIR-1);
1500                 activate_fileselect(FILE_SPECIAL, "Select Audio (RAM)", last_sounddir, add_sound_strip_ram);
1501                 break;
1502         case 104:
1503                 if (!last_sounddir[0]) strncpy(last_sounddir, U.sounddir, FILE_MAXDIR-1);
1504                 activate_fileselect(FILE_SPECIAL, "Select Audio (HD)", last_sounddir, add_sound_strip_hd);
1505                 break;
1506         }
1507 }
1508
1509 void change_sequence(void)
1510 {
1511         Sequence *last_seq= get_last_seq();
1512         Scene *sce;
1513         short event;
1514
1515         if(last_seq==0) return;
1516
1517         if(last_seq->type & SEQ_EFFECT) {
1518                 event = pupmenu("Change Effect%t"
1519                                 "|Switch A <-> B %x1"
1520                                 "|Switch B <-> C %x10"
1521                                 "|Plugin%x11"
1522                                 "|Recalculate%x12"
1523                                 "|Cross%x2"
1524                                 "|Gamma Cross%x3"
1525                                 "|Add%x4"
1526                                 "|Sub%x5"
1527                                 "|Mul%x6"
1528                                 "|Alpha Over%x7"
1529                                 "|Alpha Under%x8"
1530                                 "|Alpha Over Drop%x9"
1531                                 "|Wipe%x13"
1532                                 "|Glow%x14"
1533                                 "|Transform%x15"
1534                                 "|Color Generator%x16"
1535                                 "|Speed Control%x17");
1536                 if(event > 0) {
1537                         if(event==1) {
1538                                 SWAP(Sequence *,last_seq->seq1,last_seq->seq2);
1539                         }
1540                         else if(event==10) {
1541                                 SWAP(Sequence *,last_seq->seq2,last_seq->seq3);
1542                         }
1543                         else if(event==11) {
1544                                 activate_fileselect(
1545                                         FILE_SPECIAL, "Select Plugin", 
1546                                         U.plugseqdir, change_plugin_seq);
1547                         }
1548                         else if(event==12);     
1549                                 /* recalculate: only new_stripdata */
1550                         else {
1551                                 /* free previous effect and init new effect */
1552                                 struct SeqEffectHandle sh;
1553
1554                                 if (get_sequence_effect_num_inputs(
1555                                             last_seq->type)
1556                                     < get_sequence_effect_num_inputs(
1557                                             event_to_efftype(event))) {
1558                                         error("New effect needs more "
1559                                               "input strips!");
1560                                 } else {
1561                                         sh = get_sequence_effect(last_seq);
1562                                         sh.free(last_seq);
1563                                         
1564                                         last_seq->type 
1565                                                 = event_to_efftype(event);
1566                                         
1567                                         sh = get_sequence_effect(last_seq);
1568                                         sh.init(last_seq);
1569                                 }
1570                         }
1571
1572                         update_changed_seq_and_deps(last_seq, 0, 1);
1573                         allqueue(REDRAWSEQ, 0);
1574                         BIF_undo_push("Change effect Sequencer");
1575                 }
1576         }
1577         else if(last_seq->type == SEQ_IMAGE) {
1578                 if(okee("Change images")) {
1579                         activate_fileselect(FILE_SPECIAL, 
1580                                             "Select Images", 
1581                                             last_imagename, 
1582                                             reload_image_strip);
1583                 }
1584         }
1585         else if(last_seq->type == SEQ_MOVIE) {
1586                 ;
1587         }
1588         else if(last_seq->type == SEQ_SCENE) {
1589                 event= pupmenu("Change Scene%t|Update Start and End");
1590
1591                 if(event==1) {
1592                         sce= last_seq->scene;
1593
1594                         last_seq->len= sce->r.efra - sce->r.sfra + 1;
1595                         last_seq->sfra= sce->r.sfra;
1596                         update_changed_seq_and_deps(last_seq, 1, 1);
1597
1598                         allqueue(REDRAWSEQ, 0);
1599                 }
1600         }
1601
1602 }
1603
1604 void reassign_inputs_seq_effect()
1605 {
1606         Editing *ed= G.scene->ed;
1607         Sequence *seq1, *seq2, *seq3, *last_seq = get_last_seq();
1608
1609         if(last_seq==0 || !(last_seq->type & SEQ_EFFECT)) return;
1610         if(ed==0) return;
1611
1612         if(!seq_effect_find_selected(ed, last_seq, last_seq->type, &seq1, &seq2, &seq3))
1613                 return;
1614
1615         /* see reassigning would create a cycle */
1616         if(seq_is_predecessor(seq1, last_seq) || seq_is_predecessor(seq2, last_seq) ||
1617            seq_is_predecessor(seq3, last_seq)) {
1618                 error("Can't reassign inputs: no cycles allowed");
1619                 return;
1620         }
1621         
1622         last_seq->seq1 = seq1;
1623         last_seq->seq2 = seq2;
1624         last_seq->seq3 = seq3;
1625
1626         update_changed_seq_and_deps(last_seq, 1, 1);
1627
1628         allqueue(REDRAWSEQ, 0);
1629 }
1630
1631 static Sequence *del_seq_find_replace_recurs(Sequence *seq)
1632 {
1633         Sequence *seq1, *seq2, *seq3;
1634
1635         /* try to find a replacement input sequence, and flag for later deletion if
1636            no replacement can be found */
1637
1638         if(!seq)
1639                 return NULL;
1640         else if(!(seq->type & SEQ_EFFECT))
1641                 return ((seq->flag & SELECT)? NULL: seq);
1642         else if(!(seq->flag & SELECT)) {
1643                 /* try to find replacement for effect inputs */
1644                 seq1= del_seq_find_replace_recurs(seq->seq1);
1645                 seq2= del_seq_find_replace_recurs(seq->seq2);
1646                 seq3= del_seq_find_replace_recurs(seq->seq3);
1647
1648                 if(seq1==seq->seq1 && seq2==seq->seq2 && seq3==seq->seq3);
1649                 else if(seq1 || seq2 || seq3) {
1650                         seq->seq1= (seq1)? seq1: (seq2)? seq2: seq3;
1651                         seq->seq2= (seq2)? seq2: (seq1)? seq1: seq3;
1652                         seq->seq3= (seq3)? seq3: (seq1)? seq1: seq2;
1653
1654                         update_changed_seq_and_deps(seq, 1, 1);
1655                 }
1656                 else
1657                         seq->flag |= SELECT; /* mark for delete */
1658         }
1659
1660         if (seq->flag & SELECT) {
1661                 if((seq1 = del_seq_find_replace_recurs(seq->seq1))) return seq1;
1662                 if((seq2 = del_seq_find_replace_recurs(seq->seq2))) return seq2;
1663                 if((seq3 = del_seq_find_replace_recurs(seq->seq3))) return seq3;
1664                 else return NULL;
1665         }
1666         else
1667                 return seq;
1668 }
1669
1670 static void recurs_del_seq_flag(ListBase *lb, short flag, short deleteall)
1671 {
1672         Sequence *seq, *seqn;
1673         Sequence *last_seq = get_last_seq();
1674
1675         seq= lb->first;
1676         while(seq) {
1677                 seqn= seq->next;
1678                 if((seq->flag & flag) || deleteall) {
1679                         if(seq->type==SEQ_RAM_SOUND && seq->sound) 
1680                                 seq->sound->id.us--;
1681
1682                         BLI_remlink(lb, seq);
1683                         if(seq==last_seq) set_last_seq(0);
1684                         if(seq->type==SEQ_META) recurs_del_seq_flag(&seq->seqbase, flag, 1);
1685                         if(seq->ipo) seq->ipo->id.us--;
1686                         free_sequence(seq);
1687                 }
1688                 seq= seqn;
1689         }
1690 }
1691
1692 void del_seq(void)
1693 {
1694         Sequence *seq;
1695         MetaStack *ms;
1696         Editing *ed;
1697
1698         if(okee("Erase selected")==0) return;
1699
1700         ed= G.scene->ed;
1701         if(ed==0) return;
1702
1703         /* free imbufs of all dependent strips */
1704         for(seq=ed->seqbasep->first; seq; seq=seq->next)
1705                 if(seq->flag & SELECT)
1706                         update_changed_seq_and_deps(seq, 1, 0);
1707
1708         /* for effects, try to find a replacement input */
1709         for(seq=ed->seqbasep->first; seq; seq=seq->next)
1710                 if((seq->type & SEQ_EFFECT) && !(seq->flag & SELECT))
1711                         del_seq_find_replace_recurs(seq);
1712
1713         /* delete all selected strips */
1714         recurs_del_seq_flag(ed->seqbasep, SELECT, 0);
1715
1716         /* updates lengths etc */
1717         seq= ed->seqbasep->first;
1718         while(seq) {
1719                 calc_sequence(seq);
1720                 seq= seq->next;
1721         }
1722
1723         /* free parent metas */
1724         ms= ed->metastack.last;
1725         while(ms) {
1726                 ms->parseq->strip->len= 0;              /* force new alloc */
1727                 calc_sequence(ms->parseq);
1728                 ms= ms->prev;
1729         }
1730
1731         BIF_undo_push("Delete from Sequencer");
1732         allqueue(REDRAWSEQ, 0);
1733 }
1734
1735 static void recurs_dupli_seq(ListBase *old, ListBase *new)
1736 {
1737         Sequence *seq, *seqn;
1738         Sequence *last_seq = get_last_seq();
1739         StripElem *se;
1740         int a;
1741
1742         seq= old->first;
1743
1744         while(seq) {
1745                 seq->newseq= 0;
1746                 if(seq->flag & SELECT) {
1747
1748                         if(seq->type==SEQ_META) {
1749                                 seqn= MEM_dupallocN(seq);
1750                                 seq->newseq= seqn;
1751                                 BLI_addtail(new, seqn);
1752
1753                                 seqn->strip= MEM_dupallocN(seq->strip);
1754
1755                                 if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1756
1757                                 seq->flag &= SEQ_DESEL;
1758                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1759
1760                                 seqn->seqbase.first= seqn->seqbase.last= 0;
1761                                 recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);
1762
1763                         }
1764                         else if(seq->type == SEQ_SCENE) {
1765                                 seqn= MEM_dupallocN(seq);
1766                                 seq->newseq= seqn;
1767                                 BLI_addtail(new, seqn);
1768
1769                                 seqn->strip= MEM_dupallocN(seq->strip);
1770
1771                                 if(seq->len>0) seqn->strip->stripdata = MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1772
1773                                 seq->flag &= SEQ_DESEL;
1774                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1775                         }
1776                         else if(seq->type == SEQ_MOVIE) {
1777                                 seqn= MEM_dupallocN(seq);
1778                                 seq->newseq= seqn;
1779                                 BLI_addtail(new, seqn);
1780
1781                                 seqn->strip= MEM_dupallocN(seq->strip);
1782                                 seqn->anim= 0;
1783
1784                                 if(seqn->len>0) {
1785                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1786                                         /* copy first elem */
1787                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1788                                         se= seqn->strip->stripdata;
1789                                         a= seq->len;
1790                                         while(a--) {
1791                                                 se->ok= 1;
1792                                                 se++;
1793                                         }
1794                                 }
1795
1796                                 seq->flag &= SEQ_DESEL;
1797                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1798                         }
1799                         else if(seq->type == SEQ_RAM_SOUND) {
1800                                 seqn= MEM_dupallocN(seq);
1801                                 seq->newseq= seqn;
1802                                 BLI_addtail(new, seqn);
1803
1804                                 seqn->strip= MEM_dupallocN(seq->strip);
1805                                 seqn->anim= 0;
1806                                 seqn->sound->id.us++;
1807                                 if(seqn->ipo) seqn->ipo->id.us++;
1808
1809                                 if(seqn->len>0) {
1810                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1811                                         /* copy first elem */
1812                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1813                                         se= seqn->strip->stripdata;
1814                                         a= seq->len;
1815                                         while(a--) {
1816                                                 se->ok= 1;
1817                                                 se++;
1818                                         }
1819                                 }
1820
1821                                 seq->flag &= SEQ_DESEL;
1822                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1823                         }
1824                         else if(seq->type == SEQ_HD_SOUND) {
1825                                 seqn= MEM_dupallocN(seq);
1826                                 seq->newseq= seqn;
1827                                 BLI_addtail(new, seqn);
1828
1829                                 seqn->strip= MEM_dupallocN(seq->strip);
1830                                 seqn->anim= 0;
1831                                 seqn->hdaudio = 0;
1832                                 if(seqn->ipo) seqn->ipo->id.us++;
1833
1834                                 if(seqn->len>0) {
1835                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1836                                         /* copy first elem */
1837                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1838                                         se= seqn->strip->stripdata;
1839                                         a= seq->len;
1840                                         while(a--) {
1841                                                 se->ok= 1;
1842                                                 se++;
1843                                         }
1844                                 }
1845
1846                                 seq->flag &= SEQ_DESEL;
1847                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1848                         }
1849                         else if(seq->type < SEQ_EFFECT) {
1850                                 seqn= MEM_dupallocN(seq);
1851                                 seq->newseq= seqn;
1852                                 BLI_addtail(new, seqn);
1853
1854                                 seqn->strip->us++;
1855                                 seq->flag &= SEQ_DESEL;
1856
1857                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1858                         }
1859                         else {
1860                                 seqn= MEM_dupallocN(seq);
1861                                 seq->newseq= seqn;
1862                                 BLI_addtail(new, seqn);
1863
1864                                 if(seq->seq1 && seq->seq1->newseq) seqn->seq1= seq->seq1->newseq;
1865                                 if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
1866                                 if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
1867
1868                                 if(seqn->ipo) seqn->ipo->id.us++;
1869
1870                                 if (seq->type & SEQ_EFFECT) {
1871                                         struct SeqEffectHandle sh;
1872                                         sh = get_sequence_effect(seq);
1873                                         if(sh.copy)
1874                                                 sh.copy(seq, seqn);
1875                                 }
1876
1877                                 seqn->strip= MEM_dupallocN(seq->strip);
1878
1879                                 if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1880
1881                                 seq->flag &= SEQ_DESEL;
1882                                 
1883                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1884                         }
1885                         if (seq == last_seq) {
1886                                 set_last_seq(seqn);
1887                         }
1888                 }
1889                 seq= seq->next;
1890         }
1891 }
1892
1893 void add_duplicate_seq(void)
1894 {
1895         Editing *ed;
1896         ListBase new;
1897
1898         ed= G.scene->ed;
1899         if(ed==0) return;
1900
1901         new.first= new.last= 0;
1902
1903         recurs_dupli_seq(ed->seqbasep, &new);
1904         addlisttolist(ed->seqbasep, &new);
1905
1906         BIF_undo_push("Add duplicate Sequencer");
1907         transform_seq('g', 0);
1908 }
1909
1910 int insert_gap(int gap, int cfra)
1911 {
1912         Sequence *seq;
1913         Editing *ed;
1914         int done=0;
1915
1916         /* all strips >= cfra are shifted */
1917         ed= G.scene->ed;
1918         if(ed==0) return 0;
1919
1920         WHILE_SEQ(ed->seqbasep) {
1921                 if(seq->startdisp >= cfra) {
1922                         seq->start+= gap;
1923                         calc_sequence(seq);
1924                         done= 1;
1925                 }
1926         }
1927         END_SEQ
1928
1929         return done;
1930 }
1931
1932 void touch_seq_files(void)
1933 {
1934         Sequence *seq;
1935         Editing *ed;
1936         char str[256];
1937
1938         /* touch all strips with movies */
1939         ed= G.scene->ed;
1940         if(ed==0) return;
1941
1942         if(okee("Touch and print selected movies")==0) return;
1943
1944         waitcursor(1);
1945
1946         WHILE_SEQ(ed->seqbasep) {
1947                 if(seq->flag & SELECT) {
1948                         if(seq->type==SEQ_MOVIE) {
1949                                 if(seq->strip && seq->strip->stripdata) {
1950                                         BLI_make_file_string(G.sce, str, seq->strip->dir, seq->strip->stripdata->name);
1951                                         BLI_touch(seq->name);
1952                                 }
1953                         }
1954
1955                 }
1956         }
1957         END_SEQ
1958
1959         waitcursor(0);
1960 }
1961
1962 void set_filter_seq(void)
1963 {
1964         Sequence *seq;
1965         Editing *ed;
1966
1967         ed= G.scene->ed;
1968         if(ed==0) return;
1969
1970         if(okee("Set FilterY")==0) return;
1971
1972         WHILE_SEQ(ed->seqbasep) {
1973                 if(seq->flag & SELECT) {
1974                         if(seq->type==SEQ_MOVIE) {
1975                                 seq->flag |= SEQ_FILTERY;
1976                         }
1977
1978                 }
1979         }
1980         END_SEQ
1981
1982 }
1983
1984 void seq_remap_paths(void)
1985 {
1986         Sequence *seq, *last_seq = get_last_seq();
1987         Editing *ed;
1988         char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
1989         
1990         ed= G.scene->ed;
1991         if(ed==NULL || last_seq==NULL) 
1992                 return;
1993         
1994         BLI_strncpy(from, last_seq->strip->dir, FILE_MAX);
1995         if (0==sbutton(from, 0, sizeof(from)-1, "From: "))
1996                 return;
1997         
1998         strcpy(to, from);
1999         if (0==sbutton(to, 0, sizeof(to)-1, "To: "))
2000                 return;
2001         
2002         if (strcmp(to, from)==0)
2003                 return;
2004         
2005         WHILE_SEQ(ed->seqbasep) {
2006                 if(seq->flag & SELECT) {
2007                         if(strncmp(seq->strip->dir, from, strlen(from))==0) {
2008                                 printf("found %s\n", seq->strip->dir);
2009                                 
2010                                 /* strip off the beginning */
2011                                 stripped[0]= 0;
2012                                 BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
2013                                 
2014                                 /* new path */
2015                                 BLI_strncpy(seq->strip->dir, to, FILE_MAX);
2016                                 strcat(seq->strip->dir, stripped);
2017                                 printf("new %s\n", seq->strip->dir);
2018                         }
2019                 }
2020         }
2021         END_SEQ
2022                 
2023         BIF_undo_push("Remap paths in Sequencer");
2024         allqueue(REDRAWSEQ, 0);
2025 }
2026
2027
2028 void no_gaps(void)
2029 {
2030         Editing *ed;
2031         int cfra, first= 0, done;
2032
2033         ed= G.scene->ed;
2034         if(ed==0) return;
2035
2036         for(cfra= CFRA; cfra<=EFRA; cfra++) {
2037                 if(first==0) {
2038                         if( evaluate_seq_frame(cfra) ) first= 1;
2039                 }
2040                 else {
2041                         done= 1;
2042                         while( evaluate_seq_frame(cfra) == 0) {
2043                                 done= insert_gap(-1, cfra);
2044                                 if(done==0) break;
2045                         }
2046                         if(done==0) break;
2047                 }
2048         }
2049
2050         BIF_undo_push("No gaps Sequencer");
2051         allqueue(REDRAWSEQ, 0);
2052 }
2053
2054
2055 /* ****************** META ************************* */
2056
2057 void make_meta(void)
2058 {
2059         Sequence *seq, *seqm, *next;
2060         Editing *ed;
2061         int tot;
2062         
2063         ed= G.scene->ed;
2064         if(ed==0) return;
2065
2066         /* is there more than 1 select */
2067         tot= 0;
2068         seq= ed->seqbasep->first;
2069         while(seq) {
2070                 if(seq->flag & SELECT) {
2071                         tot++;
2072                         if (seq->type == SEQ_RAM_SOUND) { 
2073                                 error("Can't make Meta Strip from audio"); 
2074                                 return; 
2075                         }
2076                 }
2077                 seq= seq->next;
2078         }
2079         if(tot < 2) return;
2080
2081         if(okee("Make Meta Strip")==0) return;
2082
2083         /* test relationships */
2084         seq= ed->seqbasep->first;
2085         while(seq) {
2086                 if(seq->flag & SELECT) {
2087                         if(seq->type & SEQ_EFFECT) {
2088                                 if(seq->seq1 && 
2089                                    (seq->seq1->flag & SELECT)==0) tot= 0;
2090                                 if(seq->seq2 &&
2091                                    (seq->seq2->flag & SELECT)==0) tot= 0;
2092                                 if(seq->seq3 &&
2093                                    (seq->seq3->flag & SELECT)==0) tot= 0;
2094                         }
2095                 }
2096                 else if(seq->type & SEQ_EFFECT) {
2097                         if(seq->seq1 &&
2098                            (seq->seq1->flag & SELECT)) tot= 0;
2099                         if(seq->seq2 &&
2100                            (seq->seq2->flag & SELECT)) tot= 0;
2101                         if(seq->seq3 &&
2102                            (seq->seq3->flag & SELECT)) tot= 0;
2103                 }
2104                 if(tot==0) break;
2105                 seq= seq->next;
2106         }
2107         if(tot==0) {
2108                 error("Please select all related strips");
2109                 return;
2110         }
2111
2112         /* remove all selected from main list, and put in meta */
2113
2114         seqm= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, 1, 1);
2115         seqm->type= SEQ_META;
2116         seqm->flag= SELECT;
2117
2118         seq= ed->seqbasep->first;
2119         while(seq) {
2120                 next= seq->next;
2121                 if(seq!=seqm && (seq->flag & SELECT)) {
2122                         BLI_remlink(ed->seqbasep, seq);
2123                         BLI_addtail(&seqm->seqbase, seq);
2124                 }
2125                 seq= next;
2126         }
2127         calc_sequence(seqm);
2128
2129         seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
2130         seqm->strip->len= seqm->len;
2131         seqm->strip->us= 1;
2132         if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata");
2133         set_meta_stripdata(seqm);
2134
2135         BIF_undo_push("Make Meta Sequencer");
2136         allqueue(REDRAWSEQ, 0);
2137 }
2138
2139 static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
2140 {
2141         if (seq == seqm) return 1;
2142         else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
2143         else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
2144         else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
2145         else return 0;
2146 }
2147
2148 void un_meta(void)
2149 {
2150         Editing *ed;
2151         Sequence *seq, *last_seq = get_last_seq();
2152
2153         ed= G.scene->ed;
2154         if(ed==0) return;
2155
2156         if(last_seq==0 || last_seq->type!=SEQ_META) return;
2157
2158         if(okee("Un Meta")==0) return;
2159
2160         addlisttolist(ed->seqbasep, &last_seq->seqbase);
2161
2162         last_seq->seqbase.first= 0;
2163         last_seq->seqbase.last= 0;
2164
2165         BLI_remlink(ed->seqbasep, last_seq);
2166         free_sequence(last_seq);
2167
2168         /* emtpy meta strip, delete all effects depending on it */
2169         for(seq=ed->seqbasep->first; seq; seq=seq->next)
2170                 if((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq))
2171                         seq->flag |= SEQ_FLAG_DELETE;
2172
2173         recurs_del_seq_flag(ed->seqbasep, SEQ_FLAG_DELETE, 0);
2174
2175         /* test for effects and overlap */
2176         WHILE_SEQ(ed->seqbasep) {
2177                 if(seq->flag & SELECT) {
2178                         seq->flag &= ~SEQ_OVERLAP;
2179                         if( test_overlap_seq(seq) ) {
2180                                 shuffle_seq(seq);
2181                         }
2182                 }
2183         }
2184         END_SEQ;
2185
2186         sort_seq();
2187
2188         BIF_undo_push("Un-make Meta Sequencer");
2189         allqueue(REDRAWSEQ, 0);
2190
2191 }
2192
2193 void exit_meta(void)
2194 {
2195         Sequence *seq;
2196         MetaStack *ms;
2197         Editing *ed;
2198
2199         ed= G.scene->ed;
2200         if(ed==0) return;
2201
2202         if(ed->metastack.first==0) return;
2203
2204         ms= ed->metastack.last;
2205         BLI_remlink(&ed->metastack, ms);
2206
2207         ed->seqbasep= ms->oldbasep;
2208
2209         /* recalc entire meta */
2210         set_meta_stripdata(ms->parseq);
2211
2212         /* recalc all: the meta can have effects connected to it */
2213         seq= ed->seqbasep->first;
2214         while(seq) {
2215                 calc_sequence(seq);
2216                 seq= seq->next;
2217         }
2218
2219         set_last_seq(ms->parseq);
2220
2221         ms->parseq->flag= SELECT;
2222         recurs_sel_seq(ms->parseq);
2223
2224         MEM_freeN(ms);
2225         allqueue(REDRAWSEQ, 0);
2226
2227         BIF_undo_push("Exit meta strip Sequence");
2228 }
2229
2230
2231 void enter_meta(void)
2232 {
2233         MetaStack *ms;
2234         Editing *ed;
2235         Sequence *last_seq= get_last_seq();
2236
2237         ed= G.scene->ed;
2238         if(ed==0) return;
2239
2240         if(last_seq==0 || last_seq->type!=SEQ_META || last_seq->flag==0) {
2241                 exit_meta();
2242                 return;
2243         }
2244
2245         ms= MEM_mallocN(sizeof(MetaStack), "metastack");
2246         BLI_addtail(&ed->metastack, ms);
2247         ms->parseq= last_seq;
2248         ms->oldbasep= ed->seqbasep;
2249
2250         ed->seqbasep= &last_seq->seqbase;
2251
2252         set_last_seq(NULL);
2253         allqueue(REDRAWSEQ, 0);
2254         BIF_undo_push("Enter meta strip Sequence");
2255 }
2256
2257
2258 /* ****************** END META ************************* */
2259
2260
2261 typedef struct TransSeq {
2262         int start, machine;
2263         int startstill, endstill;
2264         int startdisp, enddisp;
2265         int startofs, endofs;
2266         int len;
2267 } TransSeq;
2268
2269 void transform_seq(int mode, int context)
2270 {
2271         Sequence *seq;
2272         Editing *ed;
2273         float dx, dy, dvec[2], div;
2274         TransSeq *transmain, *ts;
2275         int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0;
2276         unsigned short event = 0;
2277         short mval[2], val, xo, yo, xn, yn;
2278         char str[32];
2279
2280         if(mode!='g') return;   /* from gesture */
2281
2282         /* which seqs are involved */
2283         ed= G.scene->ed;
2284         if(ed==0) return;
2285
2286         WHILE_SEQ(ed->seqbasep) {
2287                 if(seq->flag & SELECT) tot++;
2288         }
2289         END_SEQ
2290
2291         if(tot==0) return;
2292
2293         G.moving= 1;
2294
2295         ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
2296
2297         WHILE_SEQ(ed->seqbasep) {
2298
2299                 if(seq->flag & SELECT) {
2300
2301                         ts->start= seq->start;
2302                         ts->machine= seq->machine;
2303                         ts->startstill= seq->startstill;
2304                         ts->endstill= seq->endstill;
2305                         ts->startofs= seq->startofs;
2306                         ts->endofs= seq->endofs;
2307
2308                         ts++;
2309                 }
2310         }
2311         END_SEQ
2312
2313         getmouseco_areawin(mval);
2314         xo=xn= mval[0];
2315         yo=yn= mval[1];
2316         dvec[0]= dvec[1]= 0.0;
2317
2318         while(afbreek==0) {
2319                 getmouseco_areawin(mval);
2320                 if(mval[0]!=xo || mval[1]!=yo || firsttime) {
2321                         firsttime= 0;
2322
2323                         if(mode=='g') {
2324
2325                                 dx= mval[0]- xo;
2326                                 dy= mval[1]- yo;
2327
2328                                 div= G.v2d->mask.xmax-G.v2d->mask.xmin;
2329                                 dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
2330
2331                                 div= G.v2d->mask.ymax-G.v2d->mask.ymin;
2332                                 dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
2333
2334                                 if(G.qual & LR_SHIFTKEY) {
2335                                         if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
2336                                 }
2337
2338                                 dvec[0]+= dx;
2339                                 dvec[1]+= dy;
2340
2341                                 if(midtog) dvec[proj]= 0.0;
2342                                 ix= floor(dvec[0]+0.5);
2343                                 iy= floor(dvec[1]+0.5);
2344
2345
2346                                 ts= transmain;
2347
2348                                 WHILE_SEQ(ed->seqbasep) {
2349                                         if(seq->flag & SELECT) {
2350                                                 if(seq->flag & SEQ_LEFTSEL) {
2351                                                         if(ts->startstill) {
2352                                                                 seq->startstill= ts->startstill-ix;
2353                                                                 if(seq->startstill<0) seq->startstill= 0;
2354                                                         }
2355                                                         else if(ts->startofs) {
2356                                                                 seq->startofs= ts->startofs+ix;
2357                                                                 if(seq->startofs<0) seq->startofs= 0;
2358                                                         }
2359                                                         else {
2360                                                                 if(ix>0) {
2361                                                                         seq->startofs= ix;
2362                                                                         seq->startstill= 0;
2363                                                                 }
2364                                                                 else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
2365                                                                         seq->startstill= -ix;
2366                                                                         seq->startofs= 0;
2367                                                                 }
2368                                                         }
2369                                                         if(seq->len <= seq->startofs+seq->endofs) {
2370                                                                 seq->startofs= seq->len-seq->endofs-1;
2371                                                         }
2372                                                 }
2373                                                 if(seq->flag & SEQ_RIGHTSEL) {
2374                                                         if(ts->endstill) {
2375                                                                 seq->endstill= ts->endstill+ix;
2376                                                                 if(seq->endstill<0) seq->endstill= 0;
2377                                                         }
2378                                                         else if(ts->endofs) {
2379                                                                 seq->endofs= ts->endofs-ix;
2380                                                                 if(seq->endofs<0) seq->endofs= 0;
2381                                                         }
2382                                                         else {
2383                                                                 if(ix<0) {
2384                                                                         seq->endofs= -ix;
2385                                                                         seq->endstill= 0;
2386                                                                 }
2387                                                                 else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
2388                                                                         seq->endstill= ix;
2389                                                                         seq->endofs= 0;
2390                                                                 }
2391                                                         }
2392                                                         if(seq->len <= seq->startofs+seq->endofs) {
2393                                                                 seq->endofs= seq->len-seq->startofs-1;
2394                                                         }
2395                                                 }
2396                                                 if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
2397                                                         if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
2398
2399                                                         if(seq->depth==0) seq->machine= ts->machine+ iy;
2400
2401                                                         if(seq->machine<1) seq->machine= 1;
2402                                                         else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
2403                                                 }
2404
2405                                                 calc_sequence(seq);
2406
2407                                                 ts++;
2408                                         }
2409                                 }
2410                                 END_SEQ
2411
2412                                 sprintf(str, "X: %d   Y: %d  ", ix, iy);
2413                                 headerprint(str);
2414                         }
2415
2416                         xo= mval[0];
2417                         yo= mval[1];
2418
2419                         /* test for effect and overlap */
2420
2421                         WHILE_SEQ(ed->seqbasep) {
2422                                 if(seq->flag & SELECT) {
2423                                         seq->flag &= ~SEQ_OVERLAP;
2424                                         if( test_overlap_seq(seq) ) {
2425                                                 seq->flag |= SEQ_OVERLAP;
2426                                         }
2427                                 }
2428                                 else if(seq->type & SEQ_EFFECT) {
2429                                         if(seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
2430                                         else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
2431                                         else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
2432                                 }
2433                         }
2434                         END_SEQ;
2435
2436                         force_draw(0);
2437                 }
2438                 else BIF_wait_for_statechange();
2439
2440                 while(qtest()) {
2441                         event= extern_qread(&val);
2442                         if(val) {
2443                                 switch(event) {
2444                                 case ESCKEY:
2445                                 case LEFTMOUSE:
2446                                 case RIGHTMOUSE:
2447                                 case SPACEKEY:
2448                                 case RETKEY:
2449                                         afbreek= 1;
2450                                         break;
2451                                 case MIDDLEMOUSE:
2452                                         midtog= ~midtog;
2453                                         if(midtog) {
2454                                                 if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1;
2455                                                 else proj= 0;
2456                                                 firsttime= 1;
2457                                         }
2458                                         break;
2459                                 default:
2460                                         arrows_move_cursor(event);
2461                                 }
2462                         }
2463                         if(afbreek) break;
2464                 }
2465         }
2466
2467         if((event==ESCKEY) || (event==RIGHTMOUSE)) {
2468
2469                 ts= transmain;
2470                 WHILE_SEQ(ed->seqbasep) {
2471                         if(seq->flag & SELECT) {
2472                                 seq->start= ts->start;
2473                                 seq->machine= ts->machine;
2474                                 seq->startstill= ts->startstill;
2475                                 seq->endstill= ts->endstill;
2476                                 seq->startofs= ts->startofs;
2477                                 seq->endofs= ts->endofs;
2478
2479                                 calc_sequence(seq);
2480                                 seq->flag &= ~SEQ_OVERLAP;
2481
2482                                 ts++;
2483                         } else if(seq->type & SEQ_EFFECT) {
2484                                 if(seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
2485                                 else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
2486                                 else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
2487                         }
2488
2489                 }
2490                 END_SEQ
2491         }
2492         else {
2493
2494                 /* images, effects and overlap */
2495                 WHILE_SEQ(ed->seqbasep) {
2496                         if(seq->type == SEQ_META) {
2497                                 calc_sequence(seq);
2498                                 seq->flag &= ~SEQ_OVERLAP;
2499                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
2500                         }
2501                         else if(seq->flag & SELECT) {
2502                                 calc_sequence(seq);
2503                                 seq->flag &= ~SEQ_OVERLAP;
2504                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
2505                         }
2506                         else if(seq->type & SEQ_EFFECT) calc_sequence(seq);
2507                 }
2508                 END_SEQ
2509
2510                 /* as last: */
2511                 sort_seq();
2512         }
2513
2514         G.moving= 0;
2515         MEM_freeN(transmain);
2516
2517         BIF_undo_push("Transform Sequencer");
2518         allqueue(REDRAWSEQ, 0);
2519 }
2520
2521 void seq_cut(int cutframe)
2522 {
2523         Editing *ed;
2524         Sequence *seq;
2525         TransSeq *ts, *transmain;
2526         int tot=0;
2527         ListBase newlist;
2528         
2529         ed= G.scene->ed;
2530         if(ed==0) return;
2531         
2532         /* test for validity */
2533         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2534                 if(seq->flag & SELECT) {
2535                         if(cutframe > seq->startdisp && cutframe < seq->enddisp)
2536                                 if(seq->type==SEQ_META) break;
2537                 }
2538         }
2539         if(seq) {
2540                 error("Cannot cut Meta strips");
2541                 return;
2542         }
2543         
2544         /* we build an array of TransSeq, to denote which strips take part in cutting */
2545         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2546                 if(seq->flag & SELECT) {
2547                         if(cutframe > seq->startdisp && cutframe < seq->enddisp)
2548                                 tot++;
2549                         else
2550                                 seq->flag &= ~SELECT;   // bad code, but we need it for recurs_dupli_seq... note that this ~SELECT assumption is used in loops below too (ton)
2551                 }
2552         }
2553         
2554         if(tot==0) {
2555                 error("No strips to cut");
2556                 return;
2557         }
2558         
2559         ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
2560         
2561         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2562                 if(seq->flag & SELECT) {
2563                         
2564                         ts->start= seq->start;
2565                         ts->machine= seq->machine;
2566                         ts->startstill= seq->startstill;
2567                         ts->endstill= seq->endstill;
2568                         ts->startdisp= seq->startdisp;
2569                         ts->enddisp= seq->enddisp;
2570                         ts->startofs= seq->startofs;
2571                         ts->endofs= seq->endofs;
2572                         ts->len= seq->len;
2573                         
2574                         ts++;
2575                 }
2576         }
2577                 
2578         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2579                 if(seq->flag & SELECT) {
2580                         
2581                         /* strips with extended stillframes before */
2582                         if ((seq->startstill) && (cutframe <seq->start)) {
2583                                 seq->start= cutframe -1;
2584                                 seq->startstill= cutframe -seq->startdisp -1;
2585                                 seq->len= 1;
2586                                 seq->endstill= 0;
2587                         }
2588                         
2589                         /* normal strip */
2590                         else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
2591                                 seq->endofs = (seq->start+seq->len) - cutframe;
2592                         }
2593                         
2594                         /* strips with extended stillframes after */
2595                         else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
2596                                 seq->endstill -= seq->enddisp - cutframe;
2597                         }
2598                         
2599                         calc_sequence(seq);
2600                 }
2601         }
2602                 
2603         newlist.first= newlist.last= NULL;
2604         
2605         /* now we duplicate the cut strip and move it into place afterwards */
2606         recurs_dupli_seq(ed->seqbasep, &newlist);
2607         addlisttolist(ed->seqbasep, &newlist);
2608         
2609         ts= transmain;
2610         
2611         /* go through all the strips and correct them based on their stored values */
2612         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2613                 if(seq->flag & SELECT) {
2614
2615                         /* strips with extended stillframes before */
2616                         if ((seq->startstill) && (cutframe == seq->start + 1)) {
2617                                 seq->start = ts->start;
2618                                 seq->startstill= ts->start- cutframe;
2619                                 seq->len = ts->len;
2620                                 seq->endstill = ts->endstill;
2621                         }
2622                         
2623                         /* normal strip */
2624                         else if ((cutframe>=seq->start)&&(cutframe<=(seq->start+seq->len))) {
2625                                 seq->startstill = 0;
2626                                 seq->startofs = cutframe - ts->start;
2627                                 seq->endofs = ts->endofs;
2628                                 seq->endstill = ts->endstill;
2629                         }                               
2630                         
2631                         /* strips with extended stillframes after */
2632                         else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
2633                                 seq->start = cutframe - ts->len +1;
2634                                 seq->startofs = ts->len-1;
2635                                 seq->endstill = ts->enddisp - cutframe -1;
2636                                 seq->startstill = 0;
2637                         }
2638                         calc_sequence(seq);
2639                         
2640                         ts++;
2641                 }
2642         }
2643                 
2644         /* as last: */  
2645         sort_seq();
2646         MEM_freeN(transmain);
2647         
2648         allqueue(REDRAWSEQ, 0);
2649 }
2650
2651 void seq_snap_menu(void)
2652 {
2653         short event;
2654
2655         event= pupmenu("Snap %t|To Current Frame%x1");
2656         if(event < 1) return;
2657
2658         seq_snap(event);
2659 }
2660
2661 void seq_snap(short event)
2662 {
2663         Editing *ed;
2664         Sequence *seq;
2665
2666         ed= G.scene->ed;
2667         if(ed==0) return;
2668
2669         /* problem: contents of meta's are all shifted to the same position... */
2670
2671         /* also check metas */
2672         WHILE_SEQ(ed->seqbasep) {
2673                 if(seq->flag & SELECT) {
2674                         if(sequence_is_free_transformable(seq)) seq->start= CFRA-seq->startofs+seq->startstill;
2675                         calc_sequence(seq);
2676                 }
2677         }
2678         END_SEQ
2679
2680
2681         /* test for effects and overlap */
2682         WHILE_SEQ(ed->seqbasep) {
2683                 if(seq->flag & SELECT) {
2684                         seq->flag &= ~SEQ_OVERLAP;
2685                         if( test_overlap_seq(seq) ) {
2686                                 shuffle_seq(seq);
2687                         }
2688                 }
2689                 else if(seq->type & SEQ_EFFECT) {
2690                         if(seq->seq1->flag & SELECT) calc_sequence(seq);
2691                         else if(seq->seq2->flag & SELECT) calc_sequence(seq);
2692                         else if(seq->seq3->flag & SELECT) calc_sequence(seq);
2693                 }
2694         }
2695         END_SEQ;
2696
2697         /* as last: */
2698         sort_seq();
2699
2700         BIF_undo_push("Snap menu Sequencer");
2701         allqueue(REDRAWSEQ, 0);
2702 }
2703
2704 void borderselect_seq(void)
2705 {
2706         Sequence *seq;
2707         Editing *ed;
2708         rcti rect;
2709         rctf rectf, rq;
2710         int val;
2711         short mval[2];
2712
2713         ed= G.scene->ed;
2714         if(ed==0) return;
2715
2716         val= get_border(&rect, 3);
2717
2718         if(val) {
2719                 mval[0]= rect.xmin;
2720                 mval[1]= rect.ymin;
2721                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
2722                 mval[0]= rect.xmax;
2723                 mval[1]= rect.ymax;
2724                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
2725
2726                 seq= ed->seqbasep->first;
2727                 while(seq) {
2728
2729                         if(seq->startstill) rq.xmin= seq->start;
2730                         else rq.xmin= seq->startdisp;
2731                         rq.ymin= seq->machine+0.2;
2732                         if(seq->endstill) rq.xmax= seq->start+seq->len;
2733                         else rq.xmax= seq->enddisp;
2734                         rq.ymax= seq->machine+0.8;
2735
2736                         if(BLI_isect_rctf(&rq, &rectf, 0)) {
2737                                 if(val==LEFTMOUSE) {
2738                                         seq->flag |= SELECT;
2739                                 }
2740                                 else {
2741                                         seq->flag &= ~SELECT;
2742                                 }
2743                                 recurs_sel_seq(seq);
2744                         }
2745
2746                         seq= seq->next;
2747                 }
2748
2749                 BIF_undo_push("Border select Sequencer");
2750                 addqueue(curarea->win, REDRAW, 1);
2751         }
2752 }