diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,7 @@ set(AKONADICONTACT_LIB_VERSION "5.7.80") set(IMPORTWIZARD_LIB_VERSION "5.7.80") set(MAILIMPORTER_LIB_VERSION "5.7.80") +set(KPIMPKPASS_LIB_VERSION "5.8.40") find_package(KF5CalendarUtils ${CALENDAR_UTILS_VERSION} CONFIG REQUIRED) find_package(KF5WebEngineViewer ${MESSAGELIB_LIB_VERSION} CONFIG REQUIRED) @@ -120,6 +121,7 @@ find_package(KF5AkonadiContact ${AKONADICONTACT_LIB_VERSION} CONFIG REQUIRED) find_package(KPimImportWizard ${IMPORTWIZARD_LIB_VERSION} CONFIG) find_package(KF5MailImporterAkonadi ${MAILIMPORTER_LIB_VERSION} CONFIG REQUIRED) +find_package(KPimPkPass ${KPIMPKPASS_LIB_VERSION} CONFIG REQUIRED) add_definitions(-DQT_NO_CAST_FROM_ASCII) add_definitions(-DQT_NO_CAST_TO_ASCII) add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) @@ -134,8 +136,6 @@ # Extra package find_package(Gpgmepp 1.8.0 CONFIG) set_package_properties(Gpgmepp PROPERTIES DESCRIPTION "GpgME library" URL "http://www.gnupg.org" TYPE REQUIRED) -set(SharedMimeInfo_MINIMUM_VERSION "1.3") -find_package(SharedMimeInfo ${SharedMimeInfo_MINIMUM_VERSION} REQUIRED) find_package(Poppler COMPONENTS Qt5) set_package_properties("Poppler" PROPERTIES TYPE OPTIONAL PURPOSE "Support for PDF booking confirmations in the semantic extraction plugin.") diff --git a/plugins/messageviewer/bodypartformatter/pkpass/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/pkpass/CMakeLists.txt --- a/plugins/messageviewer/bodypartformatter/pkpass/CMakeLists.txt +++ b/plugins/messageviewer/bodypartformatter/pkpass/CMakeLists.txt @@ -1,9 +1,6 @@ add_definitions(-DTRANSLATION_DOMAIN=\"messageviewer_bodypartformatter_pkpass\") set(pkpass_srcs - pkpassfield.cpp - pkpassfile.cpp - pkpassboardingpass.cpp pkpass_plugin.cpp ) qt5_add_resources(pkpass_srcs templates.qrc) @@ -15,8 +12,7 @@ KF5::Prison KF5::MessageViewer Grantlee5::Templates + KPim::PkPass ) install(TARGETS messageviewer_bodypartformatter_pkpass DESTINATION ${KDE_INSTALL_PLUGINDIR}/messageviewer/bodypartformatter) -install(FILES application-vnd-apple-pkpass.xml DESTINATION ${XDG_MIME_INSTALL_DIR}) -update_xdg_mimetypes(${XDG_MIME_INSTALL_DIR}) diff --git a/plugins/messageviewer/bodypartformatter/pkpass/application-vnd-apple-pkpass.xml b/plugins/messageviewer/bodypartformatter/pkpass/application-vnd-apple-pkpass.xml deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/pkpass/application-vnd-apple-pkpass.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - Apple Wallet pass - - - diff --git a/plugins/messageviewer/bodypartformatter/pkpass/pkpass_plugin.cpp b/plugins/messageviewer/bodypartformatter/pkpass/pkpass_plugin.cpp --- a/plugins/messageviewer/bodypartformatter/pkpass/pkpass_plugin.cpp +++ b/plugins/messageviewer/bodypartformatter/pkpass/pkpass_plugin.cpp @@ -17,33 +17,39 @@ 02110-1301, USA. */ -#include "pkpassfile.h" -#include "pkpassboardingpass.h" - #include #include #include #include #include +#include +#include + #include #include +#include + #include #include #include // Grantlee has no Q_GADGET support yet -GRANTLEE_BEGIN_LOOKUP(PkPassField) -const auto idx = PkPassField::staticMetaObject.indexOfProperty(property.toUtf8().constData()); -if (idx < 0) { - return {}; -} -const auto mp = PkPassField::staticMetaObject.property(idx); -return mp.readOnGadget(&object); +#define GRANTLEE_MAKE_GADGET(Class) \ +GRANTLEE_BEGIN_LOOKUP(Class) \ + const auto idx = Class::staticMetaObject.indexOfProperty(property.toUtf8().constData()); \ + if (idx < 0) { \ + return {}; \ + } \ + const auto mp = Class::staticMetaObject.property(idx); \ + return mp.readOnGadget(&object); \ GRANTLEE_END_LOOKUP +GRANTLEE_MAKE_GADGET(KPkPass::Barcode) +GRANTLEE_MAKE_GADGET(KPkPass::Field) + namespace { class Formatter : public MessageViewer::MessagePartRendererBase { @@ -56,8 +62,8 @@ return false; } - std::unique_ptr pass(PkPassFile::fromData(msgPart->content()->decodedContent())); - if (!qobject_cast(pass.get())) { + std::unique_ptr pass(KPkPass::Pass::fromData(msgPart->content()->decodedContent())); + if (!qobject_cast(pass.get())) { return false; // only boarding passes implemented so far } const auto dir = mp->nodeHelper()->createTempDir(QStringLiteral("pkpass")); @@ -69,14 +75,38 @@ mp->nodeHelper()->addTempFile(fileName); } - const auto barcode = pass->barcode(); - if (!barcode.isNull()) { - const auto fileName = dir + QStringLiteral("/barcode.png"); - barcode.save(fileName); - pass->setProperty("barcodeUrl", QUrl::fromLocalFile(fileName)); - mp->nodeHelper()->addTempFile(fileName); + const auto barcodes = pass->barcodes(); + if (!barcodes.isEmpty()) { + const auto barcode = barcodes.at(0); + std::unique_ptr code; + switch (barcode.format()) { + case KPkPass::Barcode::QR: + code.reset(Prison::createBarcode(Prison::QRCode)); + break; + case KPkPass::Barcode::Aztec: + code.reset(Prison::createBarcode(Prison::Aztec)); + break; + default: + break; + } + + if (code) { + code->setData(barcode.message()); + code->toImage(code->minimumSize()); // minimumSize is only available after we rendered once... + + const auto fileName = dir + QStringLiteral("/barcode.png"); + code->toImage(code->minimumSize()).save(fileName); + + pass->setProperty("barcodeUrl", QUrl::fromLocalFile(fileName)); + mp->nodeHelper()->addTempFile(fileName); + } } + // Grantlee can't handle QColor... + pass->setProperty("foregroundColorName", pass->foregroundColor().name()); + pass->setProperty("backgroundColorName", pass->backgroundColor().name()); + pass->setProperty("labelColorName", pass->labelColor().name()); + auto c = MessageViewer::MessagePartRendererManager::self()->createContext(); c.insert(QStringLiteral("block"), mp.data()); c.insert(QStringLiteral("pass"), pass.get()); @@ -96,7 +126,8 @@ explicit Plugin(QObject *parent = nullptr) : QObject(parent) { - Grantlee::registerMetaType(); + Grantlee::registerMetaType(); + Grantlee::registerMetaType(); } MessageViewer::MessagePartRendererBase *renderer(int index) override diff --git a/plugins/messageviewer/bodypartformatter/pkpass/pkpassboardingpass.h b/plugins/messageviewer/bodypartformatter/pkpass/pkpassboardingpass.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/pkpass/pkpassboardingpass.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef PKPASSBOARDINGPASS_H -#define PKPASSBOARDINGPASS_H - -#include "pkpassfile.h" - -/** Boarding pass */ -class PkPassBoardingPass : public PkPassFile -{ - Q_OBJECT - Q_PROPERTY(TransitType transitType READ transitType) -public: - enum TransitType { - Air, - Boat, - Bus, - Train, - Generic - }; - Q_ENUM(TransitType) - - explicit PkPassBoardingPass(QObject *parent = nullptr); - ~PkPassBoardingPass() = default; - - TransitType transitType() const; -}; - -#endif // PKPASSBOARDINGPASS_H diff --git a/plugins/messageviewer/bodypartformatter/pkpass/pkpassboardingpass.cpp b/plugins/messageviewer/bodypartformatter/pkpass/pkpassboardingpass.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/pkpass/pkpassboardingpass.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "pkpassboardingpass.h" - -PkPassBoardingPass::PkPassBoardingPass(QObject *parent) - : PkPassFile(QStringLiteral("boardingPass"), parent) -{ -} - -PkPassBoardingPass::TransitType PkPassBoardingPass::transitType() const -{ - const auto t = passData().value(QLatin1String("transitType")).toString(); - if (t == QLatin1String("PKTransitTypeAir")) { - return Air; - } else if (t == QLatin1String("PKTransitTypeBoat")) { - return Boat; - } else if (t == QLatin1String("PKTransitTypeBus")) { - return Bus; - } else if (t == QLatin1String("PKTransitTypeTrain")) { - return Train; - } - return Generic; -} diff --git a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfield.h b/plugins/messageviewer/bodypartformatter/pkpass/pkpassfield.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfield.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef PKPASSFIELD_H -#define PKPASSFIELD_H - -#include -#include - -class PkPassFile; -class QJsonObject; - -/** Field element in a PkPassFile. */ -class PkPassField -{ - Q_GADGET - Q_PROPERTY(QString label READ label CONSTANT) - Q_PROPERTY(QString value READ value CONSTANT) -public: - PkPassField() = default; - explicit PkPassField(const QJsonObject &obj, const PkPassFile *file); - ~PkPassField() = default; - - QString label() const; - QString value() const; - -private: - QString m_label; - QString m_value; -}; - -Q_DECLARE_METATYPE(PkPassField) - -#endif // PKPASSFIELD_H diff --git a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfield.cpp b/plugins/messageviewer/bodypartformatter/pkpass/pkpassfield.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfield.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "pkpassfield.h" -#include "pkpassfile.h" - -#include - -PkPassField::PkPassField(const QJsonObject &obj, const PkPassFile *file) -{ - m_label = file->message(obj.value(QLatin1String("label")).toString()); - m_value = file->message(obj.value(QLatin1String("value")).toString()); -} - -QString PkPassField::label() const -{ - return m_label; -} - -QString PkPassField::value() const -{ - return m_value; -} diff --git a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfile.h b/plugins/messageviewer/bodypartformatter/pkpass/pkpassfile.h deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfile.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#ifndef PKPASSFILE_H -#define PKPASSFILE_H - -#include "pkpassfield.h" - -#include -#include -#include -#include -#include - -#include - -class KZip; -class QBuffer; -class QLatin1String; -class QString; - -/** Base class for a pkpass file. */ -class PkPassFile : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString backgroundColor READ backgroundColor CONSTANT) - Q_PROPERTY(QString foregroundColor READ foregroundColor CONSTANT) - Q_PROPERTY(QString labelColor READ labelColor CONSTANT) - Q_PROPERTY(QString logoText READ logoText CONSTANT) - Q_PROPERTY(QString barcodeAltText READ barcodeAltText CONSTANT) - - Q_PROPERTY(QVector auxiliaryFields READ auxiliaryFields CONSTANT) - Q_PROPERTY(QVector backFields READ backFields CONSTANT) - Q_PROPERTY(QVector headerFields READ headerFields CONSTANT) - Q_PROPERTY(QVector primaryFields READ primaryFields CONSTANT) - Q_PROPERTY(QVector secondaryFields READ secondaryFields CONSTANT) - -public: - ~PkPassFile(); - - /** Content of the pass.json file. */ - QJsonObject data() const; - /** The pass data structure of the pass.json file. */ - QJsonObject passData() const; - /** Localized message for the given key. */ - QString message(const QString &key) const; - - QString backgroundColor() const; - QString foregroundColor() const; - QString labelColor() const; - QString logoText() const; - QImage logo() const; - QImage barcode() const; - QString barcodeAltText() const; - - QVector auxiliaryFields() const; - QVector backFields() const; - QVector headerFields() const; - QVector primaryFields() const; - QVector secondaryFields() const; - - /** Create a appropriate sub-class based on the pkpass file type. */ - static PkPassFile *fromData(const QByteArray &data, QObject *parent = nullptr); - -protected: - explicit PkPassFile(const QString &passType, QObject *parent = nullptr); - -private: - void parse(); - bool parseMessages(const QString &lang); - QVector fields(const QLatin1String &fieldType) const; - - std::unique_ptr m_buffer; - std::unique_ptr m_zip; - QJsonObject m_passObj; - QHash m_messages; - QString m_passType; -}; - -#endif // PKPASSFILE_H diff --git a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfile.cpp b/plugins/messageviewer/bodypartformatter/pkpass/pkpassfile.cpp deleted file mode 100644 --- a/plugins/messageviewer/bodypartformatter/pkpass/pkpassfile.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - Copyright (c) 2017 Volker Krause - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. -*/ - -#include "pkpassfile.h" -#include "pkpassboardingpass.h" -#include "pkpass_debug.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -PkPassFile::PkPassFile(const QString &passType, QObject *parent) - : QObject(parent) - , m_passType(passType) -{ -} - -PkPassFile::~PkPassFile() = default; - -QJsonObject PkPassFile::data() const -{ - return m_passObj; -} - -QJsonObject PkPassFile::passData() const -{ - return m_passObj.value(m_passType).toObject(); -} - -QString PkPassFile::message(const QString &key) const -{ - const auto it = m_messages.constFind(key); - if (it != m_messages.constEnd()) { - return it.value(); - } - return key; -} - -QString PkPassFile::backgroundColor() const -{ - return m_passObj.value(QLatin1String("backgroundColor")).toString(); -} - -QString PkPassFile::foregroundColor() const -{ - return m_passObj.value(QLatin1String("foregroundColor")).toString(); -} - -QString PkPassFile::labelColor() const -{ - const auto c = m_passObj.value(QLatin1String("labelColor")).toString(); - if (!c.isEmpty()) { - return c; - } - return foregroundColor(); -} - -QString PkPassFile::logoText() const -{ - return message(m_passObj.value(QLatin1String("logoText")).toString()); -} - -QImage PkPassFile::logo() const -{ - auto file = m_zip->directory()->file(QStringLiteral("logo.png")); - if (!file) { - return {}; - } - std::unique_ptr dev(file->createDevice()); - return QImage::fromData(dev->readAll()); -} - -QImage PkPassFile::barcode() const -{ - auto barcodeData = data().value(QLatin1String("barcodes")).toArray().at(0).toObject(); - if (barcodeData.isEmpty()) { - barcodeData = data().value(QLatin1String("barcode")).toObject(); - } - const auto formatName = barcodeData.value(QLatin1String("format")).toString(); - const auto msg = barcodeData.value(QLatin1String("message")).toString(); - // TODO: consider messageEncoding, once Prison supports that - if (formatName.isEmpty() || msg.isEmpty()) { - qCDebug(PKPASS_LOG) << "formatName empty or msg empty"; - return {}; - } - - std::unique_ptr code; - if (formatName == QLatin1String("PKBarcodeFormatQR")) { - code.reset(Prison::createBarcode(Prison::QRCode)); - } else if (formatName == QLatin1String("PKBarcodeFormatPDF417")) { - // TODO - } else if (formatName == QLatin1String("PKBarcodeFormatAztec")) { - code.reset(Prison::createBarcode(Prison::Aztec)); - } else if (formatName == QLatin1String("PKBarcodeFormatCode128")) { - // TODO - } else { - qCDebug(PKPASS_LOG) << "Unknown formatName: " << formatName; - } - - if (!code) { - qCDebug(PKPASS_LOG) << "Unsupported formatName: " << formatName; - return {}; - } - code->setData(msg); - code->toImage(code->minimumSize()); // minimumSize is only available after we rendered once... - return code->toImage(code->minimumSize()); -} - -QString PkPassFile::barcodeAltText() const -{ - auto barcodeData = data().value(QLatin1String("barcodes")).toArray().at(0).toObject(); - if (barcodeData.isEmpty()) { - barcodeData = data().value(QLatin1String("barcode")).toObject(); - } - return barcodeData.value(QLatin1String("altText")).toString(); -} - -QVector PkPassFile::auxiliaryFields() const -{ - return fields(QLatin1String("auxiliaryFields")); -} - -QVector PkPassFile::backFields() const -{ - return fields(QLatin1String("backFields")); -} - -QVector PkPassFile::headerFields() const -{ - return fields(QLatin1String("headerFields")); -} - -QVector PkPassFile::primaryFields() const -{ - return fields(QLatin1String("primaryFields")); -} - -QVector PkPassFile::secondaryFields() const -{ - return fields(QLatin1String("secondaryFields")); -} - -PkPassFile *PkPassFile::fromData(const QByteArray &data, QObject *parent) -{ - std::unique_ptr buffer(new QBuffer); - buffer->setData(data); - buffer->open(QBuffer::ReadOnly); - - std::unique_ptr zip(new KZip(buffer.get())); - if (!zip->open(QIODevice::ReadOnly)) { - return nullptr; - } - - // extract pass.json - auto file = zip->directory()->file(QStringLiteral("pass.json")); - if (!file) { - return nullptr; - } - std::unique_ptr dev(file->createDevice()); - const auto passObj = QJsonDocument::fromJson(dev->readAll()).object(); - - PkPassFile *pass = nullptr; - if (passObj.contains(QLatin1String("boardingPass"))) { - pass = new PkPassBoardingPass(parent); - } - // TODO: coupon, eventTicket, storeCard, generic - else { - pass = new PkPassFile(QStringLiteral("generic"), parent); - } - - pass->m_buffer = std::move(buffer); - pass->m_zip = std::move(zip); - pass->m_passObj = passObj; - pass->parse(); - return pass; -} - -void PkPassFile::parse() -{ - // find the message catalog - auto lang = QLocale().name(); - auto idx = lang.indexOf(QLatin1Char('_')); - if (idx > 0) { - lang = lang.left(idx); - } - lang += QLatin1String(".lproj"); - if (!parseMessages(lang)) { - parseMessages(QStringLiteral("en.lproj")); - } -} - -static int indexOfUnquoted(const QString &catalog, QLatin1Char c, int start) -{ - for (int i = start; i < catalog.size(); ++i) { - const QChar catalogChar = catalog.at(i); - if (catalogChar == c) { - return i; - } - if (catalogChar == QLatin1Char('\\')) { - ++i; - } - } - - return -1; -} - -static QString unquote(const QStringRef &str) -{ - QString res; - res.reserve(str.size()); - for (int i = 0; i < str.size(); ++i) { - const auto c1 = str.at(i); - if (c1 == QLatin1Char('\\') && i < str.size() - 1) { - const auto c2 = str.at(i + 1); - if (c2 == QLatin1Char('r')) { - res.push_back(QLatin1Char('\r')); - } else if (c2 == QLatin1Char('n')) { - res.push_back(QLatin1Char('\n')); - } else if (c2 == QLatin1Char('\\')) { - res.push_back(c2); - } else { - res.push_back(c1); - res.push_back(c2); - } - ++i; - } else { - res.push_back(c1); - } - } - return res; -} - -bool PkPassFile::parseMessages(const QString &lang) -{ - auto entry = m_zip->directory()->entry(lang); - if (!entry || !entry->isDirectory()) { - return false; - } - - auto dir = static_cast(entry); - auto file = dir->file(QStringLiteral("pass.strings")); - if (!file) { - return false; - } - - std::unique_ptr dev(file->createDevice()); - const auto rawData = dev->readAll(); - // this should be UTF-16BE, but that doesn't stop Eurowings from using UTF-8, - // so do a primitive auto-detection here. UTF-16's first byte would either be the BOM - // or \0. - QString catalog; - if (rawData.at(0) == '"') { - catalog = QString::fromUtf8(rawData); - } else { - auto codec = QTextCodec::codecForName("UTF-16BE"); - catalog = codec->toUnicode(rawData); - } - - int idx = 0; - while (idx < catalog.size()) { - // key - const auto keyBegin = indexOfUnquoted(catalog, QLatin1Char('"'), idx) + 1; - if (keyBegin < 1) { - break; - } - const auto keyEnd = indexOfUnquoted(catalog, QLatin1Char('"'), keyBegin); - if (keyEnd <= keyBegin) { - break; - } - - // value - const auto valueBegin = indexOfUnquoted(catalog, QLatin1Char('"'), keyEnd + 2) + 1; // there's at least also the '=' - if (valueBegin <= keyEnd) { - break; - } - const auto valueEnd = indexOfUnquoted(catalog, QLatin1Char('"'), valueBegin); - if (valueEnd <= valueBegin) { - break; - } - - const auto key = catalog.mid(keyBegin, keyEnd - keyBegin); - const auto value = unquote(catalog.midRef(valueBegin, valueEnd - valueBegin)); - m_messages.insert(key, value); - idx = valueEnd + 1; // there's at least the linebreak and/or a ';' - } - - return !m_messages.isEmpty(); -} - -QVector PkPassFile::fields(const QLatin1String &fieldType) const -{ - const auto a = passData().value(fieldType).toArray(); - QVector f; - f.reserve(a.size()); - foreach (const auto &v, a) { - f.push_back(PkPassField{v.toObject(), this}); - } - return f; -} diff --git a/plugins/messageviewer/bodypartformatter/pkpass/templates/boardingpass.html b/plugins/messageviewer/bodypartformatter/pkpass/templates/boardingpass.html --- a/plugins/messageviewer/bodypartformatter/pkpass/templates/boardingpass.html +++ b/plugins/messageviewer/bodypartformatter/pkpass/templates/boardingpass.html @@ -2,8 +2,8 @@
{{ pass.logoText }} {% for field in pass.headerFields %} - {{ field.label }} + {{ field.label }} {% endfor %} {% for field in pass.headerFields %} @@ -37,12 +37,12 @@
- + - + -
{{ pass.primaryFields.0.label }}{{ pass.primaryFields.0.label }} {{ pass.primaryFields.1.label }}{{ pass.primaryFields.1.label }}
{{ pass.primaryFields.0.value }} + {% if pass.transitType == pass.Air %} ✈ {% elif pass.transitType == pass.Bus %} @@ -64,7 +64,7 @@ {% for field in pass.auxiliaryFields %} - + {% endfor %} {% for field in pass.auxiliaryFields %} @@ -78,7 +78,7 @@
{{ field.label }}{{ field.label }}
{% for field in pass.secondaryFields %} - + {% endfor %} {% for field in pass.secondaryFields %} @@ -97,12 +97,12 @@ {% i18n "Unsupported barcode format." %} {% endif %} -
{{ pass.barcodeAltText }}
+
{{ pass.barcodes.0.alternativeText }}

{% for field in pass.backFields %} -
{{ field.label }}
+
{{ field.label }}
{{ field.value|safe|linebreaksbr }}
{% endfor %}
{{ field.label }}{{ field.label }}