b32f73323b27a09f541a74955c14781806bc7bf1
[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(
730     Main *bmain, Scene *scene, Sequence *seq, ListBase *new_seq_list, int cutframe)
731 {
732   TransSeq ts;
733   Sequence *seqn = NULL;
734   bool skip_dup = false;
735
736   /* Unlike soft-cut, it's important to use the same value for both strips. */
737   const bool is_end_exact = ((seq->start + seq->len) == cutframe);
738
739   /* backup values */
740   ts.start = seq->start;
741   ts.machine = seq->machine;
742   ts.startstill = seq->startstill;
743   ts.endstill = seq->endstill;
744   ts.startdisp = seq->startdisp;
745   ts.enddisp = seq->enddisp;
746   ts.startofs = seq->startofs;
747   ts.endofs = seq->endofs;
748   ts.anim_startofs = seq->anim_startofs;
749   ts.anim_endofs = seq->anim_endofs;
750   ts.len = seq->len;
751
752   /* First Strip! */
753   /* strips with extended stillfames before */
754
755   /* Precaution, needed because the length saved on-disk may not match the length saved in the
756    * blend file, or our code may have minor differences reading file length between versions.
757    * This causes hard-cut to fail, see: T47862 */
758   if (seq->type != SEQ_TYPE_META) {
759     BKE_sequence_reload_new_file(bmain, scene, seq, true);
760     BKE_sequence_calc(scene, seq);
761   }
762
763   /* Important to offset the start when 'cutframe == seq->start'
764    * because we need at least one frame of content after start/end still have clipped it. */
765   if ((seq->startstill) && (cutframe <= seq->start)) {
766     /* don't do funny things with METAs ... */
767     if (seq->type == SEQ_TYPE_META) {
768       skip_dup = true;
769       seq->startstill = seq->start - cutframe;
770     }
771     else {
772       seq->start = cutframe - 1;
773       seq->startstill = cutframe - seq->startdisp - 1;
774       seq->anim_endofs += seq->len - 1;
775       seq->endstill = 0;
776     }
777   }
778   /* normal strip */
779   else if ((is_end_exact == false) &&
780            ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len)))) {
781     seq->endofs = 0;
782     seq->endstill = 0;
783     seq->anim_endofs += (seq->start + seq->len) - cutframe;
784   }
785   /* strips with extended stillframes after */
786   else if ((is_end_exact == true) || (((seq->start + seq->len) < cutframe) && (seq->endstill))) {
787     seq->endstill -= seq->enddisp - cutframe;
788     /* don't do funny things with METAs ... */
789     if (seq->type == SEQ_TYPE_META) {
790       skip_dup = true;
791     }
792   }
793
794   BKE_sequence_reload_new_file(bmain, scene, seq, false);
795   BKE_sequence_calc(scene, seq);
796
797   if (!skip_dup) {
798     /* Duplicate AFTER the first change */
799     seqn = BKE_sequence_dupli_recursive(
800         scene, scene, new_seq_list, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
801   }
802
803   if (seqn) {
804     seqn->flag |= SELECT;
805
806     /* Important not to re-assign this (unlike soft-cut) */
807 #if 0
808     is_end_exact = ((seqn->start + seqn->len) == cutframe);
809 #endif
810     /* Second Strip! */
811     /* strips with extended stillframes before */
812     if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
813       seqn->start = ts.start;
814       seqn->startstill = ts.start - cutframe;
815       seqn->anim_endofs = ts.anim_endofs;
816       seqn->endstill = ts.endstill;
817     }
818
819     /* normal strip */
820     else if ((is_end_exact == false) &&
821              ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len)))) {
822       seqn->start = cutframe;
823       seqn->startstill = 0;
824       seqn->startofs = 0;
825       seqn->endofs = ts.endofs;
826       seqn->anim_startofs += cutframe - ts.start;
827       seqn->anim_endofs = ts.anim_endofs;
828       seqn->endstill = ts.endstill;
829     }
830
831     /* strips with extended stillframes after */
832     else if ((is_end_exact == true) ||
833              (((seqn->start + seqn->len) < cutframe) && (seqn->endstill))) {
834       seqn->start = cutframe;
835       seqn->startofs = 0;
836       seqn->anim_startofs += ts.len - 1;
837       seqn->endstill = ts.enddisp - cutframe - 1;
838       seqn->startstill = 0;
839     }
840
841     BKE_sequence_reload_new_file(bmain, scene, seqn, false);
842     BKE_sequence_calc(scene, seqn);
843   }
844   return seqn;
845 }
846
847 static Sequence *cut_seq_soft(
848     Main *UNUSED(bmain), Scene *scene, Sequence *seq, ListBase *new_seq_list, int cutframe)
849 {
850   TransSeq ts;
851   Sequence *seqn = NULL;
852   bool skip_dup = false;
853
854   bool is_end_exact = ((seq->start + seq->len) == cutframe);
855
856   /* backup values */
857   ts.start = seq->start;
858   ts.machine = seq->machine;
859   ts.startstill = seq->startstill;
860   ts.endstill = seq->endstill;
861   ts.startdisp = seq->startdisp;
862   ts.enddisp = seq->enddisp;
863   ts.startofs = seq->startofs;
864   ts.endofs = seq->endofs;
865   ts.anim_startofs = seq->anim_startofs;
866   ts.anim_endofs = seq->anim_endofs;
867   ts.len = seq->len;
868
869   /* First Strip! */
870   /* strips with extended stillfames before */
871
872   /* Important to offset the start when 'cutframe == seq->start'
873    * because we need at least one frame of content after start/end still have clipped it. */
874   if ((seq->startstill) && (cutframe <= seq->start)) {
875     /* don't do funny things with METAs ... */
876     if (seq->type == SEQ_TYPE_META) {
877       skip_dup = true;
878       seq->startstill = seq->start - cutframe;
879     }
880     else {
881       seq->start = cutframe - 1;
882       seq->startstill = cutframe - seq->startdisp - 1;
883       seq->endofs = seq->len - 1;
884       seq->endstill = 0;
885     }
886   }
887   /* normal strip */
888   else if ((is_end_exact == false) && (cutframe >= seq->start) &&
889            (cutframe <= (seq->start + seq->len))) {
890     seq->endofs = (seq->start + seq->len) - cutframe;
891   }
892   /* strips with extended stillframes after */
893   else if ((is_end_exact == true) || (((seq->start + seq->len) < cutframe) && (seq->endstill))) {
894     seq->endstill -= seq->enddisp - cutframe;
895     /* don't do funny things with METAs ... */
896     if (seq->type == SEQ_TYPE_META) {
897       skip_dup = true;
898     }
899   }
900
901   BKE_sequence_calc(scene, seq);
902
903   if (!skip_dup) {
904     /* Duplicate AFTER the first change */
905     seqn = BKE_sequence_dupli_recursive(
906         scene, scene, new_seq_list, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
907   }
908
909   if (seqn) {
910     seqn->flag |= SELECT;
911
912     is_end_exact = ((seqn->start + seqn->len) == cutframe);
913
914     /* Second Strip! */
915     /* strips with extended stillframes before */
916     if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
917       seqn->start = ts.start;
918       seqn->startstill = ts.start - cutframe;
919       seqn->endofs = ts.endofs;
920       seqn->endstill = ts.endstill;
921     }
922
923     /* normal strip */
924     else if ((is_end_exact == false) && (cutframe >= seqn->start) &&
925              (cutframe <= (seqn->start + seqn->len))) {
926       seqn->startstill = 0;
927       seqn->startofs = cutframe - ts.start;
928       seqn->endofs = ts.endofs;
929       seqn->endstill = ts.endstill;
930     }
931
932     /* strips with extended stillframes after */
933     else if ((is_end_exact == true) ||
934              (((seqn->start + seqn->len) < cutframe) && (seqn->endstill))) {
935       seqn->start = cutframe - ts.len + 1;
936       seqn->startofs = ts.len - 1;
937       seqn->endstill = ts.enddisp - cutframe - 1;
938       seqn->startstill = 0;
939     }
940
941     BKE_sequence_calc(scene, seqn);
942   }
943   return seqn;
944 }
945
946 /* like duplicate, but only duplicate and cut overlapping strips,
947  * strips to the left of the cutframe are ignored and strips to the right
948  * are moved to the end of slist
949  * we have to work on the same slist (not using a separate list), since
950  * otherwise dupli_seq can't check for duplicate names properly and
951  * may generate strips with the same name (which will mess up animdata)
952  */
953
954 static bool cut_seq_list(Main *bmain,
955                          Scene *scene,
956                          ListBase *slist,
957                          int cutframe,
958                          Sequence *(*cut_seq)(Main *bmain, Scene *, Sequence *, ListBase *, int))
959 {
960   Sequence *seq, *seq_next_iter;
961   Sequence *seq_first_new = NULL;
962
963   seq = slist->first;
964
965   while (seq && seq != seq_first_new) {
966     seq_next_iter = seq->next; /* we need this because we may remove seq */
967     seq->tmp = NULL;
968     if (seq->flag & SELECT) {
969       if (cutframe > seq->startdisp && cutframe < seq->enddisp) {
970         Sequence *seqn = cut_seq(bmain, scene, seq, slist, cutframe);
971         if (seqn) {
972           if (seq_first_new == NULL) {
973             seq_first_new = seqn;
974           }
975         }
976       }
977       else if (seq->enddisp <= cutframe) {
978         /* do nothing */
979       }
980       else if (seq->startdisp >= cutframe) {
981         /* move to tail */
982         BLI_remlink(slist, seq);
983         BLI_addtail(slist, seq);
984
985         if (seq_first_new == NULL) {
986           seq_first_new = seq;
987         }
988       }
989     }
990     seq = seq_next_iter;
991   }
992
993   return (seq_first_new != NULL);
994 }
995
996 static bool sequence_offset_after_frame(Scene *scene, const int delta, const int cfra)
997 {
998   Sequence *seq;
999   Editing *ed = BKE_sequencer_editing_get(scene, false);
1000   bool done = false;
1001   TimeMarker *marker;
1002
1003   /* all strips >= cfra are shifted */
1004
1005   if (ed == NULL) {
1006     return 0;
1007   }
1008
1009   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1010     if (seq->startdisp >= cfra) {
1011       BKE_sequence_translate(scene, seq, delta);
1012       BKE_sequence_calc(scene, seq);
1013       done = true;
1014     }
1015   }
1016
1017   if (!scene->toolsettings->lock_markers) {
1018     for (marker = scene->markers.first; marker; marker = marker->next) {
1019       if (marker->frame >= cfra) {
1020         marker->frame += delta;
1021       }
1022     }
1023   }
1024
1025   return done;
1026 }
1027
1028 #if 0
1029 static void set_filter_seq(Scene *scene)
1030 {
1031   Sequence *seq;
1032   Editing *ed = BKE_sequencer_editing_get(scene, false);
1033
1034   if (ed == NULL) {
1035     return;
1036   }
1037
1038   if (okee("Set Deinterlace") == 0) {
1039     return;
1040   }
1041
1042   SEQP_BEGIN (ed, seq) {
1043     if (seq->flag & SELECT) {
1044       if (seq->type == SEQ_TYPE_MOVIE) {
1045         seq->flag |= SEQ_FILTERY;
1046         BKE_sequence_reload_new_file(bmain, scene, seq, false);
1047         BKE_sequence_calc(scene, seq);
1048       }
1049     }
1050   }
1051   SEQ_END;
1052 }
1053 #endif
1054
1055 static void UNUSED_FUNCTION(seq_remap_paths)(Scene *scene)
1056 {
1057   Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
1058   Editing *ed = BKE_sequencer_editing_get(scene, false);
1059   char from[FILE_MAX], to[FILE_MAX], stripped[FILE_MAX];
1060
1061   if (last_seq == NULL) {
1062     return;
1063   }
1064
1065   BLI_strncpy(from, last_seq->strip->dir, sizeof(from));
1066   // XXX  if (0 == sbutton(from, 0, sizeof(from) - 1, "From: "))
1067   //      return;
1068
1069   BLI_strncpy(to, from, sizeof(to));
1070   // XXX  if (0 == sbutton(to, 0, sizeof(to) - 1, "To: "))
1071   //      return;
1072
1073   if (STREQ(to, from)) {
1074     return;
1075   }
1076
1077   SEQP_BEGIN (ed, seq) {
1078     if (seq->flag & SELECT) {
1079       if (STREQLEN(seq->strip->dir, from, strlen(from))) {
1080         printf("found %s\n", seq->strip->dir);
1081
1082         /* strip off the beginning */
1083         stripped[0] = 0;
1084         BLI_strncpy(stripped, seq->strip->dir + strlen(from), FILE_MAX);
1085
1086         /* new path */
1087         BLI_snprintf(seq->strip->dir, sizeof(seq->strip->dir), "%s%s", to, stripped);
1088         printf("new %s\n", seq->strip->dir);
1089       }
1090     }
1091   }
1092   SEQ_END;
1093 }
1094
1095 static int sequencer_gap_remove_exec(bContext *C, wmOperator *op)
1096 {
1097   Scene *scene = CTX_data_scene(C);
1098   rctf rectf;
1099   int cfra, efra, sfra;
1100   bool first = false, done;
1101   bool do_all = RNA_boolean_get(op->ptr, "all");
1102
1103   /* get first and last frame */
1104   boundbox_seq(scene, &rectf);
1105   sfra = (int)rectf.xmin;
1106   efra = (int)rectf.xmax;
1107
1108   /* first check if the current frame has a gap already */
1109   for (cfra = CFRA; cfra >= sfra; cfra--) {
1110     if (BKE_sequencer_evaluate_frame(scene, cfra)) {
1111       first = true;
1112       break;
1113     }
1114   }
1115
1116   for (; cfra < efra; cfra++) {
1117     /* first == 0 means there's still no strip to remove a gap for */
1118     if (first == false) {
1119       if (BKE_sequencer_evaluate_frame(scene, cfra)) {
1120         first = true;
1121       }
1122     }
1123     else if (BKE_sequencer_evaluate_frame(scene, cfra) == 0) {
1124       done = true;
1125       while (BKE_sequencer_evaluate_frame(scene, cfra) == 0) {
1126         done = sequence_offset_after_frame(scene, -1, cfra);
1127         if (done == false) {
1128           break;
1129         }
1130       }
1131       if (done == false || do_all == false) {
1132         break;
1133       }
1134     }
1135   }
1136
1137   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1138
1139   return OPERATOR_FINISHED;
1140 }
1141
1142 void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot)
1143 {
1144   /* identifiers */
1145   ot->name = "Remove Gaps";
1146   ot->idname = "SEQUENCER_OT_gap_remove";
1147   ot->description =
1148       "Remove gap at current frame to first strip at the right, independent of selection or "
1149       "locked state of strips";
1150
1151   /* api callbacks */
1152   //  ot->invoke = sequencer_snap_invoke;
1153   ot->exec = sequencer_gap_remove_exec;
1154   ot->poll = sequencer_edit_poll;
1155
1156   /* flags */
1157   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1158
1159   RNA_def_boolean(ot->srna, "all", 0, "All Gaps", "Do all gaps to right of current frame");
1160 }
1161
1162 static int sequencer_gap_insert_exec(bContext *C, wmOperator *op)
1163 {
1164   Scene *scene = CTX_data_scene(C);
1165   int frames = RNA_int_get(op->ptr, "frames");
1166
1167   sequence_offset_after_frame(scene, frames, CFRA);
1168
1169   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1170
1171   return OPERATOR_FINISHED;
1172 }
1173
1174 void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot)
1175 {
1176   /* identifiers */
1177   ot->name = "Insert Gaps";
1178   ot->idname = "SEQUENCER_OT_gap_insert";
1179   ot->description =
1180       "Insert gap at current frame to first strips at the right, independent of selection or "
1181       "locked state of strips";
1182
1183   /* api callbacks */
1184   //  ot->invoke = sequencer_snap_invoke;
1185   ot->exec = sequencer_gap_insert_exec;
1186   ot->poll = sequencer_edit_poll;
1187
1188   /* flags */
1189   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1190
1191   RNA_def_int(ot->srna,
1192               "frames",
1193               10,
1194               0,
1195               INT_MAX,
1196               "Frames",
1197               "Frames to insert after current strip",
1198               0,
1199               1000);
1200 }
1201
1202 #if 0
1203 static int seq_get_snaplimit(View2D *v2d)
1204 {
1205   /* fake mouse coords to get the snap value
1206    * a bit lazy but its only done once pre transform */
1207   float xmouse, ymouse, x;
1208   int mval[2] = {24, 0}; /* 24 screen px snap */
1209
1210   UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
1211   x = xmouse;
1212   mval[0] = 0;
1213   UI_view2d_region_to_view(v2d, mval[0], mval[1], &xmouse, &ymouse);
1214   return (int)(x - xmouse);
1215 }
1216 #endif
1217
1218 /* Operator functions */
1219 bool sequencer_edit_poll(bContext *C)
1220 {
1221   return (BKE_sequencer_editing_get(CTX_data_scene(C), false) != NULL);
1222 }
1223
1224 #if 0 /* UNUSED */
1225 bool sequencer_strip_poll(bContext *C)
1226 {
1227   Editing *ed;
1228   return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) &&
1229           (ed->act_seq != NULL));
1230 }
1231 #endif
1232
1233 bool sequencer_strip_has_path_poll(bContext *C)
1234 {
1235   Editing *ed;
1236   Sequence *seq;
1237   return (((ed = BKE_sequencer_editing_get(CTX_data_scene(C), false)) != NULL) &&
1238           ((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
1239 }
1240
1241 bool sequencer_view_preview_poll(bContext *C)
1242 {
1243   SpaceSeq *sseq = CTX_wm_space_seq(C);
1244   Editing *ed = BKE_sequencer_editing_get(CTX_data_scene(C), false);
1245   if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF)) {
1246     return 1;
1247   }
1248
1249   return 0;
1250 }
1251
1252 bool sequencer_view_strips_poll(bContext *C)
1253 {
1254   SpaceSeq *sseq = CTX_wm_space_seq(C);
1255   if (sseq && ED_space_sequencer_check_show_strip(sseq)) {
1256     return 1;
1257   }
1258
1259   return 0;
1260 }
1261
1262 /* snap operator*/
1263 static int sequencer_snap_exec(bContext *C, wmOperator *op)
1264 {
1265   Scene *scene = CTX_data_scene(C);
1266
1267   Editing *ed = BKE_sequencer_editing_get(scene, false);
1268   Sequence *seq;
1269   int snap_frame;
1270
1271   snap_frame = RNA_int_get(op->ptr, "frame");
1272
1273   /* also check metas */
1274   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1275     if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
1276         BKE_sequence_tx_test(seq)) {
1277       if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
1278         /* simple but no anim update */
1279         /* seq->start = snap_frame-seq->startofs+seq->startstill; */
1280
1281         BKE_sequence_translate(
1282             scene, seq, (snap_frame - seq->startofs + seq->startstill) - seq->start);
1283       }
1284       else {
1285         if (seq->flag & SEQ_LEFTSEL) {
1286           BKE_sequence_tx_set_final_left(seq, snap_frame);
1287         }
1288         else { /* SEQ_RIGHTSEL */
1289           BKE_sequence_tx_set_final_right(seq, snap_frame);
1290         }
1291         BKE_sequence_tx_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
1292         BKE_sequence_single_fix(seq);
1293       }
1294       BKE_sequence_calc(scene, seq);
1295     }
1296   }
1297
1298   /* test for effects and overlap
1299    * don't use SEQP_BEGIN since that would be recursive */
1300   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1301     if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
1302       seq->flag &= ~SEQ_OVERLAP;
1303       if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
1304         BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1305       }
1306     }
1307     else if (seq->type & SEQ_TYPE_EFFECT) {
1308       if (seq->seq1 && (seq->seq1->flag & SELECT)) {
1309         BKE_sequence_calc(scene, seq);
1310       }
1311       else if (seq->seq2 && (seq->seq2->flag & SELECT)) {
1312         BKE_sequence_calc(scene, seq);
1313       }
1314       else if (seq->seq3 && (seq->seq3->flag & SELECT)) {
1315         BKE_sequence_calc(scene, seq);
1316       }
1317     }
1318   }
1319
1320   /* as last: */
1321   BKE_sequencer_sort(scene);
1322
1323   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1324
1325   return OPERATOR_FINISHED;
1326 }
1327
1328 static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1329 {
1330   Scene *scene = CTX_data_scene(C);
1331
1332   int snap_frame;
1333
1334   snap_frame = CFRA;
1335
1336   RNA_int_set(op->ptr, "frame", snap_frame);
1337   return sequencer_snap_exec(C, op);
1338 }
1339
1340 void SEQUENCER_OT_snap(struct wmOperatorType *ot)
1341 {
1342   /* identifiers */
1343   ot->name = "Snap Strips to Playhead";
1344   ot->idname = "SEQUENCER_OT_snap";
1345   ot->description = "Frame where selected strips will be snapped";
1346
1347   /* api callbacks */
1348   ot->invoke = sequencer_snap_invoke;
1349   ot->exec = sequencer_snap_exec;
1350   ot->poll = sequencer_edit_poll;
1351
1352   /* flags */
1353   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1354
1355   RNA_def_int(ot->srna,
1356               "frame",
1357               0,
1358               INT_MIN,
1359               INT_MAX,
1360               "Frame",
1361               "Frame where selected strips will be snapped",
1362               INT_MIN,
1363               INT_MAX);
1364 }
1365
1366 typedef struct SlipData {
1367   int init_mouse[2];
1368   float init_mouseloc[2];
1369   TransSeq *ts;
1370   Sequence **seq_array;
1371   bool *trim;
1372   int num_seq;
1373   bool slow;
1374   int slow_offset; /* offset at the point where offset was turned on */
1375   NumInput num_input;
1376 } SlipData;
1377
1378 static void transseq_backup(TransSeq *ts, Sequence *seq)
1379 {
1380   ts->start = seq->start;
1381   ts->machine = seq->machine;
1382   ts->startstill = seq->startstill;
1383   ts->endstill = seq->endstill;
1384   ts->startdisp = seq->startdisp;
1385   ts->enddisp = seq->enddisp;
1386   ts->startofs = seq->startofs;
1387   ts->endofs = seq->endofs;
1388   ts->anim_startofs = seq->anim_startofs;
1389   ts->anim_endofs = seq->anim_endofs;
1390   ts->len = seq->len;
1391 }
1392
1393 static void transseq_restore(TransSeq *ts, Sequence *seq)
1394 {
1395   seq->start = ts->start;
1396   seq->machine = ts->machine;
1397   seq->startstill = ts->startstill;
1398   seq->endstill = ts->endstill;
1399   seq->startdisp = ts->startdisp;
1400   seq->enddisp = ts->enddisp;
1401   seq->startofs = ts->startofs;
1402   seq->endofs = ts->endofs;
1403   seq->anim_startofs = ts->anim_startofs;
1404   seq->anim_endofs = ts->anim_endofs;
1405   seq->len = ts->len;
1406 }
1407
1408 static int slip_add_sequences_rec(
1409     ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim)
1410 {
1411   Sequence *seq;
1412   int num_items = 0;
1413
1414   for (seq = seqbasep->first; seq; seq = seq->next) {
1415     if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
1416       seq_array[offset + num_items] = seq;
1417       trim[offset + num_items] = do_trim;
1418       num_items++;
1419
1420       if (seq->type == SEQ_TYPE_META) {
1421         /* trim the sub-sequences */
1422         num_items += slip_add_sequences_rec(
1423             &seq->seqbase, seq_array, trim, num_items + offset, false);
1424       }
1425       else if (seq->type & SEQ_TYPE_EFFECT) {
1426         trim[offset + num_items] = false;
1427       }
1428     }
1429   }
1430
1431   return num_items;
1432 }
1433
1434 static int slip_count_sequences_rec(ListBase *seqbasep, bool first_level)
1435 {
1436   Sequence *seq;
1437   int trimmed_sequences = 0;
1438
1439   for (seq = seqbasep->first; seq; seq = seq->next) {
1440     if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
1441       trimmed_sequences++;
1442
1443       if (seq->type == SEQ_TYPE_META) {
1444         /* trim the sub-sequences */
1445         trimmed_sequences += slip_count_sequences_rec(&seq->seqbase, false);
1446       }
1447     }
1448   }
1449
1450   return trimmed_sequences;
1451 }
1452
1453 static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1454 {
1455   SlipData *data;
1456   Scene *scene = CTX_data_scene(C);
1457   Editing *ed = BKE_sequencer_editing_get(scene, false);
1458   float mouseloc[2];
1459   int num_seq, i;
1460   View2D *v2d = UI_view2d_fromcontext(C);
1461
1462   /* first recursively count the trimmed elements */
1463   num_seq = slip_count_sequences_rec(ed->seqbasep, true);
1464
1465   if (num_seq == 0) {
1466     return OPERATOR_CANCELLED;
1467   }
1468
1469   data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
1470   data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
1471   data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
1472   data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
1473   data->num_seq = num_seq;
1474
1475   initNumInput(&data->num_input);
1476   data->num_input.idx_max = 0;
1477   data->num_input.val_flag[0] |= NUM_NO_FRACTION;
1478   data->num_input.unit_sys = USER_UNIT_NONE;
1479   data->num_input.unit_type[0] = 0;
1480
1481   slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true);
1482
1483   for (i = 0; i < num_seq; i++) {
1484     transseq_backup(data->ts + i, data->seq_array[i]);
1485   }
1486
1487   UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
1488
1489   copy_v2_v2_int(data->init_mouse, event->mval);
1490   copy_v2_v2(data->init_mouseloc, mouseloc);
1491
1492   data->slow = false;
1493
1494   WM_event_add_modal_handler(C, op);
1495
1496   /* notify so we draw extensions immediately */
1497   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1498
1499   return OPERATOR_RUNNING_MODAL;
1500 }
1501
1502 static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
1503 {
1504
1505   /* only data types supported for now */
1506   if (offset != 0) {
1507     Editing *ed = BKE_sequencer_editing_get(scene, false);
1508     int i;
1509
1510     /* we iterate in reverse so metastrips are iterated after their children */
1511     for (i = data->num_seq - 1; i >= 0; i--) {
1512       Sequence *seq = data->seq_array[i];
1513       int endframe;
1514       /* we have the offset, do the terrible math */
1515
1516       /* first, do the offset */
1517       seq->start = data->ts[i].start + offset;
1518
1519       if (data->trim[i]) {
1520         /* find the endframe */
1521         endframe = seq->start + seq->len;
1522
1523         /* now compute the terrible offsets */
1524         if (endframe > seq->enddisp) {
1525           seq->endstill = 0;
1526           seq->endofs = endframe - seq->enddisp;
1527         }
1528         else if (endframe <= seq->enddisp) {
1529           seq->endstill = seq->enddisp - endframe;
1530           seq->endofs = 0;
1531         }
1532
1533         if (seq->start > seq->startdisp) {
1534           seq->startstill = seq->start - seq->startdisp;
1535           seq->startofs = 0;
1536         }
1537         else if (seq->start <= seq->startdisp) {
1538           seq->startstill = 0;
1539           seq->startofs = seq->startdisp - seq->start;
1540         }
1541       }
1542       else {
1543         /* if no real trim, don't change the data, rather transform the strips themselves */
1544         seq->startdisp = data->ts[i].startdisp + offset;
1545         seq->enddisp = data->ts[i].enddisp + offset;
1546       }
1547
1548       /* effects are only added if we they are in a meta-strip.
1549        * In this case, dependent strips will just be transformed and
1550        * we can skip calculating for effects.
1551        * This way we can avoid an extra loop just for effects*/
1552       if (!(seq->type & SEQ_TYPE_EFFECT)) {
1553         BKE_sequence_calc(scene, seq);
1554       }
1555     }
1556     BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
1557
1558     return true;
1559   }
1560
1561   return false;
1562 }
1563
1564 static int sequencer_slip_exec(bContext *C, wmOperator *op)
1565 {
1566   SlipData *data;
1567   Scene *scene = CTX_data_scene(C);
1568   Editing *ed = BKE_sequencer_editing_get(scene, false);
1569   int num_seq, i;
1570   int offset = RNA_int_get(op->ptr, "offset");
1571   bool success = false;
1572
1573   /* first recursively count the trimmed elements */
1574   num_seq = slip_count_sequences_rec(ed->seqbasep, true);
1575
1576   if (num_seq == 0) {
1577     return OPERATOR_CANCELLED;
1578   }
1579
1580   data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
1581   data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
1582   data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
1583   data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
1584   data->num_seq = num_seq;
1585
1586   slip_add_sequences_rec(ed->seqbasep, data->seq_array, data->trim, 0, true);
1587
1588   for (i = 0; i < num_seq; i++) {
1589     transseq_backup(data->ts + i, data->seq_array[i]);
1590   }
1591
1592   success = sequencer_slip_recursively(scene, data, offset);
1593
1594   MEM_freeN(data->seq_array);
1595   MEM_freeN(data->trim);
1596   MEM_freeN(data->ts);
1597   MEM_freeN(data);
1598
1599   if (success) {
1600     WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1601     return OPERATOR_FINISHED;
1602   }
1603   else {
1604     return OPERATOR_CANCELLED;
1605   }
1606 }
1607
1608 static void sequencer_slip_update_header(Scene *scene, ScrArea *sa, SlipData *data, int offset)
1609 {
1610   char msg[UI_MAX_DRAW_STR];
1611
1612   if (sa) {
1613     if (hasNumInput(&data->num_input)) {
1614       char num_str[NUM_STR_REP_LEN];
1615       outputNumInput(&data->num_input, num_str, &scene->unit);
1616       BLI_snprintf(msg, sizeof(msg), IFACE_("Trim offset: %s"), num_str);
1617     }
1618     else {
1619       BLI_snprintf(msg, sizeof(msg), IFACE_("Trim offset: %d"), offset);
1620     }
1621   }
1622
1623   ED_area_status_text(sa, msg);
1624 }
1625
1626 static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event)
1627 {
1628   Main *bmain = CTX_data_main(C);
1629   Scene *scene = CTX_data_scene(C);
1630   SlipData *data = (SlipData *)op->customdata;
1631   ScrArea *sa = CTX_wm_area(C);
1632   const bool has_numInput = hasNumInput(&data->num_input);
1633   bool handled = true;
1634
1635   /* Modal numinput active, try to handle numeric inputs first... */
1636   if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) {
1637     float offset;
1638     applyNumInput(&data->num_input, &offset);
1639
1640     sequencer_slip_update_header(scene, sa, data, (int)offset);
1641
1642     RNA_int_set(op->ptr, "offset", offset);
1643
1644     if (sequencer_slip_recursively(scene, data, offset)) {
1645       WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1646     }
1647
1648     return OPERATOR_RUNNING_MODAL;
1649   }
1650
1651   switch (event->type) {
1652     case MOUSEMOVE: {
1653       if (!has_numInput) {
1654         float mouseloc[2];
1655         int offset;
1656         int mouse_x;
1657         View2D *v2d = UI_view2d_fromcontext(C);
1658
1659         if (data->slow) {
1660           mouse_x = event->mval[0] - data->slow_offset;
1661           mouse_x *= 0.1f;
1662           mouse_x += data->slow_offset;
1663         }
1664         else {
1665           mouse_x = event->mval[0];
1666         }
1667
1668         /* choose the side based on which side of the playhead the mouse is on */
1669         UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]);
1670         offset = mouseloc[0] - data->init_mouseloc[0];
1671
1672         sequencer_slip_update_header(scene, sa, data, offset);
1673
1674         RNA_int_set(op->ptr, "offset", offset);
1675
1676         if (sequencer_slip_recursively(scene, data, offset)) {
1677           WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1678         }
1679       }
1680       break;
1681     }
1682
1683     case LEFTMOUSE:
1684     case RETKEY:
1685     case SPACEKEY: {
1686       MEM_freeN(data->seq_array);
1687       MEM_freeN(data->trim);
1688       MEM_freeN(data->ts);
1689       MEM_freeN(data);
1690       op->customdata = NULL;
1691       if (sa) {
1692         ED_area_status_text(sa, NULL);
1693       }
1694       WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1695       return OPERATOR_FINISHED;
1696     }
1697
1698     case ESCKEY:
1699     case RIGHTMOUSE: {
1700       int i;
1701       Editing *ed = BKE_sequencer_editing_get(scene, false);
1702
1703       for (i = 0; i < data->num_seq; i++) {
1704         transseq_restore(data->ts + i, data->seq_array[i]);
1705       }
1706
1707       for (i = 0; i < data->num_seq; i++) {
1708         Sequence *seq = data->seq_array[i];
1709         BKE_sequence_reload_new_file(bmain, scene, seq, false);
1710         BKE_sequence_calc(scene, seq);
1711       }
1712
1713       MEM_freeN(data->seq_array);
1714       MEM_freeN(data->ts);
1715       MEM_freeN(data->trim);
1716       MEM_freeN(data);
1717       op->customdata = NULL;
1718
1719       WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1720
1721       BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
1722
1723       if (sa) {
1724         ED_area_status_text(sa, NULL);
1725       }
1726
1727       return OPERATOR_CANCELLED;
1728     }
1729
1730     case RIGHTSHIFTKEY:
1731     case LEFTSHIFTKEY:
1732       if (!has_numInput) {
1733         if (event->val == KM_PRESS) {
1734           data->slow = true;
1735           data->slow_offset = event->mval[0];
1736         }
1737         else if (event->val == KM_RELEASE) {
1738           data->slow = false;
1739         }
1740       }
1741       break;
1742
1743     default:
1744       handled = false;
1745       break;
1746   }
1747
1748   /* Modal numinput inactive, try to handle numeric inputs last... */
1749   if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) {
1750     float offset;
1751     applyNumInput(&data->num_input, &offset);
1752
1753     sequencer_slip_update_header(scene, sa, data, (int)offset);
1754
1755     RNA_int_set(op->ptr, "offset", offset);
1756
1757     if (sequencer_slip_recursively(scene, data, offset)) {
1758       WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1759     }
1760   }
1761
1762   return OPERATOR_RUNNING_MODAL;
1763 }
1764
1765 void SEQUENCER_OT_slip(struct wmOperatorType *ot)
1766 {
1767   /* identifiers */
1768   ot->name = "Trim Strips";
1769   ot->idname = "SEQUENCER_OT_slip";
1770   ot->description = "Trim the contents of the active strip";
1771
1772   /* api callbacks */
1773   ot->invoke = sequencer_slip_invoke;
1774   ot->modal = sequencer_slip_modal;
1775   ot->exec = sequencer_slip_exec;
1776   ot->poll = sequencer_edit_poll;
1777
1778   /* flags */
1779   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1780
1781   RNA_def_int(ot->srna,
1782               "offset",
1783               0,
1784               INT32_MIN,
1785               INT32_MAX,
1786               "Offset",
1787               "Offset to the data of the strip",
1788               INT32_MIN,
1789               INT32_MAX);
1790 }
1791
1792 /* mute operator */
1793 static int sequencer_mute_exec(bContext *C, wmOperator *op)
1794 {
1795   Scene *scene = CTX_data_scene(C);
1796   Editing *ed = BKE_sequencer_editing_get(scene, false);
1797   Sequence *seq;
1798   bool selected;
1799
1800   selected = !RNA_boolean_get(op->ptr, "unselected");
1801
1802   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1803     if ((seq->flag & SEQ_LOCK) == 0) {
1804       if (selected) { /* mute unselected */
1805         if (seq->flag & SELECT) {
1806           seq->flag |= SEQ_MUTE;
1807           BKE_sequence_invalidate_dependent(scene, seq);
1808         }
1809       }
1810       else {
1811         if ((seq->flag & SELECT) == 0) {
1812           seq->flag |= SEQ_MUTE;
1813           BKE_sequence_invalidate_dependent(scene, seq);
1814         }
1815       }
1816     }
1817   }
1818
1819   DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
1820   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1821
1822   return OPERATOR_FINISHED;
1823 }
1824
1825 void SEQUENCER_OT_mute(struct wmOperatorType *ot)
1826 {
1827   /* identifiers */
1828   ot->name = "Mute Strips";
1829   ot->idname = "SEQUENCER_OT_mute";
1830   ot->description = "Mute (un)selected strips";
1831
1832   /* api callbacks */
1833   ot->exec = sequencer_mute_exec;
1834   ot->poll = sequencer_edit_poll;
1835
1836   /* flags */
1837   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1838
1839   RNA_def_boolean(
1840       ot->srna, "unselected", 0, "Unselected", "Mute unselected rather than selected strips");
1841 }
1842
1843 /* unmute operator */
1844 static int sequencer_unmute_exec(bContext *C, wmOperator *op)
1845 {
1846   Scene *scene = CTX_data_scene(C);
1847   Editing *ed = BKE_sequencer_editing_get(scene, false);
1848   Sequence *seq;
1849   bool selected;
1850
1851   selected = !RNA_boolean_get(op->ptr, "unselected");
1852
1853   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1854     if ((seq->flag & SEQ_LOCK) == 0) {
1855       if (selected) { /* unmute unselected */
1856         if (seq->flag & SELECT) {
1857           seq->flag &= ~SEQ_MUTE;
1858           BKE_sequence_invalidate_dependent(scene, seq);
1859         }
1860       }
1861       else {
1862         if ((seq->flag & SELECT) == 0) {
1863           seq->flag &= ~SEQ_MUTE;
1864           BKE_sequence_invalidate_dependent(scene, seq);
1865         }
1866       }
1867     }
1868   }
1869
1870   DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
1871   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1872
1873   return OPERATOR_FINISHED;
1874 }
1875
1876 void SEQUENCER_OT_unmute(struct wmOperatorType *ot)
1877 {
1878   /* identifiers */
1879   ot->name = "Unmute Strips";
1880   ot->idname = "SEQUENCER_OT_unmute";
1881   ot->description = "Unmute (un)selected strips";
1882
1883   /* api callbacks */
1884   ot->exec = sequencer_unmute_exec;
1885   ot->poll = sequencer_edit_poll;
1886
1887   /* flags */
1888   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1889
1890   RNA_def_boolean(
1891       ot->srna, "unselected", 0, "Unselected", "Unmute unselected rather than selected strips");
1892 }
1893
1894 /* lock operator */
1895 static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op))
1896 {
1897   Scene *scene = CTX_data_scene(C);
1898   Editing *ed = BKE_sequencer_editing_get(scene, false);
1899   Sequence *seq;
1900
1901   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1902     if (seq->flag & SELECT) {
1903       seq->flag |= SEQ_LOCK;
1904     }
1905   }
1906
1907   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1908
1909   return OPERATOR_FINISHED;
1910 }
1911
1912 void SEQUENCER_OT_lock(struct wmOperatorType *ot)
1913 {
1914   /* identifiers */
1915   ot->name = "Lock Strips";
1916   ot->idname = "SEQUENCER_OT_lock";
1917   ot->description = "Lock strips so they can't be transformed";
1918
1919   /* api callbacks */
1920   ot->exec = sequencer_lock_exec;
1921   ot->poll = sequencer_edit_poll;
1922
1923   /* flags */
1924   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1925 }
1926
1927 /* unlock operator */
1928 static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op))
1929 {
1930   Scene *scene = CTX_data_scene(C);
1931   Editing *ed = BKE_sequencer_editing_get(scene, false);
1932   Sequence *seq;
1933
1934   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1935     if (seq->flag & SELECT) {
1936       seq->flag &= ~SEQ_LOCK;
1937     }
1938   }
1939
1940   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1941
1942   return OPERATOR_FINISHED;
1943 }
1944
1945 void SEQUENCER_OT_unlock(struct wmOperatorType *ot)
1946 {
1947   /* identifiers */
1948   ot->name = "Unlock Strips";
1949   ot->idname = "SEQUENCER_OT_unlock";
1950   ot->description = "Unlock strips so they can be transformed";
1951
1952   /* api callbacks */
1953   ot->exec = sequencer_unlock_exec;
1954   ot->poll = sequencer_edit_poll;
1955
1956   /* flags */
1957   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1958 }
1959
1960 /* reload operator */
1961 static int sequencer_reload_exec(bContext *C, wmOperator *op)
1962 {
1963   Main *bmain = CTX_data_main(C);
1964   Scene *scene = CTX_data_scene(C);
1965   Editing *ed = BKE_sequencer_editing_get(scene, false);
1966   Sequence *seq;
1967   const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length");
1968
1969   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
1970     if (seq->flag & SELECT) {
1971       BKE_sequencer_update_changed_seq_and_deps(scene, seq, 0, 1);
1972       BKE_sequence_reload_new_file(bmain, scene, seq, !adjust_length);
1973
1974       if (adjust_length) {
1975         if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
1976           BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
1977         }
1978       }
1979     }
1980   }
1981
1982   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
1983
1984   return OPERATOR_FINISHED;
1985 }
1986
1987 void SEQUENCER_OT_reload(struct wmOperatorType *ot)
1988 {
1989   PropertyRNA *prop;
1990
1991   /* identifiers */
1992   ot->name = "Reload Strips";
1993   ot->idname = "SEQUENCER_OT_reload";
1994   ot->description = "Reload strips in the sequencer";
1995
1996   /* api callbacks */
1997   ot->exec = sequencer_reload_exec;
1998   ot->poll = sequencer_edit_poll;
1999
2000   /* flags */
2001   ot->flag = OPTYPE_REGISTER; /* no undo, the data changed is stored outside 'main' */
2002
2003   prop = RNA_def_boolean(ot->srna,
2004                          "adjust_length",
2005                          0,
2006                          "Adjust Length",
2007                          "Adjust length of strips to their data length");
2008   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
2009 }
2010
2011 /* reload operator */
2012 static bool sequencer_refresh_all_poll(bContext *C)
2013 {
2014   if (G.is_rendering) {
2015     return 0;
2016   }
2017   return sequencer_edit_poll(C);
2018 }
2019
2020 static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op))
2021 {
2022   Scene *scene = CTX_data_scene(C);
2023   Editing *ed = BKE_sequencer_editing_get(scene, false);
2024
2025   BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
2026
2027   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2028
2029   return OPERATOR_FINISHED;
2030 }
2031
2032 void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot)
2033 {
2034   /* identifiers */
2035   ot->name = "Refresh Sequencer";
2036   ot->idname = "SEQUENCER_OT_refresh_all";
2037   ot->description = "Refresh the sequencer editor";
2038
2039   /* api callbacks */
2040   ot->exec = sequencer_refresh_all_exec;
2041   ot->poll = sequencer_refresh_all_poll;
2042 }
2043
2044 static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
2045 {
2046   Scene *scene = CTX_data_scene(C);
2047   Sequence *seq1, *seq2, *seq3, *last_seq = BKE_sequencer_active_get(scene);
2048   const char *error_msg;
2049
2050   if (!seq_effect_find_selected(
2051           scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg)) {
2052     BKE_report(op->reports, RPT_ERROR, error_msg);
2053     return OPERATOR_CANCELLED;
2054   }
2055   /* see reassigning would create a cycle */
2056   if (seq_is_predecessor(seq1, last_seq) || seq_is_predecessor(seq2, last_seq) ||
2057       seq_is_predecessor(seq3, last_seq)) {
2058     BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: no cycles allowed");
2059     return OPERATOR_CANCELLED;
2060   }
2061
2062   last_seq->seq1 = seq1;
2063   last_seq->seq2 = seq2;
2064   last_seq->seq3 = seq3;
2065
2066   BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1);
2067
2068   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2069
2070   return OPERATOR_FINISHED;
2071 }
2072
2073 static bool sequencer_effect_poll(bContext *C)
2074 {
2075   Scene *scene = CTX_data_scene(C);
2076   Editing *ed = BKE_sequencer_editing_get(scene, false);
2077
2078   if (ed) {
2079     Sequence *last_seq = BKE_sequencer_active_get(scene);
2080     if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) {
2081       return 1;
2082     }
2083   }
2084
2085   return 0;
2086 }
2087
2088 void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot)
2089 {
2090   /* identifiers */
2091   ot->name = "Reassign Inputs";
2092   ot->idname = "SEQUENCER_OT_reassign_inputs";
2093   ot->description = "Reassign the inputs for the effect strip";
2094
2095   /* api callbacks */
2096   ot->exec = sequencer_reassign_inputs_exec;
2097   ot->poll = sequencer_effect_poll;
2098
2099   /* flags */
2100   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2101 }
2102
2103 static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op)
2104 {
2105   Scene *scene = CTX_data_scene(C);
2106   Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
2107
2108   if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) {
2109     BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap");
2110     return OPERATOR_CANCELLED;
2111   }
2112
2113   seq = last_seq->seq1;
2114   last_seq->seq1 = last_seq->seq2;
2115   last_seq->seq2 = seq;
2116
2117   BKE_sequencer_update_changed_seq_and_deps(scene, last_seq, 1, 1);
2118
2119   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2120
2121   return OPERATOR_FINISHED;
2122 }
2123 void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot)
2124 {
2125   /* identifiers */
2126   ot->name = "Swap Inputs";
2127   ot->idname = "SEQUENCER_OT_swap_inputs";
2128   ot->description = "Swap the first two inputs for the effect strip";
2129
2130   /* api callbacks */
2131   ot->exec = sequencer_swap_inputs_exec;
2132   ot->poll = sequencer_effect_poll;
2133
2134   /* flags */
2135   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2136 }
2137
2138 /* cut operator */
2139 static const EnumPropertyItem prop_cut_types[] = {
2140     {SEQ_CUT_SOFT, "SOFT", 0, "Soft", ""},
2141     {SEQ_CUT_HARD, "HARD", 0, "Hard", ""},
2142     {0, NULL, 0, NULL, NULL},
2143 };
2144
2145 static int sequencer_cut_exec(bContext *C, wmOperator *op)
2146 {
2147   Main *bmain = CTX_data_main(C);
2148   Scene *scene = CTX_data_scene(C);
2149   Editing *ed = BKE_sequencer_editing_get(scene, false);
2150   int cut_side, cut_hard, cut_frame;
2151
2152   bool changed;
2153
2154   cut_frame = RNA_int_get(op->ptr, "frame");
2155   cut_hard = RNA_enum_get(op->ptr, "type");
2156   cut_side = RNA_enum_get(op->ptr, "side");
2157
2158   if (cut_hard == SEQ_CUT_HARD) {
2159     changed = cut_seq_list(bmain, scene, ed->seqbasep, cut_frame, cut_seq_hard);
2160   }
2161   else {
2162     changed = cut_seq_list(bmain, scene, ed->seqbasep, cut_frame, cut_seq_soft);
2163   }
2164
2165   if (changed) { /* got new strips ? */
2166     Sequence *seq;
2167
2168     if (cut_side != SEQ_SIDE_BOTH) {
2169       SEQP_BEGIN (ed, seq) {
2170         if (cut_side == SEQ_SIDE_LEFT) {
2171           if (seq->startdisp >= cut_frame) {
2172             seq->flag &= ~SEQ_ALLSEL;
2173           }
2174         }
2175         else {
2176           if (seq->enddisp <= cut_frame) {
2177             seq->flag &= ~SEQ_ALLSEL;
2178           }
2179         }
2180       }
2181       SEQ_END;
2182     }
2183
2184     SEQP_BEGIN (ed, seq) {
2185       if (seq->seq1 || seq->seq2 || seq->seq3) {
2186         BKE_sequence_calc(scene, seq);
2187       }
2188     }
2189     SEQ_END;
2190
2191     /* as last: */
2192     BKE_sequencer_sort(scene);
2193   }
2194
2195   if (changed) {
2196     WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2197     return OPERATOR_FINISHED;
2198   }
2199   else {
2200     return OPERATOR_CANCELLED;
2201   }
2202 }
2203
2204 static int sequencer_cut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
2205 {
2206   Scene *scene = CTX_data_scene(C);
2207   View2D *v2d = UI_view2d_fromcontext(C);
2208
2209   int cut_side = RNA_enum_get(op->ptr, "side");
2210   int cut_frame = CFRA;
2211
2212   if (cut_side == SEQ_SIDE_MOUSE) {
2213     if (ED_operator_sequencer_active(C) && v2d) {
2214       cut_side = mouse_frame_side(v2d, event->mval[0], cut_frame);
2215     }
2216     else {
2217       cut_side = SEQ_SIDE_BOTH;
2218     }
2219   }
2220   RNA_int_set(op->ptr, "frame", cut_frame);
2221   RNA_enum_set(op->ptr, "side", cut_side);
2222   /*RNA_enum_set(op->ptr, "type", cut_hard); */ /*This type is set from the key shortcut */
2223   return sequencer_cut_exec(C, op);
2224 }
2225
2226 void SEQUENCER_OT_cut(struct wmOperatorType *ot)
2227 {
2228   /* identifiers */
2229   ot->name = "Cut Strips";
2230   ot->idname = "SEQUENCER_OT_cut";
2231   ot->description = "Cut the selected strips";
2232
2233   /* api callbacks */
2234   ot->invoke = sequencer_cut_invoke;
2235   ot->exec = sequencer_cut_exec;
2236   ot->poll = sequencer_edit_poll;
2237
2238   /* flags */
2239   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2240
2241   PropertyRNA *prop;
2242   RNA_def_int(ot->srna,
2243               "frame",
2244               0,
2245               INT_MIN,
2246               INT_MAX,
2247               "Frame",
2248               "Frame where selected strips will be cut",
2249               INT_MIN,
2250               INT_MAX);
2251   RNA_def_enum(ot->srna,
2252                "type",
2253                prop_cut_types,
2254                SEQ_CUT_SOFT,
2255                "Type",
2256                "The type of cut operation to perform on strips");
2257   prop = RNA_def_enum(ot->srna,
2258                       "side",
2259                       prop_side_types,
2260                       SEQ_SIDE_MOUSE,
2261                       "Side",
2262                       "The side that remains selected after cutting");
2263   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
2264 }
2265
2266 #undef SEQ_SIDE_MOUSE
2267
2268 /* duplicate operator */
2269 static int apply_unique_name_cb(Sequence *seq, void *arg_pt)
2270 {
2271   Scene *scene = (Scene *)arg_pt;
2272   char name[sizeof(seq->name) - 2];
2273
2274   BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
2275   BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
2276   BKE_sequencer_dupe_animdata(scene, name, seq->name + 2);
2277   return 1;
2278 }
2279
2280 static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
2281 {
2282   Scene *scene = CTX_data_scene(C);
2283   Editing *ed = BKE_sequencer_editing_get(scene, false);
2284
2285   ListBase nseqbase = {NULL, NULL};
2286
2287   if (ed == NULL) {
2288     return OPERATOR_CANCELLED;
2289   }
2290
2291   BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0);
2292
2293   if (nseqbase.first) {
2294     Sequence *seq = nseqbase.first;
2295     /* rely on the nseqbase list being added at the end */
2296     BLI_movelisttolist(ed->seqbasep, &nseqbase);
2297
2298     for (; seq; seq = seq->next) {
2299       BKE_sequencer_recursive_apply(seq, apply_unique_name_cb, scene);
2300     }
2301
2302     WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2303     return OPERATOR_FINISHED;
2304   }
2305
2306   return OPERATOR_CANCELLED;
2307 }
2308
2309 void SEQUENCER_OT_duplicate(wmOperatorType *ot)
2310 {
2311   /* identifiers */
2312   ot->name = "Duplicate Strips";
2313   ot->idname = "SEQUENCER_OT_duplicate";
2314   ot->description = "Duplicate the selected strips";
2315
2316   /* api callbacks */
2317   ot->exec = sequencer_add_duplicate_exec;
2318   ot->poll = ED_operator_sequencer_active;
2319
2320   /* flags */
2321   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2322
2323   /* to give to transform */
2324   RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
2325 }
2326
2327 /* delete operator */
2328 static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
2329 {
2330   Main *bmain = CTX_data_main(C);
2331   Scene *scene = CTX_data_scene(C);
2332   Editing *ed = BKE_sequencer_editing_get(scene, false);
2333   Sequence *seq;
2334   MetaStack *ms;
2335   bool nothing_selected = true;
2336
2337   seq = BKE_sequencer_active_get(scene);
2338   if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
2339     nothing_selected = false;
2340   }
2341   else {
2342     for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2343       if (seq->flag & SELECT) {
2344         nothing_selected = false;
2345         break;
2346       }
2347     }
2348   }
2349
2350   if (nothing_selected) {
2351     return OPERATOR_FINISHED;
2352   }
2353
2354   /* for effects and modifiers, try to find a replacement input */
2355   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2356     if (!(seq->flag & SELECT)) {
2357       if ((seq->type & SEQ_TYPE_EFFECT)) {
2358         del_seq_find_replace_recurs(scene, seq);
2359       }
2360     }
2361     else {
2362       del_seq_clear_modifiers_recurs(scene, seq);
2363     }
2364   }
2365
2366   /* delete all selected strips */
2367   recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0);
2368
2369   /* updates lengths etc */
2370   seq = ed->seqbasep->first;
2371   while (seq) {
2372     BKE_sequence_calc(scene, seq);
2373     seq = seq->next;
2374   }
2375
2376   /* free parent metas */
2377   ms = ed->metastack.last;
2378   while (ms) {
2379     BKE_sequence_calc(scene, ms->parseq);
2380     ms = ms->prev;
2381   }
2382
2383   DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
2384   DEG_relations_tag_update(bmain);
2385   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2386
2387   return OPERATOR_FINISHED;
2388 }
2389
2390 static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
2391 {
2392   ARegion *ar = CTX_wm_region(C);
2393
2394   if (ar->regiontype == RGN_TYPE_WINDOW) {
2395     /* bounding box of 30 pixels is used for markers shortcuts,
2396      * prevent conflict with markers shortcuts here
2397      */
2398     if (event->mval[1] <= 30) {
2399       return OPERATOR_PASS_THROUGH;
2400     }
2401   }
2402
2403   return WM_operator_confirm(C, op, event);
2404 }
2405
2406 void SEQUENCER_OT_delete(wmOperatorType *ot)
2407 {
2408
2409   /* identifiers */
2410   ot->name = "Erase Strips";
2411   ot->idname = "SEQUENCER_OT_delete";
2412   ot->description = "Erase selected strips from the sequencer";
2413
2414   /* api callbacks */
2415   ot->invoke = sequencer_delete_invoke;
2416   ot->exec = sequencer_delete_exec;
2417   ot->poll = sequencer_edit_poll;
2418
2419   /* flags */
2420   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2421 }
2422
2423 /* offset clear operator */
2424 static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
2425 {
2426   Scene *scene = CTX_data_scene(C);
2427   Editing *ed = BKE_sequencer_editing_get(scene, false);
2428   Sequence *seq;
2429
2430   /* for effects, try to find a replacement input */
2431   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2432     if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
2433       seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
2434     }
2435   }
2436
2437   /* updates lengths etc */
2438   seq = ed->seqbasep->first;
2439   while (seq) {
2440     BKE_sequence_calc(scene, seq);
2441     seq = seq->next;
2442   }
2443
2444   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2445     if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
2446       if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
2447         BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
2448       }
2449     }
2450   }
2451
2452   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2453
2454   return OPERATOR_FINISHED;
2455 }
2456
2457 void SEQUENCER_OT_offset_clear(wmOperatorType *ot)
2458 {
2459
2460   /* identifiers */
2461   ot->name = "Clear Strip Offset";
2462   ot->idname = "SEQUENCER_OT_offset_clear";
2463   ot->description = "Clear strip offsets from the start and end frames";
2464
2465   /* api callbacks */
2466   ot->exec = sequencer_offset_clear_exec;
2467   ot->poll = sequencer_edit_poll;
2468
2469   /* flags */
2470   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2471 }
2472
2473 /* separate_images operator */
2474 static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
2475 {
2476   Scene *scene = CTX_data_scene(C);
2477   Editing *ed = BKE_sequencer_editing_get(scene, false);
2478
2479   Sequence *seq, *seq_new;
2480   Strip *strip_new;
2481   StripElem *se, *se_new;
2482   int start_ofs, cfra, frame_end;
2483   int step = RNA_int_get(op->ptr, "length");
2484
2485   seq = ed->seqbasep->first; /* poll checks this is valid */
2486
2487   while (seq) {
2488     if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
2489       Sequence *seq_next;
2490
2491       /* remove seq so overlap tests don't conflict,
2492        * see seq_free_sequence below for the real freeing. */
2493       BLI_remlink(ed->seqbasep, seq);
2494       /* if (seq->ipo) id_us_min(&seq->ipo->id); */
2495       /* XXX, remove fcurve and assign to split image strips */
2496
2497       start_ofs = cfra = BKE_sequence_tx_get_final_left(seq, false);
2498       frame_end = BKE_sequence_tx_get_final_right(seq, false);
2499
2500       while (cfra < frame_end) {
2501         /* new seq */
2502         se = BKE_sequencer_give_stripelem(seq, cfra);
2503
2504         seq_new = BKE_sequence_dupli_recursive(
2505             scene, scene, ed->seqbasep, seq, SEQ_DUPE_UNIQUE_NAME);
2506
2507         seq_new->start = start_ofs;
2508         seq_new->type = SEQ_TYPE_IMAGE;
2509         seq_new->len = 1;
2510         seq_new->endstill = step - 1;
2511
2512         /* new strip */
2513         strip_new = seq_new->strip;
2514         strip_new->us = 1;
2515
2516         /* new stripdata (only one element now!) */
2517         /* Note this assume all elements (images) have the same dimension,
2518          * since we only copy the name here. */
2519         se_new = MEM_reallocN(strip_new->stripdata, sizeof(*se_new));
2520         BLI_strncpy(se_new->name, se->name, sizeof(se_new->name));
2521         strip_new->stripdata = se_new;
2522
2523         BKE_sequence_calc(scene, seq_new);
2524
2525         if (step > 1) {
2526           seq_new->flag &= ~SEQ_OVERLAP;
2527           if (BKE_sequence_test_overlap(ed->seqbasep, seq_new)) {
2528             BKE_sequence_base_shuffle(ed->seqbasep, seq_new, scene);
2529           }
2530         }
2531
2532         /* XXX, COPY FCURVES */
2533
2534         cfra++;
2535         start_ofs += step;
2536       }
2537
2538       seq_next = seq->next;
2539       BKE_sequence_free(scene, seq);
2540       seq = seq_next;
2541     }
2542     else {
2543       seq = seq->next;
2544     }
2545   }
2546
2547   /* as last: */
2548   BKE_sequencer_sort(scene);
2549
2550   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2551
2552   return OPERATOR_FINISHED;
2553 }
2554
2555 void SEQUENCER_OT_images_separate(wmOperatorType *ot)
2556 {
2557   /* identifiers */
2558   ot->name = "Separate Images";
2559   ot->idname = "SEQUENCER_OT_images_separate";
2560   ot->description = "On image sequence strips, it returns a strip for each image";
2561
2562   /* api callbacks */
2563   ot->exec = sequencer_separate_images_exec;
2564   ot->invoke = WM_operator_props_popup_confirm;
2565   ot->poll = sequencer_edit_poll;
2566
2567   /* flags */
2568   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2569
2570   RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000);
2571 }
2572
2573 /* META Operators */
2574
2575 /* separate_meta_toggle operator */
2576 static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
2577 {
2578   Scene *scene = CTX_data_scene(C);
2579   Editing *ed = BKE_sequencer_editing_get(scene, false);
2580   Sequence *last_seq = BKE_sequencer_active_get(scene);
2581   MetaStack *ms;
2582
2583   if (last_seq && last_seq->type == SEQ_TYPE_META && last_seq->flag & SELECT) {
2584     /* Enter Metastrip */
2585     ms = MEM_mallocN(sizeof(MetaStack), "metastack");
2586     BLI_addtail(&ed->metastack, ms);
2587     ms->parseq = last_seq;
2588     ms->oldbasep = ed->seqbasep;
2589     copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp);
2590
2591     ed->seqbasep = &last_seq->seqbase;
2592
2593     BKE_sequencer_active_set(scene, NULL);
2594   }
2595   else {
2596     /* Exit Metastrip (if possible) */
2597
2598     Sequence *seq;
2599
2600     if (BLI_listbase_is_empty(&ed->metastack)) {
2601       return OPERATOR_CANCELLED;
2602     }
2603
2604     ms = ed->metastack.last;
2605     BLI_remlink(&ed->metastack, ms);
2606
2607     ed->seqbasep = ms->oldbasep;
2608
2609     /* for old files, update from meta */
2610     if (ms->disp_range[0] == ms->disp_range[1]) {
2611       copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp);
2612     }
2613
2614     /* recalc all: the meta can have effects connected to it */
2615     for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2616       BKE_sequence_calc(scene, seq);
2617     }
2618
2619     /* 2.73+, keeping endpoints is important!
2620      * moving them around means you can't usefully use metas in a complex edit. */
2621 #if 1
2622     BKE_sequence_tx_set_final_left(ms->parseq, ms->disp_range[0]);
2623     BKE_sequence_tx_set_final_right(ms->parseq, ms->disp_range[1]);
2624     BKE_sequence_single_fix(ms->parseq);
2625     BKE_sequence_calc(scene, ms->parseq);
2626 #else
2627     if (BKE_sequence_test_overlap(ed->seqbasep, ms->parseq)) {
2628       BKE_sequence_base_shuffle(ed->seqbasep, ms->parseq, scene);
2629     }
2630 #endif
2631
2632     BKE_sequencer_active_set(scene, ms->parseq);
2633
2634     ms->parseq->flag |= SELECT;
2635     recurs_sel_seq(ms->parseq);
2636
2637     MEM_freeN(ms);
2638   }
2639
2640   DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
2641   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2642
2643   return OPERATOR_FINISHED;
2644 }
2645
2646 void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
2647 {
2648   /* identifiers */
2649   ot->name = "Toggle Meta Strip";
2650   ot->idname = "SEQUENCER_OT_meta_toggle";
2651   ot->description = "Toggle a metastrip (to edit enclosed strips)";
2652
2653   /* api callbacks */
2654   ot->exec = sequencer_meta_toggle_exec;
2655   ot->poll = sequencer_edit_poll;
2656
2657   /* flags */
2658   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2659 }
2660
2661 /* separate_meta_make operator */
2662 static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
2663 {
2664   Scene *scene = CTX_data_scene(C);
2665   Editing *ed = BKE_sequencer_editing_get(scene, false);
2666
2667   Sequence *seq, *seqm, *next, *last_seq = BKE_sequencer_active_get(scene);
2668   int channel_max = 1;
2669
2670   if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
2671     BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
2672     return OPERATOR_CANCELLED;
2673   }
2674
2675   /* remove all selected from main list, and put in meta */
2676
2677   seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1, SEQ_TYPE_META); /* channel number set later */
2678   strcpy(seqm->name + 2, "MetaStrip");
2679   seqm->flag = SELECT;
2680
2681   seq = ed->seqbasep->first;
2682   while (seq) {
2683     next = seq->next;
2684     if (seq != seqm && (seq->flag & SELECT)) {
2685       BKE_sequence_invalidate_cache_composite(scene, seq);
2686       channel_max = max_ii(seq->machine, channel_max);
2687       BLI_remlink(ed->seqbasep, seq);
2688       BLI_addtail(&seqm->seqbase, seq);
2689     }
2690     seq = next;
2691   }
2692   seqm->machine = last_seq ? last_seq->machine : channel_max;
2693   BKE_sequence_calc(scene, seqm);
2694
2695   BKE_sequencer_active_set(scene, seqm);
2696
2697   if (BKE_sequence_test_overlap(ed->seqbasep, seqm)) {
2698     BKE_sequence_base_shuffle(ed->seqbasep, seqm, scene);
2699   }
2700
2701   DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
2702
2703   BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqm);
2704   BKE_sequence_invalidate_cache_composite(scene, seqm);
2705   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2706
2707   return OPERATOR_FINISHED;
2708 }
2709
2710 void SEQUENCER_OT_meta_make(wmOperatorType *ot)
2711 {
2712   /* identifiers */
2713   ot->name = "Make Meta Strip";
2714   ot->idname = "SEQUENCER_OT_meta_make";
2715   ot->description = "Group selected strips into a metastrip";
2716
2717   /* api callbacks */
2718   ot->exec = sequencer_meta_make_exec;
2719   ot->poll = sequencer_edit_poll;
2720
2721   /* flags */
2722   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2723 }
2724
2725 static int seq_depends_on_meta(Sequence *seq, Sequence *seqm)
2726 {
2727   if (seq == seqm) {
2728     return 1;
2729   }
2730   else if (seq->seq1 && seq_depends_on_meta(seq->seq1, seqm)) {
2731     return 1;
2732   }
2733   else if (seq->seq2 && seq_depends_on_meta(seq->seq2, seqm)) {
2734     return 1;
2735   }
2736   else if (seq->seq3 && seq_depends_on_meta(seq->seq3, seqm)) {
2737     return 1;
2738   }
2739   else {
2740     return 0;
2741   }
2742 }
2743
2744 /* separate_meta_make operator */
2745 static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
2746 {
2747   Scene *scene = CTX_data_scene(C);
2748   Editing *ed = BKE_sequencer_editing_get(scene, false);
2749
2750   Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); /* last_seq checks (ed == NULL) */
2751
2752   if (last_seq == NULL || last_seq->type != SEQ_TYPE_META) {
2753     return OPERATOR_CANCELLED;
2754   }
2755
2756   for (seq = last_seq->seqbase.first; seq != NULL; seq = seq->next) {
2757     BKE_sequence_invalidate_cache_composite(scene, seq);
2758   }
2759
2760   BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase);
2761
2762   BLI_listbase_clear(&last_seq->seqbase);
2763
2764   BLI_remlink(ed->seqbasep, last_seq);
2765   BKE_sequence_free(scene, last_seq);
2766
2767   /* empty meta strip, delete all effects depending on it */
2768   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2769     if ((seq->type & SEQ_TYPE_EFFECT) && seq_depends_on_meta(seq, last_seq)) {
2770       seq->flag |= SEQ_FLAG_DELETE;
2771     }
2772   }
2773
2774   recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0);
2775
2776   /* test for effects and overlap
2777    * don't use SEQP_BEGIN since that would be recursive */
2778   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2779     if (seq->flag & SELECT) {
2780       seq->flag &= ~SEQ_OVERLAP;
2781       if (BKE_sequence_test_overlap(ed->seqbasep, seq)) {
2782         BKE_sequence_base_shuffle(ed->seqbasep, seq, scene);
2783       }
2784     }
2785   }
2786
2787   BKE_sequencer_sort(scene);
2788   DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
2789
2790   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
2791
2792   return OPERATOR_FINISHED;
2793 }
2794
2795 void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
2796 {
2797   /* identifiers */
2798   ot->name = "UnMeta Strip";
2799   ot->idname = "SEQUENCER_OT_meta_separate";
2800   ot->description = "Put the contents of a metastrip back in the sequencer";
2801
2802   /* api callbacks */
2803   ot->exec = sequencer_meta_separate_exec;
2804   ot->poll = sequencer_edit_poll;
2805
2806   /* flags */
2807   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2808 }
2809
2810 /* view_all operator */
2811 static int sequencer_view_all_exec(bContext *C, wmOperator *op)
2812 {
2813   ARegion *ar = CTX_wm_region(C);
2814   View2D *v2d = UI_view2d_fromcontext(C);
2815   const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
2816
2817   UI_view2d_smooth_view(C, ar, &v2d->tot, smooth_viewtx);
2818   return OPERATOR_FINISHED;
2819 }
2820
2821 void SEQUENCER_OT_view_all(wmOperatorType *ot)
2822 {
2823   /* identifiers */
2824   ot->name = "View All";
2825   ot->idname = "SEQUENCER_OT_view_all";
2826   ot->description = "View all the strips in the sequencer";
2827
2828   /* api callbacks */
2829   ot->exec = sequencer_view_all_exec;
2830   ot->poll = ED_operator_sequencer_active;
2831
2832   /* flags */
2833   ot->flag = OPTYPE_REGISTER;
2834 }
2835
2836 static int sequencer_view_frame_exec(bContext *C, wmOperator *op)
2837 {
2838   const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
2839   ANIM_center_frame(C, smooth_viewtx);
2840
2841   return OPERATOR_FINISHED;
2842 }
2843
2844 void SEQUENCER_OT_view_frame(wmOperatorType *ot)
2845 {
2846   /* identifiers */
2847   ot->name = "View Frame";
2848   ot->idname = "SEQUENCER_OT_view_frame";
2849   ot->description = "Reset viewable area to show range around current frame";
2850
2851   /* api callbacks */
2852   ot->exec = sequencer_view_frame_exec;
2853   ot->poll = ED_operator_sequencer_active;
2854
2855   /* flags */
2856   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2857 }
2858
2859 /* view_all operator */
2860 static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op))
2861 {
2862   bScreen *sc = CTX_wm_screen(C);
2863   ScrArea *area = CTX_wm_area(C);
2864 #if 0
2865   ARegion *ar = CTX_wm_region(C);
2866   SpaceSeq *sseq = area->spacedata.first;
2867   Scene *scene = CTX_data_scene(C);
2868 #endif
2869   View2D *v2d = UI_view2d_fromcontext(C);
2870
2871   v2d->cur = v2d->tot;
2872   UI_view2d_curRect_validate(v2d);
2873   UI_view2d_sync(sc, area, v2d, V2D_LOCK_COPY);
2874
2875 #if 0
2876   /* Like zooming on an image view */
2877   float zoomX, zoomY;
2878   int width, height, imgwidth, imgheight;
2879
2880   width = ar->winx;
2881   height = ar->winy;
2882
2883   seq_reset_imageofs(sseq);
2884
2885   imgwidth = (scene->r.size * scene->r.xsch) / 100;
2886   imgheight = (scene->r.size * scene->r.ysch) / 100;
2887
2888   /* Apply aspect, dosnt need to be that accurate */
2889   imgwidth = (int)(imgwidth * (scene->r.xasp / scene->r.yasp));
2890
2891   if (((imgwidth >= width) || (imgheight >= height)) && ((width > 0) && (height > 0))) {
2892     /* Find the zoom value that will fit the image in the image space */
2893     zoomX = ((float)width) / ((float)imgwidth);
2894     zoomY = ((float)height) / ((float)imgheight);
2895     sseq->zoom = (zoomX < zoomY) ? zoomX : zoomY;
2896
2897     sseq->zoom = 1.0f / power_of_2(1 / min_ff(zoomX, zoomY));
2898   }
2899   else {
2900     sseq->zoom = 1.0f;
2901   }
2902 #endif
2903
2904   ED_area_tag_redraw(CTX_wm_area(C));
2905   return OPERATOR_FINISHED;
2906 }
2907
2908 void SEQUENCER_OT_view_all_preview(wmOperatorType *ot)
2909 {
2910   /* identifiers */
2911   ot->name = "View All";
2912   ot->idname = "SEQUENCER_OT_view_all_preview";
2913   ot->description = "Zoom preview to fit in the area";
2914
2915   /* api callbacks */
2916   ot->exec = sequencer_view_all_preview_exec;
2917   ot->poll = ED_operator_sequencer_active;
2918
2919   /* flags */
2920   ot->flag = OPTYPE_REGISTER;
2921 }
2922
2923 static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
2924 {
2925   RenderData *rd = &CTX_data_scene(C)->r;
2926   View2D *v2d = UI_view2d_fromcontext(C);
2927
2928   float ratio = RNA_float_get(op->ptr, "ratio");
2929
2930   float winx = (int)(rd->size * rd->xsch) / 100;
2931   float winy = (int)(rd->size * rd->ysch) / 100;
2932
2933   float facx = BLI_rcti_size_x(&v2d->mask) / winx;
2934   float facy = BLI_rcti_size_y(&v2d->mask) / winy;
2935
2936   BLI_rctf_resize(&v2d->cur, ceilf(winx * facx / ratio + 0.5f), ceilf(winy * facy / ratio + 0.5f));
2937
2938   ED_region_tag_redraw(CTX_wm_region(C));
2939
2940   return OPERATOR_FINISHED;
2941 }
2942
2943 void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
2944 {
2945   /* identifiers */
2946   ot->name = "Sequencer View Zoom Ratio";
2947   ot->idname = "SEQUENCER_OT_view_zoom_ratio";
2948   ot->description = "Change zoom ratio of sequencer preview";
2949
2950   /* api callbacks */
2951   ot->exec = sequencer_view_zoom_ratio_exec;
2952   ot->poll = ED_operator_sequencer_active;
2953
2954   /* properties */
2955   RNA_def_float(ot->srna,
2956                 "ratio",
2957                 1.0f,
2958                 -FLT_MAX,
2959                 FLT_MAX,
2960                 "Ratio",
2961                 "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out",
2962                 -FLT_MAX,
2963                 FLT_MAX);
2964 }
2965
2966 #if 0
2967 static const EnumPropertyItem view_type_items[] = {
2968     {SEQ_VIEW_SEQUENCE, "SEQUENCER", ICON_SEQ_SEQUENCER, "Sequencer", ""},
2969     {SEQ_VIEW_PREVIEW, "PREVIEW", ICON_SEQ_PREVIEW, "Image Preview", ""},
2970     {SEQ_VIEW_SEQUENCE_PREVIEW,
2971      "SEQUENCER_PREVIEW",
2972      ICON_SEQ_SEQUENCER,
2973      "Sequencer and Image Preview",
2974      ""},
2975     {0, NULL, 0, NULL, NULL},
2976 };
2977 #endif
2978
2979 /* view_all operator */
2980 static int sequencer_view_toggle_exec(bContext *C, wmOperator *UNUSED(op))
2981 {
2982   SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C);
2983
2984   sseq->view++;
2985   if (sseq->view > SEQ_VIEW_SEQUENCE_PREVIEW) {
2986     sseq->view = SEQ_VIEW_SEQUENCE;
2987   }
2988
2989   ED_area_tag_refresh(CTX_wm_area(C));
2990
2991   return OPERATOR_FINISHED;
2992 }
2993
2994 void SEQUENCER_OT_view_toggle(wmOperatorType *ot)
2995 {
2996   /* identifiers */
2997   ot->name = "View Toggle";
2998   ot->idname = "SEQUENCER_OT_view_toggle";
2999   ot->description = "Toggle between sequencer views (sequence, preview, both)";
3000
3001   /* api callbacks */
3002   ot->exec = sequencer_view_toggle_exec;
3003   ot->poll = ED_operator_sequencer_active;
3004
3005   /* flags */
3006   ot->flag = OPTYPE_REGISTER;
3007 }
3008
3009 /* view_selected operator */
3010 static int sequencer_view_selected_exec(bContext *C, wmOperator *op)
3011 {
3012   Scene *scene = CTX_data_scene(C);
3013   View2D *v2d = UI_view2d_fromcontext(C);
3014   ARegion *ar = CTX_wm_region(C);
3015   Editing *ed = BKE_sequencer_editing_get(scene, false);
3016   Sequence *last_seq = BKE_sequencer_active_get(scene);
3017   Sequence *seq;
3018   rctf cur_new = v2d->cur;
3019
3020   int xmin = MAXFRAME * 2;
3021   int xmax = -MAXFRAME * 2;
3022   int ymin = MAXSEQ + 1;
3023   int ymax = 0;
3024   int orig_height;
3025   int ymid;
3026   int ymargin = 1;
3027   int xmargin = FPS;
3028
3029   if (ed == NULL) {
3030     return OPERATOR_CANCELLED;
3031   }
3032
3033   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
3034     if ((seq->flag & SELECT) || (seq == last_seq)) {
3035       xmin = min_ii(xmin, seq->startdisp);
3036       xmax = max_ii(xmax, seq->enddisp);
3037
3038       ymin = min_ii(ymin, seq->machine);
3039       ymax = max_ii(ymax, seq->machine);
3040     }
3041   }
3042
3043   if (ymax != 0) {
3044     const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
3045
3046     xmax += xmargin;
3047     xmin -= xmargin;
3048     ymax += ymargin;
3049     ymin -= ymargin;
3050
3051     orig_height = BLI_rctf_size_y(&cur_new);
3052
3053     cur_new.xmin = xmin;
3054     cur_new.xmax = xmax;
3055
3056     cur_new.ymin = ymin;
3057     cur_new.ymax = ymax;
3058
3059     /* only zoom out vertically */
3060     if (orig_height > BLI_rctf_size_y(&cur_new)) {
3061       ymid = BLI_rctf_cent_y(&cur_new);
3062
3063       cur_new.ymin = ymid - (orig_height / 2);
3064       cur_new.ymax = ymid + (orig_height / 2);
3065     }
3066
3067     UI_view2d_smooth_view(C, ar, &cur_new, smooth_viewtx);
3068
3069     return OPERATOR_FINISHED;
3070   }
3071   else {
3072     return OPERATOR_CANCELLED;
3073   }
3074 }
3075
3076 void SEQUENCER_OT_view_selected(wmOperatorType *ot)
3077 {
3078   /* identifiers */
3079   ot->name = "View Selected";
3080   ot->idname = "SEQUENCER_OT_view_selected";
3081   ot->description = "Zoom the sequencer on the selected strips";
3082
3083   /* api callbacks */
3084   ot->exec = sequencer_view_selected_exec;
3085   ot->poll = ED_operator_sequencer_active;
3086
3087   /* flags */
3088   ot->flag = OPTYPE_REGISTER;
3089 }
3090
3091 static bool strip_jump_internal(Scene *scene,
3092                                 const short side,
3093                                 const bool do_skip_mute,
3094                                 const bool do_center)
3095 {
3096   bool changed = false;
3097   int cfra = CFRA;
3098   int nfra = BKE_sequencer_find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center, false);
3099
3100   if (nfra != cfra) {
3101     CFRA = nfra;
3102     changed = true;
3103   }
3104
3105   return changed;
3106 }
3107
3108 static bool sequencer_strip_jump_poll(bContext *C)
3109 {
3110   /* prevent changes during render */
3111   if (G.is_rendering) {
3112     return 0;
3113   }
3114
3115   return sequencer_edit_poll(C);
3116 }
3117
3118 /* jump frame to edit point operator */
3119 static int sequencer_strip_jump_exec(bContext *C, wmOperator *op)
3120 {
3121   Scene *scene = CTX_data_scene(C);
3122   const bool next = RNA_boolean_get(op->ptr, "next");
3123   const bool center = RNA_boolean_get(op->ptr, "center");
3124
3125   /* currently do_skip_mute is always true */
3126   if (!strip_jump_internal(scene, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, true, center)) {
3127     return OPERATOR_CANCELLED;
3128   }
3129
3130   WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
3131
3132   return OPERATOR_FINISHED;
3133 }
3134
3135 void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
3136 {
3137   /* identifiers */
3138   ot->name = "Jump to Strip";
3139   ot->idname = "SEQUENCER_OT_strip_jump";
3140   ot->description = "Move frame to previous edit point";
3141
3142   /* api callbacks */
3143   ot->exec = sequencer_strip_jump_exec;
3144   ot->poll = sequencer_strip_jump_poll;
3145
3146   /* flags */
3147   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3148
3149   /* properties */
3150   RNA_def_boolean(ot->srna, "next", true, "Next Strip", "");
3151   RNA_def_boolean(ot->srna, "center", true, "Use strip center", "");
3152 }
3153
3154 static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
3155 {
3156   int gap = seqb->startdisp - seqa->enddisp;
3157   int seq_a_start;
3158   int seq_b_start;
3159
3160   seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp;
3161   BKE_sequence_translate(scene, seqb, seq_b_start - seqb->start);
3162   BKE_sequence_calc(scene, seqb);
3163
3164   seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
3165   BKE_sequence_translate(scene, seqa, seq_a_start - seqa->start);
3166   BKE_sequence_calc(scene, seqa);
3167 }
3168
3169 #if 0
3170 static Sequence *sequence_find_parent(Scene *scene, Sequence *child)
3171 {
3172   Editing *ed = BKE_sequencer_editing_get(scene, false);
3173   Sequence *parent = NULL;
3174   Sequence *seq;
3175
3176   if (ed == NULL) {
3177     return NULL;
3178   }
3179
3180   for (seq = ed->seqbasep->first; seq; seq = seq->next) {
3181     if ((seq != child) && seq_is_parent(seq, child)) {
3182       parent = seq;
3183       break;
3184     }
3185   }
3186
3187   return parent;
3188 }
3189 #endif
3190
3191 static int sequencer_swap_exec(bContext *C, wmOperator *op)
3192 {
3193   Scene *scene = CTX_data_scene(C);
3194   Editing *ed = BKE_sequencer_editing_get(scene, false);
3195   Sequence *active_seq = BKE_sequencer_active_get(scene);
3196   Sequence *seq, *iseq;
3197   int side = RNA_enum_get(op->ptr, "side");
3198
3199   if (active_seq == NULL) {
3200     return OPERATOR_CANCELLED;
3201   }
3202
3203   seq = find_next_prev_sequence(scene, active_seq, side, -1);
3204
3205   if (seq) {
3206
3207     /* disallow effect strips */
3208     if (BKE_sequence_effect_get_num_inputs(seq->type) >= 1 &&
3209         (seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3)) {
3210       return OPERATOR_CANCELLED;
3211     }
3212     if ((BKE_sequence_effect_get_num_inputs(active_seq->type) >= 1) &&
3213         (active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3)) {
3214       return OPERATOR_CANCELLED;
3215     }
3216
3217     switch (side) {
3218       case SEQ_SIDE_LEFT:
3219         swap_sequence(scene, seq, active_seq);
3220         break;
3221       case SEQ_SIDE_RIGHT:
3222         swap_sequence(scene, active_seq, seq);
3223         break;
3224     }
3225
3226     // XXX - should be a generic function
3227     for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
3228       if ((iseq->type & SEQ_TYPE_EFFECT) &&
3229           (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
3230         BKE_sequence_calc(scene, iseq);
3231       }
3232     }
3233
3234     /* do this in a new loop since both effects need to be calculated first */
3235     for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
3236       if ((iseq->type & SEQ_TYPE_EFFECT) &&
3237           (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
3238         /* this may now overlap */
3239         if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) {
3240           BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene);
3241         }
3242       }
3243     }
3244
3245     BKE_sequencer_sort(scene);
3246
3247     WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
3248
3249     return OPERATOR_FINISHED;
3250   }
3251
3252   return OPERATOR_CANCELLED;
3253 }
3254
3255 void SEQUENCER_OT_swap(wmOperatorType *ot)
3256 {
3257   /* identifiers */
3258   ot->name = "Swap Strip";
3259   ot->idname = "SEQUENCER_OT_swap";
3260   ot->description = "Swap active strip with strip to the right or left";
3261
3262   /* api callbacks */
3263   ot->exec = sequencer_swap_exec;
3264   ot->poll = sequencer_edit_poll;
3265
3266   /* flags */
3267   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3268
3269   /* properties */
3270   RNA_def_enum(
3271       ot->srna, "side", prop_side_lr_types, SEQ_SIDE_RIGHT, "Side", "Side of the strip to swap");
3272 }
3273
3274 static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op))
3275 {
3276   int retval = OPERATOR_CANCELLED;
3277   Scene *scene = CTX_data_scene(C);
3278   Sequence *active_seq = BKE_sequencer_active_get(scene);
3279   StripElem *se = NULL;
3280
3281   if (active_seq == NULL) {
3282     return OPERATOR_CANCELLED;
3283   }
3284
3285   if (active_seq->strip) {
3286     switch (active_seq->type) {
3287       case SEQ_TYPE_IMAGE:
3288         se = BKE_sequencer_give_stripelem(active_seq, scene->r.cfra);
3289         break;
3290       case SEQ_TYPE_MOVIE:
3291         se = active_seq->strip->stripdata;
3292         break;
3293       case SEQ_TYPE_SCENE:
3294       case SEQ_TYPE_META:
3295       case SEQ_TYPE_SOUND_RAM:
3296       case SEQ_TYPE_SOUND_HD:
3297       default:
3298         break;
3299     }
3300   }
3301
3302   if (se) {
3303     // prevent setting the render size if sequence values aren't initialized
3304     if ((se->orig_width > 0) && (se->orig_height > 0)) {
3305       scene->r.xsch = se->orig_width;
3306       scene->r.ysch = se->orig_height;
3307       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
3308       retval = OPERATOR_FINISHED;
3309     }
3310   }
3311
3312   return retval;
3313 }
3314
3315 void SEQUENCER_OT_rendersize(wmOperatorType *ot)
3316 {
3317   /* identifiers */
3318   ot->name = "Set Render Size";
3319   ot->idname = "SEQUENCER_OT_rendersize";
3320   ot->description = "Set render size and aspect from active sequence";
3321
3322   /* api callbacks */
3323   ot->exec = sequencer_rendersize_exec;
3324   ot->poll = sequencer_edit_poll;
3325
3326   /* flags */
3327   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3328
3329   /* properties */
3330 }
3331
3332 static void seq_copy_del_sound(Scene *scene, Sequence *seq)
3333 {
3334   if (seq->type == SEQ_TYPE_META) {
3335     Sequence *iseq;
3336     for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) {
3337       seq_copy_del_sound(scene, iseq);
3338     }
3339   }
3340   else if (seq->scene_sound) {
3341     BKE_sound_remove_scene_sound(scene, seq->scene_sound);
3342     seq->scene_sound = NULL;
3343   }
3344 }
3345
3346 static int sequencer_copy_exec(bContext *C, wmOperator *op)
3347 {
3348   Main *bmain = CTX_data_main(C);
3349   Scene *scene = CTX_data_scene(C);
3350   Editing *ed = BKE_sequencer_editing_get(scene, false);
3351
3352   ListBase nseqbase = {NULL, NULL};
3353
3354   BKE_sequencer_free_clipboard();
3355
3356   if (BKE_sequence_base_isolated_sel_check(ed->seqbasep) == false) {
3357     BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
3358     return OPERATOR_CANCELLED;
3359   }
3360
3361   BKE_sequence_base_dupli_recursive(
3362       scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME, LIB_ID_CREATE_NO_USER_REFCOUNT);
3363
3364   /* To make sure the copied strips have unique names between each other add
3365    * them temporarily to the end of the original seqbase. (bug 25932)
3366    */
3367   if (nseqbase.first) {
3368     Sequence *seq, *first_seq = nseqbase.first;
3369     BLI_movelisttolist(ed->seqbasep, &nseqbase);
3370
3371     for (seq = first_seq; seq; seq = seq->next) {
3372       BKE_sequencer_recursive_apply(seq, apply_unique_name_cb, scene);
3373     }
3374
3375     seqbase_clipboard.first = first_seq;
3376     seqbase_clipboard.last = ed->seqbasep->last;
3377
3378     if (first_seq->prev) {
3379       first_seq->prev->next = NULL;
3380       ed->seqbasep->last = first_seq->prev;
3381       first_seq->prev = NULL;
3382     }
3383   }
3384
3385   seqbase_clipboard_frame = scene->r.cfra;
3386
3387   /* Need to remove anything that references the current scene */
3388   for (Sequence *seq = seqbase_clipboard.first; seq; seq = seq->next) {
3389     seq_copy_del_sound(scene, seq);
3390   }
3391
3392   /* Replace datablock pointers with copies, to keep things working in case
3393    * datablocks get deleted or another .blend file is opened. */
3394   BKE_sequencer_base_clipboard_pointers_store(bmain, &seqbase_clipboard);
3395
3396   return OPERATOR_FINISHED;
3397 }
3398
3399 void SEQUENCER_OT_copy(wmOperatorType *ot)
3400 {
3401   /* identifiers */
3402   ot->name = "Copy";
3403   ot->idname = "SEQUENCER_OT_copy";
3404
3405   /* api callbacks */
3406   ot->exec = sequencer_copy_exec;
3407   ot->poll = sequencer_edit_poll;
3408
3409   /* flags */
3410   ot->flag = OPTYPE_REGISTER;
3411
3412   /* properties */
3413 }
3414
3415 static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
3416 {
3417   Main *bmain = CTX_data_main(C);
3418   Scene *scene = CTX_data_scene(C);
3419   Editing *ed = BKE_sequencer_editing_get(scene, true); /* create if needed */
3420   ListBase nseqbase = {NULL, NULL};
3421   int ofs;
3422   Sequence *iseq, *iseq_first;
3423
3424   ED_sequencer_deselect_all(scene);
3425   ofs = scene->r.cfra - seqbase_clipboard_frame;
3426
3427   /* Copy strips, temporarily restoring pointers to actual datablocks. This
3428    * must happen on the clipboard itself, so that copying does user counting
3429    * on the actual datablocks. */
3430   BKE_sequencer_base_clipboard_pointers_restore(&seqbase_clipboard, bmain);
3431   BKE_sequence_base_dupli_recursive(
3432       scene, scene, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME, 0);
3433   BKE_sequencer_base_clipboard_pointers_store(bmain, &seqbase_clipboard);
3434
3435   /* transform pasted strips before adding */
3436   if (ofs) {
3437     for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
3438       BKE_sequence_translate(scene, iseq, ofs);
3439     }
3440   }
3441
3442   for (iseq = nseqbase.first; iseq; iseq = iseq->next) {
3443     BKE_sequence_sound_init(scene, iseq);
3444   }
3445
3446   iseq_first = nseqbase.first;
3447
3448   BLI_movelisttolist(ed->seqbasep, &nseqbase);
3449
3450   /* make sure the pasted strips have unique names between them */
3451   for (iseq = iseq_first; iseq; iseq = iseq->next) {
3452     BKE_sequencer_recursive_apply(iseq, apply_unique_name_cb, scene);
3453   }
3454
3455   /* ensure pasted strips don't overlap */
3456   for (iseq = iseq_first; iseq; iseq = iseq->next) {
3457     if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) {
3458       BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene);
3459     }
3460   }
3461
3462   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
3463
3464   return OPERATOR_FINISHED;
3465 }
3466
3467 void SEQUENCER_OT_paste(wmOperatorType *ot)
3468 {
3469   /* identifiers */
3470   ot->name = "Paste";
3471   ot->idname = "SEQUENCER_OT_paste";
3472
3473   /* api callbacks */
3474   ot->exec = sequencer_paste_exec;
3475   ot->poll = ED_operator_sequencer_active;
3476
3477   /* flags */
3478   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3479
3480   /* properties */
3481 }
3482
3483 static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
3484 {
3485   Scene *scene = CTX_data_scene(C);
3486   Sequence *seq_act;
3487   Sequence *seq_other;
3488   const char *error_msg;
3489
3490   if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) {
3491     BKE_report(op->reports, RPT_ERROR, "Please select two strips");
3492     return OPERATOR_CANCELLED;
3493   }
3494
3495   if (BKE_sequence_swap(seq_act, seq_other, &error_msg) == 0) {
3496     BKE_report(op->reports, RPT_ERROR, error_msg);
3497     return OPERATOR_CANCELLED;
3498   }
3499
3500   if (seq_act->scene_sound) {
3501     BKE_sound_remove_scene_sound(scene, seq_act->scene_sound);
3502   }
3503
3504   if (seq_other->scene_sound) {
3505     BKE_sound_remove_scene_sound(scene, seq_other->scene_sound);
3506   }
3507
3508   seq_act->scene_sound = NULL;
3509   seq_other->scene_sound = NULL;
3510
3511   BKE_sequence_calc(scene, seq_act);
3512   BKE_sequence_calc(scene, seq_other);
3513
3514   if (seq_act->sound) {
3515     BKE_sound_add_scene_sound_defaults(scene, seq_act);
3516   }
3517   if (seq_other->sound) {
3518     BKE_sound_add_scene_sound_defaults(scene, seq_other);
3519   }
3520
3521   BKE_sequence_invalidate_cache_raw(scene, seq_act);
3522   BKE_sequence_invalidate_cache_raw(scene, seq_other);
3523
3524   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
3525
3526   return OPERATOR_FINISHED;
3527 }
3528
3529 void SEQUENCER_OT_swap_data(wmOperatorType *ot)
3530 {
3531   /* identifiers */
3532   ot->name = "Sequencer Swap Data";
3533   ot->idname = "SEQUENCER_OT_swap_data";
3534   ot->description = "Swap 2 sequencer strips";
3535
3536   /* api callbacks */
3537   ot->exec = sequencer_swap_data_exec;
3538   ot->poll = ED_operator_sequencer_active;
3539
3540   /* flags */
3541   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
3542
3543   /* properties */
3544 }
3545
3546 /* box select operator */
3547 static int view_ghost_border_exec(bContext *C, wmOperator *op)
3548 {
3549   Scene *scene = CTX_data_scene(C);
3550   View2D *v2d = UI_view2d_fromcontext(C);
3551
3552   rctf rect;
3553
3554   /* convert coordinates of rect to 'tot' rect coordinates */
3555   WM_operator_properties_border_to_rctf(op, &rect);
3556   UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
3557
3558   rect.xmin /= fabsf(BLI_rctf_size_x(&v2d->tot));
3559   rect.ymin /= fabsf(BLI_rctf_size_y(&v2d->tot));
3560
3561   rect.xmax /= fabsf(BLI_rctf_size_x(&v2d->tot));
3562   rect.ymax /= fabsf(BLI_rctf_size_y(&v2d->tot));
3563
3564   rect.xmin += 0.5f;
3565   rect.xmax += 0.5f;
3566   rect.ymin += 0.5f;
3567   rect.ymax += 0.5f;
3568
3569   CLAMP(rect.xmin, 0.0f, 1.0f);
3570   CLAMP(rect.ymin, 0.0f, 1.0f);
3571   CLAMP(rect.xmax, 0.0f, 1.0f);
3572   CLAMP(rect.ymax, 0.0f, 1.0f);
3573
3574   scene->ed->over_border = rect;
3575
3576   WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
3577
3578   return OPERATOR_FINISHED;
3579 }
3580
3581 /* ****** Box Select ****** */
3582 void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
3583 {
3584   /* identifiers */
3585   ot->name = "Border Offset View";
3586   ot->idname = "SEQUENCER_OT_view_ghost_border";
3587   ot->description = "Set the boundaries of the border used for offset-view";
3588
3589   /* api callbacks */
3590   ot->invoke = WM_gesture_box_invoke;
3591   ot->exec = view_ghost_border_exec;
3592   ot->modal = WM_gesture_box_modal;
3593   ot->poll = sequencer_view_preview_poll;
3594   ot->cancel = WM_gesture_box_cancel;
3595
3596   /* flags */
3597   ot->flag = 0;
3598
3599   /* rna */
3600   WM_operator_properties_gesture_box(ot);
3601 }
3602
3603 /* rebuild_proxy operator */
3604
3605 static int sequencer_rebuild_proxy_invoke(bContext *C,
3606                                           wmOperator *UNUSED(op),
3607                                           const wmEvent *UNUSED(event))
3608 {
3609   seq_proxy_build_job(C);
3610
3611   return OPERATOR_FINISHED;
3612 }
3613
3614 static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
3615 {
3616   Main *bmain = CTX_data_main(C);
3617   struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
3618   Scene *scene = CTX_data_scene(C);
3619   Editing *ed = BKE_sequencer_editing_get(scene, false);
3620   Sequence *seq;
3621   GSet *file_list;
3622
3623   if (ed == NULL) {
3624     return OPERATOR_CANCELLED;
3625   }
3626
3627   file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list");
3628
3629   SEQP_BEGIN (ed, seq) {
3630     if ((seq->flag & SELECT)) {
3631       ListBase queue = {NULL, NULL};
3632       LinkData *link;
3633       short stop = 0, do_update;
3634       float progress;
3635
3636       BKE_sequencer_proxy_rebuild_context(bmain, depsgraph, scene, seq, file_list, &queue);
3637
3638       for (link = queue.first; link; link = link->next) {
3639         struct SeqIndexBuildContext *context = link->data;
3640         BKE_sequencer_proxy_rebuild(context, &stop, &do_update, &progress);
3641         BKE_sequencer_proxy_rebuild_finish(context, 0);
3642       }
3643       BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
3644     }
3645   }
3646   SEQ_END;
3647
3648   BLI_gset_free(file_list, MEM_freeN);
3649
3650   return OPERATOR_FINISHED;
3651 }
3652
3653 void SEQUENCER_OT_rebuild_proxy(wmOperatorType *ot)
3654 {
3655   /* identifiers */