summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/gui/icons/MMCIcon.cpp14
-rw-r--r--api/gui/icons/MMCIcon.h2
-rw-r--r--api/logic/CMakeLists.txt4
-rw-r--r--api/logic/InstanceImportTask.cpp6
-rw-r--r--api/logic/icons/IconUtils.cpp62
-rw-r--r--api/logic/icons/IconUtils.h14
-rw-r--r--application/dialogs/ExportInstanceDialog.cpp60
-rw-r--r--application/dialogs/IconPickerDialog.cpp5
8 files changed, 129 insertions, 38 deletions
diff --git a/api/gui/icons/MMCIcon.cpp b/api/gui/icons/MMCIcon.cpp
index 2a2d6e6f..5058717a 100644
--- a/api/gui/icons/MMCIcon.cpp
+++ b/api/gui/icons/MMCIcon.cpp
@@ -102,3 +102,17 @@ void MMCIcon::replace(IconType new_type, const QString& key)
m_images[new_type].filename = QString();
m_images[new_type].key = key;
}
+
+QString MMCIcon::getFilePath() const
+{
+ if(m_current_type == IconType::ToBeDeleted){
+ return QString();
+ }
+ return m_images[m_current_type].filename;
+}
+
+
+bool MMCIcon::isBuiltIn() const
+{
+ return m_current_type == IconType::Builtin;
+}
diff --git a/api/gui/icons/MMCIcon.h b/api/gui/icons/MMCIcon.h
index c0eb5570..9fd1b9a2 100644
--- a/api/gui/icons/MMCIcon.h
+++ b/api/gui/icons/MMCIcon.h
@@ -46,4 +46,6 @@ struct MULTIMC_GUI_EXPORT MMCIcon
void remove(IconType rm_type);
void replace(IconType new_type, QIcon icon, QString path = QString());
void replace(IconType new_type, const QString &key);
+ bool isBuiltIn() const;
+ QString getFilePath() const;
};
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt
index 39850163..94da2682 100644
--- a/api/logic/CMakeLists.txt
+++ b/api/logic/CMakeLists.txt
@@ -182,9 +182,11 @@ set(NEWS_SOURCES
# Icon interface
set(ICONS_SOURCES
- # News System
+ # Icons System and related code
icons/IIconList.h
icons/IIconList.cpp
+ icons/IconUtils.h
+ icons/IconUtils.cpp
)
# Minecraft services status checker
diff --git a/api/logic/InstanceImportTask.cpp b/api/logic/InstanceImportTask.cpp
index bbab557a..1e93174c 100644
--- a/api/logic/InstanceImportTask.cpp
+++ b/api/logic/InstanceImportTask.cpp
@@ -6,6 +6,7 @@
#include "NullInstance.h"
#include "settings/INISettingsObject.h"
#include "icons/IIconList.h"
+#include "icons/IconUtils.h"
#include <QtConcurrentRun>
// FIXME: this does not belong here, it's Minecraft/Flame specific
@@ -393,8 +394,9 @@ void InstanceImportTask::processMultiMC()
else
{
m_instIcon = instance.iconKey();
- auto importIconPath = FS::PathCombine(instance.instanceRoot(), m_instIcon + ".png");
- if (QFile::exists(importIconPath))
+
+ auto importIconPath = IconUtils::findBestIconIn(instance.instanceRoot(), m_instIcon);
+ if (!importIconPath.isNull() && QFile::exists(importIconPath))
{
// import icon
auto iconList = ENV.icons();
diff --git a/api/logic/icons/IconUtils.cpp b/api/logic/icons/IconUtils.cpp
new file mode 100644
index 00000000..1b6d7553
--- /dev/null
+++ b/api/logic/icons/IconUtils.cpp
@@ -0,0 +1,62 @@
+#include "IconUtils.h"
+
+#include "FileSystem.h"
+#include <QDirIterator>
+
+#include <array>
+
+namespace {
+std::array<const char *, 6> validIconExtensions = {
+ "svg",
+ "png",
+ "ico",
+ "gif",
+ "jpg",
+ "jpeg"
+};
+}
+
+namespace IconUtils{
+
+QString findBestIconIn(const QString &folder, const QString & iconKey) {
+ int best_found = validIconExtensions.size();
+ QString best_filename;
+
+ QDirIterator it(folder, QDir::NoDotAndDotDot | QDir::Files, QDirIterator::NoIteratorFlags);
+ while (it.hasNext()) {
+ it.next();
+ auto fileInfo = it.fileInfo();
+
+ if(fileInfo.completeBaseName() != iconKey)
+ continue;
+
+ auto extension = fileInfo.suffix();
+
+ for(int i = 0; i < best_found; i++) {
+ if(extension == validIconExtensions[i]) {
+ best_found = i;
+ qDebug() << i << " : " << fileInfo.fileName();
+ best_filename = fileInfo.fileName();
+ }
+ }
+ }
+ return FS::PathCombine(folder, best_filename);
+}
+
+QString getIconFilter() {
+ QString out;
+ QTextStream stream(&out);
+ stream << '(';
+ for(size_t i = 0; i < validIconExtensions.size() - 1; i++) {
+ if(i > 0) {
+ stream << " ";
+ }
+ stream << "*." << validIconExtensions[i];
+ }
+ stream << " *." << validIconExtensions[validIconExtensions.size() - 1];
+ stream << ')';
+ return out;
+}
+
+}
+
diff --git a/api/logic/icons/IconUtils.h b/api/logic/icons/IconUtils.h
new file mode 100644
index 00000000..ce236946
--- /dev/null
+++ b/api/logic/icons/IconUtils.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <QString>
+#include "multimc_logic_export.h"
+
+namespace IconUtils {
+
+// Given a folder and an icon key, find 'best' of the icons with the given key in there and return its path
+MULTIMC_LOGIC_EXPORT QString findBestIconIn(const QString &folder, const QString & iconKey);
+
+// Get icon file type filter for file browser dialogs
+MULTIMC_LOGIC_EXPORT QString getIconFilter();
+
+}
diff --git a/application/dialogs/ExportInstanceDialog.cpp b/application/dialogs/ExportInstanceDialog.cpp
index 5419b000..49c082e9 100644
--- a/application/dialogs/ExportInstanceDialog.cpp
+++ b/application/dialogs/ExportInstanceDialog.cpp
@@ -343,43 +343,37 @@ void SaveIcon(InstancePtr m_instance)
auto iconKey = m_instance->iconKey();
auto iconList = MMC->icons();
auto mmcIcon = iconList->icon(iconKey);
- if(mmcIcon)
+ if(!mmcIcon || mmcIcon->isBuiltIn()) {
+ return;
+ }
+ auto path = mmcIcon->getFilePath();
+ if(!path.isNull()) {
+ QFileInfo inInfo (path);
+ FS::copy(path, FS::PathCombine(m_instance->instanceRoot(), inInfo.fileName())) ();
+ return;
+ }
+ auto & image = mmcIcon->m_images[mmcIcon->type()];
+ auto & icon = image.icon;
+ auto sizes = icon.availableSizes();
+ if(sizes.size() == 0)
{
- bool saveIcon = false;
- switch(mmcIcon->type())
- {
- case IconType::FileBased:
- case IconType::Transient:
- saveIcon = true;
- default:
- break;
- }
- if(saveIcon)
+ return;
+ }
+ auto areaOf = [](QSize size)
+ {
+ return size.width() * size.height();
+ };
+ QSize largest = sizes[0];
+ // find variant with largest area
+ for(auto size: sizes)
+ {
+ if(areaOf(largest) < areaOf(size))
{
- auto & image = mmcIcon->m_images[mmcIcon->type()];
- auto & icon = image.icon;
- auto sizes = icon.availableSizes();
- if(sizes.size() == 0)
- {
- return;
- }
- auto areaOf = [](QSize size)
- {
- return size.width() * size.height();
- };
- QSize largest = sizes[0];
- // find variant with largest area
- for(auto size: sizes)
- {
- if(areaOf(largest) < areaOf(size))
- {
- largest = size;
- }
- }
- auto pixmap = icon.pixmap(largest);
- pixmap.save(FS::PathCombine(m_instance->instanceRoot(), iconKey + ".png"));
+ largest = size;
}
}
+ auto pixmap = icon.pixmap(largest);
+ pixmap.save(FS::PathCombine(m_instance->instanceRoot(), iconKey + ".png"));
}
bool ExportInstanceDialog::doExport()
diff --git a/application/dialogs/IconPickerDialog.cpp b/application/dialogs/IconPickerDialog.cpp
index 7727aa49..7f930717 100644
--- a/application/dialogs/IconPickerDialog.cpp
+++ b/application/dialogs/IconPickerDialog.cpp
@@ -25,6 +25,7 @@
#include "groupview/InstanceDelegate.h"
#include "icons/IconList.h"
+#include "icons/IconUtils.h"
#include <DesktopServices.h>
IconPickerDialog::IconPickerDialog(QWidget *parent)
@@ -103,8 +104,8 @@ void IconPickerDialog::addNewIcon()
//: The title of the select icons open file dialog
QString selectIcons = tr("Select Icons");
//: The type of icon files
- QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(),
- tr("Icons") + "(*.png *.jpg *.jpeg *.ico *.svg *.gif)");
+ auto filter = IconUtils::getIconFilter();
+ QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), tr("Icons %1").arg(filter));
MMC->icons()->installIcons(fileNames);
}