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