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 
30 namespace Cutelee
31 {
32 
33 static QRegularExpression getIsTitleRE()
34 {
35  QRegularExpression titleRe(QStringLiteral("\\b[a-z]"),
37  return titleRe;
38 }
39 
40 static QRegularExpression getTitleRE()
41 {
42  QRegularExpression titleRe(QStringLiteral("\\b(.)"),
44  return titleRe;
45 }
46 
47 template <>
49 TypeAccessor<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 
174 template <>
175 QVariant
176 TypeAccessor<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 }
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition: safestring.h:92
The Cutelee namespace holds all public Cutelee API.
Definition: Mainpage.dox:8
QChar toUpper() const const
QList::const_iterator constBegin() const const
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
const QChar at(int position) const const
QString::const_iterator constBegin() const const
QString::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)