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

KDE's Doxygen guidelines are available online.