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