--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/utils/hbtimer.cpp Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbCore module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbtimer_p.h"
+#include <QApplication>
+
+#if QT_VERSION < 0x040600
+#include <QtAbstractAnimation>
+#define QAbstractAnimation QtAbstractAnimation
+#else
+#include <QAbstractAnimation>
+#endif
+
+// A custom animation. We will use this instead of creating a timer ourselves, in
+// order to use the animation fw's QUnifiedTimer under the hood.
+class HbTimerAnim : public QAbstractAnimation
+{
+public:
+ HbTimerAnim(HbTimerEntry *entry) : mEntry(entry), mDuration(entry->interval()) { }
+ int duration() const { return mDuration; }
+ void updateCurrentTime(int) { }
+ void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
+ {
+ if (oldState != QAbstractAnimation::Stopped && newState == QAbstractAnimation::Stopped && mEntry) {
+ mEntry->timerFired();
+ mEntry->mAnim = 0; // to prevent confusing unregisterEntry() and double deletion
+ HbTimer::instance()->unregisterEntry(mEntry);
+ if (mEntry->mDeleteWhenFinishedNormally) {
+ delete mEntry;
+ }
+ }
+ }
+ HbTimerEntry *mEntry;
+ int mDuration;
+};
+
+/*!
+ * \class HbTimer
+ *
+ * \brief Provides a unified timer to avoid creating several separate singleshot
+ * timers.
+ *
+ * \internal
+ *
+ * For example, the following code
+ * \code
+ * QTimer *timer = new QTimer(this);
+ * timer->setSingleShot(true);
+ * connect(timer, SIGNAL(timeout()), SLOT(onTimeout()));
+ * timer->start(milliseconds);
+ * \code
+ * simply becomes
+ * \code
+ * HbTimer::instance()->addTimeout(milliseconds, this, SLOT(onTimeout()));
+ * \endcode
+ *
+ * Alternatively a class C can inherit from HbTimerEntry, pass the timer
+ * interval to the HbTimerEntry constructor, and implement timerFired(). In
+ * this case HbTimer::instance()->registerEntry(instance_of_class_C) can be
+ * called to have timerFired() invoked on instance_of_class_C after the number
+ * of milliseconds that has been passed to the HbTimerEntry constructor.
+ */
+
+HbTimer::HbTimer(QObject *parent)
+ : QObject(parent)
+{
+}
+
+HbTimer *HbTimer::instance()
+{
+ static HbTimer *inst = new HbTimer(qApp);
+ return inst;
+}
+
+/*!
+ * Requests a notification after the interval specified in \entry.
+ *
+ * The notification will mean calling timerFired() on \a entry.
+ *
+ * If \a deleteWhenFinishedNormally is true then the entry is
+ * automatically deleted after invoking timerFired(). Note that the
+ * entry is not deleted when unregisterEntry() is called explicitly.
+ *
+ * \sa addTimeout
+ */
+void HbTimer::registerEntry(HbTimerEntry *entry, bool deleteWhenFinishedNormally)
+{
+ if (!entryList.contains(entry)) {
+ entryList << entry;
+ entry->mDeleteWhenFinishedNormally = deleteWhenFinishedNormally;
+ entry->mAnim = new HbTimerAnim(entry);
+ entry->mAnim->start(QAbstractAnimation::DeleteWhenStopped);
+ }
+}
+
+/*!
+ * Cancels a pending timer notification. The HbTimerEntry instance (entry) is
+ * not deleted.
+ *
+ * \return true if the entry was successfully unregistered, false if the entry
+ * was not found amongst the registered ones.
+ */
+bool HbTimer::unregisterEntry(HbTimerEntry *entry)
+{
+ int idx = entryList.indexOf(entry);
+ if (idx >= 0) {
+ // Stop the animation but first set the anim's entry backptr to null
+ // so no callback and deletion will occur in updateState().
+ if (entry->mAnim) {
+ entry->mAnim->mEntry = 0;
+ entry->mAnim->stop(); // this will also result in deleting the HbTimerAnim instance
+ entry->mAnim = 0;
+ }
+ entryList.removeAll(entry);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ * Convenience wrapper for registerEntry(). The given \a slot on the
+ * given QObject will be invoked after \a interval miliseconds. The
+ * returned HbTimerSignalEntry instance can be used to cancel the
+ * timer; note that it will automatically be deleted after the slot
+ * has been invoked, however it has to be deleted manually if
+ * unregisterEntry() was called explicitly.
+ *
+ * \sa registerEntry
+ */
+HbTimerSignalEntry *HbTimer::addTimeout(int interval, QObject *receiver, const char *slot)
+{
+ HbTimerSignalEntry *entry = new HbTimerSignalEntry(interval);
+ connect(entry, SIGNAL(timeout()), receiver, slot);
+ registerEntry(entry, true);
+ return entry;
+}
+
+/*!
+ * Constructs a new timer entry instance. Interval is in milliseconds.
+ */
+HbTimerEntry::HbTimerEntry(int interval)
+ : mInterval(interval), mAnim(0), mDeleteWhenFinishedNormally(false)
+{
+}
+
+HbTimerEntry::~HbTimerEntry()
+{
+ if (mAnim) {
+ delete mAnim;
+ }
+}
+
+int HbTimerEntry::interval() const
+{
+ return mInterval;
+}
+
+HbTimerSignalEntry::HbTimerSignalEntry(int interval)
+ : HbTimerEntry(interval)
+{
+}
+
+void HbTimerSignalEntry::timerFired()
+{
+ emit timeout();
+}