• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KCal Library

incidencebase.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the kcal library.
00003 
00004     Copyright (c) 2001,2004 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 "incidencebase.h"
00036 
00037 #include "calformat.h"
00038 
00039 #include <kglobal.h>
00040 #include <klocale.h>
00041 #include <kdebug.h>
00042 #include <kurl.h>
00043 #include <ksystemtimezone.h>
00044 
00045 using namespace KCal;
00046 
00051 //@cond PRIVATE
00052 class KCal::IncidenceBase::Private
00053 {
00054   public:
00055     Private()
00056       : mUpdateGroupLevel( 0 ),
00057         mUpdatedPending( false ),
00058         mAllDay( true ),
00059         mHasDuration( false )
00060     { mAttendees.setAutoDelete( true ); }
00061 
00062     Private( const Private &other )
00063       : mLastModified( other.mLastModified ),
00064         mDtStart( other.mDtStart ),
00065         mOrganizer( other.mOrganizer ),
00066         mUid( other.mUid ),
00067         mDuration( other.mDuration ),
00068         mUpdateGroupLevel( 0 ),
00069         mUpdatedPending( false ),
00070         mAllDay( other.mAllDay ),
00071         mHasDuration( other.mHasDuration )
00072         //????? mComments
00073         // mObservers: the copied object is a new one, so it isn't observed
00074         // by the observer of the original object.
00075       { mAttendees.setAutoDelete( true ); }
00076 
00077     KDateTime mLastModified;     // incidence last modified date
00078     KDateTime mDtStart;          // incidence start time
00079     Person mOrganizer;           // incidence person (owner)
00080     QString mUid;                // incidence unique id
00081     Duration mDuration;          // incidence duration
00082     int mUpdateGroupLevel;       // if non-zero, suppresses update() calls
00083     bool mUpdatedPending;        // true if an update has occurred since startUpdates()
00084     bool mAllDay;                // true if the incidence is all-day
00085     bool mHasDuration;           // true if the incidence has a duration
00086 
00087     Attendee::List mAttendees;   // list of incidence attendees
00088     QStringList mComments;       // list of incidence comments
00089     QList<IncidenceObserver*> mObservers; // list of incidence observers
00090 };
00091 //@endcond
00092 
00093 IncidenceBase::IncidenceBase() : d( new KCal::IncidenceBase::Private )
00094 {
00095   mReadOnly = false;
00096 
00097   setUid( CalFormat::createUniqueId() );
00098 }
00099 
00100 IncidenceBase::IncidenceBase( const IncidenceBase &i ) :
00101   CustomProperties( i ), d( new KCal::IncidenceBase::Private( *i.d ) )
00102 {
00103   mReadOnly = i.mReadOnly;
00104 
00105   Attendee::List attendees = i.attendees();
00106   Attendee::List::ConstIterator it;
00107   for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00108     d->mAttendees.append( new Attendee( *(*it) ) );
00109   }
00110 }
00111 
00112 IncidenceBase::~IncidenceBase()
00113 {
00114   delete d;
00115 }
00116 
00117 bool IncidenceBase::operator==( const IncidenceBase &i2 ) const
00118 {
00119   if ( attendees().count() != i2.attendees().count() ) {
00120     return false; // no need to check further
00121   }
00122 
00123   Attendee::List al1 = attendees();
00124   Attendee::List al2 = i2.attendees();
00125   Attendee::List::ConstIterator a1 = al1.begin();
00126   Attendee::List::ConstIterator a2 = al2.begin();
00127   for ( ; a1 != al1.end() && a2 != al2.end(); ++a1, ++a2 ) {
00128     if ( **a1 == **a2 ) {
00129       continue;
00130     } else {
00131       return false;
00132     }
00133   }
00134 
00135   if ( !CustomProperties::operator == (i2) ) {
00136     return false;
00137   }
00138 
00139   return
00140     dtStart() == i2.dtStart() &&
00141     organizer() == i2.organizer() &&
00142     uid() == i2.uid() &&
00143     // Don't compare lastModified, otherwise the operator is not
00144     // of much use. We are not comparing for identity, after all.
00145     allDay() == i2.allDay() &&
00146     duration() == i2.duration() &&
00147     hasDuration() == i2.hasDuration();
00148   // no need to compare mObserver
00149 }
00150 
00151 void IncidenceBase::setUid( const QString &uid )
00152 {
00153   d->mUid = uid;
00154   updated();
00155 }
00156 
00157 QString IncidenceBase::uid() const
00158 {
00159   return d->mUid;
00160 }
00161 
00162 void IncidenceBase::setLastModified( const KDateTime &lm )
00163 {
00164   // DON'T! updated() because we call this from
00165   // Calendar::updateEvent().
00166 
00167   // Convert to UTC and remove milliseconds part.
00168   KDateTime current = lm.toUtc();
00169   QTime t = current.time();
00170   t.setHMS( t.hour(), t.minute(), t.second(), 0 );
00171   current.setTime( t );
00172 
00173   d->mLastModified = current;
00174 }
00175 
00176 KDateTime IncidenceBase::lastModified() const
00177 {
00178   return d->mLastModified;
00179 }
00180 
00181 void IncidenceBase::setOrganizer( const Person &o )
00182 {
00183   // we don't check for readonly here, because it is
00184   // possible that by setting the organizer we are changing
00185   // the event's readonly status...
00186   d->mOrganizer = o;
00187 
00188   updated();
00189 }
00190 
00191 void IncidenceBase::setOrganizer( const QString &o )
00192 {
00193   QString mail( o );
00194   if ( mail.startsWith( "MAILTO:", Qt::CaseInsensitive ) ) {
00195     mail = mail.remove( 0, 7 );
00196   }
00197 
00198   // split the string into full name plus email.
00199   Person organizer( mail );
00200   setOrganizer( organizer );
00201 }
00202 
00203 Person IncidenceBase::organizer() const
00204 {
00205   return d->mOrganizer;
00206 }
00207 
00208 void IncidenceBase::setReadOnly( bool readOnly )
00209 {
00210   mReadOnly = readOnly;
00211 }
00212 
00213 void IncidenceBase::setDtStart( const KDateTime &dtStart )
00214 {
00215 //  if ( mReadOnly ) return;
00216   d->mDtStart = dtStart;
00217   d->mAllDay = dtStart.isDateOnly();
00218   updated();
00219 }
00220 
00221 KDateTime IncidenceBase::dtStart() const
00222 {
00223   return d->mDtStart;
00224 }
00225 
00226 QString IncidenceBase::dtStartTimeStr( bool shortfmt, const KDateTime::Spec &spec ) const
00227 {
00228   if ( spec.isValid() ) {
00229 
00230     QString timeZone;
00231     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00232       timeZone = ' ' + spec.timeZone().name();
00233     }
00234 
00235     return KGlobal::locale()->formatTime( dtStart().toTimeSpec( spec ).time(), shortfmt )
00236       + timeZone;
00237   } else {
00238     return KGlobal::locale()->formatTime( dtStart().time(), shortfmt );
00239   }
00240 }
00241 
00242 QString IncidenceBase::dtStartDateStr( bool shortfmt, const KDateTime::Spec &spec ) const
00243 {
00244   if ( spec.isValid() ) {
00245 
00246     QString timeZone;
00247     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00248       timeZone = ' ' + spec.timeZone().name();
00249     }
00250 
00251     return KGlobal::locale()->formatDate(
00252       dtStart().toTimeSpec( spec ).date(), ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) )
00253       + timeZone;
00254   } else {
00255     return KGlobal::locale()->formatDate(
00256       dtStart().date(), ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00257   }
00258 }
00259 
00260 QString IncidenceBase::dtStartStr( bool shortfmt, const KDateTime::Spec &spec ) const
00261 {
00262   if ( spec.isValid() ) {
00263 
00264     QString timeZone;
00265     if ( spec.timeZone() != KSystemTimeZones::local() ) {
00266       timeZone = ' ' + spec.timeZone().name();
00267     }
00268 
00269     return KGlobal::locale()->formatDateTime(
00270       dtStart().toTimeSpec( spec ).dateTime(),
00271       ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) ) + timeZone;
00272   } else {
00273     return KGlobal::locale()->formatDateTime(
00274       dtStart().dateTime(),
00275       ( shortfmt ? KLocale::ShortDate : KLocale::LongDate ) );
00276   }
00277 }
00278 
00279 bool IncidenceBase::allDay() const
00280 {
00281   return d->mAllDay;
00282 }
00283 
00284 void IncidenceBase::setAllDay( bool f )
00285 {
00286   if ( mReadOnly || f == d->mAllDay ) {
00287     return;
00288   }
00289   d->mAllDay = f;
00290   updated();
00291 }
00292 
00293 void IncidenceBase::shiftTimes( const KDateTime::Spec &oldSpec,
00294                                 const KDateTime::Spec &newSpec )
00295 {
00296   d->mDtStart = d->mDtStart.toTimeSpec( oldSpec );
00297   d->mDtStart.setTimeSpec( newSpec );
00298   updated();
00299 }
00300 
00301 void IncidenceBase::addComment( const QString &comment )
00302 {
00303   d->mComments += comment;
00304 }
00305 
00306 bool IncidenceBase::removeComment( const QString &comment )
00307 {
00308   bool found = false;
00309   QStringList::Iterator i;
00310 
00311   for ( i = d->mComments.begin(); !found && i != d->mComments.end(); ++i ) {
00312     if ( (*i) == comment ) {
00313       found = true;
00314       d->mComments.erase( i );
00315     }
00316   }
00317 
00318   return found;
00319 }
00320 
00321 void IncidenceBase::clearComments()
00322 {
00323   d->mComments.clear();
00324 }
00325 
00326 QStringList IncidenceBase::comments() const
00327 {
00328   return d->mComments;
00329 }
00330 
00331 void IncidenceBase::addAttendee( Attendee *a, bool doupdate )
00332 {
00333   if ( mReadOnly ) {
00334     return;
00335   }
00336 
00337   if ( a->name().left(7).toUpper() == "MAILTO:" ) {
00338     a->setName( a->name().remove( 0, 7 ) );
00339   }
00340 
00341   d->mAttendees.append( a );
00342   if ( doupdate ) {
00343     updated();
00344   }
00345 }
00346 
00347 const Attendee::List &IncidenceBase::attendees() const
00348 {
00349   return d->mAttendees;
00350 }
00351 
00352 int IncidenceBase::attendeeCount() const
00353 {
00354   return d->mAttendees.count();
00355 }
00356 
00357 void IncidenceBase::clearAttendees()
00358 {
00359   if ( mReadOnly ) {
00360     return;
00361   }
00362   d->mAttendees.clear();
00363 }
00364 
00365 Attendee *IncidenceBase::attendeeByMail( const QString &email ) const
00366 {
00367   Attendee::List::ConstIterator it;
00368   for ( it = d->mAttendees.begin(); it != d->mAttendees.end(); ++it ) {
00369     if ( (*it)->email() == email ) {
00370       return *it;
00371     }
00372   }
00373 
00374   return 0;
00375 }
00376 
00377 Attendee *IncidenceBase::attendeeByMails( const QStringList &emails,
00378                                           const QString &email ) const
00379 {
00380   QStringList mails = emails;
00381   if ( !email.isEmpty() ) {
00382     mails.append( email );
00383   }
00384 
00385   Attendee::List::ConstIterator itA;
00386   for ( itA = d->mAttendees.begin(); itA != d->mAttendees.end(); ++itA ) {
00387     for ( QStringList::Iterator it = mails.begin(); it != mails.end(); ++it ) {
00388       if ( (*itA)->email() == (*it) ) {
00389         return *itA;
00390       }
00391     }
00392   }
00393 
00394   return 0;
00395 }
00396 
00397 Attendee *IncidenceBase::attendeeByUid( const QString &uid ) const
00398 {
00399   Attendee::List::ConstIterator it;
00400   for ( it = d->mAttendees.begin(); it != d->mAttendees.end(); ++it ) {
00401     if ( (*it)->uid() == uid ) {
00402       return *it;
00403     }
00404   }
00405 
00406   return 0;
00407 }
00408 
00409 void IncidenceBase::setDuration( const Duration &duration )
00410 {
00411   d->mDuration = duration;
00412   setHasDuration( true );
00413   updated();
00414 }
00415 
00416 Duration IncidenceBase::duration() const
00417 {
00418   return d->mDuration;
00419 }
00420 
00421 void IncidenceBase::setHasDuration( bool hasDuration )
00422 {
00423   d->mHasDuration = hasDuration;
00424 }
00425 
00426 bool IncidenceBase::hasDuration() const
00427 {
00428   return d->mHasDuration;
00429 }
00430 
00431 void IncidenceBase::registerObserver( IncidenceBase::IncidenceObserver *observer )
00432 {
00433   if ( !d->mObservers.contains( observer ) ) {
00434     d->mObservers.append( observer );
00435   }
00436 }
00437 
00438 void IncidenceBase::unRegisterObserver( IncidenceBase::IncidenceObserver *observer )
00439 {
00440   d->mObservers.removeAll( observer );
00441 }
00442 
00443 void IncidenceBase::updated()
00444 {
00445   if ( d->mUpdateGroupLevel ) {
00446     d->mUpdatedPending = true;
00447   } else {
00448     foreach ( IncidenceObserver *o, d->mObservers ) {
00449       o->incidenceUpdated( this );
00450     }
00451   }
00452 }
00453 
00454 void IncidenceBase::startUpdates()
00455 {
00456   ++d->mUpdateGroupLevel;
00457 }
00458 
00459 void IncidenceBase::endUpdates()
00460 {
00461   if ( d->mUpdateGroupLevel > 0 ) {
00462     if ( --d->mUpdateGroupLevel == 0 && d->mUpdatedPending ) {
00463       d->mUpdatedPending = false;
00464       updated();
00465     }
00466   }
00467 }
00468 
00469 void IncidenceBase::customPropertyUpdated()
00470 {
00471   updated();
00472 }
00473 
00474 KUrl IncidenceBase::uri() const
00475 {
00476   return KUrl( QString( "urn:x-ical:" ) + uid() );
00477 }
00478 
00479 bool IncidenceBase::Visitor::visit( Event *event )
00480 {
00481   Q_UNUSED( event );
00482   return false;
00483 }
00484 
00485 bool IncidenceBase::Visitor::visit( Todo *todo )
00486 {
00487   Q_UNUSED( todo );
00488   return false;
00489 }
00490 
00491 bool IncidenceBase::Visitor::visit( Journal *journal )
00492 {
00493   Q_UNUSED( journal );
00494   return false;
00495 }
00496 
00497 bool IncidenceBase::Visitor::visit( FreeBusy *freebusy )
00498 {
00499   Q_UNUSED( freebusy );
00500   return false;
00501 }

KCal Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal