diff options
author | Fabien Proriol <fabien.proriol@kazoe.org> | 2025-05-22 17:10:35 +0200 |
---|---|---|
committer | Fabien Proriol <fabien.proriol@kazoe.org> | 2025-05-26 10:48:46 +0200 |
commit | 2feba4447a482840e21fa2d3b33f1a5da12d09b7 (patch) | |
tree | 83a790b1ae5b5f32f5964350856a160dbed52e05 /src/kzsettings.h | |
parent | c842548fef050ac5f8b56a5fcb4f579820247434 (diff) |
qt: Add Qt Wrapper library and QML module
Diffstat (limited to 'src/kzsettings.h')
-rw-r--r-- | src/kzsettings.h | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/kzsettings.h b/src/kzsettings.h new file mode 100644 index 0000000..9f8d35b --- /dev/null +++ b/src/kzsettings.h @@ -0,0 +1,180 @@ +#ifndef KZSETTINGS_H +#define KZSETTINGS_H + +#include <functional> +#include <memory> +#include <variant> +#include <string> +#include <algorithm> + +/** @brief Key type for settings, composed of category and name */ +using KzSettingKey = std::pair<std::string, std::string>; + +/** @brief Value type that can hold string, int, double or boolean */ +using KzSettingValue = std::variant<std::string, int, double, bool>; + + +namespace KaZoe { + +class KzSettingsPrivate; + +/** + * @brief Main class for managing KaZoe settings + * + * This class provides a thread-safe interface for storing and retrieving + * configuration settings with support for different value types. + */ +class KzSettings +{ +public: + /** @brief Constructs a new Settings instance */ + explicit KzSettings(); + + /** @brief Virtual destructor */ + virtual ~KzSettings(); + + /** + * @brief Retrieves a setting value + * @param key The setting key + * @param category The setting category (optional) + * @param def Default value if setting not found (optional) + * @return The setting value or default if not found + */ + KzSettingValue get(const std::string &key, const std::string &category = "", KzSettingValue def = KzSettingValue()) const; + + /** + * @brief Sets a setting value + * @param key The setting key + * @param value The value to set + * @param category The setting category (optional) + * @return true if successful, false otherwise + */ + bool set(const std::string &key, KzSettingValue value, const std::string &category = ""); + + /** + * @brief Gets the current instance identifier + * @return The instance ID string, by default, this is the excecutable filename + */ + std::string id() const; + + /** + * @brief Sets the instance identifier + * @param newid The new ID to set + */ + void setId(const std::string &newid); + + /** + * @brief Sets a callback for setting changes notification + * @param callback Function to call when settings change + */ + void setNotifier(const std::function<void(const std::string&, const std::string&, KzSettingValue)>& callback); + + /** + * @brief Gets the number of settings + * @return The total count of settings + */ + std::size_t size() const; + + /** + * @brief Iterates over all settings in a thread-safe manner + * @param callback Function called for each key-value pair + */ + void forEach(const std::function<void(const KzSettingKey&, const KzSettingValue&)>& callback) const; + +private: + std::unique_ptr<KzSettingsPrivate> m_ptr; ///< Private implementation pointer +}; + + +/** + * @brief Functor to convert SettingValue variants to string + * + * Provides string conversion for all supported setting value types + */ +struct settingValueFunctor { + std::string operator()(const std::string &x) const { return x; } + std::string operator()(int x) const { return std::to_string(x); } + std::string operator()(double x) const { return std::to_string(x); } + std::string operator()(bool x) const { return x ? "true" : "false"; } +}; + +/** + * @brief Convert a SettingValue into a string for display + * @param value Input SettingValue to convert + * @return std::string containing the converted value + */ +static inline std::string valueToStr(const KzSettingValue &value) +{ + return std::visit(settingValueFunctor(), value); +} + +/** + * @brief Check if a string represents a valid numeric value + * @param str String to check + * @return true if string is numeric, false otherwise + */ +static inline bool is_numeric(const std::string& str) { + return !str.empty() && + str.find_first_not_of("0123456789.-") == std::string::npos && + (std::count(str.begin(), str.end(), '.') <= 1) && + (std::count(str.begin(), str.end(), '-') <= 1) && + (str[0] == '-' || std::isdigit(str[0])); +} + +/** + * @brief Convert a string to appropriate SettingValue type + * @param value Input string to convert + * @return SettingValue containing the converted value + * + * Conversion rules: + * - Quoted strings -> string without quotes + * - Numeric values -> int or double + * - "true"/"on" -> boolean true + * - "false"/"off" -> boolean false + * - Other -> string + */ +static inline KzSettingValue makeValue(const std::string &value) +{ + if(value.starts_with('"') || value.starts_with('\'')) + { + return value.substr(1, value.length() - 2); + } + + if(is_numeric(value)) + { + // double + if(value.find('.') != value.npos) + { + return std::stod(value); + } + else + { + return std::stoi(value); + } + } + + // To Lower case + std::string lvalue = value; + std::transform(lvalue.begin(), lvalue.end(), lvalue.begin(), + [](unsigned char c){ return std::tolower(c); }); + + + // bool true + if(lvalue == "true" || lvalue == "on") + { + return true; + } + + // bool false + if(lvalue == "false" || lvalue == "off") + { + return false; + } + + // else, string without quote + return value; +} + +}; + +#endif // KZSETTINGS_H |