Cleanup: left wrong comment in
[blender-staging.git] / source / blender / editors / space_sequencer / sequencer_edit.c
index 54e9b65e3b3f5b183e8d53a1423b0d879e9349d6..0895d28fba75fe7bd86f0997029e739c9ff4e4a8 100644 (file)
@@ -61,6 +61,7 @@
 
 /* for menu/popup icons etc etc*/
 
+#include "ED_anim_api.h"
 #include "ED_numinput.h"
 #include "ED_screen.h"
 #include "ED_transform.h"
@@ -94,6 +95,7 @@ EnumPropertyItem sequencer_prop_effect_types[] = {
        {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""},
        {SEQ_TYPE_GAUSSIAN_BLUR, "GAUSSIAN_BLUR", 0, "Gaussian Blur", ""},
        {SEQ_TYPE_TEXT, "TEXT", 0, "Text", ""},
+       {SEQ_TYPE_COLORMIX, "COLORMIX", 0, "Color Mix", ""},
        {0, NULL, 0, NULL, NULL}
 };
 
@@ -106,7 +108,7 @@ EnumPropertyItem prop_side_types[] = {
        {0, NULL, 0, NULL, NULL}
 };
 
-static EnumPropertyItem prop_side_lr_types[] = {
+static const EnumPropertyItem prop_side_lr_types[] = {
        {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
        {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
        {0, NULL, 0, NULL, NULL}
@@ -561,7 +563,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
                        }
                        if (seq1 == NULL) seq1 = seq2;
                        if (seq3 == NULL) seq3 = seq2;
-                       /* fall-through */
+                       ATTR_FALLTHROUGH;
                case 2:
                        if (seq1 == NULL || seq2 == NULL) {
                                *error_str = N_("2 selected sequence strips are needed");
@@ -669,6 +671,9 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
        Sequence *seqn = NULL;
        bool skip_dup = false;
 
+       /* Unlike soft-cut, it's important to use the same value for both strips. */
+       const bool is_end_exact = ((seq->start + seq->len) == cutframe);
+
        /* backup values */
        ts.start = seq->start;
        ts.machine = seq->machine;
@@ -681,11 +686,21 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
        ts.anim_startofs = seq->anim_startofs;
        ts.anim_endofs = seq->anim_endofs;
        ts.len = seq->len;
-       
+
        /* First Strip! */
        /* strips with extended stillfames before */
        
-       if ((seq->startstill) && (cutframe < seq->start)) {
+       /* Precaution, needed because the length saved on-disk may not match the length saved in the blend file,
+        * or our code may have minor differences reading file length between versions.
+        * This causes hard-cut to fail, see: T47862 */
+       if (seq->type != SEQ_TYPE_META) {
+               BKE_sequence_reload_new_file(scene, seq, true);
+               BKE_sequence_calc(scene, seq);
+       }
+
+       /* Important to offset the start when 'cutframe == seq->start'
+        * because we need at least one frame of content after start/end still have clipped it. */
+       if ((seq->startstill) && (cutframe <= seq->start)) {
                /* don't do funny things with METAs ... */
                if (seq->type == SEQ_TYPE_META) {
                        skip_dup = true;
@@ -699,13 +714,17 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
                }
        }
        /* normal strip */
-       else if ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len))) {
+       else if ((is_end_exact == false) &&
+                ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len))))
+       {
                seq->endofs = 0;
                seq->endstill = 0;
                seq->anim_endofs += (seq->start + seq->len) - cutframe;
        }
        /* strips with extended stillframes after */
-       else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) {
+       else if ((is_end_exact == true) ||
+                (((seq->start + seq->len) < cutframe) && (seq->endstill)))
+       {
                seq->endstill -= seq->enddisp - cutframe;
                /* don't do funny things with METAs ... */
                if (seq->type == SEQ_TYPE_META) {
@@ -718,12 +737,16 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
 
        if (!skip_dup) {
                /* Duplicate AFTER the first change */
-               seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+               seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
        }
        
        if (seqn) {
                seqn->flag |= SELECT;
-                       
+
+               /* Important not to re-assign this (unlike soft-cut) */
+#if 0
+               is_end_exact = ((seqn->start + seqn->len) == cutframe);
+#endif
                /* Second Strip! */
                /* strips with extended stillframes before */
                if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
@@ -732,9 +755,11 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
                        seqn->anim_endofs = ts.anim_endofs;
                        seqn->endstill = ts.endstill;
                }
-               
+
                /* normal strip */
-               else if ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len))) {
+               else if ((is_end_exact == false) &&
+                        ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len))))
+               {
                        seqn->start = cutframe;
                        seqn->startstill = 0;
                        seqn->startofs = 0;
@@ -743,16 +768,18 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
                        seqn->anim_endofs = ts.anim_endofs;
                        seqn->endstill = ts.endstill;
                }
