From 27bff00756a151ec029a155660e195a82da840ef Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 26 Oct 2010 13:18:19 +0000 Subject: [PATCH] the previous way to have models didn't work for most engines: some have many keys one for each item. bind a new DataModel into QML that will be associated to a specific DataSource and a key pattern an exact one like "items" of rss or a partial regexp one like "KnowledgeBase-[\d]*" like the ocs engine in this way is not necessary to change how those dataengine works and is possible to use them in QML without headaches svn path=/trunk/KDE/kdebase/runtime/; revision=1189953 --- .../core/corebindingsplugin.cpp | 5 ++ declarativeimports/core/datamodel.cpp | 64 ++++++++++++++++++- declarativeimports/core/datamodel.h | 20 +++++- declarativeimports/core/datasource.cpp | 30 +-------- declarativeimports/core/datasource_p.h | 5 +- 5 files changed, 87 insertions(+), 37 deletions(-) diff --git a/declarativeimports/core/corebindingsplugin.cpp b/declarativeimports/core/corebindingsplugin.cpp index a3accd2bc..cd0c31276 100644 --- a/declarativeimports/core/corebindingsplugin.cpp +++ b/declarativeimports/core/corebindingsplugin.cpp @@ -27,6 +27,7 @@ #include #include "datasource_p.h" +#include "datamodel.h" #include "framesvgitem_p.h" #include "svgitem_p.h" #include "theme_p.h" @@ -43,9 +44,13 @@ void CoreBindingsPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 0, 1, "Theme"); qmlRegisterType(uri, 0, 1, "DataSource"); + qmlRegisterType(uri, 0, 1, "DataModel"); qmlRegisterInterface("Service"); qRegisterMetaType("Service"); + + qmlRegisterInterface("DataSource"); + qRegisterMetaType("DataSource"); } diff --git a/declarativeimports/core/datamodel.cpp b/declarativeimports/core/datamodel.cpp index 713f6a01a..a95e7aa9a 100644 --- a/declarativeimports/core/datamodel.cpp +++ b/declarativeimports/core/datamodel.cpp @@ -1,6 +1,4 @@ /* - * Copyright 2009 by Alan Alpert - * Copyright 2010 by Ménard Alexis * Copyright 2010 by Marco Martin * This program is free software; you can redistribute it and/or modify @@ -20,6 +18,7 @@ */ #include "datamodel.h" +#include "datasource_p.h" #include @@ -27,7 +26,8 @@ namespace Plasma { DataModel::DataModel(QObject* parent) - : QAbstractItemModel(parent) + : QAbstractItemModel(parent), + m_dataSource(0) { setObjectName("DataModel"); } @@ -36,6 +36,64 @@ DataModel::~DataModel() { } +void DataModel::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) +{ + Q_UNUSED(sourceName); + + if (data.contains(m_key) && data.value(m_key).canConvert()) { + setItems(data.value(m_key).value()); + } else { + QRegExp regExp(m_key); + if (!regExp.isValid()) { + return; + } + + QHash::const_iterator i; + QVariantList list; + for (i = data.constBegin(); i != data.constEnd(); ++i) { + if (regExp.exactMatch(i.key())) { + list.append(i.value()); + } + } + setItems(list); + } +} + +void DataModel::setDataSource(QObject *object) +{ + DataSource *source = qobject_cast(object); + if (!source) { + kWarning() << "Error: DataSource type expected"; + return; + } + if (m_dataSource == source) { + return; + } + + disconnect(m_dataSource, 0, this, 0); + m_dataSource = source; + connect(m_dataSource, SIGNAL(newData(const QString &, const Plasma::DataEngine::Data &)), + this, SLOT(dataUpdated(const QString &, const Plasma::DataEngine::Data &))); +} + +QObject *DataModel::dataSource() const +{ + return m_dataSource; +} + +void DataModel::setKey(const QString key) +{ + if (m_key == key) { + return; + } + + m_key = key; +} + +QString DataModel::key() const +{ + return m_key; +} void DataModel::setItems(const QVariantList &list) { diff --git a/declarativeimports/core/datamodel.h b/declarativeimports/core/datamodel.h index 33978b808..7f5f95f0a 100644 --- a/declarativeimports/core/datamodel.h +++ b/declarativeimports/core/datamodel.h @@ -1,6 +1,4 @@ /* - * Copyright 2009 by Alan Alpert - * Copyright 2010 by Ménard Alexis * Copyright 2010 by Marco MArtin * This program is free software; you can redistribute it and/or modify @@ -25,16 +23,29 @@ #include #include +#include + namespace Plasma { +class DataSource; + class DataModel : public QAbstractItemModel { Q_OBJECT + Q_PROPERTY(QObject *dataSource READ dataSource WRITE setDataSource) + Q_PROPERTY(QString key READ key WRITE setKey) + public: DataModel(QObject* parent=0); ~DataModel(); + void setDataSource(QObject *source); + QObject *dataSource() const; + + void setKey(const QString key); + QString key() const; + void setItems(const QVariantList &list); //Reimplemented @@ -51,7 +62,12 @@ Q_SIGNALS: void modelAboutToBeReset(); void modelReset(); +private Q_SLOTS: + void dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data); + private: + DataSource *m_dataSource; + QString m_key; QVector m_items; QHash m_roleNames; }; diff --git a/declarativeimports/core/datasource.cpp b/declarativeimports/core/datasource.cpp index 080b76589..ad0234a8d 100644 --- a/declarativeimports/core/datasource.cpp +++ b/declarativeimports/core/datasource.cpp @@ -20,7 +20,6 @@ */ #include "datasource_p.h" -#include "datamodel.h" #include "qdeclarativeengine.h" #include "qdeclarativecontext.h" @@ -48,11 +47,6 @@ DataSource::DataSource(QObject* parent) this, SLOT(setupData())); } -Plasma::DataModel *DataSource::modelFromKey(const QString &key) -{ - return qobject_cast(qvariant_cast(m_data->value(key.toLatin1()))); -} - void DataSource::setSource(const QString &s) { if (s == m_source) { @@ -99,25 +93,8 @@ void DataSource::dataUpdated(const QString &sourceName, const Plasma::DataEngine // Properties in QML must start lowercase. QString ourKey = key.toLower(); - if (data.value(key).canConvert() && data.value(key).value().first().canConvert()) { - DataModel *model = modelFromKey(ourKey); + m_data->insert(ourKey.toLatin1(), data.value(key)); - if (model) { - model->removeRows(0, model->rowCount()); - } else { - model = new DataModel(m_data); - m_data->insert(ourKey.toLatin1(), qVariantFromValue(static_cast(model))); - } - - model->setItems(data.value(key).value()); - - } else { - DataModel *model = modelFromKey(ourKey); - if (model) { - model->deleteLater(); - } - m_data->insert(ourKey.toLatin1(), data.value(key)); - } newKeys << ourKey; } @@ -126,10 +103,6 @@ void DataSource::dataUpdated(const QString &sourceName, const Plasma::DataEngine //FIXME: pretty utterly inefficient foreach (const QString &key, m_keys) { if (!newKeys.contains(key)) { - DataModel *model = modelFromKey(key); - if (model) { - model->deleteLater(); - } m_data->insert(key.toLatin1(), QVariant()); } } @@ -139,6 +112,7 @@ void DataSource::dataUpdated(const QString &sourceName, const Plasma::DataEngine } emit dataChanged(); + emit newData(sourceName, data); } Plasma::Service *DataSource::service() diff --git a/declarativeimports/core/datasource_p.h b/declarativeimports/core/datasource_p.h index 716d54f9a..24e5a8b26 100644 --- a/declarativeimports/core/datasource_p.h +++ b/declarativeimports/core/datasource_p.h @@ -38,7 +38,6 @@ class QDeclarativePropertyMap; namespace Plasma { class DataEngine; - class DataModel; class DataSource : public QObject, DataEngineConsumer { @@ -79,6 +78,7 @@ namespace Plasma void setupData(); Q_SIGNALS: + void newData(const QString &sourceName, const Plasma::DataEngine::Data &data); void intervalChanged(); void engineChanged(); void sourceChanged(); @@ -86,9 +86,6 @@ namespace Plasma void dataChanged(); void sourcesChanged(); - protected: - inline DataModel *modelFromKey(const QString &key); - private: QString m_id; int m_interval;