Plasma

datasource.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Alan Alpert <[email protected]>
3  SPDX-FileCopyrightText: 2010 Ménard Alexis <[email protected]>
4  SPDX-FileCopyrightText: 2010 Marco Martin <[email protected]>
5  SPDX-FileCopyrightText: 2013 Sebastian Kügler <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "datasource.h"
11 
12 #include <QAbstractItemModel>
13 
14 namespace Plasma
15 {
16 DataSource::DataSource(QObject *parent)
17  : QObject(parent)
18  , m_ready(false)
19  , m_interval(0)
20  , m_intervalAlignment(Plasma::Types::NoAlignment)
21 {
22  m_models = new QQmlPropertyMap(this);
23  m_data = new QQmlPropertyMap(this);
24  setObjectName(QStringLiteral("DataSource"));
25 }
26 
27 void DataSource::classBegin()
28 {
29 }
30 
31 void DataSource::componentComplete()
32 {
33  m_ready = true;
34  setupData();
35 }
36 
37 void DataSource::setConnectedSources(const QStringList &sources)
38 {
39  bool sourcesChanged = false;
40  for (const QString &source : sources) {
41  if (!m_connectedSources.contains(source)) {
42  sourcesChanged = true;
43  if (m_dataEngine) {
44  m_connectedSources.append(source);
45  m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment);
46  Q_EMIT sourceConnected(source);
47  }
48  }
49  }
50 
51  for (const QString &source : std::as_const(m_connectedSources)) {
52  if (!sources.contains(source)) {
53  m_data->clear(source);
54  sourcesChanged = true;
55  if (m_dataEngine) {
56  m_dataEngine->disconnectSource(source, this);
57  Q_EMIT sourceDisconnected(source);
58  }
59  }
60  }
61 
62  if (sourcesChanged) {
63  m_connectedSources = sources;
64  Q_EMIT connectedSourcesChanged();
65  }
66 }
67 
68 void DataSource::setEngine(const QString &e)
69 {
70  if (e == m_engine) {
71  return;
72  }
73 
74  m_engine = e;
75 
76  if (m_engine.isEmpty()) {
77  Q_EMIT engineChanged();
78  return;
79  }
80 
81  m_dataEngineConsumer.reset(new Plasma::DataEngineConsumer());
82  Plasma::DataEngine *engine = dataEngine(m_engine);
83  if (!engine) {
84  qWarning() << "DataEngine" << m_engine << "not found";
85  Q_EMIT engineChanged();
86  return;
87  }
88 
89  if (m_dataEngine) {
90  m_dataEngine->disconnect(this);
91  // Deleting the consumer triggers the reference counting
92  m_dataEngineConsumer.reset();
93  }
94 
95  /*
96  * It is due little explanation why this is a queued connection:
97  * If sourceAdded arrives immediately, in the case we have a datamodel
98  * with items at source level we connect too soon (before setData for
99  * all roles is done), having a dataupdated in the datamodel with only
100  * the first role, killing off the other roles.
101  * Besides causing a model reset more, unfortunately setRoleNames can be done a single time, so is not possible adding new roles after the
102  * first setRoleNames() is called.
103  * This fixes engines that have 1 item per source like the
104  * recommendations engine.
105  */
106  m_dataEngine = engine;
107  connect(m_dataEngine, &DataEngine::sourceAdded, this, &DataSource::updateSources, Qt::QueuedConnection);
108  connect(m_dataEngine, &DataEngine::sourceRemoved, this, &DataSource::updateSources);
109 
110  connect(m_dataEngine, &DataEngine::sourceAdded, this, &DataSource::sourceAdded, Qt::QueuedConnection);
111  connect(m_dataEngine, &DataEngine::sourceRemoved, this, &DataSource::removeSource);
112  connect(m_dataEngine, &DataEngine::sourceRemoved, this, &DataSource::sourceRemoved);
113 
114  updateSources();
115 
116  Q_EMIT engineChanged();
117 }
118 
119 void DataSource::setInterval(const int interval)
120 {
121  if (interval == m_interval) {
122  return;
123  }
124 
125  m_interval = interval;
126  setupData();
127  Q_EMIT intervalChanged();
128 }
129 
130 void DataSource::setIntervalAlignment(Plasma::Types::IntervalAlignment intervalAlignment)
131 {
132  if (intervalAlignment == m_intervalAlignment) {
133  return;
134  }
135 
136  m_intervalAlignment = intervalAlignment;
137  setupData();
138  Q_EMIT intervalAlignmentChanged();
139 }
140 
141 void DataSource::setupData()
142 {
143  if (!m_ready) {
144  return;
145  }
146 
147  // qDebug() << " loading engine " << m_engine;
148  // FIXME: should all services be deleted just because we're changing the interval, etc?
149  qDeleteAll(m_services);
150  m_services.clear();
151 
152  for (const QString &source : std::as_const(m_connectedSources)) {
153  m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment);
154  Q_EMIT sourceConnected(source);
155  }
156 }
157 
158 void DataSource::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data)
159 {
160  // it can arrive also data we don't explicitly connected a source
161  if (m_connectedSources.contains(sourceName)) {
162  m_data->insert(sourceName, data);
163  Q_EMIT dataChanged();
164  Q_EMIT newData(sourceName, data);
165  } else if (m_dataEngine) {
166  m_dataEngine->disconnectSource(sourceName, this);
167  }
168 }
169 
170 void DataSource::modelChanged(const QString &sourceName, QAbstractItemModel *model)
171 {
172  if (!model) {
173  m_models->clear(sourceName);
174  return;
175  }
176 
177  m_models->insert(sourceName, QVariant::fromValue(model));
178  // FIXME: this will break in the case a second model is set
179  connect(model, &QObject::destroyed, m_models, [=]() {
180  m_models->clear(sourceName);
181  });
182 }
183 
184 void DataSource::removeSource(const QString &source)
185 {
186  m_data->clear(source);
187  m_models->clear(source);
188 
189  // TODO: emit those signals as last thing
190  if (m_connectedSources.contains(source)) {
191  m_connectedSources.removeAll(source);
192  Q_EMIT sourceDisconnected(source);
193  Q_EMIT connectedSourcesChanged();
194  }
195 
196  if (m_dataEngine) {
197  QHash<QString, Plasma::Service *>::iterator it = m_services.find(source);
198  if (it != m_services.end()) {
199  delete it.value();
200  m_services.erase(it);
201  }
202  }
203 }
204 
206 {
207  if (!m_services.contains(source)) {
208  Plasma::Service *service = m_dataEngine->serviceForSource(source);
209  if (!service) {
210  return nullptr;
211  }
212  m_services[source] = service;
213  }
214 
215  return m_services.value(source);
216 }
217 
219 {
220  if (m_connectedSources.contains(source)) {
221  return;
222  }
223 
224  m_connectedSources.append(source);
225  if (m_dataEngine) {
226  m_dataEngine->connectSource(source, this, m_interval, m_intervalAlignment);
227  Q_EMIT sourceConnected(source);
228  Q_EMIT connectedSourcesChanged();
229  }
230 }
231 
233 {
234  if (m_dataEngine && m_connectedSources.contains(source)) {
235  m_connectedSources.removeAll(source);
236  m_dataEngine->disconnectSource(source, this);
237  Q_EMIT sourceDisconnected(source);
238  Q_EMIT connectedSourcesChanged();
239  }
240 }
241 
242 void DataSource::updateSources()
243 {
245  if (m_dataEngine) {
246  sources = m_dataEngine->sources();
247  }
248 
249  if (sources != m_sources) {
250  m_sources = sources;
251  Q_EMIT sourcesChanged();
252  }
253 }
254 
255 }
256 
257 #include "moc_datasource.cpp"
void append(const T &value)
void insert(const QString &key, const QVariant &value)
const T value(const Key &key) const const
QQmlPropertyMap data
All the data fetched by this dataengine.
Definition: datasource.h:121
void clear(const QString &key)
Data provider for plasmoids (Plasma plugins)
Definition: dataengine.h:50
Q_INVOKABLE QObject * serviceForSource(const QString &source)
Definition: datasource.cpp:205
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
Namespace for everything in libplasma.
Definition: datamodel.cpp:14
void sourceRemoved(const QString &source)
Emitted when a data source is removed.
QVariant fromValue(const T &value)
virtual QStringList sources() const
Definition: dataengine.cpp:76
Q_EMITQ_EMIT
int interval
Polling interval in milliseconds when the data will be fetched again.
Definition: datasource.h:64
Plasma::Types::IntervalAlignment intervalAlignment
The interval to align polling to.
Definition: datasource.h:74
QHash::iterator erase(QHash::iterator pos)
int removeAll(const T &value)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QHash::iterator find(const Key &key)
void clear()
virtual Q_INVOKABLE Service * serviceForSource(const QString &source)
Definition: dataengine.cpp:85
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Q_INVOKABLE void connectSource(const QString &source, QObject *visualization, uint pollingInterval=0, Plasma::Types::IntervalAlignment intervalAlignment=Types::NoAlignment) const
Connects a source to an object for data updates.
Definition: dataengine.cpp:109
Q_INVOKABLE void connectSource(const QString &source)
Connects a new source and adds it to the connectedSources list.
Definition: datasource.cpp:218
void destroyed(QObject *obj)
QStringList sources
Read-only list of all the sources available from the DataEngine (connected or not).
Definition: datasource.h:105
This class provides a generic API for write access to settings or services.
Definition: service.h:77
void sourceAdded(const QString &source)
Emitted when a new data source is created.
bool isEmpty() const const
QueuedConnection
Q_INVOKABLE void disconnectSource(const QString &source)
Disconnects from a DataEngine source and removes it from the connectedSources list.
Definition: datasource.cpp:232
void setObjectName(const QString &name)
IntervalAlignment
Possible timing alignments.
Definition: plasma.h:223
bool contains(const Key &key) const const
QString dataEngine
Plugin name of the Plasma DataEngine.
Definition: datasource.h:84
Q_INVOKABLE void disconnectSource(const QString &source, QObject *visualization) const
Disconnects a source from an object that was receiving data updates.
Definition: dataengine.cpp:135
QHash::iterator end()
A class that makes it safe and easy to use DataEngines.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Sep 30 2023 04:08:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.