Merge pull request #3434 from BreadFish64/MultipleInstalls

QT: allow installation of multiple CIAs
This commit is contained in:
Weiyi Wang 2018-02-28 15:55:15 +02:00 committed by GitHub
commit 0cea9c54ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 27 deletions

View File

@ -96,8 +96,9 @@ void GMainWindow::ShowCallouts() {
} }
GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
// register size_t to use in slots and signals // register types to use in slots and signals
qRegisterMetaType<size_t>("size_t"); qRegisterMetaType<size_t>("size_t");
qRegisterMetaType<Service::AM::InstallStatus>("Service::AM::InstallStatus");
LoadTranslation(); LoadTranslation();
@ -382,6 +383,8 @@ void GMainWindow::ConnectWidgetEvents() {
connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar); connect(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar);
connect(this, &GMainWindow::UpdateProgress, this, &GMainWindow::OnUpdateProgress); connect(this, &GMainWindow::UpdateProgress, this, &GMainWindow::OnUpdateProgress);
connect(this, &GMainWindow::CIAInstallReport, this, &GMainWindow::OnCIAInstallReport);
connect(this, &GMainWindow::CIAInstallFinished, this, &GMainWindow::OnCIAInstallFinished);
} }
void GMainWindow::ConnectMenuEvents() { void GMainWindow::ConnectMenuEvents() {
@ -791,24 +794,28 @@ void GMainWindow::OnMenuSelectGameListRoot() {
} }
void GMainWindow::OnMenuInstallCIA() { void GMainWindow::OnMenuInstallCIA() {
QString filepath = QFileDialog::getOpenFileName( QStringList filepaths = QFileDialog::getOpenFileNames(
this, tr("Load File"), UISettings::values.roms_path, this, tr("Load Files"), UISettings::values.roms_path,
tr("3DS Installation File (*.CIA*)") + ";;" + tr("All Files (*.*)")); tr("3DS Installation File (*.CIA*)") + ";;" + tr("All Files (*.*)"));
if (filepath.isEmpty()) if (filepaths.isEmpty())
return; return;
ui.action_Install_CIA->setEnabled(false); ui.action_Install_CIA->setEnabled(false);
progress_bar->show(); progress_bar->show();
watcher = new QFutureWatcher<Service::AM::InstallStatus>;
QFuture<Service::AM::InstallStatus> f = QtConcurrent::run([&, filepath] { QtConcurrent::run([&, filepaths] {
QString current_path;
Service::AM::InstallStatus status;
const auto cia_progress = [&](size_t written, size_t total) { const auto cia_progress = [&](size_t written, size_t total) {
emit UpdateProgress(written, total); emit UpdateProgress(written, total);
}; };
return Service::AM::InstallCIA(filepath.toStdString(), cia_progress); for (const auto current_path : filepaths) {
status = Service::AM::InstallCIA(current_path.toStdString(), cia_progress);
emit CIAInstallReport(status, current_path);
}
emit CIAInstallFinished();
return;
}); });
connect(watcher, &QFutureWatcher<Service::AM::InstallStatus>::finished, this,
&GMainWindow::OnCIAInstallFinished);
watcher->setFuture(f);
} }
void GMainWindow::OnUpdateProgress(size_t written, size_t total) { void GMainWindow::OnUpdateProgress(size_t written, size_t total) {
@ -816,32 +823,37 @@ void GMainWindow::OnUpdateProgress(size_t written, size_t total) {
progress_bar->setValue(written); progress_bar->setValue(written);
} }
void GMainWindow::OnCIAInstallFinished() { void GMainWindow::OnCIAInstallReport(Service::AM::InstallStatus status, QString filepath) {
progress_bar->hide(); QString filename = QFileInfo(filepath).fileName();
progress_bar->setValue(0); switch (status) {
switch (watcher->future()) {
case Service::AM::InstallStatus::Success: case Service::AM::InstallStatus::Success:
this->statusBar()->showMessage(tr("The file has been installed successfully.")); this->statusBar()->showMessage(tr("%1 has been installed successfully.").arg(filename));
break; break;
case Service::AM::InstallStatus::ErrorFailedToOpenFile: case Service::AM::InstallStatus::ErrorFailedToOpenFile:
QMessageBox::critical(this, tr("Unable to open File"), QMessageBox::critical(this, tr("Unable to open File"),
tr("Could not open the selected file")); tr("Could not open %1").arg(filename));
break; break;
case Service::AM::InstallStatus::ErrorAborted: case Service::AM::InstallStatus::ErrorAborted:
QMessageBox::critical( QMessageBox::critical(
this, tr("Installation aborted"), this, tr("Installation aborted"),
tr("The installation was aborted. Please see the log for more details")); tr("The installation of %1 was aborted. Please see the log for more details")
.arg(filename));
break; break;
case Service::AM::InstallStatus::ErrorInvalid: case Service::AM::InstallStatus::ErrorInvalid:
QMessageBox::critical(this, tr("Invalid File"), tr("The selected file is not a valid CIA")); QMessageBox::critical(this, tr("Invalid File"), tr("%1 is not a valid CIA").arg(filename));
break; break;
case Service::AM::InstallStatus::ErrorEncrypted: case Service::AM::InstallStatus::ErrorEncrypted:
QMessageBox::critical(this, tr("Encrypted File"), QMessageBox::critical(this, tr("Encrypted File"),
tr("The file that you are trying to install must be decrypted " tr("%1 must be decrypted "
"before being used with Citra. A real 3DS is required.")); "before being used with Citra. A real 3DS is required.")
.arg(filename));
break; break;
} }
delete watcher; }
void GMainWindow::OnCIAInstallFinished() {
progress_bar->hide();
progress_bar->setValue(0);
ui.action_Install_CIA->setEnabled(true); ui.action_Install_CIA->setEnabled(true);
} }
@ -897,7 +909,8 @@ void GMainWindow::OnMenuReportCompatibility() {
QMessageBox::critical( QMessageBox::critical(
this, tr("Missing Citra Account"), this, tr("Missing Citra Account"),
tr("In order to submit a game compatibility test case, you must link your Citra " tr("In order to submit a game compatibility test case, you must link your Citra "
"account.<br><br/>To link your Citra account, go to Emulation &gt; Configuration &gt; " "account.<br><br/>To link your Citra account, go to Emulation &gt; Configuration "
"&gt; "
"Web.")); "Web."));
} }
} }
@ -1048,8 +1061,7 @@ void GMainWindow::UpdateStatusBar() {
.arg(results.emulation_speed * 100.0, 0, 'f', 0) .arg(results.emulation_speed * 100.0, 0, 'f', 0)
.arg(Settings::values.frame_limit)); .arg(Settings::values.frame_limit));
} else { } else {
emu_speed_label->setText(tr("Speed: %1%") emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
.arg(results.emulation_speed * 100.0, 0, 'f', 0));
} }
game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0)); game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0));
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));

