Code cleanup: remove redundant CTX calls
[blender-staging.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(sa);
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 bool seq_is_parent(Sequence *par, Sequence *seq)
423 {
424         return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq));
425 }
426
427 static bool 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 bool 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 /* are we displaying the seq output (not channels or histogram)*/
500 bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
501 {
502         return (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW) &&
503                 ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
504 }
505
506 int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequence **selseq1, Sequence **selseq2, Sequence **selseq3, const char **error_str)
507 {
508         Editing *ed = BKE_sequencer_editing_get(scene, false);
509         Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq;
510         
511         *error_str = NULL;
512
513         if (!activeseq)
514                 seq2 = BKE_sequencer_active_get(scene);
515
516         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
517                 if (seq->flag & SELECT) {
518                         if (seq->type == SEQ_TYPE_SOUND_RAM && BKE_sequence_effect_get_num_inputs(type) != 0) {
519                                 *error_str = N_("Cannot apply effects to audio sequence strips");
520                                 return 0;
521                         }
522                         if ((seq != activeseq) && (seq != seq2)) {
523                                 if      (seq2 == NULL) seq2 = seq;
524                                 else if (seq1 == NULL) seq1 = seq;
525                                 else if (seq3 == NULL) seq3 = seq;
526                                 else {
527                                         *error_str = N_("Cannot apply effect to more than 3 sequence strips");
528                                         return 0;
529                                 }
530                         }
531                 }
532         }
533
534         /* make sequence selection a little bit more intuitive
535          * for 3 strips: the last-strip should be sequence3 */
536         if (seq3 != NULL && seq2 != NULL) {
537                 Sequence *tmp = seq2;
538                 seq2 = seq3;
539                 seq3 = tmp;
540         }
541         
542
543         switch (BKE_sequence_effect_get_num_inputs(type)) {
544                 case 0:
545                         *selseq1 = *selseq2 = *selseq3 = NULL;
546                         return 1; /* succsess */
547                 case 1:
548                         if (seq2 == NULL) {
549                                 *error_str = N_("At least one selected sequence strip is needed");
550                                 return 0;
551                         }
552                         if (seq1 == NULL) seq1 = seq2;
553                         if (seq3 == NULL) seq3 = seq2;
554                         /* fall-through */
555                 case 2:
556                         if (seq1 == NULL || seq2 == NULL) {
557                                 *error_str = N_("2 selected sequence strips are needed");
558                                 return 0;
559                         }
560                         if (seq3 == NULL) seq3 = seq2;
561                         break;
562         }
563         
564         if (seq1 == NULL && seq2 == NULL && seq3 == NULL) {
565                 *error_str = N_("TODO: in what cases does this happen?");
566                 return 0;
567         }
568         
569         *selseq1 = seq1;
570         *selseq2 = seq2;
571         *selseq3 = seq3;
572
573         return 1;
574 }
575
576 static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq)
577 {
578         Sequence *seq1, *seq2, *seq3;
579
580         /* try to find a replacement input sequence, and flag for later deletion if
581          * no replacement can be found */
582
583         if (!seq)
584                 return NULL;
585         else if (!(seq->type & SEQ_TYPE_EFFECT))
586                 return ((seq->flag & SELECT) ? NULL : seq);
587         else if (!(seq->flag & SELECT)) {
588                 /* try to find replacement for effect inputs */
589                 seq1 = del_seq_find_replace_recurs(scene, seq->seq1);
590                 seq2 = del_seq_find_replace_recurs(scene, seq->seq2);
591                 seq3 = del_seq_find_replace_recurs(scene, seq->seq3);
592
593                 if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) {
594                         /* pass */
595                 }
596                 else if (seq1 || seq2 || seq3) {
597                         seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3;
598                         seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3;
599                         seq->seq3 = (seq3) ? seq3 : (seq1) ? seq1 : seq2;
600
601                         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1);
602                 }
603                 else
604                         seq->flag |= SELECT;  /* mark for delete */
605         }
606
607         if (seq->flag & SELECT) {
608                 if ((seq1 = del_seq_find_replace_recurs(scene, seq->seq1))) return seq1;
609                 if ((seq2 = del_seq_find_replace_recurs(scene, seq->seq2))) return seq2;
610                 if ((seq3 = del_seq_find_replace_recurs(scene, seq->seq3))) return seq3;
611                 else return NULL;
612         }
613         else
614                 return seq;
615 }
616
617 static void del_seq_clear_modifiers_recurs(Scene *scene, Sequence *deleting_sequence)
618 {
619         Editing *ed = BKE_sequencer_editing_get(scene, false);
620         Sequence *current_sequence;
621
622         SEQP_BEGIN(ed, current_sequence)
623         {
624                 if (!(current_sequence->flag & SELECT) && current_sequence != deleting_sequence) {
625                         SequenceModifierData *smd;
626
627                         for (smd = current_sequence->modifiers.first; smd; smd = smd->next) {
628                                 if (smd->mask_sequence == deleting_sequence) {
629                                         smd->mask_sequence = NULL;
630                                 }
631                         }
632                 }
633         }
634         SEQ_END
635 }
636
637 static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall)
638 {
639         Sequence *seq, *seqn;
640         Sequence *last_seq = BKE_sequencer_active_get(scene);
641
642         seq = lb->first;
643         while (seq) {
644                 seqn = seq->next;
645                 if ((seq->flag & flag) || deleteall) {
646                         BLI_remlink(lb, seq);
647                         if (seq == last_seq) BKE_sequencer_active_set(scene, NULL);
648                         if (seq->type == SEQ_TYPE_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1);
649                         BKE_sequence_free(scene, seq);
650                 }
651                 seq = seqn;
652         }
653 }
654
655
656 static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
657 {
658         TransSeq ts;
659         Sequence *seqn = NULL;
660         bool skip_dup = false;
661
662         /* backup values */
663         ts.start = seq->start;
664         ts.machine = seq->machine;
665         ts.startstill = seq->startstill;
666         ts.endstill = seq->endstill;
667         ts.startdisp = seq->startdisp;
668         ts.enddisp = seq->enddisp;
669         ts.startofs = seq->startofs;
670         ts.endofs = seq->endofs;
671         ts.anim_startofs = seq->anim_startofs;
672         ts.anim_endofs = seq->anim_endofs;
673         ts.len = seq->len;
674         
675         /* First Strip! */
676         /* strips with extended stillfames before */
677         
678         if ((seq->startstill) && (cutframe < seq->start)) {
679                 /* don't do funny things with METAs ... */
680                 if (seq->type == SEQ_TYPE_META) {
681                         skip_dup = true;
682                         seq->startstill = seq->start - cutframe;
683                 }
684                 else {
685                         seq->start = cutframe - 1;
686                         seq->startstill = cutframe - seq->startdisp - 1;
687                         seq->anim_endofs += seq->len - 1;
688                         seq->endstill = 0;
689                 }
690         }
691         /* normal strip */
692         else if ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len))) {
693                 seq->endofs = 0;
694                 seq->endstill = 0;
695                 seq->anim_endofs += (seq->start + seq->len) - cutframe;
696         }
697         /* strips with extended stillframes after */
698         else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) {
699                 seq->endstill -= seq->enddisp - cutframe;
700                 /* don't do funny things with METAs ... */
701                 if (seq->type == SEQ_TYPE_META) {
702                         skip_dup = true;
703                 }
704         }
705         
706         BKE_sequence_reload_new_file(scene, seq, false);
707         BKE_sequence_calc(scene, seq);
708
709         if (!skip_dup) {
710                 /* Duplicate AFTER the first change */
711                 seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
712         }
713         
714         if (seqn) {
715                 seqn->flag |= SELECT;
716                         
717                 /* Second Strip! */
718                 /* strips with extended stillframes before */
719                 if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
720                         seqn->start = ts.start;
721                         seqn->startstill = ts.start - cutframe;
722                         seqn->anim_endofs = ts.anim_endofs;
723                         seqn->endstill = ts.endstill;
724                 }
725                 
726                 /* normal strip */
727                 else if ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len))) {
728                         seqn->start = cutframe;
729                         seqn->startstill = 0;
730                         seqn->startofs = 0;
731                         seqn->endofs = ts.endofs;
732                         seqn->anim_startofs += cutframe - ts.start;
733                         seqn->anim_endofs = ts.anim_endofs;
734                         seqn->endstill = ts.endstill;
735                 }
736                 
737                 /* strips with extended stillframes after */
738                 else if (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)) {
739                         seqn->start = cutframe;
740                         seqn->startofs = 0;
741                         seqn->anim_startofs += ts.len - 1;
742                         seqn->endstill = ts.enddisp - cutframe - 1;
743                         seqn->startstill = 0;
744                 }
745                 
746                 BKE_sequence_reload_new_file(scene, seqn, false);
747                 BKE_sequence_calc(scene, seqn);
748         }
749         return seqn;
750 }
751
752 static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
753 {
754         TransSeq ts;
755         Sequence *seqn = NULL;
756         bool skip_dup = false;
757
758         /* backup values */
759         ts.start = seq->start;
760         ts.machine = seq->machine;
761         ts.startstill = seq->startstill;
762         ts.endstill = seq->endstill;
763         ts.startdisp = seq->startdisp;
764         ts.enddisp = seq->enddisp;
765         ts.startofs = seq->startofs;
766         ts.endofs = seq->endofs;
767         ts.anim_startofs = seq->anim_startofs;
768         ts.anim_endofs = seq->anim_endofs;
769         ts.len = seq->len;
770         
771         /* First Strip! */
772         /* strips with extended stillfames before */
773         
774         if ((seq->startstill) && (cutframe < seq->start)) {
775                 /* don't do funny things with METAs ... */
776                 if (seq->type == SEQ_TYPE_META) {
777                         skip_dup = true;
778                         seq->startstill = seq->start - cutframe;
779                 }
780                 else {
781                         seq->start = cutframe - 1;
782                         seq->startstill = cutframe - seq->startdisp - 1;
783                         seq->endofs = seq->len - 1;
784                         seq->endstill = 0;
785                 }
786         }
787         /* normal strip */
788         else if ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len))) {
789                 seq->endofs = (seq->start + seq->len) - cutframe;
790         }
791         /* strips with extended stillframes after */
792         else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) {
793                 seq->endstill -= seq->enddisp - cutframe;
794                 /* don't do funny things with METAs ... */
795                 if (seq->type == SEQ_TYPE_META) {
796                         skip_dup = true;
797                 }
798         }
799         
800         BKE_sequence_calc(scene, seq);
801
802         if (!skip_dup) {
803                 /* Duplicate AFTER the first change */
804                 seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
805         }
806         
807         if (seqn) {
808                 seqn->flag |= SELECT;
809                         
810                 /* Second Strip! */
811                 /* strips with extended stillframes before */
812                 if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
813                         seqn->start = ts.start;
814                         seqn->startstill = ts.start - cutframe;
815                         seqn->endofs = ts.endofs;
816                         seqn->endstill = ts.endstill;
817                 }
818                 
819                 /* normal strip */
820                 else if ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len))) {
821                         seqn->startstill = 0;
822                         seqn->startofs = cutframe - ts.start;
823                         seqn->endofs = ts.endofs;
824                         seqn->endstill = ts.endstill;
825                 }
826                 
827                 /* strips with extended stillframes after */
828                 else if (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)) {
829                         seqn->start = cutframe - ts.len + 1;
830                         seqn->startofs = ts.len - 1;
831                         seqn->endstill = ts.enddisp - cutframe - 1;
832                         seqn->startstill = 0;
833                 }
834                 
835                 BKE_sequence_calc(scene, seqn);
836         }
837         return seqn;
838 }
839
840
841 /* like duplicate, but only duplicate and cut overlapping strips,
842  * strips to the left of the cutframe are ignored and strips to the right 
843  * are moved to the end of slist
844  * we have to work on the same slist (not using a separate list), since
845  * otherwise dupli_seq can't check for duplicate names properly and
846  * may generate strips with the same name (which will mess up animdata)
847  */
848
849 static bool cut_seq_list(Scene *scene, ListBase *slist, int cutframe,
850                          Sequence * (*cut_seq)(Scene *, Sequence *, int))
851 {
852         Sequence *seq, *seq_next_iter;
853         Sequence *seq_first_new = NULL;
854         
855         seq = slist->first;
856
857         while (seq && seq != seq_first_new) {
858                 seq_next_iter = seq->next; /* we need this because we may remove seq */
859                 seq->tmp = NULL;
860                 if (seq->flag & SELECT) {
861                         if (cutframe > seq->startdisp && 
862                             cutframe < seq->enddisp)
863                         {
864                                 Sequence *seqn = cut_seq(scene, seq, cutframe);
865                                 if (seqn) {
866                                         BLI_addtail(slist, seqn);
867                                         if (seq_first_new == NULL) {
868                                                 seq_first_new = seqn;
869                                         }
870                                 }
871                         }
872                         else if (seq->enddisp <= cutframe) {
873                                 /* do nothing */
874                         }
875                         else if (seq->startdisp >= cutframe) {
876                                 /* move to tail */
877                                 BLI_remlink(slist, seq);
878                                 BLI_addtail(slist, seq);
879
880                                 if (seq_first_new == NULL) {
881                                         seq_first_new = seq;
882                                 }
883                         }
884                 }
885                 seq = seq_next_iter;
886         }
887
888         return (seq_first_new != NULL);
889 }
890
891 static bool sequence_offset_after_frame(Scene *scene, const int delta, const int cfra)
892 {
893         Sequence *seq;
894         Editing *ed = BKE_sequencer_editing_get(scene, false);
895         bool done = false;
896
897         /* all strips >= cfra are shifted */
898         
899         if (ed == NULL) return 0;
900
901         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
902                 if (seq->startdisp >= cfra) {
903                         BKE_sequence_translate(scene, seq, delta);
904                         BKE_sequence_calc(scene, seq);
905                         done = true;
906                 }
907         }
908
909         return done;
910 }
911
912 static void UNUSED_FUNCTION(touch_seq_files) (Scene *scene)
913 {
914         Sequence *seq;
915         Editing *ed = BKE_sequencer_editing_get(scene, false);
916         char str[256];
917
918         /* touch all strips with movies */
919         
920         if (ed == NULL) return;
921
922         // XXX25 if (okee("Touch and print selected movies")==0) return;
923
924         WM_cursor_wait(1);
925
926         SEQP_BEGIN (ed, seq)
927         {
928                 if (seq->flag & SELECT) {
929                         if (seq->type == SEQ_TYPE_MOVIE) {
930                                 if (seq->strip && seq->strip->stripdata) {
931                                         BLI_make_file_string(G.main->name, str, seq->strip->dir, seq->strip->stripdata->name);
932                                         BLI_file_touch(seq->name);
933                                 }
934                         }
935
936                 }
937         }
938         SEQ_END
939
940         WM_cursor_wait(0);
941 }
942
943 #if 0
944 static void set_filter_seq(Scene *scene)
945 {
946         Sequence *seq;
947         Editing *ed = BKE_sequencer_editing_get(scene, false);
948
949         
950         if (ed == NULL) return;
951
952         if (okee("Set Deinterlace") == 0) return;
953
954         SEQP_BEGIN (ed, seq)
955         {
956                 if (seq->flag & SELECT) {
957                         if (seq->type == SEQ_TYPE_MOVIE) {
958                                 seq->flag |= SEQ_FILTERY;
959                                 BKE_sequence_reload_new_file(scene, seq, false);
960                                 BKE_sequence_calc(scene, seq);
961                         }
962
963                 }
964         }
965         SEQ_END
966 }
967 #endif
968
969 static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene)
970 {
971         Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
972         Editing *ed = BKE_sequencer_editing_get(scene, false);
973         char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
974         
975         
976         if (last_seq == NULL)
977                 return;
978         
979         BLI_strncpy(from, last_seq->strip->dir, sizeof(from));
980 // XXX  if (0 == sbutton(from, 0, sizeof(from)-1, "From: "))
981 //              return;
982         
983         BLI_strncpy(to, from, sizeof(to));
984 // XXX  if (0 == sbutton(to, 0, sizeof(to)-1, "To: "))
985 //              return;
986         
987         if (strcmp(to, from) == 0)
988                 return;
989         
990         SEQP_BEGIN (ed, seq)
991         {
992                 if (seq->flag & SELECT) {
993                         if (strncmp(seq->strip->dir, from, strlen(from)) == 0) {
994                                 printf("found %s\n", seq->strip->dir);
995                                 
996                                 /* strip off the beginning */
997                                 stripped[0] = 0;
998                                 BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
999                                 
1000                                 /* new path */
1001                                 BLI_snprintf(seq->strip->dir, sizeof(seq->strip->dir), "%s%s", to, stripped);
1002                                 printf("new %s\n", seq->strip->dir);
1003                         }
1004                 }
1005         }
1006         SEQ_END
1007                 
1008 }
1009
1010
1011 static int sequencer_gap_remove_exec(bContext *C, wmOperator *op)
1012 {
1013         Scene *scene = CTX_data_scene(C);
1014         rctf rectf;
1015         int cfra, efra, sfra;
1016         bool first = false, done;
1017         bool do_all = RNA_boolean_get(op->ptr, "all");
1018
1019         /* get first and last frame */
1020         boundbox_seq(scene, &rectf);
1021         sfra = (int)rectf.xmin;
1022         efra = (int)rectf.xmax;
1023         
1024         /* first check if the current frame has a gap already */
1025         for (cfra = CFRA; cfra >= sfra; cfra--) {
1026                 if (BKE_sequencer_evaluate_frame(scene, cfra)) {
1027                         first = true;
1028                         break;
1029                 }
1030         }
1031         
1032         for ( ; cfra < efra; cfra++) {
1033                 /* first == 0 means there's still no strip to remove a gap for */
1034                 if (first == false) {
1035                         if (BKE_sequencer_evaluate_frame(scene, cfra) ) first = true;
1036                 }
1037                 else if (BKE_sequencer_evaluate_frame(scene, cfra) == 0) {
1038                         done = true;
1039                         while (BKE_sequencer_evaluate_frame(scene, cfra) == 0) {
1040                                 done = sequence_offset_after_frame(scene, -1, cfra);
1041                                 if (done == false) break;
1042                         }
1043                         if (done == false || do_all == false) break;
1044                 }
1045         }
1046
1047         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1048         
1049         return OPERATOR_FINISHED;
1050
1051 }
1052
1053
1054 void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot)
1055 {
1056         /* identifiers */
1057         ot->name = "Remove Gaps";
1058         ot->idname = "SEQUENCER_OT_gap_remove";
1059         ot->description = "Remove gap at current frame to first strip at the right, independent of selection or locked state of strips";
1060         
1061         /* api callbacks */
1062 //      ot->invoke = sequencer_snap_invoke;
1063         ot->exec = sequencer_gap_remove_exec;
1064         ot->poll = sequencer_edit_poll;
1065         
1066         /* flags */
1067         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1068         
1069         RNA_def_boolean(ot->srna, "all", 0, "All Gaps", "Do all gaps to right of current frame");
1070 }
1071
1072 static int sequencer_gap_insert_exec(bContext *C, wmOperator *op)
1073 {
1074         Scene *scene = CTX_data_scene(C);
1075         int frames = RNA_int_get(op->ptr, "frames");
1076         
1077         sequence_offset_after_frame(scene, frames, CFRA);
1078         
1079         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1080         
1081         return OPERATOR_FINISHED;
1082         
1083 }
1084
1085 void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot)
1086 {
1087         /* identifiers */
1088         ot->name = "Insert Gaps";
1089         ot->idname = "SEQUENCER_OT_gap_insert";
1090         ot->description = "Insert gap at current frame to first strips at the right, independent of selection or locked state of strips";
1091         
1092         /* api callbacks */
1093         //      ot->invoke = sequencer_snap_invoke;
1094         ot->exec = sequencer_gap_insert_exec;
1095         ot->poll = sequencer_edit_poll;
1096         
1097         /* flags */
1098         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1099         
1100         RNA_def_int(ot->srna, "frames", 10, 0, INT_MAX, "Frames", "Frames to insert after current strip", 0, 1000);
1101 }
1102
1103
1104 #if 0
1105 static int seq_get_snaplimit(View2D *v2d)
1106 {
1107         /* fake mouse coords to get the snap value
1108          * a bit lazy but its only done once pre transform */
1109         float xmouse, ymouse, x;
1110         int mval[2] = {24, 0}; /* 24 screen px snap */
1111         
1112         UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
1113         x = xmouse;
1114         mval[0] = 0;
1115         UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
1116         return (int)(x - xmouse);
1117 }
1118 #endif
1119
1120 /* Operator functions */
1121 int sequencer_edit_poll(bContext *C)
1122 {
1123         return (BKE_sequencer_editing_get(CTX_data_scene(C), false) != NULL);
1124 }
1125
1126 #if 0 /* UNUSED */
1127 int sequencer_strip_poll(bContext *C)
1128 {
1129         Editing *ed;
1130         return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && (ed->act_seq != NULL));
1131 }
1132 #endif
1133
1134 int sequencer_strip_has_path_poll(bContext *C)
1135 {
1136         Editing *ed;
1137         Sequence *seq;
1138         return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) && ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
1139 }
1140
1141 int sequencer_view_poll(bContext *C)
1142 {
1143         SpaceSeq *sseq = CTX_wm_space_seq(C);
1144         Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), false);
1145         if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF))
1146                 return 1;
1147
1148         return 0;
1149 }
1150
1151 /* snap operator*/
1152 static int sequencer_snap_exec(bContext *C, wmOperator *op)
1153 {
1154         Scene *scene = CTX_data_scene(C);
1155         
1156         Editing *ed = BKE_sequencer_editing_get(scene, false);
1157         Sequence *seq;
1158         int snap_frame;
1159
1160         snap_frame = RNA_int_get(op->ptr, "frame");
1161
1162         /* also check metas */
1163         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1164                 if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
1165                     BKE_sequence_tx_test(seq))
1166                 {
1167                         if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
1168                                 /* simple but no anim update */
1169                                 /* seq->start = snap_frame-seq->startofs+seq->startstill; */
1170
1171                                 BKE_sequence_translate(scene, seq, (snap_frame - seq->startofs + seq->startstill) - seq->start);
1172                         }
1173                         else {
1174                                 if (seq->flag & SEQ_LEFTSEL) {
1175                                         BKE_sequence_tx_set_final_left(seq, snap_frame);
1176                                 }
1177                                 else { /* SEQ_RIGHTSEL */
1178                                         BKE_sequence_tx_set_final_right(seq, snap_frame);
1179                                 }
1180                                 BKE_sequence_tx_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
1181                         }
1182                         BKE_sequence_calc(scene, seq);
1183                 }
1184         }
1185
1186         /* test for effects and overlap
1187          * don't use SEQP_BEGIN since that would be recursive */
1188         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1189                 if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
1190                         seq->flag &= ~SEQ_OVERLAP;
1191                         if (BKE_sequence_test_overlap(ed->seqbasep, seq) ) {
1192                                 BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1193                         }
1194                 }
1195                 else if (seq->type & SEQ_TYPE_EFFECT) {
1196                         if (seq->seq1 && (seq->seq1->flag & SELECT)) 
1197                                 BKE_sequence_calc(scene, seq);
1198                         else if (seq->seq2 && (seq->seq2->flag & SELECT)) 
1199                                 BKE_sequence_calc(scene, seq);
1200                         else if (seq->seq3 && (seq->seq3->flag & SELECT)) 
1201                                 BKE_sequence_calc(scene, seq);
1202                 }
1203         }
1204
1205         /* as last: */
1206         BKE_sequencer_sort(scene);
1207         
1208         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1209         
1210         return OPERATOR_FINISHED;
1211 }
1212
1213 static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1214 {
1215         Scene *scene = CTX_data_scene(C);
1216         
1217         int snap_frame;
1218         
1219         snap_frame = CFRA;
1220         
1221         RNA_int_set(op->ptr, "frame", snap_frame);
1222         return sequencer_snap_exec(C, op);
1223 }
1224
1225 void SEQUENCER_OT_snap(struct wmOperatorType *ot)
1226 {
1227         /* identifiers */
1228         ot->name = "Snap Strips";
1229         ot->idname = "SEQUENCER_OT_snap";
1230         ot->description = "Frame where selected strips will be snapped";
1231         
1232         /* api callbacks */
1233         ot->invoke = sequencer_snap_invoke;
1234         ot->exec = sequencer_snap_exec;
1235         ot->poll = sequencer_edit_poll;
1236         
1237         /* flags */
1238         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1239         
1240         RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be snapped", INT_MIN, INT_MAX);
1241 }
1242
1243 /* mute operator */
1244 static int sequencer_mute_exec(bContext *C, wmOperator *op)
1245 {
1246         Scene *scene = CTX_data_scene(C);
1247         Editing *ed = BKE_sequencer_editing_get(scene, false);
1248         Sequence *seq;
1249         bool selected;
1250
1251         selected = !RNA_boolean_get(op->ptr, "unselected");
1252         
1253         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1254                 if ((seq->flag & SEQ_LOCK) == 0) {
1255                         if (selected) { /* mute unselected */
1256                                 if (seq->flag & SELECT) {
1257                                         seq->flag |= SEQ_MUTE;
1258                                         BKE_sequence_invalidate_dependent(scene, seq);
1259                                 }
1260                         }
1261                         else {
1262                                 if ((seq->flag & SELECT) == 0) {
1263                                         seq->flag |= SEQ_MUTE;
1264                                         BKE_sequence_invalidate_dependent(scene, seq);
1265                                 }
1266                         }
1267                 }
1268         }
1269         
1270         BKE_sequencer_update_muting(ed);
1271         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1272         
1273         return OPERATOR_FINISHED;
1274 }
1275
1276 void SEQUENCER_OT_mute(struct wmOperatorType *ot)
1277 {
1278         /* identifiers */
1279         ot->name = "Mute Strips";
1280         ot->idname = "SEQUENCER_OT_mute";
1281         ot->description = "Mute selected strips";
1282         
1283         /* api callbacks */
1284         ot->exec = sequencer_mute_exec;
1285         ot->poll = sequencer_edit_poll;
1286         
1287         /* flags */
1288         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1289         
1290         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Mute unselected rather than selected strips");
1291 }
1292
1293
1294 /* unmute operator */
1295 static int sequencer_unmute_exec(bContext *C, wmOperator *op)
1296 {
1297         Scene *scene = CTX_data_scene(C);
1298         Editing *ed = BKE_sequencer_editing_get(scene, false);
1299         Sequence *seq;
1300         bool selected;
1301
1302         selected = !RNA_boolean_get(op->ptr, "unselected");
1303         
1304         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1305                 if ((seq->flag & SEQ_LOCK) == 0) {
1306                         if (selected) { /* unmute unselected */
1307                                 if (seq->flag & SELECT) {
1308                                         seq->flag &= ~SEQ_MUTE;
1309                                         BKE_sequence_invalidate_dependent(scene, seq);
1310                                 }
1311                         }
1312                         else {
1313                                 if ((seq->flag & SELECT) == 0) {
1314                                         seq->flag &= ~SEQ_MUTE;
1315                                         BKE_sequence_invalidate_dependent(scene, seq);
1316                                 }
1317                         }
1318                 }
1319         }
1320         
1321         BKE_sequencer_update_muting(ed);
1322         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1323         
1324         return OPERATOR_FINISHED;
1325 }
1326
1327 void SEQUENCER_OT_unmute(struct wmOperatorType *ot)
1328 {
1329         /* identifiers */
1330         ot->name = "Un-Mute Strips";
1331         ot->idname = "SEQUENCER_OT_unmute";
1332         ot->description = "Un-Mute unselected rather than selected strips";
1333         
1334         /* api callbacks */
1335         ot->exec = sequencer_unmute_exec;
1336         ot->poll = sequencer_edit_poll;
1337         
1338         /* flags */
1339         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1340         
1341         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "UnMute unselected rather than selected strips");
1342 }
1343
1344
1345 /* lock operator */
1346 static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op))
1347 {
1348         Scene *scene = CTX_data_scene(C);
1349         Editing *ed = BKE_sequencer_editing_get(scene, false);
1350         Sequence *seq;
1351
1352         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1353                 if (seq->flag & SELECT) {
1354                         seq->flag |= SEQ_LOCK;
1355                 }
1356         }
1357
1358         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1359
1360         return OPERATOR_FINISHED;
1361 }
1362
1363 void SEQUENCER_OT_lock(struct wmOperatorType *ot)
1364 {
1365         /* identifiers */
1366         ot->name = "Lock Strips";
1367         ot->idname = "SEQUENCER_OT_lock";
1368         ot->description = "Lock the active strip so that it can't be transformed";
1369         
1370         /* api callbacks */
1371         ot->exec = sequencer_lock_exec;
1372         ot->poll = sequencer_edit_poll;
1373         
1374         /* flags */
1375         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1376 }
1377
1378 /* unlock operator */
1379 static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op))
1380 {
1381         Scene *scene = CTX_data_scene(C);
1382         Editing *ed = BKE_sequencer_editing_get(scene, false);
1383         Sequence *seq;
1384
1385         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1386                 if (seq->flag & SELECT) {
1387                         seq->flag &= ~SEQ_LOCK;
1388                 }
1389         }
1390
1391         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1392
1393         return OPERATOR_FINISHED;
1394 }
1395
1396 void SEQUENCER_OT_unlock(struct wmOperatorType *ot)
1397 {
1398         /* identifiers */
1399         ot->name = "UnLock Strips";
1400         ot->idname = "SEQUENCER_OT_unlock";
1401         ot->description = "Unlock the active strip so that it can't be transformed";
1402         
1403         /* api callbacks */
1404         ot->exec = sequencer_unlock_exec;
1405         ot->poll = sequencer_edit_poll;
1406         
1407         /* flags */
1408         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1409 }
1410
1411 /* reload operator */
1412 static int sequencer_reload_exec(bContext *C, wmOperator *op)
1413 {
1414         Scene *scene = CTX_data_scene(C);
1415         Editing *ed = BKE_sequencer_editing_get(scene, false);
1416         Sequence *seq;
1417         const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length");
1418
1419         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1420                 if (seq->flag & SELECT) {
1421                         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
1422                         BKE_sequence_reload_new_file(scene, seq, !adjust_length);
1423
1424                         if (adjust_length) {
1425                                 if (BKE_sequence_test_overlap(ed->seqbasep, seq))
1426                                         BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1427                         }
1428                 }
1429         }
1430
1431         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1432
1433         return OPERATOR_FINISHED;
1434 }
1435
1436 void SEQUENCER_OT_reload(struct wmOperatorType *ot)
1437 {
1438         PropertyRNA *prop;
1439
1440         /* identifiers */
1441         ot->name = "Reload Strips";
1442         ot->idname = "SEQUENCER_OT_reload";
1443         ot->description = "Reload strips in the sequencer";
1444         
1445         /* api callbacks */
1446         ot->exec = sequencer_reload_exec;
1447         ot->poll = sequencer_edit_poll;
1448         
1449         /* flags */
1450         ot->flag = OPTYPE_REGISTER; /* no undo, the data changed is stored outside 'main' */
1451
1452         prop = RNA_def_boolean(ot->srna, "adjust_length", 0, "Adjust Length",
1453                                "Adjust length of strips to their data length");
1454         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1455 }
1456
1457 /* reload operator */
1458 static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op))
1459 {
1460         Scene *scene = CTX_data_scene(C);
1461         Editing *ed = BKE_sequencer_editing_get(scene, false);
1462
1463         BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
1464
1465         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1466
1467         return OPERATOR_FINISHED;
1468 }
1469
1470 void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot)
1471 {
1472         /* identifiers */
1473         ot->name = "Refresh Sequencer";
1474         ot->idname = "SEQUENCER_OT_refresh_all";
1475         ot->description = "Refresh the sequencer editor";
1476         
1477         /* api callbacks */
1478         ot->exec = sequencer_refresh_all_exec;
1479         ot->poll = sequencer_edit_poll;
1480 }
1481
1482 static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
1483 {
1484         Scene *scene = CTX_data_scene(C);
1485         Sequence *seq1, *seq2, *seq3, *last_seq = BKE_sequencer_active_get(scene);
1486         const char *error_msg;
1487
1488         if (!seq_effect_find_selected(scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg)) {
1489                 BKE_report(op->reports, RPT_ERROR, error_msg);
1490                 return OPERATOR_CANCELLED;
1491         }
1492         /* see reassigning would create a cycle */
1493         if (seq_is_predecessor(seq1, last_seq) ||
1494             seq_is_predecessor(seq2, last_seq) ||
1495             seq_is_predecessor(seq3, last_seq))
1496         {
1497                 BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: no cycles allowed");
1498                 return OPERATOR_CANCELLED;
1499         }
1500
1501         last_seq->seq1 = seq1;
1502         last_seq->seq2 = seq2;
1503         last_seq->seq3 = seq3;
1504
1505         BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1);
1506
1507         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1508
1509         return OPERATOR_FINISHED;
1510 }
1511
1512 static int sequencer_effect_poll(bContext *C)
1513 {
1514         Scene *scene = CTX_data_scene(C);
1515         Editing *ed = BKE_sequencer_editing_get(scene, false);
1516
1517         if (ed) {
1518                 Sequence *last_seq = BKE_sequencer_active_get(scene);
1519                 if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) {
1520                         return 1;
1521                 }
1522         }
1523
1524         return 0;
1525 }
1526
1527 void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot)
1528 {
1529         /* identifiers */
1530         ot->name = "Reassign Inputs";
1531         ot->idname = "SEQUENCER_OT_reassign_inputs";
1532         ot->description = "Reassign the inputs for the effect strip";
1533
1534         /* api callbacks */
1535         ot->exec = sequencer_reassign_inputs_exec;
1536         ot->poll = sequencer_effect_poll;
1537
1538         /* flags */
1539         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1540 }
1541
1542
1543 static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op)
1544 {
1545         Scene *scene = CTX_data_scene(C);
1546         Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
1547
1548         if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) {
1549                 BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap");
1550                 return OPERATOR_CANCELLED;
1551         }
1552
1553         seq = last_seq->seq1;
1554         last_seq->seq1 = last_seq->seq2;
1555         last_seq->seq2 = seq;
1556
1557         BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1);
1558
1559         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1560
1561         return OPERATOR_FINISHED;
1562 }
1563 void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot)
1564 {
1565         /* identifiers */
1566         ot->name = "Swap Inputs";
1567         ot->idname = "SEQUENCER_OT_swap_inputs";
1568         ot->description = "Swap the first two inputs for the effect strip";
1569
1570         /* api callbacks */
1571         ot->exec = sequencer_swap_inputs_exec;
1572         ot->poll = sequencer_effect_poll;
1573
1574         /* flags */
1575         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1576 }
1577
1578
1579 /* cut operator */
1580 static EnumPropertyItem prop_cut_types[] = {
1581         {SEQ_CUT_SOFT, "SOFT", 0, "Soft", ""},
1582         {SEQ_CUT_HARD, "HARD", 0, "Hard", ""},
1583         {0, NULL, 0, NULL, NULL}
1584 };
1585
1586 static int sequencer_cut_exec(bContext *C, wmOperator *op)
1587 {
1588         Scene *scene = CTX_data_scene(C);
1589         Editing *ed = BKE_sequencer_editing_get(scene, false);
1590         int cut_side, cut_hard, cut_frame;
1591
1592         bool changed;
1593
1594         cut_frame = RNA_int_get(op->ptr, "frame");
1595         cut_hard = RNA_enum_get(op->ptr, "type");
1596         cut_side = RNA_enum_get(op->ptr, "side");
1597         
1598         if (cut_hard == SEQ_CUT_HARD) {
1599                 changed = cut_seq_list(scene, ed->seqbasep, cut_frame, cut_seq_hard);
1600         }
1601         else {
1602                 changed = cut_seq_list(scene, ed->seqbasep, cut_frame, cut_seq_soft);
1603         }
1604         
1605         if (changed) { /* got new strips ? */
1606                 Sequence *seq;
1607
1608                 if (cut_side != SEQ_SIDE_BOTH) {
1609                         SEQP_BEGIN (ed, seq)
1610                         {
1611                                 if (cut_side == SEQ_SIDE_LEFT) {
1612                                         if (seq->startdisp >= cut_frame) {
1613                                                 seq->flag &= ~SEQ_ALLSEL;
1614                                         }
1615                                 }
1616                                 else {
1617                                         if (seq->enddisp <= cut_frame) {
1618                                                 seq->flag &= ~SEQ_ALLSEL;
1619                                         }
1620                                 }
1621                         }
1622                         SEQ_END;
1623                 }
1624
1625                 SEQP_BEGIN (ed, seq)
1626                 {
1627                         if (seq->seq1 || seq->seq2 || seq->seq3) {
1628                                 BKE_sequence_calc(scene, seq);
1629                         }
1630                 }
1631                 SEQ_END;
1632
1633                 /* as last: */
1634                 BKE_sequencer_sort(scene);
1635         }
1636
1637         if (changed) {
1638                 WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1639                 return OPERATOR_FINISHED;
1640         }
1641         else {
1642                 return OPERATOR_CANCELLED;
1643         }
1644 }
1645
1646
1647 static int sequencer_cut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1648 {
1649         Scene *scene = CTX_data_scene(C);
1650         View2D *v2d = UI_view2d_fromcontext(C);
1651
1652         int cut_side = SEQ_SIDE_BOTH;
1653         int cut_frame = CFRA;
1654
1655         if (ED_operator_sequencer_active(C) && v2d)
1656                 cut_side = mouse_frame_side(v2d, event->mval[0], cut_frame);
1657         
1658         RNA_int_set(op->ptr, "frame", cut_frame);
1659         RNA_enum_set(op->ptr, "side", cut_side);
1660         /*RNA_enum_set(op->ptr, "type", cut_hard); */ /*This type is set from the key shortcut */
1661
1662         return sequencer_cut_exec(C, op);
1663 }
1664
1665
1666 void SEQUENCER_OT_cut(struct wmOperatorType *ot)
1667 {
1668         /* identifiers */
1669         ot->name = "Cut Strips";
1670         ot->idname = "SEQUENCER_OT_cut";
1671         ot->description = "Cut the selected strips";
1672         
1673         /* api callbacks */
1674         ot->invoke = sequencer_cut_invoke;
1675         ot->exec = sequencer_cut_exec;
1676         ot->poll = sequencer_edit_poll;
1677         
1678         /* flags */
1679         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1680         
1681         RNA_def_int(ot->srna, "frame", 0, INT_MIN, INT_MAX, "Frame", "Frame where selected strips will be cut", INT_MIN, INT_MAX);
1682         RNA_def_enum(ot->srna, "type", prop_cut_types, SEQ_CUT_SOFT, "Type", "The type of cut operation to perform on strips");
1683         RNA_def_enum(ot->srna, "side", prop_side_types, SEQ_SIDE_BOTH, "Side", "The side that remains selected after cutting");
1684 }
1685
1686 /* duplicate operator */
1687 static int apply_unique_name_cb(Sequence *seq, void *arg_pt)
1688 {
1689         Scene *scene = (Scene *)arg_pt;
1690         char name[sizeof(seq->name) - 2];
1691
1692         BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
1693         BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
1694         BKE_sequencer_dupe_animdata(scene, name, seq->name + 2);
1695         return 1;
1696
1697 }
1698
1699 static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
1700 {
1701         Scene *scene = CTX_data_scene(C);
1702         Editing *ed = BKE_sequencer_editing_get(scene, false);
1703
1704         ListBase nseqbase = {NULL, NULL};
1705
1706         if (ed == NULL)
1707                 return OPERATOR_CANCELLED;
1708
1709         BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT);
1710
1711         if (nseqbase.first) {
1712                 Sequence *seq = nseqbase.first;
1713                 /* rely on the nseqbase list being added at the end */
1714                 BLI_movelisttolist(ed->seqbasep, &nseqbase);
1715
1716                 for (; seq; seq = seq->next)
1717                         BKE_sequencer_recursive_apply(seq, apply_unique_name_cb, scene);
1718
1719                 WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1720                 return OPERATOR_FINISHED;
1721         }
1722
1723         return OPERATOR_CANCELLED;
1724 }
1725
1726 void SEQUENCER_OT_duplicate(wmOperatorType *ot)
1727 {
1728         /* identifiers */
1729         ot->name = "Duplicate Strips";
1730         ot->idname = "SEQUENCER_OT_duplicate";
1731         ot->description = "Duplicate the selected strips";
1732         
1733         /* api callbacks */
1734         ot->exec = sequencer_add_duplicate_exec;
1735         ot->poll = ED_operator_sequencer_active;
1736         
1737         /* flags */
1738         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1739         
1740         /* to give to transform */
1741         RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
1742 }
1743
1744 /* delete operator */
1745 static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
1746 {
1747         Scene *scene = CTX_data_scene(C);
1748         Editing *ed = BKE_sequencer_editing_get(scene, false);
1749         Sequence *seq;
1750         MetaStack *ms;
1751         bool nothingSelected = true;
1752
1753         seq = BKE_sequencer_active_get(scene);
1754         if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
1755                 nothingSelected = false;
1756         }
1757         else {
1758                 for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1759                         if (seq->flag & SELECT) {
1760                                 nothingSelected = false;
1761                                 break;
1762                         }
1763                 }
1764         }
1765
1766         if (nothingSelected)
1767                 return OPERATOR_FINISHED;
1768
1769         /* for effects and modifiers, try to find a replacement input */
1770         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1771                 if (!(seq->flag & SELECT)) {
1772                         if ((seq->type & SEQ_TYPE_EFFECT)) {
1773                                 del_seq_find_replace_recurs(scene, seq);
1774                         }
1775                 }
1776                 else {
1777                         del_seq_clear_modifiers_recurs(scene, seq);
1778                 }
1779         }
1780
1781         /* delete all selected strips */
1782         recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0);
1783
1784         /* updates lengths etc */
1785         seq = ed->seqbasep->first;
1786         while (seq) {
1787                 BKE_sequence_calc(scene, seq);
1788                 seq = seq->next;
1789         }
1790
1791         /* free parent metas */
1792         ms = ed->metastack.last;
1793         while (ms) {
1794                 BKE_sequence_calc(scene, ms->parseq);
1795                 ms = ms->prev;
1796         }
1797
1798         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1799         
1800         return OPERATOR_FINISHED;
1801 }
1802
1803 static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1804 {
1805         ARegion *ar = CTX_wm_region(C);
1806
1807         if (ar->regiontype == RGN_TYPE_WINDOW) {
1808                 /* bounding box of 30 pixels is used for markers shortcuts,
1809                  * prevent conflict with markers shortcuts here
1810                  */
1811                 if (event->mval[1] <= 30)
1812                         return OPERATOR_PASS_THROUGH;
1813         }
1814
1815         return WM_operator_confirm(C, op, event);
1816 }
1817
1818 void SEQUENCER_OT_delete(wmOperatorType *ot)
1819 {
1820
1821         /* identifiers */
1822         ot->name = "Erase Strips";
1823         ot->idname = "SEQUENCER_OT_delete";
1824         ot->description = "Erase selected strips from the sequencer";
1825         
1826         /* api callbacks */
1827         ot->invoke = sequencer_delete_invoke;
1828         ot->exec = sequencer_delete_exec;
1829         ot->poll = sequencer_edit_poll;
1830         
1831         /* flags */
1832         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1833 }
1834
1835
1836 /* offset clear operator */
1837 static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
1838 {
1839         Scene *scene = CTX_data_scene(C);
1840         Editing *ed = BKE_sequencer_editing_get(scene, false);
1841         Sequence *seq;
1842
1843         /* for effects, try to find a replacement input */
1844         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1845                 if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
1846                         seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
1847                 }
1848         }
1849
1850         /* updates lengths etc */
1851         seq = ed->seqbasep->first;
1852         while (seq) {
1853                 BKE_sequence_calc(scene, seq);
1854                 seq = seq->next;
1855         }
1856
1857         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1858                 if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
1859                         if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
1860                                 BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1861                         }
1862                 }
1863         }
1864
1865         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1866
1867         return OPERATOR_FINISHED;
1868 }
1869
1870
1871 void SEQUENCER_OT_offset_clear(wmOperatorType *ot)
1872 {
1873
1874         /* identifiers */
1875         ot->name = "Clear Strip Offset";
1876         ot->idname = "SEQUENCER_OT_offset_clear";
1877         ot->description = "Clear strip offsets from the start and end frames";
1878
1879         /* api callbacks */
1880         ot->exec = sequencer_offset_clear_exec;
1881         ot->poll = sequencer_edit_poll;
1882
1883         /* flags */
1884         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1885 }
1886
1887
1888 /* separate_images operator */
1889 static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
1890 {
1891         Scene *scene = CTX_data_scene(C);
1892         Editing *ed = BKE_sequencer_editing_get(scene, false);
1893         
1894         Sequence *seq, *seq_new;
1895         Strip *strip_new;
1896         StripElem *se, *se_new;
1897         int start_ofs, cfra, frame_end;
1898         int step = RNA_int_get(op->ptr, "length");
1899
1900         seq = ed->seqbasep->first; /* poll checks this is valid */
1901
1902         while (seq) {
1903                 if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
1904                         Sequence *seq_next;
1905
1906                         /* remove seq so overlap tests don't conflict,
1907                          * see seq_free_sequence below for the real free'ing */
1908                         BLI_remlink(ed->seqbasep, seq);
1909                         /* if (seq->ipo) seq->ipo->id.us--; */
1910                         /* XXX, remove fcurve and assign to split image strips */
1911
1912                         start_ofs = cfra = BKE_sequence_tx_get_final_left(seq, false);
1913                         frame_end = BKE_sequence_tx_get_final_right(seq, false);
1914
1915                         while (cfra < frame_end) {
1916                                 /* new seq */
1917                                 se = BKE_sequencer_give_stripelem(seq, cfra);
1918
1919                                 seq_new = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME);
1920                                 BLI_addtail(ed->seqbasep, seq_new);
1921
1922                                 seq_new->start = start_ofs;
1923                                 seq_new->type = SEQ_TYPE_IMAGE;
1924                                 seq_new->len = 1;
1925                                 seq_new->endstill = step - 1;
1926
1927                                 /* new strip */
1928                                 strip_new = seq_new->strip;
1929                                 strip_new->us = 1;
1930
1931                                 /* new stripdata */
1932                                 se_new = strip_new->stripdata;
1933                                 BLI_strncpy(se_new->name, se->name, sizeof(se_new->name));
1934                                 BKE_sequence_calc(scene, seq_new);
1935
1936                                 if (step > 1) {
1937                                         seq_new->flag &= ~SEQ_OVERLAP;
1938                                         if (BKE_sequence_test_overlap(ed->seqbasep, seq_new)) {
1939                                                 BKE_sequence_base_shuffle(ed->seqbasep, seq_new, scene);
1940                                         }
1941                                 }
1942
1943                                 /* XXX, COPY FCURVES */
1944
1945                                 cfra++;
1946                                 start_ofs += step;
1947                         }
1948
1949                         seq_next = seq->next;
1950                         BKE_sequence_free(scene, seq);
1951                         seq = seq_next;
1952                 }
1953                 else {
1954                         seq = seq->next;
1955                 }
1956         }
1957
1958         /* as last: */
1959         BKE_sequencer_sort(scene);
1960         
1961         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1962
1963         return OPERATOR_FINISHED;
1964 }
1965
1966
1967 void SEQUENCER_OT_images_separate(wmOperatorType *ot)
1968 {
1969         /* identifiers */
1970         ot->name = "Separate Images";
1971         ot->idname = "SEQUENCER_OT_images_separate";
1972         ot->description = "On image sequence strips, it returns a strip for each image";
1973         
1974         /* api callbacks */
1975         ot->exec = sequencer_separate_images_exec;
1976         ot->invoke = WM_operator_props_popup;
1977         ot->poll = sequencer_edit_poll;
1978         
1979         /* flags */
1980         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1981
1982         RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000);
1983 }
1984
1985
1986 /* META Operators */
1987
1988 /* separate_meta_toggle operator */
1989 static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
1990 {
1991         Scene *scene = CTX_data_scene(C);
1992         Editing *ed = BKE_sequencer_editing_get(scene, false);
1993         Sequence *last_seq = BKE_sequencer_active_get(scene);
1994         MetaStack *ms;
1995
1996         if (last_seq && last_seq->type == SEQ_TYPE_META && last_seq->flag & SELECT) {
1997                 /* Enter Metastrip */
1998                 ms = MEM_mallocN(sizeof(MetaStack), "metastack");
1999                 BLI_addtail(&ed->metastack, ms);
2000                 ms->parseq = last_seq;
2001                 ms->oldbasep = ed->seqbasep;
2002
2003                 ed->seqbasep = &last_seq->seqbase;
2004
2005                 BKE_sequencer_active_set(scene, NULL);
2006
2007         }
2008         else {
2009                 /* Exit Metastrip (if possible) */
2010
2011                 Sequence *seq;
2012
2013                 if (BLI_listbase_is_empty(&ed->metastack))
2014                         return OPERATOR_CANCELLED;
2015
2016                 ms = ed->metastack.last;
2017                 BLI_remlink(&ed->metastack, ms);
2018
2019                 ed->seqbasep = ms->oldbasep;
2020
2021                 /* recalc all: the meta can have effects connected to it */
2022                 for (seq = ed->seqbasep->first; seq; seq = seq->next)
2023                         BKE_sequence_calc(scene, seq);
2024
2025                 if (BKE_sequence_test_overlap(ed->seqbasep, ms->parseq))
2026                         BKE_sequence_base_shuffle(ed->seqbasep, ms->parseq, scene);
2027
2028                 BKE_sequencer_active_set(scene, ms->parseq);
2029
2030                 ms->parseq->flag |= SELECT;
2031                 recurs_sel_seq(ms->parseq);
2032
2033                 MEM_freeN(ms);
2034
2035         }
2036
2037         BKE_sequencer_update_muting(ed);
2038         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2039
2040         return OPERATOR_FINISHED;
2041 }
2042
2043 void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
2044 {
2045         /* identifiers */
2046         ot->name = "Toggle Meta Strip";
2047         ot->idname = "SEQUENCER_OT_meta_toggle";
2048         ot->description = "Toggle a metastrip (to edit enclosed strips)";
2049         
2050         /* api callbacks */
2051         ot->exec = sequencer_meta_toggle_exec;
2052         ot->poll = sequencer_edit_poll;
2053         
2054         /* flags */
2055         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2056 }
2057
2058
2059 /* separate_meta_make operator */
2060 static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
2061 {
2062         Scene *scene = CTX_data_scene(C);
2063         Editing *ed = BKE_sequencer_editing_get(scene, false);
2064         
2065         Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene);
2066         int channel_max = 1;
2067
2068         if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
2069                 BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
2070                 return OPERATOR_CANCELLED;
2071         }
2072
2073         /* remove all selected from main list, and put in meta */
2074
2075         seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1); /* channel number set later */
2076         strcpy(seqm->name + 2, "MetaStrip");
2077         seqm->type = SEQ_TYPE_META;
2078         seqm->flag = SELECT;
2079
2080         seq = ed->seqbasep->first;
2081         while (seq) {
2082                 next = seq->next;
2083                 if (seq != seqm && (seq->flag & SELECT)) {
2084                         channel_max = max_ii(seq->machine, channel_max);
2085                         BLI_remlink(ed->seqbasep, seq);
2086                         BLI_addtail(&seqm->seqbase, seq);
2087                 }
2088                 seq = next;
2089         }
2090         seqm->machine = last_seq ? last_seq->machine : channel_max;
2091         BKE_sequence_calc(scene, seqm);
2092
2093         seqm->strip = MEM_callocN(sizeof(Strip), "metastrip");
2094         seqm->strip->us = 1;
2095         
2096         BKE_sequencer_active_set(scene, seqm);
2097
2098         if (BKE_sequence_test_overlap(ed->seqbasep, seqm) ) BKE_sequence_base_shuffle(ed->seqbasep, seqm, scene);
2099
2100         BKE_sequencer_update_muting(ed);
2101
2102         BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm);
2103
2104         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2105
2106         return OPERATOR_FINISHED;
2107 }
2108
2109 void SEQUENCER_OT_meta_make(wmOperatorType *ot)
2110 {
2111         /* identifiers */
2112         ot->name = "Make Meta Strip";
2113         ot->idname = "SEQUENCER_OT_meta_make";
2114         ot->description = "Group selected strips into a metastrip";
2115         
2116         /* api callbacks */
2117         ot->exec = sequencer_meta_make_exec;
2118         ot->poll = sequencer_edit_poll;
2119         
2120         /* flags */
2121         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2122 }
2123
2124
2125 static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
2126 {
2127         if (seq == seqm) return 1;
2128         else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) return 1;
2129         else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) return 1;
2130         else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) return 1;
2131         else return 0;
2132 }
2133
2134 /* separate_meta_make operator */
2135 static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
2136 {
2137         Scene *scene = CTX_data_scene(C);
2138         Editing *ed = BKE_sequencer_editing_get(scene, false);
2139
2140         Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); /* last_seq checks (ed == NULL) */
2141
2142         if (last_seq == NULL || last_seq->type != SEQ_TYPE_META)
2143                 return OPERATOR_CANCELLED;
2144
2145         BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase);
2146
2147         BLI_listbase_clear(&last_seq->seqbase);
2148
2149         BLI_remlink(ed->seqbasep, last_seq);
2150         BKE_sequence_free(scene, last_seq);
2151
2152         /* emtpy meta strip, delete all effects depending on it */
2153         for (seq = ed->seqbasep->first; seq; seq = seq->next)
2154                 if ((seq->type & SEQ_TYPE_EFFECT) && seq_depends_on_meta(seq, last_seq))
2155                         seq->flag |= SEQ_FLAG_DELETE;
2156
2157         recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0);
2158
2159         /* test for effects and overlap
2160          * don't use SEQP_BEGIN since that would be recursive */
2161         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2162                 if (seq->flag & SELECT) {
2163                         seq->flag &= ~SEQ_OVERLAP;
2164                         if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
2165                                 BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
2166                         }
2167                 }
2168         }
2169
2170         BKE_sequencer_sort(scene);
2171         BKE_sequencer_update_muting(ed);
2172
2173         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2174
2175         return OPERATOR_FINISHED;
2176 }
2177
2178 void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
2179 {
2180         /* identifiers */
2181         ot->name = "UnMeta Strip";
2182         ot->idname = "SEQUENCER_OT_meta_separate";
2183         ot->description = "Put the contents of a metastrip back in the sequencer";
2184         
2185         /* api callbacks */
2186         ot->exec = sequencer_meta_separate_exec;
2187         ot->poll = sequencer_edit_poll;
2188         
2189         /* flags */
2190         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2191 }
2192
2193 /* view_all operator */
2194 static int sequencer_view_all_exec(bContext *C, wmOperator *op)
2195 {
2196         ARegion *ar = CTX_wm_region(C);
2197         View2D *v2d = UI_view2d_fromcontext(C);
2198         const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
2199
2200         UI_view2d_smooth_view(C, ar, &v2d->tot, smooth_viewtx);
2201         return OPERATOR_FINISHED;
2202 }
2203
2204 void SEQUENCER_OT_view_all(wmOperatorType *ot)
2205 {
2206         /* identifiers */
2207         ot->name = "View All";
2208         ot->idname = "SEQUENCER_OT_view_all";
2209         ot->description = "View all the strips in the sequencer";
2210         
2211         /* api callbacks */
2212         ot->exec = sequencer_view_all_exec;
2213         ot->poll = ED_operator_sequencer_active;
2214         
2215         /* flags */
2216         ot->flag = OPTYPE_REGISTER;
2217 }
2218
2219 /* view_all operator */
2220 static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op))
2221 {
2222         bScreen *sc = CTX_wm_screen(C);
2223         ScrArea *area = CTX_wm_area(C);
2224 #if 0
2225         ARegion *ar = CTX_wm_region(C);
2226         SpaceSeq *sseq = area->spacedata.first;
2227         Scene *scene = CTX_data_scene(C);
2228 #endif
2229         View2D *v2d = UI_view2d_fromcontext(C);
2230
2231         v2d->cur = v2d->tot;
2232         UI_view2d_curRect_validate(v2d);
2233         UI_view2d_sync(sc, area, v2d, V2D_LOCK_COPY);
2234         
2235 #if 0
2236         /* Like zooming on an image view */
2237         float zoomX, zoomY;
2238         int width, height, imgwidth, imgheight;
2239
2240         width = ar->winx;
2241         height = ar->winy;
2242
2243         seq_reset_imageofs(sseq);
2244
2245         imgwidth = (scene->r.size * scene->r.xsch) / 100;
2246         imgheight = (scene->r.size * scene->r.ysch) / 100;
2247
2248         /* Apply aspect, dosnt need to be that accurate */
2249         imgwidth = (int)(imgwidth * (scene->r.xasp / scene->r.yasp));
2250
2251         if (((imgwidth >= width) || (imgheight >= height)) &&
2252             ((width > 0) && (height > 0)))
2253         {
2254                 /* Find the zoom value that will fit the image in the image space */
2255                 zoomX = ((float)width) / ((float)imgwidth);
2256                 zoomY = ((float)height) / ((float)imgheight);
2257                 sseq->zoom = (zoomX < zoomY) ? zoomX : zoomY;
2258
2259                 sseq->zoom = 1.0f / power_of_2(1 / min_ff(zoomX, zoomY));
2260         }
2261         else {
2262                 sseq->zoom = 1.0f;
2263         }
2264 #endif
2265
2266         ED_area_tag_redraw(CTX_wm_area(C));
2267         return OPERATOR_FINISHED;
2268 }
2269
2270 void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
2271 {
2272         /* identifiers */
2273         ot->name = "View All";
2274         ot->idname = "SEQUENCER_OT_view_all_preview";
2275         ot->description = "Zoom preview to fit in the area";
2276         
2277         /* api callbacks */
2278         ot->exec = sequencer_view_all_preview_exec;
2279         ot->poll = ED_operator_sequencer_active;
2280         
2281         /* flags */
2282         ot->flag = OPTYPE_REGISTER;
2283 }
2284
2285
2286 static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
2287 {
2288         RenderData *rd = &CTX_data_scene(C)->r;
2289         View2D *v2d = UI_view2d_fromcontext(C);
2290
2291         float ratio = RNA_float_get(op->ptr, "ratio");
2292
2293         float winx = (int)(rd->size * rd->xsch) / 100;
2294         float winy = (int)(rd->size * rd->ysch) / 100;
2295
2296         float facx = BLI_rcti_size_x(&v2d->mask) / winx;
2297         float facy = BLI_rcti_size_y(&v2d->mask) / winy;
2298
2299         BLI_rctf_resize(&v2d->cur, floorf(winx * facx / ratio + 0.5f), floorf(winy * facy / ratio + 0.5f));
2300
2301         ED_region_tag_redraw(CTX_wm_region(C));
2302
2303         return OPERATOR_FINISHED;
2304 }
2305
2306 void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
2307 {
2308         /* identifiers */
2309         ot->name = "Sequencer View Zoom Ratio";
2310         ot->idname = "SEQUENCER_OT_view_zoom_ratio";
2311         ot->description = "Change zoom ratio of sequencer preview";
2312
2313         /* api callbacks */
2314         ot->exec = sequencer_view_zoom_ratio_exec;
2315         ot->poll = ED_operator_sequencer_active;
2316
2317         /* properties */
2318         RNA_def_float(ot->srna, "ratio", 1.0f, -FLT_MAX, FLT_MAX,
2319                       "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX);
2320 }
2321
2322
2323 #if 0
2324 static EnumPropertyItem view_type_items[] = {
2325         {SEQ_VIEW_SEQUENCE, "SEQUENCER", ICON_SEQ_SEQUENCER, "Sequencer", ""},
2326         {SEQ_VIEW_PREVIEW,  "PREVIEW", ICON_SEQ_PREVIEW, "Image Preview", ""},
2327         {SEQ_VIEW_SEQUENCE_PREVIEW,  "SEQUENCER_PREVIEW", ICON_SEQ_SEQUENCER, "Sequencer and Image Preview", ""},
2328         {0, NULL, 0, NULL, NULL}
2329 };
2330 #endif
2331
2332 /* view_all operator */
2333 static int sequencer_view_toggle_exec(bContext *C, wmOperator *UNUSED(op))
2334 {
2335         SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C);
2336
2337         sseq->view++;
2338         if (sseq->view > SEQ_VIEW_SEQUENCE_PREVIEW) sseq->view = SEQ_VIEW_SEQUENCE;
2339
2340         ED_area_tag_refresh(CTX_wm_area(C));
2341
2342         return OPERATOR_FINISHED;
2343 }
2344
2345 void SEQUENCER_OT_view_toggle(wmOperatorType *ot)
2346 {
2347         /* identifiers */
2348         ot->name = "View Toggle";
2349         ot->idname = "SEQUENCER_OT_view_toggle";
2350         ot->description = "Toggle between sequencer views (sequence, preview, both)";
2351         
2352         /* api callbacks */
2353         ot->exec = sequencer_view_toggle_exec;
2354         ot->poll = ED_operator_sequencer_active;
2355         
2356         /* flags */
2357         ot->flag = OPTYPE_REGISTER;
2358 }
2359
2360
2361 /* view_selected operator */
2362 static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
2363 {
2364         Scene *scene = CTX_data_scene(C);
2365         View2D *v2d = UI_view2d_fromcontext(C);
2366         ARegion *ar = CTX_wm_region(C);
2367         Editing *ed = BKE_sequencer_editing_get(scene, false);
2368         Sequence *last_seq = BKE_sequencer_active_get(scene);
2369         Sequence *seq;
2370         rctf cur_new = v2d->cur;
2371
2372         int xmin =  MAXFRAME * 2;
2373         int xmax = -MAXFRAME * 2;
2374         int ymin =  MAXSEQ + 1;
2375         int ymax = 0;
2376         int orig_height;
2377         int ymid;
2378         int ymargin = 1;
2379         int xmargin = FPS;
2380
2381         if (ed == NULL)
2382                 return OPERATOR_CANCELLED;
2383
2384         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2385                 if ((seq->flag & SELECT) || (seq == last_seq)) {
2386                         xmin = min_ii(xmin, seq->startdisp);
2387                         xmax = max_ii(xmax, seq->enddisp);
2388
2389                         ymin = min_ii(ymin, seq->machine);
2390                         ymax = max_ii(ymax, seq->machine);
2391                 }
2392         }
2393
2394         if (ymax != 0) {
2395                 const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
2396                 
2397                 xmax += xmargin;
2398                 xmin -= xmargin;
2399                 ymax += ymargin;
2400                 ymin -= ymargin;
2401
2402                 orig_height = BLI_rctf_size_y(&cur_new);
2403
2404                 cur_new.xmin = xmin;
2405                 cur_new.xmax = xmax;
2406
2407                 cur_new.ymin = ymin;
2408                 cur_new.ymax = ymax;
2409
2410                 /* only zoom out vertically */
2411                 if (orig_height > BLI_rctf_size_y(&cur_new)) {
2412                         ymid = BLI_rctf_cent_y(&cur_new);
2413
2414                         cur_new.ymin = ymid - (orig_height / 2);
2415                         cur_new.ymax = ymid + (orig_height / 2);
2416                 }
2417
2418                 UI_view2d_smooth_view(C, ar, &cur_new, smooth_viewtx);
2419
2420                 return OPERATOR_FINISHED;
2421         }
2422         else {
2423                 return OPERATOR_CANCELLED;
2424         }
2425         
2426 }
2427
2428 void SEQUENCER_OT_view_selected(wmOperatorType *ot)
2429 {
2430         /* identifiers */
2431         ot->name = "View Selected";
2432         ot->idname = "SEQUENCER_OT_view_selected";
2433         ot->description = "Zoom the sequencer on the selected strips";
2434         
2435         /* api callbacks */
2436         ot->exec = sequencer_view_selected_exec;
2437         ot->poll = ED_operator_sequencer_active;
2438         
2439         /* flags */
2440         ot->flag = OPTYPE_REGISTER;
2441 }
2442
2443
2444 static int find_next_prev_edit(Scene *scene, int cfra,
2445                                const short side,
2446                                const bool do_skip_mute, const bool do_center)
2447 {
2448         Editing *ed = BKE_sequencer_editing_get(scene, false);
2449         Sequence *seq, *best_seq = NULL, *frame_seq = NULL;
2450         
2451         int dist, best_dist;
2452         best_dist = MAXFRAME * 2;
2453
2454         if (ed == NULL) return cfra;
2455         
2456         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2457                 int seq_frame;
2458
2459                 if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
2460                         continue;
2461                 }
2462
2463                 if (do_center) {
2464                         seq_frame = (seq->startdisp + seq->enddisp) / 2;
2465                 }
2466                 else {
2467                         seq_frame = seq->startdisp;
2468                 }
2469
2470                 dist = MAXFRAME * 2;
2471                         
2472                 switch (side) {
2473                         case SEQ_SIDE_LEFT:
2474                                 if (seq_frame < cfra) {
2475                                         dist = cfra - seq_frame;
2476                                 }
2477                                 break;
2478                         case SEQ_SIDE_RIGHT:
2479                                 if (seq_frame > cfra) {
2480                                         dist = seq_frame - cfra;
2481                                 }
2482                                 else if (seq_frame == cfra) {
2483                                         frame_seq = seq;
2484                                 }
2485                                 break;
2486                 }
2487
2488                 if (dist < best_dist) {
2489                         best_dist = dist;
2490                         best_seq = seq;
2491                 }
2492         }
2493
2494         /* if no sequence to the right is found and the
2495          * frame is on the start of the last sequence,
2496          * move to the end of the last sequence */
2497         if (frame_seq) {
2498                 if (do_center) {
2499                         cfra = (frame_seq->startdisp + frame_seq->enddisp) / 2;
2500                 }
2501                 else {
2502                         cfra = frame_seq->enddisp;
2503                 }
2504         }
2505
2506         if (best_seq) {
2507                 if (do_center) {
2508                         cfra = (best_seq->startdisp + best_seq->enddisp) / 2;
2509                 }
2510                 else {
2511                         cfra = best_seq->startdisp;
2512                 }
2513         }
2514
2515         return cfra;
2516 }
2517
2518 static bool strip_jump_internal(Scene *scene,
2519                                 const short side,
2520                                 const bool do_skip_mute, const bool do_center)
2521 {
2522         bool changed = false;
2523         int cfra = CFRA;
2524         int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center);
2525         
2526         if (nfra != cfra) {
2527                 CFRA = nfra;
2528                 changed = true;
2529         }
2530
2531         return changed;
2532 }
2533
2534 static int sequencer_strip_jump_poll(bContext *C)
2535 {
2536         /* prevent changes during render */
2537         if (G.is_rendering)
2538                 return 0;
2539
2540         return sequencer_edit_poll(C);
2541 }
2542
2543 /* jump frame to edit point operator */
2544 static int sequencer_strip_jump_exec(bContext *C, wmOperator *op)
2545 {
2546         Scene *scene = CTX_data_scene(C);
2547         const bool next = RNA_boolean_get(op->ptr, "next");
2548         const bool center = RNA_boolean_get(op->ptr, "center");
2549
2550         /* currently do_skip_mute is always true */
2551         if (!strip_jump_internal(scene, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, true, center)) {
2552                 return OPERATOR_CANCELLED;
2553         }
2554
2555         WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
2556         
2557         return OPERATOR_FINISHED;
2558 }
2559
2560 void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
2561 {
2562         /* identifiers */
2563         ot->name = "Jump to Strip";
2564         ot->idname = "SEQUENCER_OT_strip_jump";
2565         ot->description = "Move frame to previous edit point";
2566
2567         /* api callbacks */
2568         ot->exec = sequencer_strip_jump_exec;
2569         ot->poll = sequencer_strip_jump_poll;
2570
2571         /* flags */
2572         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2573         
2574         /* properties */
2575         RNA_def_boolean(ot->srna, "next", true, "Next Strip", "");
2576         RNA_def_boolean(ot->srna, "center", true, "Use strip center", "");
2577 }
2578
2579 static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
2580 {
2581         int gap = seqb->startdisp - seqa->enddisp;
2582         int seq_a_start;
2583         int seq_b_start;
2584
2585         seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp;
2586         BKE_sequence_translate(scene, seqb, seq_b_start - seqb->start);
2587         BKE_sequence_calc(scene, seqb);
2588
2589         seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
2590         BKE_sequence_translate(scene, seqa, seq_a_start - seqa->start);
2591         BKE_sequence_calc(scene, seqa);
2592 }
2593
2594 #if 0
2595 static Sequence *sequence_find_parent(Scene *scene, Sequence *child)
2596 {
2597         Editing *ed = BKE_sequencer_editing_get(scene, false);
2598         Sequence *parent = NULL;
2599         Sequence *seq;
2600
2601         if (ed == NULL) return NULL;
2602
2603         for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2604                 if ((seq != child) && seq_is_parent(seq, child)) {
2605                         parent = seq;
2606                         break;
2607                 }
2608         }
2609
2610         return parent;
2611 }
2612 #endif
2613
2614 static int sequencer_swap_exec(bContext *C, wmOperator *op)
2615 {
2616         Scene *scene = CTX_data_scene(C);
2617         Editing *ed = BKE_sequencer_editing_get(scene, false);
2618         Sequence *active_seq = BKE_sequencer_active_get(scene);
2619         Sequence *seq, *iseq;
2620         int side = RNA_enum_get(op->ptr, "side");
2621
2622         if (active_seq == NULL) return OPERATOR_CANCELLED;
2623
2624         seq = find_next_prev_sequence(scene, active_seq, side, -1);
2625         
2626         if (seq) {
2627                 
2628                 /* disallow effect strips */
2629                 if (BKE_sequence_effect_get_num_inputs(seq->type) >= 1 && (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3))
2630                         return OPERATOR_CANCELLED;
2631                 if ((BKE_sequence_effect_get_num_inputs(active_seq->type) >= 1) && (active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3))
2632                         return OPERATOR_CANCELLED;
2633
2634                 switch (side) {
2635                         case SEQ_SIDE_LEFT: 
2636                                 swap_sequence(scene, seq, active_seq);
2637                                 break;
2638                         case SEQ_SIDE_RIGHT: 
2639                                 swap_sequence(scene, active_seq, seq);
2640                                 break;
2641                 }
2642
2643                 // XXX - should be a generic function
2644                 for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
2645                         if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
2646                                 BKE_sequence_calc(scene, iseq);
2647                         }
2648                 }
2649
2650                 /* do this in a new loop since both effects need to be calculated first */
2651                 for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
2652                         if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
2653                                 /* this may now overlap */
2654                                 if (BKE_sequence_test_overlap(ed->seqbasep, iseq) ) {
2655                                         BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene);
2656                                 }
2657                         }
2658                 }
2659
2660
2661
2662                 BKE_sequencer_sort(scene);
2663
2664                 WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2665
2666                 return OPERATOR_FINISHED;
2667         }
2668
2669         return OPERATOR_CANCELLED;
2670 }
2671
2672 void SEQUENCER_OT_swap(wmOperatorType *ot)
2673 {
2674         /* identifiers */
2675         ot->name = "Swap Strip";
2676         ot->idname = "SEQUENCER_OT_swap";
2677         ot->description = "Swap active strip with strip to the right or left";
2678         
2679         /* api callbacks */
2680         ot->exec = sequencer_swap_exec;
2681         ot->poll = sequencer_edit_poll;
2682         
2683         /* flags */
2684         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2685         
2686         /* properties */
2687         RNA_def_enum(ot->srna, "side", prop_side_lr_types, SEQ_SIDE_RIGHT, "Side", "Side of the strip to swap");
2688 }
2689
2690 static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op))
2691 {
2692         int retval = OPERATOR_CANCELLED;
2693         Scene *scene = CTX_data_scene(C);
2694         Sequence *active_seq = BKE_sequencer_active_get(scene);
2695         StripElem *se = NULL;
2696
2697         if (active_seq == NULL)
2698                 return OPERATOR_CANCELLED;
2699
2700
2701         if (active_seq->strip) {
2702                 switch (active_seq->type) {
2703                         case SEQ_TYPE_IMAGE:
2704                                 se = BKE_sequencer_give_stripelem(active_seq, scene->r.cfra);
2705                                 break;
2706                         case SEQ_TYPE_MOVIE:
2707                                 se = active_seq->strip->stripdata;
2708                                 break;
2709                         case SEQ_TYPE_SCENE:
2710                         case SEQ_TYPE_META:
2711                         case SEQ_TYPE_SOUND_RAM:
2712                         case SEQ_TYPE_SOUND_HD:
2713                         default:
2714                                 break;
2715                 }
2716         }
2717
2718         if (se) {
2719                 // prevent setting the render size if sequence values aren't initialized
2720                 if ((se->orig_width > 0) && (se->orig_height > 0)) {
2721                         scene->r.xsch = se->orig_width;
2722                         scene->r.ysch = se->orig_height;
2723                         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
2724                         retval = OPERATOR_FINISHED;
2725                 }
2726         }
2727
2728         return retval;
2729 }
2730
2731 void SEQUENCER_OT_rendersize(wmOperatorType *ot)
2732 {
2733         /* identifiers */
2734         ot->name = "Set Render Size";
2735         ot->idname = "SEQUENCER_OT_rendersize";
2736         ot->description = "Set render size and aspect from active sequence";
2737         
2738         /* api callbacks */
2739         ot->exec = sequencer_rendersize_exec;
2740         ot->poll = sequencer_edit_poll;
2741         
2742         /* flags */
2743         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2744         
2745         /* properties */
2746 }
2747
2748 static void seq_copy_del_sound(Scene *scene, Sequence *seq)
2749 {
2750         if (seq->type == SEQ_TYPE_META) {
2751                 Sequence *iseq;
2752                 for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) {
2753                         seq_copy_del_sound(scene, iseq);
2754                 }
2755         }
2756         else if (seq->scene_sound) {
2757                 sound_remove_scene_sound(scene, seq->scene_sound);
2758                 seq->scene_sound = NULL;
2759         }
2760 }
2761
2762 static int sequencer_copy_exec(bContext *C, wmOperator *op)
2763 {
2764         Scene *scene = CTX_data_scene(C);
2765         Editing *ed = BKE_sequencer_editing_get(scene, false);
2766
2767         ListBase nseqbase = {NULL, NULL};
2768
2769         BKE_sequencer_free_clipboard();
2770
2771         if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
2772                 BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
2773                 return OPERATOR_CANCELLED;
2774         }
2775
2776         BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME);
2777
2778         /* To make sure the copied strips have unique names between each other add
2779          * them temporarily to the end of the original seqbase. (bug 25932)
2780          */
2781         if (nseqbase.first) {
2782                 Sequence *seq, *first_seq = nseqbase.first;
2783                 BLI_movelisttolist(ed->seqbasep, &nseqbase);
2784
2785                 for (seq = first_seq; seq; seq = seq->next)
2786                         BKE_sequencer_recursive_apply(seq, apply_unique_name_cb, scene);
2787
2788                 seqbase_clipboard.first = first_seq;
2789                 seqbase_clipboard.last = ed->seqbasep->last;
2790
2791                 if (first_seq->prev) {
2792                         first_seq->prev->next = NULL;
2793                         ed->seqbasep->last = first_seq->prev;
2794                         first_seq->prev = NULL;
2795                 }
2796         }
2797
2798         seqbase_clipboard_frame = scene->r.cfra;
2799
2800         /* Need to remove anything that references the current scene */
2801         {
2802                 Sequence *seq;
2803                 for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
2804                         seq_copy_del_sound(scene, seq);
2805                 }
2806
2807                 /* duplicate pointers */
2808                 for (seq = seqbase_clipboard.first; seq; seq = seq->next) {
2809                         BKE_sequence_clipboard_pointers_store(seq);
2810                 }
2811         }
2812
2813         return OPERATOR_FINISHED;
2814 }
2815
2816 void SEQUENCER_OT_copy(wmOperatorType *ot)
2817 {
2818         /* identifiers */
2819         ot->name = "Copy";
2820         ot->idname = "SEQUENCER_OT_copy";
2821         ot->description = "";
2822
2823         /* api callbacks */
2824         ot->exec = sequencer_copy_exec;
2825         ot->poll = sequencer_edit_poll;
2826
2827         /* flags */
2828         ot->flag = OPTYPE_REGISTER;
2829
2830         /* properties */
2831 }
2832
2833 static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
2834 {
2835         Main *bmain = CTX_data_main(C);
2836         Scene *scene = CTX_data_scene(C);
2837         Editing *ed = BKE_sequencer_editing_get(scene, true); /* create if needed */
2838         ListBase nseqbase = {NULL, NULL};
2839         int ofs;
2840         Sequence *iseq, *iseq_first;
2841
2842         ED_sequencer_deselect_all(scene);
2843         ofs = scene->r.cfra - seqbase_clipboard_frame;
2844
2845         BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME);
2846
2847         /* transform pasted strips before adding */
2848         if (ofs) {
2849                 for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
2850                         BKE_sequence_translate(scene, iseq, ofs);
2851                 }
2852         }
2853
2854         for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
2855                 BKE_sequence_clipboard_pointers_restore(iseq, bmain);
2856         }
2857
2858         for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
2859                 BKE_sequence_sound_init(scene, iseq);
2860         }
2861
2862         iseq_first = nseqbase.first;
2863
2864         BLI_movelisttolist(ed->seqbasep, &nseqbase);
2865
2866         /* make sure the pasted strips have unique names between them */
2867         for (iseq = iseq_first; iseq; iseq = iseq->next) {
2868                 BKE_sequencer_recursive_apply(iseq, apply_unique_name_cb, scene);
2869         }
2870
2871         /* ensure pasted strips don't overlap */
2872         for (iseq = iseq_first; iseq; iseq = iseq->next) {
2873                 if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) {
2874                         BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene);
2875                 }
2876         }
2877
2878         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2879
2880         return OPERATOR_FINISHED;
2881 }
2882
2883 void SEQUENCER_OT_paste(wmOperatorType *ot)
2884 {
2885         /* identifiers */
2886         ot->name = "Paste";
2887         ot->idname = "SEQUENCER_OT_paste";
2888         ot->description = "";
2889
2890         /* api callbacks */
2891         ot->exec = sequencer_paste_exec;
2892         ot->poll = ED_operator_sequencer_active;
2893
2894         /* flags */
2895         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2896
2897         /* properties */
2898 }
2899
2900 static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
2901 {
2902         Scene *scene = CTX_data_scene(C);
2903         Sequence *seq_act;
2904         Sequence *seq_other;
2905         const char *error_msg;
2906
2907         if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) {
2908                 BKE_report(op->reports, RPT_ERROR, "Please select two strips");
2909                 return OPERATOR_CANCELLED;
2910         }
2911
2912         if (BKE_sequence_swap(seq_act, seq_other, &error_msg) == 0) {
2913                 BKE_report(op->reports, RPT_ERROR, error_msg);
2914                 return OPERATOR_CANCELLED;
2915         }
2916
2917         if (seq_act->scene_sound)
2918                 sound_remove_scene_sound(scene, seq_act->scene_sound);
2919
2920         if (seq_other->scene_sound)
2921                 sound_remove_scene_sound(scene, seq_other->scene_sound);
2922
2923         seq_act->scene_sound = NULL;
2924         seq_other->scene_sound = NULL;
2925
2926         BKE_sequence_calc(scene, seq_act);
2927         BKE_sequence_calc(scene, seq_other);
2928
2929         if (seq_act->sound) sound_add_scene_sound_defaults(scene, seq_act);
2930         if (seq_other->sound) sound_add_scene_sound_defaults(scene, seq_other);
2931
2932         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2933
2934         return OPERATOR_FINISHED;
2935 }
2936
2937 void SEQUENCER_OT_swap_data(wmOperatorType *ot)
2938 {
2939         /* identifiers */
2940         ot->name = "Sequencer Swap Data";
2941         ot->idname = "SEQUENCER_OT_swap_data";
2942         ot->description = "Swap 2 sequencer strips";
2943
2944         /* api callbacks */
2945         ot->exec = sequencer_swap_data_exec;
2946         ot->poll = ED_operator_sequencer_active;
2947
2948         /* flags */
2949         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2950
2951         /* properties */
2952 }
2953
2954 /* borderselect operator */
2955 static int view_ghost_border_exec(bContext *C, wmOperator *op)
2956 {
2957         Scene *scene = CTX_data_scene(C);
2958         View2D *v2d = UI_view2d_fromcontext(C);
2959
2960         rctf rect;
2961
2962         /* convert coordinates of rect to 'tot' rect coordinates */
2963         WM_operator_properties_border_to_rctf(op, &rect);
2964         UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
2965
2966         rect.xmin /=  fabsf(BLI_rctf_size_x(&v2d->tot));
2967         rect.ymin /=  fabsf(BLI_rctf_size_y(&v2d->tot));
2968
2969         rect.xmax /=  fabsf(BLI_rctf_size_x(&v2d->tot));
2970         rect.ymax /=  fabsf(BLI_rctf_size_y(&v2d->tot));
2971
2972         rect.xmin += 0.5f;
2973         rect.xmax += 0.5f;
2974         rect.ymin += 0.5f;
2975         rect.ymax += 0.5f;
2976
2977         CLAMP(rect.xmin, 0.0f, 1.0f);
2978         CLAMP(rect.ymin, 0.0f, 1.0f);
2979         CLAMP(rect.xmax, 0.0f, 1.0f);
2980         CLAMP(rect.ymax, 0.0f, 1.0f);
2981
2982         scene->ed->over_border = rect;
2983
2984         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2985
2986         return OPERATOR_FINISHED;
2987 }
2988
2989 /* ****** Border Select ****** */
2990 void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
2991 {
2992         /* identifiers */
2993         ot->name = "Border Offset View";
2994         ot->idname = "SEQUENCER_OT_view_ghost_border";
2995         ot->description = "Set the boundaries of the border used for offset-view";
2996
2997         /* api callbacks */
2998         ot->invoke = WM_border_select_invoke;
2999         ot->exec = view_ghost_border_exec;
3000         ot->modal = WM_border_select_modal;
3001         ot->poll = sequencer_view_poll;
3002         ot->cancel = WM_border_select_cancel;
3003
3004         /* flags */
3005         ot->flag = 0;
3006
3007         /* rna */
3008         WM_operator_properties_gesture_border(ot, false);
3009 }
3010
3011 /* rebuild_proxy operator */
3012 static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
3013 {
3014         seq_proxy_build_job(C);
3015
3016         return OPERATOR_FINISHED;
3017 }
3018
3019 void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot)
3020 {
3021         /* identifiers */
3022         ot->name = "Rebuild Proxy and Timecode Indices";
3023         ot->idname = "SEQUENCER_OT_rebuild_proxy";
3024         ot->description = "Rebuild all selected proxies and timecode indices using the job system";
3025         
3026         /* api callbacks */
3027         ot->exec = sequencer_rebuild_proxy_exec;
3028         ot->poll = ED_operator_sequencer_active;
3029         
3030         /* flags */
3031         ot->flag = OPTYPE_REGISTER;
3032 }
3033
3034 /* change ops */
3035
3036 static EnumPropertyItem prop_change_effect_input_types[] = {
3037         {0, "A_B", 0, "A -> B", ""},
3038         {1, "B_C", 0, "B -> C", ""},
3039         {2, "A_C", 0, "A -> C", ""},
3040         {0, NULL, 0, NULL, NULL}
3041 };
3042
3043 static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op)
3044 {
3045         Scene *scene = CTX_data_scene(C);
3046         Editing *ed = BKE_sequencer_editing_get(scene, false);
3047         Sequence *seq = BKE_sequencer_active_get(scene);
3048
3049         Sequence **seq_1, **seq_2;
3050
3051         switch (RNA_enum_get(op->ptr, "swap")) {
3052                 case 0:
3053                         seq_1 = &seq->seq1;
3054                         seq_2 = &seq->seq2;
3055                         break;
3056                 case 1:
3057                         seq_1 = &seq->seq2;
3058                         seq_2 = &seq->seq3;
3059                         break;
3060                 default: /* 2 */
3061                         seq_1 = &seq->seq1;
3062                         seq_2 = &seq->seq3;
3063                         break;
3064         }
3065
3066         if (*seq_1 == NULL || *seq_2 == NULL) {
3067                 BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, cannot swap");
3068                 return OPERATOR_CANCELLED;
3069         }
3070         else {
3071                 SWAP(Sequence *, *seq_1, *seq_2);
3072         }
3073
3074         BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
3075
3076         /* important else we don't get the imbuf cache flushed */
3077         BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
3078
3079         WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
3080
3081         return OPERATOR_FINISHED;
3082 }
3083
3084 void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot)
3085 {
3086         /* identifiers */
3087         ot->name = "Change Effect Input";
3088         ot->idname = "SEQUENCER_OT_change_effect_input";
3089         ot->description = "";
3090
3091         /* api callbacks */
3092         ot->exec = sequencer_change_effect_input_exec;
3093         ot->poll = sequencer_effect_poll;
3094
3095         /* flags */
3096         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3097
3098         ot->prop = RNA_def_enum(ot->srna, "swap", prop_change_effect_input_types, 0, "Swap", "The effect inputs to swap");
3099 }
3100
3101 static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
3102 {
3103         Scene *scene = CTX_data_scene(C);
3104         Editing *ed = BKE_sequencer_editing_get(scene, false);
3105         Sequence *seq = BKE_sequencer_active_get(scene);
3106         const int new_type = RNA_enum_get(op->ptr, "type");
3107
3108         /* free previous effect and init new effect */
3109         struct SeqEffectHandle sh;
3110
3111         if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
3112                 return OPERATOR_CANCELLED;
3113         }
3114
3115         /* can someone explain the logic behind only allowing to increase this,
3116          * copied from 2.4x - campbell */
3117         if (BKE_sequence_effect_get_num_inputs(seq->type) <
3118             BKE_sequence_effect_get_num_inputs(new_type))
3119         {
3120                 BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips");
3121                 return OPERATOR_CANCELLED;
3122         }
3123         else {
3124                 sh = BKE_sequence_get_effect(seq);
3125                 sh.free(seq);
3126
3127                 seq->type = new_type;
3128
3129                 sh = BKE_sequence_get_effect(seq);