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 Alarm *Alarm::clone()
00051 {
00052   return new Alarm( *this );
00053 }
00054 
00055 Alarm &Alarm::operator=( const Alarm &a )
00056 {
00057   mParent = a.mParent;
00058   mType = a.mType;
00059   mDescription = a.mDescription;
00060   mFile = a.mFile;
00061   mMailAttachFiles = a.mMailAttachFiles;
00062   mMailAddresses = a.mMailAddresses;
00063   mMailSubject = a.mMailSubject;
00064   mAlarmSnoozeTime = a.mAlarmSnoozeTime;
00065   mAlarmRepeatCount = a.mAlarmRepeatCount;
00066   mAlarmTime = a.mAlarmTime;
00067   mOffset = a.mOffset;
00068   mEndOffset = a.mEndOffset;
00069   mHasTime = a.mHasTime;
00070   mAlarmEnabled = a.mAlarmEnabled;
00071   return *this;
00072 }
00073 
00074 bool Alarm::operator==( const Alarm& rhs ) const
00075 {
00076   if ( mType != rhs.mType ||
00077        mAlarmSnoozeTime != rhs.mAlarmSnoozeTime ||
00078        mAlarmRepeatCount != rhs.mAlarmRepeatCount ||
00079        mAlarmEnabled != rhs.mAlarmEnabled ||
00080        mHasTime != rhs.mHasTime)
00081     return false;
00082 
00083   if (mHasTime) {
00084     if (mAlarmTime != rhs.mAlarmTime)
00085       return false;
00086   } else {
00087     if (mOffset != rhs.mOffset ||
00088         mEndOffset != rhs.mEndOffset)
00089       return false;
00090   }
00091 
00092   switch (mType) {
00093     case Display:
00094       return mDescription == rhs.mDescription;
00095 
00096     case Email:
00097       return mDescription == rhs.mDescription &&
00098              mMailAttachFiles == rhs.mMailAttachFiles &&
00099              mMailAddresses == rhs.mMailAddresses &&
00100              mMailSubject == rhs.mMailSubject;
00101 
00102     case Procedure:
00103       return mFile == rhs.mFile &&
00104              mDescription == rhs.mDescription;
00105 
00106     case Audio:
00107       return mFile == rhs.mFile;
00108 
00109     case Invalid:
00110       break;
00111   }
00112   return false;
00113 }
00114 
00115 void Alarm::setType(Alarm::Type type)
00116 {
00117   if (type == mType)
00118     return;
00119 
00120   switch (type) {
00121     case Display:
00122       mDescription = "";
00123       break;
00124     case Procedure:
00125       mFile = mDescription = "";
00126       break;
00127     case Audio:
00128       mFile = "";
00129       break;
00130     case Email:
00131       mMailSubject = mDescription = "";
00132       mMailAddresses.clear();
00133       mMailAttachFiles.clear();
00134       break;
00135     case Invalid:
00136       break;
00137     default:
00138       return;
00139   }
00140   mType = type;
00141   if ( mParent ) mParent->updated();
00142 }
00143 
00144 Alarm::Type Alarm::type() const
00145 {
00146   return mType;
00147 }
00148 
00149 void Alarm::setAudioAlarm(const TQString &audioFile)
00150 {
00151   mType = Audio;
00152   mFile = audioFile;
00153   if ( mParent ) mParent->updated();
00154 }
00155 
00156 void Alarm::setAudioFile(const TQString &audioFile)
00157 {
00158   if (mType == Audio) {
00159     mFile = audioFile;
00160     if ( mParent ) mParent->updated();
00161   }
00162 }
00163 
00164 TQString Alarm::audioFile() const
00165 {
00166   return (mType == Audio) ? mFile : TQString();
00167 }
00168 
00169 void Alarm::setProcedureAlarm(const TQString &programFile, const TQString &arguments)
00170 {
00171   mType = Procedure;
00172   mFile = programFile;
00173   mDescription = arguments;
00174   if ( mParent ) mParent->updated();
00175 }
00176 
00177 void Alarm::setProgramFile(const TQString &programFile)
00178 {
00179   if (mType == Procedure) {
00180     mFile = programFile;
00181     if ( mParent ) mParent->updated();
00182   }
00183 }
00184 
00185 TQString Alarm::programFile() const
00186 {
00187   return (mType == Procedure) ? mFile : TQString();
00188 }
00189 
00190 void Alarm::setProgramArguments(const TQString &arguments)
00191 {
00192   if (mType == Procedure) {
00193     mDescription = arguments;
00194     if ( mParent ) mParent->updated();
00195   }
00196 }
00197 
00198 TQString Alarm::programArguments() const
00199 {
00200   return (mType == Procedure) ? mDescription : TQString();
00201 }
00202 
00203 void Alarm::setEmailAlarm(const TQString &subject, const TQString &text,
00204                           const TQValueList<Person> &addressees, const TQStringList &attachments)
00205 {
00206   mType = Email;
00207   mMailSubject = subject;
00208   mDescription = text;
00209   mMailAddresses = addressees;
00210   mMailAttachFiles = attachments;
00211   if ( mParent ) mParent->updated();
00212 }
00213 
00214 void Alarm::setMailAddress(const Person &mailAddress)
00215 {
00216   if (mType == Email) {
00217     mMailAddresses.clear();
00218     mMailAddresses += mailAddress;
00219     if ( mParent ) mParent->updated();
00220   }
00221 }
00222 
00223 void Alarm::setMailAddresses(const TQValueList<Person> &mailAddresses)
00224 {
00225   if (mType == Email) {
00226     mMailAddresses = mailAddresses;
00227     if ( mParent ) mParent->updated();
00228   }
00229 }
00230 
00231 void Alarm::addMailAddress(const Person &mailAddress)
00232 {
00233   if (mType == Email) {
00234     mMailAddresses += mailAddress;
00235     if ( mParent ) mParent->updated();
00236   }
00237 }
00238 
00239 TQValueList<Person> Alarm::mailAddresses() const
00240 {
00241   return (mType == Email) ? mMailAddresses : TQValueList<Person>();
00242 }
00243 
00244 void Alarm::setMailSubject(const TQString &mailAlarmSubject)
00245 {
00246   if (mType == Email) {
00247     mMailSubject = mailAlarmSubject;
00248     if ( mParent ) mParent->updated();
00249   }
00250 }
00251 
00252 TQString Alarm::mailSubject() const
00253 {
00254   return (mType == Email) ? mMailSubject : TQString();
00255 }
00256 
00257 void Alarm::setMailAttachment(const TQString &mailAttachFile)
00258 {
00259   if (mType == Email) {
00260     mMailAttachFiles.clear();
00261     mMailAttachFiles += mailAttachFile;
00262     if ( mParent ) mParent->updated();
00263   }
00264 }
00265 
00266 void Alarm::setMailAttachments(const TQStringList &mailAttachFiles)
00267 {
00268   if (mType == Email) {
00269     mMailAttachFiles = mailAttachFiles;
00270     if ( mParent ) mParent->updated();
00271   }
00272 }
00273 
00274 void Alarm::addMailAttachment(const TQString &mailAttachFile)
00275 {
00276   if (mType == Email) {
00277     mMailAttachFiles += mailAttachFile;
00278     if ( mParent ) mParent->updated();
00279   }
00280 }
00281 
00282 TQStringList Alarm::mailAttachments() const
00283 {
00284   return (mType == Email) ? mMailAttachFiles : TQStringList();
00285 }
00286 
00287 void Alarm::setMailText(const TQString &text)
00288 {
00289   if (mType == Email) {
00290     mDescription = text;
00291     if ( mParent ) mParent->updated();
00292   }
00293 }
00294 
00295 TQString Alarm::mailText() const
00296 {
00297   return (mType == Email) ? mDescription : TQString();
00298 }
00299 
00300 void Alarm::setDisplayAlarm(const TQString &text)
00301 {
00302   mType = Display;
00303   if ( !text.isNull() )
00304     mDescription = text;
00305   if ( mParent ) mParent->updated();
00306 }
00307 
00308 void Alarm::setText(const TQString &text)
00309 {
00310   if (mType == Display) {
00311     mDescription = text;
00312     if ( mParent ) mParent->updated();
00313   }
00314 }
00315 
00316 TQString Alarm::text() const
00317 {
00318   return (mType == Display) ? mDescription : TQString();
00319 }
00320 
00321 void Alarm::setTime(const TQDateTime &alarmTime)
00322 {
00323   mAlarmTime = alarmTime;
00324   mHasTime = true;
00325 
00326   if ( mParent ) mParent->updated();
00327 }
00328 
00329 TQDateTime Alarm::time() const
00330 {
00331   if ( hasTime() ) {
00332     return mAlarmTime;
00333   } else if ( mParent ) {
00334     if ( mEndOffset ) {
00335       if ( mParent->type() == "Todo" ) {
00336         Todo *t = static_cast<Todo*>( mParent );
00337         return mOffset.end( t->dtDue() );
00338       } else {
00339         return mOffset.end( mParent->dtEnd() );
00340       }
00341     } else {
00342       return mOffset.end( mParent->dtStart() );
00343     }
00344   } else {
00345     return TQDateTime();
00346   }
00347 }
00348 
00349 bool Alarm::hasTime() const
00350 {
00351   return mHasTime;
00352 }
00353 
00354 void Alarm::setSnoozeTime(const Duration &alarmSnoozeTime)
00355 {
00356   if (alarmSnoozeTime.value() > 0) {
00357     mAlarmSnoozeTime = alarmSnoozeTime;
00358     if ( mParent ) mParent->updated();
00359   }
00360 }
00361 
00362 Duration Alarm::snoozeTime() const
00363 {
00364   return mAlarmSnoozeTime;
00365 }
00366 
00367 void Alarm::setRepeatCount(int alarmRepeatCount)
00368 {
00369   mAlarmRepeatCount = alarmRepeatCount;
00370   if ( mParent ) mParent->updated();
00371 }
00372 
00373 int Alarm::repeatCount() const
00374 {
00375   return mAlarmRepeatCount;
00376 }
00377 
00378 Duration Alarm::duration() const
00379 {
00380   return Duration( mAlarmSnoozeTime.value() * mAlarmRepeatCount,
00381                    mAlarmSnoozeTime.type() );
00382 }
00383 
00384 TQDateTime Alarm::nextRepetition(const TQDateTime& preTime) const
00385 {
00386   // This method is coded to avoid 32-bit integer overflow using
00387   // TQDateTime::secsTo(), which occurs with time spans > 68 years.
00388   TQDateTime at = time();
00389   if (at > preTime)
00390     return at;
00391   if (!mAlarmRepeatCount)
00392     return TQDateTime();   // there isn't an occurrence after the specified time
00393   int snoozeSecs = mAlarmSnoozeTime * 60;
00394   TQDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs);
00395   if (lastRepetition <= preTime)
00396     return TQDateTime();    // all repetitions have finished before the specified time
00397   int repetition = (at.secsTo(preTime) + snoozeSecs) / snoozeSecs;
00398   return at.addSecs(repetition * snoozeSecs);
00399 }
00400 
00401 TQDateTime Alarm::previousRepetition(const TQDateTime& afterTime) const
00402 {
00403   // This method is coded to avoid 32-bit integer overflow using
00404   // TQDateTime::secsTo(), which occurs with time spans > 68 years.
00405   TQDateTime at = time();
00406   if (at >= afterTime)
00407     return TQDateTime();    // alarm's first/only time is at/after the specified time
00408   if (!mAlarmRepeatCount)
00409     return at;
00410   int snoozeSecs = mAlarmSnoozeTime * 60;
00411   TQDateTime lastRepetition = at.addSecs(mAlarmRepeatCount * snoozeSecs);
00412   if (lastRepetition < afterTime)
00413     return lastRepetition;   // all repetitions have finished before the specified time
00414   int repetition = (at.secsTo(afterTime) - 1) / snoozeSecs;
00415   return at.addSecs(repetition * snoozeSecs);
00416 }
00417 
00418 TQDateTime Alarm::endTime() const
00419 {
00420   if (mAlarmRepeatCount)
00421     return time().addSecs(mAlarmRepeatCount * mAlarmSnoozeTime * 60);
00422   else
00423     return time();
00424 }
00425 
00426 void Alarm::toggleAlarm()
00427 {
00428   mAlarmEnabled = !mAlarmEnabled;
00429   if ( mParent ) mParent->updated();
00430 }
00431 
00432 void Alarm::setEnabled(bool enable)
00433 {
00434   mAlarmEnabled = enable;
00435   if ( mParent ) mParent->updated();
00436 }
00437 
00438 bool Alarm::enabled() const
00439 {
00440   return mAlarmEnabled;
00441 }
00442 
00443 void Alarm::setStartOffset( const Duration &offset )
00444 {
00445   mOffset = offset;
00446   mEndOffset = false;
00447   mHasTime = false;
00448   if ( mParent ) mParent->updated();
00449 }
00450 
00451 Duration Alarm::startOffset() const
00452 {
00453   return (mHasTime || mEndOffset) ? Duration( 0 ) : mOffset;
00454 }
00455 
00456 bool Alarm::hasStartOffset() const
00457 {
00458   return !mHasTime && !mEndOffset;
00459 }
00460 
00461 bool Alarm::hasEndOffset() const
00462 {
00463   return !mHasTime && mEndOffset;
00464 }
00465 
00466 void Alarm::setEndOffset( const Duration &offset )
00467 {
00468   mOffset = offset;
00469   mEndOffset = true;
00470   mHasTime = false;
00471   if ( mParent ) mParent->updated();
00472 }
00473 
00474 Duration Alarm::endOffset() const
00475 {
00476   return (mHasTime || !mEndOffset) ? Duration( 0 ) : mOffset;
00477 }
00478 
00479 void Alarm::setParent( Incidence *parent )
00480 {
00481   mParent = parent;
00482 }
00483 
00484 void Alarm::customPropertyUpdated()
00485 {
00486   if ( mParent ) mParent->updated();
00487 }