View File

@ -70,7 +70,10 @@ signals:
* system emulation handles and memory are still valid, but are about become invalid. * system emulation handles and memory are still valid, but are about become invalid.
*/ */
void EmulationStopping(); void EmulationStopping();
void UpdateProgress(size_t written, size_t total); void UpdateProgress(size_t written, size_t total);
void CIAInstallReport(Service::AM::InstallStatus status, QString filepath);
void CIAInstallFinished();
private: private:
void InitializeWidgets(); void InitializeWidgets();
@ -136,6 +139,7 @@ private slots:
void OnMenuLoadFile(); void OnMenuLoadFile();
void OnMenuInstallCIA(); void OnMenuInstallCIA();
void OnUpdateProgress(size_t written, size_t total); void OnUpdateProgress(size_t written, size_t total);
void OnCIAInstallReport(Service::AM::InstallStatus status, QString filepath);
void OnCIAInstallFinished(); void OnCIAInstallFinished();
/// Called whenever a user selects the "File->Select Game List Root" menu item /// Called whenever a user selects the "File->Select Game List Root" menu item
void OnMenuSelectGameListRoot(); void OnMenuSelectGameListRoot();
@ -168,7 +172,6 @@ private:
GRenderWindow* render_window; GRenderWindow* render_window;
GameList* game_list; GameList* game_list;
QFutureWatcher<Service::AM::InstallStatus>* watcher = nullptr;
// Status bar elements // Status bar elements
QProgressBar* progress_bar = nullptr; QProgressBar* progress_bar = nullptr;
@ -210,3 +213,4 @@ protected:
}; };
Q_DECLARE_METATYPE(size_t); Q_DECLARE_METATYPE(size_t);
Q_DECLARE_METATYPE(Service::AM::InstallStatus);