Qt: Add a progress bar for the forwarder builder downloads

This commit is contained in:
Vicki Pfau 2022-11-04 06:25:07 -07:00
parent 694b80d289
commit b48c7a1887
5 changed files with 158 additions and 61 deletions

View File

@ -84,13 +84,11 @@ void ForwarderController::downloadForwarderKit() {
return;
#endif
QNetworkReply* reply = m_netman->get(QNetworkRequest(QUrl(fkUrl)));
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
gotForwarderKit(reply);
});
connectErrorFailure(reply);
connectReply(reply, FORWARDER_KIT, &ForwarderController::gotForwarderKit);
}
void ForwarderController::gotForwarderKit(QNetworkReply* reply) {
emit downloadComplete(FORWARDER_KIT);
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
emit buildFailed();
return;
@ -135,13 +133,11 @@ void ForwarderController::gotForwarderKit(QNetworkReply* reply) {
void ForwarderController::downloadManifest() {
QNetworkReply* reply = m_netman->get(QNetworkRequest(QUrl("https://mgba.io/latest.ini")));
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
gotManifest(reply);
});
connectErrorFailure(reply);
connectReply(reply, MANIFEST, &ForwarderController::gotManifest);
}
void ForwarderController::gotManifest(QNetworkReply* reply) {
emit downloadComplete(MANIFEST);
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
emit buildFailed();
return;
@ -179,18 +175,15 @@ void ForwarderController::downloadBuild(const QUrl& url) {
}
QNetworkReply* reply = m_netman->get(QNetworkRequest(url));
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
gotBuild(reply);
});
connectReply(reply, BASE, &ForwarderController::gotBuild);
connect(reply, &QNetworkReply::readyRead, this, [this, reply]() {
QByteArray data = reply->readAll();
m_sourceFile.write(data);
});
connectErrorFailure(reply);
}
void ForwarderController::gotBuild(QNetworkReply* reply) {
emit downloadComplete(BASE);
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
emit buildFailed();
return;
@ -223,7 +216,7 @@ bool ForwarderController::toolInstalled(const QString& tool) {
return false;
}
void ForwarderController::connectErrorFailure(QNetworkReply* reply) {
void ForwarderController::connectReply(QNetworkReply* reply, Download download, void (ForwarderController::*next)(QNetworkReply*)) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
connect(reply, &QNetworkReply::errorOccurred, this, [this, reply]() {
#else
@ -231,4 +224,12 @@ void ForwarderController::connectErrorFailure(QNetworkReply* reply) {
#endif
emit buildFailed();
});
connect(reply, &QNetworkReply::finished, this, [this, reply, next]() {
(this->*next)(reply);
});
connect(reply, &QNetworkReply::downloadProgress, this, [this, download](qint64 bytesReceived, qint64 bytesTotal) {
emit downloadProgress(download, bytesReceived, bytesTotal);
});
emit downloadStarted(download);
}

View File

@ -21,17 +21,27 @@ class ForwarderController : public QObject {
Q_OBJECT
public:
enum Download : int {
MANIFEST,
BASE,
FORWARDER_KIT
};
ForwarderController(QObject* parent = nullptr);
void setGenerator(std::unique_ptr<ForwarderGenerator>&& generator);
ForwarderGenerator* generator() { return m_generator.get(); }
QString channel() const { return m_channel; }
bool inProgress() const { return m_inProgress; }
public slots:
void startBuild(const QString& outFilename);
signals:
void buildStarted(bool needsForwarderKit);
void downloadStarted(Download which);
void downloadComplete(Download which);
void downloadProgress(Download which, qint64 bytesGotten, qint64 bytesTotal);
void buildComplete();
void buildFailed();
@ -47,7 +57,7 @@ private:
bool toolInstalled(const QString& tool);
void cleanup();
void connectErrorFailure(QNetworkReply*);
void connectReply(QNetworkReply*, Download, void (ForwarderController::*next)(QNetworkReply*));
QString m_channel{"dev"};
QString m_outFilename;

View File

@ -32,13 +32,49 @@ ForwarderView::ForwarderView(QWidget* parent)
connect(m_ui.imageSelect, qOverload<int>(&QComboBox::currentIndexChanged), this, &ForwarderView::setActiveImage);
connect(m_ui.imageBrowse, &QAbstractButton::clicked, this, &ForwarderView::selectImage);
connect(&m_controller, &ForwarderController::buildComplete, this, &QDialog::accept);
connect(&m_controller, &ForwarderController::buildComplete, this, [this]() {
QMessageBox* message = new QMessageBox(QMessageBox::Information, tr("Build finished"),
tr("Forwarder finished building"),
QMessageBox::Ok, parentWidget(), Qt::Sheet);
message->setAttribute(Qt::WA_DeleteOnClose);
message->show();
accept();
});
connect(&m_controller, &ForwarderController::buildFailed, this, [this]() {
QMessageBox* error = new QMessageBox(QMessageBox::Critical, tr("Build failed"),
tr("Failed to build forwarder"),
QMessageBox::Ok, this, Qt::Sheet);
error->setAttribute(Qt::WA_DeleteOnClose);
error->show();
m_ui.progressBar->setValue(0);
m_ui.progressBar->setEnabled(false);
validate();
});
connect(&m_controller, &ForwarderController::downloadStarted, this, [this](ForwarderController::Download download) {
m_currentDownload = download;
m_downloadProgress = 0;
if (download == ForwarderController::FORWARDER_KIT) {
m_needsForwarderKit = true;
}
updateProgress();
});
connect(&m_controller, &ForwarderController::downloadComplete, this, [this](ForwarderController::Download download) {
if (m_currentDownload != download) {
return;
}
m_downloadProgress = 1;
updateProgress();
});
connect(&m_controller, &ForwarderController::downloadProgress, this, [this](ForwarderController::Download download, qint64 bytesReceived, qint64 bytesTotal) {
if (m_currentDownload != download) {
return;
}
if (bytesTotal <= 0 || bytesTotal < bytesReceived) {
return;
}
m_downloadProgress = bytesReceived / static_cast<qreal>(bytesTotal);
updateProgress();
});
connect(m_ui.system3DS, &QAbstractButton::clicked, this, [this]() {
@ -59,6 +95,13 @@ void ForwarderView::build() {
m_controller.generator()->setTitle(m_ui.title->text());
m_controller.generator()->setRom(m_ui.romFilename->text());
m_controller.startBuild(m_ui.outputFilename->text());
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
m_ui.progressBar->setEnabled(true);
m_currentDownload = ForwarderController::FORWARDER_KIT;
m_downloadProgress = 0;
m_needsForwarderKit = false;
updateProgress();
}
void ForwarderView::validate() {
@ -80,6 +123,9 @@ void ForwarderView::validate() {
if (m_ui.baseType->currentIndex() != 1) {
valid = false;
}
if (m_controller.inProgress()) {
valid = false;
}
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
}
@ -154,3 +200,25 @@ void ForwarderView::setActiveImage(int index) {
m_ui.imagePreview->setMaximumSize(m_activeSize);
m_ui.imagePreview->setPixmap(QPixmap::fromImage(m_controller.generator()->image(index)));
}
void ForwarderView::updateProgress() {
switch (m_currentDownload) {
case ForwarderController::FORWARDER_KIT:
m_ui.progressBar->setValue(m_downloadProgress * 450);
break;
case ForwarderController::MANIFEST:
if (m_needsForwarderKit) {
m_ui.progressBar->setValue(450 + m_downloadProgress * 50);
} else {
m_ui.progressBar->setValue(m_downloadProgress * 100);
}
break;
case ForwarderController::BASE:
if (m_needsForwarderKit) {
m_ui.progressBar->setValue(500 + m_downloadProgress * 500);
} else {
m_ui.progressBar->setValue(100 + m_downloadProgress * 900);
}
break;
}
}

View File

@ -30,12 +30,17 @@ private:
void connectBrowseButton(QAbstractButton* button, QLineEdit* lineEdit, const QString& title, bool save = false, const QString& filter = {});
void selectImage();
void setActiveImage(int);
void updateProgress();
ForwarderController m_controller;
QVector<QImage> m_images;
int m_currentImage;
QSize m_activeSize;
qreal m_downloadProgress;
ForwarderController::Download m_currentDownload;
bool m_needsForwarderKit;
Ui::ForwarderView m_ui;
};

View File

@ -14,51 +14,6 @@
<string>Create forwarder</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>System</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item alignment="Qt::AlignHCenter">
<widget class="QRadioButton" name="system3DS">
<property name="text">
<string>3DS</string>
</property>
<attribute name="buttonGroup">
<string notr="true">system</string>
</attribute>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QRadioButton" name="systemVita">
<property name="text">
<string>Vita</string>
</property>
<attribute name="buttonGroup">
<string notr="true">system</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
@ -168,6 +123,51 @@
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>System</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item alignment="Qt::AlignHCenter">
<widget class="QRadioButton" name="system3DS">
<property name="text">
<string>3DS</string>
</property>
<attribute name="buttonGroup">
<string notr="true">system</string>
</attribute>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QRadioButton" name="systemVita">
<property name="text">
<string>Vita</string>
</property>
<attribute name="buttonGroup">
<string notr="true">system</string>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
@ -399,6 +399,19 @@
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QProgressBar" name="progressBar">
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>