• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Plasma

  • sources
  • kde-4.12
  • kdelibs
  • plasma
service.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Aaron Seigo <aseigo@kde.org>
3  *
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.
8  *
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
13  *
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.
18  */
19 
20 #include "service.h"
21 #include "servicejob.h"
22 #include "private/authorizationmanager_p.h"
23 #include "private/service_p.h"
24 #include "private/serviceprovider_p.h"
25 
26 #include "config-plasma.h"
27 
28 #include <QFile>
29 #include <QGraphicsWidget>
30 #include <QTimer>
31 
32 #include <kdebug.h>
33 #include <kservice.h>
34 #include <kservicetypetrader.h>
35 #include <ksharedconfig.h>
36 #include <kstandarddirs.h>
37 #include <dnssd/publicservice.h>
38 #include <dnssd/servicebrowser.h>
39 
40 #include "configloader.h"
41 #include "version.h"
42 #include "private/configloader_p.h"
43 #include "private/remoteservice_p.h"
44 #include "private/remoteservicejob_p.h"
45 #include "pluginloader.h"
46 
47 namespace Plasma
48 {
49 
50 Service::Service(QObject *parent)
51  : QObject(parent),
52  d(new ServicePrivate(this))
53 {
54 }
55 
56 Service::Service(QObject *parent, const QVariantList &args)
57  : QObject(parent),
58  d(new ServicePrivate(this))
59 {
60  Q_UNUSED(args)
61 }
62 
63 Service::~Service()
64 {
65  d->unpublish();
66  delete d;
67 }
68 
69 Service *Service::load(const QString &name, QObject *parent)
70 {
71  QVariantList args;
72  return load(name, args, parent);
73 }
74 
75 Service *Service::load(const QString &name, const QVariantList &args, QObject *parent)
76 {
77  return PluginLoader::pluginLoader()->loadService(name, args, parent);
78 }
79 
80 Service *Service::access(const KUrl &url, QObject *parent)
81 {
82  return new RemoteService(parent, url);
83 }
84 
85 void ServicePrivate::jobFinished(KJob *job)
86 {
87  emit q->finished(static_cast<ServiceJob*>(job));
88 }
89 
90 void ServicePrivate::associatedWidgetDestroyed(QObject *obj)
91 {
92  associatedWidgets.remove(static_cast<QWidget*>(obj));
93 }
94 
95 void ServicePrivate::associatedGraphicsWidgetDestroyed(QObject *obj)
96 {
97  associatedGraphicsWidgets.remove(static_cast<QGraphicsObject*>(obj));
98 }
99 
100 void ServicePrivate::publish(AnnouncementMethods methods, const QString &name, const PackageMetadata &metadata)
101 {
102 #ifdef ENABLE_REMOTE_WIDGETS
103  if (!serviceProvider) {
104  AuthorizationManager::self()->d->prepareForServicePublication();
105 
106  serviceProvider = new ServiceProvider(name, q);
107 
108  if (methods.testFlag(ZeroconfAnnouncement) &&
109  (DNSSD::ServiceBrowser::isAvailable() == DNSSD::ServiceBrowser::Working)) {
110  //TODO: dynamically pick a free port number.
111  publicService = new DNSSD::PublicService(name, "_plasma._tcp", 4000);
112 
113  QMap<QString, QByteArray> textData;
114  textData["name"] = name.toUtf8();
115  textData["plasmoidname"] = metadata.name().toUtf8();
116  textData["description"] = metadata.description().toUtf8();
117  textData["icon"] = metadata.icon().toUtf8();
118  publicService->setTextData(textData);
119  kDebug() << "about to publish";
120 
121  publicService->publishAsync();
122  } else if (methods.testFlag(ZeroconfAnnouncement) &&
123  (DNSSD::ServiceBrowser::isAvailable() != DNSSD::ServiceBrowser::Working)) {
124  kDebug() << "sorry, but your zeroconf daemon doesn't seem to be running.";
125  }
126  } else {
127  kDebug() << "already published!";
128  }
129 #else
130  kWarning() << "libplasma is compiled without support for remote widgets. not publishing.";
131 #endif
132 }
133 
134 void ServicePrivate::unpublish()
135 {
136  delete serviceProvider;
137  serviceProvider = 0;
138 
139  delete publicService;
140  publicService = 0;
141 }
142 
143 bool ServicePrivate::isPublished() const
144 {
145  if (serviceProvider) {
146  return true;
147  } else {
148  return false;
149  }
150 }
151 
152 KConfigGroup ServicePrivate::dummyGroup()
153 {
154  if (!dummyConfig) {
155  dummyConfig = new KConfig(QString(), KConfig::SimpleConfig);
156  }
157 
158  return KConfigGroup(dummyConfig, "DummyGroup");
159 }
160 
161 void Service::setDestination(const QString &destination)
162 {
163  d->destination = destination;
164 }
165 
166 QString Service::destination() const
167 {
168  return d->destination;
169 }
170 
171 QStringList Service::operationNames() const
172 {
173  if (!d->config) {
174  kDebug() << "No valid operations scheme has been registered";
175  return QStringList();
176  }
177 
178  return d->config->groupList();
179 }
180 
181 KConfigGroup Service::operationDescription(const QString &operationName)
182 {
183  if (!d->config) {
184  kDebug() << "No valid operations scheme has been registered";
185  return d->dummyGroup();
186  }
187 
188  d->config->writeConfig();
189  KConfigGroup params(d->config->config(), operationName);
190  //kDebug() << "operation" << operationName
191  // << "requested, has keys" << params.keyList() << "from"
192  // << d->config->config()->name();
193  return params;
194 }
195 
196 QMap<QString, QVariant> Service::parametersFromDescription(const KConfigGroup &description)
197 {
198  QMap<QString, QVariant> params;
199 
200  if (!d->config || !description.isValid()) {
201  return params;
202  }
203 
204  const QString op = description.name();
205  foreach (const QString &key, description.keyList()) {
206  KConfigSkeletonItem *item = d->config->findItem(op, key);
207  if (item) {
208  params.insert(key, description.readEntry(key, item->property()));
209  }
210  }
211 
212  return params;
213 }
214 
215 ServiceJob *Service::startOperationCall(const KConfigGroup &description, QObject *parent)
216 {
217  // TODO: nested groups?
218  ServiceJob *job = 0;
219  const QString op = description.isValid() ? description.name() : QString();
220 
221  RemoteService *rs = qobject_cast<RemoteService *>(this);
222  if (!op.isEmpty() && rs && !rs->isReady()) {
223  // if we have an operation, but a non-ready remote service, just let it through
224  kDebug() << "Remote service is not ready; queueing operation";
225  QMap<QString, QVariant> params;
226  job = createJob(op, params);
227  RemoteServiceJob *rsj = qobject_cast<RemoteServiceJob *>(job);
228  if (rsj) {
229  rsj->setDelayedDescription(description);
230  }
231  } else if (!d->config) {
232  kDebug() << "No valid operations scheme has been registered";
233  } else if (!op.isEmpty() && d->config->hasGroup(op)) {
234  if (d->disabledOperations.contains(op)) {
235  kDebug() << "Operation" << op << "is disabled";
236  } else {
237  QMap<QString, QVariant> params = parametersFromDescription(description);
238  job = createJob(op, params);
239  }
240  } else {
241  kDebug() << op << "is not a valid group; valid groups are:" << d->config->groupList();
242  }
243 
244  if (!job) {
245  job = new NullServiceJob(destination(), op, this);
246  }
247 
248  job->setParent(parent ? parent : this);
249  connect(job, SIGNAL(finished(KJob*)), this, SLOT(jobFinished(KJob*)));
250  QTimer::singleShot(0, job, SLOT(autoStart()));
251  return job;
252 }
253 
254 void Service::associateWidget(QWidget *widget, const QString &operation)
255 {
256  if (!widget) {
257  return;
258  }
259 
260  disassociateWidget(widget);
261  d->associatedWidgets.insert(widget, operation);
262  connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(associatedWidgetDestroyed(QObject*)));
263 
264  widget->setEnabled(!d->disabledOperations.contains(operation));
265 }
266 
267 void Service::disassociateWidget(QWidget *widget)
268 {
269  if (!widget) {
270  return;
271  }
272 
273  disconnect(widget, SIGNAL(destroyed(QObject*)),
274  this, SLOT(associatedWidgetDestroyed(QObject*)));
275  d->associatedWidgets.remove(widget);
276 }
277 
278 void Service::associateWidget(QGraphicsWidget *widget, const QString &operation)
279 {
280  associateItem(widget, operation);
281 }
282 
283 void Service::disassociateWidget(QGraphicsWidget *widget)
284 {
285  disassociateItem(widget);
286 }
287 
288 void Service::associateItem(QGraphicsObject *widget, const QString &operation)
289 {
290  if (!widget) {
291  return;
292  }
293 
294  disassociateItem(widget);
295  d->associatedGraphicsWidgets.insert(widget, operation);
296  connect(widget, SIGNAL(destroyed(QObject*)),
297  this, SLOT(associatedGraphicsWidgetDestroyed(QObject*)));
298 
299  widget->setEnabled(!d->disabledOperations.contains(operation));
300 }
301 
302 void Service::disassociateItem(QGraphicsObject *widget)
303 {
304  if (!widget) {
305  return;
306  }
307 
308  disconnect(widget, SIGNAL(destroyed(QObject*)),
309  this, SLOT(associatedGraphicsWidgetDestroyed(QObject*)));
310  d->associatedGraphicsWidgets.remove(widget);
311 }
312 
313 QString Service::name() const
314 {
315  return d->name;
316 }
317 
318 void Service::setName(const QString &name)
319 {
320  d->name = name;
321 
322  // now reset the config, which may be based on our name
323  delete d->config;
324  d->config = 0;
325 
326  delete d->dummyConfig;
327  d->dummyConfig = 0;
328 
329  registerOperationsScheme();
330 
331  emit serviceReady(this);
332 }
333 
334 void Service::setOperationEnabled(const QString &operation, bool enable)
335 {
336  if (!d->config || !d->config->hasGroup(operation)) {
337  return;
338  }
339 
340  if (enable) {
341  d->disabledOperations.remove(operation);
342  } else {
343  d->disabledOperations.insert(operation);
344  }
345 
346  {
347  QHashIterator<QWidget *, QString> it(d->associatedWidgets);
348  while (it.hasNext()) {
349  it.next();
350  if (it.value() == operation) {
351  it.key()->setEnabled(enable);
352  }
353  }
354  }
355 
356  {
357  QHashIterator<QGraphicsObject *, QString> it(d->associatedGraphicsWidgets);
358  while (it.hasNext()) {
359  it.next();
360  if (it.value() == operation) {
361  it.key()->setEnabled(enable);
362  }
363  }
364  }
365 }
366 
367 bool Service::isOperationEnabled(const QString &operation) const
368 {
369  return d->config && d->config->hasGroup(operation) && !d->disabledOperations.contains(operation);
370 }
371 
372 void Service::setOperationsScheme(QIODevice *xml)
373 {
374  delete d->config;
375 
376  delete d->dummyConfig;
377  d->dummyConfig = 0;
378 
379  KSharedConfigPtr c = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
380  d->config = new ConfigLoader(c, xml, this);
381  d->config->d->setWriteDefaults(true);
382 
383  emit operationsChanged();
384 
385  {
386  QHashIterator<QWidget *, QString> it(d->associatedWidgets);
387  while (it.hasNext()) {
388  it.next();
389  it.key()->setEnabled(d->config->hasGroup(it.value()));
390  }
391  }
392 
393  {
394  QHashIterator<QGraphicsObject *, QString> it(d->associatedGraphicsWidgets);
395  while (it.hasNext()) {
396  it.next();
397  it.key()->setEnabled(d->config->hasGroup(it.value()));
398  }
399  }
400 }
401 
402 void Service::registerOperationsScheme()
403 {
404  if (d->config) {
405  // we've already done our job. let's go home.
406  return;
407  }
408 
409  if (d->name.isEmpty()) {
410  kDebug() << "No name found";
411  return;
412  }
413 
414  const QString path = KStandardDirs::locate("data", "plasma/services/" + d->name + ".operations");
415 
416  if (path.isEmpty()) {
417  kDebug() << "Cannot find operations description:" << d->name << ".operations";
418  return;
419  }
420 
421  QFile file(path);
422  setOperationsScheme(&file);
423 }
424 
425 } // namespace Plasma
426 
427 #include "service.moc"
428 
Plasma::Service::setName
void setName(const QString &name)
Sets the name of the Service; useful for Services not loaded from plugins, which use the plugin name ...
Definition: service.cpp:318
Plasma::PluginLoader::pluginLoader
static PluginLoader * pluginLoader()
Return the active plugin loader.
Definition: pluginloader.cpp:67
Plasma::Service::Service
Service(QObject *parent=0)
Default constructor.
Definition: service.cpp:50
Plasma::ServiceJob
This class provides jobs for use with Plasma::Service.
Definition: servicejob.h:54
Plasma::Service::startOperationCall
Q_INVOKABLE ServiceJob * startOperationCall(const KConfigGroup &description, QObject *parent=0)
Called to create a ServiceJob which is associated with a given operation and parameter set...
Definition: service.cpp:215
Plasma::Service::load
static Service * load(const QString &name, const QVariantList &args, QObject *parent=0)
Used to load a given service from a plugin.
Definition: service.cpp:75
Plasma::Service::setOperationEnabled
void setOperationEnabled(const QString &operation, bool enable)
Enables a given service by name.
Definition: service.cpp:334
pluginloader.h
Plasma::Service::setOperationsScheme
void setOperationsScheme(QIODevice *xml)
Sets the XML used to define the operation schema for this Service.
Definition: service.cpp:372
Plasma::Service::disassociateWidget
Q_INVOKABLE void disassociateWidget(QWidget *widget)
Disassociates a widget if it has been associated with an operation on this service.
Definition: service.cpp:267
QWidget
Plasma::Service::operationsChanged
void operationsChanged()
Emitted when the Service's operations change.
Plasma::Service::destination
Q_INVOKABLE QString destination() const
QObject
Plasma::AuthorizationManager::self
static AuthorizationManager * self()
Singleton pattern accessor.
Definition: authorizationmanager.cpp:64
Plasma::Service::operationDescription
Q_INVOKABLE KConfigGroup operationDescription(const QString &operationName)
Retrieves the parameters for a given operation.
Definition: service.cpp:181
Plasma::Service
This class provides a generic API for write access to settings or services.
Definition: service.h:91
Plasma::Service::finished
void finished(Plasma::ServiceJob *job)
Emitted when a job associated with this Service completes its task.
Plasma::Service::setDestination
Q_INVOKABLE void setDestination(const QString &destination)
Sets the destination for this Service to operate on.
Definition: service.cpp:161
Plasma::Service::associateWidget
Q_INVOKABLE void associateWidget(QWidget *widget, const QString &operation)
Assoicates a widget with an operation, which allows the service to automatically manage, for example, the enabled state of a widget.
Definition: service.cpp:254
Plasma::Service::associateItem
Q_INVOKABLE void associateItem(QGraphicsObject *item, const QString &operation)
Associates a graphics item with an operation, which allows the service to automatically manage...
Definition: service.cpp:288
servicejob.h
Plasma::Service::parametersFromDescription
Q_INVOKABLE QMap< QString, QVariant > parametersFromDescription(const KConfigGroup &description)
Definition: service.cpp:196
configloader.h
Plasma::Service::createJob
virtual ServiceJob * createJob(const QString &operation, QMap< QString, QVariant > &parameters)=0
Called when a job should be created by the Service.
version.h
Plasma::Service::isOperationEnabled
Q_INVOKABLE bool isOperationEnabled(const QString &operation) const
Query to find if an operation is enabled or not.
Definition: service.cpp:367
Plasma::Service::name
Q_INVOKABLE QString name() const
The name of this service.
service.h
Plasma::PluginLoader::loadService
Service * loadService(const QString &name, const QVariantList &args, QObject *parent=0)
Load a Service plugin.
Definition: pluginloader.cpp:206
Plasma::ZeroconfAnnouncement
Announcements via ZeroConf.
Definition: plasma.h:267
Plasma::Service::serviceReady
void serviceReady(Plasma::Service *service)
Emitted when this service is ready for use.
Plasma::Service::access
static Service * access(const KUrl &url, QObject *parent=0)
Used to access a service from an url.
Definition: service.cpp:80
Plasma::Service::registerOperationsScheme
virtual void registerOperationsScheme()
By default this is based on the file in plasma/services/name.operations, but can be reimplented to us...
Definition: service.cpp:402
Plasma::Service::operationNames
Q_INVOKABLE QStringList operationNames() const
Plasma::ConfigLoader
Definition: configloader.h:75
Plasma::Service::~Service
~Service()
Destructor.
Definition: service.cpp:63
KJob
Plasma::Service::disassociateItem
Q_INVOKABLE void disassociateItem(QGraphicsObject *widget)
Disassociates a graphics item if it has been associated with an operation on this service...
Definition: service.cpp:302
QGraphicsWidget
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:34 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal