Akonadi Contacts

grantleecontactformatter.cpp
1 /*
2  This file is part of KAddressBook.
3 
4  SPDX-FileCopyrightText: 2010 Tobias Koenig <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #include "grantleecontactformatter.h"
10 #include "contactgrantleewrapper.h"
11 
12 #include <KContacts/Addressee>
13 
14 #include <GrantleeTheme/GrantleeKi18nLocalizer>
15 #include <GrantleeTheme/GrantleeTheme>
16 #include <GrantleeTheme/GrantleeThemeEngine>
17 
18 #include <grantlee/context.h>
19 #include <grantlee/metatype.h>
20 #include <grantlee/templateloader.h>
21 
22 #include <AkonadiCore/Item>
23 
24 #include <KColorScheme>
25 
26 #include <KConfigGroup>
27 #include <KLocalizedString>
28 #include <KStringHandler>
29 
30 #include <QLocale>
31 #include <QMetaProperty>
32 #include <QSet>
33 #include <memory>
34 
35 using namespace KAddressBookGrantlee;
36 
37 GRANTLEE_BEGIN_LOOKUP(QUrl)
38 if (property == QLatin1String("scheme")) {
39  return object.scheme();
40 } else if (property == QLatin1String("path")) {
41  return object.path();
42 }
43 GRANTLEE_END_LOOKUP
44 
45 class Q_DECL_HIDDEN GrantleeContactFormatter::Private
46 {
47 public:
48  Private()
49  {
50  KConfig config(QStringLiteral("akonadi_contactrc"));
51  KConfigGroup group(&config, QStringLiteral("View"));
52  showQRCode = group.readEntry("QRCodes", true);
53 
54  mEngine = std::make_unique<GrantleeTheme::Engine>();
55 
56  mTemplateLoader = QSharedPointer<Grantlee::FileSystemTemplateLoader>(new Grantlee::FileSystemTemplateLoader());
57  }
58 
59  ~Private()
60  {
61  mTemplateLoader.clear();
62  }
63 
64  void changeGrantleePath(const QString &path)
65  {
66  mTemplateLoader->setTemplateDirs(QStringList() << path);
67  mEngine->addTemplateLoader(mTemplateLoader);
68 
69  mSelfcontainedTemplate = mEngine->loadByName(QStringLiteral("contact.html"));
70  if (mSelfcontainedTemplate->error()) {
71  mErrorMessage += mSelfcontainedTemplate->errorString() + QStringLiteral("<br>");
72  }
73 
74  mEmbeddableTemplate = mEngine->loadByName(QStringLiteral("contact_embedded.html"));
75  if (mEmbeddableTemplate->error()) {
76  mErrorMessage += mEmbeddableTemplate->errorString() + QStringLiteral("<br>");
77  }
78  }
79 
80  QVector<QObject *> mObjects;
81  std::unique_ptr<GrantleeTheme::Engine> mEngine;
83  Grantlee::Template mSelfcontainedTemplate;
84  Grantlee::Template mEmbeddableTemplate;
85  QString mErrorMessage;
86  bool forceDisableQRCode = false;
87  bool showQRCode = true;
88 };
89 
91  : d(new Private)
92 {
93  Grantlee::registerMetaType<QUrl>();
94 }
95 
97 {
98  delete d;
99 }
100 
101 void GrantleeContactFormatter::setAbsoluteThemePath(const QString &path)
102 {
103  d->changeGrantleePath(path);
104 }
105 
106 void GrantleeContactFormatter::setGrantleeTheme(const GrantleeTheme::Theme &theme)
107 {
108  d->changeGrantleePath(theme.absolutePath());
109 }
110 
111 void GrantleeContactFormatter::setForceDisableQRCode(bool b)
112 {
113  d->forceDisableQRCode = b;
114 }
115 
116 bool GrantleeContactFormatter::forceDisableQRCode() const
117 {
118  return d->forceDisableQRCode;
119 }
120 
121 void GrantleeContactFormatter::setShowQRCode(bool b)
122 {
123  d->showQRCode = b;
124 }
125 
127 {
128  if (!d->mErrorMessage.isEmpty()) {
129  return d->mErrorMessage;
130  }
131 
132  KContacts::Addressee rawContact;
133  const Akonadi::Item localItem = item();
134  if (localItem.isValid() && localItem.hasPayload<KContacts::Addressee>()) {
135  rawContact = localItem.payload<KContacts::Addressee>();
136  } else {
137  rawContact = contact();
138  }
139 
140  if (rawContact.isEmpty()) {
141  return QString();
142  }
143 
144  // Custom fields
145  QVariantList customFields;
146  QVariantList customFieldsUrl;
147  static QSet<QString> blacklistedKeys = {QStringLiteral("CRYPTOPROTOPREF"),
148  QStringLiteral("OPENPGPFP"),
149  QStringLiteral("SMIMEFP"),
150  QStringLiteral("CRYPTOSIGNPREF"),
151  QStringLiteral("CRYPTOENCRYPTPREF"),
152  QStringLiteral("Anniversary"),
153  QStringLiteral("BlogFeed"),
154  QStringLiteral("Profession"),
155  QStringLiteral("Office"),
156  QStringLiteral("ManagersName"),
157  QStringLiteral("AssistantsName"),
158  QStringLiteral("SpousesName"),
159  QStringLiteral("IMAddress"),
160  QStringLiteral("AddressBook"),
161  QStringLiteral("MailPreferedFormatting"),
162  QStringLiteral("MailAllowToRemoteContent"),
163  QStringLiteral("MAILPREFEREDFORMATTING"),
164  QStringLiteral("MAILALLOWTOREMOTECONTENT")};
165 
166  const auto customs = rawContact.customs();
167  for (QString custom : customs) {
168  if (custom.startsWith(QLatin1String("KADDRESSBOOK-"))) {
169  custom.remove(QStringLiteral("KADDRESSBOOK-X-"));
170  custom.remove(QStringLiteral("KADDRESSBOOK-"));
171 
172  int pos = custom.indexOf(QLatin1Char(':'));
173  QString key = custom.left(pos);
174  QString value = custom.mid(pos + 1);
175 
176  if (blacklistedKeys.contains(key)) {
177  continue;
178  }
179 
180  bool addUrl = false;
181  // check whether it is a custom local field
182  for (int i = 0; i < customFieldDescriptions().size(); ++i) {
183  const QVariantMap description = customFieldDescriptions().at(i);
184  if (description.value(QStringLiteral("key")).toString() == key) {
185  key = description.value(QStringLiteral("title")).toString();
186  const QString descriptionType = description.value(QStringLiteral("type")).toString();
187  if (descriptionType == QLatin1String("boolean")) {
188  if (value == QLatin1String("true")) {
189  value = i18nc("Boolean value", "yes");
190  } else {
191  value = i18nc("Boolean value", "no");
192  }
193  } else if (descriptionType == QLatin1String("date")) {
194  const QDate date = QDate::fromString(value, Qt::ISODate);
195  value = QLocale().toString(date, QLocale::ShortFormat);
196  } else if (descriptionType == QLatin1String("time")) {
197  const QTime time = QTime::fromString(value, Qt::ISODate);
199  } else if (descriptionType == QLatin1String("datetime")) {
200  const QDateTime dateTime = QDateTime::fromString(value, Qt::ISODate);
201  value = QLocale().toString(dateTime, QLocale::ShortFormat);
202  } else if (descriptionType == QLatin1String("url")) {
203  value = KStringHandler::tagUrls(value.toHtmlEscaped());
204  addUrl = true;
205  }
206  break;
207  }
208  }
209  QVariantHash customFieldObject;
210  customFieldObject.insert(QStringLiteral("title"), key);
211  customFieldObject.insert(QStringLiteral("value"), value);
212 
213  if (addUrl) {
214  customFieldsUrl.append(customFieldObject);
215  } else {
216  customFields.append(customFieldObject);
217  }
218  }
219  }
220 
221  QVariantHash colorsObject;
222 
223  colorsObject.insert(QStringLiteral("linkColor"), KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name());
224 
225  colorsObject.insert(QStringLiteral("textColor"), KColorScheme(QPalette::Active, KColorScheme::View).foreground().color().name());
226 
227  colorsObject.insert(QStringLiteral("backgroundColor"), KColorScheme(QPalette::Active, KColorScheme::View).background().color().name());
228 
229  QVariantHash mapping;
230  mapping.insert(QStringLiteral("contact"), QVariant::fromValue(ContactGrantleeWrapper(rawContact)));
231  mapping.insert(QStringLiteral("colors"), colorsObject);
232  mapping.insert(QStringLiteral("customFields"), customFields);
233  mapping.insert(QStringLiteral("customFieldsUrl"), customFieldsUrl);
234  mapping.insert(QStringLiteral("hasqrcode"), !d->forceDisableQRCode && d->showQRCode);
235 
236  Grantlee::Context context(mapping);
237  context.setLocalizer(d->mEngine->localizer());
238 
239  if (form == SelfcontainedForm) {
240  return d->mSelfcontainedTemplate->render(&context);
241  } else if (form == EmbeddableForm) {
242  return d->mEmbeddableTemplate->render(&context);
243  } else {
244  return QString();
245  }
246 }
247 
249 {
250  d->mEngine->localizer()->setApplicationDomain(domain);
251 }
GrantleeContactFormatter()
Creates a new grantlee contact formatter.
~GrantleeContactFormatter() override
Destroys the grantlee contact formatter.
QString & append(QChar ch)
bool isValid() const
QVector< QVariantMap > customFieldDescriptions() const
Returns the custom field descriptions that will be used.
HtmlForm
Describes the form of the HTML that is created.
QString toString(qlonglong i) const const
Additional properties for the KContacts::Addressee Grantlee model.
Creates a div HTML element that can be embedded.
QTime fromString(const QString &string, Qt::DateFormat format)
T payload() const
KSharedConfigPtr config()
QLocale system()
QDate fromString(const QString &string, Qt::DateFormat format)
QString & insert(int position, QChar ch)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool isEmpty() const
int indexOf(QStringView str, int from) const const
KContacts::Addressee contact() const
Returns the contact that will be formatted.
void setApplicationDomain(const QByteArray &domain)
Translation domain for the Grantlee localizer.
QString toHtmlEscaped() const const
QDateTime fromString(const QString &string, Qt::DateFormat format)
QVariant fromValue(const T &value)
bool contains(const T &value) const const
const T & at(int i) const const
QString mid(int position, int n) const const
A class that formats a contact as HTML code.
QStringList customs() const
QString left(int n) const const
QString toHtml(HtmlForm form=SelfcontainedForm) const override
Returns the contact formatted as HTML.
Akonadi::Item item() const
Returns the item who&#39;s payload will be formatted.
bool hasPayload() const
int size() const const
KCOREADDONS_EXPORT QString tagUrls(const QString &text)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Jun 18 2021 23:08:56 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.