|
|
@@ -0,0 +1,108 @@ |
|
|
#pragma once |
|
|
|
|
|
#include <chrono> |
|
|
#include <utility> |
|
|
|
|
|
#include <QObject> |
|
|
#include <QProgressDialog> |
|
|
#include <QString> |
|
|
|
|
|
#include "Common/Flag.h" |
|
|
|
|
|
class ParallelProgressDialog final : public QObject |
|
|
{ |
|
|
Q_OBJECT |
|
|
|
|
|
public: |
|
|
// Only use this from the main thread |
|
|
template <typename... Args> |
|
|
ParallelProgressDialog(Args&&... args) : m_dialog{std::forward<Args>(args)...} |
|
|
{ |
|
|
setParent(m_dialog.parent()); |
|
|
m_dialog.setWindowFlags(m_dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); |
|
|
ConnectSignalsAndSlots(); |
|
|
} |
|
|
|
|
|
// Only use this from the main thread |
|
|
QProgressDialog* GetRaw() { return &m_dialog; } |
|
|
|
|
|
// All of the following can be called from any thread |
|
|
void Cancel() { emit CancelSignal(); } |
|
|
void Reset() { emit ResetSignal(); } |
|
|
void SetCancelButtonText(const QString& text) { emit SetCancelButtonText(text); } |
|
|
void SetLabelText(const QString& text) { emit SetLabelTextSignal(text); } |
|
|
void SetMaximum(int maximum) { emit SetMaximumSignal(maximum); } |
|
|
void SetMinimum(int minimum) { emit SetMinimumSignal(minimum); } |
|
|
void SetMinimumDuration(int ms) { emit SetMinimumDurationSignal(ms); } |
|
|
void SetRange(int minimum, int maximum) { emit SetRangeSignal(minimum, maximum); } |
|
|
|
|
|
// Can be called from any thread, but only from one thread at a time |
|
|
void SetValue(int progress) |
|
|
{ |
|
|
// HACK: To avoid the https://bugreports.qt.io/browse/QTBUG-10561 stack overflow, |
|
|
// limit how often QProgressDialog::setValue can run |
|
|
const auto current_time = std::chrono::steady_clock::now(); |
|
|
if (current_time - m_last_setvalue_time >= std::chrono::milliseconds(50)) |
|
|
{ |
|
|
m_last_setvalue_time = current_time; |
|
|
emit SetValueSignal(progress); |
|
|
} |
|
|
} |
|
|
|
|
|
// Can be called from any thread |
|
|
bool WasCanceled() { return m_was_cancelled.IsSet(); } |
|
|
|
|
|
signals: |
|
|
void CancelSignal(); |
|
|
void ResetSignal(); |
|
|
void SetCancelButtonTextSignal(const QString& cancel_button_text); |
|
|
void SetLabelTextSignal(const QString& text); |
|
|
void SetMaximumSignal(int maximum); |
|
|
void SetMinimumSignal(int minimum); |
|
|
void SetMinimumDurationSignal(int ms); |
|
|
void SetRangeSignal(int minimum, int maximum); |
|
|
void SetValueSignal(int progress); |
|
|
|
|
|
void Canceled(); |
|
|
void Finished(int result); |
|
|
|
|
|
private slots: |
|
|
void OnCancelled() { m_was_cancelled.Set(); } |
|
|
|
|
|
private: |
|
|
template <typename Func1, typename Func2> |
|
|
void ConnectSignal(Func1 signal, Func2 slot) |
|
|
{ |
|
|
QObject::connect(this, signal, &m_dialog, slot); |
|
|
} |
|
|
|
|
|
template <typename Func1, typename Func2> |
|
|
void ConnectSlot(Func1 signal, Func2 slot) |
|
|
{ |
|
|
QObject::connect(&m_dialog, signal, this, slot); |
|
|
} |
|
|
|
|
|
void ConnectSignalsAndSlots() |
|
|
{ |
|
|
ConnectSignal(&ParallelProgressDialog::CancelSignal, &QProgressDialog::cancel); |
|
|
ConnectSignal(&ParallelProgressDialog::ResetSignal, &QProgressDialog::reset); |
|
|
ConnectSignal(&ParallelProgressDialog::SetCancelButtonTextSignal, |
|
|
&QProgressDialog::setCancelButtonText); |
|
|
ConnectSignal(&ParallelProgressDialog::SetLabelTextSignal, &QProgressDialog::setLabelText); |
|
|
ConnectSignal(&ParallelProgressDialog::SetMaximumSignal, &QProgressDialog::setMaximum); |
|
|
ConnectSignal(&ParallelProgressDialog::SetMinimumSignal, &QProgressDialog::setMinimum); |
|
|
ConnectSignal(&ParallelProgressDialog::SetMinimumDurationSignal, |
|
|
&QProgressDialog::setMinimumDuration); |
|
|
ConnectSignal(&ParallelProgressDialog::SetRangeSignal, &QProgressDialog::setRange); |
|
|
ConnectSignal(&ParallelProgressDialog::SetValueSignal, &QProgressDialog::setValue); |
|
|
|
|
|
ConnectSlot(&QProgressDialog::canceled, &ParallelProgressDialog::OnCancelled); |
|
|
|
|
|
ConnectSlot(&QProgressDialog::canceled, &ParallelProgressDialog::Canceled); |
|
|
ConnectSlot(&QProgressDialog::finished, &ParallelProgressDialog::Finished); |
|
|
} |
|
|
|
|
|
QProgressDialog m_dialog; |
|
|
Common::Flag m_was_cancelled; |
|
|
std::chrono::time_point<std::chrono::steady_clock> m_last_setvalue_time; |
|
|
}; |