summaryrefslogtreecommitdiff
path: root/src/instancemanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/instancemanager.cpp')
-rw-r--r--src/instancemanager.cpp707
1 files changed, 249 insertions, 458 deletions
diff --git a/src/instancemanager.cpp b/src/instancemanager.cpp
index 4ad099ed..c79c5254 100644
--- a/src/instancemanager.cpp
+++ b/src/instancemanager.cpp
@@ -38,257 +38,320 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
-InstanceManager::InstanceManager()
+Instance::Instance(QDir dir, bool portable, QString profileName) :
+ m_dir(std::move(dir)), m_portable(portable), m_plugin(nullptr),
+ m_profile(std::move(profileName))
{
- GlobalSettings::updateRegistryKey();
}
-InstanceManager &InstanceManager::instance()
+QString Instance::name() const
{
- static InstanceManager s_Instance;
- return s_Instance;
+ if (isPortable())
+ return QObject::tr("Portable");
+ else
+ return m_dir.dirName();
}
-void InstanceManager::overrideInstance(const QString& instanceName)
+QString Instance::gameName() const
{
- m_overrideInstanceName = instanceName;
- m_overrideInstance = true;
+ return m_gameName;
}
-void InstanceManager::overrideProfile(const QString& profileName)
+QString Instance::gameDirectory() const
{
- m_overrideProfileName = profileName;
- m_overrideProfile = true;
+ return m_gameDir;
}
-QString InstanceManager::currentInstance() const
+QDir Instance::directory() const
{
- if (m_overrideInstance)
- return m_overrideInstanceName;
- else
- return GlobalSettings::currentInstance();
+ return m_dir;
}
-void InstanceManager::clearCurrentInstance()
+MOBase::IPluginGame* Instance::gamePlugin() const
{
- setCurrentInstance("");
- m_Reset = true;
- m_overrideInstance = false;
+ return m_plugin;
}
-void InstanceManager::switchToInstance(const QString& instanceName)
+QString Instance::profileName() const
{
- setCurrentInstance(instanceName);
- ExitModOrganizer(Exit::Restart);
+ return m_profile;
}
-void InstanceManager::setCurrentInstance(const QString &name)
+QString Instance::iniPath() const
{
- GlobalSettings::setCurrentInstance(name);
+ return InstanceManager::iniPath(m_dir);
}
-bool InstanceManager::deleteLocalInstance(const QString& instanceId) const
+bool Instance::isPortable() const
{
- QString dir = instancePath(instanceId);
+ return m_portable;
+}
- const auto Recycle = QMessageBox::Save;
- const auto Delete = QMessageBox::Yes;
- const auto Cancel = QMessageBox::Cancel;
+Instance::SetupResults Instance::setup(PluginContainer& plugins)
+{
+ Settings s(iniPath());
- const auto r = MOBase::TaskDialog()
- .title(QObject::tr("Deleting instance folder"))
- .main(QObject::tr("This will delete the instance folder."))
- .content(dir)
- .icon(QMessageBox::Warning)
- .button({QObject::tr("Move the folder to the recycle bin"), Recycle})
- .button({QObject::tr("Delete the folder permanently"), Delete})
- .button({QObject::tr("Cancel"), Cancel})
- .exec();
+ if (s.iniStatus() != QSettings::NoError) {
+ log::error("can't read ini {}", iniPath());
+ return SetupResults::BadIni;
+ }
- std::wstring error;
+ if (m_gameName.isEmpty()) {
+ if (auto v=s.game().name())
+ m_gameName = *v;
+ }
- switch (r)
- {
- case Recycle:
- {
- if (MOBase::shellDelete(QStringList(dir), true)) {
- return true;
- }
+ if (m_gameDir.isEmpty()) {
+ if (auto v=s.game().directory())
+ m_gameDir = *v;
+ }
- const auto e = GetLastError();
- error = formatSystemMessage(e);
- log::warn("failed to move to trash '{}', {}", dir, error);
+ const auto r = getGamePlugin(plugins);
+ if (r != SetupResults::Ok) {
+ return r;
+ }
- break;
+ if (m_gameVariant.isEmpty()) {
+ if (auto v=s.game().edition()) {
+ m_gameVariant = *v;
}
+ }
- case Delete:
- {
- if (MOBase::shellDelete(QStringList(dir), false)) {
- return true;
- }
+ if (m_gameVariant.isEmpty() && m_plugin->gameVariants().size() > 1) {
+ return SetupResults::MissingVariant;
+ } else {
+ m_plugin->setGameVariant(m_gameVariant);
+ }
- const auto e = GetLastError();
- error = formatSystemMessage(e);
- log::warn("failed to delete '{}', {}", dir, error);
+ getProfile(s);
- break;
- }
+ s.game().setName(m_gameName);
+ s.game().setDirectory(m_gameDir);
+ s.game().setSelectedProfileName(m_profile);
- default:
- {
- return true;
- }
- }
+ if (!m_gameVariant.isEmpty())
+ s.game().setEdition(m_gameVariant);
- QMessageBox::critical(
- nullptr, QObject::tr("Error"), QObject::tr(
- "Could not delete instance folder \"%1\".\n\n%2")
- .arg(dir).arg(error),
- QMessageBox::Ok);
+ m_plugin->setGamePath(m_gameDir);
- return false;
+ return SetupResults::Ok;
}
-QString InstanceManager::manageInstances(const QStringList &instanceList) const
+void Instance::setGame(const QString& name, const QString& dir)
{
- SelectionDialog selection(QString("<h3>%1</h3><br>%2")
- .arg(QObject::tr("Select an instance to delete"))
- .arg(QObject::tr(
- "Deleting an instance will delete all the mods, downloads, profiles "
- "(including profile-specific saves) and anything in the overwrite "
- "folder.<br><br>"
- "Custom paths outside of the instance folder will not be deleted.")));
-
- for (const QString &instance : instanceList) {
- selection.addChoice(QIcon(":/MO/gui/multiply_red"), instance, "", instance);
- }
-
- if (selection.exec() == QDialog::Rejected) {
- return (chooseInstance(instanceNames()));
- }
- else {
- QString choice = selection.getChoiceData().toString();
- deleteLocalInstance(choice);
- }
+ m_gameName = name;
+ m_gameDir = dir;
+}
- return(manageInstances(instanceNames()));
+void Instance::setVariant(const QString& name)
+{
+ m_gameVariant = name;
}
-QString InstanceManager::queryInstanceName(const QStringList &instanceList) const
+Instance::SetupResults Instance::getGamePlugin(PluginContainer& plugins)
{
- QString instanceId;
- QString dialogText;
- while (instanceId.isEmpty()) {
- QInputDialog dialog;
+ if (!m_gameName.isEmpty() && !m_gameDir.isEmpty())
+ {
+ // normal case: both the name and dir are in the ini
- dialog.setWindowTitle(QObject::tr("Enter a Name for the new Instance"));
- dialog.setLabelText(QObject::tr("Enter a new name or select one from the suggested list: \n"
- "(This is just a name for the Instance and can be whatever you wish,\n"
- " the actual game selection will happen on the next screen regardless of chosen name)"));
- // would be neat if we could take the names from the game plugins but
- // the required initialization order requires the ini file to be
- // available *before* we load plugins
- dialog.setComboBoxItems({ "NewName", "Fallout 4", "SkyrimSE", "Skyrim", "SkyrimVR", "Fallout 3",
- "Fallout NV", "TTW", "FO4VR", "Oblivion", "Morrowind", "Enderal" });
- dialog.setComboBoxEditable(true);
+ // find the plugin by name
+ for (IPluginGame* game : plugins.plugins<IPluginGame>()) {
+ if (m_gameName.compare(game->gameName(), Qt::CaseInsensitive) == 0) {
+ // plugin found, check if the game directory is valid
- if (dialog.exec() == QDialog::Rejected) {
- throw MOBase::MyException(QObject::tr("Canceled"));
- }
- dialogText = dialog.textValue();
- instanceId = sanitizeInstanceName(dialogText);
- if (instanceId != dialogText) {
- if (QMessageBox::question( nullptr,
- QObject::tr("Invalid instance name"),
- QObject::tr("The instance name \"%1\" is invalid. Use the name \"%2\" instead?").arg(dialogText,instanceId),
- QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
- instanceId="";
- continue;
+ if (!game->looksValid(m_gameDir)) {
+ // the directory from the ini is not valid anymore
+ log::warn(
+ "game plugin {} says dir {} from ini {} is not valid",
+ game->gameName(), m_gameDir, iniPath());
+
+ // note that some plugins return true for isInstalled() if a path
+ // is found in the registry, but without actually checking if it's
+ // valid
+
+ if (game->isInstalled() && game->looksValid(game->gameDirectory())) {
+ // bad game directory but the plugin reports there's a valid one
+ // somewhere; take it instead
+ log::warn(
+ "game plugin {} found a game at {}, taking it",
+ game->gameName(), game->gameDirectory().absolutePath());
+
+ m_gameDir = game->gameDirectory().absolutePath();
+ } else {
+ // game seems to be gone completely
+ log::warn("game plugin {} found no game installation at all", game->gameName());
+ return SetupResults::GameGone;
+ }
}
+
+ m_plugin = game;
+ return SetupResults::Ok;
+ }
}
- bool alreadyExists=false;
- for (const QString &instance : instanceList) {
- if(instanceId==instance)
- alreadyExists=true;
+ log::warn("game plugin {} not found", m_gameName);
+ return SetupResults::PluginGone;
+ }
+ else if (m_gameName.isEmpty() && !m_gameDir.isEmpty())
+ {
+ // the name is missing, but there's a directory; find a plugin that can
+ // handle it
+
+ log::warn(
+ "game name is missing from ini {} but dir {} is available",
+ iniPath(), m_gameDir);
+
+ for (IPluginGame* game : plugins.plugins<IPluginGame>()) {
+ if (game->looksValid(m_gameDir)) {
+ // take it
+ log::warn("found plugin {} that can use dir {}", game->gameName(), m_gameDir);
+
+ m_plugin = game;
+ m_gameName = game->gameName();
+
+ return SetupResults::Ok;
+ }
}
- if(alreadyExists)
- {
- QMessageBox msgBox;
- msgBox.setText( QObject::tr("The instance \"%1\" already exists.").arg(instanceId) );
- msgBox.setInformativeText(QObject::tr("Please choose a different instance name, like: \"%1 1\" .").arg(instanceId));
- msgBox.exec();
- instanceId="";
+
+ log::error("no plugins can use dir {}", m_gameDir);
+ return SetupResults::GameGone;
+ }
+ else if (!m_gameName.isEmpty() && m_gameDir.isEmpty())
+ {
+ // dir is missing, find a plugin with the correct name and use the install
+ // dir it detected
+
+ log::warn(
+ "game dir is missing from ini {} but name {} is available",
+ iniPath(), m_gameName);
+
+ for (IPluginGame* game : plugins.plugins<IPluginGame>()) {
+ if (m_gameName.compare(game->gameName(), Qt::CaseInsensitive) == 0) {
+ // plugin found, use its detected installation dir
+
+ if (game->isInstalled()) {
+ log::warn(
+ "found plugin {} that matches name in ini {}, using auto detected "
+ "game dir {}",
+ game->gameName(), iniPath(), game->gameDirectory().absolutePath());
+
+ m_plugin = game;
+ m_gameDir = game->gameDirectory().absolutePath();
+
+ return SetupResults::Ok;
+ } else {
+ log::warn(
+ "found plugin {} that matches name in ini {}, but no game install "
+ "detected by plugin",
+ game->gameName(), iniPath());
+
+ return SetupResults::GameGone;
+ }
+ }
}
+
+ // plugin seems to be gone
+ log::error("no plugin matches name {}", m_gameName);
+ return SetupResults::PluginGone;
+ }
+ else
+ {
+ // can't do anything with these two missing
+ log::error("both game name and dir are missing from ini {}", iniPath());
+ return SetupResults::IniMissingGame;
}
- return instanceId;
}
-QString InstanceManager::chooseInstance(const QStringList &instanceList) const
+void Instance::getProfile(const Settings& s)
{
- if (portableInstallIsLocked()) {
- return QString();
+ if (!m_profile.isEmpty()) {
+ // there's already a profile set up, probably an override
+ return;
}
- enum class Special : uint8_t {
- NewInstance,
- Portable,
- Manage
- };
-
- SelectionDialog selection(
- QString("<h3>%1</h3><br>%2")
- .arg(QObject::tr("Choose Instance"))
- .arg(QObject::tr(
- "Each Instance is a full set of MO data files (mods, "
- "downloads, profiles, configuration, ...). You can use multiple "
- "instances for different games. Instances are stored in Appdata and can be accessed by all MO installations. "
- "If your MO folder is writable, you can also store a single instance locally (called "
- "a Portable install, and all the MO data files will be inside the installation folder).")),
- nullptr);
- selection.disableCancel();
- for (const QString &instance : instanceList) {
- selection.addChoice(instance, "", instance);
+ if (auto name=s.game().selectedProfileName()) {
+ // use last profile
+ m_profile = *name;
+ return;
}
- selection.addChoice(QIcon(":/MO/gui/add"), QObject::tr("New"),
- QObject::tr("Create a new instance."),
- static_cast<uint8_t>(Special::NewInstance));
+ // profile missing from ini, use the default
+ m_profile = QString::fromStdWString(AppConfig::defaultProfileName());
- if (QFileInfo(qApp->applicationDirPath()).isWritable()) {
- selection.addChoice(QIcon(":/MO/gui/package"), QObject::tr("Portable"),
- QObject::tr("Use MO folder for data."),
- static_cast<uint8_t>(Special::Portable));
- }
+ log::warn(
+ "no profile found in ini {}, using default '{}'",
+ iniPath(), m_profile);
+}
- selection.addChoice(QIcon(":/MO/gui/remove"), QObject::tr("Manage Instances"),
- QObject::tr("Delete an Instance."),
- static_cast<uint8_t>(Special::Manage));
- selection.setWindowFlags(selection.windowFlags() | Qt::WindowStaysOnTopHint);
+InstanceManager::InstanceManager()
+{
+ GlobalSettings::updateRegistryKey();
+}
+
+InstanceManager &InstanceManager::instance()
+{
+ static InstanceManager s_Instance;
+ return s_Instance;
+}
- if (selection.exec() == QDialog::Rejected) {
- log::debug("rejected");
- throw MOBase::MyException(QObject::tr("Canceled"));
+void InstanceManager::overrideInstance(const QString& instanceName)
+{
+ m_overrideInstanceName = instanceName;
+ m_overrideInstance = true;
+}
+
+void InstanceManager::overrideProfile(const QString& profileName)
+{
+ m_overrideProfileName = profileName;
+ m_overrideProfile = true;
+}
+
+std::optional<Instance> InstanceManager::currentInstance() const
+{
+ const QString profile = m_overrideProfile ? m_overrideProfileName : "";
+
+ if (portableInstallIsLocked()) {
+ // force portable instance
+ return Instance(QDir(portablePath()), true, profile);
}
- QVariant choice = selection.getChoiceData();
+ QString name;
- if (choice.type() == QVariant::String) {
- return choice.toString();
- } else {
- switch (static_cast<Special>(choice.value<uint8_t>())) {
- case Special::NewInstance: return queryInstanceName(instanceList);
- case Special::Portable: return QString();
- case Special::Manage: {
+ if (m_overrideInstance)
+ name = m_overrideInstanceName;
+ else
+ name = GlobalSettings::currentInstance();
- return(manageInstances(instanceNames()));
- }
- default: throw std::runtime_error("invalid selection");
+ if (name.isEmpty()) {
+ if (portableInstanceExists()) {
+ // use portable
+ return Instance(QDir(portablePath()), true, profile);
+ } else {
+ // no instance set
+ return {};
}
}
+
+ QString path = instancePath(name);
+ if (!QFileInfo::exists(path)) {
+ // the previously used instance doesn't exist anymore
+ return {};
+ }
+
+ return Instance(QDir(path), false, profile);
+}
+
+void InstanceManager::clearCurrentInstance()
+{
+ setCurrentInstance("");
+ m_overrideInstance = false;
+}
+
+void InstanceManager::setCurrentInstance(const QString &name)
+{
+ GlobalSettings::setCurrentInstance(name);
}
QString InstanceManager::instancePath(const QString& instanceName) const
@@ -302,6 +365,11 @@ QString InstanceManager::instancesPath() const
QStandardPaths::writableLocation(QStandardPaths::DataLocation));
}
+QString InstanceManager::iniPath(const QDir& instanceDir)
+{
+ return instanceDir.filePath(QString::fromStdWString(AppConfig::iniFileName()));
+}
+
std::vector<QDir> InstanceManager::instancePaths() const
{
const std::set<QString> ignore = {
@@ -362,287 +430,10 @@ bool InstanceManager::allowedToChangeInstance() const
return !portableInstallIsLocked();
}
-
-void InstanceManager::createDataPath(const QString &dataPath) const
-{
- if (!QDir(dataPath).exists()) {
- if (!QDir().mkpath(dataPath)) {
- throw MOBase::MyException(
- QObject::tr("failed to create %1").arg(dataPath));
- } else {
- QMessageBox::information(
- nullptr, QObject::tr("Data directory created"),
- QObject::tr("New data directory created at %1. If you don't want to "
- "store a lot of data there, reconfigure the storage "
- "directories via settings.").arg(dataPath));
- }
- }
-}
-
-
-QString InstanceManager::determineDataPath()
-{
- QString instanceId = currentInstance();
- if (portableInstallIsLocked())
- {
- instanceId.clear();
- }
- if (instanceId.isEmpty() && !m_Reset && (m_overrideInstance || portableInstanceExists()))
- {
- // startup, apparently using portable mode before
- return qApp->applicationDirPath();
- }
-
- QString dataPath = QDir::fromNativeSeparators(
- QStandardPaths::writableLocation(QStandardPaths::DataLocation)
- + "/" + instanceId);
-
-
- if (!m_overrideInstance && (instanceId.isEmpty() || !QFileInfo::exists(dataPath))) {
- instanceId = chooseInstance(instanceNames());
- setCurrentInstance(instanceId);
- if (!instanceId.isEmpty()) {
- dataPath = QDir::fromNativeSeparators(
- QStandardPaths::writableLocation(QStandardPaths::DataLocation)
- + "/" + instanceId);
- }
- }
-
- if (instanceId.isEmpty()) {
- return qApp->applicationDirPath();
- } else {
- createDataPath(dataPath);
-
- return dataPath;
- }
-}
-
-QString InstanceManager::determineProfile(const Settings &settings)
-{
- auto selectedProfileName = settings.game().selectedProfileName();
-
- if (m_overrideProfile) {
- log::debug("profile overwritten on command line");
- selectedProfileName = m_overrideProfileName;
- }
-
- if (!selectedProfileName) {
- log::debug("no configured profile");
- selectedProfileName = "Default";
- }
-
- return *selectedProfileName;
-}
-
-bool InstanceManager::determineGameEdition(
- Settings& settings, IPluginGame* game)
-{
- QString edition;
-
- if (auto v=settings.game().edition()) {
- edition = *v;
- } else {
- QStringList editions = game->gameVariants();
- if (editions.size() < 2) {
- edition = "";
- return true;
- }
-
- SelectionDialog selection(
- QObject::tr("Please select the game edition you have (MO can't "
- "start the game correctly if this is set "
- "incorrectly!)"),
- nullptr);
-
- selection.setWindowFlag(Qt::WindowStaysOnTopHint, true);
-
- int index = 0;
- for (const QString &edition : editions) {
- selection.addChoice(edition, "", index++);
- }
-
- if (selection.exec() == QDialog::Rejected) {
- return false;
- }
-
- edition = selection.getChoiceString();
- settings.game().setEdition(edition);
- }
-
- game->setGameVariant(edition);
-
- return true;
-}
-
-MOBase::IPluginGame *selectGame(
- Settings &settings, QDir const &gamePath, MOBase::IPluginGame *game)
-{
- settings.game().setName(game->gameName());
-
- QString gameDir = gamePath.absolutePath();
- game->setGamePath(gameDir);
-
- settings.game().setDirectory(gameDir);
-
- return game;
-}
-
-MOBase::IPluginGame* InstanceManager::determineCurrentGame(
- const QString& moPath, Settings& settings, const PluginContainer &plugins)
-{
- //Determine what game we are running where. Be very paranoid in case the
- //user has done something odd.
-
- //If the game name has been set up, try to use that.
- const auto gameName = settings.game().name();
- const bool gameConfigured = (gameName.has_value() && *gameName != "");
-
- if (gameConfigured) {
- MOBase::IPluginGame *game = plugins.managedGame(*gameName);
- if (game == nullptr) {
- reportError(
- QObject::tr("Plugin to handle %1 no longer installed. An antivirus might have deleted files.")
- .arg(*gameName));
-
- return nullptr;
- }
-
- auto gamePath = settings.game().directory();
- if (!gamePath || *gamePath == "") {
- gamePath = game->gameDirectory().absolutePath();
- }
-
- QDir gameDir(*gamePath);
- QFileInfo directoryInfo(gameDir.path());
-
- if (directoryInfo.isSymLink()) {
- reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. "
- "This setup is incompatible with MO2's VFS and will not run correctly.").arg(*gamePath));
- }
-
- if (game->looksValid(gameDir)) {
- return selectGame(settings, gameDir, game);
- }
- }
-
- //If we've made it this far and the instance is already configured for a game, something has gone wrong.
- //Tell the user about it.
- if (gameConfigured) {
- const auto gamePath = settings.game().directory();
-
- reportError(
- QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".")
- .arg(*gameName).arg(gamePath ? *gamePath : ""));
- }
-
- SelectionDialog selection(gameConfigured ?
- QObject::tr("Please select the installation of %1 to manage").arg(*gameName) :
- QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32));
-
- for (IPluginGame *game : plugins.plugins<IPluginGame>()) {
- //If a game is already configured, skip any plugins that are not for that game
- if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0)
- continue;
-
- //Only add games that are installed
- if (game->isInstalled()) {
- QString path = game->gameDirectory().absolutePath();
- selection.addChoice(game->gameIcon(), game->gameName(), path, QVariant::fromValue(game));
- }
- }
-
- selection.addChoice(QString("Browse..."), QString(), QVariant::fromValue(static_cast<IPluginGame *>(nullptr)));
-
- while (selection.exec() != QDialog::Rejected) {
- IPluginGame * game = selection.getChoiceData().value<IPluginGame *>();
- QString gamePath = selection.getChoiceDescription();
- QFileInfo directoryInfo(gamePath);
- if (directoryInfo.isSymLink()) {
- reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. "
- "This setup is incompatible with MO2's VFS and will not run correctly.").arg(gamePath));
- }
- if (game != nullptr) {
- return selectGame(settings, game->gameDirectory(), game);
- }
-
- gamePath = QFileDialog::getExistingDirectory(nullptr, gameConfigured ?
- QObject::tr("Please select the installation of %1 to manage").arg(*gameName) :
- QObject::tr("Please select the game to manage"),
- QString(), QFileDialog::ShowDirsOnly);
-
- if (!gamePath.isEmpty()) {
- QDir gameDir(gamePath);
- QFileInfo directoryInfo(gamePath);
- if (directoryInfo.isSymLink()) {
- reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. "
- "This setup is incompatible with MO2's VFS and will not run correctly.").arg(gamePath));
- }
- QList<IPluginGame *> possibleGames;
- for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
- //If a game is already configured, skip any plugins that are not for that game
- if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0)
- continue;
-
- //Only try plugins that look valid for this directory
- if (game->looksValid(gameDir)) {
- possibleGames.append(game);
- }
- }
-
- if (possibleGames.count() > 1) {
- SelectionDialog browseSelection(gameConfigured ?
- QObject::tr("Please select the installation of %1 to manage").arg(*gameName) :
- QObject::tr("Please select the game to manage"),
- nullptr, QSize(32, 32));
-
- for (IPluginGame *game : possibleGames) {
- browseSelection.addChoice(game->gameIcon(), game->gameName(), gamePath, QVariant::fromValue(game));
- }
-
- if (browseSelection.exec() == QDialog::Accepted) {
- return selectGame(settings, gameDir, browseSelection.getChoiceData().value<IPluginGame *>());
- } else {
- reportError(gameConfigured ?
- QObject::tr("Canceled finding %1 in \"%2\".").arg(*gameName).arg(gamePath) :
- QObject::tr("Canceled finding game in \"%1\".").arg(gamePath));
- }
- } else if(possibleGames.count() == 1) {
- return selectGame(settings, gameDir, possibleGames[0]);
- } else {
- if (gameConfigured) {
- reportError(
- QObject::tr("%1 not identified in \"%2\". The directory is required to contain the game binary.")
- .arg(*gameName).arg(gamePath));
- } else {
- QString supportedGames;
-
- for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
- supportedGames += "<li>" + game->gameName() + "</li>";
- }
-
- QString text = QObject::tr(
- "No game identified in \"%1\". The directory is required to "
- "contain the game binary.<br><br>"
- "<b>These are the games supported by Mod Organizer:</b>"
- "<ul>%2</ul>")
- .arg(gamePath)
- .arg(supportedGames);
-
- reportError(text);
- }
- }
- }
- }
-
- return nullptr;
-}
-
const MOBase::IPluginGame* InstanceManager::gamePluginForDirectory(
const QDir& instanceDir, const PluginContainer& plugins) const
{
- const QString ini =
- QDir(instanceDir).filePath(QString::fromStdWString(AppConfig::iniFileName()));
-
+ const QString ini = iniPath(instanceDir);
Settings s(ini);