libkcal

alarm.cpp

00001 /*
00002     This file is part of libkcal.
00003 
00004     Copyright (c) 1998 Preston Brown <pbrown@kde.org>
00005     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include <kdebug.h>
00024 
00025 #include "incidence.h"
00026 #include "todo.h"
00027 
00028 #include "alarm.h"
00029 
00030 using namespace KCal;
00031 
00032 Alarm::Alarm(Incidence *parent)
00033  : mParent(parent),
00034    mType(Invalid),
00035    mDescription(""),    // to make operator==() not fail
00036    mFile(""),           // to make operator==() not fail
00037    mMailSubject(""),    // to make operator==() not fail
00038    mAlarmSnoozeTime(5),
00039    mAlarmRepeatCount(0),
00040    mEndOffset(false),
00041    mHasTime(false),
00042    mAlarmEnabled(false)
00043 {
00044 }
00045 
00046 Alarm::~Alarm()
00047 {
00048 }
00049 
00050 bool Alarm::operator==( const Alarm& rhs ) const
00051 {
00052   if ( mType != rhs.mType ||
00053        mAlarmSnoozeTime != rhs.mAlarmSnoozeTime ||
00054        mAlarmRepeatCount != rhs.mAlarmRepeatCount ||
00055        mAlarmEnabled != rhs.mAlarmEnabled ||
00056        mHasTime != rhs.mHasTime)
00057     return false;
00058 
00059   if (mHasTime) {
00060     if (mAlarmTime != rhs.mAlarmTime)
00061       return false;
00062   } else {
00063     if (mOffset != rhs.mOffset ||
00064         mEndOffset != rhs.mEndOffset)
00065       return false;
00066   }
00067 
00068   switch (mType) {
00069     case Display:
00070       return mDescription == rhs.mDescription;
00071 
00072     case Email:
00073       return mDescription == rhs.mDescription &&
00074              mMailAttachFiles == rhs.mMailAttachFiles &&
00075              mMailAddresses == rhs.mMailAddresses &&
00076              mMailSubject == rhs.mMailSubject;
00077 
00078     case Procedure:
00079       return mFile == rhs.mFile &&
00080              mDescription == rhs.mDescription;
00081 
00082     case Audio:
00083       return mFile == rhs.mFile;
00084 
00085     case Invalid:
00086       break;
00087   }
00088   return false;
00089 }
00090 
00091 void Alarm::setType(Alarm::Type type)
00092 {
00093   if (type == mType)
00094     return;
00095 
00096   switch (type) {
00097     case Display:
00098       mDescription = "";
00099       break;
00100     case Procedure:
00101       mFile = mDescription = "";
00102       break;
00103     case Audio:
00104       mFile = "";
00105       break;
00106     case Email:
00107       mMailSubject = mDescription = "";
00108       mMailAddresses.clear();
00109       mMailAttachFiles.clear();
00110       break;
00111     case Invalid:
00112       break;
00113     default:
00114       return;
00115   }
00116   mType = type;
00117   if ( mParent ) mParent->updated();
00118 }
00119 
00120 Alarm::Type Alarm::type() const
00121 {
00122   return mType;
00123 }
00124 
00125 void Alarm::setAudioAlarm(const QString &audioFile)
00126 {
00127   mType = Audio;
00128   mFile = audioFile;
00129   if ( mParent ) mParent->updated();
00130 }
00131 
00132 void Alarm::setAudioFile(const QString &audioFile)
00133 {
00134   if (mType == Audio) {
00135     mFile = audioFile;
00136     if ( mParent ) mParent->updated();
00137   }
00138 }
00139 
00140 QString Alarm::audioFile() const
00141 {
00142   return (mType == Audio) ? mFile : QString::null;
00143 }
00144 
00145 void Alarm::setProcedureAlarm(const QString &programFile, const QString &arguments)
00146 {
00147   mType = Procedure;
00148   mFile = programFile;
00149   mDescription = arguments;
00150   if ( mParent ) mParent->updated();
00151 }
00152 
00153 void Alarm::setProgramFile(const QString &programFile)
00154 {
00155   if (mType == Procedure) {
00156     mFile = programFile;
00157     if ( mParent ) mParent->updated();
00158   }
00159 }
00160 
00161 QString Alarm::programFile() const
00162 {
00163   return (mType == Procedure) ? mFile : QString::null;
00164 }
00165 
00166 void Alarm::setProgramArguments(const QString &arguments)
00167 {
00168   if (mType == Procedure) {
00169     mDescription = arguments;
00170     if ( mParent ) mParent->updated();
00171   }
00172 }
00173 
00174 QString Alarm::programArguments() const
00175 {
00176   return (mType == Procedure) ? mDescription : QString::null;
00177 }
00178 
00179 void Alarm::setEmailAlarm(const QString &subject, const QString &text,
00180                           const QValueList<Person> &addressees, const QStringList &attachments)
00181 {
00182   mType = Email;
00183   mMailSubject = subject;
00184   mDescription = text;
00185   mMailAddresses = addressees;
00186   mMailAttachFiles = attachments;
00187   if ( mParent ) mParent->updated();
00188 }
00189 
00190 void Alarm::setMailAddress(const Person &mailAddress)
00191 {
00192   if (mType == Email) {
00193     mMailAddresses.clear();
00194     mMailAddresses += mailAddress;
00195     if ( mParent ) mParent->updated();
00196   }
00197 }
00198 
00199 void Alarm::setMailAddresses(const QValueList<Person> &mailAddresses)
00200 {
00201   if (mType == Email) {
00202     mMailAddresses = mailAddresses;
00203     if ( mParent ) mParent->updated();
00204   }
00205 }
00206 
00207 void Alarm::addMailAddress(const Person &mailAddress)
00208 {
00209   if (mType == Email) {
00210     mMailAddresses += mailAddress;
00211     if ( mParent ) mParent->updated();
00212   }
00213 }
00214 
00215 QValueList<Person> Alarm::mailAddresses() const
00216 {
00217   return (mType == Email) ? mMailAddresses : QValueList<Person>();
00218 }
00219 
00220 void Alarm::setMailSubject(const QString &mailAlarmSubject)
00221 {
00222   if (mType == Email) {
00223     mMailSubject = mailAlarmSubject;
00224     if ( mParent ) mParent->updated();
00225   }
00226 }
00227 
00228 QString Alarm::mailSubject() const
00229 {
00230   return (mType == Email) ? mMailSubject : QString::null;
00231 }
00232 
00233 void Alarm::setMailAttachment(const QString &mailAttachFile)
00234 {
00235   if (mType == Email) {
00236     mMailAttachFiles.clear();
00237     mMailAttachFiles += mailAttachFile;
00238     if ( mParent ) mParent->updated();
00239   }
00240 }
00241 
00242 void Alarm::setMailAttachments(const QStringList &mailAttachFiles)
00243 {
00244   if (mType == Email) {
00245     mMailAttachFiles = mailAttachFiles;
00246     if ( mParent ) mParent->updated();
00247   }
00248 }
00249 
00250 void Alarm::addMailAttachment(const QString &mailAttachFile)
00251 {
00252   if (mType == Email) {
00253     mMailAttachFiles += mailAttachFile;
00254     if ( mParent ) mParent->updated();
00255   }
00256 }
00257 
00258 QStringList Alarm::mailAttachments() const
00259 {
00260   return (mType == Email) ? mMailAttachFiles : QStringList();
00261 }
00262 
00263 void Alarm::setMailText(const QString &text)
00264 {
00265   if (mType == Email) {
00266     mDescription = text;
00267     if ( mParent ) mParent->updated();
00268   }
00269 }
00270 
00271 QString Alarm::mailText() const
00272 {
00273   return (mType == Email) ? mDescription : QString::null;
00274 }
00275 
00276 void Alarm::setDisplayAlarm(const QString &text)
00277 {
00278   mType = Display;
00279   if ( !text.isNull() )
00280     mDescription = text;
00281   if ( mParent ) mParent->updated();
00282 }
00283 
00284 void Alarm::setText(const QString &text)
00285 {
00286   if (mType == Display) {
00287     mDescription = text;
00288     if ( mParent ) mParent->updated();
00289   }
00290 }
00291 
00292 QString Alarm::text() const
00293 {
00294   return (mType == Display) ? mDescription : QString::null;
00295 }
00296 
00297 void Alarm::setTime(const QDateTime &alarmTime)
00298 {
00299   mAlarmTime = alarmTime;
00300   mHasTime = true;
00301 
00302   if ( mParent ) mParent->updated();
00303 }
00304 
00305 QDateTime Alarm::time() const
00306 {
00307   if ( hasTime() ) {
00308     return mAlarmTime;
00309   } else if ( mParent ) {
00310     if ( mEndOffset ) {
00311       if ( mParent->type() == "Todo" ) {
00312         Todo *t = static_cast<Todo*>( mParent );
00313         return mOffset.end( t->dtDue() );
00314       } else {
00315         return mOffset.end( mParent->dtEnd() );
00316       }
00317     } else {
00318       return mOffset.end( mParent->dtStart() );
00319     }
00320   } else {
00321     return QDateTime();
00322   }
00323 }
00324 
00325 bool Alarm::hasTime() const
00326 {
00327   return mHasTime;
00328 }
00329 
00330 void Alarm::setSnoozeTime(const Duration &alarmSnoozeTime)
00331 {
00332   if (alarmSnoozeTime.value() > 0) {
00333     mAlarmSnoozeTime = alarmSnoozeTime;
00334     if ( mParent ) mParent->updated();
00335   }
00336 }
00337 
00338 Duration Alarm::snoozeTime() const
00339 {
00340   return mAlarmSnoozeTime;
00341 }
00342 
00343 void Alarm::setRepeatCount(int alarmRepeatCount)
00344 {
00345   mAlarmRepeatCount = alarmRepeatCount;
00346   if ( mParent ) mParent->updated();
00347 }
00348 
00349 int Alarm::repeatCount() const
00350 {
00351   return mAlarmRepeatCount;
00352 }
00353 
00354 Duration Alarm::duration() const
00355 {
00356   return Duration( mAlarmSnoozeTime.value() * mAlarmRepeatCount,
00357                    mAlarmSnoozeTime.type() );
00358 }
00359 
00360 QDateTime Alarm::nextRepetition(const QDateTime& preTime) const
00361 {
00362   // This method is coded to avoid 32-bit integer overflow using
00363   // QDateTime::secsTo(), which occurs with time spans > 68 years.
00364   QDateTime at = time();
00365   if (at > preTime)
00366     return at;
00367   if (!mAlarmRepeatCount)
00368     return QDateTime();   // there isn't an occurrence after the specified time
00369   int snoozeSecs = mAlarmSnoozeTime * 60;
00370   QDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs);
00371   if (lastRepetition <= preTime)
00372     return QDateTime();    // all repetitions have finished before the specified time
00373   int repetition = (at.secsTo(preTime) + snoozeSecs) / snoozeSecs;
00374   return at.addSecs(repetition * snoozeSecs);
00375 }
00376 
00377 QDateTime Alarm::previousRepetition(const QDateTime& afterTime) const
00378 {
00379   // This method is coded to avoid 32-bit integer overflow using
00380   // QDateTime::secsTo(), which occurs with time spans > 68 years.
00381   QDateTime at = time();
00382   if (at >= afterTime)
00383     return QDateTime();    // alarm's first/only time is at/after the specified time
00384   if (!mAlarmRepeatCount)
00385     return at;
00386   int snoozeSecs = mAlarmSnoozeTime * 60;
00387   QDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs);
00388   if (lastRepetition < afterTime)
00389     return lastRepetition;   // all repetitions have finished before the specified time
00390   int repetition = (at.secsTo(afterTime) - 1) / snoozeSecs;
00391   return at.addSecs(repetition * snoozeSecs);
00392 }
00393 
00394 QDateTime Alarm::endTime() const
00395 {
00396   if (mAlarmRepeatCount)
00397     return time().addSecs(mAlarmRepeatCount * mAlarmSnoozeTime * 60);
00398   else
00399     return time();
00400 }
00401 
00402 void Alarm::toggleAlarm()
00403 {
00404   mAlarmEnabled = !mAlarmEnabled;
00405   if ( mParent ) mParent->updated();
00406 }
00407 
00408 void Alarm::setEnabled(bool enable)
00409 {
00410   mAlarmEnabled = enable;
00411   if ( mParent ) mParent->updated();
00412 }
00413 
00414 bool Alarm::enabled() const
00415 {
00416   return mAlarmEnabled;
00417 }
00418 
00419 void Alarm::setStartOffset( const Duration &offset )
00420 {
00421   mOffset = offset;
00422   mEndOffset = false;
00423   mHasTime = false;
00424   if ( mParent ) mParent->updated();
00425 }
00426 
00427 Duration Alarm::startOffset() const
00428 {
00429   return (mHasTime || mEndOffset) ? Duration( 0 ) : mOffset;
00430 }
00431 
00432 bool Alarm::hasStartOffset() const
00433 {
00434   return !mHasTime && !mEndOffset;
00435 }
00436 
00437 bool Alarm::hasEndOffset() const
00438 {
00439   return !mHasTime && mEndOffset;
00440 }
00441 
00442 void Alarm::setEndOffset( const Duration &offset )
00443 {
00444   mOffset = offset;
00445   mEndOffset = true;
00446   mHasTime = false;
00447   if ( mParent ) mParent->updated();
00448 }
00449 
00450 Duration Alarm::endOffset() const
00451 {
00452   return (mHasTime || !mEndOffset) ? Duration( 0 ) : mOffset;
00453 }
00454 
00455 void Alarm::setParent( Incidence *parent )
00456 {
00457   mParent = parent;
00458 }
00459 
00460 void Alarm::customPropertyUpdated()
00461 {
00462   if ( mParent ) mParent->updated();
00463 }