diff --git a/src/declarativeimports/core/datasource.cpp b/src/declarativeimports/core/datasource.cpp index 759e5f4fa..4fe5dc520 100644 --- a/src/declarativeimports/core/datasource.cpp +++ b/src/declarativeimports/core/datasource.cpp @@ -26,7 +26,9 @@ namespace Plasma { DataSource::DataSource(QObject *parent) : QObject(parent), + m_ready(false), m_interval(0), + m_intervalAlignment(Plasma::Types::NoAlignment), m_dataEngine(0), m_dataEngineConsumer(0) { @@ -35,6 +37,17 @@ DataSource::DataSource(QObject *parent) setObjectName("DataSource"); } +void DataSource::classBegin() +{ + +} + +void DataSource::componentComplete() +{ + m_ready = true; + setupData(); +} + void DataSource::setConnectedSources(const QStringList &sources) { bool sourcesChanged = false; @@ -43,7 +56,7 @@ void DataSource::setConnectedSources(const QStringList &sources) sourcesChanged = true; if (m_dataEngine) { m_connectedSources.append(source); - m_dataEngine->connectSource(source, this, m_interval); + m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment); emit sourceConnected(source); } } @@ -73,7 +86,48 @@ void DataSource::setEngine(const QString &e) } m_engine = e; - setupData(); + + if (m_engine.isEmpty()) { + emit engineChanged(); + return; + } + + m_dataEngineConsumer = new Plasma::DataEngineConsumer(); + Plasma::DataEngine *engine = dataEngine(m_engine); + if (!engine) { + qWarning() << "DataEngine" << m_engine << "not found"; + emit engineChanged(); + return; + } + + if (m_dataEngine) { + m_dataEngine->disconnect(this); + // Deleting the consumer triggers the reference counting + delete m_dataEngineConsumer; + m_dataEngineConsumer = 0; + } + + /* + * It is due little explanation why this is a queued connection: + * If sourceAdded arrives immediately, in the case we have a datamodel + * with items at source level we connect too soon (before setData for + * all roles is done), having a dataupdated in the datamodel with only + * the first role, killing off the other roles. + * Besides causing a model reset more, unfortunately setRoleNames can be done a single time, so is not possible adding new roles after the + * first setRoleNames() is called. + * This fixes engines that have 1 item per source like the + * recommendations engine. + */ + m_dataEngine = engine; + connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SLOT(updateSources()), Qt::QueuedConnection); + connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SLOT(updateSources())); + + connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SIGNAL(sourceAdded(QString)), Qt::QueuedConnection); + connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SLOT(removeSource(QString))); + connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SIGNAL(sourceRemoved(QString))); + + updateSources(); + emit engineChanged(); } @@ -88,56 +142,30 @@ void DataSource::setInterval(const int interval) emit intervalChanged(); } -//TODO: event compression for this +void DataSource::setIntervalAlignment(Plasma::Types::IntervalAlignment intervalAlignment) +{ + if (intervalAlignment == m_intervalAlignment) { + return; + } + + m_intervalAlignment = intervalAlignment; + setupData(); + emit intervalAlignmentChanged(); +} + void DataSource::setupData() { + if (!m_ready) { + return; + } + // qDebug() << " loading engine " << m_engine; //FIXME: should all services be deleted just because we're changing the interval, etc? qDeleteAll(m_services); m_services.clear(); - if (m_engine.isEmpty()) { - return; - } - - m_dataEngineConsumer = new Plasma::DataEngineConsumer(); - Plasma::DataEngine *engine = dataEngine(m_engine); - if (!engine) { - qWarning() << "DataEngine" << m_engine << "not found"; - return; - } -// qDebug() << "Engine loaed .. . " << m_engine << m_dataEngineConsumer; - - if (engine != m_dataEngine) { - if (m_dataEngine) { - m_dataEngine->disconnect(this); - // Deleting the consumer triggers the reference counting - delete m_dataEngineConsumer; - m_dataEngineConsumer = 0; - } - - /* - * It is due little explanation why this is a queued connection: - * If sourceAdded arrives immediately, in the case we have a datamodel - * with items at source level we connect too soon (before setData for - * all roles is done), having a dataupdated in the datamodel with only - * the first role, killing off the other roles. - * Besides causing a model reset more, unfortunately setRoleNames can be done a single time, so is not possible adding new roles after the - * first setRoleNames() is called. - * This fixes engines that have 1 item per source like the - * recommendations engine. - */ - m_dataEngine = engine; - connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SIGNAL(sourcesChanged()), Qt::QueuedConnection); - connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SIGNAL(sourcesChanged())); - - connect(m_dataEngine, SIGNAL(sourceAdded(QString)), this, SIGNAL(sourceAdded(QString)), Qt::QueuedConnection); - connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SLOT(removeSource(QString))); - connect(m_dataEngine, SIGNAL(sourceRemoved(QString)), this, SIGNAL(sourceRemoved(QString))); - } - foreach (const QString &source, m_connectedSources) { - m_dataEngine->connectSource(source, this, m_interval); + m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment); emit sourceConnected(source); } } @@ -210,7 +238,7 @@ void DataSource::connectSource(const QString &source) m_connectedSources.append(source); if (m_dataEngine) { - m_dataEngine->connectSource(source, this, m_interval); + m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment); emit sourceConnected(source); emit connectedSourcesChanged(); } @@ -226,4 +254,17 @@ void DataSource::disconnectSource(const QString &source) } } +void DataSource::updateSources() +{ + QStringList sources; + if (m_dataEngine) { + sources = m_dataEngine->sources(); + } + + if (sources != m_sources) { + m_sources = sources; + emit sourcesChanged(); + } +} + } diff --git a/src/declarativeimports/core/datasource.h b/src/declarativeimports/core/datasource.h index 3aaa2bbaf..507daf890 100644 --- a/src/declarativeimports/core/datasource.h +++ b/src/declarativeimports/core/datasource.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -40,9 +41,11 @@ class DataEngine; * @class DataSource * @short Provides data from a range of plugins */ -class DataSource : public QObject, DataEngineConsumer +class DataSource : public QObject, public QQmlParserStatus, DataEngineConsumer { Q_OBJECT + Q_INTERFACES(QQmlParserStatus) + public: enum Change { NoChange = 0, @@ -54,6 +57,10 @@ public: typedef QMap Data; DataSource(QObject *parent = 0); + + void classBegin(); + void componentComplete(); + /** * true if the connection to the Plasma DataEngine is valid */ @@ -73,6 +80,16 @@ public: } void setInterval(const int interval); + /** + * The interval to align polling to + */ + Q_PROPERTY(Plasma::Types::IntervalAlignment intervalAlignment READ intervalAlignment WRITE setIntervalAlignment NOTIFY intervalAlignmentChanged) + Plasma::Types::IntervalAlignment intervalAlignment() const + { + return m_intervalAlignment; + } + void setIntervalAlignment(Plasma::Types::IntervalAlignment intervalAlignment); + /** * Plugin name of the Plasma DataEngine */ @@ -100,11 +117,7 @@ public: Q_PROPERTY(QStringList sources READ sources NOTIFY sourcesChanged) QStringList sources() const { - if (m_dataEngine) { - return m_dataEngine->sources(); - } else { - return QStringList(); - } + return m_sources; } /** @@ -151,6 +164,7 @@ public Q_SLOTS: protected Q_SLOTS: void removeSource(const QString &source); void setupData(); + void updateSources(); Q_SIGNALS: void newData(const QString &sourceName, const QVariantMap &data); @@ -159,19 +173,23 @@ Q_SIGNALS: void sourceConnected(const QString &source); void sourceDisconnected(const QString &source); void intervalChanged(); + void intervalAlignmentChanged(); void engineChanged(); void dataChanged(); void connectedSourcesChanged(); void sourcesChanged(); private: + bool m_ready; QString m_id; int m_interval; + Plasma::Types::IntervalAlignment m_intervalAlignment; QString m_engine; QQmlPropertyMap *m_data; QQmlPropertyMap *m_models; Plasma::DataEngine *m_dataEngine; Plasma::DataEngineConsumer *m_dataEngineConsumer; + QStringList m_sources; QStringList m_connectedSources; QStringList m_oldSources; QStringList m_newSources;