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 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
00326 {
00327 mRelations.removeRef(event);
00328
00329 mRelatedToUid=QString();
00330 }
00331
00332
00333
00334
00335
00336 Recurrence *Incidence::recurrence() const
00337 {
00338 if (!mRecurrence)
00339 {
00340 const_cast<KCal::Incidence*>(this)->mRecurrence = new Recurrence();
00341 mRecurrence->setStartDateTime( IncidenceBase::dtStart() );
00342 mRecurrence->setFloats( doesFloat() );
00343 mRecurrence->setRecurReadOnly( mReadOnly );
00344 mRecurrence->addObserver( const_cast<KCal::Incidence*>(this) );
00345 }
00346
00347 return mRecurrence;
00348 }
00349
00350 void Incidence::clearRecurrence()
00351 {
00352 delete mRecurrence;
00353 mRecurrence = 0;
00354 }
00355
00356 uint Incidence::recurrenceType() const
00357 {
00358 if ( mRecurrence ) return mRecurrence->recurrenceType();
00359 else return Recurrence::rNone;
00360 }
00361
00362 bool Incidence::doesRecur() const
00363 {
00364 if ( mRecurrence ) return mRecurrence->doesRecur();
00365 else return false;
00366 }
00367
00368 bool Incidence::recursOn(const QDate &qd) const
00369 {
00370 return ( mRecurrence && mRecurrence->recursOn(qd) );
00371 }
00372
00373 bool Incidence::recursAt(const QDateTime &qdt) const
00374 {
00375 return ( mRecurrence && mRecurrence->recursAt(qdt) );
00376 }
00377
00386 QValueList<QDateTime> Incidence::startDateTimesForDate( const QDate &date ) const
00387 {
00388
00389 QDateTime start = dtStart();
00390 QDateTime end = endDateRecurrenceBase();
00391
00392 QValueList<QDateTime> result;
00393
00394
00395 if ( !start.isValid() && ! end.isValid() ) {
00396 return result;
00397 }
00398
00399
00400 if ( !doesRecur() ) {
00401 if ( !(start.date() > date || end.date() < date ) ) {
00402 result << start;
00403 }
00404 return result;
00405 }
00406
00407 int days = start.daysTo( end );
00408
00409 QDate tmpday( date.addDays( -days - 1 ) );
00410 QDateTime tmp;
00411 while ( tmpday <= date ) {
00412 if ( recurrence()->recursOn( tmpday ) ) {
00413 QValueList<QTime> times = recurrence()->recurTimesOn( tmpday );
00414 for ( QValueList<QTime>::ConstIterator it = times.begin(); it != times.end(); ++it ) {
00415 tmp = QDateTime( tmpday, *it );
00416 if ( endDateForStart( tmp ).date() >= date )
00417 result << tmp;
00418 }
00419 }
00420 tmpday = tmpday.addDays( 1 );
00421 }
00422 return result;
00423 }
00424
00433 QValueList<QDateTime> Incidence::startDateTimesForDateTime( const QDateTime &datetime ) const
00434 {
00435
00436 QDateTime start = dtStart();
00437 QDateTime end = endDateRecurrenceBase();
00438
00439 QValueList<QDateTime> result;
00440
00441
00442 if ( !start.isValid() && ! end.isValid() ) {
00443 return result;
00444 }
00445
00446
00447 if ( !doesRecur() ) {
00448 if ( !(start > datetime || end < datetime ) ) {
00449 result << start;
00450 }
00451 return result;
00452 }
00453
00454 int days = start.daysTo( end );
00455
00456 QDate tmpday( datetime.date().addDays( -days - 1 ) );
00457 QDateTime tmp;
00458 while ( tmpday <= datetime.date() ) {
00459 if ( recurrence()->recursOn( tmpday ) ) {
00460 QValueList<QTime> times = recurrence()->recurTimesOn( tmpday );
00461 for ( QValueList<QTime>::ConstIterator it = times.begin(); it != times.end(); ++it ) {
00462 tmp = QDateTime( tmpday, *it );
00463 if ( !(tmp > datetime || endDateForStart( tmp ) < datetime ) )
00464 result << tmp;
00465 }
00466 }
00467 tmpday = tmpday.addDays( 1 );
00468 }
00469 return result;
00470 }
00471
00473 QDateTime Incidence::endDateForStart( const QDateTime &startDt ) const
00474 {
00475 QDateTime start = dtStart();
00476 QDateTime end = endDateRecurrenceBase();
00477 if ( !end.isValid() ) return start;
00478 if ( !start.isValid() ) return end;
00479
00480 return startDt.addSecs( start.secsTo( end ) );
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
00572
00573
00574 void Incidence::addAttachment(Attachment *attachment)
00575 {
00576 if (mReadOnly || !attachment) return;
00577 mAttachments.append(attachment);
00578 updated();
00579 }
00580
00581 void Incidence::deleteAttachment(Attachment *attachment)
00582 {
00583 mAttachments.removeRef(attachment);
00584 }
00585
00586 void Incidence::deleteAttachments( const QString &mime )
00587 {
00588 Attachment::List::Iterator it = mAttachments.begin();
00589 while( it != mAttachments.end() ) {
00590 if ( (*it)->mimeType() == mime ) mAttachments.remove( it );
00591 else ++it;
00592 }
00593 }
00594
00595 Attachment::List Incidence::attachments() const
00596 {
00597 return mAttachments;
00598 }
00599
00600 Attachment::List Incidence::attachments(const QString& mime) const
00601 {
00602 Attachment::List attachments;
00603 Attachment::List::ConstIterator it;
00604 for( it = mAttachments.begin(); it != mAttachments.end(); ++it ) {
00605 if ( (*it)->mimeType() == mime ) attachments.append( *it );
00606 }
00607
00608 return attachments;
00609 }
00610
00611 void Incidence::clearAttachments()
00612 {
00613 mAttachments.clear();
00614 }
00615
00616 void Incidence::setResources(const QStringList &resources)
00617 {
00618 if (mReadOnly) return;
00619 mResources = resources;
00620 updated();
00621 }
00622
00623 QStringList Incidence::resources() const
00624 {
00625 return mResources;
00626 }
00627
00628
00629 void Incidence::setPriority(int priority)
00630 {
00631 if (mReadOnly) return;
00632 mPriority = priority;
00633 updated();
00634 }
00635
00636 int Incidence::priority() const
00637 {
00638 return mPriority;
00639 }
00640
00641 void Incidence::setStatus(Incidence::Status status)
00642 {
00643 if (mReadOnly || status == StatusX) return;
00644 mStatus = status;
00645 mStatusString = QString::null;
00646 updated();
00647 }
00648
00649 void Incidence::setCustomStatus(const QString &status)
00650 {
00651 if (mReadOnly) return;
00652 mStatus = status.isEmpty() ? StatusNone : StatusX;
00653 mStatusString = status;
00654 updated();
00655 }
00656
00657 Incidence::Status Incidence::status() const
00658 {
00659 return mStatus;
00660 }
00661
00662 QString Incidence::statusStr() const
00663 {
00664 if (mStatus == StatusX)
00665 return mStatusString;
00666 return statusName(mStatus);
00667 }
00668
00669 QString Incidence::statusName(Incidence::Status status)
00670 {
00671 switch (status) {
00672 case StatusTentative: return i18n("incidence status", "Tentative");
00673 case StatusConfirmed: return i18n("Confirmed");
00674 case StatusCompleted: return i18n("Completed");
00675 case StatusNeedsAction: return i18n("Needs-Action");
00676 case StatusCanceled: return i18n("Canceled");
00677 case StatusInProcess: return i18n("In-Process");
00678 case StatusDraft: return i18n("Draft");
00679 case StatusFinal: return i18n("Final");
00680 case StatusX:
00681 case StatusNone:
00682 default: return QString::null;
00683 }
00684 }
00685
00686 void Incidence::setSecrecy(int sec)
00687 {
00688 if (mReadOnly) return;
00689 mSecrecy = sec;
00690 updated();
00691 }
00692
00693 int Incidence::secrecy() const
00694 {
00695 return mSecrecy;
00696 }
00697
00698 QString Incidence::secrecyStr() const
00699 {
00700 return secrecyName(mSecrecy);
00701 }
00702
00703 QString Incidence::secrecyName(int secrecy)
00704 {
00705 switch (secrecy) {
00706 case SecrecyPublic:
00707 return i18n("Public");
00708 case SecrecyPrivate:
00709 return i18n("Private");
00710 case SecrecyConfidential:
00711 return i18n("Confidential");
00712 default:
00713 return i18n("Undefined");
00714 }
00715 }
00716
00717 QStringList Incidence::secrecyList()
00718 {
00719 QStringList list;
00720 list << secrecyName(SecrecyPublic);
00721 list << secrecyName(SecrecyPrivate);
00722 list << secrecyName(SecrecyConfidential);
00723
00724 return list;
00725 }
00726
00727
00728 const Alarm::List &Incidence::alarms() const
00729 {
00730 return mAlarms;
00731 }
00732
00733 Alarm* Incidence::newAlarm()
00734 {
00735 Alarm* alarm = new Alarm(this);
00736 mAlarms.append(alarm);
00737
00738 return alarm;
00739 }
00740
00741 void Incidence::addAlarm(Alarm *alarm)
00742 {
00743 mAlarms.append(alarm);
00744 updated();
00745 }
00746
00747 void Incidence::removeAlarm(Alarm *alarm)
00748 {
00749 mAlarms.removeRef(alarm);
00750 updated();
00751 }
00752
00753 void Incidence::clearAlarms()
00754 {
00755 mAlarms.clear();
00756 updated();
00757 }
00758
00759 bool Incidence::isAlarmEnabled() const
00760 {
00761 Alarm::List::ConstIterator it;
00762 for( it = mAlarms.begin(); it != mAlarms.end(); ++it ) {
00763 if ( (*it)->enabled() ) return true;
00764 }
00765 return false;
00766 }
00767
00768 void Incidence::setLocation(const QString &location)
00769 {
00770 if (mReadOnly) return;
00771 mLocation = location;
00772 updated();
00773 }
00774
00775 QString Incidence::location() const
00776 {
00777 return mLocation;
00778 }
00779
00780 void Incidence::setSchedulingID( const QString& sid )
00781 {
00782 mSchedulingID = sid;
00783 }
00784
00785 QString Incidence::schedulingID() const
00786 {
00787 if ( mSchedulingID.isNull() )
00788
00789 return uid();
00790 return mSchedulingID;
00791 }
00792
00796 void Incidence::recurrenceUpdated( Recurrence *recurrence )
00797 {
00798 if ( recurrence == mRecurrence )
00799 updated();
00800 }
00801
|