File indexing completed on 2025-02-09 04:28:41
0001 /* 0002 This file is part of the KTextTemplate library 0003 0004 SPDX-FileCopyrightText: 2009, 2010 Stephen Kelly <steveire@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 0008 */ 0009 0010 #include "util.h" 0011 0012 #include "metaenumvariable_p.h" 0013 0014 #include <QStringList> 0015 0016 QString KTextTemplate::unescapeStringLiteral(const QString &input) 0017 { 0018 return input.mid(1, input.size() - 2) 0019 .replace(QStringLiteral("\\\'"), QChar::fromLatin1('\'')) 0020 .replace(QStringLiteral("\\\""), QChar::fromLatin1('"')) 0021 .replace(QStringLiteral("\\\\"), QChar::fromLatin1('\\')); 0022 } 0023 0024 bool KTextTemplate::variantIsTrue(const QVariant &variant) 0025 { 0026 if (!variant.isValid()) 0027 return false; 0028 switch (variant.userType()) { 0029 case QMetaType::Bool: { 0030 return variant.value<bool>(); 0031 } 0032 case QMetaType::Int: { 0033 return variant.value<int>() > 0; 0034 } 0035 case QMetaType::UInt: { 0036 return variant.value<uint>() > 0; 0037 } 0038 case QMetaType::LongLong: { 0039 return variant.value<qlonglong>() > 0; 0040 } 0041 case QMetaType::ULongLong: { 0042 return variant.value<qulonglong>() > 0; 0043 } 0044 case QMetaType::Double: { 0045 return variant.value<double>() > 0; 0046 } 0047 case QMetaType::Float: { 0048 return variant.value<float>() > 0; 0049 } 0050 case QMetaType::Char: { 0051 return variant.value<char>() > 0; 0052 } 0053 case QMetaType::QObjectStar: { 0054 auto obj = variant.value<QObject *>(); 0055 if (!obj) 0056 return false; 0057 0058 if (obj->property("__true__").isValid()) { 0059 return obj->property("__true__").value<bool>(); 0060 } 0061 return true; 0062 } 0063 case QMetaType::QVariantList: { 0064 return !variant.value<QVariantList>().isEmpty(); 0065 } 0066 case QMetaType::QVariantHash: { 0067 return !variant.value<QVariantHash>().isEmpty(); 0068 } 0069 } 0070 0071 return !getSafeString(variant).get().isEmpty(); 0072 } 0073 0074 KTextTemplate::SafeString KTextTemplate::markSafe(const KTextTemplate::SafeString &input) 0075 { 0076 auto sret = input; 0077 sret.setSafety(KTextTemplate::SafeString::IsSafe); 0078 return sret; 0079 } 0080 0081 KTextTemplate::SafeString KTextTemplate::markForEscaping(const KTextTemplate::SafeString &input) 0082 { 0083 auto temp = input; 0084 if (input.isSafe() || input.needsEscape()) 0085 return input; 0086 0087 temp.setNeedsEscape(true); 0088 return temp; 0089 } 0090 0091 KTextTemplate::SafeString KTextTemplate::getSafeString(const QVariant &input) 0092 { 0093 if (input.userType() == qMetaTypeId<KTextTemplate::SafeString>()) { 0094 return input.value<KTextTemplate::SafeString>(); 0095 } 0096 return input.value<QString>(); 0097 } 0098 0099 bool KTextTemplate::isSafeString(const QVariant &input) 0100 { 0101 const auto type = input.userType(); 0102 return ((type == qMetaTypeId<KTextTemplate::SafeString>()) || type == QMetaType::QString); 0103 } 0104 0105 static QList<int> getPrimitives() 0106 { 0107 QList<int> primitives; 0108 primitives << qMetaTypeId<KTextTemplate::SafeString>() << QMetaType::QString << QMetaType::Bool << QMetaType::Int << QMetaType::Double << QMetaType::Float 0109 << QMetaType::QDate << QMetaType::QTime << QMetaType::QDateTime; 0110 return primitives; 0111 } 0112 0113 bool KTextTemplate::supportedOutputType(const QVariant &input) 0114 { 0115 static const auto primitives = getPrimitives(); 0116 return primitives.contains(input.userType()); 0117 } 0118 0119 bool KTextTemplate::equals(const QVariant &lhs, const QVariant &rhs) 0120 { 0121 // TODO: Redesign... 0122 0123 // QVariant doesn't use operator== to compare its held data, so we do it 0124 // manually instead for SafeString. 0125 auto equal = false; 0126 if (lhs.userType() == qMetaTypeId<KTextTemplate::SafeString>()) { 0127 if (rhs.userType() == qMetaTypeId<KTextTemplate::SafeString>()) { 0128 equal = (lhs.value<KTextTemplate::SafeString>() == rhs.value<KTextTemplate::SafeString>()); 0129 } else if (rhs.userType() == QMetaType::QString) { 0130 equal = (lhs.value<KTextTemplate::SafeString>() == rhs.value<QString>()); 0131 } 0132 } else if (rhs.userType() == qMetaTypeId<KTextTemplate::SafeString>() && lhs.userType() == QMetaType::QString) { 0133 equal = (rhs.value<KTextTemplate::SafeString>() == lhs.value<QString>()); 0134 } else if (rhs.userType() == qMetaTypeId<MetaEnumVariable>()) { 0135 if (lhs.userType() == qMetaTypeId<MetaEnumVariable>()) { 0136 equal = (rhs.value<MetaEnumVariable>() == lhs.value<MetaEnumVariable>()); 0137 } else if (lhs.userType() == qMetaTypeId<int>()) { 0138 equal = (rhs.value<MetaEnumVariable>() == lhs.value<int>()); 0139 } 0140 } else if (lhs.userType() == qMetaTypeId<MetaEnumVariable>()) { 0141 if (rhs.userType() == qMetaTypeId<int>()) { 0142 equal = (lhs.value<MetaEnumVariable>() == rhs.value<int>()); 0143 } 0144 } else { 0145 equal = (lhs == rhs); 0146 } 0147 return equal; 0148 } 0149 0150 std::pair<qreal, QString> KTextTemplate::calcFileSize(qreal size, int unitSystem, qreal multiplier) 0151 { 0152 std::pair<qreal, QString> ret; 0153 0154 int _unitSystem = unitSystem; 0155 0156 if ((_unitSystem != 2) && (_unitSystem != 10)) { 0157 qWarning("%s", 0158 "Unrecognized file size unit system. Falling back to " 0159 "decimal unit system."); 0160 _unitSystem = 10; 0161 } 0162 0163 if (size == 0.0) { 0164 ret.first = 0.0; 0165 ret.second = QStringLiteral("bytes"); 0166 return ret; 0167 } 0168 if ((size == 1.0) || (size == -1.0)) { 0169 ret.first = 1.0; 0170 ret.second = QStringLiteral("byte"); 0171 return ret; 0172 } 0173 0174 qreal _size = size * multiplier; 0175 0176 const bool positiveValue = (_size > 0); 0177 0178 if (!positiveValue) { 0179 _size *= -1; 0180 } 0181 0182 static const QStringList binaryUnits({QStringLiteral("bytes"), 0183 QStringLiteral("KiB"), 0184 QStringLiteral("MiB"), 0185 QStringLiteral("GiB"), 0186 QStringLiteral("TiB"), 0187 QStringLiteral("PiB"), 0188 QStringLiteral("EiB"), 0189 QStringLiteral("ZiB"), 0190 QStringLiteral("YiB")}); 0191 0192 static const QStringList decimalUnits({QStringLiteral("bytes"), 0193 QStringLiteral("KB"), 0194 QStringLiteral("MB"), 0195 QStringLiteral("GB"), 0196 QStringLiteral("TB"), 0197 QStringLiteral("PB"), 0198 QStringLiteral("EB"), 0199 QStringLiteral("ZB"), 0200 QStringLiteral("YB")}); 0201 0202 bool found = false; 0203 int count = 0; 0204 const qreal baseVal = (_unitSystem == 10) ? 1000.0F : 1024.0F; 0205 qreal current = 1.0F; 0206 int units = decimalUnits.size(); 0207 while (!found && (count < units)) { 0208 current *= baseVal; 0209 if (_size < current) { 0210 found = true; 0211 break; 0212 } 0213 count++; 0214 } 0215 0216 if (count >= units) { 0217 count = (units - 1); 0218 } 0219 0220 qreal devider = current / baseVal; 0221 _size = _size / devider; 0222 0223 if (!positiveValue) { 0224 _size *= -1.0; 0225 } 0226 0227 ret.first = _size; 0228 ret.second = (_unitSystem == 10) ? decimalUnits.at(count) : binaryUnits.at(count); 0229 0230 return ret; 0231 } 0232 0233 KTextTemplate::SafeString KTextTemplate::toString(const QVariantList &list) 0234 { 0235 QString output(QLatin1Char('[')); 0236 auto it = list.constBegin(); 0237 const auto end = list.constEnd(); 0238 while (it != end) { 0239 const auto item = *it; 0240 if (isSafeString(item)) { 0241 output += QStringLiteral("u\'") + static_cast<QString>(getSafeString(item).get()) + QLatin1Char('\''); 0242 } 0243 if ((item.userType() == qMetaTypeId<int>()) || (item.userType() == qMetaTypeId<uint>()) || (item.userType() == qMetaTypeId<double>()) 0244 || (item.userType() == qMetaTypeId<float>()) || (item.userType() == qMetaTypeId<long long>()) 0245 || (item.userType() == qMetaTypeId<unsigned long long>())) { 0246 output += item.value<QString>(); 0247 } 0248 if (item.userType() == qMetaTypeId<QVariantList>()) { 0249 output += static_cast<QString>(toString(item.value<QVariantList>()).get()); 0250 } 0251 if ((it + 1) != end) 0252 output += QStringLiteral(", "); 0253 ++it; 0254 } 0255 0256 return output.append(QLatin1Char(']')); 0257 }