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 }