XPlor/app/xtreewidget.cpp

795 lines
32 KiB
C++
Raw Permalink Normal View History

2025-02-08 19:58:54 -05:00
#include "xtreewidget.h"
#include "qheaderview.h"
#include "qmenu.h"
2025-03-01 20:38:52 -05:00
#include "logmanager.h"
2025-02-08 19:58:54 -05:00
XTreeWidget::XTreeWidget(QWidget *parent)
: QTreeWidget(parent) {
mFastFiles = QMap<QString, std::shared_ptr<FastFile>>();
mZoneFiles = QMap<QString, std::shared_ptr<ZoneFile>>();
mDDSFiles = QMap<QString, std::shared_ptr<DDSFile>>();
mIWIFiles = QMap<QString, std::shared_ptr<IWIFile>>();
setContextMenuPolicy(Qt::CustomContextMenu);
setSelectionMode(QTreeWidget::SingleSelection);
setColumnCount(3);
header()->hide();
setMinimumWidth(350);
2025-02-14 16:06:27 -05:00
setSortingEnabled(true);
setIconSize(QSize(16, 16));
2025-02-14 16:06:27 -05:00
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
// Set the last two columns to a fixed width
//header()->setSectionResizeMode(1, QHeaderView::Fixed);
//header()->setSectionResizeMode(2, QHeaderView::Fixed);
// Adjust the fixed widths to suit your icon size (e.g., 32 pixels)
//header()->resizeSection(0, 275);
//header()->resizeSection(1, 32);
//header()->resizeSection(2, 32);
2025-02-08 19:58:54 -05:00
2025-03-01 20:38:52 -05:00
connect(this, &XTreeWidget::itemSelectionChanged, this, &XTreeWidget::ItemSelectionChanged);
2025-02-08 19:58:54 -05:00
connect(this, &XTreeWidget::customContextMenuRequested, this, &XTreeWidget::PrepareContextMenu);
}
XTreeWidget::~XTreeWidget() {
}
void XTreeWidget::AddFastFile(std::shared_ptr<FastFile> aFastFile) {
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this);
fastFileItem->setText(0, aFastFile->GetStem());
fastFileItem->setIcon(0, Utils::CreateAssetIcon("FF"));
2025-02-08 19:58:54 -05:00
if (aFastFile->GetPlatform() == "PC") {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("PC"));
2025-02-08 19:58:54 -05:00
} else if (aFastFile->GetPlatform() == "360") {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("360"));
} else if (aFastFile->GetPlatform() == "PS3") {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("PS3"));
2025-04-04 20:38:41 -04:00
} else if (aFastFile->GetPlatform() == "Wii") {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("WII"));
2025-04-04 20:38:41 -04:00
} else if (aFastFile->GetPlatform() == "WiiU") {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("WU"));
2025-02-08 19:58:54 -05:00
}
2025-03-01 20:38:52 -05:00
if (aFastFile->GetGame() == "COD2") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(2));
2025-03-01 20:38:52 -05:00
} if (aFastFile->GetGame() == "COD4") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(4));
2025-02-08 19:58:54 -05:00
} else if (aFastFile->GetGame() == "COD5") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(5));
2025-02-08 19:58:54 -05:00
} else if (aFastFile->GetGame() == "COD6") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(6));
2025-02-08 19:58:54 -05:00
} else if (aFastFile->GetGame() == "COD7") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(7));
2025-02-08 19:58:54 -05:00
} else if (aFastFile->GetGame() == "COD8") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(8));
2025-02-08 19:58:54 -05:00
} else if (aFastFile->GetGame() == "COD9") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(9));
2025-05-03 09:57:47 -04:00
} else if (aFastFile->GetGame() == "COD10") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(10));
2025-05-03 09:57:47 -04:00
} else if (aFastFile->GetGame() == "COD11") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(11));
2025-05-03 09:57:47 -04:00
} else if (aFastFile->GetGame() == "COD12") {
fastFileItem->setIcon(2, Utils::CreateGameIcon(12));
2025-02-08 19:58:54 -05:00
}
2025-02-19 19:17:31 -05:00
AddZoneFile(aFastFile->GetZoneFile(), fastFileItem);
2025-02-08 19:58:54 -05:00
mFastFiles[aFastFile->GetStem()] = aFastFile;
2025-02-08 19:58:54 -05:00
resizeColumnToContents(1);
2025-02-14 16:06:27 -05:00
setSortingEnabled(true);
2025-04-04 20:38:41 -04:00
sortByColumn(0, Qt::AscendingOrder);
2025-02-08 19:58:54 -05:00
}
2025-02-14 16:06:27 -05:00
void XTreeWidget::AddZoneFile(std::shared_ptr<ZoneFile> aZoneFile, XTreeWidgetItem *aParentItem) {
XTreeWidgetItem *zoneItem;
2025-02-08 19:58:54 -05:00
if (aParentItem != nullptr) {
2025-02-14 16:06:27 -05:00
zoneItem = new XTreeWidgetItem(aParentItem);
2025-02-08 19:58:54 -05:00
} else {
2025-02-14 16:06:27 -05:00
zoneItem = new XTreeWidgetItem(this);
2025-02-08 19:58:54 -05:00
}
2025-07-10 00:04:52 -04:00
zoneItem->setIcon(0, Utils::CreateAssetIcon(Utils::ASSET_ZONE_FILE));
zoneItem->setText(0, aZoneFile->GetBaseStem() + ".zone");
2025-02-08 19:58:54 -05:00
auto assetMap = aZoneFile->GetAssetMap();
2025-07-10 00:04:52 -04:00
if (!assetMap.localizeEntries.isEmpty()) {
QIcon localStrIcon = Utils::CreateAssetIcon(Utils::ASSET_LOCALIZE_ENTRY);
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *localStrRoot = new XTreeWidgetItem(zoneItem);
2025-02-08 19:58:54 -05:00
localStrRoot->setText(0, "String Files");
localStrRoot->setIcon(0, localStrIcon);
localStrRoot->SetCategory(CATEGORY_TYPE);
2025-02-08 19:58:54 -05:00
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *localStrItem = new XTreeWidgetItem(localStrRoot);
2025-02-19 19:17:31 -05:00
localStrItem->setText(0, aZoneFile->GetStem().section('.', 0, 0) + ".str");
localStrItem->setIcon(0, localStrIcon);
2025-02-08 19:58:54 -05:00
}
if (!assetMap.techSets.isEmpty()) {
2025-07-10 00:04:52 -04:00
QIcon techSetIcon = Utils::CreateAssetIcon(Utils::ASSET_TECHNIQUE_SET);
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *techSetRoot = new XTreeWidgetItem(zoneItem);
2025-02-08 19:58:54 -05:00
techSetRoot->setText(0, "Tech Sets");
techSetRoot->setIcon(0, techSetIcon);
techSetRoot->SetCategory(CATEGORY_TYPE);
2025-02-08 19:58:54 -05:00
2025-07-10 00:04:52 -04:00
for (auto techSet : assetMap.techSets) {
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *techSetItem = new XTreeWidgetItem(techSetRoot);
2025-02-08 19:58:54 -05:00
techSetItem->setText(0, techSet.name);
techSetItem->setIcon(0, techSetIcon);
2025-02-08 19:58:54 -05:00
}
}
if (!assetMap.rawFiles.isEmpty()) {
2025-07-10 00:04:52 -04:00
QIcon rawFileIcon = Utils::CreateAssetIcon(Utils::ASSET_RAWFILE);
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *rawFileRoot = new XTreeWidgetItem(zoneItem);
2025-02-08 19:58:54 -05:00
rawFileRoot->setText(0, "Raw Files");
rawFileRoot->setIcon(0, rawFileIcon);
rawFileRoot->SetCategory(CATEGORY_TYPE);
2025-07-10 00:04:52 -04:00
for (auto rawFile : assetMap.rawFiles) {
2025-02-08 19:58:54 -05:00
if (!rawFile.length) { continue; }
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *tempItem = rawFileRoot;
2025-07-10 00:04:52 -04:00
// const QStringList pathParts = rawFile->path.split('/');
// for (const QString &pathPart : pathParts) {
// bool childFound = false;
// for (int i = 0; i < tempItem->childCount(); i++) {
// QTreeWidgetItem *rawChildItem = tempItem->child(i);
// XTreeWidgetItem *childItem = dynamic_cast<XTreeWidgetItem*>(rawChildItem);
// if (childItem->text(0) == pathPart) {
// tempItem = childItem;
// childFound = true;
// break;
// }
// }
// const QString rawFileStr = pathPart;// = QString("%1 [%2-%3]").arg(pathPart).arg(rawFile.startPos).arg(rawFile.endPos);
// if (pathPart == pathParts.last()) {
// XTreeWidgetItem *rawFileItem = new XTreeWidgetItem(tempItem);
// rawFileItem->setText(0, rawFileStr);
// tempItem = rawFileItem;
// } else if (!childFound) {
// tempItem = new XTreeWidgetItem(tempItem);
// tempItem->setText(0, rawFileStr);
// }
// }
tempItem->setIcon(0, rawFileIcon);
2025-02-08 19:58:54 -05:00
}
}
2025-07-10 00:04:52 -04:00
if (!assetMap.menuDefinitions.isEmpty()) {
// QIcon MenuDefIcon = Utils::CreateAssetIcon(Utils::ASSET_MENU);
// XTreeWidgetItem *menuRoot = new XTreeWidgetItem(zoneItem);
// menuRoot->setText(0, "Menu Files");
// menuRoot->setIcon(0, MenuDefIcon);
// menuRoot->SetCategory(CATEGORY_TYPE);
// int menuIndex = 1;
// for (MenuDef menuDef : assetMap.menuDefinitions) {
// XTreeWidgetItem *MenuDefRoot = new XTreeWidgetItem(menuRoot);
// MenuDefRoot->setText(0, QString("Menu %1").arg(menuIndex));
// for (Menu menu : menuDef.men) {
// XTreeWidgetItem *menuItem = new XTreeWidgetItem(MenuDefRoot);
// menuItem->setText(0, menu.filePath);
// menuItem->setIcon(0, MenuDefIcon);
// }
// menuIndex++;
// }
2025-02-08 19:58:54 -05:00
}
if (!assetMap.images.isEmpty()) {
2025-07-10 00:04:52 -04:00
// QIcon imageIcon = Utils::CreateAssetIcon(Utils::ASSET_IMAGE);
// XTreeWidgetItem *imageRoot = new XTreeWidgetItem(zoneItem);
// imageRoot->setText(0, "Images");
// imageRoot->setIcon(0, imageIcon);
// imageRoot->SetCategory(CATEGORY_TYPE);
// for (Image image : assetMap.images) {
// XTreeWidgetItem *imageItem = new XTreeWidgetItem(imageRoot);
// imageItem->setText(0, image.materialName);
// imageItem->setIcon(0, imageIcon);
// }
2025-02-08 19:58:54 -05:00
}
2025-02-14 16:06:27 -05:00
if (!assetMap.models.isEmpty()) {
2025-07-10 00:04:52 -04:00
QIcon modelIcon = Utils::CreateAssetIcon(Utils::ASSET_XMODEL);
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *modelsRoot = new XTreeWidgetItem(zoneItem);
modelsRoot->setText(0, "Models");
modelsRoot->setIcon(0, modelIcon);
modelsRoot->SetCategory(CATEGORY_TYPE);
2025-02-14 16:06:27 -05:00
2025-07-10 00:04:52 -04:00
for (auto model: assetMap.models) {
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *modelItem = new XTreeWidgetItem(modelsRoot);
2025-07-10 00:04:52 -04:00
modelItem->setText(0, model.name);
modelItem->setIcon(0, modelIcon);
2025-02-14 16:06:27 -05:00
}
}
2025-03-01 20:38:52 -05:00
if (!assetMap.materials.isEmpty()) {
2025-07-10 00:04:52 -04:00
QIcon materialIcon = Utils::CreateAssetIcon(Utils::ASSET_MATERIAL);
2025-03-01 20:38:52 -05:00
XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem);
materialsRoot->setText(0, "Materials");
materialsRoot->setIcon(0, materialIcon);
materialsRoot->SetCategory(CATEGORY_TYPE);
2025-03-01 20:38:52 -05:00
2025-07-10 00:04:52 -04:00
for (auto material: assetMap.materials) {
2025-03-01 20:38:52 -05:00
XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot);
2025-07-10 00:04:52 -04:00
//materialItem->setText(0, material.name);
materialItem->setIcon(0, materialIcon);
2025-03-01 20:38:52 -05:00
}
}
2025-02-14 16:06:27 -05:00
if (!assetMap.stringTables.isEmpty()) {
2025-07-10 00:04:52 -04:00
QIcon stringTableIcon = Utils::CreateAssetIcon(Utils::ASSET_STRINGTABLE);
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem);
strTableRoot->setText(0, "String Tables");
strTableRoot->setIcon(0, stringTableIcon);
strTableRoot->SetCategory(CATEGORY_TYPE);
2025-02-14 16:06:27 -05:00
2025-07-10 00:04:52 -04:00
for (auto strTable: assetMap.stringTables) {
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *modelItem = new XTreeWidgetItem(strTableRoot);
modelItem->setText(0, strTable.name);
modelItem->setIcon(0, stringTableIcon);
2025-02-14 16:06:27 -05:00
}
}
if (!assetMap.sounds.isEmpty()) {
2025-07-10 00:04:52 -04:00
QIcon soundIcon = Utils::CreateAssetIcon(Utils::ASSET_SOUND);
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *soundsRoot = new XTreeWidgetItem(zoneItem);
soundsRoot->setText(0, "Sounds");
soundsRoot->setIcon(0, soundIcon);
soundsRoot->SetCategory(CATEGORY_TYPE);
2025-02-14 16:06:27 -05:00
}
mZoneFiles[aZoneFile->GetBaseStem() + ".zone"] = aZoneFile;
2025-02-08 19:58:54 -05:00
}
2025-03-01 20:38:52 -05:00
void XTreeWidget::CloseFastFile(const QString aFFName) {
const QString fileStem = aFFName;
2025-03-01 20:38:52 -05:00
emit ItemClosed(fileStem);
}
2025-02-08 19:58:54 -05:00
void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
auto activeItem = itemAt(pos);
if (!activeItem) { return; }
if (activeItem->text(0).isEmpty()) { return; }
QString activeText = activeItem->text(0);
QMenu *contextMenu = new QMenu(this);
if (activeText.contains(".dds")) {
const QString fileStem = activeText.replace(".dds", "");
if (!mDDSFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in DDS map!";
return;
}
QAction *closeAction = new QAction("Close File");
contextMenu->addAction(closeAction);
connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) {
Q_UNUSED(checked);
mDDSFiles.remove(fileStem);
invisibleRootItem()->removeChild(activeItem);
});
QMenu *exportSubmenu = new QMenu("Export...", this);
contextMenu->addMenu(exportSubmenu);
std::shared_ptr<DDSFile> ddsFile = mDDSFiles[fileStem];
QAction *exportIWIAction = new QAction("Export as IWI");
exportSubmenu->addAction(exportIWIAction);
connect(exportIWIAction, &QAction::triggered, this, [ddsFile](bool checked) {
Q_UNUSED(checked);
ddsFile->SaveIWI();
});
QAction *exportPNGAction = new QAction("Export as PNG");
exportSubmenu->addAction(exportPNGAction);
connect(exportPNGAction, &QAction::triggered, this, [ddsFile](bool checked) {
Q_UNUSED(checked);
ddsFile->SavePNG();
});
QAction *exportJPGAction = new QAction("Export as JPG");
exportSubmenu->addAction(exportJPGAction);
connect(exportJPGAction, &QAction::triggered, this, [ddsFile](bool checked) {
Q_UNUSED(checked);
ddsFile->SaveJPG();
});
} else if (activeText.contains(".iwi")) {
const QString fileStem = activeText.replace(".iwi", "");
if (!mIWIFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in IWI map!";
return;
}
QAction *closeAction = new QAction("Close File");
contextMenu->addAction(closeAction);
connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) {
Q_UNUSED(checked);
mIWIFiles.remove(fileStem);
invisibleRootItem()->removeChild(activeItem);
});
QMenu *exportSubmenu = new QMenu("Export...", this);
contextMenu->addMenu(exportSubmenu);
std::shared_ptr<IWIFile> iwiFile = mIWIFiles[fileStem];
QAction *exportDDSAction = new QAction("Export as DDS");
exportSubmenu->addAction(exportDDSAction);
connect(exportDDSAction, &QAction::triggered, this, [iwiFile](bool checked) {
Q_UNUSED(checked);
iwiFile->SaveDDS();
});
QAction *exportPNGAction = new QAction("Export as PNG");
exportSubmenu->addAction(exportPNGAction);
connect(exportPNGAction, &QAction::triggered, this, [iwiFile](bool checked) {
Q_UNUSED(checked);
iwiFile->SavePNG();
});
QAction *exportJPGAction = new QAction("Export as JPG");
exportSubmenu->addAction(exportJPGAction);
connect(exportJPGAction, &QAction::triggered, this, [iwiFile](bool checked) {
Q_UNUSED(checked);
iwiFile->SaveJPG();
});
} else if (activeText.contains(".ff")) {
const QString fileStem = activeText;
2025-02-08 19:58:54 -05:00
2025-04-04 20:38:41 -04:00
QMenu *closeMultipleAction = new QMenu("Close Multiple Tabs");
2025-03-01 20:38:52 -05:00
2025-02-08 19:58:54 -05:00
QAction *closeAllAction = new QAction("Close All");
closeMultipleAction->addAction(closeAllAction);
connect(closeAllAction, &QAction::triggered, this, [this](bool checked) {
Q_UNUSED(checked);
2025-03-01 20:38:52 -05:00
mFastFiles.clear();
2025-02-08 19:58:54 -05:00
clear();
2025-02-14 16:06:27 -05:00
emit Cleared();
2025-02-08 19:58:54 -05:00
});
QAction *closeAllButAction = new QAction("Close All BUT This");
closeMultipleAction->addAction(closeAllButAction);
connect(closeAllButAction, &QAction::triggered, this, [this, &activeItem](bool checked) {
Q_UNUSED(checked);
for (int i = 0; i < invisibleRootItem()->childCount(); i++) {
auto childItem = invisibleRootItem()->child(i);
if (childItem == activeItem) { continue; }
2025-03-01 20:38:52 -05:00
const QString fileStem = childItem->text(0);
2025-03-01 20:38:52 -05:00
if (!mFastFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
return;
}
mFastFiles.remove(fileStem);
CloseFastFile(fileStem);
2025-02-08 19:58:54 -05:00
invisibleRootItem()->removeChild(childItem);
i--;
}
});
QAction *closeAboveAction = new QAction("Close All Above");
closeMultipleAction->addAction(closeAboveAction);
connect(closeAboveAction, &QAction::triggered, this, [this, &activeItem](bool checked) {
Q_UNUSED(checked);
for (int i = 0; i < invisibleRootItem()->childCount(); i++) {
auto childItem = invisibleRootItem()->child(i);
if (childItem == activeItem) { return; }
2025-03-01 20:38:52 -05:00
const QString fileStem = childItem->text(0);
2025-03-01 20:38:52 -05:00
if (!mFastFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
return;
}
mFastFiles.remove(fileStem);
CloseFastFile(fileStem);
2025-02-08 19:58:54 -05:00
invisibleRootItem()->removeChild(childItem);
i--;
}
});
QAction *closeBelowAction = new QAction("Close All Below");
closeMultipleAction->addAction(closeBelowAction);
connect(closeBelowAction, &QAction::triggered, this, [this, &activeItem](bool checked) {
Q_UNUSED(checked);
bool ready = false;
for (int i = 0; i < invisibleRootItem()->childCount(); i++) {
auto childItem = invisibleRootItem()->child(i);
if (!ready && (childItem != activeItem)) { continue; }
if (childItem == activeItem) {
ready = true;
continue;
}
2025-03-01 20:38:52 -05:00
const QString fileStem = childItem->text(0);
2025-03-01 20:38:52 -05:00
if (!mFastFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
return;
}
mFastFiles.remove(fileStem);
CloseFastFile(fileStem);
2025-02-08 19:58:54 -05:00
invisibleRootItem()->removeChild(childItem);
i--;
}
});
contextMenu->addMenu(closeMultipleAction);
QAction *closeAction = new QAction("Close File");
contextMenu->addAction(closeAction);
2025-03-01 20:38:52 -05:00
connect(closeAction, &QAction::triggered, this, [this, &activeItem, &activeText](bool checked) {
2025-02-08 19:58:54 -05:00
Q_UNUSED(checked);
const QString fileStem = activeItem->text(0);
2025-03-01 20:38:52 -05:00
2025-02-08 19:58:54 -05:00
mFastFiles.remove(fileStem);
2025-03-01 20:38:52 -05:00
CloseFastFile(activeText);
2025-02-08 19:58:54 -05:00
invisibleRootItem()->removeChild(activeItem);
});
QMenu *exportSubmenu = new QMenu("Export...", this);
contextMenu->addMenu(exportSubmenu);
2025-04-04 20:38:41 -04:00
std::shared_ptr<FastFile> fastFile = mFastFiles[fileStem];
QAction *exportFastFileAction = new QAction("Export Fast File");
exportSubmenu->addAction(exportFastFileAction);
connect(exportFastFileAction, &QAction::triggered, this, [fastFile](bool checked) {
2025-02-08 19:58:54 -05:00
Q_UNUSED(checked);
2025-04-04 20:38:41 -04:00
const QString fastFilePath = QFileDialog::getSaveFileName(
nullptr, "Export Fast File...", QDir::currentPath(),
"Fast File (*.ff);;All Files(*.*)");
fastFile->ExportFastFile(fastFilePath);
});
QAction *exportZoneFileAction = new QAction("Export Zone File");
exportSubmenu->addAction(exportZoneFileAction);
connect(exportZoneFileAction, &QAction::triggered, this, [fastFile](bool checked) {
Q_UNUSED(checked);
const QString zoneFilePath = QFileDialog::getSaveFileName(
nullptr, "Export Zone File...", QDir::currentPath(),
"Zone File (*.zone);;All Files(*.*)");
2025-07-10 00:04:52 -04:00
//fastFile->GetZoneFile()->SaveZoneFile(zoneFilePath);
2025-02-08 19:58:54 -05:00
});
} else if (activeText.contains(".zone")) {
const QString fileStem = activeText;
2025-02-08 19:58:54 -05:00
if (!mZoneFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in Zone File map!";
return;
}
QMenu *exportSubmenu = new QMenu("Export...", this);
contextMenu->addMenu(exportSubmenu);
std::shared_ptr<ZoneFile> zoneFile = mZoneFiles[fileStem];
2025-04-04 20:38:41 -04:00
QAction *exportZoneFileAction = new QAction("Export Zone File");
exportSubmenu->addAction(exportZoneFileAction);
connect(exportZoneFileAction, &QAction::triggered, this, [](bool checked) {
Q_UNUSED(checked);
});
QAction *exportFastFileAction = new QAction("Export Fast File");
exportSubmenu->addAction(exportFastFileAction);
connect(exportFastFileAction, &QAction::triggered, this, [](bool checked) {
2025-02-08 19:58:54 -05:00
Q_UNUSED(checked);
});
2025-02-14 16:06:27 -05:00
} else if (activeItem && activeText.contains(".wav")) {
XTreeWidgetItem *parentItem = dynamic_cast<XTreeWidgetItem*>(activeItem->parent());
while (parentItem && !parentItem->text(0).contains(".zone")) {
parentItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
if (parentItem == invisibleRootItem()) {
break;
}
}
if (parentItem && parentItem != invisibleRootItem() && parentItem->text(0).contains(".zone")) {
const QString fileStem = parentItem->text(0).section('.', 0, 0);
2025-07-10 00:04:52 -04:00
// QVector<LoadedSound> LoadedSounds = mZoneFiles[fileStem]->GetAssetMap().sounds;
// for (LoadedSound LoadedSound : LoadedSounds) {
// for (Sound sound : LoadedSound.sounds) {
// if (sound.path.contains(activeText)) {
// QMenu *exportSubmenu = new QMenu("Export...", this);
// contextMenu->addMenu(exportSubmenu);
// QAction *exportWAVAction = new QAction("Export as WAV File");
// exportSubmenu->addAction(exportWAVAction);
// connect(exportWAVAction, &QAction::triggered, this, [sound](bool checked) {
// Q_UNUSED(checked);
// QDir dir = QDir::currentPath();
// if (!dir.exists("exports/")) {
// dir.mkdir("exports/");
// }
// if (!dir.exists("exports/sounds/")) {
// dir.mkdir("exports/sounds/");
// }
// const QString fileName = "exports/sounds/" + sound.path.split('/').last();
// QFile wavFile(fileName);
// if (!wavFile.open(QIODevice::WriteOnly)) {
// qDebug() << "Failed to write wav file!";
// return;
// }
// wavFile.write(sound.data);
// wavFile.close();
// });
// break;
// }
// }
// }
2025-02-14 16:06:27 -05:00
}
} else if (activeItem && activeText == "Sounds") {
XTreeWidgetItem *parentItem = dynamic_cast<XTreeWidgetItem*>(activeItem->parent());
while (parentItem && !parentItem->text(0).contains(".zone")) {
parentItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
if (parentItem == invisibleRootItem()) {
break;
}
}
if (parentItem && parentItem != invisibleRootItem() && parentItem->text(0).contains(".zone")) {
const QString fileStem = parentItem->text(0).section('.', 0, 0);
auto zoneFile = mZoneFiles[fileStem];
QMenu *exportSubmenu = new QMenu("Export...", this);
contextMenu->addMenu(exportSubmenu);
QAction *exportAllWAVAction = new QAction("Export ALL as WAV Files");
exportSubmenu->addAction(exportAllWAVAction);
connect(exportAllWAVAction, &QAction::triggered, this, [zoneFile](bool checked) {
Q_UNUSED(checked);
2025-07-10 00:04:52 -04:00
// for (LoadedSound LoadedSound : zoneFile->GetAssetMap().sounds) {
// for (Sound sound : LoadedSound.sounds) {
// if (!sound.dataLength) { continue; }
// QDir dir = QDir::currentPath();
// if (!dir.exists("exports/")) {
// dir.mkdir("exports/");
// }
// if (!dir.exists("exports/sounds/")) {
// dir.mkdir("exports/sounds/");
// }
// const QString fileName = "exports/sounds/" + sound.path.split('/').last();
// QFile wavFile(fileName);
// if (!wavFile.open(QIODevice::WriteOnly)) {
// qDebug() << "Failed to write wav file!";
// return;
// }
// wavFile.write(sound.data);
// wavFile.close();
// }
// }
2025-02-14 16:06:27 -05:00
});
}
2025-02-08 19:58:54 -05:00
}
QPoint pt(pos);
contextMenu->exec(mapToGlobal(pt));
delete contextMenu;
}
void XTreeWidget::ItemSelectionChanged() {
if (selectedItems().isEmpty()) { return; }
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *selectedItem = dynamic_cast<XTreeWidgetItem*>(selectedItems().first());
2025-02-08 19:58:54 -05:00
if (!selectedItem) { return; }
if (selectedItem->text(0).isEmpty()) { return; }
QString selectedText = selectedItem->text(0);
2025-03-01 20:38:52 -05:00
emit ItemSelected(selectedText);
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *parentItem = dynamic_cast<XTreeWidgetItem*>(selectedItem->parent());
2025-02-08 19:58:54 -05:00
if (selectedText.contains(".dds")) {
if (!mDDSFiles.contains(selectedText)) {
LogManager::instance().addError("Could not find " + selectedText + " in DDS map!");
2025-02-08 19:58:54 -05:00
return;
}
std::shared_ptr<DDSFile> ddsFile = mDDSFiles[selectedText];
emit DDSFileSelected(ddsFile, selectedText);
2025-02-08 19:58:54 -05:00
} else if (selectedText.contains(".iwi")) {
if (!mIWIFiles.contains(selectedText)) {
LogManager::instance().addError("Could not find " + selectedText + " in IWI map!");
2025-02-08 19:58:54 -05:00
return;
}
emit IWIFileSelected(mIWIFiles[selectedText], selectedText);
2025-02-08 19:58:54 -05:00
} else if (selectedText.contains(".ff")) {
if (!mFastFiles.contains(selectedText)) {
LogManager::instance().addError("Could not find " + selectedText + " in Fast File map!");
2025-02-08 19:58:54 -05:00
return;
}
emit FastFileSelected(mFastFiles[selectedText], selectedText);
2025-02-08 19:58:54 -05:00
} else if (selectedText.contains(".zone")) {
if (!mZoneFiles.contains(selectedText)) {
LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!");
2025-02-08 19:58:54 -05:00
return;
}
emit ZoneFileSelected(mZoneFiles[selectedText], selectedText);
2025-02-08 19:58:54 -05:00
} else if (selectedText.contains(".str")) {
if (!mZoneFiles.contains(selectedText.replace(".str", ".zone"))) {
LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!");
2025-02-08 19:58:54 -05:00
return;
}
emit LocalStringSelected(mZoneFiles[selectedText], selectedText);
2025-02-08 19:58:54 -05:00
} else if (parentItem && (parentItem->text(0) == "Images")) {
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
2025-02-08 19:58:54 -05:00
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
2025-07-10 00:04:52 -04:00
// QVector<Image> images = mZoneFiles[fileStem]->GetAssetMap().images;
// for (Image image : images) {
// if (image.materialName == selectedText) {
// emit ImageSelected(std::make_shared<Image>(image), fileStem);
// break;
// }
// }
2025-03-01 20:38:52 -05:00
}
} else if (parentItem && (parentItem->text(0) == "Tech Sets")) {
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
auto techsets = mZoneFiles[fileStem]->GetAssetMap().techSets;
for (auto techset : techsets) {
if (techset.name == selectedText) {
2025-07-10 00:04:52 -04:00
emit TechSetSelected(std::make_shared<MaterialTechSet>(techset), fileStem);
2025-02-08 19:58:54 -05:00
break;
}
}
}
2025-03-01 20:38:52 -05:00
} else if (parentItem && (parentItem->text(0) == "Materials")) {
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
2025-07-10 00:04:52 -04:00
auto materials = mZoneFiles[fileStem]->GetAssetMap().materials;
for (auto material : materials) {
// if (material.name == selectedText) {
// emit MaterialSelected(std::make_shared<Material>(material), fileStem);
// break;
// }
2025-02-14 16:06:27 -05:00
}
}
} else if (parentItem && selectedText.contains(".wav")) {
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
while (grandpaItem && !grandpaItem->text(0).contains(".zone")) {
grandpaItem = dynamic_cast<XTreeWidgetItem*>(grandpaItem->parent());
if (grandpaItem == invisibleRootItem()) {
break;
}
}
if (grandpaItem && grandpaItem != invisibleRootItem() && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
2025-07-10 00:04:52 -04:00
// QVector<LoadedSound> LoadedSounds = mZoneFiles[fileStem]->GetAssetMap().sounds;
// for (LoadedSound LoadedSound : LoadedSounds) {
// for (Sound sound : LoadedSound.sounds) {
// if (sound.path.contains(selectedText)) {
// emit SoundSelected(std::make_shared<Sound>(sound), fileStem);
// break;
// }
// }
// }
2025-02-14 16:06:27 -05:00
}
} else if (selectedItem->GetCategory() != CATEGORY_TYPE) {
XTreeWidgetItem *zoneRoot = selectedItem;
bool zoneChild = false;
while (zoneRoot) {
zoneRoot = dynamic_cast<XTreeWidgetItem*>(zoneRoot->parent());
if (zoneRoot->text(0).contains("Raw Files")) {
zoneChild = true;
break;
}
}
if (!zoneChild) { return; }
const QString fileStem = zoneRoot->parent()->text(0);
if (!mZoneFiles.contains(fileStem)) {
LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!");
return;
}
2025-07-10 00:04:52 -04:00
auto rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles;
for (auto rawFile : rawFiles) {
//if (rawFile->path.split('/').last() == selectedText) {
// emit RawFileSelected(std::make_shared<RawFile>(rawFile), fileStem);
// return;
//}
}
2025-02-08 19:58:54 -05:00
}
}
2025-03-01 20:38:52 -05:00
std::shared_ptr<ZoneFile> XTreeWidget::FindZoneFile(const QString aStem) {
2025-02-08 19:58:54 -05:00
foreach (auto zoneFile, mZoneFiles) {
2025-03-01 20:38:52 -05:00
if (zoneFile->GetStem() == aStem) {
2025-02-19 19:17:31 -05:00
return zoneFile;
2025-02-08 19:58:54 -05:00
}
}
2025-02-19 19:17:31 -05:00
return nullptr;
2025-02-08 19:58:54 -05:00
}
2025-03-01 20:38:52 -05:00
std::shared_ptr<FastFile> XTreeWidget::FindFastFile(const QString aStem) {
2025-02-08 19:58:54 -05:00
foreach (auto fastFile, mFastFiles) {
2025-03-01 20:38:52 -05:00
if (fastFile->GetStem() == aStem) {
2025-02-19 19:17:31 -05:00
return fastFile;
2025-02-08 19:58:54 -05:00
}
}
2025-02-19 19:17:31 -05:00
return nullptr;
2025-02-08 19:58:54 -05:00
}
2025-03-01 20:38:52 -05:00
bool XTreeWidget::HasZoneFile(const QString aStem) {
return FindZoneFile(aStem) != nullptr;
}
bool XTreeWidget::HasFastFile(const QString aStem) {
return FindFastFile(aStem) != nullptr;
}
2025-02-08 19:58:54 -05:00
void XTreeWidget::AddIWIFile(std::shared_ptr<IWIFile> aIWIFile) {
const QString iwiFileName = QString(aIWIFile->fileStem + ".iwi");
for (int i = 0; i < invisibleRootItem()->childCount(); i++) {
auto iwiFileItem = invisibleRootItem()->child(i);
if (iwiFileItem->text(0) == iwiFileName) {
delete iwiFileItem;
}
}
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this);
2025-07-10 00:04:52 -04:00
iwiItem->setIcon(0, Utils::CreateAssetIcon(Utils::ASSET_IMAGE));
2025-02-08 19:58:54 -05:00
iwiItem->setText(0, iwiFileName);
mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile;
}
void XTreeWidget::AddDDSFile(std::shared_ptr<DDSFile> aDDSFile) {
const QString ddsFileName = QString(aDDSFile->fileStem + ".dds");
for (int i = 0; i < invisibleRootItem()->childCount(); i++) {
auto ddsFileItem = invisibleRootItem()->child(i);
if (ddsFileItem->text(0) == ddsFileName) {
delete ddsFileItem;
}
}
2025-02-14 16:06:27 -05:00
XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this);
2025-07-10 00:04:52 -04:00
ddsItem->setIcon(0, Utils::CreateAssetIcon(Utils::ASSET_IMAGE));
2025-02-08 19:58:54 -05:00
ddsItem->setText(0, ddsFileName);
mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile;
}