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