diff --git a/app/codec/decoder.cpp b/app/codec/decoder.cpp index f405d27de..185a964bb 100644 --- a/app/codec/decoder.cpp +++ b/app/codec/decoder.cpp @@ -30,7 +30,7 @@ #include "common/ffmpegutils.h" #include "common/filefunctions.h" #include "conformmanager.h" -#include "node/project/project.h" +#include "node/project.h" #include "task/taskmanager.h" namespace olive { 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/core.h b/app/core.h index b32993c09..10018e7ba 100644 --- a/app/core.h +++ b/app/core.h @@ -28,12 +28,12 @@ #include #include "node/project/footage/footage.h" -#include "node/project/project.h" -#include "node/project/projectviewmodel.h" +#include "node/project.h" #include "node/project/sequence/sequence.h" #include "task/task.h" #include "tool/tool.h" #include "undo/undostack.h" +#include "widget/projectexplorer/projectviewmodel.h" namespace olive { diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index 5bdeeaec9..c5cfa2a17 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -34,7 +34,7 @@ #include "common/qtutils.h" #include "dialog/task/task.h" #include "exportsavepresetdialog.h" -#include "node/project/project.h" +#include "node/project.h" #include "node/project/sequence/sequence.h" #include "task/taskmanager.h" #include "ui/icons/icons.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/footagerelink/footagerelinkdialog.cpp b/app/dialog/footagerelink/footagerelinkdialog.cpp index 066c163e6..a608a049c 100644 --- a/app/dialog/footagerelink/footagerelinkdialog.cpp +++ b/app/dialog/footagerelink/footagerelinkdialog.cpp @@ -64,7 +64,7 @@ FootageRelinkDialog::FootageRelinkDialog(const QVector &footage, QWid connect(item_browse_btn, &QPushButton::clicked, this, &FootageRelinkDialog::BrowseForFootage); item_actions_layout->addWidget(item_browse_btn); - item->setIcon(0, f->icon()); + item->setIcon(0, f->data(Node::ICON).value()); item->setText(0, f->GetLabel()); item->setText(1, f->filename()); @@ -89,7 +89,7 @@ void FootageRelinkDialog::UpdateFootageItem(int index) { Footage* f = footage_.at(index); QTreeWidgetItem* item = table_->topLevelItem(index); - item->setIcon(0, f->icon()); + item->setIcon(0, f->data(Node::ICON).value()); item->setText(1, f->filename()); } 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/projectproperties/projectproperties.h b/app/dialog/projectproperties/projectproperties.h index e6963e541..ed0bbf786 100644 --- a/app/dialog/projectproperties/projectproperties.h +++ b/app/dialog/projectproperties/projectproperties.h @@ -28,7 +28,7 @@ #include #include -#include "node/project/project.h" +#include "node/project.h" #include "widget/path/pathwidget.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 c21485b88..ef1978c21 100644 --- a/app/node/CMakeLists.txt +++ b/app/node/CMakeLists.txt @@ -36,8 +36,6 @@ set(OLIVE_SOURCES node/factory.h node/globals.cpp node/globals.h - node/graph.cpp - node/graph.h node/inputdragger.cpp node/inputdragger.h node/inputimmediate.cpp @@ -46,8 +44,12 @@ 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 + node/project.h node/splitvalue.h node/traverser.cpp node/traverser.h diff --git a/app/node/audio/pan/pan.cpp b/app/node/audio/pan/pan.cpp index 434480dd9..5f4ecebf1 100644 --- a/app/node/audio/pan/pan.cpp +++ b/app/node/audio/pan/pan.cpp @@ -38,7 +38,7 @@ PanNode::PanNode() SetInputProperty(kPanningInput, QStringLiteral("max"), 1.0); SetInputProperty(kPanningInput, QStringLiteral("view"), FloatSlider::kPercentage); - SetFlags(kAudioEffect); + SetFlag(kAudioEffect); SetEffectInput(kSamplesInput); } diff --git a/app/node/audio/volume/volume.cpp b/app/node/audio/volume/volume.cpp index 7fe0a888a..229295d98 100644 --- a/app/node/audio/volume/volume.cpp +++ b/app/node/audio/volume/volume.cpp @@ -37,7 +37,7 @@ VolumeNode::VolumeNode() SetInputProperty(kVolumeInput, QStringLiteral("min"), 0.0); SetInputProperty(kVolumeInput, QStringLiteral("view"), FloatSlider::kDecibel); - SetFlags(kAudioEffect); + SetFlag(kAudioEffect); SetEffectInput(kSamplesInput); } diff --git a/app/node/block/block.cpp b/app/node/block/block.cpp index fb030e5b5..18e279654 100644 --- a/app/node/block/block.cpp +++ b/app/node/block/block.cpp @@ -44,9 +44,10 @@ 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); - SetFlags(kDontShowInParamView); + SetFlag(kDontShowInParamView); } QVector Block::Category() const diff --git a/app/node/block/subtitle/subtitle.cpp b/app/node/block/subtitle/subtitle.cpp index 25bccb6f4..b645a1595 100644 --- a/app/node/block/subtitle/subtitle.cpp +++ b/app/node/block/subtitle/subtitle.cpp @@ -30,15 +30,15 @@ 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 - SetFlags(GetFlags() & ~kDontShowInParamView); + SetFlag(kDontShowInParamView, false); } QString SubtitleBlock::Name() const diff --git a/app/node/block/transition/transition.cpp b/app/node/block/transition/transition.cpp index 327f3fc1c..9209a1400 100644 --- a/app/node/block/transition/transition.cpp +++ b/app/node/block/transition/transition.cpp @@ -47,7 +47,7 @@ TransitionBlock::TransitionBlock() : SetInputProperty(kCenterInput, QStringLiteral("view"), RationalSlider::kTime); SetInputProperty(kCenterInput, QStringLiteral("viewlock"), true); - SetFlags(GetFlags() & ~kDontShowInParamView); + SetFlag(kDontShowInParamView, false); } void TransitionBlock::Retranslate() diff --git a/app/node/color/ociobase/ociobase.cpp b/app/node/color/ociobase/ociobase.cpp index 498596b68..f749922ca 100644 --- a/app/node/color/ociobase/ociobase.cpp +++ b/app/node/color/ociobase/ociobase.cpp @@ -21,7 +21,7 @@ #include "ociobase.h" #include "node/color/colormanager/colormanager.h" -#include "node/project/project.h" +#include "node/project.h" namespace olive { @@ -38,16 +38,14 @@ OCIOBaseNode::OCIOBaseNode() : connect(this, &Node::AddedToGraph, this, &OCIOBaseNode::AddedToGraph); connect(this, &Node::RemovedFromGraph, this, &OCIOBaseNode::RemovedFromGraph); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); } -void OCIOBaseNode::AddedToGraph(NodeGraph *graph) +void OCIOBaseNode::AddedToGraph(Project *p) { - if (Project *p = dynamic_cast(graph)) { - manager_ = p->color_manager(); - connect(manager_, &ColorManager::ConfigChanged, this, &OCIOBaseNode::ConfigChanged); - ConfigChanged(); - } + manager_ = p->color_manager(); + connect(manager_, &ColorManager::ConfigChanged, this, &OCIOBaseNode::ConfigChanged); + ConfigChanged(); } void OCIOBaseNode::RemovedFromGraph() diff --git a/app/node/color/ociobase/ociobase.h b/app/node/color/ociobase/ociobase.h index 2336c2214..1c5f349fa 100644 --- a/app/node/color/ociobase/ociobase.h +++ b/app/node/color/ociobase/ociobase.h @@ -51,7 +51,7 @@ private: ColorProcessorPtr processor_; private slots: - void AddedToGraph(NodeGraph *graph); + void AddedToGraph(Project *p); void RemovedFromGraph(); diff --git a/app/node/color/ociogradingtransformlinear/ociogradingtransformlinear.cpp b/app/node/color/ociogradingtransformlinear/ociogradingtransformlinear.cpp index a6a37012f..6b88ab7ce 100644 --- a/app/node/color/ociogradingtransformlinear/ociogradingtransformlinear.cpp +++ b/app/node/color/ociogradingtransformlinear/ociogradingtransformlinear.cpp @@ -23,7 +23,7 @@ #include #include "common/ocioutils.h" -#include "node/project/project.h" +#include "node/project.h" #include "render/colorprocessor.h" #include "widget/slider/floatslider.h" diff --git a/app/node/distort/cornerpin/cornerpindistortnode.cpp b/app/node/distort/cornerpin/cornerpindistortnode.cpp index 2bb8a4a90..3f37e3994 100644 --- a/app/node/distort/cornerpin/cornerpindistortnode.cpp +++ b/app/node/distort/cornerpin/cornerpindistortnode.cpp @@ -51,7 +51,7 @@ CornerPinDistortNode::CornerPinDistortNode() gizmo_resize_handle_[2] = AddDraggableGizmo({NodeKeyframeTrackReference(NodeInput(this, kBottomRightInput), 0), NodeKeyframeTrackReference(NodeInput(this, kBottomRightInput), 1)}); gizmo_resize_handle_[3] = AddDraggableGizmo({NodeKeyframeTrackReference(NodeInput(this, kBottomLeftInput), 0), NodeKeyframeTrackReference(NodeInput(this, kBottomLeftInput), 1)}); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/distort/crop/cropdistortnode.cpp b/app/node/distort/crop/cropdistortnode.cpp index 1d2dfd4e3..da278f880 100644 --- a/app/node/distort/crop/cropdistortnode.cpp +++ b/app/node/distort/crop/cropdistortnode.cpp @@ -59,7 +59,7 @@ CropDistortNode::CropDistortNode() point_gizmo_[kGizmoScaleCenterLeft] = AddDraggableGizmo({kLeftInput}); point_gizmo_[kGizmoScaleCenterRight] = AddDraggableGizmo({kRightInput}); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/distort/flip/flipdistortnode.cpp b/app/node/distort/flip/flipdistortnode.cpp index 6a1083099..1d8e36034 100644 --- a/app/node/distort/flip/flipdistortnode.cpp +++ b/app/node/distort/flip/flipdistortnode.cpp @@ -36,7 +36,7 @@ FlipDistortNode::FlipDistortNode() AddInput(kVerticalInput, NodeValue::kBoolean, false); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } 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/distort/ripple/rippledistortnode.cpp b/app/node/distort/ripple/rippledistortnode.cpp index 2e137ff3c..2e8a1f1b4 100644 --- a/app/node/distort/ripple/rippledistortnode.cpp +++ b/app/node/distort/ripple/rippledistortnode.cpp @@ -44,7 +44,7 @@ RippleDistortNode::RippleDistortNode() AddInput(kPositionInput, NodeValue::kVec2, QVector2D(0, 0)); AddInput(kStretchInput, NodeValue::kBoolean, false); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); gizmo_ = AddDraggableGizmo({ diff --git a/app/node/distort/swirl/swirldistortnode.cpp b/app/node/distort/swirl/swirldistortnode.cpp index ddab58a60..eb91bc27a 100644 --- a/app/node/distort/swirl/swirldistortnode.cpp +++ b/app/node/distort/swirl/swirldistortnode.cpp @@ -41,7 +41,7 @@ SwirlDistortNode::SwirlDistortNode() AddInput(kPositionInput, NodeValue::kVec2, QVector2D(0, 0)); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); gizmo_ = AddDraggableGizmo({ diff --git a/app/node/distort/tile/tiledistortnode.cpp b/app/node/distort/tile/tiledistortnode.cpp index ec13a1ee4..864428a7a 100644 --- a/app/node/distort/tile/tiledistortnode.cpp +++ b/app/node/distort/tile/tiledistortnode.cpp @@ -48,7 +48,7 @@ TileDistortNode::TileDistortNode() AddInput(kMirrorXInput, NodeValue::kBoolean, false); AddInput(kMirrorYInput, NodeValue::kBoolean, false); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); gizmo_ = AddDraggableGizmo({ diff --git a/app/node/distort/transform/transformdistortnode.cpp b/app/node/distort/transform/transformdistortnode.cpp index bc2769a8f..01d9e1c45 100644 --- a/app/node/distort/transform/transformdistortnode.cpp +++ b/app/node/distort/transform/transformdistortnode.cpp @@ -64,7 +64,7 @@ TransformDistortNode::TransformDistortNode() point_gizmo_[i]->SetDragValueBehavior(PointGizmo::kAbsolute); } - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/distort/wave/wavedistortnode.cpp b/app/node/distort/wave/wavedistortnode.cpp index d3f948585..88171d6f2 100644 --- a/app/node/distort/wave/wavedistortnode.cpp +++ b/app/node/distort/wave/wavedistortnode.cpp @@ -40,7 +40,7 @@ WaveDistortNode::WaveDistortNode() AddInput(kVerticalInput, NodeValue::kCombo, false); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/effect/opacity/opacityeffect.cpp b/app/node/effect/opacity/opacityeffect.cpp index ee58fb632..4b7e7ce67 100644 --- a/app/node/effect/opacity/opacityeffect.cpp +++ b/app/node/effect/opacity/opacityeffect.cpp @@ -25,7 +25,7 @@ OpacityEffect::OpacityEffect() SetInputProperty(kValueInput, QStringLiteral("min"), 0.0); SetInputProperty(kValueInput, QStringLiteral("max"), 1.0); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/filter/blur/blur.cpp b/app/node/filter/blur/blur.cpp index 3955608b7..8d0b68bd3 100644 --- a/app/node/filter/blur/blur.cpp +++ b/app/node/filter/blur/blur.cpp @@ -66,7 +66,7 @@ BlurFilterNode::BlurFilterNode() AddInput(kRepeatEdgePixelsInput, NodeValue::kBoolean, true); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); radial_center_gizmo_ = AddDraggableGizmo(); @@ -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/filter/dropshadow/dropshadowfilter.cpp b/app/node/filter/dropshadow/dropshadowfilter.cpp index f8c60cdd5..fead73b09 100644 --- a/app/node/filter/dropshadow/dropshadowfilter.cpp +++ b/app/node/filter/dropshadow/dropshadowfilter.cpp @@ -54,7 +54,7 @@ DropShadowFilter::DropShadowFilter() AddInput(kFastInput, NodeValue::kBoolean, false); SetEffectInput(kTextureInput); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); } void DropShadowFilter::Retranslate() diff --git a/app/node/filter/mosaic/mosaicfilternode.cpp b/app/node/filter/mosaic/mosaicfilternode.cpp index 9cb5f9af7..63966320e 100644 --- a/app/node/filter/mosaic/mosaicfilternode.cpp +++ b/app/node/filter/mosaic/mosaicfilternode.cpp @@ -38,7 +38,7 @@ MosaicFilterNode::MosaicFilterNode() AddInput(kVertInput, NodeValue::kFloat, 18.0); SetInputProperty(kVertInput, QStringLiteral("min"), 1.0); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/filter/stroke/stroke.cpp b/app/node/filter/stroke/stroke.cpp index 858f26102..3f49cd4c4 100644 --- a/app/node/filter/stroke/stroke.cpp +++ b/app/node/filter/stroke/stroke.cpp @@ -48,7 +48,7 @@ StrokeFilterNode::StrokeFilterNode() AddInput(kInnerInput, NodeValue::kBoolean, false); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/generator/noise/noise.cpp b/app/node/generator/noise/noise.cpp index 94072db1d..8d9f70c24 100644 --- a/app/node/generator/noise/noise.cpp +++ b/app/node/generator/noise/noise.cpp @@ -41,7 +41,7 @@ NoiseGeneratorNode::NoiseGeneratorNode() AddInput(kColorInput, NodeValue::kBoolean, false); SetEffectInput(kBaseIn); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); } QString NoiseGeneratorNode::Name() const diff --git a/app/node/generator/shape/generatorwithmerge.cpp b/app/node/generator/shape/generatorwithmerge.cpp index 93f8bcde3..6832e3e6e 100644 --- a/app/node/generator/shape/generatorwithmerge.cpp +++ b/app/node/generator/shape/generatorwithmerge.cpp @@ -32,7 +32,7 @@ GeneratorWithMerge::GeneratorWithMerge() { AddInput(kBaseInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); SetEffectInput(kBaseInput); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); } void GeneratorWithMerge::Retranslate() 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/textv1.cpp b/app/node/generator/text/textv1.cpp index 68c3a5e7d..ae08389c6 100644 --- a/app/node/generator/text/textv1.cpp +++ b/app/node/generator/text/textv1.cpp @@ -54,7 +54,7 @@ TextGeneratorV1::TextGeneratorV1() AddInput(kFontSizeInput, NodeValue::kFloat, 72.0f); - SetFlags(kDontShowInCreateMenu); + SetFlag(kDontShowInCreateMenu); } QString TextGeneratorV1::Name() const diff --git a/app/node/generator/text/textv2.cpp b/app/node/generator/text/textv2.cpp index f4165afa1..3472bb601 100644 --- a/app/node/generator/text/textv2.cpp +++ b/app/node/generator/text/textv2.cpp @@ -56,7 +56,7 @@ TextGeneratorV2::TextGeneratorV2() SetStandardValue(kColorInput, QVariant::fromValue(Color(1.0f, 1.0f, 1.0))); SetStandardValue(kSizeInput, QVector2D(400, 300)); - SetFlags(kDontShowInCreateMenu); + SetFlag(kDontShowInCreateMenu); } QString TextGeneratorV2::Name() const diff --git a/app/node/generator/text/textv3.cpp b/app/node/generator/text/textv3.cpp index 6d776f462..ea1ad9d55 100644 --- a/app/node/generator/text/textv3.cpp +++ b/app/node/generator/text/textv3.cpp @@ -26,8 +26,8 @@ #include "common/html.h" #include "core.h" -#include "node/project/project.h" -#include "widget/nodeparamview/nodeparamviewundo.h" +#include "node/project.h" +#include "node/nodeundo.h" namespace olive { diff --git a/app/node/graph.cpp b/app/node/graph.cpp deleted file mode 100644 index 44165727f..000000000 --- a/app/node/graph.cpp +++ /dev/null @@ -1,131 +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 "graph.h" - -#include - -namespace olive { - -#define super QObject - -NodeGraph::NodeGraph() -{ -} - -NodeGraph::~NodeGraph() -{ - Clear(); -} - -void NodeGraph::Clear() -{ - // By deleting the last nodes first, we assume that nodes that are most important are deleted last - // (e.g. Project's ColorManager or ProjectSettingsNode. - for (auto it=node_children_.cbegin(); it!=node_children_.cend(); it++) { - (*it)->SetCachesEnabled(false); - } - - while (!node_children_.isEmpty()) { - delete node_children_.last(); - } -} - -int NodeGraph::GetNumberOfContextsNodeIsIn(Node *node, bool except_itself) const -{ - int count = 0; - - foreach (Node *ctx, node_children_) { - if (ctx->ContextContainsNode(node) && (!except_itself || ctx != node)) { - count++; - } - } - - return count; -} - -void NodeGraph::childEvent(QChildEvent *event) -{ - super::childEvent(event); - - Node* node = dynamic_cast(event->child()); - - if (node) { - if (event->type() == QEvent::ChildAdded) { - - node_children_.append(node); - - // Connect signals - connect(node, &Node::InputConnected, this, &NodeGraph::InputConnected, Qt::DirectConnection); - connect(node, &Node::InputDisconnected, this, &NodeGraph::InputDisconnected, Qt::DirectConnection); - connect(node, &Node::ValueChanged, this, &NodeGraph::ValueChanged, Qt::DirectConnection); - connect(node, &Node::InputValueHintChanged, this, &NodeGraph::InputValueHintChanged, Qt::DirectConnection); - - if (NodeGroup *group = dynamic_cast(node)) { - connect(group, &NodeGroup::InputPassthroughAdded, this, &NodeGraph::GroupAddedInputPassthrough, Qt::DirectConnection); - connect(group, &NodeGroup::InputPassthroughRemoved, this, &NodeGraph::GroupRemovedInputPassthrough, Qt::DirectConnection); - connect(group, &NodeGroup::OutputPassthroughChanged, this, &NodeGraph::GroupChangedOutputPassthrough, Qt::DirectConnection); - } - - emit NodeAdded(node); - emit node->AddedToGraph(this); - - // Emit input connections - for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) { - if (nodes().contains(it->second)) { - emit InputConnected(it->second, it->first); - } - } - - // Emit output connections - for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) { - if (nodes().contains(it->second.node())) { - emit InputConnected(it->first, it->second); - } - } - - } else if (event->type() == QEvent::ChildRemoved) { - - node_children_.removeOne(node); - - // Disconnect signals - disconnect(node, &Node::InputConnected, this, &NodeGraph::InputConnected); - disconnect(node, &Node::InputDisconnected, this, &NodeGraph::InputDisconnected); - disconnect(node, &Node::ValueChanged, this, &NodeGraph::ValueChanged); - disconnect(node, &Node::InputValueHintChanged, this, &NodeGraph::InputValueHintChanged); - - if (NodeGroup *group = dynamic_cast(node)) { - disconnect(group, &NodeGroup::InputPassthroughAdded, this, &NodeGraph::GroupAddedInputPassthrough); - disconnect(group, &NodeGroup::InputPassthroughRemoved, this, &NodeGraph::GroupRemovedInputPassthrough); - disconnect(group, &NodeGroup::OutputPassthroughChanged, this, &NodeGraph::GroupChangedOutputPassthrough); - } - - emit NodeRemoved(node); - emit node->RemovedFromGraph(this); - - // Remove from any contexts - foreach (Node *context, node_children_) { - context->RemoveNodeFromContext(node); - } - } - } -} - -} diff --git a/app/node/graph.h b/app/node/graph.h deleted file mode 100644 index 93f1100b1..000000000 --- a/app/node/graph.h +++ /dev/null @@ -1,111 +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 NODEGRAPH_H -#define NODEGRAPH_H - -#include "node/group/group.h" -#include "node/node.h" - -namespace olive { - -/** - * @brief A collection of nodes - * - * This doesn't technically need to be a derivative of Item, but since both Item and NodeGraph need - * to be QObject derivatives, this simplifies Sequence. - */ -class NodeGraph : public QObject -{ - Q_OBJECT -public: - /** - * @brief NodeGraph Constructor - */ - NodeGraph(); - - /** - * @brief NodeGraph Destructor - */ - virtual ~NodeGraph() override; - - /** - * @brief Destructively destroys all nodes in the graph - */ - void Clear(); - - /** - * @brief Retrieve a complete list of the nodes belonging to this graph - */ - const QVector& nodes() const - { - return node_children_; - } - - const QVector& default_nodes() const - { - return default_nodes_; - } - - int GetNumberOfContextsNodeIsIn(Node *node, bool except_itself = false) const; - -signals: - /** - * @brief Signal emitted when a Node is added to the graph - */ - void NodeAdded(Node* node); - - /** - * @brief Signal emitted when a Node is removed from the graph - */ - void NodeRemoved(Node* node); - - void InputConnected(Node *output, const NodeInput& input); - - void InputDisconnected(Node *output, const NodeInput& input); - - void ValueChanged(const NodeInput& input); - - void InputValueHintChanged(const NodeInput& input); - - void GroupAddedInputPassthrough(NodeGroup *group, const NodeInput &input); - - void GroupRemovedInputPassthrough(NodeGroup *group, const NodeInput &input); - - void GroupChangedOutputPassthrough(NodeGroup *group, Node *output); - -protected: - void AddDefaultNode(Node* n) - { - default_nodes_.append(n); - } - - virtual void childEvent(QChildEvent* event) override; - -private: - QVector node_children_; - - QVector default_nodes_; - -}; - -} - -#endif // NODEGRAPH_H diff --git a/app/node/group/group.cpp b/app/node/group/group.cpp index b0ed9705c..9ca495e1f 100644 --- a/app/node/group/group.cpp +++ b/app/node/group/group.cpp @@ -20,7 +20,7 @@ #include "group.h" -#include "node/graph.h" +#include "node/project.h" namespace olive { @@ -29,7 +29,7 @@ namespace olive { NodeGroup::NodeGroup() : output_passthrough_(nullptr) { - SetFlags(kDontShowInCreateMenu); + SetFlag(kDontShowInCreateMenu); } QString NodeGroup::Name() const 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/keying/colordifferencekey/colordifferencekey.cpp b/app/node/keying/colordifferencekey/colordifferencekey.cpp index 8627efdda..40ff98ccf 100644 --- a/app/node/keying/colordifferencekey/colordifferencekey.cpp +++ b/app/node/keying/colordifferencekey/colordifferencekey.cpp @@ -47,7 +47,7 @@ ColorDifferenceKeyNode::ColorDifferenceKeyNode() AddInput(kMaskOnlyInput, NodeValue::kBoolean, false); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/keying/despill/despill.cpp b/app/node/keying/despill/despill.cpp index 8b91d3dfd..267e3d3c4 100644 --- a/app/node/keying/despill/despill.cpp +++ b/app/node/keying/despill/despill.cpp @@ -15,7 +15,7 @@ #include "despill.h" -#include "node/project/project.h" +#include "node/project.h" namespace olive { @@ -36,7 +36,7 @@ DespillNode::DespillNode() AddInput(kPreserveLuminanceInput, NodeValue::kBoolean, false); - SetFlags(kVideoEffect); + SetFlag(kVideoEffect); SetEffectInput(kTextureInput); } diff --git a/app/node/math/merge/merge.cpp b/app/node/math/merge/merge.cpp index 2285a6c32..e95e0ff99 100644 --- a/app/node/math/merge/merge.cpp +++ b/app/node/math/merge/merge.cpp @@ -35,7 +35,7 @@ MergeNode::MergeNode() AddInput(kBlendIn, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable)); - SetFlags(kDontShowInParamView); + SetFlag(kDontShowInParamView); } QString MergeNode::Name() const diff --git a/app/node/node.cpp b/app/node/node.cpp index d514c5d73..60c951a0e 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -28,11 +28,11 @@ #include "common/lerp.h" #include "core.h" #include "config/config.h" -#include "project/project.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 { @@ -41,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), @@ -76,9 +75,9 @@ Node::~Node() } } -NodeGraph *Node::parent() const +Project *Node::parent() const { - return static_cast(QObject::parent()); + return static_cast(QObject::parent()); } Project *Node::project() const @@ -102,10 +101,14 @@ void Node::Retranslate() SetInputName(kEnabledInput, tr("Enabled")); } -QIcon Node::icon() const +QVariant Node::data(const DataType &d) const { - // Just a meaningless default icon to be used where necessary - return icon::New; + if (d == ICON) { + // Just a meaningless default icon to be used where necessary + return icon::New; + } + + return QVariant(); } bool Node::SetNodePositionInContext(Node *node, const QPointF &pos) @@ -200,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()) & kInputFlagIgnoreInvalidations)) { input.node()->InvalidateAll(input.input(), input.element()); } } @@ -227,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()) & kInputFlagIgnoreInvalidations)) { input.node()->InvalidateAll(input.input(), input.element()); } } @@ -777,87 +780,74 @@ bool Node::InputIsArray(const QString &id) const return GetInputFlags(id) & kInputFlagArray; } -void Node::InputArrayInsert(const QString &id, int index, bool undoable) +void Node::InputArrayInsert(const QString &id, int index) { - if (undoable) { - Core::instance()->undo_stack()->push(new ArrayInsertCommand(this, id, index)); - } else { - // Add new input - ArrayResizeInternal(id, InputArraySize(id) + 1); + // Add new input + ArrayResizeInternal(id, InputArraySize(id) + 1); - // Move connections down - InputConnections copied_edges = input_connections(); - for (auto it=copied_edges.crbegin(); it!=copied_edges.crend(); it++) { - if (it->first.input() == id && it->first.element() >= index) { - // Disconnect this and reconnect it one element down - NodeInput new_edge = it->first; - new_edge.set_element(new_edge.element() + 1); + // Move connections down + InputConnections copied_edges = input_connections(); + for (auto it=copied_edges.crbegin(); it!=copied_edges.crend(); it++) { + if (it->first.input() == id && it->first.element() >= index) { + // Disconnect this and reconnect it one element down + NodeInput new_edge = it->first; + new_edge.set_element(new_edge.element() + 1); - DisconnectEdge(it->second, it->first); - ConnectEdge(it->second, new_edge); - } + DisconnectEdge(it->second, it->first); + ConnectEdge(it->second, new_edge); } - - // Shift values and keyframes up one element - for (int i=InputArraySize(id)-1; i>index; i--) { - CopyValuesOfElement(this, this, id, i-1, i); - } - - // Reset value of element we just "inserted" - ClearElement(id, index); } + + // Shift values and keyframes up one element + for (int i=InputArraySize(id)-1; i>index; i--) { + CopyValuesOfElement(this, this, id, i-1, i); + } + + // Reset value of element we just "inserted" + ClearElement(id, index); } -void Node::InputArrayResize(const QString &id, int size, bool undoable) +void Node::InputArrayResize(const QString &id, int size) { if (InputArraySize(id) == size) { return; } - ArrayResizeCommand* c = new ArrayResizeCommand(this, id, size); - - if (undoable) { - Core::instance()->undo_stack()->push(c); - } else { - c->redo_now(); - delete c; - } + NodeArrayResizeCommand* c = new NodeArrayResizeCommand(this, id, size); + c->redo_now(); + delete c; } -void Node::InputArrayRemove(const QString &id, int index, bool undoable) +void Node::InputArrayRemove(const QString &id, int index) { - if (undoable) { - Core::instance()->undo_stack()->push(new ArrayRemoveCommand(this, id, index)); - } else { - // Remove input - ArrayResizeInternal(id, InputArraySize(id) - 1); + // Remove input + ArrayResizeInternal(id, InputArraySize(id) - 1); - // Move connections up - InputConnections copied_edges = input_connections(); - for (auto it=copied_edges.cbegin(); it!=copied_edges.cend(); it++) { - if (it->first.input() == id && it->first.element() >= index) { - // Disconnect this and reconnect it one element up if it's not the element being removed - DisconnectEdge(it->second, it->first); + // Move connections up + InputConnections copied_edges = input_connections(); + for (auto it=copied_edges.cbegin(); it!=copied_edges.cend(); it++) { + if (it->first.input() == id && it->first.element() >= index) { + // Disconnect this and reconnect it one element up if it's not the element being removed + DisconnectEdge(it->second, it->first); - if (it->first.element() > index) { - NodeInput new_edge = it->first; - new_edge.set_element(new_edge.element() - 1); + if (it->first.element() > index) { + NodeInput new_edge = it->first; + new_edge.set_element(new_edge.element() - 1); - ConnectEdge(it->second, new_edge); - } + ConnectEdge(it->second, new_edge); } } - - // Shift values and keyframes down one element - int arr_sz = InputArraySize(id); - for (int i=index; iflags = f; + if (on) { + i->flags |= f; + } else { + i->flags &= ~f; + } emit InputFlagsChanged(input, i->flags); } else { ReportInvalidInput("set flags of", input, -1); @@ -982,7 +976,7 @@ QVector Node::CopyDependencyGraph(const QVector &nodes, MultiUnd Node::CopyInputs(nodes.at(i), c, false); // Add to graph - NodeGraph* graph = static_cast(nodes.at(i)->parent()); + Project* graph = nodes.at(i)->parent(); if (command) { command->add_child(new NodeAddCommand(graph, c)); } else { @@ -1113,7 +1107,7 @@ Node *Node::CopyNodeInGraph(Node *node, MultiUndoCommand *command) } else { copy = node->copy(); - command->add_child(new NodeAddCommand(static_cast(node->parent()), copy)); + command->add_child(new NodeAddCommand(node->parent(), copy)); CopyInputs(node, copy, true, command); @@ -1317,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_; @@ -1434,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(); } @@ -1463,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); } @@ -1478,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++) { @@ -1658,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) & kInputFlagIgnoreInvalidations) { return; } @@ -1956,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() -{ - NodeGraph *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 24d13bdd8..974db61f8 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -56,7 +56,7 @@ namespace olive { #define NODE_COPY_FUNCTION(x) \ virtual Node *copy() const override {return new x();} -class NodeGraph; +class Project; class Folder; /** @@ -100,7 +100,8 @@ public: kDontShowInParamView = 0x1, kVideoEffect = 0x2, kAudioEffect = 0x4, - kDontShowInCreateMenu = 0x8 + kDontShowInCreateMenu = 0x8, + kIsItem = 0x10 }; struct ContextPair { @@ -123,7 +124,7 @@ public: /** * @brief Convenience function - assumes parent is a NodeGraph */ - NodeGraph* parent() const; + Project *parent() const; Project* project() const; @@ -184,24 +185,23 @@ public: return folder_; } - virtual bool IsItem() const - { - return false; - } + bool IsItem() const { return flags_ & kIsItem; } /** * @brief Function called to retranslate parameter names (should be overridden in derivatives) */ virtual void Retranslate(); - virtual QIcon icon() const; + enum DataType + { + ICON, + DURATION, + CREATED_TIME, + MODIFIED_TIME, + FREQUENCY_RATE + }; - virtual QString duration() const {return QString();} - - virtual qint64 creation_time() const {return 0;} - virtual qint64 mod_time() const {return 0;} - - virtual QString rate() const {return QString();} + virtual QVariant data(const DataType &d) const; const QVector& inputs() const { @@ -614,27 +614,29 @@ public: bool InputIsArray(const QString& id) const; - void InputArrayInsert(const QString& id, int index, bool undoable = false); - void InputArrayResize(const QString& id, int size, bool undoable = false); - void InputArrayRemove(const QString& id, int index, bool undoable = false); + void InputArrayInsert(const QString& id, int index); + void InputArrayResize(const QString& id, int size); + void InputArrayRemove(const QString& id, int index); - void InputArrayAppend(const QString& id, bool undoable = false) + void InputArrayAppend(const QString& id) { - InputArrayResize(id, InputArraySize(id) + 1, undoable); + InputArrayResize(id, InputArraySize(id) + 1); } - void InputArrayPrepend(const QString& id, bool undoable = false) + void InputArrayPrepend(const QString& id) { - InputArrayInsert(id, 0, undoable); + InputArrayInsert(id, 0); } - void InputArrayRemoveLast(const QString& id, bool undoable = false) + void InputArrayRemoveLast(const QString& id) { - InputArrayResize(id, InputArraySize(id) - 1, undoable); + InputArrayResize(id, InputArraySize(id) - 1); } 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_, false); - } - - virtual void undo() override - { - node_->InputArrayRemove(input_, index_, false); - } - - 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_, false); - } - - virtual void undo() override - { - node_->InputArrayInsert(input_, index_, false); - - // 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, @@ -1196,9 +1031,13 @@ protected: tooltip_ = s; } - void SetFlags(const uint64_t &f) + void SetFlag(Flag f, bool on = true) { - flags_ = f; + if (on) { + flags_ |= f; + } else { + flags_ &= ~f; + } } template @@ -1275,9 +1114,9 @@ signals: void InputDataTypeChanged(const QString& id, NodeValue::Type type); - void AddedToGraph(NodeGraph* graph); + void AddedToGraph(Project* graph); - void RemovedFromGraph(NodeGraph* graph); + void RemovedFromGraph(Project* graph); void NodeAddedToContext(Node *node); @@ -1297,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); @@ -1355,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); /** @@ -1393,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 */ @@ -1524,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 e1bdde7f3..3f2abe1c3 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -46,11 +46,7 @@ Track::Track() : locked_(false), sequence_(nullptr) { - 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 | kInputFlagIgnoreInvalidations)); AddInput(kMutedInput, NodeValue::kBoolean, false, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable)); diff --git a/app/node/output/track/tracklist.cpp b/app/node/output/track/tracklist.cpp index 94c90b6ec..767dfc195 100644 --- a/app/node/output/track/tracklist.cpp +++ b/app/node/output/track/tracklist.cpp @@ -142,7 +142,7 @@ void TrackList::UpdateTrackIndexesFrom(int index) } } -NodeGraph *TrackList::GetParentGraph() const +Project *TrackList::GetParentGraph() const { return parent()->parent(); } @@ -167,14 +167,14 @@ int TrackList::ArraySize() const return parent()->InputArraySize(track_input()); } -void TrackList::ArrayAppend(bool undoable) +void TrackList::ArrayAppend() { - parent()->InputArrayAppend(track_input(), undoable); + parent()->InputArrayAppend(track_input()); } -void TrackList::ArrayRemoveLast(bool undoable) +void TrackList::ArrayRemoveLast() { - parent()->InputArrayRemoveLast(track_input(), undoable); + parent()->InputArrayRemoveLast(track_input()); } void TrackList::UpdateTotalLength() diff --git a/app/node/output/track/tracklist.h b/app/node/output/track/tracklist.h index bfa76a30e..b9d6173fd 100644 --- a/app/node/output/track/tracklist.h +++ b/app/node/output/track/tracklist.h @@ -23,7 +23,6 @@ #include -#include "node/graph.h" #include "node/output/track/track.h" #include "timeline/timelinecommon.h" @@ -59,7 +58,7 @@ public: return track_cache_.size(); } - NodeGraph* GetParentGraph() const; + Project* GetParentGraph() const; const QString &track_input() const; NodeInput track_input(int element) const; @@ -68,8 +67,8 @@ public: int ArraySize() const; - void ArrayAppend(bool undoable = false); - void ArrayRemoveLast(bool undoable = false); + void ArrayAppend(); + void ArrayRemoveLast(); int GetArrayIndexFromCacheIndex(int index) const { diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index 5f2437889..dd7cc8dfb 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -61,7 +61,7 @@ ViewerOutput::ViewerOutput(bool create_buffer_inputs, bool create_default_stream set_default_parameters(); } - SetFlags(kDontShowInParamView); + SetFlag(kDontShowInParamView); workarea_ = new TimelineWorkArea(this); markers_ = new TimelineMarkerList(this); @@ -87,56 +87,61 @@ QString ViewerOutput::Description() const return tr("Interface between a Viewer panel and the node system."); } -QString ViewerOutput::duration() const +QVariant ViewerOutput::data(const DataType &d) const { - rational using_timebase; - Timecode::Display using_display = Core::instance()->GetTimecodeDisplay(); + switch (d) { + case DURATION: + { + rational using_timebase; + Timecode::Display using_display = Core::instance()->GetTimecodeDisplay(); - // Get first enabled streams - VideoParams video = GetFirstEnabledVideoStream(); - AudioParams audio = GetFirstEnabledAudioStream(); - SubtitleParams sub = GetFirstEnabledSubtitleStream(); + // Get first enabled streams + VideoParams video = GetFirstEnabledVideoStream(); + AudioParams audio = GetFirstEnabledAudioStream(); + SubtitleParams sub = GetFirstEnabledSubtitleStream(); - if (video.is_valid() && video.video_type() != VideoParams::kVideoTypeStill) { - // Prioritize video - using_timebase = video.frame_rate_as_time_base(); - } else if (audio.is_valid()) { - // Use audio as a backup - // If we're showing in a timecode, we prefer showing audio in seconds instead - if (using_display == Timecode::kTimecodeDropFrame - || using_display == Timecode::kTimecodeNonDropFrame) { - using_display = Timecode::kTimecodeSeconds; + if (video.is_valid() && video.video_type() != VideoParams::kVideoTypeStill) { + // Prioritize video + using_timebase = video.frame_rate_as_time_base(); + } else if (audio.is_valid()) { + // Use audio as a backup + // If we're showing in a timecode, we prefer showing audio in seconds instead + if (using_display == Timecode::kTimecodeDropFrame + || using_display == Timecode::kTimecodeNonDropFrame) { + using_display = Timecode::kTimecodeSeconds; + } + + using_timebase = audio.sample_rate_as_time_base(); + } else if (sub.is_valid()) { + using_timebase = OLIVE_CONFIG("DefaultSequenceFrameRate").value(); } - using_timebase = audio.sample_rate_as_time_base(); - } else if (sub.is_valid()) { - using_timebase = OLIVE_CONFIG("DefaultSequenceFrameRate").value(); + if (!using_timebase.isNull()) { + // Return time transformed to timecode + return QString::fromStdString(Timecode::time_to_timecode(GetLength(), using_timebase, using_display)); + } + break; + } + case FREQUENCY_RATE: + { + VideoParams video_stream; + + if (HasEnabledVideoStreams() + && (video_stream = GetFirstEnabledVideoStream()).video_type() != VideoParams::kVideoTypeStill) { + // This is a video editor, prioritize video streams + return tr("%1 FPS").arg(video_stream.frame_rate().toDouble()); + } else if (HasEnabledAudioStreams()) { + // No video streams, return audio + AudioParams audio_stream = GetFirstEnabledAudioStream(); + return tr("%1 Hz").arg(audio_stream.sample_rate()); + } + break; + } + default: + break; } - if (using_timebase.isNull()) { - // No timebase, return null - return QString(); - } else { - // Return time transformed to timecode - return QString::fromStdString(Timecode::time_to_timecode(GetLength(), using_timebase, using_display)); - } -} - -QString ViewerOutput::rate() const -{ - VideoParams video_stream; - - if (HasEnabledVideoStreams() - && (video_stream = GetFirstEnabledVideoStream()).video_type() != VideoParams::kVideoTypeStill) { - // This is a video editor, prioritize video streams - return tr("%1 FPS").arg(video_stream.frame_rate().toDouble()); - } else if (HasEnabledAudioStreams()) { - // No video streams, return audio - AudioParams audio_stream = GetFirstEnabledAudioStream(); - return tr("%1 Hz").arg(audio_stream.sample_rate()); - } - - return QString(); + return super::data(d); } bool ViewerOutput::HasEnabledVideoStreams() const diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index 70d40dd2a..053d76e67 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -53,8 +53,7 @@ public: virtual QVector Category() const override; virtual QString Description() const override; - virtual QString duration() const override; - virtual QString rate() const override; + virtual QVariant data(const DataType &d) const override; void set_default_parameters(); diff --git a/app/node/param.h b/app/node/param.h index 683d6a2fa..ae3a804e8 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, + kInputFlagIgnoreInvalidations = 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/project.cpp b/app/node/project.cpp similarity index 54% rename from app/node/project/project.cpp rename to app/node/project.cpp index b84c8ee22..6d3ac0a7e 100644 --- a/app/node/project/project.cpp +++ b/app/node/project.cpp @@ -33,6 +33,8 @@ namespace olive { +#define super QObject + const QString Project::kItemMimeType = QStringLiteral("application/x-oliveprojectitemdata"); Project::Project() : @@ -46,25 +48,120 @@ 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, this, &Project::ColorManagerValueChanged); } +Project::~Project() +{ + Clear(); +} + +void Project::Clear() +{ + // By deleting the last nodes first, we assume that nodes that are most important are deleted last + // (e.g. Project's ColorManager or ProjectSettingsNode. + for (auto it=node_children_.cbegin(); it!=node_children_.cend(); it++) { + (*it)->SetCachesEnabled(false); + } + + while (!node_children_.isEmpty()) { + delete node_children_.last(); + } +} + +int Project::GetNumberOfContextsNodeIsIn(Node *node, bool except_itself) const +{ + int count = 0; + + foreach (Node *ctx, node_children_) { + if (ctx->ContextContainsNode(node) && (!except_itself || ctx != node)) { + count++; + } + } + + return count; +} + +void Project::childEvent(QChildEvent *event) +{ + super::childEvent(event); + + Node* node = dynamic_cast(event->child()); + + if (node) { + if (event->type() == QEvent::ChildAdded) { + + node_children_.append(node); + + // Connect signals + connect(node, &Node::InputConnected, this, &Project::InputConnected, Qt::DirectConnection); + connect(node, &Node::InputDisconnected, this, &Project::InputDisconnected, Qt::DirectConnection); + connect(node, &Node::ValueChanged, this, &Project::ValueChanged, Qt::DirectConnection); + connect(node, &Node::InputValueHintChanged, this, &Project::InputValueHintChanged, Qt::DirectConnection); + + if (NodeGroup *group = dynamic_cast(node)) { + connect(group, &NodeGroup::InputPassthroughAdded, this, &Project::GroupAddedInputPassthrough, Qt::DirectConnection); + connect(group, &NodeGroup::InputPassthroughRemoved, this, &Project::GroupRemovedInputPassthrough, Qt::DirectConnection); + connect(group, &NodeGroup::OutputPassthroughChanged, this, &Project::GroupChangedOutputPassthrough, Qt::DirectConnection); + } + + emit NodeAdded(node); + emit node->AddedToGraph(this); + + // Emit input connections + for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) { + if (nodes().contains(it->second)) { + emit InputConnected(it->second, it->first); + } + } + + // Emit output connections + for (auto it=node->output_connections().cbegin(); it!=node->output_connections().cend(); it++) { + if (nodes().contains(it->second.node())) { + emit InputConnected(it->first, it->second); + } + } + + } else if (event->type() == QEvent::ChildRemoved) { + + node_children_.removeOne(node); + + // Disconnect signals + disconnect(node, &Node::InputConnected, this, &Project::InputConnected); + disconnect(node, &Node::InputDisconnected, this, &Project::InputDisconnected); + disconnect(node, &Node::ValueChanged, this, &Project::ValueChanged); + disconnect(node, &Node::InputValueHintChanged, this, &Project::InputValueHintChanged); + + if (NodeGroup *group = dynamic_cast(node)) { + disconnect(group, &NodeGroup::InputPassthroughAdded, this, &Project::GroupAddedInputPassthrough); + disconnect(group, &NodeGroup::InputPassthroughRemoved, this, &Project::GroupRemovedInputPassthrough); + disconnect(group, &NodeGroup::OutputPassthroughChanged, this, &Project::GroupChangedOutputPassthrough); + } + + emit NodeRemoved(node); + emit node->RemovedFromGraph(this); + + // Remove from any contexts + foreach (Node *context, node_children_) { + context->RemoveNodeFromContext(node); + } + } + } +} + Folder *Project::root() { return root_; diff --git a/app/node/project/project.h b/app/node/project.h similarity index 70% rename from app/node/project/project.h rename to app/node/project.h index 09e7e8606..025b0ee44 100644 --- a/app/node/project/project.h +++ b/app/node/project.h @@ -44,12 +44,34 @@ namespace olive { * * Project Settings * * Window Layout */ -class Project : public NodeGraph +class Project : public QObject { Q_OBJECT public: Project(); + virtual ~Project() override; + + /** + * @brief Destructively destroys all nodes in the graph + */ + void Clear(); + + /** + * @brief Retrieve a complete list of the nodes belonging to this graph + */ + const QVector& nodes() const + { + return node_children_; + } + + const QVector& default_nodes() const + { + return default_nodes_; + } + + int GetNumberOfContextsNodeIsIn(Node *node, bool except_itself = false) const; + Folder* root(); QString name() const; @@ -124,6 +146,38 @@ signals: void ModifiedChanged(bool e); + /** + * @brief Signal emitted when a Node is added to the graph + */ + void NodeAdded(Node* node); + + /** + * @brief Signal emitted when a Node is removed from the graph + */ + void NodeRemoved(Node* node); + + void InputConnected(Node *output, const NodeInput& input); + + void InputDisconnected(Node *output, const NodeInput& input); + + void ValueChanged(const NodeInput& input); + + void InputValueHintChanged(const NodeInput& input); + + void GroupAddedInputPassthrough(NodeGroup *group, const NodeInput &input); + + void GroupRemovedInputPassthrough(NodeGroup *group, const NodeInput &input); + + void GroupChangedOutputPassthrough(NodeGroup *group, Node *output); + +protected: + void AddDefaultNode(Node* n) + { + default_nodes_.append(n); + } + + virtual void childEvent(QChildEvent* event) override; + private: QUuid uuid_; @@ -143,6 +197,10 @@ private: MainWindowLayoutInfo layout_info_; + QVector node_children_; + + QVector default_nodes_; + private slots: void ColorManagerValueChanged(const NodeInput& input, const TimeRange& range); diff --git a/app/node/project/CMakeLists.txt b/app/node/project/CMakeLists.txt index b745ea86f..f66293413 100644 --- a/app/node/project/CMakeLists.txt +++ b/app/node/project/CMakeLists.txt @@ -22,9 +22,5 @@ add_subdirectory(serializer) set(OLIVE_SOURCES ${OLIVE_SOURCES} - node/project/project.h - node/project/project.cpp - node/project/projectviewmodel.h - node/project/projectviewmodel.cpp PARENT_SCOPE ) diff --git a/app/node/project/folder/folder.cpp b/app/node/project/folder/folder.cpp index d39c2e9e5..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 { @@ -34,12 +34,18 @@ const QString Folder::kChildInput = QStringLiteral("child_in"); Folder::Folder() { + SetFlag(kIsItem); + AddInput(kChildInput, NodeValue::kNone, InputFlags(kInputFlagArray | kInputFlagNotKeyframable)); } -QIcon Folder::icon() const +QVariant Folder::data(const DataType &d) const { - return icon::Folder; + if (d == ICON) { + return icon::Folder; + } + + return super::data(d); } void Folder::Retranslate() @@ -140,7 +146,7 @@ Project *FolderAddChild::GetRelevantProject() const void FolderAddChild::redo() { int array_index = folder_->InputArraySize(Folder::kChildInput); - folder_->InputArrayAppend(Folder::kChildInput, false); + folder_->InputArrayAppend(Folder::kChildInput); Node::ConnectEdge(child_, NodeInput(folder_, Folder::kChildInput, array_index)); } @@ -158,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/folder/folder.h b/app/node/project/folder/folder.h index 2afb0ac1c..7ed504027 100644 --- a/app/node/project/folder/folder.h +++ b/app/node/project/folder/folder.h @@ -59,7 +59,7 @@ public: return tr("Organize several items into a single collection."); } - virtual QIcon icon() const override; + virtual QVariant data(const DataType &d) const override; virtual void Retranslate() override; @@ -86,11 +86,6 @@ public: return item_children_; } - virtual bool IsItem() const override - { - return true; - } - int index_of_child(Node* item) const { return item_children_.indexOf(item); diff --git a/app/node/project/footage/footage.cpp b/app/node/project/footage/footage.cpp index 4a316c751..87b962459 100644 --- a/app/node/project/footage/footage.cpp +++ b/app/node/project/footage/footage.cpp @@ -46,6 +46,8 @@ Footage::Footage(const QString &filename) : cancelled_(nullptr), total_stream_count_(0) { + SetFlag(kIsItem); + PrependInput(kFilenameInput, NodeValue::kFile, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable)); Clear(); @@ -203,26 +205,6 @@ const QString &Footage::decoder() const return decoder_; } -QIcon Footage::icon() const -{ - if (valid_ && GetTotalStreamCount()) { - // Prioritize video > audio > image - VideoParams s = GetFirstEnabledVideoStream(); - - if (s.is_valid() && s.video_type() != VideoParams::kVideoTypeStill) { - return icon::Video; - } else if (HasEnabledAudioStreams()) { - return icon::Audio; - } else if (s.is_valid() && s.video_type() == VideoParams::kVideoTypeStill) { - return icon::Image; - } else if (HasEnabledSubtitleStreams()) { - return icon::Subtitles; - } - } - - return icon::Error; -} - QString Footage::DescribeVideoStream(const VideoParams ¶ms) { if (params.video_type() == VideoParams::kVideoTypeStill) { @@ -375,26 +357,51 @@ void Footage::LoadFinishedEvent() } } -qint64 Footage::creation_time() const +QVariant Footage::data(const DataType &d) const { - QFileInfo info(filename()); + switch (d) { + case CREATED_TIME: + { + QFileInfo info(filename()); - if (info.exists()) { - return QtUtils::GetCreationDate(info).toSecsSinceEpoch(); + if (info.exists()) { + return QtUtils::GetCreationDate(info).toSecsSinceEpoch(); + } + break; + } + case MODIFIED_TIME: + { + QFileInfo info(filename()); + + if (info.exists()) { + return info.lastModified().toSecsSinceEpoch(); + } + break; + } + case ICON: + { + if (valid_ && GetTotalStreamCount()) { + // Prioritize video > audio > image + VideoParams s = GetFirstEnabledVideoStream(); + + if (s.is_valid() && s.video_type() != VideoParams::kVideoTypeStill) { + return icon::Video; + } else if (HasEnabledAudioStreams()) { + return icon::Audio; + } else if (s.is_valid() && s.video_type() == VideoParams::kVideoTypeStill) { + return icon::Image; + } else if (HasEnabledSubtitleStreams()) { + return icon::Subtitles; + } + } + + return icon::Error; + } + default: + break; } - return 0; -} - -qint64 Footage::mod_time() const -{ - QFileInfo info(filename()); - - if (info.exists()) { - return info.lastModified().toSecsSinceEpoch(); - } - - return 0; + return super::data(d); } void Footage::UpdateTooltip() diff --git a/app/node/project/footage/footage.h b/app/node/project/footage/footage.h index 794e5062d..20c24bab1 100644 --- a/app/node/project/footage/footage.h +++ b/app/node/project/footage/footage.h @@ -153,13 +153,6 @@ public: */ const QString& decoder() const; - virtual QIcon icon() const override; - - virtual bool IsItem() const override - { - return true; - } - static QString DescribeVideoStream(const VideoParams& params); static QString DescribeAudioStream(const AudioParams& params); static QString DescribeSubtitleStream(const SubtitleParams& params); @@ -176,8 +169,7 @@ public: virtual void LoadFinishedEvent() override; - virtual qint64 creation_time() const override; - virtual qint64 mod_time() const override; + virtual QVariant data(const DataType &d) const override; virtual int GetTotalStreamCount() const override { return total_stream_count_; } diff --git a/app/node/project/sequence/sequence.cpp b/app/node/project/sequence/sequence.cpp index df0a970fd..c460d32c0 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 { @@ -34,6 +34,8 @@ const QString Sequence::kTrackInputFormat = QStringLiteral("track_in_%1"); Sequence::Sequence() { + SetFlag(kIsItem); + // Create TrackList instances track_lists_.resize(Track::kCount); @@ -41,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 | kInputFlagIgnoreInvalidations)); TrackList* list = new TrackList(this, static_cast(i), track_input_id); track_lists_.replace(i, list); @@ -71,9 +71,13 @@ void Sequence::add_default_nodes(MultiUndoCommand* command) } } -QIcon Sequence::icon() const +QVariant Sequence::data(const DataType &d) const { - return icon::Sequence; + if (d == ICON) { + return icon::Sequence; + } + + return super::data(d); } QVector Sequence::GetUnlockedTracks() const diff --git a/app/node/project/sequence/sequence.h b/app/node/project/sequence/sequence.h index 4f8b62d04..42b10702a 100644 --- a/app/node/project/sequence/sequence.h +++ b/app/node/project/sequence/sequence.h @@ -59,7 +59,7 @@ public: void add_default_nodes(MultiUndoCommand *command = nullptr); - virtual QIcon icon() const override; + virtual QVariant data(const DataType &d) const override; const QVector &GetTracks() const { @@ -87,11 +87,6 @@ public: static const QString kTrackInputFormat; - virtual bool IsItem() const override - { - return true; - } - protected: virtual void InputConnectedEvent(const QString &input, int element, Node *output) override; diff --git a/app/node/project/serializer/serializer.cpp b/app/node/project/serializer/serializer.cpp index aa4de715b..14cba1098 100644 --- a/app/node/project/serializer/serializer.cpp +++ b/app/node/project/serializer/serializer.cpp @@ -26,6 +26,7 @@ #include "common/xmlutils.h" #include "core.h" +#include "node/group/group.h" #include "serializer190219.h" #include "serializer210528.h" #include "serializer210907.h" diff --git a/app/node/project/serializer/serializer.h b/app/node/project/serializer/serializer.h index 1377b325d..a7f86dfcc 100644 --- a/app/node/project/serializer/serializer.h +++ b/app/node/project/serializer/serializer.h @@ -24,7 +24,7 @@ #include #include "common/define.h" -#include "node/project/project.h" +#include "node/project.h" #include "typeserializer.h" namespace olive { diff --git a/app/node/project/serializer/serializer210528.cpp b/app/node/project/serializer/serializer210528.cpp index 419b2c890..f4b735c70 100644 --- a/app/node/project/serializer/serializer210528.cpp +++ b/app/node/project/serializer/serializer210528.cpp @@ -22,6 +22,7 @@ #include "config/config.h" #include "node/factory.h" +#include "node/group/group.h" namespace olive { diff --git a/app/node/project/serializer/serializer210907.cpp b/app/node/project/serializer/serializer210907.cpp index 8f7250bc2..8633dc55b 100644 --- a/app/node/project/serializer/serializer210907.cpp +++ b/app/node/project/serializer/serializer210907.cpp @@ -22,6 +22,7 @@ #include "config/config.h" #include "node/factory.h" +#include "node/group/group.h" namespace olive { diff --git a/app/node/project/serializer/serializer211228.cpp b/app/node/project/serializer/serializer211228.cpp index 918b8c552..921ee4108 100644 --- a/app/node/project/serializer/serializer211228.cpp +++ b/app/node/project/serializer/serializer211228.cpp @@ -22,6 +22,7 @@ #include "config/config.h" #include "node/factory.h" +#include "node/group/group.h" namespace olive { diff --git a/app/node/project/serializer/serializer220403.cpp b/app/node/project/serializer/serializer220403.cpp index f863f1ae9..851ac8d4d 100644 --- a/app/node/project/serializer/serializer220403.cpp +++ b/app/node/project/serializer/serializer220403.cpp @@ -22,6 +22,7 @@ #include "config/config.h" #include "node/factory.h" +#include "node/group/group.h" namespace olive { @@ -1002,7 +1003,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/panel/project/project.h b/app/panel/project/project.h index 053570793..f5f9468d2 100644 --- a/app/panel/project/project.h +++ b/app/panel/project/project.h @@ -22,7 +22,7 @@ #define PROJECT_PANEL_H #include "footagemanagementpanel.h" -#include "node/project/project.h" +#include "node/project.h" #include "panel/panel.h" #include "widget/projectexplorer/projectexplorer.h" diff --git a/app/render/diskmanager.h b/app/render/diskmanager.h index 09221086a..8dc07787b 100644 --- a/app/render/diskmanager.h +++ b/app/render/diskmanager.h @@ -27,7 +27,7 @@ #include #include "common/define.h" -#include "node/project/project.h" +#include "node/project.h" namespace olive { diff --git a/app/render/playbackcache.cpp b/app/render/playbackcache.cpp index 3b23f043a..b96c65ffb 100644 --- a/app/render/playbackcache.cpp +++ b/app/render/playbackcache.cpp @@ -21,7 +21,7 @@ #include "playbackcache.h" #include "node/output/viewer/viewer.h" -#include "node/project/project.h" +#include "node/project.h" #include "node/project/sequence/sequence.h" #include "render/diskmanager.h" diff --git a/app/render/previewautocacher.cpp b/app/render/previewautocacher.cpp index dbac39eb5..db4466329 100644 --- a/app/render/previewautocacher.cpp +++ b/app/render/previewautocacher.cpp @@ -26,7 +26,7 @@ #include "codec/conformmanager.h" #include "node/input/multicam/multicamnode.h" #include "node/inputdragger.h" -#include "node/project/project.h" +#include "node/project.h" #include "render/diskmanager.h" #include "render/rendermanager.h" @@ -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/previewautocacher.h b/app/render/previewautocacher.h index 02bf99df8..7cabdcd48 100644 --- a/app/render/previewautocacher.h +++ b/app/render/previewautocacher.h @@ -25,11 +25,10 @@ #include "config/config.h" #include "node/color/colormanager/colormanager.h" -#include "node/graph.h" #include "node/group/group.h" #include "node/node.h" #include "node/output/viewer/viewer.h" -#include "node/project/project.h" +#include "node/project.h" #include "render/projectcopier.h" #include "render/renderjobtracker.h" #include "render/renderticket.h" diff --git a/app/render/projectcopier.cpp b/app/render/projectcopier.cpp index 89ff9f1e4..2ff55dae2 100644 --- a/app/render/projectcopier.cpp +++ b/app/render/projectcopier.cpp @@ -20,6 +20,8 @@ #include "projectcopier.h" +#include "node/group/group.h" + namespace olive { ProjectCopier::ProjectCopier(QObject *parent) : @@ -39,12 +41,12 @@ void ProjectCopier::SetProject(Project *project) copy_map_.clear(); graph_update_queue_.clear(); - disconnect(original_, &NodeGraph::NodeAdded, this, &ProjectCopier::QueueNodeAdd); - disconnect(original_, &NodeGraph::NodeRemoved, this, &ProjectCopier::QueueNodeRemove); - disconnect(original_, &NodeGraph::InputConnected, this, &ProjectCopier::QueueEdgeAdd); - disconnect(original_, &NodeGraph::InputDisconnected, this, &ProjectCopier::QueueEdgeRemove); - disconnect(original_, &NodeGraph::ValueChanged, this, &ProjectCopier::QueueValueChange); - disconnect(original_, &NodeGraph::InputValueHintChanged, this, &ProjectCopier::QueueValueHintChange); + disconnect(original_, &Project::NodeAdded, this, &ProjectCopier::QueueNodeAdd); + disconnect(original_, &Project::NodeRemoved, this, &ProjectCopier::QueueNodeRemove); + disconnect(original_, &Project::InputConnected, this, &ProjectCopier::QueueEdgeAdd); + disconnect(original_, &Project::InputDisconnected, this, &ProjectCopier::QueueEdgeRemove); + disconnect(original_, &Project::ValueChanged, this, &ProjectCopier::QueueValueChange); + disconnect(original_, &Project::InputValueHintChanged, this, &ProjectCopier::QueueValueHintChange); } original_ = project; @@ -71,12 +73,12 @@ void ProjectCopier::SetProject(Project *project) UpdateLastSyncedValue(); // Connect signals for future node additions/deletions - connect(original_, &NodeGraph::NodeAdded, this, &ProjectCopier::QueueNodeAdd, Qt::DirectConnection); - connect(original_, &NodeGraph::NodeRemoved, this, &ProjectCopier::QueueNodeRemove, Qt::DirectConnection); - connect(original_, &NodeGraph::InputConnected, this, &ProjectCopier::QueueEdgeAdd, Qt::DirectConnection); - connect(original_, &NodeGraph::InputDisconnected, this, &ProjectCopier::QueueEdgeRemove, Qt::DirectConnection); - connect(original_, &NodeGraph::ValueChanged, this, &ProjectCopier::QueueValueChange, Qt::DirectConnection); - connect(original_, &NodeGraph::InputValueHintChanged, this, &ProjectCopier::QueueValueHintChange, Qt::DirectConnection); + connect(original_, &Project::NodeAdded, this, &ProjectCopier::QueueNodeAdd, Qt::DirectConnection); + connect(original_, &Project::NodeRemoved, this, &ProjectCopier::QueueNodeRemove, Qt::DirectConnection); + connect(original_, &Project::InputConnected, this, &ProjectCopier::QueueEdgeAdd, Qt::DirectConnection); + connect(original_, &Project::InputDisconnected, this, &ProjectCopier::QueueEdgeRemove, Qt::DirectConnection); + connect(original_, &Project::ValueChanged, this, &ProjectCopier::QueueValueChange, Qt::DirectConnection); + connect(original_, &Project::InputValueHintChanged, this, &ProjectCopier::QueueValueHintChange, Qt::DirectConnection); } } diff --git a/app/render/projectcopier.h b/app/render/projectcopier.h index 42fd14daa..89d630872 100644 --- a/app/render/projectcopier.h +++ b/app/render/projectcopier.h @@ -21,7 +21,7 @@ #ifndef PROJECTCOPIER_H #define PROJECTCOPIER_H -#include "node/project/project.h" +#include "node/project.h" namespace olive { @@ -99,7 +99,7 @@ private: std::list graph_update_queue_; QHash copy_map_; - QHash graph_map_; + QHash graph_map_; QVector created_nodes_; JobTime graph_changed_time_; 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/rendermanager.h b/app/render/rendermanager.h index cd5dfe6a4..558478c47 100644 --- a/app/render/rendermanager.h +++ b/app/render/rendermanager.h @@ -26,8 +26,8 @@ #include "config/config.h" #include "colorprocessorcache.h" #include "dialog/rendercancel/rendercancel.h" -#include "node/graph.h" #include "node/output/viewer/viewer.h" +#include "node/project.h" #include "node/traverser.h" #include "render/previewautocacher.h" #include "render/renderer.h" diff --git a/app/render/renderprocessor.cpp b/app/render/renderprocessor.cpp index 7d146ae9b..05a79b8c8 100644 --- a/app/render/renderprocessor.cpp +++ b/app/render/renderprocessor.cpp @@ -28,7 +28,7 @@ #include "audio/audioprocessor.h" #include "node/block/clip/clip.h" #include "node/block/transition/transition.h" -#include "node/project/project.h" +#include "node/project.h" #include "rendermanager.h" namespace olive { @@ -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/precache/precachetask.cpp b/app/task/precache/precachetask.cpp index b0145474c..e355251ca 100644 --- a/app/task/precache/precachetask.cpp +++ b/app/task/precache/precachetask.cpp @@ -20,7 +20,7 @@ #include "precachetask.h" -#include "node/project/project.h" +#include "node/project.h" namespace olive { diff --git a/app/task/project/import/import.cpp b/app/task/project/import/import.cpp index 91572757b..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 { @@ -157,9 +157,6 @@ void ProjectImportTask::ValidateImageSequence(Footage *footage, QFileInfoList& i QString previous_img_fn = Decoder::TransformImageSequenceFileName(footage->filename(), ind - 1); QString next_img_fn = Decoder::TransformImageSequenceFileName(footage->filename(), ind + 1); - // See if the same decoder can retrieve surrounding files - DecoderPtr decoder = Decoder::CreateFromID(footage->decoder()); - Footage* previous_file = new Footage(previous_img_fn); Footage* next_file = new Footage(next_img_fn); diff --git a/app/task/project/import/import.h b/app/task/project/import/import.h index f02afea9e..daed1e45c 100644 --- a/app/task/project/import/import.h +++ b/app/task/project/import/import.h @@ -25,8 +25,8 @@ #include #include "codec/decoder.h" -#include "node/project/projectviewmodel.h" #include "task/task.h" +#include "widget/projectexplorer/projectviewmodel.h" namespace olive { diff --git a/app/task/project/load/loadbasetask.h b/app/task/project/load/loadbasetask.h index 74c68a4f7..31970f044 100644 --- a/app/task/project/load/loadbasetask.h +++ b/app/task/project/load/loadbasetask.h @@ -21,7 +21,7 @@ #ifndef PROJECTLOADBASETASK_H #define PROJECTLOADBASETASK_H -#include "node/project/project.h" +#include "node/project.h" #include "task/task.h" namespace olive { diff --git a/app/task/project/save/save.h b/app/task/project/save/save.h index 642d00e7f..f3d8cc9aa 100644 --- a/app/task/project/save/save.h +++ b/app/task/project/save/save.h @@ -21,7 +21,7 @@ #ifndef PROJECTSAVEMANAGER_H #define PROJECTSAVEMANAGER_H -#include "node/project/project.h" +#include "node/project.h" #include "task/task.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 99% rename from app/widget/timelinewidget/undo/timelineundopointer.cpp rename to app/timeline/timelineundopointer.cpp index f46f5a47e..864ce468b 100644 --- a/app/widget/timelinewidget/undo/timelineundopointer.cpp +++ b/app/timeline/timelineundopointer.cpp @@ -22,7 +22,7 @@ #include "node/block/gap/gap.h" #include "node/block/transition/transition.h" -#include "node/graph.h" +#include "node/project.h" #include "timelineundocommon.h" namespace olive { 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 98% rename from app/widget/timelinewidget/undo/timelineundoworkarea.h rename to app/timeline/timelineundoworkarea.h index f83601747..ae50b30f0 100644 --- a/app/widget/timelinewidget/undo/timelineundoworkarea.h +++ b/app/timeline/timelineundoworkarea.h @@ -21,7 +21,7 @@ #ifndef TIMELINEUNDOWORKAREA_H #define TIMELINEUNDOWORKAREA_H -#include "node/project/project.h" +#include "node/project.h" namespace olive { 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 0811f416f..998e1664b 100644 --- a/app/widget/keyframeview/keyframeview.cpp +++ b/app/widget/keyframeview/keyframeview.cpp @@ -27,11 +27,12 @@ #include "common/qtutils.h" #include "dialog/keyframeproperties/keyframeproperties.h" #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/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index a542fcc56..296abf392 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -24,6 +24,7 @@ #include #include +#include "node/group/group.h" #include "node/node.h" #include "node/project/serializer/serializer.h" #include "nodeparamviewcontext.h" 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 a2438bddd..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 { @@ -157,7 +157,7 @@ void NodeParamViewContext::AddEffectMenuItemTriggered(QAction *a) NodeInput new_node_input = n->GetEffectInput(); MultiUndoCommand *command = new MultiUndoCommand(); - QVector graphs_added_to; + QVector graphs_added_to; foreach (Node *ctx, contexts_) { NodeInput ctx_input = ctx->GetEffectInput(); diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index 7d0f6dc7a..41d09db57 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -26,8 +26,9 @@ #include "common/qtutils.h" #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 { @@ -443,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)); - real_input.node()->InputArrayAppend(real_input.input(), true); + Core::instance()->undo_stack()->push(new NodeArrayInsertCommand(real_input.node(), real_input.input(), real_input.GetArraySize()+1)); break; } } @@ -455,7 +456,7 @@ void NodeParamViewItemBody::ArrayInsertClicked() if (it.value().array_insert_btn == sender()) { // Found our input and element NodeInput ic = NodeGroup::ResolveInput(it.key()); - ic.node()->InputArrayInsert(ic.input(), ic.element(), true); + Core::instance()->undo_stack()->push(new NodeArrayInsertCommand(ic.node(), ic.input(), ic.element())); break; } } @@ -467,7 +468,7 @@ void NodeParamViewItemBody::ArrayRemoveClicked() if (it.value().array_remove_btn == sender()) { // Found our input and element NodeInput ic = NodeGroup::ResolveInput(it.key()); - ic.node()->InputArrayRemove(ic.input(), ic.element(), true); + 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 a3e448fda..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_, false); -} - -void NodeParamArrayAppendCommand::undo() -{ - node_->InputArrayRemoveLast(input_, false); -} - -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 693e66bd4..a73de836a 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -28,11 +28,12 @@ #include "common/qtutils.h" #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/nodeview.h b/app/widget/nodeview/nodeview.h index 01e1dd487..fd497f338 100644 --- a/app/widget/nodeview/nodeview.h +++ b/app/widget/nodeview/nodeview.h @@ -25,7 +25,7 @@ #include #include "core.h" -#include "node/graph.h" +#include "node/group/group.h" #include "nodeviewedge.h" #include "nodeviewcontext.h" #include "nodeviewminimap.h" diff --git a/app/widget/nodeview/nodeviewcontext.cpp b/app/widget/nodeview/nodeviewcontext.cpp index 4f0be5acf..9f1dbc755 100644 --- a/app/widget/nodeview/nodeviewcontext.cpp +++ b/app/widget/nodeview/nodeviewcontext.cpp @@ -9,8 +9,9 @@ #include "core.h" #include "node/block/block.h" -#include "node/graph.h" +#include "node/group/group.h" #include "node/output/track/track.h" +#include "node/project.h" #include "node/project/sequence/sequence.h" #include "nodeviewitem.h" #include "ui/colorcoding.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/nodeviewscene.h b/app/widget/nodeview/nodeviewscene.h index 6a43becf2..d466e7d41 100644 --- a/app/widget/nodeview/nodeviewscene.h +++ b/app/widget/nodeview/nodeviewscene.h @@ -24,7 +24,7 @@ #include #include -#include "node/graph.h" +#include "node/project.h" #include "nodeviewcontext.h" #include "nodeviewedge.h" #include "nodeviewitem.h" @@ -74,7 +74,7 @@ public slots: private: QHash context_map_; - NodeGraph* graph_; + Project* graph_; NodeViewCommon::FlowDirection direction_; diff --git a/app/widget/nodeview/nodeviewundo.cpp b/app/widget/nodeview/nodeviewundo.cpp deleted file mode 100644 index 03ff5a372..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(NodeGraph *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 f5508abb2..000000000 --- a/app/widget/nodeview/nodeviewundo.h +++ /dev/null @@ -1,386 +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/graph.h" -#include "node/node.h" -#include "node/project/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(NodeGraph* 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_; - - NodeGraph* 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 dynamic_cast(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_; - NodeGraph* 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; - NodeGraph *removed_from_graph; - }; - - QVector removed_nodes_; - - QObject memory_manager_; - -}; - -} - -#endif // NODEVIEWUNDO_H diff --git a/app/widget/projectexplorer/CMakeLists.txt b/app/widget/projectexplorer/CMakeLists.txt index 2de828952..35445facf 100644 --- a/app/widget/projectexplorer/CMakeLists.txt +++ b/app/widget/projectexplorer/CMakeLists.txt @@ -16,22 +16,24 @@ set(OLIVE_SOURCES ${OLIVE_SOURCES} - widget/projectexplorer/projectexplorer.h widget/projectexplorer/projectexplorer.cpp - widget/projectexplorer/projectexplorertreeview.h - widget/projectexplorer/projectexplorertreeview.cpp - widget/projectexplorer/projectexplorerlistview.h - widget/projectexplorer/projectexplorerlistview.cpp - widget/projectexplorer/projectexplorerlistviewbase.h - widget/projectexplorer/projectexplorerlistviewbase.cpp - widget/projectexplorer/projectexplorerlistviewitemdelegate.h - widget/projectexplorer/projectexplorerlistviewitemdelegate.cpp - widget/projectexplorer/projectexplorericonview.h + widget/projectexplorer/projectexplorer.h widget/projectexplorer/projectexplorericonview.cpp - widget/projectexplorer/projectexplorericonviewitemdelegate.h + widget/projectexplorer/projectexplorericonview.h widget/projectexplorer/projectexplorericonviewitemdelegate.cpp - widget/projectexplorer/projectexplorernavigation.h + widget/projectexplorer/projectexplorericonviewitemdelegate.h + widget/projectexplorer/projectexplorerlistview.cpp + widget/projectexplorer/projectexplorerlistview.h + widget/projectexplorer/projectexplorerlistviewbase.cpp + widget/projectexplorer/projectexplorerlistviewbase.h + widget/projectexplorer/projectexplorerlistviewitemdelegate.cpp + widget/projectexplorer/projectexplorerlistviewitemdelegate.h widget/projectexplorer/projectexplorernavigation.cpp + widget/projectexplorer/projectexplorernavigation.h + widget/projectexplorer/projectexplorertreeview.cpp + widget/projectexplorer/projectexplorertreeview.h widget/projectexplorer/projectexplorerundo.h + widget/projectexplorer/projectviewmodel.cpp + widget/projectexplorer/projectviewmodel.h PARENT_SCOPE ) 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/projectexplorer.h b/app/widget/projectexplorer/projectexplorer.h index c03fc2e67..851e26c25 100644 --- a/app/widget/projectexplorer/projectexplorer.h +++ b/app/widget/projectexplorer/projectexplorer.h @@ -26,8 +26,8 @@ #include #include -#include "node/project/project.h" -#include "node/project/projectviewmodel.h" +#include "node/project.h" +#include "projectviewmodel.h" #include "widget/projectexplorer/projectexplorericonview.h" #include "widget/projectexplorer/projectexplorerlistview.h" #include "widget/projectexplorer/projectexplorertreeview.h" diff --git a/app/node/project/projectviewmodel.cpp b/app/widget/projectexplorer/projectviewmodel.cpp similarity index 98% rename from app/node/project/projectviewmodel.cpp rename to app/widget/projectexplorer/projectviewmodel.cpp index c7e558249..28223f586 100644 --- a/app/node/project/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 { @@ -140,13 +139,13 @@ QVariant ProjectViewModel::data(const QModelIndex &index, int role) const case kName: return internal_item->GetLabel(); case kDuration: - return internal_item->duration(); + return internal_item->data(Node::DURATION); case kRate: - return internal_item->rate(); + return internal_item->data(Node::FREQUENCY_RATE); case kLastModified: case kCreatedTime: { - qint64 using_time = (column_type == kLastModified) ? internal_item->mod_time() : internal_item->creation_time(); + qint64 using_time = (column_type == kLastModified) ? internal_item->data(Node::MODIFIED_TIME).toLongLong() : internal_item->data(Node::CREATED_TIME).toLongLong(); if (using_time == 0) { // 0 is the null value, return nothing @@ -178,7 +177,7 @@ QVariant ProjectViewModel::data(const QModelIndex &index, int role) const case Qt::DecorationRole: // If this is the first column, return the Item's icon if (column_type == kName) { - return internal_item->icon(); + return internal_item->data(Node::ICON); } break; case Qt::ToolTipRole: diff --git a/app/node/project/projectviewmodel.h b/app/widget/projectexplorer/projectviewmodel.h similarity index 99% rename from app/node/project/projectviewmodel.h rename to app/widget/projectexplorer/projectviewmodel.h index c4fd74bc5..b47b16d8c 100644 --- a/app/node/project/projectviewmodel.h +++ b/app/widget/projectexplorer/projectviewmodel.h @@ -23,9 +23,9 @@ #include -#include "project.h" -#include "undo/undocommand.h" #include "node/block/block.h" +#include "node/project.h" +#include "undo/undocommand.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 f609d1da9..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 { @@ -724,7 +723,7 @@ void TimelineWidget::DeleteInToOut(bool ripple) gap->set_length_and_media_out(GetConnectedNode()->GetWorkArea()->length()); - command->add_child(new NodeAddCommand(static_cast(track->parent()), + command->add_child(new NodeAddCommand(static_cast(track->parent()), gap)); command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track->type()), diff --git a/app/widget/timelinewidget/tool/add.cpp b/app/widget/timelinewidget/tool/add.cpp index a765b0d73..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 { @@ -134,7 +134,7 @@ Node *AddTool::CreateAddableClip(MultiUndoCommand *command, Sequence *sequence, } clip->set_length_and_media_out(length); - NodeGraph* graph = sequence->parent(); + Project* graph = sequence->parent(); command->add_child(new NodeAddCommand(graph, clip)); command->add_child(new NodeSetPositionCommand(clip, clip, QPointF(0, 0))); diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index b09e66752..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" @@ -302,7 +301,7 @@ void ImportTool::DropGhosts(bool insert, MultiUndoCommand *parent_command) command->add_child(c); } - NodeGraph* dst_graph = nullptr; + Project* dst_graph = nullptr; Sequence* sequence = this->sequence(); bool open_sequence = false; 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 73a89d02c..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_); @@ -110,7 +110,7 @@ void TransitionTool::MouseRelease(TimelineViewMouseEvent *event) MultiUndoCommand* command = new MultiUndoCommand(); // Place transition in place - command->add_child(new NodeAddCommand(static_cast(parent()->GetConnectedNode()->parent()), + command->add_child(new NodeAddCommand(parent()->GetConnectedNode()->parent(), transition)); command->add_child(new NodeSetPositionCommand(transition, transition, QPointF(0, 0))); @@ -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/footageviewer.cpp b/app/widget/viewer/footageviewer.cpp index 05373b0f2..4d77cf341 100644 --- a/app/widget/viewer/footageviewer.cpp +++ b/app/widget/viewer/footageviewer.cpp @@ -24,7 +24,7 @@ #include #include "config/config.h" -#include "node/project/project.h" +#include "node/project.h" namespace olive { diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 19cac1d1b..791e0454a 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -37,7 +37,8 @@ #include "core.h" #include "node/block/gap/gap.h" #include "node/generator/shape/shapenodebase.h" -#include "node/project/project.h" +#include "node/nodeundo.h" +#include "node/project.h" #include "panel/multicam/multicampanel.h" #include "panel/panelmanager.h" #include "render/rendermanager.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 f718a1e3c..6722ba6ae 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 { diff --git a/app/window/mainwindow/mainwindow.h b/app/window/mainwindow/mainwindow.h index 46d515197..a624c965e 100644 --- a/app/window/mainwindow/mainwindow.h +++ b/app/window/mainwindow/mainwindow.h @@ -25,7 +25,7 @@ #include #include "mainwindowlayoutinfo.h" -#include "node/project/project.h" +#include "node/project.h" #include "panel/multicam/multicampanel.h" #include "panel/panelmanager.h" #include "panel/audiomonitor/audiomonitor.h"