mirror of
https://github.com/MultiMC/MultiMC5.git
synced 2024-10-06 06:50:16 +00:00
WIP some work on modpack metadata
This commit is contained in:
parent
66c0999901
commit
4ab7091318
@ -200,7 +200,7 @@ void ComponentUpdateTask::loadComponents()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// load all the components OR their lists...
|
// load all the components OR their lists...
|
||||||
for (auto component: d->m_list->d->components)
|
for (auto component: d->m_list->d->persitentData.components)
|
||||||
{
|
{
|
||||||
shared_qobject_ptr<Task> loadTask;
|
shared_qobject_ptr<Task> loadTask;
|
||||||
LoadResult singleResult;
|
LoadResult singleResult;
|
||||||
@ -511,7 +511,7 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
|
|||||||
*
|
*
|
||||||
* NOTE: this is a placeholder and should eventually be replaced with something 'serious'
|
* NOTE: this is a placeholder and should eventually be replaced with something 'serious'
|
||||||
*/
|
*/
|
||||||
auto & components = d->m_list->d->components;
|
auto & components = d->m_list->d->persitentData.components;
|
||||||
auto & componentIndex = d->m_list->d->componentIndex;
|
auto & componentIndex = d->m_list->d->componentIndex;
|
||||||
|
|
||||||
RequireExSet allRequires;
|
RequireExSet allRequires;
|
||||||
|
61
api/logic/minecraft/ModpackInfo.h
Normal file
61
api/logic/minecraft/ModpackInfo.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
struct MaybeInt {
|
||||||
|
MaybeInt() = default;
|
||||||
|
MaybeInt(const int value):
|
||||||
|
hasValue(true),
|
||||||
|
content(value)
|
||||||
|
{};
|
||||||
|
|
||||||
|
operator bool() const {
|
||||||
|
return hasValue;
|
||||||
|
}
|
||||||
|
void operator=(int value) {
|
||||||
|
set(value);
|
||||||
|
}
|
||||||
|
int operator *() const {
|
||||||
|
return get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(int value) {
|
||||||
|
if(value == -1) {
|
||||||
|
hasValue = false;
|
||||||
|
content = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hasValue = true;
|
||||||
|
content = value;
|
||||||
|
}
|
||||||
|
int get() const {
|
||||||
|
if(hasValue) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void reset() {
|
||||||
|
hasValue = false;
|
||||||
|
content = 0;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool hasValue = false;
|
||||||
|
int content = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PackProfileModpackInfo
|
||||||
|
{
|
||||||
|
operator bool() const {
|
||||||
|
return hasValue;
|
||||||
|
}
|
||||||
|
bool hasValue = false;
|
||||||
|
|
||||||
|
QString platform;
|
||||||
|
QString repository;
|
||||||
|
QString coordinate;
|
||||||
|
|
||||||
|
MaybeInt minHeap;
|
||||||
|
MaybeInt optimalHeap;
|
||||||
|
MaybeInt maxHeap;
|
||||||
|
QString recommendedArgs;
|
||||||
|
};
|
@ -120,16 +120,42 @@ static ComponentPtr componentFromJsonV1(PackProfile * parent, const QString & co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the given component container data to a file
|
// Save the given component container data to a file
|
||||||
static bool savePackProfile(const QString & filename, const ComponentContainer & container)
|
static bool savePackProfile(const QString & filename, const PersistentPackProfileData & container)
|
||||||
{
|
{
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
obj.insert("formatVersion", currentComponentsFileVersion);
|
obj.insert("formatVersion", currentComponentsFileVersion);
|
||||||
QJsonArray orderArray;
|
QJsonArray orderArray;
|
||||||
for(auto component: container)
|
for(auto component: container.components)
|
||||||
{
|
{
|
||||||
orderArray.append(componentToJsonV1(component));
|
orderArray.append(componentToJsonV1(component));
|
||||||
}
|
}
|
||||||
obj.insert("components", orderArray);
|
obj.insert("components", orderArray);
|
||||||
|
|
||||||
|
if(container.modpackInfo)
|
||||||
|
{
|
||||||
|
const auto & info = container.modpackInfo;
|
||||||
|
QJsonObject out;
|
||||||
|
out["platform"] = info.platform;
|
||||||
|
if(!info.repository.isNull()) {
|
||||||
|
out["repository"] = info.repository;
|
||||||
|
}
|
||||||
|
if(!info.coordinate.isNull()) {
|
||||||
|
out["coordinate"] = info.coordinate;
|
||||||
|
}
|
||||||
|
if(!info.recommendedArgs.isNull()) {
|
||||||
|
out["recommendedArgs"] = info.recommendedArgs;
|
||||||
|
}
|
||||||
|
if(info.minHeap) {
|
||||||
|
out["minHeap"] = *info.minHeap;
|
||||||
|
}
|
||||||
|
if(info.maxHeap) {
|
||||||
|
out["maxHeap"] = *info.maxHeap;
|
||||||
|
}
|
||||||
|
if(info.optimalHeap) {
|
||||||
|
out["optimalHeap"] = *info.optimalHeap;
|
||||||
|
}
|
||||||
|
obj.insert("modpackInfo", out);
|
||||||
|
}
|
||||||
QSaveFile outFile(filename);
|
QSaveFile outFile(filename);
|
||||||
if (!outFile.open(QFile::WriteOnly))
|
if (!outFile.open(QFile::WriteOnly))
|
||||||
{
|
{
|
||||||
@ -153,7 +179,7 @@ static bool savePackProfile(const QString & filename, const ComponentContainer &
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the given file into component containers
|
// Read the given file into component containers
|
||||||
static bool loadPackProfile(PackProfile * parent, const QString & filename, const QString & componentJsonPattern, ComponentContainer & container)
|
static bool loadPackProfile(PackProfile * parent, const QString & filename, const QString & componentJsonPattern, PersistentPackProfileData & container)
|
||||||
{
|
{
|
||||||
QFile componentsFile(filename);
|
QFile componentsFile(filename);
|
||||||
if (!componentsFile.exists())
|
if (!componentsFile.exists())
|
||||||
@ -194,13 +220,34 @@ static bool loadPackProfile(PackProfile * parent, const QString & filename, cons
|
|||||||
for(auto item: orderArray)
|
for(auto item: orderArray)
|
||||||
{
|
{
|
||||||
auto obj = Json::requireObject(item, "Component must be an object.");
|
auto obj = Json::requireObject(item, "Component must be an object.");
|
||||||
container.append(componentFromJsonV1(parent, componentJsonPattern, obj));
|
container.components.append(componentFromJsonV1(parent, componentJsonPattern, obj));
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PackProfileModpackInfo result;
|
||||||
|
auto modpackInfoObj = Json::ensureObject(obj, "modpackInfo", {});
|
||||||
|
if(!modpackInfoObj.isEmpty()) {
|
||||||
|
result.hasValue = true;
|
||||||
|
result.platform = Json::requireString(modpackInfoObj, "platform");
|
||||||
|
result.repository = Json::ensureString(modpackInfoObj, "repository", QString());
|
||||||
|
result.coordinate = Json::ensureString(modpackInfoObj, "coordinate", QString());
|
||||||
|
result.maxHeap = Json::ensureInteger(modpackInfoObj, "maxHeap", -1);
|
||||||
|
result.minHeap = Json::ensureInteger(modpackInfoObj, "minHeap", -1);
|
||||||
|
result.optimalHeap = Json::ensureInteger(modpackInfoObj, "optimalHeap", -1);
|
||||||
|
result.recommendedArgs = Json::ensureString(modpackInfoObj, "recommendedArgs", QString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const JSONValidationError &err)
|
||||||
|
{
|
||||||
|
qCritical() << "Couldn't parse modpack info in " << componentsFile.fileName() << ": bad file format";
|
||||||
|
container.modpackInfo = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const JSONValidationError &err)
|
catch (const JSONValidationError &err)
|
||||||
{
|
{
|
||||||
qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format";
|
qCritical() << "Couldn't parse" << componentsFile.fileName() << ": bad file format";
|
||||||
container.clear();
|
container.components.clear();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -264,7 +311,7 @@ void PackProfile::save_internal()
|
|||||||
{
|
{
|
||||||
qDebug() << "Component list save performed now for" << d->m_instance->name();
|
qDebug() << "Component list save performed now for" << d->m_instance->name();
|
||||||
auto filename = componentsFilePath();
|
auto filename = componentsFilePath();
|
||||||
savePackProfile(filename, d->components);
|
savePackProfile(filename, d->persitentData);
|
||||||
d->dirty = false;
|
d->dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,38 +332,37 @@ bool PackProfile::load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load the new component list and swap it with the current one...
|
// load the new component list and swap it with the current one...
|
||||||
ComponentContainer newComponents;
|
PersistentPackProfileData newData;
|
||||||
if(!loadPackProfile(this, filename, patchesPattern(), newComponents))
|
if(!loadPackProfile(this, filename, patchesPattern(), newData))
|
||||||
{
|
{
|
||||||
qCritical() << "Failed to load the component config for instance" << d->m_instance->name();
|
qCritical() << "Failed to load the component config for instance" << d->m_instance->name();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// FIXME: actually use fine-grained updates, not this...
|
||||||
|
beginResetModel();
|
||||||
|
// disconnect all the old components
|
||||||
|
for(auto component: d->persitentData.components)
|
||||||
{
|
{
|
||||||
// FIXME: actually use fine-grained updates, not this...
|
disconnect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
||||||
beginResetModel();
|
|
||||||
// disconnect all the old components
|
|
||||||
for(auto component: d->components)
|
|
||||||
{
|
|
||||||
disconnect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
|
||||||
}
|
|
||||||
d->components.clear();
|
|
||||||
d->componentIndex.clear();
|
|
||||||
for(auto component: newComponents)
|
|
||||||
{
|
|
||||||
if(d->componentIndex.contains(component->m_uid))
|
|
||||||
{
|
|
||||||
qWarning() << "Ignoring duplicate component entry" << component->m_uid;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
connect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
|
||||||
d->components.append(component);
|
|
||||||
d->componentIndex[component->m_uid] = component;
|
|
||||||
}
|
|
||||||
endResetModel();
|
|
||||||
d->loaded = true;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
d->persitentData.components.clear();
|
||||||
|
d->componentIndex.clear();
|
||||||
|
for(auto component: newData.components)
|
||||||
|
{
|
||||||
|
if(d->componentIndex.contains(component->m_uid))
|
||||||
|
{
|
||||||
|
qWarning() << "Ignoring duplicate component entry" << component->m_uid;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
connect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
||||||
|
d->persitentData.components.append(component);
|
||||||
|
d->componentIndex[component->m_uid] = component;
|
||||||
|
}
|
||||||
|
d->persitentData.modpackInfo = newData.modpackInfo;
|
||||||
|
endResetModel();
|
||||||
|
d->loaded = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackProfile::reload(Net::Mode netmode)
|
void PackProfile::reload(Net::Mode netmode)
|
||||||
@ -436,7 +482,8 @@ bool PackProfile::migratePreComponentConfig()
|
|||||||
// upgrade the very old files from the beginnings of MultiMC 5
|
// upgrade the very old files from the beginnings of MultiMC 5
|
||||||
upgradeDeprecatedFiles(d->m_instance->instanceRoot(), d->m_instance->name());
|
upgradeDeprecatedFiles(d->m_instance->instanceRoot(), d->m_instance->name());
|
||||||
|
|
||||||
QList<ComponentPtr> components;
|
PersistentPackProfileData data;
|
||||||
|
auto & components = data.components;
|
||||||
QSet<QString> loaded;
|
QSet<QString> loaded;
|
||||||
|
|
||||||
auto addBuiltinPatch = [&](const QString &uid, bool asDependency, const QString & emptyVersion, const Meta::Require & req, const Meta::Require & conflict)
|
auto addBuiltinPatch = [&](const QString &uid, bool asDependency, const QString & emptyVersion, const Meta::Require & req, const Meta::Require & conflict)
|
||||||
@ -598,14 +645,14 @@ bool PackProfile::migratePreComponentConfig()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// new we have a complete list of components...
|
// new we have a complete list of components...
|
||||||
return savePackProfile(componentsFilePath(), components);
|
return savePackProfile(componentsFilePath(), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// END: save/load
|
// END: save/load
|
||||||
|
|
||||||
void PackProfile::appendComponent(ComponentPtr component)
|
void PackProfile::appendComponent(ComponentPtr component)
|
||||||
{
|
{
|
||||||
insertComponent(d->components.size(), component);
|
insertComponent(d->persitentData.components.size(), component);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PackProfile::insertComponent(size_t index, ComponentPtr component)
|
void PackProfile::insertComponent(size_t index, ComponentPtr component)
|
||||||
@ -622,7 +669,7 @@ void PackProfile::insertComponent(size_t index, ComponentPtr component)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
beginInsertRows(QModelIndex(), index, index);
|
beginInsertRows(QModelIndex(), index, index);
|
||||||
d->components.insert(index, component);
|
d->persitentData.components.insert(index, component);
|
||||||
d->componentIndex[id] = component;
|
d->componentIndex[id] = component;
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
connect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
connect(component.get(), &Component::dataChanged, this, &PackProfile::componentDataChanged);
|
||||||
@ -642,7 +689,7 @@ void PackProfile::componentDataChanged()
|
|||||||
}
|
}
|
||||||
// figure out which one is it... in a seriously dumb way.
|
// figure out which one is it... in a seriously dumb way.
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto component: d->components)
|
for (auto component: d->persitentData.components)
|
||||||
{
|
{
|
||||||
if(component.get() == objPtr)
|
if(component.get() == objPtr)
|
||||||
{
|
{
|
||||||
@ -671,7 +718,7 @@ bool PackProfile::remove(const int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
beginRemoveRows(QModelIndex(), index, index);
|
beginRemoveRows(QModelIndex(), index, index);
|
||||||
d->components.removeAt(index);
|
d->persitentData.components.removeAt(index);
|
||||||
d->componentIndex.remove(patch->getID());
|
d->componentIndex.remove(patch->getID());
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
invalidateLaunchProfile();
|
invalidateLaunchProfile();
|
||||||
@ -682,7 +729,7 @@ bool PackProfile::remove(const int index)
|
|||||||
bool PackProfile::remove(const QString id)
|
bool PackProfile::remove(const QString id)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto patch : d->components)
|
for (auto patch : d->persitentData.components)
|
||||||
{
|
{
|
||||||
if (patch->getID() == id)
|
if (patch->getID() == id)
|
||||||
{
|
{
|
||||||
@ -741,11 +788,11 @@ Component * PackProfile::getComponent(const QString &id)
|
|||||||
|
|
||||||
Component * PackProfile::getComponent(int index)
|
Component * PackProfile::getComponent(int index)
|
||||||
{
|
{
|
||||||
if(index < 0 || index >= d->components.size())
|
if(index < 0 || index >= d->persitentData.components.size())
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return d->components[index].get();
|
return d->persitentData.components[index].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant PackProfile::data(const QModelIndex &index, int role) const
|
QVariant PackProfile::data(const QModelIndex &index, int role) const
|
||||||
@ -756,10 +803,10 @@ QVariant PackProfile::data(const QModelIndex &index, int role) const
|
|||||||
int row = index.row();
|
int row = index.row();
|
||||||
int column = index.column();
|
int column = index.column();
|
||||||
|
|
||||||
if (row < 0 || row >= d->components.size())
|
if (row < 0 || row >= d->persitentData.components.size())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
auto patch = d->components.at(row);
|
auto patch = d->persitentData.components.at(row);
|
||||||
|
|
||||||
switch (role)
|
switch (role)
|
||||||
{
|
{
|
||||||
@ -831,7 +878,7 @@ bool PackProfile::setData(const QModelIndex& index, const QVariant& value, int r
|
|||||||
|
|
||||||
if (role == Qt::CheckStateRole)
|
if (role == Qt::CheckStateRole)
|
||||||
{
|
{
|
||||||
auto component = d->components[index.row()];
|
auto component = d->persitentData.components[index.row()];
|
||||||
if (component->setEnabled(!component->isEnabled()))
|
if (component->setEnabled(!component->isEnabled()))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -871,11 +918,11 @@ Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const
|
|||||||
|
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
|
|
||||||
if (row < 0 || row >= d->components.size()) {
|
if (row < 0 || row >= d->persitentData.components.size()) {
|
||||||
return Qt::NoItemFlags;
|
return Qt::NoItemFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto patch = d->components.at(row);
|
auto patch = d->persitentData.components.at(row);
|
||||||
// TODO: this will need fine-tuning later...
|
// TODO: this will need fine-tuning later...
|
||||||
if(patch->canBeDisabled() && !d->interactionDisabled)
|
if(patch->canBeDisabled() && !d->interactionDisabled)
|
||||||
{
|
{
|
||||||
@ -886,7 +933,7 @@ Qt::ItemFlags PackProfile::flags(const QModelIndex &index) const
|
|||||||
|
|
||||||
int PackProfile::rowCount(const QModelIndex &parent) const
|
int PackProfile::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
return d->components.size();
|
return d->persitentData.components.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int PackProfile::columnCount(const QModelIndex &parent) const
|
int PackProfile::columnCount(const QModelIndex &parent) const
|
||||||
@ -906,7 +953,7 @@ void PackProfile::move(const int index, const MoveDirection direction)
|
|||||||
theirIndex = index + 1;
|
theirIndex = index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0 || index >= d->components.size())
|
if (index < 0 || index >= d->persitentData.components.size())
|
||||||
return;
|
return;
|
||||||
if (theirIndex >= rowCount())
|
if (theirIndex >= rowCount())
|
||||||
theirIndex = rowCount() - 1;
|
theirIndex = rowCount() - 1;
|
||||||
@ -924,7 +971,7 @@ void PackProfile::move(const int index, const MoveDirection direction)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
|
beginMoveRows(QModelIndex(), index, index, QModelIndex(), togap);
|
||||||
d->components.swap(index, theirIndex);
|
d->persitentData.components.swap(index, theirIndex);
|
||||||
endMoveRows();
|
endMoveRows();
|
||||||
invalidateLaunchProfile();
|
invalidateLaunchProfile();
|
||||||
scheduleSave();
|
scheduleSave();
|
||||||
@ -1153,7 +1200,7 @@ std::shared_ptr<LaunchProfile> PackProfile::getProfile() const
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto profile = std::make_shared<LaunchProfile>();
|
auto profile = std::make_shared<LaunchProfile>();
|
||||||
for(auto file: d->components)
|
for(auto file: d->persitentData.components)
|
||||||
{
|
{
|
||||||
qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
|
qDebug() << "Applying" << file->getID() << (file->getProblemSeverity() == ProblemSeverity::Error ? "ERROR" : "GOOD");
|
||||||
file->applyTo(profile.get());
|
file->applyTo(profile.get());
|
||||||
@ -1217,7 +1264,7 @@ void PackProfile::disableInteraction(bool disable)
|
|||||||
{
|
{
|
||||||
if(d->interactionDisabled != disable) {
|
if(d->interactionDisabled != disable) {
|
||||||
d->interactionDisabled = disable;
|
d->interactionDisabled = disable;
|
||||||
auto size = d->components.size();
|
auto size = d->persitentData.components.size();
|
||||||
if(size) {
|
if(size) {
|
||||||
emit dataChanged(index(0), index(size - 1));
|
emit dataChanged(index(0), index(size - 1));
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,17 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include "ModpackInfo.h"
|
||||||
|
|
||||||
class MinecraftInstance;
|
class MinecraftInstance;
|
||||||
using ComponentContainer = QList<ComponentPtr>;
|
using ComponentContainer = QList<ComponentPtr>;
|
||||||
using ComponentIndex = QMap<QString, ComponentPtr>;
|
using ComponentIndex = QMap<QString, ComponentPtr>;
|
||||||
|
|
||||||
|
struct PersistentPackProfileData {
|
||||||
|
ComponentContainer components;
|
||||||
|
PackProfileModpackInfo modpackInfo;
|
||||||
|
};
|
||||||
|
|
||||||
struct PackProfileData
|
struct PackProfileData
|
||||||
{
|
{
|
||||||
// the instance this belongs to
|
// the instance this belongs to
|
||||||
@ -30,8 +36,9 @@ struct PackProfileData
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// persistent list of components and related machinery
|
PersistentPackProfileData persitentData;
|
||||||
ComponentContainer components;
|
|
||||||
|
// temporary runtime machinery
|
||||||
ComponentIndex componentIndex;
|
ComponentIndex componentIndex;
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
QTimer m_saveTimer;
|
QTimer m_saveTimer;
|
||||||
@ -39,4 +46,3 @@ struct PackProfileData
|
|||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
bool interactionDisabled = true;
|
bool interactionDisabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,6 +84,8 @@ SET(MULTIMC_SOURCES
|
|||||||
pages/instance/ResourcePackPage.h
|
pages/instance/ResourcePackPage.h
|
||||||
pages/instance/ModFolderPage.cpp
|
pages/instance/ModFolderPage.cpp
|
||||||
pages/instance/ModFolderPage.h
|
pages/instance/ModFolderPage.h
|
||||||
|
pages/instance/ModpackPage.cpp
|
||||||
|
pages/instance/ModpackPage.h
|
||||||
pages/instance/NotesPage.cpp
|
pages/instance/NotesPage.cpp
|
||||||
pages/instance/NotesPage.h
|
pages/instance/NotesPage.h
|
||||||
pages/instance/LogPage.cpp
|
pages/instance/LogPage.cpp
|
||||||
@ -238,6 +240,7 @@ SET(MULTIMC_UIS
|
|||||||
pages/instance/GameOptionsPage.ui
|
pages/instance/GameOptionsPage.ui
|
||||||
pages/instance/VersionPage.ui
|
pages/instance/VersionPage.ui
|
||||||
pages/instance/ModFolderPage.ui
|
pages/instance/ModFolderPage.ui
|
||||||
|
pages/instance/ModpackPage.ui
|
||||||
pages/instance/LogPage.ui
|
pages/instance/LogPage.ui
|
||||||
pages/instance/InstanceSettingsPage.ui
|
pages/instance/InstanceSettingsPage.ui
|
||||||
pages/instance/NotesPage.ui
|
pages/instance/NotesPage.ui
|
||||||
|
148
application/pages/instance/ModpackPage.cpp
Normal file
148
application/pages/instance/ModpackPage.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#include "ModpackPage.h"
|
||||||
|
#include "ui_ModpackPage.h"
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#include "dialogs/VersionSelectDialog.h"
|
||||||
|
#include "JavaCommon.h"
|
||||||
|
#include "MultiMC.h"
|
||||||
|
|
||||||
|
#include <FileSystem.h>
|
||||||
|
#include "minecraft/ModpackInfo.h"
|
||||||
|
|
||||||
|
|
||||||
|
ModpackPage::ModpackPage(BaseInstance *inst, QWidget *parent)
|
||||||
|
: QWidget(parent), ui(new Ui::ModpackPage), m_instance(inst)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
connect(ui->activateUIButton, &QCommandLinkButton::clicked, this, &ModpackPage::activateUIClicked);
|
||||||
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModpackPage::shouldDisplay() const
|
||||||
|
{
|
||||||
|
return !m_instance->isRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
ModpackPage::~ModpackPage()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModpackPage::activateUIClicked(bool)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModpackPage::apply()
|
||||||
|
{
|
||||||
|
applySettings();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModpackPage::applySettings()
|
||||||
|
{
|
||||||
|
PackProfileModpackInfo out;
|
||||||
|
out.hasValue = ui->modpackCheck->isChecked();
|
||||||
|
// FIXME: add a layer of indirection here
|
||||||
|
if(out.hasValue) {
|
||||||
|
out.platform = ui->platformComboBox->currentText();
|
||||||
|
if(ui->javaArgumentsGroupBox->isChecked()) {
|
||||||
|
out.recommendedArgs = ui->jvmArgsTextBox->toPlainText();
|
||||||
|
}
|
||||||
|
if(ui->repositoryCheck->isChecked()) {
|
||||||
|
out.repository = ui->repositoryEdit->text();
|
||||||
|
}
|
||||||
|
if(ui->coordinateCheck->isChecked()) {
|
||||||
|
out.coordinate = ui->coordinateEdit->text();
|
||||||
|
}
|
||||||
|
if(ui->maxMemCheck->isChecked()) {
|
||||||
|
out.maxHeap = ui->maxMemSpinBox->value();
|
||||||
|
}
|
||||||
|
if(ui->mimMemCheck->isChecked()) {
|
||||||
|
out.minHeap = ui->minMemSpinBox->value();
|
||||||
|
}
|
||||||
|
if(ui->optMemCheck->isChecked()) {
|
||||||
|
out.optimalHeap = ui->optMemSpinBox->value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct PackProfileModpackInfo
|
||||||
|
{
|
||||||
|
operator bool() const {
|
||||||
|
return hasValue;
|
||||||
|
}
|
||||||
|
bool hasValue = false;
|
||||||
|
|
||||||
|
QString platform;
|
||||||
|
QString repository;
|
||||||
|
QString coordinate;
|
||||||
|
|
||||||
|
MaybeInt minHeap;
|
||||||
|
MaybeInt optimalHeap;
|
||||||
|
MaybeInt maxHeap;
|
||||||
|
QString recommendedArgs;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModpackPage::loadSettings()
|
||||||
|
{
|
||||||
|
PackProfileModpackInfo in;
|
||||||
|
|
||||||
|
// Console
|
||||||
|
ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool());
|
||||||
|
ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool());
|
||||||
|
ui->autoCloseConsoleCheck->setChecked(m_settings->get("AutoCloseConsole").toBool());
|
||||||
|
ui->showConsoleErrorCheck->setChecked(m_settings->get("ShowConsoleOnError").toBool());
|
||||||
|
|
||||||
|
// Window Size
|
||||||
|
ui->windowSizeGroupBox->setChecked(m_settings->get("OverrideWindow").toBool());
|
||||||
|
ui->maximizedCheckBox->setChecked(m_settings->get("LaunchMaximized").toBool());
|
||||||
|
ui->windowWidthSpinBox->setValue(m_settings->get("MinecraftWinWidth").toInt());
|
||||||
|
ui->windowHeightSpinBox->setValue(m_settings->get("MinecraftWinHeight").toInt());
|
||||||
|
|
||||||
|
// Memory
|
||||||
|
ui->memoryGroupBox->setChecked(m_settings->get("OverrideMemory").toBool());
|
||||||
|
int min = m_settings->get("MinMemAlloc").toInt();
|
||||||
|
int max = m_settings->get("MaxMemAlloc").toInt();
|
||||||
|
if(min < max)
|
||||||
|
{
|
||||||
|
ui->minMemSpinBox->setValue(min);
|
||||||
|
ui->maxMemSpinBox->setValue(max);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->minMemSpinBox->setValue(max);
|
||||||
|
ui->maxMemSpinBox->setValue(min);
|
||||||
|
}
|
||||||
|
ui->permGenSpinBox->setValue(m_settings->get("PermGen").toInt());
|
||||||
|
bool permGenVisible = m_settings->get("PermGenVisible").toBool();
|
||||||
|
ui->permGenSpinBox->setVisible(permGenVisible);
|
||||||
|
ui->labelPermGen->setVisible(permGenVisible);
|
||||||
|
ui->labelPermgenNote->setVisible(permGenVisible);
|
||||||
|
|
||||||
|
|
||||||
|
// Java Settings
|
||||||
|
bool overrideJava = m_settings->get("OverrideJava").toBool();
|
||||||
|
bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava;
|
||||||
|
bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava;
|
||||||
|
|
||||||
|
ui->javaSettingsGroupBox->setChecked(overrideLocation);
|
||||||
|
ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString());
|
||||||
|
|
||||||
|
ui->javaArgumentsGroupBox->setChecked(overrideArgs);
|
||||||
|
ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString());
|
||||||
|
|
||||||
|
// Custom commands
|
||||||
|
ui->customCommands->initialize(
|
||||||
|
true,
|
||||||
|
m_settings->get("OverrideCommands").toBool(),
|
||||||
|
m_settings->get("PreLaunchCommand").toString(),
|
||||||
|
m_settings->get("WrapperCommand").toString(),
|
||||||
|
m_settings->get("PostExitCommand").toString()
|
||||||
|
);
|
||||||
|
}
|
70
application/pages/instance/ModpackPage.h
Normal file
70
application/pages/instance/ModpackPage.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* Copyright 2013-2019 MultiMC Contributors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "java/JavaChecker.h"
|
||||||
|
#include "BaseInstance.h"
|
||||||
|
#include <QObjectPtr.h>
|
||||||
|
#include "pages/BasePage.h"
|
||||||
|
#include "MultiMC.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class ModpackPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModpackPage : public QWidget, public BasePage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ModpackPage(BaseInstance *inst, QWidget *parent = 0);
|
||||||
|
virtual ~ModpackPage();
|
||||||
|
virtual QString displayName() const override
|
||||||
|
{
|
||||||
|
return tr("Modpack");
|
||||||
|
}
|
||||||
|
virtual QIcon icon() const override
|
||||||
|
{
|
||||||
|
return MMC->getThemedIcon("modpack");
|
||||||
|
}
|
||||||
|
virtual QString id() const override
|
||||||
|
{
|
||||||
|
return "modpack";
|
||||||
|
}
|
||||||
|
virtual bool apply() override;
|
||||||
|
virtual QString helpPage() const override
|
||||||
|
{
|
||||||
|
return "Modpack-settings";
|
||||||
|
}
|
||||||
|
virtual bool shouldDisplay() const override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_javaDetectBtn_clicked();
|
||||||
|
void on_javaTestBtn_clicked();
|
||||||
|
void on_javaBrowseBtn_clicked();
|
||||||
|
|
||||||
|
void applySettings();
|
||||||
|
void loadSettings();
|
||||||
|
|
||||||
|
void activateUIClicked(bool checked);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::ModpackPage *ui;
|
||||||
|
BaseInstance *m_instance;
|
||||||
|
};
|
253
application/pages/instance/ModpackPage.ui
Normal file
253
application/pages/instance/ModpackPage.ui
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ModpackPage</class>
|
||||||
|
<widget class="QWidget" name="ModpackPage">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>779</width>
|
||||||
|
<height>781</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="settingsTabs">
|
||||||
|
<property name="tabShape">
|
||||||
|
<enum>QTabWidget::Rounded</enum>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Modpack</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLineEdit" name="coordinateEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="repositoryCheck">
|
||||||
|
<property name="text">
|
||||||
|
<string>Repository</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="platformComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="modpackCheck">
|
||||||
|
<property name="text">
|
||||||
|
<string>Instance is based on a modpack</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="platformLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Modpack Platform</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>platformComboBox</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QCheckBox" name="coordinateCheck">
|
||||||
|
<property name="text">
|
||||||
|
<string>Coordinate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="repositoryEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="javaTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Java</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="memoryGroupBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Memor&y</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="mimMemCheck">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimum memory allocation:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QCheckBox" name="optMemCheck">
|
||||||
|
<property name="text">
|
||||||
|
<string>Optimal memory allocation:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="minMemSpinBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The amount of memory Minecraft is started with.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true"> MB</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>65536</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1024</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="maxMemCheck">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum memory allocation:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSpinBox" name="maxMemSpinBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The maximum amount of memory Minecraft is allowed to use.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true"> MB</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>65536</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1024</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QSpinBox" name="optMemSpinBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The amount of memory available to store loaded Java classes.</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string notr="true"> MB</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>64</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999999999</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1024</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="javaArgumentsGroupBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Java argumen&ts</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_6">
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QPlainTextEdit" name="jvmArgsTextBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCommandLinkButton" name="activateUIButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Click here to unlock</string>
|
||||||
|
</property>
|
||||||
|
<property name="description">
|
||||||
|
<string>These are the modpack defaults and shouldn't be changed unless you are working on the modpack or want to change its source or target version, or work on it.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>activateUIButton</tabstop>
|
||||||
|
<tabstop>settingsTabs</tabstop>
|
||||||
|
<tabstop>modpackCheck</tabstop>
|
||||||
|
<tabstop>platformComboBox</tabstop>
|
||||||
|
<tabstop>repositoryCheck</tabstop>
|
||||||
|
<tabstop>repositoryEdit</tabstop>
|
||||||
|
<tabstop>coordinateCheck</tabstop>
|
||||||
|
<tabstop>coordinateEdit</tabstop>
|
||||||
|
<tabstop>mimMemCheck</tabstop>
|
||||||
|
<tabstop>minMemSpinBox</tabstop>
|
||||||
|
<tabstop>maxMemCheck</tabstop>
|
||||||
|
<tabstop>maxMemSpinBox</tabstop>
|
||||||
|
<tabstop>optMemCheck</tabstop>
|
||||||
|
<tabstop>optMemSpinBox</tabstop>
|
||||||
|
<tabstop>javaArgumentsGroupBox</tabstop>
|
||||||
|
<tabstop>jvmArgsTextBox</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -101,7 +101,10 @@ void TwitchPage::suggestCurrent()
|
|||||||
dialog->setSuggestedPack();
|
dialog->setSuggestedPack();
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog->setSuggestedPack(current.name, new InstanceImportTask(current.latestFile.downloadUrl));
|
dialog->setSuggestedPack(
|
||||||
|
current.name,
|
||||||
|
new InstanceImportTask(current.latestFile.downloadUrl)
|
||||||
|
);
|
||||||
QString editedLogoName;
|
QString editedLogoName;
|
||||||
editedLogoName = "twitch_" + current.logoName.section(".", 0, 0);
|
editedLogoName = "twitch_" + current.logoName.section(".", 0, 0);
|
||||||
model->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo)
|
model->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo)
|
||||||
|
Loading…
Reference in New Issue
Block a user