-               
+
                /* strips with extended stillframes after */
-               else if (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)) {
+               else if ((is_end_exact == true) ||
+                        (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)))
+               {
                        seqn->start = cutframe;
                        seqn->startofs = 0;
                        seqn->anim_startofs += ts.len - 1;
                        seqn->endstill = ts.enddisp - cutframe - 1;
                        seqn->startstill = 0;
                }
-               
+
                BKE_sequence_reload_new_file(scene, seqn, false);
                BKE_sequence_calc(scene, seqn);
        }
@@ -765,6 +792,8 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
        Sequence *seqn = NULL;
        bool skip_dup = false;
 
+       bool is_end_exact = ((seq->start + seq->len) == cutframe);
+
        /* backup values */
        ts.start = seq->start;
        ts.machine = seq->machine;
@@ -777,11 +806,13 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
        ts.anim_startofs = seq->anim_startofs;
        ts.anim_endofs = seq->anim_endofs;
        ts.len = seq->len;
-       
+
        /* First Strip! */
        /* strips with extended stillfames before */
-       
-       if ((seq->startstill) && (cutframe < seq->start)) {
+
+       /* Important to offset the start when 'cutframe == seq->start'
+        * because we need at least one frame of content after start/end still have clipped it. */
+       if ((seq->startstill) && (cutframe <= seq->start)) {
                /* don't do funny things with METAs ... */
                if (seq->type == SEQ_TYPE_META) {
                        skip_dup = true;
@@ -795,11 +826,15 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
                }
        }
        /* normal strip */
-       else if ((cutframe >= seq->start) && (cutframe <= (seq->start + seq->len))) {
+       else if ((is_end_exact == false) &&
+                (cutframe >= seq->start) && (cutframe <= (seq->start + seq->len)))
+       {
                seq->endofs = (seq->start + seq->len) - cutframe;
        }
        /* strips with extended stillframes after */
-       else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) {
+       else if ((is_end_exact == true) ||
+                (((seq->start + seq->len) < cutframe) && (seq->endstill)))
+       {
                seq->endstill -= seq->enddisp - cutframe;
                /* don't do funny things with METAs ... */
                if (seq->type == SEQ_TYPE_META) {
@@ -811,12 +846,14 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
 
        if (!skip_dup) {
                /* Duplicate AFTER the first change */
-               seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+               seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
        }
        
        if (seqn) {
                seqn->flag |= SELECT;
-                       
+
+               is_end_exact = ((seqn->start + seqn->len) == cutframe);
+
                /* Second Strip! */
                /* strips with extended stillframes before */
                if ((seqn->startstill) && (cutframe == seqn->start + 1)) {
@@ -825,23 +862,27 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
                        seqn->endofs = ts.endofs;
                        seqn->endstill = ts.endstill;
                }
-               
+
                /* normal strip */
-               else if ((cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len))) {
+               else if ((is_end_exact == false) &&
+                        (cutframe >= seqn->start) && (cutframe <= (seqn->start + seqn->len)))
+               {
                        seqn->startstill = 0;
                        seqn->startofs = cutframe - ts.start;
                        seqn->endofs = ts.endofs;
                        seqn->endstill = ts.endstill;
                }
-               
+
                /* strips with extended stillframes after */
-               else if (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)) {
+               else if ((is_end_exact == true) ||
+                        (((seqn->start + seqn->len) < cutframe) && (seqn->endstill)))
+               {
                        seqn->start = cutframe - ts.len + 1;
                        seqn->startofs = ts.len - 1;
                        seqn->endstill = ts.enddisp - cutframe - 1;
                        seqn->startstill = 0;
                }
-               
+
                BKE_sequence_calc(scene, seqn);
        }
        return seqn;
@@ -1223,7 +1264,7 @@ static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNU
 void SEQUENCER_OT_snap(struct wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name = "Snap Strips";
+       ot->name = "Snap Strips to Frame";
        ot->idname = "SEQUENCER_OT_snap";
        ot->description = "Frame where selected strips will be snapped";
        
@@ -1497,23 +1538,20 @@ static int sequencer_slip_exec(bContext *C, wmOperator *op)
 
 static void sequencer_slip_update_header(Scene *scene, ScrArea *sa, SlipData *data, int offset)
 {
-#define HEADER_LENGTH 40
-       char msg[HEADER_LENGTH];
+       char msg[UI_MAX_DRAW_STR];
 
        if (sa) {
                if (hasNumInput(&data->num_input)) {
                        char num_str[NUM_STR_REP_LEN];
                        outputNumInput(&data->num_input, num_str, &scene->unit);
-                       BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %s", num_str);
+                       BLI_snprintf(msg, sizeof(msg), IFACE_("Trim offset: %s"), num_str);
                }
                else {
-                       BLI_snprintf(msg, HEADER_LENGTH, "Trim offset: %d", offset);
+                       BLI_snprintf(msg, sizeof(msg), IFACE_("Trim offset: %d"), offset);
                }
        }
 
        ED_area_headerprint(sa, msg);
-
-#undef HEADER_LENGTH
 }
 
 static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event)
@@ -2027,7 +2065,7 @@ void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot)
 
 
 /* cut operator */
-static EnumPropertyItem prop_cut_types[] = {
+static const EnumPropertyItem prop_cut_types[] = {
        {SEQ_CUT_SOFT, "SOFT", 0, "Soft", ""},
        {SEQ_CUT_HARD, "HARD", 0, "Hard", ""},
        {0, NULL, 0, NULL, NULL}
@@ -2156,7 +2194,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
        if (ed == NULL)
                return OPERATOR_CANCELLED;
 
-       BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT);
+       BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0);
 
        if (nseqbase.first) {
                Sequence *seq = nseqbase.first;
@@ -2198,23 +2236,24 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
        Editing *ed = BKE_sequencer_editing_get(scene, false);
        Sequence *seq;
        MetaStack *ms;
-       bool nothingSelected = true;
+       bool nothing_selected = true;
 
        seq = BKE_sequencer_active_get(scene);
        if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
-               nothingSelected = false;
+               nothing_selected = false;
        }
        else {
                for (seq = ed->seqbasep->first; seq; seq = seq->next) {
                        if (seq->flag & SELECT) {
-                               nothingSelected = false;
+                               nothing_selected = false;
                                break;
                        }
                }
        }
 
-       if (nothingSelected)
+       if (nothing_selected) {
                return OPERATOR_FINISHED;
+       }
 
        /* for effects and modifiers, try to find a replacement input */
        for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -2426,7 +2465,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot)
        
        /* api callbacks */
        ot->exec = sequencer_separate_images_exec;
-       ot->invoke = WM_operator_props_popup;
+       ot->invoke = WM_operator_props_popup_confirm;
        ot->poll = sequencer_edit_poll;
        
        /* flags */
@@ -2689,6 +2728,29 @@ void SEQUENCER_OT_view_all(wmOperatorType *ot)
        ot->flag = OPTYPE_REGISTER;
 }
 
+static int sequencer_view_frame_exec(bContext *C, wmOperator *op)
+{
+       const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+       ANIM_center_frame(C, smooth_viewtx);
+       
+       return OPERATOR_FINISHED;
+}
+
+void SEQUENCER_OT_view_frame(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "View Frame";
+       ot->idname = "SEQUENCER_OT_view_frame";
+       ot->description = "Reset viewable area to show range around current frame";
+       
+       /* api callbacks */
+       ot->exec = sequencer_view_frame_exec;
+       ot->poll = ED_operator_sequencer_active;
+       
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 /* view_all operator */
 static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op))
 {
@@ -2769,7 +2831,7 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op)
        float facx = BLI_rcti_size_x(&v2d->mask) / winx;
        float facy = BLI_rcti_size_y(&v2d->mask) / winy;
 
