KCal Library
alarm.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00047 class KCal::Alarm::Private
00048 {
00049 public:
00050 Private()
00051 : mType( Alarm::Invalid ),
00052 mAlarmSnoozeTime( 5 ),
00053 mAlarmRepeatCount( 0 ),
00054 mEndOffset( false ),
00055 mHasTime( false ),
00056 mAlarmEnabled( false )
00057 {}
00058 Private( const Private &other )
00059 : mParent( other.mParent ),
00060 mType( other.mType ),
00061 mDescription( other.mDescription ),
00062 mFile( other.mFile ),
00063 mMailSubject( other.mMailSubject ),
00064 mMailAttachFiles( other.mMailAttachFiles ),
00065 mMailAddresses( other.mMailAddresses ),
00066 mAlarmTime( other.mAlarmTime ),
00067 mAlarmSnoozeTime( other.mAlarmSnoozeTime ),
00068 mAlarmRepeatCount( other.mAlarmRepeatCount ),
00069 mOffset( other.mOffset ),
00070 mEndOffset( other.mEndOffset ),
00071 mHasTime( other.mHasTime ),
00072 mAlarmEnabled( other.mAlarmEnabled )
00073 {}
00074
00075 Incidence *mParent;
00076
00077 Type mType;
00078 QString mDescription;
00079 QString mFile;
00080 QString mMailSubject;
00081 QStringList mMailAttachFiles;
00082 QList<Person> mMailAddresses;
00083
00084 KDateTime mAlarmTime;
00085 Duration mAlarmSnoozeTime;
00086
00087 int mAlarmRepeatCount;
00088
00089
00090 Duration mOffset;
00091
00092 bool mEndOffset;
00093 bool mHasTime;
00094 bool mAlarmEnabled;
00095 };
00096
00097
00098 Alarm::Alarm( Incidence *parent ) : d( new KCal::Alarm::Private )
00099 {
00100 d->mParent = parent;
00101 }
00102
00103 Alarm::Alarm( const Alarm &other ) :
00104 CustomProperties( other ), d( new KCal::Alarm::Private( *other.d ) )
00105 {
00106 }
00107
00108 Alarm::~Alarm()
00109 {
00110 delete d;
00111 }
00112
00113 bool Alarm::operator==( const Alarm &rhs ) const
00114 {
00115 if ( d->mType != rhs.d->mType ||
00116 d->mAlarmSnoozeTime != rhs.d->mAlarmSnoozeTime ||
00117 d->mAlarmRepeatCount != rhs.d->mAlarmRepeatCount ||
00118 d->mAlarmEnabled != rhs.d->mAlarmEnabled ||
00119 d->mHasTime != rhs.d->mHasTime ) {
00120 return false;
00121 }
00122
00123 if ( d->mHasTime ) {
00124 if ( d->mAlarmTime != rhs.d->mAlarmTime ) {
00125 return false;
00126 }
00127 } else {
00128 if ( d->mOffset != rhs.d->mOffset || d->mEndOffset != rhs.d->mEndOffset ) {
00129 return false;
00130 }
00131 }
00132
00133 switch ( d->mType ) {
00134 case Display:
00135 return d->mDescription == rhs.d->mDescription;
00136
00137 case Email:
00138 return d->mDescription == rhs.d->mDescription &&
00139 d->mMailAttachFiles == rhs.d->mMailAttachFiles &&
00140 d->mMailAddresses == rhs.d->mMailAddresses &&
00141 d->mMailSubject == rhs.d->mMailSubject;
00142
00143 case Procedure:
00144 return d->mFile == rhs.d->mFile &&
00145 d->mDescription == rhs.d->mDescription;
00146
00147 case Audio:
00148 return d->mFile == rhs.d->mFile;
00149
00150 case Invalid:
00151 break;
00152 }
00153 return false;
00154 }
00155
00156 void Alarm::setType( Alarm::Type type )
00157 {
00158 if ( type == d->mType ) {
00159 return;
00160 }
00161
00162 switch ( type ) {
00163 case Display:
00164 d->mDescription = "";
00165 break;
00166 case Procedure:
00167 d->mFile = d->mDescription = "";
00168 break;
00169 case Audio:
00170 d->mFile = "";
00171 break;
00172 case Email:
00173 d->mMailSubject = d->mDescription = "";
00174 d->mMailAddresses.clear();
00175 d->mMailAttachFiles.clear();
00176 break;
00177 case Invalid:
00178 break;
00179 default:
00180 return;
00181 }
00182 d->mType = type;
00183 if ( d->mParent ) {
00184 d->mParent->updated();
00185 }
00186 }
00187
00188 Alarm::Type Alarm::type() const
00189 {
00190 return d->mType;
00191 }
00192
00193 void Alarm::setAudioAlarm( const QString &audioFile )
00194 {
00195 d->mType = Audio;
00196 d->mFile = audioFile;
00197 if ( d->mParent ) {
00198 d->mParent->updated();
00199 }
00200 }
00201
00202 void Alarm::setAudioFile( const QString &audioFile )
00203 {
00204 if ( d->mType == Audio ) {
00205 d->mFile = audioFile;
00206 if ( d->mParent ) {
00207 d->mParent->updated();
00208 }
00209 }
00210 }
00211
00212 QString Alarm::audioFile() const
00213 {
00214 return ( d->mType == Audio ) ? d->mFile : QString();
00215 }
00216
00217 void Alarm::setProcedureAlarm( const QString &programFile,
00218 const QString &arguments )
00219 {
00220 d->mType = Procedure;
00221 d->mFile = programFile;
00222 d->mDescription = arguments;
00223 if ( d->mParent ) {
00224 d->mParent->updated();
00225 }
00226 }
00227
00228 void Alarm::setProgramFile( const QString &programFile )
00229 {
00230 if ( d->mType == Procedure ) {
00231 d->mFile = programFile;
00232 if ( d->mParent ) {
00233 d->mParent->updated();
00234 }
00235 }
00236 }
00237
00238 QString Alarm::programFile() const
00239 {
00240 return ( d->mType == Procedure ) ? d->mFile : QString();
00241 }
00242
00243 void Alarm::setProgramArguments( const QString &arguments )
00244 {
00245 if ( d->mType == Procedure ) {
00246 d->mDescription = arguments;
00247 if ( d->mParent ) {
00248 d->mParent->updated();
00249 }
00250 }
00251 }
00252
00253 QString Alarm::programArguments() const
00254 {
00255 return ( d->mType == Procedure ) ? d->mDescription : QString();
00256 }
00257
00258 void Alarm::setEmailAlarm( const QString &subject, const QString &text,
00259 const QList<Person> &addressees,
00260 const QStringList &attachments )
00261 {
00262 d->mType = Email;
00263 d->mMailSubject = subject;
00264 d->mDescription = text;
00265 d->mMailAddresses = addressees;
00266 d->mMailAttachFiles = attachments;
00267 if ( d->mParent ) {
00268 d->mParent->updated();
00269 }
00270 }
00271
00272 void Alarm::setMailAddress( const Person &mailAddress )
00273 {
00274 if ( d->mType == Email ) {
00275 d->mMailAddresses.clear();
00276 d->mMailAddresses += mailAddress;
00277 if ( d->mParent ) {
00278 d->mParent->updated();
00279 }
00280 }
00281 }
00282
00283 void Alarm::setMailAddresses( const QList<Person> &mailAddresses )
00284 {
00285 if ( d->mType == Email ) {
00286 d->mMailAddresses = mailAddresses;
00287 if ( d->mParent ) {
00288 d->mParent->updated();
00289 }
00290 }
00291 }
00292
00293 void Alarm::addMailAddress( const Person &mailAddress )
00294 {
00295 if ( d->mType == Email ) {
00296 d->mMailAddresses += mailAddress;
00297 if ( d->mParent ) {
00298 d->mParent->updated();
00299 }
00300 }
00301 }
00302
00303 QList<Person> Alarm::mailAddresses() const
00304 {
00305 return ( d->mType == Email ) ? d->mMailAddresses : QList<Person>();
00306 }
00307
00308 void Alarm::setMailSubject( const QString &mailAlarmSubject )
00309 {
00310 if ( d->mType == Email ) {
00311 d->mMailSubject = mailAlarmSubject;
00312 if ( d->mParent ) {
00313 d->mParent->updated();
00314 }
00315 }
00316 }
00317
00318 QString Alarm::mailSubject() const
00319 {
00320 return ( d->mType == Email ) ? d->mMailSubject : QString();
00321 }
00322
00323 void Alarm::setMailAttachment( const QString &mailAttachFile )
00324 {
00325 if ( d->mType == Email ) {
00326 d->mMailAttachFiles.clear();
00327 d->mMailAttachFiles += mailAttachFile;
00328 if ( d->mParent ) {
00329 d->mParent->updated();
00330 }
00331 }
00332 }
00333
00334 void Alarm::setMailAttachments( const QStringList &mailAttachFiles )
00335 {
00336 if ( d->mType == Email ) {
00337 d->mMailAttachFiles = mailAttachFiles;
00338 if ( d->mParent ) {
00339 d->mParent->updated();
00340 }
00341 }
00342 }
00343
00344 void Alarm::addMailAttachment( const QString &mailAttachFile )
00345 {
00346 if ( d->mType == Email ) {
00347 d->mMailAttachFiles += mailAttachFile;
00348 if ( d->mParent ) {
00349 d->mParent->updated();
00350 }
00351 }
00352 }
00353
00354 QStringList Alarm::mailAttachments() const
00355 {
00356 return ( d->mType == Email ) ? d->mMailAttachFiles : QStringList();
00357 }
00358
00359 void Alarm::setMailText( const QString &text )
00360 {
00361 if ( d->mType == Email ) {
00362 d->mDescription = text;
00363 if ( d->mParent ) {
00364 d->mParent->updated();
00365 }
00366 }
00367 }
00368
00369 QString Alarm::mailText() const
00370 {
00371 return ( d->mType == Email ) ? d->mDescription : QString();
00372 }
00373
00374 void Alarm::setDisplayAlarm( const QString &text )
00375 {
00376 d->mType = Display;
00377 if ( !text.isNull() ) {
00378 d->mDescription = text;
00379 }
00380 if ( d->mParent ) {
00381 d->mParent->updated();
00382 }
00383 }
00384
00385 void Alarm::setText( const QString &text )
00386 {
00387 if ( d->mType == Display ) {
00388 d->mDescription = text;
00389 if ( d->mParent ) {
00390 d->mParent->updated();
00391 }
00392 }
00393 }
00394
00395 QString Alarm::text() const
00396 {
00397 return ( d->mType == Display ) ? d->mDescription : QString();
00398 }
00399
00400 void Alarm::setTime( const KDateTime &alarmTime )
00401 {
00402 d->mAlarmTime = alarmTime;
00403 d->mHasTime = true;
00404
00405 if ( d->mParent ) {
00406 d->mParent->updated();
00407 }
00408 }
00409
00410 KDateTime Alarm::time() const
00411 {
00412 if ( hasTime() ) {
00413 return d->mAlarmTime;
00414 } else if ( d->mParent ) {
00415 if ( d->mParent->type() == "Todo" ) {
00416 Todo *t = static_cast<Todo*>( d->mParent );
00417 return d->mOffset.end( t->dtDue() );
00418 } else if ( d->mEndOffset ) {
00419 return d->mOffset.end( d->mParent->dtEnd() );
00420 } else {
00421 return d->mOffset.end( d->mParent->dtStart() );
00422 }
00423 } else {
00424 return KDateTime();
00425 }
00426 }
00427
00428 bool Alarm::hasTime() const
00429 {
00430 return d->mHasTime;
00431 }
00432
00433 void Alarm::shiftTimes( const KDateTime::Spec &oldSpec,
00434 const KDateTime::Spec &newSpec )
00435 {
00436 d->mAlarmTime = d->mAlarmTime.toTimeSpec( oldSpec );
00437 d->mAlarmTime.setTimeSpec( newSpec );
00438 if ( d->mParent ) {
00439 d->mParent->updated();
00440 }
00441 }
00442
00443 void Alarm::setSnoozeTime( const Duration &alarmSnoozeTime )
00444 {
00445 if ( alarmSnoozeTime.value() > 0 ) {
00446 d->mAlarmSnoozeTime = alarmSnoozeTime;
00447 if ( d->mParent ) {
00448 d->mParent->updated();
00449 }
00450 }
00451 }
00452
00453 Duration Alarm::snoozeTime() const
00454 {
00455 return d->mAlarmSnoozeTime;
00456 }
00457
00458 void Alarm::setRepeatCount( int alarmRepeatCount )
00459 {
00460 d->mAlarmRepeatCount = alarmRepeatCount;
00461 if ( d->mParent ) {
00462 d->mParent->updated();
00463 }
00464 }
00465
00466 int Alarm::repeatCount() const
00467 {
00468 return d->mAlarmRepeatCount;
00469 }
00470
00471 Duration Alarm::duration() const
00472 {
00473 return Duration( d->mAlarmSnoozeTime.value() * d->mAlarmRepeatCount,
00474 d->mAlarmSnoozeTime.type() );
00475 }
00476
00477 KDateTime Alarm::nextRepetition( const KDateTime &preTime ) const
00478 {
00479 KDateTime at = time();
00480 if ( at > preTime ) {
00481 return at;
00482 }
00483 if ( !d->mAlarmRepeatCount ) {
00484
00485 return KDateTime();
00486 }
00487 int repetition;
00488 int interval = d->mAlarmSnoozeTime.value();
00489 bool daily = d->mAlarmSnoozeTime.isDaily();
00490 if ( daily ) {
00491 int daysTo = at.daysTo( preTime );
00492 if ( !preTime.isDateOnly() && preTime.time() <= at.time() ) {
00493 --daysTo;
00494 }
00495 repetition = daysTo / interval + 1;
00496 } else {
00497 repetition = at.secsTo_long( preTime ) / interval + 1;
00498 }
00499 if ( repetition > d->mAlarmRepeatCount ) {
00500
00501 return KDateTime();
00502 }
00503 return daily ? at.addDays( repetition * interval )
00504 : at.addSecs( repetition * interval );
00505 }
00506
00507 KDateTime Alarm::previousRepetition( const KDateTime &afterTime ) const
00508 {
00509 KDateTime at = time();
00510 if ( at >= afterTime ) {
00511
00512 return KDateTime();
00513 }
00514 if ( !d->mAlarmRepeatCount ) {
00515 return at;
00516 }
00517 int repetition;
00518 int interval = d->mAlarmSnoozeTime.value();
00519 bool daily = d->mAlarmSnoozeTime.isDaily();
00520 if ( daily ) {
00521 int daysTo = at.daysTo( afterTime );
00522 if ( afterTime.isDateOnly() || afterTime.time() <= at.time() ) {
00523 --daysTo;
00524 }
00525 repetition = daysTo / interval;
00526 } else {
00527 repetition = ( at.secsTo_long( afterTime ) - 1 ) / interval;
00528 }
00529 if ( repetition > d->mAlarmRepeatCount ) {
00530 repetition = d->mAlarmRepeatCount;
00531 }
00532 return daily ? at.addDays( repetition * interval )
00533 : at.addSecs( repetition * interval );
00534 }
00535
00536 KDateTime Alarm::endTime() const
00537 {
00538 if ( !d->mAlarmRepeatCount ) {
00539 return time();
00540 }
00541 if ( d->mAlarmSnoozeTime.isDaily() ) {
00542 return time().addDays( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asDays() );
00543 } else {
00544 return time().addSecs( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asSeconds() );
00545 }
00546 }
00547
00548 void Alarm::toggleAlarm()
00549 {
00550 d->mAlarmEnabled = !d->mAlarmEnabled;
00551 if ( d->mParent ) {
00552 d->mParent->updated();
00553 }
00554 }
00555
00556 void Alarm::setEnabled( bool enable )
00557 {
00558 d->mAlarmEnabled = enable;
00559 if ( d->mParent ) {
00560 d->mParent->updated();
00561 }
00562 }
00563
00564 bool Alarm::enabled() const
00565 {
00566 return d->mAlarmEnabled;
00567 }
00568
00569 void Alarm::setStartOffset( const Duration &offset )
00570 {
00571 d->mOffset = offset;
00572 d->mEndOffset = false;
00573 d->mHasTime = false;
00574 if ( d->mParent ) {
00575 d->mParent->updated();
00576 }
00577 }
00578
00579 Duration Alarm::startOffset() const
00580 {
00581 return ( d->mHasTime || d->mEndOffset ) ? Duration( 0 ) : d->mOffset;
00582 }
00583
00584 bool Alarm::hasStartOffset() const
00585 {
00586 return !d->mHasTime && !d->mEndOffset;
00587 }
00588
00589 bool Alarm::hasEndOffset() const
00590 {
00591 return !d->mHasTime && d->mEndOffset;
00592 }
00593
00594 void Alarm::setEndOffset( const Duration &offset )
00595 {
00596 d->mOffset = offset;
00597 d->mEndOffset = true;
00598 d->mHasTime = false;
00599 if ( d->mParent ) {
00600 d->mParent->updated();
00601 }
00602 }
00603
00604 Duration Alarm::endOffset() const
00605 {
00606 return ( d->mHasTime || !d->mEndOffset ) ? Duration( 0 ) : d->mOffset;
00607 }
00608
00609 void Alarm::setParent( Incidence *parent )
00610 {
00611 d->mParent = parent;
00612 }
00613
00614 Incidence *Alarm::parent() const
00615 {
00616 return d->mParent;
00617 }
00618
00619 void Alarm::customPropertyUpdated()
00620 {
00621 if ( d->mParent ) {
00622 d->mParent->updated();
00623 }
00624 }