change: change code style to Linux style except indent.
This commit is contained in:
+96
-83
@@ -30,114 +30,127 @@
|
||||
#include "patreon.h"
|
||||
#include "scrollinglabel.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
AboutDialog::AboutDialog(bool welcome_dialog, QWidget *parent) :
|
||||
QDialog(parent)
|
||||
namespace olive
|
||||
{
|
||||
if (welcome_dialog) {
|
||||
setWindowTitle(tr("Welcome to %1").arg(QApplication::applicationName()));
|
||||
} else {
|
||||
setWindowTitle(tr("About %1").arg(QApplication::applicationName()));
|
||||
}
|
||||
|
||||
QFontMetrics fm = fontMetrics();
|
||||
AboutDialog::AboutDialog(bool welcome_dialog, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
if (welcome_dialog) {
|
||||
setWindowTitle(
|
||||
tr("Welcome to %1").arg(QApplication::applicationName()));
|
||||
} else {
|
||||
setWindowTitle(tr("About %1").arg(QApplication::applicationName()));
|
||||
}
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(fm.height(), fm.height(), fm.height(), fm.height());
|
||||
QFontMetrics fm = fontMetrics();
|
||||
|
||||
QHBoxLayout *horiz_layout = new QHBoxLayout();
|
||||
horiz_layout->setContentsMargins(fm.height(), fm.height(), fm.height(), fm.height());
|
||||
horiz_layout->setSpacing(fm.height()*2);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(fm.height(), fm.height(), fm.height(),
|
||||
fm.height());
|
||||
|
||||
QLabel* icon = new QLabel(QStringLiteral("<html><img src=':/graphics/olive-splash.png'></html>"));
|
||||
icon->setAlignment(Qt::AlignCenter);
|
||||
horiz_layout->addWidget(icon);
|
||||
QHBoxLayout *horiz_layout = new QHBoxLayout();
|
||||
horiz_layout->setContentsMargins(fm.height(), fm.height(), fm.height(),
|
||||
fm.height());
|
||||
horiz_layout->setSpacing(fm.height() * 2);
|
||||
|
||||
// Construct About text
|
||||
QLabel* label =
|
||||
new QLabel(QStringLiteral("<html><head/><body>"
|
||||
"<p><b>%1</b> %2</p>" // AppName (version identifier)
|
||||
"<p><a href=\"https://www.olivevideoeditor.org/\">"
|
||||
"https://www.olivevideoeditor.org/"
|
||||
"</a></p>"
|
||||
"<p>%3</p>" // First statement
|
||||
"</body></html>").arg(QApplication::applicationName(),
|
||||
QApplication::applicationVersion(),
|
||||
tr("Olive is a free open source non-linear video editor. "
|
||||
"This software is licensed under the GNU GPL Version 3.")));
|
||||
QLabel *icon = new QLabel(
|
||||
QStringLiteral("<html><img src=':/graphics/olive-splash.png'></html>"));
|
||||
icon->setAlignment(Qt::AlignCenter);
|
||||
horiz_layout->addWidget(icon);
|
||||
|
||||
// Set text formatting
|
||||
label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
label->setWordWrap(true);
|
||||
label->setOpenExternalLinks(true);
|
||||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse);
|
||||
label->setCursor(Qt::IBeamCursor);
|
||||
horiz_layout->addWidget(label);
|
||||
// Construct About text
|
||||
QLabel *label = new QLabel(
|
||||
QStringLiteral("<html><head/><body>"
|
||||
"<p><b>%1</b> %2</p>" // AppName (version identifier)
|
||||
"<p><a href=\"https://www.olivevideoeditor.org/\">"
|
||||
"https://www.olivevideoeditor.org/"
|
||||
"</a></p>"
|
||||
"<p>%3</p>" // First statement
|
||||
"</body></html>")
|
||||
.arg(QApplication::applicationName(),
|
||||
QApplication::applicationVersion(),
|
||||
tr("Olive is a free open source non-linear video editor. "
|
||||
"This software is licensed under the GNU GPL Version 3.")));
|
||||
|
||||
layout->addLayout(horiz_layout);
|
||||
// Set text formatting
|
||||
label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
label->setWordWrap(true);
|
||||
label->setOpenExternalLinks(true);
|
||||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
label->setTextInteractionFlags(Qt::TextSelectableByMouse |
|
||||
Qt::LinksAccessibleByMouse);
|
||||
label->setCursor(Qt::IBeamCursor);
|
||||
horiz_layout->addWidget(label);
|
||||
|
||||
// Patrons where possible
|
||||
layout->addWidget(new QLabel());
|
||||
layout->addLayout(horiz_layout);
|
||||
|
||||
QString opening_statement;
|
||||
// Patrons where possible
|
||||
layout->addWidget(new QLabel());
|
||||
|
||||
if (welcome_dialog || patrons.isEmpty()) {
|
||||
opening_statement = tr("<b>Olive relies on support from the community to continue its development.</b>");
|
||||
} else {
|
||||
opening_statement = tr("Olive wouldn't be possible without the support of gracious donations from the following people.");
|
||||
}
|
||||
QString opening_statement;
|
||||
|
||||
QLabel* support_lbl = new QLabel(tr("<html>%1 "
|
||||
"If you like this project, please consider making a "
|
||||
"<a href='https://olivevideoeditor.org/donate.php'>one-time donation</a> or "
|
||||
"<a href='https://www.patreon.com/olivevideoeditor'>pledging monthly</a> to "
|
||||
"support its development.</html>").arg(opening_statement));
|
||||
support_lbl->setWordWrap(true);
|
||||
support_lbl->setAlignment(Qt::AlignCenter);
|
||||
support_lbl->setOpenExternalLinks(true);
|
||||
layout->addWidget(support_lbl);
|
||||
if (welcome_dialog || patrons.isEmpty()) {
|
||||
opening_statement = tr(
|
||||
"<b>Olive relies on support from the community to continue its development.</b>");
|
||||
} else {
|
||||
opening_statement = tr(
|
||||
"Olive wouldn't be possible without the support of gracious donations from the following people.");
|
||||
}
|
||||
|
||||
if (!patrons.isEmpty()) {
|
||||
ScrollingLabel* scroll = new ScrollingLabel(patrons);
|
||||
scroll->StartAnimating();
|
||||
layout->addWidget(scroll);
|
||||
}
|
||||
QLabel *support_lbl = new QLabel(
|
||||
tr("<html>%1 "
|
||||
"If you like this project, please consider making a "
|
||||
"<a href='https://olivevideoeditor.org/donate.php'>one-time donation</a> or "
|
||||
"<a href='https://www.patreon.com/olivevideoeditor'>pledging monthly</a> to "
|
||||
"support its development.</html>")
|
||||
.arg(opening_statement));
|
||||
support_lbl->setWordWrap(true);
|
||||
support_lbl->setAlignment(Qt::AlignCenter);
|
||||
support_lbl->setOpenExternalLinks(true);
|
||||
layout->addWidget(support_lbl);
|
||||
|
||||
layout->addWidget(new QLabel());
|
||||
if (!patrons.isEmpty()) {
|
||||
ScrollingLabel *scroll = new ScrollingLabel(patrons);
|
||||
scroll->StartAnimating();
|
||||
layout->addWidget(scroll);
|
||||
}
|
||||
|
||||
QHBoxLayout *btn_layout = new QHBoxLayout();
|
||||
btn_layout->setContentsMargins(0, 0, 0, 0);
|
||||
btn_layout->setSpacing(0);
|
||||
layout->addWidget(new QLabel());
|
||||
|
||||
if (welcome_dialog) {
|
||||
dont_show_again_checkbox_ = new QCheckBox(tr("Don't show this message again"));
|
||||
btn_layout->addWidget(dont_show_again_checkbox_);
|
||||
} else {
|
||||
dont_show_again_checkbox_ = nullptr;
|
||||
}
|
||||
QHBoxLayout *btn_layout = new QHBoxLayout();
|
||||
btn_layout->setContentsMargins(0, 0, 0, 0);
|
||||
btn_layout->setSpacing(0);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok, this);
|
||||
if (!welcome_dialog) {
|
||||
buttons->setCenterButtons(true);
|
||||
}
|
||||
btn_layout->addWidget(buttons);
|
||||
if (welcome_dialog) {
|
||||
dont_show_again_checkbox_ =
|
||||
new QCheckBox(tr("Don't show this message again"));
|
||||
btn_layout->addWidget(dont_show_again_checkbox_);
|
||||
} else {
|
||||
dont_show_again_checkbox_ = nullptr;
|
||||
}
|
||||
|
||||
layout->addLayout(btn_layout);
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok, this);
|
||||
if (!welcome_dialog) {
|
||||
buttons->setCenterButtons(true);
|
||||
}
|
||||
btn_layout->addWidget(buttons);
|
||||
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
layout->addLayout(btn_layout);
|
||||
|
||||
setFixedSize(sizeHint());
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
|
||||
setFixedSize(sizeHint());
|
||||
}
|
||||
|
||||
void AboutDialog::accept()
|
||||
{
|
||||
if (dont_show_again_checkbox_ && dont_show_again_checkbox_->isChecked()) {
|
||||
OLIVE_CONFIG("ShowWelcomeDialog") = false;
|
||||
}
|
||||
if (dont_show_again_checkbox_ && dont_show_again_checkbox_->isChecked()) {
|
||||
OLIVE_CONFIG("ShowWelcomeDialog") = false;
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief The AboutDialog class
|
||||
@@ -34,11 +35,10 @@ namespace olive {
|
||||
* The About dialog (accessible through Help > About). Contains license and version information. This can be run from
|
||||
* anywhere
|
||||
*/
|
||||
class AboutDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
class AboutDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief AboutDialog Constructor
|
||||
*
|
||||
* Creates About dialog.
|
||||
@@ -47,14 +47,13 @@ public:
|
||||
*
|
||||
* QWidget parent object. Usually this will be MainWindow.
|
||||
*/
|
||||
explicit AboutDialog(bool welcome_dialog, QWidget *parent = nullptr);
|
||||
explicit AboutDialog(bool welcome_dialog, QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
QCheckBox *dont_show_again_checkbox_;
|
||||
|
||||
QCheckBox *dont_show_again_checkbox_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -24,98 +24,101 @@
|
||||
|
||||
#include "common/qtutils.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
const int ScrollingLabel::kMinLineHeight = 10;
|
||||
|
||||
ScrollingLabel::ScrollingLabel(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
animate_(0)
|
||||
ScrollingLabel::ScrollingLabel(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, animate_(0)
|
||||
{
|
||||
timer_.setInterval(50);
|
||||
connect(&timer_, &QTimer::timeout, this, &ScrollingLabel::AnimationUpdate);
|
||||
timer_.setInterval(50);
|
||||
connect(&timer_, &QTimer::timeout, this, &ScrollingLabel::AnimationUpdate);
|
||||
}
|
||||
|
||||
ScrollingLabel::ScrollingLabel(const QStringList &text, QWidget *parent) :
|
||||
ScrollingLabel(parent)
|
||||
ScrollingLabel::ScrollingLabel(const QStringList &text, QWidget *parent)
|
||||
: ScrollingLabel(parent)
|
||||
{
|
||||
SetText(text);
|
||||
SetText(text);
|
||||
}
|
||||
|
||||
void ScrollingLabel::SetText(const QStringList &text)
|
||||
{
|
||||
text_ = text;
|
||||
text_ = text;
|
||||
|
||||
QFontMetrics fm = fontMetrics();
|
||||
text_height_ = fm.height();
|
||||
QFontMetrics fm = fontMetrics();
|
||||
text_height_ = fm.height();
|
||||
|
||||
int width = 0;
|
||||
foreach (const QString& s, text_) {
|
||||
width = qMax(width, QtUtils::QFontMetricsWidth(fm, s));
|
||||
}
|
||||
int width = 0;
|
||||
foreach (const QString &s, text_) {
|
||||
width = qMax(width, QtUtils::QFontMetricsWidth(fm, s));
|
||||
}
|
||||
|
||||
setMinimumSize(width, text_height_ * kMinLineHeight);
|
||||
setMinimumSize(width, text_height_ * kMinLineHeight);
|
||||
}
|
||||
|
||||
void ScrollingLabel::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
QImage map(width(), height(), QImage::Format_RGBA8888_Premultiplied);
|
||||
map.fill(Qt::transparent);
|
||||
QImage map(width(), height(), QImage::Format_RGBA8888_Premultiplied);
|
||||
map.fill(Qt::transparent);
|
||||
|
||||
{
|
||||
QPainter p(&map);
|
||||
p.setPen(palette().text().color());
|
||||
{
|
||||
QPainter p(&map);
|
||||
p.setPen(palette().text().color());
|
||||
|
||||
QFontMetrics fm = p.fontMetrics();
|
||||
int half_width = width();
|
||||
QFontMetrics fm = p.fontMetrics();
|
||||
int half_width = width();
|
||||
|
||||
for (int i=0; i<text_.size(); i++) {
|
||||
int text_y = fm.ascent() + height() - animate_ + (fm.height()*i);
|
||||
int text_bottom = text_y + fm.descent();
|
||||
int text_top = text_y - fm.ascent();
|
||||
for (int i = 0; i < text_.size(); i++) {
|
||||
int text_y = fm.ascent() + height() - animate_ + (fm.height() * i);
|
||||
int text_bottom = text_y + fm.descent();
|
||||
int text_top = text_y - fm.ascent();
|
||||
|
||||
if (text_bottom < 0 || text_top >= height()) {
|
||||
continue;
|
||||
}
|
||||
if (text_bottom < 0 || text_top >= height()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const QString& s = text_.at(i);
|
||||
const QString &s = text_.at(i);
|
||||
|
||||
int width = QtUtils::QFontMetricsWidth(fm, s);
|
||||
p.drawText(half_width/2 - width/2, text_y, s);
|
||||
}
|
||||
int width = QtUtils::QFontMetricsWidth(fm, s);
|
||||
p.drawText(half_width / 2 - width / 2, text_y, s);
|
||||
}
|
||||
|
||||
for (int y=0; y<text_height_; y++) {
|
||||
double mul = double(y)/double(text_height_);
|
||||
for (int y = 0; y < text_height_; y++) {
|
||||
double mul = double(y) / double(text_height_);
|
||||
|
||||
SetOpacityOfScanLine(map.scanLine(y), map.width(), 4, mul);
|
||||
SetOpacityOfScanLine(map.scanLine(map.height()-1-y), map.width(), 4, mul);
|
||||
}
|
||||
}
|
||||
SetOpacityOfScanLine(map.scanLine(y), map.width(), 4, mul);
|
||||
SetOpacityOfScanLine(map.scanLine(map.height() - 1 - y),
|
||||
map.width(), 4, mul);
|
||||
}
|
||||
}
|
||||
|
||||
QPainter wp(this);
|
||||
wp.drawImage(0, 0, map);
|
||||
QPainter wp(this);
|
||||
wp.drawImage(0, 0, map);
|
||||
}
|
||||
|
||||
void ScrollingLabel::SetOpacityOfScanLine(uchar *scan_line, int width, int channels, double mul)
|
||||
void ScrollingLabel::SetOpacityOfScanLine(uchar *scan_line, int width,
|
||||
int channels, double mul)
|
||||
{
|
||||
for (int x=0; x<width; x++) {
|
||||
uchar* pixel = &scan_line[x*4];
|
||||
for (int x = 0; x < width; x++) {
|
||||
uchar *pixel = &scan_line[x * 4];
|
||||
|
||||
for (int c=0; c<channels; c++) {
|
||||
pixel[c] *= mul;
|
||||
}
|
||||
}
|
||||
for (int c = 0; c < channels; c++) {
|
||||
pixel[c] *= mul;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollingLabel::AnimationUpdate()
|
||||
{
|
||||
animate_++;
|
||||
animate_++;
|
||||
|
||||
if (animate_ >= height() + text_.size() * text_height_) {
|
||||
animate_ = 0;
|
||||
}
|
||||
if (animate_ >= height() + text_.size() * text_height_) {
|
||||
animate_ = 0;
|
||||
}
|
||||
|
||||
update();
|
||||
update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,46 +24,46 @@
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ScrollingLabel : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ScrollingLabel : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScrollingLabel(QWidget* parent = nullptr);
|
||||
ScrollingLabel(const QStringList& text, QWidget* parent = nullptr);
|
||||
ScrollingLabel(QWidget *parent = nullptr);
|
||||
ScrollingLabel(const QStringList &text, QWidget *parent = nullptr);
|
||||
|
||||
void SetText(const QStringList& text);
|
||||
void SetText(const QStringList &text);
|
||||
|
||||
void StartAnimating()
|
||||
{
|
||||
timer_.start();
|
||||
}
|
||||
void StartAnimating()
|
||||
{
|
||||
timer_.start();
|
||||
}
|
||||
|
||||
void StopAnimating()
|
||||
{
|
||||
timer_.stop();
|
||||
}
|
||||
void StopAnimating()
|
||||
{
|
||||
timer_.stop();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* e) override;
|
||||
virtual void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
static void SetOpacityOfScanLine(uchar* scan_line, int width, int channels, double mul);
|
||||
static void SetOpacityOfScanLine(uchar *scan_line, int width, int channels,
|
||||
double mul);
|
||||
|
||||
static const int kMinLineHeight;
|
||||
static const int kMinLineHeight;
|
||||
|
||||
QStringList text_;
|
||||
QStringList text_;
|
||||
|
||||
int text_height_;
|
||||
int text_height_;
|
||||
|
||||
QTimer timer_;
|
||||
QTimer timer_;
|
||||
|
||||
int animate_;
|
||||
int animate_;
|
||||
|
||||
private slots:
|
||||
void AnimationUpdate();
|
||||
|
||||
void AnimationUpdate();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,247 +25,251 @@
|
||||
#include <QMenuBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace olive {
|
||||
|
||||
ActionSearch::ActionSearch(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
menu_bar_(nullptr)
|
||||
namespace olive
|
||||
{
|
||||
// ActionSearch requires a parent widget
|
||||
Q_ASSERT(parent != nullptr);
|
||||
|
||||
// Set styling (object name is required for CSS specific to this object)
|
||||
setObjectName("ASDiag");
|
||||
setStyleSheet("#ASDiag{border: 2px solid #808080;}");
|
||||
ActionSearch::ActionSearch(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, menu_bar_(nullptr)
|
||||
{
|
||||
// ActionSearch requires a parent widget
|
||||
Q_ASSERT(parent != nullptr);
|
||||
|
||||
// Size proportionally to the parent (usually MainWindow).
|
||||
resize(parent->width()/3, parent->height()/3);
|
||||
// Set styling (object name is required for CSS specific to this object)
|
||||
setObjectName("ASDiag");
|
||||
setStyleSheet("#ASDiag{border: 2px solid #808080;}");
|
||||
|
||||
// Show dialog as a "popup", which will make the dialog close if the user clicks out of it.
|
||||
setWindowFlags(Qt::Popup);
|
||||
// Size proportionally to the parent (usually MainWindow).
|
||||
resize(parent->width() / 3, parent->height() / 3);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
// Show dialog as a "popup", which will make the dialog close if the user clicks out of it.
|
||||
setWindowFlags(Qt::Popup);
|
||||
|
||||
// Construct the main entry text field.
|
||||
ActionSearchEntry* entry_field = new ActionSearchEntry(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
// Set the main entry field font size to 1.2x its standard font size.
|
||||
QFont entry_field_font = entry_field->font();
|
||||
entry_field_font.setPointSize(qRound(entry_field_font.pointSize()*1.2));
|
||||
entry_field->setFont(entry_field_font);
|
||||
// Construct the main entry text field.
|
||||
ActionSearchEntry *entry_field = new ActionSearchEntry(this);
|
||||
|
||||
// Set placeholder text for the main entry field
|
||||
entry_field->setPlaceholderText(tr("Search for action..."));
|
||||
// Set the main entry field font size to 1.2x its standard font size.
|
||||
QFont entry_field_font = entry_field->font();
|
||||
entry_field_font.setPointSize(qRound(entry_field_font.pointSize() * 1.2));
|
||||
entry_field->setFont(entry_field_font);
|
||||
|
||||
// Connect signals/slots
|
||||
connect(entry_field, SIGNAL(textChanged(const QString&)), this, SLOT(search_update(const QString &)));
|
||||
connect(entry_field, SIGNAL(returnPressed()), this, SLOT(perform_action()));
|
||||
// Set placeholder text for the main entry field
|
||||
entry_field->setPlaceholderText(tr("Search for action..."));
|
||||
|
||||
// moveSelectionUp() and moveSelectionDown() are emitted when the user pressed up or down on the text field.
|
||||
// We override it here to select the upper or lower item in the list.
|
||||
connect(entry_field, SIGNAL(moveSelectionUp()), this, SLOT(move_selection_up()));
|
||||
connect(entry_field, SIGNAL(moveSelectionDown()), this, SLOT(move_selection_down()));
|
||||
layout->addWidget(entry_field);
|
||||
// Connect signals/slots
|
||||
connect(entry_field, SIGNAL(textChanged(const QString &)), this,
|
||||
SLOT(search_update(const QString &)));
|
||||
connect(entry_field, SIGNAL(returnPressed()), this, SLOT(perform_action()));
|
||||
|
||||
// Construct list of actions
|
||||
list_widget = new ActionSearchList(this);
|
||||
// moveSelectionUp() and moveSelectionDown() are emitted when the user pressed up or down on the text field.
|
||||
// We override it here to select the upper or lower item in the list.
|
||||
connect(entry_field, SIGNAL(moveSelectionUp()), this,
|
||||
SLOT(move_selection_up()));
|
||||
connect(entry_field, SIGNAL(moveSelectionDown()), this,
|
||||
SLOT(move_selection_down()));
|
||||
layout->addWidget(entry_field);
|
||||
|
||||
// Set list's font to 1.2x its standard font size
|
||||
QFont list_widget_font = list_widget->font();
|
||||
list_widget_font.setPointSize(qRound(list_widget_font.pointSize()*1.2));
|
||||
list_widget->setFont(list_widget_font);
|
||||
// Construct list of actions
|
||||
list_widget = new ActionSearchList(this);
|
||||
|
||||
layout->addWidget(list_widget);
|
||||
// Set list's font to 1.2x its standard font size
|
||||
QFont list_widget_font = list_widget->font();
|
||||
list_widget_font.setPointSize(qRound(list_widget_font.pointSize() * 1.2));
|
||||
list_widget->setFont(list_widget_font);
|
||||
|
||||
connect(list_widget, SIGNAL(dbl_click()), this, SLOT(perform_action()));
|
||||
layout->addWidget(list_widget);
|
||||
|
||||
// Instantly focus on the entry field to allow for fully keyboard operation (if this popup was initiated by keyboard
|
||||
// shortcut for example).
|
||||
entry_field->setFocus();
|
||||
connect(list_widget, SIGNAL(dbl_click()), this, SLOT(perform_action()));
|
||||
|
||||
// Instantly focus on the entry field to allow for fully keyboard operation (if this popup was initiated by keyboard
|
||||
// shortcut for example).
|
||||
entry_field->setFocus();
|
||||
}
|
||||
|
||||
void ActionSearch::SetMenuBar(QMenuBar *menu_bar)
|
||||
{
|
||||
menu_bar_ = menu_bar;
|
||||
menu_bar_ = menu_bar;
|
||||
}
|
||||
|
||||
void ActionSearch::search_update(const QString &s, const QString &p, QMenu *parent)
|
||||
void ActionSearch::search_update(const QString &s, const QString &p,
|
||||
QMenu *parent)
|
||||
{
|
||||
// Do nothing if there's no menu bar to work with
|
||||
if (menu_bar_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
// Do nothing if there's no menu bar to work with
|
||||
if (menu_bar_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This function is recursive, using the `parent` parameter to loop through a menu's items. It functions in two
|
||||
// modes - the parent being NULL, meaning it'll get MainWindow's menubar and loop over its menus, and the parent
|
||||
// referring to a menu at which point it'll loop over its actions (and call itself recursively if it finds any
|
||||
// submenus).
|
||||
// This function is recursive, using the `parent` parameter to loop through a menu's items. It functions in two
|
||||
// modes - the parent being NULL, meaning it'll get MainWindow's menubar and loop over its menus, and the parent
|
||||
// referring to a menu at which point it'll loop over its actions (and call itself recursively if it finds any
|
||||
// submenus).
|
||||
|
||||
if (parent == nullptr) {
|
||||
if (parent == nullptr) {
|
||||
// If parent is NULL, we'll pull from the MainWindow's menubar and call this recursively on all of its submenus
|
||||
// (and their submenus).
|
||||
|
||||
// If parent is NULL, we'll pull from the MainWindow's menubar and call this recursively on all of its submenus
|
||||
// (and their submenus).
|
||||
// We'll clear all the current items in the list since if we're here, we're just starting.
|
||||
list_widget->clear();
|
||||
|
||||
// We'll clear all the current items in the list since if we're here, we're just starting.
|
||||
list_widget->clear();
|
||||
QList<QAction *> menus = menu_bar_->actions();
|
||||
|
||||
QList<QAction*> menus = menu_bar_->actions();
|
||||
// Loop through all menus from the menubar and run this function on each one.
|
||||
for (int i = 0; i < menus.size(); i++) {
|
||||
QMenu *menu = menus.at(i)->menu();
|
||||
|
||||
// Loop through all menus from the menubar and run this function on each one.
|
||||
for (int i=0;i<menus.size();i++) {
|
||||
QMenu* menu = menus.at(i)->menu();
|
||||
search_update(s, p, menu);
|
||||
}
|
||||
|
||||
search_update(s, p, menu);
|
||||
}
|
||||
// Once we're here, all the recursion/item retrieval is complete. We auto-select the first item for better
|
||||
// keyboard-exclusive functionality.
|
||||
if (list_widget->count() > 0) {
|
||||
list_widget->item(0)->setSelected(true);
|
||||
}
|
||||
|
||||
// Once we're here, all the recursion/item retrieval is complete. We auto-select the first item for better
|
||||
// keyboard-exclusive functionality.
|
||||
if (list_widget->count() > 0) {
|
||||
list_widget->item(0)->setSelected(true);
|
||||
}
|
||||
} else {
|
||||
// Parent was not NULL, so we loop over the actions in the menu we were given in `parent`.
|
||||
|
||||
} else {
|
||||
// The list shows a '>' delimited hierarchy of the menus in which this action came from. We construct it here by
|
||||
// adding the current menu's text to the existing hierarchy (passed in `p`).
|
||||
QString menu_text;
|
||||
if (!p.isEmpty())
|
||||
menu_text += p + " > ";
|
||||
menu_text += parent->title().replace(
|
||||
"&", ""); // Strip out any &s used in menu action names
|
||||
|
||||
// Parent was not NULL, so we loop over the actions in the menu we were given in `parent`.
|
||||
// Loop over the menu's actions
|
||||
QList<QAction *> actions = parent->actions();
|
||||
for (int i = 0; i < actions.size(); i++) {
|
||||
QAction *a = actions.at(i);
|
||||
|
||||
// The list shows a '>' delimited hierarchy of the menus in which this action came from. We construct it here by
|
||||
// adding the current menu's text to the existing hierarchy (passed in `p`).
|
||||
QString menu_text;
|
||||
if (!p.isEmpty()) menu_text += p + " > ";
|
||||
menu_text += parent->title().replace("&", ""); // Strip out any &s used in menu action names
|
||||
// Ignore separator actions
|
||||
if (!a->isSeparator()) {
|
||||
if (a->menu() != nullptr) {
|
||||
// If the action is a menu, run this function recursively on it
|
||||
search_update(s, menu_text, a->menu());
|
||||
|
||||
// Loop over the menu's actions
|
||||
QList<QAction*> actions = parent->actions();
|
||||
for (int i=0;i<actions.size();i++) {
|
||||
} else {
|
||||
// This is a valid non-separator non-menu action, so check it against the currently entered string.
|
||||
|
||||
QAction* a = actions.at(i);
|
||||
// Strip out all &s from the action's name
|
||||
QString comp = a->text().replace("&", "");
|
||||
|
||||
// Ignore separator actions
|
||||
if (!a->isSeparator()) {
|
||||
// See if the action's name contains any of the currently entered string
|
||||
if (comp.contains(s, Qt::CaseInsensitive)) {
|
||||
// If so, we add it to the list widget.
|
||||
QListWidgetItem *item = new QListWidgetItem(
|
||||
QStringLiteral("%1\n(%2)").arg(comp, menu_text),
|
||||
list_widget);
|
||||
|
||||
if (a->menu() != nullptr) {
|
||||
// Add a pointer to the original QAction in the item's data
|
||||
item->setData(Qt::UserRole + 1,
|
||||
reinterpret_cast<quintptr>(a));
|
||||
|
||||
// If the action is a menu, run this function recursively on it
|
||||
search_update(s, menu_text, a->menu());
|
||||
|
||||
} else {
|
||||
|
||||
// This is a valid non-separator non-menu action, so check it against the currently entered string.
|
||||
|
||||
// Strip out all &s from the action's name
|
||||
QString comp = a->text().replace("&", "");
|
||||
|
||||
// See if the action's name contains any of the currently entered string
|
||||
if (comp.contains(s, Qt::CaseInsensitive)) {
|
||||
|
||||
// If so, we add it to the list widget.
|
||||
QListWidgetItem* item = new QListWidgetItem(QStringLiteral("%1\n(%2)").arg(comp, menu_text), list_widget);
|
||||
|
||||
// Add a pointer to the original QAction in the item's data
|
||||
item->setData(Qt::UserRole+1, reinterpret_cast<quintptr>(a));
|
||||
|
||||
list_widget->addItem(item);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
list_widget->addItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionSearch::perform_action() {
|
||||
void ActionSearch::perform_action()
|
||||
{
|
||||
// Loop over all the items in the list and if we find one that's selected, we trigger it.
|
||||
QList<QListWidgetItem *> selected_items = list_widget->selectedItems();
|
||||
if (list_widget->count() > 0 && selected_items.size() > 0) {
|
||||
QListWidgetItem *item = selected_items.at(0);
|
||||
|
||||
// Loop over all the items in the list and if we find one that's selected, we trigger it.
|
||||
QList<QListWidgetItem*> selected_items = list_widget->selectedItems();
|
||||
if (list_widget->count() > 0 && selected_items.size() > 0) {
|
||||
// Get QAction pointer from item's data
|
||||
QAction *a = reinterpret_cast<QAction *>(
|
||||
item->data(Qt::UserRole + 1).value<quintptr>());
|
||||
|
||||
QListWidgetItem* item = selected_items.at(0);
|
||||
|
||||
// Get QAction pointer from item's data
|
||||
QAction* a = reinterpret_cast<QAction*>(item->data(Qt::UserRole+1).value<quintptr>());
|
||||
|
||||
a->trigger();
|
||||
|
||||
}
|
||||
|
||||
// Close this popup
|
||||
accept();
|
||||
a->trigger();
|
||||
}
|
||||
|
||||
// Close this popup
|
||||
accept();
|
||||
}
|
||||
|
||||
void ActionSearch::move_selection_up() {
|
||||
void ActionSearch::move_selection_up()
|
||||
{
|
||||
// Here we loop over all the items to find the currently selected one, and then select the one above it. We start
|
||||
// iterating at 1 (instead of 0) to efficiently ignore the first item (since the selection can't go below the very
|
||||
// bottom item).
|
||||
|
||||
// Here we loop over all the items to find the currently selected one, and then select the one above it. We start
|
||||
// iterating at 1 (instead of 0) to efficiently ignore the first item (since the selection can't go below the very
|
||||
// bottom item).
|
||||
|
||||
int lim = list_widget->count();
|
||||
for (int i=1;i<lim;i++) {
|
||||
if (list_widget->item(i)->isSelected()) {
|
||||
list_widget->item(i-1)->setSelected(true);
|
||||
list_widget->scrollToItem(list_widget->item(i-1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
int lim = list_widget->count();
|
||||
for (int i = 1; i < lim; i++) {
|
||||
if (list_widget->item(i)->isSelected()) {
|
||||
list_widget->item(i - 1)->setSelected(true);
|
||||
list_widget->scrollToItem(list_widget->item(i - 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionSearch::move_selection_down() {
|
||||
void ActionSearch::move_selection_down()
|
||||
{
|
||||
// Here we loop over all the items to find the currently selected one, and then select the one below it. We limit it
|
||||
// one entry before count() to efficiently ignore the item at the end (since the selection can't go below the very
|
||||
// bottom item).
|
||||
|
||||
// Here we loop over all the items to find the currently selected one, and then select the one below it. We limit it
|
||||
// one entry before count() to efficiently ignore the item at the end (since the selection can't go below the very
|
||||
// bottom item).
|
||||
|
||||
int lim = list_widget->count()-1;
|
||||
for (int i=0;i<lim;i++) {
|
||||
if (list_widget->item(i)->isSelected()) {
|
||||
list_widget->item(i+1)->setSelected(true);
|
||||
list_widget->scrollToItem(list_widget->item(i+1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
int lim = list_widget->count() - 1;
|
||||
for (int i = 0; i < lim; i++) {
|
||||
if (list_widget->item(i)->isSelected()) {
|
||||
list_widget->item(i + 1)->setSelected(true);
|
||||
list_widget->scrollToItem(list_widget->item(i + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActionSearchEntry::ActionSearchEntry(QWidget *parent) : QLineEdit(parent) {}
|
||||
ActionSearchEntry::ActionSearchEntry(QWidget *parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool ActionSearchEntry::event(QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::ShortcutOverride:
|
||||
switch (static_cast<QKeyEvent*>(e)->key()) {
|
||||
case Qt::Key_Up:
|
||||
case Qt::Key_Down:
|
||||
e->accept();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QEvent::KeyPress:
|
||||
// Listen for up/down, otherwise pass the key event to the base class.
|
||||
switch (static_cast<QKeyEvent*>(e)->key()) {
|
||||
case Qt::Key_Up:
|
||||
e->accept();
|
||||
emit moveSelectionUp();
|
||||
return true;
|
||||
case Qt::Key_Down:
|
||||
e->accept();
|
||||
emit moveSelectionDown();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (e->type()) {
|
||||
case QEvent::ShortcutOverride:
|
||||
switch (static_cast<QKeyEvent *>(e)->key()) {
|
||||
case Qt::Key_Up:
|
||||
case Qt::Key_Down:
|
||||
e->accept();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QEvent::KeyPress:
|
||||
// Listen for up/down, otherwise pass the key event to the base class.
|
||||
switch (static_cast<QKeyEvent *>(e)->key()) {
|
||||
case Qt::Key_Up:
|
||||
e->accept();
|
||||
emit moveSelectionUp();
|
||||
return true;
|
||||
case Qt::Key_Down:
|
||||
e->accept();
|
||||
emit moveSelectionDown();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QLineEdit::event(e);
|
||||
return QLineEdit::event(e);
|
||||
}
|
||||
|
||||
ActionSearchList::ActionSearchList(QWidget *parent) : QListWidget(parent) {}
|
||||
|
||||
void ActionSearchList::mouseDoubleClickEvent(QMouseEvent *) {
|
||||
|
||||
// Indiscriminately emit a signal on any double click
|
||||
emit dbl_click();
|
||||
ActionSearchList::ActionSearchList(QWidget *parent)
|
||||
: QListWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void ActionSearchList::mouseDoubleClickEvent(QMouseEvent *)
|
||||
{
|
||||
// Indiscriminately emit a signal on any double click
|
||||
emit dbl_click();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ActionSearchList;
|
||||
|
||||
@@ -39,11 +40,10 @@ class ActionSearchList;
|
||||
* A popup window (accessible through Help > Action Search) that allows users to search for a menu command by typing
|
||||
* rather than browsing through the menu bar. This can be created from anywhere provided olive::MainWindow is valid.
|
||||
*/
|
||||
class ActionSearch : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
class ActionSearch : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief ActionSearch Constructor
|
||||
*
|
||||
* Create ActionSearch popup.
|
||||
@@ -52,14 +52,14 @@ public:
|
||||
*
|
||||
* QWidget parent. Usually MainWindow.
|
||||
*/
|
||||
ActionSearch(QWidget* parent);
|
||||
ActionSearch(QWidget *parent);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Set the menu bar to use in this action search
|
||||
*/
|
||||
void SetMenuBar(QMenuBar* menu_bar);
|
||||
void SetMenuBar(QMenuBar *menu_bar);
|
||||
private slots:
|
||||
/**
|
||||
/**
|
||||
* @brief Update the list of actions according to a search query
|
||||
*
|
||||
* This function adds/removes actions in the action list according to a given search query entered by the user.
|
||||
@@ -82,42 +82,44 @@ private slots:
|
||||
* The current menu to loop over. In most cases, this should be left as nullptr when called externally.
|
||||
* search_update() will fill this automatically as it needs while calling itself recursively.
|
||||
*/
|
||||
void search_update(const QString& s, const QString &p = nullptr, QMenu *parent = nullptr);
|
||||
void search_update(const QString &s, const QString &p = nullptr,
|
||||
QMenu *parent = nullptr);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Perform the currently selected action
|
||||
*
|
||||
* Usually triggered by pressing Enter on the ActionSearchEntry field, this will trigger whatever action is currently
|
||||
* highlighted and then close this popup. If no entries are highlighted (i.e. the list is empty), no action is
|
||||
* triggered and the popup closes anyway.
|
||||
*/
|
||||
void perform_action();
|
||||
void perform_action();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Move selection up
|
||||
*
|
||||
* A slot for pressing up on the ActionSearchEntry field. Moves the selection in the list up once. If the
|
||||
* selection is already at the top of the list, this is a no-op.
|
||||
*/
|
||||
void move_selection_up();
|
||||
void move_selection_up();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Move selection down
|
||||
*
|
||||
* A slot for pressing down on the ActionSearchEntry field. Moves the selection in the list down once. If the
|
||||
* selection is already at the bottom of the list, this is a no-op.
|
||||
*/
|
||||
void move_selection_down();
|
||||
void move_selection_down();
|
||||
|
||||
private:
|
||||
/**
|
||||
/**
|
||||
* @brief Main widget that shows the list of commands
|
||||
*/
|
||||
ActionSearchList* list_widget;
|
||||
ActionSearchList *list_widget;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Attached menu bar object
|
||||
*/
|
||||
QMenuBar* menu_bar_;
|
||||
QMenuBar *menu_bar_;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -127,25 +129,26 @@ private:
|
||||
* to a slot that triggers the currently selected action.
|
||||
*/
|
||||
class ActionSearchList : public QListWidget {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief ActionSearchList Constructor
|
||||
* @param parent
|
||||
*
|
||||
* Usually ActionSearch.
|
||||
*/
|
||||
ActionSearchList(QWidget* parent);
|
||||
ActionSearchList(QWidget *parent);
|
||||
|
||||
protected:
|
||||
/**
|
||||
/**
|
||||
* @brief Override of QListWidget's double click event that emits a signal.
|
||||
*/
|
||||
void mouseDoubleClickEvent(QMouseEvent *);
|
||||
void mouseDoubleClickEvent(QMouseEvent *);
|
||||
signals:
|
||||
/**
|
||||
/**
|
||||
* @brief Signal emitted when a QListWidget item is double clicked.
|
||||
*/
|
||||
void dbl_click();
|
||||
void dbl_click();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -155,32 +158,33 @@ signals:
|
||||
* can connect them to moving the current selection up or down.
|
||||
*/
|
||||
class ActionSearchEntry : public QLineEdit {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief ActionSearchEntry
|
||||
* @param parent
|
||||
*
|
||||
* Usually ActionSearch.
|
||||
*/
|
||||
ActionSearchEntry(QWidget* parent);
|
||||
ActionSearchEntry(QWidget *parent);
|
||||
|
||||
protected:
|
||||
/**
|
||||
/**
|
||||
* @brief Override of QLineEdit's key press event that listens for up/down key presses.
|
||||
* @param event
|
||||
*/
|
||||
virtual bool event(QEvent *e) override;
|
||||
virtual bool event(QEvent *e) override;
|
||||
|
||||
signals:
|
||||
/**
|
||||
/**
|
||||
* @brief Emitted when the user presses the up arrow key.
|
||||
*/
|
||||
void moveSelectionUp();
|
||||
void moveSelectionUp();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Emitted when the user presses the down arrow key.
|
||||
*/
|
||||
void moveSelectionDown();
|
||||
void moveSelectionDown();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,108 +29,127 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super QDialog
|
||||
|
||||
AutoRecoveryDialog::AutoRecoveryDialog(const QString &message, const QStringList &recoveries, bool autocheck_latest, QWidget* parent) :
|
||||
QDialog(parent)
|
||||
AutoRecoveryDialog::AutoRecoveryDialog(const QString &message,
|
||||
const QStringList &recoveries,
|
||||
bool autocheck_latest, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
Init(message);
|
||||
Init(message);
|
||||
|
||||
PopulateTree(recoveries, autocheck_latest);
|
||||
PopulateTree(recoveries, autocheck_latest);
|
||||
}
|
||||
|
||||
void AutoRecoveryDialog::accept()
|
||||
{
|
||||
foreach (QTreeWidgetItem* checkable, checkable_items_) {
|
||||
if (checkable->checkState(0) == Qt::Checked) {
|
||||
QString filename = checkable->data(0, kFilenameRole).toString();
|
||||
Core::instance()->OpenRecoveryProject(filename);
|
||||
}
|
||||
}
|
||||
foreach (QTreeWidgetItem *checkable, checkable_items_) {
|
||||
if (checkable->checkState(0) == Qt::Checked) {
|
||||
QString filename = checkable->data(0, kFilenameRole).toString();
|
||||
Core::instance()->OpenRecoveryProject(filename);
|
||||
}
|
||||
}
|
||||
|
||||
super::accept();
|
||||
super::accept();
|
||||
}
|
||||
|
||||
void AutoRecoveryDialog::Init(const QString& header_text)
|
||||
void AutoRecoveryDialog::Init(const QString &header_text)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
setWindowTitle(tr("Auto-Recovery"));
|
||||
setWindowTitle(tr("Auto-Recovery"));
|
||||
|
||||
layout->addWidget(new QLabel(header_text));
|
||||
layout->addWidget(new QLabel(header_text));
|
||||
|
||||
tree_widget_ = new QTreeWidget();
|
||||
tree_widget_->setHeaderHidden(true);
|
||||
layout->addWidget(tree_widget_);
|
||||
tree_widget_ = new QTreeWidget();
|
||||
tree_widget_->setHeaderHidden(true);
|
||||
layout->addWidget(tree_widget_);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttons->button(QDialogButtonBox::Ok)->setText(tr("Load"));
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &AutoRecoveryDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &AutoRecoveryDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttons->button(QDialogButtonBox::Ok)->setText(tr("Load"));
|
||||
connect(buttons, &QDialogButtonBox::accepted, this,
|
||||
&AutoRecoveryDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this,
|
||||
&AutoRecoveryDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
}
|
||||
|
||||
void AutoRecoveryDialog::PopulateTree(const QStringList& recoveries, bool autocheck_latest)
|
||||
void AutoRecoveryDialog::PopulateTree(const QStringList &recoveries,
|
||||
bool autocheck_latest)
|
||||
{
|
||||
// Each entry in `recoveries` is a directory with 1+ recovery projects in it
|
||||
QDir autorecovery_root(FileFunctions::GetAutoRecoveryRoot());
|
||||
// Each entry in `recoveries` is a directory with 1+ recovery projects in it
|
||||
QDir autorecovery_root(FileFunctions::GetAutoRecoveryRoot());
|
||||
|
||||
foreach (const QString& recovery_folder, recoveries) {
|
||||
QDir recovery_dir(autorecovery_root.filePath(recovery_folder));
|
||||
foreach (const QString &recovery_folder, recoveries) {
|
||||
QDir recovery_dir(autorecovery_root.filePath(recovery_folder));
|
||||
|
||||
QString pretty_name;
|
||||
{
|
||||
// Retrieve pretty name
|
||||
QFile pretty_name_file(recovery_dir.filePath(QStringLiteral("realname.txt")));
|
||||
if (pretty_name_file.open(QFile::ReadOnly)) {
|
||||
// Read pretty name that we should have written in the autorecovery process
|
||||
pretty_name = QString::fromUtf8(pretty_name_file.readAll());
|
||||
pretty_name_file.close();
|
||||
}
|
||||
QString pretty_name;
|
||||
{
|
||||
// Retrieve pretty name
|
||||
QFile pretty_name_file(
|
||||
recovery_dir.filePath(QStringLiteral("realname.txt")));
|
||||
if (pretty_name_file.open(QFile::ReadOnly)) {
|
||||
// Read pretty name that we should have written in the autorecovery process
|
||||
pretty_name = QString::fromUtf8(pretty_name_file.readAll());
|
||||
pretty_name_file.close();
|
||||
}
|
||||
|
||||
if (pretty_name.isEmpty()) {
|
||||
// Fallback to just the UUID. While it won't mean much to the user, it's better than nothing.
|
||||
pretty_name = recovery_dir.dirName();
|
||||
}
|
||||
}
|
||||
if (pretty_name.isEmpty()) {
|
||||
// Fallback to just the UUID. While it won't mean much to the user, it's better than nothing.
|
||||
pretty_name = recovery_dir.dirName();
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem* top_level = new QTreeWidgetItem(tree_widget_);
|
||||
top_level->setText(0, pretty_name);
|
||||
QTreeWidgetItem *top_level = new QTreeWidgetItem(tree_widget_);
|
||||
top_level->setText(0, pretty_name);
|
||||
|
||||
{
|
||||
// Populate with recoveries
|
||||
QStringList entries = recovery_dir.entryList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
|
||||
for (int i=0; i<entries.size(); i++) {
|
||||
const QString& entry = entries.at(i);
|
||||
{
|
||||
// Populate with recoveries
|
||||
QStringList entries =
|
||||
recovery_dir.entryList(QDir::Files | QDir::NoDotAndDotDot,
|
||||
QDir::Name | QDir::Reversed);
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
const QString &entry = entries.at(i);
|
||||
|
||||
if (entry.endsWith(QStringLiteral(".ove"), Qt::CaseInsensitive)) {
|
||||
QTreeWidgetItem* entry_item = new QTreeWidgetItem(top_level);
|
||||
if (entry.endsWith(QStringLiteral(".ove"),
|
||||
Qt::CaseInsensitive)) {
|
||||
QTreeWidgetItem *entry_item =
|
||||
new QTreeWidgetItem(top_level);
|
||||
|
||||
bool ok;
|
||||
qint64 recovery_time = entry.left(entry.indexOf('.')).toLongLong(&ok);
|
||||
QString entry_name;
|
||||
bool ok;
|
||||
qint64 recovery_time =
|
||||
entry.left(entry.indexOf('.')).toLongLong(&ok);
|
||||
QString entry_name;
|
||||
|
||||
if (ok) {
|
||||
// Set as time/date of recovery
|
||||
entry_name = QDateTime::fromSecsSinceEpoch(recovery_time).toString();
|
||||
} else {
|
||||
// Fallback if we couldn't discern a date from this
|
||||
entry_name = entry;
|
||||
}
|
||||
if (ok) {
|
||||
// Set as time/date of recovery
|
||||
entry_name =
|
||||
QDateTime::fromSecsSinceEpoch(recovery_time)
|
||||
.toString();
|
||||
} else {
|
||||
// Fallback if we couldn't discern a date from this
|
||||
entry_name = entry;
|
||||
}
|
||||
|
||||
entry_item->setText(0, entry_name);
|
||||
entry_item->setData(0, kFilenameRole, recovery_dir.filePath(entry));
|
||||
entry_item->setText(0, entry_name);
|
||||
entry_item->setData(0, kFilenameRole,
|
||||
recovery_dir.filePath(entry));
|
||||
|
||||
// Allow to be checked, auto-checking the first entry
|
||||
entry_item->setCheckState(0, (autocheck_latest && top_level->childCount() == 1) ? Qt::Checked : Qt::Unchecked);
|
||||
// Allow to be checked, auto-checking the first entry
|
||||
entry_item->setCheckState(
|
||||
0, (autocheck_latest && top_level->childCount() == 1) ?
|
||||
Qt::Checked :
|
||||
Qt::Unchecked);
|
||||
|
||||
checkable_items_.append(entry_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checkable_items_.append(entry_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,30 +26,28 @@
|
||||
|
||||
#include "common/define.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class AutoRecoveryDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class AutoRecoveryDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AutoRecoveryDialog(const QString& message, const QStringList& recoveries, bool autocheck_latest, QWidget* parent);
|
||||
AutoRecoveryDialog(const QString &message, const QStringList &recoveries,
|
||||
bool autocheck_latest, QWidget *parent);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
void Init(const QString &header_text);
|
||||
void Init(const QString &header_text);
|
||||
|
||||
void PopulateTree(const QStringList &recoveries, bool autocheck);
|
||||
void PopulateTree(const QStringList &recoveries, bool autocheck);
|
||||
|
||||
QTreeWidget* tree_widget_;
|
||||
QTreeWidget *tree_widget_;
|
||||
|
||||
QVector<QTreeWidgetItem*> checkable_items_;
|
||||
|
||||
enum DataRole {
|
||||
kFilenameRole = Qt::UserRole
|
||||
};
|
||||
QVector<QTreeWidgetItem *> checkable_items_;
|
||||
|
||||
enum DataRole { kFilenameRole = Qt::UserRole };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+120
-101
@@ -26,167 +26,186 @@
|
||||
|
||||
#include "common/qtutils.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
ColorDialog::ColorDialog(ColorManager* color_manager, const ManagedColor& start, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
color_manager_(color_manager)
|
||||
namespace olive
|
||||
{
|
||||
setWindowTitle(tr("Select Color"));
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
ColorDialog::ColorDialog(ColorManager *color_manager, const ManagedColor &start,
|
||||
QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, color_manager_(color_manager)
|
||||
{
|
||||
setWindowTitle(tr("Select Color"));
|
||||
|
||||
QSplitter* splitter = new QSplitter(Qt::Horizontal);
|
||||
splitter->setChildrenCollapsible(false);
|
||||
layout->addWidget(splitter);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
QWidget* graphics_area = new QWidget();
|
||||
splitter->addWidget(graphics_area);
|
||||
QSplitter *splitter = new QSplitter(Qt::Horizontal);
|
||||
splitter->setChildrenCollapsible(false);
|
||||
layout->addWidget(splitter);
|
||||
|
||||
QVBoxLayout *graphics_layout = new QVBoxLayout(graphics_area);
|
||||
QWidget *graphics_area = new QWidget();
|
||||
splitter->addWidget(graphics_area);
|
||||
|
||||
QHBoxLayout* wheel_layout = new QHBoxLayout();
|
||||
graphics_layout->addLayout(wheel_layout);
|
||||
QVBoxLayout *graphics_layout = new QVBoxLayout(graphics_area);
|
||||
|
||||
color_wheel_ = new ColorWheelWidget();
|
||||
wheel_layout->addWidget(color_wheel_);
|
||||
QHBoxLayout *wheel_layout = new QHBoxLayout();
|
||||
graphics_layout->addLayout(wheel_layout);
|
||||
|
||||
hsv_value_gradient_ = new ColorGradientWidget(Qt::Vertical);
|
||||
hsv_value_gradient_->setFixedWidth(QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral("HHH")));
|
||||
wheel_layout->addWidget(hsv_value_gradient_);
|
||||
color_wheel_ = new ColorWheelWidget();
|
||||
wheel_layout->addWidget(color_wheel_);
|
||||
|
||||
QHBoxLayout *swatch_layout = new QHBoxLayout();
|
||||
graphics_layout->addLayout(swatch_layout);
|
||||
hsv_value_gradient_ = new ColorGradientWidget(Qt::Vertical);
|
||||
hsv_value_gradient_->setFixedWidth(
|
||||
QtUtils::QFontMetricsWidth(fontMetrics(), QStringLiteral("HHH")));
|
||||
wheel_layout->addWidget(hsv_value_gradient_);
|
||||
|
||||
swatch_layout->addStretch();
|
||||
QHBoxLayout *swatch_layout = new QHBoxLayout();
|
||||
graphics_layout->addLayout(swatch_layout);
|
||||
|
||||
swatch_ = new ColorSwatchChooser(color_manager_);
|
||||
swatch_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
swatch_layout->addWidget(swatch_);
|
||||
swatch_layout->addStretch();
|
||||
|
||||
swatch_layout->addStretch();
|
||||
swatch_ = new ColorSwatchChooser(color_manager_);
|
||||
swatch_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
|
||||
swatch_layout->addWidget(swatch_);
|
||||
|
||||
QWidget* value_area = new QWidget();
|
||||
QVBoxLayout* value_layout = new QVBoxLayout(value_area);
|
||||
value_layout->setSpacing(0);
|
||||
splitter->addWidget(value_area);
|
||||
swatch_layout->addStretch();
|
||||
|
||||
color_values_widget_ = new ColorValuesWidget(color_manager_);
|
||||
color_values_widget_->IgnorePickFrom(this);
|
||||
value_layout->addWidget(color_values_widget_);
|
||||
QWidget *value_area = new QWidget();
|
||||
QVBoxLayout *value_layout = new QVBoxLayout(value_area);
|
||||
value_layout->setSpacing(0);
|
||||
splitter->addWidget(value_area);
|
||||
|
||||
chooser_ = new ColorSpaceChooser(color_manager_);
|
||||
color_values_widget_ = new ColorValuesWidget(color_manager_);
|
||||
color_values_widget_->IgnorePickFrom(this);
|
||||
value_layout->addWidget(color_values_widget_);
|
||||
|
||||
value_layout->addWidget(chooser_);
|
||||
chooser_ = new ColorSpaceChooser(color_manager_);
|
||||
|
||||
// Split window 50/50
|
||||
splitter->setSizes({INT_MAX, INT_MAX});
|
||||
value_layout->addWidget(chooser_);
|
||||
|
||||
connect(color_wheel_, &ColorWheelWidget::SelectedColorChanged, color_values_widget_, &ColorValuesWidget::SetColor);
|
||||
connect(color_wheel_, &ColorWheelWidget::SelectedColorChanged, hsv_value_gradient_, &ColorGradientWidget::SetSelectedColor);
|
||||
connect(color_wheel_, &ColorWheelWidget::SelectedColorChanged, swatch_, &ColorSwatchChooser::SetCurrentColor);
|
||||
connect(hsv_value_gradient_, &ColorGradientWidget::SelectedColorChanged, color_values_widget_, &ColorValuesWidget::SetColor);
|
||||
connect(hsv_value_gradient_, &ColorGradientWidget::SelectedColorChanged, color_wheel_, &ColorWheelWidget::SetSelectedColor);
|
||||
connect(hsv_value_gradient_, &ColorGradientWidget::SelectedColorChanged, swatch_, &ColorSwatchChooser::SetCurrentColor);
|
||||
connect(color_values_widget_, &ColorValuesWidget::ColorChanged, hsv_value_gradient_, &ColorGradientWidget::SetSelectedColor);
|
||||
connect(color_values_widget_, &ColorValuesWidget::ColorChanged, color_wheel_, &ColorWheelWidget::SetSelectedColor);
|
||||
connect(color_values_widget_, &ColorValuesWidget::ColorChanged, swatch_, &ColorSwatchChooser::SetCurrentColor);
|
||||
connect(swatch_, &ColorSwatchChooser::ColorClicked, hsv_value_gradient_, &ColorGradientWidget::SetSelectedColor);
|
||||
connect(swatch_, &ColorSwatchChooser::ColorClicked, color_wheel_, &ColorWheelWidget::SetSelectedColor);
|
||||
connect(swatch_, &ColorSwatchChooser::ColorClicked, color_values_widget_, &ColorValuesWidget::SetColor);
|
||||
// Split window 50/50
|
||||
splitter->setSizes({ INT_MAX, INT_MAX });
|
||||
|
||||
connect(color_wheel_, &ColorWheelWidget::DiameterChanged, hsv_value_gradient_, &ColorGradientWidget::setFixedHeight);
|
||||
connect(color_wheel_, &ColorWheelWidget::SelectedColorChanged,
|
||||
color_values_widget_, &ColorValuesWidget::SetColor);
|
||||
connect(color_wheel_, &ColorWheelWidget::SelectedColorChanged,
|
||||
hsv_value_gradient_, &ColorGradientWidget::SetSelectedColor);
|
||||
connect(color_wheel_, &ColorWheelWidget::SelectedColorChanged, swatch_,
|
||||
&ColorSwatchChooser::SetCurrentColor);
|
||||
connect(hsv_value_gradient_, &ColorGradientWidget::SelectedColorChanged,
|
||||
color_values_widget_, &ColorValuesWidget::SetColor);
|
||||
connect(hsv_value_gradient_, &ColorGradientWidget::SelectedColorChanged,
|
||||
color_wheel_, &ColorWheelWidget::SetSelectedColor);
|
||||
connect(hsv_value_gradient_, &ColorGradientWidget::SelectedColorChanged,
|
||||
swatch_, &ColorSwatchChooser::SetCurrentColor);
|
||||
connect(color_values_widget_, &ColorValuesWidget::ColorChanged,
|
||||
hsv_value_gradient_, &ColorGradientWidget::SetSelectedColor);
|
||||
connect(color_values_widget_, &ColorValuesWidget::ColorChanged,
|
||||
color_wheel_, &ColorWheelWidget::SetSelectedColor);
|
||||
connect(color_values_widget_, &ColorValuesWidget::ColorChanged, swatch_,
|
||||
&ColorSwatchChooser::SetCurrentColor);
|
||||
connect(swatch_, &ColorSwatchChooser::ColorClicked, hsv_value_gradient_,
|
||||
&ColorGradientWidget::SetSelectedColor);
|
||||
connect(swatch_, &ColorSwatchChooser::ColorClicked, color_wheel_,
|
||||
&ColorWheelWidget::SetSelectedColor);
|
||||
connect(swatch_, &ColorSwatchChooser::ColorClicked, color_values_widget_,
|
||||
&ColorValuesWidget::SetColor);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
connect(color_wheel_, &ColorWheelWidget::DiameterChanged,
|
||||
hsv_value_gradient_, &ColorGradientWidget::setFixedHeight);
|
||||
|
||||
SetColor(start);
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
connect(chooser_, &ColorSpaceChooser::ColorSpaceChanged, this, &ColorDialog::ColorSpaceChanged);
|
||||
ColorSpaceChanged(chooser_->input(), chooser_->output());
|
||||
SetColor(start);
|
||||
|
||||
// Set default size ratio to 2:1
|
||||
resize(sizeHint().height() * 2, sizeHint().height());
|
||||
connect(chooser_, &ColorSpaceChooser::ColorSpaceChanged, this,
|
||||
&ColorDialog::ColorSpaceChanged);
|
||||
ColorSpaceChanged(chooser_->input(), chooser_->output());
|
||||
|
||||
// Set default size ratio to 2:1
|
||||
resize(sizeHint().height() * 2, sizeHint().height());
|
||||
}
|
||||
|
||||
void ColorDialog::SetColor(const ManagedColor &start)
|
||||
{
|
||||
chooser_->set_input(start.color_input());
|
||||
chooser_->set_output(start.color_output());
|
||||
chooser_->set_input(start.color_input());
|
||||
chooser_->set_output(start.color_output());
|
||||
|
||||
Color managed_start;
|
||||
Color managed_start;
|
||||
|
||||
if (start.color_input().isEmpty()) {
|
||||
if (start.color_input().isEmpty()) {
|
||||
managed_start = start;
|
||||
|
||||
managed_start = start;
|
||||
} else {
|
||||
// Convert reference color to the input space
|
||||
ColorProcessorPtr linear_to_input = ColorProcessor::Create(
|
||||
color_manager_, color_manager_->GetReferenceColorSpace(),
|
||||
start.color_input());
|
||||
|
||||
} else {
|
||||
managed_start = linear_to_input->ConvertColor(start);
|
||||
}
|
||||
|
||||
// Convert reference color to the input space
|
||||
ColorProcessorPtr linear_to_input = ColorProcessor::Create(color_manager_,
|
||||
color_manager_->GetReferenceColorSpace(),
|
||||
start.color_input());
|
||||
|
||||
managed_start = linear_to_input->ConvertColor(start);
|
||||
|
||||
}
|
||||
|
||||
color_wheel_->SetSelectedColor(managed_start);
|
||||
hsv_value_gradient_->SetSelectedColor(managed_start);
|
||||
color_values_widget_->SetColor(managed_start);
|
||||
swatch_->SetCurrentColor(managed_start);
|
||||
color_wheel_->SetSelectedColor(managed_start);
|
||||
hsv_value_gradient_->SetSelectedColor(managed_start);
|
||||
color_values_widget_->SetColor(managed_start);
|
||||
swatch_->SetCurrentColor(managed_start);
|
||||
}
|
||||
|
||||
ManagedColor ColorDialog::GetSelectedColor() const
|
||||
{
|
||||
ManagedColor selected = color_wheel_->GetSelectedColor();
|
||||
ManagedColor selected = color_wheel_->GetSelectedColor();
|
||||
|
||||
// Convert to linear and return a linear color
|
||||
if (input_to_ref_processor_) {
|
||||
selected = input_to_ref_processor_->ConvertColor(selected);
|
||||
}
|
||||
// Convert to linear and return a linear color
|
||||
if (input_to_ref_processor_) {
|
||||
selected = input_to_ref_processor_->ConvertColor(selected);
|
||||
}
|
||||
|
||||
selected.set_color_input(GetColorSpaceInput());
|
||||
selected.set_color_output(GetColorSpaceOutput());
|
||||
selected.set_color_input(GetColorSpaceInput());
|
||||
selected.set_color_output(GetColorSpaceOutput());
|
||||
|
||||
return selected;
|
||||
return selected;
|
||||
}
|
||||
|
||||
QString ColorDialog::GetColorSpaceInput() const
|
||||
{
|
||||
return chooser_->input();
|
||||
return chooser_->input();
|
||||
}
|
||||
|
||||
ColorTransform ColorDialog::GetColorSpaceOutput() const
|
||||
{
|
||||
return chooser_->output();
|
||||
return chooser_->output();
|
||||
}
|
||||
|
||||
void ColorDialog::ColorSpaceChanged(const QString &input, const ColorTransform &output)
|
||||
void ColorDialog::ColorSpaceChanged(const QString &input,
|
||||
const ColorTransform &output)
|
||||
{
|
||||
input_to_ref_processor_ = ColorProcessor::Create(color_manager_, input, color_manager_->GetReferenceColorSpace());
|
||||
input_to_ref_processor_ = ColorProcessor::Create(
|
||||
color_manager_, input, color_manager_->GetReferenceColorSpace());
|
||||
|
||||
ColorProcessorPtr ref_to_display = ColorProcessor::Create(color_manager_,
|
||||
color_manager_->GetReferenceColorSpace(),
|
||||
output);
|
||||
ColorProcessorPtr ref_to_display = ColorProcessor::Create(
|
||||
color_manager_, color_manager_->GetReferenceColorSpace(), output);
|
||||
|
||||
ColorProcessorPtr ref_to_input = ColorProcessor::Create(color_manager_, color_manager_->GetReferenceColorSpace(), input);
|
||||
ColorProcessorPtr ref_to_input = ColorProcessor::Create(
|
||||
color_manager_, color_manager_->GetReferenceColorSpace(), input);
|
||||
|
||||
// FIXME: For some reason, using OCIO::TRANSFORM_DIR_INVERSE (wrapped by ColorProcessor::kInverse) causes OCIO to
|
||||
// crash. We've disabled that functionality for now (also disabling display_tab_ in ColorValuesWidget)
|
||||
// FIXME: For some reason, using OCIO::TRANSFORM_DIR_INVERSE (wrapped by ColorProcessor::kInverse) causes OCIO to
|
||||
// crash. We've disabled that functionality for now (also disabling display_tab_ in ColorValuesWidget)
|
||||
|
||||
/*ColorProcessorPtr display_to_ref = ColorProcessor::Create(color_manager_->GetConfig(),
|
||||
/*ColorProcessorPtr display_to_ref = ColorProcessor::Create(color_manager_->GetConfig(),
|
||||
color_manager_->GetReferenceColorSpace(),
|
||||
display,
|
||||
view,
|
||||
look,
|
||||
ColorProcessor::kInverse);*/
|
||||
|
||||
color_wheel_->SetColorProcessor(input_to_ref_processor_, ref_to_display);
|
||||
hsv_value_gradient_->SetColorProcessor(input_to_ref_processor_, ref_to_display);
|
||||
color_values_widget_->SetColorProcessor(input_to_ref_processor_, ref_to_display, nullptr, ref_to_input);
|
||||
color_wheel_->SetColorProcessor(input_to_ref_processor_, ref_to_display);
|
||||
hsv_value_gradient_->SetColorProcessor(input_to_ref_processor_,
|
||||
ref_to_display);
|
||||
color_values_widget_->SetColorProcessor(
|
||||
input_to_ref_processor_, ref_to_display, nullptr, ref_to_input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
#include "widget/colorwheel/colorvalueswidget.h"
|
||||
#include "widget/colorwheel/colorwheelwidget.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ColorDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ColorDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief ColorDialog Constructor
|
||||
*
|
||||
* @param color_manager
|
||||
@@ -56,40 +56,41 @@ public:
|
||||
*
|
||||
* QWidget parent.
|
||||
*/
|
||||
ColorDialog(ColorManager* color_manager, const ManagedColor &start = Color(1.0f, 1.0f, 1.0f), QWidget* parent = nullptr);
|
||||
ColorDialog(ColorManager *color_manager,
|
||||
const ManagedColor &start = Color(1.0f, 1.0f, 1.0f),
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Retrieves the color selected by the user
|
||||
*
|
||||
* The color is always returned in the ColorManager's reference space (usually scene linear).
|
||||
*/
|
||||
ManagedColor GetSelectedColor() const;
|
||||
ManagedColor GetSelectedColor() const;
|
||||
|
||||
QString GetColorSpaceInput() const;
|
||||
QString GetColorSpaceInput() const;
|
||||
|
||||
ColorTransform GetColorSpaceOutput() const;
|
||||
ColorTransform GetColorSpaceOutput() const;
|
||||
|
||||
public slots:
|
||||
void SetColor(const ManagedColor &c);
|
||||
void SetColor(const ManagedColor &c);
|
||||
|
||||
private:
|
||||
ColorManager* color_manager_;
|
||||
ColorManager *color_manager_;
|
||||
|
||||
ColorWheelWidget* color_wheel_;
|
||||
ColorWheelWidget *color_wheel_;
|
||||
|
||||
ColorValuesWidget* color_values_widget_;
|
||||
ColorValuesWidget *color_values_widget_;
|
||||
|
||||
ColorGradientWidget* hsv_value_gradient_;
|
||||
ColorGradientWidget *hsv_value_gradient_;
|
||||
|
||||
ColorProcessorPtr input_to_ref_processor_;
|
||||
ColorProcessorPtr input_to_ref_processor_;
|
||||
|
||||
ColorSpaceChooser* chooser_;
|
||||
ColorSpaceChooser *chooser_;
|
||||
|
||||
ColorSwatchChooser *swatch_;
|
||||
ColorSwatchChooser *swatch_;
|
||||
|
||||
private slots:
|
||||
void ColorSpaceChanged(const QString& input, const ColorTransform &output);
|
||||
|
||||
void ColorSpaceChanged(const QString &input, const ColorTransform &output);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,66 +26,68 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
ConfigDialogBase::ConfigDialogBase(QWidget* parent) :
|
||||
QDialog(parent)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
QSplitter* splitter = new QSplitter();
|
||||
splitter->setChildrenCollapsible(false);
|
||||
layout->addWidget(splitter);
|
||||
ConfigDialogBase::ConfigDialogBase(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
list_widget_ = new QListWidget();
|
||||
QSplitter *splitter = new QSplitter();
|
||||
splitter->setChildrenCollapsible(false);
|
||||
layout->addWidget(splitter);
|
||||
|
||||
preference_pane_stack_ = new QStackedWidget(this);
|
||||
list_widget_ = new QListWidget();
|
||||
|
||||
splitter->addWidget(list_widget_);
|
||||
splitter->addWidget(preference_pane_stack_);
|
||||
preference_pane_stack_ = new QStackedWidget(this);
|
||||
|
||||
QDialogButtonBox* button_box = new QDialogButtonBox(this);
|
||||
button_box->setOrientation(Qt::Horizontal);
|
||||
button_box->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
|
||||
splitter->addWidget(list_widget_);
|
||||
splitter->addWidget(preference_pane_stack_);
|
||||
|
||||
layout->addWidget(button_box);
|
||||
QDialogButtonBox *button_box = new QDialogButtonBox(this);
|
||||
button_box->setOrientation(Qt::Horizontal);
|
||||
button_box->setStandardButtons(QDialogButtonBox::Cancel |
|
||||
QDialogButtonBox::Ok);
|
||||
|
||||
connect(button_box, &QDialogButtonBox::accepted, this, &ConfigDialogBase::accept);
|
||||
connect(button_box, &QDialogButtonBox::rejected, this, &ConfigDialogBase::reject);
|
||||
layout->addWidget(button_box);
|
||||
|
||||
connect(list_widget_,
|
||||
&QListWidget::currentRowChanged,
|
||||
preference_pane_stack_,
|
||||
&QStackedWidget::setCurrentIndex);
|
||||
connect(button_box, &QDialogButtonBox::accepted, this,
|
||||
&ConfigDialogBase::accept);
|
||||
connect(button_box, &QDialogButtonBox::rejected, this,
|
||||
&ConfigDialogBase::reject);
|
||||
|
||||
connect(list_widget_, &QListWidget::currentRowChanged,
|
||||
preference_pane_stack_, &QStackedWidget::setCurrentIndex);
|
||||
}
|
||||
|
||||
void ConfigDialogBase::accept()
|
||||
{
|
||||
foreach (ConfigDialogBaseTab* tab, tabs_) {
|
||||
if (!tab->Validate()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
foreach (ConfigDialogBaseTab *tab, tabs_) {
|
||||
if (!tab->Validate()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MultiUndoCommand* command = new MultiUndoCommand();
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
|
||||
foreach (ConfigDialogBaseTab* tab, tabs_) {
|
||||
tab->Accept(command);
|
||||
}
|
||||
foreach (ConfigDialogBaseTab *tab, tabs_) {
|
||||
tab->Accept(command);
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command, tr("Set Configuration"));
|
||||
Core::instance()->undo_stack()->push(command, tr("Set Configuration"));
|
||||
|
||||
AcceptEvent();
|
||||
AcceptEvent();
|
||||
|
||||
QDialog::accept();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void ConfigDialogBase::AddTab(ConfigDialogBaseTab *tab, const QString &title)
|
||||
{
|
||||
list_widget_->addItem(title);
|
||||
preference_pane_stack_->addWidget(tab);
|
||||
list_widget_->addItem(title);
|
||||
preference_pane_stack_->addWidget(tab);
|
||||
|
||||
tabs_.append(tab);
|
||||
tabs_.append(tab);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,32 +27,33 @@
|
||||
|
||||
#include "configdialogbasetab.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ConfigDialogBase : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ConfigDialogBase : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConfigDialogBase(QWidget* parent = nullptr);
|
||||
ConfigDialogBase(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
/**
|
||||
/**
|
||||
* @brief Override of accept to save preferences to Config.
|
||||
*/
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
protected:
|
||||
void AddTab(ConfigDialogBaseTab* tab, const QString& title);
|
||||
void AddTab(ConfigDialogBaseTab *tab, const QString &title);
|
||||
|
||||
virtual void AcceptEvent(){}
|
||||
virtual void AcceptEvent()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
QListWidget* list_widget_;
|
||||
QListWidget *list_widget_;
|
||||
|
||||
QStackedWidget* preference_pane_stack_;
|
||||
|
||||
QList<ConfigDialogBaseTab*> tabs_;
|
||||
QStackedWidget *preference_pane_stack_;
|
||||
|
||||
QList<ConfigDialogBaseTab *> tabs_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
|
||||
#include "configdialogbasetab.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
bool ConfigDialogBaseTab::Validate()
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,16 +26,16 @@
|
||||
#include "config/config.h"
|
||||
#include "undo/undocommand.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ConfigDialogBaseTab : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class ConfigDialogBaseTab : public QWidget {
|
||||
public:
|
||||
ConfigDialogBaseTab() = default;
|
||||
ConfigDialogBaseTab() = default;
|
||||
|
||||
virtual bool Validate();
|
||||
virtual bool Validate();
|
||||
|
||||
virtual void Accept(MultiUndoCommand *parent) = 0;
|
||||
virtual void Accept(MultiUndoCommand *parent) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,86 +28,101 @@
|
||||
#include "config/config.h"
|
||||
#include "core.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
DiskCacheDialog::DiskCacheDialog(DiskCacheFolder *folder, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
folder_(folder)
|
||||
namespace olive
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
|
||||
int row = 0;
|
||||
DiskCacheDialog::DiskCacheDialog(DiskCacheFolder *folder, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, folder_(folder)
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Disk Cache: %1").arg(folder->GetPath())), row, 0, 1, 2);
|
||||
setWindowTitle(tr("Disk Cache Settings"));
|
||||
int row = 0;
|
||||
|
||||
row++;
|
||||
layout->addWidget(new QLabel(tr("Disk Cache: %1").arg(folder->GetPath())),
|
||||
row, 0, 1, 2);
|
||||
setWindowTitle(tr("Disk Cache Settings"));
|
||||
|
||||
layout->addWidget(new QLabel(tr("Maximum Disk Cache:")), row, 0);
|
||||
row++;
|
||||
|
||||
maximum_cache_slider_ = new FloatSlider();
|
||||
maximum_cache_slider_->SetFormat(tr("%1 GB"));
|
||||
maximum_cache_slider_->SetMinimum(1.0);
|
||||
maximum_cache_slider_->SetValue(static_cast<double>(folder->GetLimit()) / static_cast<double>(kBytesInGigabyte));
|
||||
layout->addWidget(maximum_cache_slider_, row, 1);
|
||||
layout->addWidget(new QLabel(tr("Maximum Disk Cache:")), row, 0);
|
||||
|
||||
row++;
|
||||
maximum_cache_slider_ = new FloatSlider();
|
||||
maximum_cache_slider_->SetFormat(tr("%1 GB"));
|
||||
maximum_cache_slider_->SetMinimum(1.0);
|
||||
maximum_cache_slider_->SetValue(static_cast<double>(folder->GetLimit()) /
|
||||
static_cast<double>(kBytesInGigabyte));
|
||||
layout->addWidget(maximum_cache_slider_, row, 1);
|
||||
|
||||
clear_cache_btn_ = new QPushButton(tr("Clear Disk Cache"));
|
||||
connect(clear_cache_btn_, &QPushButton::clicked, this, static_cast<void(DiskCacheDialog::*)()>(&DiskCacheDialog::ClearDiskCache));
|
||||
layout->addWidget(clear_cache_btn_, row, 1);
|
||||
row++;
|
||||
|
||||
row++;
|
||||
clear_cache_btn_ = new QPushButton(tr("Clear Disk Cache"));
|
||||
connect(clear_cache_btn_, &QPushButton::clicked, this,
|
||||
static_cast<void (DiskCacheDialog::*)()>(
|
||||
&DiskCacheDialog::ClearDiskCache));
|
||||
layout->addWidget(clear_cache_btn_, row, 1);
|
||||
|
||||
clear_disk_cache_ = new QCheckBox(tr("Automatically clear disk cache on close"));
|
||||
clear_disk_cache_->setChecked(folder->GetClearOnClose());
|
||||
layout->addWidget(clear_disk_cache_, row, 1);
|
||||
row++;
|
||||
|
||||
row++;
|
||||
clear_disk_cache_ =
|
||||
new QCheckBox(tr("Automatically clear disk cache on close"));
|
||||
clear_disk_cache_->setChecked(folder->GetClearOnClose());
|
||||
layout->addWidget(clear_disk_cache_, row, 1);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &DiskCacheDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &DiskCacheDialog::reject);
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
row++;
|
||||
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this,
|
||||
&DiskCacheDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this,
|
||||
&DiskCacheDialog::reject);
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
void DiskCacheDialog::accept()
|
||||
{
|
||||
qint64 new_disk_cache_limit = qRound64(maximum_cache_slider_->GetValue() * kBytesInGigabyte);
|
||||
if (new_disk_cache_limit != folder_->GetLimit()) {
|
||||
folder_->SetLimit(new_disk_cache_limit);
|
||||
}
|
||||
qint64 new_disk_cache_limit =
|
||||
qRound64(maximum_cache_slider_->GetValue() * kBytesInGigabyte);
|
||||
if (new_disk_cache_limit != folder_->GetLimit()) {
|
||||
folder_->SetLimit(new_disk_cache_limit);
|
||||
}
|
||||
|
||||
if (folder_->GetClearOnClose() != clear_disk_cache_->isChecked()) {
|
||||
folder_->SetClearOnClose(clear_disk_cache_->isChecked());
|
||||
}
|
||||
if (folder_->GetClearOnClose() != clear_disk_cache_->isChecked()) {
|
||||
folder_->SetClearOnClose(clear_disk_cache_->isChecked());
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void DiskCacheDialog::ClearDiskCache()
|
||||
{
|
||||
ClearDiskCache(folder_->GetPath(), this, clear_cache_btn_);
|
||||
ClearDiskCache(folder_->GetPath(), this, clear_cache_btn_);
|
||||
}
|
||||
|
||||
void DiskCacheDialog::ClearDiskCache(const QString &path, QWidget *parent, QPushButton *clear_btn)
|
||||
void DiskCacheDialog::ClearDiskCache(const QString &path, QWidget *parent,
|
||||
QPushButton *clear_btn)
|
||||
{
|
||||
if (QMessageBox::question(parent,
|
||||
tr("Clear Disk Cache"),
|
||||
tr("Are you sure you want to clear the disk cache in '%1'?").arg(path),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
if (clear_btn) clear_btn->setEnabled(false);
|
||||
if (QMessageBox::question(
|
||||
parent, tr("Clear Disk Cache"),
|
||||
tr("Are you sure you want to clear the disk cache in '%1'?")
|
||||
.arg(path),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
if (clear_btn)
|
||||
clear_btn->setEnabled(false);
|
||||
|
||||
if (DiskManager::instance()->ClearDiskCache(path)) {
|
||||
if (clear_btn) clear_btn->setText(tr("Disk Cache Cleared"));
|
||||
} else {
|
||||
QMessageBox::information(parent,
|
||||
tr("Clear Disk Cache"),
|
||||
tr("Disk cache failed to fully clear. You may have to delete the cache files manually."),
|
||||
QMessageBox::Ok);
|
||||
if (clear_btn) clear_btn->setText(tr("Disk Cache Partially Cleared"));
|
||||
}
|
||||
}
|
||||
if (DiskManager::instance()->ClearDiskCache(path)) {
|
||||
if (clear_btn)
|
||||
clear_btn->setText(tr("Disk Cache Cleared"));
|
||||
} else {
|
||||
QMessageBox::information(
|
||||
parent, tr("Clear Disk Cache"),
|
||||
tr("Disk cache failed to fully clear. You may have to delete the cache files manually."),
|
||||
QMessageBox::Ok);
|
||||
if (clear_btn)
|
||||
clear_btn->setText(tr("Disk Cache Partially Cleared"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,31 +28,31 @@
|
||||
#include "render/diskmanager.h"
|
||||
#include "widget/slider/floatslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class DiskCacheDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DiskCacheDialog(DiskCacheFolder* folder, QWidget* parent = nullptr);
|
||||
|
||||
static void ClearDiskCache(const QString &path, QWidget *parent, QPushButton *clear_btn = nullptr);
|
||||
class DiskCacheDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DiskCacheDialog(DiskCacheFolder *folder, QWidget *parent = nullptr);
|
||||
|
||||
static void ClearDiskCache(const QString &path, QWidget *parent,
|
||||
QPushButton *clear_btn = nullptr);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
DiskCacheFolder* folder_;
|
||||
DiskCacheFolder *folder_;
|
||||
|
||||
FloatSlider* maximum_cache_slider_;
|
||||
FloatSlider *maximum_cache_slider_;
|
||||
|
||||
QCheckBox* clear_disk_cache_;
|
||||
QCheckBox *clear_disk_cache_;
|
||||
|
||||
QPushButton* clear_cache_btn_;
|
||||
QPushButton *clear_cache_btn_;
|
||||
|
||||
private slots:
|
||||
void ClearDiskCache();
|
||||
|
||||
void ClearDiskCache();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,105 +28,111 @@
|
||||
#include "common/qtutils.h"
|
||||
#include "widget/slider/integerslider.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
AV1Section::AV1Section(QWidget *parent) :
|
||||
AV1Section(AV1CRFSection::kDefaultAV1CRF, parent)
|
||||
AV1Section::AV1Section(QWidget *parent)
|
||||
: AV1Section(AV1CRFSection::kDefaultAV1CRF, parent)
|
||||
{
|
||||
}
|
||||
|
||||
AV1Section::AV1Section(int default_crf, QWidget *parent) :
|
||||
CodecSection(parent)
|
||||
AV1Section::AV1Section(int default_crf, QWidget *parent)
|
||||
: CodecSection(parent)
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
layout->addWidget(new QLabel(tr("Preset:")), row, 0);
|
||||
int row = 0;
|
||||
layout->addWidget(new QLabel(tr("Preset:")), row, 0);
|
||||
|
||||
preset_combobox_ = new QComboBox();
|
||||
preset_combobox_->setToolTip(tr("This parameter governs the efficiency/encode-time trade-off.\n"
|
||||
"Lower presets will result in an output with better quality for a given file size, but will take longer to encode.\n"
|
||||
"Higher presets can result in a very fast encode, but will make some compromises on visual quality for a given crf value."));
|
||||
preset_combobox_ = new QComboBox();
|
||||
preset_combobox_->setToolTip(tr(
|
||||
"This parameter governs the efficiency/encode-time trade-off.\n"
|
||||
"Lower presets will result in an output with better quality for a given file size, but will take longer to encode.\n"
|
||||
"Higher presets can result in a very fast encode, but will make some compromises on visual quality for a given crf value."));
|
||||
|
||||
for (int i = 0; i <= 13; i++)
|
||||
preset_combobox_->addItem(QString::number(i));
|
||||
for (int i = 0; i <= 13; i++)
|
||||
preset_combobox_->addItem(QString::number(i));
|
||||
|
||||
preset_combobox_->setCurrentIndex(8);
|
||||
preset_combobox_->setCurrentIndex(8);
|
||||
|
||||
layout->addWidget(preset_combobox_, row, 1);
|
||||
layout->addWidget(preset_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Compression Method:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Compression Method:")), row, 0);
|
||||
|
||||
QComboBox* compression_box = new QComboBox();
|
||||
compression_box->setToolTip(tr("This parameter governs the quality/size trade-off.\n"
|
||||
"Higher CRF values will result in a final output that takes less space, but begins to lose detail.\n"
|
||||
"Lower CRF values retain more detail at the cost of larger file sizes.\n"
|
||||
"The possible range of CRF in SVT-AV1 is 1-63."));
|
||||
QComboBox *compression_box = new QComboBox();
|
||||
compression_box->setToolTip(tr(
|
||||
"This parameter governs the quality/size trade-off.\n"
|
||||
"Higher CRF values will result in a final output that takes less space, but begins to lose detail.\n"
|
||||
"Lower CRF values retain more detail at the cost of larger file sizes.\n"
|
||||
"The possible range of CRF in SVT-AV1 is 1-63."));
|
||||
|
||||
// These items must correspond to the CompressionMethod enum
|
||||
compression_box->addItem(tr("Constant Rate Factor"));
|
||||
// These items must correspond to the CompressionMethod enum
|
||||
compression_box->addItem(tr("Constant Rate Factor"));
|
||||
|
||||
layout->addWidget(compression_box, row, 1);
|
||||
layout->addWidget(compression_box, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
compression_method_stack_ = new QStackedWidget();
|
||||
layout->addWidget(compression_method_stack_, row, 0, 1, 2);
|
||||
compression_method_stack_ = new QStackedWidget();
|
||||
layout->addWidget(compression_method_stack_, row, 0, 1, 2);
|
||||
|
||||
crf_section_ = new AV1CRFSection(default_crf);
|
||||
compression_method_stack_->addWidget(crf_section_);
|
||||
crf_section_ = new AV1CRFSection(default_crf);
|
||||
compression_method_stack_->addWidget(crf_section_);
|
||||
|
||||
connect(compression_box,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
compression_method_stack_,
|
||||
&QStackedWidget::setCurrentIndex);
|
||||
connect(
|
||||
compression_box,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
compression_method_stack_, &QStackedWidget::setCurrentIndex);
|
||||
}
|
||||
|
||||
void AV1Section::AddOpts(EncodingParams *params)
|
||||
{
|
||||
CompressionMethod method = static_cast<CompressionMethod>(
|
||||
compression_method_stack_->currentIndex());
|
||||
|
||||
CompressionMethod method = static_cast<CompressionMethod>(compression_method_stack_->currentIndex());
|
||||
if (method == kConstantRateFactor) {
|
||||
// Set Quantizer value
|
||||
params->set_video_option(QStringLiteral("qp"),
|
||||
QString::number(crf_section_->GetValue()));
|
||||
}
|
||||
|
||||
if (method == kConstantRateFactor) {
|
||||
|
||||
// Set Quantizer value
|
||||
params->set_video_option(QStringLiteral("qp"), QString::number(crf_section_->GetValue()));
|
||||
|
||||
}
|
||||
|
||||
params->set_video_option(QStringLiteral("preset"), QString::number(preset_combobox_->currentIndex()));
|
||||
params->set_video_option(QStringLiteral("preset"),
|
||||
QString::number(preset_combobox_->currentIndex()));
|
||||
}
|
||||
|
||||
AV1CRFSection::AV1CRFSection(int default_crf, QWidget *parent) :
|
||||
QWidget(parent)
|
||||
AV1CRFSection::AV1CRFSection(int default_crf, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
crf_slider_ = new QSlider(Qt::Horizontal);
|
||||
crf_slider_->setMinimum(kMinimumCRF);
|
||||
crf_slider_->setMaximum(kMaximumCRF);
|
||||
crf_slider_->setValue(default_crf);
|
||||
layout->addWidget(crf_slider_);
|
||||
crf_slider_ = new QSlider(Qt::Horizontal);
|
||||
crf_slider_->setMinimum(kMinimumCRF);
|
||||
crf_slider_->setMaximum(kMaximumCRF);
|
||||
crf_slider_->setValue(default_crf);
|
||||
layout->addWidget(crf_slider_);
|
||||
|
||||
IntegerSlider* crf_input = new IntegerSlider();
|
||||
crf_input->setMaximumWidth(QtUtils::QFontMetricsWidth(crf_input->fontMetrics(), QStringLiteral("HHHH")));
|
||||
crf_input->SetMinimum(kMinimumCRF);
|
||||
crf_input->SetMaximum(kMaximumCRF);
|
||||
crf_input->SetValue(default_crf);
|
||||
crf_input->SetDefaultValue(default_crf);
|
||||
layout->addWidget(crf_input);
|
||||
IntegerSlider *crf_input = new IntegerSlider();
|
||||
crf_input->setMaximumWidth(QtUtils::QFontMetricsWidth(
|
||||
crf_input->fontMetrics(), QStringLiteral("HHHH")));
|
||||
crf_input->SetMinimum(kMinimumCRF);
|
||||
crf_input->SetMaximum(kMaximumCRF);
|
||||
crf_input->SetValue(default_crf);
|
||||
crf_input->SetDefaultValue(default_crf);
|
||||
layout->addWidget(crf_input);
|
||||
|
||||
connect(crf_slider_, &QSlider::valueChanged, crf_input, &IntegerSlider::SetValue);
|
||||
connect(crf_input, &IntegerSlider::ValueChanged, crf_slider_, &QSlider::setValue);
|
||||
connect(crf_slider_, &QSlider::valueChanged, crf_input,
|
||||
&IntegerSlider::SetValue);
|
||||
connect(crf_input, &IntegerSlider::ValueChanged, crf_slider_,
|
||||
&QSlider::setValue);
|
||||
}
|
||||
|
||||
int AV1CRFSection::GetValue() const
|
||||
{
|
||||
return crf_slider_->value();
|
||||
return crf_slider_->value();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,45 +28,43 @@
|
||||
#include "codecsection.h"
|
||||
#include "widget/slider/floatslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class AV1CRFSection : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class AV1CRFSection : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AV1CRFSection(int default_crf, QWidget* parent = nullptr);
|
||||
AV1CRFSection(int default_crf, QWidget *parent = nullptr);
|
||||
|
||||
int GetValue() const;
|
||||
int GetValue() const;
|
||||
|
||||
static const int kDefaultAV1CRF = 30;
|
||||
static const int kDefaultAV1CRF = 30;
|
||||
|
||||
private:
|
||||
static const int kMinimumCRF = 0;
|
||||
static const int kMaximumCRF = 63;
|
||||
|
||||
QSlider* crf_slider_;
|
||||
static const int kMinimumCRF = 0;
|
||||
static const int kMaximumCRF = 63;
|
||||
|
||||
QSlider *crf_slider_;
|
||||
};
|
||||
|
||||
class AV1Section : public CodecSection
|
||||
{
|
||||
Q_OBJECT
|
||||
class AV1Section : public CodecSection {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum CompressionMethod {
|
||||
kConstantRateFactor,
|
||||
};
|
||||
enum CompressionMethod {
|
||||
kConstantRateFactor,
|
||||
};
|
||||
|
||||
AV1Section(QWidget* parent = nullptr);
|
||||
AV1Section(int default_crf, QWidget* parent);
|
||||
AV1Section(QWidget *parent = nullptr);
|
||||
AV1Section(int default_crf, QWidget *parent);
|
||||
|
||||
virtual void AddOpts(EncodingParams* params) override;
|
||||
virtual void AddOpts(EncodingParams *params) override;
|
||||
|
||||
private:
|
||||
QStackedWidget* compression_method_stack_;
|
||||
QStackedWidget *compression_method_stack_;
|
||||
|
||||
AV1CRFSection* crf_section_;
|
||||
AV1CRFSection *crf_section_;
|
||||
|
||||
QComboBox *preset_combobox_;
|
||||
QComboBox *preset_combobox_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,22 +23,23 @@
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
|
||||
namespace olive {
|
||||
|
||||
CineformSection::CineformSection(QWidget *parent) :
|
||||
CodecSection(parent)
|
||||
namespace olive
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
CineformSection::CineformSection(QWidget *parent)
|
||||
: CodecSection(parent)
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
int row = 0;
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Quality:")), row, 0);
|
||||
int row = 0;
|
||||
|
||||
quality_combobox_ = new QComboBox();
|
||||
layout->addWidget(new QLabel(tr("Quality:")), row, 0);
|
||||
|
||||
/* Correspond to the following indexes for FFmpeg
|
||||
quality_combobox_ = new QComboBox();
|
||||
|
||||
/* Correspond to the following indexes for FFmpeg
|
||||
*
|
||||
* -quality <int> E..V....... set quality (from 0 to 12) (default film3+)
|
||||
* film3+ 0 E..V.......
|
||||
@@ -57,34 +58,37 @@ CineformSection::CineformSection(QWidget *parent) :
|
||||
*
|
||||
*/
|
||||
|
||||
quality_combobox_->addItem(tr("Film Scan 3+"));
|
||||
quality_combobox_->addItem(tr("Film Scan 3"));
|
||||
quality_combobox_->addItem(tr("Film Scan 2+"));
|
||||
quality_combobox_->addItem(tr("Film Scan 2"));
|
||||
quality_combobox_->addItem(tr("Film Scan 1.5"));
|
||||
quality_combobox_->addItem(tr("Film Scan 1+"));
|
||||
quality_combobox_->addItem(tr("Film Scan 1"));
|
||||
quality_combobox_->addItem(tr("High+"));
|
||||
quality_combobox_->addItem(tr("High"));
|
||||
quality_combobox_->addItem(tr("Medium+"));
|
||||
quality_combobox_->addItem(tr("Medium"));
|
||||
quality_combobox_->addItem(tr("Low+"));
|
||||
quality_combobox_->addItem(tr("Low"));
|
||||
quality_combobox_->addItem(tr("Film Scan 3+"));
|
||||
quality_combobox_->addItem(tr("Film Scan 3"));
|
||||
quality_combobox_->addItem(tr("Film Scan 2+"));
|
||||
quality_combobox_->addItem(tr("Film Scan 2"));
|
||||
quality_combobox_->addItem(tr("Film Scan 1.5"));
|
||||
quality_combobox_->addItem(tr("Film Scan 1+"));
|
||||
quality_combobox_->addItem(tr("Film Scan 1"));
|
||||
quality_combobox_->addItem(tr("High+"));
|
||||
quality_combobox_->addItem(tr("High"));
|
||||
quality_combobox_->addItem(tr("Medium+"));
|
||||
quality_combobox_->addItem(tr("Medium"));
|
||||
quality_combobox_->addItem(tr("Low+"));
|
||||
quality_combobox_->addItem(tr("Low"));
|
||||
|
||||
// Default to "medium"
|
||||
quality_combobox_->setCurrentIndex(10);
|
||||
// Default to "medium"
|
||||
quality_combobox_->setCurrentIndex(10);
|
||||
|
||||
layout->addWidget(quality_combobox_, row, 1);
|
||||
layout->addWidget(quality_combobox_, row, 1);
|
||||
}
|
||||
|
||||
void CineformSection::AddOpts(EncodingParams *params)
|
||||
{
|
||||
params->set_video_option(QStringLiteral("quality"), QString::number(quality_combobox_->currentIndex()));
|
||||
params->set_video_option(
|
||||
QStringLiteral("quality"),
|
||||
QString::number(quality_combobox_->currentIndex()));
|
||||
}
|
||||
|
||||
void CineformSection::SetOpts(const EncodingParams *p)
|
||||
{
|
||||
quality_combobox_->setCurrentIndex(p->video_option(QStringLiteral("quality")).toInt());
|
||||
quality_combobox_->setCurrentIndex(
|
||||
p->video_option(QStringLiteral("quality")).toInt());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,21 +25,20 @@
|
||||
|
||||
#include "codecsection.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class CineformSection : public CodecSection
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class CineformSection : public CodecSection {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CineformSection(QWidget *parent = nullptr);
|
||||
CineformSection(QWidget *parent = nullptr);
|
||||
|
||||
virtual void AddOpts(EncodingParams* params) override;
|
||||
virtual void AddOpts(EncodingParams *params) override;
|
||||
|
||||
virtual void SetOpts(const EncodingParams *p) override;
|
||||
virtual void SetOpts(const EncodingParams *p) override;
|
||||
|
||||
private:
|
||||
QComboBox *quality_combobox_;
|
||||
|
||||
QComboBox *quality_combobox_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
#include "codecsection.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
CodecSection::CodecSection(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
CodecSection::CodecSection(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -25,18 +25,23 @@
|
||||
|
||||
#include "codec/encoder.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class CodecSection : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class CodecSection : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CodecSection(QWidget* parent = nullptr);
|
||||
CodecSection(QWidget *parent = nullptr);
|
||||
|
||||
virtual void AddOpts(EncodingParams* params){Q_UNUSED(params)}
|
||||
|
||||
virtual void SetOpts(const EncodingParams *p){Q_UNUSED(p)}
|
||||
virtual void AddOpts(EncodingParams *params)
|
||||
{
|
||||
Q_UNUSED(params)
|
||||
}
|
||||
|
||||
virtual void SetOpts(const EncodingParams *p)
|
||||
{
|
||||
Q_UNUSED(p)
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,34 +20,37 @@
|
||||
|
||||
#include "codecstack.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super QStackedWidget
|
||||
|
||||
CodecStack::CodecStack(QWidget *parent)
|
||||
: super{parent}
|
||||
: super{ parent }
|
||||
{
|
||||
connect(this, &CodecStack::currentChanged, this, &CodecStack::OnChange);
|
||||
connect(this, &CodecStack::currentChanged, this, &CodecStack::OnChange);
|
||||
}
|
||||
|
||||
void CodecStack::addWidget(QWidget *widget)
|
||||
{
|
||||
super::addWidget(widget);
|
||||
super::addWidget(widget);
|
||||
|
||||
OnChange(currentIndex());
|
||||
OnChange(currentIndex());
|
||||
}
|
||||
|
||||
void CodecStack::OnChange(int index)
|
||||
{
|
||||
for (int i=0; i<count(); i++) {
|
||||
if (i == index) {
|
||||
widget(i)->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
} else {
|
||||
widget(i)->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||
}
|
||||
widget(i)->adjustSize();
|
||||
}
|
||||
adjustSize();
|
||||
for (int i = 0; i < count(); i++) {
|
||||
if (i == index) {
|
||||
widget(i)->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
} else {
|
||||
widget(i)->setSizePolicy(QSizePolicy::Ignored,
|
||||
QSizePolicy::Ignored);
|
||||
}
|
||||
widget(i)->adjustSize();
|
||||
}
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,21 +23,20 @@
|
||||
|
||||
#include <QStackedWidget>
|
||||
|
||||
namespace olive {
|
||||
|
||||
class CodecStack : public QStackedWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CodecStack(QWidget *parent = nullptr);
|
||||
|
||||
void addWidget(QWidget *widget);
|
||||
class CodecStack : public QStackedWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CodecStack(QWidget *parent = nullptr);
|
||||
|
||||
void addWidget(QWidget *widget);
|
||||
|
||||
signals:
|
||||
|
||||
private slots:
|
||||
void OnChange(int index);
|
||||
|
||||
void OnChange(int index);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,274 +28,284 @@
|
||||
#include "common/qtutils.h"
|
||||
#include "widget/slider/integerslider.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
H264Section::H264Section(QWidget *parent) :
|
||||
H264Section(H264CRFSection::kDefaultH264CRF, parent)
|
||||
H264Section::H264Section(QWidget *parent)
|
||||
: H264Section(H264CRFSection::kDefaultH264CRF, parent)
|
||||
{
|
||||
}
|
||||
|
||||
H264Section::H264Section(int default_crf, QWidget *parent) :
|
||||
CodecSection(parent)
|
||||
H264Section::H264Section(int default_crf, QWidget *parent)
|
||||
: CodecSection(parent)
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
layout->addWidget(new QLabel(tr("Encode Speed:")), row, 0);
|
||||
int row = 0;
|
||||
layout->addWidget(new QLabel(tr("Encode Speed:")), row, 0);
|
||||
|
||||
preset_combobox_ = new QComboBox();
|
||||
preset_combobox_->setToolTip(tr(
|
||||
"This setting allows you to tweak the ratio of export speed to compression quality. \n\n"
|
||||
"If using Constant Rate Factor, slower speeds will result in smaller file sizes for the same quality. \n\n"
|
||||
"If using Target Bit Rate or Target File Size, slower speeds will result in higher quality for the same bitrate/filesize. \n\n"
|
||||
"This setting is equivalent to the `preset` setting in libx264."));
|
||||
|
||||
preset_combobox_ = new QComboBox();
|
||||
preset_combobox_->setToolTip(tr("This setting allows you to tweak the ratio of export speed to compression quality. \n\n"
|
||||
"If using Constant Rate Factor, slower speeds will result in smaller file sizes for the same quality. \n\n"
|
||||
"If using Target Bit Rate or Target File Size, slower speeds will result in higher quality for the same bitrate/filesize. \n\n"
|
||||
"This setting is equivalent to the `preset` setting in libx264."));
|
||||
preset_combobox_->addItem(tr("Ultra Fast"));
|
||||
preset_combobox_->addItem(tr("Super Fast"));
|
||||
preset_combobox_->addItem(tr("Very Fast"));
|
||||
preset_combobox_->addItem(tr("Faster"));
|
||||
preset_combobox_->addItem(tr("Fast"));
|
||||
preset_combobox_->addItem(tr("Medium"));
|
||||
preset_combobox_->addItem(tr("Slow"));
|
||||
preset_combobox_->addItem(tr("Slower"));
|
||||
preset_combobox_->addItem(tr("Very Slow"));
|
||||
|
||||
preset_combobox_->addItem(tr("Ultra Fast"));
|
||||
preset_combobox_->addItem(tr("Super Fast"));
|
||||
preset_combobox_->addItem(tr("Very Fast"));
|
||||
preset_combobox_->addItem(tr("Faster"));
|
||||
preset_combobox_->addItem(tr("Fast"));
|
||||
preset_combobox_->addItem(tr("Medium"));
|
||||
preset_combobox_->addItem(tr("Slow"));
|
||||
preset_combobox_->addItem(tr("Slower"));
|
||||
preset_combobox_->addItem(tr("Very Slow"));
|
||||
//Default to "medium"
|
||||
preset_combobox_->setCurrentIndex(5);
|
||||
|
||||
//Default to "medium"
|
||||
preset_combobox_->setCurrentIndex(5);
|
||||
layout->addWidget(preset_combobox_, row, 1);
|
||||
|
||||
layout->addWidget(preset_combobox_, row, 1);
|
||||
row++;
|
||||
|
||||
row++;
|
||||
layout->addWidget(new QLabel(tr("Compression Method:")), row, 0);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Compression Method:")), row, 0);
|
||||
QComboBox *compression_box = new QComboBox();
|
||||
|
||||
QComboBox* compression_box = new QComboBox();
|
||||
// These items must correspond to the CompressionMethod enum
|
||||
compression_box->addItem(tr("Constant Rate Factor"));
|
||||
compression_box->addItem(tr("Target Bit Rate"));
|
||||
compression_box->addItem(tr("Target File Size"));
|
||||
|
||||
// These items must correspond to the CompressionMethod enum
|
||||
compression_box->addItem(tr("Constant Rate Factor"));
|
||||
compression_box->addItem(tr("Target Bit Rate"));
|
||||
compression_box->addItem(tr("Target File Size"));
|
||||
layout->addWidget(compression_box, row, 1);
|
||||
|
||||
layout->addWidget(compression_box, row, 1);
|
||||
row++;
|
||||
|
||||
row++;
|
||||
compression_method_stack_ = new QStackedWidget();
|
||||
layout->addWidget(compression_method_stack_, row, 0, 1, 2);
|
||||
|
||||
compression_method_stack_ = new QStackedWidget();
|
||||
layout->addWidget(compression_method_stack_, row, 0, 1, 2);
|
||||
crf_section_ = new H264CRFSection(default_crf);
|
||||
compression_method_stack_->addWidget(crf_section_);
|
||||
|
||||
crf_section_ = new H264CRFSection(default_crf);
|
||||
compression_method_stack_->addWidget(crf_section_);
|
||||
bitrate_section_ = new H264BitRateSection();
|
||||
compression_method_stack_->addWidget(bitrate_section_);
|
||||
|
||||
bitrate_section_ = new H264BitRateSection();
|
||||
compression_method_stack_->addWidget(bitrate_section_);
|
||||
filesize_section_ = new H264FileSizeSection();
|
||||
compression_method_stack_->addWidget(filesize_section_);
|
||||
|
||||
filesize_section_ = new H264FileSizeSection();
|
||||
compression_method_stack_->addWidget(filesize_section_);
|
||||
|
||||
connect(compression_box,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
compression_method_stack_,
|
||||
&QStackedWidget::setCurrentIndex);
|
||||
connect(
|
||||
compression_box,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
compression_method_stack_, &QStackedWidget::setCurrentIndex);
|
||||
}
|
||||
|
||||
void H264Section::AddOpts(EncodingParams *params)
|
||||
{
|
||||
// FIXME: Implement two-pass
|
||||
// FIXME: Implement two-pass
|
||||
|
||||
CompressionMethod method = static_cast<CompressionMethod>(compression_method_stack_->currentIndex());
|
||||
CompressionMethod method = static_cast<CompressionMethod>(
|
||||
compression_method_stack_->currentIndex());
|
||||
|
||||
// This option is not used by the encoder (nor is anything with the ove_ prefix), it's to help us
|
||||
// identify which option was chosen when params are restored
|
||||
params->set_video_option(QStringLiteral("ove_compressionmethod"), QString::number(method));
|
||||
// This option is not used by the encoder (nor is anything with the ove_ prefix), it's to help us
|
||||
// identify which option was chosen when params are restored
|
||||
params->set_video_option(QStringLiteral("ove_compressionmethod"),
|
||||
QString::number(method));
|
||||
|
||||
if (method == kConstantRateFactor) {
|
||||
if (method == kConstantRateFactor) {
|
||||
// Simply set CRF value
|
||||
params->set_video_option(QStringLiteral("crf"),
|
||||
QString::number(crf_section_->GetValue()));
|
||||
|
||||
// Simply set CRF value
|
||||
params->set_video_option(QStringLiteral("crf"), QString::number(crf_section_->GetValue()));
|
||||
} else {
|
||||
int64_t target_rate, max_rate, min_rate;
|
||||
|
||||
} else {
|
||||
if (method == kTargetBitRate) {
|
||||
// Use user-supplied values for the bit rate
|
||||
target_rate = bitrate_section_->GetTargetBitRate();
|
||||
min_rate = 0;
|
||||
max_rate = bitrate_section_->GetMaximumBitRate();
|
||||
} else {
|
||||
// Calculate the bit rate from the file size divided by the sequence length in seconds (bits per second)
|
||||
int64_t target_fs = filesize_section_->GetFileSize();
|
||||
target_rate = qRound64(static_cast<double>(target_fs) /
|
||||
params->GetExportLength().toDouble());
|
||||
min_rate = target_rate;
|
||||
max_rate = target_rate;
|
||||
|
||||
int64_t target_rate, max_rate, min_rate;
|
||||
params->set_video_option(QStringLiteral("ove_targetfilesize"),
|
||||
QString::number(target_fs));
|
||||
}
|
||||
|
||||
if (method == kTargetBitRate) {
|
||||
// Use user-supplied values for the bit rate
|
||||
target_rate = bitrate_section_->GetTargetBitRate();
|
||||
min_rate = 0;
|
||||
max_rate = bitrate_section_->GetMaximumBitRate();
|
||||
} else {
|
||||
// Calculate the bit rate from the file size divided by the sequence length in seconds (bits per second)
|
||||
int64_t target_fs = filesize_section_->GetFileSize();
|
||||
target_rate = qRound64(static_cast<double>(target_fs) / params->GetExportLength().toDouble());
|
||||
min_rate = target_rate;
|
||||
max_rate = target_rate;
|
||||
// Disable CRF encoding
|
||||
params->set_video_option(QStringLiteral("crf"), QStringLiteral("-1"));
|
||||
|
||||
params->set_video_option(QStringLiteral("ove_targetfilesize"), QString::number(target_fs));
|
||||
}
|
||||
params->set_video_bit_rate(target_rate);
|
||||
params->set_video_min_bit_rate(min_rate);
|
||||
params->set_video_max_bit_rate(max_rate);
|
||||
params->set_video_buffer_size(2000000);
|
||||
}
|
||||
|
||||
// Disable CRF encoding
|
||||
params->set_video_option(QStringLiteral("crf"), QStringLiteral("-1"));
|
||||
|
||||
params->set_video_bit_rate(target_rate);
|
||||
params->set_video_min_bit_rate(min_rate);
|
||||
params->set_video_max_bit_rate(max_rate);
|
||||
params->set_video_buffer_size(2000000);
|
||||
|
||||
}
|
||||
|
||||
params->set_video_option(QStringLiteral("preset"), QString::number(preset_combobox_->currentIndex()));
|
||||
params->set_video_option(QStringLiteral("preset"),
|
||||
QString::number(preset_combobox_->currentIndex()));
|
||||
}
|
||||
|
||||
void H264Section::SetOpts(const EncodingParams *p)
|
||||
{
|
||||
CompressionMethod method = static_cast<CompressionMethod>(p->video_option(QStringLiteral("ove_compressionmethod")).toInt());
|
||||
CompressionMethod method = static_cast<CompressionMethod>(
|
||||
p->video_option(QStringLiteral("ove_compressionmethod")).toInt());
|
||||
|
||||
compression_method_stack_->setCurrentIndex(method);
|
||||
compression_method_stack_->setCurrentIndex(method);
|
||||
|
||||
if (method == kConstantRateFactor) {
|
||||
crf_section_->SetValue(p->video_option(QStringLiteral("crf")).toInt());
|
||||
} else {
|
||||
int64_t target_rate = p->video_bit_rate();
|
||||
int64_t max_rate = p->video_max_bit_rate();
|
||||
if (method == kConstantRateFactor) {
|
||||
crf_section_->SetValue(p->video_option(QStringLiteral("crf")).toInt());
|
||||
} else {
|
||||
int64_t target_rate = p->video_bit_rate();
|
||||
int64_t max_rate = p->video_max_bit_rate();
|
||||
|
||||
if (method == kTargetBitRate) {
|
||||
// Use user-supplied values for the bit rate
|
||||
bitrate_section_->SetTargetBitRate(target_rate);
|
||||
bitrate_section_->SetMaximumBitRate(max_rate);
|
||||
} else {
|
||||
// Calculate the bit rate from the file size divided by the sequence length in seconds (bits per second)
|
||||
filesize_section_->SetFileSize(p->video_option(QStringLiteral("ove_targetfilesize")).toLongLong());
|
||||
}
|
||||
}
|
||||
if (method == kTargetBitRate) {
|
||||
// Use user-supplied values for the bit rate
|
||||
bitrate_section_->SetTargetBitRate(target_rate);
|
||||
bitrate_section_->SetMaximumBitRate(max_rate);
|
||||
} else {
|
||||
// Calculate the bit rate from the file size divided by the sequence length in seconds (bits per second)
|
||||
filesize_section_->SetFileSize(
|
||||
p->video_option(QStringLiteral("ove_targetfilesize"))
|
||||
.toLongLong());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
H264CRFSection::H264CRFSection(int default_crf, QWidget *parent) :
|
||||
QWidget(parent)
|
||||
H264CRFSection::H264CRFSection(int default_crf, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
crf_slider_ = new QSlider(Qt::Horizontal);
|
||||
crf_slider_->setMinimum(kMinimumCRF);
|
||||
crf_slider_->setMaximum(kMaximumCRF);
|
||||
crf_slider_->setValue(default_crf);
|
||||
layout->addWidget(crf_slider_);
|
||||
crf_slider_ = new QSlider(Qt::Horizontal);
|
||||
crf_slider_->setMinimum(kMinimumCRF);
|
||||
crf_slider_->setMaximum(kMaximumCRF);
|
||||
crf_slider_->setValue(default_crf);
|
||||
layout->addWidget(crf_slider_);
|
||||
|
||||
IntegerSlider* crf_input = new IntegerSlider();
|
||||
crf_input->setMaximumWidth(QtUtils::QFontMetricsWidth(crf_input->fontMetrics(), QStringLiteral("HHHH")));
|
||||
crf_input->SetMinimum(kMinimumCRF);
|
||||
crf_input->SetMaximum(kMaximumCRF);
|
||||
crf_input->SetValue(default_crf);
|
||||
crf_input->SetDefaultValue(default_crf);
|
||||
layout->addWidget(crf_input);
|
||||
IntegerSlider *crf_input = new IntegerSlider();
|
||||
crf_input->setMaximumWidth(QtUtils::QFontMetricsWidth(
|
||||
crf_input->fontMetrics(), QStringLiteral("HHHH")));
|
||||
crf_input->SetMinimum(kMinimumCRF);
|
||||
crf_input->SetMaximum(kMaximumCRF);
|
||||
crf_input->SetValue(default_crf);
|
||||
crf_input->SetDefaultValue(default_crf);
|
||||
layout->addWidget(crf_input);
|
||||
|
||||
connect(crf_slider_, &QSlider::valueChanged, crf_input, &IntegerSlider::SetValue);
|
||||
connect(crf_input, &IntegerSlider::ValueChanged, crf_slider_, &QSlider::setValue);
|
||||
connect(crf_slider_, &QSlider::valueChanged, crf_input,
|
||||
&IntegerSlider::SetValue);
|
||||
connect(crf_input, &IntegerSlider::ValueChanged, crf_slider_,
|
||||
&QSlider::setValue);
|
||||
}
|
||||
|
||||
int H264CRFSection::GetValue() const
|
||||
{
|
||||
return crf_slider_->value();
|
||||
return crf_slider_->value();
|
||||
}
|
||||
|
||||
void H264CRFSection::SetValue(int c)
|
||||
{
|
||||
crf_slider_->setValue(c);
|
||||
crf_slider_->setValue(c);
|
||||
}
|
||||
|
||||
H264BitRateSection::H264BitRateSection(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
H264BitRateSection::H264BitRateSection(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Target Bit Rate (Mbps):")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Target Bit Rate (Mbps):")), row, 0);
|
||||
|
||||
target_rate_ = new FloatSlider();
|
||||
target_rate_->SetMinimum(0);
|
||||
layout->addWidget(target_rate_, row, 1);
|
||||
target_rate_ = new FloatSlider();
|
||||
target_rate_->SetMinimum(0);
|
||||
layout->addWidget(target_rate_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Maximum Bit Rate (Mbps):")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Maximum Bit Rate (Mbps):")), row, 0);
|
||||
|
||||
max_rate_ = new FloatSlider();
|
||||
max_rate_->SetMinimum(0);
|
||||
layout->addWidget(max_rate_, row, 1);
|
||||
max_rate_ = new FloatSlider();
|
||||
max_rate_->SetMinimum(0);
|
||||
layout->addWidget(max_rate_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Two-Pass")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Two-Pass")), row, 0);
|
||||
|
||||
QCheckBox* two_pass_box = new QCheckBox();
|
||||
layout->addWidget(two_pass_box, row, 1);
|
||||
QCheckBox *two_pass_box = new QCheckBox();
|
||||
layout->addWidget(two_pass_box, row, 1);
|
||||
|
||||
// Bit rate defaults
|
||||
target_rate_->SetValue(16.0);
|
||||
max_rate_->SetValue(32.0);
|
||||
// Bit rate defaults
|
||||
target_rate_->SetValue(16.0);
|
||||
max_rate_->SetValue(32.0);
|
||||
}
|
||||
|
||||
int64_t H264BitRateSection::GetTargetBitRate() const
|
||||
{
|
||||
return qRound64(target_rate_->GetValue() * 1000000.0);
|
||||
return qRound64(target_rate_->GetValue() * 1000000.0);
|
||||
}
|
||||
|
||||
void H264BitRateSection::SetTargetBitRate(int64_t b)
|
||||
{
|
||||
target_rate_->SetValue(double(b) * 0.000001);
|
||||
target_rate_->SetValue(double(b) * 0.000001);
|
||||
}
|
||||
|
||||
int64_t H264BitRateSection::GetMaximumBitRate() const
|
||||
{
|
||||
return qRound64(max_rate_->GetValue() * 1000000.0);
|
||||
return qRound64(max_rate_->GetValue() * 1000000.0);
|
||||
}
|
||||
|
||||
void H264BitRateSection::SetMaximumBitRate(int64_t b)
|
||||
{
|
||||
max_rate_->SetValue(double(b) * 0.000001);
|
||||
max_rate_->SetValue(double(b) * 0.000001);
|
||||
}
|
||||
|
||||
H264FileSizeSection::H264FileSizeSection(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
H264FileSizeSection::H264FileSizeSection(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Target File Size (MB):")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Target File Size (MB):")), row, 0);
|
||||
|
||||
file_size_ = new FloatSlider();
|
||||
file_size_->SetMinimum(0);
|
||||
layout->addWidget(file_size_, row, 1);
|
||||
file_size_ = new FloatSlider();
|
||||
file_size_->SetMinimum(0);
|
||||
layout->addWidget(file_size_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Two-Pass")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Two-Pass")), row, 0);
|
||||
|
||||
QCheckBox* two_pass_box = new QCheckBox();
|
||||
layout->addWidget(two_pass_box, row, 1);
|
||||
QCheckBox *two_pass_box = new QCheckBox();
|
||||
layout->addWidget(two_pass_box, row, 1);
|
||||
|
||||
// File size defaults
|
||||
file_size_->SetValue(700.0);
|
||||
// File size defaults
|
||||
file_size_->SetValue(700.0);
|
||||
}
|
||||
|
||||
int64_t H264FileSizeSection::GetFileSize() const
|
||||
{
|
||||
// Convert megabytes to BITS
|
||||
return qRound64(file_size_->GetValue() * 1024.0 * 1024.0 * 8.0);
|
||||
// Convert megabytes to BITS
|
||||
return qRound64(file_size_->GetValue() * 1024.0 * 1024.0 * 8.0);
|
||||
}
|
||||
|
||||
void H264FileSizeSection::SetFileSize(int64_t f)
|
||||
{
|
||||
// Convert bits back to megabytes
|
||||
file_size_->SetValue(double(f) / 8.0 / 1024.0 / 1024.0);
|
||||
// Convert bits back to megabytes
|
||||
file_size_->SetValue(double(f) / 8.0 / 1024.0 / 1024.0);
|
||||
}
|
||||
|
||||
H265Section::H265Section(QWidget *parent) :
|
||||
H264Section(H264CRFSection::kDefaultH265CRF, parent)
|
||||
H265Section::H265Section(QWidget *parent)
|
||||
: H264Section(H264CRFSection::kDefaultH265CRF, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -28,104 +28,97 @@
|
||||
#include "codecsection.h"
|
||||
#include "widget/slider/floatslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class H264CRFSection : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class H264CRFSection : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
H264CRFSection(int default_crf, QWidget* parent = nullptr);
|
||||
H264CRFSection(int default_crf, QWidget *parent = nullptr);
|
||||
|
||||
int GetValue() const;
|
||||
void SetValue(int c);
|
||||
int GetValue() const;
|
||||
void SetValue(int c);
|
||||
|
||||
static const int kDefaultH264CRF = 18;
|
||||
static const int kDefaultH265CRF = 23;
|
||||
static const int kDefaultH264CRF = 18;
|
||||
static const int kDefaultH265CRF = 23;
|
||||
|
||||
private:
|
||||
static const int kMinimumCRF = 0;
|
||||
static const int kMaximumCRF = 51;
|
||||
|
||||
QSlider* crf_slider_;
|
||||
static const int kMinimumCRF = 0;
|
||||
static const int kMaximumCRF = 51;
|
||||
|
||||
QSlider *crf_slider_;
|
||||
};
|
||||
|
||||
class H264BitRateSection : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
class H264BitRateSection : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
H264BitRateSection(QWidget* parent = nullptr);
|
||||
H264BitRateSection(QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Get user-selected target bit rate (returns in BITS)
|
||||
*/
|
||||
int64_t GetTargetBitRate() const;
|
||||
void SetTargetBitRate(int64_t b);
|
||||
int64_t GetTargetBitRate() const;
|
||||
void SetTargetBitRate(int64_t b);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Get user-selected maximum bit rate (returns in BITS)
|
||||
*/
|
||||
int64_t GetMaximumBitRate() const;
|
||||
void SetMaximumBitRate(int64_t b);
|
||||
int64_t GetMaximumBitRate() const;
|
||||
void SetMaximumBitRate(int64_t b);
|
||||
|
||||
private:
|
||||
FloatSlider* target_rate_;
|
||||
|
||||
FloatSlider* max_rate_;
|
||||
FloatSlider *target_rate_;
|
||||
|
||||
FloatSlider *max_rate_;
|
||||
};
|
||||
|
||||
class H264FileSizeSection : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
class H264FileSizeSection : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
H264FileSizeSection(QWidget* parent = nullptr);
|
||||
H264FileSizeSection(QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Returns file size in BITS
|
||||
*/
|
||||
int64_t GetFileSize() const;
|
||||
void SetFileSize(int64_t f);
|
||||
int64_t GetFileSize() const;
|
||||
void SetFileSize(int64_t f);
|
||||
|
||||
private:
|
||||
FloatSlider* file_size_;
|
||||
|
||||
FloatSlider *file_size_;
|
||||
};
|
||||
|
||||
class H264Section : public CodecSection
|
||||
{
|
||||
Q_OBJECT
|
||||
class H264Section : public CodecSection {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum CompressionMethod {
|
||||
kConstantRateFactor,
|
||||
kTargetBitRate,
|
||||
kTargetFileSize
|
||||
};
|
||||
enum CompressionMethod {
|
||||
kConstantRateFactor,
|
||||
kTargetBitRate,
|
||||
kTargetFileSize
|
||||
};
|
||||
|
||||
H264Section(QWidget* parent = nullptr);
|
||||
H264Section(int default_crf, QWidget* parent);
|
||||
H264Section(QWidget *parent = nullptr);
|
||||
H264Section(int default_crf, QWidget *parent);
|
||||
|
||||
virtual void AddOpts(EncodingParams* params) override;
|
||||
virtual void AddOpts(EncodingParams *params) override;
|
||||
|
||||
virtual void SetOpts(const EncodingParams *p) override;
|
||||
virtual void SetOpts(const EncodingParams *p) override;
|
||||
|
||||
private:
|
||||
QStackedWidget* compression_method_stack_;
|
||||
QStackedWidget *compression_method_stack_;
|
||||
|
||||
H264CRFSection* crf_section_;
|
||||
H264CRFSection *crf_section_;
|
||||
|
||||
H264BitRateSection* bitrate_section_;
|
||||
H264BitRateSection *bitrate_section_;
|
||||
|
||||
H264FileSizeSection* filesize_section_;
|
||||
H264FileSizeSection *filesize_section_;
|
||||
|
||||
QComboBox *preset_combobox_;
|
||||
QComboBox *preset_combobox_;
|
||||
};
|
||||
|
||||
class H265Section : public H264Section
|
||||
{
|
||||
Q_OBJECT
|
||||
class H265Section : public H264Section {
|
||||
Q_OBJECT
|
||||
public:
|
||||
H265Section(QWidget* parent = nullptr);
|
||||
H265Section(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,37 +23,40 @@
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
|
||||
namespace olive {
|
||||
|
||||
ImageSection::ImageSection(QWidget* parent) :
|
||||
CodecSection(parent)
|
||||
namespace olive
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
ImageSection::ImageSection(QWidget *parent)
|
||||
: CodecSection(parent)
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Image Sequence:")), row, 0);
|
||||
int row = 0;
|
||||
|
||||
image_sequence_checkbox_ = new QCheckBox();
|
||||
connect(image_sequence_checkbox_, &QCheckBox::toggled, this, &ImageSection::ImageSequenceCheckBoxToggled);
|
||||
layout->addWidget(image_sequence_checkbox_, row, 1);
|
||||
layout->addWidget(new QLabel(tr("Image Sequence:")), row, 0);
|
||||
|
||||
row++;
|
||||
image_sequence_checkbox_ = new QCheckBox();
|
||||
connect(image_sequence_checkbox_, &QCheckBox::toggled, this,
|
||||
&ImageSection::ImageSequenceCheckBoxToggled);
|
||||
layout->addWidget(image_sequence_checkbox_, row, 1);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Frame to Export:")), row, 0);
|
||||
row++;
|
||||
|
||||
frame_slider_ = new RationalSlider();
|
||||
frame_slider_->SetMinimum(0);
|
||||
frame_slider_->SetValue(0);
|
||||
frame_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
connect(frame_slider_, &RationalSlider::ValueChanged, this, &ImageSection::TimeChanged);
|
||||
layout->addWidget(frame_slider_, row, 1);
|
||||
layout->addWidget(new QLabel(tr("Frame to Export:")), row, 0);
|
||||
|
||||
frame_slider_ = new RationalSlider();
|
||||
frame_slider_->SetMinimum(0);
|
||||
frame_slider_->SetValue(0);
|
||||
frame_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
connect(frame_slider_, &RationalSlider::ValueChanged, this,
|
||||
&ImageSection::TimeChanged);
|
||||
layout->addWidget(frame_slider_, row, 1);
|
||||
}
|
||||
|
||||
void ImageSection::ImageSequenceCheckBoxToggled(bool e)
|
||||
{
|
||||
frame_slider_->setEnabled(!e);
|
||||
frame_slider_->setEnabled(!e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,50 +26,49 @@
|
||||
#include "codecsection.h"
|
||||
#include "widget/slider/rationalslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ImageSection : public CodecSection
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ImageSection : public CodecSection {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImageSection(QWidget* parent = nullptr);
|
||||
ImageSection(QWidget *parent = nullptr);
|
||||
|
||||
bool IsImageSequenceChecked() const
|
||||
{
|
||||
return image_sequence_checkbox_->isChecked();
|
||||
}
|
||||
bool IsImageSequenceChecked() const
|
||||
{
|
||||
return image_sequence_checkbox_->isChecked();
|
||||
}
|
||||
|
||||
void SetImageSequenceChecked(bool e)
|
||||
{
|
||||
image_sequence_checkbox_->setChecked(e);
|
||||
}
|
||||
void SetImageSequenceChecked(bool e)
|
||||
{
|
||||
image_sequence_checkbox_->setChecked(e);
|
||||
}
|
||||
|
||||
void SetTimebase(const rational& r)
|
||||
{
|
||||
frame_slider_->SetTimebase(r);
|
||||
}
|
||||
void SetTimebase(const rational &r)
|
||||
{
|
||||
frame_slider_->SetTimebase(r);
|
||||
}
|
||||
|
||||
rational GetTime() const
|
||||
{
|
||||
return frame_slider_->GetValue();
|
||||
}
|
||||
rational GetTime() const
|
||||
{
|
||||
return frame_slider_->GetValue();
|
||||
}
|
||||
|
||||
void SetTime(const rational &t)
|
||||
{
|
||||
frame_slider_->SetValue(t);
|
||||
}
|
||||
void SetTime(const rational &t)
|
||||
{
|
||||
frame_slider_->SetValue(t);
|
||||
}
|
||||
|
||||
signals:
|
||||
void TimeChanged(const rational &t);
|
||||
void TimeChanged(const rational &t);
|
||||
|
||||
private:
|
||||
QCheckBox* image_sequence_checkbox_;
|
||||
QCheckBox *image_sequence_checkbox_;
|
||||
|
||||
RationalSlider* frame_slider_;
|
||||
RationalSlider *frame_slider_;
|
||||
|
||||
private slots:
|
||||
void ImageSequenceCheckBoxToggled(bool e);
|
||||
|
||||
void ImageSequenceCheckBoxToggled(bool e);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+594
-548
File diff suppressed because it is too large
Load Diff
+60
-62
@@ -37,107 +37,105 @@
|
||||
#include "widget/nodeparamview/nodeparamviewwidgetbridge.h"
|
||||
#include "widget/viewer/viewer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ExportDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ExportDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportDialog(ViewerOutput* viewer_node, bool stills_only_mode, QWidget* parent = nullptr);
|
||||
ExportDialog(ViewerOutput* viewer_node, QWidget* parent = nullptr) :
|
||||
ExportDialog(viewer_node, false, parent)
|
||||
{}
|
||||
ExportDialog(ViewerOutput *viewer_node, bool stills_only_mode,
|
||||
QWidget *parent = nullptr);
|
||||
ExportDialog(ViewerOutput *viewer_node, QWidget *parent = nullptr)
|
||||
: ExportDialog(viewer_node, false, parent)
|
||||
{
|
||||
}
|
||||
|
||||
rational GetSelectedTimebase() const;
|
||||
void SetSelectedTimebase(const rational &r);
|
||||
rational GetSelectedTimebase() const;
|
||||
void SetSelectedTimebase(const rational &r);
|
||||
|
||||
EncodingParams GenerateParams() const;
|
||||
void SetParams(const EncodingParams &e);
|
||||
EncodingParams GenerateParams() const;
|
||||
void SetParams(const EncodingParams &e);
|
||||
|
||||
virtual bool eventFilter(QObject *o, QEvent *e) override;
|
||||
virtual bool eventFilter(QObject *o, QEvent *e) override;
|
||||
|
||||
public slots:
|
||||
virtual void done(int r) override;
|
||||
virtual void done(int r) override;
|
||||
|
||||
signals:
|
||||
void RequestImportFile(const QString &s);
|
||||
void RequestImportFile(const QString &s);
|
||||
|
||||
private:
|
||||
void AddPreferencesTab(QWidget *inner_widget, const QString &title);
|
||||
void AddPreferencesTab(QWidget *inner_widget, const QString &title);
|
||||
|
||||
void LoadPresets();
|
||||
void SetDefaultFilename();
|
||||
void LoadPresets();
|
||||
void SetDefaultFilename();
|
||||
|
||||
bool SequenceHasSubtitles() const;
|
||||
bool SequenceHasSubtitles() const;
|
||||
|
||||
void SetDefaults();
|
||||
void SetDefaults();
|
||||
|
||||
ViewerOutput* viewer_node_;
|
||||
ViewerOutput *viewer_node_;
|
||||
|
||||
ExportFormat::Format previously_selected_format_;
|
||||
ExportFormat::Format previously_selected_format_;
|
||||
|
||||
rational GetExportLength() const;
|
||||
int64_t GetExportLengthInTimebaseUnits() const;
|
||||
rational GetExportLength() const;
|
||||
int64_t GetExportLengthInTimebaseUnits() const;
|
||||
|
||||
enum RangeSelection {
|
||||
kRangeEntireSequence,
|
||||
kRangeInToOut
|
||||
};
|
||||
enum RangeSelection { kRangeEntireSequence, kRangeInToOut };
|
||||
|
||||
enum AutoPreset {
|
||||
kPresetDefault = -1,
|
||||
kPresetLastUsed = -2,
|
||||
};
|
||||
enum AutoPreset {
|
||||
kPresetDefault = -1,
|
||||
kPresetLastUsed = -2,
|
||||
};
|
||||
|
||||
QTabWidget* preferences_tabs_;
|
||||
QTabWidget *preferences_tabs_;
|
||||
|
||||
QComboBox* preset_combobox_;
|
||||
QComboBox* range_combobox_;
|
||||
std::vector<EncodingParams> presets_;
|
||||
QComboBox *preset_combobox_;
|
||||
QComboBox *range_combobox_;
|
||||
std::vector<EncodingParams> presets_;
|
||||
|
||||
QCheckBox* video_enabled_;
|
||||
QCheckBox* audio_enabled_;
|
||||
QCheckBox* subtitles_enabled_;
|
||||
QCheckBox *video_enabled_;
|
||||
QCheckBox *audio_enabled_;
|
||||
QCheckBox *subtitles_enabled_;
|
||||
|
||||
ViewerWidget* preview_viewer_;
|
||||
QLineEdit* filename_edit_;
|
||||
ExportFormatComboBox* format_combobox_;
|
||||
ViewerWidget *preview_viewer_;
|
||||
QLineEdit *filename_edit_;
|
||||
ExportFormatComboBox *format_combobox_;
|
||||
|
||||
ExportVideoTab* video_tab_;
|
||||
ExportAudioTab* audio_tab_;
|
||||
ExportSubtitlesTab* subtitle_tab_;
|
||||
ExportVideoTab *video_tab_;
|
||||
ExportAudioTab *audio_tab_;
|
||||
ExportSubtitlesTab *subtitle_tab_;
|
||||
|
||||
double video_aspect_ratio_;
|
||||
double video_aspect_ratio_;
|
||||
|
||||
ColorManager* color_manager_;
|
||||
ColorManager *color_manager_;
|
||||
|
||||
QWidget* preferences_area_;
|
||||
QCheckBox *export_bkg_box_;
|
||||
QCheckBox *import_file_after_export_;
|
||||
QWidget *preferences_area_;
|
||||
QCheckBox *export_bkg_box_;
|
||||
QCheckBox *import_file_after_export_;
|
||||
|
||||
bool stills_only_mode_;
|
||||
bool stills_only_mode_;
|
||||
|
||||
bool loading_presets_;
|
||||
bool loading_presets_;
|
||||
|
||||
private slots:
|
||||
void BrowseFilename();
|
||||
void BrowseFilename();
|
||||
|
||||
void FormatChanged(ExportFormat::Format current_format);
|
||||
void FormatChanged(ExportFormat::Format current_format);
|
||||
|
||||
void ResolutionChanged();
|
||||
void ResolutionChanged();
|
||||
|
||||
void UpdateViewerDimensions();
|
||||
void UpdateViewerDimensions();
|
||||
|
||||
void StartExport();
|
||||
void StartExport();
|
||||
|
||||
void ExportFinished();
|
||||
void ExportFinished();
|
||||
|
||||
void ImageSequenceCheckBoxChanged(bool e);
|
||||
void ImageSequenceCheckBoxChanged(bool e);
|
||||
|
||||
void SavePreset();
|
||||
|
||||
void PresetComboBoxChanged();
|
||||
void SavePreset();
|
||||
|
||||
void PresetComboBoxChanged();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -5,65 +5,71 @@
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
|
||||
namespace olive {
|
||||
|
||||
ExportAdvancedVideoDialog::ExportAdvancedVideoDialog(const QList<QString> &pix_fmts, QWidget *parent) :
|
||||
QDialog(parent)
|
||||
namespace olive
|
||||
{
|
||||
setWindowTitle(tr("Advanced"));
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
ExportAdvancedVideoDialog::ExportAdvancedVideoDialog(
|
||||
const QList<QString> &pix_fmts, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setWindowTitle(tr("Advanced"));
|
||||
|
||||
{
|
||||
// Pixel Settings
|
||||
QGroupBox* pixel_group = new QGroupBox();
|
||||
layout->addWidget(pixel_group);
|
||||
pixel_group->setTitle(tr("Pixel"));
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* pixel_layout = new QGridLayout(pixel_group);
|
||||
{
|
||||
// Pixel Settings
|
||||
QGroupBox *pixel_group = new QGroupBox();
|
||||
layout->addWidget(pixel_group);
|
||||
pixel_group->setTitle(tr("Pixel"));
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *pixel_layout = new QGridLayout(pixel_group);
|
||||
|
||||
pixel_layout->addWidget(new QLabel(tr("Pixel Format:")), row, 0);
|
||||
int row = 0;
|
||||
|
||||
pixel_format_combobox_ = new QComboBox();
|
||||
pixel_format_combobox_->addItems(pix_fmts);
|
||||
pixel_layout->addWidget(pixel_format_combobox_, row, 1);
|
||||
pixel_layout->addWidget(new QLabel(tr("Pixel Format:")), row, 0);
|
||||
|
||||
row++;
|
||||
pixel_format_combobox_ = new QComboBox();
|
||||
pixel_format_combobox_->addItems(pix_fmts);
|
||||
pixel_layout->addWidget(pixel_format_combobox_, row, 1);
|
||||
|
||||
pixel_layout->addWidget(new QLabel(tr("YUV Color Range:")), row, 0);
|
||||
row++;
|
||||
|
||||
yuv_color_range_combobox_ = new QComboBox();
|
||||
yuv_color_range_combobox_->addItems({tr("Limited (16-235)"), tr("Full (0-255)")});
|
||||
pixel_layout->addWidget(yuv_color_range_combobox_, row, 1);
|
||||
}
|
||||
pixel_layout->addWidget(new QLabel(tr("YUV Color Range:")), row, 0);
|
||||
|
||||
{
|
||||
// Performance Settings
|
||||
QGroupBox* performance_group = new QGroupBox();
|
||||
layout->addWidget(performance_group);
|
||||
performance_group->setTitle(tr("Performance"));
|
||||
yuv_color_range_combobox_ = new QComboBox();
|
||||
yuv_color_range_combobox_->addItems(
|
||||
{ tr("Limited (16-235)"), tr("Full (0-255)") });
|
||||
pixel_layout->addWidget(yuv_color_range_combobox_, row, 1);
|
||||
}
|
||||
|
||||
QGridLayout* performance_layout = new QGridLayout(performance_group);
|
||||
{
|
||||
// Performance Settings
|
||||
QGroupBox *performance_group = new QGroupBox();
|
||||
layout->addWidget(performance_group);
|
||||
performance_group->setTitle(tr("Performance"));
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *performance_layout = new QGridLayout(performance_group);
|
||||
|
||||
performance_layout->addWidget(new QLabel(tr("Threads:")), row, 0);
|
||||
int row = 0;
|
||||
|
||||
thread_slider_ = new IntegerSlider();
|
||||
thread_slider_->SetMinimum(0);
|
||||
thread_slider_->SetDefaultValue(0);
|
||||
thread_slider_->InsertLabelSubstitution(0, tr("Auto"));
|
||||
performance_layout->addWidget(thread_slider_, row, 1);
|
||||
performance_layout->addWidget(new QLabel(tr("Threads:")), row, 0);
|
||||
|
||||
row++;
|
||||
}
|
||||
thread_slider_ = new IntegerSlider();
|
||||
thread_slider_->SetMinimum(0);
|
||||
thread_slider_->SetDefaultValue(0);
|
||||
thread_slider_->InsertLabelSubstitution(0, tr("Auto"));
|
||||
performance_layout->addWidget(thread_slider_, row, 1);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &ExportAdvancedVideoDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &ExportAdvancedVideoDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
row++;
|
||||
}
|
||||
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this,
|
||||
&ExportAdvancedVideoDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this,
|
||||
&ExportAdvancedVideoDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,52 +7,52 @@
|
||||
#include "codec/encoder.h"
|
||||
#include "widget/slider/integerslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ExportAdvancedVideoDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ExportAdvancedVideoDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportAdvancedVideoDialog(const QList<QString>& pix_fmts,
|
||||
QWidget* parent = nullptr);
|
||||
ExportAdvancedVideoDialog(const QList<QString> &pix_fmts,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
int threads() const
|
||||
{
|
||||
return static_cast<int>(thread_slider_->GetValue());
|
||||
}
|
||||
int threads() const
|
||||
{
|
||||
return static_cast<int>(thread_slider_->GetValue());
|
||||
}
|
||||
|
||||
void set_threads(int t)
|
||||
{
|
||||
thread_slider_->SetValue(t);
|
||||
}
|
||||
void set_threads(int t)
|
||||
{
|
||||
thread_slider_->SetValue(t);
|
||||
}
|
||||
|
||||
QString pix_fmt() const
|
||||
{
|
||||
return pixel_format_combobox_->currentText();
|
||||
}
|
||||
QString pix_fmt() const
|
||||
{
|
||||
return pixel_format_combobox_->currentText();
|
||||
}
|
||||
|
||||
void set_pix_fmt(const QString& s)
|
||||
{
|
||||
pixel_format_combobox_->setCurrentText(s);
|
||||
}
|
||||
void set_pix_fmt(const QString &s)
|
||||
{
|
||||
pixel_format_combobox_->setCurrentText(s);
|
||||
}
|
||||
|
||||
VideoParams::ColorRange yuv_range() const
|
||||
{
|
||||
return static_cast<VideoParams::ColorRange>(yuv_color_range_combobox_->currentIndex());
|
||||
}
|
||||
VideoParams::ColorRange yuv_range() const
|
||||
{
|
||||
return static_cast<VideoParams::ColorRange>(
|
||||
yuv_color_range_combobox_->currentIndex());
|
||||
}
|
||||
|
||||
void set_yuv_range(VideoParams::ColorRange i)
|
||||
{
|
||||
yuv_color_range_combobox_->setCurrentIndex(i);
|
||||
}
|
||||
void set_yuv_range(VideoParams::ColorRange i)
|
||||
{
|
||||
yuv_color_range_combobox_->setCurrentIndex(i);
|
||||
}
|
||||
|
||||
private:
|
||||
IntegerSlider* thread_slider_;
|
||||
IntegerSlider *thread_slider_;
|
||||
|
||||
QComboBox* pixel_format_combobox_;
|
||||
|
||||
QComboBox* yuv_color_range_combobox_;
|
||||
QComboBox *pixel_format_combobox_;
|
||||
|
||||
QComboBox *yuv_color_range_combobox_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,96 +25,103 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
const int ExportAudioTab::kDefaultBitRate = 320;
|
||||
|
||||
ExportAudioTab::ExportAudioTab(QWidget* parent) :
|
||||
QWidget(parent)
|
||||
ExportAudioTab::ExportAudioTab(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QVBoxLayout* outer_layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *outer_layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* layout = new QGridLayout();
|
||||
outer_layout->addLayout(layout);
|
||||
QGridLayout *layout = new QGridLayout();
|
||||
outer_layout->addLayout(layout);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Codec:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Codec:")), row, 0);
|
||||
|
||||
codec_combobox_ = new QComboBox();
|
||||
connect(codec_combobox_, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ExportAudioTab::UpdateSampleFormats);
|
||||
connect(codec_combobox_, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ExportAudioTab::UpdateBitRateEnabled);
|
||||
layout->addWidget(codec_combobox_, row, 1);
|
||||
codec_combobox_ = new QComboBox();
|
||||
connect(
|
||||
codec_combobox_,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &ExportAudioTab::UpdateSampleFormats);
|
||||
connect(
|
||||
codec_combobox_,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &ExportAudioTab::UpdateBitRateEnabled);
|
||||
layout->addWidget(codec_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Sample Rate:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Sample Rate:")), row, 0);
|
||||
|
||||
sample_rate_combobox_ = new SampleRateComboBox();
|
||||
layout->addWidget(sample_rate_combobox_, row, 1);
|
||||
sample_rate_combobox_ = new SampleRateComboBox();
|
||||
layout->addWidget(sample_rate_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Channel Layout:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Channel Layout:")), row, 0);
|
||||
|
||||
channel_layout_combobox_ = new ChannelLayoutComboBox();
|
||||
layout->addWidget(channel_layout_combobox_, row, 1);
|
||||
channel_layout_combobox_ = new ChannelLayoutComboBox();
|
||||
layout->addWidget(channel_layout_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Format:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Format:")), row, 0);
|
||||
|
||||
sample_format_combobox_ = new SampleFormatComboBox();
|
||||
layout->addWidget(sample_format_combobox_, row, 1);
|
||||
sample_format_combobox_ = new SampleFormatComboBox();
|
||||
layout->addWidget(sample_format_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Bit Rate:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Bit Rate:")), row, 0);
|
||||
|
||||
bit_rate_slider_ = new IntegerSlider();
|
||||
bit_rate_slider_->SetMinimum(32);
|
||||
bit_rate_slider_->SetMaximum(320);
|
||||
bit_rate_slider_->SetValue(kDefaultBitRate);
|
||||
bit_rate_slider_->SetFormat(tr("%1 kbps"));
|
||||
layout->addWidget(bit_rate_slider_, row, 1);
|
||||
bit_rate_slider_ = new IntegerSlider();
|
||||
bit_rate_slider_->SetMinimum(32);
|
||||
bit_rate_slider_->SetMaximum(320);
|
||||
bit_rate_slider_->SetValue(kDefaultBitRate);
|
||||
bit_rate_slider_->SetFormat(tr("%1 kbps"));
|
||||
layout->addWidget(bit_rate_slider_, row, 1);
|
||||
|
||||
outer_layout->addStretch();
|
||||
outer_layout->addStretch();
|
||||
}
|
||||
|
||||
int ExportAudioTab::SetFormat(ExportFormat::Format format)
|
||||
{
|
||||
QList<ExportCodec::Codec> acodecs = ExportFormat::GetAudioCodecs(format);
|
||||
setEnabled(!acodecs.isEmpty());
|
||||
codec_combobox_->blockSignals(true);
|
||||
codec_combobox_->clear();
|
||||
foreach (ExportCodec::Codec acodec, acodecs) {
|
||||
codec_combobox_->addItem(ExportCodec::GetCodecName(acodec), acodec);
|
||||
}
|
||||
codec_combobox_->blockSignals(false);
|
||||
fmt_ = format;
|
||||
QList<ExportCodec::Codec> acodecs = ExportFormat::GetAudioCodecs(format);
|
||||
setEnabled(!acodecs.isEmpty());
|
||||
codec_combobox_->blockSignals(true);
|
||||
codec_combobox_->clear();
|
||||
foreach (ExportCodec::Codec acodec, acodecs) {
|
||||
codec_combobox_->addItem(ExportCodec::GetCodecName(acodec), acodec);
|
||||
}
|
||||
codec_combobox_->blockSignals(false);
|
||||
fmt_ = format;
|
||||
|
||||
UpdateSampleFormats();
|
||||
UpdateBitRateEnabled();
|
||||
UpdateSampleFormats();
|
||||
UpdateBitRateEnabled();
|
||||
|
||||
return acodecs.size();
|
||||
return acodecs.size();
|
||||
}
|
||||
|
||||
void ExportAudioTab::UpdateSampleFormats()
|
||||
{
|
||||
auto fmts = ExportFormat::GetSampleFormatsForCodec(fmt_, GetCodec());
|
||||
sample_format_combobox_->SetAvailableFormats(fmts);
|
||||
auto fmts = ExportFormat::GetSampleFormatsForCodec(fmt_, GetCodec());
|
||||
sample_format_combobox_->SetAvailableFormats(fmts);
|
||||
}
|
||||
|
||||
void ExportAudioTab::UpdateBitRateEnabled()
|
||||
{
|
||||
bool uses_bitrate = !ExportCodec::IsCodecLossless(GetCodec());
|
||||
bit_rate_slider_->setEnabled(uses_bitrate);
|
||||
bool uses_bitrate = !ExportCodec::IsCodecLossless(GetCodec());
|
||||
bit_rate_slider_->setEnabled(uses_bitrate);
|
||||
|
||||
if (!uses_bitrate) {
|
||||
bit_rate_slider_->SetTristate();
|
||||
} else {
|
||||
bit_rate_slider_->SetValue(kDefaultBitRate );
|
||||
}
|
||||
if (!uses_bitrate) {
|
||||
bit_rate_slider_->SetTristate();
|
||||
} else {
|
||||
bit_rate_slider_->SetValue(kDefaultBitRate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,67 +29,67 @@
|
||||
#include "widget/slider/integerslider.h"
|
||||
#include "widget/standardcombos/standardcombos.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ExportAudioTab : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ExportAudioTab : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportAudioTab(QWidget* parent = nullptr);
|
||||
ExportAudioTab(QWidget *parent = nullptr);
|
||||
|
||||
ExportCodec::Codec GetCodec() const
|
||||
{
|
||||
return static_cast<ExportCodec::Codec>(codec_combobox_->currentData().toInt());
|
||||
}
|
||||
ExportCodec::Codec GetCodec() const
|
||||
{
|
||||
return static_cast<ExportCodec::Codec>(
|
||||
codec_combobox_->currentData().toInt());
|
||||
}
|
||||
|
||||
void SetCodec(ExportCodec::Codec c)
|
||||
{
|
||||
for (int i=0; i<codec_combobox_->count(); i++) {
|
||||
if (codec_combobox_->itemData(i) == c) {
|
||||
codec_combobox_->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void SetCodec(ExportCodec::Codec c)
|
||||
{
|
||||
for (int i = 0; i < codec_combobox_->count(); i++) {
|
||||
if (codec_combobox_->itemData(i) == c) {
|
||||
codec_combobox_->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SampleRateComboBox* sample_rate_combobox() const
|
||||
{
|
||||
return sample_rate_combobox_;
|
||||
}
|
||||
SampleRateComboBox *sample_rate_combobox() const
|
||||
{
|
||||
return sample_rate_combobox_;
|
||||
}
|
||||
|
||||
SampleFormatComboBox* sample_format_combobox() const
|
||||
{
|
||||
return sample_format_combobox_;
|
||||
}
|
||||
SampleFormatComboBox *sample_format_combobox() const
|
||||
{
|
||||
return sample_format_combobox_;
|
||||
}
|
||||
|
||||
ChannelLayoutComboBox* channel_layout_combobox() const
|
||||
{
|
||||
return channel_layout_combobox_;
|
||||
}
|
||||
ChannelLayoutComboBox *channel_layout_combobox() const
|
||||
{
|
||||
return channel_layout_combobox_;
|
||||
}
|
||||
|
||||
IntegerSlider* bit_rate_slider() const
|
||||
{
|
||||
return bit_rate_slider_;
|
||||
}
|
||||
IntegerSlider *bit_rate_slider() const
|
||||
{
|
||||
return bit_rate_slider_;
|
||||
}
|
||||
|
||||
public slots:
|
||||
int SetFormat(ExportFormat::Format format);
|
||||
int SetFormat(ExportFormat::Format format);
|
||||
|
||||
private:
|
||||
ExportFormat::Format fmt_;
|
||||
QComboBox* codec_combobox_;
|
||||
SampleRateComboBox* sample_rate_combobox_;
|
||||
ChannelLayoutComboBox* channel_layout_combobox_;
|
||||
SampleFormatComboBox *sample_format_combobox_;
|
||||
IntegerSlider* bit_rate_slider_;
|
||||
ExportFormat::Format fmt_;
|
||||
QComboBox *codec_combobox_;
|
||||
SampleRateComboBox *sample_rate_combobox_;
|
||||
ChannelLayoutComboBox *channel_layout_combobox_;
|
||||
SampleFormatComboBox *sample_format_combobox_;
|
||||
IntegerSlider *bit_rate_slider_;
|
||||
|
||||
static const int kDefaultBitRate;
|
||||
static const int kDefaultBitRate;
|
||||
|
||||
private slots:
|
||||
void UpdateSampleFormats();
|
||||
|
||||
void UpdateBitRateEnabled();
|
||||
void UpdateSampleFormats();
|
||||
|
||||
void UpdateBitRateEnabled();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,115 +25,119 @@
|
||||
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
ExportFormatComboBox::ExportFormatComboBox(Mode mode, QWidget *parent) :
|
||||
QComboBox(parent)
|
||||
namespace olive
|
||||
{
|
||||
custom_menu_ = new Menu(this);
|
||||
|
||||
// Populate combobox formats
|
||||
switch (mode) {
|
||||
case kShowAllFormats:
|
||||
custom_menu_->addAction(CreateHeader(icon::Video, tr("Video")));
|
||||
PopulateType(Track::kVideo);
|
||||
custom_menu_->addSeparator();
|
||||
ExportFormatComboBox::ExportFormatComboBox(Mode mode, QWidget *parent)
|
||||
: QComboBox(parent)
|
||||
{
|
||||
custom_menu_ = new Menu(this);
|
||||
|
||||
custom_menu_->addAction(CreateHeader(icon::Audio, tr("Audio")));
|
||||
PopulateType(Track::kAudio);
|
||||
custom_menu_->addSeparator();
|
||||
// Populate combobox formats
|
||||
switch (mode) {
|
||||
case kShowAllFormats:
|
||||
custom_menu_->addAction(CreateHeader(icon::Video, tr("Video")));
|
||||
PopulateType(Track::kVideo);
|
||||
custom_menu_->addSeparator();
|
||||
|
||||
custom_menu_->addAction(CreateHeader(icon::Subtitles, tr("Subtitle")));
|
||||
PopulateType(Track::kSubtitle);
|
||||
break;
|
||||
case kShowAudioOnly:
|
||||
PopulateType(Track::kAudio);
|
||||
break;
|
||||
case kShowVideoOnly:
|
||||
PopulateType(Track::kVideo);
|
||||
break;
|
||||
case kShowSubtitlesOnly:
|
||||
PopulateType(Track::kSubtitle);
|
||||
break;
|
||||
}
|
||||
custom_menu_->addAction(CreateHeader(icon::Audio, tr("Audio")));
|
||||
PopulateType(Track::kAudio);
|
||||
custom_menu_->addSeparator();
|
||||
|
||||
connect(custom_menu_, &Menu::triggered, this, &ExportFormatComboBox::HandleIndexChange);
|
||||
custom_menu_->addAction(CreateHeader(icon::Subtitles, tr("Subtitle")));
|
||||
PopulateType(Track::kSubtitle);
|
||||
break;
|
||||
case kShowAudioOnly:
|
||||
PopulateType(Track::kAudio);
|
||||
break;
|
||||
case kShowVideoOnly:
|
||||
PopulateType(Track::kVideo);
|
||||
break;
|
||||
case kShowSubtitlesOnly:
|
||||
PopulateType(Track::kSubtitle);
|
||||
break;
|
||||
}
|
||||
|
||||
connect(custom_menu_, &Menu::triggered, this,
|
||||
&ExportFormatComboBox::HandleIndexChange);
|
||||
}
|
||||
|
||||
void ExportFormatComboBox::showPopup()
|
||||
{
|
||||
custom_menu_->setMinimumWidth(this->width());
|
||||
custom_menu_->exec(mapToGlobal(QPoint(0, 0)));
|
||||
custom_menu_->setMinimumWidth(this->width());
|
||||
custom_menu_->exec(mapToGlobal(QPoint(0, 0)));
|
||||
}
|
||||
|
||||
void ExportFormatComboBox::SetFormat(ExportFormat::Format fmt)
|
||||
{
|
||||
current_ = fmt;
|
||||
clear();
|
||||
addItem(ExportFormat::GetName(current_));
|
||||
current_ = fmt;
|
||||
clear();
|
||||
addItem(ExportFormat::GetName(current_));
|
||||
}
|
||||
|
||||
void ExportFormatComboBox::HandleIndexChange(QAction *a)
|
||||
{
|
||||
ExportFormat::Format f = static_cast<ExportFormat::Format>(a->data().toInt());
|
||||
SetFormat(f);
|
||||
emit FormatChanged(f);
|
||||
ExportFormat::Format f =
|
||||
static_cast<ExportFormat::Format>(a->data().toInt());
|
||||
SetFormat(f);
|
||||
emit FormatChanged(f);
|
||||
}
|
||||
|
||||
void ExportFormatComboBox::PopulateType(Track::Type type)
|
||||
{
|
||||
for (int i=0; i<ExportFormat::kFormatCount; i++) {
|
||||
ExportFormat::Format f = static_cast<ExportFormat::Format>(i);
|
||||
for (int i = 0; i < ExportFormat::kFormatCount; i++) {
|
||||
ExportFormat::Format f = static_cast<ExportFormat::Format>(i);
|
||||
|
||||
if (type == Track::kVideo
|
||||
&& !ExportFormat::GetVideoCodecs(f).isEmpty()) {
|
||||
// Do nothing
|
||||
} else if (type == Track::kAudio
|
||||
&& ExportFormat::GetVideoCodecs(f).isEmpty()
|
||||
&& !ExportFormat::GetAudioCodecs(f).isEmpty()) {
|
||||
// Do nothing
|
||||
} else if (type == Track::kSubtitle
|
||||
&& ExportFormat::GetVideoCodecs(f).isEmpty()
|
||||
&& ExportFormat::GetAudioCodecs(f).isEmpty()
|
||||
&& !ExportFormat::GetSubtitleCodecs(f).isEmpty()) {
|
||||
// Do nothing
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if (type == Track::kVideo &&
|
||||
!ExportFormat::GetVideoCodecs(f).isEmpty()) {
|
||||
// Do nothing
|
||||
} else if (type == Track::kAudio &&
|
||||
ExportFormat::GetVideoCodecs(f).isEmpty() &&
|
||||
!ExportFormat::GetAudioCodecs(f).isEmpty()) {
|
||||
// Do nothing
|
||||
} else if (type == Track::kSubtitle &&
|
||||
ExportFormat::GetVideoCodecs(f).isEmpty() &&
|
||||
ExportFormat::GetAudioCodecs(f).isEmpty() &&
|
||||
!ExportFormat::GetSubtitleCodecs(f).isEmpty()) {
|
||||
// Do nothing
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString format_name = ExportFormat::GetName(f);
|
||||
QString format_name = ExportFormat::GetName(f);
|
||||
|
||||
QAction *a = custom_menu_->addAction(format_name);
|
||||
a->setData(i);
|
||||
a->setIconVisibleInMenu(false);
|
||||
}
|
||||
QAction *a = custom_menu_->addAction(format_name);
|
||||
a->setData(i);
|
||||
a->setIconVisibleInMenu(false);
|
||||
}
|
||||
}
|
||||
|
||||
QWidgetAction *ExportFormatComboBox::CreateHeader(const QIcon &icon, const QString &title)
|
||||
QWidgetAction *ExportFormatComboBox::CreateHeader(const QIcon &icon,
|
||||
const QString &title)
|
||||
{
|
||||
QWidgetAction *a = new QWidgetAction(this);
|
||||
QWidgetAction *a = new QWidgetAction(this);
|
||||
|
||||
QWidget *w = new QWidget();
|
||||
QHBoxLayout *layout = new QHBoxLayout(w);
|
||||
QWidget *w = new QWidget();
|
||||
QHBoxLayout *layout = new QHBoxLayout(w);
|
||||
|
||||
QLabel *icon_lbl = new QLabel();
|
||||
QLabel *icon_lbl = new QLabel();
|
||||
|
||||
QLabel *text_lbl = new QLabel(title);
|
||||
text_lbl->setAlignment(Qt::AlignCenter);
|
||||
QFont f = text_lbl->font();
|
||||
f.setWeight(QFont::Bold);
|
||||
text_lbl->setFont(f);
|
||||
QLabel *text_lbl = new QLabel(title);
|
||||
text_lbl->setAlignment(Qt::AlignCenter);
|
||||
QFont f = text_lbl->font();
|
||||
f.setWeight(QFont::Bold);
|
||||
text_lbl->setFont(f);
|
||||
|
||||
icon_lbl->setPixmap(icon.pixmap(text_lbl->sizeHint()));
|
||||
icon_lbl->setPixmap(icon.pixmap(text_lbl->sizeHint()));
|
||||
|
||||
layout->addStretch();
|
||||
layout->addWidget(icon_lbl);
|
||||
layout->addWidget(text_lbl);
|
||||
layout->addStretch();
|
||||
layout->addStretch();
|
||||
layout->addWidget(icon_lbl);
|
||||
layout->addWidget(text_lbl);
|
||||
layout->addStretch();
|
||||
|
||||
a->setDefaultWidget(w);
|
||||
a->setEnabled(false);
|
||||
return a;
|
||||
a->setDefaultWidget(w);
|
||||
a->setEnabled(false);
|
||||
return a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,49 +28,49 @@
|
||||
#include "node/output/track/track.h"
|
||||
#include "widget/menu/menu.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ExportFormatComboBox : public QComboBox
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ExportFormatComboBox : public QComboBox {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Mode {
|
||||
kShowAllFormats,
|
||||
kShowAudioOnly,
|
||||
kShowVideoOnly,
|
||||
kShowSubtitlesOnly
|
||||
};
|
||||
enum Mode {
|
||||
kShowAllFormats,
|
||||
kShowAudioOnly,
|
||||
kShowVideoOnly,
|
||||
kShowSubtitlesOnly
|
||||
};
|
||||
|
||||
ExportFormatComboBox(Mode mode, QWidget *parent = nullptr);
|
||||
ExportFormatComboBox(QWidget *parent = nullptr) :
|
||||
ExportFormatComboBox(kShowAllFormats, parent)
|
||||
{}
|
||||
ExportFormatComboBox(Mode mode, QWidget *parent = nullptr);
|
||||
ExportFormatComboBox(QWidget *parent = nullptr)
|
||||
: ExportFormatComboBox(kShowAllFormats, parent)
|
||||
{
|
||||
}
|
||||
|
||||
ExportFormat::Format GetFormat() const
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
ExportFormat::Format GetFormat() const
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
|
||||
void showPopup();
|
||||
void showPopup();
|
||||
|
||||
signals:
|
||||
void FormatChanged(ExportFormat::Format fmt);
|
||||
void FormatChanged(ExportFormat::Format fmt);
|
||||
|
||||
public slots:
|
||||
void SetFormat(ExportFormat::Format fmt);
|
||||
void SetFormat(ExportFormat::Format fmt);
|
||||
|
||||
private slots:
|
||||
void HandleIndexChange(QAction *a);
|
||||
void HandleIndexChange(QAction *a);
|
||||
|
||||
private:
|
||||
void PopulateType(Track::Type type);
|
||||
void PopulateType(Track::Type type);
|
||||
|
||||
QWidgetAction *CreateHeader(const QIcon &icon, const QString &title);
|
||||
QWidgetAction *CreateHeader(const QIcon &icon, const QString &title);
|
||||
|
||||
Menu *custom_menu_;
|
||||
|
||||
ExportFormat::Format current_;
|
||||
Menu *custom_menu_;
|
||||
|
||||
ExportFormat::Format current_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,73 +25,86 @@
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace olive {
|
||||
|
||||
ExportSavePresetDialog::ExportSavePresetDialog(const EncodingParams &p, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
params_(p)
|
||||
namespace olive
|
||||
{
|
||||
auto layout = new QVBoxLayout(this);
|
||||
|
||||
name_edit_ = new QLineEdit();
|
||||
ExportSavePresetDialog::ExportSavePresetDialog(const EncodingParams &p,
|
||||
QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, params_(p)
|
||||
{
|
||||
auto layout = new QVBoxLayout(this);
|
||||
|
||||
// Populate existing list
|
||||
QStringList l = EncodingParams::GetListOfPresets();
|
||||
if (!l.empty()) {
|
||||
auto list_widget_ = new QListWidget();
|
||||
for (const QString &f : l) {
|
||||
list_widget_->addItem(f);
|
||||
}
|
||||
connect(list_widget_, &QListWidget::currentTextChanged, name_edit_, &QLineEdit::setText);
|
||||
layout->addWidget(list_widget_);
|
||||
}
|
||||
name_edit_ = new QLineEdit();
|
||||
|
||||
auto name_layout = new QHBoxLayout();
|
||||
layout->addLayout(name_layout);
|
||||
// Populate existing list
|
||||
QStringList l = EncodingParams::GetListOfPresets();
|
||||
if (!l.empty()) {
|
||||
auto list_widget_ = new QListWidget();
|
||||
for (const QString &f : l) {
|
||||
list_widget_->addItem(f);
|
||||
}
|
||||
connect(list_widget_, &QListWidget::currentTextChanged, name_edit_,
|
||||
&QLineEdit::setText);
|
||||
layout->addWidget(list_widget_);
|
||||
}
|
||||
|
||||
name_layout->addWidget(new QLabel(tr("Name:")));
|
||||
auto name_layout = new QHBoxLayout();
|
||||
layout->addLayout(name_layout);
|
||||
|
||||
name_edit_->setFocus();
|
||||
name_layout->addWidget(name_edit_);
|
||||
name_layout->addWidget(new QLabel(tr("Name:")));
|
||||
|
||||
auto btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(btns, &QDialogButtonBox::accepted, this, &ExportSavePresetDialog::accept);
|
||||
connect(btns, &QDialogButtonBox::rejected, this, &ExportSavePresetDialog::reject);
|
||||
layout->addWidget(btns);
|
||||
name_edit_->setFocus();
|
||||
name_layout->addWidget(name_edit_);
|
||||
|
||||
setWindowTitle(tr("Save Export Preset"));
|
||||
auto btns =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(btns, &QDialogButtonBox::accepted, this,
|
||||
&ExportSavePresetDialog::accept);
|
||||
connect(btns, &QDialogButtonBox::rejected, this,
|
||||
&ExportSavePresetDialog::reject);
|
||||
layout->addWidget(btns);
|
||||
|
||||
setWindowTitle(tr("Save Export Preset"));
|
||||
}
|
||||
|
||||
void ExportSavePresetDialog::accept()
|
||||
{
|
||||
if (name_edit_->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Invalid Name"), tr("You must enter a name to save an export preset."));
|
||||
return;
|
||||
}
|
||||
if (name_edit_->text().isEmpty()) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Invalid Name"),
|
||||
tr("You must enter a name to save an export preset."));
|
||||
return;
|
||||
}
|
||||
|
||||
QDir d(EncodingParams::GetPresetPath());
|
||||
if (!d.exists()) {
|
||||
d.mkpath(QStringLiteral("."));
|
||||
}
|
||||
QDir d(EncodingParams::GetPresetPath());
|
||||
if (!d.exists()) {
|
||||
d.mkpath(QStringLiteral("."));
|
||||
}
|
||||
|
||||
QFile f(d.filePath(name_edit_->text()));
|
||||
if (f.exists()) {
|
||||
if (QMessageBox::question(this, tr("Overwrite Preset"), tr("A preset with the name \"%1\" already exists. Do you wish to overwrite it?").arg(name_edit_->text()),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
QFile f(d.filePath(name_edit_->text()));
|
||||
if (f.exists()) {
|
||||
if (QMessageBox::question(
|
||||
this, tr("Overwrite Preset"),
|
||||
tr("A preset with the name \"%1\" already exists. Do you wish to overwrite it?")
|
||||
.arg(name_edit_->text()),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!f.open(QFile::WriteOnly)) {
|
||||
QMessageBox::critical(this, tr("Write Error"), tr("Failed to open file \"%1\" for writing.").arg(f.fileName()));
|
||||
return;
|
||||
}
|
||||
if (!f.open(QFile::WriteOnly)) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Write Error"),
|
||||
tr("Failed to open file \"%1\" for writing.").arg(f.fileName()));
|
||||
return;
|
||||
}
|
||||
|
||||
params_.Save(&f);
|
||||
params_.Save(&f);
|
||||
|
||||
f.close();
|
||||
f.close();
|
||||
|
||||
QDialog::accept();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,27 +27,26 @@
|
||||
|
||||
#include "codec/encoder.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ExportSavePresetDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportSavePresetDialog(const EncodingParams &p, QWidget *parent = nullptr);
|
||||
|
||||
QString GetSelectedPresetName() const
|
||||
{
|
||||
return name_edit_->text();
|
||||
}
|
||||
class ExportSavePresetDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportSavePresetDialog(const EncodingParams &p, QWidget *parent = nullptr);
|
||||
|
||||
QString GetSelectedPresetName() const
|
||||
{
|
||||
return name_edit_->text();
|
||||
}
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
QLineEdit *name_edit_;
|
||||
|
||||
EncodingParams params_;
|
||||
QLineEdit *name_edit_;
|
||||
|
||||
EncodingParams params_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -2,69 +2,74 @@
|
||||
|
||||
#include <QGridLayout>
|
||||
|
||||
namespace olive {
|
||||
|
||||
ExportSubtitlesTab::ExportSubtitlesTab(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* outer_layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* layout = new QGridLayout();
|
||||
outer_layout->addLayout(layout);
|
||||
ExportSubtitlesTab::ExportSubtitlesTab(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QVBoxLayout *outer_layout = new QVBoxLayout(this);
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *layout = new QGridLayout();
|
||||
outer_layout->addLayout(layout);
|
||||
|
||||
sidecar_checkbox_ = new QCheckBox(tr("Export to sidecar file"));
|
||||
layout->addWidget(sidecar_checkbox_, row, 0, 1, 2);
|
||||
int row = 0;
|
||||
|
||||
row++;
|
||||
sidecar_checkbox_ = new QCheckBox(tr("Export to sidecar file"));
|
||||
layout->addWidget(sidecar_checkbox_, row, 0, 1, 2);
|
||||
|
||||
sidecar_format_label_ = new QLabel(tr("Sidecar Format:"));
|
||||
sidecar_format_label_->setVisible(false);
|
||||
layout->addWidget(sidecar_format_label_, row, 0);
|
||||
row++;
|
||||
|
||||
sidecar_format_combobox_ = new ExportFormatComboBox(ExportFormatComboBox::kShowSubtitlesOnly);
|
||||
sidecar_format_combobox_->setVisible(true);
|
||||
layout->addWidget(sidecar_format_combobox_, row, 1);
|
||||
sidecar_format_label_ = new QLabel(tr("Sidecar Format:"));
|
||||
sidecar_format_label_->setVisible(false);
|
||||
layout->addWidget(sidecar_format_label_, row, 0);
|
||||
|
||||
row++;
|
||||
sidecar_format_combobox_ =
|
||||
new ExportFormatComboBox(ExportFormatComboBox::kShowSubtitlesOnly);
|
||||
sidecar_format_combobox_->setVisible(true);
|
||||
layout->addWidget(sidecar_format_combobox_, row, 1);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Codec:")), row, 0);
|
||||
row++;
|
||||
|
||||
codec_combobox_ = new QComboBox();
|
||||
layout->addWidget(codec_combobox_, row, 1);
|
||||
layout->addWidget(new QLabel(tr("Codec:")), row, 0);
|
||||
|
||||
outer_layout->addStretch();
|
||||
codec_combobox_ = new QComboBox();
|
||||
layout->addWidget(codec_combobox_, row, 1);
|
||||
|
||||
connect(sidecar_checkbox_, &QCheckBox::toggled, sidecar_format_label_, &QWidget::setVisible);
|
||||
connect(sidecar_checkbox_, &QCheckBox::toggled, sidecar_format_combobox_, &QWidget::setVisible);
|
||||
outer_layout->addStretch();
|
||||
|
||||
connect(sidecar_checkbox_, &QCheckBox::toggled, sidecar_format_label_,
|
||||
&QWidget::setVisible);
|
||||
connect(sidecar_checkbox_, &QCheckBox::toggled, sidecar_format_combobox_,
|
||||
&QWidget::setVisible);
|
||||
}
|
||||
|
||||
int ExportSubtitlesTab::SetFormat(ExportFormat::Format format)
|
||||
{
|
||||
auto vcodecs = ExportFormat::GetVideoCodecs(format);
|
||||
auto acodecs = ExportFormat::GetAudioCodecs(format);
|
||||
auto vcodecs = ExportFormat::GetVideoCodecs(format);
|
||||
auto acodecs = ExportFormat::GetAudioCodecs(format);
|
||||
|
||||
auto scodecs = ExportFormat::GetSubtitleCodecs(format);
|
||||
auto scodecs = ExportFormat::GetSubtitleCodecs(format);
|
||||
|
||||
if (!scodecs.empty() && vcodecs.empty() && acodecs.empty()) {
|
||||
// If format supports ONLY scodecs, default this to off and disable it
|
||||
sidecar_checkbox_->setChecked(false);
|
||||
sidecar_checkbox_->setEnabled(false);
|
||||
} else {
|
||||
// If format does not support scodecs, default this to checked and disable it
|
||||
sidecar_checkbox_->setChecked(scodecs.empty());
|
||||
sidecar_checkbox_->setEnabled(!scodecs.empty());
|
||||
}
|
||||
if (!scodecs.empty() && vcodecs.empty() && acodecs.empty()) {
|
||||
// If format supports ONLY scodecs, default this to off and disable it
|
||||
sidecar_checkbox_->setChecked(false);
|
||||
sidecar_checkbox_->setEnabled(false);
|
||||
} else {
|
||||
// If format does not support scodecs, default this to checked and disable it
|
||||
sidecar_checkbox_->setChecked(scodecs.empty());
|
||||
sidecar_checkbox_->setEnabled(!scodecs.empty());
|
||||
}
|
||||
|
||||
scodecs = ExportFormat::GetSubtitleCodecs(sidecar_format_combobox_->GetFormat());
|
||||
scodecs =
|
||||
ExportFormat::GetSubtitleCodecs(sidecar_format_combobox_->GetFormat());
|
||||
|
||||
codec_combobox_->clear();
|
||||
foreach (ExportCodec::Codec scodec, scodecs) {
|
||||
codec_combobox_->addItem(ExportCodec::GetCodecName(scodec), scodec);
|
||||
}
|
||||
codec_combobox_->clear();
|
||||
foreach (ExportCodec::Codec scodec, scodecs) {
|
||||
codec_combobox_->addItem(ExportCodec::GetCodecName(scodec), scodec);
|
||||
}
|
||||
|
||||
return scodecs.size();
|
||||
return scodecs.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,40 +29,52 @@
|
||||
#include "common/qtutils.h"
|
||||
#include "dialog/export/exportformatcombobox.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ExportSubtitlesTab : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ExportSubtitlesTab : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportSubtitlesTab(QWidget *parent = nullptr);
|
||||
ExportSubtitlesTab(QWidget *parent = nullptr);
|
||||
|
||||
bool GetSidecarEnabled() const { return sidecar_checkbox_->isChecked(); }
|
||||
void SetSidecarEnabled(bool e) { sidecar_checkbox_->setEnabled(e); }
|
||||
bool GetSidecarEnabled() const
|
||||
{
|
||||
return sidecar_checkbox_->isChecked();
|
||||
}
|
||||
void SetSidecarEnabled(bool e)
|
||||
{
|
||||
sidecar_checkbox_->setEnabled(e);
|
||||
}
|
||||
|
||||
ExportFormat::Format GetSidecarFormat() const { return sidecar_format_combobox_->GetFormat(); }
|
||||
void SetSidecarFormat(ExportFormat::Format f) { sidecar_format_combobox_->SetFormat(f); }
|
||||
ExportFormat::Format GetSidecarFormat() const
|
||||
{
|
||||
return sidecar_format_combobox_->GetFormat();
|
||||
}
|
||||
void SetSidecarFormat(ExportFormat::Format f)
|
||||
{
|
||||
sidecar_format_combobox_->SetFormat(f);
|
||||
}
|
||||
|
||||
int SetFormat(ExportFormat::Format format);
|
||||
int SetFormat(ExportFormat::Format format);
|
||||
|
||||
ExportCodec::Codec GetSubtitleCodec()
|
||||
{
|
||||
return static_cast<ExportCodec::Codec>(codec_combobox_->currentData().toInt());
|
||||
}
|
||||
ExportCodec::Codec GetSubtitleCodec()
|
||||
{
|
||||
return static_cast<ExportCodec::Codec>(
|
||||
codec_combobox_->currentData().toInt());
|
||||
}
|
||||
|
||||
void SetSubtitleCodec(ExportCodec::Codec c)
|
||||
{
|
||||
QtUtils::SetComboBoxData(codec_combobox_, c);
|
||||
}
|
||||
void SetSubtitleCodec(ExportCodec::Codec c)
|
||||
{
|
||||
QtUtils::SetComboBoxData(codec_combobox_, c);
|
||||
}
|
||||
|
||||
private:
|
||||
QCheckBox *sidecar_checkbox_;
|
||||
QCheckBox *sidecar_checkbox_;
|
||||
|
||||
QLabel *sidecar_format_label_;
|
||||
ExportFormatComboBox *sidecar_format_combobox_;
|
||||
|
||||
QComboBox *codec_combobox_;
|
||||
QLabel *sidecar_format_label_;
|
||||
ExportFormatComboBox *sidecar_format_combobox_;
|
||||
|
||||
QComboBox *codec_combobox_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -30,259 +30,272 @@
|
||||
#include "exportadvancedvideodialog.h"
|
||||
#include "node/color/colormanager/colormanager.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
ExportVideoTab::ExportVideoTab(ColorManager* color_manager, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
color_manager_(color_manager),
|
||||
threads_(0),
|
||||
color_range_(VideoParams::kColorRangeDefault)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* outer_layout = new QVBoxLayout(this);
|
||||
|
||||
outer_layout->addWidget(SetupResolutionSection());
|
||||
ExportVideoTab::ExportVideoTab(ColorManager *color_manager, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, color_manager_(color_manager)
|
||||
, threads_(0)
|
||||
, color_range_(VideoParams::kColorRangeDefault)
|
||||
{
|
||||
QVBoxLayout *outer_layout = new QVBoxLayout(this);
|
||||
|
||||
outer_layout->addWidget(SetupCodecSection());
|
||||
outer_layout->addWidget(SetupResolutionSection());
|
||||
|
||||
outer_layout->addWidget(SetupColorSection());
|
||||
outer_layout->addWidget(SetupCodecSection());
|
||||
|
||||
outer_layout->addStretch();
|
||||
outer_layout->addWidget(SetupColorSection());
|
||||
|
||||
outer_layout->addStretch();
|
||||
}
|
||||
|
||||
int ExportVideoTab::SetFormat(ExportFormat::Format format)
|
||||
{
|
||||
format_ = format;
|
||||
format_ = format;
|
||||
|
||||
QList<ExportCodec::Codec> vcodecs = ExportFormat::GetVideoCodecs(format);
|
||||
setEnabled(!vcodecs.isEmpty());
|
||||
codec_combobox()->clear();
|
||||
foreach (ExportCodec::Codec vcodec, vcodecs) {
|
||||
codec_combobox()->addItem(ExportCodec::GetCodecName(vcodec), vcodec);
|
||||
}
|
||||
return vcodecs.size();
|
||||
QList<ExportCodec::Codec> vcodecs = ExportFormat::GetVideoCodecs(format);
|
||||
setEnabled(!vcodecs.isEmpty());
|
||||
codec_combobox()->clear();
|
||||
foreach (ExportCodec::Codec vcodec, vcodecs) {
|
||||
codec_combobox()->addItem(ExportCodec::GetCodecName(vcodec), vcodec);
|
||||
}
|
||||
return vcodecs.size();
|
||||
}
|
||||
|
||||
bool ExportVideoTab::IsImageSequenceSet() const
|
||||
{
|
||||
ImageSection* img_section = dynamic_cast<ImageSection*>(codec_stack_->currentWidget());
|
||||
ImageSection *img_section =
|
||||
dynamic_cast<ImageSection *>(codec_stack_->currentWidget());
|
||||
|
||||
return (img_section && img_section->IsImageSequenceChecked());
|
||||
return (img_section && img_section->IsImageSequenceChecked());
|
||||
}
|
||||
|
||||
void ExportVideoTab::SetImageSequence(bool e) const
|
||||
{
|
||||
if (ImageSection* img_section = dynamic_cast<ImageSection*>(codec_stack_->currentWidget())) {
|
||||
img_section->SetImageSequenceChecked(e);
|
||||
}
|
||||
if (ImageSection *img_section =
|
||||
dynamic_cast<ImageSection *>(codec_stack_->currentWidget())) {
|
||||
img_section->SetImageSequenceChecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* ExportVideoTab::SetupResolutionSection()
|
||||
QWidget *ExportVideoTab::SetupResolutionSection()
|
||||
{
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
QGroupBox* resolution_group = new QGroupBox();
|
||||
resolution_group->setTitle(tr("General"));
|
||||
QGroupBox *resolution_group = new QGroupBox();
|
||||
resolution_group->setTitle(tr("General"));
|
||||
|
||||
QGridLayout* layout = new QGridLayout(resolution_group);
|
||||
QGridLayout *layout = new QGridLayout(resolution_group);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Width:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Width:")), row, 0);
|
||||
|
||||
width_slider_ = new IntegerSlider();
|
||||
width_slider_->SetMinimum(1);
|
||||
layout->addWidget(width_slider_, row, 1);
|
||||
width_slider_ = new IntegerSlider();
|
||||
width_slider_->SetMinimum(1);
|
||||
layout->addWidget(width_slider_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Height:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Height:")), row, 0);
|
||||
|
||||
height_slider_ = new IntegerSlider();
|
||||
height_slider_->SetMinimum(1);
|
||||
layout->addWidget(height_slider_, row, 1);
|
||||
height_slider_ = new IntegerSlider();
|
||||
height_slider_->SetMinimum(1);
|
||||
layout->addWidget(height_slider_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Maintain Aspect Ratio:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Maintain Aspect Ratio:")), row, 0);
|
||||
|
||||
maintain_aspect_checkbox_ = new QCheckBox();
|
||||
maintain_aspect_checkbox_->setChecked(true);
|
||||
layout->addWidget(maintain_aspect_checkbox_, row, 1);
|
||||
maintain_aspect_checkbox_ = new QCheckBox();
|
||||
maintain_aspect_checkbox_->setChecked(true);
|
||||
layout->addWidget(maintain_aspect_checkbox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Scaling Method:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Scaling Method:")), row, 0);
|
||||
|
||||
scaling_method_combobox_ = new QComboBox();
|
||||
scaling_method_combobox_->setEnabled(false);
|
||||
scaling_method_combobox_->addItem(tr("Fit"), EncodingParams::kFit);
|
||||
scaling_method_combobox_->addItem(tr("Stretch"), EncodingParams::kStretch);
|
||||
scaling_method_combobox_->addItem(tr("Crop"), EncodingParams::kCrop);
|
||||
layout->addWidget(scaling_method_combobox_, row, 1);
|
||||
scaling_method_combobox_ = new QComboBox();
|
||||
scaling_method_combobox_->setEnabled(false);
|
||||
scaling_method_combobox_->addItem(tr("Fit"), EncodingParams::kFit);
|
||||
scaling_method_combobox_->addItem(tr("Stretch"), EncodingParams::kStretch);
|
||||
scaling_method_combobox_->addItem(tr("Crop"), EncodingParams::kCrop);
|
||||
layout->addWidget(scaling_method_combobox_, row, 1);
|
||||
|
||||
// Automatically enable/disable the scaling method depending on maintain aspect ratio
|
||||
connect(maintain_aspect_checkbox_, &QCheckBox::toggled, this, &ExportVideoTab::MaintainAspectRatioChanged);
|
||||
// Automatically enable/disable the scaling method depending on maintain aspect ratio
|
||||
connect(maintain_aspect_checkbox_, &QCheckBox::toggled, this,
|
||||
&ExportVideoTab::MaintainAspectRatioChanged);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Frame Rate:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Frame Rate:")), row, 0);
|
||||
|
||||
frame_rate_combobox_ = new FrameRateComboBox();
|
||||
connect(frame_rate_combobox_, &FrameRateComboBox::FrameRateChanged, this, &ExportVideoTab::UpdateFrameRate);
|
||||
layout->addWidget(frame_rate_combobox_, row, 1);
|
||||
frame_rate_combobox_ = new FrameRateComboBox();
|
||||
connect(frame_rate_combobox_, &FrameRateComboBox::FrameRateChanged, this,
|
||||
&ExportVideoTab::UpdateFrameRate);
|
||||
layout->addWidget(frame_rate_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Pixel Aspect Ratio:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Pixel Aspect Ratio:")), row, 0);
|
||||
|
||||
pixel_aspect_combobox_ = new PixelAspectRatioComboBox();
|
||||
layout->addWidget(pixel_aspect_combobox_, row, 1);
|
||||
pixel_aspect_combobox_ = new PixelAspectRatioComboBox();
|
||||
layout->addWidget(pixel_aspect_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Interlacing:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Interlacing:")), row, 0);
|
||||
|
||||
interlaced_combobox_ = new InterlacedComboBox();
|
||||
layout->addWidget(interlaced_combobox_, row, 1);
|
||||
interlaced_combobox_ = new InterlacedComboBox();
|
||||
layout->addWidget(interlaced_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Quality:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Quality:")), row, 0);
|
||||
|
||||
pixel_format_field_ = new PixelFormatComboBox(false);
|
||||
layout->addWidget(pixel_format_field_, row, 1);
|
||||
pixel_format_field_ = new PixelFormatComboBox(false);
|
||||
layout->addWidget(pixel_format_field_, row, 1);
|
||||
|
||||
return resolution_group;
|
||||
return resolution_group;
|
||||
}
|
||||
|
||||
QWidget* ExportVideoTab::SetupColorSection()
|
||||
QWidget *ExportVideoTab::SetupColorSection()
|
||||
{
|
||||
color_space_chooser_ = new ColorSpaceChooser(color_manager_, true, false);
|
||||
connect(color_space_chooser_, &ColorSpaceChooser::InputColorSpaceChanged, this, &ExportVideoTab::ColorSpaceChanged);
|
||||
return color_space_chooser_;
|
||||
color_space_chooser_ = new ColorSpaceChooser(color_manager_, true, false);
|
||||
connect(color_space_chooser_, &ColorSpaceChooser::InputColorSpaceChanged,
|
||||
this, &ExportVideoTab::ColorSpaceChanged);
|
||||
return color_space_chooser_;
|
||||
}
|
||||
|
||||
QWidget *ExportVideoTab::SetupCodecSection()
|
||||
{
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
QGroupBox* codec_group = new QGroupBox();
|
||||
codec_group->setTitle(tr("Codec"));
|
||||
QGroupBox *codec_group = new QGroupBox();
|
||||
codec_group->setTitle(tr("Codec"));
|
||||
|
||||
QGridLayout* codec_layout = new QGridLayout(codec_group);
|
||||
QGridLayout *codec_layout = new QGridLayout(codec_group);
|
||||
|
||||
codec_layout->addWidget(new QLabel(tr("Codec:")), row, 0);
|
||||
codec_layout->addWidget(new QLabel(tr("Codec:")), row, 0);
|
||||
|
||||
codec_combobox_ = new QComboBox();
|
||||
codec_layout->addWidget(codec_combobox_, row, 1);
|
||||
connect(codec_combobox_,
|
||||
static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
&ExportVideoTab::VideoCodecChanged);
|
||||
codec_combobox_ = new QComboBox();
|
||||
codec_layout->addWidget(codec_combobox_, row, 1);
|
||||
connect(
|
||||
codec_combobox_,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &ExportVideoTab::VideoCodecChanged);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
codec_stack_ = new CodecStack();
|
||||
codec_layout->addWidget(codec_stack_, row, 0, 1, 2);
|
||||
codec_stack_ = new CodecStack();
|
||||
codec_layout->addWidget(codec_stack_, row, 0, 1, 2);
|
||||
|
||||
image_section_ = new ImageSection();
|
||||
connect(image_section_, &ImageSection::TimeChanged, this, &ExportVideoTab::TimeChanged);
|
||||
codec_stack_->addWidget(image_section_);
|
||||
image_section_ = new ImageSection();
|
||||
connect(image_section_, &ImageSection::TimeChanged, this,
|
||||
&ExportVideoTab::TimeChanged);
|
||||
codec_stack_->addWidget(image_section_);
|
||||
|
||||
h264_section_ = new H264Section();
|
||||
codec_stack_->addWidget(h264_section_);
|
||||
h264_section_ = new H264Section();
|
||||
codec_stack_->addWidget(h264_section_);
|
||||
|
||||
h265_section_ = new H265Section();
|
||||
codec_stack_->addWidget(h265_section_);
|
||||
h265_section_ = new H265Section();
|
||||
codec_stack_->addWidget(h265_section_);
|
||||
|
||||
av1_section_ = new AV1Section();
|
||||
codec_stack_->addWidget(av1_section_);
|
||||
av1_section_ = new AV1Section();
|
||||
codec_stack_->addWidget(av1_section_);
|
||||
|
||||
cineform_section_ = new CineformSection();
|
||||
codec_stack_->addWidget(cineform_section_);
|
||||
cineform_section_ = new CineformSection();
|
||||
codec_stack_->addWidget(cineform_section_);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
QPushButton* advanced_btn = new QPushButton(tr("Advanced"));
|
||||
connect(advanced_btn, &QPushButton::clicked, this, &ExportVideoTab::OpenAdvancedDialog);
|
||||
codec_layout->addWidget(advanced_btn, row, 1);
|
||||
QPushButton *advanced_btn = new QPushButton(tr("Advanced"));
|
||||
connect(advanced_btn, &QPushButton::clicked, this,
|
||||
&ExportVideoTab::OpenAdvancedDialog);
|
||||
codec_layout->addWidget(advanced_btn, row, 1);
|
||||
|
||||
return codec_group;
|
||||
return codec_group;
|
||||
}
|
||||
|
||||
void ExportVideoTab::MaintainAspectRatioChanged(bool val)
|
||||
{
|
||||
scaling_method_combobox_->setEnabled(!val);
|
||||
scaling_method_combobox_->setEnabled(!val);
|
||||
}
|
||||
|
||||
void ExportVideoTab::OpenAdvancedDialog()
|
||||
{
|
||||
// Find export formats compatible with this encoder
|
||||
QStringList pixel_formats = ExportFormat::GetPixelFormatsForCodec(format_, GetSelectedCodec());
|
||||
// Find export formats compatible with this encoder
|
||||
QStringList pixel_formats =
|
||||
ExportFormat::GetPixelFormatsForCodec(format_, GetSelectedCodec());
|
||||
|
||||
ExportAdvancedVideoDialog d(pixel_formats, this);
|
||||
ExportAdvancedVideoDialog d(pixel_formats, this);
|
||||
|
||||
d.set_threads(threads_);
|
||||
d.set_pix_fmt(pix_fmt_);
|
||||
d.set_yuv_range(color_range_);
|
||||
d.set_threads(threads_);
|
||||
d.set_pix_fmt(pix_fmt_);
|
||||
d.set_yuv_range(color_range_);
|
||||
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
threads_ = d.threads();
|
||||
pix_fmt_ = d.pix_fmt();
|
||||
color_range_ = d.yuv_range();
|
||||
}
|
||||
if (d.exec() == QDialog::Accepted) {
|
||||
threads_ = d.threads();
|
||||
pix_fmt_ = d.pix_fmt();
|
||||
color_range_ = d.yuv_range();
|
||||
}
|
||||
}
|
||||
|
||||
void ExportVideoTab::UpdateFrameRate(rational r)
|
||||
{
|
||||
// Convert frame rate to timebase
|
||||
r.flip();
|
||||
// Convert frame rate to timebase
|
||||
r.flip();
|
||||
|
||||
for (int i=0; i<codec_stack_->count(); i++) {
|
||||
ImageSection* img = dynamic_cast<ImageSection*>(codec_stack_->widget(i));
|
||||
if (img) {
|
||||
img->SetTimebase(r);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < codec_stack_->count(); i++) {
|
||||
ImageSection *img =
|
||||
dynamic_cast<ImageSection *>(codec_stack_->widget(i));
|
||||
if (img) {
|
||||
img->SetTimebase(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExportVideoTab::VideoCodecChanged()
|
||||
{
|
||||
ExportCodec::Codec codec = GetSelectedCodec();
|
||||
ExportCodec::Codec codec = GetSelectedCodec();
|
||||
|
||||
switch (codec) {
|
||||
case ExportCodec::kCodecH264:
|
||||
case ExportCodec::kCodecH264rgb:
|
||||
SetCodecSection(h264_section_);
|
||||
break;
|
||||
case ExportCodec::kCodecH265:
|
||||
SetCodecSection(h265_section_);
|
||||
break;
|
||||
case ExportCodec::kCodecAV1:
|
||||
SetCodecSection(av1_section_);
|
||||
break;
|
||||
case ExportCodec::kCodecCineform:
|
||||
SetCodecSection(cineform_section_);
|
||||
break;
|
||||
default:
|
||||
SetCodecSection(ExportCodec::IsCodecAStillImage(codec) ? image_section_ : nullptr);
|
||||
}
|
||||
switch (codec) {
|
||||
case ExportCodec::kCodecH264:
|
||||
case ExportCodec::kCodecH264rgb:
|
||||
SetCodecSection(h264_section_);
|
||||
break;
|
||||
case ExportCodec::kCodecH265:
|
||||
SetCodecSection(h265_section_);
|
||||
break;
|
||||
case ExportCodec::kCodecAV1:
|
||||
SetCodecSection(av1_section_);
|
||||
break;
|
||||
case ExportCodec::kCodecCineform:
|
||||
SetCodecSection(cineform_section_);
|
||||
break;
|
||||
default:
|
||||
SetCodecSection(
|
||||
ExportCodec::IsCodecAStillImage(codec) ? image_section_ : nullptr);
|
||||
}
|
||||
|
||||
// Set default pixel format
|
||||
QStringList pix_fmts = ExportFormat::GetPixelFormatsForCodec(format_, codec);
|
||||
if (!pix_fmts.isEmpty()) {
|
||||
pix_fmt_ = pix_fmts.first();
|
||||
} else {
|
||||
pix_fmt_.clear();
|
||||
}
|
||||
// Set default pixel format
|
||||
QStringList pix_fmts =
|
||||
ExportFormat::GetPixelFormatsForCodec(format_, codec);
|
||||
if (!pix_fmts.isEmpty()) {
|
||||
pix_fmt_ = pix_fmts.first();
|
||||
} else {
|
||||
pix_fmt_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ExportVideoTab::SetTime(const rational &time)
|
||||
{
|
||||
for (int i=0; i<codec_stack_->count(); i++) {
|
||||
ImageSection* img = dynamic_cast<ImageSection*>(codec_stack_->widget(i));
|
||||
if (img) {
|
||||
img->SetTime(time);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < codec_stack_->count(); i++) {
|
||||
ImageSection *img =
|
||||
dynamic_cast<ImageSection *>(codec_stack_->widget(i));
|
||||
if (img) {
|
||||
img->SetTime(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+139
-127
@@ -36,180 +36,192 @@
|
||||
#include "widget/slider/integerslider.h"
|
||||
#include "widget/standardcombos/standardcombos.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ExportVideoTab : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ExportVideoTab : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportVideoTab(ColorManager* color_manager, QWidget* parent = nullptr);
|
||||
ExportVideoTab(ColorManager *color_manager, QWidget *parent = nullptr);
|
||||
|
||||
int SetFormat(ExportFormat::Format format);
|
||||
int SetFormat(ExportFormat::Format format);
|
||||
|
||||
bool IsImageSequenceSet() const;
|
||||
void SetImageSequence(bool e) const;
|
||||
bool IsImageSequenceSet() const;
|
||||
void SetImageSequence(bool e) const;
|
||||
|
||||
rational GetStillImageTime() const
|
||||
{
|
||||
return image_section_->GetTime();
|
||||
}
|
||||
rational GetStillImageTime() const
|
||||
{
|
||||
return image_section_->GetTime();
|
||||
}
|
||||
|
||||
ExportCodec::Codec GetSelectedCodec() const
|
||||
{
|
||||
return static_cast<ExportCodec::Codec>(codec_combobox()->currentData().toInt());
|
||||
}
|
||||
ExportCodec::Codec GetSelectedCodec() const
|
||||
{
|
||||
return static_cast<ExportCodec::Codec>(
|
||||
codec_combobox()->currentData().toInt());
|
||||
}
|
||||
|
||||
void SetSelectedCodec(ExportCodec::Codec c)
|
||||
{
|
||||
QtUtils::SetComboBoxData(codec_combobox(), c);
|
||||
}
|
||||
void SetSelectedCodec(ExportCodec::Codec c)
|
||||
{
|
||||
QtUtils::SetComboBoxData(codec_combobox(), c);
|
||||
}
|
||||
|
||||
QComboBox* codec_combobox() const
|
||||
{
|
||||
return codec_combobox_;
|
||||
}
|
||||
QComboBox *codec_combobox() const
|
||||
{
|
||||
return codec_combobox_;
|
||||
}
|
||||
|
||||
IntegerSlider* width_slider() const
|
||||
{
|
||||
return width_slider_;
|
||||
}
|
||||
IntegerSlider *width_slider() const
|
||||
{
|
||||
return width_slider_;
|
||||
}
|
||||
|
||||
IntegerSlider* height_slider() const
|
||||
{
|
||||
return height_slider_;
|
||||
}
|
||||
IntegerSlider *height_slider() const
|
||||
{
|
||||
return height_slider_;
|
||||
}
|
||||
|
||||
QCheckBox* maintain_aspect_checkbox() const
|
||||
{
|
||||
return maintain_aspect_checkbox_;
|
||||
}
|
||||
QCheckBox *maintain_aspect_checkbox() const
|
||||
{
|
||||
return maintain_aspect_checkbox_;
|
||||
}
|
||||
|
||||
QComboBox* scaling_method_combobox() const
|
||||
{
|
||||
return scaling_method_combobox_;
|
||||
}
|
||||
QComboBox *scaling_method_combobox() const
|
||||
{
|
||||
return scaling_method_combobox_;
|
||||
}
|
||||
|
||||
rational GetSelectedFrameRate() const
|
||||
{
|
||||
return frame_rate_combobox_->GetFrameRate();
|
||||
}
|
||||
rational GetSelectedFrameRate() const
|
||||
{
|
||||
return frame_rate_combobox_->GetFrameRate();
|
||||
}
|
||||
|
||||
void SetSelectedFrameRate(const rational& fr)
|
||||
{
|
||||
frame_rate_combobox_->SetFrameRate(fr);
|
||||
UpdateFrameRate(fr);
|
||||
}
|
||||
void SetSelectedFrameRate(const rational &fr)
|
||||
{
|
||||
frame_rate_combobox_->SetFrameRate(fr);
|
||||
UpdateFrameRate(fr);
|
||||
}
|
||||
|
||||
QString CurrentOCIOColorSpace()
|
||||
{
|
||||
return color_space_chooser_->input();
|
||||
}
|
||||
QString CurrentOCIOColorSpace()
|
||||
{
|
||||
return color_space_chooser_->input();
|
||||
}
|
||||
|
||||
void SetOCIOColorSpace(const QString &s)
|
||||
{
|
||||
color_space_chooser_->set_input(s);
|
||||
}
|
||||
void SetOCIOColorSpace(const QString &s)
|
||||
{
|
||||
color_space_chooser_->set_input(s);
|
||||
}
|
||||
|
||||
CodecSection* GetCodecSection() const
|
||||
{
|
||||
return static_cast<CodecSection*>(codec_stack_->currentWidget());
|
||||
}
|
||||
CodecSection *GetCodecSection() const
|
||||
{
|
||||
return static_cast<CodecSection *>(codec_stack_->currentWidget());
|
||||
}
|
||||
|
||||
void SetCodecSection(CodecSection* section)
|
||||
{
|
||||
if (section) {
|
||||
codec_stack_->setVisible(true);
|
||||
codec_stack_->setCurrentWidget(section);
|
||||
} else {
|
||||
codec_stack_->setVisible(false);
|
||||
}
|
||||
}
|
||||
void SetCodecSection(CodecSection *section)
|
||||
{
|
||||
if (section) {
|
||||
codec_stack_->setVisible(true);
|
||||
codec_stack_->setCurrentWidget(section);
|
||||
} else {
|
||||
codec_stack_->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
InterlacedComboBox* interlaced_combobox() const
|
||||
{
|
||||
return interlaced_combobox_;
|
||||
}
|
||||
InterlacedComboBox *interlaced_combobox() const
|
||||
{
|
||||
return interlaced_combobox_;
|
||||
}
|
||||
|
||||
PixelAspectRatioComboBox* pixel_aspect_combobox() const
|
||||
{
|
||||
return pixel_aspect_combobox_;
|
||||
}
|
||||
PixelAspectRatioComboBox *pixel_aspect_combobox() const
|
||||
{
|
||||
return pixel_aspect_combobox_;
|
||||
}
|
||||
|
||||
PixelFormatComboBox* pixel_format_field() const
|
||||
{
|
||||
return pixel_format_field_;
|
||||
}
|
||||
PixelFormatComboBox *pixel_format_field() const
|
||||
{
|
||||
return pixel_format_field_;
|
||||
}
|
||||
|
||||
const int& threads() const
|
||||
{
|
||||
return threads_;
|
||||
}
|
||||
const int &threads() const
|
||||
{
|
||||
return threads_;
|
||||
}
|
||||
|
||||
void SetThreads(int t)
|
||||
{
|
||||
threads_ = t;
|
||||
}
|
||||
void SetThreads(int t)
|
||||
{
|
||||
threads_ = t;
|
||||
}
|
||||
|
||||
const QString& pix_fmt() const { return pix_fmt_; }
|
||||
void SetPixFmt(const QString &s) { pix_fmt_ = s; }
|
||||
const QString &pix_fmt() const
|
||||
{
|
||||
return pix_fmt_;
|
||||
}
|
||||
void SetPixFmt(const QString &s)
|
||||
{
|
||||
pix_fmt_ = s;
|
||||
}
|
||||
|
||||
VideoParams::ColorRange color_range() const { return color_range_; }
|
||||
void SetColorRange(VideoParams::ColorRange c) { color_range_ = c; }
|
||||
VideoParams::ColorRange color_range() const
|
||||
{
|
||||
return color_range_;
|
||||
}
|
||||
void SetColorRange(VideoParams::ColorRange c)
|
||||
{
|
||||
color_range_ = c;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void VideoCodecChanged();
|
||||
void VideoCodecChanged();
|
||||
|
||||
void SetTime(const rational &time);
|
||||
void SetTime(const rational &time);
|
||||
|
||||
signals:
|
||||
void ColorSpaceChanged(const QString& colorspace);
|
||||
void ColorSpaceChanged(const QString &colorspace);
|
||||
|
||||
void ImageSequenceCheckBoxChanged(bool e);
|
||||
void ImageSequenceCheckBoxChanged(bool e);
|
||||
|
||||
void TimeChanged(const rational &time);
|
||||
void TimeChanged(const rational &time);
|
||||
|
||||
private:
|
||||
QWidget* SetupResolutionSection();
|
||||
QWidget* SetupColorSection();
|
||||
QWidget* SetupCodecSection();
|
||||
QWidget *SetupResolutionSection();
|
||||
QWidget *SetupColorSection();
|
||||
QWidget *SetupCodecSection();
|
||||
|
||||
QComboBox* codec_combobox_;
|
||||
FrameRateComboBox* frame_rate_combobox_;
|
||||
QCheckBox* maintain_aspect_checkbox_;
|
||||
QComboBox* scaling_method_combobox_;
|
||||
QComboBox *codec_combobox_;
|
||||
FrameRateComboBox *frame_rate_combobox_;
|
||||
QCheckBox *maintain_aspect_checkbox_;
|
||||
QComboBox *scaling_method_combobox_;
|
||||
|
||||
CodecStack* codec_stack_;
|
||||
ImageSection* image_section_;
|
||||
H264Section* h264_section_;
|
||||
H264Section* h265_section_;
|
||||
AV1Section* av1_section_;
|
||||
CineformSection *cineform_section_;
|
||||
CodecStack *codec_stack_;
|
||||
ImageSection *image_section_;
|
||||
H264Section *h264_section_;
|
||||
H264Section *h265_section_;
|
||||
AV1Section *av1_section_;
|
||||
CineformSection *cineform_section_;
|
||||
|
||||
ColorSpaceChooser* color_space_chooser_;
|
||||
ColorSpaceChooser *color_space_chooser_;
|
||||
|
||||
IntegerSlider* width_slider_;
|
||||
IntegerSlider* height_slider_;
|
||||
IntegerSlider *width_slider_;
|
||||
IntegerSlider *height_slider_;
|
||||
|
||||
ColorManager* color_manager_;
|
||||
ColorManager *color_manager_;
|
||||
|
||||
InterlacedComboBox* interlaced_combobox_;
|
||||
PixelAspectRatioComboBox* pixel_aspect_combobox_;
|
||||
PixelFormatComboBox* pixel_format_field_;
|
||||
InterlacedComboBox *interlaced_combobox_;
|
||||
PixelAspectRatioComboBox *pixel_aspect_combobox_;
|
||||
PixelFormatComboBox *pixel_format_field_;
|
||||
|
||||
int threads_;
|
||||
int threads_;
|
||||
|
||||
QString pix_fmt_;
|
||||
VideoParams::ColorRange color_range_;
|
||||
QString pix_fmt_;
|
||||
VideoParams::ColorRange color_range_;
|
||||
|
||||
ExportFormat::Format format_;
|
||||
ExportFormat::Format format_;
|
||||
|
||||
private slots:
|
||||
void MaintainAspectRatioChanged(bool val);
|
||||
void MaintainAspectRatioChanged(bool val);
|
||||
|
||||
void OpenAdvancedDialog();
|
||||
|
||||
void UpdateFrameRate(rational r);
|
||||
void OpenAdvancedDialog();
|
||||
|
||||
void UpdateFrameRate(rational r);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,241 +36,246 @@
|
||||
#include "streamproperties/audiostreamproperties.h"
|
||||
#include "streamproperties/videostreamproperties.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
FootagePropertiesDialog::FootagePropertiesDialog(QWidget *parent, Footage *footage) :
|
||||
QDialog(parent),
|
||||
footage_(footage)
|
||||
namespace olive
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
|
||||
setWindowTitle(tr("\"%1\" Properties").arg(footage_->GetLabelOrName()));
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
FootagePropertiesDialog::FootagePropertiesDialog(QWidget *parent,
|
||||
Footage *footage)
|
||||
: QDialog(parent)
|
||||
, footage_(footage)
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
int row = 0;
|
||||
setWindowTitle(tr("\"%1\" Properties").arg(footage_->GetLabelOrName()));
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Name:")), row, 0);
|
||||
int row = 0;
|
||||
|
||||
footage_name_field_ = new QLineEdit(footage_->GetLabel());
|
||||
layout->addWidget(footage_name_field_, row, 1);
|
||||
row++;
|
||||
layout->addWidget(new QLabel(tr("Name:")), row, 0);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Tracks:")), row, 0, 1, 2);
|
||||
row++;
|
||||
footage_name_field_ = new QLineEdit(footage_->GetLabel());
|
||||
layout->addWidget(footage_name_field_, row, 1);
|
||||
row++;
|
||||
|
||||
track_list = new QListWidget();
|
||||
layout->addWidget(track_list, row, 0, 1, 2);
|
||||
layout->addWidget(new QLabel(tr("Tracks:")), row, 0, 1, 2);
|
||||
row++;
|
||||
|
||||
row++;
|
||||
track_list = new QListWidget();
|
||||
layout->addWidget(track_list, row, 0, 1, 2);
|
||||
|
||||
stacked_widget_ = new QStackedWidget();
|
||||
layout->addWidget(stacked_widget_, row, 0, 1, 2);
|
||||
row++;
|
||||
|
||||
int first_usable_stream = -1;
|
||||
stacked_widget_ = new QStackedWidget();
|
||||
layout->addWidget(stacked_widget_, row, 0, 1, 2);
|
||||
|
||||
for (int i=0; i<footage_->GetTotalStreamCount(); i++) {
|
||||
Track::Reference reference = footage_->GetReferenceFromRealIndex(i);
|
||||
int first_usable_stream = -1;
|
||||
|
||||
QString description;
|
||||
bool is_enabled = false;
|
||||
for (int i = 0; i < footage_->GetTotalStreamCount(); i++) {
|
||||
Track::Reference reference = footage_->GetReferenceFromRealIndex(i);
|
||||
|
||||
switch (reference.type()) {
|
||||
case Track::kVideo:
|
||||
{
|
||||
stacked_widget_->addWidget(new VideoStreamProperties(footage_, reference.index()));
|
||||
QString description;
|
||||
bool is_enabled = false;
|
||||
|
||||
VideoParams vp = footage_->GetVideoParams(reference.index());
|
||||
is_enabled = vp.enabled();
|
||||
description = Footage::DescribeVideoStream(vp);
|
||||
break;
|
||||
}
|
||||
case Track::kAudio:
|
||||
{
|
||||
stacked_widget_->addWidget(new AudioStreamProperties(footage_, reference.index()));
|
||||
switch (reference.type()) {
|
||||
case Track::kVideo: {
|
||||
stacked_widget_->addWidget(
|
||||
new VideoStreamProperties(footage_, reference.index()));
|
||||
|
||||
AudioParams ap = footage_->GetAudioParams(reference.index());
|
||||
is_enabled = ap.enabled();
|
||||
description = Footage::DescribeAudioStream(ap);
|
||||
break;
|
||||
}
|
||||
case Track::kSubtitle:
|
||||
{
|
||||
SubtitleParams sp = footage_->GetSubtitleParams(reference.index());
|
||||
is_enabled = sp.enabled();
|
||||
VideoParams vp = footage_->GetVideoParams(reference.index());
|
||||
is_enabled = vp.enabled();
|
||||
description = Footage::DescribeVideoStream(vp);
|
||||
break;
|
||||
}
|
||||
case Track::kAudio: {
|
||||
stacked_widget_->addWidget(
|
||||
new AudioStreamProperties(footage_, reference.index()));
|
||||
|
||||
// FIXME: Language?
|
||||
description = tr("Subtitles");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
stacked_widget_->addWidget(new StreamProperties());
|
||||
description = tr("Unknown");
|
||||
break;
|
||||
}
|
||||
AudioParams ap = footage_->GetAudioParams(reference.index());
|
||||
is_enabled = ap.enabled();
|
||||
description = Footage::DescribeAudioStream(ap);
|
||||
break;
|
||||
}
|
||||
case Track::kSubtitle: {
|
||||
SubtitleParams sp = footage_->GetSubtitleParams(reference.index());
|
||||
is_enabled = sp.enabled();
|
||||
|
||||
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);
|
||||
// FIXME: Language?
|
||||
description = tr("Subtitles");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
stacked_widget_->addWidget(new StreamProperties());
|
||||
description = tr("Unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
if (first_usable_stream == -1
|
||||
&& (reference.type() == Track::kVideo
|
||||
|| reference.type() == Track::kAudio
|
||||
|| reference.type() == Track::kSubtitle)) {
|
||||
first_usable_stream = i;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
row++;
|
||||
if (first_usable_stream == -1 &&
|
||||
(reference.type() == Track::kVideo ||
|
||||
reference.type() == Track::kAudio ||
|
||||
reference.type() == Track::kSubtitle)) {
|
||||
first_usable_stream = i;
|
||||
}
|
||||
}
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttons->setCenterButtons(true);
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
row++;
|
||||
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttons->setCenterButtons(true);
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
|
||||
connect(track_list, &QListWidget::currentRowChanged, stacked_widget_, &QStackedWidget::setCurrentIndex);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
// Auto-select first item that actually has properties
|
||||
if (first_usable_stream >= 0) {
|
||||
track_list->setCurrentRow(first_usable_stream);
|
||||
}
|
||||
track_list->setFocus();
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// Do nothing (it's up to the property panel itself to throw the error message)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MultiUndoCommand* command = new MultiUndoCommand();
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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:
|
||||
old_stream_enabled = footage_->GetSubtitleParams(reference.index()).enabled();
|
||||
break;
|
||||
case Track::kNone:
|
||||
case Track::kCount:
|
||||
break;
|
||||
}
|
||||
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:
|
||||
old_stream_enabled =
|
||||
footage_->GetSubtitleParams(reference.index()).enabled();
|
||||
break;
|
||||
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));
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
for (int i = 0; i < stacked_widget_->count(); i++) {
|
||||
static_cast<StreamProperties *>(stacked_widget_->widget(i))
|
||||
->Accept(command);
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command, tr("Set Footage \"%1\" Properties").arg(footage_->GetLabel()));
|
||||
Core::instance()->undo_stack()->push(
|
||||
command, tr("Set Footage \"%1\" Properties").arg(footage_->GetLabel()));
|
||||
|
||||
QDialog::accept();
|
||||
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)
|
||||
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
|
||||
Project *
|
||||
FootagePropertiesDialog::StreamEnableChangeCommand::GetRelevantProject() const
|
||||
{
|
||||
return footage_->project();
|
||||
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:
|
||||
{
|
||||
SubtitleParams sp = footage_->GetSubtitleParams(index_);
|
||||
old_enabled_ = sp.enabled();
|
||||
sp.set_enabled(new_enabled_);
|
||||
footage_->SetSubtitleParams(sp, index_);
|
||||
break;
|
||||
}
|
||||
case Track::kNone:
|
||||
case Track::kCount:
|
||||
break;
|
||||
}
|
||||
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: {
|
||||
SubtitleParams sp = footage_->GetSubtitleParams(index_);
|
||||
old_enabled_ = sp.enabled();
|
||||
sp.set_enabled(new_enabled_);
|
||||
footage_->SetSubtitleParams(sp, index_);
|
||||
break;
|
||||
}
|
||||
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:
|
||||
{
|
||||
SubtitleParams sp = footage_->GetSubtitleParams(index_);
|
||||
sp.set_enabled(old_enabled_);
|
||||
footage_->SetSubtitleParams(sp, index_);
|
||||
break;
|
||||
}
|
||||
case Track::kNone:
|
||||
case Track::kCount:
|
||||
break;
|
||||
}
|
||||
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: {
|
||||
SubtitleParams sp = footage_->GetSubtitleParams(index_);
|
||||
sp.set_enabled(old_enabled_);
|
||||
footage_->SetSubtitleParams(sp, index_);
|
||||
break;
|
||||
}
|
||||
case Track::kNone:
|
||||
case Track::kCount:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
#include "node/project/footage/footage.h"
|
||||
#include "undo/undocommand.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief The MediaPropertiesDialog class
|
||||
@@ -41,9 +42,9 @@ namespace olive {
|
||||
* a valid Media object.
|
||||
*/
|
||||
class FootagePropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief MediaPropertiesDialog Constructor
|
||||
*
|
||||
* @param parent
|
||||
@@ -54,61 +55,59 @@ public:
|
||||
*
|
||||
* Media object to set properties for.
|
||||
*/
|
||||
FootagePropertiesDialog(QWidget *parent, Footage* footage);
|
||||
FootagePropertiesDialog(QWidget *parent, Footage *footage);
|
||||
|
||||
private:
|
||||
class StreamEnableChangeCommand : public UndoCommand {
|
||||
public:
|
||||
StreamEnableChangeCommand(Footage *footage,
|
||||
Track::Type type,
|
||||
int index_in_type,
|
||||
bool enabled);
|
||||
class StreamEnableChangeCommand : public UndoCommand {
|
||||
public:
|
||||
StreamEnableChangeCommand(Footage *footage, Track::Type type,
|
||||
int index_in_type, bool enabled);
|
||||
|
||||
virtual Project* GetRelevantProject() const override;
|
||||
virtual Project *GetRelevantProject() const override;
|
||||
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
|
||||
private:
|
||||
Footage *footage_;
|
||||
Track::Type type_;
|
||||
int index_;
|
||||
private:
|
||||
Footage *footage_;
|
||||
Track::Type type_;
|
||||
int index_;
|
||||
|
||||
bool old_enabled_;
|
||||
bool new_enabled_;
|
||||
};
|
||||
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_;
|
||||
QStackedWidget *stacked_widget_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Media name text field
|
||||
*/
|
||||
QLineEdit* footage_name_field_;
|
||||
QLineEdit *footage_name_field_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Internal pointer to Media object (set in constructor)
|
||||
*/
|
||||
Footage* footage_;
|
||||
Footage *footage_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief A list widget for listing the tracks in Media
|
||||
*/
|
||||
QListWidget* track_list;
|
||||
QListWidget *track_list;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Frame rate to conform to
|
||||
*/
|
||||
QDoubleSpinBox* conform_fr;
|
||||
QDoubleSpinBox *conform_fr;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
/**
|
||||
* @brief Overridden accept function for saving the properties back to the Media class
|
||||
*/
|
||||
void accept();
|
||||
|
||||
void accept();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,18 +20,19 @@
|
||||
|
||||
#include "audiostreamproperties.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
AudioStreamProperties::AudioStreamProperties(Footage *footage, int audio_index) :
|
||||
footage_(footage),
|
||||
audio_index_(audio_index)
|
||||
AudioStreamProperties::AudioStreamProperties(Footage *footage, int audio_index)
|
||||
: footage_(footage)
|
||||
, audio_index_(audio_index)
|
||||
{
|
||||
}
|
||||
|
||||
void AudioStreamProperties::Accept(MultiUndoCommand*)
|
||||
void AudioStreamProperties::Accept(MultiUndoCommand *)
|
||||
{
|
||||
Q_UNUSED(footage_)
|
||||
Q_UNUSED(audio_index_)
|
||||
Q_UNUSED(footage_)
|
||||
Q_UNUSED(audio_index_)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,20 +24,19 @@
|
||||
#include "node/project/footage/footage.h"
|
||||
#include "streamproperties.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class AudioStreamProperties : public StreamProperties
|
||||
namespace olive
|
||||
{
|
||||
public:
|
||||
AudioStreamProperties(Footage *footage, int audio_index);
|
||||
|
||||
virtual void Accept(MultiUndoCommand* parent) override;
|
||||
class AudioStreamProperties : public StreamProperties {
|
||||
public:
|
||||
AudioStreamProperties(Footage *footage, int audio_index);
|
||||
|
||||
virtual void Accept(MultiUndoCommand *parent) override;
|
||||
|
||||
private:
|
||||
Footage *footage_;
|
||||
|
||||
int audio_index_;
|
||||
Footage *footage_;
|
||||
|
||||
int audio_index_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
#include "streamproperties.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
StreamProperties::StreamProperties(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
StreamProperties::StreamProperties(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -26,17 +26,21 @@
|
||||
#include "common/define.h"
|
||||
#include "undo/undocommand.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class StreamProperties : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class StreamProperties : public QWidget {
|
||||
public:
|
||||
StreamProperties(QWidget* parent = nullptr);
|
||||
StreamProperties(QWidget *parent = nullptr);
|
||||
|
||||
virtual void Accept(MultiUndoCommand*){}
|
||||
|
||||
virtual bool SanityCheck(){return true;}
|
||||
virtual void Accept(MultiUndoCommand *)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool SanityCheck()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -30,259 +30,272 @@
|
||||
#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)
|
||||
namespace olive
|
||||
{
|
||||
QGridLayout* video_layout = new QGridLayout(this);
|
||||
video_layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
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->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
video_layout->addWidget(new QLabel(tr("Pixel Aspect:")), row, 0);
|
||||
int row = 0;
|
||||
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
video_layout->addWidget(new QLabel(tr("Pixel Aspect:")), row, 0);
|
||||
|
||||
pixel_aspect_combo_ = new PixelAspectRatioComboBox();
|
||||
pixel_aspect_combo_->SetPixelAspectRatio(vp.pixel_aspect_ratio());
|
||||
video_layout->addWidget(pixel_aspect_combo_, row, 1);
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
|
||||
row++;
|
||||
pixel_aspect_combo_ = new PixelAspectRatioComboBox();
|
||||
pixel_aspect_combo_->SetPixelAspectRatio(vp.pixel_aspect_ratio());
|
||||
video_layout->addWidget(pixel_aspect_combo_, row, 1);
|
||||
|
||||
video_layout->addWidget(new QLabel(tr("Interlacing:")), row, 0);
|
||||
row++;
|
||||
|
||||
video_interlace_combo_ = new InterlacedComboBox();
|
||||
video_interlace_combo_->SetInterlaceMode(vp.interlacing());
|
||||
video_layout->addWidget(new QLabel(tr("Interlacing:")), row, 0);
|
||||
|
||||
video_layout->addWidget(video_interlace_combo_, row, 1);
|
||||
video_interlace_combo_ = new InterlacedComboBox();
|
||||
video_interlace_combo_->SetInterlaceMode(vp.interlacing());
|
||||
|
||||
row++;
|
||||
video_layout->addWidget(video_interlace_combo_, row, 1);
|
||||
|
||||
video_layout->addWidget(new QLabel(tr("Color Space:")), row, 0);
|
||||
row++;
|
||||
|
||||
video_color_space_ = new QComboBox();
|
||||
OCIO::ConstConfigRcPtr config = footage_->project()->color_manager()->GetConfig();
|
||||
int number_of_colorspaces = config->getNumColorSpaces();
|
||||
video_layout->addWidget(new QLabel(tr("Color Space:")), row, 0);
|
||||
|
||||
video_color_space_->addItem(tr("Default (%1)").arg(footage_->project()->color_manager()->GetDefaultInputColorSpace()));
|
||||
video_color_space_ = new QComboBox();
|
||||
OCIO::ConstConfigRcPtr config =
|
||||
footage_->project()->color_manager()->GetConfig();
|
||||
int number_of_colorspaces = config->getNumColorSpaces();
|
||||
|
||||
for (int i=0;i<number_of_colorspaces;i++) {
|
||||
QString colorspace = config->getColorSpaceNameByIndex(i);
|
||||
video_color_space_->addItem(tr("Default (%1)")
|
||||
.arg(footage_->project()
|
||||
->color_manager()
|
||||
->GetDefaultInputColorSpace()));
|
||||
|
||||
video_color_space_->addItem(colorspace);
|
||||
}
|
||||
for (int i = 0; i < number_of_colorspaces; i++) {
|
||||
QString colorspace = config->getColorSpaceNameByIndex(i);
|
||||
|
||||
video_color_space_->setCurrentText(vp.colorspace());
|
||||
video_color_space_->addItem(colorspace);
|
||||
}
|
||||
|
||||
video_layout->addWidget(video_color_space_, row, 1);
|
||||
video_color_space_->setCurrentText(vp.colorspace());
|
||||
|
||||
row++;
|
||||
video_layout->addWidget(video_color_space_, row, 1);
|
||||
|
||||
video_layout->addWidget(new QLabel(tr("Color Range:")), row, 0);
|
||||
row++;
|
||||
|
||||
color_range_combo_ = new QComboBox();
|
||||
color_range_combo_->addItem(tr("Limited (16-235)"), VideoParams::kColorRangeLimited);
|
||||
color_range_combo_->addItem(tr("Full (0-255)"), VideoParams::kColorRangeFull);
|
||||
color_range_combo_->setCurrentIndex(vp.color_range());
|
||||
video_layout->addWidget(new QLabel(tr("Color Range:")), row, 0);
|
||||
|
||||
video_layout->addWidget(color_range_combo_, row, 1);
|
||||
color_range_combo_ = new QComboBox();
|
||||
color_range_combo_->addItem(tr("Limited (16-235)"),
|
||||
VideoParams::kColorRangeLimited);
|
||||
color_range_combo_->addItem(tr("Full (0-255)"),
|
||||
VideoParams::kColorRangeFull);
|
||||
color_range_combo_->setCurrentIndex(vp.color_range());
|
||||
|
||||
if (vp.channel_count() == VideoParams::kRGBAChannelCount) {
|
||||
row++;
|
||||
video_layout->addWidget(color_range_combo_, row, 1);
|
||||
|
||||
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);
|
||||
}
|
||||
if (vp.channel_count() == VideoParams::kRGBAChannelCount) {
|
||||
row++;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (vp.video_type() == VideoParams::kVideoTypeImageSequence) {
|
||||
QGroupBox* imgseq_group = new QGroupBox(tr("Image Sequence"));
|
||||
QGridLayout* imgseq_layout = new QGridLayout(imgseq_group);
|
||||
row++;
|
||||
|
||||
int imgseq_row = 0;
|
||||
if (vp.video_type() == VideoParams::kVideoTypeImageSequence) {
|
||||
QGroupBox *imgseq_group = new QGroupBox(tr("Image Sequence"));
|
||||
QGridLayout *imgseq_layout = new QGridLayout(imgseq_group);
|
||||
|
||||
imgseq_layout->addWidget(new QLabel(tr("Start Index:")), imgseq_row, 0);
|
||||
int 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_layout->addWidget(new QLabel(tr("Start Index:")), imgseq_row, 0);
|
||||
|
||||
imgseq_row++;
|
||||
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_layout->addWidget(new QLabel(tr("End Index:")), imgseq_row, 0);
|
||||
imgseq_row++;
|
||||
|
||||
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_layout->addWidget(new QLabel(tr("End Index:")), imgseq_row, 0);
|
||||
|
||||
imgseq_row++;
|
||||
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_layout->addWidget(new QLabel(tr("Frame Rate:")), imgseq_row, 0);
|
||||
imgseq_row++;
|
||||
|
||||
imgseq_frame_rate_ = new FrameRateComboBox();
|
||||
imgseq_frame_rate_->SetFrameRate(vp.frame_rate());
|
||||
imgseq_layout->addWidget(imgseq_frame_rate_, imgseq_row, 1);
|
||||
imgseq_layout->addWidget(new QLabel(tr("Frame Rate:")), imgseq_row, 0);
|
||||
|
||||
video_layout->addWidget(imgseq_group, row, 0, 1, 2);
|
||||
}
|
||||
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;
|
||||
QString set_colorspace;
|
||||
|
||||
if (video_color_space_->currentIndex() > 0) {
|
||||
set_colorspace = video_color_space_->currentText();
|
||||
}
|
||||
if (video_color_space_->currentIndex() > 0) {
|
||||
set_colorspace = video_color_space_->currentText();
|
||||
}
|
||||
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
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()
|
||||
|| color_range_combo_->currentData().toInt() != vp.color_range()) {
|
||||
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() ||
|
||||
color_range_combo_->currentData().toInt() != vp.color_range()) {
|
||||
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(),
|
||||
static_cast<VideoParams::ColorRange>(
|
||||
color_range_combo_->currentData().toInt())));
|
||||
}
|
||||
|
||||
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(),
|
||||
static_cast<VideoParams::ColorRange>(color_range_combo_->currentData().toInt())));
|
||||
}
|
||||
if (vp.video_type() == VideoParams::kVideoTypeImageSequence) {
|
||||
int64_t new_dur =
|
||||
imgseq_end_time_->GetValue() - imgseq_start_time_->GetValue() + 1;
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
VideoStreamProperties::VideoStreamChangeCommand::VideoStreamChangeCommand(Footage *footage,
|
||||
int video_index,
|
||||
bool premultiplied,
|
||||
QString colorspace,
|
||||
VideoParams::Interlacing interlacing,
|
||||
const rational &pixel_ar, VideoParams::ColorRange range) :
|
||||
footage_(footage),
|
||||
video_index_(video_index),
|
||||
new_premultiplied_(premultiplied),
|
||||
new_colorspace_(colorspace),
|
||||
new_interlacing_(interlacing),
|
||||
new_pixel_ar_(pixel_ar),
|
||||
new_range_(range)
|
||||
VideoStreamProperties::VideoStreamChangeCommand::VideoStreamChangeCommand(
|
||||
Footage *footage, int video_index, bool premultiplied, QString colorspace,
|
||||
VideoParams::Interlacing interlacing, const rational &pixel_ar,
|
||||
VideoParams::ColorRange range)
|
||||
: footage_(footage)
|
||||
, video_index_(video_index)
|
||||
, new_premultiplied_(premultiplied)
|
||||
, new_colorspace_(colorspace)
|
||||
, new_interlacing_(interlacing)
|
||||
, new_pixel_ar_(pixel_ar)
|
||||
, new_range_(range)
|
||||
{
|
||||
}
|
||||
|
||||
Project *VideoStreamProperties::VideoStreamChangeCommand::GetRelevantProject() const
|
||||
Project *
|
||||
VideoStreamProperties::VideoStreamChangeCommand::GetRelevantProject() const
|
||||
{
|
||||
return footage_->project();
|
||||
return footage_->project();
|
||||
}
|
||||
|
||||
void VideoStreamProperties::VideoStreamChangeCommand::redo()
|
||||
{
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
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();
|
||||
old_range_ = vp.color_range();
|
||||
old_premultiplied_ = vp.premultiplied_alpha();
|
||||
old_colorspace_ = vp.colorspace();
|
||||
old_interlacing_ = vp.interlacing();
|
||||
old_pixel_ar_ = vp.pixel_aspect_ratio();
|
||||
old_range_ = vp.color_range();
|
||||
|
||||
vp.set_premultiplied_alpha(new_premultiplied_);
|
||||
vp.set_colorspace(new_colorspace_);
|
||||
vp.set_interlacing(new_interlacing_);
|
||||
vp.set_pixel_aspect_ratio(new_pixel_ar_);
|
||||
vp.set_color_range(new_range_);
|
||||
vp.set_premultiplied_alpha(new_premultiplied_);
|
||||
vp.set_colorspace(new_colorspace_);
|
||||
vp.set_interlacing(new_interlacing_);
|
||||
vp.set_pixel_aspect_ratio(new_pixel_ar_);
|
||||
vp.set_color_range(new_range_);
|
||||
|
||||
footage_->SetVideoParams(vp, video_index_);
|
||||
footage_->SetVideoParams(vp, video_index_);
|
||||
}
|
||||
|
||||
void VideoStreamProperties::VideoStreamChangeCommand::undo()
|
||||
{
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
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_);
|
||||
vp.set_color_range(old_range_);
|
||||
vp.set_premultiplied_alpha(old_premultiplied_);
|
||||
vp.set_colorspace(old_colorspace_);
|
||||
vp.set_interlacing(old_interlacing_);
|
||||
vp.set_pixel_aspect_ratio(old_pixel_ar_);
|
||||
vp.set_color_range(old_range_);
|
||||
|
||||
footage_->SetVideoParams(vp, video_index_);
|
||||
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)
|
||||
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
|
||||
Project *
|
||||
VideoStreamProperties::ImageSequenceChangeCommand::GetRelevantProject() const
|
||||
{
|
||||
return footage_->project();
|
||||
return footage_->project();
|
||||
}
|
||||
|
||||
void VideoStreamProperties::ImageSequenceChangeCommand::redo()
|
||||
{
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
|
||||
old_start_index_ = vp.start_time();
|
||||
vp.set_start_time(new_start_index_);
|
||||
old_start_index_ = vp.start_time();
|
||||
vp.set_start_time(new_start_index_);
|
||||
|
||||
old_duration_ = vp.duration();
|
||||
vp.set_duration(new_duration_);
|
||||
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());
|
||||
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_);
|
||||
footage_->SetVideoParams(vp, video_index_);
|
||||
}
|
||||
|
||||
void VideoStreamProperties::ImageSequenceChangeCommand::undo()
|
||||
{
|
||||
VideoParams vp = footage_->GetVideoParams(video_index_);
|
||||
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());
|
||||
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_);
|
||||
footage_->SetVideoParams(vp, video_index_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,126 +29,119 @@
|
||||
#include "widget/slider/integerslider.h"
|
||||
#include "widget/standardcombos/standardcombos.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class VideoStreamProperties : public StreamProperties
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class VideoStreamProperties : public StreamProperties {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VideoStreamProperties(Footage *footage, int video_index);
|
||||
VideoStreamProperties(Footage *footage, int video_index);
|
||||
|
||||
virtual void Accept(MultiUndoCommand *parent) override;
|
||||
virtual void Accept(MultiUndoCommand *parent) override;
|
||||
|
||||
virtual bool SanityCheck() override;
|
||||
virtual bool SanityCheck() override;
|
||||
|
||||
private:
|
||||
Footage *footage_;
|
||||
Footage *footage_;
|
||||
|
||||
int video_index_;
|
||||
int video_index_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Setting for associated/premultiplied alpha
|
||||
*/
|
||||
QCheckBox* video_premultiply_alpha_;
|
||||
QCheckBox *video_premultiply_alpha_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Setting for this media's color space
|
||||
*/
|
||||
QComboBox* video_color_space_;
|
||||
QComboBox *video_color_space_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Setting for this streams's color range
|
||||
*/
|
||||
QComboBox *color_range_combo_;
|
||||
QComboBox *color_range_combo_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Setting for video interlacing
|
||||
*/
|
||||
InterlacedComboBox* video_interlace_combo_;
|
||||
InterlacedComboBox *video_interlace_combo_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Sets the start index for image sequences
|
||||
*/
|
||||
IntegerSlider* imgseq_start_time_;
|
||||
IntegerSlider *imgseq_start_time_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Sets the end index for image sequences
|
||||
*/
|
||||
IntegerSlider* imgseq_end_time_;
|
||||
IntegerSlider *imgseq_end_time_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Sets the frame rate for image sequences
|
||||
*/
|
||||
FrameRateComboBox* imgseq_frame_rate_;
|
||||
FrameRateComboBox *imgseq_frame_rate_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Sets the pixel aspect ratio of the stream
|
||||
*/
|
||||
PixelAspectRatioComboBox* pixel_aspect_combo_;
|
||||
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,
|
||||
VideoParams::ColorRange range);
|
||||
class VideoStreamChangeCommand : public UndoCommand {
|
||||
public:
|
||||
VideoStreamChangeCommand(Footage *footage, int video_index,
|
||||
bool premultiplied, QString colorspace,
|
||||
VideoParams::Interlacing interlacing,
|
||||
const rational &pixel_ar,
|
||||
VideoParams::ColorRange range);
|
||||
|
||||
virtual Project* GetRelevantProject() const override;
|
||||
virtual Project *GetRelevantProject() const override;
|
||||
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
|
||||
private:
|
||||
Footage *footage_;
|
||||
int video_index_;
|
||||
private:
|
||||
Footage *footage_;
|
||||
int video_index_;
|
||||
|
||||
bool new_premultiplied_;
|
||||
QString new_colorspace_;
|
||||
VideoParams::Interlacing new_interlacing_;
|
||||
rational new_pixel_ar_;
|
||||
VideoParams::ColorRange new_range_;
|
||||
bool new_premultiplied_;
|
||||
QString new_colorspace_;
|
||||
VideoParams::Interlacing new_interlacing_;
|
||||
rational new_pixel_ar_;
|
||||
VideoParams::ColorRange new_range_;
|
||||
|
||||
bool old_premultiplied_;
|
||||
QString old_colorspace_;
|
||||
VideoParams::Interlacing old_interlacing_;
|
||||
rational old_pixel_ar_;
|
||||
VideoParams::ColorRange old_range_;
|
||||
bool old_premultiplied_;
|
||||
QString old_colorspace_;
|
||||
VideoParams::Interlacing old_interlacing_;
|
||||
rational old_pixel_ar_;
|
||||
VideoParams::ColorRange old_range_;
|
||||
};
|
||||
|
||||
};
|
||||
class ImageSequenceChangeCommand : public UndoCommand {
|
||||
public:
|
||||
ImageSequenceChangeCommand(Footage *footage, int video_index,
|
||||
int64_t start_index, int64_t duration,
|
||||
const rational &frame_rate);
|
||||
|
||||
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 Project* GetRelevantProject() const override;
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
private:
|
||||
Footage *footage_;
|
||||
int video_index_;
|
||||
|
||||
private:
|
||||
Footage *footage_;
|
||||
int video_index_;
|
||||
int64_t new_start_index_;
|
||||
int64_t old_start_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_;
|
||||
|
||||
};
|
||||
int64_t new_duration_;
|
||||
int64_t old_duration_;
|
||||
|
||||
rational new_frame_rate_;
|
||||
rational old_frame_rate_;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,155 +29,160 @@
|
||||
#include <QScrollBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace olive {
|
||||
|
||||
FootageRelinkDialog::FootageRelinkDialog(const QVector<Footage *> &footage, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
footage_(footage)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
layout->addWidget(new QLabel("The following files couldn't be found. Clips using them will be "
|
||||
"unplayable until they're relinked."));
|
||||
FootageRelinkDialog::FootageRelinkDialog(const QVector<Footage *> &footage,
|
||||
QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, footage_(footage)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
table_ = new QTreeWidget();
|
||||
layout->addWidget(new QLabel(
|
||||
"The following files couldn't be found. Clips using them will be "
|
||||
"unplayable until they're relinked."));
|
||||
|
||||
table_->setColumnCount(3);
|
||||
table_->setHeaderLabels({tr("Footage"), tr("Filename"), tr("Actions")});
|
||||
table_->setRootIsDecorated(false);
|
||||
table_->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
table_->header()->setSectionsMovable(false);
|
||||
table_ = new QTreeWidget();
|
||||
|
||||
// Prefer stretching URL column (QHeaderView defaults to stretching the last column, which in
|
||||
// our case is just a browse button)
|
||||
table_->header()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
table_->header()->setStretchLastSection(false);
|
||||
table_->setColumnCount(3);
|
||||
table_->setHeaderLabels({ tr("Footage"), tr("Filename"), tr("Actions") });
|
||||
table_->setRootIsDecorated(false);
|
||||
table_->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
table_->header()->setSectionsMovable(false);
|
||||
|
||||
for (int i=0; i<footage.size(); i++) {
|
||||
Footage* f = footage.at(i);
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
// Prefer stretching URL column (QHeaderView defaults to stretching the last column, which in
|
||||
// our case is just a browse button)
|
||||
table_->header()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
table_->header()->setStretchLastSection(false);
|
||||
|
||||
QWidget* item_actions = new QWidget();
|
||||
QHBoxLayout* item_actions_layout = new QHBoxLayout(item_actions);
|
||||
QPushButton* item_browse_btn = new QPushButton(tr("Browse"));
|
||||
item_browse_btn->setProperty("index", i);
|
||||
connect(item_browse_btn, &QPushButton::clicked, this, &FootageRelinkDialog::BrowseForFootage);
|
||||
item_actions_layout->addWidget(item_browse_btn);
|
||||
for (int i = 0; i < footage.size(); i++) {
|
||||
Footage *f = footage.at(i);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
|
||||
item->setIcon(0, f->data(Node::ICON).value<QIcon>());
|
||||
item->setText(0, f->GetLabel());
|
||||
item->setText(1, f->filename());
|
||||
QWidget *item_actions = new QWidget();
|
||||
QHBoxLayout *item_actions_layout = new QHBoxLayout(item_actions);
|
||||
QPushButton *item_browse_btn = new QPushButton(tr("Browse"));
|
||||
item_browse_btn->setProperty("index", i);
|
||||
connect(item_browse_btn, &QPushButton::clicked, this,
|
||||
&FootageRelinkDialog::BrowseForFootage);
|
||||
item_actions_layout->addWidget(item_browse_btn);
|
||||
|
||||
table_->addTopLevelItem(item);
|
||||
item->setIcon(0, f->data(Node::ICON).value<QIcon>());
|
||||
item->setText(0, f->GetLabel());
|
||||
item->setText(1, f->filename());
|
||||
|
||||
table_->setItemWidget(item, 2, item_actions);
|
||||
}
|
||||
table_->addTopLevelItem(item);
|
||||
|
||||
layout->addWidget(table_);
|
||||
table_->setItemWidget(item, 2, item_actions);
|
||||
}
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &FootageRelinkDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &FootageRelinkDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
setWindowTitle(tr("Relink Footage"));
|
||||
layout->addWidget(table_);
|
||||
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this,
|
||||
&FootageRelinkDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this,
|
||||
&FootageRelinkDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
setWindowTitle(tr("Relink Footage"));
|
||||
}
|
||||
|
||||
void FootageRelinkDialog::UpdateFootageItem(int index)
|
||||
{
|
||||
Footage* f = footage_.at(index);
|
||||
QTreeWidgetItem* item = table_->topLevelItem(index);
|
||||
item->setIcon(0, f->data(Node::ICON).value<QIcon>());
|
||||
item->setText(1, f->filename());
|
||||
Footage *f = footage_.at(index);
|
||||
QTreeWidgetItem *item = table_->topLevelItem(index);
|
||||
item->setIcon(0, f->data(Node::ICON).value<QIcon>());
|
||||
item->setText(1, f->filename());
|
||||
}
|
||||
|
||||
void FootageRelinkDialog::BrowseForFootage()
|
||||
{
|
||||
int index = sender()->property("index").toInt();
|
||||
Footage* f = footage_.at(index);
|
||||
int index = sender()->property("index").toInt();
|
||||
Footage *f = footage_.at(index);
|
||||
|
||||
QFileInfo info(f->filename());
|
||||
QFileInfo info(f->filename());
|
||||
|
||||
QString new_fn = QFileDialog::getOpenFileName(this,
|
||||
tr("Relink \"%1\"").arg(f->GetLabel()),
|
||||
info.absolutePath());
|
||||
QString new_fn = QFileDialog::getOpenFileName(
|
||||
this, tr("Relink \"%1\"").arg(f->GetLabel()), info.absolutePath());
|
||||
|
||||
// Originally, this function would attempt to filter to the exact filename of the missing file.
|
||||
// However, this would break on Windows if the filename had any spaces in it. The reason is
|
||||
// Windows separates its extensions with ';' while Qt separates them with ' '. Qt isn't
|
||||
// intelligent enough to determine whether it's a list of extensions or a single filename with a
|
||||
// space in it, it just does a global replace of ' ' to ';'. There's no way around it, outside of
|
||||
// bypassing Qt entirely and using Win32's GetOpenFileName() directly. As annoying as it is, I've
|
||||
// just disabled it for now.
|
||||
//QStringLiteral("%1 (\"%1\");;%2 (*)").arg(info.fileName(), tr("All Files")));
|
||||
// Originally, this function would attempt to filter to the exact filename of the missing file.
|
||||
// However, this would break on Windows if the filename had any spaces in it. The reason is
|
||||
// Windows separates its extensions with ';' while Qt separates them with ' '. Qt isn't
|
||||
// intelligent enough to determine whether it's a list of extensions or a single filename with a
|
||||
// space in it, it just does a global replace of ' ' to ';'. There's no way around it, outside of
|
||||
// bypassing Qt entirely and using Win32's GetOpenFileName() directly. As annoying as it is, I've
|
||||
// just disabled it for now.
|
||||
//QStringLiteral("%1 (\"%1\");;%2 (*)").arg(info.fileName(), tr("All Files")));
|
||||
|
||||
// We received a new filename
|
||||
if (!new_fn.isEmpty()) {
|
||||
// Store original dir since we might be able to use this to find other files
|
||||
QDir original_dir = info.dir();
|
||||
QDir new_dir = QFileInfo(new_fn).dir();
|
||||
// We received a new filename
|
||||
if (!new_fn.isEmpty()) {
|
||||
// Store original dir since we might be able to use this to find other files
|
||||
QDir original_dir = info.dir();
|
||||
QDir new_dir = QFileInfo(new_fn).dir();
|
||||
|
||||
// Set new filename since this was set manually by the user
|
||||
f->set_filename(new_fn);
|
||||
// Set new filename since this was set manually by the user
|
||||
f->set_filename(new_fn);
|
||||
|
||||
// Assume footage is valid here. We could do some decoder probing to ensure it's a usable file
|
||||
// but otherwise we assume the user knows what they're doing here.
|
||||
// Assume footage is valid here. We could do some decoder probing to ensure it's a usable file
|
||||
// but otherwise we assume the user knows what they're doing here.
|
||||
|
||||
// Set footage to valid and update icon
|
||||
f->SetValid();
|
||||
// Set footage to valid and update icon
|
||||
f->SetValid();
|
||||
|
||||
// Update item visually
|
||||
UpdateFootageItem(index);
|
||||
// Update item visually
|
||||
UpdateFootageItem(index);
|
||||
|
||||
// Check all other footage files for matches
|
||||
for (int it=0; it<footage_.size(); it++) {
|
||||
Footage* other_footage = footage_.at(it);
|
||||
// Check all other footage files for matches
|
||||
for (int it = 0; it < footage_.size(); it++) {
|
||||
Footage *other_footage = footage_.at(it);
|
||||
|
||||
// Ignore current footage file and footage that's already valid of course
|
||||
if (index != it && !other_footage->IsValid()) {
|
||||
// Get footage path relative to original directory
|
||||
QString relative_to_original = original_dir.relativeFilePath(other_footage->filename());
|
||||
QString absolute_to_new = new_dir.filePath(relative_to_original);
|
||||
// Ignore current footage file and footage that's already valid of course
|
||||
if (index != it && !other_footage->IsValid()) {
|
||||
// Get footage path relative to original directory
|
||||
QString relative_to_original =
|
||||
original_dir.relativeFilePath(other_footage->filename());
|
||||
QString absolute_to_new =
|
||||
new_dir.filePath(relative_to_original);
|
||||
|
||||
// Second attempt. Try appending the filename to our new filepath
|
||||
if (!QFileInfo::exists(absolute_to_new)) {
|
||||
QFileInfo file_info(other_footage->filename());
|
||||
absolute_to_new = new_dir.filePath(file_info.fileName());
|
||||
}
|
||||
// Second attempt. Try appending the filename to our new filepath
|
||||
if (!QFileInfo::exists(absolute_to_new)) {
|
||||
QFileInfo file_info(other_footage->filename());
|
||||
absolute_to_new = new_dir.filePath(file_info.fileName());
|
||||
}
|
||||
|
||||
// Check if file exists
|
||||
if (QFileInfo::exists(absolute_to_new)) {
|
||||
other_footage->set_filename(absolute_to_new);
|
||||
other_footage->SetValid();
|
||||
UpdateFootageItem(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if file exists
|
||||
if (QFileInfo::exists(absolute_to_new)) {
|
||||
other_footage->set_filename(absolute_to_new);
|
||||
other_footage->SetValid();
|
||||
UpdateFootageItem(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check where the next invalid footage is. If there is none, accept automatically. Otherwise,
|
||||
// jump to that footage so the user knows where it is.
|
||||
int next_invalid = -1;
|
||||
for (int i=0; i<footage_.size(); i++) {
|
||||
if (!footage_.at(i)->IsValid()) {
|
||||
next_invalid = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check where the next invalid footage is. If there is none, accept automatically. Otherwise,
|
||||
// jump to that footage so the user knows where it is.
|
||||
int next_invalid = -1;
|
||||
for (int i = 0; i < footage_.size(); i++) {
|
||||
if (!footage_.at(i)->IsValid()) {
|
||||
next_invalid = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (next_invalid == -1) {
|
||||
// No more invalid footage, just accept
|
||||
this->accept();
|
||||
} else {
|
||||
// Jump to next invalid footage
|
||||
QModelIndex idx = table_->model()->index(next_invalid, 0);
|
||||
table_->selectionModel()->select(idx,
|
||||
QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
table_->scrollTo(idx);
|
||||
|
||||
}
|
||||
if (next_invalid == -1) {
|
||||
// No more invalid footage, just accept
|
||||
this->accept();
|
||||
} else {
|
||||
// Jump to next invalid footage
|
||||
QModelIndex idx = table_->model()->index(next_invalid, 0);
|
||||
table_->selectionModel()->select(idx, QItemSelectionModel::Select |
|
||||
QItemSelectionModel::Rows);
|
||||
table_->scrollTo(idx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,24 +26,24 @@
|
||||
|
||||
#include "node/project/footage/footage.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class FootageRelinkDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class FootageRelinkDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FootageRelinkDialog(const QVector<Footage*>& footage, QWidget* parent = nullptr);
|
||||
FootageRelinkDialog(const QVector<Footage *> &footage,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void UpdateFootageItem(int index);
|
||||
void UpdateFootageItem(int index);
|
||||
|
||||
QTreeWidget* table_;
|
||||
QTreeWidget *table_;
|
||||
|
||||
QVector<Footage*> footage_;
|
||||
QVector<Footage *> footage_;
|
||||
|
||||
private slots:
|
||||
void BrowseForFootage();
|
||||
|
||||
void BrowseForFootage();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -27,215 +27,230 @@
|
||||
#include "node/nodeundo.h"
|
||||
#include "widget/keyframeview/keyframeviewundo.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
KeyframePropertiesDialog::KeyframePropertiesDialog(const std::vector<NodeKeyframe*> &keys, const rational &timebase, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
keys_(keys),
|
||||
timebase_(timebase)
|
||||
namespace olive
|
||||
{
|
||||
setWindowTitle(tr("Keyframe Properties"));
|
||||
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
KeyframePropertiesDialog::KeyframePropertiesDialog(
|
||||
const std::vector<NodeKeyframe *> &keys, const rational &timebase,
|
||||
QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, keys_(keys)
|
||||
, timebase_(timebase)
|
||||
{
|
||||
setWindowTitle(tr("Keyframe Properties"));
|
||||
|
||||
int row = 0;
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
layout->addWidget(new QLabel("Time:"), row, 0);
|
||||
int row = 0;
|
||||
|
||||
time_slider_ = new RationalSlider();
|
||||
time_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
time_slider_->SetTimebase(timebase_);
|
||||
layout->addWidget(time_slider_, row, 1);
|
||||
layout->addWidget(new QLabel("Time:"), row, 0);
|
||||
|
||||
row++;
|
||||
time_slider_ = new RationalSlider();
|
||||
time_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
time_slider_->SetTimebase(timebase_);
|
||||
layout->addWidget(time_slider_, row, 1);
|
||||
|
||||
layout->addWidget(new QLabel("Type:"), row, 0);
|
||||
row++;
|
||||
|
||||
type_select_ = new QComboBox();
|
||||
connect(type_select_, SIGNAL(currentIndexChanged(int)), this, SLOT(KeyTypeChanged(int)));
|
||||
layout->addWidget(type_select_, row, 1);
|
||||
layout->addWidget(new QLabel("Type:"), row, 0);
|
||||
|
||||
row++;
|
||||
type_select_ = new QComboBox();
|
||||
connect(type_select_, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(KeyTypeChanged(int)));
|
||||
layout->addWidget(type_select_, row, 1);
|
||||
|
||||
// Bezier handles
|
||||
bezier_group_ = new QGroupBox();
|
||||
row++;
|
||||
|
||||
QGridLayout* bezier_group_layout = new QGridLayout(bezier_group_);
|
||||
// Bezier handles
|
||||
bezier_group_ = new QGroupBox();
|
||||
|
||||
bezier_group_layout->addWidget(new QLabel(tr("In:")), 0, 0);
|
||||
QGridLayout *bezier_group_layout = new QGridLayout(bezier_group_);
|
||||
|
||||
bezier_in_x_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_in_x_slider_, 0, 1);
|
||||
bezier_group_layout->addWidget(new QLabel(tr("In:")), 0, 0);
|
||||
|
||||
bezier_in_y_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_in_y_slider_, 0, 2);
|
||||
bezier_in_x_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_in_x_slider_, 0, 1);
|
||||
|
||||
bezier_group_layout->addWidget(new QLabel(tr("Out:")), 1, 0);
|
||||
bezier_in_y_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_in_y_slider_, 0, 2);
|
||||
|
||||
bezier_out_x_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_out_x_slider_, 1, 1);
|
||||
bezier_group_layout->addWidget(new QLabel(tr("Out:")), 1, 0);
|
||||
|
||||
bezier_out_y_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_out_y_slider_, 1, 2);
|
||||
bezier_out_x_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_out_x_slider_, 1, 1);
|
||||
|
||||
layout->addWidget(bezier_group_, row, 0, 1, 2);
|
||||
bezier_out_y_slider_ = new FloatSlider();
|
||||
bezier_group_layout->addWidget(bezier_out_y_slider_, 1, 2);
|
||||
|
||||
bool all_same_time = true;
|
||||
bool can_set_time = true;
|
||||
layout->addWidget(bezier_group_, row, 0, 1, 2);
|
||||
|
||||
bool all_same_type = true;
|
||||
bool all_same_time = true;
|
||||
bool can_set_time = true;
|
||||
|
||||
bool all_same_bezier_in_x = true;
|
||||
bool all_same_bezier_in_y = true;
|
||||
bool all_same_bezier_out_x = true;
|
||||
bool all_same_bezier_out_y = true;
|
||||
bool all_same_type = true;
|
||||
|
||||
for (size_t i=0;i<keys_.size();i++) {
|
||||
if (i > 0) {
|
||||
NodeKeyframe* prev_key = keys_.at(i-1);
|
||||
NodeKeyframe* this_key = keys_.at(i);
|
||||
bool all_same_bezier_in_x = true;
|
||||
bool all_same_bezier_in_y = true;
|
||||
bool all_same_bezier_out_x = true;
|
||||
bool all_same_bezier_out_y = true;
|
||||
|
||||
// Determine if the keyframes are all the same time or not
|
||||
if (all_same_time) {
|
||||
all_same_time = (prev_key->time() == this_key->time());
|
||||
}
|
||||
for (size_t i = 0; i < keys_.size(); i++) {
|
||||
if (i > 0) {
|
||||
NodeKeyframe *prev_key = keys_.at(i - 1);
|
||||
NodeKeyframe *this_key = keys_.at(i);
|
||||
|
||||
// Determine if the keyframes are all the same type
|
||||
if (all_same_type) {
|
||||
all_same_type = (prev_key->type() == this_key->type());
|
||||
}
|
||||
// Determine if the keyframes are all the same time or not
|
||||
if (all_same_time) {
|
||||
all_same_time = (prev_key->time() == this_key->time());
|
||||
}
|
||||
|
||||
// Check all four bezier control points
|
||||
if (all_same_bezier_in_x) {
|
||||
all_same_bezier_in_x = (prev_key->bezier_control_in().x() == this_key->bezier_control_in().x());
|
||||
}
|
||||
// Determine if the keyframes are all the same type
|
||||
if (all_same_type) {
|
||||
all_same_type = (prev_key->type() == this_key->type());
|
||||
}
|
||||
|
||||
if (all_same_bezier_in_y) {
|
||||
all_same_bezier_in_y = (prev_key->bezier_control_in().y() == this_key->bezier_control_in().y());
|
||||
}
|
||||
// Check all four bezier control points
|
||||
if (all_same_bezier_in_x) {
|
||||
all_same_bezier_in_x = (prev_key->bezier_control_in().x() ==
|
||||
this_key->bezier_control_in().x());
|
||||
}
|
||||
|
||||
if (all_same_bezier_out_x) {
|
||||
all_same_bezier_out_x = (prev_key->bezier_control_out().x() == this_key->bezier_control_out().x());
|
||||
}
|
||||
if (all_same_bezier_in_y) {
|
||||
all_same_bezier_in_y = (prev_key->bezier_control_in().y() ==
|
||||
this_key->bezier_control_in().y());
|
||||
}
|
||||
|
||||
if (all_same_bezier_out_y) {
|
||||
all_same_bezier_out_y = (prev_key->bezier_control_out().y() == this_key->bezier_control_out().y());
|
||||
}
|
||||
}
|
||||
if (all_same_bezier_out_x) {
|
||||
all_same_bezier_out_x = (prev_key->bezier_control_out().x() ==
|
||||
this_key->bezier_control_out().x());
|
||||
}
|
||||
|
||||
// Determine if any keyframes are on the same track (in which case we can't set the time)
|
||||
if (can_set_time) {
|
||||
for (size_t j=0;j<keys_.size();j++) {
|
||||
if (i != j
|
||||
&& keys_.at(j)->track() == keys_.at(i)->track()) {
|
||||
can_set_time = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (all_same_bezier_out_y) {
|
||||
all_same_bezier_out_y = (prev_key->bezier_control_out().y() ==
|
||||
this_key->bezier_control_out().y());
|
||||
}
|
||||
}
|
||||
|
||||
if (!all_same_time
|
||||
&& !all_same_type
|
||||
&& !can_set_time
|
||||
&& !all_same_bezier_in_x
|
||||
&& !all_same_bezier_in_y
|
||||
&& !all_same_bezier_out_x
|
||||
&& !all_same_bezier_out_y) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Determine if any keyframes are on the same track (in which case we can't set the time)
|
||||
if (can_set_time) {
|
||||
for (size_t j = 0; j < keys_.size(); j++) {
|
||||
if (i != j && keys_.at(j)->track() == keys_.at(i)->track()) {
|
||||
can_set_time = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (all_same_time) {
|
||||
time_slider_->SetValue(keys_.front()->time());
|
||||
} else {
|
||||
time_slider_->SetTristate();
|
||||
}
|
||||
if (!all_same_time && !all_same_type && !can_set_time &&
|
||||
!all_same_bezier_in_x && !all_same_bezier_in_y &&
|
||||
!all_same_bezier_out_x && !all_same_bezier_out_y) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
time_slider_->setEnabled(can_set_time);
|
||||
if (all_same_time) {
|
||||
time_slider_->SetValue(keys_.front()->time());
|
||||
} else {
|
||||
time_slider_->SetTristate();
|
||||
}
|
||||
|
||||
if (!all_same_type) {
|
||||
// If all keyframes aren't the same type, add an empty item
|
||||
type_select_->addItem(QStringLiteral("--"), -1);
|
||||
time_slider_->setEnabled(can_set_time);
|
||||
|
||||
// Ensure UI updates for the index being 0
|
||||
KeyTypeChanged(0);
|
||||
}
|
||||
if (!all_same_type) {
|
||||
// If all keyframes aren't the same type, add an empty item
|
||||
type_select_->addItem(QStringLiteral("--"), -1);
|
||||
|
||||
type_select_->addItem(tr("Linear"), NodeKeyframe::kLinear);
|
||||
type_select_->addItem(tr("Hold"), NodeKeyframe::kHold);
|
||||
type_select_->addItem(tr("Bezier"), NodeKeyframe::kBezier);
|
||||
// Ensure UI updates for the index being 0
|
||||
KeyTypeChanged(0);
|
||||
}
|
||||
|
||||
if (all_same_type) {
|
||||
// If all keyframes are the same type, set it here
|
||||
for (int i=0;i<type_select_->count();i++) {
|
||||
if (type_select_->itemData(i).toInt() == keys_.front()->type()) {
|
||||
type_select_->setCurrentIndex(i);
|
||||
type_select_->addItem(tr("Linear"), NodeKeyframe::kLinear);
|
||||
type_select_->addItem(tr("Hold"), NodeKeyframe::kHold);
|
||||
type_select_->addItem(tr("Bezier"), NodeKeyframe::kBezier);
|
||||
|
||||
// Ensure UI updates for this index
|
||||
KeyTypeChanged(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (all_same_type) {
|
||||
// If all keyframes are the same type, set it here
|
||||
for (int i = 0; i < type_select_->count(); i++) {
|
||||
if (type_select_->itemData(i).toInt() == keys_.front()->type()) {
|
||||
type_select_->setCurrentIndex(i);
|
||||
|
||||
SetUpBezierSlider(bezier_in_x_slider_, all_same_bezier_in_x, keys_.front()->bezier_control_in().x());
|
||||
SetUpBezierSlider(bezier_in_y_slider_, all_same_bezier_in_y, keys_.front()->bezier_control_in().y());
|
||||
SetUpBezierSlider(bezier_out_x_slider_, all_same_bezier_out_x, keys_.front()->bezier_control_out().x());
|
||||
SetUpBezierSlider(bezier_out_y_slider_, all_same_bezier_out_y, keys_.front()->bezier_control_out().y());
|
||||
// Ensure UI updates for this index
|
||||
KeyTypeChanged(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
row++;
|
||||
SetUpBezierSlider(bezier_in_x_slider_, all_same_bezier_in_x,
|
||||
keys_.front()->bezier_control_in().x());
|
||||
SetUpBezierSlider(bezier_in_y_slider_, all_same_bezier_in_y,
|
||||
keys_.front()->bezier_control_in().y());
|
||||
SetUpBezierSlider(bezier_out_x_slider_, all_same_bezier_out_x,
|
||||
keys_.front()->bezier_control_out().x());
|
||||
SetUpBezierSlider(bezier_out_y_slider_, all_same_bezier_out_y,
|
||||
keys_.front()->bezier_control_out().y());
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
void KeyframePropertiesDialog::accept()
|
||||
{
|
||||
MultiUndoCommand* command = new MultiUndoCommand();
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
|
||||
rational new_time = time_slider_->GetValue();
|
||||
int new_type = type_select_->currentData().toInt();
|
||||
rational new_time = time_slider_->GetValue();
|
||||
int new_type = type_select_->currentData().toInt();
|
||||
|
||||
foreach (NodeKeyframe* key, keys_) {
|
||||
if (time_slider_->isEnabled() && !time_slider_->IsTristate()) {
|
||||
command->add_child(new NodeParamSetKeyframeTimeCommand(key, new_time));
|
||||
}
|
||||
foreach (NodeKeyframe *key, keys_) {
|
||||
if (time_slider_->isEnabled() && !time_slider_->IsTristate()) {
|
||||
command->add_child(
|
||||
new NodeParamSetKeyframeTimeCommand(key, new_time));
|
||||
}
|
||||
|
||||
if (new_type > -1) {
|
||||
command->add_child(new KeyframeSetTypeCommand(key, static_cast<NodeKeyframe::Type>(new_type)));
|
||||
}
|
||||
if (new_type > -1) {
|
||||
command->add_child(new KeyframeSetTypeCommand(
|
||||
key, static_cast<NodeKeyframe::Type>(new_type)));
|
||||
}
|
||||
|
||||
if (bezier_group_->isEnabled()) {
|
||||
command->add_child(new KeyframeSetBezierControlPoint(key,
|
||||
NodeKeyframe::kInHandle,
|
||||
QPointF(bezier_in_x_slider_->GetValue(), bezier_in_y_slider_->GetValue())));
|
||||
if (bezier_group_->isEnabled()) {
|
||||
command->add_child(new KeyframeSetBezierControlPoint(
|
||||
key, NodeKeyframe::kInHandle,
|
||||
QPointF(bezier_in_x_slider_->GetValue(),
|
||||
bezier_in_y_slider_->GetValue())));
|
||||
|
||||
command->add_child(new KeyframeSetBezierControlPoint(key,
|
||||
NodeKeyframe::kOutHandle,
|
||||
QPointF(bezier_out_x_slider_->GetValue(), bezier_out_y_slider_->GetValue())));
|
||||
}
|
||||
}
|
||||
command->add_child(new KeyframeSetBezierControlPoint(
|
||||
key, NodeKeyframe::kOutHandle,
|
||||
QPointF(bezier_out_x_slider_->GetValue(),
|
||||
bezier_out_y_slider_->GetValue())));
|
||||
}
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command, tr("Set Keyframe Properties"));
|
||||
Core::instance()->undo_stack()->push(command,
|
||||
tr("Set Keyframe Properties"));
|
||||
|
||||
QDialog::accept();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void KeyframePropertiesDialog::SetUpBezierSlider(FloatSlider *slider, bool all_same, double value)
|
||||
void KeyframePropertiesDialog::SetUpBezierSlider(FloatSlider *slider,
|
||||
bool all_same, double value)
|
||||
{
|
||||
if (all_same) {
|
||||
slider->SetValue(value);
|
||||
} else {
|
||||
slider->SetTristate();
|
||||
}
|
||||
if (all_same) {
|
||||
slider->SetValue(value);
|
||||
} else {
|
||||
slider->SetTristate();
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframePropertiesDialog::KeyTypeChanged(int index)
|
||||
{
|
||||
bezier_group_->setEnabled(type_select_->itemData(index) == NodeKeyframe::kBezier);
|
||||
bezier_group_->setEnabled(type_select_->itemData(index) ==
|
||||
NodeKeyframe::kBezier);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,41 +29,42 @@
|
||||
#include "widget/slider/floatslider.h"
|
||||
#include "widget/slider/rationalslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class KeyframePropertiesDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class KeyframePropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
KeyframePropertiesDialog(const std::vector<NodeKeyframe*>& keys, const rational& timebase, QWidget* parent = nullptr);
|
||||
KeyframePropertiesDialog(const std::vector<NodeKeyframe *> &keys,
|
||||
const rational &timebase,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
void SetUpBezierSlider(FloatSlider *slider, bool all_same, double value);
|
||||
void SetUpBezierSlider(FloatSlider *slider, bool all_same, double value);
|
||||
|
||||
const std::vector<NodeKeyframe*>& keys_;
|
||||
const std::vector<NodeKeyframe *> &keys_;
|
||||
|
||||
rational timebase_;
|
||||
rational timebase_;
|
||||
|
||||
RationalSlider* time_slider_;
|
||||
RationalSlider *time_slider_;
|
||||
|
||||
QComboBox* type_select_;
|
||||
QComboBox *type_select_;
|
||||
|
||||
QGroupBox* bezier_group_;
|
||||
QGroupBox *bezier_group_;
|
||||
|
||||
FloatSlider* bezier_in_x_slider_;
|
||||
FloatSlider *bezier_in_x_slider_;
|
||||
|
||||
FloatSlider* bezier_in_y_slider_;
|
||||
FloatSlider *bezier_in_y_slider_;
|
||||
|
||||
FloatSlider* bezier_out_x_slider_;
|
||||
FloatSlider *bezier_out_x_slider_;
|
||||
|
||||
FloatSlider* bezier_out_y_slider_;
|
||||
FloatSlider *bezier_out_y_slider_;
|
||||
|
||||
private slots:
|
||||
void KeyTypeChanged(int index);
|
||||
|
||||
void KeyTypeChanged(int index);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,128 +28,139 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super QDialog
|
||||
|
||||
MarkerPropertiesDialog::MarkerPropertiesDialog(const std::vector<TimelineMarker *> &markers, const rational &timebase, QWidget *parent) :
|
||||
super(parent),
|
||||
markers_(markers)
|
||||
MarkerPropertiesDialog::MarkerPropertiesDialog(
|
||||
const std::vector<TimelineMarker *> &markers, const rational &timebase,
|
||||
QWidget *parent)
|
||||
: super(parent)
|
||||
, markers_(markers)
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
QGroupBox *time_group = new QGroupBox(tr("Time"));
|
||||
QGridLayout *time_layout = new QGridLayout(time_group);
|
||||
QGroupBox *time_group = new QGroupBox(tr("Time"));
|
||||
QGridLayout *time_layout = new QGridLayout(time_group);
|
||||
|
||||
{
|
||||
int time_row = 0;
|
||||
{
|
||||
int time_row = 0;
|
||||
|
||||
time_layout->addWidget(new QLabel(tr("In:")), time_row, 0);
|
||||
time_layout->addWidget(new QLabel(tr("In:")), time_row, 0);
|
||||
|
||||
in_slider_ = new RationalSlider();
|
||||
time_layout->addWidget(in_slider_, time_row, 1);
|
||||
in_slider_ = new RationalSlider();
|
||||
time_layout->addWidget(in_slider_, time_row, 1);
|
||||
|
||||
time_row++;
|
||||
time_row++;
|
||||
|
||||
time_layout->addWidget(new QLabel(tr("Out:")), time_row, 0);
|
||||
time_layout->addWidget(new QLabel(tr("Out:")), time_row, 0);
|
||||
|
||||
out_slider_ = new RationalSlider();
|
||||
time_layout->addWidget(out_slider_, time_row, 1);
|
||||
}
|
||||
out_slider_ = new RationalSlider();
|
||||
time_layout->addWidget(out_slider_, time_row, 1);
|
||||
}
|
||||
|
||||
if (markers.size() == 1) {
|
||||
in_slider_->SetValue(markers.front()->time().in());
|
||||
in_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
in_slider_->SetTimebase(timebase);
|
||||
out_slider_->SetValue(markers.front()->time().out());
|
||||
out_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
out_slider_->SetTimebase(timebase);
|
||||
} else {
|
||||
// Markers cannot be on the same time, so we disable setting time if multiple markers are selected
|
||||
in_slider_->setEnabled(false);
|
||||
in_slider_->SetTristate();
|
||||
out_slider_->setEnabled(false);
|
||||
out_slider_->SetTristate();
|
||||
}
|
||||
if (markers.size() == 1) {
|
||||
in_slider_->SetValue(markers.front()->time().in());
|
||||
in_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
in_slider_->SetTimebase(timebase);
|
||||
out_slider_->SetValue(markers.front()->time().out());
|
||||
out_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
out_slider_->SetTimebase(timebase);
|
||||
} else {
|
||||
// Markers cannot be on the same time, so we disable setting time if multiple markers are selected
|
||||
in_slider_->setEnabled(false);
|
||||
in_slider_->SetTristate();
|
||||
out_slider_->setEnabled(false);
|
||||
out_slider_->SetTristate();
|
||||
}
|
||||
|
||||
layout->addWidget(time_group, row, 0, 1, 2);
|
||||
layout->addWidget(time_group, row, 0, 1, 2);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Color:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Color:")), row, 0);
|
||||
|
||||
color_menu_ = new ColorCodingComboBox();
|
||||
layout->addWidget(color_menu_, row, 1);
|
||||
color_menu_ = new ColorCodingComboBox();
|
||||
layout->addWidget(color_menu_, row, 1);
|
||||
|
||||
color_menu_->SetColor(markers.front()->color());
|
||||
for (size_t i=1; i<markers.size(); i++) {
|
||||
if (markers.at(i)->color() != color_menu_->GetSelectedColor()) {
|
||||
color_menu_->SetColor(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
color_menu_->SetColor(markers.front()->color());
|
||||
for (size_t i = 1; i < markers.size(); i++) {
|
||||
if (markers.at(i)->color() != color_menu_->GetSelectedColor()) {
|
||||
color_menu_->SetColor(-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
layout->addWidget(new QLabel(tr("Name:")), row, 0);
|
||||
layout->addWidget(new QLabel(tr("Name:")), row, 0);
|
||||
|
||||
label_edit_ = new LineEditWithFocusSignal();
|
||||
connect(label_edit_, &LineEditWithFocusSignal::Focused, this, [this]{
|
||||
label_edit_->setPlaceholderText(QString());
|
||||
});
|
||||
layout->addWidget(label_edit_, row, 1);
|
||||
label_edit_ = new LineEditWithFocusSignal();
|
||||
connect(label_edit_, &LineEditWithFocusSignal::Focused, this,
|
||||
[this] { label_edit_->setPlaceholderText(QString()); });
|
||||
layout->addWidget(label_edit_, row, 1);
|
||||
|
||||
// Determine what the startup label text should be
|
||||
label_edit_->setText(markers.front()->name());
|
||||
for (size_t i=1; i<markers.size(); i++) {
|
||||
if (markers.at(i)->name() != label_edit_->text()) {
|
||||
label_edit_->clear();
|
||||
label_edit_->setPlaceholderText(tr("(multiple)"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Determine what the startup label text should be
|
||||
label_edit_->setText(markers.front()->name());
|
||||
for (size_t i = 1; i < markers.size(); i++) {
|
||||
if (markers.at(i)->name() != label_edit_->text()) {
|
||||
label_edit_->clear();
|
||||
label_edit_->setPlaceholderText(tr("(multiple)"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &MarkerPropertiesDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &MarkerPropertiesDialog::reject);
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this,
|
||||
&MarkerPropertiesDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this,
|
||||
&MarkerPropertiesDialog::reject);
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
|
||||
setWindowTitle(tr("Edit Markers"));
|
||||
label_edit_->setFocus();
|
||||
setWindowTitle(tr("Edit Markers"));
|
||||
label_edit_->setFocus();
|
||||
}
|
||||
|
||||
void MarkerPropertiesDialog::accept()
|
||||
{
|
||||
if (in_slider_->isEnabled() && in_slider_->GetValue() > out_slider_->GetValue()) {
|
||||
QMessageBox::critical(this, tr("Invalid Values"), tr("In point must be less than or equal to out point."));
|
||||
return;
|
||||
}
|
||||
if (in_slider_->isEnabled() &&
|
||||
in_slider_->GetValue() > out_slider_->GetValue()) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Invalid Values"),
|
||||
tr("In point must be less than or equal to out point."));
|
||||
return;
|
||||
}
|
||||
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
|
||||
int color = color_menu_->GetSelectedColor();
|
||||
int color = color_menu_->GetSelectedColor();
|
||||
|
||||
foreach (TimelineMarker *m, markers_) {
|
||||
if (color != -1) {
|
||||
command->add_child(new MarkerChangeColorCommand(m, color));
|
||||
}
|
||||
foreach (TimelineMarker *m, markers_) {
|
||||
if (color != -1) {
|
||||
command->add_child(new MarkerChangeColorCommand(m, color));
|
||||
}
|
||||
|
||||
if (label_edit_->placeholderText().isEmpty()) {
|
||||
command->add_child(new MarkerChangeNameCommand(m, label_edit_->text()));
|
||||
}
|
||||
}
|
||||
if (label_edit_->placeholderText().isEmpty()) {
|
||||
command->add_child(
|
||||
new MarkerChangeNameCommand(m, label_edit_->text()));
|
||||
}
|
||||
}
|
||||
|
||||
if (markers_.size() == 1) {
|
||||
command->add_child(new MarkerChangeTimeCommand(markers_.front(), TimeRange(in_slider_->GetValue(), out_slider_->GetValue())));
|
||||
}
|
||||
if (markers_.size() == 1) {
|
||||
command->add_child(new MarkerChangeTimeCommand(
|
||||
markers_.front(),
|
||||
TimeRange(in_slider_->GetValue(), out_slider_->GetValue())));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->push(command, tr("Set Marker Properties"));
|
||||
Core::instance()->undo_stack()->push(command, tr("Set Marker Properties"));
|
||||
|
||||
super::accept();
|
||||
super::accept();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,49 +28,47 @@
|
||||
#include "widget/colorlabelmenu/colorcodingcombobox.h"
|
||||
#include "widget/slider/rationalslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class LineEditWithFocusSignal : public QLineEdit
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class LineEditWithFocusSignal : public QLineEdit {
|
||||
Q_OBJECT
|
||||
public:
|
||||
LineEditWithFocusSignal(QWidget *parent = nullptr) :
|
||||
QLineEdit(parent)
|
||||
{
|
||||
}
|
||||
LineEditWithFocusSignal(QWidget *parent = nullptr)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void focusInEvent(QFocusEvent *e) override
|
||||
{
|
||||
QLineEdit::focusInEvent(e);
|
||||
emit Focused();
|
||||
}
|
||||
virtual void focusInEvent(QFocusEvent *e) override
|
||||
{
|
||||
QLineEdit::focusInEvent(e);
|
||||
emit Focused();
|
||||
}
|
||||
|
||||
signals:
|
||||
void Focused();
|
||||
|
||||
void Focused();
|
||||
};
|
||||
|
||||
class MarkerPropertiesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
class MarkerPropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MarkerPropertiesDialog(const std::vector<TimelineMarker*> &markers, const rational &timebase, QWidget *parent = nullptr);
|
||||
MarkerPropertiesDialog(const std::vector<TimelineMarker *> &markers,
|
||||
const rational &timebase, QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
std::vector<TimelineMarker*> markers_;
|
||||
std::vector<TimelineMarker *> markers_;
|
||||
|
||||
LineEditWithFocusSignal *label_edit_;
|
||||
LineEditWithFocusSignal *label_edit_;
|
||||
|
||||
ColorCodingComboBox *color_menu_;
|
||||
ColorCodingComboBox *color_menu_;
|
||||
|
||||
RationalSlider *in_slider_;
|
||||
|
||||
RationalSlider *out_slider_;
|
||||
RationalSlider *in_slider_;
|
||||
|
||||
RationalSlider *out_slider_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,64 +26,72 @@
|
||||
#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)
|
||||
namespace olive
|
||||
{
|
||||
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);
|
||||
OTIOPropertiesDialog::OTIOPropertiesDialog(const QList<Sequence *> &sequences,
|
||||
Project *active_project,
|
||||
QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, sequences_(sequences)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
table_ = new QTreeWidget();
|
||||
table_->setColumnCount(2);
|
||||
table_->setHeaderLabels({tr("Sequence"), tr("Actions")});
|
||||
table_->setRootIsDecorated(false);
|
||||
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);
|
||||
|
||||
for (int i = 0; i < sequences.size(); i++) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
Sequence* s = sequences.at(i);
|
||||
table_ = new QTreeWidget();
|
||||
table_->setColumnCount(2);
|
||||
table_->setHeaderLabels({ tr("Sequence"), tr("Actions") });
|
||||
table_->setRootIsDecorated(false);
|
||||
|
||||
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);
|
||||
for (int i = 0; i < sequences.size(); i++) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
Sequence *s = sequences.at(i);
|
||||
|
||||
item->setText(0, s->GetLabel());
|
||||
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);
|
||||
|
||||
table_->addTopLevelItem(item);
|
||||
item->setText(0, s->GetLabel());
|
||||
|
||||
table_->setItemWidget(item, 1, item_actions);
|
||||
}
|
||||
table_->addTopLevelItem(item);
|
||||
|
||||
// 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);
|
||||
table_->setItemWidget(item, 1, item_actions);
|
||||
}
|
||||
|
||||
layout->addWidget(table_);
|
||||
// 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);
|
||||
|
||||
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);
|
||||
layout->addWidget(table_);
|
||||
|
||||
setWindowTitle(tr("Load OpenTimelineIO Project"));
|
||||
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();
|
||||
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
|
||||
} // namespace olive
|
||||
|
||||
@@ -10,30 +10,32 @@
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "node/project.h"
|
||||
|
||||
namespace olive {
|
||||
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);
|
||||
class OTIOPropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OTIOPropertiesDialog(const QList<Sequence *> &sequences,
|
||||
Project *active_project, QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
QTreeWidget* table_;
|
||||
private:
|
||||
QTreeWidget *table_;
|
||||
|
||||
const QList<Sequence*> sequences_;
|
||||
const QList<Sequence *> sequences_;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
private slots:
|
||||
/**
|
||||
* @brief Brings up the Sequence settings dialog.
|
||||
*/
|
||||
void SetupSequence();
|
||||
};
|
||||
void SetupSequence();
|
||||
};
|
||||
|
||||
} //namespace olive
|
||||
|
||||
#endif // OTIOPROPERTIESDIALOG_H
|
||||
#endif // OTIOPROPERTIESDIALOG_H
|
||||
|
||||
@@ -23,55 +23,62 @@
|
||||
#include <QAction>
|
||||
#include <QKeyEvent>
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super QKeySequenceEdit
|
||||
|
||||
KeySequenceEditor::KeySequenceEditor(QWidget* parent, QAction* a)
|
||||
: super(parent), action(a) {
|
||||
setKeySequence(action->shortcut());
|
||||
KeySequenceEditor::KeySequenceEditor(QWidget *parent, QAction *a)
|
||||
: super(parent)
|
||||
, action(a)
|
||||
{
|
||||
setKeySequence(action->shortcut());
|
||||
}
|
||||
|
||||
void KeySequenceEditor::set_action_shortcut() {
|
||||
action->setShortcut(keySequence());
|
||||
void KeySequenceEditor::set_action_shortcut()
|
||||
{
|
||||
action->setShortcut(keySequence());
|
||||
}
|
||||
|
||||
void KeySequenceEditor::reset_to_default() {
|
||||
setKeySequence(action->property("keydefault").toString());
|
||||
void KeySequenceEditor::reset_to_default()
|
||||
{
|
||||
setKeySequence(action->property("keydefault").toString());
|
||||
}
|
||||
|
||||
QString KeySequenceEditor::action_name() {
|
||||
return action->property("id").toString();
|
||||
QString KeySequenceEditor::action_name()
|
||||
{
|
||||
return action->property("id").toString();
|
||||
}
|
||||
|
||||
QString KeySequenceEditor::export_shortcut() {
|
||||
QKeySequence ks = keySequence();
|
||||
if (ks != action->property("keydefault").value<QKeySequence>()) {
|
||||
return action->property("id").toString() + "\t" + ks.toString();
|
||||
}
|
||||
return nullptr;
|
||||
QString KeySequenceEditor::export_shortcut()
|
||||
{
|
||||
QKeySequence ks = keySequence();
|
||||
if (ks != action->property("keydefault").value<QKeySequence>()) {
|
||||
return action->property("id").toString() + "\t" + ks.toString();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void KeySequenceEditor::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
if (e->key() == Qt::Key_Backspace) {
|
||||
clear();
|
||||
} else if (e->key() == Qt::Key_Escape) {
|
||||
e->ignore();
|
||||
} else{
|
||||
super::keyPressEvent(e);
|
||||
}
|
||||
if (e->key() == Qt::Key_Backspace) {
|
||||
clear();
|
||||
} else if (e->key() == Qt::Key_Escape) {
|
||||
e->ignore();
|
||||
} else {
|
||||
super::keyPressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void KeySequenceEditor::keyReleaseEvent(QKeyEvent *e)
|
||||
{
|
||||
if (e->key() == Qt::Key_Backspace) {
|
||||
// Do nothing
|
||||
} else if (e->key() == Qt::Key_Escape) {
|
||||
e->ignore();
|
||||
} else {
|
||||
super::keyReleaseEvent(e);
|
||||
}
|
||||
if (e->key() == Qt::Key_Backspace) {
|
||||
// Do nothing
|
||||
} else if (e->key() == Qt::Key_Escape) {
|
||||
e->ignore();
|
||||
} else {
|
||||
super::keyReleaseEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief The KeySequenceEditor class
|
||||
@@ -34,9 +35,9 @@ namespace olive {
|
||||
* keyboard shortcuts to and from it.
|
||||
*/
|
||||
class KeySequenceEditor : public QKeySequenceEdit {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief KeySequenceEditor Constructor
|
||||
*
|
||||
* @param parent
|
||||
@@ -47,18 +48,18 @@ public:
|
||||
*
|
||||
* The QAction to link to. This cannot be changed throughout the lifetime of a KeySequenceEditor.
|
||||
*/
|
||||
KeySequenceEditor(QWidget *parent, QAction* a);
|
||||
KeySequenceEditor(QWidget *parent, QAction *a);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Sets the attached QAction's shortcut to the shortcut entered in this field.
|
||||
*
|
||||
* This is not done automatically in case the user cancels out of the Preferences dialog, in which case the
|
||||
* expectation is that the changes made will not be saved. Therefore, this needs to be triggered manually when
|
||||
* PreferencesDialog saves.
|
||||
*/
|
||||
void set_action_shortcut();
|
||||
void set_action_shortcut();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Set this shortcut back to the QAction's default shortcut
|
||||
*
|
||||
* Each QAction contains the default shortcut in its `property("default")` and can be used to restore the default
|
||||
@@ -68,9 +69,9 @@ public:
|
||||
* the QAction into this edit field. To save it into the QAction, it's necessary to call set_action_shortcut() after
|
||||
* calling this function.
|
||||
*/
|
||||
void reset_to_default();
|
||||
void reset_to_default();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Return attached QAction's unique ID
|
||||
*
|
||||
* Each of Olive's menu actions has a unique string ID (that, unlike the text, is not translated) for matching with
|
||||
@@ -81,9 +82,9 @@ public:
|
||||
*
|
||||
* The QAction's unique ID.
|
||||
*/
|
||||
QString action_name();
|
||||
QString action_name();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Serialize this shortcut entry into a string that can be saved to a file
|
||||
*
|
||||
* @return
|
||||
@@ -93,18 +94,18 @@ public:
|
||||
* the QAction). If the entered shortcut is the same as the QAction's default shortcut, the return value is empty
|
||||
* because a default shortcut does not need to be saved to a file.
|
||||
*/
|
||||
QString export_shortcut();
|
||||
QString export_shortcut();
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent *e) override;
|
||||
virtual void keyPressEvent(QKeyEvent *e) override;
|
||||
|
||||
virtual void keyReleaseEvent(QKeyEvent *e) override;
|
||||
virtual void keyReleaseEvent(QKeyEvent *e) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
/**
|
||||
* @brief Internal reference to the linked QAction
|
||||
*/
|
||||
QAction* action;
|
||||
QAction *action;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -34,24 +34,25 @@
|
||||
#include "tabs/preferenceskeyboardtab.h"
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
PreferencesDialog::PreferencesDialog(MainWindow *main_window) :
|
||||
ConfigDialogBase(main_window)
|
||||
namespace olive
|
||||
{
|
||||
setWindowTitle(tr("Preferences"));
|
||||
|
||||
AddTab(new PreferencesGeneralTab(), tr("General"));
|
||||
AddTab(new PreferencesAppearanceTab(), tr("Appearance"));
|
||||
AddTab(new PreferencesBehaviorTab(), tr("Behavior"));
|
||||
AddTab(new PreferencesDiskTab(), tr("Disk"));
|
||||
AddTab(new PreferencesAudioTab(), tr("Audio"));
|
||||
AddTab(new PreferencesKeyboardTab(main_window), tr("Keyboard"));
|
||||
PreferencesDialog::PreferencesDialog(MainWindow *main_window)
|
||||
: ConfigDialogBase(main_window)
|
||||
{
|
||||
setWindowTitle(tr("Preferences"));
|
||||
|
||||
AddTab(new PreferencesGeneralTab(), tr("General"));
|
||||
AddTab(new PreferencesAppearanceTab(), tr("Appearance"));
|
||||
AddTab(new PreferencesBehaviorTab(), tr("Behavior"));
|
||||
AddTab(new PreferencesDiskTab(), tr("Disk"));
|
||||
AddTab(new PreferencesAudioTab(), tr("Audio"));
|
||||
AddTab(new PreferencesKeyboardTab(main_window), tr("Keyboard"));
|
||||
}
|
||||
|
||||
void PreferencesDialog::AcceptEvent()
|
||||
{
|
||||
Config::Save();
|
||||
Config::Save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
|
||||
#include "dialog/configbase/configdialogbase.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class MainWindow;
|
||||
|
||||
@@ -39,16 +40,14 @@ class MainWindow;
|
||||
*
|
||||
* A dialog for the global application settings. Mostly an interface for Config.
|
||||
*/
|
||||
class PreferencesDialog : public ConfigDialogBase
|
||||
{
|
||||
Q_OBJECT
|
||||
class PreferencesDialog : public ConfigDialogBase {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PreferencesDialog(MainWindow *main_window);
|
||||
PreferencesDialog(MainWindow *main_window);
|
||||
|
||||
protected:
|
||||
virtual void AcceptEvent() override;
|
||||
|
||||
virtual void AcceptEvent() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -31,92 +31,96 @@
|
||||
#include "widget/menu/menushared.h"
|
||||
#include "ui/colorcoding.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
PreferencesAppearanceTab::PreferencesAppearanceTab()
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
QGridLayout* appearance_layout = new QGridLayout();
|
||||
layout->addLayout(appearance_layout);
|
||||
QGridLayout *appearance_layout = new QGridLayout();
|
||||
layout->addLayout(appearance_layout);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
// Appearance -> Theme
|
||||
appearance_layout->addWidget(new QLabel(tr("Theme")), row, 0);
|
||||
// Appearance -> Theme
|
||||
appearance_layout->addWidget(new QLabel(tr("Theme")), row, 0);
|
||||
|
||||
style_combobox_ = new QComboBox();
|
||||
style_combobox_ = new QComboBox();
|
||||
|
||||
{
|
||||
const QMap<QString, QString>& themes = StyleManager::available_themes();
|
||||
QMap<QString, QString>::const_iterator i;
|
||||
for (i=themes.cbegin(); i!=themes.cend(); i++) {
|
||||
style_combobox_->addItem(i.value(), i.key());
|
||||
{
|
||||
const QMap<QString, QString> &themes = StyleManager::available_themes();
|
||||
QMap<QString, QString>::const_iterator i;
|
||||
for (i = themes.cbegin(); i != themes.cend(); i++) {
|
||||
style_combobox_->addItem(i.value(), i.key());
|
||||
|
||||
if (StyleManager::GetStyle() == i.key()) {
|
||||
style_combobox_->setCurrentIndex(style_combobox_->count()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StyleManager::GetStyle() == i.key()) {
|
||||
style_combobox_->setCurrentIndex(style_combobox_->count() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appearance_layout->addWidget(style_combobox_, row, 1);
|
||||
appearance_layout->addWidget(style_combobox_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
{
|
||||
QGroupBox* color_group = new QGroupBox();
|
||||
color_group->setTitle(tr("Default Node Colors"));
|
||||
{
|
||||
QGroupBox *color_group = new QGroupBox();
|
||||
color_group->setTitle(tr("Default Node Colors"));
|
||||
|
||||
QGridLayout* color_layout = new QGridLayout(color_group);
|
||||
QGridLayout *color_layout = new QGridLayout(color_group);
|
||||
|
||||
for (int i=0; i<Node::kCategoryCount; i++) {
|
||||
QString cat_name = Node::GetCategoryName(static_cast<Node::CategoryID>(i));
|
||||
color_layout->addWidget(new QLabel(cat_name), i, 0);
|
||||
for (int i = 0; i < Node::kCategoryCount; i++) {
|
||||
QString cat_name =
|
||||
Node::GetCategoryName(static_cast<Node::CategoryID>(i));
|
||||
color_layout->addWidget(new QLabel(cat_name), i, 0);
|
||||
|
||||
ColorCodingComboBox* ccc = new ColorCodingComboBox();
|
||||
ccc->SetColor(OLIVE_CONFIG_STR(QStringLiteral("CatColor%1").arg(i)).toInt());
|
||||
color_layout->addWidget(ccc, i, 1);
|
||||
color_btns_.append(ccc);
|
||||
}
|
||||
ColorCodingComboBox *ccc = new ColorCodingComboBox();
|
||||
ccc->SetColor(
|
||||
OLIVE_CONFIG_STR(QStringLiteral("CatColor%1").arg(i)).toInt());
|
||||
color_layout->addWidget(ccc, i, 1);
|
||||
color_btns_.append(ccc);
|
||||
}
|
||||
|
||||
appearance_layout->addWidget(color_group, row, 0, 1, 2);
|
||||
}
|
||||
appearance_layout->addWidget(color_group, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
row++;
|
||||
{
|
||||
QGroupBox* marker_group = new QGroupBox();
|
||||
marker_group->setTitle(tr("Miscellaneous"));
|
||||
row++;
|
||||
{
|
||||
QGroupBox *marker_group = new QGroupBox();
|
||||
marker_group->setTitle(tr("Miscellaneous"));
|
||||
|
||||
QGridLayout* marker_layout = new QGridLayout(marker_group);
|
||||
QGridLayout *marker_layout = new QGridLayout(marker_group);
|
||||
|
||||
marker_layout->addWidget(new QLabel("Default Marker Color"), 0, 0);
|
||||
marker_layout->addWidget(new QLabel("Default Marker Color"), 0, 0);
|
||||
|
||||
marker_btn_ = new ColorCodingComboBox();
|
||||
marker_btn_->SetColor(OLIVE_CONFIG("MarkerColor").toInt());
|
||||
marker_layout->addWidget(marker_btn_, 0, 1);
|
||||
marker_btn_ = new ColorCodingComboBox();
|
||||
marker_btn_->SetColor(OLIVE_CONFIG("MarkerColor").toInt());
|
||||
marker_layout->addWidget(marker_btn_, 0, 1);
|
||||
|
||||
appearance_layout->addWidget(marker_group, row, 0, 1, 2);
|
||||
}
|
||||
appearance_layout->addWidget(marker_group, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
layout->addStretch();
|
||||
layout->addStretch();
|
||||
}
|
||||
|
||||
void PreferencesAppearanceTab::Accept(MultiUndoCommand *command)
|
||||
{
|
||||
Q_UNUSED(command)
|
||||
Q_UNUSED(command)
|
||||
|
||||
QString style_path = style_combobox_->currentData().toString();
|
||||
QString style_path = style_combobox_->currentData().toString();
|
||||
|
||||
if (style_path != StyleManager::GetStyle()) {
|
||||
StyleManager::SetStyle(style_path);
|
||||
OLIVE_CONFIG("Style") = style_path;
|
||||
}
|
||||
if (style_path != StyleManager::GetStyle()) {
|
||||
StyleManager::SetStyle(style_path);
|
||||
OLIVE_CONFIG("Style") = style_path;
|
||||
}
|
||||
|
||||
for (int i=0; i<color_btns_.size(); i++) {
|
||||
OLIVE_CONFIG_STR(QStringLiteral("CatColor%1").arg(i)) = color_btns_.at(i)->GetSelectedColor();
|
||||
}
|
||||
for (int i = 0; i < color_btns_.size(); i++) {
|
||||
OLIVE_CONFIG_STR(QStringLiteral("CatColor%1").arg(i)) =
|
||||
color_btns_.at(i)->GetSelectedColor();
|
||||
}
|
||||
|
||||
OLIVE_CONFIG("MarkerColor") = marker_btn_->GetSelectedColor();
|
||||
OLIVE_CONFIG("MarkerColor") = marker_btn_->GetSelectedColor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,26 +29,25 @@
|
||||
#include "ui/style/style.h"
|
||||
#include "widget/colorlabelmenu/colorcodingcombobox.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class PreferencesAppearanceTab : public ConfigDialogBaseTab
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesAppearanceTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand* command) override;
|
||||
class PreferencesAppearanceTab : public ConfigDialogBaseTab {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesAppearanceTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand *command) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
/**
|
||||
* @brief UI widget for selecting the current UI style
|
||||
*/
|
||||
QComboBox* style_combobox_;
|
||||
QComboBox *style_combobox_;
|
||||
|
||||
QVector<ColorCodingComboBox*> color_btns_;
|
||||
|
||||
ColorCodingComboBox* marker_btn_;
|
||||
QVector<ColorCodingComboBox *> color_btns_;
|
||||
|
||||
ColorCodingComboBox *marker_btn_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -27,248 +27,291 @@
|
||||
#include "audio/audiomanager.h"
|
||||
#include "config/config.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
PreferencesAudioTab::PreferencesAudioTab()
|
||||
{
|
||||
QVBoxLayout* audio_tab_layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *audio_tab_layout = new QVBoxLayout(this);
|
||||
|
||||
{
|
||||
// Backend Layout
|
||||
QGridLayout* main_layout = new QGridLayout();
|
||||
main_layout->setContentsMargins(0, 0, 0, 0);
|
||||
{
|
||||
// Backend Layout
|
||||
QGridLayout *main_layout = new QGridLayout();
|
||||
main_layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
main_layout->addWidget(new QLabel(tr("Backend:")), row, 0);
|
||||
main_layout->addWidget(new QLabel(tr("Backend:")), row, 0);
|
||||
|
||||
audio_backend_combobox_ = new QComboBox();
|
||||
connect(audio_backend_combobox_, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &PreferencesAudioTab::RefreshDevices);
|
||||
main_layout->addWidget(audio_backend_combobox_, row, 1);
|
||||
audio_backend_combobox_ = new QComboBox();
|
||||
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);
|
||||
}
|
||||
audio_tab_layout->addLayout(main_layout);
|
||||
}
|
||||
|
||||
{
|
||||
QGroupBox* groupbox = new QGroupBox();
|
||||
audio_tab_layout->addWidget(groupbox);
|
||||
{
|
||||
QGroupBox *groupbox = new QGroupBox();
|
||||
audio_tab_layout->addWidget(groupbox);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(groupbox);
|
||||
QVBoxLayout *layout = new QVBoxLayout(groupbox);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
{
|
||||
// Output Group
|
||||
QGroupBox* output_group = new QGroupBox();
|
||||
output_group->setTitle(tr("Output"));
|
||||
layout->addWidget(output_group);
|
||||
{
|
||||
// Output Group
|
||||
QGroupBox *output_group = new QGroupBox();
|
||||
output_group->setTitle(tr("Output"));
|
||||
layout->addWidget(output_group);
|
||||
|
||||
QGridLayout* output_layout = new QGridLayout(output_group);
|
||||
QGridLayout *output_layout = new QGridLayout(output_group);
|
||||
|
||||
output_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
output_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
|
||||
audio_output_devices_ = new QComboBox();
|
||||
output_layout->addWidget(audio_output_devices_, row, 1);
|
||||
audio_output_devices_ = new QComboBox();
|
||||
output_layout->addWidget(audio_output_devices_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
{
|
||||
int output_row = 0;
|
||||
{
|
||||
int output_row = 0;
|
||||
|
||||
QGroupBox *output_param_group = new QGroupBox(tr("Advanced"));
|
||||
output_layout->addWidget(output_param_group, row, 0, 1, 2);
|
||||
QGroupBox *output_param_group = new QGroupBox(tr("Advanced"));
|
||||
output_layout->addWidget(output_param_group, row, 0, 1, 2);
|
||||
|
||||
QGridLayout *output_param_layout = new QGridLayout(output_param_group);
|
||||
QGridLayout *output_param_layout =
|
||||
new QGridLayout(output_param_group);
|
||||
|
||||
output_param_layout->addWidget(new QLabel(tr("Sample Rate:")), output_row, 0);
|
||||
output_param_layout->addWidget(new QLabel(tr("Sample Rate:")),
|
||||
output_row, 0);
|
||||
|
||||
output_rate_combo_ = new SampleRateComboBox();
|
||||
output_rate_combo_->SetSampleRate(OLIVE_CONFIG("AudioOutputSampleRate").toInt());
|
||||
output_param_layout->addWidget(output_rate_combo_, output_row, 1);
|
||||
output_rate_combo_ = new SampleRateComboBox();
|
||||
output_rate_combo_->SetSampleRate(
|
||||
OLIVE_CONFIG("AudioOutputSampleRate").toInt());
|
||||
output_param_layout->addWidget(output_rate_combo_, output_row,
|
||||
1);
|
||||
|
||||
output_row++;
|
||||
output_row++;
|
||||
|
||||
output_param_layout->addWidget(new QLabel(tr("Channel Layout:")), output_row, 0);
|
||||
output_param_layout->addWidget(
|
||||
new QLabel(tr("Channel Layout:")), output_row, 0);
|
||||
|
||||
output_ch_layout_combo_ = new ChannelLayoutComboBox();
|
||||
output_ch_layout_combo_->SetChannelLayout(OLIVE_CONFIG("AudioOutputChannelLayout").toULongLong());
|
||||
output_param_layout->addWidget(output_ch_layout_combo_, output_row, 1);
|
||||
output_ch_layout_combo_ = new ChannelLayoutComboBox();
|
||||
output_ch_layout_combo_->SetChannelLayout(
|
||||
OLIVE_CONFIG("AudioOutputChannelLayout").toULongLong());
|
||||
output_param_layout->addWidget(output_ch_layout_combo_,
|
||||
output_row, 1);
|
||||
|
||||
output_row++;
|
||||
output_row++;
|
||||
|
||||
output_param_layout->addWidget(new QLabel(tr("Sample Format:")), output_row, 0);
|
||||
output_param_layout->addWidget(new QLabel(tr("Sample Format:")),
|
||||
output_row, 0);
|
||||
|
||||
output_fmt_combo_ = new SampleFormatComboBox();
|
||||
output_fmt_combo_->SetPackedFormats();
|
||||
output_fmt_combo_->SetSampleFormat(SampleFormat::from_string(OLIVE_CONFIG("AudioOutputSampleFormat").toString().toStdString()));
|
||||
output_param_layout->addWidget(output_fmt_combo_, output_row, 1);
|
||||
}
|
||||
}
|
||||
output_fmt_combo_ = new SampleFormatComboBox();
|
||||
output_fmt_combo_->SetPackedFormats();
|
||||
output_fmt_combo_->SetSampleFormat(SampleFormat::from_string(
|
||||
OLIVE_CONFIG("AudioOutputSampleFormat")
|
||||
.toString()
|
||||
.toStdString()));
|
||||
output_param_layout->addWidget(output_fmt_combo_, output_row,
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
row = 0;
|
||||
row = 0;
|
||||
|
||||
{
|
||||
QGroupBox* input_group = new QGroupBox();
|
||||
input_group->setTitle(tr("Input"));
|
||||
layout->addWidget(input_group);
|
||||
{
|
||||
QGroupBox *input_group = new QGroupBox();
|
||||
input_group->setTitle(tr("Input"));
|
||||
layout->addWidget(input_group);
|
||||
|
||||
QGridLayout* input_layout = new QGridLayout(input_group);
|
||||
QGridLayout *input_layout = new QGridLayout(input_group);
|
||||
|
||||
input_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
input_layout->addWidget(new QLabel(tr("Device:")), row, 0);
|
||||
|
||||
audio_input_devices_ = new QComboBox();
|
||||
input_layout->addWidget(audio_input_devices_, row, 1);
|
||||
audio_input_devices_ = new QComboBox();
|
||||
input_layout->addWidget(audio_input_devices_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
QGroupBox *recording_group = new QGroupBox(tr("Recording"));
|
||||
input_layout->addWidget(recording_group, row, 0, 1, 2);
|
||||
QGroupBox *recording_group = new QGroupBox(tr("Recording"));
|
||||
input_layout->addWidget(recording_group, row, 0, 1, 2);
|
||||
|
||||
QVBoxLayout *recording_layout = new QVBoxLayout(recording_group);
|
||||
QVBoxLayout *recording_layout = new QVBoxLayout(recording_group);
|
||||
|
||||
QHBoxLayout *fmt_layout = new QHBoxLayout();
|
||||
recording_layout->addLayout(fmt_layout);
|
||||
QHBoxLayout *fmt_layout = new QHBoxLayout();
|
||||
recording_layout->addLayout(fmt_layout);
|
||||
|
||||
fmt_layout->addWidget(new QLabel(tr("Format:")));
|
||||
fmt_layout->addWidget(new QLabel(tr("Format:")));
|
||||
|
||||
record_format_combo_ = new ExportFormatComboBox(ExportFormatComboBox::kShowAudioOnly);
|
||||
record_format_combo_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
record_format_combo_->SetFormat(static_cast<ExportFormat::Format>(OLIVE_CONFIG("AudioRecordingFormat").toInt()));
|
||||
fmt_layout->addWidget(record_format_combo_);
|
||||
record_format_combo_ =
|
||||
new ExportFormatComboBox(ExportFormatComboBox::kShowAudioOnly);
|
||||
record_format_combo_->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
record_format_combo_->SetFormat(static_cast<ExportFormat::Format>(
|
||||
OLIVE_CONFIG("AudioRecordingFormat").toInt()));
|
||||
fmt_layout->addWidget(record_format_combo_);
|
||||
|
||||
record_options_ = new ExportAudioTab();
|
||||
record_options_->SetFormat(record_format_combo_->GetFormat());
|
||||
record_options_->SetCodec(static_cast<ExportCodec::Codec>(OLIVE_CONFIG("AudioRecordingCodec").toInt()));
|
||||
record_options_->sample_rate_combobox()->SetSampleRate(OLIVE_CONFIG("AudioRecordingSampleRate").toInt());
|
||||
record_options_->channel_layout_combobox()->SetChannelLayout(OLIVE_CONFIG("AudioRecordingChannelLayout").toULongLong());
|
||||
record_options_->bit_rate_slider()->SetValue(OLIVE_CONFIG("AudioRecordingBitRate").toInt());
|
||||
record_options_->sample_format_combobox()->SetSampleFormat(SampleFormat::from_string(OLIVE_CONFIG("AudioRecordingSampleFormat").toString().toStdString()));
|
||||
recording_layout->addWidget(record_options_);
|
||||
record_options_ = new ExportAudioTab();
|
||||
record_options_->SetFormat(record_format_combo_->GetFormat());
|
||||
record_options_->SetCodec(static_cast<ExportCodec::Codec>(
|
||||
OLIVE_CONFIG("AudioRecordingCodec").toInt()));
|
||||
record_options_->sample_rate_combobox()->SetSampleRate(
|
||||
OLIVE_CONFIG("AudioRecordingSampleRate").toInt());
|
||||
record_options_->channel_layout_combobox()->SetChannelLayout(
|
||||
OLIVE_CONFIG("AudioRecordingChannelLayout").toULongLong());
|
||||
record_options_->bit_rate_slider()->SetValue(
|
||||
OLIVE_CONFIG("AudioRecordingBitRate").toInt());
|
||||
record_options_->sample_format_combobox()->SetSampleFormat(
|
||||
SampleFormat::from_string(
|
||||
OLIVE_CONFIG("AudioRecordingSampleFormat")
|
||||
.toString()
|
||||
.toStdString()));
|
||||
recording_layout->addWidget(record_options_);
|
||||
|
||||
connect(record_format_combo_, &ExportFormatComboBox::FormatChanged, record_options_, &ExportAudioTab::SetFormat);
|
||||
}
|
||||
connect(record_format_combo_, &ExportFormatComboBox::FormatChanged,
|
||||
record_options_, &ExportAudioTab::SetFormat);
|
||||
}
|
||||
|
||||
QHBoxLayout* refresh_layout = new QHBoxLayout();
|
||||
layout->addLayout(refresh_layout);
|
||||
refresh_layout->addStretch();
|
||||
QHBoxLayout *refresh_layout = new QHBoxLayout();
|
||||
layout->addLayout(refresh_layout);
|
||||
refresh_layout->addStretch();
|
||||
|
||||
refresh_devices_btn_ = new QPushButton(tr("Refresh Devices"));
|
||||
refresh_layout->addWidget(refresh_devices_btn_);
|
||||
refresh_devices_btn_ = new QPushButton(tr("Refresh Devices"));
|
||||
refresh_layout->addWidget(refresh_devices_btn_);
|
||||
|
||||
connect(refresh_devices_btn_, &QPushButton::clicked, this, &PreferencesAudioTab::HardRefreshBackends);
|
||||
}
|
||||
connect(refresh_devices_btn_, &QPushButton::clicked, this,
|
||||
&PreferencesAudioTab::HardRefreshBackends);
|
||||
}
|
||||
|
||||
audio_tab_layout->addStretch();
|
||||
audio_tab_layout->addStretch();
|
||||
|
||||
// Populate lists
|
||||
RefreshBackends();
|
||||
// Populate lists
|
||||
RefreshBackends();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::Accept(MultiUndoCommand *command)
|
||||
{
|
||||
Q_UNUSED(command)
|
||||
Q_UNUSED(command)
|
||||
|
||||
// Get device indexes
|
||||
PaDeviceIndex output_device = audio_output_devices_->currentData().value<PaDeviceIndex>();
|
||||
PaDeviceIndex input_device = audio_input_devices_->currentData().value<PaDeviceIndex>();
|
||||
// Get device indexes
|
||||
PaDeviceIndex output_device =
|
||||
audio_output_devices_->currentData().value<PaDeviceIndex>();
|
||||
PaDeviceIndex input_device =
|
||||
audio_input_devices_->currentData().value<PaDeviceIndex>();
|
||||
|
||||
// Get device names, which seem to be the closest thing we have to a "unique identifier" for them
|
||||
OLIVE_CONFIG("AudioOutput") = audio_output_devices_->currentText();
|
||||
OLIVE_CONFIG("AudioInput") = audio_input_devices_->currentText();
|
||||
// Get device names, which seem to be the closest thing we have to a "unique identifier" for them
|
||||
OLIVE_CONFIG("AudioOutput") = audio_output_devices_->currentText();
|
||||
OLIVE_CONFIG("AudioInput") = audio_input_devices_->currentText();
|
||||
|
||||
// Set devices to be used from now on
|
||||
AudioManager::instance()->SetOutputDevice(output_device);
|
||||
AudioManager::instance()->SetInputDevice(input_device);
|
||||
// Set devices to be used from now on
|
||||
AudioManager::instance()->SetOutputDevice(output_device);
|
||||
AudioManager::instance()->SetInputDevice(input_device);
|
||||
|
||||
OLIVE_CONFIG("AudioOutputSampleRate") = output_rate_combo_->GetSampleRate();
|
||||
OLIVE_CONFIG("AudioOutputChannelLayout") = QVariant::fromValue(output_ch_layout_combo_->GetChannelLayout());
|
||||
OLIVE_CONFIG("AudioOutputSampleFormat") = QString::fromStdString(output_fmt_combo_->GetSampleFormat().to_string());
|
||||
OLIVE_CONFIG("AudioOutputSampleRate") = output_rate_combo_->GetSampleRate();
|
||||
OLIVE_CONFIG("AudioOutputChannelLayout") =
|
||||
QVariant::fromValue(output_ch_layout_combo_->GetChannelLayout());
|
||||
OLIVE_CONFIG("AudioOutputSampleFormat") = QString::fromStdString(
|
||||
output_fmt_combo_->GetSampleFormat().to_string());
|
||||
|
||||
OLIVE_CONFIG("AudioRecordingFormat") = record_format_combo_->GetFormat();
|
||||
OLIVE_CONFIG("AudioRecordingCodec") = record_options_->GetCodec();
|
||||
OLIVE_CONFIG("AudioRecordingSampleRate") = record_options_->sample_rate_combobox()->GetSampleRate();
|
||||
OLIVE_CONFIG("AudioRecordingChannelLayout") = QVariant::fromValue(record_options_->channel_layout_combobox()->GetChannelLayout());
|
||||
OLIVE_CONFIG("AudioRecordingBitRate") = QVariant::fromValue(record_options_->bit_rate_slider()->GetValue());
|
||||
OLIVE_CONFIG("AudioRecordingSampleFormat") = QString::fromStdString(record_options_->sample_format_combobox()->GetSampleFormat().to_string());
|
||||
OLIVE_CONFIG("AudioRecordingFormat") = record_format_combo_->GetFormat();
|
||||
OLIVE_CONFIG("AudioRecordingCodec") = record_options_->GetCodec();
|
||||
OLIVE_CONFIG("AudioRecordingSampleRate") =
|
||||
record_options_->sample_rate_combobox()->GetSampleRate();
|
||||
OLIVE_CONFIG("AudioRecordingChannelLayout") = QVariant::fromValue(
|
||||
record_options_->channel_layout_combobox()->GetChannelLayout());
|
||||
OLIVE_CONFIG("AudioRecordingBitRate") =
|
||||
QVariant::fromValue(record_options_->bit_rate_slider()->GetValue());
|
||||
OLIVE_CONFIG("AudioRecordingSampleFormat") =
|
||||
QString::fromStdString(record_options_->sample_format_combobox()
|
||||
->GetSampleFormat()
|
||||
.to_string());
|
||||
|
||||
emit AudioManager::instance()->OutputParamsChanged();
|
||||
emit AudioManager::instance() -> OutputParamsChanged();
|
||||
}
|
||||
|
||||
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_->clear();
|
||||
for (PaHostApiIndex i = 0, end = Pa_GetHostApiCount(); i < end; i++) {
|
||||
const PaHostApiInfo *info = Pa_GetHostApiInfo(i);
|
||||
|
||||
audio_backend_combobox_->addItem(info->name);
|
||||
}
|
||||
audio_backend_combobox_->addItem(info->name);
|
||||
}
|
||||
|
||||
RefreshDevices();
|
||||
RefreshDevices();
|
||||
|
||||
AttemptToSetDevicesFromConfig();
|
||||
AttemptToSetDevicesFromConfig();
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::RefreshDevices()
|
||||
{
|
||||
if (audio_backend_combobox_->count() == 0) {
|
||||
return;
|
||||
}
|
||||
if (audio_backend_combobox_->count() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
PaHostApiIndex host_index = audio_backend_combobox_->currentIndex();
|
||||
const PaHostApiInfo *host = Pa_GetHostApiInfo(host_index);
|
||||
PaHostApiIndex host_index = audio_backend_combobox_->currentIndex();
|
||||
const PaHostApiInfo *host = Pa_GetHostApiInfo(host_index);
|
||||
|
||||
audio_output_devices_->clear();
|
||||
audio_input_devices_->clear();
|
||||
audio_output_devices_->clear();
|
||||
audio_input_devices_->clear();
|
||||
|
||||
for (int i=0; i<host->deviceCount; i++) {
|
||||
PaDeviceIndex device_index = Pa_HostApiDeviceIndexToDeviceIndex(host_index, i);
|
||||
const PaDeviceInfo *device = Pa_GetDeviceInfo(device_index);
|
||||
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->maxOutputChannels) {
|
||||
audio_output_devices_->addItem(device->name, device_index);
|
||||
}
|
||||
|
||||
if (device->maxInputChannels) {
|
||||
audio_input_devices_->addItem(device->name, device_index);
|
||||
}
|
||||
}
|
||||
if (device->maxInputChannels) {
|
||||
audio_input_devices_->addItem(device->name, device_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesAudioTab::HardRefreshBackends()
|
||||
{
|
||||
AudioManager::instance()->HardReset();
|
||||
RefreshBackends();
|
||||
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();
|
||||
// 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);
|
||||
}
|
||||
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;
|
||||
if (current_output || current_input) {
|
||||
PaHostApiIndex host = current_output ? current_output->hostApi :
|
||||
current_input->hostApi;
|
||||
|
||||
// Set backend accordingly
|
||||
audio_backend_combobox_->setCurrentIndex(host);
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
if (current_input) {
|
||||
audio_input_devices_->setCurrentText(current_input->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,56 +28,55 @@
|
||||
#include "dialog/export/exportaudiotab.h"
|
||||
#include "dialog/export/exportformatcombobox.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class PreferencesAudioTab : public ConfigDialogBaseTab
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesAudioTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand* command) override;
|
||||
class PreferencesAudioTab : public ConfigDialogBaseTab {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesAudioTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand *command) override;
|
||||
|
||||
private:
|
||||
QComboBox* audio_backend_combobox_;
|
||||
QComboBox *audio_backend_combobox_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief UI widget for selecting the output audio device
|
||||
*/
|
||||
QComboBox* audio_output_devices_;
|
||||
QComboBox *audio_output_devices_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief UI widget for selecting the input audio device
|
||||
*/
|
||||
QComboBox* audio_input_devices_;
|
||||
QComboBox *audio_input_devices_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief UI widget for editing the recording channels
|
||||
*/
|
||||
QComboBox* recording_combobox_;
|
||||
QComboBox *recording_combobox_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Button that triggers a refresh of the available audio devices
|
||||
*/
|
||||
QPushButton* refresh_devices_btn_;
|
||||
QPushButton *refresh_devices_btn_;
|
||||
|
||||
SampleRateComboBox *output_rate_combo_;
|
||||
ChannelLayoutComboBox *output_ch_layout_combo_;
|
||||
SampleFormatComboBox *output_fmt_combo_;
|
||||
SampleRateComboBox *output_rate_combo_;
|
||||
ChannelLayoutComboBox *output_ch_layout_combo_;
|
||||
SampleFormatComboBox *output_fmt_combo_;
|
||||
|
||||
ExportFormatComboBox *record_format_combo_;
|
||||
ExportFormatComboBox *record_format_combo_;
|
||||
|
||||
ExportAudioTab *record_options_;
|
||||
ExportAudioTab *record_options_;
|
||||
|
||||
private slots:
|
||||
void RefreshBackends();
|
||||
void RefreshBackends();
|
||||
|
||||
void RefreshDevices();
|
||||
void RefreshDevices();
|
||||
|
||||
void HardRefreshBackends();
|
||||
|
||||
void AttemptToSetDevicesFromConfig();
|
||||
void HardRefreshBackends();
|
||||
|
||||
void AttemptToSetDevicesFromConfig();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -25,143 +25,140 @@
|
||||
|
||||
#include "config/config.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
PreferencesBehaviorTab::PreferencesBehaviorTab()
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
behavior_tree_ = new QTreeWidget();
|
||||
layout->addWidget(behavior_tree_);
|
||||
behavior_tree_ = new QTreeWidget();
|
||||
layout->addWidget(behavior_tree_);
|
||||
|
||||
behavior_tree_->setHeaderLabel(tr("Behavior"));
|
||||
behavior_tree_->setHeaderLabel(tr("Behavior"));
|
||||
|
||||
QTreeWidgetItem* general_group = AddParent(tr("General"));
|
||||
AddItem(tr("Enable hover focus"),
|
||||
QStringLiteral("HoverFocus"),
|
||||
tr("Panels will be considered focused when the mouse cursor is over them without having to click them."),
|
||||
general_group);
|
||||
AddItem(tr("Enable slider ladder"),
|
||||
QStringLiteral("UseSliderLadders"),
|
||||
general_group);
|
||||
AddItem(tr("Scrolling zooms by default"),
|
||||
QStringLiteral("ScrollZooms"),
|
||||
tr("By default, scrolling will move the view around, and holding Ctrl/Cmd will make it zoom instead. "
|
||||
"Enabling this will switch those, scrolling will zoom by default, and holding Ctrl/Cmd will move the view instead."),
|
||||
general_group);
|
||||
QTreeWidgetItem *general_group = AddParent(tr("General"));
|
||||
AddItem(
|
||||
tr("Enable hover focus"), QStringLiteral("HoverFocus"),
|
||||
tr("Panels will be considered focused when the mouse cursor is over them without having to click them."),
|
||||
general_group);
|
||||
AddItem(tr("Enable slider ladder"), QStringLiteral("UseSliderLadders"),
|
||||
general_group);
|
||||
AddItem(
|
||||
tr("Scrolling zooms by default"), QStringLiteral("ScrollZooms"),
|
||||
tr("By default, scrolling will move the view around, and holding Ctrl/Cmd will make it zoom instead. "
|
||||
"Enabling this will switch those, scrolling will zoom by default, and holding Ctrl/Cmd will move the view instead."),
|
||||
general_group);
|
||||
|
||||
QTreeWidgetItem* audio_group = AddParent(tr("Audio"));
|
||||
AddItem(tr("Enable audio scrubbing"),
|
||||
QStringLiteral("AudioScrubbing"),
|
||||
audio_group);
|
||||
QTreeWidgetItem *audio_group = AddParent(tr("Audio"));
|
||||
AddItem(tr("Enable audio scrubbing"), QStringLiteral("AudioScrubbing"),
|
||||
audio_group);
|
||||
|
||||
QTreeWidgetItem* timeline_group = AddParent(tr("Timeline"));
|
||||
AddItem(tr("Auto-Seek to Imported Clips"),
|
||||
QStringLiteral("EnableSeekToImport"),
|
||||
timeline_group);
|
||||
AddItem(tr("Edit Tool Also Seeks"),
|
||||
QStringLiteral("EditToolAlsoSeeks"),
|
||||
timeline_group);
|
||||
AddItem(tr("Edit Tool Selects Links"),
|
||||
QStringLiteral("EditToolSelectsLinks"),
|
||||
timeline_group);
|
||||
AddItem(tr("Enable Drag Files to Timeline"),
|
||||
QStringLiteral("EnableDragFilesToTimeline"),
|
||||
timeline_group);
|
||||
AddItem(tr("Invert Timeline Scroll Axes"),
|
||||
QStringLiteral("InvertTimelineScrollAxes"),
|
||||
tr("Hold ALT on any UI element to switch scrolling axes"),
|
||||
timeline_group);
|
||||
AddItem(tr("Seek Also Selects"),
|
||||
QStringLiteral("SeekAlsoSelects"),
|
||||
timeline_group);
|
||||
AddItem(tr("Seek to the End of Pastes"),
|
||||
QStringLiteral("PasteSeeks"),
|
||||
timeline_group);
|
||||
AddItem(tr("Selecting Also Seeks"),
|
||||
QStringLiteral("SelectAlsoSeeks"),
|
||||
timeline_group);
|
||||
QTreeWidgetItem *timeline_group = AddParent(tr("Timeline"));
|
||||
AddItem(tr("Auto-Seek to Imported Clips"),
|
||||
QStringLiteral("EnableSeekToImport"), timeline_group);
|
||||
AddItem(tr("Edit Tool Also Seeks"), QStringLiteral("EditToolAlsoSeeks"),
|
||||
timeline_group);
|
||||
AddItem(tr("Edit Tool Selects Links"),
|
||||
QStringLiteral("EditToolSelectsLinks"), timeline_group);
|
||||
AddItem(tr("Enable Drag Files to Timeline"),
|
||||
QStringLiteral("EnableDragFilesToTimeline"), timeline_group);
|
||||
AddItem(tr("Invert Timeline Scroll Axes"),
|
||||
QStringLiteral("InvertTimelineScrollAxes"),
|
||||
tr("Hold ALT on any UI element to switch scrolling axes"),
|
||||
timeline_group);
|
||||
AddItem(tr("Seek Also Selects"), QStringLiteral("SeekAlsoSelects"),
|
||||
timeline_group);
|
||||
AddItem(tr("Seek to the End of Pastes"), QStringLiteral("PasteSeeks"),
|
||||
timeline_group);
|
||||
AddItem(tr("Selecting Also Seeks"), QStringLiteral("SelectAlsoSeeks"),
|
||||
timeline_group);
|
||||
|
||||
QTreeWidgetItem* playback_group = AddParent(tr("Playback"));
|
||||
AddItem(tr("Ask For Name When Setting Marker"),
|
||||
QStringLiteral("SetNameWithMarker"),
|
||||
playback_group);
|
||||
AddItem(tr("Automatically rewind at the end of a sequence"),
|
||||
QStringLiteral("AutoSeekToBeginning"),
|
||||
playback_group);
|
||||
QTreeWidgetItem *playback_group = AddParent(tr("Playback"));
|
||||
AddItem(tr("Ask For Name When Setting Marker"),
|
||||
QStringLiteral("SetNameWithMarker"), playback_group);
|
||||
AddItem(tr("Automatically rewind at the end of a sequence"),
|
||||
QStringLiteral("AutoSeekToBeginning"), playback_group);
|
||||
|
||||
QTreeWidgetItem* project_group = AddParent(tr("Project"));
|
||||
AddItem(tr("Drop Files on Media to Replace"),
|
||||
QStringLiteral("DropFileOnMediaToReplace"),
|
||||
project_group);
|
||||
QTreeWidgetItem *project_group = AddParent(tr("Project"));
|
||||
AddItem(tr("Drop Files on Media to Replace"),
|
||||
QStringLiteral("DropFileOnMediaToReplace"), project_group);
|
||||
|
||||
QTreeWidgetItem* node_group = AddParent(tr("Nodes"));
|
||||
AddItem(tr("Add Default Effects to New Clips"),
|
||||
QStringLiteral("AddDefaultEffectsToClips"),
|
||||
node_group);
|
||||
AddItem(tr("Auto-Scale By Default"),
|
||||
QStringLiteral("AutoscaleByDefault"),
|
||||
node_group);
|
||||
AddItem(tr("Splitting Clips Copies Dependencies"),
|
||||
QStringLiteral("SplitClipsCopyNodes"),
|
||||
tr("Multiple clips can share the same nodes. Disable this to automatically share node "
|
||||
"dependencies among clips when copying or splitting them."),
|
||||
node_group);
|
||||
QTreeWidgetItem *node_group = AddParent(tr("Nodes"));
|
||||
AddItem(tr("Add Default Effects to New Clips"),
|
||||
QStringLiteral("AddDefaultEffectsToClips"), node_group);
|
||||
AddItem(tr("Auto-Scale By Default"), QStringLiteral("AutoscaleByDefault"),
|
||||
node_group);
|
||||
AddItem(
|
||||
tr("Splitting Clips Copies Dependencies"),
|
||||
QStringLiteral("SplitClipsCopyNodes"),
|
||||
tr("Multiple clips can share the same nodes. Disable this to automatically share node "
|
||||
"dependencies among clips when copying or splitting them."),
|
||||
node_group);
|
||||
|
||||
QTreeWidgetItem* opengl_group = AddParent(tr("OpenGL"));
|
||||
AddItem(tr("Use glFinish"),
|
||||
QStringLiteral("UseGLFinish"),
|
||||
opengl_group);
|
||||
QTreeWidgetItem *opengl_group = AddParent(tr("OpenGL"));
|
||||
AddItem(tr("Use glFinish"), QStringLiteral("UseGLFinish"), opengl_group);
|
||||
}
|
||||
|
||||
void PreferencesBehaviorTab::Accept(MultiUndoCommand *command)
|
||||
{
|
||||
Q_UNUSED(command)
|
||||
Q_UNUSED(command)
|
||||
|
||||
for (auto iterator=config_map_.begin();iterator!=config_map_.end();iterator++) {
|
||||
OLIVE_CONFIG_STR(iterator.value()) = (iterator.key()->checkState(0) == Qt::Checked);
|
||||
}
|
||||
for (auto iterator = config_map_.begin(); iterator != config_map_.end();
|
||||
iterator++) {
|
||||
OLIVE_CONFIG_STR(iterator.value()) =
|
||||
(iterator.key()->checkState(0) == Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem* PreferencesBehaviorTab::AddItem(const QString &text, const QString &config_key, const QString& tooltip, QTreeWidgetItem* parent)
|
||||
QTreeWidgetItem *PreferencesBehaviorTab::AddItem(const QString &text,
|
||||
const QString &config_key,
|
||||
const QString &tooltip,
|
||||
QTreeWidgetItem *parent)
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem({text});
|
||||
item->setToolTip(0, tooltip);
|
||||
item->setCheckState(0, OLIVE_CONFIG_STR(config_key).toBool() ? Qt::Checked : Qt::Unchecked);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem({ text });
|
||||
item->setToolTip(0, tooltip);
|
||||
item->setCheckState(
|
||||
0, OLIVE_CONFIG_STR(config_key).toBool() ? Qt::Checked : Qt::Unchecked);
|
||||
|
||||
config_map_.insert(item, config_key);
|
||||
config_map_.insert(item, config_key);
|
||||
|
||||
if (parent) {
|
||||
parent->addChild(item);
|
||||
} else {
|
||||
behavior_tree_->addTopLevelItem(item);
|
||||
}
|
||||
if (parent) {
|
||||
parent->addChild(item);
|
||||
} else {
|
||||
behavior_tree_->addTopLevelItem(item);
|
||||
}
|
||||
|
||||
return item;
|
||||
return item;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *PreferencesBehaviorTab::AddItem(const QString &text, const QString &config_key, QTreeWidgetItem *parent)
|
||||
QTreeWidgetItem *PreferencesBehaviorTab::AddItem(const QString &text,
|
||||
const QString &config_key,
|
||||
QTreeWidgetItem *parent)
|
||||
{
|
||||
return AddItem(text, config_key, QString(), parent);
|
||||
return AddItem(text, config_key, QString(), parent);
|
||||
}
|
||||
|
||||
QTreeWidgetItem *PreferencesBehaviorTab::AddParent(const QString &text, const QString &tooltip, QTreeWidgetItem *parent)
|
||||
QTreeWidgetItem *PreferencesBehaviorTab::AddParent(const QString &text,
|
||||
const QString &tooltip,
|
||||
QTreeWidgetItem *parent)
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem({text});
|
||||
item->setToolTip(0, tooltip);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem({ text });
|
||||
item->setToolTip(0, tooltip);
|
||||
|
||||
if (parent) {
|
||||
parent->addChild(item);
|
||||
} else {
|
||||
behavior_tree_->addTopLevelItem(item);
|
||||
}
|
||||
if (parent) {
|
||||
parent->addChild(item);
|
||||
} else {
|
||||
behavior_tree_->addTopLevelItem(item);
|
||||
}
|
||||
|
||||
return item;
|
||||
return item;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *PreferencesBehaviorTab::AddParent(const QString &text, QTreeWidgetItem *parent)
|
||||
QTreeWidgetItem *PreferencesBehaviorTab::AddParent(const QString &text,
|
||||
QTreeWidgetItem *parent)
|
||||
{
|
||||
return AddParent(text, QString(), parent);
|
||||
return AddParent(text, QString(), parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,27 +25,30 @@
|
||||
|
||||
#include "dialog/configbase/configdialogbase.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class PreferencesBehaviorTab : public ConfigDialogBaseTab
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesBehaviorTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand* command) override;
|
||||
class PreferencesBehaviorTab : public ConfigDialogBaseTab {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesBehaviorTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand *command) override;
|
||||
|
||||
private:
|
||||
QTreeWidgetItem *AddParent(const QString& text, const QString &tooltip, QTreeWidgetItem *parent = nullptr);
|
||||
QTreeWidgetItem *AddParent(const QString& text, QTreeWidgetItem *parent = nullptr);
|
||||
QTreeWidgetItem *AddParent(const QString &text, const QString &tooltip,
|
||||
QTreeWidgetItem *parent = nullptr);
|
||||
QTreeWidgetItem *AddParent(const QString &text,
|
||||
QTreeWidgetItem *parent = nullptr);
|
||||
|
||||
QTreeWidgetItem *AddItem(const QString& text, const QString& config_key, const QString &tooltip, QTreeWidgetItem *parent );
|
||||
QTreeWidgetItem *AddItem(const QString& text, const QString& config_key, QTreeWidgetItem *parent);
|
||||
QTreeWidgetItem *AddItem(const QString &text, const QString &config_key,
|
||||
const QString &tooltip, QTreeWidgetItem *parent);
|
||||
QTreeWidgetItem *AddItem(const QString &text, const QString &config_key,
|
||||
QTreeWidgetItem *parent);
|
||||
|
||||
QMap<QTreeWidgetItem*, QString> config_map_;
|
||||
|
||||
QTreeWidget* behavior_tree_;
|
||||
QMap<QTreeWidgetItem *, QString> config_map_;
|
||||
|
||||
QTreeWidget *behavior_tree_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,94 +29,105 @@
|
||||
|
||||
#include "common/filefunctions.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
PreferencesDiskTab::PreferencesDiskTab()
|
||||
{
|
||||
// Get default disk cache folder
|
||||
default_disk_cache_folder_ = DiskManager::instance()->GetDefaultCacheFolder();
|
||||
// Get default disk cache folder
|
||||
default_disk_cache_folder_ =
|
||||
DiskManager::instance()->GetDefaultCacheFolder();
|
||||
|
||||
QVBoxLayout* outer_layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *outer_layout = new QVBoxLayout(this);
|
||||
|
||||
QGroupBox* disk_management_group = new QGroupBox(tr("Disk Management"));
|
||||
outer_layout->addWidget(disk_management_group);
|
||||
QGroupBox *disk_management_group = new QGroupBox(tr("Disk Management"));
|
||||
outer_layout->addWidget(disk_management_group);
|
||||
|
||||
QGridLayout* disk_management_layout = new QGridLayout(disk_management_group);
|
||||
QGridLayout *disk_management_layout =
|
||||
new QGridLayout(disk_management_group);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
disk_management_layout->addWidget(new QLabel(tr("Disk Cache Location:")), row, 0);
|
||||
disk_management_layout->addWidget(new QLabel(tr("Disk Cache Location:")),
|
||||
row, 0);
|
||||
|
||||
disk_cache_location_ = new PathWidget(default_disk_cache_folder_->GetPath());
|
||||
disk_management_layout->addWidget(disk_cache_location_, row, 1);
|
||||
disk_cache_location_ =
|
||||
new PathWidget(default_disk_cache_folder_->GetPath());
|
||||
disk_management_layout->addWidget(disk_cache_location_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
QPushButton* disk_cache_settings_btn = new QPushButton(tr("Disk Cache Settings"));
|
||||
connect(disk_cache_settings_btn, &QPushButton::clicked, this, [this](){
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(disk_cache_location_->text(), this);
|
||||
});
|
||||
disk_management_layout->addWidget(disk_cache_settings_btn, row, 1);
|
||||
QPushButton *disk_cache_settings_btn =
|
||||
new QPushButton(tr("Disk Cache Settings"));
|
||||
connect(disk_cache_settings_btn, &QPushButton::clicked, this, [this]() {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(
|
||||
disk_cache_location_->text(), this);
|
||||
});
|
||||
disk_management_layout->addWidget(disk_cache_settings_btn, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
QGroupBox* cache_behavior = new QGroupBox(tr("Cache Behavior"));
|
||||
outer_layout->addWidget(cache_behavior);
|
||||
QGridLayout* cache_behavior_layout = new QGridLayout(cache_behavior);
|
||||
QGroupBox *cache_behavior = new QGroupBox(tr("Cache Behavior"));
|
||||
outer_layout->addWidget(cache_behavior);
|
||||
QGridLayout *cache_behavior_layout = new QGridLayout(cache_behavior);
|
||||
|
||||
row = 0;
|
||||
row = 0;
|
||||
|
||||
cache_behavior_layout->addWidget(new QLabel(tr("Cache Ahead:")), row, 0);
|
||||
cache_behavior_layout->addWidget(new QLabel(tr("Cache Ahead:")), row, 0);
|
||||
|
||||
cache_ahead_slider_ = new FloatSlider();
|
||||
cache_ahead_slider_->SetFormat(tr("%1 seconds"));
|
||||
cache_ahead_slider_->SetMinimum(0);
|
||||
cache_ahead_slider_->SetValue(OLIVE_CONFIG("DiskCacheAhead").value<rational>().toDouble());
|
||||
cache_behavior_layout->addWidget(cache_ahead_slider_, row, 1);
|
||||
cache_ahead_slider_ = new FloatSlider();
|
||||
cache_ahead_slider_->SetFormat(tr("%1 seconds"));
|
||||
cache_ahead_slider_->SetMinimum(0);
|
||||
cache_ahead_slider_->SetValue(
|
||||
OLIVE_CONFIG("DiskCacheAhead").value<rational>().toDouble());
|
||||
cache_behavior_layout->addWidget(cache_ahead_slider_, row, 1);
|
||||
|
||||
cache_behavior_layout->addWidget(new QLabel(tr("Cache Behind:")), row, 2);
|
||||
cache_behavior_layout->addWidget(new QLabel(tr("Cache Behind:")), row, 2);
|
||||
|
||||
cache_behind_slider_ = new FloatSlider();
|
||||
cache_behind_slider_->SetMinimum(0);
|
||||
cache_behind_slider_->SetFormat(tr("%1 seconds"));
|
||||
cache_behind_slider_->SetValue(OLIVE_CONFIG("DiskCacheBehind").value<rational>().toDouble());
|
||||
cache_behavior_layout->addWidget(cache_behind_slider_, row, 3);
|
||||
cache_behind_slider_ = new FloatSlider();
|
||||
cache_behind_slider_->SetMinimum(0);
|
||||
cache_behind_slider_->SetFormat(tr("%1 seconds"));
|
||||
cache_behind_slider_->SetValue(
|
||||
OLIVE_CONFIG("DiskCacheBehind").value<rational>().toDouble());
|
||||
cache_behavior_layout->addWidget(cache_behind_slider_, row, 3);
|
||||
|
||||
outer_layout->addStretch();
|
||||
outer_layout->addStretch();
|
||||
}
|
||||
|
||||
bool PreferencesDiskTab::Validate()
|
||||
{
|
||||
if (disk_cache_location_->text() != default_disk_cache_folder_->GetPath()) {
|
||||
// Disk cache location is changing
|
||||
if (disk_cache_location_->text() != default_disk_cache_folder_->GetPath()) {
|
||||
// Disk cache location is changing
|
||||
|
||||
// Check if the user is okay with invalidating the current cache
|
||||
if (!DiskManager::ShowDiskCacheChangeConfirmationDialog(this)) {
|
||||
return false;
|
||||
}
|
||||
// Check if the user is okay with invalidating the current cache
|
||||
if (!DiskManager::ShowDiskCacheChangeConfirmationDialog(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check validity of the new path
|
||||
if (!FileFunctions::DirectoryIsValid(disk_cache_location_->text())) {
|
||||
QMessageBox::critical(this,
|
||||
tr("Disk Cache"),
|
||||
tr("Failed to set disk cache location. Access was denied."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Check validity of the new path
|
||||
if (!FileFunctions::DirectoryIsValid(disk_cache_location_->text())) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Disk Cache"),
|
||||
tr("Failed to set disk cache location. Access was denied."));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PreferencesDiskTab::Accept(MultiUndoCommand *command)
|
||||
{
|
||||
Q_UNUSED(command)
|
||||
Q_UNUSED(command)
|
||||
|
||||
if (disk_cache_location_->text() != default_disk_cache_folder_->GetPath()) {
|
||||
default_disk_cache_folder_->SetPath(disk_cache_location_->text());
|
||||
}
|
||||
if (disk_cache_location_->text() != default_disk_cache_folder_->GetPath()) {
|
||||
default_disk_cache_folder_->SetPath(disk_cache_location_->text());
|
||||
}
|
||||
|
||||
OLIVE_CONFIG("DiskCacheBehind") = QVariant::fromValue(rational::fromDouble(cache_behind_slider_->GetValue()));
|
||||
OLIVE_CONFIG("DiskCacheAhead") = QVariant::fromValue(rational::fromDouble(cache_ahead_slider_->GetValue()));
|
||||
OLIVE_CONFIG("DiskCacheBehind") = QVariant::fromValue(
|
||||
rational::fromDouble(cache_behind_slider_->GetValue()));
|
||||
OLIVE_CONFIG("DiskCacheAhead") = QVariant::fromValue(
|
||||
rational::fromDouble(cache_ahead_slider_->GetValue()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,27 +30,26 @@
|
||||
#include "widget/slider/floatslider.h"
|
||||
#include "widget/path/pathwidget.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class PreferencesDiskTab : public ConfigDialogBaseTab
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class PreferencesDiskTab : public ConfigDialogBaseTab {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesDiskTab();
|
||||
PreferencesDiskTab();
|
||||
|
||||
virtual bool Validate() override;
|
||||
virtual bool Validate() override;
|
||||
|
||||
virtual void Accept(MultiUndoCommand* command) override;
|
||||
virtual void Accept(MultiUndoCommand *command) override;
|
||||
|
||||
private:
|
||||
PathWidget* disk_cache_location_;
|
||||
PathWidget *disk_cache_location_;
|
||||
|
||||
FloatSlider* cache_ahead_slider_;
|
||||
FloatSlider *cache_ahead_slider_;
|
||||
|
||||
FloatSlider* cache_behind_slider_;
|
||||
|
||||
DiskCacheFolder* default_disk_cache_folder_;
|
||||
FloatSlider *cache_behind_slider_;
|
||||
|
||||
DiskCacheFolder *default_disk_cache_folder_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -30,162 +30,187 @@
|
||||
#include "dialog/sequence/sequence.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
PreferencesGeneralTab::PreferencesGeneralTab()
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
{
|
||||
QGroupBox* global_groupbox = new QGroupBox(tr("Locale"));
|
||||
QGridLayout* global_layout = new QGridLayout(global_groupbox);
|
||||
layout->addWidget(global_groupbox);
|
||||
{
|
||||
QGroupBox *global_groupbox = new QGroupBox(tr("Locale"));
|
||||
QGridLayout *global_layout = new QGridLayout(global_groupbox);
|
||||
layout->addWidget(global_groupbox);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
// General -> Language
|
||||
global_layout->addWidget(new QLabel(tr("Language:")), row, 0);
|
||||
// General -> Language
|
||||
global_layout->addWidget(new QLabel(tr("Language:")), row, 0);
|
||||
|
||||
language_combobox_ = new QComboBox();
|
||||
language_combobox_ = new QComboBox();
|
||||
|
||||
// Add default language (en-US)
|
||||
QDir language_dir(QStringLiteral(":/ts"));
|
||||
QStringList languages = language_dir.entryList();
|
||||
foreach (const QString& l, languages) {
|
||||
AddLanguage(l);
|
||||
}
|
||||
// Add default language (en-US)
|
||||
QDir language_dir(QStringLiteral(":/ts"));
|
||||
QStringList languages = language_dir.entryList();
|
||||
foreach (const QString &l, languages) {
|
||||
AddLanguage(l);
|
||||
}
|
||||
|
||||
QString current_language = OLIVE_CONFIG("Language").toString();
|
||||
if (current_language.isEmpty()) {
|
||||
// No configured language, use system language
|
||||
current_language = QLocale::system().name();
|
||||
QString current_language = OLIVE_CONFIG("Language").toString();
|
||||
if (current_language.isEmpty()) {
|
||||
// No configured language, use system language
|
||||
current_language = QLocale::system().name();
|
||||
|
||||
// If we don't have a language for this, default to en_US
|
||||
if (!languages.contains(current_language)) {
|
||||
current_language = QStringLiteral("en_US");
|
||||
}
|
||||
}
|
||||
language_combobox_->setCurrentIndex(languages.indexOf(current_language));
|
||||
// If we don't have a language for this, default to en_US
|
||||
if (!languages.contains(current_language)) {
|
||||
current_language = QStringLiteral("en_US");
|
||||
}
|
||||
}
|
||||
language_combobox_->setCurrentIndex(
|
||||
languages.indexOf(current_language));
|
||||
|
||||
global_layout->addWidget(language_combobox_, row, 1);
|
||||
}
|
||||
global_layout->addWidget(language_combobox_, row, 1);
|
||||
}
|
||||
|
||||
{
|
||||
QGroupBox* timeline_groupbox = new QGroupBox(tr("Timeline"));
|
||||
QGridLayout* timeline_layout = new QGridLayout(timeline_groupbox);
|
||||
layout->addWidget(timeline_groupbox);
|
||||
{
|
||||
QGroupBox *timeline_groupbox = new QGroupBox(tr("Timeline"));
|
||||
QGridLayout *timeline_layout = new QGridLayout(timeline_groupbox);
|
||||
layout->addWidget(timeline_groupbox);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
QLabel* autoscroll_lbl = new QLabel(tr("Auto-Scroll Method:"));
|
||||
autoscroll_lbl->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
timeline_layout->addWidget(autoscroll_lbl, row, 0);
|
||||
QLabel *autoscroll_lbl = new QLabel(tr("Auto-Scroll Method:"));
|
||||
autoscroll_lbl->setSizePolicy(QSizePolicy::Expanding,
|
||||
QSizePolicy::Expanding);
|
||||
timeline_layout->addWidget(autoscroll_lbl, row, 0);
|
||||
|
||||
// ComboBox indices match enum indices
|
||||
autoscroll_method_ = new QComboBox();
|
||||
autoscroll_method_->addItem(tr("None"), AutoScroll::kNone);
|
||||
autoscroll_method_->addItem(tr("Page Scrolling"), AutoScroll::kPage);
|
||||
autoscroll_method_->addItem(tr("Smooth Scrolling"), AutoScroll::kSmooth);
|
||||
autoscroll_method_->setCurrentIndex(OLIVE_CONFIG("Autoscroll").toInt());
|
||||
timeline_layout->addWidget(autoscroll_method_, row, 1);
|
||||
// ComboBox indices match enum indices
|
||||
autoscroll_method_ = new QComboBox();
|
||||
autoscroll_method_->addItem(tr("None"), AutoScroll::kNone);
|
||||
autoscroll_method_->addItem(tr("Page Scrolling"), AutoScroll::kPage);
|
||||
autoscroll_method_->addItem(tr("Smooth Scrolling"),
|
||||
AutoScroll::kSmooth);
|
||||
autoscroll_method_->setCurrentIndex(OLIVE_CONFIG("Autoscroll").toInt());
|
||||
timeline_layout->addWidget(autoscroll_method_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
timeline_layout->addWidget(new QLabel(tr("Rectified Waveforms:")), row, 0);
|
||||
timeline_layout->addWidget(new QLabel(tr("Rectified Waveforms:")), row,
|
||||
0);
|
||||
|
||||
rectified_waveforms_ = new QCheckBox();
|
||||
rectified_waveforms_->setChecked(OLIVE_CONFIG("RectifiedWaveforms").toBool());
|
||||
timeline_layout->addWidget(rectified_waveforms_, row, 1);
|
||||
rectified_waveforms_ = new QCheckBox();
|
||||
rectified_waveforms_->setChecked(
|
||||
OLIVE_CONFIG("RectifiedWaveforms").toBool());
|
||||
timeline_layout->addWidget(rectified_waveforms_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
timeline_layout->addWidget(new QLabel(tr("Default Still Image Length:")), row, 0);
|
||||
timeline_layout->addWidget(
|
||||
new QLabel(tr("Default Still Image Length:")), row, 0);
|
||||
|
||||
default_still_length_ = new RationalSlider();
|
||||
default_still_length_->SetMinimum(rational(100, 1000));
|
||||
default_still_length_->SetTimebase(rational(100, 1000));
|
||||
default_still_length_->SetFormat(tr("%1 seconds"));
|
||||
default_still_length_->SetValue(OLIVE_CONFIG("DefaultStillLength").value<rational>());
|
||||
timeline_layout->addWidget(default_still_length_);
|
||||
}
|
||||
default_still_length_ = new RationalSlider();
|
||||
default_still_length_->SetMinimum(rational(100, 1000));
|
||||
default_still_length_->SetTimebase(rational(100, 1000));
|
||||
default_still_length_->SetFormat(tr("%1 seconds"));
|
||||
default_still_length_->SetValue(
|
||||
OLIVE_CONFIG("DefaultStillLength").value<rational>());
|
||||
timeline_layout->addWidget(default_still_length_);
|
||||
}
|
||||
|
||||
{
|
||||
QGroupBox* autorecovery_groupbox = new QGroupBox(tr("Auto-Recovery"));
|
||||
QGridLayout* autorecovery_layout = new QGridLayout(autorecovery_groupbox);
|
||||
layout->addWidget(autorecovery_groupbox);
|
||||
{
|
||||
QGroupBox *autorecovery_groupbox = new QGroupBox(tr("Auto-Recovery"));
|
||||
QGridLayout *autorecovery_layout =
|
||||
new QGridLayout(autorecovery_groupbox);
|
||||
layout->addWidget(autorecovery_groupbox);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
autorecovery_layout->addWidget(new QLabel(tr("Enable Auto-Recovery:")), row, 0);
|
||||
autorecovery_layout->addWidget(new QLabel(tr("Enable Auto-Recovery:")),
|
||||
row, 0);
|
||||
|
||||
autorecovery_enabled_ = new QCheckBox();
|
||||
autorecovery_enabled_->setChecked(OLIVE_CONFIG("AutorecoveryEnabled").toBool());
|
||||
autorecovery_layout->addWidget(autorecovery_enabled_, row, 1);
|
||||
autorecovery_enabled_ = new QCheckBox();
|
||||
autorecovery_enabled_->setChecked(
|
||||
OLIVE_CONFIG("AutorecoveryEnabled").toBool());
|
||||
autorecovery_layout->addWidget(autorecovery_enabled_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
autorecovery_layout->addWidget(new QLabel(tr("Auto-Recovery Interval:")), row, 0);
|
||||
autorecovery_layout->addWidget(
|
||||
new QLabel(tr("Auto-Recovery Interval:")), row, 0);
|
||||
|
||||
autorecovery_interval_ = new IntegerSlider();
|
||||
autorecovery_interval_->SetMinimum(1);
|
||||
autorecovery_interval_->SetMaximum(60);
|
||||
autorecovery_interval_->SetFormat(QT_TRANSLATE_N_NOOP("olive::SliderBase", "%n minute(s)"), true);
|
||||
autorecovery_interval_->SetValue(OLIVE_CONFIG("AutorecoveryInterval").toLongLong());
|
||||
autorecovery_layout->addWidget(autorecovery_interval_, row, 1);
|
||||
autorecovery_interval_ = new IntegerSlider();
|
||||
autorecovery_interval_->SetMinimum(1);
|
||||
autorecovery_interval_->SetMaximum(60);
|
||||
autorecovery_interval_->SetFormat(
|
||||
QT_TRANSLATE_N_NOOP("olive::SliderBase", "%n minute(s)"), true);
|
||||
autorecovery_interval_->SetValue(
|
||||
OLIVE_CONFIG("AutorecoveryInterval").toLongLong());
|
||||
autorecovery_layout->addWidget(autorecovery_interval_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
autorecovery_layout->addWidget(new QLabel(tr("Maximum Versions Per Project:")), row, 0);
|
||||
autorecovery_layout->addWidget(
|
||||
new QLabel(tr("Maximum Versions Per Project:")), row, 0);
|
||||
|
||||
autorecovery_maximum_ = new IntegerSlider();
|
||||
autorecovery_maximum_->SetMinimum(1);
|
||||
autorecovery_maximum_->SetMaximum(1000);
|
||||
autorecovery_maximum_->SetValue(OLIVE_CONFIG("AutorecoveryMaximum").toLongLong());
|
||||
autorecovery_layout->addWidget(autorecovery_maximum_, row, 1);
|
||||
autorecovery_maximum_ = new IntegerSlider();
|
||||
autorecovery_maximum_->SetMinimum(1);
|
||||
autorecovery_maximum_->SetMaximum(1000);
|
||||
autorecovery_maximum_->SetValue(
|
||||
OLIVE_CONFIG("AutorecoveryMaximum").toLongLong());
|
||||
autorecovery_layout->addWidget(autorecovery_maximum_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
QPushButton* browse_autorecoveries = new QPushButton(tr("Browse Auto-Recoveries"));
|
||||
connect(browse_autorecoveries, &QPushButton::clicked, Core::instance(), &Core::BrowseAutoRecoveries);
|
||||
autorecovery_layout->addWidget(browse_autorecoveries, row, 1);
|
||||
}
|
||||
QPushButton *browse_autorecoveries =
|
||||
new QPushButton(tr("Browse Auto-Recoveries"));
|
||||
connect(browse_autorecoveries, &QPushButton::clicked, Core::instance(),
|
||||
&Core::BrowseAutoRecoveries);
|
||||
autorecovery_layout->addWidget(browse_autorecoveries, row, 1);
|
||||
}
|
||||
|
||||
layout->addStretch();
|
||||
layout->addStretch();
|
||||
}
|
||||
|
||||
void PreferencesGeneralTab::Accept(MultiUndoCommand *command)
|
||||
{
|
||||
Q_UNUSED(command)
|
||||
Q_UNUSED(command)
|
||||
|
||||
OLIVE_CONFIG("RectifiedWaveforms") = rectified_waveforms_->isChecked();
|
||||
OLIVE_CONFIG("RectifiedWaveforms") = rectified_waveforms_->isChecked();
|
||||
|
||||
OLIVE_CONFIG("Autoscroll") = autoscroll_method_->currentData();
|
||||
OLIVE_CONFIG("Autoscroll") = autoscroll_method_->currentData();
|
||||
|
||||
OLIVE_CONFIG("DefaultStillLength") = QVariant::fromValue(default_still_length_->GetValue());
|
||||
OLIVE_CONFIG("DefaultStillLength") =
|
||||
QVariant::fromValue(default_still_length_->GetValue());
|
||||
|
||||
QString set_language = language_combobox_->currentData().toString();
|
||||
if (QLocale::system().name() == set_language) {
|
||||
// Language is set to the system, assume this is effectively "auto"
|
||||
set_language = QString();
|
||||
}
|
||||
QString set_language = language_combobox_->currentData().toString();
|
||||
if (QLocale::system().name() == set_language) {
|
||||
// Language is set to the system, assume this is effectively "auto"
|
||||
set_language = QString();
|
||||
}
|
||||
|
||||
// If the language has changed, set it now
|
||||
if (OLIVE_CONFIG("Language").toString() != set_language) {
|
||||
OLIVE_CONFIG("Language") = set_language;
|
||||
Core::instance()->SetLanguage(set_language.isEmpty() ? QLocale::system().name() : set_language);
|
||||
}
|
||||
// If the language has changed, set it now
|
||||
if (OLIVE_CONFIG("Language").toString() != set_language) {
|
||||
OLIVE_CONFIG("Language") = set_language;
|
||||
Core::instance()->SetLanguage(
|
||||
set_language.isEmpty() ? QLocale::system().name() : set_language);
|
||||
}
|
||||
|
||||
OLIVE_CONFIG("AutorecoveryEnabled") = autorecovery_enabled_->isChecked();
|
||||
OLIVE_CONFIG("AutorecoveryInterval") = QVariant::fromValue(autorecovery_interval_->GetValue());
|
||||
OLIVE_CONFIG("AutorecoveryMaximum") = QVariant::fromValue(autorecovery_maximum_->GetValue());
|
||||
Core::instance()->SetAutorecoveryInterval(autorecovery_interval_->GetValue());
|
||||
OLIVE_CONFIG("AutorecoveryEnabled") = autorecovery_enabled_->isChecked();
|
||||
OLIVE_CONFIG("AutorecoveryInterval") =
|
||||
QVariant::fromValue(autorecovery_interval_->GetValue());
|
||||
OLIVE_CONFIG("AutorecoveryMaximum") =
|
||||
QVariant::fromValue(autorecovery_maximum_->GetValue());
|
||||
Core::instance()->SetAutorecoveryInterval(
|
||||
autorecovery_interval_->GetValue());
|
||||
}
|
||||
|
||||
void PreferencesGeneralTab::AddLanguage(const QString &locale_name)
|
||||
{
|
||||
language_combobox_->addItem(tr("%1 (%2)").arg(QLocale(locale_name).nativeLanguageName(),
|
||||
locale_name));;
|
||||
language_combobox_->setItemData(language_combobox_->count() - 1, locale_name);
|
||||
language_combobox_->addItem(tr("%1 (%2)").arg(
|
||||
QLocale(locale_name).nativeLanguageName(), locale_name));
|
||||
;
|
||||
language_combobox_->setItemData(language_combobox_->count() - 1,
|
||||
locale_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,33 +30,32 @@
|
||||
#include "widget/slider/rationalslider.h"
|
||||
#include "widget/slider/integerslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class PreferencesGeneralTab : public ConfigDialogBaseTab
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesGeneralTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand* command) override;
|
||||
class PreferencesGeneralTab : public ConfigDialogBaseTab {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesGeneralTab();
|
||||
|
||||
virtual void Accept(MultiUndoCommand *command) override;
|
||||
|
||||
private:
|
||||
void AddLanguage(const QString& locale_name);
|
||||
void AddLanguage(const QString &locale_name);
|
||||
|
||||
QComboBox* language_combobox_;
|
||||
QComboBox *language_combobox_;
|
||||
|
||||
QComboBox* autoscroll_method_;
|
||||
QComboBox *autoscroll_method_;
|
||||
|
||||
QCheckBox* rectified_waveforms_;
|
||||
QCheckBox *rectified_waveforms_;
|
||||
|
||||
RationalSlider* default_still_length_;
|
||||
RationalSlider *default_still_length_;
|
||||
|
||||
QCheckBox* autorecovery_enabled_;
|
||||
QCheckBox *autorecovery_enabled_;
|
||||
|
||||
IntegerSlider* autorecovery_interval_;
|
||||
|
||||
IntegerSlider* autorecovery_maximum_;
|
||||
IntegerSlider *autorecovery_interval_;
|
||||
|
||||
IntegerSlider *autorecovery_maximum_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,224 +29,250 @@
|
||||
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
PreferencesKeyboardTab::PreferencesKeyboardTab(MainWindow *main_window) :
|
||||
main_window_(main_window)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* shortcut_layout = new QVBoxLayout(this);
|
||||
|
||||
QLineEdit* key_search_line = new QLineEdit();
|
||||
key_search_line->setPlaceholderText(tr("Search for action or shortcut"));
|
||||
connect(key_search_line, SIGNAL(textChanged(const QString &)), this, SLOT(refine_shortcut_list(const QString &)));
|
||||
PreferencesKeyboardTab::PreferencesKeyboardTab(MainWindow *main_window)
|
||||
: main_window_(main_window)
|
||||
{
|
||||
QVBoxLayout *shortcut_layout = new QVBoxLayout(this);
|
||||
|
||||
shortcut_layout->addWidget(key_search_line);
|
||||
QLineEdit *key_search_line = new QLineEdit();
|
||||
key_search_line->setPlaceholderText(tr("Search for action or shortcut"));
|
||||
connect(key_search_line, SIGNAL(textChanged(const QString &)), this,
|
||||
SLOT(refine_shortcut_list(const QString &)));
|
||||
|
||||
keyboard_tree_ = new QTreeWidget();
|
||||
QTreeWidgetItem* tree_header = keyboard_tree_->headerItem();
|
||||
tree_header->setText(0, tr("Action"));
|
||||
tree_header->setText(1, tr("Shortcut"));
|
||||
shortcut_layout->addWidget(keyboard_tree_);
|
||||
shortcut_layout->addWidget(key_search_line);
|
||||
|
||||
QHBoxLayout* reset_shortcut_layout = new QHBoxLayout();
|
||||
keyboard_tree_ = new QTreeWidget();
|
||||
QTreeWidgetItem *tree_header = keyboard_tree_->headerItem();
|
||||
tree_header->setText(0, tr("Action"));
|
||||
tree_header->setText(1, tr("Shortcut"));
|
||||
shortcut_layout->addWidget(keyboard_tree_);
|
||||
|
||||
QPushButton* import_shortcut_button = new QPushButton(tr("Import"));
|
||||
reset_shortcut_layout->addWidget(import_shortcut_button);
|
||||
connect(import_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(load_shortcut_file()));
|
||||
QHBoxLayout *reset_shortcut_layout = new QHBoxLayout();
|
||||
|
||||
QPushButton* export_shortcut_button = new QPushButton(tr("Export"));
|
||||
reset_shortcut_layout->addWidget(export_shortcut_button);
|
||||
connect(export_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(save_shortcut_file()));
|
||||
QPushButton *import_shortcut_button = new QPushButton(tr("Import"));
|
||||
reset_shortcut_layout->addWidget(import_shortcut_button);
|
||||
connect(import_shortcut_button, SIGNAL(clicked(bool)), this,
|
||||
SLOT(load_shortcut_file()));
|
||||
|
||||
reset_shortcut_layout->addStretch();
|
||||
QPushButton *export_shortcut_button = new QPushButton(tr("Export"));
|
||||
reset_shortcut_layout->addWidget(export_shortcut_button);
|
||||
connect(export_shortcut_button, SIGNAL(clicked(bool)), this,
|
||||
SLOT(save_shortcut_file()));
|
||||
|
||||
QPushButton* reset_selected_shortcut_button = new QPushButton(tr("Reset Selected"));
|
||||
reset_shortcut_layout->addWidget(reset_selected_shortcut_button);
|
||||
connect(reset_selected_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_default_shortcut()));
|
||||
reset_shortcut_layout->addStretch();
|
||||
|
||||
QPushButton* reset_all_shortcut_button = new QPushButton(tr("Reset All"));
|
||||
reset_shortcut_layout->addWidget(reset_all_shortcut_button);
|
||||
connect(reset_all_shortcut_button, SIGNAL(clicked(bool)), this, SLOT(reset_all_shortcuts()));
|
||||
QPushButton *reset_selected_shortcut_button =
|
||||
new QPushButton(tr("Reset Selected"));
|
||||
reset_shortcut_layout->addWidget(reset_selected_shortcut_button);
|
||||
connect(reset_selected_shortcut_button, SIGNAL(clicked(bool)), this,
|
||||
SLOT(reset_default_shortcut()));
|
||||
|
||||
shortcut_layout->addLayout(reset_shortcut_layout);
|
||||
QPushButton *reset_all_shortcut_button = new QPushButton(tr("Reset All"));
|
||||
reset_shortcut_layout->addWidget(reset_all_shortcut_button);
|
||||
connect(reset_all_shortcut_button, SIGNAL(clicked(bool)), this,
|
||||
SLOT(reset_all_shortcuts()));
|
||||
|
||||
setup_kbd_shortcuts(main_window_->menuBar());
|
||||
shortcut_layout->addLayout(reset_shortcut_layout);
|
||||
|
||||
setup_kbd_shortcuts(main_window_->menuBar());
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::Accept(MultiUndoCommand *command)
|
||||
{
|
||||
Q_UNUSED(command)
|
||||
Q_UNUSED(command)
|
||||
|
||||
// Save keyboard shortcuts
|
||||
for (int i=0;i<key_shortcut_fields_.size();i++) {
|
||||
key_shortcut_fields_.at(i)->set_action_shortcut();
|
||||
}
|
||||
// Save keyboard shortcuts
|
||||
for (int i = 0; i < key_shortcut_fields_.size(); i++) {
|
||||
key_shortcut_fields_.at(i)->set_action_shortcut();
|
||||
}
|
||||
|
||||
main_window_->SaveLayout();
|
||||
main_window_->SaveLayout();
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::setup_kbd_shortcuts(QMenuBar* menubar) {
|
||||
QList<QAction*> menus = menubar->actions();
|
||||
void PreferencesKeyboardTab::setup_kbd_shortcuts(QMenuBar *menubar)
|
||||
{
|
||||
QList<QAction *> menus = menubar->actions();
|
||||
|
||||
for (int i=0;i<menus.size();i++) {
|
||||
QMenu* menu = menus.at(i)->menu();
|
||||
for (int i = 0; i < menus.size(); i++) {
|
||||
QMenu *menu = menus.at(i)->menu();
|
||||
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(keyboard_tree_);
|
||||
item->setText(0, menu->title().replace("&", ""));
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(keyboard_tree_);
|
||||
item->setText(0, menu->title().replace("&", ""));
|
||||
|
||||
keyboard_tree_->addTopLevelItem(item);
|
||||
keyboard_tree_->addTopLevelItem(item);
|
||||
|
||||
setup_kbd_shortcut_worker(menu, item);
|
||||
}
|
||||
setup_kbd_shortcut_worker(menu, item);
|
||||
}
|
||||
|
||||
for (int i=0;i<key_shortcut_items_.size();i++) {
|
||||
if (!key_shortcut_actions_.at(i)->property("id").isNull()) {
|
||||
KeySequenceEditor* editor = new KeySequenceEditor(keyboard_tree_, key_shortcut_actions_.at(i));
|
||||
keyboard_tree_->setItemWidget(key_shortcut_items_.at(i), 1, editor);
|
||||
key_shortcut_fields_.append(editor);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < key_shortcut_items_.size(); i++) {
|
||||
if (!key_shortcut_actions_.at(i)->property("id").isNull()) {
|
||||
KeySequenceEditor *editor = new KeySequenceEditor(
|
||||
keyboard_tree_, key_shortcut_actions_.at(i));
|
||||
keyboard_tree_->setItemWidget(key_shortcut_items_.at(i), 1, editor);
|
||||
key_shortcut_fields_.append(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent) {
|
||||
QList<QAction*> actions = menu->actions();
|
||||
for (int i=0;i<actions.size();i++) {
|
||||
QAction* a = actions.at(i);
|
||||
void PreferencesKeyboardTab::setup_kbd_shortcut_worker(QMenu *menu,
|
||||
QTreeWidgetItem *parent)
|
||||
{
|
||||
QList<QAction *> actions = menu->actions();
|
||||
for (int i = 0; i < actions.size(); i++) {
|
||||
QAction *a = actions.at(i);
|
||||
|
||||
if (!a->isSeparator() && a->property("keyignore").isNull()) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(parent);
|
||||
item->setText(0, a->text().replace("&", ""));
|
||||
if (!a->isSeparator() && a->property("keyignore").isNull()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(parent);
|
||||
item->setText(0, a->text().replace("&", ""));
|
||||
|
||||
parent->addChild(item);
|
||||
parent->addChild(item);
|
||||
|
||||
if (a->menu() != nullptr) {
|
||||
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
setup_kbd_shortcut_worker(a->menu(), item);
|
||||
} else {
|
||||
key_shortcut_items_.append(item);
|
||||
key_shortcut_actions_.append(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (a->menu() != nullptr) {
|
||||
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
setup_kbd_shortcut_worker(a->menu(), item);
|
||||
} else {
|
||||
key_shortcut_items_.append(item);
|
||||
key_shortcut_actions_.append(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::reset_default_shortcut() {
|
||||
QList<QTreeWidgetItem*> items = keyboard_tree_->selectedItems();
|
||||
for (int i=0;i<items.size();i++) {
|
||||
QTreeWidgetItem* item = keyboard_tree_->selectedItems().at(i);
|
||||
static_cast<KeySequenceEditor*>(keyboard_tree_->itemWidget(item, 1))->reset_to_default();
|
||||
}
|
||||
void PreferencesKeyboardTab::reset_default_shortcut()
|
||||
{
|
||||
QList<QTreeWidgetItem *> items = keyboard_tree_->selectedItems();
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
QTreeWidgetItem *item = keyboard_tree_->selectedItems().at(i);
|
||||
static_cast<KeySequenceEditor *>(keyboard_tree_->itemWidget(item, 1))
|
||||
->reset_to_default();
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::reset_all_shortcuts() {
|
||||
if (QMessageBox::question(
|
||||
this,
|
||||
tr("Confirm Reset All Shortcuts"),
|
||||
tr("Are you sure you wish to reset all keyboard shortcuts to their defaults?"),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
for (int i=0;i<key_shortcut_fields_.size();i++) {
|
||||
key_shortcut_fields_.at(i)->reset_to_default();
|
||||
}
|
||||
}
|
||||
void PreferencesKeyboardTab::reset_all_shortcuts()
|
||||
{
|
||||
if (QMessageBox::question(
|
||||
this, tr("Confirm Reset All Shortcuts"),
|
||||
tr("Are you sure you wish to reset all keyboard shortcuts to their defaults?"),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
for (int i = 0; i < key_shortcut_fields_.size(); i++) {
|
||||
key_shortcut_fields_.at(i)->reset_to_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PreferencesKeyboardTab::refine_shortcut_list(const QString &s, QTreeWidgetItem* parent) {
|
||||
if (parent == nullptr) {
|
||||
for (int i=0;i<keyboard_tree_->topLevelItemCount();i++) {
|
||||
refine_shortcut_list(s, keyboard_tree_->topLevelItem(i));
|
||||
}
|
||||
bool PreferencesKeyboardTab::refine_shortcut_list(const QString &s,
|
||||
QTreeWidgetItem *parent)
|
||||
{
|
||||
if (parent == nullptr) {
|
||||
for (int i = 0; i < keyboard_tree_->topLevelItemCount(); i++) {
|
||||
refine_shortcut_list(s, keyboard_tree_->topLevelItem(i));
|
||||
}
|
||||
|
||||
// Return value is `all_children_are_hidden` which doesn't matter at the top level
|
||||
return false;
|
||||
} else {
|
||||
parent->setExpanded(!s.isEmpty());
|
||||
// Return value is `all_children_are_hidden` which doesn't matter at the top level
|
||||
return false;
|
||||
} else {
|
||||
parent->setExpanded(!s.isEmpty());
|
||||
|
||||
bool all_children_are_hidden = !s.isEmpty();
|
||||
bool all_children_are_hidden = !s.isEmpty();
|
||||
|
||||
for (int i=0;i<parent->childCount();i++) {
|
||||
QTreeWidgetItem* item = parent->child(i);
|
||||
if (item->childCount() > 0) {
|
||||
if (!refine_shortcut_list(s, item)) {
|
||||
all_children_are_hidden = false;
|
||||
}
|
||||
} else {
|
||||
item->setHidden(false);
|
||||
if (s.isEmpty()) {
|
||||
all_children_are_hidden = false;
|
||||
} else {
|
||||
QString shortcut;
|
||||
if (keyboard_tree_->itemWidget(item, 1) != nullptr) {
|
||||
shortcut = static_cast<QKeySequenceEdit*>(keyboard_tree_->itemWidget(item, 1))->keySequence().toString();
|
||||
}
|
||||
if (item->text(0).contains(s, Qt::CaseInsensitive) || shortcut.contains(s, Qt::CaseInsensitive)) {
|
||||
all_children_are_hidden = false;
|
||||
} else {
|
||||
item->setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < parent->childCount(); i++) {
|
||||
QTreeWidgetItem *item = parent->child(i);
|
||||
if (item->childCount() > 0) {
|
||||
if (!refine_shortcut_list(s, item)) {
|
||||
all_children_are_hidden = false;
|
||||
}
|
||||
} else {
|
||||
item->setHidden(false);
|
||||
if (s.isEmpty()) {
|
||||
all_children_are_hidden = false;
|
||||
} else {
|
||||
QString shortcut;
|
||||
if (keyboard_tree_->itemWidget(item, 1) != nullptr) {
|
||||
shortcut = static_cast<QKeySequenceEdit *>(
|
||||
keyboard_tree_->itemWidget(item, 1))
|
||||
->keySequence()
|
||||
.toString();
|
||||
}
|
||||
if (item->text(0).contains(s, Qt::CaseInsensitive) ||
|
||||
shortcut.contains(s, Qt::CaseInsensitive)) {
|
||||
all_children_are_hidden = false;
|
||||
} else {
|
||||
item->setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parent->text(0).contains(s, Qt::CaseInsensitive)) all_children_are_hidden = false;
|
||||
if (parent->text(0).contains(s, Qt::CaseInsensitive))
|
||||
all_children_are_hidden = false;
|
||||
|
||||
parent->setHidden(all_children_are_hidden);
|
||||
parent->setHidden(all_children_are_hidden);
|
||||
|
||||
return all_children_are_hidden;
|
||||
}
|
||||
return all_children_are_hidden;
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::load_shortcut_file() {
|
||||
QString fn = QFileDialog::getOpenFileName(this, tr("Import Keyboard Shortcuts"));
|
||||
if (!fn.isEmpty()) {
|
||||
QFile f(fn);
|
||||
if (f.exists() && f.open(QFile::ReadOnly)) {
|
||||
QString ba = f.readAll();
|
||||
f.close();
|
||||
for (int i=0;i<key_shortcut_fields_.size();i++) {
|
||||
int index = ba.indexOf(key_shortcut_fields_.at(i)->action_name());
|
||||
if (index == 0 || (index > 0 && ba.at(index-1) == '\n')) {
|
||||
while (index < ba.size() && ba.at(index) != '\t') index++;
|
||||
QString ks;
|
||||
index++;
|
||||
while (index < ba.size() && ba.at(index) != '\n') {
|
||||
ks.append(ba.at(index));
|
||||
index++;
|
||||
}
|
||||
key_shortcut_fields_.at(i)->setKeySequence(ks);
|
||||
} else {
|
||||
key_shortcut_fields_.at(i)->reset_to_default();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Error saving shortcuts"),
|
||||
tr("Failed to open file for reading")
|
||||
);
|
||||
}
|
||||
}
|
||||
void PreferencesKeyboardTab::load_shortcut_file()
|
||||
{
|
||||
QString fn =
|
||||
QFileDialog::getOpenFileName(this, tr("Import Keyboard Shortcuts"));
|
||||
if (!fn.isEmpty()) {
|
||||
QFile f(fn);
|
||||
if (f.exists() && f.open(QFile::ReadOnly)) {
|
||||
QString ba = f.readAll();
|
||||
f.close();
|
||||
for (int i = 0; i < key_shortcut_fields_.size(); i++) {
|
||||
int index =
|
||||
ba.indexOf(key_shortcut_fields_.at(i)->action_name());
|
||||
if (index == 0 || (index > 0 && ba.at(index - 1) == '\n')) {
|
||||
while (index < ba.size() && ba.at(index) != '\t')
|
||||
index++;
|
||||
QString ks;
|
||||
index++;
|
||||
while (index < ba.size() && ba.at(index) != '\n') {
|
||||
ks.append(ba.at(index));
|
||||
index++;
|
||||
}
|
||||
key_shortcut_fields_.at(i)->setKeySequence(ks);
|
||||
} else {
|
||||
key_shortcut_fields_.at(i)->reset_to_default();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error saving shortcuts"),
|
||||
tr("Failed to open file for reading"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesKeyboardTab::save_shortcut_file() {
|
||||
QString fn = QFileDialog::getSaveFileName(this, tr("Export Keyboard Shortcuts"));
|
||||
if (!fn.isEmpty()) {
|
||||
QFile f(fn);
|
||||
if (f.open(QFile::WriteOnly)) {
|
||||
bool start = true;
|
||||
for (int i=0;i<key_shortcut_fields_.size();i++) {
|
||||
QString s = key_shortcut_fields_.at(i)->export_shortcut();
|
||||
if (!s.isEmpty()) {
|
||||
if (!start) f.write("\n");
|
||||
f.write(s.toUtf8());
|
||||
start = false;
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
QMessageBox::information(this, tr("Export Shortcuts"), tr("Shortcuts exported successfully"));
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error saving shortcuts"), tr("Failed to open file for writing"));
|
||||
}
|
||||
}
|
||||
void PreferencesKeyboardTab::save_shortcut_file()
|
||||
{
|
||||
QString fn =
|
||||
QFileDialog::getSaveFileName(this, tr("Export Keyboard Shortcuts"));
|
||||
if (!fn.isEmpty()) {
|
||||
QFile f(fn);
|
||||
if (f.open(QFile::WriteOnly)) {
|
||||
bool start = true;
|
||||
for (int i = 0; i < key_shortcut_fields_.size(); i++) {
|
||||
QString s = key_shortcut_fields_.at(i)->export_shortcut();
|
||||
if (!s.isEmpty()) {
|
||||
if (!start)
|
||||
f.write("\n");
|
||||
f.write(s.toUtf8());
|
||||
start = false;
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
QMessageBox::information(this, tr("Export Shortcuts"),
|
||||
tr("Shortcuts exported successfully"));
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error saving shortcuts"),
|
||||
tr("Failed to open file for writing"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,42 +27,42 @@
|
||||
#include "dialog/configbase/configdialogbase.h"
|
||||
#include "../keysequenceeditor.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class MainWindow;
|
||||
|
||||
class PreferencesKeyboardTab : public ConfigDialogBaseTab
|
||||
{
|
||||
Q_OBJECT
|
||||
class PreferencesKeyboardTab : public ConfigDialogBaseTab {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PreferencesKeyboardTab(MainWindow* main_window);
|
||||
PreferencesKeyboardTab(MainWindow *main_window);
|
||||
|
||||
virtual void Accept(MultiUndoCommand* command) override;
|
||||
virtual void Accept(MultiUndoCommand *command) override;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
/**
|
||||
* @brief Show a file dialog to load an external shortcut preset from file
|
||||
*/
|
||||
void load_shortcut_file();
|
||||
void load_shortcut_file();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Show a file dialog to save an external shortcut preset from file
|
||||
*/
|
||||
void save_shortcut_file();
|
||||
void save_shortcut_file();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Reset all selected shortcuts in keyboard_tree to their defaults
|
||||
*/
|
||||
void reset_default_shortcut();
|
||||
void reset_default_shortcut();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Reset all shortcuts indiscriminately to their defaults
|
||||
*
|
||||
* This is safe to call directly as it'll ask the user if they wish to do so before it resets.
|
||||
*/
|
||||
void reset_all_shortcuts();
|
||||
void reset_all_shortcuts();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Shows/hides shortcut entries according to a shortcut query.
|
||||
*
|
||||
* This function can be directly connected to QLineEdit::textChanged() for simplicity.
|
||||
@@ -82,19 +82,20 @@ private slots:
|
||||
* If so, TRUE is returned so the parent is shown too (even if it doesn't match the search query). If not, FALSE is
|
||||
* returned so the parent is hidden.
|
||||
*/
|
||||
bool refine_shortcut_list(const QString &s, QTreeWidgetItem* parent = nullptr);
|
||||
bool refine_shortcut_list(const QString &s,
|
||||
QTreeWidgetItem *parent = nullptr);
|
||||
|
||||
private:
|
||||
/**
|
||||
/**
|
||||
* @brief Populate keyboard shortcut panel with keyboard shortcuts from the menu bar
|
||||
*
|
||||
* @param menu
|
||||
*
|
||||
* A reference to the main application's menu bar. Usually MainWindow::menuBar().
|
||||
*/
|
||||
void setup_kbd_shortcuts(QMenuBar* menu);
|
||||
void setup_kbd_shortcuts(QMenuBar *menu);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Internal function called by setup_kbd_shortcuts() to traverse down the menu bar's hierarchy and populate the
|
||||
* shortcut panel.
|
||||
*
|
||||
@@ -110,33 +111,32 @@ private:
|
||||
*
|
||||
* The parent item to add QTreeWidgetItems to.
|
||||
*/
|
||||
void setup_kbd_shortcut_worker(QMenu* menu, QTreeWidgetItem* parent);
|
||||
void setup_kbd_shortcut_worker(QMenu *menu, QTreeWidgetItem *parent);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief UI widget for editing keyboard shortcuts
|
||||
*/
|
||||
QTreeWidget* keyboard_tree_;
|
||||
QTreeWidget *keyboard_tree_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief List of keyboard shortcut actions that can be triggered (links with key_shortcut_items and
|
||||
* key_shortcut_fields)
|
||||
*/
|
||||
QVector<QAction*> key_shortcut_actions_;
|
||||
QVector<QAction *> key_shortcut_actions_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief List of keyboard shortcut items in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<QTreeWidgetItem*> key_shortcut_items_;
|
||||
QVector<QTreeWidgetItem *> key_shortcut_items_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief List of keyboard shortcut editing fields in keyboard_tree corresponding to existing actions (links with
|
||||
* key_shortcut_actions and key_shortcut_fields)
|
||||
*/
|
||||
QVector<KeySequenceEditor*> key_shortcut_fields_;
|
||||
|
||||
MainWindow *main_window_;
|
||||
QVector<KeySequenceEditor *> key_shortcut_fields_;
|
||||
|
||||
MainWindow *main_window_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -27,116 +27,126 @@
|
||||
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super QDialog
|
||||
|
||||
ProgressDialog::ProgressDialog(const QString& message, const QString& title, QWidget *parent) :
|
||||
super(parent),
|
||||
show_progress_(true),
|
||||
first_show_(true)
|
||||
ProgressDialog::ProgressDialog(const QString &message, const QString &title,
|
||||
QWidget *parent)
|
||||
: super(parent)
|
||||
, show_progress_(true)
|
||||
, first_show_(true)
|
||||
{
|
||||
if (!title.isEmpty()) {
|
||||
setWindowTitle(title);
|
||||
}
|
||||
if (!title.isEmpty()) {
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
layout->addWidget(new QLabel(message));
|
||||
layout->addWidget(new QLabel(message));
|
||||
|
||||
bar_ = new QProgressBar();
|
||||
bar_->setMinimum(0);
|
||||
bar_->setValue(0);
|
||||
bar_->setMaximum(100);
|
||||
layout->addWidget(bar_);
|
||||
bar_ = new QProgressBar();
|
||||
bar_->setMinimum(0);
|
||||
bar_->setValue(0);
|
||||
bar_->setMaximum(100);
|
||||
layout->addWidget(bar_);
|
||||
|
||||
elapsed_timer_lbl_ = new ElapsedCounterWidget();
|
||||
layout->addWidget(elapsed_timer_lbl_);
|
||||
elapsed_timer_lbl_ = new ElapsedCounterWidget();
|
||||
layout->addWidget(elapsed_timer_lbl_);
|
||||
|
||||
QHBoxLayout* cancel_layout = new QHBoxLayout();
|
||||
layout->addLayout(cancel_layout);
|
||||
cancel_layout->setContentsMargins(0, 0, 0, 0);
|
||||
cancel_layout->setSpacing(0);
|
||||
cancel_layout->addStretch();
|
||||
QHBoxLayout *cancel_layout = new QHBoxLayout();
|
||||
layout->addLayout(cancel_layout);
|
||||
cancel_layout->setContentsMargins(0, 0, 0, 0);
|
||||
cancel_layout->setSpacing(0);
|
||||
cancel_layout->addStretch();
|
||||
|
||||
QPushButton* cancel_btn = new QPushButton(tr("Cancel"));
|
||||
QPushButton *cancel_btn = new QPushButton(tr("Cancel"));
|
||||
|
||||
// Signal that derivatives can connect to
|
||||
connect(cancel_btn, &QPushButton::clicked, this, &ProgressDialog::Cancelled, Qt::DirectConnection);
|
||||
// Signal that derivatives can connect to
|
||||
connect(cancel_btn, &QPushButton::clicked, this, &ProgressDialog::Cancelled,
|
||||
Qt::DirectConnection);
|
||||
|
||||
// Stop updating the elapsed/remaining timers
|
||||
connect(cancel_btn, &QPushButton::clicked, elapsed_timer_lbl_, &ElapsedCounterWidget::Stop);
|
||||
// Stop updating the elapsed/remaining timers
|
||||
connect(cancel_btn, &QPushButton::clicked, elapsed_timer_lbl_,
|
||||
&ElapsedCounterWidget::Stop);
|
||||
|
||||
// Disable the button so that users know they don't need to keep clicking it
|
||||
connect(cancel_btn, &QPushButton::clicked, this, &ProgressDialog::DisableSenderWidget);
|
||||
// Disable the button so that users know they don't need to keep clicking it
|
||||
connect(cancel_btn, &QPushButton::clicked, this,
|
||||
&ProgressDialog::DisableSenderWidget);
|
||||
|
||||
// Prevent the progress bar from continuing to move
|
||||
connect(cancel_btn, &QPushButton::clicked, this, &ProgressDialog::DisableProgressWidgets);
|
||||
// Prevent the progress bar from continuing to move
|
||||
connect(cancel_btn, &QPushButton::clicked, this,
|
||||
&ProgressDialog::DisableProgressWidgets);
|
||||
|
||||
cancel_layout->addWidget(cancel_btn);
|
||||
cancel_layout->addWidget(cancel_btn);
|
||||
|
||||
cancel_layout->addStretch();
|
||||
cancel_layout->addStretch();
|
||||
}
|
||||
|
||||
void ProgressDialog::showEvent(QShowEvent *e)
|
||||
{
|
||||
super::showEvent(e);
|
||||
super::showEvent(e);
|
||||
|
||||
if (first_show_) {
|
||||
elapsed_timer_lbl_->Start();
|
||||
if (first_show_) {
|
||||
elapsed_timer_lbl_->Start();
|
||||
|
||||
Core::instance()->main_window()->SetApplicationProgressStatus(MainWindow::kProgressShow);
|
||||
Core::instance()->main_window()->SetApplicationProgressStatus(
|
||||
MainWindow::kProgressShow);
|
||||
|
||||
first_show_ = false;
|
||||
}
|
||||
first_show_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressDialog::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
super::closeEvent(e);
|
||||
super::closeEvent(e);
|
||||
|
||||
Core::instance()->main_window()->SetApplicationProgressStatus(MainWindow::kProgressNone);
|
||||
Core::instance()->main_window()->SetApplicationProgressStatus(
|
||||
MainWindow::kProgressNone);
|
||||
|
||||
elapsed_timer_lbl_->Stop();
|
||||
elapsed_timer_lbl_->Stop();
|
||||
|
||||
first_show_ = true;
|
||||
first_show_ = true;
|
||||
}
|
||||
|
||||
void ProgressDialog::SetProgress(double value)
|
||||
{
|
||||
if (!show_progress_) {
|
||||
return;
|
||||
}
|
||||
if (!show_progress_) {
|
||||
return;
|
||||
}
|
||||
|
||||
int percent = qRound(100.0 * value);
|
||||
int percent = qRound(100.0 * value);
|
||||
|
||||
bar_->setValue(percent);
|
||||
elapsed_timer_lbl_->SetProgress(value);
|
||||
bar_->setValue(percent);
|
||||
elapsed_timer_lbl_->SetProgress(value);
|
||||
|
||||
Core::instance()->main_window()->SetApplicationProgressValue(percent);
|
||||
Core::instance()->main_window()->SetApplicationProgressValue(percent);
|
||||
}
|
||||
|
||||
void ProgressDialog::ShowErrorMessage(const QString &title, const QString &message)
|
||||
void ProgressDialog::ShowErrorMessage(const QString &title,
|
||||
const QString &message)
|
||||
{
|
||||
Core::instance()->main_window()->SetApplicationProgressStatus(MainWindow::kProgressError);
|
||||
Core::instance()->main_window()->SetApplicationProgressStatus(
|
||||
MainWindow::kProgressError);
|
||||
|
||||
QMessageBox b(this);
|
||||
b.setIcon(QMessageBox::Critical);
|
||||
b.setWindowModality(Qt::WindowModal);
|
||||
b.setWindowTitle(title);
|
||||
b.setText(message);
|
||||
b.addButton(QMessageBox::Ok);
|
||||
b.exec();
|
||||
QMessageBox b(this);
|
||||
b.setIcon(QMessageBox::Critical);
|
||||
b.setWindowModality(Qt::WindowModal);
|
||||
b.setWindowTitle(title);
|
||||
b.setText(message);
|
||||
b.addButton(QMessageBox::Ok);
|
||||
b.exec();
|
||||
}
|
||||
|
||||
void ProgressDialog::DisableSenderWidget()
|
||||
{
|
||||
static_cast<QWidget*>(sender())->setEnabled(false);
|
||||
static_cast<QWidget *>(sender())->setEnabled(false);
|
||||
}
|
||||
|
||||
void ProgressDialog::DisableProgressWidgets()
|
||||
{
|
||||
show_progress_ = false;
|
||||
show_progress_ = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,42 +27,42 @@
|
||||
#include "common/debug.h"
|
||||
#include "widget/taskview/elapsedcounterwidget.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProgressDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ProgressDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProgressDialog(const QString &message, const QString &title, QWidget* parent = nullptr);
|
||||
ProgressDialog(const QString &message, const QString &title,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
virtual void showEvent(QShowEvent *e) override;
|
||||
|
||||
virtual void closeEvent(QCloseEvent *) override;
|
||||
virtual void closeEvent(QCloseEvent *) override;
|
||||
|
||||
public slots:
|
||||
void SetProgress(double value);
|
||||
void SetProgress(double value);
|
||||
|
||||
signals:
|
||||
void Cancelled();
|
||||
void Cancelled();
|
||||
|
||||
protected:
|
||||
void ShowErrorMessage(const QString& title, const QString& message);
|
||||
void ShowErrorMessage(const QString &title, const QString &message);
|
||||
|
||||
private:
|
||||
QProgressBar* bar_;
|
||||
QProgressBar *bar_;
|
||||
|
||||
ElapsedCounterWidget* elapsed_timer_lbl_;
|
||||
ElapsedCounterWidget *elapsed_timer_lbl_;
|
||||
|
||||
bool show_progress_;
|
||||
bool show_progress_;
|
||||
|
||||
bool first_show_;
|
||||
bool first_show_;
|
||||
|
||||
private slots:
|
||||
void DisableSenderWidget();
|
||||
|
||||
void DisableProgressWidgets();
|
||||
void DisableSenderWidget();
|
||||
|
||||
void DisableProgressWidgets();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -32,234 +32,271 @@
|
||||
#include "node/color/colormanager/colormanager.h"
|
||||
#include "render/diskmanager.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super QDialog
|
||||
|
||||
ProjectPropertiesDialog::ProjectPropertiesDialog(Project* p, QWidget *parent) :
|
||||
super(parent),
|
||||
working_project_(p),
|
||||
ocio_config_is_valid_(true)
|
||||
ProjectPropertiesDialog::ProjectPropertiesDialog(Project *p, QWidget *parent)
|
||||
: super(parent)
|
||||
, working_project_(p)
|
||||
, ocio_config_is_valid_(true)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
setWindowTitle(tr("Project Properties for '%1'").arg(working_project_->name()));
|
||||
setWindowTitle(
|
||||
tr("Project Properties for '%1'").arg(working_project_->name()));
|
||||
|
||||
QTabWidget* tabs = new QTabWidget;
|
||||
layout->addWidget(tabs);
|
||||
QTabWidget *tabs = new QTabWidget;
|
||||
layout->addWidget(tabs);
|
||||
|
||||
{
|
||||
// Color management group
|
||||
QWidget* color_group = new QWidget();
|
||||
{
|
||||
// Color management group
|
||||
QWidget *color_group = new QWidget();
|
||||
|
||||
QVBoxLayout* color_outer_layout = new QVBoxLayout(color_group);
|
||||
QVBoxLayout *color_outer_layout = new QVBoxLayout(color_group);
|
||||
|
||||
QGridLayout* color_layout = new QGridLayout();
|
||||
color_outer_layout->addLayout(color_layout);
|
||||
QGridLayout *color_layout = new QGridLayout();
|
||||
color_outer_layout->addLayout(color_layout);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
color_layout->addWidget(new QLabel(tr("OpenColorIO Configuration:")), 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);
|
||||
ocio_filename_ = new QLineEdit();
|
||||
ocio_filename_->setPlaceholderText(tr("(default)"));
|
||||
color_layout->addWidget(ocio_filename_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
color_layout->addWidget(new QLabel(tr("Default Input Color Space:")), row, 0);
|
||||
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);
|
||||
default_input_colorspace_ = new QComboBox();
|
||||
color_layout->addWidget(default_input_colorspace_, row, 1, 1, 2);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
color_layout->addWidget(new QLabel(tr("Reference Space:")), row, 0);
|
||||
color_layout->addWidget(new QLabel(tr("Reference Space:")), row, 0);
|
||||
|
||||
reference_space_ = new QComboBox(this);
|
||||
reference_space_->addItem(tr("Scene Linear"), OCIO::ROLE_SCENE_LINEAR);
|
||||
reference_space_->addItem(tr("Compositing Log"), OCIO::ROLE_COMPOSITING_LOG);
|
||||
QtUtils::SetComboBoxData(reference_space_, p->GetColorReferenceSpace());
|
||||
color_layout->addWidget(reference_space_, row, 1, 1, 2);
|
||||
reference_space_ = new QComboBox(this);
|
||||
reference_space_->addItem(tr("Scene Linear"), OCIO::ROLE_SCENE_LINEAR);
|
||||
reference_space_->addItem(tr("Compositing Log"),
|
||||
OCIO::ROLE_COMPOSITING_LOG);
|
||||
QtUtils::SetComboBoxData(reference_space_, p->GetColorReferenceSpace());
|
||||
color_layout->addWidget(reference_space_, row, 1, 1, 2);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
QPushButton* browse_btn = new QPushButton(tr("Browse"));
|
||||
color_layout->addWidget(browse_btn, 0, 2);
|
||||
connect(browse_btn, &QPushButton::clicked, this, &ProjectPropertiesDialog::BrowseForOCIOConfig);
|
||||
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());
|
||||
ocio_filename_->setText(
|
||||
working_project_->color_manager()->GetConfigFilename());
|
||||
|
||||
connect(ocio_filename_, &QLineEdit::textChanged, this, &ProjectPropertiesDialog::OCIOFilenameUpdated);
|
||||
OCIOFilenameUpdated();
|
||||
connect(ocio_filename_, &QLineEdit::textChanged, this,
|
||||
&ProjectPropertiesDialog::OCIOFilenameUpdated);
|
||||
OCIOFilenameUpdated();
|
||||
|
||||
tabs->addTab(color_group, tr("Color Management"));
|
||||
tabs->addTab(color_group, tr("Color Management"));
|
||||
|
||||
color_outer_layout->addStretch();
|
||||
}
|
||||
color_outer_layout->addStretch();
|
||||
}
|
||||
|
||||
{
|
||||
// Cache group
|
||||
QWidget* cache_group = new QWidget();
|
||||
{
|
||||
// Cache group
|
||||
QWidget *cache_group = new QWidget();
|
||||
|
||||
QVBoxLayout* cache_layout = new QVBoxLayout(cache_group);
|
||||
QVBoxLayout *cache_layout = new QVBoxLayout(cache_group);
|
||||
|
||||
QButtonGroup* disk_cache_btn_group = new QButtonGroup();
|
||||
QButtonGroup *disk_cache_btn_group = new QButtonGroup();
|
||||
|
||||
// Create radio buttons and add to widget and button group
|
||||
disk_cache_radios_[Project::kCacheUseDefaultLocation] = new QRadioButton(tr("Use Default Location"));
|
||||
disk_cache_radios_[Project::kCacheStoreAlongsideProject] = new QRadioButton(tr("Store Alongside Project"));
|
||||
disk_cache_radios_[Project::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 radio buttons and add to widget and button group
|
||||
disk_cache_radios_[Project::kCacheUseDefaultLocation] =
|
||||
new QRadioButton(tr("Use Default Location"));
|
||||
disk_cache_radios_[Project::kCacheStoreAlongsideProject] =
|
||||
new QRadioButton(tr("Store Alongside Project"));
|
||||
disk_cache_radios_[Project::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_->GetCustomCachePath(), this);
|
||||
custom_cache_path_->setEnabled(false);
|
||||
cache_layout->addWidget(custom_cache_path_);
|
||||
// Create custom cache path widget
|
||||
custom_cache_path_ =
|
||||
new PathWidget(working_project_->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_[Project::kCacheCustomPath], &QRadioButton::toggled, custom_cache_path_, &PathWidget::setEnabled);
|
||||
// Ensure custom cache path "enabled" is tied to the radio button being checked
|
||||
connect(disk_cache_radios_[Project::kCacheCustomPath],
|
||||
&QRadioButton::toggled, custom_cache_path_,
|
||||
&PathWidget::setEnabled);
|
||||
|
||||
// Check the radio button that should currently be active
|
||||
disk_cache_radios_[working_project_->GetCacheLocationSetting()]->setChecked(true);
|
||||
// Check the radio button that should currently be active
|
||||
disk_cache_radios_[working_project_->GetCacheLocationSetting()]
|
||||
->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);
|
||||
// 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"));
|
||||
}
|
||||
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);
|
||||
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 (!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_[Project::kCacheUseDefaultLocation]->isChecked()) {
|
||||
// Keep new cache path empty, which means default
|
||||
} else if (disk_cache_radios_[Project::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 (disk_cache_radios_[Project::kCacheUseDefaultLocation]->isChecked()) {
|
||||
// Keep new cache path empty, which means default
|
||||
} else if (disk_cache_radios_[Project::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_->GetCustomCachePath()) {
|
||||
// Check if the user is okay with invalidating the current cache
|
||||
if (!DiskManager::ShowDiskCacheChangeConfirmationDialog(this)) {
|
||||
return;
|
||||
}
|
||||
if (custom_cache_path_->text() != working_project_->GetCustomCachePath()) {
|
||||
// Check if the user is okay with invalidating the current cache
|
||||
if (!DiskManager::ShowDiskCacheChangeConfirmationDialog(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
working_project_->SetCustomCachePath(custom_cache_path_->text());
|
||||
working_project_->SetCustomCachePath(custom_cache_path_->text());
|
||||
|
||||
emit DiskManager::instance()->InvalidateProject(working_project_);
|
||||
}
|
||||
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());
|
||||
}
|
||||
if (working_project_->GetColorReferenceSpace() != reference_space_->currentData().toString()) {
|
||||
working_project_->SetColorReferenceSpace(reference_space_->currentData().toString());
|
||||
}
|
||||
// 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());
|
||||
}
|
||||
if (working_project_->GetColorReferenceSpace() !=
|
||||
reference_space_->currentData().toString()) {
|
||||
working_project_->SetColorReferenceSpace(
|
||||
reference_space_->currentData().toString());
|
||||
}
|
||||
|
||||
super::accept();
|
||||
super::accept();
|
||||
}
|
||||
|
||||
bool ProjectPropertiesDialog::VerifyPathAndWarnIfBad(const QString &path)
|
||||
{
|
||||
if (!FileFunctions::DirectoryIsValid(path)) {
|
||||
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;
|
||||
}
|
||||
if (!FileFunctions::DirectoryIsValid(path)) {
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProjectPropertiesDialog::BrowseForOCIOConfig()
|
||||
{
|
||||
QString fn = QFileDialog::getOpenFileName(this, tr("Browse for OpenColorIO configuration"));
|
||||
if (!fn.isEmpty()) {
|
||||
ocio_filename_->setText(fn);
|
||||
}
|
||||
QString fn = QFileDialog::getOpenFileName(
|
||||
this, tr("Browse for OpenColorIO configuration"));
|
||||
if (!fn.isEmpty()) {
|
||||
ocio_filename_->setText(fn);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectPropertiesDialog::OCIOFilenameUpdated()
|
||||
{
|
||||
default_input_colorspace_->clear();
|
||||
default_input_colorspace_->clear();
|
||||
|
||||
try {
|
||||
OCIO::ConstConfigRcPtr c;
|
||||
try {
|
||||
OCIO::ConstConfigRcPtr c;
|
||||
|
||||
if (ocio_filename_->text().isEmpty()) {
|
||||
c = ColorManager::GetDefaultConfig();
|
||||
} else {
|
||||
c = ColorManager::CreateConfigFromFile(ocio_filename_->text());
|
||||
}
|
||||
if (ocio_filename_->text().isEmpty()) {
|
||||
c = ColorManager::GetDefaultConfig();
|
||||
} else {
|
||||
c = ColorManager::CreateConfigFromFile(ocio_filename_->text());
|
||||
}
|
||||
|
||||
ocio_filename_->setStyleSheet(QString());
|
||||
ocio_config_is_valid_ = true;
|
||||
ocio_filename_->setStyleSheet(QString());
|
||||
ocio_config_is_valid_ = true;
|
||||
|
||||
// List input color spaces
|
||||
QStringList input_cs = ColorManager::ListAvailableColorspaces(c);
|
||||
// List input color spaces
|
||||
QStringList input_cs = ColorManager::ListAvailableColorspaces(c);
|
||||
|
||||
foreach (QString cs, input_cs) {
|
||||
default_input_colorspace_->addItem(cs);
|
||||
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();
|
||||
}
|
||||
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_[Project::kCacheUseDefaultLocation]->isChecked()) {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(DiskManager::instance()->GetDefaultCacheFolder(), this);
|
||||
} else if (disk_cache_radios_[Project::kCacheStoreAlongsideProject]->isChecked()) {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(working_project_->get_cache_alongside_project_path(), this);
|
||||
} else {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(custom_cache_path_->text(), this);
|
||||
}
|
||||
if (disk_cache_radios_[Project::kCacheUseDefaultLocation]->isChecked()) {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(
|
||||
DiskManager::instance()->GetDefaultCacheFolder(), this);
|
||||
} else if (disk_cache_radios_[Project::kCacheStoreAlongsideProject]
|
||||
->isChecked()) {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(
|
||||
working_project_->get_cache_alongside_project_path(), this);
|
||||
} else {
|
||||
DiskManager::instance()->ShowDiskCacheSettingsDialog(
|
||||
custom_cache_path_->text(), this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,44 +31,43 @@
|
||||
#include "node/project.h"
|
||||
#include "widget/path/pathwidget.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class ProjectPropertiesDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ProjectPropertiesDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProjectPropertiesDialog(Project *p, QWidget* parent);
|
||||
ProjectPropertiesDialog(Project *p, QWidget *parent);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
bool VerifyPathAndWarnIfBad(const QString &path);
|
||||
bool VerifyPathAndWarnIfBad(const QString &path);
|
||||
|
||||
Project* working_project_;
|
||||
Project *working_project_;
|
||||
|
||||
QLineEdit* ocio_filename_;
|
||||
QLineEdit *ocio_filename_;
|
||||
|
||||
QComboBox* default_input_colorspace_;
|
||||
QComboBox *default_input_colorspace_;
|
||||
|
||||
QComboBox *reference_space_;
|
||||
QComboBox *reference_space_;
|
||||
|
||||
bool ocio_config_is_valid_;
|
||||
bool ocio_config_is_valid_;
|
||||
|
||||
QString ocio_config_error_;
|
||||
QString ocio_config_error_;
|
||||
|
||||
PathWidget* custom_cache_path_;
|
||||
PathWidget *custom_cache_path_;
|
||||
|
||||
static const int kDiskCacheRadioCount = 3;
|
||||
QRadioButton *disk_cache_radios_[kDiskCacheRadioCount];
|
||||
static const int kDiskCacheRadioCount = 3;
|
||||
QRadioButton *disk_cache_radios_[kDiskCacheRadioCount];
|
||||
|
||||
private slots:
|
||||
void BrowseForOCIOConfig();
|
||||
void BrowseForOCIOConfig();
|
||||
|
||||
void OCIOFilenameUpdated();
|
||||
|
||||
void OpenDiskCacheSettings();
|
||||
void OCIOFilenameUpdated();
|
||||
|
||||
void OpenDiskCacheSettings();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,63 +20,67 @@
|
||||
|
||||
#include "rendercancel.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
RenderCancelDialog::RenderCancelDialog(QWidget *parent) :
|
||||
ProgressDialog(tr("Waiting for workers to finish..."), tr("Renderer"), parent),
|
||||
busy_workers_(0),
|
||||
total_workers_(0)
|
||||
RenderCancelDialog::RenderCancelDialog(QWidget *parent)
|
||||
: ProgressDialog(tr("Waiting for workers to finish..."), tr("Renderer"),
|
||||
parent)
|
||||
, busy_workers_(0)
|
||||
, total_workers_(0)
|
||||
{
|
||||
}
|
||||
|
||||
void RenderCancelDialog::RunIfWorkersAreBusy()
|
||||
{
|
||||
if (busy_workers_ > 0) {
|
||||
waiting_workers_ = busy_workers_;
|
||||
if (busy_workers_ > 0) {
|
||||
waiting_workers_ = busy_workers_;
|
||||
|
||||
exec();
|
||||
}
|
||||
exec();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCancelDialog::SetWorkerCount(int count)
|
||||
{
|
||||
total_workers_ = count;
|
||||
total_workers_ = count;
|
||||
|
||||
UpdateProgress();
|
||||
UpdateProgress();
|
||||
}
|
||||
|
||||
void RenderCancelDialog::WorkerStarted()
|
||||
{
|
||||
busy_workers_++;
|
||||
busy_workers_++;
|
||||
|
||||
UpdateProgress();
|
||||
UpdateProgress();
|
||||
}
|
||||
|
||||
void RenderCancelDialog::WorkerDone()
|
||||
{
|
||||
busy_workers_--;
|
||||
busy_workers_--;
|
||||
|
||||
UpdateProgress();
|
||||
UpdateProgress();
|
||||
}
|
||||
|
||||
void RenderCancelDialog::showEvent(QShowEvent *event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
|
||||
UpdateProgress();
|
||||
QDialog::showEvent(event);
|
||||
|
||||
UpdateProgress();
|
||||
}
|
||||
|
||||
void RenderCancelDialog::UpdateProgress()
|
||||
{
|
||||
if (!total_workers_ || !isVisible()) {
|
||||
return;
|
||||
}
|
||||
if (!total_workers_ || !isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetProgress(qRound(100.0 * static_cast<double>(waiting_workers_ - busy_workers_) / static_cast<double>(waiting_workers_)));
|
||||
SetProgress(
|
||||
qRound(100.0 * static_cast<double>(waiting_workers_ - busy_workers_) /
|
||||
static_cast<double>(waiting_workers_)));
|
||||
|
||||
if (busy_workers_ == 0) {
|
||||
accept();
|
||||
}
|
||||
if (busy_workers_ == 0) {
|
||||
accept();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,35 +23,34 @@
|
||||
|
||||
#include "dialog/progress/progress.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class RenderCancelDialog : public ProgressDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class RenderCancelDialog : public ProgressDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
RenderCancelDialog(QWidget* parent = nullptr);
|
||||
RenderCancelDialog(QWidget *parent = nullptr);
|
||||
|
||||
void RunIfWorkersAreBusy();
|
||||
void RunIfWorkersAreBusy();
|
||||
|
||||
void SetWorkerCount(int count);
|
||||
void SetWorkerCount(int count);
|
||||
|
||||
void WorkerStarted();
|
||||
void WorkerStarted();
|
||||
|
||||
public slots:
|
||||
void WorkerDone();
|
||||
void WorkerDone();
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* event) override;
|
||||
virtual void showEvent(QShowEvent *event) override;
|
||||
|
||||
private:
|
||||
void UpdateProgress();
|
||||
void UpdateProgress();
|
||||
|
||||
int busy_workers_;
|
||||
int busy_workers_;
|
||||
|
||||
int total_workers_;
|
||||
|
||||
int waiting_workers_;
|
||||
int total_workers_;
|
||||
|
||||
int waiting_workers_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+158
-155
@@ -35,210 +35,213 @@
|
||||
#include "common/filefunctions.h"
|
||||
#include "common/xmlutils.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class Preset
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class Preset {
|
||||
public:
|
||||
Preset() = default;
|
||||
Preset() = default;
|
||||
|
||||
virtual ~Preset(){}
|
||||
virtual ~Preset()
|
||||
{
|
||||
}
|
||||
|
||||
const QString& GetName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
const QString &GetName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
void SetName(const QString& s)
|
||||
{
|
||||
name_ = s;
|
||||
}
|
||||
void SetName(const QString &s)
|
||||
{
|
||||
name_ = s;
|
||||
}
|
||||
|
||||
virtual void Load(QXmlStreamReader* reader) = 0;
|
||||
virtual void Load(QXmlStreamReader *reader) = 0;
|
||||
|
||||
virtual void Save(QXmlStreamWriter* writer) const = 0;
|
||||
virtual void Save(QXmlStreamWriter *writer) const = 0;
|
||||
|
||||
private:
|
||||
QString name_;
|
||||
|
||||
QString name_;
|
||||
};
|
||||
|
||||
using PresetPtr = std::shared_ptr<Preset>;
|
||||
|
||||
template <typename T>
|
||||
class PresetManager
|
||||
{
|
||||
template <typename T> class PresetManager {
|
||||
public:
|
||||
PresetManager(QWidget* parent, const QString& preset_name) :
|
||||
preset_name_(preset_name),
|
||||
parent_(parent)
|
||||
{
|
||||
// Load custom preset data from file
|
||||
QFile preset_file(GetCustomPresetFilename());
|
||||
if (preset_file.open(QFile::ReadOnly)) {
|
||||
QXmlStreamReader reader(&preset_file);
|
||||
PresetManager(QWidget *parent, const QString &preset_name)
|
||||
: preset_name_(preset_name)
|
||||
, parent_(parent)
|
||||
{
|
||||
// Load custom preset data from file
|
||||
QFile preset_file(GetCustomPresetFilename());
|
||||
if (preset_file.open(QFile::ReadOnly)) {
|
||||
QXmlStreamReader reader(&preset_file);
|
||||
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("presets")) {
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("preset")) {
|
||||
PresetPtr p = std::make_unique<T>();
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("presets")) {
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("preset")) {
|
||||
PresetPtr p = std::make_unique<T>();
|
||||
|
||||
p->Load(&reader);
|
||||
p->Load(&reader);
|
||||
|
||||
custom_preset_data_.append(p);
|
||||
} else {
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
custom_preset_data_.append(p);
|
||||
} else {
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
preset_file.close();
|
||||
}
|
||||
}
|
||||
preset_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
~PresetManager()
|
||||
{
|
||||
// Save custom presets to disk
|
||||
QFile preset_file(GetCustomPresetFilename());
|
||||
if (preset_file.open(QFile::WriteOnly)) {
|
||||
QXmlStreamWriter writer(&preset_file);
|
||||
writer.setAutoFormatting(true);
|
||||
~PresetManager()
|
||||
{
|
||||
// Save custom presets to disk
|
||||
QFile preset_file(GetCustomPresetFilename());
|
||||
if (preset_file.open(QFile::WriteOnly)) {
|
||||
QXmlStreamWriter writer(&preset_file);
|
||||
writer.setAutoFormatting(true);
|
||||
|
||||
writer.writeStartDocument();
|
||||
writer.writeStartDocument();
|
||||
|
||||
writer.writeStartElement(QStringLiteral("presets"));
|
||||
writer.writeStartElement(QStringLiteral("presets"));
|
||||
|
||||
foreach (PresetPtr p, custom_preset_data_) {
|
||||
writer.writeStartElement(QStringLiteral("preset"));
|
||||
foreach (PresetPtr p, custom_preset_data_) {
|
||||
writer.writeStartElement(QStringLiteral("preset"));
|
||||
|
||||
p->Save(&writer);
|
||||
p->Save(&writer);
|
||||
|
||||
writer.writeEndElement(); // preset
|
||||
}
|
||||
writer.writeEndElement(); // preset
|
||||
}
|
||||
|
||||
writer.writeEndElement(); // presets
|
||||
writer.writeEndElement(); // presets
|
||||
|
||||
writer.writeEndDocument();
|
||||
writer.writeEndDocument();
|
||||
|
||||
preset_file.close();
|
||||
}
|
||||
}
|
||||
preset_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
QString GetPresetName(QString start) const
|
||||
{
|
||||
bool ok;
|
||||
QString GetPresetName(QString start) const
|
||||
{
|
||||
bool ok;
|
||||
|
||||
forever {
|
||||
start = QInputDialog::getText(parent_,
|
||||
QCoreApplication::translate("PresetManager", "Save Preset"),
|
||||
QCoreApplication::translate("PresetManager", "Set preset name:"),
|
||||
QLineEdit::Normal,
|
||||
start,
|
||||
&ok);
|
||||
forever
|
||||
{
|
||||
start = QInputDialog::getText(
|
||||
parent_,
|
||||
QCoreApplication::translate("PresetManager", "Save Preset"),
|
||||
QCoreApplication::translate("PresetManager",
|
||||
"Set preset name:"),
|
||||
QLineEdit::Normal, start, &ok);
|
||||
|
||||
if (!ok) {
|
||||
// Dialog cancelled - leave function entirely
|
||||
return QString();
|
||||
}
|
||||
if (!ok) {
|
||||
// Dialog cancelled - leave function entirely
|
||||
return QString();
|
||||
}
|
||||
|
||||
if (start.isEmpty()) {
|
||||
// No preset name entered, start loop over
|
||||
QMessageBox::critical(parent_,
|
||||
QCoreApplication::translate("PresetManager", "Invalid preset name"),
|
||||
QCoreApplication::translate("PresetManager", "You must enter a preset name"),
|
||||
QMessageBox::Ok);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (start.isEmpty()) {
|
||||
// No preset name entered, start loop over
|
||||
QMessageBox::critical(
|
||||
parent_,
|
||||
QCoreApplication::translate("PresetManager",
|
||||
"Invalid preset name"),
|
||||
QCoreApplication::translate("PresetManager",
|
||||
"You must enter a preset name"),
|
||||
QMessageBox::Ok);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
enum SaveStatus {
|
||||
kAppended,
|
||||
kReplaced,
|
||||
kNotSaved
|
||||
};
|
||||
enum SaveStatus { kAppended, kReplaced, kNotSaved };
|
||||
|
||||
SaveStatus SavePreset(PresetPtr preset)
|
||||
{
|
||||
QString preset_name;
|
||||
int existing_preset;
|
||||
SaveStatus SavePreset(PresetPtr preset)
|
||||
{
|
||||
QString preset_name;
|
||||
int existing_preset;
|
||||
|
||||
forever {
|
||||
preset_name = GetPresetName(preset_name);
|
||||
forever
|
||||
{
|
||||
preset_name = GetPresetName(preset_name);
|
||||
|
||||
if (preset_name.isEmpty()) {
|
||||
// Dialog cancelled - leave function entirely
|
||||
return kNotSaved;
|
||||
}
|
||||
if (preset_name.isEmpty()) {
|
||||
// Dialog cancelled - leave function entirely
|
||||
return kNotSaved;
|
||||
}
|
||||
|
||||
existing_preset = -1;
|
||||
for (int i=0; i<custom_preset_data_.size(); i++) {
|
||||
if (custom_preset_data_.at(i)->GetName() == preset_name) {
|
||||
existing_preset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
existing_preset = -1;
|
||||
for (int i = 0; i < custom_preset_data_.size(); i++) {
|
||||
if (custom_preset_data_.at(i)->GetName() == preset_name) {
|
||||
existing_preset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (existing_preset == -1
|
||||
|| QMessageBox::question(parent_,
|
||||
QCoreApplication::translate("PresetManager", "Preset exists"),
|
||||
QCoreApplication::translate("PresetManager",
|
||||
"A preset with this name already exists. "
|
||||
"Would you like to replace it?")) == QMessageBox::Yes) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existing_preset == -1 ||
|
||||
QMessageBox::question(
|
||||
parent_,
|
||||
QCoreApplication::translate("PresetManager",
|
||||
"Preset exists"),
|
||||
QCoreApplication::translate(
|
||||
"PresetManager",
|
||||
"A preset with this name already exists. "
|
||||
"Would you like to replace it?")) == QMessageBox::Yes) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
preset->SetName(preset_name);
|
||||
preset->SetName(preset_name);
|
||||
|
||||
if (existing_preset >= 0) {
|
||||
custom_preset_data_.replace(existing_preset, preset);
|
||||
return kReplaced;
|
||||
} else {
|
||||
custom_preset_data_.append(preset);
|
||||
return kAppended;
|
||||
}
|
||||
}
|
||||
if (existing_preset >= 0) {
|
||||
custom_preset_data_.replace(existing_preset, preset);
|
||||
return kReplaced;
|
||||
} else {
|
||||
custom_preset_data_.append(preset);
|
||||
return kAppended;
|
||||
}
|
||||
}
|
||||
|
||||
QString GetCustomPresetFilename() const
|
||||
{
|
||||
return QDir(FileFunctions::GetConfigurationLocation()).filePath(preset_name_);
|
||||
}
|
||||
QString GetCustomPresetFilename() const
|
||||
{
|
||||
return QDir(FileFunctions::GetConfigurationLocation())
|
||||
.filePath(preset_name_);
|
||||
}
|
||||
|
||||
PresetPtr GetPreset(int index)
|
||||
{
|
||||
return custom_preset_data_.at(index);
|
||||
}
|
||||
PresetPtr GetPreset(int index)
|
||||
{
|
||||
return custom_preset_data_.at(index);
|
||||
}
|
||||
|
||||
void DeletePreset(int index)
|
||||
{
|
||||
custom_preset_data_.removeAt(index);
|
||||
}
|
||||
void DeletePreset(int index)
|
||||
{
|
||||
custom_preset_data_.removeAt(index);
|
||||
}
|
||||
|
||||
int GetNumberOfPresets() const
|
||||
{
|
||||
return custom_preset_data_.size();
|
||||
}
|
||||
int GetNumberOfPresets() const
|
||||
{
|
||||
return custom_preset_data_.size();
|
||||
}
|
||||
|
||||
const QVector<PresetPtr>& GetPresetData() const
|
||||
{
|
||||
return custom_preset_data_;
|
||||
}
|
||||
const QVector<PresetPtr> &GetPresetData() const
|
||||
{
|
||||
return custom_preset_data_;
|
||||
}
|
||||
|
||||
private:
|
||||
QVector<PresetPtr> custom_preset_data_;
|
||||
QVector<PresetPtr> custom_preset_data_;
|
||||
|
||||
QString preset_name_;
|
||||
|
||||
QWidget* parent_;
|
||||
QString preset_name_;
|
||||
|
||||
QWidget *parent_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+156
-137
@@ -35,194 +35,213 @@
|
||||
#include "common/qtutils.h"
|
||||
#include "undo/undostack.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
SequenceDialog::SequenceDialog(Sequence* s, Type t, QWidget* parent) :
|
||||
QDialog(parent),
|
||||
sequence_(s),
|
||||
make_undoable_(true)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
QSplitter* splitter = new QSplitter();
|
||||
layout->addWidget(splitter);
|
||||
SequenceDialog::SequenceDialog(Sequence *s, Type t, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, sequence_(s)
|
||||
, make_undoable_(true)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
preset_tab_ = new SequenceDialogPresetTab();
|
||||
splitter->addWidget(preset_tab_);
|
||||
QSplitter *splitter = new QSplitter();
|
||||
layout->addWidget(splitter);
|
||||
|
||||
parameter_tab_ = new SequenceDialogParameterTab(sequence_);
|
||||
splitter->addWidget(parameter_tab_);
|
||||
preset_tab_ = new SequenceDialogPresetTab();
|
||||
splitter->addWidget(preset_tab_);
|
||||
|
||||
connect(preset_tab_, &SequenceDialogPresetTab::PresetChanged,
|
||||
parameter_tab_, &SequenceDialogParameterTab::PresetChanged);
|
||||
connect(preset_tab_, &SequenceDialogPresetTab::PresetAccepted,
|
||||
this, &SequenceDialog::accept);
|
||||
connect(parameter_tab_, &SequenceDialogParameterTab::SaveParametersAsPreset,
|
||||
preset_tab_, &SequenceDialogPresetTab::SaveParametersAsPreset);
|
||||
parameter_tab_ = new SequenceDialogParameterTab(sequence_);
|
||||
splitter->addWidget(parameter_tab_);
|
||||
|
||||
// Set up name section
|
||||
QHBoxLayout* name_layout = new QHBoxLayout();
|
||||
name_layout->addWidget(new QLabel(tr("Name:")));
|
||||
name_field_ = new QLineEdit();
|
||||
name_layout->addWidget(name_field_);
|
||||
layout->addLayout(name_layout);
|
||||
connect(preset_tab_, &SequenceDialogPresetTab::PresetChanged,
|
||||
parameter_tab_, &SequenceDialogParameterTab::PresetChanged);
|
||||
connect(preset_tab_, &SequenceDialogPresetTab::PresetAccepted, this,
|
||||
&SequenceDialog::accept);
|
||||
connect(parameter_tab_, &SequenceDialogParameterTab::SaveParametersAsPreset,
|
||||
preset_tab_, &SequenceDialogPresetTab::SaveParametersAsPreset);
|
||||
|
||||
// Set up dialog buttons
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
QPushButton *default_btn = buttons->addButton(tr("Set As Default"), QDialogButtonBox::ActionRole);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &SequenceDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &SequenceDialog::reject);
|
||||
connect(default_btn, &QPushButton::clicked, this, &SequenceDialog::SetAsDefaultClicked);
|
||||
layout->addWidget(buttons);
|
||||
// Set up name section
|
||||
QHBoxLayout *name_layout = new QHBoxLayout();
|
||||
name_layout->addWidget(new QLabel(tr("Name:")));
|
||||
name_field_ = new QLineEdit();
|
||||
name_layout->addWidget(name_field_);
|
||||
layout->addLayout(name_layout);
|
||||
|
||||
// Set window title based on type
|
||||
switch (t) {
|
||||
case kNew:
|
||||
setWindowTitle(tr("New Sequence"));
|
||||
break;
|
||||
case kExisting:
|
||||
setWindowTitle(tr("Editing \"%1\"").arg(sequence_->GetLabel()));
|
||||
break;
|
||||
}
|
||||
// Set up dialog buttons
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
QPushButton *default_btn =
|
||||
buttons->addButton(tr("Set As Default"), QDialogButtonBox::ActionRole);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this,
|
||||
&SequenceDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this,
|
||||
&SequenceDialog::reject);
|
||||
connect(default_btn, &QPushButton::clicked, this,
|
||||
&SequenceDialog::SetAsDefaultClicked);
|
||||
layout->addWidget(buttons);
|
||||
|
||||
name_field_->setText(sequence_->GetLabel());
|
||||
// Set window title based on type
|
||||
switch (t) {
|
||||
case kNew:
|
||||
setWindowTitle(tr("New Sequence"));
|
||||
break;
|
||||
case kExisting:
|
||||
setWindowTitle(tr("Editing \"%1\"").arg(sequence_->GetLabel()));
|
||||
break;
|
||||
}
|
||||
|
||||
name_field_->setText(sequence_->GetLabel());
|
||||
}
|
||||
|
||||
void SequenceDialog::SetUndoable(bool u)
|
||||
{
|
||||
make_undoable_ = u;
|
||||
make_undoable_ = u;
|
||||
}
|
||||
|
||||
void SequenceDialog::SetNameIsEditable(bool e)
|
||||
{
|
||||
name_field_->setEnabled(e);
|
||||
name_field_->setEnabled(e);
|
||||
}
|
||||
|
||||
void SequenceDialog::accept()
|
||||
{
|
||||
if (name_field_->isEnabled() && name_field_->text().isEmpty()) {
|
||||
QtUtils::MsgBox(this, QMessageBox::Critical, tr("Error editing Sequence"), tr("Please enter a name for this Sequence."));
|
||||
return;
|
||||
}
|
||||
if (name_field_->isEnabled() && name_field_->text().isEmpty()) {
|
||||
QtUtils::MsgBox(this, QMessageBox::Critical,
|
||||
tr("Error editing Sequence"),
|
||||
tr("Please enter a name for this Sequence."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VideoParams::FormatIsFloat(parameter_tab_->GetSelectedPreviewFormat())
|
||||
&& !OLIVE_CONFIG("PreviewNonFloatDontAskAgain").toBool()) {
|
||||
QMessageBox b(this);
|
||||
QCheckBox *dont_show_again_ = new QCheckBox(tr("Don't ask me again"));
|
||||
if (!VideoParams::FormatIsFloat(
|
||||
parameter_tab_->GetSelectedPreviewFormat()) &&
|
||||
!OLIVE_CONFIG("PreviewNonFloatDontAskAgain").toBool()) {
|
||||
QMessageBox b(this);
|
||||
QCheckBox *dont_show_again_ = new QCheckBox(tr("Don't ask me again"));
|
||||
|
||||
b.setIcon(QMessageBox::Warning);
|
||||
b.setWindowTitle(tr("Low Quality Preview"));
|
||||
b.setText(tr("The preview resolution has been set to a non-float format. This may cause banding and clipping artifacts in the preview.\n\n"
|
||||
"Do you wish to continue?"));
|
||||
b.setCheckBox(dont_show_again_);
|
||||
b.setIcon(QMessageBox::Warning);
|
||||
b.setWindowTitle(tr("Low Quality Preview"));
|
||||
b.setText(tr(
|
||||
"The preview resolution has been set to a non-float format. This may cause banding and clipping artifacts in the preview.\n\n"
|
||||
"Do you wish to continue?"));
|
||||
b.setCheckBox(dont_show_again_);
|
||||
|
||||
b.addButton(QMessageBox::Yes);
|
||||
b.addButton(QMessageBox::No);
|
||||
b.addButton(QMessageBox::Yes);
|
||||
b.addButton(QMessageBox::No);
|
||||
|
||||
if (b.exec() == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
if (b.exec() == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dont_show_again_->isChecked()) {
|
||||
OLIVE_CONFIG("PreviewNonFloatDontAskAgain") = true;
|
||||
}
|
||||
}
|
||||
if (dont_show_again_->isChecked()) {
|
||||
OLIVE_CONFIG("PreviewNonFloatDontAskAgain") = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate video and audio parameter structs from data
|
||||
VideoParams video_params = VideoParams(parameter_tab_->GetSelectedVideoWidth(),
|
||||
parameter_tab_->GetSelectedVideoHeight(),
|
||||
parameter_tab_->GetSelectedVideoFrameRate().flipped(),
|
||||
parameter_tab_->GetSelectedPreviewFormat(),
|
||||
VideoParams::kInternalChannelCount,
|
||||
parameter_tab_->GetSelectedVideoPixelAspect(),
|
||||
parameter_tab_->GetSelectedVideoInterlacingMode(),
|
||||
parameter_tab_->GetSelectedPreviewResolution());
|
||||
// Generate video and audio parameter structs from data
|
||||
VideoParams video_params =
|
||||
VideoParams(parameter_tab_->GetSelectedVideoWidth(),
|
||||
parameter_tab_->GetSelectedVideoHeight(),
|
||||
parameter_tab_->GetSelectedVideoFrameRate().flipped(),
|
||||
parameter_tab_->GetSelectedPreviewFormat(),
|
||||
VideoParams::kInternalChannelCount,
|
||||
parameter_tab_->GetSelectedVideoPixelAspect(),
|
||||
parameter_tab_->GetSelectedVideoInterlacingMode(),
|
||||
parameter_tab_->GetSelectedPreviewResolution());
|
||||
|
||||
AudioParams audio_params = AudioParams(parameter_tab_->GetSelectedAudioSampleRate(),
|
||||
parameter_tab_->GetSelectedAudioChannelLayout(),
|
||||
Sequence::kDefaultSampleFormat);
|
||||
AudioParams audio_params =
|
||||
AudioParams(parameter_tab_->GetSelectedAudioSampleRate(),
|
||||
parameter_tab_->GetSelectedAudioChannelLayout(),
|
||||
Sequence::kDefaultSampleFormat);
|
||||
|
||||
if (make_undoable_) {
|
||||
if (make_undoable_) {
|
||||
// Make undoable command to change the parameters
|
||||
SequenceParamCommand *param_command = new SequenceParamCommand(
|
||||
sequence_, video_params, audio_params, name_field_->text(),
|
||||
parameter_tab_->GetSelectedPreviewAutoCache());
|
||||
|
||||
// Make undoable command to change the parameters
|
||||
SequenceParamCommand* param_command = new SequenceParamCommand(sequence_,
|
||||
video_params,
|
||||
audio_params,
|
||||
name_field_->text(),
|
||||
parameter_tab_->GetSelectedPreviewAutoCache());
|
||||
Core::instance()->undo_stack()->push(
|
||||
param_command,
|
||||
tr("Set Sequence Parameters For \"%1\"").arg(sequence_->GetLabel()));
|
||||
|
||||
Core::instance()->undo_stack()->push(param_command, tr("Set Sequence Parameters For \"%1\"").arg(sequence_->GetLabel()));
|
||||
} else {
|
||||
// Set sequence values directly with no undo command
|
||||
sequence_->SetVideoParams(video_params);
|
||||
sequence_->SetAudioParams(audio_params);
|
||||
sequence_->SetLabel(name_field_->text());
|
||||
sequence_->SetVideoAutoCacheEnabled(
|
||||
parameter_tab_->GetSelectedPreviewAutoCache());
|
||||
}
|
||||
|
||||
} else {
|
||||
// Set sequence values directly with no undo command
|
||||
sequence_->SetVideoParams(video_params);
|
||||
sequence_->SetAudioParams(audio_params);
|
||||
sequence_->SetLabel(name_field_->text());
|
||||
sequence_->SetVideoAutoCacheEnabled(parameter_tab_->GetSelectedPreviewAutoCache());
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void SequenceDialog::SetAsDefaultClicked()
|
||||
{
|
||||
if (QtUtils::MsgBox(this, QMessageBox::Question, tr("Confirm Set As Default"),
|
||||
tr("Are you sure you want to set the current parameters as defaults?"),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
// Maybe replace with Preset system
|
||||
OLIVE_CONFIG("DefaultSequenceWidth") = parameter_tab_->GetSelectedVideoWidth();
|
||||
OLIVE_CONFIG("DefaultSequenceHeight") = parameter_tab_->GetSelectedVideoHeight();
|
||||
OLIVE_CONFIG("DefaultSequencePixelAspect") = QVariant::fromValue(parameter_tab_->GetSelectedVideoPixelAspect());
|
||||
OLIVE_CONFIG("DefaultSequenceFrameRate") = QVariant::fromValue(parameter_tab_->GetSelectedVideoFrameRate().flipped());
|
||||
OLIVE_CONFIG("DefaultSequenceInterlacing") = parameter_tab_->GetSelectedVideoInterlacingMode();
|
||||
OLIVE_CONFIG("DefaultSequenceAudioFrequency") = parameter_tab_->GetSelectedAudioSampleRate();
|
||||
OLIVE_CONFIG("DefaultSequenceAudioLayout") = QVariant::fromValue(parameter_tab_->GetSelectedAudioChannelLayout());
|
||||
}
|
||||
if (QtUtils::MsgBox(
|
||||
this, QMessageBox::Question, tr("Confirm Set As Default"),
|
||||
tr("Are you sure you want to set the current parameters as defaults?"),
|
||||
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
// Maybe replace with Preset system
|
||||
OLIVE_CONFIG("DefaultSequenceWidth") =
|
||||
parameter_tab_->GetSelectedVideoWidth();
|
||||
OLIVE_CONFIG("DefaultSequenceHeight") =
|
||||
parameter_tab_->GetSelectedVideoHeight();
|
||||
OLIVE_CONFIG("DefaultSequencePixelAspect") =
|
||||
QVariant::fromValue(parameter_tab_->GetSelectedVideoPixelAspect());
|
||||
OLIVE_CONFIG("DefaultSequenceFrameRate") = QVariant::fromValue(
|
||||
parameter_tab_->GetSelectedVideoFrameRate().flipped());
|
||||
OLIVE_CONFIG("DefaultSequenceInterlacing") =
|
||||
parameter_tab_->GetSelectedVideoInterlacingMode();
|
||||
OLIVE_CONFIG("DefaultSequenceAudioFrequency") =
|
||||
parameter_tab_->GetSelectedAudioSampleRate();
|
||||
OLIVE_CONFIG("DefaultSequenceAudioLayout") = QVariant::fromValue(
|
||||
parameter_tab_->GetSelectedAudioChannelLayout());
|
||||
}
|
||||
}
|
||||
|
||||
SequenceDialog::SequenceParamCommand::SequenceParamCommand(Sequence* s,
|
||||
const VideoParams& video_params,
|
||||
const AudioParams &audio_params,
|
||||
const QString& name, bool autocache) :
|
||||
sequence_(s),
|
||||
new_video_params_(video_params),
|
||||
new_audio_params_(audio_params),
|
||||
new_name_(name),
|
||||
new_autocache_(autocache),
|
||||
old_video_params_(s->GetVideoParams()),
|
||||
old_audio_params_(s->GetAudioParams()),
|
||||
old_name_(s->GetLabel()),
|
||||
old_autocache_(s->IsVideoAutoCacheEnabled())
|
||||
SequenceDialog::SequenceParamCommand::SequenceParamCommand(
|
||||
Sequence *s, const VideoParams &video_params,
|
||||
const AudioParams &audio_params, const QString &name, bool autocache)
|
||||
: sequence_(s)
|
||||
, new_video_params_(video_params)
|
||||
, new_audio_params_(audio_params)
|
||||
, new_name_(name)
|
||||
, new_autocache_(autocache)
|
||||
, old_video_params_(s->GetVideoParams())
|
||||
, old_audio_params_(s->GetAudioParams())
|
||||
, old_name_(s->GetLabel())
|
||||
, old_autocache_(s->IsVideoAutoCacheEnabled())
|
||||
{
|
||||
}
|
||||
|
||||
Project *SequenceDialog::SequenceParamCommand::GetRelevantProject() const
|
||||
{
|
||||
return sequence_->project();
|
||||
return sequence_->project();
|
||||
}
|
||||
|
||||
void SequenceDialog::SequenceParamCommand::redo()
|
||||
{
|
||||
if (sequence_->GetVideoParams() != new_video_params_) {
|
||||
sequence_->SetVideoParams(new_video_params_);
|
||||
}
|
||||
if (sequence_->GetAudioParams() != new_audio_params_) {
|
||||
sequence_->SetAudioParams(new_audio_params_);
|
||||
}
|
||||
sequence_->SetLabel(new_name_);
|
||||
sequence_->SetVideoAutoCacheEnabled(new_autocache_);
|
||||
if (sequence_->GetVideoParams() != new_video_params_) {
|
||||
sequence_->SetVideoParams(new_video_params_);
|
||||
}
|
||||
if (sequence_->GetAudioParams() != new_audio_params_) {
|
||||
sequence_->SetAudioParams(new_audio_params_);
|
||||
}
|
||||
sequence_->SetLabel(new_name_);
|
||||
sequence_->SetVideoAutoCacheEnabled(new_autocache_);
|
||||
}
|
||||
|
||||
void SequenceDialog::SequenceParamCommand::undo()
|
||||
{
|
||||
if (sequence_->GetVideoParams() != old_video_params_) {
|
||||
sequence_->SetVideoParams(old_video_params_);
|
||||
}
|
||||
if (sequence_->GetAudioParams() != old_audio_params_) {
|
||||
sequence_->SetAudioParams(old_audio_params_);
|
||||
}
|
||||
sequence_->SetLabel(old_name_);
|
||||
sequence_->SetVideoAutoCacheEnabled(old_autocache_);
|
||||
if (sequence_->GetVideoParams() != old_video_params_) {
|
||||
sequence_->SetVideoParams(old_video_params_);
|
||||
}
|
||||
if (sequence_->GetAudioParams() != old_audio_params_) {
|
||||
sequence_->SetAudioParams(old_audio_params_);
|
||||
}
|
||||
sequence_->SetLabel(old_name_);
|
||||
sequence_->SetVideoAutoCacheEnabled(old_autocache_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
#include "sequencedialogpresettab.h"
|
||||
#include "undo/undocommand.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A dialog for editing Sequence parameters
|
||||
@@ -46,19 +47,15 @@ namespace olive {
|
||||
* latter will be the main undoable action, the parameter editing doesn't have to be undoable since to the user they'll
|
||||
* be viewed as one single action (see SetUndoable()).
|
||||
*/
|
||||
class SequenceDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
class SequenceDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief Used to set the dialog mode of operation (see SequenceDialog())
|
||||
*/
|
||||
enum Type {
|
||||
kNew,
|
||||
kExisting
|
||||
};
|
||||
enum Type { kNew, kExisting };
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief SequenceDialog Constructor
|
||||
*
|
||||
* @param s
|
||||
@@ -70,73 +67,70 @@ public:
|
||||
* @param parent
|
||||
* QWidget parent
|
||||
*/
|
||||
SequenceDialog(Sequence* s, Type t = kExisting, QWidget* parent = nullptr);
|
||||
SequenceDialog(Sequence *s, Type t = kExisting, QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Set whether the parameter changes should be made into an undo command or not
|
||||
*
|
||||
* Defaults to true.
|
||||
*/
|
||||
void SetUndoable(bool u);
|
||||
void SetUndoable(bool u);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Set whether the name of this Sequence can be edited with this dialog
|
||||
*
|
||||
* Defaults to true.
|
||||
*/
|
||||
void SetNameIsEditable(bool e);
|
||||
void SetNameIsEditable(bool e);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
/**
|
||||
* @brief Function called when the user presses OK
|
||||
*/
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
private:
|
||||
Sequence* sequence_;
|
||||
Sequence *sequence_;
|
||||
|
||||
SequenceDialogPresetTab* preset_tab_;
|
||||
SequenceDialogPresetTab *preset_tab_;
|
||||
|
||||
SequenceDialogParameterTab* parameter_tab_;
|
||||
SequenceDialogParameterTab *parameter_tab_;
|
||||
|
||||
bool make_undoable_;
|
||||
bool make_undoable_;
|
||||
|
||||
QLineEdit* name_field_;
|
||||
QLineEdit *name_field_;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief An UndoCommand for setting the parameters on a sequence
|
||||
*/
|
||||
class SequenceParamCommand : public UndoCommand {
|
||||
public:
|
||||
SequenceParamCommand(Sequence* s,
|
||||
const VideoParams& video_params,
|
||||
const AudioParams& audio_params,
|
||||
const QString& name,
|
||||
bool autocache);
|
||||
class SequenceParamCommand : public UndoCommand {
|
||||
public:
|
||||
SequenceParamCommand(Sequence *s, const VideoParams &video_params,
|
||||
const AudioParams &audio_params,
|
||||
const QString &name, bool autocache);
|
||||
|
||||
virtual Project* GetRelevantProject() const override;
|
||||
virtual Project *GetRelevantProject() const override;
|
||||
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
protected:
|
||||
virtual void redo() override;
|
||||
virtual void undo() override;
|
||||
|
||||
private:
|
||||
Sequence* sequence_;
|
||||
private:
|
||||
Sequence *sequence_;
|
||||
|
||||
VideoParams new_video_params_;
|
||||
AudioParams new_audio_params_;
|
||||
QString new_name_;
|
||||
bool new_autocache_;
|
||||
VideoParams new_video_params_;
|
||||
AudioParams new_audio_params_;
|
||||
QString new_name_;
|
||||
bool new_autocache_;
|
||||
|
||||
VideoParams old_video_params_;
|
||||
AudioParams old_audio_params_;
|
||||
QString old_name_;
|
||||
bool old_autocache_;
|
||||
};
|
||||
VideoParams old_video_params_;
|
||||
AudioParams old_audio_params_;
|
||||
QString old_name_;
|
||||
bool old_autocache_;
|
||||
};
|
||||
|
||||
private slots:
|
||||
void SetAsDefaultClicked();
|
||||
|
||||
void SetAsDefaultClicked();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -7,150 +7,149 @@
|
||||
|
||||
#include "core.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence* sequence, QWidget* parent) :
|
||||
QWidget(parent)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
int row = 0;
|
||||
SequenceDialogParameterTab::SequenceDialogParameterTab(Sequence *sequence,
|
||||
QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
// Set up video section
|
||||
QGroupBox* video_group = new QGroupBox();
|
||||
video_group->setTitle(tr("Video"));
|
||||
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);
|
||||
int row = 0;
|
||||
|
||||
row = 0;
|
||||
// Set up video section
|
||||
QGroupBox *video_group = new QGroupBox();
|
||||
video_group->setTitle(tr("Video"));
|
||||
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);
|
||||
|
||||
// Set up audio section
|
||||
QGroupBox* audio_group = new QGroupBox();
|
||||
audio_group->setTitle(tr("Audio"));
|
||||
QGridLayout* audio_layout = new QGridLayout(audio_group);
|
||||
audio_layout->addWidget(new QLabel(tr("Sample Rate:")), row, 0);
|
||||
audio_sample_rate_field_ = new SampleRateComboBox();
|
||||
audio_layout->addWidget(audio_sample_rate_field_, row, 1);
|
||||
row++;
|
||||
audio_layout->addWidget(new QLabel(tr("Channels:")), row, 0);
|
||||
audio_channels_field_ = new ChannelLayoutComboBox();
|
||||
audio_layout->addWidget(audio_channels_field_, row, 1);
|
||||
layout->addWidget(audio_group);
|
||||
row = 0;
|
||||
|
||||
row = 0;
|
||||
// Set up audio section
|
||||
QGroupBox *audio_group = new QGroupBox();
|
||||
audio_group->setTitle(tr("Audio"));
|
||||
QGridLayout *audio_layout = new QGridLayout(audio_group);
|
||||
audio_layout->addWidget(new QLabel(tr("Sample Rate:")), row, 0);
|
||||
audio_sample_rate_field_ = new SampleRateComboBox();
|
||||
audio_layout->addWidget(audio_sample_rate_field_, row, 1);
|
||||
row++;
|
||||
audio_layout->addWidget(new QLabel(tr("Channels:")), row, 0);
|
||||
audio_channels_field_ = new ChannelLayoutComboBox();
|
||||
audio_layout->addWidget(audio_channels_field_, row, 1);
|
||||
layout->addWidget(audio_group);
|
||||
|
||||
// Set up preview section
|
||||
QGroupBox* preview_group = new QGroupBox();
|
||||
preview_group->setTitle(tr("Preview"));
|
||||
QGridLayout* preview_layout = new QGridLayout(preview_group);
|
||||
preview_layout->addWidget(new QLabel(tr("Resolution:")), row, 0);
|
||||
preview_resolution_field_ = new VideoDividerComboBox();
|
||||
preview_layout->addWidget(preview_resolution_field_, row, 1);
|
||||
preview_resolution_label_ = new QLabel();
|
||||
preview_layout->addWidget(preview_resolution_label_, row, 2);
|
||||
row++;
|
||||
preview_layout->addWidget(new QLabel(tr("Quality:")), row, 0);
|
||||
preview_format_field_ = new PixelFormatComboBox(false);
|
||||
preview_layout->addWidget(preview_format_field_, row, 1, 1, 2);
|
||||
row = 0;
|
||||
|
||||
/* TEMP: Disable sequence auto-cache, wanna see if clip cache supersedes it.
|
||||
// Set up preview section
|
||||
QGroupBox *preview_group = new QGroupBox();
|
||||
preview_group->setTitle(tr("Preview"));
|
||||
QGridLayout *preview_layout = new QGridLayout(preview_group);
|
||||
preview_layout->addWidget(new QLabel(tr("Resolution:")), row, 0);
|
||||
preview_resolution_field_ = new VideoDividerComboBox();
|
||||
preview_layout->addWidget(preview_resolution_field_, row, 1);
|
||||
preview_resolution_label_ = new QLabel();
|
||||
preview_layout->addWidget(preview_resolution_label_, row, 2);
|
||||
row++;
|
||||
preview_layout->addWidget(new QLabel(tr("Quality:")), row, 0);
|
||||
preview_format_field_ = new PixelFormatComboBox(false);
|
||||
preview_layout->addWidget(preview_format_field_, row, 1, 1, 2);
|
||||
|
||||
/* TEMP: Disable sequence auto-cache, wanna see if clip cache supersedes it.
|
||||
row++;
|
||||
preview_layout->addWidget(new QLabel(tr("Auto-Cache:")), row, 0);
|
||||
preview_layout->addWidget(preview_autocache_field_, row, 1);*/
|
||||
preview_autocache_field_ = new QCheckBox();
|
||||
preview_autocache_field_ = new QCheckBox();
|
||||
|
||||
layout->addWidget(preview_group);
|
||||
layout->addWidget(preview_group);
|
||||
|
||||
// Set values based on input sequence
|
||||
VideoParams vp = sequence->GetVideoParams();
|
||||
AudioParams ap = sequence->GetAudioParams();
|
||||
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->IsVideoAutoCacheEnabled());
|
||||
audio_sample_rate_field_->SetSampleRate(ap.sample_rate());
|
||||
audio_channels_field_->SetChannelLayout(ap.channel_layout());
|
||||
// Set values based on input sequence
|
||||
VideoParams vp = sequence->GetVideoParams();
|
||||
AudioParams ap = sequence->GetAudioParams();
|
||||
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->IsVideoAutoCacheEnabled());
|
||||
audio_sample_rate_field_->SetSampleRate(ap.sample_rate());
|
||||
audio_channels_field_->SetChannelLayout(ap.channel_layout());
|
||||
|
||||
connect(preview_resolution_field_, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &SequenceDialogParameterTab::UpdatePreviewResolutionLabel);
|
||||
connect(
|
||||
preview_resolution_field_,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &SequenceDialogParameterTab::UpdatePreviewResolutionLabel);
|
||||
|
||||
layout->addStretch();
|
||||
layout->addStretch();
|
||||
|
||||
QPushButton* save_preset_btn = new QPushButton(tr("Save Preset"));
|
||||
connect(save_preset_btn, &QPushButton::clicked, this, &SequenceDialogParameterTab::SavePresetClicked);
|
||||
layout->addWidget(save_preset_btn);
|
||||
QPushButton *save_preset_btn = new QPushButton(tr("Save Preset"));
|
||||
connect(save_preset_btn, &QPushButton::clicked, this,
|
||||
&SequenceDialogParameterTab::SavePresetClicked);
|
||||
layout->addWidget(save_preset_btn);
|
||||
|
||||
UpdatePreviewResolutionLabel();
|
||||
UpdatePreviewResolutionLabel();
|
||||
}
|
||||
|
||||
void SequenceDialogParameterTab::PresetChanged(const SequencePreset &preset)
|
||||
{
|
||||
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());
|
||||
preview_format_field_->SetPixelFormat(preset.preview_format());
|
||||
preview_autocache_field_->setChecked(preset.preview_autocache());
|
||||
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());
|
||||
preview_format_field_->SetPixelFormat(preset.preview_format());
|
||||
preview_autocache_field_->setChecked(preset.preview_autocache());
|
||||
}
|
||||
|
||||
void SequenceDialogParameterTab::SavePresetClicked()
|
||||
{
|
||||
AVChannelLayout layout=GetSelectedAudioChannelLayout();
|
||||
emit SaveParametersAsPreset(SequencePreset(QString(),
|
||||
GetSelectedVideoWidth(),
|
||||
GetSelectedVideoHeight(),
|
||||
GetSelectedVideoFrameRate(),
|
||||
GetSelectedVideoPixelAspect(),
|
||||
GetSelectedVideoInterlacingMode(),
|
||||
GetSelectedAudioSampleRate(),
|
||||
layout,
|
||||
GetSelectedPreviewResolution(),
|
||||
GetSelectedPreviewFormat(),
|
||||
GetSelectedPreviewAutoCache()));
|
||||
av_channel_layout_uninit(&layout);
|
||||
AVChannelLayout layout = GetSelectedAudioChannelLayout();
|
||||
emit SaveParametersAsPreset(SequencePreset(
|
||||
QString(), GetSelectedVideoWidth(), GetSelectedVideoHeight(),
|
||||
GetSelectedVideoFrameRate(), GetSelectedVideoPixelAspect(),
|
||||
GetSelectedVideoInterlacingMode(), GetSelectedAudioSampleRate(), layout,
|
||||
GetSelectedPreviewResolution(), GetSelectedPreviewFormat(),
|
||||
GetSelectedPreviewAutoCache()));
|
||||
av_channel_layout_uninit(&layout);
|
||||
}
|
||||
|
||||
void SequenceDialogParameterTab::UpdatePreviewResolutionLabel()
|
||||
{
|
||||
VideoParams test_param(GetSelectedVideoWidth(),
|
||||
GetSelectedVideoHeight(),
|
||||
PixelFormat::INVALID,
|
||||
VideoParams::kInternalChannelCount,
|
||||
rational(1),
|
||||
VideoParams::kInterlaceNone,
|
||||
preview_resolution_field_->currentData().toInt());
|
||||
VideoParams test_param(GetSelectedVideoWidth(), GetSelectedVideoHeight(),
|
||||
PixelFormat::INVALID,
|
||||
VideoParams::kInternalChannelCount, rational(1),
|
||||
VideoParams::kInterlaceNone,
|
||||
preview_resolution_field_->currentData().toInt());
|
||||
|
||||
preview_resolution_label_->setText(tr("(%1x%2)").arg(QString::number(test_param.effective_width()),
|
||||
QString::number(test_param.effective_height())));
|
||||
preview_resolution_label_->setText(
|
||||
tr("(%1x%2)").arg(QString::number(test_param.effective_width()),
|
||||
QString::number(test_param.effective_height())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,97 +11,99 @@
|
||||
#include "widget/slider/integerslider.h"
|
||||
#include "widget/standardcombos/standardcombos.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class SequenceDialogParameterTab : public QWidget
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class SequenceDialogParameterTab : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SequenceDialogParameterTab(Sequence* sequence, QWidget* parent = nullptr);
|
||||
SequenceDialogParameterTab(Sequence *sequence, QWidget *parent = nullptr);
|
||||
|
||||
int GetSelectedVideoWidth() const
|
||||
{
|
||||
return width_slider_->GetValue();
|
||||
}
|
||||
int GetSelectedVideoWidth() const
|
||||
{
|
||||
return width_slider_->GetValue();
|
||||
}
|
||||
|
||||
int GetSelectedVideoHeight() const
|
||||
{
|
||||
return height_slider_->GetValue();
|
||||
}
|
||||
int GetSelectedVideoHeight() const
|
||||
{
|
||||
return height_slider_->GetValue();
|
||||
}
|
||||
|
||||
rational GetSelectedVideoFrameRate() const
|
||||
{
|
||||
return framerate_combo_->GetFrameRate();
|
||||
}
|
||||
rational GetSelectedVideoFrameRate() const
|
||||
{
|
||||
return framerate_combo_->GetFrameRate();
|
||||
}
|
||||
|
||||
rational GetSelectedVideoPixelAspect() const
|
||||
{
|
||||
return pixelaspect_combo_->GetPixelAspectRatio();
|
||||
}
|
||||
rational GetSelectedVideoPixelAspect() const
|
||||
{
|
||||
return pixelaspect_combo_->GetPixelAspectRatio();
|
||||
}
|
||||
|
||||
VideoParams::Interlacing GetSelectedVideoInterlacingMode() const
|
||||
{
|
||||
return interlacing_combo_->GetInterlaceMode();
|
||||
}
|
||||
VideoParams::Interlacing GetSelectedVideoInterlacingMode() const
|
||||
{
|
||||
return interlacing_combo_->GetInterlaceMode();
|
||||
}
|
||||
|
||||
int GetSelectedAudioSampleRate() const { return audio_sample_rate_field_->GetSampleRate(); }
|
||||
int GetSelectedAudioSampleRate() const
|
||||
{
|
||||
return audio_sample_rate_field_->GetSampleRate();
|
||||
}
|
||||
|
||||
[[nodiscard]] AVChannelLayout GetSelectedAudioChannelLayout() const
|
||||
{
|
||||
return audio_channels_field_->GetChannelLayout();
|
||||
}
|
||||
[[nodiscard]] AVChannelLayout GetSelectedAudioChannelLayout() const
|
||||
{
|
||||
return audio_channels_field_->GetChannelLayout();
|
||||
}
|
||||
|
||||
int GetSelectedPreviewResolution() const
|
||||
{
|
||||
return preview_resolution_field_->GetDivider();
|
||||
}
|
||||
int GetSelectedPreviewResolution() const
|
||||
{
|
||||
return preview_resolution_field_->GetDivider();
|
||||
}
|
||||
|
||||
PixelFormat GetSelectedPreviewFormat() const
|
||||
{
|
||||
return preview_format_field_->GetPixelFormat();
|
||||
}
|
||||
PixelFormat GetSelectedPreviewFormat() const
|
||||
{
|
||||
return preview_format_field_->GetPixelFormat();
|
||||
}
|
||||
|
||||
bool GetSelectedPreviewAutoCache() const
|
||||
{
|
||||
//return preview_autocache_field_->isChecked();
|
||||
// TEMP: Disable sequence auto-cache, wanna see if clip cache supersedes it.
|
||||
return false;
|
||||
}
|
||||
bool GetSelectedPreviewAutoCache() const
|
||||
{
|
||||
//return preview_autocache_field_->isChecked();
|
||||
// TEMP: Disable sequence auto-cache, wanna see if clip cache supersedes it.
|
||||
return false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void PresetChanged(const SequencePreset& preset);
|
||||
void PresetChanged(const SequencePreset &preset);
|
||||
|
||||
signals:
|
||||
void SaveParametersAsPreset(const SequencePreset& preset);
|
||||
void SaveParametersAsPreset(const SequencePreset &preset);
|
||||
|
||||
private:
|
||||
IntegerSlider *width_slider_;
|
||||
IntegerSlider *width_slider_;
|
||||
|
||||
IntegerSlider *height_slider_;
|
||||
IntegerSlider *height_slider_;
|
||||
|
||||
FrameRateComboBox *framerate_combo_;
|
||||
FrameRateComboBox *framerate_combo_;
|
||||
|
||||
PixelAspectRatioComboBox *pixelaspect_combo_;
|
||||
PixelAspectRatioComboBox *pixelaspect_combo_;
|
||||
|
||||
InterlacedComboBox *interlacing_combo_;
|
||||
InterlacedComboBox *interlacing_combo_;
|
||||
|
||||
SampleRateComboBox* audio_sample_rate_field_;
|
||||
SampleRateComboBox *audio_sample_rate_field_;
|
||||
|
||||
ChannelLayoutComboBox* audio_channels_field_;
|
||||
ChannelLayoutComboBox *audio_channels_field_;
|
||||
|
||||
VideoDividerComboBox* preview_resolution_field_;
|
||||
VideoDividerComboBox *preview_resolution_field_;
|
||||
|
||||
QLabel* preview_resolution_label_;
|
||||
QLabel *preview_resolution_label_;
|
||||
|
||||
PixelFormatComboBox* preview_format_field_;
|
||||
PixelFormatComboBox *preview_format_field_;
|
||||
|
||||
QCheckBox *preview_autocache_field_;
|
||||
QCheckBox *preview_autocache_field_;
|
||||
|
||||
private slots:
|
||||
void SavePresetClicked();
|
||||
|
||||
void UpdatePreviewResolutionLabel();
|
||||
void SavePresetClicked();
|
||||
|
||||
void UpdatePreviewResolutionLabel();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -35,279 +35,269 @@
|
||||
#include "ui/icons/icons.h"
|
||||
#include "widget/menu/menu.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
const int kDataIsPreset = Qt::UserRole;
|
||||
const int kDataPresetIsCustomRole = Qt::UserRole + 1;
|
||||
const int kDataPresetDataRole = Qt::UserRole + 2;
|
||||
|
||||
SequenceDialogPresetTab::SequenceDialogPresetTab(QWidget* parent) :
|
||||
QWidget(parent),
|
||||
PresetManager<SequencePreset>(this, QStringLiteral("sequencepresets"))
|
||||
SequenceDialogPresetTab::SequenceDialogPresetTab(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, PresetManager<SequencePreset>(this, QStringLiteral("sequencepresets"))
|
||||
{
|
||||
QVBoxLayout* outer_layout = new QVBoxLayout(this);
|
||||
outer_layout->setContentsMargins(0, 0, 0, 0);
|
||||
QVBoxLayout *outer_layout = new QVBoxLayout(this);
|
||||
outer_layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
preset_tree_ = new QTreeWidget();
|
||||
preset_tree_->setColumnCount(1);
|
||||
preset_tree_->setHeaderLabel(tr("Preset"));
|
||||
preset_tree_->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(preset_tree_, &QTreeWidget::customContextMenuRequested, this, &SequenceDialogPresetTab::ShowContextMenu);
|
||||
outer_layout->addWidget(preset_tree_);
|
||||
connect(preset_tree_, &QTreeWidget::currentItemChanged, this, &SequenceDialogPresetTab::SelectedItemChanged);
|
||||
connect(preset_tree_, &QTreeWidget::itemDoubleClicked, this, &SequenceDialogPresetTab::ItemDoubleClicked);
|
||||
preset_tree_ = new QTreeWidget();
|
||||
preset_tree_->setColumnCount(1);
|
||||
preset_tree_->setHeaderLabel(tr("Preset"));
|
||||
preset_tree_->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(preset_tree_, &QTreeWidget::customContextMenuRequested, this,
|
||||
&SequenceDialogPresetTab::ShowContextMenu);
|
||||
outer_layout->addWidget(preset_tree_);
|
||||
connect(preset_tree_, &QTreeWidget::currentItemChanged, this,
|
||||
&SequenceDialogPresetTab::SelectedItemChanged);
|
||||
connect(preset_tree_, &QTreeWidget::itemDoubleClicked, this,
|
||||
&SequenceDialogPresetTab::ItemDoubleClicked);
|
||||
|
||||
// Add "my presets" folder
|
||||
my_presets_folder_ = CreateFolder(tr("My Presets"));
|
||||
preset_tree_->addTopLevelItem(my_presets_folder_);
|
||||
// Add "my presets" folder
|
||||
my_presets_folder_ = CreateFolder(tr("My Presets"));
|
||||
preset_tree_->addTopLevelItem(my_presets_folder_);
|
||||
|
||||
// Add presets
|
||||
preset_tree_->addTopLevelItem(CreateHDPresetFolder(tr("4K UHD"), 3840, 2160, 2));
|
||||
preset_tree_->addTopLevelItem(CreateHDPresetFolder(tr("1080p"), 1920, 1080, 1));
|
||||
preset_tree_->addTopLevelItem(CreateHDPresetFolder(tr("720p"), 1280, 720, 1));
|
||||
// Add presets
|
||||
preset_tree_->addTopLevelItem(
|
||||
CreateHDPresetFolder(tr("4K UHD"), 3840, 2160, 2));
|
||||
preset_tree_->addTopLevelItem(
|
||||
CreateHDPresetFolder(tr("1080p"), 1920, 1080, 1));
|
||||
preset_tree_->addTopLevelItem(
|
||||
CreateHDPresetFolder(tr("720p"), 1280, 720, 1));
|
||||
|
||||
preset_tree_->addTopLevelItem(CreateSDPresetFolder(tr("NTSC"), 720, 480, rational(30000, 1001),
|
||||
VideoParams::kPixelAspectNTSCStandard,
|
||||
VideoParams::kPixelAspectNTSCWidescreen, 1));
|
||||
preset_tree_->addTopLevelItem(CreateSDPresetFolder(tr("PAL"), 720, 576, rational(25, 1),
|
||||
VideoParams::kPixelAspectPALStandard,
|
||||
VideoParams::kPixelAspectPALWidescreen, 1));
|
||||
preset_tree_->addTopLevelItem(
|
||||
CreateSDPresetFolder(tr("NTSC"), 720, 480, rational(30000, 1001),
|
||||
VideoParams::kPixelAspectNTSCStandard,
|
||||
VideoParams::kPixelAspectNTSCWidescreen, 1));
|
||||
preset_tree_->addTopLevelItem(
|
||||
CreateSDPresetFolder(tr("PAL"), 720, 576, rational(25, 1),
|
||||
VideoParams::kPixelAspectPALStandard,
|
||||
VideoParams::kPixelAspectPALWidescreen, 1));
|
||||
|
||||
// Load custom presets
|
||||
for (int i=0;i<GetNumberOfPresets();i++) {
|
||||
AddCustomItem(my_presets_folder_, GetPreset(i), i);
|
||||
}
|
||||
// Load custom presets
|
||||
for (int i = 0; i < GetNumberOfPresets(); i++) {
|
||||
AddCustomItem(my_presets_folder_, GetPreset(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::SaveParametersAsPreset(SequencePreset preset)
|
||||
{
|
||||
PresetPtr preset_ptr = std::make_shared<SequencePreset>(preset);
|
||||
PresetPtr preset_ptr = std::make_shared<SequencePreset>(preset);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem* SequenceDialogPresetTab::CreateFolder(const QString &name)
|
||||
QTreeWidgetItem *SequenceDialogPresetTab::CreateFolder(const QString &name)
|
||||
{
|
||||
QTreeWidgetItem* folder = new QTreeWidgetItem();
|
||||
folder->setText(0, name);
|
||||
folder->setIcon(0, icon::Folder);
|
||||
return folder;
|
||||
QTreeWidgetItem *folder = new QTreeWidgetItem();
|
||||
folder->setText(0, name);
|
||||
folder->setIcon(0, icon::Folder);
|
||||
return folder;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *SequenceDialogPresetTab::CreateHDPresetFolder(const QString &name, int width, int height, int divider)
|
||||
QTreeWidgetItem *
|
||||
SequenceDialogPresetTab::CreateHDPresetFolder(const QString &name, int width,
|
||||
int height, int divider)
|
||||
{
|
||||
const PixelFormat default_format = static_cast<PixelFormat::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
|
||||
const bool default_autocache = false;
|
||||
QTreeWidgetItem* parent = CreateFolder(name);
|
||||
AVChannelLayout layout;
|
||||
av_channel_layout_from_mask(&layout, AV_CH_LAYOUT_STEREO);
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 23.976 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(24000, 1001),
|
||||
VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone,
|
||||
48000,
|
||||
layout,
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 25 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(25, 1),
|
||||
VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone,
|
||||
48000,
|
||||
layout,
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 29.97 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(30000, 1001),
|
||||
VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone,
|
||||
48000,
|
||||
layout,
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 50 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(50, 1),
|
||||
VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone,
|
||||
48000,
|
||||
layout,
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 59.94 FPS").arg(name),
|
||||
width,
|
||||
height,
|
||||
rational(60000, 1001),
|
||||
VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone,
|
||||
48000,
|
||||
layout,
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
av_channel_layout_uninit(&layout);
|
||||
return parent;
|
||||
const PixelFormat default_format = static_cast<PixelFormat::Format>(
|
||||
OLIVE_CONFIG("OfflinePixelFormat").toInt());
|
||||
const bool default_autocache = false;
|
||||
QTreeWidgetItem *parent = CreateFolder(name);
|
||||
AVChannelLayout layout;
|
||||
av_channel_layout_from_mask(&layout, AV_CH_LAYOUT_STEREO);
|
||||
AddStandardItem(parent,
|
||||
std::make_shared<SequencePreset>(
|
||||
tr("%1 23.976 FPS").arg(name), width, height,
|
||||
rational(24000, 1001), VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone, 48000, layout, divider,
|
||||
default_format, default_autocache));
|
||||
AddStandardItem(parent,
|
||||
std::make_shared<SequencePreset>(
|
||||
tr("%1 25 FPS").arg(name), width, height,
|
||||
rational(25, 1), VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone, 48000, layout, divider,
|
||||
default_format, default_autocache));
|
||||
AddStandardItem(parent,
|
||||
std::make_shared<SequencePreset>(
|
||||
tr("%1 29.97 FPS").arg(name), width, height,
|
||||
rational(30000, 1001), VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone, 48000, layout, divider,
|
||||
default_format, default_autocache));
|
||||
AddStandardItem(parent,
|
||||
std::make_shared<SequencePreset>(
|
||||
tr("%1 50 FPS").arg(name), width, height,
|
||||
rational(50, 1), VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone, 48000, layout, divider,
|
||||
default_format, default_autocache));
|
||||
AddStandardItem(parent,
|
||||
std::make_shared<SequencePreset>(
|
||||
tr("%1 59.94 FPS").arg(name), width, height,
|
||||
rational(60000, 1001), VideoParams::kPixelAspectSquare,
|
||||
VideoParams::kInterlaceNone, 48000, layout, divider,
|
||||
default_format, default_autocache));
|
||||
av_channel_layout_uninit(&layout);
|
||||
return parent;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *SequenceDialogPresetTab::CreateSDPresetFolder(const QString &name, int width, int height, const rational& frame_rate, const rational &standard_par, const rational &wide_par, int divider)
|
||||
QTreeWidgetItem *SequenceDialogPresetTab::CreateSDPresetFolder(
|
||||
const QString &name, int width, int height, const rational &frame_rate,
|
||||
const rational &standard_par, const rational &wide_par, int divider)
|
||||
{
|
||||
const PixelFormat default_format = static_cast<PixelFormat::Format>(OLIVE_CONFIG("OfflinePixelFormat").toInt());
|
||||
const bool default_autocache = false;
|
||||
QTreeWidgetItem* parent = CreateFolder(name);
|
||||
preset_tree_->addTopLevelItem(parent);
|
||||
AVChannelLayout layout;
|
||||
av_channel_layout_from_mask(&layout,AV_CH_LAYOUT_STEREO);
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 Standard").arg(name),
|
||||
width,
|
||||
height,
|
||||
frame_rate,
|
||||
standard_par,
|
||||
VideoParams::kInterlacedBottomFirst,
|
||||
48000,
|
||||
layout,
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
AddStandardItem(parent, std::make_shared<SequencePreset>(tr("%1 Widescreen").arg(name),
|
||||
width,
|
||||
height,
|
||||
frame_rate,
|
||||
wide_par,
|
||||
VideoParams::kInterlacedBottomFirst,
|
||||
48000,
|
||||
layout,
|
||||
divider,
|
||||
default_format,
|
||||
default_autocache));
|
||||
av_channel_layout_uninit(&layout);
|
||||
return parent;
|
||||
const PixelFormat default_format = static_cast<PixelFormat::Format>(
|
||||
OLIVE_CONFIG("OfflinePixelFormat").toInt());
|
||||
const bool default_autocache = false;
|
||||
QTreeWidgetItem *parent = CreateFolder(name);
|
||||
preset_tree_->addTopLevelItem(parent);
|
||||
AVChannelLayout layout;
|
||||
av_channel_layout_from_mask(&layout, AV_CH_LAYOUT_STEREO);
|
||||
AddStandardItem(
|
||||
parent, std::make_shared<SequencePreset>(
|
||||
tr("%1 Standard").arg(name), width, height, frame_rate,
|
||||
standard_par, VideoParams::kInterlacedBottomFirst, 48000,
|
||||
layout, divider, default_format, default_autocache));
|
||||
AddStandardItem(
|
||||
parent, std::make_shared<SequencePreset>(
|
||||
tr("%1 Widescreen").arg(name), width, height, frame_rate,
|
||||
wide_par, VideoParams::kInterlacedBottomFirst, 48000,
|
||||
layout, divider, default_format, default_autocache));
|
||||
av_channel_layout_uninit(&layout);
|
||||
return parent;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *SequenceDialogPresetTab::GetSelectedItem()
|
||||
{
|
||||
QList<QTreeWidgetItem*> selected_items = preset_tree_->selectedItems();
|
||||
QList<QTreeWidgetItem *> selected_items = preset_tree_->selectedItems();
|
||||
|
||||
if (selected_items.isEmpty()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return selected_items.first();
|
||||
}
|
||||
if (selected_items.isEmpty()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return selected_items.first();
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem *SequenceDialogPresetTab::GetSelectedCustomPreset()
|
||||
{
|
||||
QTreeWidgetItem* sel = GetSelectedItem();
|
||||
QTreeWidgetItem *sel = GetSelectedItem();
|
||||
|
||||
if (sel
|
||||
&& sel->data(0, kDataIsPreset).toBool()
|
||||
&& sel->data(0, kDataPresetIsCustomRole).toBool()) {
|
||||
return sel;
|
||||
}
|
||||
if (sel && sel->data(0, kDataIsPreset).toBool() &&
|
||||
sel->data(0, kDataPresetIsCustomRole).toBool()) {
|
||||
return sel;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::AddStandardItem(QTreeWidgetItem *folder, PresetPtr 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);
|
||||
int index = default_preset_data_.size();
|
||||
default_preset_data_.append(preset);
|
||||
AddItemInternal(folder, preset, false, index, description);
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::AddCustomItem(QTreeWidgetItem *folder, PresetPtr preset, int index, const QString &description)
|
||||
void SequenceDialogPresetTab::AddCustomItem(QTreeWidgetItem *folder,
|
||||
PresetPtr preset, int index,
|
||||
const QString &description)
|
||||
{
|
||||
AddItemInternal(folder, preset, true, index, description);
|
||||
AddItemInternal(folder, preset, true, index, description);
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::AddItemInternal(QTreeWidgetItem *folder, PresetPtr 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();
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem();
|
||||
|
||||
item->setText(0, preset->GetName());
|
||||
item->setIcon(0, icon::Video);
|
||||
item->setToolTip(0, description);
|
||||
item->setData(0, kDataIsPreset, true);
|
||||
item->setData(0, kDataPresetIsCustomRole, is_custom);
|
||||
item->setData(0, kDataPresetDataRole, index);
|
||||
item->setText(0, preset->GetName());
|
||||
item->setIcon(0, icon::Video);
|
||||
item->setToolTip(0, description);
|
||||
item->setData(0, kDataIsPreset, true);
|
||||
item->setData(0, kDataPresetIsCustomRole, is_custom);
|
||||
item->setData(0, kDataPresetDataRole, index);
|
||||
|
||||
folder->addChild(item);
|
||||
folder->addChild(item);
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::SelectedItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
|
||||
void SequenceDialogPresetTab::SelectedItemChanged(QTreeWidgetItem *current,
|
||||
QTreeWidgetItem *previous)
|
||||
{
|
||||
Q_UNUSED(previous)
|
||||
Q_UNUSED(previous)
|
||||
|
||||
if (current->data(0, kDataIsPreset).toBool()) {
|
||||
int preset_index = current->data(0, kDataPresetDataRole).toInt();
|
||||
if (current->data(0, kDataIsPreset).toBool()) {
|
||||
int preset_index = current->data(0, kDataPresetDataRole).toInt();
|
||||
|
||||
PresetPtr preset_data = (current->data(0, kDataPresetIsCustomRole).toBool())
|
||||
? GetPreset(preset_index)
|
||||
: default_preset_data_.at(preset_index);
|
||||
PresetPtr preset_data =
|
||||
(current->data(0, kDataPresetIsCustomRole).toBool()) ?
|
||||
GetPreset(preset_index) :
|
||||
default_preset_data_.at(preset_index);
|
||||
|
||||
emit PresetChanged(*static_cast<SequencePreset*>(preset_data.get()));
|
||||
}
|
||||
emit PresetChanged(*static_cast<SequencePreset *>(preset_data.get()));
|
||||
}
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::ItemDoubleClicked(QTreeWidgetItem *item, int column)
|
||||
void SequenceDialogPresetTab::ItemDoubleClicked(QTreeWidgetItem *item,
|
||||
int column)
|
||||
{
|
||||
Q_UNUSED(column)
|
||||
Q_UNUSED(column)
|
||||
|
||||
if (item->data(0, kDataIsPreset).toBool()) {
|
||||
emit PresetAccepted();
|
||||
}
|
||||
if (item->data(0, kDataIsPreset).toBool()) {
|
||||
emit PresetAccepted();
|
||||
}
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::ShowContextMenu()
|
||||
{
|
||||
QTreeWidgetItem* sel = GetSelectedCustomPreset();
|
||||
QTreeWidgetItem *sel = GetSelectedCustomPreset();
|
||||
|
||||
if (sel) {
|
||||
Menu m(this);
|
||||
if (sel) {
|
||||
Menu m(this);
|
||||
|
||||
QAction* delete_action = m.addAction(tr("Delete Preset"));
|
||||
connect(delete_action, &QAction::triggered, this, &SequenceDialogPresetTab::DeleteSelectedPreset);
|
||||
QAction *delete_action = m.addAction(tr("Delete Preset"));
|
||||
connect(delete_action, &QAction::triggered, this,
|
||||
&SequenceDialogPresetTab::DeleteSelectedPreset);
|
||||
|
||||
m.exec(QCursor::pos());
|
||||
}
|
||||
m.exec(QCursor::pos());
|
||||
}
|
||||
}
|
||||
|
||||
void SequenceDialogPresetTab::DeleteSelectedPreset()
|
||||
{
|
||||
QTreeWidgetItem* sel = GetSelectedCustomPreset();
|
||||
QTreeWidgetItem *sel = GetSelectedCustomPreset();
|
||||
|
||||
if (sel) {
|
||||
int preset_index = sel->data(0, kDataPresetDataRole).toInt();
|
||||
if (sel) {
|
||||
int preset_index = sel->data(0, kDataPresetDataRole).toInt();
|
||||
|
||||
// Shift all items whose index was after this preset forward
|
||||
for (int i=0; i<my_presets_folder_->childCount(); i++) {
|
||||
QTreeWidgetItem* custom_item = my_presets_folder_->child(i);
|
||||
int this_item_index = custom_item->data(0, kDataPresetDataRole).toInt();
|
||||
// Shift all items whose index was after this preset forward
|
||||
for (int i = 0; i < my_presets_folder_->childCount(); i++) {
|
||||
QTreeWidgetItem *custom_item = my_presets_folder_->child(i);
|
||||
int this_item_index =
|
||||
custom_item->data(0, kDataPresetDataRole).toInt();
|
||||
|
||||
if (this_item_index > preset_index) {
|
||||
custom_item->setData(0, kDataPresetDataRole, this_item_index - 1);
|
||||
}
|
||||
}
|
||||
if (this_item_index > preset_index) {
|
||||
custom_item->setData(0, kDataPresetDataRole,
|
||||
this_item_index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the preset
|
||||
DeletePreset(preset_index);
|
||||
// Remove the preset
|
||||
DeletePreset(preset_index);
|
||||
|
||||
// Delete the item
|
||||
delete sel;
|
||||
}
|
||||
// Delete the item
|
||||
delete sel;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,53 +28,61 @@
|
||||
#include "presetmanager.h"
|
||||
#include "sequencepreset.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class SequenceDialogPresetTab : public QWidget, public PresetManager<SequencePreset>
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class SequenceDialogPresetTab : public QWidget,
|
||||
public PresetManager<SequencePreset> {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SequenceDialogPresetTab(QWidget* parent = nullptr);
|
||||
SequenceDialogPresetTab(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void SaveParametersAsPreset(SequencePreset preset);
|
||||
void SaveParametersAsPreset(SequencePreset preset);
|
||||
|
||||
signals:
|
||||
void PresetChanged(const SequencePreset& preset);
|
||||
void PresetChanged(const SequencePreset &preset);
|
||||
|
||||
void PresetAccepted();
|
||||
void PresetAccepted();
|
||||
|
||||
private:
|
||||
QTreeWidgetItem *CreateFolder(const QString& name);
|
||||
QTreeWidgetItem *CreateFolder(const QString &name);
|
||||
|
||||
QTreeWidgetItem *CreateHDPresetFolder(const QString& name, int width, int height, int divider);
|
||||
QTreeWidgetItem *CreateHDPresetFolder(const QString &name, int width,
|
||||
int height, int divider);
|
||||
|
||||
QTreeWidgetItem *CreateSDPresetFolder(const QString& name, int width, int height, const rational &frame_rate, const rational& standard_par, const rational& wide_par, int divider);
|
||||
QTreeWidgetItem *CreateSDPresetFolder(
|
||||
const QString &name, int width, int height, const rational &frame_rate,
|
||||
const rational &standard_par, const rational &wide_par, int divider);
|
||||
|
||||
QTreeWidgetItem* GetSelectedItem();
|
||||
QTreeWidgetItem* GetSelectedCustomPreset();
|
||||
QTreeWidgetItem *GetSelectedItem();
|
||||
QTreeWidgetItem *GetSelectedCustomPreset();
|
||||
|
||||
void AddStandardItem(QTreeWidgetItem* folder, PresetPtr preset, const QString &description = QString());
|
||||
void AddStandardItem(QTreeWidgetItem *folder, PresetPtr preset,
|
||||
const QString &description = QString());
|
||||
|
||||
void AddCustomItem(QTreeWidgetItem* folder, PresetPtr preset, int index, const QString& description = QString());
|
||||
void AddCustomItem(QTreeWidgetItem *folder, PresetPtr preset, int index,
|
||||
const QString &description = QString());
|
||||
|
||||
void AddItemInternal(QTreeWidgetItem* folder, PresetPtr 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_;
|
||||
QTreeWidget *preset_tree_;
|
||||
|
||||
QTreeWidgetItem* my_presets_folder_;
|
||||
QTreeWidgetItem *my_presets_folder_;
|
||||
|
||||
QVector<PresetPtr> default_preset_data_;
|
||||
QVector<PresetPtr> default_preset_data_;
|
||||
|
||||
private slots:
|
||||
void SelectedItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
|
||||
void SelectedItemChanged(QTreeWidgetItem *current,
|
||||
QTreeWidgetItem *previous);
|
||||
|
||||
void ItemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||
void ItemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||
|
||||
void ShowContextMenu();
|
||||
|
||||
void DeleteSelectedPreset();
|
||||
void ShowContextMenu();
|
||||
|
||||
void DeleteSelectedPreset();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,145 +28,156 @@
|
||||
#include "dialog/sequence/presetmanager.h"
|
||||
#include "render/videoparams.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
class SequencePreset : public Preset {
|
||||
public:
|
||||
SequencePreset() = default;
|
||||
SequencePreset() = default;
|
||||
|
||||
SequencePreset(const QString& name,
|
||||
int width,
|
||||
int height,
|
||||
const rational& frame_rate,
|
||||
const rational& pixel_aspect,
|
||||
VideoParams::Interlacing interlacing,
|
||||
int sample_rate,
|
||||
AVChannelLayout &channel_layout,
|
||||
int preview_divider,
|
||||
PixelFormat preview_format,
|
||||
bool preview_autocache) :
|
||||
width_(width),
|
||||
height_(height),
|
||||
frame_rate_(frame_rate),
|
||||
pixel_aspect_(pixel_aspect),
|
||||
interlacing_(interlacing),
|
||||
sample_rate_(sample_rate),
|
||||
channel_layout_(channel_layout),
|
||||
preview_divider_(preview_divider),
|
||||
preview_format_(preview_format),
|
||||
preview_autocache_(preview_autocache)
|
||||
{
|
||||
SetName(name);
|
||||
}
|
||||
SequencePreset(const QString &name, int width, int height,
|
||||
const rational &frame_rate, const rational &pixel_aspect,
|
||||
VideoParams::Interlacing interlacing, int sample_rate,
|
||||
AVChannelLayout &channel_layout, int preview_divider,
|
||||
PixelFormat preview_format, bool preview_autocache)
|
||||
: width_(width)
|
||||
, height_(height)
|
||||
, frame_rate_(frame_rate)
|
||||
, pixel_aspect_(pixel_aspect)
|
||||
, interlacing_(interlacing)
|
||||
, sample_rate_(sample_rate)
|
||||
, channel_layout_(channel_layout)
|
||||
, preview_divider_(preview_divider)
|
||||
, preview_format_(preview_format)
|
||||
, preview_autocache_(preview_autocache)
|
||||
{
|
||||
SetName(name);
|
||||
}
|
||||
|
||||
virtual void Load(QXmlStreamReader* reader) override
|
||||
{
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("name")) {
|
||||
SetName(reader->readElementText());
|
||||
} else if (reader->name() == QStringLiteral("width")) {
|
||||
width_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("height")) {
|
||||
height_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("framerate")) {
|
||||
frame_rate_ = rational::fromString(reader->readElementText().toStdString());
|
||||
} else if (reader->name() == QStringLiteral("pixelaspect")) {
|
||||
pixel_aspect_ = rational::fromString(reader->readElementText().toStdString());
|
||||
} else if (reader->name() == QStringLiteral("interlacing")) {
|
||||
interlacing_ = static_cast<VideoParams::Interlacing>(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("samplerate")) {
|
||||
sample_rate_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("chlayout")) {
|
||||
channel_layout_.u.mask = reader->readElementText().toULongLong();
|
||||
} else if (reader->name() == QStringLiteral("divider")) {
|
||||
preview_divider_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("format")) {
|
||||
preview_format_ = static_cast<PixelFormat::Format>(reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("autocache")) {
|
||||
preview_autocache_ = reader->readElementText().toInt();
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void Load(QXmlStreamReader *reader) override
|
||||
{
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("name")) {
|
||||
SetName(reader->readElementText());
|
||||
} else if (reader->name() == QStringLiteral("width")) {
|
||||
width_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("height")) {
|
||||
height_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("framerate")) {
|
||||
frame_rate_ = rational::fromString(
|
||||
reader->readElementText().toStdString());
|
||||
} else if (reader->name() == QStringLiteral("pixelaspect")) {
|
||||
pixel_aspect_ = rational::fromString(
|
||||
reader->readElementText().toStdString());
|
||||
} else if (reader->name() == QStringLiteral("interlacing")) {
|
||||
interlacing_ = static_cast<VideoParams::Interlacing>(
|
||||
reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("samplerate")) {
|
||||
sample_rate_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("chlayout")) {
|
||||
channel_layout_.u.mask =
|
||||
reader->readElementText().toULongLong();
|
||||
} else if (reader->name() == QStringLiteral("divider")) {
|
||||
preview_divider_ = reader->readElementText().toInt();
|
||||
} else if (reader->name() == QStringLiteral("format")) {
|
||||
preview_format_ = static_cast<PixelFormat::Format>(
|
||||
reader->readElementText().toInt());
|
||||
} else if (reader->name() == QStringLiteral("autocache")) {
|
||||
preview_autocache_ = reader->readElementText().toInt();
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Save(QXmlStreamWriter* writer) const override
|
||||
{
|
||||
writer->writeTextElement(QStringLiteral("name"), GetName());
|
||||
writer->writeTextElement(QStringLiteral("width"), QString::number(width_));
|
||||
writer->writeTextElement(QStringLiteral("height"), QString::number(height_));
|
||||
writer->writeTextElement(QStringLiteral("framerate"), QString::fromStdString(frame_rate_.toString()));
|
||||
writer->writeTextElement(QStringLiteral("pixelaspect"), QString::fromStdString(pixel_aspect_.toString()));
|
||||
writer->writeTextElement(QStringLiteral("interlacing_"), QString::number(interlacing_));
|
||||
writer->writeTextElement(QStringLiteral("samplerate"), QString::number(sample_rate_));
|
||||
writer->writeTextElement(QStringLiteral("chlayout"), QString::number(channel_layout_.u.mask));
|
||||
writer->writeTextElement(QStringLiteral("divider"), QString::number(preview_divider_));
|
||||
writer->writeTextElement(QStringLiteral("format"), QString::number(preview_format_));
|
||||
writer->writeTextElement(QStringLiteral("autocache"), QString::number(preview_autocache_));
|
||||
}
|
||||
virtual void Save(QXmlStreamWriter *writer) const override
|
||||
{
|
||||
writer->writeTextElement(QStringLiteral("name"), GetName());
|
||||
writer->writeTextElement(QStringLiteral("width"),
|
||||
QString::number(width_));
|
||||
writer->writeTextElement(QStringLiteral("height"),
|
||||
QString::number(height_));
|
||||
writer->writeTextElement(
|
||||
QStringLiteral("framerate"),
|
||||
QString::fromStdString(frame_rate_.toString()));
|
||||
writer->writeTextElement(
|
||||
QStringLiteral("pixelaspect"),
|
||||
QString::fromStdString(pixel_aspect_.toString()));
|
||||
writer->writeTextElement(QStringLiteral("interlacing_"),
|
||||
QString::number(interlacing_));
|
||||
writer->writeTextElement(QStringLiteral("samplerate"),
|
||||
QString::number(sample_rate_));
|
||||
writer->writeTextElement(QStringLiteral("chlayout"),
|
||||
QString::number(channel_layout_.u.mask));
|
||||
writer->writeTextElement(QStringLiteral("divider"),
|
||||
QString::number(preview_divider_));
|
||||
writer->writeTextElement(QStringLiteral("format"),
|
||||
QString::number(preview_format_));
|
||||
writer->writeTextElement(QStringLiteral("autocache"),
|
||||
QString::number(preview_autocache_));
|
||||
}
|
||||
|
||||
int width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
int width() const
|
||||
{
|
||||
return width_;
|
||||
}
|
||||
|
||||
int height() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
int height() const
|
||||
{
|
||||
return height_;
|
||||
}
|
||||
|
||||
const rational& frame_rate() const
|
||||
{
|
||||
return frame_rate_;
|
||||
}
|
||||
const rational &frame_rate() const
|
||||
{
|
||||
return frame_rate_;
|
||||
}
|
||||
|
||||
const rational& pixel_aspect() const
|
||||
{
|
||||
return pixel_aspect_;
|
||||
}
|
||||
const rational &pixel_aspect() const
|
||||
{
|
||||
return pixel_aspect_;
|
||||
}
|
||||
|
||||
VideoParams::Interlacing interlacing() const
|
||||
{
|
||||
return interlacing_;
|
||||
}
|
||||
VideoParams::Interlacing interlacing() const
|
||||
{
|
||||
return interlacing_;
|
||||
}
|
||||
|
||||
int sample_rate() const
|
||||
{
|
||||
return sample_rate_;
|
||||
}
|
||||
int sample_rate() const
|
||||
{
|
||||
return sample_rate_;
|
||||
}
|
||||
|
||||
AVChannelLayout channel_layout() const
|
||||
{
|
||||
return channel_layout_;
|
||||
}
|
||||
AVChannelLayout channel_layout() const
|
||||
{
|
||||
return channel_layout_;
|
||||
}
|
||||
|
||||
int preview_divider() const
|
||||
{
|
||||
return preview_divider_;
|
||||
}
|
||||
int preview_divider() const
|
||||
{
|
||||
return preview_divider_;
|
||||
}
|
||||
|
||||
PixelFormat preview_format() const
|
||||
{
|
||||
return preview_format_;
|
||||
}
|
||||
PixelFormat preview_format() const
|
||||
{
|
||||
return preview_format_;
|
||||
}
|
||||
|
||||
bool preview_autocache() const
|
||||
{
|
||||
return preview_autocache_;
|
||||
}
|
||||
bool preview_autocache() const
|
||||
{
|
||||
return preview_autocache_;
|
||||
}
|
||||
|
||||
private:
|
||||
int width_;
|
||||
int height_;
|
||||
rational frame_rate_;
|
||||
rational pixel_aspect_;
|
||||
VideoParams::Interlacing interlacing_;
|
||||
int sample_rate_;
|
||||
AVChannelLayout channel_layout_;
|
||||
int preview_divider_;
|
||||
PixelFormat preview_format_;
|
||||
bool preview_autocache_;
|
||||
|
||||
int width_;
|
||||
int height_;
|
||||
rational frame_rate_;
|
||||
rational pixel_aspect_;
|
||||
VideoParams::Interlacing interlacing_;
|
||||
int sample_rate_;
|
||||
AVChannelLayout channel_layout_;
|
||||
int preview_divider_;
|
||||
PixelFormat preview_format_;
|
||||
bool preview_autocache_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,268 +29,311 @@
|
||||
#include "node/nodeundo.h"
|
||||
#include "timeline/timelineundopointer.h"
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super QDialog
|
||||
|
||||
SpeedDurationDialog::SpeedDurationDialog(const QVector<ClipBlock *> &clips, const rational &timebase, QWidget *parent) :
|
||||
super(parent),
|
||||
clips_(clips),
|
||||
timebase_(timebase)
|
||||
SpeedDurationDialog::SpeedDurationDialog(const QVector<ClipBlock *> &clips,
|
||||
const rational &timebase,
|
||||
QWidget *parent)
|
||||
: super(parent)
|
||||
, clips_(clips)
|
||||
, timebase_(timebase)
|
||||
{
|
||||
setWindowTitle(tr("Clip Properties"));
|
||||
setWindowTitle(tr("Clip Properties"));
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
{
|
||||
QGroupBox *speed_group = new QGroupBox(tr("Speed/Duration"));
|
||||
layout->addWidget(speed_group);
|
||||
{
|
||||
QGroupBox *speed_group = new QGroupBox(tr("Speed/Duration"));
|
||||
layout->addWidget(speed_group);
|
||||
|
||||
QGridLayout *speed_layout = new QGridLayout(speed_group);
|
||||
QGridLayout *speed_layout = new QGridLayout(speed_group);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
speed_layout->addWidget(new QLabel(tr("Speed:")), row, 0);
|
||||
speed_layout->addWidget(new QLabel(tr("Speed:")), row, 0);
|
||||
|
||||
speed_slider_ = new FloatSlider();
|
||||
speed_slider_->SetDisplayType(FloatSlider::kPercentage);
|
||||
connect(speed_slider_, &FloatSlider::ValueChanged, this, &SpeedDurationDialog::SpeedChanged);
|
||||
speed_layout->addWidget(speed_slider_, row, 1);
|
||||
speed_slider_ = new FloatSlider();
|
||||
speed_slider_->SetDisplayType(FloatSlider::kPercentage);
|
||||
connect(speed_slider_, &FloatSlider::ValueChanged, this,
|
||||
&SpeedDurationDialog::SpeedChanged);
|
||||
speed_layout->addWidget(speed_slider_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
speed_layout->addWidget(new QLabel(tr("Duration:")), row, 0);
|
||||
speed_layout->addWidget(new QLabel(tr("Duration:")), row, 0);
|
||||
|
||||
dur_slider_ = new RationalSlider();
|
||||
dur_slider_->SetTimebase(timebase);
|
||||
dur_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
connect(dur_slider_, &RationalSlider::ValueChanged, this, &SpeedDurationDialog::DurationChanged);
|
||||
speed_layout->addWidget(dur_slider_, row, 1);
|
||||
dur_slider_ = new RationalSlider();
|
||||
dur_slider_->SetTimebase(timebase);
|
||||
dur_slider_->SetDisplayType(RationalSlider::kTime);
|
||||
connect(dur_slider_, &RationalSlider::ValueChanged, this,
|
||||
&SpeedDurationDialog::DurationChanged);
|
||||
speed_layout->addWidget(dur_slider_, row, 1);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
link_box_ = new QCheckBox(tr("Link Speed and Duration"));
|
||||
link_box_->setChecked(true);
|
||||
speed_layout->addWidget(link_box_, row, 0, 1, 2);
|
||||
link_box_ = new QCheckBox(tr("Link Speed and Duration"));
|
||||
link_box_->setChecked(true);
|
||||
speed_layout->addWidget(link_box_, row, 0, 1, 2);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
reverse_box_ = new QCheckBox(tr("Reverse"));
|
||||
speed_layout->addWidget(reverse_box_, row, 0, 1, 2);
|
||||
reverse_box_ = new QCheckBox(tr("Reverse"));
|
||||
speed_layout->addWidget(reverse_box_, row, 0, 1, 2);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
maintain_audio_pitch_box_ = new QCheckBox(tr("Maintain Audio Pitch"));
|
||||
speed_layout->addWidget(maintain_audio_pitch_box_, row, 0, 1, 2);
|
||||
maintain_audio_pitch_box_ = new QCheckBox(tr("Maintain Audio Pitch"));
|
||||
speed_layout->addWidget(maintain_audio_pitch_box_, row, 0, 1, 2);
|
||||
|
||||
row++;
|
||||
row++;
|
||||
|
||||
ripple_box_ = new QCheckBox(tr("Ripple Trailing Clips"));
|
||||
speed_layout->addWidget(ripple_box_, row, 0, 1, 2);
|
||||
}
|
||||
ripple_box_ = new QCheckBox(tr("Ripple Trailing Clips"));
|
||||
speed_layout->addWidget(ripple_box_, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
{
|
||||
auto loop_box = new QGroupBox(tr("Loop"));
|
||||
layout->addWidget(loop_box);
|
||||
{
|
||||
auto loop_box = new QGroupBox(tr("Loop"));
|
||||
layout->addWidget(loop_box);
|
||||
|
||||
auto loop_layout = new QGridLayout(loop_box);
|
||||
auto loop_layout = new QGridLayout(loop_box);
|
||||
|
||||
int row = 0;
|
||||
int row = 0;
|
||||
|
||||
loop_layout->addWidget(new QLabel(tr("Loop:")), row, 0);
|
||||
loop_layout->addWidget(new QLabel(tr("Loop:")), row, 0);
|
||||
|
||||
loop_combo_ = new QComboBox();
|
||||
loop_combo_->addItem(tr("None"), int(LoopMode::kLoopModeOff));
|
||||
loop_combo_->addItem(tr("Loop"), int(LoopMode::kLoopModeLoop));
|
||||
loop_combo_->addItem(tr("Clamp"), int(LoopMode::kLoopModeClamp));
|
||||
loop_layout->addWidget(loop_combo_, row, 1);
|
||||
}
|
||||
loop_combo_ = new QComboBox();
|
||||
loop_combo_->addItem(tr("None"), int(LoopMode::kLoopModeOff));
|
||||
loop_combo_->addItem(tr("Loop"), int(LoopMode::kLoopModeLoop));
|
||||
loop_combo_->addItem(tr("Clamp"), int(LoopMode::kLoopModeClamp));
|
||||
loop_layout->addWidget(loop_combo_, row, 1);
|
||||
}
|
||||
|
||||
QDialogButtonBox *btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
btns->setCenterButtons(true);
|
||||
connect(btns, &QDialogButtonBox::accepted, this, &SpeedDurationDialog::accept);
|
||||
connect(btns, &QDialogButtonBox::rejected, this, &SpeedDurationDialog::reject);
|
||||
layout->addWidget(btns);
|
||||
QDialogButtonBox *btns =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
btns->setCenterButtons(true);
|
||||
connect(btns, &QDialogButtonBox::accepted, this,
|
||||
&SpeedDurationDialog::accept);
|
||||
connect(btns, &QDialogButtonBox::rejected, this,
|
||||
&SpeedDurationDialog::reject);
|
||||
layout->addWidget(btns);
|
||||
|
||||
// Determine which speed value to use
|
||||
start_speed_ = clips.first()->speed();
|
||||
start_duration_ = clips.first()->length();
|
||||
start_reverse_ = clips.first()->reverse();
|
||||
start_maintain_audio_pitch_ = clips.first()->maintain_audio_pitch();
|
||||
start_loop_ = int(clips.first()->loop_mode());
|
||||
for (int i=1; i<clips.size(); i++) {
|
||||
ClipBlock *c = clips.at(i);
|
||||
// Determine which speed value to use
|
||||
start_speed_ = clips.first()->speed();
|
||||
start_duration_ = clips.first()->length();
|
||||
start_reverse_ = clips.first()->reverse();
|
||||
start_maintain_audio_pitch_ = clips.first()->maintain_audio_pitch();
|
||||
start_loop_ = int(clips.first()->loop_mode());
|
||||
for (int i = 1; i < clips.size(); i++) {
|
||||
ClipBlock *c = clips.at(i);
|
||||
|
||||
if (!qIsNaN(start_speed_) && !qFuzzyCompare(start_speed_, c->speed())) {
|
||||
// Speed differs per clip
|
||||
start_speed_ = qSNaN();
|
||||
}
|
||||
if (!qIsNaN(start_speed_) && !qFuzzyCompare(start_speed_, c->speed())) {
|
||||
// Speed differs per clip
|
||||
start_speed_ = qSNaN();
|
||||
}
|
||||
|
||||
if (start_duration_ != -1 && c->length() != start_duration_) {
|
||||
start_duration_ = -1;
|
||||
}
|
||||
if (start_duration_ != -1 && c->length() != start_duration_) {
|
||||
start_duration_ = -1;
|
||||
}
|
||||
|
||||
// Yes, in theory a bool should only ever be 0 or 1 anyway, but MSVC complained and it is
|
||||
// *possible* that a bool could be something else, so this code is safer
|
||||
int clip_reverse = c->reverse() ? 1 : 0;
|
||||
int clip_maintain_pitch = c->maintain_audio_pitch() ? 1 : 0;
|
||||
if (start_reverse_ != -1 && clip_reverse != start_reverse_) {
|
||||
start_reverse_ = -1;
|
||||
}
|
||||
if (start_maintain_audio_pitch_ != -1 && clip_maintain_pitch != start_maintain_audio_pitch_) {
|
||||
start_maintain_audio_pitch_ = -1;
|
||||
}
|
||||
// Yes, in theory a bool should only ever be 0 or 1 anyway, but MSVC complained and it is
|
||||
// *possible* that a bool could be something else, so this code is safer
|
||||
int clip_reverse = c->reverse() ? 1 : 0;
|
||||
int clip_maintain_pitch = c->maintain_audio_pitch() ? 1 : 0;
|
||||
if (start_reverse_ != -1 && clip_reverse != start_reverse_) {
|
||||
start_reverse_ = -1;
|
||||
}
|
||||
if (start_maintain_audio_pitch_ != -1 &&
|
||||
clip_maintain_pitch != start_maintain_audio_pitch_) {
|
||||
start_maintain_audio_pitch_ = -1;
|
||||
}
|
||||
|
||||
if (start_loop_ != -1 && int(c->loop_mode()) != start_loop_) {
|
||||
start_loop_ = -1;
|
||||
}
|
||||
}
|
||||
if (start_loop_ != -1 && int(c->loop_mode()) != start_loop_) {
|
||||
start_loop_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (qIsNaN(start_speed_)) {
|
||||
speed_slider_->SetTristate();
|
||||
} else {
|
||||
speed_slider_->SetValue(start_speed_);
|
||||
}
|
||||
if (qIsNaN(start_speed_)) {
|
||||
speed_slider_->SetTristate();
|
||||
} else {
|
||||
speed_slider_->SetValue(start_speed_);
|
||||
}
|
||||
|
||||
if (start_duration_ == -1) {
|
||||
dur_slider_->SetTristate();
|
||||
} else {
|
||||
dur_slider_->SetValue(start_duration_);
|
||||
}
|
||||
if (start_duration_ == -1) {
|
||||
dur_slider_->SetTristate();
|
||||
} else {
|
||||
dur_slider_->SetValue(start_duration_);
|
||||
}
|
||||
|
||||
if (start_reverse_ == -1) {
|
||||
reverse_box_->setTristate();
|
||||
} else {
|
||||
reverse_box_->setChecked(start_reverse_);
|
||||
}
|
||||
if (start_reverse_ == -1) {
|
||||
reverse_box_->setTristate();
|
||||
} else {
|
||||
reverse_box_->setChecked(start_reverse_);
|
||||
}
|
||||
|
||||
if (start_maintain_audio_pitch_ == -1) {
|
||||
maintain_audio_pitch_box_->setTristate();
|
||||
} else {
|
||||
maintain_audio_pitch_box_->setChecked(start_maintain_audio_pitch_);
|
||||
}
|
||||
if (start_maintain_audio_pitch_ == -1) {
|
||||
maintain_audio_pitch_box_->setTristate();
|
||||
} else {
|
||||
maintain_audio_pitch_box_->setChecked(start_maintain_audio_pitch_);
|
||||
}
|
||||
|
||||
if (start_loop_ == -1) {
|
||||
loop_combo_->setCurrentIndex(-1);
|
||||
} else {
|
||||
loop_combo_->setCurrentIndex(start_loop_);
|
||||
}
|
||||
if (start_loop_ == -1) {
|
||||
loop_combo_->setCurrentIndex(-1);
|
||||
} else {
|
||||
loop_combo_->setCurrentIndex(start_loop_);
|
||||
}
|
||||
}
|
||||
|
||||
void SpeedDurationDialog::accept()
|
||||
{
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
|
||||
// Set duration values
|
||||
TimelineRippleDeleteGapsAtRegionsCommand::RangeList ripple_ranges;
|
||||
// Set duration values
|
||||
TimelineRippleDeleteGapsAtRegionsCommand::RangeList ripple_ranges;
|
||||
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
rational proposed_length = c->length();
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
rational proposed_length = c->length();
|
||||
|
||||
if (dur_slider_->IsTristate()) {
|
||||
if (link_box_->isChecked() && !speed_slider_->IsTristate()) {
|
||||
proposed_length = GetLengthAdjustment(c->length(), c->speed(), speed_slider_->GetValue(), timebase_);
|
||||
}
|
||||
} else {
|
||||
proposed_length = dur_slider_->GetValue();
|
||||
}
|
||||
if (dur_slider_->IsTristate()) {
|
||||
if (link_box_->isChecked() && !speed_slider_->IsTristate()) {
|
||||
proposed_length = GetLengthAdjustment(c->length(), c->speed(),
|
||||
speed_slider_->GetValue(),
|
||||
timebase_);
|
||||
}
|
||||
} else {
|
||||
proposed_length = dur_slider_->GetValue();
|
||||
}
|
||||
|
||||
if (proposed_length != c->length()) {
|
||||
// Clip length should ideally change, but check if there's "room" to do so
|
||||
if (proposed_length > c->length() && c->next()) {
|
||||
if (GapBlock *gap = dynamic_cast<GapBlock*>(c->next())) {
|
||||
proposed_length = qMin(proposed_length, gap->out() - c->in());
|
||||
} else {
|
||||
proposed_length = c->length();
|
||||
}
|
||||
}
|
||||
if (proposed_length != c->length()) {
|
||||
// Clip length should ideally change, but check if there's "room" to do so
|
||||
if (proposed_length > c->length() && c->next()) {
|
||||
if (GapBlock *gap = dynamic_cast<GapBlock *>(c->next())) {
|
||||
proposed_length =
|
||||
qMin(proposed_length, gap->out() - c->in());
|
||||
} else {
|
||||
proposed_length = c->length();
|
||||
}
|
||||
}
|
||||
|
||||
if (proposed_length != c->length()) {
|
||||
command->add_child(new BlockTrimCommand(c->track(), c, proposed_length, Timeline::kTrimOut));
|
||||
ripple_ranges.append({c->track(), TimeRange(c->in() + proposed_length, c->out())});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (proposed_length != c->length()) {
|
||||
command->add_child(new BlockTrimCommand(
|
||||
c->track(), c, proposed_length, Timeline::kTrimOut));
|
||||
ripple_ranges.append(
|
||||
{ c->track(),
|
||||
TimeRange(c->in() + proposed_length, c->out()) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ripple_box_->isChecked()) {
|
||||
command->add_child(new TimelineRippleDeleteGapsAtRegionsCommand(clips_.first()->track()->sequence(), ripple_ranges));
|
||||
}
|
||||
if (ripple_box_->isChecked()) {
|
||||
command->add_child(new TimelineRippleDeleteGapsAtRegionsCommand(
|
||||
clips_.first()->track()->sequence(), ripple_ranges));
|
||||
}
|
||||
|
||||
// Set speed values
|
||||
if (speed_slider_->IsTristate()) {
|
||||
if (link_box_->isChecked() && !dur_slider_->IsTristate()) {
|
||||
// Automatically determine speed from duration
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), GetSpeedAdjustment(c->speed(), c->length(), dur_slider_->GetValue())));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Set speeds to value of slider
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), speed_slider_->GetValue()));
|
||||
}
|
||||
}
|
||||
// Set speed values
|
||||
if (speed_slider_->IsTristate()) {
|
||||
if (link_box_->isChecked() && !dur_slider_->IsTristate()) {
|
||||
// Automatically determine speed from duration
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(
|
||||
NodeKeyframeTrackReference(
|
||||
NodeInput(c, ClipBlock::kSpeedInput)),
|
||||
GetSpeedAdjustment(c->speed(), c->length(),
|
||||
dur_slider_->GetValue())));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Set speeds to value of slider
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(
|
||||
NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)),
|
||||
speed_slider_->GetValue()));
|
||||
}
|
||||
}
|
||||
|
||||
// Set reverse values
|
||||
if (!reverse_box_->isTristate()) {
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kReverseInput)), reverse_box_->isChecked()));
|
||||
}
|
||||
}
|
||||
// Set reverse values
|
||||
if (!reverse_box_->isTristate()) {
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(
|
||||
NodeKeyframeTrackReference(
|
||||
NodeInput(c, ClipBlock::kReverseInput)),
|
||||
reverse_box_->isChecked()));
|
||||
}
|
||||
}
|
||||
|
||||
// Set reverse values
|
||||
if (!maintain_audio_pitch_box_->isTristate()) {
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kMaintainAudioPitchInput)), maintain_audio_pitch_box_->isChecked()));
|
||||
}
|
||||
}
|
||||
// Set reverse values
|
||||
if (!maintain_audio_pitch_box_->isTristate()) {
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(
|
||||
NodeKeyframeTrackReference(
|
||||
NodeInput(c, ClipBlock::kMaintainAudioPitchInput)),
|
||||
maintain_audio_pitch_box_->isChecked()));
|
||||
}
|
||||
}
|
||||
|
||||
if (loop_combo_->currentIndex() != -1) {
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kLoopModeInput)), loop_combo_->currentData()));
|
||||
}
|
||||
}
|
||||
if (loop_combo_->currentIndex() != -1) {
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(
|
||||
NodeKeyframeTrackReference(
|
||||
NodeInput(c, ClipBlock::kLoopModeInput)),
|
||||
loop_combo_->currentData()));
|
||||
}
|
||||
}
|
||||
|
||||
QString name = (clips_.size() > 1) ? tr("Set %1 Clip Properties").arg(clips_.size()) : tr("Set Clip \"%1\" Properties").arg(clips_.first()->GetLabelOrName());
|
||||
Core::instance()->undo_stack()->push(command, name);
|
||||
QString name = (clips_.size() > 1) ?
|
||||
tr("Set %1 Clip Properties").arg(clips_.size()) :
|
||||
tr("Set Clip \"%1\" Properties")
|
||||
.arg(clips_.first()->GetLabelOrName());
|
||||
Core::instance()->undo_stack()->push(command, name);
|
||||
|
||||
super::accept();
|
||||
super::accept();
|
||||
}
|
||||
|
||||
rational SpeedDurationDialog::GetLengthAdjustment(const rational &original_length, double original_speed, double new_speed, const rational &timebase)
|
||||
rational SpeedDurationDialog::GetLengthAdjustment(
|
||||
const rational &original_length, double original_speed, double new_speed,
|
||||
const rational &timebase)
|
||||
{
|
||||
return Timecode::snap_time_to_timebase(rational::fromDouble(original_length.toDouble() / new_speed * original_speed), timebase);
|
||||
return Timecode::snap_time_to_timebase(
|
||||
rational::fromDouble(original_length.toDouble() / new_speed *
|
||||
original_speed),
|
||||
timebase);
|
||||
}
|
||||
|
||||
double SpeedDurationDialog::GetSpeedAdjustment(double original_speed, const rational &original_length, const rational &new_length)
|
||||
double SpeedDurationDialog::GetSpeedAdjustment(double original_speed,
|
||||
const rational &original_length,
|
||||
const rational &new_length)
|
||||
{
|
||||
return original_speed / new_length.toDouble() * original_length.toDouble();
|
||||
return original_speed / new_length.toDouble() * original_length.toDouble();
|
||||
}
|
||||
|
||||
void SpeedDurationDialog::SpeedChanged(double s)
|
||||
{
|
||||
if (!link_box_->isChecked()) {
|
||||
return;
|
||||
}
|
||||
if (!link_box_->isChecked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (start_duration_ == -1) {
|
||||
dur_slider_->SetTristate();
|
||||
} else {
|
||||
dur_slider_->SetValue(GetLengthAdjustment(start_duration_, start_speed_, s, timebase_));
|
||||
}
|
||||
if (start_duration_ == -1) {
|
||||
dur_slider_->SetTristate();
|
||||
} else {
|
||||
dur_slider_->SetValue(
|
||||
GetLengthAdjustment(start_duration_, start_speed_, s, timebase_));
|
||||
}
|
||||
}
|
||||
|
||||
void SpeedDurationDialog::DurationChanged(const rational &r)
|
||||
{
|
||||
if (!link_box_->isChecked()) {
|
||||
return;
|
||||
}
|
||||
if (!link_box_->isChecked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (qIsNaN(start_speed_)) {
|
||||
speed_slider_->SetTristate();
|
||||
} else {
|
||||
speed_slider_->SetValue(GetSpeedAdjustment(start_speed_, start_duration_, r));
|
||||
}
|
||||
if (qIsNaN(start_speed_)) {
|
||||
speed_slider_->SetTristate();
|
||||
} else {
|
||||
speed_slider_->SetValue(
|
||||
GetSpeedAdjustment(start_speed_, start_duration_, r));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,57 +31,62 @@
|
||||
#include "widget/slider/floatslider.h"
|
||||
#include "widget/slider/rationalslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class SpeedDurationDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class SpeedDurationDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SpeedDurationDialog(const QVector<ClipBlock*> &clips, const rational &timebase, QWidget *parent = nullptr);
|
||||
explicit SpeedDurationDialog(const QVector<ClipBlock *> &clips,
|
||||
const rational &timebase,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
static rational GetLengthAdjustment(const rational &original_length, double original_speed, double new_speed, const rational &timebase);
|
||||
static rational GetLengthAdjustment(const rational &original_length,
|
||||
double original_speed, double new_speed,
|
||||
const rational &timebase);
|
||||
|
||||
static double GetSpeedAdjustment(double original_speed, const rational &original_length, const rational &new_length);
|
||||
static double GetSpeedAdjustment(double original_speed,
|
||||
const rational &original_length,
|
||||
const rational &new_length);
|
||||
|
||||
QVector<ClipBlock*> clips_;
|
||||
QVector<ClipBlock *> clips_;
|
||||
|
||||
FloatSlider *speed_slider_;
|
||||
FloatSlider *speed_slider_;
|
||||
|
||||
RationalSlider *dur_slider_;
|
||||
RationalSlider *dur_slider_;
|
||||
|
||||
QCheckBox *link_box_;
|
||||
QCheckBox *link_box_;
|
||||
|
||||
QCheckBox *reverse_box_;
|
||||
QCheckBox *reverse_box_;
|
||||
|
||||
QCheckBox *maintain_audio_pitch_box_;
|
||||
QCheckBox *maintain_audio_pitch_box_;
|
||||
|
||||
QCheckBox *ripple_box_;
|
||||
QCheckBox *ripple_box_;
|
||||
|
||||
QComboBox *loop_combo_;
|
||||
QComboBox *loop_combo_;
|
||||
|
||||
int start_reverse_;
|
||||
int start_reverse_;
|
||||
|
||||
int start_maintain_audio_pitch_;
|
||||
int start_maintain_audio_pitch_;
|
||||
|
||||
double start_speed_;
|
||||
double start_speed_;
|
||||
|
||||
rational start_duration_;
|
||||
rational start_duration_;
|
||||
|
||||
int start_loop_;
|
||||
int start_loop_;
|
||||
|
||||
rational timebase_;
|
||||
rational timebase_;
|
||||
|
||||
private slots:
|
||||
void SpeedChanged(double s);
|
||||
|
||||
void DurationChanged(const rational &r);
|
||||
void SpeedChanged(double s);
|
||||
|
||||
void DurationChanged(const rational &r);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+50
-46
@@ -22,83 +22,87 @@
|
||||
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
namespace olive {
|
||||
namespace olive
|
||||
{
|
||||
|
||||
#define super ProgressDialog
|
||||
|
||||
TaskDialog::TaskDialog(Task* task, const QString& title, QWidget *parent) :
|
||||
super(task->GetTitle(), title, parent),
|
||||
task_(task),
|
||||
destroy_on_close_(true),
|
||||
already_shown_(false)
|
||||
TaskDialog::TaskDialog(Task *task, const QString &title, QWidget *parent)
|
||||
: super(task->GetTitle(), title, parent)
|
||||
, task_(task)
|
||||
, destroy_on_close_(true)
|
||||
, already_shown_(false)
|
||||
{
|
||||
// Clear task when this dialog is destroyed
|
||||
task_->setParent(this);
|
||||
// Clear task when this dialog is destroyed
|
||||
task_->setParent(this);
|
||||
|
||||
// Connect the save manager progress signal to the progress bar update on the dialog
|
||||
connect(task_, &Task::ProgressChanged, this, &TaskDialog::SetProgress, Qt::QueuedConnection);
|
||||
// Connect the save manager progress signal to the progress bar update on the dialog
|
||||
connect(task_, &Task::ProgressChanged, this, &TaskDialog::SetProgress,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
// Connect cancel signal (must be a direct connection or it'll be queued after the task has
|
||||
// already finished)
|
||||
connect(this, &TaskDialog::Cancelled, task_, &Task::Cancel, Qt::DirectConnection);
|
||||
// Connect cancel signal (must be a direct connection or it'll be queued after the task has
|
||||
// already finished)
|
||||
connect(this, &TaskDialog::Cancelled, task_, &Task::Cancel,
|
||||
Qt::DirectConnection);
|
||||
}
|
||||
|
||||
void TaskDialog::showEvent(QShowEvent *e)
|
||||
{
|
||||
super::showEvent(e);
|
||||
super::showEvent(e);
|
||||
|
||||
if (!already_shown_) {
|
||||
// Create watcher for when the task finishes
|
||||
QFutureWatcher<bool>* task_watcher = new QFutureWatcher<bool>();
|
||||
if (!already_shown_) {
|
||||
// Create watcher for when the task finishes
|
||||
QFutureWatcher<bool> *task_watcher = new QFutureWatcher<bool>();
|
||||
|
||||
// Listen for when the task finishes
|
||||
connect(task_watcher, &QFutureWatcher<bool>::finished,
|
||||
this, &TaskDialog::TaskFinished, Qt::QueuedConnection);
|
||||
// Listen for when the task finishes
|
||||
connect(task_watcher, &QFutureWatcher<bool>::finished, this,
|
||||
&TaskDialog::TaskFinished, Qt::QueuedConnection);
|
||||
|
||||
// Run task in another thread with QtConcurrent
|
||||
task_watcher->setFuture(
|
||||
// Run task in another thread with QtConcurrent
|
||||
task_watcher->setFuture(
|
||||
#if QT_VERSION_MAJOR >= 6
|
||||
QtConcurrent::run(&Task::Start, task_)
|
||||
QtConcurrent::run(&Task::Start, task_)
|
||||
#else
|
||||
QtConcurrent::run(task_, &Task::Start)
|
||||
QtConcurrent::run(task_, &Task::Start)
|
||||
#endif
|
||||
);
|
||||
);
|
||||
|
||||
already_shown_ = true;
|
||||
}
|
||||
already_shown_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TaskDialog::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
// Cancel task if it is running
|
||||
task_->Cancel();
|
||||
// Cancel task if it is running
|
||||
task_->Cancel();
|
||||
|
||||
// Standard close function
|
||||
super::closeEvent(e);
|
||||
// Standard close function
|
||||
super::closeEvent(e);
|
||||
|
||||
// Reset shown
|
||||
already_shown_ = false;
|
||||
// Reset shown
|
||||
already_shown_ = false;
|
||||
|
||||
// Clean up this task and dialog
|
||||
if (destroy_on_close_) {
|
||||
deleteLater();
|
||||
}
|
||||
// Clean up this task and dialog
|
||||
if (destroy_on_close_) {
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void TaskDialog::TaskFinished()
|
||||
{
|
||||
QFutureWatcher<bool>* task_watcher = static_cast<QFutureWatcher<bool>*>(sender());
|
||||
QFutureWatcher<bool> *task_watcher =
|
||||
static_cast<QFutureWatcher<bool> *>(sender());
|
||||
|
||||
if (task_watcher->result()) {
|
||||
emit TaskSucceeded(task_);
|
||||
} else {
|
||||
ShowErrorMessage(tr("Task Failed"), task_->GetError());
|
||||
emit TaskFailed(task_);
|
||||
}
|
||||
if (task_watcher->result()) {
|
||||
emit TaskSucceeded(task_);
|
||||
} else {
|
||||
ShowErrorMessage(tr("Task Failed"), task_->GetError());
|
||||
emit TaskFailed(task_);
|
||||
}
|
||||
|
||||
task_watcher->deleteLater();
|
||||
task_watcher->deleteLater();
|
||||
|
||||
close();
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+24
-25
@@ -24,59 +24,58 @@
|
||||
#include "dialog/progress/progress.h"
|
||||
#include "task/task.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class TaskDialog : public ProgressDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class TaskDialog : public ProgressDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* @brief TaskDialog Constructor
|
||||
*
|
||||
* Creates a TaskDialog. The TaskDialog takes ownership of the Task and will destroy it on close.
|
||||
* Connect to the Task::Succeeded() if you want to retrieve information from the task before it
|
||||
* gets destroyed.
|
||||
*/
|
||||
TaskDialog(Task *task, const QString &title, QWidget* parent = nullptr);
|
||||
TaskDialog(Task *task, const QString &title, QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Set whether TaskDialog should destroy itself (and the task) when it's closed
|
||||
*
|
||||
* This is TRUE by default.
|
||||
*/
|
||||
void SetDestroyOnClose(bool e)
|
||||
{
|
||||
destroy_on_close_ = e;
|
||||
}
|
||||
void SetDestroyOnClose(bool e)
|
||||
{
|
||||
destroy_on_close_ = e;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Returns this dialog's task
|
||||
*/
|
||||
Task* GetTask() const
|
||||
{
|
||||
return task_;
|
||||
}
|
||||
Task *GetTask() const
|
||||
{
|
||||
return task_;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
virtual void showEvent(QShowEvent *e) override;
|
||||
|
||||
virtual void closeEvent(QCloseEvent* e) override;
|
||||
virtual void closeEvent(QCloseEvent *e) override;
|
||||
|
||||
signals:
|
||||
void TaskSucceeded(Task* task);
|
||||
void TaskSucceeded(Task *task);
|
||||
|
||||
void TaskFailed(Task* task);
|
||||
void TaskFailed(Task *task);
|
||||
|
||||
private:
|
||||
Task* task_;
|
||||
Task *task_;
|
||||
|
||||
bool destroy_on_close_;
|
||||
bool destroy_on_close_;
|
||||
|
||||
bool already_shown_;
|
||||
bool already_shown_;
|
||||
|
||||
private slots:
|
||||
void TaskFinished();
|
||||
|
||||
void TaskFinished();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+16
-14
@@ -28,23 +28,25 @@
|
||||
|
||||
#include "ui/icons/icons.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
TextDialog::TextDialog(const QString &start, QWidget* parent) :
|
||||
QDialog(parent)
|
||||
namespace olive
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
// Create text edit widget
|
||||
text_edit_ = new QPlainTextEdit();
|
||||
text_edit_->document()->setPlainText(start);
|
||||
layout->addWidget(text_edit_);
|
||||
TextDialog::TextDialog(const QString &start, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
// Create buttons
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
layout->addWidget(buttons);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &TextDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &TextDialog::reject);
|
||||
// Create text edit widget
|
||||
text_edit_ = new QPlainTextEdit();
|
||||
text_edit_->document()->setPlainText(start);
|
||||
layout->addWidget(text_edit_);
|
||||
|
||||
// Create buttons
|
||||
QDialogButtonBox *buttons =
|
||||
new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
layout->addWidget(buttons);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &TextDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &TextDialog::reject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-12
@@ -28,22 +28,21 @@
|
||||
#include "common/define.h"
|
||||
#include "widget/slider/floatslider.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
class TextDialog : public QDialog
|
||||
namespace olive
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TextDialog(const QString &start, QWidget* parent = nullptr);
|
||||
|
||||
QString text() const
|
||||
{
|
||||
return text_edit_->toPlainText();
|
||||
}
|
||||
class TextDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TextDialog(const QString &start, QWidget *parent = nullptr);
|
||||
|
||||
QString text() const
|
||||
{
|
||||
return text_edit_->toPlainText();
|
||||
}
|
||||
|
||||
private:
|
||||
QPlainTextEdit* text_edit_;
|
||||
|
||||
QPlainTextEdit *text_edit_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user