pcsx2/pcsx2-qt/QtProgressCallback.cpp

248 lines
6.2 KiB
C++

/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 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 PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "common/Assertions.h"
#include "QtProgressCallback.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtWidgets/QMessageBox>
#include <array>
QtModalProgressCallback::QtModalProgressCallback(QWidget* parent_widget, float show_delay)
: QObject(parent_widget)
, m_dialog(QString(), QString(), 0, 1, parent_widget)
, m_show_delay(show_delay)
{
m_dialog.setWindowTitle(tr("PCSX2"));
m_dialog.setMinimumSize(QSize(500, 0));
m_dialog.setModal(parent_widget != nullptr);
m_dialog.setAutoClose(false);
m_dialog.setAutoReset(false);
checkForDelayedShow();
}
QtModalProgressCallback::~QtModalProgressCallback() = default;
bool QtModalProgressCallback::IsCancelled() const
{
return m_dialog.wasCanceled();
}
void QtModalProgressCallback::SetCancellable(bool cancellable)
{
if (m_cancellable == cancellable)
return;
BaseProgressCallback::SetCancellable(cancellable);
m_dialog.setCancelButtonText(cancellable ? tr("Cancel") : QString());
}
void QtModalProgressCallback::SetTitle(const char* title)
{
m_dialog.setWindowTitle(QString::fromUtf8(title));
}
void QtModalProgressCallback::SetStatusText(const char* text)
{
BaseProgressCallback::SetStatusText(text);
checkForDelayedShow();
if (m_dialog.isVisible())
m_dialog.setLabelText(QString::fromUtf8(text));
}
void QtModalProgressCallback::SetProgressRange(u32 range)
{
BaseProgressCallback::SetProgressRange(range);
checkForDelayedShow();
if (m_dialog.isVisible())
m_dialog.setRange(0, m_progress_range);
}
void QtModalProgressCallback::SetProgressValue(u32 value)
{
BaseProgressCallback::SetProgressValue(value);
checkForDelayedShow();
if (m_dialog.isVisible() && static_cast<u32>(m_dialog.value()) != m_progress_range)
m_dialog.setValue(m_progress_value);
QCoreApplication::processEvents();
}
void QtModalProgressCallback::DisplayError(const char* message)
{
qWarning() << message;
}
void QtModalProgressCallback::DisplayWarning(const char* message)
{
qWarning() << message;
}
void QtModalProgressCallback::DisplayInformation(const char* message)
{
qWarning() << message;
}
void QtModalProgressCallback::DisplayDebugMessage(const char* message)
{
qWarning() << message;
}
void QtModalProgressCallback::ModalError(const char* message)
{
QMessageBox::critical(&m_dialog, tr("Error"), QString::fromUtf8(message));
}
bool QtModalProgressCallback::ModalConfirmation(const char* message)
{
return (QMessageBox::question(&m_dialog, tr("Question"), QString::fromUtf8(message), QMessageBox::Yes,
QMessageBox::No) == QMessageBox::Yes);
}
void QtModalProgressCallback::ModalInformation(const char* message)
{
QMessageBox::information(&m_dialog, tr("Information"), QString::fromUtf8(message));
}
void QtModalProgressCallback::checkForDelayedShow()
{
if (m_dialog.isVisible())
return;
if (m_show_timer.GetTimeSeconds() >= m_show_delay)
{
m_dialog.setRange(0, m_progress_range);
m_dialog.setValue(m_progress_value);
m_dialog.show();
}
}
QtAsyncProgressThread::QtAsyncProgressThread(QWidget* parent)
: QThread()
{
// NOTE: We deliberately don't set the thread parent, because otherwise we can't move it.
}
QtAsyncProgressThread::~QtAsyncProgressThread() = default;
bool QtAsyncProgressThread::IsCancelled() const
{
return isInterruptionRequested();
}
void QtAsyncProgressThread::SetCancellable(bool cancellable)
{
if (m_cancellable == cancellable)
return;
BaseProgressCallback::SetCancellable(cancellable);
}
void QtAsyncProgressThread::SetTitle(const char* title)
{
emit titleUpdated(QString::fromUtf8(title));
}
void QtAsyncProgressThread::SetStatusText(const char* text)
{
BaseProgressCallback::SetStatusText(text);
emit statusUpdated(QString::fromUtf8(text));
}
void QtAsyncProgressThread::SetProgressRange(u32 range)
{
BaseProgressCallback::SetProgressRange(range);
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
}
void QtAsyncProgressThread::SetProgressValue(u32 value)
{
BaseProgressCallback::SetProgressValue(value);
emit progressUpdated(static_cast<int>(m_progress_value), static_cast<int>(m_progress_range));
}
void QtAsyncProgressThread::DisplayError(const char* message)
{
qWarning() << message;
}
void QtAsyncProgressThread::DisplayWarning(const char* message)
{
qWarning() << message;
}
void QtAsyncProgressThread::DisplayInformation(const char* message)
{
qWarning() << message;
}
void QtAsyncProgressThread::DisplayDebugMessage(const char* message)
{
qWarning() << message;
}
void QtAsyncProgressThread::ModalError(const char* message)
{
QMessageBox::critical(parentWidget(), tr("Error"), QString::fromUtf8(message));
}
bool QtAsyncProgressThread::ModalConfirmation(const char* message)
{
return (QMessageBox::question(parentWidget(), tr("Question"), QString::fromUtf8(message), QMessageBox::Yes,
QMessageBox::No) == QMessageBox::Yes);
}
void QtAsyncProgressThread::ModalInformation(const char* message)
{
QMessageBox::information(parentWidget(), tr("Information"), QString::fromUtf8(message));
}
void QtAsyncProgressThread::start()
{
pxAssertRel(!isRunning(), "Async progress thread is not already running");
QThread::start();
moveToThread(this);
m_starting_thread = QThread::currentThread();
m_start_semaphore.release();
}
void QtAsyncProgressThread::join()
{
if (isRunning())
QThread::wait();
}
void QtAsyncProgressThread::run()
{
m_start_semaphore.acquire();
emit threadStarting();
runAsync();
emit threadFinished();
moveToThread(m_starting_thread);
}
QWidget* QtAsyncProgressThread::parentWidget() const
{
return qobject_cast<QWidget*>(parent());
}