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