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 }