From e921cbe57cf64c473521e9911e4a40dcf9efd96a Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Wed, 20 Nov 2019 21:47:10 +0100 Subject: [PATCH] GCMemcardManager: Add GUI to create new memory card. --- Source/Core/DolphinQt/CMakeLists.txt | 2 + Source/Core/DolphinQt/DolphinQt.vcxproj | 3 + .../DolphinQt/GCMemcardCreateNewDialog.cpp | 87 +++++++++++++++++++ .../Core/DolphinQt/GCMemcardCreateNewDialog.h | 28 ++++++ Source/Core/DolphinQt/GCMemcardManager.cpp | 20 ++++- Source/Core/DolphinQt/GCMemcardManager.h | 4 +- 6 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp create mode 100644 Source/Core/DolphinQt/GCMemcardCreateNewDialog.h diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 8449920c61..1121424812 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -200,6 +200,8 @@ add_executable(dolphin-emu GameList/GridProxyModel.h GameList/ListProxyModel.cpp GameList/ListProxyModel.h + GCMemcardCreateNewDialog.cpp + GCMemcardCreateNewDialog.h GCMemcardManager.cpp GCMemcardManager.h QtUtils/BlockUserInputFilter.cpp diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 023f50a5e1..936a412a7e 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -153,6 +153,7 @@ + @@ -225,6 +226,7 @@ + @@ -401,6 +403,7 @@ + diff --git a/Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp b/Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp new file mode 100644 index 0000000000..cbd77ee32a --- /dev/null +++ b/Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp @@ -0,0 +1,87 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt/GCMemcardCreateNewDialog.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "Common/FileUtil.h" +#include "Common/MsgHandler.h" + +#include "Core/HW/GCMemcard/GCMemcard.h" + +GCMemcardCreateNewDialog::GCMemcardCreateNewDialog(QWidget* parent) : QDialog(parent) +{ + m_combobox_size = new QComboBox(); + m_combobox_size->addItem(tr("4 Mbit (59 blocks)"), 4); + m_combobox_size->addItem(tr("8 Mbit (123 blocks)"), 8); + m_combobox_size->addItem(tr("16 Mbit (251 blocks)"), 16); + m_combobox_size->addItem(tr("32 Mbit (507 blocks)"), 32); + m_combobox_size->addItem(tr("64 Mbit (1019 blocks)"), 64); + m_combobox_size->addItem(tr("128 Mbit (2043 blocks)"), 128); + m_combobox_size->setCurrentIndex(5); + + m_radio_western = new QRadioButton(tr("Western (Windows-1252)")); + m_radio_shiftjis = new QRadioButton(tr("Japanese (Shift-JIS)")); + m_radio_western->setChecked(true); + + auto* card_size_label = new QLabel(tr("Card Size")); + auto* card_encoding_label = new QLabel(tr("Encoding")); + auto* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + button_box->button(QDialogButtonBox::Ok)->setText(tr("Create...")); + + auto* layout = new QGridLayout(); + layout->addWidget(card_size_label, 0, 0); + layout->addWidget(m_combobox_size, 0, 1); + layout->addWidget(card_encoding_label, 1, 0); + layout->addWidget(m_radio_western, 1, 1); + layout->addWidget(m_radio_shiftjis, 2, 1); + layout->addWidget(button_box, 3, 0, 1, 2, Qt::AlignRight); + setLayout(layout); + + connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(button_box, &QDialogButtonBox::accepted, [this] { + if (CreateCard()) + accept(); + }); + + setWindowTitle(tr("Create New Memory Card")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); +} + +GCMemcardCreateNewDialog::~GCMemcardCreateNewDialog() = default; + +bool GCMemcardCreateNewDialog::CreateCard() +{ + const u16 size = static_cast(m_combobox_size->currentData().toInt()); + const bool is_shift_jis = m_radio_shiftjis->isChecked(); + + const QString path = QFileDialog::getSaveFileName( + this, tr("Create New Memory Card"), QString::fromStdString(File::GetUserPath(D_GCUSER_IDX)), + tr("GameCube Memory Cards (*.raw *.gcp)") + QStringLiteral(";;") + tr("All Files (*)")); + + if (path.isEmpty()) + return false; + + const std::string p = path.toStdString(); + auto memcard = GCMemcard::Create(p, size, is_shift_jis); + if (memcard && memcard->Save()) + { + m_card_path = p; + return true; + } + + return false; +} + +std::string GCMemcardCreateNewDialog::GetMemoryCardPath() const +{ + return m_card_path; +} diff --git a/Source/Core/DolphinQt/GCMemcardCreateNewDialog.h b/Source/Core/DolphinQt/GCMemcardCreateNewDialog.h new file mode 100644 index 0000000000..571699ea49 --- /dev/null +++ b/Source/Core/DolphinQt/GCMemcardCreateNewDialog.h @@ -0,0 +1,28 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +class QComboBox; +class QRadioButton; + +class GCMemcardCreateNewDialog : public QDialog +{ + Q_OBJECT +public: + explicit GCMemcardCreateNewDialog(QWidget* parent = nullptr); + ~GCMemcardCreateNewDialog(); + + std::string GetMemoryCardPath() const; + +private: + bool CreateCard(); + + QComboBox* m_combobox_size; + QRadioButton* m_radio_western; + QRadioButton* m_radio_shiftjis; + std::string m_card_path; +}; diff --git a/Source/Core/DolphinQt/GCMemcardManager.cpp b/Source/Core/DolphinQt/GCMemcardManager.cpp index 52c2dcfa35..6a20522980 100644 --- a/Source/Core/DolphinQt/GCMemcardManager.cpp +++ b/Source/Core/DolphinQt/GCMemcardManager.cpp @@ -30,6 +30,7 @@ #include "Core/Config/MainSettings.h" #include "Core/HW/GCMemcard/GCMemcard.h" +#include "DolphinQt/GCMemcardCreateNewDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" constexpr float ROW_HEIGHT = 28; @@ -91,7 +92,8 @@ void GCMemcardManager::CreateWidgets() { m_slot_group[i] = new QGroupBox(i == 0 ? tr("Slot A") : tr("Slot B")); m_slot_file_edit[i] = new QLineEdit; - m_slot_file_button[i] = new QPushButton(tr("&Browse...")); + m_slot_open_button[i] = new QPushButton(tr("&Open...")); + m_slot_create_button[i] = new QPushButton(tr("&Create...")); m_slot_table[i] = new QTableWidget; m_slot_table[i]->setTabKeyNavigation(false); m_slot_stat_label[i] = new QLabel; @@ -107,8 +109,9 @@ void GCMemcardManager::CreateWidgets() m_slot_group[i]->setLayout(slot_layout); slot_layout->addWidget(m_slot_file_edit[i], 0, 0); - slot_layout->addWidget(m_slot_file_button[i], 0, 1); - slot_layout->addWidget(m_slot_table[i], 1, 0, 1, 2); + slot_layout->addWidget(m_slot_open_button[i], 0, 1); + slot_layout->addWidget(m_slot_create_button[i], 0, 2); + slot_layout->addWidget(m_slot_table[i], 1, 0, 1, 3); slot_layout->addWidget(m_slot_stat_label[i], 2, 0); layout->addWidget(m_slot_group[i], 0, i * 2, 9, 1); @@ -143,8 +146,10 @@ void GCMemcardManager::ConnectWidgets() { connect(m_slot_file_edit[slot], &QLineEdit::textChanged, [this, slot](const QString& path) { SetSlotFile(slot, path); }); - connect(m_slot_file_button[slot], &QPushButton::clicked, + connect(m_slot_open_button[slot], &QPushButton::clicked, [this, slot] { SetSlotFileInteractive(slot); }); + connect(m_slot_create_button[slot], &QPushButton::clicked, + [this, slot] { CreateNewCard(slot); }); connect(m_slot_table[slot], &QTableWidget::itemSelectionChanged, this, &GCMemcardManager::UpdateActions); } @@ -459,6 +464,13 @@ void GCMemcardManager::FixChecksums() PanicAlertT("File write failed"); } +void GCMemcardManager::CreateNewCard(int slot) +{ + GCMemcardCreateNewDialog dialog(this); + if (dialog.exec() == QDialog::Accepted) + m_slot_file_edit[slot]->setText(QString::fromStdString(dialog.GetMemoryCardPath())); +} + void GCMemcardManager::DrawIcons() { const auto column = 3; diff --git a/Source/Core/DolphinQt/GCMemcardManager.h b/Source/Core/DolphinQt/GCMemcardManager.h index 1f8b8ad3a3..ccacf98c2c 100644 --- a/Source/Core/DolphinQt/GCMemcardManager.h +++ b/Source/Core/DolphinQt/GCMemcardManager.h @@ -54,6 +54,7 @@ private: void ExportFiles(bool prompt); void ExportAllFiles(); void FixChecksums(); + void CreateNewCard(int slot); void DrawIcons(); QPixmap GetBannerFromSaveFile(int file_index, int slot); @@ -75,7 +76,8 @@ private: std::array, SLOT_COUNT> m_slot_memcard; std::array m_slot_group; std::array m_slot_file_edit; - std::array m_slot_file_button; + std::array m_slot_open_button; + std::array m_slot_create_button; std::array m_slot_table; std::array m_slot_stat_label;