From d66fdcd4cc6913508d2987c14cd9fc4d6760b8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 3 Oct 2016 00:55:54 +0200 Subject: NOISSUE Granular instance reload --- application/InstanceWindow.cpp | 39 +++++-- application/InstanceWindow.h | 2 + application/MainWindow.cpp | 235 ++++++----------------------------------- application/MainWindow.h | 5 +- application/MultiMC.cpp | 14 ++- application/MultiMC.h | 7 ++ 6 files changed, 87 insertions(+), 215 deletions(-) (limited to 'application') 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 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 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 +#include 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(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(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(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 #include "InstanceList.h" +#include "FolderInstanceProvider.h" +#include "minecraft/ftb/FTBInstanceProvider.h" + #include #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 #include #include +class FolderInstanceProvider; class GenericPageProvider; class QFile; @@ -91,6 +92,11 @@ public: return m_instances; } + FolderInstanceProvider * folderProvider() + { + return m_instanceFolder; + } + std::shared_ptr icons() { return m_icons; @@ -164,6 +170,7 @@ private: std::shared_ptr m_mmc_translator; std::shared_ptr m_settings; std::shared_ptr m_instances; + FolderInstanceProvider * m_instanceFolder; std::shared_ptr m_icons; std::shared_ptr m_updateChecker; std::shared_ptr m_accounts; -- cgit v1.2.3