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