KCal Library
alarm.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the kcal library. 00003 00004 Copyright (c) 1998 Preston Brown <pbrown@kde.org> 00005 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 00006 Copyright (c) 2003 David Jarvie <software@astrojar.org.uk> 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00021 Boston, MA 02110-1301, USA. 00022 */ 00034 #include "alarm.h" 00035 #include "incidence.h" 00036 #include "todo.h" 00037 00038 #include <kdebug.h> 00039 00040 using namespace KCal; 00041 00046 //@cond PRIVATE 00047 class KCal::Alarm::Private 00048 { 00049 public: 00050 Private() 00051 : mParent( 0 ), 00052 mType( Alarm::Invalid ), 00053 mAlarmSnoozeTime( 5 ), 00054 mAlarmRepeatCount( 0 ), 00055 mEndOffset( false ), 00056 mHasTime( false ), 00057 mAlarmEnabled( false ) 00058 {} 00059 Private( const Private &other ) 00060 : mParent( other.mParent ), 00061 mType( other.mType ), 00062 mDescription( other.mDescription ), 00063 mFile( other.mFile ), 00064 mMailSubject( other.mMailSubject ), 00065 mMailAttachFiles( other.mMailAttachFiles ), 00066 mMailAddresses( other.mMailAddresses ), 00067 mAlarmTime( other.mAlarmTime ), 00068 mAlarmSnoozeTime( other.mAlarmSnoozeTime ), 00069 mAlarmRepeatCount( other.mAlarmRepeatCount ), 00070 mOffset( other.mOffset ), 00071 mEndOffset( other.mEndOffset ), 00072 mHasTime( other.mHasTime ), 00073 mAlarmEnabled( other.mAlarmEnabled ) 00074 {} 00075 00076 Incidence *mParent; // the incidence which this alarm belongs to 00077 00078 Type mType; // type of alarm 00079 QString mDescription;// text to display/email body/procedure arguments 00080 QString mFile; // program to run/optional audio file to play 00081 QString mMailSubject;// subject of email 00082 QStringList mMailAttachFiles; // filenames to attach to email 00083 QList<Person> mMailAddresses; // who to mail for reminder 00084 00085 KDateTime mAlarmTime;// time at which to trigger the alarm 00086 Duration mAlarmSnoozeTime; // how long after alarm to snooze before 00087 // triggering again 00088 int mAlarmRepeatCount;// number of times for alarm to repeat 00089 // after the initial time 00090 00091 Duration mOffset; // time relative to incidence DTSTART 00092 // to trigger the alarm 00093 bool mEndOffset; // if true, mOffset relates to DTEND, not DTSTART 00094 bool mHasTime; // use mAlarmTime, not mOffset 00095 bool mAlarmEnabled; 00096 }; 00097 //@endcond 00098 00099 Alarm::Alarm( Incidence *parent ) : d( new KCal::Alarm::Private ) 00100 { 00101 d->mParent = parent; 00102 } 00103 00104 Alarm::Alarm( const Alarm &other ) : 00105 CustomProperties( other ), d( new KCal::Alarm::Private( *other.d ) ) 00106 { 00107 } 00108 00109 Alarm::~Alarm() 00110 { 00111 delete d; 00112 } 00113 00114 Alarm &Alarm::operator=( const Alarm &a ) 00115 { 00116 d->mParent = a.d->mParent; 00117 d->mType = a.d->mType; 00118 d->mDescription = a.d->mDescription; 00119 d->mFile = a.d->mFile; 00120 d->mMailAttachFiles = a.d->mMailAttachFiles; 00121 d->mMailAddresses = a.d->mMailAddresses; 00122 d->mMailSubject = a.d->mMailSubject; 00123 d->mAlarmSnoozeTime = a.d->mAlarmSnoozeTime; 00124 d->mAlarmRepeatCount = a.d->mAlarmRepeatCount; 00125 d->mAlarmTime = a.d->mAlarmTime; 00126 d->mOffset = a.d->mOffset; 00127 d->mEndOffset = a.d->mEndOffset; 00128 d->mHasTime = a.d->mHasTime; 00129 d->mAlarmEnabled = a.d->mAlarmEnabled; 00130 return *this; 00131 } 00132 00133 bool Alarm::operator==( const Alarm &rhs ) const 00134 { 00135 if ( d->mType != rhs.d->mType || 00136 d->mAlarmSnoozeTime != rhs.d->mAlarmSnoozeTime || 00137 d->mAlarmRepeatCount != rhs.d->mAlarmRepeatCount || 00138 d->mAlarmEnabled != rhs.d->mAlarmEnabled || 00139 d->mHasTime != rhs.d->mHasTime ) { 00140 return false; 00141 } 00142 00143 if ( d->mHasTime ) { 00144 if ( d->mAlarmTime != rhs.d->mAlarmTime ) { 00145 return false; 00146 } 00147 } else { 00148 if ( d->mOffset != rhs.d->mOffset || d->mEndOffset != rhs.d->mEndOffset ) { 00149 return false; 00150 } 00151 } 00152 00153 switch ( d->mType ) { 00154 case Display: 00155 return d->mDescription == rhs.d->mDescription; 00156 00157 case Email: 00158 return d->mDescription == rhs.d->mDescription && 00159 d->mMailAttachFiles == rhs.d->mMailAttachFiles && 00160 d->mMailAddresses == rhs.d->mMailAddresses && 00161 d->mMailSubject == rhs.d->mMailSubject; 00162 00163 case Procedure: 00164 return d->mFile == rhs.d->mFile && 00165 d->mDescription == rhs.d->mDescription; 00166 00167 case Audio: 00168 return d->mFile == rhs.d->mFile; 00169 00170 case Invalid: 00171 break; 00172 } 00173 return false; 00174 } 00175 00176 void Alarm::setType( Alarm::Type type ) 00177 { 00178 if ( type == d->mType ) { 00179 return; 00180 } 00181 00182 switch ( type ) { 00183 case Display: 00184 d->mDescription = ""; 00185 break; 00186 case Procedure: 00187 d->mFile = d->mDescription = ""; 00188 break; 00189 case Audio: 00190 d->mFile = ""; 00191 break; 00192 case Email: 00193 d->mMailSubject = d->mDescription = ""; 00194 d->mMailAddresses.clear(); 00195 d->mMailAttachFiles.clear(); 00196 break; 00197 case Invalid: 00198 break; 00199 default: 00200 return; 00201 } 00202 d->mType = type; 00203 if ( d->mParent ) { 00204 d->mParent->updated(); 00205 } 00206 } 00207 00208 Alarm::Type Alarm::type() const 00209 { 00210 return d->mType; 00211 } 00212 00213 void Alarm::setAudioAlarm( const QString &audioFile ) 00214 { 00215 d->mType = Audio; 00216 d->mFile = audioFile; 00217 if ( d->mParent ) { 00218 d->mParent->updated(); 00219 } 00220 } 00221 00222 void Alarm::setAudioFile( const QString &audioFile ) 00223 { 00224 if ( d->mType == Audio ) { 00225 d->mFile = audioFile; 00226 if ( d->mParent ) { 00227 d->mParent->updated(); 00228 } 00229 } 00230 } 00231 00232 QString Alarm::audioFile() const 00233 { 00234 return ( d->mType == Audio ) ? d->mFile : QString(); 00235 } 00236 00237 void Alarm::setProcedureAlarm( const QString &programFile, 00238 const QString &arguments ) 00239 { 00240 d->mType = Procedure; 00241 d->mFile = programFile; 00242 d->mDescription = arguments; 00243 if ( d->mParent ) { 00244 d->mParent->updated(); 00245 } 00246 } 00247 00248 void Alarm::setProgramFile( const QString &programFile ) 00249 { 00250 if ( d->mType == Procedure ) { 00251 d->mFile = programFile; 00252 if ( d->mParent ) { 00253 d->mParent->updated(); 00254 } 00255 } 00256 } 00257 00258 QString Alarm::programFile() const 00259 { 00260 return ( d->mType == Procedure ) ? d->mFile : QString(); 00261 } 00262 00263 void Alarm::setProgramArguments( const QString &arguments ) 00264 { 00265 if ( d->mType == Procedure ) { 00266 d->mDescription = arguments; 00267 if ( d->mParent ) { 00268 d->mParent->updated(); 00269 } 00270 } 00271 } 00272 00273 QString Alarm::programArguments() const 00274 { 00275 return ( d->mType == Procedure ) ? d->mDescription : QString(); 00276 } 00277 00278 void Alarm::setEmailAlarm( const QString &subject, const QString &text, 00279 const QList<Person> &addressees, 00280 const QStringList &attachments ) 00281 { 00282 d->mType = Email; 00283 d->mMailSubject = subject; 00284 d->mDescription = text; 00285 d->mMailAddresses = addressees; 00286 d->mMailAttachFiles = attachments; 00287 if ( d->mParent ) { 00288 d->mParent->updated(); 00289 } 00290 } 00291 00292 void Alarm::setMailAddress( const Person &mailAddress ) 00293 { 00294 if ( d->mType == Email ) { 00295 d->mMailAddresses.clear(); 00296 d->mMailAddresses += mailAddress; 00297 if ( d->mParent ) { 00298 d->mParent->updated(); 00299 } 00300 } 00301 } 00302 00303 void Alarm::setMailAddresses( const QList<Person> &mailAddresses ) 00304 { 00305 if ( d->mType == Email ) { 00306 d->mMailAddresses = mailAddresses; 00307 if ( d->mParent ) { 00308 d->mParent->updated(); 00309 } 00310 } 00311 } 00312 00313 void Alarm::addMailAddress( const Person &mailAddress ) 00314 { 00315 if ( d->mType == Email ) { 00316 d->mMailAddresses += mailAddress; 00317 if ( d->mParent ) { 00318 d->mParent->updated(); 00319 } 00320 } 00321 } 00322 00323 QList<Person> Alarm::mailAddresses() const 00324 { 00325 return ( d->mType == Email ) ? d->mMailAddresses : QList<Person>(); 00326 } 00327 00328 void Alarm::setMailSubject( const QString &mailAlarmSubject ) 00329 { 00330 if ( d->mType == Email ) { 00331 d->mMailSubject = mailAlarmSubject; 00332 if ( d->mParent ) { 00333 d->mParent->updated(); 00334 } 00335 } 00336 } 00337 00338 QString Alarm::mailSubject() const 00339 { 00340 return ( d->mType == Email ) ? d->mMailSubject : QString(); 00341 } 00342 00343 void Alarm::setMailAttachment( const QString &mailAttachFile ) 00344 { 00345 if ( d->mType == Email ) { 00346 d->mMailAttachFiles.clear(); 00347 d->mMailAttachFiles += mailAttachFile; 00348 if ( d->mParent ) { 00349 d->mParent->updated(); 00350 } 00351 } 00352 } 00353 00354 void Alarm::setMailAttachments( const QStringList &mailAttachFiles ) 00355 { 00356 if ( d->mType == Email ) { 00357 d->mMailAttachFiles = mailAttachFiles; 00358 if ( d->mParent ) { 00359 d->mParent->updated(); 00360 } 00361 } 00362 } 00363 00364 void Alarm::addMailAttachment( const QString &mailAttachFile ) 00365 { 00366 if ( d->mType == Email ) { 00367 d->mMailAttachFiles += mailAttachFile; 00368 if ( d->mParent ) { 00369 d->mParent->updated(); 00370 } 00371 } 00372 } 00373 00374 QStringList Alarm::mailAttachments() const 00375 { 00376 return ( d->mType == Email ) ? d->mMailAttachFiles : QStringList(); 00377 } 00378 00379 void Alarm::setMailText( const QString &text ) 00380 { 00381 if ( d->mType == Email ) { 00382 d->mDescription = text; 00383 if ( d->mParent ) { 00384 d->mParent->updated(); 00385 } 00386 } 00387 } 00388 00389 QString Alarm::mailText() const 00390 { 00391 return ( d->mType == Email ) ? d->mDescription : QString(); 00392 } 00393 00394 void Alarm::setDisplayAlarm( const QString &text ) 00395 { 00396 d->mType = Display; 00397 if ( !text.isNull() ) { 00398 d->mDescription = text; 00399 } 00400 if ( d->mParent ) { 00401 d->mParent->updated(); 00402 } 00403 } 00404 00405 void Alarm::setText( const QString &text ) 00406 { 00407 if ( d->mType == Display ) { 00408 d->mDescription = text; 00409 if ( d->mParent ) { 00410 d->mParent->updated(); 00411 } 00412 } 00413 } 00414 00415 QString Alarm::text() const 00416 { 00417 return ( d->mType == Display ) ? d->mDescription : QString(); 00418 } 00419 00420 void Alarm::setTime( const KDateTime &alarmTime ) 00421 { 00422 d->mAlarmTime = alarmTime; 00423 d->mHasTime = true; 00424 00425 if ( d->mParent ) { 00426 d->mParent->updated(); 00427 } 00428 } 00429 00430 KDateTime Alarm::time() const 00431 { 00432 if ( hasTime() ) { 00433 return d->mAlarmTime; 00434 } else if ( d->mParent ) { 00435 if ( d->mEndOffset ) { 00436 if ( d->mParent->type() == "Todo" ) { 00437 Todo *t = static_cast<Todo*>( d->mParent ); 00438 return d->mOffset.end( t->dtDue() ); 00439 } else { 00440 return d->mOffset.end( d->mParent->dtEnd() ); 00441 } 00442 } else { 00443 return d->mOffset.end( d->mParent->dtStart() ); 00444 } 00445 } else { 00446 return KDateTime(); 00447 } 00448 } 00449 00450 bool Alarm::hasTime() const 00451 { 00452 return d->mHasTime; 00453 } 00454 00455 void Alarm::shiftTimes( const KDateTime::Spec &oldSpec, 00456 const KDateTime::Spec &newSpec ) 00457 { 00458 d->mAlarmTime = d->mAlarmTime.toTimeSpec( oldSpec ); 00459 d->mAlarmTime.setTimeSpec( newSpec ); 00460 if ( d->mParent ) { 00461 d->mParent->updated(); 00462 } 00463 } 00464 00465 void Alarm::setSnoozeTime( const Duration &alarmSnoozeTime ) 00466 { 00467 if ( alarmSnoozeTime.value() > 0 ) { 00468 d->mAlarmSnoozeTime = alarmSnoozeTime; 00469 if ( d->mParent ) { 00470 d->mParent->updated(); 00471 } 00472 } 00473 } 00474 00475 Duration Alarm::snoozeTime() const 00476 { 00477 return d->mAlarmSnoozeTime; 00478 } 00479 00480 void Alarm::setRepeatCount( int alarmRepeatCount ) 00481 { 00482 d->mAlarmRepeatCount = alarmRepeatCount; 00483 if ( d->mParent ) { 00484 d->mParent->updated(); 00485 } 00486 } 00487 00488 int Alarm::repeatCount() const 00489 { 00490 return d->mAlarmRepeatCount; 00491 } 00492 00493 Duration Alarm::duration() const 00494 { 00495 return Duration( d->mAlarmSnoozeTime.value() * d->mAlarmRepeatCount, 00496 d->mAlarmSnoozeTime.type() ); 00497 } 00498 00499 KDateTime Alarm::nextRepetition( const KDateTime &preTime ) const 00500 { 00501 KDateTime at = time(); 00502 if ( at > preTime ) { 00503 return at; 00504 } 00505 if ( !d->mAlarmRepeatCount ) { 00506 // there isn't an occurrence after the specified time 00507 return KDateTime(); 00508 } 00509 qint64 repetition; 00510 int interval = d->mAlarmSnoozeTime.value(); 00511 bool daily = d->mAlarmSnoozeTime.isDaily(); 00512 if ( daily ) { 00513 int daysTo = at.daysTo( preTime ); 00514 if ( !preTime.isDateOnly() && preTime.time() <= at.time() ) { 00515 --daysTo; 00516 } 00517 repetition = daysTo / interval + 1; 00518 } else { 00519 repetition = at.secsTo_long( preTime ) / interval + 1; 00520 } 00521 if ( repetition > d->mAlarmRepeatCount ) { 00522 // all repetitions have finished before the specified time 00523 return KDateTime(); 00524 } 00525 return daily ? at.addDays( int( repetition * interval ) ) 00526 : at.addSecs( repetition * interval ); 00527 } 00528 00529 KDateTime Alarm::previousRepetition( const KDateTime &afterTime ) const 00530 { 00531 KDateTime at = time(); 00532 if ( at >= afterTime ) { 00533 // alarm's first/only time is at/after the specified time 00534 return KDateTime(); 00535 } 00536 if ( !d->mAlarmRepeatCount ) { 00537 return at; 00538 } 00539 qint64 repetition; 00540 int interval = d->mAlarmSnoozeTime.value(); 00541 bool daily = d->mAlarmSnoozeTime.isDaily(); 00542 if ( daily ) { 00543 int daysTo = at.daysTo( afterTime ); 00544 if ( afterTime.isDateOnly() || afterTime.time() <= at.time() ) { 00545 --daysTo; 00546 } 00547 repetition = daysTo / interval; 00548 } else { 00549 repetition = ( at.secsTo_long( afterTime ) - 1 ) / interval; 00550 } 00551 if ( repetition > d->mAlarmRepeatCount ) { 00552 repetition = d->mAlarmRepeatCount; 00553 } 00554 return daily ? at.addDays( int( repetition * interval ) ) 00555 : at.addSecs( repetition * interval ); 00556 } 00557 00558 KDateTime Alarm::endTime() const 00559 { 00560 if ( !d->mAlarmRepeatCount ) { 00561 return time(); 00562 } 00563 if ( d->mAlarmSnoozeTime.isDaily() ) { 00564 return time().addDays( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asDays() ); 00565 } else { 00566 return time().addSecs( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asSeconds() ); 00567 } 00568 } 00569 00570 void Alarm::toggleAlarm() 00571 { 00572 d->mAlarmEnabled = !d->mAlarmEnabled; 00573 if ( d->mParent ) { 00574 d->mParent->updated(); 00575 } 00576 } 00577 00578 void Alarm::setEnabled( bool enable ) 00579 { 00580 d->mAlarmEnabled = enable; 00581 if ( d->mParent ) { 00582 d->mParent->updated(); 00583 } 00584 } 00585 00586 bool Alarm::enabled() const 00587 { 00588 return d->mAlarmEnabled; 00589 } 00590 00591 void Alarm::setStartOffset( const Duration &offset ) 00592 { 00593 d->mOffset = offset; 00594 d->mEndOffset = false; 00595 d->mHasTime = false; 00596 if ( d->mParent ) { 00597 d->mParent->updated(); 00598 } 00599 } 00600 00601 Duration Alarm::startOffset() const 00602 { 00603 return ( d->mHasTime || d->mEndOffset ) ? Duration( 0 ) : d->mOffset; 00604 } 00605 00606 bool Alarm::hasStartOffset() const 00607 { 00608 return !d->mHasTime && !d->mEndOffset; 00609 } 00610 00611 bool Alarm::hasEndOffset() const 00612 { 00613 return !d->mHasTime && d->mEndOffset; 00614 } 00615 00616 void Alarm::setEndOffset( const Duration &offset ) 00617 { 00618 d->mOffset = offset; 00619 d->mEndOffset = true; 00620 d->mHasTime = false; 00621 if ( d->mParent ) { 00622 d->mParent->updated(); 00623 } 00624 } 00625 00626 Duration Alarm::endOffset() const 00627 { 00628 return ( d->mHasTime || !d->mEndOffset ) ? Duration( 0 ) : d->mOffset; 00629 } 00630 00631 void Alarm::setParent( Incidence *parent ) 00632 { 00633 d->mParent = parent; 00634 } 00635 00636 Incidence *Alarm::parent() const 00637 { 00638 return d->mParent; 00639 } 00640 00641 void Alarm::customPropertyUpdated() 00642 { 00643 if ( d->mParent ) { 00644 d->mParent->updated(); 00645 } 00646 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:10:03 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:10:03 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.