1343 lines
55 KiB
C++
1343 lines
55 KiB
C++
#include "form_deviceconfig.h"
|
|
#include <QTabWidget>
|
|
#include <QScrollArea>
|
|
#include <QFormLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QVBoxLayout>
|
|
#include <QLabel>
|
|
#include <QComboBox>
|
|
#include <QSlider>
|
|
#include <QCheckBox>
|
|
#include <QSpinBox>
|
|
#include <QSpacerItem>
|
|
#include <QPushButton>
|
|
#include <QEvent>
|
|
#include <QMessageBox>
|
|
#include "lang/app_language.h"
|
|
|
|
Form_DeviceConfig::Form_DeviceConfig(SANE_Handle devHandle, const std::vector<DeviceConfig>& deviceConfigs, QWidget *parent)
|
|
: QWidget(parent)
|
|
, m_clrToolDlg(nullptr)
|
|
, m_devHandle(devHandle)
|
|
, m_defButtonId(-1)
|
|
{
|
|
Init(deviceConfigs);
|
|
}
|
|
|
|
Form_DeviceConfig::~Form_DeviceConfig()
|
|
{
|
|
assert(nullptr == m_clrToolDlg);
|
|
}
|
|
|
|
std::vector<DeviceConfig> Form_DeviceConfig::GetDeviceConfigs()
|
|
{
|
|
std::vector<DeviceConfig> 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);
|
|
}
|
|
else if (5 == deviceConfigEx.valueType && (0 != memcmp(&deviceConfigEx.gammaValue, &deviceConfigEx.defGammaValue, sizeof(SANE_Gamma))))
|
|
{
|
|
deviceConfig.gammaValue = deviceConfigEx.gammaValue;
|
|
deviceConfigs.push_back(deviceConfig);
|
|
}
|
|
}
|
|
}
|
|
|
|
return deviceConfigs;
|
|
}
|
|
|
|
void Form_DeviceConfig::Init(const std::vector<DeviceConfig>& 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;
|
|
|
|
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);
|
|
|
|
if (0 == strcmp(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, name))
|
|
{
|
|
SANE_Gamma value = {0};
|
|
sane_control_option(m_devHandle, SANE_OPT_ID_CUSTOM_GAMMA, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
|
|
DeviceConfigEx devConfigEx;
|
|
devConfigEx.valueType = 5;
|
|
devConfigEx.gammaValue = value;
|
|
devConfigEx.defGammaValue = value;
|
|
|
|
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];
|
|
if (5 == deviceConfigEx.valueType)
|
|
continue;
|
|
|
|
// 创建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)
|
|
{
|
|
if (0 == strcmp(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, deviceConfigEx.name.c_str()))
|
|
{
|
|
QCheckBox *checkBox = new QCheckBox;
|
|
checkBox->setChecked(deviceConfigEx.boolValue);
|
|
connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_customGamma_checkedClicked()));
|
|
|
|
QPushButton *button = new QPushButton(tr("Custom gamma"));
|
|
button->setEnabled(deviceConfigEx.boolValue);
|
|
connect(button, &QPushButton::clicked, this, &Form_DeviceConfig::on_customGammaBtn_clicked);
|
|
|
|
checkBox->setProperty("relate_ctrl", QVariant::fromValue(button));
|
|
button->setProperty("relate_ctrl", QVariant::fromValue(checkBox));
|
|
|
|
QHBoxLayout* hLayout = new QHBoxLayout;
|
|
hLayout->addWidget(checkBox);
|
|
hLayout->addWidget(button);
|
|
hLayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding));
|
|
QWidget* checkBoxBtnWidget = new QWidget;
|
|
checkBoxBtnWidget->setLayout(hLayout);
|
|
|
|
ctrl = checkBox;
|
|
ctrlWidget = checkBoxBtnWidget;
|
|
}
|
|
else
|
|
{
|
|
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)
|
|
{
|
|
if (5 == deviceConfigs[i].valueType)
|
|
{
|
|
sane_control_option(m_devHandle, SANE_OPT_ID_CUSTOM_GAMMA, SANE_ACTION_SET_VALUE, (void *)&deviceConfigs[i].gammaValue, NULL);
|
|
continue;
|
|
}
|
|
|
|
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;
|
|
|
|
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)
|
|
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);
|
|
|
|
if (0 == strcmp(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, name))
|
|
{
|
|
for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i)
|
|
{
|
|
bool find = false;
|
|
for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j)
|
|
{
|
|
if (5 == m_deviceConfigsGroups[i].deviceConfigs[j].valueType)
|
|
{
|
|
SANE_Gamma value = {0};
|
|
sane_control_option(m_devHandle, SANE_OPT_ID_CUSTOM_GAMMA, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
m_deviceConfigsGroups[i].deviceConfigs[j].gammaValue = value;
|
|
find = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (find)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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 (5 == deviceConfigEx.valueType)
|
|
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<QSpinBox*>(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<QDoubleSpinBox*>(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)
|
|
{
|
|
if (0 == strcmp(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, deviceConfigEx.name.c_str()))
|
|
{
|
|
QCheckBox *checkBox = (QCheckBox*)deviceConfigEx.ctrl;
|
|
QPushButton* button = qvariant_cast<QPushButton*>(checkBox->property("relate_ctrl"));
|
|
disconnect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_customGamma_checkedClicked()));
|
|
disconnect(button, &QPushButton::clicked, this, &Form_DeviceConfig::on_customGammaBtn_clicked);
|
|
checkBox->setChecked(deviceConfigEx.boolValue);
|
|
button->setEnabled(deviceConfigEx.boolValue);
|
|
connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_customGamma_checkedClicked()));
|
|
connect(button, &QPushButton::clicked, this, &Form_DeviceConfig::on_customGammaBtn_clicked);
|
|
}
|
|
else
|
|
{
|
|
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_closeDevice()
|
|
{
|
|
if (nullptr != m_clrToolDlg)
|
|
m_clrToolDlg->reject();
|
|
}
|
|
|
|
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<QComboBox*>(sender());
|
|
std::string currentText = comboBox->currentText().toUtf8();
|
|
SANE_Int id = comboBox->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(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<QComboBox*>(sender());
|
|
SANE_Int currentValue = comboBox->currentText().toInt();
|
|
SANE_Int id = comboBox->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(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<QComboBox*>(sender());
|
|
SANE_Word currentValue = SANE_FIX(comboBox->currentText().toDouble());
|
|
SANE_Int id = comboBox->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(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<QSlider*>(sender());
|
|
SANE_Int currentValue = value;
|
|
SANE_Int id = slider->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(slider->property("configex_ptr"));
|
|
|
|
QSpinBox* spinBox = qvariant_cast<QSpinBox*>(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<QSlider*>(sender());
|
|
SANE_Word currentValue = SANE_FIX(value / 100.0);
|
|
SANE_Int id = slider->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(slider->property("configex_ptr"));
|
|
|
|
QDoubleSpinBox* doubleSpinBox = qvariant_cast<QDoubleSpinBox*>(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<QSpinBox*>(sender());
|
|
QSlider* slider = qvariant_cast<QSlider*>(spinBox->property("relate_ctrl"));
|
|
slider->setValue(value);
|
|
}
|
|
|
|
void Form_DeviceConfig::on_relate_doubleSpinboxClicked(double value)
|
|
{
|
|
QDoubleSpinBox* doubleSpinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
|
QSlider* slider = qvariant_cast<QSlider*>(doubleSpinBox->property("relate_ctrl"));
|
|
slider->setValue(round(value * 100));
|
|
}
|
|
|
|
void Form_DeviceConfig::on_string_comboBoxClicked()
|
|
{
|
|
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
|
std::string currentText = comboBox->currentText().toUtf8();
|
|
SANE_Int id = comboBox->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(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<QSpinBox*>(sender());
|
|
SANE_Int currentValue = value;
|
|
SANE_Int id = spinBox->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(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_customGamma_checkedClicked()
|
|
{
|
|
QCheckBox *checkBox = qobject_cast<QCheckBox*>(sender());
|
|
SANE_Bool currentState = checkBox->isChecked();
|
|
int id = checkBox->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(checkBox->property("configex_ptr"));
|
|
|
|
QPushButton* button = qvariant_cast<QPushButton*>(checkBox->property("relate_ctrl"));
|
|
disconnect(button, &QPushButton::clicked, this, &Form_DeviceConfig::on_customGammaBtn_clicked);
|
|
button->setEnabled((bool)currentState);
|
|
connect(button, &QPushButton::clicked, this, &Form_DeviceConfig::on_customGammaBtn_clicked);
|
|
|
|
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()));
|
|
disconnect(button, &QPushButton::clicked, this, &Form_DeviceConfig::on_customGammaBtn_clicked);
|
|
checkBox->setCheckState(value ? Qt::Checked : Qt::Unchecked);
|
|
button->setEnabled((bool)value);
|
|
connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(on_checkedClicked()));
|
|
connect(button, &QPushButton::clicked, this, &Form_DeviceConfig::on_customGammaBtn_clicked);
|
|
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);
|
|
}
|
|
}
|
|
|
|
void Form_DeviceConfig::on_customGammaBtn_clicked()
|
|
{
|
|
SANE_Gamma *gammaData = nullptr;
|
|
|
|
for (int i = 0; i < (int)m_deviceConfigsGroups.size(); ++i)
|
|
{
|
|
for (int j = 0; j < (int)m_deviceConfigsGroups[i].deviceConfigs.size(); ++j)
|
|
{
|
|
DeviceConfigEx &deviceConfigEx = m_deviceConfigsGroups[i].deviceConfigs[j];
|
|
if (5 == deviceConfigEx.valueType)
|
|
{
|
|
gammaData = &deviceConfigEx.gammaValue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (nullptr != gammaData)
|
|
break;
|
|
}
|
|
|
|
if (nullptr == gammaData)
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::string colorMode = from_default_language(OPTION_VALUE_YSMS_24WCS);
|
|
bool isMultiOut = false;
|
|
std::string multiOutType = from_default_language(OPTION_VALUE_DLSCLX_CS_HD_HB);
|
|
|
|
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.name == SANE_STD_OPT_NAME_COLOR_MODE)
|
|
colorMode = deviceConfigEx.stringValue;
|
|
else if (deviceConfigEx.name == SANE_STD_OPT_NAME_IS_MULTI_OUT)
|
|
isMultiOut = deviceConfigEx.boolValue;
|
|
else if (deviceConfigEx.name == SANE_STD_OPT_NAME_MULTI_OUT_TYPE)
|
|
multiOutType = deviceConfigEx.stringValue;
|
|
}
|
|
}
|
|
|
|
int clrMode = 0; // 0-彩色, 1-灰度
|
|
if (!isMultiOut)
|
|
{
|
|
if (colorMode == from_default_language(OPTION_VALUE_YSMS_256JHD)
|
|
|| colorMode == from_default_language(OPTION_VALUE_YSMS_HB))
|
|
{
|
|
clrMode = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (multiOutType == from_default_language(OPTION_VALUE_DLSCLX_HD_HB))
|
|
{
|
|
clrMode = 1;
|
|
}
|
|
}
|
|
|
|
assert(nullptr == m_clrToolDlg);
|
|
m_clrToolDlg = new setPicClrTool(clrMode, this);
|
|
|
|
if (1 == clrMode)
|
|
{
|
|
QList<QPoint> grayKeyTable;
|
|
for (int i = 0; i < gammaData->count[GAMMA_INDEX_GRAY]; ++i)
|
|
{
|
|
uchar x = gammaData->pt_gray[i];
|
|
uchar y = gammaData->table[256 * GAMMA_INDEX_GRAY + x];
|
|
grayKeyTable.append(QPoint(x, y));
|
|
}
|
|
|
|
if (!grayKeyTable.empty())
|
|
{
|
|
m_clrToolDlg->setGrayKeyTable(grayKeyTable);
|
|
}
|
|
}
|
|
else if (0 == clrMode)
|
|
{
|
|
QList<QPoint> colorKeyTable;
|
|
for (int i = 0; i < gammaData->count[GAMMA_INDEX_COLOR]; ++i)
|
|
{
|
|
uchar x = gammaData->pt_color[i];
|
|
uchar y = gammaData->table[256 * GAMMA_INDEX_COLOR + x];
|
|
colorKeyTable.append(QPoint(x, y));
|
|
}
|
|
|
|
QList<QPoint> rKeyTable;
|
|
for (int i = 0; i < gammaData->count[GAMMA_INDEX_RED]; ++i)
|
|
{
|
|
uchar x = gammaData->pt_red[i];
|
|
uchar y = gammaData->table[256 * GAMMA_INDEX_RED + x];
|
|
rKeyTable.append(QPoint(x, y));
|
|
}
|
|
|
|
QList<QPoint> gKeyTable;
|
|
for (int i = 0; i < gammaData->count[GAMMA_INDEX_GREEN]; ++i)
|
|
{
|
|
uchar x = gammaData->pt_green[i];
|
|
uchar y = gammaData->table[256 * GAMMA_INDEX_GREEN + x];
|
|
gKeyTable.append(QPoint(x, y));
|
|
}
|
|
|
|
QList<QPoint> bKeyTable;
|
|
for (int i = 0; i < gammaData->count[GAMMA_INDEX_BLUE]; ++i)
|
|
{
|
|
uchar x = gammaData->pt_blue[i];
|
|
uchar y = gammaData->table[256 * GAMMA_INDEX_BLUE + x];
|
|
bKeyTable.append(QPoint(x, y));
|
|
}
|
|
|
|
QVector<QList<QPoint>> keyTableList;
|
|
if (!colorKeyTable.empty() && !rKeyTable.empty() && !gKeyTable.empty() && !bKeyTable.empty())
|
|
{
|
|
keyTableList.append(colorKeyTable);
|
|
keyTableList.append(rKeyTable);
|
|
keyTableList.append(gKeyTable);
|
|
keyTableList.append(bKeyTable);
|
|
m_clrToolDlg->setRGBKeyTable(keyTableList);
|
|
}
|
|
}
|
|
|
|
int rgbTypeIndex = 0;
|
|
rgbTypeIndex = gammaData->app_data & 0x0F;
|
|
int colorTypeIndex = 0;
|
|
colorTypeIndex = (gammaData->app_data & 0xF0) >> 4;
|
|
|
|
m_clrToolDlg->setRgbAndColorType(rgbTypeIndex, colorTypeIndex);
|
|
if (m_clrToolDlg->exec())
|
|
{
|
|
if (1 == clrMode)
|
|
{
|
|
QList<QPoint> keyTable = m_clrToolDlg->getGrayKeyTable();
|
|
|
|
gammaData->count[GAMMA_INDEX_GRAY] = HGMIN(4, keyTable.size());
|
|
int i = 0;
|
|
for (QPoint pt : keyTable)
|
|
{
|
|
if (i >= 4)
|
|
break;
|
|
|
|
gammaData->pt_gray[i] = pt.x();
|
|
++i;
|
|
}
|
|
|
|
m_clrToolDlg->getGrayTable(gammaData->table, 256);
|
|
}
|
|
else
|
|
{
|
|
QVector<QList<QPoint>> keyTableList = m_clrToolDlg->getRGBKeyTable();
|
|
|
|
gammaData->count[GAMMA_INDEX_COLOR] = HGMIN(4, keyTableList[0].size());
|
|
int i = 0;
|
|
for (QPoint pt : keyTableList[0])
|
|
{
|
|
if (i >= 4)
|
|
break;
|
|
|
|
gammaData->pt_color[i] = pt.x();
|
|
++i;
|
|
}
|
|
|
|
gammaData->count[GAMMA_INDEX_RED] = HGMIN(4, keyTableList[1].size());
|
|
i = 0;
|
|
for (QPoint pt : keyTableList[1])
|
|
{
|
|
if (i >= 4)
|
|
break;
|
|
|
|
gammaData->pt_red[i] = pt.x();
|
|
++i;
|
|
}
|
|
|
|
gammaData->count[GAMMA_INDEX_GREEN] = HGMIN(4, keyTableList[2].size());
|
|
i = 0;
|
|
for (QPoint pt : keyTableList[2])
|
|
{
|
|
if (i >= 4)
|
|
break;
|
|
|
|
gammaData->pt_green[i] = pt.x();
|
|
++i;
|
|
}
|
|
|
|
gammaData->count[GAMMA_INDEX_BLUE] = HGMIN(4, keyTableList[3].size());
|
|
i = 0;
|
|
for (QPoint pt : keyTableList[3])
|
|
{
|
|
if (i >= 4)
|
|
break;
|
|
|
|
gammaData->pt_blue[i] = pt.x();
|
|
++i;
|
|
}
|
|
|
|
m_clrToolDlg->getRGBTable(gammaData->table + 256, 256 * 4);
|
|
}
|
|
|
|
QVector<int> type = m_clrToolDlg->getRgbAndColorType();
|
|
gammaData->app_data = type[0] | (type[1] << 4);
|
|
|
|
SANE_Status ret = sane_control_option(m_devHandle, SANE_OPT_ID_CUSTOM_GAMMA, SANE_ACTION_SET_VALUE, (void *)gammaData, NULL);
|
|
if (SANE_STATUS_GOOD != ret)
|
|
{
|
|
sane_control_option(m_devHandle, SANE_OPT_ID_CUSTOM_GAMMA, SANE_ACTION_GET_VALUE, (void *)gammaData, NULL);
|
|
}
|
|
}
|
|
|
|
delete m_clrToolDlg;
|
|
m_clrToolDlg = nullptr;
|
|
}
|
|
|
|
void Form_DeviceConfig::on_checkedClicked()
|
|
{
|
|
QCheckBox *checkBox = qobject_cast<QCheckBox*>(sender());
|
|
SANE_Bool currentState = checkBox->isChecked();
|
|
int id = checkBox->property("config_id").toInt();
|
|
DeviceConfigEx *deviceConfigEx = qvariant_cast<DeviceConfigEx*>(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);
|
|
}
|
|
}
|