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