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