KTextTemplate

variable.cpp
1/*
2 This file is part of the KTextTemplate library
3
4 SPDX-FileCopyrightText: 2009, 2010 Stephen Kelly <steveire@gmail.com>
5
6 SPDX-License-Identifier: LGPL-2.1-or-later
7
8*/
9
10#include "variable.h"
11
12#include "abstractlocalizer.h"
13#include "context.h"
14#include "exception.h"
15#include "metaenumvariable_p.h"
16#include "metatype.h"
17#include "util.h"
18
19#include <QMetaEnum>
20#include <QStringList>
21
22using namespace KTextTemplate;
23
24namespace KTextTemplate
25{
26
27class VariablePrivate
28{
29public:
30 VariablePrivate(Variable *variable)
31 : q_ptr(variable)
32 {
33 }
34
35 Q_DECLARE_PUBLIC(Variable)
36 Variable *const q_ptr;
37
38 QString m_varString;
39 QVariant m_literal;
40 QStringList m_lookups;
41 bool m_localize = false;
42};
43}
44
46 : d_ptr(new VariablePrivate(this))
47{
48 *this = other;
49}
50
52 : d_ptr(new VariablePrivate(this))
53{
54}
55
57{
58 delete d_ptr;
59}
60
62{
63 if (&other == this)
64 return *this;
65 d_ptr->m_varString = other.d_ptr->m_varString;
66 d_ptr->m_literal = other.d_ptr->m_literal;
67 d_ptr->m_lookups = other.d_ptr->m_lookups;
68 d_ptr->m_localize = other.d_ptr->m_localize;
69 return *this;
70}
71
73 : d_ptr(new VariablePrivate(this))
74{
76 d->m_varString = var;
77
78 auto localVar = var;
79 if (var.startsWith(QStringLiteral("_("))) {
80 // The FilterExpression parser ensures this:
81 Q_ASSERT(var.endsWith(QLatin1Char(')')));
82 d->m_localize = true;
83 localVar = var.mid(2, var.size() - 3);
84 }
85 if (localVar.endsWith(QLatin1Char('.'))) {
86 delete d_ptr;
87 throw KTextTemplate::Exception(TagSyntaxError, QStringLiteral("Variable may not end with a dot: %1").arg(localVar));
88 }
89
90 auto processedNumber = false;
91 {
92 const auto intResult = QLocale::c().toInt(localVar, &processedNumber);
93 if (processedNumber) {
94 d->m_literal = intResult;
95 } else {
96 const auto doubleResult = QLocale::c().toDouble(localVar, &processedNumber);
97 if (processedNumber) {
98 d->m_literal = doubleResult;
99 }
100 }
101 }
102 if (!processedNumber) {
103 if (localVar.startsWith(QLatin1Char('"')) || localVar.startsWith(QLatin1Char('\''))) {
104 // The FilterExpression parser ensures this:
105 Q_ASSERT(localVar.endsWith(QLatin1Char('\'')) || localVar.endsWith(QLatin1Char('"')));
106 const auto unesc = unescapeStringLiteral(localVar);
107 const auto ss = markSafe(unesc);
109 } else {
110 if (localVar.contains(QStringLiteral("._")) || (localVar.startsWith(QLatin1Char('_')))) {
111 delete d_ptr;
112 throw KTextTemplate::Exception(TagSyntaxError, QStringLiteral("Variables and attributes may not begin with underscores: %1").arg(localVar));
113 }
114 d->m_lookups = localVar.split(QLatin1Char('.'));
115 }
116 }
117}
118
120{
121 Q_D(const Variable);
122 return !d->m_varString.isEmpty();
123}
124
126{
127 Q_D(const Variable);
128 return !d->m_literal.isNull();
129}
130
132{
133 return variantIsTrue(resolve(c));
134}
135
137{
138 Q_D(const Variable);
139 return d->m_localize;
140}
141
143{
144 Q_D(const Variable);
145 return d->m_literal;
146}
147
149{
150 Q_D(const Variable);
151 return d->m_lookups;
152}
153
154class StaticQtMetaObject : public QObject
155{
156public:
157 static const QMetaObject *_smo()
158 {
159 return &Qt::staticMetaObject;
160 }
161};
162
164{
165 Q_D(const Variable);
166 QVariant var;
167 if (!d->m_lookups.isEmpty()) {
168 auto i = 0;
169 if (d->m_lookups.at(i) == QStringLiteral("Qt")) {
170 ++i;
171 if (d->m_lookups.size() <= i)
172 return {};
173
174 const auto nextPart = d->m_lookups.at(i);
175 ++i;
176
177 static auto globalMetaObject = StaticQtMetaObject::_smo();
178
179 auto breakout = false;
180 for (auto j = 0; j < globalMetaObject->enumeratorCount(); ++j) {
181 const auto me = globalMetaObject->enumerator(j);
182
183 if (QLatin1String(me.name()) == nextPart) {
184 const MetaEnumVariable mev(me);
185 var = QVariant::fromValue(mev);
186 break;
187 }
188
189 for (auto k = 0; k < me.keyCount(); ++k) {
190 if (QLatin1String(me.key(k)) == nextPart) {
191 const MetaEnumVariable mev(me, k);
192 var = QVariant::fromValue(mev);
193 breakout = true;
194 break;
195 }
196 }
197 if (breakout)
198 break;
199 }
200 if (!var.isValid())
201 return {};
202
203 } else {
204 var = c->lookup(d->m_lookups.at(i++));
205 }
206 while (i < d->m_lookups.size()) {
207 var = MetaType::lookup(var, d->m_lookups.at(i++));
208 if (!var.isValid())
209 return {};
210 }
211 } else {
212 if (isSafeString(d->m_literal))
213 var = QVariant::fromValue(getSafeString(d->m_literal));
214 else
215 var = d->m_literal;
216 }
217
218 if (d->m_localize) {
219 return c->localizer()->localize(var);
220 }
221 return var;
222}
The Context class holds the context to render a Template with.
Definition context.h:107
QSharedPointer< AbstractLocalizer > localizer() const
Returns the localizer currently in use.
Definition context.cpp:224
QVariant lookup(const QString &str) const
Returns the context object identified by the key str.
Definition context.cpp:97
An exception for use when implementing template tags.
Definition exception.h:74
A container for static variables defined in Templates.
Definition variable.h:42
QStringList lookups() const
Returns the lookup components of this Variable.
Definition variable.cpp:148
QVariant literal() const
Returns whether this variable is a literal string or number.
Definition variable.cpp:142
QVariant resolve(Context *c) const
Resolves this Variable with the Context c.
Definition variable.cpp:163
Variable()
Constructs an invalid Variable
Definition variable.cpp:51
bool isTrue(Context *c) const
Returns whether this Variable evaluates to true with the Context c.
Definition variable.cpp:131
bool isConstant() const
Returns whether this Variable is a constant in the Template.
Definition variable.cpp:125
Variable & operator=(const Variable &other)
Assignment operator.
Definition variable.cpp:61
bool isLocalized() const
Returns whether this variable is localized, that is, if it is wrapped with _().
Definition variable.cpp:136
bool isValid() const
Returns whether this Variable is valid.
Definition variable.cpp:119
~Variable()
Destructor.
Definition variable.cpp:56
The KTextTemplate namespace holds all public KTextTemplate API.
Definition Mainpage.dox:8
KTextTemplate::SafeString getSafeString(const QVariant &input)
Retrieves and returns a SafeString from the input.
Definition util.cpp:91
bool isSafeString(const QVariant &input)
Returns whether input contains a SafeString.
Definition util.cpp:99
bool variantIsTrue(const QVariant &variant)
Returns whether the variant is evaluated to true.
Definition util.cpp:24
QString unescapeStringLiteral(const QString &input)
Converts the input into its unescaped form.
Definition util.cpp:16
KTextTemplate::SafeString markSafe(const KTextTemplate::SafeString &input)
Marks the input as safe.
Definition util.cpp:74
QLocale c()
double toDouble(QStringView s, bool *ok) const const
int toInt(QStringView s, bool *ok) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QString mid(qsizetype position, qsizetype n) const const
qsizetype size() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QVariant fromValue(T &&value)
bool isValid() const const
Q_D(Todo)
Utility functions used throughout KTextTemplate.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:17:29 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.