diff --git a/app/dialog/task/CMakeLists.txt b/app/dialog/task/CMakeLists.txt new file mode 100644 index 000000000..df35aad3a --- /dev/null +++ b/app/dialog/task/CMakeLists.txt @@ -0,0 +1,22 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 Olive Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + dialog/task/task.h + dialog/task/task.cpp + PARENT_SCOPE +) diff --git a/app/dialog/task/task.cpp b/app/dialog/task/task.cpp new file mode 100644 index 000000000..88ded60bc --- /dev/null +++ b/app/dialog/task/task.cpp @@ -0,0 +1,67 @@ +#include "task.h" + +#include +#include + +TaskDialog::TaskDialog(Task* task, const QString& title, QWidget *parent) : + ProgressDialog(task->GetTitle(), title, parent), + task_(task), + task_failed_(false) +{ + thread_ = new QThread(); + + // 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 save is already finished) + connect(this, &TaskDialog::Cancelled, this, &TaskDialog::reject, Qt::DirectConnection); + + // Connect cleanup functions (ensure everything new'd in this function is deleteLater'd) + connect(task_, &Task::Finished, this, &TaskDialog::accept, Qt::QueuedConnection); + connect(task_, &Task::Finished, this, &TaskDialog::deleteLater, Qt::QueuedConnection); + connect(task_, &Task::Finished, task_, &Task::deleteLater, Qt::QueuedConnection); + connect(task_, &Task::Finished, thread_, &QThread::quit, Qt::QueuedConnection); + connect(task_, &Task::Finished, thread_, &QThread::deleteLater, Qt::QueuedConnection); +} + +void TaskDialog::open() +{ + ProgressDialog::open(); + + if (thread_->isRunning()) { + // Task has already started, no need to do anymore + return; + } + + // Create a separate thread to run this task in + thread_->start(QThread::LowPriority); + + // Move the task to this thread + task_->moveToThread(thread_); + + // Start the task + QMetaObject::invokeMethod(task_, "Start", Qt::QueuedConnection); +} + +void TaskDialog::accept() +{ + if (task_failed_) { + QMessageBox::critical(this, + tr("Task Error"), + task_error_, + QMessageBox::Ok); + } + + ProgressDialog::accept(); +} + +void TaskDialog::reject() +{ + task_->Cancel(); +} + +void TaskDialog::TaskFailed(const QString &s) +{ + task_failed_ = true; + task_error_ = s; +} diff --git a/app/dialog/task/task.h b/app/dialog/task/task.h new file mode 100644 index 000000000..a2d339c2c --- /dev/null +++ b/app/dialog/task/task.h @@ -0,0 +1,31 @@ +#ifndef TASKDIALOG_H +#define TASKDIALOG_H + +#include "dialog/progress/progress.h" +#include "task/task.h" + +class TaskDialog : public ProgressDialog +{ +public: + TaskDialog(Task *task, const QString &title, QWidget* parent = nullptr); + +public slots: + virtual void open() override; + + virtual void accept() override; + virtual void reject() override; + +private: + Task* task_; + + QThread* thread_; + + bool task_failed_; + QString task_error_; + +private slots: + void TaskFailed(const QString& s); + +}; + +#endif // TASKDIALOG_H