1
/* ============================================================
3
* This file is part of the KDE project
6
* Description : Sane interface for KDE
8
* Copyright (C) 2009 by Kare Sars <kare dot sars at iki dot fi>
10
* This library is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2.1 of the License, or (at your option) version 3, or any
14
* later version accepted by the membership of KDE e.V. (or its
15
* successor approved by the membership of KDE e.V.), which shall
16
* act as a proxy defined in Section 6 of version 3 of the license.
18
* This library is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
* Lesser General Public License for more details.
23
* You should have received a copy of the GNU Lesser General Public
24
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
26
* ============================================================ */
28
#include "ksane_opt_combo.h"
29
#include "ksane_opt_combo.moc"
31
#include "labeled_combo.h"
34
#include <QtCore/QVarLengthArray>
43
static const char tmp_binary[] = "Binary";
45
KSaneOptCombo::KSaneOptCombo(const SANE_Handle handle, const int index)
46
: KSaneOption(handle, index), m_combo(0)
50
void KSaneOptCombo::createWidget(QWidget *parent)
54
m_widget = m_combo = new LabeledCombo(parent, "", QStringList());
56
m_widget->setToolTip(i18n(m_optDesc->desc));
57
connect(m_combo, SIGNAL(activated(int)), this, SLOT(comboboxChangedIndex(int)));
61
void KSaneOptCombo::readValue()
63
if (state() == STATE_HIDDEN) return;
65
// read that current value
66
QVarLengthArray<unsigned char> data(m_optDesc->size);
69
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
70
if (status != SANE_STATUS_GOOD) {
75
m_currentText = getSaneComboString(data.data());
77
if (m_combo->currentText() != m_currentText) {
78
m_combo->setCurrentText(m_currentText);
84
void KSaneOptCombo::readOption()
86
KSaneOption::readOption();
90
QString saved = m_combo->currentText();
92
m_strList = genComboStringList();
94
m_combo->setLabelText(i18n(m_optDesc->title));
95
m_combo->addItems(m_strList);
96
m_combo->setIcon(KIcon("color"), getSaneComboString((unsigned char*)SANE_VALUE_SCAN_MODE_COLOR));
97
m_combo->setIcon(KIcon("gray-scale"),
98
getSaneComboString((unsigned char*)SANE_VALUE_SCAN_MODE_GRAY));
99
m_combo->setIcon(KIcon("black-white"),
100
getSaneComboString((unsigned char*)SANE_VALUE_SCAN_MODE_LINEART));
101
// The epkowa/epson backend uses "Binary" which is the same as "Lineart"
102
m_combo->setIcon(KIcon("black-white"), i18n(tmp_binary));
104
// set the previous value
105
m_combo->setCurrentText(saved);
109
QStringList &KSaneOptCombo::genComboStringList()
114
switch (m_optDesc->type)
117
for (i=1; i<=m_optDesc->constraint.word_list[0]; ++i) {
118
m_strList += getSaneComboString((int)m_optDesc->constraint.word_list[i]);
121
case SANE_TYPE_FIXED:
122
for (i=1; i<=m_optDesc->constraint.word_list[0]; ++i) {
123
m_strList += getSaneComboString((float)SANE_UNFIX(m_optDesc->constraint.word_list[i]));
126
case SANE_TYPE_STRING:
128
while (m_optDesc->constraint.string_list[i] != 0) {
129
m_strList += getSaneComboString((unsigned char *)m_optDesc->constraint.string_list[i]);
134
m_strList += "NOT HANDELED";
139
QString KSaneOptCombo::getSaneComboString(int ival)
141
switch(m_optDesc->unit)
143
case SANE_UNIT_NONE: break;
144
case SANE_UNIT_PIXEL: return i18np("%1 Pixel","%1 Pixels", ival);
145
case SANE_UNIT_BIT: return i18np("%1 Bit","%1 Bits", ival);
146
case SANE_UNIT_MM: return i18np("%1 mm","%1 mm", ival);
147
case SANE_UNIT_DPI: return i18np("%1 DPI","%1 DPI", ival);
148
case SANE_UNIT_PERCENT: return i18np("%1 %","%1 %", ival);
149
case SANE_UNIT_MICROSECOND: return i18np("%1 µs","%1 µs", ival);
151
return QString::number(ival);
154
QString KSaneOptCombo::getSaneComboString(float fval)
156
switch(m_optDesc->unit)
158
case SANE_UNIT_NONE: break;
159
case SANE_UNIT_PIXEL: return i18ncp("Parameter and Unit","%1 Pixel", "%1 Pixels", fval);
160
case SANE_UNIT_BIT: return i18ncp("Parameter and Unit","%1 Bit","%1 Bits", fval);
161
case SANE_UNIT_MM: return i18nc("Parameter and Unit (Millimeter)","%1 mm", fval);
162
case SANE_UNIT_DPI: return i18nc("Parameter and Unit (Dots Per Inch)","%1 DPI", fval);
163
case SANE_UNIT_PERCENT: return i18nc("Parameter and Unit (Percentage)","%1 %", fval);
164
case SANE_UNIT_MICROSECOND: return i18nc("Parameter and Unit (Microseconds)","%1 µs", fval);
166
return QString::number(fval, 'F', 4);
169
QString KSaneOptCombo::getSaneComboString(unsigned char *data)
172
if (data == 0) return QString();
174
switch (m_optDesc->type)
177
return getSaneComboString((int)toSANE_Word(data));
178
case SANE_TYPE_FIXED:
179
return getSaneComboString((float)SANE_UNFIX(toSANE_Word(data)));
180
case SANE_TYPE_STRING:
181
tmp = i18n(reinterpret_cast<char*>(data));
182
tmp = tmp.simplified();
183
if (tmp.length() > 25) {
196
void KSaneOptCombo::comboboxChangedIndex(int i)
198
if (m_combo && (m_combo->currentText() == m_currentText)) {
202
unsigned char data[4];
205
switch (m_optDesc->type)
208
case SANE_TYPE_FIXED:
209
fromSANE_Word(data, m_optDesc->constraint.word_list[i+1]);
212
case SANE_TYPE_STRING:
213
dataPtr = (void *)m_optDesc->constraint.string_list[i];
216
kDebug() << "can not handle type:" << m_optDesc->type;
224
bool KSaneOptCombo::getMinValue(float &val)
226
if (state() == STATE_HIDDEN) return false;
227
switch (m_optDesc->type)
230
val = (float)m_optDesc->constraint.word_list[1];
231
for (int i=2; i<=m_optDesc->constraint.word_list[0]; i++) {
232
val = qMin((float)m_optDesc->constraint.word_list[i], val);
235
case SANE_TYPE_FIXED:
236
val = (float)SANE_UNFIX(m_optDesc->constraint.word_list[1]);
237
for (int i=2; i<=m_optDesc->constraint.word_list[0]; i++) {
238
val = qMin((float)SANE_UNFIX(m_optDesc->constraint.word_list[i]), val);
242
kDebug() << "can not handle type:" << m_optDesc->type;
248
bool KSaneOptCombo::getValue(float &val)
250
if (state() == STATE_HIDDEN) return false;
252
// read that current value
253
QVarLengthArray<unsigned char> data(m_optDesc->size);
256
status = sane_control_option (m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
257
if (status != SANE_STATUS_GOOD) {
258
kDebug() << m_optDesc->name << "sane_control_option returned" << status;
262
switch (m_optDesc->type)
265
val = (float)toSANE_Word(data.data());
267
case SANE_TYPE_FIXED:
268
val = SANE_UNFIX(toSANE_Word(data.data()));
271
kDebug() << "Type" << m_optDesc->type << "not supported!";
276
bool KSaneOptCombo::setValue(float value)
278
unsigned char data[4];
284
switch (m_optDesc->type)
287
tmp = (float)m_optDesc->constraint.word_list[minIndex];
288
minDiff = qAbs(value - tmp);
289
for (i=2; i<=m_optDesc->constraint.word_list[0]; ++i) {
290
tmp = (float)m_optDesc->constraint.word_list[i];
291
if (qAbs(value - tmp) < minDiff) {
292
minDiff = qAbs(value - tmp);
296
fromSANE_Word(data, m_optDesc->constraint.word_list[minIndex]);
299
return (minDiff < 1.0);
300
case SANE_TYPE_FIXED:
301
tmp = (float)SANE_UNFIX(m_optDesc->constraint.word_list[minIndex]);
302
minDiff = qAbs(value - tmp);
303
for (i=2; i<=m_optDesc->constraint.word_list[0]; ++i) {
304
tmp = (float)SANE_UNFIX(m_optDesc->constraint.word_list[i]);
305
if (qAbs(value - tmp) < minDiff) {
306
minDiff = qAbs(value - tmp);
310
fromSANE_Word(data, m_optDesc->constraint.word_list[minIndex]);
313
return (minDiff < 1.0);
315
kDebug() << "can not handle type:" << m_optDesc->type;
321
bool KSaneOptCombo::getValue(QString &val)
323
if (state() == STATE_HIDDEN) return false;
328
bool KSaneOptCombo::setValue(const QString &val)
330
if (state() == STATE_HIDDEN) return false;
331
if (val == m_currentText) return true;
333
unsigned char data[4];
341
switch (m_optDesc->type)
344
tmp = val.left(val.indexOf(' ')); // strip the unit
345
// accept float formating of the string
346
i = (int)(tmp.toFloat(&ok));
347
if (ok == false) return false;
348
fromSANE_Word(data, i);
351
case SANE_TYPE_FIXED:
352
tmp = val.left(val.indexOf(' ')); // strip the unit
353
f = tmp.toFloat(&ok);
354
if (ok == false) return false;
356
fromSANE_Word(data, fixed);
359
case SANE_TYPE_STRING:
361
while (m_optDesc->constraint.string_list[i] != 0) {
362
tmp = getSaneComboString((unsigned char *)m_optDesc->constraint.string_list[i]);
364
data_ptr = (void *)m_optDesc->constraint.string_list[i];
369
if (m_optDesc->constraint.string_list[i] == 0) return false;
372
kDebug() << "can only handle SANE_TYPE: INT, FIXED and STRING";
382
} // NameSpace KSaneIface