2023-09-08 09:42:40 +00:00
|
|
|
|
//
|
|
|
|
|
// device_opt: option manager of device
|
|
|
|
|
//
|
|
|
|
|
// Created: 2023-09-07
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <sane/sane_ex.h>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
|
|
#include "simple_logic.h"
|
|
|
|
|
#include <json/gb_json.h>
|
|
|
|
|
|
2023-09-21 08:11:58 +00:00
|
|
|
|
enum opt_visible_level // "visible" field
|
|
|
|
|
{
|
|
|
|
|
OPT_VISIBLE_ALL = 0, // visible on ui and accessible
|
|
|
|
|
OPT_VISIBLE_ACCESS, // accessible only
|
|
|
|
|
OPT_VISIBLE_HIDE, // invisible and inaccessible unless user has DEVELOPE privilege
|
|
|
|
|
};
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
class device_option
|
|
|
|
|
{
|
|
|
|
|
gb_json* origin_;
|
|
|
|
|
gb_json* now_;
|
|
|
|
|
std::vector<std::string> master_opts_; // options that value changed will affect others
|
|
|
|
|
std::map<std::string, simple_logic*> slaver_;
|
2023-09-21 03:23:38 +00:00
|
|
|
|
std::function<bool(int)> user_;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
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<std::string, EXPRCALC> compare_; // simple condition compare
|
|
|
|
|
|
|
|
|
|
class condition_value
|
|
|
|
|
{
|
|
|
|
|
typedef struct _cond_val
|
|
|
|
|
{
|
|
|
|
|
simple_logic *logic;
|
|
|
|
|
std::string value;
|
|
|
|
|
}CONDVAL;
|
|
|
|
|
std::vector<CONDVAL> 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<condition_value*> 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<std::string, range_value*> range_value_;
|
2023-09-14 03:28:21 +00:00
|
|
|
|
std::map<std::string, condition_value*> init_value_;
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2023-09-13 03:20:51 +00:00
|
|
|
|
gb_json* group_opt(const char* title);
|
|
|
|
|
bool arrange_raw_json(const char* txt); // create origin_ and re-arrange groups
|
2023-09-08 09:42:40 +00:00
|
|
|
|
void init_depends(gb_json* opt);
|
|
|
|
|
gb_json* copy_opt(gb_json* from);
|
2023-09-14 09:53:17 +00:00
|
|
|
|
bool to_now(bool init, bool* changed);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
|
2023-09-15 09:53:13 +00:00
|
|
|
|
protected:
|
2023-09-08 09:42:40 +00:00
|
|
|
|
static std::string option_value(gb_json* jsn, bool def_val);
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-15 09:53:13 +00:00
|
|
|
|
public:
|
2023-09-21 03:23:38 +00:00
|
|
|
|
device_option(std::function<bool(int)> user_priv = std::function<bool(int)>());
|
2023-09-15 09:53:13 +00:00
|
|
|
|
~device_option();
|
|
|
|
|
|
2023-09-13 03:20:51 +00:00
|
|
|
|
static std::string trans_group(const char* utf8, bool to_title);
|
|
|
|
|
static std::string get_group(int ind, bool title);
|
|
|
|
|
|
2023-09-08 09:42:40 +00:00
|
|
|
|
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
|
|
|
|
|
|
2023-09-15 09:53:13 +00:00
|
|
|
|
int count(void); // return option count
|
|
|
|
|
std::string get_name_by_sane_id(int sane_ind);
|
2023-09-08 09:42:40 +00:00
|
|
|
|
std::string get_option_value_type(const char* name);
|
2023-09-15 09:53:13 +00:00
|
|
|
|
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
|
2023-09-08 09:42:40 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
// "noise-size": {
|
|
|
|
|
// "cat": "base",
|
|
|
|
|
// "group" : "base",
|
|
|
|
|
// "title" : " <20><><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><C5BB>ߴ<EFBFBD>",
|
|
|
|
|
// "desc" : "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫȥ<D2AA><C8A5><EFBFBD>ĺ<EFBFBD>",
|
|
|
|
|
// "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" : "ֽ<>ųߴ<C5B3>",
|
|
|
|
|
// "desc" : "<22><><EFBFBD>ó<EFBFBD>ͼ<EFBFBD><CDBC>С",
|
|
|
|
|
// "ver" : 0,
|
|
|
|
|
// "pos" : 0,
|
|
|
|
|
// "fix-id" : 0,
|
|
|
|
|
// "type" : "string",
|
|
|
|
|
// "unit" : "none",
|
|
|
|
|
// "affect" : 0,
|
|
|
|
|
// "readonly" : false,
|
|
|
|
|
// "visible" : true,
|
|
|
|
|
// "enabled" : false,
|
|
|
|
|
// "size" : 96,
|
|
|
|
|
// "cur" : "ƥ<><C6A5>ԭʼ<D4AD>ߴ<EFBFBD>",
|
|
|
|
|
// "default" : "ƥ<><C6A5>ԭʼ<D4AD>ߴ<EFBFBD>",
|
|
|
|
|
// "range" : ["A3", "8<><38>", {
|
|
|
|
|
// "mode==24λ<34><CEBB>ɫ": "A4" // condition value
|
|
|
|
|
// }, "A4<41><34><EFBFBD><EFBFBD>", "16<31><36>", "16<31><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "A5", "A5<41><35><EFBFBD><EFBFBD>", "A6", "A6<41><36><EFBFBD><EFBFBD>", "B4", "B5", "B5<42><35><EFBFBD><EFBFBD>", "B6", "B6<42><36><EFBFBD><EFBFBD>", "Letter", "Letter<65><72><EFBFBD><EFBFBD>", "Double Letter", "LEGAL", "ƥ<><C6A5>ԭʼ<D4AD>ߴ<EFBFBD>", "<22><><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD>ߴ<EFBFBD><DFB4>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>", "<22><><EFBFBD><EFBFBD>ɨ<EFBFBD><C9A8><EFBFBD>ߴ<EFBFBD>", "<22><><EFBFBD><EFBFBD><EFBFBD>Ծ<EFBFBD>"]
|
|
|
|
|
// }
|
|
|
|
|
//}
|