summaryrefslogtreecommitdiffstats
path: root/libkcal/freebusy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libkcal/freebusy.cpp')
-rw-r--r--libkcal/freebusy.cpp224
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() );
+}