diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2020-07-24 15:29:28 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2020-11-03 11:39:05 -0500 |
| commit | 4ac8ab98563e223075c1c93852d4112ab6e4579c (patch) | |
| tree | 586bfd3541c7831fc4923397e6eea52667dfdd31 | |
| parent | 7b02c77a3961d859aae270922db26bbc999677cb (diff) | |
don't skip paths for portable instance, what am I doing
implemented actual creation
removed mentions of %BASE_DIR% everywhere, use constant and functions from PathSettings
| -rw-r--r-- | modorganizer.natvis | 97 | ||||
| -rw-r--r-- | src/createinstancedialog.cpp | 379 | ||||
| -rw-r--r-- | src/createinstancedialog.h | 20 | ||||
| -rw-r--r-- | src/createinstancedialog.ui | 16 | ||||
| -rw-r--r-- | src/instancemanager.h | 3 | ||||
| -rw-r--r-- | src/settings.cpp | 18 | ||||
| -rw-r--r-- | src/settings.h | 12 | ||||
| -rw-r--r-- | src/settingsdialog.cpp | 2 | ||||
| -rw-r--r-- | src/settingsdialogpaths.cpp | 12 |
9 files changed, 484 insertions, 75 deletions
diff --git a/modorganizer.natvis b/modorganizer.natvis index fe4a7ce2..6e21e099 100644 --- a/modorganizer.natvis +++ b/modorganizer.natvis @@ -8,5 +8,102 @@ file={m_wsFile} loaded={m_loaded} expanded={m_expanded} }}</DisplayString></Type> + <Type Name="QFileInfoPrivate"> + <DisplayString Condition="0 == this"><null></DisplayString> + <DisplayString>{fileEntry}</DisplayString> + <StringView>fileEntry</StringView> + <Expand> + <Item Name="QSharedData">*((Qt5Core.dll!QSharedData *) this)</Item> + <Item Name="fileEntry">fileEntry</Item> + <!-- + <Item Name="metaData">metaData</Item> + <Item Name="fileListsInitialized">fileListsInitialized</Item> + <Item Name="fileEngine">fileEngine</Item> + <Item Name="fileNames">fileNames</Item> + <Item Name="fileOwners">fileOwners</Item> + <Item Name="cachedFlags">cachedFlags</Item> + <Item Name="isDefaultConstructed">isDefaultConstructed</Item> + <Item Name="cache_enabled">cache_enabled</Item> + <Item Name="fileFlags">fileFlags</Item> + <Item Name="fileSize">fileSize</Item> + <Item Name="fileTimes">fileTimes</Item> + --> + </Expand> + </Type> + + <Type Name="QFileInfo"> + <DisplayString>{*((Qt5Core.dll!QFileInfoPrivate *) d_ptr.d)}</DisplayString> + <StringView>*((Qt5Core.dll!QFileInfoPrivate *) d_ptr.d)</StringView> + <Expand> + <Item Name="QFileInfoPrivate">*((Qt5Core.dll!QFileInfoPrivate *) d_ptr.d)</Item> + </Expand> + </Type> + + + <Type Name="QFileSystemEntry"> + <DisplayString Condition="0 == this"><null></DisplayString> + <DisplayString>{m_filePath}</DisplayString> + <StringView>m_filePath</StringView> + <!-- + <Expand> + <Item Name="m_filePath">m_filePath</Item> + <Item Name="m_nativeFilePath">m_nativeFilePath</Item> + <Item Name="m_lastSeparator">m_lastSeparator</Item> + <Item Name="m_firstDotInFileName">m_firstDotInFileName</Item> + <Item Name="m_lastDotInFileName">m_lastDotInFileName</Item> + </Expand> + --> + </Type> + + + <Type Name="QDirPrivate"> + <DisplayString Condition="0 == this"><null></DisplayString> + <DisplayString>{dirEntry}</DisplayString> + <StringView>dirEntry</StringView> + <Expand> + <Item Name="QSharedData">*((Qt5Core.dll!QSharedData *) this)</Item> + <Item Name="dirEntry">dirEntry</Item> + <Item Name="nameFilters">nameFilters</Item> + <Item Name="absoluteDirEntry">absoluteDirEntry</Item> + <!-- + <Item Name="metaData">metaData</Item> + <Item Name="fileListsInitialized">fileListsInitialized</Item> + <Item Name="fileEngine">fileEngine</Item> + <Item Name="files">files</Item> + <Item Name="fileInfos">fileInfos</Item> + <Item Name="sort">sort</Item> + <Item Name="filters">filters</Item> + --> + </Expand> + </Type> + + + <Type Name="QDir"> + <DisplayString>{*((Qt5Core.dll!QDirPrivate *) d_ptr.d)}</DisplayString> + <StringView>*((Qt5Core.dll!QDirPrivate *) d_ptr.d)</StringView> + <Expand> + <Item Name="QDirPrivate">*((Qt5Core.dll!QDirPrivate *) d_ptr.d)</Item> + </Expand> + </Type> + + + <Type Name="QFilePrivate"> + <DisplayString Condition="0 == this"><null></DisplayString> + <DisplayString>{fileName}</DisplayString> + <StringView>fileName</StringView> + <Expand> + <Item Name="QFileDevice">*((Qt5Core.dll!QFileDevice *) this)</Item> + <Item Name="fileName">fileName</Item> + </Expand> + </Type> + + + <Type Name="QFile"> + <DisplayString>{*((Qt5Core.dll!QFilePrivate *) d_ptr.d)}</DisplayString> + <StringView>*((Qt5Core.dll!QFilePrivate *) d_ptr.d)</StringView> + <Expand> + <Item Name="QFilePrivate">*((Qt5Core.dll!QFilePrivate *) d_ptr.d)</Item> + </Expand> + </Type> </AutoVisualizer> diff --git a/src/createinstancedialog.cpp b/src/createinstancedialog.cpp index 8c6605ed..5c85aa68 100644 --- a/src/createinstancedialog.cpp +++ b/src/createinstancedialog.cpp @@ -2,13 +2,19 @@ #include "ui_createinstancedialog.h" #include "instancemanager.h" #include "plugincontainer.h" +#include "settings.h" #include "shared/appconfig.h" #include <report.h> #include <iplugingame.h> +#include <utility.h> + +using namespace MOBase; namespace cid { +using MOBase::TaskDialog; + class PathChecker { public: @@ -153,6 +159,12 @@ private: } }; +QString makeDefaultPath(const std::wstring& dir) +{ + return QDir::toNativeSeparators( + PathSettings::makeDefaultPath(QString::fromStdWString(dir))); +} + class Page { @@ -195,7 +207,7 @@ public: return CreateInstanceDialog::NoType; } - virtual MOBase::IPluginGame* selectedGame() const + virtual IPluginGame* selectedGame() const { // no-op return nullptr; @@ -315,7 +327,7 @@ public: return (m_selection != nullptr); } - MOBase::IPluginGame* selectedGame() const override + IPluginGame* selectedGame() const override { if (!m_selection) { return nullptr; @@ -330,10 +342,10 @@ public: return {}; } - return m_selection->dir; + return QDir::toNativeSeparators(m_selection->dir); } - void select(MOBase::IPluginGame* game) + void select(IPluginGame* game) { Game* checked = findGame(game); @@ -397,12 +409,12 @@ public: private: struct Game { - MOBase::IPluginGame* game = nullptr; + IPluginGame* game = nullptr; QCommandLinkButton* button = nullptr; QString dir; bool installed = false; - Game(MOBase::IPluginGame* g) + Game(IPluginGame* g) : game(g), installed(g->isInstalled()) { if (installed) { @@ -418,11 +430,11 @@ private: Game* m_selection; - std::vector<MOBase::IPluginGame*> sortedGamePlugins() const + std::vector<IPluginGame*> sortedGamePlugins() const { - std::vector<MOBase::IPluginGame*> v; + std::vector<IPluginGame*> v; - for (auto* game : m_pc.plugins<MOBase::IPluginGame>()) { + for (auto* game : m_pc.plugins<IPluginGame>()) { v.push_back(game); } @@ -433,7 +445,7 @@ private: return v; } - Game* findGame(MOBase::IPluginGame* game) + Game* findGame(IPluginGame* game) { for (auto& g : m_games) { if (g->game == game) { @@ -598,9 +610,9 @@ private: return g; } - MOBase::IPluginGame* findAnotherGame(const QString& path) + IPluginGame* findAnotherGame(const QString& path) { - for (auto* otherGame : m_pc.plugins<MOBase::IPluginGame>()) { + for (auto* otherGame : m_pc.plugins<IPluginGame>()) { if (otherGame->looksValid(path)) { return otherGame; } @@ -609,9 +621,9 @@ private: return nullptr; } - bool confirmUnknown(const QString& path, MOBase::IPluginGame* game) + bool confirmUnknown(const QString& path, IPluginGame* game) { - const auto r = MOBase::TaskDialog(&m_dlg) + const auto r = TaskDialog(&m_dlg) .title(QObject::tr("Unrecognized game")) .main(QObject::tr("Unrecognized game")) .content(QObject::tr( @@ -632,11 +644,11 @@ private: return (r == QMessageBox::Ignore); } - MOBase::IPluginGame* confirmOtherGame( + IPluginGame* confirmOtherGame( const QString& path, - MOBase::IPluginGame* selectedGame, MOBase::IPluginGame* guessedGame) + IPluginGame* selectedGame, IPluginGame* guessedGame) { - const auto r = MOBase::TaskDialog(&m_dlg) + const auto r = TaskDialog(&m_dlg) .title(QObject::tr("Incorrect game")) .main(QObject::tr("Incorrect game")) .content(QObject::tr( @@ -742,7 +754,7 @@ public: } private: - MOBase::IPluginGame* m_previousGame; + IPluginGame* m_previousGame; std::vector<QCommandLinkButton*> m_buttons; QString m_selection; @@ -868,10 +880,6 @@ public: ui->pathPages->setCurrentIndex(0); } - bool skip() const override - { - return (m_dlg.instanceType() == CreateInstanceDialog::Portable); - } bool ready() const override { @@ -934,7 +942,7 @@ private: bool checkVarPath(QString path) const { - path.replace("%BASE_DIR%", ui->base->text()); + path = PathSettings::resolve(path, ui->base->text()); return checkAdvancedPath(path); } @@ -971,11 +979,6 @@ private: e->setText(path); } } - - QString makeDefaultPath(const std::wstring& dir) - { - return "%BASE_DIR%\\" + QString::fromStdWString(dir); - } }; @@ -990,54 +993,52 @@ public: void activated() override { ui->review->setPlainText(makeReview()); + ui->creationLog->clear(); } - QString makeReview() const + QString toLocalizedString(CreateInstanceDialog::Types t) const { - QStringList lines; - - const auto paths = m_dlg.paths(); - - // type - switch (m_dlg.instanceType()) + switch (t) { case CreateInstanceDialog::Global: - { - lines.push_back(QObject::tr("Instance type: %1").arg(QObject::tr("Global"))); - lines.push_back(QObject::tr("Instance name: %1").arg(m_dlg.instanceName())); - - if (paths.downloads.isEmpty()) { - // simple settings - lines.push_back(QObject::tr("Instance location: %1").arg(paths.base)); - } else { - // advanced settings - lines.push_back(QObject::tr("Instance base folder: %1").arg(paths.base)); - lines.push_back(dirLine(QObject::tr("Downloads"), paths.downloads)); - lines.push_back(dirLine(QObject::tr("Mods"), paths.mods)); - lines.push_back(dirLine(QObject::tr("Profiles"), paths.profiles)); - lines.push_back(dirLine(QObject::tr("Overwrite"), paths.overwrite)); - } - - break; - } + return QObject::tr("Global"); case CreateInstanceDialog::Portable: - { - lines.push_back(QObject::tr("Instance type: %1").arg(QObject::tr("Portable"))); - lines.push_back(QObject::tr("Instance location: %1").arg(qApp->applicationDirPath())); - break; - } + return QObject::tr("Portable"); default: - { - lines.push_back(QObject::tr("Instance type: %1").arg(QObject::tr("?"))); + return QObject::tr("Instance type: %1").arg(QObject::tr("?")); + } + } + + QString makeReview() const + { + QStringList lines; + const auto paths = m_dlg.paths(); + + lines.push_back(QObject::tr("Instance type: %1").arg(toLocalizedString(m_dlg.instanceType()))); + lines.push_back(QObject::tr("Instance location: %1").arg(m_dlg.dataPath())); + + if (m_dlg.instanceType() != CreateInstanceDialog::Portable) { + lines.push_back(QObject::tr("Instance name: %1").arg(m_dlg.instanceName())); + } + + if (paths.downloads.isEmpty()) { + // simple settings + if (paths.base != m_dlg.dataPath()) { + lines.push_back(QObject::tr("Base directory: %1").arg(paths.base)); } + } else { + // advanced settings + lines.push_back(QObject::tr("Base directory: %1").arg(paths.base)); + lines.push_back(dirLine(QObject::tr("Downloads"), paths.downloads)); + lines.push_back(dirLine(QObject::tr("Mods"), paths.mods)); + lines.push_back(dirLine(QObject::tr("Profiles"), paths.profiles)); + lines.push_back(dirLine(QObject::tr("Overwrite"), paths.overwrite)); } // game - MOBase::IPluginGame* game = m_dlg.game(); - - QString name = game->gameName(); + QString name = m_dlg.game()->gameName(); if (!m_dlg.gameEdition().isEmpty()) { name += " (" + m_dlg.gameEdition() + ")"; } @@ -1157,8 +1158,195 @@ void CreateInstanceDialog::changePage(int d) } } + +class Failed {}; + +class DirectoryCreator +{ +public: + DirectoryCreator(const DirectoryCreator&) = delete; + DirectoryCreator& operator=(const DirectoryCreator&) = delete; + + static std::unique_ptr<DirectoryCreator> create( + const QDir& target, std::function<void (QString)> log) + { + return std::unique_ptr<DirectoryCreator>(new DirectoryCreator(target, log)); + } + + ~DirectoryCreator() + { + rollback(); + } + + void commit() + { + m_created.clear(); + } + + void rollback() noexcept + { + try + { + for (auto itor=m_created.rbegin(); itor!=m_created.rend(); ++itor) { + const auto r = shell::DeleteDirectoryRecursive(*itor); + if (!r) { + m_logger(r.toString()); + } + } + + m_created.clear(); + } + catch(...) + { + // eat it + } + } + +private: + std::function<void (QString)> m_logger; + + DirectoryCreator(const QDir& target, std::function<void (QString)> log) + : m_logger(log) + { + try + { + const QString s = QDir::toNativeSeparators(target.absolutePath()); + const QStringList cs = s.split("\\"); + + if (cs.empty()) { + return; + } + + QDir d(cs[0]); + + for (int i=1; i<cs.size(); ++i) { + d = d.filePath(cs[i]); + + if (!d.exists()) { + m_logger(QObject::tr("Creating %1").arg(d.path())); + const auto r = shell::CreateDirectories(d); + + if (!r) { + m_logger(r.toString()); + throw Failed(); + } + + m_created.push_back(d); + } + } + } + catch(...) + { + rollback(); + throw; + } + } + +private: + std::vector<QDir> m_created; +}; + void CreateInstanceDialog::finish() { + ui->creationLog->clear(); + logCreation(tr("Creating instance...")); + + const auto& m = InstanceManager::instance(); + const auto ci = creationInfo(); + + auto logger = [&](QString s) { + logCreation(s); + }; + + auto createDir = [&](QString path) { + return DirectoryCreator::create(path, logger); + }; + + + try + { + std::vector<std::unique_ptr<DirectoryCreator>> dirs; + + dirs.push_back(createDir(ci.dataPath)); + dirs.push_back(createDir(ci.paths.base)); + dirs.push_back(createDir(PathSettings::resolve(ci.paths.downloads, ci.paths.base))); + dirs.push_back(createDir(PathSettings::resolve(ci.paths.mods, ci.paths.base))); + dirs.push_back(createDir(PathSettings::resolve(ci.paths.profiles, ci.paths.base))); + dirs.push_back(createDir(PathSettings::resolve(ci.paths.overwrite, ci.paths.base))); + + + Settings s(ci.iniPath); + s.game().setName(ci.game->gameName()); + s.game().setDirectory(ci.gameLocation); + + if (!ci.gameEdition.isEmpty()) { + s.game().setEdition(ci.gameEdition); + } + + if (ci.type == Global) { + if (ci.paths.base != ci.dataPath) { + s.paths().setBase(ci.paths.base); + } + + if (ci.paths.downloads != cid::makeDefaultPath(AppConfig::downloadPath())) { + s.paths().setDownloads(ci.paths.downloads); + } + + if (ci.paths.mods != cid::makeDefaultPath(AppConfig::modsPath())) { + s.paths().setMods(ci.paths.mods); + } + + if (ci.paths.profiles != cid::makeDefaultPath(AppConfig::profilesPath())) { + s.paths().setProfiles(ci.paths.profiles); + } + + if (ci.paths.overwrite != cid::makeDefaultPath(AppConfig::overwritePath())) { + s.paths().setOverwrite(ci.paths.overwrite); + } + } + + + logCreation(tr("Writing %1...").arg(ci.iniPath)); + + const auto r = s.sync(); + if (r != QSettings::NoError) { + switch (r) + { + case QSettings::AccessError: + logCreation(formatSystemMessage(ERROR_ACCESS_DENIED)); + break; + + case QSettings::FormatError: + logCreation(tr("Format error.")); + break; + + default: + logCreation(tr("Error %1.").arg(static_cast<int>(r))); + break; + } + + throw Failed(); + } + + for (auto& d : dirs) { + d->commit(); + } + + logCreation(tr("Done.")); + } + catch(Failed&) + { + } +} + +void CreateInstanceDialog::logCreation(const QString& s) +{ + ui->creationLog->insertPlainText(s + "\n"); +} + +void CreateInstanceDialog::logCreation(const std::wstring& s) +{ + logCreation(QString::fromStdWString(s)); } void CreateInstanceDialog::selectPage(std::size_t i) @@ -1213,7 +1401,72 @@ QString CreateInstanceDialog::instanceName() const return getSelected(&cid::Page::selectedInstanceName); } +QString CreateInstanceDialog::dataPath() const +{ + QString s; + + if (instanceType() == Portable) { + s = QDir(qApp->applicationDirPath()).absolutePath(); + } else { + s = InstanceManager::instance().instancePath(instanceName()); + } + + return QDir::toNativeSeparators(s); +} + CreateInstanceDialog::Paths CreateInstanceDialog::paths() const { return getSelected(&cid::Page::selectedPaths); } + +CreateInstanceDialog::CreationInfo CreateInstanceDialog::creationInfo() const +{ + CreationInfo ci; + + ci.type = getSelected(&cid::Page::selectedInstanceType); + ci.game = getSelected(&cid::Page::selectedGame); + ci.gameLocation = getSelected(&cid::Page::selectedGameLocation); + ci.gameEdition = getSelected(&cid::Page::selectedGameEdition); + ci.instanceName = getSelected(&cid::Page::selectedInstanceName); + ci.paths = getSelected(&cid::Page::selectedPaths); + ci.dataPath = dataPath(); + + ci.paths.base = QDir(ci.paths.base).absolutePath(); + + if (ci.paths.downloads.isEmpty()) { + ci.paths.downloads = cid::makeDefaultPath(AppConfig::downloadPath()); + } else if (!ci.paths.downloads.contains(PathSettings::BaseDirVariable)) { + ci.paths.downloads = QDir(ci.paths.downloads).absolutePath(); + } + + if (ci.paths.mods.isEmpty()) { + ci.paths.mods = cid::makeDefaultPath(AppConfig::modsPath()); + } else if (!ci.paths.mods.contains(PathSettings::BaseDirVariable)) { + ci.paths.mods = QDir(ci.paths.mods).absolutePath(); + } + + if (ci.paths.profiles.isEmpty()) { + ci.paths.profiles = cid::makeDefaultPath(AppConfig::profilesPath()); + } else if (!ci.paths.profiles.contains(PathSettings::BaseDirVariable)) { + ci.paths.profiles = QDir(ci.paths.profiles).absolutePath(); + } + + if (ci.paths.overwrite.isEmpty()) { + ci.paths.overwrite = cid::makeDefaultPath(AppConfig::overwritePath()); + } else if (!ci.paths.overwrite.contains(PathSettings::BaseDirVariable)) { + ci.paths.overwrite = QDir(ci.paths.overwrite).absolutePath(); + } + + ci.iniPath = QFileInfo( + ci.dataPath + "/" + QString::fromStdWString(AppConfig::iniFileName())) + .absoluteFilePath(); + + ci.paths.base = QDir::toNativeSeparators(ci.paths.base); + ci.paths.downloads = QDir::toNativeSeparators(ci.paths.downloads); + ci.paths.mods = QDir::toNativeSeparators(ci.paths.mods); + ci.paths.profiles = QDir::toNativeSeparators(ci.paths.profiles); + ci.paths.overwrite = QDir::toNativeSeparators(ci.paths.overwrite); + ci.paths.ini = QDir::toNativeSeparators(ci.paths.ini); + + return ci; +} diff --git a/src/createinstancedialog.h b/src/createinstancedialog.h index d9c392ca..2f5774ae 100644 --- a/src/createinstancedialog.h +++ b/src/createinstancedialog.h @@ -28,10 +28,24 @@ public: QString mods; QString profiles; QString overwrite; + QString ini; auto operator<=>(const Paths&) const = default; }; + struct CreationInfo + { + Types type; + MOBase::IPluginGame* game; + QString gameLocation; + QString gameEdition; + QString instanceName; + QString dataPath; + QString iniPath; + Paths paths; + }; + + explicit CreateInstanceDialog( const PluginContainer& pc, QWidget *parent = nullptr); @@ -54,8 +68,11 @@ public: QString gameLocation() const; QString gameEdition() const; QString instanceName() const; + QString dataPath() const; Paths paths() const; + CreationInfo creationInfo() const; + private: std::unique_ptr<Ui::CreateInstanceDialog> ui; const PluginContainer& m_pc; @@ -74,6 +91,9 @@ private: return T(); } + + void logCreation(const QString& s); + void logCreation(const std::wstring& s); }; #endif // MODORGANIZER_CREATEINSTANCEDIALOG_INCLUDED diff --git a/src/createinstancedialog.ui b/src/createinstancedialog.ui index c899a5b7..cfb343fa 100644 --- a/src/createinstancedialog.ui +++ b/src/createinstancedialog.ui @@ -891,7 +891,21 @@ <number>0</number> </property> <item> - <widget class="QTextEdit" name="review"/> + <widget class="QTextEdit" name="review"> + <property name="lineWrapMode"> + <enum>QTextEdit::NoWrap</enum> + </property> + </widget> + </item> + <item> + <widget class="QTextEdit" name="creationLog"> + <property name="lineWrapMode"> + <enum>QTextEdit::NoWrap</enum> + </property> + <property name="textInteractionFlags"> + <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> </item> </layout> </widget> diff --git a/src/instancemanager.h b/src/instancemanager.h index 0cd5ef4c..6a6b52ac 100644 --- a/src/instancemanager.h +++ b/src/instancemanager.h @@ -56,13 +56,12 @@ public: QString sanitizeInstanceName(const QString &name) const; QString makeUniqueName(const QString& instanceName) const; bool instanceExists(const QString& instanceName) const; + QString instancePath(const QString& instanceName) const; private: InstanceManager(); - QString instancePath(const QString& instanceName) const; - bool deleteLocalInstance(const QString &instanceId) const; QString manageInstances(const QStringList &instanceList) const; diff --git a/src/settings.cpp b/src/settings.cpp index 8db9c623..661cf429 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1464,6 +1464,8 @@ QSet<QString> PluginSettings::readBlacklist() const } +const QString PathSettings::BaseDirVariable = "%BASE_DIR%"; + PathSettings::PathSettings(QSettings& settings) : m_Settings(settings) { @@ -1511,10 +1513,10 @@ QString PathSettings::getConfigurablePath(const QString &key, bool resolve) const { QString result = QDir::fromNativeSeparators( - get<QString>(m_Settings, "Settings", key, QString("%BASE_DIR%/") + def)); + get<QString>(m_Settings, "Settings", key, makeDefaultPath(def))); if (resolve) { - result.replace("%BASE_DIR%", base()); + result = PathSettings::resolve(result, base()); } return result; @@ -1529,6 +1531,18 @@ void PathSettings::setConfigurablePath(const QString &key, const QString& path) } } +QString PathSettings::resolve(const QString& path, const QString& baseDir) +{ + QString s = path; + s.replace(BaseDirVariable, baseDir); + return s; +} + +QString PathSettings::makeDefaultPath(const QString dirName) +{ + return BaseDirVariable + "/" + dirName; +} + QString PathSettings::base() const { return QDir::fromNativeSeparators(get<QString>(m_Settings, diff --git a/src/settings.h b/src/settings.h index a8c527d6..c723faec 100644 --- a/src/settings.h +++ b/src/settings.h @@ -391,6 +391,9 @@ private: class PathSettings { public: + // %BASE_DIR% + static const QString BaseDirVariable; + PathSettings(QSettings& settings); QString base() const; @@ -418,6 +421,15 @@ public: std::map<QString, QString> recent() const; void setRecent(const std::map<QString, QString>& map); + + // resolves %BASE_DIR% + // + static QString resolve(const QString& path, const QString& baseDir); + + // returns %BASE_DIR%/dirName + // + static QString makeDefaultPath(const QString dirName); + private: QSettings& m_Settings; diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 87c7201d..c4a53fcd 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -114,7 +114,7 @@ QString SettingsDialog::getColoredButtonStyleSheet() const void SettingsDialog::accept() { QString newModPath = ui->modDirEdit->text(); - newModPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); + newModPath = PathSettings::resolve(newModPath, ui->baseDirEdit->text()); if ((QDir::fromNativeSeparators(newModPath) != QDir::fromNativeSeparators( diff --git a/src/settingsdialogpaths.cpp b/src/settingsdialogpaths.cpp index 74ba4f25..eb334541 100644 --- a/src/settingsdialogpaths.cpp +++ b/src/settingsdialogpaths.cpp @@ -64,7 +64,7 @@ void PathsSettingsTab::update() std::tie(path, setter, defaultName) = dir; QString realPath = path; - realPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); + realPath = PathSettings::resolve(realPath, ui->baseDirEdit->text()); if (!QDir(realPath).exists()) { if (!QDir().mkpath(realPath)) { @@ -113,7 +113,7 @@ void PathsSettingsTab::on_browseBaseDirBtn_clicked() void PathsSettingsTab::on_browseDownloadDirBtn_clicked() { QString searchPath = ui->downloadDirEdit->text(); - searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); + searchPath = PathSettings::resolve(searchPath, ui->baseDirEdit->text()); QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select download directory"), searchPath); if (!temp.isEmpty()) { @@ -124,7 +124,7 @@ void PathsSettingsTab::on_browseDownloadDirBtn_clicked() void PathsSettingsTab::on_browseModDirBtn_clicked() { QString searchPath = ui->modDirEdit->text(); - searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); + searchPath = PathSettings::resolve(searchPath, ui->baseDirEdit->text()); QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select mod directory"), searchPath); if (!temp.isEmpty()) { @@ -135,7 +135,7 @@ void PathsSettingsTab::on_browseModDirBtn_clicked() void PathsSettingsTab::on_browseCacheDirBtn_clicked() { QString searchPath = ui->cacheDirEdit->text(); - searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); + searchPath = PathSettings::resolve(searchPath, ui->baseDirEdit->text()); QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select cache directory"), searchPath); if (!temp.isEmpty()) { @@ -146,7 +146,7 @@ void PathsSettingsTab::on_browseCacheDirBtn_clicked() void PathsSettingsTab::on_browseProfilesDirBtn_clicked() { QString searchPath = ui->profilesDirEdit->text(); - searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); + searchPath = PathSettings::resolve(searchPath, ui->baseDirEdit->text()); QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select profiles directory"), searchPath); if (!temp.isEmpty()) { @@ -157,7 +157,7 @@ void PathsSettingsTab::on_browseProfilesDirBtn_clicked() void PathsSettingsTab::on_browseOverwriteDirBtn_clicked() { QString searchPath = ui->overwriteDirEdit->text(); - searchPath.replace("%BASE_DIR%", ui->baseDirEdit->text()); + searchPath = PathSettings::resolve(searchPath, ui->baseDirEdit->text()); QString temp = QFileDialog::getExistingDirectory(&dialog(), QObject::tr("Select overwrite directory"), searchPath); if (!temp.isEmpty()) { |
