From 815e90a133f8194c8edf2abed7ccaf5518981435 Mon Sep 17 00:00:00 2001 From: luoliangyi <87842688@qq.com> Date: Mon, 29 Apr 2024 17:29:39 +0800 Subject: [PATCH] =?UTF-8?q?scantool=E8=AE=BE=E5=A4=87=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E6=A1=86=E5=AE=9E=E7=8E=B0=E4=BA=92=E6=96=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/scantool/form_deviceconfig.cpp | 1500 ++++++++++++++++++---------- app/scantool/form_deviceconfig.h | 36 +- app/scantool/mainwindow.cpp | 3 - 3 files changed, 994 insertions(+), 545 deletions(-) diff --git a/app/scantool/form_deviceconfig.cpp b/app/scantool/form_deviceconfig.cpp index 4a12b545..25ba433e 100644 --- a/app/scantool/form_deviceconfig.cpp +++ b/app/scantool/form_deviceconfig.cpp @@ -18,8 +18,7 @@ Form_DeviceConfig::Form_DeviceConfig(SANE_Handle devHandle, const std::vector Form_DeviceConfig::GetDeviceConfigs() { std::vector deviceConfigs; - for (int i = 0; i < (int)m_baseDeviceConfigsGroups.size(); ++i) + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) { - for (int j = 0; j < (int)m_baseDeviceConfigsGroups[i].deviceConfigs.size(); ++j) + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) { - const DeviceConfigEx &deviceConfig = m_baseDeviceConfigsGroups[i].deviceConfigs[j]; + const DeviceConfigEx &deviceConfigEx = m_deviceConfigsGroups[i].deviceConfigs[j]; - QWidget *ctrl = nullptr; - QList widgets = this->findChildren(); - foreach (QWidget* widget, widgets) + bool out = true; + for (int k = 0; k < (int)m_defDeviceConfigs.size(); ++k) { - if (deviceConfig.name == widget->property("config_name").toString().toStdString()) + if (deviceConfigEx.name == m_defDeviceConfigs[k].name + && deviceConfigEx.valueType == m_defDeviceConfigs[k].valueType + && deviceConfigEx.stringValue == m_defDeviceConfigs[k].stringValue + && deviceConfigEx.intValue == m_defDeviceConfigs[k].intValue + && deviceConfigEx.doubleValue == m_defDeviceConfigs[k].doubleValue + && deviceConfigEx.boolValue == m_defDeviceConfigs[k].boolValue) { - ctrl = widget; + out = false; break; } } - if (nullptr != ctrl) + if (out) { - DeviceConfig dc; - dc.name = deviceConfig.name; - dc.valueType = deviceConfig.valueType; - - if (1 == deviceConfig.rangeType) - { - assert(1 == deviceConfig.valueType); - QComboBox *comboBox = (QComboBox *)ctrl; - if (deviceConfig.stringValue != comboBox->currentText().toStdString()) - { - dc.stringValue = comboBox->currentText().toStdString(); - deviceConfigs.push_back(dc); - } - } - else if (2 == deviceConfig.rangeType) - { - assert(2 == deviceConfig.valueType); - QComboBox *comboBox = (QComboBox *)ctrl; - if (deviceConfig.intValue != comboBox->currentText().toInt()) - { - dc.intValue = comboBox->currentText().toInt(); - deviceConfigs.push_back(dc); - } - } - else if (3 == deviceConfig.rangeType) - { - assert(3 == deviceConfig.valueType); - QComboBox *comboBox = (QComboBox *)ctrl; - if (deviceConfig.doubleValue != comboBox->currentText().toDouble()) - { - dc.doubleValue = comboBox->currentText().toDouble(); - deviceConfigs.push_back(dc); - } - } - else if (4 == deviceConfig.rangeType) - { - assert(2 == deviceConfig.valueType); - QSlider *slider = (QSlider *)ctrl; - if (deviceConfig.intValue != slider->value()) - { - dc.intValue = slider->value(); - deviceConfigs.push_back(dc); - } - } - else if (5 == deviceConfig.rangeType) - { - assert(3 == deviceConfig.valueType); - QSlider *slider = (QSlider *)ctrl; - if (round(deviceConfig.doubleValue * 100) != slider->value()) - { - dc.doubleValue = slider->value() / 100.0; - deviceConfigs.push_back(dc); - } - } - else if (0 == deviceConfig.rangeType) - { - if (1 == deviceConfig.valueType) - { - - } - else if (2 == deviceConfig.valueType) - { - QSpinBox* spinBox = (QSpinBox *)ctrl; - if (deviceConfig.intValue != spinBox->value()) - { - dc.intValue = spinBox->value(); - deviceConfigs.push_back(dc); - } - } - else if (3 == deviceConfig.valueType) - { - - } - else if (4 == deviceConfig.valueType) - { - QCheckBox *checkBox = (QCheckBox *)ctrl; - if (deviceConfig.boolValue != checkBox->isChecked()) - { - dc.boolValue = checkBox->isChecked(); - deviceConfigs.push_back(dc); - } - } - } + DeviceConfig deviceConfig; + deviceConfig.name = deviceConfigEx.name; + deviceConfig.valueType = deviceConfigEx.valueType; + deviceConfig.stringValue = deviceConfigEx.stringValue; + deviceConfig.intValue = deviceConfigEx.intValue; + deviceConfig.doubleValue = deviceConfigEx.doubleValue; + deviceConfig.boolValue = deviceConfigEx.boolValue; + deviceConfigs.push_back(deviceConfig); } } } @@ -140,24 +68,9 @@ std::vector Form_DeviceConfig::GetDeviceConfigs() return deviceConfigs; } -bool Form_DeviceConfig::eventFilter(QObject *target, QEvent *event) +void Form_DeviceConfig::Init(const std::vector& deviceConfigs) { - if (typeid(*target) == typeid(QSlider) || typeid(*target) == typeid(QComboBox) || typeid(*target) == typeid(QSpinBox) || - typeid(*target) == typeid(QDoubleSpinBox)) - { - if (event->type() == QEvent::Wheel) - { - return true; - } - } - - return QWidget::eventFilter(target, event); -} - -void Form_DeviceConfig::Init() -{ - // 1.重置设备 - + // 1.恢复默认 SANE_Int num_dev_options = 0; sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL); for (int i = 1; i < num_dev_options; ++i) @@ -177,9 +90,8 @@ void Form_DeviceConfig::Init() } } - // 2.获取基本配置 - - m_baseDeviceConfigsGroups.clear(); + // 2.保存默认配置值 + m_defDeviceConfigs.clear(); for (int i = 1; i < num_dev_options; ++i) { const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i); @@ -190,422 +102,53 @@ void Form_DeviceConfig::Init() while (' ' == *name) ++name; - const char* title = desp->title; - while (' ' == *title) - ++title; - - if (SANE_TYPE_GROUP == desp->type) - { - DeviceConfigsGroup group; - group.groupTitle = title; - m_baseDeviceConfigsGroups.push_back(group); - } - else if (SANE_TYPE_STRING == desp->type) + if (SANE_TYPE_STRING == desp->type) { char value[256] = { 0 }; sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, value, NULL); - DeviceConfigEx devConfig; - devConfig.id = i; - devConfig.name = name; - devConfig.title = title; - devConfig.valueType = 1; - devConfig.stringValue = value; - - devConfig.rangeType = 1; - if (SANE_CONSTRAINT_STRING_LIST == desp->constraint_type) - { - const SANE_String_Const* p = desp->constraint.string_list; - while (NULL != *p) - { - devConfig.stringValueList.push_back(*p); - ++p; - } - - assert(!m_baseDeviceConfigsGroups.empty()); - m_baseDeviceConfigsGroups[m_baseDeviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfig); - } + DeviceConfig deviceConfig; + deviceConfig.name = name; + deviceConfig.valueType = 1; + deviceConfig.stringValue = value; + m_defDeviceConfigs.push_back(deviceConfig); } else if (SANE_TYPE_INT == desp->type) { SANE_Int value = 0; sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); - DeviceConfigEx devConfig; - devConfig.id = i; - devConfig.name = name; - devConfig.title = title; - devConfig.valueType = 2; - devConfig.intValue = (int)value; - - if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type) - { - devConfig.rangeType = 2; - const SANE_Word* p = desp->constraint.word_list; - for (SANE_Int i = 0; i < p[0]; ++i) - { - devConfig.intValueList.push_back(p[i + 1]); - } - } - else if (SANE_CONSTRAINT_RANGE == desp->constraint_type) - { - devConfig.rangeType = 4; - devConfig.intValueMin = desp->constraint.range->min; - devConfig.intValueMax = desp->constraint.range->max; - } - - assert(!m_baseDeviceConfigsGroups.empty()); - m_baseDeviceConfigsGroups[m_baseDeviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfig); + DeviceConfig deviceConfig; + deviceConfig.name = name; + deviceConfig.valueType = 2; + deviceConfig.intValue = (int)value; + m_defDeviceConfigs.push_back(deviceConfig); } else if (SANE_TYPE_FIXED == desp->type) { SANE_Word value = 0; sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); - DeviceConfigEx devConfig; - devConfig.id = i; - devConfig.name = name; - devConfig.title = title; - devConfig.valueType = 3; - devConfig.doubleValue = SANE_UNFIX(value); - - if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type) - { - devConfig.rangeType = 3; - const SANE_Word* p = desp->constraint.word_list; - for (SANE_Int i = 0; i < p[0]; ++i) - { - devConfig.doubleValueList.push_back(SANE_UNFIX(p[i + 1])); - } - } - else if (SANE_CONSTRAINT_RANGE == desp->constraint_type) - { - devConfig.rangeType = 5; - devConfig.doubleValueMin = SANE_UNFIX(desp->constraint.range->min); - devConfig.doubleValueMax = SANE_UNFIX(desp->constraint.range->max); - } - - assert(!m_baseDeviceConfigsGroups.empty()); - m_baseDeviceConfigsGroups[m_baseDeviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfig); + DeviceConfig deviceConfig; + deviceConfig.name = name; + deviceConfig.valueType = 3; + deviceConfig.doubleValue = SANE_UNFIX(value); + m_defDeviceConfigs.push_back(deviceConfig); } else if (SANE_TYPE_BOOL == desp->type) { SANE_Bool value = 0; sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); - DeviceConfigEx devConfig; - devConfig.id = i; - devConfig.name = name; - devConfig.title = title; - devConfig.valueType = 4; - devConfig.boolValue = (bool)value; - - assert(!m_baseDeviceConfigsGroups.empty()); - m_baseDeviceConfigsGroups[m_baseDeviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfig); + DeviceConfig deviceConfig; + deviceConfig.name = name; + deviceConfig.valueType = 4; + deviceConfig.boolValue = (bool)value; + m_defDeviceConfigs.push_back(deviceConfig); } } - // 3.创建UI - - QPushButton *defaultBtn = new QPushButton(tr("Default")); - connect(defaultBtn, &QPushButton::clicked, this, &Form_DeviceConfig::on_defaultBtn_clicked); - QHBoxLayout *hLayout = new QHBoxLayout; - hLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); - hLayout->addWidget(defaultBtn); - QTabWidget *tabWidget = new QTabWidget(this); - tabWidget->setTabPosition(QTabWidget::North); - QVBoxLayout *mainLayout = new QVBoxLayout(this); - mainLayout->addLayout(hLayout); - mainLayout->addWidget(tabWidget); - this->setLayout(mainLayout); - - for (int i = 0; i < (int)m_baseDeviceConfigsGroups.size(); ++i) - { - QWidget *widget = new QWidget; - QFormLayout* layout = new QFormLayout; - widget->setLayout(layout); - - QScrollArea* scrollArea = new QScrollArea(this); - scrollArea->setWidgetResizable(true); - scrollArea->setAlignment(Qt::AlignCenter); - scrollArea->setWindowTitle(QString::fromStdString(m_baseDeviceConfigsGroups[i].groupTitle)); - scrollArea->setWidget(widget); - - for (int j = 0; j < (int)m_baseDeviceConfigsGroups[i].deviceConfigs.size(); ++j) - { - const DeviceConfigEx &deviceConfig = m_baseDeviceConfigsGroups[i].deviceConfigs[j]; - - // 创建Label - QLabel *label = new QLabel; - label->setText(QString::fromStdString(deviceConfig.title) + QString(" : ")); - - // 创建控件 - QWidget *ctrl = nullptr; - QWidget *ctrlWidget = nullptr; - - if (1 == deviceConfig.rangeType) - { - assert(1 == deviceConfig.valueType); - QComboBox *comboBox = new QComboBox; - for (int k = 0; k < (int)deviceConfig.stringValueList.size(); ++k) - comboBox->addItem(QString::fromStdString(deviceConfig.stringValueList[k])); - comboBox->installEventFilter(this); - ctrl = comboBox; - ctrlWidget = comboBox; - } - else if (2 == deviceConfig.rangeType) - { - assert(2 == deviceConfig.valueType); - QComboBox *comboBox = new QComboBox; - for (int k = 0; k < (int)deviceConfig.intValueList.size(); ++k) - comboBox->addItem(QString::number(deviceConfig.intValueList[k])); - comboBox->installEventFilter(this); - ctrl = comboBox; - ctrlWidget = comboBox; - } - else if (3 == deviceConfig.rangeType) - { - assert(3 == deviceConfig.valueType); - QComboBox *comboBox = new QComboBox; - for (int k = 0; k < (int)deviceConfig.doubleValueList.size(); ++k) - comboBox->addItem(QString::number(deviceConfig.doubleValueList[k])); - comboBox->installEventFilter(this); - ctrl = comboBox; - ctrlWidget = comboBox; - } - else if (4 == deviceConfig.rangeType) - { - assert(2 == deviceConfig.valueType); - QSlider *slider = new QSlider; - slider->setOrientation(Qt::Horizontal); - slider->setRange(deviceConfig.intValueMin, deviceConfig.intValueMax); - slider->installEventFilter(this); - connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_sliderClicked(int))); - - QSpinBox* spinBox = new QSpinBox; - spinBox->setMinimumWidth(75); - spinBox->setMaximumWidth(75); - spinBox->setRange(deviceConfig.intValueMin, deviceConfig.intValueMax); - spinBox->installEventFilter(this); - connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxClicked(int))); - - slider->setProperty("relate_ctrl", QVariant::fromValue(spinBox)); - spinBox->setProperty("relate_ctrl", QVariant::fromValue(slider)); - - QHBoxLayout* hLayout = new QHBoxLayout; - hLayout->addWidget(slider); - hLayout->addWidget(spinBox); - QWidget* sliderSpinWidget = new QWidget; - sliderSpinWidget->setLayout(hLayout); - - ctrl = slider; - ctrlWidget = sliderSpinWidget; - } - else if (5 == deviceConfig.rangeType) - { - assert(3 == deviceConfig.valueType); - QSlider *slider = new QSlider; - slider->setOrientation(Qt::Horizontal); - slider->setRange(round(deviceConfig.doubleValueMin * 100), round(deviceConfig.doubleValueMax * 100)); - slider->installEventFilter(this); - connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_sliderClicked(int))); - - QDoubleSpinBox* doubleSpinBox = new QDoubleSpinBox; - doubleSpinBox->setMinimumWidth(75); - doubleSpinBox->setMaximumWidth(75); - doubleSpinBox->setRange(deviceConfig.doubleValueMin, deviceConfig.doubleValueMax); - doubleSpinBox->setDecimals(2); - doubleSpinBox->setSingleStep(0.01); - doubleSpinBox->installEventFilter(this); - connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_doubleSpinboxClicked(double))); - - slider->setProperty("relate_ctrl", QVariant::fromValue(doubleSpinBox)); - doubleSpinBox->setProperty("relate_ctrl", QVariant::fromValue(slider)); - - QHBoxLayout* hLayout = new QHBoxLayout; - hLayout->addWidget(slider); - hLayout->addWidget(doubleSpinBox); - QWidget* sliderSpinWidget = new QWidget; - sliderSpinWidget->setLayout(hLayout); - - ctrl = slider; - ctrlWidget = sliderSpinWidget; - } - else if (0 == deviceConfig.rangeType) - { - if (1 == deviceConfig.valueType) - { - - } - else if (2 == deviceConfig.valueType) - { - QSpinBox* spinBox = new QSpinBox; - spinBox->setMinimumWidth(75); - spinBox->setMaximumWidth(75); - spinBox->setRange(-1, 1000); - spinBox->installEventFilter(this); - ctrl = spinBox; - ctrlWidget = spinBox; - } - else if (3 == deviceConfig.valueType) - { - - } - else if (4 == deviceConfig.valueType) - { - QCheckBox *checkBox = new QCheckBox; - connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_checkedClicked())); - ctrl = checkBox; - ctrlWidget = checkBox; - } - } - - if (nullptr != ctrl) - { - ctrl->setProperty("config_name", QString::fromStdString(deviceConfig.name)); - ctrl->setProperty("config_id", deviceConfig.id); - ctrl->setProperty("ctrl_label", QVariant::fromValue(label)); - ctrl->setProperty("ctrl_widget", QVariant::fromValue(ctrlWidget)); - } - - if (nullptr != ctrlWidget) - { - layout->addRow(label, ctrlWidget); - } - } - - tabWidget->addTab(scrollArea, QString::fromStdString(m_baseDeviceConfigsGroups[i].groupTitle)); - } -} - -void Form_DeviceConfig::Update(const std::vector& deviceConfigs) -{ - // 1.更新UI - - std::vector deviceConfigsGroups = m_baseDeviceConfigsGroups; - for (int i = 0; i < (int)deviceConfigs.size(); ++i) - { - bool set = false; - for (int m = 0; m < (int)deviceConfigsGroups.size(); ++m) - { - for (int n = 0; n < (int)deviceConfigsGroups[m].deviceConfigs.size(); ++n) - { - DeviceConfigEx &deviceConfig = deviceConfigsGroups[m].deviceConfigs[n]; - if (deviceConfig.name == deviceConfigs[i].name && deviceConfig.valueType == deviceConfigs[i].valueType) - { - deviceConfig.stringValue = deviceConfigs[i].stringValue; - deviceConfig.intValue = deviceConfigs[i].intValue; - deviceConfig.doubleValue = deviceConfigs[i].doubleValue; - deviceConfig.boolValue = deviceConfigs[i].boolValue; - set = true; - break; - } - } - - if (set) - { - break; - } - } - } - - for (int i = 0; i < (int)deviceConfigsGroups.size(); ++i) - { - for (int j = 0; j < (int)deviceConfigsGroups[i].deviceConfigs.size(); ++j) - { - const DeviceConfigEx &deviceConfig = deviceConfigsGroups[i].deviceConfigs[j]; - - QWidget *ctrl = nullptr; - QList widgets = this->findChildren(); - foreach (QWidget* widget, widgets) - { - if (deviceConfig.name == widget->property("config_name").toString().toStdString()) - { - ctrl = widget; - break; - } - } - - if (nullptr != ctrl) - { - if (1 == deviceConfig.rangeType) - { - assert(1 == deviceConfig.valueType); - QComboBox *comboBox = (QComboBox *)ctrl; - comboBox->setCurrentText(QString::fromStdString(deviceConfig.stringValue)); - } - else if (2 == deviceConfig.rangeType) - { - assert(2 == deviceConfig.valueType); - QComboBox *comboBox = (QComboBox *)ctrl; - comboBox->setCurrentText(QString::number(deviceConfig.intValue)); - } - else if (3 == deviceConfig.rangeType) - { - assert(3 == deviceConfig.valueType); - QComboBox *comboBox = (QComboBox *)ctrl; - comboBox->setCurrentText(QString::number(deviceConfig.doubleValue)); - } - else if (4 == deviceConfig.rangeType) - { - assert(2 == deviceConfig.valueType); - QSlider *slider = (QSlider *)ctrl; - slider->setValue(deviceConfig.intValue); - } - else if (5 == deviceConfig.rangeType) - { - assert(3 == deviceConfig.valueType); - QSlider *slider = (QSlider *)ctrl; - slider->setValue(round(deviceConfig.doubleValue * 100)); - } - else if (0 == deviceConfig.rangeType) - { - if (1 == deviceConfig.valueType) - { - - } - else if (2 == deviceConfig.valueType) - { - QSpinBox* spinBox = (QSpinBox *)ctrl; - spinBox->setValue(deviceConfig.intValue); - } - else if (3 == deviceConfig.valueType) - { - - } - else if (4 == deviceConfig.valueType) - { - QCheckBox *checkBox = (QCheckBox *)ctrl; - checkBox->setChecked(deviceConfig.boolValue); - } - } - } - } - } - - // 2.恢复默认 - - SANE_Int num_dev_options = 0; - sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL); - for (int i = 1; i < num_dev_options; ++i) - { - const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i); - if (NULL == desp) - continue; - - const char* name = desp->name; - while (' ' == *name) - ++name; - - if (0 == strcmp(SANE_STD_OPT_NAME_RESTORE, name) && SANE_TYPE_BUTTON == desp->type) - { - sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, NULL, NULL); - break; - } - } - - // 3.设置新的属性 - + // 3.设置新配置 for (int i = 0; i < (int)deviceConfigs.size(); ++i) { for (int j = 1; j < num_dev_options; ++j) @@ -645,11 +188,600 @@ void Form_DeviceConfig::Update(const std::vector& deviceConfigs) } } - UpdateControls(); + // 4.更新当前配置信息 + m_deviceConfigsGroups.clear(); + for (int i = 1; i < num_dev_options; ++i) + { + const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i); + if (NULL == desp) + continue; + + const char* name = desp->name; + while (' ' == *name) + ++name; + + const char* title = desp->title; + while (' ' == *title) + ++title; + + if (SANE_TYPE_GROUP == desp->type) + { + DeviceConfigsGroup group; + group.groupTitle = title; + m_deviceConfigsGroups.push_back(group); + } + else if (SANE_TYPE_STRING == desp->type) + { + char value[256] = { 0 }; + sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, value, NULL); + + DeviceConfigEx devConfigEx; + devConfigEx.id = i; + devConfigEx.name = name; + devConfigEx.title = title; + devConfigEx.valueType = 1; + devConfigEx.stringValue = value; + + if (SANE_CONSTRAINT_STRING_LIST == desp->constraint_type) + { + devConfigEx.rangeType = 1; + const SANE_String_Const* p = desp->constraint.string_list; + while (NULL != *p) + { + devConfigEx.stringValueList.push_back(*p); + ++p; + } + } + + assert(!m_deviceConfigsGroups.empty()); + m_deviceConfigsGroups[m_deviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfigEx); + } + else if (SANE_TYPE_INT == desp->type) + { + SANE_Int value = 0; + sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); + + DeviceConfigEx devConfigEx; + devConfigEx.id = i; + devConfigEx.name = name; + devConfigEx.title = title; + devConfigEx.valueType = 2; + devConfigEx.intValue = (int)value; + + if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type) + { + devConfigEx.rangeType = 2; + const SANE_Word* p = desp->constraint.word_list; + for (SANE_Int i = 0; i < p[0]; ++i) + { + devConfigEx.intValueList.push_back(p[i + 1]); + } + } + else if (SANE_CONSTRAINT_RANGE == desp->constraint_type) + { + devConfigEx.rangeType = 4; + devConfigEx.intValueMin = desp->constraint.range->min; + devConfigEx.intValueMax = desp->constraint.range->max; + } + + assert(!m_deviceConfigsGroups.empty()); + m_deviceConfigsGroups[m_deviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfigEx); + } + else if (SANE_TYPE_FIXED == desp->type) + { + SANE_Word value = 0; + sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); + + DeviceConfigEx devConfigEx; + devConfigEx.id = i; + devConfigEx.name = name; + devConfigEx.title = title; + devConfigEx.valueType = 3; + devConfigEx.doubleValue = SANE_UNFIX(value); + + if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type) + { + devConfigEx.rangeType = 3; + const SANE_Word* p = desp->constraint.word_list; + for (SANE_Int i = 0; i < p[0]; ++i) + { + devConfigEx.doubleValueList.push_back(SANE_UNFIX(p[i + 1])); + } + } + else if (SANE_CONSTRAINT_RANGE == desp->constraint_type) + { + devConfigEx.rangeType = 5; + devConfigEx.doubleValueMin = SANE_UNFIX(desp->constraint.range->min); + devConfigEx.doubleValueMax = SANE_UNFIX(desp->constraint.range->max); + } + + assert(!m_deviceConfigsGroups.empty()); + m_deviceConfigsGroups[m_deviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfigEx); + } + else if (SANE_TYPE_BOOL == desp->type) + { + SANE_Bool value = 0; + sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); + + DeviceConfigEx devConfigEx; + devConfigEx.id = i; + devConfigEx.name = name; + devConfigEx.title = title; + devConfigEx.valueType = 4; + devConfigEx.boolValue = (bool)value; + + assert(!m_deviceConfigsGroups.empty()); + m_deviceConfigsGroups[m_deviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfigEx); + } + } + + // 5.创建UI + QPushButton *defaultBtn = new QPushButton(tr("Default")); + connect(defaultBtn, &QPushButton::clicked, this, &Form_DeviceConfig::on_defaultBtn_clicked); + QHBoxLayout *hLayout = new QHBoxLayout; + hLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); + hLayout->addWidget(defaultBtn); + QTabWidget *tabWidget = new QTabWidget(this); + tabWidget->setTabPosition(QTabWidget::North); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->addLayout(hLayout); + mainLayout->addWidget(tabWidget); + this->setLayout(mainLayout); + + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + QWidget *widget = new QWidget; + QFormLayout* layout = new QFormLayout; + widget->setLayout(layout); + + QScrollArea* scrollArea = new QScrollArea(this); + scrollArea->setWidgetResizable(true); + scrollArea->setAlignment(Qt::AlignCenter); + scrollArea->setWindowTitle(QString::fromStdString(m_deviceConfigsGroups[i].groupTitle)); + scrollArea->setWidget(widget); + + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + DeviceConfigEx &deviceConfigEx = m_deviceConfigsGroups[i].deviceConfigs[j]; + + // 创建Label + QLabel *label = new QLabel; + label->setText(QString::fromStdString(deviceConfigEx.title) + QString(" : ")); + + // 创建控件 + QWidget *ctrl = nullptr; + QWidget *ctrlWidget = nullptr; + + if (1 == deviceConfigEx.rangeType) + { + assert(1 == deviceConfigEx.valueType); + QComboBox *comboBox = new QComboBox; + for (int k = 0; k < (int)deviceConfigEx.stringValueList.size(); ++k) + comboBox->addItem(QString::fromStdString(deviceConfigEx.stringValueList[k])); + comboBox->setCurrentText(QString::fromStdString(deviceConfigEx.stringValue)); + comboBox->installEventFilter(this); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_list_comboBoxClicked())); + + ctrl = comboBox; + ctrlWidget = comboBox; + } + else if (2 == deviceConfigEx.rangeType) + { + assert(2 == deviceConfigEx.valueType); + QComboBox *comboBox = new QComboBox; + for (int k = 0; k < (int)deviceConfigEx.intValueList.size(); ++k) + comboBox->addItem(QString::number(deviceConfigEx.intValueList[k])); + comboBox->setCurrentText(QString::number(deviceConfigEx.intValue)); + comboBox->installEventFilter(this); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_int_list_comboBoxClicked())); + + ctrl = comboBox; + ctrlWidget = comboBox; + } + else if (3 == deviceConfigEx.rangeType) + { + assert(3 == deviceConfigEx.valueType); + QComboBox *comboBox = new QComboBox; + for (int k = 0; k < (int)deviceConfigEx.doubleValueList.size(); ++k) + comboBox->addItem(QString::number(deviceConfigEx.doubleValueList[k])); + comboBox->setCurrentText(QString::number(deviceConfigEx.doubleValue)); + comboBox->installEventFilter(this); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_double_list_comboBoxClicked())); + + ctrl = comboBox; + ctrlWidget = comboBox; + } + else if (4 == deviceConfigEx.rangeType) + { + assert(2 == deviceConfigEx.valueType); + QSlider *slider = new QSlider; + slider->setOrientation(Qt::Horizontal); + slider->setRange(deviceConfigEx.intValueMin, deviceConfigEx.intValueMax); + slider->setValue(deviceConfigEx.intValue); + slider->installEventFilter(this); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_int_sliderClicked(int))); + + QSpinBox* spinBox = new QSpinBox; + spinBox->setMinimumWidth(75); + spinBox->setMaximumWidth(75); + spinBox->setRange(deviceConfigEx.intValueMin, deviceConfigEx.intValueMax); + spinBox->setValue(deviceConfigEx.intValue); + spinBox->installEventFilter(this); + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_relate_spinBoxClicked(int))); + + slider->setProperty("relate_ctrl", QVariant::fromValue(spinBox)); + spinBox->setProperty("relate_ctrl", QVariant::fromValue(slider)); + + QHBoxLayout* hLayout = new QHBoxLayout; + hLayout->addWidget(slider); + hLayout->addWidget(spinBox); + QWidget* sliderSpinWidget = new QWidget; + sliderSpinWidget->setLayout(hLayout); + + ctrl = slider; + ctrlWidget = sliderSpinWidget; + } + else if (5 == deviceConfigEx.rangeType) + { + assert(3 == deviceConfigEx.valueType); + QSlider *slider = new QSlider; + slider->setOrientation(Qt::Horizontal); + slider->setRange(round(deviceConfigEx.doubleValueMin * 100), round(deviceConfigEx.doubleValueMax * 100)); + slider->setValue(round(deviceConfigEx.doubleValue * 100)); + slider->installEventFilter(this); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_double_sliderClicked(int))); + + QDoubleSpinBox* doubleSpinBox = new QDoubleSpinBox; + doubleSpinBox->setMinimumWidth(75); + doubleSpinBox->setMaximumWidth(75); + doubleSpinBox->setRange(deviceConfigEx.doubleValueMin, deviceConfigEx.doubleValueMax); + doubleSpinBox->setDecimals(2); + doubleSpinBox->setSingleStep(0.01); + doubleSpinBox->setValue(deviceConfigEx.doubleValue); + doubleSpinBox->installEventFilter(this); + connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_relate_doubleSpinboxClicked(double))); + + slider->setProperty("relate_ctrl", QVariant::fromValue(doubleSpinBox)); + doubleSpinBox->setProperty("relate_ctrl", QVariant::fromValue(slider)); + + QHBoxLayout* hLayout = new QHBoxLayout; + hLayout->addWidget(slider); + hLayout->addWidget(doubleSpinBox); + QWidget* sliderSpinWidget = new QWidget; + sliderSpinWidget->setLayout(hLayout); + + ctrl = slider; + ctrlWidget = sliderSpinWidget; + } + else if (0 == deviceConfigEx.rangeType) + { + if (1 == deviceConfigEx.valueType) + { + QComboBox *comboBox = new QComboBox; + comboBox->addItem(QString::fromStdString(deviceConfigEx.stringValue)); + comboBox->setCurrentText(QString::fromStdString(deviceConfigEx.stringValue)); + comboBox->installEventFilter(this); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_comboBoxClicked())); + + ctrl = comboBox; + ctrlWidget = comboBox; + } + else if (2 == deviceConfigEx.valueType) + { + QSpinBox* spinBox = new QSpinBox; + spinBox->setMinimumWidth(75); + spinBox->setMaximumWidth(75); + spinBox->setRange(-1, 1000); + spinBox->setValue(deviceConfigEx.intValue); + spinBox->installEventFilter(this); + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxClicked(int))); + + ctrl = spinBox; + ctrlWidget = spinBox; + } + else if (3 == deviceConfigEx.valueType) + { + + } + else if (4 == deviceConfigEx.valueType) + { + QCheckBox *checkBox = new QCheckBox; + checkBox->setChecked(deviceConfigEx.boolValue); + connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_checkedClicked())); + + ctrl = checkBox; + ctrlWidget = checkBox; + } + } + + ctrl->setProperty("config_id", deviceConfigEx.id); + deviceConfigEx.label = label; + deviceConfigEx.ctrl = ctrl; + deviceConfigEx.ctrlWidget = ctrlWidget; + layout->addRow(label, ctrlWidget); + } + + tabWidget->addTab(scrollArea, QString::fromStdString(m_deviceConfigsGroups[i].groupTitle)); + } + + // 6.更新控件显示状态 + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + const DeviceConfigEx &deviceConfigEx = m_deviceConfigsGroups[i].deviceConfigs[j]; + const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, deviceConfigEx.id); + bool hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); + deviceConfigEx.label->setVisible(!hide); + deviceConfigEx.ctrlWidget->setVisible(!hide); + } + } } -void Form_DeviceConfig::UpdateControls() +void Form_DeviceConfig::Update(int ignoreId) { + // 1.更新当前配置信息 + SANE_Int num_dev_options = 0; + sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL); + for (int k = 1; k < num_dev_options; ++k) + { + const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, k); + if (NULL == desp) + continue; + + if (k == ignoreId) + continue; + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == k) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } + } + } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->valueType = 0; + pDeviceConfigEx->stringValue.clear(); + pDeviceConfigEx->intValue = 0; + pDeviceConfigEx->doubleValue = 0; + pDeviceConfigEx->boolValue = false; + + pDeviceConfigEx->rangeType = 0; + pDeviceConfigEx->stringValueList.clear(); + pDeviceConfigEx->intValueList.clear(); + pDeviceConfigEx->doubleValueList.clear(); + pDeviceConfigEx->intValueMin = 0; + pDeviceConfigEx->intValueMax = 0; + pDeviceConfigEx->doubleValueMin = 0; + pDeviceConfigEx->doubleValueMax = 0; + } + + if (SANE_TYPE_STRING == desp->type) + { + char value[256] = { 0 }; + sane_control_option(m_devHandle, k, SANE_ACTION_GET_VALUE, value, NULL); + + assert(nullptr != pDeviceConfigEx); + pDeviceConfigEx->valueType = 1; + pDeviceConfigEx->stringValue = value; + + if (SANE_CONSTRAINT_STRING_LIST == desp->constraint_type) + { + pDeviceConfigEx->rangeType = 1; + const SANE_String_Const* p = desp->constraint.string_list; + while (NULL != *p) + { + pDeviceConfigEx->stringValueList.push_back(*p); + ++p; + } + } + } + else if (SANE_TYPE_INT == desp->type) + { + SANE_Int value = 0; + sane_control_option(m_devHandle, k, SANE_ACTION_GET_VALUE, &value, NULL); + + assert(nullptr != pDeviceConfigEx); + pDeviceConfigEx->valueType = 2; + pDeviceConfigEx->intValue = (int)value; + + if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type) + { + pDeviceConfigEx->rangeType = 2; + const SANE_Word* p = desp->constraint.word_list; + for (SANE_Int i = 0; i < p[0]; ++i) + { + pDeviceConfigEx->intValueList.push_back(p[i + 1]); + } + } + else if (SANE_CONSTRAINT_RANGE == desp->constraint_type) + { + pDeviceConfigEx->rangeType = 4; + pDeviceConfigEx->intValueMin = desp->constraint.range->min; + pDeviceConfigEx->intValueMax = desp->constraint.range->max; + } + } + else if (SANE_TYPE_FIXED == desp->type) + { + SANE_Word value = 0; + sane_control_option(m_devHandle, k, SANE_ACTION_GET_VALUE, &value, NULL); + + assert(nullptr != pDeviceConfigEx); + pDeviceConfigEx->valueType = 3; + pDeviceConfigEx->doubleValue = SANE_UNFIX(value); + + if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type) + { + pDeviceConfigEx->rangeType = 3; + const SANE_Word* p = desp->constraint.word_list; + for (SANE_Int i = 0; i < p[0]; ++i) + { + pDeviceConfigEx->doubleValueList.push_back(SANE_UNFIX(p[i + 1])); + } + } + else if (SANE_CONSTRAINT_RANGE == desp->constraint_type) + { + pDeviceConfigEx->rangeType = 5; + pDeviceConfigEx->doubleValueMin = SANE_UNFIX(desp->constraint.range->min); + pDeviceConfigEx->doubleValueMax = SANE_UNFIX(desp->constraint.range->max); + } + } + else if (SANE_TYPE_BOOL == desp->type) + { + SANE_Bool value = 0; + sane_control_option(m_devHandle, k, SANE_ACTION_GET_VALUE, &value, NULL); + + assert(nullptr != pDeviceConfigEx); + pDeviceConfigEx->valueType = 4; + pDeviceConfigEx->boolValue = (bool)value; + + assert(SANE_CONSTRAINT_NONE == desp->constraint_type); + } + } + + // 2.更新UI + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + const DeviceConfigEx &deviceConfigEx = m_deviceConfigsGroups[i].deviceConfigs[j]; + if (deviceConfigEx.id == ignoreId) + continue; + + if (1 == deviceConfigEx.rangeType) + { + assert(1 == deviceConfigEx.valueType); + QComboBox *comboBox = (QComboBox *)deviceConfigEx.ctrl; + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_list_comboBoxClicked())); + comboBox->clear(); + for (int k = 0; k < (int)deviceConfigEx.stringValueList.size(); ++k) + comboBox->addItem(QString::fromStdString(deviceConfigEx.stringValueList[k])); + comboBox->setCurrentText(QString::fromStdString(deviceConfigEx.stringValue)); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_list_comboBoxClicked())); + } + else if (2 == deviceConfigEx.rangeType) + { + assert(2 == deviceConfigEx.valueType); + QComboBox *comboBox = (QComboBox *)deviceConfigEx.ctrl; + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_int_list_comboBoxClicked())); + comboBox->clear(); + for (int k = 0; k < (int)deviceConfigEx.intValueList.size(); ++k) + comboBox->addItem(QString::number(deviceConfigEx.intValueList[k])); + comboBox->setCurrentText(QString::number(deviceConfigEx.intValue)); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_int_list_comboBoxClicked())); + } + else if (3 == deviceConfigEx.rangeType) + { + assert(3 == deviceConfigEx.valueType); + QComboBox *comboBox = (QComboBox *)deviceConfigEx.ctrl; + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_double_list_comboBoxClicked())); + comboBox->clear(); + for (int k = 0; k < (int)deviceConfigEx.doubleValueList.size(); ++k) + comboBox->addItem(QString::number(deviceConfigEx.doubleValueList[k])); + comboBox->setCurrentText(QString::number(deviceConfigEx.doubleValue)); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_double_list_comboBoxClicked())); + } + else if (4 == deviceConfigEx.rangeType) + { + assert(2 == deviceConfigEx.valueType); + QSlider *slider = (QSlider*)deviceConfigEx.ctrl; + QSpinBox* spinBox = qvariant_cast(slider->property("relate_ctrl")); + disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_int_sliderClicked(int))); + disconnect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_relate_spinBoxClicked(int))); + slider->setRange(deviceConfigEx.intValueMin, deviceConfigEx.intValueMax); + slider->setValue(deviceConfigEx.intValue); + spinBox->setRange(deviceConfigEx.intValueMin, deviceConfigEx.intValueMax); + spinBox->setValue(deviceConfigEx.intValue); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_int_sliderClicked(int))); + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_relate_spinBoxClicked(int))); + } + else if (5 == deviceConfigEx.rangeType) + { + assert(3 == deviceConfigEx.valueType); + QSlider *slider = (QSlider*)deviceConfigEx.ctrl; + QDoubleSpinBox* doubleSpinBox = qvariant_cast(slider->property("relate_ctrl")); + disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_double_sliderClicked(int))); + disconnect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_relate_doubleSpinboxClicked(double))); + slider->setRange(round(deviceConfigEx.doubleValueMin * 100), round(deviceConfigEx.doubleValueMax * 100)); + slider->setValue(round(deviceConfigEx.doubleValue * 100)); + doubleSpinBox->setRange(deviceConfigEx.doubleValueMin, deviceConfigEx.doubleValueMax); + doubleSpinBox->setValue(deviceConfigEx.doubleValue); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_double_sliderClicked(int))); + connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_relate_doubleSpinboxClicked(double))); + } + else if (0 == deviceConfigEx.rangeType) + { + if (1 == deviceConfigEx.valueType) + { + QComboBox *comboBox = (QComboBox*)deviceConfigEx.ctrl; + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_comboBoxClicked())); + comboBox->clear(); + comboBox->addItem(QString::fromStdString(deviceConfigEx.stringValue)); + comboBox->setCurrentText(QString::fromStdString(deviceConfigEx.stringValue)); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_comboBoxClicked())); + } + else if (2 == deviceConfigEx.valueType) + { + QSpinBox* spinBox = (QSpinBox*)deviceConfigEx.ctrl; + disconnect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxClicked(int))); + spinBox->setValue(deviceConfigEx.intValue); + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxClicked(int))); + } + else if (3 == deviceConfigEx.valueType) + { + + } + else if (4 == deviceConfigEx.valueType) + { + QCheckBox *checkBox = (QCheckBox*)deviceConfigEx.ctrl; + disconnect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_checkedClicked())); + checkBox->setChecked(deviceConfigEx.boolValue); + connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_checkedClicked())); + } + } + } + } + + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + const DeviceConfigEx &deviceConfigEx = m_deviceConfigsGroups[i].deviceConfigs[j]; + if (deviceConfigEx.id == ignoreId) + continue; + + const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, deviceConfigEx.id); + bool hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); + deviceConfigEx.label->setVisible(!hide); + deviceConfigEx.ctrlWidget->setVisible(!hide); + } + } +} + +bool Form_DeviceConfig::eventFilter(QObject *target, QEvent *event) +{ + if (typeid(*target) == typeid(QSlider) || typeid(*target) == typeid(QComboBox) || typeid(*target) == typeid(QSpinBox) || + typeid(*target) == typeid(QDoubleSpinBox)) + { + if (event->type() == QEvent::Wheel) + { + return true; + } + } + + return QWidget::eventFilter(target, event); +} + +void Form_DeviceConfig::on_defaultBtn_clicked() +{ + // 1.恢复默认 SANE_Int num_dev_options = 0; sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL); for (int i = 1; i < num_dev_options; ++i) @@ -662,66 +794,346 @@ void Form_DeviceConfig::UpdateControls() while (' ' == *name) ++name; - QWidget *ctrl = nullptr; - QList widgets = this->findChildren(); - foreach (QWidget* widget, widgets) + if (0 == strcmp(SANE_STD_OPT_NAME_RESTORE, name) && SANE_TYPE_BUTTON == desp->type) { - if (widget->property("config_name").toString().toStdString() == name) + sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, NULL, NULL); + break; + } + } + + // 2.更新UI + Update(-1); +} + +void Form_DeviceConfig::on_string_list_comboBoxClicked() +{ + QComboBox *comboBox = qobject_cast(sender()); + std::string currentText = comboBox->currentText().toUtf8(); + SANE_Int id = comboBox->property("config_id").toInt(); + + SANE_Int method = 0; + SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, (void *)currentText.c_str(), &method); + if (ret == SANE_STATUS_UNSUPPORTED) + { + SANE_Char v[256] = {0}; + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &v, &method); + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_list_comboBoxClicked())); + comboBox->setCurrentText(QString::fromUtf8(v)); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_list_comboBoxClicked())); + QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); + return; + } + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) { - ctrl = widget; + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; break; } } + } - if (nullptr != ctrl) + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->stringValue = currentText; + } + + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) + { + Update(id); + } +} + +void Form_DeviceConfig::on_int_list_comboBoxClicked() +{ + QComboBox *comboBox = qobject_cast(sender()); + SANE_Int currentValue = comboBox->currentText().toInt(); + SANE_Int id = comboBox->property("config_id").toInt(); + + SANE_Int method = 0; + SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, ¤tValue, &method); + if (ret == SANE_STATUS_UNSUPPORTED) + { + SANE_Int v = 0; + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &v, &method); + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_int_list_comboBoxClicked())); + comboBox->setCurrentText(QString::number(v)); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_int_list_comboBoxClicked())); + QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); + return; + } + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) { - QWidget *label = qvariant_cast(ctrl->property("ctrl_label")); - QWidget *ctrlWidget = qvariant_cast(ctrl->property("ctrl_widget")); - - bool hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); - label->setVisible(!hide); - ctrlWidget->setVisible(!hide);; + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } } } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->intValue = currentValue; + } + + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) + { + Update(id); + } } -void Form_DeviceConfig::on_defaultBtn_clicked() +void Form_DeviceConfig::on_double_list_comboBoxClicked() { - std::vector deviceConfigs; - Update(deviceConfigs); + QComboBox *comboBox = qobject_cast(sender()); + SANE_Word currentValue = SANE_FIX(comboBox->currentText().toDouble()); + SANE_Int id = comboBox->property("config_id").toInt(); + + SANE_Int method = 0; + SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, ¤tValue, &method); + if (ret == SANE_STATUS_UNSUPPORTED) + { + SANE_Word v = 0; + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &v, &method); + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_double_list_comboBoxClicked())); + comboBox->setCurrentText(QString::number(SANE_UNFIX(v))); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_double_list_comboBoxClicked())); + QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); + return; + } + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } + } + } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->doubleValue = comboBox->currentText().toDouble(); + } + + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) + { + Update(id); + } } -void Form_DeviceConfig::on_sliderClicked(int value) +void Form_DeviceConfig::on_int_sliderClicked(int value) { QSlider *slider = qobject_cast(sender()); - QWidget* ctrl = qvariant_cast(slider->property("relate_ctrl")); - if (typeid(*ctrl) == typeid(QSpinBox)) + SANE_Int currentValue = value; + SANE_Int id = slider->property("config_id").toInt(); + QSpinBox* spinBox = qvariant_cast(slider->property("relate_ctrl")); + disconnect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_relate_spinBoxClicked(int))); + spinBox->setValue(value); + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_relate_spinBoxClicked(int))); + + SANE_Int method = 0; + SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, ¤tValue, &method); + if (ret == SANE_STATUS_UNSUPPORTED) { - QSpinBox* spinBox = reinterpret_cast(ctrl); - spinBox->setValue(value); + SANE_Int v = 0; + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &v, &method); + disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_int_sliderClicked(int))); + disconnect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_relate_spinBoxClicked(int))); + slider->setValue(v); + spinBox->setValue(v); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_int_sliderClicked(int))); + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_relate_spinBoxClicked(int))); + QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); + return; } - else + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) { - assert(typeid(*ctrl) == typeid(QDoubleSpinBox)); - QDoubleSpinBox* doubleSpinBox = reinterpret_cast(ctrl); - doubleSpinBox->setValue(value / 100.0); + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } + } + } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->intValue = currentValue; + } + + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) + { + Update(id); } } -void Form_DeviceConfig::on_spinBoxClicked(int value) +void Form_DeviceConfig::on_double_sliderClicked(int value) +{ + QSlider *slider = qobject_cast(sender()); + SANE_Word currentValue = SANE_FIX(value / 100.0); + SANE_Int id = slider->property("config_id").toInt(); + QDoubleSpinBox* doubleSpinBox = qvariant_cast(slider->property("relate_ctrl")); + disconnect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_relate_doubleSpinboxClicked(double))); + doubleSpinBox->setValue(value / 100.0); + connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_relate_doubleSpinboxClicked(double))); + + SANE_Int method = 0; + SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, ¤tValue, &method); + if (ret == SANE_STATUS_UNSUPPORTED) + { + SANE_Word v = 0; + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &v, &method); + disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_double_sliderClicked(int))); + disconnect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_relate_doubleSpinboxClicked(double))); + slider->setValue(round(SANE_UNFIX(v) * 100)); + doubleSpinBox->setValue(SANE_UNFIX(v)); + connect(slider, SIGNAL(valueChanged(int)), this, SLOT(on_double_sliderClicked(int))); + connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_relate_doubleSpinboxClicked(double))); + QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); + return; + } + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } + } + } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->doubleValue = value / 100.0; + } + + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) + { + Update(id); + } +} + +void Form_DeviceConfig::on_relate_spinBoxClicked(int value) { QSpinBox* spinBox = qobject_cast(sender()); QSlider* slider = qvariant_cast(spinBox->property("relate_ctrl")); slider->setValue(value); } -void Form_DeviceConfig::on_doubleSpinboxClicked(double value) +void Form_DeviceConfig::on_relate_doubleSpinboxClicked(double value) { QDoubleSpinBox* doubleSpinBox = qobject_cast(sender()); QSlider* slider = qvariant_cast(doubleSpinBox->property("relate_ctrl")); slider->setValue(round(value * 100)); } +void Form_DeviceConfig::on_string_comboBoxClicked() +{ + QComboBox *comboBox = qobject_cast(sender()); + std::string currentText = comboBox->currentText().toUtf8(); + SANE_Int id = comboBox->property("config_id").toInt(); + + SANE_Int method = 0; + SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, (void *)currentText.c_str(), &method); + if (ret == SANE_STATUS_UNSUPPORTED) + { + SANE_Char v[256] = {0}; + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &v, &method); + disconnect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_comboBoxClicked())); + comboBox->setCurrentText(QString::fromUtf8(v)); + connect(comboBox, SIGNAL(currentTextChanged(const QString)), this, SLOT(on_string_comboBoxClicked())); + QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); + return; + } + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } + } + } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->stringValue = currentText; + } + + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) + { + Update(id); + } +} + +void Form_DeviceConfig::on_spinBoxClicked(int value) +{ + QSpinBox* spinBox = qobject_cast(sender()); + SANE_Int currentValue = value; + SANE_Int id = spinBox->property("config_id").toInt(); + + SANE_Int method = 0; + SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, ¤tValue, &method); + if (ret == SANE_STATUS_UNSUPPORTED) + { + SANE_Int v = 0; + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &v, &method); + disconnect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxClicked(int))); + spinBox->setValue(v); + connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxClicked(int))); + QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); + return; + } + + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } + } + } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->intValue = currentValue; + } + + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) + { + Update(id); + } +} + void Form_DeviceConfig::on_checkedClicked() { QCheckBox *checkBox = qobject_cast(sender()); @@ -733,7 +1145,7 @@ void Form_DeviceConfig::on_checkedClicked() if (ret == SANE_STATUS_UNSUPPORTED) { SANE_Bool value = false; - ret = sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &value, &method); + sane_control_option(m_devHandle, id, SANE_ACTION_GET_VALUE, &value, &method); disconnect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_checkedClicked())); checkBox->setCheckState(value ? Qt::Checked : Qt::Unchecked); connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_checkedClicked())); @@ -741,8 +1153,26 @@ void Form_DeviceConfig::on_checkedClicked() return; } + DeviceConfigEx *pDeviceConfigEx = nullptr; + for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i) + { + for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j) + { + if (m_deviceConfigsGroups[i].deviceConfigs[j].id == id) + { + pDeviceConfigEx = &m_deviceConfigsGroups[i].deviceConfigs[j]; + break; + } + } + } + + if (nullptr != pDeviceConfigEx) + { + pDeviceConfigEx->boolValue = currentState; + } + if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) { - UpdateControls(); + Update(id); } } diff --git a/app/scantool/form_deviceconfig.h b/app/scantool/form_deviceconfig.h index 5d320089..b9f67959 100644 --- a/app/scantool/form_deviceconfig.h +++ b/app/scantool/form_deviceconfig.h @@ -30,18 +30,33 @@ struct DeviceConfigEx { DeviceConfigEx() { + label = nullptr; + ctrl = nullptr; + ctrlWidget = nullptr; + id = -1; + name.clear(); + title.clear(); + valueType = 0; + stringValue.clear(); intValue = 0; doubleValue = 0; boolValue = false; rangeType = 0; + stringValueList.clear(); + intValueList.clear(); + doubleValueList.clear(); intValueMin = 0; intValueMax = 0; doubleValueMin = 0; doubleValueMax = 0; } + // 控件 + QWidget *label; + QWidget *ctrl; + QWidget *ctrlWidget; // 配置名 int id; std::string name; @@ -82,22 +97,29 @@ public: std::vector GetDeviceConfigs(); private: - virtual bool eventFilter(QObject *target, QEvent *event) override; + void Init(const std::vector& deviceConfigs); + void Update(int ignoreId); - void Init(); - void Update(const std::vector& deviceConfigs); - void UpdateControls(); +protected: + virtual bool eventFilter(QObject *target, QEvent *event) override; private slots: void on_defaultBtn_clicked(); - void on_sliderClicked(int value); + void on_string_list_comboBoxClicked(); + void on_int_list_comboBoxClicked(); + void on_double_list_comboBoxClicked(); + void on_int_sliderClicked(int value); + void on_double_sliderClicked(int value); + void on_relate_spinBoxClicked(int value); + void on_relate_doubleSpinboxClicked(double value); + void on_string_comboBoxClicked(); void on_spinBoxClicked(int value); - void on_doubleSpinboxClicked(double value); void on_checkedClicked(); private: SANE_Handle m_devHandle; - std::vector m_baseDeviceConfigsGroups; + std::vector m_defDeviceConfigs; // 默认配置值 + std::vector m_deviceConfigsGroups; // 当前配置信息 }; #endif // FORM_DEVICECONFIG_H diff --git a/app/scantool/mainwindow.cpp b/app/scantool/mainwindow.cpp index 709ae999..9676a6d6 100644 --- a/app/scantool/mainwindow.cpp +++ b/app/scantool/mainwindow.cpp @@ -231,7 +231,6 @@ void MainWindow::StartScan(unsigned int buttonId) } // 1.恢复默认 - SANE_Int num_dev_options = 0; sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL); for (int i = 1; i < num_dev_options; ++i) @@ -252,7 +251,6 @@ void MainWindow::StartScan(unsigned int buttonId) } // 2.设置新的属性 - for (int i = 0; i < (int)scanParam.deviceConfigs.size(); ++i) { for (int j = 1; j < num_dev_options; ++j) @@ -293,7 +291,6 @@ void MainWindow::StartScan(unsigned int buttonId) } // 3. 获取DPI - for (int i = 1; i < num_dev_options; ++i) { const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);