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 : #include "qgpgmenewcryptoconfig.h"
35 :
36 : #include <QDebug>
37 : #include "gpgme_backend_debug.h"
38 :
39 : #include <QFile>
40 :
41 : #include "global.h"
42 : #include "error.h"
43 :
44 :
45 : #include <sstream>
46 : #include <string>
47 : #include <cassert>
48 :
49 : using namespace QGpgME;
50 : using namespace GpgME;
51 : using namespace GpgME::Configuration;
52 :
53 : namespace
54 : {
55 : struct Select1St {
56 : template <typename U, typename V>
57 : const U &operator()(const std::pair<U, V> &p) const
58 : {
59 : return p.first;
60 : }
61 : template <typename U, typename V>
62 : const U &operator()(const QPair<U, V> &p) const
63 : {
64 : return p.first;
65 : }
66 : };
67 : }
68 :
69 : // Just for the Q_ASSERT in the dtor. Not thread-safe, but who would
70 : // have 2 threads talking to gpgconf anyway? :)
71 : static bool s_duringClear = false;
72 :
73 0 : QGpgMENewCryptoConfig::QGpgMENewCryptoConfig()
74 0 : : m_parsed(false)
75 : {
76 0 : }
77 :
78 0 : QGpgMENewCryptoConfig::~QGpgMENewCryptoConfig()
79 : {
80 0 : clear();
81 0 : }
82 :
83 0 : void QGpgMENewCryptoConfig::reloadConfiguration(bool showErrors)
84 : {
85 0 : clear();
86 :
87 0 : Error error;
88 0 : const std::vector<Component> components = Component::load(error);
89 : #ifndef NDEBUG
90 : {
91 0 : std::stringstream ss;
92 0 : ss << "error: " << error
93 0 : << "components:\n";
94 : std::copy(components.begin(), components.end(),
95 0 : std::ostream_iterator<Component>(ss, "\n"));
96 0 : qCDebug(GPGPME_BACKEND_LOG) << ss.str().c_str();
97 : }
98 : #endif
99 : #if 0
100 : TODO port?
101 : if (error && showErrors) {
102 : const QString wmsg = i18n("<qt>Failed to execute gpgconf:<p>%1</p></qt>", QString::fromLocal8Bit(error.asString()));
103 : qCWarning(GPGPME_BACKEND_LOG) << wmsg; // to see it from test_cryptoconfig.cpp
104 : KMessageBox::error(0, wmsg);
105 : }
106 : #endif
107 0 : Q_FOREACH(const Component & c, components) {
108 0 : const std::shared_ptr<QGpgMENewCryptoConfigComponent> comp(new QGpgMENewCryptoConfigComponent);
109 0 : comp->setComponent(c);
110 0 : m_componentsByName[ comp->name() ] = comp;
111 0 : }
112 0 : m_parsed = true;
113 0 : }
114 :
115 0 : QStringList QGpgMENewCryptoConfig::componentList() const
116 : {
117 0 : if (!m_parsed) {
118 0 : const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(true);
119 : }
120 0 : QStringList result;
121 : std::transform(m_componentsByName.begin(), m_componentsByName.end(),
122 : std::back_inserter(result),
123 0 : mem_fn(&QGpgMENewCryptoConfigComponent::name));
124 0 : return result;
125 : }
126 :
127 0 : QGpgMENewCryptoConfigComponent *QGpgMENewCryptoConfig::component(const QString &name) const
128 : {
129 0 : if (!m_parsed) {
130 0 : const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(false);
131 : }
132 0 : return m_componentsByName.value(name).get();
133 : }
134 :
135 0 : void QGpgMENewCryptoConfig::sync(bool runtime)
136 : {
137 0 : Q_FOREACH(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &c, m_componentsByName)
138 0 : c->sync(runtime);
139 0 : }
140 :
141 0 : void QGpgMENewCryptoConfig::clear()
142 : {
143 0 : s_duringClear = true;
144 0 : m_componentsByName.clear();
145 0 : s_duringClear = false;
146 0 : m_parsed = false; // next call to componentList/component will need to run gpgconf again
147 0 : }
148 :
149 : ////
150 :
151 0 : QGpgMENewCryptoConfigComponent::QGpgMENewCryptoConfigComponent()
152 : : CryptoConfigComponent(),
153 0 : m_component()
154 : {
155 :
156 0 : }
157 :
158 0 : void QGpgMENewCryptoConfigComponent::setComponent(const Component &component)
159 : {
160 0 : m_component = component;
161 0 : m_groupsByName.clear();
162 :
163 0 : std::shared_ptr<QGpgMENewCryptoConfigGroup> group;
164 :
165 0 : const std::vector<Option> options = m_component.options();
166 0 : Q_FOREACH(const Option & o, options)
167 0 : if (o.flags() & Group) {
168 0 : if (group) {
169 0 : m_groupsByName[group->name()] = group;
170 : }
171 0 : group.reset(new QGpgMENewCryptoConfigGroup(shared_from_this(), o));
172 0 : } else if (group) {
173 0 : const std::shared_ptr<QGpgMENewCryptoConfigEntry> entry(new QGpgMENewCryptoConfigEntry(group, o));
174 0 : const QString name = entry->name();
175 0 : group->m_entryNames.push_back(name);
176 0 : group->m_entriesByName[name] = entry;
177 : } else {
178 0 : qCWarning(GPGPME_BACKEND_LOG) << "found no group for entry" << o.name() << "of component" << name();
179 0 : }
180 0 : if (group) {
181 0 : m_groupsByName[group->name()] = group;
182 0 : }
183 :
184 0 : }
185 :
186 0 : QGpgMENewCryptoConfigComponent::~QGpgMENewCryptoConfigComponent() {}
187 :
188 0 : QString QGpgMENewCryptoConfigComponent::name() const
189 : {
190 0 : return QString::fromUtf8(m_component.name());
191 : }
192 :
193 0 : QString QGpgMENewCryptoConfigComponent::description() const
194 : {
195 0 : return QString::fromUtf8(m_component.description());
196 : }
197 :
198 0 : QStringList QGpgMENewCryptoConfigComponent::groupList() const
199 : {
200 0 : QStringList result;
201 0 : result.reserve(m_groupsByName.size());
202 : std::transform(m_groupsByName.begin(), m_groupsByName.end(),
203 : std::back_inserter(result),
204 0 : std::mem_fn(&QGpgMENewCryptoConfigGroup::name));
205 0 : return result;
206 : }
207 :
208 0 : QGpgMENewCryptoConfigGroup *QGpgMENewCryptoConfigComponent::group(const QString &name) const
209 : {
210 0 : return m_groupsByName.value(name).get();
211 : }
212 :
213 0 : void QGpgMENewCryptoConfigComponent::sync(bool runtime)
214 : {
215 : Q_UNUSED(runtime)
216 : // ### how to pass --runtime to gpgconf? -> marcus: not yet supported (2010-11-20)
217 0 : if (const Error err = m_component.save()) {
218 : #if 0
219 : TODO port
220 : const QString wmsg = i18n("Error from gpgconf while saving configuration: %1", QString::fromLocal8Bit(err.asString()));
221 : qCWarning(GPGPME_BACKEND_LOG) << ":" << wmsg;
222 : KMessageBox::error(0, wmsg);
223 : #endif
224 0 : }
225 : // ### unset dirty state again
226 0 : }
227 :
228 : ////
229 :
230 0 : QGpgMENewCryptoConfigGroup::QGpgMENewCryptoConfigGroup(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &comp, const Option &option)
231 : : CryptoConfigGroup(),
232 : m_component(comp),
233 0 : m_option(option)
234 : {
235 0 : }
236 :
237 0 : QGpgMENewCryptoConfigGroup::~QGpgMENewCryptoConfigGroup() {}
238 :
239 0 : QString QGpgMENewCryptoConfigGroup::name() const
240 : {
241 0 : 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 0 : }
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 0 : QGpgMENewCryptoConfigEntry *QGpgMENewCryptoConfigGroup::entry(const QString &name) const
270 : {
271 0 : 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 0 : QGpgMENewCryptoConfigEntry::QGpgMENewCryptoConfigEntry(const std::shared_ptr<QGpgMENewCryptoConfigGroup> &group, const Option &option)
312 0 : : m_group(group), m_option(option)
313 : {
314 0 : }
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 0 : QGpgMENewCryptoConfigEntry::~QGpgMENewCryptoConfigEntry()
366 : {
367 : #ifndef NDEBUG
368 0 : 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 0 : }
373 :
374 0 : QString QGpgMENewCryptoConfigEntry::name() const
375 : {
376 0 : 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 0 : }
391 : }
392 :
393 0 : bool QGpgMENewCryptoConfigEntry::isOptional() const
394 : {
395 0 : return m_option.flags() & Optional;
396 : }
397 :
398 0 : bool QGpgMENewCryptoConfigEntry::isReadOnly() const
399 : {
400 0 : return m_option.flags() & NoChange;
401 : }
402 :
403 0 : bool QGpgMENewCryptoConfigEntry::isList() const
404 : {
405 0 : 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 0 : QString QGpgMENewCryptoConfigEntry::stringValue() const
443 : {
444 : //return toString( false );
445 0 : Q_ASSERT(m_option.alternateType() == StringType);
446 0 : Q_ASSERT(!isList());
447 0 : 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 0 : }
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 : QList<QUrl> QGpgMENewCryptoConfigEntry::urlValueList() const
551 : {
552 0 : const Type type = m_option.type();
553 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
554 0 : Q_ASSERT(isList());
555 0 : const Argument arg = m_option.currentValue();
556 0 : const std::vector<const char *> values = arg.stringValues();
557 0 : QList<QUrl> ret;
558 0 : Q_FOREACH(const char *value, values)
559 0 : if (type == FilenameType) {
560 0 : QUrl url;
561 0 : url.setPath(QFile::decodeName(value));
562 0 : ret << url;
563 : } else {
564 0 : ret << parseURL(type, QString::fromUtf8(value));
565 0 : }
566 0 : return ret;
567 : }
568 :
569 0 : void QGpgMENewCryptoConfigEntry::resetToDefault()
570 : {
571 0 : m_option.resetToDefaultValue();
572 0 : }
573 :
574 0 : void QGpgMENewCryptoConfigEntry::setBoolValue(bool b)
575 : {
576 0 : Q_ASSERT(m_option.alternateType() == NoType);
577 0 : Q_ASSERT(!isList());
578 : // A "no arg" option is either set or not set.
579 : // Being set means createNoneArgument(), being unset means resetToDefault()
580 0 : m_option.setNewValue(m_option.createNoneArgument(b));
581 0 : }
582 :
583 0 : void QGpgMENewCryptoConfigEntry::setStringValue(const QString &str)
584 : {
585 0 : Q_ASSERT(m_option.alternateType() == StringType);
586 0 : Q_ASSERT(!isList());
587 0 : const Type type = m_option.type();
588 : // When setting a string to empty (and there's no default), we need to act like resetToDefault
589 : // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers:
590 : // "gpgconf: argument required for option ocsp-responder"
591 0 : if (str.isEmpty() && !isOptional()) {
592 0 : m_option.resetToDefaultValue();
593 0 : } else if (type == FilenameType) {
594 0 : m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
595 : } else {
596 0 : m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
597 : }
598 0 : }
599 :
600 0 : void QGpgMENewCryptoConfigEntry::setIntValue(int i)
601 : {
602 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
603 0 : Q_ASSERT(!isList());
604 0 : m_option.setNewValue(m_option.createIntArgument(i));
605 0 : }
606 :
607 0 : void QGpgMENewCryptoConfigEntry::setUIntValue(unsigned int i)
608 : {
609 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
610 0 : Q_ASSERT(!isList());
611 0 : m_option.setNewValue(m_option.createUIntArgument(i));
612 0 : }
613 :
614 0 : void QGpgMENewCryptoConfigEntry::setURLValue(const QUrl &url)
615 : {
616 0 : const Type type = m_option.type();
617 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
618 0 : Q_ASSERT(!isList());
619 0 : const QString str = splitURL(type, url);
620 : // cf. setStringValue()
621 0 : if (str.isEmpty() && !isOptional()) {
622 0 : m_option.resetToDefaultValue();
623 0 : } else if (type == FilenameType) {
624 0 : m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
625 : } else {
626 0 : m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
627 0 : }
628 0 : }
629 :
630 0 : void QGpgMENewCryptoConfigEntry::setNumberOfTimesSet(unsigned int i)
631 : {
632 0 : Q_ASSERT(m_option.alternateType() == NoType);
633 0 : Q_ASSERT(isList());
634 0 : m_option.setNewValue(m_option.createNoneListArgument(i));
635 0 : }
636 :
637 0 : void QGpgMENewCryptoConfigEntry::setIntValueList(const std::vector<int> &lst)
638 : {
639 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
640 0 : Q_ASSERT(isList());
641 0 : m_option.setNewValue(m_option.createIntListArgument(lst));
642 0 : }
643 :
644 0 : void QGpgMENewCryptoConfigEntry::setUIntValueList(const std::vector<unsigned int> &lst)
645 : {
646 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
647 0 : Q_ASSERT(isList());
648 0 : m_option.setNewValue(m_option.createUIntListArgument(lst));
649 0 : }
650 :
651 0 : void QGpgMENewCryptoConfigEntry::setURLValueList(const QList<QUrl> &urls)
652 : {
653 0 : const Type type = m_option.type();
654 0 : Q_ASSERT(m_option.alternateType() == StringType);
655 0 : Q_ASSERT(isList());
656 0 : std::vector<std::string> values;
657 0 : values.reserve(urls.size());
658 0 : Q_FOREACH (const QUrl &url, urls)
659 0 : if (type == FilenameType) {
660 0 : values.push_back(QFile::encodeName(url.path()).constData());
661 : } else {
662 0 : values.push_back(splitURL(type, url).toUtf8().constData());
663 0 : }
664 0 : m_option.setNewValue(m_option.createStringListArgument(values));
665 0 : }
666 :
667 0 : bool QGpgMENewCryptoConfigEntry::isDirty() const
668 : {
669 0 : return m_option.dirty();
670 : }
671 :
672 : #if 0
673 : QString QGpgMENewCryptoConfigEntry::toString(bool escape) const
674 : {
675 : // Basically the opposite of stringToValue
676 : if (isStringType()) {
677 : if (mValue.isNull()) {
678 : return QString();
679 : } else if (isList()) { // string list
680 : QStringList lst = mValue.toStringList();
681 : if (escape) {
682 : for (QStringList::iterator it = lst.begin(); it != lst.end(); ++it) {
683 : if (!(*it).isNull()) {
684 : *it = gpgconf_escape(*it).prepend("\"");
685 : }
686 : }
687 : }
688 : QString res = lst.join(",");
689 : //qCDebug(GPGPME_BACKEND_LOG) <<"toString:" << res;
690 : return res;
691 : } else { // normal string
692 : QString res = mValue.toString();
693 : if (escape) {
694 : res = gpgconf_escape(res).prepend("\"");
695 : }
696 : return res;
697 : }
698 : }
699 : if (!isList()) { // non-list non-string
700 : if (mArgType == ArgType_None) {
701 : return mValue.toBool() ? QString::fromLatin1("1") : QString();
702 : } else { // some int
703 : Q_ASSERT(mArgType == ArgType_Int || mArgType == ArgType_UInt);
704 : return mValue.toString(); // int to string conversion
705 : }
706 : }
707 :
708 : // Lists (of other types than strings)
709 : if (mArgType == ArgType_None) {
710 : return QString::number(numberOfTimesSet());
711 : }
712 : QStringList ret;
713 : QList<QVariant> lst = mValue.toList();
714 : for (QList<QVariant>::const_iterator it = lst.constBegin(); it != lst.constEnd(); ++it) {
715 : ret << (*it).toString(); // QVariant does the conversion
716 : }
717 : return ret.join(",");
718 : }
719 :
720 : QString QGpgMENewCryptoConfigEntry::outputString() const
721 : {
722 : Q_ASSERT(mSet);
723 : return toString(true);
724 : }
725 :
726 : bool QGpgMENewCryptoConfigEntry::isStringType() const
727 : {
728 : return (mArgType == QGpgME::NewCryptoConfigEntry::ArgType_String
729 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_Path
730 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_URL
731 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_LDAPURL);
732 : }
733 :
734 : void QGpgMENewCryptoConfigEntry::setDirty(bool b)
735 : {
736 : mDirty = b;
737 : }
738 : #endif
|