code_app/app/scanner/hg_settingdialog.cpp

1748 lines
59 KiB
C++
Raw Normal View History

2022-05-03 10:25:52 +00:00
#include "hg_settingdialog.h"
#include <QDebug>
#include <QLatin1String>
hg_settingdialog::hg_settingdialog(void *handle, QWidget *parent
, DEVCFG* cfg)
: QDialog(parent)
, schemes_(cfg), cur_ind_(cfg->cur_scheme), changed_count_(0), save_(false)
{
m_handle = handle;
initUi();
on_select_scheme(cur_ind_, false);
}
hg_settingdialog::~hg_settingdialog()
{
}
void hg_settingdialog::initUi()
{
updateOpt();
createUI();
setWindowTitle(schemes_ ? QString::fromStdString(schemes_->name) : tr("set"));
}
void hg_settingdialog::updateOpt()
{
bool first = default_vals_.empty();
m_list_defaultOptions.clear();
SANE_Int dev_options = 0;
sane_control_option(m_handle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
for (int i = 1, j= dev_options; i < j; i++)
{
const SANE_Option_Descriptor* opt = sane_get_option_descriptor(m_handle, i);
SANE_Int method = 0;
if (opt == nullptr)
{
m_list_defaultOptions.append(QPair<const void*, QVariant>(opt, QVariant(0)));
}
else
{
CHANGEDOPT co;
co.opt = i;
co.val.clear();
if(opt->type == SANE_TYPE_INT)
{
SANE_Int init = 0;
sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, &init, &method);
m_list_defaultOptions.append(QPair<const void*, QVariant>(opt, QVariant(init)));
std::vector<CHANGEDOPT>::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i);
if(it != changed_opts_.end())
it->val = QVariant(init);
if(first)
{
unsigned int opt = i;
sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &opt);
co.val = QVariant(init);
}
}
else if(opt->type == SANE_TYPE_FIXED)
{
SANE_Fixed init = 0;
sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, &init, &method);
m_list_defaultOptions.append(QPair<const void*, QVariant>(opt, QVariant(init)));
std::vector<CHANGEDOPT>::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i);
if(it != changed_opts_.end())
it->val = QVariant(SANE_UNFIX(init));
if(first)
{
unsigned int opt = i;
sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &opt);
co.val = QVariant(SANE_UNFIX(init));
}
}
else if(opt->type == SANE_TYPE_BOOL)
{
SANE_Bool init = 0;
sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, &init, &method);
m_list_defaultOptions.append(QPair<const void*, QVariant>(opt, QVariant(init)));
std::vector<CHANGEDOPT>::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i);
if(it != changed_opts_.end())
it->val = QVariant(init);
if(first)
{
unsigned int opt = i;
sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, &init, &opt);
co.val = QVariant(init);
}
}
else if(opt->type == SANE_TYPE_STRING)
{
char *init = (char*)malloc(opt->size * 2 + 4);
sane_control_option(m_handle, i, SANE_ACTION_GET_VALUE, init, &method);
m_list_defaultOptions.append(QPair<const void*, QVariant>(opt, QVariant(QString::fromStdString(init))));
std::vector<CHANGEDOPT>::iterator it = std::find(changed_opts_.begin(), changed_opts_.end(), i);
if(it != changed_opts_.end())
it->val = QVariant(QString::fromStdString(init));
if(first)
{
unsigned int opt = i;
int err = sane_io_control(m_handle, IO_CTRL_CODE_GET_DEFAULT_VALUE, init, &opt);
(void)err;
co.val = QVariant(QString::fromStdString(init));
}
free(init);
}
else
{
co.opt = -1;
m_list_defaultOptions.append(QPair<const void*, QVariant>(opt, QVariant(0)));
}
if(first && co.opt != -1)
default_vals_.push_back(co);
}
}
}
QAction* hg_settingdialog::find_current_scheme_menu(int *scheme_id)
{
QList<QAction*> acts = top_menu_->actions();
for(size_t i = 0; i < (size_t)acts.size(); ++i)
{
if(!acts[i]->isChecked())
continue;
if(scheme_id)
{
*scheme_id = -1;
for(size_t j = 1; j < schemes_->schemes.size(); ++j)
{
if(schemes_->schemes[j].name != acts[i]->text().toStdString())
continue;
*scheme_id = j - 1;
break;
}
}
return acts[i];
}
return NULL;
}
void hg_settingdialog::create_scheme_management_ui(QVBoxLayout* layout)
{
QLabel *title = new QLabel(this);
QMenuBar *mb = new QMenuBar(this);
QActionGroup *group = new QActionGroup(this);
bool enabled = false;
QAction *acts = NULL;
top_menu_ = new QMenu(this);
top_menu_->setTitle(tr("configuration management"));
layout->setMenuBar(mb);
mb->addMenu(top_menu_);
edit_name_ = new QLineEdit(tr("No configuration selected"), this);
for(int i = 1; i < (int)schemes_->schemes.size(); ++i)
{
QAction *item = group->addAction(QString::fromStdString(schemes_->schemes[i].name));
top_menu_->addAction(item);
item->setCheckable(true);
if(schemes_->cur_scheme == i - 1)
{
acts = item;
edit_name_->setText(QString::fromStdString(schemes_->schemes[i].name));
item->setChecked(true);
enabled = true;
}
}
connect(group, SIGNAL(triggered(QAction*)), this, SLOT(on_scheme_triggered(QAction*)));
if(schemes_->schemes.size() <= 1)
{
acts = top_menu_->addAction(tr("No custom configuration was found"));
acts->setEnabled(false);
}
title->setFixedWidth(100);
layout->addWidget(title);
layout->addSpacing(30);
title = new QLabel(this);
title->setText(tr("configuration name: "));
layout->addWidget(title);
edit_name_->setEnabled(enabled);
edit_name_->setFixedWidth(title->width());
layout->addWidget(edit_name_);
rename_ = new QPushButton(this);
rename_->setText(tr("configuration change name"));
rename_->setEnabled(enabled);
rename_->setFixedWidth(title->width());
layout->addWidget(rename_);
connect(rename_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management()));
apply_ = new QPushButton(this);
apply_->setText(tr("apply configuration-->"));
apply_->setEnabled(enabled);
apply_->setFixedWidth(title->width());
layout->addWidget(apply_);
connect(apply_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management()));
layout->addSpacing(10);
del_this_ = new QPushButton(this);
del_this_->setText(tr("delete configuration"));
del_this_->setEnabled(enabled);
del_this_->setFixedWidth(title->width());
layout->addWidget(del_this_);
connect(del_this_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management()));
del_all_ = new QPushButton(this);
del_all_->setText(tr("delete all configurations"));
del_all_->setEnabled(enabled);
del_all_->setFixedWidth(title->width());
layout->addWidget(del_all_);
connect(del_all_, SIGNAL(clicked(bool)), this, SLOT(slot_pushButton_scheme_management()));
sketch_ = new QTextEdit(this);
sketch_->setReadOnly(true);
sketch_->setFixedSize(title->width(), 200);
layout->addWidget(sketch_);
layout->addStretch();
on_scheme_triggered(acts);
}
void hg_settingdialog::createUI()
{
QTabWidget *tabWidgetCreation = new QTabWidget(this);
QPushButton *buttonOk = new QPushButton(this);
buttonOk->setText(tr("ok"));
QPushButton *buttonCancel = new QPushButton(this);
buttonCancel->setText(tr("cancel"));
QHBoxLayout *hlayoutOkAndCancel = new QHBoxLayout;
hlayoutOkAndCancel->addStretch();
hlayoutOkAndCancel->addWidget(buttonOk);
hlayoutOkAndCancel->addWidget(buttonCancel);
QWidget *widgetOkAndCancel = new QWidget();
widgetOkAndCancel->setLayout(hlayoutOkAndCancel);
connect(buttonOk, SIGNAL(clicked(bool)), this, SLOT(slot_buttonOkClicked()));
connect(buttonCancel, SIGNAL(clicked(bool)), this, SLOT(slot_buttonCancelClicked()));
QHBoxLayout *h = new QHBoxLayout();
QVBoxLayout *v1 = new QVBoxLayout(),
*v2 = new QVBoxLayout();
create_scheme_management_ui(v1);
v2->addWidget(tabWidgetCreation);
h->addItem(v1);
h->addItem(v2);
QVBoxLayout* mainVerticalLayout = new QVBoxLayout(this);
mainVerticalLayout->addItem(h);
// mainVerticalLayout->addWidget(tabWidgetCreation);
mainVerticalLayout->addWidget(widgetOkAndCancel);
this->setLayout(mainVerticalLayout);
QScrollArea* scrollArea = new QScrollArea;
scrollArea->setWidgetResizable(true);
scrollArea->setAlignment(Qt::AlignCenter);
QFormLayout* layout = new QFormLayout;
QWidget* widget = new QWidget;
widget->setLayout(layout);
bool isBegin = true;
CHANGEDOPT init;
for (int i = 0; i < m_list_defaultOptions.size(); i++)
{
const SANE_Option_Descriptor* opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_defaultOptions.at(i).first);
int ind = -1, scheme = cur_ind_ + 1;
if(opt == nullptr) continue;
if(schemes_ && cur_ind_ != -1)
ind = find_opt_setting(opt->title, schemes_->schemes[scheme].opts);
init.opt = i + 1;
switch (opt->type)
{
case SANE_TYPE_BOOL:
{
QCheckBox *checkBoxCreation = new QCheckBox(scrollArea);
reinterpret_cast<QFormLayout*>(widget->layout())->addRow(opt->title + QString(" : "), checkBoxCreation);
checkBoxCreation->setToolTip(opt->desc);
int id = i + 1;
checkBoxCreation->setProperty("controls_id", id);
if(ind != -1)
init.val = QVariant(schemes_->schemes[scheme].opts[ind].val == "true");
else
init.val = m_list_defaultOptions.at(i).second;
checkBoxCreation->setChecked(init.val.toBool());
connect(checkBoxCreation, SIGNAL(stateChanged(int)), this, SLOT(slot_checkedClicked()));
m_list_widgets.append(checkBoxCreation);
m_list_getOpt.append(QPair<int, const void*>(id, opt));
iniRead(md5(opt->title), id, checkBoxCreation);
break;
}
case SANE_TYPE_INT:
{
switch(opt->constraint_type)
{
case SANE_CONSTRAINT_NONE:
{
QSpinBox* spinBox = new QSpinBox(scrollArea);
spinBox->setMinimumWidth(150);
spinBox->setToolTip(opt->desc);
spinBox->setRange(1, 500);
int id = i + 1;
spinBox->setProperty("controls_id", id);
QHBoxLayout* hLayout = new QHBoxLayout;
hLayout->addWidget(spinBox);
hLayout->addStretch();
reinterpret_cast<QFormLayout*>(widget->layout())->addRow(opt->title + QString(" : "), spinBox);
m_list_widgets.append(spinBox);
m_list_getOpt.append(QPair<int, const void*>(id, opt));
if(ind == -1)
init.val = m_list_defaultOptions.at(i).second;
else
init.val = QVariant(atoi(schemes_->schemes[scheme].opts[ind].val.c_str()));
spinBox->setValue(init.val.toInt());
connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int)));
break;
}
case SANE_CONSTRAINT_RANGE:
{
QWidget* widget_slider_spin = new QWidget(scrollArea);
widget_slider_spin->setMinimumWidth(200);
QSlider* sliderCreation = new QSlider(widget_slider_spin);
sliderCreation->setOrientation(Qt::Horizontal);
sliderCreation->setMinimumWidth(120);
sliderCreation->setRange(opt->constraint.range->min, opt->constraint.range->max);
sliderCreation->setToolTip(opt->desc);
sliderCreation->setProperty("controls_id", i+1);
sliderCreation->setValue(m_list_defaultOptions.at(i).second.toInt());
QSpinBox* spinBox = new QSpinBox(widget_slider_spin);
spinBox->setMinimumWidth(150);
spinBox->setToolTip(opt->desc);
spinBox->setRange(opt->constraint.range->min, opt->constraint.range->max);
spinBox->setSingleStep(1);
spinBox->setValue(m_list_defaultOptions.at(i).second.toInt());
int id = i + 1;
spinBox->setProperty("controls_id", id);
m_list_sliderSpinbox.append(QPair<QObject*, QObject*>(sliderCreation, spinBox));
QHBoxLayout* hLayout = new QHBoxLayout;
hLayout->addWidget(sliderCreation);
hLayout->addWidget(spinBox);
hLayout->addStretch();
widget_slider_spin->setLayout(hLayout);
reinterpret_cast<QFormLayout*>(widget->layout())->addRow(opt->title + QString(" : "), widget_slider_spin);
m_list_widgets.append(sliderCreation);
m_list_widgets.append(spinBox);
m_list_getOpt.append(QPair<int, const void*>(id, opt));
if(ind == -1)
init.val = m_list_defaultOptions.at(i).second;
else
init.val = QVariant(atoi(schemes_->schemes[scheme].opts[ind].val.c_str()));
spinBox->setValue(init.val.toInt());
sliderCreation->setValue(init.val.toInt());
connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int)));
connect(sliderCreation, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int)));
break;
}
case SANE_CONSTRAINT_WORD_LIST:
{
break;
}
case SANE_CONSTRAINT_STRING_LIST:
break;
}
break;
}
case SANE_TYPE_FIXED:
{
QWidget* widget_slider_spin = new QWidget(scrollArea);
widget_slider_spin->setMinimumWidth(200);
QSlider* sliderCreation = new QSlider(widget_slider_spin);
sliderCreation->setOrientation(Qt::Horizontal);
sliderCreation->setMinimumWidth(120);
sliderCreation->setToolTip(opt->desc);
int id = i + 1;
sliderCreation->setProperty("controls_id", id);
sliderCreation->setRange(SANE_UNFIX(opt->constraint.range->min) * 100, SANE_UNFIX(opt->constraint.range->max) * 100);
sliderCreation->setValue(SANE_UNFIX(m_list_defaultOptions.at(i).second.toDouble()) * 100);
QDoubleSpinBox* spinBox = new QDoubleSpinBox(widget_slider_spin);
spinBox->setMinimumWidth(150);
spinBox->setToolTip(opt->desc);
spinBox->setDecimals(2);
spinBox->setSingleStep(0.01);
spinBox->setRange(SANE_UNFIX(opt->constraint.range->min), SANE_UNFIX(opt->constraint.range->max));
spinBox->setValue(sliderCreation->value() * spinBox->singleStep());
spinBox->setProperty("controls_id", id);
m_list_sliderSpinbox.append(QPair<QObject*, QObject*>(sliderCreation, spinBox));
QHBoxLayout* hLayout = new QHBoxLayout;
hLayout->addWidget(sliderCreation);
hLayout->addWidget(spinBox);
hLayout->addStretch();
widget_slider_spin->setLayout(hLayout);
reinterpret_cast<QFormLayout*>(widget->layout())->addRow(opt->title + QString(" : "), widget_slider_spin);
m_list_widgets.append(sliderCreation);
m_list_widgets.append(spinBox);
m_list_getOpt.append(QPair<int, const void*>(id, opt));
// iniRead(md5(opt->title), id, sliderCreation);
// iniRead(md5(opt->title), id, spinBox);
if(ind == -1)
init.val = SANE_UNFIX(m_list_defaultOptions.at(i).second.toInt());
else
init.val = QVariant(atof(schemes_->schemes[scheme].opts[ind].val.c_str()));
sliderCreation->setValue(init.val.toDouble() * 100);
spinBox->setValue(sliderCreation->value() * spinBox->singleStep());
connect(spinBox, SIGNAL(valueChanged(double)), this, SLOT(slot_doubleSpinboxClicked(double)));
connect(sliderCreation, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int)));
break;
}
case SANE_TYPE_STRING:
{
switch(opt->constraint_type)
{
case SANE_CONSTRAINT_NONE:
{
QLineEdit *lineEdit = new QLineEdit(scrollArea);
lineEdit->setToolTip(opt->desc);
int id = i + 1;
lineEdit->setProperty("controls_id", id);
reinterpret_cast<QFormLayout*>(widget->layout())->addRow(opt->title + QString(" : "), lineEdit);
m_list_widgets.append(lineEdit);
m_list_getOpt.append(QPair<int, const void*>(id, opt));
// iniRead(md5(opt->title), id, lineEdit);
if(ind == -1)
init.val = m_list_defaultOptions.at(i).second;
else
init.val = QVariant(schemes_->schemes[scheme].opts[ind].val.c_str());
lineEdit->setText(init.val.toString());
connect(lineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slot_lineEditInput()));
break;
}
case SANE_CONSTRAINT_RANGE:
break;
case SANE_CONSTRAINT_WORD_LIST:
break;
case SANE_CONSTRAINT_STRING_LIST:
{
QComboBox* comboBoxCreation = new QComboBox(scrollArea);
comboBoxCreation->setToolTip(opt->desc);
int id = i + 1;
comboBoxCreation->setProperty("controls_id", id);
reinterpret_cast<QFormLayout*>(widget->layout())->addRow(opt->title + QString(" : "), comboBoxCreation);
auto p_str = opt->constraint.string_list;
QStringList stringList;
while(*p_str)
{
stringList.append(*p_str);
p_str++;
}
if(stringList.isEmpty() != true)
{
for(int i = 0; i < (stringList.size()); i++)
comboBoxCreation->addItem(stringList.at(i));
}
comboBoxCreation->setCurrentText(m_list_defaultOptions.at(i).second.toString());
//printf("Option %02d default value is: %s\n", i + 1, m_list_defaultOptions.at(i).second.toString().data());
m_list_widgets.append(comboBoxCreation);
m_list_getOpt.append(QPair<int, const void*>(id, opt));
// iniRead(md5(opt->title), id, comboBoxCreation);
if(ind == -1)
init.val = m_list_defaultOptions.at(i).second;
else
init.val = QVariant(QString::fromStdString(schemes_->schemes[scheme].opts[ind].val));
comboBoxCreation->setCurrentText(init.val.toString());
connect(comboBoxCreation, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked()));
break;
}
}
break;
}
case SANE_TYPE_BUTTON:
{
QPushButton* pushButton = new QPushButton(this);
pushButton->setText(opt->title);
pushButton->setToolTip(opt->desc);
int id = i + 1;
pushButton->setProperty("controls_id", id);
hlayoutOkAndCancel->insertWidget(0, pushButton, 0, Qt::AlignRight);
connect(pushButton, SIGNAL(clicked(bool)), this, SLOT(slot_pushButtonClicked()));
init.opt = -1;
break;
}
case SANE_TYPE_GROUP:
{
if (isBegin)
{
scrollArea->setWindowTitle(opt->title);
isBegin = false;
}else{
scrollArea->setWidget(widget);
tabWidgetCreation->addTab(scrollArea, scrollArea->windowTitle());
scrollArea = new QScrollArea;
scrollArea->setWidgetResizable(true);
scrollArea->setWindowTitle(opt->title);
layout = new QFormLayout;
widget = new QWidget;
widget->setLayout(layout);
}
m_list_widgets.append(nullptr);
init.opt = -1;
break;
}
} //switch(opt->type)
if(init.opt != -1)
init_vals_.push_back(init);
} //for
updateUIStatus();
scrollArea->setWidget(widget);
tabWidgetCreation->addTab(scrollArea, scrollArea->windowTitle());
}
void hg_settingdialog::refresh_control_value(int op_id)
{
QVector<QWidget*> ctrls = find_control(op_id);
if(ctrls.empty())
return;
const SANE_Option_Descriptor* opt = (const SANE_Option_Descriptor*)m_list_defaultOptions.at(op_id - 1).first;
if(opt->type == SANE_TYPE_BOOL)
{
for(size_t i = 0; i < (size_t)ctrls.size(); ++i)
{
QCheckBox* cb = qobject_cast<QCheckBox*>(ctrls[i]);
if(cb)
{
disconnect(cb, SIGNAL(stateChanged(int)), this, SLOT(slot_checkedClicked()));
cb->setChecked(m_list_defaultOptions.at(op_id - 1).second.toBool());
connect(cb, SIGNAL(stateChanged(int)), this, SLOT(slot_checkedClicked()));
break;
}
}
}
else if(opt->type == SANE_TYPE_INT)
{
for(size_t i = 0; i < (size_t)ctrls.size(); ++i)
{
QSlider* slider = qobject_cast<QSlider*>(ctrls[i]);
if(slider)
{
disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int)));
slider->setValue(m_list_defaultOptions.at(op_id - 1).second.toInt());
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int)));
}
else
{
QSpinBox* spin = qobject_cast<QSpinBox*>(ctrls[i]);
if(spin)
{
disconnect(spin, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int)));
spin->setValue(m_list_defaultOptions.at(op_id - 1).second.toInt());
connect(spin, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int)));
}
}
}
}
else if(opt->type == SANE_TYPE_FIXED)
{
double val = SANE_UNFIX(m_list_defaultOptions.at(op_id - 1).second.toInt());
QSlider *slider = NULL;
QDoubleSpinBox* spin = NULL;
for(size_t i = 0; i < (size_t)ctrls.size(); ++i)
{
if(!slider)
{
slider = qobject_cast<QSlider*>(ctrls[i]);
if(slider)
disconnect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int)));
}
if(!spin)
{
spin = qobject_cast<QDoubleSpinBox*>(ctrls[i]);
if(spin)
disconnect(spin, SIGNAL(valueChanged(double)), this, SLOT(slot_spinBoxClicked(double)));
}
}
if(slider)
slider->setValue(val * 100);
if(spin)
spin->setValue(val);
if(slider)
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slot_sliderClicked(int)));
if(spin)
connect(spin, SIGNAL(valueChanged(double)), this, SLOT(slot_spinBoxClicked(double)));
}
else if(opt->type == SANE_TYPE_STRING)
{
for(size_t i = 0; i < (size_t)ctrls.size(); ++i)
{
QComboBox* comb = qobject_cast<QComboBox*>(ctrls[i]);
if(comb)
{
disconnect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked()));
comb->setCurrentText(m_list_defaultOptions.at(op_id - 1).second.toString());
connect(comb, SIGNAL(currentTextChanged(const QString)), this, SLOT(slot_string_list_comboBoxClicked()));
}
else
{
QLineEdit* edit = qobject_cast<QLineEdit*>(ctrls[i]);
if(edit)
{
disconnect(edit, SIGNAL(textChanged(const QString&)), this, SLOT(slot_lineEditInput()));
edit->setText(m_list_defaultOptions.at(op_id - 1).second.toString());
connect(edit, SIGNAL(textChanged(const QString&)), this, SLOT(slot_lineEditInput()));
}
}
}
}
}
bool hg_settingdialog::is_covered(std::vector<OPTVAL>& org, std::vector<OPTVAL>& now)
{
bool yes = now.size() >= org.size();
if(yes)
{
for(size_t i = 0; i < org.size(); ++i)
{
std::vector<OPTVAL>::iterator it = std::find(now.begin(), now.end(), org[i].name);
if(it == now.end())
{
yes = false;
break;
}
}
}
return yes;
}
QVector<QWidget*> hg_settingdialog::find_control(int opt_num)
{
QVector<QWidget*> list_w;
for(int i = 0; i< m_list_widgets.size(); i++)
{
if (m_list_widgets.at(i) == nullptr) continue;
QWidget* w = m_list_widgets.at(i);
int id = w->property("controls_id").toInt();
if(opt_num == id)
list_w.append(w);
}
return list_w;
}
void hg_settingdialog::updateUIStatus()
{
updateOpt();
SANE_Int dev_options = 0;
sane_control_option(m_handle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
for(int id = 1, optons = dev_options; id < optons; id++)
{
QVector<QWidget*> list_widgets = find_control(id);
if (list_widgets.empty()) continue;
QWidget* widget = list_widgets.first();
if (widget == nullptr) continue;
QWidget* parentWidget = widget->parentWidget();
while (typeid(*(parentWidget->layout())) != typeid(QFormLayout))
{
widget = parentWidget;
parentWidget = widget->parentWidget();
}
QFormLayout* layout = reinterpret_cast<QFormLayout*>(parentWidget->layout());
const SANE_Option_Descriptor* opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_defaultOptions.at(id - 1).first);
refresh_control_value(id);
if((opt->cap & SANE_CAP_INACTIVE) == SANE_CAP_INACTIVE)
{
QWidget* w_label = layout->labelForField(widget);
if(w_label != nullptr)
w_label->hide();
widget->setVisible(false);
}else{
QWidget* w_label = layout->labelForField(widget);
if(w_label != nullptr)
w_label->show();
widget->setVisible(true);
}
}
// Temporarily block the multi-stream output function
QVector<QWidget*> list_w;
for(int i = 0; i< m_list_widgets.size(); i++)
{
if (m_list_widgets.at(i) == nullptr) continue;
QWidget* w = m_list_widgets.at(i);
int id = w->property("controls_id").toInt();
const SANE_Option_Descriptor* opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_defaultOptions.at(id - 1).first);
if(strcmp(opt->title, "24位彩色图像-多流输出") == 0)
{
QFormLayout* layout = reinterpret_cast<QFormLayout*>(w->parentWidget()->layout());
QWidget* w_label = layout->labelForField(w);
if(w_label != nullptr)
w_label->hide();
w->hide();
}
}
}
void hg_settingdialog::slot_checkedClicked()
{
QCheckBox *checkBox = qobject_cast<QCheckBox*>(sender());
SANE_Int id = checkBox->property("controls_id").toInt();
SANE_Bool checkBoxcurrentState = checkBox->isChecked();
const SANE_Option_Descriptor* opt = nullptr;
for(int i = 0; i < m_list_getOpt.size(); i++)
if (m_list_getOpt.at(i).first == id)
{
opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
break;
}
m_list_IdValueTitle.append(QPair<QPair<int, QVariant>, QString>(QPair<int, QVariant>(id, checkBoxcurrentState), md5(opt->title)));
SANE_Int method = 0;
sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, &checkBoxcurrentState, &method);
if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS)
updateUIStatus();
else if(method & SANE_INFO_INEXACT)
checkBox->setCheckState(checkBoxcurrentState ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
std::vector<CHANGEDOPT>::iterator it =
std::find(changed_opts_.begin(), changed_opts_.end(), (int)id);
if(it == changed_opts_.end())
{
CHANGEDOPT co;
co.opt = id;
co.val = QVariant((bool)checkBoxcurrentState);
changed_opts_.push_back(co);
}
else {
it->val = QVariant((bool)checkBoxcurrentState);
}
}
void hg_settingdialog::slot_string_list_comboBoxClicked()
{
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
SANE_Int id = comboBox->property("controls_id").toInt();
std::string comboBoxcurrentItem(comboBox->currentText().toUtf8());
const SANE_Option_Descriptor* opt = nullptr;
for(int i = 0; i < m_list_getOpt.size(); i++)
if (m_list_getOpt.at(i).first == id)
{
opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
break;
}
m_list_IdValueTitle.append(QPair<QPair<int, QVariant>, QString>(QPair<int, QVariant>(id, &comboBoxcurrentItem.at(0)), md5(opt->title)));
SANE_Int method = 0;
SANE_String buf = (SANE_String)malloc(opt->size * 2 + 4);
strcpy(buf, comboBoxcurrentItem.c_str());
sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, buf, &method);
if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS)
updateUIStatus();
else if(method & SANE_INFO_INEXACT)
comboBox->setCurrentText(QString::fromStdString(buf));
std::vector<CHANGEDOPT>::iterator it =
std::find(changed_opts_.begin(), changed_opts_.end(), (int)id);
if(it == changed_opts_.end())
{
CHANGEDOPT co;
co.opt = id;
co.val = QVariant(buf);
changed_opts_.push_back(co);
}
else {
it->val = QVariant(buf);
}
free(buf);
}
void hg_settingdialog::slot_pushButtonClicked()
{
QPushButton *pushButton = qobject_cast<QPushButton*>(sender());
SANE_Int id = pushButton->property("controls_id").toInt(),
after = 0;
id = sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, NULL, &after);
if((after & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS)
updateUIStatus();
}
void hg_settingdialog::slot_word_list_comboBoxClicked(int value)
{
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
SANE_Int id = comboBox->property("controls_id").toInt();
SANE_Int temp = value;
const SANE_Option_Descriptor* opt = nullptr;
for(int i = 0; i < m_list_getOpt.size(); i++)
if (m_list_getOpt.at(i).first == id)
{
opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
break;
}
m_list_IdValueTitle.append(QPair<QPair<int, QVariant>, QString>(QPair<int, QVariant>(id, temp), md5(opt->title)));
SANE_Int method = 0;
sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, &temp, &method);
if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS)
updateUIStatus();
else if(method & SANE_INFO_INEXACT)
{
char buf[20];
sprintf(buf, "%d", temp);
comboBox->setCurrentText(QString::fromStdString(buf));
}
std::vector<CHANGEDOPT>::iterator it =
std::find(changed_opts_.begin(), changed_opts_.end(), (int)id);
if(it == changed_opts_.end())
{
CHANGEDOPT co;
co.opt = id;
co.val = QVariant(temp);
changed_opts_.push_back(co);
}
else {
it->val = QVariant(temp);
}
}
void hg_settingdialog::slot_sliderClicked(int value)
{
QSlider *slider = qobject_cast<QSlider*>(sender());
SANE_Int id = slider->property("controls_id").toInt();
const SANE_Option_Descriptor* opt = nullptr;
for(int i = 0; i < m_list_getOpt.size(); i++)
if (m_list_getOpt.at(i).first == id)
{
opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
break;
}
QAbstractSpinBox* spin = nullptr;
for(int i = 0; i < m_list_sliderSpinbox.size(); i++)
if (m_list_sliderSpinbox.at(i).first == slider)
{
spin = reinterpret_cast<QAbstractSpinBox*>(m_list_sliderSpinbox.at(i).second);
break;
}
if (spin != nullptr)
{
SANE_Int val = value, method = 0;
bool db_val = false;
if (typeid(*spin) == typeid(QSpinBox))
{
QSpinBox* spin_ = reinterpret_cast<QSpinBox*>(spin);
spin_->setValue(value);
m_list_IdValueTitle.append(QPair<QPair<int, QVariant>, QString>(QPair<int, QVariant>(id, val), md5(opt->title)));
}
else
{
QDoubleSpinBox* spin_ = reinterpret_cast<QDoubleSpinBox*>(spin);
double temp = value * spin_->singleStep();
if(temp != spin_->value())
spin_->setValue(temp);
val = SANE_FIX(temp);
db_val = true;
m_list_IdValueTitle.append(QPair<QPair<int, QVariant>, QString>(QPair<int, QVariant>(id, temp), md5(opt->title)));
}
sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, &val, &method);
if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS)
updateUIStatus();
else if(method & SANE_INFO_INEXACT)
{
if(db_val)
{
QDoubleSpinBox* spin_ = reinterpret_cast<QDoubleSpinBox*>(spin);
double v = SANE_UNFIX(val);
spin_->setValue(v);
slider->setValue(spin_->value() / spin_->singleStep());
}
else {
QSpinBox* spin_ = reinterpret_cast<QSpinBox*>(spin);
spin_->setValue(val);
slider->setValue(spin_->value() / spin_->singleStep());
}
}
std::vector<CHANGEDOPT>::iterator it =
std::find(changed_opts_.begin(), changed_opts_.end(), (int)id);
if(it == changed_opts_.end())
{
CHANGEDOPT co;
co.opt = id;
if(db_val)
co.val = QVariant(SANE_UNFIX(val));
else
co.val = QVariant(val);
changed_opts_.push_back(co);
}
else {
if(db_val)
it->val = QVariant(SANE_UNFIX(val));
else
it->val = QVariant(val);
}
}
}
void hg_settingdialog::slot_doubleSpinboxClicked(double value)
{
QDoubleSpinBox* spinBox = qobject_cast<QDoubleSpinBox*>(sender());
QAbstractSlider* slider = nullptr;
int id = spinBox->property("controls_id").toInt();
for (int i = 0; i < m_list_sliderSpinbox.size(); i++)
if (m_list_sliderSpinbox.at(i).second == spinBox)
{
slider = reinterpret_cast<QAbstractSlider*>(m_list_sliderSpinbox.at(i).first);
break;
}
if(slider != nullptr)
{
int temp = static_cast<int>(value / spinBox->singleStep() + 0.5);
QSlider* slider_ = reinterpret_cast<QSlider*>(slider);
if (slider_->value() != temp)
slider_->setValue(temp);
}
std::vector<CHANGEDOPT>::iterator it =
std::find(changed_opts_.begin(), changed_opts_.end(), (int)id);
if(it == changed_opts_.end())
{
CHANGEDOPT co;
co.opt = id;
co.val = value;
changed_opts_.push_back(co);
}
else {
it->val = value;
}
}
void hg_settingdialog::slot_spinBoxClicked(int value)
{
QSpinBox* spinBox = qobject_cast<QSpinBox*>(sender());
int id = spinBox->property("controls_id").toInt();
const SANE_Option_Descriptor* opt = nullptr;
for(int i = 0; i < m_list_getOpt.size(); i++)
if (m_list_getOpt.at(i).first == id)
{
opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
break;
}
QAbstractSlider* slider = nullptr;
for (int i = 0; i < m_list_sliderSpinbox.size(); i++)
if (m_list_sliderSpinbox.at(i).second == spinBox)
{
slider = reinterpret_cast<QAbstractSlider*>(m_list_sliderSpinbox.at(i).first);
break;
}
if(slider == nullptr)
{
SANE_Int temp = value;
m_list_IdValueTitle.append(QPair<QPair<int, QVariant>, QString>(QPair<int, QVariant>(id, temp), md5(opt->title)));
SANE_Int method = 0;
sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, &temp, &method);
if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS)
updateUIStatus();
else if(value != temp)
{
disconnect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int)));
spinBox->setValue(temp);
connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(slot_spinBoxClicked(int)));
}
value = temp;
}else
{
QSlider* slider_ = reinterpret_cast<QSlider*>(slider);
slider_->setValue(spinBox->value());
}
std::vector<CHANGEDOPT>::iterator it =
std::find(changed_opts_.begin(), changed_opts_.end(), (int)id);
if(it == changed_opts_.end())
{
CHANGEDOPT co;
co.opt = id;
co.val = value;
changed_opts_.push_back(co);
}
else {
it->val = value;
}
}
void hg_settingdialog::slot_lineEditInput()
{
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(sender());
int id = lineEdit->property("controls_id").toInt();
std::string lineEditCurrentText(lineEdit->text().toUtf8());
const SANE_Option_Descriptor* opt = nullptr;
for(int i = 0; i < m_list_getOpt.size(); i++)
if (m_list_getOpt.at(i).first == id)
{
opt = reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
break;
}
m_list_IdValueTitle.append(QPair<QPair<int, QVariant>, QString>(QPair<int, QVariant>(id, &lineEditCurrentText.at(0)), md5(opt->title)));
SANE_Int method = 0;
void *buf = NULL;
SANE_Int nv = 0;
if(opt->type == SANE_TYPE_INT)
{
nv = atoi(lineEditCurrentText.c_str());
buf = &nv;
}
else if(opt->type == SANE_TYPE_FIXED)
{
nv = SANE_FIX(atof(lineEditCurrentText.c_str()));
buf = &nv;
}
else
{
buf = malloc(opt->size * 2 + 4);
strcpy((char*)buf, lineEditCurrentText.c_str());
}
sane_control_option(m_handle, id, SANE_ACTION_SET_VALUE, buf, &method);
if((method & SANE_INFO_RELOAD_OPTIONS) == SANE_INFO_RELOAD_OPTIONS)
updateUIStatus();
else if(method & SANE_INFO_INEXACT)
{
char mem[20], *v = mem;
if(opt->type == SANE_TYPE_INT)
sprintf(mem, "%d", nv);
else if(opt->type == SANE_TYPE_FIXED)
sprintf(mem, "%f", SANE_UNFIX(nv));
else
v = (char*)buf;
lineEdit->setText(QString::fromStdString(v));
}
QVariant changed;
if(opt->type == SANE_TYPE_INT)
changed = QVariant(nv);
else if(opt->type == SANE_TYPE_FIXED)
changed = QVariant(SANE_UNFIX(nv));
else
{
changed = QVariant((char*)buf);
free(buf);
}
std::vector<CHANGEDOPT>::iterator it =
std::find(changed_opts_.begin(), changed_opts_.end(), (int)id);
if(it == changed_opts_.end())
{
CHANGEDOPT co;
co.opt = id;
co.val = changed;
changed_opts_.push_back(co);
}
else {
it->val = changed;
}
}
void hg_settingdialog::slot_buttonOkClicked()
{
save_ = true;
close();
}
void hg_settingdialog::slot_buttonCancelClicked()
{
close();
}
void hg_settingdialog::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Escape) {
e->ignore();
}
else {
QDialog::keyPressEvent(e);
}
}
int hg_settingdialog::get_changed_items(void)
{
return changed_count_;
}
void hg_settingdialog::iniWrite(QString title, int id, QVariant value)
{
(void)title;
(void)id;
(void)value;
// m_qstrFileName = QCoreApplication::applicationDirPath() + "/config.ini";
// m_configIniWrite = new QSettings(m_qstrFileName, QSettings::IniFormat);
// m_configIniWrite->setIniCodec(QTextCodec::codecForName("UTF-8"));
// m_configIniWrite->setValue(title + "/id", id);
// m_configIniWrite->setValue(title + "/value", value);
// delete m_configIniWrite;
// m_configIniWrite = nullptr;
}
void hg_settingdialog::iniRead(QString title, int id, QWidget *w)
{
(void)title;
(void)id;
(void)w;
// m_configIniRead = new QSettings("config.ini", QSettings::IniFormat);
// m_configIniRead->setIniCodec(QTextCodec::codecForName("UTF-8"));
// int id_ini = m_configIniRead->value(title + "/id").toInt();
// QVariant value = m_configIniRead->value(title + "/value");
// if(id_ini == id)
// {
// if(typeid(*w) == typeid(QCheckBox))
// reinterpret_cast<QCheckBox*>(w)->setChecked(value.toBool());
// else if(typeid(*w) == typeid(QSlider))
// reinterpret_cast<QSlider*>(w)->setValue(value.toInt());
// else if(typeid(*w) == typeid(QSpinBox))
// reinterpret_cast<QSpinBox*>(w)->setValue(value.toInt());
// else if(typeid(*w) == typeid(QDoubleSpinBox))
// reinterpret_cast<QDoubleSpinBox*>(w)->setValue(value.toDouble());
// else if(typeid(*w) == typeid(QComboBox))
// reinterpret_cast<QComboBox*>(w)->setCurrentText(value.toString());
// }
// delete m_configIniRead;
// m_configIniRead = nullptr;
}
//生成UTF-8编码的MD5值
QString hg_settingdialog::md5(QString key)
{
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(key.toUtf8());
return QString(md5.result().toHex());
}
const void* hg_settingdialog::find_option_description(int id)
{
for(int i = 0; i < m_list_getOpt.size(); i++)
{
if (m_list_getOpt.at(i).first == id)
return reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
}
return nullptr;
}
const void* hg_settingdialog::find_option_description(const std::string& title, int* id)
{
for(int i = 0; i < m_list_getOpt.size(); i++)
{
std::string t((reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second))->title);
if (title == t)
{
if(id)
*id = m_list_getOpt.at(i).first;
return reinterpret_cast<const SANE_Option_Descriptor*>(m_list_getOpt.at(i).second);
}
}
return nullptr;
}
QVariant hg_settingdialog::find_default_value(int id)
{
std::vector<CHANGEDOPT>::iterator it = std::find(default_vals_.begin(), default_vals_.end(), id);
if(it == default_vals_.end())
return QVariant();
else
return it->val;
}
bool hg_settingdialog::is_equal_default_value(const CHANGEDOPT& opt, int type)
{
QVariant qv = find_default_value(opt.opt);
if(qv.isNull())
return false;
if(type == SANE_TYPE_INT)
return opt.val.toInt() == qv.toInt();
if(type == SANE_TYPE_FIXED)
return IS_DOUBLE_EQUAL(opt.val.toDouble(), qv.toDouble());
if(type == SANE_TYPE_BOOL)
return opt.val.toBool() == qv.toBool();
if(type == SANE_TYPE_STRING)
return qv.toString() == opt.val.toString();
return true;
}
bool hg_settingdialog::set_opt_value_for_OPTVAL(QVariant val, int type, OPTVAL* ov)
{
char buf[40];
if(type == SANE_TYPE_INT)
{
ov->type = "int";
sprintf(buf, "%d", val.toInt());
ov->val = buf;
}
else if(type == SANE_TYPE_BOOL)
{
ov->type = "bool";
ov->val = val.toBool() ? "true" : "false";
}
else if(type == SANE_TYPE_FIXED)
{
sprintf(buf, "%f", val.toDouble());
ov->type = "float";
ov->val = buf;
}
else if(type == SANE_TYPE_STRING)
{
ov->type = "string";
ov->val = val.toString().toStdString();
}
else {
return false;
}
return true;
}
void hg_settingdialog::on_select_scheme(int scheme_ind, bool apply_to_dev)
{
OPTSCHEME *schm = NULL;
changed_opts_.clear();
if(scheme_ind >= 0 && scheme_ind + 1 < (int)schemes_->schemes.size())
{
scheme_ind++;
schm = &schemes_->schemes[scheme_ind];
for(size_t i = 0; i < schemes_->schemes[scheme_ind].opts.size(); ++i)
{
CHANGEDOPT co;
const SANE_Option_Descriptor* opt = (const SANE_Option_Descriptor*)find_option_description(schemes_->schemes[scheme_ind].opts[i].name, &co.opt);
if(opt)
{
bool ok = true;
if(opt->type == SANE_TYPE_BOOL)
co.val = QVariant(schemes_->schemes[scheme_ind].opts[i].val == "true");
else if(opt->type == SANE_TYPE_INT)
co.val = QVariant(atoi(schemes_->schemes[scheme_ind].opts[i].val.c_str()));
else if(opt->type == SANE_TYPE_FIXED)
co.val = QVariant(atof(schemes_->schemes[scheme_ind].opts[i].val.c_str()));
else if(opt->type == SANE_TYPE_STRING)
co.val = QVariant(QString::fromStdString(schemes_->schemes[scheme_ind].opts[i].val));
else
ok = false;
if(ok)
changed_opts_.push_back(co);
}
}
}
if(apply_to_dev)
{
if(scheme_ind >= 0 && scheme_ind + 1 < (int)schemes_->schemes.size())
schemes_->cur_scheme = scheme_ind;
else
schemes_->cur_scheme = -1;
apply_settings(schm);
updateUIStatus();
}
}
void hg_settingdialog::closeEvent(QCloseEvent* e)
{
if(e->type() == QEvent::Close) // consider as cancel ...
{
if(save_)
save_scheme();
else
cancel_setting();
}
e->accept();
}
int hg_settingdialog::find_covered_scheme(OPTSCHEME& scheme)
{
for(int ind = 1; ind < (int)schemes_->schemes.size(); ++ind)
{
if(is_covered(schemes_->schemes[ind].opts, scheme.opts))
{
schemes_->schemes.erase(schemes_->schemes.begin() + ind);
return ind - 1;
}
}
return schemes_->schemes.size() - 1;
}
void hg_settingdialog::save_scheme(void)
{
OPTSCHEME src;
int names = 0;
OPTVAL ov;
OPTSCHEME os;
const SANE_Option_Descriptor *opt = nullptr;
if(cur_ind_ >= 0 && cur_ind_ + 1 < (int)schemes_->schemes.size())
src = schemes_->schemes[cur_ind_ + 1];
for(size_t i = 0; i < changed_opts_.size(); ++i)
{
opt = (const SANE_Option_Descriptor*)find_option_description(changed_opts_[i].opt);
if(!opt)
continue;
if(is_equal_default_value(changed_opts_[i], opt->type))
continue;
if(!set_opt_value_for_OPTVAL(changed_opts_[i].val, opt->type, &ov))
continue;
// bool existing = false;
ov.name = opt->title;
// for(size_t i = 0; i < src.opts.size(); ++i)
// {
// if(ov == src.opts[i])
// {
// existing = true;
// break;
// }
// }
// if(existing)
// continue;
os.opts.push_back(ov);
if(names < 3)
{
if(opt->type == SANE_TYPE_STRING)
{
if(!os.name.empty())
os.name += " + ";
os.name += ov.val;
names++;
}
}
}
if(os == src)
{
if(changed_count_ == 0)
changed_count_ = schemes_->cur_scheme != cur_ind_;
schemes_->cur_scheme = cur_ind_;
}
else if(os.opts.size())
{
char buf[20];
int ind = 1;
if(os.name.empty())
os.name = os.opts[0].name + "(" + os.opts[0].val + ")";
buf[0] = 0;
while(std::find(schemes_->schemes.begin(), schemes_->schemes.end(), os.name + buf)
!= schemes_->schemes.end())
{
sprintf(buf, "-%d", ind++);
}
os.name += buf;
if (cur_ind_ >= 0 && cur_ind_ + 1 < (int)schemes_->schemes.size())
{
QString title(tr("save the configuration"));
QString text(tr("The Settings you just set are in the original configuration \""));
text += QString::fromStdString(schemes_->schemes[cur_ind_ + 1].name);
text += tr("\" changed on the basis,Please select overwrite this configuration or add a new one?\nYes: cover \"") + QString::fromStdString(schemes_->schemes[cur_ind_ + 1].name);
text += tr("\"\nNo: add new configuration") + QString::fromStdString(os.name);
QMessageBox msg(QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::No, this);
msg.setButtonText(QMessageBox::Yes, tr("yes"));
msg.setButtonText(QMessageBox::No, tr("no"));
msg.exec();
if (msg.clickedButton() == msg.button(QMessageBox::Yes))
{
os.name = schemes_->schemes[cur_ind_ + 1].name;
schemes_->schemes.erase(schemes_->schemes.begin() + cur_ind_ + 1);
}
else
cur_ind_ = schemes_->schemes.size() - 1;
}
else
cur_ind_ = find_covered_scheme(os); // schemes_->schemes.size() - 1;
schemes_->schemes.insert(schemes_->schemes.begin() + cur_ind_ + 1, os);
schemes_->cur_scheme = cur_ind_;
changed_count_++;
}
else
{
if(changed_count_ == 0)
changed_count_ = schemes_->cur_scheme != -1;
schemes_->cur_scheme = -1; // no option has changed, means default setting
}
}
void hg_settingdialog::cancel_setting(void)
{
// restore changed value ...
for(size_t i = 0; i < changed_opts_.size(); ++i)
{
const SANE_Option_Descriptor* opt = (const SANE_Option_Descriptor*)find_option_description(changed_opts_[i].opt);
if(!opt)
continue;
std::vector<CHANGEDOPT>::iterator it = std::find(init_vals_.begin(), init_vals_.end(), changed_opts_[i].opt);
if(it == init_vals_.end())
continue;
SANE_Bool vb = SANE_TRUE;
SANE_Int vn = 0, after;
SANE_String str = (SANE_String)malloc(opt->size * 2 + 4);
void* val = str;
bool go = true;
//bzero(str, opt->size * 2 + 4);
memset(str, 0, opt->size * 2 + 4);
if(opt->type == SANE_TYPE_BOOL)
{
vb = it->val.toBool();
val = &vb;
if(changed_opts_[i].val.toBool() == (bool)vb)
go = false;
}
else if(opt->type == SANE_TYPE_INT)
{
vn = it->val.toInt();
val = &vn;
if(changed_opts_[i].val.toInt() == vn)
go = false;
}
else if(opt->type == SANE_TYPE_FIXED)
{
vn = SANE_FIX(it->val.toDouble());
val = &vn;
if(IS_DOUBLE_EQUAL(changed_opts_[i].val.toDouble(), it->val.toDouble()))
go = false;
}
else {
if(changed_opts_[i].val.toString() == it->val.toString())
go = false;
else
strcpy(str, it->val.toString().toStdString().c_str());
val = str;
}
if(go)
sane_control_option(m_handle, changed_opts_[i].opt, SANE_ACTION_SET_VALUE, val, &after);
// here need not to check flags in 'after' and update UIs, for this dialog will close ^_^
free(str);
}
}
int hg_settingdialog::find_opt_setting(const char* name, const std::vector<OPTVAL>& opts)
{
for(size_t i = 0; i < opts.size(); ++i)
{
if(opts[i].name.compare(name) == 0)
return i;
}
return -1;
}
int hg_settingdialog::apply_setting(const SANE_Option_Descriptor* desc, int opt_ind, OPTVAL* val)
{
SANE_Int after = 0;
SANE_Status ret = SANE_STATUS_GOOD;
if(desc->type == SANE_TYPE_INT)
{
SANE_Int v = atoi(val->val.c_str());
ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, &v, &after);
if(after & SANE_INFO_INEXACT)
{
char buf[20];
sprintf(buf, "%d", v);
val->val = buf;
}
}
else if(desc->type == SANE_TYPE_BOOL)
{
SANE_Bool v = val->val == "true";
ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, &v, &after);
if(after & SANE_INFO_INEXACT)
{
val->val = v ? "true" : "false";
}
}
else if(desc->type == SANE_TYPE_FIXED)
{
SANE_Fixed v = SANE_FIX(atof(val->val.c_str()));
ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, &v, &after);
if(after & SANE_INFO_INEXACT)
{
char buf[20];
double dv = SANE_UNFIX(v);
sprintf(buf, "%f", dv);
val->val = buf;
}
}
else if(desc->type == SANE_TYPE_STRING)
{
SANE_String v = (SANE_String)malloc(desc->size);
strcpy(v, val->val.c_str());
ret = sane_control_option(m_handle, opt_ind, SANE_ACTION_SET_VALUE, v, &after);
if(after & SANE_INFO_INEXACT)
val->val = v;
free(v);
}
return ret;
}
int hg_settingdialog::apply_settings(OPTSCHEME* scheme)
{
SANE_Int count = 0, none = 0;
none = sane_io_control(m_handle, IO_CTRL_CODE_RESTORE_SETTINGS, NULL, NULL);
if(!scheme)
return none;
sane_control_option(m_handle, 0, SANE_ACTION_GET_VALUE, &count, &none);
none = 0;
for(int i = 1; i < count; ++i)
{
const SANE_Option_Descriptor* desc = sane_get_option_descriptor(m_handle, i);
if(!desc)
continue;
if(desc->type == SANE_TYPE_GROUP ||
desc->type == SANE_TYPE_BUTTON)
continue;
int opt = find_opt_setting(desc->title, scheme->opts);
if(opt == -1)
continue;
// apply ...
none = apply_setting(desc, i, &scheme->opts[opt]);
if(none != SANE_STATUS_GOOD)
{
sane_io_control(m_handle, IO_CTRL_CODE_RESTORE_SETTINGS, NULL, NULL);
break;
}
}
return none;
}
void hg_settingdialog::on_scheme_triggered(QAction* act)
{
bool enabled = false;
edit_name_->setText(tr(""));
if(act)
{
std::vector<OPTSCHEME>::iterator it = std::find(schemes_->schemes.begin(), schemes_->schemes.end(), act->text().toStdString());
enabled = it != schemes_->schemes.end();
edit_name_->setText(act->text());
}
edit_name_->setCursorPosition(0);
edit_name_->setEnabled(enabled);
rename_->setEnabled(enabled);
apply_->setEnabled(enabled);
del_this_->setEnabled(enabled);
del_all_->setEnabled(enabled);
int id = -1;
QString info(tr(""));
find_current_scheme_menu(&id);
if(id >= 0 && id + 1 < (int)schemes_->schemes.size())
{
const std::vector<OPTVAL>& opts = schemes_->schemes[id + 1].opts;
for(size_t i = 0; i < opts.size(); ++i)
{
info += tr("<h6><b>") + QString::fromStdString(opts[i].name) + tr(":</b></h6>");
info += tr("<p> ") + QString::fromStdString(opts[i].val) + tr("</p>");
}
}
sketch_->setHtml(info);
}
void hg_settingdialog::slot_pushButton_scheme_management(void)
{
QPushButton* btn = qobject_cast<QPushButton*>(sender());
if(btn == rename_)
{
int id = 0;
QAction *act = find_current_scheme_menu(&id);
if(act)
act->setText(edit_name_->text());
if(id >= 0)
schemes_->schemes[id + 1].name = edit_name_->text().toStdString();
changed_count_++;
}
else if(btn == apply_)
{
find_current_scheme_menu(&cur_ind_);
on_select_scheme(cur_ind_);
changed_count_++;
}
else if(btn == del_this_)
{
int id = 0;
QAction *act = find_current_scheme_menu(&id);
if(!act)
return;
QMessageBox msg(QMessageBox::Question, tr("be sure to delete the configuration"),
tr("Are you sure you want to delete the configuration \"") + act->text() + tr("\" ?"), QMessageBox::Yes | QMessageBox::No, this);
msg.setButtonText(QMessageBox::Yes, tr("yes"));
msg.setButtonText(QMessageBox::No, tr("no"));
msg.exec();
if (msg.clickedButton() != msg.button(QMessageBox::Yes))
return;
if(id >= 0)
{
QList<QAction*> acts = top_menu_->actions();
for(size_t i = 0; i < (size_t)acts.size(); ++i)
{
if(acts[i]->text().toStdString() == schemes_->schemes[id + 1].name)
{
top_menu_->removeAction(acts[i]);
break;
}
}
schemes_->schemes.erase(schemes_->schemes.begin() + id + 1);
if(top_menu_->actions().size() == 0)
{
QAction* acts = top_menu_->addAction(tr("No custom configuration was found"));
acts->setEnabled(false);
}
cur_ind_ = -1;
on_select_scheme(-1);
}
on_scheme_triggered(NULL);
changed_count_++;
}
else if(btn == del_all_)
{
QMessageBox msg(QMessageBox::Question, tr("be sure to delete the configuration"),
tr("Are you sure you want to delete the configuration?"), QMessageBox::Yes | QMessageBox::No, this);
msg.setButtonText(QMessageBox::Yes, tr("yes"));
msg.setButtonText(QMessageBox::No, tr("no"));
msg.exec();
if (msg.clickedButton() != msg.button(QMessageBox::Yes))
return;
schemes_->schemes.erase(schemes_->schemes.begin() + 1, schemes_->schemes.end());
QAction* acts = top_menu_->addAction(tr("No custom configuration was found"));
acts->setEnabled(false);
cur_ind_ = -1;
on_select_scheme(-1);
top_menu_->clear();
on_scheme_triggered(NULL);
changed_count_++;
}
}