diff --git a/app/common/qtutils.h b/app/common/qtutils.h index 851078aed..8fb85ae1c 100644 --- a/app/common/qtutils.h +++ b/app/common/qtutils.h @@ -75,6 +75,23 @@ public: static QColor toQColor(const core::Color &c); + /** + * @brief Convert a pointer to a value that can be sent between NodeParams + */ + static QVariant PtrToValue(void* ptr) + { + return reinterpret_cast(ptr); + } + + /** + * @brief Convert a NodeParam value to a pointer of any kind + */ + template + static T* ValueToPtr(const QVariant &ptr) + { + return reinterpret_cast(ptr.value()); + } + }; namespace core { diff --git a/app/common/xmlutils.cpp b/app/common/xmlutils.cpp index 8396532ff..ec451d415 100644 --- a/app/common/xmlutils.cpp +++ b/app/common/xmlutils.cpp @@ -22,8 +22,6 @@ #include "node/block/block.h" #include "node/factory.h" -#include "widget/nodeparamview/nodeparamviewundo.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { diff --git a/app/core.cpp b/app/core.cpp index dff06168e..f06e48c15 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -52,6 +52,7 @@ #include "dialog/preferences/preferences.h" #include "node/color/colormanager/colormanager.h" #include "node/factory.h" +#include "node/nodeundo.h" #include "node/project/serializer/serializer.h" #include "panel/panelmanager.h" #include "panel/project/project.h" @@ -73,7 +74,6 @@ #include "widget/menu/menushared.h" #include "widget/taskview/taskviewitem.h" #include "widget/viewer/viewer.h" -#include "widget/nodeparamview/nodeparamviewundo.h" #include "window/mainwindow/mainstatusbar.h" #include "window/mainwindow/mainwindow.h" diff --git a/app/dialog/footageproperties/footageproperties.cpp b/app/dialog/footageproperties/footageproperties.cpp index d33517766..ece3e5688 100644 --- a/app/dialog/footageproperties/footageproperties.cpp +++ b/app/dialog/footageproperties/footageproperties.cpp @@ -32,9 +32,9 @@ #include #include "core.h" +#include "node/nodeundo.h" #include "streamproperties/audiostreamproperties.h" #include "streamproperties/videostreamproperties.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { diff --git a/app/dialog/keyframeproperties/keyframeproperties.cpp b/app/dialog/keyframeproperties/keyframeproperties.cpp index 53d7558c2..45fa39d32 100644 --- a/app/dialog/keyframeproperties/keyframeproperties.cpp +++ b/app/dialog/keyframeproperties/keyframeproperties.cpp @@ -24,8 +24,8 @@ #include #include "core.h" +#include "node/nodeundo.h" #include "widget/keyframeview/keyframeviewundo.h" -#include "widget/nodeparamview/nodeparamviewundo.h" namespace olive { diff --git a/app/dialog/speedduration/speeddurationdialog.cpp b/app/dialog/speedduration/speeddurationdialog.cpp index 8f186ed20..818952024 100644 --- a/app/dialog/speedduration/speeddurationdialog.cpp +++ b/app/dialog/speedduration/speeddurationdialog.cpp @@ -1,7 +1,7 @@ /*** Olive - Non-Linear Video Editor - Copyright (C) 2022 Olive Team + Copyright (C) 2023 Olive Studios LLC This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,8 +26,8 @@ #include #include "core.h" -#include "widget/nodeparamview/nodeparamviewundo.h" -#include "widget/timelinewidget/undo/timelineundopointer.h" +#include "node/nodeundo.h" +#include "timeline/timelineundopointer.h" namespace olive { diff --git a/app/node/CMakeLists.txt b/app/node/CMakeLists.txt index 48734c072..ef1978c21 100644 --- a/app/node/CMakeLists.txt +++ b/app/node/CMakeLists.txt @@ -44,6 +44,8 @@ set(OLIVE_SOURCES node/keyframe.h node/node.cpp node/node.h + node/nodeundo.cpp + node/nodeundo.h node/param.cpp node/param.h node/project.cpp diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index 8beda3450..d6bfbe56a 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -44,7 +44,8 @@ Block::Block() : SetInputProperty(kLengthInput, QStringLiteral("view"), RationalSlider::kTime); SetInputProperty(kLengthInput, QStringLiteral("viewlock"), true); - SetInputFlags(kEnabledInput, InputFlags(GetInputFlags(kEnabledInput) | kInputFlagNotConnectable | kInputFlagNotKeyframable)); + SetInputFlag(kEnabledInput, kInputFlagNotConnectable); + SetInputFlag(kEnabledInput, kInputFlagNotKeyframable); SetFlag(kDontShowInParamView); } diff --git a/app/node/block/subtitle/subtitle.cpp b/app/node/block/subtitle/subtitle.cpp index 61c02f045..b645a1595 100644 --- a/app/node/block/subtitle/subtitle.cpp +++ b/app/node/block/subtitle/subtitle.cpp @@ -30,12 +30,12 @@ SubtitleBlock::SubtitleBlock() { AddInput(kTextIn, NodeValue::kText, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable)); - SetInputFlags(kBufferIn, InputFlags(GetInputFlags(kBufferIn) | kInputFlagHidden)); - SetInputFlags(kLengthInput, InputFlags(GetInputFlags(kLengthInput) | kInputFlagHidden)); - SetInputFlags(kMediaInInput, InputFlags(GetInputFlags(kMediaInInput) | kInputFlagHidden)); - SetInputFlags(kSpeedInput, InputFlags(GetInputFlags(kSpeedInput) | kInputFlagHidden)); - SetInputFlags(kReverseInput, InputFlags(GetInputFlags(kReverseInput) | kInputFlagHidden)); - SetInputFlags(kMaintainAudioPitchInput, InputFlags(GetInputFlags(kMaintainAudioPitchInput) | kInputFlagHidden)); + SetInputFlag(kBufferIn, kInputFlagHidden); + SetInputFlag(kLengthInput, kInputFlagHidden); + SetInputFlag(kMediaInInput, kInputFlagHidden); + SetInputFlag(kSpeedInput, kInputFlagHidden); + SetInputFlag(kReverseInput, kInputFlagHidden); + SetInputFlag(kMaintainAudioPitchInput, kInputFlagHidden); // Undo block flag that hides in param view SetFlag(kDontShowInParamView, false); diff --git a/app/node/distort/mask/mask.cpp b/app/node/distort/mask/mask.cpp index dc1941b03..1dc0acb49 100644 --- a/app/node/distort/mask/mask.cpp +++ b/app/node/distort/mask/mask.cpp @@ -32,7 +32,7 @@ const QString MaskDistortNode::kInvertInput = QStringLiteral("invert_in"); MaskDistortNode::MaskDistortNode() { // Mask should always be (1.0, 1.0, 1.0) for multiply to work correctly - SetInputFlags(kColorInput, InputFlags(GetInputFlags(kColorInput) | kInputFlagHidden)); + SetInputFlag(kColorInput, kInputFlagHidden); AddInput(kInvertInput, NodeValue::kBoolean, false); diff --git a/app/node/filter/blur/blur.cpp b/app/node/filter/blur/blur.cpp index 3498cddec..8d0b68bd3 100644 --- a/app/node/filter/blur/blur.cpp +++ b/app/node/filter/blur/blur.cpp @@ -209,10 +209,10 @@ void BlurFilterNode::InputValueChangedEvent(const QString &input, int element) void BlurFilterNode::UpdateInputs(Method method) { - SetInputFlags(kHorizInput, (method == kBox || method == kGaussian) ? InputFlags() : InputFlags(kInputFlagHidden)); - SetInputFlags(kVertInput, (method == kBox || method == kGaussian) ? InputFlags() : InputFlags(kInputFlagHidden)); - SetInputFlags(kDirectionalDegreesInput, (method == kDirectional) ? InputFlags() : InputFlags(kInputFlagHidden)); - SetInputFlags(kRadialCenterInput, (method == kRadial) ? InputFlags() : InputFlags(kInputFlagHidden)); + SetInputFlag(kHorizInput, kInputFlagHidden, !(method == kBox || method == kGaussian)); + SetInputFlag(kVertInput, kInputFlagHidden, !(method == kBox || method == kGaussian)); + SetInputFlag(kDirectionalDegreesInput, kInputFlagHidden, !(method == kDirectional)); + SetInputFlag(kRadialCenterInput, kInputFlagHidden, !(method == kRadial)); } } diff --git a/app/node/generator/shape/shapenode.cpp b/app/node/generator/shape/shapenode.cpp index b8f5a7132..4c866e279 100644 --- a/app/node/generator/shape/shapenode.cpp +++ b/app/node/generator/shape/shapenode.cpp @@ -90,13 +90,7 @@ void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Nod void ShapeNode::InputValueChangedEvent(const QString &input, int element) { if (input == kTypeInput) { - InputFlags i = GetInputFlags(kRadiusInput); - if (GetStandardValue(kTypeInput).toInt() == kRoundedRectangle) { - i &= InputFlag(~kInputFlagHidden); - } else { - i |= kInputFlagHidden; - } - SetInputFlags(kRadiusInput, i); + SetInputFlag(kRadiusInput, kInputFlagHidden, (GetStandardValue(kTypeInput).toInt() != kRoundedRectangle)); } super::InputValueChangedEvent(input, element); } diff --git a/app/node/generator/shape/shapenodebase.cpp b/app/node/generator/shape/shapenodebase.cpp index 2a008526d..f57034ca7 100644 --- a/app/node/generator/shape/shapenodebase.cpp +++ b/app/node/generator/shape/shapenodebase.cpp @@ -25,7 +25,7 @@ #include "common/util.h" #include "core.h" -#include "widget/nodeparamview/nodeparamviewundo.h" +#include "node/nodeundo.h" namespace olive { diff --git a/app/node/generator/text/textv3.cpp b/app/node/generator/text/textv3.cpp index b33ec71c9..ea1ad9d55 100644 --- a/app/node/generator/text/textv3.cpp +++ b/app/node/generator/text/textv3.cpp @@ -27,7 +27,7 @@ #include "common/html.h" #include "core.h" #include "node/project.h" -#include "widget/nodeparamview/nodeparamviewundo.h" +#include "node/nodeundo.h" namespace olive { diff --git a/app/node/input/multicam/multicamnode.cpp b/app/node/input/multicam/multicamnode.cpp index e34220906..1ea80d5ae 100644 --- a/app/node/input/multicam/multicamnode.cpp +++ b/app/node/input/multicam/multicamnode.cpp @@ -103,7 +103,7 @@ void MultiCamNode::InputConnectedEvent(const QString &input, int element, Node * { if (input == kSequenceInput) { if (Sequence *s = dynamic_cast(output)) { - SetInputFlags(kSequenceTypeInput, GetInputFlags(kSequenceTypeInput) & InputFlag(~kInputFlagHidden)); + SetInputFlag(kSequenceTypeInput, kInputFlagHidden, false); sequence_ = s; } } @@ -112,7 +112,7 @@ void MultiCamNode::InputConnectedEvent(const QString &input, int element, Node * void MultiCamNode::InputDisconnectedEvent(const QString &input, int element, Node *output) { if (input == kSequenceInput) { - SetInputFlags(kSequenceTypeInput, GetInputFlags(kSequenceTypeInput) | kInputFlagHidden); + SetInputFlag(kSequenceTypeInput, kInputFlagHidden, true); sequence_ = nullptr; } } diff --git a/app/node/inputdragger.cpp b/app/node/inputdragger.cpp index daff897b3..5832d0097 100644 --- a/app/node/inputdragger.cpp +++ b/app/node/inputdragger.cpp @@ -22,7 +22,7 @@ #include "core.h" #include "node.h" -#include "widget/nodeparamview/nodeparamviewundo.h" +#include "nodeundo.h" namespace olive { diff --git a/app/node/node.cpp b/app/node/node.cpp index 94af73f63..11803f124 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -29,11 +29,10 @@ #include "core.h" #include "config/config.h" #include "node/group/group.h" +#include "nodeundo.h" #include "project.h" #include "ui/colorcoding.h" #include "ui/icons/icons.h" -#include "widget/nodeparamview/nodeparamviewundo.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { @@ -42,7 +41,6 @@ namespace olive { const QString Node::kEnabledInput = QStringLiteral("enabled_in"); Node::Node() : - can_be_deleted_(true), override_color_(-1), folder_(nullptr), flags_(kNone), @@ -205,7 +203,7 @@ void Node::ConnectEdge(Node *output, const NodeInput &input) emit output->OutputConnected(output, input); // Invalidate all if this node isn't ignoring this input - if (!input.node()->ignore_connections_.contains(input.input())) { + if (!(input.node()->GetInputFlags(input.input()) & kInputFlagIgnoreConnections)) { input.node()->InvalidateAll(input.input(), input.element()); } } @@ -232,7 +230,7 @@ void Node::DisconnectEdge(Node *output, const NodeInput &input) emit input.node()->InputDisconnected(output, input); emit output->OutputDisconnected(output, input); - if (!input.node()->ignore_connections_.contains(input.input())) { + if (!(input.node()->GetInputFlags(input.input()) & kInputFlagIgnoreConnections)) { input.node()->InvalidateAll(input.input(), input.element()); } } @@ -815,7 +813,7 @@ void Node::InputArrayResize(const QString &id, int size) return; } - ArrayResizeCommand* c = new ArrayResizeCommand(this, id, size); + NodeArrayResizeCommand* c = new NodeArrayResizeCommand(this, id, size); c->redo_now(); delete c; } @@ -905,12 +903,16 @@ InputFlags Node::GetInputFlags(const QString &input) const } } -void Node::SetInputFlags(const QString &input, const InputFlags &f) +void Node::SetInputFlag(const QString &input, InputFlag f, bool on) { Input* i = GetInternalInputData(input); if (i) { - i->flags = f; + if (on) { + i->flags |= f; + } else { + i->flags &= ~f; + } emit InputFlagsChanged(input, i->flags); } else { ReportInvalidInput("set flags of", input, -1); @@ -1309,11 +1311,6 @@ void Node::SetInputName(const QString &id, const QString &name) } } -void Node::IgnoreInvalidationsFrom(const QString& input_id) -{ - ignore_connections_.append(input_id); -} - const QString &Node::GetLabel() const { return label_; @@ -1426,7 +1423,7 @@ void Node::CopyValuesOfElement(const Node *src, Node *dst, const QString &input, // Copy keyframes if (NodeInputImmediate *immediate = dst->GetImmediate(input, dst_element)) { if (command) { - command->add_child(new ImmediateRemoveAllKeyframesCommand(immediate)); + command->add_child(new NodeImmediateRemoveAllKeyframesCommand(immediate)); } else { immediate->delete_all_keyframes(); } @@ -1455,7 +1452,7 @@ void Node::CopyValuesOfElement(const Node *src, Node *dst, const QString &input, if (src_element == -1 && dst_element == -1) { int array_sz = src->InputArraySize(input); if (command) { - command->add_child(new Node::ArrayResizeCommand(dst, input, array_sz)); + command->add_child(new NodeArrayResizeCommand(dst, input, array_sz)); } else { dst->ArrayResizeInternal(input, array_sz); } @@ -1470,16 +1467,6 @@ void Node::CopyValuesOfElement(const Node *src, Node *dst, const QString &input, } } -bool Node::CanBeDeleted() const -{ - return can_be_deleted_; -} - -void Node::SetCanBeDeleted(bool s) -{ - can_be_deleted_ = s; -} - void GetDependenciesRecursively(QVector& list, const Node* node, bool traverse, bool exclusive_only) { for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) { @@ -1650,18 +1637,13 @@ TimeRange Node::TransformTimeTo(TimeRange time, Node *target, TransformTimeDirec return time; } -QVariant Node::PtrToValue(void *ptr) -{ - return reinterpret_cast(ptr); -} - void Node::ParameterValueChanged(const QString& input, int element, const TimeRange& range) { InputValueChangedEvent(input, element); emit ValueChanged(NodeInput(this, input, element), range); - if (ignore_connections_.contains(input)) { + if (GetInputFlags(input) & kInputFlagIgnoreConnections) { return; } @@ -1948,131 +1930,4 @@ std::list Node::FindPath(Node *from, Node *to, int path_index) return v; } -Project *Node::ArrayInsertCommand::GetRelevantProject() const -{ - return node_->project(); -} - -Project *Node::ArrayRemoveCommand::GetRelevantProject() const -{ - return node_->project(); -} - -Project *Node::ArrayResizeCommand::GetRelevantProject() const -{ - return node_->project(); -} - -void NodeSetPositionCommand::redo() -{ - added_ = !context_->ContextContainsNode(node_); - - if (!added_) { - old_pos_ = context_->GetNodePositionDataInContext(node_); - } - - context_->SetNodePositionInContext(node_, pos_); -} - -void NodeSetPositionCommand::undo() -{ - if (added_) { - context_->RemoveNodeFromContext(node_); - } else { - context_->SetNodePositionInContext(node_, old_pos_); - } -} - -void NodeRemovePositionFromContextCommand::redo() -{ - contained_ = context_->ContextContainsNode(node_); - - if (contained_) { - old_pos_ = context_->GetNodePositionDataInContext(node_); - context_->RemoveNodeFromContext(node_); - } -} - -void NodeRemovePositionFromContextCommand::undo() -{ - if (contained_) { - context_->SetNodePositionInContext(node_, old_pos_); - } -} - -void NodeRemovePositionFromAllContextsCommand::redo() -{ - Project *graph = node_->parent(); - - foreach (Node* context, graph->nodes()) { - if (context->ContextContainsNode(node_)) { - contexts_.insert({context, context->GetNodePositionInContext(node_)}); - context->RemoveNodeFromContext(node_); - } - } -} - -void NodeRemovePositionFromAllContextsCommand::undo() -{ - for (auto it = contexts_.crbegin(); it != contexts_.crend(); it++) { - it->first->SetNodePositionInContext(node_, it->second); - } - - contexts_.clear(); -} - -void NodeSetPositionAndDependenciesRecursivelyCommand::prepare() -{ - move_recursively(node_, pos_.position - context_->GetNodePositionDataInContext(node_).position); -} - -void NodeSetPositionAndDependenciesRecursivelyCommand::redo() -{ - for (auto it=commands_.cbegin(); it!=commands_.cend(); it++) { - (*it)->redo_now(); - } -} - -void NodeSetPositionAndDependenciesRecursivelyCommand::undo() -{ - for (auto it=commands_.crbegin(); it!=commands_.crend(); it++) { - (*it)->undo_now(); - } -} - -void NodeSetPositionAndDependenciesRecursivelyCommand::move_recursively(Node *node, const QPointF &diff) -{ - Node::Position pos = context_->GetNodePositionDataInContext(node); - pos += diff; - commands_.append(new NodeSetPositionCommand(node_, context_, pos)); - - for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) { - Node *output = it->second; - if (context_->ContextContainsNode(output)) { - move_recursively(output, diff); - } - } -} - -void Node::ImmediateRemoveAllKeyframesCommand::prepare() -{ - for (const NodeKeyframeTrack& track : immediate_->keyframe_tracks()) { - keys_.append(track); - } -} - -void Node::ImmediateRemoveAllKeyframesCommand::redo() -{ - for (auto it=keys_.cbegin(); it!=keys_.cend(); it++) { - (*it)->setParent(&memory_manager_); - } -} - -void Node::ImmediateRemoveAllKeyframesCommand::undo() -{ - for (auto it=keys_.crbegin(); it!=keys_.crend(); it++) { - (*it)->setParent(&memory_manager_); - } -} - } diff --git a/app/node/node.h b/app/node/node.h index ae9007916..974db61f8 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -635,6 +635,8 @@ public: int InputArraySize(const QString& id) const; + NodeInputImmediate* GetImmediate(const QString& input, int element) const; + NodeInput GetEffectInput() { return effect_input_.isEmpty() ? NodeInput() : NodeInput(this, effect_input_); @@ -832,17 +834,6 @@ public: template static QVector FindInputNodesConnectedToInput(const NodeInput &input, int maximum = 0); - /** - * @brief Convert a pointer to a value that can be sent between NodeParams - */ - static QVariant PtrToValue(void* ptr); - - template - /** - * @brief Convert a NodeParam value to a pointer of any kind - */ - static T* ValueToPtr(const QVariant& ptr); - using InvalidateCacheOptions = QHash; /** @@ -899,16 +890,6 @@ public: static Node* CopyNodeInGraph(Node *node, MultiUndoCommand* command); - /** - * @brief Return whether this Node can be deleted or not - */ - bool CanBeDeleted() const; - - /** - * @brief Set whether this Node can be deleted in the UI or not - */ - void SetCanBeDeleted(bool s); - /** * @brief The main processing function * @@ -965,147 +946,8 @@ public: folder_ = folder; } - class ArrayInsertCommand : public UndoCommand - { - public: - ArrayInsertCommand(Node* node, const QString& input, int index) : - node_(node), - input_(input), - index_(index) - { - } - - virtual Project* GetRelevantProject() const override; - - protected: - virtual void redo() override - { - node_->InputArrayInsert(input_, index_); - } - - virtual void undo() override - { - node_->InputArrayRemove(input_, index_); - } - - private: - Node* node_; - QString input_; - int index_; - - }; - - class ArrayResizeCommand : public UndoCommand - { - public: - ArrayResizeCommand(Node* node, const QString& input, int size) : - node_(node), - input_(input), - size_(size) - {} - - virtual Project* GetRelevantProject() const override; - - protected: - virtual void redo() override - { - old_size_ = node_->InputArraySize(input_); - - if (old_size_ > size_) { - // Decreasing in size, disconnect any extraneous edges - for (int i=size_; iinput_connections().at(input); - - removed_connections_[input] = output; - - DisconnectEdge(output, input); - } catch (std::out_of_range&) {} - } - } - - node_->ArrayResizeInternal(input_, size_); - } - - virtual void undo() override - { - for (auto it=removed_connections_.cbegin(); it!=removed_connections_.cend(); it++) { - ConnectEdge(it->second, it->first); - } - removed_connections_.clear(); - - node_->ArrayResizeInternal(input_, old_size_); - } - - private: - Node* node_; - QString input_; - int size_; - int old_size_; - - InputConnections removed_connections_; - - }; - - class ArrayRemoveCommand : public UndoCommand - { - public: - ArrayRemoveCommand(Node* node, const QString& input, int index) : - node_(node), - input_(input), - index_(index) - { - } - - virtual Project* GetRelevantProject() const override; - - protected: - virtual void redo() override - { - // Save immediate data - if (node_->IsInputKeyframable(input_)) { - is_keyframing_ = node_->IsInputKeyframing(input_, index_); - } - standard_value_ = node_->GetSplitStandardValue(input_, index_); - keyframes_ = node_->GetKeyframeTracks(input_, index_); - node_->GetImmediate(input_, index_)->delete_all_keyframes(&memory_manager_); - - node_->InputArrayRemove(input_, index_); - } - - virtual void undo() override - { - node_->InputArrayInsert(input_, index_); - - // Restore keyframes - foreach (const NodeKeyframeTrack& track, keyframes_) { - foreach (NodeKeyframe* key, track) { - key->setParent(node_); - } - } - node_->SetSplitStandardValue(input_, standard_value_, index_); - - if (node_->IsInputKeyframable(input_)) { - node_->SetInputIsKeyframing(input_, is_keyframing_, index_); - } - } - - private: - Node* node_; - QString input_; - int index_; - - SplitValue standard_value_; - bool is_keyframing_; - QVector keyframes_; - QObject memory_manager_; - - }; - InputFlags GetInputFlags(const QString& input) const; - void SetInputFlags(const QString &input, const InputFlags &f); + void SetInputFlag(const QString &input, InputFlag f, bool on = true); virtual void LoadFinishedEvent(){} virtual void ConnectedToPreviewEvent(){} @@ -1117,6 +959,8 @@ public: */ static std::list FindPath(Node *from, Node *to, int path_index); + void ArrayResizeInternal(const QString& id, int size); + static const QString kEnabledInput; protected: @@ -1151,15 +995,6 @@ protected: void SendInvalidateCache(const TimeRange &range, const InvalidateCacheOptions &options); - /** - * @brief Don't send cache invalidation signals if `input` is connected or disconnected - * - * By default, when a node is connected or disconnected from input, the Node assumes that the - * parameters has changed throughout the duration of the clip (essential from 0 to infinity). - * In some scenarios, it may be preferable to handle this signal separately in order to - */ - void IgnoreInvalidationsFrom(const QString &input_id); - enum GizmoScaleHandles { kGizmoScaleTopLeft, kGizmoScaleTopCenter, @@ -1301,35 +1136,8 @@ private: int array_size; }; - class ImmediateRemoveAllKeyframesCommand : public UndoCommand - { - public: - ImmediateRemoveAllKeyframesCommand(NodeInputImmediate *immediate) : - immediate_(immediate) - {} - - virtual Project* GetRelevantProject() const override { return nullptr; } - - protected: - virtual void prepare() override; - - virtual void redo() override; - - virtual void undo() override; - - private: - NodeInputImmediate *immediate_; - - QObject memory_manager_; - - QVector keys_; - - }; - NodeInputImmediate* CreateImmediate(const QString& input); - NodeInputImmediate* GetImmediate(const QString& input, int element) const; - int GetInternalInputIndex(const QString& input) const { return input_ids_.indexOf(input); @@ -1359,8 +1167,6 @@ private: void ReportInvalidInput(const char* attempted_action, const QString &id, int element) const; - void ArrayResizeInternal(const QString& id, int size); - static Node *CopyNodeAndDependencyGraphMinusItemsInternal(QMap &created, Node *node, MultiUndoCommand *command); /** @@ -1397,13 +1203,6 @@ private: void ClearElement(const QString &input, int index); - QVector ignore_connections_; - - /** - * @brief Internal variable for whether this Node can be deleted or not - */ - bool can_be_deleted_; - /** * @brief Custom user label for node */ @@ -1528,128 +1327,6 @@ QVector Node::FindInputNodes(int maximum) const return list; } -template -T* Node::ValueToPtr(const QVariant &ptr) -{ - return reinterpret_cast(ptr.value()); -} - -using NodePtr = std::shared_ptr; - -class NodeSetPositionCommand : public UndoCommand -{ -public: - NodeSetPositionCommand(Node* node, Node* context, const Node::Position& pos) - { - node_ = node; - context_ = context; - pos_ = pos; - } - - virtual Project* GetRelevantProject() const override - { - return node_->project(); - } - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - Node* node_; - Node* context_; - Node::Position pos_; - Node::Position old_pos_; - bool added_; - -}; - -class NodeSetPositionAndDependenciesRecursivelyCommand : public UndoCommand{ -public: - NodeSetPositionAndDependenciesRecursivelyCommand(Node* node, Node* context, const Node::Position& pos) : - node_(node), - context_(context), - pos_(pos) - {} - - virtual Project* GetRelevantProject() const override - { - return node_->project(); - } - -protected: - virtual void prepare() override; - - virtual void redo() override; - - virtual void undo() override; - -private: - void move_recursively(Node *node, const QPointF &diff); - - Node* node_; - Node* context_; - Node::Position pos_; - QVector commands_; - -}; - -class NodeRemovePositionFromContextCommand : public UndoCommand -{ -public: - NodeRemovePositionFromContextCommand(Node *node, Node *context) : - node_(node), - context_(context) - { - } - - virtual Project * GetRelevantProject() const override - { - return node_->project(); - } - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - Node *node_; - - Node *context_; - - Node::Position old_pos_; - - bool contained_; - -}; - -class NodeRemovePositionFromAllContextsCommand : public UndoCommand -{ -public: - NodeRemovePositionFromAllContextsCommand(Node *node) : - node_(node) - { - } - - virtual Project * GetRelevantProject() const override - { - return node_->project(); - } - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - Node *node_; - - std::map contexts_; - -}; - } Q_DECLARE_METATYPE(olive::Node::ValueHint) diff --git a/app/node/nodeundo.cpp b/app/node/nodeundo.cpp new file mode 100644 index 000000000..d78ab94c7 --- /dev/null +++ b/app/node/nodeundo.cpp @@ -0,0 +1,602 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2023 Olive Studios LLC + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "nodeundo.h" + +namespace olive { + +void NodeSetPositionCommand::redo() +{ + added_ = !context_->ContextContainsNode(node_); + + if (!added_) { + old_pos_ = context_->GetNodePositionDataInContext(node_); + } + + context_->SetNodePositionInContext(node_, pos_); +} + +void NodeSetPositionCommand::undo() +{ + if (added_) { + context_->RemoveNodeFromContext(node_); + } else { + context_->SetNodePositionInContext(node_, old_pos_); + } +} + +void NodeRemovePositionFromContextCommand::redo() +{ + contained_ = context_->ContextContainsNode(node_); + + if (contained_) { + old_pos_ = context_->GetNodePositionDataInContext(node_); + context_->RemoveNodeFromContext(node_); + } +} + +void NodeRemovePositionFromContextCommand::undo() +{ + if (contained_) { + context_->SetNodePositionInContext(node_, old_pos_); + } +} + +void NodeRemovePositionFromAllContextsCommand::redo() +{ + Project *graph = node_->parent(); + + foreach (Node* context, graph->nodes()) { + if (context->ContextContainsNode(node_)) { + contexts_.insert({context, context->GetNodePositionInContext(node_)}); + context->RemoveNodeFromContext(node_); + } + } +} + +void NodeRemovePositionFromAllContextsCommand::undo() +{ + for (auto it = contexts_.crbegin(); it != contexts_.crend(); it++) { + it->first->SetNodePositionInContext(node_, it->second); + } + + contexts_.clear(); +} + +void NodeSetPositionAndDependenciesRecursivelyCommand::prepare() +{ + move_recursively(node_, pos_.position - context_->GetNodePositionDataInContext(node_).position); +} + +void NodeSetPositionAndDependenciesRecursivelyCommand::redo() +{ + for (auto it=commands_.cbegin(); it!=commands_.cend(); it++) { + (*it)->redo_now(); + } +} + +void NodeSetPositionAndDependenciesRecursivelyCommand::undo() +{ + for (auto it=commands_.crbegin(); it!=commands_.crend(); it++) { + (*it)->undo_now(); + } +} + +void NodeSetPositionAndDependenciesRecursivelyCommand::move_recursively(Node *node, const QPointF &diff) +{ + Node::Position pos = context_->GetNodePositionDataInContext(node); + pos += diff; + commands_.append(new NodeSetPositionCommand(node_, context_, pos)); + + for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) { + Node *output = it->second; + if (context_->ContextContainsNode(output)) { + move_recursively(output, diff); + } + } +} + +NodeEdgeAddCommand::NodeEdgeAddCommand(Node *output, const NodeInput &input) : + output_(output), + input_(input), + remove_command_(nullptr) +{ +} + +NodeEdgeAddCommand::~NodeEdgeAddCommand() +{ + delete remove_command_; +} + +void NodeEdgeAddCommand::redo() +{ + if (input_.IsConnected()) { + if (!remove_command_) { + remove_command_ = new NodeEdgeRemoveCommand(input_.GetConnectedOutput(), input_); + } + + remove_command_->redo_now(); + } + + Node::ConnectEdge(output_, input_); +} + +void NodeEdgeAddCommand::undo() +{ + Node::DisconnectEdge(output_, input_); + + if (remove_command_) { + remove_command_->undo_now(); + } +} + +Project *NodeEdgeAddCommand::GetRelevantProject() const +{ + return output_->project(); +} + +NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(Node *output, const NodeInput &input) : + output_(output), + input_(input) +{ +} + +void NodeEdgeRemoveCommand::redo() +{ + Node::DisconnectEdge(output_, input_); +} + +void NodeEdgeRemoveCommand::undo() +{ + Node::ConnectEdge(output_, input_); +} + +Project *NodeEdgeRemoveCommand::GetRelevantProject() const +{ + return output_->project(); +} + +NodeAddCommand::NodeAddCommand(Project *graph, Node *node) : + graph_(graph), + node_(node) +{ + // 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::PushToThread(QThread *thread) +{ + memory_manager_.moveToThread(thread); +} + +void NodeAddCommand::redo() +{ + node_->setParent(graph_); +} + +void NodeAddCommand::undo() +{ + node_->setParent(&memory_manager_); +} + +Project *NodeAddCommand::GetRelevantProject() const +{ + return dynamic_cast(graph_); +} + +void NodeRemoveAndDisconnectCommand::prepare() +{ + command_ = new MultiUndoCommand(); + + // If this is a block, remove all links + if (node_->HasLinks()) { + command_->add_child(new NodeUnlinkAllCommand(node_)); + } + + // Disconnect everything + for (auto it=node_->input_connections().cbegin(); it!=node_->input_connections().cend(); it++) { + command_->add_child(new NodeEdgeRemoveCommand(it->second, it->first)); + } + + for (const Node::OutputConnection& conn : node_->output_connections()) { + command_->add_child(new NodeEdgeRemoveCommand(conn.first, conn.second)); + } + + command_->add_child(new NodeRemovePositionFromAllContextsCommand(node_)); +} + +void NodeRenameCommand::AddNode(Node *node, const QString &new_name) +{ + nodes_.append(node); + new_labels_.append(new_name); + old_labels_.append(node->GetLabel()); +} + +void NodeRenameCommand::redo() +{ + for (int i=0; iSetLabel(new_labels_.at(i)); + } +} + +void NodeRenameCommand::undo() +{ + for (int i=0; iSetLabel(old_labels_.at(i)); + } +} + +Project *NodeRenameCommand::GetRelevantProject() const +{ + return nodes_.isEmpty() ? nullptr : nodes_.first()->project(); +} + +NodeOverrideColorCommand::NodeOverrideColorCommand(Node *node, int index) : + node_(node), + new_index_(index) +{ +} + +Project *NodeOverrideColorCommand::GetRelevantProject() const +{ + return node_->project(); +} + +void NodeOverrideColorCommand::redo() +{ + old_index_ = node_->GetOverrideColor(); + node_->SetOverrideColor(new_index_); +} + +void NodeOverrideColorCommand::undo() +{ + node_->SetOverrideColor(old_index_); +} + +NodeViewDeleteCommand::NodeViewDeleteCommand() +{ +} + +void NodeViewDeleteCommand::AddNode(Node *node, Node *context) +{ + if (ContainsNode(node, context)) { + return; + } + + Node::ContextPair p = {node, context}; + nodes_.append(p); + + for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) { + if (context->ContextContainsNode(it->second)) { + AddEdge(it->second, it->first); + } + } + + for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) { + if (context->ContextContainsNode(it->second.node())) { + AddEdge(it->first, it->second); + } + } +} + +void NodeViewDeleteCommand::AddEdge(Node *output, const NodeInput &input) +{ + foreach (const Node::OutputConnection &edge, edges_) { + if (edge.first == output && edge.second == input) { + return; + } + } + + edges_.append({output, input}); +} + +bool NodeViewDeleteCommand::ContainsNode(Node *node, Node *context) +{ + foreach (const Node::ContextPair &pair, nodes_) { + if (pair.node == node && pair.context == context) { + return true; + } + } + + return false; +} + +Project *NodeViewDeleteCommand::GetRelevantProject() const +{ + if (!nodes_.isEmpty()) { + return nodes_.first().node->project(); + } + + if (!edges_.isEmpty()) { + return edges_.first().first->project(); + } + + return nullptr; +} + +void NodeViewDeleteCommand::redo() +{ + foreach (const Node::OutputConnection &edge, edges_) { + Node::DisconnectEdge(edge.first, edge.second); + } + + foreach (const Node::ContextPair &pair, nodes_) { + RemovedNode rn; + + rn.node = pair.node; + rn.context = pair.context; + rn.pos = rn.context->GetNodePositionInContext(rn.node); + + rn.context->RemoveNodeFromContext(rn.node); + + // If node is no longer in any contexts and is not connected to anything, remove it + if (rn.node->parent()->GetNumberOfContextsNodeIsIn(rn.node, true) == 0 + && rn.node->input_connections().empty() + && rn.node->output_connections().empty()) { + rn.removed_from_graph = rn.node->parent(); + rn.node->setParent(&memory_manager_); + } else { + rn.removed_from_graph = nullptr; + } + + removed_nodes_.append(rn); + } +} + +void NodeViewDeleteCommand::undo() +{ + for (auto rn=removed_nodes_.crbegin(); rn!=removed_nodes_.crend(); rn++) { + if (rn->removed_from_graph) { + rn->node->setParent(rn->removed_from_graph); + } + + rn->context->SetNodePositionInContext(rn->node, rn->pos); + } + removed_nodes_.clear(); + + for (auto edge=edges_.crbegin(); edge!=edges_.crend(); edge++) { + Node::ConnectEdge(edge->first, edge->second); + } +} + +NodeParamSetKeyframingCommand::NodeParamSetKeyframingCommand(const NodeInput &input, bool setting) : + input_(input), + new_setting_(setting) +{ +} + +Project *NodeParamSetKeyframingCommand::GetRelevantProject() const +{ + return input_.node()->project(); +} + +void NodeParamSetKeyframingCommand::redo() +{ + old_setting_ = input_.IsKeyframing(); + input_.node()->SetInputIsKeyframing(input_, new_setting_); +} + +void NodeParamSetKeyframingCommand::undo() +{ + input_.node()->SetInputIsKeyframing(input_, old_setting_); +} + +NodeParamSetKeyframeValueCommand::NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& value) : + key_(key), + old_value_(key_->value()), + new_value_(value) +{ +} + +NodeParamSetKeyframeValueCommand::NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant &new_value, const QVariant &old_value) : + key_(key), + old_value_(old_value), + new_value_(new_value) +{ + +} + +Project *NodeParamSetKeyframeValueCommand::GetRelevantProject() const +{ + return key_->parent()->project(); +} + +void NodeParamSetKeyframeValueCommand::redo() +{ + key_->set_value(new_value_); +} + +void NodeParamSetKeyframeValueCommand::undo() +{ + key_->set_value(old_value_); +} + +NodeParamInsertKeyframeCommand::NodeParamInsertKeyframeCommand(Node* node, NodeKeyframe* keyframe) : + input_(node), + keyframe_(keyframe) +{ + // Take ownership of the keyframe + undo(); +} + +Project *NodeParamInsertKeyframeCommand::GetRelevantProject() const +{ + return input_->project(); +} + +void NodeParamInsertKeyframeCommand::redo() +{ + keyframe_->setParent(input_); +} + +void NodeParamInsertKeyframeCommand::undo() +{ + keyframe_->setParent(&memory_manager_); +} + +NodeParamRemoveKeyframeCommand::NodeParamRemoveKeyframeCommand(NodeKeyframe* keyframe) : + input_(keyframe->parent()), + keyframe_(keyframe) +{ +} + +Project *NodeParamRemoveKeyframeCommand::GetRelevantProject() const +{ + return input_->project(); +} + +void NodeParamRemoveKeyframeCommand::redo() +{ + // Removes from input + keyframe_->setParent(&memory_manager_); +} + +void NodeParamRemoveKeyframeCommand::undo() +{ + keyframe_->setParent(input_); +} + +NodeParamSetKeyframeTimeCommand::NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational &time) : + key_(key), + old_time_(key->time()), + new_time_(time) +{ +} + +NodeParamSetKeyframeTimeCommand::NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational &new_time, const rational &old_time) : + key_(key), + old_time_(old_time), + new_time_(new_time) +{ +} + +Project *NodeParamSetKeyframeTimeCommand::GetRelevantProject() const +{ + return key_->parent()->project(); +} + +void NodeParamSetKeyframeTimeCommand::redo() +{ + key_->set_time(new_time_); +} + +void NodeParamSetKeyframeTimeCommand::undo() +{ + key_->set_time(old_time_); +} + +NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant &value) : + ref_(input), + old_value_(ref_.input().node()->GetStandardValue(ref_.input())), + new_value_(value) +{ +} + +NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant &new_value, const QVariant &old_value) : + ref_(input), + old_value_(old_value), + new_value_(new_value) +{ +} + +Project *NodeParamSetStandardValueCommand::GetRelevantProject() const +{ + return ref_.input().node()->project(); +} + +void NodeParamSetStandardValueCommand::redo() +{ + ref_.input().node()->SetSplitStandardValueOnTrack(ref_, new_value_); +} + +void NodeParamSetStandardValueCommand::undo() +{ + ref_.input().node()->SetSplitStandardValueOnTrack(ref_, old_value_); +} + +NodeParamArrayAppendCommand::NodeParamArrayAppendCommand(Node *node, const QString &input) : + node_(node), + input_(input) +{ +} + +Project *NodeParamArrayAppendCommand::GetRelevantProject() const +{ + return node_->project(); +} + +void NodeParamArrayAppendCommand::redo() +{ + node_->InputArrayAppend(input_); +} + +void NodeParamArrayAppendCommand::undo() +{ + node_->InputArrayRemoveLast(input_); +} + +void NodeSetValueHintCommand::redo() +{ + old_hint_ = input_.node()->GetValueHintForInput(input_.input(), input_.element()); + input_.node()->SetValueHintForInput(input_.input(), new_hint_, input_.element()); +} + +void NodeSetValueHintCommand::undo() +{ + input_.node()->SetValueHintForInput(input_.input(), old_hint_, input_.element()); +} + +Project *NodeArrayInsertCommand::GetRelevantProject() const +{ + return node_->project(); +} + +Project *NodeArrayRemoveCommand::GetRelevantProject() const +{ + return node_->project(); +} + +Project *NodeArrayResizeCommand::GetRelevantProject() const +{ + return node_->project(); +} + +void NodeImmediateRemoveAllKeyframesCommand::prepare() +{ + for (const NodeKeyframeTrack& track : immediate_->keyframe_tracks()) { + keys_.append(track); + } +} + +void NodeImmediateRemoveAllKeyframesCommand::redo() +{ + for (auto it=keys_.cbegin(); it!=keys_.cend(); it++) { + (*it)->setParent(&memory_manager_); + } +} + +void NodeImmediateRemoveAllKeyframesCommand::undo() +{ + for (auto it=keys_.crbegin(); it!=keys_.crend(); it++) { + (*it)->setParent(&memory_manager_); + } +} + +} diff --git a/app/node/nodeundo.h b/app/node/nodeundo.h new file mode 100644 index 000000000..6df91caac --- /dev/null +++ b/app/node/nodeundo.h @@ -0,0 +1,869 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2023 Olive Studios LLC + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef NODEUNDO_H +#define NODEUNDO_H + +#include "node/node.h" +#include "node/project.h" +#include "undo/undocommand.h" + +namespace olive { + +class NodeSetPositionCommand : public UndoCommand +{ +public: + NodeSetPositionCommand(Node* node, Node* context, const Node::Position& pos) + { + node_ = node; + context_ = context; + pos_ = pos; + } + + virtual Project* GetRelevantProject() const override + { + return node_->project(); + } + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + Node* node_; + Node* context_; + Node::Position pos_; + Node::Position old_pos_; + bool added_; + +}; + +class NodeSetPositionAndDependenciesRecursivelyCommand : public UndoCommand{ +public: + NodeSetPositionAndDependenciesRecursivelyCommand(Node* node, Node* context, const Node::Position& pos) : + node_(node), + context_(context), + pos_(pos) + {} + + virtual Project* GetRelevantProject() const override + { + return node_->project(); + } + +protected: + virtual void prepare() override; + + virtual void redo() override; + + virtual void undo() override; + +private: + void move_recursively(Node *node, const QPointF &diff); + + Node* node_; + Node* context_; + Node::Position pos_; + QVector commands_; + +}; + +class NodeRemovePositionFromContextCommand : public UndoCommand +{ +public: + NodeRemovePositionFromContextCommand(Node *node, Node *context) : + node_(node), + context_(context) + { + } + + virtual Project * GetRelevantProject() const override + { + return node_->project(); + } + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + Node *node_; + + Node *context_; + + Node::Position old_pos_; + + bool contained_; + +}; + +class NodeRemovePositionFromAllContextsCommand : public UndoCommand +{ +public: + NodeRemovePositionFromAllContextsCommand(Node *node) : + node_(node) + { + } + + virtual Project * GetRelevantProject() const override + { + return node_->project(); + } + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + Node *node_; + + std::map contexts_; + +}; + +class NodeArrayInsertCommand : public UndoCommand +{ +public: + NodeArrayInsertCommand(Node* node, const QString& input, int index) : + node_(node), + input_(input), + index_(index) + { + } + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override + { + node_->InputArrayInsert(input_, index_); + } + + virtual void undo() override + { + node_->InputArrayRemove(input_, index_); + } + +private: + Node* node_; + QString input_; + int index_; + +}; + +class NodeArrayResizeCommand : public UndoCommand +{ +public: + NodeArrayResizeCommand(Node* node, const QString& input, int size) : + node_(node), + input_(input), + size_(size) + {} + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override + { + old_size_ = node_->InputArraySize(input_); + + if (old_size_ > size_) { + // Decreasing in size, disconnect any extraneous edges + for (int i=size_; iinput_connections().at(input); + + removed_connections_[input] = output; + + Node::DisconnectEdge(output, input); + } catch (std::out_of_range&) {} + } + } + + node_->ArrayResizeInternal(input_, size_); + } + + virtual void undo() override + { + for (auto it=removed_connections_.cbegin(); it!=removed_connections_.cend(); it++) { + Node::ConnectEdge(it->second, it->first); + } + removed_connections_.clear(); + + node_->ArrayResizeInternal(input_, old_size_); + } + +private: + Node* node_; + QString input_; + int size_; + int old_size_; + + Node::InputConnections removed_connections_; + +}; + +class NodeArrayRemoveCommand : public UndoCommand +{ +public: + NodeArrayRemoveCommand(Node* node, const QString& input, int index) : + node_(node), + input_(input), + index_(index) + { + } + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override + { + // Save immediate data + if (node_->IsInputKeyframable(input_)) { + is_keyframing_ = node_->IsInputKeyframing(input_, index_); + } + standard_value_ = node_->GetSplitStandardValue(input_, index_); + keyframes_ = node_->GetKeyframeTracks(input_, index_); + node_->GetImmediate(input_, index_)->delete_all_keyframes(&memory_manager_); + + node_->InputArrayRemove(input_, index_); + } + + virtual void undo() override + { + node_->InputArrayInsert(input_, index_); + + // Restore keyframes + foreach (const NodeKeyframeTrack& track, keyframes_) { + foreach (NodeKeyframe* key, track) { + key->setParent(node_); + } + } + node_->SetSplitStandardValue(input_, standard_value_, index_); + + if (node_->IsInputKeyframable(input_)) { + node_->SetInputIsKeyframing(input_, is_keyframing_, index_); + } + } + +private: + Node* node_; + QString input_; + int index_; + + SplitValue standard_value_; + bool is_keyframing_; + QVector keyframes_; + QObject memory_manager_; + +}; + +/** + * @brief An undoable command for disconnecting two NodeParams + * + * Can be considered a UndoCommand wrapper for NodeParam::DisonnectEdge()/ + */ +class NodeEdgeRemoveCommand : public UndoCommand { +public: + NodeEdgeRemoveCommand(Node *output, const NodeInput& input); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + Node *output_; + NodeInput input_; + +}; + +/** + * @brief An undoable command for connecting two NodeParams together + * + * Can be considered a UndoCommand wrapper for NodeParam::ConnectEdge()/ + */ +class NodeEdgeAddCommand : public UndoCommand { +public: + NodeEdgeAddCommand(Node *output, const NodeInput& input); + + virtual ~NodeEdgeAddCommand() override; + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + Node *output_; + NodeInput input_; + + NodeEdgeRemoveCommand* remove_command_; + +}; + +class NodeAddCommand : public UndoCommand { +public: + NodeAddCommand(Project* graph, Node* node); + + void PushToThread(QThread* thread); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + QObject memory_manager_; + + Project* graph_; + Node* node_; +}; + +class NodeRemoveAndDisconnectCommand : public UndoCommand { +public: + NodeRemoveAndDisconnectCommand(Node* node) : + node_(node), + graph_(nullptr), + command_(nullptr) + { + } + + virtual ~NodeRemoveAndDisconnectCommand() override + { + delete command_; + } + + virtual Project* GetRelevantProject() const override + { + return graph_; + } + +protected: + virtual void prepare() override; + + virtual void redo() override + { + command_->redo_now(); + + graph_ = node_->parent(); + node_->setParent(&memory_manager_); + } + + virtual void undo() override + { + node_->setParent(graph_); + graph_ = nullptr; + + command_->undo_now(); + } + +private: + QObject memory_manager_; + + Node* node_; + Project* graph_; + + MultiUndoCommand* command_; + +}; + +class NodeRemoveWithExclusiveDependenciesAndDisconnect : public UndoCommand { +public: + NodeRemoveWithExclusiveDependenciesAndDisconnect(Node* node) : + node_(node), + command_(nullptr) + { + } + + virtual ~NodeRemoveWithExclusiveDependenciesAndDisconnect() override + { + delete command_; + } + + virtual Project* GetRelevantProject() const override + { + if (command_) { + return static_cast(command_->child(0))->GetRelevantProject(); + } else { + return node_->project(); + } + } + +protected: + virtual void prepare() override + { + command_ = new MultiUndoCommand(); + + command_->add_child(new NodeRemoveAndDisconnectCommand(node_)); + + // Remove exclusive dependencies + QVector deps = node_->GetExclusiveDependencies(); + foreach (Node* d, deps) { + command_->add_child(new NodeRemoveAndDisconnectCommand(d)); + } + } + + virtual void redo() override + { + command_->redo_now(); + } + + virtual void undo() override + { + command_->undo_now(); + } + +private: + Node* node_; + MultiUndoCommand* command_; + +}; + +class NodeLinkCommand : public UndoCommand { +public: + NodeLinkCommand(Node* a, Node* b, bool link) : + a_(a), + b_(b), + link_(link) + { + } + + virtual Project* GetRelevantProject() const override + { + return a_->project(); + } + +protected: + virtual void redo() override + { + if (link_) { + done_ = Node::Link(a_, b_); + } else { + done_ = Node::Unlink(a_, b_); + } + } + + virtual void undo() override + { + if (done_) { + if (link_) { + Node::Unlink(a_, b_); + } else { + Node::Link(a_, b_); + } + } + } + +private: + Node* a_; + Node* b_; + bool link_; + bool done_; + +}; + +class NodeUnlinkAllCommand : public UndoCommand { +public: + NodeUnlinkAllCommand(Node* node) : + node_(node) + { + } + + virtual Project* GetRelevantProject() const override + { + return node_->project(); + } + +protected: + virtual void redo() override + { + unlinked_ = node_->links(); + + foreach (Node* link, unlinked_) { + Node::Unlink(node_, link); + } + } + + virtual void undo() override + { + foreach (Node* link, unlinked_) { + Node::Link(node_, link); + } + + unlinked_.clear(); + } + +private: + Node* node_; + + QVector unlinked_; + +}; + +class NodeLinkManyCommand : public MultiUndoCommand { +public: + NodeLinkManyCommand(const QVector nodes, bool link) : + nodes_(nodes) + { + foreach (Node* a, nodes_) { + foreach (Node* b, nodes_) { + if (a != b) { + add_child(new NodeLinkCommand(a, b, link)); + } + } + } + } + + virtual Project* GetRelevantProject() const override + { + return nodes_.first()->project(); + } + +private: + QVector nodes_; + +}; + +class NodeRenameCommand : public UndoCommand +{ +public: + NodeRenameCommand() = default; + NodeRenameCommand(Node* node, const QString& new_name) + { + AddNode(node, new_name); + } + + void AddNode(Node* node, const QString& new_name); + + virtual Project * GetRelevantProject() const override; + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + QVector nodes_; + + QStringList new_labels_; + QStringList old_labels_; + +}; + +class NodeOverrideColorCommand : public UndoCommand +{ +public: + NodeOverrideColorCommand(Node *node, int index); + + virtual Project * GetRelevantProject() const override; + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + Node *node_; + + int old_index_; + + int new_index_; + +}; + +class NodeViewDeleteCommand : public UndoCommand +{ +public: + NodeViewDeleteCommand(); + + void AddNode(Node *node, Node *context); + + void AddEdge(Node *output, const NodeInput &input); + + bool ContainsNode(Node *node, Node *context); + + virtual Project * GetRelevantProject() const override; + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + QVector nodes_; + + QVector edges_; + + struct RemovedNode { + Node *node; + Node *context; + QPointF pos; + Project *removed_from_graph; + }; + + QVector removed_nodes_; + + QObject memory_manager_; + +}; + +class NodeParamSetKeyframingCommand : public UndoCommand +{ +public: + NodeParamSetKeyframingCommand(const NodeInput& input, bool setting); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + NodeInput input_; + bool new_setting_; + bool old_setting_; + +}; + +class NodeParamInsertKeyframeCommand : public UndoCommand +{ +public: + NodeParamInsertKeyframeCommand(Node *node, NodeKeyframe* keyframe); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + Node* input_; + + NodeKeyframe* keyframe_; + + QObject memory_manager_; + +}; + +class NodeParamRemoveKeyframeCommand : public UndoCommand +{ +public: + NodeParamRemoveKeyframeCommand(NodeKeyframe* keyframe); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + Node* input_; + + NodeKeyframe* keyframe_; + + QObject memory_manager_; + +}; + +class NodeParamSetKeyframeTimeCommand : public UndoCommand +{ +public: + NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational& time); + NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational& new_time, const rational& old_time); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + NodeKeyframe* key_; + + rational old_time_; + rational new_time_; + +}; + +class NodeParamSetKeyframeValueCommand : public UndoCommand +{ +public: + NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& value); + NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& new_value, const QVariant& old_value); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + NodeKeyframe* key_; + + QVariant old_value_; + QVariant new_value_; + +}; + +class NodeParamSetStandardValueCommand : public UndoCommand +{ +public: + NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant& value); + NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant& new_value, const QVariant& old_value); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + virtual void undo() override; + +private: + NodeKeyframeTrackReference ref_; + + QVariant old_value_; + QVariant new_value_; + +}; + +class NodeParamSetSplitStandardValueCommand : public UndoCommand +{ +public: + NodeParamSetSplitStandardValueCommand(const NodeInput& input, const SplitValue& new_value, const SplitValue& old_value) : + ref_(input), + old_value_(old_value), + new_value_(new_value) + {} + + NodeParamSetSplitStandardValueCommand(const NodeInput& input, const SplitValue& value) : + NodeParamSetSplitStandardValueCommand(input, value, input.node()->GetSplitStandardValue(input.input())) + {} + + virtual Project* GetRelevantProject() const override + { + return ref_.node()->project(); + } + +protected: + virtual void redo() override + { + ref_.node()->SetSplitStandardValue(ref_.input(), new_value_, ref_.element()); + } + + virtual void undo() override + { + ref_.node()->SetSplitStandardValue(ref_.input(), old_value_, ref_.element()); + } + +private: + NodeInput ref_; + + SplitValue old_value_; + SplitValue new_value_; + +}; + +class NodeParamArrayAppendCommand : public UndoCommand +{ +public: + NodeParamArrayAppendCommand(Node* node, const QString& input); + + virtual Project* GetRelevantProject() const override; + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + Node* node_; + + QString input_; + +}; + +class NodeSetValueHintCommand : public UndoCommand +{ +public: + NodeSetValueHintCommand(const NodeInput &input, const Node::ValueHint &hint) : + input_(input), + new_hint_(hint) + { + } + + NodeSetValueHintCommand(Node *node, const QString &input, int element, const Node::ValueHint &hint) : + NodeSetValueHintCommand(NodeInput(node, input, element), hint) + { + } + + virtual Project* GetRelevantProject() const override + { + return input_.node()->project(); + } + +protected: + virtual void redo() override; + + virtual void undo() override; + +private: + NodeInput input_; + + Node::ValueHint new_hint_; + Node::ValueHint old_hint_; + +}; + +class NodeImmediateRemoveAllKeyframesCommand : public UndoCommand +{ +public: + NodeImmediateRemoveAllKeyframesCommand(NodeInputImmediate *immediate) : + immediate_(immediate) + {} + + virtual Project* GetRelevantProject() const override { return nullptr; } + +protected: + virtual void prepare() override; + + virtual void redo() override; + + virtual void undo() override; + +private: + NodeInputImmediate *immediate_; + + QObject memory_manager_; + + QVector keys_; + +}; + +} + +#endif // NODEUNDO_H diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 1249e3c13..d99d0178f 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -49,11 +49,7 @@ Track::Track() : ignore_arraymap_(0), arraymap_invalid_(false) { - AddInput(kBlockInput, NodeValue::kNone, InputFlags(kInputFlagArray | kInputFlagNotKeyframable | kInputFlagHidden)); - - // Since blocks are time based, we can handle the invalidate timing a little more intelligently - // on our end - IgnoreInvalidationsFrom(kBlockInput); + AddInput(kBlockInput, NodeValue::kNone, InputFlags(kInputFlagArray | kInputFlagNotKeyframable | kInputFlagHidden | kInputFlagIgnoreConnections)); AddInput(kMutedInput, NodeValue::kBoolean, false, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable)); diff --git a/app/node/param.h b/app/node/param.h index 683d6a2fa..8c8949f20 100644 --- a/app/node/param.h +++ b/app/node/param.h @@ -30,14 +30,16 @@ namespace olive { class Node; class NodeKeyframe; -enum InputFlag { +enum InputFlag : uint64_t { /// By default, inputs are keyframable, connectable, and NOT arrays kInputFlagNormal = 0x0, kInputFlagArray = 0x1, kInputFlagNotKeyframable = 0x2, kInputFlagNotConnectable = 0x4, - kInputFlagStatic = kInputFlagNotKeyframable | kInputFlagNotConnectable, - kInputFlagHidden = 0x8 + kInputFlagHidden = 0x8, + kInputFlagIgnoreConnections = 0x10, + + kInputFlagStatic = kInputFlagNotKeyframable | kInputFlagNotConnectable }; class InputFlags { @@ -59,12 +61,6 @@ public: return i; } - InputFlags &operator|=(const InputFlags &f) - { - f_ |= f.f_; - return *this; - } - InputFlags operator|(const InputFlag &f) const { InputFlags i = *this; @@ -72,12 +68,31 @@ public: return i; } + InputFlags operator|(const uint64_t &f) const + { + InputFlags i = *this; + i |= f; + return i; + } + + InputFlags &operator|=(const InputFlags &f) + { + f_ |= f.f_; + return *this; + } + InputFlags &operator|=(const InputFlag &f) { f_ |= f; return *this; } + InputFlags &operator|=(const uint64_t &f) + { + f_ |= f; + return *this; + } + InputFlags operator&(const InputFlags &f) const { InputFlags i = *this; @@ -85,12 +100,6 @@ public: return i; } - InputFlags &operator&=(const InputFlags &f) - { - f_ &= f.f_; - return *this; - } - InputFlags operator&(const InputFlag &f) const { InputFlags i = *this; @@ -98,12 +107,31 @@ public: return i; } + InputFlags operator&(const uint64_t &f) const + { + InputFlags i = *this; + i &= f; + return i; + } + + InputFlags &operator&=(const InputFlags &f) + { + f_ &= f.f_; + return *this; + } + InputFlags &operator&=(const InputFlag &f) { f_ &= f; return *this; } + InputFlags &operator&=(const uint64_t &f) + { + f_ &= f; + return *this; + } + InputFlags operator~() const { InputFlags i = *this; diff --git a/app/node/project.cpp b/app/node/project.cpp index ecfe73df6..6d3ac0a7e 100644 --- a/app/node/project.cpp +++ b/app/node/project.cpp @@ -48,19 +48,16 @@ Project::Project() : root_ = new Folder(); root_->setParent(this); root_->SetLabel(tr("Root")); - root_->SetCanBeDeleted(false); AddDefaultNode(root_); // Adds a color manager "node" to this project so that it synchronizes color_manager_ = new ColorManager(); color_manager_->setParent(this); - color_manager_->SetCanBeDeleted(false); AddDefaultNode(color_manager_); // Same with project settings settings_ = new ProjectSettingsNode(); settings_->setParent(this); - settings_->SetCanBeDeleted(false); AddDefaultNode(settings_); connect(color_manager(), &ColorManager::ValueChanged, diff --git a/app/node/project/folder/folder.cpp b/app/node/project/folder/folder.cpp index 45f1dacf4..801f6cf7b 100644 --- a/app/node/project/folder/folder.cpp +++ b/app/node/project/folder/folder.cpp @@ -21,10 +21,10 @@ #include "folder.h" #include "common/xmlutils.h" +#include "node/nodeundo.h" #include "node/project/footage/footage.h" #include "node/project/sequence/sequence.h" #include "ui/icons/icons.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { @@ -164,7 +164,7 @@ void Folder::RemoveElementCommand::redo() NodeInput connected_input(folder_, Folder::kChildInput, remove_index_); subcommand_ = new MultiUndoCommand(); subcommand_->add_child(new NodeEdgeRemoveCommand(folder_->GetConnectedOutput(connected_input), connected_input)); - subcommand_->add_child(new Node::ArrayRemoveCommand(folder_, Folder::kChildInput, remove_index_)); + subcommand_->add_child(new NodeArrayRemoveCommand(folder_, Folder::kChildInput, remove_index_)); } } diff --git a/app/node/project/sequence/sequence.cpp b/app/node/project/sequence/sequence.cpp index 76d7d969f..0910e3b6f 100644 --- a/app/node/project/sequence/sequence.cpp +++ b/app/node/project/sequence/sequence.cpp @@ -24,7 +24,7 @@ #include "panel/timeline/timeline.h" #include "ui/icons/icons.h" -#include "widget/timelinewidget/undo/timelineundogeneral.h" +#include "timeline/timelineundogeneral.h" namespace olive { @@ -43,9 +43,7 @@ Sequence::Sequence() // Create track input QString track_input_id = kTrackInputFormat.arg(i); - AddInput(track_input_id, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable | kInputFlagArray | kInputFlagHidden)); - - IgnoreInvalidationsFrom(track_input_id); + AddInput(track_input_id, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable | kInputFlagArray | kInputFlagHidden | kInputFlagIgnoreConnections)); TrackList* list = new TrackList(this, static_cast(i), track_input_id); track_lists_.replace(i, list); diff --git a/app/node/project/serializer/serializer220403.cpp b/app/node/project/serializer/serializer220403.cpp index 226790570..a7f4eced6 100644 --- a/app/node/project/serializer/serializer220403.cpp +++ b/app/node/project/serializer/serializer220403.cpp @@ -681,7 +681,7 @@ void ProjectSerializer220403::PostConnect(const XMLNodeData &xml_node_data) cons l.group->AddInputPassthrough(resolved, l.passthrough_id); - l.group->SetInputFlags(l.passthrough_id, resolved.GetFlags() | l.custom_flags); + l.group->SetInputFlag(l.passthrough_id, InputFlag(l.custom_flags.value())); if (!l.custom_name.isEmpty()) { l.group->SetInputName(l.passthrough_id, l.custom_name); diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index e95dbeb65..db4466329 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -80,8 +80,8 @@ RenderTicketPtr PreviewAutoCacher::GetSingleFrame(Node *n, ViewerOutput *viewer, sfr->Start(); sfr->setProperty("time", QVariant::fromValue(t)); sfr->setProperty("dry", dry); - sfr->setProperty("node", Node::PtrToValue(n)); - sfr->setProperty("viewer", Node::PtrToValue(viewer)); + sfr->setProperty("node", QtUtils::PtrToValue(n)); + sfr->setProperty("viewer", QtUtils::PtrToValue(viewer)); // Queue it and try to render single_frame_render_ = sfr; @@ -159,10 +159,10 @@ void PreviewAutoCacher::AudioRendered() if (running_audio_tasks_.removeOne(watcher)) { // Assume that a "result" is a fully completed image and a non-result is a cancelled ticket TimeRange range = watcher->property("time").value(); - Node *node = copier_->GetOriginal(Node::ValueToPtr(watcher->property("node"))); + Node *node = copier_->GetOriginal(QtUtils::ValueToPtr(watcher->property("node"))); if (watcher->HasResult() && node) { - if (PlaybackCache *cache = Node::ValueToPtr(watcher->property("cache"))) { + if (PlaybackCache *cache = QtUtils::ValueToPtr(watcher->property("cache"))) { AudioCacheData &d = audio_cache_data_[cache]; JobTime watcher_job_time = watcher->property("job").value(); @@ -236,7 +236,7 @@ void PreviewAutoCacher::VideoRendered() // Assume that a "result" is a fully completed image and a non-result is a cancelled ticket if (watcher->HasResult()) { if (watcher->GetTicket()->property("cached").toBool()) { - if (FrameHashCache *cache = Node::ValueToPtr(watcher->property("cache"))) { + if (FrameHashCache *cache = QtUtils::ValueToPtr(watcher->property("cache"))) { rational time = watcher->property("time").value(); JobTime job = watcher->property("job").value(); @@ -490,12 +490,12 @@ void PreviewAutoCacher::TryRender() single_frame_render_ = nullptr; // Check if already caching this - Node *n = Node::ValueToPtr(t->property("node")); + Node *n = QtUtils::ValueToPtr(t->property("node")); Node *copy = copier_->GetCopy(n); if (copy) { RenderTicketWatcher *watcher = RenderFrame(copy, - Node::ValueToPtr(t->property("viewer")), + QtUtils::ValueToPtr(t->property("viewer")), t->property("time").value(), nullptr, t->property("dry").toBool()); @@ -576,7 +576,7 @@ RenderTicketWatcher* PreviewAutoCacher::RenderFrame(Node *node, ViewerOutput *co { RenderTicketWatcher* watcher = new RenderTicketWatcher(); watcher->setProperty("job", QVariant::fromValue(copier_->GetLastUpdateTime())); - watcher->setProperty("cache", Node::PtrToValue(cache)); + watcher->setProperty("cache", QtUtils::PtrToValue(cache)); watcher->setProperty("time", QVariant::fromValue(time)); connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::VideoRendered); @@ -591,6 +591,7 @@ RenderTicketWatcher* PreviewAutoCacher::RenderFrame(Node *node, ViewerOutput *co if (FrameHashCache *frame_cache = dynamic_cast(cache)) { if (ThumbnailCache *wave_cache = dynamic_cast(cache)) { + Q_UNUSED(wave_cache) rvp.video_params.set_divider(VideoParams::GetDividerForTargetResolution(rvp.video_params.width(), rvp.video_params.height(), 160, 120)); rvp.force_color_output = display_color_processor_; rvp.force_format = PixelFormat::U8; @@ -618,8 +619,8 @@ RenderTicketPtr PreviewAutoCacher::RenderAudio(Node *node, ViewerOutput *context { RenderTicketWatcher* watcher = new RenderTicketWatcher(); watcher->setProperty("job", QVariant::fromValue(copier_->GetLastUpdateTime())); - watcher->setProperty("node", Node::PtrToValue(node)); - watcher->setProperty("cache", Node::PtrToValue(cache)); + watcher->setProperty("node", QtUtils::PtrToValue(node)); + watcher->setProperty("cache", QtUtils::PtrToValue(cache)); watcher->setProperty("time", QVariant::fromValue(r)); connect(watcher, &RenderTicketWatcher::Finished, this, &PreviewAutoCacher::AudioRendered); running_audio_tasks_.append(watcher); diff --git a/app/render/rendermanager.cpp b/app/render/rendermanager.cpp index 6c1c136c7..ab91b0280 100644 --- a/app/render/rendermanager.cpp +++ b/app/render/rendermanager.cpp @@ -99,7 +99,7 @@ RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams ¶ms) // Create ticket RenderTicketPtr ticket = std::make_shared(); - ticket->setProperty("node", Node::PtrToValue(params.node)); + ticket->setProperty("node", QtUtils::PtrToValue(params.node)); ticket->setProperty("time", QVariant::fromValue(params.time)); ticket->setProperty("size", params.force_size); ticket->setProperty("matrix", params.force_matrix); @@ -108,7 +108,7 @@ RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams ¶ms) ticket->setProperty("channelcount", params.force_channel_count); ticket->setProperty("mode", params.mode); ticket->setProperty("type", kTypeVideo); - ticket->setProperty("colormanager", Node::PtrToValue(params.color_manager)); + ticket->setProperty("colormanager", QtUtils::PtrToValue(params.color_manager)); ticket->setProperty("coloroutput", QVariant::fromValue(params.force_color_output)); Q_ASSERT(params.video_params.is_valid()); ticket->setProperty("vparam", QVariant::fromValue(params.video_params)); @@ -117,7 +117,7 @@ RenderTicketPtr RenderManager::RenderFrame(const RenderVideoParams ¶ms) ticket->setProperty("cache", params.cache_dir); ticket->setProperty("cachetimebase", QVariant::fromValue(params.cache_timebase)); ticket->setProperty("cacheid", QVariant::fromValue(params.cache_id)); - ticket->setProperty("multicam", Node::PtrToValue(params.multicam)); + ticket->setProperty("multicam", QtUtils::PtrToValue(params.multicam)); if (params.return_type == ReturnType::kNull) { dry_run_thread_->AddTicket(ticket); @@ -133,7 +133,7 @@ RenderTicketPtr RenderManager::RenderAudio(const RenderAudioParams ¶ms) // Create ticket RenderTicketPtr ticket = std::make_shared(); - ticket->setProperty("node", Node::PtrToValue(params.node)); + ticket->setProperty("node", QtUtils::PtrToValue(params.node)); ticket->setProperty("time", QVariant::fromValue(params.range)); ticket->setProperty("type", kTypeAudio); ticket->setProperty("enablewaveforms", params.generate_waveforms); diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index 1df08f60b..05a79b8c8 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -48,7 +48,7 @@ TexturePtr RenderProcessor::GenerateTexture(const rational &time, const rational TimeRange range = TimeRange(time, time + frame_length); NodeValueTable table; - if (Node* node = Node::ValueToPtr(ticket_->property("node"))) { + if (Node* node = QtUtils::ValueToPtr(ticket_->property("node"))) { table = GenerateTable(node, range); } @@ -220,7 +220,7 @@ void RenderProcessor::Run() TimeRange time = ticket_->property("time").value(); NodeValueTable table; - if (Node* node = Node::ValueToPtr(ticket_->property("node"))) { + if (Node* node = QtUtils::ValueToPtr(ticket_->property("node"))) { table = GenerateTable(node, time); } @@ -299,7 +299,7 @@ NodeValueDatabase RenderProcessor::GenerateDatabase(const Node *node, const Time NodeValueDatabase db = super::GenerateDatabase(node, range); if (const MultiCamNode *multicam = dynamic_cast(node)) { - if (Node::ValueToPtr(ticket_->property("multicam")) == multicam) { + if (QtUtils::ValueToPtr(ticket_->property("multicam")) == multicam) { int sz = multicam->GetSourceCount(); QVector multicam_tex(sz); for (int i=0; ivideo_params(); - ColorManager* color_manager = Node::ValueToPtr(ticket_->property("colormanager")); + ColorManager* color_manager = QtUtils::ValueToPtr(ticket_->property("colormanager")); QString using_colorspace = stream_data.colorspace(); @@ -557,7 +557,7 @@ void RenderProcessor::ConvertToReferenceSpace(TexturePtr destination, TexturePtr return; } - ColorManager* color_manager = Node::ValueToPtr(ticket_->property("colormanager")); + ColorManager* color_manager = QtUtils::ValueToPtr(ticket_->property("colormanager")); ColorProcessorPtr cp = ColorProcessor::Create(color_manager, input_cs, color_manager->GetReferenceColorSpace()); ColorTransformJob ctj; diff --git a/app/task/project/import/import.cpp b/app/task/project/import/import.cpp index dc049469a..0c9c1b4fa 100644 --- a/app/task/project/import/import.cpp +++ b/app/task/project/import/import.cpp @@ -25,8 +25,8 @@ #include "config/config.h" #include "core.h" +#include "node/nodeundo.h" #include "node/project/footage/footage.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { diff --git a/app/timeline/CMakeLists.txt b/app/timeline/CMakeLists.txt index f43d93de3..af2d1070f 100644 --- a/app/timeline/CMakeLists.txt +++ b/app/timeline/CMakeLists.txt @@ -1,5 +1,5 @@ # Olive - Non-Linear Video Editor -# Copyright (C) 2022 Olive Team +# Copyright (C) 2023 Olive Studios LLC # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -21,6 +21,17 @@ set(OLIVE_SOURCES timeline/timelinecoordinate.cpp timeline/timelinemarker.h timeline/timelinemarker.cpp + timeline/timelineundocommon.h + timeline/timelineundogeneral.cpp + timeline/timelineundogeneral.h + timeline/timelineundopointer.cpp + timeline/timelineundopointer.h + timeline/timelineundoripple.cpp + timeline/timelineundoripple.h + timeline/timelineundosplit.cpp + timeline/timelineundosplit.h + timeline/timelineundotrack.cpp + timeline/timelineundotrack.h timeline/timelineworkarea.h timeline/timelineworkarea.cpp PARENT_SCOPE diff --git a/app/widget/timelinewidget/undo/timelineundocommon.h b/app/timeline/timelineundocommon.h similarity index 96% rename from app/widget/timelinewidget/undo/timelineundocommon.h rename to app/timeline/timelineundocommon.h index 0dc793240..60f333d91 100644 --- a/app/widget/timelinewidget/undo/timelineundocommon.h +++ b/app/timeline/timelineundocommon.h @@ -22,7 +22,7 @@ #define TIMELINEUNDOCOMMON_H #include "node/node.h" -#include "widget/nodeview/nodeviewundo.h" +#include "node/nodeundo.h" namespace olive { diff --git a/app/widget/timelinewidget/undo/timelineundogeneral.cpp b/app/timeline/timelineundogeneral.cpp similarity index 99% rename from app/widget/timelinewidget/undo/timelineundogeneral.cpp rename to app/timeline/timelineundogeneral.cpp index d46da4fb8..9c18e9cdb 100644 --- a/app/widget/timelinewidget/undo/timelineundogeneral.cpp +++ b/app/timeline/timelineundogeneral.cpp @@ -26,7 +26,7 @@ #include "node/math/math/math.h" #include "node/math/merge/merge.h" #include "timelineundocommon.h" -#include "widget/timelinewidget/undo/timelineundotrack.h" +#include "timelineundotrack.h" namespace olive { diff --git a/app/widget/timelinewidget/undo/timelineundogeneral.h b/app/timeline/timelineundogeneral.h similarity index 100% rename from app/widget/timelinewidget/undo/timelineundogeneral.h rename to app/timeline/timelineundogeneral.h diff --git a/app/widget/timelinewidget/undo/timelineundopointer.cpp b/app/timeline/timelineundopointer.cpp similarity index 100% rename from app/widget/timelinewidget/undo/timelineundopointer.cpp rename to app/timeline/timelineundopointer.cpp diff --git a/app/widget/timelinewidget/undo/timelineundopointer.h b/app/timeline/timelineundopointer.h similarity index 100% rename from app/widget/timelinewidget/undo/timelineundopointer.h rename to app/timeline/timelineundopointer.h diff --git a/app/widget/timelinewidget/undo/timelineundoripple.cpp b/app/timeline/timelineundoripple.cpp similarity index 100% rename from app/widget/timelinewidget/undo/timelineundoripple.cpp rename to app/timeline/timelineundoripple.cpp diff --git a/app/widget/timelinewidget/undo/timelineundoripple.h b/app/timeline/timelineundoripple.h similarity index 100% rename from app/widget/timelinewidget/undo/timelineundoripple.h rename to app/timeline/timelineundoripple.h diff --git a/app/widget/timelinewidget/undo/timelineundosplit.cpp b/app/timeline/timelineundosplit.cpp similarity index 99% rename from app/widget/timelinewidget/undo/timelineundosplit.cpp rename to app/timeline/timelineundosplit.cpp index 8386f6387..a4448e442 100644 --- a/app/widget/timelinewidget/undo/timelineundosplit.cpp +++ b/app/timeline/timelineundosplit.cpp @@ -22,7 +22,7 @@ #include "node/block/clip/clip.h" #include "node/block/transition/transition.h" -#include "widget/nodeview/nodeviewundo.h" +#include "node/nodeundo.h" namespace olive { diff --git a/app/widget/timelinewidget/undo/timelineundosplit.h b/app/timeline/timelineundosplit.h similarity index 100% rename from app/widget/timelinewidget/undo/timelineundosplit.h rename to app/timeline/timelineundosplit.h diff --git a/app/widget/timelinewidget/undo/timelineundotrack.cpp b/app/timeline/timelineundotrack.cpp similarity index 100% rename from app/widget/timelinewidget/undo/timelineundotrack.cpp rename to app/timeline/timelineundotrack.cpp diff --git a/app/widget/timelinewidget/undo/timelineundotrack.h b/app/timeline/timelineundotrack.h similarity index 100% rename from app/widget/timelinewidget/undo/timelineundotrack.h rename to app/timeline/timelineundotrack.h diff --git a/app/widget/timelinewidget/undo/timelineundoworkarea.cpp b/app/timeline/timelineundoworkarea.cpp similarity index 100% rename from app/widget/timelinewidget/undo/timelineundoworkarea.cpp rename to app/timeline/timelineundoworkarea.cpp diff --git a/app/widget/timelinewidget/undo/timelineundoworkarea.h b/app/timeline/timelineundoworkarea.h similarity index 100% rename from app/widget/timelinewidget/undo/timelineundoworkarea.h rename to app/timeline/timelineundoworkarea.h diff --git a/app/widget/curvewidget/curveview.cpp b/app/widget/curvewidget/curveview.cpp index 6f105a22d..df51b25b3 100644 --- a/app/widget/curvewidget/curveview.cpp +++ b/app/widget/curvewidget/curveview.cpp @@ -28,8 +28,8 @@ #include #include "common/qtutils.h" +#include "node/nodeundo.h" #include "widget/keyframeview/keyframeviewundo.h" -#include "widget/nodeparamview/nodeparamviewundo.h" namespace olive { diff --git a/app/widget/keyframeview/keyframeview.cpp b/app/widget/keyframeview/keyframeview.cpp index e2a11ef3b..998e1664b 100644 --- a/app/widget/keyframeview/keyframeview.cpp +++ b/app/widget/keyframeview/keyframeview.cpp @@ -29,10 +29,10 @@ #include "keyframeviewundo.h" #include "node/group/group.h" #include "node/node.h" +#include "node/nodeundo.h" #include "node/project/serializer/serializer.h" #include "widget/menu/menu.h" #include "widget/menu/menushared.h" -#include "widget/nodeparamview/nodeparamviewundo.h" namespace olive { diff --git a/app/widget/multicam/multicamwidget.cpp b/app/widget/multicam/multicamwidget.cpp index a11495339..9487b16f3 100644 --- a/app/widget/multicam/multicamwidget.cpp +++ b/app/widget/multicam/multicamwidget.cpp @@ -19,10 +19,12 @@ ***/ #include "multicamwidget.h" -#include "qshortcut.h" -#include "widget/nodeparamview/nodeparamviewundo.h" + +#include + +#include "node/nodeundo.h" +#include "timeline/timelineundosplit.h" #include "widget/timeruler/timeruler.h" -#include "widget/timelinewidget/undo/timelineundosplit.h" namespace olive { diff --git a/app/widget/nodeparamview/CMakeLists.txt b/app/widget/nodeparamview/CMakeLists.txt index 8a891bf2c..1b80edebc 100644 --- a/app/widget/nodeparamview/CMakeLists.txt +++ b/app/widget/nodeparamview/CMakeLists.txt @@ -36,8 +36,6 @@ set(OLIVE_SOURCES widget/nodeparamview/nodeparamviewkeyframecontrol.h widget/nodeparamview/nodeparamviewtextedit.cpp widget/nodeparamview/nodeparamviewtextedit.h - widget/nodeparamview/nodeparamviewundo.cpp - widget/nodeparamview/nodeparamviewundo.h widget/nodeparamview/nodeparamviewwidgetbridge.cpp widget/nodeparamview/nodeparamviewwidgetbridge.h PARENT_SCOPE diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index da5519964..cf12c44e5 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -26,9 +26,8 @@ #include #include +#include "node/nodeundo.h" #include "node/output/viewer/viewer.h" -#include "widget/nodeparamview/nodeparamviewundo.h" -#include "widget/nodeview/nodeviewundo.h" #include "widget/timeruler/timeruler.h" namespace olive { diff --git a/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp b/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp index a4ba1761a..c523f7912 100644 --- a/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp +++ b/app/widget/nodeparamview/nodeparamviewconnectedlabel.cpp @@ -25,9 +25,9 @@ #include "common/qtutils.h" #include "core.h" #include "node/node.h" +#include "node/nodeundo.h" #include "widget/collapsebutton/collapsebutton.h" #include "widget/menu/menu.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { diff --git a/app/widget/nodeparamview/nodeparamviewcontext.cpp b/app/widget/nodeparamview/nodeparamviewcontext.cpp index d66227044..d4a0adeb5 100644 --- a/app/widget/nodeparamview/nodeparamviewcontext.cpp +++ b/app/widget/nodeparamview/nodeparamviewcontext.cpp @@ -24,7 +24,7 @@ #include "node/block/clip/clip.h" #include "node/factory.h" -#include "widget/nodeview/nodeviewundo.h" +#include "node/nodeundo.h" namespace olive { diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index 5d3f6331e..41d09db57 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -27,8 +27,8 @@ #include "core.h" #include "dialog/speedduration/speeddurationdialog.h" #include "node/group/group.h" +#include "node/nodeundo.h" #include "node/project/sequence/sequence.h" -#include "nodeparamviewundo.h" namespace olive { @@ -444,7 +444,7 @@ void NodeParamViewItemBody::ArrayAppendClicked() for (auto it=array_ui_.cbegin(); it!=array_ui_.cend(); it++) { if (it.value().append_btn == sender()) { NodeInput real_input = NodeGroup::ResolveInput(NodeInput(it.key().node, it.key().input)); - Core::instance()->undo_stack()->push(new Node::ArrayInsertCommand(real_input.node(), real_input.input(), real_input.GetArraySize()+1)); + Core::instance()->undo_stack()->push(new NodeArrayInsertCommand(real_input.node(), real_input.input(), real_input.GetArraySize()+1)); break; } } @@ -456,7 +456,7 @@ void NodeParamViewItemBody::ArrayInsertClicked() if (it.value().array_insert_btn == sender()) { // Found our input and element NodeInput ic = NodeGroup::ResolveInput(it.key()); - Core::instance()->undo_stack()->push(new Node::ArrayInsertCommand(ic.node(), ic.input(), ic.element())); + Core::instance()->undo_stack()->push(new NodeArrayInsertCommand(ic.node(), ic.input(), ic.element())); break; } } @@ -468,7 +468,7 @@ void NodeParamViewItemBody::ArrayRemoveClicked() if (it.value().array_remove_btn == sender()) { // Found our input and element NodeInput ic = NodeGroup::ResolveInput(it.key()); - Core::instance()->undo_stack()->push(new Node::ArrayRemoveCommand(ic.node(), ic.input(), ic.element())); + Core::instance()->undo_stack()->push(new NodeArrayRemoveCommand(ic.node(), ic.input(), ic.element())); break; } } diff --git a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp index cd0c637a5..2dd98aa7a 100644 --- a/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp +++ b/app/widget/nodeparamview/nodeparamviewkeyframecontrol.cpp @@ -24,7 +24,7 @@ #include #include "core.h" -#include "nodeparamviewundo.h" +#include "node/nodeundo.h" #include "ui/icons/icons.h" namespace olive { diff --git a/app/widget/nodeparamview/nodeparamviewundo.cpp b/app/widget/nodeparamview/nodeparamviewundo.cpp deleted file mode 100644 index 81a7d0d8d..000000000 --- a/app/widget/nodeparamview/nodeparamviewundo.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2022 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#include "nodeparamviewundo.h" - -#include "node/node.h" -#include "node/project/sequence/sequence.h" - -namespace olive { - -NodeParamSetKeyframingCommand::NodeParamSetKeyframingCommand(const NodeInput &input, bool setting) : - input_(input), - new_setting_(setting) -{ -} - -Project *NodeParamSetKeyframingCommand::GetRelevantProject() const -{ - return input_.node()->project(); -} - -void NodeParamSetKeyframingCommand::redo() -{ - old_setting_ = input_.IsKeyframing(); - input_.node()->SetInputIsKeyframing(input_, new_setting_); -} - -void NodeParamSetKeyframingCommand::undo() -{ - input_.node()->SetInputIsKeyframing(input_, old_setting_); -} - -NodeParamSetKeyframeValueCommand::NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& value) : - key_(key), - old_value_(key_->value()), - new_value_(value) -{ -} - -NodeParamSetKeyframeValueCommand::NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant &new_value, const QVariant &old_value) : - key_(key), - old_value_(old_value), - new_value_(new_value) -{ - -} - -Project *NodeParamSetKeyframeValueCommand::GetRelevantProject() const -{ - return key_->parent()->project(); -} - -void NodeParamSetKeyframeValueCommand::redo() -{ - key_->set_value(new_value_); -} - -void NodeParamSetKeyframeValueCommand::undo() -{ - key_->set_value(old_value_); -} - -NodeParamInsertKeyframeCommand::NodeParamInsertKeyframeCommand(Node* node, NodeKeyframe* keyframe) : - input_(node), - keyframe_(keyframe) -{ - // Take ownership of the keyframe - undo(); -} - -Project *NodeParamInsertKeyframeCommand::GetRelevantProject() const -{ - return input_->project(); -} - -void NodeParamInsertKeyframeCommand::redo() -{ - keyframe_->setParent(input_); -} - -void NodeParamInsertKeyframeCommand::undo() -{ - keyframe_->setParent(&memory_manager_); -} - -NodeParamRemoveKeyframeCommand::NodeParamRemoveKeyframeCommand(NodeKeyframe* keyframe) : - input_(keyframe->parent()), - keyframe_(keyframe) -{ -} - -Project *NodeParamRemoveKeyframeCommand::GetRelevantProject() const -{ - return input_->project(); -} - -void NodeParamRemoveKeyframeCommand::redo() -{ - // Removes from input - keyframe_->setParent(&memory_manager_); -} - -void NodeParamRemoveKeyframeCommand::undo() -{ - keyframe_->setParent(input_); -} - -NodeParamSetKeyframeTimeCommand::NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational &time) : - key_(key), - old_time_(key->time()), - new_time_(time) -{ -} - -NodeParamSetKeyframeTimeCommand::NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational &new_time, const rational &old_time) : - key_(key), - old_time_(old_time), - new_time_(new_time) -{ -} - -Project *NodeParamSetKeyframeTimeCommand::GetRelevantProject() const -{ - return key_->parent()->project(); -} - -void NodeParamSetKeyframeTimeCommand::redo() -{ - key_->set_time(new_time_); -} - -void NodeParamSetKeyframeTimeCommand::undo() -{ - key_->set_time(old_time_); -} - -NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant &value) : - ref_(input), - old_value_(ref_.input().node()->GetStandardValue(ref_.input())), - new_value_(value) -{ -} - -NodeParamSetStandardValueCommand::NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant &new_value, const QVariant &old_value) : - ref_(input), - old_value_(old_value), - new_value_(new_value) -{ -} - -Project *NodeParamSetStandardValueCommand::GetRelevantProject() const -{ - return ref_.input().node()->project(); -} - -void NodeParamSetStandardValueCommand::redo() -{ - ref_.input().node()->SetSplitStandardValueOnTrack(ref_, new_value_); -} - -void NodeParamSetStandardValueCommand::undo() -{ - ref_.input().node()->SetSplitStandardValueOnTrack(ref_, old_value_); -} - -NodeParamArrayAppendCommand::NodeParamArrayAppendCommand(Node *node, const QString &input) : - node_(node), - input_(input) -{ -} - -Project *NodeParamArrayAppendCommand::GetRelevantProject() const -{ - return node_->project(); -} - -void NodeParamArrayAppendCommand::redo() -{ - node_->InputArrayAppend(input_); -} - -void NodeParamArrayAppendCommand::undo() -{ - node_->InputArrayRemoveLast(input_); -} - -void NodeSetValueHintCommand::redo() -{ - old_hint_ = input_.node()->GetValueHintForInput(input_.input(), input_.element()); - input_.node()->SetValueHintForInput(input_.input(), new_hint_, input_.element()); -} - -void NodeSetValueHintCommand::undo() -{ - input_.node()->SetValueHintForInput(input_.input(), old_hint_, input_.element()); -} - -} diff --git a/app/widget/nodeparamview/nodeparamviewundo.h b/app/widget/nodeparamview/nodeparamviewundo.h deleted file mode 100644 index 90cdce452..000000000 --- a/app/widget/nodeparamview/nodeparamviewundo.h +++ /dev/null @@ -1,239 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2022 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#ifndef NODEPARAMVIEWUNDO_H -#define NODEPARAMVIEWUNDO_H - -#include "node/keyframe.h" -#include "node/node.h" -#include "node/param.h" -#include "undo/undocommand.h" - -namespace olive { - -class NodeParamSetKeyframingCommand : public UndoCommand -{ -public: - NodeParamSetKeyframingCommand(const NodeInput& input, bool setting); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - NodeInput input_; - bool new_setting_; - bool old_setting_; - -}; - -class NodeParamInsertKeyframeCommand : public UndoCommand -{ -public: - NodeParamInsertKeyframeCommand(Node *node, NodeKeyframe* keyframe); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - Node* input_; - - NodeKeyframe* keyframe_; - - QObject memory_manager_; - -}; - -class NodeParamRemoveKeyframeCommand : public UndoCommand -{ -public: - NodeParamRemoveKeyframeCommand(NodeKeyframe* keyframe); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - Node* input_; - - NodeKeyframe* keyframe_; - - QObject memory_manager_; - -}; - -class NodeParamSetKeyframeTimeCommand : public UndoCommand -{ -public: - NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational& time); - NodeParamSetKeyframeTimeCommand(NodeKeyframe* key, const rational& new_time, const rational& old_time); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - NodeKeyframe* key_; - - rational old_time_; - rational new_time_; - -}; - -class NodeParamSetKeyframeValueCommand : public UndoCommand -{ -public: - NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& value); - NodeParamSetKeyframeValueCommand(NodeKeyframe* key, const QVariant& new_value, const QVariant& old_value); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - NodeKeyframe* key_; - - QVariant old_value_; - QVariant new_value_; - -}; - -class NodeParamSetStandardValueCommand : public UndoCommand -{ -public: - NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant& value); - NodeParamSetStandardValueCommand(const NodeKeyframeTrackReference& input, const QVariant& new_value, const QVariant& old_value); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - NodeKeyframeTrackReference ref_; - - QVariant old_value_; - QVariant new_value_; - -}; - -class NodeParamSetSplitStandardValueCommand : public UndoCommand -{ -public: - NodeParamSetSplitStandardValueCommand(const NodeInput& input, const SplitValue& new_value, const SplitValue& old_value) : - ref_(input), - old_value_(old_value), - new_value_(new_value) - {} - - NodeParamSetSplitStandardValueCommand(const NodeInput& input, const SplitValue& value) : - NodeParamSetSplitStandardValueCommand(input, value, input.node()->GetSplitStandardValue(input.input())) - {} - - virtual Project* GetRelevantProject() const override - { - return ref_.node()->project(); - } - -protected: - virtual void redo() override - { - ref_.node()->SetSplitStandardValue(ref_.input(), new_value_, ref_.element()); - } - - virtual void undo() override - { - ref_.node()->SetSplitStandardValue(ref_.input(), old_value_, ref_.element()); - } - -private: - NodeInput ref_; - - SplitValue old_value_; - SplitValue new_value_; - -}; - -class NodeParamArrayAppendCommand : public UndoCommand -{ -public: - NodeParamArrayAppendCommand(Node* node, const QString& input); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - Node* node_; - - QString input_; - -}; - -class NodeSetValueHintCommand : public UndoCommand -{ -public: - NodeSetValueHintCommand(const NodeInput &input, const Node::ValueHint &hint) : - input_(input), - new_hint_(hint) - { - } - - NodeSetValueHintCommand(Node *node, const QString &input, int element, const Node::ValueHint &hint) : - NodeSetValueHintCommand(NodeInput(node, input, element), hint) - { - } - - virtual Project* GetRelevantProject() const override - { - return input_.node()->project(); - } - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - NodeInput input_; - - Node::ValueHint new_hint_; - Node::ValueHint old_hint_; - -}; - -} - -#endif // NODEPARAMVIEWUNDO_H diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index 23b9d59f0..29d55bd23 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -30,10 +30,10 @@ #include "core.h" #include "node/group/group.h" #include "node/node.h" +#include "node/nodeundo.h" #include "node/project/sequence/sequence.h" #include "nodeparamviewarraywidget.h" #include "nodeparamviewtextedit.h" -#include "nodeparamviewundo.h" #include "undo/undostack.h" #include "widget/bezier/bezierwidget.h" #include "widget/colorbutton/colorbutton.h" diff --git a/app/widget/nodetreeview/nodetreeview.cpp b/app/widget/nodetreeview/nodetreeview.cpp index f54757c92..b298bab61 100644 --- a/app/widget/nodetreeview/nodetreeview.cpp +++ b/app/widget/nodetreeview/nodetreeview.cpp @@ -72,7 +72,7 @@ void NodeTreeView::SetNodes(const QVector &nodes) node_item->setCheckState(0, disabled_nodes_.contains(n) ? Qt::Unchecked : Qt::Checked); } node_item->setData(0, kItemType, kItemTypeNode); - node_item->setData(0, kItemNodePointer, Node::PtrToValue(n)); + node_item->setData(0, kItemNodePointer, QtUtils::PtrToValue(n)); foreach (const QString& input, n->inputs()) { if (n->IsInputHidden(input) || (only_show_keyframable_ && !n->IsInputKeyframable(input))) { @@ -158,7 +158,7 @@ NodeKeyframeTrackReference NodeTreeView::GetSelectedInput() if (item->data(0, kItemType).toInt() == kItemTypeInput) { selected_ref = item->data(0, kItemInputReference).value(); } else { - selected_ref = NodeKeyframeTrackReference(NodeInput(Node::ValueToPtr(item->data(0, kItemNodePointer)), QString())); + selected_ref = NodeKeyframeTrackReference(NodeInput(QtUtils::ValueToPtr(item->data(0, kItemNodePointer)), QString())); } } @@ -232,7 +232,7 @@ void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column) switch (item->data(0, kItemType).toInt()) { case kItemTypeNode: { - Node* n = Node::ValueToPtr(item->data(0, kItemNodePointer)); + Node* n = QtUtils::ValueToPtr(item->data(0, kItemNodePointer)); if (item->checkState(0) == Qt::Checked) { if (disabled_nodes_.contains(n)) { diff --git a/app/widget/nodeview/CMakeLists.txt b/app/widget/nodeview/CMakeLists.txt index 6395ae407..184ef1190 100644 --- a/app/widget/nodeview/CMakeLists.txt +++ b/app/widget/nodeview/CMakeLists.txt @@ -33,8 +33,6 @@ set(OLIVE_SOURCES widget/nodeview/nodeviewscene.h widget/nodeview/nodeviewtoolbar.cpp widget/nodeview/nodeviewtoolbar.h - widget/nodeview/nodeviewundo.cpp - widget/nodeview/nodeviewundo.h widget/nodeview/nodewidget.cpp widget/nodeview/nodewidget.h PARENT_SCOPE diff --git a/app/widget/nodeview/nodeview.cpp b/app/widget/nodeview/nodeview.cpp index 97a818fe3..39b1ec791 100644 --- a/app/widget/nodeview/nodeview.cpp +++ b/app/widget/nodeview/nodeview.cpp @@ -28,11 +28,11 @@ #include #include -#include "nodeviewundo.h" #include "node/audio/volume/volume.h" #include "node/distort/transform/transformdistortnode.h" #include "node/factory.h" #include "node/group/group.h" +#include "node/nodeundo.h" #include "node/project/serializer/serializer.h" #include "node/traverser.h" #include "ui/icons/icons.h" diff --git a/app/widget/nodeview/nodeviewcontext.h b/app/widget/nodeview/nodeviewcontext.h index b71aab9b2..3c38e2036 100644 --- a/app/widget/nodeview/nodeviewcontext.h +++ b/app/widget/nodeview/nodeviewcontext.h @@ -5,9 +5,9 @@ #include #include "node/node.h" +#include "node/nodeundo.h" #include "nodeviewcommon.h" #include "nodeviewedge.h" -#include "nodeviewundo.h" namespace olive { diff --git a/app/widget/nodeview/nodeviewitem.cpp b/app/widget/nodeview/nodeviewitem.cpp index d752095f6..09333d27a 100644 --- a/app/widget/nodeview/nodeviewitem.cpp +++ b/app/widget/nodeview/nodeviewitem.cpp @@ -29,9 +29,9 @@ #include "common/qtutils.h" #include "config/config.h" #include "core.h" +#include "node/nodeundo.h" #include "nodeview.h" #include "nodeviewscene.h" -#include "nodeviewundo.h" #include "ui/colorcoding.h" #include "ui/icons/icons.h" #include "window/mainwindow/mainwindow.h" diff --git a/app/widget/nodeview/nodeviewundo.cpp b/app/widget/nodeview/nodeviewundo.cpp deleted file mode 100644 index 6820379ab..000000000 --- a/app/widget/nodeview/nodeviewundo.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2022 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#include "nodeviewundo.h" - -#include "node/project/sequence/sequence.h" - -namespace olive { - -NodeEdgeAddCommand::NodeEdgeAddCommand(Node *output, const NodeInput &input) : - output_(output), - input_(input), - remove_command_(nullptr) -{ -} - -NodeEdgeAddCommand::~NodeEdgeAddCommand() -{ - delete remove_command_; -} - -void NodeEdgeAddCommand::redo() -{ - if (input_.IsConnected()) { - if (!remove_command_) { - remove_command_ = new NodeEdgeRemoveCommand(input_.GetConnectedOutput(), input_); - } - - remove_command_->redo_now(); - } - - Node::ConnectEdge(output_, input_); -} - -void NodeEdgeAddCommand::undo() -{ - Node::DisconnectEdge(output_, input_); - - if (remove_command_) { - remove_command_->undo_now(); - } -} - -Project *NodeEdgeAddCommand::GetRelevantProject() const -{ - return output_->project(); -} - -NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(Node *output, const NodeInput &input) : - output_(output), - input_(input) -{ -} - -void NodeEdgeRemoveCommand::redo() -{ - Node::DisconnectEdge(output_, input_); -} - -void NodeEdgeRemoveCommand::undo() -{ - Node::ConnectEdge(output_, input_); -} - -Project *NodeEdgeRemoveCommand::GetRelevantProject() const -{ - return output_->project(); -} - -NodeAddCommand::NodeAddCommand(Project *graph, Node *node) : - graph_(graph), - node_(node) -{ - // 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::PushToThread(QThread *thread) -{ - memory_manager_.moveToThread(thread); -} - -void NodeAddCommand::redo() -{ - node_->setParent(graph_); -} - -void NodeAddCommand::undo() -{ - node_->setParent(&memory_manager_); -} - -Project *NodeAddCommand::GetRelevantProject() const -{ - return dynamic_cast(graph_); -} - -void NodeRemoveAndDisconnectCommand::prepare() -{ - command_ = new MultiUndoCommand(); - - // If this is a block, remove all links - if (node_->HasLinks()) { - command_->add_child(new NodeUnlinkAllCommand(node_)); - } - - // Disconnect everything - for (auto it=node_->input_connections().cbegin(); it!=node_->input_connections().cend(); it++) { - command_->add_child(new NodeEdgeRemoveCommand(it->second, it->first)); - } - - for (const Node::OutputConnection& conn : node_->output_connections()) { - command_->add_child(new NodeEdgeRemoveCommand(conn.first, conn.second)); - } - - command_->add_child(new NodeRemovePositionFromAllContextsCommand(node_)); -} - -void NodeRenameCommand::AddNode(Node *node, const QString &new_name) -{ - nodes_.append(node); - new_labels_.append(new_name); - old_labels_.append(node->GetLabel()); -} - -void NodeRenameCommand::redo() -{ - for (int i=0; iSetLabel(new_labels_.at(i)); - } -} - -void NodeRenameCommand::undo() -{ - for (int i=0; iSetLabel(old_labels_.at(i)); - } -} - -Project *NodeRenameCommand::GetRelevantProject() const -{ - return nodes_.isEmpty() ? nullptr : nodes_.first()->project(); -} - -NodeOverrideColorCommand::NodeOverrideColorCommand(Node *node, int index) : - node_(node), - new_index_(index) -{ -} - -Project *NodeOverrideColorCommand::GetRelevantProject() const -{ - return node_->project(); -} - -void NodeOverrideColorCommand::redo() -{ - old_index_ = node_->GetOverrideColor(); - node_->SetOverrideColor(new_index_); -} - -void NodeOverrideColorCommand::undo() -{ - node_->SetOverrideColor(old_index_); -} - -NodeViewDeleteCommand::NodeViewDeleteCommand() -{ -} - -void NodeViewDeleteCommand::AddNode(Node *node, Node *context) -{ - if (ContainsNode(node, context)) { - return; - } - - Node::ContextPair p = {node, context}; - nodes_.append(p); - - for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) { - if (context->ContextContainsNode(it->second)) { - AddEdge(it->second, it->first); - } - } - - for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) { - if (context->ContextContainsNode(it->second.node())) { - AddEdge(it->first, it->second); - } - } -} - -void NodeViewDeleteCommand::AddEdge(Node *output, const NodeInput &input) -{ - foreach (const Node::OutputConnection &edge, edges_) { - if (edge.first == output && edge.second == input) { - return; - } - } - - edges_.append({output, input}); -} - -bool NodeViewDeleteCommand::ContainsNode(Node *node, Node *context) -{ - foreach (const Node::ContextPair &pair, nodes_) { - if (pair.node == node && pair.context == context) { - return true; - } - } - - return false; -} - -Project *NodeViewDeleteCommand::GetRelevantProject() const -{ - if (!nodes_.isEmpty()) { - return nodes_.first().node->project(); - } - - if (!edges_.isEmpty()) { - return edges_.first().first->project(); - } - - return nullptr; -} - -void NodeViewDeleteCommand::redo() -{ - foreach (const Node::OutputConnection &edge, edges_) { - Node::DisconnectEdge(edge.first, edge.second); - } - - foreach (const Node::ContextPair &pair, nodes_) { - RemovedNode rn; - - rn.node = pair.node; - rn.context = pair.context; - rn.pos = rn.context->GetNodePositionInContext(rn.node); - - rn.context->RemoveNodeFromContext(rn.node); - - // If node is no longer in any contexts and is not connected to anything, remove it - if (rn.node->parent()->GetNumberOfContextsNodeIsIn(rn.node, true) == 0 - && rn.node->input_connections().empty() - && rn.node->output_connections().empty()) { - rn.removed_from_graph = rn.node->parent(); - rn.node->setParent(&memory_manager_); - } else { - rn.removed_from_graph = nullptr; - } - - removed_nodes_.append(rn); - } -} - -void NodeViewDeleteCommand::undo() -{ - for (auto rn=removed_nodes_.crbegin(); rn!=removed_nodes_.crend(); rn++) { - if (rn->removed_from_graph) { - rn->node->setParent(rn->removed_from_graph); - } - - rn->context->SetNodePositionInContext(rn->node, rn->pos); - } - removed_nodes_.clear(); - - for (auto edge=edges_.crbegin(); edge!=edges_.crend(); edge++) { - Node::ConnectEdge(edge->first, edge->second); - } -} - -} diff --git a/app/widget/nodeview/nodeviewundo.h b/app/widget/nodeview/nodeviewundo.h deleted file mode 100644 index ffa2c174f..000000000 --- a/app/widget/nodeview/nodeviewundo.h +++ /dev/null @@ -1,385 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2022 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#ifndef NODEVIEWUNDO_H -#define NODEVIEWUNDO_H - -#include "node/node.h" -#include "node/project.h" -#include "undo/undocommand.h" - -namespace olive { - -/** - * @brief An undoable command for disconnecting two NodeParams - * - * Can be considered a UndoCommand wrapper for NodeParam::DisonnectEdge()/ - */ -class NodeEdgeRemoveCommand : public UndoCommand { -public: - NodeEdgeRemoveCommand(Node *output, const NodeInput& input); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - Node *output_; - NodeInput input_; - -}; - -/** - * @brief An undoable command for connecting two NodeParams together - * - * Can be considered a UndoCommand wrapper for NodeParam::ConnectEdge()/ - */ -class NodeEdgeAddCommand : public UndoCommand { -public: - NodeEdgeAddCommand(Node *output, const NodeInput& input); - - virtual ~NodeEdgeAddCommand() override; - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - Node *output_; - NodeInput input_; - - NodeEdgeRemoveCommand* remove_command_; - -}; - -class NodeAddCommand : public UndoCommand { -public: - NodeAddCommand(Project* graph, Node* node); - - void PushToThread(QThread* thread); - - virtual Project* GetRelevantProject() const override; - -protected: - virtual void redo() override; - virtual void undo() override; - -private: - QObject memory_manager_; - - Project* graph_; - Node* node_; -}; - -class NodeRemoveAndDisconnectCommand : public UndoCommand { -public: - NodeRemoveAndDisconnectCommand(Node* node) : - node_(node), - graph_(nullptr), - command_(nullptr) - { - } - - virtual ~NodeRemoveAndDisconnectCommand() override - { - delete command_; - } - - virtual Project* GetRelevantProject() const override - { - return graph_; - } - -protected: - virtual void prepare() override; - - virtual void redo() override - { - command_->redo_now(); - - graph_ = node_->parent(); - node_->setParent(&memory_manager_); - } - - virtual void undo() override - { - node_->setParent(graph_); - graph_ = nullptr; - - command_->undo_now(); - } - -private: - QObject memory_manager_; - - Node* node_; - Project* graph_; - - MultiUndoCommand* command_; - -}; - -class NodeRemoveWithExclusiveDependenciesAndDisconnect : public UndoCommand { -public: - NodeRemoveWithExclusiveDependenciesAndDisconnect(Node* node) : - node_(node), - command_(nullptr) - { - } - - virtual ~NodeRemoveWithExclusiveDependenciesAndDisconnect() override - { - delete command_; - } - - virtual Project* GetRelevantProject() const override - { - if (command_) { - return static_cast(command_->child(0))->GetRelevantProject(); - } else { - return node_->project(); - } - } - -protected: - virtual void prepare() override - { - command_ = new MultiUndoCommand(); - - command_->add_child(new NodeRemoveAndDisconnectCommand(node_)); - - // Remove exclusive dependencies - QVector deps = node_->GetExclusiveDependencies(); - foreach (Node* d, deps) { - command_->add_child(new NodeRemoveAndDisconnectCommand(d)); - } - } - - virtual void redo() override - { - command_->redo_now(); - } - - virtual void undo() override - { - command_->undo_now(); - } - -private: - Node* node_; - MultiUndoCommand* command_; - -}; - -class NodeLinkCommand : public UndoCommand { -public: - NodeLinkCommand(Node* a, Node* b, bool link) : - a_(a), - b_(b), - link_(link) - { - } - - virtual Project* GetRelevantProject() const override - { - return a_->project(); - } - -protected: - virtual void redo() override - { - if (link_) { - done_ = Node::Link(a_, b_); - } else { - done_ = Node::Unlink(a_, b_); - } - } - - virtual void undo() override - { - if (done_) { - if (link_) { - Node::Unlink(a_, b_); - } else { - Node::Link(a_, b_); - } - } - } - -private: - Node* a_; - Node* b_; - bool link_; - bool done_; - -}; - -class NodeUnlinkAllCommand : public UndoCommand { -public: - NodeUnlinkAllCommand(Node* node) : - node_(node) - { - } - - virtual Project* GetRelevantProject() const override - { - return node_->project(); - } - -protected: - virtual void redo() override - { - unlinked_ = node_->links(); - - foreach (Node* link, unlinked_) { - Node::Unlink(node_, link); - } - } - - virtual void undo() override - { - foreach (Node* link, unlinked_) { - Node::Link(node_, link); - } - - unlinked_.clear(); - } - -private: - Node* node_; - - QVector unlinked_; - -}; - -class NodeLinkManyCommand : public MultiUndoCommand { -public: - NodeLinkManyCommand(const QVector nodes, bool link) : - nodes_(nodes) - { - foreach (Node* a, nodes_) { - foreach (Node* b, nodes_) { - if (a != b) { - add_child(new NodeLinkCommand(a, b, link)); - } - } - } - } - - virtual Project* GetRelevantProject() const override - { - return nodes_.first()->project(); - } - -private: - QVector nodes_; - -}; - -class NodeRenameCommand : public UndoCommand -{ -public: - NodeRenameCommand() = default; - NodeRenameCommand(Node* node, const QString& new_name) - { - AddNode(node, new_name); - } - - void AddNode(Node* node, const QString& new_name); - - virtual Project * GetRelevantProject() const override; - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - QVector nodes_; - - QStringList new_labels_; - QStringList old_labels_; - -}; - -class NodeOverrideColorCommand : public UndoCommand -{ -public: - NodeOverrideColorCommand(Node *node, int index); - - virtual Project * GetRelevantProject() const override; - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - Node *node_; - - int old_index_; - - int new_index_; - -}; - -class NodeViewDeleteCommand : public UndoCommand -{ -public: - NodeViewDeleteCommand(); - - void AddNode(Node *node, Node *context); - - void AddEdge(Node *output, const NodeInput &input); - - bool ContainsNode(Node *node, Node *context); - - virtual Project * GetRelevantProject() const override; - -protected: - virtual void redo() override; - - virtual void undo() override; - -private: - QVector nodes_; - - QVector edges_; - - struct RemovedNode { - Node *node; - Node *context; - QPointF pos; - Project *removed_from_graph; - }; - - QVector removed_nodes_; - - QObject memory_manager_; - -}; - -} - -#endif // NODEVIEWUNDO_H diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 88c458e79..70a95f874 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -38,11 +38,9 @@ #include "task/taskmanager.h" #include "widget/menu/menu.h" #include "widget/menu/menushared.h" -#include "widget/nodeparamview/nodeparamviewundo.h" -#include "widget/nodeview/nodeviewundo.h" +#include "node/nodeundo.h" #include "window/mainwindow/mainwindow.h" #include "window/mainwindow/mainwindowundo.h" -#include "widget/nodeview/nodeviewundo.h" #include "widget/timelinewidget/timelinewidget.h" namespace olive { @@ -396,7 +394,7 @@ void ProjectExplorer::ShowContextMenu() } else { foreach (Sequence* i, sequences) { QAction* a = proxy_menu->addAction(tr("For \"%1\"").arg(i->GetLabel())); - a->setData(Node::PtrToValue(i)); + a->setData(QtUtils::PtrToValue(i)); } connect(proxy_menu, &Menu::triggered, this, &ProjectExplorer::ContextMenuStartProxy); @@ -505,7 +503,7 @@ void ProjectExplorer::OpenContextMenuItemInNewWindow() void ProjectExplorer::ContextMenuStartProxy(QAction *a) { - Sequence* sequence = Node::ValueToPtr(a->data()); + Sequence* sequence = QtUtils::ValueToPtr(a->data()); // To get here, the `context_menu_items_` must be all kFootage foreach (Node* item, context_menu_items_) { diff --git a/app/widget/projectexplorer/projectviewmodel.cpp b/app/widget/projectexplorer/projectviewmodel.cpp index 550d3f972..28223f586 100644 --- a/app/widget/projectexplorer/projectviewmodel.cpp +++ b/app/widget/projectexplorer/projectviewmodel.cpp @@ -26,8 +26,7 @@ #include "common/qtutils.h" #include "core.h" -#include "widget/nodeview/nodeviewundo.h" -#include "widget/nodeparamview/nodeparamviewundo.h" +#include "node/nodeundo.h" namespace olive { diff --git a/app/widget/timebased/timebasedwidget.cpp b/app/widget/timebased/timebasedwidget.cpp index 2673792e1..20fcb3734 100644 --- a/app/widget/timebased/timebasedwidget.cpp +++ b/app/widget/timebased/timebasedwidget.cpp @@ -28,8 +28,8 @@ #include "core.h" #include "dialog/markerproperties/markerpropertiesdialog.h" #include "node/project/sequence/sequence.h" +#include "timeline/timelineundoworkarea.h" #include "widget/timeruler/timeruler.h" -#include "widget/timelinewidget/undo/timelineundoworkarea.h" namespace olive { diff --git a/app/widget/timelinewidget/CMakeLists.txt b/app/widget/timelinewidget/CMakeLists.txt index c3cd173bc..44f5392c1 100644 --- a/app/widget/timelinewidget/CMakeLists.txt +++ b/app/widget/timelinewidget/CMakeLists.txt @@ -16,7 +16,6 @@ add_subdirectory(trackview) add_subdirectory(tool) -add_subdirectory(undo) add_subdirectory(view) set(OLIVE_SOURCES diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index a65e8606c..23bc574d7 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -30,8 +30,13 @@ #include "dialog/sequence/sequence.h" #include "dialog/speedduration/speeddurationdialog.h" #include "node/block/transition/transition.h" +#include "node/nodeundo.h" #include "node/project/serializer/serializer.h" #include "task/project/import/import.h" +#include "timeline/timelineundogeneral.h" +#include "timeline/timelineundopointer.h" +#include "timeline/timelineundoripple.h" +#include "timeline/timelineundoworkarea.h" #include "tool/add.h" #include "tool/beam.h" #include "tool/edit.h" @@ -47,15 +52,9 @@ #include "tool/zoom.h" #include "tool/tool.h" #include "trackview/trackview.h" -#include "undo/timelineundogeneral.h" -#include "undo/timelineundopointer.h" -#include "undo/timelineundoripple.h" -#include "undo/timelineundoworkarea.h" #include "widget/menu/menu.h" #include "widget/menu/menushared.h" -#include "widget/nodeparamview/nodeparamviewundo.h" #include "widget/nodeparamview/nodeparamview.h" -#include "widget/nodeview/nodeviewundo.h" #include "widget/timeruler/timeruler.h" namespace olive { diff --git a/app/widget/timelinewidget/tool/add.cpp b/app/widget/timelinewidget/tool/add.cpp index f587a775b..b3fbc8a14 100644 --- a/app/widget/timelinewidget/tool/add.cpp +++ b/app/widget/timelinewidget/tool/add.cpp @@ -25,9 +25,9 @@ #include "node/generator/shape/shapenode.h" #include "node/generator/solid/solid.h" #include "node/generator/text/textv3.h" -#include "widget/nodeparamview/nodeparamviewundo.h" +#include "node/nodeundo.h" +#include "timeline/timelineundopointer.h" #include "widget/timelinewidget/timelinewidget.h" -#include "widget/timelinewidget/undo/timelineundopointer.h" namespace olive { diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index 1ce71f427..ae42257da 100644 --- a/app/widget/timelinewidget/tool/import.cpp +++ b/app/widget/timelinewidget/tool/import.cpp @@ -34,10 +34,9 @@ #include "node/distort/transform/transformdistortnode.h" #include "node/generator/matrix/matrix.h" #include "node/math/math/math.h" +#include "node/nodeundo.h" #include "node/project/sequence/sequence.h" -#include "widget/nodeparamview/nodeparamviewundo.h" -#include "widget/nodeview/nodeviewundo.h" -#include "widget/timelinewidget/undo/timelineundopointer.h" +#include "timeline/timelineundopointer.h" #include "window/mainwindow/mainwindow.h" #include "window/mainwindow/mainwindowundo.h" diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index 0cd3ddfd0..6c2296ab8 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -29,9 +29,9 @@ #include "core.h" #include "node/block/gap/gap.h" #include "node/block/transition/transition.h" +#include "node/nodeundo.h" #include "pointer.h" -#include "widget/nodeview/nodeviewundo.h" -#include "widget/timelinewidget/undo/timelineundopointer.h" +#include "timeline/timelineundopointer.h" #include "widget/timeruler/timeruler.h" namespace olive { @@ -615,7 +615,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event) // Sort ghosts depending on which ones are trimming, which are moving, and which are sliding foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) { if (ghost->HasBeenAdjusted()) { - Block* b = Node::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); + Block* b = QtUtils::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); if (ghost->GetData(TimelineViewGhostItem::kGhostIsSliding).toBool()) { blocks_sliding.append({ghost, b}); @@ -829,7 +829,7 @@ void PointerTool::InitiateDrag(Block *clicked_item, Timeline::MovementMode trim_ TimelineViewGhostItem *PointerTool::GetExistingGhostFromBlock(Block *block) { foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) { - if (Node::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)) == block) { + if (QtUtils::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)) == block) { return ghost; } } diff --git a/app/widget/timelinewidget/tool/razor.cpp b/app/widget/timelinewidget/tool/razor.cpp index 76b8c720f..d2068fc0b 100644 --- a/app/widget/timelinewidget/tool/razor.cpp +++ b/app/widget/timelinewidget/tool/razor.cpp @@ -19,8 +19,10 @@ ***/ #include "razor.h" + +#include "node/nodeundo.h" +#include "timeline/timelineundosplit.h" #include "widget/timelinewidget/timelinewidget.h" -#include "widget/timelinewidget/undo/timelineundosplit.h" namespace olive { diff --git a/app/widget/timelinewidget/tool/ripple.cpp b/app/widget/timelinewidget/tool/ripple.cpp index 0e1a75008..35ad7184e 100644 --- a/app/widget/timelinewidget/tool/ripple.cpp +++ b/app/widget/timelinewidget/tool/ripple.cpp @@ -21,9 +21,8 @@ #include "widget/timelinewidget/timelinewidget.h" #include "node/block/gap/gap.h" +#include "timeline/timelineundoripple.h" #include "ripple.h" -#include "widget/nodeview/nodeviewundo.h" -#include "widget/timelinewidget/undo/timelineundoripple.h" namespace olive { @@ -105,7 +104,7 @@ void RippleTool::InitiateDrag(Block *clicked_item, Timeline::MovementMode trim_m } else { // Previous is not a gap, we'll have to insert one there ourselves ghost = AddGhostFromNull(block_after_ripple->in(), block_after_ripple->in(), track->ToReference(), trim_mode); - ghost->SetData(TimelineViewGhostItem::kReferenceBlock, Node::PtrToValue(block_after_ripple)); + ghost->SetData(TimelineViewGhostItem::kReferenceBlock, QtUtils::PtrToValue(block_after_ripple)); } } } @@ -128,13 +127,13 @@ void RippleTool::FinishDrag(TimelineViewMouseEvent *event) Track* track = parent()->GetTrackFromReference(ghost->GetTrack()); TrackListRippleToolCommand::RippleInfo info; - Block* b = Node::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); + Block* b = QtUtils::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); if (b) { info.block = b; info.append_gap = false; } else { - info.block = Node::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kReferenceBlock)); + info.block = QtUtils::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kReferenceBlock)); info.append_gap = true; } diff --git a/app/widget/timelinewidget/tool/rolling.cpp b/app/widget/timelinewidget/tool/rolling.cpp index 12688f684..71c6f6443 100644 --- a/app/widget/timelinewidget/tool/rolling.cpp +++ b/app/widget/timelinewidget/tool/rolling.cpp @@ -21,8 +21,8 @@ #include "widget/timelinewidget/timelinewidget.h" #include "node/block/gap/gap.h" +#include "node/nodeundo.h" #include "rolling.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { diff --git a/app/widget/timelinewidget/tool/slide.cpp b/app/widget/timelinewidget/tool/slide.cpp index 5bdc61889..4bb85af51 100644 --- a/app/widget/timelinewidget/tool/slide.cpp +++ b/app/widget/timelinewidget/tool/slide.cpp @@ -21,8 +21,8 @@ #include "widget/timelinewidget/timelinewidget.h" #include "node/block/gap/gap.h" +#include "node/nodeundo.h" #include "slide.h" -#include "widget/nodeview/nodeviewundo.h" namespace olive { diff --git a/app/widget/timelinewidget/tool/slip.cpp b/app/widget/timelinewidget/tool/slip.cpp index 94337928f..af267eae4 100644 --- a/app/widget/timelinewidget/tool/slip.cpp +++ b/app/widget/timelinewidget/tool/slip.cpp @@ -18,13 +18,13 @@ ***/ -#include "widget/timelinewidget/timelinewidget.h" +#include "slip.h" #include #include "config/config.h" -#include "slip.h" -#include "widget/timelinewidget/undo/timelineundogeneral.h" +#include "timeline/timelineundogeneral.h" +#include "widget/timelinewidget/timelinewidget.h" namespace olive { @@ -72,7 +72,7 @@ void SlipTool::FinishDrag(TimelineViewMouseEvent *event) // Find earliest point to ripple around foreach (TimelineViewGhostItem* ghost, parent()->GetGhostItems()) { - Block* b = Node::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); + Block* b = QtUtils::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); ClipBlock *cb = dynamic_cast(b); if (cb) { diff --git a/app/widget/timelinewidget/tool/tool.h b/app/widget/timelinewidget/tool/tool.h index 450e39060..424a6f184 100644 --- a/app/widget/timelinewidget/tool/tool.h +++ b/app/widget/timelinewidget/tool/tool.h @@ -23,7 +23,6 @@ #include -#include "widget/nodeview/nodeviewundo.h" #include "widget/timelinewidget/view/timelineviewghostitem.h" #include "widget/timelinewidget/view/timelineviewmouseevent.h" diff --git a/app/widget/timelinewidget/tool/transition.cpp b/app/widget/timelinewidget/tool/transition.cpp index 52675028e..314ca5bee 100644 --- a/app/widget/timelinewidget/tool/transition.cpp +++ b/app/widget/timelinewidget/tool/transition.cpp @@ -23,9 +23,9 @@ #include "node/block/transition/crossdissolve/crossdissolvetransition.h" #include "node/block/transition/transition.h" #include "node/factory.h" +#include "node/nodeundo.h" +#include "timeline/timelineundopointer.h" #include "transition.h" -#include "widget/nodeview/nodeviewundo.h" -#include "widget/timelinewidget/undo/timelineundopointer.h" namespace olive { @@ -65,11 +65,11 @@ void TransitionTool::MousePress(TimelineViewMouseEvent *event) ghost_->SetIn(transition_start_point); ghost_->SetOut(transition_start_point); ghost_->SetMode(trim_mode); - ghost_->SetData(TimelineViewGhostItem::kAttachedBlock, Node::PtrToValue(primary)); + ghost_->SetData(TimelineViewGhostItem::kAttachedBlock, QtUtils::PtrToValue(primary)); dual_transition_ = (secondary); if (secondary) - ghost_->SetData(TimelineViewGhostItem::kReferenceBlock, Node::PtrToValue(secondary)); + ghost_->SetData(TimelineViewGhostItem::kReferenceBlock, QtUtils::PtrToValue(secondary)); parent()->AddGhost(ghost_); @@ -122,10 +122,10 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event) if (dual_transition_) { // Block mouse is hovering over - Block* active_block = Node::ValueToPtr(ghost_->GetData(TimelineViewGhostItem::kAttachedBlock)); + Block* active_block = QtUtils::ValueToPtr(ghost_->GetData(TimelineViewGhostItem::kAttachedBlock)); // Block mouse is next to - Block* friend_block = Node::ValueToPtr(ghost_->GetData(TimelineViewGhostItem::kReferenceBlock)); + Block* friend_block = QtUtils::ValueToPtr(ghost_->GetData(TimelineViewGhostItem::kReferenceBlock)); // Use ghost mode to determine which block is which Block* out_block = (ghost_->GetMode() == Timeline::kTrimIn) ? friend_block : active_block; @@ -141,7 +141,7 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event) command->add_child(new NodeSetPositionCommand(out_block, transition, QPointF(-1, -0.5))); command->add_child(new NodeSetPositionCommand(in_block, transition, QPointF(-1, 0.5))); } else { - Block* block_to_transition = Node::ValueToPtr(ghost_->GetData(TimelineViewGhostItem::kAttachedBlock)); + Block* block_to_transition = QtUtils::ValueToPtr(ghost_->GetData(TimelineViewGhostItem::kAttachedBlock)); QString transition_input_to_connect; if (ghost_->GetMode() == Timeline::kTrimIn) { diff --git a/app/widget/timelinewidget/trackview/trackviewitem.cpp b/app/widget/timelinewidget/trackview/trackviewitem.cpp index e0b1eab5d..9f6a7f808 100644 --- a/app/widget/timelinewidget/trackview/trackviewitem.cpp +++ b/app/widget/timelinewidget/trackview/trackviewitem.cpp @@ -28,9 +28,9 @@ #include #include "core.h" +#include "timeline/timelineundogeneral.h" #include "ui/icons/icons.h" #include "widget/menu/menu.h" -#include "widget/timelinewidget/undo/timelineundogeneral.h" namespace olive { diff --git a/app/widget/timelinewidget/undo/CMakeLists.txt b/app/widget/timelinewidget/undo/CMakeLists.txt deleted file mode 100644 index e93f6ed50..000000000 --- a/app/widget/timelinewidget/undo/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# Olive - Non-Linear Video Editor -# Copyright (C) 2022 Olive Team -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/timelinewidget/undo/timelineundocommon.h - widget/timelinewidget/undo/timelineundogeneral.cpp - widget/timelinewidget/undo/timelineundogeneral.h - widget/timelinewidget/undo/timelineundopointer.cpp - widget/timelinewidget/undo/timelineundopointer.h - widget/timelinewidget/undo/timelineundoripple.cpp - widget/timelinewidget/undo/timelineundoripple.h - widget/timelinewidget/undo/timelineundosplit.cpp - widget/timelinewidget/undo/timelineundosplit.h - widget/timelinewidget/undo/timelineundotrack.cpp - widget/timelinewidget/undo/timelineundotrack.h - widget/timelinewidget/undo/timelineundoworkarea.cpp - widget/timelinewidget/undo/timelineundoworkarea.h - PARENT_SCOPE -) diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 2062b1c2e..d5b6e77b1 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -242,7 +242,7 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect) && !ghost->IsInvisible()) { int track_index = ghost->GetAdjustedTrack().index(); - Block *attached = Node::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); + Block *attached = QtUtils::ValueToPtr(ghost->GetData(TimelineViewGhostItem::kAttachedBlock)); if (attached && OLIVE_CONFIG("ShowClipWhileDragging").toBool()) { int adj_track = ghost->GetAdjustedTrack().index(); diff --git a/app/widget/timelinewidget/view/timelineviewghostitem.h b/app/widget/timelinewidget/view/timelineviewghostitem.h index 16a3c0e8a..40a936ab4 100644 --- a/app/widget/timelinewidget/view/timelineviewghostitem.h +++ b/app/widget/timelinewidget/view/timelineviewghostitem.h @@ -69,7 +69,7 @@ public: ghost->SetMediaIn(static_cast(block)->media_in()); } ghost->SetTrack(block->track()->ToReference()); - ghost->SetData(kAttachedBlock, Node::PtrToValue(block)); + ghost->SetData(kAttachedBlock, QtUtils::PtrToValue(block)); if (dynamic_cast(block)) { ghost->can_have_zero_length_ = false; diff --git a/app/widget/timeruler/seekablewidget.cpp b/app/widget/timeruler/seekablewidget.cpp index d40015680..6fb2a5765 100644 --- a/app/widget/timeruler/seekablewidget.cpp +++ b/app/widget/timeruler/seekablewidget.cpp @@ -30,10 +30,10 @@ #include "core.h" #include "dialog/markerproperties/markerpropertiesdialog.h" #include "node/project/serializer/serializer.h" +#include "timeline/timelineundoworkarea.h" #include "widget/colorlabelmenu/colorlabelmenu.h" #include "widget/menu/menushared.h" #include "widget/timebased/timebasedwidget.h" -#include "widget/timelinewidget/undo/timelineundoworkarea.h" namespace olive { diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 438625b6b..791e0454a 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -37,6 +37,7 @@ #include "core.h" #include "node/block/gap/gap.h" #include "node/generator/shape/shapenodebase.h" +#include "node/nodeundo.h" #include "node/project.h" #include "panel/multicam/multicampanel.h" #include "panel/panelmanager.h" @@ -45,7 +46,6 @@ #include "widget/audiomonitor/audiomonitor.h" #include "widget/menu/menu.h" #include "widget/multicam/multicamdisplay.h" -#include "widget/nodeparamview/nodeparamviewundo.h" #include "widget/timelinewidget/tool/add.h" #include "widget/timeruler/timeruler.h" diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index e12a8ebe0..dffa65302 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -32,7 +32,7 @@ #include "dialog/about/about.h" #include "mainmenu.h" #include "mainstatusbar.h" -#include "widget/timelinewidget/undo/timelineundoworkarea.h" +#include "timeline/timelineundoworkarea.h" namespace olive {