moved load project functions from project panel to global

This commit is contained in:
itsmattkc
2019-03-21 20:54:27 +11:00
parent 1da4a315f8
commit 3e74d3dccb
12 changed files with 318 additions and 80 deletions
+1 -1
View File
@@ -33,7 +33,7 @@ extern "C" {
}
AdvancedVideoDialog::AdvancedVideoDialog(QWidget *parent,
int encoding_codec,
AVCodecID encoding_codec,
VideoCodecParams &iparams) :
QDialog(parent),
params_(iparams)
+19 -1
View File
@@ -36,11 +36,29 @@
class AdvancedVideoDialog : public QDialog {
Q_OBJECT
public:
/**
* @brief AdvancedVideoDialog Constructor
*
* @param parent
*
* QWidget parent. Usually ExportDialog.
*
* @param encoding_codec
*
* The AVCodecID of the selected export codec.
*
* @param iparams
*
* A VideoCodecParams struct containing the extra codec data.
*/
AdvancedVideoDialog(QWidget* parent,
int encoding_codec,
AVCodecID encoding_codec,
VideoCodecParams& iparams);
public slots:
/**
* @brief Overrided accept for saving the UI data into the provided VideoCodecParams struct.
*/
virtual void accept() override;
private:
/**
+11 -11
View File
@@ -330,16 +330,16 @@ void ExportDialog::format_changed(int index) {
audioGroupbox->setEnabled(audio_enabled);
}
void ExportDialog::render_thread_finished() {
void ExportDialog::export_thread_finished() {
// Determine if the export succeeded
bool succeeded = (progressBar->value() == 100);
// If it failed and we didn't cancel it, it must have errored out. Show an error message.
if (!succeeded && !et->WasInterrupted()) {
if (!succeeded && !export_thread_->WasInterrupted()) {
QMessageBox::critical(
this,
tr("Export Failed"),
tr("Export failed - %1").arg(et->GetError()),
tr("Export failed - %1").arg(export_thread_->GetError()),
QMessageBox::Ok
);
}
@@ -358,10 +358,10 @@ void ExportDialog::render_thread_finished() {
update_ui(false);
// Disconnect cancel button from export thread
disconnect(renderCancel, SIGNAL(clicked(bool)), et, SLOT(Interrupt()));
disconnect(renderCancel, SIGNAL(clicked(bool)), export_thread_, SLOT(Interrupt()));
// Free the export thread
et->deleteLater();
export_thread_->deleteLater();
// If the export succeeded, close the dialog
if (succeeded) {
@@ -562,12 +562,12 @@ void ExportDialog::StartExport() {
}
// Create export thread
et = new ExportThread(params, vcodec_params, this);
export_thread_ = new ExportThread(params, vcodec_params, this);
// Connect export thread signals/slots
connect(et, SIGNAL(finished()), this, SLOT(render_thread_finished()));
connect(et, SIGNAL(ProgressChanged(int, qint64)), this, SLOT(update_progress_bar(int, qint64)));
connect(renderCancel, SIGNAL(clicked(bool)), et, SLOT(Interrupt()));
connect(export_thread_, SIGNAL(finished()), this, SLOT(export_thread_finished()));
connect(export_thread_, SIGNAL(ProgressChanged(int, qint64)), this, SLOT(update_progress_bar(int, qint64)));
connect(renderCancel, SIGNAL(clicked(bool)), export_thread_, SLOT(Interrupt()));
// Close all currently open clips
close_active_clips(olive::ActiveSequence.get());
@@ -580,7 +580,7 @@ void ExportDialog::StartExport() {
total_export_time_start = QDateTime::currentMSecsSinceEpoch();
et->start();
export_thread_->start();
}
}
@@ -667,7 +667,7 @@ void ExportDialog::comp_type_changed(int) {
}
void ExportDialog::open_advanced_video_dialog() {
AdvancedVideoDialog avd(this, vcodecCombobox->currentData().toInt(), vcodec_params);
AdvancedVideoDialog avd(this, static_cast<AVCodecID>(vcodecCombobox->currentData().toInt()), vcodec_params);
avd.exec();
}
+167 -4
View File
@@ -68,42 +68,205 @@ private slots:
* Asks the user for the file to save to.
*/
void StartExport();
/**
* @brief Slot for the export thread to update the progress bar's value
*
* @param value
*
* An value between 0 - 100. A percentage of the Sequence that has been exported so far.
*
* @param remaining_ms
*
* The estimated time in milliseconds that it will take to complete the rest of the Sequence.
*/
void update_progress_bar(int value, qint64 remaining_ms);
void render_thread_finished();
/**
* @brief Slot for the export thread completing (both succeeding and failing)
*
* Runs whenever the thread has finished. Determines whether the thread succeeded or not (and shows an error message
* if not), cleans up the ExportThread object, sets the UI state back to normal.
*
* Connect to ExportThread::finished().
*/
void export_thread_finished();
/**
* @brief Slot for when the video codec changes
*
* Some video codecs require different settings. In the case of that, this function sorts through those.
*
* @param index
*
* Current vcodecCombobox index - its item data contains the AVCodecID.
*/
void vcodec_changed(int index);
/**
* @brief Slot for when the compression type changes
*
* Different UI objects should be displayed for different compression types.
*
* @param index
*
* Unused.
*/
void comp_type_changed(int index);
/**
* @brief Slot to open the Advanced Video Dialog
*
* Opens a dialog for setting more advanced video settings and passes a reference to vcodec_params to it.
*/
void open_advanced_video_dialog();
private:
/**
* @brief Function to create UI objects.
*/
void setup_ui();
/**
* @brief Enables/disables certain UI objects based on the exporting state.
*
* Some UI controls don't need to be set while exporting. This function enables/disables them appropriately.
*
* @param r
*
* TRUE if we're exporting, FALSE if we finished.
*/
void prep_ui_for_render(bool r);
QVector<QString> format_strings;
ExportThread* et;
/**
* @brief Retrieves the human-readable name of an AVCodecID and adds it to a QComboBox
*
* Also sets that item's data to the AVCodecID so it can be retrieved directly from the QComboBox.
*
* @param box
*
* The QComboBox to add the item to.
*
* @param codec
*
* The codec to add to the QComboBox.
*/
void add_codec_to_combobox(QComboBox* box, enum AVCodecID codec);
/**
* @brief Internal array of human-readable names corresponding to enum ExportFormats
*/
QVector<QString> format_strings;
/**
* @brief Pointer to an ExportThread
*
* Set when exporting starts, and deleted by export_thread_finished() when the thread is complete.
*/
ExportThread* export_thread_;
/**
* @brief Struct for advanced video codec parameters.
*
* More advanced video encoding parameters to be sent to the ExportThread. These variables are not directly editable
* in this dialog, instead calling open_advanced_video_dialog() will open an AdvancedVideoDialog for setting these
* values directly. vcodec_changed() should also set these to the defaults for that codec where appropriate.
*/
VideoCodecParams vcodec_params;
/**
* @brief ComboBox for selecting the time range of the Sequence to export
*/
QComboBox* rangeCombobox;
/**
* @brief SpinBox for the exported video's width
*/
QSpinBox* widthSpinbox;
/**
* @brief SpinBox for the exported video's bitrate
*/
QDoubleSpinBox* videobitrateSpinbox;
/**
* @brief Label for the exported video's bitrate - changes depending on the compression type
*/
QLabel* videoBitrateLabel;
/**
* @brief SpinBox for the exported video's frame rate
*/
QDoubleSpinBox* framerateSpinbox;
/**
* @brief ComboBox for the exported video codec
*/
QComboBox* vcodecCombobox;
/**
* @brief ComboBox for the exported audio's codec
*/
QComboBox* acodecCombobox;
/**
* @brief SpinBox for the exported audio's sample rate
*/
QSpinBox* samplingRateSpinbox;
/**
* @brief SpinBox for the exported audio's bitrate
*/
QSpinBox* audiobitrateSpinbox;
/**
* @brief Progress bar for visually showing the export progress
*/
QProgressBar* progressBar;
/**
* @brief ComboBox for the exported video's format
*/
QComboBox* formatCombobox;
/**
* @brief SpinBox for the exported video's height
*/
QSpinBox* heightSpinbox;
/**
* @brief Export button to trigger the start of an export
*/
QPushButton* export_button;
/**
* @brief Dialog cancel button to close this dialog
*/
QPushButton* cancel_button;
/**
* @brief Cancel button to abort the export before completion
*/
QPushButton* renderCancel;
/**
* @brief GroupBox containing all video-related UI objects
*/
QGroupBox* videoGroupbox;
/**
* @brief GroupBox containing all audio-related UI objects
*/
QGroupBox* audioGroupbox;
/**
* @brief ComboBox for the exported video compression type
*/
QComboBox* compressionTypeCombobox;
/**
* @brief Time value set when exporting begins to determine the total duration of the export
*/
qint64 total_export_time_start;
};
+5 -23
View File
@@ -31,7 +31,7 @@
#include "ui/sourcetable.h"
#include "ui/mainwindow.h"
LoadDialog::LoadDialog(QWidget *parent, const QString& fn, bool autorecovery, bool clear) :
LoadDialog::LoadDialog(QWidget *parent) :
QDialog(parent)
{
setWindowTitle(tr("Loading..."));
@@ -46,7 +46,7 @@ LoadDialog::LoadDialog(QWidget *parent, const QString& fn, bool autorecovery, bo
layout->addWidget(bar);
cancel_button = new QPushButton(tr("Cancel"), this);
connect(cancel_button, SIGNAL(clicked(bool)), this, SLOT(cancel()));
connect(cancel_button, SIGNAL(clicked(bool)), this, SIGNAL(cancel()));
hboxLayout = new QHBoxLayout();
hboxLayout->addStretch();
@@ -54,27 +54,9 @@ LoadDialog::LoadDialog(QWidget *parent, const QString& fn, bool autorecovery, bo
hboxLayout->addStretch();
layout->addLayout(hboxLayout);
update();
lt = new LoadThread(fn, autorecovery, clear);
QObject::connect(lt, SIGNAL(success()), this, SLOT(thread_done()));
QObject::connect(lt, SIGNAL(error()), this, SLOT(die()));
QObject::connect(lt, SIGNAL(report_progress(int)), bar, SLOT(setValue(int)));
lt->start();
}
void LoadDialog::cancel() {
lt->cancel();
lt->wait();
die();
}
void LoadDialog::die() {
olive::Global->new_project();
reject();
}
void LoadDialog::thread_done() {
accept();
QProgressBar *LoadDialog::progress_bar()
{
return bar;
}
+26 -4
View File
@@ -28,15 +28,37 @@
#include "project/projectelements.h"
#include "project/loadthread.h"
/**
* @brief The LoadDialog class
*
* Shows a modal dialog for loading a project and creates a LoadThread to load it.
*/
class LoadDialog : public QDialog
{
Q_OBJECT
public:
LoadDialog(QWidget* parent, const QString& filename, bool autorecovery, bool clear);
private slots:
/**
* @brief LoadDialog Constructor
*
* @param parent
*
* QWidget parent. Usually MainWindow.
*
* @param filename
*
* URL of the project file to load.
*
* @param autorecovery
*
* TRUE if this is an autorecovery project
*
* @param clear
*/
LoadDialog(QWidget* parent);
QProgressBar* progress_bar();
signals:
void cancel();
void die();
void thread_done();
private:
QProgressBar* bar;
QPushButton* cancel_button;
+44 -8
View File
@@ -38,6 +38,8 @@
#include "dialogs/aboutdialog.h"
#include "dialogs/speeddialog.h"
#include "dialogs/actionsearch.h"
#include "dialogs/loaddialog.h"
#include "project/loadthread.h"
#include "timeline/sequence.h"
#include "ui/mediaiconservice.h"
#include "ui/mainwindow.h"
@@ -91,7 +93,7 @@ void OliveGlobal::check_for_autorecovery_file() {
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);
OpenProjectWorker(autorecovery_filename, true);
}
}
autorecovery_timer.setInterval(60000);
@@ -164,6 +166,33 @@ void OliveGlobal::SetNativeStyling(QWidget *w)
#endif
}
void OliveGlobal::LoadProject(const QString &fn, bool autorecovery, bool clear)
{
// Normally, the user will be closing the previous project to load a new one, but just in case the user
// is importing a new project
if (clear) {
new_project();
}
LoadDialog ld(olive::MainWindow);
LoadThread* lt = new LoadThread(fn, autorecovery, clear);
connect(&ld, SIGNAL(cancel()), lt, SLOT(cancel()));
connect(lt, SIGNAL(success()), &ld, SLOT(accept()));
connect(lt, SIGNAL(error()), &ld, SLOT(reject()));
connect(lt, SIGNAL(error()), this, SLOT(new_project()));
connect(lt, SIGNAL(report_progress(int)), ld.progress_bar(), SLOT(setValue(int)));
lt->start();
ld.exec();
}
void OliveGlobal::ImportProject(const QString &fn)
{
LoadProject(fn, false, false);
}
void OliveGlobal::new_project() {
if (can_close_project()) {
// clear graph editor
@@ -172,8 +201,12 @@ void OliveGlobal::new_project() {
// clear effects panel
panel_effect_controls->Clear(true);
// clear existing project
olive::Global->set_sequence(nullptr);
panel_footage_viewer->set_media(nullptr);
// clear project contents (footage, sequences, etc.)
panel_project->new_project();
panel_project->clear();
// clear undo stack
olive::UndoStack.clear();
@@ -183,13 +216,16 @@ void OliveGlobal::new_project() {
// full update of all panels
update_ui(false);
// set to unmodified
olive::Global->set_modified(false);
}
}
void OliveGlobal::open_project() {
void OliveGlobal::OpenProject() {
QString fn = QFileDialog::getOpenFileName(olive::MainWindow, tr("Open Project..."), "", project_file_filter);
if (!fn.isEmpty() && can_close_project()) {
open_project_worker(fn, false);
OpenProjectWorker(fn, false);
}
}
@@ -205,7 +241,7 @@ void OliveGlobal::open_recent(int index) {
panel_project->save_recent_projects();
}
} else if (can_close_project()) {
open_project_worker(recent_url, false);
OpenProjectWorker(recent_url, false);
}
}
@@ -269,7 +305,7 @@ void OliveGlobal::finished_initialize() {
// 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);
OpenProjectWorker(olive::ActiveProjectFilename, false);
} else {
QMessageBox::critical(olive::MainWindow,
tr("Missing Project File"),
@@ -323,9 +359,9 @@ void OliveGlobal::set_sequence(SequencePtr s)
panel_timeline->setFocus();
}
void OliveGlobal::open_project_worker(const QString& fn, bool autorecovery) {
void OliveGlobal::OpenProjectWorker(const QString& fn, bool autorecovery) {
update_project_filename(fn);
panel_project->load_project(fn, autorecovery, true);
LoadProject(fn, autorecovery, true);
olive::UndoStack.clear();
}
+41 -2
View File
@@ -193,7 +193,18 @@ public slots:
* Confirms whether the current project can be closed, and if so, shows an open file dialog to allow the user to
* select a project file and then triggers a project load with it.
*/
void open_project();
void OpenProject();
/**
* @brief Import project from file
*
* Imports an Olive project into the current project, effectively merging them.
*
* @param fn
*
* The filename of the project to import.
*/
void ImportProject(const QString& fn);
/**
* @brief Open recent project from list
@@ -327,7 +338,35 @@ private:
* beside the original project file so that it does not overwrite the original and so that the user is not working
* on the autorecovery project in Olive's application data directory.
*/
void open_project_worker(const QString& fn, bool autorecovery);
void OpenProjectWorker(const QString& fn, bool autorecovery);
/**
* @brief Create a LoadDialog and start a LoadThread to load data from a project
*
* Loads data from an Olive project file creating a LoadDialog to show visual information and a LoadThread to load
* outside of the main/GUI thread.
*
* All project loading functions eventually lead to this one and there's no reason to use it directly. Instead use
* one of the following functions:
*
* * OpenProject() - to check if the current project can be closed and prompt the user for the new project file
* * OpenProjectWorker() - if you already have the filename and wish to close the current project and open it
* * ImportProject() - to import a project file into this one, effectively merging them both
*
* @param fn
*
* The URL of the project file to open
*
* @param autorecovery
*
* TRUE if this file is an autorecovery file, in which case it's loaded slightly differently
*
* @param clear
*
* TRUE if the current project should be closed before opening, FALSE if the project should be imported into the
* currently open one.
*/
void LoadProject(const QString& fn, bool autorecovery, bool clear);
/**
* @brief File filter used for any file dialogs relating to Olive project files.
+2 -23
View File
@@ -111,7 +111,7 @@ Project::Project(QWidget *parent) :
QPushButton* toolbar_open = new QPushButton();
toolbar_open->setIcon(olive::icon::CreateIconFromSVG(QStringLiteral(":/icons/open.svg")));
toolbar_open->setToolTip("Open Project");
connect(toolbar_open, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(open_project()));
connect(toolbar_open, SIGNAL(clicked(bool)), olive::Global.get(), SLOT(OpenProject()));
toolbar->addWidget(toolbar_open);
QPushButton* toolbar_save = new QPushButton();
@@ -724,7 +724,7 @@ void Project::process_file_list(QStringList& files, bool recursive, MediaPtr rep
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
// load the project without clearing the current one
load_project(file, false, false);
olive::Global->ImportProject(file);
}
@@ -1041,27 +1041,6 @@ void Project::clear() {
tree_view->update();
}
void Project::new_project() {
// clear existing project
olive::Global->set_sequence(nullptr);
panel_footage_viewer->set_media(nullptr);
clear();
olive::Global->set_modified(false);
}
void Project::load_project(const QString& filename, bool autorecovery, bool clear) {
// Normally, the user will be closing the previous project to load a new one, but just in case the user
// is importing a new project
if (clear) {
new_project();
}
LoadDialog ld(this, filename, autorecovery, clear);
ld.exec();
}
void save_marker(QXmlStreamWriter& stream, const Marker& m) {
stream.writeStartElement("marker");
stream.writeAttribute("frame", QString::number(m.frame));
-2
View File
@@ -66,8 +66,6 @@ public:
bool reveal_media(Media *media, QModelIndex parent = QModelIndex());
void add_recent_project(QString url);
void new_project();
void load_project(const QString &filename, bool autorecovery, bool clear);
void save_project(bool autorecovery);
MediaPtr create_folder_internal(QString name);
+1
View File
@@ -37,6 +37,7 @@ class LoadThread : public QThread
public:
LoadThread(const QString& filename, bool autorecovery, bool clear);
void run();
public slots:
void cancel();
signals:
void start_question(const QString &title, const QString &text, int buttons);
+1 -1
View File
@@ -453,7 +453,7 @@ void MainWindow::setup_menus() {
new_menu = MenuHelper::create_submenu(file_menu);
olive::MenuHelper.make_new_menu(new_menu);
open_project = MenuHelper::create_menu_action(file_menu, "openproj", olive::Global.get(), SLOT(open_project()), QKeySequence("Ctrl+O"));
open_project = MenuHelper::create_menu_action(file_menu, "openproj", olive::Global.get(), SLOT(OpenProject()), QKeySequence("Ctrl+O"));
open_recent = MenuHelper::create_submenu(file_menu);