Qt: Add cover downloader
This commit is contained in:
parent
21b7261dc9
commit
389143db64
|
@ -48,6 +48,9 @@ set(SRCS
|
|||
controllersettingsdialog.h
|
||||
controllersettingsdialog.ui
|
||||
controllersettingwidgetbinder.h
|
||||
coverdownloaddialog.cpp
|
||||
coverdownloaddialog.h
|
||||
coverdownloaddialog.ui
|
||||
debuggermodels.cpp
|
||||
debuggermodels.h
|
||||
debuggerwindow.cpp
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
#include "coverdownloaddialog.h"
|
||||
#include "common/assert.h"
|
||||
#include "frontend-common/game_list.h"
|
||||
|
||||
CoverDownloadDialog::CoverDownloadDialog(QWidget* parent /*= nullptr*/) : QDialog(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
updateEnabled();
|
||||
|
||||
connect(m_ui.start, &QPushButton::clicked, this, &CoverDownloadDialog::onStartClicked);
|
||||
connect(m_ui.close, &QPushButton::clicked, this, &CoverDownloadDialog::onCloseClicked);
|
||||
connect(m_ui.urls, &QTextEdit::textChanged, this, &CoverDownloadDialog::updateEnabled);
|
||||
}
|
||||
|
||||
CoverDownloadDialog::~CoverDownloadDialog()
|
||||
{
|
||||
Assert(!m_thread);
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::closeEvent(QCloseEvent* ev)
|
||||
{
|
||||
cancelThread();
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::onDownloadStatus(const QString& text)
|
||||
{
|
||||
m_ui.status->setText(text);
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::onDownloadProgress(int value, int range)
|
||||
{
|
||||
// limit to once every five seconds
|
||||
if (m_last_refresh_time.GetTimeSeconds() >= 5.0f)
|
||||
{
|
||||
emit coverRefreshRequested();
|
||||
m_last_refresh_time.Reset();
|
||||
}
|
||||
|
||||
if (range != m_ui.progress->maximum())
|
||||
m_ui.progress->setMaximum(range);
|
||||
m_ui.progress->setValue(value);
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::onDownloadComplete()
|
||||
{
|
||||
emit coverRefreshRequested();
|
||||
|
||||
if (m_thread)
|
||||
{
|
||||
m_thread->join();
|
||||
m_thread.reset();
|
||||
}
|
||||
|
||||
updateEnabled();
|
||||
|
||||
m_ui.status->setText(tr("Download complete."));
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::onStartClicked()
|
||||
{
|
||||
if (m_thread)
|
||||
cancelThread();
|
||||
else
|
||||
startThread();
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::onCloseClicked()
|
||||
{
|
||||
if (m_thread)
|
||||
cancelThread();
|
||||
|
||||
done(0);
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::updateEnabled()
|
||||
{
|
||||
const bool running = static_cast<bool>(m_thread);
|
||||
m_ui.start->setText(running ? tr("Stop") : tr("Start"));
|
||||
m_ui.start->setEnabled(running || !m_ui.urls->toPlainText().isEmpty());
|
||||
m_ui.close->setEnabled(!running);
|
||||
m_ui.urls->setEnabled(!running);
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::startThread()
|
||||
{
|
||||
m_thread = std::make_unique<CoverDownloadThread>(this, m_ui.urls->toPlainText());
|
||||
connect(m_thread.get(), &CoverDownloadThread::statusUpdated, this, &CoverDownloadDialog::onDownloadStatus);
|
||||
connect(m_thread.get(), &CoverDownloadThread::progressUpdated, this, &CoverDownloadDialog::onDownloadProgress);
|
||||
connect(m_thread.get(), &CoverDownloadThread::threadFinished, this, &CoverDownloadDialog::onDownloadComplete);
|
||||
m_thread->start();
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
void CoverDownloadDialog::cancelThread()
|
||||
{
|
||||
if (!m_thread)
|
||||
return;
|
||||
|
||||
m_thread->requestInterruption();
|
||||
m_thread->join();
|
||||
m_thread.reset();
|
||||
}
|
||||
|
||||
CoverDownloadDialog::CoverDownloadThread::CoverDownloadThread(QWidget* parent, const QString& urls)
|
||||
: QtAsyncProgressThread(parent)
|
||||
{
|
||||
for (const QString& str : urls.split(QChar('\n')))
|
||||
m_urls.push_back(str.toStdString());
|
||||
}
|
||||
|
||||
CoverDownloadDialog::CoverDownloadThread::~CoverDownloadThread() = default;
|
||||
|
||||
void CoverDownloadDialog::CoverDownloadThread::runAsync()
|
||||
{
|
||||
GameList::DownloadCovers(m_urls, this);
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
#include "common/timer.h"
|
||||
#include "common/types.h"
|
||||
#include "qtprogresscallback.h"
|
||||
#include "ui_coverdownloaddialog.h"
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class CoverDownloadDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CoverDownloadDialog(QWidget* parent = nullptr);
|
||||
~CoverDownloadDialog();
|
||||
|
||||
Q_SIGNALS:
|
||||
void coverRefreshRequested();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* ev);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onDownloadStatus(const QString& text);
|
||||
void onDownloadProgress(int value, int range);
|
||||
void onDownloadComplete();
|
||||
void onStartClicked();
|
||||
void onCloseClicked();
|
||||
void updateEnabled();
|
||||
|
||||
private:
|
||||
class CoverDownloadThread : public QtAsyncProgressThread
|
||||
{
|
||||
public:
|
||||
CoverDownloadThread(QWidget* parent, const QString& urls);
|
||||
~CoverDownloadThread();
|
||||
|
||||
protected:
|
||||
void runAsync() override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_urls;
|
||||
};
|
||||
|
||||
void startThread();
|
||||
void cancelThread();
|
||||
|
||||
Ui::CoverDownloadDialog m_ui;
|
||||
std::unique_ptr<CoverDownloadThread> m_thread;
|
||||
Common::Timer m_last_refresh_time;
|
||||
};
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CoverDownloadDialog</class>
|
||||
<widget class="QDialog" name="CoverDownloadDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>656</width>
|
||||
<height>343</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Download Covers</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>DuckStation can automatically download covers for games which do not currently have a cover set. We do not host any cover images, the user must provide their own source for images.</p><p>In the form below, specify the URLs to download covers from, with one template URL per line. The following variables are available:</p><p><span style=" font-style:italic;">${title}:</span> Title of the game.<br/><span style=" font-style:italic;">${filetitle}:</span> Name component of the game's filename.<br/><span style=" font-style:italic;">${serial}:</span> Serial of the game.</p><p><span style=" font-weight:700;">Example:</span> https://www.example-not-a-real-domain.com/covers/${serial}.jpg</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="urls"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="status">
|
||||
<property name="text">
|
||||
<string>Waiting to start...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progress"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="start">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="close">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -16,6 +16,7 @@
|
|||
<ClCompile Include="controllerbindingwidgets.cpp" />
|
||||
<ClCompile Include="controllerglobalsettingswidget.cpp" />
|
||||
<ClCompile Include="controllersettingsdialog.cpp" />
|
||||
<ClCompile Include="coverdownloaddialog.cpp" />
|
||||
<ClCompile Include="emulationsettingswidget.cpp" />
|
||||
<ClCompile Include="debuggermodels.cpp" />
|
||||
<ClCompile Include="debuggerwindow.cpp" />
|
||||
|
@ -55,6 +56,7 @@
|
|||
<QtMoc Include="biossettingswidget.h" />
|
||||
<QtMoc Include="cheatmanagerdialog.h" />
|
||||
<QtMoc Include="cheatcodeeditordialog.h" />
|
||||
<QtMoc Include="coverdownloaddialog.h" />
|
||||
<QtMoc Include="enhancementsettingswidget.h" />
|
||||
<QtMoc Include="memorycardsettingswidget.h" />
|
||||
<QtMoc Include="memorycardeditordialog.h" />
|
||||
|
@ -210,6 +212,9 @@
|
|||
<QtUi Include="foldersettingswidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="coverdownloaddialog.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtResource Include="resources\resources.qrc">
|
||||
|
@ -231,6 +236,7 @@
|
|||
<ClCompile Include="$(IntDir)moc_controllerbindingwidgets.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_controllerglobalsettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_controllersettingsdialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_coverdownloaddialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_displaywidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_emulationsettingswidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_enhancementsettingswidget.cpp" />
|
||||
|
|
|
@ -220,7 +220,7 @@ void GameSummaryWidget::onComputeHashClicked()
|
|||
QtConcurrent::run([]() { return &GameDatabase::GetTrackHashesMap(); });
|
||||
#endif
|
||||
|
||||
QtProgressCallback progress_callback(this);
|
||||
QtModalProgressCallback progress_callback(this);
|
||||
progress_callback.SetProgressRange(image->GetTrackCount());
|
||||
|
||||
std::vector<CDImageHasher::Hash> track_hashes;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "core/memory_card.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/system.h"
|
||||
#include "coverdownloaddialog.h"
|
||||
#include "debuggerwindow.h"
|
||||
#include "displaywidget.h"
|
||||
#include "frontend-common/game_list.h"
|
||||
|
@ -1828,6 +1829,7 @@ void MainWindow::connectSignals()
|
|||
connect(m_ui.actionAbout, &QAction::triggered, this, &MainWindow::onAboutActionTriggered);
|
||||
connect(m_ui.actionCheckForUpdates, &QAction::triggered, this, &MainWindow::onCheckForUpdatesActionTriggered);
|
||||
connect(m_ui.actionMemory_Card_Editor, &QAction::triggered, this, &MainWindow::onToolsMemoryCardEditorTriggered);
|
||||
connect(m_ui.actionCoverDownloader, &QAction::triggered, this, &MainWindow::onToolsCoverDownloaderTriggered);
|
||||
connect(m_ui.actionCheatManager, &QAction::triggered, this, &MainWindow::onToolsCheatManagerTriggered);
|
||||
connect(m_ui.actionCPUDebugger, &QAction::triggered, this, &MainWindow::openCPUDebugger);
|
||||
connect(m_ui.actionOpenDataDirectory, &QAction::triggered, this, &MainWindow::onToolsOpenDataDirectoryTriggered);
|
||||
|
@ -2521,6 +2523,13 @@ void MainWindow::onToolsMemoryCardEditorTriggered()
|
|||
openMemoryCardEditor(QString(), QString());
|
||||
}
|
||||
|
||||
void MainWindow::onToolsCoverDownloaderTriggered()
|
||||
{
|
||||
CoverDownloadDialog dlg(this);
|
||||
connect(&dlg, &CoverDownloadDialog::coverRefreshRequested, m_game_list_widget, &GameListWidget::refreshGridCovers);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::onToolsCheatManagerTriggered()
|
||||
{
|
||||
if (!m_cheat_manager_dialog)
|
||||
|
|
|
@ -147,6 +147,7 @@ private Q_SLOTS:
|
|||
void onAboutActionTriggered();
|
||||
void onCheckForUpdatesActionTriggered();
|
||||
void onToolsMemoryCardEditorTriggered();
|
||||
void onToolsCoverDownloaderTriggered();
|
||||
void onToolsCheatManagerTriggered();
|
||||
void onToolsOpenDataDirectoryTriggered();
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
<string>DuckStation</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/duck.png</normaloff>:/icons/duck.png</iconset>
|
||||
</property>
|
||||
<widget class="QStackedWidget" name="mainContainer" />
|
||||
<widget class="QStackedWidget" name="mainContainer"/>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
@ -105,7 +105,8 @@
|
|||
<string>Theme</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="paint-brush-line"/>
|
||||
<iconset theme="paint-brush-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuSettingsLanguage">
|
||||
|
@ -113,7 +114,8 @@
|
|||
<string>Language</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="global-line"/>
|
||||
<iconset theme="global-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="separator"/>
|
||||
|
@ -229,6 +231,7 @@
|
|||
<string>&Tools</string>
|
||||
</property>
|
||||
<addaction name="actionMemory_Card_Editor"/>
|
||||
<addaction name="actionCoverDownloader"/>
|
||||
<addaction name="actionCheatManager"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionOpenDataDirectory"/>
|
||||
|
@ -468,7 +471,7 @@
|
|||
</action>
|
||||
<action name="actionGitHubRepository">
|
||||
<property name="icon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/github.png</normaloff>:/icons/github.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -477,7 +480,7 @@
|
|||
</action>
|
||||
<action name="actionIssueTracker">
|
||||
<property name="icon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/IssueTracker.png</normaloff>:/icons/IssueTracker.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -486,7 +489,7 @@
|
|||
</action>
|
||||
<action name="actionDiscordServer">
|
||||
<property name="icon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/discord.png</normaloff>:/icons/discord.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -504,7 +507,7 @@
|
|||
</action>
|
||||
<action name="actionAboutQt">
|
||||
<property name="icon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/QT.png</normaloff>:/icons/QT.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -513,7 +516,7 @@
|
|||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="icon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/duck_64.png</normaloff>:/icons/duck_64.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -940,6 +943,11 @@
|
|||
<string>Big Picture</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCoverDownloader">
|
||||
<property name="text">
|
||||
<string>Cover Downloader</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "qtprogresscallback.h"
|
||||
#include "common/assert.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <array>
|
||||
|
||||
QtProgressCallback::QtProgressCallback(QWidget* parent_widget, float show_delay)
|
||||
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("DuckStation"));
|
||||
|
@ -15,14 +16,14 @@ QtProgressCallback::QtProgressCallback(QWidget* parent_widget, float show_delay)
|
|||
checkForDelayedShow();
|
||||
}
|
||||
|
||||
QtProgressCallback::~QtProgressCallback() = default;
|
||||
QtModalProgressCallback::~QtModalProgressCallback() = default;
|
||||
|
||||
bool QtProgressCallback::IsCancelled() const
|
||||
bool QtModalProgressCallback::IsCancelled() const
|
||||
{
|
||||
return m_dialog.wasCanceled();
|
||||
}
|
||||
|
||||
void QtProgressCallback::SetCancellable(bool cancellable)
|
||||
void QtModalProgressCallback::SetCancellable(bool cancellable)
|
||||
{
|
||||
if (m_cancellable == cancellable)
|
||||
return;
|
||||
|
@ -31,12 +32,12 @@ void QtProgressCallback::SetCancellable(bool cancellable)
|
|||
m_dialog.setCancelButtonText(cancellable ? tr("Cancel") : QString());
|
||||
}
|
||||
|
||||
void QtProgressCallback::SetTitle(const char* title)
|
||||
void QtModalProgressCallback::SetTitle(const char* title)
|
||||
{
|
||||
m_dialog.setWindowTitle(QString::fromUtf8(title));
|
||||
}
|
||||
|
||||
void QtProgressCallback::SetStatusText(const char* text)
|
||||
void QtModalProgressCallback::SetStatusText(const char* text)
|
||||
{
|
||||
BaseProgressCallback::SetStatusText(text);
|
||||
checkForDelayedShow();
|
||||
|
@ -45,7 +46,7 @@ void QtProgressCallback::SetStatusText(const char* text)
|
|||
m_dialog.setLabelText(QString::fromUtf8(text));
|
||||
}
|
||||
|
||||
void QtProgressCallback::SetProgressRange(u32 range)
|
||||
void QtModalProgressCallback::SetProgressRange(u32 range)
|
||||
{
|
||||
BaseProgressCallback::SetProgressRange(range);
|
||||
checkForDelayedShow();
|
||||
|
@ -54,7 +55,7 @@ void QtProgressCallback::SetProgressRange(u32 range)
|
|||
m_dialog.setRange(0, m_progress_range);
|
||||
}
|
||||
|
||||
void QtProgressCallback::SetProgressValue(u32 value)
|
||||
void QtModalProgressCallback::SetProgressValue(u32 value)
|
||||
{
|
||||
BaseProgressCallback::SetProgressValue(value);
|
||||
checkForDelayedShow();
|
||||
|
@ -65,43 +66,43 @@ void QtProgressCallback::SetProgressValue(u32 value)
|
|||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void QtProgressCallback::DisplayError(const char* message)
|
||||
void QtModalProgressCallback::DisplayError(const char* message)
|
||||
{
|
||||
qWarning() << message;
|
||||
}
|
||||
|
||||
void QtProgressCallback::DisplayWarning(const char* message)
|
||||
void QtModalProgressCallback::DisplayWarning(const char* message)
|
||||
{
|
||||
qWarning() << message;
|
||||
}
|
||||
|
||||
void QtProgressCallback::DisplayInformation(const char* message)
|
||||
void QtModalProgressCallback::DisplayInformation(const char* message)
|
||||
{
|
||||
qWarning() << message;
|
||||
}
|
||||
|
||||
void QtProgressCallback::DisplayDebugMessage(const char* message)
|
||||
void QtModalProgressCallback::DisplayDebugMessage(const char* message)
|
||||
{
|
||||
qWarning() << message;
|
||||
}
|
||||
|
||||
void QtProgressCallback::ModalError(const char* message)
|
||||
void QtModalProgressCallback::ModalError(const char* message)
|
||||
{
|
||||
QMessageBox::critical(&m_dialog, tr("Error"), QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
bool QtProgressCallback::ModalConfirmation(const char* message)
|
||||
bool QtModalProgressCallback::ModalConfirmation(const char* message)
|
||||
{
|
||||
return (QMessageBox::question(&m_dialog, tr("Question"), QString::fromUtf8(message), QMessageBox::Yes,
|
||||
QMessageBox::No) == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void QtProgressCallback::ModalInformation(const char* message)
|
||||
void QtModalProgressCallback::ModalInformation(const char* message)
|
||||
{
|
||||
QMessageBox::information(&m_dialog, tr("Information"), QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
void QtProgressCallback::checkForDelayedShow()
|
||||
void QtModalProgressCallback::checkForDelayedShow()
|
||||
{
|
||||
if (m_dialog.isVisible())
|
||||
return;
|
||||
|
@ -113,3 +114,109 @@ void QtProgressCallback::checkForDelayedShow()
|
|||
m_dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
QtAsyncProgressThread::QtAsyncProgressThread(QWidget* parent) : QThread(parent) {}
|
||||
|
||||
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()
|
||||
{
|
||||
Assert(!isRunning());
|
||||
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
#pragma once
|
||||
#include "common/progress_callback.h"
|
||||
#include "common/timer.h"
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QSemaphore>
|
||||
#include <QtWidgets/QProgressDialog>
|
||||
#include <atomic>
|
||||
|
||||
class QtProgressCallback final : public QObject, public BaseProgressCallback
|
||||
class QtModalProgressCallback final : public QObject, public BaseProgressCallback
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtProgressCallback(QWidget* parent_widget, float show_delay = 0.0f);
|
||||
~QtProgressCallback();
|
||||
QtModalProgressCallback(QWidget* parent_widget, float show_delay = 0.0f);
|
||||
~QtModalProgressCallback();
|
||||
|
||||
bool IsCancelled() const override;
|
||||
|
||||
|
@ -34,4 +37,51 @@ private:
|
|||
QProgressDialog m_dialog;
|
||||
Common::Timer m_show_timer;
|
||||
float m_show_delay;
|
||||
};
|
||||
};
|
||||
|
||||
class QtAsyncProgressThread : public QThread, public BaseProgressCallback
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtAsyncProgressThread(QWidget* parent);
|
||||
~QtAsyncProgressThread();
|
||||
|
||||
bool IsCancelled() const override;
|
||||
|
||||
void SetCancellable(bool cancellable) override;
|
||||
void SetTitle(const char* title) override;
|
||||
void SetStatusText(const char* text) override;
|
||||
void SetProgressRange(u32 range) override;
|
||||
void SetProgressValue(u32 value) override;
|
||||
|
||||
void DisplayError(const char* message) override;
|
||||
void DisplayWarning(const char* message) override;
|
||||
void DisplayInformation(const char* message) override;
|
||||
void DisplayDebugMessage(const char* message) override;
|
||||
|
||||
void ModalError(const char* message) override;
|
||||
bool ModalConfirmation(const char* message) override;
|
||||
void ModalInformation(const char* message) override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void titleUpdated(const QString& title);
|
||||
void statusUpdated(const QString& status);
|
||||
void progressUpdated(int value, int range);
|
||||
void threadStarting();
|
||||
void threadFinished();
|
||||
|
||||
public Q_SLOTS:
|
||||
void start();
|
||||
void join();
|
||||
|
||||
protected:
|
||||
virtual void runAsync() = 0;
|
||||
void run() final;
|
||||
|
||||
private:
|
||||
QWidget* parentWidget() const;
|
||||
|
||||
QSemaphore m_start_semaphore;
|
||||
QThread* m_starting_thread = nullptr;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue