• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 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::Duration
Represents a span of time measured in seconds or days.
Definition: duration.h:56
KCalCore::Event
This class provides an Event in the sense of RFC2445.
Definition: event.h:42
KCalCore::Event::Transparent
@ Transparent
Event does not appear in free/busy time.
Definition: event.h:49
KCalCore::Event::Ptr
QSharedPointer< Event > Ptr
A shared pointer to an Event object.
Definition: event.h:55
KCalCore::Event::List
QVector< Ptr > List
List of events.
Definition: event.h:60
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:47
KCalCore::FreeBusyPeriod::List
QVector< FreeBusyPeriod > List
List of periods.
Definition: freebusyperiod.h:52
KCalCore::FreeBusy
Provides information about the free/busy time of a calendar.
Definition: freebusy.h:53
KCalCore::FreeBusy::dtEnd
virtual KDateTime dtEnd() const
Returns the end datetime for the free/busy.
Definition: freebusy.cpp:228
KCalCore::FreeBusy::equals
virtual bool equals(const IncidenceBase &freebusy) const
Compare this with freebusy for equality.
Definition: freebusy.cpp:322
KCalCore::FreeBusy::busyPeriods
Period::List busyPeriods() const
Returns the list of all periods within the free/busy.
Definition: freebusy.cpp:233
KCalCore::FreeBusy::sortList
void sortList()
Sorts the list of free/busy periods into ascending order.
Definition: freebusy.cpp:249
KCalCore::FreeBusy::dateTime
KDateTime dateTime(DateTimeRole role) const
Definition: freebusy.cpp:340
KCalCore::FreeBusy::setDateTime
void setDateTime(const KDateTime &dateTime, DateTimeRole role)
Definition: freebusy.cpp:347
KCalCore::FreeBusy::Ptr
QSharedPointer< FreeBusy > Ptr
A shared pointer to a FreeBusy object.
Definition: freebusy.h:64
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::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::FreeBusy::setDtEnd
void setDtEnd(const KDateTime &end)
Sets the end datetime for the free/busy.
Definition: freebusy.cpp:223
KCalCore::FreeBusy::typeStr
QByteArray typeStr() const
Definition: freebusy.cpp:212
KCalCore::FreeBusy::type
IncidenceType type() const
Definition: freebusy.cpp:207
KCalCore::FreeBusy::mimeType
QLatin1String mimeType() const
Definition: freebusy.cpp:397
KCalCore::FreeBusy::merge
void merge(FreeBusy::Ptr freebusy)
Merges another free/busy into this free/busy.
Definition: freebusy.cpp:281
KCalCore::FreeBusy::~FreeBusy
~FreeBusy()
Destroys a free/busy.
Definition: freebusy.cpp:202
KCalCore::FreeBusy::FreeBusy
FreeBusy()
Constructs an free/busy without any periods.
Definition: freebusy.cpp:78
KCalCore::FreeBusy::freeBusyMimeType
static QLatin1String freeBusyMimeType()
Returns the Akonadi specific sub MIME type of a KCalCore::FreeBusy.
Definition: freebusy.cpp:402
KCalCore::FreeBusy::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: freebusy.cpp:353
KCalCore::FreeBusy::setDtStart
virtual void setDtStart(const KDateTime &start)
Sets the start date/time for the free/busy.
Definition: freebusy.cpp:217
KCalCore::FreeBusy::shiftTimes
virtual void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
Definition: freebusy.cpp:299
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::ICalFormat
iCalendar format implementation.
Definition: icalformat.h:59
KCalCore::ICalFormat::parseFreeBusy
FreeBusy::Ptr parseFreeBusy(const QString &string)
Converts a QString into a FreeBusy object.
Definition: icalformat.cpp:416
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
An abstract class that provides a common base for all calendar incidence classes.
Definition: incidencebase.h:110
KCalCore::IncidenceBase::updated
void updated()
Call this to notify the observers after the IncidenceBase object has changed.
Definition: incidencebase.cpp:604
KCalCore::IncidenceBase::IncidenceType
IncidenceType
The different types of incidences, per RFC2445.
Definition: incidencebase.h:121
KCalCore::IncidenceBase::TypeFreeBusy
@ TypeFreeBusy
Type is a free/busy.
Definition: incidencebase.h:125
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::IncidenceBase::duration
Duration duration() const
Returns the length of the incidence duration.
Definition: incidencebase.cpp:555
KCalCore::IncidenceBase::dtStart
virtual KDateTime dtStart() const
Returns an incidence's starting date/time as a KDateTime.
Definition: incidencebase.cpp:321
KCalCore::IncidenceBase::Ptr
QSharedPointer< IncidenceBase > Ptr
A shared pointer to an IncidenceBase.
Definition: incidencebase.h:115
KCalCore::IncidenceBase::assign
virtual IncidenceBase & assign(const IncidenceBase &other)
Provides polymorfic assignment.
Definition: incidencebase.cpp:154
KCalCore::IncidenceBase::setDtStart
virtual void setDtStart(const KDateTime &dtStart)
Sets the incidence's starting date/time with a KDateTime.
Definition: incidencebase.cpp:306
KCalCore::IncidenceBase::DateTimeRole
DateTimeRole
The different types of incidence date/times roles.
Definition: incidencebase.h:133
KCalCore::IncidenceBase::equals
virtual bool equals(const IncidenceBase &incidenceBase) const
Provides polymorfic comparison for equality.
Definition: incidencebase.cpp:179
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:50
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::Period::List
QVector< Period > List
List of periods.
Definition: period.h:55
KCalCore::Visitor
This class provides the interface for a visitor of calendar components.
Definition: visitor.h:44
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
freebusy.h
This file is part of the API for handling calendar data and defines the FreeBusy class.
icalformat.h
This file is part of the API for handling calendar data and defines the ICalFormat class.
KCalCore
TODO: KDE5:
Definition: alarm.h:47
KCalCore::iTIPPublish
@ iTIPPublish
Event, to-do, journal or freebusy posting.
Definition: schedulemessage.h:36
KCalCore::operator>>
KCALCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalCore::Alarm::Ptr &)
Alarm deserializer.
Definition: alarm.cpp:863
KCalCore::operator<<
KCALCORE_EXPORT QDataStream & operator<<(QDataStream &out, const KCalCore::Alarm::Ptr &)
Alarm serializer.
Definition: alarm.cpp:853
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Jul 22 2021 00:00:00 by doxygen 1.9.1 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.14.10 API Reference

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