TaskDialog::closeEvent() was calling deleteLater() immediately when the user closed the window. The ExportTask was a child QObject of the dialog, so it got destroyed while its Run() method was still executing in the worker thread, leading to a use-after-free on encoder_->Close(). Defer deletion until the QFutureWatcher reports that the task has actually finished. A new task_finished_ flag tracks this so closeEvent only deletes when it is safe, and TaskFinished() closes the dialog (which now deletes instead of calling close() again while the task is still alive).
87 lines
1.9 KiB
C++
87 lines
1.9 KiB
C++
/***
|
|
|
|
Olive - Non-Linear Video Editor
|
|
Copyright (C) 2022 Olive Team
|
|
Modifications Copyright (C) 2025 mikesolar
|
|
|
|
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 <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
#ifndef TASKDIALOG_H
|
|
#define TASKDIALOG_H
|
|
|
|
#include "dialog/progress/progress.h"
|
|
#include "task/task.h"
|
|
|
|
namespace olive
|
|
{
|
|
|
|
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);
|
|
|
|
/**
|
|
* @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;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns this dialog's task
|
|
*/
|
|
Task *GetTask() const
|
|
{
|
|
return task_;
|
|
}
|
|
|
|
protected:
|
|
virtual void showEvent(QShowEvent *e) override;
|
|
|
|
virtual void closeEvent(QCloseEvent *e) override;
|
|
|
|
signals:
|
|
void TaskSucceeded(Task *task);
|
|
|
|
void TaskFailed(Task *task);
|
|
|
|
private:
|
|
Task *task_;
|
|
|
|
bool destroy_on_close_;
|
|
|
|
bool already_shown_;
|
|
|
|
bool task_finished_;
|
|
|
|
private slots:
|
|
void TaskFinished();
|
|
};
|
|
|
|
}
|
|
|
|
#endif // TASKDIALOG_H
|