00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "service.h"
00021 #include "private/service_p.h"
00022
00023 #include <QFile>
00024 #include <QTimer>
00025
00026 #include <kdebug.h>
00027 #include <kservice.h>
00028 #include <kservicetypetrader.h>
00029 #include <ksharedconfig.h>
00030 #include <kstandarddirs.h>
00031 #include <ktemporaryfile.h>
00032
00033 #include "configloader.h"
00034 #include "version.h"
00035 #include "private/configloader_p.h"
00036
00037 namespace Plasma
00038 {
00039
00040 Service::Service(QObject *parent)
00041 : QObject(parent),
00042 d(new ServicePrivate(this))
00043 {
00044 }
00045
00046 Service::Service(QObject *parent, const QVariantList &args)
00047 : QObject(parent),
00048 d(new ServicePrivate(this))
00049 {
00050 Q_UNUSED(args)
00051 }
00052
00053 Service::~Service()
00054 {
00055 delete d;
00056 }
00057
00058 Service *Service::load(const QString &name, QObject *parent)
00059 {
00060
00061 if (name.isEmpty()) {
00062 return new NullService(QString(), parent);
00063 }
00064
00065 QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(name);
00066 KService::List offers = KServiceTypeTrader::self()->query("Plasma/Service", constraint);
00067
00068 if (offers.isEmpty()) {
00069 kDebug() << "offers is empty for " << name;
00070 return new NullService(name, parent);
00071 }
00072
00073 KService::Ptr offer = offers.first();
00074 QString error;
00075 QVariantList args;
00076
00077 Service *service = 0;
00078
00079 if (Plasma::isPluginVersionCompatible(KPluginLoader(*offer).pluginVersion())) {
00080 service = offer->createInstance<Plasma::Service>(parent, args, &error);
00081 }
00082
00083 if (!service) {
00084 kDebug() << "Couldn't load Service \"" << name << "\"! reason given: " << error;
00085 return new NullService(name, parent);
00086 }
00087
00088 if (service->name().isEmpty()) {
00089 service->setName(name);
00090 }
00091
00092 return service;
00093 }
00094
00095 void Service::setDestination(const QString &destination)
00096 {
00097 d->destination = destination;
00098 }
00099
00100 QString Service::destination() const
00101 {
00102 return d->destination;
00103 }
00104
00105 QStringList Service::operationNames() const
00106 {
00107 if (!d->config) {
00108 kDebug() << "No valid operations scheme has been registered";
00109 return QStringList();
00110 }
00111
00112 return d->config->groupList();
00113 }
00114
00115 KConfigGroup Service::operationDescription(const QString &operationName)
00116 {
00117 if (!d->config) {
00118 kDebug() << "No valid operations scheme has been registered";
00119 return d->dummyGroup();
00120 }
00121
00122 d->config->writeConfig();
00123 KConfigGroup params(d->config->config(), operationName);
00124
00125
00126
00127 return params;
00128 }
00129
00130 ServiceJob *Service::startOperationCall(const KConfigGroup &description, QObject *parent)
00131 {
00132
00133 ServiceJob *job = 0;
00134 QString op = description.isValid() ? description.name() : QString();
00135
00136 if (!d->config) {
00137 kDebug() << "No valid operations scheme has been registered";
00138 } else if (!op.isEmpty() && d->config->hasGroup(op)) {
00139 if (d->disabledOperations.contains(op)) {
00140 kDebug() << "Operation" << op << "is disabled";
00141 } else {
00142 QMap<QString, QVariant> params;
00143 foreach (const QString &key, description.keyList()) {
00144 KConfigSkeletonItem *item = d->config->findItem(op, key);
00145 if (item) {
00146 params.insert(key, description.readEntry(key, item->property()));
00147 }
00148 }
00149
00150 job = createJob(description.name(), params);
00151 }
00152 } else {
00153 kDebug() << "Not a valid group!";
00154 }
00155
00156 if (!job) {
00157 job = new NullServiceJob(destination(), op, this);
00158 }
00159
00160 job->setParent(parent ? parent : this);
00161 connect(job, SIGNAL(finished(KJob*)), this, SLOT(jobFinished(KJob*)));
00162 QTimer::singleShot(0, job, SLOT(slotStart()));
00163 return job;
00164 }
00165
00166 void Service::associateWidget(QWidget *widget, const QString &operation)
00167 {
00168 disassociateWidget(widget);
00169 d->associatedWidgets.insert(widget, operation);
00170 connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(associatedWidgetDestroyed(QObject*)));
00171
00172 widget->setEnabled(!d->disabledOperations.contains(operation));
00173 }
00174
00175 void Service::disassociateWidget(QWidget *widget)
00176 {
00177 disconnect(widget, SIGNAL(destroyed(QObject*)),
00178 this, SLOT(associatedWidgetDestroyed(QObject*)));
00179 d->associatedWidgets.remove(widget);
00180 }
00181
00182 void Service::associateWidget(QGraphicsWidget *widget, const QString &operation)
00183 {
00184 disassociateWidget(widget);
00185 d->associatedGraphicsWidgets.insert(widget, operation);
00186 connect(widget, SIGNAL(destroyed(QObject*)),
00187 this, SLOT(associatedGraphicsWidgetDestroyed(QObject*)));
00188
00189 widget->setEnabled(!d->disabledOperations.contains(operation));
00190 }
00191
00192 void Service::disassociateWidget(QGraphicsWidget *widget)
00193 {
00194 disconnect(widget, SIGNAL(destroyed(QObject*)),
00195 this, SLOT(associatedGraphicsWidgetDestroyed(QObject*)));
00196 d->associatedGraphicsWidgets.remove(widget);
00197 }
00198
00199 QString Service::name() const
00200 {
00201 return d->name;
00202 }
00203
00204 void Service::setName(const QString &name)
00205 {
00206 d->name = name;
00207
00208
00209 delete d->config;
00210 d->config = 0;
00211
00212 delete d->tempFile;
00213 d->tempFile = 0;
00214
00215 delete d->dummyConfig;
00216 d->dummyConfig = 0;
00217
00218 registerOperationsScheme();
00219 }
00220
00221 void Service::setOperationEnabled(const QString &operation, bool enable)
00222 {
00223 if (!d->config || !d->config->hasGroup(operation)) {
00224 return;
00225 }
00226
00227 if (enable) {
00228 d->disabledOperations.remove(operation);
00229 } else {
00230 d->disabledOperations.insert(operation);
00231 }
00232
00233 {
00234 QHashIterator<QWidget *, QString> it(d->associatedWidgets);
00235 while (it.hasNext()) {
00236 it.next();
00237 if (it.value() == operation) {
00238 it.key()->setEnabled(enable);
00239 }
00240 }
00241 }
00242
00243 {
00244 QHashIterator<QGraphicsWidget *, QString> it(d->associatedGraphicsWidgets);
00245 while (it.hasNext()) {
00246 it.next();
00247 if (it.value() == operation) {
00248 it.key()->setEnabled(enable);
00249 }
00250 }
00251 }
00252 }
00253
00254 bool Service::isOperationEnabled(const QString &operation) const
00255 {
00256 return d->config && d->config->hasGroup(operation) && !d->disabledOperations.contains(operation);
00257 }
00258
00259 void Service::setOperationsScheme(QIODevice *xml)
00260 {
00261 delete d->config;
00262 delete d->tempFile;
00263
00264 delete d->dummyConfig;
00265 d->dummyConfig = 0;
00266
00267
00268
00269 d->tempFile = new KTemporaryFile;
00270 d->tempFile->open();
00271
00272 KSharedConfigPtr c = KSharedConfig::openConfig(d->tempFile->fileName(), KConfig::NoGlobals);
00273 d->config = new ConfigLoader(c, xml, this);
00274 d->config->d->setWriteDefaults(true);
00275
00276 emit operationsChanged();
00277
00278 {
00279 QHashIterator<QWidget *, QString> it(d->associatedWidgets);
00280 while (it.hasNext()) {
00281 it.next();
00282 it.key()->setEnabled(d->config->hasGroup(it.value()));
00283 }
00284 }
00285
00286 {
00287 QHashIterator<QGraphicsWidget *, QString> it(d->associatedGraphicsWidgets);
00288 while (it.hasNext()) {
00289 it.next();
00290 it.key()->setEnabled(d->config->hasGroup(it.value()));
00291 }
00292 }
00293 }
00294
00295 void Service::registerOperationsScheme()
00296 {
00297 if (d->config) {
00298
00299 return;
00300 }
00301
00302 if (d->name.isEmpty()) {
00303 kDebug() << "No name found";
00304 return;
00305 }
00306
00307 QString path = KStandardDirs::locate("data", "plasma/services/" + d->name + ".operations");
00308
00309 if (path.isEmpty()) {
00310 kDebug() << "Cannot find operations description:" << d->name << ".operations";
00311 return;
00312 }
00313
00314 QFile file(path);
00315 setOperationsScheme(&file);
00316 }
00317
00318 }
00319
00320 #include "service.moc"
00321