Skip to content

Commit

Permalink
NOISSUE improve icon handling while importing and exporting instances
Browse files Browse the repository at this point in the history
Now it handles formats other than png.
  • Loading branch information
peterix committed May 31, 2019
1 parent 61913da commit 3470a3d
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 38 deletions.
14 changes: 14 additions & 0 deletions api/gui/icons/MMCIcon.cpp
Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions api/gui/icons/MMCIcon.h
Expand Up @@ -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;
};
4 changes: 3 additions & 1 deletion api/logic/CMakeLists.txt
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions api/logic/InstanceImportTask.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
62 changes: 62 additions & 0 deletions 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;
}

}

14 changes: 14 additions & 0 deletions 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();

}
60 changes: 27 additions & 33 deletions application/dialogs/ExportInstanceDialog.cpp
Expand Up @@ -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()
Expand Down
5 changes: 3 additions & 2 deletions application/dialogs/IconPickerDialog.cpp
Expand Up @@ -25,6 +25,7 @@
#include "groupview/InstanceDelegate.h"

#include "icons/IconList.h"
#include "icons/IconUtils.h"
#include <DesktopServices.h>

IconPickerDialog::IconPickerDialog(QWidget *parent)
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit 3470a3d

Please sign in to comment.