diff --git a/src/Gui/DlgPreferencePackManagementImp.cpp b/src/Gui/DlgPreferencePackManagementImp.cpp index 50f3982f21e4..b1e96bb829fc 100644 --- a/src/Gui/DlgPreferencePackManagementImp.cpp +++ b/src/Gui/DlgPreferencePackManagementImp.cpp @@ -53,25 +53,25 @@ void DlgPreferencePackManagementImp::showEvent(QShowEvent* event) // Separate out user-saved packs from installed packs: we can remove individual user-saved packs, // but can only disable individual installed packs (though we can completely uninstall the pack's // containing Addon by redirecting to the Addon Manager). - auto savedPreferencePacksDirectory = fs::path(App::Application::getUserAppDataDir()) / "SavedPreferencePacks"; + auto savedPreferencePacksDirectory = Application::Instance->prefPackManager()->getSavedPreferencePacksPath(); auto modDirectories = Application::Instance->prefPackManager()->modPaths(); - auto resourcePath = fs::path(App::Application::getResourceDir()) / "Gui" / "PreferencePacks"; + auto resourcePath = Application::Instance->prefPackManager()->getResourcePreferencePacksPath(); // The displayed tree has two levels: at the toplevel is either "User-Saved Packs" or the name // of the addon containing the pack. Beneath those are the individual packs themselves. The tree view shows // "Hide"/"Show" for packs installed as a Mod, and "Delete" for packs in the user-saved pack // section. - auto userPacks = getPacksFromDirectory(savedPreferencePacksDirectory); + auto userPacks = Application::Instance->prefPackManager()->getPacksFromDirectory(savedPreferencePacksDirectory); - auto builtinPacks = getPacksFromDirectory(resourcePath); + auto builtinPacks = Application::Instance->prefPackManager()->getPacksFromDirectory(resourcePath); std::map> installedPacks; for (const auto& modDirectory : modDirectories) { if (fs::exists(modDirectory) && fs::is_directory(modDirectory)) { for (const auto& mod : fs::directory_iterator(modDirectory)) { - auto packs = getPacksFromDirectory(mod); + auto packs = Application::Instance->prefPackManager()->getPacksFromDirectory(mod); if (!packs.empty()) { - auto modName = mod.path().filename().string(); + auto modName = Base::FileInfo::pathToString(mod.path().filename()); installedPacks.emplace(modName, packs); } } @@ -98,8 +98,7 @@ void DlgPreferencePackManagementImp::showEvent(QShowEvent* event) addTreeNode(installedPack.first, installedPack.second, TreeWidgetType::ADDON); } - if (event) - QDialog::showEvent(event); + QDialog::showEvent(event); } void DlgPreferencePackManagementImp::addTreeNode(const std::string &name, const std::vector &contents, TreeWidgetType twt) @@ -152,29 +151,6 @@ void DlgPreferencePackManagementImp::addTreeNode(const std::string &name, const } } -std::vector DlgPreferencePackManagementImp::getPacksFromDirectory(const fs::path& path) const -{ - std::vector results; - auto packageMetadataFile = path / "package.xml"; - if (fs::exists(packageMetadataFile) && fs::is_regular_file(packageMetadataFile)) { - try { - App::Metadata metadata(packageMetadataFile); - auto content = metadata.content(); - for (const auto& item : content) { - if (item.first == "preferencepack") { - results.push_back(item.second.name()); - } - } - } - catch (...) { - // Failed to read the metadata, or to create the preferencePack based on it... - Base::Console().Error(("Failed to read " + packageMetadataFile.string()).c_str()); - } - } - return results; -} - - void DlgPreferencePackManagementImp::deleteUserPack(const std::string& name) { // Do the deletion here... diff --git a/src/Gui/DlgPreferencePackManagementImp.h b/src/Gui/DlgPreferencePackManagementImp.h index 079d4a3be477..a2a5843cb507 100644 --- a/src/Gui/DlgPreferencePackManagementImp.h +++ b/src/Gui/DlgPreferencePackManagementImp.h @@ -76,9 +76,7 @@ protected Q_SLOTS: std::unique_ptr ui; - std::vector getPacksFromDirectory(const boost::filesystem::path& path) const; void addTreeNode(const std::string& name, const std::vector& contents, TreeWidgetType twt); - }; } // namespace Dialog diff --git a/src/Gui/PreferencePackManager.cpp b/src/Gui/PreferencePackManager.cpp index 2328bcb04d81..54b42784e4d7 100644 --- a/src/Gui/PreferencePackManager.cpp +++ b/src/Gui/PreferencePackManager.cpp @@ -50,6 +50,18 @@ using namespace Gui; using namespace xercesc; namespace fs = boost::filesystem; +static boost::filesystem::path getSavedPrefPacksPath() +{ + return fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) + / "SavedPreferencePacks"; +} + +static boost::filesystem::path getResourcePrefPacksPath() +{ + return fs::path(Base::FileInfo::stringToPath(App::Application::getResourceDir())) / "Gui" + / "PreferencePacks"; +} + PreferencePack::PreferencePack(const fs::path& path, const App::Metadata& metadata) : _path(path), _metadata(metadata) { @@ -90,7 +102,7 @@ bool PreferencePack::apply() const } // Back up the old config file - auto savedPreferencePacksDirectory = fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks"; + auto savedPreferencePacksDirectory = getSavedPrefPacksPath(); auto backupFile = savedPreferencePacksDirectory / "user.cfg.backup"; try { fs::remove(backupFile); @@ -137,8 +149,8 @@ void PreferencePack::applyConfigChanges() const PreferencePackManager::PreferencePackManager() : _preferencePackPaths(modPaths()) { - auto savedPath = fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks"; - auto resourcePath = fs::path(Base::FileInfo::stringToPath(App::Application::getResourceDir())) / "Gui" / "PreferencePacks"; + auto savedPath = getSavedPreferencePacksPath(); + auto resourcePath = getResourcePreferencePacksPath(); _preferencePackPaths.insert(_preferencePackPaths.begin(), resourcePath); _preferencePackPaths.push_back(savedPath); rescan(); @@ -166,8 +178,7 @@ void PreferencePackManager::rescan() void Gui::PreferencePackManager::AddPackToMetadata(const std::string &packName) const { std::lock_guard lock(_mutex); - auto savedPreferencePacksDirectory = - fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks"; + auto savedPreferencePacksDirectory = getSavedPreferencePacksPath(); fs::path preferencePackDirectory(savedPreferencePacksDirectory / packName); if (fs::exists(preferencePackDirectory) && !fs::is_directory(preferencePackDirectory)) throw std::runtime_error("Cannot create " + savedPreferencePacksDirectory.string() @@ -221,8 +232,7 @@ void Gui::PreferencePackManager::importConfig(const std::string& packName, { AddPackToMetadata(packName); - auto savedPreferencePacksDirectory = - fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks"; + auto savedPreferencePacksDirectory = getSavedPreferencePacksPath(); auto cfgFilename = savedPreferencePacksDirectory / packName / (packName + ".cfg"); #if BOOST_VERSION >= 107400 fs::copy_file(path, cfgFilename, fs::copy_options::overwrite_existing); @@ -252,6 +262,38 @@ std::vector Gui::PreferencePackManager::modPaths() cons return result; } +boost::filesystem::path Gui::PreferencePackManager::getSavedPreferencePacksPath() const +{ + return getSavedPrefPacksPath(); +} + +boost::filesystem::path Gui::PreferencePackManager::getResourcePreferencePacksPath() const +{ + return getResourcePrefPacksPath(); +} + +std::vector Gui::PreferencePackManager::getPacksFromDirectory(const fs::path& path) const +{ + std::vector results; + auto packageMetadataFile = path / "package.xml"; + if (fs::exists(packageMetadataFile) && fs::is_regular_file(packageMetadataFile)) { + try { + App::Metadata metadata(packageMetadataFile); + auto content = metadata.content(); + for (const auto& item : content) { + if (item.first == "preferencepack") { + results.push_back(item.second.name()); + } + } + } + catch (...) { + // Failed to read the metadata, or to create the preferencePack based on it... + Base::Console().Error(("Failed to read " + packageMetadataFile.string()).c_str()); + } + } + return results; +} + void Gui::PreferencePackManager::FindPreferencePacksInPackage(const fs::path &mod) { try { @@ -271,7 +313,7 @@ void PreferencePackManager::TryFindPreferencePacksInPackage(const boost::filesys { auto packageMetadataFile = mod / "package.xml"; static const auto modDirectory = fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "Mod" / "SavedPreferencePacks"; - static const auto resourcePath = fs::path(Base::FileInfo::stringToPath(App::Application::getResourceDir())) / "Gui" / "PreferencePacks"; + static const auto resourcePath = getResourcePreferencePacksPath(); if (fs::exists(packageMetadataFile) && fs::is_regular_file(packageMetadataFile)) { App::Metadata metadata(packageMetadataFile); @@ -330,7 +372,7 @@ bool PreferencePackManager::apply(const std::string& preferencePackName) const } } -std::string findUnusedName(const std::string &basename, ParameterGrp::handle parent) +static std::string findUnusedName(const std::string &basename, ParameterGrp::handle parent) { int i = 1; while (true) { @@ -385,7 +427,7 @@ void Gui::PreferencePackManager::deleteUserPack(const std::string& name) { if (name.empty()) return; - auto savedPreferencePacksDirectory = fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks"; + auto savedPreferencePacksDirectory = getSavedPreferencePacksPath(); auto savedPath = savedPreferencePacksDirectory / name; std::unique_ptr metadata; if (fs::exists(savedPreferencePacksDirectory / "package.xml")) { @@ -401,7 +443,7 @@ void Gui::PreferencePackManager::deleteUserPack(const std::string& name) rescan(); } -void copyTemplateParameters(Base::Reference templateGroup, const std::string& path, Base::Reference outputGroup) +static void copyTemplateParameters(Base::Reference templateGroup, const std::string& path, Base::Reference outputGroup) { auto userParameterHandle = App::GetApplication().GetParameterGroupByPath(path.c_str()); @@ -452,7 +494,7 @@ void copyTemplateParameters(Base::Reference templateGroup, const s } } -void copyTemplateParameters(/*const*/ ParameterManager& templateParameterManager, ParameterManager& outputParameterManager) +static void copyTemplateParameters(/*const*/ ParameterManager& templateParameterManager, ParameterManager& outputParameterManager) { auto groups = templateParameterManager.GetGroups(); for (auto& group : groups) { @@ -477,19 +519,12 @@ void PreferencePackManager::save(const std::string& name, const std::vectorLoadDocument(Base::FileInfo::pathToString(t.path).c_str()); copyTemplateParameters(*templateParameterManager, *outputParameterManager); } - auto savedPreferencePacksDirectory = - fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks"; + auto savedPreferencePacksDirectory = getSavedPreferencePacksPath(); auto cfgFilename = savedPreferencePacksDirectory / name / (name + ".cfg"); outputParameterManager->SaveDocument(Base::FileInfo::pathToString(cfgFilename).c_str()); } -// Needed until we support only C++20 and above and can use std::string's built-in ends_with() -bool fc_ends_with(std::string_view str, std::string_view suffix) -{ - return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; -} - -std::vector scanForTemplateFolders(const std::string& groupName, const fs::path& entry) +static std::vector scanForTemplateFolders(const std::string& groupName, const fs::path& entry) { // From this location, find the folder(s) called "PreferencePackTemplates" std::vector templateFolders; @@ -511,7 +546,7 @@ std::vector scanForTemplateFolders(const std::string& groupName, const return templateFolders; } -std::vector scanForTemplateFiles(const std::string& groupName, const fs::path& entry) +static std::vector scanForTemplateFiles(const std::string& groupName, const fs::path& entry) { auto templateFolders = scanForTemplateFolders(groupName, entry); @@ -570,7 +605,7 @@ std::vector PreferencePackManager::template void Gui::PreferencePackManager::BackupCurrentConfig() const { - auto backupDirectory = fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks" / "Backups"; + auto backupDirectory = getSavedPreferencePacksPath() / "Backups"; fs::create_directories(backupDirectory); // Create a timestamped filename: @@ -587,7 +622,7 @@ void Gui::PreferencePackManager::DeleteOldBackups() const { constexpr auto oneWeek = 60.0 * 60.0 * 24.0 * 7.0; const auto now = std::time(nullptr); - auto backupDirectory = fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks" / "Backups"; + auto backupDirectory = getSavedPreferencePacksPath() / "Backups"; if (fs::exists(backupDirectory) && fs::is_directory(backupDirectory)) { for (const auto& backup : fs::directory_iterator(backupDirectory)) { if (std::difftime(now, fs::last_write_time(backup)) > oneWeek) { @@ -603,7 +638,7 @@ void Gui::PreferencePackManager::DeleteOldBackups() const std::vector Gui::PreferencePackManager::configBackups() const { std::vector results; - auto backupDirectory = fs::path(Base::FileInfo::stringToPath(App::Application::getUserAppDataDir())) / "SavedPreferencePacks" / "Backups"; + auto backupDirectory = getSavedPreferencePacksPath() / "Backups"; if (fs::exists(backupDirectory) && fs::is_directory(backupDirectory)) { for (const auto& backup : fs::directory_iterator(backupDirectory)) { results.push_back(backup); diff --git a/src/Gui/PreferencePackManager.h b/src/Gui/PreferencePackManager.h index e5776e47a02d..0358fe77ea6d 100644 --- a/src/Gui/PreferencePackManager.h +++ b/src/Gui/PreferencePackManager.h @@ -196,6 +196,21 @@ namespace Gui { */ std::vector modPaths() const; + /** + * Get the path to the saved preference packs. + */ + boost::filesystem::path getSavedPreferencePacksPath() const; + + /** + * Get the path to the preference packs of the resource directory. + */ + boost::filesystem::path getResourcePreferencePacksPath() const; + + /** + * Collect all preference packs of a directory. + */ + std::vector getPacksFromDirectory(const boost::filesystem::path& path) const; + private: void FindPreferencePacksInPackage(const boost::filesystem::path& mod);