NOISSUE redo new instance dialog

This commit is contained in:
Petr Mrázek 2018-03-19 02:36:12 +01:00
parent 4c7ea0f99a
commit 8e44ab2338
98 changed files with 1916 additions and 1254 deletions

View File

@ -8,14 +8,10 @@ set(CORE_SOURCES
BaseInstaller.cpp BaseInstaller.cpp
BaseVersionList.h BaseVersionList.h
BaseVersionList.cpp BaseVersionList.cpp
InstanceCreationTask.h
InstanceCreationTask.cpp
InstanceCopyTask.h
InstanceCopyTask.cpp
InstanceImportTask.h
InstanceImportTask.cpp
InstanceList.h InstanceList.h
InstanceList.cpp InstanceList.cpp
InstanceTask.h
InstanceTask.cpp
LoggedProcess.h LoggedProcess.h
LoggedProcess.cpp LoggedProcess.cpp
MessageLevel.cpp MessageLevel.cpp
@ -32,6 +28,14 @@ set(CORE_SOURCES
MMCStrings.h MMCStrings.h
MMCStrings.cpp MMCStrings.cpp
# Basic instance manipulation tasks (derived from InstanceTask)
InstanceCreationTask.h
InstanceCreationTask.cpp
InstanceCopyTask.h
InstanceCopyTask.cpp
InstanceImportTask.h
InstanceImportTask.cpp
# Use tracking separate from memory management # Use tracking separate from memory management
Usable.h Usable.h
@ -42,6 +46,10 @@ set(CORE_SOURCES
Env.h Env.h
Env.cpp Env.cpp
# String filters
Filter.h
Filter.cpp
# JSON parsing helpers # JSON parsing helpers
Json.h Json.h
Json.cpp Json.cpp

31
api/logic/Filter.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "Filter.h"
Filter::~Filter(){}
ContainsFilter::ContainsFilter(const QString& pattern) : pattern(pattern){}
ContainsFilter::~ContainsFilter(){}
bool ContainsFilter::accepts(const QString& value)
{
return value.contains(pattern);
}
ExactFilter::ExactFilter(const QString& pattern) : pattern(pattern){}
ExactFilter::~ExactFilter(){}
bool ExactFilter::accepts(const QString& value)
{
return value.contains(pattern);
}
RegexpFilter::RegexpFilter(const QString& regexp, bool invert)
:invert(invert)
{
pattern.setPattern(regexp);
pattern.optimize();
}
RegexpFilter::~RegexpFilter(){}
bool RegexpFilter::accepts(const QString& value)
{
auto match = pattern.match(value);
bool matched = match.hasMatch();
return invert ? (!matched) : (matched);
}

44
api/logic/Filter.h Normal file
View File

@ -0,0 +1,44 @@
#pragma once
#include <QString>
#include <QRegularExpression>
#include "multimc_logic_export.h"
class MULTIMC_LOGIC_EXPORT Filter
{
public:
virtual ~Filter();
virtual bool accepts(const QString & value) = 0;
};
class MULTIMC_LOGIC_EXPORT ContainsFilter: public Filter
{
public:
ContainsFilter(const QString &pattern);
virtual ~ContainsFilter();
bool accepts(const QString & value) override;
private:
QString pattern;
};
class MULTIMC_LOGIC_EXPORT ExactFilter: public Filter
{
public:
ExactFilter(const QString &pattern);
virtual ~ExactFilter();
bool accepts(const QString & value) override;
private:
QString pattern;
};
class MULTIMC_LOGIC_EXPORT RegexpFilter: public Filter
{
public:
RegexpFilter(const QString &regexp, bool invert);
virtual ~RegexpFilter();
bool accepts(const QString & value) override;
private:
QRegularExpression pattern;
bool invert = false;
};

View File

@ -412,46 +412,13 @@ private:
QTimer m_backoffTimer; QTimer m_backoffTimer;
}; };
#include "InstanceImportTask.h" #include "InstanceTask.h"
Task * FolderInstanceProvider::zipImportTask(const QUrl sourceUrl, const QString& instName, const QString& instGroup, const QString& instIcon) Task * FolderInstanceProvider::wrapInstanceTask(InstanceTask * task)
{ {
auto stagingPath = getStagedInstancePath(); auto stagingPath = getStagedInstancePath();
auto task = new InstanceImportTask(m_globalSettings, sourceUrl, stagingPath, instName, instIcon, instGroup); task->setStagingPath(stagingPath);
return new FolderInstanceStaging(this, task, stagingPath, instName, instGroup); task->setParentSettings(m_globalSettings);
} return new FolderInstanceStaging(this, task, stagingPath, task->name(), task->group());
#include "InstanceCreationTask.h"
Task * FolderInstanceProvider::creationTask(BaseVersionPtr version, const QString& instName, const QString& instGroup, const QString& instIcon)
{
auto stagingPath = getStagedInstancePath();
auto task = new InstanceCreationTask(m_globalSettings, stagingPath, version, instName, instIcon, instGroup);
return new FolderInstanceStaging(this, task, stagingPath, instName, instGroup);
}
#include <modplatform/ftb/FtbPackInstallTask.h>
Task * FolderInstanceProvider::ftbCreationTask(FtbPackDownloader *downloader, const QString& instName, const QString& instGroup, const QString& instIcon)
{
auto stagingPath = getStagedInstancePath();
auto task = new FtbPackInstallTask(downloader, m_globalSettings, stagingPath, instName, instIcon, instGroup);
return new FolderInstanceStaging(this, task, stagingPath, instName, instGroup);
}
#include "InstanceCopyTask.h"
Task * FolderInstanceProvider::copyTask(const InstancePtr& oldInstance, const QString& instName, const QString& instGroup, const QString& instIcon, bool copySaves)
{
auto stagingPath = getStagedInstancePath();
auto task = new InstanceCopyTask(m_globalSettings, stagingPath, oldInstance, instName, instIcon, instGroup, copySaves);
return new FolderInstanceStaging(this, task, stagingPath, instName, instGroup);
}
// FIXME: find a better place for this
#include "minecraft/legacy/LegacyUpgradeTask.h"
Task * FolderInstanceProvider::legacyUpgradeTask(const InstancePtr& oldInstance)
{
auto stagingPath = getStagedInstancePath();
QString newName = tr("%1 (Migrated)").arg(oldInstance->name());
auto task = new LegacyUpgradeTask(m_globalSettings, stagingPath, oldInstance, newName);
return new FolderInstanceStaging(this, task, stagingPath, newName, oldInstance->group());
} }
QString FolderInstanceProvider::getStagedInstancePath() QString FolderInstanceProvider::getStagedInstancePath()

View File

@ -2,9 +2,9 @@
#include "BaseInstanceProvider.h" #include "BaseInstanceProvider.h"
#include <QMap> #include <QMap>
#include <modplatform/ftb/FtbPackDownloader.h>
class QFileSystemWatcher; class QFileSystemWatcher;
class InstanceTask;
class MULTIMC_LOGIC_EXPORT FolderInstanceProvider : public BaseInstanceProvider class MULTIMC_LOGIC_EXPORT FolderInstanceProvider : public BaseInstanceProvider
{ {
@ -20,6 +20,7 @@ public:
InstancePtr loadInstance(const InstanceId& id) override; InstancePtr loadInstance(const InstanceId& id) override;
/*
// create instance in this provider // create instance in this provider
Task * creationTask(BaseVersionPtr version, const QString &instName, const QString &instGroup, const QString &instIcon); Task * creationTask(BaseVersionPtr version, const QString &instName, const QString &instGroup, const QString &instIcon);
@ -34,6 +35,10 @@ public:
// migrate an instance to the current format // migrate an instance to the current format
Task * legacyUpgradeTask(const InstancePtr& oldInstance); Task * legacyUpgradeTask(const InstancePtr& oldInstance);
*/
// Wrap an instance creation task in some more task machinery and make it ready to be used
Task * wrapInstanceTask(InstanceTask * task);
/** /**
* Create a new empty staging area for instance creation and @return a path/key top commit it later. * Create a new empty staging area for instance creation and @return a path/key top commit it later.

View File

@ -6,14 +6,9 @@
#include "pathmatcher/RegexpMatcher.h" #include "pathmatcher/RegexpMatcher.h"
#include <QtConcurrentRun> #include <QtConcurrentRun>
InstanceCopyTask::InstanceCopyTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance, const QString& instName, const QString& instIcon, const QString& instGroup, bool copySaves) InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, bool copySaves)
{ {
m_globalSettings = settings;
m_stagingPath = stagingPath;
m_origInstance = origInstance; m_origInstance = origInstance;
m_instName = instName;
m_instIcon = instIcon;
m_instGroup = instGroup;
if(!copySaves) if(!copySaves)
{ {

View File

@ -9,16 +9,15 @@
#include "settings/SettingsObject.h" #include "settings/SettingsObject.h"
#include "BaseVersion.h" #include "BaseVersion.h"
#include "BaseInstance.h" #include "BaseInstance.h"
#include "InstanceTask.h"
class BaseInstanceProvider; class BaseInstanceProvider;
class MULTIMC_LOGIC_EXPORT InstanceCopyTask : public Task class MULTIMC_LOGIC_EXPORT InstanceCopyTask : public InstanceTask
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceCopyTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance, const QString &instName, explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves);
const QString &instIcon, const QString &instGroup, bool copySaves);
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.
@ -27,15 +26,8 @@ protected:
void copyAborted(); void copyAborted();
private: /* data */ private: /* data */
SettingsObjectPtr m_globalSettings;
InstancePtr m_origInstance; InstancePtr m_origInstance;
QString m_instName;
QString m_instIcon;
QString m_instGroup;
QString m_stagingPath;
QFuture<bool> m_copyFuture; QFuture<bool> m_copyFuture;
QFutureWatcher<bool> m_copyFutureWatcher; QFutureWatcher<bool> m_copyFutureWatcher;
std::unique_ptr<IPathMatcher> m_matcher; std::unique_ptr<IPathMatcher> m_matcher;
}; };

View File

@ -7,14 +7,8 @@
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
#include "minecraft/ComponentList.h" #include "minecraft/ComponentList.h"
InstanceCreationTask::InstanceCreationTask(SettingsObjectPtr settings, const QString & stagingPath, BaseVersionPtr version, InstanceCreationTask::InstanceCreationTask(BaseVersionPtr version)
const QString& instName, const QString& instIcon, const QString& instGroup)
{ {
m_globalSettings = settings;
m_stagingPath = stagingPath;
m_instName = instName;
m_instIcon = instIcon;
m_instGroup = instGroup;
m_version = version; m_version = version;
} }

View File

@ -6,24 +6,18 @@
#include <QUrl> #include <QUrl>
#include "settings/SettingsObject.h" #include "settings/SettingsObject.h"
#include "BaseVersion.h" #include "BaseVersion.h"
#include "InstanceTask.h"
class MULTIMC_LOGIC_EXPORT InstanceCreationTask : public Task class MULTIMC_LOGIC_EXPORT InstanceCreationTask : public InstanceTask
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceCreationTask(SettingsObjectPtr settings, const QString & stagingPath, BaseVersionPtr version, const QString &instName, explicit InstanceCreationTask(BaseVersionPtr version);
const QString &instIcon, const QString &instGroup);
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.
virtual void executeTask() override; virtual void executeTask() override;
private: /* data */ private: /* data */
SettingsObjectPtr m_globalSettings;
QString m_stagingPath;
BaseVersionPtr m_version; BaseVersionPtr m_version;
QString m_instName;
QString m_instIcon;
QString m_instGroup;
}; };

View File

@ -16,15 +16,9 @@
#include "modplatform/flame/PackManifest.h" #include "modplatform/flame/PackManifest.h"
#include "Json.h" #include "Json.h"
InstanceImportTask::InstanceImportTask(SettingsObjectPtr settings, const QUrl sourceUrl, const QString & stagingPath, InstanceImportTask::InstanceImportTask(const QUrl sourceUrl)
const QString &instName, const QString &instIcon, const QString &instGroup)
{ {
m_globalSettings = settings;
m_sourceUrl = sourceUrl; m_sourceUrl = sourceUrl;
m_stagingPath = stagingPath;
m_instName = instName;
m_instIcon = instIcon;
m_instGroup = instGroup;
} }
void InstanceImportTask::executeTask() void InstanceImportTask::executeTask()

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "tasks/Task.h" #include "InstanceTask.h"
#include "multimc_logic_export.h" #include "multimc_logic_export.h"
#include "net/NetJob.h" #include "net/NetJob.h"
#include <QUrl> #include <QUrl>
@ -16,12 +16,11 @@ namespace Flame
class FileResolvingTask; class FileResolvingTask;
} }
class MULTIMC_LOGIC_EXPORT InstanceImportTask : public Task class MULTIMC_LOGIC_EXPORT InstanceImportTask : public InstanceTask
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit InstanceImportTask(SettingsObjectPtr settings, const QUrl sourceUrl, const QString & stagingPath, const QString &instName, explicit InstanceImportTask(const QUrl sourceUrl);
const QString &instIcon, const QString &instGroup);
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.
@ -40,16 +39,11 @@ private slots:
void extractAborted(); void extractAborted();
private: /* data */ private: /* data */
SettingsObjectPtr m_globalSettings;
NetJobPtr m_filesNetJob; NetJobPtr m_filesNetJob;
shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver; shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver;
QUrl m_sourceUrl; QUrl m_sourceUrl;
QString m_archivePath; QString m_archivePath;
bool m_downloadRequired = false; bool m_downloadRequired = false;
QString m_instName;
QString m_instIcon;
QString m_instGroup;
QString m_stagingPath;
std::unique_ptr<QuaZip> m_packZip; std::unique_ptr<QuaZip> m_packZip;
QFuture<QStringList> m_extractFuture; QFuture<QStringList> m_extractFuture;
QFutureWatcher<QStringList> m_extractFutureWatcher; QFutureWatcher<QStringList> m_extractFutureWatcher;

View File

@ -0,0 +1,9 @@
#include "InstanceTask.h"
InstanceTask::InstanceTask()
{
}
InstanceTask::~InstanceTask()
{
}

55
api/logic/InstanceTask.h Normal file
View File

@ -0,0 +1,55 @@
#pragma once
#include "tasks/Task.h"
#include "multimc_logic_export.h"
#include "settings/SettingsObject.h"
class BaseInstanceProvider;
class MULTIMC_LOGIC_EXPORT InstanceTask : public Task
{
Q_OBJECT
public:
explicit InstanceTask();
virtual ~InstanceTask();
void setParentSettings(SettingsObjectPtr settings)
{
m_globalSettings = settings;
}
void setStagingPath(const QString &stagingPath)
{
m_stagingPath = stagingPath;
}
void setName(const QString &name)
{
m_instName = name;
}
QString name() const
{
return m_instName;
}
void setIcon(const QString &icon)
{
m_instIcon = icon;
}
void setGroup(const QString &group)
{
m_instGroup = group;
}
QString group() const
{
return m_instGroup;
}
protected: /* data */
SettingsObjectPtr m_globalSettings;
QString m_instName;
QString m_instIcon;
QString m_instGroup;
QString m_stagingPath;
};

