• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.11.5 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 
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Fri Jan 17 2014 22:11:59 by doxygen 1.8.3.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.11.5 API Reference

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