00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00035 #include "incidence.h"
00036 #include "calformat.h"
00037
00038 #include "kpimutils/kfileio.h"
00039
00040 #include <kglobal.h>
00041 #include <klocale.h>
00042 #include <kdebug.h>
00043 #include <ktemporaryfile.h>
00044 #include <kde_file.h>
00045
00046 #include <QtCore/QList>
00047 #include <QtGui/QTextDocument>
00048 #include <KMimeType>
00049
00050 using namespace KCal;
00051
00056
00057 class KCal::Incidence::Private
00058 {
00059 public:
00060 Private()
00061 : mDescriptionIsRich( false ),
00062 mSummaryIsRich( false ),
00063 mLocationIsRich( false ),
00064 mRecurrence( 0 ),
00065 mStatus( StatusNone ),
00066 mSecrecy( SecrecyPublic ),
00067 mPriority( 0 ),
00068 mRelatedTo( 0 ),
00069 mGeoLatitude( 0 ),
00070 mGeoLongitude( 0 ),
00071 mHasGeo( false )
00072 {
00073 mAlarms.setAutoDelete( true );
00074 mAttachments.setAutoDelete( true );
00075 }
00076
00077 Private( const Private &p )
00078 : mCreated( p.mCreated ),
00079 mRevision( p.mRevision ),
00080 mDescription( p.mDescription ),
00081 mDescriptionIsRich( p.mDescriptionIsRich ),
00082 mSummary( p.mSummary ),
00083 mSummaryIsRich( p.mSummaryIsRich ),
00084 mLocation( p.mLocation ),
00085 mLocationIsRich( p.mLocationIsRich ),
00086 mCategories( p.mCategories ),
00087 mRecurrence( p.mRecurrence ),
00088 mResources( p.mResources ),
00089 mStatus( p.mStatus ),
00090 mStatusString( p.mStatusString ),
00091 mSecrecy( p.mSecrecy ),
00092 mPriority( p.mPriority ),
00093 mSchedulingID( p.mSchedulingID ),
00094 mRelatedTo( p.mRelatedTo ),
00095 mRelatedToUid( p.mRelatedToUid ),
00096 mGeoLatitude( p.mGeoLatitude ),
00097 mGeoLongitude( p.mGeoLongitude ),
00098 mHasGeo( p.mHasGeo )
00099 {
00100 mAlarms.setAutoDelete( true );
00101 mAttachments.setAutoDelete( true );
00102 }
00103
00104 void clear()
00105 {
00106 mAlarms.clearAll();
00107 mAttachments.clearAll();
00108 delete mRecurrence;
00109 }
00110
00111 KDateTime mCreated;
00112 int mRevision;
00113
00114 QString mDescription;
00115 bool mDescriptionIsRich;
00116 QString mSummary;
00117 bool mSummaryIsRich;
00118 QString mLocation;
00119 bool mLocationIsRich;
00120 QStringList mCategories;
00121 mutable Recurrence *mRecurrence;
00122 Attachment::List mAttachments;
00123 Alarm::List mAlarms;
00124 QStringList mResources;
00125 Status mStatus;
00126 QString mStatusString;
00127 Secrecy mSecrecy;
00128 int mPriority;
00129 QString mSchedulingID;
00130
00131 Incidence *mRelatedTo;
00132 QString mRelatedToUid;
00133 Incidence::List mRelations;
00134 float mGeoLatitude;
00135 float mGeoLongitude;
00136 bool mHasGeo;
00137 QHash<Attachment *, QString> mTempFiles;
00138 };
00139
00140
00141 Incidence::Incidence()
00142 : IncidenceBase(), d( new KCal::Incidence::Private )
00143 {
00144 recreate();
00145 }
00146
00147 Incidence::Incidence( const Incidence &i )
00148 : IncidenceBase( i ),
00149 Recurrence::RecurrenceObserver(),
00150 d( new KCal::Incidence::Private( *i.d ) )
00151 {
00152 init( i );
00153 }
00154
00155 void Incidence::init( const Incidence &i )
00156 {
00157 d->mRevision = i.d->mRevision;
00158 d->mCreated = i.d->mCreated;
00159 d->mDescription = i.d->mDescription;
00160 d->mSummary = i.d->mSummary;
00161 d->mCategories = i.d->mCategories;
00162 d->mRelatedTo = i.d->mRelatedTo;
00163 d->mRelatedToUid = i.d->mRelatedToUid;
00164 d->mRelations = i.d->mRelations;
00165 d->mResources = i.d->mResources;
00166 d->mStatusString = i.d->mStatusString;
00167 d->mStatus = i.d->mStatus;
00168 d->mSecrecy = i.d->mSecrecy;
00169 d->mPriority = i.d->mPriority;
00170 d->mLocation = i.d->mLocation;
00171 d->mGeoLatitude = i.d->mGeoLatitude;
00172 d->mGeoLongitude = i.d->mGeoLongitude;
00173 d->mHasGeo = i.d->mHasGeo;
00174
00175
00176
00177
00178 foreach ( Alarm *alarm, i.d->mAlarms ) {
00179 Alarm *b = new Alarm( *alarm );
00180 b->setParent( this );
00181 d->mAlarms.append( b );
00182 }
00183
00184 foreach ( Attachment *attachment, i.d->mAttachments ) {
00185 Attachment *a = new Attachment( *attachment );
00186 d->mAttachments.append( a );
00187 }
00188
00189 if ( i.d->mRecurrence ) {
00190 d->mRecurrence = new Recurrence( *( i.d->mRecurrence ) );
00191 d->mRecurrence->addObserver( this );
00192 } else {
00193 d->mRecurrence = 0;
00194 }
00195 }
00196
00197 Incidence::~Incidence()
00198 {
00199 Incidence::List relations = d->mRelations;
00200 foreach ( Incidence *incidence, relations ) {
00201 if ( incidence->relatedTo() == this ) {
00202 incidence->setRelatedTo( 0 );
00203 }
00204 }
00205
00206 if ( relatedTo() ) {
00207 relatedTo()->removeRelation( this );
00208 }
00209 delete d->mRecurrence;
00210 delete d;
00211 }
00212
00213
00214
00215 static bool stringCompare( const QString &s1, const QString &s2 )
00216 {
00217 return ( s1.isEmpty() && s2.isEmpty() ) || ( s1 == s2 );
00218 }
00219
00220
00221 Incidence &Incidence::operator=( const Incidence &other )
00222 {
00223
00224 if ( &other == this ) {
00225 return *this;
00226 }
00227
00228 d->clear();
00229
00230 IncidenceBase::operator=( other );
00231 init( other );
00232 return *this;
00233 }
00234
00235 bool Incidence::operator==( const Incidence &i2 ) const
00236 {
00237 if ( alarms().count() != i2.alarms().count() ) {
00238 return false;
00239 }
00240
00241 Alarm::List::ConstIterator a1 = alarms().constBegin();
00242 Alarm::List::ConstIterator a1end = alarms().constEnd();
00243 Alarm::List::ConstIterator a2 = i2.alarms().begin();
00244 Alarm::List::ConstIterator a2end = i2.alarms().constEnd();
00245 for ( ; a1 != a1end && a2 != a2end; ++a1, ++a2 ) {
00246 if ( **a1 == **a2 ) {
00247 continue;
00248 } else {
00249 return false;
00250 }
00251 }
00252
00253 if ( !IncidenceBase::operator==( i2 ) ) {
00254 return false;
00255 }
00256
00257 bool recurrenceEqual = ( d->mRecurrence == 0 && i2.d->mRecurrence == 0 );
00258 if ( !recurrenceEqual ) {
00259 recurrenceEqual = d->mRecurrence != 0 &&
00260 i2.d->mRecurrence != 0 &&
00261 *d->mRecurrence == *i2.d->mRecurrence;
00262 }
00263
00264 return
00265 recurrenceEqual &&
00266 created() == i2.created() &&
00267 stringCompare( description(), i2.description() ) &&
00268 stringCompare( summary(), i2.summary() ) &&
00269 categories() == i2.categories() &&
00270
00271 stringCompare( relatedToUid(), i2.relatedToUid() ) &&
00272 relations() == i2.relations() &&
00273 attachments() == i2.attachments() &&
00274 resources() == i2.resources() &&
00275 d->mStatus == i2.d->mStatus &&
00276 ( d->mStatus == StatusNone ||
00277 stringCompare( d->mStatusString, i2.d->mStatusString ) ) &&
00278 secrecy() == i2.secrecy() &&
00279 priority() == i2.priority() &&
00280 stringCompare( location(), i2.location() ) &&
00281 stringCompare( schedulingID(), i2.schedulingID() );
00282 }
00283
00284 void Incidence::recreate()
00285 {
00286 KDateTime nowUTC = KDateTime::currentUtcDateTime();
00287 setCreated( nowUTC );
00288
00289 setUid( CalFormat::createUniqueId() );
00290 setSchedulingID( QString() );
00291
00292 setRevision( 0 );
00293
00294 setLastModified( nowUTC );
00295 }
00296
00297 void Incidence::setReadOnly( bool readOnly )
00298 {
00299 IncidenceBase::setReadOnly( readOnly );
00300 if ( d->mRecurrence ) {
00301 d->mRecurrence->setRecurReadOnly( readOnly );
00302 }
00303 }
00304
00305 void Incidence::setAllDay( bool allDay )
00306 {
00307 if ( mReadOnly ) {
00308 return;
00309 }
00310 if ( recurrence() ) {
00311 recurrence()->setAllDay( allDay );
00312 }
00313 IncidenceBase::setAllDay( allDay );
00314 }
00315
00316 void Incidence::setCreated( const KDateTime &created )
00317 {
00318 if ( mReadOnly ) {
00319 return;
00320 }
00321
00322 d->mCreated = created.toUtc();
00323
00324
00325
00326 }
00327
00328 KDateTime Incidence::created() const
00329 {
00330 return d->mCreated;
00331 }
00332
00333 void Incidence::setRevision( int rev )
00334 {
00335 if ( mReadOnly ) {
00336 return;
00337 }
00338
00339 d->mRevision = rev;
00340
00341 updated();
00342 }
00343
00344 int Incidence::revision() const
00345 {
00346 return d->mRevision;
00347 }
00348
00349 void Incidence::setDtStart( const KDateTime &dt )
00350 {
00351 if ( d->mRecurrence ) {
00352 d->mRecurrence->setStartDateTime( dt );
00353 d->mRecurrence->setAllDay( allDay() );
00354 }
00355 IncidenceBase::setDtStart( dt );
00356 }
00357
00358 KDateTime Incidence::dtEnd() const
00359 {
00360 return KDateTime();
00361 }
00362
00363 void Incidence::shiftTimes( const KDateTime::Spec &oldSpec,
00364 const KDateTime::Spec &newSpec )
00365 {
00366 IncidenceBase::shiftTimes( oldSpec, newSpec );
00367 if ( d->mRecurrence ) {
00368 d->mRecurrence->shiftTimes( oldSpec, newSpec );
00369 }
00370 for ( int i = 0, end = d->mAlarms.count(); i < end; ++i ) {
00371 d->mAlarms[i]->shiftTimes( oldSpec, newSpec );
00372 }
00373 }
00374
00375 void Incidence::setDescription( const QString &description, bool isRich )
00376 {
00377 if ( mReadOnly ) {
00378 return;
00379 }
00380 d->mDescription = description;
00381 d->mDescriptionIsRich = isRich;
00382 updated();
00383 }
00384
00385 void Incidence::setDescription( const QString &description )
00386 {
00387 setDescription( description, Qt::mightBeRichText( description ) );
00388 }
00389
00390 QString Incidence::description() const
00391 {
00392 return d->mDescription;
00393 }
00394
00395 QString Incidence::richDescription() const
00396 {
00397 if ( descriptionIsRich() ) {
00398 return d->mDescription;
00399 } else {
00400 return Qt::escape( d->mDescription ).replace( '\n', "<br/>" );
00401 }
00402 }
00403
00404 bool Incidence::descriptionIsRich() const
00405 {
00406 return d->mDescriptionIsRich;
00407 }
00408
00409 void Incidence::setSummary( const QString &summary, bool isRich )
00410 {
00411 if ( mReadOnly ) {
00412 return;
00413 }
00414 d->mSummary = summary;
00415 d->mSummaryIsRich = isRich;
00416 updated();
00417 }
00418
00419 void Incidence::setSummary( const QString &summary )
00420 {
00421 setSummary( summary, Qt::mightBeRichText( summary ) );
00422 }
00423
00424 QString Incidence::summary() const
00425 {
00426 return d->mSummary;
00427 }
00428
00429 QString Incidence::richSummary() const
00430 {
00431 if ( summaryIsRich() ) {
00432 return d->mSummary;
00433 } else {
00434 return Qt::escape( d->mSummary ).replace( '\n', "<br/>" );
00435 }
00436 }
00437
00438 bool Incidence::summaryIsRich() const
00439 {
00440 return d->mSummaryIsRich;
00441 }
00442
00443 void Incidence::setCategories( const QStringList &categories )
00444 {
00445 if ( mReadOnly ) {
00446 return;
00447 }
00448 d->mCategories = categories;
00449 updated();
00450 }
00451
00452 void Incidence::setCategories( const QString &catStr )
00453 {
00454 if ( mReadOnly ) {
00455 return;
00456 }
00457 d->mCategories.clear();
00458
00459 if ( catStr.isEmpty() ) {
00460 return;
00461 }
00462
00463 d->mCategories = catStr.split( ',' );
00464
00465 QStringList::Iterator it;
00466 for ( it = d->mCategories.begin();it != d->mCategories.end(); ++it ) {
00467 *it = (*it).trimmed();
00468 }
00469
00470 updated();
00471 }
00472
00473 QStringList Incidence::categories() const
00474 {
00475 return d->mCategories;
00476 }
00477
00478 QString Incidence::categoriesStr() const
00479 {
00480 return d->mCategories.join( "," );
00481 }
00482
00483 void Incidence::setRelatedToUid( const QString &relatedToUid )
00484 {
00485 if ( d->mRelatedToUid == relatedToUid ) {
00486 return;
00487 }
00488 d->mRelatedToUid = relatedToUid;
00489 updated();
00490 }
00491
00492 QString Incidence::relatedToUid() const
00493 {
00494 return d->mRelatedToUid;
00495 }
00496
00497 void Incidence::setRelatedTo( Incidence *incidence )
00498 {
00499 if ( d->mRelatedTo == incidence ) {
00500 return;
00501 }
00502 if ( d->mRelatedTo ) {
00503 d->mRelatedTo->removeRelation( this );
00504 }
00505 d->mRelatedTo = incidence;
00506 if ( d->mRelatedTo ) {
00507 d->mRelatedTo->addRelation( this );
00508 if ( d->mRelatedTo->uid() != d->mRelatedToUid ) {
00509 setRelatedToUid( d->mRelatedTo->uid() );
00510 }
00511 } else {
00512 setRelatedToUid( QString() );
00513 }
00514 }
00515
00516 Incidence *Incidence::relatedTo() const
00517 {
00518 return d->mRelatedTo;
00519 }
00520
00521 Incidence::List Incidence::relations() const
00522 {
00523 return d->mRelations;
00524 }
00525
00526 void Incidence::addRelation( Incidence *incidence )
00527 {
00528 if ( !d->mRelations.contains( incidence ) ) {
00529 d->mRelations.append( incidence );
00530 }
00531 }
00532
00533 void Incidence::removeRelation( Incidence *incidence )
00534 {
00535 d->mRelations.removeRef( incidence );
00536 if ( d->mRelatedToUid == incidence->uid() ) {
00537 d->mRelatedToUid.clear();
00538 }
00539
00540 }
00541
00542
00543
00544 Recurrence *Incidence::recurrence() const
00545 {
00546 if ( !d->mRecurrence ) {
00547 d->mRecurrence = new Recurrence();
00548 d->mRecurrence->setStartDateTime( IncidenceBase::dtStart() );
00549 d->mRecurrence->setAllDay( allDay() );
00550 d->mRecurrence->setRecurReadOnly( mReadOnly );
00551 d->mRecurrence->addObserver( const_cast<KCal::Incidence*>( this ) );
00552 }
00553
00554 return d->mRecurrence;
00555 }
00556
00557 void Incidence::clearRecurrence()
00558 {
00559 delete d->mRecurrence;
00560 d->mRecurrence = 0;
00561 }
00562
00563 ushort Incidence::recurrenceType() const
00564 {
00565 if ( d->mRecurrence ) {
00566 return d->mRecurrence->recurrenceType();
00567 } else {
00568 return Recurrence::rNone;
00569 }
00570 }
00571
00572 bool Incidence::recurs() const
00573 {
00574 if ( d->mRecurrence ) {
00575 return d->mRecurrence->recurs();
00576 } else {
00577 return false;
00578 }
00579 }
00580
00581 bool Incidence::recursOn( const QDate &date,
00582 const KDateTime::Spec &timeSpec ) const
00583 {
00584 return d->mRecurrence && d->mRecurrence->recursOn( date, timeSpec );
00585 }
00586
00587 bool Incidence::recursAt( const KDateTime &qdt ) const
00588 {
00589 return d->mRecurrence && d->mRecurrence->recursAt( qdt );
00590 }
00591
00592 QList<KDateTime> Incidence::startDateTimesForDate( const QDate &date,
00593 const KDateTime::Spec &timeSpec ) const
00594 {
00595 KDateTime start = dtStart();
00596 KDateTime end = endDateRecurrenceBase();
00597
00598 QList<KDateTime> result;
00599
00600
00601 if ( !start.isValid() && ! end.isValid() ) {
00602 return result;
00603 }
00604
00605
00606 KDateTime kdate( date, timeSpec );
00607 if ( !recurs() ) {
00608 if ( !( start > kdate || end < kdate ) ) {
00609 result << start;
00610 }
00611 return result;
00612 }
00613
00614 int days = start.daysTo( end );
00615
00616 QDate tmpday( date.addDays( -days - 1 ) );
00617 KDateTime tmp;
00618 while ( tmpday <= date ) {
00619 if ( recurrence()->recursOn( tmpday, timeSpec ) ) {
00620 QList<QTime> times = recurrence()->recurTimesOn( tmpday, timeSpec );
00621 foreach ( const QTime &time, times ) {
00622 tmp = KDateTime( tmpday, time, start.timeSpec() );
00623 if ( endDateForStart( tmp ) >= kdate ) {
00624 result << tmp;
00625 }
00626 }
00627 }
00628 tmpday = tmpday.addDays( 1 );
00629 }
00630 return result;
00631 }
00632
00633 QList<KDateTime> Incidence::startDateTimesForDateTime( const KDateTime &datetime ) const
00634 {
00635 KDateTime start = dtStart();
00636 KDateTime end = endDateRecurrenceBase();
00637
00638 QList<KDateTime> result;
00639
00640
00641 if ( !start.isValid() && ! end.isValid() ) {
00642 return result;
00643 }
00644
00645
00646 if ( !recurs() ) {
00647 if ( !( start > datetime || end < datetime ) ) {
00648 result << start;
00649 }
00650 return result;
00651 }
00652
00653 int days = start.daysTo( end );
00654
00655 QDate tmpday( datetime.date().addDays( -days - 1 ) );
00656 KDateTime tmp;
00657 while ( tmpday <= datetime.date() ) {
00658 if ( recurrence()->recursOn( tmpday, datetime.timeSpec() ) ) {
00659
00660 QList<QTime> times = recurrence()->recurTimesOn( tmpday, start.timeSpec() );
00661 foreach ( const QTime &time, times ) {
00662 tmp = KDateTime( tmpday, time, start.timeSpec() );
00663 if ( !( tmp > datetime || endDateForStart( tmp ) < datetime ) ) {
00664 result << tmp;
00665 }
00666 }
00667 }
00668 tmpday = tmpday.addDays( 1 );
00669 }
00670 return result;
00671 }
00672
00673 KDateTime Incidence::endDateForStart( const KDateTime &startDt ) const
00674 {
00675 KDateTime start = dtStart();
00676 KDateTime end = endDateRecurrenceBase();
00677 if ( !end.isValid() ) {
00678 return start;
00679 }
00680 if ( !start.isValid() ) {
00681 return end;
00682 }
00683
00684 return startDt.addSecs( start.secsTo( end ) );
00685 }
00686
00687 void Incidence::addAttachment( Attachment *attachment )
00688 {
00689 if ( mReadOnly || !attachment ) {
00690 return;
00691 }
00692
00693 d->mAttachments.append( attachment );
00694 updated();
00695 }
00696
00697 void Incidence::deleteAttachment( Attachment *attachment )
00698 {
00699 d->mAttachments.removeRef( attachment );
00700 }
00701
00702 void Incidence::deleteAttachments( const QString &mime )
00703 {
00704 Attachment::List::Iterator it = d->mAttachments.begin();
00705 while ( it != d->mAttachments.end() ) {
00706 if ( (*it)->mimeType() == mime ) {
00707 d->mAttachments.removeRef( it );
00708 } else {
00709 ++it;
00710 }
00711 }
00712 }
00713
00714 Attachment::List Incidence::attachments() const
00715 {
00716 return d->mAttachments;
00717 }
00718
00719 Attachment::List Incidence::attachments( const QString &mime ) const
00720 {
00721 Attachment::List attachments;
00722 Attachment::List::ConstIterator it;
00723 foreach ( Attachment *attachment, d->mAttachments ) {
00724 if ( attachment->mimeType() == mime ) {
00725 attachments.append( attachment );
00726 }
00727 }
00728 return attachments;
00729 }
00730
00731 void Incidence::clearAttachments()
00732 {
00733 d->mAttachments.clearAll();
00734 }
00735
00736 QString Incidence::writeAttachmentToTempFile( Attachment* attachment ) const
00737 {
00738 if ( d->mTempFiles.contains( attachment ) ) {
00739 return d->mTempFiles.value( attachment );
00740 }
00741 KTemporaryFile *file = new KTemporaryFile();
00742
00743 QStringList patterns = KMimeType::mimeType( attachment->mimeType() )->patterns();
00744
00745 if ( !patterns.empty() ) {
00746 file->setSuffix( QString( patterns.first() ).remove( '*' ) );
00747 }
00748 file->setAutoRemove( true );
00749 file->open();
00750
00751 file->setPermissions( QFile::ReadUser );
00752 file->write( QByteArray::fromBase64( attachment->data() ) );
00753 d->mTempFiles.insert( attachment, file->fileName() );
00754 file->close();
00755 return d->mTempFiles.value( attachment );
00756 }
00757
00758 void Incidence::clearTempFiles()
00759 {
00760 QHash<Attachment*, QString>::const_iterator it = d->mTempFiles.constBegin();
00761 const QHash<Attachment*, QString>::const_iterator end = d->mTempFiles.constEnd();
00762 for ( ; it != end; ++it )
00763 {
00764 QFile::remove( it.value() );
00765 }
00766 d->mTempFiles.clear();
00767 }
00768
00769 void Incidence::setResources( const QStringList &resources )
00770 {
00771 if ( mReadOnly ) {
00772 return;
00773 }
00774
00775 d->mResources = resources;
00776 updated();
00777 }
00778
00779 QStringList Incidence::resources() const
00780 {
00781 return d->mResources;
00782 }
00783
00784 void Incidence::setPriority( int priority )
00785 {
00786 if ( mReadOnly ) {
00787 return;
00788 }
00789
00790 d->mPriority = priority;
00791 updated();
00792 }
00793
00794 int Incidence::priority() const
00795 {
00796 return d->mPriority;
00797 }
00798
00799 void Incidence::setStatus( Incidence::Status status )
00800 {
00801 if ( mReadOnly || status == StatusX ) {
00802 return;
00803 }
00804
00805 d->mStatus = status;
00806 d->mStatusString.clear();
00807 updated();
00808 }
00809
00810 void Incidence::setCustomStatus( const QString &status )
00811 {
00812 if ( mReadOnly ) {
00813 return;
00814 }
00815
00816 d->mStatus = status.isEmpty() ? StatusNone : StatusX;
00817 d->mStatusString = status;
00818 updated();
00819 }
00820
00821 Incidence::Status Incidence::status() const
00822 {
00823 return d->mStatus;
00824 }
00825
00826 QString Incidence::statusStr() const
00827 {
00828 if ( d->mStatus == StatusX ) {
00829 return d->mStatusString;
00830 }
00831
00832 return statusName( d->mStatus );
00833 }
00834
00835 QString Incidence::statusName( Incidence::Status status )
00836 {
00837 switch ( status ) {
00838 case StatusTentative:
00839 return i18nc( "@item event is tentative", "Tentative" );
00840 case StatusConfirmed:
00841 return i18nc( "@item event is definite", "Confirmed" );
00842 case StatusCompleted:
00843 return i18nc( "@item to-do is complete", "Completed" );
00844 case StatusNeedsAction:
00845 return i18nc( "@item to-do needs action", "Needs-Action" );
00846 case StatusCanceled:
00847 return i18nc( "@item event orto-do is canceled; journal is removed", "Canceled" );
00848 case StatusInProcess:
00849 return i18nc( "@item to-do is in process", "In-Process" );
00850 case StatusDraft:
00851 return i18nc( "@item journal is in draft form", "Draft" );
00852 case StatusFinal:
00853 return i18nc( "@item journal is in final form", "Final" );
00854 case StatusX:
00855 case StatusNone:
00856 default:
00857 return QString();
00858 }
00859 }
00860
00861 void Incidence::setSecrecy( Incidence::Secrecy secrecy )
00862 {
00863 if ( mReadOnly ) {
00864 return;
00865 }
00866
00867 d->mSecrecy = secrecy;
00868 updated();
00869 }
00870
00871 Incidence::Secrecy Incidence::secrecy() const
00872 {
00873 return d->mSecrecy;
00874 }
00875
00876 QString Incidence::secrecyStr() const
00877 {
00878 return secrecyName( d->mSecrecy );
00879 }
00880
00881 QString Incidence::secrecyName( Incidence::Secrecy secrecy )
00882 {
00883 switch ( secrecy ) {
00884 case SecrecyPublic:
00885 return i18nc( "@item incidence access if for everyone", "Public" );
00886 case SecrecyPrivate:
00887 return i18nc( "@item incidence access is by owner only", "Private" );
00888 case SecrecyConfidential:
00889 return i18nc( "@item incidence access is by owner and a controlled group", "Confidential" );
00890 default:
00891 return QString();
00892 }
00893 }
00894
00895 QStringList Incidence::secrecyList()
00896 {
00897 QStringList list;
00898 list << secrecyName( SecrecyPublic );
00899 list << secrecyName( SecrecyPrivate );
00900 list << secrecyName( SecrecyConfidential );
00901
00902 return list;
00903 }
00904
00905 const Alarm::List &Incidence::alarms() const
00906 {
00907 return d->mAlarms;
00908 }
00909
00910 Alarm *Incidence::newAlarm()
00911 {
00912 Alarm *alarm = new Alarm( this );
00913 d->mAlarms.append( alarm );
00914 return alarm;
00915 }
00916
00917 void Incidence::addAlarm( Alarm *alarm )
00918 {
00919 d->mAlarms.append( alarm );
00920 updated();
00921 }
00922
00923 void Incidence::removeAlarm( Alarm *alarm )
00924 {
00925 d->mAlarms.removeRef( alarm );
00926 updated();
00927 }
00928
00929 void Incidence::clearAlarms()
00930 {
00931 d->mAlarms.clearAll();
00932 updated();
00933 }
00934
00935 bool Incidence::isAlarmEnabled() const
00936 {
00937 foreach ( Alarm *alarm, d->mAlarms ) {
00938 if ( alarm->enabled() ) {
00939 return true;
00940 }
00941 }
00942 return false;
00943 }
00944
00945 void Incidence::setLocation( const QString &location, bool isRich )
00946 {
00947 if ( mReadOnly ) {
00948 return;
00949 }
00950
00951 d->mLocation = location;
00952 d->mLocationIsRich = isRich;
00953 updated();
00954 }
00955
00956 void Incidence::setLocation( const QString &location )
00957 {
00958 setLocation( location, Qt::mightBeRichText( location ) );
00959 }
00960
00961 QString Incidence::location() const
00962 {
00963 return d->mLocation;
00964 }
00965
00966 QString Incidence::richLocation() const
00967 {
00968 if ( locationIsRich() ) {
00969 return d->mLocation;
00970 } else {
00971 return Qt::escape( d->mLocation ).replace( '\n', "<br/>" );
00972 }
00973 }
00974
00975 bool Incidence::locationIsRich() const
00976 {
00977 return d->mLocationIsRich;
00978 }
00979
00980 void Incidence::setSchedulingID( const QString &sid )
00981 {
00982 d->mSchedulingID = sid;
00983 }
00984
00985 QString Incidence::schedulingID() const
00986 {
00987 if ( d->mSchedulingID.isNull() ) {
00988
00989 return uid();
00990 }
00991 return d->mSchedulingID;
00992 }
00993
00994 bool Incidence::hasGeo() const
00995 {
00996 return d->mHasGeo;
00997 }
00998
00999 void Incidence::setHasGeo( bool hasGeo )
01000 {
01001 if ( mReadOnly ) {
01002 return;
01003 }
01004
01005 d->mHasGeo = hasGeo;
01006 updated();
01007 }
01008
01009 float &Incidence::geoLatitude() const
01010 {
01011 return d->mGeoLatitude;
01012 }
01013
01014 void Incidence::setGeoLatitude( float geolatitude )
01015 {
01016 if ( mReadOnly ) {
01017 return;
01018 }
01019
01020 d->mGeoLatitude = geolatitude;
01021 updated();
01022 }
01023
01024 float &Incidence::geoLongitude() const
01025 {
01026 return d->mGeoLongitude;
01027 }
01028
01029 void Incidence::setGeoLongitude( float geolongitude )
01030 {
01031 if ( mReadOnly ) {
01032 return;
01033 }
01034
01035 d->mGeoLongitude = geolongitude;
01036 updated();
01037 }
01038
01042 void Incidence::recurrenceUpdated( Recurrence *recurrence )
01043 {
01044 if ( recurrence == d->mRecurrence ) {
01045 updated();
01046 }
01047 }