Skip to content

Commit

Permalink
Gui: Refactor PreferencePackManager & DlgPreferencePackManagementImp
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer authored and chennes committed Nov 28, 2024
1 parent 354d095 commit 3595c30
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 58 deletions.
38 changes: 7 additions & 31 deletions src/Gui/DlgPreferencePackManagementImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string, std::vector<std::string>> installedPacks;

Check warning on line 68 in src/Gui/DlgPreferencePackManagementImp.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

variable 'installedPacks' is not initialized [cppcoreguidelines-init-variables]
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);
}
}
Expand All @@ -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<std::string> &contents, TreeWidgetType twt)
Expand Down Expand Up @@ -152,29 +151,6 @@ void DlgPreferencePackManagementImp::addTreeNode(const std::string &name, const
}
}

std::vector<std::string> DlgPreferencePackManagementImp::getPacksFromDirectory(const fs::path& path) const
{
std::vector<std::string> 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...
Expand Down
2 changes: 0 additions & 2 deletions src/Gui/DlgPreferencePackManagementImp.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ protected Q_SLOTS:

std::unique_ptr<Ui_DlgPreferencePackManagement> ui;

std::vector<std::string> getPacksFromDirectory(const boost::filesystem::path& path) const;
void addTreeNode(const std::string& name, const std::vector<std::string>& contents, TreeWidgetType twt);

};

} // namespace Dialog
Expand Down
85 changes: 60 additions & 25 deletions src/Gui/PreferencePackManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -166,8 +178,7 @@ void PreferencePackManager::rescan()
void Gui::PreferencePackManager::AddPackToMetadata(const std::string &packName) const
{
std::lock_guard<std::mutex> 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))

Check warning on line 183 in src/Gui/PreferencePackManager.cpp

View workflow job for this annotation

GitHub Actions / Lint / Lint

statement should be inside braces [readability-braces-around-statements]
throw std::runtime_error("Cannot create " + savedPreferencePacksDirectory.string()
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -252,6 +262,38 @@ std::vector<boost::filesystem::path> 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<std::string> Gui::PreferencePackManager::getPacksFromDirectory(const fs::path& path) const
{
std::vector<std::string> 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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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<App::Metadata> metadata;
if (fs::exists(savedPreferencePacksDirectory / "package.xml")) {
Expand All @@ -401,7 +443,7 @@ void Gui::PreferencePackManager::deleteUserPack(const std::string& name)
rescan();
}

void copyTemplateParameters(Base::Reference<ParameterGrp> templateGroup, const std::string& path, Base::Reference<ParameterGrp> outputGroup)
static void copyTemplateParameters(Base::Reference<ParameterGrp> templateGroup, const std::string& path, Base::Reference<ParameterGrp> outputGroup)
{
auto userParameterHandle = App::GetApplication().GetParameterGroupByPath(path.c_str());

Expand Down Expand Up @@ -452,7 +494,7 @@ void copyTemplateParameters(Base::Reference<ParameterGrp> 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) {
Expand All @@ -477,19 +519,12 @@ void PreferencePackManager::save(const std::string& name, const std::vector<Temp
templateParameterManager->LoadDocument(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<fs::path> scanForTemplateFolders(const std::string& groupName, const fs::path& entry)
static std::vector<fs::path> scanForTemplateFolders(const std::string& groupName, const fs::path& entry)
{
// From this location, find the folder(s) called "PreferencePackTemplates"
std::vector<fs::path> templateFolders;
Expand All @@ -511,7 +546,7 @@ std::vector<fs::path> scanForTemplateFolders(const std::string& groupName, const
return templateFolders;
}

std::vector<PreferencePackManager::TemplateFile> scanForTemplateFiles(const std::string& groupName, const fs::path& entry)
static std::vector<PreferencePackManager::TemplateFile> scanForTemplateFiles(const std::string& groupName, const fs::path& entry)
{
auto templateFolders = scanForTemplateFolders(groupName, entry);

Expand Down Expand Up @@ -570,7 +605,7 @@ std::vector<PreferencePackManager::TemplateFile> 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:
Expand All @@ -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) {
Expand All @@ -603,7 +638,7 @@ void Gui::PreferencePackManager::DeleteOldBackups() const
std::vector<boost::filesystem::path> Gui::PreferencePackManager::configBackups() const
{
std::vector<boost::filesystem::path> 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);
Expand Down
15 changes: 15 additions & 0 deletions src/Gui/PreferencePackManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,21 @@ namespace Gui {
*/
std::vector<boost::filesystem::path> 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<std::string> getPacksFromDirectory(const boost::filesystem::path& path) const;

private:

void FindPreferencePacksInPackage(const boost::filesystem::path& mod);
Expand Down

0 comments on commit 3595c30

Please sign in to comment.