507 lines
19 KiB
C
507 lines
19 KiB
C
|
#ifndef DEVICE_MENU_H
|
|||
|
#define DEVICE_MENU_H
|
|||
|
|
|||
|
#include <QMenu>
|
|||
|
#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"
|
|||
|
#include "lang/app_language.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);
|
|||
|
std::string langCN(to_default_language(buf, nullptr));
|
|||
|
schm->set_default_value(i, opt->name, &langCN[0], langCN.length());
|
|||
|
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());
|
|||
|
std::string langCN(from_default_language(buf, nullptr));
|
|||
|
sane_control_option(h, id, SANE_ACTION_SET_VALUE, &langCN[0], &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);
|
|||
|
}
|
|||
|
|
|||
|
return statu;
|
|||
|
}
|
|||
|
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_ = v.cfg->get_current_scheme_name();
|
|||
|
v.cfg->save();
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return SCANNER_ERR_OK;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
class device_menu : public QMenu
|
|||
|
{
|
|||
|
Q_OBJECT
|
|||
|
typedef struct _pop_menu
|
|||
|
{
|
|||
|
QMenu* menu;
|
|||
|
std::vector<QAction*> actions;
|
|||
|
|
|||
|
bool operator==(const QString& menu_title)
|
|||
|
{
|
|||
|
return menu->title() == menu_title;
|
|||
|
}
|
|||
|
}POPMENU;
|
|||
|
std::vector<POPMENU> menus_;
|
|||
|
QAction* cur_action_;
|
|||
|
QAction* none_action_;
|
|||
|
QActionGroup* group_action_;
|
|||
|
std::mutex mutex_;
|
|||
|
|
|||
|
QMenu* find_device_menu(const QString& dev_name);
|
|||
|
QAction* find_device_config(const QString& dev_name, const QString& cfg_name);
|
|||
|
|
|||
|
public:
|
|||
|
device_menu(QWidget* parent = nullptr);
|
|||
|
device_menu(const QString& title, QWidget* parent = nullptr);
|
|||
|
|
|||
|
void deviceMenuUpdate(dev_que* que);
|
|||
|
|
|||
|
void connectedDevice(const QString& device);
|
|||
|
|
|||
|
void disconnectedDevice(const QString& device);
|
|||
|
|
|||
|
void setOptionChecked(const QString& device, const QString& opt, bool checked);
|
|||
|
|
|||
|
void get_online_devices(QList<QString>& dev_names);
|
|||
|
|
|||
|
signals:
|
|||
|
void scanOptionsChanged(const QString& device, const QString& opt, bool checked_now);
|
|||
|
|
|||
|
private slots:
|
|||
|
void on_act_triggered(QAction* act);
|
|||
|
};
|
|||
|
|
|||
|
#endif // DEVICE_MENU_H
|