File indexing completed on 2025-02-02 05:08:37
0001 /* 0002 SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "resource.h" 0008 0009 #include <Akonadi/AgentConfigurationDialog> 0010 #include <Akonadi/AgentInstanceCreateJob> 0011 #include <Akonadi/AgentManager> 0012 #include <Akonadi/AgentType> 0013 #include <Akonadi/ServerManager> 0014 0015 #include "accountwizard_debug.h" 0016 #include <KLocalizedString> 0017 0018 #include <QDBusInterface> 0019 #include <QDBusReply> 0020 #include <QMetaMethod> 0021 #include <QPointer> 0022 #include <QVariant> 0023 0024 using namespace Akonadi; 0025 0026 static QVariant::Type argumentType(const QMetaObject *mo, const QString &method) 0027 { 0028 QMetaMethod m; 0029 const int numberOfMethod(mo->methodCount()); 0030 for (int i = 0; i < numberOfMethod; ++i) { 0031 const QString signature = QLatin1StringView(mo->method(i).methodSignature()); 0032 if (signature.contains(method + QLatin1Char('('))) { 0033 m = mo->method(i); 0034 break; 0035 } 0036 } 0037 0038 if (m.methodSignature().isEmpty()) { 0039 qCWarning(ACCOUNTWIZARD_LOG) << "Did not find D-Bus method: " << method << " available methods are:"; 0040 for (int i = 0; i < numberOfMethod; ++i) { 0041 qCWarning(ACCOUNTWIZARD_LOG) << mo->method(i).methodSignature(); 0042 } 0043 return QVariant::Invalid; 0044 } 0045 0046 const QList<QByteArray> argTypes = m.parameterTypes(); 0047 if (argTypes.count() != 1) { 0048 return QVariant::Invalid; 0049 } 0050 0051 return QVariant::nameToType(argTypes.first().constData()); 0052 } 0053 0054 Resource::Resource(const QString &type, QObject *parent) 0055 : SetupObject(parent) 0056 , m_typeIdentifier(type) 0057 { 0058 } 0059 0060 void Resource::setOption(const QString &key, const QVariant &value) 0061 { 0062 m_settings.insert(key, value); 0063 } 0064 0065 void Resource::setName(const QString &name) 0066 { 0067 m_name = name; 0068 } 0069 0070 void Resource::create() 0071 { 0072 const AgentType type = AgentManager::self()->type(m_typeIdentifier); 0073 if (!type.isValid()) { 0074 Q_EMIT error(i18n("Resource type '%1' is not available.", m_typeIdentifier)); 0075 return; 0076 } 0077 0078 // check if unique instance already exists 0079 qCDebug(ACCOUNTWIZARD_LOG) << type.capabilities(); 0080 if (type.capabilities().contains(QLatin1StringView("Unique"))) { 0081 const Akonadi::AgentInstance::List lstAgent = AgentManager::self()->instances(); 0082 for (const AgentInstance &instance : lstAgent) { 0083 qCDebug(ACCOUNTWIZARD_LOG) << instance.type().identifier() << (instance.type() == type); 0084 if (instance.type() == type) { 0085 if (m_editMode) { 0086 edit(); 0087 } 0088 Q_EMIT finished(i18n("Resource '%1' is already set up.", type.name())); 0089 return; 0090 } 0091 } 0092 } 0093 0094 Q_EMIT info(i18n("Creating resource instance for '%1'...", type.name())); 0095 auto *job = new AgentInstanceCreateJob(type, this); 0096 connect(job, &AgentInstanceCreateJob::result, this, &Resource::instanceCreateResult); 0097 job->start(); 0098 } 0099 0100 void Resource::instanceCreateResult(KJob *job) 0101 { 0102 if (job->error()) { 0103 Q_EMIT error(i18n("Failed to create resource instance: %1", job->errorText())); 0104 return; 0105 } 0106 0107 m_instance = qobject_cast<AgentInstanceCreateJob *>(job)->instance(); 0108 0109 if (!m_settings.isEmpty()) { 0110 Q_EMIT info(i18n("Configuring resource instance...")); 0111 const auto service = ServerManager::agentServiceName(ServerManager::Resource, m_instance.identifier()); 0112 QDBusInterface iface(service, QStringLiteral("/Settings")); 0113 if (!iface.isValid()) { 0114 Q_EMIT error(i18n("Unable to configure resource instance.")); 0115 return; 0116 } 0117 0118 // configure resource 0119 if (!m_name.isEmpty()) { 0120 m_instance.setName(m_name); 0121 } 0122 QMap<QString, QVariant>::const_iterator end(m_settings.constEnd()); 0123 for (QMap<QString, QVariant>::const_iterator it = m_settings.constBegin(); it != end; ++it) { 0124 qCDebug(ACCOUNTWIZARD_LOG) << "Setting up " << it.key() << " for agent " << m_instance.identifier(); 0125 const QString methodName = QStringLiteral("set%1").arg(it.key()); 0126 QVariant arg = it.value(); 0127 const QVariant::Type targetType = argumentType(iface.metaObject(), methodName); 0128 if (!arg.canConvert(targetType)) { 0129 Q_EMIT error( 0130 i18n("Could not convert value of setting '%1' to required type %2.", it.key(), QLatin1StringView(QVariant::typeToName(targetType)))); 0131 qCWarning(ACCOUNTWIZARD_LOG) << "Impossible to convert argument : " << arg; 0132 return; 0133 } 0134 arg.convert(targetType); 0135 QDBusReply<void> reply = iface.call(methodName, arg); 0136 if (!reply.isValid()) { 0137 Q_EMIT error(i18n("Could not set setting '%1': %2", it.key(), reply.error().message())); 0138 return; 0139 } 0140 } 0141 QDBusReply<void> reply = iface.call(QStringLiteral("save")); 0142 if (!reply.isValid()) { 0143 Q_EMIT error(i18n("Could not save settings: %1", reply.error().message())); 0144 return; 0145 } 0146 m_instance.reconfigure(); 0147 } 0148 0149 if (m_editMode) { 0150 edit(); 0151 } 0152 Q_EMIT finished(i18n("Resource setup completed.")); 0153 } 0154 0155 void Resource::edit() 0156 { 0157 if (m_instance.isValid()) { 0158 QPointer<Akonadi::AgentConfigurationDialog> dlg = new Akonadi::AgentConfigurationDialog(m_instance); 0159 dlg->exec(); 0160 delete dlg; 0161 } 0162 } 0163 0164 void Resource::destroy() 0165 { 0166 if (m_instance.isValid()) { 0167 AgentManager::self()->removeInstance(m_instance); 0168 Q_EMIT info(i18n("Removed resource instance for '%1'.", m_instance.type().name())); 0169 } 0170 } 0171 0172 QString Resource::identifier() 0173 { 0174 return m_instance.identifier(); 0175 } 0176 0177 void Resource::reconfigure() 0178 { 0179 m_instance.reconfigure(); 0180 } 0181 0182 void Resource::setEditMode(const bool editMode) 0183 { 0184 m_editMode = editMode; 0185 } 0186 0187 #include "moc_resource.cpp"