Merge branch 'master' into marker
This commit is contained in:
@@ -21,11 +21,15 @@ add_subdirectory(color)
|
||||
add_subdirectory(configbase)
|
||||
add_subdirectory(diskcache)
|
||||
add_subdirectory(export)
|
||||
add_subdirectory(footageproperties)
|
||||
add_subdirectory(footagerelink)
|
||||
add_subdirectory(keyframeproperties)
|
||||
add_subdirectory(nodeproperties)
|
||||
if(OpenTimelineIO_FOUND)
|
||||
add_subdirectory(otioproperties)
|
||||
endif()
|
||||
add_subdirectory(preferences)
|
||||
add_subdirectory(progress)
|
||||
add_subdirectory(projectproperties)
|
||||
add_subdirectory(rendercancel)
|
||||
add_subdirectory(sequence)
|
||||
add_subdirectory(speedduration)
|
||||
|
||||
@@ -27,6 +27,6 @@ while True:
|
||||
else:
|
||||
break
|
||||
|
||||
text_file = open("patreon.h", "w")
|
||||
text_file = open("patreon.h", "w", encoding="utf-8")
|
||||
text_file.write("#ifndef PATREON_H\n#define PATREON_H\n\n#include <QStringList>\n\nQStringList patrons = {\n%s\n};\n\n#endif // PATREON_H\n" % name_list)
|
||||
text_file.close()
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "dialog/task/task.h"
|
||||
#include "node/project/project.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "task/taskmanager.h"
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
namespace olive {
|
||||
@@ -152,13 +153,27 @@ ExportDialog::ExportDialog(ViewerOutput *viewer_node, QWidget *parent) :
|
||||
|
||||
row++;
|
||||
|
||||
buttons_ = new QDialogButtonBox();
|
||||
buttons_->setCenterButtons(true);
|
||||
buttons_->addButton(tr("Export"), QDialogButtonBox::AcceptRole);
|
||||
buttons_->addButton(QDialogButtonBox::Cancel);
|
||||
connect(buttons_, &QDialogButtonBox::accepted, this, &ExportDialog::StartExport);
|
||||
connect(buttons_, &QDialogButtonBox::rejected, this, &ExportDialog::reject);
|
||||
preferences_layout->addWidget(buttons_, row, 0, 1, 4);
|
||||
QHBoxLayout *btn_layout = new QHBoxLayout();
|
||||
btn_layout->setMargin(0);
|
||||
preferences_layout->addLayout(btn_layout, row, 0, 1, 4);
|
||||
|
||||
btn_layout->addStretch();
|
||||
|
||||
QPushButton *export_btn = new QPushButton(tr("Export"));
|
||||
btn_layout->addWidget(export_btn);
|
||||
connect(export_btn, &QPushButton::clicked, this, &ExportDialog::StartExport);
|
||||
|
||||
QPushButton *cancel_btn = new QPushButton(tr("Cancel"));
|
||||
btn_layout->addWidget(cancel_btn);
|
||||
connect(cancel_btn, &QPushButton::clicked, this, &ExportDialog::reject);
|
||||
|
||||
export_bkg_box_ = new QCheckBox(tr("Run In Background"));
|
||||
export_bkg_box_->setToolTip(tr("Exporting in the background allows you to continue using Olive while "
|
||||
"exporting, but may result in slower export speeds, and may"
|
||||
"severely impact editing and playback performance."));
|
||||
btn_layout->addWidget(export_bkg_box_);
|
||||
|
||||
btn_layout->addStretch();
|
||||
|
||||
splitter->addWidget(preferences_area_);
|
||||
|
||||
@@ -346,9 +361,17 @@ void ExportDialog::StartExport()
|
||||
}
|
||||
|
||||
ExportTask* task = new ExportTask(viewer_node_, color_manager_, GenerateParams());
|
||||
TaskDialog* td = new TaskDialog(task, tr("Export"), this);
|
||||
connect(td, &TaskDialog::TaskSucceeded, this, &ExportDialog::ExportFinished);
|
||||
td->open();
|
||||
|
||||
if (export_bkg_box_->isChecked()) {
|
||||
// Send to TaskManager to export in background
|
||||
TaskManager::instance()->AddTask(task);
|
||||
this->accept();
|
||||
} else {
|
||||
// Use modal dialog box
|
||||
TaskDialog* td = new TaskDialog(task, tr("Export"), this);
|
||||
connect(td, &TaskDialog::TaskSucceeded, this, &ExportDialog::ExportFinished);
|
||||
td->open();
|
||||
}
|
||||
}
|
||||
|
||||
void ExportDialog::ExportFinished()
|
||||
|
||||
@@ -93,7 +93,7 @@ private:
|
||||
ColorManager* color_manager_;
|
||||
|
||||
QWidget* preferences_area_;
|
||||
QDialogButtonBox* buttons_;
|
||||
QCheckBox *export_bkg_box_;
|
||||
|
||||
private slots:
|
||||
void BrowseFilename();
|
||||
|
||||
@@ -232,14 +232,16 @@ void ExportVideoTab::VideoCodecChanged()
|
||||
{
|
||||
ExportCodec::Codec codec = GetSelectedCodec();
|
||||
|
||||
if (codec == ExportCodec::kCodecH264) {
|
||||
SetCodecSection(h264_section_);
|
||||
} else if (codec == ExportCodec::kCodecH265) {
|
||||
SetCodecSection(h265_section_);
|
||||
} else if (ExportCodec::IsCodecAStillImage(codec)) {
|
||||
SetCodecSection(image_section_);
|
||||
} else {
|
||||
SetCodecSection(nullptr);
|
||||
switch (codec) {
|
||||
case ExportCodec::kCodecH264:
|
||||
case ExportCodec::kCodecH264rgb:
|
||||
SetCodecSection(h264_section_);
|
||||
break;
|
||||
case ExportCodec::kCodecH265:
|
||||
SetCodecSection(h265_section_);
|
||||
break;
|
||||
default:
|
||||
SetCodecSection(ExportCodec::IsCodecAStillImage(codec) ? image_section_ : nullptr);
|
||||
}
|
||||
|
||||
// Set default pixel format
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
add_subdirectory(streamproperties)
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
dialog/footageproperties/footageproperties.cpp
|
||||
dialog/footageproperties/footageproperties.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "footageproperties.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QGroupBox>
|
||||
#include <QListWidget>
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
|
||||
#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; i<footage_->GetTotalStreamCount(); 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;i<stacked_widget_->count();i++) {
|
||||
if (!static_cast<StreamProperties*>(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; i<footage_->GetTotalStreamCount(); 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;i<stacked_widget_->count();i++) {
|
||||
static_cast<StreamProperties*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef MEDIAPROPERTIESDIALOG_H
|
||||
#define MEDIAPROPERTIESDIALOG_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QStackedWidget>
|
||||
|
||||
#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;
|
||||
|
||||
protected:
|
||||
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
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
||||
)
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#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_)
|
||||
}
|
||||
|
||||
}
|
||||
+11
-18
@@ -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 <QDialog>
|
||||
|
||||
#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 *> &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
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "streamproperties.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
StreamProperties::StreamProperties(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef STREAMPROPERTIES_H
|
||||
#define STREAMPROPERTIES_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#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
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "videostreamproperties.h"
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
|
||||
#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;i<number_of_colorspaces;i++) {
|
||||
QString colorspace = config->getColorSpaceNameByIndex(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<VideoParams::Interlacing>(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<VideoParams::Interlacing>(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_);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef VIDEOSTREAMPROPERTIES_H
|
||||
#define VIDEOSTREAMPROPERTIES_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
|
||||
#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;
|
||||
|
||||
protected:
|
||||
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;
|
||||
|
||||
protected:
|
||||
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
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "nodepropertiesdialog.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#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);
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
# Olive - Non-Linear Video Editor
|
||||
# Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
dialog/otioproperties/otiopropertiesdialog.h
|
||||
dialog/otioproperties/otiopropertiesdialog.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,89 @@
|
||||
/***
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2019 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 <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "otiopropertiesdialog.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "core.h"
|
||||
#include "dialog/sequence/sequence.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
OTIOPropertiesDialog::OTIOPropertiesDialog(const QList<Sequence*>& sequences, Project* active_project, QWidget* parent)
|
||||
:
|
||||
QDialog(parent),
|
||||
sequences_(sequences)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
QLabel *msg = new QLabel(tr("OpenTimelineIO files do not store sequence parameters (resolution, frame rate, etc.)\n\n"
|
||||
"Please set the correct parameters on the sequences below (they have been set to your default sequence parameters as a starting point)."));
|
||||
msg->setWordWrap(true);
|
||||
layout->addWidget(msg);
|
||||
|
||||
table_ = new QTreeWidget();
|
||||
table_->setColumnCount(2);
|
||||
table_->setHeaderLabels({tr("Sequence"), tr("Actions")});
|
||||
table_->setRootIsDecorated(false);
|
||||
|
||||
for (int i = 0; i < sequences.size(); i++) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
Sequence* s = sequences.at(i);
|
||||
|
||||
QWidget* item_actions = new QWidget();
|
||||
QHBoxLayout* item_actions_layout = new QHBoxLayout(item_actions);
|
||||
QPushButton* item_settings_btn = new QPushButton(tr("Settings"));
|
||||
item_settings_btn->setProperty("index", i);
|
||||
connect(item_settings_btn, &QPushButton::clicked, this, &OTIOPropertiesDialog::SetupSequence);
|
||||
item_actions_layout->addWidget(item_settings_btn);
|
||||
|
||||
item->setText(0, s->GetLabel());
|
||||
|
||||
table_->addTopLevelItem(item);
|
||||
|
||||
table_->setItemWidget(item, 1, item_actions);
|
||||
}
|
||||
|
||||
// Stretch first column to take up as much space as possible, and second column to take as little
|
||||
table_->header()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
table_->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
table_->header()->setStretchLastSection(false);
|
||||
|
||||
layout->addWidget(table_);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &OTIOPropertiesDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &OTIOPropertiesDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
setWindowTitle(tr("Load OpenTimelineIO Project"));
|
||||
}
|
||||
|
||||
void OTIOPropertiesDialog::SetupSequence() {
|
||||
int index = sender()->property("index").toInt();
|
||||
Sequence* s = sequences_.at(index);
|
||||
SequenceDialog sd(s, SequenceDialog::kNew);
|
||||
sd.SetUndoable(false);
|
||||
sd.exec();
|
||||
}
|
||||
|
||||
} // namespace olive
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
#ifndef OTIOPROPERTIESDIALOG_H
|
||||
#define OTIOPROPERTIESDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "common/define.h"
|
||||
#include "opentimelineio/timeline.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "node/project/project.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief Dialog to load setting for OTIO sequences.
|
||||
*
|
||||
* Takes a list of Sequences and allows the setting of options for each.
|
||||
*/
|
||||
class OTIOPropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OTIOPropertiesDialog(const QList<Sequence*>& sequences, Project* active_project, QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
QTreeWidget* table_;
|
||||
|
||||
const QList<Sequence*> sequences_;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief Brings up the Sequence settings dialog.
|
||||
*/
|
||||
void SetupSequence();
|
||||
};
|
||||
|
||||
} //namespace olive
|
||||
|
||||
#endif // OTIOPROPERTIESDIALOG_H
|
||||
@@ -33,12 +33,7 @@ PreferencesAudioTab::PreferencesAudioTab()
|
||||
{
|
||||
QVBoxLayout* audio_tab_layout = new QVBoxLayout(this);
|
||||
|
||||
QLabel *wip_lbl = new QLabel(tr("We just ported our audio backend to PortAudio so this section will need to be redone. Come back later..."));
|
||||
wip_lbl->setWordWrap(true);
|
||||
wip_lbl->setAlignment(Qt::AlignCenter);
|
||||
audio_tab_layout->addWidget(wip_lbl);
|
||||
|
||||
/*{
|
||||
{
|
||||
// Backend Layout
|
||||
QGridLayout* main_layout = new QGridLayout();
|
||||
main_layout->setMargin(0);
|
||||
@@ -48,195 +43,166 @@ PreferencesAudioTab::PreferencesAudioTab()
|
||||
main_layout->addWidget(new QLabel(tr("Backend:")), row, 0);
|
||||
|
||||
audio_backend_combobox_ = new QComboBox();
|
||||
for (int i=0; i<AudioManager::kAudioBackendCount; i++) {
|
||||
audio_backend_combobox_->addItem(AudioManager::GetAudioBackendName(static_cast<AudioManager::Backend>(i)));
|
||||
}
|
||||
connect(audio_backend_combobox_, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &PreferencesAudioTab::RefreshDevices);
|
||||
main_layout->addWidget(audio_backend_combobox_, row, 1);
|
||||
|
||||
audio_tab_layout->addLayout(main_layout);
|
||||
}
|
||||
|
||||
{
|
||||
// Qt-Backend Layout
|
||||
QGroupBox* qt_groupbox = new QGroupBox();
|
||||
audio_tab_layout->addWidget(qt_groupbox);
|
||||
QGroupBox* groupbox = new QGroupBox();
|
||||
audio_tab_layout->addWidget(groupbox);
|
||||
|
||||
QVBoxLayout* qt_layout = new QVBoxLayout(qt_groupbox);
|
||||
QVBoxLayout* layout = new QVBoxLayout(groupbox);
|
||||
|
||||
int row = 0;
|
||||
|
||||
{
|
||||
// Output Group
|
||||
QGroupBox* qt_output_group = new QGroupBox();
|
||||
qt_output_group->setTitle(tr("Output"));
|
||||
qt_layout->addWidget(qt_output_group);
|
||||
QGroupBox* output_group = new QGroupBox();
|
||||
output_group->setTitle(tr("Output"));
|
||||
layout->addWidget(output_group);
|
||||
|
||||
QGridLayout* qt_output_layout = new QGridLayout(qt_output_group);
|
||||
QGridLayout* output_layout = new QGridLayout(output_group);
|
||||
|
||||
qt_output_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
output_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
|
||||
audio_output_devices_ = new QComboBox();
|
||||
qt_output_layout->addWidget(audio_output_devices_, row, 1);
|
||||
output_layout->addWidget(audio_output_devices_, row, 1);
|
||||
}
|
||||
|
||||
row = 0;
|
||||
|
||||
{
|
||||
QGroupBox* qt_input_group = new QGroupBox();
|
||||
qt_input_group->setTitle(tr("Input"));
|
||||
qt_layout->addWidget(qt_input_group);
|
||||
QGroupBox* input_group = new QGroupBox();
|
||||
input_group->setTitle(tr("Input"));
|
||||
layout->addWidget(input_group);
|
||||
|
||||
QGridLayout* qt_input_layout = new QGridLayout(qt_input_group);
|
||||
QGridLayout* input_layout = new QGridLayout(input_group);
|
||||
|
||||
qt_input_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
input_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
|
||||
audio_input_devices_ = new QComboBox();
|
||||
qt_input_layout->addWidget(audio_input_devices_, row, 1);
|
||||
input_layout->addWidget(audio_input_devices_, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
qt_input_layout->addWidget(new QLabel(tr("Recording Mode:"), this), row, 0);
|
||||
input_layout->addWidget(new QLabel(tr("Recording Mode:"), this), row, 0);
|
||||
|
||||
recording_combobox_ = new QComboBox();
|
||||
recording_combobox_->addItem(tr("Mono"));
|
||||
recording_combobox_->addItem(tr("Stereo"));
|
||||
qt_input_layout->addWidget(recording_combobox_, row, 1);
|
||||
input_layout->addWidget(recording_combobox_, row, 1);
|
||||
}
|
||||
|
||||
QHBoxLayout* qt_refresh_layout = new QHBoxLayout();
|
||||
qt_layout->addLayout(qt_refresh_layout);
|
||||
qt_refresh_layout->addStretch();
|
||||
QHBoxLayout* refresh_layout = new QHBoxLayout();
|
||||
layout->addLayout(refresh_layout);
|
||||
refresh_layout->addStretch();
|
||||
|
||||
refresh_devices_btn_ = new QPushButton(tr("Refresh Devices"));
|
||||
qt_refresh_layout->addWidget(refresh_devices_btn_);
|
||||
refresh_layout->addWidget(refresh_devices_btn_);
|
||||
|
||||
RetrieveDeviceLists();
|
||||
|
||||
connect(refresh_devices_btn_, &QPushButton::clicked, this, &PreferencesAudioTab::RefreshDevices);
|
||||
connect(AudioManager::instance(), &AudioManager::OutputListReady, this, &PreferencesAudioTab::RetrieveOutputList);
|
||||
connect(AudioManager::instance(), &AudioManager::InputListReady, this, &PreferencesAudioTab::RetrieveInputList);
|
||||
connect(refresh_devices_btn_, &QPushButton::clicked, this, &PreferencesAudioTab::HardRefreshBackends);
|
||||
}
|
||||
|
||||
audio_tab_layout->addStretch();*/
|
||||
audio_tab_layout->addStretch();
|
||||
|
||||
// Populate lists
|
||||
RefreshBackends();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::Accept(MultiUndoCommand *command)
|
||||
{
|
||||
/*
|
||||
Q_UNUSED(command)
|
||||
|
||||
// FIXME: Qt documentation states that QAudioDeviceInfo::deviceName() is a "unique identifiers", which would make them
|
||||
// ideal for saving in preferences, but in practice they don't actually appear to be unique.
|
||||
// See: https://bugreports.qt.io/browse/QTBUG-16841
|
||||
// Get device indexes
|
||||
PaDeviceIndex output_device = audio_output_devices_->currentData().value<PaDeviceIndex>();
|
||||
PaDeviceIndex input_device = audio_input_devices_->currentData().value<PaDeviceIndex>();
|
||||
|
||||
// If we don't have the device list, we can't set it
|
||||
if (audio_output_devices_->isEnabled()) {
|
||||
// Get device info
|
||||
QAudioDeviceInfo selected_output;
|
||||
QString selected_output_name;
|
||||
// Get device names, which seem to be the closest thing we have to a "unique identifier" for them
|
||||
Config::Current()[QStringLiteral("AudioOutput")] = audio_output_devices_->currentText();
|
||||
Config::Current()[QStringLiteral("AudioInput")] = audio_input_devices_->currentText();
|
||||
|
||||
// Index 0 is always the default device
|
||||
if (audio_output_devices_->currentIndex() == 0) {
|
||||
selected_output = QAudioDeviceInfo::defaultOutputDevice();
|
||||
} else {
|
||||
selected_output = AudioManager::instance()->ListOutputDevices().at(audio_output_devices_->currentData().toInt());
|
||||
selected_output_name = selected_output.deviceName();
|
||||
}
|
||||
// Set devices to be used from now on
|
||||
AudioManager::instance()->SetOutputDevice(output_device);
|
||||
AudioManager::instance()->SetInputDevice(input_device);
|
||||
}
|
||||
|
||||
// Save it in the global application preferences
|
||||
if (Config::Current()["AudioOutput"] != selected_output_name) {
|
||||
Config::Current()["AudioOutput"] = selected_output_name;
|
||||
AudioManager::instance()->SetOutputDevice(selected_output);
|
||||
}
|
||||
void PreferencesAudioTab::RefreshBackends()
|
||||
{
|
||||
audio_backend_combobox_->clear();
|
||||
for (PaHostApiIndex i=0, end=Pa_GetHostApiCount(); i<end; i++) {
|
||||
const PaHostApiInfo *info = Pa_GetHostApiInfo(i);
|
||||
|
||||
audio_backend_combobox_->addItem(info->name);
|
||||
}
|
||||
|
||||
if (audio_input_devices_->isEnabled()) {
|
||||
QAudioDeviceInfo selected_input;
|
||||
QString selected_input_name;
|
||||
RefreshDevices();
|
||||
|
||||
// Index 0 is always the default device
|
||||
if (audio_input_devices_->currentIndex() == 0) {
|
||||
selected_input = QAudioDeviceInfo::defaultInputDevice();
|
||||
} else {
|
||||
selected_input = AudioManager::instance()->ListInputDevices().at(audio_input_devices_->currentData().toInt());
|
||||
selected_input_name = selected_input.deviceName();
|
||||
}
|
||||
|
||||
if (Config::Current()["AudioInput"] != selected_input_name) {
|
||||
Config::Current()["AudioInput"] = selected_input_name;
|
||||
AudioManager::instance()->SetInputDevice(selected_input);
|
||||
}
|
||||
}
|
||||
*/
|
||||
AttemptToSetDevicesFromConfig();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::RefreshDevices()
|
||||
{
|
||||
AudioManager::instance()->RefreshDevices();
|
||||
if (audio_backend_combobox_->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
RetrieveDeviceLists();
|
||||
}
|
||||
PaHostApiIndex host_index = audio_backend_combobox_->currentIndex();
|
||||
const PaHostApiInfo *host = Pa_GetHostApiInfo(host_index);
|
||||
|
||||
void PreferencesAudioTab::RetrieveOutputList()
|
||||
{
|
||||
/*PopulateComboBox(audio_output_devices_,
|
||||
AudioManager::instance()->IsRefreshingOutputs(),
|
||||
AudioManager::instance()->ListOutputDevices(),
|
||||
Config::Current()["AudioOutput"].toString());*/
|
||||
audio_output_devices_->clear();
|
||||
audio_input_devices_->clear();
|
||||
|
||||
UpdateRefreshButtonEnabled();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::RetrieveInputList()
|
||||
{
|
||||
/*PopulateComboBox(audio_input_devices_,
|
||||
AudioManager::instance()->IsRefreshingInputs(),
|
||||
AudioManager::instance()->ListInputDevices(),
|
||||
Config::Current()["AudioInput"].toString());*/
|
||||
|
||||
UpdateRefreshButtonEnabled();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::RetrieveDeviceLists()
|
||||
{
|
||||
RetrieveOutputList();
|
||||
RetrieveInputList();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::UpdateRefreshButtonEnabled()
|
||||
{
|
||||
refresh_devices_btn_->setEnabled(audio_output_devices_->isEnabled()
|
||||
&& audio_input_devices_->isEnabled());
|
||||
}
|
||||
|
||||
/*void PreferencesAudioTab::PopulateComboBox(QComboBox *cb, bool still_refreshing, const QList<QAudioDeviceInfo> &list, const QString& preferred)
|
||||
{
|
||||
cb->clear();
|
||||
|
||||
cb->setEnabled(!still_refreshing);
|
||||
|
||||
if (still_refreshing) {
|
||||
cb->addItem(tr("Please wait..."));
|
||||
} else {
|
||||
bool found_preferred_device = false;
|
||||
|
||||
// Add null default item
|
||||
cb->addItem(tr("Default"), QVariant());
|
||||
|
||||
// For each entry, add it to the combobox
|
||||
for (int i=0;i<list.size();i++) {
|
||||
|
||||
cb->addItem(list.at(i).deviceName(), i);
|
||||
|
||||
if (!found_preferred_device
|
||||
&& list.at(i).deviceName() == preferred) {
|
||||
cb->setCurrentIndex(cb->count()-1);
|
||||
found_preferred_device = true;
|
||||
}
|
||||
for (int i=0; i<host->deviceCount; i++) {
|
||||
PaDeviceIndex device_index = Pa_HostApiDeviceIndexToDeviceIndex(host_index, i);
|
||||
const PaDeviceInfo *device = Pa_GetDeviceInfo(device_index);
|
||||
|
||||
if (device->maxOutputChannels) {
|
||||
audio_output_devices_->addItem(device->name, device_index);
|
||||
}
|
||||
|
||||
if (device->maxInputChannels) {
|
||||
audio_input_devices_->addItem(device->name, device_index);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::HardRefreshBackends()
|
||||
{
|
||||
AudioManager::instance()->HardReset();
|
||||
RefreshBackends();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::AttemptToSetDevicesFromConfig()
|
||||
{
|
||||
// Load with currently active devices
|
||||
PaDeviceIndex current_output_index = AudioManager::instance()->GetOutputDevice();
|
||||
PaDeviceIndex current_input_index = AudioManager::instance()->GetInputDevice();
|
||||
|
||||
const PaDeviceInfo *current_output = nullptr, *current_input = nullptr;
|
||||
if (current_output_index != paNoDevice) {
|
||||
current_output = Pa_GetDeviceInfo(current_output_index);
|
||||
}
|
||||
if (current_input_index != paNoDevice) {
|
||||
current_input = Pa_GetDeviceInfo(current_input_index);
|
||||
}
|
||||
|
||||
if (current_output || current_input) {
|
||||
PaHostApiIndex host = current_output ? current_output->hostApi : current_input->hostApi;
|
||||
|
||||
// Set backend accordingly
|
||||
audio_backend_combobox_->setCurrentIndex(host);
|
||||
|
||||
// Device comboboxes should be populated correctly now
|
||||
if (current_output) {
|
||||
audio_output_devices_->setCurrentText(current_output->name);
|
||||
}
|
||||
|
||||
if (current_input) {
|
||||
audio_input_devices_->setCurrentText(current_input->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,18 +60,13 @@ private:
|
||||
QPushButton* refresh_devices_btn_;
|
||||
|
||||
private slots:
|
||||
void RefreshBackends();
|
||||
|
||||
void RefreshDevices();
|
||||
|
||||
void RetrieveOutputList();
|
||||
void HardRefreshBackends();
|
||||
|
||||
void RetrieveInputList();
|
||||
|
||||
private:
|
||||
void RetrieveDeviceLists();
|
||||
|
||||
void UpdateRefreshButtonEnabled();
|
||||
|
||||
//static void PopulateComboBox(QComboBox* cb, bool still_refreshing, const QList<QAudioDeviceInfo>& list, const QString &preferred);
|
||||
void AttemptToSetDevicesFromConfig();
|
||||
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -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
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
dialog/nodeproperties/nodepropertiesdialog.cpp
|
||||
dialog/nodeproperties/nodepropertiesdialog.h
|
||||
dialog/projectproperties/projectproperties.h
|
||||
dialog/projectproperties/projectproperties.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,255 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "projectproperties.h"
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "common/filefunctions.h"
|
||||
#include "common/ocioutils.h"
|
||||
#include "config/config.h"
|
||||
#include "core.h"
|
||||
#include "node/color/colormanager/colormanager.h"
|
||||
#include "render/diskmanager.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
#define super QDialog
|
||||
|
||||
ProjectPropertiesDialog::ProjectPropertiesDialog(Project* p, QWidget *parent) :
|
||||
super(parent),
|
||||
working_project_(p),
|
||||
ocio_config_is_valid_(true)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
setWindowTitle(tr("Project Properties for '%1'").arg(working_project_->name()));
|
||||
|
||||
QTabWidget* tabs = new QTabWidget;
|
||||
layout->addWidget(tabs);
|
||||
|
||||
{
|
||||
// Color management group
|
||||
QWidget* color_group = new QWidget();
|
||||
|
||||
QVBoxLayout* color_outer_layout = new QVBoxLayout(color_group);
|
||||
|
||||
QGridLayout* color_layout = new QGridLayout();
|
||||
color_outer_layout->addLayout(color_layout);
|
||||
|
||||
int row = 0;
|
||||
|
||||
color_layout->addWidget(new QLabel(tr("OpenColorIO Configuration:")), row, 0);
|
||||
|
||||
ocio_filename_ = new QLineEdit();
|
||||
ocio_filename_->setPlaceholderText(tr("(default)"));
|
||||
color_layout->addWidget(ocio_filename_, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
color_layout->addWidget(new QLabel(tr("Default Input Color Space:")), row, 0);
|
||||
|
||||
default_input_colorspace_ = new QComboBox();
|
||||
color_layout->addWidget(default_input_colorspace_, row, 1, 1, 2);
|
||||
|
||||
row++;
|
||||
|
||||
QPushButton* browse_btn = new QPushButton(tr("Browse"));
|
||||
color_layout->addWidget(browse_btn, 0, 2);
|
||||
connect(browse_btn, &QPushButton::clicked, this, &ProjectPropertiesDialog::BrowseForOCIOConfig);
|
||||
|
||||
ocio_filename_->setText(working_project_->color_manager()->GetConfigFilename());
|
||||
|
||||
connect(ocio_filename_, &QLineEdit::textChanged, this, &ProjectPropertiesDialog::OCIOFilenameUpdated);
|
||||
OCIOFilenameUpdated();
|
||||
|
||||
tabs->addTab(color_group, tr("Color Management"));
|
||||
|
||||
color_outer_layout->addStretch();
|
||||
}
|
||||
|
||||
{
|
||||
// Cache group
|
||||
QWidget* cache_group = new QWidget();
|
||||
|
||||
QVBoxLayout* cache_layout = new QVBoxLayout(cache_group);
|
||||
|
||||
QButtonGroup* disk_cache_btn_group = new QButtonGroup();
|
||||
|
||||
// Create radio buttons and add to widget and button group
|
||||
disk_cache_radios_[ProjectSettingsNode::kCacheUseDefaultLocation] = new QRadioButton(tr("Use Default Location"));
|
||||
disk_cache_radios_[ProjectSettingsNode::kCacheStoreAlongsideProject] = new QRadioButton(tr("Store Alongside Project"));
|
||||
disk_cache_radios_[ProjectSettingsNode::kCacheCustomPath] = new QRadioButton(tr("Use Custom Location:"));
|
||||
for (int i=0; i<kDiskCacheRadioCount; i++) {
|
||||
disk_cache_btn_group->addButton(disk_cache_radios_[i]);
|
||||
cache_layout->addWidget(disk_cache_radios_[i]);
|
||||
}
|
||||
|
||||
// Create custom cache path widget
|
||||
custom_cache_path_ = new PathWidget(working_project_->settings()->GetCustomCachePath(), this);
|
||||
custom_cache_path_->setEnabled(false);
|
||||
cache_layout->addWidget(custom_cache_path_);
|
||||
|
||||
// Ensure custom cache path "enabled" is tied to the radio button being checked
|
||||
connect(disk_cache_radios_[ProjectSettingsNode::kCacheCustomPath], &QRadioButton::toggled, custom_cache_path_, &PathWidget::setEnabled);
|
||||
|
||||
// Check the radio button that should currently be active
|
||||
disk_cache_radios_[working_project_->settings()->GetCacheSetting()]->setChecked(true);
|
||||
|
||||
// Add disk cache settings button
|
||||
QPushButton* disk_cache_settings_btn = new QPushButton(tr("Disk Cache Settings"));
|
||||
connect(disk_cache_settings_btn, &QPushButton::clicked, this, &ProjectPropertiesDialog::OpenDiskCacheSettings);
|
||||
cache_layout->addWidget(disk_cache_settings_btn);
|
||||
|
||||
tabs->addTab(cache_group, tr("Disk Cache"));
|
||||
}
|
||||
|
||||
QDialogButtonBox* dialog_btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
|
||||
Qt::Horizontal);
|
||||
layout->addWidget(dialog_btns);
|
||||
connect(dialog_btns, &QDialogButtonBox::accepted, this, &ProjectPropertiesDialog::accept);
|
||||
connect(dialog_btns, &QDialogButtonBox::rejected, this, &ProjectPropertiesDialog::reject);
|
||||
}
|
||||
|
||||
void ProjectPropertiesDialog::accept()
|
||||
{
|
||||
if (!ocio_config_is_valid_) {
|
||||
QMessageBox mb(this);
|
||||
mb.setWindowModality(Qt::WindowModal);
|
||||
mb.setIcon(QMessageBox::Critical);
|
||||
mb.setWindowTitle(tr("OpenColorIO Config Error"));
|
||||
mb.setText(tr("Failed to set OpenColorIO configuration: %1").arg(ocio_config_error_));
|
||||
mb.addButton(QMessageBox::Ok);
|
||||
mb.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
if (disk_cache_radios_[ProjectSettingsNode::kCacheUseDefaultLocation]->isChecked()) {
|
||||
// Keep new cache path empty, which means default
|
||||
} else if (disk_cache_radios_[ProjectSettingsNode::kCacheStoreAlongsideProject]->isChecked()) {
|
||||
// Ensure alongside project path is valid
|
||||
if (!VerifyPathAndWarnIfBad(working_project_->get_cache_alongside_project_path())) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Ensure custom path is valid
|
||||
if (!VerifyPathAndWarnIfBad(custom_cache_path_->text())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (custom_cache_path_->text() != working_project_->settings()->GetCustomCachePath()) {
|
||||
// Check if the user is okay with invalidating the current cache
|
||||
if (!DiskManager::ShowDiskCacheChangeConfirmationDialog(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
working_project_->settings()->SetCustomCachePath(custom_cache_path_->text());
|
||||
|
||||
emit DiskManager::instance()->InvalidateProject(working_project_);
|
||||
}
|
||||
|
||||
// This should ripple changes throughout the graph/cache that the color config has changed, and
|
||||
// therefore should be done after the cache path is changed
|
||||
if (working_project_->color_manager()->GetConfigFilename() != ocio_filename_->text()) {
|
||||
working_project_->color_manager()->SetConfigFilename(ocio_filename_->text());
|
||||
}
|
||||
if (working_project_->color_manager()->GetDefaultInputColorSpace() != default_input_colorspace_->currentText()) {
|
||||
working_project_->color_manager()->SetDefaultInputColorSpace(default_input_colorspace_->currentText());
|
||||
}
|
||||
|
||||
super::accept();
|
||||
}
|
||||
|
||||
bool ProjectPropertiesDialog::VerifyPathAndWarnIfBad(const QString &path)
|
||||
{
|
||||
if (!FileFunctions::DirectoryIsValid(path, true)) {
|
||||
QMessageBox mb(this);
|
||||
mb.setWindowModality(Qt::WindowModal);
|
||||
mb.setIcon(QMessageBox::Critical);
|
||||
mb.setWindowTitle(tr("Invalid path"));
|
||||
mb.setText(tr("The custom cache path is invalid. Please check it and try again."));
|
||||
mb.addButton(QMessageBox::Ok);
|
||||
mb.exec();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProjectPropertiesDialog::BrowseForOCIOConfig()
|
||||
{
|
||||
QString fn = QFileDialog::getOpenFileName(this, tr("Browse for OpenColorIO configuration"));
|
||||
if (!fn.isEmpty()) {
|
||||
ocio_filename_->setText(fn);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectPropertiesDialog::OCIOFilenameUpdated()
|
||||
{
|
||||
default_input_colorspace_->clear();
|
||||
|
||||
try {
|
||||
OCIO::ConstConfigRcPtr c;
|
||||
|
||||
if (ocio_filename_->text().isEmpty()) {
|
||||
c = ColorManager::GetDefaultConfig();
|
||||
} else {
|
||||
c = ColorManager::CreateConfigFromFile(ocio_filename_->text());
|
||||
}
|
||||
|
||||
ocio_filename_->setStyleSheet(QString());
|
||||
ocio_config_is_valid_ = true;
|
||||
|
||||
// List input color spaces
|
||||
QStringList input_cs = ColorManager::ListAvailableColorspaces(c);
|
||||
|
||||
foreach (QString cs, input_cs) {
|
||||
default_input_colorspace_->addItem(cs);
|
||||
|
||||
if (cs == working_project_->color_manager()->GetDefaultInputColorSpace()) {
|
||||
default_input_colorspace_->setCurrentIndex(default_input_colorspace_->count()-1);
|
||||
}
|
||||
}
|
||||
} catch (OCIO::Exception& e) {
|
||||
ocio_config_is_valid_ = false;
|
||||
ocio_filename_->setStyleSheet(QStringLiteral("QLineEdit {color: red;}"));
|
||||
ocio_config_error_ = e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectPropertiesDialog::OpenDiskCacheSettings()
|
||||
{
|
||||
if (disk_cache_radios_[ProjectSettingsNode::kCacheUseDefaultLocation]->isChecked()) {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(DiskManager::instance()->GetDefaultCacheFolder(), this);
|
||||
} else if (disk_cache_radios_[ProjectSettingsNode::kCacheStoreAlongsideProject]->isChecked()) {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(working_project_->get_cache_alongside_project_path(), this);
|
||||
} else {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(custom_cache_path_->text(), this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/***
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#ifndef PROJECTPROPERTIESDIALOG_H
|
||||
#define PROJECTPROPERTIESDIALOG_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QGridLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QRadioButton>
|
||||
|
||||
#include "node/project/project.h"
|
||||
#include "widget/path/pathwidget.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProjectPropertiesDialog(Project *p, QWidget* parent);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
bool VerifyPathAndWarnIfBad(const QString &path);
|
||||
|
||||
Project* working_project_;
|
||||
|
||||
QLineEdit* ocio_filename_;
|
||||
|
||||
QComboBox* default_input_colorspace_;
|
||||
|
||||
bool ocio_config_is_valid_;
|
||||
|
||||
QString ocio_config_error_;
|
||||
|
||||
PathWidget* custom_cache_path_;
|
||||
|
||||
static const int kDiskCacheRadioCount = 3;
|
||||
QRadioButton *disk_cache_radios_[kDiskCacheRadioCount];
|
||||
|
||||
private slots:
|
||||
void BrowseForOCIOConfig();
|
||||
|
||||
void OCIOFilenameUpdated();
|
||||
|
||||
void OpenDiskCacheSettings();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PROJECTPROPERTIESDIALOG_H
|
||||
@@ -63,6 +63,8 @@ private:
|
||||
|
||||
};
|
||||
|
||||
using PresetPtr = std::shared_ptr<Preset>;
|
||||
|
||||
template <typename T>
|
||||
class PresetManager
|
||||
{
|
||||
@@ -80,7 +82,7 @@ public:
|
||||
if (reader.name() == QStringLiteral("presets")) {
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("preset")) {
|
||||
Preset* p = new T();
|
||||
PresetPtr p = std::make_unique<T>();
|
||||
|
||||
p->Load(&reader);
|
||||
|
||||
@@ -110,7 +112,7 @@ public:
|
||||
|
||||
writer.writeStartElement(QStringLiteral("presets"));
|
||||
|
||||
foreach (Preset* p, custom_preset_data_) {
|
||||
foreach (PresetPtr p, custom_preset_data_) {
|
||||
writer.writeStartElement(QStringLiteral("preset"));
|
||||
|
||||
p->Save(&writer);
|
||||
@@ -124,8 +126,6 @@ public:
|
||||
|
||||
preset_file.close();
|
||||
}
|
||||
|
||||
qDeleteAll(custom_preset_data_);
|
||||
}
|
||||
|
||||
QString GetPresetName(QString start) const
|
||||
@@ -159,7 +159,13 @@ public:
|
||||
return start;
|
||||
}
|
||||
|
||||
bool SavePreset(Preset* preset)
|
||||
enum SaveStatus {
|
||||
kAppended,
|
||||
kReplaced,
|
||||
kNotSaved
|
||||
};
|
||||
|
||||
SaveStatus SavePreset(PresetPtr preset)
|
||||
{
|
||||
QString preset_name;
|
||||
int existing_preset;
|
||||
@@ -169,7 +175,7 @@ public:
|
||||
|
||||
if (preset_name.isEmpty()) {
|
||||
// Dialog cancelled - leave function entirely
|
||||
return false;
|
||||
return kNotSaved;
|
||||
}
|
||||
|
||||
existing_preset = -1;
|
||||
@@ -194,10 +200,10 @@ public:
|
||||
|
||||
if (existing_preset >= 0) {
|
||||
custom_preset_data_.replace(existing_preset, preset);
|
||||
return false;
|
||||
return kReplaced;
|
||||
} else {
|
||||
custom_preset_data_.append(preset);
|
||||
return true;
|
||||
return kAppended;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +212,7 @@ public:
|
||||
return QDir(FileFunctions::GetConfigurationLocation()).filePath(preset_name_);
|
||||
}
|
||||
|
||||
Preset* GetPreset(int index)
|
||||
PresetPtr GetPreset(int index)
|
||||
{
|
||||
return custom_preset_data_.at(index);
|
||||
}
|
||||
@@ -221,13 +227,13 @@ public:
|
||||
return custom_preset_data_.size();
|
||||
}
|
||||
|
||||
const QVector<Preset*>& GetPresetData() const
|
||||
const QVector<PresetPtr>& GetPresetData() const
|
||||
{
|
||||
return custom_preset_data_;
|
||||
}
|
||||
|
||||
private:
|
||||
QVector<Preset*> custom_preset_data_;
|
||||
QVector<PresetPtr> custom_preset_data_;
|
||||
|
||||
QString preset_name_;
|
||||
|
||||
|
||||
@@ -19,11 +19,28 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg
|
||||
// Set up video section
|
||||
QGroupBox* video_group = new QGroupBox();
|
||||
video_group->setTitle(tr("Video"));
|
||||
QHBoxLayout* video_layout = new QHBoxLayout(video_group);
|
||||
video_section_ = new VideoParamEdit();
|
||||
video_section_->SetParameterMask(Sequence::kVideoParamEditMask);
|
||||
connect(video_section_, &VideoParamEdit::Changed, this, &SequenceDialogParameterTab::UpdatePreviewResolutionLabel);
|
||||
video_layout->addWidget(video_section_);
|
||||
QGridLayout *video_layout = new QGridLayout(video_group);
|
||||
video_layout->addWidget(new QLabel(tr("Width:")), row, 0);
|
||||
width_slider_ = new IntegerSlider();
|
||||
width_slider_->SetMinimum(0);
|
||||
video_layout->addWidget(width_slider_, row, 1);
|
||||
row++;
|
||||
video_layout->addWidget(new QLabel(tr("Height:")), row, 0);
|
||||
height_slider_ = new IntegerSlider();
|
||||
height_slider_->SetMinimum(0);
|
||||
video_layout->addWidget(height_slider_, row, 1);
|
||||
row++;
|
||||
video_layout->addWidget(new QLabel(tr("Frame Rate:")), row, 0);
|
||||
framerate_combo_ = new FrameRateComboBox();
|
||||
video_layout->addWidget(framerate_combo_, row, 1);
|
||||
row++;
|
||||
video_layout->addWidget(new QLabel(tr("Pixel Aspect Ratio:")), row, 0);
|
||||
pixelaspect_combo_ = new PixelAspectRatioComboBox();
|
||||
video_layout->addWidget(pixelaspect_combo_, row, 1);
|
||||
row++;
|
||||
video_layout->addWidget(new QLabel(tr("Interlacing:")), row, 0);
|
||||
interlacing_combo_ = new InterlacedComboBox();
|
||||
video_layout->addWidget(interlacing_combo_, row, 1);
|
||||
layout->addWidget(video_group);
|
||||
|
||||
row = 0;
|
||||
@@ -65,7 +82,11 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg
|
||||
// Set values based on input sequence
|
||||
VideoParams vp = sequence->GetVideoParams();
|
||||
AudioParams ap = sequence->GetAudioParams();
|
||||
video_section_->SetVideoParams(vp);
|
||||
width_slider_->SetValue(vp.width());
|
||||
height_slider_->SetValue(vp.height());
|
||||
framerate_combo_->SetFrameRate(vp.time_base().flipped());
|
||||
pixelaspect_combo_->SetPixelAspectRatio(vp.pixel_aspect_ratio());
|
||||
interlacing_combo_->SetInterlaceMode(vp.interlacing());
|
||||
preview_resolution_field_->SetDivider(vp.divider());
|
||||
preview_format_field_->SetPixelFormat(vp.format());
|
||||
preview_autocache_field_->setChecked(sequence->GetVideoAutoCacheEnabled());
|
||||
@@ -86,11 +107,11 @@ SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidg
|
||||
|
||||
void SequenceDialogParameterTab::PresetChanged(const SequencePreset &preset)
|
||||
{
|
||||
video_section_->SetWidth(preset.width());
|
||||
video_section_->SetHeight(preset.height());
|
||||
video_section_->SetFrameRate(preset.frame_rate());
|
||||
video_section_->SetPixelAspectRatio(preset.pixel_aspect());
|
||||
video_section_->SetInterlaceMode(preset.interlacing());
|
||||
width_slider_->SetValue(preset.width());
|
||||
height_slider_->SetValue(preset.height());
|
||||
framerate_combo_->SetFrameRate(preset.frame_rate());
|
||||
pixelaspect_combo_->SetPixelAspectRatio(preset.pixel_aspect());
|
||||
interlacing_combo_->SetInterlaceMode(preset.interlacing());
|
||||
audio_sample_rate_field_->SetSampleRate(preset.sample_rate());
|
||||
audio_channels_field_->SetChannelLayout(preset.channel_layout());
|
||||
preview_resolution_field_->SetDivider(preset.preview_divider());
|
||||
@@ -115,8 +136,8 @@ void SequenceDialogParameterTab::SavePresetClicked()
|
||||
|
||||
void SequenceDialogParameterTab::UpdatePreviewResolutionLabel()
|
||||
{
|
||||
VideoParams test_param(video_section_->GetWidth(),
|
||||
video_section_->GetHeight(),
|
||||
VideoParams test_param(GetSelectedVideoWidth(),
|
||||
GetSelectedVideoHeight(),
|
||||
VideoParams::kFormatInvalid,
|
||||
VideoParams::kInternalChannelCount,
|
||||
rational(1),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef SEQUENCEDIALOGPARAMETERTAB_H
|
||||
#define SEQUENCEDIALOGPARAMETERTAB_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QList>
|
||||
#include <QSpinBox>
|
||||
@@ -9,7 +10,6 @@
|
||||
#include "sequencepreset.h"
|
||||
#include "widget/slider/integerslider.h"
|
||||
#include "widget/standardcombos/standardcombos.h"
|
||||
#include "widget/videoparamedit/videoparamedit.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -21,27 +21,27 @@ public:
|
||||
|
||||
int GetSelectedVideoWidth() const
|
||||
{
|
||||
return video_section_->GetWidth();
|
||||
return width_slider_->GetValue();
|
||||
}
|
||||
|
||||
int GetSelectedVideoHeight() const
|
||||
{
|
||||
return video_section_->GetHeight();
|
||||
return height_slider_->GetValue();
|
||||
}
|
||||
|
||||
rational GetSelectedVideoFrameRate() const
|
||||
{
|
||||
return video_section_->GetFrameRate();
|
||||
return framerate_combo_->GetFrameRate();
|
||||
}
|
||||
|
||||
rational GetSelectedVideoPixelAspect() const
|
||||
{
|
||||
return video_section_->GetPixelAspectRatio();
|
||||
return pixelaspect_combo_->GetPixelAspectRatio();
|
||||
}
|
||||
|
||||
VideoParams::Interlacing GetSelectedVideoInterlacingMode() const
|
||||
{
|
||||
return video_section_->GetInterlaceMode();
|
||||
return interlacing_combo_->GetInterlaceMode();
|
||||
}
|
||||
|
||||
int GetSelectedAudioSampleRate() const
|
||||
@@ -76,7 +76,15 @@ signals:
|
||||
void SaveParametersAsPreset(const SequencePreset& preset);
|
||||
|
||||
private:
|
||||
VideoParamEdit* video_section_;
|
||||
IntegerSlider *width_slider_;
|
||||
|
||||
IntegerSlider *height_slider_;
|
||||
|
||||
FrameRateComboBox *framerate_combo_;
|
||||
|
||||
PixelAspectRatioComboBox *pixelaspect_combo_;
|
||||
|
||||
InterlacedComboBox *interlacing_combo_;
|
||||
|
||||
SampleRateComboBox* audio_sample_rate_field_;
|
||||
|
||||
|
||||
@@ -79,19 +79,13 @@ SequenceDialogPresetTab::SequenceDialogPresetTab(QWidget* parent) :
|
||||
}
|
||||
}
|
||||
|
||||
SequenceDialogPresetTab::~SequenceDialogPresetTab()
|
||||
{
|
||||
qDeleteAll(default_preset_data_);
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::SaveParametersAsPreset(SequencePreset preset)
|
||||
{
|
||||
Preset* preset_ptr = new SequencePreset(preset);
|
||||
PresetPtr preset_ptr = std::make_shared<SequencePreset>(preset);
|
||||
|
||||
if (SavePreset(preset_ptr)) {
|
||||
// If replaced, no need to make another item. If not saved, shared ptr will delete itself
|
||||
if (SavePreset(preset_ptr) == kAppended) {
|
||||
AddCustomItem(my_presets_folder_, preset_ptr, GetNumberOfPresets() - 1);
|
||||
} else {
|
||||
delete preset_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +102,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &na
|
||||
const VideoParams::Format default_format = static_cast<VideoParams::Format>(Config::Current()["OfflinePixelFormat"].toInt());
|
||||
const bool default_autocache = Config::Current()[QStringLiteral("DefaultSequenceAutoCache")].toBool();
|
||||
QTreeWidgetItem* parent = CreateFolder(name);
|
||||
AddStandardItem(parent, new SequencePreset(tr("%1 23.976 FPS").arg(name),
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 23.976 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(24000, 1001),
|
||||
@@ -119,7 +113,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &na
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, new SequencePreset(tr("%1 25 FPS").arg(name),
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 25 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(25, 1),
|
||||
@@ -130,7 +124,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &na
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, new SequencePreset(tr("%1 29.97 FPS").arg(name),
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 29.97 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(30000, 1001),
|
||||
@@ -141,7 +135,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &na
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, new SequencePreset(tr("%1 50 FPS").arg(name),
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 50 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(50, 1),
|
||||
@@ -152,7 +146,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &na
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, new SequencePreset(tr("%1 59.94 FPS").arg(name),
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 59.94 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(60000, 1001),
|
||||
@@ -172,7 +166,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateSDPresetFolder(const QString &na
|
||||
const bool default_autocache = Config::Current()[QStringLiteral("DefaultSequenceAutoCache")].toBool();
|
||||
QTreeWidgetItem* parent = CreateFolder(name);
|
||||
preset_tree_->addTopLevelItem(parent);
|
||||
AddStandardItem(parent, new SequencePreset(tr("%1 Standard").arg(name),
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 Standard").arg(name),
|
||||
width,
|
||||
height,
|
||||
frame_rate,
|
||||
@@ -183,7 +177,7 @@ QTreeWidgetItem *SequenceDialogPresetTab::CreateSDPresetFolder(const QString &na
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, new SequencePreset(tr("%1 Widescreen").arg(name),
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 Widescreen").arg(name),
|
||||
width,
|
||||
height,
|
||||
frame_rate,
|
||||
@@ -221,19 +215,19 @@ QTreeWidgetItem *SequenceDialogPresetTab::GetSelectedCustomPreset()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::AddStandardItem(QTreeWidgetItem *folder, Preset* preset, const QString& description)
|
||||
void SequenceDialogPresetTab::AddStandardItem(QTreeWidgetItem *folder, PresetPtr preset, const QString& description)
|
||||
{
|
||||
int index = default_preset_data_.size();
|
||||
default_preset_data_.append(preset);
|
||||
AddItemInternal(folder, preset, false, index, description);
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::AddCustomItem(QTreeWidgetItem *folder, Preset* preset, int index, const QString &description)
|
||||
void SequenceDialogPresetTab::AddCustomItem(QTreeWidgetItem *folder, PresetPtr preset, int index, const QString &description)
|
||||
{
|
||||
AddItemInternal(folder, preset, true, index, description);
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::AddItemInternal(QTreeWidgetItem *folder, Preset* preset, bool is_custom, int index, const QString &description)
|
||||
void SequenceDialogPresetTab::AddItemInternal(QTreeWidgetItem *folder, PresetPtr preset, bool is_custom, int index, const QString &description)
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
|
||||
@@ -254,11 +248,11 @@ void SequenceDialogPresetTab::SelectedItemChanged(QTreeWidgetItem* current, QTre
|
||||
if (current->data(0, kDataIsPreset).toBool()) {
|
||||
int preset_index = current->data(0, kDataPresetDataRole).toInt();
|
||||
|
||||
Preset* preset_data = (current->data(0, kDataPresetIsCustomRole).toBool())
|
||||
PresetPtr preset_data = (current->data(0, kDataPresetIsCustomRole).toBool())
|
||||
? GetPreset(preset_index)
|
||||
: default_preset_data_.at(preset_index);
|
||||
|
||||
emit PresetChanged(*static_cast<SequencePreset*>(preset_data));
|
||||
emit PresetChanged(*static_cast<SequencePreset*>(preset_data.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,6 @@ class SequenceDialogPresetTab : public QWidget, public PresetManager<SequencePre
|
||||
public:
|
||||
SequenceDialogPresetTab(QWidget* parent = nullptr);
|
||||
|
||||
virtual ~SequenceDialogPresetTab() override;
|
||||
|
||||
public slots:
|
||||
void SaveParametersAsPreset(SequencePreset preset);
|
||||
|
||||
@@ -56,17 +54,17 @@ private:
|
||||
QTreeWidgetItem* GetSelectedItem();
|
||||
QTreeWidgetItem* GetSelectedCustomPreset();
|
||||
|
||||
void AddStandardItem(QTreeWidgetItem* folder, Preset* preset, const QString &description = QString());
|
||||
void AddStandardItem(QTreeWidgetItem* folder, PresetPtr preset, const QString &description = QString());
|
||||
|
||||
void AddCustomItem(QTreeWidgetItem* folder, Preset* preset, int index, const QString& description = QString());
|
||||
void AddCustomItem(QTreeWidgetItem* folder, PresetPtr preset, int index, const QString& description = QString());
|
||||
|
||||
void AddItemInternal(QTreeWidgetItem* folder, Preset* preset, bool is_custom, int index, const QString& description = QString());
|
||||
void AddItemInternal(QTreeWidgetItem* folder, PresetPtr preset, bool is_custom, int index, const QString& description = QString());
|
||||
|
||||
QTreeWidget* preset_tree_;
|
||||
|
||||
QTreeWidgetItem* my_presets_folder_;
|
||||
|
||||
QVector<Preset*> default_preset_data_;
|
||||
QVector<PresetPtr> default_preset_data_;
|
||||
|
||||
private slots:
|
||||
void SelectedItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
||||
|
||||
Reference in New Issue
Block a user