duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

qtprogresscallback.cpp (5346B)


      1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #include "qtprogresscallback.h"
      5 #include "qtutils.h"
      6 
      7 #include "common/assert.h"
      8 
      9 #include <QtCore/QCoreApplication>
     10 #include <QtCore/QDebug>
     11 #include <QtWidgets/QMessageBox>
     12 #include <array>
     13 
     14 QtModalProgressCallback::QtModalProgressCallback(QWidget* parent_widget, float show_delay)
     15   : QObject(parent_widget), m_dialog(QString(), QString(), 0, 1, parent_widget), m_show_delay(show_delay)
     16 {
     17   m_dialog.setWindowTitle(tr("DuckStation"));
     18   m_dialog.setMinimumSize(QSize(500, 0));
     19   m_dialog.setModal(parent_widget != nullptr);
     20   m_dialog.setAutoClose(false);
     21   m_dialog.setAutoReset(false);
     22   connect(&m_dialog, &QProgressDialog::canceled, this, &QtModalProgressCallback::dialogCancelled);
     23   checkForDelayedShow();
     24 }
     25 
     26 QtModalProgressCallback::~QtModalProgressCallback() = default;
     27 
     28 void QtModalProgressCallback::SetCancellable(bool cancellable)
     29 {
     30   if (m_cancellable == cancellable)
     31     return;
     32 
     33   ProgressCallback::SetCancellable(cancellable);
     34   m_dialog.setCancelButtonText(cancellable ? tr("Cancel") : QString());
     35 }
     36 
     37 void QtModalProgressCallback::SetTitle(const std::string_view title)
     38 {
     39   m_dialog.setWindowTitle(QtUtils::StringViewToQString(title));
     40 }
     41 
     42 void QtModalProgressCallback::SetStatusText(const std::string_view text)
     43 {
     44   ProgressCallback::SetStatusText(text);
     45   checkForDelayedShow();
     46 
     47   if (m_dialog.isVisible())
     48     m_dialog.setLabelText(QtUtils::StringViewToQString(text));
     49 }
     50 
     51 void QtModalProgressCallback::SetProgressRange(u32 range)
     52 {
     53   ProgressCallback::SetProgressRange(range);
     54   checkForDelayedShow();
     55 
     56   if (m_dialog.isVisible())
     57     m_dialog.setRange(0, m_progress_range);
     58 }
     59 
     60 void QtModalProgressCallback::SetProgressValue(u32 value)
     61 {
     62   ProgressCallback::SetProgressValue(value);
     63   checkForDelayedShow();
     64 
     65   if (m_dialog.isVisible() && static_cast<u32>(m_dialog.value()) != m_progress_range)
     66     m_dialog.setValue(m_progress_value);
     67 
     68   QCoreApplication::processEvents();
     69 }
     70 
     71 void QtModalProgressCallback::ModalError(const std::string_view message)
     72 {
     73   QMessageBox::critical(&m_dialog, tr("Error"), QtUtils::StringViewToQString(message));
     74 }
     75 
     76 bool QtModalProgressCallback::ModalConfirmation(const std::string_view message)
     77 {
     78   return (QMessageBox::question(&m_dialog, tr("Question"), QtUtils::StringViewToQString(message), QMessageBox::Yes,
     79                                 QMessageBox::No) == QMessageBox::Yes);
     80 }
     81 
     82 void QtModalProgressCallback::ModalInformation(const std::string_view message)
     83 {
     84   QMessageBox::information(&m_dialog, tr("Information"), QtUtils::StringViewToQString(message));
     85 }
     86 
     87 void QtModalProgressCallback::dialogCancelled()
     88 {
     89   m_cancelled = true;
     90 }
     91 
     92 void QtModalProgressCallback::checkForDelayedShow()
     93 {
     94   if (m_dialog.isVisible())
     95     return;
     96 
     97   if (m_show_timer.GetTimeSeconds() >= m_show_delay)
     98   {
     99     m_dialog.setRange(0, m_progress_range);
    100     m_dialog.setValue(m_progress_value);
    101     m_dialog.show();
    102   }
    103 }
    104 
    105 // NOTE: We deliberately don't set the thread parent, because otherwise we can't move it.
    106 QtAsyncProgressThread::QtAsyncProgressThread(QWidget* parent) : QThread()
    107 {
    108 }
    109 
    110 QtAsyncProgressThread::~QtAsyncProgressThread() = default;
    111 
    112 bool QtAsyncProgressThread::IsCancelled() const
    113 {
    114   return isInterruptionRequested();
    115 }
    116 
    117 void QtAsyncProgressThread::SetCancellable(bool cancellable)
    118 {
    119   if (m_cancellable == cancellable)
    120     return;
    121 
    122   ProgressCallback::SetCancellable(cancellable);
    123 }
    124 
    125 void QtAsyncProgressThread::SetTitle(const std::string_view title)
    126 {
    127   emit titleUpdated(QtUtils::StringViewToQString(title));
    128 }
    129 
    130 void QtAsyncProgressThread::SetStatusText(const std::string_view text)
    131 {
    132   ProgressCallback::SetStatusText(text);
    133   emit statusUpdated(QtUtils::StringViewToQString(text));
    134 }
    135 
    136 void QtAsyncProgressThread::SetProgressRange(u32 range)
    137 {
    138   ProgressCallback::SetProgressRange(range);
    139   emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
    140 }
    141 
    142 void QtAsyncProgressThread::SetProgressValue(u32 value)
    143 {
    144   ProgressCallback::SetProgressValue(value);
    145   emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
    146 }
    147 
    148 void QtAsyncProgressThread::ModalError(const std::string_view message)
    149 {
    150   QMessageBox::critical(parentWidget(), tr("Error"), QtUtils::StringViewToQString(message));
    151 }
    152 
    153 bool QtAsyncProgressThread::ModalConfirmation(const std::string_view message)
    154 {
    155   return (QMessageBox::question(parentWidget(), tr("Question"), QtUtils::StringViewToQString(message), QMessageBox::Yes,
    156                                 QMessageBox::No) == QMessageBox::Yes);
    157 }
    158 
    159 void QtAsyncProgressThread::ModalInformation(const std::string_view message)
    160 {
    161   QMessageBox::information(parentWidget(), tr("Information"), QtUtils::StringViewToQString(message));
    162 }
    163 
    164 void QtAsyncProgressThread::start()
    165 {
    166   Assert(!isRunning());
    167 
    168   QThread::start();
    169   moveToThread(this);
    170   m_starting_thread = QThread::currentThread();
    171   m_start_semaphore.release();
    172 }
    173 
    174 void QtAsyncProgressThread::join()
    175 {
    176   if (isRunning())
    177     QThread::wait();
    178 }
    179 
    180 void QtAsyncProgressThread::run()
    181 {
    182   m_start_semaphore.acquire();
    183   emit threadStarting();
    184   runAsync();
    185   emit threadFinished();
    186   moveToThread(m_starting_thread);
    187 }
    188 
    189 QWidget* QtAsyncProgressThread::parentWidget() const
    190 {
    191   return qobject_cast<QWidget*>(parent());
    192 }