// // device_opt: option manager of device // // Created: 2023-09-07 // #pragma once #include #include #include #include #include #include "simple_logic.h" #include class device_option { gb_json* origin_; gb_json* now_; std::vector master_opts_; // options that value changed will affect others std::map slaver_; std::function user_; typedef struct _expr_calc { std::string name; std::string val1; std::string val2; bool not_op; bool(*compare)(gb_json*, void* val, void* v1, void* v2); }EXPRCALC; std::map compare_; // simple condition compare class condition_value { typedef struct _cond_val { simple_logic *logic; std::string value; }CONDVAL; std::vector vals_; void clear(void) { for (auto& v : vals_) { if (v.logic) delete v.logic; } vals_.clear(); } public: condition_value() {} ~condition_value() { clear(); } public: bool set_value(gb_json* jsn, const char* type, device_option* parent); // jsn contains only ONE value or its object std::string value(bool(*compare)(const char*, void*), void* param) { for (auto& v : vals_) { if (!v.logic) return v.value; else if (v.logic->value(compare, param)) return v.value; } return ""; } }; class range_value { bool is_range_; // true - range; false - list int val_ind_; std::vector vals_; void clear(void) { for (auto& v : vals_) delete v; vals_.clear(); } public: range_value() : is_range_(false), val_ind_(0) {} ~range_value() { clear(); } public: bool set_value(gb_json* jsn, const char* type, device_option *parent); // jsn contains all range object int count(void) { return vals_.size(); } bool is_range(void) { return is_range_; } // return first element in list-value or min-value of range std::string first_value(bool(*compare)(const char*, void*), void* param) { val_ind_ = 0; if (val_ind_ < count()) return vals_[val_ind_]->value(compare, param); else return ""; } // return next element in list-value or max-value of range std::string next_value(bool(*compare)(const char*, void*), void* param) { if (++val_ind_ < count()) return vals_[val_ind_]->value(compare, param); else return ""; } }; std::map range_value_; std::map init_value_; std::map support_value_; static bool is_equal_b(gb_json* opt, void* val, void* v1, void* v2); static bool is_equal_i(gb_json* opt, void* val, void* v1, void* v2); static bool is_equal_f(gb_json* opt, void* val, void* v1, void* v2); static bool is_equal_s(gb_json* opt, void* val, void* v1, void* v2); static bool is_less_b(gb_json* opt, void* val, void* v1, void* v2); static bool is_less_i(gb_json* opt, void* val, void* v1, void* v2); static bool is_less_f(gb_json* opt, void* val, void* v1, void* v2); static bool is_less_s(gb_json* opt, void* val, void* v1, void* v2); static bool is_great_b(gb_json* opt, void* val, void* v1, void* v2); static bool is_great_i(gb_json* opt, void* val, void* v1, void* v2); static bool is_great_f(gb_json* opt, void* val, void* v1, void* v2); static bool is_great_s(gb_json* opt, void* val, void* v1, void* v2); static bool is_between_b(gb_json* opt, void* val, void* v1, void* v2); static bool is_between_i(gb_json* opt, void* val, void* v1, void* v2); static bool is_between_f(gb_json* opt, void* val, void* v1, void* v2); static bool is_between_s(gb_json* opt, void* val, void* v1, void* v2); static bool is_opt_enabled(gb_json* opt, void* val, void* v1, void* v2); static bool get_equal(const char* type, bool(**f)(gb_json*, void*, void*, void*)); static bool get_less(const char* type, bool(**f)(gb_json*, void*, void*, void*)); static bool get_great(const char* type, bool(**f)(gb_json*, void*, void*, void*)); static bool get_between(const char* type, bool(**f)(gb_json*, void*, void*, void*)); static std::string from_text_value(const char* type, const char* text_val); static bool parse_simple_logic_expression(gb_json* root, const char* expr, std::string* name, EXPRCALC& calc); static void init_condition(const char* expr, void* param); static bool calc_simple_logic_expression(const char* expr, void* param); void clear(void); gb_json* group_opt(const char* title); bool arrange_raw_json(const char* txt); // create origin_ and re-arrange groups void init_depends(gb_json* opt); gb_json* copy_opt(gb_json* from); int visibility(gb_json* jsn); bool to_now(bool init, bool* changed); protected: static std::string option_value(gb_json* jsn, bool def_val); template static condition_value* to_condition_value(gb_json* jsn, const char* key, const char* type, device_option* parent) { condition_value* ret = nullptr; gb_json* child = nullptr; if (!jsn->get_value(key, child)) { T v; jsn->get_value(key, v); child = new gb_json("", v); } ret = new condition_value(); if (!ret->set_value(child, type, parent)) { delete ret; ret = nullptr; } child->release(); return ret; } public: device_option(std::function user_priv = std::function()); ~device_option(); static std::string trans_group(const char* utf8, bool to_title); static std::string get_group(int ind, bool title); public: bool init(const char* opt_json); bool refine_data(const char* name, void* value); // return true if the 'value' is out of range and refined it in the range int update_data(const char* name, void* value); // return scanner_err. name and value would be null if invoked for language changed int count(void); // return option count bool is_auto_restore_default(const char* name); std::string get_name_by_sane_id(int sane_ind); std::string get_option_value_type(const char* name); std::string get_option_value(const char* name, int type/*OPT_VAL_xxx*/, int* size = nullptr); // return whole json-text if name was null std::string get_option_field_string(const char* name, const char* key); std::string get_option_value_type(int sane_ind); std::string get_option_value(int sane_ind, int type/*OPT_VAL_xxx*/, int* size = nullptr); // return whole json-text if name was null }; //{ // "noise-size": { // "cat": "base", // "group" : "base", // "title" : " 噪点优化尺寸", // "desc" : "设置需要去除的黑", // "ver" : 0, // "pos" : 0, // "fix-id" : 0, // "type" : "int", // "unit" : "none", // "affect" : 0, // "readonly" : false, // "visible" : true, // "enabled" : false, // "size" : 4, // "cur" : 10, // "default" : 10, // "range" : { // "min": 1, // "max" : { // "paper==A3": 50, // condition value // "default": 45} , // "step" : 1 // }, // "depend_or": ["is-noise-optimize==true"] // }, // // "paper": { // "cat": "base", // "group" : "base", // "title" : "纸张尺寸", // "desc" : "设置出图大小", // "ver" : 0, // "pos" : 0, // "fix-id" : 0, // "type" : "string", // "unit" : "none", // "affect" : 0, // "readonly" : false, // "visible" : true, // "enabled" : false, // "size" : 96, // "cur" : "匹配原始尺寸", // "default" : "匹配原始尺寸", // "range" : ["A3", "8开", { // "mode==24位彩色": "A4" // condition value // }, "A4横向", "16开", "16开横向", "A5", "A5横向", "A6", "A6横向", "B4", "B5", "B5横向", "B6", "B6横向", "Letter", "Letter横向", "Double Letter", "LEGAL", "匹配原始尺寸", "最大扫描尺寸自动裁切", "最大扫描尺寸", "三联试卷"] // } //}