From 1644b9e4c15465f42fb37ddd3c453f5d56be3ac0 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Wed, 15 Dec 2021 13:45:51 -0800 Subject: [PATCH] remove dodgy node properties dialog --- app/dialog/CMakeLists.txt | 2 +- .../CMakeLists.txt | 8 +- .../footageproperties/footageproperties.cpp | 251 ++++++++++++++++ .../footageproperties/footageproperties.h | 120 ++++++++ .../streamproperties/CMakeLists.txt | 26 ++ .../audiostreamproperties.cpp | 37 +++ .../streamproperties/audiostreamproperties.h} | 29 +- .../streamproperties/streamproperties.cpp | 30 ++ .../streamproperties/streamproperties.h | 44 +++ .../videostreamproperties.cpp | 271 ++++++++++++++++++ .../streamproperties/videostreamproperties.h | 146 ++++++++++ .../nodeproperties/nodepropertiesdialog.cpp | 74 ----- .../projectexplorer/projectexplorer.cpp | 6 +- app/widget/timelinewidget/timelinewidget.cpp | 13 +- 14 files changed, 946 insertions(+), 111 deletions(-) rename app/dialog/{nodeproperties => footageproperties}/CMakeLists.txt (81%) create mode 100644 app/dialog/footageproperties/footageproperties.cpp create mode 100644 app/dialog/footageproperties/footageproperties.h create mode 100644 app/dialog/footageproperties/streamproperties/CMakeLists.txt create mode 100644 app/dialog/footageproperties/streamproperties/audiostreamproperties.cpp rename app/dialog/{nodeproperties/nodepropertiesdialog.h => footageproperties/streamproperties/audiostreamproperties.h} (54%) create mode 100644 app/dialog/footageproperties/streamproperties/streamproperties.cpp create mode 100644 app/dialog/footageproperties/streamproperties/streamproperties.h create mode 100644 app/dialog/footageproperties/streamproperties/videostreamproperties.cpp create mode 100644 app/dialog/footageproperties/streamproperties/videostreamproperties.h delete mode 100644 app/dialog/nodeproperties/nodepropertiesdialog.cpp diff --git a/app/dialog/CMakeLists.txt b/app/dialog/CMakeLists.txt index 01bbfd5ec..afe445704 100644 --- a/app/dialog/CMakeLists.txt +++ b/app/dialog/CMakeLists.txt @@ -21,10 +21,10 @@ add_subdirectory(color) add_subdirectory(configbase) add_subdirectory(diskcache) add_subdirectory(export) +add_subdirectory(footageproperties) add_subdirectory(footagerelink) add_subdirectory(keyframeproperties) add_subdirectory(nodegroup) -add_subdirectory(nodeproperties) add_subdirectory(preferences) add_subdirectory(progress) add_subdirectory(rendercancel) diff --git a/app/dialog/nodeproperties/CMakeLists.txt b/app/dialog/footageproperties/CMakeLists.txt similarity index 81% rename from app/dialog/nodeproperties/CMakeLists.txt rename to app/dialog/footageproperties/CMakeLists.txt index f1c44b5af..25287c233 100644 --- a/app/dialog/nodeproperties/CMakeLists.txt +++ b/app/dialog/footageproperties/CMakeLists.txt @@ -1,5 +1,5 @@ # Olive - Non-Linear Video Editor -# Copyright (C) 2021 Olive Team +# 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 @@ -14,9 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +add_subdirectory(streamproperties) + set(OLIVE_SOURCES ${OLIVE_SOURCES} - dialog/nodeproperties/nodepropertiesdialog.cpp - dialog/nodeproperties/nodepropertiesdialog.h + dialog/footageproperties/footageproperties.cpp + dialog/footageproperties/footageproperties.h PARENT_SCOPE ) diff --git a/app/dialog/footageproperties/footageproperties.cpp b/app/dialog/footageproperties/footageproperties.cpp new file mode 100644 index 000000000..7cb56c63a --- /dev/null +++ b/app/dialog/footageproperties/footageproperties.cpp @@ -0,0 +1,251 @@ +/*** + + 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 . + +***/ + +#include "footageproperties.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core.h" +#include "streamproperties/audiostreamproperties.h" +#include "streamproperties/videostreamproperties.h" +#include "widget/nodeview/nodeviewundo.h" + +namespace olive { + +FootagePropertiesDialog::FootagePropertiesDialog(QWidget *parent, Footage *footage) : + QDialog(parent), + footage_(footage) +{ + QGridLayout* layout = new QGridLayout(this); + + setWindowTitle(tr("\"%1\" Properties").arg(footage_->GetLabelOrName())); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + int row = 0; + + layout->addWidget(new QLabel(tr("Name:")), row, 0); + + footage_name_field_ = new QLineEdit(footage_->GetLabel()); + layout->addWidget(footage_name_field_, row, 1); + row++; + + layout->addWidget(new QLabel(tr("Tracks:")), row, 0, 1, 2); + row++; + + track_list = new QListWidget(); + layout->addWidget(track_list, row, 0, 1, 2); + + row++; + + stacked_widget_ = new QStackedWidget(); + layout->addWidget(stacked_widget_, row, 0, 1, 2); + + int first_usable_stream = -1; + + for (int i=0; iGetTotalStreamCount(); i++) { + Track::Reference reference = footage_->GetReferenceFromRealIndex(i); + + QString description; + bool is_enabled = false; + + switch (reference.type()) { + case Track::kVideo: + { + stacked_widget_->addWidget(new VideoStreamProperties(footage_, reference.index())); + + VideoParams vp = footage_->GetVideoParams(reference.index()); + is_enabled = vp.enabled(); + description = tr("%1x%2 %3 FPS").arg(QString::number(vp.width()), QString::number(vp.height()), QString::number(vp.frame_rate().toDouble())); + break; + } + case Track::kAudio: + { + stacked_widget_->addWidget(new AudioStreamProperties(footage_, reference.index())); + + AudioParams ap = footage_->GetAudioParams(reference.index()); + is_enabled = ap.enabled(); + description = tr("%1 Hz %2 channels").arg(QString::number(ap.sample_rate()), QString::number(ap.channel_count())); + break; + } + default: + stacked_widget_->addWidget(new StreamProperties()); + description = tr("Unknown"); + break; + } + + QListWidgetItem* item = new QListWidgetItem(description, track_list); + item->setFlags(item->flags() | Qt::ItemIsUserCheckable); + item->setCheckState(is_enabled ? Qt::Checked : Qt::Unchecked); + track_list->addItem(item); + + if (first_usable_stream == -1 + && (reference.type() == Track::kVideo + || reference.type() == Track::kAudio)) { + first_usable_stream = i; + } + } + + row++; + + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + buttons->setCenterButtons(true); + layout->addWidget(buttons, row, 0, 1, 2); + + connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); + + connect(track_list, &QListWidget::currentRowChanged, stacked_widget_, &QStackedWidget::setCurrentIndex); + + // Auto-select first item that actually has properties + if (first_usable_stream >= 0) { + track_list->setCurrentRow(first_usable_stream); + } + track_list->setFocus(); +} + +void FootagePropertiesDialog::accept() +{ + // Perform sanity check on all pages + for (int i=0;icount();i++) { + if (!static_cast(stacked_widget_->widget(i))->SanityCheck()) { + // Switch to the failed panel in question + stacked_widget_->setCurrentIndex(i); + + // Do nothing (it's up to the property panel itself to throw the error message) + return; + } + } + + MultiUndoCommand* command = new MultiUndoCommand(); + + if (footage_->GetLabel() != footage_name_field_->text()) { + NodeRenameCommand *nrc = new NodeRenameCommand(); + nrc->AddNode(footage_, footage_name_field_->text()); + command->add_child(nrc); + } + + for (int i=0; iGetTotalStreamCount(); i++) { + Track::Reference reference = footage_->GetReferenceFromRealIndex(i); + bool new_stream_enabled = (track_list->item(i)->checkState() == Qt::Checked); + bool old_stream_enabled = new_stream_enabled; + + switch (reference.type()) { + case Track::kVideo: + old_stream_enabled = footage_->GetVideoParams(reference.index()).enabled(); + break; + case Track::kAudio: + old_stream_enabled = footage_->GetAudioParams(reference.index()).enabled(); + break; + case Track::kSubtitle: + case Track::kNone: + case Track::kCount: + break; + } + + if (old_stream_enabled != new_stream_enabled) { + command->add_child(new StreamEnableChangeCommand(footage_, + reference.type(), + reference.index(), + new_stream_enabled)); + } + } + + for (int i=0;icount();i++) { + static_cast(stacked_widget_->widget(i))->Accept(command); + } + + Core::instance()->undo_stack()->pushIfHasChildren(command); + + QDialog::accept(); +} + +FootagePropertiesDialog::StreamEnableChangeCommand::StreamEnableChangeCommand(Footage *footage, Track::Type type, int index_in_type, bool enabled) : + footage_(footage), + type_(type), + index_(index_in_type), + new_enabled_(enabled) +{ +} + +Project *FootagePropertiesDialog::StreamEnableChangeCommand::GetRelevantProject() const +{ + return footage_->project(); +} + +void FootagePropertiesDialog::StreamEnableChangeCommand::redo() +{ + switch (type_) { + case Track::kVideo: + { + VideoParams vp = footage_->GetVideoParams(index_); + old_enabled_ = vp.enabled(); + vp.set_enabled(new_enabled_); + footage_->SetVideoParams(vp, index_); + break; + } + case Track::kAudio: + { + AudioParams ap = footage_->GetAudioParams(index_); + old_enabled_ = ap.enabled(); + ap.set_enabled(new_enabled_); + footage_->SetAudioParams(ap, index_); + break; + } + case Track::kSubtitle: + case Track::kNone: + case Track::kCount: + break; + } +} + +void FootagePropertiesDialog::StreamEnableChangeCommand::undo() +{ + switch (type_) { + case Track::kVideo: + { + VideoParams vp = footage_->GetVideoParams(index_); + vp.set_enabled(old_enabled_); + footage_->SetVideoParams(vp, index_); + break; + } + case Track::kAudio: + { + AudioParams ap = footage_->GetAudioParams(index_); + ap.set_enabled(old_enabled_); + footage_->SetAudioParams(ap, index_); + break; + } + case Track::kSubtitle: + case Track::kNone: + case Track::kCount: + break; + } +} + +} diff --git a/app/dialog/footageproperties/footageproperties.h b/app/dialog/footageproperties/footageproperties.h new file mode 100644 index 000000000..7fd58a14e --- /dev/null +++ b/app/dialog/footageproperties/footageproperties.h @@ -0,0 +1,120 @@ +/*** + + 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 MEDIAPROPERTIESDIALOG_H +#define MEDIAPROPERTIESDIALOG_H + +#include +#include +#include +#include +#include +#include +#include + +#include "node/project/footage/footage.h" +#include "undo/undocommand.h" + +namespace olive { + +/** + * @brief The MediaPropertiesDialog class + * + * A dialog for setting properties on Media. This can be loaded from any part of the application provided it's given + * a valid Media object. + */ +class FootagePropertiesDialog : public QDialog { + Q_OBJECT +public: + /** + * @brief MediaPropertiesDialog Constructor + * + * @param parent + * + * QWidget parent. Usually MainWindow or Project panel. + * + * @param i + * + * Media object to set properties for. + */ + FootagePropertiesDialog(QWidget *parent, Footage* footage); +private: + class StreamEnableChangeCommand : public UndoCommand { + public: + StreamEnableChangeCommand(Footage *footage, + Track::Type type, + int index_in_type, + bool enabled); + + virtual Project* GetRelevantProject() const override; + + virtual void redo() override; + virtual void undo() override; + + private: + Footage *footage_; + Track::Type type_; + int index_; + + bool old_enabled_; + bool new_enabled_; + }; + + /** + * @brief Stack of widgets that changes based on whether the stream is a video or audio stream + */ + QStackedWidget* stacked_widget_; + + /** + * @brief ComboBox for interlacing setting + */ + QComboBox* interlacing_box; + + /** + * @brief Media name text field + */ + QLineEdit* footage_name_field_; + + /** + * @brief Internal pointer to Media object (set in constructor) + */ + Footage* footage_; + + /** + * @brief A list widget for listing the tracks in Media + */ + QListWidget* track_list; + + /** + * @brief Frame rate to conform to + */ + QDoubleSpinBox* conform_fr; + +private slots: + /** + * @brief Overridden accept function for saving the properties back to the Media class + */ + void accept(); + +}; + +} + +#endif // MEDIAPROPERTIESDIALOG_H diff --git a/app/dialog/footageproperties/streamproperties/CMakeLists.txt b/app/dialog/footageproperties/streamproperties/CMakeLists.txt new file mode 100644 index 000000000..3228e9520 --- /dev/null +++ b/app/dialog/footageproperties/streamproperties/CMakeLists.txt @@ -0,0 +1,26 @@ +# 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 . + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + dialog/footageproperties/streamproperties/streamproperties.h + dialog/footageproperties/streamproperties/streamproperties.cpp + dialog/footageproperties/streamproperties/audiostreamproperties.h + dialog/footageproperties/streamproperties/audiostreamproperties.cpp + dialog/footageproperties/streamproperties/videostreamproperties.h + dialog/footageproperties/streamproperties/videostreamproperties.cpp + PARENT_SCOPE +) diff --git a/app/dialog/footageproperties/streamproperties/audiostreamproperties.cpp b/app/dialog/footageproperties/streamproperties/audiostreamproperties.cpp new file mode 100644 index 000000000..0359e7577 --- /dev/null +++ b/app/dialog/footageproperties/streamproperties/audiostreamproperties.cpp @@ -0,0 +1,37 @@ +/*** + + 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 . + +***/ + +#include "audiostreamproperties.h" + +namespace olive { + +AudioStreamProperties::AudioStreamProperties(Footage *footage, int audio_index) : + footage_(footage), + audio_index_(audio_index) +{ +} + +void AudioStreamProperties::Accept(MultiUndoCommand*) +{ + Q_UNUSED(footage_) + Q_UNUSED(audio_index_) +} + +} diff --git a/app/dialog/nodeproperties/nodepropertiesdialog.h b/app/dialog/footageproperties/streamproperties/audiostreamproperties.h similarity index 54% rename from app/dialog/nodeproperties/nodepropertiesdialog.h rename to app/dialog/footageproperties/streamproperties/audiostreamproperties.h index 5375a1313..058ff2bfc 100644 --- a/app/dialog/nodeproperties/nodepropertiesdialog.h +++ b/app/dialog/footageproperties/streamproperties/audiostreamproperties.h @@ -1,7 +1,7 @@ /*** Olive - Non-Linear Video Editor - Copyright (C) 2021 Olive Team + 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 @@ -18,35 +18,28 @@ ***/ -#ifndef NODEPROPERTIESDIALOG_H -#define NODEPROPERTIESDIALOG_H +#ifndef AUDIOSTREAMPROPERTIES_H +#define AUDIOSTREAMPROPERTIES_H -#include - -#include "widget/nodeparamview/nodeparamviewitem.h" +#include "node/project/footage/footage.h" +#include "streamproperties.h" namespace olive { -class NodePropertiesDialog : public QDialog +class AudioStreamProperties : public StreamProperties { - Q_OBJECT public: - NodePropertiesDialog(Node *node, const rational &timebase, QWidget *parent = nullptr); - NodePropertiesDialog(const QVector &node, const rational &timebase, QWidget *parent = nullptr) : - NodePropertiesDialog(node.first(), timebase, parent) - { - } + AudioStreamProperties(Footage *footage, int audio_index); -public slots: - virtual void accept() override; + virtual void Accept(MultiUndoCommand* parent) override; private: - Node *node_; + Footage *footage_; - QLineEdit *label_edit_; + int audio_index_; }; } -#endif // NODEPROPERTIESDIALOG_H +#endif // AUDIOSTREAMPROPERTIES_H diff --git a/app/dialog/footageproperties/streamproperties/streamproperties.cpp b/app/dialog/footageproperties/streamproperties/streamproperties.cpp new file mode 100644 index 000000000..96f3bbd5a --- /dev/null +++ b/app/dialog/footageproperties/streamproperties/streamproperties.cpp @@ -0,0 +1,30 @@ +/*** + + 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 . + +***/ + +#include "streamproperties.h" + +namespace olive { + +StreamProperties::StreamProperties(QWidget *parent) : + QWidget(parent) +{ +} + +} diff --git a/app/dialog/footageproperties/streamproperties/streamproperties.h b/app/dialog/footageproperties/streamproperties/streamproperties.h new file mode 100644 index 000000000..c8457216b --- /dev/null +++ b/app/dialog/footageproperties/streamproperties/streamproperties.h @@ -0,0 +1,44 @@ +/*** + + 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 STREAMPROPERTIES_H +#define STREAMPROPERTIES_H + +#include + +#include "common/define.h" +#include "undo/undocommand.h" + +namespace olive { + +class StreamProperties : public QWidget +{ +public: + StreamProperties(QWidget* parent = nullptr); + + virtual void Accept(MultiUndoCommand*){} + + virtual bool SanityCheck(){return true;} + +}; + +} + +#endif // STREAMPROPERTIES_H diff --git a/app/dialog/footageproperties/streamproperties/videostreamproperties.cpp b/app/dialog/footageproperties/streamproperties/videostreamproperties.cpp new file mode 100644 index 000000000..6fcbdd914 --- /dev/null +++ b/app/dialog/footageproperties/streamproperties/videostreamproperties.cpp @@ -0,0 +1,271 @@ +/*** + + 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 . + +***/ + +#include "videostreamproperties.h" + +#include +#include +#include +#include +#include + +#include "common/ocioutils.h" +#include "core.h" +#include "undo/undostack.h" + +namespace olive { + +VideoStreamProperties::VideoStreamProperties(Footage *footage, int video_index) : + footage_(footage), + video_index_(video_index), + video_premultiply_alpha_(nullptr) +{ + QGridLayout* video_layout = new QGridLayout(this); + video_layout->setMargin(0); + + int row = 0; + + video_layout->addWidget(new QLabel(tr("Pixel Aspect:")), row, 0); + + VideoParams vp = footage_->GetVideoParams(video_index_); + + pixel_aspect_combo_ = new PixelAspectRatioComboBox(); + pixel_aspect_combo_->SetPixelAspectRatio(vp.pixel_aspect_ratio()); + video_layout->addWidget(pixel_aspect_combo_, row, 1); + + row++; + + video_layout->addWidget(new QLabel(tr("Interlacing:")), row, 0); + + video_interlace_combo_ = new InterlacedComboBox(); + video_interlace_combo_->SetInterlaceMode(vp.interlacing()); + + video_layout->addWidget(video_interlace_combo_, row, 1); + + row++; + + video_layout->addWidget(new QLabel(tr("Color Space:")), row, 0); + + video_color_space_ = new QComboBox(); + OCIO::ConstConfigRcPtr config = footage_->project()->color_manager()->GetConfig(); + int number_of_colorspaces = config->getNumColorSpaces(); + + video_color_space_->addItem(tr("Default (%1)").arg(footage_->project()->color_manager()->GetDefaultInputColorSpace())); + + for (int i=0;igetColorSpaceNameByIndex(i); + + video_color_space_->addItem(colorspace); + } + + video_color_space_->setCurrentText(vp.colorspace()); + + video_layout->addWidget(video_color_space_, row, 1); + + if (vp.channel_count() == VideoParams::kRGBAChannelCount) { + row++; + + video_premultiply_alpha_ = new QCheckBox(tr("Premultiplied Alpha")); + video_premultiply_alpha_->setChecked(vp.premultiplied_alpha()); + video_layout->addWidget(video_premultiply_alpha_, row, 0, 1, 2); + } + + row++; + + if (vp.video_type() == VideoParams::kVideoTypeImageSequence) { + QGroupBox* imgseq_group = new QGroupBox(tr("Image Sequence")); + QGridLayout* imgseq_layout = new QGridLayout(imgseq_group); + + int imgseq_row = 0; + + imgseq_layout->addWidget(new QLabel(tr("Start Index:")), imgseq_row, 0); + + imgseq_start_time_ = new IntegerSlider(); + imgseq_start_time_->SetMinimum(0); + imgseq_start_time_->SetValue(vp.start_time()); + imgseq_layout->addWidget(imgseq_start_time_, imgseq_row, 1); + + imgseq_row++; + + imgseq_layout->addWidget(new QLabel(tr("End Index:")), imgseq_row, 0); + + imgseq_end_time_ = new IntegerSlider(); + imgseq_end_time_->SetMinimum(0); + imgseq_end_time_->SetValue(vp.start_time() + vp.duration() - 1); + imgseq_layout->addWidget(imgseq_end_time_, imgseq_row, 1); + + imgseq_row++; + + imgseq_layout->addWidget(new QLabel(tr("Frame Rate:")), imgseq_row, 0); + + imgseq_frame_rate_ = new FrameRateComboBox(); + imgseq_frame_rate_->SetFrameRate(vp.frame_rate()); + imgseq_layout->addWidget(imgseq_frame_rate_, imgseq_row, 1); + + video_layout->addWidget(imgseq_group, row, 0, 1, 2); + } +} + +void VideoStreamProperties::Accept(MultiUndoCommand *parent) +{ + QString set_colorspace; + + if (video_color_space_->currentIndex() > 0) { + set_colorspace = video_color_space_->currentText(); + } + + VideoParams vp = footage_->GetVideoParams(video_index_); + + if ((video_premultiply_alpha_ && video_premultiply_alpha_->isChecked() != vp.premultiplied_alpha()) + || set_colorspace != vp.colorspace() + || static_cast(video_interlace_combo_->currentIndex()) != vp.interlacing() + || pixel_aspect_combo_->GetPixelAspectRatio() != vp.pixel_aspect_ratio()) { + + parent->add_child(new VideoStreamChangeCommand(footage_, + video_index_, + video_premultiply_alpha_ ? video_premultiply_alpha_->isChecked() : vp.premultiplied_alpha(), + set_colorspace, + static_cast(video_interlace_combo_->currentIndex()), + pixel_aspect_combo_->GetPixelAspectRatio())); + } + + if (vp.video_type() == VideoParams::kVideoTypeImageSequence) { + int64_t new_dur = imgseq_end_time_->GetValue() - imgseq_start_time_->GetValue() + 1; + + if (vp.start_time() != imgseq_start_time_->GetValue() + || vp.duration() != new_dur + || vp.frame_rate() != imgseq_frame_rate_->GetFrameRate()) { + parent->add_child(new ImageSequenceChangeCommand(footage_, + video_index_, + imgseq_start_time_->GetValue(), + new_dur, + imgseq_frame_rate_->GetFrameRate())); + } + } +} + +bool VideoStreamProperties::SanityCheck() +{ + if (footage_->GetVideoParams(video_index_).video_type() == VideoParams::kVideoTypeImageSequence) { + if (imgseq_start_time_->GetValue() >= imgseq_end_time_->GetValue()) { + QMessageBox::critical(this, + tr("Invalid Configuration"), + tr("Image sequence end index must be a value higher than the start index."), + QMessageBox::Ok); + return false; + } + } + + return true; +} + +VideoStreamProperties::VideoStreamChangeCommand::VideoStreamChangeCommand(Footage *footage, + int video_index, + bool premultiplied, + QString colorspace, + VideoParams::Interlacing interlacing, + const rational &pixel_ar) : + footage_(footage), + video_index_(video_index), + new_premultiplied_(premultiplied), + new_colorspace_(colorspace), + new_interlacing_(interlacing), + new_pixel_ar_(pixel_ar) +{ +} + +Project *VideoStreamProperties::VideoStreamChangeCommand::GetRelevantProject() const +{ + return footage_->project(); +} + +void VideoStreamProperties::VideoStreamChangeCommand::redo() +{ + VideoParams vp = footage_->GetVideoParams(video_index_); + + old_premultiplied_ = vp.premultiplied_alpha(); + old_colorspace_ = vp.colorspace(); + old_interlacing_ = vp.interlacing(); + old_pixel_ar_ = vp.pixel_aspect_ratio(); + + vp.set_premultiplied_alpha(new_premultiplied_); + vp.set_colorspace(new_colorspace_); + vp.set_interlacing(new_interlacing_); + vp.set_pixel_aspect_ratio(new_pixel_ar_); + + footage_->SetVideoParams(vp, video_index_); +} + +void VideoStreamProperties::VideoStreamChangeCommand::undo() +{ + VideoParams vp = footage_->GetVideoParams(video_index_); + + vp.set_premultiplied_alpha(old_premultiplied_); + vp.set_colorspace(old_colorspace_); + vp.set_interlacing(old_interlacing_); + vp.set_pixel_aspect_ratio(old_pixel_ar_); + + footage_->SetVideoParams(vp, video_index_); +} + +VideoStreamProperties::ImageSequenceChangeCommand::ImageSequenceChangeCommand(Footage *footage, int video_index, int64_t start_index, int64_t duration, const rational &frame_rate) : + footage_(footage), + video_index_(video_index), + new_start_index_(start_index), + new_duration_(duration), + new_frame_rate_(frame_rate) +{ +} + +Project *VideoStreamProperties::ImageSequenceChangeCommand::GetRelevantProject() const +{ + return footage_->project(); +} + +void VideoStreamProperties::ImageSequenceChangeCommand::redo() +{ + VideoParams vp = footage_->GetVideoParams(video_index_); + + old_start_index_ = vp.start_time(); + vp.set_start_time(new_start_index_); + + old_duration_ = vp.duration(); + vp.set_duration(new_duration_); + + old_frame_rate_ = vp.frame_rate(); + vp.set_frame_rate(new_frame_rate_); + vp.set_time_base(new_frame_rate_.flipped()); + + footage_->SetVideoParams(vp, video_index_); +} + +void VideoStreamProperties::ImageSequenceChangeCommand::undo() +{ + VideoParams vp = footage_->GetVideoParams(video_index_); + + vp.set_start_time(old_start_index_); + vp.set_duration(old_duration_); + vp.set_frame_rate(old_frame_rate_); + vp.set_time_base(old_frame_rate_.flipped()); + + footage_->SetVideoParams(vp, video_index_); +} + +} diff --git a/app/dialog/footageproperties/streamproperties/videostreamproperties.h b/app/dialog/footageproperties/streamproperties/videostreamproperties.h new file mode 100644 index 000000000..3d858b2c1 --- /dev/null +++ b/app/dialog/footageproperties/streamproperties/videostreamproperties.h @@ -0,0 +1,146 @@ +/*** + + 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 VIDEOSTREAMPROPERTIES_H +#define VIDEOSTREAMPROPERTIES_H + +#include +#include + +#include "node/project/footage/footage.h" +#include "streamproperties.h" +#include "widget/slider/integerslider.h" +#include "widget/standardcombos/standardcombos.h" + +namespace olive { + +class VideoStreamProperties : public StreamProperties +{ + Q_OBJECT +public: + VideoStreamProperties(Footage *footage, int video_index); + + virtual void Accept(MultiUndoCommand *parent) override; + + virtual bool SanityCheck() override; + +private: + Footage *footage_; + + int video_index_; + + /** + * @brief Setting for associated/premultiplied alpha + */ + QCheckBox* video_premultiply_alpha_; + + /** + * @brief Setting for this media's color space + */ + QComboBox* video_color_space_; + + /** + * @brief Setting for video interlacing + */ + InterlacedComboBox* video_interlace_combo_; + + /** + * @brief Sets the start index for image sequences + */ + IntegerSlider* imgseq_start_time_; + + /** + * @brief Sets the end index for image sequences + */ + IntegerSlider* imgseq_end_time_; + + /** + * @brief Sets the frame rate for image sequences + */ + FrameRateComboBox* imgseq_frame_rate_; + + /** + * @brief Sets the pixel aspect ratio of the stream + */ + PixelAspectRatioComboBox* pixel_aspect_combo_; + + class VideoStreamChangeCommand : public UndoCommand { + public: + VideoStreamChangeCommand(Footage *footage, + int video_index, + bool premultiplied, + QString colorspace, + VideoParams::Interlacing interlacing, + const rational& pixel_ar); + + virtual Project* GetRelevantProject() const override; + + virtual void redo() override; + virtual void undo() override; + + private: + Footage *footage_; + int video_index_; + + bool new_premultiplied_; + QString new_colorspace_; + VideoParams::Interlacing new_interlacing_; + rational new_pixel_ar_; + + bool old_premultiplied_; + QString old_colorspace_; + VideoParams::Interlacing old_interlacing_; + rational old_pixel_ar_; + + }; + + class ImageSequenceChangeCommand : public UndoCommand { + public: + ImageSequenceChangeCommand(Footage *footage, + int video_index, + int64_t start_index, + int64_t duration, + const rational& frame_rate); + + virtual Project* GetRelevantProject() const override; + + virtual void redo() override; + virtual void undo() override; + + private: + Footage *footage_; + int video_index_; + + int64_t new_start_index_; + int64_t old_start_index_; + + int64_t new_duration_; + int64_t old_duration_; + + rational new_frame_rate_; + rational old_frame_rate_; + + }; + +}; + +} + +#endif // VIDEOSTREAMPROPERTIES_H diff --git a/app/dialog/nodeproperties/nodepropertiesdialog.cpp b/app/dialog/nodeproperties/nodepropertiesdialog.cpp deleted file mode 100644 index fca1935ba..000000000 --- a/app/dialog/nodeproperties/nodepropertiesdialog.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2021 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 "nodepropertiesdialog.h" - -#include -#include - -#include "core.h" -#include "widget/nodeview/nodeviewundo.h" - -namespace olive { - -NodePropertiesDialog::NodePropertiesDialog(Node *node, const rational &timebase, QWidget *parent) : - QDialog(parent), - node_(node) -{ - setWindowTitle(tr("Node Properties")); - - QVBoxLayout *layout = new QVBoxLayout(this); - - QHBoxLayout *label_layout = new QHBoxLayout(); - label_layout->setMargin(0); - layout->addLayout(label_layout); - - label_layout->addWidget(new QLabel(tr("Name:"))); - - label_edit_ = new QLineEdit(); - label_edit_->setText(node->GetLabel()); - label_layout->addWidget(label_edit_); - - NodeParamViewItem *item = new NodeParamViewItem(node, kNoCheckBoxes); - item->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - item->SetTimebase(timebase); - item->setTitleBarWidget(new QWidget()); - layout->addWidget(item); - - layout->addStretch(); - - QDialogButtonBox *btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(btns, &QDialogButtonBox::accepted, this, &NodePropertiesDialog::accept); - connect(btns, &QDialogButtonBox::rejected, this, &NodePropertiesDialog::reject); - layout->addWidget(btns); -} - -void NodePropertiesDialog::accept() -{ - if (label_edit_->text() != node_->GetLabel()) { - NodeRenameCommand* rename_command = new NodeRenameCommand(); - rename_command->AddNode(node_, label_edit_->text()); - Core::instance()->undo_stack()->push(rename_command); - } - - QDialog::accept(); -} - -} diff --git a/app/widget/projectexplorer/projectexplorer.cpp b/app/widget/projectexplorer/projectexplorer.cpp index 9326cd357..4482ac8d7 100644 --- a/app/widget/projectexplorer/projectexplorer.cpp +++ b/app/widget/projectexplorer/projectexplorer.cpp @@ -30,7 +30,7 @@ #include "common/define.h" #include "core.h" -#include "dialog/nodeproperties/nodepropertiesdialog.h" +#include "dialog/footageproperties/footageproperties.h" #include "dialog/sequence/sequence.h" #include "projectexplorerundo.h" #include "task/precache/precachetask.h" @@ -446,8 +446,8 @@ void ProjectExplorer::ShowItemPropertiesDialog() // FIXME: Support for multiple items if (dynamic_cast(sel)) { - NodePropertiesDialog npd(sel, static_cast(sel)->GetVideoParams().time_base(), this); - npd.exec(); + FootagePropertiesDialog fpd(this, static_cast(sel)); + fpd.exec(); } else if (dynamic_cast(sel)) { diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 3416f6e05..a16bdbc31 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -28,7 +28,6 @@ #include "core.h" #include "common/range.h" #include "common/timecodefunctions.h" -#include "dialog/nodeproperties/nodepropertiesdialog.h" #include "dialog/sequence/sequence.h" #include "dialog/speedduration/speeddurationdialog.h" #include "node/block/transition/transition.h" @@ -1023,17 +1022,7 @@ void TimelineWidget::ShowContextMenu() menu.addSeparator(); QAction* properties_action = menu.addAction(tr("Properties")); - connect(properties_action, &QAction::triggered, this, [this](){ - QVector block_items = GetSelectedBlocks(); - QVector nodes; - - foreach (Block* i, block_items) { - nodes.append(i); - } - - NodePropertiesDialog npd(nodes, timebase(), this); - npd.exec(); - }); + connect(properties_action, &QAction::triggered, this, &TimelineWidget::ShowSpeedDurationDialogForSelectedClips); } if (selected.isEmpty()) {