• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.10.5 API Reference
  • KDE Home
  • Contact Us
 

KCal Library

  • kcal
freebusy.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcal library.
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 */
34 #include "freebusy.h"
35 #include "calendar.h"
36 #include "event.h"
37 
38 #include <kdebug.h>
39 #include <klocale.h>
40 
41 using namespace KCal;
42 
43 //@cond PRIVATE
44 class KCal::FreeBusy::Private
45 {
46  private:
47  FreeBusy *const q;
48  public:
49  Private( FreeBusy *qq ) : q( qq )
50  {}
51 
52  Private( const KCal::FreeBusy::Private &other, FreeBusy *qq ) : q( qq )
53  { init( other ); }
54 
55  Private( const FreeBusyPeriod::List &busyPeriods, FreeBusy *qq )
56  : q( qq ), mBusyPeriods( busyPeriods )
57  {}
58 
59  void init( const KCal::FreeBusy::Private &other );
60  void init( const Event::List &events, const KDateTime &start, const KDateTime &end );
61 
62  KDateTime mDtEnd; // end datetime
63  FreeBusyPeriod::List mBusyPeriods; // list of periods
64 
65  // This is used for creating a freebusy object for the current user
66  bool addLocalPeriod( FreeBusy *fb, const KDateTime &start, const KDateTime &end );
67 };
68 
69 void KCal::FreeBusy::Private::init( const KCal::FreeBusy::Private &other )
70 {
71  mDtEnd = other.mDtEnd;
72  mBusyPeriods = other.mBusyPeriods;
73 }
74 //@endcond
75 
76 FreeBusy::FreeBusy()
77  : d( new KCal::FreeBusy::Private( this ) )
78 {
79 }
80 
81 FreeBusy::FreeBusy( const FreeBusy &other )
82  : IncidenceBase( other ),
83  d( new KCal::FreeBusy::Private( *other.d, this ) )
84 {
85 }
86 
87 FreeBusy::FreeBusy( const KDateTime &start, const KDateTime &end )
88  : d( new KCal::FreeBusy::Private( this ) )
89 {
90  setDtStart( start );
91  setDtEnd( end );
92 }
93 
94 FreeBusy::FreeBusy( const Event::List &events, const KDateTime &start, const KDateTime &end )
95  : d( new KCal::FreeBusy::Private( this ) )
96 {
97  setDtStart( start );
98  setDtEnd( end );
99 
100  d->init( events, start, end );
101 }
102 
103 void FreeBusy::Private::init( const Event::List &eventList,
104  const KDateTime &start, const KDateTime &end )
105 {
106  int extraDays, i, x, duration;
107  duration = start.daysTo( end );
108  QDate day;
109  KDateTime tmpStart;
110  KDateTime tmpEnd;
111 
112  // Loops through every event in the calendar
113  Event::List::ConstIterator it;
114  for ( it = eventList.constBegin(); it != eventList.constEnd(); ++it ) {
115  Event *event = *it;
116 
117  // If this event is transparent it shouldn't be in the freebusy list.
118  if ( event->transparency() == Event::Transparent ) {
119  continue;
120  }
121 
122  // The code below can not handle all-day events. Fixing this resulted
123  // in a lot of duplicated code. Instead, make a copy of the event and
124  // set the period to the full day(s). This trick works for recurring,
125  // multiday, and single day all-day events.
126  Event *allDayEvent = 0;
127  if ( event->allDay() ) {
128  // addDay event. Do the hack
129  kDebug() << "All-day event";
130  allDayEvent = new Event( *event );
131 
132  // Set the start and end times to be on midnight
133  KDateTime st = allDayEvent->dtStart();
134  st.setTime( QTime( 0, 0 ) );
135  KDateTime nd = allDayEvent->dtEnd();
136  nd.setTime( QTime( 23, 59, 59, 999 ) );
137  allDayEvent->setAllDay( false );
138  allDayEvent->setDtStart( st );
139  allDayEvent->setDtEnd( nd );
140 
141  kDebug() << "Use:" << st.toString() << "to" << nd.toString();
142  // Finally, use this event for the setting below
143  event = allDayEvent;
144  }
145 
146  // This whole for loop is for recurring events, it loops through
147  // each of the days of the freebusy request
148 
149  for ( i = 0; i <= duration; ++i ) {
150  day = start.addDays(i).date();
151  tmpStart.setDate( day );
152  tmpEnd.setDate( day );
153 
154  if ( event->recurs() ) {
155  if ( event->isMultiDay() ) {
156  // FIXME: This doesn't work for sub-daily recurrences or recurrences with
157  // a different time than the original event.
158  extraDays = event->dtStart().daysTo( event->dtEnd() );
159  for ( x = 0; x <= extraDays; ++x ) {
160  if ( event->recursOn( day.addDays(-x), start.timeSpec() ) ) {
161  tmpStart.setDate( day.addDays(-x) );
162  tmpStart.setTime( event->dtStart().time() );
163  tmpEnd = event->duration().end( tmpStart );
164 
165  addLocalPeriod( q, tmpStart, tmpEnd );
166  break;
167  }
168  }
169  } else {
170  if ( event->recursOn( day, start.timeSpec() ) ) {
171  tmpStart.setTime( event->dtStart().time() );
172  tmpEnd.setTime( event->dtEnd().time() );
173 
174  addLocalPeriod ( q, tmpStart, tmpEnd );
175  }
176  }
177  }
178 
179  }
180  // Non-recurring events
181  addLocalPeriod( q, event->dtStart(), event->dtEnd() );
182 
183  // Clean up
184  delete allDayEvent;
185  }
186 
187  q->sortList();
188 }
189 
190 FreeBusy::FreeBusy( Calendar *calendar, const KDateTime &start, const KDateTime &end )
191  : d( new KCal::FreeBusy::Private( this ) )
192 {
193  kDebug();
194 
195  setDtStart( start );
196  setDtEnd( end );
197 
198  d->init( calendar ? calendar->rawEvents( start.date(), end.date() ) : Event::List(), start, end );
199 }
200 
201 FreeBusy::FreeBusy( const Period::List &busyPeriods )
202  : d( new KCal::FreeBusy::Private( this ) )
203 {
204  addPeriods(busyPeriods);
205 }
206 
207 FreeBusy::FreeBusy( const FreeBusyPeriod::List &busyPeriods )
208  : d( new KCal::FreeBusy::Private( busyPeriods, this ) )
209 {
210 }
211 
212 FreeBusy::~FreeBusy()
213 {
214  delete d;
215 }
216 
217 QByteArray FreeBusy::type() const
218 {
219  return "FreeBusy";
220 }
221 
222 //KDE5:
223 //QString FreeBusy::typeStr() const
224 //{
225 // return i18nc( "incidence type is freebusy", "free/busy" );
226 //}
227 
228 void FreeBusy::setDtStart( const KDateTime &start )
229 {
230  IncidenceBase::setDtStart( start.toUtc() );
231  updated();
232 }
233 
234 void FreeBusy::setDtEnd( const KDateTime &end )
235 {
236  d->mDtEnd = end;
237 }
238 
239 KDateTime FreeBusy::dtEnd() const
240 {
241  return d->mDtEnd;
242 }
243 
244 Period::List FreeBusy::busyPeriods() const
245 {
246  Period::List res;
247 
248  foreach ( const FreeBusyPeriod &p, d->mBusyPeriods ) {
249  res << p;
250  }
251 
252  return res;
253 }
254 
255 FreeBusyPeriod::List FreeBusy::fullBusyPeriods() const
256 {
257  return d->mBusyPeriods;
258 }
259 
260 void FreeBusy::sortList()
261 {
262  qSort( d->mBusyPeriods );
263  return;
264 }
265 
266 void FreeBusy::addPeriods( const Period::List &list )
267 {
268  foreach ( const Period &p, list ) {
269  d->mBusyPeriods << FreeBusyPeriod( p );
270  }
271  sortList();
272 }
273 
274 void FreeBusy::addPeriods( const FreeBusyPeriod::List &list )
275 {
276  d->mBusyPeriods += list;
277  sortList();
278 }
279 
280 void FreeBusy::addPeriod( const KDateTime &start, const KDateTime &end )
281 {
282  d->mBusyPeriods.append( FreeBusyPeriod( start, end ) );
283  sortList();
284 }
285 
286 void FreeBusy::addPeriod( const KDateTime &start, const Duration &duration )
287 {
288  d->mBusyPeriods.append( FreeBusyPeriod( start, duration ) );
289  sortList();
290 }
291 
292 void FreeBusy::merge( FreeBusy *freeBusy )
293 {
294  if ( freeBusy->dtStart() < dtStart() ) {
295  setDtStart( freeBusy->dtStart() );
296  }
297 
298  if ( freeBusy->dtEnd() > dtEnd() ) {
299  setDtEnd( freeBusy->dtEnd() );
300  }
301 
302  Period::List periods = freeBusy->busyPeriods();
303  Period::List::ConstIterator it;
304  for ( it = periods.constBegin(); it != periods.constEnd(); ++it ) {
305  d->mBusyPeriods.append( FreeBusyPeriod( (*it).start(), (*it).end() ) );
306  }
307  sortList();
308 }
309 
310 void FreeBusy::shiftTimes( const KDateTime::Spec &oldSpec,
311  const KDateTime::Spec &newSpec )
312 {
313  if ( oldSpec.isValid() && newSpec.isValid() && oldSpec != newSpec ) {
314  IncidenceBase::shiftTimes( oldSpec, newSpec );
315  d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
316  d->mDtEnd.setTimeSpec( newSpec );
317  foreach ( FreeBusyPeriod p, d->mBusyPeriods ) { //krazy:exclude=foreach
318  p.shiftTimes( oldSpec, newSpec );
319  }
320  }
321 }
322 
323 FreeBusy &FreeBusy::operator=( const FreeBusy &other )
324 {
325  // check for self assignment
326  if ( &other == this ) {
327  return *this;
328  }
329 
330  IncidenceBase::operator=( other );
331  d->init( *other.d );
332  return *this;
333 }
334 
335 bool FreeBusy::operator==( const FreeBusy &freebusy ) const
336 {
337  return
338  IncidenceBase::operator==( freebusy ) &&
339  dtEnd() == freebusy.dtEnd() &&
340  d->mBusyPeriods == freebusy.d->mBusyPeriods;
341 }
342 
343 //@cond PRIVATE
344 bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
345  const KDateTime &eventStart,
346  const KDateTime &eventEnd )
347 {
348  KDateTime tmpStart;
349  KDateTime tmpEnd;
350 
351  //Check to see if the start *or* end of the event is
352  //between the start and end of the freebusy dates.
353  KDateTime start = fb->dtStart();
354  if ( !( ( ( start.secsTo(eventStart) >= 0 ) &&
355  ( eventStart.secsTo(mDtEnd) >= 0 ) ) ||
356  ( ( start.secsTo(eventEnd) >= 0 ) &&
357  ( eventEnd.secsTo(mDtEnd) >= 0 ) ) ) ) {
358  return false;
359  }
360 
361  if ( eventStart.secsTo( start ) >= 0 ) {
362  tmpStart = start;
363  } else {
364  tmpStart = eventStart;
365  }
366 
367  if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
368  tmpEnd = mDtEnd;
369  } else {
370  tmpEnd = eventEnd;
371  }
372 
373  FreeBusyPeriod p( tmpStart, tmpEnd );
374  mBusyPeriods.append( p );
375 
376  return true;
377 }
378 //@endcond
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:29:14 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal