#include "hg_settingdialog.h" #include #include #include "cutpapertool.h" #include "setpicclrtool.h" #include "base/HGDef.h" #include "HGString.h" #include "sane/sane_option_definitions.h" #include "dialog_input.h" #include std::string hg_settingdialog::property_combox_data_type_ = "combox_value_type"; hg_settingdialog::hg_settingdialog(void *handle, QWidget *parent , DEVCFG* cfg) : QDialog(parent) , schemes_(cfg), cur_ind_(cfg->cur_scheme), changed_count_(0), save_(false) , btn_cut_area_(nullptr), btn_gamma_(nullptr), cfg_file_(nullptr), clicked_gamma_(false) , custom_area_lable_(nullptr), comb_(nullptr) { 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; m_handle = handle; initUi(); on_select_scheme(cur_ind_, false); } hg_settingdialog::~hg_settingdialog() { } void hg_settingdialog::initUi() { updateOpt(); createUI(); setWindowTitle(schemes_ ? QString::fromStdString(schemes_->name) : tr("set")); resize(690, height()); } void hg_settingdialog::updateOpt() { bool first = default_vals_.empty(); m_list_defaultOptions.clear(); SANE_Int dev_options = 0; sane_control_option(m_handle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr); for (int i = 1, j= dev_options; i < j; i++) { const SANE_Option_Descriptor* opt = sane_get_option_descriptor(m_handle, i); SANE_Int method = 0; if (opt == nullptr) { m_list_defaultOptions.append(QPair(opt, QVariant(0))); } else { CHANGEDOPT co; co.opt = i; co.val.clear(); if(opt->type == SANE_TYPE_INT) { SANE_Int init = 0; sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, &init, &method); m_list_defaultOptions.append(QPair(opt, QVariant(init))); std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i); if(it != changed_opts_.end()) it->val = QVariant(init); if(first) { unsigned int opt = i; sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &opt); co.val = QVariant(init); } } else if(opt->type == SANE_TYPE_FIXED) { SANE_Fixed init = 0; sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, &init, &method); m_list_defaultOptions.append(QPair(opt, QVariant(init))); std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i); if(it != changed_opts_.end()) it->val = QVariant(SANE_UNFIX(init)); if(first) { unsigned int opt = i; sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &opt); co.val = QVariant(SANE_UNFIX(init)); } } else if(opt->type == SANE_TYPE_BOOL) { SANE_Bool init = 0; sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, &init, &method); m_list_defaultOptions.append(QPair(opt, QVariant(init))); std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i); if(it != changed_opts_.end()) it->val = QVariant(init); if(first) { unsigned int opt = i; sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &opt); co.val = QVariant(init); } } else if(opt->type == SANE_TYPE_STRING) { char *init = (char*)malloc(opt->size * 2 + 4); sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, init, &method); m_list_defaultOptions.append(QPair(opt, QVariant(QString::fromStdString(init)))); std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i); if(it != changed_opts_.end()) it->val = QVariant(QString::fromStdString(init)); if(first) { unsigned int opt = i; int err = sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, init, &opt); (void)err; co.val = QVariant(QString::fromStdString(init)); } free(init); } else { co.opt = -1; m_list_defaultOptions.append(QPair(opt, QVariant(0))); } if(first && co.opt != -1) default_vals_.push_back(co); } } } 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; comb_ = new QComboBox(this); layout->addSpacing(30); for(int i = 1; i < (int)schemes_->schemes.size(); ++i) { comb_->addItem(QString::fromStdString(schemes_->schemes[i].name)); if(schemes_->cur_scheme == i - 1) { enabled = true; comb_->setCurrentText(QString::fromStdString(schemes_->schemes[i].name)); } } if(!enabled) comb_->setCurrentIndex(-1); title->setFixedWidth(width); comb_->setFixedWidth(width); title->setText(QString::fromStdString("\347\216\260\346\234\211\351\205\215\347\275\256\346\226\271\346\241\210\357\274\232")); layout->addWidget(title); layout->addWidget(comb_); rename_ = new QPushButton(this); rename_->setText(QString::fromStdString("\346\224\271\345\220\215")); 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(QString::fromStdString("\345\210\240\351\231\244")); 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(QString::fromStdString("\345\272\224\347\224\250")); 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(QString::fromStdString("\351\205\215\347\275\256\344\277\241\346\201\257\357\274\232")); 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 *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(buttonOk); hlayoutOkAndCancel->addWidget(buttonCancel); QWidget *widgetOkAndCancel = new QWidget(); widgetOkAndCancel->setLayout(hlayoutOkAndCancel); connect(buttonOk, SIGNAL(clicked(bool)), this, SLOT(slot_buttonOkClicked())); connect(buttonCancel, SIGNAL(clicked(bool)), this, SLOT(slot_buttonCancelClicked())); QHBoxLayout *h = new QHBoxLayout(); QVBoxLayout *v1 = new QVBoxLayout(), *v2 = new QVBoxLayout(); create_scheme_management_ui(v1); v2->addWidget(tabWidgetCreation); QGroupBox *grp = new QGroupBox(QString::fromStdString("\351\205\215\347\275\256\346\226\271\346\241\210\347\256\241\347\220\206"), 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; CHANGEDOPT init; 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, scheme = cur_ind_ + 1; if(opt == nullptr) continue; if(schemes_ && cur_ind_ != -1) ind = find_opt_setting(opt->title, schemes_->schemes[scheme].opts); init.opt = i + 1; h = nullptr; switch (opt->type) { case SANE_TYPE_BOOL: { QCheckBox *checkBoxCreation = new QCheckBox(scrollArea); if (strcmp(opt->title, OPTION_TITLE_ZDYSMQY) == 0) { QLabel *title = new QLabel(scrollArea); h = new QHBoxLayout(); title->setText(QString::fromStdString(opt->title) + QString(" : ")); h->addWidget(title); h->addWidget(checkBoxCreation); btn_cut_area_ = new QPushButton(this); btn_cut_area_->setText(StdStringToUtf8("区域裁剪").c_str()); btn_cut_area_->setFixedWidth(120); h->addWidget(btn_cut_area_); custom_area_lable_ = title; reinterpret_cast(widget->layout())->addRow(h); connect(btn_cut_area_, SIGNAL(clicked(bool)), this, SLOT(slot_cutButtonClicked())); } else if (strcmp(opt->title, OPTION_TITLE_QYSDQX) == 0) { QLabel *title = new QLabel(scrollArea); h = new QHBoxLayout(); title->setText(QString::fromStdString(opt->title) + QString(" : ")); h->addWidget(title); h->addWidget(checkBoxCreation); btn_gamma_ = new QPushButton(this); btn_gamma_->setText(StdStringToUtf8("自定义色调曲线").c_str()); btn_gamma_->setFixedWidth(120); h->addWidget(btn_gamma_); reinterpret_cast(widget->layout())->addRow(h); 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; checkBoxCreation->setProperty("controls_id", id); if(ind != -1) init.val = QVariant(schemes_->schemes[scheme].opts[ind].val == "true"); else init.val = m_list_defaultOptions.at(i).second; checkBoxCreation->setChecked(init.val.toBool()); if (strcmp(opt->title, OPTION_TITLE_ZDYSMQY) == 0) btn_cut_area_->setEnabled(init.val.toBool()); else if (strcmp(opt->title, OPTION_TITLE_QYSDQX) == 0) btn_gamma_->setEnabled(init.val.toBool()); connect(checkBoxCreation, SIGNAL(stateChanged(int)), this, SLOT(slot_checkedClicked())); m_list_widgets.append(checkBoxCreation); m_list_getOpt.append(QPair(id, opt)); iniRead(md5(opt->title), id, checkBoxCreation); 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, 500); 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)); if(ind == -1) init.val = m_list_defaultOptions.at(i).second; else init.val = QVariant(atoi(schemes_->schemes[scheme].opts[ind].val.c_str())); spinBox->setValue(init.val.toInt()); 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(200); 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)); if(ind == -1) init.val = m_list_defaultOptions.at(i).second; else init.val = QVariant(atoi(schemes_->schemes[scheme].opts[ind].val.c_str())); spinBox->setValue(init.val.toInt()); sliderCreation->setValue(init.val.toInt()); 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)); if(ind == -1) init.val = m_list_defaultOptions.at(i).second; else init.val = QVariant(QString::fromStdString(schemes_->schemes[scheme].opts[ind].val)); comboBoxCreation->setCurrentText(init.val.toString()); 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(200); 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); if(ind == -1) init.val = SANE_UNFIX(m_list_defaultOptions.at(i).second.toInt()); else init.val = QVariant(atof(schemes_->schemes[scheme].opts[ind].val.c_str())); sliderCreation->setValue(init.val.toDouble() * 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); if(ind == -1) init.val = m_list_defaultOptions.at(i).second; else init.val = QVariant(schemes_->schemes[scheme].opts[ind].val.c_str()); lineEdit->setText(init.val.toString()); 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); if(ind == -1) init.val = m_list_defaultOptions.at(i).second; else init.val = QVariant(QString::fromStdString(schemes_->schemes[scheme].opts[ind].val)); comboBoxCreation->setCurrentText(init.val.toString()); 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())); init.opt = -1; 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); init.opt = -1; break; } } //switch(opt->type) // if (Utf8ToStdString(opt->title) == "分辨率") if (strcmp(opt->title, OPTION_TITLE_FBL) == 0) { m_dpiId = i + 1; m_dpiValue = m_list_defaultOptions.at(i).second.toInt(); } // else if (Utf8ToStdString(opt->title) == "纸张尺寸") else if (strcmp(opt->title, OPTION_TITLE_ZZCC) == 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->title, OPTION_TITLE_YSMS) == 0) { m_colorModeId = i + 1; m_colorModeValue = m_list_defaultOptions.at(i).second.toString(); } // else if (Utf8ToStdString(opt->title) == "伽玛" || Utf8ToStdString(opt->title) == "伽玛值") if(init.opt != -1) init_vals_.push_back(init); } //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())); } } } } } bool hg_settingdialog::is_covered(std::vector& org, std::vector& now) { bool yes = now.size() >= org.size(); if(yes) { for(size_t i = 0; i < org.size(); ++i) { std::vector::iterator it = std::find(now.begin(), now.end(), org[i].name); if(it == now.end()) { yes = false; break; } } } return yes; } 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; sane_control_option(m_handle, 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->title, OPTION_TITLE_SMQYZCmm) == 0 || strcmp(opt->title, OPTION_TITLE_SMQYSCmm) == 0 || strcmp(opt->title, OPTION_TITLE_SMQYYCmm) == 0 || strcmp(opt->title, OPTION_TITLE_SMQYXCmm) == 0 ) hide = true; refresh_control_value(id); if(w_label) hide ? w_label->hide() : w_label->show(); widget->setVisible(!hide); if(strcmp(opt->title, OPTION_TITLE_ZDYSMQY) == 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; sane_control_option(m_handle, 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->title, OPTION_TITLE_ZDYSMQY) == 0) btn_cut_area_->setEnabled(checkBoxcurrentState); else if (strcmp(opt->title, OPTION_TITLE_QYSDQX) == 0) btn_gamma_->setEnabled(checkBoxcurrentState); record_changed_option((int)id, 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()); sane_control_option(m_handle, 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) record_changed_option((int)id, *((SANE_Int*)buf)); else if(type == COMBO_VAL_FLOAT) record_changed_option((int)id, SANE_UNFIX(*(SANE_Fixed*)buf)); else record_changed_option((int)id, buf); free(buf); } void hg_settingdialog::slot_pushButtonClicked() { QPushButton *pushButton = qobject_cast(sender()); SANE_Int id = pushButton->property("controls_id").toInt(), after = 0; id = sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, NULL, &after); if((after & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) updateUIStatus(); } 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); sane_control_option(m_handle, m_cutLeftId, SANE_ACTION_SET_VALUE, &value, &info); value = SANE_FIX(m_cutTopValue); sane_control_option(m_handle, m_cutTopId, SANE_ACTION_SET_VALUE, &value, &info); value = SANE_FIX(m_cutRightValue); sane_control_option(m_handle, m_cutRightId, SANE_ACTION_SET_VALUE, &value, &info); value = SANE_FIX(m_cutBottomValue); sane_control_option(m_handle, m_cutBottomId, SANE_ACTION_SET_VALUE, &value, &info); // write-down changes ... record_changed_option(m_cutLeftId, m_cutLeftValue); record_changed_option(m_cutRightId, m_cutRightValue); record_changed_option(m_cutTopId, m_cutTopValue); record_changed_option(m_cutBottomId, m_cutBottomValue); } } 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); sane_io_control(m_handle, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &m_gammaData, &len); } } 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; sane_control_option(m_handle, 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)); } std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), (int)id); if(it == changed_opts_.end()) { CHANGEDOPT co; co.opt = id; co.val = QVariant(temp); changed_opts_.push_back(co); } else { it->val = QVariant(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))); } sane_control_option(m_handle, 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()); } } std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), (int)id); if(it == changed_opts_.end()) { CHANGEDOPT co; co.opt = id; if(db_val) co.val = QVariant(SANE_UNFIX(val)); else co.val = QVariant(val); changed_opts_.push_back(co); } else { if(db_val) it->val = QVariant(SANE_UNFIX(val)); else it->val = QVariant(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); } std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), (int)id); if(it == changed_opts_.end()) { CHANGEDOPT co; co.opt = id; co.val = value; changed_opts_.push_back(co); } else { it->val = value; } } 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; sane_control_option(m_handle, 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))); } value = temp; }else { QSlider* slider_ = reinterpret_cast(slider); slider_->setValue(spinBox->value()); } std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), (int)id); if(it == changed_opts_.end()) { CHANGEDOPT co; co.opt = id; co.val = value; changed_opts_.push_back(co); } else { it->val = 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()); } sane_control_option(m_handle, 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)); } QVariant changed; if(opt->type == SANE_TYPE_INT) changed = QVariant(nv); else if(opt->type == SANE_TYPE_FIXED) changed = QVariant(SANE_UNFIX(nv)); else { changed = QVariant((char*)buf); free(buf); } std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), (int)id); if(it == changed_opts_.end()) { CHANGEDOPT co; co.opt = id; co.val = changed; changed_opts_.push_back(co); } else { it->val = changed; } } void hg_settingdialog::slot_buttonOkClicked() { save_ = true; close(); } void hg_settingdialog::slot_buttonCancelClicked() { 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_; } void hg_settingdialog::set_config_file(config* cfg) { cfg_file_ = cfg; } void hg_settingdialog::iniWrite(QString title, int id, QVariant value) { (void)title; (void)id; (void)value; // m_qstrFileName = QCoreApplication::applicationDirPath() + "/config.ini"; // m_configIniWrite = new QSettings(m_qstrFileName, QSettings::IniFormat); // m_configIniWrite->setIniCodec(QTextCodec::codecForName("UTF-8")); // m_configIniWrite->setValue(title + "/id", id); // m_configIniWrite->setValue(title + "/value", value); // delete m_configIniWrite; // m_configIniWrite = nullptr; } void hg_settingdialog::iniRead(QString title, int id, QWidget *w) { (void)title; (void)id; (void)w; // m_configIniRead = new QSettings("config.ini", QSettings::IniFormat); // m_configIniRead->setIniCodec(QTextCodec::codecForName("UTF-8")); // int id_ini = m_configIniRead->value(title + "/id").toInt(); // QVariant value = m_configIniRead->value(title + "/value"); // if(id_ini == id) // { // if(typeid(*w) == typeid(QCheckBox)) // reinterpret_cast(w)->setChecked(value.toBool()); // else if(typeid(*w) == typeid(QSlider)) // reinterpret_cast(w)->setValue(value.toInt()); // else if(typeid(*w) == typeid(QSpinBox)) // reinterpret_cast(w)->setValue(value.toInt()); // else if(typeid(*w) == typeid(QDoubleSpinBox)) // reinterpret_cast(w)->setValue(value.toDouble()); // else if(typeid(*w) == typeid(QComboBox)) // reinterpret_cast(w)->setCurrentText(value.toString()); // } // delete m_configIniRead; // m_configIniRead = nullptr; } //生成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))->title); if (title == t) { if(id) *id = m_list_getOpt.at(i).first; return reinterpret_cast(m_list_getOpt.at(i).second); } } return nullptr; } QVariant hg_settingdialog::find_default_value(int id) { std::vector::iterator it = std::find(default_vals_.begin(), default_vals_.end(), id); if(it == default_vals_.end()) return QVariant(); else return it->val; } bool hg_settingdialog::is_equal_default_value(const CHANGEDOPT& opt, int type) { QVariant qv = find_default_value(opt.opt); if(qv.isNull()) return false; if(type == SANE_TYPE_INT) return opt.val.toInt() == qv.toInt(); if(type == SANE_TYPE_FIXED) return IS_DOUBLE_EQUAL(opt.val.toDouble(), qv.toDouble()); if(type == SANE_TYPE_BOOL) return opt.val.toBool() == qv.toBool(); if(type == SANE_TYPE_STRING) return qv.toString() == opt.val.toString(); return true; } bool hg_settingdialog::set_opt_value_for_OPTVAL(QVariant val, int type, OPTVAL* ov) { char buf[40]; if(type == SANE_TYPE_INT) { ov->type = "int"; sprintf(buf, "%d", val.toInt()); ov->val = buf; } else if(type == SANE_TYPE_BOOL) { ov->type = "bool"; ov->val = val.toBool() ? "true" : "false"; } else if(type == SANE_TYPE_FIXED) { sprintf(buf, "%f", val.toDouble()); ov->type = "float"; ov->val = buf; } else if(type == SANE_TYPE_STRING) { ov->type = "string"; ov->val = val.toString().toStdString(); } else { return false; } return true; } void hg_settingdialog::on_select_scheme(int scheme_ind, bool apply_to_dev) { OPTSCHEME *schm = NULL; 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; btn_cut_area_->setEnabled(false); btn_gamma_->setEnabled(false); changed_opts_.clear(); if(scheme_ind >= 0 && scheme_ind + 1 < (int)schemes_->schemes.size()) { scheme_ind++; schm = &schemes_->schemes[scheme_ind]; for(size_t i = 0; i < schemes_->schemes[scheme_ind].opts.size(); ++i) { CHANGEDOPT co; const SANE_Option_Descriptor* opt = (const SANE_Option_Descriptor*)find_option_description(schemes_->schemes[scheme_ind].opts[i].name, &co.opt); if(opt) { bool ok = true; if(opt->type == SANE_TYPE_BOOL) co.val = QVariant(schemes_->schemes[scheme_ind].opts[i].val == "true"); else if(opt->type == SANE_TYPE_INT) co.val = QVariant(atoi(schemes_->schemes[scheme_ind].opts[i].val.c_str())); else if(opt->type == SANE_TYPE_FIXED) co.val = QVariant(atof(schemes_->schemes[scheme_ind].opts[i].val.c_str())); else if(opt->type == SANE_TYPE_STRING) co.val = QVariant(QString::fromStdString(schemes_->schemes[scheme_ind].opts[i].val)); else ok = false; if(ok) { changed_opts_.push_back(co); if(strcmp(opt->title, OPTION_TITLE_ZDYSMQY) == 0) btn_cut_area_->setEnabled(co.val.toBool()); else if(strcmp(opt->title, OPTION_TITLE_QYSDQX) == 0) { btn_gamma_->setEnabled(co.val.toBool()); if(co.val.toBool()) config::load_custom_gamma(schm->opts[i].extra.c_str(), &m_gammaData); } } } } } if(apply_to_dev) { clicked_gamma_ = false; if(scheme_ind >= 0 && scheme_ind + 1 < (int)schemes_->schemes.size()) schemes_->cur_scheme = scheme_ind; else schemes_->cur_scheme = -1; apply_settings(schm); updateUIStatus(); } } QString hg_settingdialog::gen_gamma_file_path(void) { time_t now = time(nullptr); tm *ptm = localtime(&now); char name[80] = {0}; QString gamma_file; sprintf(name, "/%04d%02d%02d%02d%02d%02d.gma", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); if(cfg_file_) { std::string str(cfg_file_->get_file().toStdString()); size_t pos = str.rfind('/'); if(pos == std::string::npos) pos = str.rfind('\\'); if(pos != std::string::npos) str.erase(pos); gamma_file = QString::fromStdString(str); } else gamma_file = config::self_path(); gamma_file += QString::fromStdString(name); return gamma_file; } void hg_settingdialog::closeEvent(QCloseEvent* e) { if(e->type() == QEvent::Close) // consider as cancel ... { if(save_) save_scheme(); else cancel_setting(); } e->accept(); } int hg_settingdialog::find_covered_scheme(OPTSCHEME& scheme) { for(int ind = 1; ind < (int)schemes_->schemes.size(); ++ind) { if(is_covered(schemes_->schemes[ind].opts, scheme.opts)) { schemes_->schemes.erase(schemes_->schemes.begin() + ind); return ind - 1; } } return schemes_->schemes.size() - 1; } void hg_settingdialog::save_scheme(void) { OPTSCHEME src; int names = 0; OPTVAL ov; OPTSCHEME os; QString gamma_file(""); const SANE_Option_Descriptor *opt = nullptr; if(cur_ind_ >= 0 && cur_ind_ + 1 < (int)schemes_->schemes.size()) src = schemes_->schemes[cur_ind_ + 1]; for(size_t i = 0; i < changed_opts_.size(); ++i) { opt = (const SANE_Option_Descriptor*)find_option_description(changed_opts_[i].opt); if(!opt) continue; if(opt->cap & SANE_CAP_INACTIVE) // fixed for bug-126 continue; if(is_equal_default_value(changed_opts_[i], opt->type)) continue; if(!set_opt_value_for_OPTVAL(changed_opts_[i].val, opt->type, &ov)) continue; // bool existing = false; ov.name = opt->title; // for(size_t i = 0; i < src.opts.size(); ++i) // { // if(ov == src.opts[i]) // { // existing = true; // break; // } // } // if(existing) // continue; os.opts.push_back(ov); if(names < 3) { if(opt->type == SANE_TYPE_STRING) { if(!os.name.empty()) os.name += " + "; os.name += ov.val; names++; } } } if(os == src) { if(changed_count_ == 0) changed_count_ = schemes_->cur_scheme != cur_ind_; schemes_->cur_scheme = cur_ind_; if(cur_ind_ >= 0 && cur_ind_ + 1 < (int)schemes_->schemes.size()) { OPTSCHEME& schm = schemes_->schemes[cur_ind_ + 1]; std::vector::iterator it1 = std::find(schm.opts.begin(), schm.opts.end(), OPTION_TITLE_QYSDQX); if(it1 != schm.opts.end()) { if(it1->extra.empty()) { changed_count_++; gamma_file = gen_gamma_file_path(); it1->extra = gamma_file.toStdString(); } else gamma_file = QString::fromStdString(it1->extra); config::save_2_file(gamma_file, &m_gammaData, sizeof(m_gammaData)); } } } else if(os.opts.size()) { char buf[20]; int ind = 1; bool save_gamma = false; if(os.name.empty()) os.name = os.opts[0].name + "(" + os.opts[0].val + ")"; buf[0] = 0; while(std::find(schemes_->schemes.begin(), schemes_->schemes.end(), os.name + buf) != schemes_->schemes.end()) { sprintf(buf, "-%d", ind++); } os.name += buf; std::vector::iterator it1 = std::find(os.opts.begin(), os.opts.end(), OPTION_TITLE_QYSDQX); save_gamma = it1 != os.opts.end(); if (cur_ind_ >= 0 && cur_ind_ + 1 < (int)schemes_->schemes.size()) { bool overwrite = true, ask = true; std::vector::iterator it2 = std::find(src.opts.begin(), src.opts.end(), OPTION_TITLE_QYSDQX); if(save_gamma && it2 != src.opts.end()) { OPTVAL v1(*it1), v2(*it2); os.opts.erase(it1); src.opts.erase(it2); if(os == src) { v1 = v2; gamma_file = QString::fromStdString(v1.extra); ask = false; } os.opts.push_back(v1); src.opts.push_back(v2); } if(ask) { QString title(tr("save the configuration")); QString text(tr("The Settings you just set are in the original configuration \"")); text += QString::fromStdString(schemes_->schemes[cur_ind_ + 1].name); text += tr("\" changed on the basis,Please select overwrite this configuration or add a new one?\nYes: cover \"") + QString::fromStdString(schemes_->schemes[cur_ind_ + 1].name); text += tr("\"\nNo: add new configuration") + QString::fromStdString(os.name); QMessageBox msg(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::No, this); msg.setButtonText(QMessageBox::Yes, tr("yes")); msg.setButtonText(QMessageBox::No, tr("no")); msg.exec(); overwrite = msg.clickedButton() == msg.button(QMessageBox::Yes); } if (overwrite) { os.name = schemes_->schemes[cur_ind_ + 1].name; schemes_->schemes.erase(schemes_->schemes.begin() + cur_ind_ + 1); } else { gamma_file = ""; cur_ind_ = schemes_->schemes.size() - 1; } } else cur_ind_ = find_covered_scheme(os); // schemes_->schemes.size() - 1; if(save_gamma) { if(gamma_file.length() == 0) gamma_file = gen_gamma_file_path(); config::save_2_file(gamma_file, &m_gammaData, sizeof(m_gammaData)); std::vector::iterator it1 = std::find(os.opts.begin(), os.opts.end(), OPTION_TITLE_QYSDQX); if(it1 != os.opts.end()) it1->extra = gamma_file.toStdString(); } schemes_->schemes.insert(schemes_->schemes.begin() + cur_ind_ + 1, os); schemes_->cur_scheme = cur_ind_; changed_count_++; } else { if(changed_count_ == 0) changed_count_ = schemes_->cur_scheme != -1; schemes_->cur_scheme = -1; // no option has changed, means default setting } } void hg_settingdialog::cancel_setting(void) { // restore changed value ... for(size_t i = 0; i < changed_opts_.size(); ++i) { const SANE_Option_Descriptor* opt = (const SANE_Option_Descriptor*)find_option_description(changed_opts_[i].opt); if(!opt) continue; std::vector::iterator it = std::find(init_vals_.begin(), init_vals_.end(), changed_opts_[i].opt); if(it == init_vals_.end()) continue; SANE_Bool vb = SANE_TRUE; SANE_Int vn = 0, after; SANE_String str = (SANE_String)malloc(opt->size * 2 + 4); void* val = str; bool go = true; //bzero(str, opt->size * 2 + 4); memset(str, 0, opt->size * 2 + 4); if(opt->type == SANE_TYPE_BOOL) { vb = it->val.toBool(); val = &vb; if(changed_opts_[i].val.toBool() == (bool)vb) go = false; } else if(opt->type == SANE_TYPE_INT) { vn = it->val.toInt(); val = &vn; if(changed_opts_[i].val.toInt() == vn) go = false; } else if(opt->type == SANE_TYPE_FIXED) { vn = SANE_FIX(it->val.toDouble()); val = &vn; if(IS_DOUBLE_EQUAL(changed_opts_[i].val.toDouble(), it->val.toDouble())) go = false; } else { if(changed_opts_[i].val.toString() == it->val.toString()) go = false; else strcpy(str, it->val.toString().toStdString().c_str()); val = str; } if(go) sane_control_option(m_handle, changed_opts_[i].opt, SANE_ACTION_SET_VALUE, val, &after); // here need not to check flags in 'after' and update UIs, for this dialog will close ^_^ free(str); } } int hg_settingdialog::find_opt_setting(const char* name, const std::vector& opts) { for(size_t i = 0; i < opts.size(); ++i) { if(opts[i].name.compare(name) == 0) return i; } return -1; } int hg_settingdialog::apply_setting(const SANE_Option_Descriptor* desc, int opt_ind, OPTVAL* val) { SANE_Int after = 0; SANE_Status ret = SANE_STATUS_GOOD; if(desc->type == SANE_TYPE_INT) { SANE_Int v = atoi(val->val.c_str()); ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, &v, &after); if(after & SANE_INFO_INEXACT) { char buf[20]; sprintf(buf, "%d", v); val->val = buf; } } else if(desc->type == SANE_TYPE_BOOL) { SANE_Bool v = val->val == "true"; ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, &v, &after); if(after & SANE_INFO_INEXACT) { val->val = v ? "true" : "false"; } } else if(desc->type == SANE_TYPE_FIXED) { SANE_Fixed v = SANE_FIX(atof(val->val.c_str())); ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, &v, &after); if(after & SANE_INFO_INEXACT) { char buf[20]; double dv = SANE_UNFIX(v); sprintf(buf, "%f", dv); val->val = buf; } } else if(desc->type == SANE_TYPE_STRING) { SANE_String v = (SANE_String)malloc(desc->size); strcpy(v, val->val.c_str()); ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, v, &after); if(after & SANE_INFO_INEXACT) val->val = v; free(v); } return ret; } int hg_settingdialog::apply_settings(OPTSCHEME* scheme) { SANE_Int count = 0, none = 0; none = sane_io_control(m_handle, IO_CTRL_CODE_RESTORE_SETTINGS, NULL, NULL); if(!scheme) return none; sane_control_option(m_handle, 0, SANE_ACTION_GET_VALUE, &count, &none); none = 0; for(int i = 1; i < count; ++i) { const SANE_Option_Descriptor* desc = sane_get_option_descriptor(m_handle, i); if(!desc) continue; if(desc->type == SANE_TYPE_GROUP || desc->type == SANE_TYPE_BUTTON) continue; int opt = find_opt_setting(desc->title, scheme->opts); if(opt == -1) continue; // apply ... none = apply_setting(desc, i, &scheme->opts[opt]); if(none != SANE_STATUS_GOOD) { sane_io_control(m_handle, IO_CTRL_CODE_RESTORE_SETTINGS, NULL, NULL); break; } } return none; } void hg_settingdialog::record_changed_option(int opt, const QVariant& var) { std::vector::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), opt); if(it == changed_opts_.end()) { CHANGEDOPT chg; chg.opt = opt; chg.val = var; changed_opts_.push_back(chg); } else it->val = var; } void hg_settingdialog::on_current_scheme_changed() { QString scheme(comb_->currentText()); std::vector::iterator it = std::find(schemes_->schemes.begin(), schemes_->schemes.end(), scheme.toStdString()); bool enabled = scheme.isEmpty() ? false : it != schemes_->schemes.end(); rename_->setEnabled(enabled); apply_->setEnabled(enabled); del_this_->setEnabled(enabled); del_all_->setEnabled(enabled); int id = enabled ? it - schemes_->schemes.begin() - 1 : -1; QString info(tr("")); if(id >= 0 && id + 1 < (int)schemes_->schemes.size()) { const std::vector& opts = schemes_->schemes[id + 1].opts; for(size_t i = 0; i < opts.size(); ++i) { info += tr("
") + QString::fromStdString(opts[i].name) + tr(":
"); info += tr("

") + QString::fromStdString(opts[i].val) + tr("

"); } } 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 && id + 1 < schemes_->schemes.size()) { Dialog_Input dlg; dlg.init_value(text); dlg.setWindowTitle(QString::fromStdString("\351\205\215\347\275\256\346\226\271\346\241\210\346\224\271\345\220\215")); if(dlg.exec()) { text = dlg.get_inputting_value(); disconnect(comb_, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_current_scheme_changed())); comb_->removeItem(id); comb_->insertItem(id, text); comb_->setCurrentIndex(id); connect(comb_, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_current_scheme_changed())); schemes_->schemes[id + 1].name = text.toStdString(); changed_count_++; } } } else if(btn == apply_) { find_current_scheme_menu(&cur_ind_); on_select_scheme(cur_ind_); changed_count_++; } else if(btn == del_this_) { int id = -1; QString text(find_current_scheme_menu(&id)); if(id < 0 || id + 1 >= schemes_->schemes.size()) { on_current_scheme_changed(); return; } 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.setButtonText(QMessageBox::Yes, tr("yes")); msg.setButtonText(QMessageBox::No, tr("no")); msg.exec(); if (msg.clickedButton() != msg.button(QMessageBox::Yes)) return; OPTSCHEME* s = &schemes_->schemes[id + 1]; for(size_t i = 0; i < s->opts.size(); ++i) { if(s->opts[i].name == OPTION_TITLE_QYSDQX) { SANE_Gamma gmma; if(config::load_custom_gamma(s->opts[i].extra.c_str(), &gmma)) remove(s->opts[i].extra.c_str()); } } comb_->removeItem(id); schemes_->schemes.erase(schemes_->schemes.begin() + id + 1); if(cur_ind_ == id) { cur_ind_ = -1; on_select_scheme(-1); } on_current_scheme_changed(); changed_count_++; } 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.setButtonText(QMessageBox::Yes, tr("yes")); msg.setButtonText(QMessageBox::No, tr("no")); msg.exec(); if (msg.clickedButton() != msg.button(QMessageBox::Yes)) return; for(size_t i = 1; i < schemes_->schemes.size(); ++i) { OPTSCHEME* s = &schemes_->schemes[i]; for(size_t i = 0; i < s->opts.size(); ++i) { if(s->opts[i].name == OPTION_TITLE_QYSDQX) { SANE_Gamma gmma; if(config::load_custom_gamma(s->opts[i].extra.c_str(), &gmma)) remove(s->opts[i].extra.c_str()); } } } schemes_->schemes.erase(schemes_->schemes.begin() + 1, schemes_->schemes.end()); comb_->clear(); cur_ind_ = -1; on_select_scheme(-1); on_current_scheme_changed(); changed_count_++; } }