From dc2ada2a4249917f538938298deb193ed1dd6bb9 Mon Sep 17 00:00:00 2001
From: isanae <14251494+isanae@users.noreply.github.com>
Date: Fri, 6 Nov 2020 13:56:04 -0500
Subject: added ... to the "Delete Instance" button to make it less scary
merged InstanceInfo into Instance, most of it was redundant added logging
before deleting instance added Instance::readFromIni(), contains stuff that
used to be in setup(), used by instance dialog replaced QDir with QString in
a few places, I hate QDir
---
src/instancemanager.cpp | 278 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 248 insertions(+), 30 deletions(-)
(limited to 'src/instancemanager.cpp')
diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp
index e7c2a611..fbafc6e8 100644
--- a/src/instancemanager.cpp
+++ b/src/instancemanager.cpp
@@ -38,7 +38,7 @@ along with Mod Organizer. If not, see .
using namespace MOBase;
-Instance::Instance(QDir dir, bool portable, QString profileName) :
+Instance::Instance(QString dir, bool portable, QString profileName) :
m_dir(std::move(dir)), m_portable(portable), m_plugin(nullptr),
m_profile(std::move(profileName))
{
@@ -49,7 +49,7 @@ QString Instance::name() const
if (isPortable())
return QObject::tr("Portable");
else
- return m_dir.dirName();
+ return QDir(m_dir).dirName();
}
QString Instance::gameName() const
@@ -62,11 +62,16 @@ QString Instance::gameDirectory() const
return m_gameDir;
}
-QDir Instance::directory() const
+QString Instance::directory() const
{
return m_dir;
}
+QString Instance::baseDirectory() const
+{
+ return m_baseDir;
+}
+
MOBase::IPluginGame* Instance::gamePlugin() const
{
return m_plugin;
@@ -87,13 +92,29 @@ bool Instance::isPortable() const
return m_portable;
}
-Instance::SetupResults Instance::setup(PluginContainer& plugins)
+bool Instance::isActive() const
+{
+ auto& m = InstanceManager::singleton();
+
+ if (auto i=m.currentInstance())
+ {
+ if (m_portable) {
+ return i->isPortable();
+ } else {
+ return (i->name() == name());
+ }
+ }
+
+ return false;
+}
+
+bool Instance::readFromIni()
{
Settings s(iniPath());
if (s.iniStatus() != QSettings::NoError) {
log::error("can't read ini {}", iniPath());
- return SetupResults::BadIni;
+ return false;
}
// game name and directory are from ini unless overridden by setGame()
@@ -107,27 +128,61 @@ Instance::SetupResults Instance::setup(PluginContainer& plugins)
m_gameDir = *v;
}
- // getting game plugin
- const auto r = getGamePlugin(plugins);
- if (r != SetupResults::Ok) {
- return r;
- }
-
- // getting game variant, error if it's missing and required by the plugin
if (m_gameVariant.isEmpty()) {
if (auto v=s.game().edition()) {
m_gameVariant = *v;
}
}
+ if (m_baseDir.isEmpty()) {
+ m_baseDir = s.paths().base();
+ }
+
+ // figuring out profile from ini if it's missing
+ getProfile(s);
+
+ return true;
+}
+
+Instance::SetupResults Instance::setup(PluginContainer& plugins)
+{
+ // read initial values from the ini
+ if (!readFromIni()) {
+ return SetupResults::BadIni;
+ }
+
+ // getting game plugin
+ const auto r = getGamePlugin(plugins);
+ if (r != SetupResults::Ok) {
+ return r;
+ }
+
+ // error if the variant missing and required by the plugin
if (m_gameVariant.isEmpty() && m_plugin->gameVariants().size() > 1) {
return SetupResults::MissingVariant;
} else {
m_plugin->setGameVariant(m_gameVariant);
}
- // figuring out profile from ini if it's missing
- getProfile(s);
+ // update the ini in case anything was missing
+ updateIni();
+
+ // the game directory may be different than what the plugin detected, the user
+ // can change it in the settings and might have multiple versions of the game
+ // installed
+ m_plugin->setGamePath(m_gameDir);
+
+ return SetupResults::Ok;
+}
+
+void Instance::updateIni()
+{
+ Settings s(iniPath());
+
+ if (s.iniStatus() != QSettings::NoError) {
+ log::error("can't open ini {}", iniPath());
+ return;
+ }
// updating the settings since some of these values might have been missing
s.game().setName(m_gameName);
@@ -138,13 +193,6 @@ Instance::SetupResults Instance::setup(PluginContainer& plugins)
// don't write a variant to the ini if the plugin doesn't require one
s.game().setEdition(m_gameVariant);
}
-
- // the game directory may be different than what the plugin detected, the user
- // can change it in the settings and might have multiple versions of the game
- // installed
- m_plugin->setGamePath(m_gameDir);
-
- return SetupResults::Ok;
}
void Instance::setGame(const QString& name, const QString& dir)
@@ -272,7 +320,6 @@ Instance::SetupResults Instance::getGamePlugin(PluginContainer& plugins)
}
}
-
void Instance::getProfile(const Settings& s)
{
if (!m_profile.isEmpty()) {
@@ -294,6 +341,176 @@ void Instance::getProfile(const Settings& s)
iniPath(), m_profile);
}
+// returns a list of files and folders that must be deleted when deleting
+// this instance
+//
+std::vector Instance::objectsForDeletion() const
+{
+ // native separators and ending slash
+ auto prettyDir = [](auto s) {
+ if (!s.endsWith("/") || !s.endsWith("\\")) {
+ s += "/";
+ }
+
+ return QDir::toNativeSeparators(s);
+ };
+
+ // native separators
+ auto prettyFile = [](auto s) {
+ return QDir::toNativeSeparators(s);
+ };
+
+
+ // lowercase, native separators and ending slash
+ auto canonicalDir = [](QString s) {
+ s = s.toLower();
+
+ if (!s.endsWith("/") || !s.endsWith("\\")) {
+ s += "/";
+ }
+
+ return QDir::toNativeSeparators(s);
+ };
+
+ // lower and native separators
+ auto canonicalFile = [](auto s) {
+ return QDir::toNativeSeparators(s.toLower());
+ };
+
+
+
+ // whether the given directory is contained in the root
+ auto dirInRoot = [&](const QString& root, const QString& dir) {
+ return canonicalDir(dir).startsWith(canonicalDir(root));
+ };
+
+ // whether the given file is contained in the root
+ auto fileInRoot = [&](const QString& root, const QString& file) {
+ return canonicalFile(file).startsWith(canonicalDir(root));
+ };
+
+
+ Settings settings(iniPath());
+
+ if (settings.iniStatus() != QSettings::NoError) {
+ log::error("can't read ini {}", iniPath());
+ return {};
+ }
+
+
+
+ const QString loc = directory();
+ const QString base = settings.paths().base();
+
+
+ // directories that might contain the individual files and directories
+ // set in the path settings
+ std::vector