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