KItinerary

calendarhandler.cpp
1 /*
2  SPDX-FileCopyrightText: 2017 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "config-kitinerary.h"
8 #include "calendarhandler.h"
9 #include "jsonlddocument.h"
10 #include "locationutil_p.h"
11 #include "logging.h"
12 #include "mergeutil.h"
13 #include "sortutil.h"
14 
15 #include <KItinerary/BusTrip>
16 #include <KItinerary/Event>
17 #include <KItinerary/Flight>
18 #include <KItinerary/Organization>
19 #include <KItinerary/Person>
20 #include <KItinerary/Place>
21 #include <KItinerary/RentalCar>
22 #include <KItinerary/Reservation>
23 #include <KItinerary/Ticket>
24 #include <KItinerary/TrainTrip>
25 #include <KItinerary/Visit>
26 
27 #ifdef HAVE_KCAL
28 #include <KCalendarCore/Alarm>
29 #include <KCalendarCore/Calendar>
30 #include <KCalendarCore/Event>
31 #endif
32 
33 #include <KContacts/Address>
34 
35 #include <KLocalizedString>
36 
37 #include <QDateTime>
38 #include <QJsonArray>
39 #include <QJsonDocument>
40 
41 using namespace KItinerary;
42 
43 static QString formatAddress(const PostalAddress &addr)
44 {
45  return LocationUtil::toAddress(addr).formatted(KContacts::AddressFormatStyle::MultiLineInternational);
46 }
47 
48 static QString formatAddressSingleLine(const PostalAddress &addr)
49 {
50  return LocationUtil::toAddress(addr).formatted(KContacts::AddressFormatStyle::SingleLineInternational);
51 }
52 
53 #ifdef HAVE_KCAL
54 using namespace KCalendarCore;
55 static void fillFlightReservation(const QVector<QVariant> &reservations, const KCalendarCore::Event::Ptr &event);
56 static void fillTrainReservation(const TrainReservation &reservation, const KCalendarCore::Event::Ptr &event);
57 static void fillBusReservation(const BusReservation &reservation, const KCalendarCore::Event::Ptr &event);
58 static void fillLodgingReservation(const QVector<QVariant> &reservations, const KCalendarCore::Event::Ptr &event);
59 static void fillEvent(const KItinerary::Event &ev, const KCalendarCore::Event::Ptr &event);
60 static void fillEventReservation(const QVector<QVariant> &reservations, const KCalendarCore::Event::Ptr &event);
61 static void fillGeoPosition(const QVariant &place, const KCalendarCore::Event::Ptr &event);
62 static void fillFoodReservation(const FoodEstablishmentReservation &reservation, const KCalendarCore::Event::Ptr &event);
63 static void fillRentalCarReservation(const RentalCarReservation &reservation, const KCalendarCore::Event::Ptr &event);
64 static void fillTaxiReservation(const TaxiReservation &reservation, const KCalendarCore::Event::Ptr &event);
65 #endif
66 
68 {
69 #ifdef HAVE_KCAL
70  if (!(JsonLd::canConvert<Reservation>(reservation) || JsonLd::canConvert<KItinerary::Event>(reservation)) || !calendar) {
71  return {};
72  }
73 
76  const auto dt = SortUtil::startDateTime(reservation).toTimeZone(calendar->timeZone()).date();
77  if (dt.isValid()) {
78  // we know the exact day to search at
79  events = calendar->events(dt);
80  } else if (JsonLd::canConvert<Reservation>(reservation)) {
81  // for minimal cancellations, we need to search in a larger range
82  const auto res = JsonLd::convert<Reservation>(reservation);
83  if (!res.modifiedTime().isValid() || res.reservationStatus() != Reservation::ReservationCancelled) {
84  return {};
85  }
86  const auto date = res.modifiedTime().toTimeZone(calendar->timeZone()).date();
87  events = calendar->events(date, date.addDays(180));
88  }
89 
90  for (const auto &event : events) {
91  if (!event->uid().startsWith(QLatin1String("KIT-"))) {
92  continue;
93  }
94  const auto otherRes = CalendarHandler::reservationsForEvent(event);
95  for (const auto &other : otherRes) {
96  if (MergeUtil::isSame(other, reservation)) {
97  results.push_back(event);
98  }
99  }
100  }
101 
102  return results;
103 #else
104  Q_UNUSED(calendar)
105  Q_UNUSED(reservation)
106  return {};
107 #endif
108 }
109 
111 {
112 #ifdef HAVE_KCAL
113  const auto evs = findEvents(calendar, reservation);
114  return evs.empty() ? KCalendarCore::Event::Ptr() : evs.at(0);
115 #else
116  Q_UNUSED(calendar)
117  Q_UNUSED(reservation)
118  return {};
119 #endif
120 }
121 
123 {
124 #ifdef HAVE_KCAL
125  const auto payload = event->customProperty("KITINERARY", "RESERVATION").toUtf8();
126  const auto json = QJsonDocument::fromJson(payload).array();
127  return JsonLdDocument::fromJson(json);
128 #else
129  Q_UNUSED(event)
130  return {};
131 #endif
132 }
133 
135 {
136 #ifdef HAVE_KCAL
137  if (JsonLd::isA<FlightReservation>(reservation)) {
138  const auto f = reservation.value<FlightReservation>().reservationFor().value<Flight>();
139  if (f.departureTime().isValid() && f.arrivalTime().isValid()) {
140  return true;
141  }
142  }
143  return SortUtil::startDateTime(reservation).isValid();
144 #else
145  Q_UNUSED(reservation)
146  return false;
147 #endif
148 }
149 
151 {
152  if (reservations.isEmpty()) {
153  return;
154  }
155 
156 #ifdef HAVE_KCAL
157  // TODO pass reservationS into all functions below for multi-traveler support
158  const auto &reservation = reservations.at(0);
159  const int typeId = reservation.userType();
160  if (typeId == qMetaTypeId<FlightReservation>()) {
161  fillFlightReservation(reservations, event);
162  } else if (typeId == qMetaTypeId<LodgingReservation>()) {
163  fillLodgingReservation(reservations, event);
164  } else if (typeId == qMetaTypeId<TrainReservation>()) {
165  fillTrainReservation(reservation.value<TrainReservation>(), event);
166  } else if (typeId == qMetaTypeId<BusReservation>()) {
167  fillBusReservation(reservation.value<BusReservation>(), event);
168  } else if (JsonLd::isA<EventReservation>(reservation)) {
169  fillEventReservation(reservations, event);
170  } else if (JsonLd::isA<Event>(reservation)) {
171  fillEvent(reservation.value<KItinerary::Event>(), event);
172  } else if (JsonLd::isA<FoodEstablishmentReservation>(reservation)) {
173  fillFoodReservation(reservation.value<FoodEstablishmentReservation>(), event);
174  } else if (JsonLd::isA<RentalCarReservation>(reservation)) {
175  fillRentalCarReservation(reservation.value<RentalCarReservation>(), event);
176  } else if (JsonLd::isA<TaxiReservation>(reservation)) {
177  fillTaxiReservation(reservation.value<TaxiReservation>(), event);
178  } else {
179  return;
180  }
181 
182  if (JsonLd::canConvert<Reservation>(reservation) && JsonLd::convert<Reservation>(reservation).reservationStatus() == Reservation::ReservationCancelled) {
183  event->setTransparency(KCalendarCore::Event::Transparent);
184  event->setSummary(i18nc("canceled train/flight/loading reservation", "Canceled: %1", event->summary()));
185  event->clearAlarms();
186  }
187 
188  if (!event->uid().startsWith(QLatin1String("KIT-"))) {
189  event->setUid(QLatin1String("KIT-") + event->uid());
190  }
191 
192  const auto payload = QJsonDocument(JsonLdDocument::toJson(reservations)).toJson(QJsonDocument::Compact);
193  event->setCustomProperty("KITINERARY", "RESERVATION", QString::fromUtf8(payload));
194 #else
195  Q_UNUSED(event)
196 #endif
197 }
198 
199 #ifdef HAVE_KCAL
200 static QString airportDisplayCode(const Airport &airport)
201 {
202  return airport.iataCode().isEmpty() ? airport.name() : airport.iataCode();
203 }
204 
205 static void fillFlightReservation(const QVector<QVariant> &reservations, const KCalendarCore::Event::Ptr &event)
206 {
207  const auto flight = reservations.at(0).value<FlightReservation>().reservationFor().value<Flight>();
208  const auto airline = flight.airline();
209  const auto depPort = flight.departureAirport();
210  const auto arrPort = flight.arrivalAirport();
211 
212  const QString flightNumber = airline.iataCode() + QLatin1Char(' ') + flight.flightNumber();
213 
214  event->setSummary(i18n("Flight %1 from %2 to %3", flightNumber, airportDisplayCode(depPort), airportDisplayCode(arrPort)));
215  event->setLocation(depPort.name());
216  fillGeoPosition(depPort, event);
217  event->setDtStart(flight.departureTime());
218  event->setDtEnd(flight.arrivalTime());
219  event->setAllDay(false);
220 
221  const auto boardingTime = flight.boardingTime();
222  const auto departureGate = flight.departureGate();
223  if (boardingTime.isValid()) {
224  const auto startOffset = Duration(event->dtStart(), boardingTime);
225  const auto existinAlarms = event->alarms();
226  const auto it = std::find_if(existinAlarms.begin(), existinAlarms.end(), [startOffset](const Alarm::Ptr &other) {
227  return other->startOffset() == startOffset;
228  });
229  if (it == existinAlarms.end()) {
230  Alarm::Ptr alarm(new Alarm(event.data()));
231  alarm->setStartOffset(Duration(event->dtStart(), boardingTime));
232  if (departureGate.isEmpty()) {
233  alarm->setDisplayAlarm(i18n("Boarding for flight %1", flightNumber));
234  } else {
235  alarm->setDisplayAlarm(i18n("Boarding for flight %1 at gate %2", flightNumber, departureGate));
236  }
237  alarm->setEnabled(true);
238  event->addAlarm(alarm);
239  }
240  }
241 
242  QStringList desc;
243  if (boardingTime.isValid()) {
244  desc.push_back(i18n("Boarding time: %1", QLocale().toString(boardingTime.time(), QLocale::ShortFormat)));
245  }
246  if (!departureGate.isEmpty()) {
247  desc.push_back(i18nc("flight departure gate", "Departure gate: %1", departureGate));
248  }
249 
250  for (const auto &r : reservations) {
251  const auto reservation = r.value<FlightReservation>();
252  const auto person = reservation.underName().value<KItinerary::Person>();
253  if (!person.name().isEmpty()) {
254  desc.push_back(person.name());
255  }
256  if (!reservation.boardingGroup().isEmpty()) {
257  desc.push_back(i18n("Boarding group: %1", reservation.boardingGroup()));
258  }
259  if (!reservation.airplaneSeat().isEmpty()) {
260  desc.push_back(i18n("Seat: %1", reservation.airplaneSeat()));
261  }
262  if (!reservation.reservationNumber().isEmpty()) {
263  desc.push_back(i18n("Booking reference: %1", reservation.reservationNumber()));
264  }
265  }
266  event->setDescription(desc.join(QLatin1Char('\n')));
267 }
268 
269 static void fillTrainReservation(const TrainReservation &reservation, const KCalendarCore::Event::Ptr &event)
270 {
271  const auto trip = reservation.reservationFor().value<TrainTrip>();
272  const auto depStation = trip.departureStation();
273  const auto arrStation = trip.arrivalStation();
274 
275  event->setSummary(i18n("Train %1 from %2 to %3", trip.trainNumber(), depStation.name(), arrStation.name()));
276  event->setLocation(depStation.name());
277  fillGeoPosition(depStation, event);
278  event->setDtStart(trip.departureTime());
279  event->setDtEnd(trip.arrivalTime());
280  event->setAllDay(false);
281 
282  QStringList desc;
283  if (!trip.departurePlatform().isEmpty()) {
284  desc.push_back(i18n("Departure platform: %1", trip.departurePlatform()));
285  }
286  const auto ticket = reservation.reservedTicket().value<Ticket>();
287  const auto seat = ticket.ticketedSeat();
288  if (!seat.seatSection().isEmpty()) {
289  desc.push_back(i18n("Coach: %1", seat.seatSection()));
290  }
291  if (!seat.seatNumber().isEmpty()) {
292  desc.push_back(i18n("Seat: %1", seat.seatNumber()));
293  }
294  if (!trip.arrivalPlatform().isEmpty()) {
295  desc.push_back(i18n("Arrival platform: %1", trip.arrivalPlatform()));
296  }
297  if (!reservation.reservationNumber().isEmpty()) {
298  desc.push_back(i18n("Booking reference: %1", reservation.reservationNumber()));
299  }
300  event->setDescription(desc.join(QLatin1Char('\n')));
301 }
302 
303 static void fillBusReservation(const BusReservation &reservation, const KCalendarCore::Event::Ptr &event)
304 {
305  const auto trip = reservation.reservationFor().value<BusTrip>();
306  const auto depStation = trip.departureBusStop();
307  const auto arrStation = trip.arrivalBusStop();
308 
309  event->setSummary(i18n("Bus %1 from %2 to %3", trip.busNumber(), depStation.name(), arrStation.name()));
310  event->setLocation(depStation.name());
311  fillGeoPosition(depStation, event);
312  event->setDtStart(trip.departureTime());
313  event->setDtEnd(trip.arrivalTime());
314  event->setAllDay(false);
315 
316  QStringList desc;
317  const auto ticket = reservation.reservedTicket().value<Ticket>();
318  const auto seat = ticket.ticketedSeat();
319  if (!seat.seatNumber().isEmpty()) {
320  desc.push_back(i18n("Seat: %1", seat.seatNumber()));
321  }
322  if (!reservation.reservationNumber().isEmpty()) {
323  desc.push_back(i18n("Booking reference: %1", reservation.reservationNumber()));
324  }
325  event->setDescription(desc.join(QLatin1Char('\n')));
326 }
327 
328 static void fillLodgingReservation(const QVector<QVariant> &reservations, const KCalendarCore::Event::Ptr &event)
329 {
330  const auto reservation = reservations.at(0).value<LodgingReservation>();
331  const auto lodgingBusiness = reservation.reservationFor().value<LodgingBusiness>();
332 
333  event->setSummary(i18n("Hotel reservation: %1", lodgingBusiness.name()));
334  event->setLocation(formatAddressSingleLine(lodgingBusiness.address()));
335  fillGeoPosition(lodgingBusiness, event);
336 
337  event->setDtStart(QDateTime(reservation.checkinTime().date(), QTime()));
338  event->setDtEnd(QDateTime(reservation.checkoutTime().date(), QTime()));
339  event->setAllDay(true);
340  event->setTransparency(KCalendarCore::Event::Transparent);
341 
342  QStringList desc;
343  if (reservation.checkinTime().isValid()) {
344  desc.push_back(i18n("Check-in: %1", QLocale().toString(reservation.checkinTime().time(), QLocale::ShortFormat)));
345  }
346  if (reservation.checkoutTime().isValid()) {
347  desc.push_back(i18n("Check-out: %1", QLocale().toString(reservation.checkoutTime().time(), QLocale::ShortFormat)));
348  }
349  if (!lodgingBusiness.telephone().isEmpty()) {
350  desc.push_back(i18n("Phone: %1", lodgingBusiness.telephone()));
351  }
352  if (!lodgingBusiness.email().isEmpty()) {
353  desc.push_back(i18n("Email: %1", lodgingBusiness.email()));
354  }
355  if (!lodgingBusiness.url().isEmpty()) {
356  desc.push_back(i18n("Website: %1", lodgingBusiness.url().toString()));
357  }
358 
359  for (const auto &r : reservations) {
360  const auto reservation = r.value<LodgingReservation>();
361  const auto person = reservation.underName().value<KItinerary::Person>();
362  if (!person.name().isEmpty()) {
363  desc.push_back(person.name());
364  }
365  if (!reservation.reservationNumber().isEmpty()) {
366  desc.push_back(i18n("Booking reference: %1", reservation.reservationNumber()));
367  }
368  }
369  event->setDescription(desc.join(QLatin1Char('\n')));
370 }
371 
372 static void fillEvent(const KItinerary::Event &ev, const KCalendarCore::Event::Ptr &event)
373 {
374  Place location;
375  if (JsonLd::canConvert<Place>(ev.location())) {
376  location = JsonLd::convert<Place>(ev.location());
377  }
378 
379  event->setSummary(ev.name());
380  event->setLocation(location.name());
381  fillGeoPosition(location, event);
382  event->setDtStart(ev.startDate());
383  if (ev.endDate().isValid()) {
384  event->setDtEnd(ev.endDate());
385  } else {
386  event->setDtEnd(ev.startDate().addSecs(3600));
387  }
388  event->setAllDay(false);
389 
390  if (ev.doorTime().isValid()) {
391  const auto startOffset = Duration(event->dtStart(), ev.doorTime());
392  const auto existinAlarms = event->alarms();
393  const auto it = std::find_if(existinAlarms.begin(), existinAlarms.end(), [startOffset](const Alarm::Ptr &other) {
394  return other->startOffset() == startOffset;
395  });
396  if (it == existinAlarms.end()) {
397  Alarm::Ptr alarm(new Alarm(event.data()));
398  alarm->setStartOffset(Duration(event->dtStart(), ev.doorTime()));
399  alarm->setDisplayAlarm(i18n("Entrance for %1", ev.name()));
400  alarm->setEnabled(true);
401  event->addAlarm(alarm);
402  }
403  }
404 
405  event->setDescription(formatAddress(location.address()) + QLatin1Char('\n'));
406 }
407 
408 static void fillEventReservation(const QVector<QVariant> &reservations, const KCalendarCore::Event::Ptr &event)
409 {
410  const auto ev = reservations.at(0).value<EventReservation>().reservationFor().value<KItinerary::Event>();
411  fillEvent(ev, event);
412 
413  QStringList desc = { event->description() };
414  for (const auto &r : reservations) {
415  const auto reservation = r.value<EventReservation>();
416  const auto person = reservation.underName().value<KItinerary::Person>();
417  if (!person.name().isEmpty()) {
418  desc.push_back(person.name());
419  }
420  // TODO: add seat information if present
421  if (!reservation.reservationNumber().isEmpty()) {
422  desc.push_back(i18n("Booking reference: %1", reservation.reservationNumber()));
423  }
424  }
425  event->setDescription(desc.join(QLatin1Char('\n')));
426 }
427 
428 static void fillGeoPosition(const QVariant &place, const KCalendarCore::Event::Ptr &event)
429 {
430  if (!JsonLd::canConvert<Place>(place)) {
431  return;
432  }
433  const auto geo = JsonLd::convert<Place>(place).geo();
434  if (!geo.isValid()) {
435  return;
436  }
437 
438  event->setGeoLatitude(geo.latitude());
439  event->setGeoLongitude(geo.longitude());
440 }
441 
442 static void fillFoodReservation(const FoodEstablishmentReservation &reservation, const KCalendarCore::Event::Ptr &event)
443 {
444  const auto foodEstablishment = reservation.reservationFor().value<FoodEstablishment>();
445 
446  event->setSummary(i18n("Restaurant reservation: %1", foodEstablishment.name()));
447  event->setLocation(formatAddressSingleLine(foodEstablishment.address()));
448  fillGeoPosition(foodEstablishment, event);
449 
450  event->setDtStart(reservation.startTime());
451  auto endTime = reservation.endTime();
452  if (!endTime.isValid()) {
453  endTime = reservation.startTime().addSecs(7200); // if we have no end time, let's assume 2h
454  }
455  event->setDtEnd(endTime);
456  event->setAllDay(false);
457 
458  QStringList desc;
459  if (reservation.partySize() > 0) {
460  desc.push_back(i18n("Number of people: %1", reservation.partySize()));
461  }
462  if (!reservation.reservationNumber().isEmpty()) {
463  desc.push_back(i18n("Booking reference: %1", reservation.reservationNumber()));
464  }
465  const auto person = reservation.underName().value<KItinerary::Person>();
466  if (!person.name().isEmpty()) {
467  desc.push_back(i18n("Under name: %1", person.name()));
468  }
469  event->setDescription(desc.join(QLatin1Char('\n')));
470 }
471 
472 static void fillRentalCarReservation(const RentalCarReservation &reservation, const KCalendarCore::Event::Ptr &event)
473 {
474  const auto rentalCalPickup = reservation.pickupLocation();
475  const auto addressPickUp = rentalCalPickup.address();
476  const auto rentalCar = reservation.reservationFor().value<RentalCar>();
477  event->setSummary(i18n("Rental car reservation: %1", rentalCar.name()));
478  event->setLocation(rentalCalPickup.name());
479  fillGeoPosition(rentalCalPickup, event);
480 
481  event->setDtStart(reservation.pickupTime());
482  event->setDtEnd(reservation.dropoffTime());
483  event->setAllDay(false);
484  event->setTransparency(KCalendarCore::Event::Transparent);
485 
486  QStringList desc;
487  if (!addressPickUp.isEmpty()) {
488  desc.push_back(i18n("Pickup location: %1\n%2\n", rentalCalPickup.name(), formatAddress(addressPickUp)));
489  }
490  const auto dropOff = reservation.dropoffLocation();
491  if (!dropOff.name().isEmpty()) {
492  desc.push_back(i18n("Dropoff location: %1\n%2\n", dropOff.name(), formatAddress(dropOff.address())));
493  }
494  if (!reservation.reservationNumber().isEmpty()) {
495  desc.push_back(i18n("Booking reference: %1", reservation.reservationNumber()));
496  }
497  const auto person = reservation.underName().value<KItinerary::Person>();
498  if (!person.name().isEmpty()) {
499  desc.push_back(i18n("Under name: %1", person.name()));
500  }
501 
502  event->setDescription(desc.join(QLatin1Char('\n')));
503 }
504 
505 static void fillTaxiReservation(const TaxiReservation &reservation, const KCalendarCore::Event::Ptr &event)
506 {
507  const auto taxiPickup = reservation.pickupLocation();
508  const auto addressPickUp = taxiPickup.address();
509  //TODO const auto rentalCar = reservation.reservationFor().value<RentalCar>();
510  //TODO event->setSummary(i18n("Rental Car reservation: %1", rentalCar.name()));
511  event->setLocation(formatAddressSingleLine(addressPickUp));
512  fillGeoPosition(taxiPickup, event);
513 
514  event->setDtStart(reservation.pickupTime());
515  //TODO event->setDtEnd(reservation.dropoffTime());
516  event->setAllDay(false);
517  event->setTransparency(KCalendarCore::Event::Transparent);
518  //TODO event->setSummary(i18n("Rent car reservation: %1", rentalCar.name()));
519  const QString pickUpAddress = formatAddress(addressPickUp);
520 
521  const QString description = i18n("Reservation reference: %1\nUnder name: %2\nPickup location: %3",
522  reservation.reservationNumber(),
523  reservation.underName().value<KItinerary::Person>().name(),
524  pickUpAddress);
525 
526  event->setDescription(description);
527 }
528 
529 #endif
T * data() const const
A train reservation.
Definition: reservation.h:99
bool isEmpty() const const
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
void fillEvent(const QVector< QVariant > &reservations, const QSharedPointer< KCalendarCore::Event > &event)
Fills event with details of reservations.
QVariant location(const QVariant &res)
Returns the location of a non-transport reservation.
A Taxi reservation.
Definition: reservation.h:148
QString fromUtf8(const char *str, int size)
A booked ticket.
Definition: ticket.h:36
Food-related business (such as a restaurant, or a bakery).
Definition: organization.h:89
bool isSame(const QVariant &lhs, const QVariant &rhs)
Checks if two Reservation or Trip values refer to the same booking element.
Definition: mergeutil.cpp:80
T value() const const
void push_back(const T &value)
An event reservation.
Definition: reservation.h:128
void push_back(const T &value)
A person.
Definition: person.h:19
static QJsonArray toJson(const QVector< QVariant > &data)
Serialize instantiated data types to JSON-LD.
bool canCreateEvent(const QVariant &reservation)
Checks if the given reservation contains enough information to create an iCal event from it.
QDateTime toTimeZone(const QTimeZone &timeZone) const const
A bus trip.
Definition: bustrip.h:21
A hotel reservation.
Definition: reservation.h:70
static QVector< QVariant > fromJson(const QJsonArray &array)
Convert JSON-LD array into instantiated data types.
QString i18n(const char *text, const TYPE &arg...)
Base class for places.
Definition: place.h:68
A bus reservation.
Definition: reservation.h:107
char * toString(const T &value)
const T & at(int i) const const
KITINERARY_DEPRECATED_EXPORT QSharedPointer< KCalendarCore::Event > findEvent(const QSharedPointer< KCalendarCore::Calendar > &calendar, const QVariant &reservation)
Attempts to find an event in calendar for reservation.
An event.
Definition: event.h:20
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
GeoCoordinates geo(const QVariant &location)
Returns the geo coordinates of a given location.
QString join(const QString &separator) const const
Postal address.
Definition: place.h:45
QDateTime startDateTime(const QVariant &elem)
Returns the (start) time associated with the given element.
Definition: sortutil.cpp:28
A car rental.
Definition: rentalcar.h:21
QVector< QSharedPointer< KCalendarCore::Event > > findEvents(const QSharedPointer< KCalendarCore::Calendar > &calendar, const QVariant &reservation)
Attempts to find calendar events in calendar for reservation.
Airport.
Definition: place.h:102
QVector< QVariant > reservationsForEvent(const QSharedPointer< KCalendarCore::Event > &event)
Returns the reservations for this event.
A flight.
Definition: flight.h:24
QJsonArray array() const const
QDate date() const const
bool isValid() const const
QByteArray toJson() const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
A Rental Car reservation.
Definition: reservation.h:136
A train trip.
Definition: traintrip.h:23
A flight reservation.
Definition: reservation.h:81
QSharedPointer< Event > Ptr
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu May 19 2022 03:54:55 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.