diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index e403f68ec05..fa50c713376 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -8628,6 +8628,14 @@ def km_sequencer_tool_blade(_params): ("use_cursor_position", True), ("ignore_selection", True), ]}), + ("sequencer.split", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, + {"properties": [ + ("type", 'SOFT'), + ("side", 'NO_CHANGE'), + ("use_cursor_position", True), + ("ignore_selection", True), + ("ignore_connections", True), + ]}), ]}, ) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.cc b/source/blender/editors/space_sequencer/sequencer_edit.cc index 09d09a48a93..098dcc4141f 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.cc +++ b/source/blender/editors/space_sequencer/sequencer_edit.cc @@ -1757,6 +1757,7 @@ static wmOperatorStatus sequencer_split_exec(bContext *C, wmOperator *op) const seq::eSplitMethod method = seq::eSplitMethod(RNA_enum_get(op->ptr, "type")); const int split_side = sequence_split_side_for_exec_get(op); const bool ignore_selection = RNA_boolean_get(op->ptr, "ignore_selection"); + const bool ignore_connections = RNA_boolean_get(op->ptr, "ignore_connections"); seq::prefetch_stop(scene); @@ -1767,9 +1768,14 @@ static wmOperatorStatus sequencer_split_exec(bContext *C, wmOperator *op) if (ignore_selection || strip->flag & SELECT) { const char *error_msg = nullptr; - if (seq::edit_strip_split( - bmain, scene, ed->current_strips(), strip, split_frame, method, &error_msg) != - nullptr) + if (seq::edit_strip_split(bmain, + scene, + ed->current_strips(), + strip, + split_frame, + method, + ignore_connections, + &error_msg) != nullptr) { changed = true; } @@ -1881,6 +1887,10 @@ static void sequencer_split_ui(bContext * /*C*/, wmOperator *op) if (RNA_boolean_get(op->ptr, "use_cursor_position")) { layout->prop(op->ptr, "channel", UI_ITEM_NONE, std::nullopt, ICON_NONE); } + + layout->separator(); + + layout->prop(op->ptr, "ignore_connections", UI_ITEM_NONE, std::nullopt, ICON_NONE); } void SEQUENCER_OT_split(wmOperatorType *ot) @@ -1948,6 +1958,12 @@ void SEQUENCER_OT_split(wmOperatorType *ot) "Make cut even if strip is not selected preserving selection state after cut"); RNA_def_property_flag(prop, PROP_HIDDEN); + + RNA_def_boolean(ot->srna, + "ignore_connections", + false, + "Ignore Connections", + "Don't propagate split to connected strips"); } /** \} */ diff --git a/source/blender/makesrna/intern/rna_sequencer_api.cc b/source/blender/makesrna/intern/rna_sequencer_api.cc index efbfa11a42e..2aaba7f5c1a 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.cc +++ b/source/blender/makesrna/intern/rna_sequencer_api.cc @@ -88,15 +88,26 @@ static void rna_Strips_move_strip_to_meta( WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene); } -static Strip *rna_Strip_split( - ID *id, Strip *strip, Main *bmain, ReportList *reports, int frame, int split_method) +static Strip *rna_Strip_split(ID *id, + Strip *strip, + Main *bmain, + ReportList *reports, + int frame, + int split_method, + bool ignore_connections) { Scene *scene = (Scene *)id; ListBase *seqbase = blender::seq::get_seqbase_by_strip(scene, strip); const char *error_msg = nullptr; - Strip *strip_split = blender::seq::edit_strip_split( - bmain, scene, seqbase, strip, frame, blender::seq::eSplitMethod(split_method), &error_msg); + Strip *strip_split = blender::seq::edit_strip_split(bmain, + scene, + seqbase, + strip, + frame, + blender::seq::eSplitMethod(split_method), + ignore_connections, + &error_msg); if (error_msg != nullptr) { BKE_report(reports, RPT_ERROR, error_msg); } @@ -754,6 +765,8 @@ void RNA_api_strip(StructRNA *srna) RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED); parm = RNA_def_enum(func, "split_method", strip_split_method_items, 0, "", ""); RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + parm = RNA_def_boolean( + func, "ignore_connections", false, "", "Don't propagate split to connected strips"); /* Return type. */ parm = RNA_def_pointer(func, "sequence", "Strip", "", "Right side Strip"); RNA_def_function_return(func, parm); diff --git a/source/blender/sequencer/SEQ_edit.hh b/source/blender/sequencer/SEQ_edit.hh index 1d5921a8521..ea71d66c09f 100644 --- a/source/blender/sequencer/SEQ_edit.hh +++ b/source/blender/sequencer/SEQ_edit.hh @@ -73,6 +73,7 @@ Strip *edit_strip_split(Main *bmain, Strip *strip, int timeline_frame, eSplitMethod method, + bool ignore_connections, const char **r_error); /** * Find gap after initial_frame and move strips on right side to close the gap diff --git a/source/blender/sequencer/intern/strip_edit.cc b/source/blender/sequencer/intern/strip_edit.cc index 0eeee93f4b8..f368ac533db 100644 --- a/source/blender/sequencer/intern/strip_edit.cc +++ b/source/blender/sequencer/intern/strip_edit.cc @@ -409,6 +409,7 @@ Strip *edit_strip_split(Main *bmain, Strip *strip, const int timeline_frame, const eSplitMethod method, + const bool ignore_connections, const char **r_error) { if (!seq_edit_split_intersect_check(scene, strip, timeline_frame)) { @@ -418,21 +419,11 @@ Strip *edit_strip_split(Main *bmain, /* Whole strip effect chain must be duplicated in order to preserve relationships. */ blender::VectorSet strips; strips.add(strip); - iterator_set_expand(scene, seqbase, strips, query_strip_effect_chain); - - /* All connected strips (that are selected and at the cut frame) must also be duplicated. */ - blender::VectorSet strips_old(strips); - for (Strip *strip : strips_old) { - blender::VectorSet connections = connected_strips_get(strip); - connections.remove_if([&](Strip *connection) { - return !(connection->flag & SELECT) || - !seq_edit_split_intersect_check(scene, connection, timeline_frame); - }); - strips.add_multiple(connections.as_span()); - } - - /* In case connected strips had effects, duplicate those too: */ - iterator_set_expand(scene, seqbase, strips, query_strip_effect_chain); + iterator_set_expand(scene, + seqbase, + strips, + ignore_connections ? query_strip_effect_chain : + query_strip_connected_and_effect_chain); if (!seq_edit_split_operation_permitted_check(scene, strips, timeline_frame, r_error)) { return nullptr; @@ -448,6 +439,10 @@ Strip *edit_strip_split(Main *bmain, BLI_remlink(seqbase, strip_iter); BLI_addtail(&left_strips, strip_iter); + if (ignore_connections) { + seq::disconnect(strip_iter); + } + /* Duplicate curves from backup, so they can be renamed along with split strips. */ animation_duplicate_backup_to_scene(scene, strip_iter, &animation_backup); } diff --git a/source/blender/sequencer/intern/strip_transform.cc b/source/blender/sequencer/intern/strip_transform.cc index 114a14fa0d2..a107860972e 100644 --- a/source/blender/sequencer/intern/strip_transform.cc +++ b/source/blender/sequencer/intern/strip_transform.cc @@ -410,6 +410,7 @@ static void strip_transform_handle_overwrite_split(Scene *scene, target, time_left_handle_frame_get(scene, transformed), SPLIT_SOFT, + true, nullptr); edit_strip_split(bmain, scene, @@ -417,6 +418,7 @@ static void strip_transform_handle_overwrite_split(Scene *scene, split_strip, time_right_handle_frame_get(scene, transformed), SPLIT_SOFT, + true, nullptr); edit_flag_for_removal(scene, seqbasep, split_strip); edit_remove_flagged_strips(scene, seqbasep);