diff --git a/src/cli/main.cpp b/src/cli/main.cpp index fb827c8..87d28cd 100644 --- a/src/cli/main.cpp +++ b/src/cli/main.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -35,16 +36,17 @@ int handle_apply_theme(const argparse::ArgumentParser &program, const std::strin { clrsync::core::theme_renderer renderer; std::string theme_identifier; + clrsync::core::Result result = clrsync::core::Ok(); if (program.is_used("--theme")) { theme_identifier = program.get("--theme"); - renderer.apply_theme(theme_identifier); + result = renderer.apply_theme(theme_identifier); } else if (program.is_used("--path")) { theme_identifier = program.get("--path"); - renderer.apply_theme_from_path(theme_identifier); + result = renderer.apply_theme_from_path(theme_identifier); } else { @@ -54,17 +56,23 @@ int handle_apply_theme(const argparse::ArgumentParser &program, const std::strin return 1; } theme_identifier = default_theme; - renderer.apply_theme(theme_identifier); + result = renderer.apply_theme(theme_identifier); + } + + if (!result) + { + std::cerr << "Failed to apply theme: " << result.error().description() << std::endl; + return 1; } std::cout << "Applied theme " << theme_identifier << std::endl; return 0; } -void initialize_config(const std::string &config_path) +clrsync::core::Result initialize_config(const std::string &config_path) { auto conf = std::make_unique(config_path); - clrsync::core::config::instance().initialize(std::move(conf)); + return clrsync::core::config::instance().initialize(std::move(conf)); } void setup_argument_parser(argparse::ArgumentParser &program) @@ -103,13 +111,10 @@ int main(int argc, char *argv[]) std::string config_path = program.get("--config"); - try + auto config_result = initialize_config(config_path); + if (!config_result) { - initialize_config(config_path); - } - catch (const std::exception &err) - { - std::cerr << "Error loading config: " << err.what() << std::endl; + std::cerr << "Error loading config: " << config_result.error().description() << std::endl; return 1; } diff --git a/src/core/config/config.cpp b/src/core/config/config.cpp index b456bcc..3578175 100644 --- a/src/core/config/config.cpp +++ b/src/core/config/config.cpp @@ -1,10 +1,10 @@ #include "config.hpp" #include "core/utils.hpp" +#include "core/error.hpp" #include #include #include -#include #ifdef _WIN32 #include "windows.h" @@ -19,14 +19,18 @@ config &config::instance() return inst; } -void config::initialize(std::unique_ptr file) +Result config::initialize(std::unique_ptr file) { copy_default_configs(); m_file = std::move(file); if (!m_file) - throw std::runtime_error{"Config file is missing"}; - if (!m_file->parse()) - throw std::runtime_error{"Could not parse config file"}; + return Err(error_code::config_missing, "Config file is missing"); + + auto parse_result = m_file->parse(); + if (!parse_result) + return Err(error_code::config_invalid, parse_result.error().message, parse_result.error().context); + + return Ok(); } std::filesystem::path config::get_user_config_dir() @@ -65,19 +69,13 @@ void config::copy_file(const std::filesystem::path &src, const std::filesystem:: return; if (!std::filesystem::exists(src)) - { - std::cerr << "Warning: Source file does not exist: " << src << std::endl; return; - } std::ifstream in(src, std::ios::binary); std::ofstream out(dst, std::ios::binary); if (!in || !out) - { - std::cerr << "Warning: Failed to copy file from " << src << " to " << dst << std::endl; return; - } out << in.rdbuf(); } @@ -85,10 +83,7 @@ void config::copy_file(const std::filesystem::path &src, const std::filesystem:: void config::copy_dir(const std::filesystem::path &src, const std::filesystem::path &dst) { if (!std::filesystem::exists(src)) - { - std::cerr << "Warning: Source directory does not exist: " << src << std::endl; return; - } for (auto const &entry : std::filesystem::recursive_directory_iterator(src)) { @@ -114,10 +109,7 @@ void config::copy_default_configs() std::filesystem::create_directories(user_dir); if (system_dir.empty()) - { - std::cerr << "Warning: No system data directory found, skipping default config copy\n"; return; - } { auto src = system_dir / "config.toml"; @@ -175,50 +167,53 @@ const uint32_t config::font_size() const return 14; } -void config::set_default_theme(const std::string &theme) +Result config::set_default_theme(const std::string &theme) { - if (m_file) - { - m_file->set_value("general", "default_theme", theme); - m_file->save_file(); - } + if (!m_file) + return Err(error_code::config_missing, "Configuration not initialized"); + + m_file->set_value("general", "default_theme", theme); + return m_file->save_file(); } -void config::set_palettes_path(const std::string &path) +Result config::set_palettes_path(const std::string &path) { - if (m_file) - { - m_file->set_value("general", "palettes_path", path); - m_file->save_file(); - } + if (!m_file) + return Err(error_code::config_missing, "Configuration not initialized"); + + m_file->set_value("general", "palettes_path", path); + return m_file->save_file(); } -void config::set_font(const std::string &font) +Result config::set_font(const std::string &font) { - if (m_file) - { - m_file->set_value("general", "font", font); - m_file->save_file(); - } + if (!m_file) + return Err(error_code::config_missing, "Configuration not initialized"); + + m_file->set_value("general", "font", font); + return m_file->save_file(); } -void config::set_font_size(int font_size) +Result config::set_font_size(int font_size) { - if (m_file) - { - m_file->set_value("general", "font_size", font_size); - m_file->save_file(); - } + if (!m_file) + return Err(error_code::config_missing, "Configuration not initialized"); + + m_file->set_value("general", "font_size", font_size); + return m_file->save_file(); } -void config::update_template(const std::string &key, +Result config::update_template(const std::string &key, const clrsync::core::theme_template &theme_template) { + if (!m_file) + return Err(error_code::config_missing, "Configuration not initialized"); + m_themes[key] = theme_template; m_file->set_value("templates." + key, "input_path", theme_template.template_path()); m_file->set_value("templates." + key, "output_path", theme_template.output_path()); m_file->set_value("templates." + key, "enabled", theme_template.enabled()); m_file->set_value("templates." + key, "reload_cmd", theme_template.reload_command()); - m_file->save_file(); + return m_file->save_file(); } const std::unordered_map config::templates() @@ -241,21 +236,21 @@ const std::unordered_map config::tem theme.set_enabled(false); } theme.set_reload_command(std::get(current["reload_cmd"])); - theme.load_template(); + (void)theme.load_template(); m_themes.insert({theme.name(), theme}); } } return m_themes; } -const clrsync::core::theme_template &config::template_by_name(const std::string &name) const +Result config::template_by_name(const std::string &name) const { auto it = m_themes.find(name); if (it != m_themes.end()) { - return it->second; + return Ok(&it->second); } - throw std::runtime_error("Template not found: " + name); + return Err(error_code::template_not_found, "Template not found", name); } } // namespace clrsync::core diff --git a/src/core/config/config.hpp b/src/core/config/config.hpp index 1858a8d..a53d16f 100644 --- a/src/core/config/config.hpp +++ b/src/core/config/config.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -14,23 +15,23 @@ class config public: static config &instance(); - void initialize(std::unique_ptr file); + Result initialize(std::unique_ptr file); const std::string font() const; const uint32_t font_size() const; const std::string &palettes_path(); const std::string default_theme() const; const std::unordered_map templates(); - const clrsync::core::theme_template &template_by_name(const std::string &name) const; + Result template_by_name(const std::string &name) const; std::filesystem::path get_user_config_dir(); - void set_default_theme(const std::string &theme); - void set_palettes_path(const std::string &path); - void set_font(const std::string &font); - void set_font_size(int font_size); + Result set_default_theme(const std::string &theme); + Result set_palettes_path(const std::string &path); + Result set_font(const std::string &font); + Result set_font_size(int font_size); - void update_template(const std::string &key, + Result update_template(const std::string &key, const clrsync::core::theme_template &theme_template); static std::filesystem::path get_data_dir(); diff --git a/src/core/error.hpp b/src/core/error.hpp new file mode 100644 index 0000000..0833417 --- /dev/null +++ b/src/core/error.hpp @@ -0,0 +1,207 @@ +#ifndef CLRSYNC_CORE_ERROR_HPP +#define CLRSYNC_CORE_ERROR_HPP + +#include +#include +#include + +namespace clrsync::core +{ + +enum class error_code +{ + unknown, + + file_not_found, + file_open_failed, + file_write_failed, + file_read_failed, + dir_create_failed, + + parse_failed, + invalid_format, + + config_missing, + config_invalid, + + template_not_found, + template_load_failed, + template_apply_failed, + + palette_not_found, + palette_load_failed, + + init_failed, + invalid_arg, + resource_missing, +}; + +inline const char* error_code_string(error_code code) +{ + switch (code) + { + case error_code::unknown: return "Unknown error"; + case error_code::file_not_found: return "File not found"; + case error_code::file_open_failed: return "Failed to open file"; + case error_code::file_write_failed: return "Failed to write file"; + case error_code::file_read_failed: return "Failed to read file"; + case error_code::dir_create_failed: return "Failed to create directory"; + case error_code::parse_failed: return "Parse failed"; + case error_code::invalid_format: return "Invalid format"; + case error_code::config_missing: return "Configuration missing"; + case error_code::config_invalid: return "Configuration invalid"; + case error_code::template_not_found: return "Template not found"; + case error_code::template_load_failed: return "Failed to load template"; + case error_code::template_apply_failed: return "Failed to apply template"; + case error_code::palette_not_found: return "Palette not found"; + case error_code::palette_load_failed: return "Failed to load palette"; + case error_code::init_failed: return "Initialization failed"; + case error_code::invalid_arg: return "Invalid argument"; + case error_code::resource_missing: return "Resource missing"; + default: return "Unknown error code"; + } +} + +struct Error +{ + error_code code; + std::string message; + std::string context; + + Error(error_code c) : code(c), message(error_code_string(c)) {} + + Error(error_code c, std::string msg) + : code(c), message(std::move(msg)) {} + + Error(error_code c, std::string msg, std::string ctx) + : code(c), message(std::move(msg)), context(std::move(ctx)) {} + + std::string description() const + { + if (context.empty()) + return message; + return message + " [" + context + "]"; + } +}; + +template +class [[nodiscard]] Result +{ +private: + std::variant m_data; + +public: + Result(T value) : m_data(std::move(value)) {} + + Result(Error error) : m_data(std::move(error)) {} + + bool is_ok() const { return std::holds_alternative(m_data); } + + bool is_error() const { return std::holds_alternative(m_data); } + + explicit operator bool() const { return is_ok(); } + + T& value() & { return std::get(m_data); } + const T& value() const & { return std::get(m_data); } + T&& value() && { return std::get(std::move(m_data)); } + + const Error& error() const { return std::get(m_data); } + + T value_or(T default_value) const + { + return is_ok() ? std::get(m_data) : std::move(default_value); + } + + std::optional ok() const + { + if (is_ok()) + return std::get(m_data); + return std::nullopt; + } + + std::optional err() const + { + if (is_error()) + return std::get(m_data); + return std::nullopt; + } + + template + auto map(F&& func) -> Result()))> + { + using U = decltype(func(std::declval())); + if (is_ok()) + return Result(func(std::get(m_data))); + return Result(std::get(m_data)); + } + + template + auto and_then(F&& func) -> decltype(func(std::declval())) + { + if (is_ok()) + return func(std::get(m_data)); + using ResultType = decltype(func(std::declval())); + return ResultType(std::get(m_data)); + } +}; + +template<> +class [[nodiscard]] Result +{ +private: + std::optional m_error; + +public: + Result() : m_error(std::nullopt) {} + + Result(Error error) : m_error(std::move(error)) {} + + bool is_ok() const { return !m_error.has_value(); } + + bool is_error() const { return m_error.has_value(); } + + explicit operator bool() const { return is_ok(); } + + const Error& error() const { return *m_error; } + + std::optional err() const { return m_error; } +}; + +template +Result Ok(T value) +{ + return Result(std::move(value)); +} + +inline Result Ok() +{ + return Result(); +} + +template +Result Err(Error error) +{ + return Result(std::move(error)); +} + +template +Result Err(error_code code) +{ + return Result(Error(code)); +} + +template +Result Err(error_code code, std::string message) +{ + return Result(Error(code, std::move(message))); +} + +template +Result Err(error_code code, std::string message, std::string context) +{ + return Result(Error(code, std::move(message), std::move(context))); +} + +} // namespace clrsync::core + +#endif // CLRSYNC_CORE_ERROR_HPP diff --git a/src/core/io/file.hpp b/src/core/io/file.hpp index 1f36a57..96d910c 100644 --- a/src/core/io/file.hpp +++ b/src/core/io/file.hpp @@ -4,6 +4,7 @@ #include #include #include +#include using value_type = std::variant; @@ -14,7 +15,8 @@ class file public: file() = default; file(std::string path) {}; - virtual bool parse() { return false; }; + virtual ~file() = default; + virtual Result parse() { return Ok(); }; virtual const std::string get_string_value(const std::string §ion, const std::string &key) const { @@ -39,7 +41,7 @@ class file } virtual void insert_or_update_value(const std::string §ion, const std::string &key, const value_type &value) {}; - virtual void save_file() {}; + virtual Result save_file() { return Ok(); }; }; } // namespace clrsync::core::io #endif \ No newline at end of file diff --git a/src/core/io/toml_file.cpp b/src/core/io/toml_file.cpp index d41713a..5c1afe0 100644 --- a/src/core/io/toml_file.cpp +++ b/src/core/io/toml_file.cpp @@ -11,12 +11,13 @@ toml_file::toml_file(std::string path) m_path = expand_user(path); } -bool toml_file::parse() +Result toml_file::parse() { if (!std::filesystem::exists(m_path)) - return false; + return Err(error_code::file_not_found, "File does not exist", m_path); + m_file = toml::parse_file(m_path); - return true; + return Ok(); } const std::string toml_file::get_string_value(const std::string §ion, @@ -91,11 +92,23 @@ void toml_file::insert_or_update_value(const std::string §ion, const std::st std::visit([&](auto &&v) { tbl->insert_or_assign(key, v); }, value); } -void toml_file::save_file() +Result toml_file::save_file() { - std::filesystem::create_directories(std::filesystem::path(m_path).parent_path()); + try { + std::filesystem::create_directories(std::filesystem::path(m_path).parent_path()); + } catch (const std::exception& e) { + return Err(error_code::dir_create_failed, e.what(), m_path); + } + std::ofstream stream(m_path, std::ios::binary); + if (!stream) + return Err(error_code::file_write_failed, "Failed to open file for writing", m_path); + stream << m_file; + if (!stream) + return Err(error_code::file_write_failed, "Failed to write to file", m_path); + + return Ok(); } std::vector toml_file::split(const std::string &s, char delim) const diff --git a/src/core/io/toml_file.hpp b/src/core/io/toml_file.hpp index f62a5dc..a2f1c65 100644 --- a/src/core/io/toml_file.hpp +++ b/src/core/io/toml_file.hpp @@ -1,6 +1,7 @@ #ifndef CLRSYNC_CORE_IO_TOML_FILE_HPP #define CLRSYNC_CORE_IO_TOML_FILE_HPP #include +#include #include #include @@ -10,7 +11,7 @@ class toml_file : public file { public: explicit toml_file(std::string path); - bool parse() override; + Result parse() override; const std::string get_string_value(const std::string §ion, const std::string &key) const override; uint32_t get_uint_value(const std::string §ion, const std::string &key) const override; @@ -18,7 +19,7 @@ class toml_file : public file std::map get_table(const std::string §ion_path) const override; void insert_or_update_value(const std::string §ion, const std::string &key, const value_type &value) override; - void save_file() override; + Result save_file() override; private: toml::parse_result m_file{}; diff --git a/src/core/palette/palette_file.hpp b/src/core/palette/palette_file.hpp index 5c64568..476890f 100644 --- a/src/core/palette/palette_file.hpp +++ b/src/core/palette/palette_file.hpp @@ -52,7 +52,7 @@ template class palette_file } void save() { - m_file->save_file(); + (void)m_file->save_file(); } private: diff --git a/src/core/palette/palette_manager.hpp b/src/core/palette/palette_manager.hpp index 5e4a532..5df0e7c 100644 --- a/src/core/palette/palette_manager.hpp +++ b/src/core/palette/palette_manager.hpp @@ -21,10 +21,7 @@ template class palette_manager { auto directory_path_expanded = expand_user(directory_path); if (!std::filesystem::exists(directory_path_expanded)) - { - std::cerr << "Palettes directory does not exist\n" ; return; - } for (const auto &entry : std::filesystem::directory_iterator(directory_path_expanded)) { if (entry.is_regular_file()) diff --git a/src/core/theme/theme_renderer.hpp b/src/core/theme/theme_renderer.hpp index 1b5e53b..4c052f9 100644 --- a/src/core/theme/theme_renderer.hpp +++ b/src/core/theme/theme_renderer.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace clrsync::core @@ -18,38 +19,52 @@ template class theme_renderer m_template_manager = template_manager(); } - void apply_theme(const std::string &theme_name) + Result apply_theme(const std::string &theme_name) { auto palette = m_pal_manager.get_palette(theme_name); if (!palette) - throw std::runtime_error("Palette not found: " + theme_name); - apply_palette_to_all_templates(*palette); + return Err(error_code::palette_not_found, "Palette not found", theme_name); + return apply_palette_to_all_templates(*palette); } - void apply_theme_from_path(const std::string &path) + + Result apply_theme_from_path(const std::string &path) { auto palette = m_pal_manager.load_palette_from_file(path); - apply_palette_to_all_templates(palette); + return apply_palette_to_all_templates(palette); } private: palette_manager m_pal_manager; template_manager m_template_manager; - void apply_palette_to_all_templates(const palette &pal) + Result apply_palette_to_all_templates(const palette &pal) { for (auto &t_pair : m_template_manager.templates()) { auto &tmpl = t_pair.second; if (!tmpl.enabled()) continue; - tmpl.load_template(); + + auto load_result = tmpl.load_template(); + if (!load_result) + return load_result; + tmpl.apply_palette(pal); - tmpl.save_output(); + + auto save_result = tmpl.save_output(); + if (!save_result) + return save_result; + if (!tmpl.reload_command().empty()) { - std::system(tmpl.reload_command().c_str()); + int result = std::system(tmpl.reload_command().c_str()); + if (result != 0) + { + std::cerr << "Warning: Command " << tmpl.reload_command() << " failed with code " << result << "\n"; + } } } + return Ok(); } }; diff --git a/src/core/theme/theme_template.cpp b/src/core/theme/theme_template.cpp index a51458a..ac18aca 100644 --- a/src/core/theme/theme_template.cpp +++ b/src/core/theme/theme_template.cpp @@ -43,21 +43,21 @@ void theme_template::set_output_path(const std::string &path) m_output_path = expand_user(path); } -void theme_template::load_template() +Result theme_template::load_template() { if (!std::filesystem::exists(m_template_path)) { - std::cerr << "Warning: Template file '" << m_template_path << "' is missing\n"; - return; + return Err(error_code::template_not_found, "Template file is missing", m_template_path); } + std::ifstream input(m_template_path, std::ios::binary); if (!input) { - std::cerr << "Warning: Failed to open template file: " << m_template_path << std::endl; - return; + return Err(error_code::template_load_failed, "Failed to open template file", m_template_path); } m_template_data.assign(std::istreambuf_iterator(input), std::istreambuf_iterator()); + return Ok(); } void theme_template::apply_palette(const core::palette &palette) @@ -90,7 +90,7 @@ void theme_template::apply_palette(const core::palette &palette) } } -void theme_template::save_output() const +Result theme_template::save_output() const { try { @@ -98,18 +98,22 @@ void theme_template::save_output() const } catch (const std::exception& e) { - std::cerr << "Warning: Failed to create output directory for " << m_output_path << ": " << e.what() << std::endl; - return; + return Err(error_code::dir_create_failed, e.what(), m_output_path); } std::ofstream output(m_output_path, std::ios::binary); if (!output) { - std::cerr << "Warning: Failed to write output file: " << m_output_path << std::endl; - return; + return Err(error_code::file_write_failed, "Failed to open output file for writing", m_output_path); } output << m_processed_data; + if (!output) + { + return Err(error_code::file_write_failed, "Failed to write to output file", m_output_path); + } + + return Ok(); } const std::string &theme_template::raw_template() const diff --git a/src/core/theme/theme_template.hpp b/src/core/theme/theme_template.hpp index 2b067e5..50aaf40 100644 --- a/src/core/theme/theme_template.hpp +++ b/src/core/theme/theme_template.hpp @@ -2,6 +2,7 @@ #define clrsync_CORE_IO_THEME_TEMPLATE_HPP #include +#include #include namespace clrsync::core @@ -26,11 +27,11 @@ class theme_template void set_output_path(const std::string &path); - void load_template(); + Result load_template(); void apply_palette(const core::palette &palette); - void save_output() const; + Result save_output() const; const std::string &raw_template() const; diff --git a/src/gui/main.cpp b/src/gui/main.cpp index 9cdb249..3f497c5 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -7,6 +7,7 @@ #include "core/config/config.hpp" #include "core/io/toml_file.hpp" #include "core/utils.hpp" +#include "core/error.hpp" #include "color_scheme_editor.hpp" #include "gui/font_loader.hpp" @@ -21,13 +22,10 @@ int main(int, char**) auto config_path = clrsync::core::get_default_config_path(); auto conf = std::make_unique(config_path); - try + auto init_result = clrsync::core::config::instance().initialize(std::move(conf)); + if (!init_result) { - clrsync::core::config::instance().initialize(std::move(conf)); - } - catch (const std::exception& e) - { - std::cerr << "Fatal error: " << e.what() << std::endl; + std::cerr << "Fatal error: " << init_result.error().description() << std::endl; std::cerr << "Hint: Set CLRSYNC_CONFIG_PATH environment variable or ensure config exists at: " << config_path << std::endl; return 1; } diff --git a/src/gui/palette_controller.cpp b/src/gui/palette_controller.cpp index 7f64651..de27253 100644 --- a/src/gui/palette_controller.cpp +++ b/src/gui/palette_controller.cpp @@ -10,10 +10,12 @@ palette_controller::palette_controller() if (m_palettes.empty()) return; - - try { - m_current_palette = m_palettes[clrsync::core::config::instance().default_theme()]; - } catch (...) { + + auto default_theme = clrsync::core::config::instance().default_theme(); + auto it = m_palettes.find(default_theme); + if (it != m_palettes.end()) { + m_current_palette = it->second; + } else { m_current_palette = m_palettes.begin()->second; } } @@ -54,7 +56,7 @@ void palette_controller::delete_current_palette() void palette_controller::apply_current_theme() const { clrsync::core::theme_renderer theme_renderer; - theme_renderer.apply_theme(m_current_palette.name()); + (void)theme_renderer.apply_theme(m_current_palette.name()); } void palette_controller::set_color(const std::string& key, const clrsync::core::color& color) diff --git a/src/gui/settings_window.cpp b/src/gui/settings_window.cpp index 122ebb0..7e4a8c7 100644 --- a/src/gui/settings_window.cpp +++ b/src/gui/settings_window.cpp @@ -1,5 +1,6 @@ #include "settings_window.hpp" #include "core/config/config.hpp" +#include "core/error.hpp" #include "gui/font_loader.hpp" #include "imgui.h" #include @@ -119,83 +120,85 @@ void settings_window::render() void settings_window::load_settings() { - try - { - auto& cfg = clrsync::core::config::instance(); - - std::string default_theme = cfg.default_theme(); - strncpy(m_default_theme, default_theme.c_str(), sizeof(m_default_theme) - 1); - m_default_theme[sizeof(m_default_theme) - 1] = '\0'; - - std::string palettes_path = cfg.palettes_path(); - strncpy(m_palettes_path, palettes_path.c_str(), sizeof(m_palettes_path) - 1); - m_palettes_path[sizeof(m_palettes_path) - 1] = '\0'; - - std::string font = cfg.font(); - strncpy(m_font, font.c_str(), sizeof(m_font) - 1); - m_font[sizeof(m_font) - 1] = '\0'; - - m_font_size = cfg.font_size(); - - m_error_message = ""; - } - catch (const std::exception& e) - { - m_error_message = std::string("Failed to load settings: ") + e.what(); - - // Set defaults on error - strncpy(m_default_theme, "dark", sizeof(m_default_theme)); - strncpy(m_palettes_path, "~/.config/clrsync/palettes", sizeof(m_palettes_path)); - strncpy(m_font, "JetBrains Mono Nerd Font", sizeof(m_font)); - m_font_size = 14; - } + auto& cfg = clrsync::core::config::instance(); + + std::string default_theme = cfg.default_theme(); + strncpy(m_default_theme, default_theme.c_str(), sizeof(m_default_theme) - 1); + m_default_theme[sizeof(m_default_theme) - 1] = '\0'; + + std::string palettes_path = cfg.palettes_path(); + strncpy(m_palettes_path, palettes_path.c_str(), sizeof(m_palettes_path) - 1); + m_palettes_path[sizeof(m_palettes_path) - 1] = '\0'; + + std::string font = cfg.font(); + strncpy(m_font, font.c_str(), sizeof(m_font) - 1); + m_font[sizeof(m_font) - 1] = '\0'; + + m_font_size = cfg.font_size(); + + m_error_message = ""; } void settings_window::apply_settings() { - try + auto& cfg = clrsync::core::config::instance(); + + if (strlen(m_default_theme) == 0) { - auto& cfg = clrsync::core::config::instance(); - - if (strlen(m_default_theme) == 0) - { - m_error_message = "Default theme cannot be empty"; - return; - } - - if (strlen(m_palettes_path) == 0) - { - m_error_message = "Palettes path cannot be empty"; - return; - } - - if (strlen(m_font) == 0) - { - m_error_message = "Font cannot be empty"; - return; - } - - if (m_font_size < 8 || m_font_size > 48) - { - m_error_message = "Font size must be between 8 and 48"; - return; - } - - cfg.set_default_theme(m_default_theme); - cfg.set_palettes_path(m_palettes_path); - cfg.set_font(m_font); - cfg.set_font_size(m_font_size); - - - font_loader fn_loader; - auto font = fn_loader.load_font(m_font, m_font_size); - if (font) - ImGui::GetIO().FontDefault = font; - - m_error_message = ""; + m_error_message = "Default theme cannot be empty"; + return; } - catch (const std::exception& e) + + if (strlen(m_palettes_path) == 0) { - m_error_message = std::string("Failed to apply settings: ") + e.what(); + m_error_message = "Palettes path cannot be empty"; + return; } + + if (strlen(m_font) == 0) + { + m_error_message = "Font cannot be empty"; + return; + } + + if (m_font_size < 8 || m_font_size > 48) + { + m_error_message = "Font size must be between 8 and 48"; + return; + } + + auto result1 = cfg.set_default_theme(m_default_theme); + if (!result1) + { + m_error_message = "Failed to set default theme: " + result1.error().description(); + return; + } + + auto result2 = cfg.set_palettes_path(m_palettes_path); + if (!result2) + { + m_error_message = "Failed to set palettes path: " + result2.error().description(); + return; + } + + auto result3 = cfg.set_font(m_font); + if (!result3) + { + m_error_message = "Failed to set font: " + result3.error().description(); + return; + } + + auto result4 = cfg.set_font_size(m_font_size); + if (!result4) + { + m_error_message = "Failed to set font size: " + result4.error().description(); + return; + } + + font_loader fn_loader; + auto font = fn_loader.load_font(m_font, m_font_size); + if (font) + ImGui::GetIO().FontDefault = font; + + m_error_message = ""; } \ No newline at end of file diff --git a/src/gui/template_controller.cpp b/src/gui/template_controller.cpp index 6b1925a..061196f 100644 --- a/src/gui/template_controller.cpp +++ b/src/gui/template_controller.cpp @@ -11,7 +11,7 @@ void template_controller::set_template_enabled(const std::string& key, bool enab auto it = m_templates.find(key); if (it != m_templates.end()) { it->second.set_enabled(enabled); - clrsync::core::config::instance().update_template(key, it->second); + (void)clrsync::core::config::instance().update_template(key, it->second); } } @@ -20,7 +20,7 @@ void template_controller::set_template_output_path(const std::string& key, const auto it = m_templates.find(key); if (it != m_templates.end()) { it->second.set_output_path(path); - clrsync::core::config::instance().update_template(key, it->second); + (void)clrsync::core::config::instance().update_template(key, it->second); } } @@ -29,7 +29,7 @@ void template_controller::set_template_reload_command(const std::string& key, co auto it = m_templates.find(key); if (it != m_templates.end()) { it->second.set_reload_command(cmd); - clrsync::core::config::instance().update_template(key, it->second); + (void)clrsync::core::config::instance().update_template(key, it->second); } } diff --git a/src/gui/template_editor.cpp b/src/gui/template_editor.cpp index 0db0563..150ca3b 100644 --- a/src/gui/template_editor.cpp +++ b/src/gui/template_editor.cpp @@ -343,59 +343,62 @@ void template_editor::save_template() m_validation_error = ""; - try + auto &cfg = clrsync::core::config::instance(); + std::string palettes_path = cfg.palettes_path(); + std::filesystem::path templates_dir = + std::filesystem::path(palettes_path).parent_path() / "templates"; + + if (!std::filesystem::exists(templates_dir)) { - auto &cfg = clrsync::core::config::instance(); - std::string palettes_path = cfg.palettes_path(); - std::filesystem::path templates_dir = - std::filesystem::path(palettes_path).parent_path() / "templates"; + std::filesystem::create_directories(templates_dir); + } - if (!std::filesystem::exists(templates_dir)) + std::filesystem::path template_file; + if (m_is_editing_existing) + { + auto existing_template_result = cfg.template_by_name(trimmed_name); + if (!existing_template_result) { - std::filesystem::create_directories(templates_dir); - } - - std::filesystem::path template_file; - if (m_is_editing_existing) - { - const auto &existing_template = cfg.template_by_name(trimmed_name); - template_file = existing_template.template_path(); - } - else - { - template_file = templates_dir / trimmed_name; - } - - std::string template_content = m_editor.GetText(); - - std::ofstream out(template_file); - if (!out.is_open()) - { - m_validation_error = "Failed to write template file"; + m_validation_error = "Template not found: " + existing_template_result.error().description(); return; } - - out << template_content; - out.close(); - - clrsync::core::theme_template tmpl(trimmed_name, template_file.string(), trimmed_path); - tmpl.set_reload_command(m_reload_command); - tmpl.set_enabled(m_enabled); - - cfg.update_template(trimmed_name, tmpl); - - m_template_name = trimmed_name; - m_output_path = trimmed_path; - m_is_editing_existing = true; - m_saved_content = m_editor.GetText(); - m_has_unsaved_changes = false; - - refresh_templates(); + template_file = existing_template_result.value()->template_path(); } - catch (const std::exception &e) + else { - m_validation_error = std::string("Error saving template: ") + e.what(); + template_file = templates_dir / trimmed_name; } + + std::string template_content = m_editor.GetText(); + + std::ofstream out(template_file); + if (!out.is_open()) + { + m_validation_error = "Failed to write template file"; + return; + } + + out << template_content; + out.close(); + + clrsync::core::theme_template tmpl(trimmed_name, template_file.string(), trimmed_path); + tmpl.set_reload_command(m_reload_command); + tmpl.set_enabled(m_enabled); + + auto result = cfg.update_template(trimmed_name, tmpl); + if (!result) + { + m_validation_error = "Error saving template: " + result.error().description(); + return; + } + + m_template_name = trimmed_name; + m_output_path = trimmed_path; + m_is_editing_existing = true; + m_saved_content = m_editor.GetText(); + m_has_unsaved_changes = false; + + refresh_templates(); } void template_editor::load_template(const std::string &name) @@ -413,27 +416,24 @@ void template_editor::load_template(const std::string &name) m_is_editing_existing = true; m_validation_error = ""; - try + std::ifstream in(tmpl.template_path()); + if (in.is_open()) { - std::ifstream in(tmpl.template_path()); - if (in.is_open()) + std::string content; + std::string line; + while (std::getline(in, line)) { - std::string content; - std::string line; - while (std::getline(in, line)) - { - content += line + "\n"; - } - in.close(); - - m_editor.SetText(content); - m_saved_content = content; - m_has_unsaved_changes = false; + content += line + "\n"; } + in.close(); + + m_editor.SetText(content); + m_saved_content = content; + m_has_unsaved_changes = false; } - catch (const std::exception &e) + else { - m_validation_error = std::string("Error loading template: ") + e.what(); + m_validation_error = "Error loading template: Failed to open file"; } } }