summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/logic/BaseInstance.cpp9
-rw-r--r--api/logic/BaseInstance.h4
-rw-r--r--api/logic/BaseInstanceProvider.h1
-rw-r--r--api/logic/FolderInstanceProvider.cpp30
-rw-r--r--api/logic/FolderInstanceProvider.h22
-rw-r--r--api/logic/InstanceList.cpp20
-rw-r--r--api/logic/InstanceList.h3
-rw-r--r--application/MainWindow.cpp2
-rw-r--r--application/dialogs/NewInstanceDialog.cpp32
9 files changed, 77 insertions, 46 deletions
diff --git a/api/logic/BaseInstance.cpp b/api/logic/BaseInstance.cpp
index c81b70c6..f07b2bd0 100644
--- a/api/logic/BaseInstance.cpp
+++ b/api/logic/BaseInstance.cpp
@@ -99,16 +99,11 @@ void BaseInstance::iconUpdated(QString key)
void BaseInstance::invalidate()
{
changeStatus(Status::Gone);
+ m_group = QString();
+ emit groupChanged();
qDebug() << "Instance" << id() << "has been invalidated.";
}
-void BaseInstance::nuke()
-{
- changeStatus(Status::Gone);
- qDebug() << "Instance" << id() << "has been deleted by MultiMC.";
- FS::deletePath(instanceRoot());
-}
-
void BaseInstance::changeStatus(BaseInstance::Status newStatus)
{
Status status = currentStatus();
diff --git a/api/logic/BaseInstance.h b/api/logic/BaseInstance.h
index a7004701..d9713a58 100644
--- a/api/logic/BaseInstance.h
+++ b/api/logic/BaseInstance.h
@@ -72,10 +72,6 @@ public:
virtual void init() = 0;
virtual void saveNow() = 0;
- /// nuke thoroughly - deletes the instance contents, notifies the list/model which is
- /// responsible of cleaning up the husk
- void nuke();
-
/***
* the instance has been invalidated - it is no longer tracked by MultiMC for some reason,
* but it has not necessarily been deleted.
diff --git a/api/logic/BaseInstanceProvider.h b/api/logic/BaseInstanceProvider.h
index 1eee0e4f..095d4dab 100644
--- a/api/logic/BaseInstanceProvider.h
+++ b/api/logic/BaseInstanceProvider.h
@@ -8,6 +8,7 @@
#include "multimc_logic_export.h"
using InstanceId = QString;
+using GroupId = QString;
using InstanceLocator = std::pair<InstancePtr, int>;
enum class InstCreateError
diff --git a/api/logic/FolderInstanceProvider.cpp b/api/logic/FolderInstanceProvider.cpp
index 4f89e5b7..4a20127a 100644
--- a/api/logic/FolderInstanceProvider.cpp
+++ b/api/logic/FolderInstanceProvider.cpp
@@ -48,6 +48,7 @@ FolderInstanceProvider::FolderInstanceProvider(SettingsObjectPtr settings, const
QList< InstanceId > FolderInstanceProvider::discoverInstances()
{
+ qDebug() << "Discovering instances in" << m_instDir;
QList<InstanceId> out;
QDirIterator iter(m_instDir, QDir::Dirs | QDir::NoDot | QDir::NoDotDot | QDir::Readable | QDir::Hidden, QDirIterator::FollowSymlinks);
while (iter.hasNext())
@@ -71,6 +72,8 @@ QList< InstanceId > FolderInstanceProvider::discoverInstances()
out.append(id);
qDebug() << "Found instance ID" << id;
}
+ instanceSet = out.toSet();
+ m_instancesProbed = true;
return out;
}
@@ -115,6 +118,12 @@ InstancePtr FolderInstanceProvider::loadInstance(const InstanceId& id)
void FolderInstanceProvider::saveGroupList()
{
+ qDebug() << "Will save group list now.";
+ if(!m_instancesProbed)
+ {
+ qDebug() << "Group saving prevented because we don't know the full list of instances yet.";
+ return;
+ }
WatchLock foo(m_watcher, m_instDir);
QString groupFileName = m_instDir + "/instgroups.json";
QMap<QString, QSet<QString>> reverseGroupMap;
@@ -124,6 +133,11 @@ void FolderInstanceProvider::saveGroupList()
QString group = iter.value();
if (group.isEmpty())
continue;
+ if(!instanceSet.contains(id))
+ {
+ qDebug() << "Skipping saving missing instance" << id << "to groups list.";
+ continue;
+ }
if (!reverseGroupMap.count(group))
{
@@ -159,6 +173,7 @@ void FolderInstanceProvider::saveGroupList()
try
{
FS::write(groupFileName, doc.toJson());
+ qDebug() << "Group list saved.";
}
catch (const FS::FileSystemException &e)
{
@@ -168,6 +183,7 @@ void FolderInstanceProvider::saveGroupList()
void FolderInstanceProvider::loadGroupList()
{
+ qDebug() << "Will load group list now.";
QSet<QString> groupSet;
QString groupFileName = m_instDir + "/instgroups.json";
@@ -262,6 +278,7 @@ void FolderInstanceProvider::loadGroupList()
}
m_groupsLoaded = true;
emit groupsChanged(groupSet);
+ qDebug() << "Group list loaded.";
}
void FolderInstanceProvider::groupChanged()
@@ -309,6 +326,7 @@ static void clamp(T& current, T min, T max)
}
}
+namespace {
// List of numbers from min to max. Next is exponent times bigger than previous.
class ExponentialSeries
{
@@ -335,12 +353,8 @@ public:
unsigned m_max;
unsigned m_exponent;
};
+}
-/*
- * WHY: the whole reason why this uses an exponential backoff retry scheme is antivirus on Windows.
- * Basically, it starts messing things up while MultiMC is extracting/creating instances
- * and causes that horrible failure that is NTFS to lock files in place because they are open.
- */
class FolderInstanceStaging : public Task
{
Q_OBJECT
@@ -405,6 +419,11 @@ private slots:
}
private:
+ /*
+ * WHY: the whole reason why this uses an exponential backoff retry scheme is antivirus on Windows.
+ * Basically, it starts messing things up while MultiMC is extracting/creating instances
+ * and causes that horrible failure that is NTFS to lock files in place because they are open.
+ */
ExponentialSeries backoff;
QString m_stagingPath;
FolderInstanceProvider * m_parent;
@@ -449,6 +468,7 @@ bool FolderInstanceProvider::commitStagedInstance(const QString& path, const QSt
return false;
}
groupMap[instID] = groupName;
+ instanceSet.insert(instID);
emit groupsChanged({groupName});
emit instancesChanged();
}
diff --git a/api/logic/FolderInstanceProvider.h b/api/logic/FolderInstanceProvider.h
index fc14ba7a..e1f2ad64 100644
--- a/api/logic/FolderInstanceProvider.h
+++ b/api/logic/FolderInstanceProvider.h
@@ -19,24 +19,6 @@ public:
/// used by InstanceList to (re)load an instance with the given @id.
InstancePtr loadInstance(const InstanceId& id) override;
-
- /*
- // create instance in this provider
- Task * creationTask(BaseVersionPtr version, const QString &instName, const QString &instGroup, const QString &instIcon);
-
- // copy instance to this provider
- Task * copyTask(const InstancePtr &oldInstance, const QString& instName, const QString& instGroup, const QString& instIcon, bool copySaves);
-
- // import zipped instance into this provider
- Task * zipImportTask(const QUrl sourceUrl, const QString &instName, const QString &instGroup, const QString &instIcon);
-
- //create FtbInstance
- Task * ftbCreationTask(FtbPackDownloader *downloader, const QString &instName, const QString &instGroup, const QString &instIcon);
-
- // migrate an instance to the current format
- 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);
@@ -70,6 +52,8 @@ private: /* methods */
private: /* data */
QString m_instDir;
QFileSystemWatcher * m_watcher;
- QMap<QString, QString> groupMap;
+ QMap<InstanceId, GroupId> groupMap;
+ QSet<InstanceId> instanceSet;
bool m_groupsLoaded = false;
+ bool m_instancesProbed = false;
};
diff --git a/api/logic/InstanceList.cpp b/api/logic/InstanceList.cpp
index c7a22b08..9dd08b5b 100644
--- a/api/logic/InstanceList.cpp
+++ b/api/logic/InstanceList.cpp
@@ -25,6 +25,7 @@
#include "BaseInstance.h"
#include "FolderInstanceProvider.h"
+#include "FileSystem.h"
InstanceList::InstanceList(QObject *parent)
: QAbstractListModel(parent)
@@ -118,6 +119,25 @@ void InstanceList::deleteGroup(const QString& name)
}
}
+void InstanceList::deleteInstance(const InstanceId& id)
+{
+ auto inst = getInstanceById(id);
+ if(!inst)
+ {
+ qDebug() << "Cannot delete instance" << id << " No such instance is present.";
+ return;
+ }
+
+ qDebug() << "Will delete instance" << id;
+ if(!FS::deletePath(inst->instanceRoot()))
+ {
+ qWarning() << "Deletion of instance" << id << "has not been completely successful ...";
+ return;
+ }
+
+ qDebug() << "Instance" << id << "has been deleted by MultiMC.";
+}
+
static QMap<InstanceId, InstanceLocator> getIdMapping(const QList<InstancePtr> &list)
{
QMap<InstanceId, InstanceLocator> out;
diff --git a/api/logic/InstanceList.h b/api/logic/InstanceList.h
index 7fe5ea34..14d5280d 100644
--- a/api/logic/InstanceList.h
+++ b/api/logic/InstanceList.h
@@ -80,7 +80,8 @@ public:
QModelIndex getInstanceIndexById(const QString &id) const;
QStringList getGroups();
- void deleteGroup(const QString & name);
+ void deleteGroup(const GroupId & name);
+ void deleteInstance(const InstanceId & id);
signals:
void dataIsInvalid();
diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp
index acb8e92b..cf9e5099 100644
--- a/application/MainWindow.cpp
+++ b/application/MainWindow.cpp
@@ -1617,7 +1617,7 @@ void MainWindow::on_actionDeleteInstance_triggered()
)->exec();
if (response == QMessageBox::Yes)
{
- m_selectedInstance->nuke();
+ MMC->instances()->deleteInstance(m_selectedInstance->id());
}
}
diff --git a/application/dialogs/NewInstanceDialog.cpp b/application/dialogs/NewInstanceDialog.cpp
index c68d6537..46e6ca34 100644
--- a/application/dialogs/NewInstanceDialog.cpp
+++ b/application/dialogs/NewInstanceDialog.cpp
@@ -64,8 +64,6 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
ui->groupBox->setCurrentIndex(index);
ui->groupBox->lineEdit()->setPlaceholderText(tr("No group"));
- m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- m_buttons->button(QDialogButtonBox::Ok)->setDefault(true);
m_container = new PageContainer(this);
@@ -73,8 +71,25 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
m_container->layout()->setContentsMargins(0, 0, 0, 0);
ui->verticalLayout->insertWidget(2, m_container);
+ m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
m_container->addButtons(m_buttons);
- m_buttons->setFocus();
+
+ // Bonk Qt over its stupid head and make sure it understands which button is the default one...
+ // See: https://stackoverflow.com/questions/24556831/qbuttonbox-set-default-button
+ auto OkButton = m_buttons->button(QDialogButtonBox::Ok);
+ OkButton->setDefault(true);
+ OkButton->setAutoDefault(true);
+ connect(OkButton, &QPushButton::clicked, this, &NewInstanceDialog::accept);
+
+ auto CancelButton = m_buttons->button(QDialogButtonBox::Cancel);
+ CancelButton->setDefault(false);
+ CancelButton->setAutoDefault(false);
+ connect(CancelButton, &QPushButton::clicked, this, &NewInstanceDialog::reject);
+
+ auto HelpButton = m_buttons->button(QDialogButtonBox::Help);
+ HelpButton->setDefault(false);
+ HelpButton->setAutoDefault(false);
+ connect(HelpButton, &QPushButton::clicked, m_container, &PageContainer::help);
if(!url.isEmpty())
{
@@ -82,14 +97,9 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString
importPage->setUrl(url);
}
- connect(m_buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &NewInstanceDialog::accept);
- connect(m_buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &NewInstanceDialog::reject);
- connect(m_buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, m_container, &PageContainer::help);
-
updateDialogState();
restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("NewInstanceGeometry").toByteArray()));
-
}
void NewInstanceDialog::reject()
@@ -160,7 +170,11 @@ InstanceTask * NewInstanceDialog::extractTask()
void NewInstanceDialog::updateDialogState()
{
auto allowOK = creationTask && !instName().isEmpty();
- m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
+ auto OkButton = m_buttons->button(QDialogButtonBox::Ok);
+ if(OkButton->isEnabled() != allowOK)
+ {
+ OkButton->setEnabled(allowOK);
+ }
}
QString NewInstanceDialog::instName() const