Big i18n commit: add "reports" from bmesh/readfile/tracking/dynapaint (and a few...
[blender.git] / source / blender / editors / space_sequencer / sequencer_edit.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2003-2009
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_sequencer/sequencer_edit.c
27  *  \ingroup spseq
28  */
29
30
31 #include <stdlib.h>
32 #include <math.h>
33 #include <string.h>
34
35 #ifndef WIN32
36 #include <unistd.h>
37 #else
38 #include <io.h>
39 #endif
40 #include <sys/types.h>
41
42 #include "MEM_guardedalloc.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_math.h"
46 #include "BLI_utildefines.h"
47 #include "BLI_threads.h"
48
49 #include "BLF_translation.h"
50
51 #include "DNA_scene_types.h"
52 #include "DNA_userdef_types.h"
53
54 #include "BKE_context.h"
55 #include "BKE_global.h"
56 #include "BKE_main.h"
57 #include "BKE_sequencer.h"
58 #include "BKE_report.h"
59 #include "BKE_sound.h"
60 #include "BKE_movieclip.h"
61
62 #include "IMB_imbuf.h"
63
64 #include "WM_api.h"
65 #include "WM_types.h"
66
67 #include "RNA_define.h"
68 #include "RNA_enum_types.h"
69
70 /* for menu/popup icons etc etc*/
71
72 #include "ED_screen.h"
73 #include "ED_transform.h"
74 #include "ED_sequencer.h"
75
76 #include "UI_view2d.h"
77
78 /* own include */
79 #include "sequencer_intern.h"
80
81 /* XXX */
82 /* RNA Enums, used in multiple files */
83 EnumPropertyItem sequencer_prop_effect_types[] = {
84         {SEQ_TYPE_CROSS, "CROSS", 0, "Crossfade", "Crossfade effect strip type"},
85         {SEQ_TYPE_ADD, "ADD", 0, "Add", "Add effect strip type"},
86         {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", "Subtract effect strip type"},
87         {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", "Alpha Over effect strip type"},
88         {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", "Alpha Under effect strip type"},
89         {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", "Gamma Cross effect strip type"},
90         {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", "Multiply effect strip type"},
91         {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Alpha Over Drop", "Alpha Over Drop effect strip type"},
92         {SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", "Wipe effect strip type"},
93         {SEQ_TYPE_GLOW, "GLOW", 0, "Glow", "Glow effect strip type"},
94         {SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", "Transform effect strip type"},
95         {SEQ_TYPE_COLOR, "COLOR", 0, "Color", "Color effect strip type"},
96         {SEQ_TYPE_SPEED, "SPEED", 0, "Speed", "Color effect strip type"},
97         {SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""},
98         {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""},
99         {0, NULL, 0, NULL, NULL}
100 };
101
102 /* mute operator */
103
104 EnumPropertyItem prop_side_types[] = {
105         {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
106         {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
107         {SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""},
108         {0, NULL, 0, NULL, NULL}
109 };
110
111 static EnumPropertyItem prop_side_lr_types[] = {
112         {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
113         {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
114         {0, NULL, 0, NULL, NULL}
115 };
116
117 typedef struct TransSeq {
118         int start, machine;
119         int startstill, endstill;
120         int startdisp, enddisp;
121         int startofs, endofs;
122         int anim_startofs, anim_endofs;
123         /* int final_left, final_right; */ /* UNUSED */
124         int len;
125 } TransSeq;
126
127 /* ********************************************************************** */
128
129 /* ***************** proxy job manager ********************** */
130
131 typedef struct ProxyBuildJob {
132         Scene *scene; 
133         struct Main *main;
134         ListBase queue;
135         int stop;
136 } ProxyJob;
137
138 static void proxy_freejob(void *pjv)
139 {
140         ProxyJob *pj = pjv;
141
142         BLI_freelistN(&pj->queue);
143
144         MEM_freeN(pj);
145 }
146
147 /* only this runs inside thread */
148 static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
149 {
150         ProxyJob *pj = pjv;
151         LinkData *link;
152
153         for (link = pj->queue.first; link; link = link->next) {
154                 struct SeqIndexBuildContext *context = link->data;
155
156                 BKE_sequencer_proxy_rebuild(context, stop, do_update, progress);
157         }
158
159         if (*stop) {
160                 pj->stop = 1;
161                 fprintf(stderr,  "Canceling proxy rebuild on users request...\n");
162         }
163 }
164
165 static void proxy_endjob(void *pjv)
166 {
167         ProxyJob *pj = pjv;
168         Editing *ed = BKE_sequencer_editing_get(pj->scene, FALSE);
169         LinkData *link;
170
171         for (link = pj->queue.first; link; link = link->next) {
172                 BKE_sequencer_proxy_rebuild_finish(link->data, pj->stop);
173         }
174
175         BKE_sequencer_free_imbuf(pj->scene, &ed->seqbase, FALSE);
176
177         WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene);
178 }
179
180 static void seq_proxy_build_job(const bContext *C)
181 {
182         wmJob *wm_job;
183         ProxyJob *pj;
184         Scene *scene = CTX_data_scene(C);
185         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
186         ScrArea *sa = CTX_wm_area(C);
187         struct SeqIndexBuildContext *context;
188         LinkData *link;
189         Sequence *seq;
190
191         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies",
192                              WM_JOB_PROGRESS, WM_JOB_TYPE_SEQ_BUILD_PROXY);
193
194         pj = WM_jobs_customdata_get(wm_job);
195
196         if (!pj) {
197                 pj = MEM_callocN(sizeof(ProxyJob), "proxy rebuild job");
198         
199                 pj->scene = scene;
200                 pj->main = CTX_data_main(C);
201
202                 WM_jobs_customdata_set(wm_job, pj, proxy_freejob);
203                 WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_SEQUENCER, NC_SCENE | ND_SEQUENCER);
204                 WM_jobs_callbacks(wm_job, proxy_startjob, NULL, NULL, proxy_endjob);
205         }
206
207         SEQP_BEGIN (ed, seq)
208         {
209                 if ((seq->flag & SELECT)) {
210                         context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq);
211                         link = BLI_genericNodeN(context);
212                         BLI_addtail(&pj->queue, link);
213                 }
214         }
215         SEQ_END
216
217         if (!WM_jobs_is_running(wm_job)) {
218                 G.is_break = FALSE;
219                 WM_jobs_start(CTX_wm_manager(C), wm_job);
220         }
221
222         ED_area_tag_redraw(CTX_wm_area(C));
223 }
224
225 /* ********************************************************************** */
226
227 void seq_rectf(Sequence *seq, rctf *rectf)
228 {
229         if (seq->startstill) rectf->xmin = seq->start;
230         else rectf->xmin = seq->startdisp;
231         rectf->ymin = seq->machine + SEQ_STRIP_OFSBOTTOM;
232         if (seq->endstill) rectf->xmax = seq->start + seq->len;
233         else rectf->xmax = seq->enddisp;
234         rectf->ymax = seq->machine + SEQ_STRIP_OFSTOP;
235 }
236
237 void boundbox_seq(Scene *scene, rctf *rect)
238 {
239         Sequence *seq;
240         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
241         float min[2], max[2];
242
243         
244         if (ed == NULL) return;
245
246         min[0] = 0.0;
247         max[0] = EFRA + 1;
248         min[1] = 0.0;
249         max[1] = 8.0;
250
251         seq = ed->seqbasep->first;
252         while (seq) {
253
254                 if (min[0] > seq->startdisp - 1) min[0] = seq->startdisp - 1;
255                 if (max[0] < seq->enddisp + 1) max[0] = seq->enddisp + 1;
256                 if (max[1] < seq->machine + 2) max[1] = seq->machine + 2;
257
258                 seq = seq->next;
259         }
260
261         rect->xmin = min[0];
262         rect->xmax = max[0];
263         rect->ymin = min[1];
264         rect->ymax = max[1];
265
266 }
267
268 static int mouse_frame_side(View2D *v2d, short mouse_x, int frame)
269 {
270         int mval[2];
271         float mouseloc[2];
272         
273         mval[0] = mouse_x;
274         mval[1] = 0;
275         
276         /* choose the side based on which side of the playhead the mouse is on */
277         UI_view2d_region_to_view(v2d, mval[0], mval[1], &mouseloc[0], &mouseloc[1]);
278         
279         return mouseloc[0] > frame ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT;
280 }
281
282
283 Sequence *find_neighboring_sequence(Scene *scene, Sequence *test, int lr, int sel) 
284 {
285         /* sel - 0==unselected, 1==selected, -1==done care*/
286         Sequence *seq;
287         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
288
289         if (ed == NULL) return NULL;
290
291         if (sel > 0) sel = SELECT;
292         
293         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
294                 if ((seq != test) &&
295                     (test->machine == seq->machine) &&
296                     ((sel == -1) || (sel && (seq->flag & SELECT)) || (sel == 0 && (seq->flag & SELECT) == 0)  ))
297                 {
298                         switch (lr) {
299                                 case SEQ_SIDE_LEFT:
300                                         if (test->startdisp == (seq->enddisp)) {
301                                                 return seq;
302                                         }
303                                         break;
304                                 case SEQ_SIDE_RIGHT:
305                                         if (test->enddisp == (seq->startdisp)) {
306                                                 return seq;
307                                         }
308                                         break;
309                         }
310                 }
311         }
312         return NULL;
313 }
314
315 static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel) 
316 {
317         /* sel - 0==unselected, 1==selected, -1==done care*/
318         Sequence *seq, *best_seq = NULL;
319         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
320         
321         int dist, best_dist;
322         best_dist = MAXFRAME * 2;
323
324         
325         if (ed == NULL) return NULL;
326
327         seq = ed->seqbasep->first;
328         while (seq) {
329                 if ((seq != test) &&
330                     (test->machine == seq->machine) &&
331                     (test->depth == seq->depth) &&
332                     ((sel == -1) || (sel == (seq->flag & SELECT))))
333                 {
334                         dist = MAXFRAME * 2;
335                         
336                         switch (lr) {
337                                 case SEQ_SIDE_LEFT:
338                                         if (seq->enddisp <= test->startdisp) {
339                                                 dist = test->enddisp - seq->startdisp;
340                                         }
341                                         break;
342                                 case SEQ_SIDE_RIGHT:
343                                         if (seq->startdisp >= test->enddisp) {
344                                                 dist = seq->startdisp - test->enddisp;
345                                         }
346                                         break;
347                         }
348                         
349                         if (dist == 0) {
350                                 best_seq = seq;
351                                 break;
352                         }
353                         else if (dist < best_dist) {
354                                 best_dist = dist;
355                                 best_seq = seq;
356                         }
357                 }
358                 seq = seq->next;
359         }
360         return best_seq; /* can be null */
361 }
362
363
364 Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, const int mval[2])
365 {
366         Sequence *seq;
367         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
368         float x, y;
369         float pixelx;
370         float handsize;
371         float displen;
372         *hand = SEQ_SIDE_NONE;
373
374         
375         if (ed == NULL) return NULL;
376         
377         pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
378
379         UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
380         
381         seq = ed->seqbasep->first;
382         
383         while (seq) {
384                 if (seq->machine == (int)y) {
385                         /* check for both normal strips, and strips that have been flipped horizontally */
386                         if (((seq->startdisp < seq->enddisp) && (seq->startdisp <= x && seq->enddisp >= x)) ||
387                             ((seq->startdisp > seq->enddisp) && (seq->startdisp >= x && seq->enddisp <= x)) )
388                         {
389                                 if (BKE_sequence_tx_test(seq)) {
390                                         
391                                         /* clamp handles to defined size in pixel space */
392                                         
393                                         handsize = seq->handsize;
394                                         displen = (float)abs(seq->startdisp - seq->enddisp);
395                                         
396                                         if (displen / pixelx > 16) { /* don't even try to grab the handles of small strips */
397                                                 /* Set the max value to handle to 1/3 of the total len when its less then 28.
398                                                  * This is important because otherwise selecting handles happens even when you click in the middle */
399                                                 
400                                                 if ((displen / 3) < 30 * pixelx) {
401                                                         handsize = displen / 3;
402                                                 }
403                                                 else {
404                                                         CLAMP(handsize, 7 * pixelx, 30 * pixelx);
405                                                 }
406                                                 
407                                                 if (handsize + seq->startdisp >= x)
408                                                         *hand = SEQ_SIDE_LEFT;
409                                                 else if (-handsize + seq->enddisp <= x)
410                                                         *hand = SEQ_SIDE_RIGHT;
411                                         }
412                                 }
413                                 return seq;
414                         }
415                 }
416                 seq = seq->next;
417         }
418         return NULL;
419 }
420
421
422 static int seq_is_parent(Sequence *par, Sequence *seq)
423 {
424         return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq));
425 }
426
427 static int seq_is_predecessor(Sequence *pred, Sequence *seq)
428 {
429         if (!pred) return 0;
430         if (pred == seq) return 0;
431         else if (seq_is_parent(pred, seq)) return 1;
432         else if (pred->seq1 && seq_is_predecessor(pred->seq1, seq)) return 1;
433         else if (pred->seq2 && seq_is_predecessor(pred->seq2, seq)) return 1;
434         else if (pred->seq3 && seq_is_predecessor(pred->seq3, seq)) return 1;
435
436         return 0;
437 }
438
439 void ED_sequencer_deselect_all(Scene *scene)
440 {
441         Sequence *seq;
442         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
443
444         
445         if (ed == NULL) return;
446
447         SEQP_BEGIN (ed, seq)
448         {
449                 seq->flag &= ~SEQ_ALLSEL;
450         }
451         SEQ_END
452                 
453 }
454
455 void recurs_sel_seq(Sequence *seqm)
456 {
457         Sequence *seq;
458
459         seq = seqm->seqbase.first;
460         while (seq) {
461
462                 if (seqm->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) seq->flag &= ~SEQ_ALLSEL;
463                 else if (seqm->flag & SELECT) seq->flag |= SELECT;
464                 else seq->flag &= ~SEQ_ALLSEL;
465
466                 if (seq->seqbase.first) recurs_sel_seq(seq);
467
468                 seq = seq->next;
469         }
470 }
471
472 int ED_space_sequencer_maskedit_mask_poll(bContext *C)
473 {
474         /* in this case both funcs are the same, for clip editor not */
475         return ED_space_sequencer_maskedit_poll(C);
476 }
477
478 int ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, Scene *scene)
479 {
480         if (sseq && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
481                 return (BKE_sequencer_mask_get(scene) != NULL);
482         }
483
484         return FALSE;
485 }
486
487 int ED_space_sequencer_maskedit_poll(bContext *C)
488 {
489         SpaceSeq *sseq = CTX_wm_space_seq(C);
490
491         if (sseq) {
492                 Scene *scene = CTX_data_scene(C);
493                 return ED_space_sequencer_check_show_maskedit(sseq, scene);
494         }
495
496         return FALSE;
497 }
498
499 int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str)
500 {
501         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
502         Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq;
503         
504         *error_str = NULL;
505
506         if (!activeseq)
507                 seq2 = BKE_sequencer_active_get(scene);
508
509         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
510                 if (seq->flag & SELECT) {
511                         if (seq->type == SEQ_TYPE_SOUND_RAM && BKE_sequence_effect_get_num_inputs(type) != 0) {
512                                 *error_str = N_("Cannot apply effects to audio sequence strips");
513                                 return 0;
514                         }
515                         if ((seq != activeseq) && (seq != seq2)) {
516                                 if (seq2 == NULL) seq2 = seq;
517                                 else if (seq1 == NULL) seq1 = seq;
518                                 else if (seq3 == NULL) seq3 = seq;
519                                 else {
520                                         *error_str = N_("Cannot apply effect to more than 3 sequence strips");
521                                         return 0;
522                                 }
523                         }
524                 }
525         }
526
527         /* make sequence selection a little bit more intuitive
528          * for 3 strips: the last-strip should be sequence3 */
529         if (seq3 != NULL && seq2 != NULL) {
530                 Sequence *tmp = seq2;
531                 seq2 = seq3;
532                 seq3 = tmp;
533         }
534         
535
536         switch (BKE_sequence_effect_get_num_inputs(type)) {
537                 case 0:
538                         *selseq1 = *selseq2 = *selseq3 = NULL;
539                         return 1; /* succsess */
540                 case 1:
541                         if (seq2 == NULL) {
542                                 *error_str = N_("At least one selected sequence strip is needed");
543                                 return 0;
544                         }
545                         if (seq1 == NULL) seq1 = seq2;
546                         if (seq3 == NULL) seq3 = seq2;
547                 case 2:
548                         if (seq1 == NULL || seq2 == NULL) {
549                                 *error_str = N_("2 selected sequence strips are needed");
550                                 return 0;
551                         }
552                         if (seq3 == NULL) seq3 = seq2;
553         }
554         
555         if (seq1 == NULL && seq2 == NULL && seq3 == NULL) {
556                 *error_str = N_("TODO: in what cases does this happen?");
557                 return 0;
558         }
559         
560         *selseq1 = seq1;
561         *selseq2 = seq2;
562         *selseq3 = seq3;
563
564         return 1;
565 }
566
567 static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq)
568 {
569         Sequence *seq1, *seq2, *seq3;
570
571         /* try to find a replacement input sequence, and flag for later deletion if
572          * no replacement can be found */
573
574         if (!seq)
575                 return NULL;
576         else if (!(seq->type & SEQ_TYPE_EFFECT))
577                 return ((seq->flag & SELECT) ? NULL : seq);
578         else if (!(seq->flag & SELECT)) {
579                 /* try to find replacement for effect inputs */
580                 seq1 = del_seq_find_replace_recurs(scene, seq->seq1);
581                 seq2 = del_seq_find_replace_recurs(scene, seq->seq2);
582                 seq3 = del_seq_find_replace_recurs(scene, seq->seq3);
583
584                 if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) {
585                         /* pass */
586                 }
587                 else if (seq1 || seq2 || seq3) {
588                         seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3;
589                         seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3;
590                         seq->seq3 = (seq3) ? seq3 : (seq1) ? seq1 : seq2;
591
592                         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1);
593                 }
594                 else
595                         seq->flag |= SELECT;  /* mark for delete */
596         }
597
598         if (seq->flag & SELECT) {
599                 if ((seq1 = del_seq_find_replace_recurs(scene, seq->seq1))) return seq1;
600                 if ((seq2 = del_seq_find_replace_recurs(scene, seq->seq2))) return seq2;
601                 if ((seq3 = del_seq_find_replace_recurs(scene, seq->seq3))) return seq3;
602                 else return NULL;
603         }
604         else
605                 return seq;
606 }
607
608 static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall)
609 {
610         Sequence *seq, *seqn;
611         Sequence *last_seq = BKE_sequencer_active_get(scene);
612
613         seq = lb->first;
614         while (seq) {
615                 seqn = seq->next;
616                 if ((seq->flag & flag) || deleteall) {
617                         BLI_remlink(lb, seq);
618                         if (seq == last_seq) BKE_sequencer_active_set(scene, NULL);
619                         if (seq->type == SEQ_TYPE_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1);
620                         BKE_sequence_free(scene, seq);
621                 }
622                 seq = seqn;
623         }
624 }
625
626
627 static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
628 {
629         TransSeq ts;
630         Sequence *seqn = NULL;
631         int skip_dup = FALSE;
632
633         /* backup values */
634         ts.start = seq->start;
635         ts.machine = seq->machine;
636         ts.startstill = seq->startstill;
637         ts.endstill = seq->endstill;
638         ts.startdisp = seq->startdisp;
639         ts.enddisp = seq->enddisp;
640         ts.startofs = seq->startofs;
641         ts.endofs = seq->endofs;
642         ts.anim_startofs = seq->anim_startofs;
643         ts.anim_endofs = seq->anim_endofs;
644         ts.len = seq->len;
645         
646         /* First Strip! */
647         /* strips with extended stillfames before */
648         
649         if ((seq->startstill) && (cutframe < seq->start)) {
650                 /* don't do funny things with METAs ... */
651                 if (seq->type == SEQ_TYPE_META) {
652                         skip_dup = TRUE;
653                         seq->startstill = seq->start - cutframe;
654                 }
655                 else {
656                         seq->start = cutframe - 1;
657                         seq->startstill = cutframe - seq->startdisp - 1;
658                         seq->anim_endofs += seq->len - 1;
659                         seq->endstill = 0;
660                 }
661         }
662         /* normal strip */
663         else if ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len))) {
664                 seq->endofs = 0;
665                 seq->endstill = 0;
666                 seq->anim_endofs += (seq->start + seq->len) - cutframe;
667         }
668         /* strips with extended stillframes after */
669         else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) {
670                 seq->endstill -= seq->enddisp - cutframe;
671                 /* don't do funny things with METAs ... */
672                 if (seq->type == SEQ_TYPE_META) {
673                         skip_dup = TRUE;
674                 }
675         }
676         
677         BKE_sequence_reload_new_file(scene, seq, FALSE);
678         BKE_sequence_calc(scene, seq);
679
680         if (!skip_dup) {
681                 /* Duplicate AFTER the first change */
682                 seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
683         }
684         
685         if (seqn) {
686                 seqn->flag |= SELECT;
687                         
688                 /* Second Strip! */
689                 /* strips with extended stillframes before */
690                 if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
691                         seqn->start = ts.start;
692                         seqn->startstill = ts.start - cutframe;
693                         seqn->anim_endofs = ts.anim_endofs;
694                         seqn->endstill = ts.endstill;
695                 }
696                 
697                 /* normal strip */
698                 else if ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len))) {
699                         seqn->start = cutframe;
700                         seqn->startstill = 0;
701                         seqn->startofs = 0;
702                         seqn->endofs = ts.endofs;
703                         seqn->anim_startofs += cutframe - ts.start;
704                         seqn->anim_endofs = ts.anim_endofs;
705                         seqn->endstill = ts.endstill;
706                 }
707                 
708                 /* strips with extended stillframes after */
709                 else if (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)) {
710                         seqn->start = cutframe;
711                         seqn->startofs = 0;
712                         seqn->anim_startofs += ts.len - 1;
713                         seqn->endstill = ts.enddisp - cutframe - 1;
714                         seqn->startstill = 0;
715                 }
716                 
717                 BKE_sequence_reload_new_file(scene, seqn, FALSE);
718                 BKE_sequence_calc(scene, seqn);
719         }
720         return seqn;
721 }
722
723 static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
724 {
725         TransSeq ts;
726         Sequence *seqn = NULL;
727         int skip_dup = FALSE;
728
729         /* backup values */
730         ts.start = seq->start;
731         ts.machine = seq->machine;
732         ts.startstill = seq->startstill;
733         ts.endstill = seq->endstill;
734         ts.startdisp = seq->startdisp;
735         ts.enddisp = seq->enddisp;
736         ts.startofs = seq->startofs;
737         ts.endofs = seq->endofs;
738         ts.anim_startofs = seq->anim_startofs;
739         ts.anim_endofs = seq->anim_endofs;
740         ts.len = seq->len;
741         
742         /* First Strip! */
743         /* strips with extended stillfames before */
744         
745         if ((seq->startstill) && (cutframe < seq->start)) {
746                 /* don't do funny things with METAs ... */
747                 if (seq->type == SEQ_TYPE_META) {
748                         skip_dup = TRUE;
749                         seq->startstill = seq->start - cutframe;
750                 }
751                 else {
752                         seq->start = cutframe - 1;
753                         seq->startstill = cutframe - seq->startdisp - 1;
754                         seq->endofs = seq->len - 1;
755                         seq->endstill = 0;
756                 }
757         }
758         /* normal strip */
759         else if ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len))) {
760                 seq->endofs = (seq->start + seq->len) - cutframe;
761         }
762         /* strips with extended stillframes after */
763         else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) {
764                 seq->endstill -= seq->enddisp - cutframe;
765                 /* don't do funny things with METAs ... */
766                 if (seq->type == SEQ_TYPE_META) {
767                         skip_dup = TRUE;
768                 }
769         }
770         
771         BKE_sequence_calc(scene, seq);
772
773         if (!skip_dup) {
774                 /* Duplicate AFTER the first change */
775                 seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
776         }
777         
778         if (seqn) {
779                 seqn->flag |= SELECT;
780                         
781                 /* Second Strip! */
782                 /* strips with extended stillframes before */
783                 if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
784                         seqn->start = ts.start;
785                         seqn->startstill = ts.start - cutframe;
786                         seqn->endofs = ts.endofs;
787                         seqn->endstill = ts.endstill;
788                 }
789                 
790                 /* normal strip */
791                 else if ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len))) {
792                         seqn->startstill = 0;
793                         seqn->startofs = cutframe - ts.start;
794                         seqn->endofs = ts.endofs;
795                         seqn->endstill = ts.endstill;
796                 }
797                 
798                 /* strips with extended stillframes after */
799                 else if (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)) {
800                         seqn->start = cutframe - ts.len + 1;
801                         seqn->startofs = ts.len - 1;
802                         seqn->endstill = ts.enddisp - cutframe - 1;
803                         seqn->startstill = 0;
804                 }
805                 
806                 BKE_sequence_calc(scene, seqn);
807         }
808         return seqn;
809 }
810
811
812 /* like duplicate, but only duplicate and cut overlapping strips,
813  * strips to the left of the cutframe are ignored and strips to the right are moved into the new list */
814 static int cut_seq_list(Scene *scene, ListBase *old, ListBase *new, int cutframe,
815                         Sequence * (*cut_seq)(Scene *, Sequence *, int))
816 {
817         int did_something = FALSE;
818         Sequence *seq, *seq_next_iter;
819         
820         seq = old->first;
821         
822         while (seq) {
823                 seq_next_iter = seq->next; /* we need this because we may remove seq */
824                 
825                 seq->tmp = NULL;
826                 if (seq->flag & SELECT) {
827                         if (cutframe > seq->startdisp && 
828                             cutframe < seq->enddisp)
829                         {
830                                 Sequence *seqn = cut_seq(scene, seq, cutframe);
831                                 if (seqn) {
832                                         BLI_addtail(new, seqn);
833                                 }
834                                 did_something = TRUE;
835                         }
836                         else if (seq->enddisp <= cutframe) {
837                                 /* do nothing */
838                         }
839                         else if (seq->startdisp >= cutframe) {
840                                 /* move into new list */
841                                 BLI_remlink(old, seq);
842                                 BLI_addtail(new, seq);
843                         }
844                 }
845                 seq = seq_next_iter;
846         }
847         return did_something;
848 }
849
850 static int insert_gap(Scene *scene, int gap, int cfra)
851 {
852         Sequence *seq;
853         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
854         int done = FALSE;
855
856         /* all strips >= cfra are shifted */
857         
858         if (ed == NULL) return 0;
859
860         SEQP_BEGIN (ed, seq)
861         {
862                 if (seq->startdisp >= cfra) {
863                         seq->start += gap;
864                         BKE_sequence_calc(scene, seq);
865                         done = TRUE;
866                 }
867         }
868         SEQ_END
869
870         return done;
871 }
872
873 static void UNUSED_FUNCTION(touch_seq_files) (Scene * scene)
874 {
875         Sequence *seq;
876         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
877         char str[256];
878
879         /* touch all strips with movies */
880         
881         if (ed == NULL) return;
882
883         // XXX25 if (okee("Touch and print selected movies")==0) return;
884
885         WM_cursor_wait(1);
886
887         SEQP_BEGIN (ed, seq)
888         {
889                 if (seq->flag & SELECT) {
890                         if (seq->type == SEQ_TYPE_MOVIE) {
891                                 if (seq->strip && seq->strip->stripdata) {
892                                         BLI_make_file_string(G.main->name, str, seq->strip->dir, seq->strip->stripdata->name);
893                                         BLI_file_touch(seq->name);
894                                 }
895                         }
896
897                 }
898         }
899         SEQ_END
900
901         WM_cursor_wait(0);
902 }
903
904 #if 0
905 static void set_filter_seq(Scene *scene)
906 {
907         Sequence *seq;
908         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
909
910         
911         if (ed == NULL) return;
912
913         if (okee("Set Deinterlace") == 0) return;
914
915         SEQP_BEGIN (ed, seq)
916         {
917                 if (seq->flag & SELECT) {
918                         if (seq->type == SEQ_TYPE_MOVIE) {
919                                 seq->flag |= SEQ_FILTERY;
920                                 reload_sequence_new_file(scene, seq, FALSE);
921                                 calc_sequence(scene, seq);
922                         }
923
924                 }
925         }
926         SEQ_END
927 }
928 #endif
929
930 static void UNUSED_FUNCTION(seq_remap_paths) (Scene * scene)
931 {
932         Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
933         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
934         char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
935         
936         
937         if (last_seq == NULL)
938                 return;
939         
940         BLI_strncpy(from, last_seq->strip->dir, sizeof(from));
941 // XXX  if (0 == sbutton(from, 0, sizeof(from)-1, "From: "))
942 //              return;
943         
944         BLI_strncpy(to, from, sizeof(to));
945 // XXX  if (0 == sbutton(to, 0, sizeof(to)-1, "To: "))
946 //              return;
947         
948         if (strcmp(to, from) == 0)
949                 return;
950         
951         SEQP_BEGIN (ed, seq)
952         {
953                 if (seq->flag & SELECT) {
954                         if (strncmp(seq->strip->dir, from, strlen(from)) == 0) {
955                                 printf("found %s\n", seq->strip->dir);
956                                 
957                                 /* strip off the beginning */
958                                 stripped[0] = 0;
959                                 BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
960                                 
961                                 /* new path */
962                                 BLI_snprintf(seq->strip->dir, sizeof(seq->strip->dir), "%s%s", to, stripped);
963                                 printf("new %s\n", seq->strip->dir);
964                         }
965                 }
966         }
967         SEQ_END
968                 
969 }
970
971
972 static void UNUSED_FUNCTION(no_gaps) (Scene * scene)
973 {
974         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
975         int cfra, first = 0, done;
976
977         
978         if (ed == NULL) return;
979
980         for (cfra = CFRA; cfra <= EFRA; cfra++) {
981                 if (first == 0) {
982                         if (BKE_sequencer_evaluate_frame(scene, cfra) ) first = 1;
983                 }
984                 else {
985                         done = TRUE;
986                         while (BKE_sequencer_evaluate_frame(scene, cfra) == 0) {
987                                 done = insert_gap(scene, -1, cfra);
988                                 if (done == 0) break;
989                         }
990                         if (done == 0) break;
991                 }
992         }
993
994 }
995
996 #if 0
997 static int seq_get_snaplimit(View2D *v2d)
998 {
999         /* fake mouse coords to get the snap value
1000          * a bit lazy but its only done once pre transform */
1001         float xmouse, ymouse, x;
1002         int mval[2] = {24, 0}; /* 24 screen px snap */
1003         
1004         UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
1005         x = xmouse;
1006         mval[0] = 0;
1007         UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
1008         return (int)(x - xmouse);
1009 }
1010 #endif
1011
1012 /* Operator functions */
1013 int sequencer_edit_poll(bContext *C)
1014 {
1015         return (BKE_sequencer_editing_get(CTX_data_scene(C), FALSE) != NULL);
1016 }
1017
1018 #if 0 /* UNUSED */
1019 int sequencer_strip_poll(bContext *C)
1020 {
1021         Editing *ed;
1022         return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), FALSE)) != NULL) && (ed->act_seq != NULL));
1023 }
1024 #endif
1025
1026 int sequencer_strip_has_path_poll(bContext *C)
1027 {
1028         Editing *ed;
1029         Sequence *seq;
1030         return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), FALSE)) != NULL) && ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
1031 }
1032
1033 int sequencer_view_poll(bContext *C)
1034 {
1035         SpaceSeq *sseq = CTX_wm_space_seq(C);
1036         Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), FALSE);
1037         if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF))
1038                 return 1;
1039
1040         return 0;
1041 }
1042
1043 /* snap operator*/
1044 static int sequencer_snap_exec(bContext *C, wmOperator *op)
1045 {
1046         Scene *scene = CTX_data_scene(C);
1047         
1048         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1049         Sequence *seq;
1050         int snap_frame;
1051
1052         snap_frame = RNA_int_get(op->ptr, "frame");
1053
1054         /* also check metas */
1055         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1056                 if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
1057                     BKE_sequence_tx_test(seq))
1058                 {
1059                         if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
1060                                 /* simple but no anim update */
1061                                 /* seq->start = snap_frame-seq->startofs+seq->startstill; */
1062
1063                                 BKE_sequence_translate(scene, seq, (snap_frame - seq->startofs + seq->startstill) - seq->start);
1064                         }
1065                         else {
1066                                 if (seq->flag & SEQ_LEFTSEL) {
1067                                         BKE_sequence_tx_set_final_left(seq, snap_frame);
1068                                 }
1069                                 else { /* SEQ_RIGHTSEL */
1070                                         BKE_sequence_tx_set_final_right(seq, snap_frame);
1071                                 }
1072                                 BKE_sequence_tx_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
1073                         }
1074                         BKE_sequence_calc(scene, seq);
1075                 }
1076         }
1077
1078         /* test for effects and overlap
1079          * don't use SEQP_BEGIN since that would be recursive */
1080         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1081                 if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
1082                         seq->flag &= ~SEQ_OVERLAP;
1083                         if (BKE_sequence_test_overlap(ed->seqbasep, seq) ) {
1084                                 BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1085                         }
1086                 }
1087                 else if (seq->type & SEQ_TYPE_EFFECT) {
1088                         if (seq->seq1 && (seq->seq1->flag & SELECT)) 
1089                                 BKE_sequence_calc(scene, seq);
1090                         else if (seq->seq2 && (seq->seq2->flag & SELECT)) 
1091                                 BKE_sequence_calc(scene, seq);
1092                         else if (seq->seq3 && (seq->seq3->flag & SELECT)) 
1093                                 BKE_sequence_calc(scene, seq);
1094                 }
1095         }
1096
1097         /* as last: */
1098         BKE_sequencer_sort(scene);
1099         
1100         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1101         
1102         return OPERATOR_FINISHED;
1103 }
1104
1105 static int sequencer_snap_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1106 {
1107         Scene *scene = CTX_data_scene(C);
1108         
1109         int snap_frame;
1110         
1111         snap_frame = CFRA;
1112         
1113         RNA_int_set(op->ptr, "frame", snap_frame);
1114         return sequencer_snap_exec(C, op);
1115 }
1116
1117 void SEQUENCER_OT_snap(struct wmOperatorType *ot)
1118 {
1119         /* identifiers */
1120         ot->name = "Snap strips";
1121         ot->idname = "SEQUENCER_OT_snap";
1122         ot->description = "Frame where selected strips will be snapped";
1123         
1124         /* api callbacks */
1125         ot->invoke = sequencer_snap_invoke;
1126         ot->exec = sequencer_snap_exec;
1127         ot->poll = sequencer_edit_poll;
1128         
1129         /* flags */
1130         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1131         
1132         RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX);
1133 }
1134
1135 /* mute operator */
1136 static int sequencer_mute_exec(bContext *C, wmOperator *op)
1137 {
1138         Scene *scene = CTX_data_scene(C);
1139         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1140         Sequence *seq;
1141         int selected;
1142
1143         selected = !RNA_boolean_get(op->ptr, "unselected");
1144         
1145         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1146                 if ((seq->flag & SEQ_LOCK) == 0) {
1147                         if (selected) { /* mute unselected */
1148                                 if (seq->flag & SELECT) {
1149                                         seq->flag |= SEQ_MUTE;
1150                                         BKE_sequence_invalidate_dependent(scene, seq);
1151                                 }
1152                         }
1153                         else {
1154                                 if ((seq->flag & SELECT) == 0) {
1155                                         seq->flag |= SEQ_MUTE;
1156                                         BKE_sequence_invalidate_dependent(scene, seq);
1157                                 }
1158                         }
1159                 }
1160         }
1161         
1162         BKE_sequencer_update_muting(ed);
1163         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1164         
1165         return OPERATOR_FINISHED;
1166 }
1167
1168 void SEQUENCER_OT_mute(struct wmOperatorType *ot)
1169 {
1170         /* identifiers */
1171         ot->name = "Mute Strips";
1172         ot->idname = "SEQUENCER_OT_mute";
1173         ot->description = "Mute selected strips";
1174         
1175         /* api callbacks */
1176         ot->exec = sequencer_mute_exec;
1177         ot->poll = sequencer_edit_poll;
1178         
1179         /* flags */
1180         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1181         
1182         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Mute unselected rather than selected strips");
1183 }
1184
1185
1186 /* unmute operator */
1187 static int sequencer_unmute_exec(bContext *C, wmOperator *op)
1188 {
1189         Scene *scene = CTX_data_scene(C);
1190         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1191         Sequence *seq;
1192         int selected;
1193
1194         selected = !RNA_boolean_get(op->ptr, "unselected");
1195         
1196         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1197                 if ((seq->flag & SEQ_LOCK) == 0) {
1198                         if (selected) { /* unmute unselected */
1199                                 if (seq->flag & SELECT) {
1200                                         seq->flag &= ~SEQ_MUTE;
1201                                         BKE_sequence_invalidate_dependent(scene, seq);
1202                                 }
1203                         }
1204                         else {
1205                                 if ((seq->flag & SELECT) == 0) {
1206                                         seq->flag &= ~SEQ_MUTE;
1207                                         BKE_sequence_invalidate_dependent(scene, seq);
1208                                 }
1209                         }
1210                 }
1211         }
1212         
1213         BKE_sequencer_update_muting(ed);
1214         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1215         
1216         return OPERATOR_FINISHED;
1217 }
1218
1219 void SEQUENCER_OT_unmute(struct wmOperatorType *ot)
1220 {
1221         /* identifiers */
1222         ot->name = "Un-Mute Strips";
1223         ot->idname = "SEQUENCER_OT_unmute";
1224         ot->description = "Un-Mute unselected rather than selected strips";
1225         
1226         /* api callbacks */
1227         ot->exec = sequencer_unmute_exec;
1228         ot->poll = sequencer_edit_poll;
1229         
1230         /* flags */
1231         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1232         
1233         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "UnMute unselected rather than selected strips");
1234 }
1235
1236
1237 /* lock operator */
1238 static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op))
1239 {
1240         Scene *scene = CTX_data_scene(C);
1241         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1242         Sequence *seq;
1243
1244         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1245                 if (seq->flag & SELECT) {
1246                         seq->flag |= SEQ_LOCK;
1247                 }
1248         }
1249
1250         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1251
1252         return OPERATOR_FINISHED;
1253 }
1254
1255 void SEQUENCER_OT_lock(struct wmOperatorType *ot)
1256 {
1257         /* identifiers */
1258         ot->name = "Lock Strips";
1259         ot->idname = "SEQUENCER_OT_lock";
1260         ot->description = "Lock the active strip so that it can't be transformed";
1261         
1262         /* api callbacks */
1263         ot->exec = sequencer_lock_exec;
1264         ot->poll = sequencer_edit_poll;
1265         
1266         /* flags */
1267         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1268 }
1269
1270 /* unlock operator */
1271 static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op))
1272 {
1273         Scene *scene = CTX_data_scene(C);
1274         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1275         Sequence *seq;
1276
1277         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1278                 if (seq->flag & SELECT) {
1279                         seq->flag &= ~SEQ_LOCK;
1280                 }
1281         }
1282
1283         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1284
1285         return OPERATOR_FINISHED;
1286 }
1287
1288 void SEQUENCER_OT_unlock(struct wmOperatorType *ot)
1289 {
1290         /* identifiers */
1291         ot->name = "UnLock Strips";
1292         ot->idname = "SEQUENCER_OT_unlock";
1293         ot->description = "Unlock the active strip so that it can't be transformed";
1294         
1295         /* api callbacks */
1296         ot->exec = sequencer_unlock_exec;
1297         ot->poll = sequencer_edit_poll;
1298         
1299         /* flags */
1300         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1301 }
1302
1303 /* reload operator */
1304 static int sequencer_reload_exec(bContext *C, wmOperator *op)
1305 {
1306         Scene *scene = CTX_data_scene(C);
1307         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1308         Sequence *seq;
1309         int adjust_length = RNA_boolean_get(op->ptr, "adjust_length");
1310
1311         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1312                 if (seq->flag & SELECT) {
1313                         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
1314                         BKE_sequence_reload_new_file(scene, seq, !adjust_length);
1315
1316                         if (adjust_length) {
1317                                 if (BKE_sequence_test_overlap(ed->seqbasep, seq))
1318                                         BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1319                         }
1320                 }
1321         }
1322
1323         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1324
1325         return OPERATOR_FINISHED;
1326 }
1327
1328 void SEQUENCER_OT_reload(struct wmOperatorType *ot)
1329 {
1330         PropertyRNA *prop;
1331
1332         /* identifiers */
1333         ot->name = "Reload Strips";
1334         ot->idname = "SEQUENCER_OT_reload";
1335         ot->description = "Reload strips in the sequencer";
1336         
1337         /* api callbacks */
1338         ot->exec = sequencer_reload_exec;
1339         ot->poll = sequencer_edit_poll;
1340         
1341         /* flags */
1342         ot->flag = OPTYPE_REGISTER; /* no undo, the data changed is stored outside 'main' */
1343
1344         prop = RNA_def_boolean(ot->srna, "adjust_length", 0, "Adjust Length",
1345                                "Adjust length of strips to their data length");
1346         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1347 }
1348
1349 /* reload operator */
1350 static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op))
1351 {
1352         Scene *scene = CTX_data_scene(C);
1353         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1354
1355         BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
1356
1357         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1358
1359         return OPERATOR_FINISHED;
1360 }
1361
1362 void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot)
1363 {
1364         /* identifiers */
1365         ot->name = "Refresh Sequencer";
1366         ot->idname = "SEQUENCER_OT_refresh_all";
1367         ot->description = "Refresh the sequencer editor";
1368         
1369         /* api callbacks */
1370         ot->exec = sequencer_refresh_all_exec;
1371         ot->poll = sequencer_edit_poll;
1372 }
1373
1374 static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
1375 {
1376         Scene *scene = CTX_data_scene(C);
1377         Sequence *seq1, *seq2, *seq3, *last_seq = BKE_sequencer_active_get(scene);
1378         const char *error_msg;
1379
1380         if (!seq_effect_find_selected(scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg)) {
1381                 BKE_report(op->reports, RPT_ERROR, error_msg);
1382                 return OPERATOR_CANCELLED;
1383         }
1384         /* see reassigning would create a cycle */
1385         if (seq_is_predecessor(seq1, last_seq) ||
1386             seq_is_predecessor(seq2, last_seq) ||
1387             seq_is_predecessor(seq3, last_seq))
1388         {
1389                 BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: no cycles allowed");
1390                 return OPERATOR_CANCELLED;
1391         }
1392
1393         last_seq->seq1 = seq1;
1394         last_seq->seq2 = seq2;
1395         last_seq->seq3 = seq3;
1396
1397         BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1);
1398
1399         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1400
1401         return OPERATOR_FINISHED;
1402 }
1403
1404 static int sequencer_effect_poll(bContext *C)
1405 {
1406         Scene *scene = CTX_data_scene(C);
1407         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1408
1409         if (ed) {
1410                 Sequence *last_seq = BKE_sequencer_active_get(scene);
1411                 if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) {
1412                         return 1;
1413                 }
1414         }
1415
1416         return 0;
1417 }
1418
1419 void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot)
1420 {
1421         /* identifiers */
1422         ot->name = "Reassign Inputs";
1423         ot->idname = "SEQUENCER_OT_reassign_inputs";
1424         ot->description = "Reassign the inputs for the effect strip";
1425
1426         /* api callbacks */
1427         ot->exec = sequencer_reassign_inputs_exec;
1428         ot->poll = sequencer_effect_poll;
1429
1430         /* flags */
1431         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1432 }
1433
1434
1435 static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op)
1436 {
1437         Scene *scene = CTX_data_scene(C);
1438         Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
1439
1440         if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) {
1441                 BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap");
1442                 return OPERATOR_CANCELLED;
1443         }
1444
1445         seq = last_seq->seq1;
1446         last_seq->seq1 = last_seq->seq2;
1447         last_seq->seq2 = seq;
1448
1449         BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1);
1450
1451         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1452
1453         return OPERATOR_FINISHED;
1454 }
1455 void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot)
1456 {
1457         /* identifiers */
1458         ot->name = "Swap Inputs";
1459         ot->idname = "SEQUENCER_OT_swap_inputs";
1460         ot->description = "Swap the first two inputs for the effect strip";
1461
1462         /* api callbacks */
1463         ot->exec = sequencer_swap_inputs_exec;
1464         ot->poll = sequencer_effect_poll;
1465
1466         /* flags */
1467         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1468 }
1469
1470
1471 /* cut operator */
1472 static EnumPropertyItem prop_cut_types[] = {
1473         {SEQ_CUT_SOFT, "SOFT", 0, "Soft", ""},
1474         {SEQ_CUT_HARD, "HARD", 0, "Hard", ""},
1475         {0, NULL, 0, NULL, NULL}
1476 };
1477
1478 static int sequencer_cut_exec(bContext *C, wmOperator *op)
1479 {
1480         Scene *scene = CTX_data_scene(C);
1481         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1482         int cut_side, cut_hard, cut_frame;
1483
1484         ListBase newlist;
1485         int changed;
1486
1487         cut_frame = RNA_int_get(op->ptr, "frame");
1488         cut_hard = RNA_enum_get(op->ptr, "type");
1489         cut_side = RNA_enum_get(op->ptr, "side");
1490         
1491         newlist.first = newlist.last = NULL;
1492
1493         if (cut_hard == SEQ_CUT_HARD) {
1494                 changed = cut_seq_list(scene, ed->seqbasep, &newlist, cut_frame, cut_seq_hard);
1495         }
1496         else {
1497                 changed = cut_seq_list(scene, ed->seqbasep, &newlist, cut_frame, cut_seq_soft);
1498         }
1499         
1500         if (newlist.first) { /* got new strips ? */
1501                 Sequence *seq;
1502                 BLI_movelisttolist(ed->seqbasep, &newlist);
1503
1504                 if (cut_side != SEQ_SIDE_BOTH) {
1505                         SEQP_BEGIN (ed, seq)
1506                         {
1507                                 if (cut_side == SEQ_SIDE_LEFT) {
1508                                         if (seq->startdisp >= cut_frame) {
1509                                                 seq->flag &= ~SEQ_ALLSEL;
1510                                         }
1511                                 }
1512                                 else {
1513                                         if (seq->enddisp <= cut_frame) {
1514                                                 seq->flag &= ~SEQ_ALLSEL;
1515                                         }
1516                                 }
1517                         }
1518                         SEQ_END;
1519                 }
1520                 /* as last: */
1521                 BKE_sequencer_sort(scene);
1522         }
1523
1524         if (changed) {
1525                 WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1526                 return OPERATOR_FINISHED;
1527         }
1528         else {
1529                 return OPERATOR_CANCELLED;
1530         }
1531 }
1532
1533
1534 static int sequencer_cut_invoke(bContext *C, wmOperator *op, wmEvent *event)
1535 {
1536         Scene *scene = CTX_data_scene(C);
1537         View2D *v2d = UI_view2d_fromcontext(C);
1538
1539         int cut_side = SEQ_SIDE_BOTH;
1540         int cut_frame = CFRA;
1541
1542         if (ED_operator_sequencer_active(C) && v2d)
1543                 cut_side = mouse_frame_side(v2d, event->mval[0], cut_frame);
1544         
1545         RNA_int_set(op->ptr, "frame", cut_frame);
1546         RNA_enum_set(op->ptr, "side", cut_side);
1547         /*RNA_enum_set(op->ptr, "type", cut_hard); */ /*This type is set from the key shortcut */
1548
1549         return sequencer_cut_exec(C, op);
1550 }
1551
1552
1553 void SEQUENCER_OT_cut(struct wmOperatorType *ot)
1554 {
1555         /* identifiers */
1556         ot->name = "Cut Strips";
1557         ot->idname = "SEQUENCER_OT_cut";
1558         ot->description = "Cut the selected strips";
1559         
1560         /* api callbacks */
1561         ot->invoke = sequencer_cut_invoke;
1562         ot->exec = sequencer_cut_exec;
1563         ot->poll = sequencer_edit_poll;
1564         
1565         /* flags */
1566         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1567         
1568         RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be cut", INT_MIN, INT_MAX);
1569         RNA_def_enum(ot->srna, "type", prop_cut_types, SEQ_CUT_SOFT, "Type", "The type of cut operation to perform on strips");
1570         RNA_def_enum(ot->srna, "side", prop_side_types, SEQ_SIDE_BOTH, "Side", "The side that remains selected after cutting");
1571 }
1572
1573 /* duplicate operator */
1574 static int apply_unique_name_cb(Sequence *seq, void *arg_pt)
1575 {
1576         Scene *scene = (Scene *)arg_pt;
1577         char name[sizeof(seq->name) - 2];
1578
1579         BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
1580         BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
1581         BKE_sequencer_dupe_animdata(scene, name, seq->name + 2);
1582         return 1;
1583
1584 }
1585
1586 static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
1587 {
1588         Scene *scene = CTX_data_scene(C);
1589         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1590
1591         ListBase nseqbase = {NULL, NULL};
1592
1593         if (ed == NULL)
1594                 return OPERATOR_CANCELLED;
1595
1596         BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT);
1597
1598         if (nseqbase.first) {
1599                 Sequence *seq = nseqbase.first;
1600                 /* rely on the nseqbase list being added at the end */
1601                 BLI_movelisttolist(ed->seqbasep, &nseqbase);
1602
1603                 for (; seq; seq = seq->next)
1604                         BKE_sequencer_recursive_apply(seq, apply_unique_name_cb, scene);
1605
1606                 WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1607                 return OPERATOR_FINISHED;
1608         }
1609
1610         return OPERATOR_CANCELLED;
1611 }
1612
1613 void SEQUENCER_OT_duplicate(wmOperatorType *ot)
1614 {
1615         /* identifiers */
1616         ot->name = "Duplicate Strips";
1617         ot->idname = "SEQUENCER_OT_duplicate";
1618         ot->description = "Duplicate the selected strips";
1619         
1620         /* api callbacks */
1621         ot->exec = sequencer_add_duplicate_exec;
1622         ot->poll = ED_operator_sequencer_active;
1623         
1624         /* flags */
1625         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1626         
1627         /* to give to transform */
1628         RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
1629 }
1630
1631 /* delete operator */
1632 static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
1633 {
1634         Scene *scene = CTX_data_scene(C);
1635         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1636         Sequence *seq;
1637         MetaStack *ms;
1638         int nothingSelected = TRUE;
1639
1640         seq = BKE_sequencer_active_get(scene);
1641         if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
1642                 nothingSelected = FALSE;
1643         }
1644         else {
1645                 for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1646                         if (seq->flag & SELECT) {
1647                                 nothingSelected = FALSE;
1648                                 break;
1649                         }
1650                 }
1651         }
1652
1653         if (nothingSelected)
1654                 return OPERATOR_FINISHED;
1655
1656         /* for effects, try to find a replacement input */
1657         for (seq = ed->seqbasep->first; seq; seq = seq->next)
1658                 if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SELECT))
1659                         del_seq_find_replace_recurs(scene, seq);
1660
1661         /* delete all selected strips */
1662         recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0);
1663
1664         /* updates lengths etc */
1665         seq = ed->seqbasep->first;
1666         while (seq) {
1667                 BKE_sequence_calc(scene, seq);
1668                 seq = seq->next;
1669         }
1670
1671         /* free parent metas */
1672         ms = ed->metastack.last;
1673         while (ms) {
1674                 BKE_sequence_calc(scene, ms->parseq);
1675                 ms = ms->prev;
1676         }
1677
1678         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1679         
1680         return OPERATOR_FINISHED;
1681 }
1682
1683 static int sequencer_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
1684 {
1685         ARegion *ar = CTX_wm_region(C);
1686
1687         if (ar->regiontype == RGN_TYPE_WINDOW) {
1688                 /* bounding box of 30 pixels is used for markers shortcuts,
1689                  * prevent conflict with markers shortcurts here
1690                  */
1691                 if (event->mval[1] <= 30)
1692                         return OPERATOR_PASS_THROUGH;
1693         }
1694
1695         return WM_operator_confirm(C, op, event);
1696 }
1697
1698 void SEQUENCER_OT_delete(wmOperatorType *ot)
1699 {
1700
1701         /* identifiers */
1702         ot->name = "Erase Strips";
1703         ot->idname = "SEQUENCER_OT_delete";
1704         ot->description = "Erase selected strips from the sequencer";
1705         
1706         /* api callbacks */
1707         ot->invoke = sequencer_delete_invoke;
1708         ot->exec = sequencer_delete_exec;
1709         ot->poll = sequencer_edit_poll;
1710         
1711         /* flags */
1712         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1713 }
1714
1715
1716 /* offset clear operator */
1717 static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
1718 {
1719         Scene *scene = CTX_data_scene(C);
1720         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1721         Sequence *seq;
1722
1723         /* for effects, try to find a replacement input */
1724         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1725                 if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
1726                         seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
1727                 }
1728         }
1729
1730         /* updates lengths etc */
1731         seq = ed->seqbasep->first;
1732         while (seq) {
1733                 BKE_sequence_calc(scene, seq);
1734                 seq = seq->next;
1735         }
1736
1737         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1738                 if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
1739                         if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
1740                                 BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1741                         }
1742                 }
1743         }
1744
1745         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1746
1747         return OPERATOR_FINISHED;
1748 }
1749
1750
1751 void SEQUENCER_OT_offset_clear(wmOperatorType *ot)
1752 {
1753
1754         /* identifiers */
1755         ot->name = "Clear Strip Offset";
1756         ot->idname = "SEQUENCER_OT_offset_clear";
1757         ot->description = "Clear strip offsets from the start and end frames";
1758
1759         /* api callbacks */
1760         ot->exec = sequencer_offset_clear_exec;
1761         ot->poll = sequencer_edit_poll;
1762
1763         /* flags */
1764         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1765 }
1766
1767
1768 /* separate_images operator */
1769 static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
1770 {
1771         Scene *scene = CTX_data_scene(C);
1772         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1773         
1774         Sequence *seq, *seq_new;
1775         Strip *strip_new;
1776         StripElem *se, *se_new;
1777         int start_ofs, cfra, frame_end;
1778         int step = RNA_int_get(op->ptr, "length");
1779
1780         seq = ed->seqbasep->first; /* poll checks this is valid */
1781
1782         while (seq) {
1783                 if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
1784                         /* remove seq so overlap tests don't conflict,
1785                          * see seq_free_sequence below for the real free'ing */
1786                         BLI_remlink(ed->seqbasep, seq);
1787                         /* if (seq->ipo) seq->ipo->id.us--; */
1788                         /* XXX, remove fcurve and assign to split image strips */
1789
1790                         start_ofs = cfra = BKE_sequence_tx_get_final_left(seq, 0);
1791                         frame_end = BKE_sequence_tx_get_final_right(seq, 0);
1792
1793                         while (cfra < frame_end) {
1794                                 /* new seq */
1795                                 se = BKE_sequencer_give_stripelem(seq, cfra);
1796
1797                                 seq_new = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME);
1798                                 BLI_addtail(ed->seqbasep, seq_new);
1799
1800                                 seq_new->start = start_ofs;
1801                                 seq_new->type = SEQ_TYPE_IMAGE;
1802                                 seq_new->len = 1;
1803                                 seq_new->endstill = step - 1;
1804
1805                                 /* new strip */
1806                                 strip_new = seq_new->strip;
1807                                 strip_new->us = 1;
1808
1809                                 /* new stripdata */
1810                                 se_new = strip_new->stripdata;
1811                                 BLI_strncpy(se_new->name, se->name, sizeof(se_new->name));
1812                                 BKE_sequence_calc(scene, seq_new);
1813
1814                                 if (step > 1) {
1815                                         seq_new->flag &= ~SEQ_OVERLAP;
1816                                         if (BKE_sequence_test_overlap(ed->seqbasep, seq_new)) {
1817                                                 BKE_sequence_base_shuffle(ed->seqbasep, seq_new, scene);
1818                                         }
1819                                 }
1820
1821                                 /* XXX, COPY FCURVES */
1822
1823                                 cfra++;
1824                                 start_ofs += step;
1825                         }
1826
1827                         BKE_sequence_free(scene, seq);
1828                         seq = seq->next;
1829                 }
1830                 else {
1831                         seq = seq->next;
1832                 }
1833         }
1834
1835         /* as last: */
1836         BKE_sequencer_sort(scene);
1837         
1838         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1839
1840         return OPERATOR_FINISHED;
1841 }
1842
1843
1844 void SEQUENCER_OT_images_separate(wmOperatorType *ot)
1845 {
1846         /* identifiers */
1847         ot->name = "Separate Images";
1848         ot->idname = "SEQUENCER_OT_images_separate";
1849         ot->description = "On image sequence strips, it returns a strip for each image";
1850         
1851         /* api callbacks */
1852         ot->exec = sequencer_separate_images_exec;
1853         ot->poll = sequencer_edit_poll;
1854         
1855         /* flags */
1856         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1857
1858         RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000);
1859 }
1860
1861
1862 /* META Operators */
1863
1864 /* separate_meta_toggle operator */
1865 static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1866 {
1867         Scene *scene = CTX_data_scene(C);
1868         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1869         Sequence *last_seq = BKE_sequencer_active_get(scene);
1870         MetaStack *ms;
1871
1872         if (last_seq && last_seq->type == SEQ_TYPE_META && last_seq->flag & SELECT) {
1873                 /* Enter Metastrip */
1874                 ms = MEM_mallocN(sizeof(MetaStack), "metastack");
1875                 BLI_addtail(&ed->metastack, ms);
1876                 ms->parseq = last_seq;
1877                 ms->oldbasep = ed->seqbasep;
1878
1879                 ed->seqbasep = &last_seq->seqbase;
1880
1881                 BKE_sequencer_active_set(scene, NULL);
1882
1883         }
1884         else {
1885                 /* Exit Metastrip (if possible) */
1886
1887                 Sequence *seq;
1888
1889                 if (ed->metastack.first == NULL)
1890                         return OPERATOR_CANCELLED;
1891
1892                 ms = ed->metastack.last;
1893                 BLI_remlink(&ed->metastack, ms);
1894
1895                 ed->seqbasep = ms->oldbasep;
1896
1897                 /* recalc all: the meta can have effects connected to it */
1898                 for (seq = ed->seqbasep->first; seq; seq = seq->next)
1899                         BKE_sequence_calc(scene, seq);
1900
1901                 BKE_sequencer_active_set(scene, ms->parseq);
1902
1903                 ms->parseq->flag |= SELECT;
1904                 recurs_sel_seq(ms->parseq);
1905
1906                 MEM_freeN(ms);
1907
1908         }
1909
1910         BKE_sequencer_update_muting(ed);
1911         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1912
1913         return OPERATOR_FINISHED;
1914 }
1915
1916 void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
1917 {
1918         /* identifiers */
1919         ot->name = "Toggle Meta Strip";
1920         ot->idname = "SEQUENCER_OT_meta_toggle";
1921         ot->description = "Toggle a metastrip (to edit enclosed strips)";
1922         
1923         /* api callbacks */
1924         ot->exec = sequencer_meta_toggle_exec;
1925         ot->poll = sequencer_edit_poll;
1926         
1927         /* flags */
1928         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1929 }
1930
1931
1932 /* separate_meta_make operator */
1933 static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
1934 {
1935         Scene *scene = CTX_data_scene(C);
1936         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
1937         
1938         Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene);
1939         int channel_max = 1;
1940
1941         if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == FALSE) {
1942                 BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
1943                 return OPERATOR_CANCELLED;
1944         }
1945
1946         /* remove all selected from main list, and put in meta */
1947
1948         seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1); /* channel number set later */
1949         strcpy(seqm->name + 2, "MetaStrip");
1950         seqm->type = SEQ_TYPE_META;
1951         seqm->flag = SELECT;
1952
1953         seq = ed->seqbasep->first;
1954         while (seq) {
1955                 next = seq->next;
1956                 if (seq != seqm && (seq->flag & SELECT)) {
1957                         channel_max = max_ii(seq->machine, channel_max);
1958                         BLI_remlink(ed->seqbasep, seq);
1959                         BLI_addtail(&seqm->seqbase, seq);
1960                 }
1961                 seq = next;
1962         }
1963         seqm->machine = last_seq ? last_seq->machine : channel_max;
1964         BKE_sequence_calc(scene, seqm);
1965
1966         seqm->strip = MEM_callocN(sizeof(Strip), "metastrip");
1967         seqm->strip->us = 1;
1968         
1969         BKE_sequencer_active_set(scene, seqm);
1970
1971         if (BKE_sequence_test_overlap(ed->seqbasep, seqm) ) BKE_sequence_base_shuffle(ed->seqbasep, seqm, scene);
1972
1973         BKE_sequencer_update_muting(ed);
1974
1975         BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm);
1976
1977         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1978
1979         return OPERATOR_FINISHED;
1980 }
1981
1982 void SEQUENCER_OT_meta_make(wmOperatorType *ot)
1983 {
1984         /* identifiers */
1985         ot->name = "Make Meta Strip";
1986         ot->idname = "SEQUENCER_OT_meta_make";
1987         ot->description = "Group selected strips into a metastrip";
1988         
1989         /* api callbacks */
1990         ot->invoke = WM_operator_confirm;
1991         ot->exec = sequencer_meta_make_exec;
1992         ot->poll = sequencer_edit_poll;
1993         
1994         /* flags */
1995         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1996 }
1997
1998
1999 static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
2000 {
2001         if (seq == seqm) return 1;
2002         else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
2003         else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
2004         else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
2005         else return 0;
2006 }
2007
2008 /* separate_meta_make operator */
2009 static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
2010 {
2011         Scene *scene = CTX_data_scene(C);
2012         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2013
2014         Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); /* last_seq checks (ed == NULL) */
2015
2016         if (last_seq == NULL || last_seq->type != SEQ_TYPE_META)
2017                 return OPERATOR_CANCELLED;
2018
2019         BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase);
2020
2021         last_seq->seqbase.first = NULL;
2022         last_seq->seqbase.last = NULL;
2023
2024         BLI_remlink(ed->seqbasep, last_seq);
2025         BKE_sequence_free(scene, last_seq);
2026
2027         /* emtpy meta strip, delete all effects depending on it */
2028         for (seq = ed->seqbasep->first; seq; seq = seq->next)
2029                 if ((seq->type & SEQ_TYPE_EFFECT) && seq_depends_on_meta(seq, last_seq))
2030                         seq->flag |= SEQ_FLAG_DELETE;
2031
2032         recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0);
2033
2034         /* test for effects and overlap
2035          * don't use SEQP_BEGIN since that would be recursive */
2036         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2037                 if (seq->flag & SELECT) {
2038                         seq->flag &= ~SEQ_OVERLAP;
2039                         if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
2040                                 BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
2041                         }
2042                 }
2043         }
2044
2045         BKE_sequencer_sort(scene);
2046         BKE_sequencer_update_muting(ed);
2047
2048         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2049
2050         return OPERATOR_FINISHED;
2051 }
2052
2053 void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
2054 {
2055         /* identifiers */
2056         ot->name = "UnMeta Strip";
2057         ot->idname = "SEQUENCER_OT_meta_separate";
2058         ot->description = "Put the contents of a metastrip back in the sequencer";
2059         
2060         /* api callbacks */
2061         ot->invoke = WM_operator_confirm;
2062         ot->exec = sequencer_meta_separate_exec;
2063         ot->poll = sequencer_edit_poll;
2064         
2065         /* flags */
2066         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2067 }
2068
2069 /* view_all operator */
2070 static int sequencer_view_all_exec(bContext *C, wmOperator *UNUSED(op))
2071 {
2072         ARegion *ar = CTX_wm_region(C);
2073         View2D *v2d = UI_view2d_fromcontext(C);
2074
2075         UI_view2d_smooth_view(C, ar, &v2d->tot);
2076         return OPERATOR_FINISHED;
2077 }
2078
2079 void SEQUENCER_OT_view_all(wmOperatorType *ot)
2080 {
2081         /* identifiers */
2082         ot->name = "View All";
2083         ot->idname = "SEQUENCER_OT_view_all";
2084         ot->description = "View all the strips in the sequencer";
2085         
2086         /* api callbacks */
2087         ot->exec = sequencer_view_all_exec;
2088         ot->poll = ED_operator_sequencer_active;
2089         
2090         /* flags */
2091         ot->flag = OPTYPE_REGISTER;
2092 }
2093
2094 /* view_all operator */
2095 static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op))
2096 {
2097         bScreen *sc = CTX_wm_screen(C);
2098         ScrArea *area = CTX_wm_area(C);
2099 #if 0
2100         ARegion *ar = CTX_wm_region(C);
2101         SpaceSeq *sseq = area->spacedata.first;
2102         Scene *scene = CTX_data_scene(C);
2103 #endif
2104         View2D *v2d = UI_view2d_fromcontext(C);
2105
2106         v2d->cur = v2d->tot;
2107         UI_view2d_curRect_validate(v2d);
2108         UI_view2d_sync(sc, area, v2d, V2D_LOCK_COPY);
2109         
2110 #if 0
2111         /* Like zooming on an image view */
2112         float zoomX, zoomY;
2113         int width, height, imgwidth, imgheight;
2114
2115         width = ar->winx;
2116         height = ar->winy;
2117
2118         seq_reset_imageofs(sseq);
2119
2120         imgwidth = (scene->r.size * scene->r.xsch) / 100;
2121         imgheight = (scene->r.size * scene->r.ysch) / 100;
2122
2123         /* Apply aspect, dosnt need to be that accurate */
2124         imgwidth = (int)(imgwidth * (scene->r.xasp / scene->r.yasp));
2125
2126         if (((imgwidth >= width) || (imgheight >= height)) &&
2127             ((width > 0) && (height > 0)))
2128         {
2129                 /* Find the zoom value that will fit the image in the image space */
2130                 zoomX = ((float)width) / ((float)imgwidth);
2131                 zoomY = ((float)height) / ((float)imgheight);
2132                 sseq->zoom = (zoomX < zoomY) ? zoomX : zoomY;
2133
2134                 sseq->zoom = 1.0f / power_of_2(1 / min_ff(zoomX, zoomY));
2135         }
2136         else {
2137                 sseq->zoom = 1.0f;
2138         }
2139 #endif
2140
2141         ED_area_tag_redraw(CTX_wm_area(C));
2142         return OPERATOR_FINISHED;
2143 }
2144
2145 void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
2146 {
2147         /* identifiers */
2148         ot->name = "View All";
2149         ot->idname = "SEQUENCER_OT_view_all_preview";
2150         ot->description = "Zoom preview to fit in the area";
2151         
2152         /* api callbacks */
2153         ot->exec = sequencer_view_all_preview_exec;
2154         ot->poll = ED_operator_sequencer_active;
2155         
2156         /* flags */
2157         ot->flag = OPTYPE_REGISTER;
2158 }
2159
2160
2161 static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
2162 {
2163         RenderData *rd = &CTX_data_scene(C)->r;
2164         View2D *v2d = UI_view2d_fromcontext(C);
2165
2166         float ratio = RNA_float_get(op->ptr, "ratio");
2167
2168         float winx = (int)(rd->size * rd->xsch) / 100;
2169         float winy = (int)(rd->size * rd->ysch) / 100;
2170
2171         float facx = BLI_rcti_size_x(&v2d->mask) / winx;
2172         float facy = BLI_rcti_size_y(&v2d->mask) / winy;
2173
2174         BLI_rctf_resize(&v2d->cur, (int)(winx * facx * ratio) + 1, (int)(winy * facy * ratio) + 1);
2175
2176         ED_region_tag_redraw(CTX_wm_region(C));
2177
2178         return OPERATOR_FINISHED;
2179 }
2180
2181 void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
2182 {
2183         /* identifiers */
2184         ot->name = "Sequencer View Zoom Ratio";
2185         ot->idname = "SEQUENCER_OT_view_zoom_ratio";
2186         ot->description = "Change zoom ratio of sequencer preview";
2187
2188         /* api callbacks */
2189         ot->exec = sequencer_view_zoom_ratio_exec;
2190         ot->poll = ED_operator_sequencer_active;
2191
2192         /* properties */
2193         RNA_def_float(ot->srna, "ratio", 1.0f, -FLT_MAX, FLT_MAX,
2194                       "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
2195 }
2196
2197
2198 #if 0
2199 static EnumPropertyItem view_type_items[] = {
2200         {SEQ_VIEW_SEQUENCE, "SEQUENCER", ICON_SEQ_SEQUENCER, "Sequencer", ""},
2201         {SEQ_VIEW_PREVIEW,  "PREVIEW", ICON_SEQ_PREVIEW, "Image Preview", ""},
2202         {SEQ_VIEW_SEQUENCE_PREVIEW,  "SEQUENCER_PREVIEW", ICON_SEQ_SEQUENCER, "Sequencer and Image Preview", ""},
2203         {0, NULL, 0, NULL, NULL}
2204 };
2205 #endif
2206
2207 /* view_all operator */
2208 static int sequencer_view_toggle_exec(bContext *C, wmOperator *UNUSED(op))
2209 {
2210         SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C);
2211
2212         sseq->view++;
2213         if (sseq->view > SEQ_VIEW_SEQUENCE_PREVIEW) sseq->view = SEQ_VIEW_SEQUENCE;
2214
2215         ED_area_tag_refresh(CTX_wm_area(C));
2216
2217         return OPERATOR_FINISHED;
2218 }
2219
2220 void SEQUENCER_OT_view_toggle(wmOperatorType *ot)
2221 {
2222         /* identifiers */
2223         ot->name = "View Toggle";
2224         ot->idname = "SEQUENCER_OT_view_toggle";
2225         ot->description = "Toggle between sequencer views (sequence, preview, both)";
2226         
2227         /* api callbacks */
2228         ot->exec = sequencer_view_toggle_exec;
2229         ot->poll = ED_operator_sequencer_active;
2230         
2231         /* flags */
2232         ot->flag = OPTYPE_REGISTER;
2233 }
2234
2235
2236 /* view_selected operator */
2237 static int sequencer_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
2238 {
2239         Scene *scene = CTX_data_scene(C);
2240         View2D *v2d = UI_view2d_fromcontext(C);
2241         ARegion *ar = CTX_wm_region(C);
2242         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2243         Sequence *seq;
2244         rctf cur_new = v2d->cur;
2245
2246         int xmin =  MAXFRAME * 2;
2247         int xmax = -MAXFRAME * 2;
2248         int ymin =  MAXSEQ + 1;
2249         int ymax = 0;
2250         int orig_height;
2251         int ymid;
2252         int ymargin = 1;
2253         int xmargin = FPS;
2254
2255         if (ed == NULL)
2256                 return OPERATOR_CANCELLED;
2257
2258         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2259                 if (seq->flag & SELECT) {
2260                         xmin = min_ii(xmin, seq->startdisp);
2261                         xmax = max_ii(xmax, seq->enddisp);
2262
2263                         ymin = min_ii(ymin, seq->machine);
2264                         ymax = max_ii(ymax, seq->machine);
2265                 }
2266         }
2267
2268         if (ymax != 0) {
2269                 
2270                 xmax += xmargin;
2271                 xmin -= xmargin;
2272                 ymax += ymargin;
2273                 ymin -= ymargin;
2274
2275                 orig_height = BLI_rctf_size_y(&cur_new);
2276
2277                 cur_new.xmin = xmin;
2278                 cur_new.xmax = xmax;
2279
2280                 cur_new.ymin = ymin;
2281                 cur_new.ymax = ymax;
2282
2283                 /* only zoom out vertically */
2284                 if (orig_height > BLI_rctf_size_y(&cur_new)) {
2285                         ymid = BLI_rctf_cent_y(&cur_new);
2286
2287                         cur_new.ymin = ymid - (orig_height / 2);
2288                         cur_new.ymax = ymid + (orig_height / 2);
2289                 }
2290
2291                 UI_view2d_smooth_view(C, ar, &cur_new);
2292
2293                 return OPERATOR_FINISHED;
2294         }
2295         else {
2296                 return OPERATOR_CANCELLED;
2297         }
2298         
2299 }
2300
2301 void SEQUENCER_OT_view_selected(wmOperatorType *ot)
2302 {
2303         /* identifiers */
2304         ot->name = "View Selected";
2305         ot->idname = "SEQUENCER_OT_view_selected";
2306         ot->description = "Zoom the sequencer on the selected strips";
2307         
2308         /* api callbacks */
2309         ot->exec = sequencer_view_selected_exec;
2310         ot->poll = ED_operator_sequencer_active;
2311         
2312         /* flags */
2313         ot->flag = OPTYPE_REGISTER;
2314 }
2315
2316
2317 static int find_next_prev_edit(Scene *scene, int cfra,
2318                                const short side,
2319                                const short do_skip_mute, const short do_center)
2320 {
2321         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2322         Sequence *seq, *best_seq = NULL, *frame_seq = NULL;
2323         
2324         int dist, best_dist;
2325         best_dist = MAXFRAME * 2;
2326
2327         if (ed == NULL) return cfra;
2328         
2329         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2330                 int seq_frame;
2331
2332                 if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
2333                         continue;
2334                 }
2335
2336                 if (do_center) {
2337                         seq_frame = (seq->startdisp + seq->enddisp) / 2;
2338                 }
2339                 else {
2340                         seq_frame = seq->startdisp;
2341                 }
2342
2343                 dist = MAXFRAME * 2;
2344                         
2345                 switch (side) {
2346                         case SEQ_SIDE_LEFT:
2347                                 if (seq_frame < cfra) {
2348                                         dist = cfra - seq_frame;
2349                                 }
2350                                 break;
2351                         case SEQ_SIDE_RIGHT:
2352                                 if (seq_frame > cfra) {
2353                                         dist = seq_frame - cfra;
2354                                 }
2355                                 else if (seq_frame == cfra) {
2356                                         frame_seq = seq;
2357                                 }
2358                                 break;
2359                 }
2360
2361                 if (dist < best_dist) {
2362                         best_dist = dist;
2363                         best_seq = seq;
2364                 }
2365         }
2366
2367         /* if no sequence to the right is found and the
2368          * frame is on the start of the last sequence,
2369          * move to the end of the last sequence */
2370         if (frame_seq) {
2371                 if (do_center) {
2372                         cfra = (frame_seq->startdisp + frame_seq->enddisp) / 2;
2373                 }
2374                 else {
2375                         cfra = frame_seq->enddisp;
2376                 }
2377         }
2378
2379         if (best_seq) {
2380                 if (do_center) {
2381                         cfra = (best_seq->startdisp + best_seq->enddisp) / 2;
2382                 }
2383                 else {
2384                         cfra = best_seq->startdisp;
2385                 }
2386         }
2387
2388         return cfra;
2389 }
2390
2391 static int strip_jump_internal(Scene *scene,
2392                                const short side,
2393                                const short do_skip_mute, const short do_center)
2394 {
2395         int change = FALSE;
2396         int cfra = CFRA;
2397         int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center);
2398         
2399         if (nfra != cfra) {
2400                 CFRA = nfra;
2401                 change = TRUE;
2402         }
2403
2404         return change;
2405 }
2406
2407 /* jump frame to edit point operator */
2408 static int sequencer_strip_jump_exec(bContext *C, wmOperator *op)
2409 {
2410         Scene *scene = CTX_data_scene(C);
2411         short next = RNA_boolean_get(op->ptr, "next");
2412         short center = RNA_boolean_get(op->ptr, "center");
2413
2414         /* currently do_skip_mute is always TRUE */
2415         if (!strip_jump_internal(scene, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, TRUE, center)) {
2416                 return OPERATOR_CANCELLED;
2417         }
2418
2419         WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
2420         
2421         return OPERATOR_FINISHED;
2422 }
2423
2424 void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
2425 {
2426         /* identifiers */
2427         ot->name = "Jump to Strip";
2428         ot->idname = "SEQUENCER_OT_strip_jump";
2429         ot->description = "Move frame to previous edit point";
2430
2431         /* api callbacks */
2432         ot->exec = sequencer_strip_jump_exec;
2433         ot->poll = sequencer_edit_poll;
2434
2435         /* flags */
2436         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2437         
2438         /* properties */
2439         RNA_def_boolean(ot->srna, "next", TRUE, "Next Strip", "");
2440         RNA_def_boolean(ot->srna, "center", TRUE, "Use strip center", "");
2441 }
2442
2443 static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
2444 {
2445         int gap = seqb->startdisp - seqa->enddisp;
2446         seqb->start = (seqb->start - seqb->startdisp) + seqa->startdisp;
2447         BKE_sequence_calc(scene, seqb);
2448         seqa->start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
2449         BKE_sequence_calc(scene, seqa);
2450 }
2451
2452 #if 0
2453 static Sequence *sequence_find_parent(Scene *scene, Sequence *child)
2454 {
2455         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2456         Sequence *parent = NULL;
2457         Sequence *seq;
2458
2459         if (ed == NULL) return NULL;
2460
2461         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2462                 if ((seq != child) && seq_is_parent(seq, child)) {
2463                         parent = seq;
2464                         break;
2465                 }
2466         }
2467
2468         return parent;
2469 }
2470 #endif
2471
2472 static int sequencer_swap_exec(bContext *C, wmOperator *op)
2473 {
2474         Scene *scene = CTX_data_scene(C);
2475         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2476         Sequence *active_seq = BKE_sequencer_active_get(scene);
2477         Sequence *seq, *iseq;
2478         int side = RNA_enum_get(op->ptr, "side");
2479
2480         if (active_seq == NULL) return OPERATOR_CANCELLED;
2481
2482         seq = find_next_prev_sequence(scene, active_seq, side, -1);
2483         
2484         if (seq) {
2485                 
2486                 /* disallow effect strips */
2487                 if (BKE_sequence_effect_get_num_inputs(seq->type) >= 1 && (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3))
2488                         return OPERATOR_CANCELLED;
2489                 if ((BKE_sequence_effect_get_num_inputs(active_seq->type) >= 1) && (active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3))
2490                         return OPERATOR_CANCELLED;
2491
2492                 switch (side) {
2493                         case SEQ_SIDE_LEFT: 
2494                                 swap_sequence(scene, seq, active_seq);
2495                                 break;
2496                         case SEQ_SIDE_RIGHT: 
2497                                 swap_sequence(scene, active_seq, seq);
2498                                 break;
2499                 }
2500
2501                 // XXX - should be a generic function
2502                 for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
2503                         if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
2504                                 BKE_sequence_calc(scene, iseq);
2505                         }
2506                 }
2507
2508                 /* do this in a new loop since both effects need to be calculated first */
2509                 for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
2510                         if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
2511                                 /* this may now overlap */
2512                                 if (BKE_sequence_test_overlap(ed->seqbasep, iseq) ) {
2513                                         BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene);
2514                                 }
2515                         }
2516                 }
2517
2518
2519
2520                 BKE_sequencer_sort(scene);
2521
2522                 WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2523
2524                 return OPERATOR_FINISHED;
2525         }
2526
2527         return OPERATOR_CANCELLED;
2528 }
2529
2530 void SEQUENCER_OT_swap(wmOperatorType *ot)
2531 {
2532         /* identifiers */
2533         ot->name = "Swap Strip";
2534         ot->idname = "SEQUENCER_OT_swap";
2535         ot->description = "Swap active strip with strip to the right or left";
2536         
2537         /* api callbacks */
2538         ot->exec = sequencer_swap_exec;
2539         ot->poll = sequencer_edit_poll;
2540         
2541         /* flags */
2542         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2543         
2544         /* properties */
2545         RNA_def_enum(ot->srna, "side", prop_side_lr_types, SEQ_SIDE_RIGHT, "Side", "Side of the strip to swap");
2546 }
2547
2548 static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op))
2549 {
2550         int retval = OPERATOR_CANCELLED;
2551         Scene *scene = CTX_data_scene(C);
2552         Sequence *active_seq = BKE_sequencer_active_get(scene);
2553         StripElem *se = NULL;
2554
2555         if (active_seq == NULL)
2556                 return OPERATOR_CANCELLED;
2557
2558
2559         if (active_seq->strip) {
2560                 switch (active_seq->type) {
2561                         case SEQ_TYPE_IMAGE:
2562                                 se = BKE_sequencer_give_stripelem(active_seq, scene->r.cfra);
2563                                 break;
2564                         case SEQ_TYPE_MOVIE:
2565                                 se = active_seq->strip->stripdata;
2566                                 break;
2567                         case SEQ_TYPE_SCENE:
2568                         case SEQ_TYPE_META:
2569                         case SEQ_TYPE_SOUND_RAM:
2570                         case SEQ_TYPE_SOUND_HD:
2571                         default:
2572                                 break;
2573                 }
2574         }
2575
2576         if (se) {
2577                 // prevent setting the render size if sequence values aren't initialized
2578                 if ((se->orig_width > 0) && (se->orig_height > 0)) {
2579                         scene->r.xsch = se->orig_width;
2580                         scene->r.ysch = se->orig_height;
2581                         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
2582                         retval = OPERATOR_FINISHED;
2583                 }
2584         }
2585
2586         return retval;
2587 }
2588
2589 void SEQUENCER_OT_rendersize(wmOperatorType *ot)
2590 {
2591         /* identifiers */
2592         ot->name = "Set Render Size";
2593         ot->idname = "SEQUENCER_OT_rendersize";
2594         ot->description = "Set render size and aspect from active sequence";
2595         
2596         /* api callbacks */
2597         ot->exec = sequencer_rendersize_exec;
2598         ot->poll = sequencer_edit_poll;
2599         
2600         /* flags */
2601         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2602         
2603         /* properties */
2604 }
2605
2606 static void seq_copy_del_sound(Scene *scene, Sequence *seq)
2607 {
2608         if (seq->type == SEQ_TYPE_META) {
2609                 Sequence *iseq;
2610                 for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) {
2611                         seq_copy_del_sound(scene, iseq);
2612                 }
2613         }
2614         else if (seq->scene_sound) {
2615                 sound_remove_scene_sound(scene, seq->scene_sound);
2616                 seq->scene_sound = NULL;
2617         }
2618 }
2619
2620 /* TODO, validate scenes */
2621 static int sequencer_copy_exec(bContext *C, wmOperator *op)
2622 {
2623         Scene *scene = CTX_data_scene(C);
2624         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2625
2626         ListBase nseqbase = {NULL, NULL};
2627
2628         BKE_sequencer_free_clipboard();
2629
2630         if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == FALSE) {
2631                 BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
2632                 return OPERATOR_CANCELLED;
2633         }
2634
2635         BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME);
2636
2637         /* To make sure the copied strips have unique names between each other add
2638          * them temporarily to the end of the original seqbase. (bug 25932)
2639          */
2640         if (nseqbase.first) {
2641                 Sequence *seq, *first_seq = nseqbase.first;
2642                 BLI_movelisttolist(ed->seqbasep, &nseqbase);
2643
2644                 for (seq = first_seq; seq; seq = seq->next)
2645                         BKE_sequencer_recursive_apply(seq, apply_unique_name_cb, scene);
2646
2647                 seqbase_clipboard.first = first_seq;
2648                 seqbase_clipboard.last = ed->seqbasep->last;
2649
2650                 if (first_seq->prev) {
2651                         first_seq->prev->next = NULL;
2652                         ed->seqbasep->last = first_seq->prev;
2653                         first_seq->prev = NULL;
2654                 }
2655         }
2656
2657         seqbase_clipboard_frame = scene->r.cfra;
2658
2659         /* Need to remove anything that references the current scene */
2660         {
2661                 Sequence *seq;
2662                 for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
2663                         seq_copy_del_sound(scene, seq);
2664                 }
2665         }
2666
2667         return OPERATOR_FINISHED;
2668 }
2669
2670 void SEQUENCER_OT_copy(wmOperatorType *ot)
2671 {
2672         /* identifiers */
2673         ot->name = "Copy";
2674         ot->idname = "SEQUENCER_OT_copy";
2675         ot->description = "";
2676
2677         /* api callbacks */
2678         ot->exec = sequencer_copy_exec;
2679         ot->poll = sequencer_edit_poll;
2680
2681         /* flags */
2682         ot->flag = OPTYPE_REGISTER;
2683
2684         /* properties */
2685 }
2686
2687 static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
2688 {
2689         Scene *scene = CTX_data_scene(C);
2690         Editing *ed = BKE_sequencer_editing_get(scene, TRUE); /* create if needed */
2691         ListBase nseqbase = {NULL, NULL};
2692         int ofs;
2693         Sequence *iseq;
2694
2695         ED_sequencer_deselect_all(scene);
2696         ofs = scene->r.cfra - seqbase_clipboard_frame;
2697
2698         BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME);
2699
2700         /* transform pasted strips before adding */
2701         if (ofs) {
2702                 for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
2703                         BKE_sequence_translate(scene, iseq, ofs);
2704                         BKE_sequence_sound_init(scene, iseq);
2705                 }
2706         }
2707
2708         iseq = nseqbase.first;
2709
2710         BLI_movelisttolist(ed->seqbasep, &nseqbase);
2711
2712         /* make sure the pasted strips have unique names between them */
2713         for (; iseq; iseq = iseq->next) {
2714                 BKE_sequencer_recursive_apply(iseq, apply_unique_name_cb, scene);
2715         }
2716
2717         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2718
2719         return OPERATOR_FINISHED;
2720 }
2721
2722 void SEQUENCER_OT_paste(wmOperatorType *ot)
2723 {
2724         /* identifiers */
2725         ot->name = "Paste";
2726         ot->idname = "SEQUENCER_OT_paste";
2727         ot->description = "";
2728
2729         /* api callbacks */
2730         ot->exec = sequencer_paste_exec;
2731         ot->poll = ED_operator_sequencer_active;
2732
2733         /* flags */
2734         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2735
2736         /* properties */
2737 }
2738
2739 static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
2740 {
2741         Scene *scene = CTX_data_scene(C);
2742         Sequence *seq_act;
2743         Sequence *seq_other;
2744         const char *error_msg;
2745
2746         if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) {
2747                 BKE_report(op->reports, RPT_ERROR, "Please select two strips");
2748                 return OPERATOR_CANCELLED;
2749         }
2750
2751         if (BKE_sequence_swap(seq_act, seq_other, &error_msg) == 0) {
2752                 BKE_report(op->reports, RPT_ERROR, error_msg);
2753                 return OPERATOR_CANCELLED;
2754         }
2755
2756         if (seq_act->scene_sound)
2757                 sound_remove_scene_sound(scene, seq_act->scene_sound);
2758
2759         if (seq_other->scene_sound)
2760                 sound_remove_scene_sound(scene, seq_other->scene_sound);
2761
2762         seq_act->scene_sound = NULL;
2763         seq_other->scene_sound = NULL;
2764
2765         BKE_sequence_calc(scene, seq_act);
2766         BKE_sequence_calc(scene, seq_other);
2767
2768         if (seq_act->sound) sound_add_scene_sound_defaults(scene, seq_act);
2769         if (seq_other->sound) sound_add_scene_sound_defaults(scene, seq_other);
2770
2771         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2772
2773         return OPERATOR_FINISHED;
2774 }
2775
2776 void SEQUENCER_OT_swap_data(wmOperatorType *ot)
2777 {
2778         /* identifiers */
2779         ot->name = "Sequencer Swap Data";
2780         ot->idname = "SEQUENCER_OT_swap_data";
2781         ot->description = "Swap 2 sequencer strips";
2782
2783         /* api callbacks */
2784         ot->exec = sequencer_swap_data_exec;
2785         ot->poll = ED_operator_sequencer_active;
2786
2787         /* flags */
2788         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2789
2790         /* properties */
2791 }
2792
2793 /* borderselect operator */
2794 static int view_ghost_border_exec(bContext *C, wmOperator *op)
2795 {
2796         Scene *scene = CTX_data_scene(C);
2797         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2798         View2D *v2d = UI_view2d_fromcontext(C);
2799
2800         rctf rect;
2801
2802         /* convert coordinates of rect to 'tot' rect coordinates */
2803         UI_view2d_region_to_view(v2d, RNA_int_get(op->ptr, "xmin"), RNA_int_get(op->ptr, "ymin"), &rect.xmin, &rect.ymin);
2804         UI_view2d_region_to_view(v2d, RNA_int_get(op->ptr, "xmax"), RNA_int_get(op->ptr, "ymax"), &rect.xmax, &rect.ymax);
2805
2806         if (ed == NULL)
2807                 return OPERATOR_CANCELLED;
2808
2809         rect.xmin /=  fabsf(BLI_rctf_size_x(&v2d->tot));
2810         rect.ymin /=  fabsf(BLI_rctf_size_y(&v2d->tot));
2811
2812         rect.xmax /=  fabsf(BLI_rctf_size_x(&v2d->tot));
2813         rect.ymax /=  fabsf(BLI_rctf_size_y(&v2d->tot));
2814
2815         rect.xmin += 0.5f;
2816         rect.xmax += 0.5f;
2817         rect.ymin += 0.5f;
2818         rect.ymax += 0.5f;
2819
2820         CLAMP(rect.xmin, 0.0f, 1.0f);
2821         CLAMP(rect.ymin, 0.0f, 1.0f);
2822         CLAMP(rect.xmax, 0.0f, 1.0f);
2823         CLAMP(rect.ymax, 0.0f, 1.0f);
2824
2825         scene->ed->over_border = rect;
2826
2827         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2828
2829         return OPERATOR_FINISHED;
2830 }
2831
2832 /* ****** Border Select ****** */
2833 void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
2834 {
2835         /* identifiers */
2836         ot->name = "Border Offset View";
2837         ot->idname = "SEQUENCER_OT_view_ghost_border";
2838         ot->description = "Enable border select mode";
2839
2840         /* api callbacks */
2841         ot->invoke = WM_border_select_invoke;
2842         ot->exec = view_ghost_border_exec;
2843         ot->modal = WM_border_select_modal;
2844         ot->poll = sequencer_view_poll;
2845         ot->cancel = WM_border_select_cancel;
2846
2847         /* flags */
2848         ot->flag = 0;
2849
2850         /* rna */
2851         WM_operator_properties_gesture_border(ot, FALSE);
2852 }
2853
2854 /* rebuild_proxy operator */
2855 static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
2856 {
2857         seq_proxy_build_job(C);
2858
2859         return OPERATOR_FINISHED;
2860 }
2861
2862 void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot)
2863 {
2864         /* identifiers */
2865         ot->name = "Rebuild Proxy and Timecode Indices";
2866         ot->idname = "SEQUENCER_OT_rebuild_proxy";
2867         ot->description = "Rebuild all selected proxies and timecode indices using the job system";
2868         
2869         /* api callbacks */
2870         ot->exec = sequencer_rebuild_proxy_exec;
2871         ot->poll = ED_operator_sequencer_active;
2872         
2873         /* flags */
2874         ot->flag = OPTYPE_REGISTER;
2875 }
2876
2877 /* change ops */
2878
2879 static EnumPropertyItem prop_change_effect_input_types[] = {
2880         {0, "A_B", 0, "A -> B", ""},
2881         {1, "B_C", 0, "B -> C", ""},
2882         {2, "A_C", 0, "A -> C", ""},
2883         {0, NULL, 0, NULL, NULL}
2884 };
2885
2886 static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op)
2887 {
2888         Scene *scene = CTX_data_scene(C);
2889         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2890         Sequence *seq = BKE_sequencer_active_get(scene);
2891
2892         Sequence **seq_1, **seq_2;
2893
2894         switch (RNA_enum_get(op->ptr, "swap")) {
2895                 case 0:
2896                         seq_1 = &seq->seq1;
2897                         seq_2 = &seq->seq2;
2898                         break;
2899                 case 1:
2900                         seq_1 = &seq->seq2;
2901                         seq_2 = &seq->seq3;
2902                         break;
2903                 default: /* 2 */
2904                         seq_1 = &seq->seq1;
2905                         seq_2 = &seq->seq3;
2906                         break;
2907         }
2908
2909         if (*seq_1 == NULL || *seq_2 == NULL) {
2910                 BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, cannot swap");
2911                 return OPERATOR_CANCELLED;
2912         }
2913         else {
2914                 SWAP(Sequence *, *seq_1, *seq_2);
2915         }
2916
2917         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
2918
2919         /* important else we don't get the imbuf cache flushed */
2920         BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
2921
2922         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2923
2924         return OPERATOR_FINISHED;
2925 }
2926
2927 void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot)
2928 {
2929         /* identifiers */
2930         ot->name = "Change Effect Input";
2931         ot->idname = "SEQUENCER_OT_change_effect_input";
2932         ot->description = "";
2933
2934         /* api callbacks */
2935         ot->exec = sequencer_change_effect_input_exec;
2936         ot->poll = sequencer_effect_poll;
2937
2938         /* flags */
2939         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2940
2941         ot->prop = RNA_def_enum(ot->srna, "swap", prop_change_effect_input_types, 0, "Swap", "The effect inputs to swap");
2942 }
2943
2944 static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
2945 {
2946         Scene *scene = CTX_data_scene(C);
2947         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
2948         Sequence *seq = BKE_sequencer_active_get(scene);
2949         const int new_type = RNA_enum_get(op->ptr, "type");
2950
2951         /* free previous effect and init new effect */
2952         struct SeqEffectHandle sh;
2953
2954         if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
2955                 return OPERATOR_CANCELLED;
2956         }
2957
2958         /* can someone explain the logic behind only allowing to increase this,
2959          * copied from 2.4x - campbell */
2960         if (BKE_sequence_effect_get_num_inputs(seq->type) <
2961             BKE_sequence_effect_get_num_inputs(new_type))
2962         {
2963                 BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips");
2964                 return OPERATOR_CANCELLED;
2965         }
2966         else {
2967                 sh = BKE_sequence_get_effect(seq);
2968                 sh.free(seq);
2969
2970                 seq->type = new_type;
2971
2972                 sh = BKE_sequence_get_effect(seq);
2973                 sh.init(seq);
2974         }
2975
2976         /* update */
2977         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
2978
2979         /* important else we don't get the imbuf cache flushed */
2980         BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
2981
2982         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2983
2984         return OPERATOR_FINISHED;
2985 }
2986
2987 void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot)
2988 {
2989         /* identifiers */
2990         ot->name = "Change Effect Type";
2991         ot->idname = "SEQUENCER_OT_change_effect_type";
2992         ot->description = "";
2993
2994         /* api callbacks */
2995         ot->exec = sequencer_change_effect_type_exec;
2996         ot->poll = sequencer_effect_poll;
2997
2998         /* flags */
2999         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3000
3001         ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type");
3002 }
3003
3004 static int sequencer_change_path_exec(bContext *C, wmOperator *op)
3005 {
3006         Main *bmain = CTX_data_main(C);
3007         Scene *scene = CTX_data_scene(C);
3008         Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
3009         Sequence *seq = BKE_sequencer_active_get(scene);
3010         const int is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
3011
3012         if (seq->type == SEQ_TYPE_IMAGE) {
3013                 char directory[FILE_MAX];
3014                 const int len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
3015                 StripElem *se;
3016
3017                 if (len == 0)
3018                         return OPERATOR_CANCELLED;
3019
3020                 RNA_string_get(op->ptr, "directory", directory);
3021                 if (is_relative_path) {
3022                         /* TODO, shouldn't this already be relative from the filesel?
3023                          * (as the 'filepath' is) for now just make relative here,
3024                          * but look into changing after 2.60 - campbell */
3025                         BLI_path_rel(directory, bmain->name);
3026                 }
3027                 BLI_strncpy(seq->strip->dir, directory, sizeof(seq->strip->dir));
3028
3029                 if (seq->strip->stripdata) {
3030                         MEM_freeN(seq->strip->stripdata);
3031                 }
3032                 seq->strip->stripdata = se = MEM_callocN(len * sizeof(StripElem), "stripelem");
3033
3034                 RNA_BEGIN (op->ptr, itemptr, "files")
3035                 {
3036                         char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
3037                         BLI_strncpy(se->name, filename, sizeof(se->name));
3038                         MEM_freeN(filename);
3039                         se++;
3040                 }
3041                 RNA_END;
3042
3043                 /* reset these else we wont see all the images */
3044                 seq->anim_startofs = seq->anim_endofs = 0;
3045
3046                 /* correct start/end frames so we don't move
3047                  * important not to set seq->len = len; allow the function to handle it */
3048                 BKE_sequence_reload_new_file(scene, seq, TRUE);
3049
3050                 BKE_sequence_calc(scene, seq);
3051
3052                 /* important else we don't get the imbuf cache flushed */
3053                 BKE_sequencer_free_imbuf(scene, &ed->seqbase, FALSE);
3054         }
3055         else {
3056                 /* lame, set rna filepath */
3057                 PointerRNA seq_ptr;
3058                 PropertyRNA *prop;
3059                 char filepath[FILE_MAX];
3060
3061                 RNA_pointer_create(&scene->id, &RNA_Sequence, seq, &seq_ptr);
3062
3063                 RNA_string_get(op->ptr, "filepath", filepath);
3064                 prop = RNA_struct_find_property(&seq_ptr, "filepath");
3065                 RNA_property_string_set(&seq_ptr, prop, filepath);
3066                 RNA_property_update(C, &seq_ptr, prop);
3067         }
3068
3069         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
3070
3071         return OPERATOR_FINISHED;
3072 }
3073
3074 static int sequencer_change_path_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
3075 {
3076         Scene *scene = CTX_data_scene(C);
3077         Sequence *seq = BKE_sequencer_active_get(scene);
3078
3079         RNA_string_set(op->ptr, "directory", seq->strip->dir);
3080
3081         /* set default display depending on seq type */
3082         if (seq->type == SEQ_TYPE_IMAGE) {
3083                 RNA_boolean_set(op->ptr, "filter_movie", FALSE);
3084         }
3085         else {
3086                 RNA_boolean_set(op->ptr, "filter_image", FALSE);
3087         }
3088
3089         WM_event_add_fileselect(C, op);
3090
3091         return OPERATOR_RUNNING_MODAL;
3092 }
3093
3094 void SEQUENCER_OT_change_path(struct wmOperatorType *ot)
3095 {
3096         /* identifiers */
3097         ot->name = "Change Data/Files";
3098         ot->idname = "SEQUENCER_OT_change_path";
3099         ot->description = "";
3100
3101         /* api callbacks */
3102         ot->exec = sequencer_change_path_exec;
3103         ot->invoke = sequencer_change_path_invoke;
3104         ot->poll = sequencer_strip_has_path_poll;
3105
3106         /* flags */
3107         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3108
3109         WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE,
3110                                        WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES,
3111                                        FILE_DEFAULTDISPLAY);
3112 }
3113