KSaneCore

listoption.cpp
1/*
2 * SPDX-FileCopyrightText: 2009 Kare Sars <kare dot sars at iki dot fi>
3 * SPDX-FileCopyrightText: 2014 Gregor Mitsch : port to KDE5 frameworks
4 *
5 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8#include "listoption.h"
9
10#include <QVarLengthArray>
11
12#include <ksanecore_debug.h>
13
14namespace KSaneCore
15{
16
17ListOption::ListOption(const SANE_Handle handle, const int index)
18 : BaseOption(handle, index)
19{
20 m_optionType = Option::TypeValueList;
21}
22
23void ListOption::readValue()
24{
25 if (BaseOption::state() == Option::StateHidden) {
26 return;
27 }
28
29 // read that current value
30 QVarLengthArray<unsigned char> data(m_optDesc->size);
31 SANE_Status status;
32 SANE_Int res;
33 status = sane_control_option(m_handle, m_index, SANE_ACTION_GET_VALUE, data.data(), &res);
34 if (status != SANE_STATUS_GOOD) {
35 return;
36 }
37
38 QVariant newValue;
39 switch (m_optDesc->type) {
40 case SANE_TYPE_INT:
41 newValue = static_cast<int>(toSANE_Word(data.data()));
42 break;
43 case SANE_TYPE_FIXED:
44 newValue = SANE_UNFIX(toSANE_Word(data.data()));
45 break;
46 case SANE_TYPE_STRING:
47 newValue = sane_i18n(reinterpret_cast<char *>(data.data()));
48 break;
49 default:
50 break;
51 }
52
53 if (newValue != m_currentValue) {
54 m_currentValue = newValue;
55 Q_EMIT valueChanged(m_currentValue);
56 }
57}
58
59void ListOption::readOption()
60{
61 beginOptionReload();
62 countEntries();
63 endOptionReload();
64}
65
66QVariantList ListOption::valueList() const
67{
68 int i;
69 QVariantList list;
70 list.reserve(m_entriesCount);
71
72 switch (m_optDesc->type) {
73 case SANE_TYPE_INT:
74 for (i = 1; i <= m_optDesc->constraint.word_list[0]; ++i) {
75 list << static_cast<int>(m_optDesc->constraint.word_list[i]);;
76 }
77 break;
78 case SANE_TYPE_FIXED:
79 for (i = 1; i <= m_optDesc->constraint.word_list[0]; ++i) {
80 list << SANE_UNFIX(m_optDesc->constraint.word_list[i]);
81 }
82 break;
83 case SANE_TYPE_STRING:
84 i = 0;
85 while (m_optDesc->constraint.string_list[i] != nullptr) {
86 list << sane_i18n(m_optDesc->constraint.string_list[i]);
87 i++;
88 }
89 break;
90 default :
91 qCDebug(KSANECORE_LOG) << "can not handle type:" << m_optDesc->type;
92 break;
93 }
94 return list;
95}
96
97QVariantList ListOption::internalValueList() const
98{
99 int i;
100 QVariantList list;
101 list.reserve(m_entriesCount);
102
103 switch (m_optDesc->type) {
104 case SANE_TYPE_INT:
105 for (i = 1; i <= m_optDesc->constraint.word_list[0]; ++i) {
106 list << static_cast<int>(m_optDesc->constraint.word_list[i]);;
107 }
108 break;
109 case SANE_TYPE_FIXED:
110 for (i = 1; i <= m_optDesc->constraint.word_list[0]; ++i) {
111 list << SANE_UNFIX(m_optDesc->constraint.word_list[i]);
112 }
113 break;
114 case SANE_TYPE_STRING:
115 i = 0;
116 while (m_optDesc->constraint.string_list[i] != nullptr) {
117 list << QString::fromLatin1(m_optDesc->constraint.string_list[i]);
118 i++;
119 }
120 break;
121 default :
122 qCDebug(KSANECORE_LOG) << "can not handle type:" << m_optDesc->type;
123 break;
124 }
125 return list;
126}
127
128bool ListOption::setValue(const QVariant &value)
129{
130 bool success = false;
131 if (value.userType() == QMetaType::QString) {
132 success = setValue(value.toString());
133 } else {
134 success = setValue(value.toDouble());
135 }
136
137 return success;
138}
139
140QVariant ListOption::minimumValue() const
141{
142 QVariant value;
143 if (BaseOption::state() == Option::StateHidden) {
144 return value;
145 }
146 double dValueMin;
147 int iValueMin;
148 switch (m_optDesc->type) {
149 case SANE_TYPE_INT:
150 iValueMin = static_cast<int>(m_optDesc->constraint.word_list[1]);
151 for (int i = 2; i <= m_optDesc->constraint.word_list[0]; i++) {
152 iValueMin = qMin(static_cast<int>(m_optDesc->constraint.word_list[i]), iValueMin);
153 }
154 value = iValueMin;
155 break;
156 case SANE_TYPE_FIXED:
157 dValueMin = SANE_UNFIX(m_optDesc->constraint.word_list[1]);
158 for (int i = 2; i <= m_optDesc->constraint.word_list[0]; i++) {
159 dValueMin = qMin(SANE_UNFIX(m_optDesc->constraint.word_list[i]), dValueMin);
160 }
161 value = dValueMin;
162 break;
163 default:
164 qCDebug(KSANECORE_LOG) << "can not handle type:" << m_optDesc->type;
165 return value;
166 }
167 return value;
168}
169
170QVariant ListOption::value() const
171{
172 if (BaseOption::state() == Option::StateHidden) {
173 return QVariant();
174 }
175 return m_currentValue;
176}
177
178bool ListOption::setValue(double value)
179{
180 unsigned char data[4];
181 double tmp;
182 double minDiff;
183 int i;
184 int minIndex = 1;
185
186 switch (m_optDesc->type) {
187 case SANE_TYPE_INT:
188 tmp = static_cast<double>(m_optDesc->constraint.word_list[minIndex]);
189 minDiff = qAbs(value - tmp);
190 for (i = 2; i <= m_optDesc->constraint.word_list[0]; ++i) {
191 tmp = static_cast<double>(m_optDesc->constraint.word_list[i]);
192 if (qAbs(value - tmp) < minDiff) {
193 minDiff = qAbs(value - tmp);
194 minIndex = i;
195 }
196 }
197 fromSANE_Word(data, m_optDesc->constraint.word_list[minIndex]);
198 writeData(data);
199 readValue();
200 return (minDiff < 1.0);
201 case SANE_TYPE_FIXED:
202 tmp = SANE_UNFIX(m_optDesc->constraint.word_list[minIndex]);
203 minDiff = qAbs(value - tmp);
204 for (i = 2; i <= m_optDesc->constraint.word_list[0]; ++i) {
205 tmp = SANE_UNFIX(m_optDesc->constraint.word_list[i]);
206 if (qAbs(value - tmp) < minDiff) {
207 minDiff = qAbs(value - tmp);
208 minIndex = i;
209 }
210 }
211 fromSANE_Word(data, m_optDesc->constraint.word_list[minIndex]);
212 writeData(data);
213 readValue();
214 return (minDiff < 1.0);
215 default:
216 qCDebug(KSANECORE_LOG) << "can not handle type:" << m_optDesc->type;
217 break;
218 }
219 return false;
220}
221
222QString ListOption::valueAsString() const
223{
224 if (BaseOption::state() == Option::StateHidden) {
225 return QString();
226 }
227 return m_currentValue.toString();
228}
229
230bool ListOption::setValue(const QString &value)
231{
232 if (BaseOption::state() == Option::StateHidden) {
233 return false;
234 }
235
236 unsigned char data[4];
237 void* data_ptr = nullptr;
238 SANE_Word fixed;
239 int i;
240 double d;
241 bool ok;
242 QString tmp;
243
244 switch (m_optDesc->type) {
245 case SANE_TYPE_INT:
246 i = value.toInt(&ok);
247 if (ok) {
248 fromSANE_Word(data, i);
249 data_ptr = data;
250 } else {
251 return false;
252 }
253
254 break;
255 case SANE_TYPE_FIXED:
256 d = value.toDouble(&ok);
257 if (ok) {
258 fixed = SANE_FIX(d);
259 fromSANE_Word(data, fixed);
260 data_ptr = data;
261 } else {
262 return false;
263 }
264
265 break;
266 case SANE_TYPE_STRING:
267 i = 0;
268 while (m_optDesc->constraint.string_list[i] != nullptr) {
269 tmp = QString::fromLatin1(m_optDesc->constraint.string_list[i]);
270 if (value != tmp) {
271 tmp = sane_i18n(m_optDesc->constraint.string_list[i]);
272 }
273 if (value == tmp) {
274 data_ptr = (void *)m_optDesc->constraint.string_list[i];
275 break;
276 }
277 i++;
278 }
279 if (m_optDesc->constraint.string_list[i] == nullptr) {
280 return false;
281 }
282 break;
283 default:
284 qCDebug(KSANECORE_LOG) << "can only handle SANE_TYPE: INT, FIXED and STRING";
285 return false;
286 }
287 writeData(data_ptr);
288
289 readValue();
290 return true;
291}
292
293void ListOption::countEntries()
294{
295 m_entriesCount = 0;
296
297 switch (m_optDesc->type) {
298
299 case SANE_TYPE_INT:
300 case SANE_TYPE_FIXED:
301 m_entriesCount = m_optDesc->constraint.word_list[0];
302 break;
303
304 case SANE_TYPE_STRING:
305 while (m_optDesc->constraint.string_list[m_entriesCount] != nullptr) {
306 m_entriesCount++;
307 }
308 break;
309
310 default :
311 qCDebug(KSANECORE_LOG) << "can not handle type:" << m_optDesc->type;
312 break;
313 }
314}
315
316Option::OptionState ListOption::state() const
317{
318 if (m_entriesCount <= 1) {
319 return Option::StateHidden;
320 } else {
321 return BaseOption::state();
322 }
323}
324
325} // namespace KSaneCore
326
327#include "moc_listoption.cpp"
Q_SCRIPTABLE CaptureState status()
KIOCORE_EXPORT QStringList list(const QString &fileClass)
void reserve(qsizetype size)
QString fromLatin1(QByteArrayView str)
double toDouble(bool *ok) const const
int toInt(bool *ok, int base) const const
QTextStream & fixed(QTextStream &stream)
double toDouble(bool *ok) const const
QString toString() const const
int userType() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:56:33 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.