Line data Source code
1 : /*
2 : qgpgmenewcryptoconfig.cpp
3 :
4 : This file is part of qgpgme, the Qt API binding for gpgme
5 : Copyright (c) 2010 Klarälvdalens Datakonsult AB
6 : Copyright (c) 2016 Intevation GmbH
7 :
8 : QGpgME is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2 of the
11 : License, or (at your option) any later version.
12 :
13 : QGpgME is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 :
22 : In addition, as a special exception, the copyright holders give
23 : permission to link the code of this program with any edition of
24 : the Qt library by Trolltech AS, Norway (or with modified versions
25 : of Qt that use the same license as Qt), and distribute linked
26 : combinations including the two. You must obey the GNU General
27 : Public License in all respects for all of the code used other than
28 : Qt. If you modify this file, you may extend this exception to
29 : your version of the file, but you are not obligated to do so. If
30 : you do not wish to do so, delete this exception statement from
31 : your version.
32 : */
33 :
34 : #ifdef HAVE_CONFIG_H
35 : #include "config.h"
36 : #endif
37 :
38 : #include "qgpgmenewcryptoconfig.h"
39 :
40 : #include <QDebug>
41 : #include "gpgme_backend_debug.h"
42 :
43 : #include <QFile>
44 :
45 : #include "global.h"
46 : #include "error.h"
47 :
48 :
49 : #include <sstream>
50 : #include <string>
51 : #include <cassert>
52 : #include <functional>
53 :
54 : using namespace QGpgME;
55 : using namespace GpgME;
56 : using namespace GpgME::Configuration;
57 :
58 : namespace
59 : {
60 : struct Select1St {
61 : template <typename U, typename V>
62 : const U &operator()(const std::pair<U, V> &p) const
63 : {
64 : return p.first;
65 : }
66 : template <typename U, typename V>
67 : const U &operator()(const QPair<U, V> &p) const
68 : {
69 : return p.first;
70 : }
71 : };
72 : }
73 :
74 : // Just for the Q_ASSERT in the dtor. Not thread-safe, but who would
75 : // have 2 threads talking to gpgconf anyway? :)
76 : static bool s_duringClear = false;
77 :
78 1 : QGpgMENewCryptoConfig::QGpgMENewCryptoConfig()
79 1 : : m_parsed(false)
80 : {
81 1 : }
82 :
83 0 : QGpgMENewCryptoConfig::~QGpgMENewCryptoConfig()
84 : {
85 0 : clear();
86 0 : }
87 :
88 21 : void QGpgMENewCryptoConfig::reloadConfiguration(bool)
89 : {
90 21 : clear();
91 :
92 42 : Error error;
93 42 : const std::vector<Component> components = Component::load(error);
94 : #ifndef NDEBUG
95 : {
96 42 : std::stringstream ss;
97 21 : ss << "error: " << error
98 21 : << "components:\n";
99 : std::copy(components.begin(), components.end(),
100 21 : std::ostream_iterator<Component>(ss, "\n"));
101 21 : qCDebug(GPGPME_BACKEND_LOG) << ss.str().c_str();
102 : }
103 : #endif
104 : #if 0
105 : TODO port?
106 : if (error && showErrors) {
107 : const QString wmsg = i18n("<qt>Failed to execute gpgconf:<p>%1</p></qt>", QString::fromLocal8Bit(error.asString()));
108 : qCWarning(GPGPME_BACKEND_LOG) << wmsg; // to see it from test_cryptoconfig.cpp
109 : KMessageBox::error(0, wmsg);
110 : }
111 : #endif
112 147 : Q_FOREACH(const Component & c, components) {
113 252 : const std::shared_ptr<QGpgMENewCryptoConfigComponent> comp(new QGpgMENewCryptoConfigComponent);
114 126 : comp->setComponent(c);
115 126 : m_componentsByName[ comp->name() ] = comp;
116 : }
117 21 : m_parsed = true;
118 21 : }
119 :
120 0 : QStringList QGpgMENewCryptoConfig::componentList() const
121 : {
122 0 : if (!m_parsed) {
123 0 : const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(true);
124 : }
125 0 : QStringList result;
126 : std::transform(m_componentsByName.begin(), m_componentsByName.end(),
127 : std::back_inserter(result),
128 0 : mem_fn(&QGpgMENewCryptoConfigComponent::name));
129 0 : return result;
130 : }
131 :
132 30 : QGpgMENewCryptoConfigComponent *QGpgMENewCryptoConfig::component(const QString &name) const
133 : {
134 30 : if (!m_parsed) {
135 21 : const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(false);
136 : }
137 30 : return m_componentsByName.value(name).get();
138 : }
139 :
140 20 : void QGpgMENewCryptoConfig::sync(bool runtime)
141 : {
142 140 : Q_FOREACH(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &c, m_componentsByName)
143 120 : c->sync(runtime);
144 20 : }
145 :
146 41 : void QGpgMENewCryptoConfig::clear()
147 : {
148 41 : s_duringClear = true;
149 41 : m_componentsByName.clear();
150 41 : s_duringClear = false;
151 41 : m_parsed = false; // next call to componentList/component will need to run gpgconf again
152 41 : }
153 :
154 : ////
155 :
156 126 : QGpgMENewCryptoConfigComponent::QGpgMENewCryptoConfigComponent()
157 : : CryptoConfigComponent(),
158 126 : m_component()
159 : {
160 :
161 126 : }
162 :
163 126 : void QGpgMENewCryptoConfigComponent::setComponent(const Component &component)
164 : {
165 126 : m_component = component;
166 126 : m_groupsByName.clear();
167 :
168 252 : std::shared_ptr<QGpgMENewCryptoConfigGroup> group;
169 :
170 252 : const std::vector<Option> options = m_component.options();
171 2625 : Q_FOREACH(const Option & o, options)
172 2499 : if (o.flags() & Group) {
173 567 : if (group) {
174 462 : m_groupsByName[group->name()] = group;
175 : }
176 567 : group.reset(new QGpgMENewCryptoConfigGroup(shared_from_this(), o));
177 1932 : } else if (group) {
178 3864 : const std::shared_ptr<QGpgMENewCryptoConfigEntry> entry(new QGpgMENewCryptoConfigEntry(group, o));
179 3864 : const QString name = entry->name();
180 1932 : group->m_entryNames.push_back(name);
181 1932 : group->m_entriesByName[name] = entry;
182 : } else {
183 0 : qCWarning(GPGPME_BACKEND_LOG) << "found no group for entry" << o.name() << "of component" << name();
184 : }
185 126 : if (group) {
186 105 : m_groupsByName[group->name()] = group;
187 : }
188 :
189 126 : }
190 :
191 240 : QGpgMENewCryptoConfigComponent::~QGpgMENewCryptoConfigComponent() {}
192 :
193 126 : QString QGpgMENewCryptoConfigComponent::name() const
194 : {
195 126 : return QString::fromUtf8(m_component.name());
196 : }
197 :
198 0 : QString QGpgMENewCryptoConfigComponent::description() const
199 : {
200 0 : return QString::fromUtf8(m_component.description());
201 : }
202 :
203 0 : QStringList QGpgMENewCryptoConfigComponent::groupList() const
204 : {
205 0 : QStringList result;
206 0 : result.reserve(m_groupsByName.size());
207 : std::transform(m_groupsByName.begin(), m_groupsByName.end(),
208 : std::back_inserter(result),
209 0 : std::mem_fn(&QGpgMENewCryptoConfigGroup::name));
210 0 : return result;
211 : }
212 :
213 30 : QGpgMENewCryptoConfigGroup *QGpgMENewCryptoConfigComponent::group(const QString &name) const
214 : {
215 30 : return m_groupsByName.value(name).get();
216 : }
217 :
218 120 : void QGpgMENewCryptoConfigComponent::sync(bool runtime)
219 : {
220 : Q_UNUSED(runtime) // runtime is always set by engine_gpgconf
221 240 : if (const Error err = m_component.save()) {
222 0 : qCWarning(GPGPME_BACKEND_LOG) << ":"
223 0 : << "Error from gpgconf while saving configuration: %1"
224 0 : << QString::fromLocal8Bit(err.asString());
225 : }
226 120 : }
227 :
228 : ////
229 :
230 567 : QGpgMENewCryptoConfigGroup::QGpgMENewCryptoConfigGroup(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &comp, const Option &option)
231 : : CryptoConfigGroup(),
232 : m_component(comp),
233 567 : m_option(option)
234 : {
235 567 : }
236 :
237 1080 : QGpgMENewCryptoConfigGroup::~QGpgMENewCryptoConfigGroup() {}
238 :
239 567 : QString QGpgMENewCryptoConfigGroup::name() const
240 : {
241 567 : return QString::fromUtf8(m_option.name());
242 : }
243 :
244 0 : QString QGpgMENewCryptoConfigGroup::description() const
245 : {
246 0 : return QString::fromUtf8(m_option.description());
247 : }
248 :
249 0 : QString QGpgMENewCryptoConfigGroup::path() const
250 : {
251 0 : if (const std::shared_ptr<QGpgMENewCryptoConfigComponent> c = m_component.lock()) {
252 0 : return c->name() + QLatin1Char('/') + name();
253 : } else {
254 0 : return QString();
255 : }
256 : }
257 :
258 0 : CryptoConfigEntry::Level QGpgMENewCryptoConfigGroup::level() const
259 : {
260 : // two casts to make SunCC happy:
261 0 : return static_cast<CryptoConfigEntry::Level>(static_cast<unsigned int>(m_option.level()));
262 : }
263 :
264 0 : QStringList QGpgMENewCryptoConfigGroup::entryList() const
265 : {
266 0 : return m_entryNames;
267 : }
268 :
269 30 : QGpgMENewCryptoConfigEntry *QGpgMENewCryptoConfigGroup::entry(const QString &name) const
270 : {
271 30 : return m_entriesByName.value(name).get();
272 : }
273 :
274 0 : static QString urlpart_encode(const QString &str)
275 : {
276 0 : QString enc(str);
277 0 : enc.replace(QLatin1Char('%'), QStringLiteral("%25")); // first!
278 0 : enc.replace(QLatin1Char(':'), QStringLiteral("%3a"));
279 : //qCDebug(GPGPME_BACKEND_LOG) <<" urlpart_encode:" << str <<" ->" << enc;
280 0 : return enc;
281 : }
282 :
283 0 : static QString urlpart_decode(const QString &str)
284 : {
285 0 : return QUrl::fromPercentEncoding(str.toLatin1());
286 : }
287 :
288 : // gpgconf arg type number -> NewCryptoConfigEntry arg type enum mapping
289 0 : static QGpgME::CryptoConfigEntry::ArgType knownArgType(int argType, bool &ok)
290 : {
291 0 : ok = true;
292 0 : switch (argType) {
293 : case 0: // none
294 0 : return QGpgME::CryptoConfigEntry::ArgType_None;
295 : case 1: // string
296 0 : return QGpgME::CryptoConfigEntry::ArgType_String;
297 : case 2: // int32
298 0 : return QGpgME::CryptoConfigEntry::ArgType_Int;
299 : case 3: // uint32
300 0 : return QGpgME::CryptoConfigEntry::ArgType_UInt;
301 : case 32: // pathname
302 0 : return QGpgME::CryptoConfigEntry::ArgType_Path;
303 : case 33: // ldap server
304 0 : return QGpgME::CryptoConfigEntry::ArgType_LDAPURL;
305 : default:
306 0 : ok = false;
307 0 : return QGpgME::CryptoConfigEntry::ArgType_None;
308 : }
309 : }
310 :
311 1932 : QGpgMENewCryptoConfigEntry::QGpgMENewCryptoConfigEntry(const std::shared_ptr<QGpgMENewCryptoConfigGroup> &group, const Option &option)
312 1932 : : m_group(group), m_option(option)
313 : {
314 1932 : }
315 :
316 : #if 0
317 : QVariant QGpgMENewCryptoConfigEntry::stringToValue(const QString &str, bool unescape) const
318 : {
319 : const bool isString = isStringType();
320 :
321 : if (isList()) {
322 : if (argType() == ArgType_None) {
323 : bool ok = true;
324 : const QVariant v = str.isEmpty() ? 0U : str.toUInt(&ok);
325 : if (!ok) {
326 : qCWarning(GPGPME_BACKEND_LOG) << "list-of-none should have an unsigned int as value:" << str;
327 : }
328 : return v;
329 : }
330 : QList<QVariant> lst;
331 : QStringList items = str.split(',', QString::SkipEmptyParts);
332 : for (QStringList::const_iterator valit = items.constBegin(); valit != items.constEnd(); ++valit) {
333 : QString val = *valit;
334 : if (isString) {
335 : if (val.isEmpty()) {
336 : lst << QVariant(QString());
337 : continue;
338 : } else if (unescape) {
339 : if (val[0] != '"') { // see README.gpgconf
340 : qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
341 : }
342 : val = val.mid(1);
343 : }
344 : }
345 : lst << QVariant(unescape ? gpgconf_unescape(val) : val);
346 : }
347 : return lst;
348 : } else { // not a list
349 : QString val(str);
350 : if (isString) {
351 : if (val.isEmpty()) {
352 : return QVariant(QString()); // not set [ok with lists too?]
353 : } else if (unescape) {
354 : if (val[0] != '"') { // see README.gpgconf
355 : qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
356 : }
357 : val = val.mid(1);
358 : }
359 : }
360 : return QVariant(unescape ? gpgconf_unescape(val) : val);
361 : }
362 : }
363 : #endif
364 :
365 5520 : QGpgMENewCryptoConfigEntry::~QGpgMENewCryptoConfigEntry()
366 : {
367 : #ifndef NDEBUG
368 1840 : if (!s_duringClear && m_option.dirty())
369 0 : qCWarning(GPGPME_BACKEND_LOG) << "Deleting a QGpgMENewCryptoConfigEntry that was modified (" << m_option.description() << ")"
370 0 : << "You forgot to call sync() (to commit) or clear() (to discard)";
371 : #endif
372 3680 : }
373 :
374 1932 : QString QGpgMENewCryptoConfigEntry::name() const
375 : {
376 1932 : return QString::fromUtf8(m_option.name());
377 : }
378 :
379 0 : QString QGpgMENewCryptoConfigEntry::description() const
380 : {
381 0 : return QString::fromUtf8(m_option.description());
382 : }
383 :
384 0 : QString QGpgMENewCryptoConfigEntry::path() const
385 : {
386 0 : if (const std::shared_ptr<QGpgMENewCryptoConfigGroup> g = m_group.lock()) {
387 0 : return g->path() + QLatin1Char('/') + name();
388 : } else {
389 0 : return QString();
390 : }
391 : }
392 :
393 10 : bool QGpgMENewCryptoConfigEntry::isOptional() const
394 : {
395 10 : return m_option.flags() & Optional;
396 : }
397 :
398 0 : bool QGpgMENewCryptoConfigEntry::isReadOnly() const
399 : {
400 0 : return m_option.flags() & NoChange;
401 : }
402 :
403 40 : bool QGpgMENewCryptoConfigEntry::isList() const
404 : {
405 40 : return m_option.flags() & List;
406 : }
407 :
408 0 : bool QGpgMENewCryptoConfigEntry::isRuntime() const
409 : {
410 0 : return m_option.flags() & Runtime;
411 : }
412 :
413 0 : CryptoConfigEntry::Level QGpgMENewCryptoConfigEntry::level() const
414 : {
415 : // two casts to make SunCC happy:
416 0 : return static_cast<Level>(static_cast<unsigned int>(m_option.level()));
417 : }
418 :
419 0 : CryptoConfigEntry::ArgType QGpgMENewCryptoConfigEntry::argType() const
420 : {
421 0 : bool ok = false;
422 0 : const ArgType type = knownArgType(m_option.type(), ok);
423 0 : if (ok) {
424 0 : return type;
425 : } else {
426 0 : return knownArgType(m_option.alternateType(), ok);
427 : }
428 : }
429 :
430 0 : bool QGpgMENewCryptoConfigEntry::isSet() const
431 : {
432 0 : return m_option.set();
433 : }
434 :
435 0 : bool QGpgMENewCryptoConfigEntry::boolValue() const
436 : {
437 0 : Q_ASSERT(m_option.alternateType() == NoType);
438 0 : Q_ASSERT(!isList());
439 0 : return m_option.currentValue().boolValue();
440 : }
441 :
442 20 : QString QGpgMENewCryptoConfigEntry::stringValue() const
443 : {
444 : //return toString( false );
445 20 : Q_ASSERT(m_option.alternateType() == StringType);
446 20 : Q_ASSERT(!isList());
447 20 : return QString::fromUtf8(m_option.currentValue().stringValue());
448 : }
449 :
450 0 : int QGpgMENewCryptoConfigEntry::intValue() const
451 : {
452 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
453 0 : Q_ASSERT(!isList());
454 0 : return m_option.currentValue().intValue();
455 : }
456 :
457 0 : unsigned int QGpgMENewCryptoConfigEntry::uintValue() const
458 : {
459 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
460 0 : Q_ASSERT(!isList());
461 0 : return m_option.currentValue().uintValue();
462 : }
463 :
464 0 : static QUrl parseURL(int mRealArgType, const QString &str)
465 : {
466 0 : if (mRealArgType == 33) { // LDAP server
467 : // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
468 0 : QStringList items = str.split(QLatin1Char(':'));
469 0 : if (items.count() == 5) {
470 0 : QStringList::const_iterator it = items.constBegin();
471 0 : QUrl url;
472 0 : url.setScheme(QStringLiteral("ldap"));
473 0 : url.setHost(urlpart_decode(*it++));
474 :
475 : bool ok;
476 0 : const int port = (*it++).toInt(&ok);
477 0 : if (ok) {
478 0 : url.setPort(port);
479 0 : } else if (!it->isEmpty()) {
480 0 : qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server port, ignoring: \"" << *it << "\"";
481 : }
482 :
483 0 : const QString userName = urlpart_decode(*it++);
484 0 : if (!userName.isEmpty()) {
485 0 : url.setUserName(userName);
486 : }
487 0 : const QString passWord = urlpart_decode(*it++);
488 0 : if (!passWord.isEmpty()) {
489 0 : url.setPassword(passWord);
490 : }
491 0 : url.setQuery(urlpart_decode(*it));
492 0 : return url;
493 : } else {
494 0 : qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server:" << str;
495 : }
496 : }
497 : // other URLs : assume wellformed URL syntax.
498 0 : return QUrl(str);
499 : }
500 :
501 : // The opposite of parseURL
502 0 : static QString splitURL(int mRealArgType, const QUrl &url)
503 : {
504 0 : if (mRealArgType == 33) { // LDAP server
505 : // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
506 0 : Q_ASSERT(url.scheme() == QLatin1String("ldap"));
507 0 : return urlpart_encode(url.host()) + QLatin1Char(':') +
508 0 : (url.port() != -1 ? QString::number(url.port()) : QString()) + QLatin1Char(':') + // -1 is used for default ports, omit
509 0 : urlpart_encode(url.userName()) + QLatin1Char(':') +
510 0 : urlpart_encode(url.password()) + QLatin1Char(':') +
511 0 : urlpart_encode(url.query());
512 : }
513 0 : return url.path();
514 : }
515 :
516 0 : QUrl QGpgMENewCryptoConfigEntry::urlValue() const
517 : {
518 0 : const Type type = m_option.type();
519 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
520 0 : Q_ASSERT(!isList());
521 0 : if (type == FilenameType) {
522 0 : QUrl url;
523 0 : url.setPath(QFile::decodeName(m_option.currentValue().stringValue()));
524 0 : return url;
525 : }
526 0 : return parseURL(type, stringValue());
527 : }
528 :
529 0 : unsigned int QGpgMENewCryptoConfigEntry::numberOfTimesSet() const
530 : {
531 0 : Q_ASSERT(m_option.alternateType() == NoType);
532 0 : Q_ASSERT(isList());
533 0 : return m_option.currentValue().uintValue();
534 : }
535 :
536 0 : std::vector<int> QGpgMENewCryptoConfigEntry::intValueList() const
537 : {
538 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
539 0 : Q_ASSERT(isList());
540 0 : return m_option.currentValue().intValues();
541 : }
542 :
543 0 : std::vector<unsigned int> QGpgMENewCryptoConfigEntry::uintValueList() const
544 : {
545 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
546 0 : Q_ASSERT(isList());
547 0 : return m_option.currentValue().uintValues();
548 : }
549 :
550 0 : QStringList QGpgMENewCryptoConfigEntry::stringValueList() const
551 : {
552 0 : Q_ASSERT(isList());
553 0 : const Argument arg = m_option.currentValue();
554 0 : const std::vector<const char *> values = arg.stringValues();
555 0 : QStringList ret;
556 0 : for(const char *value: values) {
557 0 : ret << QString::fromUtf8(value);
558 : }
559 0 : return ret;
560 : }
561 :
562 0 : QList<QUrl> QGpgMENewCryptoConfigEntry::urlValueList() const
563 : {
564 0 : const Type type = m_option.type();
565 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
566 0 : Q_ASSERT(isList());
567 0 : const Argument arg = m_option.currentValue();
568 0 : const std::vector<const char *> values = arg.stringValues();
569 0 : QList<QUrl> ret;
570 0 : Q_FOREACH(const char *value, values)
571 0 : if (type == FilenameType) {
572 0 : QUrl url;
573 0 : url.setPath(QFile::decodeName(value));
574 0 : ret << url;
575 : } else {
576 0 : ret << parseURL(type, QString::fromUtf8(value));
577 : }
578 0 : return ret;
579 : }
580 :
581 0 : void QGpgMENewCryptoConfigEntry::resetToDefault()
582 : {
583 0 : m_option.resetToDefaultValue();
584 0 : }
585 :
586 0 : void QGpgMENewCryptoConfigEntry::setBoolValue(bool b)
587 : {
588 0 : Q_ASSERT(m_option.alternateType() == NoType);
589 0 : Q_ASSERT(!isList());
590 : // A "no arg" option is either set or not set.
591 : // Being set means createNoneArgument(), being unset means resetToDefault()
592 0 : m_option.setNewValue(m_option.createNoneArgument(b));
593 0 : }
594 :
595 20 : void QGpgMENewCryptoConfigEntry::setStringValue(const QString &str)
596 : {
597 20 : Q_ASSERT(m_option.alternateType() == StringType);
598 20 : Q_ASSERT(!isList());
599 20 : const Type type = m_option.type();
600 : // When setting a string to empty (and there's no default), we need to act like resetToDefault
601 : // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers:
602 : // "gpgconf: argument required for option ocsp-responder"
603 20 : if (str.isEmpty() && !isOptional()) {
604 10 : m_option.resetToDefaultValue();
605 10 : } else if (type == FilenameType) {
606 0 : m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
607 : } else {
608 10 : m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
609 : }
610 20 : }
611 :
612 0 : void QGpgMENewCryptoConfigEntry::setIntValue(int i)
613 : {
614 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
615 0 : Q_ASSERT(!isList());
616 0 : m_option.setNewValue(m_option.createIntArgument(i));
617 0 : }
618 :
619 0 : void QGpgMENewCryptoConfigEntry::setUIntValue(unsigned int i)
620 : {
621 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
622 0 : Q_ASSERT(!isList());
623 0 : m_option.setNewValue(m_option.createUIntArgument(i));
624 0 : }
625 :
626 0 : void QGpgMENewCryptoConfigEntry::setURLValue(const QUrl &url)
627 : {
628 0 : const Type type = m_option.type();
629 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
630 0 : Q_ASSERT(!isList());
631 0 : const QString str = splitURL(type, url);
632 : // cf. setStringValue()
633 0 : if (str.isEmpty() && !isOptional()) {
634 0 : m_option.resetToDefaultValue();
635 0 : } else if (type == FilenameType) {
636 0 : m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
637 : } else {
638 0 : m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
639 : }
640 0 : }
641 :
642 0 : void QGpgMENewCryptoConfigEntry::setNumberOfTimesSet(unsigned int i)
643 : {
644 0 : Q_ASSERT(m_option.alternateType() == NoType);
645 0 : Q_ASSERT(isList());
646 0 : m_option.setNewValue(m_option.createNoneListArgument(i));
647 0 : }
648 :
649 0 : void QGpgMENewCryptoConfigEntry::setIntValueList(const std::vector<int> &lst)
650 : {
651 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
652 0 : Q_ASSERT(isList());
653 0 : m_option.setNewValue(m_option.createIntListArgument(lst));
654 0 : }
655 :
656 0 : void QGpgMENewCryptoConfigEntry::setUIntValueList(const std::vector<unsigned int> &lst)
657 : {
658 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
659 0 : Q_ASSERT(isList());
660 0 : m_option.setNewValue(m_option.createUIntListArgument(lst));
661 0 : }
662 :
663 0 : void QGpgMENewCryptoConfigEntry::setURLValueList(const QList<QUrl> &urls)
664 : {
665 0 : const Type type = m_option.type();
666 0 : Q_ASSERT(m_option.alternateType() == StringType);
667 0 : Q_ASSERT(isList());
668 0 : std::vector<std::string> values;
669 0 : values.reserve(urls.size());
670 0 : Q_FOREACH (const QUrl &url, urls)
671 0 : if (type == FilenameType) {
672 0 : values.push_back(QFile::encodeName(url.path()).constData());
673 : } else {
674 0 : values.push_back(splitURL(type, url).toUtf8().constData());
675 : }
676 0 : m_option.setNewValue(m_option.createStringListArgument(values));
677 0 : }
678 :
679 0 : bool QGpgMENewCryptoConfigEntry::isDirty() const
680 : {
681 0 : return m_option.dirty();
682 : }
683 :
684 : #if 0
685 : QString QGpgMENewCryptoConfigEntry::toString(bool escape) const
686 : {
687 : // Basically the opposite of stringToValue
688 : if (isStringType()) {
689 : if (mValue.isNull()) {
690 : return QString();
691 : } else if (isList()) { // string list
692 : QStringList lst = mValue.toStringList();
693 : if (escape) {
694 : for (QStringList::iterator it = lst.begin(); it != lst.end(); ++it) {
695 : if (!(*it).isNull()) {
696 : *it = gpgconf_escape(*it).prepend("\"");
697 : }
698 : }
699 : }
700 : QString res = lst.join(",");
701 : //qCDebug(GPGPME_BACKEND_LOG) <<"toString:" << res;
702 : return res;
703 : } else { // normal string
704 : QString res = mValue.toString();
705 : if (escape) {
706 : res = gpgconf_escape(res).prepend("\"");
707 : }
708 : return res;
709 : }
710 : }
711 : if (!isList()) { // non-list non-string
712 : if (mArgType == ArgType_None) {
713 : return mValue.toBool() ? QString::fromLatin1("1") : QString();
714 : } else { // some int
715 : Q_ASSERT(mArgType == ArgType_Int || mArgType == ArgType_UInt);
716 : return mValue.toString(); // int to string conversion
717 : }
718 : }
719 :
720 : // Lists (of other types than strings)
721 : if (mArgType == ArgType_None) {
722 : return QString::number(numberOfTimesSet());
723 : }
724 : QStringList ret;
725 : QList<QVariant> lst = mValue.toList();
726 : for (QList<QVariant>::const_iterator it = lst.constBegin(); it != lst.constEnd(); ++it) {
727 : ret << (*it).toString(); // QVariant does the conversion
728 : }
729 : return ret.join(",");
730 : }
731 :
732 : QString QGpgMENewCryptoConfigEntry::outputString() const
733 : {
734 : Q_ASSERT(mSet);
735 : return toString(true);
736 : }
737 :
738 : bool QGpgMENewCryptoConfigEntry::isStringType() const
739 : {
740 : return (mArgType == QGpgME::NewCryptoConfigEntry::ArgType_String
741 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_Path
742 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_URL
743 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_LDAPURL);
744 : }
745 :
746 : void QGpgMENewCryptoConfigEntry::setDirty(bool b)
747 : {
748 : mDirty = b;
749 : }
750 : #endif
|