• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

KCal Library

incidence.cpp
Go to the documentation of this file.
00001 /*
00002   This file is part of the kcal library.
00003 
00004   Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00005   Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007   This library is free software; you can redistribute it and/or
00008   modify it under the terms of the GNU Library General Public
00009   License as published by the Free Software Foundation; either
00010   version 2 of the License, or (at your option) any later version.
00011 
00012   This library is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015   Library General Public License for more details.
00016 
00017   You should have received a copy of the GNU Library General Public License
00018   along with this library; see the file COPYING.LIB.  If not, write to
00019   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020   Boston, MA 02110-1301, USA.
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> // for Qt::escape() and Qt::mightBeRichText()
00048 #include <KMimeType>
00049 
00050 using namespace KCal;
00051 
00056 //@cond PRIVATE
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;              // creation datetime
00112     int mRevision;                   // revision number
00113 
00114     QString mDescription;            // description string
00115     bool mDescriptionIsRich;         // description string is richtext.
00116     QString mSummary;                // summary string
00117     bool mSummaryIsRich;             // summary string is richtext.
00118     QString mLocation;               // location string
00119     bool mLocationIsRich;            // location string is richtext.
00120     QStringList mCategories;         // category list
00121     mutable Recurrence *mRecurrence; // recurrence
00122     Attachment::List mAttachments;   // attachments list
00123     Alarm::List mAlarms;             // alarms list
00124     QStringList mResources;          // resources list (not calendar resources)
00125     Status mStatus;                  // status
00126     QString mStatusString;           // status string, for custom status
00127     Secrecy mSecrecy;                // secrecy
00128     int mPriority;                   // priority: 1 = highest, 2 = less, etc.
00129     QString mSchedulingID;           // ID for scheduling mails
00130 
00131     Incidence *mRelatedTo;           // incidence this is related to
00132     QString mRelatedToUid;           // incidence (by Uid) this is related to
00133     Incidence::List mRelations;      // a list of incidences related to this
00134     float mGeoLatitude;              // Specifies latitude in decimal degrees
00135     float mGeoLongitude;             // Specifies longitude in decimal degrees
00136     bool mHasGeo;                    // if incidence has geo data
00137     QHash<Attachment *, QString> mTempFiles;   // Temporary files for writing attachments to.
00138 };
00139 //@endcond
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   // Alarms and Attachments are stored in ListBase<...>, which is a QValueList<...*>.
00176   // We need to really duplicate the objects stored therein, otherwise deleting
00177   // i will also delete all attachments from this object (setAutoDelete...)
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 //@cond PRIVATE
00214 // A string comparison that considers that null and empty are the same
00215 static bool stringCompare( const QString &s1, const QString &s2 )
00216 {
00217   return ( s1.isEmpty() && s2.isEmpty() ) || ( s1 == s2 );
00218 }
00219 
00220 //@endcond
00221 Incidence &Incidence::operator=( const Incidence &other )
00222 {
00223   // check for self assignment
00224   if ( &other == this ) {
00225     return *this;
00226   }
00227 
00228   d->clear();
00229   //TODO: should relations be cleared out, as in destructor???
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; // no need to check further
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     // no need to compare mRelatedTo
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 // FIXME: Shouldn't we call updated for the creation date, too?
00325 //  updated();
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 //  if (incidence->getRelatedTo() == this) incidence->setRelatedTo(0);
00540 }
00541 
00542 // %%%%%%%%%%%%  Recurrence-related methods %%%%%%%%%%%%%%%%%%%%
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   // TODO_Recurrence: Also work if only due date is given...
00601   if ( !start.isValid() && ! end.isValid() ) {
00602     return result;
00603   }
00604 
00605   // if the incidence doesn't recur,
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   // Account for possible recurrences going over midnight, while the original event doesn't
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   // TODO_Recurrence: Also work if only due date is given...
00641   if ( !start.isValid() && ! end.isValid() ) {
00642     return result;
00643   }
00644 
00645   // if the incidence doesn't recur,
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   // Account for possible recurrences going over midnight, while the original event doesn't
00655   QDate tmpday( datetime.date().addDays( -days - 1 ) );
00656   KDateTime tmp;
00657   while ( tmpday <= datetime.date() ) {
00658     if ( recurrence()->recursOn( tmpday, datetime.timeSpec() ) ) {
00659       // Get the times during the day (in start date's time zone) when recurrences happen
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   // read-only not to give the idea that it could be written to
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();  // to make compilers happy
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     // Nothing set, so use the normal uid
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 }
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:19:47 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal