File indexing completed on 2025-02-16 04:45:49

0001 /*
0002   This file is part of KAddressBook.
0003 
0004   SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org>
0005 
0006   SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "grantleecontactgroupformatter.h"
0010 
0011 #include <GrantleeTheme/GrantleeTheme>
0012 
0013 #include <KTextTemplate/Context>
0014 #include <KTextTemplate/Engine>
0015 #include <KTextTemplate/TemplateLoader>
0016 
0017 #include <Akonadi/ContactGroupExpandJob>
0018 #include <Akonadi/Item>
0019 
0020 #include <KColorScheme>
0021 
0022 using namespace KAddressBookGrantlee;
0023 
0024 class KAddressBookGrantlee::GrantleeContactGroupFormatterPrivate
0025 {
0026 public:
0027     GrantleeContactGroupFormatterPrivate()
0028         : mEngine(new KTextTemplate::Engine)
0029     {
0030         mTemplateLoader = QSharedPointer<KTextTemplate::FileSystemTemplateLoader>(new KTextTemplate::FileSystemTemplateLoader);
0031     }
0032 
0033     ~GrantleeContactGroupFormatterPrivate()
0034     {
0035         delete mEngine;
0036         mTemplateLoader.clear();
0037     }
0038 
0039     void changeGrantleePath(const QString &path)
0040     {
0041         mTemplateLoader->setTemplateDirs(QStringList() << path);
0042         mEngine->addTemplateLoader(mTemplateLoader);
0043 
0044         mSelfcontainedTemplate = mEngine->loadByName(QStringLiteral("contactgroup.html"));
0045         if (mSelfcontainedTemplate->error()) {
0046             mErrorMessage += mSelfcontainedTemplate->errorString() + QStringLiteral("<br>");
0047         }
0048 
0049         mEmbeddableTemplate = mEngine->loadByName(QStringLiteral("contactgroup_embedded.html"));
0050         if (mEmbeddableTemplate->error()) {
0051             mErrorMessage += mEmbeddableTemplate->errorString() + QStringLiteral("<br>");
0052         }
0053     }
0054 
0055     QList<QObject *> mObjects;
0056     KTextTemplate::Engine *const mEngine;
0057     QSharedPointer<KTextTemplate::FileSystemTemplateLoader> mTemplateLoader;
0058     KTextTemplate::Template mSelfcontainedTemplate;
0059     KTextTemplate::Template mEmbeddableTemplate;
0060     QString mErrorMessage;
0061 };
0062 
0063 GrantleeContactGroupFormatter::GrantleeContactGroupFormatter()
0064     : d(new GrantleeContactGroupFormatterPrivate)
0065 {
0066 }
0067 
0068 GrantleeContactGroupFormatter::~GrantleeContactGroupFormatter() = default;
0069 
0070 void GrantleeContactGroupFormatter::setAbsoluteThemePath(const QString &path)
0071 {
0072     d->changeGrantleePath(path);
0073 }
0074 
0075 void GrantleeContactGroupFormatter::setGrantleeTheme(const GrantleeTheme::Theme &theme)
0076 {
0077     d->changeGrantleePath(theme.absolutePath());
0078 }
0079 
0080 inline static void setHashField(QVariantHash &hash, const QString &name, const QString &value)
0081 {
0082     if (!value.isEmpty()) {
0083         hash.insert(name, value);
0084     }
0085 }
0086 
0087 static QVariantHash memberHash(const KContacts::ContactGroup::Data &data)
0088 {
0089     QVariantHash memberObject;
0090 
0091     setHashField(memberObject, QStringLiteral("name"), data.name());
0092     setHashField(memberObject, QStringLiteral("email"), data.email());
0093 
0094     KContacts::Addressee contact;
0095     contact.setFormattedName(data.name());
0096     KContacts::Email email(data.email());
0097     contact.addEmail(email);
0098     const QString emailLink = QStringLiteral("<a href=\"mailto:") + QString::fromLatin1(QUrl::toPercentEncoding(contact.fullEmail()))
0099         + QStringLiteral("\">%1</a>").arg(contact.preferredEmail());
0100 
0101     setHashField(memberObject, QStringLiteral("emailLink"), emailLink);
0102 
0103     return memberObject;
0104 }
0105 
0106 QString GrantleeContactGroupFormatter::toHtml(HtmlForm form) const
0107 {
0108     if (!d->mErrorMessage.isEmpty()) {
0109         return d->mErrorMessage;
0110     }
0111 
0112     KContacts::ContactGroup group;
0113     const Akonadi::Item localItem = item();
0114     if (localItem.isValid() && localItem.hasPayload<KContacts::ContactGroup>()) {
0115         group = localItem.payload<KContacts::ContactGroup>();
0116     } else {
0117         group = contactGroup();
0118     }
0119 
0120     if (group.name().isEmpty() && group.count() == 0) { // empty group
0121         return {};
0122     }
0123 
0124     if (group.contactReferenceCount() != 0) {
0125         // we got a contact group with unresolved references -> we have to resolve
0126         // it ourself.  this shouldn't be the normal case, actually the calling
0127         // code should pass in an already resolved contact group
0128         auto job = new Akonadi::ContactGroupExpandJob(group);
0129         if (job->exec()) {
0130             group.removeAllContactData();
0131             const KContacts::Addressee::List lstContacts = job->contacts();
0132             for (const KContacts::Addressee &contact : lstContacts) {
0133                 group.append(KContacts::ContactGroup::Data(contact.realName(), contact.preferredEmail()));
0134             }
0135         }
0136     }
0137 
0138     QVariantHash contactGroupObject;
0139 
0140     setHashField(contactGroupObject, QStringLiteral("name"), group.name());
0141 
0142     // Group members
0143     QVariantList members;
0144     const int numberOfData(group.dataCount());
0145     members.reserve(numberOfData);
0146     for (int i = 0; i < numberOfData; ++i) {
0147         members << memberHash(group.data(i));
0148     }
0149 
0150     contactGroupObject.insert(QStringLiteral("members"), members);
0151 
0152     // Additional fields
0153     QVariantList fields;
0154     for (int i = 0; i < additionalFields().size(); ++i) {
0155         const QVariantMap field = additionalFields().at(i);
0156         QVariantHash fieldObject;
0157         setHashField(fieldObject, QStringLiteral("key"), field.value(QStringLiteral("key")).toString());
0158 
0159         setHashField(fieldObject, QStringLiteral("title"), field.value(QStringLiteral("title")).toString());
0160 
0161         setHashField(fieldObject, QStringLiteral("value"), field.value(QStringLiteral("value")).toString());
0162 
0163         fields << fieldObject;
0164     }
0165 
0166     contactGroupObject.insert(QStringLiteral("additionalFields"), fields);
0167 
0168     QVariantHash colorsObject;
0169     colorsObject.insert(QStringLiteral("linkColor"), KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name());
0170 
0171     colorsObject.insert(QStringLiteral("textColor"), KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name());
0172 
0173     colorsObject.insert(QStringLiteral("backgroundColor"), KColorScheme(QPalette::Active, KColorScheme::View).background().color().name());
0174 
0175     QVariantHash mapping;
0176     mapping.insert(QStringLiteral("contactGroup"), contactGroupObject);
0177     mapping.insert(QStringLiteral("colors"), colorsObject);
0178     KTextTemplate::Context context(mapping);
0179 
0180     if (form == SelfcontainedForm) {
0181         return d->mSelfcontainedTemplate->render(&context);
0182     } else if (form == EmbeddableForm) {
0183         return d->mEmbeddableTemplate->render(&context);
0184     } else {
0185         return {};
0186     }
0187 }