summaryrefslogtreecommitdiff
path: root/lang/qt/src/qgpgmenewcryptoconfig.cpp
diff options
context:
space:
mode:
authorJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:36 +0900
committerJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:36 +0900
commite158cb38f461261d019c653a5f5e0ca9ddab8d6d (patch)
tree3872a21bc5b5797ee3c705509aace3393b0de251 /lang/qt/src/qgpgmenewcryptoconfig.cpp
parentfd5caec0dccd1229c2b9dd5220c8e2b1ef966d0e (diff)
downloadgpgme-e158cb38f461261d019c653a5f5e0ca9ddab8d6d.tar.gz
gpgme-e158cb38f461261d019c653a5f5e0ca9ddab8d6d.tar.bz2
gpgme-e158cb38f461261d019c653a5f5e0ca9ddab8d6d.zip
Imported Upstream version 1.7.0upstream/1.7.0
Diffstat (limited to 'lang/qt/src/qgpgmenewcryptoconfig.cpp')
-rw-r--r--lang/qt/src/qgpgmenewcryptoconfig.cpp738
1 files changed, 738 insertions, 0 deletions
diff --git a/lang/qt/src/qgpgmenewcryptoconfig.cpp b/lang/qt/src/qgpgmenewcryptoconfig.cpp
new file mode 100644
index 0000000..7303f10
--- /dev/null
+++ b/lang/qt/src/qgpgmenewcryptoconfig.cpp
@@ -0,0 +1,738 @@
+/*
+ qgpgmenewcryptoconfig.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2010 Klarälvdalens Datakonsult AB
+ Copyright (c) 2016 Intevation GmbH
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "qgpgmenewcryptoconfig.h"
+
+#include <QDebug>
+#include "gpgme_backend_debug.h"
+
+#include <QFile>
+
+#include "global.h"
+#include "error.h"
+
+
+#include <sstream>
+#include <string>
+#include <cassert>
+
+using namespace QGpgME;
+using namespace GpgME;
+using namespace GpgME::Configuration;
+
+namespace
+{
+struct Select1St {
+ template <typename U, typename V>
+ const U &operator()(const std::pair<U, V> &p) const
+ {
+ return p.first;
+ }
+ template <typename U, typename V>
+ const U &operator()(const QPair<U, V> &p) const
+ {
+ return p.first;
+ }
+};
+}
+
+// Just for the Q_ASSERT in the dtor. Not thread-safe, but who would
+// have 2 threads talking to gpgconf anyway? :)
+static bool s_duringClear = false;
+
+QGpgMENewCryptoConfig::QGpgMENewCryptoConfig()
+ : m_parsed(false)
+{
+}
+
+QGpgMENewCryptoConfig::~QGpgMENewCryptoConfig()
+{
+ clear();
+}
+
+void QGpgMENewCryptoConfig::reloadConfiguration(bool showErrors)
+{
+ clear();
+
+ Error error;
+ const std::vector<Component> components = Component::load(error);
+#ifndef NDEBUG
+ {
+ std::stringstream ss;
+ ss << "error: " << error
+ << "components:\n";
+ std::copy(components.begin(), components.end(),
+ std::ostream_iterator<Component>(ss, "\n"));
+ qCDebug(GPGPME_BACKEND_LOG) << ss.str().c_str();
+ }
+#endif
+#if 0
+ TODO port?
+ if (error && showErrors) {
+ const QString wmsg = i18n("<qt>Failed to execute gpgconf:<p>%1</p></qt>", QString::fromLocal8Bit(error.asString()));
+ qCWarning(GPGPME_BACKEND_LOG) << wmsg; // to see it from test_cryptoconfig.cpp
+ KMessageBox::error(0, wmsg);
+ }
+#endif
+ Q_FOREACH(const Component & c, components) {
+ const std::shared_ptr<QGpgMENewCryptoConfigComponent> comp(new QGpgMENewCryptoConfigComponent);
+ comp->setComponent(c);
+ m_componentsByName[ comp->name() ] = comp;
+ }
+ m_parsed = true;
+}
+
+QStringList QGpgMENewCryptoConfig::componentList() const
+{
+ if (!m_parsed) {
+ const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(true);
+ }
+ QStringList result;
+ std::transform(m_componentsByName.begin(), m_componentsByName.end(),
+ std::back_inserter(result),
+ mem_fn(&QGpgMENewCryptoConfigComponent::name));
+ return result;
+}
+
+QGpgMENewCryptoConfigComponent *QGpgMENewCryptoConfig::component(const QString &name) const
+{
+ if (!m_parsed) {
+ const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(false);
+ }
+ return m_componentsByName.value(name).get();
+}
+
+void QGpgMENewCryptoConfig::sync(bool runtime)
+{
+ Q_FOREACH(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &c, m_componentsByName)
+ c->sync(runtime);
+}
+
+void QGpgMENewCryptoConfig::clear()
+{
+ s_duringClear = true;
+ m_componentsByName.clear();
+ s_duringClear = false;
+ m_parsed = false; // next call to componentList/component will need to run gpgconf again
+}
+
+////
+
+QGpgMENewCryptoConfigComponent::QGpgMENewCryptoConfigComponent()
+ : CryptoConfigComponent(),
+ m_component()
+{
+
+}
+
+void QGpgMENewCryptoConfigComponent::setComponent(const Component &component)
+{
+ m_component = component;
+ m_groupsByName.clear();
+
+ std::shared_ptr<QGpgMENewCryptoConfigGroup> group;
+
+ const std::vector<Option> options = m_component.options();
+ Q_FOREACH(const Option & o, options)
+ if (o.flags() & Group) {
+ if (group) {
+ m_groupsByName[group->name()] = group;
+ }
+ group.reset(new QGpgMENewCryptoConfigGroup(shared_from_this(), o));
+ } else if (group) {
+ const std::shared_ptr<QGpgMENewCryptoConfigEntry> entry(new QGpgMENewCryptoConfigEntry(group, o));
+ const QString name = entry->name();
+ group->m_entryNames.push_back(name);
+ group->m_entriesByName[name] = entry;
+ } else {
+ qCWarning(GPGPME_BACKEND_LOG) << "found no group for entry" << o.name() << "of component" << name();
+ }
+ if (group) {
+ m_groupsByName[group->name()] = group;
+ }
+
+}
+
+QGpgMENewCryptoConfigComponent::~QGpgMENewCryptoConfigComponent() {}
+
+QString QGpgMENewCryptoConfigComponent::name() const
+{
+ return QString::fromUtf8(m_component.name());
+}
+
+QString QGpgMENewCryptoConfigComponent::description() const
+{
+ return QString::fromUtf8(m_component.description());
+}
+
+QStringList QGpgMENewCryptoConfigComponent::groupList() const
+{
+ QStringList result;
+ result.reserve(m_groupsByName.size());
+ std::transform(m_groupsByName.begin(), m_groupsByName.end(),
+ std::back_inserter(result),
+ std::mem_fn(&QGpgMENewCryptoConfigGroup::name));
+ return result;
+}
+
+QGpgMENewCryptoConfigGroup *QGpgMENewCryptoConfigComponent::group(const QString &name) const
+{
+ return m_groupsByName.value(name).get();
+}
+
+void QGpgMENewCryptoConfigComponent::sync(bool runtime)
+{
+ Q_UNUSED(runtime)
+ // ### how to pass --runtime to gpgconf? -> marcus: not yet supported (2010-11-20)
+ if (const Error err = m_component.save()) {
+#if 0
+ TODO port
+ const QString wmsg = i18n("Error from gpgconf while saving configuration: %1", QString::fromLocal8Bit(err.asString()));
+ qCWarning(GPGPME_BACKEND_LOG) << ":" << wmsg;
+ KMessageBox::error(0, wmsg);
+#endif
+ }
+ // ### unset dirty state again
+}
+
+////
+
+QGpgMENewCryptoConfigGroup::QGpgMENewCryptoConfigGroup(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &comp, const Option &option)
+ : CryptoConfigGroup(),
+ m_component(comp),
+ m_option(option)
+{
+}
+
+QGpgMENewCryptoConfigGroup::~QGpgMENewCryptoConfigGroup() {}
+
+QString QGpgMENewCryptoConfigGroup::name() const
+{
+ return QString::fromUtf8(m_option.name());
+}
+
+QString QGpgMENewCryptoConfigGroup::description() const
+{
+ return QString::fromUtf8(m_option.description());
+}
+
+QString QGpgMENewCryptoConfigGroup::path() const
+{
+ if (const std::shared_ptr<QGpgMENewCryptoConfigComponent> c = m_component.lock()) {
+ return c->name() + QLatin1Char('/') + name();
+ } else {
+ return QString();
+ }
+}
+
+CryptoConfigEntry::Level QGpgMENewCryptoConfigGroup::level() const
+{
+ // two casts to make SunCC happy:
+ return static_cast<CryptoConfigEntry::Level>(static_cast<unsigned int>(m_option.level()));
+}
+
+QStringList QGpgMENewCryptoConfigGroup::entryList() const
+{
+ return m_entryNames;
+}
+
+QGpgMENewCryptoConfigEntry *QGpgMENewCryptoConfigGroup::entry(const QString &name) const
+{
+ return m_entriesByName.value(name).get();
+}
+
+static QString urlpart_encode(const QString &str)
+{
+ QString enc(str);
+ enc.replace(QLatin1Char('%'), QStringLiteral("%25")); // first!
+ enc.replace(QLatin1Char(':'), QStringLiteral("%3a"));
+ //qCDebug(GPGPME_BACKEND_LOG) <<" urlpart_encode:" << str <<" ->" << enc;
+ return enc;
+}
+
+static QString urlpart_decode(const QString &str)
+{
+ return QUrl::fromPercentEncoding(str.toLatin1());
+}
+
+// gpgconf arg type number -> NewCryptoConfigEntry arg type enum mapping
+static QGpgME::CryptoConfigEntry::ArgType knownArgType(int argType, bool &ok)
+{
+ ok = true;
+ switch (argType) {
+ case 0: // none
+ return QGpgME::CryptoConfigEntry::ArgType_None;
+ case 1: // string
+ return QGpgME::CryptoConfigEntry::ArgType_String;
+ case 2: // int32
+ return QGpgME::CryptoConfigEntry::ArgType_Int;
+ case 3: // uint32
+ return QGpgME::CryptoConfigEntry::ArgType_UInt;
+ case 32: // pathname
+ return QGpgME::CryptoConfigEntry::ArgType_Path;
+ case 33: // ldap server
+ return QGpgME::CryptoConfigEntry::ArgType_LDAPURL;
+ default:
+ ok = false;
+ return QGpgME::CryptoConfigEntry::ArgType_None;
+ }
+}
+
+QGpgMENewCryptoConfigEntry::QGpgMENewCryptoConfigEntry(const std::shared_ptr<QGpgMENewCryptoConfigGroup> &group, const Option &option)
+ : m_group(group), m_option(option)
+{
+}
+
+#if 0
+QVariant QGpgMENewCryptoConfigEntry::stringToValue(const QString &str, bool unescape) const
+{
+ const bool isString = isStringType();
+
+ if (isList()) {
+ if (argType() == ArgType_None) {
+ bool ok = true;
+ const QVariant v = str.isEmpty() ? 0U : str.toUInt(&ok);
+ if (!ok) {
+ qCWarning(GPGPME_BACKEND_LOG) << "list-of-none should have an unsigned int as value:" << str;
+ }
+ return v;
+ }
+ QList<QVariant> lst;
+ QStringList items = str.split(',', QString::SkipEmptyParts);
+ for (QStringList::const_iterator valit = items.constBegin(); valit != items.constEnd(); ++valit) {
+ QString val = *valit;
+ if (isString) {
+ if (val.isEmpty()) {
+ lst << QVariant(QString());
+ continue;
+ } else if (unescape) {
+ if (val[0] != '"') { // see README.gpgconf
+ qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
+ }
+ val = val.mid(1);
+ }
+ }
+ lst << QVariant(unescape ? gpgconf_unescape(val) : val);
+ }
+ return lst;
+ } else { // not a list
+ QString val(str);
+ if (isString) {
+ if (val.isEmpty()) {
+ return QVariant(QString()); // not set [ok with lists too?]
+ } else if (unescape) {
+ if (val[0] != '"') { // see README.gpgconf
+ qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
+ }
+ val = val.mid(1);
+ }
+ }
+ return QVariant(unescape ? gpgconf_unescape(val) : val);
+ }
+}
+#endif
+
+QGpgMENewCryptoConfigEntry::~QGpgMENewCryptoConfigEntry()
+{
+#ifndef NDEBUG
+ if (!s_duringClear && m_option.dirty())
+ qCWarning(GPGPME_BACKEND_LOG) << "Deleting a QGpgMENewCryptoConfigEntry that was modified (" << m_option.description() << ")"
+ << "You forgot to call sync() (to commit) or clear() (to discard)";
+#endif
+}
+
+QString QGpgMENewCryptoConfigEntry::name() const
+{
+ return QString::fromUtf8(m_option.name());
+}
+
+QString QGpgMENewCryptoConfigEntry::description() const
+{
+ return QString::fromUtf8(m_option.description());
+}
+
+QString QGpgMENewCryptoConfigEntry::path() const
+{
+ if (const std::shared_ptr<QGpgMENewCryptoConfigGroup> g = m_group.lock()) {
+ return g->path() + QLatin1Char('/') + name();
+ } else {
+ return QString();
+ }
+}
+
+bool QGpgMENewCryptoConfigEntry::isOptional() const
+{
+ return m_option.flags() & Optional;
+}
+
+bool QGpgMENewCryptoConfigEntry::isReadOnly() const
+{
+ return m_option.flags() & NoChange;
+}
+
+bool QGpgMENewCryptoConfigEntry::isList() const
+{
+ return m_option.flags() & List;
+}
+
+bool QGpgMENewCryptoConfigEntry::isRuntime() const
+{
+ return m_option.flags() & Runtime;
+}
+
+CryptoConfigEntry::Level QGpgMENewCryptoConfigEntry::level() const
+{
+ // two casts to make SunCC happy:
+ return static_cast<Level>(static_cast<unsigned int>(m_option.level()));
+}
+
+CryptoConfigEntry::ArgType QGpgMENewCryptoConfigEntry::argType() const
+{
+ bool ok = false;
+ const ArgType type = knownArgType(m_option.type(), ok);
+ if (ok) {
+ return type;
+ } else {
+ return knownArgType(m_option.alternateType(), ok);
+ }
+}
+
+bool QGpgMENewCryptoConfigEntry::isSet() const
+{
+ return m_option.set();
+}
+
+bool QGpgMENewCryptoConfigEntry::boolValue() const
+{
+ Q_ASSERT(m_option.alternateType() == NoType);
+ Q_ASSERT(!isList());
+ return m_option.currentValue().boolValue();
+}
+
+QString QGpgMENewCryptoConfigEntry::stringValue() const
+{
+ //return toString( false );
+ Q_ASSERT(m_option.alternateType() == StringType);
+ Q_ASSERT(!isList());
+ return QString::fromUtf8(m_option.currentValue().stringValue());
+}
+
+int QGpgMENewCryptoConfigEntry::intValue() const
+{
+ Q_ASSERT(m_option.alternateType() == IntegerType);
+ Q_ASSERT(!isList());
+ return m_option.currentValue().intValue();
+}
+
+unsigned int QGpgMENewCryptoConfigEntry::uintValue() const
+{
+ Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
+ Q_ASSERT(!isList());
+ return m_option.currentValue().uintValue();
+}
+
+static QUrl parseURL(int mRealArgType, const QString &str)
+{
+ if (mRealArgType == 33) { // LDAP server
+ // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
+ QStringList items = str.split(QLatin1Char(':'));
+ if (items.count() == 5) {
+ QStringList::const_iterator it = items.constBegin();
+ QUrl url;
+ url.setScheme(QStringLiteral("ldap"));
+ url.setHost(urlpart_decode(*it++));
+
+ bool ok;
+ const int port = (*it++).toInt(&ok);
+ if (ok) {
+ url.setPort(port);
+ } else if (!it->isEmpty()) {
+ qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server port, ignoring: \"" << *it << "\"";
+ }
+
+ const QString userName = urlpart_decode(*it++);
+ if (!userName.isEmpty()) {
+ url.setUserName(userName);
+ }
+ const QString passWord = urlpart_decode(*it++);
+ if (!passWord.isEmpty()) {
+ url.setPassword(passWord);
+ }
+ url.setQuery(urlpart_decode(*it));
+ return url;
+ } else {
+ qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server:" << str;
+ }
+ }
+ // other URLs : assume wellformed URL syntax.
+ return QUrl(str);
+}
+
+// The opposite of parseURL
+static QString splitURL(int mRealArgType, const QUrl &url)
+{
+ if (mRealArgType == 33) { // LDAP server
+ // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
+ Q_ASSERT(url.scheme() == QLatin1String("ldap"));
+ return urlpart_encode(url.host()) + QLatin1Char(':') +
+ (url.port() != -1 ? QString::number(url.port()) : QString()) + QLatin1Char(':') + // -1 is used for default ports, omit
+ urlpart_encode(url.userName()) + QLatin1Char(':') +
+ urlpart_encode(url.password()) + QLatin1Char(':') +
+ urlpart_encode(url.query());
+ }
+ return url.path();
+}
+
+QUrl QGpgMENewCryptoConfigEntry::urlValue() const
+{
+ const Type type = m_option.type();
+ Q_ASSERT(type == FilenameType || type == LdapServerType);
+ Q_ASSERT(!isList());
+ if (type == FilenameType) {
+ QUrl url;
+ url.setPath(QFile::decodeName(m_option.currentValue().stringValue()));
+ return url;
+ }
+ return parseURL(type, stringValue());
+}
+
+unsigned int QGpgMENewCryptoConfigEntry::numberOfTimesSet() const
+{
+ Q_ASSERT(m_option.alternateType() == NoType);
+ Q_ASSERT(isList());
+ return m_option.currentValue().uintValue();
+}
+
+std::vector<int> QGpgMENewCryptoConfigEntry::intValueList() const
+{
+ Q_ASSERT(m_option.alternateType() == IntegerType);
+ Q_ASSERT(isList());
+ return m_option.currentValue().intValues();
+}
+
+std::vector<unsigned int> QGpgMENewCryptoConfigEntry::uintValueList() const
+{
+ Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
+ Q_ASSERT(isList());
+ return m_option.currentValue().uintValues();
+}
+
+QList<QUrl> QGpgMENewCryptoConfigEntry::urlValueList() const
+{
+ const Type type = m_option.type();
+ Q_ASSERT(type == FilenameType || type == LdapServerType);
+ Q_ASSERT(isList());
+ const Argument arg = m_option.currentValue();
+ const std::vector<const char *> values = arg.stringValues();
+ QList<QUrl> ret;
+ Q_FOREACH(const char *value, values)
+ if (type == FilenameType) {
+ QUrl url;
+ url.setPath(QFile::decodeName(value));
+ ret << url;
+ } else {
+ ret << parseURL(type, QString::fromUtf8(value));
+ }
+ return ret;
+}
+
+void QGpgMENewCryptoConfigEntry::resetToDefault()
+{
+ m_option.resetToDefaultValue();
+}
+
+void QGpgMENewCryptoConfigEntry::setBoolValue(bool b)
+{
+ Q_ASSERT(m_option.alternateType() == NoType);
+ Q_ASSERT(!isList());
+ // A "no arg" option is either set or not set.
+ // Being set means createNoneArgument(), being unset means resetToDefault()
+ m_option.setNewValue(m_option.createNoneArgument(b));
+}
+
+void QGpgMENewCryptoConfigEntry::setStringValue(const QString &str)
+{
+ Q_ASSERT(m_option.alternateType() == StringType);
+ Q_ASSERT(!isList());
+ const Type type = m_option.type();
+ // When setting a string to empty (and there's no default), we need to act like resetToDefault
+ // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers:
+ // "gpgconf: argument required for option ocsp-responder"
+ if (str.isEmpty() && !isOptional()) {
+ m_option.resetToDefaultValue();
+ } else if (type == FilenameType) {
+ m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
+ } else {
+ m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
+ }
+}
+
+void QGpgMENewCryptoConfigEntry::setIntValue(int i)
+{
+ Q_ASSERT(m_option.alternateType() == IntegerType);
+ Q_ASSERT(!isList());
+ m_option.setNewValue(m_option.createIntArgument(i));
+}
+
+void QGpgMENewCryptoConfigEntry::setUIntValue(unsigned int i)
+{
+ Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
+ Q_ASSERT(!isList());
+ m_option.setNewValue(m_option.createUIntArgument(i));
+}
+
+void QGpgMENewCryptoConfigEntry::setURLValue(const QUrl &url)
+{
+ const Type type = m_option.type();
+ Q_ASSERT(type == FilenameType || type == LdapServerType);
+ Q_ASSERT(!isList());
+ const QString str = splitURL(type, url);
+ // cf. setStringValue()
+ if (str.isEmpty() && !isOptional()) {
+ m_option.resetToDefaultValue();
+ } else if (type == FilenameType) {
+ m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
+ } else {
+ m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
+ }
+}
+
+void QGpgMENewCryptoConfigEntry::setNumberOfTimesSet(unsigned int i)
+{
+ Q_ASSERT(m_option.alternateType() == NoType);
+ Q_ASSERT(isList());
+ m_option.setNewValue(m_option.createNoneListArgument(i));
+}
+
+void QGpgMENewCryptoConfigEntry::setIntValueList(const std::vector<int> &lst)
+{
+ Q_ASSERT(m_option.alternateType() == IntegerType);
+ Q_ASSERT(isList());
+ m_option.setNewValue(m_option.createIntListArgument(lst));
+}
+
+void QGpgMENewCryptoConfigEntry::setUIntValueList(const std::vector<unsigned int> &lst)
+{
+ Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
+ Q_ASSERT(isList());
+ m_option.setNewValue(m_option.createUIntListArgument(lst));
+}
+
+void QGpgMENewCryptoConfigEntry::setURLValueList(const QList<QUrl> &urls)
+{
+ const Type type = m_option.type();
+ Q_ASSERT(m_option.alternateType() == StringType);
+ Q_ASSERT(isList());
+ std::vector<std::string> values;
+ values.reserve(urls.size());
+ Q_FOREACH (const QUrl &url, urls)
+ if (type == FilenameType) {
+ values.push_back(QFile::encodeName(url.path()).constData());
+ } else {
+ values.push_back(splitURL(type, url).toUtf8().constData());
+ }
+ m_option.setNewValue(m_option.createStringListArgument(values));
+}
+
+bool QGpgMENewCryptoConfigEntry::isDirty() const
+{
+ return m_option.dirty();
+}
+
+#if 0
+QString QGpgMENewCryptoConfigEntry::toString(bool escape) const
+{
+ // Basically the opposite of stringToValue
+ if (isStringType()) {
+ if (mValue.isNull()) {
+ return QString();
+ } else if (isList()) { // string list
+ QStringList lst = mValue.toStringList();
+ if (escape) {
+ for (QStringList::iterator it = lst.begin(); it != lst.end(); ++it) {
+ if (!(*it).isNull()) {
+ *it = gpgconf_escape(*it).prepend("\"");
+ }
+ }
+ }
+ QString res = lst.join(",");
+ //qCDebug(GPGPME_BACKEND_LOG) <<"toString:" << res;
+ return res;
+ } else { // normal string
+ QString res = mValue.toString();
+ if (escape) {
+ res = gpgconf_escape(res).prepend("\"");
+ }
+ return res;
+ }
+ }
+ if (!isList()) { // non-list non-string
+ if (mArgType == ArgType_None) {
+ return mValue.toBool() ? QString::fromLatin1("1") : QString();
+ } else { // some int
+ Q_ASSERT(mArgType == ArgType_Int || mArgType == ArgType_UInt);
+ return mValue.toString(); // int to string conversion
+ }
+ }
+
+ // Lists (of other types than strings)
+ if (mArgType == ArgType_None) {
+ return QString::number(numberOfTimesSet());
+ }
+ QStringList ret;
+ QList<QVariant> lst = mValue.toList();
+ for (QList<QVariant>::const_iterator it = lst.constBegin(); it != lst.constEnd(); ++it) {
+ ret << (*it).toString(); // QVariant does the conversion
+ }
+ return ret.join(",");
+}
+
+QString QGpgMENewCryptoConfigEntry::outputString() const
+{
+ Q_ASSERT(mSet);
+ return toString(true);
+}
+
+bool QGpgMENewCryptoConfigEntry::isStringType() const
+{
+ return (mArgType == QGpgME::NewCryptoConfigEntry::ArgType_String
+ || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_Path
+ || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_URL
+ || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_LDAPURL);
+}
+
+void QGpgMENewCryptoConfigEntry::setDirty(bool b)
+{
+ mDirty = b;
+}
+#endif