added thread count selection in export settings
This commit is contained in:
@@ -28,63 +28,80 @@
|
||||
#include <QDebug>
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
}
|
||||
|
||||
AdvancedVideoDialog::AdvancedVideoDialog(QWidget *parent,
|
||||
int encoding_codec,
|
||||
VideoCodecParams &iparams) :
|
||||
QDialog(parent),
|
||||
params(iparams)
|
||||
QDialog(parent),
|
||||
params_(iparams)
|
||||
{
|
||||
setWindowTitle(tr("Advanced Video Settings"));
|
||||
setWindowTitle(tr("Advanced Video Settings"));
|
||||
|
||||
// use variable for row to assist adding new fields to this dialog
|
||||
int row = 0;
|
||||
// use variable for row to assist adding new fields to the grid layout
|
||||
int row = 0;
|
||||
|
||||
// get encoder information for this codec
|
||||
AVCodec* codec_info = avcodec_find_encoder(static_cast<AVCodecID>(encoding_codec));
|
||||
// get encoder information for this codec from FFmpeg
|
||||
AVCodec* codec_info = avcodec_find_encoder(static_cast<AVCodecID>(encoding_codec));
|
||||
|
||||
// set up grid layout for dialog
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
// set up grid layout for dialog
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
|
||||
// codec pixel formats
|
||||
layout->addWidget(new QLabel(tr("Pixel Format:")), row, 0);
|
||||
// create row for codec pixel formats
|
||||
layout->addWidget(new QLabel(tr("Pixel Format:")), row, 0);
|
||||
pix_fmt_combo_ = new QComboBox();
|
||||
|
||||
pix_fmt_combo = new QComboBox();
|
||||
// loop through available pixel formats for this codec
|
||||
int pix_fmt_index = 0;
|
||||
while (codec_info->pix_fmts[pix_fmt_index] != -1) { // AVCodec->pix_fmts is terminated by "-1"
|
||||
|
||||
// load possible pixel formats for this codec into the combobox
|
||||
int pix_fmt_index = 0;
|
||||
// get the name of the pixel format and add it to the combobox (with the pixel format constant)
|
||||
pix_fmt_combo_->addItem(av_get_pix_fmt_name(codec_info->pix_fmts[pix_fmt_index]),
|
||||
codec_info->pix_fmts[pix_fmt_index]);
|
||||
|
||||
// AVCodec->pix_fmts is terminated by "-1"
|
||||
while (codec_info->pix_fmts[pix_fmt_index] != -1) {
|
||||
pix_fmt_combo->addItem(av_get_pix_fmt_name(codec_info->pix_fmts[pix_fmt_index]),
|
||||
codec_info->pix_fmts[pix_fmt_index]);
|
||||
|
||||
if (codec_info->pix_fmts[pix_fmt_index] == params.pix_fmt) {
|
||||
pix_fmt_combo->setCurrentIndex(pix_fmt_combo->count()-1);
|
||||
}
|
||||
|
||||
pix_fmt_index++;
|
||||
// if the user has already selected a pixel format, set the combobox to it as well
|
||||
if (codec_info->pix_fmts[pix_fmt_index] == params_.pix_fmt) {
|
||||
pix_fmt_combo_->setCurrentIndex(pix_fmt_combo_->count()-1);
|
||||
}
|
||||
|
||||
layout->addWidget(pix_fmt_combo, row, 1);
|
||||
pix_fmt_index++;
|
||||
}
|
||||
|
||||
row++;
|
||||
layout->addWidget(pix_fmt_combo_, row, 1);
|
||||
|
||||
// buttons
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttons->setCenterButtons(true);
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
row++;
|
||||
|
||||
// create row for multithreading thread count
|
||||
layout->addWidget(new QLabel(tr("Threads:")), row, 0);
|
||||
|
||||
thread_spinbox_ = new QSpinBox();
|
||||
|
||||
// with the thread count, "0" is considered automatics
|
||||
thread_spinbox_->setMinimum(0);
|
||||
thread_spinbox_->setSpecialValueText("Auto");
|
||||
|
||||
// load current thread value
|
||||
thread_spinbox_->setValue(params_.threads);
|
||||
|
||||
layout->addWidget(thread_spinbox_);
|
||||
|
||||
row++;
|
||||
|
||||
// buttons
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttons->setCenterButtons(true);
|
||||
connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
layout->addWidget(buttons, row, 0, 1, 2);
|
||||
}
|
||||
|
||||
void AdvancedVideoDialog::accept() {
|
||||
// store settings back into struct
|
||||
// store settings back into struct
|
||||
|
||||
params.pix_fmt = pix_fmt_combo->currentData().toInt();
|
||||
params_.pix_fmt = pix_fmt_combo_->currentData().toInt();
|
||||
params_.threads = thread_spinbox_->value();
|
||||
|
||||
QDialog::accept();
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
@@ -23,22 +23,40 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QComboBox>
|
||||
#include <QSpinBox>
|
||||
|
||||
#include "io/exportthread.h"
|
||||
|
||||
/**
|
||||
* @brief The AdvancedVideoDialog class
|
||||
*
|
||||
* A dialog for interfacing with VideoCodecParams, a struct for more advanced video settings sometimes specific to
|
||||
* one codec.
|
||||
*/
|
||||
class AdvancedVideoDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
AdvancedVideoDialog(QWidget* parent,
|
||||
int encoding_codec,
|
||||
VideoCodecParams& iparams);
|
||||
AdvancedVideoDialog(QWidget* parent,
|
||||
int encoding_codec,
|
||||
VideoCodecParams& iparams);
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
virtual void accept() override;
|
||||
private:
|
||||
VideoCodecParams& params;
|
||||
/**
|
||||
* @brief Internal reference to VideoCodecParams struct provided by ExportDialog.
|
||||
*/
|
||||
VideoCodecParams& params_;
|
||||
|
||||
QComboBox* pix_fmt_combo;
|
||||
/**
|
||||
* @brief ComboBox to show available pixel formats for this codec
|
||||
*/
|
||||
QComboBox* pix_fmt_combo_;
|
||||
|
||||
/**
|
||||
* @brief SpinBox for multithreading settings
|
||||
*/
|
||||
QSpinBox* thread_spinbox_;
|
||||
};
|
||||
|
||||
#endif // ADVANCEDVIDEODIALOG_H
|
||||
|
||||
@@ -107,10 +107,14 @@ ExportDialog::ExportDialog(QWidget *parent) :
|
||||
}
|
||||
formatCombobox->setCurrentIndex(FORMAT_MPEG4);
|
||||
|
||||
// default to sequence's native dimensions
|
||||
widthSpinbox->setValue(olive::ActiveSequence->width);
|
||||
heightSpinbox->setValue(olive::ActiveSequence->height);
|
||||
samplingRateSpinbox->setValue(olive::ActiveSequence->audio_frequency);
|
||||
framerateSpinbox->setValue(olive::ActiveSequence->frame_rate);
|
||||
|
||||
// set some advanced defaults
|
||||
vcodec_params.threads = 0;
|
||||
}
|
||||
|
||||
ExportDialog::~ExportDialog()
|
||||
|
||||
+37
-37
@@ -35,52 +35,52 @@
|
||||
|
||||
class ExportDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExportDialog(QWidget *parent = 0);
|
||||
~ExportDialog();
|
||||
QString export_error;
|
||||
explicit ExportDialog(QWidget *parent = nullptr);
|
||||
~ExportDialog();
|
||||
QString export_error;
|
||||
|
||||
private slots:
|
||||
void format_changed(int index);
|
||||
void export_action();
|
||||
void update_progress_bar(int value, qint64 remaining_ms);
|
||||
void cancel_render();
|
||||
void render_thread_finished();
|
||||
void vcodec_changed(int index);
|
||||
void comp_type_changed(int index);
|
||||
void open_advanced_video_dialog();
|
||||
void format_changed(int index);
|
||||
void export_action();
|
||||
void update_progress_bar(int value, qint64 remaining_ms);
|
||||
void cancel_render();
|
||||
void render_thread_finished();
|
||||
void vcodec_changed(int index);
|
||||
void comp_type_changed(int index);
|
||||
void open_advanced_video_dialog();
|
||||
|
||||
private:
|
||||
QVector<QString> format_strings;
|
||||
void setup_ui();
|
||||
QVector<QString> format_strings;
|
||||
void setup_ui();
|
||||
|
||||
ExportThread* et;
|
||||
void prep_ui_for_render(bool r);
|
||||
bool cancelled;
|
||||
ExportThread* et;
|
||||
void prep_ui_for_render(bool r);
|
||||
bool cancelled;
|
||||
|
||||
void add_codec_to_combobox(QComboBox* box, enum AVCodecID codec);
|
||||
void add_codec_to_combobox(QComboBox* box, enum AVCodecID codec);
|
||||
|
||||
VideoCodecParams vcodec_params;
|
||||
VideoCodecParams vcodec_params;
|
||||
|
||||
QComboBox* rangeCombobox;
|
||||
QSpinBox* widthSpinbox;
|
||||
QDoubleSpinBox* videobitrateSpinbox;
|
||||
QLabel* videoBitrateLabel;
|
||||
QDoubleSpinBox* framerateSpinbox;
|
||||
QComboBox* vcodecCombobox;
|
||||
QComboBox* acodecCombobox;
|
||||
QSpinBox* samplingRateSpinbox;
|
||||
QSpinBox* audiobitrateSpinbox;
|
||||
QProgressBar* progressBar;
|
||||
QComboBox* formatCombobox;
|
||||
QSpinBox* heightSpinbox;
|
||||
QPushButton* export_button;
|
||||
QPushButton* cancel_button;
|
||||
QPushButton* renderCancel;
|
||||
QGroupBox* videoGroupbox;
|
||||
QGroupBox* audioGroupbox;
|
||||
QComboBox* compressionTypeCombobox;
|
||||
QComboBox* rangeCombobox;
|
||||
QSpinBox* widthSpinbox;
|
||||
QDoubleSpinBox* videobitrateSpinbox;
|
||||
QLabel* videoBitrateLabel;
|
||||
QDoubleSpinBox* framerateSpinbox;
|
||||
QComboBox* vcodecCombobox;
|
||||
QComboBox* acodecCombobox;
|
||||
QSpinBox* samplingRateSpinbox;
|
||||
QSpinBox* audiobitrateSpinbox;
|
||||
QProgressBar* progressBar;
|
||||
QComboBox* formatCombobox;
|
||||
QSpinBox* heightSpinbox;
|
||||
QPushButton* export_button;
|
||||
QPushButton* cancel_button;
|
||||
QPushButton* renderCancel;
|
||||
QGroupBox* videoGroupbox;
|
||||
QGroupBox* audioGroupbox;
|
||||
QComboBox* compressionTypeCombobox;
|
||||
};
|
||||
|
||||
#endif // EXPORTDIALOG_H
|
||||
|
||||
+8
-1
@@ -151,6 +151,8 @@ bool ExportThread::setupVideo() {
|
||||
}
|
||||
|
||||
switch (vcodec_ctx->codec_id) {
|
||||
|
||||
/// H.264 specific settings
|
||||
case AV_CODEC_ID_H264:
|
||||
switch (params.video_compression_type) {
|
||||
case COMPRESSION_TYPE_CFR:
|
||||
@@ -158,10 +160,15 @@ bool ExportThread::setupVideo() {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
AVDictionary* opts = nullptr;
|
||||
av_dict_set(&opts, "threads", "auto", 0);
|
||||
if (vcodec_params.threads == 0) {
|
||||
av_dict_set(&opts, "threads", "auto", 0);
|
||||
} else {
|
||||
av_dict_set(&opts, "threads", QString::number(vcodec_params.threads).toUtf8(), 0);
|
||||
}
|
||||
|
||||
ret = avcodec_open2(vcodec_ctx, vcodec, &opts);
|
||||
if (ret < 0) {
|
||||
|
||||
+56
-55
@@ -36,7 +36,7 @@ struct SwsContext;
|
||||
struct SwrContext;
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
}
|
||||
|
||||
#define COMPRESSION_TYPE_CBR 0
|
||||
@@ -47,79 +47,80 @@ extern "C" {
|
||||
// structs that store parameters passed from the export dialogs to this thread
|
||||
|
||||
struct ExportParams {
|
||||
// export parameters
|
||||
QString filename;
|
||||
bool video_enabled;
|
||||
int video_codec;
|
||||
int video_width;
|
||||
int video_height;
|
||||
double video_frame_rate;
|
||||
int video_compression_type;
|
||||
double video_bitrate;
|
||||
bool audio_enabled;
|
||||
int audio_codec;
|
||||
int audio_sampling_rate;
|
||||
int audio_bitrate;
|
||||
long start_frame;
|
||||
long end_frame;
|
||||
// export parameters
|
||||
QString filename;
|
||||
bool video_enabled;
|
||||
int video_codec;
|
||||
int video_width;
|
||||
int video_height;
|
||||
double video_frame_rate;
|
||||
int video_compression_type;
|
||||
double video_bitrate;
|
||||
bool audio_enabled;
|
||||
int audio_codec;
|
||||
int audio_sampling_rate;
|
||||
int audio_bitrate;
|
||||
long start_frame;
|
||||
long end_frame;
|
||||
};
|
||||
|
||||
struct VideoCodecParams {
|
||||
int pix_fmt;
|
||||
int pix_fmt;
|
||||
int threads;
|
||||
};
|
||||
|
||||
class ExportThread : public QThread {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExportThread(const ExportParams& iparams, const VideoCodecParams& ivparams, QObject* parent = nullptr);
|
||||
void run();
|
||||
ExportThread(const ExportParams& iparams, const VideoCodecParams& ivparams, QObject* parent = nullptr);
|
||||
void run();
|
||||
|
||||
const QString& getError();
|
||||
const QString& getError();
|
||||
|
||||
QOffscreenSurface surface;
|
||||
QOffscreenSurface surface;
|
||||
|
||||
bool continueEncode;
|
||||
bool continueEncode;
|
||||
signals:
|
||||
void progress_changed(int value, qint64 remaining_ms);
|
||||
void progress_changed(int value, qint64 remaining_ms);
|
||||
public slots:
|
||||
void wake();
|
||||
void wake();
|
||||
private:
|
||||
bool encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream, bool rescale);
|
||||
bool setupVideo();
|
||||
bool setupAudio();
|
||||
bool setupContainer();
|
||||
bool encode(AVFormatContext* ofmt_ctx, AVCodecContext* codec_ctx, AVFrame* frame, AVPacket* packet, AVStream* stream, bool rescale);
|
||||
bool setupVideo();
|
||||
bool setupAudio();
|
||||
bool setupContainer();
|
||||
|
||||
// params imported from dialogs
|
||||
ExportParams params;
|
||||
VideoCodecParams vcodec_params;
|
||||
// params imported from dialogs
|
||||
ExportParams params;
|
||||
VideoCodecParams vcodec_params;
|
||||
|
||||
AVFormatContext* fmt_ctx;
|
||||
AVStream* video_stream;
|
||||
AVCodec* vcodec;
|
||||
AVCodecContext* vcodec_ctx;
|
||||
AVFrame* video_frame;
|
||||
AVFrame* sws_frame;
|
||||
SwsContext* sws_ctx;
|
||||
AVStream* audio_stream;
|
||||
AVCodec* acodec;
|
||||
AVFrame* audio_frame;
|
||||
AVFrame* swr_frame;
|
||||
AVCodecContext* acodec_ctx;
|
||||
AVPacket video_pkt;
|
||||
AVPacket audio_pkt;
|
||||
SwrContext* swr_ctx;
|
||||
AVFormatContext* fmt_ctx;
|
||||
AVStream* video_stream;
|
||||
AVCodec* vcodec;
|
||||
AVCodecContext* vcodec_ctx;
|
||||
AVFrame* video_frame;
|
||||
AVFrame* sws_frame;
|
||||
SwsContext* sws_ctx;
|
||||
AVStream* audio_stream;
|
||||
AVCodec* acodec;
|
||||
AVFrame* audio_frame;
|
||||
AVFrame* swr_frame;
|
||||
AVCodecContext* acodec_ctx;
|
||||
AVPacket video_pkt;
|
||||
AVPacket audio_pkt;
|
||||
SwrContext* swr_ctx;
|
||||
|
||||
bool vpkt_alloc;
|
||||
bool apkt_alloc;
|
||||
bool vpkt_alloc;
|
||||
bool apkt_alloc;
|
||||
|
||||
int aframe_bytes;
|
||||
int ret;
|
||||
char* c_filename;
|
||||
int aframe_bytes;
|
||||
int ret;
|
||||
char* c_filename;
|
||||
|
||||
QMutex mutex;
|
||||
QWaitCondition waitCond;
|
||||
QMutex mutex;
|
||||
QWaitCondition waitCond;
|
||||
|
||||
QString export_error;
|
||||
QString export_error;
|
||||
};
|
||||
|
||||
#endif // EXPORTTHREAD_H
|
||||
|
||||
@@ -343,6 +343,10 @@ void MainWindow::editMenu_About_To_Be_Shown() {
|
||||
|
||||
void MainWindow::setup_menus() {
|
||||
QMenuBar* menuBar = new QMenuBar(this);
|
||||
menuBar->setStyle(QStyleFactory::create("windowsvista"));
|
||||
menuBar->setPalette(menuBar->style()->standardPalette());
|
||||
menuBar->setStyleSheet("");
|
||||
|
||||
setMenuBar(menuBar);
|
||||
|
||||
olive::MenuHelper.InitializeSharedMenus();
|
||||
|
||||
+168
-168
@@ -52,64 +52,64 @@ QString olive::ActiveProjectFilename;
|
||||
QString olive::AppName;
|
||||
|
||||
OliveGlobal::OliveGlobal() {
|
||||
// sets current app name
|
||||
QString version_id;
|
||||
// sets current app name
|
||||
QString version_id;
|
||||
#ifdef GITHASH
|
||||
version_id = QString(" | %1").arg(GITHASH);
|
||||
version_id = QString(" | %1").arg(GITHASH);
|
||||
#endif
|
||||
olive::AppName = QString("Olive (February 2019 | Alpha%1)").arg(version_id);
|
||||
olive::AppName = QString("Olive (February 2019 | Alpha%1)").arg(version_id);
|
||||
|
||||
// set the file filter used in all file dialogs pertaining to Olive project files.
|
||||
project_file_filter = tr("Olive Project %1").arg("(*.ove)");
|
||||
// set the file filter used in all file dialogs pertaining to Olive project files.
|
||||
project_file_filter = tr("Olive Project %1").arg("(*.ove)");
|
||||
|
||||
// set default value
|
||||
enable_load_project_on_init = false;
|
||||
// set default value
|
||||
enable_load_project_on_init = false;
|
||||
|
||||
// alloc QTranslator
|
||||
translator = std::unique_ptr<QTranslator>(new QTranslator());
|
||||
// alloc QTranslator
|
||||
translator = std::unique_ptr<QTranslator>(new QTranslator());
|
||||
}
|
||||
|
||||
const QString &OliveGlobal::get_project_file_filter() {
|
||||
return project_file_filter;
|
||||
return project_file_filter;
|
||||
}
|
||||
|
||||
void OliveGlobal::update_project_filename(const QString &s) {
|
||||
// set filename to s
|
||||
olive::ActiveProjectFilename = s;
|
||||
// set filename to s
|
||||
olive::ActiveProjectFilename = s;
|
||||
|
||||
// update main window title to reflect new project filename
|
||||
olive::MainWindow->updateTitle();
|
||||
// update main window title to reflect new project filename
|
||||
olive::MainWindow->updateTitle();
|
||||
}
|
||||
|
||||
void OliveGlobal::check_for_autorecovery_file() {
|
||||
QString data_dir = get_data_path();
|
||||
if (!data_dir.isEmpty()) {
|
||||
// detect auto-recovery file
|
||||
autorecovery_filename = data_dir + "/autorecovery.ove";
|
||||
if (QFile::exists(autorecovery_filename)) {
|
||||
if (QMessageBox::question(nullptr, tr("Auto-recovery"), tr("Olive didn't close properly and an autorecovery file was detected. Would you like to open it?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
||||
enable_load_project_on_init = false;
|
||||
open_project_worker(autorecovery_filename, true);
|
||||
}
|
||||
}
|
||||
autorecovery_timer.setInterval(60000);
|
||||
QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(save_autorecovery_file()));
|
||||
autorecovery_timer.start();
|
||||
QString data_dir = get_data_path();
|
||||
if (!data_dir.isEmpty()) {
|
||||
// detect auto-recovery file
|
||||
autorecovery_filename = data_dir + "/autorecovery.ove";
|
||||
if (QFile::exists(autorecovery_filename)) {
|
||||
if (QMessageBox::question(nullptr, tr("Auto-recovery"), tr("Olive didn't close properly and an autorecovery file was detected. Would you like to open it?"), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
||||
enable_load_project_on_init = false;
|
||||
open_project_worker(autorecovery_filename, true);
|
||||
}
|
||||
}
|
||||
autorecovery_timer.setInterval(60000);
|
||||
QObject::connect(&autorecovery_timer, SIGNAL(timeout()), this, SLOT(save_autorecovery_file()));
|
||||
autorecovery_timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::set_rendering_state(bool rendering) {
|
||||
audio_rendering = rendering;
|
||||
if (rendering) {
|
||||
autorecovery_timer.stop();
|
||||
} else {
|
||||
autorecovery_timer.start();
|
||||
}
|
||||
audio_rendering = rendering;
|
||||
if (rendering) {
|
||||
autorecovery_timer.stop();
|
||||
} else {
|
||||
autorecovery_timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::load_project_on_launch(const QString& s) {
|
||||
olive::ActiveProjectFilename = s;
|
||||
enable_load_project_on_init = true;
|
||||
olive::ActiveProjectFilename = s;
|
||||
enable_load_project_on_init = true;
|
||||
}
|
||||
|
||||
QString OliveGlobal::get_recent_project_list_file() {
|
||||
@@ -143,142 +143,142 @@ void OliveGlobal::load_translation_from_config() {
|
||||
}
|
||||
|
||||
void OliveGlobal::new_project() {
|
||||
if (can_close_project()) {
|
||||
// clear effects panel
|
||||
panel_effect_controls->clear_effects(true);
|
||||
if (can_close_project()) {
|
||||
// clear effects panel
|
||||
panel_effect_controls->clear_effects(true);
|
||||
|
||||
// clear project contents (footage, sequences, etc.)
|
||||
panel_project->new_project();
|
||||
// clear project contents (footage, sequences, etc.)
|
||||
panel_project->new_project();
|
||||
|
||||
// clear undo stack
|
||||
olive::UndoStack.clear();
|
||||
// clear undo stack
|
||||
olive::UndoStack.clear();
|
||||
|
||||
// empty current project filename
|
||||
update_project_filename("");
|
||||
// empty current project filename
|
||||
update_project_filename("");
|
||||
|
||||
// full update of all panels
|
||||
update_ui(false);
|
||||
}
|
||||
// full update of all panels
|
||||
update_ui(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::open_project() {
|
||||
QString fn = QFileDialog::getOpenFileName(olive::MainWindow, tr("Open Project..."), "", project_file_filter);
|
||||
if (!fn.isEmpty() && can_close_project()) {
|
||||
open_project_worker(fn, false);
|
||||
}
|
||||
QString fn = QFileDialog::getOpenFileName(olive::MainWindow, tr("Open Project..."), "", project_file_filter);
|
||||
if (!fn.isEmpty() && can_close_project()) {
|
||||
open_project_worker(fn, false);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::open_recent(int index) {
|
||||
QString recent_url = recent_projects.at(index);
|
||||
if (!QFile::exists(recent_url)) {
|
||||
if (QMessageBox::question(
|
||||
olive::MainWindow,
|
||||
tr("Missing recent project"),
|
||||
tr("The project '%1' no longer exists. Would you like to remove it from the recent projects list?").arg(recent_url),
|
||||
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
||||
recent_projects.removeAt(index);
|
||||
panel_project->save_recent_projects();
|
||||
}
|
||||
} else if (can_close_project()) {
|
||||
open_project_worker(recent_url, false);
|
||||
QString recent_url = recent_projects.at(index);
|
||||
if (!QFile::exists(recent_url)) {
|
||||
if (QMessageBox::question(
|
||||
olive::MainWindow,
|
||||
tr("Missing recent project"),
|
||||
tr("The project '%1' no longer exists. Would you like to remove it from the recent projects list?").arg(recent_url),
|
||||
QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
|
||||
recent_projects.removeAt(index);
|
||||
panel_project->save_recent_projects();
|
||||
}
|
||||
} else if (can_close_project()) {
|
||||
open_project_worker(recent_url, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool OliveGlobal::save_project_as() {
|
||||
QString fn = QFileDialog::getSaveFileName(olive::MainWindow, tr("Save Project As..."), "", project_file_filter);
|
||||
if (!fn.isEmpty()) {
|
||||
if (!fn.endsWith(".ove", Qt::CaseInsensitive)) {
|
||||
fn += ".ove";
|
||||
}
|
||||
update_project_filename(fn);
|
||||
panel_project->save_project(false);
|
||||
return true;
|
||||
QString fn = QFileDialog::getSaveFileName(olive::MainWindow, tr("Save Project As..."), "", project_file_filter);
|
||||
if (!fn.isEmpty()) {
|
||||
if (!fn.endsWith(".ove", Qt::CaseInsensitive)) {
|
||||
fn += ".ove";
|
||||
}
|
||||
return false;
|
||||
update_project_filename(fn);
|
||||
panel_project->save_project(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OliveGlobal::save_project() {
|
||||
if (olive::ActiveProjectFilename.isEmpty()) {
|
||||
return save_project_as();
|
||||
} else {
|
||||
panel_project->save_project(false);
|
||||
return true;
|
||||
}
|
||||
if (olive::ActiveProjectFilename.isEmpty()) {
|
||||
return save_project_as();
|
||||
} else {
|
||||
panel_project->save_project(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool OliveGlobal::can_close_project() {
|
||||
if (olive::MainWindow->isWindowModified()) {
|
||||
QMessageBox* m = new QMessageBox(
|
||||
QMessageBox::Question,
|
||||
tr("Unsaved Project"),
|
||||
tr("This project has changed since it was last saved. Would you like to save it before closing?"),
|
||||
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
|
||||
olive::MainWindow
|
||||
);
|
||||
m->setWindowModality(Qt::WindowModal);
|
||||
int r = m->exec();
|
||||
delete m;
|
||||
if (r == QMessageBox::Yes) {
|
||||
return save_project();
|
||||
} else if (r == QMessageBox::Cancel) {
|
||||
return false;
|
||||
}
|
||||
if (olive::MainWindow->isWindowModified()) {
|
||||
QMessageBox* m = new QMessageBox(
|
||||
QMessageBox::Question,
|
||||
tr("Unsaved Project"),
|
||||
tr("This project has changed since it was last saved. Would you like to save it before closing?"),
|
||||
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
|
||||
olive::MainWindow
|
||||
);
|
||||
m->setWindowModality(Qt::WindowModal);
|
||||
int r = m->exec();
|
||||
delete m;
|
||||
if (r == QMessageBox::Yes) {
|
||||
return save_project();
|
||||
} else if (r == QMessageBox::Cancel) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OliveGlobal::open_export_dialog() {
|
||||
if (olive::ActiveSequence == nullptr) {
|
||||
QMessageBox::information(olive::MainWindow,
|
||||
tr("No active sequence"),
|
||||
tr("Please open the sequence you wish to export."),
|
||||
QMessageBox::Ok);
|
||||
} else {
|
||||
ExportDialog e(olive::MainWindow);
|
||||
e.exec();
|
||||
}
|
||||
if (olive::ActiveSequence == nullptr) {
|
||||
QMessageBox::information(olive::MainWindow,
|
||||
tr("No active sequence"),
|
||||
tr("Please open the sequence you wish to export."),
|
||||
QMessageBox::Ok);
|
||||
} else {
|
||||
ExportDialog e(olive::MainWindow);
|
||||
e.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::finished_initialize() {
|
||||
if (enable_load_project_on_init) {
|
||||
|
||||
// if a project was set as a command line argument, we load it here
|
||||
if (QFileInfo::exists(olive::ActiveProjectFilename)) {
|
||||
open_project_worker(olive::ActiveProjectFilename, false);
|
||||
} else {
|
||||
QMessageBox::critical(olive::MainWindow,
|
||||
tr("Missing Project File"),
|
||||
tr("Specified project '%1' does not exist.").arg(olive::ActiveProjectFilename),
|
||||
QMessageBox::Ok);
|
||||
update_project_filename(nullptr);
|
||||
}
|
||||
|
||||
enable_load_project_on_init = false;
|
||||
if (enable_load_project_on_init) {
|
||||
|
||||
// if a project was set as a command line argument, we load it here
|
||||
if (QFileInfo::exists(olive::ActiveProjectFilename)) {
|
||||
open_project_worker(olive::ActiveProjectFilename, false);
|
||||
} else {
|
||||
// if we are not loading a project on launch and are running a release build, open the demo notice dialog
|
||||
#ifndef QT_DEBUG
|
||||
DemoNotice* d = new DemoNotice(olive::MainWindow);
|
||||
connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater()));
|
||||
d->open();
|
||||
#endif
|
||||
QMessageBox::critical(olive::MainWindow,
|
||||
tr("Missing Project File"),
|
||||
tr("Specified project '%1' does not exist.").arg(olive::ActiveProjectFilename),
|
||||
QMessageBox::Ok);
|
||||
update_project_filename(nullptr);
|
||||
}
|
||||
|
||||
enable_load_project_on_init = false;
|
||||
|
||||
} else {
|
||||
// if we are not loading a project on launch and are running a release build, open the demo notice dialog
|
||||
#ifndef QT_DEBUG
|
||||
DemoNotice* d = new DemoNotice(olive::MainWindow);
|
||||
connect(d, SIGNAL(finished(int)), d, SLOT(deleteLater()));
|
||||
d->open();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::save_autorecovery_file() {
|
||||
if (olive::MainWindow->isWindowModified()) {
|
||||
panel_project->save_project(true);
|
||||
qInfo() << "Auto-recovery project saved";
|
||||
}
|
||||
if (olive::MainWindow->isWindowModified()) {
|
||||
panel_project->save_project(true);
|
||||
qInfo() << "Auto-recovery project saved";
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::open_preferences() {
|
||||
panel_sequence_viewer->pause();
|
||||
panel_footage_viewer->pause();
|
||||
panel_sequence_viewer->pause();
|
||||
panel_footage_viewer->pause();
|
||||
|
||||
PreferencesDialog pd(olive::MainWindow);
|
||||
pd.setup_kbd_shortcuts(olive::MainWindow->menuBar());
|
||||
pd.exec();
|
||||
PreferencesDialog pd(olive::MainWindow);
|
||||
pd.setup_kbd_shortcuts(olive::MainWindow->menuBar());
|
||||
pd.exec();
|
||||
}
|
||||
|
||||
void OliveGlobal::set_sequence(SequencePtr s)
|
||||
@@ -292,66 +292,66 @@ void OliveGlobal::set_sequence(SequencePtr s)
|
||||
}
|
||||
|
||||
void OliveGlobal::open_project_worker(const QString& fn, bool autorecovery) {
|
||||
update_project_filename(fn);
|
||||
panel_project->load_project(autorecovery);
|
||||
olive::UndoStack.clear();
|
||||
update_project_filename(fn);
|
||||
panel_project->load_project(autorecovery);
|
||||
olive::UndoStack.clear();
|
||||
}
|
||||
|
||||
void OliveGlobal::undo() {
|
||||
// workaround to prevent crash (and also users should never need to do this)
|
||||
if (!panel_timeline->importing) {
|
||||
olive::UndoStack.undo();
|
||||
update_ui(true);
|
||||
}
|
||||
// workaround to prevent crash (and also users should never need to do this)
|
||||
if (!panel_timeline->importing) {
|
||||
olive::UndoStack.undo();
|
||||
update_ui(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::redo() {
|
||||
// workaround to prevent crash (and also users should never need to do this)
|
||||
if (!panel_timeline->importing) {
|
||||
olive::UndoStack.redo();
|
||||
update_ui(true);
|
||||
}
|
||||
// workaround to prevent crash (and also users should never need to do this)
|
||||
if (!panel_timeline->importing) {
|
||||
olive::UndoStack.redo();
|
||||
update_ui(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::paste() {
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
panel_timeline->paste(false);
|
||||
}
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
panel_timeline->paste(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::paste_insert() {
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
panel_timeline->paste(true);
|
||||
}
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
panel_timeline->paste(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::open_about_dialog() {
|
||||
AboutDialog a(olive::MainWindow);
|
||||
a.exec();
|
||||
AboutDialog a(olive::MainWindow);
|
||||
a.exec();
|
||||
}
|
||||
|
||||
void OliveGlobal::open_debug_log() {
|
||||
olive::DebugDialog->show();
|
||||
olive::DebugDialog->show();
|
||||
}
|
||||
|
||||
void OliveGlobal::open_speed_dialog() {
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
SpeedDialog s(olive::MainWindow);
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
ClipPtr c = olive::ActiveSequence->clips.at(i);
|
||||
if (c != nullptr && is_clip_selected(c, true)) {
|
||||
s.clips.append(c);
|
||||
}
|
||||
}
|
||||
if (s.clips.size() > 0) s.run();
|
||||
if (olive::ActiveSequence != nullptr) {
|
||||
SpeedDialog s(olive::MainWindow);
|
||||
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
|
||||
ClipPtr c = olive::ActiveSequence->clips.at(i);
|
||||
if (c != nullptr && is_clip_selected(c, true)) {
|
||||
s.clips.append(c);
|
||||
}
|
||||
}
|
||||
if (s.clips.size() > 0) s.run();
|
||||
}
|
||||
}
|
||||
|
||||
void OliveGlobal::clear_undo_stack() {
|
||||
olive::UndoStack.clear();
|
||||
olive::UndoStack.clear();
|
||||
}
|
||||
|
||||
void OliveGlobal::open_action_search() {
|
||||
ActionSearch as(olive::MainWindow);
|
||||
as.exec();
|
||||
ActionSearch as(olive::MainWindow);
|
||||
as.exec();
|
||||
}
|
||||
|
||||
+9
-1
@@ -33,7 +33,7 @@
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
#include <QPushButton>
|
||||
#include <QMenuBar>
|
||||
#include <QStyleFactory>
|
||||
|
||||
MenuHelper olive::MenuHelper;
|
||||
|
||||
@@ -266,6 +266,10 @@ QMenu* MenuHelper::create_submenu(QMenuBar* parent,
|
||||
const QObject *receiver,
|
||||
const char *member) {
|
||||
QMenu* menu = new QMenu(parent);
|
||||
menu->setStyle(QStyleFactory::create("windowsvista"));
|
||||
menu->setPalette(menu->style()->standardPalette());
|
||||
menu->setStyleSheet("");
|
||||
|
||||
parent->addMenu(menu);
|
||||
|
||||
if (receiver != nullptr) {
|
||||
@@ -277,6 +281,10 @@ QMenu* MenuHelper::create_submenu(QMenuBar* parent,
|
||||
|
||||
QMenu* MenuHelper::create_submenu(QMenu* parent) {
|
||||
QMenu* menu = new QMenu(parent);
|
||||
menu->setStyle(QStyleFactory::create("windowsvista"));
|
||||
menu->setPalette(menu->style()->standardPalette());
|
||||
menu->setStyleSheet("");
|
||||
|
||||
parent->addMenu(menu);
|
||||
return menu;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user