libkcal

incidence.cpp

00001 /*
00002     This file is part of libkcal.
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 */
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 // TODO: reenable attributes currently commented out.
00047   mRevision = i.mRevision;
00048   mCreated = i.mCreated;
00049   mDescription = i.mDescription;
00050   mSummary = i.mSummary;
00051   mCategories = i.mCategories;
00052 //  Incidence *mRelatedTo;          Incidence *mRelatedTo;
00053   mRelatedTo = 0;
00054   mRelatedToUid = i.mRelatedToUid;
00055 //  Incidence::List mRelations;    Incidence::List mRelations;
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   // Alarms and Attachments are stored in ListBase<...>, which is a QValueList<...*>.
00064   // We need to really duplicate the objects stored therein, otherwise deleting
00065   // i will also delete all attachments from this object (setAutoDelete...)
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 // A string comparison that considers that null and empty are the same
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; // no need to check further
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         // no need to compare mRelatedTo
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 // FIXME: Shouldn't we call updated for the creation date, too?
00191 //  updated();
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 // TODO: remove setCategories(QString) function
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 //  if (event->getRelatedTo() == this) event->setRelatedTo(0);
00329 }
00330 
00331 
00332 // %%%%%%%%%%%%  Recurrence-related methods %%%%%%%%%%%%%%%%%%%%
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 //kdDebug(5800) << "Incidence::startDateTimesForDate " << date << ", incidence=" << summary() << endl;
00388   QDateTime start = dtStart();
00389   QDateTime end = endDateRecurrenceBase();
00390 
00391   QValueList<QDateTime> result;
00392 
00393   // TODO_Recurrence: Also work if only due date is given...
00394   if ( !start.isValid() && ! end.isValid() ) {
00395     return result;
00396   }
00397 
00398   // if the incidence doesn't recur,
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   // Account for possible recurrences going over midnight, while the original event doesn't
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 // kdDebug(5800) << "Incidence::startDateTimesForDateTime " << datetime << ", incidence=" << summary() << endl;
00435   QDateTime start = dtStart();
00436   QDateTime end = endDateRecurrenceBase();
00437 
00438   QValueList<QDateTime> result;
00439 
00440   // TODO_Recurrence: Also work if only due date is given...
00441   if ( !start.isValid() && ! end.isValid() ) {
00442     return result;
00443   }
00444 
00445   // if the incidence doesn't recur,
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   // Account for possible recurrences going over midnight, while the original event doesn't
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 // %%%%%%%%%%%%%%%%% begin:RecurrenceRule %%%%%%%%%%%%%%%%%
00483 
00484 // Exception Dates
00485 /*void Incidence::setExDates(const DateList &exDates)
00486 {
00487   if ( mReadOnly ) return;
00488   recurrence()->setExDates( exDates );
00489   updated();
00490 }
00491 
00492 void Incidence::addExDate( const QDate &date )
00493 {
00494   if ( mReadOnly ) return;
00495   recurrence()->addExDate( date );
00496   updated();
00497 }
00498 
00499 DateList Incidence::exDates() const
00500 {
00501   if ( mRecurrence ) return mRecurrence->exDates();
00502   else return DateList();
00503 }
00504 
00505 
00506 // Exception DateTimes
00507 void Incidence::setExDateTimes( const DateTimeList &exDates )
00508 {
00509   if ( mReadOnly ) return;
00510   recurrence()->setExDateTimes( exDates );
00511   updated();
00512 }
00513 
00514 void Incidence::addExDateTime( const QDateTime &date )
00515 {
00516   if ( mReadOnly ) return;
00517   recurrence()->addExDateTime( date );
00518   updated();
00519 }
00520 
00521 DateTimeList Incidence::exDateTimes() const
00522 {
00523   if ( mRecurrence ) return mRecurrence->exDateTimes();
00524   else return DateTimeList();
00525 }
00526 
00527 
00528 // Recurrence Dates
00529 void Incidence::setRDates(const DateList &exDates)
00530 {
00531   if ( mReadOnly ) return;
00532   recurrence()->setRDates( exDates );
00533   updated();
00534 }
00535 
00536 void Incidence::addRDate( const QDate &date )
00537 {
00538   if ( mReadOnly ) return;
00539   recurrence()->addRDate( date );
00540   updated();
00541 }
00542 
00543 DateList Incidence::rDates() const
00544 {
00545   if ( mRecurrence ) return mRecurrence->rDates();
00546   else return DateList();
00547 }
00548 
00549 
00550 // Recurrence DateTimes
00551 void Incidence::setRDateTimes( const DateTimeList &exDates )
00552 {
00553   if ( mReadOnly ) return;
00554   recurrence()->setRDateTimes( exDates );
00555   updated();
00556 }
00557 
00558 void Incidence::addRDateTime( const QDateTime &date )
00559 {
00560   if ( mReadOnly ) return;
00561   recurrence()->addRDateTime( date );
00562   updated();
00563 }
00564 
00565 DateTimeList Incidence::rDateTimes() const
00566 {
00567   if ( mRecurrence ) return mRecurrence->rDateTimes();
00568   else return DateTimeList();
00569 }*/
00570 
00571 // %%%%%%%%%%%%%%%%% end:RecurrenceRule %%%%%%%%%%%%%%%%%
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 //  updated();
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     // Nothing set, so use the normal uid
00788     return uid();
00789   return mSchedulingID;
00790 }
00791 
00795 void Incidence::recurrenceUpdated( Recurrence *recurrence )
00796 {
00797   if ( recurrence == mRecurrence )
00798     updated();
00799 }
00800 
KDE Home | KDE Accessibility Home | Description of Access Keys