1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-23 20:47:45 +00:00
novus/parts/exd/exdpart.cpp

248 lines
9.1 KiB
C++
Raw Normal View History

// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#include "exdpart.h"
2024-02-04 15:23:24 -05:00
#include <KLocalizedString>
2023-09-23 14:09:00 -04:00
#include <QFile>
#include <QGroupBox>
#include <QJsonArray>
2023-09-23 14:09:00 -04:00
#include <QJsonDocument>
#include <QJsonObject>
#include <QLabel>
#include <QTableWidget>
#include <QVBoxLayout>
#include <physis.hpp>
EXDPart::EXDPart(GameData *data, QWidget *parent)
: QWidget(parent)
, data(data)
{
auto layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
// TODO: This information should really be somewhere else
/*auto headerBox = new QGroupBox(QStringLiteral("Header"));
layout->addWidget(headerBox);
headerFormLayout = new QFormLayout();
headerBox->setLayout(headerFormLayout);*/
pageTabWidget = new QTabWidget();
pageTabWidget->setTabPosition(QTabWidget::TabPosition::South);
pageTabWidget->setDocumentMode(true); // hide borders
layout->addWidget(pageTabWidget);
}
void EXDPart::loadSheet(const QString &name, physis_Buffer buffer, const QString &definitionPath)
{
pageTabWidget->clear();
QFile definitionFile(definitionPath);
2023-09-23 14:09:00 -04:00
definitionFile.open(QIODevice::ReadOnly);
QJsonArray definitionList;
if (definitionFile.isOpen()) {
auto document = QJsonDocument::fromJson(definitionFile.readAll());
definitionList = document.object()[QLatin1String("definitions")].toArray();
2023-09-23 14:09:00 -04:00
for (auto definition : definitionList) {
if (definition.toObject().contains(QLatin1String("converter"))
&& definition.toObject()[QLatin1String("converter")].toObject()[QLatin1String("type")].toString() == QStringLiteral("link")) {
auto linkName = definition.toObject()[QLatin1String("converter")].toObject()[QLatin1String("target")].toString();
2023-09-23 14:09:00 -04:00
auto path = QStringLiteral("exd/%1.exh").arg(linkName.toLower());
auto pathStd = path.toStdString();
auto file = physis_gamedata_extract_file(data, pathStd.c_str());
auto linkExh = physis_parse_excel_sheet_header(file);
auto linkExd = physis_gamedata_read_excel_sheet(data, linkName.toStdString().c_str(), linkExh, getSuitableLanguage(linkExh), 0);
2023-09-23 14:09:00 -04:00
if (linkExd.p_ptr != nullptr) {
cachedExcelSheets[linkName] = CachedExcel{linkExh, linkExd};
}
2023-09-23 14:09:00 -04:00
}
}
}
auto exh = physis_parse_excel_sheet_header(buffer);
// ditto
/*QLayoutItem *child;
while ((child = headerFormLayout->takeAt(0)) != nullptr) {
delete child->widget();
delete child;
}
headerFormLayout->addRow(QStringLiteral("Num Rows"), new QLabel(QString::number(exh->row_count)));
headerFormLayout->addRow(QStringLiteral("Num Columns"), new QLabel(QString::number(exh->column_count)));
headerFormLayout->addRow(QStringLiteral("Num Pages"), new QLabel(QString::number(exh->page_count)));
headerFormLayout->addRow(QStringLiteral("Num Languages"), new QLabel(QString::number(exh->language_count)));*/
2023-12-09 22:35:59 -05:00
for (uint32_t i = 0; i < exh->page_count; i++) {
2023-09-23 14:09:00 -04:00
auto tableWidget = new QTableWidget();
2023-07-08 10:18:07 -04:00
tableWidget->setColumnCount(exh->column_count);
2023-10-12 21:43:36 -04:00
tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
2023-09-23 14:09:00 -04:00
auto exd = physis_gamedata_read_excel_sheet(data, name.toStdString().c_str(), exh, getSuitableLanguage(exh), i);
2025-03-23 19:55:28 -04:00
tableWidget->setRowCount(exh->row_count);
2023-12-09 22:35:59 -05:00
for (unsigned int z = 0; z < exd.column_count; z++) {
2025-03-23 19:55:28 -04:00
auto columnData = exh->column_types[z];
2023-09-23 14:09:00 -04:00
QString columnType;
2025-03-23 19:55:28 -04:00
switch (columnData) {
case ColumnDataType::String:
2024-02-04 15:23:24 -05:00
columnType = i18n("String");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::Bool:
2024-02-04 15:23:24 -05:00
columnType = i18n("Bool");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::Int8:
2024-02-04 15:23:24 -05:00
columnType = i18n("Int8");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::UInt8:
2024-02-04 15:23:24 -05:00
columnType = i18n("UInt8");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::Int16:
2024-02-04 15:23:24 -05:00
columnType = i18n("Int16");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::UInt16:
2024-02-04 15:23:24 -05:00
columnType = i18n("UInt16");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::Int32:
2024-02-04 15:23:24 -05:00
columnType = i18n("Int32");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::UInt32:
2024-02-04 15:23:24 -05:00
columnType = i18n("UInt32");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::Float32:
2024-02-04 15:23:24 -05:00
columnType = i18n("Float32");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::Int64:
2024-02-04 15:23:24 -05:00
columnType = i18n("Int64");
2023-09-26 00:37:55 -04:00
break;
2025-03-23 19:55:28 -04:00
case ColumnDataType::UInt64:
2024-02-04 15:23:24 -05:00
columnType = i18n("UInt64");
2023-09-26 00:37:55 -04:00
break;
2023-09-23 14:09:00 -04:00
}
// TODO: index could be different
2024-05-10 16:37:10 -04:00
if (z < definitionList.size()) {
columnType = definitionList[z].toObject()[QLatin1String("name")].toString();
}
2023-09-23 14:09:00 -04:00
auto headerItem = new QTableWidgetItem();
headerItem->setText(columnType);
tableWidget->setHorizontalHeaderItem(z, headerItem);
}
2025-03-23 19:55:28 -04:00
for (unsigned int j = 0; j < exh->row_count; j++) {
auto rows = physis_exd_read_row(&exd, exh, j); // TODO: free, use other rows
2023-12-09 22:35:59 -05:00
for (unsigned int z = 0; z < exd.column_count; z++) {
2025-03-23 19:55:28 -04:00
auto columnData = rows.row_data[0].column_data[z];
auto [columnString, columnRow] = getColumnData(columnData);
2024-05-10 16:37:10 -04:00
if (z < definitionList.size()) {
auto definition = definitionList[z].toObject();
if (definition.contains(QLatin1String("converter"))
&& definition[QLatin1String("converter")].toObject()[QLatin1String("type")].toString() == QLatin1String("link")) {
2023-09-26 00:37:55 -04:00
auto linkName = definition[QLatin1String("converter")].toObject()[QLatin1String("target")].toString();
if (cachedExcelSheets.contains(linkName)) {
auto cachedExcel = cachedExcelSheets[linkName];
2025-03-23 19:55:28 -04:00
if (static_cast<unsigned int>(columnRow) < cachedExcel.exh->row_count) {
// TODO: add back
2025-03-23 19:55:28 -04:00
// auto [colString, _] = getColumnData(*cachedExcel.exh->row_data[columnRow].column_data);
// columnString = colString;
2023-09-26 00:37:55 -04:00
}
2023-09-23 14:09:00 -04:00
}
}
2023-09-23 14:09:00 -04:00
}
2023-09-23 14:09:00 -04:00
auto newItem = new QTableWidgetItem(columnString);
2023-09-23 14:09:00 -04:00
tableWidget->setItem(j, z, newItem);
}
}
2023-09-23 14:09:00 -04:00
tableWidget->resizeColumnsToContents();
2024-02-04 15:36:08 -05:00
pageTabWidget->addTab(tableWidget, i18nc("@title:tab", "Page %1", i));
}
// Expand the tabs and hide the tab bar if there's only one page
// (it effectively makes the tab bar useless, so why show it?)
pageTabWidget->tabBar()->setExpanding(true);
pageTabWidget->tabBar()->setVisible(exh->page_count > 1);
2023-09-23 14:09:00 -04:00
}
2023-10-12 23:45:21 -04:00
Language EXDPart::getSuitableLanguage(physis_EXH *pExh)
{
2023-12-09 22:35:59 -05:00
for (uint32_t i = 0; i < pExh->language_count; i++) {
2023-09-23 14:09:00 -04:00
if (pExh->languages[i] == Language::English) {
return Language::English;
}
}
return Language::None;
}
2023-10-12 23:45:21 -04:00
std::pair<QString, int> EXDPart::getColumnData(physis_ColumnData &columnData)
{
QString columnString;
int columnRow;
switch (columnData.tag) {
case physis_ColumnData::Tag::String:
columnString = QString::fromStdString(columnData.string._0);
break;
case physis_ColumnData::Tag::Bool:
2024-02-04 15:23:24 -05:00
columnString = columnData.bool_._0 ? i18nc("Value is true", "True") : i18nc("Value is false", "False");
break;
case physis_ColumnData::Tag::Int8:
columnString = QString::number(columnData.int8._0);
columnRow = columnData.int8._0;
break;
case physis_ColumnData::Tag::UInt8:
columnString = QString::number(columnData.u_int8._0);
columnRow = columnData.u_int8._0;
break;
case physis_ColumnData::Tag::Int16:
columnString = QString::number(columnData.int16._0);
columnRow = columnData.int16._0;
break;
case physis_ColumnData::Tag::UInt16:
columnString = QString::number(columnData.u_int16._0);
columnRow = columnData.u_int16._0;
break;
case physis_ColumnData::Tag::Int32:
columnString = QString::number(columnData.int32._0);
columnRow = columnData.int32._0;
break;
case physis_ColumnData::Tag::UInt32:
columnString = QString::number(columnData.u_int32._0);
columnRow = columnData.u_int32._0;
break;
case physis_ColumnData::Tag::Float32:
columnString = QString::number(columnData.float32._0);
break;
case physis_ColumnData::Tag::Int64:
columnString = QString::number(columnData.int64._0);
columnRow = columnData.int64._0;
break;
case physis_ColumnData::Tag::UInt64:
columnString = QString::number(columnData.u_int64._0);
columnRow = columnData.u_int64._0;
break;
}
return {columnString, columnRow};
}
2023-10-12 23:45:21 -04:00
#include "moc_exdpart.cpp"