Cutelee 6.1.0
typeaccessors.cpp
1/*
2 This file is part of the Cutelee template system.
3
4 Copyright (c) 2010 Stephen Kelly <steveire@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either version
9 2.1 of the Licence, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library. If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#include "typeaccessor.h"
22
23#include "metaenumvariable_p.h"
24#include "safestring.h"
25
26#include <QtCore/QRegularExpression>
27#include <QtCore/QStringList>
28#include <QtCore/QVariant>
29
30namespace Cutelee
31{
32
33static QRegularExpression getIsTitleRE()
34{
35 QRegularExpression titleRe(QStringLiteral("\\b[a-z]"),
37 return titleRe;
38}
39
40static QRegularExpression getTitleRE()
41{
42 QRegularExpression titleRe(QStringLiteral("\\b(.)"),
44 return titleRe;
45}
46
47template <>
48QVariant
49TypeAccessor<Cutelee::SafeString &>::lookUp(const Cutelee::SafeString &object,
50 const QString &property)
51{
52 if (property == QStringLiteral("capitalize")) {
53 const QString s = object.get();
54 return QVariant(s.at(0).toUpper() + s.right(s.length() - 1));
55 }
56
57 static const QLatin1String falseString("False");
58 static const QLatin1String trueString("True");
59
60 if (property == QStringLiteral("isalnum")) {
61 const QString s = object.get();
62 auto it = s.constBegin();
63 while (it != s.constEnd()) {
64 if (!it->isLetterOrNumber())
65 return falseString;
66 ++it;
67 }
68 return trueString;
69 }
70 if (property == QStringLiteral("isalpha")) {
71 const QString s = object.get();
72 auto it = s.constBegin();
73 if (it == s.constEnd())
74 return falseString;
75 while (it != s.constEnd()) {
76 if (!it->isLetter())
77 return falseString;
78 ++it;
79 }
80 return trueString;
81 }
82 if (property == QStringLiteral("isdigit")) {
83 const QString s = object.get();
84 auto it = s.constBegin();
85 while (it != s.constEnd()) {
86 if (!it->isNumber())
87 return falseString;
88 ++it;
89 }
90 return trueString;
91 }
92 if (property == QStringLiteral("islower")) {
93 const QString s = object.get().toLower();
94 return (s == object.get()) ? trueString : falseString;
95 }
96 if (property == QStringLiteral("isspace")) {
97 const QString s = object.get().trimmed();
98 return (s.isEmpty()) ? trueString : falseString;
99 }
100 if (property == QStringLiteral("istitle")) {
101 const QString s = object.get();
102
103 static const auto titleRe = getIsTitleRE();
104 return (titleRe.match(s).hasMatch()) ? falseString : trueString;
105 }
106 if (property == QStringLiteral("isupper")) {
107 const QString s = object.get().toUpper();
108 return (s == object) ? trueString : falseString;
109 }
110 if (property == QStringLiteral("lower")) {
111 return object.get().toLower();
112 }
113 if (property == QStringLiteral("splitlines")) {
114 const auto strings = object.get().split(QLatin1Char('\n'));
115 QVariantList list;
116 auto it = strings.constBegin();
117 const auto end = strings.constEnd();
118 for (; it != end; ++it)
119 list << *it;
120 return list;
121 }
122 if (property == QStringLiteral("strip")) {
123 return object.get().trimmed();
124 }
125 if (property == QStringLiteral("swapcase")) {
126 const QString inputString = object.get();
127 QString s;
128 s.reserve(inputString.size());
129 auto it = inputString.constBegin();
130 while (it != inputString.constEnd()) {
131 if (it->isUpper())
132 s += it->toLower();
133 else if (it->isLower())
134 s += it->toUpper();
135 else
136 s += *it;
137 ++it;
138 }
139 return s;
140 }
141 if (property == QStringLiteral("title")) {
142 static const auto titleRe = getTitleRE();
143
144 const QString s = object.get();
145 QString output;
146 output.reserve(s.size());
147 auto pos = 0;
148 auto nextPos = 0;
149 int matchedLength;
150
151 auto it = titleRe.globalMatch(s);
152 while (it.hasNext()) {
153 auto match = it.next();
154 pos = match.capturedStart();
155 output += match.captured().toUpper();
156 matchedLength = match.capturedLength();
157 if (it.hasNext()) {
158 match = it.peekNext();
159 nextPos = match.capturedStart();
160 output += s.mid(pos + matchedLength, nextPos - pos - 1);
161 } else {
162 output += s.right(s.length() - (pos + matchedLength));
163 }
164 }
165
166 return output;
167 }
168 if (property == QStringLiteral("upper")) {
169 return object.get().toUpper();
170 }
171 return QVariant();
172}
173
174template <>
175QVariant
176TypeAccessor<MetaEnumVariable &>::lookUp(const MetaEnumVariable &object,
177 const QString &property)
178{
179 if (property == QStringLiteral("name"))
180 return QLatin1String(object.enumerator.name());
181 if (property == QStringLiteral("value"))
182 return object.value;
183 if (property == QStringLiteral("key"))
184 return QLatin1String(object.enumerator.valueToKey(object.value));
185 if (property == QStringLiteral("scope"))
186 return QLatin1String(object.enumerator.scope());
187 if (property == QStringLiteral("keyCount"))
188 return object.enumerator.keyCount();
189
190 auto ok = false;
191 const auto listIndex = property.toInt(&ok);
192 if (ok) {
193 if (listIndex >= object.enumerator.keyCount())
194 return QVariant();
195
196 const MetaEnumVariable mev(object.enumerator,
197 object.enumerator.value(listIndex));
198 return QVariant::fromValue(mev);
199 }
200
201 return QVariant();
202}
203}
The Cutelee namespace holds all public Cutelee API.
Definition Mainpage.dox:8
QChar toUpper() const const
const QChar at(int position) const const
const_iterator constBegin() const const
const_iterator constEnd() const const
bool isEmpty() const const
int length() const const
QString mid(int position, int n) const const
void reserve(int size)
QString right(int n) const const
int size() const const
QString toLower() const const
QString toUpper() const const
QString trimmed() const const
QVariant fromValue(const T &value)