KItinerary

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

KDE's Doxygen guidelines are available online.