add CIA installation to QT frontend

This commit is contained in:
BreadFish64 2017-12-02 15:35:20 -06:00
parent b7cf793814
commit 80852f918a
3 changed files with 87 additions and 2 deletions

View file

@ -10,7 +10,9 @@
#define QT_NO_OPENGL #define QT_NO_OPENGL
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QFileDialog> #include <QFileDialog>
#include <QFutureWatcher>
#include <QMessageBox> #include <QMessageBox>
#include <QtConcurrent/QtConcurrentRun>
#include <QtGui> #include <QtGui>
#include <QtWidgets> #include <QtWidgets>
#include "citra_qt/aboutdialog.h" #include "citra_qt/aboutdialog.h"
@ -92,6 +94,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
qRegisterMetaType<size_t>("size_t");
Pica::g_debug_context = Pica::DebugContext::Construct(); Pica::g_debug_context = Pica::DebugContext::Construct();
setAcceptDrops(true); setAcceptDrops(true);
ui.setupUi(this); ui.setupUi(this);
@ -158,6 +163,10 @@ void GMainWindow::InitializeWidgets() {
message_label->setAlignment(Qt::AlignLeft); message_label->setAlignment(Qt::AlignLeft);
statusBar()->addPermanentWidget(message_label, 1); statusBar()->addPermanentWidget(message_label, 1);
progress_bar = new QProgressBar();
progress_bar->hide();
statusBar()->addPermanentWidget(progress_bar);
emu_speed_label = new QLabel(); emu_speed_label = new QLabel();
emu_speed_label->setToolTip(tr("Current emulation speed. Values higher or lower than 100% " emu_speed_label->setToolTip(tr("Current emulation speed. Values higher or lower than 100% "
"indicate emulation is running faster or slower than a 3DS.")); "indicate emulation is running faster or slower than a 3DS."));
@ -333,11 +342,14 @@ void GMainWindow::ConnectWidgetEvents() {
connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping())); connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping()));
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);
} }
void GMainWindow::ConnectMenuEvents() { void GMainWindow::ConnectMenuEvents() {
// File // File
connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile); connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile);
connect(ui.action_Install_CIA, &QAction::triggered, this, &GMainWindow::OnMenuInstallCIA);
connect(ui.action_Select_Game_List_Root, &QAction::triggered, this, connect(ui.action_Select_Game_List_Root, &QAction::triggered, this,
&GMainWindow::OnMenuSelectGameListRoot); &GMainWindow::OnMenuSelectGameListRoot);
connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close); connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close);
@ -696,6 +708,61 @@ void GMainWindow::OnMenuSelectGameListRoot() {
} }
} }
void GMainWindow::OnMenuInstallCIA() {
QString filepath = QFileDialog::getOpenFileName(
this, tr("Load File"), UISettings::values.roms_path,
tr("3DS Installation File (*.CIA*)") + ";;" + tr("All Files (*.*)"));
if (filepath.isEmpty())
return;
ui.action_Install_CIA->setEnabled(false);
progress_bar->show();
watcher = new QFutureWatcher<Service::AM::InstallStatus>;
QFuture<Service::AM::InstallStatus> f = QtConcurrent::run([&, filepath] {
const auto cia_progress = [&](size_t written, size_t total) {
emit UpdateProgress(written, total);
};
return Service::AM::InstallCIA(filepath.toStdString(), cia_progress);
});
connect(watcher, &QFutureWatcher<Service::AM::InstallStatus>::finished, this,
&GMainWindow::OnCIAInstallFinished);
watcher->setFuture(f);
}
void GMainWindow::OnUpdateProgress(size_t written, size_t total) {
progress_bar->setMaximum(total);
progress_bar->setValue(written);
}
void GMainWindow::OnCIAInstallFinished() {
progress_bar->hide();
progress_bar->setValue(0);
switch (watcher->future()) {
case Service::AM::InstallStatus::Success:
this->statusBar()->showMessage(tr("The file has been installed successfully."));
break;
case Service::AM::InstallStatus::ErrorFailedToOpenFile:
QMessageBox::critical(this, tr("Unable to open File"),
tr("Could not open the selected file"));
break;
case Service::AM::InstallStatus::ErrorAborted:
QMessageBox::critical(
this, tr("Installation aborted"),
tr("The installation was aborted. Please see the log for more details"));
break;
case Service::AM::InstallStatus::ErrorInvalid:
QMessageBox::critical(this, tr("Invalid File"), tr("The selected file is not a valid CIA"));
break;
case Service::AM::InstallStatus::ErrorEncrypted:
QMessageBox::critical(this, tr("Encrypted File"),
tr("The file that you are trying to install must be decrypted "
"before being used with Citra. A real 3DS is required."));
break;
}
delete watcher;
ui.action_Install_CIA->setEnabled(true);
}
void GMainWindow::OnMenuRecentFile() { void GMainWindow::OnMenuRecentFile() {
QAction* action = qobject_cast<QAction*>(sender()); QAction* action = qobject_cast<QAction*>(sender());
assert(action); assert(action);

View file

@ -8,24 +8,28 @@
#include <QMainWindow> #include <QMainWindow>
#include <QTimer> #include <QTimer>
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/am/am.h"
#include "ui_main.h" #include "ui_main.h"
class AboutDialog;
class Config; class Config;
class EmuThread; class EmuThread;
class GameList; class GameList;
class GImageInfo; class GImageInfo;
class GPUCommandStreamWidget;
class GPUCommandListWidget; class GPUCommandListWidget;
class GPUCommandStreamWidget;
class GraphicsBreakPointsWidget; class GraphicsBreakPointsWidget;
class GraphicsTracingWidget; class GraphicsTracingWidget;
class GraphicsVertexShaderWidget; class GraphicsVertexShaderWidget;
class GRenderWindow; class GRenderWindow;
class MicroProfileDialog; class MicroProfileDialog;
class ProfilerWidget; class ProfilerWidget;
template <typename>
class QFutureWatcher;
class QProgressBar;
class RegistersWidget; class RegistersWidget;
class Updater; class Updater;
class WaitTreeWidget; class WaitTreeWidget;
class AboutDialog;
class GMainWindow : public QMainWindow { class GMainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
@ -64,6 +68,7 @@ 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);
private: private:
void InitializeWidgets(); void InitializeWidgets();
@ -125,6 +130,9 @@ private slots:
void OnGameListLoadFile(QString game_path); void OnGameListLoadFile(QString game_path);
void OnGameListOpenSaveFolder(u64 program_id); void OnGameListOpenSaveFolder(u64 program_id);
void OnMenuLoadFile(); void OnMenuLoadFile();
void OnMenuInstallCIA();
void OnUpdateProgress(size_t written, size_t total);
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();
void OnMenuRecentFile(); void OnMenuRecentFile();
@ -149,8 +157,10 @@ 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;
QLabel* message_label = nullptr; QLabel* message_label = nullptr;
QLabel* emu_speed_label = nullptr; QLabel* emu_speed_label = nullptr;
QLabel* game_fps_label = nullptr; QLabel* game_fps_label = nullptr;
@ -185,3 +195,5 @@ protected:
void dragEnterEvent(QDragEnterEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override;
void dragMoveEvent(QDragMoveEvent* event) override; void dragMoveEvent(QDragMoveEvent* event) override;
}; };
Q_DECLARE_METATYPE(size_t);

View file

@ -58,6 +58,7 @@
</property> </property>
</widget> </widget>
<addaction name="action_Load_File"/> <addaction name="action_Load_File"/>
<addaction name="action_Install_CIA"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_Select_Game_List_Root"/> <addaction name="action_Select_Game_List_Root"/>
<addaction name="menu_recent_files"/> <addaction name="menu_recent_files"/>
@ -112,6 +113,11 @@
<string>Load File...</string> <string>Load File...</string>
</property> </property>
</action> </action>
<action name="action_Install_CIA">
<property name="text">
<string>Install CIA...</string>
</property>
</action>
<action name="action_Load_Symbol_Map"> <action name="action_Load_Symbol_Map">
<property name="text"> <property name="text">
<string>Load Symbol Map...</string> <string>Load Symbol Map...</string>