#include "hg_settingdialog.h" #include #include #include "cutpapertool.h" #include "setpicclrtool.h" #include "base/HGDef.h" #include "base/HGUtility.h" #include "HGString.h" #include "sane/sane_option_definitions.h" #include "lang/app_language.h" #include "dialog_input.h" #include #include "device_menu.h" #include "dialog_device_scan.h" hg_settingdialog * hg_settingdialog::hg_setting_ui_ =NULL; std::string hg_settingdialog::property_combox_data_type_ = "combox_value_type"; hg_settingdialog::hg_settingdialog(SANE_Handle handle, const SANEAPI* saneApi, bool showScan, const char* devName, std::function callback, QWidget *parent) : QDialog(parent) , save_(false) , btn_cut_area_(nullptr), btn_gamma_(nullptr), clicked_gamma_(false) , custom_area_lable_(nullptr), comb_(nullptr) , m_devHandle(handle) , m_showScan(showScan) , m_devName(devName) , m_callback(callback) { hg_setting_ui_ = this; m_langCode = lang_get_cur_code_page(); if (20127 == m_langCode) { m_translator.load(":translation/TwainUI_zh_EN.qm"); } else { m_translator.load(":translation/TwainUI_zh_CN.qm"); m_translator_qt.load(":translation/qt_zh_CN.qm"); } QCoreApplication::installTranslator(&m_translator); if (20127 != m_langCode) QCoreApplication::installTranslator(&m_translator_qt); setAttribute(Qt::WA_DeleteOnClose, true); HGChar cfgpath[512] = {0}; QString old; HGBase_GetConfigPath(cfgpath, _countof(cfgpath) - 1); HGBase_CreateDir(cfgpath); 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()); int pid = 0; saneApi->sane_control_option_api(m_devHandle, (SANE_Int)0x8853, SANE_ACTION_GET_VALUE, &pid, NULL); char buf[10] = { 0 }; sprintf(buf, "%x", pid); std::string deviceName = m_devName; if (pid != 0) { deviceName = deviceName.substr(0, deviceName.find(" ")) + " " + buf; } dev_que_.add_scanner(deviceName.c_str()); dev_que_.open_scanner(saneApi, handle, deviceName.c_str(), false); std::string n(dev_que_.opened_scanner_name()); for(int i = 0; i < dev_que_.scanners(); ++i) { SCANNER s = dev_que_.get_at(i); if(s.name == n) { cur_cfg_ = s.cfg; break; } } cur_scheme_ = cur_cfg_->get_scheme(); if(!cur_scheme_) cur_scheme_ = new gb::sane_config_schm(); cur_scheme_->begin_setting(); m_dpiId = -1; m_dpiValue = 200; m_paperSizeId = -1; m_paperSizeValue.clear(); m_cutLeftId = -1; m_cutTopId = -1; m_cutRightId = -1; m_cutBottomId = -1; m_cutWidth = 210; m_cutHeight = 297; m_cutLeftValue = 0; m_cutTopValue = 0; m_cutRightValue = 210; m_cutBottomValue = 297; m_colorModeId = -1; m_colorModeValue.clear(); memset(&m_gammaData, 0, sizeof(m_gammaData)); for(int i = 0; i < sizeof(m_gammaData.table) / sizeof(m_gammaData.table[0]); ++i) m_gammaData.table[i] = i & 0x0ff; memcpy(&m_saneAPI, saneApi, sizeof(SANEAPI)); m_closeButton = closeButtonNormal; initUi(); on_current_scheme_changed(); getAppVersion(); } hg_settingdialog::~hg_settingdialog() { QCoreApplication::removeTranslator(&m_translator); if (20127 != m_langCode) QCoreApplication::removeTranslator(&m_translator_qt); cur_scheme_->release(); cur_cfg_->release(); hg_setting_ui_ = NULL; m_callback(UI_RESULT_CLOSE_SETTING); } hg_settingdialog *hg_settingdialog::GetSettingDialog() { return hg_setting_ui_; } void hg_settingdialog::initUi() { updateOpt(); createUI(); #if defined(OEM_ZHONGJING) setWindowTitle("Microtek DocWizard EX TWAIN"); #else setWindowTitle(QString::fromStdString(dev_que_.opened_scanner_name())); #endif setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint); resize(740, height()); } void hg_settingdialog::updateOpt() { bool first = true; m_list_defaultOptions.clear(); SANE_Int dev_options = 0; m_saneAPI.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr); for (int i = 1, j= dev_options; i < j; i++) { const SANE_Option_Descriptor* opt = m_saneAPI.sane_get_option_descriptor_api(m_devHandle, i); SANE_Int method = 0; if (opt == nullptr) { m_list_defaultOptions.append(QPair(opt, QVariant(0))); } else { if(opt->type == SANE_TYPE_INT) { SANE_Int init = 0; m_saneAPI.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, &init, &method); m_list_defaultOptions.append(QPair(opt, QVariant(init))); if(first) { unsigned int n = i; m_saneAPI.sane_io_control_api(m_devHandle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &n); cur_scheme_->set_default_value(i, opt->name, (char*)&init, sizeof(init)); } } else if(opt->type == SANE_TYPE_FIXED) { SANE_Fixed init = 0; m_saneAPI.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, &init, &method); m_list_defaultOptions.append(QPair(opt, QVariant(init))); if(first) { unsigned int n = i; m_saneAPI.sane_io_control_api(m_devHandle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &n); cur_scheme_->set_default_value(i, opt->name, (char*)&init, sizeof(init)); } } else if(opt->type == SANE_TYPE_BOOL) { SANE_Bool init = 0; m_saneAPI.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, &init, &method); m_list_defaultOptions.append(QPair(opt, QVariant(init))); if(first) { unsigned int n = i; m_saneAPI.sane_io_control_api(m_devHandle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &n); cur_scheme_->set_default_value(i, opt->name, (char*)&init, sizeof(init)); } } else if(opt->type == SANE_TYPE_STRING) { char *init = (char*)malloc(opt->size * 2 + 4); m_saneAPI.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, init, &method); QString str = QString::fromStdString(init); m_list_defaultOptions.append(QPair(opt, QVariant(QString::fromStdString(init)))); if(first) { unsigned int n = i; int err = m_saneAPI.sane_io_control_api(m_devHandle, IO_CTRL_CODE_GET_DEFAULT_VALUE, init, &n); (void)err; std::string langCN(to_default_language(init, nullptr)); cur_scheme_->set_default_value(i, opt->name, &langCN[0], langCN.length()); } free(init); } else { m_list_defaultOptions.append(QPair(opt, QVariant(0))); } } } } QString hg_settingdialog::find_current_scheme_menu(int *scheme_id) { QString text(comb_->currentText()); if(scheme_id) { if(comb_->currentIndex() >= 0 && comb_->currentIndex() < comb_->count()) *scheme_id = comb_->currentIndex(); else { *scheme_id = -1; } } return text; } void hg_settingdialog::create_scheme_management_ui(QVBoxLayout* layout) { QLabel *title = new QLabel(this); bool enabled = false; QHBoxLayout *hbox = new QHBoxLayout(); int width = 180; std::vector schemes; std::string cur_schm(cur_cfg_->get_current_scheme_name()); cur_cfg_->get_all_schemes(schemes); comb_ = new QComboBox(this); layout->addSpacing(30); for(int i = 1; i < (int)schemes.size(); ++i) { comb_->addItem(QString::fromStdString(schemes[i])); if(cur_schm == schemes[i]) { enabled = true; comb_->setCurrentText(QString::fromStdString(schemes[i])); } } if(!enabled) comb_->setCurrentIndex(-1); title->setFixedWidth(width); comb_->setFixedWidth(width); title->setText(tr("existing configuration scheme")); layout->addWidget(title); layout->addWidget(comb_); rename_ = new QPushButton(this); rename_->setText(tr("change name")); rename_->setEnabled(enabled); rename_->setFixedWidth(width/3); hbox->addWidget(rename_); connect(rename_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management())); del_this_ = new QPushButton(this); del_this_->setText(tr("delete")); del_this_->setEnabled(enabled); del_this_->setFixedWidth(width / 3); hbox->addWidget(del_this_); connect(del_this_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management())); apply_ = new QPushButton(this); apply_->setText(tr("apply")); apply_->setEnabled(enabled); apply_->setFixedWidth(width / 3); hbox->addWidget(apply_); connect(apply_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management())); hbox->setSizeConstraint(QLayout::SetFixedSize); layout->addLayout(hbox); layout->addSpacing(10); del_all_ = new QPushButton(this); del_all_->setText(tr("delete all configurations")); del_all_->setEnabled(enabled); del_all_->setFixedWidth(width); layout->addWidget(del_all_); connect(del_all_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management())); layout->addStretch(); title = new QLabel(this); title->setText(tr("confgiuration information:")); layout->addWidget(title); sketch_ = new QTextEdit(this); sketch_->setReadOnly(true); sketch_->setFixedSize(width, 200); layout->addWidget(sketch_); connect(comb_, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_current_scheme_changed())); on_current_scheme_changed(); } void hg_settingdialog::createUI() { QTabWidget *tabWidgetCreation = new QTabWidget(this); QPushButton *buttonAbout = new QPushButton(this); buttonAbout->setText(tr("about...")); QPushButton *buttonScan = new QPushButton(this); buttonScan->setText(tr("scan")); QPushButton *buttonOk = new QPushButton(this); buttonOk->setText(tr("ok")); QPushButton *buttonCancel = new QPushButton(this); buttonCancel->setText(tr("cancel")); QHBoxLayout *hlayoutOkAndCancel = new QHBoxLayout; hlayoutOkAndCancel->addStretch(); hlayoutOkAndCancel->addWidget(buttonAbout); hlayoutOkAndCancel->addWidget(buttonScan); hlayoutOkAndCancel->addWidget(buttonOk); hlayoutOkAndCancel->addWidget(buttonCancel); QWidget *widgetOkAndCancel = new QWidget(); widgetOkAndCancel->setLayout(hlayoutOkAndCancel); connect(buttonAbout, SIGNAL(clicked(bool)), this, SLOT(slot_buttonAboutClicked())); connect(buttonScan, SIGNAL(clicked(bool)), this, SLOT(slot_buttonScanClicked())); connect(buttonOk, SIGNAL(clicked(bool)), this, SLOT(slot_buttonOkClicked())); connect(buttonCancel, SIGNAL(clicked(bool)), this, SLOT(slot_buttonCancelClicked())); if (!m_showScan) { buttonScan->setVisible(false); } else { buttonOk->setVisible(false); } QHBoxLayout *h = new QHBoxLayout(); QVBoxLayout *v1 = new QVBoxLayout(), *v2 = new QVBoxLayout(); create_scheme_management_ui(v1); v2->addWidget(tabWidgetCreation); QGroupBox *grp = new QGroupBox(tr("configuration scheme management"), this); grp->setLayout(v1); grp->setFixedSize(195, 500); h->addWidget(grp); h->addLayout(v2); QVBoxLayout* mainVerticalLayout = new QVBoxLayout(this); mainVerticalLayout->addLayout(h); // mainVerticalLayout->addWidget(tabWidgetCreation); mainVerticalLayout->addWidget(widgetOkAndCancel); this->setLayout(mainVerticalLayout); QScrollArea* scrollArea = new QScrollArea; scrollArea->setWidgetResizable(true); scrollArea->setAlignment(Qt::AlignCenter); QFormLayout* layout = new QFormLayout; QWidget* widget = new QWidget; widget->setLayout(layout); bool isBegin = true; std::string cur_val(""); for (int i = 0; i < m_list_defaultOptions.size(); i++) { const SANE_Option_Descriptor* opt = reinterpret_cast(m_list_defaultOptions.at(i).first); int ind = -1; if(opt == nullptr) continue; h = nullptr; cur_scheme_->get_config(opt->name, cur_val); switch (opt->type) { case SANE_TYPE_BOOL: { QCheckBox *checkBoxCreation = new QCheckBox; if (strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA) == 0) { QWidget* widget_cbtn_pbtn = new QWidget; widget_cbtn_pbtn->setMaximumWidth(200); QLabel *label = new QLabel; label->setText(QString::fromStdString(opt->title) + QString(" : ")); btn_cut_area_ = new QPushButton; btn_cut_area_->setText(tr("regional crop")); btn_cut_area_->setFixedWidth(150); QHBoxLayout *hLayout = new QHBoxLayout; hLayout->addWidget(checkBoxCreation); hLayout->addWidget(btn_cut_area_); widget_cbtn_pbtn->setLayout(hLayout); custom_area_lable_ = label; reinterpret_cast(widget->layout())->addRow(label, widget_cbtn_pbtn); connect(btn_cut_area_, SIGNAL(clicked(bool)), this, SLOT(slot_cutButtonClicked())); } else if (strcmp(opt->name, SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA) == 0) { QWidget* widget_cbtn_pbtn = new QWidget(scrollArea); widget_cbtn_pbtn->setMaximumWidth(200); btn_gamma_ = new QPushButton(widget_cbtn_pbtn); btn_gamma_->setText(tr("custom tone curve")); btn_gamma_->setFixedWidth(150); QHBoxLayout *hLayout = new QHBoxLayout; hLayout->addWidget(checkBoxCreation); hLayout->addWidget(btn_gamma_); widget_cbtn_pbtn->setLayout(hLayout); reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), widget_cbtn_pbtn); connect(btn_gamma_, SIGNAL(clicked(bool)), this, SLOT(slot_gammaButtonClicked())); } else reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), checkBoxCreation); checkBoxCreation->setToolTip(opt->desc); int id = i + 1; bool enable = *(bool*)&cur_val[0]; checkBoxCreation->setProperty("controls_id", id); checkBoxCreation->setChecked(enable); if (strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA) == 0) btn_cut_area_->setEnabled(enable); else if (strcmp(opt->name, SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA) == 0) btn_gamma_->setEnabled(enable); connect(checkBoxCreation, SIGNAL(stateChanged(int)), this, SLOT(slot_checkedClicked())); m_list_widgets.append(checkBoxCreation); m_list_getOpt.append(QPair(id, opt)); break; } case SANE_TYPE_INT: { switch(opt->constraint_type) { case SANE_CONSTRAINT_NONE: { QSpinBox* spinBox = new QSpinBox(scrollArea); spinBox->setMinimumWidth(150); spinBox->setToolTip(opt->desc); spinBox->setRange(1, 1000); int id = i + 1; spinBox->setProperty("controls_id", id); QHBoxLayout* hLayout = new QHBoxLayout; hLayout->addWidget(spinBox); hLayout->addStretch(); reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), spinBox); m_list_widgets.append(spinBox); m_list_getOpt.append(QPair(id, opt)); spinBox->setValue(*(int*)&cur_val[0]); connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int))); break; } case SANE_CONSTRAINT_RANGE: { QWidget* widget_slider_spin = new QWidget(scrollArea); widget_slider_spin->setMinimumWidth(300); QSlider* sliderCreation = new QSlider(widget_slider_spin); sliderCreation->setOrientation(Qt::Horizontal); sliderCreation->setMinimumWidth(120); sliderCreation->setRange(opt->constraint.range->min, opt->constraint.range->max); sliderCreation->setToolTip(opt->desc); sliderCreation->setProperty("controls_id", i+1); sliderCreation->setValue(m_list_defaultOptions.at(i).second.toInt()); QSpinBox* spinBox = new QSpinBox(widget_slider_spin); spinBox->setMinimumWidth(150); spinBox->setToolTip(opt->desc); spinBox->setRange(opt->constraint.range->min, opt->constraint.range->max); spinBox->setSingleStep(1); spinBox->setValue(m_list_defaultOptions.at(i).second.toInt()); int id = i + 1; spinBox->setProperty("controls_id", id); m_list_sliderSpinbox.append(QPair(sliderCreation, spinBox)); QHBoxLayout* hLayout = new QHBoxLayout; hLayout->addWidget(sliderCreation); hLayout->addWidget(spinBox); // hLayout->addStretch(); widget_slider_spin->setLayout(hLayout); reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), widget_slider_spin); m_list_widgets.append(sliderCreation); m_list_widgets.append(spinBox); m_list_getOpt.append(QPair(id, opt)); int cur = *(int*)&cur_val[0]; spinBox->setValue(cur); sliderCreation->setValue(cur); connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int))); connect(sliderCreation, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int))); break; } case SANE_CONSTRAINT_WORD_LIST: { QComboBox* comboBoxCreation = new QComboBox(scrollArea); comboBoxCreation->setToolTip(opt->desc); int id = i + 1; comboBoxCreation->setProperty("controls_id", id); reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), comboBoxCreation); auto p_str = opt->constraint.word_list; char buf[20]; for(SANE_Int i = 0; i < p_str[0]; ++i) { sprintf(buf, "%d", p_str[i + 1]); comboBoxCreation->addItem(QString::fromStdString(buf)); } sprintf(buf, "%d", m_list_defaultOptions.at(i).second.toInt()); comboBoxCreation->setProperty(hg_settingdialog::property_combox_data_type_.c_str(), COMBO_VAL_INT); m_list_widgets.append(comboBoxCreation); m_list_getOpt.append(QPair(id, opt)); char nstr[40] = {0}; sprintf(nstr, "%d", *(int*)&cur_val[0]); comboBoxCreation->setCurrentText(QString::fromStdString(nstr)); connect(comboBoxCreation, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); break; } case SANE_CONSTRAINT_STRING_LIST: break; } break; } case SANE_TYPE_FIXED: { QWidget* widget_slider_spin = new QWidget(scrollArea); widget_slider_spin->setMinimumWidth(300); QSlider* sliderCreation = new QSlider(widget_slider_spin); sliderCreation->setOrientation(Qt::Horizontal); sliderCreation->setMinimumWidth(120); sliderCreation->setToolTip(opt->desc); int id = i + 1; sliderCreation->setProperty("controls_id", id); sliderCreation->setRange(SANE_UNFIX(opt->constraint.range->min) * 100, SANE_UNFIX(opt->constraint.range->max) * 100); sliderCreation->setValue(SANE_UNFIX(m_list_defaultOptions.at(i).second.toDouble()) * 100); QDoubleSpinBox* spinBox = new QDoubleSpinBox(widget_slider_spin); spinBox->setMinimumWidth(150); spinBox->setToolTip(opt->desc); spinBox->setDecimals(2); spinBox->setSingleStep(0.01); spinBox->setRange(SANE_UNFIX(opt->constraint.range->min), SANE_UNFIX(opt->constraint.range->max)); spinBox->setValue(sliderCreation->value() * spinBox->singleStep()); spinBox->setProperty("controls_id", id); m_list_sliderSpinbox.append(QPair(sliderCreation, spinBox)); QHBoxLayout* hLayout = new QHBoxLayout; hLayout->addWidget(sliderCreation); hLayout->addWidget(spinBox); // hLayout->addStretch(); widget_slider_spin->setLayout(hLayout); reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), widget_slider_spin); m_list_widgets.append(sliderCreation); m_list_widgets.append(spinBox); m_list_getOpt.append(QPair(id, opt)); // iniRead(md5(opt->title), id, sliderCreation); // iniRead(md5(opt->title), id, spinBox); float v = SANE_UNFIX(*(SANE_Fixed*)&cur_val[0]); sliderCreation->setValue(v * 100); spinBox->setValue(sliderCreation->value() * spinBox->singleStep()); connect(spinBox, SIGNAL(valueChanged(double)), this, SLOT(slot_doubleSpinboxClicked(double))); connect(sliderCreation, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int))); break; } case SANE_TYPE_STRING: { switch(opt->constraint_type) { case SANE_CONSTRAINT_NONE: { QLineEdit *lineEdit = new QLineEdit(scrollArea); lineEdit->setToolTip(opt->desc); int id = i + 1; lineEdit->setProperty("controls_id", id); reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), lineEdit); m_list_widgets.append(lineEdit); m_list_getOpt.append(QPair(id, opt)); // iniRead(md5(opt->title), id, lineEdit); lineEdit->setText(QString::fromStdString(cur_val)); connect(lineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slot_lineEditInput())); break; } case SANE_CONSTRAINT_RANGE: break; case SANE_CONSTRAINT_WORD_LIST: break; case SANE_CONSTRAINT_STRING_LIST: { QComboBox* comboBoxCreation = new QComboBox(scrollArea); comboBoxCreation->setToolTip(opt->desc); int id = i + 1; comboBoxCreation->setProperty("controls_id", id); reinterpret_cast(widget->layout())->addRow(opt->title + QString(" : "), comboBoxCreation); auto p_str = opt->constraint.string_list; QStringList stringList; while(*p_str) { stringList.append(*p_str); p_str++; } if(stringList.isEmpty() != true) { for(int i = 0; i < (stringList.size()); i++) comboBoxCreation->addItem(stringList.at(i)); } comboBoxCreation->setCurrentText(m_list_defaultOptions.at(i).second.toString()); comboBoxCreation->setProperty(hg_settingdialog::property_combox_data_type_.c_str(), COMBO_VAL_STRING); //printf("Option %02d default value is: %s\n", i + 1, m_list_defaultOptions.at(i).second.toString().data()); m_list_widgets.append(comboBoxCreation); m_list_getOpt.append(QPair(id, opt)); // iniRead(md5(opt->title), id, comboBoxCreation); comboBoxCreation->setCurrentText(QString::fromStdString(cur_val)); connect(comboBoxCreation, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); break; } } break; } case SANE_TYPE_BUTTON: { QPushButton* pushButton = new QPushButton(this); pushButton->setText(opt->title); pushButton->setToolTip(opt->desc); int id = i + 1; pushButton->setProperty("controls_id", id); hlayoutOkAndCancel->insertWidget(0, pushButton, 0, Qt::AlignRight); connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(slot_pushButtonClicked())); break; } case SANE_TYPE_GROUP: { if (isBegin) { scrollArea->setWindowTitle(opt->title); isBegin = false; }else{ scrollArea->setWidget(widget); tabWidgetCreation->addTab(scrollArea, scrollArea->windowTitle()); scrollArea = new QScrollArea; scrollArea->setWidgetResizable(true); scrollArea->setWindowTitle(opt->title); layout = new QFormLayout; widget = new QWidget; widget->setLayout(layout); } m_list_widgets.append(nullptr); break; } } //switch(opt->type) // if (Utf8ToStdString(opt->title) == "分辨率") if (strcmp(opt->name, SANE_STD_OPT_NAME_RESOLUTION) == 0) { m_dpiId = i + 1; m_dpiValue = m_list_defaultOptions.at(i).second.toInt(); } // else if (Utf8ToStdString(opt->title) == "纸张尺寸") else if (strcmp(opt->name, SANE_STD_OPT_NAME_PAPER) == 0) { m_paperSizeId = i + 1; m_paperSizeValue = m_list_defaultOptions.at(i).second.toString(); } if (0 == strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT)) { m_cutLeftId = i + 1; m_cutLeftValue = SANE_UNFIX(m_list_defaultOptions.at(i).second.toInt()); if (opt->constraint_type == SANE_CONSTRAINT_RANGE) m_cutWidth = SANE_UNFIX(opt->constraint.range->max); } else if (0 == strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_TOP)) { m_cutTopId = i + 1; m_cutTopValue = SANE_UNFIX(m_list_defaultOptions.at(i).second.toInt()); if (opt->constraint_type == SANE_CONSTRAINT_RANGE) m_cutHeight = SANE_UNFIX(opt->constraint.range->max); } else if (0 == strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT)) { m_cutRightId = i + 1; m_cutRightValue = SANE_UNFIX(m_list_defaultOptions.at(i).second.toInt()); } else if (0 == strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM)) { m_cutBottomId = i + 1; m_cutBottomValue = SANE_UNFIX(m_list_defaultOptions.at(i).second.toInt()); } // else if (Utf8ToStdString(opt->title) == "颜色模式") if (strcmp(opt->name, SANE_STD_OPT_NAME_COLOR_MODE) == 0) { m_colorModeId = i + 1; m_colorModeValue = m_list_defaultOptions.at(i).second.toString(); } // else if (Utf8ToStdString(opt->title) == "伽玛" || Utf8ToStdString(opt->title) == "伽玛值") } //for updateUIStatus(); scrollArea->setWidget(widget); tabWidgetCreation->addTab(scrollArea, scrollArea->windowTitle()); } void hg_settingdialog::refresh_control_value(int op_id) { QVector ctrls = find_control(op_id); if(ctrls.empty()) return; const SANE_Option_Descriptor* opt = (const SANE_Option_Descriptor*)m_list_defaultOptions.at(op_id - 1).first; if(opt->type == SANE_TYPE_BOOL) { for(size_t i = 0; i < (size_t)ctrls.size(); ++i) { QCheckBox* cb = qobject_cast(ctrls[i]); if(cb) { disconnect(cb, SIGNAL(stateChanged(int)), this, SLOT(slot_checkedClicked())); cb->setChecked(m_list_defaultOptions.at(op_id - 1).second.toBool()); connect(cb, SIGNAL(stateChanged(int)), this, SLOT(slot_checkedClicked())); break; } } } else if(opt->type == SANE_TYPE_INT) { for(size_t i = 0; i < (size_t)ctrls.size(); ++i) { QComboBox* comb = qobject_cast(ctrls[i]); if(comb) { char buf[40] = {0}; sprintf(buf, "%d", m_list_defaultOptions.at(op_id - 1).second.toInt()); comb->disconnect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); comb->setCurrentText(QString::fromStdString(buf)); connect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); } else { QSlider* slider = qobject_cast(ctrls[i]); if(slider) { disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int))); slider->setValue(m_list_defaultOptions.at(op_id - 1).second.toInt()); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int))); } else { QSpinBox* spin = qobject_cast(ctrls[i]); if(spin) { disconnect(spin, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int))); spin->setValue(m_list_defaultOptions.at(op_id - 1).second.toInt()); connect(spin, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int))); } } } } } else if(opt->type == SANE_TYPE_FIXED) { double val = SANE_UNFIX(m_list_defaultOptions.at(op_id - 1).second.toInt()); QSlider *slider = NULL; QDoubleSpinBox* spin = NULL; for(size_t i = 0; i < (size_t)ctrls.size(); ++i) { QComboBox* comb = qobject_cast(ctrls[i]); if(comb) { char buf[40] = {0}; sprintf(buf, "%f", val); comb->disconnect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); comb->setCurrentText(QString::fromStdString(buf)); connect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); } else if(!slider) { slider = qobject_cast(ctrls[i]); if(slider) disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int))); } else if(!spin) { spin = qobject_cast(ctrls[i]); if(spin) disconnect(spin, SIGNAL(valueChanged(double)), this, SLOT(slot_spinBoxClicked(double))); } } if(slider) slider->setValue(val * 100); if(spin) spin->setValue(val); if(slider) connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int))); if(spin) connect(spin, SIGNAL(valueChanged(double)), this, SLOT(slot_spinBoxClicked(double))); } else if(opt->type == SANE_TYPE_STRING) { for(size_t i = 0; i < (size_t)ctrls.size(); ++i) { QComboBox* comb = qobject_cast(ctrls[i]); if(comb) { disconnect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); comb->setCurrentText(m_list_defaultOptions.at(op_id - 1).second.toString()); // comb->setProperty(hg_settingdialog::property_combox_data_type_.c_str(), COMBO_VAL_STRING); connect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked())); } else { QLineEdit* edit = qobject_cast(ctrls[i]); if(edit) { disconnect(edit, SIGNAL(textChanged(const QString&)), this, SLOT(slot_lineEditInput())); edit->setText(m_list_defaultOptions.at(op_id - 1).second.toString()); connect(edit, SIGNAL(textChanged(const QString&)), this, SLOT(slot_lineEditInput())); } } } } } QVector hg_settingdialog::find_control(int opt_num) { QVector list_w; for(int i = 0; i< m_list_widgets.size(); i++) { if (m_list_widgets.at(i) == nullptr) continue; QWidget* w = m_list_widgets.at(i); int id = w->property("controls_id").toInt(); if(opt_num == id) list_w.append(w); } return list_w; } void hg_settingdialog::updateUIStatus() { updateOpt(); SANE_Int dev_options = 0; m_saneAPI.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr); for(int id = 1, optons = dev_options; id < optons; id++) { QVector list_widgets = find_control(id); if (list_widgets.empty()) continue; QWidget* widget = list_widgets.first(); if (widget == nullptr) continue; QWidget* parentWidget = widget->parentWidget(); while (parentWidget->layout() && typeid(*(parentWidget->layout())) != typeid(QFormLayout)) { widget = parentWidget; parentWidget = widget->parentWidget(); } QFormLayout* layout = reinterpret_cast(parentWidget->layout()); const SANE_Option_Descriptor* opt = reinterpret_cast(m_list_defaultOptions.at(id - 1).first); bool hide = (opt->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE; QWidget* w_label = layout ? layout->labelForField(widget) : nullptr; if( strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT) == 0 || strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_TOP) == 0 || strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT) == 0 || strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM) == 0 ) hide = true; refresh_control_value(id); if(w_label) hide ? w_label->hide() : w_label->show(); widget->setVisible(!hide); if(strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA) == 0) { if(hide) { custom_area_lable_->hide(); btn_cut_area_->hide(); } else { custom_area_lable_->show(); btn_cut_area_->show(); } } } } void hg_settingdialog::slot_checkedClicked() { QCheckBox *checkBox = qobject_cast(sender()); SANE_Int id = checkBox->property("controls_id").toInt(); SANE_Bool checkBoxcurrentState = checkBox->isChecked(); const SANE_Option_Descriptor* opt = nullptr; for(int i = 0; i < m_list_getOpt.size(); i++) if (m_list_getOpt.at(i).first == id) { opt = reinterpret_cast(m_list_getOpt.at(i).second); break; } m_list_IdValueTitle.append(QPair, QString>(QPair(id, checkBoxcurrentState), md5(opt->title))); SANE_Int method = 0; m_saneAPI.sane_control_option_api(m_devHandle, id, SANE_ACTION_SET_VALUE, &checkBoxcurrentState, &method); if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); else if(method & SANE_INFO_INEXACT) checkBox->setCheckState(checkBoxcurrentState ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); if(strcmp(opt->name, SANE_STD_OPT_NAME_CUSTOM_AREA) == 0) btn_cut_area_->setEnabled(checkBoxcurrentState); else if (strcmp(opt->name, SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA) == 0) btn_gamma_->setEnabled(checkBoxcurrentState); cur_scheme_->config_changed(id, (char*)&checkBoxcurrentState, sizeof(checkBoxcurrentState)); } void hg_settingdialog::slot_string_list_comboBoxClicked() { QComboBox *comboBox = qobject_cast(sender()); SANE_Int id = comboBox->property("controls_id").toInt(); std::string comboBoxcurrentItem(comboBox->currentText().toUtf8()); int type = comboBox->property(hg_settingdialog::property_combox_data_type_.c_str()).toInt(); if (id == m_dpiId) { m_dpiValue = atoi(comboBoxcurrentItem.c_str()); qDebug("dpi=%d", m_dpiValue); } else if (id == m_paperSizeId) { m_paperSizeValue = comboBoxcurrentItem.c_str(); qDebug("paperSize=%s", comboBoxcurrentItem.c_str()); } else if (id == m_colorModeId) { m_colorModeValue = comboBoxcurrentItem.c_str(); qDebug("colorMode=%s", comboBoxcurrentItem.c_str()); } const SANE_Option_Descriptor* opt = nullptr; for(int i = 0; i < m_list_getOpt.size(); i++) if (m_list_getOpt.at(i).first == id) { opt = reinterpret_cast(m_list_getOpt.at(i).second); break; } m_list_IdValueTitle.append(QPair, QString>(QPair(id, &comboBoxcurrentItem.at(0)), md5(opt->title))); SANE_Int method = 0; SANE_String buf = (SANE_String)malloc(opt->size * 2 + 4); if(type == COMBO_VAL_INT) *((SANE_Int*)buf) = atoi(comboBoxcurrentItem.c_str()); else if(type == COMBO_VAL_FLOAT) *((SANE_Fixed*)buf) = SANE_FIX(atof(comboBoxcurrentItem.c_str())); else strcpy(buf, comboBoxcurrentItem.c_str()); m_saneAPI.sane_control_option_api(m_devHandle, id, SANE_ACTION_SET_VALUE, buf, &method); if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); else if(method & SANE_INFO_INEXACT) comboBox->setCurrentText(QString::fromStdString(buf)); if(type == COMBO_VAL_INT) cur_scheme_->config_changed(id, buf, sizeof(SANE_Int)); else if(type == COMBO_VAL_FLOAT) cur_scheme_->config_changed(id, buf, sizeof(SANE_Fixed)); else { std::string langCN(to_default_language(buf, nullptr)); cur_scheme_->config_changed(id, &langCN[0], langCN.length()); } free(buf); } void hg_settingdialog::slot_pushButtonClicked() { QPushButton *pushButton = qobject_cast(sender()); SANE_Int id = pushButton->property("controls_id").toInt(), after = 0; // restore to default setting ? m_saneAPI.sane_control_option_api(m_devHandle, id, SANE_ACTION_SET_VALUE, NULL, &after); if((after & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); const SANE_Option_Descriptor* opt = m_saneAPI.sane_get_option_descriptor_api(m_devHandle, id); if(opt && strcmp(opt->name, SANE_STD_OPT_NAME_RESTORE) == 0) { restore_2_default_settings(); } } void hg_settingdialog::slot_cutButtonClicked() { //int width = 0.03937 * m_cutWidth * m_dpiValue; //int height = 0.03937 * m_cutHeight * m_dpiValue; int left = 0.03937 * m_cutLeftValue * m_dpiValue; int top = 0.03937 * m_cutTopValue * m_dpiValue; int right = 0.03937 * m_cutRightValue * m_dpiValue; int bottom = 0.03937 * m_cutBottomValue * m_dpiValue; CutPaperTool dlg(this); dlg.setPaperType(m_dpiValue, m_paperSizeValue, 300); QRectF rc(left, top, right - left, bottom - top); dlg.setCutRect(rc); if (dlg.exec()) { QRectF rcRet = dlg.getCutRectPixel(); m_cutLeftValue = rcRet.left() / (0.03937 * m_dpiValue); m_cutTopValue = rcRet.top() / (0.03937 * m_dpiValue); m_cutRightValue = rcRet.right() / (0.03937 * m_dpiValue); m_cutBottomValue = rcRet.bottom() / (0.03937 * m_dpiValue); SANE_Int info; SANE_Word value = SANE_FIX(m_cutLeftValue); m_saneAPI.sane_control_option_api(m_devHandle, m_cutLeftId, SANE_ACTION_SET_VALUE, &value, &info); cur_scheme_->config_changed(m_cutLeftId, (char*)&value, sizeof(value)); value = SANE_FIX(m_cutTopValue); m_saneAPI.sane_control_option_api(m_devHandle, m_cutTopId, SANE_ACTION_SET_VALUE, &value, &info); cur_scheme_->config_changed(m_cutTopId, (char*)&value, sizeof(value)); value = SANE_FIX(m_cutRightValue); m_saneAPI.sane_control_option_api(m_devHandle, m_cutRightId, SANE_ACTION_SET_VALUE, &value, &info); cur_scheme_->config_changed(m_cutRightId, (char*)&value, sizeof(value)); value = SANE_FIX(m_cutBottomValue); m_saneAPI.sane_control_option_api(m_devHandle, m_cutBottomId, SANE_ACTION_SET_VALUE, &value, &info); cur_scheme_->config_changed(m_cutBottomId, (char*)&value, sizeof(value)); } } void hg_settingdialog::slot_gammaButtonClicked() { setPicClrTool dlg(this); int colorMode; // 0-彩色, 1-灰度 if (m_colorModeValue.toStdString() == OPTION_VALUE_YSMS_256JHD || m_colorModeValue.toStdString() == OPTION_VALUE_YSMS_HB) { colorMode = 1; QList keyTable; for (int i = 0; i < m_gammaData.pt_count; ++i) { QPoint pt(m_gammaData.keypoint[i].x, m_gammaData.keypoint[i].y); keyTable.append(pt); } if (!keyTable.empty()) { dlg.setGrayKeyTable(keyTable); } } else { colorMode = 0; QList keyTable; for (int i = 0; i < m_gammaData.pt_count; ++i) { QPoint pt(m_gammaData.keypoint[i].x, m_gammaData.keypoint[i].y); keyTable.append(pt); } QList rKeyTable; for (int i = 0; i < m_gammaData.pt_count_r; ++i) { QPoint pt(m_gammaData.keypoint_r[i].x, m_gammaData.keypoint_r[i].y); rKeyTable.append(pt); } QList gKeyTable; for (int i = 0; i < m_gammaData.pt_count_g; ++i) { QPoint pt(m_gammaData.keypoint_g[i].x, m_gammaData.keypoint_g[i].y); gKeyTable.append(pt); } QList bKeyTable; for (int i = 0; i < m_gammaData.pt_count_b; ++i) { QPoint pt(m_gammaData.keypoint_b[i].x, m_gammaData.keypoint_b[i].y); bKeyTable.append(pt); } QVector> keyTableList; if (!keyTable.empty() && !rKeyTable.empty() && !gKeyTable.empty() && !bKeyTable.empty()) { keyTableList.append(keyTable); keyTableList.append(rKeyTable); keyTableList.append(gKeyTable); keyTableList.append(bKeyTable); dlg.setRGBKeyTable(keyTableList); } } dlg.setColorMode(colorMode); if (dlg.exec()) { memset(&m_gammaData, 0, sizeof(m_gammaData)); clicked_gamma_ = true; if (1 == colorMode) { QList keyTable = dlg.getGrayKeyTable(); m_gammaData.pt_count = HGMIN(4, keyTable.size()); int i = 0; for (QPoint pt : keyTable) { if (i >= 4) break; m_gammaData.keypoint[i].x = pt.x(); m_gammaData.keypoint[i].y = pt.y(); ++i; } uchar data[256]; dlg.getGrayTable(data, 256); for (int i = 0; i < 256; ++i) { m_gammaData.table[i] = data[i]; } } else { QVector> keyTableList = dlg.getRGBKeyTable(); m_gammaData.pt_count = HGMIN(4, keyTableList[0].size()); int i = 0; for (QPoint pt : keyTableList[0]) { if (i >= 4) break; m_gammaData.keypoint[i].x = pt.x(); m_gammaData.keypoint[i].y = pt.y(); ++i; } m_gammaData.pt_count_r = HGMIN(4, keyTableList[1].size()); i = 0; for (QPoint pt : keyTableList[1]) { if (i >= 4) break; m_gammaData.keypoint_r[i].x = pt.x(); m_gammaData.keypoint_r[i].y = pt.y(); ++i; } m_gammaData.pt_count_g = HGMIN(4, keyTableList[2].size()); i = 0; for (QPoint pt : keyTableList[2]) { if (i >= 4) break; m_gammaData.keypoint_g[i].x = pt.x(); m_gammaData.keypoint_g[i].y = pt.y(); ++i; } m_gammaData.pt_count_b = HGMIN(4, keyTableList[3].size()); i = 0; for (QPoint pt : keyTableList[3]) { if (i >= 4) break; m_gammaData.keypoint_b[i].x = pt.x(); m_gammaData.keypoint_b[i].y = pt.y(); ++i; } uchar data[256 * 3]; dlg.getRGBTable(data, 256 * 3); for (int i = 0; i < 256; ++i) { m_gammaData.table[i] = data[i * 3 + 2]; m_gammaData.table[i + 256] = data[i * 3 + 1]; m_gammaData.table[i + 512] = data[i * 3 + 0]; } } unsigned int len = sizeof(SANE_Gamma); m_saneAPI.sane_io_control_api(m_devHandle, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &m_gammaData, &len); cur_scheme_->config_changed(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, (char*)&m_gammaData, sizeof(m_gammaData), true); } } void hg_settingdialog::slot_word_list_comboBoxClicked(int value) { QComboBox *comboBox = qobject_cast(sender()); SANE_Int id = comboBox->property("controls_id").toInt(); SANE_Int temp = value; const SANE_Option_Descriptor* opt = nullptr; for(int i = 0; i < m_list_getOpt.size(); i++) if (m_list_getOpt.at(i).first == id) { opt = reinterpret_cast(m_list_getOpt.at(i).second); break; } m_list_IdValueTitle.append(QPair, QString>(QPair(id, temp), md5(opt->title))); SANE_Int method = 0; m_saneAPI.sane_control_option_api(m_devHandle, id, SANE_ACTION_SET_VALUE, &temp, &method); if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); else if(method & SANE_INFO_INEXACT) { char buf[20]; sprintf(buf, "%d", temp); comboBox->setCurrentText(QString::fromStdString(buf)); } cur_scheme_->config_changed(id, (char*)&temp, sizeof(temp)); } void hg_settingdialog::slot_sliderClicked(int value) { QSlider *slider = qobject_cast(sender()); SANE_Int id = slider->property("controls_id").toInt(); const SANE_Option_Descriptor* opt = nullptr; for(int i = 0; i < m_list_getOpt.size(); i++) if (m_list_getOpt.at(i).first == id) { opt = reinterpret_cast(m_list_getOpt.at(i).second); break; } QAbstractSpinBox* spin = nullptr; for(int i = 0; i < m_list_sliderSpinbox.size(); i++) if (m_list_sliderSpinbox.at(i).first == slider) { spin = reinterpret_cast(m_list_sliderSpinbox.at(i).second); break; } if (spin != nullptr) { SANE_Int val = value, method = 0; bool db_val = false; if (typeid(*spin) == typeid(QSpinBox)) { QSpinBox* spin_ = reinterpret_cast(spin); spin_->setValue(value); m_list_IdValueTitle.append(QPair, QString>(QPair(id, val), md5(opt->title))); } else { QDoubleSpinBox* spin_ = reinterpret_cast(spin); double temp = value * spin_->singleStep(); if(temp != spin_->value()) spin_->setValue(temp); val = SANE_FIX(temp); db_val = true; m_list_IdValueTitle.append(QPair, QString>(QPair(id, temp), md5(opt->title))); } m_saneAPI.sane_control_option_api(m_devHandle, id, SANE_ACTION_SET_VALUE, &val, &method); if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); else if(method & SANE_INFO_INEXACT) { if(db_val) { QDoubleSpinBox* spin_ = reinterpret_cast(spin); double v = SANE_UNFIX(val); spin_->setValue(v); slider->setValue(spin_->value() / spin_->singleStep()); } else { QSpinBox* spin_ = reinterpret_cast(spin); spin_->setValue(val); slider->setValue(spin_->value() / spin_->singleStep()); } } cur_scheme_->config_changed(id, (char*)&val, sizeof(val)); } } void hg_settingdialog::slot_doubleSpinboxClicked(double value) { QDoubleSpinBox* spinBox = qobject_cast(sender()); QAbstractSlider* slider = nullptr; int id = spinBox->property("controls_id").toInt(); for (int i = 0; i < m_list_sliderSpinbox.size(); i++) if (m_list_sliderSpinbox.at(i).second == spinBox) { slider = reinterpret_cast(m_list_sliderSpinbox.at(i).first); break; } if(slider != nullptr) { int temp = static_cast(value / spinBox->singleStep() + 0.5); QSlider* slider_ = reinterpret_cast(slider); if (slider_->value() != temp) slider_->setValue(temp); } } void hg_settingdialog::slot_spinBoxClicked(int value) { QSpinBox* spinBox = qobject_cast(sender()); int id = spinBox->property("controls_id").toInt(); const SANE_Option_Descriptor* opt = nullptr; for(int i = 0; i < m_list_getOpt.size(); i++) if (m_list_getOpt.at(i).first == id) { opt = reinterpret_cast(m_list_getOpt.at(i).second); break; } QAbstractSlider* slider = nullptr; for (int i = 0; i < m_list_sliderSpinbox.size(); i++) if (m_list_sliderSpinbox.at(i).second == spinBox) { slider = reinterpret_cast(m_list_sliderSpinbox.at(i).first); break; } if(slider == nullptr) { SANE_Int temp = value; m_list_IdValueTitle.append(QPair, QString>(QPair(id, temp), md5(opt->title))); SANE_Int method = 0; m_saneAPI.sane_control_option_api(m_devHandle, id, SANE_ACTION_SET_VALUE, &temp, &method); if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); else if(value != temp) { disconnect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int))); spinBox->setValue(temp); connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int))); } cur_scheme_->config_changed(id, (char*)&temp, sizeof(temp)); }else { QSlider* slider_ = reinterpret_cast(slider); slider_->setValue(spinBox->value()); } } void hg_settingdialog::slot_lineEditInput() { QLineEdit* lineEdit = qobject_cast(sender()); int id = lineEdit->property("controls_id").toInt(); std::string lineEditCurrentText(lineEdit->text().toUtf8()); const SANE_Option_Descriptor* opt = nullptr; for(int i = 0; i < m_list_getOpt.size(); i++) if (m_list_getOpt.at(i).first == id) { opt = reinterpret_cast(m_list_getOpt.at(i).second); break; } m_list_IdValueTitle.append(QPair, QString>(QPair(id, &lineEditCurrentText.at(0)), md5(opt->title))); SANE_Int method = 0; void *buf = NULL; SANE_Int nv = 0; if(opt->type == SANE_TYPE_INT) { nv = atoi(lineEditCurrentText.c_str()); buf = &nv; } else if(opt->type == SANE_TYPE_FIXED) { nv = SANE_FIX(atof(lineEditCurrentText.c_str())); buf = &nv; } else { buf = malloc(opt->size * 2 + 4); strcpy((char*)buf, lineEditCurrentText.c_str()); } m_saneAPI.sane_control_option_api(m_devHandle, id, SANE_ACTION_SET_VALUE, buf, &method); if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); else if(method & SANE_INFO_INEXACT) { char mem[20], *v = mem; if(opt->type == SANE_TYPE_INT) sprintf(mem, "%d", nv); else if(opt->type == SANE_TYPE_FIXED) sprintf(mem, "%f", SANE_UNFIX(nv)); else v = (char*)buf; lineEdit->setText(QString::fromStdString(v)); } if(opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED) { cur_scheme_->config_changed(id, (char*)buf, sizeof(SANE_Int)); } else { std::string langCN(to_default_language((char*)buf, nullptr)); cur_scheme_->config_changed(id, &langCN[0], langCN.length()); free(buf); } } void hg_settingdialog::slot_buttonAboutClicked() { char info[256] = { 0 }; SANE_Int data = 0; SANE_Status ret = SANE_STATUS_GOOD; QString content; QString title = tr("about ") + QString::fromStdString(m_devName); ret = m_saneAPI.sane_control_option_api(m_devHandle, (SANE_Int)0x8855, SANE_ACTION_GET_VALUE, info, NULL); if (ret != SANE_STATUS_GOOD) { QString str = tr("Not supported"); strcpy(info, str.toStdString().c_str()); } content += tr("

