File indexing completed on 2025-03-09 04:54:36

0001 /*
0002    SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "messagepartrenderermanager.h"
0008 #include "messageviewer_debug.h"
0009 #include <GrantleeTheme/GrantleeKi18nLocalizer>
0010 #include <GrantleeTheme/GrantleeThemeEngine>
0011 #include <KIconLoader>
0012 #include <QStandardPaths>
0013 
0014 #include <gpgme++/decryptionresult.h>
0015 #include <gpgme++/key.h>
0016 #include <gpgme++/verificationresult.h>
0017 
0018 #include <QGpgME/Protocol>
0019 
0020 #include <KTextTemplate/Context>
0021 #include <KTextTemplate/Engine>
0022 #include <KTextTemplate/MetaType>
0023 #include <KTextTemplate/TemplateLoader>
0024 
0025 #include <QGuiApplication>
0026 Q_DECLARE_METATYPE(GpgME::DecryptionResult::Recipient)
0027 Q_DECLARE_METATYPE(const QGpgME::Protocol *)
0028 Q_DECLARE_METATYPE(GpgME::Key)
0029 
0030 // Read-only introspection of GpgME::DecryptionResult::Recipient object.
0031 KTEXTTEMPLATE_BEGIN_LOOKUP(GpgME::DecryptionResult::Recipient)
0032 if (property == QLatin1StringView("keyID")) {
0033     return QString::fromLatin1(object.keyID());
0034 }
0035 KTEXTTEMPLATE_END_LOOKUP
0036 // Read-only introspection of QGpgME::Protocol object.
0037 namespace KTextTemplate
0038 {
0039 template<>
0040 inline QVariant TypeAccessor<const QGpgME::Protocol *>::lookUp(const QGpgME::Protocol *const object, const QString &property)
0041 {
0042     if (property == QLatin1StringView("name")) {
0043         return object->name();
0044     } else if (property == QLatin1StringView("displayName")) {
0045         return object->displayName();
0046     }
0047     return {};
0048 }
0049 }
0050 
0051 // Read-only introspection of std::pair<GpgME::DecryptionResult::Recipient, GpgME::Key> object.
0052 namespace KTextTemplate
0053 {
0054 template<>
0055 inline QVariant
0056 TypeAccessor<std::pair<GpgME::DecryptionResult::Recipient, GpgME::Key> &>::lookUp(std::pair<GpgME::DecryptionResult::Recipient, GpgME::Key> const &object,
0057                                                                                   const QString &property)
0058 {
0059     if (property == QLatin1StringView("keyID")) {
0060         return QString::fromLatin1(object.first.keyID());
0061     }
0062     if (property == QLatin1StringView("id")) {
0063         return QString::fromUtf8(object.second.userID(0).id());
0064     }
0065     if (property == QLatin1StringView("mainID")) {
0066         return QString::fromLatin1(object.second.keyID());
0067     }
0068     return {};
0069 }
0070 }
0071 
0072 namespace MessageViewer
0073 {
0074 class GlobalContext : public QObject
0075 {
0076     Q_OBJECT
0077     Q_PROPERTY(QString dir READ layoutDirection CONSTANT)
0078     Q_PROPERTY(int iconSize READ iconSize CONSTANT)
0079 public:
0080     explicit GlobalContext(QObject *parent)
0081         : QObject(parent)
0082     {
0083     }
0084 
0085     [[nodiscard]] QString layoutDirection() const
0086     {
0087         return QGuiApplication::isRightToLeft() ? QStringLiteral("rtl") : QStringLiteral("ltr");
0088     }
0089 
0090     [[nodiscard]] int iconSize() const
0091     {
0092         return KIconLoader::global()->currentSize(KIconLoader::Desktop);
0093     }
0094 };
0095 }
0096 
0097 using namespace MessageViewer;
0098 
0099 MessagePartRendererManager::MessagePartRendererManager(QObject *parent)
0100     : QObject(parent)
0101     , m_globalContext(new GlobalContext(this))
0102 {
0103     initializeRenderer();
0104 }
0105 
0106 MessagePartRendererManager::~MessagePartRendererManager()
0107 {
0108     delete m_engine;
0109 }
0110 
0111 MessagePartRendererManager *MessagePartRendererManager::self()
0112 {
0113     static MessagePartRendererManager s_self;
0114     return &s_self;
0115 }
0116 
0117 void MessagePartRendererManager::initializeRenderer()
0118 {
0119     KTextTemplate::registerMetaType<GpgME::DecryptionResult::Recipient>();
0120     KTextTemplate::registerMetaType<const QGpgME::Protocol *>();
0121     KTextTemplate::registerMetaType<std::pair<GpgME::DecryptionResult::Recipient, GpgME::Key>>();
0122     m_engine = new GrantleeTheme::Engine;
0123     const auto libraryPaths = QCoreApplication::libraryPaths();
0124     const QString subPath = QStringLiteral("/pim6/messageviewer");
0125     for (const auto &p : libraryPaths) {
0126         m_engine->addPluginPath(p + subPath);
0127     }
0128     m_engine->addDefaultLibrary(QStringLiteral("messageviewer_ktexttemplate_extension"));
0129     m_engine->localizer()->setApplicationDomain(QByteArrayLiteral("libmessageviewer6"));
0130     auto loader = QSharedPointer<KTextTemplate::FileSystemTemplateLoader>(new KTextTemplate::FileSystemTemplateLoader());
0131     loader->setTemplateDirs({QStringLiteral(":/")});
0132     m_engine->addTemplateLoader(loader);
0133 }
0134 KTextTemplate::Template MessagePartRendererManager::loadByName(const QString &name)
0135 {
0136     KTextTemplate::Template t = m_engine->loadByName(name);
0137     if (t->error()) {
0138         qCWarning(MESSAGEVIEWER_LOG) << t->errorString() << ". Searched in subdir mimetreeparser/themes/default in these locations"
0139                                      << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
0140     }
0141     return t;
0142 }
0143 KTextTemplate::Context MessagePartRendererManager::createContext()
0144 {
0145     KTextTemplate::Context c;
0146 
0147     // careful, m_engine->localizer() is actually a factory function!
0148     auto localizer = m_engine->localizer();
0149     localizer->setApplicationDomain(QByteArrayLiteral("libmessageviewer"));
0150     c.setLocalizer(localizer);
0151 
0152     c.insert(QStringLiteral("global"), m_globalContext);
0153     return c;
0154 }
0155 
0156 #include "messagepartrenderermanager.moc"
0157 
0158 #include "moc_messagepartrenderermanager.cpp"