change: change code style to Linux style except indent.

This commit is contained in:
Mike Solar
2025-08-03 03:09:40 +08:00
parent 65ab76edc8
commit 74f73ab3be
789 changed files with 77113 additions and 68888 deletions
+96 -83
View File
@@ -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();
}
}
+8 -9
View File
@@ -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_;
};
}
+58 -55
View File
@@ -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 -24
View File
@@ -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();
};
}
+187 -183
View File
@@ -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();
}
}
+40 -36
View File
@@ -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();
};
}
+90 -71
View File
@@ -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);
}
}
}
}
}
}
+12 -14
View File
@@ -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
View File
@@ -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);
}
}
+21 -20
View File
@@ -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);
};
}
+39 -37
View File
@@ -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);
}
}
+14 -13
View File
@@ -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;
}
}
+6 -6
View File
@@ -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;
};
}
+69 -54
View File
@@ -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"));
}
}
}
}
+14 -14
View File
@@ -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();
};
}
+70 -64
View File
@@ -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();
}
}
+21 -23
View File
@@ -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_;
};
}
+32 -28
View File
@@ -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());
}
}
+8 -9
View File
@@ -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_;
};
}
+4 -3
View File
@@ -20,10 +20,11 @@
#include "codecsection.h"
namespace olive {
namespace olive
{
CodecSection::CodecSection(QWidget *parent) :
QWidget(parent)
CodecSection::CodecSection(QWidget *parent)
: QWidget(parent)
{
}
+13 -8
View File
@@ -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)
}
};
}
+17 -14
View File
@@ -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();
}
}
+8 -9
View File
@@ -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);
};
}
+174 -164
View File
@@ -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)
{
}
+49 -56
View File
@@ -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 -20
View File
@@ -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);
}
}
+29 -30
View File
@@ -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);
};
}
File diff suppressed because it is too large Load Diff
+60 -62
View File
@@ -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();
};
}
+48 -42
View File
@@ -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);
}
}
+34 -34
View File
@@ -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_;
};
}
+61 -54
View File
@@ -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);
}
}
}
+45 -45
View File
@@ -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();
};
}
+80 -76
View File
@@ -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;
}
}
+27 -27
View File
@@ -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_;
};
}
+62 -49
View File
@@ -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();
}
}
+13 -14
View File
@@ -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_;
};
}
+47 -42
View File
@@ -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();
}
}
+35 -23
View File
@@ -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_;
};
}
+170 -157
View File
@@ -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
View File
@@ -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);
};
}
+190 -185
View File
@@ -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_;
};
};
}
+118 -113
View File
@@ -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);
}
}
}
+10 -10
View File
@@ -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
+37 -30
View File
@@ -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);
}
}
}
+17 -16
View File
@@ -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;
};
}
+13 -12
View File
@@ -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();
}
}
+6 -7
View File
@@ -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_;
};
}
+71 -61
View File
@@ -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;
}
}
+17 -17
View File
@@ -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();
};
}
+198 -161
View File
@@ -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();
};
}
+29 -25
View File
@@ -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();
}
}
}
+14 -15
View File
@@ -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
View File
@@ -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
View File
@@ -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_);
}
}
+41 -47
View File
@@ -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();
};
}
+113 -114
View File
@@ -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();
};
}
+190 -200
View File
@@ -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;
}
}
}
+32 -24
View File
@@ -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();
};
}
+132 -121
View File
@@ -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_;
};
}
+236 -193
View File
@@ -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));
}
}
}
+30 -25
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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_;
};
}