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