Plasma

dataengine.h
1 /*
2  SPDX-FileCopyrightText: 2006-2007 Aaron Seigo <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef PLASMA_DATAENGINE_H
8 #define PLASMA_DATAENGINE_H
9 
10 #include <QHash>
11 #include <QObject>
12 #include <QStringList>
13 
14 #include <plasma/plasma_export.h>
15 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 94)
16 #include <KPluginInfo>
17 #include <KService>
18 #endif
19 
20 #include <KPluginFactory>
21 #include <KPluginMetaData>
22 #include <plasma/plasma.h>
23 #include <plasma/service.h>
24 
25 class QAbstractItemModel;
26 
27 namespace Plasma
28 {
29 class DataContainer;
30 class DataEngineScript;
31 class Package;
32 class Service;
33 class DataEnginePrivate;
34 
35 /**
36  * @class DataEngine plasma/dataengine.h <Plasma/DataEngine>
37  *
38  * @short Data provider for plasmoids (Plasma plugins)
39  *
40  * This is the base class for DataEngines, which provide access to bodies of
41  * data via a common and consistent interface. The common use of a DataEngine
42  * is to provide data to a widget for display. This allows a user interface
43  * element to show all sorts of data: as long as there is a DataEngine, the
44  * data is retrievable.
45  *
46  * DataEngines are loaded as plugins on demand and provide zero, one or more
47  * data sources which are identified by name. For instance, a network
48  * DataEngine might provide a data source for each network interface.
49  **/
50 class PLASMA_EXPORT DataEngine : public QObject
51 {
52  Q_OBJECT
53 
54 public:
59 
60 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 67)
61  /**
62  * Constructor.
63  *
64  * @param parent The parent object.
65  * @param plugin plugin info that describes the engine
66  *
67  * @deprecated since 5.67
68  **/
69  PLASMA_DEPRECATED_VERSION(5, 67, "Use KPluginMetaData")
70  explicit DataEngine(const KPluginInfo &plugin, QObject *parent = nullptr);
71 #endif
72 
73  /**
74  * Constructor.
75  *
76  * @param parent The parent object.
77  * @param plugin metadata that describes the engine
78  *
79  * @since 5.67
80  */
81  explicit DataEngine(const KPluginMetaData &plugin, QObject *parent = nullptr);
82 
83  explicit DataEngine(QObject *parent = nullptr, const QVariantList &args = QVariantList());
84 
85  ~DataEngine() override;
86 
87  /**
88  * @return a list of all the data sources available via this DataEngine
89  * Whether these sources are currently available (which is what
90  * the default implementation provides) or not is up to the
91  * DataEngine to decide.
92  **/
93  virtual QStringList sources() const;
94 
95  /**
96  * @param source the source to target the Service at
97  * @return a Service that has the source as a destination. The service
98  * is parented to the DataEngine, but should be deleted by the
99  * caller when finished with it
100  */
101  Q_INVOKABLE virtual Service *serviceForSource(const QString &source);
102 
103 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 67)
104  /**
105  * @return description of the plugin that implements this DataEngine
106  *
107  * @deprecated since 5.67, use metadata
108  */
109  PLASMA_DEPRECATED_VERSION(5, 67, "Use metadata()")
110  KPluginInfo pluginInfo() const;
111 #endif
112 
113  /**
114  * @return description of the plugin that implements this DataEngine
115  *
116  * @since 5.67
117  */
118  KPluginMetaData metadata() const;
119 
120  /**
121  * Connects a source to an object for data updates. The object must
122  * have a slot with the following signature:
123  * @code
124  * void dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data);
125  * @endcode
126  *
127  * The data is a QHash of QVariants keyed by QString names, allowing
128  * one data source to provide sets of related data.
129  *
130  * @param source the name of the data source
131  * @param visualization the object to connect the data source to
132  * @param pollingInterval the frequency, in milliseconds, with which to check for updates;
133  * a value of 0 (the default) means to update only
134  * when there is new data spontaneously generated
135  * (e.g. by the engine); any other value results in
136  * periodic updates from this source. This value is
137  * per-visualization and can be handy for items that require
138  * constant updates such as scrolling graphs or clocks.
139  * If the data has not changed, no update will be sent.
140  * @param intervalAlignment the number of ms to align the interval to
141  **/
142  Q_INVOKABLE void connectSource(const QString &source,
143  QObject *visualization,
144  uint pollingInterval = 0,
145  Plasma::Types::IntervalAlignment intervalAlignment = Types::NoAlignment) const;
146 
147  /**
148  * Connects all currently existing sources to an object for data updates.
149  * The object must have a slot with the following signature:
150  * @code
151  * void dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data);
152  * @endcode
153  *
154  * The data is a QHash of QVariants keyed by QString names, allowing
155  * one data source to provide sets of related data.
156  *
157  * This method may be called multiple times for the same visualization
158  * without side-effects. This can be useful to change the pollingInterval.
159  *
160  * Note that this method does not automatically connect sources that
161  * may appear later on. Connecting and responding to the sourceAdded signal
162  * is still required to achieve that.
163  *
164  * @param visualization the object to connect the data source to
165  * @param pollingInterval the frequency, in milliseconds, with which to check for updates;
166  * a value of 0 (the default) means to update only
167  * when there is new data spontaneously generated
168  * (e.g. by the engine); any other value results in
169  * periodic updates from this source. This value is
170  * per-visualization and can be handy for items that require
171  * constant updates such as scrolling graphs or clocks.
172  * If the data has not changed, no update will be sent.
173  * @param intervalAlignment the number of ms to align the interval to
174  **/
175  Q_INVOKABLE void
176  connectAllSources(QObject *visualization, uint pollingInterval = 0, Plasma::Types::IntervalAlignment intervalAlignment = Types::NoAlignment) const;
177 
178  /**
179  * Disconnects a source from an object that was receiving data updates.
180  *
181  * @param source the name of the data source
182  * @param visualization the object to connect the data source to
183  **/
184  Q_INVOKABLE void disconnectSource(const QString &source, QObject *visualization) const;
185 
186  /**
187  * Retrieves a pointer to the DataContainer for a given source. This method
188  * should not be used if possible. An exception is for script engines that
189  * can not provide a QMetaObject as required by connectSource for the initial
190  * call to dataUpdated. Using this method, such engines can provide their own
191  * connectSource API.
192  *
193  * @param source the name of the source.
194  * @return pointer to a DataContainer, or zero on failure
195  **/
196  Q_INVOKABLE DataContainer *containerForSource(const QString &source);
197 
198  /**
199  * @return The model associated to a source if any. The ownership of the model stays with the DataContainer.
200  * Returns 0 if there isn't any model associated or if the source doesn't exists.
201  */
202  QAbstractItemModel *modelForSource(const QString &source);
203 
204  /**
205  * Returns true if this engine is valid, otherwise returns false
206  *
207  * @return true if the engine is valid
208  **/
209  bool isValid() const;
210 
211  /**
212  * Returns true if the data engine is empty, which is to say that it has no
213  * data sources currently.
214  *
215  * @return true if the engine has no sources currently
216  */
217  bool isEmpty() const;
218 
219 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 83)
220  /**
221  * Accessor for the associated Package object if any.
222  *
223  * @return the Package object, or 0 if none
224  **/
225  PLASMA_DEPRECATED_VERSION(5, 83, "Use kpackage API instead")
226  Package package() const;
227 #endif
228 
229 Q_SIGNALS:
230  /**
231  * Emitted when a new data source is created
232  *
233  * Note that you do not need to emit this yourself unless
234  * you are reimplementing sources() and want to advertise
235  * that a new source is available (but hasn't been created
236  * yet).
237  *
238  * @param source the name of the new data source
239  **/
240  void sourceAdded(const QString &source);
241 
242  /**
243  * Emitted when a data source is removed.
244  *
245  * Note that you do not need to emit this yourself unless
246  * you have reimplemented sources() and want to signal that
247  * a source that was available but was never created is no
248  * longer available.
249  *
250  * @param source the name of the data source that was removed
251  **/
252  void sourceRemoved(const QString &source);
253 
254 protected:
255  /**
256  * When a source that does not currently exist is requested by the
257  * consumer, this method is called to give the DataEngine the
258  * opportunity to create one.
259  *
260  * The name of the data source (e.g. the source parameter passed into
261  * setData) must be the same as the name passed to sourceRequestEvent
262  * otherwise the requesting visualization may not receive notice of a
263  * data update.
264  *
265  * If the source can not be populated with data immediately (e.g. due to
266  * an asynchronous data acquisition method such as an HTTP request)
267  * the source must still be created, even if it is empty. This can
268  * be accomplished in these cases with the follow line:
269  *
270  * setData(name, DataEngine::Data());
271  *
272  * @param source the name of the source that has been requested
273  * @return true if a DataContainer was set up, false otherwise
274  */
275  virtual bool sourceRequestEvent(const QString &source);
276 
277  /**
278  * Called by internal updating mechanisms to trigger the engine
279  * to refresh the data contained in a given source. Reimplement this
280  * method when using facilities such as setPollingInterval.
281  * @see setPollingInterval
282  *
283  * @param source the name of the source that should be updated
284  * @return true if the data was changed, or false if there was no
285  * change or if the change will occur later
286  **/
287  virtual bool updateSourceEvent(const QString &source);
288 
289  /**
290  * Sets a value for a data source. If the source
291  * doesn't exist then it is created.
292  *
293  * @param source the name of the data source
294  * @param value the data to associated with the source
295  **/
296  void setData(const QString &source, const QVariant &value);
297 
298  /**
299  * Sets a value for a data source. If the source
300  * doesn't exist then it is created.
301  *
302  * @param source the name of the data source
303  * @param key the key to use for the data
304  * @param value the data to associated with the source
305  **/
306  void setData(const QString &source, const QString &key, const QVariant &value);
307 
308  /**
309  * Adds a set of data to a data source. If the source
310  * doesn't exist then it is created.
311  *
312  * @param source the name of the data source
313  * @param data the data to add to the source
314  **/
315  void setData(const QString &source, const QVariantMap &data);
316 
317  /**
318  * Removes all the data associated with a data source.
319  *
320  * @param source the name of the data source
321  **/
322  void removeAllData(const QString &source);
323 
324  /**
325  * Removes a data entry from a source
326  *
327  * @param source the name of the data source
328  * @param key the data entry to remove
329  **/
330  void removeData(const QString &source, const QString &key);
331 
332  /**
333  * Associates a model to a data source. If the source
334  * doesn't exist then it is created. The source will have the key "HasModel" to easily indicate there is a model present.
335  *
336  * The ownership of the model is transferred to the DataContainer,
337  * so the model will be deleted when a new one is set or when the
338  * DataContainer itself is deleted. As the DataContainer, it will be
339  * deleted when there won't be any
340  * visualization associated to this source.
341  *
342  * @param source the name of the data source
343  * @param model the model instance
344  */
345  void setModel(const QString &source, QAbstractItemModel *model);
346 
347  /**
348  * Adds an already constructed data source. The DataEngine takes
349  * ownership of the DataContainer object. The objectName of the source
350  * is used for the source name.
351  *
352  * @param source the DataContainer to add to the DataEngine
353  **/
354  void addSource(DataContainer *source);
355 
356  /**
357  * Sets the minimum amount of time, in milliseconds, that must pass between
358  * successive updates of data. This can help prevent too many updates happening
359  * due to multiple update requests coming in, which can be useful for
360  * expensive (time- or resource-wise) update mechanisms.
361  *
362  * The default minimumPollingInterval is -1, or "never perform automatic updates"
363  *
364  * @param minimumMs the minimum time lapse, in milliseconds, between updates.
365  * A value less than 0 means to never perform automatic updates,
366  * a value of 0 means update immediately on every update request,
367  * a value >0 will result in a minimum time lapse being enforced.
368  **/
369  void setMinimumPollingInterval(int minimumMs);
370 
371  /**
372  * @return the minimum time between updates. @see setMinimumPollingInterval
373  **/
374  int minimumPollingInterval() const;
375 
376  /**
377  * Sets up an internal update tick for all data sources. On every update,
378  * updateSourceEvent will be called for each applicable source.
379  * @see updateSourceEvent
380  *
381  * @param frequency the time, in milliseconds, between updates. A value of 0
382  * will stop internally triggered updates.
383  **/
384  void setPollingInterval(uint frequency);
385 
386  /**
387  * Removes all data sources
388  **/
389  void removeAllSources();
390 
391  /**
392  * Sets whether or not this engine is valid, e.g. can be used.
393  * In practice, only the internal fall-back engine, the NullEngine
394  * should have need for this.
395  *
396  * @param valid whether or not the engine is valid
397  **/
398  void setValid(bool valid);
399 
400  /**
401  * @return the list of active DataContainers.
402  */
403  QHash<QString, DataContainer *> containerDict() const;
404 
405  /**
406  * Reimplemented from QObject
407  **/
408  void timerEvent(QTimerEvent *event) override;
409 
410  /**
411  * Sets a source to be stored for easy retrieval
412  * when the real source of the data (usually a network connection)
413  * is unavailable.
414  * @param source the name of the source
415  * @param store if source should be stored
416  * @since 4.6
417  */
418  void setStorageEnabled(const QString &source, bool store);
419 
420 protected Q_SLOTS:
421  /**
422  * Removes a data source.
423  * @param source the name of the data source to remove
424  **/
425  void removeSource(const QString &source);
426 
427  /**
428  * Immediately updates all existing sources when called
429  */
430  void updateAllSources();
431 
432  /**
433  * Forces an immediate update to all connected sources, even those with
434  * timeouts that haven't yet expired. This should _only_ be used when
435  * there was no data available, e.g. due to network non-availability,
436  * and then it becomes available. Normal changes in data values due to
437  * calls to updateSource or in the natural progression of the monitored
438  * object (e.g. CPU heat) should not result in a call to this method!
439  *
440  * @since 4.4
441  */
442  void forceImmediateUpdateOfAllVisualizations();
443 
444 private:
445  friend class DataEnginePrivate;
446  friend class DataEngineScript;
447  friend class DataEngineManager;
448  friend class PlasmoidServiceJob;
449  friend class NullEngine;
450 
451  Q_PRIVATE_SLOT(d, void internalUpdateSource(DataContainer *source))
452  Q_PRIVATE_SLOT(d, void sourceDestroyed(QObject *object))
453  Q_PRIVATE_SLOT(d, void scheduleSourcesUpdated())
454 
455  DataEnginePrivate *d;
456 };
457 
458 } // Plasma namespace
459 
460 #if PLASMA_ENABLE_DEPRECATED_SINCE(5, 88)
461 /**
462  * Register a data engine when it is contained in a loadable module
463  * @deprecated Since 5.88, use K_PLUGIN_CLASS_WITH_JSON instead
464  */
465 /* clang-format off */
466 #define K_EXPORT_PLASMA_DATAENGINE(libname, classname) \
467  K_PLUGIN_FACTORY(factory, registerPlugin<classname>();)
468 
469 /// @deprecated Since 5.88, use K_PLUGIN_CLASS_WITH_JSON instead
470 #define K_EXPORT_PLASMA_DATAENGINE_WITH_JSON(libname, classname, jsonFile) \
471  K_PLUGIN_FACTORY_WITH_JSON(factory, jsonFile, registerPlugin<classname>();)
472 /* clang-format on */
473 #endif
474 
475 #endif // multiple inclusion guard
Provides a restricted interface for scripting a DataEngine.
Data provider for plasmoids (Plasma plugins)
Definition: dataengine.h:50
Namespace for everything in libplasma.
Definition: datamodel.cpp:14
This class provides a generic API for write access to settings or services.
Definition: service.h:77
A set of data exported via a DataEngine.
Definition: datacontainer.h:51
@ NoAlignment
No alignment.
Definition: plasma.h:224
IntervalAlignment
Possible timing alignments.
Definition: plasma.h:223
object representing an installed Plasma package
Definition: package.h:76
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Feb 5 2023 04:14:15 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.