-       BLI_rctf_resize(&v2d->cur, floorf(winx * facx / ratio + 0.5f), floorf(winy * facy / ratio + 0.5f));
+       BLI_rctf_resize(&v2d->cur, ceilf(winx * facx / ratio + 0.5f), ceilf(winy * facy / ratio + 0.5f));
 
        ED_region_tag_redraw(CTX_wm_region(C));
 
@@ -2794,7 +2856,7 @@ void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot)
 
 
 #if 0
-static EnumPropertyItem view_type_items[] = {
+static const EnumPropertyItem view_type_items[] = {
        {SEQ_VIEW_SEQUENCE, "SEQUENCER", ICON_SEQ_SEQUENCER, "Sequencer", ""},
        {SEQ_VIEW_PREVIEW,  "PREVIEW", ICON_SEQ_PREVIEW, "Image Preview", ""},
        {SEQ_VIEW_SEQUENCE_PREVIEW,  "SEQUENCER_PREVIEW", ICON_SEQ_SEQUENCER, "Sequencer and Image Preview", ""},
@@ -3171,7 +3233,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        }
 
-       BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME);
+       BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME, 0);
 
        /* To make sure the copied strips have unique names between each other add
         * them temporarily to the end of the original seqbase. (bug 25932)
@@ -3238,7 +3300,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
        ED_sequencer_deselect_all(scene);
        ofs = scene->r.cfra - seqbase_clipboard_frame;
 
-       BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME);
+       BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME, 0);
 
        /* transform pasted strips before adding */
        if (ofs) {
@@ -3323,6 +3385,9 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
        if (seq_act->sound) BKE_sound_add_scene_sound_defaults(scene, seq_act);
        if (seq_other->sound) BKE_sound_add_scene_sound_defaults(scene, seq_other);
 
+       BKE_sequence_invalidate_cache(scene, seq_act);
+       BKE_sequence_invalidate_cache(scene, seq_other);
+
        WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
 
        return OPERATOR_FINISHED;
@@ -3389,17 +3454,17 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
        ot->description = "Set the boundaries of the border used for offset-view";
 
        /* api callbacks */
-       ot->invoke = WM_border_select_invoke;
+       ot->invoke = WM_gesture_border_invoke;
        ot->exec = view_ghost_border_exec;
-       ot->modal = WM_border_select_modal;
+       ot->modal = WM_gesture_border_modal;
        ot->poll = sequencer_view_preview_poll;
-       ot->cancel = WM_border_select_cancel;
+       ot->cancel = WM_gesture_border_cancel;
 
        /* flags */
        ot->flag = 0;
 
        /* rna */
-       WM_operator_properties_gesture_border(ot, false);
+       WM_operator_properties_gesture_border(ot);
 }
 
 /* rebuild_proxy operator */
