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
This commit is contained in:
Marco Martin 2010-10-26 13:18:19 +00:00
parent 7ee1ebf5ac
commit 27bff00756
5 changed files with 87 additions and 37 deletions

View File

@ -27,6 +27,7 @@
#include <Plasma/Svg>
#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<ThemeProxy>(uri, 0, 1, "Theme");
qmlRegisterType<Plasma::DataSource>(uri, 0, 1, "DataSource");
qmlRegisterType<Plasma::DataModel>(uri, 0, 1, "DataModel");
qmlRegisterInterface<Plasma::Service>("Service");
qRegisterMetaType<Plasma::Service*>("Service");
qmlRegisterInterface<Plasma::DataSource>("DataSource");
qRegisterMetaType<Plasma::DataSource*>("DataSource");
}

View File

@ -1,6 +1,4 @@
/*
* Copyright 2009 by Alan Alpert <alan.alpert@nokia.com>
* Copyright 2010 by Ménard Alexis <menard@kde.org>
* Copyright 2010 by Marco Martin <mart@kde.org>
* This program is free software; you can redistribute it and/or modify
@ -20,6 +18,7 @@
*/
#include "datamodel.h"
#include "datasource_p.h"
#include <KDebug>
@ -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<QVariantList>()) {
setItems(data.value(m_key).value<QVariantList>());
} else {
QRegExp regExp(m_key);
if (!regExp.isValid()) {
return;
}
QHash<QString, QVariant>::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<DataSource *>(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)
{

View File

@ -1,6 +1,4 @@
/*
* Copyright 2009 by Alan Alpert <alan.alpert@nokia.com>
* Copyright 2010 by Ménard Alexis <menard@kde.org>
* Copyright 2010 by Marco MArtin <mart@kde.org>
* This program is free software; you can redistribute it and/or modify
@ -25,16 +23,29 @@
#include <QAbstractItemModel>
#include <QVector>
#include <Plasma/DataEngine>
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<QVariant> m_items;
QHash<int, QByteArray> m_roleNames;
};

View File

@ -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<DataModel*>(qvariant_cast<QObject*>(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<QVariantList>() && data.value(key).value<QVariantList>().first().canConvert<QVariantMap>()) {
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<QObject*>(model)));
}
model->setItems(data.value(key).value<QVariantList>());
} 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()

View File

@ -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;