You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
6.0 KiB
225 lines
6.0 KiB
/*
|
|
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() );
|
|
}
|