diff --git a/app/node/edge.cpp b/app/node/edge.cpp index 1765d6c1b..5f009b8f3 100644 --- a/app/node/edge.cpp +++ b/app/node/edge.cpp @@ -20,22 +20,31 @@ #include "edge.h" +#include "input.h" +#include "node.h" +#include "output.h" + OLIVE_NAMESPACE_ENTER -NodeEdge::NodeEdge(NodeOutput *output, NodeInput *input) : - output_(output), - input_(input) +NodeEdge::NodeEdge(NodeOutput *output, NodeInput *input) { + output_ = ParamToConnection(output); + input_ = ParamToConnection(input); } -NodeOutput *NodeEdge::output() +NodeOutput *NodeEdge::output() const { - return output_; + return output_.node->GetOutputWithID(output_.id); } -NodeInput *NodeEdge::input() +NodeInput *NodeEdge::input() const { - return input_; + return input_.node->GetInputWithID(input_.id); +} + +NodeEdge::Connection NodeEdge::ParamToConnection(NodeParam *param) +{ + return {param->parentNode(), param->id()}; } OLIVE_NAMESPACE_EXIT diff --git a/app/node/edge.h b/app/node/edge.h index 990fdc626..a79b8aec7 100644 --- a/app/node/edge.h +++ b/app/node/edge.h @@ -22,13 +22,16 @@ #define EDGE_H #include +#include #include "common/define.h" OLIVE_NAMESPACE_ENTER -class NodeOutput; +class Node; class NodeInput; +class NodeOutput; +class NodeParam; /** * @brief A connection between two node parameters (a NodeOutput and a NodeInput) @@ -44,19 +47,37 @@ public: */ NodeEdge(NodeOutput* output, NodeInput* input); + Node* output_node() const + { + return output_.node; + } + + Node* input_node() const + { + return input_.node; + } + /** * @brief Return the output parameter this edge is connected to */ - NodeOutput* output(); + NodeOutput* output() const; /** * @brief Return the input parameter this edge is connected to */ - NodeInput* input(); + NodeInput* input() const; private: - NodeOutput* output_; - NodeInput* input_; + struct Connection { + Node* node; + QString id; + }; + + static Connection ParamToConnection(NodeParam* param); + + Connection output_; + Connection input_; + }; using NodeEdgePtr = std::shared_ptr; diff --git a/app/node/inputarray.cpp b/app/node/inputarray.cpp index b1ec0caa8..d9be9bf58 100644 --- a/app/node/inputarray.cpp +++ b/app/node/inputarray.cpp @@ -33,6 +33,12 @@ NodeInputArray::NodeInputArray(const QString &id, const DataType &type, const QV { } +NodeInputArray::~NodeInputArray() +{ + // Clear all connected edges (make sure our override is called) + DisconnectAll(); +} + bool NodeInputArray::IsArray() const { return true; @@ -58,6 +64,10 @@ void NodeInputArray::SetSize(int size) if (size < old_size) { // If the new size is less, delete all extraneous parameters + for (int i=size;iDisconnectAll(); + } + for (int i=size;i &NodeInputArray::sub_params() return sub_params_; } +void NodeInputArray::DisconnectAll() +{ + NodeParam::DisconnectAll(); + + foreach (NodeInput* input, sub_params_) { + input->DisconnectAll(); + } +} + void NodeInputArray::InsertAt(int index) { // Add another input at the end diff --git a/app/node/inputarray.h b/app/node/inputarray.h index 8a935f73e..5aac757ac 100644 --- a/app/node/inputarray.h +++ b/app/node/inputarray.h @@ -31,6 +31,8 @@ class NodeInputArray : public NodeInput public: NodeInputArray(const QString &id, const DataType& type, const QVariant& default_value = 0); + virtual ~NodeInputArray() override; + virtual bool IsArray() const override; int GetSize() const; @@ -51,6 +53,8 @@ public: const QVector& sub_params(); + virtual void DisconnectAll() override; + signals: void SizeChanged(int size); diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 92eb93290..3c0c11ced 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -55,6 +55,11 @@ TrackOutput::TrackOutput() : track_height_ = kTrackHeightDefault; } +TrackOutput::~TrackOutput() +{ + DisconnectAll(); +} + void TrackOutput::set_track_type(const Timeline::TrackType &track_type) { track_type_ = track_type; @@ -553,7 +558,7 @@ void TrackOutput::BlockConnected(NodeEdgePtr edge) void TrackOutput::BlockDisconnected(NodeEdgePtr edge) { - Block* b = static_cast(edge->output()->parentNode()); + Block* b = static_cast(edge->output_node()); if (block_cache_.contains(b)) { block_cache_.removeOne(b); diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index 954b9b45f..dc02b1979 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -36,6 +36,8 @@ class TrackOutput : public Node public: TrackOutput(); + virtual ~TrackOutput() override; + const Timeline::TrackType& track_type() const; void set_track_type(const Timeline::TrackType& track_type); diff --git a/app/node/output/track/tracklist.cpp b/app/node/output/track/tracklist.cpp index 9871baabb..835e031c5 100644 --- a/app/node/output/track/tracklist.cpp +++ b/app/node/output/track/tracklist.cpp @@ -134,7 +134,7 @@ TrackOutput* TrackList::AddTrack() return track; } -void TrackList::RemoveTrack() +void TrackList::RemoveTrack(QObject* new_parent) { if (track_cache_.isEmpty()) { return; @@ -144,7 +144,11 @@ void TrackList::RemoveTrack() GetParentGraph()->TakeNode(track); - delete track; + if (!new_parent) { + delete track; + } else { + track->setParent(new_parent); + } track_input_->RemoveLast(); } diff --git a/app/node/output/track/tracklist.h b/app/node/output/track/tracklist.h index d0923f577..78a7aa035 100644 --- a/app/node/output/track/tracklist.h +++ b/app/node/output/track/tracklist.h @@ -44,7 +44,7 @@ public: TrackOutput *AddTrack(); - void RemoveTrack(); + void RemoveTrack(QObject *new_parent); const rational& GetTotalLength() const; diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index b88fb86ba..ca99b0837 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -62,6 +62,11 @@ ViewerOutput::ViewerOutput() : uuid_ = QUuid::createUuid(); } +ViewerOutput::~ViewerOutput() +{ + DisconnectAll(); +} + Node *ViewerOutput::copy() const { return new ViewerOutput(); diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index b4aef96a0..94185f2ac 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -47,6 +47,8 @@ class ViewerOutput : public Node public: ViewerOutput(); + virtual ~ViewerOutput() override; + virtual Node* copy() const override; virtual QString Name() const override; diff --git a/app/node/param.cpp b/app/node/param.cpp index 601b393da..de6453a7d 100644 --- a/app/node/param.cpp +++ b/app/node/param.cpp @@ -43,9 +43,7 @@ NodeParam::NodeParam(const QString &id) : NodeParam::~NodeParam() { // Clear all connected edges - while (!edges_.isEmpty()) { - DisconnectEdge(edges_.last()); - } + DisconnectAll(); } const QString NodeParam::id() const @@ -111,7 +109,7 @@ const QVector &NodeParam::edges() void NodeParam::DisconnectAll() { while (!edges_.isEmpty()) { - DisconnectEdge(edges_.first()); + DisconnectEdge(edges_.last()); } } diff --git a/app/node/param.h b/app/node/param.h index 0157d7bdd..553dbe248 100644 --- a/app/node/param.h +++ b/app/node/param.h @@ -319,7 +319,7 @@ public: /** * @brief Disconnect any edges connecting this parameter to other parameters */ - void DisconnectAll(); + virtual void DisconnectAll(); /** * @brief Connect an output parameter to an input parameter diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp index b8d7e526f..77d3e250f 100644 --- a/app/widget/nodeview/nodeview.cpp +++ b/app/widget/nodeview/nodeview.cpp @@ -922,8 +922,8 @@ void NodeView::UpdateBlockFilter() // Show only edges between those dependencies foreach (NodeViewEdge* edge, scene_.edge_map()) { - edge->setVisible((currently_visible.contains(edge->edge()->input()->parentNode()) - && currently_visible.contains(edge->edge()->output()->parentNode()))); + edge->setVisible((currently_visible.contains(edge->edge()->input_node()) + && currently_visible.contains(edge->edge()->output_node()))); } } @@ -1024,7 +1024,7 @@ void NodeView::GraphEdgeRemoved(NodeEdgePtr edge) { scene_.RemoveEdge(edge); - Node* output_node = edge->output()->parentNode(); + Node* output_node = edge->output_node(); // Check if this disconnected node still connects to a selected block, in which case do nothing foreach (Block* b, selected_blocks_) { diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index bfb186655..6bb7c11b2 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -271,6 +271,10 @@ void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n) disconnect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase); disconnect(n, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged); + foreach (TrackOutput* track, n->GetTracks()) { + RemoveTrack(track); + } + ruler()->SetPlaybackCache(nullptr); SetTimebase(0); diff --git a/app/widget/timelinewidget/undo/undo.cpp b/app/widget/timelinewidget/undo/undo.cpp index c807c46c2..dd6a48b09 100644 --- a/app/widget/timelinewidget/undo/undo.cpp +++ b/app/widget/timelinewidget/undo/undo.cpp @@ -397,7 +397,7 @@ void TrackPlaceBlockCommand::undo_internal() } for (;added_track_count_>0;added_track_count_--) { - timeline_->RemoveTrack(); + timeline_->RemoveTrack(&memory_manager_); } } diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index 07e81dea5..cf5424700 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -319,19 +319,6 @@ void MainWindow::ProjectOpen(Project *p) void MainWindow::ProjectClose(Project *p) { - // Close project from project panel - foreach (ProjectPanel* panel, project_panels_) { - if (panel->project() == p) { - RemoveProjectPanel(panel); - } - } - - foreach (ProjectPanel* panel, folder_panels_) { - if (panel->project() == p) { - panel->close(); - } - } - // Close any open sequences from project QList open_sequences = p->get_items_of_type(Item::kSequence); @@ -358,6 +345,20 @@ void MainWindow::ProjectClose(Project *p) } } } + + // Close any extra folder panels + foreach (ProjectPanel* panel, folder_panels_) { + if (panel->project() == p) { + panel->close(); + } + } + + // Close project from project panel + foreach (ProjectPanel* panel, project_panels_) { + if (panel->project() == p) { + RemoveProjectPanel(panel); + } + } } void MainWindow::SetApplicationProgressStatus(ProgressStatus status)