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