KCalendarCore

event.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcalcore library.
3 
4  SPDX-FileCopyrightText: 2001 Cornelius Schumacher <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 /**
9  @file
10  This file is part of the API for handling calendar data and
11  defines the Event class.
12 
13  @brief
14  This class provides an Event in the sense of RFC2445.
15 
16  @author Cornelius Schumacher <[email protected]>
17 */
18 
19 #include "event.h"
20 #include "kcalendarcore_debug.h"
21 #include "utils_p.h"
22 #include "visitor.h"
23 
24 #include <QDate>
25 
26 using namespace KCalendarCore;
27 
28 /**
29  Private class that helps to provide binary compatibility between releases.
30  @internal
31 */
32 //@cond PRIVATE
33 class Q_DECL_HIDDEN KCalendarCore::Event::Private
34 {
35 public:
36  QDateTime mDtEnd;
37  Transparency mTransparency = Opaque;
38  bool mMultiDayValid = false;
39  bool mMultiDay = false;
40 };
41 //@endcond
42 
44  : d(new KCalendarCore::Event::Private)
45 {
46 }
47 
48 Event::Event(const Event &other)
49  : Incidence(other)
50  , d(new KCalendarCore::Event::Private(*other.d))
51 {
52 }
53 
54 Event::Event(const Incidence &other)
55  : Incidence(other)
56  , d(new KCalendarCore::Event::Private)
57 {
58 }
59 
61 {
62  delete d;
63 }
64 
66 {
67  return new Event(*this);
68 }
69 
71 {
72  if (&other != this) {
73  Incidence::assign(other);
74  const Event *e = static_cast<const Event *>(&other);
75  *d = *(e->d);
76  }
77  return *this;
78 }
79 
80 bool Event::equals(const IncidenceBase &event) const
81 {
82  if (!Incidence::equals(event)) {
83  return false;
84  } else {
85  // If they weren't the same type IncidenceBase::equals would had returned false already
86  const Event *e = static_cast<const Event *>(&event);
87  return ((dtEnd() == e->dtEnd()) || (!dtEnd().isValid() && !e->dtEnd().isValid())) && transparency() == e->transparency();
88  }
89 }
90 
92 {
93  return TypeEvent;
94 }
95 
97 {
98  return QByteArrayLiteral("Event");
99 }
100 
102 {
103  d->mMultiDayValid = false;
105 }
106 
108 {
109  if (mReadOnly) {
110  return;
111  }
112 
113  if (d->mDtEnd != dtEnd || hasDuration() == dtEnd.isValid()) {
114  update();
115  d->mDtEnd = dtEnd;
116  d->mMultiDayValid = false;
117  setHasDuration(!dtEnd.isValid());
119  updated();
120  }
121 }
122 
123 QDateTime Event::dtEnd() const
124 {
125  if (d->mDtEnd.isValid()) {
126  return d->mDtEnd;
127  }
128 
129  if (hasDuration()) {
130  if (allDay()) {
131  // For all day events, dtEnd is always inclusive
132  QDateTime end = duration().end(dtStart().addDays(-1));
133  return end >= dtStart() ? end : dtStart();
134  } else {
135  return duration().end(dtStart());
136  }
137  }
138 
139  // It is valid for a VEVENT to be without a DTEND. See RFC2445, Sect4.6.1.
140  // Be careful to use Event::dateEnd() as appropriate due to this possibility.
141  return dtStart();
142 }
143 
145 {
146  QDateTime end = dtEnd().toTimeZone(dtStart().timeZone());
147  if (allDay()) {
148  return end.date();
149  } else {
150  return end.addSecs(-1).date();
151  }
152 }
153 
154 bool Event::hasEndDate() const
155 {
156  return d->mDtEnd.isValid();
157 }
158 
159 bool Event::isMultiDay(const QTimeZone &zone) const
160 {
161  // First off, if spec's not valid, we can check for cache
162  if (!zone.isValid() && d->mMultiDayValid) {
163  return d->mMultiDay;
164  }
165 
166  // Not in cache -> do it the hard way
167  QDateTime start, end;
168 
169  if (!zone.isValid()) {
170  start = dtStart();
171  end = dtEnd();
172  } else {
173  start = dtStart().toTimeZone(zone);
174  end = dtEnd().toTimeZone(zone);
175  }
176 
177  bool multi = (start < end && start.date() != end.date());
178 
179  // End date is non inclusive
180  // If we have an incidence that duration is one day and ends with a start of a new day
181  // than it is not a multiday event
182  if (multi && end.time() == QTime(0, 0, 0)) {
183  multi = start.daysTo(end) > 1;
184  }
185 
186  // Update the cache
187  // Also update Cache if spec is invalid
188  d->mMultiDayValid = true;
189  d->mMultiDay = multi;
190  return multi;
191 }
192 
193 void Event::shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
194 {
195  Incidence::shiftTimes(oldZone, newZone);
196  if (d->mDtEnd.isValid()) {
197  d->mDtEnd = d->mDtEnd.toTimeZone(oldZone);
198  d->mDtEnd.setTimeZone(newZone);
199  }
200 }
201 
203 {
204  if (mReadOnly) {
205  return;
206  }
207  update();
208  d->mTransparency = transparency;
210  updated();
211 }
212 
214 {
215  return d->mTransparency;
216 }
217 
219 {
220  setDtEnd(QDateTime());
221  Incidence::setDuration(duration);
222 }
223 
224 void Event::setAllDay(bool allday)
225 {
226  if (allday != allDay() && !mReadOnly) {
228  Incidence::setAllDay(allday);
229  }
230 }
231 
232 bool Event::accept(Visitor &v, const IncidenceBase::Ptr &incidence)
233 {
234  return v.visit(incidence.staticCast<Event>());
235 }
236 
238 {
239  switch (role) {
240  case RoleRecurrenceStart:
242  case RoleStartTimeZone:
243  case RoleSort:
244  return dtStart();
245  case RoleCalendarHashing:
246  return !recurs() && !isMultiDay() ? dtStart() : QDateTime();
247  case RoleAlarmEndOffset:
248  case RoleEndTimeZone:
249  case RoleEndRecurrenceBase:
250  case RoleEnd:
251  case RoleDisplayEnd:
252  return dtEnd();
253  case RoleDisplayStart:
254  return dtStart();
255  case RoleAlarm:
256  if (alarms().isEmpty()) {
257  return QDateTime();
258  } else {
259  Alarm::Ptr alarm = alarms().at(0);
260  return alarm->hasStartOffset() ? dtStart() : dtEnd();
261  }
262  default:
263  return QDateTime();
264  }
265 }
266 
268 {
269  switch (role) {
270  case RoleDnD: {
271  const qint64 duration = dtStart().secsTo(dtEnd());
272 
273  setDtStart(dateTime);
274  setDtEnd(dateTime.addSecs(duration <= 0 ? 3600 : duration));
275  break;
276  }
277  case RoleEnd:
278  setDtEnd(dateTime);
279  break;
280  default:
281  qCDebug(KCALCORE_LOG) << "Unhandled role" << role;
282  }
283 }
284 
285 void Event::virtual_hook(VirtualHook id, void *data)
286 {
287  Q_UNUSED(id);
288  Q_UNUSED(data);
289 }
290 
292 {
293  return Event::eventMimeType();
294 }
295 
297 {
298  return QLatin1String("application/x-vnd.akonadi.calendar.event");
299 }
300 
302 {
303  return QLatin1String("view-calendar-day");
304 }
305 
306 void Event::serialize(QDataStream &out) const
307 {
309  serializeQDateTimeAsKDateTime(out, d->mDtEnd);
310  out << hasEndDate() << static_cast<quint32>(d->mTransparency) << d->mMultiDayValid << d->mMultiDay;
311 }
312 
313 void Event::deserialize(QDataStream &in)
314 {
316  bool hasEndDateDummy = true;
317  deserializeKDateTimeAsQDateTime(in, d->mDtEnd);
318  in >> hasEndDateDummy;
319  quint32 transp;
320  in >> transp;
321  d->mTransparency = static_cast<Transparency>(transp);
322  in >> d->mMultiDayValid >> d->mMultiDay;
323 }
324 
326 {
327  return true;
328 }
Transparency transparency() const
Returns the event&#39;s time transparency level.
void shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone) override
Definition: event.cpp:193
Alarm::List alarms() const
Returns a list of all incidence alarms.
Definition: incidence.cpp:850
QLatin1String mimeType() const override
Definition: event.cpp:291
Role for determining new start and end dates after a DnD.
void update()
Call this to notify the observers after the IncidenceBase object will be changed. ...
void setDateTime(const QDateTime &dateTime, DateTimeRole role) override
Definition: event.cpp:267
This class provides the interface for a visitor of calendar components.
Definition: visitor.h:30
bool hasDuration() const
Returns true if the incidence has a duration; false otherwise.
void serialize(QDataStream &out) const override
Sub-type specific serialization.
Definition: incidence.cpp:1121
bool supportsGroupwareCommunication() const override
Definition: event.cpp:325
qint64 daysTo(const QDateTime &other) const const
virtual QDateTime dtEnd() const
Returns the event end date and time.
QDateTime end(const QDateTime &start) const
Computes a duration end time by adding the number of seconds or days in the duration to the specified...
Definition: duration.cpp:171
bool recurs() const
Returns whether the event recurs at all.
Definition: incidence.cpp:598
void setDtStart(const QDateTime &dt) override
Sets the incidence starting date/time.
Definition: event.cpp:101
static QLatin1String eventMimeType()
Returns the Akonadi specific sub MIME type of a KCalendarCore::Event.
Definition: event.cpp:296
QTime time() const const
QLatin1String iconName(const QDateTime &recurrenceId={}) const override
Definition: event.cpp:301
QDateTime toTimeZone(const QTimeZone &timeZone) const const
QDate dateEnd() const
Returns the date when the event ends.
Definition: event.cpp:144
Role for determining the start of the recurrence.
DateTimeRole
The different types of incidence date/times roles.
Field representing the TRANSPARENCY component.
virtual void setDuration(const Duration &duration)
Sets the incidence duration.
An abstract class that provides a common base for all calendar incidence classes. ...
Definition: incidencebase.h:97
Role for an incidence&#39;s date/time used when sorting.
void setAllDay(bool allDay) override
Definition: incidence.cpp:343
bool equals(const IncidenceBase &event) const override
Compares two events for equality.
Definition: event.cpp:80
Represents a span of time measured in seconds or days.
Definition: duration.h:43
Role for determining an incidence&#39;s starting timezone.
Duration duration() const
Returns the length of the incidence duration.
Role for determining an incidence&#39;s ending timezone.
This class provides an Event in the sense of RFC2445.
Definition: event.h:29
void setHasDuration(bool hasDuration)
Sets if the incidence has a duration.
Role for looking up an incidence in a Calendar.
QDateTime dateTime(DateTimeRole role) const override
Definition: event.cpp:237
void shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone) override
Shift the times of the incidence so that they appear at the same clock time as before but in a new ti...
Definition: incidence.cpp:401
Role for determining the date/time of the first alarm.
Role for an incidence alarm&#39;s starting offset date/time.
IncidenceType
The different types of incidences, per RFC2445.
void setDtStart(const QDateTime &dt) override
Sets the incidence starting date/time.
Definition: incidence.cpp:393
void setDtEnd(const QDateTime &dtEnd)
Sets the event end date and time.
Definition: event.cpp:107
Field representing the DTEND component.
void updated()
Call this to notify the observers after the IncidenceBase object has changed.
IncidenceType type() const override
Definition: event.cpp:91
bool isValid() const const
Role for display purposes, represents the start boundary of an incidence.
Transparency
The different Event transparency types.
Definition: event.h:38
Event * clone() const override
Returns an exact copy of this Event.
Definition: event.cpp:65
const T & at(int i) const const
~Event() override
Destroys the event.
Definition: event.cpp:60
QDate date() const const
void setFieldDirty(IncidenceBase::Field field)
Marks Field field as dirty.
This file is part of the API for handling calendar data and defines the Event class.
qint64 secsTo(const QDateTime &other) const const
Event()
Constructs an event.
Definition: event.cpp:43
IncidenceBase & assign(const IncidenceBase &other) override
Definition: event.cpp:70
void deserialize(QDataStream &in) override
Sub-type specific deserialization.
Definition: incidence.cpp:1147
bool isMultiDay(const QTimeZone &zone={}) const
Returns true if the event spans multiple days, otherwise return false.
Definition: event.cpp:159
bool allDay() const
Returns true or false depending on whether the incidence is all-day.
Role for determining an incidence&#39;s dtEnd, will return an invalid QDateTime if the incidence does not...
Role used for display purposes, represents the end boundary if an incidence supports dtEnd...
bool isValid() const const
virtual bool visit(const Event::Ptr &event)
Reimplement this function in your concrete subclass of IncidenceBase::Visitor to perform actions on a...
Definition: visitor.cpp:29
void setDuration(const Duration &duration) override
Sets the duration of this event.
Definition: event.cpp:218
void virtual_hook(VirtualHook id, void *data) override
Definition: event.cpp:285
virtual QDateTime dtStart() const
Returns an incidence&#39;s starting date/time as a QDateTime.
void setAllDay(bool allDay) override
Definition: event.cpp:224
QDateTime addSecs(qint64 s) const const
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Definition: incidence.h:56
QSharedPointer< X > staticCast() const const
bool hasEndDate() const
Returns whether the event has an end date/time.
Definition: event.cpp:154
IncidenceBase & assign(const IncidenceBase &other) override
Provides polymorfic assignment.
Definition: incidence.cpp:203
void setTransparency(Transparency transparency)
Sets the event&#39;s time transparency level.
Definition: event.cpp:202
bool equals(const IncidenceBase &incidence) const override
Compares this with Incidence incidence for equality.
Definition: incidence.cpp:216
Namespace for all KCalendarCore types.
Definition: alarm.h:36
Role for an incidence alarm&#39;s ending offset date/time.
QByteArray typeStr() const override
Definition: event.cpp:96
bool mReadOnly
Identifies a read-only incidence.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Apr 10 2021 22:50:59 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.