diff --git a/app/node/graph.cpp b/app/node/graph.cpp index e6f1187ac..1023f2619 100644 --- a/app/node/graph.cpp +++ b/app/node/graph.cpp @@ -49,18 +49,6 @@ void NodeGraph::AddNode(Node *node) emit NodeAdded(node); } -void NodeGraph::AddNodeWithDependencies(Node *node) -{ - // Add node and its connected nodes to graph - AddNode(node); - - // Add all of Block's dependencies - QList node_dependencies = node->GetDependencies(); - foreach (Node* dep, node_dependencies) { - AddNode(dep); - } -} - void NodeGraph::TakeNode(Node *node, QObject* new_parent) { if (!ContainsNode(node)) { @@ -84,21 +72,6 @@ void NodeGraph::TakeNode(Node *node, QObject* new_parent) emit NodeRemoved(node); } -QList NodeGraph::TakeNodeWithItsDependencies(Node *node, QObject *new_parent) -{ - if (!ContainsNode(node)) { - return QList(); - } - - QList deps = node->GetExclusiveDependencies(); - - foreach (Node* d, deps) { - TakeNode(d, new_parent); - } - - return deps; -} - const QList &NodeGraph::nodes() { return node_children_; diff --git a/app/node/graph.h b/app/node/graph.h index df3613648..c006f0508 100644 --- a/app/node/graph.h +++ b/app/node/graph.h @@ -50,31 +50,11 @@ public: */ void AddNode(Node* node); - /** - * @brief Adds a node to this graph and all nodes connected to its inputs - * - * Adds the Node to the graph and runs through its inputs adding all of its dependencies (and all of their - * dependencies and so forth). The graph takes ownershi of all Nodes added through this process. - */ - void AddNodeWithDependencies(Node* node); - /** * @brief Removes a Node from the graph BUT doesn't destroy it. Ownership is passed to `new_parent`. */ void TakeNode(Node* node, QObject* new_parent = nullptr); - /** - * @brief Removes a Node from the graph and its dependencies (ONLY if the dependencies are exclusive to this Node). - * - * Returns a list of all Nodes that were removed in this process (except the Node used as a parameter) - * - * Only dependencies that are exclusively dependencies of this Node are removed. If a dependency Node is also - * used as the dependency of another Node, it is not removed and not returned in the list. - * - * Ownership of all Nodes is passed to `new_parent`. - */ - QList TakeNodeWithItsDependencies(Node* node, QObject* new_parent = nullptr); - /** * @brief Retrieve a complete list of the nodes belonging to this graph */ diff --git a/app/node/node.cpp b/app/node/node.cpp index 2521aa22e..e0c6955e9 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -468,6 +468,16 @@ QVariant Node::InputValueFromTable(NodeInput *input, const NodeValueTable &table return table.Get(find_data_type); } +const QPointF &Node::GetPosition() +{ + return position_; +} + +void Node::SetPosition(const QPointF &pos) +{ + position_ = pos; +} + void Node::AddInput(NodeInput *input) { AddParameter(input); diff --git a/app/node/node.h b/app/node/node.h index 8a6646130..39e896f4c 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "common/rational.h" #include "node/dependency.h" @@ -270,6 +271,10 @@ public: virtual QVariant InputValueFromTable(NodeInput* input, const NodeValueTable& table) const; + const QPointF& GetPosition(); + + void SetPosition(const QPointF& pos); + protected: void AddInput(NodeInput* input); @@ -339,6 +344,11 @@ private: */ NodeOutput* output_; + /** + * @brief UI position for NodeViews + */ + QPointF position_; + private slots: void InputChanged(rational start, rational end); diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 47a39bb43..5e4559b4c 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -231,17 +231,19 @@ void TrackOutput::PrependBlock(Block *block) void TrackOutput::InsertBlockAtIndex(Block *block, int index) { - AddBlockToGraph(block); + BlockInvalidateCache(); block_input_->InsertAt(index); NodeParam::ConnectEdge(block->output(), block_input_->At(index)); + + UnblockInvalidateCache(); + + InvalidateCache(block->in(), track_length()); } void TrackOutput::AppendBlock(Block *block) { - AddBlockToGraph(block); - BlockInvalidateCache(); int last_index = block_input_->GetSize(); @@ -255,13 +257,6 @@ void TrackOutput::AppendBlock(Block *block) InvalidateCache(block->in(), track_length()); } -void TrackOutput::AddBlockToGraph(Block *block) -{ - // Find the parent graph - NodeGraph* graph = static_cast(parent()); - graph->AddNodeWithDependencies(block); -} - void TrackOutput::BlockInvalidateCache() { block_invalidate_cache_stack_++; @@ -272,14 +267,6 @@ void TrackOutput::UnblockInvalidateCache() block_invalidate_cache_stack_--; } -void TrackOutput::RemoveBlock(Block *block) -{ - GapBlock* gap = new GapBlock(); - gap->set_length(block->length()); - - ReplaceBlock(block, gap); -} - void TrackOutput::RippleRemoveBlock(Block *block) { BlockInvalidateCache(); @@ -293,8 +280,6 @@ void TrackOutput::RippleRemoveBlock(Block *block) UnblockInvalidateCache(); InvalidateCache(remove_in, track_length()); - - // FIXME: Should there be removing the Blocks from the graph? } void TrackOutput::ReplaceBlock(Block *old, Block *replace) @@ -303,8 +288,6 @@ void TrackOutput::ReplaceBlock(Block *old, Block *replace) BlockInvalidateCache(); - AddBlockToGraph(replace); - int index_of_old_block = block_cache_.indexOf(old); NodeParam::DisconnectEdge(old->output(), diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index 667a01fe7..cd65ce3c2 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -98,11 +98,6 @@ public: */ void AppendBlock(Block* block); - /** - * @brief Removes a Block and places a Gap in its place - */ - void RemoveBlock(Block* block); - /** * @brief Removes a Block pushing all subsequent Blocks earlier to take up the space */ @@ -119,13 +114,6 @@ public: void UnblockInvalidateCache(); - /** - * @brief Adds a Block to the parent graph so it can be connected to other Nodes - * - * Also runs through Node's dependencies (the Nodes whose outputs are connected to this Node's inputs) - */ - void AddBlockToGraph(Block* block); - static TrackOutput* TrackFromBlock(Block* block); const rational& track_length() const; diff --git a/app/node/param.cpp b/app/node/param.cpp index 09a9d07d0..8f5f3d7aa 100644 --- a/app/node/param.cpp +++ b/app/node/param.cpp @@ -116,10 +116,7 @@ NodeEdgePtr NodeParam::ConnectEdge(NodeOutput *output, NodeInput *input, bool lo } // Ensure both nodes are in the same graph - if (output->parentNode()->parent() != input->parentNode()->parent()) { - qWarning() << "Tried to connect two nodes that aren't part of the same graph"; - return nullptr; - } + Q_ASSERT(output->parentNode()->parent() == input->parentNode()->parent()); NodeEdgePtr edge = std::make_shared(output, input); diff --git a/app/widget/nodeview/nodeviewitem.cpp b/app/widget/nodeview/nodeviewitem.cpp index b0d283c1a..a08a7d91c 100644 --- a/app/widget/nodeview/nodeviewitem.cpp +++ b/app/widget/nodeview/nodeviewitem.cpp @@ -47,6 +47,7 @@ NodeViewItem::NodeViewItem(QGraphicsItem *parent) : // Set flags for this widget setFlag(QGraphicsItem::ItemIsMovable); setFlag(QGraphicsItem::ItemIsSelectable); + setFlag(QGraphicsItem::ItemSendsGeometryChanges); // // We use font metrics to set all the UI measurements for DPI-awareness @@ -77,6 +78,8 @@ void NodeViewItem::SetNode(Node *n) { node_ = n; + setPos(node_->GetPosition()); + update(); } @@ -256,8 +259,6 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti } } -#include "node/block/block.h" - void NodeViewItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { // We override standard mouse behavior in some cases. In these cases, we don't want the standard "move" and "release" @@ -470,3 +471,12 @@ void NodeViewItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) QGraphicsRectItem::mouseReleaseEvent(event); } } + +QVariant NodeViewItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + if (change == ItemPositionHasChanged && node_) { + node_->SetPosition(value.toPointF()); + } + + return QGraphicsItem::itemChange(change, value); +} diff --git a/app/widget/nodeview/nodeviewitem.h b/app/widget/nodeview/nodeviewitem.h index 4fa76c716..1c0c629f7 100644 --- a/app/widget/nodeview/nodeviewitem.h +++ b/app/widget/nodeview/nodeviewitem.h @@ -82,6 +82,8 @@ protected: virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; + virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override; + private: /** * @brief Get the relative position to draw text for a parameter at a certain index diff --git a/app/widget/nodeview/nodeviewundo.cpp b/app/widget/nodeview/nodeviewundo.cpp index 7d522cdd0..a7cf98898 100644 --- a/app/widget/nodeview/nodeviewundo.cpp +++ b/app/widget/nodeview/nodeviewundo.cpp @@ -70,8 +70,8 @@ NodeAddCommand::NodeAddCommand(NodeGraph *graph, Node *node, QUndoCommand *paren graph_(graph), node_(node) { - // Ensures that when this command is destroyed, if redo() hasn't been called, the node will be destroyed too - node->setParent(&memory_manager_); + // Ensures that when this command is destroyed, if redo() is never called again, the node will be destroyed too + node_->setParent(&memory_manager_); } void NodeAddCommand::redo() diff --git a/app/widget/nodeview/nodeviewundo.h b/app/widget/nodeview/nodeviewundo.h index 77457da5c..72dcfaffc 100644 --- a/app/widget/nodeview/nodeviewundo.h +++ b/app/widget/nodeview/nodeviewundo.h @@ -5,6 +5,7 @@ #include "node/graph.h" #include "node/node.h" +#include "nodeviewitem.h" /** * @brief An undoable commnd for connecting two NodeParams together @@ -62,7 +63,9 @@ private: class NodeRemoveCommand : public QUndoCommand { public: - NodeRemoveCommand(NodeGraph* graph, const QList& nodes, QUndoCommand* parent = nullptr); + NodeRemoveCommand(NodeGraph* graph, + const QList& nodes, + QUndoCommand* parent = nullptr); virtual void redo() override; virtual void undo() override; diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 673cf315c..5dc1047e2 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -8,6 +8,7 @@ #include "common/timecodefunctions.h" #include "tool/tool.h" #include "trackview/trackview.h" +#include "widget/nodeview/nodeviewundo.h" TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent), @@ -382,6 +383,18 @@ void TimelineWidget::SplitAtPlayhead() } } +void TimelineWidget::DeleteSelected() +{ + QList list = GetSelectedBlocks(); + + // No-op if nothing is selected + if (list.isEmpty()) { + return; + } + + +} + QList TimelineWidget::GetSelectedBlocks() { QList list; @@ -440,14 +453,19 @@ void TimelineWidget::RippleEditTo(olive::timeline::MovementMode mode, bool inser rational ripple_length = out_ripple - in_ripple; foreach (TrackOutput* track, timeline_node_->Tracks()) { + GapBlock* gap = nullptr; + if (insert_gaps) { + gap = new GapBlock(); + gap->set_length(ripple_length); + new NodeAddCommand(static_cast(track->parent()), gap, command); + } + TrackRippleRemoveAreaCommand* ripple_command = new TrackRippleRemoveAreaCommand(track, in_ripple, out_ripple, command); if (insert_gaps) { - GapBlock* gap = new GapBlock(); - gap->set_length(ripple_length); ripple_command->SetInsert(gap); } } diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index 3fe8bd47a..caa0649e7 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -51,6 +51,8 @@ public: void SplitAtPlayhead(); + void DeleteSelected(); + QList GetSelectedBlocks(); public slots: diff --git a/app/widget/timelinewidget/tool/add.cpp b/app/widget/timelinewidget/tool/add.cpp index b9b9ef538..11cd20bae 100644 --- a/app/widget/timelinewidget/tool/add.cpp +++ b/app/widget/timelinewidget/tool/add.cpp @@ -1,6 +1,7 @@ #include "widget/timelinewidget/timelinewidget.h" #include "core.h" +#include "widget/nodeview/nodeviewundo.h" TimelineWidget::AddTool::AddTool(TimelineWidget *parent) : Tool(parent), @@ -46,12 +47,21 @@ void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event) if (ghost_) { if (!ghost_->AdjustedLength().isNull()) { + QUndoCommand* command = new QUndoCommand(); + ClipBlock* clip = new ClipBlock(); clip->set_length(ghost_->AdjustedLength()); - olive::undo_stack.push(new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track.type()), - track.index(), - clip, - ghost_->GetAdjustedIn())); + new NodeAddCommand(static_cast(parent()->timeline_node_->parent()), + clip, + command); + + new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track.type()), + track.index(), + clip, + ghost_->GetAdjustedIn(), + command); + + olive::undo_stack.push(command); } parent()->ClearGhosts(); diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index 1a4b4ad53..fa4cb3e5b 100644 --- a/app/widget/timelinewidget/tool/import.cpp +++ b/app/widget/timelinewidget/tool/import.cpp @@ -30,6 +30,7 @@ #include "node/color/opacity/opacity.h" #include "node/input/media/audio/audio.h" #include "node/input/media/video/video.h" +#include "widget/nodeview/nodeviewundo.h" TrackType TrackTypeFromStreamType(Stream::Type stream_type) { @@ -207,6 +208,7 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) { if (parent()->HasGhosts()) { QUndoCommand* command = new QUndoCommand(); + NodeGraph* dst_graph = static_cast(parent()->timeline_node_->parent()); QVector block_items(parent()->ghost_items_.size()); @@ -218,6 +220,7 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) ClipBlock* clip = new ClipBlock(); clip->set_length(ghost->Length()); clip->set_block_name(footage_stream->footage()->name()); + new NodeAddCommand(dst_graph, clip, command); switch (footage_stream->type()) { case Stream::kVideo: @@ -225,10 +228,12 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) { VideoInput* video_input = new VideoInput(); video_input->SetFootage(footage_stream); - NodeParam::ConnectEdge(video_input->output(), clip->texture_input()); + new NodeAddCommand(dst_graph, video_input, command); + new NodeEdgeAddCommand(video_input->output(), clip->texture_input(), command); TransformDistort* transform = new TransformDistort(); - NodeParam::ConnectEdge(transform->output(), video_input->matrix_input()); + new NodeAddCommand(dst_graph, transform, command); + new NodeEdgeAddCommand(transform->output(), video_input->matrix_input(), command); //OpacityNode* opacity = new OpacityNode(); //NodeParam::ConnectEdge(opacity->texture_output(), clip->texture_input()); @@ -239,7 +244,8 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event) { AudioInput* audio_input = new AudioInput(); audio_input->SetFootage(footage_stream); - NodeParam::ConnectEdge(audio_input->output(), clip->texture_input()); + new NodeAddCommand(dst_graph, audio_input, command); + new NodeEdgeAddCommand(audio_input->output(), clip->texture_input(), command); break; } default: diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index 98952deee..6b3a38fb0 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -30,6 +30,7 @@ #include "config/config.h" #include "core.h" #include "node/block/gap/gap.h" +#include "widget/nodeview/nodeviewundo.h" TimelineWidget::PointerTool::PointerTool(TimelineWidget *parent) : Tool(parent), @@ -158,10 +159,6 @@ void TimelineWidget::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *e { Q_UNUSED(event) - // We create a QObject on the stack so that when we allocate objects on the heap, they aren't parent-less and will - // get cleaned up if they aren't re-parented by the attached NodeGraph - QObject block_memory_manager; - QUndoCommand* command = new QUndoCommand(); // Since all the ghosts will be leaving their old position in some way, we replace all of them with gaps here so the @@ -171,9 +168,12 @@ void TimelineWidget::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *e // Replace old Block with a new Gap GapBlock* gap = new GapBlock(); - gap->setParent(&block_memory_manager); gap->set_length(b->length()); + new NodeAddCommand(static_cast(b->parent()), + gap, + command); + new TrackReplaceBlockCommand(parent()->GetTrackFromReference(ghost->Track()), b, gap, diff --git a/app/widget/timelinewidget/tool/ripple.cpp b/app/widget/timelinewidget/tool/ripple.cpp index 3d9f5f2cc..9bc3148b7 100644 --- a/app/widget/timelinewidget/tool/ripple.cpp +++ b/app/widget/timelinewidget/tool/ripple.cpp @@ -21,6 +21,7 @@ #include "widget/timelinewidget/timelinewidget.h" #include "node/block/gap/gap.h" +#include "widget/nodeview/nodeviewundo.h" TimelineWidget::RippleTool::RippleTool(TimelineWidget* parent) : PointerTool(parent) @@ -48,13 +49,15 @@ void TimelineWidget::RippleTool::MouseReleaseInternal(TimelineViewMouseEvent *ev if (ghost->AdjustedLength() > 0) { GapBlock* gap = new GapBlock(); gap->set_length(ghost->AdjustedLength()); + new NodeAddCommand(static_cast(parent()->timeline_node_->parent()), gap, command); Block* block_to_append_gap_to = Node::ValueToPtr(ghost->data(TimelineViewGhostItem::kReferenceBlock)); new TrackInsertBlockBetweenBlocksCommand(parent()->GetTrackFromReference(ghost->Track()), gap, block_to_append_gap_to, - block_to_append_gap_to->next()); + block_to_append_gap_to->next(), + command); } } else { // This was a Block that already existed @@ -68,6 +71,8 @@ void TimelineWidget::RippleTool::MouseReleaseInternal(TimelineViewMouseEvent *ev } else { // Assumed the Block was a Gap and it was reduced to zero length, remove it here new TrackRippleRemoveBlockCommand(parent()->GetTrackFromReference(ghost->Track()), b, command); + + new NodeRemoveCommand(static_cast(b->parent()), {b}, command); } } } diff --git a/app/widget/timelinewidget/tool/rolling.cpp b/app/widget/timelinewidget/tool/rolling.cpp index 4e51f9454..1435c0d4f 100644 --- a/app/widget/timelinewidget/tool/rolling.cpp +++ b/app/widget/timelinewidget/tool/rolling.cpp @@ -21,6 +21,7 @@ #include "widget/timelinewidget/timelinewidget.h" #include "node/block/gap/gap.h" +#include "widget/nodeview/nodeviewundo.h" TimelineWidget::RollingTool::RollingTool(TimelineWidget* parent) : PointerTool(parent) @@ -43,6 +44,9 @@ void TimelineWidget::RollingTool::MouseReleaseInternal(TimelineViewMouseEvent *e // We'll need to insert a gap here, so we'll do a Place command instead GapBlock* gap = new GapBlock(); gap->set_length(ghost->Length()); + new NodeAddCommand(static_cast(b->parent()), + gap, + command); new TrackReplaceBlockCommand(parent()->GetTrackFromReference(ghost->Track()), b, gap, command); } diff --git a/app/widget/timelinewidget/tool/slide.cpp b/app/widget/timelinewidget/tool/slide.cpp index 55c7db3e6..cc2b38e62 100644 --- a/app/widget/timelinewidget/tool/slide.cpp +++ b/app/widget/timelinewidget/tool/slide.cpp @@ -21,6 +21,7 @@ #include "widget/timelinewidget/timelinewidget.h" #include "node/block/gap/gap.h" +#include "widget/nodeview/nodeviewundo.h" TimelineWidget::SlideTool::SlideTool(TimelineWidget* parent) : PointerTool(parent) @@ -46,6 +47,7 @@ void TimelineWidget::SlideTool::MouseReleaseInternal(TimelineViewMouseEvent *eve } else if (ghost->mode() == olive::timeline::kMove && b->previous() == nullptr) { GapBlock* gap = new GapBlock(); gap->set_length(ghost->InAdjustment()); + new NodeAddCommand(static_cast(b->parent()), gap, command); new TrackPrependBlockCommand(parent()->GetTrackFromReference(ghost->Track()), gap, command); } } diff --git a/app/widget/timelinewidget/tool/transition.cpp b/app/widget/timelinewidget/tool/transition.cpp index c32790fe8..2699821c2 100644 --- a/app/widget/timelinewidget/tool/transition.cpp +++ b/app/widget/timelinewidget/tool/transition.cpp @@ -94,6 +94,9 @@ void TimelineWidget::TransitionTool::MouseRelease(TimelineViewMouseEvent *event) QUndoCommand* command = new QUndoCommand(); // Place transition in place + new NodeAddCommand(static_cast(parent()->timeline_node_->parent()), + transition, + command); new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track.type()), track.index(), transition, diff --git a/app/widget/timelinewidget/undo/undo.cpp b/app/widget/timelinewidget/undo/undo.cpp index 79a1c16d4..2314ad1d7 100644 --- a/app/widget/timelinewidget/undo/undo.cpp +++ b/app/widget/timelinewidget/undo/undo.cpp @@ -183,7 +183,7 @@ void TrackRippleRemoveAreaCommand::redo() splice_original_length_ = splice_->length(); splice_->set_length(out_ - splice_->in()); - track_->AddBlockToGraph(copy); + static_cast(track_->parent())->AddNode(copy); Node::CopyInputs(splice_, copy); track_->InsertBlockAfter(copy, splice_); @@ -213,6 +213,8 @@ void TrackRippleRemoveAreaCommand::redo() // Remove all blocks that are flagged for removal foreach (Block* remove_block, removed_blocks_) { track_->RippleRemoveBlock(remove_block); + + // FIXME: Delete blocks from graph and restore them in undo } // If we picked up a block to trim the out point of @@ -221,13 +223,12 @@ void TrackRippleRemoveAreaCommand::redo() } // If we were given a block to insert, insert it here - if (insert_ != nullptr) { - track_->AddBlockToGraph(insert_); - - if (trim_out_ == nullptr) { + if (insert_) { + qDebug() << "Insert is" << insert_ << ", parent is" << insert_->parent(); + if (!trim_out_) { // This is the start of the Sequence track_->PrependBlock(insert_); - } else if (trim_in_ == nullptr) { + } else if (!trim_in_) { // This is the end of the Sequence track_->AppendBlock(insert_); } else { @@ -291,7 +292,6 @@ TrackPlaceBlockCommand::TrackPlaceBlockCommand(TrackList *timeline, int track, B gap_(nullptr) { insert_ = block; - insert_->setParent(&memory_manager_); } void TrackPlaceBlockCommand::redo() @@ -315,6 +315,7 @@ void TrackPlaceBlockCommand::redo() // If so, insert a gap here gap_ = new GapBlock(); gap_->set_length(in_ - track_->track_length()); + static_cast(track_->parent())->AddNode(gap_); track_->AppendBlock(gap_); } @@ -331,7 +332,6 @@ void TrackPlaceBlockCommand::undo() { if (append_) { track_->RippleRemoveBlock(insert_); - TakeNodeFromParentGraph(insert_, &memory_manager_); if (gap_ != nullptr) { track_->RippleRemoveBlock(gap_); @@ -365,7 +365,7 @@ void BlockSplitCommand::redo() block_->set_length(new_length_); - track_->AddBlockToGraph(new_block_); + static_cast(block_->parent())->AddNode(new_block_); Node::CopyInputs(block_, new_block_); // Will re-parent new_block_ to the track's graph