mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #3144 from BreadFish64/CIAInstallUI
QT CIA installation
This commit is contained in:
		
						commit
						466bec2d43
					
				
					 3 changed files with 87 additions and 2 deletions
				
			
		|  | @ -10,7 +10,9 @@ | |||
| #define QT_NO_OPENGL | ||||
| #include <QDesktopWidget> | ||||
| #include <QFileDialog> | ||||
| #include <QFutureWatcher> | ||||
| #include <QMessageBox> | ||||
| #include <QtConcurrent/QtConcurrentRun> | ||||
| #include <QtGui> | ||||
| #include <QtWidgets> | ||||
| #include "citra_qt/aboutdialog.h" | ||||
|  | @ -92,6 +94,9 @@ void GMainWindow::ShowCallouts() { | |||
| } | ||||
| 
 | ||||
| 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(); | ||||
|     setAcceptDrops(true); | ||||
|     ui.setupUi(this); | ||||
|  | @ -158,6 +163,10 @@ void GMainWindow::InitializeWidgets() { | |||
|     message_label->setAlignment(Qt::AlignLeft); | ||||
|     statusBar()->addPermanentWidget(message_label, 1); | ||||
| 
 | ||||
|     progress_bar = new QProgressBar(); | ||||
|     progress_bar->hide(); | ||||
|     statusBar()->addPermanentWidget(progress_bar); | ||||
| 
 | ||||
|     emu_speed_label = new QLabel(); | ||||
|     emu_speed_label->setToolTip(tr("Current emulation speed. Values higher or lower than 100% " | ||||
|                                    "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(&status_bar_update_timer, &QTimer::timeout, this, &GMainWindow::UpdateStatusBar); | ||||
| 
 | ||||
|     connect(this, &GMainWindow::UpdateProgress, this, &GMainWindow::OnUpdateProgress); | ||||
| } | ||||
| 
 | ||||
| void GMainWindow::ConnectMenuEvents() { | ||||
|     // File
 | ||||
|     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, | ||||
|             &GMainWindow::OnMenuSelectGameListRoot); | ||||
|     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() { | ||||
|     QAction* action = qobject_cast<QAction*>(sender()); | ||||
|     assert(action); | ||||
|  |  | |||
|  | @ -8,24 +8,28 @@ | |||
| #include <QMainWindow> | ||||
| #include <QTimer> | ||||
| #include "core/core.h" | ||||
| #include "core/hle/service/am/am.h" | ||||
| #include "ui_main.h" | ||||
| 
 | ||||
| class AboutDialog; | ||||
| class Config; | ||||
| class EmuThread; | ||||
| class GameList; | ||||
| class GImageInfo; | ||||
| class GPUCommandStreamWidget; | ||||
| class GPUCommandListWidget; | ||||
| class GPUCommandStreamWidget; | ||||
| class GraphicsBreakPointsWidget; | ||||
| class GraphicsTracingWidget; | ||||
| class GraphicsVertexShaderWidget; | ||||
| class GRenderWindow; | ||||
| class MicroProfileDialog; | ||||
| class ProfilerWidget; | ||||
| template <typename> | ||||
| class QFutureWatcher; | ||||
| class QProgressBar; | ||||
| class RegistersWidget; | ||||
| class Updater; | ||||
| class WaitTreeWidget; | ||||
| class AboutDialog; | ||||
| 
 | ||||
| class GMainWindow : public QMainWindow { | ||||
|     Q_OBJECT | ||||
|  | @ -64,6 +68,7 @@ signals: | |||
|      * system emulation handles and memory are still valid, but are about become invalid. | ||||
|      */ | ||||
|     void EmulationStopping(); | ||||
|     void UpdateProgress(size_t written, size_t total); | ||||
| 
 | ||||
| private: | ||||
|     void InitializeWidgets(); | ||||
|  | @ -125,6 +130,9 @@ private slots: | |||
|     void OnGameListLoadFile(QString game_path); | ||||
|     void OnGameListOpenSaveFolder(u64 program_id); | ||||
|     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
 | ||||
|     void OnMenuSelectGameListRoot(); | ||||
|     void OnMenuRecentFile(); | ||||
|  | @ -149,8 +157,10 @@ private: | |||
| 
 | ||||
|     GRenderWindow* render_window; | ||||
|     GameList* game_list; | ||||
|     QFutureWatcher<Service::AM::InstallStatus>* watcher = nullptr; | ||||
| 
 | ||||
|     // Status bar elements
 | ||||
|     QProgressBar* progress_bar = nullptr; | ||||
|     QLabel* message_label = nullptr; | ||||
|     QLabel* emu_speed_label = nullptr; | ||||
|     QLabel* game_fps_label = nullptr; | ||||
|  | @ -185,3 +195,5 @@ protected: | |||
|     void dragEnterEvent(QDragEnterEvent* event) override; | ||||
|     void dragMoveEvent(QDragMoveEvent* event) override; | ||||
| }; | ||||
| 
 | ||||
| Q_DECLARE_METATYPE(size_t); | ||||
|  |  | |||
|  | @ -58,6 +58,7 @@ | |||
|      </property> | ||||
|     </widget> | ||||
|     <addaction name="action_Load_File"/> | ||||
|     <addaction name="action_Install_CIA"/> | ||||
|     <addaction name="separator"/> | ||||
|     <addaction name="action_Select_Game_List_Root"/> | ||||
|     <addaction name="menu_recent_files"/> | ||||
|  | @ -112,6 +113,11 @@ | |||
|     <string>Load File...</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Install_CIA"> | ||||
|    <property name="text"> | ||||
|     <string>Install CIA...</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="action_Load_Symbol_Map"> | ||||
|    <property name="text"> | ||||
|     <string>Load Symbol Map...</string> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue