diff options
Diffstat (limited to 'libkcal/freebusy.cpp')
-rw-r--r-- | libkcal/freebusy.cpp | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/libkcal/freebusy.cpp b/libkcal/freebusy.cpp new file mode 100644 index 000000000..71f05b35b --- /dev/null +++ b/libkcal/freebusy.cpp @@ -0,0 +1,224 @@ +/* + This file is part of libkcal. + + Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> + Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <kdebug.h> + +#include "freebusy.h" + +using namespace KCal; + +FreeBusy::FreeBusy() +{ +} + +FreeBusy::FreeBusy(const QDateTime &start, const QDateTime &end) +{ + setDtStart(start); + setDtEnd(end); +} + +FreeBusy::FreeBusy( Calendar *calendar, const QDateTime &start, const QDateTime &end ) +{ + kdDebug(5800) << "FreeBusy::FreeBusy" << endl; + mCalendar = calendar; + + setDtStart(start); + setDtEnd(end); + + // Get all the events in the calendar + Event::List eventList = mCalendar->rawEvents( start.date(), end.date() ); + + int extraDays, i, x, duration; + duration = start.daysTo(end); + QDate day; + QDateTime tmpStart; + QDateTime tmpEnd; + // Loops through every event in the calendar + Event::List::ConstIterator it; + for( it = eventList.begin(); it != eventList.end(); ++it ) { + Event *event = *it; + + // The code below can not handle floating events. Fixing this resulted + // in a lot of duplicated code. Instead, make a copy of the event and + // set the period to the full day(s). This trick works for recurring, + // multiday, and single day floating events. + Event *floatingEvent = 0; + if ( event->doesFloat() ) { + // Floating event. Do the hack + kdDebug(5800) << "Floating event\n"; + floatingEvent = new Event( *event ); + + // Set the start and end times to be on midnight + QDateTime start( floatingEvent->dtStart().date(), QTime( 0, 0 ) ); + QDateTime end( floatingEvent->dtEnd().date(), QTime( 23, 59, 59, 999 ) ); + floatingEvent->setFloats( false ); + floatingEvent->setDtStart( start ); + floatingEvent->setDtEnd( end ); + + kdDebug(5800) << "Use: " << start.toString() << " to " << end.toString() + << endl; + // Finally, use this event for the setting below + event = floatingEvent; + } + + // This whole for loop is for recurring events, it loops through + // each of the days of the freebusy request + + // First check if this is transparent. If it is, it shouldn't be in the + // freebusy list + if ( event->transparency() == Event::Transparent ) + // Transparent + continue; + + for( i = 0; i <= duration; ++i ) { + day=(start.addDays(i).date()); + tmpStart.setDate(day); + tmpEnd.setDate(day); + + if( event->doesRecur() ) { + if ( event->isMultiDay() ) { +// FIXME: This doesn't work for sub-daily recurrences or recurrences with +// a different time than the original event. + extraDays = event->dtStart().date().daysTo(event->dtEnd().date()); + for ( x = 0; x <= extraDays; ++x ) { + if ( event->recursOn(day.addDays(-x))) { + tmpStart.setDate(day.addDays(-x)); + tmpStart.setTime(event->dtStart().time()); + tmpEnd=tmpStart.addSecs( (event->duration()) ); + + addLocalPeriod( tmpStart, tmpEnd ); + break; + } + } + } else { + if (event->recursOn(day)) { + tmpStart.setTime(event->dtStart().time()); + tmpEnd.setTime(event->dtEnd().time()); + + addLocalPeriod (tmpStart, tmpEnd); + } + } + } + + } + // Non-recurring events + addLocalPeriod(event->dtStart(), event->dtEnd()); + + // Clean up + delete floatingEvent; + } + + sortList(); +} + +FreeBusy::~FreeBusy() +{ +} + +bool FreeBusy::setDtEnd( const QDateTime &end ) +{ + mDtEnd = end; + return true; +} + +QDateTime FreeBusy::dtEnd() const +{ + return mDtEnd; +} + +PeriodList FreeBusy::busyPeriods() const +{ + return mBusyPeriods; +} + +bool FreeBusy::addLocalPeriod(const QDateTime &eventStart, const QDateTime &eventEnd ) { + QDateTime tmpStart; + QDateTime tmpEnd; + + //Check to see if the start *or* end of the event is + //between the start and end of the freebusy dates. + if ( !( ( ( dtStart().secsTo(eventStart) >= 0 ) && + ( eventStart.secsTo(dtEnd()) >= 0 ) ) + || ( ( dtStart().secsTo(eventEnd) >= 0 ) && + ( eventEnd.secsTo(dtEnd()) >= 0 ) ) ) ) + return false; + + if ( eventStart.secsTo( dtStart() ) >= 0 ) { + tmpStart = dtStart(); + } else { + tmpStart = eventStart; + } + + if ( eventEnd.secsTo( dtEnd() ) <= 0 ) { + tmpEnd = dtEnd(); + } else { + tmpEnd = eventEnd; + } + + Period p(tmpStart, tmpEnd); + mBusyPeriods.append( p ); + + return true; +} + +FreeBusy::FreeBusy( PeriodList busyPeriods) +{ + mBusyPeriods = busyPeriods; +} + +void FreeBusy::sortList() +{ + qHeapSort( mBusyPeriods ); + return; +} + +void FreeBusy::addPeriods(const PeriodList &list ) +{ + mBusyPeriods += list; + sortList(); +} + +void FreeBusy::addPeriod(const QDateTime &start, const QDateTime &end) +{ + mBusyPeriods.append( Period(start, end) ); + sortList(); +} + +void FreeBusy::addPeriod( const QDateTime &start, const Duration &dur ) +{ + mBusyPeriods.append( Period(start, dur) ); + sortList(); +} + +void FreeBusy::merge( FreeBusy *freeBusy ) +{ + if ( freeBusy->dtStart() < dtStart() ) + setDtStart( freeBusy->dtStart() ); + + if ( freeBusy->dtEnd() > dtEnd() ) + setDtEnd( freeBusy->dtEnd() ); + + QValueList<Period> periods = freeBusy->busyPeriods(); + QValueList<Period>::ConstIterator it; + for ( it = periods.begin(); it != periods.end(); ++it ) + addPeriod( (*it).start(), (*it).end() ); +} |