#include "xtreewidget.h" #include "qheaderview.h" #include "qmenu.h" #include "utils.h" XTreeWidget::XTreeWidget(QWidget *parent) : QTreeWidget(parent) { mFastFiles = QMap>(); mZoneFiles = QMap>(); mDDSFiles = QMap>(); mIWIFiles = QMap>(); setContextMenuPolicy(Qt::CustomContextMenu); setSelectionMode(QTreeWidget::SingleSelection); setColumnCount(3); setColumnWidth(0, 275); setColumnWidth(1, 50); setColumnWidth(2, 50); header()->hide(); setMinimumWidth(350); connect(this, &QTreeWidget::itemSelectionChanged, this, &XTreeWidget::ItemSelectionChanged); connect(this, &XTreeWidget::customContextMenuRequested, this, &XTreeWidget::PrepareContextMenu); } XTreeWidget::~XTreeWidget() { } void XTreeWidget::AddFastFile(std::shared_ptr aFastFile) { QTreeWidgetItem *fastFileItem = new QTreeWidgetItem(this); fastFileItem->setText(0, aFastFile->GetFileStem()); fastFileItem->setIcon(0, QIcon(":/icons/icons/Icon_FastFile.png")); if (aFastFile->GetPlatform() == "PC") { fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_PC.png")); } else if (aFastFile->GetPlatform() == "360") { fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_Xbox.png")); } if (aFastFile->GetGame() == "COD4") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD4.png")); } else if (aFastFile->GetGame() == "COD5") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD5.png")); } else if (aFastFile->GetGame() == "COD6") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD6.png")); } else if (aFastFile->GetGame() == "COD7") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD7.png")); } else if (aFastFile->GetGame() == "COD8") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD8.png")); } else if (aFastFile->GetGame() == "COD9") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD9.png")); } AddZoneFile(std::make_shared(aFastFile->GetZoneFile()), fastFileItem); mFastFiles[aFastFile->GetFileStem().section(".", 0, 0)] = aFastFile; resizeColumnToContents(1); } void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, QTreeWidgetItem *aParentItem) { QTreeWidgetItem *zoneItem; if (aParentItem != nullptr) { zoneItem = new QTreeWidgetItem(aParentItem); } else { zoneItem = new QTreeWidgetItem(this); } zoneItem->setIcon(0, QIcon(":/icons/icons/Icon_ZoneFile.png")); zoneItem->setText(0, aZoneFile->GetFileStem()); auto assetMap = aZoneFile->GetAssetMap(); if (!assetMap.localStrings.isEmpty()) { QTreeWidgetItem *localStrRoot = new QTreeWidgetItem(zoneItem); localStrRoot->setText(0, "String Files"); localStrRoot->setIcon(0, QIcon(":/icons/icons/Icon_StringFile.png")); QTreeWidgetItem *localStrItem = new QTreeWidgetItem(localStrRoot); localStrItem->setText(0, aZoneFile->GetFileStem().section('.', 0, 0) + ".str"); localStrItem->setIcon(0, QIcon(":/icons/icons/Icon_StringFile.png")); } if (!assetMap.techSets.isEmpty()) { QTreeWidgetItem *techSetRoot = new QTreeWidgetItem(zoneItem); techSetRoot->setText(0, "Tech Sets"); techSetRoot->setIcon(0, QIcon(":/icons/icons/Icon_TechSetFile.png")); for (TechSet techSet : assetMap.techSets) { QTreeWidgetItem *techSetItem = new QTreeWidgetItem(techSetRoot); techSetItem->setText(0, techSet.name); techSetItem->setIcon(0, QIcon(":/icons/icons/Icon_TechSetFile.png")); } } if (!assetMap.rawFiles.isEmpty()) { QTreeWidgetItem *rawFileRoot = new QTreeWidgetItem(zoneItem); rawFileRoot->setText(0, "Raw Files"); rawFileRoot->setIcon(0, QIcon(":/icons/icons/Icon_GSCFile.png")); for (RawFile rawFile : assetMap.rawFiles) { if (!rawFile.length) { continue; } QTreeWidgetItem *tempItem = rawFileRoot; for (const QString &pathPart : rawFile.path.split('/')) { bool childFound = false; for (int i = 0; i < tempItem->childCount(); i++) { QTreeWidgetItem *childItem = tempItem->child(i); //qDebug() << "Child text: " << childItem->text(0); if (childItem->text(0) == pathPart) { tempItem = childItem; childFound = true; break; } } if (pathPart.contains(".gsc")) { QTreeWidgetItem *rawFileItem = new QTreeWidgetItem(tempItem); rawFileItem->setText(0, pathPart); tempItem = rawFileItem; } else if (!childFound) { tempItem = new QTreeWidgetItem(tempItem); tempItem->setText(0, pathPart); } } tempItem->setIcon(0, QIcon(":/icons/icons/Icon_GSCFile.png")); } } if (!assetMap.menuFiles.isEmpty()) { QTreeWidgetItem *menuRoot = new QTreeWidgetItem(zoneItem); menuRoot->setText(0, "Menu Files"); menuRoot->setIcon(0, QIcon(":/icons/icons/Icon_MenuFile.png")); int menuIndex = 1; for (MenuFile menuFile : assetMap.menuFiles) { QTreeWidgetItem *menuFileRoot = new QTreeWidgetItem(menuRoot); menuFileRoot->setText(0, QString("Menu %1").arg(menuIndex)); for (Menu menu : menuFile.menuDefs) { QTreeWidgetItem *menuItem = new QTreeWidgetItem(menuFileRoot); menuItem->setText(0, menu.name); menuItem->setIcon(0, QIcon(":/icons/icons/Icon_MenuFile.png")); } menuIndex++; } } if (!assetMap.images.isEmpty()) { QTreeWidgetItem *imageRoot = new QTreeWidgetItem(zoneItem); imageRoot->setText(0, "Images"); imageRoot->setIcon(0, QIcon(":/icons/icons/Icon_Image.png")); for (Image image : assetMap.images) { QTreeWidgetItem *imageItem = new QTreeWidgetItem(imageRoot); imageItem->setText(0, image.materialName); imageItem->setIcon(0, QIcon(":/icons/icons/Icon_Image.png")); } } mZoneFiles[aZoneFile->GetFileStem().section(".", 0, 0)] = aZoneFile; } 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")) { 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); clear(); }); 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; } 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; } 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; } invisibleRootItem()->removeChild(childItem); i--; } }); contextMenu->addMenu(closeMultipleAction); const QString fileStem = activeText.replace(".ff", ""); if (!mFastFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; return; } QAction *closeAction = new QAction("Close File"); contextMenu->addAction(closeAction); connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) { Q_UNUSED(checked); mFastFiles.remove(fileStem); invisibleRootItem()->removeChild(activeItem); }); QMenu *exportSubmenu = new QMenu("Export...", this); contextMenu->addMenu(exportSubmenu); std::shared_ptr fastFile = mFastFiles[fileStem]; QAction *exportDDSAction = new QAction("Export as Zone File"); exportSubmenu->addAction(exportDDSAction); connect(exportDDSAction, &QAction::triggered, this, [fastFile](bool checked) { Q_UNUSED(checked); //fastFile->SaveZone(); }); } else if (activeText.contains(".zone")) { const QString fileStem = activeText.replace(".zone", ""); 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 *exportDDSAction = new QAction("Export as Fast File"); exportSubmenu->addAction(exportDDSAction); connect(exportDDSAction, &QAction::triggered, this, [zoneFile](bool checked) { Q_UNUSED(checked); //zoneFile->SaveFastFile(); }); } QPoint pt(pos); contextMenu->exec(mapToGlobal(pt)); delete contextMenu; } void XTreeWidget::ItemSelectionChanged() { if (selectedItems().isEmpty()) { return; } QTreeWidgetItem *selectedItem = selectedItems().first(); if (!selectedItem) { return; } if (selectedItem->text(0).isEmpty()) { return; } QString selectedText = selectedItem->text(0); const QString fileStem = selectedText.section(".", 0, 0); QTreeWidgetItem *parentItem = selectedItem->parent(); if (selectedText.contains(".dds")) { if (!mDDSFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in DDS map!"; return; } std::shared_ptr ddsFile = mDDSFiles[fileStem]; emit DDSFileSelected(ddsFile); } else if (selectedText.contains(".iwi")) { if (!mIWIFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in IWI map!"; return; } emit IWIFileSelected(mIWIFiles[fileStem]); } else if (selectedText.contains(".ff")) { if (!mFastFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; return; } emit FastFileSelected(mFastFiles[fileStem]); } else if (selectedText.contains(".zone")) { if (!mZoneFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; return; } emit ZoneFileSelected(mZoneFiles[fileStem]); } else if (selectedText.contains(".str")) { if (!mZoneFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; return; } emit LocalStringSelected(mZoneFiles[fileStem]); } else if (selectedText.contains(".gsc")) { QTreeWidgetItem *zoneRoot = selectedItem; if (!zoneRoot) { return; } while (!zoneRoot->text(0).contains(".zone")) { zoneRoot = zoneRoot->parent(); if (!zoneRoot) { return; } } const QString fileStem = zoneRoot->text(0).section('.', 0, 0); if (!mZoneFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; return; } QVector rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles; for (RawFile rawFile : rawFiles) { if (rawFile.path.contains(selectedText)) { emit RawFileSelected(std::make_shared(rawFile)); return; } } } else if (parentItem && (parentItem->text(0) == "Images")) { QTreeWidgetItem *grandpaItem = 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)); break; } } } } else if (parentItem && (parentItem->text(0) == "Tech Sets")) { QTreeWidgetItem *grandpaItem = 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)); break; } } } } } ZoneFile XTreeWidget::pFindZoneFile(const QString aFilePart) { foreach (auto zoneFile, mZoneFiles) { if (zoneFile->GetFileStem() == aFilePart) { return *zoneFile.get(); } } return ZoneFile(); } FastFile XTreeWidget::pFindFastFile(const QString aFilePart) { foreach (auto fastFile, mFastFiles) { if (fastFile->GetFileStem() == aFilePart) { return *fastFile.get(); } } return FastFile(); } 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; } } QTreeWidgetItem *iwiItem = new QTreeWidgetItem(this); iwiItem->setIcon(0, QIcon(":/icons/icons/Icon_IWIFile.png")); 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; } } QTreeWidgetItem *ddsItem = new QTreeWidgetItem(this); ddsItem->setIcon(0, QIcon(":/icons/icons/Icon_DDSFile.png")); ddsItem->setText(0, ddsFileName); mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile; }