38 #include "kpimutils/kfileio.h"
43 #include <ktemporaryfile.h>
46 #include <QtCore/QList>
47 #include <QTextDocument>
57 class KCal::Incidence::Private
61 : mDescriptionIsRich( false ),
62 mSummaryIsRich( false ),
63 mLocationIsRich( false ),
65 mStatus( StatusNone ),
66 mSecrecy( SecrecyPublic ),
73 mAlarms.setAutoDelete(
true );
74 mAttachments.setAutoDelete(
true );
77 Private(
const Private &p )
78 : mCreated( p.mCreated ),
79 mRevision( p.mRevision ),
80 mDescription( p.mDescription ),
81 mDescriptionIsRich( p.mDescriptionIsRich ),
82 mSummary( p.mSummary ),
83 mSummaryIsRich( p.mSummaryIsRich ),
84 mLocation( p.mLocation ),
85 mLocationIsRich( p.mLocationIsRich ),
86 mCategories( p.mCategories ),
87 mRecurrence( p.mRecurrence ),
88 mResources( p.mResources ),
90 mStatusString( p.mStatusString ),
91 mSecrecy( p.mSecrecy ),
92 mPriority( p.mPriority ),
93 mSchedulingID( p.mSchedulingID ),
94 mRelatedTo( p.mRelatedTo ),
95 mRelatedToUid( p.mRelatedToUid ),
96 mGeoLatitude( p.mGeoLatitude ),
97 mGeoLongitude( p.mGeoLongitude ),
100 mAlarms.setAutoDelete(
true );
101 mAttachments.setAutoDelete(
true );
107 mAttachments.clearAll();
114 QString mDescription;
115 bool mDescriptionIsRich;
119 bool mLocationIsRich;
120 QStringList mCategories;
124 QStringList mResources;
126 QString mStatusString;
129 QString mSchedulingID;
132 QString mRelatedToUid;
137 QHash<Attachment *, QString> mTempFiles;
150 d( new KCal::
Incidence::Private( *i.d ) )
155 void Incidence::init(
const Incidence &i )
157 d->mRevision = i.d->mRevision;
158 d->mCreated = i.d->mCreated;
159 d->mDescription = i.d->mDescription;
160 d->mSummary = i.d->mSummary;
161 d->mCategories = i.d->mCategories;
162 d->mRelatedTo = i.d->mRelatedTo;
163 d->mRelatedToUid = i.d->mRelatedToUid;
164 d->mRelations = i.d->mRelations;
165 d->mResources = i.d->mResources;
166 d->mStatusString = i.d->mStatusString;
167 d->mStatus = i.d->mStatus;
168 d->mSecrecy = i.d->mSecrecy;
169 d->mPriority = i.d->mPriority;
170 d->mLocation = i.d->mLocation;
171 d->mGeoLatitude = i.d->mGeoLatitude;
172 d->mGeoLongitude = i.d->mGeoLongitude;
173 d->mHasGeo = i.d->mHasGeo;
178 foreach (
Alarm *alarm, i.d->mAlarms ) {
181 d->mAlarms.append( b );
184 foreach (
Attachment *attachment, i.d->mAttachments ) {
186 d->mAttachments.append( a );
189 if ( i.d->mRecurrence ) {
190 d->mRecurrence =
new Recurrence( *( i.d->mRecurrence ) );
191 d->mRecurrence->addObserver(
this );
200 foreach (
Incidence *incidence, relations ) {
209 delete d->mRecurrence;
215 static bool stringCompare(
const QString &s1,
const QString &s2 )
217 return ( s1.isEmpty() && s2.isEmpty() ) || ( s1 == s2 );
224 if ( &other ==
this ) {
241 Alarm::List::ConstIterator a1 =
alarms().constBegin();
242 Alarm::List::ConstIterator a1end =
alarms().constEnd();
243 Alarm::List::ConstIterator a2 = i2.
alarms().begin();
244 Alarm::List::ConstIterator a2end = i2.
alarms().constEnd();
245 for ( ; a1 != a1end && a2 != a2end; ++a1, ++a2 ) {
246 if ( **a1 == **a2 ) {
253 if ( !IncidenceBase::operator==( i2 ) ) {
257 bool recurrenceEqual = ( d->mRecurrence == 0 && i2.d->mRecurrence == 0 );
258 if ( !recurrenceEqual ) {
259 recurrenceEqual = d->mRecurrence != 0 &&
260 i2.d->mRecurrence != 0 &&
261 *d->mRecurrence == *i2.d->mRecurrence;
275 d->mStatus == i2.d->mStatus &&
277 stringCompare( d->mStatusString, i2.d->mStatusString ) ) &&
286 KDateTime nowUTC = KDateTime::currentUtcDateTime();
300 if ( d->mRecurrence ) {
301 d->mRecurrence->setRecurReadOnly( readOnly );
322 d->mCreated = created.toUtc();
351 if ( d->mRecurrence ) {
352 d->mRecurrence->setStartDateTime( dt );
353 d->mRecurrence->setAllDay(
allDay() );
364 const KDateTime::Spec &newSpec )
367 if ( d->mRecurrence ) {
368 d->mRecurrence->shiftTimes( oldSpec, newSpec );
370 for (
int i = 0, end = d->mAlarms.count(); i < end; ++i ) {
371 d->mAlarms[i]->shiftTimes( oldSpec, newSpec );
381 d->mDescriptionIsRich = isRich;
387 setDescription( description, Qt::mightBeRichText( description ) );
392 return d->mDescription;
398 return d->mDescription;
400 return Qt::escape( d->mDescription ).replace(
'\n',
"<br/>" );
406 return d->mDescriptionIsRich;
415 d->mSummaryIsRich = isRich;
421 setSummary( summary, Qt::mightBeRichText( summary ) );
434 return Qt::escape( d->mSummary ).replace(
'\n',
"<br/>" );
440 return d->mSummaryIsRich;
457 d->mCategories.clear();
459 if ( catStr.isEmpty() ) {
463 d->mCategories = catStr.split(
',' );
465 QStringList::Iterator it;
466 for ( it = d->mCategories.begin();it != d->mCategories.end(); ++it ) {
467 *it = (*it).trimmed();
475 return d->mCategories;
480 return d->mCategories.join(
"," );
485 if ( d->mRelatedToUid == relatedToUid ) {
494 return d->mRelatedToUid;
499 if ( d->mRelatedTo == incidence ) {
502 if ( d->mRelatedTo ) {
503 d->mRelatedTo->removeRelation(
this );
505 d->mRelatedTo = incidence;
506 if ( d->mRelatedTo ) {
508 if ( d->mRelatedTo->uid() != d->mRelatedToUid ) {
518 return d->mRelatedTo;
523 return d->mRelations;
528 if ( !d->mRelations.contains( incidence ) ) {
529 d->mRelations.append( incidence );
535 d->mRelations.removeRef( incidence );
536 if ( d->mRelatedToUid == incidence->
uid() ) {
537 d->mRelatedToUid.clear();
546 if ( !d->mRecurrence ) {
549 d->mRecurrence->setAllDay(
allDay() );
550 d->mRecurrence->setRecurReadOnly(
mReadOnly );
551 d->mRecurrence->addObserver( const_cast<KCal::Incidence*>(
this ) );
554 return d->mRecurrence;
559 delete d->mRecurrence;
565 if ( d->mRecurrence ) {
566 return d->mRecurrence->recurrenceType();
568 return Recurrence::rNone;
574 if ( d->mRecurrence ) {
575 return d->mRecurrence->recurs();
582 const KDateTime::Spec &timeSpec )
const
584 return d->mRecurrence && d->mRecurrence->recursOn( date, timeSpec );
589 return d->mRecurrence && d->mRecurrence->recursAt( qdt );
593 const KDateTime::Spec &timeSpec )
const
598 QList<KDateTime> result;
601 if ( !start.isValid() && ! end.isValid() ) {
606 KDateTime kdate( date, timeSpec );
608 if ( !( start > kdate || end < kdate ) ) {
614 int days = start.daysTo( end );
616 QDate tmpday( date.addDays( -days - 1 ) );
618 while ( tmpday <= date ) {
621 foreach (
const QTime &time, times ) {
622 tmp = KDateTime( tmpday, time, start.timeSpec() );
628 tmpday = tmpday.addDays( 1 );
638 QList<KDateTime> result;
641 if ( !start.isValid() && ! end.isValid() ) {
647 if ( !( start > datetime || end < datetime ) ) {
653 int days = start.daysTo( end );
655 QDate tmpday( datetime.date().addDays( -days - 1 ) );
657 while ( tmpday <= datetime.date() ) {
661 foreach (
const QTime &time, times ) {
662 tmp = KDateTime( tmpday, time, start.timeSpec() );
668 tmpday = tmpday.addDays( 1 );
677 if ( !end.isValid() ) {
680 if ( !start.isValid() ) {
684 return startDt.addSecs( start.secsTo( end ) );
693 d->mAttachments.append( attachment );
699 d->mAttachments.removeRef( attachment );
704 Attachment::List::Iterator it = d->mAttachments.begin();
705 while ( it != d->mAttachments.end() ) {
706 if ( (*it)->mimeType() == mime ) {
707 d->mAttachments.removeRef( it );
716 return d->mAttachments;
722 Attachment::List::ConstIterator it;
723 foreach (
Attachment *attachment, d->mAttachments ) {
724 if ( attachment->
mimeType() == mime ) {
725 attachments.append( attachment );
733 d->mAttachments.clearAll();
738 if ( d->mTempFiles.contains( attachment ) ) {
739 return d->mTempFiles.value( attachment );
741 KTemporaryFile *file =
new KTemporaryFile();
743 QStringList patterns = KMimeType::mimeType( attachment->
mimeType() )->patterns();
745 if ( !patterns.empty() ) {
746 file->setSuffix( QString( patterns.first() ).
remove(
'*' ) );
748 file->setAutoRemove(
true );
751 file->setPermissions( QFile::ReadUser );
752 file->write( QByteArray::fromBase64( attachment->
data() ) );
753 d->mTempFiles.insert( attachment, file->fileName() );
755 return d->mTempFiles.value( attachment );
758 void Incidence::clearTempFiles()
760 QHash<Attachment*, QString>::const_iterator it = d->mTempFiles.constBegin();
761 const QHash<Attachment*, QString>::const_iterator end = d->mTempFiles.constEnd();
762 for ( ; it != end; ++it )
764 QFile::remove( it.value() );
766 d->mTempFiles.clear();
781 return d->mResources;
806 d->mStatusString.clear();
817 d->mStatusString =
status;
829 return d->mStatusString;
839 return i18nc(
"@item event is tentative",
"Tentative" );
841 return i18nc(
"@item event is definite",
"Confirmed" );
843 return i18nc(
"@item to-do is complete",
"Completed" );
845 return i18nc(
"@item to-do needs action",
"Needs-Action" );
847 return i18nc(
"@item event orto-do is canceled; journal is removed",
"Canceled" );
849 return i18nc(
"@item to-do is in process",
"In-Process" );
851 return i18nc(
"@item journal is in draft form",
"Draft" );
853 return i18nc(
"@item journal is in final form",
"Final" );
885 return i18nc(
"@item incidence access if for everyone",
"Public" );
887 return i18nc(
"@item incidence access is by owner only",
"Private" );
889 return i18nc(
"@item incidence access is by owner and a controlled group",
"Confidential" );
913 d->mAlarms.append( alarm );
919 d->mAlarms.append( alarm );
925 d->mAlarms.removeRef( alarm );
931 d->mAlarms.clearAll();
937 foreach (
Alarm *alarm, d->mAlarms ) {
952 d->mLocationIsRich = isRich;
958 setLocation( location, Qt::mightBeRichText( location ) );
971 return Qt::escape( d->mLocation ).replace(
'\n',
"<br/>" );
977 return d->mLocationIsRich;
982 d->mSchedulingID = sid;
987 if ( d->mSchedulingID.isNull() ) {
991 return d->mSchedulingID;
1011 return d->mGeoLatitude;
1020 d->mGeoLatitude = geolatitude;
1026 return d->mGeoLongitude;
1035 d->mGeoLongitude = geolongitude;
1044 if ( recurrence == d->mRecurrence ) {