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 KConfigGroup();
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 registerOperationsScheme();
00216 }
00217
00218 void Service::setOperationEnabled(const QString &operation, bool enable)
00219 {
00220 if (!d->config || !d->config->hasGroup(operation)) {
00221 return;
00222 }
00223
00224 if (enable) {
00225 d->disabledOperations.remove(operation);
00226 } else {
00227 d->disabledOperations.insert(operation);
00228 }
00229
00230 {
00231 QHashIterator<QWidget *, QString> it(d->associatedWidgets);
00232 while (it.hasNext()) {
00233 it.next();
00234 if (it.value() == operation) {
00235 it.key()->setEnabled(enable);
00236 }
00237 }
00238 }
00239
00240 {
00241 QHashIterator<QGraphicsWidget *, QString> it(d->associatedGraphicsWidgets);
00242 while (it.hasNext()) {
00243 it.next();
00244 if (it.value() == operation) {
00245 it.key()->setEnabled(enable);
00246 }
00247 }
00248 }
00249 }
00250
00251 bool Service::isOperationEnabled(const QString &operation) const
00252 {
00253 return d->config && d->config->hasGroup(operation) && !d->disabledOperations.contains(operation);
00254 }
00255
00256 void Service::setOperationsScheme(QIODevice *xml)
00257 {
00258 delete d->config;
00259 delete d->tempFile;
00260
00261
00262
00263 d->tempFile = new KTemporaryFile;
00264 d->tempFile->open();
00265
00266 KSharedConfigPtr c = KSharedConfig::openConfig(d->tempFile->fileName(), KConfig::NoGlobals);
00267 d->config = new ConfigLoader(c, xml, this);
00268 d->config->d->setWriteDefaults(true);
00269
00270 emit operationsChanged();
00271
00272 {
00273 QHashIterator<QWidget *, QString> it(d->associatedWidgets);
00274 while (it.hasNext()) {
00275 it.next();
00276 it.key()->setEnabled(d->config->hasGroup(it.value()));
00277 }
00278 }
00279
00280 {
00281 QHashIterator<QGraphicsWidget *, QString> it(d->associatedGraphicsWidgets);
00282 while (it.hasNext()) {
00283 it.next();
00284 it.key()->setEnabled(d->config->hasGroup(it.value()));
00285 }
00286 }
00287 }
00288
00289 void Service::registerOperationsScheme()
00290 {
00291 if (d->config) {
00292
00293 return;
00294 }
00295
00296 if (d->name.isEmpty()) {
00297 kDebug() << "No name found";
00298 return;
00299 }
00300
00301 QString path = KStandardDirs::locate("data", "plasma/services/" + d->name + ".operations");
00302
00303 if (path.isEmpty()) {
00304 kDebug() << "Cannot find operations description:" << d->name << ".operations";
00305 return;
00306 }
00307
00308 QFile file(path);
00309 setOperationsScheme(&file);
00310 }
00311
00312 }
00313
00314 #include "service.moc"
00315