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

KCalCore Library

  • kcalcore
freebusy.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcalcore 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 */
33 #include "freebusy.h"
34 #include "visitor.h"
35 
36 #include "icalformat.h"
37 
38 #include <KDebug>
39 #include <QTime>
40 
41 using namespace KCalCore;
42 
43 //@cond PRIVATE
44 class KCalCore::FreeBusy::Private
45 {
46  private:
47  FreeBusy *q;
48  public:
49  Private( FreeBusy *qq ) : q( qq )
50  {}
51 
52  Private( const KCalCore::FreeBusy::Private &other, FreeBusy *qq ) : q( qq )
53  {
54  init( other );
55  }
56 
57  Private( const FreeBusyPeriod::List &busyPeriods, FreeBusy *qq )
58  : q( qq ), mBusyPeriods( busyPeriods )
59  {}
60 
61  void init( const KCalCore::FreeBusy::Private &other );
62  void init( const Event::List &events, const KDateTime &start, const KDateTime &end );
63 
64  KDateTime mDtEnd; // end datetime
65  FreeBusyPeriod::List mBusyPeriods; // list of periods
66 
67  // This is used for creating a freebusy object for the current user
68  bool addLocalPeriod( FreeBusy *fb, const KDateTime &start, const KDateTime &end );
69 };
70 
71 void KCalCore::FreeBusy::Private::init( const KCalCore::FreeBusy::Private &other )
72 {
73  mDtEnd = other.mDtEnd;
74  mBusyPeriods = other.mBusyPeriods;
75 }
76 //@endcond
77 
78 FreeBusy::FreeBusy()
79  : d( new KCalCore::FreeBusy::Private( this ) )
80 {
81 }
82 
83 FreeBusy::FreeBusy( const FreeBusy &other )
84  : IncidenceBase( other ),
85  d( new KCalCore::FreeBusy::Private( *other.d, this ) )
86 {
87 }
88 
89 FreeBusy::FreeBusy( const KDateTime &start, const KDateTime &end )
90  : d( new KCalCore::FreeBusy::Private( this ) )
91 {
92  setDtStart( start );
93  setDtEnd( end );
94 }
95 
96 FreeBusy::FreeBusy( const Event::List &events, const KDateTime &start, const KDateTime &end )
97  : d( new KCalCore::FreeBusy::Private( this ) )
98 {
99  setDtStart( start );
100  setDtEnd( end );
101 
102  d->init( events, start, end );
103 }
104 
105 //@cond PRIVATE
106 void FreeBusy::Private::init( const Event::List &eventList,
107  const KDateTime &start, const KDateTime &end )
108 {
109  int extraDays, i, x, duration;
110  duration = start.daysTo( end );
111  QDate day;
112  KDateTime tmpStart;
113  KDateTime tmpEnd;
114 
115  // Loops through every event in the calendar
116  Event::List::ConstIterator it;
117  for ( it = eventList.constBegin(); it != eventList.constEnd(); ++it ) {
118  Event::Ptr event = *it;
119 
120  // If this event is transparent it shouldn't be in the freebusy list.
121  if ( event->transparency() == Event::Transparent ) {
122  continue;
123  }
124 
125  // The code below can not handle all-day events. Fixing this resulted
126  // in a lot of duplicated code. Instead, make a copy of the event and
127  // set the period to the full day(s). This trick works for recurring,
128  // multiday, and single day all-day events.
129  Event::Ptr allDayEvent;
130  if ( event->allDay() ) {
131  // addDay event. Do the hack
132  kDebug() << "All-day event";
133  allDayEvent = Event::Ptr( new Event( *event ) );
134 
135  // Set the start and end times to be on midnight
136  KDateTime st = allDayEvent->dtStart();
137  st.setTime( QTime( 0, 0 ) );
138  KDateTime nd = allDayEvent->dtEnd();
139  nd.setTime( QTime( 23, 59, 59, 999 ) );
140  allDayEvent->setAllDay( false );
141  allDayEvent->setDtStart( st );
142  allDayEvent->setDtEnd( nd );
143 
144  kDebug() << "Use:" << st.toString() << "to" << nd.toString();
145  // Finally, use this event for the setting below
146  event = allDayEvent;
147  }
148 
149  // This whole for loop is for recurring events, it loops through
150  // each of the days of the freebusy request
151 
152  for ( i = 0; i <= duration; ++i ) {
153  day = start.addDays( i ).date();
154  tmpStart.setDate( day );
155  tmpEnd.setDate( day );
156 
157  if ( event->recurs() ) {
158  if ( event->isMultiDay() ) {
159  // FIXME: This doesn't work for sub-daily recurrences or recurrences with
160  // a different time than the original event.
161  extraDays = event->dtStart().daysTo( event->dtEnd() );
162  for ( x = 0; x <= extraDays; ++x ) {
163  if ( event->recursOn( day.addDays( -x ), start.timeSpec() ) ) {
164  tmpStart.setDate( day.addDays( -x ) );
165  tmpStart.setTime( event->dtStart().time() );
166  tmpEnd = event->duration().end( tmpStart );
167 
168  addLocalPeriod( q, tmpStart, tmpEnd );
169  break;
170  }
171  }
172  } else {
173  if ( event->recursOn( day, start.timeSpec() ) ) {
174  tmpStart.setTime( event->dtStart().time() );
175  tmpEnd.setTime( event->dtEnd().time() );
176 
177  addLocalPeriod ( q, tmpStart, tmpEnd );
178  }
179  }
180  }
181 
182  }
183  // Non-recurring events
184  addLocalPeriod( q, event->dtStart(), event->dtEnd() );
185  }
186 
187  q->sortList();
188 }
189 //@endcond
190 
191 FreeBusy::FreeBusy( const Period::List &busyPeriods )
192  : d( new KCalCore::FreeBusy::Private( this ) )
193 {
194  addPeriods( busyPeriods );
195 }
196 
197 FreeBusy::FreeBusy( const FreeBusyPeriod::List &busyPeriods )
198  : d( new KCalCore::FreeBusy::Private( busyPeriods, this ) )
199 {
200 }
201 
202 FreeBusy::~FreeBusy()
203 {
204  delete d;
205 }
206 
207 IncidenceBase::IncidenceType FreeBusy::type() const
208 {
209  return TypeFreeBusy;
210 }
211 
212 QByteArray FreeBusy::typeStr() const
213 {
214  return "FreeBusy";
215 }
216 
217 void FreeBusy::setDtStart( const KDateTime &start )
218 {
219  IncidenceBase::setDtStart( start.toUtc() );
220  updated();
221 }
222 
223 void FreeBusy::setDtEnd( const KDateTime &end )
224 {
225  d->mDtEnd = end;
226 }
227 
228 KDateTime FreeBusy::dtEnd() const
229 {
230  return d->mDtEnd;
231 }
232 
233 Period::List FreeBusy::busyPeriods() const
234 {
235  Period::List res;
236 
237  foreach ( const FreeBusyPeriod &p, d->mBusyPeriods ) {
238  res << p;
239  }
240 
241  return res;
242 }
243 
244 FreeBusyPeriod::List FreeBusy::fullBusyPeriods() const
245 {
246  return d->mBusyPeriods;
247 }
248 
249 void FreeBusy::sortList()
250 {
251  qSort( d->mBusyPeriods );
252  return;
253 }
254 
255 void FreeBusy::addPeriods( const Period::List &list )
256 {
257  foreach ( const Period &p, list ) {
258  d->mBusyPeriods << FreeBusyPeriod( p );
259  }
260  sortList();
261 }
262 
263 void FreeBusy::addPeriods( const FreeBusyPeriod::List &list )
264 {
265  d->mBusyPeriods += list;
266  sortList();
267 }
268 
269 void FreeBusy::addPeriod( const KDateTime &start, const KDateTime &end )
270 {
271  d->mBusyPeriods.append( FreeBusyPeriod( start, end ) );
272  sortList();
273 }
274 
275 void FreeBusy::addPeriod( const KDateTime &start, const Duration &duration )
276 {
277  d->mBusyPeriods.append( FreeBusyPeriod( start, duration ) );
278  sortList();
279 }
280 
281 void FreeBusy::merge( FreeBusy::Ptr freeBusy )
282 {
283  if ( freeBusy->dtStart() < dtStart() ) {
284  setDtStart( freeBusy->dtStart() );
285  }
286 
287  if ( freeBusy->dtEnd() > dtEnd() ) {
288  setDtEnd( freeBusy->dtEnd() );
289  }
290 
291  Period::List periods = freeBusy->busyPeriods();
292  Period::List::ConstIterator it;
293  for ( it = periods.constBegin(); it != periods.constEnd(); ++it ) {
294  d->mBusyPeriods.append( FreeBusyPeriod( ( *it ).start(), ( *it ).end() ) );
295  }
296  sortList();
297 }
298 
299 void FreeBusy::shiftTimes( const KDateTime::Spec &oldSpec,
300  const KDateTime::Spec &newSpec )
301 {
302  if ( oldSpec.isValid() && newSpec.isValid() && oldSpec != newSpec ) {
303  IncidenceBase::shiftTimes( oldSpec, newSpec );
304  d->mDtEnd = d->mDtEnd.toTimeSpec( oldSpec );
305  d->mDtEnd.setTimeSpec( newSpec );
306  foreach ( FreeBusyPeriod p, d->mBusyPeriods ) { //krazy:exclude=foreach
307  p.shiftTimes( oldSpec, newSpec );
308  }
309  }
310 }
311 
312 IncidenceBase &FreeBusy::assign( const IncidenceBase &other )
313 {
314  if ( &other != this ) {
315  IncidenceBase::assign( other );
316  const FreeBusy *f = static_cast<const FreeBusy*>( &other );
317  d->init( *( f->d ) );
318  }
319  return *this;
320 }
321 
322 bool FreeBusy::equals( const IncidenceBase &freeBusy ) const
323 {
324  if ( !IncidenceBase::equals( freeBusy ) ) {
325  return false;
326  } else {
327  // If they weren't the same type IncidenceBase::equals would had returned false already
328  const FreeBusy *fb = static_cast<const FreeBusy*>( &freeBusy );
329  return
330  dtEnd() == fb->dtEnd() &&
331  d->mBusyPeriods == fb->d->mBusyPeriods;
332  }
333 }
334 
335 bool FreeBusy::accept( Visitor &v, IncidenceBase::Ptr incidence )
336 {
337  return v.visit( incidence.staticCast<FreeBusy>() );
338 }
339 
340 KDateTime FreeBusy::dateTime( DateTimeRole role ) const
341 {
342  Q_UNUSED( role );
343  // No roles affecting freeBusy yet
344  return KDateTime();
345 }
346 
347 void FreeBusy::setDateTime( const KDateTime &dateTime, DateTimeRole role )
348 {
349  Q_UNUSED( dateTime );
350  Q_UNUSED( role );
351 }
352 
353 void FreeBusy::virtual_hook( int id, void *data )
354 {
355  Q_UNUSED( id );
356  Q_UNUSED( data );
357  Q_ASSERT( false );
358 }
359 
360 //@cond PRIVATE
361 bool FreeBusy::Private::addLocalPeriod( FreeBusy *fb,
362  const KDateTime &eventStart,
363  const KDateTime &eventEnd )
364 {
365  KDateTime tmpStart;
366  KDateTime tmpEnd;
367 
368  //Check to see if the start *or* end of the event is
369  //between the start and end of the freebusy dates.
370  KDateTime start = fb->dtStart();
371  if ( !( ( ( start.secsTo( eventStart ) >= 0 ) &&
372  ( eventStart.secsTo( mDtEnd ) >= 0 ) ) ||
373  ( ( start.secsTo( eventEnd ) >= 0 ) &&
374  ( eventEnd.secsTo( mDtEnd ) >= 0 ) ) ) ) {
375  return false;
376  }
377 
378  if ( eventStart.secsTo( start ) >= 0 ) {
379  tmpStart = start;
380  } else {
381  tmpStart = eventStart;
382  }
383 
384  if ( eventEnd.secsTo( mDtEnd ) <= 0 ) {
385  tmpEnd = mDtEnd;
386  } else {
387  tmpEnd = eventEnd;
388  }
389 
390  FreeBusyPeriod p( tmpStart, tmpEnd );
391  mBusyPeriods.append( p );
392 
393  return true;
394 }
395 //@endcond
396 
397 QLatin1String FreeBusy::mimeType() const
398 {
399  return FreeBusy::freeBusyMimeType();
400 }
401 
402 QLatin1String KCalCore::FreeBusy::freeBusyMimeType()
403 {
404  return QLatin1String( "application/x-vnd.akonadi.calendar.freebusy" );
405 }
406 
407 QDataStream &KCalCore::operator<<( QDataStream &stream, const KCalCore::FreeBusy::Ptr &freebusy )
408 {
409  KCalCore::ICalFormat format;
410  QString data = format.createScheduleMessage( freebusy, iTIPPublish );
411  return stream << data;
412 }
413 
414 QDataStream &KCalCore::operator>>( QDataStream &stream, KCalCore::FreeBusy::Ptr &freebusy )
415 {
416  QString freeBusyVCal;
417  stream >> freeBusyVCal;
418 
419  KCalCore::ICalFormat format;
420  freebusy = format.parseFreeBusy( freeBusyVCal );
421 
422  if ( !freebusy ) {
423  kDebug() << "Error parsing free/busy";
424  kDebug() << freeBusyVCal;
425  }
426 
427  return stream;
428 }
429 
KCalCore::IncidenceBase::TypeFreeBusy
Type is a free/busy.
Definition: incidencebase.h:123
KCalCore::FreeBusy::shiftTimes
virtual void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
Definition: freebusy.cpp:299
KCalCore::IncidenceBase::setDtStart
virtual void setDtStart(const KDateTime &dtStart)
Sets the incidence&#39;s starting date/time with a KDateTime.
Definition: incidencebase.cpp:304
KCalCore::FreeBusy::addPeriods
void addPeriods(const Period::List &list)
Adds a list of periods to the freebusy object and then sorts that list.
Definition: freebusy.cpp:255
KCalCore::Duration
Represents a span of time measured in seconds or days.
Definition: duration.h:52
KCalCore::Visitor::visit
virtual bool visit(Event::Ptr event)
Reimplement this function in your concrete subclass of IncidenceBase::Visitor to perform actions on a...
Definition: visitor.cpp:42
KCalCore::Event::Ptr
QSharedPointer< Event > Ptr
A shared pointer to an Event object.
Definition: event.h:55
KCalCore::IncidenceBase
An abstract class that provides a common base for all calendar incidence classes. ...
Definition: incidencebase.h:107
KCalCore::FreeBusy::freeBusyMimeType
static QLatin1String freeBusyMimeType()
Returns the Akonadi specific sub MIME type of a KCalCore::FreeBusy.
Definition: freebusy.cpp:402
KCalCore::Visitor
This class provides the interface for a visitor of calendar components.
Definition: visitor.h:43
KCalCore::IncidenceBase::equals
virtual bool equals(const IncidenceBase &incidenceBase) const
Provides polymorfic comparison for equality.
Definition: incidencebase.cpp:183
KCalCore::IncidenceBase::IncidenceType
IncidenceType
The different types of incidences, per RFC2445.
Definition: incidencebase.h:119
KCalCore::FreeBusy::mimeType
QLatin1String mimeType() const
Definition: freebusy.cpp:397
KCalCore::FreeBusy::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: freebusy.cpp:353
KCalCore::FreeBusy::merge
void merge(FreeBusy::Ptr freebusy)
Merges another free/busy into this free/busy.
Definition: freebusy.cpp:281
KCalCore::FreeBusy::equals
virtual bool equals(const IncidenceBase &freebusy) const
Compare this with freebusy for equality.
Definition: freebusy.cpp:322
KCalCore::FreeBusy::setDtStart
virtual void setDtStart(const KDateTime &start)
Sets the start date/time for the free/busy.
Definition: freebusy.cpp:217
KCalCore::FreeBusy::dateTime
KDateTime dateTime(DateTimeRole role) const
Definition: freebusy.cpp:340
KCalCore::FreeBusyPeriod
The period can be defined by either a start time and an end time or by a start time and a duration...
Definition: freebusyperiod.h:46
KCalCore::Period
The period can be defined by either a start time and an end time or by a start time and a duration...
Definition: period.h:49
KCalCore::Event::List
QVector< Ptr > List
List of events.
Definition: event.h:60
KCalCore::FreeBusy::~FreeBusy
~FreeBusy()
Destroys a free/busy.
Definition: freebusy.cpp:202
KCalCore::IncidenceBase::updated
void updated()
Call this to notify the observers after the IncidenceBase object has changed.
Definition: incidencebase.cpp:591
KCalCore::Event::Transparent
Event does not appear in free/busy time.
Definition: event.h:49
KCalCore::Period::List
QVector< Period > List
List of periods.
Definition: period.h:55
KCalCore::FreeBusy::assign
virtual IncidenceBase & assign(const IncidenceBase &other)
Definition: freebusy.cpp:312
KCalCore::FreeBusy::fullBusyPeriods
FreeBusyPeriod::List fullBusyPeriods() const
Returns the list of all periods within the free/busy.
Definition: freebusy.cpp:244
KCalCore::FreeBusyPeriod::List
QVector< FreeBusyPeriod > List
List of periods.
Definition: freebusyperiod.h:52
KCalCore::IncidenceBase::Ptr
QSharedPointer< IncidenceBase > Ptr
A shared pointer to an IncidenceBase.
Definition: incidencebase.h:113
KCalCore::ICalFormat
iCalendar format implementation.
Definition: icalformat.h:58
KCalCore::FreeBusy::typeStr
QByteArray typeStr() const
Definition: freebusy.cpp:212
freebusy.h
This file is part of the API for handling calendar data and defines the FreeBusy class.
KCalCore::ICalFormat::parseFreeBusy
FreeBusy::Ptr parseFreeBusy(const QString &string)
Converts a QString into a FreeBusy object.
Definition: icalformat.cpp:414
KCalCore::IncidenceBase::DateTimeRole
DateTimeRole
The different types of incidence date/times roles.
Definition: incidencebase.h:131
KCalCore::FreeBusy::busyPeriods
Period::List busyPeriods() const
Returns the list of all periods within the free/busy.
Definition: freebusy.cpp:233
KCalCore::Period::shiftTimes
void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
Shift the times of the period so that they appear at the same clock time as before but in a new time ...
Definition: period.cpp:141
KCalCore::operator<<
KCALCORE_EXPORT QDataStream & operator<<(QDataStream &stream, const KCalCore::Attendee::Ptr &attendee)
Serializes an Attendee object into a data stream.
Definition: attendee.cpp:186
KCalCore::FreeBusy::type
IncidenceType type() const
Definition: freebusy.cpp:207
KCalCore::IncidenceBase::assign
virtual IncidenceBase & assign(const IncidenceBase &other)
Provides polymorfic assignment.
Definition: incidencebase.cpp:149
KCalCore::FreeBusy::Ptr
QSharedPointer< FreeBusy > Ptr
A shared pointer to a FreeBusy object.
Definition: freebusy.h:64
KCalCore::Event
This class provides an Event in the sense of RFC2445.
Definition: event.h:41
KCalCore::FreeBusy::dtEnd
virtual KDateTime dtEnd() const
Returns the end datetime for the free/busy.
Definition: freebusy.cpp:228
KCalCore::FreeBusy
Provides information about the free/busy time of a calendar.
Definition: freebusy.h:52
KCalCore::FreeBusy::FreeBusy
FreeBusy()
Constructs an free/busy without any periods.
Definition: freebusy.cpp:78
KCalCore::iTIPPublish
Event, to-do, journal or freebusy posting.
Definition: schedulemessage.h:36
KCalCore::FreeBusy::setDateTime
void setDateTime(const KDateTime &dateTime, DateTimeRole role)
Definition: freebusy.cpp:347
KCalCore::FreeBusy::sortList
void sortList()
Sorts the list of free/busy periods into ascending order.
Definition: freebusy.cpp:249
KCalCore::ICalFormat::createScheduleMessage
QString createScheduleMessage(const IncidenceBase::Ptr &incidence, iTIPMethod method)
Creates a scheduling message string for an Incidence.
Definition: icalformat.cpp:365
KCalCore::operator>>
KCALCORE_EXPORT QDataStream & operator>>(QDataStream &stream, KCalCore::Attendee::Ptr &attendee)
Initializes an Attendee object from a data stream.
Definition: attendee.cpp:199
KCalCore::IncidenceBase::shiftTimes
virtual void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
Shift the times of the incidence so that they appear at the same clock time as before but in a new ti...
Definition: incidencebase.cpp:342
KCalCore::FreeBusy::setDtEnd
void setDtEnd(const KDateTime &end)
Sets the end datetime for the free/busy.
Definition: freebusy.cpp:223
icalformat.h
This file is part of the API for handling calendar data and defines the ICalFormat class...
KCalCore::FreeBusy::addPeriod
void addPeriod(const KDateTime &start, const KDateTime &end)
Adds a period to the freebusy list and sorts the list.
Definition: freebusy.cpp:269
KCalCore::IncidenceBase::dtStart
virtual KDateTime dtStart() const
Returns an incidence&#39;s starting date/time as a KDateTime.
Definition: incidencebase.cpp:319
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Tue Nov 26 2013 09:02:04 by doxygen 1.8.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCalCore Library

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

kdepimlibs-4.11.3 API Reference

Skip menu "kdepimlibs-4.11.3 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