adfe3205f920423e2a75b05808b6923204d054ac
[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         return 0;
1050 }
1051
1052 static int can_insert_seq_between(Sequence *seq1, 
1053                                   Sequence *seq2, Sequence *seq3)
1054 {
1055        Editing *ed= G.scene->ed;
1056        Sequence *seq;
1057
1058        if (seq1 == 0 || seq2 == 0 || seq3 == 0) {
1059                return 0;
1060        }
1061
1062        /* see if inserting inbetween would create a cycle */
1063        if(seq_is_predecessor(seq1, seq2) || seq_is_predecessor(seq2, seq1) ||
1064           seq_is_predecessor(seq2, seq3) || seq_is_predecessor(seq3, seq2) ||
1065           seq_is_predecessor(seq3, seq1) || seq_is_predecessor(seq1, seq3))
1066                return 0;
1067
1068        /* see if there is a parent that we can insert inbetween */
1069        for(seq=ed->seqbasep->first; seq; seq=seq->next)
1070                if((seq != seq1) && (seq != seq2) && (seq != seq3))
1071                        if(seq_is_parent(seq, seq1) || 
1072                           seq_is_parent(seq, seq2) ||
1073                           seq_is_parent(seq, seq3))
1074                                return 1;
1075
1076        return 0;
1077 }
1078
1079
1080 static int seq_effect_find_selected(Editing *ed, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3)
1081 {
1082         Sequence *seq1= 0, *seq2= 0, *seq3= 0, *seq;
1083         
1084         if (!activeseq)
1085                 seq2= get_last_seq();
1086
1087         for(seq=ed->seqbasep->first; seq; seq=seq->next) {
1088                 if(seq->flag & SELECT) {
1089                         if (seq->type == SEQ_RAM_SOUND
1090                             || seq->type == SEQ_HD_SOUND) { 
1091                                 error("Can't apply effects to "
1092                                       "audio sequence strips");
1093                                 return 0;
1094                         }
1095                         if((seq != activeseq) && (seq != seq2)) {
1096                                 if(seq2==0) seq2= seq;
1097                                 else if(seq1==0) seq1= seq;
1098                                 else if(seq3==0) seq3= seq;
1099                                 else {
1100                                        error("Can't apply effect to more than 3 sequence strips");
1101                                        return 0;
1102                                 }
1103                         }
1104                 }
1105         }
1106        
1107         /* make sequence selection a little bit more intuitive
1108            for 3 strips: the last-strip should be sequence3 */
1109         if (seq3 != 0 && seq2 != 0) {
1110                 Sequence *tmp = seq2;
1111                 seq2 = seq3;
1112                 seq3 = tmp;
1113         }
1114         
1115
1116         switch(get_sequence_effect_num_inputs(type)) {
1117         case 0:
1118                 seq1 = seq2 = seq3 = 0;
1119                 break;
1120         case 1:
1121                 if(seq2==0)  {
1122                         error("Need at least one selected sequence strip");
1123                         return 0;
1124                 }
1125                 if(seq1==0) seq1= seq2;
1126                 if(seq3==0) seq3= seq2;
1127         case 2:
1128                 if(seq1==0 || seq2==0) {
1129                         error("Need 2 selected sequence strips");
1130                         return 0;
1131                 }
1132                 if(seq3==0) seq3= seq2;
1133         }
1134
1135         *selseq1= seq1;
1136         *selseq2= seq2;
1137         *selseq3= seq3;
1138
1139         return 1;
1140 }
1141
1142 static void insert_seq_between(Sequence *newseq, Sequence *seq1, Sequence *seq2, Sequence *seq3)
1143 {
1144        Editing *ed= G.scene->ed;
1145        Sequence *seq, *firstseq = NULL;
1146        Sequence *oldseq[3];
1147        int i;
1148
1149        oldseq[0]= seq1;
1150        oldseq[1]= seq2;
1151        oldseq[2]= seq3;
1152
1153        for(seq=ed->seqbasep->first; seq; seq=seq->next) {
1154                if((seq != seq1) && (seq != seq2) && (seq != seq3)) {
1155                        /* set pointers to new children */
1156                        for(i=0; i < 3; i++) {
1157                                if(seq_is_parent(seq, oldseq[i]) && (seq != newseq)) {
1158                                        if(seq->seq1 == oldseq[i]) seq->seq1= newseq;
1159                                        if(seq->seq2 == oldseq[i]) seq->seq2= newseq;
1160                                        if(seq->seq3 == oldseq[i]) seq->seq3= newseq;
1161                                        if(!firstseq) firstseq= seq;
1162                                }
1163                        }
1164                }
1165        }
1166
1167        /* reinsert sequence in the list before the first sequence depending on it,
1168           this is needed for the strips to be evaluated in correct order */
1169        if(firstseq) {
1170                BLI_remlink(ed->seqbasep, newseq);
1171                BLI_insertlinkbefore(ed->seqbasep, firstseq, newseq);
1172        }
1173 }
1174
1175
1176 static int add_seq_effect(int type, char *str)
1177 {
1178         Editing *ed;
1179         Sequence *newseq, *seq1, *seq2, *seq3;
1180         Strip *strip;
1181         float x, y;
1182         int cfra, machine;
1183         short mval[2];
1184         struct SeqEffectHandle sh;
1185         int mode, insertbetween= 0;
1186
1187         if(G.scene->ed==0) return 0;
1188         ed= G.scene->ed;
1189
1190         if(!seq_effect_find_selected(ed, NULL, event_to_efftype(type), &seq1, &seq2, &seq3))
1191                 return 0;
1192
1193          if (can_insert_seq_between(seq1, seq2, seq3)) {
1194                 force_draw(0); /* to make sure popup is not drawn over file select */
1195                 mode= pupmenu("Insert Between %x1|Insert After %x2");
1196                 if(mode == 1)
1197                         insertbetween= 1;
1198         }
1199
1200         deselect_all_seq();
1201
1202         /* where will it be (cfra is not realy needed) */
1203         getmouseco_areawin(mval);
1204         areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1205         cfra= (int)(x+0.5);
1206         machine= (int)(y+0.5);
1207
1208         /* allocate and initialize */
1209         newseq= alloc_sequence(cfra, machine);
1210         newseq->type= event_to_efftype(type);
1211
1212         sh = get_sequence_effect(newseq);
1213
1214         newseq->seq1= seq1;
1215         newseq->seq2= seq2;
1216         newseq->seq3= seq3;
1217
1218         sh.init(newseq);
1219
1220         if (!seq1) {
1221                 newseq->len= 1;
1222                 newseq->startstill= 25;
1223                 newseq->endstill= 24;
1224         }
1225
1226         calc_sequence(newseq);
1227
1228         newseq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
1229         strip->len= newseq->len;
1230         strip->us= 1;
1231         if(newseq->len>0)
1232                 strip->stripdata= MEM_callocN(newseq->len*sizeof(StripElem), "stripelem");
1233
1234         /* initialize plugin */
1235         if(newseq->type == SEQ_PLUGIN) {
1236                 sh.init_plugin(newseq, str);
1237
1238                 if(newseq->plugin==0) {
1239                         BLI_remlink(ed->seqbasep, newseq);
1240                         free_sequence(newseq);
1241                         set_last_seq(NULL);
1242                         return 0;
1243                 }
1244         }
1245
1246         /* set find a free spot to but the strip */
1247         if (newseq->seq1) {
1248                 newseq->machine= MAX3(newseq->seq1->machine, 
1249                                       newseq->seq2->machine,
1250                                       newseq->seq3->machine);
1251         }
1252         if(test_overlap_seq(newseq)) shuffle_seq(newseq);
1253
1254         /* set inbetween relation */
1255         if(insertbetween)
1256                 insert_seq_between(newseq, seq1, seq2, seq3);
1257
1258         update_changed_seq_and_deps(newseq, 1, 1);
1259
1260         /* push undo and go into grab mode */
1261         if(newseq->type == SEQ_PLUGIN) {
1262                 BIF_undo_push("Add plugin strip Sequencer");
1263         } else {
1264                 BIF_undo_push("Add effect strip Sequencer");
1265         }
1266
1267         transform_seq('g', 0);
1268
1269         return 1;
1270 }
1271
1272 static void load_plugin_seq(char *str)          /* called from fileselect */
1273 {
1274         add_seq_effect(10, str);
1275 }
1276
1277 void add_sequence(int type)
1278 {
1279         Editing *ed;
1280         Sequence *seq;
1281         Strip *strip;
1282         Scene *sce;
1283         float x, y;
1284         int cfra, machine;
1285         short nr, event, mval[2];
1286         char *str;
1287
1288         if (type >= 0){
1289                 /* bypass pupmenu for calls from menus (aphex) */
1290                 switch(type){
1291                 case SEQ_SCENE:
1292                         event = 101;
1293                         break;
1294                 case SEQ_IMAGE:
1295                         event = 1;
1296                         break;
1297                 case SEQ_MOVIE:
1298                         event = 102;
1299                         break;
1300                 case SEQ_RAM_SOUND:
1301                         event = 103;
1302                         break;
1303                 case SEQ_HD_SOUND:
1304                         event = 104;
1305                         break;
1306                 case SEQ_MOVIE_AND_HD_SOUND:
1307                         event = 105;
1308                         break;
1309                 case SEQ_PLUGIN:
1310                         event = 10;
1311                         break;
1312                 case SEQ_CROSS:
1313                         event = 2;
1314                         break;
1315                 case SEQ_ADD:
1316                         event = 4;
1317                         break;
1318                 case SEQ_SUB:
1319                         event = 5;
1320                         break;
1321                 case SEQ_ALPHAOVER:
1322                         event = 7;
1323                         break;
1324                 case SEQ_ALPHAUNDER:
1325                         event = 8;
1326                         break;
1327                 case SEQ_GAMCROSS:
1328                         event = 3;
1329                         break;
1330                 case SEQ_MUL:
1331                         event = 6;
1332                         break;
1333                 case SEQ_OVERDROP:
1334                         event = 9;
1335                         break;
1336                 case SEQ_WIPE:
1337                         event = 13;
1338                         break;
1339                 case SEQ_GLOW:
1340                         event = 14;
1341                         break;
1342                 case SEQ_TRANSFORM:
1343                         event = 15;
1344                         break;
1345                 case SEQ_COLOR:
1346                         event = 16;
1347                         break;
1348                 default:
1349                         event = 0;
1350                         break;
1351                 }
1352         }
1353         else {
1354                 event= pupmenu("Add Sequence Strip%t"
1355                                "|Images%x1"
1356                                "|Movie%x102"
1357 #ifdef WITH_FFMPEG
1358                                    "|Movie + Audio (HD)%x105"
1359                                "|Audio (RAM)%x103"
1360                                "|Audio (HD)%x104"
1361 #else
1362                                    "|Audio (Wav)%x103"
1363 #endif
1364                                "|Scene%x101"
1365                                "|Plugin%x10"
1366                                "|Cross%x2"
1367                                "|Gamma Cross%x3"
1368                                "|Add%x4"
1369                                "|Sub%x5"
1370                                "|Mul%x6"
1371                                "|Alpha Over%x7"
1372                                "|Alpha Under%x8"
1373                                "|Alpha Over Drop%x9"
1374                                "|Wipe%x13"
1375                                "|Glow%x14"
1376                                "|Transforms%x15"
1377                                "|Color Generator%x16");
1378         }
1379
1380         if(event<1) return;
1381
1382         if(G.scene->ed==0) {
1383                 ed= G.scene->ed= MEM_callocN( sizeof(Editing), "addseq");
1384                 ed->seqbasep= &ed->seqbase;
1385         }
1386         else ed= G.scene->ed;
1387
1388         switch(event) {
1389         case 1:
1390
1391                 activate_fileselect(FILE_SPECIAL, "Select Images", last_imagename, add_image_strips);
1392                 break;
1393         case 105:
1394                 activate_fileselect(FILE_SPECIAL, "Select Movie+Audio", last_imagename, add_movie_and_hdaudio_strip);
1395                 break;
1396         case 102:
1397
1398                 activate_fileselect(FILE_SPECIAL, "Select Movie", last_imagename, add_movie_strip);
1399                 break;
1400         case 101:
1401                 /* new menu: */
1402                 IDnames_to_pupstring(&str, NULL, NULL, &G.main->scene, (ID *)G.scene, NULL);
1403
1404                 event= pupmenu_col(str, 20);
1405
1406                 if(event> -1) {
1407                         nr= 1;
1408                         sce= G.main->scene.first;
1409                         while(sce) {
1410                                 if( event==nr) break;
1411                                 nr++;
1412                                 sce= sce->id.next;
1413                         }
1414                         if(sce) {
1415
1416                                 deselect_all_seq();
1417
1418                                 /* where ? */
1419                                 getmouseco_areawin(mval);
1420                                 areamouseco_to_ipoco(G.v2d, mval, &x, &y);
1421                                 cfra= (int)(x+0.5);
1422                                 machine= (int)(y+0.5);
1423
1424                                 seq= alloc_sequence(cfra, machine);
1425                                 seq->type= SEQ_SCENE;
1426                                 seq->scene= sce;
1427                                 seq->sfra= sce->r.sfra;
1428                                 seq->len= sce->r.efra - sce->r.sfra + 1;
1429
1430                                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
1431                                 strncpy(seq->name + 2, sce->id.name + 2, 
1432                                         sizeof(seq->name) - 2);
1433                                 strip->len= seq->len;
1434                                 strip->us= 1;
1435                                 if(seq->len>0) strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1436
1437                                 BIF_undo_push("Add scene strip Sequencer");
1438                                 transform_seq('g', 0);
1439                         }
1440                 }
1441                 MEM_freeN(str);
1442
1443                 break;
1444         case 2:
1445         case 3:
1446         case 4:
1447         case 5:
1448         case 6:
1449         case 7:
1450         case 8:
1451         case 9:
1452         case 10:
1453         case 13:
1454         case 14:
1455         case 15:
1456         case 16:
1457                 if(get_last_seq()==0 && 
1458                    get_sequence_effect_num_inputs( event_to_efftype(event))> 0)
1459                         error("Need at least one active sequence strip");
1460                 else if(event==10)
1461                         activate_fileselect(FILE_SPECIAL, "Select Plugin", U.plugseqdir, load_plugin_seq);
1462                 else
1463                         add_seq_effect(event, NULL);
1464
1465                 break;
1466         case 103:
1467                 if (!last_sounddir[0]) strncpy(last_sounddir, U.sounddir, FILE_MAXDIR-1);
1468                 activate_fileselect(FILE_SPECIAL, "Select Audio (RAM)", last_sounddir, add_sound_strip_ram);
1469                 break;
1470         case 104:
1471                 if (!last_sounddir[0]) strncpy(last_sounddir, U.sounddir, FILE_MAXDIR-1);
1472                 activate_fileselect(FILE_SPECIAL, "Select Audio (HD)", last_sounddir, add_sound_strip_hd);
1473                 break;
1474         }
1475 }
1476
1477 void change_sequence(void)
1478 {
1479         Sequence *last_seq= get_last_seq();
1480         Scene *sce;
1481         short event;
1482
1483         if(last_seq==0) return;
1484
1485         if(last_seq->type & SEQ_EFFECT) {
1486                 event = pupmenu("Change Effect%t"
1487                                 "|Switch A <-> B %x1"
1488                                 "|Switch B <-> C %x10"
1489                                 "|Plugin%x11"
1490                                 "|Recalculate%x12"
1491                                 "|Cross%x2"
1492                                 "|Gamma Cross%x3"
1493                                 "|Add%x4"
1494                                 "|Sub%x5"
1495                                 "|Mul%x6"
1496                                 "|Alpha Over%x7"
1497                                 "|Alpha Under%x8"
1498                                 "|Alpha Over Drop%x9"
1499                                 "|Wipe%x13"
1500                                 "|Glow%x14"
1501                                 "|Transform%x15"
1502                                 "|Color Generator%x16");
1503                 if(event > 0) {
1504                         if(event==1) {
1505                                 SWAP(Sequence *,last_seq->seq1,last_seq->seq2);
1506                         }
1507                         else if(event==10) {
1508                                 SWAP(Sequence *,last_seq->seq2,last_seq->seq3);
1509                         }
1510                         else if(event==11) {
1511                                 activate_fileselect(
1512                                         FILE_SPECIAL, "Select Plugin", 
1513                                         U.plugseqdir, change_plugin_seq);
1514                         }
1515                         else if(event==12);     
1516                                 /* recalculate: only new_stripdata */
1517                         else {
1518                                 /* free previous effect and init new effect */
1519                                 struct SeqEffectHandle sh;
1520
1521                                 if (get_sequence_effect_num_inputs(
1522                                             last_seq->type)
1523                                     < get_sequence_effect_num_inputs(
1524                                             event_to_efftype(event))) {
1525                                         error("New effect needs more "
1526                                               "input strips!");
1527                                 } else {
1528                                         sh = get_sequence_effect(last_seq);
1529                                         sh.free(last_seq);
1530                                         
1531                                         last_seq->type 
1532                                                 = event_to_efftype(event);
1533                                         
1534                                         sh = get_sequence_effect(last_seq);
1535                                         sh.init(last_seq);
1536                                 }
1537                         }
1538
1539                         update_changed_seq_and_deps(last_seq, 0, 1);
1540                         allqueue(REDRAWSEQ, 0);
1541                         BIF_undo_push("Change effect Sequencer");
1542                 }
1543         }
1544         else if(last_seq->type == SEQ_IMAGE) {
1545                 if(okee("Change images")) {
1546                         activate_fileselect(FILE_SPECIAL, 
1547                                             "Select Images", 
1548                                             last_imagename, 
1549                                             reload_image_strip);
1550                 }
1551         }
1552         else if(last_seq->type == SEQ_MOVIE) {
1553                 ;
1554         }
1555         else if(last_seq->type == SEQ_SCENE) {
1556                 event= pupmenu("Change Scene%t|Update Start and End");
1557
1558                 if(event==1) {
1559                         sce= last_seq->scene;
1560
1561                         last_seq->len= sce->r.efra - sce->r.sfra + 1;
1562                         last_seq->sfra= sce->r.sfra;
1563                         update_changed_seq_and_deps(last_seq, 1, 1);
1564
1565                         allqueue(REDRAWSEQ, 0);
1566                 }
1567         }
1568
1569 }
1570
1571 void reassign_inputs_seq_effect()
1572 {
1573         Editing *ed= G.scene->ed;
1574         Sequence *seq1, *seq2, *seq3, *last_seq = get_last_seq();
1575
1576         if(last_seq==0 || !(last_seq->type & SEQ_EFFECT)) return;
1577         if(ed==0) return;
1578
1579         if(!seq_effect_find_selected(ed, last_seq, last_seq->type, &seq1, &seq2, &seq3))
1580                 return;
1581
1582         /* see reassigning would create a cycle */
1583         if(seq_is_predecessor(seq1, last_seq) || seq_is_predecessor(seq2, last_seq) ||
1584            seq_is_predecessor(seq3, last_seq)) {
1585                 error("Can't reassign inputs: no cycles allowed");
1586                 return;
1587         }
1588         
1589         last_seq->seq1 = seq1;
1590         last_seq->seq2 = seq2;
1591         last_seq->seq3 = seq3;
1592
1593         update_changed_seq_and_deps(last_seq, 1, 1);
1594
1595         allqueue(REDRAWSEQ, 0);
1596 }
1597
1598 static Sequence *del_seq_find_replace_recurs(Sequence *seq)
1599 {
1600         Sequence *seq1, *seq2, *seq3;
1601
1602         /* try to find a replacement input sequence, and flag for later deletion if
1603            no replacement can be found */
1604
1605         if(!seq)
1606                 return NULL;
1607         else if(!(seq->type & SEQ_EFFECT))
1608                 return ((seq->flag & SELECT)? NULL: seq);
1609         else if(!(seq->flag & SELECT)) {
1610                 /* try to find replacement for effect inputs */
1611                 seq1= del_seq_find_replace_recurs(seq->seq1);
1612                 seq2= del_seq_find_replace_recurs(seq->seq2);
1613                 seq3= del_seq_find_replace_recurs(seq->seq3);
1614
1615                 if(seq1==seq->seq1 && seq2==seq->seq2 && seq3==seq->seq3);
1616                 else if(seq1 || seq2 || seq3) {
1617                         seq->seq1= (seq1)? seq1: (seq2)? seq2: seq3;
1618                         seq->seq2= (seq2)? seq2: (seq1)? seq1: seq3;
1619                         seq->seq3= (seq3)? seq3: (seq1)? seq1: seq2;
1620
1621                         update_changed_seq_and_deps(seq, 1, 1);
1622                 }
1623                 else
1624                         seq->flag |= SELECT; /* mark for delete */
1625         }
1626
1627         if (seq->flag & SELECT) {
1628                 if((seq1 = del_seq_find_replace_recurs(seq->seq1))) return seq1;
1629                 if((seq2 = del_seq_find_replace_recurs(seq->seq2))) return seq2;
1630                 if((seq3 = del_seq_find_replace_recurs(seq->seq3))) return seq3;
1631                 else return NULL;
1632         }
1633         else
1634                 return seq;
1635 }
1636
1637 static void recurs_del_seq_flag(ListBase *lb, short flag, short deleteall)
1638 {
1639         Sequence *seq, *seqn;
1640         Sequence *last_seq = get_last_seq();
1641
1642         seq= lb->first;
1643         while(seq) {
1644                 seqn= seq->next;
1645                 if((seq->flag & flag) || deleteall) {
1646                         if(seq->type==SEQ_RAM_SOUND && seq->sound) 
1647                                 seq->sound->id.us--;
1648
1649                         BLI_remlink(lb, seq);
1650                         if(seq==last_seq) set_last_seq(0);
1651                         if(seq->type==SEQ_META) recurs_del_seq_flag(&seq->seqbase, flag, 1);
1652                         if(seq->ipo) seq->ipo->id.us--;
1653                         free_sequence(seq);
1654                 }
1655                 seq= seqn;
1656         }
1657 }
1658
1659 void del_seq(void)
1660 {
1661         Sequence *seq;
1662         MetaStack *ms;
1663         Editing *ed;
1664
1665         if(okee("Erase selected")==0) return;
1666
1667         ed= G.scene->ed;
1668         if(ed==0) return;
1669
1670         /* free imbufs of all dependent strips */
1671         for(seq=ed->seqbasep->first; seq; seq=seq->next)
1672                 if(seq->flag & SELECT)
1673                         update_changed_seq_and_deps(seq, 1, 0);
1674
1675         /* for effects, try to find a replacement input */
1676         for(seq=ed->seqbasep->first; seq; seq=seq->next)
1677                 if((seq->type & SEQ_EFFECT) && !(seq->flag & SELECT))
1678                         del_seq_find_replace_recurs(seq);
1679
1680         /* delete all selected strips */
1681         recurs_del_seq_flag(ed->seqbasep, SELECT, 0);
1682
1683         /* updates lengths etc */
1684         seq= ed->seqbasep->first;
1685         while(seq) {
1686                 calc_sequence(seq);
1687                 seq= seq->next;
1688         }
1689
1690         /* free parent metas */
1691         ms= ed->metastack.last;
1692         while(ms) {
1693                 ms->parseq->strip->len= 0;              /* force new alloc */
1694                 calc_sequence(ms->parseq);
1695                 ms= ms->prev;
1696         }
1697
1698         BIF_undo_push("Delete from Sequencer");
1699         allqueue(REDRAWSEQ, 0);
1700 }
1701
1702 static void recurs_dupli_seq(ListBase *old, ListBase *new)
1703 {
1704         Sequence *seq, *seqn;
1705         StripElem *se;
1706         int a;
1707
1708         seq= old->first;
1709
1710         while(seq) {
1711                 seq->newseq= 0;
1712                 if(seq->flag & SELECT) {
1713
1714                         if(seq->type==SEQ_META) {
1715                                 seqn= MEM_dupallocN(seq);
1716                                 seq->newseq= seqn;
1717                                 BLI_addtail(new, seqn);
1718
1719                                 seqn->strip= MEM_dupallocN(seq->strip);
1720
1721                                 if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1722
1723                                 seq->flag &= SEQ_DESEL;
1724                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1725
1726                                 seqn->seqbase.first= seqn->seqbase.last= 0;
1727                                 recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);
1728
1729                         }
1730                         else if(seq->type == SEQ_SCENE) {
1731                                 seqn= MEM_dupallocN(seq);
1732                                 seq->newseq= seqn;
1733                                 BLI_addtail(new, seqn);
1734
1735                                 seqn->strip= MEM_dupallocN(seq->strip);
1736
1737                                 if(seq->len>0) seqn->strip->stripdata = MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1738
1739                                 seq->flag &= SEQ_DESEL;
1740                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1741                         }
1742                         else if(seq->type == SEQ_MOVIE) {
1743                                 seqn= MEM_dupallocN(seq);
1744                                 seq->newseq= seqn;
1745                                 BLI_addtail(new, seqn);
1746
1747                                 seqn->strip= MEM_dupallocN(seq->strip);
1748                                 seqn->anim= 0;
1749
1750                                 if(seqn->len>0) {
1751                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1752                                         /* copy first elem */
1753                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1754                                         se= seqn->strip->stripdata;
1755                                         a= seq->len;
1756                                         while(a--) {
1757                                                 se->ok= 1;
1758                                                 se++;
1759                                         }
1760                                 }
1761
1762                                 seq->flag &= SEQ_DESEL;
1763                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1764                         }
1765                         else if(seq->type == SEQ_RAM_SOUND) {
1766                                 seqn= MEM_dupallocN(seq);
1767                                 seq->newseq= seqn;
1768                                 BLI_addtail(new, seqn);
1769
1770                                 seqn->strip= MEM_dupallocN(seq->strip);
1771                                 seqn->anim= 0;
1772                                 seqn->sound->id.us++;
1773                                 if(seqn->ipo) seqn->ipo->id.us++;
1774
1775                                 if(seqn->len>0) {
1776                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1777                                         /* copy first elem */
1778                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1779                                         se= seqn->strip->stripdata;
1780                                         a= seq->len;
1781                                         while(a--) {
1782                                                 se->ok= 1;
1783                                                 se++;
1784                                         }
1785                                 }
1786
1787                                 seq->flag &= SEQ_DESEL;
1788                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1789                         }
1790                         else if(seq->type == SEQ_HD_SOUND) {
1791                                 seqn= MEM_dupallocN(seq);
1792                                 seq->newseq= seqn;
1793                                 BLI_addtail(new, seqn);
1794
1795                                 seqn->strip= MEM_dupallocN(seq->strip);
1796                                 seqn->anim= 0;
1797                                 seqn->hdaudio
1798                                         = sound_copy_hdaudio(seq->hdaudio);
1799                                 if(seqn->ipo) seqn->ipo->id.us++;
1800
1801                                 if(seqn->len>0) {
1802                                         seqn->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1803                                         /* copy first elem */
1804                                         *seqn->strip->stripdata= *seq->strip->stripdata;
1805                                         se= seqn->strip->stripdata;
1806                                         a= seq->len;
1807                                         while(a--) {
1808                                                 se->ok= 1;
1809                                                 se++;
1810                                         }
1811                                 }
1812
1813                                 seq->flag &= SEQ_DESEL;
1814                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1815                         }
1816                         else if(seq->type < SEQ_EFFECT) {
1817                                 seqn= MEM_dupallocN(seq);
1818                                 seq->newseq= seqn;
1819                                 BLI_addtail(new, seqn);
1820
1821                                 seqn->strip->us++;
1822                                 seq->flag &= SEQ_DESEL;
1823
1824                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1825                         }
1826                         else {
1827                                 seqn= MEM_dupallocN(seq);
1828                                 seq->newseq= seqn;
1829                                 BLI_addtail(new, seqn);
1830
1831                                 if(seq->seq1 && seq->seq1->newseq) seqn->seq1= seq->seq1->newseq;
1832                                 if(seq->seq2 && seq->seq2->newseq) seqn->seq2= seq->seq2->newseq;
1833                                 if(seq->seq3 && seq->seq3->newseq) seqn->seq3= seq->seq3->newseq;
1834
1835                                 if(seqn->ipo) seqn->ipo->id.us++;
1836
1837                                 if (seq->type & SEQ_EFFECT) {
1838                                         struct SeqEffectHandle sh;
1839                                         sh = get_sequence_effect(seq);
1840                                         if(sh.copy)
1841                                                 sh.copy(seq, seqn);
1842                                 }
1843
1844                                 seqn->strip= MEM_dupallocN(seq->strip);
1845
1846                                 if(seq->len>0) seq->strip->stripdata= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
1847
1848                                 seq->flag &= SEQ_DESEL;
1849                                 
1850                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
1851                         }
1852
1853                 }
1854                 seq= seq->next;
1855         }
1856 }
1857
1858 void add_duplicate_seq(void)
1859 {
1860         Editing *ed;
1861         ListBase new;
1862
1863         ed= G.scene->ed;
1864         if(ed==0) return;
1865
1866         new.first= new.last= 0;
1867
1868         recurs_dupli_seq(ed->seqbasep, &new);
1869         addlisttolist(ed->seqbasep, &new);
1870
1871         BIF_undo_push("Add duplicate Sequencer");
1872         transform_seq('g', 0);
1873 }
1874
1875 int insert_gap(int gap, int cfra)
1876 {
1877         Sequence *seq;
1878         Editing *ed;
1879         int done=0;
1880
1881         /* all strips >= cfra are shifted */
1882         ed= G.scene->ed;
1883         if(ed==0) return 0;
1884
1885         WHILE_SEQ(ed->seqbasep) {
1886                 if(seq->startdisp >= cfra) {
1887                         seq->start+= gap;
1888                         calc_sequence(seq);
1889                         done= 1;
1890                 }
1891         }
1892         END_SEQ
1893
1894         return done;
1895 }
1896
1897 void touch_seq_files(void)
1898 {
1899         Sequence *seq;
1900         Editing *ed;
1901         char str[256];
1902
1903         /* touch all strips with movies */
1904         ed= G.scene->ed;
1905         if(ed==0) return;
1906
1907         if(okee("Touch and print selected movies")==0) return;
1908
1909         waitcursor(1);
1910
1911         WHILE_SEQ(ed->seqbasep) {
1912                 if(seq->flag & SELECT) {
1913                         if(seq->type==SEQ_MOVIE) {
1914                                 if(seq->strip && seq->strip->stripdata) {
1915                                         BLI_make_file_string(G.sce, str, seq->strip->dir, seq->strip->stripdata->name);
1916                                         BLI_touch(seq->name);
1917                                 }
1918                         }
1919
1920                 }
1921         }
1922         END_SEQ
1923
1924         waitcursor(0);
1925 }
1926
1927 void set_filter_seq(void)
1928 {
1929         Sequence *seq;
1930         Editing *ed;
1931
1932         ed= G.scene->ed;
1933         if(ed==0) return;
1934
1935         if(okee("Set FilterY")==0) return;
1936
1937         WHILE_SEQ(ed->seqbasep) {
1938                 if(seq->flag & SELECT) {
1939                         if(seq->type==SEQ_MOVIE) {
1940                                 seq->flag |= SEQ_FILTERY;
1941                         }
1942
1943                 }
1944         }
1945         END_SEQ
1946
1947 }
1948
1949
1950
1951 void no_gaps(void)
1952 {
1953         Editing *ed;
1954         int cfra, first= 0, done;
1955
1956         ed= G.scene->ed;
1957         if(ed==0) return;
1958
1959         for(cfra= CFRA; cfra<=EFRA; cfra++) {
1960                 if(first==0) {
1961                         if( evaluate_seq_frame(cfra) ) first= 1;
1962                 }
1963                 else {
1964                         done= 1;
1965                         while( evaluate_seq_frame(cfra) == 0) {
1966                                 done= insert_gap(-1, cfra);
1967                                 if(done==0) break;
1968                         }
1969                         if(done==0) break;
1970                 }
1971         }
1972
1973         BIF_undo_push("No gaps Sequencer");
1974         allqueue(REDRAWSEQ, 0);
1975 }
1976
1977
1978 /* ****************** META ************************* */
1979
1980 void make_meta(void)
1981 {
1982         Sequence *seq, *seqm, *next;
1983         Editing *ed;
1984         int tot;
1985
1986         ed= G.scene->ed;
1987         if(ed==0) return;
1988
1989         /* is there more than 1 select */
1990         tot= 0;
1991         seq= ed->seqbasep->first;
1992         while(seq) {
1993                 if(seq->flag & SELECT) {
1994                         tot++;
1995                         if (seq->type == SEQ_RAM_SOUND) { 
1996                                 error("Can't make Meta Strip from audio"); 
1997                                 return; 
1998                         }
1999                 }
2000                 seq= seq->next;
2001         }
2002         if(tot < 2) return;
2003
2004         if(okee("Make Meta Strip")==0) return;
2005
2006         /* test relationships */
2007         seq= ed->seqbasep->first;
2008         while(seq) {
2009                 if(seq->flag & SELECT) {
2010                         if(seq->type & SEQ_EFFECT) {
2011                                 if((seq->seq1->flag & SELECT)==0) tot= 0;
2012                                 if((seq->seq2->flag & SELECT)==0) tot= 0;
2013                                 if((seq->seq3->flag & SELECT)==0) tot= 0;
2014                         }
2015                 }
2016                 else if(seq->type & SEQ_EFFECT) {
2017                         if(seq->seq1->flag & SELECT) tot= 0;
2018                         if(seq->seq2->flag & SELECT) tot= 0;
2019                         if(seq->seq3->flag & SELECT) tot= 0;
2020                 }
2021                 if(tot==0) break;
2022                 seq= seq->next;
2023         }
2024         if(tot==0) {
2025                 error("Please select all related strips");
2026                 return;
2027         }
2028
2029         /* remove all selected from main list, and put in meta */
2030
2031         seqm= alloc_sequence(1, 1);
2032         seqm->type= SEQ_META;
2033         seqm->flag= SELECT;
2034
2035         seq= ed->seqbasep->first;
2036         while(seq) {
2037                 next= seq->next;
2038                 if(seq!=seqm && (seq->flag & SELECT)) {
2039                         BLI_remlink(ed->seqbasep, seq);
2040                         BLI_addtail(&seqm->seqbase, seq);
2041                 }
2042                 seq= next;
2043         }
2044         calc_sequence(seqm);
2045
2046         seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
2047         seqm->strip->len= seqm->len;
2048         seqm->strip->us= 1;
2049         if(seqm->len) seqm->strip->stripdata= MEM_callocN(seqm->len*sizeof(StripElem), "metastripdata");
2050
2051         set_meta_stripdata(seqm);
2052
2053         BIF_undo_push("Make Meta Sequencer");
2054         allqueue(REDRAWSEQ, 0);
2055 }
2056
2057 static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
2058 {
2059         if (seq == seqm) return 1;
2060         else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
2061         else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
2062         else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
2063         else return 0;
2064 }
2065
2066 void un_meta(void)
2067 {
2068         Editing *ed;
2069         Sequence *seq, *last_seq = get_last_seq();
2070
2071         ed= G.scene->ed;
2072         if(ed==0) return;
2073
2074         if(last_seq==0 || last_seq->type!=SEQ_META) return;
2075
2076         if(okee("Un Meta")==0) return;
2077
2078         addlisttolist(ed->seqbasep, &last_seq->seqbase);
2079
2080         last_seq->seqbase.first= 0;
2081         last_seq->seqbase.last= 0;
2082
2083         BLI_remlink(ed->seqbasep, last_seq);
2084         free_sequence(last_seq);
2085
2086         /* emtpy meta strip, delete all effects depending on it */
2087         for(seq=ed->seqbasep->first; seq; seq=seq->next)
2088                 if((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq))
2089                         seq->flag |= SEQ_FLAG_DELETE;
2090
2091         recurs_del_seq_flag(ed->seqbasep, SEQ_FLAG_DELETE, 0);
2092
2093         /* test for effects and overlap */
2094         WHILE_SEQ(ed->seqbasep) {
2095                 if(seq->flag & SELECT) {
2096                         seq->flag &= ~SEQ_OVERLAP;
2097                         if( test_overlap_seq(seq) ) {
2098                                 shuffle_seq(seq);
2099                         }
2100                 }
2101         }
2102         END_SEQ;
2103
2104         sort_seq();
2105
2106         BIF_undo_push("Un-make Meta Sequencer");
2107         allqueue(REDRAWSEQ, 0);
2108
2109 }
2110
2111 void exit_meta(void)
2112 {
2113         Sequence *seq;
2114         MetaStack *ms;
2115         Editing *ed;
2116
2117         ed= G.scene->ed;
2118         if(ed==0) return;
2119
2120         if(ed->metastack.first==0) return;
2121
2122         ms= ed->metastack.last;
2123         BLI_remlink(&ed->metastack, ms);
2124
2125         ed->seqbasep= ms->oldbasep;
2126
2127         /* recalc entire meta */
2128         set_meta_stripdata(ms->parseq);
2129
2130         /* recalc all: the meta can have effects connected to it */
2131         seq= ed->seqbasep->first;
2132         while(seq) {
2133                 calc_sequence(seq);
2134                 seq= seq->next;
2135         }
2136
2137         set_last_seq(ms->parseq);
2138
2139         ms->parseq->flag= SELECT;
2140         recurs_sel_seq(ms->parseq);
2141
2142         MEM_freeN(ms);
2143         allqueue(REDRAWSEQ, 0);
2144
2145         BIF_undo_push("Exit meta strip Sequence");
2146 }
2147
2148
2149 void enter_meta(void)
2150 {
2151         MetaStack *ms;
2152         Editing *ed;
2153         Sequence *last_seq= get_last_seq();
2154
2155         ed= G.scene->ed;
2156         if(ed==0) return;
2157
2158         if(last_seq==0 || last_seq->type!=SEQ_META || last_seq->flag==0) {
2159                 exit_meta();
2160                 return;
2161         }
2162
2163         ms= MEM_mallocN(sizeof(MetaStack), "metastack");
2164         BLI_addtail(&ed->metastack, ms);
2165         ms->parseq= last_seq;
2166         ms->oldbasep= ed->seqbasep;
2167
2168         ed->seqbasep= &last_seq->seqbase;
2169
2170         set_last_seq(NULL);
2171         allqueue(REDRAWSEQ, 0);
2172         BIF_undo_push("Enter meta strip Sequence");
2173 }
2174
2175
2176 /* ****************** END META ************************* */
2177
2178
2179 typedef struct TransSeq {
2180         int start, machine;
2181         int startstill, endstill;
2182         int startdisp, enddisp;
2183         int startofs, endofs;
2184         int len;
2185 } TransSeq;
2186
2187 void transform_seq(int mode, int context)
2188 {
2189         Sequence *seq;
2190         Editing *ed;
2191         float dx, dy, dvec[2], div;
2192         TransSeq *transmain, *ts;
2193         int tot=0, ix, iy, firsttime=1, afbreek=0, midtog= 0, proj= 0;
2194         unsigned short event = 0;
2195         short mval[2], val, xo, yo, xn, yn;
2196         char str[32];
2197
2198         if(mode!='g') return;   /* from gesture */
2199
2200         /* which seqs are involved */
2201         ed= G.scene->ed;
2202         if(ed==0) return;
2203
2204         WHILE_SEQ(ed->seqbasep) {
2205                 if(seq->flag & SELECT) tot++;
2206         }
2207         END_SEQ
2208
2209         if(tot==0) return;
2210
2211         G.moving= 1;
2212
2213         ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
2214
2215         WHILE_SEQ(ed->seqbasep) {
2216
2217                 if(seq->flag & SELECT) {
2218
2219                         ts->start= seq->start;
2220                         ts->machine= seq->machine;
2221                         ts->startstill= seq->startstill;
2222                         ts->endstill= seq->endstill;
2223                         ts->startofs= seq->startofs;
2224                         ts->endofs= seq->endofs;
2225
2226                         ts++;
2227                 }
2228         }
2229         END_SEQ
2230
2231         getmouseco_areawin(mval);
2232         xo=xn= mval[0];
2233         yo=yn= mval[1];
2234         dvec[0]= dvec[1]= 0.0;
2235
2236         while(afbreek==0) {
2237                 getmouseco_areawin(mval);
2238                 if(mval[0]!=xo || mval[1]!=yo || firsttime) {
2239                         firsttime= 0;
2240
2241                         if(mode=='g') {
2242
2243                                 dx= mval[0]- xo;
2244                                 dy= mval[1]- yo;
2245
2246                                 div= G.v2d->mask.xmax-G.v2d->mask.xmin;
2247                                 dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
2248
2249                                 div= G.v2d->mask.ymax-G.v2d->mask.ymin;
2250                                 dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
2251
2252                                 if(G.qual & LR_SHIFTKEY) {
2253                                         if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
2254                                 }
2255
2256                                 dvec[0]+= dx;
2257                                 dvec[1]+= dy;
2258
2259                                 if(midtog) dvec[proj]= 0.0;
2260                                 ix= floor(dvec[0]+0.5);
2261                                 iy= floor(dvec[1]+0.5);
2262
2263
2264                                 ts= transmain;
2265
2266                                 WHILE_SEQ(ed->seqbasep) {
2267                                         if(seq->flag & SELECT) {
2268                                                 if(seq->flag & SEQ_LEFTSEL) {
2269                                                         if(ts->startstill) {
2270                                                                 seq->startstill= ts->startstill-ix;
2271                                                                 if(seq->startstill<0) seq->startstill= 0;
2272                                                         }
2273                                                         else if(ts->startofs) {
2274                                                                 seq->startofs= ts->startofs+ix;
2275                                                                 if(seq->startofs<0) seq->startofs= 0;
2276                                                         }
2277                                                         else {
2278                                                                 if(ix>0) {
2279                                                                         seq->startofs= ix;
2280                                                                         seq->startstill= 0;
2281                                                                 }
2282                                                                 else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
2283                                                                         seq->startstill= -ix;
2284                                                                         seq->startofs= 0;
2285                                                                 }
2286                                                         }
2287                                                         if(seq->len <= seq->startofs+seq->endofs) {
2288                                                                 seq->startofs= seq->len-seq->endofs-1;
2289                                                         }
2290                                                 }
2291                                                 if(seq->flag & SEQ_RIGHTSEL) {
2292                                                         if(ts->endstill) {
2293                                                                 seq->endstill= ts->endstill+ix;
2294                                                                 if(seq->endstill<0) seq->endstill= 0;
2295                                                         }
2296                                                         else if(ts->endofs) {
2297                                                                 seq->endofs= ts->endofs-ix;
2298                                                                 if(seq->endofs<0) seq->endofs= 0;
2299                                                         }
2300                                                         else {
2301                                                                 if(ix<0) {
2302                                                                         seq->endofs= -ix;
2303                                                                         seq->endstill= 0;
2304                                                                 }
2305                                                                 else if (seq->type != SEQ_RAM_SOUND && seq->type != SEQ_HD_SOUND) {
2306                                                                         seq->endstill= ix;
2307                                                                         seq->endofs= 0;
2308                                                                 }
2309                                                         }
2310                                                         if(seq->len <= seq->startofs+seq->endofs) {
2311                                                                 seq->endofs= seq->len-seq->startofs-1;
2312                                                         }
2313                                                 }
2314                                                 if( (seq->flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
2315                                                         if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
2316
2317                                                         if(seq->depth==0) seq->machine= ts->machine+ iy;
2318
2319                                                         if(seq->machine<1) seq->machine= 1;
2320                                                         else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
2321                                                 }
2322
2323                                                 calc_sequence(seq);
2324
2325                                                 ts++;
2326                                         }
2327                                 }
2328                                 END_SEQ
2329
2330                                 sprintf(str, "X: %d   Y: %d  ", ix, iy);
2331                                 headerprint(str);
2332                         }
2333
2334                         xo= mval[0];
2335                         yo= mval[1];
2336
2337                         /* test for effect and overlap */
2338
2339                         WHILE_SEQ(ed->seqbasep) {
2340                                 if(seq->flag & SELECT) {
2341                                         seq->flag &= ~SEQ_OVERLAP;
2342                                         if( test_overlap_seq(seq) ) {
2343                                                 seq->flag |= SEQ_OVERLAP;
2344                                         }
2345                                 }
2346                                 else if(seq->type & SEQ_EFFECT) {
2347                                         if(seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
2348                                         else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
2349                                         else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
2350                                 }
2351                         }
2352                         END_SEQ;
2353
2354                         force_draw(0);
2355                 }
2356                 else BIF_wait_for_statechange();
2357
2358                 while(qtest()) {
2359                         event= extern_qread(&val);
2360                         if(val) {
2361                                 switch(event) {
2362                                 case ESCKEY:
2363                                 case LEFTMOUSE:
2364                                 case RIGHTMOUSE:
2365                                 case SPACEKEY:
2366                                 case RETKEY:
2367                                         afbreek= 1;
2368                                         break;
2369                                 case MIDDLEMOUSE:
2370                                         midtog= ~midtog;
2371                                         if(midtog) {
2372                                                 if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1;
2373                                                 else proj= 0;
2374                                                 firsttime= 1;
2375                                         }
2376                                         break;
2377                                 default:
2378                                         arrows_move_cursor(event);
2379                                 }
2380                         }
2381                         if(afbreek) break;
2382                 }
2383         }
2384
2385         if((event==ESCKEY) || (event==RIGHTMOUSE)) {
2386
2387                 ts= transmain;
2388                 WHILE_SEQ(ed->seqbasep) {
2389                         if(seq->flag & SELECT) {
2390                                 seq->start= ts->start;
2391                                 seq->machine= ts->machine;
2392                                 seq->startstill= ts->startstill;
2393                                 seq->endstill= ts->endstill;
2394                                 seq->startofs= ts->startofs;
2395                                 seq->endofs= ts->endofs;
2396
2397                                 calc_sequence(seq);
2398                                 seq->flag &= ~SEQ_OVERLAP;
2399
2400                                 ts++;
2401                         } else if(seq->type & SEQ_EFFECT) {
2402                                 if(seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(seq);
2403                                 else if(seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(seq);
2404                                 else if(seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(seq);
2405                         }
2406
2407                 }
2408                 END_SEQ
2409         }
2410         else {
2411
2412                 /* images, effects and overlap */
2413                 WHILE_SEQ(ed->seqbasep) {
2414                         if(seq->type == SEQ_META) {
2415                                 calc_sequence(seq);
2416                                 seq->flag &= ~SEQ_OVERLAP;
2417                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
2418                         }
2419                         else if(seq->flag & SELECT) {
2420                                 calc_sequence(seq);
2421                                 seq->flag &= ~SEQ_OVERLAP;
2422                                 if( test_overlap_seq(seq) ) shuffle_seq(seq);
2423                         }
2424                         else if(seq->type & SEQ_EFFECT) calc_sequence(seq);
2425                 }
2426                 END_SEQ
2427
2428                 /* as last: */
2429                 sort_seq();
2430         }
2431
2432         G.moving= 0;
2433         MEM_freeN(transmain);
2434
2435         BIF_undo_push("Transform Sequencer");
2436         allqueue(REDRAWSEQ, 0);
2437 }
2438
2439 void seq_cut(int cutframe)
2440 {
2441         Editing *ed;
2442         Sequence *seq;
2443         TransSeq *ts, *transmain;
2444         int tot=0;
2445         ListBase newlist;
2446         
2447         ed= G.scene->ed;
2448         if(ed==0) return;
2449         
2450         /* test for validity */
2451         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2452                 if(seq->flag & SELECT) {
2453                         if(cutframe > seq->startdisp && cutframe < seq->enddisp)
2454                                 if(seq->type==SEQ_META) break;
2455                 }
2456         }
2457         if(seq) {
2458                 error("Cannot cut Meta strips");
2459                 return;
2460         }
2461         
2462         /* we build an array of TransSeq, to denote which strips take part in cutting */
2463         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2464                 if(seq->flag & SELECT) {
2465                         if(cutframe > seq->startdisp && cutframe < seq->enddisp)
2466                                 tot++;
2467                         else
2468                                 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)
2469                 }
2470         }
2471         
2472         if(tot==0) {
2473                 error("No strips to cut");
2474                 return;
2475         }
2476         
2477         ts=transmain= MEM_callocN(tot*sizeof(TransSeq), "transseq");
2478         
2479         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2480                 if(seq->flag & SELECT) {
2481                         
2482                         ts->start= seq->start;
2483                         ts->machine= seq->machine;
2484                         ts->startstill= seq->startstill;
2485                         ts->endstill= seq->endstill;
2486                         ts->startdisp= seq->startdisp;
2487                         ts->enddisp= seq->enddisp;
2488                         ts->startofs= seq->startofs;
2489                         ts->endofs= seq->endofs;
2490                         ts->len= seq->len;
2491                         
2492                         ts++;
2493                 }
2494         }
2495                 
2496         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2497                 if(seq->flag & SELECT) {
2498                         
2499                         /* strips with extended stillframes before */
2500                         if ((seq->startstill) && (cutframe <seq->start)) {
2501                                 seq->start= cutframe -1;
2502                                 seq->startstill= cutframe -seq->startdisp -1;
2503                                 seq->len= 1;
2504                                 seq->endstill= 0;
2505                         }
2506                         
2507                         /* normal strip */
2508                         else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
2509                                 seq->endofs = (seq->start+seq->len) - cutframe;
2510                         }
2511                         
2512                         /* strips with extended stillframes after */
2513                         else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
2514                                 seq->endstill -= seq->enddisp - cutframe;
2515                         }
2516                         
2517                         calc_sequence(seq);
2518                 }
2519         }
2520                 
2521         newlist.first= newlist.last= NULL;
2522         
2523         /* now we duplicate the cut strip and move it into place afterwards */
2524         recurs_dupli_seq(ed->seqbasep, &newlist);
2525         addlisttolist(ed->seqbasep, &newlist);
2526         
2527         ts= transmain;
2528         
2529         /* go through all the strips and correct them based on their stored values */
2530         for(seq= ed->seqbasep->first; seq; seq= seq->next) {
2531                 if(seq->flag & SELECT) {
2532
2533                         /* strips with extended stillframes before */
2534                         if ((seq->startstill) && (cutframe == seq->start + 1)) {
2535                                 seq->start = ts->start;
2536                                 seq->startstill= ts->start- cutframe;
2537                                 seq->len = ts->len;
2538                                 seq->endstill = ts->endstill;
2539                         }
2540                         
2541                         /* normal strip */
2542                         else if ((cutframe>=seq->start)&&(cutframe<=(seq->start+seq->len))) {
2543                                 seq->startstill = 0;
2544                                 seq->startofs = cutframe - ts->start;
2545                                 seq->endofs = ts->endofs;
2546                                 seq->endstill = ts->endstill;
2547                         }                               
2548                         
2549                         /* strips with extended stillframes after */
2550                         else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
2551                                 seq->start = cutframe - ts->len +1;
2552                                 seq->startofs = ts->len-1;
2553                                 seq->endstill = ts->enddisp - cutframe -1;
2554                                 seq->startstill = 0;
2555                         }
2556                         calc_sequence(seq);
2557                         
2558                         ts++;
2559                 }
2560         }
2561                 
2562         /* as last: */  
2563         sort_seq();
2564         MEM_freeN(transmain);
2565         
2566         allqueue(REDRAWSEQ, 0);
2567 }
2568
2569 void seq_snap_menu(void)
2570 {
2571         short event;
2572
2573         event= pupmenu("Snap %t|To Current Frame%x1");
2574         if(event < 1) return;
2575
2576         seq_snap(event);
2577 }
2578
2579 void seq_snap(short event)
2580 {
2581         Editing *ed;
2582         Sequence *seq;
2583
2584         ed= G.scene->ed;
2585         if(ed==0) return;
2586
2587         /* problem: contents of meta's are all shifted to the same position... */
2588
2589         /* also check metas */
2590         WHILE_SEQ(ed->seqbasep) {
2591                 if(seq->flag & SELECT) {
2592                         if(sequence_is_free_transformable(seq)) seq->start= CFRA-seq->startofs+seq->startstill;
2593                         calc_sequence(seq);
2594                 }
2595         }
2596         END_SEQ
2597
2598
2599         /* test for effects and overlap */
2600         WHILE_SEQ(ed->seqbasep) {
2601                 if(seq->flag & SELECT) {
2602                         seq->flag &= ~SEQ_OVERLAP;
2603                         if( test_overlap_seq(seq) ) {
2604                                 shuffle_seq(seq);
2605                         }
2606                 }
2607                 else if(seq->type & SEQ_EFFECT) {
2608                         if(seq->seq1->flag & SELECT) calc_sequence(seq);
2609                         else if(seq->seq2->flag & SELECT) calc_sequence(seq);
2610                         else if(seq->seq3->flag & SELECT) calc_sequence(seq);
2611                 }
2612         }
2613         END_SEQ;
2614
2615         /* as last: */
2616         sort_seq();
2617
2618         BIF_undo_push("Snap menu Sequencer");
2619         allqueue(REDRAWSEQ, 0);
2620 }
2621
2622 void borderselect_seq(void)
2623 {
2624         Sequence *seq;
2625         Editing *ed;
2626         rcti rect;
2627         rctf rectf, rq;
2628         int val;
2629         short mval[2];
2630
2631         ed= G.scene->ed;
2632         if(ed==0) return;
2633
2634         val= get_border(&rect, 3);
2635
2636         if(val) {
2637                 mval[0]= rect.xmin;
2638                 mval[1]= rect.ymin;
2639                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
2640                 mval[0]= rect.xmax;
2641                 mval[1]= rect.ymax;
2642                 areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
2643
2644                 seq= ed->seqbasep->first;
2645                 while(seq) {
2646
2647                         if(seq->startstill) rq.xmin= seq->start;
2648                         else rq.xmin= seq->startdisp;
2649                         rq.ymin= seq->machine+0.2;
2650                         if(seq->endstill) rq.xmax= seq->start+seq->len;
2651                         else rq.xmax= seq->enddisp;
2652                         rq.ymax= seq->machine+0.8;
2653
2654                         if(BLI_isect_rctf(&rq, &rectf, 0)) {
2655                                 if(val==LEFTMOUSE) {
2656                                         seq->flag |= SELECT;
2657                                 }
2658                                 else {
2659                                         seq->flag &= ~SELECT;
2660                                 }
2661                                 recurs_sel_seq(seq);
2662                         }
2663
2664                         seq= seq->next;
2665                 }
2666
2667                 BIF_undo_push("Border select Sequencer");
2668                 addqueue(curarea->win, REDRAW, 1);
2669         }
2670 }