diff --git a/launcher/modplatform/import_ftb/PackHelpers.cpp b/launcher/modplatform/import_ftb/PackHelpers.cpp index e523b9d20..089b5fff2 100644 --- a/launcher/modplatform/import_ftb/PackHelpers.cpp +++ b/launcher/modplatform/import_ftb/PackHelpers.cpp @@ -19,6 +19,7 @@ #include "modplatform/import_ftb/PackHelpers.h" #include +#include #include #include @@ -27,6 +28,35 @@ namespace FTBImportAPP { +QIcon loadFTBIcon(const QString& imagePath) +{ + // Map of type byte to image type string + static const QHash imageTypeMap = { { 0x00, "png" }, { 0x01, "jpg" }, { 0x02, "gif" }, { 0x03, "webp" } }; + QFile file(imagePath); + if (!file.exists() || !file.open(QIODevice::ReadOnly)) { + return QIcon(); + } + char type; + if (!file.getChar(&type)) { + qDebug() << "Missing FTB image type header at" << imagePath; + return QIcon(); + } + if (!imageTypeMap.contains(type)) { + qDebug().nospace().noquote() << "Don't recognize FTB image type 0x" << QString::number(type, 16); + return QIcon(); + } + + auto imageType = imageTypeMap[type]; + // Extract actual image data beyond the first byte + QImageReader reader(&file, imageType); + auto pixmap = QPixmap::fromImageReader(&reader); + if (pixmap.isNull()) { + qDebug() << "The FTB image at" << imagePath << "is not valid"; + return QIcon(); + } + return QIcon(pixmap); +} + Modpack parseDirectory(QString path) { Modpack modpack{ path }; @@ -48,9 +78,14 @@ Modpack parseDirectory(QString path) qDebug() << "Couldn't load ftb instance json: " << e.cause(); return {}; } + auto versionsFile = QFileInfo(FS::PathCombine(path, "version.json")); - if (!versionsFile.exists() || !versionsFile.isFile()) + if (!versionsFile.exists() || !versionsFile.isFile()) { + versionsFile = QFileInfo(FS::PathCombine(path, ".ftbapp", "version.json")); + } + if (!versionsFile.exists() || !versionsFile.isFile()) { return {}; + } try { auto doc = Json::requireDocument(versionsFile.absoluteFilePath(), "FTB_APP version JSON file"); const auto root = doc.object(); @@ -85,6 +120,8 @@ Modpack parseDirectory(QString path) auto iconFile = QFileInfo(FS::PathCombine(path, "folder.jpg")); if (iconFile.exists() && iconFile.isFile()) { modpack.icon = QIcon(iconFile.absoluteFilePath()); + } else { // the logo is a file that the first bit denotes the image tipe followed by the actual image data + modpack.icon = loadFTBIcon(FS::PathCombine(path, ".ftbapp", "logo")); } return modpack; } diff --git a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp index 35e1dc110..9a2b31768 100644 --- a/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp +++ b/launcher/ui/pages/modplatform/import_ftb/ImportFTBPage.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include "FileSystem.h" #include "ListModel.h" @@ -88,6 +89,34 @@ void ImportFTBPage::retranslate() ui->retranslateUi(this); } +QString saveIconToTempFile(const QIcon& icon) +{ + if (icon.isNull()) { + return QString(); + } + + QPixmap pixmap = icon.pixmap(icon.availableSizes().last()); + if (pixmap.isNull()) { + return QString(); + } + + QTemporaryFile tempFile(QDir::tempPath() + "/iconXXXXXX.png"); + tempFile.setAutoRemove(false); + if (!tempFile.open()) { + return QString(); + } + + QString tempPath = tempFile.fileName(); + tempFile.close(); + + if (!pixmap.save(tempPath, "PNG")) { + QFile::remove(tempPath); + return QString(); + } + + return tempPath; // Success +} + void ImportFTBPage::suggestCurrent() { if (!isOpened) @@ -100,7 +129,14 @@ void ImportFTBPage::suggestCurrent() dialog->setSuggestedPack(selected.name, new PackInstallTask(selected)); QString editedLogoName = QString("ftb_%1_%2.jpg").arg(selected.name, QString::number(selected.id)); - dialog->setSuggestedIconFromFile(FS::PathCombine(selected.path, "folder.jpg"), editedLogoName); + auto iconPath = FS::PathCombine(selected.path, "folder.jpg"); + if (!QFileInfo::exists(iconPath)) { + // need to save the icon as that actual logo is not a image on the disk + iconPath = saveIconToTempFile(selected.icon); + } + if (!iconPath.isEmpty() && QFileInfo::exists(iconPath)) { + dialog->setSuggestedIconFromFile(iconPath, editedLogoName); + } } void ImportFTBPage::onPublicPackSelectionChanged(QModelIndex now, QModelIndex) diff --git a/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp index 8d3beea01..daa2189ad 100644 --- a/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/import_ftb/ListModel.cpp @@ -17,7 +17,6 @@ */ #include "ListModel.h" -#include #include #include #include