Merged 15170:15635 from trunk (no conflicts or even merges)
[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         int nothingSelected = TRUE;
2139
2140         ed= G.scene->ed;
2141         if(ed==0) return;
2142
2143         seq=get_last_seq();
2144         if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
2145                 nothingSelected = FALSE;
2146         } else {
2147                 for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2148                         if (seq->flag & SELECT) {
2149                                 nothingSelected = FALSE;
2150                                 break;
2151                         }
2152                 }
2153         }
2154         
2155         if(nothingSelected || okee("Erase selected")==0) return;
2156
2157         /* free imbufs of all dependent strips */
2158         for(seq=ed->seqbasep->first; seq; seq=seq->next)
2159                 if(seq->flag & SELECT)
2160                         update_changed_seq_and_deps(seq, 1, 0);
2161
2162         /* for effects, try to find a replacement input */
2163         for(seq=ed->seqbasep->first; seq; seq=seq->next)
2164                 if((seq->type & SEQ_EFFECT) && !(seq->flag & SELECT))
2165                         del_seq_find_replace_recurs(seq);
2166
2167         /* delete all selected strips */
2168         recurs_del_seq_flag(ed->seqbasep, SELECT, 0);
2169
2170         /* updates lengths etc */
2171         seq= ed->seqbasep->first;
2172         while(seq) {
2173                 calc_sequence(seq);
2174                 seq= seq->next;
2175         }
2176
2177         /* free parent metas */
2178         ms= ed->metastack.last;
2179         while(ms) {
2180                 ms->parseq->strip->len= 0;              /* force new alloc */
2181                 calc_sequence(ms->parseq);
2182                 ms= ms->prev;
2183         }
2184
2185         BIF_undo_push("Delete Strip(s), Sequencer");
2186         allqueue(REDRAWSEQ, 0);
2187 }
2188
2189 static Sequence *dupli_seq(Sequence *seq) 
2190 {
2191         Sequence *seqn = MEM_dupallocN(seq);
2192
2193         seq->tmp = seqn;
2194                 
2195         seqn->strip= MEM_dupallocN(seq->strip);
2196
2197         if(seqn->ipo) seqn->ipo->id.us++;
2198
2199         seqn->strip->tstripdata = 0;
2200         seqn->strip->tstripdata_startstill = 0;
2201         seqn->strip->tstripdata_endstill = 0;
2202         seqn->strip->ibuf_startstill = 0;
2203         seqn->strip->ibuf_endstill = 0;
2204
2205         if (seq->strip->crop) {
2206                 seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
2207         }
2208
2209         if (seq->strip->transform) {
2210                 seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
2211         }
2212
2213         if (seq->strip->proxy) {
2214                 seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
2215         }
2216
2217         if (seq->strip->color_balance) {
2218                 seqn->strip->color_balance 
2219                         = MEM_dupallocN(seq->strip->color_balance);
2220         }
2221         
2222         if(seq->type==SEQ_META) {
2223                 seqn->strip->stripdata = 0;
2224
2225                 seqn->seqbase.first= seqn->seqbase.last= 0;
2226                 /* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
2227                 /* - recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);*/
2228         } else if(seq->type == SEQ_SCENE) {
2229                 seqn->strip->stripdata = 0;
2230         } else if(seq->type == SEQ_MOVIE) {
2231                 seqn->strip->stripdata = 
2232                                 MEM_dupallocN(seq->strip->stripdata);
2233                 seqn->anim= 0;
2234         } else if(seq->type == SEQ_RAM_SOUND) {
2235                 seqn->strip->stripdata = 
2236                                 MEM_dupallocN(seq->strip->stripdata);
2237                 seqn->sound->id.us++;
2238         } else if(seq->type == SEQ_HD_SOUND) {
2239                 seqn->strip->stripdata = 
2240                                 MEM_dupallocN(seq->strip->stripdata);
2241                 seqn->hdaudio = 0;
2242         } else if(seq->type == SEQ_IMAGE) {
2243                 seqn->strip->stripdata = 
2244                                 MEM_dupallocN(seq->strip->stripdata);
2245         } else if(seq->type >= SEQ_EFFECT) {
2246                 if(seq->seq1 && seq->seq1->tmp) seqn->seq1= seq->seq1->tmp;
2247                 if(seq->seq2 && seq->seq2->tmp) seqn->seq2= seq->seq2->tmp;
2248                 if(seq->seq3 && seq->seq3->tmp) seqn->seq3= seq->seq3->tmp;
2249
2250                 if (seq->type & SEQ_EFFECT) {
2251                         struct SeqEffectHandle sh;
2252                         sh = get_sequence_effect(seq);
2253                         if(sh.copy)
2254                                 sh.copy(seq, seqn);
2255                 }
2256
2257                 seqn->strip->stripdata = 0;
2258                 
2259         } else {
2260                 fprintf(stderr, "Aiiiiekkk! sequence type not "
2261                                 "handled in duplicate!\nExpect a crash"
2262                                                 " now...\n");
2263         }
2264         
2265         return seqn;
2266 }
2267
2268 static Sequence * deep_dupli_seq(Sequence * seq)
2269 {
2270         Sequence * seqn = dupli_seq(seq);
2271         if (seq->type == SEQ_META) {
2272                 Sequence * s;
2273                 for(s= seq->seqbase.first; s; s = s->next) {
2274                         Sequence * n = deep_dupli_seq(s);
2275                         if (n) { 
2276                                 BLI_addtail(&seqn->seqbase, n);
2277                         }
2278                 }
2279         }
2280         return seqn;
2281 }
2282
2283
2284 static void recurs_dupli_seq(ListBase *old, ListBase *new)
2285 {
2286         Sequence *seq;
2287         Sequence *seqn = 0;
2288         Sequence *last_seq = get_last_seq();
2289
2290         for(seq= old->first; seq; seq= seq->next) {
2291                 seq->tmp= NULL;
2292                 if(seq->flag & SELECT) {
2293                         seqn = dupli_seq(seq);
2294                         if (seqn) { /*should never fail */
2295                                 seq->flag &= SEQ_DESEL;
2296                                 seqn->flag &= ~(SEQ_LEFTSEL+SEQ_RIGHTSEL+SEQ_LOCK);
2297
2298                                 BLI_addtail(new, seqn);
2299                                 if(seq->type==SEQ_META)
2300                                         recurs_dupli_seq(&seq->seqbase,&seqn->seqbase);
2301                                 
2302                                 if (seq == last_seq) {
2303                                         set_last_seq(seqn);
2304                                 }
2305                         }
2306                 }
2307         }
2308 }
2309
2310 static Sequence * cut_seq_hard(Sequence * seq, int cutframe)
2311 {
2312         TransSeq ts;
2313         Sequence *seqn = 0;
2314         int skip_dup = FALSE;
2315
2316         /* backup values */
2317         ts.start= seq->start;
2318         ts.machine= seq->machine;
2319         ts.startstill= seq->startstill;
2320         ts.endstill= seq->endstill;
2321         ts.startdisp= seq->startdisp;
2322         ts.enddisp= seq->enddisp;
2323         ts.startofs= seq->anim_startofs;
2324         ts.endofs= seq->anim_endofs;
2325         ts.len= seq->len;
2326         
2327         /* First Strip! */
2328         /* strips with extended stillfames before */
2329         
2330         if ((seq->startstill) && (cutframe <seq->start)) {
2331                 /* don't do funny things with METAs ... */
2332                 if (seq->type == SEQ_META) {
2333                         skip_dup = TRUE;
2334                         seq->startstill = seq->start - cutframe;
2335                 } else {
2336                         seq->start= cutframe -1;
2337                         seq->startstill= cutframe -seq->startdisp -1;
2338                         seq->anim_endofs += seq->len - 1;
2339                         seq->endstill= 0;
2340                 }
2341         }
2342         /* normal strip */
2343         else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
2344                 seq->endofs = 0;
2345                 seq->endstill = 0;
2346                 seq->anim_endofs += (seq->start+seq->len) - cutframe;
2347         }
2348         /* strips with extended stillframes after */
2349         else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
2350                 seq->endstill -= seq->enddisp - cutframe;
2351                 /* don't do funny things with METAs ... */
2352                 if (seq->type == SEQ_META) {
2353                         skip_dup = TRUE;
2354                 }
2355         }
2356         
2357         reload_sequence_new_file(seq);
2358         calc_sequence(seq);
2359         
2360         if (!skip_dup) {
2361                 /* Duplicate AFTER the first change */
2362                 seqn = deep_dupli_seq(seq);
2363         }
2364         
2365         if (seqn) { 
2366                 seqn->flag |= SELECT;
2367                         
2368                 /* Second Strip! */
2369                 /* strips with extended stillframes before */
2370                 if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
2371                         seqn->start = ts.start;
2372                         seqn->startstill= ts.start- cutframe;
2373                         seqn->anim_endofs = ts.endofs;
2374                         seqn->endstill = ts.endstill;
2375                 }
2376                 
2377                 /* normal strip */
2378                 else if ((cutframe>=seqn->start)&&(cutframe<=(seqn->start+seqn->len))) {
2379                         seqn->start = cutframe;
2380                         seqn->startstill = 0;
2381                         seqn->startofs = 0;
2382                         seqn->anim_startofs += cutframe - ts.start;
2383                         seqn->anim_endofs = ts.endofs;
2384                         seqn->endstill = ts.endstill;
2385                 }                               
2386                 
2387                 /* strips with extended stillframes after */
2388                 else if (((seqn->start+seqn->len) < cutframe) && (seqn->endstill)) {
2389                         seqn->start = cutframe;
2390                         seqn->startofs = 0;
2391                         seqn->anim_startofs += ts.len-1;
2392                         seqn->endstill = ts.enddisp - cutframe -1;
2393                         seqn->startstill = 0;
2394                 }
2395                 
2396                 reload_sequence_new_file(seqn);
2397                 calc_sequence(seqn);
2398         }
2399         return seqn;
2400 }
2401
2402 static Sequence * cut_seq_soft(Sequence * seq, int cutframe)
2403 {
2404         TransSeq ts;
2405         Sequence *seqn = 0;
2406         int skip_dup = FALSE;
2407
2408         /* backup values */
2409         ts.start= seq->start;
2410         ts.machine= seq->machine;
2411         ts.startstill= seq->startstill;
2412         ts.endstill= seq->endstill;
2413         ts.startdisp= seq->startdisp;
2414         ts.enddisp= seq->enddisp;
2415         ts.startofs= seq->startofs;
2416         ts.endofs= seq->endofs;
2417         ts.len= seq->len;
2418         
2419         /* First Strip! */
2420         /* strips with extended stillfames before */
2421         
2422         if ((seq->startstill) && (cutframe <seq->start)) {
2423                 /* don't do funny things with METAs ... */
2424                 if (seq->type == SEQ_META) {
2425                         skip_dup = TRUE;
2426                         seq->startstill = seq->start - cutframe;
2427                 } else {
2428                         seq->start= cutframe -1;
2429                         seq->startstill= cutframe -seq->startdisp -1;
2430                         seq->endofs = seq->len - 1;
2431                         seq->endstill= 0;
2432                 }
2433         }
2434         /* normal strip */
2435         else if ((cutframe >=seq->start)&&(cutframe <=(seq->start+seq->len))) {
2436                 seq->endofs = (seq->start+seq->len) - cutframe;
2437         }
2438         /* strips with extended stillframes after */
2439         else if (((seq->start+seq->len) < cutframe) && (seq->endstill)) {
2440                 seq->endstill -= seq->enddisp - cutframe;
2441                 /* don't do funny things with METAs ... */
2442                 if (seq->type == SEQ_META) {
2443                         skip_dup = TRUE;
2444                 }
2445         }
2446         
2447         calc_sequence(seq);
2448         
2449         if (!skip_dup) {
2450                 /* Duplicate AFTER the first change */
2451                 seqn = deep_dupli_seq(seq);
2452         }
2453         
2454         if (seqn) { 
2455                 seqn->flag |= SELECT;
2456                         
2457                 /* Second Strip! */
2458                 /* strips with extended stillframes before */
2459                 if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
2460                         seqn->start = ts.start;
2461                         seqn->startstill= ts.start- cutframe;
2462                         seqn->endofs = ts.endofs;
2463                         seqn->endstill = ts.endstill;
2464                 }
2465                 
2466                 /* normal strip */
2467                 else if ((cutframe>=seqn->start)&&(cutframe<=(seqn->start+seqn->len))) {
2468                         seqn->startstill = 0;
2469                         seqn->startofs = cutframe - ts.start;
2470                         seqn->endofs = ts.endofs;
2471                         seqn->endstill = ts.endstill;
2472                 }                               
2473                 
2474                 /* strips with extended stillframes after */
2475                 else if (((seqn->start+seqn->len) < cutframe) && (seqn->endstill)) {
2476                         seqn->start = cutframe - ts.len +1;
2477                         seqn->startofs = ts.len-1;
2478                         seqn->endstill = ts.enddisp - cutframe -1;
2479                         seqn->startstill = 0;
2480                 }
2481                 
2482                 calc_sequence(seqn);
2483         }
2484         return seqn;
2485 }
2486
2487
2488 /* like duplicate, but only duplicate and cut overlapping strips,
2489  * strips to the left of the cutframe are ignored and strips to the right are moved into the new list */
2490 static int cut_seq_list(ListBase *old, ListBase *new, int cutframe,
2491                         Sequence * (*cut_seq)(Sequence *, int))
2492 {
2493         int did_something = FALSE;
2494         Sequence *seq, *seq_next;
2495         
2496         seq= old->first;
2497         
2498         while(seq) {
2499                 seq_next = seq->next; /* we need this because we may remove seq */
2500                 
2501                 seq->tmp= NULL;
2502                 if(seq->flag & SELECT) {
2503                         if(cutframe > seq->startdisp && 
2504                            cutframe < seq->enddisp) {
2505                                 Sequence * seqn = cut_seq(seq, cutframe);
2506                                 if (seqn) {
2507                                         BLI_addtail(new, seqn);
2508                                 }
2509                                 did_something = TRUE;
2510                         } else if (seq->enddisp <= cutframe) {
2511                                 /* do nothing */
2512                         } else if (seq->startdisp >= cutframe) {
2513                                 /* move into new list */
2514                                 BLI_remlink(old, seq);
2515                                 BLI_addtail(new, seq);
2516                         }
2517                 }
2518                 seq = seq_next;
2519         }
2520         return did_something;
2521 }
2522
2523 void seq_cut(int cutframe, int hard_cut)
2524 {
2525         Editing *ed;
2526         ListBase newlist;
2527         char side;
2528         int did_something;
2529
2530         ed= G.scene->ed;
2531         if(ed==0) return;
2532         
2533         newlist.first= newlist.last= NULL;
2534
2535         if (hard_cut) {
2536                 did_something = cut_seq_list(
2537                         ed->seqbasep, &newlist, cutframe, cut_seq_hard);
2538         } else {
2539                 did_something = cut_seq_list(
2540                         ed->seqbasep, &newlist, cutframe, cut_seq_soft);
2541         }
2542         
2543         if (newlist.first) { /* got new strips ? */
2544                 Sequence *seq;
2545                 addlisttolist(ed->seqbasep, &newlist);
2546                 
2547                 
2548                 /* change the selection, not strictly needed but nice */
2549                 side = mouse_cfra_side(cutframe);
2550                 
2551                 WHILE_SEQ(ed->seqbasep) {
2552                         if (side=='L') {
2553                                 if ( seq->startdisp >= cutframe ) {
2554                                         seq->flag &= ~SELECT;
2555                                 }
2556                         } else {
2557                                 if ( seq->enddisp <= cutframe ) {
2558                                         seq->flag &= ~SELECT;
2559                                 }
2560                         }
2561                 }
2562                 END_SEQ;
2563                 
2564                 /* as last: */
2565                 sort_seq();
2566         }
2567         if (did_something) {
2568                 allqueue(REDRAWSEQ, 0);
2569                 BIF_undo_push("Cut Strips, Sequencer");
2570         }
2571 }
2572
2573 void add_duplicate_seq(void)
2574 {
2575         Editing *ed;
2576         ListBase new;
2577
2578         ed= G.scene->ed;
2579         if(ed==0) return;
2580
2581         new.first= new.last= 0;
2582
2583         recurs_dupli_seq(ed->seqbasep, &new);
2584         addlisttolist(ed->seqbasep, &new);
2585
2586         BIF_undo_push("Add Duplicate, Sequencer");
2587         transform_seq_nomarker('g', 0);
2588 }
2589
2590 int insert_gap(int gap, int cfra)
2591 {
2592         Sequence *seq;
2593         Editing *ed;
2594         int done=0;
2595
2596         /* all strips >= cfra are shifted */
2597         ed= G.scene->ed;
2598         if(ed==0) return 0;
2599
2600         WHILE_SEQ(ed->seqbasep) {
2601                 if(seq->startdisp >= cfra) {
2602                         seq->start+= gap;
2603                         calc_sequence(seq);
2604                         done= 1;
2605                 }
2606         }
2607         END_SEQ
2608
2609         return done;
2610 }
2611
2612 void touch_seq_files(void)
2613 {
2614         Sequence *seq;
2615         Editing *ed;
2616         char str[256];
2617
2618         /* touch all strips with movies */
2619         ed= G.scene->ed;
2620         if(ed==0) return;
2621
2622         if(okee("Touch and print selected movies")==0) return;
2623
2624         waitcursor(1);
2625
2626         WHILE_SEQ(ed->seqbasep) {
2627                 if(seq->flag & SELECT) {
2628                         if(seq->type==SEQ_MOVIE) {
2629                                 if(seq->strip && seq->strip->stripdata) {
2630                                         BLI_make_file_string(G.sce, str, seq->strip->dir, seq->strip->stripdata->name);
2631                                         BLI_touch(seq->name);
2632                                 }
2633                         }
2634
2635                 }
2636         }
2637         END_SEQ
2638
2639         waitcursor(0);
2640 }
2641
2642 void set_filter_seq(void)
2643 {
2644         Sequence *seq;
2645         Editing *ed;
2646
2647         ed= G.scene->ed;
2648         if(ed==0) return;
2649
2650         if(okee("Set Deinterlace")==0) return;
2651
2652         WHILE_SEQ(ed->seqbasep) {
2653                 if(seq->flag & SELECT) {
2654                         if(seq->type==SEQ_MOVIE) {
2655                                 seq->flag |= SEQ_FILTERY;
2656                                 reload_sequence_new_file(seq);
2657                         }
2658
2659                 }
2660         }
2661         END_SEQ
2662
2663 }
2664
2665 void seq_remap_paths(void)
2666 {
2667         Sequence *seq, *last_seq = get_last_seq();
2668         Editing *ed;
2669         char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
2670         
2671         ed= G.scene->ed;
2672         if(ed==NULL || last_seq==NULL) 
2673                 return;
2674         
2675         BLI_strncpy(from, last_seq->strip->dir, FILE_MAX);
2676         if (0==sbutton(from, 0, sizeof(from)-1, "From: "))
2677                 return;
2678         
2679         strcpy(to, from);
2680         if (0==sbutton(to, 0, sizeof(to)-1, "To: "))
2681                 return;
2682         
2683         if (strcmp(to, from)==0)
2684                 return;
2685         
2686         WHILE_SEQ(ed->seqbasep) {
2687                 if(seq->flag & SELECT) {
2688                         if(strncmp(seq->strip->dir, from, strlen(from))==0) {
2689                                 printf("found %s\n", seq->strip->dir);
2690                                 
2691                                 /* strip off the beginning */
2692                                 stripped[0]= 0;
2693                                 BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
2694                                 
2695                                 /* new path */
2696                                 BLI_strncpy(seq->strip->dir, to, FILE_MAX);
2697                                 strcat(seq->strip->dir, stripped);
2698                                 printf("new %s\n", seq->strip->dir);
2699                         }
2700                 }
2701         }
2702         END_SEQ
2703                 
2704         BIF_undo_push("Remap Paths, Sequencer");
2705         allqueue(REDRAWSEQ, 0);
2706 }
2707
2708
2709 void no_gaps(void)
2710 {
2711         Editing *ed;
2712         int cfra, first= 0, done;
2713
2714         ed= G.scene->ed;
2715         if(ed==0) return;
2716
2717         for(cfra= CFRA; cfra<=EFRA; cfra++) {
2718                 if(first==0) {
2719                         if( evaluate_seq_frame(cfra) ) first= 1;
2720                 }
2721                 else {
2722                         done= 1;
2723                         while( evaluate_seq_frame(cfra) == 0) {
2724                                 done= insert_gap(-1, cfra);
2725                                 if(done==0) break;
2726                         }
2727                         if(done==0) break;
2728                 }
2729         }
2730
2731         BIF_undo_push("No Gaps, Sequencer");
2732         allqueue(REDRAWSEQ, 0);
2733 }
2734
2735
2736 /* ****************** META ************************* */
2737
2738 void make_meta(void)
2739 {
2740         Sequence *seq, *seqm, *next;
2741         Editing *ed;
2742         int tot;
2743         
2744         ed= G.scene->ed;
2745         if(ed==0) return;
2746
2747         /* is there more than 1 select */
2748         tot= 0;
2749         seq= ed->seqbasep->first;
2750         while(seq) {
2751                 if(seq->flag & SELECT) {
2752                         tot++;
2753                         if (seq->type == SEQ_RAM_SOUND) { 
2754                                 error("Can't make Meta Strip from audio"); 
2755                                 return; 
2756                         }
2757                 }
2758                 seq= seq->next;
2759         }
2760         if(tot < 1) return;
2761
2762         if(okee("Make Meta Strip")==0) return;
2763
2764         /* test relationships */
2765         seq= ed->seqbasep->first;
2766         while(seq) {
2767                 if(seq->flag & SELECT) {
2768                         if(seq->type & SEQ_EFFECT) {
2769                                 if(seq->seq1 && 
2770                                    (seq->seq1->flag & SELECT)==0) tot= 0;
2771                                 if(seq->seq2 &&
2772                                    (seq->seq2->flag & SELECT)==0) tot= 0;
2773                                 if(seq->seq3 &&
2774                                    (seq->seq3->flag & SELECT)==0) tot= 0;
2775                         }
2776                 }
2777                 else if(seq->type & SEQ_EFFECT) {
2778                         if(seq->seq1 &&
2779                            (seq->seq1->flag & SELECT)) tot= 0;
2780                         if(seq->seq2 &&
2781                            (seq->seq2->flag & SELECT)) tot= 0;
2782                         if(seq->seq3 &&
2783                            (seq->seq3->flag & SELECT)) tot= 0;
2784                 }
2785                 if(tot==0) break;
2786                 seq= seq->next;
2787         }
2788         if(tot==0) {
2789                 error("Please select all related strips");
2790                 return;
2791         }
2792
2793         /* remove all selected from main list, and put in meta */
2794
2795         seqm= alloc_sequence(((Editing *)G.scene->ed)->seqbasep, 1, 1);
2796         seqm->type= SEQ_META;
2797         seqm->flag= SELECT;
2798
2799         seq= ed->seqbasep->first;
2800         while(seq) {
2801                 next= seq->next;
2802                 if(seq!=seqm && (seq->flag & SELECT)) {
2803                         BLI_remlink(ed->seqbasep, seq);
2804                         BLI_addtail(&seqm->seqbase, seq);
2805                 }
2806                 seq= next;
2807         }
2808         calc_sequence(seqm);
2809
2810         seqm->strip= MEM_callocN(sizeof(Strip), "metastrip");
2811         seqm->strip->len= seqm->len;
2812         seqm->strip->us= 1;
2813
2814         if( test_overlap_seq(seqm) ) shuffle_seq(seqm);
2815         
2816         BIF_undo_push("Make Meta Strip, Sequencer");
2817         allqueue(REDRAWSEQ, 0);
2818 }
2819
2820 static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
2821 {
2822         if (seq == seqm) return 1;
2823         else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
2824         else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
2825         else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
2826         else return 0;
2827 }
2828
2829 void un_meta(void)
2830 {
2831         Editing *ed;
2832         Sequence *seq, *last_seq = get_last_seq();
2833
2834         ed= G.scene->ed;
2835         if(ed==0) return;
2836
2837         if(last_seq==0 || last_seq->type!=SEQ_META) return;
2838
2839         if(okee("Un Meta Strip")==0) return;
2840
2841         addlisttolist(ed->seqbasep, &last_seq->seqbase);
2842
2843         last_seq->seqbase.first= 0;
2844         last_seq->seqbase.last= 0;
2845
2846         BLI_remlink(ed->seqbasep, last_seq);
2847         free_sequence(last_seq);
2848
2849         /* emtpy meta strip, delete all effects depending on it */
2850         for(seq=ed->seqbasep->first; seq; seq=seq->next)
2851                 if((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq))
2852                         seq->flag |= SEQ_FLAG_DELETE;
2853
2854         recurs_del_seq_flag(ed->seqbasep, SEQ_FLAG_DELETE, 0);
2855
2856         /* test for effects and overlap */
2857         WHILE_SEQ(ed->seqbasep) {
2858                 if(seq->flag & SELECT) {
2859                         seq->flag &= ~SEQ_OVERLAP;
2860                         if( test_overlap_seq(seq) ) {
2861                                 shuffle_seq(seq);
2862                         }
2863                 }
2864         }
2865         END_SEQ;
2866
2867         sort_seq();
2868
2869         BIF_undo_push("Un-Make Meta Strip, Sequencer");
2870         allqueue(REDRAWSEQ, 0);
2871
2872 }
2873
2874 void exit_meta(void)
2875 {
2876         Sequence *seq;
2877         MetaStack *ms;
2878         Editing *ed;
2879
2880         ed= G.scene->ed;
2881         if(ed==0) return;
2882
2883         if(ed->metastack.first==0) return;
2884
2885         ms= ed->metastack.last;
2886         BLI_remlink(&ed->metastack, ms);
2887
2888         ed->seqbasep= ms->oldbasep;
2889
2890         /* recalc all: the meta can have effects connected to it */
2891         seq= ed->seqbasep->first;
2892         while(seq) {
2893                 calc_sequence(seq);
2894                 seq= seq->next;
2895         }
2896
2897         set_last_seq(ms->parseq);
2898
2899         ms->parseq->flag |= SELECT;
2900         recurs_sel_seq(ms->parseq);
2901
2902         MEM_freeN(ms);
2903         allqueue(REDRAWSEQ, 0);
2904
2905         BIF_undo_push("Exit Meta Strip, Sequence");
2906 }
2907
2908
2909 void enter_meta(void)
2910 {
2911         MetaStack *ms;
2912         Editing *ed;
2913         Sequence *last_seq= get_last_seq();
2914
2915         ed= G.scene->ed;
2916         if(ed==0) return;
2917
2918         if(last_seq==0 || last_seq->type!=SEQ_META || (last_seq->flag & SELECT)==0) {
2919                 exit_meta();
2920                 return;
2921         }
2922
2923         ms= MEM_mallocN(sizeof(MetaStack), "metastack");
2924         BLI_addtail(&ed->metastack, ms);
2925         ms->parseq= last_seq;
2926         ms->oldbasep= ed->seqbasep;
2927
2928         ed->seqbasep= &last_seq->seqbase;
2929
2930         set_last_seq(NULL);
2931         allqueue(REDRAWSEQ, 0);
2932         BIF_undo_push("Enter Meta Strip, Sequence");
2933 }
2934
2935
2936 /* ****************** END META ************************* */
2937
2938 static int seq_get_snaplimit(void)
2939 {
2940         /* fake mouse coords to get the snap value
2941         a bit lazy but its only done once pre transform */
2942         float xmouse, ymouse, x;
2943         short mval[2] = {24, 0}; /* 24 screen px snap */
2944         areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
2945         x = xmouse;
2946         mval[0] = 0;
2947         areamouseco_to_ipoco(G.v2d, mval, &xmouse, &ymouse);
2948         return (int)(x - xmouse);
2949 }
2950
2951 /* use to impose limits when dragging/extending - so impossible situations dont happen */
2952 static void transform_grab_xlimits(Sequence *seq, int leftflag, int rightflag)
2953 {
2954         if(leftflag) {
2955                 if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_final_right(seq, 0)) {
2956                         seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1);
2957                 }
2958                 
2959                 if (check_single_seq(seq)==0) {
2960                         if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) {
2961                                 seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1);
2962                         }
2963                         
2964                         /* dosnt work now - TODO */
2965                         /*
2966                         if (seq_tx_get_start(seq) >= seq_tx_get_final_right(seq, 0)) {
2967                                 int ofs;
2968                                 ofs = seq_tx_get_start(seq) - seq_tx_get_final_right(seq, 0);
2969                                 seq->start -= ofs;
2970                                 seq_tx_set_final_left(seq, seq_tx_get_final_left(seq, 0) + ofs );
2971                         }*/
2972                         
2973                 }
2974         }
2975         
2976         if(rightflag) {
2977                 if (seq_tx_get_final_right(seq, 0) <=  seq_tx_get_final_left(seq, 0)) {
2978                         seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1);
2979                 }
2980                                                                         
2981                 if (check_single_seq(seq)==0) {
2982                         if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) {
2983                                 seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1);
2984                         }
2985                 }
2986         }
2987         
2988         /* sounds cannot be extended past their endpoints */
2989         if (seq->type == SEQ_RAM_SOUND || seq->type == SEQ_HD_SOUND) {
2990                 seq->startstill= 0;
2991                 seq->endstill= 0;
2992         }
2993 }
2994
2995 static int can_transform_seq_test_func(Sequence * seq)
2996 {
2997         if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
2998                 return BUILD_SEQAR_COUNT_CURRENT | BUILD_SEQAR_COUNT_CHILDREN;
2999         }
3000         if ((seq->depth==0 && seq->flag & SEQ_LOCK) && !(seq->type & SEQ_EFFECT)) {
3001                 if (seq->type != SEQ_META) {
3002                         return BUILD_SEQAR_COUNT_NOTHING;
3003                 } else {
3004                         return BUILD_SEQAR_COUNT_CURRENT;
3005                 }
3006         }
3007         return BUILD_SEQAR_COUNT_CURRENT | BUILD_SEQAR_COUNT_CHILDREN;
3008 }
3009
3010 void transform_seq(int mode, int context)
3011 {
3012         SpaceSeq *sseq= curarea->spacedata.first;
3013         Sequence *seq, *last_seq;
3014         Editing *ed;
3015         float dx, dy, dvec[2], div;
3016         TransSeq *transmain, *ts;
3017         int totstrip=0, firsttime=1, afbreek=0, midtog= 0, proj= 0;
3018         int ix, iy; /* these values are used for storing the mouses offset from its original location */
3019         int ix_old = 0;
3020         unsigned short event = 0;
3021         short mval[2], val, xo, yo, xn, yn;
3022         char str[32];
3023         char side= 'L'; /* for extend mode only - use to know which side to extend on */
3024         char marker_moved=0; /* if we mvoed a marker, redraw all marker views */
3025         /* used for extend in a number of places */
3026         int cfra = CFRA;
3027         
3028         /* for snapping */
3029         char snapskip = 0, snap, snap_old= 0;
3030         int snapdist_max = seq_get_snaplimit();
3031         /* at the moment there are only 4 possible snap points,
3032         -       last_seq (start,end)
3033         -       selected bounds (start/end)
3034         -       last_seq (next/prev)
3035         -       current frame */
3036         int snap_points[4], snap_point_num = 0;
3037         int j; /* loop on snap_points */
3038         
3039         /* for markers */
3040         int *oldframe = NULL, totmark=0, a;
3041         TimeMarker *marker;
3042         
3043         /* looping on sequences, WHILE_SEQ macro allocates memory each time */
3044         int totseq_index, seq_index; 
3045         Sequence **seqar = 0;
3046         
3047         if(mode!='g' && mode!='e') return;      /* from gesture */
3048
3049         /* which seqs are involved */
3050         ed= G.scene->ed;
3051         if(ed==0) return;
3052
3053         /* Build the sequence array once, be sure to free it */
3054         build_seqar_cb( ed->seqbasep,  &seqar, &totseq_index, 
3055                         can_transform_seq_test_func );
3056         
3057         if (seqar) {
3058                 for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
3059                         if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) 
3060                                 totstrip++;
3061                         /* only needed for extend but can set here anyway since were alredy looping */
3062                         seq->tmp= NULL;
3063                 }
3064         }
3065         
3066         /* for extending we need the metastrip clipped left/right values, set the metastrips as parents in seq->tmp */
3067         if (mode=='e') {
3068                 Sequence *meta_seq;
3069                 for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
3070                         if (seq->type == SEQ_META) {
3071                                 for (meta_seq = seq->seqbase.first; meta_seq; meta_seq= meta_seq->next){
3072                                         meta_seq->tmp= (void *)seq;
3073                                 }
3074                         }
3075                 }
3076         }
3077         
3078         
3079         if (sseq->flag & SEQ_MARKER_TRANS) {
3080                 for(marker= G.scene->markers.first; marker; marker= marker->next) {
3081                         if(marker->flag & SELECT) totmark++;
3082                 }
3083         }
3084         
3085         if(totstrip==0 && totmark==0) {
3086                 if(seqar) MEM_freeN(seqar);
3087                 return;
3088         }
3089
3090         G.moving= 1;
3091         
3092         last_seq = get_last_seq();
3093         
3094         ts=transmain= MEM_callocN(totstrip*sizeof(TransSeq), "transseq");
3095
3096         for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
3097                 if((seq->flag & SELECT) && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
3098                         ts->start= seq->start;
3099                         ts->machine= seq->machine;
3100                         ts->startstill= seq->startstill;
3101                         ts->endstill= seq->endstill;
3102                         ts->startofs= seq->startofs;
3103                         ts->endofs= seq->endofs;
3104                         
3105                         /* for extend only */
3106                         if (mode=='e') {
3107                                 ts->final_left = seq_tx_get_final_left(seq, 1);
3108                                 ts->final_right = seq_tx_get_final_right(seq, 1);
3109                         }
3110                         ts++;
3111                 }
3112         }
3113         
3114         getmouseco_areawin(mval);
3115         
3116         /* choose the side based on which side of the playhead the mouse is on */
3117         if (mode=='e')
3118                 side = mouse_cfra_side(cfra);
3119         
3120         /* Markers */
3121         if (sseq->flag & SEQ_MARKER_TRANS && totmark) {
3122                 oldframe= MEM_mallocN(totmark*sizeof(int), "marker array");
3123                 for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
3124                         if(marker->flag & SELECT) {
3125                                 if (mode=='e') {
3126                                         
3127                                         /* when extending, invalidate markers on the other side by using an invalid frame value */
3128                                         if ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)) {
3129                                                 oldframe[a] = MAXFRAME+1;
3130                                         } else {
3131                                                 oldframe[a]= marker->frame;
3132                                         }
3133                                 } else {
3134                                         oldframe[a]= marker->frame;
3135                                 }
3136                                 a++;
3137                         }
3138                 }
3139         }
3140         
3141         xo=xn= mval[0];
3142         yo=yn= mval[1];
3143         dvec[0]= dvec[1]= 0.0;
3144
3145         while(afbreek==0) {
3146                 getmouseco_areawin(mval);
3147                 G.qual = get_qual();
3148                 snap = (G.qual & LR_CTRLKEY) ? 1 : 0;
3149                 
3150                 if(mval[0]!=xo || mval[1]!=yo || firsttime || snap != snap_old) {
3151                         if (firsttime) {
3152                                 snap_old = snap;
3153                                 firsttime= 0;
3154                         }
3155                         
3156                         /* run for either grab or extend */
3157                         dx= mval[0]- xo;
3158                         dy= mval[1]- yo;
3159
3160                         div= G.v2d->mask.xmax-G.v2d->mask.xmin;
3161                         dx= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
3162
3163                         div= G.v2d->mask.ymax-G.v2d->mask.ymin;
3164                         dy= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
3165
3166                         if(G.qual & LR_SHIFTKEY) {
3167                                 if(dx>1.0) dx= 1.0; else if(dx<-1.0) dx= -1.0;
3168                         }
3169
3170                         dvec[0]+= dx;
3171                         dvec[1]+= dy;
3172
3173                         if(midtog) dvec[proj]= 0.0;
3174                         ix= floor(dvec[0]+0.5);
3175                         iy= floor(dvec[1]+0.5);
3176                         
3177                         ts= transmain;
3178                         
3179                         /* SNAP! use the active Seq */
3180                         snap = G.qual & LR_CTRLKEY ? 1 : 0;
3181                         
3182                         if (!snap) {
3183                                 snapskip = 0;
3184                         } else {
3185                                 int dist;
3186                                 int snap_ofs= 0;
3187                                 int snap_dist= snapdist_max;
3188                                 
3189                                 /* Get sequence points to snap to the markers */
3190                                 
3191                                 snap_point_num=0;
3192                                 if (last_seq && (last_seq->flag & SELECT)) { /* active seq bounds */
3193                                         if(seq_tx_check_left(last_seq))
3194                                                 snap_points[snap_point_num++] = seq_tx_get_final_left(last_seq, 0);
3195                                         if(seq_tx_check_right(last_seq))
3196                                                 snap_points[snap_point_num++] = seq_tx_get_final_right(last_seq, 0);
3197                                         
3198                                 }
3199                                 if (totstrip > 1) { /* selection bounds */
3200                                         int bounds_left = MAXFRAME*2;
3201                                         int bounds_right = -(MAXFRAME*2);
3202                                         
3203                                         for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
3204                                                 if(seq->flag & SELECT) {
3205                                                         if(seq_tx_check_left(seq))
3206                                                                 bounds_left             = MIN2(bounds_left,     seq_tx_get_final_left(seq, 0));
3207                                                         if(seq_tx_check_right(seq))
3208                                                                 bounds_right    = MAX2(bounds_right,seq_tx_get_final_right(seq, 0));
3209                                                 }
3210                                         }
3211                                         
3212                                         /* its possible there were no points to set on either side */
3213                                         if (bounds_left != MAXFRAME*2)
3214                                                 snap_points[snap_point_num++] = bounds_left;
3215                                         if (bounds_right != -(MAXFRAME*2))
3216                                                 snap_points[snap_point_num++] = bounds_right;
3217                                 }
3218                                 
3219                                 
3220                                 /* Define so we can snap to other points without hassle */
3221                                 
3222 #define TESTSNAP(test_frame)\
3223                                 for(j=0; j<snap_point_num; j++) {\
3224                                         /* see if this beats the current best snap point */\
3225                                         dist = abs(snap_points[j] - test_frame);\
3226                                         if (dist < snap_dist) {\
3227                                                 snap_ofs = test_frame - snap_points[j];\
3228                                                 snap_dist = dist;\
3229                                         }\
3230                                 }
3231                                 
3232                                 
3233                                 /* Detect the best marker to snap to! */
3234                                 for(a=0, marker= G.scene->markers.first; marker; a++, marker= marker->next) {
3235                                         
3236                                         /* dont snap to a marker on the wrong extend side */
3237                                         if (mode=='e' && ((side == 'L' && marker->frame > cfra) || (side == 'R' && marker->frame < cfra)))
3238                                                 continue;
3239                                         
3240                                         /* when we are moving markers, dont snap to selected markers, durr */
3241                                         if ((sseq->flag & SEQ_MARKER_TRANS)==0 || (marker->flag & SELECT)==0) {
3242                                                 
3243                                                 /* loop over the sticky points - max 4 */
3244                                                 TESTSNAP(marker->frame);
3245                                                 if (snap_dist == 0) break; /* alredy snapped? - stop looking */
3246                                         }
3247                                 }
3248                                 
3249                                 if (snap_dist) {
3250                                         TESTSNAP(cfra);
3251                                 }
3252                                 
3253                                 /* check seq's next to the active also - nice for quick snapping */
3254                                 if (snap_dist && last_seq && seq_tx_check_left(last_seq)) {
3255                                         seq = find_next_prev_sequence(last_seq, 1, 0); /* left */
3256                                         if(seq && !seq_tx_check_right(seq))
3257                                                 TESTSNAP(seq_tx_get_final_right(seq, 0));
3258                                 }
3259                                 
3260                                 if (snap_dist && last_seq && seq_tx_check_right(last_seq)) {
3261                                         seq = find_next_prev_sequence(last_seq, 2, 0); /* right */
3262                                         if(seq && !seq_tx_check_left(seq))
3263                                                 TESTSNAP(seq_tx_get_final_left(seq, 0));
3264                                 }
3265
3266 #undef TESTSNAP
3267
3268                                 if (abs(ix_old-ix) >= snapdist_max) {
3269                                         /* mouse has moved out of snap range */
3270                                         snapskip = 0;
3271                                 } else if (snap_dist==0) {
3272                                         /* nowhere to move, dont do anything */
3273                                         snapskip = 1;
3274                                 } else if (snap_dist < snapdist_max) {
3275                                         /* do the snapping by adjusting the mouse offset value */
3276                                         ix = ix_old + snap_ofs;
3277                                 }
3278                         }
3279                         
3280                         if (mode=='g' && !snapskip) {
3281                                 /* Grab */
3282                                 for(seq_index=0, seq=seqar[0]; seq_index < totseq_index; seq=seqar[++seq_index]) {
3283                                         if(seq->flag & SELECT && !(seq->depth==0 && seq->flag & SEQ_LOCK)) {
3284                                                 int myofs;
3285                                                 /* flag, ignores lefsel/rightsel for nested strips */
3286                                                 int sel_flag = (seq->depth==0) ? seq->flag : seq->flag & ~(SEQ_LEFTSEL+SEQ_RIGHTSEL);
3287                                                 
3288                                                 // SEQ_DEBUG_INFO(seq);
3289                                                 
3290                                                 /* X Transformation */
3291                                                 if((seq->depth==0) && (sel_flag & SEQ_LEFTSEL)) {
3292                                                         myofs = (ts->startofs - ts->startstill);
3293                                                         seq_tx_set_final_left(seq, ts->start + (myofs + ix));
3294                                                 }
3295                                                 if((seq->depth==0) && (sel_flag & SEQ_RIGHTSEL)) {
3296                                                         myofs = (ts->endstill - ts->endofs);
3297                                                         seq_tx_set_final_right(seq, ts->start + seq->len + (myofs + ix));
3298                                                 }
3299                                                 transform_grab_xlimits(seq, sel_flag & SEQ_LEFTSEL, sel_flag & SEQ_RIGHTSEL);
3300                                                 
3301                                                 if( (sel_flag & (SEQ_LEFTSEL+SEQ_RIGHTSEL))==0 ) {
3302                                                         if(sequence_is_free_transformable(seq)) seq->start= ts->start+ ix;
3303
3304                                                         /* Y Transformation */
3305                                                         if(seq->depth==0) seq->machine= ts->machine+ iy;
3306
3307                                                         if(seq->machine<1) seq->machine= 1;
3308                                                         else if(seq->machine>= MAXSEQ) seq->machine= MAXSEQ;
3309                                                 }
3310                                                 calc_sequence(seq);
3311                                                 ts++;
3312                                         }
3313                                 }
3314                                 
3315                                 /* Markers */
3316                                 if (sseq->flag & SEQ_MARKER_TRANS) {
3317                                         for(a=0, marker= G.scene->markers.first; marker; marker= marker->next) {
3318                                &nb