#include "form_deviceconfig.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include Form_DeviceConfig::Form_DeviceConfig(SANE_Handle devHandle, const std::vector& deviceConfigs, QWidget *parent) : QWidget(parent) , m_devHandle(devHandle) , m_defButtonId(-1) { Init(deviceConfigs); } Form_DeviceConfig::~Form_DeviceConfig() { } std::vector Form_DeviceConfig::GetDeviceConfigs() { std::vector deviceConfigs; 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]; DeviceConfig deviceConfig; deviceConfig.name = deviceConfigEx.name; deviceConfig.valueType = deviceConfigEx.valueType; if (1 == deviceConfigEx.valueType && deviceConfigEx.stringValue != deviceConfigEx.defStringValue) { deviceConfig.stringValue = deviceConfigEx.stringValue; deviceConfigs.push_back(deviceConfig); } else if (2 == deviceConfigEx.valueType && deviceConfigEx.intValue != deviceConfigEx.defIntValue) { deviceConfig.intValue = deviceConfigEx.intValue; deviceConfigs.push_back(deviceConfig); } else if (3 == deviceConfigEx.valueType && deviceConfigEx.doubleValue != deviceConfigEx.defDoubleValue) { deviceConfig.doubleValue = deviceConfigEx.doubleValue; deviceConfigs.push_back(deviceConfig); } else if (4 == deviceConfigEx.valueType && deviceConfigEx.boolValue != deviceConfigEx.defBoolValue) { deviceConfig.boolValue = deviceConfigEx.boolValue; deviceConfigs.push_back(deviceConfig); } } } return deviceConfigs; } void Form_DeviceConfig::Init(const std::vector& deviceConfigs) { // 1.获取默认ID m_defButtonId = -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) { 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) { m_defButtonId = i; break; } } // 2.恢复默认 assert(-1 != m_defButtonId); sane_control_option(m_devHandle, m_defButtonId, SANE_ACTION_SET_VALUE, NULL, NULL); // 3.更新当前配置信息 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; if (0 == strcmp(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, name)) continue; 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; devConfigEx.defStringValue = value; devConfigEx.hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); devConfigEx.readOnly = IS_CAP_READONLY(desp->cap); 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; devConfigEx.defIntValue = (int)value; devConfigEx.hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); devConfigEx.readOnly = IS_CAP_READONLY(desp->cap); 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); devConfigEx.defDoubleValue = SANE_UNFIX(value); devConfigEx.hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); devConfigEx.readOnly = IS_CAP_READONLY(desp->cap); 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; devConfigEx.defBoolValue = (bool)value; devConfigEx.hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); devConfigEx.readOnly = IS_CAP_READONLY(desp->cap); assert(!m_deviceConfigsGroups.empty()); m_deviceConfigsGroups[m_deviceConfigsGroups.size() - 1].deviceConfigs.push_back(devConfigEx); } } // 4.创建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 (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); ctrl->setProperty("configex_ptr", QVariant::fromValue(&deviceConfigEx)); deviceConfigEx.label = label; deviceConfigEx.ctrl = ctrl; deviceConfigEx.ctrlWidget = ctrlWidget; layout->addRow(label, ctrlWidget); label->setVisible(!deviceConfigEx.hide); ctrlWidget->setVisible(!deviceConfigEx.hide); ctrl->setEnabled(!deviceConfigEx.readOnly); } tabWidget->addTab(scrollArea, QString::fromStdString(m_deviceConfigsGroups[i].groupTitle)); } // 5.设置新配置 bool update = false; for (int i = 0; i < (int)deviceConfigs.size(); ++i) { for (int j = 1; j < num_dev_options; ++j) { const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, j); if (NULL == desp) continue; const char* name = desp->name; while (' ' == *name) ++name; if (0 == strcmp(deviceConfigs[i].name.c_str(), name)) { SANE_Int method = 0; if (SANE_TYPE_STRING == desp->type) { sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, (void*)deviceConfigs[i].stringValue.c_str(), &method); } else if (SANE_TYPE_INT == desp->type) { SANE_Int value = deviceConfigs[i].intValue; sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, &value, &method); } else if (SANE_TYPE_FIXED == desp->type) { SANE_Fixed value = SANE_FIX(deviceConfigs[i].doubleValue); sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, &value, &method); } else if (SANE_TYPE_BOOL == desp->type) { SANE_Bool value = (SANE_Bool)deviceConfigs[i].boolValue; sane_control_option(m_devHandle, j, SANE_ACTION_SET_VALUE, &value, &method); } if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) update = true; break; } } } // 6.更新UI if (update) { Update(-1); } } 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) { if (k == ignoreId) continue; const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, k); if (NULL == desp) continue; const char* name = desp->name; while (' ' == *name) ++name; if (0 == strcmp(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, name)) continue; const char* title = desp->title; while (' ' == *title) ++title; 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) { assert(pDeviceConfigEx->id == k); assert(pDeviceConfigEx->name == name); assert(pDeviceConfigEx->title == title); pDeviceConfigEx->hide = ((desp->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE); pDeviceConfigEx->readOnly = IS_CAP_READONLY(desp->cap); 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 (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())); } } deviceConfigEx.label->setVisible(!deviceConfigEx.hide); deviceConfigEx.ctrlWidget->setVisible(!deviceConfigEx.hide); deviceConfigEx.ctrl->setEnabled(!deviceConfigEx.readOnly); } } } 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.恢复默认 assert(-1 != m_defButtonId); sane_control_option(m_devHandle, m_defButtonId, SANE_ACTION_SET_VALUE, NULL, NULL); // 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(); DeviceConfigEx *deviceConfigEx = qvariant_cast(comboBox->property("configex_ptr")); 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->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(); DeviceConfigEx *deviceConfigEx = qvariant_cast(comboBox->property("configex_ptr")); 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->intValue = currentValue; if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) { Update(id); } } void Form_DeviceConfig::on_double_list_comboBoxClicked() { QComboBox *comboBox = qobject_cast(sender()); SANE_Word currentValue = SANE_FIX(comboBox->currentText().toDouble()); SANE_Int id = comboBox->property("config_id").toInt(); DeviceConfigEx *deviceConfigEx = qvariant_cast(comboBox->property("configex_ptr")); 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->doubleValue = comboBox->currentText().toDouble(); if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) { Update(id); } } void Form_DeviceConfig::on_int_sliderClicked(int value) { QSlider *slider = qobject_cast(sender()); SANE_Int currentValue = value; SANE_Int id = slider->property("config_id").toInt(); DeviceConfigEx *deviceConfigEx = qvariant_cast(slider->property("configex_ptr")); 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) { 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; } deviceConfigEx->intValue = currentValue; if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) { Update(id); } } 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(); DeviceConfigEx *deviceConfigEx = qvariant_cast(slider->property("configex_ptr")); 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->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_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(); DeviceConfigEx *deviceConfigEx = qvariant_cast(comboBox->property("configex_ptr")); 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->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(); DeviceConfigEx *deviceConfigEx = qvariant_cast(spinBox->property("configex_ptr")); 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->intValue = currentValue; if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) { Update(id); } } void Form_DeviceConfig::on_checkedClicked() { QCheckBox *checkBox = qobject_cast(sender()); SANE_Bool currentState = checkBox->isChecked(); int id = checkBox->property("config_id").toInt(); DeviceConfigEx *deviceConfigEx = qvariant_cast(checkBox->property("configex_ptr")); SANE_Int method = 0; SANE_Status ret = sane_control_option(m_devHandle, id, SANE_ACTION_SET_VALUE, ¤tState, &method); if (ret == SANE_STATUS_UNSUPPORTED) { SANE_Bool value = false; 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())); QMessageBox::information(this, tr("Prompt"), tr("The funtion is unsupported")); return; } deviceConfigEx->boolValue = currentState; if ((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS) { Update(id); } }