#include "singletons.h" #include "config.h" #include "logging.h" #include #include "files.h" #include using namespace std; //TODO: remove MainConfig::MainConfig() { init_home_path(); } void MainConfig::read() { auto config_json = (home/"config"/"config.json").string(); // This causes some redundant copies, but assures windows support try { find_or_create_config_files(); boost::property_tree::json_parser::read_json(config_json, cfg); update_config_file(); retrieve_config(); } catch(const std::exception &e) { Singleton::terminal()->print("Error reading "+config_json + "config.json: "+e.what()+"\n"); std::stringstream ss; ss << configjson; boost::property_tree::read_json(ss, cfg); retrieve_config(); } cfg.clear(); } void MainConfig::find_or_create_config_files() { auto config_dir = home/"config"; auto config_json = config_dir/"config.json"; auto plugins_py = config_dir/"plugins.py"; boost::filesystem::create_directories(config_dir); // io exp captured by calling method if (!boost::filesystem::exists(config_json)) filesystem::write(config_json, configjson); // vars configjson and pluginspy if (!boost::filesystem::exists(plugins_py)) // live in files.h filesystem::write(plugins_py, pluginspy); auto juci_style_path = home/"styles"; boost::filesystem::create_directories(juci_style_path); // io exp captured by calling method juci_style_path/="juci-light.xml"; if(!boost::filesystem::exists(juci_style_path)) filesystem::write(juci_style_path, juci_light_style); juci_style_path=juci_style_path.parent_path(); juci_style_path/="juci-dark.xml"; if(!boost::filesystem::exists(juci_style_path)) filesystem::write(juci_style_path, juci_dark_style); juci_style_path=juci_style_path.parent_path(); juci_style_path/="juci-dark-blue.xml"; if(!boost::filesystem::exists(juci_style_path)) filesystem::write(juci_style_path, juci_dark_blue_style); } void MainConfig::retrieve_config() { auto keybindings_pt = cfg.get_child("keybindings"); for (auto &i : keybindings_pt) { Singleton::Config::menu()->keys[i.first] = i.second.get_value(); } GenerateSource(); GenerateDirectoryFilter(); Singleton::Config::window()->theme_name=cfg.get("gtk_theme.name"); Singleton::Config::window()->theme_variant=cfg.get("gtk_theme.variant"); Singleton::Config::window()->version = cfg.get("version"); Singleton::Config::window()->default_size = {cfg.get("default_window_size.width"), cfg.get("default_window_size.height")}; Singleton::Config::terminal()->make_command=cfg.get("project.make_command"); Singleton::Config::terminal()->cmake_command=cfg.get("project.cmake_command"); Singleton::Config::terminal()->history_size=cfg.get("terminal_history_size"); } bool MainConfig::check_config_file(const boost::property_tree::ptree &default_cfg, std::string parent_path) { if(parent_path.size()>0) parent_path+="."; bool exists=true; for(auto &node: default_cfg) { auto path=parent_path+node.first; try { cfg.get(path); } catch(const std::exception &e) { cfg.add(path, node.second.data()); exists=false; } try { exists&=check_config_file(node.second, path); } catch(const std::exception &e) { } } return exists; } void MainConfig::update_config_file() { boost::property_tree::ptree default_cfg; bool cfg_ok=true; try { if(cfg.get("version")!=JUCI_VERSION) { std::stringstream ss; ss << configjson; boost::property_tree::read_json(ss, default_cfg); cfg_ok=false; if(cfg.count("version")>0) cfg.find("version")->second.data()=default_cfg.get("version"); } else return; } catch(const std::exception &e) { std::cerr << "Error reading json-file: " << e.what() << std::endl; cfg_ok=false; } cfg_ok&=check_config_file(default_cfg); if(!cfg_ok) { boost::property_tree::write_json((home/"config"/"config.json").string(), cfg); } } void MainConfig::GenerateSource() { auto source_cfg = Singleton::Config::source(); auto source_json = cfg.get_child("source"); Singleton::Config::source()->style=source_json.get("style"); source_cfg->font=source_json.get("font"); source_cfg->show_map = source_json.get("show_map"); source_cfg->map_font_size = source_json.get("map_font_size"); source_cfg->spellcheck_language = source_json.get("spellcheck_language"); source_cfg->default_tab_char = source_json.get("default_tab_char"); source_cfg->default_tab_size = source_json.get("default_tab_size"); source_cfg->auto_tab_char_and_size = source_json.get("auto_tab_char_and_size"); source_cfg->wrap_lines = source_json.get("wrap_lines"); source_cfg->highlight_current_line = source_json.get("highlight_current_line"); source_cfg->show_line_numbers = source_json.get("show_line_numbers"); for (auto &i : source_json.get_child("clang_types")) source_cfg->clang_types[i.first] = i.second.get_value(); source_cfg->clang_format_style = source_json.get("clang_format_style"); auto pt_doc_search=cfg.get_child("documentation_searches"); for(auto &pt_doc_search_lang: pt_doc_search) { source_cfg->documentation_searches[pt_doc_search_lang.first].separator=pt_doc_search_lang.second.get("separator"); auto &queries=source_cfg->documentation_searches.find(pt_doc_search_lang.first)->second.queries; for(auto &i: pt_doc_search_lang.second.get_child("queries")) { queries[i.first]=i.second.get_value(); } } } void MainConfig::GenerateDirectoryFilter() { auto dir_cfg=Singleton::Config::directories(); boost::property_tree::ptree dir_json = cfg.get_child("directoryfilter"); boost::property_tree::ptree ignore_json = dir_json.get_child("ignore"); boost::property_tree::ptree except_json = dir_json.get_child("exceptions"); for ( auto &i : except_json ) dir_cfg->exceptions.emplace_back(i.second.get_value()); for ( auto &i : ignore_json ) dir_cfg->ignored.emplace_back(i.second.get_value()); } void MainConfig::init_home_path(){ std::vector locations = JUCI_ENV_SEARCH_LOCATIONS; char *ptr = nullptr; for (auto &env : locations) { ptr=std::getenv(env.c_str()); if (ptr==nullptr) continue; else if (boost::filesystem::exists(ptr)) { home /= ptr; home /= ".juci"; break; } } if(home.empty()) { std::string searched_envs = "["; for(auto &env : locations) searched_envs+=env+", "; searched_envs.erase(searched_envs.end()-2, searched_envs.end()); searched_envs+="]"; throw std::runtime_error("One of these environment variables needs to point to a writable directory to save configuration: " + searched_envs); } return; }