some more win32'fication to fix non-ascii filename handling
[kdelibs.git] / plasma / service.cpp
blobfc96913f827bc806951b02cc0001a632e5364496
1 /*
2 * Copyright 2008 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "service.h"
21 #include "private/service_p.h"
23 #include <QFile>
24 #include <QTimer>
26 #include <kdebug.h>
27 #include <kservice.h>
28 #include <kservicetypetrader.h>
29 #include <ksharedconfig.h>
30 #include <kstandarddirs.h>
31 #include <ktemporaryfile.h>
33 #include "configloader.h"
34 #include "version.h"
35 #include "private/configloader_p.h"
37 namespace Plasma
40 Service::Service(QObject *parent)
41 : QObject(parent),
42 d(new ServicePrivate(this))
46 Service::Service(QObject *parent, const QVariantList &args)
47 : QObject(parent),
48 d(new ServicePrivate(this))
50 Q_UNUSED(args)
53 Service::~Service()
55 delete d;
58 Service *Service::load(const QString &name, QObject *parent)
60 //TODO: scripting API support
61 if (name.isEmpty()) {
62 return new NullService(QString(), parent);
65 QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(name);
66 KService::List offers = KServiceTypeTrader::self()->query("Plasma/Service", constraint);
68 if (offers.isEmpty()) {
69 kDebug() << "offers is empty for " << name;
70 return new NullService(name, parent);
73 KService::Ptr offer = offers.first();
74 QString error;
75 QVariantList args;
76 //args << name;
77 Service *service = 0;
79 if (Plasma::isPluginVersionCompatible(KPluginLoader(*offer).pluginVersion())) {
80 service = offer->createInstance<Plasma::Service>(parent, args, &error);
83 if (!service) {
84 kDebug() << "Couldn't load Service \"" << name << "\"! reason given: " << error;
85 return new NullService(name, parent);
88 if (service->name().isEmpty()) {
89 service->setName(name);
92 return service;
95 void Service::setDestination(const QString &destination)
97 d->destination = destination;
100 QString Service::destination() const
102 return d->destination;
105 QStringList Service::operationNames() const
107 if (!d->config) {
108 kDebug() << "No valid operations scheme has been registered";
109 return QStringList();
112 return d->config->groupList();
115 KConfigGroup Service::operationDescription(const QString &operationName)
117 if (!d->config) {
118 kDebug() << "No valid operations scheme has been registered";
119 return KConfigGroup();
122 d->config->writeConfig();
123 KConfigGroup params(d->config->config(), operationName);
124 //kDebug() << "operation" << operationName
125 // << "requested, has keys" << params.keyList() << "from"
126 // << d->config->config()->name();
127 return params;
130 ServiceJob *Service::startOperationCall(const KConfigGroup &description, QObject *parent)
132 // TODO: nested groups?
133 ServiceJob *job = 0;
134 QString op = description.isValid() ? description.name() : QString();
136 if (!d->config) {
137 kDebug() << "No valid operations scheme has been registered";
138 } else if (!op.isEmpty() && d->config->hasGroup(op)) {
139 if (d->disabledOperations.contains(op)) {
140 kDebug() << "Operation" << op << "is disabled";
141 } else {
142 QMap<QString, QVariant> params;
143 foreach (const QString &key, description.keyList()) {
144 KConfigSkeletonItem *item = d->config->findItem(op, key);
145 if (item) {
146 params.insert(key, description.readEntry(key, item->property()));
150 job = createJob(description.name(), params);
152 } else {
153 kDebug() << "Not a valid group!";
156 if (!job) {
157 job = new NullServiceJob(destination(), op, this);
160 job->setParent(parent ? parent : this);
161 connect(job, SIGNAL(finished(KJob*)), this, SLOT(jobFinished(KJob*)));
162 QTimer::singleShot(0, job, SLOT(slotStart()));
163 return job;
166 void Service::associateWidget(QWidget *widget, const QString &operation)
168 disassociateWidget(widget);
169 d->associatedWidgets.insert(widget, operation);
170 connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(associatedWidgetDestroyed(QObject*)));
172 widget->setEnabled(!d->disabledOperations.contains(operation));
175 void Service::disassociateWidget(QWidget *widget)
177 disconnect(widget, SIGNAL(destroyed(QObject*)),
178 this, SLOT(associatedWidgetDestroyed(QObject*)));
179 d->associatedWidgets.remove(widget);
182 void Service::associateWidget(QGraphicsWidget *widget, const QString &operation)
184 disassociateWidget(widget);
185 d->associatedGraphicsWidgets.insert(widget, operation);
186 connect(widget, SIGNAL(destroyed(QObject*)),
187 this, SLOT(associatedGraphicsWidgetDestroyed(QObject*)));
189 widget->setEnabled(!d->disabledOperations.contains(operation));
192 void Service::disassociateWidget(QGraphicsWidget *widget)
194 disconnect(widget, SIGNAL(destroyed(QObject*)),
195 this, SLOT(associatedGraphicsWidgetDestroyed(QObject*)));
196 d->associatedGraphicsWidgets.remove(widget);
199 QString Service::name() const
201 return d->name;
204 void Service::setName(const QString &name)
206 d->name = name;
208 // now reset the config, which may be based on our name
209 delete d->config;
210 d->config = 0;
212 delete d->tempFile;
213 d->tempFile = 0;
215 registerOperationsScheme();
218 void Service::setOperationEnabled(const QString &operation, bool enable)
220 if (!d->config || !d->config->hasGroup(operation)) {
221 return;
224 if (enable) {
225 d->disabledOperations.remove(operation);
226 } else {
227 d->disabledOperations.insert(operation);
231 QHashIterator<QWidget *, QString> it(d->associatedWidgets);
232 while (it.hasNext()) {
233 it.next();
234 if (it.value() == operation) {
235 it.key()->setEnabled(enable);
241 QHashIterator<QGraphicsWidget *, QString> it(d->associatedGraphicsWidgets);
242 while (it.hasNext()) {
243 it.next();
244 if (it.value() == operation) {
245 it.key()->setEnabled(enable);
251 bool Service::isOperationEnabled(const QString &operation) const
253 return d->config && d->config->hasGroup(operation) && !d->disabledOperations.contains(operation);
256 void Service::setOperationsScheme(QIODevice *xml)
258 delete d->config;
259 delete d->tempFile;
261 //FIXME: make KSharedConfig and KConfigSkeleton not braindamaged in 4.2 and then get rid of the
262 // temp file object here
263 d->tempFile = new KTemporaryFile;
264 d->tempFile->open();
266 KSharedConfigPtr c = KSharedConfig::openConfig(d->tempFile->fileName(), KConfig::NoGlobals);
267 d->config = new ConfigLoader(c, xml, this);
268 d->config->d->setWriteDefaults(true);
270 emit operationsChanged();
273 QHashIterator<QWidget *, QString> it(d->associatedWidgets);
274 while (it.hasNext()) {
275 it.next();
276 it.key()->setEnabled(d->config->hasGroup(it.value()));
281 QHashIterator<QGraphicsWidget *, QString> it(d->associatedGraphicsWidgets);
282 while (it.hasNext()) {
283 it.next();
284 it.key()->setEnabled(d->config->hasGroup(it.value()));
289 void Service::registerOperationsScheme()
291 if (d->config) {
292 // we've already done our job. let's go home.
293 return;
296 if (d->name.isEmpty()) {
297 kDebug() << "No name found";
298 return;
301 QString path = KStandardDirs::locate("data", "plasma/services/" + d->name + ".operations");
303 if (path.isEmpty()) {
304 kDebug() << "Cannot find operations description:" << d->name << ".operations";
305 return;
308 QFile file(path);
309 setOperationsScheme(&file);
312 } // namespace Plasma
314 #include "service.moc"