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;
168  QDateTime end;
169 
170  if (!zone.isValid()) {
171  start = dtStart();
172  end = dtEnd();
173  } else {
174  start = dtStart().toTimeZone(zone);
175  end = dtEnd().toTimeZone(zone);
176  }
177 
178  bool multi = (start < end && start.date() != end.date());
179 
180  // End date is non inclusive
181  // If we have an incidence that duration is one day and ends with a start of a new day
182  // than it is not a multiday event
183  if (multi && end.time() == QTime(0, 0, 0)) {
184  multi = start.daysTo(end) > 1;
185  }
186 
187  // Update the cache
188  // Also update Cache if spec is invalid
189  d->mMultiDayValid = true;
190  d->mMultiDay = multi;
191  return multi;
192 }
193 
194 void Event::shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone)
195 {
196  Incidence::shiftTimes(oldZone, newZone);
197  if (d->mDtEnd.isValid()) {
198  d->mDtEnd = d->mDtEnd.toTimeZone(oldZone);
199  d->mDtEnd.setTimeZone(newZone);
200  }
201 }
202 
204 {
205  if (mReadOnly) {
206  return;
207  }
208  update();
209  d->mTransparency = transparency;
211  updated();
212 }
213 
215 {
216  return d->mTransparency;
217 }
218 
220 {
221  setDtEnd(QDateTime());
222  Incidence::setDuration(duration);
223 }
224 
225 void Event::setAllDay(bool allday)
226 {
227  if (allday != allDay() && !mReadOnly) {
229  Incidence::setAllDay(allday);
230  }
231 }
232 
233 bool Event::accept(Visitor &v, const IncidenceBase::Ptr &incidence)
234 {
235  return v.visit(incidence.staticCast<Event>());
236 }
237 
239 {
240  switch (role) {
241  case RoleRecurrenceStart:
243  case RoleStartTimeZone:
244  case RoleSort:
245  return dtStart();
246  case RoleCalendarHashing:
247  return !recurs() && !isMultiDay() ? dtStart() : QDateTime();
248  case RoleAlarmEndOffset:
249  case RoleEndTimeZone:
250  case RoleEndRecurrenceBase:
251  case RoleEnd:
252  case RoleDisplayEnd:
253  return dtEnd();
254  case RoleDisplayStart:
255  return dtStart();
256  case RoleAlarm:
257  if (alarms().isEmpty()) {
258  return QDateTime();
259  } else {
260  Alarm::Ptr alarm = alarms().at(0);
261  return alarm->hasStartOffset() ? dtStart() : dtEnd();
262  }
263  default:
264  return QDateTime();
265  }
266 }
267 
269 {
270  switch (role) {
271  case RoleDnD: {
272  const qint64 duration = dtStart().secsTo(dtEnd());
273 
274  setDtStart(dateTime);
275  setDtEnd(dateTime.addSecs(duration <= 0 ? 3600 : duration));
276  break;
277  }
278  case RoleEnd:
279  setDtEnd(dateTime);
280  break;
281  default:
282  qCDebug(KCALCORE_LOG) << "Unhandled role" << role;
283  }
284 }
285 
286 void Event::virtual_hook(VirtualHook id, void *data)
287 {
288  Q_UNUSED(id);
289  Q_UNUSED(data);
290 }
291 
293 {
294  return Event::eventMimeType();
295 }
296 
298 {
299  return QLatin1String("application/x-vnd.akonadi.calendar.event");
300 }
301 
303 {
304  return QLatin1String("view-calendar-day");
305 }
306 
307 void Event::serialize(QDataStream &out) const
308 {
310  serializeQDateTimeAsKDateTime(out, d->mDtEnd);
311  out << hasEndDate() << static_cast<quint32>(d->mTransparency) << d->mMultiDayValid << d->mMultiDay;
312 }
313 
314 void Event::deserialize(QDataStream &in)
315 {
317  bool hasEndDateDummy = true;
318  deserializeKDateTimeAsQDateTime(in, d->mDtEnd);
319  in >> hasEndDateDummy;
320  quint32 transp;
321  in >> transp;
322  d->mTransparency = static_cast<Transparency>(transp);
323  in >> d->mMultiDayValid >> d->mMultiDay;
324 }
325 
327 {
328  return true;
329 }
Transparency transparency() const
Returns the event&#39;s time transparency level.
void shiftTimes(const QTimeZone &oldZone, const QTimeZone &newZone) override
Definition: event.cpp:194
Alarm::List alarms() const
Returns a list of all incidence alarms.
Definition: incidence.cpp:857
QLatin1String mimeType() const override
Definition: event.cpp:292
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:268
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:1128
bool supportsGroupwareCommunication() const override
Definition: event.cpp:326
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:605
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:297
QTime time() const const
QLatin1String iconName(const QDateTime &recurrenceId={}) const override
Definition: event.cpp:302
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:350
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:238
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:408
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:400
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:1154
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:25
void setDuration(const Duration &duration) override
Sets the duration of this event.
Definition: event.cpp:219
void virtual_hook(VirtualHook id, void *data) override
Definition: event.cpp:286
virtual QDateTime dtStart() const
Returns an incidence&#39;s starting date/time as a QDateTime.
void setAllDay(bool allDay) override
Definition: event.cpp:225
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:207
void setTransparency(Transparency transparency)
Sets the event&#39;s time transparency level.
Definition: event.cpp:203
bool equals(const IncidenceBase &incidence) const override
Compares this with Incidence incidence for equality.
Definition: incidence.cpp:220
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 Sun Sep 26 2021 22:51:52 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.