engine: timeline panel core edit commands migrate to the facade (part 1)

- new batch primitives: split_clips (link-preserving, single undo
  command), delete_clips (gap replace + optional ripple with explicit
  region support), ripple_delete_range, marker_add_ex with color
- razor/split-at-playhead, clip delete, ripple-to-point, track delete,
  and the non-dialog marker path now issue facade commands instead of
  the app's own undo command classes
- batch operations deliberately produce one undo command per user
  action (deleting twenty clips is one entry, not twenty); selection
  and transition removal stay UI-side as documented leftovers
This commit is contained in:
2026-07-20 13:17:07 +08:00
parent 0a25d43218
commit 2aa7eec016
8 changed files with 528 additions and 51 deletions
+16 -6
View File
@@ -21,8 +21,7 @@
#include "razor.h"
#include "node/nodeundo.h"
#include "timeline/timelineundosplit.h"
#include "oakengine/timeline.h"
#include "widget/timelinewidget/timelinewidget.h"
namespace olive
@@ -94,10 +93,21 @@ void RazorTool::mouse_release(TimelineViewMouseEvent *event)
split_tracks_.clear();
if (!blocks_to_split.isEmpty()) {
Core::instance()->undo_stack()->push(
new BlockSplitPreservingLinksCommand(blocks_to_split,
{ split_time }),
qApp->translate("RazorTool", "Split Clips"));
// Split through the liboakengine C ABI facade: one undoable,
// link-preserving command with the same semantics as the old
// app-side BlockSplitPreservingLinksCommand push.
QVector<OakEngineClip *> clips;
clips.reserve(blocks_to_split.size());
foreach (Block *b, blocks_to_split) {
if (ClipBlock *clip = dynamic_cast<ClipBlock *>(b)) {
clips.append(reinterpret_cast<OakEngineClip *>(clip));
}
}
oakengine_sequence_split_clips(
reinterpret_cast<OakEngineSequence *>(parent()->sequence()),
clips.data(), clips.size(),
Timecode::time_to_timestamp(split_time, parent()->timebase(),
Timecode::k_round));
}
dragging_ = false;