View File

@ -10,12 +10,9 @@
#include "minecraft/ComponentList.h" #include "minecraft/ComponentList.h"
#include "classparser.h" #include "classparser.h"
LegacyUpgradeTask::LegacyUpgradeTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance, const QString & newName) LegacyUpgradeTask::LegacyUpgradeTask(InstancePtr origInstance)
{ {
m_globalSettings = settings;
m_stagingPath = stagingPath;
m_origInstance = origInstance; m_origInstance = origInstance;
m_newName = newName;
} }
void LegacyUpgradeTask::executeTask() void LegacyUpgradeTask::executeTask()
@ -70,7 +67,7 @@ void LegacyUpgradeTask::copyFinished()
// NOTE: this scope ensures the instance is fully saved before we emitSucceeded // NOTE: this scope ensures the instance is fully saved before we emitSucceeded
{ {
MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath); MinecraftInstance inst(m_globalSettings, instanceSettings, m_stagingPath);
inst.setName(m_newName); inst.setName(m_instName);
inst.init(); inst.init();
QString preferredVersionNumber = decideVersion(legacyInst->currentVersionId(), legacyInst->intendedVersionId()); QString preferredVersionNumber = decideVersion(legacyInst->currentVersionId(), legacyInst->intendedVersionId());

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "tasks/Task.h" #include "InstanceTask.h"
#include "multimc_logic_export.h" #include "multimc_logic_export.h"
#include "net/NetJob.h" #include "net/NetJob.h"
#include <QUrl> #include <QUrl>
@ -13,11 +13,11 @@
class BaseInstanceProvider; class BaseInstanceProvider;
class MULTIMC_LOGIC_EXPORT LegacyUpgradeTask : public Task class MULTIMC_LOGIC_EXPORT LegacyUpgradeTask : public InstanceTask
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit LegacyUpgradeTask(SettingsObjectPtr settings, const QString & stagingPath, InstancePtr origInstance, const QString & newName); explicit LegacyUpgradeTask(InstancePtr origInstance);
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.
@ -26,13 +26,7 @@ protected:
void copyAborted(); void copyAborted();
private: /* data */ private: /* data */
SettingsObjectPtr m_globalSettings;
InstancePtr m_origInstance; InstancePtr m_origInstance;
QString m_stagingPath;
QString m_newName;
QFuture<bool> m_copyFuture; QFuture<bool> m_copyFuture;
QFutureWatcher<bool> m_copyFutureWatcher; QFutureWatcher<bool> m_copyFutureWatcher;
}; };

View File

