From ce5c98b78d788596fcce8a055ce98a15cc9021a4 Mon Sep 17 00:00:00 2001 From: RedLine AI Agent Date: Fri, 5 Sep 2025 20:53:15 +0000 Subject: [PATCH] Update: app/soundviewer.ui --- app/xtreewidget.cpp | 1600 ++++++++++++++++++++++--------------------- 1 file changed, 806 insertions(+), 794 deletions(-) diff --git a/app/xtreewidget.cpp b/app/xtreewidget.cpp index 9eb2158..6972d35 100644 --- a/app/xtreewidget.cpp +++ b/app/xtreewidget.cpp @@ -1,794 +1,806 @@ -#include "xtreewidget.h" -#include "qheaderview.h" -#include "qmenu.h" -#include "logmanager.h" - -XTreeWidget::XTreeWidget(QWidget *parent) - : QTreeWidget(parent) { - mFastFiles = QMap>(); - mZoneFiles = QMap>(); - mDDSFiles = QMap>(); - mIWIFiles = QMap>(); - - setContextMenuPolicy(Qt::CustomContextMenu); - setSelectionMode(QTreeWidget::SingleSelection); - setColumnCount(3); - header()->hide(); - setMinimumWidth(350); - setSortingEnabled(true); - setIconSize(QSize(16, 16)); - - 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); - - connect(this, &XTreeWidget::itemSelectionChanged, this, &XTreeWidget::ItemSelectionChanged); - connect(this, &XTreeWidget::customContextMenuRequested, this, &XTreeWidget::PrepareContextMenu); -} - -XTreeWidget::~XTreeWidget() { - -} - -void XTreeWidget::AddFastFile(std::shared_ptr aFastFile) { - XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this); - fastFileItem->setText(0, aFastFile->GetStem()); - fastFileItem->setIcon(0, Utils::CreateAssetIcon("FF")); - if (aFastFile->GetPlatform() == "PC") { - fastFileItem->setIcon(1, Utils::CreateAssetIcon("PC")); - } else if (aFastFile->GetPlatform() == "360") { - fastFileItem->setIcon(1, Utils::CreateAssetIcon("360")); - } else if (aFastFile->GetPlatform() == "PS3") { - fastFileItem->setIcon(1, Utils::CreateAssetIcon("PS3")); - } else if (aFastFile->GetPlatform() == "Wii") { - fastFileItem->setIcon(1, Utils::CreateAssetIcon("WII")); - } else if (aFastFile->GetPlatform() == "WiiU") { - fastFileItem->setIcon(1, Utils::CreateAssetIcon("WU")); - } - if (aFastFile->GetGame() == "COD2") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(2)); - } if (aFastFile->GetGame() == "COD4") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(4)); - } else if (aFastFile->GetGame() == "COD5") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(5)); - } else if (aFastFile->GetGame() == "COD6") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(6)); - } else if (aFastFile->GetGame() == "COD7") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(7)); - } else if (aFastFile->GetGame() == "COD8") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(8)); - } else if (aFastFile->GetGame() == "COD9") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(9)); - } else if (aFastFile->GetGame() == "COD10") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(10)); - } else if (aFastFile->GetGame() == "COD11") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(11)); - } else if (aFastFile->GetGame() == "COD12") { - fastFileItem->setIcon(2, Utils::CreateGameIcon(12)); - } - - AddZoneFile(aFastFile->GetZoneFile(), fastFileItem); - - mFastFiles[aFastFile->GetStem()] = aFastFile; - - resizeColumnToContents(1); - setSortingEnabled(true); - sortByColumn(0, Qt::AscendingOrder); -} - -void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetItem *aParentItem) { - XTreeWidgetItem *zoneItem; - if (aParentItem != nullptr) { - zoneItem = new XTreeWidgetItem(aParentItem); - } else { - zoneItem = new XTreeWidgetItem(this); - } - zoneItem->setIcon(0, Utils::CreateAssetIcon(Utils::ASSET_ZONE_FILE)); - zoneItem->setText(0, aZoneFile->GetBaseStem() + ".zone"); - - auto assetMap = aZoneFile->GetAssetMap(); - - if (!assetMap.localizeEntries.isEmpty()) { - QIcon localStrIcon = Utils::CreateAssetIcon(Utils::ASSET_LOCALIZE_ENTRY); - - XTreeWidgetItem *localStrRoot = new XTreeWidgetItem(zoneItem); - localStrRoot->setText(0, "String Files"); - localStrRoot->setIcon(0, localStrIcon); - localStrRoot->SetCategory(CATEGORY_TYPE); - - XTreeWidgetItem *localStrItem = new XTreeWidgetItem(localStrRoot); - localStrItem->setText(0, aZoneFile->GetStem().section('.', 0, 0) + ".str"); - localStrItem->setIcon(0, localStrIcon); - } - - if (!assetMap.techSets.isEmpty()) { - QIcon techSetIcon = Utils::CreateAssetIcon(Utils::ASSET_TECHNIQUE_SET); - - XTreeWidgetItem *techSetRoot = new XTreeWidgetItem(zoneItem); - techSetRoot->setText(0, "Tech Sets"); - techSetRoot->setIcon(0, techSetIcon); - techSetRoot->SetCategory(CATEGORY_TYPE); - - for (auto techSet : assetMap.techSets) { - XTreeWidgetItem *techSetItem = new XTreeWidgetItem(techSetRoot); - techSetItem->setText(0, techSet.name); - techSetItem->setIcon(0, techSetIcon); - } - } - - if (!assetMap.rawFiles.isEmpty()) { - QIcon rawFileIcon = Utils::CreateAssetIcon(Utils::ASSET_RAWFILE); - - XTreeWidgetItem *rawFileRoot = new XTreeWidgetItem(zoneItem); - rawFileRoot->setText(0, "Raw Files"); - rawFileRoot->setIcon(0, rawFileIcon); - rawFileRoot->SetCategory(CATEGORY_TYPE); - for (auto rawFile : assetMap.rawFiles) { - if (!rawFile.length) { continue; } - - XTreeWidgetItem *tempItem = rawFileRoot; - // 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(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); - } - } - - 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++; - // } - } - - if (!assetMap.images.isEmpty()) { - // 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); - // } - } - - if (!assetMap.models.isEmpty()) { - QIcon modelIcon = Utils::CreateAssetIcon(Utils::ASSET_XMODEL); - - XTreeWidgetItem *modelsRoot = new XTreeWidgetItem(zoneItem); - modelsRoot->setText(0, "Models"); - modelsRoot->setIcon(0, modelIcon); - modelsRoot->SetCategory(CATEGORY_TYPE); - - for (auto model: assetMap.models) { - XTreeWidgetItem *modelItem = new XTreeWidgetItem(modelsRoot); - modelItem->setText(0, model.name); - modelItem->setIcon(0, modelIcon); - } - } - - if (!assetMap.materials.isEmpty()) { - QIcon materialIcon = Utils::CreateAssetIcon(Utils::ASSET_MATERIAL); - - XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem); - materialsRoot->setText(0, "Materials"); - materialsRoot->setIcon(0, materialIcon); - materialsRoot->SetCategory(CATEGORY_TYPE); - - for (auto material: assetMap.materials) { - XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot); - //materialItem->setText(0, material.name); - materialItem->setIcon(0, materialIcon); - } - } - - if (!assetMap.stringTables.isEmpty()) { - QIcon stringTableIcon = Utils::CreateAssetIcon(Utils::ASSET_STRINGTABLE); - - XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem); - strTableRoot->setText(0, "String Tables"); - strTableRoot->setIcon(0, stringTableIcon); - strTableRoot->SetCategory(CATEGORY_TYPE); - - for (auto strTable: assetMap.stringTables) { - XTreeWidgetItem *modelItem = new XTreeWidgetItem(strTableRoot); - modelItem->setText(0, strTable.name); - modelItem->setIcon(0, stringTableIcon); - } - } - - if (!assetMap.sounds.isEmpty()) { - QIcon soundIcon = Utils::CreateAssetIcon(Utils::ASSET_SOUND); - - XTreeWidgetItem *soundsRoot = new XTreeWidgetItem(zoneItem); - soundsRoot->setText(0, "Sounds"); - soundsRoot->setIcon(0, soundIcon); - soundsRoot->SetCategory(CATEGORY_TYPE); - } - - mZoneFiles[aZoneFile->GetBaseStem() + ".zone"] = aZoneFile; -} - -void XTreeWidget::CloseFastFile(const QString aFFName) { - const QString fileStem = aFFName; - emit ItemClosed(fileStem); -} - -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 = 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 = 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; - - QMenu *closeMultipleAction = new QMenu("Close Multiple Tabs"); - - QAction *closeAllAction = new QAction("Close All"); - closeMultipleAction->addAction(closeAllAction); - connect(closeAllAction, &QAction::triggered, this, [this](bool checked) { - Q_UNUSED(checked); - - mFastFiles.clear(); - clear(); - - emit Cleared(); - }); - - 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; } - - const QString fileStem = childItem->text(0); - if (!mFastFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; - return; - } - - mFastFiles.remove(fileStem); - CloseFastFile(fileStem); - 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; } - - const QString fileStem = childItem->text(0); - if (!mFastFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; - return; - } - - mFastFiles.remove(fileStem); - CloseFastFile(fileStem); - 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; - } - - const QString fileStem = childItem->text(0); - if (!mFastFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; - return; - } - - mFastFiles.remove(fileStem); - CloseFastFile(fileStem); - invisibleRootItem()->removeChild(childItem); - i--; - } - }); - - contextMenu->addMenu(closeMultipleAction); - - QAction *closeAction = new QAction("Close File"); - contextMenu->addAction(closeAction); - connect(closeAction, &QAction::triggered, this, [this, &activeItem, &activeText](bool checked) { - Q_UNUSED(checked); - - const QString fileStem = activeItem->text(0); - - mFastFiles.remove(fileStem); - CloseFastFile(activeText); - invisibleRootItem()->removeChild(activeItem); - }); - - QMenu *exportSubmenu = new QMenu("Export...", this); - contextMenu->addMenu(exportSubmenu); - - std::shared_ptr fastFile = mFastFiles[fileStem]; - - QAction *exportFastFileAction = new QAction("Export Fast File"); - exportSubmenu->addAction(exportFastFileAction); - connect(exportFastFileAction, &QAction::triggered, this, [fastFile](bool checked) { - Q_UNUSED(checked); - - 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(*.*)"); - //fastFile->GetZoneFile()->SaveZoneFile(zoneFilePath); - }); - } else if (activeText.contains(".zone")) { - const QString fileStem = activeText; - 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 = mZoneFiles[fileStem]; - - 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) { - Q_UNUSED(checked); - }); - } else if (activeItem && activeText.contains(".wav")) { - XTreeWidgetItem *parentItem = dynamic_cast(activeItem->parent()); - while (parentItem && !parentItem->text(0).contains(".zone")) { - parentItem = dynamic_cast(parentItem->parent()); - - if (parentItem == invisibleRootItem()) { - break; - } - } - if (parentItem && parentItem != invisibleRootItem() && parentItem->text(0).contains(".zone")) { - const QString fileStem = parentItem->text(0).section('.', 0, 0); - // QVector 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; - // } - // } - // } - } - } else if (activeItem && activeText == "Sounds") { - XTreeWidgetItem *parentItem = dynamic_cast(activeItem->parent()); - while (parentItem && !parentItem->text(0).contains(".zone")) { - parentItem = dynamic_cast(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); - - // 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(); - // } - // } - }); - } - } - - QPoint pt(pos); - contextMenu->exec(mapToGlobal(pt)); - - delete contextMenu; -} - -void XTreeWidget::ItemSelectionChanged() { - if (selectedItems().isEmpty()) { return; } - - XTreeWidgetItem *selectedItem = dynamic_cast(selectedItems().first()); - if (!selectedItem) { return; } - if (selectedItem->text(0).isEmpty()) { return; } - QString selectedText = selectedItem->text(0); - emit ItemSelected(selectedText); - - XTreeWidgetItem *parentItem = dynamic_cast(selectedItem->parent()); - - if (selectedText.contains(".dds")) { - if (!mDDSFiles.contains(selectedText)) { - LogManager::instance().addError("Could not find " + selectedText + " in DDS map!"); - return; - } - std::shared_ptr ddsFile = mDDSFiles[selectedText]; - emit DDSFileSelected(ddsFile, selectedText); - } else if (selectedText.contains(".iwi")) { - if (!mIWIFiles.contains(selectedText)) { - LogManager::instance().addError("Could not find " + selectedText + " in IWI map!"); - return; - } - emit IWIFileSelected(mIWIFiles[selectedText], selectedText); - } else if (selectedText.contains(".ff")) { - if (!mFastFiles.contains(selectedText)) { - LogManager::instance().addError("Could not find " + selectedText + " in Fast File map!"); - return; - } - emit FastFileSelected(mFastFiles[selectedText], selectedText); - } else if (selectedText.contains(".zone")) { - if (!mZoneFiles.contains(selectedText)) { - LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!"); - return; - } - emit ZoneFileSelected(mZoneFiles[selectedText], selectedText); - } else if (selectedText.contains(".str")) { - if (!mZoneFiles.contains(selectedText.replace(".str", ".zone"))) { - LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!"); - return; - } - emit LocalStringSelected(mZoneFiles[selectedText], selectedText); - } else if (parentItem && (parentItem->text(0) == "Images")) { - XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); - if (grandpaItem && grandpaItem->text(0).contains(".zone")) { - const QString fileStem = grandpaItem->text(0).section('.', 0, 0); - // QVector images = mZoneFiles[fileStem]->GetAssetMap().images; - // for (Image image : images) { - // if (image.materialName == selectedText) { - // emit ImageSelected(std::make_shared(image), fileStem); - // break; - // } - // } - } - } else if (parentItem && (parentItem->text(0) == "Tech Sets")) { - XTreeWidgetItem *grandpaItem = dynamic_cast(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) { - emit TechSetSelected(std::make_shared(techset), fileStem); - break; - } - } - } - } else if (parentItem && (parentItem->text(0) == "Materials")) { - XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); - if (grandpaItem && grandpaItem->text(0).contains(".zone")) { - const QString fileStem = grandpaItem->text(0).section('.', 0, 0); - auto materials = mZoneFiles[fileStem]->GetAssetMap().materials; - for (auto material : materials) { - // if (material.name == selectedText) { - // emit MaterialSelected(std::make_shared(material), fileStem); - // break; - // } - } - } - } else if (parentItem && selectedText.contains(".wav")) { - XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); - while (grandpaItem && !grandpaItem->text(0).contains(".zone")) { - grandpaItem = dynamic_cast(grandpaItem->parent()); - - if (grandpaItem == invisibleRootItem()) { - break; - } - } - if (grandpaItem && grandpaItem != invisibleRootItem() && grandpaItem->text(0).contains(".zone")) { - const QString fileStem = grandpaItem->text(0).section('.', 0, 0); - // QVector 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), fileStem); - // break; - // } - // } - // } - } - } else if (selectedItem->GetCategory() != CATEGORY_TYPE) { - XTreeWidgetItem *zoneRoot = selectedItem; - - bool zoneChild = false; - while (zoneRoot) { - zoneRoot = dynamic_cast(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; - } - - auto rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles; - for (auto rawFile : rawFiles) { - //if (rawFile->path.split('/').last() == selectedText) { - // emit RawFileSelected(std::make_shared(rawFile), fileStem); - // return; - //} - } - } -} - -std::shared_ptr XTreeWidget::FindZoneFile(const QString aStem) { - foreach (auto zoneFile, mZoneFiles) { - if (zoneFile->GetStem() == aStem) { - return zoneFile; - } - } - return nullptr; -} - -std::shared_ptr XTreeWidget::FindFastFile(const QString aStem) { - foreach (auto fastFile, mFastFiles) { - if (fastFile->GetStem() == aStem) { - return fastFile; - } - } - return nullptr; -} - -bool XTreeWidget::HasZoneFile(const QString aStem) { - return FindZoneFile(aStem) != nullptr; -} - -bool XTreeWidget::HasFastFile(const QString aStem) { - return FindFastFile(aStem) != nullptr; -} - -void XTreeWidget::AddIWIFile(std::shared_ptr 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; - } - } - - XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this); - iwiItem->setIcon(0, Utils::CreateAssetIcon(Utils::ASSET_IMAGE)); - iwiItem->setText(0, iwiFileName); - mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile; -} - -void XTreeWidget::AddDDSFile(std::shared_ptr 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; - } - } - - XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this); - ddsItem->setIcon(0, Utils::CreateAssetIcon(Utils::ASSET_IMAGE)); - ddsItem->setText(0, ddsFileName); - mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile; -} +#include "xtreewidget.h" +#include "qheaderview.h" +#include "qmenu.h" +#include "logmanager.h" + +XTreeWidget::XTreeWidget(QWidget *parent) + : QTreeWidget(parent) { + mFastFiles = QMap(); + mZoneFiles = QMap(); + mDDSFiles = QMap(); + mIWIFiles = QMap(); + + setContextMenuPolicy(Qt::CustomContextMenu); + setSelectionMode(QTreeWidget::SingleSelection); + setColumnCount(3); + header()->hide(); + setMinimumWidth(350); + setSortingEnabled(true); + setIconSize(QSize(16, 16)); + + 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); + + connect(this, &XTreeWidget::itemSelectionChanged, this, &XTreeWidget::ItemSelectionChanged); + connect(this, &XTreeWidget::customContextMenuRequested, this, &XTreeWidget::PrepareContextMenu); +} + +XTreeWidget::~XTreeWidget() { + +} + +void XTreeWidget::AddFastFile(FastFile* aFastFile) { + XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this); + fastFileItem->setText(0, aFastFile->GetStem()); + fastFileItem->setIcon(0, Utils::CreateAssetIcon("FF")); + if (aFastFile->GetPlatform() == "PC") { + fastFileItem->setIcon(1, Utils::CreateAssetIcon("PC")); + } else if (aFastFile->GetPlatform() == "360") { + fastFileItem->setIcon(1, Utils::CreateAssetIcon("360")); + } else if (aFastFile->GetPlatform() == "PS3") { + fastFileItem->setIcon(1, Utils::CreateAssetIcon("PS3")); + } else if (aFastFile->GetPlatform() == "Wii") { + fastFileItem->setIcon(1, Utils::CreateAssetIcon("WII")); + } else if (aFastFile->GetPlatform() == "WiiU") { + fastFileItem->setIcon(1, Utils::CreateAssetIcon("WU")); + } + if (aFastFile->GetGame() == "COD2") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(2)); + } if (aFastFile->GetGame() == "COD4") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(4)); + } else if (aFastFile->GetGame() == "COD5") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(5)); + } else if (aFastFile->GetGame() == "COD6") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(6)); + } else if (aFastFile->GetGame() == "COD7") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(7)); + } else if (aFastFile->GetGame() == "COD8") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(8)); + } else if (aFastFile->GetGame() == "COD9") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(9)); + } else if (aFastFile->GetGame() == "COD10") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(10)); + } else if (aFastFile->GetGame() == "COD11") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(11)); + } else if (aFastFile->GetGame() == "COD12") { + fastFileItem->setIcon(2, Utils::CreateGameIcon(12)); + } + + AddZoneFile(aFastFile->GetZoneFile(), fastFileItem); + + mFastFiles[aFastFile->GetStem()] = aFastFile; + + resizeColumnToContents(1); + setSortingEnabled(true); + sortByColumn(0, Qt::AscendingOrder); +} + +void XTreeWidget::AddZoneFile(const ZoneFile* aZoneFile, XTreeWidgetItem *aParentItem) { + XTreeWidgetItem *zoneItem; + if (aParentItem != nullptr) { + zoneItem = new XTreeWidgetItem(aParentItem); + } else { + zoneItem = new XTreeWidgetItem(this); + } + zoneItem->setIcon(0, Utils::CreateAssetIcon("ZF")); + zoneItem->setText(0, aZoneFile->GetBaseStem() + ".zone"); + + XAssetList assetList = aZoneFile->GetAssetList(); + QVector localizeEntries; + for (int i = 0; i < assetList.Size(); i++) + { + XAsset *currentAsset = assetList.GetAsset(i); + if (currentAsset->GetType() == ASSET_TYPE_LOCALIZE_ENTRY) + { + localizeEntries.append(currentAsset); + } else if (currentAsset->GetType() == ASSET_TYPE_LOCALIZE_ENTRY) + { + localizeEntries.append(currentAsset); + } + } + + + // if (!assetMap.localizeEntries.isEmpty()) { + // QIcon localStrIcon = Utils::CreateAssetIcon(ASSET_TYPE_LOCALIZE_ENTRY); + + // XTreeWidgetItem *localStrRoot = new XTreeWidgetItem(zoneItem); + // localStrRoot->setText(0, "String Files"); + // localStrRoot->setIcon(0, localStrIcon); + // localStrRoot->SetCategory(CATEGORY_TYPE); + + // XTreeWidgetItem *localStrItem = new XTreeWidgetItem(localStrRoot); + // localStrItem->setText(0, aZoneFile->GetStem().section('.', 0, 0) + ".str"); + // localStrItem->setIcon(0, localStrIcon); + // } + + // if (!assetMap.techSets.isEmpty()) { + // QIcon techSetIcon = Utils::CreateAssetIcon(ASSET_TYPE_TECHNIQUE_SET); + + // XTreeWidgetItem *techSetRoot = new XTreeWidgetItem(zoneItem); + // techSetRoot->setText(0, "Tech Sets"); + // techSetRoot->setIcon(0, techSetIcon); + // techSetRoot->SetCategory(CATEGORY_TYPE); + + // for (auto techSet : assetMap.techSets) { + // XTreeWidgetItem *techSetItem = new XTreeWidgetItem(techSetRoot); + // techSetItem->setText(0, techSet.name); + // techSetItem->setIcon(0, techSetIcon); + // } + // } + + // if (!assetMap.rawFiles.isEmpty()) { + // QIcon rawFileIcon = Utils::CreateAssetIcon(ASSET_TYPE_RAWFILE); + + // XTreeWidgetItem *rawFileRoot = new XTreeWidgetItem(zoneItem); + // rawFileRoot->setText(0, "Raw Files"); + // rawFileRoot->setIcon(0, rawFileIcon); + // rawFileRoot->SetCategory(CATEGORY_TYPE); + // for (auto rawFile : assetMap.rawFiles) { + // if (!rawFile.length) { continue; } + + // XTreeWidgetItem *tempItem = rawFileRoot; + // // 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(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); + // } + // } + + // if (!assetMap.menuDefinitions.isEmpty()) { + // // QIcon MenuDefIcon = Utils::CreateAssetIcon(ASSET_TYPE_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++; + // // } + // } + + // if (!assetMap.images.isEmpty()) { + // // QIcon imageIcon = Utils::CreateAssetIcon(ASSET_TYPE_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); + // // } + // } + + // if (!assetMap.models.isEmpty()) { + // QIcon modelIcon = Utils::CreateAssetIcon(ASSET_TYPE_XMODEL); + + // XTreeWidgetItem *modelsRoot = new XTreeWidgetItem(zoneItem); + // modelsRoot->setText(0, "Models"); + // modelsRoot->setIcon(0, modelIcon); + // modelsRoot->SetCategory(CATEGORY_TYPE); + + // for (auto model: assetMap.models) { + // XTreeWidgetItem *modelItem = new XTreeWidgetItem(modelsRoot); + // modelItem->setText(0, model.name); + // modelItem->setIcon(0, modelIcon); + // } + // } + + // if (!assetMap.materials.isEmpty()) { + // QIcon materialIcon = Utils::CreateAssetIcon(ASSET_TYPE_MATERIAL); + + // XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem); + // materialsRoot->setText(0, "Materials"); + // materialsRoot->setIcon(0, materialIcon); + // materialsRoot->SetCategory(CATEGORY_TYPE); + + // for (auto material: assetMap.materials) { + // XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot); + // //materialItem->setText(0, material.name); + // materialItem->setIcon(0, materialIcon); + // } + // } + + // if (!assetMap.stringTables.isEmpty()) { + // QIcon stringTableIcon = Utils::CreateAssetIcon(ASSET_TYPE_STRINGTABLE); + + // XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem); + // strTableRoot->setText(0, "String Tables"); + // strTableRoot->setIcon(0, stringTableIcon); + // strTableRoot->SetCategory(CATEGORY_TYPE); + + // for (auto strTable: assetMap.stringTables) { + // XTreeWidgetItem *modelItem = new XTreeWidgetItem(strTableRoot); + // modelItem->setText(0, strTable.name); + // modelItem->setIcon(0, stringTableIcon); + // } + // } + + // if (!assetMap.sounds.isEmpty()) { + // QIcon soundIcon = Utils::CreateAssetIcon(ASSET_TYPE_SOUND); + + // XTreeWidgetItem *soundsRoot = new XTreeWidgetItem(zoneItem); + // soundsRoot->setText(0, "Sounds"); + // soundsRoot->setIcon(0, soundIcon); + // soundsRoot->SetCategory(CATEGORY_TYPE); + // } + + mZoneFiles[aZoneFile->GetBaseStem() + ".zone"] = aZoneFile; +} + +void XTreeWidget::CloseFastFile(const QString aFFName) { + const QString fileStem = aFFName; + emit ItemClosed(fileStem); +} + +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); + + const 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); + + const 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; + + QMenu *closeMultipleAction = new QMenu("Close Multiple Tabs"); + + QAction *closeAllAction = new QAction("Close All"); + closeMultipleAction->addAction(closeAllAction); + connect(closeAllAction, &QAction::triggered, this, [this](bool checked) { + Q_UNUSED(checked); + + mFastFiles.clear(); + clear(); + + emit Cleared(); + }); + + 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; } + + const QString fileStem = childItem->text(0); + if (!mFastFiles.contains(fileStem)) { + qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; + return; + } + + mFastFiles.remove(fileStem); + CloseFastFile(fileStem); + 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; } + + const QString fileStem = childItem->text(0); + if (!mFastFiles.contains(fileStem)) { + qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; + return; + } + + mFastFiles.remove(fileStem); + CloseFastFile(fileStem); + 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; + } + + const QString fileStem = childItem->text(0); + if (!mFastFiles.contains(fileStem)) { + qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; + return; + } + + mFastFiles.remove(fileStem); + CloseFastFile(fileStem); + invisibleRootItem()->removeChild(childItem); + i--; + } + }); + + contextMenu->addMenu(closeMultipleAction); + + QAction *closeAction = new QAction("Close File"); + contextMenu->addAction(closeAction); + connect(closeAction, &QAction::triggered, this, [this, &activeItem, &activeText](bool checked) { + Q_UNUSED(checked); + + const QString fileStem = activeItem->text(0); + + mFastFiles.remove(fileStem); + CloseFastFile(activeText); + invisibleRootItem()->removeChild(activeItem); + }); + + QMenu *exportSubmenu = new QMenu("Export...", this); + contextMenu->addMenu(exportSubmenu); + + const FastFile* fastFile = mFastFiles[fileStem]; + + QAction *exportFastFileAction = new QAction("Export Fast File"); + exportSubmenu->addAction(exportFastFileAction); + connect(exportFastFileAction, &QAction::triggered, this, [fastFile](bool checked) { + Q_UNUSED(checked); + + 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(*.*)"); + //fastFile->GetZoneFile()->SaveZoneFile(zoneFilePath); + }); + } else if (activeText.contains(".zone")) { + const QString fileStem = activeText; + if (!mZoneFiles.contains(fileStem)) { + qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; + return; + } + + QMenu *exportSubmenu = new QMenu("Export...", this); + contextMenu->addMenu(exportSubmenu); + + const ZoneFile* zoneFile = mZoneFiles[fileStem]; + + 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) { + Q_UNUSED(checked); + }); + } else if (activeItem && activeText.contains(".wav")) { + XTreeWidgetItem *parentItem = dynamic_cast(activeItem->parent()); + while (parentItem && !parentItem->text(0).contains(".zone")) { + parentItem = dynamic_cast(parentItem->parent()); + + if (parentItem == invisibleRootItem()) { + break; + } + } + if (parentItem && parentItem != invisibleRootItem() && parentItem->text(0).contains(".zone")) { + const QString fileStem = parentItem->text(0).section('.', 0, 0); + // QVector 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; + // } + // } + // } + } + } else if (activeItem && activeText == "Sounds") { + XTreeWidgetItem *parentItem = dynamic_cast(activeItem->parent()); + while (parentItem && !parentItem->text(0).contains(".zone")) { + parentItem = dynamic_cast(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); + + // 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(); + // } + // } + }); + } + } + + QPoint pt(pos); + contextMenu->exec(mapToGlobal(pt)); + + delete contextMenu; +} + +void XTreeWidget::ItemSelectionChanged() { + if (selectedItems().isEmpty()) { return; } + + XTreeWidgetItem *selectedItem = dynamic_cast(selectedItems().first()); + if (!selectedItem) { return; } + if (selectedItem->text(0).isEmpty()) { return; } + QString selectedText = selectedItem->text(0); + emit ItemSelected(selectedText); + + XTreeWidgetItem *parentItem = dynamic_cast(selectedItem->parent()); + + /*if (selectedText.contains(".dds")) { + if (!mDDSFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in DDS map!"); + return; + } + emit DDSFileSelected(mDDSFiles[selectedText], selectedText); + } else if (selectedText.contains(".iwi")) { + if (!mIWIFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in IWI map!"); + return; + } + emit IWIFileSelected(mIWIFiles[selectedText], selectedText); + } else */if (selectedText.contains(".ff")) { + if (!mFastFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in Fast File map!"); + return; + } + emit FastFileSelected(mFastFiles[selectedText], selectedText); + } else if (selectedText.contains(".zone")) { + if (!mZoneFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!"); + return; + } + emit ZoneFileSelected(mZoneFiles[selectedText], selectedText); + } else if (selectedText.contains(".str")) { + if (!mZoneFiles.contains(selectedText.replace(".str", ".zone"))) { + LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!"); + return; + } + emit LocalStringSelected(mZoneFiles[selectedText], selectedText); + } else if (parentItem && (parentItem->text(0) == "Images")) { + XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); + if (grandpaItem && grandpaItem->text(0).contains(".zone")) { + const QString fileStem = grandpaItem->text(0).section('.', 0, 0); + // QVector images = mZoneFiles[fileStem]->GetAssetMap().images; + // for (Image image : images) { + // if (image.materialName == selectedText) { + // emit ImageSelected(std::make_shared(image), fileStem); + // break; + // } + // } + } + } /*else if (parentItem && (parentItem->text(0) == "Tech Sets")) { + XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); + if (grandpaItem && grandpaItem->text(0).contains(".zone")) { + const QString fileStem = grandpaItem->text(0).section('.', 0, 0); + auto techsets = mZoneFiles[fileStem]->GetAssetList().techSets; + for (auto techset : techsets) { + if (techset.name == selectedText) { + emit TechSetSelected(new MaterialTechSet(techset), fileStem); + break; + } + } + } + } else if (parentItem && (parentItem->text(0) == "Materials")) { + XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); + if (grandpaItem && grandpaItem->text(0).contains(".zone")) { + const QString fileStem = grandpaItem->text(0).section('.', 0, 0); + auto materials = mZoneFiles[fileStem]->GetAssetMap().materials; + for (auto material : materials) { + // if (material.name == selectedText) { + // emit MaterialSelected(std::make_shared(material), fileStem); + // break; + // } + } + } + } else if (parentItem && selectedText.contains(".wav")) { + XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); + while (grandpaItem && !grandpaItem->text(0).contains(".zone")) { + grandpaItem = dynamic_cast(grandpaItem->parent()); + + if (grandpaItem == invisibleRootItem()) { + break; + } + } + if (grandpaItem && grandpaItem != invisibleRootItem() && grandpaItem->text(0).contains(".zone")) { + const QString fileStem = grandpaItem->text(0).section('.', 0, 0); + // QVector 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), fileStem); + // break; + // } + // } + // } + } + } else if (selectedItem->GetCategory() != CATEGORY_TYPE) { + XTreeWidgetItem *zoneRoot = selectedItem; + + bool zoneChild = false; + while (zoneRoot) { + zoneRoot = dynamic_cast(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; + } + + auto rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles; + for (auto rawFile : rawFiles) { + //if (rawFile->path.split('/').last() == selectedText) { + // emit RawFileSelected(std::make_shared(rawFile), fileStem); + // return; + //} + } + }*/ +} + +const ZoneFile* XTreeWidget::FindZoneFile(const QString aStem) { + foreach (auto zoneFile, mZoneFiles) { + if (zoneFile->GetStem() == aStem) { + return zoneFile; + } + } + return nullptr; +} + +const FastFile *XTreeWidget::FindFastFile(const QString aStem) { + foreach (auto fastFile, mFastFiles) { + if (fastFile->GetStem() == aStem) { + return fastFile; + } + } + return nullptr; +} + +bool XTreeWidget::HasZoneFile(const QString aStem) { + return FindZoneFile(aStem) != nullptr; +} + +bool XTreeWidget::HasFastFile(const QString aStem) { + return FindFastFile(aStem) != nullptr; +} + +void XTreeWidget::AddIWIFile(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; + } + } + + XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this); + iwiItem->setIcon(0, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE)); + iwiItem->setText(0, iwiFileName); + mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile; +} + +void XTreeWidget::AddDDSFile(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; + } + } + + XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this); + ddsItem->setIcon(0, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE)); + ddsItem->setText(0, ddsFileName); + mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile; +}