mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 09:39:55 +00:00
214 lines
4.6 KiB
C++
214 lines
4.6 KiB
C++
#include "stdafx.h"
|
|
#include "config_checker.h"
|
|
#include "Emu/system_config.h"
|
|
|
|
#include <QDialog>
|
|
#include <QDialogButtonBox>
|
|
#include <QMessageBox>
|
|
#include <QTextEdit>
|
|
#include <QVBoxLayout>
|
|
#include <QLabel>
|
|
|
|
LOG_CHANNEL(gui_log, "GUI");
|
|
|
|
config_checker::config_checker(QWidget* parent, const QString& content, bool is_log) : QDialog(parent)
|
|
{
|
|
setObjectName("config_checker");
|
|
setAttribute(Qt::WA_DeleteOnClose);
|
|
|
|
QVBoxLayout* layout = new QVBoxLayout();
|
|
QLabel* label = new QLabel(this);
|
|
layout->addWidget(label);
|
|
|
|
QString result;
|
|
|
|
if (check_config(content, result, is_log))
|
|
{
|
|
setWindowTitle(tr("Interesting!"));
|
|
|
|
if (result.isEmpty())
|
|
{
|
|
label->setText(tr("Found config.\nIt seems to match the default config."));
|
|
}
|
|
else
|
|
{
|
|
label->setText(tr("Found config.\nSome settings seem to deviate from the default config:"));
|
|
|
|
QTextEdit* text_box = new QTextEdit();
|
|
text_box->setReadOnly(true);
|
|
text_box->setHtml(result);
|
|
layout->addWidget(text_box);
|
|
|
|
resize(400, 600);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
setWindowTitle(tr("Ooops!"));
|
|
label->setText(result);
|
|
}
|
|
|
|
QDialogButtonBox* box = new QDialogButtonBox(QDialogButtonBox::Close);
|
|
connect(box, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
|
layout->addWidget(box);
|
|
|
|
setLayout(layout);
|
|
}
|
|
|
|
bool config_checker::check_config(QString content, QString& result, bool is_log)
|
|
{
|
|
cfg_root config{};
|
|
|
|
if (is_log)
|
|
{
|
|
const QString start_token = "SYS: Used configuration:\n";
|
|
const QString end_token = "\n·";
|
|
|
|
qsizetype start = content.indexOf(start_token);
|
|
qsizetype end = -1;
|
|
|
|
if (start >= 0)
|
|
{
|
|
start += start_token.size();
|
|
end = content.indexOf(end_token, start);
|
|
}
|
|
|
|
if (end < 0)
|
|
{
|
|
result = tr("Cannot find any config!");
|
|
return false;
|
|
}
|
|
|
|
content = content.mid(start, end - start);
|
|
}
|
|
|
|
if (!config.from_string(content.toStdString()))
|
|
{
|
|
gui_log.error("log_viewer: Failed to parse config:\n%s", content);
|
|
result = tr("Cannot find any config!");
|
|
return false;
|
|
}
|
|
|
|
std::function<void(const cfg::_base*, std::string&, int)> print_diff_recursive;
|
|
print_diff_recursive = [&print_diff_recursive](const cfg::_base* base, std::string& diff, int indentation) -> void
|
|
{
|
|
if (!base)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const auto indent = [](std::string& str, int indentation)
|
|
{
|
|
for (int i = 0; i < indentation * 2; i++)
|
|
{
|
|
str += " ";
|
|
}
|
|
};
|
|
|
|
switch (base->get_type())
|
|
{
|
|
case cfg::type::node:
|
|
{
|
|
if (const auto& node = static_cast<const cfg::node*>(base))
|
|
{
|
|
std::string diff_tmp;
|
|
|
|
for (const auto& n : node->get_nodes())
|
|
{
|
|
print_diff_recursive(n, diff_tmp, indentation + 1);
|
|
}
|
|
|
|
if (!diff_tmp.empty())
|
|
{
|
|
indent(diff, indentation);
|
|
|
|
if (!base->get_name().empty())
|
|
{
|
|
fmt::append(diff, "<b>%s:</b><br>", base->get_name());
|
|
}
|
|
|
|
fmt::append(diff, "%s", diff_tmp);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case cfg::type::_bool:
|
|
case cfg::type::_enum:
|
|
case cfg::type::_int:
|
|
case cfg::type::uint:
|
|
case cfg::type::string:
|
|
{
|
|
const std::string val = base->to_string();
|
|
const std::string def = base->def_to_string();
|
|
|
|
if (val != def)
|
|
{
|
|
indent(diff, indentation);
|
|
|
|
if (def.empty())
|
|
{
|
|
fmt::append(diff, "%s: <span style=\"color:red;\">%s</span><br>", base->get_name(), val);
|
|
}
|
|
else
|
|
{
|
|
fmt::append(diff, "%s: <span style=\"color:red;\">%s</span> <span style=\"color:gray;\">default:</span> <span style=\"color:green;\">%s</span><br>", base->get_name(), val, def);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case cfg::type::set:
|
|
{
|
|
if (const auto& node = static_cast<const cfg::set_entry*>(base))
|
|
{
|
|
const std::vector<std::string> set_entries = node->to_list();
|
|
|
|
if (!set_entries.empty())
|
|
{
|
|
indent(diff, indentation);
|
|
fmt::append(diff, "<b>%s:</b><br>", base->get_name());
|
|
|
|
for (const std::string& entry : set_entries)
|
|
{
|
|
indent(diff, indentation + 1);
|
|
fmt::append(diff, "- <span style=\"color:red;\">%s</span><br>", entry);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case cfg::type::log:
|
|
{
|
|
if (const auto& node = static_cast<const cfg::log_entry*>(base))
|
|
{
|
|
const auto& log_entries = node->get_map();
|
|
|
|
if (!log_entries.empty())
|
|
{
|
|
indent(diff, indentation);
|
|
fmt::append(diff, "<b>%s:</b><br>", base->get_name());
|
|
|
|
for (const auto& entry : log_entries)
|
|
{
|
|
indent(diff, indentation + 1);
|
|
fmt::append(diff, "<span style=\"color:red;\">%s: %s</span><br>", entry.first, entry.second);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case cfg::type::map:
|
|
case cfg::type::device:
|
|
{
|
|
// Ignored
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
std::string diff;
|
|
print_diff_recursive(&config, diff, 0);
|
|
result = QString::fromStdString(diff);
|
|
|
|
return true;
|
|
}
|