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(0), 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 Incidence& Incidence::operator=( const Incidence &i )
00109 {
00110 IncidenceBase::operator=( i );
00111 mRevision = i.mRevision;
00112 mCreated = i.mCreated;
00113 mDescription = i.mDescription;
00114 mSummary = i.mSummary;
00115 mCategories = i.mCategories;
00116 mRelatedTo = 0;
00117 mRelatedToUid = i.mRelatedToUid;
00118 mRelations.clear();
00119 mResources = i.mResources;
00120 mStatusString = i.mStatusString;
00121 mStatus = i.mStatus;
00122 mSecrecy = i.mSecrecy;
00123 mPriority = i.mPriority;
00124 mLocation = i.mLocation;
00125
00126 mAlarms.clear();
00127 Alarm::List::ConstIterator it;
00128 for( it = i.mAlarms.begin(); it != i.mAlarms.end(); ++it ) {
00129 Alarm *b = new Alarm( **it );
00130 b->setParent( this );
00131 mAlarms.append( b );
00132 }
00133
00134 mAttachments.clear();
00135 Attachment::List::ConstIterator it1;
00136 for ( it1 = i.mAttachments.begin(); it1 != i.mAttachments.end(); ++it1 ) {
00137 Attachment *a = new Attachment( **it1 );
00138 mAttachments.append( a );
00139 }
00140
00141 delete mRecurrence;
00142 if (i.mRecurrence) {
00143 mRecurrence = new Recurrence( *(i.mRecurrence) );
00144 mRecurrence->addObserver( this );
00145 } else
00146 mRecurrence = 0;
00147
00148 mSchedulingID = i.mSchedulingID;
00149 return *this;
00150 }
00151
00152 bool Incidence::operator==( const Incidence& i2 ) const
00153 {
00154 if( alarms().count() != i2.alarms().count() ) {
00155 return false;
00156 }
00157
00158 Alarm::List::ConstIterator a1 = alarms().begin();
00159 Alarm::List::ConstIterator a2 = i2.alarms().begin();
00160 for( ; a1 != alarms().end() && a2 != i2.alarms().end(); ++a1, ++a2 )
00161 if( **a1 == **a2 )
00162 continue;
00163 else {
00164 return false;
00165 }
00166
00167 if ( !IncidenceBase::operator==(i2) )
00168 return false;
00169
00170 bool recurrenceEqual = ( mRecurrence == 0 && i2.mRecurrence == 0 );
00171 if ( !recurrenceEqual )
00172 {
00173 recurrenceEqual = mRecurrence != 0 &&
00174 i2.mRecurrence != 0 &&
00175 *mRecurrence == *i2.mRecurrence;
00176 }
00177
00178 return
00179 recurrenceEqual &&
00180 created() == i2.created() &&
00181 stringCompare( description(), i2.description() ) &&
00182 stringCompare( summary(), i2.summary() ) &&
00183 categories() == i2.categories() &&
00184
00185 stringCompare( relatedToUid(), i2.relatedToUid() ) &&
00186 relations() == i2.relations() &&
00187 attachments() == i2.attachments() &&
00188 resources() == i2.resources() &&
00189 mStatus == i2.mStatus &&
00190 ( mStatus == StatusNone || stringCompare( mStatusString, i2.mStatusString ) ) &&
00191 secrecy() == i2.secrecy() &&
00192 priority() == i2.priority() &&
00193 stringCompare( location(), i2.location() ) &&
00194 stringCompare( schedulingID(), i2.schedulingID() );
00195 }
00196
00197
00198 void Incidence::recreate()
00199 {
00200 setCreated(QDateTime::currentDateTime());
00201
00202 setUid(CalFormat::createUniqueId());
00203 setSchedulingID( QString::null );
00204
00205 setRevision(0);
00206
00207 setLastModified(QDateTime::currentDateTime());
00208 setPilotId( 0 );
00209 setSyncStatus( SYNCNONE );
00210 }
00211
00212 void Incidence::setReadOnly( bool readOnly )
00213 {
00214 IncidenceBase::setReadOnly( readOnly );
00215 if ( mRecurrence )
00216 mRecurrence->setRecurReadOnly( readOnly );
00217 }
00218
00219 void Incidence::setFloats(bool f)
00220 {
00221 if (mReadOnly) return;
00222 if ( recurrence() )
00223 recurrence()->setFloats( f );
00224 IncidenceBase::setFloats( f );
00225 }
00226
00227 void Incidence::setCreated( const QDateTime &created )
00228 {
00229 if (mReadOnly) return;
00230 mCreated = created;
00231
00232
00233
00234 }
00235
00236 QDateTime Incidence::created() const
00237 {
00238 return mCreated;
00239 }
00240
00241 void Incidence::setRevision( int rev )
00242 {
00243 if (mReadOnly) return;
00244 mRevision = rev;
00245
00246 updated();
00247 }
00248
00249 int Incidence::revision() const
00250 {
00251 return mRevision;
00252 }
00253
00254 void Incidence::setDtStart(const QDateTime &dtStart)
00255 {
00256 if ( mRecurrence ) {
00257 mRecurrence->setStartDateTime( dtStart );
00258 mRecurrence->setFloats( doesFloat() );
00259 }
00260 IncidenceBase::setDtStart( dtStart );
00261 }
00262
00263 void Incidence::setDescription(const QString &description)
00264 {
00265 if (mReadOnly) return;
00266 mDescription = description;
00267 updated();
00268 }
00269
00270 QString Incidence::description() const
00271 {
00272 return mDescription;
00273 }
00274
00275
00276 void Incidence::setSummary(const QString &summary)
00277 {
00278 if (mReadOnly) return;
00279 mSummary = summary;
00280 updated();
00281 }
00282
00283 QString Incidence::summary() const
00284 {
00285 return mSummary;
00286 }
00287
00288 void Incidence::setCategories(const QStringList &categories)
00289 {
00290 if (mReadOnly) return;
00291 mCategories = categories;
00292 updated();
00293 }
00294
00295
00296 void Incidence::setCategories(const QString &catStr)
00297 {
00298 if (mReadOnly) return;
00299 mCategories.clear();
00300
00301 if (catStr.isEmpty()) return;
00302
00303 mCategories = QStringList::split(",",catStr);
00304
00305 QStringList::Iterator it;
00306 for(it = mCategories.begin();it != mCategories.end(); ++it) {
00307 *it = (*it).stripWhiteSpace();
00308 }
00309
00310 updated();
00311 }
00312
00313 QStringList Incidence::categories() const
00314 {
00315 return mCategories;
00316 }
00317
00318 QString Incidence::categoriesStr() const
00319 {
00320 return mCategories.join(",");
00321 }
00322
00323 void Incidence::setRelatedToUid(const QString &relatedToUid)
00324 {
00325 if ( mReadOnly || mRelatedToUid == relatedToUid ) return;
00326 mRelatedToUid = relatedToUid;
00327 updated();
00328 }
00329
00330 QString Incidence::relatedToUid() const
00331 {
00332 return mRelatedToUid;
00333 }
00334
00335 void Incidence::setRelatedTo(Incidence *relatedTo)
00336 {
00337 if (mReadOnly || mRelatedTo == relatedTo) return;
00338 if(mRelatedTo)
00339 mRelatedTo->removeRelation(this);
00340 mRelatedTo = relatedTo;
00341 if (mRelatedTo) {
00342 mRelatedTo->addRelation(this);
00343 if ( mRelatedTo->uid() != mRelatedToUid )
00344 setRelatedToUid( mRelatedTo->uid() );
00345 } else {
00346 setRelatedToUid( QString::null );
00347 }
00348 }
00349
00350 Incidence *Incidence::relatedTo() const
00351 {
00352 return mRelatedTo;
00353 }
00354
00355 Incidence::List Incidence::relations() const
00356 {
00357 return mRelations;
00358 }
00359
00360 void Incidence::addRelation( Incidence *event )
00361 {
00362 if ( mRelations.find( event ) == mRelations.end() ) {
00363 mRelations.append( event );
00364 }
00365 }
00366
00367 void Incidence::removeRelation(Incidence *event)
00368
00369
00370 {
00371 mRelations.removeRef(event);
00372
00373 mRelatedToUid=QString();
00374 }
00375
00376
00377
00378
00379
00380 Recurrence *Incidence::recurrence() const
00381 {
00382 if (!mRecurrence)
00383 {
00384 const_cast<KCal::Incidence*>(this)->mRecurrence = new Recurrence();
00385 mRecurrence->setStartDateTime( IncidenceBase::dtStart() );
00386 mRecurrence->setFloats( doesFloat() );
00387 mRecurrence->setRecurReadOnly( mReadOnly );
00388 mRecurrence->addObserver( const_cast<KCal::Incidence*>(this) );
00389 }
00390
00391 return mRecurrence;
00392 }
00393
00394 void Incidence::clearRecurrence()
00395 {
00396 delete mRecurrence;
00397 mRecurrence = 0;
00398 }
00399
00400 uint Incidence::recurrenceType() const
00401 {
00402 if ( mRecurrence ) return mRecurrence->recurrenceType();
00403 else return Recurrence::rNone;
00404 }
00405
00406 bool Incidence::doesRecur() const
00407 {
00408 if ( mRecurrence ) return mRecurrence->doesRecur();
00409 else return false;
00410 }
00411
00412 bool Incidence::recursOn(const QDate &qd) const
00413 {
00414 return ( mRecurrence && mRecurrence->recursOn(qd) );
00415 }
00416
00417 bool Incidence::recursAt(const QDateTime &qdt) const
00418 {
00419 return ( mRecurrence && mRecurrence->recursAt(qdt) );
00420 }
00421
00430 QValueList<QDateTime> Incidence::startDateTimesForDate( const QDate &date ) 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.date() > date || end.date() < date ) ) {
00446 result << start;
00447 }
00448 return result;
00449 }
00450
00451 int days = start.daysTo( end );
00452
00453 QDate tmpday( date.addDays( -days - 1 ) );
00454 QDateTime tmp;
00455 while ( tmpday <= 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 ( endDateForStart( tmp ).date() >= date )
00461 result << tmp;
00462 }
00463 }
00464 tmpday = tmpday.addDays( 1 );
00465 }
00466 return result;
00467 }
00468
00477 QValueList<QDateTime> Incidence::startDateTimesForDateTime( const QDateTime &datetime ) const
00478 {
00479
00480 QDateTime start = dtStart();
00481 QDateTime end = endDateRecurrenceBase();
00482
00483 QValueList<QDateTime> result;
00484
00485
00486 if ( !start.isValid() && ! end.isValid() ) {
00487 return result;
00488 }
00489
00490
00491 if ( !doesRecur() ) {
00492 if ( !(start > datetime || end < datetime ) ) {
00493 result << start;
00494 }
00495 return result;
00496 }
00497
00498 int days = start.daysTo( end );
00499
00500 QDate tmpday( datetime.date().addDays( -days - 1 ) );
00501 QDateTime tmp;
00502 while ( tmpday <= datetime.date() ) {
00503 if ( recurrence()->recursOn( tmpday ) ) {
00504 QValueList<QTime> times = recurrence()->recurTimesOn( tmpday );
00505 for ( QValueList<QTime>::ConstIterator it = times.begin(); it != times.end(); ++it ) {
00506 tmp = QDateTime( tmpday, *it );
00507 if ( !(tmp > datetime || endDateForStart( tmp ) < datetime ) )
00508 result << tmp;
00509 }
00510 }
00511 tmpday = tmpday.addDays( 1 );
00512 }
00513 return result;
00514 }
00515
00517 QDateTime Incidence::endDateForStart( const QDateTime &startDt ) const
00518 {
00519 QDateTime start = dtStart();
00520 QDateTime end = endDateRecurrenceBase();
00521 if ( !end.isValid() ) return start;
00522 if ( !start.isValid() ) return end;
00523
00524 return startDt.addSecs( start.secsTo( end ) );
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
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 void Incidence::addAttachment(Attachment *attachment)
00619 {
00620 if (mReadOnly || !attachment) return;
00621 mAttachments.append(attachment);
00622 updated();
00623 }
00624
00625 void Incidence::deleteAttachment(Attachment *attachment)
00626 {
00627 mAttachments.removeRef(attachment);
00628 }
00629
00630 void Incidence::deleteAttachments( const QString &mime )
00631 {
00632 Attachment::List::Iterator it = mAttachments.begin();
00633 while( it != mAttachments.end() ) {
00634 if ( (*it)->mimeType() == mime ) mAttachments.remove( it );
00635 else ++it;
00636 }
00637 }
00638
00639 Attachment::List Incidence::attachments() const
00640 {
00641 return mAttachments;
00642 }
00643
00644 Attachment::List Incidence::attachments(const QString& mime) const
00645 {
00646 Attachment::List attachments;
00647 Attachment::List::ConstIterator it;
00648 for( it = mAttachments.begin(); it != mAttachments.end(); ++it ) {
00649 if ( (*it)->mimeType() == mime ) attachments.append( *it );
00650 }
00651
00652 return attachments;
00653 }
00654
00655 void Incidence::clearAttachments()
00656 {
00657 mAttachments.clear();
00658 }
00659
00660 void Incidence::setResources(const QStringList &resources)
00661 {
00662 if (mReadOnly) return;
00663 mResources = resources;
00664 updated();
00665 }
00666
00667 QStringList Incidence::resources() const
00668 {
00669 return mResources;
00670 }
00671
00672
00673 void Incidence::setPriority(int priority)
00674 {
00675 if (mReadOnly) return;
00676 mPriority = priority;
00677 updated();
00678 }
00679
00680 int Incidence::priority() const
00681 {
00682 return mPriority;
00683 }
00684
00685 void Incidence::setStatus(Incidence::Status status)
00686 {
00687 if (mReadOnly || status == StatusX) return;
00688 mStatus = status;
00689 mStatusString = QString::null;
00690 updated();
00691 }
00692
00693 void Incidence::setCustomStatus(const QString &status)
00694 {
00695 if (mReadOnly) return;
00696 mStatus = status.isEmpty() ? StatusNone : StatusX;
00697 mStatusString = status;
00698 updated();
00699 }
00700
00701 Incidence::Status Incidence::status() const
00702 {
00703 return mStatus;
00704 }
00705
00706 QString Incidence::statusStr() const
00707 {
00708 if (mStatus == StatusX)
00709 return mStatusString;
00710 return statusName(mStatus);
00711 }
00712
00713 QString Incidence::statusName(Incidence::Status status)
00714 {
00715 switch (status) {
00716 case StatusTentative: return i18n("incidence status", "Tentative");
00717 case StatusConfirmed: return i18n("Confirmed");
00718 case StatusCompleted: return i18n("Completed");
00719 case StatusNeedsAction: return i18n("Needs-Action");
00720 case StatusCanceled: return i18n("Canceled");
00721 case StatusInProcess: return i18n("In-Process");
00722 case StatusDraft: return i18n("Draft");
00723 case StatusFinal: return i18n("Final");
00724 case StatusX:
00725 case StatusNone:
00726 default: return QString::null;
00727 }
00728 }
00729
00730 void Incidence::setSecrecy(int sec)
00731 {
00732 if (mReadOnly) return;
00733 mSecrecy = sec;
00734 updated();
00735 }
00736
00737 int Incidence::secrecy() const
00738 {
00739 return mSecrecy;
00740 }
00741
00742 QString Incidence::secrecyStr() const
00743 {
00744 return secrecyName(mSecrecy);
00745 }
00746
00747 QString Incidence::secrecyName(int secrecy)
00748 {
00749 switch (secrecy) {
00750 case SecrecyPublic:
00751 return i18n("Public");
00752 case SecrecyPrivate:
00753 return i18n("Private");
00754 case SecrecyConfidential:
00755 return i18n("Confidential");
00756 default:
00757 return i18n("Undefined");
00758 }
00759 }
00760
00761 QStringList Incidence::secrecyList()
00762 {
00763 QStringList list;
00764 list << secrecyName(SecrecyPublic);
00765 list << secrecyName(SecrecyPrivate);
00766 list << secrecyName(SecrecyConfidential);
00767
00768 return list;
00769 }
00770
00771
00772 const Alarm::List &Incidence::alarms() const
00773 {
00774 return mAlarms;
00775 }
00776
00777 Alarm* Incidence::newAlarm()
00778 {
00779 Alarm* alarm = new Alarm(this);
00780 mAlarms.append(alarm);
00781
00782 return alarm;
00783 }
00784
00785 void Incidence::addAlarm(Alarm *alarm)
00786 {
00787 mAlarms.append(alarm);
00788 updated();
00789 }
00790
00791 void Incidence::removeAlarm(Alarm *alarm)
00792 {
00793 mAlarms.removeRef(alarm);
00794 updated();
00795 }
00796
00797 void Incidence::clearAlarms()
00798 {
00799 mAlarms.clear();
00800 updated();
00801 }
00802
00803 bool Incidence::isAlarmEnabled() const
00804 {
00805 Alarm::List::ConstIterator it;
00806 for( it = mAlarms.begin(); it != mAlarms.end(); ++it ) {
00807 if ( (*it)->enabled() ) return true;
00808 }
00809 return false;
00810 }
00811
00812 void Incidence::setLocation(const QString &location)
00813 {
00814 if (mReadOnly) return;
00815 mLocation = location;
00816 updated();
00817 }
00818
00819 QString Incidence::location() const
00820 {
00821 return mLocation;
00822 }
00823
00824 void Incidence::setSchedulingID( const QString& sid )
00825 {
00826 mSchedulingID = sid;
00827 }
00828
00829 QString Incidence::schedulingID() const
00830 {
00831 if ( mSchedulingID.isNull() )
00832
00833 return uid();
00834 return mSchedulingID;
00835 }
00836
00840 void Incidence::recurrenceUpdated( Recurrence *recurrence )
00841 {
00842 if ( recurrence == mRecurrence )
00843 updated();
00844 }
00845
|