KTextTemplate

metatype.cpp
1/*
2 This file is part of the KTextTemplate library
3
4 SPDX-FileCopyrightText: 2010 Michael Jansen <kde@michael-jansen.biz>
5 SPDX-FileCopyrightText: 2010 Stephen Kelly <steveire@gmail.com>
6
7 SPDX-License-Identifier: LGPL-2.1-or-later
8
9*/
10
11#include "metatype.h"
12
13#include "customtyperegistry_p.h"
14#include "metaenumvariable_p.h"
15
16#include <QAssociativeIterable>
17#include <QDebug>
18#include <QSequentialIterable>
19
20using namespace KTextTemplate;
21
22Q_GLOBAL_STATIC(CustomTypeRegistry, customTypes)
23
24void KTextTemplate::MetaType::internalLock()
25{
26 return customTypes()->mutex.lock();
27}
28
29void KTextTemplate::MetaType::internalUnlock()
30{
31 return customTypes()->mutex.unlock();
32}
33
34void KTextTemplate::MetaType::registerLookUpOperator(int id, LookupFunction f)
35{
36 Q_ASSERT(id > 0);
37 Q_ASSERT(f);
38
39 customTypes()->registerLookupOperator(id, f);
40}
41
42static QVariant doQobjectLookUp(const QObject *const object, const QString &property)
43{
44 if (!object)
45 return {};
46 if (property == QStringLiteral("children")) {
47 const auto &childList = object->children();
48 if (childList.isEmpty())
49 return {};
50 QVariantList children;
51
52 auto it = childList.constBegin();
53 const auto end = childList.constEnd();
54 for (; it != end; ++it)
55 children.append(QVariant::fromValue(*it));
56 return children;
57 }
58
59 if (property == QStringLiteral("objectName")) {
60 return object->objectName();
61 }
62 // Can't be const because of invokeMethod.
63 auto metaObj = object->metaObject();
64
66 for (auto i = 0; i < metaObj->propertyCount(); ++i) {
67 // TODO only read-only properties should be allowed here.
68 // This might also handle the variant messing I hit before.
69 mp = metaObj->property(i);
70
71 if (QString::fromUtf8(mp.name()) != property)
72 continue;
73
74 if (mp.isEnumType()) {
75 MetaEnumVariable mev(mp.enumerator(), mp.read(object).value<int>());
76 return QVariant::fromValue(mev);
77 }
78
79 return mp.read(object);
80 }
81 QMetaEnum me;
82 for (auto i = 0; i < metaObj->enumeratorCount(); ++i) {
83 me = metaObj->enumerator(i);
84
85 if (QLatin1String(me.name()) == property) {
86 MetaEnumVariable mev(me);
87 return QVariant::fromValue(mev);
88 }
89
90 const auto value = me.keyToValue(property.toLatin1().constData());
91
92 if (value < 0)
93 continue;
94
95 const MetaEnumVariable mev(me, value);
96
97 return QVariant::fromValue(mev);
98 }
99 return object->property(property.toUtf8().constData());
100}
101
102QVariant KTextTemplate::MetaType::lookup(const QVariant &object, const QString &property)
103{
104 if (object.canConvert<QObject *>()) {
105 return doQobjectLookUp(object.value<QObject *>(), property);
106 }
107 if (object.canConvert<QVariantList>()) {
108 auto iter = object.value<QSequentialIterable>();
109 if (property == QStringLiteral("size") || property == QStringLiteral("count")) {
110 return iter.size();
111 }
112
113 auto ok = false;
114 const auto listIndex = property.toInt(&ok);
115
116 if (!ok || listIndex >= iter.size()) {
117 return {};
118 }
119
120 return iter.at(listIndex);
121 }
122 if (object.canConvert<QVariantHash>()) {
123 auto iter = object.value<QAssociativeIterable>();
124
125 if (iter.find(property) != iter.end()) {
126 return iter.value(property);
127 }
128
129 if (property == QStringLiteral("size") || property == QStringLiteral("count")) {
130 return iter.size();
131 }
132
133 if (property == QStringLiteral("items")) {
134 auto it = iter.begin();
135 const auto end = iter.end();
136 QVariantList list;
137 for (; it != end; ++it) {
138 list.push_back(QVariantList{it.key(), it.value()});
139 }
140 return list;
141 }
142
143 if (property == QStringLiteral("keys")) {
144 auto it = iter.begin();
145 const auto end = iter.end();
146 QVariantList list;
147 for (; it != end; ++it) {
148 list.push_back(it.key());
149 }
150 return list;
151 }
152
153 if (property == QStringLiteral("values")) {
154 auto it = iter.begin();
155 const auto end = iter.end();
156 QVariantList list;
157 for (; it != end; ++it) {
158 list.push_back(it.value());
159 }
160 return list;
161 }
162
163 return {};
164 }
165 auto mo = QMetaType(object.userType()).metaObject();
166 if (mo) {
167 QMetaType mt(object.userType());
168 if (mt.flags().testFlag(QMetaType::IsGadget)) {
169 const auto idx = mo->indexOfProperty(property.toUtf8().constData());
170 if (idx >= 0) {
171 const auto mp = mo->property(idx);
172
173 if (mp.isEnumType()) {
174 MetaEnumVariable mev(mp.enumerator(), mp.readOnGadget(object.constData()).value<int>());
175 return QVariant::fromValue(mev);
176 }
177
178 return mp.readOnGadget(object.constData());
179 }
180
181 QMetaEnum me;
182 for (auto i = 0; i < mo->enumeratorCount(); ++i) {
183 me = mo->enumerator(i);
184
185 if (QLatin1String(me.name()) == property) {
186 MetaEnumVariable mev(me);
187 return QVariant::fromValue(mev);
188 }
189
190 const auto value = me.keyToValue(property.toLatin1().constData());
191
192 if (value < 0) {
193 continue;
194 }
195
196 MetaEnumVariable mev(me, value);
197 return QVariant::fromValue(mev);
198 }
199 }
200 }
201
202 return customTypes()->lookup(object, property);
203}
204
205bool KTextTemplate::MetaType::lookupAlreadyRegistered(int id)
206{
207 return customTypes()->lookupAlreadyRegistered(id);
208}
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const QList< QKeySequence > & end()
The KTextTemplate namespace holds all public KTextTemplate API.
Definition Mainpage.dox:8
const char * constData() const const
void push_back(parameter_type value)
int keyToValue(const char *key, bool *ok) const const
const char * name() const const
QMetaEnum enumerator() const const
bool isEnumType() const const
const char * name() const const
QVariant read(const QObject *object) const const
QVariant readOnGadget(const void *gadget) const const
const QMetaObject * metaObject() const const
QString fromUtf8(QByteArrayView str)
QByteArray toLatin1() const const
QByteArray toUtf8() const const
QVariant fromValue(T &&value)
T value() const const
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.