21 #include "private/dataengine_p.h"
22 #include "private/datacontainer_p.h"
27 #include <QTimerEvent>
31 #include <kplugininfo.h>
33 #include <kstandarddirs.h>
41 #include "private/authorizationmanager_p.h"
42 #include "private/dataengineservice_p.h"
43 #include "private/remotedataengine_p.h"
44 #include "private/service_p.h"
45 #include "private/storage_p.h"
52 d(new DataEnginePrivate(this, KPluginInfo(service)))
58 d(new DataEnginePrivate(this, KPluginInfo(KService::serviceByStorageId(args.count() > 0 ? args[0].
toString() : QString()))))
71 return d->script->sources();
73 return d->sources.keys();
80 Service * s = d->script->serviceForSource(source);
86 return new NullService(source,
this);
102 if (newSource && !s->
data().isEmpty()) {
105 d->connectSource(s, visualization, pollingInterval, intervalAlignment,
106 !newSource || pollingInterval > 0);
115 d->connectSource(s, visualization, pollingInterval, intervalAlignment);
130 return d->source(source,
false);
140 }
else if (!newSource && d->minPollingInterval >= 0 &&
156 d->setupScriptSupport();
168 return d->script->sourceRequestEvent(name);
177 return d->script->updateSourceEvent(source);
186 setData(source, source, value);
195 s = d->source(source);
200 if (isNew && source != d->waitingSourceRequest) {
213 s = d->source(source);
216 Data::const_iterator it = data.constBegin();
217 while (it != data.constEnd()) {
218 s->
setData(it.key(), it.value());
222 if (isNew && source != d->waitingSourceRequest) {
249 if (d->sources.contains(source->objectName())) {
250 kDebug() <<
"source named \"" << source->objectName() <<
"\" already exists.";
254 QObject::connect(source, SIGNAL(updateRequested(
DataContainer*)),
256 QObject::connect(source, SIGNAL(destroyed(
QObject*)),
this, SLOT(sourceDestroyed(
QObject*)));
257 d->sources.insert(source->objectName(), source);
264 if (d->limit == limit) {
273 d->sourceQueue.clear();
284 d->minPollingInterval = minimumMs;
289 return d->minPollingInterval;
294 killTimer(d->updateTimerId);
295 d->updateTimerId = 0;
298 d->updateTimerId = startTimer(frequency);
304 SourceDict::iterator it = d->sources.find(source);
305 if (it != d->sources.end()) {
310 QQueue<DataContainer*>::iterator it = d->sourceQueue.begin();
311 while (it != d->sourceQueue.end()) {
313 d->sourceQueue.erase(it);
323 d->sources.erase(it);
330 QMutableHashIterator<QString, Plasma::DataContainer*> it(d->sources);
331 while (it.hasNext()) {
334 const QString source = it.key();
349 return d->sources.isEmpty();
365 if (event->timerId() == d->updateTimerId) {
367 if (d->minPollingInterval < 0) {
373 if (d->updateTimestamp.elapsed() < d->minPollingInterval) {
378 d->updateTimestamp.restart();
380 }
else if (event->timerId() == d->checkSourcesTimerId) {
381 killTimer(d->checkSourcesTimerId);
382 d->checkSourcesTimerId = 0;
384 QHashIterator<QString, Plasma::DataContainer*> it(d->sources);
385 while (it.hasNext()) {
387 it.value()->checkForUpdate();
390 QObject::timerEvent(event);
396 QHashIterator<QString, Plasma::DataContainer*> it(d->sources);
397 while (it.hasNext()) {
425 if (!d->dataEngineDescription.isValid()) {
429 return d->dataEngineDescription.pluginName();
434 d->serviceName = serviceName;
440 args << QVariant::fromValue<DataEngine*>(
this);
444 void DataEnginePrivate::publish(AnnouncementMethods methods,
const QString &name)
446 if (!publishedService) {
447 publishedService =
new DataEngineService(q);
454 kDebug() <<
"name: " << name;
455 publishedService->d->publish(methods, name);
458 void DataEnginePrivate::unpublish(
const QString &name)
462 if (publishedService) {
463 publishedService->d->unpublish();
467 bool DataEnginePrivate::isPublished()
const
469 if (publishedService) {
470 return publishedService->d->isPublished();
483 if (d->checkSourcesTimerId) {
487 d->checkSourcesTimerId = startTimer(0);
492 return d->engineName;
497 d->engineName =
name;
510 DataEnginePrivate::DataEnginePrivate(
DataEngine *e,
const KPluginInfo &info)
512 dataEngineDescription(info),
514 checkSourcesTimerId(0),
516 minPollingInterval(-1),
523 updateTimestamp.start();
525 if (!info.isValid()) {
526 engineName = i18n(
"Unnamed");
530 engineName = info.name();
531 if (engineName.isEmpty()) {
532 engineName = i18n(
"Unnamed");
534 e->setObjectName(engineName);
537 if (dataEngineDescription.isValid()) {
538 QString api = dataEngineDescription.property(
"X-Plasma-API").toString();
540 if (!api.isEmpty()) {
542 KStandardDirs::locate(
"data",
543 "plasma/dataengines/" + dataEngineDescription.pluginName() +
'/');
545 structure->setPath(path);
546 package = new Package(path, structure);
550 kDebug() <<
"Could not create a" << api <<
"ScriptEngine for the"
551 << dataEngineDescription.name() <<
"DataEngine.";
559 DataEnginePrivate::~DataEnginePrivate()
567 void DataEnginePrivate::internalUpdateSource(DataContainer *source)
569 if (minPollingInterval > 0 &&
570 source->timeSinceLastUpdate() < (uint)minPollingInterval) {
576 source->setNeedsUpdate();
580 if (q->updateSourceEvent(source->objectName())) {
582 q->scheduleSourcesUpdated();
588 void DataEnginePrivate::ref()
593 void DataEnginePrivate::deref()
598 bool DataEnginePrivate::isUsed()
const
600 return refCount != 0;
603 DataContainer *DataEnginePrivate::source(
const QString &sourceName,
bool createWhenMissing)
605 DataEngine::SourceDict::const_iterator it =
sources.constFind(sourceName);
606 if (it !=
sources.constEnd()) {
607 DataContainer *s = it.value();
609 QQueue<DataContainer*>::iterator it = sourceQueue.begin();
610 while (it != sourceQueue.end()) {
612 sourceQueue.erase(it);
617 sourceQueue.enqueue(s);
622 if (!createWhenMissing) {
627 DataContainer *s =
new DataContainer(q);
628 s->setObjectName(sourceName);
630 QObject::connect(s, SIGNAL(destroyed(
QObject*)), q, SLOT(sourceDestroyed(
QObject*)));
631 QObject::connect(s, SIGNAL(updateRequested(DataContainer*)),
632 q, SLOT(internalUpdateSource(DataContainer*)));
636 sourceQueue.enqueue(s);
641 void DataEnginePrivate::connectSource(DataContainer *s,
QObject *visualization,
642 uint pollingInterval,
649 if (pollingInterval == 0 && qobject_cast<RemoteDataEngine *>(q)) {
650 pollingInterval = 5000;
652 if (pollingInterval > 0) {
654 uint min = qMax(50, minPollingInterval);
655 pollingInterval = qMax(min, pollingInterval);
658 pollingInterval = pollingInterval - (pollingInterval % 50);
665 immediateCall = !s->data().isEmpty() &&
666 !s->visualizationIsConnected(visualization);
669 s->connectVisualization(visualization, pollingInterval, align);
672 QMetaObject::invokeMethod(visualization,
"dataUpdated",
673 Q_ARG(QString, s->objectName()),
679 void DataEnginePrivate::sourceDestroyed(
QObject *
object)
681 DataEngine::SourceDict::iterator it =
sources.begin();
683 if (it.value() == object) {
685 emit q->sourceRemoved(object->objectName());
692 DataContainer *DataEnginePrivate::requestSource(
const QString &sourceName,
bool *newSource)
699 DataContainer *s = source(sourceName,
false);
706 waitingSourceRequest = sourceName;
707 if (q->sourceRequestEvent(sourceName)) {
708 s = source(sourceName,
false);
715 QObject::connect(s, SIGNAL(becameUnused(QString)), q, SLOT(
removeSource(QString)));
716 emit q->sourceAdded(sourceName);
719 waitingSourceRequest.clear();
725 void DataEnginePrivate::trimQueue()
727 uint queueCount = sourceQueue.count();
728 while (queueCount >= limit && !sourceQueue.isEmpty()) {
729 DataContainer *punted = sourceQueue.dequeue();
730 q->removeSource(punted->objectName());
731 queueCount = sourceQueue.count();
737 void DataEnginePrivate::setupScriptSupport()
750 if (!translationsPath.isEmpty()) {
753 KGlobal::dirs()->addResourceDir(
"locale", translationsPath);
760 #include "dataengine.moc"