File indexing completed on 2024-06-02 05:18:25

0001 /*
0002  * SPDX-FileCopyrightText: 2015 Daniel Vrátil <dvratil@redhat.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005  *
0006  */
0007 
0008 #include "icon.h"
0009 #include <KTextTemplate/Exception>
0010 #include <KTextTemplate/Parser>
0011 #include <KTextTemplate/Variable>
0012 
0013 #include <KIconLoader>
0014 
0015 IconTag::IconTag(QObject *parent)
0016     : KTextTemplate::AbstractNodeFactory(parent)
0017 {
0018 }
0019 
0020 IconTag::~IconTag() = default;
0021 KTextTemplate::Node *IconTag::getNode(const QString &tagContent, KTextTemplate::Parser *p) const
0022 {
0023     Q_UNUSED(p)
0024 
0025     static QHash<QString, int> sizeOrGroupLookup = {{QStringLiteral("toolbar"), KIconLoader::Toolbar},
0026                                                     {QStringLiteral("maintoolbar"), KIconLoader::MainToolbar},
0027                                                     {QStringLiteral("small"), KIconLoader::Small},
0028                                                     {QStringLiteral("dialog"), KIconLoader::Dialog},
0029                                                     {QStringLiteral("sizesmall"), KIconLoader::SizeSmall},
0030                                                     {QStringLiteral("sizesmallmedium"), KIconLoader::SizeSmallMedium},
0031                                                     {QStringLiteral("sizemedium"), KIconLoader::SizeMedium},
0032                                                     {QStringLiteral("sizelarge"), KIconLoader::SizeLarge},
0033                                                     {QStringLiteral("sizehuge"), KIconLoader::SizeHuge},
0034                                                     {QStringLiteral("sizeenormous"), KIconLoader::SizeEnormous}};
0035 
0036     const QStringList parts = smartSplit(tagContent);
0037     const int partsSize = parts.size();
0038     if (partsSize < 2) {
0039         throw KTextTemplate::Exception(KTextTemplate::TagSyntaxError, QStringLiteral("icon tag takes at least 1 argument"));
0040     }
0041     if (partsSize > 4) {
0042         throw KTextTemplate::Exception(KTextTemplate::TagSyntaxError, QStringLiteral("icon tag takes at maximum 3 arguments, %1 given").arg(partsSize));
0043     }
0044 
0045     int sizeOrGroup = KIconLoader::Small;
0046     QString altText;
0047     if (partsSize >= 3) {
0048         const QString sizeStr = parts.at(2);
0049         bool ok = false;
0050         // Try to convert to pixel size
0051         sizeOrGroup = sizeStr.toInt(&ok);
0052         if (!ok) {
0053             // If failed, then try to map the string to one of tne enums
0054             const auto size = sizeOrGroupLookup.constFind(sizeStr);
0055             if (size == sizeOrGroupLookup.cend()) {
0056                 // If it's not  a valid size string, assume it's an alt text
0057                 altText = sizeStr;
0058             } else {
0059                 sizeOrGroup = (*size);
0060             }
0061         }
0062     }
0063     if (partsSize == 4) {
0064         altText = parts.at(3);
0065     }
0066 
0067     return new IconNode(parts.at(1), sizeOrGroup, altText);
0068 }
0069 
0070 IconNode::IconNode(QObject *parent)
0071     : KTextTemplate::Node(parent)
0072 {
0073 }
0074 
0075 IconNode::IconNode(const QString &iconName, int sizeOrGroup, const QString &altText, QObject *parent)
0076     : KTextTemplate::Node(parent)
0077     , mIconName(iconName)
0078     , mAltText(altText)
0079     , mSizeOrGroup(sizeOrGroup)
0080 {
0081 }
0082 
0083 IconNode::~IconNode() = default;
0084 void IconNode::render(KTextTemplate::OutputStream *stream, KTextTemplate::Context *c) const
0085 {
0086     Q_UNUSED(c)
0087 
0088     QString iconName = mIconName;
0089     if (iconName.startsWith(QLatin1Char('"')) && iconName.endsWith(QLatin1Char('"'))) {
0090         iconName = iconName.mid(1, iconName.size() - 2);
0091     } else {
0092         const QVariant val = KTextTemplate::Variable(mIconName).resolve(c);
0093         if (val.metaType().id() == QMetaType::QString) {
0094             iconName = val.toString();
0095         } else {
0096             iconName = val.value<KTextTemplate::SafeString>().get();
0097         }
0098     }
0099 
0100     QString altText;
0101     if (!mAltText.isEmpty()) {
0102         if (mAltText.startsWith(QLatin1Char('"')) && mAltText.endsWith(QLatin1Char('"'))) {
0103             altText = mAltText.mid(1, mAltText.size() - 2);
0104         } else {
0105             const QVariant v = KTextTemplate::Variable(mAltText).resolve(c);
0106             if (v.isValid()) {
0107                 if (v.canConvert<KTextTemplate::SafeString>()) {
0108                     altText = v.value<KTextTemplate::SafeString>().get();
0109                 } else {
0110                     altText = v.toString();
0111                 }
0112             }
0113         }
0114     }
0115 
0116     const QString html =
0117         QStringLiteral("<img src=\"file://%1\" align=\"top\" height=\"%2\" width=\"%2\" alt=\"%3\" title=\"%4\" />")
0118             .arg(KIconLoader::global()->iconPath(iconName, mSizeOrGroup < KIconLoader::LastGroup ? mSizeOrGroup : -mSizeOrGroup))
0119             .arg(mSizeOrGroup < KIconLoader::LastGroup ? KIconLoader::global()->currentSize(static_cast<KIconLoader::Group>(mSizeOrGroup)) : mSizeOrGroup)
0120             .arg(altText.isEmpty() ? iconName : altText, altText); // title is intentionally blank if no alt is provided
0121     (*stream) << KTextTemplate::SafeString(html, KTextTemplate::SafeString::IsSafe);
0122 }
0123 
0124 #include "moc_icon.cpp"