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 : 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;
00077
00078 Type mType;
00079 QString mDescription;
00080 QString mFile;
00081 QString mMailSubject;
00082 QStringList mMailAttachFiles;
00083 QList<Person> mMailAddresses;
00084
00085 KDateTime mAlarmTime;
00086 Duration mAlarmSnoozeTime;
00087
00088 int mAlarmRepeatCount;
00089
00090
00091 Duration mOffset;
00092
00093 bool mEndOffset;
00094 bool mHasTime;
00095 bool mAlarmEnabled;
00096 };
00097
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
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
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
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 }