Gui: Add YamlParameterSource for StyleParameters
This adds ability to read and write Style Parameters from YAML files. This will allow to move certain tokens out of the User Parameter system to ensure that they can be update without user needing to reapply the theme.
This commit is contained in:
@@ -146,7 +146,9 @@ target_include_directories(
|
||||
${QtNetwork_INCLUDE_DIRS}
|
||||
${QtUiTools_INCLUDE_DIRS}
|
||||
${QtXml_INCLUDE_DIRS}
|
||||
${YAML_CPP_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
list(APPEND FreeCADGui_LIBS
|
||||
${QtCore_LIBRARIES}
|
||||
${QtWidgets_LIBRARIES}
|
||||
@@ -159,6 +161,18 @@ list(APPEND FreeCADGui_LIBS
|
||||
${QtUiTools_LIBRARIES}
|
||||
)
|
||||
|
||||
link_directories(${YAML_CPP_LIBRARY_DIR})
|
||||
|
||||
if(yaml-cpp_VERSION VERSION_LESS 0.8.0)
|
||||
list(APPEND FreeCADGui_LIBS
|
||||
${YAML_CPP_LIBRARIES}
|
||||
)
|
||||
else()
|
||||
list(APPEND FreeCADGui_LIBS
|
||||
yaml-cpp::yaml-cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(${Qt5WinExtras_FOUND})
|
||||
target_include_directories(
|
||||
FreeCADGui
|
||||
|
||||
@@ -465,6 +465,10 @@ void StyleParametersModel::flush()
|
||||
}
|
||||
});
|
||||
|
||||
for (auto* source : sources) {
|
||||
source->flush();
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include "ParameterManager.h"
|
||||
#include "Parser.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <fstream>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <QColor>
|
||||
#include <QRegularExpression>
|
||||
@@ -35,6 +39,8 @@
|
||||
#include <variant>
|
||||
#endif
|
||||
|
||||
FC_LOG_LEVEL_INIT("Gui", true, true)
|
||||
|
||||
namespace Gui::StyleParameters
|
||||
{
|
||||
|
||||
@@ -215,6 +221,81 @@ void UserParameterSource::remove(const std::string& name)
|
||||
hGrp->RemoveASCII(name.c_str());
|
||||
}
|
||||
|
||||
YamlParameterSource::YamlParameterSource(const std::string& filePath, const Metadata& metadata)
|
||||
: ParameterSource(metadata)
|
||||
, filePath(filePath)
|
||||
{
|
||||
QFile file(QString::fromStdString(filePath));
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
FC_TRACE("StyleParameters: Unable to open file " << filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (filePath.starts_with(":/")) {
|
||||
this->metadata.options |= ReadOnly;
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
std::string content = in.readAll().toStdString();
|
||||
|
||||
YAML::Node root = YAML::Load(content);
|
||||
for (auto it = root.begin(); it != root.end(); ++it) {
|
||||
auto key = it->first.as<std::string>();
|
||||
auto value = it->second.as<std::string>();
|
||||
|
||||
parameters[key] = Parameter {
|
||||
.name = key,
|
||||
.value = value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
std::list<Parameter> YamlParameterSource::all() const
|
||||
{
|
||||
std::list<Parameter> result;
|
||||
for (const auto& param : parameters | std::views::values) {
|
||||
result.push_back(param);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<Parameter> YamlParameterSource::get(const std::string& name) const
|
||||
{
|
||||
if (auto it = parameters.find(name); it != parameters.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void YamlParameterSource::define(const Parameter& param)
|
||||
{
|
||||
parameters[param.name] = param;
|
||||
}
|
||||
|
||||
void YamlParameterSource::remove(const std::string& name)
|
||||
{
|
||||
parameters.erase(name);
|
||||
}
|
||||
|
||||
void YamlParameterSource::flush()
|
||||
{
|
||||
YAML::Node root;
|
||||
for (const auto& [name, param] : parameters) {
|
||||
root[name] = param.value;
|
||||
}
|
||||
|
||||
QFile file(QString::fromStdString(filePath));
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
|
||||
FC_TRACE("StyleParameters: Unable to open file " << filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
out << QString::fromStdString(YAML::Dump(root));
|
||||
}
|
||||
|
||||
ParameterManager::ParameterManager() = default;
|
||||
|
||||
void ParameterManager::reload()
|
||||
|
||||
@@ -306,6 +306,11 @@ public:
|
||||
* @param[in] name The name of the parameter to remove.
|
||||
*/
|
||||
virtual void remove([[maybe_unused]] const std::string& name) {}
|
||||
|
||||
/**
|
||||
* @brief Flushes buffered changes into more persistent storage.
|
||||
*/
|
||||
virtual void flush() {}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -376,6 +381,40 @@ public:
|
||||
void remove(const std::string& name) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class YamlParameterSource
|
||||
* @brief A ParameterSource implementation that loads and saves parameters
|
||||
* from a YAML file using yaml-cpp.
|
||||
*
|
||||
* This class maintains an in-memory map of parameters loaded from a YAML file.
|
||||
* Any changes through define() or remove() will also update the file.
|
||||
*/
|
||||
class GuiExport YamlParameterSource : public ParameterSource
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a YamlParameterSource that reads parameters from the given YAML file.
|
||||
*
|
||||
* If the file exists, all key-value pairs are loaded into memory.
|
||||
* If the file does not exist, an empty parameter set is initialized.
|
||||
*
|
||||
* @param filePath Path to the YAML file used for persistence.
|
||||
* @param metadata Optional metadata describing this source.
|
||||
*/
|
||||
explicit YamlParameterSource(const std::string& filePath, const Metadata& metadata = {});
|
||||
|
||||
std::list<Parameter> all() const override;
|
||||
std::optional<Parameter> get(const std::string& name) const override;
|
||||
void define(const Parameter& param) override;
|
||||
void remove(const std::string& name) override;
|
||||
|
||||
void flush() override;
|
||||
|
||||
private:
|
||||
std::string filePath;
|
||||
std::map<std::string, Parameter> parameters;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Central manager for style parameters that aggregates multiple sources.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user