duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

memorycardsettingswidget.cpp (7592B)


      1 // SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #include "memorycardsettingswidget.h"
      5 
      6 #include "core/controller.h"
      7 #include "core/settings.h"
      8 #include "inputbindingwidgets.h"
      9 #include "mainwindow.h"
     10 #include "qthost.h"
     11 #include "qtutils.h"
     12 #include "settingswindow.h"
     13 #include "settingwidgetbinder.h"
     14 
     15 #include "common/small_string.h"
     16 #include "common/string_util.h"
     17 
     18 #include <QtCore/QUrl>
     19 #include <QtWidgets/QFileDialog>
     20 #include <QtWidgets/QLabel>
     21 
     22 static constexpr char MEMORY_CARD_IMAGE_FILTER[] =
     23   QT_TRANSLATE_NOOP("MemoryCardSettingsWidget", "All Memory Card Types (*.mcd *.mcr *.mc)");
     24 
     25 MemoryCardSettingsWidget::MemoryCardSettingsWidget(SettingsWindow* dialog, QWidget* parent)
     26   : QWidget(parent), m_dialog(dialog)
     27 {
     28   createUi(dialog);
     29 }
     30 
     31 MemoryCardSettingsWidget::~MemoryCardSettingsWidget() = default;
     32 
     33 void MemoryCardSettingsWidget::createUi(SettingsWindow* dialog)
     34 {
     35   QVBoxLayout* layout = new QVBoxLayout(this);
     36   layout->setContentsMargins(0, 0, 0, 0);
     37 
     38   for (int i = 0; i < static_cast<int>(m_port_ui.size()); i++)
     39   {
     40     createPortSettingsUi(dialog, i, &m_port_ui[i]);
     41     layout->addWidget(m_port_ui[i].container);
     42   }
     43 
     44   {
     45     QGroupBox* box = new QGroupBox(tr("Shared Settings"), this);
     46     QVBoxLayout* box_layout = new QVBoxLayout(box);
     47     QPushButton* browse = new QPushButton(tr("Browse..."), box);
     48     QPushButton* open_memcards = new QPushButton(tr("Open..."), box);
     49     QPushButton* reset = new QPushButton(tr("Reset"), box);
     50 
     51     {
     52       QLabel* label = new QLabel(tr("Memory Card Directory:"), box);
     53       box_layout->addWidget(label);
     54 
     55       QHBoxLayout* hbox = new QHBoxLayout();
     56       m_memory_card_directory = new QLineEdit(box);
     57 
     58       hbox->addWidget(m_memory_card_directory);
     59       hbox->addWidget(browse);
     60       hbox->addWidget(open_memcards);
     61       hbox->addWidget(reset);
     62 
     63       box_layout->addLayout(hbox);
     64     }
     65 
     66     QCheckBox* playlist_title_as_game_title = new QCheckBox(tr("Use Single Card For Multi-Disc Games"), box);
     67     SettingWidgetBinder::BindWidgetToBoolSetting(m_dialog->getSettingsInterface(), playlist_title_as_game_title,
     68                                                  "MemoryCards", "UsePlaylistTitle", true);
     69     box_layout->addWidget(playlist_title_as_game_title);
     70     dialog->registerWidgetHelp(
     71       playlist_title_as_game_title, tr("Use Single Card For Multi-Disc Games"), tr("Checked"),
     72       tr("When playing a multi-disc game and using per-game (title) memory cards, a single memory card "
     73          "will be used for all discs. If unchecked, a separate card will be used for each disc."));
     74 
     75     box_layout->addWidget(QtUtils::CreateHorizontalLine(box));
     76 
     77     {
     78       QHBoxLayout* hbox = new QHBoxLayout();
     79       QLabel* label = new QLabel(
     80         tr("The memory card editor enables you to move saves between cards, as well as import cards of other formats."),
     81         box);
     82       label->setWordWrap(true);
     83       hbox->addWidget(label, 1);
     84 
     85       QPushButton* button = new QPushButton(tr("Memory Card Editor..."), box);
     86       connect(button, &QPushButton::clicked, []() { g_main_window->openMemoryCardEditor(QString(), QString()); });
     87       hbox->addWidget(button);
     88       box_layout->addLayout(hbox);
     89     }
     90 
     91     layout->addWidget(box);
     92 
     93     SettingWidgetBinder::BindWidgetToFolderSetting(
     94       m_dialog->getSettingsInterface(), m_memory_card_directory, browse, tr("Select Memory Card Directory"),
     95       open_memcards, reset, "MemoryCards", "Directory", Path::Combine(EmuFolders::DataRoot, "memcards"));
     96   }
     97 
     98   layout->addStretch(1);
     99 
    100   setLayout(layout);
    101 }
    102 
    103 void MemoryCardSettingsWidget::createPortSettingsUi(SettingsWindow* dialog, int index, PortSettingsUI* ui)
    104 {
    105   ui->container = new QGroupBox(tr("Memory Card %1").arg(index + 1), this);
    106   ui->layout = new QVBoxLayout(ui->container);
    107 
    108   ui->memory_card_type = new QComboBox(ui->container);
    109   for (int i = 0; i < static_cast<int>(MemoryCardType::Count); i++)
    110   {
    111     ui->memory_card_type->addItem(
    112       QString::fromUtf8(Settings::GetMemoryCardTypeDisplayName(static_cast<MemoryCardType>(i))));
    113   }
    114 
    115   const MemoryCardType default_value = (index == 0) ? MemoryCardType::PerGameTitle : MemoryCardType::None;
    116   SettingWidgetBinder::BindWidgetToEnumSetting(m_dialog->getSettingsInterface(), ui->memory_card_type, "MemoryCards",
    117                                                fmt::format("Card{}Type", index + 1), &Settings::ParseMemoryCardTypeName,
    118                                                &Settings::GetMemoryCardTypeName, default_value);
    119   ui->layout->addWidget(new QLabel(tr("Memory Card Type:"), ui->container));
    120   ui->layout->addWidget(ui->memory_card_type);
    121 
    122   QHBoxLayout* memory_card_layout = new QHBoxLayout();
    123   ui->memory_card_path = new QLineEdit(ui->container);
    124   updateMemoryCardPath(index);
    125   connect(ui->memory_card_path, &QLineEdit::textChanged, this, [this, index]() { onMemoryCardPathChanged(index); });
    126   if (ui->memory_card_path->text().isEmpty())
    127   {
    128     QSignalBlocker sb(ui->memory_card_path);
    129     ui->memory_card_path->setText(QString::fromStdString(g_settings.GetSharedMemoryCardPath(static_cast<u32>(index))));
    130   }
    131   memory_card_layout->addWidget(ui->memory_card_path);
    132 
    133   QPushButton* memory_card_path_browse = new QPushButton(tr("Browse..."), ui->container);
    134   connect(memory_card_path_browse, &QPushButton::clicked, this,
    135           [this, index]() { onBrowseMemoryCardPathClicked(index); });
    136   memory_card_layout->addWidget(memory_card_path_browse);
    137 
    138   QPushButton* memory_card_path_reset = new QPushButton(tr("Reset"), ui->container);
    139   connect(memory_card_path_reset, &QPushButton::clicked, this,
    140           [this, index]() { onResetMemoryCardPathClicked(index); });
    141   memory_card_layout->addWidget(memory_card_path_reset);
    142 
    143   ui->layout->addWidget(new QLabel(tr("Shared Memory Card Path:"), ui->container));
    144   ui->layout->addLayout(memory_card_layout);
    145 
    146   ui->layout->addStretch(1);
    147 }
    148 
    149 void MemoryCardSettingsWidget::onBrowseMemoryCardPathClicked(int index)
    150 {
    151   QString path = QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Select path to memory card image"),
    152                                                                        QString(), tr(MEMORY_CARD_IMAGE_FILTER)));
    153   if (path.isEmpty())
    154     return;
    155 
    156   m_port_ui[index].memory_card_path->setText(path);
    157 }
    158 
    159 void MemoryCardSettingsWidget::onMemoryCardPathChanged(int index)
    160 {
    161   const auto key = TinyString::from_format("Card{}Path", index + 1);
    162   std::string relative_path(
    163     Path::MakeRelative(m_port_ui[index].memory_card_path->text().toStdString(), EmuFolders::MemoryCards));
    164   m_dialog->setStringSettingValue("MemoryCards", key, relative_path.c_str());
    165 }
    166 
    167 void MemoryCardSettingsWidget::onResetMemoryCardPathClicked(int index)
    168 {
    169   const auto key = TinyString::from_format("Card{}Path", index + 1);
    170   if (m_dialog->isPerGameSettings())
    171     m_dialog->removeSettingValue("MemoryCards", key);
    172   else
    173     m_dialog->setStringSettingValue("MemoryCards", key, Settings::GetDefaultSharedMemoryCardName(index).c_str());
    174 
    175   updateMemoryCardPath(index);
    176 }
    177 
    178 void MemoryCardSettingsWidget::updateMemoryCardPath(int index)
    179 {
    180   const auto key = TinyString::from_format("Card{}Path", index + 1);
    181   std::string path(
    182     m_dialog->getEffectiveStringValue("MemoryCards", key, Settings::GetDefaultSharedMemoryCardName(index).c_str()));
    183   if (!Path::IsAbsolute(path))
    184     path = Path::Canonicalize(Path::Combine(EmuFolders::MemoryCards, path));
    185 
    186   QSignalBlocker db(m_port_ui[index].memory_card_path);
    187   m_port_ui[index].memory_card_path->setText(QString::fromStdString(path));
    188 }