• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

kalarm/lib

synchtimer.cpp

Go to the documentation of this file.
00001 /*
00002  *  synchtimer.cpp  -  timers which synchronize to time boundaries
00003  *  Program:  kalarm
00004  *  Copyright © 2004,2005,2007,2008 by David Jarvie <djarvie@kde.org>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include "kalarm.h"
00022 #include <QTimer>
00023 #include <kdebug.h>
00024 #include "synchtimer.moc"
00025 
00026 
00027 /*=============================================================================
00028 =  Class: SynchTimer
00029 =  Virtual base class for application-wide timer synchronized to a time boundary.
00030 =============================================================================*/
00031 
00032 SynchTimer::SynchTimer()
00033 {
00034     mTimer = new QTimer(this);
00035     mTimer->setSingleShot(true);
00036 }
00037 
00038 SynchTimer::~SynchTimer()
00039 {
00040     delete mTimer;
00041     mTimer = 0;
00042 }
00043 
00044 /******************************************************************************
00045 * Connect to the timer. The timer is started if necessary.
00046 */
00047 void SynchTimer::connecT(QObject* receiver, const char* member)
00048 {
00049     Connection connection(receiver, member);
00050     if (mConnections.contains(connection))
00051         return;           // the slot is already connected, so ignore request
00052     connect(mTimer, SIGNAL(timeout()), receiver, member);
00053     mConnections.append(connection);
00054     if (!mTimer->isActive())
00055     {
00056         connect(mTimer, SIGNAL(timeout()), this, SLOT(slotTimer()));
00057         start();
00058     }
00059 }
00060 
00061 /******************************************************************************
00062 * Disconnect from the timer. The timer is stopped if no longer needed.
00063 */
00064 void SynchTimer::disconnecT(QObject* receiver, const char* member)
00065 {
00066     if (mTimer)
00067     {
00068         mTimer->disconnect(receiver, member);
00069         if (member)
00070         {
00071             mConnections.removeAt(mConnections.indexOf(Connection(receiver, member)));
00072         }
00073         else
00074         {
00075             for (int i = 0;  i < mConnections.count();  )
00076             {
00077                 if (mConnections[i].receiver == receiver)
00078                     mConnections.removeAt(i);
00079                 else
00080                     ++i;
00081             }
00082         }
00083         if (mConnections.isEmpty())
00084         {
00085             mTimer->disconnect();
00086             mTimer->stop();
00087         }
00088     }
00089 }
00090 
00091 
00092 /*=============================================================================
00093 =  Class: MinuteTimer
00094 =  Application-wide timer synchronized to the minute boundary.
00095 =============================================================================*/
00096 
00097 MinuteTimer* MinuteTimer::mInstance = 0;
00098 
00099 MinuteTimer* MinuteTimer::instance()
00100 {
00101     if (!mInstance)
00102         mInstance = new MinuteTimer;
00103     return mInstance;
00104 }
00105 
00106 /******************************************************************************
00107 * Called when the timer triggers, or to start the timer.
00108 * Timers can under some circumstances wander off from the correct trigger time,
00109 * so rather than setting a 1 minute interval, calculate the correct next
00110 * interval each time it triggers.
00111 */
00112 void MinuteTimer::slotTimer()
00113 {
00114     kDebug();
00115     int interval = 62 - QTime::currentTime().second();
00116     mTimer->start(interval * 1000);     // execute a single shot
00117 }
00118 
00119 
00120 /*=============================================================================
00121 =  Class: DailyTimer
00122 =  Application-wide timer synchronized to midnight.
00123 =============================================================================*/
00124 
00125 QList<DailyTimer*> DailyTimer::mFixedTimers;
00126 
00127 DailyTimer::DailyTimer(const QTime& timeOfDay, bool fixed)
00128     : mTime(timeOfDay),
00129       mFixed(fixed)
00130 {
00131     if (fixed)
00132         mFixedTimers.append(this);
00133 }
00134 
00135 DailyTimer::~DailyTimer()
00136 {
00137     if (mFixed)
00138         mFixedTimers.removeAt(mFixedTimers.indexOf(this));
00139 }
00140 
00141 DailyTimer* DailyTimer::fixedInstance(const QTime& timeOfDay, bool create)
00142 {
00143     for (int i = 0, end = mFixedTimers.count();  i < end;  ++i)
00144         if (mFixedTimers[i]->mTime == timeOfDay)
00145             return mFixedTimers[i];
00146     return create ? new DailyTimer(timeOfDay, true) : 0;
00147 }
00148 
00149 /******************************************************************************
00150 * Disconnect from the timer signal which triggers at the given fixed time of day.
00151 * If there are no remaining connections to that timer, it is destroyed.
00152 */
00153 void DailyTimer::disconnect(const QTime& timeOfDay, QObject* receiver, const char* member)
00154 {
00155     DailyTimer* timer = fixedInstance(timeOfDay, false);
00156     if (!timer)
00157         return;
00158     timer->disconnecT(receiver, member);
00159     if (!timer->hasConnections())
00160         delete timer;
00161 }
00162 
00163 /******************************************************************************
00164 * Change the time at which the variable timer triggers.
00165 */
00166 void DailyTimer::changeTime(const QTime& newTimeOfDay, bool triggerMissed)
00167 {
00168     if (mFixed)
00169         return;
00170     if (mTimer->isActive())
00171     {
00172         mTimer->stop();
00173         bool triggerNow = false;
00174         if (triggerMissed)
00175         {
00176             QTime now = QTime::currentTime();
00177             if (now >= newTimeOfDay  &&  now < mTime)
00178             {
00179                 // The trigger time is now earlier and it has already arrived today.
00180                 // Trigger a timer event immediately.
00181                 triggerNow = true;
00182             }
00183         }
00184         mTime = newTimeOfDay;
00185         if (triggerNow)
00186             mTimer->start(0);    // trigger immediately
00187         else
00188             start();
00189     }
00190     else
00191         mTime = newTimeOfDay;
00192 }
00193 
00194 /******************************************************************************
00195 * Initialise the timer to trigger at the specified time.
00196 * This will either be today or tomorrow, depending on whether the trigger time
00197 * has already passed.
00198 */
00199 void DailyTimer::start()
00200 {
00201     // TIMEZONE = local time
00202     QDateTime now = QDateTime::currentDateTime();
00203     // Find out whether to trigger today or tomorrow.
00204     // In preference, use the last trigger date to determine this, since
00205     // that will avoid possible errors due to daylight savings time changes.
00206     bool today;
00207     if (mLastDate.isValid())
00208         today = (mLastDate < now.date());
00209     else
00210         today = (now.time() < mTime);
00211     QDateTime next;
00212     if (today)
00213         next = QDateTime(now.date(), mTime);
00214     else
00215         next = QDateTime(now.date().addDays(1), mTime);
00216     uint interval = next.toTime_t() - now.toTime_t();
00217     mTimer->start(interval * 1000);    // execute a single shot
00218     kDebug() << "at" << mTime.hour() << ":" << mTime.minute() << ": interval =" << interval/3600 << ":" << (interval/60)%60 << ":" << interval%60;
00219 }
00220 
00221 /******************************************************************************
00222 * Called when the timer triggers.
00223 * Set the timer to trigger again tomorrow at the specified time.
00224 * Note that if daylight savings time changes occur, this will not be 24 hours
00225 * from now.
00226 */
00227 void DailyTimer::slotTimer()
00228 {
00229     // TIMEZONE = local time
00230     QDateTime now = QDateTime::currentDateTime();
00231     mLastDate = now.date();
00232     QDateTime next = QDateTime(mLastDate.addDays(1), mTime);
00233     uint interval = next.toTime_t() - now.toTime_t();
00234     mTimer->start(interval * 1000);    // execute a single shot
00235     kDebug() << "at" << mTime.hour() << ":" << mTime.minute() << ": interval =" << interval/3600 << ":" << (interval/60)%60 << ":" << interval%60;
00236 }

kalarm/lib

Skip menu "kalarm/lib"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal