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

KCal Library

freebusy.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) 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 */
00034 #include "freebusy.h"
00035 #include "calendar.h"
00036 #include "event.h"
00037 
00038 #include <kdebug.h>
00039 
00040 #include <QtCore/QList>
00041 
00042 using namespace KCal;
00043 
00044 //@cond PRIVATE
00045 class KCal::FreeBusy::Private
00046 {
00047   public:
00048     Private()
00049       : mCalendar( 0 )
00050     {}
00051 
00052     Private( const KCal::FreeBusy::Private &other )
00053     { init( other ); }
00054 
00055     Private( const FreeBusyPeriod::List &busyPeriods )
00056       : mBusyPeriods( busyPeriods ),
00057         mCalendar( 0 )
00058     {}
00059 
00060     void init( const KCal::FreeBusy::Private &other );
00061 
00062     KDateTime mDtEnd;         // end datetime
00063     FreeBusyPeriod::List mBusyPeriods;// list of periods
00064     Calendar *mCalendar;      // associated calendar, not owned by this instance
00065 
00066     //This is used for creating a freebusy object for the current user
00067     bool addLocalPeriod( FreeBusy *fb, const KDateTime &start, const KDateTime &end );
00068 };
00069 
00070 void KCal::FreeBusy::Private::init( const KCal::FreeBusy::Private &other )
00071 {
00072   mDtEnd = other.mDtEnd;
00073   mBusyPeriods = other.mBusyPeriods;
00074   mCalendar = other.mCalendar;
00075 }
00076 
00077 //@endcond
00078 
00079 FreeBusy::FreeBusy()
00080   : d( new KCal::FreeBusy::Private() )
00081 {
00082 }
00083 
00084 FreeBusy::FreeBusy( const FreeBusy &other )
00085   : IncidenceBase( other ),
00086     d( new KCal::FreeBusy::Private( *other.d ) )
00087 {
00088 }
00089 
00090 FreeBusy::FreeBusy( const KDateTime &start, const KDateTime &end )
00091   : d( new KCal::FreeBusy::Private() )
00092 {
00093   setDtStart( start );
00094   setDtEnd( end );
00095 }
00096 
00097 FreeBusy::FreeBusy( Calendar *calendar, const KDateTime &start, const KDateTime &end )
00098   : d( new KCal::FreeBusy::Private() )
00099 {
00100   kDebug();
00101   d->mCalendar = calendar;
00102 
00103   setDtStart( start );
00104   setDtEnd( end );
00105 
00106   // Get all the events in the calendar
00107   Event::List eventList = d->mCalendar->rawEvents( start.date(), end.date() );
00108 
00109   int extraDays, i, x, duration;
00110   duration = start.daysTo( end );
00111   QDate day;
00112   KDateTime tmpStart;
00113   KDateTime tmpEnd;
00114 
00115   // Loops through every event in the calendar
00116   Event::List::ConstIterator it;
00117   for ( it = eventList.begin(); it != eventList.end(); ++it ) {
00118     Event *event = *it;
00119 
00120     // The code below can not handle all-dayevents. Fixing this resulted
00121     // in a lot of duplicated code. Instead, make a copy of the event and
00122     // set the period to the full day(s). This trick works for recurring,
00123     // multiday, and single day all-day events.
00124     Event *allDayEvent = 0;
00125     if ( event->allDay() ) {
00126       // addDay event. Do the hack
00127       kDebug() << "All-day event";
00128       allDayEvent = new Event( *event );
00129 
00130       // Set the start and end times to be on midnight
00131       KDateTime st = allDayEvent->dtStart();
00132       st.setTime( QTime( 0, 0 ) );
00133       KDateTime nd = allDayEvent->dtEnd();
00134       nd.setTime( QTime( 23, 59, 59, 999 ) );
00135       allDayEvent->setAllDay( false );
00136       allDayEvent->setDtStart( st );
00137       allDayEvent->setDtEnd( nd );
00138 
00139       kDebug() << "Use:" << st.toString() << "to" << nd.toString();
00140       // Finally, use this event for the setting below
00141       event = allDayEvent;
00142     }
00143 
00144     // This whole for loop is for recurring events, it loops through
00145     // each of the days of the freebusy request
00146 
00147     // If this event is transparent it shouldn't be in the freebusy list.
00148     if ( event->transparency() == Event::Transparent ) {
00149       continue;
00150     }
00151 
00152     for ( i = 0; i <= duration; ++i ) {
00153       day = start.addDays(i).date();
00154       tmpStart.setDate( day );
00155       tmpEnd.setDate( day );
00156 
00157       if ( event->recurs() ) {
00158         if ( event->isMultiDay() ) {
00159 // FIXME: This doesn't work for sub-daily recurrences or recurrences with
00160 //        a different time than the original event.
00161           extraDays = event->dtStart().daysTo( event->dtEnd() );
00162           for ( x = 0; x <= extraDays; ++x ) {
00163             if ( event->recursOn( day.addDays(-x), start.timeSpec() ) ) {
00164               tmpStart.setDate( day.addDays(-x) );
00165               tmpStart.setTime( event->dtStart().time() );
00166               tmpEnd = event->duration().end( tmpStart );
00167 
00168               d->addLocalPeriod( this, tmpStart, tmpEnd );
00169               break;
00170             }
00171           }
00172         } else {
00173           if ( event->recursOn( day, start.timeSpec() ) ) {
00174             tmpStart.setTime( event->dtStart().time() );
00175             tmpEnd.setTime( event->dtEnd().time() );
00176 
00177             d->addLocalPeriod ( this, tmpStart, tmpEnd );
00178           }
00179         }
00180       }
00181 
00182     }
00183     // Non-recurring events
00184     d->addLocalPeriod( this, event->dtStart(), event->dtEnd() );
00185 
00186     // Clean up
00187     delete allDayEvent;
00188   }
00189 
00190   sortList();
00191 }
00192 
00193 FreeBusy::FreeBusy( const Period::List &busyPeriods )
00194   : d( new KCal::FreeBusy::Private() )
00195 {
00196   addPeriods(busyPeriods);
00197 }
00198 
00199 FreeBusy::FreeBusy( const FreeBusyPeriod::List &busyPeriods )
00200   : d( new KCal::FreeBusy::Private( busyPeriods ) )
00201 {
00202 }
00203 
00204 FreeBusy::~FreeBusy()
00205 {
00206   delete d;
00207 }
00208 
00209 QByteArray FreeBusy::type() const
00210 {
00211   return "FreeBusy";
00212 }
00213 
00214 void FreeBusy::setDtStart( const KDateTime &start )
00215 {
00216   IncidenceBase::setDtStart( start.toUtc() );
00217   updated();
00218 }
00219 
00220 void FreeBusy::setDtEnd( const KDateTime &end )
00221 {
00222   d->mDtEnd = end;
00223 }
00224 
00225 KDateTime FreeBusy::dtEnd() const
00226 {
00227   return d->mDtEnd;
00228 }
00229 
00230 Period::List FreeBusy::busyPeriods() const
00231 {
00232   Period::List res;
00233 
00234   foreach ( const FreeBusyPeriod &p, d->mBusyPeriods ) {
00235     res << p;
00236   }
00237 
00238   return res;
00239 }
00240 
00241 FreeBusyPeriod::List FreeBusy::fullBusyPeriods() const
00242 {
00243   return d->mBusyPeriods;
00244 }
00245 
00246 void FreeBusy::sortList()
00247 {
00248   qSort( d->mBusyPeriods );
00249   return;
00250 }
00251 
00252 void FreeBusy::addPeriods( const Period::List &list )
00253 {
00254   foreach ( const Period &p, list ) {
00255     d->mBusyPeriods << FreeBusyPeriod(p);
00256   }
00257   sortList();
00258 }
00259 
00260 void FreeBusy::addPeriods( const FreeBusyPeriod::List &list )
00261 {
00262   d->mBusyPeriods += list;
00263   sortList();
00264 }
00265 
00266 void FreeBusy::addPeriod( const KDateTime &start, const KDateTime &end )
00267 {
00268   d->mBusyPeriods.append( FreeBusyPeriod( start, end ) );
00269   sortList();
00270 }
00271 
00272 void FreeBusy::addPeriod( const KDateTime &start, const Duration &duration )
00273 {
00274   d->mBusyPeriods.append( FreeBusyPeriod( start, duration ) );
00275   sortList();
00276 }
00277 
00278 void FreeBusy::merge( FreeBusy *freeBusy )
00279 {
00280   if ( freeBusy->dtStart() < dtStart() ) {
00281     setDtStart( freeBusy->dtStart() );
00282   }
00283 
00284   if ( freeBusy->dtEnd() > dtEnd() ) {
00285     setDtEnd( freeBusy->dtEnd() );
00286   }
00287 
00288   Period::List periods = freeBusy->busyPeriods();
00289   Period::List::ConstIterator it;
00290   for ( it = periods.begin(); it != periods.end(); ++it ) {
00291     addPeriod( (*it).start(), (*it).end() );
00292   }
00293 }
00294 
00295 void FreeBusy::shiftTimes( const KDateTime::Spec &oldSpec,
00296                            const KDateTime::Spec &newSpec )
00297 {
00298   IncidenceBase::shiftTimes( oldSpec, newSpec );
00299   d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
00300   d->mDtEnd.setTimeSpec( newSpec );
00301   for ( int i = 0, end = d->mBusyPeriods.count();  i < end;  ++end ) {
00302     d->mBusyPeriods[i].shiftTimes( oldSpec, newSpec );
00303   }
00304 }
00305 
00306 FreeBusy &FreeBusy::operator=( const FreeBusy &other )
00307 {
00308   IncidenceBase::operator=( other );
00309   d->init( *other.d );
00310   return *this;
00311 }
00312 
00313 bool FreeBusy::operator==( const FreeBusy &freebusy ) const
00314 {
00315   return
00316     static_cast<const IncidenceBase &>( *this ) == static_cast<const IncidenceBase &>( freebusy ) &&
00317     dtEnd() == freebusy.dtEnd() &&
00318     d->mCalendar == freebusy.d->mCalendar &&
00319     d->mBusyPeriods == freebusy.d->mBusyPeriods;
00320 }
00321 
00322 //@cond PRIVATE
00323 bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
00324                                         const KDateTime &eventStart,
00325                                         const KDateTime &eventEnd )
00326 {
00327   KDateTime tmpStart;
00328   KDateTime tmpEnd;
00329 
00330   //Check to see if the start *or* end of the event is
00331   //between the start and end of the freebusy dates.
00332   KDateTime start = fb->dtStart();
00333   if ( !( ( ( start.secsTo(eventStart) >= 0 ) &&
00334             ( eventStart.secsTo(mDtEnd) >= 0 ) ) ||
00335           ( ( start.secsTo(eventEnd) >= 0 ) &&
00336             ( eventEnd.secsTo(mDtEnd) >= 0 ) ) ) ) {
00337     return false;
00338   }
00339 
00340   if ( eventStart.secsTo( start ) >= 0 ) {
00341     tmpStart = start;
00342   } else {
00343     tmpStart = eventStart;
00344   }
00345 
00346   if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
00347     tmpEnd = mDtEnd;
00348   } else {
00349     tmpEnd = eventEnd;
00350   }
00351 
00352   FreeBusyPeriod p( tmpStart, tmpEnd );
00353   mBusyPeriods.append( p );
00354 
00355   return true;
00356 }
00357 //@endcond

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
  • 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.4
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