From eb47805d72bee6524777280d11af7a38e9adc373 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 24 Dec 2013 13:51:20 +0100 Subject: [PATCH] DataContainer can carry a QAbstractItemModel aroun same rules of sharing and memory management apply. The model will be shared between all visualizations and deleted when nobody is connected to the source anymore --- src/plasma/datacontainer.cpp | 27 +++++++++++++++++++++++++++ src/plasma/datacontainer.h | 25 +++++++++++++++++++++++++ src/plasma/private/datacontainer_p.h | 3 +++ 3 files changed, 55 insertions(+) diff --git a/src/plasma/datacontainer.cpp b/src/plasma/datacontainer.cpp index 3ebc66a3b..58a34bfc2 100644 --- a/src/plasma/datacontainer.cpp +++ b/src/plasma/datacontainer.cpp @@ -21,6 +21,7 @@ #include "private/storage_p.h" #include +#include #include "plasma.h" @@ -65,6 +66,17 @@ void DataContainer::setData(const QString &key, const QVariant &value) setNeedsToBeStored(true); } +void DataContainer::setModel(QAbstractItemModel *model) +{ + if (d->model) { + d->model.data()->deleteLater(); + } + + d->model = model; + model->setParent(this); + emit modelChanged(objectName(), model); +} + void DataContainer::removeAllData() { if (d->data.isEmpty()) { @@ -109,6 +121,9 @@ void DataContainer::connectVisualization(QObject *visualization, uint pollingInt } else { disconnect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); + //modelChanged is always emitted by the dataSource since there is no polling there + disconnect(this, SIGNAL(modelChanged(QString, QAbstractItemModel *)), + visualization, SLOT(modelChanged(QString, QAbstractItemModel *))); //relay->isUnused(); } } else if (pollingInterval < 1) { @@ -120,6 +135,8 @@ void DataContainer::connectVisualization(QObject *visualization, uint pollingInt } else { disconnect(this, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); + disconnect(this, SIGNAL(modelChanged(QString, QAbstractItemModel *)), + visualization, SLOT(modelChanged(QString, QAbstractItemModel *))); } } else { connect(visualization, SIGNAL(destroyed(QObject*)), @@ -131,6 +148,8 @@ void DataContainer::connectVisualization(QObject *visualization, uint pollingInt d->relayObjects[visualization] = 0; connect(this, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); + connect(this, SIGNAL(modelChanged(QString, QAbstractItemModel *)), + visualization, SLOT(modelChanged(QString, QAbstractItemModel *))); } else { //qDebug() << " connecting to a relay"; // we only want to do an imediate update if this is not the first object to connect to us @@ -141,6 +160,9 @@ void DataContainer::connectVisualization(QObject *visualization, uint pollingInt alignment, immediateUpdate); connect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); + //modelChanged is always emitted by the dataSource since there is no polling there + connect(this, SIGNAL(modelChanged(QString, QAbstractItemModel *)), + visualization, SLOT(modelChanged(QString, QAbstractItemModel *))); } } @@ -271,6 +293,8 @@ void DataContainer::disconnectVisualization(QObject *visualization) // it is connected directly to the DataContainer itself disconnect(this, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); + disconnect(this, SIGNAL(modelChanged(QString, QAbstractItemModel *)), + visualization, SLOT(modelChanged(QString, QAbstractItemModel *))); } else { SignalRelay *relay = objIt.value(); @@ -280,6 +304,9 @@ void DataContainer::disconnectVisualization(QObject *visualization) } else { disconnect(relay, SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)), visualization, SLOT(dataUpdated(QString,Plasma::DataEngine::Data))); + //modelChanged is always emitted by the dataSource since there is no polling there + disconnect(this, SIGNAL(modelChanged(QString, QAbstractItemModel *)), + visualization, SLOT(modelChanged(QString, QAbstractItemModel *))); } } diff --git a/src/plasma/datacontainer.h b/src/plasma/datacontainer.h index f7a165980..2a3841427 100644 --- a/src/plasma/datacontainer.h +++ b/src/plasma/datacontainer.h @@ -28,6 +28,8 @@ #include #include +class QAbstractItemModel; + namespace Plasma { @@ -106,6 +108,19 @@ class PLASMA_EXPORT DataContainer : public QObject **/ void removeAllData(); + /** + * Associates a model with this DataContainer. Use this for data + * that is intended to be a long list of items. + * + * The ownership of the model is transferred to the DataContainer, + * so the model will be deletd when a new one is set or when the + * DataContainer itself is deleted, so it will be deleted when there won't be any + * visualization associated to this source. + * + * @param model the model that will be associated with this DataContainer + */ + void setModel(QAbstractItemModel *model); + /** * @return true if the visualization is currently connected */ @@ -188,6 +203,16 @@ class PLASMA_EXPORT DataContainer : public QObject **/ void dataUpdated(const QString &source, const Plasma::DataEngine::Data &data); + /** + * A new model has been associated to this source, + * visualizations can safely use it as long they are connected to this source. + * + * @param source the objectName() of the DataContainer (and hence the name + * of the source) that owns the model + * @param model the QAbstractItemModel instance + */ + void modelChanged(const QString &source, QAbstractItemModel *model); + /** * Emitted when the last visualization is disconnected. * diff --git a/src/plasma/private/datacontainer_p.h b/src/plasma/private/datacontainer_p.h index 19cd3516a..a4760dcda 100644 --- a/src/plasma/private/datacontainer_p.h +++ b/src/plasma/private/datacontainer_p.h @@ -27,6 +27,8 @@ #include #include +#include + class QTimer; namespace Plasma @@ -87,6 +89,7 @@ public: Storage* storage; QBasicTimer storageTimer; QBasicTimer checkUsageTimer; + QWeakPointer model; int storageCount; bool dirty : 1; bool cached : 1;