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->mEndOffset ) {
00416 if ( d->mParent->type() == "Todo" ) {
00417 Todo *t = static_cast<Todo*>( d->mParent );
00418 return d->mOffset.end( t->dtDue() );
00419 } else {
00420 return d->mOffset.end( d->mParent->dtEnd() );
00421 }
00422 } else {
00423 return d->mOffset.end( d->mParent->dtStart() );
00424 }
00425 } else {
00426 return KDateTime();
00427 }
00428 }
00429
00430 bool Alarm::hasTime() const
00431 {
00432 return d->mHasTime;
00433 }
00434
00435 void Alarm::shiftTimes( const KDateTime::Spec &oldSpec,
00436 const KDateTime::Spec &newSpec )
00437 {
00438 d->mAlarmTime = d->mAlarmTime.toTimeSpec( oldSpec );
00439 d->mAlarmTime.setTimeSpec( newSpec );
00440 if ( d->mParent ) {
00441 d->mParent->updated();
00442 }
00443 }
00444
00445 void Alarm::setSnoozeTime( const Duration &alarmSnoozeTime )
00446 {
00447 if ( alarmSnoozeTime.value() > 0 ) {
00448 d->mAlarmSnoozeTime = alarmSnoozeTime;
00449 if ( d->mParent ) {
00450 d->mParent->updated();
00451 }
00452 }
00453 }
00454
00455 Duration Alarm::snoozeTime() const
00456 {
00457 return d->mAlarmSnoozeTime;
00458 }
00459
00460 void Alarm::setRepeatCount( int alarmRepeatCount )
00461 {
00462 d->mAlarmRepeatCount = alarmRepeatCount;
00463 if ( d->mParent ) {
00464 d->mParent->updated();
00465 }
00466 }
00467
00468 int Alarm::repeatCount() const
00469 {
00470 return d->mAlarmRepeatCount;
00471 }
00472
00473 Duration Alarm::duration() const
00474 {
00475 return Duration( d->mAlarmSnoozeTime.value() * d->mAlarmRepeatCount,
00476 d->mAlarmSnoozeTime.type() );
00477 }
00478
00479 KDateTime Alarm::nextRepetition( const KDateTime &preTime ) const
00480 {
00481 KDateTime at = time();
00482 if ( at > preTime ) {
00483 return at;
00484 }
00485 if ( !d->mAlarmRepeatCount ) {
00486
00487 return KDateTime();
00488 }
00489 int repetition;
00490 int interval = d->mAlarmSnoozeTime.value();
00491 bool daily = d->mAlarmSnoozeTime.isDaily();
00492 if ( daily ) {
00493 int daysTo = at.daysTo( preTime );
00494 if ( !preTime.isDateOnly() && preTime.time() <= at.time() ) {
00495 --daysTo;
00496 }
00497 repetition = daysTo / interval + 1;
00498 } else {
00499 repetition = at.secsTo_long( preTime ) / interval + 1;
00500 }
00501 if ( repetition > d->mAlarmRepeatCount ) {
00502
00503 return KDateTime();
00504 }
00505 return daily ? at.addDays( repetition * interval )
00506 : at.addSecs( repetition * interval );
00507 }
00508
00509 KDateTime Alarm::previousRepetition( const KDateTime &afterTime ) const
00510 {
00511 KDateTime at = time();
00512 if ( at >= afterTime ) {
00513
00514 return KDateTime();
00515 }
00516 if ( !d->mAlarmRepeatCount ) {
00517 return at;
00518 }
00519 int repetition;
00520 int interval = d->mAlarmSnoozeTime.value();
00521 bool daily = d->mAlarmSnoozeTime.isDaily();
00522 if ( daily ) {
00523 int daysTo = at.daysTo( afterTime );
00524 if ( afterTime.isDateOnly() || afterTime.time() <= at.time() ) {
00525 --daysTo;
00526 }
00527 repetition = daysTo / interval;
00528 } else {
00529 repetition = ( at.secsTo_long( afterTime ) - 1 ) / interval;
00530 }
00531 if ( repetition > d->mAlarmRepeatCount ) {
00532 repetition = d->mAlarmRepeatCount;
00533 }
00534 return daily ? at.addDays( repetition * interval )
00535 : at.addSecs( repetition * interval );
00536 }
00537
00538 KDateTime Alarm::endTime() const
00539 {
00540 if ( !d->mAlarmRepeatCount ) {
00541 return time();
00542 }
00543 if ( d->mAlarmSnoozeTime.isDaily() ) {
00544 return time().addDays( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asDays() );
00545 } else {
00546 return time().addSecs( d->mAlarmRepeatCount * d->mAlarmSnoozeTime.asSeconds() );
00547 }
00548 }
00549
00550 void Alarm::toggleAlarm()
00551 {
00552 d->mAlarmEnabled = !d->mAlarmEnabled;
00553 if ( d->mParent ) {
00554 d->mParent->updated();
00555 }
00556 }
00557
00558 void Alarm::setEnabled( bool enable )
00559 {
00560 d->mAlarmEnabled = enable;
00561 if ( d->mParent ) {
00562 d->mParent->updated();
00563 }
00564 }
00565
00566 bool Alarm::enabled() const
00567 {
00568 return d->mAlarmEnabled;
00569 }
00570
00571 void Alarm::setStartOffset( const Duration &offset )
00572 {
00573 d->mOffset = offset;
00574 d->mEndOffset = false;
00575 d->mHasTime = false;
00576 if ( d->mParent ) {
00577 d->mParent->updated();
00578 }
00579 }
00580
00581 Duration Alarm::startOffset() const
00582 {
00583 return ( d->mHasTime || d->mEndOffset ) ? Duration( 0 ) : d->mOffset;
00584 }
00585
00586 bool Alarm::hasStartOffset() const
00587 {
00588 return !d->mHasTime && !d->mEndOffset;
00589 }
00590
00591 bool Alarm::hasEndOffset() const
00592 {
00593 return !d->mHasTime && d->mEndOffset;
00594 }
00595
00596 void Alarm::setEndOffset( const Duration &offset )
00597 {
00598 d->mOffset = offset;
00599 d->mEndOffset = true;
00600 d->mHasTime = false;
00601 if ( d->mParent ) {
00602 d->mParent->updated();
00603 }
00604 }
00605
00606 Duration Alarm::endOffset() const
00607 {
00608 return ( d->mHasTime || !d->mEndOffset ) ? Duration( 0 ) : d->mOffset;
00609 }
00610
00611 void Alarm::setParent( Incidence *parent )
00612 {
00613 d->mParent = parent;
00614 }
00615
00616 Incidence *Alarm::parent() const
00617 {
00618 return d->mParent;
00619 }
00620
00621 void Alarm::customPropertyUpdated()
00622 {
00623 if ( d->mParent ) {
00624 d->mParent->updated();
00625 }
00626 }