dolphin/Source/Core/DolphinQt2/Config/ARCodeWidget.cpp

183 lines
4.7 KiB
C++

// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "DolphinQt2/Config/ARCodeWidget.h"
#include <QButtonGroup>
#include <QHBoxLayout>
#include <QListWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Core/ActionReplay.h"
#include "Core/ConfigManager.h"
#include "DolphinQt2/Config/CheatCodeEditor.h"
#include "DolphinQt2/Config/CheatWarningWidget.h"
#include "UICommon/GameFile.h"
ARCodeWidget::ARCodeWidget(const UICommon::GameFile& game)
: m_game(game), m_game_id(game.GetGameID()), m_game_revision(game.GetRevision())
{
CreateWidgets();
ConnectWidgets();
IniFile game_ini_local;
// We don't use LoadLocalGameIni() here because user cheat codes that are installed via the UI
// will always be stored in GS/${GAMEID}.ini
game_ini_local.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + m_game_id + ".ini");
IniFile game_ini_default = SConfig::GetInstance().LoadDefaultGameIni(m_game_id, m_game_revision);
m_ar_codes = ActionReplay::LoadCodes(game_ini_default, game_ini_local);
UpdateList();
OnSelectionChanged();
}
void ARCodeWidget::CreateWidgets()
{
m_warning = new CheatWarningWidget(m_game_id);
m_code_list = new QListWidget;
m_code_add = new QPushButton(tr("&Add New Code..."));
m_code_edit = new QPushButton(tr("&Edit Code..."));
m_code_remove = new QPushButton(tr("&Remove Code"));
auto* button_layout = new QHBoxLayout;
button_layout->addWidget(m_code_add);
button_layout->addWidget(m_code_edit);
button_layout->addWidget(m_code_remove);
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(m_warning);
layout->addWidget(m_code_list);
layout->addLayout(button_layout);
setLayout(layout);
}
void ARCodeWidget::ConnectWidgets()
{
connect(m_warning, &CheatWarningWidget::OpenCheatEnableSettings, this,
&ARCodeWidget::OpenGeneralSettings);
connect(m_code_list, &QListWidget::itemChanged, this, &ARCodeWidget::OnItemChanged);
connect(m_code_list, &QListWidget::itemSelectionChanged, this, &ARCodeWidget::OnSelectionChanged);
connect(m_code_add, &QPushButton::pressed, this, &ARCodeWidget::OnCodeAddPressed);
connect(m_code_edit, &QPushButton::pressed, this, &ARCodeWidget::OnCodeEditPressed);
connect(m_code_remove, &QPushButton::pressed, this, &ARCodeWidget::OnCodeRemovePressed);
}
void ARCodeWidget::OnItemChanged(QListWidgetItem* item)
{
m_ar_codes[m_code_list->row(item)].active = (item->checkState() == Qt::Checked);
SaveCodes();
}
void ARCodeWidget::OnSelectionChanged()
{
auto items = m_code_list->selectedItems();
if (items.empty())
return;
const auto* selected = items[0];
bool user_defined = m_ar_codes[m_code_list->row(selected)].user_defined;
m_code_remove->setEnabled(user_defined);
m_code_edit->setText(user_defined ? tr("&Edit Code...") : tr("Clone and &Edit Code..."));
}
void ARCodeWidget::UpdateList()
{
m_code_list->clear();
for (const auto& ar : m_ar_codes)
{
auto* item = new QListWidgetItem(QString::fromStdString(ar.name)
.replace(QStringLiteral("&lt;"), QStringLiteral("<"))
.replace(QStringLiteral("&gt;"), QStringLiteral(">")));
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
item->setCheckState(ar.active ? Qt::Checked : Qt::Unchecked);
m_code_list->addItem(item);
}
}
void ARCodeWidget::SaveCodes()
{
IniFile game_ini_local;
game_ini_local.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + m_game_id + ".ini");
ActionReplay::SaveCodes(&game_ini_local, m_ar_codes);
game_ini_local.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + m_game_id + ".ini");
}
void ARCodeWidget::OnCodeAddPressed()
{
ActionReplay::ARCode ar;
ar.active = true;
CheatCodeEditor ed;
ed.SetARCode(&ar);
if (ed.exec())
{
m_ar_codes.push_back(std::move(ar));
UpdateList();
SaveCodes();
}
}
void ARCodeWidget::OnCodeEditPressed()
{
auto items = m_code_list->selectedItems();
if (items.empty())
return;
const auto* selected = items[0];
auto& current_ar = m_ar_codes[m_code_list->row(selected)];
bool user_defined = current_ar.user_defined;
ActionReplay::ARCode ar = current_ar;
CheatCodeEditor ed;
ed.SetARCode(user_defined ? &current_ar : &ar);
ed.exec();
if (!user_defined)
m_ar_codes.push_back(ar);
SaveCodes();
UpdateList();
}
void ARCodeWidget::OnCodeRemovePressed()
{
auto items = m_code_list->selectedItems();
if (items.empty())
return;
const auto* selected = items[0];
m_ar_codes.erase(m_ar_codes.begin() + m_code_list->row(selected));
SaveCodes();
UpdateList();
m_code_remove->setEnabled(false);
}