升级配置文件及设备菜单
This commit is contained in:
parent
da08031499
commit
99fc6f06a5
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -20,8 +20,8 @@
|
|||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CJSON_H
|
||||
#define CJSON_H
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,232 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(WIN32) || defined(_WIN64)
|
||||
#include <Windows.h>
|
||||
#define PATH_SYMBOL "\\"
|
||||
#else
|
||||
#define PATH_SYMBOL "/"
|
||||
#define NULL nullptr
|
||||
#define DWORD_PTR char*
|
||||
#define _countof(a) sizeof(a) / sizeof(a[0])
|
||||
#endif
|
||||
|
||||
#include "cJSON.h"
|
||||
//#include "../../code_device/hgsane/cJSON.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
namespace gb
|
||||
{
|
||||
class scanner_cfg;
|
||||
class refer
|
||||
{
|
||||
volatile long ref_;
|
||||
|
||||
protected:
|
||||
refer();
|
||||
virtual ~refer();
|
||||
|
||||
public:
|
||||
long add_ref(void);
|
||||
long release(void);
|
||||
};
|
||||
|
||||
|
||||
class json : public refer
|
||||
{
|
||||
cJSON *obj_;
|
||||
cJSON *cur_child_;
|
||||
cJSON walk_head_;
|
||||
bool is_array_;
|
||||
|
||||
cJSON* find_sibling(cJSON* first, const char* name, cJSON*** addr);
|
||||
cJSON* find_child(cJSON *parent, std::vector<std::string>& path, bool create, cJSON*** addr = NULL);
|
||||
cJSON* find(const char* path, bool create = false, cJSON*** addr = NULL);
|
||||
|
||||
protected:
|
||||
~json();
|
||||
|
||||
public:
|
||||
json(char* json_txt = 0);
|
||||
|
||||
static std::string to_string(cJSON* root, bool formatted);
|
||||
static std::string get_value_as_string(cJSON* root, bool integer = false);
|
||||
static void free_node_data(cJSON* node);
|
||||
static cJSON* create_element(bool is_array = false);
|
||||
static cJSON* create_element_with_name(const char* name);
|
||||
|
||||
public:
|
||||
bool attach_text(char* json_txt);
|
||||
bool attach_cjson(cJSON* cjson);
|
||||
bool create_empty(bool array = false);
|
||||
void clear(void);
|
||||
std::string to_string(bool formatted);
|
||||
|
||||
// can be path: child/value ...
|
||||
bool get_value(const char* key, bool& val);
|
||||
bool get_value(const char* key, int& val);
|
||||
bool get_value(const char* key, double& val);
|
||||
bool get_value(const char* key, std::string& val);
|
||||
bool get_value(const char* key, json*& val); // caller shoud call "delete" to free the returned object !!!
|
||||
bool get_value_as_string(const char* key, std::string& val, bool integer);
|
||||
bool get_as_array(const char* key, std::vector<std::string>& val);
|
||||
|
||||
bool first_child(std::string& val, std::string* name = NULL);
|
||||
bool next_child(std::string& val, std::string* name = NULL);
|
||||
|
||||
bool set_value(const char* key, bool val);
|
||||
bool set_value(const char* key, int val);
|
||||
bool set_value(const char* key, double val);
|
||||
bool set_value(const char* key, std::string val);
|
||||
bool set_value(const char* key, const char* val);
|
||||
bool set_value(const char* key, json* obj);
|
||||
|
||||
bool change_key(const char* old_key, const char* new_key);
|
||||
bool remove(const char* key);
|
||||
};
|
||||
|
||||
class base64
|
||||
{
|
||||
char base64_ind_[128];
|
||||
char base64_char_[80];
|
||||
char padding_char_;
|
||||
|
||||
bool is_valid_base64_table(const char* table);
|
||||
bool initialize_base64_table(const char* table);
|
||||
|
||||
public:
|
||||
base64();
|
||||
~base64();
|
||||
|
||||
public:
|
||||
bool set_base64_table(const char* table = NULL);
|
||||
std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true);
|
||||
std::string decode(const char* data, size_t bytes);
|
||||
};
|
||||
|
||||
class sane_config_schm : public refer
|
||||
{
|
||||
std::string scheme_name_;
|
||||
scanner_cfg *scanner_;
|
||||
std::string file_;
|
||||
json* jsn_;
|
||||
json* bkp_;
|
||||
json* def_val_;
|
||||
bool in_setting_;
|
||||
std::map<int, std::string> id_name_; // (id, default-val)
|
||||
|
||||
void clear();
|
||||
std::string default_value(const char* name);
|
||||
|
||||
protected:
|
||||
~sane_config_schm();
|
||||
|
||||
public:
|
||||
sane_config_schm(scanner_cfg* scanner = nullptr);
|
||||
|
||||
static std::string opt_data_appendix_;
|
||||
static bool hex(unsigned char ch, unsigned char* val);
|
||||
static bool hex_char(const char* data, unsigned char* val);
|
||||
static std::string to_hex_letter(const char* data, size_t bytes);
|
||||
static std::string from_hex_letter(const char* data, size_t bytes);
|
||||
static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true
|
||||
|
||||
public:
|
||||
sane_config_schm* copy(void);
|
||||
bool load_from_file(const char* file);
|
||||
bool load_from_mem(const char* mem, bool in_b64 = true);
|
||||
bool save_to(const char* file);
|
||||
void set_default_value(int sn, const char* name, const char* val, size_t bytes);
|
||||
void copy_default_value(sane_config_schm* from);
|
||||
bool first_config(std::string& name, std::string& val);
|
||||
bool next_config(std::string& name, std::string& val);
|
||||
bool get_config(const char* name, std::string& val);
|
||||
void begin_setting(bool restore = false);
|
||||
void config_changed(const char* name, const char* val, size_t bytes, bool extra = false);
|
||||
void config_changed(int sn, const char* val, size_t bytes, bool extra = false);
|
||||
void remove_config(const char* name);
|
||||
void set_value(const char* name, const char* val, size_t bytes, bool extra = false);
|
||||
bool has_changed(void);
|
||||
void end_setting(bool cancel);
|
||||
int id_from_name(const char* name);
|
||||
std::string to_text_stream(bool b64 = true, bool with_ver = true);
|
||||
std::string get_version(void);
|
||||
std::string get_scheme_name(void);
|
||||
void set_scheme_name(const char* name);
|
||||
void update(bool(* is_float)(int, void*), void* param, const char*(* t2n)(const char*), std::string* discard = NULL);
|
||||
};
|
||||
|
||||
class scanner_cfg : public refer
|
||||
{
|
||||
// format: in base64
|
||||
//
|
||||
// {
|
||||
// "global": {
|
||||
// "ver": "4.33",
|
||||
// "cur": -1
|
||||
// },
|
||||
// "scheme_1": sane_config_schm*,
|
||||
// "scheme_2": sane_config_schm*,
|
||||
// "scheme_3": sane_config_schm*,
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
std::string path_;
|
||||
std::string scanner_name_; // scanner type: HUAGOSCAN G100 - 0100
|
||||
json *global_; // version, current scheme, ...
|
||||
|
||||
typedef struct _cfg_schm
|
||||
{
|
||||
std::string name;
|
||||
sane_config_schm* schm;
|
||||
|
||||
bool operator==(const char* n)
|
||||
{
|
||||
return name == n;
|
||||
}
|
||||
}CFGSCHM;
|
||||
std::vector<CFGSCHM> schemes_;
|
||||
|
||||
static std::string global_name_;
|
||||
static std::string cur_sel_;
|
||||
static std::string default_setting_name_;
|
||||
|
||||
void clear(void);
|
||||
void init_version(void);
|
||||
void init_select(void);
|
||||
void walk_sibling_schemes(cJSON* first);
|
||||
|
||||
protected:
|
||||
~scanner_cfg();
|
||||
|
||||
public:
|
||||
scanner_cfg();
|
||||
|
||||
typedef struct _update_func
|
||||
{
|
||||
void(* trans_number)(const char* name, std::string& val, void* param);
|
||||
const char* (* title2name)(const char* title, void* param);
|
||||
std::string discard_msg; // update failed items ...
|
||||
void* func_param;
|
||||
}UDF, *LPUDF;
|
||||
static bool update(const char* file, LPUDF func);
|
||||
|
||||
public:
|
||||
int load_file(const char* file);
|
||||
int load_mem(const char* mem);
|
||||
int save(const char* file = nullptr);
|
||||
|
||||
void get_all_schemes(std::vector<std::string>& schemes); // return all schemes name queue, the first is always be 'Default settings'
|
||||
sane_config_schm* get_scheme(const char* scheme_name = nullptr/*return current scheme if was null*/); // call sane_config_schm::release() if not use anymore
|
||||
std::string get_current_scheme_name(void);
|
||||
bool remove_scheme(const char* scheme_name);
|
||||
void remove_all_schemes(void);
|
||||
bool select_scheme(const char* scheme_name);
|
||||
|
||||
sane_config_schm* copy_scheme(const char* cp_from_name); // for UI setting, call release() if not use anymore
|
||||
bool add_scheme(sane_config_schm* schm, const char* name = nullptr);
|
||||
bool rename_scheme(const char* from, const char* to);
|
||||
};
|
||||
};
|
|
@ -1,626 +0,0 @@
|
|||
#include "config.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <QDir>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <QLatin1String>
|
||||
#include <qtextcodec.h>
|
||||
#include <string.h>
|
||||
#include <QCoreApplication>
|
||||
#include "base/HGUtility.h"
|
||||
|
||||
struct
|
||||
|
||||
{
|
||||
|
||||
const char* name;
|
||||
|
||||
const char* title;
|
||||
|
||||
}g_opts[] = { {SANE_STD_OPT_NAME_RESTORE , OPTION_TITLE_HFMRSZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_HELP , OPTION_TITLE_BZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_MULTI_OUT , OPTION_TITLE_DLSC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_MULTI_OUT_TYPE , OPTION_TITLE_DLSCLX}
|
||||
|
||||
, {SANE_STD_OPT_NAME_COLOR_MODE , OPTION_TITLE_YSMS}
|
||||
|
||||
, {SANE_STD_OPT_NAME_BINARY_THRESHOLD , OPTION_TITLE_HBTXYZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_REVERSE_01 , OPTION_TITLE_HBTXFSSC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_FILTER , OPTION_TITLE_HDHHBTX_CSYZQ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_MULTIOUT_RED , OPTION_TITLE_24WCSTX_DLSCCH}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED , OPTION_TITLE_24WCSTX_DTKCH}
|
||||
|
||||
, {SANE_STD_OPT_NAME_ERASE_BACKGROUND , OPTION_TITLE_BJYC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_BKG_COLOR_RANGE , OPTION_TITLE_BJSCFDFW}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SHARPEN , OPTION_TITLE_RHYMH}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_MORR , OPTION_TITLE_QCMW}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_GRID , OPTION_TITLE_CWW}
|
||||
|
||||
, {SANE_STD_OPT_NAME_ERROR_EXTENSION , OPTION_TITLE_CWKS}
|
||||
|
||||
, {SANE_STD_OPT_NAME_NOISE_OPTIMIZE , OPTION_TITLE_HBTXZDYH}
|
||||
|
||||
, {SANE_STD_OPT_NAME_NOISE_SIZE , OPTION_TITLE_ZDYHCC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_PAPER , OPTION_TITLE_ZZCC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA , OPTION_TITLE_ZDYSMQY}
|
||||
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT , OPTION_TITLE_SMQYZCmm}
|
||||
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT , OPTION_TITLE_SMQYYCmm}
|
||||
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_TOP , OPTION_TITLE_SMQYSCmm}
|
||||
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM , OPTION_TITLE_SMQYXCmm}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SIZE_CHECK , OPTION_TITLE_CCJC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_PAGE , OPTION_TITLE_SMYM}
|
||||
|
||||
, {SANE_STD_OPT_NAME_DISCARD_BLANK_SENS , OPTION_TITLE_TGKBYLMD}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RESOLUTION , OPTION_TITLE_FBL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_TIME_TO_SLEEP , OPTION_TITLE_XMSJ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IMAGE_QUALITY , OPTION_TITLE_HZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_EXCHANGE ,OPTION_TITLE_JHZFM}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SPLIT ,OPTION_TITLE_TXCF }
|
||||
|
||||
, {SANE_STD_OPT_NAME_ANTI_SKEW , OPTION_TITLE_ZDJP}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA , OPTION_TITLE_QYSDQX}
|
||||
|
||||
, {SANE_STD_OPT_NAME_GAMMA , OPTION_TITLE_JMZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_BRIGHTNESS , OPTION_TITLE_LDZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_CONTRAST , OPTION_TITLE_DBD}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_PHOTO_MODE , OPTION_TITLE_ZPMS}
|
||||
|
||||
, {SANE_STD_OPT_NAME_ERASE_BLACK_FRAME , OPTION_TITLE_XCHK}
|
||||
|
||||
, {SANE_STD_OPT_NAME_DARK_SAMPLE , OPTION_TITLE_SSYZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_THRESHOLD , OPTION_TITLE_YZ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL , OPTION_TITLE_BJKZDJ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_MARGIN , OPTION_TITLE_BYSJ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_FILL_BKG_MODE , OPTION_TITLE_BJTCFS}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_ANTI_PERMEATE , OPTION_TITLE_FZST}
|
||||
|
||||
, {SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL , OPTION_TITLE_FZSTDJ}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_L , OPTION_TITLE_CKYCZC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L , OPTION_TITLE_ZCCKSSFWZFMBL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_R , OPTION_TITLE_CKYCYC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R , OPTION_TITLE_YCCKSSFWZFMBL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_T , OPTION_TITLE_CKYCSC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T , OPTION_TITLE_SCCKSSFWZFMBL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_B , OPTION_TITLE_CKYCXC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B , OPTION_TITLE_XCCKSSFWZFMBL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_FILL_COLOR , OPTION_TITLE_SCTC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK , OPTION_TITLE_CSBJC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE , OPTION_TITLE_SZTPCL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_CHECK_STAPLE , OPTION_TITLE_ZDJC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SCAN_MODE , OPTION_TITLE_SMZS}
|
||||
|
||||
, {SANE_STD_OPT_NAME_SCAN_COUNT , OPTION_TITLE_SMSL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_TEXT_DIRECTION , OPTION_TITLE_WGFX}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_ROTATE_BKG_180 , OPTION_TITLE_BMXZ180}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR , OPTION_TITLE_ZJJC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_DOG_EAR_SIZE , OPTION_TITLE_ZJDX}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_CHECK_ASKEW , OPTION_TITLE_WXJC}
|
||||
|
||||
, {SANE_STD_OPT_NAME_ASKEW_RANGE , OPTION_TITLE_WXRRD}
|
||||
|
||||
, {SANE_STD_OPT_NAME_FEED_STRENGTH , OPTION_TITLE_FZQD}
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , OPTION_TITLE_ZDFZQD}
|
||||
|
||||
, {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , OPTION_TITLE_JZSBL}
|
||||
|
||||
, {SANE_STD_OPT_NAME_WAIT_TO_SCAN , OPTION_TITLE_DZSM}
|
||||
|
||||
},
|
||||
|
||||
g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // 黑白图像反色输出(正常颜色为:0-黑色;1-白色)
|
||||
|
||||
, {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // 灰度或黑白图像 - 除色
|
||||
|
||||
, {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // 自动搓纸强度
|
||||
|
||||
, {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 搓纸阈值"
|
||||
|
||||
};
|
||||
config::config() : ini_(NULL), file_(""), schem_jsn_(NULL)
|
||||
{
|
||||
}
|
||||
config::~config()
|
||||
{
|
||||
if(ini_)
|
||||
delete ini_;
|
||||
if(schem_jsn_)
|
||||
delete schem_jsn_;
|
||||
}
|
||||
|
||||
QString config::get_scanner_config_file(void)
|
||||
{
|
||||
QString file(get_val("scanner", "schemes"));
|
||||
|
||||
if(file.length() == 0)
|
||||
{
|
||||
HGChar logpath[512] = {0};
|
||||
HGBase_GetConfigPath(logpath, 512);
|
||||
file = strcat(logpath, "scanner.schm");
|
||||
ini_->setValue("schemes", file);
|
||||
}
|
||||
|
||||
if(file[0] != '/')
|
||||
{
|
||||
std::string path(file_.toStdString());
|
||||
path.erase(path.rfind('/') + 1);
|
||||
path += file.toStdString();
|
||||
file = QString::fromStdString(path);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
void config::reload_schemes(void)
|
||||
{
|
||||
if(schem_jsn_)
|
||||
{
|
||||
delete schem_jsn_;
|
||||
schem_jsn_ = NULL;
|
||||
}
|
||||
|
||||
std::string jsntxt(""), org(config::read_mini_file(get_scanner_config_file()));
|
||||
gb::base64 base64;
|
||||
if(org.empty())
|
||||
return;
|
||||
|
||||
jsntxt = base64.decode(org.c_str(), org.length());
|
||||
schem_jsn_ = new gb::json();
|
||||
if(!schem_jsn_->attach_text(&jsntxt[0]))
|
||||
{
|
||||
delete schem_jsn_;
|
||||
schem_jsn_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
QString config::self_path(void)
|
||||
{
|
||||
QString qexePath = QCoreApplication::applicationDirPath();
|
||||
return qexePath;
|
||||
}
|
||||
std::string config::read_mini_file(QString file)
|
||||
{
|
||||
std::string f(file.toStdString()),
|
||||
ret("");
|
||||
FILE* src = fopen(f.c_str(), "rb");
|
||||
|
||||
if(src)
|
||||
{
|
||||
long l = 0;
|
||||
char *buf = NULL;
|
||||
|
||||
fseek(src, 0, SEEK_END);
|
||||
l = ftell(src);
|
||||
fseek(src, 0, SEEK_SET);
|
||||
buf = (char*)malloc(l + 4);
|
||||
memset(buf, 0, l + 4);
|
||||
fread(buf, 1, l, src);
|
||||
fclose(src);
|
||||
ret = buf;
|
||||
free(buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
std::string config::device_to_config_dev_name(QString& dev_name)
|
||||
{
|
||||
std::string name(dev_name.toStdString());
|
||||
size_t pos = name.find(" - ");
|
||||
|
||||
if(pos != std::string::npos)
|
||||
{
|
||||
pos = name.find(" - ", pos + 3); // the first is ' - PID' 2022-10-11
|
||||
if(pos != std::string::npos)
|
||||
name.erase(pos);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
int config::save_2_file(QString file, const void* buf, size_t l)
|
||||
{
|
||||
FILE* dst = fopen(file.toStdString().c_str(), "wb");
|
||||
|
||||
if(!dst)
|
||||
return errno;
|
||||
|
||||
fwrite(buf, 1, l, dst);
|
||||
fclose(dst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int config::find_config(QString dev_name, std::vector<DEVCFG>& cfgs)
|
||||
{
|
||||
std::string name = dev_name.toStdString();
|
||||
int ind = -1;
|
||||
|
||||
for(size_t i = 0; i < cfgs.size(); ++i)
|
||||
{
|
||||
if(cfgs[i].m_originDeviceName == name)
|
||||
{
|
||||
ind = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ind;
|
||||
}
|
||||
bool config::is_accessible_file(const std::string& path_file)
|
||||
{
|
||||
size_t pos = path_file.rfind('.');
|
||||
|
||||
if(pos++ == std::string::npos)
|
||||
return false;
|
||||
|
||||
std::string ext(path_file.substr(pos));
|
||||
|
||||
config::to_lower(ext);
|
||||
|
||||
return (ext == "png" ||
|
||||
ext == "jpg" ||
|
||||
ext == "jpeg" ||
|
||||
ext == "bmp" ||
|
||||
ext == "tif" ||
|
||||
ext == "pdf" ||
|
||||
ext == "png");
|
||||
}
|
||||
void config::to_lower(std::string& str)
|
||||
{
|
||||
for(size_t i = 0; i < str.length(); ++i)
|
||||
{
|
||||
if(str[i] >= 'A' && str[i] <= 'Z')
|
||||
str[i] -= 'A' - 'a';
|
||||
}
|
||||
}
|
||||
bool config::load_custom_gamma(const char* file, SANE_Gamma* gamma)
|
||||
{
|
||||
bool ret = false;
|
||||
FILE* src = fopen(file, "rb");
|
||||
if(src)
|
||||
{
|
||||
long l = 0;
|
||||
SANE_Gamma tmp = {0};
|
||||
fseek(src, 0, SEEK_END);
|
||||
l = ftell(src);
|
||||
fseek(src, 0, SEEK_SET);
|
||||
if(l == sizeof(SANE_Gamma) &&
|
||||
fread(&tmp, l, 1, src) == 1)
|
||||
{
|
||||
if( tmp.pt_count >= 0 && tmp.pt_count <= sizeof (tmp.keypoint) / sizeof(tmp.keypoint[0]) &&
|
||||
tmp.pt_count_r >= 0 && tmp.pt_count_r <= sizeof (tmp.keypoint_r) / sizeof(tmp.keypoint_r[0]) &&
|
||||
tmp.pt_count_g >= 0 && tmp.pt_count_g <= sizeof (tmp.keypoint_g) / sizeof(tmp.keypoint_g[0]) &&
|
||||
tmp.pt_count_b >= 0 && tmp.pt_count_b <= sizeof (tmp.keypoint_b) / sizeof(tmp.keypoint_b[0]))
|
||||
{
|
||||
memcpy(gamma, &tmp, l);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
fclose(src);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int config::load(QString file)
|
||||
{
|
||||
if(ini_)
|
||||
delete ini_;
|
||||
ini_ = NULL;
|
||||
|
||||
if(file.length() == 0)
|
||||
file = "scanner.conf";
|
||||
|
||||
file_ = file;
|
||||
if(file_[0] != '/')
|
||||
{
|
||||
HGChar logpath[512] = {0};
|
||||
|
||||
HGBase_GetConfigPath(logpath, sizeof(logpath) / sizeof(logpath[0]) - 1);
|
||||
file_ = logpath;
|
||||
file_ += file;
|
||||
}
|
||||
ini_ = new QSettings(file_, QSettings::IniFormat);
|
||||
ini_->setIniCodec(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
reload_schemes();
|
||||
|
||||
return 0;
|
||||
}
|
||||
QString config::get_val(QString sec_name, QString key, QString def_val)
|
||||
{
|
||||
if(!ini_)
|
||||
return def_val;
|
||||
|
||||
QVariant qv = ini_->value(sec_name + "/" + key);
|
||||
char buf[128];
|
||||
|
||||
if(qv.isNull())
|
||||
return def_val;
|
||||
|
||||
if(qv.type() == QVariant::Type::Int)
|
||||
{
|
||||
sprintf(buf, "%d", qv.toInt());
|
||||
|
||||
return QString::fromStdString(buf);
|
||||
}
|
||||
else if(qv.type() == QVariant::Type::UInt)
|
||||
{
|
||||
sprintf(buf, "%u", qv.toInt());
|
||||
|
||||
return QString::fromStdString(buf);
|
||||
}
|
||||
else if(qv.type() == QVariant::Type::Double)
|
||||
{
|
||||
sprintf(buf, "%f", qv.toFloat());
|
||||
|
||||
return QString::fromStdString(buf);
|
||||
}
|
||||
else
|
||||
return qv.toString();
|
||||
}
|
||||
QString config::get_file(void)
|
||||
{
|
||||
return file_;
|
||||
}
|
||||
|
||||
void config::load_all_scanner_configs(std::vector<DEVCFG>& cfgs)
|
||||
{
|
||||
#if 0
|
||||
_opt_scheme opt1;
|
||||
opt1.name = "aaa";
|
||||
_opt_scheme opt2;
|
||||
opt2.name = "bbb";
|
||||
DEVCFG d1;
|
||||
d1.name = "d1";
|
||||
d1.schemes.push_back(opt1);
|
||||
d1.schemes.push_back(opt2);
|
||||
cfgs.push_back(d1);
|
||||
|
||||
_opt_scheme opt3;
|
||||
opt3.name = "ccc";
|
||||
_opt_scheme opt4;
|
||||
opt4.name = "ddd";
|
||||
DEVCFG d2;
|
||||
d2.name = "d2";
|
||||
d2.schemes.push_back(opt1);
|
||||
d2.schemes.push_back(opt2);
|
||||
cfgs.push_back(d2);
|
||||
#endif
|
||||
if(!schem_jsn_)
|
||||
return;
|
||||
|
||||
std::vector<std::string> devs;
|
||||
std::string cont(""), name("");
|
||||
if(schem_jsn_->first_child(cont, &name))
|
||||
{
|
||||
do
|
||||
{
|
||||
if(!name.empty())
|
||||
devs.push_back(name);
|
||||
}while(schem_jsn_->next_child(cont, &name));
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < devs.size(); ++i)
|
||||
{
|
||||
DEVCFG cfg;
|
||||
load_scanner_configs(QString::fromStdString(devs[i]), &cfg);
|
||||
cfgs.push_back(cfg);
|
||||
}
|
||||
}
|
||||
void config::transferTitle2Name(std::string& name)
|
||||
{
|
||||
int size = sizeof(g_opts) / sizeof(g_opts[0]);
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
if (strcmp(name.c_str(), g_opts[i].title) == 0)
|
||||
{
|
||||
name = g_opts[i].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string config::transferName2Title(std::string& name)
|
||||
{
|
||||
int size = sizeof(g_opts) / sizeof(g_opts[0]);
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
if (strcmp(name.c_str(), g_opts[i].name) == 0)
|
||||
{
|
||||
name = g_opts[i].title;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
void config::load_scanner_configs(QString dev_name, DEVCFG* cfg)
|
||||
{
|
||||
std::string name(config::device_to_config_dev_name(dev_name)), cont("");
|
||||
OPTSCHEME scheme;
|
||||
OPTVAL val;
|
||||
|
||||
cfg->m_deviceName = name;
|
||||
cfg->cur_scheme = -1;
|
||||
|
||||
if(!schem_jsn_)
|
||||
return;
|
||||
|
||||
gb::json *child = NULL;
|
||||
schem_jsn_->get_value(name.c_str(), child);
|
||||
if(!child)
|
||||
return;
|
||||
|
||||
if(child->first_child(cont))
|
||||
{
|
||||
gb::json *cur = new gb::json();
|
||||
if(cur->attach_text(&cont[0]))
|
||||
{
|
||||
if(!cur->get_value("cur_sel", cfg->cur_scheme))
|
||||
cfg->cur_scheme = -1;
|
||||
}
|
||||
delete cur;
|
||||
|
||||
while(child->next_child(cont))
|
||||
{
|
||||
if(cont.empty())
|
||||
continue;
|
||||
|
||||
gb::json jsn, *son = NULL;
|
||||
if(!jsn.attach_text(&cont[0]))
|
||||
continue;
|
||||
|
||||
jsn.get_value("scheme", scheme.m_schemeTitle);
|
||||
jsn.get_value("opts", son);
|
||||
if(!son)
|
||||
continue;
|
||||
|
||||
scheme.opts.clear();
|
||||
if(son->first_child(cont))
|
||||
{
|
||||
do
|
||||
{
|
||||
if(cont.empty())
|
||||
continue;
|
||||
|
||||
gb::json item;
|
||||
if(!item.attach_text(&cont[0]))
|
||||
continue;
|
||||
|
||||
if(item.get_value("name", val.name) && item.get_value("value", val.val))
|
||||
{
|
||||
transferTitle2Name(val.name); // chinese title to english name
|
||||
item.get_value("title", val.title);
|
||||
item.get_value("extra", val.extra);
|
||||
scheme.opts.push_back(val);
|
||||
}
|
||||
}while(son->next_child(cont));
|
||||
}
|
||||
delete son;
|
||||
if(scheme.opts.size())
|
||||
cfg->schemes.push_back(scheme);
|
||||
}
|
||||
}
|
||||
|
||||
delete child;
|
||||
}
|
||||
int config::save_scanner_configs(const DEVCFG* cfg)
|
||||
{
|
||||
if(!schem_jsn_)
|
||||
schem_jsn_ = new gb::json();
|
||||
|
||||
gb::json *child = NULL, *scheme = NULL, *val = NULL;
|
||||
std::string text("");
|
||||
|
||||
schem_jsn_->get_value(cfg->m_deviceName.c_str(), child);
|
||||
if(child)
|
||||
schem_jsn_->remove(cfg->m_deviceName.c_str());
|
||||
if(child)
|
||||
child->clear();
|
||||
else {
|
||||
child = new gb::json();
|
||||
}
|
||||
|
||||
|
||||
child->create_empty(true);
|
||||
scheme = new gb::json();
|
||||
scheme->set_value("cur_sel", cfg->cur_scheme);
|
||||
scheme->set_value("version", cfg->appVersionNum);
|
||||
child->set_value(NULL, scheme);
|
||||
delete scheme;
|
||||
for(size_t i = 0; i < cfg->schemes.size(); ++i)
|
||||
{
|
||||
if(cfg->schemes[i].opts.empty())
|
||||
continue;
|
||||
|
||||
scheme = new gb::json();
|
||||
scheme->create_empty();
|
||||
scheme->set_value("scheme", cfg->schemes[i].m_schemeTitle);
|
||||
|
||||
gb::json *opt = new gb::json();
|
||||
opt->create_empty(true);
|
||||
for(size_t j = 0; j < cfg->schemes[i].opts.size(); ++j)
|
||||
{
|
||||
val = new gb::json();
|
||||
val->set_value("name", cfg->schemes[i].opts[j].name);
|
||||
val->set_value("title", cfg->schemes[i].opts[j].title);
|
||||
// val->set_value("type", cfg->schemes[i].opts[j].type);
|
||||
val->set_value("extra", cfg->schemes[i].opts[j].extra);
|
||||
val->set_value("value", cfg->schemes[i].opts[j].val);
|
||||
text = val->to_string(false);
|
||||
opt->set_value(NULL, val);
|
||||
text = opt->to_string(false);
|
||||
delete val;
|
||||
}
|
||||
printf("scheme %d: %s\n", i + 1, text.c_str());
|
||||
scheme->set_value("opts", opt);
|
||||
text = scheme->to_string(false);
|
||||
printf("all: %s\n", text.c_str());
|
||||
delete opt;
|
||||
child->set_value(NULL, scheme);
|
||||
text = child->to_string(false);
|
||||
delete scheme;
|
||||
}
|
||||
|
||||
schem_jsn_->set_value(cfg->m_deviceName.c_str(), child);
|
||||
delete child;
|
||||
|
||||
text = schem_jsn_->to_string(false);
|
||||
|
||||
// save as base64
|
||||
gb::base64 base64;
|
||||
std::string ec(base64.encode(text.c_str(), text.length()));
|
||||
|
||||
return save_2_file(get_scanner_config_file(), ec.c_str(), ec.length());
|
||||
}
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <qsettings.h>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#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 title;
|
||||
std::string type;
|
||||
std::string val;
|
||||
std::string extra;
|
||||
|
||||
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 && extra == r.extra;
|
||||
}
|
||||
}
|
||||
bool operator==(const std::string& n)
|
||||
{
|
||||
return name == n;
|
||||
}
|
||||
}OPTVAL;
|
||||
typedef struct _opt_scheme
|
||||
{
|
||||
std::string m_schemeName; // scheme name
|
||||
std::string m_schemeTitle; //shcheme title
|
||||
std::vector<OPTVAL> opts;
|
||||
bool operator==(const std::string& n)
|
||||
{
|
||||
return m_schemeName == 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<OPTVAL>::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 m_deviceName; // device name
|
||||
std::string m_originDeviceName; //If the model of the second device is the same, remember the original name of the second device
|
||||
int cur_scheme; // -1 is none user scheme applied, and points to the default setting which at first in 'schemes'
|
||||
std::string appVersionNum;
|
||||
std::vector<OPTSCHEME> 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 m_deviceName == n;
|
||||
}
|
||||
|
||||
_dev_configs()
|
||||
{
|
||||
OPTSCHEME none;
|
||||
none.m_schemeName = "\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<OPTSCHEME>::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<DEVCFG>& 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<DEVCFG>& cfgs);
|
||||
void load_scanner_configs(QString dev_name, DEVCFG* cfg);
|
||||
int save_scanner_configs(const DEVCFG* cfg);
|
||||
void transferTitle2Name(std::string& name);
|
||||
std::string transferName2Title(std::string& name);
|
||||
};
|
|
@ -7,7 +7,7 @@ device_menu::device_menu(QWidget *parent)
|
|||
, cur_action_(nullptr), none_action_(nullptr)
|
||||
{
|
||||
group_action_ = new QActionGroup(this);
|
||||
deviceMenuUpdate(nullptr, "");
|
||||
deviceMenuUpdate(nullptr);
|
||||
connect(group_action_, SIGNAL(triggered(QAction*)), this, SLOT(on_act_triggered(QAction*)));
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ device_menu::device_menu(const QString &title, QWidget *parent)
|
|||
, cur_action_(nullptr), none_action_(nullptr)
|
||||
{
|
||||
group_action_ = new QActionGroup(this);
|
||||
deviceMenuUpdate(nullptr, "");
|
||||
deviceMenuUpdate(nullptr);
|
||||
connect(group_action_, SIGNAL(triggered(QAction*)), this, SLOT(on_act_triggered(QAction*)));
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ void device_menu::get_online_devices(QList<QString>& dev_names)
|
|||
}
|
||||
}
|
||||
|
||||
void device_menu::deviceMenuUpdate(const std::vector<DEVCFG>* dev_cfgs, std::string curDeviceName)
|
||||
void device_menu::deviceMenuUpdate(dev_que* que)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if(none_action_)
|
||||
|
@ -102,7 +102,7 @@ void device_menu::deviceMenuUpdate(const std::vector<DEVCFG>* dev_cfgs, std::str
|
|||
|
||||
for(size_t i = 0; i < menus_.size(); ++i)
|
||||
menus_[i].menu->setEnabled(false);
|
||||
if (!dev_cfgs || dev_cfgs->empty())
|
||||
if (!que || que->scanners() == 0)
|
||||
{
|
||||
if(menus_.empty())
|
||||
{
|
||||
|
@ -113,13 +113,15 @@ void device_menu::deviceMenuUpdate(const std::vector<DEVCFG>* dev_cfgs, std::str
|
|||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < dev_cfgs->size(); i++)
|
||||
for (size_t i = 0; i < que->scanners(); i++)
|
||||
{
|
||||
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), QString::fromStdString((*dev_cfgs)[i].m_originDeviceName));
|
||||
SCANNER s = que->get_at(i);
|
||||
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), QString::fromStdString((s.name)));
|
||||
POPMENU pm;
|
||||
std::vector<std::string> schemes;
|
||||
|
||||
if(it == menus_.end())
|
||||
pm.menu = addMenu(QString::fromStdString((*dev_cfgs)[i].m_originDeviceName));
|
||||
pm.menu = addMenu(QString::fromStdString(s.name));
|
||||
else
|
||||
{
|
||||
pm = *it;
|
||||
|
@ -133,43 +135,29 @@ void device_menu::deviceMenuUpdate(const std::vector<DEVCFG>* dev_cfgs, std::str
|
|||
group_action_->removeAction(pm.actions[j]);
|
||||
}
|
||||
pm.actions.clear();
|
||||
for (size_t j = 0; j < (*dev_cfgs)[i].schemes.size(); j++)
|
||||
s.cfg->get_all_schemes(schemes);
|
||||
for (size_t j = 0; j < schemes.size(); j++)
|
||||
{
|
||||
QAction *child;
|
||||
if(!(*dev_cfgs)[i].schemes[j].m_schemeTitle.empty())
|
||||
child = group_action_->addAction(QString::fromStdString((*dev_cfgs)[i].schemes[j].m_schemeTitle));
|
||||
else
|
||||
child = group_action_->addAction(QString::fromStdString((*dev_cfgs)[i].schemes[j].m_schemeName));
|
||||
child->setProperty(ACTION_DEVICE_NAME_PROPERTY, QVariant(QString::fromStdString((*dev_cfgs)[i].m_originDeviceName)));
|
||||
QAction *child = group_action_->addAction(QString::fromStdString(schemes[j]));
|
||||
child->setProperty(ACTION_DEVICE_NAME_PROPERTY, QVariant(QString::fromStdString(s.name)));
|
||||
child->setCheckable(true);
|
||||
|
||||
if((*dev_cfgs)[i].cur_scheme == -1)
|
||||
{
|
||||
if(child->text().toStdString() == (*dev_cfgs)[i].schemes[j].m_schemeName)
|
||||
child->setChecked(true);
|
||||
}
|
||||
else
|
||||
if(que->opened_scanner_name() == s.name &&
|
||||
schemes[j] == s.cfg->get_current_scheme_name())
|
||||
child->setChecked(true);
|
||||
|
||||
pm.menu->addAction(child);
|
||||
pm.actions.push_back(child);
|
||||
|
||||
const std::vector<OPTVAL>& opts = (*dev_cfgs)[i].schemes[j].opts;
|
||||
QString tips;
|
||||
for(size_t k = 0; k < opts.size(); ++k)
|
||||
{
|
||||
if(!opts[k].title.empty())
|
||||
tips += QString::fromStdString(opts[k].title + ": " + opts[k].val + "\n");
|
||||
else
|
||||
tips += QString::fromStdString(opts[k].name + ": " + opts[k].val + "\n");
|
||||
}
|
||||
if(tips.isNull())
|
||||
{
|
||||
tips = tr("default setting");
|
||||
}
|
||||
child->setToolTip(tips);
|
||||
// child->setToolTip(tips);
|
||||
}
|
||||
menus_.push_back(pm);
|
||||
s.cfg->release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,462 @@
|
|||
#define DEVICE_MENU_H
|
||||
|
||||
#include <QMenu>
|
||||
#include "config.h"
|
||||
#include <mutex>
|
||||
#include "sane/sane_ex.h"
|
||||
#include "sane/sane_option_definitions.h"
|
||||
#include "../../../sdk/include/huagao/hgscanner_error.h"
|
||||
|
||||
#include "cfg/gb_json.h"
|
||||
|
||||
typedef struct _scanner
|
||||
{
|
||||
std::string name;
|
||||
std::string model;
|
||||
bool online;
|
||||
gb::scanner_cfg *cfg;
|
||||
}SCANNER;
|
||||
class dev_que
|
||||
{
|
||||
std::vector<SCANNER> que_;
|
||||
std::string root_dir_;
|
||||
std::string opened_scanner_;
|
||||
std::string applied_scheme_;
|
||||
SANE_Handle handle_;
|
||||
|
||||
|
||||
static void trans_number(const char* name, std::string& val, void* param)
|
||||
{
|
||||
if (strcmp(name, "tl-x") == 0
|
||||
|| strcmp(name, "br-x") == 0
|
||||
|| strcmp(name, "tl-y") == 0
|
||||
|| strcmp(name, "br-y") == 0
|
||||
|| strcmp(name, "gamma") == 0
|
||||
|| strcmp(name, "search-hole-range-l") == 0
|
||||
|| strcmp(name, "search-hole-range-r") == 0
|
||||
|| strcmp(name, "search-hole-range-t") == 0
|
||||
|| strcmp(name, "search-hole-range-b") == 0
|
||||
|| strcmp(name, "feed-strength-value") == 0
|
||||
)
|
||||
{
|
||||
float v = atof(val.c_str());
|
||||
SANE_Fixed f = SANE_FIX(v);
|
||||
|
||||
val = std::string((char*)&f, sizeof(f));
|
||||
}
|
||||
else if (strcmp(name, "binary-threshold") == 0
|
||||
|| strcmp(name, "bkg-color-range") == 0
|
||||
|| strcmp(name, "noise-size") == 0
|
||||
|| strcmp(name, "blank-sensitivity") == 0
|
||||
|| strcmp(name, "resolution") == 0
|
||||
|| strcmp(name, "brightness") == 0
|
||||
|| strcmp(name, "contrast") == 0
|
||||
|| strcmp(name, "threshold") == 0
|
||||
|| strcmp(name, "anti-noise-level") == 0
|
||||
|| strcmp(name, "margin") == 0
|
||||
|| strcmp(name, "scan-count") == 0
|
||||
|| strcmp(name, "askew-range") == 0
|
||||
|| strcmp(name, "dog-ear-size") == 0
|
||||
)
|
||||
{
|
||||
SANE_Int v = atoi(val.c_str());
|
||||
val = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if (strcmp(val.c_str(), "true") == 0)
|
||||
{
|
||||
SANE_Bool b = SANE_TRUE;
|
||||
val = std::string((char*)&b, sizeof(b));
|
||||
}
|
||||
else if (strcmp(val.c_str(), "false") == 0)
|
||||
{
|
||||
SANE_Bool b = SANE_FALSE;
|
||||
val = std::string((char*)&b, sizeof(b));
|
||||
}
|
||||
}
|
||||
static const char* title_2_name(const char* title, void* param)
|
||||
{
|
||||
struct
|
||||
{
|
||||
const char* name;
|
||||
const char* title;
|
||||
}g_opts[] = { {SANE_STD_OPT_NAME_RESTORE , OPTION_TITLE_HFMRSZ}
|
||||
, {SANE_STD_OPT_NAME_HELP , OPTION_TITLE_BZ}
|
||||
, {SANE_STD_OPT_NAME_IS_MULTI_OUT , OPTION_TITLE_DLSC}
|
||||
, {SANE_STD_OPT_NAME_MULTI_OUT_TYPE , OPTION_TITLE_DLSCLX}
|
||||
, {SANE_STD_OPT_NAME_COLOR_MODE , OPTION_TITLE_YSMS}
|
||||
, {SANE_STD_OPT_NAME_BINARY_THRESHOLD , OPTION_TITLE_HBTXYZ}
|
||||
, {SANE_STD_OPT_NAME_REVERSE_01 , OPTION_TITLE_HBTXFSSC}
|
||||
, {SANE_STD_OPT_NAME_FILTER , OPTION_TITLE_HDHHBTX_CSYZQ}
|
||||
, {SANE_STD_OPT_NAME_RID_MULTIOUT_RED , OPTION_TITLE_24WCSTX_DLSCCH}
|
||||
, {SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED , OPTION_TITLE_24WCSTX_DTKCH}
|
||||
, {SANE_STD_OPT_NAME_ERASE_BACKGROUND , OPTION_TITLE_BJYC}
|
||||
, {SANE_STD_OPT_NAME_BKG_COLOR_RANGE , OPTION_TITLE_BJSCFDFW}
|
||||
, {SANE_STD_OPT_NAME_SHARPEN , OPTION_TITLE_RHYMH}
|
||||
, {SANE_STD_OPT_NAME_RID_MORR , OPTION_TITLE_QCMW}
|
||||
, {SANE_STD_OPT_NAME_RID_GRID , OPTION_TITLE_CWW}
|
||||
, {SANE_STD_OPT_NAME_ERROR_EXTENSION , OPTION_TITLE_CWKS}
|
||||
, {SANE_STD_OPT_NAME_NOISE_OPTIMIZE , OPTION_TITLE_HBTXZDYH}
|
||||
, {SANE_STD_OPT_NAME_NOISE_SIZE , OPTION_TITLE_ZDYHCC}
|
||||
, {SANE_STD_OPT_NAME_PAPER , OPTION_TITLE_ZZCC}
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA , OPTION_TITLE_ZDYSMQY}
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT , OPTION_TITLE_SMQYZCmm}
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT , OPTION_TITLE_SMQYYCmm}
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_TOP , OPTION_TITLE_SMQYSCmm}
|
||||
, {SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM , OPTION_TITLE_SMQYXCmm}
|
||||
, {SANE_STD_OPT_NAME_SIZE_CHECK , OPTION_TITLE_CCJC}
|
||||
, {SANE_STD_OPT_NAME_PAGE , OPTION_TITLE_SMYM}
|
||||
, {SANE_STD_OPT_NAME_DISCARD_BLANK_SENS , OPTION_TITLE_TGKBYLMD}
|
||||
, {SANE_STD_OPT_NAME_RESOLUTION , OPTION_TITLE_FBL}
|
||||
, {SANE_STD_OPT_NAME_TIME_TO_SLEEP , OPTION_TITLE_XMSJ}
|
||||
, {SANE_STD_OPT_NAME_IMAGE_QUALITY , OPTION_TITLE_HZ}
|
||||
, {SANE_STD_OPT_NAME_EXCHANGE ,OPTION_TITLE_JHZFM}
|
||||
, {SANE_STD_OPT_NAME_SPLIT ,OPTION_TITLE_TXCF }
|
||||
, {SANE_STD_OPT_NAME_ANTI_SKEW , OPTION_TITLE_ZDJP}
|
||||
, {SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA , OPTION_TITLE_QYSDQX}
|
||||
, {SANE_STD_OPT_NAME_GAMMA , OPTION_TITLE_JMZ}
|
||||
, {SANE_STD_OPT_NAME_BRIGHTNESS , OPTION_TITLE_LDZ}
|
||||
, {SANE_STD_OPT_NAME_CONTRAST , OPTION_TITLE_DBD}
|
||||
, {SANE_STD_OPT_NAME_IS_PHOTO_MODE , OPTION_TITLE_ZPMS}
|
||||
, {SANE_STD_OPT_NAME_ERASE_BLACK_FRAME , OPTION_TITLE_XCHK}
|
||||
, {SANE_STD_OPT_NAME_DARK_SAMPLE , OPTION_TITLE_SSYZ}
|
||||
, {SANE_STD_OPT_NAME_THRESHOLD , OPTION_TITLE_YZ}
|
||||
, {SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL , OPTION_TITLE_BJKZDJ}
|
||||
, {SANE_STD_OPT_NAME_MARGIN , OPTION_TITLE_BYSJ}
|
||||
, {SANE_STD_OPT_NAME_FILL_BKG_MODE , OPTION_TITLE_BJTCFS}
|
||||
, {SANE_STD_OPT_NAME_IS_ANTI_PERMEATE , OPTION_TITLE_FZST}
|
||||
, {SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL , OPTION_TITLE_FZSTDJ}
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_L , OPTION_TITLE_CKYCZC}
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L , OPTION_TITLE_ZCCKSSFWZFMBL}
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_R , OPTION_TITLE_CKYCYC}
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R , OPTION_TITLE_YCCKSSFWZFMBL}
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_T , OPTION_TITLE_CKYCSC}
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T , OPTION_TITLE_SCCKSSFWZFMBL}
|
||||
, {SANE_STD_OPT_NAME_RID_HOLE_B , OPTION_TITLE_CKYCXC}
|
||||
, {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B , OPTION_TITLE_XCCKSSFWZFMBL}
|
||||
, {SANE_STD_OPT_NAME_IS_FILL_COLOR , OPTION_TITLE_SCTC}
|
||||
, {SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK , OPTION_TITLE_CSBJC}
|
||||
, {SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE , OPTION_TITLE_SZTPCL}
|
||||
, {SANE_STD_OPT_NAME_IS_CHECK_STAPLE , OPTION_TITLE_ZDJC}
|
||||
, {SANE_STD_OPT_NAME_SCAN_MODE , OPTION_TITLE_SMZS}
|
||||
, {SANE_STD_OPT_NAME_SCAN_COUNT , OPTION_TITLE_SMSL}
|
||||
, {SANE_STD_OPT_NAME_TEXT_DIRECTION , OPTION_TITLE_WGFX}
|
||||
, {SANE_STD_OPT_NAME_IS_ROTATE_BKG_180 , OPTION_TITLE_BMXZ180}
|
||||
, {SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR , OPTION_TITLE_ZJJC}
|
||||
, {SANE_STD_OPT_NAME_DOG_EAR_SIZE , OPTION_TITLE_ZJDX}
|
||||
, {SANE_STD_OPT_NAME_IS_CHECK_ASKEW , OPTION_TITLE_WXJC}
|
||||
, {SANE_STD_OPT_NAME_ASKEW_RANGE , OPTION_TITLE_WXRRD}
|
||||
, {SANE_STD_OPT_NAME_FEED_STRENGTH , OPTION_TITLE_FZQD}
|
||||
, {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , OPTION_TITLE_ZDFZQD}
|
||||
, {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , OPTION_TITLE_JZSBL}
|
||||
, {SANE_STD_OPT_NAME_WAIT_TO_SCAN , OPTION_TITLE_DZSM}
|
||||
, {SANE_STD_OPT_NAME_FOLD_TYPE , OPTION_TITLE_DZMS}
|
||||
},
|
||||
g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // 黑白图像反色输出(正常颜色为:0-黑色;1-白色)
|
||||
, {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // 灰度或黑白图像 - 除色
|
||||
, {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // 自动搓纸强度
|
||||
, {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 搓纸阈值"
|
||||
};
|
||||
while (*title == ' ')
|
||||
title++;
|
||||
|
||||
for (size_t i = 0; i < _countof(g_opts); ++i)
|
||||
{
|
||||
if (strcmp(title, g_opts[i].title) == 0)
|
||||
return g_opts[i].name;
|
||||
}
|
||||
for (size_t i = 0; i < _countof(g_discard); ++i)
|
||||
{
|
||||
if (strcmp(title, g_discard[i].title) == 0)
|
||||
return g_discard[i].name;
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
public:
|
||||
dev_que() : handle_(nullptr)
|
||||
{}
|
||||
~dev_que()
|
||||
{
|
||||
close_scanner();
|
||||
|
||||
for(auto& v : que_)
|
||||
v.cfg->release();
|
||||
}
|
||||
|
||||
static void update_old_cfg(const char* conf)
|
||||
{
|
||||
gb::scanner_cfg::UDF func;
|
||||
|
||||
func.func_param = nullptr;
|
||||
func.title2name = &dev_que::title_2_name;
|
||||
func.trans_number = &dev_que::trans_number;
|
||||
|
||||
gb::scanner_cfg::update(conf, &func);
|
||||
}
|
||||
static void apply_scheme(SANE_Handle h, gb::sane_config_schm* schm)
|
||||
{
|
||||
SANE_Int count = 0, none = 0;
|
||||
std::string name(""), val("");
|
||||
|
||||
none = sane_io_control(h, IO_CTRL_CODE_RESTORE_SETTINGS, NULL, NULL);
|
||||
if(schm && schm->id_from_name(SANE_STD_OPT_NAME_COLOR_MODE) == -1)
|
||||
{
|
||||
SANE_Int dev_options = 0;
|
||||
sane_control_option(h, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
|
||||
for(int i = 1; i < dev_options; ++i)
|
||||
{
|
||||
const SANE_Option_Descriptor* opt = sane_get_option_descriptor(h, i);
|
||||
if(!opt)
|
||||
continue;
|
||||
|
||||
unsigned int n = i;
|
||||
if(opt->type == SANE_TYPE_BOOL)
|
||||
{
|
||||
SANE_Bool v = SANE_TRUE;
|
||||
sane_io_control(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, &v, &n);
|
||||
schm->set_default_value(i, opt->name, (char*)&v, sizeof(v));
|
||||
}
|
||||
else if (opt->type == SANE_TYPE_INT) {
|
||||
SANE_Int v = 0;
|
||||
sane_io_control(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, &v, &n);
|
||||
schm->set_default_value(i, opt->name, (char*)&v, sizeof(v));
|
||||
}
|
||||
else if(opt->type == SANE_TYPE_FIXED)
|
||||
{
|
||||
SANE_Fixed v = 0;
|
||||
sane_io_control(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, &v, &n);
|
||||
schm->set_default_value(i, opt->name, (char*)&v, sizeof(v));
|
||||
}
|
||||
else {
|
||||
char *buf = new char[opt->size + 4];
|
||||
memset(buf, 0, opt->size + 4);
|
||||
sane_io_control(h, IO_CTRL_CODE_GET_DEFAULT_VALUE, buf, &n);
|
||||
schm->set_default_value(i, opt->name, buf, strlen(buf));
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(schm && schm->first_config(name, val))
|
||||
{
|
||||
do
|
||||
{
|
||||
int id = schm->id_from_name(name.c_str());
|
||||
if(id == -1)
|
||||
{
|
||||
if(gb::sane_config_schm::is_option_data(name))
|
||||
{
|
||||
if(name == SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA && val.length() == sizeof(SANE_Gamma))
|
||||
{
|
||||
unsigned int l = val.length();
|
||||
sane_io_control(h, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &val[0], &l);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const SANE_Option_Descriptor* opt = reinterpret_cast<const SANE_Option_Descriptor*>(sane_get_option_descriptor(h, id));
|
||||
if(opt)
|
||||
{
|
||||
if(opt->type == SANE_TYPE_STRING)
|
||||
{
|
||||
char *buf = new char[opt->size + 4];
|
||||
memset(buf, 0, opt->size + 4);
|
||||
strcpy(buf, val.c_str());
|
||||
sane_control_option(h, id, SANE_ACTION_SET_VALUE, buf, &none);
|
||||
delete[] buf;
|
||||
}
|
||||
else {
|
||||
sane_control_option(h, id, SANE_ACTION_SET_VALUE, &val[0], &none);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}while(schm->next_config(name, val));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
void set_root_dir(const char* root)
|
||||
{
|
||||
root_dir_ = std::string(root) + PATH_SYMBOL;
|
||||
}
|
||||
void add_scanner(const char* sane_name)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
for(auto& v: que_)
|
||||
{
|
||||
if(v.name == sane_name)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
{
|
||||
SCANNER s;
|
||||
size_t pos = 0;
|
||||
|
||||
s.model = s.name = sane_name;
|
||||
s.cfg = nullptr;
|
||||
pos = s.model.find(" - ");
|
||||
if(pos != std::string::npos)
|
||||
{
|
||||
pos = s.model.find(" - ", pos + 3);
|
||||
if(pos != std::string::npos)
|
||||
s.model.erase(pos);
|
||||
}
|
||||
for(auto& v: que_)
|
||||
{
|
||||
if(v.model == s.model)
|
||||
{
|
||||
s.cfg = v.cfg;
|
||||
s.cfg->add_ref();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!s.cfg)
|
||||
{
|
||||
s.cfg = new gb::scanner_cfg();
|
||||
s.cfg->load_file((root_dir_ + s.model + ".cfg").c_str());
|
||||
}
|
||||
s.online = true;
|
||||
que_.push_back(s);
|
||||
}
|
||||
}
|
||||
void get_schemes(const char* scanner_name, std::vector<std::string>& schemes)
|
||||
{
|
||||
schemes.clear();
|
||||
for(auto& v : que_)
|
||||
{
|
||||
if(v.name == scanner_name)
|
||||
{
|
||||
v.cfg->get_all_schemes(schemes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SANE_Handle handle(void)
|
||||
{
|
||||
return handle_;
|
||||
}
|
||||
std::string opened_scanner_name(void)
|
||||
{
|
||||
return opened_scanner_;
|
||||
}
|
||||
std::string applied_scheme(void)
|
||||
{
|
||||
return applied_scheme_;
|
||||
}
|
||||
int open_scanner(const char* scanner_name, const char* scheme = nullptr)
|
||||
{
|
||||
SANE_Status statu = SANE_STATUS_GOOD;
|
||||
|
||||
close_scanner();
|
||||
statu = sane_open(scanner_name, &handle_);
|
||||
if(statu == SANE_STATUS_GOOD && handle_)
|
||||
{
|
||||
opened_scanner_ = scanner_name;
|
||||
apply_scheme(scheme);
|
||||
}
|
||||
}
|
||||
int close_scanner(void)
|
||||
{
|
||||
if(handle_)
|
||||
{
|
||||
sane_close(handle_);
|
||||
handle_ = nullptr;
|
||||
opened_scanner_ = "";
|
||||
applied_scheme_ = "";
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
int scanners(void)
|
||||
{
|
||||
return que_.size();
|
||||
}
|
||||
SCANNER get_at(int pos)
|
||||
{
|
||||
SCANNER s;
|
||||
|
||||
s.name = s.model = "";
|
||||
s.cfg = nullptr;
|
||||
if(pos >= 0 && pos < que_.size())
|
||||
{
|
||||
s = que_[pos];
|
||||
s.cfg->add_ref();
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
bool is_online(const char* scanner = nullptr)
|
||||
{
|
||||
if(!scanner)
|
||||
scanner = opened_scanner_.c_str();
|
||||
|
||||
for(auto& v : que_)
|
||||
{
|
||||
if(v.name == scanner)
|
||||
return v.online;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void set_online(bool online, const char* scanner = nullptr)
|
||||
{
|
||||
if(!scanner)
|
||||
scanner = opened_scanner_.c_str();
|
||||
|
||||
for(auto& v : que_)
|
||||
{
|
||||
if(v.name == scanner)
|
||||
{
|
||||
v.online = online;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void get_scanners(std::vector<std::string>& que)
|
||||
{
|
||||
for(auto& v: que_)
|
||||
que.push_back(v.name);
|
||||
}
|
||||
int apply_scheme(const char* scheme_name)
|
||||
{
|
||||
if(!handle_)
|
||||
return SCANNER_ERR_NOT_OPEN;
|
||||
|
||||
for(auto& v: que_)
|
||||
{
|
||||
if(v.name == opened_scanner_)
|
||||
{
|
||||
gb::sane_config_schm* schm = v.cfg->get_scheme(scheme_name);
|
||||
dev_que::apply_scheme(handle_, schm);
|
||||
if(schm)
|
||||
{
|
||||
v.cfg->select_scheme(schm->get_scheme_name().c_str());
|
||||
schm->release();
|
||||
}
|
||||
else {
|
||||
v.cfg->select_scheme(scheme_name);
|
||||
}
|
||||
applied_scheme_ = scheme_name ? scheme_name : "";
|
||||
if(applied_scheme_.empty())
|
||||
{
|
||||
std::vector<std::string> all;
|
||||
v.cfg->get_all_schemes(all);
|
||||
applied_scheme_ = all[0];
|
||||
}
|
||||
v.cfg->save();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(OPTSCHEME)
|
||||
|
||||
class device_menu : public QMenu
|
||||
{
|
||||
|
@ -33,7 +485,7 @@ public:
|
|||
device_menu(QWidget* parent = nullptr);
|
||||
device_menu(const QString& title, QWidget* parent = nullptr);
|
||||
|
||||
void deviceMenuUpdate(const std::vector<DEVCFG>* dev_cfgs, std::string curDeviceName);
|
||||
void deviceMenuUpdate(dev_que* que);
|
||||
|
||||
void connectedDevice(const QString& device);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,36 +5,22 @@
|
|||
#include <QSettings>
|
||||
#include <algorithm>
|
||||
#include "sane/sane_ex.h"
|
||||
#include "config.h"
|
||||
#include "cfg/gb_json.h"
|
||||
#include "device_menu.h"
|
||||
|
||||
class hg_settingdialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
DEVCFG* schemes_;
|
||||
int cur_ind_; // [0, scheme size - 2] will be replaced when click 'OK' button, if want to add new item, set it to -1; add ONE on it when accept source
|
||||
|
||||
typedef struct _changed_opt
|
||||
{
|
||||
int opt;
|
||||
QVariant val;
|
||||
|
||||
bool operator==(const int& ind)
|
||||
{
|
||||
return opt == ind;
|
||||
}
|
||||
}CHANGEDOPT;
|
||||
std::vector<CHANGEDOPT> default_vals_; // values which changed
|
||||
std::vector<CHANGEDOPT> init_vals_; // values when initialize controls
|
||||
std::vector<CHANGEDOPT> changed_opts_; // values which changed
|
||||
int changed_count_;
|
||||
bool save_;
|
||||
bool clicked_gamma_;
|
||||
config* cfg_file_;
|
||||
dev_que *dev_que_;
|
||||
gb::scanner_cfg *cur_cfg_;
|
||||
gb::sane_config_schm *cur_scheme_;
|
||||
|
||||
void refresh_control_value(int op_id);
|
||||
bool is_covered(std::vector<OPTVAL>& org, std::vector<OPTVAL>& now); // if all options in org are inclued in now, then return true
|
||||
void on_select_scheme(int scheme_ind, bool apply_to_dev = true);
|
||||
void on_select_scheme(bool apply_to_dev = true);
|
||||
QString gen_gamma_file_path(void);
|
||||
|
||||
QMenu *top_menu_;
|
||||
|
@ -60,7 +46,7 @@ class hg_settingdialog : public QDialog
|
|||
|
||||
public:
|
||||
explicit hg_settingdialog(void *handle, QWidget *parent = nullptr,
|
||||
DEVCFG* cfg = nullptr);
|
||||
dev_que* dev = nullptr);
|
||||
~hg_settingdialog();
|
||||
|
||||
public:
|
||||
|
@ -71,7 +57,6 @@ public:
|
|||
QVector<QWidget*> find_control(int opt_num);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
int get_changed_items(void);
|
||||
void set_config_file(config* cfg);
|
||||
|
||||
private:
|
||||
void *m_handle;
|
||||
|
@ -88,18 +73,12 @@ private:
|
|||
const void* find_option_description(int id); // return const SANE_Option_Descriptor* pointer
|
||||
const void* find_option_description(const std::string& title, int* id); // return const SANE_Option_Descriptor* pointer
|
||||
QVariant find_default_value(int id);
|
||||
bool is_equal_default_value(const CHANGEDOPT& opt, int type);
|
||||
bool set_opt_value_for_OPTVAL(QVariant val, int type, OPTVAL* ov);
|
||||
|
||||
virtual void closeEvent(QCloseEvent* e);
|
||||
int find_covered_scheme(OPTSCHEME& scheme); // return [1, schemes_.size()]
|
||||
void save_scheme(void);
|
||||
void cancel_setting(void);
|
||||
static int find_opt_setting(const char* name, const std::vector<OPTVAL>& opts);
|
||||
int apply_setting(const SANE_Option_Descriptor* desc, int opt_ind, OPTVAL* val);
|
||||
int apply_settings(OPTSCHEME* scheme);
|
||||
void record_changed_option(int opt, const QVariant& var);
|
||||
void getAppVersion();
|
||||
void apply_current_scheme(void);
|
||||
|
||||
private:
|
||||
QVector<QPair<QPair<int, QVariant>, QString>> m_list_IdValueTitle;
|
||||
|
@ -145,7 +124,6 @@ private:
|
|||
QString m_colorModeValue;
|
||||
SANE_Gamma m_gammaData;
|
||||
QComboBox *comb_;
|
||||
config *m_config;
|
||||
};
|
||||
|
||||
#endif // HG_SETTING_DIALOG_H
|
||||
|
|
|
@ -1,772 +0,0 @@
|
|||
|
||||
#include "json.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#define bzero(b, s) memset(b, 0, s)
|
||||
#endif
|
||||
|
||||
namespace gb
|
||||
{
|
||||
static std::vector<std::string> split_with(const char* str, const char* splitor = "/")
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
std::string src(str);
|
||||
size_t pos = src.find(splitor);
|
||||
|
||||
while(pos != std::string::npos)
|
||||
{
|
||||
if(pos++)
|
||||
ret.push_back(src.substr(0, pos - 1));
|
||||
src.erase(0, pos + strlen(splitor));
|
||||
pos = src.find(splitor);
|
||||
}
|
||||
if(src.length())
|
||||
ret.push_back(src);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
json::json(char* json_txt) : obj_(0), cur_child_(0), is_array_(false)
|
||||
{
|
||||
attach_text(json_txt);
|
||||
}
|
||||
json::~json()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
std::string json::to_string(cJSON* root, bool formatted)
|
||||
{
|
||||
char* txt = formatted ? cJSON_Print(root) : cJSON_PrintUnformatted(root);
|
||||
std::string ret(txt ? txt : "");
|
||||
|
||||
if (txt)
|
||||
free(txt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
std::string json::get_value_as_string(cJSON* root, bool integer)
|
||||
{
|
||||
std::string ret("");
|
||||
|
||||
switch (root->type)
|
||||
{
|
||||
case cJSON_False:
|
||||
ret = "false";
|
||||
break;
|
||||
case cJSON_True:
|
||||
ret = "true";
|
||||
break;
|
||||
case cJSON_NULL:
|
||||
ret = "null";
|
||||
break;
|
||||
case cJSON_Number:
|
||||
{
|
||||
char buf[40];
|
||||
if (integer)
|
||||
sprintf(buf, "%d", root->valueint);
|
||||
else
|
||||
sprintf(buf, "%f", root->valuedouble);
|
||||
ret = buf;
|
||||
}
|
||||
break;
|
||||
case cJSON_String:
|
||||
if (root->valuestring)
|
||||
ret = root->valuestring;
|
||||
break;
|
||||
default:
|
||||
ret = json::to_string(root, false);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
void json::free_node_data(cJSON* node)
|
||||
{
|
||||
if (node->type == cJSON_String && node->valuestring)
|
||||
free(node->valuestring);
|
||||
else if((node->type == cJSON_Object || node->type == cJSON_Array) && node->child)
|
||||
cJSON_Delete(node->child);
|
||||
|
||||
node->type = cJSON_NULL;
|
||||
node->valuestring = NULL;
|
||||
node->child = NULL;
|
||||
}
|
||||
cJSON* json::create_element_with_name(const char* name)
|
||||
{
|
||||
cJSON* obj = cJSON_CreateObject();
|
||||
|
||||
bzero(obj, sizeof(*obj));
|
||||
if(name)
|
||||
{
|
||||
obj->string = (char*)malloc(strlen(name) + 4);
|
||||
bzero(obj->string, strlen(name) + 4);
|
||||
strcpy(obj->string, name);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
cJSON* json::find_sibling(cJSON* first, const char* name, cJSON*** prev)
|
||||
{
|
||||
cJSON* now = first, **prv = NULL;
|
||||
while(now)
|
||||
{
|
||||
if(now->string && strcmp(now->string, name) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
prv = &now->next;
|
||||
now = now->next;
|
||||
}
|
||||
if(prev)
|
||||
*prev = prv;
|
||||
|
||||
return now;
|
||||
}
|
||||
cJSON* json::find_child(cJSON *parent, std::vector<std::string>& path, bool create, cJSON*** addr)
|
||||
{
|
||||
if(!parent->child)
|
||||
{
|
||||
if(!create)
|
||||
return NULL;
|
||||
|
||||
parent->child = json::create_element_with_name(path[0].c_str());
|
||||
if(path.size() == 1)
|
||||
{
|
||||
if(addr)
|
||||
*addr = &parent->child;
|
||||
|
||||
return parent->child;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON** prev = NULL,
|
||||
*now = find_sibling(parent->child, path[0].c_str(), &prev);
|
||||
if(!now)
|
||||
{
|
||||
if(!create)
|
||||
return now;
|
||||
|
||||
now = json::create_element_with_name(path[0].c_str());
|
||||
if(prev)
|
||||
*prev = now;
|
||||
else
|
||||
{
|
||||
obj_->child = now;
|
||||
prev = &obj_->child;
|
||||
}
|
||||
}
|
||||
|
||||
path.erase(path.begin());
|
||||
if(path.empty())
|
||||
{
|
||||
if(addr)
|
||||
*addr = prev ? prev : &parent->child;
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
return find_child(now, path, create, addr);
|
||||
}
|
||||
cJSON* json::find(const char* path, bool create, cJSON*** addr)
|
||||
{
|
||||
std::vector<std::string> tree(split_with(path));
|
||||
|
||||
if(tree.empty())
|
||||
return NULL;
|
||||
|
||||
if(!obj_)
|
||||
{
|
||||
if(!create)
|
||||
return NULL;
|
||||
|
||||
obj_ = cJSON_CreateObject();
|
||||
obj_->child = json::create_element_with_name(tree[0].c_str());
|
||||
}
|
||||
|
||||
return find_child(obj_, tree, create, addr);
|
||||
}
|
||||
|
||||
bool json::attach_text(char* json_txt)
|
||||
{
|
||||
clear();
|
||||
|
||||
obj_ = cJSON_Parse(json_txt);
|
||||
if(obj_)
|
||||
is_array_ = obj_->type == cJSON_Array;
|
||||
|
||||
return obj_ != 0;
|
||||
}
|
||||
bool json::attach_cjson(cJSON* cjson)
|
||||
{
|
||||
clear();
|
||||
|
||||
if (cjson)
|
||||
{
|
||||
std::string txt(json::to_string(cjson, false));
|
||||
if (txt.length())
|
||||
obj_ = cJSON_Parse(txt.c_str());
|
||||
}
|
||||
if(obj_)
|
||||
is_array_ = obj_->type == cJSON_Array;
|
||||
|
||||
return obj_ != 0;
|
||||
}
|
||||
bool json::create_empty(bool array)
|
||||
{
|
||||
clear();
|
||||
|
||||
obj_ = array ? cJSON_CreateArray() : cJSON_CreateObject();
|
||||
is_array_ = array;
|
||||
|
||||
return true;
|
||||
}
|
||||
void json::clear(void)
|
||||
{
|
||||
if (obj_)
|
||||
{
|
||||
cJSON_Delete(obj_);
|
||||
obj_ = 0;
|
||||
}
|
||||
}
|
||||
std::string json::to_string(bool formatted)
|
||||
{
|
||||
if (obj_)
|
||||
return json::to_string(obj_, formatted);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
bool json::get_value(const char* key, bool& val)
|
||||
{
|
||||
cJSON* obj = find(key);
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (obj->type == cJSON_True)
|
||||
val = true;
|
||||
else if (obj->type == cJSON_False)
|
||||
val = false;
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::get_value(const char* key, int& val)
|
||||
{
|
||||
cJSON* obj = find(key);
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (obj->type != cJSON_Number)
|
||||
return false;
|
||||
|
||||
val = obj->valueint;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::get_value(const char* key, double& val)
|
||||
{
|
||||
cJSON *obj = find(key);
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (obj->type != cJSON_Number)
|
||||
return false;
|
||||
|
||||
val = obj->valuedouble;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::get_value(const char* key, std::string& val)
|
||||
{
|
||||
cJSON *obj = find(key);
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
if (obj->type != cJSON_String)
|
||||
return false;
|
||||
|
||||
val = obj->valuestring ? obj->valuestring : "";
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::get_value(const char* key, json*& val)
|
||||
{
|
||||
cJSON *obj = find(key);
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
val = new json();
|
||||
if (!val->attach_cjson(obj))
|
||||
{
|
||||
delete val;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::get_value_as_string(const char* key, std::string& val, bool integer)
|
||||
{
|
||||
cJSON* obj = find(key);
|
||||
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
val = json::get_value_as_string(obj, integer);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::get_as_array(const char* key, std::vector<std::string>& val)
|
||||
{
|
||||
cJSON *obj = find(key);
|
||||
|
||||
val.clear();
|
||||
if (obj && obj->type == cJSON_Array)
|
||||
{
|
||||
cJSON *child = obj->child;
|
||||
while (child)
|
||||
{
|
||||
if (child->type == cJSON_Number)
|
||||
{
|
||||
char buf[40];
|
||||
sprintf(buf, "%d", child->valueint);
|
||||
val.push_back(buf);
|
||||
}
|
||||
else if (child->type == cJSON_String)
|
||||
val.push_back(child->valuestring ? child->valuestring : "");
|
||||
else
|
||||
{
|
||||
char *text = cJSON_Print(child);
|
||||
val.push_back(text);
|
||||
free(text);
|
||||
}
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool json::first_child(std::string& val, std::string* name)
|
||||
{
|
||||
cur_child_ = obj_->child;
|
||||
val = "";
|
||||
if (cur_child_)
|
||||
{
|
||||
val = json::get_value_as_string(cur_child_);
|
||||
if (name && cur_child_->string)
|
||||
*name = cur_child_->string;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool json::next_child(std::string& val, std::string* name)
|
||||
{
|
||||
if (cur_child_)
|
||||
cur_child_ = cur_child_->next;
|
||||
|
||||
val = "";
|
||||
if (cur_child_)
|
||||
{
|
||||
val = json::get_value_as_string(cur_child_);
|
||||
if (name && cur_child_->string)
|
||||
*name = cur_child_->string;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool json::set_value(const char* key, bool val)
|
||||
{
|
||||
if(!key)
|
||||
{
|
||||
if(is_array_)
|
||||
{
|
||||
if(!obj_)
|
||||
obj_ = cJSON_CreateArray();
|
||||
cJSON_AddItemToArray(obj_, val ? cJSON_CreateTrue() : cJSON_CreateFalse());
|
||||
}
|
||||
|
||||
return is_array_;
|
||||
}
|
||||
|
||||
cJSON* ele = this->find(key, true);
|
||||
|
||||
if (!ele)
|
||||
return false;
|
||||
|
||||
json::free_node_data(ele);
|
||||
|
||||
if (val)
|
||||
ele->type = cJSON_True;
|
||||
else
|
||||
ele->type = cJSON_False;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::set_value(const char* key, int val)
|
||||
{
|
||||
if(!key)
|
||||
{
|
||||
if(is_array_)
|
||||
{
|
||||
if(!obj_)
|
||||
obj_ = cJSON_CreateArray();
|
||||
cJSON_AddItemToArray(obj_, cJSON_CreateNumber(val));
|
||||
}
|
||||
|
||||
return is_array_;
|
||||
}
|
||||
|
||||
cJSON* ele = this->find(key, true);
|
||||
|
||||
if (!ele)
|
||||
return false;
|
||||
|
||||
json::free_node_data(ele);
|
||||
|
||||
ele->type = cJSON_Number;
|
||||
ele->valuedouble = ele->valueint = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::set_value(const char* key, double val)
|
||||
{
|
||||
if(!key)
|
||||
{
|
||||
if(is_array_)
|
||||
{
|
||||
if(!obj_)
|
||||
obj_ = cJSON_CreateArray();
|
||||
cJSON_AddItemToArray(obj_, cJSON_CreateNumber(val));
|
||||
}
|
||||
|
||||
return is_array_;
|
||||
}
|
||||
|
||||
cJSON* ele = this->find(key, true);
|
||||
|
||||
if (!ele)
|
||||
return false;
|
||||
|
||||
json::free_node_data(ele);
|
||||
|
||||
ele->type = cJSON_Number;
|
||||
ele->valuedouble = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::set_value(const char* key, std::string val)
|
||||
{
|
||||
if(!key)
|
||||
{
|
||||
if(is_array_)
|
||||
{
|
||||
if(!obj_)
|
||||
obj_ = cJSON_CreateArray();
|
||||
cJSON_AddItemToArray(obj_, cJSON_CreateString(val.c_str()));
|
||||
}
|
||||
|
||||
return is_array_;
|
||||
}
|
||||
|
||||
cJSON* ele = this->find(key, true);
|
||||
|
||||
if (!ele)
|
||||
return false;
|
||||
|
||||
json::free_node_data(ele);
|
||||
|
||||
ele->type = cJSON_String;
|
||||
ele->valuestring = (char*)malloc(val.length() + 4);
|
||||
bzero(ele->valuestring, val.length() + 4);
|
||||
strcpy(ele->valuestring, val.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
bool json::set_value(const char* key, const char* val)
|
||||
{
|
||||
return set_value(key, std::string(val));
|
||||
}
|
||||
bool json::set_value(const char* key, json* obj)
|
||||
{
|
||||
if(!key)
|
||||
{
|
||||
if(is_array_)
|
||||
{
|
||||
if(!obj_)
|
||||
obj_ = cJSON_CreateArray();
|
||||
if(obj && obj->obj_)
|
||||
{
|
||||
cJSON_AddItemToArray(obj_, obj->obj_);
|
||||
obj->obj_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return is_array_;
|
||||
}
|
||||
|
||||
cJSON** addr = NULL;
|
||||
cJSON* ele = this->find(key, true, &addr);
|
||||
|
||||
if (!ele)
|
||||
return false;
|
||||
|
||||
// json::free_node_data(ele);
|
||||
cJSON_Delete(ele);
|
||||
*addr = obj->obj_;
|
||||
ele = obj->obj_;
|
||||
if(ele->string)
|
||||
free(ele->string);
|
||||
ele->string = (char*)malloc(strlen(key) + 4);
|
||||
bzero(ele->string, strlen(key) + 4);
|
||||
strcpy(ele->string, key);
|
||||
obj->obj_ = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool json::remove(const char* key)
|
||||
{
|
||||
if(!obj_)
|
||||
return false;
|
||||
|
||||
cJSON **addr = NULL,
|
||||
*ele = find(key, false, &addr);
|
||||
|
||||
if(ele)
|
||||
{
|
||||
if(addr)
|
||||
*addr = NULL;
|
||||
cJSON_Delete(ele);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace gb
|
||||
{
|
||||
static char base64_default_table[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" };
|
||||
|
||||
base64::base64() : padding_char_('=')
|
||||
{
|
||||
base64_ind_[0] = base64_char_[0] = 0;
|
||||
|
||||
initialize_base64_table(base64_default_table);
|
||||
}
|
||||
base64::~base64()
|
||||
{}
|
||||
|
||||
bool base64::is_valid_base64_table(const char* table)
|
||||
{
|
||||
bool valid = false;
|
||||
|
||||
if (table && strlen(table) >= 64)
|
||||
{
|
||||
char repeat[4] = { 0 };
|
||||
|
||||
valid = true;
|
||||
for (int i = 0; i < 63; ++i)
|
||||
{
|
||||
repeat[0] = table[i];
|
||||
if (strstr(table + i + 1, repeat))
|
||||
{
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
bool base64::initialize_base64_table(const char* table)
|
||||
{
|
||||
if (!table || strlen(table) < 64)
|
||||
{
|
||||
if (memcmp(base64_default_table, base64_char_, 64) == 0)
|
||||
{
|
||||
return !table;
|
||||
}
|
||||
|
||||
memcpy(base64_char_, base64_default_table, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memcmp(base64_char_, table, 64) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!is_valid_base64_table(table))
|
||||
return false;
|
||||
|
||||
memcpy(base64_char_, table, 64);
|
||||
}
|
||||
base64_char_[64] = base64_char_[65] = 0;
|
||||
|
||||
// initialize base64_index
|
||||
memset(base64_ind_, 0, sizeof(base64_ind_));
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
base64_ind_[base64_char_[i]] = i;
|
||||
}
|
||||
|
||||
// padding char
|
||||
padding_char_ = '=';
|
||||
if (base64_ind_[padding_char_])
|
||||
{
|
||||
for (padding_char_ = 0x21; padding_char_ < 0x7e && base64_ind_[padding_char_] && padding_char_ != base64_char_[0]; ++padding_char_);
|
||||
}
|
||||
|
||||
return padding_char_ < 0x7e;
|
||||
}
|
||||
|
||||
bool base64::set_base64_table(const char* table)
|
||||
{
|
||||
return initialize_base64_table(table ? table : base64_default_table);
|
||||
}
|
||||
std::string base64::encode(const char* data, size_t bytes, unsigned int line_bytes, bool need_padding)
|
||||
{
|
||||
char* str = (char*)malloc(bytes * 2 + 3);
|
||||
unsigned char c1 = 0, c2 = 0, c3 = 0;
|
||||
unsigned long line_len = 0;
|
||||
unsigned long words = bytes / 3;
|
||||
int rest = bytes % 3,
|
||||
pos = 0;
|
||||
std::string ret("");
|
||||
|
||||
for (unsigned long i = 0; i < words; ++i)
|
||||
{
|
||||
// fetch 3 letters
|
||||
c1 = *data++;
|
||||
c2 = *data++;
|
||||
c3 = *data++;
|
||||
|
||||
// encoding into 4-bytes
|
||||
str[pos++] = base64_char_[c1 >> 2];
|
||||
str[pos++] = base64_char_[((c1 << 4) | (c2 >> 4)) & 0x3f];
|
||||
str[pos++] = base64_char_[((c2 << 2) | (c3 >> 6)) & 0x3f];
|
||||
str[pos++] = base64_char_[c3 & 0x3f];
|
||||
line_len += 4;
|
||||
|
||||
// new line ...
|
||||
if ((unsigned int)line_len > line_bytes - 4)
|
||||
{
|
||||
str[pos++] = '\r';
|
||||
str[pos++] = '\n';
|
||||
line_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// rest ...
|
||||
if (rest == 1)
|
||||
{
|
||||
c1 = *data++;
|
||||
str[pos++] = base64_char_[(c1 & 0xfc) >> 2];
|
||||
str[pos++] = base64_char_[((c1 & 0x03) << 4)];
|
||||
if (need_padding)
|
||||
{
|
||||
str[pos++] = padding_char_;
|
||||
str[pos++] = padding_char_;
|
||||
}
|
||||
}
|
||||
else if (rest == 2)
|
||||
{
|
||||
c1 = *data++;
|
||||
c2 = *data++;
|
||||
str[pos++] = base64_char_[(c1 & 0xfc) >> 2];
|
||||
str[pos++] = base64_char_[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
|
||||
str[pos++] = base64_char_[((c2 & 0x0f) << 2)];
|
||||
if (need_padding)
|
||||
{
|
||||
str[pos++] = padding_char_;
|
||||
}
|
||||
}
|
||||
if (pos > 0)
|
||||
{
|
||||
str[pos++] = 0;
|
||||
ret = std::string(str, pos - 1);
|
||||
}
|
||||
free(str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
std::string base64::decode(const char* data, size_t bytes)
|
||||
{
|
||||
char* str = (char*)malloc(bytes + 1);
|
||||
int pos = 0,
|
||||
shifts = 18,
|
||||
value = 0;
|
||||
std::string ret("");
|
||||
|
||||
for (int i = 0; i < (int)bytes; ++i)
|
||||
{
|
||||
if (*data != '\r' && *data != '\n')
|
||||
{
|
||||
if (*data == padding_char_)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
value += base64_ind_[*data] << shifts;
|
||||
if (shifts == 0)
|
||||
{
|
||||
shifts = 18;
|
||||
str[pos++] = (value >> 16) & 0x0ff;
|
||||
str[pos++] = (value >> 8) & 0x0ff;
|
||||
str[pos++] = (value >> 0) & 0x0ff;
|
||||
value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
shifts -= 6;
|
||||
}
|
||||
}
|
||||
data++;
|
||||
}
|
||||
|
||||
if (shifts == 12 || shifts == 6)
|
||||
{
|
||||
str[pos++] = (value >> 16) & 0x0ff;
|
||||
}
|
||||
else if (shifts == 0)
|
||||
{
|
||||
str[pos++] = (value >> 16) & 0x0ff;
|
||||
str[pos++] = (value >> 8) & 0x0ff;
|
||||
}
|
||||
|
||||
if (pos > 0)
|
||||
{
|
||||
str[pos++] = 0;
|
||||
ret = std::string(str, pos - 1);
|
||||
}
|
||||
free(str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include "cJSON.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace gb
|
||||
{
|
||||
class json
|
||||
{
|
||||
cJSON *obj_;
|
||||
cJSON* cur_child_;
|
||||
bool is_array_;
|
||||
|
||||
cJSON* find_sibling(cJSON* first, const char* name, cJSON*** addr);
|
||||
cJSON* find_child(cJSON *parent, std::vector<std::string>& path, bool create, cJSON*** addr = NULL);
|
||||
cJSON* find(const char* path, bool create = false, cJSON*** addr = NULL);
|
||||
|
||||
public:
|
||||
json(char* json_txt = 0);
|
||||
~json();
|
||||
|
||||
static std::string to_string(cJSON* root, bool formatted);
|
||||
static std::string get_value_as_string(cJSON* root, bool integer = false);
|
||||
static void free_node_data(cJSON* node);
|
||||
static cJSON* create_element_with_name(const char* name);
|
||||
|
||||
public:
|
||||
bool attach_text(char* json_txt);
|
||||
bool attach_cjson(cJSON* cjson);
|
||||
bool create_empty(bool array = false);
|
||||
void clear(void);
|
||||
std::string to_string(bool formatted);
|
||||
|
||||
// can be path: child/value ...
|
||||
bool get_value(const char* key, bool& val);
|
||||
bool get_value(const char* key, int& val);
|
||||
bool get_value(const char* key, double& val);
|
||||
bool get_value(const char* key, std::string& val);
|
||||
bool get_value(const char* key, json*& val); // caller shoud call "delete" to free the returned object !!!
|
||||
bool get_value_as_string(const char* key, std::string& val, bool integer);
|
||||
bool get_as_array(const char* key, std::vector<std::string>& val);
|
||||
|
||||
bool first_child(std::string& val, std::string* name = NULL);
|
||||
bool next_child(std::string& val, std::string* name = NULL);
|
||||
|
||||
bool set_value(const char* key, bool val);
|
||||
bool set_value(const char* key, int val);
|
||||
bool set_value(const char* key, double val);
|
||||
bool set_value(const char* key, std::string val);
|
||||
bool set_value(const char* key, const char* val);
|
||||
bool set_value(const char* key, json* obj);
|
||||
|
||||
bool remove(const char* key);
|
||||
};
|
||||
|
||||
class base64
|
||||
{
|
||||
char base64_ind_[128];
|
||||
char base64_char_[80];
|
||||
char padding_char_;
|
||||
|
||||
bool is_valid_base64_table(const char* table);
|
||||
bool initialize_base64_table(const char* table);
|
||||
|
||||
public:
|
||||
base64();
|
||||
~base64();
|
||||
|
||||
public:
|
||||
bool set_base64_table(const char* table = NULL);
|
||||
std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true);
|
||||
std::string decode(const char* data, size_t bytes);
|
||||
};
|
||||
}
|
|
@ -112,7 +112,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
m_versionDll->PostUserOpenInfo(HGVERSION_APPNAME_SCANNER);
|
||||
}
|
||||
|
||||
m_config.load();
|
||||
HGChar cfgpath[512] = {0};
|
||||
QString old;
|
||||
HGBase_GetConfigPath(cfgpath, _countof(cfgpath) - 1);
|
||||
dev_que_.set_root_dir(cfgpath);
|
||||
old = QString::fromStdString(cfgpath) + PATH_SYMBOL + "scanner.schm";
|
||||
if(QFile::exists(old))
|
||||
dev_que::update_old_cfg(old.toStdString().c_str());
|
||||
|
||||
ui->toolBar->addAction(ui->act_scannerSettings);
|
||||
ui->toolBar->addAction(ui->act_acquire);
|
||||
|
@ -292,7 +298,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
m_password = passwordDecrypt(password);
|
||||
|
||||
m_dlgFullScreen = nullptr;
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(!dev_que_.opened_scanner_name().empty() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
ui->act_autoSave->setChecked(auto_save_changes_);
|
||||
ui->act_autoSave->setText(tr("auto save"));
|
||||
|
@ -320,7 +326,6 @@ MainWindow::~MainWindow()
|
|||
m_dlgFullScreen = nullptr;
|
||||
}
|
||||
|
||||
cur_dev_.close();
|
||||
sane_exit();
|
||||
m_versionDll->PostDeviceCloseInfo(m_currDeviceName.toStdString().c_str(), m_devSerialNum.toStdString().c_str(), "", m_devVersionNum.toStdString().c_str());
|
||||
|
||||
|
@ -537,7 +542,7 @@ void MainWindow::on_currItemChanged(int index)
|
|||
bool save = false;
|
||||
if(auto_save_changes_)
|
||||
{
|
||||
// 切换图片时,自动保存编辑过的图像。若想取消,请取消勾选菜单项:图像->自动保存
|
||||
// 切æ<EFBFBD>¢å›¾ç‰‡æ—¶ï¼Œè‡ªåŠ¨ä¿<EFBFBD>å˜ç¼–辑过的图åƒ<EFBFBD>。若想å<EFBFBD>–消,请å<EFBFBD>–消勾选è<EFBFBD>œå<EFBFBD>•é¡¹ï¼šå›¾åƒ?>自动ä¿<C3A4>å˜
|
||||
QString info(tr("Automatically save the edited the edited iamge when switching pictures. To cancel, uncheck the menu item: image-> automatically save"));
|
||||
m_wndStatusBar->setDeviceStatusInfo(info, false);
|
||||
save = true;
|
||||
|
@ -779,15 +784,14 @@ void MainWindow::on_clearCache()
|
|||
void MainWindow::on_sane_dev_arrive(QString devName, bool opened)
|
||||
{
|
||||
bool reconnected = false;
|
||||
if(std::find(dev_schemes_.begin(), dev_schemes_.end(), devName.toStdString()) == dev_schemes_.end())
|
||||
std::vector<std::string> now;
|
||||
std::string stdn(devName.toStdString());
|
||||
|
||||
dev_que_.get_scanners(now);
|
||||
if(std::find(now.begin(), now.end(), stdn) == now.end())
|
||||
{
|
||||
// initializing the device configuration ...
|
||||
DEVCFG cfg;
|
||||
cfg.m_deviceName = devName.toStdString();
|
||||
cfg.m_originDeviceName = devName.toStdString();
|
||||
m_config.load_scanner_configs(devName, &cfg);
|
||||
dev_schemes_.push_back(cfg);
|
||||
ui->menu_device->deviceMenuUpdate(&dev_schemes_, m_currDeviceName.toStdString());
|
||||
dev_que_.add_scanner(stdn.c_str());
|
||||
|
||||
// statu info ...
|
||||
QString info(tr("found device ") +": " + devName);
|
||||
|
@ -807,31 +811,20 @@ void MainWindow::on_sane_dev_arrive(QString devName, bool opened)
|
|||
m_dialogLog->addLog(info, !opened);
|
||||
HGBase_WriteInfo(!opened ? HGBASE_INFOTYPE_ERROR : HGBASE_INFOTYPE_DESC, "%s", getStdString(info).c_str());
|
||||
reconnected = true;
|
||||
dev_que_.set_online(true, stdn.c_str());
|
||||
}
|
||||
|
||||
// enable the device menu item ...
|
||||
ui->menu_device->connectedDevice(devName);
|
||||
|
||||
// open it if no device has been opened ...
|
||||
if (!cur_dev_.is_online())
|
||||
if (dev_que_.opened_scanner_name().empty())
|
||||
{
|
||||
if (cur_dev_.handle() && devName.toStdString() == cur_dev_.name())
|
||||
{
|
||||
cur_dev_.set_online(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<DEVCFG>::iterator it = std::find(dev_schemes_.begin(), dev_schemes_.end(), devName.toStdString());
|
||||
OPTSCHEME *schm = nullptr;
|
||||
|
||||
if(it!= dev_schemes_.end())
|
||||
schm = it->get_current();
|
||||
|
||||
open_scanner(devName, schm);
|
||||
}
|
||||
dev_que_.open_scanner(stdn.c_str());
|
||||
}
|
||||
ui->menu_device->deviceMenuUpdate(&dev_que_);
|
||||
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(!dev_que_.opened_scanner_name().empty() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
}
|
||||
|
||||
|
@ -842,18 +835,15 @@ void MainWindow::on_sane_dev_remove(QString devName)
|
|||
|
||||
m_wndStatusBar->setDeviceStatusInfo(info, true);
|
||||
m_dialogLog->addLog(info, true);
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "%s", getStdString(info).c_str());
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "%s", getStdString(info).c_str());
|
||||
|
||||
// enable the device menu item ...
|
||||
ui->menu_device->disconnectedDevice(devName);
|
||||
|
||||
// set openning device offline ...
|
||||
if(devName.toStdString() == cur_dev_.name())
|
||||
{
|
||||
cur_dev_.set_online(false);
|
||||
}
|
||||
dev_que_.set_online(false, devName.toStdString().c_str());
|
||||
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1111,7 @@ void MainWindow::on_scan_finish(QString finishInfo, int err)
|
|||
m_currScanCount = 0;
|
||||
m_isScanning = false;
|
||||
m_thumb->setAcceptDrops(true);
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
m_wndStatusBar->setDeviceStatusInfo(finishInfo, (err != SANE_STATUS_GOOD));
|
||||
m_dialogLog->addLog(finishInfo, (err != SANE_STATUS_GOOD), LOG_EVENT_SCAN_STOPPED);
|
||||
|
@ -1142,7 +1132,7 @@ void MainWindow::on_continueScan()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!cur_dev_.is_online() || m_isScanning || 0 == m_scanType)
|
||||
if (!dev_que_.is_online() || m_isScanning || 0 == m_scanType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1158,9 +1148,9 @@ void MainWindow::on_continueScan()
|
|||
|
||||
m_dpi = getDpi();
|
||||
if (m_singleScan)
|
||||
ret = sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_TEST_SINGLE, nullptr, nullptr);
|
||||
ret = sane_io_control(dev_que_.handle(), IO_CTRL_CODE_TEST_SINGLE, nullptr, nullptr);
|
||||
else
|
||||
ret = sane_start(cur_dev_.handle());
|
||||
ret = sane_start(dev_que_.handle());
|
||||
if (ret != SANE_STATUS_GOOD)
|
||||
{
|
||||
m_wndStatusBar->setDeviceStatusInfo(tr("start failed"), true);
|
||||
|
@ -1191,7 +1181,7 @@ void MainWindow::on_continueScan()
|
|||
{
|
||||
m_isScanning = true;
|
||||
m_thumb->setAcceptDrops(false);
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
}
|
||||
|
||||
|
@ -1200,7 +1190,7 @@ void MainWindow::on_continueScan()
|
|||
|
||||
void MainWindow::on_stopScan()
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online(), m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online(), m_isScanning);
|
||||
|
||||
if (!m_isScanning)
|
||||
{
|
||||
|
@ -1215,9 +1205,9 @@ void MainWindow::on_stopScan()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (cur_dev_.is_online())
|
||||
if (dev_que_.is_online())
|
||||
{
|
||||
sane_cancel(cur_dev_.handle());
|
||||
sane_cancel(dev_que_.handle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1322,17 +1312,17 @@ HGUInt MainWindow::getDpi()
|
|||
{
|
||||
HGUInt dpi = 200;
|
||||
SANE_Int num_dev_options = 0;
|
||||
sane_control_option(cur_dev_.handle(), 0, SANE_ACTION_GET_VALUE, &num_dev_options, nullptr);
|
||||
sane_control_option(dev_que_.handle(), 0, SANE_ACTION_GET_VALUE, &num_dev_options, nullptr);
|
||||
for (int i = 1; i < num_dev_options; ++i)
|
||||
{
|
||||
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(cur_dev_.handle(), i);
|
||||
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(dev_que_.handle(), i);
|
||||
if (nullptr == desp)
|
||||
continue;
|
||||
|
||||
if (SANE_TYPE_INT == desp->type)
|
||||
{
|
||||
SANE_Int value = 0;
|
||||
sane_control_option(cur_dev_.handle(), i, SANE_ACTION_GET_VALUE, &value, nullptr);
|
||||
sane_control_option(dev_que_.handle(), i, SANE_ACTION_GET_VALUE, &value, nullptr);
|
||||
if (0 == strcmp(desp->name, SANE_STD_OPT_NAME_RESOLUTION))
|
||||
{
|
||||
dpi = (HGUInt)value;
|
||||
|
@ -1452,41 +1442,41 @@ void MainWindow::updateActionStatus()
|
|||
selectIndexs.push_back(i);
|
||||
}
|
||||
|
||||
ui->act_open->setEnabled(!cur_dev_.is_online() || !m_isScanning);
|
||||
ui->act_insert->setEnabled(!cur_dev_.is_online() || !m_isScanning);
|
||||
ui->act_open->setEnabled(!dev_que_.is_online() || !m_isScanning);
|
||||
ui->act_insert->setEnabled(!dev_que_.is_online() || !m_isScanning);
|
||||
ui->act_save->setEnabled(nullptr != img && -1 != m_currIndex && m_multiPageCount == 1
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_saveAs->setEnabled(nullptr != img);
|
||||
ui->act_Export->setEnabled(0 != count && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_closeFile->setEnabled(!selectIndexs.empty() && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_closeAll->setEnabled(0 != count && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_imageInfo->setEnabled(-1 != m_currIndex && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->menu_multiPages->setEnabled(m_multiPageCount > 1 && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_Export->setEnabled(0 != count && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_closeFile->setEnabled(!selectIndexs.empty() && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_closeAll->setEnabled(0 != count && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_imageInfo->setEnabled(-1 != m_currIndex && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->menu_multiPages->setEnabled(m_multiPageCount > 1 && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_previous->setEnabled(count > 0 && (-1 == m_currIndex || m_currIndex > 0)
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_next->setEnabled(count > 0 && (-1 == m_currIndex || m_currIndex < count - 1)
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_first->setEnabled(count > 0 && 0 != m_currIndex && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_last->setEnabled(count > 0 && count - 1 != m_currIndex && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_openPageNum->setEnabled(count > 0 && (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_first->setEnabled(count > 0 && 0 != m_currIndex && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_last->setEnabled(count > 0 && count - 1 != m_currIndex && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_openPageNum->setEnabled(count > 0 && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_previousPage->setEnabled(-1 != m_currIndex && m_multiPageCount > 0 && m_multiIndex > 0
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_nextPage->setEnabled(-1 != m_currIndex && m_multiPageCount > 0 && -1 != m_multiIndex && m_multiIndex < m_multiPageCount - 1
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_firstPage->setEnabled(-1 != m_currIndex && m_multiPageCount > 0 && 0 != m_multiIndex
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_lastPage->setEnabled(-1 != m_currIndex && m_multiPageCount > 0 && m_multiIndex != m_multiPageCount - 1
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
m_multiPageLineEdit->setText(QString("%1/%2").arg(m_multiIndex + 1).arg(m_multiPageCount));
|
||||
ui->toolBar->actions().at(16)->setVisible(-1 != m_currIndex && m_multiPageCount > 1 && -1 != m_multiIndex
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_sortPages->setEnabled(0 != count && (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_sortPages->setEnabled(0 != count && (!dev_que_.is_online() || !m_isScanning));
|
||||
|
||||
ui->act_imageEdit->setEnabled(nullptr != img);
|
||||
ui->act_zoomIn->setEnabled(nullptr != img);
|
||||
ui->act_zoomOut->setEnabled(nullptr != img);
|
||||
ui->act_fullscreen->setEnabled(count > 0 && -1 != m_currIndex && -1 != m_multiIndex
|
||||
&& (!cur_dev_.is_online() || !m_isScanning));
|
||||
&& (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_fitWindowSize->setEnabled(nullptr != img);
|
||||
ui->act_fitWindowWidth->setEnabled(nullptr != img);
|
||||
ui->act_realSize->setEnabled(nullptr != img);
|
||||
|
@ -1495,8 +1485,8 @@ void MainWindow::updateActionStatus()
|
|||
ui->act_180->setEnabled(nullptr != img);
|
||||
ui->menu_Auto_Image_Size->setEnabled(nullptr != img);
|
||||
ui->act_adjust->setEnabled(nullptr != img);
|
||||
ui->act_multiRotate->setEnabled(0 != count && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->menu_Rotate->setEnabled((0 != count || nullptr != img) && (!cur_dev_.is_online() || !m_isScanning));
|
||||
ui->act_multiRotate->setEnabled(0 != count && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->menu_Rotate->setEnabled((0 != count || nullptr != img) && (!dev_que_.is_online() || !m_isScanning));
|
||||
ui->act_autoCrop->setEnabled(nullptr != img);
|
||||
|
||||
ui->act_signIn->setEnabled(!m_admin_loggedIn);
|
||||
|
@ -1507,17 +1497,17 @@ void MainWindow::updateActionStatus()
|
|||
ui->act_consume->setEnabled(m_admin_loggedIn);
|
||||
ui->act_clearRoller->setEnabled(m_admin_loggedIn);
|
||||
|
||||
ui->act_acquireInto->setEnabled(cur_dev_.is_online() && !m_isScanning);
|
||||
ui->act_acquireSingle->setEnabled(cur_dev_.is_online() && !m_isScanning);
|
||||
ui->act_acquire->setEnabled(cur_dev_.is_online() && !m_isScanning);
|
||||
ui->act_scannerSettings->setEnabled(cur_dev_.is_online() && !m_isScanning);
|
||||
ui->act_insertFromScanner->setEnabled(cur_dev_.is_online() && !m_isScanning);
|
||||
ui->menu_scan->setEnabled(cur_dev_.is_online() && !m_isScanning);
|
||||
ui->menu_device->setEnabled(!cur_dev_.is_online() || !m_isScanning);
|
||||
ui->act_device_log->setEnabled(m_admin_loggedIn && !m_isScanning && cur_dev_.is_online());
|
||||
ui->act_acquireInto->setEnabled(dev_que_.is_online() && !m_isScanning);
|
||||
ui->act_acquireSingle->setEnabled(dev_que_.is_online() && !m_isScanning);
|
||||
ui->act_acquire->setEnabled(dev_que_.is_online() && !m_isScanning);
|
||||
ui->act_scannerSettings->setEnabled(dev_que_.is_online() && !m_isScanning);
|
||||
ui->act_insertFromScanner->setEnabled(dev_que_.is_online() && !m_isScanning);
|
||||
ui->menu_scan->setEnabled(dev_que_.is_online() && !m_isScanning);
|
||||
ui->menu_device->setEnabled(!dev_que_.is_online() || !m_isScanning);
|
||||
ui->act_device_log->setEnabled(m_admin_loggedIn && !m_isScanning && dev_que_.is_online());
|
||||
ui->act_driver_log->setEnabled(m_admin_loggedIn);
|
||||
|
||||
m_moveToAction->setEnabled(!selectIndexs.empty() && (!cur_dev_.is_online() || !m_isScanning));
|
||||
m_moveToAction->setEnabled(!selectIndexs.empty() && (!dev_que_.is_online() || !m_isScanning));
|
||||
}
|
||||
|
||||
void MainWindow::startSaveMessageBox(QWidget* parent)
|
||||
|
@ -1914,7 +1904,7 @@ void MainWindow::on_act_save_triggered()
|
|||
|
||||
if (!judgeDiskSpace(savePath))
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2089,7 +2079,7 @@ void MainWindow::on_act_saveAs_triggered()
|
|||
|
||||
if(!judgeDiskSpace(savePath))
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2193,7 +2183,7 @@ void MainWindow::on_act_Export_triggered()
|
|||
|
||||
if(!judgeDiskSpace(fileName))
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2743,7 +2733,7 @@ void MainWindow::on_act_clearRoller_triggered()
|
|||
return;
|
||||
|
||||
unsigned int count = 0;
|
||||
int ret = sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_CLEAR_ROLLER_COUNT, nullptr, &count);
|
||||
int ret = sane_io_control(dev_que_.handle(), IO_CTRL_CODE_CLEAR_ROLLER_COUNT, nullptr, &count);
|
||||
|
||||
if(ret == SANE_STATUS_GOOD)
|
||||
{
|
||||
|
@ -2814,15 +2804,14 @@ void MainWindow::my_url_handler(const QUrl& url)
|
|||
if(msg.clickedButton() == msg.button(QMessageBox::Yes))
|
||||
{
|
||||
unsigned int count = 0;
|
||||
int ret = sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_CLEAR_ROLLER_COUNT, nullptr, &count);
|
||||
int ret = sane_io_control(dev_que_.handle(), IO_CTRL_CODE_CLEAR_ROLLER_COUNT, nullptr, &count);
|
||||
|
||||
QString info;
|
||||
if(ret == SANE_STATUS_GOOD)
|
||||
{
|
||||
info = tr("Roller scanned count has been set to 0.");
|
||||
|
||||
// +请重新进入关于界面以获取最新值
|
||||
info += tr("Please re-enter the Abount screen to obtain the latest value");
|
||||
// +请é‡<C3A9>新进入关于界é<C592>¢ä»¥èŽ·å<C2B7>–最新å€? info += tr("Please re-enter the Abount screen to obtain the latest value");
|
||||
}
|
||||
else
|
||||
info = tr("Roller scanned count reset failed.");
|
||||
|
@ -2853,13 +2842,13 @@ void MainWindow::on_act_about_triggered()
|
|||
.arg(appName).arg("v2.0.9.061").arg(copyRight).arg(developer).arg(website).arg(contact).arg(afterSelesContact).arg(address).arg(navigation));
|
||||
|
||||
QDesktopServices::setUrlHandler(MY_URL_SCHEME, this, "my_url_handler");
|
||||
if (sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_ABOUT_INFO, about, &len) == SANE_STATUS_NO_MEM)
|
||||
if (sane_io_control(dev_que_.handle(), IO_CTRL_CODE_ABOUT_INFO, about, &len) == SANE_STATUS_NO_MEM)
|
||||
{
|
||||
about = (SANE_About*)malloc(len + 128);
|
||||
if (about)
|
||||
{
|
||||
memset(about, 0, len + 128);
|
||||
if (sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_ABOUT_INFO, about, &len) == SANE_STATUS_GOOD)
|
||||
if (sane_io_control(dev_que_.handle(), IO_CTRL_CODE_ABOUT_INFO, about, &len) == SANE_STATUS_GOOD)
|
||||
{
|
||||
title = tr("about %1").arg(QString::fromStdString(about->title));
|
||||
content = tr("<p>Version: %1</p>").arg(QString::fromStdString(about->version));
|
||||
|
@ -2890,45 +2879,14 @@ void MainWindow::on_act_about_triggered()
|
|||
|
||||
void MainWindow::on_act_scannerSettings_triggered()
|
||||
{
|
||||
if (!cur_dev_.is_online() || m_isScanning)
|
||||
if (!dev_que_.is_online() || m_isScanning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DEVCFG cfg;
|
||||
|
||||
int m = 0;
|
||||
for(; m < (int)dev_schemes_.size(); ++m)
|
||||
{
|
||||
std::string t = dev_schemes_[m].m_originDeviceName;
|
||||
cfg.m_deviceName = cur_dev_.name();
|
||||
if(strcmp(t.c_str(), cur_dev_.name().c_str()) == 0)
|
||||
{
|
||||
cfg = dev_schemes_[m];
|
||||
dev_schemes_.erase(dev_schemes_.begin() + m);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hg_settingdialog dlg(cur_dev_.handle(), this, &cfg);
|
||||
dlg.set_config_file(&m_config);
|
||||
hg_settingdialog dlg(dev_que_.handle(), this, &dev_que_);
|
||||
dlg.exec();
|
||||
int changes = dlg.get_changed_items();
|
||||
dev_schemes_.insert(dev_schemes_.begin(), cfg);
|
||||
if(changes)
|
||||
{
|
||||
m_config.save_scanner_configs(&cfg);
|
||||
ui->menu_device->deviceMenuUpdate(&dev_schemes_, m_currDeviceName.toStdString());
|
||||
|
||||
QString dev(QString::fromStdString(cfg.m_deviceName)), scheme("");
|
||||
if(cfg.get_current())
|
||||
scheme = QString::fromStdString(cfg.get_current()->m_schemeTitle);
|
||||
else if(cfg.schemes.size())
|
||||
scheme = QString::fromStdString(cfg.schemes[0].m_schemeTitle);
|
||||
ui->menu_device->setOptionChecked(dev, scheme, true);
|
||||
|
||||
// setWindowTitle(dev + "(" + scheme + ")");
|
||||
}
|
||||
ui->menu_device->deviceMenuUpdate(&dev_que_);
|
||||
}
|
||||
|
||||
void MainWindow::on_act_acquire_triggered()
|
||||
|
@ -2938,7 +2896,7 @@ void MainWindow::on_act_acquire_triggered()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!cur_dev_.is_online() || m_isScanning)
|
||||
if (!dev_que_.is_online() || m_isScanning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2958,17 +2916,17 @@ void MainWindow::on_act_acquire_triggered()
|
|||
|
||||
if (!startSpaceCheck(this))
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
return;
|
||||
}
|
||||
|
||||
startSaveMessageBox(this);
|
||||
|
||||
m_dpi = getDpi();
|
||||
SANE_Status ret = sane_start(cur_dev_.handle());
|
||||
SANE_Status ret = sane_start(dev_que_.handle());
|
||||
if (ret != SANE_STATUS_GOOD)
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_wndStatusBar->setDeviceStatusInfo(tr("start failed"), true);
|
||||
m_dialogLog->addLog(tr("start failed") + "(" + QString(sane_err_desc(ret)) + ")", true);
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "%s", getStdString(tr("start failed")).c_str());
|
||||
|
@ -2997,7 +2955,7 @@ void MainWindow::on_act_acquire_triggered()
|
|||
{
|
||||
m_isScanning = true;
|
||||
m_thumb->setAcceptDrops(false);
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
}
|
||||
|
||||
|
@ -3011,7 +2969,7 @@ void MainWindow::on_act_acquireSingle_triggered()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!cur_dev_.is_online() || m_isScanning)
|
||||
if (!dev_que_.is_online() || m_isScanning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3031,17 +2989,17 @@ void MainWindow::on_act_acquireSingle_triggered()
|
|||
|
||||
if (!startSpaceCheck(this))
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
return;
|
||||
}
|
||||
|
||||
startSaveMessageBox(this);
|
||||
|
||||
m_dpi = getDpi();
|
||||
SANE_Status ret = sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_TEST_SINGLE, nullptr, nullptr);
|
||||
SANE_Status ret = sane_io_control(dev_que_.handle(), IO_CTRL_CODE_TEST_SINGLE, nullptr, nullptr);
|
||||
if (ret != SANE_STATUS_GOOD)
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_wndStatusBar->setDeviceStatusInfo(tr("start failed"), true);
|
||||
m_dialogLog->addLog(tr("start failed") + "(" + QString(sane_err_desc(ret)) + ")", true);
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "%s", getStdString(tr("start failed")).c_str());
|
||||
|
@ -3070,7 +3028,7 @@ void MainWindow::on_act_acquireSingle_triggered()
|
|||
{
|
||||
m_isScanning = true;
|
||||
m_thumb->setAcceptDrops(false);
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
}
|
||||
|
||||
|
@ -3079,7 +3037,7 @@ void MainWindow::on_act_acquireSingle_triggered()
|
|||
|
||||
void MainWindow::on_act_acquireInto_triggered()
|
||||
{
|
||||
if (!cur_dev_.is_online() || m_isScanning)
|
||||
if (!dev_que_.is_online() || m_isScanning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3120,17 +3078,17 @@ void MainWindow::on_act_acquireInto_triggered()
|
|||
|
||||
if (!startSpaceCheck(this))
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
return;
|
||||
}
|
||||
|
||||
startSaveMessageBox(this);
|
||||
|
||||
m_dpi = getDpi();
|
||||
SANE_Status ret = sane_start(cur_dev_.handle());
|
||||
SANE_Status ret = sane_start(dev_que_.handle());
|
||||
if (ret != SANE_STATUS_GOOD)
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_wndStatusBar->setDeviceStatusInfo(tr("start failed"), true);
|
||||
m_dialogLog->addLog(tr("start failed") + "(" + QString(sane_err_desc(ret)) + ")", true);
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "%s", getStdString(tr("start failed")).c_str());
|
||||
|
@ -3159,7 +3117,7 @@ void MainWindow::on_act_acquireInto_triggered()
|
|||
{
|
||||
m_isScanning = true;
|
||||
m_thumb->setAcceptDrops(false);
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
}
|
||||
|
||||
|
@ -3174,7 +3132,7 @@ void MainWindow::on_act_insertFromScanner_triggered()
|
|||
return;
|
||||
}
|
||||
|
||||
if (!cur_dev_.is_online() || m_isScanning)
|
||||
if (!dev_que_.is_online() || m_isScanning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3208,17 +3166,17 @@ void MainWindow::on_act_insertFromScanner_triggered()
|
|||
|
||||
if (!startSpaceCheck(this))
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
return;
|
||||
}
|
||||
|
||||
startSaveMessageBox(this);
|
||||
|
||||
m_dpi = getDpi();
|
||||
SANE_Status ret = sane_start(cur_dev_.handle());
|
||||
SANE_Status ret = sane_start(dev_que_.handle());
|
||||
if (ret != SANE_STATUS_GOOD)
|
||||
{
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_wndStatusBar->setDeviceStatusInfo(tr("start failed"), true);
|
||||
m_dialogLog->addLog(tr("start failed") + "(" + QString(sane_err_desc(ret)) + ")", true);
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "%s", getStdString(tr("start failed")).c_str());
|
||||
|
@ -3247,7 +3205,7 @@ void MainWindow::on_act_insertFromScanner_triggered()
|
|||
{
|
||||
m_isScanning = true;
|
||||
m_thumb->setAcceptDrops(false);
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
}
|
||||
|
||||
|
@ -3331,9 +3289,9 @@ void MainWindow::on_act_imageEdit_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
bool MainWindow::open_scanner(const QString& name, OPTSCHEME* schm)
|
||||
bool MainWindow::open_scanner(const QString& name, const QString& scheme)
|
||||
{
|
||||
bool ret = cur_dev_.open(name.toStdString());
|
||||
bool ret = dev_que_.open_scanner(name.toStdString().c_str(), scheme.toStdString().c_str()) == SANE_STATUS_GOOD;
|
||||
QString info(tr("open scanner ") + " " + name + " ");
|
||||
QString title(tr("app name"));
|
||||
|
||||
|
@ -3341,21 +3299,21 @@ bool MainWindow::open_scanner(const QString& name, OPTSCHEME* schm)
|
|||
{
|
||||
std::string serialNum;
|
||||
unsigned int serialNumLen = 0;
|
||||
if(SANE_STATUS_NO_MEM == sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_GET_SERIAL, nullptr, &serialNumLen)
|
||||
if(SANE_STATUS_NO_MEM == sane_io_control(dev_que_.handle(), IO_CTRL_CODE_GET_SERIAL, nullptr, &serialNumLen)
|
||||
&& serialNumLen)
|
||||
{
|
||||
serialNum.resize(serialNumLen);
|
||||
sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_GET_SERIAL, &serialNum[0], &serialNumLen);
|
||||
sane_io_control(dev_que_.handle(), IO_CTRL_CODE_GET_SERIAL, &serialNum[0], &serialNumLen);
|
||||
}
|
||||
m_devSerialNum = QString::fromStdString(serialNum);
|
||||
|
||||
std::string versionNum;
|
||||
unsigned int versionNumLen = 0;
|
||||
if(SANE_STATUS_NO_MEM == sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_GET_HARDWARE_VERSION, nullptr, &versionNumLen)
|
||||
if(SANE_STATUS_NO_MEM == sane_io_control(dev_que_.handle(), IO_CTRL_CODE_GET_HARDWARE_VERSION, nullptr, &versionNumLen)
|
||||
&& versionNumLen)
|
||||
{
|
||||
versionNum.resize(versionNumLen);
|
||||
sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_GET_HARDWARE_VERSION, &versionNum[0], &versionNumLen);
|
||||
sane_io_control(dev_que_.handle(), IO_CTRL_CODE_GET_HARDWARE_VERSION, &versionNum[0], &versionNumLen);
|
||||
}
|
||||
m_devVersionNum = QString::fromStdString(versionNum);
|
||||
|
||||
|
@ -3368,26 +3326,6 @@ bool MainWindow::open_scanner(const QString& name, OPTSCHEME* schm)
|
|||
m_dialogLog->addLog(info, false);
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "%s", getStdString(info).c_str());
|
||||
|
||||
bool apply = false;
|
||||
if(schm)
|
||||
{
|
||||
apply = cur_dev_.apply_setting(schm);
|
||||
info = tr("apply setting ") + QString::fromStdString(schm->m_schemeTitle) + (apply ? tr(" success") : tr(" failed"));
|
||||
ui->menu_device->setOptionChecked(name, QString::fromStdString(schm->m_schemeTitle), apply);
|
||||
if(apply)
|
||||
title += "(" + QString::fromStdString(schm->m_schemeTitle) + ")";
|
||||
}
|
||||
|
||||
if(!apply)
|
||||
{
|
||||
DEVCFG first;
|
||||
if(first.schemes.size())
|
||||
{
|
||||
ui->menu_device->setOptionChecked(name, QString::fromStdString(first.schemes[0].m_schemeTitle), true);
|
||||
title += "(" + QString::fromStdString(first.schemes[0].m_schemeTitle) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
m_wndStatusBar->setDeviceStatusInfo(tr("be ready"), false);
|
||||
}
|
||||
else
|
||||
|
@ -3398,7 +3336,7 @@ bool MainWindow::open_scanner(const QString& name, OPTSCHEME* schm)
|
|||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "%s", getStdString(info).c_str());
|
||||
}
|
||||
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
// setWindowTitle(title);
|
||||
return ret;
|
||||
|
@ -3591,75 +3529,30 @@ void MainWindow::on_scanOptions_changed(const QString &device, const QString &op
|
|||
QString title(tr("app name"));
|
||||
if(checked_now)
|
||||
{
|
||||
OPTSCHEME *schm = nullptr;
|
||||
int ind = config::find_config(device, dev_schemes_);
|
||||
|
||||
if(ind == -1)
|
||||
std::string curdev(dev_que_.opened_scanner_name());
|
||||
int ret = 0;
|
||||
if(curdev != device.toStdString())
|
||||
{
|
||||
QString info(tr("lost config") + ": " + device);
|
||||
m_wndStatusBar->setDeviceStatusInfo(info, true);
|
||||
m_dialogLog->addLog(info, true);
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "%s", getStdString(info).c_str());
|
||||
|
||||
if(cur_dev_.name() != device.toStdString())
|
||||
open_scanner(device, nullptr);
|
||||
return;
|
||||
ret = dev_que_.open_scanner(device.toStdString().c_str(), option.toStdString().c_str());
|
||||
}
|
||||
|
||||
DEVCFG& cfg = dev_schemes_[ind];
|
||||
// std::vector<OPTSCHEME>::iterator it = std::find(cfg.schemes.begin(), cfg.schemes.end(), option.toStdString());
|
||||
// if(it == cfg.schemes.end())
|
||||
// cfg.cur_scheme = -1;
|
||||
int m = 0;
|
||||
for(; m < (int)cfg.schemes.size(); ++m)
|
||||
{
|
||||
std::string t = cfg.schemes[m].m_schemeTitle;
|
||||
if(strcmp(t.c_str(), option.toStdString().c_str()) == 0)
|
||||
{
|
||||
schm = &(cfg.schemes[m]);
|
||||
cfg.cur_scheme = m - 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg.cur_scheme = -1;
|
||||
}
|
||||
}
|
||||
m_config.save_scanner_configs(&cfg);
|
||||
|
||||
if(cur_dev_.name() != device.toStdString())
|
||||
{
|
||||
if(!open_scanner(device, schm))
|
||||
ui->menu_device->setOptionChecked(device, option, false);
|
||||
return;
|
||||
else {
|
||||
ret = dev_que_.apply_scheme(option.toStdString().c_str());
|
||||
}
|
||||
|
||||
QString info(tr("apply setting") + " '" + option + "' ");
|
||||
bool ok = cur_dev_.apply_setting(schm); // check result ?
|
||||
if(ok)
|
||||
if(ret == 0)
|
||||
{
|
||||
info += tr("success");
|
||||
cfg.select(option.toStdString().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->menu_device->setOptionChecked(device, option, false);
|
||||
{
|
||||
DEVCFG init;
|
||||
if(init.schemes.size())
|
||||
{
|
||||
std::string name(init.schemes[0].m_schemeTitle);
|
||||
cfg.select(name.c_str());
|
||||
ui->menu_device->setOptionChecked(device, QString::fromStdString(name), true);
|
||||
}
|
||||
}
|
||||
info += tr("failed");
|
||||
}
|
||||
|
||||
m_config.save_scanner_configs(&cfg);
|
||||
m_wndStatusBar->setDeviceStatusInfo(info, !ok);
|
||||
m_dialogLog->addLog(info, !ok);
|
||||
HGBase_WriteInfo(!ok ? HGBASE_INFOTYPE_ERROR : HGBASE_INFOTYPE_DESC, "%s", getStdString(info).c_str());
|
||||
m_wndStatusBar->setDeviceStatusInfo(info, ret != 0);
|
||||
m_dialogLog->addLog(info, ret != 0);
|
||||
HGBase_WriteInfo(ret != 0 ? HGBASE_INFOTYPE_ERROR : HGBASE_INFOTYPE_DESC, "%s", getStdString(info).c_str());
|
||||
title = device + "(" + option + ")";
|
||||
}
|
||||
else
|
||||
|
@ -3672,7 +3565,7 @@ void MainWindow::on_scanOptions_changed(const QString &device, const QString &op
|
|||
msg.exec();
|
||||
if(msg.clickedButton() == msg.button(QMessageBox::Yes))
|
||||
{
|
||||
cur_dev_.close();
|
||||
dev_que_.close_scanner();
|
||||
m_versionDll->PostDeviceCloseInfo(device.toStdString().c_str(), m_devSerialNum.toStdString().c_str(), "", m_devVersionNum.toStdString().c_str());
|
||||
|
||||
m_dialogLog->addLog(tr("close ") + device, false);
|
||||
|
@ -3684,14 +3577,14 @@ void MainWindow::on_scanOptions_changed(const QString &device, const QString &op
|
|||
}
|
||||
}
|
||||
|
||||
m_dialogLog->updateStatus(cur_dev_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
m_dialogLog->updateStatus(dev_que_.is_online() && 0 != m_scanType, m_isScanning);
|
||||
updateActionStatus();
|
||||
// setWindowTitle(title);
|
||||
}
|
||||
|
||||
void MainWindow::on_act_sortPages_triggered()
|
||||
{
|
||||
if (cur_dev_.is_online() && m_isScanning)
|
||||
if (dev_que_.is_online() && m_isScanning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3781,7 +3674,7 @@ void MainWindow::on_act_driver_log_triggered()
|
|||
{
|
||||
char log_file_path[260] = {0};
|
||||
unsigned int type = SANE_LogFileType::LOG_FILE_DRIVER;
|
||||
SANE_Status statu = sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_GET_LOG_FILE, log_file_path, &type);
|
||||
SANE_Status statu = sane_io_control(dev_que_.handle(), IO_CTRL_CODE_GET_LOG_FILE, log_file_path, &type);
|
||||
if(statu == SANE_STATUS_GOOD)
|
||||
{
|
||||
if(log_file_path[0])
|
||||
|
@ -3799,7 +3692,7 @@ void MainWindow::on_act_device_log_triggered()
|
|||
{
|
||||
char log_file_path[260] = {0};
|
||||
unsigned int type = SANE_LogFileType::LOG_FILE_DEVICE;
|
||||
SANE_Status statu = sane_io_control(cur_dev_.handle(), IO_CTRL_CODE_GET_LOG_FILE, log_file_path, &type);
|
||||
SANE_Status statu = sane_io_control(dev_que_.handle(), IO_CTRL_CODE_GET_LOG_FILE, log_file_path, &type);
|
||||
if(statu == SANE_STATUS_GOOD)
|
||||
{
|
||||
if(log_file_path[0])
|
||||
|
|
|
@ -7,14 +7,12 @@
|
|||
#include "HGImgView.h"
|
||||
#include "HGImgThumb.h"
|
||||
#include "sane/sane_ex.h"
|
||||
#include "config.h"
|
||||
#include "dialog_aquireinto.h"
|
||||
#include "imgfmt/HGImgFmt.h"
|
||||
#include "VersionDll.h"
|
||||
#include "device_menu.h"
|
||||
#include "sane_device.h"
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
QT_END_NAMESPACE
|
||||
|
@ -235,7 +233,7 @@ private:
|
|||
bool startSpaceCheck(QWidget* parent);
|
||||
QString passwordEncrypt(const QString& password);
|
||||
QString passwordDecrypt(const QString& transcode);
|
||||
bool open_scanner(const QString& name, OPTSCHEME* schm);
|
||||
bool open_scanner(const QString& name, const QString& scheme);
|
||||
bool judgeDiskSpace(QString currentPath);
|
||||
void upgradeApp(QString pkgPath);
|
||||
bool isLimitAccessFolder(QString filePath);
|
||||
|
@ -251,9 +249,7 @@ private:
|
|||
QAction *m_moveToAction;
|
||||
QListWidget* m_listwidget;
|
||||
|
||||
config m_config;
|
||||
sane_dev cur_dev_;
|
||||
std::vector<DEVCFG> dev_schemes_;
|
||||
dev_que dev_que_;
|
||||
|
||||
bool auto_save_changes_;
|
||||
bool save_from_changed_;
|
||||
|
|
|
@ -8,108 +8,14 @@ sane_dev::~sane_dev()
|
|||
close();
|
||||
}
|
||||
|
||||
bool sane_dev::apply(OPTSCHEME* schm)
|
||||
bool sane_dev::apply(gb::sane_config_schm* schm)
|
||||
{
|
||||
SANE_Int count = 0,
|
||||
afterdo = 0;
|
||||
bool ret = false;
|
||||
|
||||
if(sane_control_option(hdev_, 0, SANE_ACTION_GET_VALUE, &count, &afterdo) == SANE_STATUS_GOOD)
|
||||
{
|
||||
int applied = 0;
|
||||
for(int i = 1; i < count; ++i)
|
||||
{
|
||||
const SANE_Option_Descriptor* desc = sane_get_option_descriptor(hdev_, i);
|
||||
|
||||
if(!desc)
|
||||
continue;
|
||||
if(desc->type == SANE_TYPE_GROUP ||
|
||||
desc->type == SANE_TYPE_BUTTON)
|
||||
continue;
|
||||
|
||||
act_result result = apply(desc, i, schm->opts);
|
||||
if(result == ACT_RESULT_NO_NEED)
|
||||
continue;
|
||||
|
||||
if(result == ACT_RESULT_SUCCESS)
|
||||
applied++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
ret = schm->opts.size() == applied;
|
||||
}
|
||||
|
||||
if(ret)
|
||||
cfg_name_ = schm->m_schemeTitle;
|
||||
|
||||
return ret;
|
||||
}
|
||||
sane_dev::act_result sane_dev::apply(const SANE_Option_Descriptor* desc, int opt, const std::vector<OPTVAL>& vals)
|
||||
{
|
||||
act_result result = ACT_RESULT_NO_NEED;
|
||||
const OPTVAL *cfg = nullptr;
|
||||
|
||||
for(size_t i = 0; i < vals.size(); ++i)
|
||||
{
|
||||
if(vals[i].name == desc->name)
|
||||
{
|
||||
cfg = &vals[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(cfg)
|
||||
{
|
||||
SANE_Int afterdo = 0;
|
||||
void *data = nullptr, *str = nullptr;
|
||||
SANE_Int nv = 0;
|
||||
SANE_Bool bv = false;
|
||||
SANE_Fixed fv = 0;
|
||||
|
||||
result = ACT_RESULT_FAILED;
|
||||
if(desc->type == SANE_TYPE_INT)
|
||||
{
|
||||
nv = atoi(cfg->val.c_str());
|
||||
data = &nv;
|
||||
}
|
||||
else if(desc->type == SANE_TYPE_BOOL)
|
||||
{
|
||||
bv = cfg->val == "true";
|
||||
data = &bv;
|
||||
}
|
||||
else if(desc->type == SANE_TYPE_FIXED)
|
||||
{
|
||||
fv = SANE_FIX(atof(cfg->val.c_str()));
|
||||
data = &fv;
|
||||
}
|
||||
else if(desc->type == SANE_TYPE_STRING)
|
||||
{
|
||||
int len = (int)cfg->val.length() > desc->size * 4 ? cfg->val.length() : desc->size * 4;
|
||||
|
||||
str = new char[len + 4];
|
||||
if(str)
|
||||
{
|
||||
memset(str, 0, len + 4);
|
||||
strcpy((char*)str, cfg->val.c_str());
|
||||
data = str;
|
||||
}
|
||||
}
|
||||
|
||||
if(data)
|
||||
result = sane_control_option(hdev_, opt, SANE_ACTION_SET_VALUE, data, &afterdo) == SANE_STATUS_GOOD ? ACT_RESULT_SUCCESS : result;
|
||||
if(str)
|
||||
delete[] str;
|
||||
|
||||
if(cfg->name == SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA && cfg->val == "true")
|
||||
{
|
||||
SANE_Gamma gamma = {0};
|
||||
unsigned int l = 0;
|
||||
if(config::load_custom_gamma(cfg->extra.c_str(), &gamma))
|
||||
sane_io_control(hdev_, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &gamma, &l);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string sane_dev::name(void)
|
||||
{
|
||||
|
@ -138,40 +44,10 @@ bool sane_dev::open(const std::string& name)
|
|||
SANE_Status statu = sane_open(name.c_str(), &hdev_);
|
||||
if(statu == SANE_STATUS_GOOD)
|
||||
{
|
||||
DEVCFG first;
|
||||
|
||||
name_ = name;
|
||||
offline_ = false;
|
||||
if(first.schemes.size())
|
||||
cfg_name_ = first.schemes[0].m_schemeTitle;
|
||||
}
|
||||
|
||||
return statu == SANE_STATUS_GOOD;
|
||||
}
|
||||
bool sane_dev::apply_setting(OPTSCHEME* schm)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if(hdev_)
|
||||
{
|
||||
if(sane_io_control(hdev_, IO_CTRL_CODE_RESTORE_SETTINGS, nullptr, nullptr) == SANE_STATUS_GOOD)
|
||||
{
|
||||
DEVCFG first;
|
||||
if(first.schemes.size())
|
||||
cfg_name_ = first.schemes[0].m_schemeTitle;
|
||||
if(schm)
|
||||
{
|
||||
ret = apply(schm);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
void sane_dev::set_online(bool online)
|
||||
{
|
||||
offline_ = !online;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <string>
|
||||
#include "sane/sane_ex.h"
|
||||
#include "config.h"
|
||||
#include "cfg/gb_json.h"
|
||||
|
||||
|
||||
|
||||
|
@ -20,8 +20,7 @@ class sane_dev
|
|||
ACT_RESULT_SUCCESS,
|
||||
};
|
||||
|
||||
bool apply(OPTSCHEME* schm);
|
||||
act_result apply(const SANE_Option_Descriptor* desc, int opt, const std::vector<OPTVAL>& vals);
|
||||
bool apply(gb::sane_config_schm* schm);
|
||||
|
||||
public:
|
||||
sane_dev();
|
||||
|
@ -34,7 +33,6 @@ public:
|
|||
SANE_Handle handle(void);
|
||||
|
||||
bool open(const std::string& name);
|
||||
bool apply_setting(OPTSCHEME* schm = nullptr);
|
||||
void set_online(bool online);
|
||||
void close(void);
|
||||
};
|
||||
|
|
|
@ -188,9 +188,8 @@ SOURCES += \
|
|||
../../../app/scanner/widget_statusbar.cpp \
|
||||
../../../app/scanner/dialog_admin.cpp \
|
||||
../../../app/scanner/dialog_log.cpp \
|
||||
../../../app/scanner/config.cpp \
|
||||
../../../app/scanner/json.cpp \
|
||||
../../../app/scanner/cJSON.c \
|
||||
../../../app/scanner/cfg/gb_json.cpp \
|
||||
../../../app/scanner/cfg/cJSON.c \
|
||||
../../../app/scanner/HGImgThumb.cpp \
|
||||
../../../app/scanner/HGImgView.cpp \
|
||||
../../../app/scanner/HGUIGlobal.cpp \
|
||||
|
@ -237,8 +236,8 @@ HEADERS += \
|
|||
../../../app/scanner/dialog_admin.h \
|
||||
../../../app/scanner/dialog_log.h \
|
||||
../../../app/scanner/config.h \
|
||||
../../../app/scanner/json.h \
|
||||
../../../app/scanner/cJSON.h \
|
||||
../../../app/scanner/cfg/gb_json.h \
|
||||
../../../app/scanner/cfg/cJSON.h \
|
||||
../../../app/scanner/HGImgThumb.h \
|
||||
../../../app/scanner/HGImgView.h \
|
||||
../../../app/scanner/HGUIGlobal.h \
|
||||
|
|
Loading…
Reference in New Issue