From e15c950bc36281b3cdd86bf762f20b9410dfde38 Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Wed, 12 Sep 2007 17:53:54 +0000 Subject: [PATCH] introduce interval alignment, so it is possible to align a time interval to the minute or hour (we can add arbitrary ones to the mix should we choose; e.g. "every 10 mins" or whatever..but there needs to be good use cases =) this is needed by clocks, as the obvious example, since "once a minute" isn't enough: it needs to be once a minute *on* the minute svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=711737 --- datacontainer.cpp | 14 +++++------- datacontainer.h | 8 +------ datacontainer_p.h | 56 +++++++++++++++++++++++++++++++++++++++++------ dataengine.cpp | 14 +++++++----- dataengine.h | 9 ++++++-- plasma.h | 8 +++++++ 6 files changed, 78 insertions(+), 31 deletions(-) diff --git a/datacontainer.cpp b/datacontainer.cpp index 43b8e78cc..a48648a7d 100644 --- a/datacontainer.cpp +++ b/datacontainer.cpp @@ -16,6 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "plasma.h" #include "datacontainer.h" #include "datacontainer_p.h" @@ -76,11 +77,6 @@ void DataContainer::checkForUpdate() } } -QObject* DataContainer::signalRelay(QObject *visualization, uint updateInterval) const -{ - return d->signalRelay(this, visualization, updateInterval); -} - void DataContainer::checkUsage() { if (d->relays.count() < 1 && @@ -90,7 +86,7 @@ void DataContainer::checkUsage() } } -void DataContainer::connectVisualization(QObject* visualization, uint updateInterval) +void DataContainer::connectVisualization(QObject* visualization, uint updateInterval, Plasma::IntervalAlignment alignment) { // kDebug() << "connecting visualization" << (void*)visualization << "at interval of" << updateInterval; QMap::iterator objIt = d->relayObjects.find(visualization); @@ -105,7 +101,7 @@ void DataContainer::connectVisualization(QObject* visualization, uint updateInte visualization, SLOT(updated(QString,Plasma::DataEngine::Data))); if (relay->isUnused()) { - d->relays.erase(d->relays.find(relay->interval)); + d->relays.erase(d->relays.find(relay->m_interval)); delete relay; } // kDebug() << " already connected, but to a relay"; @@ -134,7 +130,7 @@ void DataContainer::connectVisualization(QObject* visualization, uint updateInte visualization, SLOT(updated(QString,Plasma::DataEngine::Data))); } else { // kDebug() << " connecting to a relay"; - connect(signalRelay(visualization, updateInterval), + connect(d->signalRelay(this, visualization, updateInterval, alignment), SIGNAL(updated(QString,Plasma::DataEngine::Data)), visualization, SLOT(updated(QString,Plasma::DataEngine::Data))); } @@ -154,7 +150,7 @@ void DataContainer::disconnectVisualization(QObject* visualization) visualization, SLOT(updated(QString,Plasma::DataEngine::Data))); if (relay->isUnused()) { - d->relays.erase(d->relays.find(relay->interval)); + d->relays.erase(d->relays.find(relay->m_interval)); delete relay; } diff --git a/datacontainer.h b/datacontainer.h index 5ab879c22..8bc51b159 100644 --- a/datacontainer.h +++ b/datacontainer.h @@ -80,12 +80,6 @@ class PLASMA_EXPORT DataContainer : public QObject **/ void checkForUpdate(); - /** - * Returns a QObject that can be used to relay the updated() signal - * at a given timing frequency independantly. - **/ - QObject* signalRelay(QObject *visualization, uint updateInterval) const; - public Q_SLOTS: /** * Check if the DataContainer is still in use. @@ -101,7 +95,7 @@ class PLASMA_EXPORT DataContainer : public QObject * @param visualization the object to connect to this DataContainer * @param updateInterval the time in milliseconds between updates **/ - void connectVisualization(QObject* visualization, uint updateInterval); + void connectVisualization(QObject* visualization, uint updateInterval, Plasma::IntervalAlignment alignment); /** * Disconnects an object from this DataContainer. diff --git a/datacontainer_p.h b/datacontainer_p.h index fd739b2ac..2cd0d087e 100644 --- a/datacontainer_p.h +++ b/datacontainer_p.h @@ -33,7 +33,8 @@ public: : dirty(false) {} - QObject* signalRelay(const DataContainer* dc, QObject *visualization, uint updateInterval); + QObject* signalRelay(const DataContainer* dc, QObject *visualization, + uint updateInterval, Plasma::IntervalAlignment align); DataEngine::Data data; QMap relayObjects; @@ -46,13 +47,15 @@ class SignalRelay : public QObject Q_OBJECT public: - SignalRelay(DataContainer* parent, DataContainer::Private *data, uint ival) + SignalRelay(DataContainer* parent, DataContainer::Private *data, uint ival, Plasma::IntervalAlignment align) : QObject(parent), dc(parent), d(data), - interval(ival) + m_interval(ival), + m_align(align), + m_resetTimer(false) { - startTimer(interval); + m_timerId = startTimer(m_interval); } bool isUnused() @@ -60,9 +63,38 @@ public: return receivers(SIGNAL(updated(QString,Plasma::DataEngine::Data))) < 1; } + void checkAlignment() + { + int newTime = 0; + + QTime t = QTime::currentTime(); + if (m_align == Plasma::AlignToMinute) { + int seconds = t.second(); + if (seconds > 2) { + newTime = ((60 - seconds) * 1000) + 500; + } + } else if (m_align == Plasma::AlignToHour) { + int minutes = t.minute(); + int seconds = t.second(); + if (minutes > 1 || seconds > 10) { + newTime = ((60 - minutes) * 1000 * 60) + + ((60 - seconds) * 1000) + 500; + } + } + + if (newTime) { + killTimer(m_timerId); + m_timerId = startTimer(newTime); + m_resetTimer = true; + } + } + DataContainer *dc; DataContainer::Private *d; - uint interval; + uint m_interval; + Plasma::IntervalAlignment m_align; + int m_timerId; + bool m_resetTimer; signals: void updated(const QString&, const Plasma::DataEngine::Data&); @@ -70,19 +102,29 @@ signals: protected: void timerEvent(QTimerEvent *event) { + if (m_resetTimer) { + killTimer(m_timerId); + m_timerId = startTimer(m_interval); + m_resetTimer = false; + } + + if (m_align != Plasma::NoAlignment) { + checkAlignment(); + } + emit dc->requestUpdate(dc->objectName()); emit updated(dc->objectName(), d->data); event->accept(); } }; -QObject* DataContainer::Private::signalRelay(const DataContainer* dc, QObject *visualization, uint updateInterval) +QObject* DataContainer::Private::signalRelay(const DataContainer* dc, QObject *visualization, uint updateInterval, Plasma::IntervalAlignment align) { QMap::const_iterator relayIt = relays.find(updateInterval); SignalRelay *relay = 0; if (relayIt == relays.end()) { - relay = new SignalRelay(const_cast(dc), this, updateInterval); + relay = new SignalRelay(const_cast(dc), this, updateInterval, align); relays[updateInterval] = relay; } else { relay = relayIt.value(); diff --git a/dataengine.cpp b/dataengine.cpp index 58bd4ace5..4a9a54fa4 100644 --- a/dataengine.cpp +++ b/dataengine.cpp @@ -86,7 +86,7 @@ class DataEngine::Private return s; } - void connectSource(DataContainer* s, QObject* visualization, uint updateInterval) + void connectSource(DataContainer* s, QObject* visualization, uint updateInterval, Plasma::IntervalAlignment align) { if (updateInterval > 0) { // never more frequently than allowed, never more than 20 times per second @@ -97,7 +97,7 @@ class DataEngine::Private updateInterval = updateInterval - (updateInterval % 50); } - s->connectVisualization(visualization, updateInterval); + s->connectVisualization(visualization, updateInterval, align); QMetaObject::invokeMethod(visualization, "updated", Q_ARG(QString, s->objectName()), @@ -174,7 +174,8 @@ QStringList DataEngine::sources() const return d->sources.keys(); } -void DataEngine::connectSource(const QString& source, QObject* visualization, uint updateInterval) const +void DataEngine::connectSource(const QString& source, QObject* visualization, + uint updateInterval, Plasma::IntervalAlignment intervalAlignment) const { DataContainer* s = d->requestSource(source); @@ -182,13 +183,14 @@ void DataEngine::connectSource(const QString& source, QObject* visualization, ui return; } - d->connectSource(s, visualization, updateInterval); + d->connectSource(s, visualization, updateInterval, intervalAlignment); } -void DataEngine::connectAllSources(QObject* visualization, uint updateInterval) const +void DataEngine::connectAllSources(QObject* visualization, uint updateInterval, + Plasma::IntervalAlignment intervalAlignment) const { foreach (DataContainer* s, d->sources) { - d->connectSource(s, visualization, updateInterval); + d->connectSource(s, visualization, updateInterval, intervalAlignment); } } diff --git a/dataengine.h b/dataengine.h index 546681b89..f8be7501a 100644 --- a/dataengine.h +++ b/dataengine.h @@ -27,6 +27,7 @@ #include #include +#include namespace Plasma { @@ -94,8 +95,11 @@ class PLASMA_EXPORT DataEngine : public QObject * periodic updates from this source. This value is * per-visualization and can be handy for items that require * constant updates such as scrolling graphs or clocks. + * @param intervalAlignedTo the number of ms to aling the interval to **/ - Q_INVOKABLE void connectSource(const QString& source, QObject* visualization, uint updateInterval = 0) const; + Q_INVOKABLE void connectSource(const QString& source, QObject* visualization, + uint updateInterval = 0, + Plasma::IntervalAlignment intervalAlignment = NoAlignment) const; /** * Connects all sources to an object for data updates. The object must @@ -118,7 +122,8 @@ class PLASMA_EXPORT DataEngine : public QObject * per-visualization and can be handy for items that require * constant updates such as scrolling graphs or clocks. **/ - Q_INVOKABLE void connectAllSources(QObject* viualization, uint updateInterval = 0) const; + Q_INVOKABLE void connectAllSources(QObject* viualization, uint updateInterval = 0, + Plasma::IntervalAlignment intervalAlignment = NoAlignment) const; /** * Disconnects a source to an object that was receiving data updates. diff --git a/plasma.h b/plasma.h index 3c3a8fc48..da3671087 100644 --- a/plasma.h +++ b/plasma.h @@ -86,6 +86,14 @@ enum ZoomLevel { DesktopZoom = 0 /**< Normal desktop usage, plasmoids are painte OverviewZoom /**< Groups become icons themselves */ }; +/** + * Possible timing alignments + **/ +enum IntervalAlignment { NoAlignment = 0, + AlignToMinute, + AlignToHour }; + + enum ItemTypes { AppletType = QGraphicsItem::UserType + 1, LineEditType = QGraphicsItem::UserType + 2 };