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

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"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.1
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