libkcal
incidence.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <kglobal.h>
00024 #include <klocale.h>
00025 #include <kdebug.h>
00026
00027 #include "calformat.h"
00028
00029 #include "incidence.h"
00030
00031 using namespace KCal;
00032
00033 Incidence::Incidence() :
00034 IncidenceBase(),
00035 mRelatedTo(0), mStatus(StatusNone), mSecrecy(SecrecyPublic),
00036 mPriority(5), mRecurrence(0)
00037 {
00038 recreate();
00039
00040 mAlarms.setAutoDelete(true);
00041 mAttachments.setAutoDelete(true);
00042 }
00043
00044 Incidence::Incidence( const Incidence &i ) : IncidenceBase( i ),Recurrence::Observer()
00045 {
00046
00047 mRevision = i.mRevision;
00048 mCreated = i.mCreated;
00049 mDescription = i.mDescription;
00050 mSummary = i.mSummary;
00051 mCategories = i.mCategories;
00052
00053 mRelatedTo = 0;
00054 mRelatedToUid = i.mRelatedToUid;
00055
00056 mResources = i.mResources;
00057 mStatusString = i.mStatusString;
00058 mStatus = i.mStatus;
00059 mSecrecy = i.mSecrecy;
00060 mPriority = i.mPriority;
00061 mLocation = i.mLocation;
00062
00063
00064
00065
00066 Alarm::List::ConstIterator it;
00067 for( it = i.mAlarms.begin(); it != i.mAlarms.end(); ++it ) {
00068 Alarm *b = new Alarm( **it );
00069 b->setParent( this );
00070 mAlarms.append( b );
00071 }
00072 mAlarms.setAutoDelete(true);
00073
00074 Attachment::List::ConstIterator it1;
00075 for ( it1 = i.mAttachments.begin(); it1 != i.mAttachments.end(); ++it1 ) {
00076 Attachment *a = new Attachment( **it1 );
00077 mAttachments.append( a );
00078 }
00079 mAttachments.setAutoDelete( true );
00080
00081 if (i.mRecurrence) {
00082 mRecurrence = new Recurrence( *(i.mRecurrence) );
00083 mRecurrence->addObserver( this );
00084 } else
00085 mRecurrence = 0;
00086
00087 mSchedulingID = i.mSchedulingID;
00088 }
00089
00090 Incidence::~Incidence()
00091 {
00092 Incidence::List Relations = mRelations;
00093 List::ConstIterator it;
00094 for ( it = Relations.begin(); it != Relations.end(); ++it ) {
00095 if ( (*it)->relatedTo() == this ) (*it)->mRelatedTo = 0;
00096 }
00097 if ( relatedTo() ) relatedTo()->removeRelation( this );
00098
00099 delete mRecurrence;
00100 }
00101
00102
00103 static bool stringCompare( const QString& s1, const QString& s2 )
00104 {
00105 return ( s1.isEmpty() && s2.isEmpty() ) || (s1 == s2);
00106 }
00107
00108 bool Incidence::operator==( const Incidence& i2 ) const
00109 {
00110 if( alarms().count() != i2.alarms().count() ) {
00111 return false;
00112 }
00113
00114 Alarm::List::ConstIterator a1 = alarms().begin();
00115 Alarm::List::ConstIterator a2 = i2.alarms().begin();
00116 for( ; a1 != alarms().end() && a2 != i2.alarms().end(); ++a1, ++a2 )
00117 if( **a1 == **a2 )
00118 continue;
00119 else {
00120 return false;
00121 }
00122
00123 if ( !IncidenceBase::operator==(i2) )
00124 return false;
00125
00126 bool recurrenceEqual = ( mRecurrence == 0 && i2.mRecurrence == 0 );
00127 if ( !recurrenceEqual )
00128 {
00129 recurrenceEqual = mRecurrence != 0 &&
00130 i2.mRecurrence != 0 &&
00131 *mRecurrence == *i2.mRecurrence;
00132 }
00133
00134 return
00135 recurrenceEqual &&
00136 created() == i2.created() &&
00137 stringCompare( description(), i2.description() ) &&
00138 stringCompare( summary(), i2.summary() ) &&
00139 categories() == i2.categories() &&
00140
00141 stringCompare( relatedToUid(), i2.relatedToUid() ) &&
00142 relations() == i2.relations() &&
00143 attachments() == i2.attachments() &&
00144 resources() == i2.resources() &&
00145 mStatus == i2.mStatus &&
00146 ( mStatus == StatusNone || stringCompare( mStatusString, i2.mStatusString ) ) &&
00147 secrecy() == i2.secrecy() &&
00148 priority() == i2.priority() &&
00149 stringCompare( location(), i2.location() ) &&
00150 stringCompare( schedulingID(), i2.schedulingID() );
00151 }
00152
00153
00154 void Incidence::recreate()
00155 {
00156 setCreated(QDateTime::currentDateTime());
00157
00158 setUid(CalFormat::createUniqueId());
00159 setSchedulingID( QString::null );
00160
00161 setRevision(0);
00162
00163 setLastModified(QDateTime::currentDateTime());
00164 setPilotId( 0 );
00165 setSyncStatus( SYNCNONE );
00166 }
00167
00168 void Incidence::setReadOnly( bool readOnly )
00169 {
00170 IncidenceBase::setReadOnly( readOnly );
00171 if ( mRecurrence )
00172 mRecurrence->setRecurReadOnly( readOnly );
00173 }
00174
00175 void Incidence::setFloats(bool f)
00176 {
00177 if (mReadOnly) return;
00178 if ( recurrence() )
00179 recurrence()->setFloats( f );
00180 IncidenceBase::setFloats( f );
00181 }
00182
00183 void Incidence::setCreated( const QDateTime &created )
00184 {
00185 if (mReadOnly) return;
00186 mCreated = created;
00187
00188
00189
00190 }
00191
00192 QDateTime Incidence::created() const
00193 {
00194 return mCreated;
00195 }
00196
00197 void Incidence::setRevision( int rev )
00198 {
00199 if (mReadOnly) return;
00200 mRevision = rev;
00201
00202 updated();
00203 }
00204
00205 int Incidence::revision() const
00206 {
00207 return mRevision;
00208 }
00209
00210 void Incidence::setDtStart(const QDateTime &dtStart)
00211 {
00212 if ( mRecurrence ) {
00213 mRecurrence->setStartDateTime( dtStart );
00214 mRecurrence->setFloats( doesFloat() );
00215 }
00216 IncidenceBase::setDtStart( dtStart );
00217 }
00218
00219 void Incidence::setDescription(const QString &description)
00220 {
00221 if (mReadOnly) return;
00222 mDescription = description;
00223 updated();
00224 }
00225
00226 QString Incidence::description() const
00227 {
00228 return mDescription;
00229 }
00230
00231
00232 void Incidence::setSummary(const QString &summary)
00233 {
00234 if (mReadOnly) return;
00235 mSummary = summary;
00236 updated();
00237 }
00238
00239 QString Incidence::summary() const
00240 {
00241 return mSummary;
00242 }
00243
00244 void Incidence::setCategories(const QStringList &categories)
00245 {
00246 if (mReadOnly) return;
00247 mCategories = categories;
00248 updated();
00249 }
00250
00251
00252 void Incidence::setCategories(const QString &catStr)
00253 {
00254 if (mReadOnly) return;
00255 mCategories.clear();
00256
00257 if (catStr.isEmpty()) return;
00258
00259 mCategories = QStringList::split(",",catStr);
00260
00261 QStringList::Iterator it;
00262 for(it = mCategories.begin();it != mCategories.end(); ++it) {
00263 *it = (*it).stripWhiteSpace();
00264 }
00265
00266 updated();
00267 }
00268
00269 QStringList Incidence::categories() const
00270 {
00271 return mCategories;
00272 }
00273
00274 QString Incidence::categoriesStr() const
00275 {
00276 return mCategories.join(",");
00277 }
00278
00279 void Incidence::setRelatedToUid(const QString &relatedToUid)
00280 {
00281 if ( mReadOnly || mRelatedToUid == relatedToUid ) return;
00282 mRelatedToUid = relatedToUid;
00283 updated();
00284 }
00285
00286 QString Incidence::relatedToUid() const
00287 {
00288 return mRelatedToUid;
00289 }
00290
00291 void Incidence::setRelatedTo(Incidence *relatedTo)
00292 {
00293 if (mReadOnly || mRelatedTo == relatedTo) return;
00294 if(mRelatedTo)
00295 mRelatedTo->removeRelation(this);
00296 mRelatedTo = relatedTo;
00297 if (mRelatedTo) {
00298 mRelatedTo->addRelation(this);
00299 if ( mRelatedTo->uid() != mRelatedToUid )
00300 setRelatedToUid( mRelatedTo->uid() );
00301 } else {
00302 setRelatedToUid( QString::null );
00303 }
00304 }
00305
00306 Incidence *Incidence::relatedTo() const
00307 {
00308 return mRelatedTo;
00309 }
00310
00311 Incidence::List Incidence::relations() const
00312 {
00313 return mRelations;
00314 }
00315
00316 void Incidence::addRelation( Incidence *event )
00317 {
00318 if ( mRelations.find( event ) == mRelations.end() ) {
00319 mRelations.append( event );
00320 }
00321 }
00322
00323 void Incidence::removeRelation(Incidence *event)
00324 {
00325 mRelations.removeRef(event);
00326
00327 }
00328
00329
00330
00331
00332
00333 Recurrence *Incidence::recurrence() const
00334 {
00335 if (!mRecurrence)
00336 {
00337 const_cast<KCal::Incidence*>(this)->mRecurrence = new Recurrence();
00338 mRecurrence->setStartDateTime( IncidenceBase::dtStart() );
00339 mRecurrence->setFloats( doesFloat() );
00340 mRecurrence->setRecurReadOnly( mReadOnly );
00341 mRecurrence->addObserver( const_cast<KCal::Incidence*>(this) );
00342 }
00343
00344 return mRecurrence;
00345 }
00346
00347 void Incidence::clearRecurrence()
00348 {
00349 delete mRecurrence;
00350 mRecurrence = 0;
00351 }
00352
00353 uint Incidence::recurrenceType() const
00354 {
00355 if ( mRecurrence ) return mRecurrence->recurrenceType();
00356 else return Recurrence::rNone;
00357 }
00358
00359 bool Incidence::doesRecur() const
00360 {
00361 if ( mRecurrence ) return mRecurrence->doesRecur();
00362 else return false;
00363 }
00364
00365 bool Incidence::recursOn(const QDate &qd) const
00366 {
00367 return ( mRecurrence && mRecurrence->recursOn(qd) );
00368 }
00369
00370 bool Incidence::recursAt(const QDateTime &qdt) const
00371 {
00372 return ( mRecurrence && mRecurrence->recursAt(qdt) );
00373 }
00374
00383 QValueList<QDateTime> Incidence::startDateTimesForDate( const QDate &date ) const
00384 {
00385
00386 QDateTime start = dtStart();
00387 QDateTime end = endDateRecurrenceBase();
00388
00389 QValueList<QDateTime> result;
00390
00391
00392 if ( !start.isValid() && ! end.isValid() ) {
00393 return result;
00394 }
00395
00396
00397 if ( !doesRecur() ) {
00398 if ( !(start.date() > date || end.date() < date ) ) {
00399 result << start;
00400 }
00401 return result;
00402 }
00403
00404 int days = start.daysTo( end );
00405
00406 QDate tmpday( date.addDays( -days - 1 ) );
00407 QDateTime tmp;
00408 while ( tmpday <= date ) {
00409 if ( recurrence()->recursOn( tmpday ) ) {
00410 QValueList<QTime> times = recurrence()->recurTimesOn( tmpday );
00411 for ( QValueList<QTime>::ConstIterator it = times.begin(); it != times.end(); ++it ) {
00412 tmp = QDateTime( tmpday, *it );
00413 if ( endDateForStart( tmp ).date() >= date )
00414 result << tmp;
00415 }
00416 }
00417 tmpday = tmpday.addDays( 1 );
00418 }
00419 return result;
00420 }
00421
00430 QValueList<QDateTime> Incidence::startDateTimesForDateTime( const QDateTime &datetime ) const
00431 {
00432
00433 QDateTime start = dtStart();
00434 QDateTime end = endDateRecurrenceBase();
00435
00436 QValueList<QDateTime> result;
00437
00438
00439 if ( !start.isValid() && ! end.isValid() ) {
00440 return result;
00441 }
00442
00443
00444 if ( !doesRecur() ) {
00445 if ( !(start > datetime || end < datetime ) ) {
00446 result << start;
00447 }
00448 return result;
00449 }
00450
00451 int days = start.daysTo( end );
00452
00453 QDate tmpday( datetime.date().addDays( -days - 1 ) );
00454 QDateTime tmp;
00455 while ( tmpday <= datetime.date() ) {
00456 if ( recurrence()->recursOn( tmpday ) ) {
00457 QValueList<QTime> times = recurrence()->recurTimesOn( tmpday );
00458 for ( QValueList<QTime>::ConstIterator it = times.begin(); it != times.end(); ++it ) {
00459 tmp = QDateTime( tmpday, *it );
00460 if ( !(tmp > datetime || endDateForStart( tmp ) < datetime ) )
00461 result << tmp;
00462 }
00463 }
00464 tmpday = tmpday.addDays( 1 );
00465 }
00466 return result;
00467 }
00468
00470 QDateTime Incidence::endDateForStart( const QDateTime &startDt ) const
00471 {
00472 QDateTime start = dtStart();
00473 QDateTime end = endDateRecurrenceBase();
00474 if ( !end.isValid() ) return start;
00475 if ( !start.isValid() ) return end;
00476
00477 return startDt.addSecs( start.secsTo( end ) );
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 void Incidence::addAttachment(Attachment *attachment)
00572 {
00573 if (mReadOnly || !attachment) return;
00574 mAttachments.append(attachment);
00575 updated();
00576 }
00577
00578 void Incidence::deleteAttachment(Attachment *attachment)
00579 {
00580 mAttachments.removeRef(attachment);
00581 }
00582
00583 void Incidence::deleteAttachments( const QString &mime )
00584 {
00585 Attachment::List::Iterator it = mAttachments.begin();
00586 while( it != mAttachments.end() ) {
00587 if ( (*it)->mimeType() == mime ) mAttachments.remove( it );
00588 else ++it;
00589 }
00590 }
00591
00592 Attachment::List Incidence::attachments() const
00593 {
00594 return mAttachments;
00595 }
00596
00597 Attachment::List Incidence::attachments(const QString& mime) const
00598 {
00599 Attachment::List attachments;
00600 Attachment::List::ConstIterator it;
00601 for( it = mAttachments.begin(); it != mAttachments.end(); ++it ) {
00602 if ( (*it)->mimeType() == mime ) attachments.append( *it );
00603 }
00604
00605 return attachments;
00606 }
00607
00608 void Incidence::clearAttachments()
00609 {
00610 mAttachments.clear();
00611 }
00612
00613 void Incidence::setResources(const QStringList &resources)
00614 {
00615 if (mReadOnly) return;
00616 mResources = resources;
00617 updated();
00618 }
00619
00620 QStringList Incidence::resources() const
00621 {
00622 return mResources;
00623 }
00624
00625
00626 void Incidence::setPriority(int priority)
00627 {
00628 if (mReadOnly) return;
00629 mPriority = priority;
00630 updated();
00631 }
00632
00633 int Incidence::priority() const
00634 {
00635 return mPriority;
00636 }
00637
00638 void Incidence::setStatus(Incidence::Status status)
00639 {
00640 if (mReadOnly || status == StatusX) return;
00641 mStatus = status;
00642 mStatusString = QString::null;
00643 updated();
00644 }
00645
00646 void Incidence::setCustomStatus(const QString &status)
00647 {
00648 if (mReadOnly) return;
00649 mStatus = status.isEmpty() ? StatusNone : StatusX;
00650 mStatusString = status;
00651 updated();
00652 }
00653
00654 Incidence::Status Incidence::status() const
00655 {
00656 return mStatus;
00657 }
00658
00659 QString Incidence::statusStr() const
00660 {
00661 if (mStatus == StatusX)
00662 return mStatusString;
00663 return statusName(mStatus);
00664 }
00665
00666 QString Incidence::statusName(Incidence::Status status)
00667 {
00668 switch (status) {
00669 case StatusTentative: return i18n("incidence status", "Tentative");
00670 case StatusConfirmed: return i18n("Confirmed");
00671 case StatusCompleted: return i18n("Completed");
00672 case StatusNeedsAction: return i18n("Needs-Action");
00673 case StatusCanceled: return i18n("Canceled");
00674 case StatusInProcess: return i18n("In-Process");
00675 case StatusDraft: return i18n("Draft");
00676 case StatusFinal: return i18n("Final");
00677 case StatusX:
00678 case StatusNone:
00679 default: return QString::null;
00680 }
00681 }
00682
00683 void Incidence::setSecrecy(int sec)
00684 {
00685 if (mReadOnly) return;
00686 mSecrecy = sec;
00687 updated();
00688 }
00689
00690 int Incidence::secrecy() const
00691 {
00692 return mSecrecy;
00693 }
00694
00695 QString Incidence::secrecyStr() const
00696 {
00697 return secrecyName(mSecrecy);
00698 }
00699
00700 QString Incidence::secrecyName(int secrecy)
00701 {
00702 switch (secrecy) {
00703 case SecrecyPublic:
00704 return i18n("Public");
00705 case SecrecyPrivate:
00706 return i18n("Private");
00707 case SecrecyConfidential:
00708 return i18n("Confidential");
00709 default:
00710 return i18n("Undefined");
00711 }
00712 }
00713
00714 QStringList Incidence::secrecyList()
00715 {
00716 QStringList list;
00717 list << secrecyName(SecrecyPublic);
00718 list << secrecyName(SecrecyPrivate);
00719 list << secrecyName(SecrecyConfidential);
00720
00721 return list;
00722 }
00723
00724
00725 const Alarm::List &Incidence::alarms() const
00726 {
00727 return mAlarms;
00728 }
00729
00730 Alarm* Incidence::newAlarm()
00731 {
00732 Alarm* alarm = new Alarm(this);
00733 mAlarms.append(alarm);
00734
00735 return alarm;
00736 }
00737
00738 void Incidence::addAlarm(Alarm *alarm)
00739 {
00740 mAlarms.append(alarm);
00741 updated();
00742 }
00743
00744 void Incidence::removeAlarm(Alarm *alarm)
00745 {
00746 mAlarms.removeRef(alarm);
00747 updated();
00748 }
00749
00750 void Incidence::clearAlarms()
00751 {
00752 mAlarms.clear();
00753 updated();
00754 }
00755
00756 bool Incidence::isAlarmEnabled() const
00757 {
00758 Alarm::List::ConstIterator it;
00759 for( it = mAlarms.begin(); it != mAlarms.end(); ++it ) {
00760 if ( (*it)->enabled() ) return true;
00761 }
00762 return false;
00763 }
00764
00765 void Incidence::setLocation(const QString &location)
00766 {
00767 if (mReadOnly) return;
00768 mLocation = location;
00769 updated();
00770 }
00771
00772 QString Incidence::location() const
00773 {
00774 return mLocation;
00775 }
00776
00777 void Incidence::setSchedulingID( const QString& sid )
00778 {
00779 mSchedulingID = sid;
00780 }
00781
00782 QString Incidence::schedulingID() const
00783 {
00784 if ( mSchedulingID.isNull() )
00785
00786 return uid();
00787 return mSchedulingID;
00788 }
00789
00793 void Incidence::recurrenceUpdated( Recurrence *recurrence )
00794 {
00795 if ( recurrence == mRecurrence )
00796 updated();
00797 }
00798
|