(reservation);
const auto data = memento->rawPassData(res.pkpassPassTypeIdentifier(), res.pkpassSerialNumber());
if (data.isEmpty()) {
return;
}
event->deleteAttachments(QStringLiteral("application/vnd.apple.pkpass"));
using namespace KCalendarCore;
Attachment att(data.toBase64(), QStringLiteral("application/vnd.apple.pkpass"));
att.setLabel(i18n("Boarding Pass")); // TODO add passenger name after string freeze is lifted
event->addAttachment(att);
}
}
void ItineraryUrlHandler::addToCalendar(ItineraryMemento *memento) const
{
using namespace KCalendarCore;
const auto calendar = CalendarSupport::calendarSingleton(true);
for (const auto &d : memento->data()) {
auto event = d.event;
if (!event) {
event.reset(new KCalendarCore::Event);
CalendarHandler::fillEvent(d.reservations, event);
if (!event->dtStart().isValid() || !event->dtEnd().isValid() || event->summary().isEmpty()) {
continue;
}
attachPass(event, d.reservations, memento);
calendar->addEvent(event);
} else {
event->startUpdates();
CalendarHandler::fillEvent(d.reservations, event);
event->endUpdates();
attachPass(event, d.reservations, memento);
calendar->modifyIncidence(event);
}
}
}
void ItineraryUrlHandler::openInApp(MimeTreeParser::Interface::BodyPart *part) const
{
const auto fileName = createItineraryFile(part);
QProcess::startDetached(m_appPath, {fileName});
}
void ItineraryUrlHandler::openWithKDEConnect(MimeTreeParser::Interface::BodyPart *part, const QString &deviceId) const
{
const auto fileName = createItineraryFile(part);
QDBusInterface remoteApp(QStringLiteral("org.kde.kdeconnect"), QStringLiteral("/MainApplication"), QStringLiteral("org.qtproject.Qt.QCoreApplication"));
QVersionNumber kdeconnectVersion = QVersionNumber::fromString(remoteApp.property("applicationVersion").toString());
QString method;
if (kdeconnectVersion >= QVersionNumber(1, 4, 0)) {
method = QStringLiteral("openFile");
} else {
method = QStringLiteral("shareUrl");
}
QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect"),
QStringLiteral("/modules/kdeconnect/devices/") + deviceId + QStringLiteral("/share"),
QStringLiteral("org.kde.kdeconnect.device.share"), method);
msg.setArguments({QUrl::fromLocalFile(fileName).toString()});
QDBusConnection::sessionBus().send(msg);
}
QString ItineraryUrlHandler::createItineraryFile(MimeTreeParser::Interface::BodyPart *part) const
{
QTemporaryFile f(QStringLiteral("XXXXXX.itinerary"));
if (!f.open()) {
qCWarning(ITINERARY_LOG) << "Failed to open temporary file:" << f.errorString();
return {};
}
f.close();
part->nodeHelper()->addTempFile(f.fileName());
f.setAutoRemove(false);
KItinerary::File file(f.fileName());
if (!file.open(KItinerary::File::Write)) {
qCWarning(ITINERARY_LOG) << "Failed to open itinerary bundle file:" << file.errorString();
return {};
}
const auto m = memento(part);
// add reservations
const auto extractedData = m->data();
for (const auto &d : extractedData) {
for (const auto &res : d.reservations) {
file.addReservation(res);
}
}
// add pkpass attachments
for (const auto &passData : m->passData()) {
file.addPass(KItinerary::File::passId(passData.passTypeIdentifier, passData.serialNumber), passData.rawData);
}
// add documents
for (const auto &docData : m->documentData()) {
file.addDocument(docData.docId, docData.docInfo, docData.rawData);
}
return f.fileName();
}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/busreservation.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/busreservation.html
index 136d5411..83b93a2f 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/busreservation.html
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/busreservation.html
@@ -1,54 +1,56 @@
{{ trip.departureBusStop.name }}
{% if trip.departurePlatform %}
[{{ trip.departurePlatform }}]
{% endif %}
+ {% with trip.departureBusStop as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
|
→ |
{{ trip.arrivalBusStop.name }}
{% if trip.arrivalPlatform %}
[{{ trip.arrivalPlatform }}]
{% endif %}
+ {% with trip.arrivalBusStop as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
|
{{ trip.departureTime|formatDateTime }} |
{% if trip.busName and trip.busNumber %}
{{ trip.busName }} {{ trip.busNumber }}
{% else %}
{{ trip.busName }} {{ trip.busNumber }}
{% endif %}
|
{{ trip.arrivalTime|formatDateTime }} |
{% include "org.kde.messageviewer/itinerary/actions.html" %}
|
{% if elem.state.expanded %}
{% endif %}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/event.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/event.html
index 4fe3ec57..9222d5fc 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/event.html
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/event.html
@@ -1,11 +1,14 @@
{{ trip.name }}
{{ trip.startDate|formatDateTime }}
- {{ trip.location.name }}
- {{ trip.location.address|formatAddress|safe }}
+ {{ trip.location.name }}
+ {% with trip.location as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
+ {% if not trip.location.address.isEmpty %}
+
{{ trip.location.address|formatAddress|safe }}
+ {% endif %}
{% if res.underName.name %}
{% i18n "Under Name: %1" res.underName.name %}
{% endif %}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/flightreservation.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/flightreservation.html
index 1800e7d2..59a0780a 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/flightreservation.html
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/flightreservation.html
@@ -1,85 +1,87 @@
- {% if trip.departureAirport.iataCode %}
-
- {{ trip.departureAirport.iataCode }}
- |
- {% else %}
- {{ trip.departureAirport.name }} |
- {% endif %}
+
+ {% if trip.departureAirport.iataCode %}
+ {{ trip.departureAirport.iataCode }}
+ {% else %}
+ {{ trip.departureAirport.name }}
+ {% endif %}
+ {% with trip.departureAirport as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
+ |
✈ |
- {% if trip.arrivalAirport.iataCode %}
-
- {{ trip.arrivalAirport.iataCode }}
- |
- {% else %}
- {{ trip.arrivalAirport.name }} |
- {% endif %}
+
+ {% if trip.arrivalAirport.iataCode %}
+ {{ trip.arrivalAirport.iataCode }}
+ {% else %}
+ {{ trip.arrivalAirport.name }}
+ {% endif %}
+ {% with trip.arrivalAirport as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
+ |
{% if trip.departureTime %}
{{ trip.departureTime|formatDateTime }}
{% else %}
{{ trip.departureDay|formatDate }}
{% endif %}
|
{{ trip.airline.iataCode }} {{ trip.flightNumber }} |
{{ trip.arrivalTime|formatDateTime }} |
{% if elem.reservations.0.ticketToken or elem.reservations.size > 1 %}
{% if elem.state.expanded %}
{% else %}
{% endif %}
{% endif %}
{% if trip.departureGate %}
{% i18n "Gate: %1" trip.departureGate %}
{% endif %}
{% if trip.boardingTime %}
{% i18n "Boarding: %1" trip.boardingTime|formatTime %}
{% endif %}
{% if res.boardingGroup and elem.reservations.size == 1 and not elem.state.expanded %}
{% i18n "Group: %1" res.boardingGroup %}
{% endif %}
{% if res.airplaneSeat and elem.reservations.size == 1 and not elem.state.expanded %}
{% i18n "Seat: %1" res.airplaneSeat %}
{% endif %}
{% if elem.reservations.size == 1 %}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
{% endif %}
|
{% if elem.state.expanded %}
{% for d in elem.reservations %}
{% with d.reservation as res %}
{% if res.underName.name %}
{{ res.underName.name }}
{% endif %}
{% if res.boardingGroup %} {% i18n "Group: %1" res.boardingGroup %} {% endif %}
{% if res.airplaneSeat %} {% i18n "Seat: %1" res.airplaneSeat %} {% endif %}
{% if d.ticketToken %}
{% endif %}
{% if elem.reservations.size > 1 %}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
{% endif %}
{% endwith %}
{% endfor %}
{% endif %}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/foodestablishmentreservation.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/foodestablishmentreservation.html
index beb885ba..185c3c98 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/foodestablishmentreservation.html
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/foodestablishmentreservation.html
@@ -1,13 +1,15 @@
-{{ trip.name }} - {{ res.startTime|formatDateTime }}
+{{ trip.name }}
+ {% with trip as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
+ - {{ res.startTime|formatDateTime }}
{% if res.partySize > 0 %}
{% i18n "Number Of People: %1" res.partySize %}
{% endif %}
{% if res.reservationNumber %}
{% i18n "Reservation Number: %1" res.reservationNumber %}
{% endif %}
{% if res.underName.name %}
{% i18n "Under Name: %1" res.underName.name %}
{% endif %}
{{ trip.address|formatAddress|safe }}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/location.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/location.html
new file mode 100644
index 00000000..6f458154
--- /dev/null
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/location.html
@@ -0,0 +1,13 @@
+{% if location.geo.isValid %}
+
+{% elif location.address.addressLocality or location.address.streetAddress %}
+
+{% endif %}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/lodgingreservation.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/lodgingreservation.html
index 066f5bda..a134577f 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/lodgingreservation.html
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/lodgingreservation.html
@@ -1,4 +1,6 @@
-{{ trip.name }} {{ res.checkinTime|formatDate }} - {{ res.checkoutTime|formatDate }}
+{{ trip.name }}
+ {% with trip as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
+ {{ res.checkinTime|formatDate }} - {{ res.checkoutTime|formatDate }}
{{ trip.address|formatAddress|safe }}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/rentalcarreservation.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/rentalcarreservation.html
index 1afa01dc..e2b73b1e 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/rentalcarreservation.html
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/rentalcarreservation.html
@@ -1,16 +1,17 @@
{% if trip.rentalCompany.name %}
{{ trip.rentalCompany.name }}:
{% endif %}
{{ trip.name }}
{% if trip.name and trip.model %}({% endif %}
{{ trip.model }}
{% if trip.name and trip.model %}){% endif %}
{{ res.pickupTime|formatDateTime }} - {{ res.dropoffTime|formatDateTime }}
{{ res.pickupLocation.name }}
+ {% with trip.pickupLocation as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
{{ res.pickupLocation|formatAddress|safe }}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/templates.qrc b/plugins/messageviewer/bodypartformatter/itinerary/templates/templates.qrc
index ffc3d784..f0d1c7bd 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/templates.qrc
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/templates.qrc
@@ -1,14 +1,15 @@
itinerary.html
flightreservation.html
+ location.html
lodgingreservation.html
trainreservation.html
busreservation.html
event.html
actions.html
foodestablishmentreservation.html
rentalcarreservation.html
taxireservation.html
diff --git a/plugins/messageviewer/bodypartformatter/itinerary/templates/trainreservation.html b/plugins/messageviewer/bodypartformatter/itinerary/templates/trainreservation.html
index 2f4a012c..40d0631f 100644
--- a/plugins/messageviewer/bodypartformatter/itinerary/templates/trainreservation.html
+++ b/plugins/messageviewer/bodypartformatter/itinerary/templates/trainreservation.html
@@ -1,84 +1,86 @@
{{ trip.departureStation.name }}
{% if trip.departurePlatform %}
[{{ trip.departurePlatform }}]
{% endif %}
+ {% with trip.departureStation as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
|
→ |
{{ trip.arrivalStation.name}}
{% if trip.arrivalPlatform %}
[{{ trip.arrivalPlatform }}]
{% endif %}
+ {% with trip.arrivalStation as location %}{% include "org.kde.messageviewer/itinerary/location.html" %}{% endwith %}
|
{% if trip.departureTime %}
{{ trip.departureTime|formatDateTime }}
{% else %}
{{ trip.departureDay|formatDate }}
{% endif %}
|
{% if trip.trainName and trip.trainNumber %}
{{ trip.trainName }} {{ trip.trainNumber }}
{% else %}
{{ trip.trainName }} {{ trip.trainNumber }}
{% endif %}
|
{{ trip.arrivalTime|formatDateTime }} |
{% if elem.reservations.0.ticketToken or elem.reservations.size > 1 %}
{% if elem.state.expanded %}
{% else %}
{% endif %}
{% endif %}
{% if res.reservedTicket.ticketedSeat.seatSection and not elem.state.expanded %}
{% i18n "Coach: %1" res.reservedTicket.ticketedSeat.seatSection %}
{% endif %}
{% if res.reservedTicket.ticketedSeat.seatNumber and not elem.state.expanded %}
{% i18n "Seat: %1" res.reservedTicket.ticketedSeat.seatNumber %}
{% endif %}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
|
{% if elem.state.expanded %}
{% for d in elem.reservations %}
{% with d.reservation as res %}
{% if res.underName.name %}
{{ res.underName.name }}
{% endif %}
{% if res.reservedTicket.ticketedSeat.seatSection %}
{% i18n "Coach: %1" res.reservedTicket.ticketedSeat.seatSection %}
{% endif %}
{% if res.reservedTicket.ticketedSeat.seatNumber %}
{% i18n "Seat: %1" res.reservedTicket.ticketedSeat.seatNumber %}
{% endif %}
{% if d.ticketToken %}
{% endif %}
{% if elem.reservations.size > 1 %}
{% include "org.kde.messageviewer/itinerary/actions.html" %}
{% endif %}
{% endwith %}
{% endfor %}
{% endif %}