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