engine: timeline panel batch/composite commands migrate to the facade (part 2)

- new primitives: ripple_delete_in_to_out (ripple or gap fill plus
  work-area state, one undo command), trim_clips_to (batch edge trim
  returning a count), delete_empty_tracks (type-filtered batch), and
  marker_remove_many (sparse marker deletion by timestamp array)
- delete-in-to-out, edit-to, delete-all-empty-tracks, and sequence
  viewer marker deletion now go through the facade; empty operations
  no longer push empty undo entries
- footage viewer marker deletion keeps its app path deliberately
  (facade marker handles are Sequences, not generic viewers); the
  tentative subtitle track and pointer drag chain stay as documented
  leftovers
This commit is contained in:
2026-07-20 13:37:10 +08:00
parent 2aa7eec016
commit 0fe37dba3c
6 changed files with 452 additions and 74 deletions
+28 -4
View File
@@ -30,7 +30,9 @@
#include "common/range.h"
#include "core.h"
#include "dialog/markerproperties/markerpropertiesdialog.h"
#include "node/project/sequence/sequence.h"
#include "node/project/serializer/serializer.h"
#include "oakengine/timeline.h"
#include "timeline/timelineundoworkarea.h"
#include "widget/colorlabelmenu/colorlabelmenu.h"
#include "widget/menu/menushared.h"
@@ -122,16 +124,38 @@ void SeekableWidget::set_work_area(TimelineWorkArea *workarea)
void SeekableWidget::delete_selected()
{
if (!selection_manager_.is_dragging()) {
const auto &selected = selection_manager_.get_selected_objects();
if (selected.empty()) {
return;
}
if (Sequence *sequence =
dynamic_cast<Sequence *>(get_viewer_node())) {
// Batch removal through the liboakengine C ABI facade (one
// undoable command). The facade family only wraps sequences;
// markers of other viewer nodes (e.g. footage viewers) keep
// the old per-marker command path below.
QVector<int64_t> times;
times.reserve(int(selected.size()));
for (TimelineMarker *marker : selected) {
times.append(Timecode::time_to_timestamp(
marker->time().in(), timebase(), Timecode::k_round));
}
oakengine_sequence_marker_remove_many(
reinterpret_cast<OakEngineSequence *>(sequence),
times.constData(), times.size());
return;
}
MultiUndoCommand *command = new MultiUndoCommand();
foreach (TimelineMarker *marker,
selection_manager_.get_selected_objects()) {
foreach (TimelineMarker *marker, selected) {
command->add_child(new MarkerRemoveCommand(marker));
}
Core::instance()->undo_stack()->push(
command, tr("Deleted %1 Marker(s)")
.arg(selection_manager_.get_selected_objects().size()));
command,
tr("Deleted %1 Marker(s)").arg(selected.size()));
}
}