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