summaryrefslogtreecommitdiff
path: root/src/instancemanagerdialog.cpp
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2020-11-06 13:56:04 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2020-11-07 20:16:25 -0500
commitdc2ada2a4249917f538938298deb193ed1dd6bb9 (patch)
tree9f5564aae12004e4a55ed63f1ce294c0c75d7816 /src/instancemanagerdialog.cpp
parentb7cb63ddb1e2b263d5e485c97faea527c7c0af44 (diff)
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
Diffstat (limited to 'src/instancemanagerdialog.cpp')
-rw-r--r--src/instancemanagerdialog.cpp347
1 files changed, 41 insertions, 306 deletions
diff --git a/src/instancemanagerdialog.cpp b/src/instancemanagerdialog.cpp
index c2108f9d..c199fa7b 100644
--- a/src/instancemanagerdialog.cpp
+++ b/src/instancemanagerdialog.cpp
@@ -13,292 +13,19 @@
using namespace MOBase;
-class InstanceInfo
-{
-public:
- struct Object
- {
- QString path;
- bool mandatoryDelete;
-
- Object(QString p, bool d=false)
- : path(std::move(p)), mandatoryDelete(d)
- {
- }
-
- bool operator<(const Object& o) const
- {
- if (mandatoryDelete && !o.mandatoryDelete) {
- return true;
- } else if (!mandatoryDelete && o.mandatoryDelete) {
- return false;
- }
-
- return false;
- }
- };
-
-
- InstanceInfo(QDir dir, bool isPortable)
- : m_portable(isPortable)
- {
- setDir(dir);
- }
-
- void setDir(const QDir& dir)
- {
- m_dir = dir;
- m_settings.reset(new Settings(InstanceManager::singleton().iniPath(dir)));
- }
-
- QString name() const
- {
- if (m_portable) {
- return QObject::tr("Portable");
- } else {
- return m_dir.dirName();
- }
- }
-
- QString gameName() const
- {
- if (auto n=m_settings->game().name()) {
- if (auto e=m_settings->game().edition()) {
- if (!e->isEmpty()) {
- return *n + " (" + *e + ")";
- }
- }
-
- return *n;
- } else {
- return {};
- }
- }
-
- QString gamePath() const
- {
- if (auto n=m_settings->game().directory()) {
- return QDir::toNativeSeparators(*n);
- } else {
- return {};
- }
- }
-
- QString location() const
- {
- return QDir::toNativeSeparators(m_dir.path());
- }
-
- QString baseDirectory() const
- {
- return QDir::toNativeSeparators(m_settings->paths().base());
- }
-
- QString iniFile() const
- {
- return InstanceManager::singleton().iniPath(m_dir);
- }
-
- QIcon icon(const PluginContainer& plugins) const
- {
- const auto* game = InstanceManager::singleton().gamePluginForDirectory(
- m_dir, plugins);
-
- if (game)
- return game->gameIcon();
-
- QPixmap empty(32, 32);
- empty.fill(QColor(0, 0, 0, 0));
- return QIcon(empty);
- }
-
- bool isPortable() const
- {
- return m_portable;
- }
-
- bool isActive() const
- {
- auto& m = InstanceManager::singleton();
-
- if (auto i=m.currentInstance())
- {
- if (m_portable) {
- return i->isPortable();
- } else {
- return (i->name() == name());
- }
- }
-
- return false;
- }
-
- // returns a list of files and folders that must be deleted when deleting
- // this instance
- //
- std::vector<Object> 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 = [](auto 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 = [&](auto root, auto dir) {
- return canonicalDir(dir).startsWith(canonicalDir(root));
- };
-
- // whether the given file is contained in the root
- auto fileInRoot = [&](auto root, auto file) {
- return canonicalFile(file).startsWith(canonicalDir(root));
- };
+QIcon instanceIcon(const PluginContainer& pc, const Instance& i)
+{
+ const auto* game = InstanceManager::singleton()
+ .gamePluginForDirectory(i.directory(), pc);
+ if (game)
+ return game->gameIcon();
-
- const auto loc = location();
- const auto base = m_settings->paths().base();
-
-
- // directories that might contain the individual files and directories
- // set in the path settings
- std::vector<Object> roots;
-
- // a portable instance has its location in the installation directory,
- // don't delete that
- if (!isPortable()) {
- if (QDir(loc).exists()) {
- roots.push_back({loc, true});
- }
- }
-
- // the base directory is the location directory by default, don't add it
- // if it's the same
- if (canonicalDir(base) != canonicalDir(loc)) {
- if (QDir(base).exists()) {
- roots.push_back({base, false});
- }
- }
-
-
- // all the directories that are part of an instance; none of them are
- // mandatory for deletion
- const std::vector<Object> dirs = {
- m_settings->paths().downloads(),
- m_settings->paths().mods(),
- m_settings->paths().cache(),
- m_settings->paths().profiles(),
- m_settings->paths().overwrite(),
- m_dir.filePath(QString::fromStdWString(AppConfig::dumpsDir())),
- m_dir.filePath(QString::fromStdWString(AppConfig::logPath())),
- };
-
- // all the files that are part of an instance
- const std::vector<Object> files = {
- {iniFile(), true}, // the ini file must be deleted
- };
-
-
- // this will contain the root directories, plus all the individual
- // directories that are not inside these roots
- std::vector<Object> cleanDirs;
-
- for (const auto& f : dirs) {
- bool inRoots = false;
-
- for (const auto& root : roots) {
- if (dirInRoot(root.path, f.path)) {
- inRoots = true;
- break;
- }
- }
-
- if (!inRoots) {
- // not in roots, this is a path that was changed by the user; make
- // sure it exists
- if (QDir(f.path).exists()) {
- cleanDirs.push_back({prettyDir(f.path), f.mandatoryDelete});
- }
- }
- }
-
- // prepending the roots
- for (auto itor=roots.rbegin(); itor!=roots.rend(); ++itor) {
- cleanDirs.insert(
- cleanDirs.begin(),
- {prettyDir(itor->path), itor->mandatoryDelete});
- }
-
-
-
- // this will contain the individual files that are not inside the roots;
- // not that this only contains the INI file for now, so most of this is
- // useless
- std::vector<Object> cleanFiles;
-
- for (const auto& f : files) {
- bool inRoots = false;
-
- for (const auto& root : roots) {
- if (fileInRoot(root.path, f.path)) {
- inRoots = true;
- break;
- }
- }
-
- if (!inRoots) {
- // not in roots, this is a path that was changed by the user; make
- // sure it exists
- if (QFileInfo(f.path).exists()) {
- cleanFiles.push_back({prettyFile(f.path), f.mandatoryDelete});
- }
- }
- }
-
-
- // contains all the directories and files to be deleted
- std::vector<Object> all;
- all.insert(all.end(), cleanDirs.begin(), cleanDirs.end());
- all.insert(all.end(), cleanFiles.begin(), cleanFiles.end());
-
- // mandatory on top
- std::stable_sort(all.begin(), all.end());
-
- return all;
- }
-
-private:
- const bool m_portable;
- QDir m_dir;
- std::unique_ptr<Settings> m_settings;
-};
+ QPixmap empty(32, 32);
+ empty.fill(QColor(0, 0, 0, 0));
+ return QIcon(empty);
+}
InstanceManagerDialog::~InstanceManagerDialog() = default;
@@ -352,7 +79,7 @@ void InstanceManagerDialog::updateInstances()
m_instances.clear();
for (auto&& d : m.globalInstancePaths()) {
- m_instances.push_back(std::make_unique<InstanceInfo>(d, false));
+ m_instances.push_back(std::make_unique<Instance>(d, false));
}
// sort first, prepend portable after so it's always on top
@@ -363,7 +90,12 @@ void InstanceManagerDialog::updateInstances()
if (m.portableInstanceExists()) {
m_instances.insert(
m_instances.begin(),
- std::make_unique<InstanceInfo>(m.portablePath(), true));
+ std::make_unique<Instance>(m.portablePath(), true));
+ }
+
+ // read all inis, ignore errors
+ for (auto&& i : m_instances) {
+ i->readFromIni();
}
}
@@ -381,7 +113,7 @@ void InstanceManagerDialog::updateList()
const auto& ii = *m_instances[i];
auto* item = new QStandardItem(ii.name());
- item->setIcon(ii.icon(m_pc));
+ item->setIcon(instanceIcon(m_pc, ii));
m_model->appendRow(item);
@@ -568,9 +300,9 @@ void InstanceManagerDialog::rename()
return;
}
- const QString src = i->location();
+ const QString src = i->directory();
const QString dest = QDir::toNativeSeparators(
- QFileInfo(i->location()).dir().path() + "/" + newName);
+ QFileInfo(src).dir().path() + "/" + newName);
const auto r = shell::Rename(src, dest, false);
if (!r) {
@@ -582,15 +314,19 @@ void InstanceManagerDialog::rename()
return;
}
+ auto newInstance = std::make_unique<Instance>(dest, false);
+ i = newInstance.get();
+
m_model->item(selIndex)->setText(newName);
- i->setDir(dest);
+ m_instances[selIndex] = std::move(newInstance);
+
fillData(*i);
}
void InstanceManagerDialog::exploreLocation()
{
if (const auto* i=singleSelection()) {
- shell::Explore(i->location());
+ shell::Explore(i->directory());
}
}
@@ -604,14 +340,14 @@ void InstanceManagerDialog::exploreBaseDirectory()
void InstanceManagerDialog::exploreGame()
{
if (const auto* i=singleSelection()) {
- shell::Explore(i->gamePath());
+ shell::Explore(i->gameDirectory());
}
}
void InstanceManagerDialog::openINI()
{
if (const auto* i=singleSelection()) {
- shell::Open(i->iniFile());
+ shell::Open(i->iniPath());
}
}
@@ -707,6 +443,15 @@ void InstanceManagerDialog::setRestartOnSelect(bool b)
bool InstanceManagerDialog::doDelete(const QStringList& files, bool recycle)
{
+ // logging
+ for (auto&& f : files) {
+ if (recycle) {
+ log::info("will recycle {}", f);
+ } else {
+ log::info("will delete {}", f);
+ }
+ }
+
if (MOBase::shellDelete(files, recycle, this)) {
return true;
}
@@ -771,17 +516,7 @@ std::size_t InstanceManagerDialog::singleSelectionIndex() const
return static_cast<std::size_t>(sel.indexes()[0].row());
}
-InstanceInfo* InstanceManagerDialog::singleSelection()
-{
- const auto i = singleSelectionIndex();
- if (i == NoSelection) {
- return nullptr;
- }
-
- return m_instances[i].get();
-}
-
-const InstanceInfo* InstanceManagerDialog::singleSelection() const
+const Instance* InstanceManagerDialog::singleSelection() const
{
const auto i = singleSelectionIndex();
if (i == NoSelection) {
@@ -791,13 +526,13 @@ const InstanceInfo* InstanceManagerDialog::singleSelection() const
return m_instances[i].get();
}
-void InstanceManagerDialog::fillData(const InstanceInfo& ii)
+void InstanceManagerDialog::fillData(const Instance& ii)
{
ui->name->setText(ii.name());
- ui->location->setText(ii.location());
+ ui->location->setText(ii.directory());
ui->baseDirectory->setText(ii.baseDirectory());
ui->gameName->setText(ii.gameName());
- ui->gameDir->setText(ii.gamePath());
+ ui->gameDir->setText(ii.gameDirectory());
setButtonsEnabled(true);
const auto& m = InstanceManager::singleton();