diff --git a/app/core.cpp b/app/core.cpp index 18464120e..960193084 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -342,11 +342,10 @@ void Core::DialogPreferencesShow() void Core::DialogExportShow() { - ViewerOutput* viewer; - TimelinePoints* points; + ViewerOutput* viewer = GetSequenceToExport(); - if (GetSequenceToExport(&viewer, &points) && viewer) { - ExportDialog* ed = new ExportDialog(viewer, points, main_window_); + if (viewer) { + ExportDialog* ed = new ExportDialog(viewer, main_window_); connect(ed, &ExportDialog::finished, ed, &ExportDialog::deleteLater); ed->open(); } @@ -752,7 +751,7 @@ void Core::SaveProjectInternal(Project* project, const QString& override_filenam task_dialog->open(); } -bool Core::GetSequenceToExport(ViewerOutput** viewer, TimelinePoints** points) +ViewerOutput* Core::GetSequenceToExport() { // First try the most recently focused time based window TimeBasedPanel* time_panel = PanelManager::instance()->MostRecentlyFocused(); @@ -770,9 +769,7 @@ bool Core::GetSequenceToExport(ViewerOutput** viewer, TimelinePoints** points) tr("This Sequence is empty. There is nothing to export."), QMessageBox::Ok); } else { - *viewer = time_panel->GetConnectedViewer(); - *points = time_panel->GetConnectedTimelinePoints(); - return true; + return time_panel->GetConnectedViewer(); } } else { QMessageBox::critical(main_window_, @@ -781,7 +778,7 @@ bool Core::GetSequenceToExport(ViewerOutput** viewer, TimelinePoints** points) QMessageBox::Ok); } - return false; + return nullptr; } QString Core::GetAutoRecoveryIndexFilename() diff --git a/app/core.h b/app/core.h index 8275b188d..7d9526947 100644 --- a/app/core.h +++ b/app/core.h @@ -496,7 +496,7 @@ private: /** * @brief Retrieves the currently most active sequence for exporting */ - bool GetSequenceToExport(ViewerOutput **viewer, TimelinePoints **points); + ViewerOutput *GetSequenceToExport(); static QString GetAutoRecoveryIndexFilename(); diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index bf1971c21..fa1f8772c 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -39,10 +39,9 @@ namespace olive { -ExportDialog::ExportDialog(ViewerOutput *viewer_node, TimelinePoints *points, QWidget *parent) : +ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) : QDialog(parent), - viewer_node_(viewer_node), - timeline_points_(points) + viewer_node_(viewer_node) { QHBoxLayout* layout = new QHBoxLayout(this); @@ -105,7 +104,7 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, TimelinePoints *points, QW range_combobox_ = new QComboBox(); range_combobox_->addItem(tr("Entire Sequence")); range_combobox_->addItem(tr("In to Out")); - range_combobox_->setEnabled(timeline_points_ && timeline_points_->workarea()->enabled()); + range_combobox_->setEnabled(viewer_node_->GetTimelinePoints()->workarea()->enabled()); preferences_layout->addWidget(range_combobox_, row, 1, 1, 3); @@ -229,7 +228,7 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, TimelinePoints *points, QW // Set viewer to view the node preview_viewer_->ConnectViewerNode(viewer_node_); - preview_viewer_->ruler()->ConnectTimelinePoints(timeline_points_); + preview_viewer_->ruler()->ConnectTimelinePoints(viewer_node_->GetTimelinePoints()); preview_viewer_->SetColorMenuEnabled(false); preview_viewer_->SetColorTransform(video_tab_->CurrentOCIOColorSpace()); } @@ -462,10 +461,9 @@ ExportParams ExportDialog::GenerateParams() const params.SetFilename(filename_edit_->text().trimmed()); params.SetExportLength(viewer_node_->GetLength()); - if (range_combobox_->isEnabled() && range_combobox_->currentIndex() == kRangeInToOut) { - // Assume if this combobox is enabled, that we have timeline points - a check that we make - // in this dialog's constructor - params.set_custom_range(timeline_points_->workarea()->range()); + if (range_combobox_->currentIndex() == kRangeInToOut) { + // Assume if this combobox is enabled, workarea is enabled - a check that we make in this dialog's constructor + params.set_custom_range(viewer_node_->GetTimelinePoints()->workarea()->range()); } if (video_tab_->scaling_method_combobox()->isEnabled()) { @@ -500,12 +498,13 @@ void ExportDialog::UpdateViewerDimensions() preview_viewer_->SetViewerResolution(static_cast(video_tab_->width_slider()->GetValue()), static_cast(video_tab_->height_slider()->GetValue())); - QMatrix4x4 transform = - ExportParams::GenerateMatrix(static_cast(video_tab_->scaling_method_combobox()->currentData().toInt()), - viewer_node_->video_params().width(), - viewer_node_->video_params().height(), - static_cast(video_tab_->width_slider()->GetValue()), - static_cast(video_tab_->height_slider()->GetValue())); + QMatrix4x4 transform = ExportParams::GenerateMatrix( + static_cast(video_tab_->scaling_method_combobox()->currentData().toInt()), + viewer_node_->video_params().width(), + viewer_node_->video_params().height(), + static_cast(video_tab_->width_slider()->GetValue()), + static_cast(video_tab_->height_slider()->GetValue()) + ); preview_viewer_->SetMatrix(transform); } diff --git a/app/dialog/export/export.h b/app/dialog/export/export.h index 179485f74..74b920db5 100644 --- a/app/dialog/export/export.h +++ b/app/dialog/export/export.h @@ -40,7 +40,7 @@ class ExportDialog : public QDialog { Q_OBJECT public: - ExportDialog(ViewerOutput* viewer_node, TimelinePoints* points, QWidget* parent = nullptr); + ExportDialog(ViewerOutput* viewer_node, QWidget* parent = nullptr); protected: virtual void closeEvent(QCloseEvent *e) override; @@ -52,7 +52,6 @@ private: ExportParams GenerateParams() const; ViewerOutput* viewer_node_; - TimelinePoints* timeline_points_; ExportFormat::Format previously_selected_format_; diff --git a/app/node/node.cpp b/app/node/node.cpp index 94c82f332..dcd5704d1 100644 --- a/app/node/node.cpp +++ b/app/node/node.cpp @@ -116,7 +116,11 @@ void Node::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, uint versi } } } else if (reader->name() == QStringLiteral("custom")) { - LoadInternal(reader, xml_node_data, version, cancelled); + while (XMLReadNextStartElement(reader)) { + if (!LoadCustom(reader, xml_node_data, version, cancelled)) { + reader->skipCurrentElement(); + } + } } else if (reader->name() == QStringLiteral("connections")) { // Load connections while (XMLReadNextStartElement(reader)) { @@ -197,7 +201,7 @@ void Node::Save(QXmlStreamWriter *writer) const writer->writeEndElement(); // connections writer->writeStartElement(QStringLiteral("custom")); - SaveInternal(writer); + SaveCustom(writer); writer->writeEndElement(); // custom } @@ -1376,12 +1380,12 @@ void Node::IgnoreHashingFrom(const QString &input_id) ignore_when_hashing_.append(input_id); } -void Node::LoadInternal(QXmlStreamReader *reader, XMLNodeData &, uint, const QAtomicInt*) +bool Node::LoadCustom(QXmlStreamReader *, XMLNodeData &, uint, const QAtomicInt*) { - reader->skipCurrentElement(); + return false; } -void Node::SaveInternal(QXmlStreamWriter *) const +void Node::SaveCustom(QXmlStreamWriter *) const { } diff --git a/app/node/node.h b/app/node/node.h index 5f9c8134a..14990f9c6 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -808,9 +808,9 @@ protected: void IgnoreHashingFrom(const QString& input_id); - virtual void LoadInternal(QXmlStreamReader* reader, XMLNodeData& xml_node_data, uint version, const QAtomicInt* cancelled); + virtual bool LoadCustom(QXmlStreamReader* reader, XMLNodeData& xml_node_data, uint version, const QAtomicInt* cancelled); - virtual void SaveInternal(QXmlStreamWriter* writer) const; + virtual void SaveCustom(QXmlStreamWriter* writer) const; enum GizmoScaleHandles { kGizmoScaleTopLeft, diff --git a/app/node/output/track/track.cpp b/app/node/output/track/track.cpp index 2b116c8c6..d6bf3a3f1 100644 --- a/app/node/output/track/track.cpp +++ b/app/node/output/track/track.cpp @@ -29,6 +29,8 @@ namespace olive { +#define super Node + const double Track::kTrackHeightDefault = 3.0; const double Track::kTrackHeightMinimum = 1.5; const double Track::kTrackHeightInterval = 0.5; @@ -143,18 +145,17 @@ void Track::SetTrackHeight(const double &height) emit TrackHeightChangedInPixels(GetTrackHeightInPixels()); } -void Track::LoadInternal(QXmlStreamReader *reader, XMLNodeData &, uint , const QAtomicInt* ) +bool Track::LoadCustom(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled) { - while (XMLReadNextStartElement(reader)) { - if (reader->name() == QStringLiteral("height")) { - SetTrackHeight(reader->readElementText().toDouble()); - } else { - reader->skipCurrentElement(); - } + if (reader->name() == QStringLiteral("height")) { + SetTrackHeight(reader->readElementText().toDouble()); + return true; + } else { + return super::LoadCustom(reader, xml_node_data, version, cancelled); } } -void Track::SaveInternal(QXmlStreamWriter *writer) const +void Track::SaveCustom(QXmlStreamWriter *writer) const { writer->writeTextElement(QStringLiteral("height"), QString::number(GetTrackHeight())); } diff --git a/app/node/output/track/track.h b/app/node/output/track/track.h index 7b32e36e1..8eb1f5ce4 100644 --- a/app/node/output/track/track.h +++ b/app/node/output/track/track.h @@ -335,9 +335,9 @@ signals: void BlocksRefreshed(); protected: - virtual void LoadInternal(QXmlStreamReader* reader, XMLNodeData& xml_node_data, uint version, const QAtomicInt* cancelled) override; + virtual bool LoadCustom(QXmlStreamReader* reader, XMLNodeData& xml_node_data, uint version, const QAtomicInt* cancelled) override; - virtual void SaveInternal(QXmlStreamWriter* writer) const override; + virtual void SaveCustom(QXmlStreamWriter* writer) const override; virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output) override; diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index 0b70b65a6..c27a9ebb4 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -354,4 +354,22 @@ void ViewerOutput::set_parameters_from_footage(const QVector footage) } } +bool ViewerOutput::LoadCustom(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt *cancelled) +{ + if (reader->name() == QStringLiteral("points")) { + timeline_points_.Load(reader); + return true; + } else { + return LoadCustom(reader, xml_node_data, version, cancelled); + } +} + +void ViewerOutput::SaveCustom(QXmlStreamWriter *writer) const +{ + // Write TimelinePoints + writer->writeStartElement(QStringLiteral("points")); + timeline_points_.Save(writer); + writer->writeEndElement(); // points +} + } diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index 5acb22ad8..8393a7017 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -24,15 +24,17 @@ #include "common/rational.h" #include "node/node.h" #include "node/output/track/track.h" -#include "project/item/footage/footage.h" #include "render/audioparams.h" #include "render/audioplaybackcache.h" #include "render/framehashcache.h" #include "render/videoparams.h" #include "render/videoparams.h" +#include "timeline/timelinepoints.h" namespace olive { +class Footage; + /** * @brief A bridge between a node system and a ViewerPanel * @@ -97,6 +99,11 @@ public: return &audio_playback_cache_; } + TimelinePoints* GetTimelinePoints() + { + return &timeline_points_; + } + virtual void Retranslate() override; virtual void BeginOperation() override; @@ -143,6 +150,10 @@ protected: virtual void InputValueChangedEvent(const QString& input, int element) override; + virtual bool LoadCustom(QXmlStreamReader* reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled) override; + + virtual void SaveCustom(QXmlStreamWriter *writer) const override; + private: rational last_length_; @@ -154,6 +165,8 @@ private: VideoParams cached_video_params_; + TimelinePoints timeline_points_; + }; } diff --git a/app/panel/timebased/timebased.h b/app/panel/timebased/timebased.h index b090b786e..bff649439 100644 --- a/app/panel/timebased/timebased.h +++ b/app/panel/timebased/timebased.h @@ -43,11 +43,6 @@ public: return widget_->GetConnectedNode(); } - TimelinePoints* GetConnectedTimelinePoints() const - { - return widget_->GetConnectedTimelinePoints(); - } - TimeRuler* ruler() const { return widget_->ruler(); diff --git a/app/project/item/footage/footage.cpp b/app/project/item/footage/footage.cpp index 35e076e24..ab81bf6a1 100644 --- a/app/project/item/footage/footage.cpp +++ b/app/project/item/footage/footage.cpp @@ -38,7 +38,7 @@ namespace olive { const QString Footage::kFilenameInput = QStringLiteral("file_in"); const QString Footage::kStreamPropertiesFormat = QStringLiteral("stream_properties:%1"); -#define super Node +#define super ViewerOutput Footage::Footage(const QString &filename) : cancelled_(nullptr) @@ -63,33 +63,21 @@ void Footage::Retranslate() } } -void Footage::LoadInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled) +bool Footage::LoadCustom(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled) { - Q_UNUSED(xml_node_data) - Q_UNUSED(version) - - while (XMLReadNextStartElement(reader)) { - if (cancelled && *cancelled) { - return; - } - - if (reader->name() == QStringLiteral("timestamp")) { - set_timestamp(reader->readElementText().toLongLong()); - } else if (reader->name() == QStringLiteral("points")) { - TimelinePoints::Load(reader); - } else { - reader->skipCurrentElement(); - } + if (reader->name() == QStringLiteral("timestamp")) { + set_timestamp(reader->readElementText().toLongLong()); + return true; + } else { + return super::LoadCustom(reader, xml_node_data, version, cancelled); } } -void Footage::SaveInternal(QXmlStreamWriter *writer) const +void Footage::SaveCustom(QXmlStreamWriter *writer) const { - writer->writeTextElement(QStringLiteral("timestamp"), QString::number(timestamp_)); + super::SaveCustom(writer); - writer->writeStartElement(QStringLiteral("points")); - TimelinePoints::Save(writer); - writer->writeEndElement(); // points + writer->writeTextElement(QStringLiteral("timestamp"), QString::number(timestamp_)); } void Footage::InputValueChangedEvent(const QString &input, int element) diff --git a/app/project/item/footage/footage.h b/app/project/item/footage/footage.h index 56eb3ba76..88b61dd91 100644 --- a/app/project/item/footage/footage.h +++ b/app/project/item/footage/footage.h @@ -26,7 +26,7 @@ #include "common/rational.h" #include "footagedescription.h" -#include "node/node.h" +#include "node/output/viewer/viewer.h" #include "render/audioparams.h" #include "render/videoparams.h" #include "stream.h" @@ -41,7 +41,7 @@ namespace olive { * Footage objects store a list of Stream objects which store the majority of video/audio metadata. These streams * are identical to the stream data in the files. */ -class Footage : public Node, public TimelinePoints +class Footage : public ViewerOutput { Q_OBJECT public: @@ -140,61 +140,6 @@ public: cancelled_ = c; } - class StreamReference - { - public: - StreamReference() - { - type_ = Stream::kUnknown; - index_ = -1; - } - - StreamReference(Stream::Type type, int index) - { - type_ = type; - index_ = index; - } - - bool operator==(const StreamReference& rhs) const - { - return type_ == rhs.type_ && index_ == rhs.index_; - } - - bool operator<(const StreamReference& rhs) const - { - if (type_ != rhs.type_) { - return type_ < rhs.type_; - } - - return index_ < rhs.index_; - } - - bool IsValid() const - { - return type_ != Stream::kUnknown && index_ >= 0; - } - - void Reset() - { - *this = StreamReference(); - } - - Stream::Type type() const - { - return type_; - } - - int index() const - { - return index_; - } - - private: - Stream::Type type_; - int index_; - - }; - static QString GetStringFromReference(Stream::Type type, int index); static QString GetStringFromReference(const StreamReference& ref) { @@ -293,12 +238,12 @@ protected: /** * @brief Load function */ - virtual void LoadInternal(QXmlStreamReader* reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt *cancelled) override; + virtual bool LoadCustom(QXmlStreamReader* reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt *cancelled) override; /** * @brief Save function */ - virtual void SaveInternal(QXmlStreamWriter *writer) const override; + virtual void SaveCustom(QXmlStreamWriter *writer) const override; virtual void InputValueChangedEvent(const QString &input, int element) override; diff --git a/app/project/item/footage/stream.h b/app/project/item/footage/stream.h deleted file mode 100644 index 0d9251ec7..000000000 --- a/app/project/item/footage/stream.h +++ /dev/null @@ -1,41 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2020 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 STREAM_H -#define STREAM_H - -namespace olive { - -class Stream -{ -public: - enum Type { - kUnknown = -1, - kVideo, - kAudio, - kData, - kSubtitle, - kAttachment - }; -}; - -} - -#endif // STREAM_H diff --git a/app/project/item/sequence/sequence.cpp b/app/project/item/sequence/sequence.cpp index 1203b6427..3f4fe07b7 100644 --- a/app/project/item/sequence/sequence.cpp +++ b/app/project/item/sequence/sequence.cpp @@ -178,27 +178,4 @@ void Sequence::UpdateTrackCache() } } -void Sequence::LoadInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt *cancelled) -{ - Q_UNUSED(xml_node_data) - Q_UNUSED(version) - Q_UNUSED(cancelled) - - while (XMLReadNextStartElement(reader)) { - if (reader->name() == QStringLiteral("points")) { - timeline_points_.Load(reader); - } else { - reader->skipCurrentElement(); - } - } -} - -void Sequence::SaveInternal(QXmlStreamWriter *writer) const -{ - // Write TimelinePoints - writer->writeStartElement(QStringLiteral("points")); - timeline_points_.Save(writer); - writer->writeEndElement(); // points -} - } diff --git a/app/project/item/sequence/sequence.h b/app/project/item/sequence/sequence.h index 2608b424f..7f7ec9315 100644 --- a/app/project/item/sequence/sequence.h +++ b/app/project/item/sequence/sequence.h @@ -91,21 +91,12 @@ public: static const QString kTrackInputFormat; - TimelinePoints* timeline_points() - { - return &timeline_points_; - } - virtual bool IsItem() const override { return true; } protected: - virtual void LoadInternal(QXmlStreamReader* reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled) override; - - virtual void SaveInternal(QXmlStreamWriter *writer) const override; - virtual void ShiftAudioEvent(const rational &from, const rational &to) override; virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override; @@ -123,8 +114,6 @@ private: QVector track_cache_; - TimelinePoints timeline_points_; - private slots: void UpdateTrackCache(); diff --git a/app/project/project.cpp b/app/project/project.cpp index 979f87f24..7730bdcfc 100644 --- a/app/project/project.cpp +++ b/app/project/project.cpp @@ -51,13 +51,6 @@ Project::Project() : settings_->SetPosition(QPointF(2, 0)); AddDefaultNode(settings_); - // Viewer node for connecting with the footage viewer - footage_viewer_ = new ViewerOutput(); - footage_viewer_->setParent(this); - footage_viewer_->SetLabel(tr("Footage Viewer")); - footage_viewer_->SetPosition(QPointF(3, 0)); - AddDefaultNode(footage_viewer_); - // Folder root for project root_ = new Folder(); root_->setParent(this); @@ -295,6 +288,7 @@ void Project::RegenerateUuid() void Project::ColorManagerValueChanged(const NodeInput &input, const TimeRange &range) { + Q_UNUSED(input) Q_UNUSED(range) QVector footage = root()->ListChildrenOfType(); diff --git a/app/project/project.h b/app/project/project.h index 022531034..8a432a4e8 100644 --- a/app/project/project.h +++ b/app/project/project.h @@ -74,11 +74,6 @@ public: QString cache_path() const; - ViewerOutput* footage_viewer() - { - return footage_viewer_; - } - const QUuid& GetUuid() const { return uuid_; @@ -102,8 +97,6 @@ private: ProjectSettingsNode* settings_; - ViewerOutput* footage_viewer_; - bool is_modified_; bool autorecovery_saved_; diff --git a/app/task/project/saveotio/saveotio.cpp b/app/task/project/saveotio/saveotio.cpp index 850d7385c..6da4b2f4d 100644 --- a/app/task/project/saveotio/saveotio.cpp +++ b/app/task/project/saveotio/saveotio.cpp @@ -29,6 +29,7 @@ #include #include "node/block/transition/transition.h" +#include "project/item/footage/footage.h" namespace olive { diff --git a/app/widget/timebased/timebasedwidget.cpp b/app/widget/timebased/timebasedwidget.cpp index 8236e57e9..6a18af37d 100644 --- a/app/widget/timebased/timebasedwidget.cpp +++ b/app/widget/timebased/timebasedwidget.cpp @@ -35,7 +35,6 @@ TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_statu TimelineScaledWidget(parent), viewer_node_(nullptr), auto_max_scrollbar_(false), - points_(nullptr), toggle_show_all_(false), auto_set_timebase_(true) { @@ -89,7 +88,6 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node) SetTimebase(rational()); } - points_ = nullptr; ruler()->ConnectTimelinePoints(nullptr); scrollbar_->ConnectTimelinePoints(nullptr); } @@ -101,10 +99,8 @@ void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node) if (viewer_node_) { connect(viewer_node_, &ViewerOutput::LengthChanged, this, &TimeBasedWidget::UpdateMaximumScroll); - if ((points_ = GetTimelinePointsToConnect())) { - ruler()->ConnectTimelinePoints(points_); - scrollbar_->ConnectTimelinePoints(points_); - } + ruler()->ConnectTimelinePoints(viewer_node_->GetTimelinePoints()); + scrollbar_->ConnectTimelinePoints(viewer_node_->GetTimelinePoints()); if (auto_set_timebase_) { if (!viewer_node_->video_params().time_base().isNull()) { @@ -242,27 +238,6 @@ void TimeBasedWidget::resizeEvent(QResizeEvent *event) UpdateMaximumScroll(); } -TimelinePoints *TimeBasedWidget::GetTimelinePointsToConnect() -{ - Sequence* sequence = dynamic_cast(viewer_node_); - - if (sequence) { - return sequence->timeline_points(); - } - - return nullptr; -} - -Project *TimeBasedWidget::GetTimelinePointsProject() -{ - return viewer_node_->project(); -} - -TimelinePoints *TimeBasedWidget::GetConnectedTimelinePoints() const -{ - return points_; -} - void TimeBasedWidget::ConnectTimelineView(TimeBasedView *base, bool connect_time_change_event) { if (connect_time_change_event) { @@ -442,15 +417,16 @@ void TimeBasedWidget::SetAutoSetTimebase(bool e) void TimeBasedWidget::SetPoint(Timeline::MovementMode m, const rational& time) { - if (!points_) { + if (!viewer_node_) { return; } MultiUndoCommand* command = new MultiUndoCommand(); + TimelinePoints* points = viewer_node_->GetTimelinePoints(); // Enable workarea if it isn't already enabled - if (!points_->workarea()->enabled()) { - command->add_child(new WorkareaSetEnabledCommand(GetTimelinePointsProject(), points_, true)); + if (!points->workarea()->enabled()) { + command->add_child(new WorkareaSetEnabledCommand(viewer_node_->project(), points, true)); } // Determine our new range @@ -459,34 +435,40 @@ void TimeBasedWidget::SetPoint(Timeline::MovementMode m, const rational& time) if (m == Timeline::kTrimIn) { in_point = time; - if (!points_->workarea()->enabled() || points_->workarea()->out() < in_point) { + if (!points->workarea()->enabled() || points->workarea()->out() < in_point) { out_point = TimelineWorkArea::kResetOut; } else { - out_point = points_->workarea()->out(); + out_point = points->workarea()->out(); } } else { out_point = time; - if (!points_->workarea()->enabled() || points_->workarea()->in() > out_point) { + if (!points->workarea()->enabled() || points->workarea()->in() > out_point) { in_point = TimelineWorkArea::kResetIn; } else { - in_point = points_->workarea()->in(); + in_point = points->workarea()->in(); } } // Set workarea - command->add_child(new WorkareaSetRangeCommand(GetTimelinePointsProject(), points_, TimeRange(in_point, out_point))); + command->add_child(new WorkareaSetRangeCommand(viewer_node_->project(), points, TimeRange(in_point, out_point))); Core::instance()->undo_stack()->push(command); } void TimeBasedWidget::ResetPoint(Timeline::MovementMode m) { - if (!points_ || !points_->workarea()->enabled()) { + if (!GetConnectedNode()) { return; } - TimeRange r = points_->workarea()->range(); + TimelinePoints* points = GetConnectedNode()->GetTimelinePoints(); + + if (!GetConnectedNode() || !points->workarea()->enabled()) { + return; + } + + TimeRange r = points->workarea()->range(); if (m == Timeline::kTrimIn) { r.set_in(TimelineWorkArea::kResetIn); @@ -494,7 +476,7 @@ void TimeBasedWidget::ResetPoint(Timeline::MovementMode m) r.set_out(TimelineWorkArea::kResetOut); } - Core::instance()->undo_stack()->push(new WorkareaSetRangeCommand(GetTimelinePointsProject(), points_, r)); + Core::instance()->undo_stack()->push(new WorkareaSetRangeCommand(viewer_node_->project(), points, r)); } void TimeBasedWidget::PageScrollInternal(QScrollBar *bar, int maximum, int screen_position, bool whole_page_scroll) @@ -561,17 +543,17 @@ void TimeBasedWidget::ResetOut() void TimeBasedWidget::ClearInOutPoints() { - if (!points_) { + if (!GetConnectedNode()) { return; } - Core::instance()->undo_stack()->push(new WorkareaSetEnabledCommand(GetTimelinePointsProject(), points_, false)); + Core::instance()->undo_stack()->push(new WorkareaSetEnabledCommand(GetConnectedNode()->project(), GetConnectedNode()->GetTimelinePoints(), false)); } void TimeBasedWidget::SetMarker() { - if (!points_) { + if (!GetConnectedNode()) { return; } @@ -586,7 +568,7 @@ void TimeBasedWidget::SetMarker() if (ok) { Core::instance()->undo_stack()->push(new MarkerAddCommand(GetConnectedNode()->project(), - points_->markers(), TimeRange(GetTime(), GetTime()), marker_name)); + GetConnectedNode()->GetTimelinePoints()->markers(), TimeRange(GetTime(), GetTime()), marker_name)); } } @@ -625,9 +607,9 @@ void TimeBasedWidget::ToggleShowAll() void TimeBasedWidget::GoToIn() { - if (viewer_node_) { - if (points_ && points_->workarea()->enabled()) { - SetTimeAndSignal(Timecode::time_to_timestamp(points_->workarea()->in(), timebase())); + if (GetConnectedNode()) { + if (GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { + SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->in(), timebase())); } else { GoToStart(); } @@ -636,9 +618,9 @@ void TimeBasedWidget::GoToIn() void TimeBasedWidget::GoToOut() { - if (viewer_node_) { - if (points_ && points_->workarea()->enabled()) { - SetTimeAndSignal(Timecode::time_to_timestamp(points_->workarea()->out(), timebase())); + if (GetConnectedNode()) { + if (GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { + SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->out(), timebase())); } else { GoToEnd(); } diff --git a/app/widget/timebased/timebasedwidget.h b/app/widget/timebased/timebasedwidget.h index 1089bacfc..023ceb7b5 100644 --- a/app/widget/timebased/timebasedwidget.h +++ b/app/widget/timebased/timebasedwidget.h @@ -48,8 +48,6 @@ public: ViewerOutput* GetConnectedNode() const; - TimelinePoints* GetConnectedTimelinePoints() const; - void ConnectViewerNode(ViewerOutput *node); void SetScaleAndCenterOnPlayhead(const double& scale); @@ -117,10 +115,6 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; - virtual TimelinePoints* GetTimelinePointsToConnect(); - - virtual Project* GetTimelinePointsProject(); - void ConnectTimelineView(TimeBasedView* base, bool connect_time_change_event = true); void PassWheelEventsToScrollBar(QObject* object); @@ -197,8 +191,6 @@ private: bool auto_max_scrollbar_; - TimelinePoints* points_; - QList timeline_views_; bool toggle_show_all_; diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 41994e765..3f92d3be3 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -630,8 +630,7 @@ void TimelineWidget::Paste(bool insert) void TimelineWidget::DeleteInToOut(bool ripple) { if (!GetConnectedNode() - || !GetConnectedTimelinePoints() - || !GetConnectedTimelinePoints()->workarea()->enabled()) { + || !GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { return; } @@ -639,9 +638,10 @@ void TimelineWidget::DeleteInToOut(bool ripple) if (ripple) { - command->add_child(new TimelineRippleRemoveAreaCommand(sequence(), - GetConnectedTimelinePoints()->workarea()->in(), - GetConnectedTimelinePoints()->workarea()->out())); + command->add_child(new TimelineRippleRemoveAreaCommand( + sequence(), + GetConnectedNode()->GetTimelinePoints()->workarea()->in(), + GetConnectedNode()->GetTimelinePoints()->workarea()->out())); } else { QVector unlocked_tracks = sequence()->GetUnlockedTracks(); @@ -649,7 +649,7 @@ void TimelineWidget::DeleteInToOut(bool ripple) foreach (Track* track, unlocked_tracks) { GapBlock* gap = new GapBlock(); - gap->set_length_and_media_out(GetConnectedTimelinePoints()->workarea()->length()); + gap->set_length_and_media_out(GetConnectedNode()->GetTimelinePoints()->workarea()->length()); command->add_child(new NodeAddCommand(static_cast(track->parent()), gap)); @@ -657,17 +657,17 @@ void TimelineWidget::DeleteInToOut(bool ripple) command->add_child(new TrackPlaceBlockCommand(sequence()->track_list(track->type()), track->Index(), gap, - GetConnectedTimelinePoints()->workarea()->in())); + GetConnectedNode()->GetTimelinePoints()->workarea()->in())); } } // Clear workarea after this - command->add_child(new WorkareaSetEnabledCommand(GetTimelinePointsProject(), - GetConnectedTimelinePoints(), + command->add_child(new WorkareaSetEnabledCommand(GetConnectedNode()->project(), + GetConnectedNode()->GetTimelinePoints(), false)); if (ripple) { - SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedTimelinePoints()->workarea()->in(), + SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->in(), timebase())); } @@ -1513,8 +1513,8 @@ bool TimelineWidget::SnapPoint(QVector start_times, rational* movement } } - if ((snap_points & kSnapToMarkers) && GetConnectedTimelinePoints()) { - foreach (TimelineMarker* m, GetConnectedTimelinePoints()->markers()->list()) { + if ((snap_points & kSnapToMarkers)) { + foreach (TimelineMarker* m, GetConnectedNode()->GetTimelinePoints()->markers()->list()) { qreal marker_pos = TimeToScene(m->time().in()); potential_snaps.append(AttemptSnap(screen_pt, marker_pos, start_times, m->time().in())); diff --git a/app/widget/timelinewidget/tool/import.cpp b/app/widget/timelinewidget/tool/import.cpp index ddfeb2d3d..3b4a90f75 100644 --- a/app/widget/timelinewidget/tool/import.cpp +++ b/app/widget/timelinewidget/tool/import.cpp @@ -237,9 +237,10 @@ void ImportTool::FootageToGhosts(rational ghost_start, const QMapworkarea()->enabled()) { - footage_duration = qMax(footage_duration, it.key()->workarea()->range().length()); - ghost->SetMediaIn(it.key()->workarea()->in()); + TimelinePoints* tp = it.key()->GetTimelinePoints(); + if (tp->workarea()->enabled()) { + footage_duration = qMax(footage_duration, tp->workarea()->range().length()); + ghost->SetMediaIn(tp->workarea()->in()); } else { int64_t dur; rational tb; diff --git a/app/widget/viewer/footageviewer.cpp b/app/widget/viewer/footageviewer.cpp index 6df6a8763..9f96b9680 100644 --- a/app/widget/viewer/footageviewer.cpp +++ b/app/widget/viewer/footageviewer.cpp @@ -28,9 +28,10 @@ namespace olive { +#define super ViewerWidget + FootageViewerWidget::FootageViewerWidget(QWidget *parent) : - ViewerWidget(parent), - footage_(nullptr) + super(parent) { connect(display_widget(), &ViewerDisplayWidget::DragStarted, this, &FootageViewerWidget::StartFootageDrag); @@ -39,71 +40,21 @@ FootageViewerWidget::FootageViewerWidget(QWidget *parent) : connect(controls_, &PlaybackControls::AudioPressed, this, &FootageViewerWidget::StartAudioDrag); } -Footage *FootageViewerWidget::GetFootage() const +void FootageViewerWidget::ConnectNodeInternal(ViewerOutput *n) { - return footage_; + SetTimestamp(cached_timestamps_.value(n, 0)); } -void FootageViewerWidget::SetFootage(Footage *footage) +void FootageViewerWidget::DisconnectNodeInternal(ViewerOutput *n) { - if (footage && !footage->project()) { - qCritical() << "Failed to set footage in footage viewer - footage had no project"; - return; - } - - if (footage_) { - cached_timestamps_.insert(footage_, GetTimestamp()); - - ViewerOutput* old_viewer = footage_->project()->footage_viewer(); - - ConnectViewerNode(nullptr); - - if (old_viewer->IsInputConnected(ViewerOutput::kTextureInput)) { - Node::DisconnectEdge(old_viewer->GetConnectedOutput(ViewerOutput::kTextureInput), NodeInput(old_viewer, ViewerOutput::kTextureInput)); - } - - if (old_viewer->IsInputConnected(ViewerOutput::kSamplesInput)) { - Node::DisconnectEdge(old_viewer->GetConnectedOutput(ViewerOutput::kSamplesInput), NodeInput(old_viewer, ViewerOutput::kSamplesInput)); - } - } - - footage_ = footage; - - if (footage_) { - ViewerOutput* new_viewer = footage_->project()->footage_viewer(); - - // Update sequence media name - new_viewer->SetLabel(footage_->GetLabel()); - - // Reset parameters and then attempt to set from footage - new_viewer->set_default_parameters(); - new_viewer->set_parameters_from_footage({footage_}); - - // Try to connect video stream - TryConnectingType(new_viewer, footage, Stream::kVideo); - TryConnectingType(new_viewer, footage, Stream::kAudio); - - ConnectViewerNode(new_viewer); - - SetTimestamp(cached_timestamps_.value(footage_, 0)); - } else { - SetTimestamp(0); - } -} - -TimelinePoints *FootageViewerWidget::GetTimelinePointsToConnect() -{ - return footage_; -} - -Project *FootageViewerWidget::GetTimelinePointsProject() -{ - return footage_->project(); + // Cache timestamp in case this footage is opened again later + cached_timestamps_.insert(n, GetTimestamp()); + SetTimestamp(0); } void FootageViewerWidget::StartFootageDragInternal(bool enable_video, bool enable_audio) { - if (!GetFootage()) { + if (!GetConnectedNode()) { return; } @@ -113,7 +64,7 @@ void FootageViewerWidget::StartFootageDragInternal(bool enable_video, bool enabl QByteArray encoded_data; QDataStream data_stream(&encoded_data, QIODevice::WriteOnly); - QVector streams = GetFootage()->GetEnabledStreamsAsReferences(); + QVector streams = GetConnectedNode()->GetEnabledStreamsAsReferences(); // Disable streams that have been disabled if (!enable_video || !enable_audio) { @@ -129,7 +80,7 @@ void FootageViewerWidget::StartFootageDragInternal(bool enable_video, bool enabl } if (!streams.isEmpty()) { - data_stream << streams << reinterpret_cast(GetFootage()); + data_stream << streams << reinterpret_cast(GetConnectedNode()); mimedata->setData(QStringLiteral("application/x-oliveprojectitemdata"), encoded_data); drag->setMimeData(mimedata); @@ -138,51 +89,6 @@ void FootageViewerWidget::StartFootageDragInternal(bool enable_video, bool enabl } } -void FootageViewerWidget::TryConnectingType(ViewerOutput* viewer, Footage *footage, Stream::Type type) -{ - int index = -1; - - for (int i=0; ; i++) { - if (type == Stream::kVideo) { - VideoParams vp = footage->GetVideoParams(i); - - if (!vp.is_valid()) { - break; - } - - if (vp.enabled()) { - index = i; - break; - } - } else if (type == Stream::kAudio) { - AudioParams vp = footage->GetAudioParams(i); - - if (!vp.is_valid()) { - break; - } - - if (vp.enabled()) { - index = i; - break; - } - } - } - - if (index != -1) { - QString s = Footage::GetStringFromReference(type, index); - - QString input_param; - - if (type == Stream::kVideo) { - input_param = ViewerOutput::kTextureInput; - } else { - input_param = ViewerOutput::kSamplesInput; - } - - Node::ConnectEdge(NodeOutput(footage, s), NodeInput(viewer, input_param)); - } -} - void FootageViewerWidget::StartFootageDrag() { StartFootageDragInternal(true, true); diff --git a/app/widget/viewer/footageviewer.h b/app/widget/viewer/footageviewer.h index 8da9f478f..c41378251 100644 --- a/app/widget/viewer/footageviewer.h +++ b/app/widget/viewer/footageviewer.h @@ -32,22 +32,15 @@ class FootageViewerWidget : public ViewerWidget public: FootageViewerWidget(QWidget* parent = nullptr); - Footage* GetFootage() const; - void SetFootage(Footage* footage); - protected: - virtual TimelinePoints* GetTimelinePointsToConnect() override; + virtual void ConnectNodeInternal(ViewerOutput *) override; - virtual Project* GetTimelinePointsProject() override; + virtual void DisconnectNodeInternal(ViewerOutput *) override; private: void StartFootageDragInternal(bool enable_video, bool enable_audio); - void TryConnectingType(ViewerOutput *viewer, Footage* footage, Stream::Type type); - - Footage* footage_; - - QHash cached_timestamps_; + QHash cached_timestamps_; private slots: void StartFootageDrag(); diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index d03c3ccb4..49dbb9a94 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -212,9 +212,7 @@ void ViewerWidget::ConnectNodeInternal(ViewerOutput *n) UpdateStack(); waveform_view_->SetViewer(GetConnectedNode()->audio_playback_cache()); - if (GetConnectedTimelinePoints()) { - waveform_view_->ConnectTimelinePoints(GetConnectedTimelinePoints()); - } + waveform_view_->ConnectTimelinePoints(GetConnectedNode()->GetTimelinePoints()); UpdateRendererVideoParameters(); UpdateRendererAudioParameters(); @@ -361,8 +359,8 @@ void ViewerWidget::CacheEntireSequence() void ViewerWidget::CacheSequenceInOut() { - if (GetConnectedTimelinePoints() && GetConnectedTimelinePoints()->workarea()->enabled()) { - auto_cacher_.ForceCacheRange(GetConnectedTimelinePoints()->workarea()->range()); + if (GetConnectedNode() && GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { + auto_cacher_.ForceCacheRange(GetConnectedNode()->GetTimelinePoints()->workarea()->range()); } else { QMessageBox::warning(this, tr("Error"), @@ -974,10 +972,10 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos) void ViewerWidget::Play(bool in_to_out_only) { if (in_to_out_only) { - if (GetConnectedTimelinePoints() - && GetConnectedTimelinePoints()->workarea()->enabled()) { + if (GetConnectedNode() + && GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { // Jump to in point - SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedTimelinePoints()->workarea()->in(), timebase())); + SetTimeAndSignal(Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->in(), timebase())); } else { in_to_out_only = false; } @@ -1072,12 +1070,11 @@ void ViewerWidget::PlaybackTimerUpdate() { if ((play_in_to_out_only_ || Config::Current()["Loop"].toBool()) - && GetConnectedTimelinePoints() - && GetConnectedTimelinePoints()->workarea()->enabled()) { + && GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { // If "play in to out" is enabled or we're looping AND we have a workarea, only play the workarea - min_time = Timecode::time_to_timestamp(GetConnectedTimelinePoints()->workarea()->in(), timebase()); - max_time = Timecode::time_to_timestamp(GetConnectedTimelinePoints()->workarea()->out(), timebase()); + min_time = Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->in(), timebase()); + max_time = Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->out(), timebase()); } else {