@ -3,36 +3,25 @@
#include "FtbPackFetchTask.h" #include "FtbPackFetchTask.h"
#include "Env.h" #include "Env.h"
FtbPackDownloader::FtbPackDownloader() { FtbPackDownloader::FtbPackDownloader()
{
done = false; done = false;
fetching = false; fetching = false;
} }
FtbPackDownloader::~FtbPackDownloader(){ FtbPackDownloader::~FtbPackDownloader()
{
} }
bool FtbPackDownloader::isValidPackSelected(){ FtbModpackList FtbPackDownloader::getModpacks()
FtbModpack dummy; {
dummy.name = "__INVALID__";
FtbModpack other = fetchedPacks.value(selected.name, dummy);
if(other.name == "__INVALID__") {
return false;
}
return other.oldVersions.contains(selectedVersion) && !other.broken;
}
QString FtbPackDownloader::getSuggestedInstanceName() {
return selected.name;
}
FtbModpackList FtbPackDownloader::getModpacks() {
return static_cast<FtbModpackList>(fetchedPacks.values()); return static_cast<FtbModpackList>(fetchedPacks.values());
} }
void FtbPackDownloader::fetchModpacks(bool force = false){ void FtbPackDownloader::fetchModpacks(bool force = false)
if(fetching || (!force && done)) { {
if(fetching || (!force && done))
{
qDebug() << "Skipping modpack refetch because done or already fetching [done =>" << done << "| fetching =>" << fetching << "]"; qDebug() << "Skipping modpack refetch because done or already fetching [done =>" << done << "| fetching =>" << fetching << "]";
return; return;
} }
@ -46,8 +35,10 @@ void FtbPackDownloader::fetchModpacks(bool force = false){
} }
void FtbPackDownloader::fetchSuccess(FtbModpackList modpacks) { void FtbPackDownloader::fetchSuccess(FtbModpackList modpacks)
for(int i = 0; i < modpacks.size(); i++) { {
for(int i = 0; i < modpacks.size(); i++)
{
fetchedPacks.insert(modpacks.at(i).name, modpacks.at(i)); fetchedPacks.insert(modpacks.at(i).name, modpacks.at(i));
} }
@ -57,53 +48,10 @@ void FtbPackDownloader::fetchSuccess(FtbModpackList modpacks) {
fetchTask->deleteLater(); fetchTask->deleteLater();
} }
void FtbPackDownloader::fetchFailed(QString reason) { void FtbPackDownloader::fetchFailed(QString reason)
{
qWarning() << "Failed to fetch FtbData" << reason; qWarning() << "Failed to fetch FtbData" << reason;
fetching = false; fetching = false;
emit packFetchFailed(); emit packFetchFailed();
fetchTask->deleteLater(); fetchTask->deleteLater();
} }
void FtbPackDownloader::selectPack(FtbModpack modpack, QString version) {
selected = modpack;
selectedVersion = version;
}
FtbModpack FtbPackDownloader::getSelectedPack() {
return selected;
}
void FtbPackDownloader::downloadSelected(MetaEntryPtr cache) {
NetJob *job = new NetJob("Downlad FTB Pack");
cache->setStale(true);
QString url = QString("http://ftb.cursecdn.com/FTB2/modpacks/%1/%2/%3").arg(selected.dir, selectedVersion.replace(".", "_"), selected.file);
job->addNetAction(Net::Download::makeCached(url, cache));
downloadPath = cache->getFullPath();
netJobContainer.reset(job);
connect(job, &NetJob::succeeded, this, &FtbPackDownloader::_downloadSucceeded);
connect(job, &NetJob::failed, this, &FtbPackDownloader::_downloadFailed);
connect(job, &NetJob::progress, this, &FtbPackDownloader::_downloadProgress);
job->start();
}
void FtbPackDownloader::_downloadSucceeded() {
netJobContainer.reset();
emit downloadSucceded(downloadPath);
}
void FtbPackDownloader::_downloadProgress(qint64 current, qint64 total) {
emit downloadProgress(current, total);
}
void FtbPackDownloader::_downloadFailed(QString reason) {
netJobContainer.reset();
emit downloadFailed(reason);
}
NetJobPtr FtbPackDownloader::getNetJob()
{
return netJobContainer;
}

View File

@ -11,54 +11,29 @@
#pragma once #pragma once
class FtbPackDownloader; class MULTIMC_LOGIC_EXPORT FtbPackDownloader : public QObject
class MULTIMC_LOGIC_EXPORT FtbPackDownloader : public QObject { {
Q_OBJECT Q_OBJECT
public:
FtbPackDownloader();
virtual ~FtbPackDownloader();
void fetchModpacks(bool force);
FtbModpackList getModpacks();
signals:
void ready();
void packFetchFailed();
private slots:
void fetchSuccess(FtbModpackList modlist);
void fetchFailed(QString reason);
private: private:
QMap<QString, FtbModpack> fetchedPacks; QMap<QString, FtbModpack> fetchedPacks;
bool fetching = false; bool fetching = false;
bool done = false; bool done = false;
FtbModpack selected;
QString selectedVersion;
QString downloadPath;
FtbPackFetchTask *fetchTask = 0; FtbPackFetchTask *fetchTask = 0;
NetJobPtr netJobContainer;
void _downloadSucceeded();
void _downloadFailed(QString reason);
void _downloadProgress(qint64 current, qint64 total);
private slots:
void fetchSuccess(FtbModpackList modlist);
void fetchFailed(QString reason);
public:
FtbPackDownloader();
~FtbPackDownloader();
bool isValidPackSelected();
void selectPack(FtbModpack modpack, QString version);
FtbModpack getSelectedPack();
void fetchModpacks(bool force);
void downloadSelected(MetaEntryPtr cache);
QString getSuggestedInstanceName();
FtbModpackList getModpacks();
NetJobPtr getNetJob();
signals:
void ready();
void packFetchFailed();
void downloadSucceded(QString archivePath);
void downloadFailed(QString reason);
void downloadProgress(qint64 current, qint64 total);
}; };

View File

@ -58,6 +58,8 @@ void FtbPackFetchTask::fileDownloadFinished(){
modpack.mods = element.attribute("mods"); modpack.mods = element.attribute("mods");
modpack.image = element.attribute("image"); modpack.image = element.attribute("image");
modpack.oldVersions = element.attribute("oldVersions").split(";"); modpack.oldVersions = element.attribute("oldVersions").split(";");
modpack.broken = false;
modpack.bugged = false;
//remove empty if the xml is bugged //remove empty if the xml is bugged
for(QString curr : modpack.oldVersions) { for(QString curr : modpack.oldVersions) {

View File

@ -12,7 +12,7 @@ class MULTIMC_LOGIC_EXPORT FtbPackFetchTask : public QObject {
public: public:
FtbPackFetchTask(); FtbPackFetchTask();
~FtbPackFetchTask(); virtual ~FtbPackFetchTask();
void fetch(); void fetch();

View File

@ -9,52 +9,65 @@
#include "minecraft/ComponentList.h" #include "minecraft/ComponentList.h"
#include "minecraft/GradleSpecifier.h" #include "minecraft/GradleSpecifier.h"
FtbPackInstallTask::FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, FtbPackInstallTask::FtbPackInstallTask(FtbModpack pack, QString version)
const QString &stagingPath, const QString &instName, const QString &instIcon, const QString &instGroup) :
m_globalSettings(settings), m_stagingPath(stagingPath), m_instName(instName), m_instIcon(instIcon), m_instGroup(instGroup)
{ {
m_downloader = downloader; m_pack = pack;
m_version = version;
} }
void FtbPackInstallTask::executeTask() { void FtbPackInstallTask::executeTask()
{
downloadPack(); downloadPack();
} }
void FtbPackInstallTask::downloadPack(){ void FtbPackInstallTask::downloadPack()
FtbModpack toInstall = m_downloader->getSelectedPack(); {
setStatus(tr("Downloading zip for %1").arg(toInstall.name)); setStatus(tr("Downloading zip for %1").arg(m_pack.name));
auto entry = ENV.metacache()->resolveEntry("general", "FTBPacks/" + toInstall.name); auto entry = ENV.metacache()->resolveEntry("general", "FTBPacks/" + m_pack.name);
m_downloader->downloadSelected(entry); NetJob *job = new NetJob("Downlad FTB Pack");
entry->setStale(true);
QString url = QString("http://ftb.cursecdn.com/FTB2/modpacks/%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
job->addNetAction(Net::Download::makeCached(url, entry));
archivePath = entry->getFullPath();
netJobContainer.reset(job);
connect(job, &NetJob::succeeded, this, &FtbPackInstallTask::onDownloadSucceeded);
connect(job, &NetJob::failed, this, &FtbPackInstallTask::onDownloadFailed);
connect(job, &NetJob::progress, this, &FtbPackInstallTask::onDownloadProgress);
job->start();
connect(m_downloader, &FtbPackDownloader::downloadSucceded, this, &FtbPackInstallTask::onDownloadSucceeded);
connect(m_downloader, &FtbPackDownloader::downloadProgress, this, &FtbPackInstallTask::onDownloadProgress);
connect(m_downloader, &FtbPackDownloader::downloadFailed, this,&FtbPackInstallTask::onDownloadFailed);
progress(1, 4); progress(1, 4);
} }
void FtbPackInstallTask::onDownloadSucceeded(QString archivePath){ void FtbPackInstallTask::onDownloadSucceeded()
{
abortable = false; abortable = false;
unzip(archivePath); unzip();
} }
void FtbPackInstallTask::onDownloadFailed(QString reason) { void FtbPackInstallTask::onDownloadFailed(QString reason)
{
emitFailed(reason); emitFailed(reason);
} }
void FtbPackInstallTask::onDownloadProgress(qint64 current, qint64 total){ void FtbPackInstallTask::onDownloadProgress(qint64 current, qint64 total)
{
abortable = true; abortable = true;
progress(current, total * 4); progress(current, total * 4);
setStatus(tr("Downloading zip for %1 (%2\%)").arg(m_downloader->getSelectedPack().name).arg(current / 10)); setStatus(tr("Downloading zip for %1 (%2\%)").arg(m_pack.name).arg(current / 10));
} }
void FtbPackInstallTask::unzip(QString archivePath) { void FtbPackInstallTask::unzip()
{
progress(2, 4); progress(2, 4);
setStatus(tr("Extracting modpack")); setStatus(tr("Extracting modpack"));
QDir extractDir(m_stagingPath); QDir extractDir(m_stagingPath);
m_packZip.reset(new QuaZip(archivePath)); m_packZip.reset(new QuaZip(archivePath));
if(!m_packZip->open(QuaZip::mdUnzip)) { if(!m_packZip->open(QuaZip::mdUnzip))
{
emitFailed(tr("Failed to open modpack file %1!").arg(archivePath)); emitFailed(tr("Failed to open modpack file %1!").arg(archivePath));
return; return;
} }
@ -65,22 +78,26 @@ void FtbPackInstallTask::unzip(QString archivePath) {
m_extractFutureWatcher.setFuture(m_extractFuture); m_extractFutureWatcher.setFuture(m_extractFuture);
} }
void FtbPackInstallTask::onUnzipFinished() { void FtbPackInstallTask::onUnzipFinished()
{
install(); install();
} }
void FtbPackInstallTask::onUnzipCanceled() { void FtbPackInstallTask::onUnzipCanceled()
{
emitAborted(); emitAborted();
} }
void FtbPackInstallTask::install() { void FtbPackInstallTask::install()
{
progress(3, 4); progress(3, 4);
FtbModpack toInstall = m_downloader->getSelectedPack();
setStatus(tr("Installing modpack")); setStatus(tr("Installing modpack"));
QDir unzipMcDir(m_stagingPath + "/unzip/minecraft"); QDir unzipMcDir(m_stagingPath + "/unzip/minecraft");
if(unzipMcDir.exists()) { if(unzipMcDir.exists())
{
//ok, found minecraft dir, move contents to instance dir //ok, found minecraft dir, move contents to instance dir
if(!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft")) { if(!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft"))
{
emitFailed(tr("Failed to move unzipped minecraft!")); emitFailed(tr("Failed to move unzipped minecraft!"));
return; return;
} }
@ -94,14 +111,15 @@ void FtbPackInstallTask::install() {
MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath); MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
auto components = instance.getComponentList(); auto components = instance.getComponentList();
components->buildingFromScratch(); components->buildingFromScratch();
components->setComponentVersion("net.minecraft", toInstall.mcVersion, true); components->setComponentVersion("net.minecraft", m_pack.mcVersion, true);
bool fallback = true; bool fallback = true;
//handle different versions //handle different versions
QFile packJson(m_stagingPath + "/.minecraft/pack.json"); QFile packJson(m_stagingPath + "/.minecraft/pack.json");
QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods"); QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods");
if(packJson.exists()) { if(packJson.exists())
{
packJson.open(QIODevice::ReadOnly | QIODevice::Text); packJson.open(QIODevice::ReadOnly | QIODevice::Text);
QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll()); QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll());
packJson.close(); packJson.close();
@ -109,15 +127,17 @@ void FtbPackInstallTask::install() {
//we only care about the libs //we only care about the libs
QJsonArray libs = doc.object().value("libraries").toArray(); QJsonArray libs = doc.object().value("libraries").toArray();
foreach (const QJsonValue &value, libs) { foreach (const QJsonValue &value, libs)
{
QString nameValue = value.toObject().value("name").toString(); QString nameValue = value.toObject().value("name").toString();
if(!nameValue.startsWith("net.minecraftforge")) { if(!nameValue.startsWith("net.minecraftforge"))
{
continue; continue;
} }
GradleSpecifier forgeVersion(nameValue); GradleSpecifier forgeVersion(nameValue);
components->setComponentVersion("net.minecraftforge", forgeVersion.version().replace(toInstall.mcVersion, "").replace("-", "")); components->setComponentVersion("net.minecraftforge", forgeVersion.version().replace(m_pack.mcVersion, "").replace("-", ""));
packJson.remove(); packJson.remove();
fallback = false; fallback = false;
break; break;
@ -125,7 +145,8 @@ void FtbPackInstallTask::install() {
} }
if(jarmodDir.exists()) { if(jarmodDir.exists())
{
qDebug() << "Found jarmods, installing..."; qDebug() << "Found jarmods, installing...";
QStringList jarmods; QStringList jarmods;
@ -142,7 +163,8 @@ void FtbPackInstallTask::install() {
//just nuke unzip directory, it s not needed anymore //just nuke unzip directory, it s not needed anymore
FS::deletePath(m_stagingPath + "/unzip"); FS::deletePath(m_stagingPath + "/unzip");
if(fallback) { if(fallback)
{
//TODO: Some fallback mechanism... or just keep failing! //TODO: Some fallback mechanism... or just keep failing!
emitFailed(tr("No installation method found!")); emitFailed(tr("No installation method found!"));
return; return;
@ -154,7 +176,8 @@ void FtbPackInstallTask::install() {
instance.init(); instance.init();
instance.setName(m_instName); instance.setName(m_instName);
if(m_instIcon == "default") { if(m_instIcon == "default")
{
m_instIcon = "ftb_logo"; m_instIcon = "ftb_logo";
} }
instance.setIconKey(m_instIcon); instance.setIconKey(m_instIcon);
@ -166,8 +189,9 @@ void FtbPackInstallTask::install() {
bool FtbPackInstallTask::abort() bool FtbPackInstallTask::abort()
{ {
if(abortable) { if(abortable)
return m_downloader->getNetJob()->abort(); {
return netJobContainer->abort();
} }
return false; return false;
} }

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include "tasks/Task.h" #include "InstanceTask.h"
#include "modplatform/ftb/FtbPackDownloader.h" #include "modplatform/ftb/FtbPackDownloader.h"
#include "BaseInstanceProvider.h" #include "BaseInstanceProvider.h"
#include "net/NetJob.h" #include "net/NetJob.h"
@ -9,47 +9,41 @@
#include "meta/Version.h" #include "meta/Version.h"
#include "meta/VersionList.h" #include "meta/VersionList.h"
class MULTIMC_LOGIC_EXPORT FtbPackInstallTask : public Task { class MULTIMC_LOGIC_EXPORT FtbPackInstallTask : public InstanceTask {
Q_OBJECT Q_OBJECT
public: public:
explicit FtbPackInstallTask(FtbPackDownloader *downloader, SettingsObjectPtr settings, const QString &stagingPath, const QString &instName, explicit FtbPackInstallTask(FtbModpack pack, QString version);
const QString &instIcon, const QString &instGroup); virtual ~FtbPackInstallTask(){}
bool abort() override; bool abort() override;
protected: protected:
//! Entry point for tasks. //! Entry point for tasks.
virtual void executeTask() override; virtual void executeTask() override;
private: /* data */ private:
SettingsObjectPtr m_globalSettings;
QString m_stagingPath;
QString m_instName;
QString m_instIcon;
QString m_instGroup;
NetJobPtr m_netJobPtr;
FtbPackDownloader *m_downloader;
std::unique_ptr<QuaZip> m_packZip;
QFuture<QStringList> m_extractFuture;
QFutureWatcher<QStringList> m_extractFutureWatcher;
void downloadPack(); void downloadPack();
void unzip(QString archivePath); void unzip();
void install(); void install();
bool moveRecursively(QString source, QString dest);
bool abortable = false;
private slots: private slots:
void onDownloadSucceeded(QString archivePath); void onDownloadSucceeded();
void onDownloadFailed(QString reason); void onDownloadFailed(QString reason);
void onDownloadProgress(qint64 current, qint64 total); void onDownloadProgress(qint64 current, qint64 total);
void onUnzipFinished(); void onUnzipFinished();
void onUnzipCanceled(); void onUnzipCanceled();
private: /* data */
bool abortable = false;
std::unique_ptr<QuaZip> m_packZip;
QFuture<QStringList> m_extractFuture;
QFutureWatcher<QStringList> m_extractFutureWatcher;
NetJobPtr netJobContainer;
QString archivePath;
FtbModpack m_pack;
QString m_version;
}; };

View File

@ -17,8 +17,8 @@ struct FtbModpack {
QString dir; QString dir;
QString file; //<- Url in the xml, but doesn't make much sense QString file; //<- Url in the xml, but doesn't make much sense
bool bugged = false; bool bugged = true;
bool broken = false; bool broken = true;
}; };
//We need it for the proxy model //We need it for the proxy model
Q_DECLARE_METATYPE(FtbModpack) Q_DECLARE_METATYPE(FtbModpack)

View File

@ -80,29 +80,32 @@ SET(MULTIMC_SOURCES
JavaCommon.h JavaCommon.h
JavaCommon.cpp JavaCommon.cpp
# GUI - page dialog pages # GUI - paged dialog base
pages/BasePage.h pages/BasePage.h
pages/BasePageContainer.h pages/BasePageContainer.h
pages/VersionPage.cpp pages/BasePageProvider.h
pages/VersionPage.h
pages/TexturePackPage.h # GUI - instance pages
pages/ResourcePackPage.h pages/instance/VersionPage.cpp
pages/ModFolderPage.cpp pages/instance/VersionPage.h
pages/ModFolderPage.h pages/instance/TexturePackPage.h
pages/NotesPage.cpp pages/instance/ResourcePackPage.h
pages/NotesPage.h pages/instance/ModFolderPage.cpp
pages/LogPage.cpp pages/instance/ModFolderPage.h
pages/LogPage.h pages/instance/NotesPage.cpp
pages/InstanceSettingsPage.cpp pages/instance/NotesPage.h
pages/InstanceSettingsPage.h pages/instance/LogPage.cpp
pages/ScreenshotsPage.cpp pages/instance/LogPage.h
pages/ScreenshotsPage.h pages/instance/InstanceSettingsPage.cpp
pages/OtherLogsPage.cpp pages/instance/InstanceSettingsPage.h
pages/OtherLogsPage.h pages/instance/ScreenshotsPage.cpp
pages/LegacyUpgradePage.cpp pages/instance/ScreenshotsPage.h
pages/LegacyUpgradePage.h pages/instance/OtherLogsPage.cpp
pages/WorldListPage.cpp pages/instance/OtherLogsPage.h
pages/WorldListPage.h pages/instance/LegacyUpgradePage.cpp
pages/instance/LegacyUpgradePage.h
pages/instance/WorldListPage.cpp
pages/instance/WorldListPage.h
# GUI - global settings pages # GUI - global settings pages
pages/global/AccountListPage.cpp pages/global/AccountListPage.cpp
@ -124,6 +127,18 @@ SET(MULTIMC_SOURCES
pages/global/PackagesPage.cpp pages/global/PackagesPage.cpp
pages/global/PackagesPage.h pages/global/PackagesPage.h
# GUI - platform pages
pages/modplatform/VanillaPage.cpp
pages/modplatform/VanillaPage.h
pages/modplatform/FTBPage.cpp
pages/modplatform/FTBPage.h
pages/modplatform/TwitchPage.cpp
pages/modplatform/TwitchPage.h
pages/modplatform/TechnicPage.cpp
pages/modplatform/TechnicPage.h
pages/modplatform/ImportPage.cpp
pages/modplatform/ImportPage.h
# GUI - dialogs # GUI - dialogs
dialogs/AboutDialog.cpp dialogs/AboutDialog.cpp
dialogs/AboutDialog.h dialogs/AboutDialog.h
@ -159,8 +174,6 @@ SET(MULTIMC_SOURCES
dialogs/VersionSelectDialog.h dialogs/VersionSelectDialog.h
dialogs/SkinUploadDialog.cpp dialogs/SkinUploadDialog.cpp
dialogs/SkinUploadDialog.h dialogs/SkinUploadDialog.h
dialogs/ChooseFtbPackDialog.cpp
dialogs/ChooseFtbPackDialog.h
# GUI - widgets # GUI - widgets
@ -210,15 +223,15 @@ SET(MULTIMC_SOURCES
######## UIs ######## ######## UIs ########
SET(MULTIMC_UIS SET(MULTIMC_UIS
# Instance pages # Instance pages
pages/VersionPage.ui pages/instance/VersionPage.ui
pages/ModFolderPage.ui pages/instance/ModFolderPage.ui
pages/LogPage.ui pages/instance/LogPage.ui
pages/InstanceSettingsPage.ui pages/instance/InstanceSettingsPage.ui
pages/NotesPage.ui pages/instance/NotesPage.ui
pages/ScreenshotsPage.ui pages/instance/ScreenshotsPage.ui
pages/OtherLogsPage.ui pages/instance/OtherLogsPage.ui
pages/LegacyUpgradePage.ui pages/instance/LegacyUpgradePage.ui
pages/WorldListPage.ui pages/instance/WorldListPage.ui
# Global settings pages # Global settings pages
pages/global/AccountListPage.ui pages/global/AccountListPage.ui
@ -230,6 +243,13 @@ SET(MULTIMC_UIS
pages/global/PasteEEPage.ui pages/global/PasteEEPage.ui
pages/global/PackagesPage.ui pages/global/PackagesPage.ui
# Platform pages
pages/modplatform/VanillaPage.ui
pages/modplatform/FTBPage.ui
pages/modplatform/TwitchPage.ui
pages/modplatform/TechnicPage.ui
pages/modplatform/ImportPage.ui
# Dialogs # Dialogs
dialogs/CopyInstanceDialog.ui dialogs/CopyInstanceDialog.ui
dialogs/NewComponentDialog.ui dialogs/NewComponentDialog.ui
@ -244,7 +264,6 @@ SET(MULTIMC_UIS
dialogs/UpdateDialog.ui dialogs/UpdateDialog.ui
dialogs/NotificationDialog.ui dialogs/NotificationDialog.ui
dialogs/SkinUploadDialog.ui dialogs/SkinUploadDialog.ui
dialogs/ChooseFtbPackDialog.ui
# Widgets/other # Widgets/other
widgets/CustomCommands.ui widgets/CustomCommands.ui

View File

@ -108,7 +108,9 @@ QVariant FtbListModel::data(const QModelIndex &index, int role) const
void FtbListModel::fill(FtbModpackList modpacks) void FtbListModel::fill(FtbModpackList modpacks)
{ {
beginResetModel();
this->modpacks = modpacks; this->modpacks = modpacks;
endResetModel();
} }
FtbModpack FtbListModel::at(int row) FtbModpack FtbListModel::at(int row)

View File

@ -3,18 +3,18 @@
#include "minecraft/legacy/LegacyInstance.h" #include "minecraft/legacy/LegacyInstance.h"
#include <FileSystem.h> #include <FileSystem.h>
#include "pages/BasePage.h" #include "pages/BasePage.h"
#include "pages/LogPage.h"
#include "pages/VersionPage.h"
#include "pages/ModFolderPage.h"
#include "pages/ResourcePackPage.h"
#include "pages/TexturePackPage.h"
#include "pages/NotesPage.h"
#include "pages/ScreenshotsPage.h"
#include "pages/InstanceSettingsPage.h"
#include "pages/OtherLogsPage.h"
#include "pages/BasePageProvider.h" #include "pages/BasePageProvider.h"
#include "pages/LegacyUpgradePage.h" #include "pages/instance/LogPage.h"
#include "pages/WorldListPage.h" #include "pages/instance/VersionPage.h"
#include "pages/instance/ModFolderPage.h"
#include "pages/instance/ResourcePackPage.h"
#include "pages/instance/TexturePackPage.h"
#include "pages/instance/NotesPage.h"
#include "pages/instance/ScreenshotsPage.h"
#include "pages/instance/InstanceSettingsPage.h"
#include "pages/instance/OtherLogsPage.h"
#include "pages/instance/LegacyUpgradePage.h"
#include "pages/instance/WorldListPage.h"
class InstancePageProvider : public QObject, public BasePageProvider class InstancePageProvider : public QObject, public BasePageProvider

View File

@ -47,7 +47,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent)
// Add page container // Add page container
{ {
auto provider = std::make_shared<InstancePageProvider>(m_instance); auto provider = std::make_shared<InstancePageProvider>(m_instance);
m_container = new PageContainer(provider, "console", this); m_container = new PageContainer(provider.get(), "console", this);
m_container->setParentContainer(this); m_container->setParentContainer(this);
setCentralWidget(m_container); setCentralWidget(m_container);
} }

View File

@ -90,6 +90,7 @@
#include <InstanceImportTask.h> #include <InstanceImportTask.h>
#include "UpdateController.h" #include "UpdateController.h"
#include "KonamiCode.h" #include "KonamiCode.h"
#include <InstanceCopyTask.h>
// WHY: to hold the pre-translation strings together with the T pointer, so it can be retranslated without a lot of ugly code // WHY: to hold the pre-translation strings together with the T pointer, so it can be retranslated without a lot of ugly code
template <typename T> template <typename T>
@ -1267,26 +1268,9 @@ void MainWindow::runModalTask(Task *task)
loadDialog.execWithTask(task); loadDialog.execWithTask(task);
} }
void MainWindow::instanceFromZipPack(QString instName, QString instGroup, QString instIcon, QUrl url) void MainWindow::instanceFromInstanceTask(InstanceTask *rawTask)
{ {
std::unique_ptr<Task> task(MMC->folderProvider()->zipImportTask(url, instName, instGroup, instIcon)); std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(rawTask));
runModalTask(task.get());
// FIXME: handle instance selection after creation
// finalizeInstance(newInstance);
}
void MainWindow::instanceFromVersion(QString instName, QString instGroup, QString instIcon, BaseVersionPtr version)
{
std::unique_ptr<Task> task(MMC->folderProvider()->creationTask(version, instName, instGroup, instIcon));
runModalTask(task.get());
// FIXME: handle instance selection after creation
// finalizeInstance(newInstance);
}
void MainWindow::instanceFromFtbPack(FtbPackDownloader *downloader, QString instName, QString instGroup, QString instIcon) {
std::unique_ptr<Task> task(MMC->folderProvider()->ftbCreationTask(downloader, instName, instGroup, instIcon));
runModalTask(task.get()); runModalTask(task.get());
// FIXME: handle instance selection after creation // FIXME: handle instance selection after creation
@ -1302,8 +1286,11 @@ void MainWindow::on_actionCopyInstance_triggered()
if (!copyInstDlg.exec()) if (!copyInstDlg.exec())
return; return;
std::unique_ptr<Task> task(MMC->folderProvider()->copyTask(m_selectedInstance, copyInstDlg.instName(), copyInstDlg.instGroup(), auto copyTask = new InstanceCopyTask(m_selectedInstance, copyInstDlg.shouldCopySaves());
copyInstDlg.iconKey(), copyInstDlg.shouldCopySaves())); copyTask->setName(copyInstDlg.instName());
copyTask->setGroup(copyInstDlg.instGroup());
copyTask->setIcon(copyInstDlg.iconKey());
std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(copyTask));
runModalTask(task.get()); runModalTask(task.get());
// FIXME: handle instance selection after creation // FIXME: handle instance selection after creation
@ -1366,19 +1353,10 @@ void MainWindow::addInstance(QString url)
MMC->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup()); MMC->settings()->set("LastUsedGroupForNewInstance", newInstDlg.instGroup());
const QUrl modpackUrl = newInstDlg.modpackUrl(); InstanceTask * creationTask = newInstDlg.extractTask();
if(creationTask)
if(newInstDlg.isFtbModpackRequested())
{ {
instanceFromFtbPack(newInstDlg.getFtbPackDownloader(), newInstDlg.instName(), newInstDlg.instGroup(), newInstDlg.iconKey()); instanceFromInstanceTask(creationTask);
}
else if (modpackUrl.isValid())
{
instanceFromZipPack(newInstDlg.instName(), newInstDlg.instGroup(), newInstDlg.iconKey(), modpackUrl);
}
else
{
instanceFromVersion(newInstDlg.instName(), newInstDlg.instGroup(), newInstDlg.iconKey(), newInstDlg.selectedVersion());
} }
} }

View File

@ -39,6 +39,7 @@ class BaseProfilerFactory;
class GroupView; class GroupView;
class ServerStatus; class ServerStatus;
class KonamiCode; class KonamiCode;
class InstanceTask;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
@ -187,9 +188,7 @@ private:
void setSelectedInstanceById(const QString &id); void setSelectedInstanceById(const QString &id);
void runModalTask(Task *task); void runModalTask(Task *task);
void instanceFromVersion(QString instName, QString instGroup, QString instIcon, BaseVersionPtr version); void instanceFromInstanceTask(InstanceTask *task);
void instanceFromZipPack(QString instName, QString instGroup, QString instIcon, QUrl url);
void instanceFromFtbPack(FtbPackDownloader *downloader, QString instName, QString instGroup, QString instIcon);
void finalizeInstance(InstancePtr inst); void finalizeInstance(InstancePtr inst);
private: private:

View File

@ -497,6 +497,8 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("PagedGeometry", ""); m_settings->registerSetting("PagedGeometry", "");
m_settings->registerSetting("NewInstanceGeometry", "");
m_settings->registerSetting("UpdateDialogGeometry", ""); m_settings->registerSetting("UpdateDialogGeometry", "");
// paste.ee API key // paste.ee API key

View File

@ -19,7 +19,7 @@ void ShowPageDialog(T raw_provider, QWidget * parent, QString open_page = QStrin
return; return;
{ {
SettingsObject::Lock lock(MMC->settings()); SettingsObject::Lock lock(MMC->settings());
PageDialog dlg(provider, open_page, parent); PageDialog dlg(provider.get(), open_page, parent);
dlg.exec(); dlg.exec();
} }
} }

View File

@ -20,34 +20,21 @@ public:
const auto &filters = m_parent->filters(); const auto &filters = m_parent->filters();
for (auto it = filters.begin(); it != filters.end(); ++it) for (auto it = filters.begin(); it != filters.end(); ++it)
{ {
auto role = it.key();
auto idx = sourceModel()->index(source_row, 0, source_parent); auto idx = sourceModel()->index(source_row, 0, source_parent);
auto data = sourceModel()->data(idx, role); auto data = sourceModel()->data(idx, it.key());
switch(role)
{
case BaseVersionList::ParentVersionRole:
case BaseVersionList::VersionIdRole:
// TODO: work with metadata here. Previous implementation based on the Version class is not sufficient
default:
{
auto match = data.toString(); auto match = data.toString();
if(it.value().exact) if(!it.value()->accepts(match))
{
if (match != it.value().string)
{ {
return false; return false;
} }
} }
else if (match.contains(it.value().string))
{
return false;
}
}
}
}
return true; return true;
} }
void filterChanged()
{
invalidateFilter();
}
private: private:
VersionProxyModel *m_parent; VersionProxyModel *m_parent;
}; };
@ -56,12 +43,12 @@ VersionProxyModel::VersionProxyModel(QObject *parent) : QAbstractProxyModel(pare
{ {
filterModel = new VersionFilterModel(this); filterModel = new VersionFilterModel(this);
connect(filterModel, &QAbstractItemModel::dataChanged, this, &VersionProxyModel::sourceDataChanged); connect(filterModel, &QAbstractItemModel::dataChanged, this, &VersionProxyModel::sourceDataChanged);
connect(filterModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &VersionProxyModel::sourceRowsAboutToBeInserted);
connect(filterModel, &QAbstractItemModel::rowsInserted, this, &VersionProxyModel::sourceRowsInserted);
connect(filterModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &VersionProxyModel::sourceRowsAboutToBeRemoved);
connect(filterModel, &QAbstractItemModel::rowsRemoved, this, &VersionProxyModel::sourceRowsRemoved);
// FIXME: implement when needed // FIXME: implement when needed
/* /*
connect(replacing, &QAbstractItemModel::rowsAboutToBeInserted, this, &VersionProxyModel::sourceRowsAboutToBeInserted);
connect(replacing, &QAbstractItemModel::rowsInserted, this, &VersionProxyModel::sourceRowsInserted);
connect(replacing, &QAbstractItemModel::rowsAboutToBeRemoved, this, &VersionProxyModel::sourceRowsAboutToBeRemoved);
connect(replacing, &QAbstractItemModel::rowsRemoved, this, &VersionProxyModel::sourceRowsRemoved);
connect(replacing, &QAbstractItemModel::rowsAboutToBeMoved, this, &VersionProxyModel::sourceRowsAboutToBeMoved); connect(replacing, &QAbstractItemModel::rowsAboutToBeMoved, this, &VersionProxyModel::sourceRowsAboutToBeMoved);
connect(replacing, &QAbstractItemModel::rowsMoved, this, &VersionProxyModel::sourceRowsMoved); connect(replacing, &QAbstractItemModel::rowsMoved, this, &VersionProxyModel::sourceRowsMoved);
connect(replacing, &QAbstractItemModel::layoutAboutToBeChanged, this, &VersionProxyModel::sourceLayoutAboutToBeChanged); connect(replacing, &QAbstractItemModel::layoutAboutToBeChanged, this, &VersionProxyModel::sourceLayoutAboutToBeChanged);
@ -390,16 +377,13 @@ QModelIndex VersionProxyModel::getVersion(const QString& version) const
void VersionProxyModel::clearFilters() void VersionProxyModel::clearFilters()
{ {
m_filters.clear(); m_filters.clear();
filterModel->invalidate(); filterModel->filterChanged();
} }
void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, const QString &filter, const bool exact) void VersionProxyModel::setFilter(const BaseVersionList::ModelRoles column, Filter * f)
{ {
Filter f; m_filters[column].reset(f);
f.string = filter; filterModel->filterChanged();
f.exact = exact;
m_filters[column] = f;
filterModel->invalidate();
} }
const VersionProxyModel::FilterMap &VersionProxyModel::filters() const const VersionProxyModel::FilterMap &VersionProxyModel::filters() const
@ -417,4 +401,25 @@ void VersionProxyModel::sourceReset()
endResetModel(); endResetModel();
} }
void VersionProxyModel::sourceRowsAboutToBeInserted(const QModelIndex& parent, int first, int last)
{
beginInsertRows(parent, first, last);
}
void VersionProxyModel::sourceRowsInserted(const QModelIndex& parent, int first, int last)
{
endInsertRows();
}
void VersionProxyModel::sourceRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last)
{
beginRemoveRows(parent, first, last);
}
void VersionProxyModel::sourceRowsRemoved(const QModelIndex& parent, int first, int last)
{
endRemoveRows();
}
#include "VersionProxyModel.moc" #include "VersionProxyModel.moc"

View File

@ -2,17 +2,15 @@
#include <QAbstractProxyModel> #include <QAbstractProxyModel>
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include <Filter.h>
class VersionFilterModel; class VersionFilterModel;
class VersionProxyModel: public QAbstractProxyModel class VersionProxyModel: public QAbstractProxyModel
{ {
Q_OBJECT Q_OBJECT
public: public:
struct Filter
{
QString string;
bool exact = false;
};
enum Column enum Column
{ {
Name, Name,
@ -22,7 +20,7 @@ public:
Architecture, Architecture,
Path Path
}; };
typedef QHash<BaseVersionList::ModelRoles, Filter> FilterMap; typedef QHash<BaseVersionList::ModelRoles, std::shared_ptr<Filter>> FilterMap;
public: public:
VersionProxyModel ( QObject* parent = 0 ); VersionProxyModel ( QObject* parent = 0 );
@ -39,16 +37,23 @@ public:
virtual void setSourceModel(QAbstractItemModel *sourceModel) override; virtual void setSourceModel(QAbstractItemModel *sourceModel) override;
const FilterMap &filters() const; const FilterMap &filters() const;
void setFilter(const BaseVersionList::ModelRoles column, const QString &filter, const bool exact); void setFilter(const BaseVersionList::ModelRoles column, Filter * filter);
void clearFilters(); void clearFilters();
QModelIndex getRecommended() const; QModelIndex getRecommended() const;
QModelIndex getVersion(const QString & version) const; QModelIndex getVersion(const QString & version) const;
private slots: private slots:
void sourceDataChanged(const QModelIndex &source_top_left,const QModelIndex &source_bottom_right); void sourceDataChanged(const QModelIndex &source_top_left,const QModelIndex &source_bottom_right);
void sourceAboutToBeReset(); void sourceAboutToBeReset();
void sourceReset(); void sourceReset();
void sourceRowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
void sourceRowsInserted(const QModelIndex &parent, int first, int last);
void sourceRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
void sourceRowsRemoved(const QModelIndex &parent, int first, int last);
private: private:
QList<Column> m_columns; QList<Column> m_columns;
FilterMap m_filters; FilterMap m_filters;

View File

@ -1,88 +0,0 @@
#include "ChooseFtbPackDialog.h"
#include <QPushButton>
ChooseFtbPackDialog::ChooseFtbPackDialog(FtbModpackList modpacks) : ui(new Ui::ChooseFtbPackDialog)
{
ui->setupUi(this);
filterModel = new FtbFilterModel(this);
listModel = new FtbListModel(this);
filterModel->setSourceModel(listModel);
listModel->fill(modpacks);
ui->packList->setModel(filterModel);
ui->packList->setSortingEnabled(true);
ui->packList->header()->hide();
ui->packList->setIndentation(0);
filterModel->setSorting(FtbFilterModel::Sorting::ByName);
for(int i = 0; i < filterModel->getAvailableSortings().size(); i++){
ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i));
}
ui->sortByBox->setCurrentText(filterModel->getAvailableSortings().key(filterModel->getCurrentSorting()));
connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &ChooseFtbPackDialog::onSortingSelectionChanged);
connect(ui->packVersionSelection, &QComboBox::currentTextChanged, this, &ChooseFtbPackDialog::onVersionSelectionItemChanged);
connect(ui->packList->selectionModel(), &QItemSelectionModel::currentChanged, this, &ChooseFtbPackDialog::onPackSelectionChanged);
ui->modpackInfo->setOpenExternalLinks(true);
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
ChooseFtbPackDialog::~ChooseFtbPackDialog()
{
delete ui;
}
void ChooseFtbPackDialog::onPackSelectionChanged(QModelIndex now, QModelIndex prev)
{
ui->packVersionSelection->clear();
FtbModpack selectedPack = filterModel->data(now, Qt::UserRole).value<FtbModpack>();
ui->modpackInfo->setHtml("Pack by <b>" + selectedPack.author + "</b>" + "<br>Minecraft " + selectedPack.mcVersion + "<br>"
"<br>" + selectedPack.description + "<ul><li>" + selectedPack.mods.replace(";", "</li><li>") + "</li></ul>");
bool currentAdded = false;
for(int i = 0; i < selectedPack.oldVersions.size(); i++) {
if(selectedPack.currentVersion == selectedPack.oldVersions.at(i)) {
currentAdded = true;
}
ui->packVersionSelection->addItem(selectedPack.oldVersions.at(i));
}
if(!currentAdded) {
ui->packVersionSelection->addItem(selectedPack.currentVersion);
}
selected = selectedPack;
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!selected.broken);
}
void ChooseFtbPackDialog::onVersionSelectionItemChanged(QString data)
{
if(data.isNull() || data.isEmpty()) {
selectedVersion = "";
return;
}
selectedVersion = data;
}
FtbModpack ChooseFtbPackDialog::getSelectedModpack()
{
return selected;
}
QString ChooseFtbPackDialog::getSelectedVersion()
{
return selectedVersion;
}
void ChooseFtbPackDialog::onSortingSelectionChanged(QString data)
{
filterModel->setSorting(filterModel->getAvailableSortings().value(data));
}

View File

@ -1,34 +0,0 @@
#pragma once
#include <QDialog>
#include <net/NetJob.h>
#include <modplatform/ftb/PackHelpers.h>
#include "ui_ChooseFtbPackDialog.h"
#include "FtbListModel.h"
namespace Ui {
class ChooseFtbPackDialog;
}
class ChooseFtbPackDialog : public QDialog {
Q_OBJECT
private:
Ui::ChooseFtbPackDialog *ui;
FtbModpack selected;
QString selectedVersion;
FtbListModel* listModel;
FtbFilterModel* filterModel;
private slots:
void onSortingSelectionChanged(QString data);
void onVersionSelectionItemChanged(QString data);
void onPackSelectionChanged(QModelIndex first, QModelIndex second);
public:
ChooseFtbPackDialog(FtbModpackList packs);
~ChooseFtbPackDialog();
FtbModpack getSelectedModpack();
QString getSelectedVersion();
};

View File

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChooseFtbPackDialog</class>
<widget class="QDialog" name="ChooseFtbPackDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>700</width>
<height>437</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="QLabel" name="selectedVersionLabel">
<property name="text">
<string>Version selected:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QTreeView" name="packList">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="sortByBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="packVersionSelection">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QTextBrowser" name="modpackInfo"/>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ChooseFtbPackDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>211</x>
<y>173</y>
</hint>
<hint type="destinationlabel">
<x>889</x>
<y>501</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ChooseFtbPackDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>225</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>524</x>
<y>458</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -25,80 +25,30 @@
#include "VersionSelectDialog.h" #include "VersionSelectDialog.h"
#include "ProgressDialog.h" #include "ProgressDialog.h"
#include "IconPickerDialog.h" #include "IconPickerDialog.h"
#include "ChooseFtbPackDialog.h"
#include <QLayout> #include <QLayout>
#include <QPushButton> #include <QPushButton>
#include <QFileDialog> #include <QFileDialog>
#include <QValidator> #include <QValidator>
#include <QDialogButtonBox>
#include <meta/Index.h> #include "widgets/PageContainer.h"
#include <meta/VersionList.h> #include <pages/modplatform/VanillaPage.h>
#include <pages/modplatform/FTBPage.h>
class UrlValidator : public QValidator #include <pages/modplatform/TwitchPage.h>
{ #include <pages/modplatform/ImportPage.h>
public: #include <pages/modplatform/TechnicPage.h>
using QValidator::QValidator;
State validate(QString &in, int &pos) const
{
const QUrl url(in);
if (url.isValid() && !url.isRelative() && !url.isEmpty())
{
return Acceptable;
}
else if (QFile::exists(in))
{
return Acceptable;
}
else
{
return Intermediate;
}
}
};
NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString & url, QWidget *parent) NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString & url, QWidget *parent)
: QDialog(parent), ui(new Ui::NewInstanceDialog) : QDialog(parent), ui(new Ui::NewInstanceDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
resize(minimumSizeHint());
layout()->setSizeConstraint(QLayout::SetFixedSize);
auto vlist = ENV.metadataIndex()->get("net.minecraft"); setWindowIcon(MMC->getThemedIcon("new"));
if(vlist->isLoaded())
{
setSelectedVersion(vlist->getRecommended());
}
else
{
vlist->load(Net::Mode::Online);
auto task = vlist->getLoadTask();
if(vlist->isLoaded())
{
setSelectedVersion(vlist->getRecommended());
}
if(task)
{
connect(task.get(), &Task::succeeded, this, &NewInstanceDialog::versionListUpdated);
}
}
InstIconKey = "default"; InstIconKey = "default";
ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey)); ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
ui->modpackEdit->setValidator(new UrlValidator(ui->modpackEdit));
ui->instNameTextBox->setAlignment(Qt::AlignHCenter);
connect(ui->modpackEdit, &QLineEdit::textChanged, this, &NewInstanceDialog::updateDialogState);
connect(ui->modpackBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState);
connect(ui->versionBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState);
connect(ui->versionTextBox, &QLineEdit::textChanged, this, &NewInstanceDialog::updateDialogState);
connect(ui->ftbBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState);
auto groups = MMC->instances()->getGroups().toSet(); auto groups = MMC->instances()->getGroups().toSet();
auto groupList = QStringList(groups.toList()); auto groupList = QStringList(groups.toList());
groupList.sort(Qt::CaseInsensitive); groupList.sort(Qt::CaseInsensitive);
@ -113,32 +63,47 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
} }
ui->groupBox->setCurrentIndex(index); ui->groupBox->setCurrentIndex(index);
ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); ui->groupBox->lineEdit()->setPlaceholderText(tr("No group"));
ui->buttonBox->setFocus();
originalPlaceholderText = ui->instNameTextBox->placeholderText(); m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok);
m_buttons->button(QDialogButtonBox::Ok)->setDefault(true);
connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &QDialog::accept);
connect(m_buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, m_container, &PageContainer::help);
m_container = new PageContainer(this);
m_container->setSizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Expanding);
ui->verticalLayout->insertWidget(2, m_container);
m_container->addButtons(m_buttons);
m_buttons->setFocus();
if(!url.isEmpty()) if(!url.isEmpty())
{ {
ui->modpackBox->setChecked(true); m_container->selectPage("import");
ui->modpackEdit->setText(url); importPage->setUrl(url);
} }
ftbPackDownloader = new FtbPackDownloader();
connect(ftbPackDownloader, &FtbPackDownloader::ready, this, &NewInstanceDialog::ftbPackDataDownloadSuccessfully);
connect(ftbPackDownloader, &FtbPackDownloader::packFetchFailed, this, &NewInstanceDialog::ftbPackDataDownloadFailed);
ftbPackDownloader->fetchModpacks(false);
updateDialogState(); updateDialogState();
restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("NewInstanceGeometry").toByteArray()));
} }
void NewInstanceDialog::versionListUpdated() QList<BasePage *> NewInstanceDialog::getPages()
{ {
if(!m_versionSetByUser) importPage = new ImportPage(this);
return
{ {
auto vlist = ENV.metadataIndex()->get("net.minecraft"); new VanillaPage(this),
setSelectedVersion(vlist->getRecommended()); new FTBPage(this),
importPage,
new TwitchPage(this),
new TechnicPage(this)
};
} }
QString NewInstanceDialog::dialogTitle()
{
return tr("New Instance");
} }
NewInstanceDialog::~NewInstanceDialog() NewInstanceDialog::~NewInstanceDialog()
@ -146,58 +111,29 @@ NewInstanceDialog::~NewInstanceDialog()
delete ui; delete ui;
} }
void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task)
{
creationTask.reset(task);
ui->instNameTextBox->setPlaceholderText(name);
auto allowOK = task && !instName().isEmpty();
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
}
InstanceTask * NewInstanceDialog::extractTask()
{
InstanceTask * extracted = creationTask.get();
creationTask.release();
extracted->setName(instName());
extracted->setGroup(instGroup());
extracted->setIcon(iconKey());
return extracted;
}
void NewInstanceDialog::updateDialogState() void NewInstanceDialog::updateDialogState()
{ {
QString suggestedName; auto allowOK = creationTask && !instName().isEmpty();
if(ui->versionBox->isChecked()) m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
{
suggestedName = ui->versionTextBox->text();
}
else if (ui->modpackBox->isChecked())
{
auto url = QUrl::fromUserInput(ui->modpackEdit->text());
QFileInfo fi(url.fileName());
suggestedName = fi.completeBaseName();
}
else if (ui->ftbBox->isChecked())
{
if(ftbPackDownloader->isValidPackSelected()) {
suggestedName = ftbPackDownloader->getSuggestedInstanceName();
ui->labelFtbPack->setText(selectedPack.name);
}
}
ftbModpackRequested = ui->ftbBox->isChecked();
if(suggestedName.isEmpty())
{
ui->instNameTextBox->setPlaceholderText(originalPlaceholderText);
}
else
{
ui->instNameTextBox->setPlaceholderText(suggestedName);
}
bool allowOK = !instName().isEmpty() && (
(ui->versionBox->isChecked() && m_selectedVersion) ||
(ui->modpackBox->isChecked() && ui->modpackEdit->hasAcceptableInput()) ||
(ui->ftbBox->isChecked() && ftbPackDownloader && ftbPackDownloader->isValidPackSelected() )
);
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
}
void NewInstanceDialog::setSelectedVersion(BaseVersionPtr version)
{
m_selectedVersion = version;
if (m_selectedVersion)
{
ui->versionTextBox->setText(version->descriptor());
}
else
{
ui->versionTextBox->setText("");
}
} }
QString NewInstanceDialog::instName() const QString NewInstanceDialog::instName() const
@ -208,7 +144,7 @@ QString NewInstanceDialog::instName() const
return result.trimmed(); return result.trimmed();
} }
result = ui->instNameTextBox->placeholderText(); result = ui->instNameTextBox->placeholderText();
if(result.size() && result != originalPlaceholderText) if(result.size())
{ {
return result.trimmed(); return result.trimmed();
} }
@ -223,45 +159,6 @@ QString NewInstanceDialog::iconKey() const
{ {
return InstIconKey; return InstIconKey;
} }
QUrl NewInstanceDialog::modpackUrl() const
{
if (ui->modpackBox->isChecked())
{
const QUrl url(ui->modpackEdit->text());
if (url.isValid() && !url.isRelative() && !url.host().isEmpty())
{
return url;
}
else
{
return QUrl::fromLocalFile(ui->modpackEdit->text());
}
}
else
{
return QUrl();
}
}
BaseVersionPtr NewInstanceDialog::selectedVersion() const
{
return m_selectedVersion;
}
void NewInstanceDialog::on_btnChangeVersion_clicked()
{
VersionSelectDialog vselect(ENV.metadataIndex()->get("net.minecraft").get(), tr("Change Minecraft version"), this);
vselect.exec();
if (vselect.result() == QDialog::Accepted)
{
BaseVersionPtr version = vselect.selectedVersion();
if (version)
{
m_versionSetByUser = true;
setSelectedVersion(version);
}
}
}
void NewInstanceDialog::on_iconButton_clicked() void NewInstanceDialog::on_iconButton_clicked()
{ {
@ -280,46 +177,14 @@ void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1)
updateDialogState(); updateDialogState();
} }
void NewInstanceDialog::on_modpackBtn_clicked() void NewInstanceDialog::closeEvent(QCloseEvent* event)
{ {
const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), tr("Zip (*.zip)")); qDebug() << "New instance dialog close requested";
if (url.isValid()) if (m_container->prepareToClose())
{ {
if (url.isLocalFile()) qDebug() << "New instance dialog close approved";
{ MMC->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());
ui->modpackEdit->setText(url.toLocalFile()); qDebug() << "New instance dialog geometry saved";
} QDialog::closeEvent(event);
else
{
ui->modpackEdit->setText(url.toString());
} }
} }
}
bool NewInstanceDialog::isFtbModpackRequested() {
return ftbModpackRequested;
}
FtbPackDownloader *NewInstanceDialog::getFtbPackDownloader() {
return ftbPackDownloader;
}
void NewInstanceDialog::on_btnChooseFtbPack_clicked() {
ChooseFtbPackDialog dl(ftbPackDownloader->getModpacks());
dl.exec();
if(dl.result() == QDialog::Accepted) {
selectedPack = dl.getSelectedModpack();
ftbPackDownloader->selectPack(selectedPack, dl.getSelectedVersion());
}
updateDialogState();
}
void NewInstanceDialog::ftbPackDataDownloadSuccessfully() {
ui->packDataDownloadStatus->setText(tr("(Data download complete)"));
ui->ftbBox->setEnabled(true);
}
void NewInstanceDialog::ftbPackDataDownloadFailed() {
ui->packDataDownloadStatus->setText(tr("(Data download failed)"));
}

View File

@ -18,15 +18,19 @@
#include <QDialog> #include <QDialog>
#include "BaseVersion.h" #include "BaseVersion.h"
#include "modplatform/ftb/FtbPackDownloader.h" #include "pages/BasePageProvider.h"
#include "modplatform/ftb/PackHelpers.h" #include "InstanceTask.h"
namespace Ui namespace Ui
{ {
class NewInstanceDialog; class NewInstanceDialog;
} }
class NewInstanceDialog : public QDialog class PageContainer;
class QDialogButtonBox;
class ImportPage;
class NewInstanceDialog : public QDialog, public BasePageProvider
{ {
Q_OBJECT Q_OBJECT
@ -36,39 +40,28 @@ public:
void updateDialogState(); void updateDialogState();
void setSelectedVersion(BaseVersionPtr version); void setSuggestedPack(const QString & name = QString(), InstanceTask * task = nullptr);
InstanceTask * extractTask();
QString dialogTitle() override;
QList<BasePage *> getPages() override;
QString instName() const; QString instName() const;
QString instGroup() const; QString instGroup() const;
QString iconKey() const; QString iconKey() const;
QUrl modpackUrl() const;
BaseVersionPtr selectedVersion() const;
bool isFtbModpackRequested();
FtbPackDownloader* getFtbPackDownloader();
private private
slots: slots:
void on_btnChangeVersion_clicked();
void on_iconButton_clicked(); void on_iconButton_clicked();
void on_modpackBtn_clicked();
void on_btnChooseFtbPack_clicked();
void on_instNameTextBox_textChanged(const QString &arg1); void on_instNameTextBox_textChanged(const QString &arg1);
void versionListUpdated(); virtual void closeEvent(QCloseEvent *event);
void ftbPackDataDownloadSuccessfully();
void ftbPackDataDownloadFailed();
private: private:
Ui::NewInstanceDialog *ui; Ui::NewInstanceDialog *ui = nullptr;
PageContainer * m_container = nullptr;
QDialogButtonBox * m_buttons = nullptr;
bool m_versionSetByUser = false;
bool ftbModpackRequested = false;
BaseVersionPtr m_selectedVersion;
QString InstIconKey; QString InstIconKey;
QString originalPlaceholderText; ImportPage *importPage = nullptr;
std::unique_ptr<InstanceTask> creationTask;
FtbPackDownloader* ftbPackDownloader;
FtbModpack selectedPack;
}; };

View File

@ -9,8 +9,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>281</width> <width>730</width>
<height>407</height> <height>127</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -25,21 +25,38 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QHBoxLayout" name="iconBtnLayout"> <layout class="QGridLayout" name="gridLayout_2">
<item> <item row="1" column="2">
<spacer name="iconBtnLeftSpacer"> <widget class="QComboBox" name="groupBox">
<property name="orientation"> <property name="editable">
<enum>Qt::Horizontal</enum> <bool>true</bool>
</property> </property>
<property name="sizeHint" stdset="0"> </widget>
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item> </item>
<item> <item row="1" column="1">
<widget class="QLabel" name="groupLabel">
<property name="text">
<string>&amp;Group:</string>
</property>
<property name="buddy">
<cstring>groupBox</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="instNameTextBox"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>&amp;Name:</string>
</property>
<property name="buddy">
<cstring>instNameTextBox</cstring>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2">
<widget class="QToolButton" name="iconButton"> <widget class="QToolButton" name="iconButton">
<property name="iconSize"> <property name="iconSize">
<size> <size>
@ -49,28 +66,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<spacer name="iconBtnRightSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</item> </item>
<item>
<widget class="QLineEdit" name="instNameTextBox">
<property name="placeholderText">
<string>Name</string>
</property>
</widget>
</item>
<item> <item>
<widget class="Line" name="line"> <widget class="Line" name="line">
<property name="orientation"> <property name="orientation">
@ -78,304 +75,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labelVersion_3">
<property name="text">
<string>&amp;Group:</string>
</property>
<property name="buddy">
<cstring>groupBox</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0">
<widget class="QRadioButton" name="ftbBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Install FTB Pack</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QToolButton" name="btnChangeVersion">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QToolButton" name="btnChooseFtbPack">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QToolButton" name="modpackBtn">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<widget class="QLabel" name="labelFtbPack">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string> No Pack choosen</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QRadioButton" name="modpackBox">
<property name="text">
<string>Impor&amp;t Modpack (local file or link):</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QRadioButton" name="versionBox">
<property name="text">
<string>Vani&amp;lla Minecraft (select version):</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLineEdit" name="versionTextBox">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="FocusLineEdit" name="modpackEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string notr="true">http://</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="QLabel" name="packDataDownloadStatus">
<property name="text">
<string>(Loading Pack data...)</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<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>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>FocusLineEdit</class>
<extends>QLineEdit</extends>
<header>widgets/FocusLineEdit.h</header>
</customwidget>
</customwidgets>
<tabstops> <tabstops>
<tabstop>iconButton</tabstop>
<tabstop>instNameTextBox</tabstop> <tabstop>instNameTextBox</tabstop>
<tabstop>groupBox</tabstop> <tabstop>groupBox</tabstop>
<tabstop>versionBox</tabstop>
<tabstop>versionTextBox</tabstop>
<tabstop>btnChangeVersion</tabstop>
<tabstop>modpackBox</tabstop>
<tabstop>modpackEdit</tabstop>
<tabstop>modpackBtn</tabstop>
<tabstop>iconButton</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections/>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>NewInstanceDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>266</x>
<y>378</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>NewInstanceDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>271</x>
<y>378</y>
</hint>
<hint type="destinationlabel">
<x>280</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>modpackBox</sender>
<signal>toggled(bool)</signal>
<receiver>modpackEdit</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>91</x>
<y>251</y>
</hint>
<hint type="destinationlabel">
<x>240</x>
<y>278</y>
</hint>
</hints>
</connection>
<connection>
<sender>modpackBox</sender>
<signal>toggled(bool)</signal>
<receiver>modpackBtn</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>139</x>
<y>251</y>
</hint>
<hint type="destinationlabel">
<x>270</x>
<y>278</y>
</hint>
</hints>
</connection>
<connection>
<sender>versionBox</sender>
<signal>toggled(bool)</signal>
<receiver>versionTextBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>93</x>
<y>195</y>
</hint>
<hint type="destinationlabel">
<x>223</x>
<y>224</y>
</hint>
</hints>
</connection>
<connection>
<sender>versionBox</sender>
<signal>toggled(bool)</signal>
<receiver>btnChangeVersion</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>104</x>
<y>198</y>
</hint>
<hint type="destinationlabel">
<x>270</x>
<y>224</y>
</hint>
</hints>
</connection>
<connection>
<sender>ftbBox</sender>
<signal>toggled(bool)</signal>
<receiver>btnChooseFtbPack</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>67</x>
<y>301</y>
</hint>
<hint type="destinationlabel">
<x>254</x>
<y>327</y>
</hint>
</hints>
</connection>
<connection>
<sender>ftbBox</sender>
<signal>toggled(bool)</signal>
<receiver>labelFtbPack</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>81</x>
<y>310</y>
</hint>
<hint type="destinationlabel">
<x>73</x>
<y>334</y>
</hint>
</hints>
</connection>
</connections>
</ui> </ui>

View File

@ -40,7 +40,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title,
m_verticalLayout = new QVBoxLayout(this); m_verticalLayout = new QVBoxLayout(this);
m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
m_versionWidget = new VersionSelectWidget(vlist, parent); m_versionWidget = new VersionSelectWidget(parent);
m_verticalLayout->addWidget(m_versionWidget); m_verticalLayout->addWidget(m_versionWidget);
m_horizontalLayout = new QHBoxLayout(); m_horizontalLayout = new QHBoxLayout();
@ -107,7 +107,7 @@ void VersionSelectDialog::setResizeOn(int column)
int VersionSelectDialog::exec() int VersionSelectDialog::exec()
{ {
QDialog::open(); QDialog::open();
m_versionWidget->initialize(); m_versionWidget->initialize(m_vlist);
return QDialog::exec(); return QDialog::exec();
} }

View File

@ -25,7 +25,7 @@
#include "widgets/IconLabel.h" #include "widgets/IconLabel.h"
#include "widgets/PageContainer.h" #include "widgets/PageContainer.h"
PageDialog::PageDialog(BasePageProviderPtr pageProvider, QString defaultId, QWidget *parent) PageDialog::PageDialog(BasePageProvider *pageProvider, QString defaultId, QWidget *parent)
: QDialog(parent) : QDialog(parent)
{ {
setWindowTitle(pageProvider->dialogTitle()); setWindowTitle(pageProvider->dialogTitle());
@ -37,17 +37,14 @@ PageDialog::PageDialog(BasePageProviderPtr pageProvider, QString defaultId, QWid
mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->setContentsMargins(0, 0, 0, 0);
setLayout(mainLayout); setLayout(mainLayout);
QDialogButtonBox *buttons = QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close);
new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close);
buttons->button(QDialogButtonBox::Close)->setDefault(true); buttons->button(QDialogButtonBox::Close)->setDefault(true);
m_container->addButtons(buttons); m_container->addButtons(buttons);
connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close())); connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close()));
connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, SLOT(help()));
SLOT(help()));
restoreGeometry( restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("PagedGeometry").toByteArray()));
QByteArray::fromBase64(MMC->settings()->get("PagedGeometry").toByteArray()));
} }
void PageDialog::closeEvent(QCloseEvent *event) void PageDialog::closeEvent(QCloseEvent *event)

View File

@ -23,8 +23,7 @@ class PageDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit PageDialog(BasePageProviderPtr pageProvider, QString defaultId = QString(), explicit PageDialog(BasePageProvider *pageProvider, QString defaultId = QString(), QWidget *parent = 0);
QWidget *parent = 0);
virtual ~PageDialog() {} virtual ~PageDialog() {}
private private

View File

@ -31,8 +31,18 @@ public:
virtual bool apply() { return true; } virtual bool apply() { return true; }
virtual bool shouldDisplay() const { return true; } virtual bool shouldDisplay() const { return true; }
virtual QString helpPage() const { return QString(); } virtual QString helpPage() const { return QString(); }
virtual void opened() {} void opened()
virtual void closed() {} {
isOpened = true;
openedImpl();
}
void closed()
{
isOpened = false;
closedImpl();
}
virtual void openedImpl() {}
virtual void closedImpl() {}
virtual void setParentContainer(BasePageContainer * container) virtual void setParentContainer(BasePageContainer * container)
{ {
m_container = container; m_container = container;
@ -42,6 +52,7 @@ public:
int listIndex = -1; int listIndex = -1;
protected: protected:
BasePageContainer * m_container = nullptr; BasePageContainer * m_container = nullptr;
bool isOpened = false;
}; };
typedef std::shared_ptr<BasePage> BasePagePtr; typedef std::shared_ptr<BasePage> BasePagePtr;

View File

@ -15,7 +15,7 @@
#pragma once #pragma once
#include "BasePage.h" #include "pages/BasePage.h"
#include <memory> #include <memory>
#include <functional> #include <functional>
@ -65,5 +65,3 @@ private:
QList<PageCreator> m_creators; QList<PageCreator> m_creators;
QString m_dialogTitle; QString m_dialogTitle;
}; };
typedef std::shared_ptr<BasePageProvider> BasePageProviderPtr;

View File

@ -218,7 +218,7 @@ void PackagesPage::updateVersion()
} }
} }
void PackagesPage::opened() void PackagesPage::openedImpl()
{ {
ENV.metadataIndex()->load(Net::Mode::Offline); ENV.metadataIndex()->load(Net::Mode::Offline);
} }

View File

@ -36,7 +36,7 @@ public:
QString id() const override { return "packages-global"; } QString id() const override { return "packages-global"; }
QString displayName() const override { return tr("Packages"); } QString displayName() const override { return tr("Packages"); }
QIcon icon() const override; QIcon icon() const override;
void opened() override; void openedImpl() override;
private slots: private slots:
void on_refreshIndexBtn_clicked(); void on_refreshIndexBtn_clicked();

View File

@ -20,7 +20,7 @@
#include "java/JavaChecker.h" #include "java/JavaChecker.h"
#include "BaseInstance.h" #include "BaseInstance.h"
#include <QObjectPtr.h> #include <QObjectPtr.h>
#include "BasePage.h" #include "pages/BasePage.h"
#include "JavaCommon.h" #include "JavaCommon.h"
#include "MultiMC.h" #include "MultiMC.h"

View File

@ -35,7 +35,12 @@ void LegacyUpgradePage::runModalTask(Task *task)
void LegacyUpgradePage::on_upgradeButton_clicked() void LegacyUpgradePage::on_upgradeButton_clicked()
{ {
std::unique_ptr<Task> task(MMC->folderProvider()->legacyUpgradeTask(m_inst)); QString newName = tr("%1 (Migrated)").arg(m_inst->name());
auto upgradeTask = new LegacyUpgradeTask(m_inst);
upgradeTask->setName(newName);
upgradeTask->setGroup(m_inst->group());
upgradeTask->setIcon(m_inst->iconKey());
std::unique_ptr<Task> task(MMC->folderProvider()->wrapInstanceTask(upgradeTask));
runModalTask(task.get()); runModalTask(task.get());
} }

View File

@ -19,7 +19,7 @@
#include "BaseInstance.h" #include "BaseInstance.h"
#include "launch/LaunchTask.h" #include "launch/LaunchTask.h"
#include "BasePage.h" #include "pages/BasePage.h"
#include <MultiMC.h> #include <MultiMC.h>
namespace Ui namespace Ui

View File

@ -59,12 +59,12 @@ ModFolderPage::ModFolderPage(BaseInstance *inst, std::shared_ptr<ModList> mods,
connect(ui->filterEdit, &QLineEdit::textChanged, this, &ModFolderPage::on_filterTextChanged ); connect(ui->filterEdit, &QLineEdit::textChanged, this, &ModFolderPage::on_filterTextChanged );
} }
void ModFolderPage::opened() void ModFolderPage::openedImpl()
{ {
m_mods->startWatching(); m_mods->startWatching();
} }
void ModFolderPage::closed() void ModFolderPage::closedImpl()
{ {
m_mods->stopWatching(); m_mods->stopWatching();
} }

View File

@ -18,7 +18,7 @@
#include <QWidget> #include <QWidget>
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
#include "BasePage.h" #include "pages/BasePage.h"
#include <MultiMC.h> #include <MultiMC.h>
class ModList; class ModList;
@ -60,8 +60,8 @@ public:
} }
virtual bool shouldDisplay() const override; virtual bool shouldDisplay() const override;
virtual void opened() override; virtual void openedImpl() override;
virtual void closed() override; virtual void closedImpl() override;
protected: protected:
bool eventFilter(QObject *obj, QEvent *ev) override; bool eventFilter(QObject *obj, QEvent *ev) override;
bool modListFilter(QKeyEvent *ev); bool modListFilter(QKeyEvent *ev);

View File

@ -18,7 +18,7 @@
#include <QWidget> #include <QWidget>
#include "BaseInstance.h" #include "BaseInstance.h"
#include "BasePage.h" #include "pages/BasePage.h"
#include <MultiMC.h> #include <MultiMC.h>
namespace Ui namespace Ui

View File

@ -54,11 +54,11 @@ OtherLogsPage::~OtherLogsPage()
delete ui; delete ui;
} }
void OtherLogsPage::opened() void OtherLogsPage::openedImpl()
{ {
m_watcher->enable(); m_watcher->enable();
} }
void OtherLogsPage::closed() void OtherLogsPage::closedImpl()
{ {
m_watcher->disable(); m_watcher->disable();
} }

View File

@ -17,7 +17,7 @@
#include <QWidget> #include <QWidget>
#include "BasePage.h" #include "pages/BasePage.h"
#include <MultiMC.h> #include <MultiMC.h>
#include <pathmatcher/IPathMatcher.h> #include <pathmatcher/IPathMatcher.h>
@ -52,8 +52,8 @@ public:
{ {
return "Minecraft-Logs"; return "Minecraft-Logs";
} }
void opened() override; void openedImpl() override;
void closed() override; void closedImpl() override;
private slots: private slots:
void populateSelectLogBox(); void populateSelectLogBox();

View File

@ -347,7 +347,7 @@ void ScreenshotsPage::on_renameBtn_clicked()
// TODO: mass renaming // TODO: mass renaming
} }
void ScreenshotsPage::opened() void ScreenshotsPage::openedImpl()
{ {
if(!m_valid) if(!m_valid)
{ {

View File

@ -17,7 +17,7 @@
#include <QWidget> #include <QWidget>
#include "BasePage.h" #include "pages/BasePage.h"
#include <MultiMC.h> #include <MultiMC.h>
class QFileSystemModel; class QFileSystemModel;
@ -39,7 +39,7 @@ public:
explicit ScreenshotsPage(QString path, QWidget *parent = 0); explicit ScreenshotsPage(QString path, QWidget *parent = 0);
virtual ~ScreenshotsPage(); virtual ~ScreenshotsPage();
virtual void opened() override; virtual void openedImpl() override;
enum enum
{ {

View File

@ -19,7 +19,7 @@
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
#include "minecraft/ComponentList.h" #include "minecraft/ComponentList.h"
#include "BasePage.h" #include "pages/BasePage.h"
namespace Ui namespace Ui
{ {

View File

@ -55,12 +55,12 @@ WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worl
worldChanged(QModelIndex(), QModelIndex()); worldChanged(QModelIndex(), QModelIndex());
} }
void WorldListPage::opened() void WorldListPage::openedImpl()
{ {
m_worlds->startWatching(); m_worlds->startWatching();
} }
void WorldListPage::closed() void WorldListPage::closedImpl()
{ {
m_worlds->stopWatching(); m_worlds->stopWatching();
} }

View File

@ -18,7 +18,7 @@
#include <QWidget> #include <QWidget>
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
#include "BasePage.h" #include "pages/BasePage.h"
#include <MultiMC.h> #include <MultiMC.h>
#include <LoggedProcess.h> #include <LoggedProcess.h>
@ -56,8 +56,8 @@ public:
} }
virtual bool shouldDisplay() const override; virtual bool shouldDisplay() const override;
virtual void opened() override; virtual void openedImpl() override;
virtual void closed() override; virtual void closedImpl() override;
protected: protected:
bool eventFilter(QObject *obj, QEvent *ev) override; bool eventFilter(QObject *obj, QEvent *ev) override;

View File

@ -0,0 +1,152 @@
#include "FTBPage.h"
#include "ui_FTBPage.h"
#include "MultiMC.h"
#include "FolderInstanceProvider.h"
#include "dialogs/CustomMessageBox.h"
#include "dialogs/NewInstanceDialog.h"
#include "modplatform/ftb/FtbPackDownloader.h"
#include "modplatform/ftb/FtbPackInstallTask.h"
#include <FtbListModel.h>
FTBPage::FTBPage(NewInstanceDialog* dialog, QWidget *parent)
: QWidget(parent), dialog(dialog), ui(new Ui::FTBPage)
{
ui->setupUi(this);
ftbPackDownloader = new FtbPackDownloader();
connect(ftbPackDownloader, &FtbPackDownloader::ready, this, &FTBPage::ftbPackDataDownloadSuccessfully);
connect(ftbPackDownloader, &FtbPackDownloader::packFetchFailed, this, &FTBPage::ftbPackDataDownloadFailed);
filterModel = new FtbFilterModel(this);
listModel = new FtbListModel(this);
filterModel->setSourceModel(listModel);
ui->packList->setModel(filterModel);
ui->packList->setSortingEnabled(true);
ui->packList->header()->hide();
ui->packList->setIndentation(0);
filterModel->setSorting(FtbFilterModel::Sorting::ByName);
for(int i = 0; i < filterModel->getAvailableSortings().size(); i++)
{
ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i));
}
ui->sortByBox->setCurrentText(filterModel->getAvailableSortings().key(filterModel->getCurrentSorting()));
connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &FTBPage::onSortingSelectionChanged);
connect(ui->packVersionSelection, &QComboBox::currentTextChanged, this, &FTBPage::onVersionSelectionItemChanged);
connect(ui->packList->selectionModel(), &QItemSelectionModel::currentChanged, this, &FTBPage::onPackSelectionChanged);
ui->modpackInfo->setOpenExternalLinks(true);
}
FTBPage::~FTBPage()
{
delete ui;
if(ftbPackDownloader)
{
ftbPackDownloader->deleteLater();
}
}
bool FTBPage::shouldDisplay() const
{
return true;
}
void FTBPage::openedImpl()
{
if(!initialized)
{
ftbPackDownloader->fetchModpacks(false);
initialized = true;
}
suggestCurrent();
}
void FTBPage::suggestCurrent()
{
if(isOpened)
{
if(!selected.broken)
{
dialog->setSuggestedPack(selected.name, new FtbPackInstallTask(selected, selectedVersion));
}
else
{
dialog->setSuggestedPack();
}
}
}
FtbPackDownloader *FTBPage::getFtbPackDownloader()
{
return ftbPackDownloader;
}
void FTBPage::ftbPackDataDownloadSuccessfully()
{
listModel->fill(ftbPackDownloader->getModpacks());
}
void FTBPage::ftbPackDataDownloadFailed()
{
qDebug() << "Stuff went missing while grabbing FTB pack list or something...";
}
void FTBPage::onPackSelectionChanged(QModelIndex now, QModelIndex prev)
{
ui->packVersionSelection->clear();
FtbModpack selectedPack = filterModel->data(now, Qt::UserRole).value<FtbModpack>();
ui->modpackInfo->setHtml("Pack by <b>" + selectedPack.author + "</b>" + "<br>Minecraft " + selectedPack.mcVersion + "<br>"
"<br>" + selectedPack.description + "<ul><li>" + selectedPack.mods.replace(";", "</li><li>") + "</li></ul>");
bool currentAdded = false;
for(int i = 0; i < selectedPack.oldVersions.size(); i++)
{
if(selectedPack.currentVersion == selectedPack.oldVersions.at(i))
{
currentAdded = true;
}
ui->packVersionSelection->addItem(selectedPack.oldVersions.at(i));
}
if(!currentAdded)
{
ui->packVersionSelection->addItem(selectedPack.currentVersion);
}
selected = selectedPack;
suggestCurrent();
}
void FTBPage::onVersionSelectionItemChanged(QString data)
{
if(data.isNull() || data.isEmpty())
{
selectedVersion = "";
return;
}
selectedVersion = data;
}
FtbModpack FTBPage::getSelectedModpack()
{
return selected;
}
QString FTBPage::getSelectedVersion()
{
return selectedVersion;
}
void FTBPage::onSortingSelectionChanged(QString data)
{
filterModel->setSorting(filterModel->getAvailableSortings().value(data));
}

View File

@ -0,0 +1,86 @@
/* Copyright 2013-2018 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 "pages/BasePage.h"
#include <MultiMC.h>
#include "tasks/Task.h"
#include "modplatform/ftb/PackHelpers.h"
namespace Ui
{
class FTBPage;
}
class FtbListModel;
class FtbFilterModel;
class FtbPackDownloader;
class NewInstanceDialog;
class FTBPage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit FTBPage(NewInstanceDialog * dialog, QWidget *parent = 0);
virtual ~FTBPage();
QString displayName() const override
{
return tr("FTB Legacy");
}
QIcon icon() const override
{
return MMC->getThemedIcon("ftb_logo");
}
QString id() const override
{
return "ftb";
}
QString helpPage() const override
{
return "FTB-platform";
}
bool shouldDisplay() const override;
void openedImpl() override;
FtbPackDownloader* getFtbPackDownloader();
FtbModpack getSelectedModpack();
QString getSelectedVersion();
private:
void suggestCurrent();
private slots:
void ftbPackDataDownloadSuccessfully();
void ftbPackDataDownloadFailed();
void onSortingSelectionChanged(QString data);
void onVersionSelectionItemChanged(QString data);
void onPackSelectionChanged(QModelIndex first, QModelIndex second);
private:
bool initialized = false;
FtbPackDownloader* ftbPackDownloader = nullptr;
FtbModpack selectedPack;
FtbModpack selected;
QString selectedVersion;
FtbListModel* listModel = nullptr;
FtbFilterModel* filterModel = nullptr;
NewInstanceDialog* dialog = nullptr;
Ui::FTBPage *ui = nullptr;
};

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FTBPage</class>
<widget class="QWidget" name="FTBPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>801</width>
<height>674</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTreeView" name="packList">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QTextBrowser" name="modpackInfo"/>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="sortByBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="selectedVersionLabel">
<property name="text">
<string>Version selected:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QComboBox" name="packVersionSelection">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,125 @@
#include "ImportPage.h"
#include "ui_ImportPage.h"
#include "MultiMC.h"
#include "FolderInstanceProvider.h"
#include "dialogs/CustomMessageBox.h"
#include "dialogs/ProgressDialog.h"
#include "dialogs/NewInstanceDialog.h"
#include <QFileDialog>
#include <InstanceImportTask.h>
class UrlValidator : public QValidator
{
public:
using QValidator::QValidator;
State validate(QString &in, int &pos) const
{
const QUrl url(in);
if (url.isValid() && !url.isRelative() && !url.isEmpty())
{
return Acceptable;
}
else if (QFile::exists(in))
{
return Acceptable;
}
else
{
return Intermediate;
}
}
};
ImportPage::ImportPage(NewInstanceDialog* dialog, QWidget *parent)
: QWidget(parent), ui(new Ui::ImportPage), dialog(dialog)
{
ui->setupUi(this);
ui->modpackEdit->setValidator(new UrlValidator(ui->modpackEdit));
connect(ui->modpackEdit, &QLineEdit::textChanged, this, &ImportPage::updateState);
}
ImportPage::~ImportPage()
{
delete ui;
}
bool ImportPage::shouldDisplay() const
{
return true;
}
void ImportPage::openedImpl()
{
updateState();
}
void ImportPage::updateState()
{
if(!isOpened)
{
return;
}
if(ui->modpackEdit->hasAcceptableInput())
{
QString input = ui->modpackEdit->text();
auto url = QUrl::fromUserInput(input);
if(url.isLocalFile())
{
// FIXME: actually do some validation of what's inside here... this is fake AF
QFileInfo fi(input);
if(fi.exists() && fi.suffix() == "zip")
{
QFileInfo fi(url.fileName());
dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
}
}
else
{
// hook, line and sinker.
QFileInfo fi(url.fileName());
dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
}
}
else
{
dialog->setSuggestedPack();
}
}
void ImportPage::setUrl(const QString& url)
{
ui->modpackEdit->setText(url);
updateState();
}
void ImportPage::on_modpackBtn_clicked()
{
const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), tr("Zip (*.zip)"));
if (url.isValid())
{
if (url.isLocalFile())
{
ui->modpackEdit->setText(url.toLocalFile());
}
else
{
ui->modpackEdit->setText(url.toString());
}
}
}
QUrl ImportPage::modpackUrl() const
{
const QUrl url(ui->modpackEdit->text());
if (url.isValid() && !url.isRelative() && !url.host().isEmpty())
{
return url;
}
else
{
return QUrl::fromLocalFile(ui->modpackEdit->text());
}
}

View File

@ -0,0 +1,70 @@
/* Copyright 2013-2018 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 "pages/BasePage.h"
#include <MultiMC.h>
#include "tasks/Task.h"
namespace Ui
{
class ImportPage;
}
class NewInstanceDialog;
class ImportPage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit ImportPage(NewInstanceDialog* dialog, QWidget *parent = 0);
virtual ~ImportPage();
virtual QString displayName() const override
{
return tr("Import from zip");
}
virtual QIcon icon() const override
{
return MMC->getThemedIcon("viewfolder");
}
virtual QString id() const override
{
return "import";
}
virtual QString helpPage() const override
{
return "Zip-import";
}
virtual bool shouldDisplay() const override;
void setUrl(const QString & url);
void openedImpl() override;
private slots:
void on_modpackBtn_clicked();
void updateState();
private:
QUrl modpackUrl() const;
private:
Ui::ImportPage *ui = nullptr;
NewInstanceDialog* dialog = nullptr;
};

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImportPage</class>
<widget class="QWidget" name="ImportPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>546</width>
<height>405</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QPushButton" name="modpackBtn">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="modpackEdit">
<property name="placeholderText">
<string notr="true">http://</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="modpackLabel">
<property name="text">
<string>Local file or link to a direct download:</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<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>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,29 @@
#include "TechnicPage.h"
#include "ui_TechnicPage.h"
#include "MultiMC.h"
#include "FolderInstanceProvider.h"
#include "dialogs/CustomMessageBox.h"
#include "dialogs/ProgressDialog.h"
#include "dialogs/NewInstanceDialog.h"
TechnicPage::TechnicPage(NewInstanceDialog* dialog, QWidget *parent)
: QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog)
{
ui->setupUi(this);
}
TechnicPage::~TechnicPage()
{
delete ui;
}
bool TechnicPage::shouldDisplay() const
{
return true;
}
void TechnicPage::openedImpl()
{
dialog->setSuggestedPack();
}

View File

@ -0,0 +1,61 @@
/* Copyright 2013-2018 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 "pages/BasePage.h"
#include <MultiMC.h>
#include "tasks/Task.h"
namespace Ui
{
class TechnicPage;
}
class NewInstanceDialog;
class TechnicPage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit TechnicPage(NewInstanceDialog* dialog, QWidget *parent = 0);
virtual ~TechnicPage();
virtual QString displayName() const override
{
return tr("Technic");
}
virtual QIcon icon() const override
{
return MMC->getThemedIcon("technic");
}
virtual QString id() const override
{
return "technic";
}
virtual QString helpPage() const override
{
return "Technic-platform";
}
virtual bool shouldDisplay() const override;
void openedImpl() override;
private:
Ui::TechnicPage *ui = nullptr;
NewInstanceDialog* dialog = nullptr;
};

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TechnicPage</class>
<widget class="QWidget" name="TechnicPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>546</width>
<height>405</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>40</pointsize>
</font>
</property>
<property name="text">
<string notr="true">¯\_(ツ)_/¯ </string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,29 @@
#include "TwitchPage.h"
#include "ui_TwitchPage.h"
#include "MultiMC.h"
#include "FolderInstanceProvider.h"
#include "dialogs/CustomMessageBox.h"
#include "dialogs/ProgressDialog.h"
#include "dialogs/NewInstanceDialog.h"
TwitchPage::TwitchPage(NewInstanceDialog* dialog, QWidget *parent)
: QWidget(parent), ui(new Ui::TwitchPage), dialog(dialog)
{
ui->setupUi(this);
}
TwitchPage::~TwitchPage()
{
delete ui;
}
bool TwitchPage::shouldDisplay() const
{
return true;
}
void TwitchPage::openedImpl()
{
dialog->setSuggestedPack();
}

View File

@ -0,0 +1,61 @@
/* Copyright 2013-2018 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 "pages/BasePage.h"
#include <MultiMC.h>
#include "tasks/Task.h"
namespace Ui
{
class TwitchPage;
}
class NewInstanceDialog;
class TwitchPage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit TwitchPage(NewInstanceDialog* dialog, QWidget *parent = 0);
virtual ~TwitchPage();
virtual QString displayName() const override
{
return tr("Twitch");
}
virtual QIcon icon() const override
{
return MMC->getThemedIcon("twitch");
}
virtual QString id() const override
{
return "twitch";
}
virtual QString helpPage() const override
{
return "Twitch-platform";
}
virtual bool shouldDisplay() const override;
void openedImpl() override;
private:
Ui::TwitchPage *ui = nullptr;
NewInstanceDialog* dialog = nullptr;
};

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TwitchPage</class>
<widget class="QWidget" name="TwitchPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>546</width>
<height>405</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>40</pointsize>
</font>
</property>
<property name="text">
<string notr="true">¯\_(ツ)_/¯ </string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,114 @@
#include "VanillaPage.h"
#include "ui_VanillaPage.h"
#include "MultiMC.h"
#include "FolderInstanceProvider.h"
#include "dialogs/CustomMessageBox.h"
#include "dialogs/ProgressDialog.h"
#include <meta/Index.h>
#include <meta/VersionList.h>
#include <dialogs/NewInstanceDialog.h>
#include <Filter.h>
#include <Env.h>
#include <InstanceCreationTask.h>
VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent)
: QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage)
{
ui->setupUi(this);
ui->tabWidget->tabBar()->hide();
connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedVersion);
filterChanged();
connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
connect(ui->betaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
}
void VanillaPage::openedImpl()
{
if(!initialized)
{
auto vlist = ENV.metadataIndex()->get("net.minecraft");
ui->versionList->initialize(vlist.get());
if(vlist->isLoaded())
{
setSelectedVersion(vlist->getRecommended());
}
else
{
vlist->load(Net::Mode::Online);
auto task = vlist->getLoadTask();
if(vlist->isLoaded())
{
setSelectedVersion(vlist->getRecommended());
}
if(task)
{
connect(task.get(), &Task::succeeded, this, &VanillaPage::versionListUpdated);
}
}
initialized = true;
}
else
{
suggestCurrent();
}
}
void VanillaPage::filterChanged()
{
QStringList out;
if(ui->alphaFilter->isChecked())
out << "(old_alpha)";
if(ui->betaFilter->isChecked())
out << "(old_beta)";
if(ui->snapshotFilter->isChecked())
out << "(snapshot)";
if(ui->oldSnapshotFilter->isChecked())
out << "(old_snapshot)";
if(ui->releaseFilter->isChecked())
out << "(release)";
auto regexp = out.join('|');
ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false));
}
VanillaPage::~VanillaPage()
{
delete ui;
}
bool VanillaPage::shouldDisplay() const
{
return true;
}
BaseVersionPtr VanillaPage::selectedVersion() const
{
return m_selectedVersion;
}
void VanillaPage::versionListUpdated()
{
if(!m_versionSetByUser)
{
auto vlist = ENV.metadataIndex()->get("net.minecraft");
setSelectedVersion(vlist->getRecommended());
}
}
void VanillaPage::suggestCurrent()
{
if(m_selectedVersion && isOpened)
{
dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
}
}
void VanillaPage::setSelectedVersion(BaseVersionPtr version)
{
m_selectedVersion = version;
suggestCurrent();
}

View File

@ -0,0 +1,75 @@
/* Copyright 2013-2018 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 "pages/BasePage.h"
#include <MultiMC.h>
#include "tasks/Task.h"
namespace Ui
{
class VanillaPage;
}
class NewInstanceDialog;
class VanillaPage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit VanillaPage(NewInstanceDialog *dialog, QWidget *parent = 0);
virtual ~VanillaPage();
virtual QString displayName() const override
{
return tr("Vanilla");
}
virtual QIcon icon() const override
{
return MMC->getThemedIcon("minecraft");
}
virtual QString id() const override
{
return "vanilla";
}
virtual QString helpPage() const override
{
return "Vanilla-platform";
}
virtual bool shouldDisplay() const override;
void openedImpl() override;
BaseVersionPtr selectedVersion() const;
public slots:
void setSelectedVersion(BaseVersionPtr version);
private slots:
void versionListUpdated();
void filterChanged();
private:
void suggestCurrent();
private:
bool initialized = false;
NewInstanceDialog *dialog = nullptr;
Ui::VanillaPage *ui = nullptr;
bool m_versionSetByUser = false;
BaseVersionPtr m_selectedVersion;
};

View File

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VanillaPage</class>
<widget class="QWidget" name="VanillaPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>815</width>
<height>607</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string notr="true">Tab 1</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Filter</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="releaseFilter">
<property name="text">
<string>Releases</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="snapshotFilter">
<property name="text">
<string>Snapshots</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="oldSnapshotFilter">
<property name="text">
<string>Old Snapshots</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="betaFilter">
<property name="text">
<string>Betas</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="alphaFilter">
<property name="text">
<string>Alphas</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<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>
<widget class="QPushButton" name="refreshBtn">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="VersionSelectWidget" name="versionList" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>VersionSelectWidget</class>
<extends>QWidget</extends>
<header>widgets/VersionSelectWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -11,6 +11,12 @@
<!-- REDDIT logo icon, needs reddit license! --> <!-- REDDIT logo icon, needs reddit license! -->
<file>scalable/reddit-alien.svg</file> <file>scalable/reddit-alien.svg</file>
<!-- twitch logo icon -->
<file>scalable/twitch.svg</file>
<!-- technic logo icon -->
<file>scalable/technic.svg</file>
<!-- A proxy icon. Our own. SSSsss --> <!-- A proxy icon. Our own. SSSsss -->
<file>scalable/proxy.svg</file> <file>scalable/proxy.svg</file>

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2479" viewBox="0 0 1464.248 1452.156"><path fill="#1389D2" d="M644.592 5.192c159.049-19.094 324.188 14.764 461.941 96.756 143.299 84.188 256.41 218.769 313.509 374.945 62.353 168.133 58.63 359.689-10.432 525.205-63.691 154.529-182.775 285.021-330.227 363.417-149.71 80.709-327.849 105.845-494.333 71.979-172.465-34.279-331.022-133.533-437.232-273.729C51.059 1037.725-2.015 878.924.058 719.941c.548-167.949 63.08-334.559 172.343-461.998C290.451 118.177 462.794 25.934 644.592 5.192m-120.67 181.494c-131.408 49.538-243.479 148.488-308.511 273.003-60.641 114.509-80.038 249.94-54.906 377.018 25.076 130.193 97.609 250.192 200.162 334.012 101.76 84.247 232.924 131.896 365.063 132.754-.795-37.831-.366-75.591-1.04-113.416-.792-31.415-30.866-53.744-59.722-58.563-.917 28.305.119 62.895-24.771 82.113-23.731 16.288-55.638 15.919-82.479 8.782-27.149-7.626-42.216-35.808-43.011-62.532-1.647-40.565-.244-81.196-.729-121.828-10.86-.059-21.781-.059-32.702-.059-.06-35.442-.06-70.892 0-106.273 10.92-.065 21.84-.125 32.762-.125 0-12.076 0-24.093-.06-36.115-14.033-4.635-30.263-10.188-35.934-25.379-14.033-33.186 3.417-70.462-10.188-103.891-13.911-35.203-27.759-74.125-14.825-111.888 7.992-26.598 34.042-43.56 61.007-45.694-.06-76.808 0-153.553-.06-230.358-.429-40.754 16.288-82.725 48.924-108.164 37.215-29.525 86.57-37.092 132.812-36.786 102.921.061 203.701 48.864 270.2 126.893-.124 18.362 0 36.727-.124 55.149-92.185.061-184.359-.063-276.54 0-10.006-1.828-19.523 7.505-17.754 17.569.304 58.812-.549 117.682-.308 176.492 17.021.061 34.104.304 51.125-.488 2.866-11.774 6.038-23.425 9.454-35.019 74.982 18.424 149.893 36.789 224.809 55.335-2.502 8.6-4.938 17.266-7.382 25.927-6.588 2.5-13.177 5.001-19.767 7.504-2.621 203.154-4.331 406.363-6.648 609.514 176.251-60.091 319.795-208.828 369.755-388.73 39.415-137.021 25.262-288.622-39.527-415.699-63.628-126.646-175.579-227.98-307.72-279.104-133.783-52.65-287.092-53.321-421.365-1.954m140.741 710.665c0 11.401 0 22.817.063 34.221 10.125.06 20.253.06 30.381.06.061 35.448.061 70.896 0 106.34-10.128 0-20.315 0-30.442.059v32.333c19.949.06 39.961.06 59.909-.061-.917-57.646-.365-115.305-1.283-172.95a9391.232 9391.232 0 0 0-58.628-.002z"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="Layer_1"
data-name="Layer 1"
viewBox="0 0 134 134"
version="1.1"
sodipodi:docname="twitch.svg"
inkscape:version="0.92.2 2405546, 2018-03-11"
width="134"
height="134">
<metadata
id="metadata13">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Glitch</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1414"
inkscape:window-height="944"
id="namedview11"
showgrid="false"
inkscape:zoom="1.761194"
inkscape:cx="-109.17797"
inkscape:cy="66.999998"
inkscape:window-x="2640"
inkscape:window-y="554"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:#6441a4;fill-rule:evenodd;}</style>
</defs>
<title
id="title6">Glitch</title>
<path
class="cls-1"
d="M 9,0 0,23 v 94 h 32 v 17 H 50 L 67,117 H 93 L 128,82 V 0 Z M 116,76 96,96 H 64 L 47,113 V 96 H 20 V 12 h 96 z M 96,35 V 70 H 84 V 35 Z M 64,35 V 70 H 52 V 35 Z"
id="path8"
style="fill:#6441a4;fill-opacity:1;fill-rule:evenodd"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InstanceCardWidget</class>
<widget class="QWidget" name="InstanceCardWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>473</width>
<height>118</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QToolButton" name="iconButton">
<property name="iconSize">
<size>
<width>80</width>
<height>80</height>
</size>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>&amp;Name:</string>
</property>
<property name="buddy">
<cstring>instNameTextBox</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="instNameTextBox"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="groupLabel">
<property name="text">
<string>&amp;Group:</string>
</property>
<property name="buddy">
<cstring>groupBox</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="groupBox">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -41,7 +41,7 @@ void JavaSettingsWidget::setupUi()
m_verticalLayout = new QVBoxLayout(this); m_verticalLayout = new QVBoxLayout(this);
m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
m_versionWidget = new VersionSelectWidget(MMC->javalist().get(), this); m_versionWidget = new VersionSelectWidget(this);
m_versionWidget->setResizeOn(2); m_versionWidget->setResizeOn(2);
m_verticalLayout->addWidget(m_versionWidget); m_verticalLayout->addWidget(m_versionWidget);
@ -116,7 +116,7 @@ void JavaSettingsWidget::setupUi()
void JavaSettingsWidget::initialize() void JavaSettingsWidget::initialize()
{ {
m_versionWidget->initialize(); m_versionWidget->initialize(MMC->javalist().get());
auto s = MMC->settings(); auto s = MMC->settings();
// Memory // Memory
observedMinMemory = s->get("MinMemAlloc").toInt(); observedMinMemory = s->get("MinMemAlloc").toInt();

View File

@ -53,7 +53,7 @@ protected:
} }
}; };
PageContainer::PageContainer(BasePageProviderPtr pageProvider, QString defaultId, PageContainer::PageContainer(BasePageProvider *pageProvider, QString defaultId,
QWidget *parent) QWidget *parent)
: QWidget(parent) : QWidget(parent)
{ {
@ -158,6 +158,7 @@ void PageContainer::createUI()
m_layout->addWidget(m_pageList, 0, 0, 2, 1); m_layout->addWidget(m_pageList, 0, 0, 2, 1);
m_layout->addLayout(m_pageStack, 1, 1, 1, 1); m_layout->addLayout(m_pageStack, 1, 1, 1, 1);
m_layout->setColumnStretch(1, 4); m_layout->setColumnStretch(1, 4);
m_layout->setContentsMargins(0, 0, 0, 0);
setLayout(m_layout); setLayout(m_layout);
} }

View File

@ -35,7 +35,7 @@ class PageContainer : public QWidget, public BasePageContainer
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit PageContainer(BasePageProviderPtr pageProvider, QString defaultId = QString(), explicit PageContainer(BasePageProvider *pageProvider, QString defaultId = QString(),
QWidget *parent = 0); QWidget *parent = 0);
virtual ~PageContainer() {} virtual ~PageContainer() {}
@ -67,11 +67,13 @@ public:
private: private:
void createUI(); void createUI();
private
slots: public slots:
void help();
private slots:
void currentChanged(const QModelIndex &current); void currentChanged(const QModelIndex &current);
void showPage(int row); void showPage(int row);
void help();
private: private:
BasePageContainer * m_container = nullptr; BasePageContainer * m_container = nullptr;

View File

@ -6,8 +6,8 @@
#include <VersionProxyModel.h> #include <VersionProxyModel.h>
#include <dialogs/CustomMessageBox.h> #include <dialogs/CustomMessageBox.h>
VersionSelectWidget::VersionSelectWidget(BaseVersionList* vlist, QWidget* parent) VersionSelectWidget::VersionSelectWidget(QWidget* parent)
: QWidget(parent), m_vlist(vlist) : QWidget(parent)
{ {
setObjectName(QStringLiteral("VersionSelectWidget")); setObjectName(QStringLiteral("VersionSelectWidget"));
verticalLayout = new QVBoxLayout(this); verticalLayout = new QVBoxLayout(this);
@ -15,7 +15,6 @@ VersionSelectWidget::VersionSelectWidget(BaseVersionList* vlist, QWidget* parent
verticalLayout->setContentsMargins(0, 0, 0, 0); verticalLayout->setContentsMargins(0, 0, 0, 0);
m_proxyModel = new VersionProxyModel(this); m_proxyModel = new VersionProxyModel(this);
m_proxyModel->setSourceModel(vlist);
listView = new VersionListView(this); listView = new VersionListView(this);
listView->setObjectName(QStringLiteral("listView")); listView->setObjectName(QStringLiteral("listView"));
@ -27,8 +26,6 @@ VersionSelectWidget::VersionSelectWidget(BaseVersionList* vlist, QWidget* parent
listView->header()->setCascadingSectionResizes(true); listView->header()->setCascadingSectionResizes(true);
listView->header()->setStretchLastSection(false); listView->header()->setStretchLastSection(false);
listView->setModel(m_proxyModel); listView->setModel(m_proxyModel);
listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch);
verticalLayout->addWidget(listView); verticalLayout->addWidget(listView);
sneakyProgressBar = new QProgressBar(this); sneakyProgressBar = new QProgressBar(this);
@ -67,8 +64,13 @@ void VersionSelectWidget::setResizeOn(int column)
listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch);
} }
void VersionSelectWidget::initialize() void VersionSelectWidget::initialize(BaseVersionList *vlist)
{ {
m_vlist = vlist;
m_proxyModel->setSourceModel(vlist);
listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch);
if (!m_vlist->isLoaded()) if (!m_vlist->isLoaded())
{ {
loadList(); loadList();
@ -185,10 +187,15 @@ BaseVersionPtr VersionSelectWidget::selectedVersion() const
void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter) void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter)
{ {
m_proxyModel->setFilter(role, filter, true); m_proxyModel->setFilter(role, new ExactFilter(filter));
} }
void VersionSelectWidget::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter) void VersionSelectWidget::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter)
{ {
m_proxyModel->setFilter(role, filter, false); m_proxyModel->setFilter(role, new ContainsFilter(filter));
}
void VersionSelectWidget::setFilter(BaseVersionList::ModelRoles role, Filter *filter)
{
m_proxyModel->setFilter(role, filter);
} }

View File

@ -23,16 +23,17 @@ class VersionProxyModel;
class VersionListView; class VersionListView;
class QVBoxLayout; class QVBoxLayout;
class QProgressBar; class QProgressBar;
class Filter;
class VersionSelectWidget: public QWidget class VersionSelectWidget: public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit VersionSelectWidget(BaseVersionList *vlist, QWidget *parent = 0); explicit VersionSelectWidget(QWidget *parent = 0);
~VersionSelectWidget(); ~VersionSelectWidget();
//! loads the list if needed. //! loads the list if needed.
void initialize(); void initialize(BaseVersionList *vlist);
//! Starts a task that loads the list. //! Starts a task that loads the list.
void loadList(); void loadList();
@ -45,6 +46,7 @@ public:
void setCurrentVersion(const QString & version); void setCurrentVersion(const QString & version);
void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
void setExactFilter(BaseVersionList::ModelRoles role, QString filter); void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
void setFilter(BaseVersionList::ModelRoles role, Filter *filter);
void setEmptyString(QString emptyString); void setEmptyString(QString emptyString);
void setEmptyErrorString(QString emptyErrorString); void setEmptyErrorString(QString emptyErrorString);
void setResizeOn(int column); void setResizeOn(int column);