diff --git a/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.cpp b/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.cpp index 71a5005..3daeb8c 100644 --- a/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.cpp +++ b/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.cpp @@ -1,164 +1,136 @@ /* Copyright (C) 2019 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "contactgrantleewrapper.h" -#include - #include #include #include #include #include using namespace KAddressBookGrantlee; static_assert(sizeof(KContacts::Addressee) == sizeof(KAddressBookGrantlee::ContactGrantleeWrapper), "Grantlee wrapper must not have member variables to prevent sliciing issues"); ContactGrantleeWrapper::ContactGrantleeWrapper() = default; ContactGrantleeWrapper::ContactGrantleeWrapper(const KContacts::Addressee& addr) : KContacts::Addressee(addr) { } QString ContactGrantleeWrapper::addressBookLabel() const { return i18n("Address Book"); } QString ContactGrantleeWrapper::anniversaryLabel() const { return i18n("Anniversary"); } QString ContactGrantleeWrapper::assistantLabel() const { return i18n("Assistant's Name"); } QString ContactGrantleeWrapper::managerLabel() const { return i18n("Manager's Name"); } QString ContactGrantleeWrapper::officeLabel() const { return i18n("Office"); } QString ContactGrantleeWrapper::professionLabel() const { return i18n("Profession"); } QString ContactGrantleeWrapper::spouseLabel() const { return i18n("Partner's Name"); } QString ContactGrantleeWrapper::addressBookName() const { return custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("AddressBook")); } int ContactGrantleeWrapper::age() const { QDate now = QDate::currentDate(); int age = now.year() - birthday().date().year(); if (birthday().date() > now.addYears(-age)) { age--; } return age; } QString ContactGrantleeWrapper::cryptoPreference() const { return Kleo::encryptionPreferenceToLabel(Kleo::stringToEncryptionPreference(custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("CRYPTOENCRYPTPREF")))); } QString ContactGrantleeWrapper::signaturePreference() const { return Kleo::signingPreferenceToLabel(Kleo::stringToSigningPreference(custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("CRYPTOSIGNPREF")))); } static QString imgToDataUrl(const QImage &image) { QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); image.save(&buffer, "PNG"); return QStringLiteral("data:image/%1;base64,%2").arg(QStringLiteral("PNG"), QString::fromLatin1(ba.toBase64())); } QString ContactGrantleeWrapper::logoImgElement() const { if (logo().isEmpty()) { return {}; } return QStringLiteral("  ").arg(imgToDataUrl(logo().data()), QString::number(60), QString::number(60)); } QString ContactGrantleeWrapper::photoImgElement() const { if (photo().isEmpty()) { return {}; } return QStringLiteral("  ").arg(imgToDataUrl(photo().data()), QString::number(60), QString::number(60)); } QString ContactGrantleeWrapper::formattedBirthday() const { return QLocale().toString(birthday().date()); } QString ContactGrantleeWrapper::formattedAnniversary() const { return QLocale().toString(anniversary()); } -static QVariantHash imAddressHash(const QString &typeKey, const QString &imAddress) -{ - QVariantHash addressObject; - addressObject.insert(QStringLiteral("serviceLabel"), IMProtocols::self()->name(typeKey)); - addressObject.insert(QStringLiteral("address"), imAddress); - addressObject.insert(QStringLiteral("serviceIcon"), IMProtocols::self()->icon(typeKey)); - return addressObject; -} - -QVariantList ContactGrantleeWrapper::imAddresses() const -{ - QVariantList imAddrs; - const QStringList customs = this->customs(); - for (const QString &custom : customs) { - if (custom.startsWith(QLatin1String("messaging/"))) { - const int pos = custom.indexOf(QLatin1Char(':')); - QString key = custom.left(pos); - key.remove(QStringLiteral("-All")); - const QString value = custom.mid(pos + 1); - imAddrs.append(imAddressHash(key, value)); - } - } - - return imAddrs; -} - #include "moc_contactgrantleewrapper.cpp" diff --git a/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.h b/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.h index a0f287f..c721a9a 100644 --- a/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.h +++ b/kaddressbookgrantlee/src/contactobject/contactgrantleewrapper.h @@ -1,93 +1,90 @@ /* Copyright (C) 2019 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KADDRESSBOOKGRANTLEE_CONTACTGRANTLEEWRAPPER_H #define KADDRESSBOOKGRANTLEE_CONTACTGRANTLEEWRAPPER_H #include namespace KAddressBookGrantlee { /** * Additional properties for the KContacts::Addressee Grantlee model. */ class ContactGrantleeWrapper : public KContacts::Addressee { Q_GADGET // ### those probably should eventually become i18n calls in the template itself Q_PROPERTY(QString addressBookLabel READ addressBookLabel) Q_PROPERTY(QString anniversaryLabel READ anniversaryLabel) Q_PROPERTY(QString assistantLabel READ assistantLabel) Q_PROPERTY(QString birthdayLabel READ birthdayLabel) Q_PROPERTY(QString departmentLabel READ departmentLabel) Q_PROPERTY(QString noteLabel READ noteLabel) Q_PROPERTY(QString managerLabel READ managerLabel) Q_PROPERTY(QString officeLabel READ officeLabel) Q_PROPERTY(QString professionLabel READ professionLabel) Q_PROPERTY(QString spouseLabel READ spouseLabel) Q_PROPERTY(QString addressBookName READ addressBookName) Q_PROPERTY(int age READ age) Q_PROPERTY(QString cryptoPreference READ cryptoPreference) Q_PROPERTY(QString signaturePreference READ signaturePreference) // ### this shouldn't be returning assembled HTML, that's a job for Grantlee Q_PROPERTY(QString photo READ photoImgElement) Q_PROPERTY(QString logo READ logoImgElement) // ### those two would be unneccessary if we had a proper way for formatting dates in Grantlee Q_PROPERTY(QString formattedBirthday READ formattedBirthday) Q_PROPERTY(QString formattedAnniversary READ formattedAnniversary) - // ### this is temporary, until KContacts::Impp takes over this part - Q_PROPERTY(QVariantList imAddresses READ imAddresses) - public: ContactGrantleeWrapper(); ContactGrantleeWrapper(const KContacts::Addressee &addr); private: QString addressBookLabel() const; QString anniversaryLabel() const; QString assistantLabel() const; QString managerLabel() const; QString officeLabel() const; QString professionLabel() const; QString spouseLabel() const; QString addressBookName() const; int age() const; QString cryptoPreference() const; QString signaturePreference() const; QString photoImgElement() const; QString logoImgElement() const; QString formattedBirthday() const; QString formattedAnniversary() const; QVariantList imAddresses() const; }; } Q_DECLARE_METATYPE(KAddressBookGrantlee::ContactGrantleeWrapper) #endif // KADDRESSBOOKGRANTLEE_CONTACTGRANTLEEWRAPPER_H diff --git a/kaddressbookgrantlee/src/formatter/grantleecontactformatter.cpp b/kaddressbookgrantlee/src/formatter/grantleecontactformatter.cpp index af0cefc..4f287e4 100644 --- a/kaddressbookgrantlee/src/formatter/grantleecontactformatter.cpp +++ b/kaddressbookgrantlee/src/formatter/grantleecontactformatter.cpp @@ -1,295 +1,299 @@ /* This file is part of KAddressBook. Copyright (c) 2010 Tobias Koenig 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 "grantleecontactformatter.h" #include "grantleetheme/grantleetheme.h" #include "../contactobject/contactgrantleewrapper.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KAddressBookGrantlee; // Grantlee has no Q_GADGET support yet #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(KContacts::Address) GRANTLEE_MAKE_GADGET(KContacts::Email) +GRANTLEE_MAKE_GADGET(KContacts::Impp) GRANTLEE_MAKE_GADGET(KContacts::PhoneNumber) GRANTLEE_MAKE_GADGET(KContacts::ResourceLocatorUrl) GRANTLEE_MAKE_GADGET(KAddressBookGrantlee::ContactGrantleeWrapper) GRANTLEE_BEGIN_LOOKUP(QUrl) if (property == QLatin1String("scheme")) { return object.scheme(); +} else if (property == QLatin1String("path")) { + return object.path(); } GRANTLEE_END_LOOKUP class Q_DECL_HIDDEN GrantleeContactFormatter::Private { public: Private() : forceDisableQRCode(false) , showQRCode(true) { KConfig config(QStringLiteral("akonadi_contactrc")); KConfigGroup group(&config, QStringLiteral("View")); showQRCode = group.readEntry("QRCodes", true); mEngine.reset(new GrantleeTheme::Engine); mTemplateLoader = QSharedPointer(new Grantlee::FileSystemTemplateLoader()); } ~Private() { mTemplateLoader.clear(); } void changeGrantleePath(const QString &path) { mTemplateLoader->setTemplateDirs(QStringList() << path); mEngine->addTemplateLoader(mTemplateLoader); mSelfcontainedTemplate = mEngine->loadByName(QStringLiteral("contact.html")); if (mSelfcontainedTemplate->error()) { mErrorMessage += mSelfcontainedTemplate->errorString() + QStringLiteral("
"); } mEmbeddableTemplate = mEngine->loadByName(QStringLiteral("contact_embedded.html")); if (mEmbeddableTemplate->error()) { mErrorMessage += mEmbeddableTemplate->errorString() + QStringLiteral("
"); } } QVector mObjects; std::unique_ptr mEngine; QSharedPointer mTemplateLoader; Grantlee::Template mSelfcontainedTemplate; Grantlee::Template mEmbeddableTemplate; QString mErrorMessage; bool forceDisableQRCode = false; bool showQRCode = false; }; GrantleeContactFormatter::GrantleeContactFormatter() : d(new Private) { Grantlee::registerMetaType(); Grantlee::registerMetaType(); + Grantlee::registerMetaType(); Grantlee::registerMetaType(); Grantlee::registerMetaType(); Grantlee::registerMetaType(); Grantlee::registerMetaType(); } GrantleeContactFormatter::~GrantleeContactFormatter() { delete d; } void GrantleeContactFormatter::setAbsoluteThemePath(const QString &path) { d->changeGrantleePath(path); } void GrantleeContactFormatter::setGrantleeTheme(const GrantleeTheme::Theme &theme) { d->changeGrantleePath(theme.absolutePath()); } void GrantleeContactFormatter::setForceDisableQRCode(bool b) { if (d->forceDisableQRCode != b) { d->forceDisableQRCode = b; } } bool GrantleeContactFormatter::forceDisableQRCode() const { return d->forceDisableQRCode; } void GrantleeContactFormatter::setShowQRCode(bool b) { d->showQRCode = b; } QString GrantleeContactFormatter::toHtml(HtmlForm form) const { if (!d->mErrorMessage.isEmpty()) { return d->mErrorMessage; } KContacts::Addressee rawContact; const Akonadi::Item localItem = item(); if (localItem.isValid() && localItem.hasPayload()) { rawContact = localItem.payload(); } else { rawContact = contact(); } if (rawContact.isEmpty()) { return QString(); } // Custom fields QVariantList customFields; QVariantList customFieldsUrl; static QSet blacklistedKeys = { QStringLiteral("CRYPTOPROTOPREF"), QStringLiteral("OPENPGPFP"), QStringLiteral("SMIMEFP"), QStringLiteral("CRYPTOSIGNPREF"), QStringLiteral("CRYPTOENCRYPTPREF"), QStringLiteral("Anniversary"), QStringLiteral("BlogFeed"), QStringLiteral("Profession"), QStringLiteral("Office"), QStringLiteral("ManagersName"), QStringLiteral("AssistantsName"), QStringLiteral("SpousesName"), QStringLiteral("IMAddress"), QStringLiteral("AddressBook"), QStringLiteral("MailPreferedFormatting"), QStringLiteral("MailAllowToRemoteContent"), QStringLiteral("MAILPREFEREDFORMATTING"), QStringLiteral("MAILALLOWTOREMOTECONTENT") }; const auto customs = rawContact.customs(); for (QString custom : customs) { if (custom.startsWith(QLatin1String("KADDRESSBOOK-"))) { custom.remove(QStringLiteral("KADDRESSBOOK-X-")); custom.remove(QStringLiteral("KADDRESSBOOK-")); int pos = custom.indexOf(QLatin1Char(':')); QString key = custom.left(pos); QString value = custom.mid(pos + 1); if (blacklistedKeys.contains(key)) { continue; } bool addUrl = false; // check whether it is a custom local field for (int i = 0; i < customFieldDescriptions().size(); ++i) { const QVariantMap description = customFieldDescriptions().at(i); if (description.value(QStringLiteral("key")).toString() == key) { key = description.value(QStringLiteral("title")).toString(); const QString descriptionType = description.value(QStringLiteral("type")).toString(); if (descriptionType == QLatin1String("boolean")) { if (value == QLatin1String("true")) { value = i18nc("Boolean value", "yes"); } else { value = i18nc("Boolean value", "no"); } } else if (descriptionType == QLatin1String("date")) { const QDate date = QDate::fromString(value, Qt::ISODate); value = QLocale().toString(date, QLocale::ShortFormat); } else if (descriptionType == QLatin1String("time")) { const QTime time = QTime::fromString(value, Qt::ISODate); value = QLocale::system().toString(time, QLocale::ShortFormat); } else if (descriptionType == QLatin1String("datetime")) { const QDateTime dateTime = QDateTime::fromString(value, Qt::ISODate); value = QLocale().toString(dateTime, QLocale::ShortFormat); } else if (descriptionType == QLatin1String("url")) { value = KStringHandler::tagUrls(value.toHtmlEscaped()); addUrl = true; } break; } } QVariantHash customFieldObject; customFieldObject.insert(QStringLiteral("title"), key); customFieldObject.insert(QStringLiteral("value"), value); if (addUrl) { customFieldsUrl.append(customFieldObject); } else { customFields.append(customFieldObject); } } } QVariantHash colorsObject; colorsObject.insert( QStringLiteral("linkColor"), KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name()); colorsObject.insert( QStringLiteral("textColor"), KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name()); colorsObject.insert( QStringLiteral("backgroundColor"), KColorScheme(QPalette::Active, KColorScheme::View).background().color().name()); QVariantHash mapping; mapping.insert(QStringLiteral("contact"), QVariant::fromValue(ContactGrantleeWrapper(rawContact))); mapping.insert(QStringLiteral("colors"), colorsObject); mapping.insert(QStringLiteral("customFields"), customFields); mapping.insert(QStringLiteral("customFieldsUrl"), customFieldsUrl); mapping.insert(QStringLiteral("hasqrcode"), !d->forceDisableQRCode && d->showQRCode); Grantlee::Context context(mapping); context.setLocalizer(d->mEngine->localizer()); if (form == SelfcontainedForm) { return d->mSelfcontainedTemplate->render(&context); } else if (form == EmbeddableForm) { return d->mEmbeddableTemplate->render(&context); } else { return QString(); } } void GrantleeContactFormatter::setApplicationDomain(const QByteArray &domain) { d->mEngine->localizer()->setApplicationDomain(domain); }