| 49 | } |
| 50 | |
| 51 | void ThreadControlWidget::StartThread(const QString& progress_text, |
| 52 | const bool stoppable, |
| 53 | std::unique_ptr<Thread> thread) { |
| 54 | THROW_CHECK(!thread_); |
| 55 | THROW_CHECK_NOTNULL(thread); |
| 56 | |
| 57 | thread_ = std::move(thread); |
| 58 | |
| 59 | if (progress_bar_ == nullptr) { |
| 60 | progress_bar_ = new QProgressDialog(this); |
| 61 | progress_bar_->setWindowModality(Qt::ApplicationModal); |
| 62 | progress_bar_->setWindowFlags(Qt::Dialog | Qt::WindowTitleHint | |
| 63 | Qt::CustomizeWindowHint); |
| 64 | // Use a single space to clear the window title on Windows, otherwise it |
| 65 | // will contain the name of the executable. |
| 66 | progress_bar_->setWindowTitle(" "); |
| 67 | progress_bar_->setLabel(new QLabel(this)); |
| 68 | progress_bar_->setMaximum(0); |
| 69 | progress_bar_->setMinimum(0); |
| 70 | progress_bar_->setValue(0); |
| 71 | connect(progress_bar_, &QProgressDialog::canceled, [this]() { |
| 72 | destructor_->trigger(); |
| 73 | }); |
| 74 | } |
| 75 | |
| 76 | // Enable the cancel button if the thread is stoppable. |
| 77 | QPushButton* cancel_button = |
| 78 | progress_bar_->findChildren<QPushButton*>().at(0); |
| 79 | cancel_button->setEnabled(stoppable); |
| 80 | |
| 81 | progress_bar_->setLabelText(progress_text); |
| 82 | |
| 83 | // Center the progress bar wrt. the parent widget. |
| 84 | const QPoint global = |
| 85 | parentWidget()->mapToGlobal(parentWidget()->rect().center()); |
| 86 | progress_bar_->move(global.x() - progress_bar_->width() / 2, |
| 87 | global.y() - progress_bar_->height() / 2); |
| 88 | |
| 89 | progress_bar_->show(); |
| 90 | progress_bar_->raise(); |
| 91 | |
| 92 | thread_->AddCallback(Thread::FINISHED_CALLBACK, |
| 93 | [this]() { destructor_->trigger(); }); |
| 94 | thread_->Start(); |
| 95 | } |
| 96 | |
| 97 | void ThreadControlWidget::StartFunction(const QString& progress_text, |
| 98 | const std::function<void()>& func) { |