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