#pragma once #include #include #include #include #include #include "sane/sane_ex.h" #include "sane/sane_option_definitions.h" #include "json.h" #define IS_DOUBLE_EQUAL(a, b) fabs((a) - (b)) < .00001 typedef struct _opt_val { std::string name; std::string type; std::string val; bool operator==(const struct _opt_val& r) { if(name != r.name) return false; if(type == "float") { return IS_DOUBLE_EQUAL(atof(val.c_str()), atof(r.val.c_str())); } else { return val == r.val; } } bool operator==(const std::string& n) { return name == n; } }OPTVAL; typedef struct _opt_scheme { std::string name; // scheme name std::vector opts; bool operator==(const std::string& n) { return name == n; } bool operator==(const struct _opt_scheme& r) { if(opts.size() != r.opts.size()) return false; bool equal = true; for(size_t i = 0; i < r.opts.size(); ++i) { std::vector::iterator it = std::find(opts.begin(), opts.end(), r.opts[i].name); if(it == opts.end() || r.opts[i].val != it->val) { equal = false; break; } } return equal; } }OPTSCHEME; typedef struct _dev_configs { std::string name; // device name int cur_scheme; // -1 is none user scheme applied, and points to the default setting which at first in 'schemes' std::vector schemes; // NOTE: the first is always the default setting, and (cur_scheme + 1) is the user customizing setting, -1 is the default setting bool operator==(const std::string& n) { return name == n; } _dev_configs() { OPTSCHEME none; none.name = "\351\273\230\350\256\244\350\256\276\347\275\256"; // "默认设置"; schemes.push_back(none); cur_scheme = -1; } OPTSCHEME* get_current(void) { if(cur_scheme >= 0 && cur_scheme + 1 < (int)schemes.size()) return &schemes[cur_scheme + 1]; else return nullptr; } OPTSCHEME* select(const std::string& name) { std::vector::iterator it = std::find(schemes.begin(), schemes.end(), name); if(it == schemes.end()) return nullptr; cur_scheme = it - schemes.begin() - 1; return &(*it); } }DEVCFG; // // { // "G100" : [ // { // "scheme": "color-A4R", // "opts": [ // { // "name": "color-mode", // "type": "string", // "value": "24-bits", // "init": "24-bits" // }, // { // "name": "paper", // "type": "string", // "value": "A4R" // "init": "A4" // }], // }], // // "G200" : [ ... ] // // } // class config { QSettings *ini_; QString file_; gb::json *schem_jsn_; QString get_scanner_config_file(void); void reload_schemes(void); public: config(); ~config(); static QString self_path(void); // without last '/' static std::string read_mini_file(QString file); static std::string device_to_config_dev_name(QString& dev_name); static int save_2_file(QString file, const void* buf, size_t l); static int find_config(QString dev_name, std::vector& cfgs); static bool is_accessible_file(const std::string& path_file); static void to_lower(std::string& str); static bool load_custom_gamma(const char* file, SANE_Gamma* gamma); public: int load(QString file = ""); QString get_val(QString sec_name, QString key, QString def_val = ""); QString get_file(void); void load_all_scanner_configs(std::vector& cfgs); void load_scanner_configs(QString dev_name, DEVCFG* cfg); int save_scanner_configs(const DEVCFG* cfg); };