mirror of https://github.com/PCSX2/pcsx2.git
Qt: Replace QTreeWidget with QTreeView for cheat list
This commit is contained in:
parent
47cf69d2b3
commit
d89b051e6d
|
@ -13,11 +13,22 @@
|
|||
|
||||
#include "common/HeterogeneousContainers.h"
|
||||
|
||||
#include <QtGui/QStandardItemModel>
|
||||
|
||||
GameCheatSettingsWidget::GameCheatSettingsWidget(SettingsWindow* dialog, QWidget* parent)
|
||||
: m_dialog(dialog)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
m_model = new QStandardItemModel(this);
|
||||
|
||||
QStringList headers;
|
||||
headers.push_back(tr("Name"));
|
||||
headers.push_back(tr("Author"));
|
||||
headers.push_back(tr("Description"));
|
||||
m_model->setHorizontalHeaderLabels(headers);
|
||||
|
||||
m_ui.cheatList->setModel(m_model);
|
||||
reloadList();
|
||||
|
||||
SettingsInterface* sif = m_dialog->getSettingsInterface();
|
||||
|
@ -26,8 +37,8 @@ GameCheatSettingsWidget::GameCheatSettingsWidget(SettingsWindow* dialog, QWidget
|
|||
updateListEnabled();
|
||||
|
||||
connect(m_ui.enableCheats, &QCheckBox::checkStateChanged, this, &GameCheatSettingsWidget::updateListEnabled);
|
||||
connect(m_ui.cheatList, &QTreeWidget::itemDoubleClicked, this, &GameCheatSettingsWidget::onCheatListItemDoubleClicked);
|
||||
connect(m_ui.cheatList, &QTreeWidget::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
|
||||
connect(m_ui.cheatList, &QTreeView::doubleClicked, this, &GameCheatSettingsWidget::onCheatListItemDoubleClicked);
|
||||
connect(m_model, &QStandardItemModel::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
|
||||
connect(m_ui.reloadCheats, &QPushButton::clicked, this, &GameCheatSettingsWidget::onReloadClicked);
|
||||
connect(m_ui.enableAll, &QPushButton::clicked, this, [this]() { setStateForAll(true); });
|
||||
connect(m_ui.disableAll, &QPushButton::clicked, this, [this]() { setStateForAll(false); });
|
||||
|
@ -39,28 +50,43 @@ GameCheatSettingsWidget::GameCheatSettingsWidget(SettingsWindow* dialog, QWidget
|
|||
|
||||
GameCheatSettingsWidget::~GameCheatSettingsWidget() = default;
|
||||
|
||||
void GameCheatSettingsWidget::onCheatListItemDoubleClicked(QTreeWidgetItem* item, int column)
|
||||
void GameCheatSettingsWidget::onCheatListItemDoubleClicked(const QModelIndex& index)
|
||||
{
|
||||
QVariant data = item->data(0, Qt::UserRole);
|
||||
QModelIndex sibling_index = index.sibling(index.row(), 0);
|
||||
QStandardItem* item = m_model->itemFromIndex(sibling_index);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (item->hasChildren() && index.column() != 0)
|
||||
{
|
||||
bool isExpanded = m_ui.cheatList->isExpanded(sibling_index);
|
||||
if (isExpanded)
|
||||
m_ui.cheatList->collapse(sibling_index);
|
||||
else
|
||||
m_ui.cheatList->expand(sibling_index);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariant data = item->data(Qt::UserRole);
|
||||
if (!data.isValid())
|
||||
return;
|
||||
|
||||
std::string cheat_name = data.toString().toStdString();
|
||||
const bool new_state = !(item->checkState(0) == Qt::Checked);
|
||||
item->setCheckState(0, new_state ? Qt::Checked : Qt::Unchecked);
|
||||
const bool new_state = !(item->checkState() == Qt::Checked);
|
||||
item->setCheckState(new_state ? Qt::Checked : Qt::Unchecked);
|
||||
setCheatEnabled(std::move(cheat_name), new_state, true);
|
||||
}
|
||||
|
||||
void GameCheatSettingsWidget::onCheatListItemChanged(QTreeWidgetItem* item, int column)
|
||||
void GameCheatSettingsWidget::onCheatListItemChanged(QStandardItem* item)
|
||||
{
|
||||
QVariant data = item->data(0, Qt::UserRole);
|
||||
QVariant data = item->data(Qt::UserRole);
|
||||
if (!data.isValid())
|
||||
return;
|
||||
|
||||
std::string cheat_name = data.toString().toStdString();
|
||||
const bool current_enabled =
|
||||
(std::find(m_enabled_patches.begin(), m_enabled_patches.end(), cheat_name) != m_enabled_patches.end());
|
||||
const bool current_checked = (item->checkState(0) == Qt::Checked);
|
||||
const bool current_checked = (item->checkState() == Qt::Checked);
|
||||
if (current_enabled == current_checked)
|
||||
return;
|
||||
|
||||
|
@ -125,24 +151,28 @@ void GameCheatSettingsWidget::setCheatEnabled(std::string name, bool enabled, bo
|
|||
|
||||
void GameCheatSettingsWidget::setStateForAll(bool enabled)
|
||||
{
|
||||
QSignalBlocker sb(m_ui.cheatList);
|
||||
// Temporarily disconnect from itemChanged to prevent redundant saves
|
||||
disconnect(m_model, &QStandardItemModel::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
|
||||
|
||||
setStateRecursively(nullptr, enabled);
|
||||
m_dialog->getSettingsInterface()->Save();
|
||||
g_emu_thread->reloadGameSettings();
|
||||
|
||||
connect(m_model, &QStandardItemModel::itemChanged, this, &GameCheatSettingsWidget::onCheatListItemChanged);
|
||||
}
|
||||
|
||||
void GameCheatSettingsWidget::setStateRecursively(QTreeWidgetItem* parent, bool enabled)
|
||||
void GameCheatSettingsWidget::setStateRecursively(QStandardItem* parent, bool enabled)
|
||||
{
|
||||
const int count = parent ? parent->childCount() : m_ui.cheatList->topLevelItemCount();
|
||||
const int count = parent ? parent->rowCount() : m_model->rowCount();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QTreeWidgetItem* item = parent ? parent->child(i) : m_ui.cheatList->topLevelItem(i);
|
||||
QVariant data = item->data(0, Qt::UserRole);
|
||||
QStandardItem* item = parent ? parent->child(i, 0) : m_model->item(i, 0);
|
||||
QVariant data = item->data(Qt::UserRole);
|
||||
if (data.isValid())
|
||||
{
|
||||
if ((item->checkState(0) == Qt::Checked) != enabled)
|
||||
if ((item->checkState() == Qt::Checked) != enabled)
|
||||
{
|
||||
item->setCheckState(0, enabled ? Qt::Checked : Qt::Unchecked);
|
||||
item->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
|
||||
setCheatEnabled(data.toString().toStdString(), enabled, false);
|
||||
}
|
||||
}
|
||||
|
@ -162,8 +192,7 @@ void GameCheatSettingsWidget::reloadList()
|
|||
m_dialog->getSettingsInterface()->GetStringList(Patch::CHEATS_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY);
|
||||
|
||||
m_parent_map.clear();
|
||||
while (m_ui.cheatList->topLevelItemCount() > 0)
|
||||
delete m_ui.cheatList->takeTopLevelItem(0);
|
||||
m_model->removeRows(0, m_model->rowCount());
|
||||
|
||||
for (const Patch::PatchInfo& pi : m_patches)
|
||||
{
|
||||
|
@ -171,14 +200,12 @@ void GameCheatSettingsWidget::reloadList()
|
|||
(std::find(m_enabled_patches.begin(), m_enabled_patches.end(), pi.name) != m_enabled_patches.end());
|
||||
|
||||
const std::string_view parent_part = pi.GetNameParentPart();
|
||||
|
||||
QTreeWidgetItem* parent = getTreeWidgetParent(parent_part);
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
populateTreeWidgetItem(item, pi, enabled);
|
||||
QStandardItem* parent = getTreeViewParent(parent_part);
|
||||
QList<QStandardItem*> items = populateTreeViewRow(pi, enabled);
|
||||
if (parent)
|
||||
parent->addChild(item);
|
||||
parent->appendRow(items);
|
||||
else
|
||||
m_ui.cheatList->addTopLevelItem(item);
|
||||
m_model->appendRow(items);
|
||||
}
|
||||
|
||||
// Hide root indicator when there's no groups, frees up some whitespace.
|
||||
|
@ -186,13 +213,13 @@ void GameCheatSettingsWidget::reloadList()
|
|||
|
||||
if (num_unlabelled_codes > 0)
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
item->setText(0, tr("%1 unlabelled patch codes will automatically activate.").arg(num_unlabelled_codes));
|
||||
m_ui.cheatList->addTopLevelItem(item);
|
||||
QStandardItem* item = new QStandardItem();
|
||||
item->setText(tr("%1 unlabelled patch codes will automatically activate.").arg(num_unlabelled_codes));
|
||||
m_model->appendRow(item);
|
||||
}
|
||||
}
|
||||
|
||||
QTreeWidgetItem* GameCheatSettingsWidget::getTreeWidgetParent(const std::string_view parent)
|
||||
QStandardItem* GameCheatSettingsWidget::getTreeViewParent(const std::string_view parent)
|
||||
{
|
||||
if (parent.empty())
|
||||
return nullptr;
|
||||
|
@ -202,37 +229,45 @@ QTreeWidgetItem* GameCheatSettingsWidget::getTreeWidgetParent(const std::string_
|
|||
return it->second;
|
||||
|
||||
std::string_view this_part = parent;
|
||||
QTreeWidgetItem* parent_to_this = nullptr;
|
||||
QStandardItem* parent_to_this = nullptr;
|
||||
const std::string_view::size_type pos = parent.rfind('\\');
|
||||
if (pos != std::string::npos && pos != (parent.size() - 1))
|
||||
{
|
||||
// go up the chain until we find the real parent, then back down
|
||||
parent_to_this = getTreeWidgetParent(parent.substr(0, pos));
|
||||
parent_to_this = getTreeViewParent(parent.substr(0, pos));
|
||||
this_part = parent.substr(pos + 1);
|
||||
}
|
||||
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
item->setText(0, QString::fromUtf8(this_part.data(), this_part.length()));
|
||||
QStandardItem* item = new QStandardItem();
|
||||
item->setText(QString::fromUtf8(this_part.data(), this_part.length()));
|
||||
|
||||
if (parent_to_this)
|
||||
parent_to_this->addChild(item);
|
||||
parent_to_this->appendRow(item);
|
||||
else
|
||||
m_ui.cheatList->addTopLevelItem(item);
|
||||
m_model->appendRow(item);
|
||||
|
||||
// Must be called after adding.
|
||||
item->setExpanded(true);
|
||||
m_ui.cheatList->expand(item->index());
|
||||
m_parent_map.emplace(parent, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
void GameCheatSettingsWidget::populateTreeWidgetItem(QTreeWidgetItem* item, const Patch::PatchInfo& pi, bool enabled)
|
||||
QList<QStandardItem*> GameCheatSettingsWidget::populateTreeViewRow(const Patch::PatchInfo& pi, bool enabled)
|
||||
{
|
||||
QList<QStandardItem*> items;
|
||||
|
||||
QStandardItem* nameItem = new QStandardItem();
|
||||
const std::string_view name_part = pi.GetNamePart();
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren);
|
||||
item->setCheckState(0, enabled ? Qt::Checked : Qt::Unchecked);
|
||||
item->setData(0, Qt::UserRole, QString::fromStdString(pi.name));
|
||||
nameItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemNeverHasChildren | Qt::ItemIsEnabled);
|
||||
nameItem->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
|
||||
nameItem->setData(QString::fromStdString(pi.name), Qt::UserRole);
|
||||
if (!name_part.empty())
|
||||
item->setText(0, QString::fromUtf8(name_part.data(), name_part.length()));
|
||||
item->setText(1, QString::fromStdString(pi.author));
|
||||
item->setText(2, QString::fromStdString(pi.description));
|
||||
nameItem->setText(QString::fromUtf8(name_part.data(), name_part.length()));
|
||||
|
||||
QStandardItem* authorItem = new QStandardItem(QString::fromStdString(pi.author));
|
||||
QStandardItem* descriptionItem = new QStandardItem(QString::fromStdString(pi.description));
|
||||
|
||||
items.push_back(nameItem);
|
||||
items.push_back(authorItem);
|
||||
items.push_back(descriptionItem);
|
||||
return items;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QtGui/QStandardItemModel>
|
||||
|
||||
#include "ui_GameCheatSettingsWidget.h"
|
||||
|
||||
|
@ -36,23 +36,24 @@ protected:
|
|||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onCheatListItemDoubleClicked(QTreeWidgetItem* item, int column);
|
||||
void onCheatListItemChanged(QTreeWidgetItem* item, int column);
|
||||
void onCheatListItemDoubleClicked(const QModelIndex& index);
|
||||
void onCheatListItemChanged(QStandardItem* item);
|
||||
void onReloadClicked();
|
||||
void updateListEnabled();
|
||||
void reloadList();
|
||||
|
||||
private:
|
||||
QTreeWidgetItem* getTreeWidgetParent(const std::string_view parent);
|
||||
void populateTreeWidgetItem(QTreeWidgetItem* item, const Patch::PatchInfo& pi, bool enabled);
|
||||
QStandardItem* getTreeViewParent(const std::string_view parent);
|
||||
QList<QStandardItem*> populateTreeViewRow(const Patch::PatchInfo& pi, bool enabled);
|
||||
void setCheatEnabled(std::string name, bool enabled, bool save_and_reload_settings);
|
||||
void setStateForAll(bool enabled);
|
||||
void setStateRecursively(QTreeWidgetItem* parent, bool enabled);
|
||||
void setStateRecursively(QStandardItem* parent, bool enabled);
|
||||
|
||||
Ui::GameCheatSettingsWidget m_ui;
|
||||
SettingsWindow* m_dialog;
|
||||
QStandardItemModel* m_model = nullptr;
|
||||
|
||||
UnorderedStringMap<QTreeWidgetItem*> m_parent_map;
|
||||
UnorderedStringMap<QStandardItem*> m_parent_map;
|
||||
std::vector<Patch::PatchInfo> m_patches;
|
||||
std::vector<std::string> m_enabled_patches;
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="cheatList">
|
||||
<widget class="QTreeView" name="cheatList">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
|
@ -51,21 +51,6 @@
|
|||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Author</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
Loading…
Reference in New Issue