File indexing completed on 2023-10-01 04:11:43
0001 /* 0002 SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <aseigo@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef PLASMA_DATACONTAINER_H 0008 #define PLASMA_DATACONTAINER_H 0009 0010 #include <QHash> 0011 #include <QObject> 0012 #include <QTimer> 0013 0014 #include <KJob> 0015 #include <plasma/dataengine.h> 0016 #include <plasma/plasma_export.h> 0017 0018 class QAbstractItemModel; 0019 0020 namespace Plasma 0021 { 0022 class DataContainerPrivate; 0023 0024 /** 0025 * @class DataContainer plasma/datacontainer.h <Plasma/DataContainer> 0026 * 0027 * @brief A set of data exported via a DataEngine 0028 * 0029 * Plasma::DataContainer wraps the data exported by a DataEngine 0030 * implementation, providing a generic wrapper for the data. 0031 * 0032 * A DataContainer may have zero or more associated pieces of data which 0033 * are keyed by strings. The data itself is stored as QVariants. This allows 0034 * easy and flexible retrieval of the information associated with this object 0035 * without writing DataContainer or DataEngine specific code in visualizations. 0036 * 0037 * If you are creating your own DataContainer objects (and are passing them to 0038 * DataEngine::addSource()), you normally just need to listen to the 0039 * updateRequested() signal (as well as any other methods you might have of 0040 * being notified of new data) and call setData() to actually update the data. 0041 * Then you need to either trigger the scheduleSourcesUpdated signal of the 0042 * parent DataEngine or call checkForUpdate() on the DataContainer. 0043 * 0044 * You also need to set a suitable name for the source with setObjectName(). 0045 * See DataEngine::addSource() for more information. 0046 * 0047 * Note that there is normally no need to subclass DataContainer, except as 0048 * a way of encapsulating the data retrieval for a source, since all notifications 0049 * are done via signals rather than virtual methods. 0050 **/ 0051 class PLASMA_EXPORT DataContainer : public QObject 0052 { 0053 friend class DataEngine; 0054 friend class DataEnginePrivate; 0055 Q_OBJECT 0056 0057 public: 0058 /** 0059 * Constructs a default DataContainer that has no name or data 0060 * associated with it 0061 **/ 0062 explicit DataContainer(QObject *parent = nullptr); 0063 ~DataContainer() override; 0064 0065 /** 0066 * Returns the data for this DataContainer 0067 **/ 0068 const DataEngine::Data data() const; 0069 0070 /** 0071 * Set a value for a key. 0072 * 0073 * This also marks this source as needing to signal an update. 0074 * 0075 * If you call setData() directly on a DataContainer, you need to 0076 * either trigger the scheduleSourcesUpdated() slot for the 0077 * data engine it belongs to or call checkForUpdate() on the 0078 * DataContainer. 0079 * 0080 * @param key a string used as the key for the data 0081 * @param value a QVariant holding the actual data. If a invalid 0082 * QVariant is passed in and the key currently exists in the 0083 * data, then the data entry is removed 0084 **/ 0085 void setData(const QString &key, const QVariant &value); 0086 0087 /** 0088 * Removes all data currently associated with this source 0089 * 0090 * If you call removeAllData() on a DataContainer, you need to 0091 * either trigger the scheduleSourcesUpdated() slot for the 0092 * data engine it belongs to or call checkForUpdate() on the 0093 * DataContainer. 0094 **/ 0095 void removeAllData(); 0096 0097 /** 0098 * Associates a model with this DataContainer. Use this for data 0099 * that is intended to be a long list of items. 0100 * 0101 * The ownership of the model is transferred to the DataContainer, 0102 * so the model will be deleted when a new one is set or when the 0103 * DataContainer itself is deleted, so it will be deleted when there won't be any 0104 * visualization associated to this source. 0105 * 0106 * Normally you should set the model from DataEngine::setModel instead from here. 0107 * 0108 * @param model the model that will be associated with this DataContainer 0109 */ 0110 void setModel(QAbstractItemModel *model); 0111 0112 /** 0113 * @return the model owned by this DataSource 0114 */ 0115 QAbstractItemModel *model(); 0116 0117 /** 0118 * @return true if the visualization is currently connected 0119 */ 0120 bool visualizationIsConnected(QObject *visualization) const; 0121 0122 /** 0123 * Connects an object to this DataContainer. 0124 * 0125 * May be called repeatedly for the same visualization without 0126 * side effects 0127 * 0128 * @param visualization the object to connect to this DataContainer 0129 * @param pollingInterval the time in milliseconds between updates 0130 * @param alignment the clock position to align updates to 0131 **/ 0132 void connectVisualization(QObject *visualization, uint pollingInterval, Plasma::Types::IntervalAlignment alignment); 0133 0134 /** 0135 * sets this data container to be automatically stored. 0136 * @param whether this data container should be stored 0137 * @since 4.6 0138 */ 0139 void setStorageEnabled(bool store); 0140 0141 /** 0142 * @return true if the data container has been marked for storage 0143 * @since 4.6 0144 */ 0145 bool isStorageEnabled() const; 0146 0147 /** 0148 * @return true if the data container has been updated, but not stored 0149 */ 0150 bool needsToBeStored() const; 0151 0152 /** 0153 * sets that the data container needs to be stored or not. 0154 * @param whether the data container needs to be stored 0155 */ 0156 void setNeedsToBeStored(bool store); 0157 0158 /** 0159 * @return the DataEngine that the DataContainer is 0160 * a child of. 0161 */ 0162 DataEngine *getDataEngine(); 0163 0164 /** 0165 * @return true if one or more visualizations is connected to this DataContainer 0166 */ 0167 bool isUsed() const; 0168 0169 public Q_SLOTS: 0170 /** 0171 * Disconnects an object from this DataContainer. 0172 * 0173 * Note that if this source was created by DataEngine::sourceRequestEvent(), 0174 * it will be deleted by DataEngine once control returns to the event loop. 0175 **/ 0176 void disconnectVisualization(QObject *visualization); 0177 0178 /** 0179 * Forces immediate update signals to all visualizations 0180 * @since 4.4 0181 */ 0182 void forceImmediateUpdate(); 0183 0184 Q_SIGNALS: 0185 /** 0186 * Emitted when the data has been updated, allowing visualizations to 0187 * reflect the new data. 0188 * 0189 * Note that you should not normally emit this directly. Instead, use 0190 * checkForUpdate() or the DataEngine::scheduleSourcesUpdated() slot. 0191 * 0192 * @param source the objectName() of the DataContainer (and hence the name 0193 * of the source) that updated its data 0194 * @param data the updated data 0195 **/ 0196 void dataUpdated(const QString &source, const Plasma::DataEngine::Data &data); 0197 0198 /** 0199 * A new model has been associated to this source, 0200 * visualizations can safely use it as long they are connected to this source. 0201 * 0202 * @param source the objectName() of the DataContainer (and hence the name 0203 * of the source) that owns the model 0204 * @param model the QAbstractItemModel instance 0205 */ 0206 void modelChanged(const QString &source, QAbstractItemModel *model); 0207 0208 /** 0209 * Emitted when the last visualization is disconnected. 0210 * 0211 * Note that if this source was created by DataEngine::sourceRequestEvent(), 0212 * it will be deleted by DataEngine once control returns to the event loop 0213 * after this signal is emitted. 0214 * 0215 * @param source the name of the source that became unused 0216 **/ 0217 void becameUnused(const QString &source); 0218 0219 /** 0220 * Emitted when an update is requested. 0221 * 0222 * If a polling interval was passed connectVisualization(), this signal 0223 * will be emitted every time the interval expires. 0224 * 0225 * Note that if you create your own DataContainer (and pass it to 0226 * DataEngine::addSource()), you will need to listen to this signal 0227 * and refresh the data when it is triggered. 0228 * 0229 * @param source the datacontainer the update was requested for. Useful 0230 * for classes that update the data for several containers. 0231 **/ 0232 void updateRequested(DataContainer *source); 0233 0234 protected: 0235 /** 0236 * Checks whether any data has changed and, if so, emits dataUpdated(). 0237 **/ 0238 void checkForUpdate(); 0239 0240 /** 0241 * Returns how long ago, in msecs, that the data in this container was last updated. 0242 * 0243 * This is used by DataEngine to compress updates that happen more quickly than the 0244 * minimum polling interval by calling setNeedsUpdate() instead of calling 0245 * updateSourceEvent() immediately. 0246 **/ 0247 uint timeSinceLastUpdate() const; 0248 0249 /** 0250 * Indicates that the data should be treated as dirty the next time hasUpdates() is called. 0251 * 0252 * This is needed for the case where updateRequested() is triggered but we don't want to 0253 * update the data immediately because it has just been updated. The second request won't 0254 * be fulfilled in this case, because we never updated the data and so never called 0255 * checkForUpdate(). So we claim it needs an update anyway. 0256 **/ 0257 void setNeedsUpdate(bool update = true); 0258 0259 protected Q_SLOTS: 0260 /** 0261 * @reimp from QObject 0262 */ 0263 void timerEvent(QTimerEvent *event) override; 0264 0265 private: 0266 friend class SignalRelay; 0267 friend class DataContainerPrivate; 0268 friend class DataEngineManager; 0269 DataContainerPrivate *const d; 0270 0271 Q_PRIVATE_SLOT(d, void storeJobFinished(KJob *job)) 0272 Q_PRIVATE_SLOT(d, void populateFromStoredData(KJob *job)) 0273 Q_PRIVATE_SLOT(d, void retrieve()) 0274 }; 0275 0276 } // Plasma namespace 0277 0278 #endif // multiple inclusion guard