#include "form_deviceconfig.h" #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) { Init(devHandle); 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; } } } Update(deviceConfigsGroups); } Form_DeviceConfig::~Form_DeviceConfig() { } std::vector Form_DeviceConfig::GetDeviceConfigs() { std::vector deviceConfigs; for (int i = 0; i < (int)m_baseDeviceConfigsGroups.size(); ++i) { for (int j = 0; j < (int)m_baseDeviceConfigsGroups[i].deviceConfigs.size(); ++j) { const DeviceConfigEx &deviceConfig = m_baseDeviceConfigsGroups[i].deviceConfigs[j]; QWidget *ctrl = nullptr; for (int k = 0; k < (int)m_ctrlList.size(); ++k) { if (deviceConfig.name == m_ctrlList[k]->property("config_name").toString().toStdString()) { ctrl = m_ctrlList[k]; break; } } if (nullptr != ctrl) { 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); } } } } } } return deviceConfigs; } 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::Init(SANE_Handle devHandle) { // 1.重置设备 SANE_Int num_dev_options = 0; sane_control_option(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(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(devHandle, i, SANE_ACTION_SET_VALUE, NULL, NULL); break; } } // 2.获取基本配置 m_baseDeviceConfigsGroups.clear(); for (int i = 1; i < num_dev_options; ++i) { const SANE_Option_Descriptor* desp = sane_get_option_descriptor(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_baseDeviceConfigsGroups.push_back(group); } else if (SANE_TYPE_STRING == desp->type) { char value[256] = { 0 }; sane_control_option(devHandle, i, SANE_ACTION_GET_VALUE, value, NULL); DeviceConfigEx devConfig; 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); } } else if (SANE_TYPE_INT == desp->type) { SANE_Int value = 0; sane_control_option(devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); DeviceConfigEx devConfig; 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); } else if (SANE_TYPE_FIXED == desp->type) { SANE_Word value = 0; sane_control_option(devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); DeviceConfigEx devConfig; 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); } else if (SANE_TYPE_BOOL == desp->type) { SANE_Bool value = 0; sane_control_option(devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL); DeviceConfigEx devConfig; 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); } } // 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->setCurrentText(QString::fromStdString(deviceConfig.stringValue)); 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->setCurrentText(QString::number(deviceConfig.intValue)); 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->setCurrentText(QString::number(deviceConfig.doubleValue)); 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->setValue(deviceConfig.intValue); 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->setProperty("config_name", QString::fromStdString(deviceConfig.name)); spinBox->installEventFilter(this); connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_spinBoxClicked(int))); ctrl = slider; QHBoxLayout* hLayout = new QHBoxLayout; hLayout->addWidget(ctrl); hLayout->addWidget(spinBox); QWidget* sliderSpinWidget = new QWidget; sliderSpinWidget->setLayout(hLayout); 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->setValue(round(deviceConfig.doubleValue * 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(round(deviceConfig.doubleValueMin), round(deviceConfig.doubleValueMax)); doubleSpinBox->setDecimals(2); doubleSpinBox->setSingleStep(0.01); doubleSpinBox->setProperty("config_name", QString::fromStdString(deviceConfig.name)); doubleSpinBox->installEventFilter(this); connect(doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(on_doubleSpinboxClicked(double))); ctrl = slider; QHBoxLayout* hLayout = new QHBoxLayout; hLayout->addWidget(ctrl); hLayout->addWidget(doubleSpinBox); QWidget* sliderSpinWidget = new QWidget; sliderSpinWidget->setLayout(hLayout); 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->setValue(deviceConfig.intValue); spinBox->installEventFilter(this); ctrl = spinBox; ctrlWidget = spinBox; } else if (3 == deviceConfig.valueType) { } else if (4 == deviceConfig.valueType) { QCheckBox *checkBox = new QCheckBox; //checkBox->setChecked(deviceConfig.boolValue); ctrl = checkBox; ctrlWidget = checkBox; } } if (nullptr != ctrl) { ctrl->setProperty("config_name", QString::fromStdString(deviceConfig.name)); m_ctrlList.push_back(ctrl); } if (nullptr != ctrlWidget) { layout->addRow(label, ctrlWidget); } } tabWidget->addTab(scrollArea, QString::fromStdString(m_baseDeviceConfigsGroups[i].groupTitle)); } } void Form_DeviceConfig::Update(std::vector &deviceConfigsGroups) { 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; for (int k = 0; k < (int)m_ctrlList.size(); ++k) { if (deviceConfig.name == m_ctrlList[k]->property("config_name").toString().toStdString()) { ctrl = m_ctrlList[k]; 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); } } } } } } void Form_DeviceConfig::on_defaultBtn_clicked() { Update(m_baseDeviceConfigsGroups); } void Form_DeviceConfig::on_sliderClicked(int value) { QSlider *slider = qobject_cast(sender()); QString sliderProverty = slider->property("config_name").toString(); QList buttons = this->findChildren(); foreach(QAbstractSpinBox* abstractSpinBox, buttons) { QString spinBoxProverty = abstractSpinBox->property("config_name").toString(); if (spinBoxProverty == sliderProverty) { if (typeid(*abstractSpinBox) == typeid(QSpinBox)) { QSpinBox* spinBox = reinterpret_cast(abstractSpinBox); spinBox->setValue(value); } else { QDoubleSpinBox* doubleSpinBox = reinterpret_cast(abstractSpinBox); double temp = value * doubleSpinBox->singleStep(); doubleSpinBox->setValue(temp); } break; } } } void Form_DeviceConfig::on_spinBoxClicked(int value) { QSpinBox* spinBox = qobject_cast(sender()); QString spinBoxProverty = spinBox->property("config_name").toString(); QList buttons = this->findChildren(); foreach(QSlider* slider, buttons) { QString sliderProverty = slider->property("config_name").toString(); if (sliderProverty == spinBoxProverty) { slider->setValue(value); break; } } } void Form_DeviceConfig::on_doubleSpinboxClicked(double value) { QDoubleSpinBox* spinBox = qobject_cast(sender()); QString spinBoxProverty = spinBox->property("config_name").toString(); QList buttons = this->findChildren(); foreach(QSlider* slider, buttons) { QString sliderProverty = slider->property("config_name").toString(); if (sliderProverty == spinBoxProverty) { int temp = value / spinBox->singleStep() + 0.5; slider->setValue(temp); break; } } }