21#include "private/dataengine_p.h"
22#include "private/datacontainer_p.h"
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"
50DataEngine::DataEngine(
QObject *parent, KService::Ptr service)
52 d(new DataEnginePrivate(this, KPluginInfo(service)))
56DataEngine::DataEngine(
QObject *parent,
const QVariantList &args)
58 d(new DataEnginePrivate(this, KPluginInfo(KService::serviceByStorageId(args.count() > 0 ? args[0].toString() : QString()))))
62DataEngine::~DataEngine()
68QStringList DataEngine::sources()
const
71 return d->script->sources();
73 return d->sources.keys();
77Service *DataEngine::serviceForSource(
const QString &source)
80 Service * s = d->script->serviceForSource(source);
86 return new NullService(source,
this);
89void DataEngine::connectSource(
const QString &source,
QObject *visualization,
102 if (newSource && !s->
data().isEmpty()) {
105 d->connectSource(s, visualization, pollingInterval, intervalAlignment,
106 !newSource || pollingInterval > 0);
111void DataEngine::connectAllSources(
QObject *visualization, uint pollingInterval,
115 d->connectSource(s, visualization, pollingInterval, intervalAlignment);
119void DataEngine::disconnectSource(
const QString &source,
QObject *visualization)
const
130 return d->source(source,
false);
140 }
else if (!newSource && d->minPollingInterval >= 0 &&
153void DataEngine::init()
156 d->setupScriptSupport();
165bool DataEngine::sourceRequestEvent(
const QString &name)
168 return d->script->sourceRequestEvent(
name);
174bool DataEngine::updateSourceEvent(
const QString &source)
177 return d->script->updateSourceEvent(source);
184void DataEngine::setData(
const QString &source,
const QVariant &value)
186 setData(source, source, value);
189void DataEngine::setData(
const QString &source,
const QString &key,
const QVariant &value)
195 s = d->source(source);
200 if (isNew && source != d->waitingSourceRequest) {
207void DataEngine::setData(
const QString &source,
const Data &data)
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) {
229void DataEngine::removeAllData(
const QString &source)
238void DataEngine::removeData(
const QString &source,
const QString &key)
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);
262void DataEngine::setMaxSourceCount(uint limit)
264 if (d->limit == limit) {
273 d->sourceQueue.clear();
277uint DataEngine::maxSourceCount()
const
282void DataEngine::setMinimumPollingInterval(
int minimumMs)
284 d->minPollingInterval = minimumMs;
287int DataEngine::minimumPollingInterval()
const
289 return d->minPollingInterval;
292void DataEngine::setPollingInterval(uint frequency)
294 killTimer(d->updateTimerId);
295 d->updateTimerId = 0;
298 d->updateTimerId = startTimer(frequency);
302void DataEngine::removeSource(
const QString &source)
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);
328void DataEngine::removeAllSources()
330 QMutableHashIterator<QString, Plasma::DataContainer*> it(d->sources);
331 while (it.hasNext()) {
334 const QString source = it.key();
342bool DataEngine::isValid()
const
347bool DataEngine::isEmpty()
const
349 return d->sources.isEmpty();
352void DataEngine::setValid(
bool valid)
362void DataEngine::timerEvent(QTimerEvent *event)
365 if (event->timerId() == d->updateTimerId) {
367 if (d->minPollingInterval < 0) {
373 if (d->updateTimer.elapsed() < d->minPollingInterval) {
378 d->updateTimer.start();
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);
394void DataEngine::updateAllSources()
396 QHashIterator<QString, Plasma::DataContainer*> it(d->sources);
397 while (it.hasNext()) {
406void DataEngine::forceImmediateUpdateOfAllVisualizations()
413void DataEngine::setIcon(
const QString &icon)
418QString DataEngine::icon()
const
423QString DataEngine::pluginName()
const
425 if (!d->dataEngineDescription.isValid()) {
429 return d->dataEngineDescription.pluginName();
432void DataEngine::setDefaultService(
const QString &serviceName)
434 d->serviceName = serviceName;
440 args << QVariant::fromValue<DataEngine*>(
this);
444void 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);
458void DataEnginePrivate::unpublish(
const QString &name)
462 if (publishedService) {
463 publishedService->d->unpublish();
467bool DataEnginePrivate::isPublished()
const
469 if (publishedService) {
470 return publishedService->d->isPublished();
481void DataEngine::scheduleSourcesUpdated()
483 if (d->checkSourcesTimerId) {
487 d->checkSourcesTimerId = startTimer(0);
490QString DataEngine::name()
const
492 return d->engineName;
495void DataEngine::setName(
const QString &name)
497 d->engineName =
name;
501void DataEngine::setStorageEnabled(
const QString &source,
bool store)
510DataEnginePrivate::DataEnginePrivate(
DataEngine *e,
const KPluginInfo &info)
512 dataEngineDescription(info),
514 checkSourcesTimerId(0),
516 minPollingInterval(-1),
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.";
559DataEnginePrivate::~DataEnginePrivate()
567void 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();
588void DataEnginePrivate::ref()
593void DataEnginePrivate::deref()
598bool DataEnginePrivate::isUsed()
const
600 return refCount != 0;
603DataContainer *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);
641void 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()),
679void DataEnginePrivate::sourceDestroyed(
QObject *
object)
681 DataEngine::SourceDict::iterator it =
sources.begin();
683 if (it.value() ==
object) {
685 emit q->sourceRemoved(object->objectName());
692DataContainer *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();
725void 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();
737void DataEnginePrivate::setupScriptSupport()
750 if (!translationsPath.isEmpty()) {
753 KGlobal::dirs()->addResourceDir(
"locale", translationsPath);
760#include "dataengine.moc"
A set of data exported via a DataEngine.
const DataEngine::Data data() const
Returns the data for this DataContainer.
void checkUsage()
Check if the DataContainer is still in use.
uint timeSinceLastUpdate() const
Returns how long ago, in msecs, that the data in this container was last updated.
void disconnectVisualization(QObject *visualization)
Disconnects an object from this DataContainer.
void removeAllData()
Removes all data currently associated with this source.
void setData(const QString &key, const QVariant &value)
Set a value for a key.
void setStorageEnabled(bool store)
sets this data container to be automatically stored.
void forceImmediateUpdate()
Forces immediate update signals to all visualizations.
Data provider for plasmoids (Plasma plugins)
void sourceRemoved(const QString &source)
Emitted when a data source is removed.
virtual bool updateSourceEvent(const QString &source)
Called by internal updating mechanisms to trigger the engine to refresh the data contained in a given...
void setData(const QString &source, const QVariant &value)
Sets a value for a data source.
QHash< QString, DataContainer * > SourceDict
const Package * package() const
Accessor for the associated Package object if any.
void scheduleSourcesUpdated()
Call this method when you call setData directly on a DataContainer instead of using the DataEngine::s...
void updateAllSources()
Immediately updates all existing sources when called.
void removeSource(const QString &source)
Removes a data source.
QHash< QString, QVariant > Data
void sourceAdded(const QString &source)
Emitted when a new data source is created.
KSharedPtr< PackageStructure > Ptr
object representing an installed Plasmagik package
PackageMetadata metadata() const
QString filePath(const char *fileType, const QString &filename) const
Get the path to a given file.
This class provides a generic API for write access to settings or services.
static Service * load(const QString &name, const QVariantList &args, QObject *parent=0)
Used to load a given service from a plugin.
Namespace for everything in libplasma.
PackageStructure::Ptr packageStructure(const QString &language, ComponentType type)
Loads an appropriate PackageStructure for the given language and type.
AppletScript * loadScriptEngine(const QString &language, Applet *applet)
Loads an Applet script engine for the given language.
IntervalAlignment
Possible timing alignments.
@ DataEngineComponent
Plasma::DataEngine based plugins.