Device model: %1

").arg(QString(info)); info[0] = 0; ret = m_saneAPI.sane_control_option_api(m_devHandle, (SANE_Int)0x884A, SANE_ACTION_GET_VALUE, info, NULL); if (ret != SANE_STATUS_GOOD) { QString str = tr("Not supported"); strcpy(info, str.toStdString().c_str()); } content += tr("

Driver version: %1

").arg(QString(info)); info[0] = 0; ret = m_saneAPI.sane_control_option_api(m_devHandle, (SANE_Int)0x8857, SANE_ACTION_GET_VALUE, info, NULL); if (ret != SANE_STATUS_GOOD) { QString str = tr("Not supported"); strcpy(info, str.toStdString().c_str()); } content += tr("

Firmware number: %1

").arg(QString(info)); info[0] = 0; ret = m_saneAPI.sane_control_option_api(m_devHandle, (SANE_Int)0x8856, SANE_ACTION_GET_VALUE, info, NULL); if (ret != SANE_STATUS_GOOD) { QString str = tr("Not supported"); strcpy(info, str.toStdString().c_str()); } content += tr("

Serial number: %1

").arg(QString(info)); info[0] = 0; ret = m_saneAPI.sane_control_option_api(m_devHandle, (SANE_Int)0x9902, SANE_ACTION_GET_VALUE, &data, NULL); if (ret != SANE_STATUS_GOOD) { QString str = tr("Not supported"); strcpy(info, str.toStdString().c_str()); content += tr("

Roller count: %1

").arg(QString(info)); info[0] = 0; } else { content += tr("

Roller count: %1

").arg(QString::number(data)); } ret = m_saneAPI.sane_control_option_api(m_devHandle, (SANE_Int)0x8849, SANE_ACTION_GET_VALUE, &data, NULL); if (ret != SANE_STATUS_GOOD) { QString str = tr("Not supported"); strcpy(info, str.toStdString().c_str()); content += tr("

Roller count: %1

").arg(QString(info)); info[0] = 0; } else { content += tr("

History count: %1

").arg(QString::number(data)); } QMessageBox msg(QMessageBox::NoIcon, title, content, QMessageBox::Ok, this); msg.setStyleSheet("QLabel{""min-width: 250px;""}"); msg.exec(); } void hg_settingdialog::slot_buttonScanClicked() { save_scheme(); m_closeButton = closeButtonScan; m_callback(UI_RESULT_START_SCAN); } void hg_settingdialog::slot_buttonOkClicked() { save_ = true; m_closeButton = closeButtonOk; close(); } void hg_settingdialog::slot_buttonCancelClicked() { m_closeButton = closeButtonCancel; close(); } void hg_settingdialog::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { e->ignore(); } else { QDialog::keyPressEvent(e); } } int hg_settingdialog::get_changed_items(void) { return changed_count_; } int hg_settingdialog::getCloseButtonCliked() { return m_closeButton; } gb::sane_config_schm *hg_settingdialog::getCurScheme() { return cur_scheme_; } //生成UTF-8编码的MD5值 QString hg_settingdialog::md5(QString key) { QCryptographicHash md5(QCryptographicHash::Md5); md5.addData(key.toUtf8()); return QString(md5.result().toHex()); } const void* hg_settingdialog::find_option_description(int id) { for(int i = 0; i < m_list_getOpt.size(); i++) { if (m_list_getOpt.at(i).first == id) return reinterpret_cast(m_list_getOpt.at(i).second); } return nullptr; } const void* hg_settingdialog::find_option_description(const std::string& title, int* id) { for(int i = 0; i < m_list_getOpt.size(); i++) { std::string t((reinterpret_cast(m_list_getOpt.at(i).second))->name); if (title == t) { if(id) *id = m_list_getOpt.at(i).first; return reinterpret_cast(m_list_getOpt.at(i).second); } } return nullptr; } void hg_settingdialog::closeEvent(QCloseEvent* e) { if(e->type() == QEvent::Close) // consider as cancel ... { if(save_) save_scheme(); else cancel_setting(); } e->accept(); } bool hg_settingdialog::createMsgBoxUi(bool add, std::string &name) { QString text(tr("Please select to overwrite the original configuration:")); text += QString::fromStdString(name); text += tr(",or add a new configuration"); QDialog *dlg = new QDialog(this); dlg->setWindowTitle(tr("save the configuration")); QLabel *label_question = new QLabel; label_question->setText(text); QRadioButton *radioButtonCover = new QRadioButton; radioButtonCover->setText(tr("cover original configuration:") + QString::fromStdString(name)); radioButtonCover->setChecked(true); add = false; QRadioButton *radioButtonNew = new QRadioButton; radioButtonNew->setText(tr("add new configuration")); QHBoxLayout *hLayoutName = new QHBoxLayout; QLabel *label_name = new QLabel; label_name->setText(tr("rename:")); m_lineEdit_name = new QLineEdit; std::string name2; m_lineEdit_name->setText(QString::fromStdString(getCurUiShemeName(name2))); QSpacerItem *spacer1 = new QSpacerItem(20, 20, QSizePolicy::Expanding); hLayoutName->addWidget(label_name); hLayoutName->addWidget(m_lineEdit_name); hLayoutName->addSpacerItem(spacer1); label_name->setVisible(false); m_lineEdit_name->setVisible(false); bool cover = true; connect(radioButtonCover, &QRadioButton::clicked, this, [=, &add, &cover](){ cover = true; add = false; label_name->setVisible(false); m_lineEdit_name->setVisible(false); }); connect(radioButtonNew, &QRadioButton::clicked, this, [=, &add, &cover](){ cover = false; add = true; label_name->setVisible(true); m_lineEdit_name->setVisible(true); m_lineEdit_name->setFocus(); QTimer::singleShot(0, m_lineEdit_name, &QLineEdit::selectAll); }); QSpacerItem *spacer2 = new QSpacerItem(20, 20, QSizePolicy::Expanding); QPushButton *pbtnOk = new QPushButton; pbtnOk->setText(tr("ok")); connect(pbtnOk, &QPushButton::clicked, this, [=, &name, &cover](){ QString text = m_lineEdit_name->text(); static QRegularExpression re("\\s"); text.remove(re);//Remove space name = text.toStdString(); if(name.empty()) { QMessageBox::information(this, tr("tips"), tr("scheme name cannot be empty")); m_lineEdit_name->setText(QString::fromStdString(getCurUiShemeName(name))); return; } if (!cover) { std::vector now; cur_cfg_->get_all_schemes(now); for(auto& v: now) { if(v == name) { QMessageBox::information(this, tr("tips"), tr("scheme name: ") + QString::fromStdString(name) + tr(" already exists")); m_lineEdit_name->setText(QString::fromStdString(getCurUiShemeName(name))); return; } } } dlg->close(); }); QHBoxLayout *hLayout_pbtnOk = new QHBoxLayout; hLayout_pbtnOk->addSpacerItem(spacer2); hLayout_pbtnOk->addWidget(pbtnOk); QVBoxLayout *vLayout = new QVBoxLayout; vLayout->addWidget(label_question); vLayout->addWidget(radioButtonCover); vLayout->addWidget(radioButtonNew); vLayout->addLayout(hLayoutName); vLayout->addLayout(hLayout_pbtnOk); dlg->setLayout(vLayout); dlg->exec(); return add; } std::string hg_settingdialog::getCurUiShemeName(std::string name) { std::string k(""), val(""); int id = 0; const SANE_Option_Descriptor* opt = nullptr; if (cur_scheme_->first_config(k, val)) { int count = 0; do { id = cur_scheme_->id_from_name(k.c_str()); opt = id == -1 ? nullptr : m_saneAPI.sane_get_option_descriptor_api(m_devHandle, id); if (opt) { if (count++) name += " + "; if (opt->type == SANE_TYPE_STRING) name += from_default_language(val.c_str(), nullptr); else { name += opt->title; if (opt->type == SANE_TYPE_BOOL) { name += std::string("("); if (*(SANE_Bool*)&val[0] == SANE_TRUE) name += "true)"; else name += "false)"; } else if (opt->type == SANE_TYPE_INT) { char buf[128] = { 0 }; sprintf(buf, "(%d)", *(int*)&val[0]); name += buf; } else if (opt->type == SANE_TYPE_FIXED) { char buf[128] = { 0 }; sprintf(buf, "(%.4f)", SANE_UNFIX(*(SANE_Fixed*)&val[0])); name += buf; } } } } while (count < 3 && cur_scheme_->next_config(k, val)); } return name; } void hg_settingdialog::save_scheme(void) { std::string name(cur_scheme_->get_scheme_name()); bool add = name.empty(); if(add) { name = getCurUiShemeName(name); } else { int items = 0; add = cur_scheme_->has_changed(&items); if(add) { if(items == 0) // while shemes is default { cur_cfg_->select_scheme(nullptr); return; } else add = createMsgBoxUi(add, name); } } if(add) { if(name.empty() && cur_scheme_->get_scheme_name().empty()) { cur_scheme_->end_setting(true); return; } gb::sane_config_schm* cp = cur_scheme_->copy(); cur_scheme_->end_setting(true); cur_scheme_->release(); cur_scheme_ = cp; size_t pos = name.rfind('-'); int ind = 0; char append[20] = {0}; if(pos != std::string::npos) { ind = atoi(name.c_str() + pos + 1); if(ind > 0) { name.erase(pos); sprintf(append, "-%d", ++ind); } } while(!cur_cfg_->add_scheme(cur_scheme_, (name + append).c_str())) { sprintf(append, "-%d", ++ind); } } else { cur_scheme_->end_setting(false); } cur_cfg_->select_scheme(cur_scheme_->get_scheme_name().c_str()); cur_cfg_->save(); } void hg_settingdialog::cancel_setting(void) { // restore changed value ... cur_scheme_->end_setting(true); dev_que::apply_scheme(&m_saneAPI, m_devHandle, cur_scheme_); } void hg_settingdialog::getAppVersion() { SANE_About *about = nullptr; unsigned int len = 0; std::string versionNum; if (m_saneAPI.sane_io_control_api(m_devHandle, 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 (m_saneAPI.sane_io_control_api(m_devHandle, IO_CTRL_CODE_ABOUT_INFO, about, &len) == SANE_STATUS_GOOD) { versionNum = about->version; } } } } void hg_settingdialog::apply_current_scheme(void) { dev_que::apply_scheme(&m_saneAPI, m_devHandle, cur_scheme_); } std::string sane_val_to_string(const char* val, SANE_Value_Type type) { char buf[128] = {0}; std::string ret(""); switch(type) { case SANE_TYPE_BOOL: ret = *(SANE_Bool*)val == SANE_TRUE ? "true" : "false"; break; case SANE_TYPE_INT: sprintf(buf, "%d", *(int*)val); ret = buf; break; case SANE_TYPE_FIXED: sprintf(buf, "%.4f", SANE_UNFIX(*(SANE_Fixed*)val)); ret = buf; break; default: ret = val; break; } return ret; } void hg_settingdialog::on_current_scheme_changed() { QString scheme(comb_->currentText()); bool enabled = false; gb::sane_config_schm *schm = cur_cfg_->get_scheme(scheme.toStdString().c_str()); if(schm) enabled = true; rename_->setEnabled(enabled); apply_->setEnabled(enabled); del_this_->setEnabled(enabled); del_all_->setEnabled(enabled); memset(&m_gammaData, 0, sizeof(m_gammaData)); for(int i = 0; i < sizeof(m_gammaData.table) / sizeof(m_gammaData.table[0]); ++i) m_gammaData.table[i] = i & 0x0ff; QString info(tr("")); std::string name(""), val(""); if(schm && schm->first_config(name, val)) { do { QString title; SANE_Value_Type type = SANE_TYPE_STRING; for (int ii = 0; ii < m_list_defaultOptions.size(); ii++) { const SANE_Option_Descriptor* opt = reinterpret_cast(m_list_defaultOptions.at(ii).first); if(strcmp(opt->name, name.c_str()) == 0) { title = QString::fromStdString(opt->title); type = opt->type; if(type == SANE_TYPE_STRING) val = from_default_language(val.c_str(), nullptr); break; } } if(title.length()) { info += tr("
") + title + tr(":
"); info += tr("

