libkcal

freebusy.cpp
1 /*
2  This file is part of libkcal.
3 
4  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5  Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include <kdebug.h>
24 
25 #include "freebusy.h"
26 
27 using namespace KCal;
28 
29 FreeBusy::FreeBusy()
30 {
31 }
32 
33 FreeBusy::FreeBusy(const TQDateTime &start, const TQDateTime &end)
34 {
35  setDtStart(start);
36  setDtEnd(end);
37 }
38 
39 FreeBusy::FreeBusy( Calendar *calendar, const TQDateTime &start, const TQDateTime &end )
40 {
41  kdDebug(5800) << "FreeBusy::FreeBusy" << endl;
42  mCalendar = calendar;
43 
44  setDtStart(start);
45  setDtEnd(end);
46 
47  // Get all the events in the calendar
48  Event::List eventList = mCalendar->rawEvents( start.date(), end.date() );
49 
50  int extraDays, i, x, duration;
51  duration = start.daysTo(end);
52  TQDate day;
53  TQDateTime tmpStart;
54  TQDateTime tmpEnd;
55  // Loops through every event in the calendar
56  Event::List::ConstIterator it;
57  for( it = eventList.begin(); it != eventList.end(); ++it ) {
58  Event *event = *it;
59 
60  // The code below can not handle floating events. Fixing this resulted
61  // in a lot of duplicated code. Instead, make a copy of the event and
62  // set the period to the full day(s). This trick works for recurring,
63  // multiday, and single day floating events.
64  Event *floatingEvent = 0;
65  if ( event->doesFloat() ) {
66  // Floating event. Do the hack
67  kdDebug(5800) << "Floating event\n";
68  floatingEvent = new Event( *event );
69 
70  // Set the start and end times to be on midnight
71  TQDateTime start( floatingEvent->dtStart().date(), TQTime( 0, 0 ) );
72  TQDateTime end( floatingEvent->dtEnd().date(), TQTime( 23, 59, 59, 999 ) );
73  floatingEvent->setFloats( false );
74  floatingEvent->setDtStart( start );
75  floatingEvent->setDtEnd( end );
76 
77  kdDebug(5800) << "Use: " << start.toString() << " to " << end.toString()
78  << endl;
79  // Finally, use this event for the setting below
80  event = floatingEvent;
81  }
82 
83  // This whole for loop is for recurring events, it loops through
84  // each of the days of the freebusy request
85 
86  // First check if this is transparent. If it is, it shouldn't be in the
87  // freebusy list
88  if ( event->transparency() == Event::Transparent )
89  // Transparent
90  continue;
91 
92  for( i = 0; i <= duration; ++i ) {
93  day=(start.addDays(i).date());
94  tmpStart.setDate(day);
95  tmpEnd.setDate(day);
96 
97  if( event->doesRecur() ) {
98  if ( event->isMultiDay() ) {
99 // FIXME: This doesn't work for sub-daily recurrences or recurrences with
100 // a different time than the original event.
101  extraDays = event->dtStart().date().daysTo(event->dtEnd().date());
102  for ( x = 0; x <= extraDays; ++x ) {
103  if ( event->recursOn(day.addDays(-x))) {
104  tmpStart.setDate(day.addDays(-x));
105  tmpStart.setTime(event->dtStart().time());
106  tmpEnd=tmpStart.addSecs( (event->duration()) );
107 
108  addLocalPeriod( tmpStart, tmpEnd );
109  break;
110  }
111  }
112  } else {
113  if (event->recursOn(day)) {
114  tmpStart.setTime(event->dtStart().time());
115  tmpEnd.setTime(event->dtEnd().time());
116 
117  addLocalPeriod (tmpStart, tmpEnd);
118  }
119  }
120  }
121 
122  }
123  // Non-recurring events
124  addLocalPeriod(event->dtStart(), event->dtEnd());
125 
126  // Clean up
127  delete floatingEvent;
128  }
129 
130  sortList();
131 }
132 
133 FreeBusy::~FreeBusy()
134 {
135 }
136 
137 bool FreeBusy::setDtEnd( const TQDateTime &end )
138 {
139  mDtEnd = end;
140  return true;
141 }
142 
143 TQDateTime FreeBusy::dtEnd() const
144 {
145  return mDtEnd;
146 }
147 
148 PeriodList FreeBusy::busyPeriods() const
149 {
150  return mBusyPeriods;
151 }
152 
153 bool FreeBusy::addLocalPeriod(const TQDateTime &eventStart, const TQDateTime &eventEnd ) {
154  TQDateTime tmpStart;
155  TQDateTime tmpEnd;
156 
157  //Check to see if the start *or* end of the event is
158  //between the start and end of the freebusy dates.
159  if ( !( ( ( dtStart().secsTo(eventStart) >= 0 ) &&
160  ( eventStart.secsTo(dtEnd()) >= 0 ) )
161  || ( ( dtStart().secsTo(eventEnd) >= 0 ) &&
162  ( eventEnd.secsTo(dtEnd()) >= 0 ) ) ) )
163  return false;
164 
165  if ( eventStart.secsTo( dtStart() ) >= 0 ) {
166  tmpStart = dtStart();
167  } else {
168  tmpStart = eventStart;
169  }
170 
171  if ( eventEnd.secsTo( dtEnd() ) <= 0 ) {
172  tmpEnd = dtEnd();
173  } else {
174  tmpEnd = eventEnd;
175  }
176 
177  Period p(tmpStart, tmpEnd);
178  mBusyPeriods.append( p );
179 
180  return true;
181 }
182 
183 FreeBusy::FreeBusy( PeriodList busyPeriods)
184 {
185  mBusyPeriods = busyPeriods;
186 }
187 
188 void FreeBusy::sortList()
189 {
190  qHeapSort( mBusyPeriods );
191  return;
192 }
193 
194 void FreeBusy::addPeriods(const PeriodList &list )
195 {
196  mBusyPeriods += list;
197  sortList();
198 }
199 
200 void FreeBusy::addPeriod(const TQDateTime &start, const TQDateTime &end)
201 {
202  mBusyPeriods.append( Period(start, end) );
203  sortList();
204 }
205 
206 void FreeBusy::addPeriod( const TQDateTime &start, const Duration &dur )
207 {
208  mBusyPeriods.append( Period(start, dur) );
209  sortList();
210 }
211 
212 void FreeBusy::merge( FreeBusy *freeBusy )
213 {
214  if ( freeBusy->dtStart() < dtStart() )
215  setDtStart( freeBusy->dtStart() );
216 
217  if ( freeBusy->dtEnd() > dtEnd() )
218  setDtEnd( freeBusy->dtEnd() );
219 
220  TQValueList<Period> periods = freeBusy->busyPeriods();
221  TQValueList<Period>::ConstIterator it;
222  for ( it = periods.begin(); it != periods.end(); ++it )
223  addPeriod( (*it).start(), (*it).end() );
224 }
225 
226 bool FreeBusy::operator==( const FreeBusy &freebusy ) const
227 {
228  return
229  static_cast<const IncidenceBase &>( *this ) == static_cast<const IncidenceBase &>( freebusy ) &&
230  dtEnd() == freebusy.dtEnd() &&
231  mCalendar == freebusy.mCalendar &&
232  mBusyPeriods == freebusy.mBusyPeriods;
233 }
This is the main "calendar" object class.
Definition: calendar.h:171
virtual Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Events for this Calendar.
This class represents a duration.
Definition: duration.h:34
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
virtual TQDateTime dtEnd() const
Return end date and time.
Definition: event.cpp:85
void setDtEnd(const TQDateTime &dtEnd)
Set end date and time.
Definition: event.cpp:73
This class provides information about free/busy time of a calendar user.
Definition: freebusy.h:41
void addPeriod(const TQDateTime &start, const TQDateTime &end)
Adds a period to the freebusy list and sorts the list.
Definition: freebusy.cpp:200
void addPeriods(const PeriodList &)
Adds a list of periods to the freebusy object and then sorts that list.
Definition: freebusy.cpp:194
bool operator==(const FreeBusy &freebusy) const
Compare this with freebusy for equality.
Definition: freebusy.cpp:226
This class provides the base class common to all calendar components.
Definition: incidencebase.h:46
virtual TQDateTime dtStart() const
returns an event's starting date/time as a TQDateTime.
virtual void setDtStart(const TQDateTime &dtStart)
for setting the event's starting date/time with a TQDateTime.
void setFloats(bool f)
Set whether the incidence floats, i.e.
Definition: incidence.cpp:229
virtual void setDtStart(const TQDateTime &dtStart)
Set starting date/time.
Definition: incidence.cpp:264
This class represents a period of time.
Definition: period.h:36
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38