File indexing completed on 2023-09-24 04:14:57
0001 /* 0002 SPDX-FileCopyrightText: 2008 Aaron Seigo <aseigo@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "service.h" 0008 #include "private/service_p.h" 0009 0010 #include "config-plasma.h" 0011 0012 #include <QFile> 0013 #include <QTimer> 0014 0015 #include <KConfigLoader> 0016 #include <KConfigSkeleton> 0017 #include <KService> 0018 #include <KSharedConfig> 0019 #include <QDebug> 0020 0021 #include <QStandardPaths> 0022 0023 #include "debug_p.h" 0024 #include "pluginloader.h" 0025 #include "version.h" 0026 0027 namespace Plasma 0028 { 0029 Service::Service(QObject *parent) 0030 : QObject(parent) 0031 , d(new ServicePrivate(this)) 0032 { 0033 } 0034 0035 Service::Service(QObject *parent, const QVariantList &args) 0036 : QObject(parent) 0037 , d(new ServicePrivate(this)) 0038 { 0039 Q_UNUSED(args) 0040 } 0041 0042 Service::~Service() 0043 { 0044 delete d; 0045 } 0046 0047 void Service::setDestination(const QString &destination) 0048 { 0049 d->destination = destination; 0050 } 0051 0052 QString Service::destination() const 0053 { 0054 return d->destination; 0055 } 0056 0057 QStringList Service::operationNames() const 0058 { 0059 if (d->operationsMap.isEmpty()) { 0060 #ifndef NDEBUG 0061 // qCDebug(LOG_PLASMA) << "No valid operations scheme has been registered"; 0062 #endif 0063 return QStringList(); 0064 } 0065 0066 return d->operationsMap.keys(); 0067 } 0068 0069 QVariantMap Service::operationDescription(const QString &operationName) 0070 { 0071 if (d->operationsMap.isEmpty()) { 0072 #ifndef NDEBUG 0073 // qCDebug(LOG_PLASMA) << "No valid operations scheme has been registered"; 0074 #endif 0075 return QVariantMap(); 0076 } 0077 0078 // qCDebug(LOG_PLASMA) << "operation" << operationName 0079 // << "requested, has keys" << d->operationsMap.keys(); 0080 return d->operationsMap.value(operationName); 0081 } 0082 0083 ServiceJob *Service::startOperationCall(const QVariantMap &description, QObject *parent) 0084 { 0085 // TODO: nested groups? 0086 ServiceJob *job = nullptr; 0087 const QString op = !description.isEmpty() ? description.value(QStringLiteral("_name")).toString() : QString(); 0088 0089 if (d->operationsMap.isEmpty()) { 0090 #ifndef NDEBUG 0091 // qCDebug(LOG_PLASMA) << "No valid operations scheme has been registered"; 0092 #endif 0093 } else if (!op.isEmpty() && d->operationsMap.contains(op)) { 0094 if (d->disabledOperations.contains(op)) { 0095 #ifndef NDEBUG 0096 // qCDebug(LOG_PLASMA) << "Operation" << op << "is disabled"; 0097 #endif 0098 } else { 0099 QVariantMap map = description; 0100 job = createJob(op, map); 0101 } 0102 } else { 0103 #ifndef NDEBUG 0104 // qCDebug(LOG_PLASMA) << op << "is not a valid group; valid groups are:" << d->operationsMap.keys(); 0105 #endif 0106 } 0107 0108 if (!job) { 0109 job = new NullServiceJob(d->destination, op, this); 0110 } 0111 0112 job->setParent(parent ? parent : this); 0113 QTimer::singleShot(0, job, SLOT(autoStart())); 0114 return job; 0115 } 0116 0117 QString Service::name() const 0118 { 0119 return d->name; 0120 } 0121 0122 void Service::setName(const QString &name) 0123 { 0124 d->name = name; 0125 0126 // now reset the config, which may be based on our name 0127 d->operationsMap.clear(); 0128 0129 registerOperationsScheme(); 0130 0131 Q_EMIT serviceReady(this); 0132 } 0133 0134 void Service::setOperationEnabled(const QString &operation, bool enable) 0135 { 0136 if (d->operationsMap.isEmpty() || !d->operationsMap.contains(operation)) { 0137 return; 0138 } 0139 0140 if (enable) { 0141 d->disabledOperations.remove(operation); 0142 } else { 0143 d->disabledOperations.insert(operation); 0144 } 0145 0146 Q_EMIT operationEnabledChanged(operation, enable); 0147 } 0148 0149 bool Service::isOperationEnabled(const QString &operation) const 0150 { 0151 return d->operationsMap.contains(operation) && !d->disabledOperations.contains(operation); 0152 } 0153 0154 void Service::setOperationsScheme(QIODevice *xml) 0155 { 0156 d->operationsMap.clear(); 0157 0158 // /dev/null is because I need to pass a filename argument to construct a 0159 // KSharedConfig. We need a config object for the config loader even 0160 // though we dont' actually want to use any config parts from it, 0161 // we just want to share the KConfigLoader XML parsing. 0162 KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("/dev/null"), KConfig::SimpleConfig); 0163 KConfigLoader loader(config, xml); 0164 0165 const auto groupList = loader.groupList(); 0166 for (const QString &group : groupList) { 0167 d->operationsMap[group][QStringLiteral("_name")] = group; 0168 } 0169 const auto itemsList = loader.items(); 0170 for (KConfigSkeletonItem *item : itemsList) { 0171 d->operationsMap[item->group()][item->key()] = item->property(); 0172 } 0173 } 0174 0175 void Service::registerOperationsScheme() 0176 { 0177 if (!d->operationsMap.isEmpty()) { 0178 // we've already done our job. let's go home. 0179 return; 0180 } 0181 0182 if (d->name.isEmpty()) { 0183 #ifndef NDEBUG 0184 // qCDebug(LOG_PLASMA) << "No name found"; 0185 #endif 0186 return; 0187 } 0188 0189 const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0190 QStringLiteral(PLASMA_RELATIVE_DATA_INSTALL_DIR "/services/") + d->name + QStringLiteral(".operations")); 0191 0192 if (path.isEmpty()) { 0193 #ifndef NDEBUG 0194 // qCDebug(LOG_PLASMA) << "Cannot find operations description:" << d->name << ".operations"; 0195 #endif 0196 return; 0197 } 0198 0199 QFile file(path); 0200 setOperationsScheme(&file); 0201 } 0202 0203 } // namespace Plasma 0204 0205 #include "moc_service.cpp"