• Skip to content
  • Skip to link menu
KDE 4.3 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;
00108   if ( d->mCalendar ) {
00109     eventList = d->mCalendar->rawEvents( start.date(), end.date() );
00110   }
00111 
00112   int extraDays, i, x, duration;
00113   duration = start.daysTo( end );
00114   QDate day;
00115   KDateTime tmpStart;
00116   KDateTime tmpEnd;
00117 
00118   // Loops through every event in the calendar
00119   Event::List::ConstIterator it;
00120   for ( it = eventList.constBegin(); it != eventList.constEnd(); ++it ) {
00121     Event *event = *it;
00122 
00123     // The code below can not handle all-dayevents. Fixing this resulted
00124     // in a lot of duplicated code. Instead, make a copy of the event and
00125     // set the period to the full day(s). This trick works for recurring,
00126     // multiday, and single day all-day events.
00127     Event *allDayEvent = 0;
00128     if ( event->allDay() ) {
00129       // addDay event. Do the hack
00130       kDebug() << "All-day event";
00131       allDayEvent = new Event( *event );
00132 
00133       // Set the start and end times to be on midnight
00134       KDateTime st = allDayEvent->dtStart();
00135       st.setTime( QTime( 0, 0 ) );
00136       KDateTime nd = allDayEvent->dtEnd();
00137       nd.setTime( QTime( 23, 59, 59, 999 ) );
00138       allDayEvent->setAllDay( false );
00139       allDayEvent->setDtStart( st );
00140       allDayEvent->setDtEnd( nd );
00141 
00142       kDebug() << "Use:" << st.toString() << "to" << nd.toString();
00143       // Finally, use this event for the setting below
00144       event = allDayEvent;
00145     }
00146 
00147     // This whole for loop is for recurring events, it loops through
00148     // each of the days of the freebusy request
00149 
00150     // If this event is transparent it shouldn't be in the freebusy list.
00151     if ( event->transparency() == Event::Transparent ) {
00152       continue;
00153     }
00154 
00155     for ( i = 0; i <= duration; ++i ) {
00156       day = start.addDays(i).date();
00157       tmpStart.setDate( day );
00158       tmpEnd.setDate( day );
00159 
00160       if ( event->recurs() ) {
00161         if ( event->isMultiDay() ) {
00162 // FIXME: This doesn't work for sub-daily recurrences or recurrences with
00163 //        a different time than the original event.
00164           extraDays = event->dtStart().daysTo( event->dtEnd() );
00165           for ( x = 0; x <= extraDays; ++x ) {
00166             if ( event->recursOn( day.addDays(-x), start.timeSpec() ) ) {
00167               tmpStart.setDate( day.addDays(-x) );
00168               tmpStart.setTime( event->dtStart().time() );
00169               tmpEnd = event->duration().end( tmpStart );
00170 
00171               d->addLocalPeriod( this, tmpStart, tmpEnd );
00172               break;
00173             }
00174           }
00175         } else {
00176           if ( event->recursOn( day, start.timeSpec() ) ) {
00177             tmpStart.setTime( event->dtStart().time() );
00178             tmpEnd.setTime( event->dtEnd().time() );
00179 
00180             d->addLocalPeriod ( this, tmpStart, tmpEnd );
00181           }
00182         }
00183       }
00184 
00185     }
00186     // Non-recurring events
00187     d->addLocalPeriod( this, event->dtStart(), event->dtEnd() );
00188 
00189     // Clean up
00190     delete allDayEvent;
00191   }
00192 
00193   sortList();
00194 }
00195 
00196 FreeBusy::FreeBusy( const Period::List &busyPeriods )
00197   : d( new KCal::FreeBusy::Private() )
00198 {
00199   addPeriods(busyPeriods);
00200 }
00201 
00202 FreeBusy::FreeBusy( const FreeBusyPeriod::List &busyPeriods )
00203   : d( new KCal::FreeBusy::Private( busyPeriods ) )
00204 {
00205 }
00206 
00207 FreeBusy::~FreeBusy()
00208 {
00209   delete d;
00210 }
00211 
00212 QByteArray FreeBusy::type() const
00213 {
00214   return "FreeBusy";
00215 }
00216 
00217 void FreeBusy::setDtStart( const KDateTime &start )
00218 {
00219   IncidenceBase::setDtStart( start.toUtc() );
00220   updated();
00221 }
00222 
00223 void FreeBusy::setDtEnd( const KDateTime &end )
00224 {
00225   d->mDtEnd = end;
00226 }
00227 
00228 KDateTime FreeBusy::dtEnd() const
00229 {
00230   return d->mDtEnd;
00231 }
00232 
00233 Period::List FreeBusy::busyPeriods() const
00234 {
00235   Period::List res;
00236 
00237   foreach ( const FreeBusyPeriod &p, d->mBusyPeriods ) {
00238     res << p;
00239   }
00240 
00241   return res;
00242 }
00243 
00244 FreeBusyPeriod::List FreeBusy::fullBusyPeriods() const
00245 {
00246   return d->mBusyPeriods;
00247 }
00248 
00249 void FreeBusy::sortList()
00250 {
00251   qSort( d->mBusyPeriods );
00252   return;
00253 }
00254 
00255 void FreeBusy::addPeriods( const Period::List &list )
00256 {
00257   foreach ( const Period &p, list ) {
00258     d->mBusyPeriods << FreeBusyPeriod( p );
00259   }
00260   sortList();
00261 }
00262 
00263 void FreeBusy::addPeriods( const FreeBusyPeriod::List &list )
00264 {
00265   d->mBusyPeriods += list;
00266   sortList();
00267 }
00268 
00269 void FreeBusy::addPeriod( const KDateTime &start, const KDateTime &end )
00270 {
00271   d->mBusyPeriods.append( FreeBusyPeriod( start, end ) );
00272   sortList();
00273 }
00274 
00275 void FreeBusy::addPeriod( const KDateTime &start, const Duration &duration )
00276 {
00277   d->mBusyPeriods.append( FreeBusyPeriod( start, duration ) );
00278   sortList();
00279 }
00280 
00281 void FreeBusy::merge( FreeBusy *freeBusy )
00282 {
00283   if ( freeBusy->dtStart() < dtStart() ) {
00284     setDtStart( freeBusy->dtStart() );
00285   }
00286 
00287   if ( freeBusy->dtEnd() > dtEnd() ) {
00288     setDtEnd( freeBusy->dtEnd() );
00289   }
00290 
00291   Period::List periods = freeBusy->busyPeriods();
00292   Period::List::ConstIterator it;
00293   for ( it = periods.constBegin(); it != periods.constEnd(); ++it ) {
00294     addPeriod( (*it).start(), (*it).end() );
00295   }
00296 }
00297 
00298 void FreeBusy::shiftTimes( const KDateTime::Spec &oldSpec,
00299                            const KDateTime::Spec &newSpec )
00300 {
00301   if ( oldSpec.isValid() && newSpec.isValid() && oldSpec != newSpec ) {
00302     IncidenceBase::shiftTimes( oldSpec, newSpec );
00303     d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
00304     d->mDtEnd.setTimeSpec( newSpec );
00305     foreach ( FreeBusyPeriod p, d->mBusyPeriods ) { //krazy:exclude=foreach
00306       p.shiftTimes( oldSpec, newSpec );
00307     }
00308   }
00309 }
00310 
00311 FreeBusy &FreeBusy::operator=( const FreeBusy &other )
00312 {
00313   // check for self assignment
00314   if ( &other == this ) {
00315     return *this;
00316   }
00317 
00318   IncidenceBase::operator=( other );
00319   d->init( *other.d );
00320   return *this;
00321 }
00322 
00323 bool FreeBusy::operator==( const FreeBusy &freebusy ) const
00324 {
00325   return
00326     IncidenceBase::operator==( freebusy ) &&
00327     dtEnd() == freebusy.dtEnd() &&
00328     d->mCalendar == freebusy.d->mCalendar &&
00329     d->mBusyPeriods == freebusy.d->mBusyPeriods;
00330 }
00331 
00332 //@cond PRIVATE
00333 bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
00334                                         const KDateTime &eventStart,
00335                                         const KDateTime &eventEnd )
00336 {
00337   KDateTime tmpStart;
00338   KDateTime tmpEnd;
00339 
00340   //Check to see if the start *or* end of the event is
00341   //between the start and end of the freebusy dates.
00342   KDateTime start = fb->dtStart();
00343   if ( !( ( ( start.secsTo(eventStart) >= 0 ) &&
00344             ( eventStart.secsTo(mDtEnd) >= 0 ) ) ||
00345           ( ( start.secsTo(eventEnd) >= 0 ) &&
00346             ( eventEnd.secsTo(mDtEnd) >= 0 ) ) ) ) {
00347     return false;
00348   }
00349 
00350   if ( eventStart.secsTo( start ) >= 0 ) {
00351     tmpStart = start;
00352   } else {
00353     tmpStart = eventStart;
00354   }
00355 
00356   if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
00357     tmpEnd = mDtEnd;
00358   } else {
00359     tmpEnd = eventEnd;
00360   }
00361 
00362   FreeBusyPeriod p( tmpStart, tmpEnd );
00363   mBusyPeriods.append( p );
00364 
00365   return true;
00366 }
00367 //@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
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • 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