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