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

KCalCore Library

  • sources
  • kde-4.12
  • kdepimlibs
  • 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:125
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's starting date/time with a KDateTime.
Definition: incidencebase.cpp:306
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:55
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:109
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:179
KCalCore::IncidenceBase::IncidenceType
IncidenceType
The different types of incidences, per RFC2445.
Definition: incidencebase.h:121
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:604
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:115
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:416
KCalCore::operator>>
KCALCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalCore::Alarm::Ptr &)
Alarm deserializer.
Definition: alarm.cpp:863
KCalCore::IncidenceBase::DateTimeRole
DateTimeRole
The different types of incidence date/times roles.
Definition: incidencebase.h:133
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::FreeBusy::type
IncidenceType type() const
Definition: freebusy.cpp:207
KCalCore::IncidenceBase::assign
virtual IncidenceBase & assign(const IncidenceBase &other)
Provides polymorfic assignment.
Definition: incidencebase.cpp:154
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::operator<<
KCALCORE_EXPORT QDataStream & operator<<(QDataStream &out, const KCalCore::Alarm::Ptr &)
Alarm serializer.
Definition: alarm.cpp:853
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:367
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:344
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's starting date/time as a KDateTime.
Definition: incidencebase.cpp:321
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:59:57 by doxygen 1.8.7 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 API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



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