File indexing completed on 2025-02-16 04:49:11

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