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