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
This commit is contained in:
Marco Martin 2013-12-24 13:51:20 +01:00
parent 35b43f097e
commit eb47805d72
3 changed files with 55 additions and 0 deletions

View File

@ -21,6 +21,7 @@
#include "private/storage_p.h"
#include <QDebug>
#include <QAbstractItemModel>
#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 *)));
}
}

View File

@ -28,6 +28,8 @@
#include <plasma/plasma_export.h>
#include <plasma/dataengine.h>
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.
*

View File

@ -27,6 +27,8 @@
#include <QtCore/QTime>
#include <QtCore/QBasicTimer>
#include <QAbstractItemModel>
class QTimer;
namespace Plasma
@ -87,6 +89,7 @@ public:
Storage* storage;
QBasicTimer storageTimer;
QBasicTimer checkUsageTimer;
QWeakPointer<QAbstractItemModel> model;
int storageCount;
bool dirty : 1;
bool cached : 1;