@@ -3480,7 +3545,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
        bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50");
        bool proxy_75 = RNA_boolean_get(op->ptr, "proxy_75");
        bool proxy_100 = RNA_boolean_get(op->ptr, "proxy_100");
-       bool override = RNA_boolean_get(op->ptr, "override");
+       bool overwrite = RNA_boolean_get(op->ptr, "overwrite");
        bool turnon = true;
 
        if (ed == NULL || !(proxy_25 || proxy_50 || proxy_75 || proxy_100)) {
@@ -3516,7 +3581,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
                                else 
                                        seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_100;
                                
-                               if (!override)
+                               if (!overwrite)
                                        seq->strip->proxy->build_flags |= SEQ_PROXY_SKIP_EXISTING;
                                else 
                                        seq->strip->proxy->build_flags &= ~SEQ_PROXY_SKIP_EXISTING;
@@ -3548,12 +3613,12 @@ void SEQUENCER_OT_enable_proxies(wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "proxy_50", false, "50%", "");
        RNA_def_boolean(ot->srna, "proxy_75", false, "75%", "");
        RNA_def_boolean(ot->srna, "proxy_100", false, "100%", "");
-       RNA_def_boolean(ot->srna, "override", false, "Override", "");
+       RNA_def_boolean(ot->srna, "overwrite", false, "Overwrite", "");
 }
 
 /* change ops */
 
-static EnumPropertyItem prop_change_effect_input_types[] = {
+static const EnumPropertyItem prop_change_effect_input_types[] = {
        {0, "A_B", 0, "A -> B", ""},
        {1, "B_C", 0, "B -> C", ""},
        {2, "A_C", 0, "A -> C", ""},
@@ -3811,9 +3876,10 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot)
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
-       WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER, FILE_SPECIAL, FILE_OPENFILE,
-                                      WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES,
-                                      FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+       WM_operator_properties_filesel(
+               ot, FILE_TYPE_FOLDER, FILE_SPECIAL, FILE_OPENFILE,
+               WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES,
+               FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
        RNA_def_boolean(ot->srna, "use_placeholders", false, "Use Placeholders", "Use placeholders for missing frames of the strip");
 }
 
@@ -3928,6 +3994,7 @@ void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot)
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
-       WM_operator_properties_filesel(ot,  FILE_TYPE_FOLDER, FILE_BLENDER, FILE_SAVE,
-                                      WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+       WM_operator_properties_filesel(
+               ot,  FILE_TYPE_FOLDER, FILE_BLENDER, FILE_SAVE,
+               WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
 }