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