") + QString::fromStdString(sane_val_to_string(val.c_str(), type)) + tr("

"); } else { if(val.length() == sizeof(SANE_Gamma)) memcpy(&m_gammaData, val.c_str(), sizeof(SANE_Gamma)); } }while(schm->next_config(name, val)); } if(schm) schm->release(); sketch_->setHtml(info); } void hg_settingdialog::slot_pushButton_scheme_management(void) { QPushButton* btn = qobject_cast(sender()); if(btn == rename_) { int id = 0; QString text(find_current_scheme_menu(&id)); if(!text.isEmpty() && id >= 0) { Dialog_Input dlg; dlg.init_value(text); dlg.setWindowTitle(tr("configuration scheme name change")); if(dlg.exec() && text != dlg.get_inputting_value()) { std::vector now; std::string str = dlg.get_inputting_value().toStdString(); cur_cfg_->get_all_schemes(now); for(auto& v: now) { if(v == str) { QMessageBox::information(this, tr("tips"), tr("scheme name: ") + QString::fromStdString(str) + tr(" already exists")); return; } } disconnect(comb_, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_current_scheme_changed())); comb_->removeItem(id); comb_->insertItem(id, QString::fromStdString(str)); comb_->setCurrentIndex(id); connect(comb_, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_current_scheme_changed())); cur_cfg_->rename_scheme(text.toStdString().c_str(), str.c_str()); cur_cfg_->save(); changed_count_++; } } } else if(btn == apply_) { QString text(find_current_scheme_menu()); gb::sane_config_schm *cur = nullptr; cur_cfg_->select_scheme(text.toStdString().c_str()); cur = cur_cfg_->get_scheme(); if(!cur) cur = new gb::sane_config_schm(); cur->copy_default_value(cur_scheme_); cur_scheme_->end_setting(true); cur_scheme_->release(); cur_scheme_ = cur; cur_scheme_->begin_setting(); apply_current_scheme(); updateUIStatus(); changed_count_++; } else if(btn == del_this_) { int id = -1; QString text(find_current_scheme_menu(&id)); if(text.isEmpty()) return; QMessageBox msg(QMessageBox::Question, tr("be sure to delete the configuration"), tr("Are you sure you want to delete the configuration \"") + text + tr("\" ?"), QMessageBox::Yes | QMessageBox::No, this); msg.exec(); if (msg.clickedButton() != msg.button(QMessageBox::Yes)) return; gb::sane_config_schm *sch = cur_cfg_->get_scheme(text.toStdString().c_str()); cur_cfg_->remove_scheme(text.toStdString().c_str()); comb_->removeItem(id); sch->release(); if(sch == cur_scheme_) { restore_2_default_settings(); updateUIStatus(); } on_current_scheme_changed(); changed_count_++; cur_cfg_->save(); } else if(btn == del_all_) { QMessageBox msg(QMessageBox::Question, tr("be sure to delete the configuration"), tr("Are you sure you want to delete the configuration?"), QMessageBox::Yes | QMessageBox::No, this); msg.exec(); if (msg.clickedButton() != msg.button(QMessageBox::Yes)) return; restore_2_default_settings(); updateUIStatus(); comb_->clear(); changed_count_++; cur_cfg_->remove_all_schemes(); cur_cfg_->save(); } } void hg_settingdialog::restore_2_default_settings(void) { cur_scheme_->end_setting(true); cur_cfg_->select_scheme(nullptr); dev_que_.apply_scheme(&m_saneAPI, nullptr); cur_cfg_->save(); gb::sane_config_schm *s = new gb::sane_config_schm(); s->copy_default_value(cur_scheme_); cur_scheme_->release(); cur_scheme_ = s; cur_scheme_->begin_setting(); on_current_scheme_changed(); }