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