Verified Commit 2a0511a9 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖

Move libkf5kaddressbookgrantlee to akonadi-contacts repo

parent cf096a35
......@@ -23,54 +23,6 @@ include(FeatureSummary)
include(ECMQtDeclareLoggingCategory)
include(ECMAddTests)
set(KDEPIM_APPS_LIB_VERSION ${PIM_VERSION})
set(QT_REQUIRED_VERSION "5.13.0")
set(AKONADI_VERSION "5.15.40")
set(GRANTLEETHEME_LIB_VERSION "5.15.40")
set(AKONADICONTACT_LIB_VERSION "5.15.40")
set(LIBKLEO_LIB_VERSION "5.15.40")
set(PIMCOMMON_LIB_VERSION "5.15.40")
set(GRANTLEE_LIB_VERSION "5.2")
find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Widgets Gui)
find_package(KF5Config ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5ConfigWidgets ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5CoreAddons ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5I18n ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5Contacts ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5KIO ${KF5_MIN_VERSION} CONFIG REQUIRED)
find_package(KF5Akonadi ${AKONADI_VERSION} CONFIG REQUIRED)
find_package(KF5AkonadiContact ${AKONADICONTACT_LIB_VERSION} CONFIG REQUIRED)
find_package(KF5ContactEditor ${AKONADICONTACT_LIB_VERSION} CONFIG REQUIRED)
find_package(KF5GrantleeTheme ${GRANTLEETHEME_LIB_VERSION} CONFIG REQUIRED)
find_package(KF5Libkleo ${LIBKLEO_LIB_VERSION} CONFIG REQUIRED)
find_package(KF5PimCommonAkonadi ${PIMCOMMON_LIB_VERSION} CONFIG REQUIRED)
find_package(Grantlee5 ${GRANTLEE_LIB_VERSION} CONFIG REQUIRED)
if(BUILD_TESTING)
find_package(Qt5 ${QT_REQUIRED_VERSION} CONFIG REQUIRED Test)
add_definitions(-DBUILD_TESTING)
endif()
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050e00)
add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x054A00)
add_definitions(-DQT_NO_FOREACH)
add_definitions(-DQT_NO_KEYWORDS)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(kaddressbookgrantlee)
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
ecm_qt_install_logging_categories(
EXPORT KDEPIMAPPSLIB
FILE kdepim-apps-lib.categories
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
)
ecm_setup_version(PROJECT VARIABLE_PREFIX KADDRESSBOOKGRANTLEE
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kaddressbookgrantlee_version.h"
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5KaddressbookGrantleeConfigVersion.cmake"
SOVERSION 5
)
########### CMake Config Files ###########
set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5KaddressbookGrantlee")
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/KF5KaddressbookGrantleeConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/KF5KaddressbookGrantleeConfig.cmake"
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/KF5KaddressbookGrantleeConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/KF5KaddressbookGrantleeConfigVersion.cmake"
DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
COMPONENT Devel
)
install(EXPORT KF5KaddressbookGrantleeTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5KaddressbookGrantleeTargets.cmake NAMESPACE KF5::)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/kaddressbookgrantlee_version.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} COMPONENT Devel
)
add_subdirectory(src)
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Grantlee5 "@GRANTLEE_LIB_VERSION@")
include("${CMAKE_CURRENT_LIST_DIR}/KF5KaddressbookGrantleeTargets.cmake")
add_definitions(-DTRANSLATION_DOMAIN=\"libkaddressbookgrantlee\")
set(kaddressbook_grantlee_LIB_SRCS
widget/grantleecontactviewer.cpp
formatter/grantleecontactformatter.cpp
formatter/grantleecontactgroupformatter.cpp
contactobject/contactgrantleewrapper.cpp
printing/grantleeprint.cpp
)
add_library(KF5KaddressbookGrantlee ${kaddressbook_grantlee_LIB_SRCS})
generate_export_header(KF5KaddressbookGrantlee BASE_NAME kaddressbook_grantlee)
add_library(KF5::KaddressbookGrantlee ALIAS KF5KaddressbookGrantlee)
target_include_directories(KF5KaddressbookGrantlee INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR_KF5}/KaddressbookGrantlee/;${KDE_INSTALL_INCLUDEDIR_KF5}/kaddressbookgrantlee>")
target_include_directories(KF5KaddressbookGrantlee PUBLIC "$<BUILD_INTERFACE:${Grantlee_INCLUDE_DIRS}>")
target_link_libraries(KF5KaddressbookGrantlee
PUBLIC
KF5::GrantleeTheme
PRIVATE
Grantlee5::Templates
KF5::ConfigWidgets
KF5::AkonadiCore
KF5::ContactEditor
KF5::Contacts
KF5::AkonadiContact
KF5::Libkleo
KF5::I18n
)
set_target_properties(KF5KaddressbookGrantlee PROPERTIES
VERSION ${KADDRESSBOOKGRANTLEE_VERSION_STRING}
SOVERSION ${KADDRESSBOOKGRANTLEE_SOVERSION}
EXPORT_NAME KaddressbookGrantlee
)
install(TARGETS
KF5KaddressbookGrantlee
EXPORT KF5KaddressbookGrantleeTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}
)
ecm_generate_headers(KaddressbookGrantlee_CamelCaseformatter_HEADERS
HEADER_NAMES
GrantleeContactFormatter
GrantleeContactGroupFormatter
REQUIRED_HEADERS KaddressbookGrantlee_formatter_HEADERS
RELATIVE formatter
PREFIX KaddressbookGrantlee
)
ecm_generate_headers(KaddressbookGrantlee_CamelCasewidgets_HEADERS
HEADER_NAMES
GrantleeContactViewer
REQUIRED_HEADERS KaddressbookGrantlee_widgets_HEADERS
RELATIVE widget
PREFIX KaddressbookGrantlee
)
ecm_generate_headers(KaddressbookGrantlee_CamelCaseprinting_HEADERS
HEADER_NAMES
GrantleePrint
REQUIRED_HEADERS KaddressbookGrantlee_printing_HEADERS
RELATIVE printing
PREFIX KaddressbookGrantlee
)
ecm_generate_pri_file(BASE_NAME KaddressbookGrantlee
LIB_NAME KF5KaddressbookGrantlee
DEPS "Grantlee5" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KaddressbookGrantlee
)
install(FILES
${KaddressbookGrantlee_CamelCasewidgets_HEADERS}
${KaddressbookGrantlee_CamelCaseformatter_HEADERS}
${KaddressbookGrantlee_CamelCaseprinting_HEADERS}
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KaddressbookGrantlee
COMPONENT Devel
)
install(FILES
${KaddressbookGrantlee_HEADERS}
${KaddressbookGrantlee_widgets_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/kaddressbook_grantlee_export.h
${KaddressbookGrantlee_formatter_HEADERS}
${KaddressbookGrantlee_printing_HEADERS}
DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/kaddressbookgrantlee
COMPONENT Devel
)
install(FILES
${PRI_FILENAME}
DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
if (BUILD_TESTING)
add_subdirectory(printing/autotests)
endif()
#! /bin/sh
$XGETTEXT `find . -name '*.cpp' -o -name '*.h'` -o $podir/libkaddressbookgrantlee.pot
rm -f rc.cpp
/*
SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "contactgrantleewrapper.h"
#include <Libkleo/Enum>
#include <KLocalizedString>
#include <QBuffer>
#include <QImage>
#include <QLocale>
using namespace KAddressBookGrantlee;
static_assert(sizeof(KContacts::Addressee) == sizeof(KAddressBookGrantlee::ContactGrantleeWrapper), "Grantlee wrapper must not have member variables to prevent slicing 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("<img src=\"%1\" width=\"%2\" height=\"%3\"> &nbsp;").arg(imgToDataUrl(logo().data()), QString::number(60), QString::number(60));
}
QString ContactGrantleeWrapper::photoImgElement() const
{
if (photo().isEmpty()) {
return {};
}
return QStringLiteral("<img src=\"%1\" width=\"%2\" height=\"%3\"> &nbsp;").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());
}
#include "moc_contactgrantleewrapper.cpp"
/*
SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef KADDRESSBOOKGRANTLEE_CONTACTGRANTLEEWRAPPER_H
#define KADDRESSBOOKGRANTLEE_CONTACTGRANTLEEWRAPPER_H
#include <KContacts/Addressee>
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 unnecessary if we had a proper way for formatting dates in Grantlee
Q_PROPERTY(QString formattedBirthday READ formattedBirthday)
Q_PROPERTY(QString formattedAnniversary READ formattedAnniversary)
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
/*
This file is part of KAddressBook.
SPDX-FileCopyrightText: 2010 Tobias Koenig <tokoe@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "grantleecontactformatter.h"
#include <GrantleeTheme/GrantleeTheme>
#include "../contactobject/contactgrantleewrapper.h"
#include <KContacts/Addressee>
#include <GrantleeTheme/GrantleeThemeEngine>
#include <GrantleeTheme/GrantleeKi18nLocalizer>
#include <grantlee/context.h>
#include <grantlee/metatype.h>
#include <grantlee/templateloader.h>
#include <AkonadiCore/Item>
#include <KColorScheme>
#include <KStringHandler>
#include <KConfigGroup>
#include <KLocalizedString>
#include <QLocale>
#include <QMetaProperty>
#include <QRegularExpression>
#include <QSet>
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()
{
KConfig config(QStringLiteral("akonadi_contactrc"));
KConfigGroup group(&config, QStringLiteral("View"));
showQRCode = group.readEntry("QRCodes", true);
mEngine.reset(new GrantleeTheme::Engine);
mTemplateLoader = QSharedPointer<Grantlee::FileSystemTemplateLoader>(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("<br>");
}
mEmbeddableTemplate = mEngine->loadByName(QStringLiteral("contact_embedded.html"));
if (mEmbeddableTemplate->error()) {
mErrorMessage += mEmbeddableTemplate->errorString() + QStringLiteral("<br>");
}
}
QVector<QObject *> mObjects;
std::unique_ptr<GrantleeTheme::Engine> mEngine;
QSharedPointer<Grantlee::FileSystemTemplateLoader> mTemplateLoader;
Grantlee::Template mSelfcontainedTemplate;
Grantlee::Template mEmbeddableTemplate;
QString mErrorMessage;
bool forceDisableQRCode = false;
bool showQRCode = true;
};
GrantleeContactFormatter::GrantleeContactFormatter()
: d(new Private)
{
Grantlee::registerMetaType<KContacts::Address>();
Grantlee::registerMetaType<KContacts::Email>();
Grantlee::registerMetaType<KContacts::Impp>();
Grantlee::registerMetaType<KContacts::PhoneNumber>();
Grantlee::registerMetaType<KContacts::ResourceLocatorUrl>();
Grantlee::registerMetaType<ContactGrantleeWrapper>();
Grantlee::registerMetaType<QUrl>();
}
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)
{
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<KContacts::Addressee>()) {
rawContact = localItem.payload<KContacts::Addressee>();
} else {
rawContact = contact();
}
if (rawContact.isEmpty()) {
return QString();
}
// Custom fields
QVariantList customFields;
QVariantList customFieldsUrl;
static QSet<QString> 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");