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.
21 #include "private/service_p.h"
28 #include <kservicetypetrader.h>
29 #include <ksharedconfig.h>
30 #include <kstandarddirs.h>
31 #include <ktemporaryfile.h>
33 #include "configloader.h"
35 #include "private/configloader_p.h"
40 Service::Service(QObject
*parent
)
42 d(new ServicePrivate(this))
46 Service::Service(QObject
*parent
, const QVariantList
&args
)
48 d(new ServicePrivate(this))
58 Service
*Service::load(const QString
&name
, QObject
*parent
)
60 //TODO: scripting API support
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();
79 if (Plasma::isPluginVersionCompatible(KPluginLoader(*offer
).pluginVersion())) {
80 service
= offer
->createInstance
<Plasma::Service
>(parent
, args
, &error
);
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
);
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
108 kDebug() << "No valid operations scheme has been registered";
109 return QStringList();
112 return d
->config
->groupList();
115 KConfigGroup
Service::operationDescription(const QString
&operationName
)
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();
130 ServiceJob
*Service::startOperationCall(const KConfigGroup
&description
, QObject
*parent
)
132 // TODO: nested groups?
134 QString op
= description
.isValid() ? description
.name() : QString();
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";
142 QMap
<QString
, QVariant
> params
;
143 foreach (const QString
&key
, description
.keyList()) {
144 KConfigSkeletonItem
*item
= d
->config
->findItem(op
, key
);
146 params
.insert(key
, description
.readEntry(key
, item
->property()));
150 job
= createJob(description
.name(), params
);
153 kDebug() << "Not a valid group!";
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()));
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
204 void Service::setName(const QString
&name
)
208 // now reset the config, which may be based on our name
215 registerOperationsScheme();
218 void Service::setOperationEnabled(const QString
&operation
, bool enable
)
220 if (!d
->config
|| !d
->config
->hasGroup(operation
)) {
225 d
->disabledOperations
.remove(operation
);
227 d
->disabledOperations
.insert(operation
);
231 QHashIterator
<QWidget
*, QString
> it(d
->associatedWidgets
);
232 while (it
.hasNext()) {
234 if (it
.value() == operation
) {
235 it
.key()->setEnabled(enable
);
241 QHashIterator
<QGraphicsWidget
*, QString
> it(d
->associatedGraphicsWidgets
);
242 while (it
.hasNext()) {
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
)
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
;
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()) {
276 it
.key()->setEnabled(d
->config
->hasGroup(it
.value()));
281 QHashIterator
<QGraphicsWidget
*, QString
> it(d
->associatedGraphicsWidgets
);
282 while (it
.hasNext()) {
284 it
.key()->setEnabled(d
->config
->hasGroup(it
.value()));
289 void Service::registerOperationsScheme()
292 // we've already done our job. let's go home.
296 if (d
->name
.isEmpty()) {
297 kDebug() << "No name found";
301 QString path
= KStandardDirs::locate("data", "plasma/services/" + d
->name
+ ".operations");
303 if (path
.isEmpty()) {
304 kDebug() << "Cannot find operations description:" << d
->name
<< ".operations";
309 setOperationsScheme(&file
);
312 } // namespace Plasma
314 #include "service.moc"