Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / workspace / libs / plasma / datacontainer_p.h
blob818676ac0a4d2263acd3346ae3c349977f143424
1 /*
2 * Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #ifndef PLASMA_DATACONTAINER_P_H
21 #define PLASMA_DATACONTAINER_P_H
23 #include <QtCore/QTimerEvent>
24 #include <QtCore/QTime>
26 namespace Plasma
29 class SignalRelay;
31 class DataContainer::Private
33 public:
34 Private()
35 : dirty(false), cached(false)
38 QObject* signalRelay(const DataContainer* dc, QObject *visualization,
39 uint updateInterval, Plasma::IntervalAlignment align);
41 DataEngine::Data data;
42 QMap<QObject *, SignalRelay *> relayObjects;
43 QMap<uint, SignalRelay *> relays;
44 QTime updateTs;
45 bool dirty : 1;
46 bool cached : 1;
49 class SignalRelay : public QObject
51 Q_OBJECT
53 public:
54 SignalRelay(DataContainer* parent, DataContainer::Private *data, uint ival, Plasma::IntervalAlignment align)
55 : QObject(parent),
56 dc(parent),
57 d(data),
58 m_interval(ival),
59 m_align(align),
60 m_resetTimer(true),
61 m_queued(false)
63 //kDebug() << "signal relay with time of" << m_timerId << "being set up";
64 m_timerId = startTimer(0);
65 if (m_align != Plasma::NoAlignment) {
66 checkAlignment();
70 bool isUnused()
72 return receivers(SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data))) < 1;
75 void checkAlignment()
77 int newTime = 0;
79 QTime t = QTime::currentTime();
80 if (m_align == Plasma::AlignToMinute) {
81 int seconds = t.second();
82 if (seconds > 2) {
83 newTime = ((60 - seconds) * 1000) + 500;
85 } else if (m_align == Plasma::AlignToHour) {
86 int minutes = t.minute();
87 int seconds = t.second();
88 if (minutes > 1 || seconds > 10) {
89 newTime = ((60 - minutes) * 1000 * 60) +
90 ((60 - seconds) * 1000) + 500;
94 if (newTime) {
95 killTimer(m_timerId);
96 m_timerId = startTimer(newTime);
97 m_resetTimer = true;
101 void checkQueueing() {
102 if (m_queued) {
103 emit dataUpdated(dc->objectName(), d->data);
104 m_queued = false;
105 //TODO: should we re-align our timer at this point, to avoid
106 // constant queueing due to more-or-less constant time
107 // async update time? this might make sense for
108 // staggered accesses to the same source by multiple
109 // visualizations causing a minimumUpdateInterval violation.
110 // it may not make sense for purely async-and-takes-a-while
111 // type operations (e.g. network fetching).
112 // we need more real world data before making such a change
113 // change
115 // killTimer(m_timerId);
116 // m_timerId = startTime(m_interval);
120 DataContainer *dc;
121 DataContainer::Private *d;
122 uint m_interval;
123 Plasma::IntervalAlignment m_align;
124 int m_timerId;
125 bool m_resetTimer;
126 bool m_queued;
128 signals:
129 void dataUpdated(const QString&, const Plasma::DataEngine::Data&);
131 protected:
132 void timerEvent(QTimerEvent *event)
134 if (m_resetTimer) {
135 killTimer(m_timerId);
136 m_timerId = startTimer(m_interval);
137 m_resetTimer = false;
140 if (m_align != Plasma::NoAlignment) {
141 checkAlignment();
144 emit dc->requestUpdate(dc);
145 if (!dc->hasUpdates()) {
146 // the source wasn't actually updated; so let's put ourselves in the queue
147 // so we get an dataUpdated() when the data does arrive
148 m_queued = true;
149 } else {
150 emit dataUpdated(dc->objectName(), d->data);
152 event->accept();
156 QObject* DataContainer::Private::signalRelay(const DataContainer* dc, QObject *visualization, uint updateInterval, Plasma::IntervalAlignment align)
158 QMap<uint, SignalRelay *>::const_iterator relayIt = relays.find(updateInterval);
159 SignalRelay *relay = 0;
161 //FIXME what if we have two applets with the same interval and different alignment?
162 if (relayIt == relays.end()) {
163 relay = new SignalRelay(const_cast<DataContainer*>(dc), this, updateInterval, align);
164 relays[updateInterval] = relay;
165 } else {
166 relay = relayIt.value();
169 relayObjects[visualization] = relay;
170 return relay;
175 #endif // multiple inclusion guard