Files
RMG/Source/RMG/UserInterface/Dialog/Cheats/CheatsDialog.cpp
T

325 lines
8.6 KiB
C++

/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <rosalie@mailbox.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "CheatsDialog.hpp"
#include "AddCheatDialog.hpp"
#include "ChooseCheatOptionDialog.hpp"
#include "Utilities/QtMessageBox.hpp"
#include <QFileInfo>
#include <RMG-Core/Core.hpp>
Q_DECLARE_METATYPE(CoreCheat);
using namespace UserInterface::Dialog;
using namespace Utilities;
CheatsDialog::CheatsDialog(QWidget *parent) : QDialog(parent)
{
qRegisterMetaType<CoreCheat>();
this->setupUi(this);
this->loadCheats();
}
CheatsDialog::~CheatsDialog(void)
{
}
bool CheatsDialog::HasFailed(void)
{
return this->failedToParseCheats;
}
void CheatsDialog::loadCheats(void)
{
std::vector<CoreCheat> cheats;
// reset tree widget
this->cheatsTreeWidget->clear();
if (!CoreGetCurrentCheats(cheats))
{
QtMessageBox::Error(this, "CoreGetCurrentCheats() Failed", QString::fromStdString(CoreGetError()));
this->failedToParseCheats = true;
return;
}
for (CoreCheat& cheat : cheats)
{
QString name = QString::fromStdString(cheat.Name);
QString section;
QStringList sections = name.split("\\");
bool enabled = CoreIsCheatEnabled(cheat);
for (int i = 0; i < sections.size(); i++)
{
section = sections.at(i);
// when item already exists,
// we don't need to add it anymore
QTreeWidgetItem* foundItem = this->findItem(sections, i, section);
if (foundItem != nullptr)
{
continue;
}
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0, section);
// if at the last item,
// add the cheat as data
// and make it a checkbox
if (i == (sections.size() - 1))
{
item->setText(0, this->getTreeWidgetItemTextFromCheat(cheat));
item->setCheckState(0, (enabled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked));
item->setData(0, Qt::UserRole, QVariant::fromValue(cheat));
}
if (i == 0)
{
this->cheatsTreeWidget->addTopLevelItem(item);
}
else
{
QTreeWidgetItem* foundParent = this->findItem(sections, i - 1, sections.at(i - 1));
if (foundParent != nullptr)
{
foundParent->addChild(item);
}
else
{
delete item;
}
// when the cheat is enabled & we're at the last item,
// expand each parent
if (i == (sections.size() - 1) && enabled)
{
QTreeWidgetItem* parent = foundParent;
while (parent != nullptr)
{
parent->setExpanded(true);
parent = parent->parent();
}
}
}
}
}
this->cheatsTreeWidget->sortItems(0, Qt::SortOrder::AscendingOrder);
}
QTreeWidgetItem* CheatsDialog::findItem(QStringList sections, int size, QString itemText)
{
QTreeWidgetItem* parent;
bool foundItem = false;
QList<QTreeWidgetItem*> foundItems = this->cheatsTreeWidget->findItems(itemText, Qt::MatchExactly | Qt::MatchRecursive, 0);
// loop over all the found items,
// then loop over all the parents
// to make sure they match aswell
for (auto& item : foundItems)
{
parent = item;
foundItem = true;
for (int i = size; i >= 0; i--)
{
// make sure the parent matches
if (parent == nullptr || parent->text(0) != sections.at(i))
{
foundItem = false;
break;
}
// make sure that when there are no sections left,
// that there are no more parents either
if (i == 0 && parent->parent() != nullptr)
{
foundItem = false;
break;
}
parent = parent->parent();
}
// when we've found the item,
// return it
if (foundItem)
{
return item;
}
}
return nullptr;
}
QString CheatsDialog::getTreeWidgetItemTextFromCheat(CoreCheat cheat)
{
QString cheatName = QString::fromStdString(cheat.Name).split('\\').last();
QString text;
if (cheat.HasOptions)
{
CoreCheatOption cheatOption;
if (!CoreHasCheatOptionSet(cheat) || !CoreGetCheatOption(cheat, cheatOption))
{
text = cheatName + " (=> ???? - Not Set)";
}
else
{
text = cheatName + " (=> ";
text += QString::fromStdString(cheatOption.Name);
text += ")";
}
}
else
{
text = cheatName;
}
return text;
}
void CheatsDialog::on_cheatsTreeWidget_itemChanged(QTreeWidgetItem *item, int column)
{
if (item == nullptr || item->data(column, Qt::UserRole).isNull())
{
return;
}
CoreCheat cheat = item->data(column, Qt::UserRole).value<CoreCheat>();
bool enabled = (item->checkState(column) == Qt::CheckState::Checked);
if (enabled && cheat.HasOptions && !CoreHasCheatOptionSet(cheat))
{
// ask user to select an option
this->on_cheatsTreeWidget_itemDoubleClicked(item, column);
// make sure the user selected an option,
// if they did then enable the cheat as requested,
// if not, reset the checkbox
if (!CoreHasCheatOptionSet(cheat))
{
item->setCheckState(0, Qt::CheckState::Unchecked);
return;
}
}
CoreEnableCheat(cheat, enabled);
}
void CheatsDialog::on_cheatsTreeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
if (current == nullptr || current->data(0, Qt::UserRole).isNull())
{ // we can't edit/remove a section
this->removeCheatButton->setEnabled(false);
this->editCheatButton->setEnabled(false);
this->notesTextEdit->setPlainText("");
return;
}
CoreCheat cheat = current->data(0, Qt::UserRole).value<CoreCheat>();
this->removeCheatButton->setEnabled(CoreCanRemoveCheat(cheat));
this->editCheatButton->setEnabled(true);
this->notesTextEdit->setPlainText(QString::fromStdString(cheat.Note));
}
void CheatsDialog::on_cheatsTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
if (item == nullptr || item->data(column, Qt::UserRole).isNull())
{
return;
}
CoreCheat cheat = item->data(column, Qt::UserRole).value<CoreCheat>();
if (!cheat.HasOptions)
{
return;
}
Dialog::ChooseCheatOptionDialog dialog(cheat, this);
dialog.exec();
// re-load cheat options
item->setText(column, this->getTreeWidgetItemTextFromCheat(cheat));
}
void CheatsDialog::on_addCheatButton_clicked(void)
{
AddCheatDialog dialog(this);
dialog.exec();
// re-load cheats
this->loadCheats();
}
void CheatsDialog::on_editCheatButton_clicked(void)
{
QTreeWidgetItem* item = this->cheatsTreeWidget->currentItem();
if (item == nullptr || item->data(0, Qt::UserRole).isNull())
{
return;
}
CoreCheat cheat = item->data(0, Qt::UserRole).value<CoreCheat>();
AddCheatDialog dialog(this);
dialog.SetCheat(cheat);
int ret = dialog.exec();
if (ret == QDialog::Accepted)
{
// re-load cheats
this->loadCheats();
}
}
void CheatsDialog::on_removeCheatButton_clicked(void)
{
QTreeWidgetItem* item = this->cheatsTreeWidget->currentItem();
if (item == nullptr || item->data(0, Qt::UserRole).isNull())
{
return;
}
CoreCheat cheat = item->data(0, Qt::UserRole).value<CoreCheat>();
// try to remove cheat
if (!CoreRemoveCheat(cheat))
{
QtMessageBox::Error(this, "CoreRemoveCheat() Failed", QString::fromStdString(CoreGetError()));
return;
}
// re-load cheats
this->loadCheats();
}
void CheatsDialog::accept(void)
{
CoreSettingsSave();
if (!CoreApplyCheats())
{
QtMessageBox::Error(this, "CoreApplyCheats() Failed", QString::fromStdString(CoreGetError()));
return;
}
QDialog::accept();
}