summaryrefslogtreecommitdiffstats
path: root/application
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2016-10-03 00:55:54 +0200
committerPetr Mrázek <peterix@gmail.com>2016-10-26 18:21:24 +0200
commitd66fdcd4cc6913508d2987c14cd9fc4d6760b8a5 (patch)
tree4f385106ce732d4f7338feab5391f2a06c68a0e6 /application
parentbbe139dce51a7965394c800cac974946820d3869 (diff)
downloadMultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar
MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar.gz
MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar.lz
MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.tar.xz
MultiMC-d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5.zip
NOISSUE Granular instance reload
Diffstat (limited to 'application')
-rw-r--r--application/InstanceWindow.cpp39
-rw-r--r--application/InstanceWindow.h2
-rw-r--r--application/MainWindow.cpp235
-rw-r--r--application/MainWindow.h5
-rw-r--r--application/MultiMC.cpp14
-rw-r--r--application/MultiMC.h7
6 files changed, 87 insertions, 215 deletions
diff --git a/application/InstanceWindow.cpp b/application/InstanceWindow.cpp
index 3bfc78db..9fdd3ca8 100644
--- a/application/InstanceWindow.cpp
+++ b/application/InstanceWindow.cpp
@@ -95,9 +95,23 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent)
connect(m_instance.get(), &BaseInstance::runningStatusChanged,
this, &InstanceWindow::on_RunningState_changed);
}
+
+ // set up instance destruction detection
+ {
+ connect(m_instance.get(), &BaseInstance::statusChanged, this, &InstanceWindow::on_instanceStatusChanged);
+ }
show();
}
+void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus)
+{
+ if(newStatus == BaseInstance::Status::Gone)
+ {
+ m_doNotSave = true;
+ close();
+ }
+}
+
void InstanceWindow::setKillButton(bool kill)
{
if(kill)
@@ -145,18 +159,25 @@ void InstanceWindow::on_closeButton_clicked()
void InstanceWindow::closeEvent(QCloseEvent *event)
{
+ bool proceed = true;
+ if(!m_doNotSave)
+ {
+ proceed &= m_container->requestClose(event);
+ }
+
+ if(!proceed)
+ {
+ return;
+ }
+
MMC->settings()->set("ConsoleWindowState", saveState().toBase64());
MMC->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64());
-
- if(m_container->requestClose(event))
+ emit isClosing();
+ event->accept();
+ if(m_shouldQuit)
{
- emit isClosing();
- event->accept();
- if(m_shouldQuit)
- {
- // this needs to be delayed so we don't do horrible things
- QMetaObject::invokeMethod(MMC, "quit", Qt::QueuedConnection);
- }
+ // this needs to be delayed so we don't do horrible things
+ QMetaObject::invokeMethod(MMC, "quit", Qt::QueuedConnection);
}
}
diff --git a/application/InstanceWindow.h b/application/InstanceWindow.h
index 1da2231f..71bf4d40 100644
--- a/application/InstanceWindow.h
+++ b/application/InstanceWindow.h
@@ -55,6 +55,7 @@ slots:
void on_InstanceLaunchTask_changed(std::shared_ptr<LaunchTask> proc);
void on_RunningState_changed(bool running);
+ void on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus);
protected:
void closeEvent(QCloseEvent *) override;
@@ -67,6 +68,7 @@ private:
unique_qobject_ptr<LaunchController> m_launchController;
InstancePtr m_instance;
bool m_shouldQuit = false;
+ bool m_doNotSave = false;
PageContainer *m_container = nullptr;
QPushButton *m_closeButton = nullptr;
QPushButton *m_killButton = nullptr;
diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp
index c91f5256..3a297784 100644
--- a/application/MainWindow.cpp
+++ b/application/MainWindow.cpp
@@ -88,6 +88,8 @@
#include "dialogs/EditAccountDialog.h"
#include "dialogs/NotificationDialog.h"
#include "dialogs/ExportInstanceDialog.h"
+#include <FolderInstanceProvider.h>
+#include <InstanceImportTask.h>
class MainWindow::Ui
{
@@ -996,26 +998,6 @@ void MainWindow::setCatBackground(bool enabled)
}
}
-static QFileInfo findRecursive(const QString &dir, const QString &name)
-{
- for (const auto info : QDir(dir).entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files, QDir::DirsLast))
- {
- if (info.isFile() && info.fileName() == name)
- {
- return info;
- }
- else if (info.isDir())
- {
- const QFileInfo res = findRecursive(info.absoluteFilePath(), name);
- if (res.isFile() && res.exists())
- {
- return res;
- }
- }
- }
- return QFileInfo();
-}
-
// FIXME: eliminate, should not be needed
void MainWindow::waitForMinecraftVersions()
{
@@ -1028,147 +1010,50 @@ void MainWindow::waitForMinecraftVersions()
}
}
-InstancePtr MainWindow::instanceFromZipPack(QString instName, QString instGroup, QString instIcon, QUrl url)
+void MainWindow::runModalTask(Task *task)
{
- InstancePtr newInstance;
-
- QString instancesDir = MMC->settings()->get("InstanceDir").toString();
- QString instDirName = FS::DirNameFromString(instName, instancesDir);
- QString instDir = FS::PathCombine(instancesDir, instDirName);
-
- QString archivePath;
- if (url.isLocalFile())
- {
- archivePath = url.toLocalFile();
- }
- else
- {
- const QString path = url.host() + '/' + url.path();
- auto entry = ENV.metacache()->resolveEntry("general", path);
- entry->setStale(true);
- NetJob job(tr("Modpack download"));
- job.addNetAction(Net::Download::makeCached(url, entry));
-
- // FIXME: possibly causes endless loop problems
- ProgressDialog dlDialog(this);
- job.setStatus(tr("Downloading modpack:\n%1").arg(url.toString()));
- if (dlDialog.execWithTask(&job) != QDialog::Accepted)
+ connect(task, &Task::failed, [this](QString reason)
{
- return nullptr;
- }
- archivePath = entry->getFullPath();
- }
+ CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
+ });
+ ProgressDialog loadDialog(this);
+ loadDialog.setSkipButton(true, tr("Abort"));
+ loadDialog.execWithTask(task);
+}
- QTemporaryDir extractTmpDir;
- QDir extractDir(extractTmpDir.path());
- qDebug() << "Attempting to create instance from" << archivePath;
- if (MMCZip::extractDir(archivePath, extractDir.absolutePath()).isEmpty())
- {
- CustomMessageBox::selectable(this, tr("Error"), tr("Failed to extract modpack"), QMessageBox::Warning)->show();
- return nullptr;
- }
- const QFileInfo instanceCfgFile = findRecursive(extractDir.absolutePath(), "instance.cfg");
- if (!instanceCfgFile.isFile() || !instanceCfgFile.exists())
- {
- CustomMessageBox::selectable(this, tr("Error"), tr("Archive does not contain instance.cfg"))->show();
- return nullptr;
- }
- if (!FS::copy(instanceCfgFile.absoluteDir().absolutePath(), instDir)())
- {
- CustomMessageBox::selectable(this, tr("Error"), tr("Unable to copy instance"))->show();
- return nullptr;
- }
+void MainWindow::instanceFromZipPack(QString instName, QString instGroup, QString instIcon, QUrl url)
+{
+ std::unique_ptr<Task> task(MMC->folderProvider()->zipImportTask(url, instName, instGroup, instIcon));
+ runModalTask(task.get());
- auto error = MMC->instances()->loadInstance(newInstance, instDir);
- QString errorMsg = tr("Failed to load instance %1: ").arg(instDirName);
- switch (error)
- {
- case InstanceList::UnknownLoadError:
- errorMsg += tr("Unkown error");
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- return nullptr;
- case InstanceList::NotAnInstance:
- errorMsg += tr("Not an instance");
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- return nullptr;
- default:
- break;
- }
+ // FIXME: handle instance selection after creation
+ // finalizeInstance(newInstance);
+}
- newInstance->setName(instName);
- if (instIcon != "default")
- {
- newInstance->setIconKey(instIcon);
- }
- else
- {
- instIcon = newInstance->iconKey();
- auto importIconPath = FS::PathCombine(newInstance->instanceRoot(), instIcon + ".png");
- if (QFile::exists(importIconPath))
- {
- // import icon
- auto iconList = MMC->icons();
- // FIXME: check if the file is OK before removing the existing one...
- if (iconList->iconFileExists(instIcon))
- {
- // FIXME: ask if icon should be overwritten. Show difference in the question dialog.
- iconList->deleteIcon(instIcon);
- }
- iconList->installIcons({importIconPath});
- }
- }
- newInstance->setGroupInitial(instGroup);
- // reset time played on import... because packs.
- newInstance->resetTimePlayed();
- MMC->instances()->add(InstancePtr(newInstance));
- MMC->instances()->saveGroupList();
+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());
- finalizeInstance(newInstance);
- return newInstance;
+ // FIXME: handle instance selection after creation
+ // finalizeInstance(newInstance);
}
-InstancePtr MainWindow::instanceFromVersion(QString instName, QString instGroup, QString instIcon, BaseVersionPtr version)
+void MainWindow::on_actionCopyInstance_triggered()
{
- InstancePtr newInstance;
-
- QString instancesDir = MMC->settings()->get("InstanceDir").toString();
- QString instDirName = FS::DirNameFromString(instName, instancesDir);
- QString instDir = FS::PathCombine(instancesDir, instDirName);
- auto error = MMC->instances()->createInstance(newInstance, version, instDir);
- QString errorMsg = tr("Failed to create instance %1: ").arg(instDirName);
- switch (error)
- {
- case InstanceList::NoCreateError:
- break;
+ if (!m_selectedInstance)
+ return;
- case InstanceList::InstExists:
- {
- errorMsg += tr("An instance with the given directory name already exists.");
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- return nullptr;
- }
+ CopyInstanceDialog copyInstDlg(m_selectedInstance, this);
+ if (!copyInstDlg.exec())
+ return;
- case InstanceList::CantCreateDir:
- {
- errorMsg += tr("Failed to create the instance directory.");
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- return nullptr;
- }
+ std::unique_ptr<Task> task(MMC->folderProvider()->copyTask(m_selectedInstance, copyInstDlg.instName(), copyInstDlg.instGroup(),
+ copyInstDlg.iconKey(), copyInstDlg.shouldCopySaves()));
+ runModalTask(task.get());
- default:
- {
- errorMsg += tr("Unknown instance loader error %1").arg(error);
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- return nullptr;
- }
- }
- newInstance->setName(instName);
- newInstance->setIconKey(instIcon);
- newInstance->setGroupInitial(instGroup);
- MMC->instances()->add(InstancePtr(newInstance));
- MMC->instances()->saveGroupList();
- finalizeInstance(newInstance);
- return newInstance;
+ // FIXME: handle instance selection after creation
+ // finalizeInstance(newInstance);
}
void MainWindow::finalizeInstance(InstancePtr inst)
@@ -1251,56 +1136,6 @@ void MainWindow::on_actionDISCORD_triggered()
DesktopServices::openUrl(QUrl("https://discord.gg/0k2zsXGNHs0fE4Wm"));
}
-void MainWindow::on_actionCopyInstance_triggered()
-{
- if (!m_selectedInstance)
- return;
-
- CopyInstanceDialog copyInstDlg(m_selectedInstance, this);
- if (!copyInstDlg.exec())
- return;
-
- QString instancesDir = MMC->settings()->get("InstanceDir").toString();
- QString instDirName = FS::DirNameFromString(copyInstDlg.instName(), instancesDir);
- QString instDir = FS::PathCombine(instancesDir, instDirName);
- bool copySaves = copyInstDlg.shouldCopySaves();
-
- InstancePtr newInstance;
- auto error = MMC->instances()->copyInstance(newInstance, m_selectedInstance, instDir, copySaves);
-
- QString errorMsg = tr("Failed to create instance %1: ").arg(instDirName);
- switch (error)
- {
- case InstanceList::NoCreateError:
- newInstance->setName(copyInstDlg.instName());
- newInstance->setIconKey(copyInstDlg.iconKey());
- MMC->instances()->add(newInstance);
- newInstance->setGroupPost(copyInstDlg.instGroup());
- return;
-
- case InstanceList::InstExists:
- {
- errorMsg += tr("An instance with the given directory name already exists.");
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- break;
- }
-
- case InstanceList::CantCreateDir:
- {
- errorMsg += tr("Failed to create the instance directory.");
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- break;
- }
-
- default:
- {
- errorMsg += tr("Unknown instance loader error %1").arg(error);
- CustomMessageBox::selectable(this, tr("Error"), errorMsg, QMessageBox::Warning)->show();
- break;
- }
- }
-}
-
void MainWindow::on_actionChangeInstIcon_triggered()
{
if (!m_selectedInstance)
@@ -1386,7 +1221,7 @@ void MainWindow::on_actionViewInstanceFolder_triggered()
void MainWindow::on_actionRefresh_triggered()
{
- MMC->instances()->loadList();
+ MMC->instances()->loadList(true);
}
void MainWindow::on_actionViewCentralModsFolder_triggered()
diff --git a/application/MainWindow.h b/application/MainWindow.h
index 3f0ec6e6..d0660676 100644
--- a/application/MainWindow.h
+++ b/application/MainWindow.h
@@ -170,8 +170,9 @@ private:
void setSelectedInstanceById(const QString &id);
void waitForMinecraftVersions();
- InstancePtr instanceFromVersion(QString instName, QString instGroup, QString instIcon, BaseVersionPtr version);
- InstancePtr instanceFromZipPack(QString instName, QString instGroup, QString instIcon, QUrl url);
+ void runModalTask(Task *task);
+ void instanceFromVersion(QString instName, QString instGroup, QString instIcon, BaseVersionPtr version);
+ void instanceFromZipPack(QString instName, QString instGroup, QString instIcon, QUrl url);
void finalizeInstance(InstancePtr inst);
void launch(InstancePtr instance, bool online = true, BaseProfilerFactory *profiler = nullptr);
diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp
index 6d671bd4..a226f3b7 100644
--- a/application/MultiMC.cpp
+++ b/application/MultiMC.cpp
@@ -25,6 +25,9 @@
#include <QStyleFactory>
#include "InstanceList.h"
+#include "FolderInstanceProvider.h"
+#include "minecraft/ftb/FTBInstanceProvider.h"
+
#include <minecraft/auth/MojangAccountList.h>
#include "icons/IconList.h"
//FIXME: get rid of this
@@ -261,10 +264,13 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar
<< "Your instance path contains \'!\' and this is known to cause java problems";
}
m_instances.reset(new InstanceList(m_settings, InstDirSetting->get().toString(), this));
+ m_instanceFolder = new FolderInstanceProvider(m_settings, instDir);
+ connect(InstDirSetting.get(), &Setting::SettingChanged, m_instanceFolder, &FolderInstanceProvider::on_InstFolderChanged);
+ m_instances->addInstanceProvider(m_instanceFolder);
+ m_instances->addInstanceProvider(new FTBInstanceProvider(m_settings));
+
qDebug() << "Loading Instances...";
- m_instances->loadList();
- connect(InstDirSetting.get(), SIGNAL(SettingChanged(const Setting &, QVariant)),
- m_instances.get(), SLOT(on_InstFolderChanged(const Setting &, QVariant)));
+ m_instances->loadList(true);
// and accounts
m_accounts.reset(new MojangAccountList(this));
@@ -1007,7 +1013,7 @@ void MultiMC::onExit()
{
if(m_instances)
{
- m_instances->saveGroupList();
+ // m_instances->saveGroupList();
}
ENV.destroy();
if(logFile)
diff --git a/application/MultiMC.h b/application/MultiMC.h
index 3b8751c1..02038578 100644
--- a/application/MultiMC.h
+++ b/application/MultiMC.h
@@ -7,6 +7,7 @@
#include <QIcon>
#include <QDateTime>
#include <updater/GoUpdate.h>
+class FolderInstanceProvider;
class GenericPageProvider;
class QFile;
@@ -91,6 +92,11 @@ public:
return m_instances;
}
+ FolderInstanceProvider * folderProvider()
+ {
+ return m_instanceFolder;
+ }
+
std::shared_ptr<IconList> icons()
{
return m_icons;
@@ -164,6 +170,7 @@ private:
std::shared_ptr<QTranslator> m_mmc_translator;
std::shared_ptr<SettingsObject> m_settings;
std::shared_ptr<InstanceList> m_instances;
+ FolderInstanceProvider * m_instanceFolder;
std::shared_ptr<IconList> m_icons;
std::shared_ptr<UpdateChecker> m_updateChecker;
std::shared_ptr<MojangAccountList> m_accounts;