|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Designer of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qdesigner_introspection_p.h" |
|
43 |
|
44 #include <QtCore/QMetaObject> |
|
45 #include <QtCore/QMetaEnum> |
|
46 #include <QtCore/QStringList> |
|
47 #include <QtCore/QVector> |
|
48 |
|
49 QT_BEGIN_NAMESPACE |
|
50 |
|
51 // Qt Implementation |
|
52 static QStringList byteArrayListToStringList(const QList<QByteArray> &l) |
|
53 { |
|
54 if (l.empty()) |
|
55 return QStringList(); |
|
56 QStringList rc; |
|
57 const QList<QByteArray>::const_iterator cend = l.constEnd(); |
|
58 for (QList<QByteArray>::const_iterator it = l.constBegin(); it != cend; ++it) |
|
59 rc += QString::fromUtf8(*it); |
|
60 return rc; |
|
61 } |
|
62 |
|
63 static inline QString charToQString(const char *c) |
|
64 { |
|
65 if (!c) |
|
66 return QString::null; |
|
67 return QString::fromUtf8(c); |
|
68 } |
|
69 |
|
70 namespace { |
|
71 // ------- QDesignerMetaEnum |
|
72 class QDesignerMetaEnum : public QDesignerMetaEnumInterface { |
|
73 public: |
|
74 QDesignerMetaEnum(const QMetaEnum &qEnum); |
|
75 virtual bool isFlag() const { return m_enum.isFlag(); } |
|
76 virtual QString key(int index) const { return charToQString(m_enum.key(index)); } |
|
77 virtual int keyCount() const { return m_enum.keyCount(); } |
|
78 virtual int keyToValue(const QString &key) const { return m_enum.keyToValue(key.toUtf8()); } |
|
79 virtual int keysToValue(const QString &keys) const { return m_enum.keysToValue(keys.toUtf8()); } |
|
80 virtual QString name() const { return m_name; } |
|
81 virtual QString scope() const { return m_scope; } |
|
82 virtual QString separator() const; |
|
83 virtual int value(int index) const { return m_enum.value(index); } |
|
84 virtual QString valueToKey(int value) const { return charToQString(m_enum.valueToKey(value)); } |
|
85 virtual QString valueToKeys(int value) const { return charToQString(m_enum.valueToKeys(value)); } |
|
86 |
|
87 private: |
|
88 const QMetaEnum m_enum; |
|
89 const QString m_name; |
|
90 const QString m_scope; |
|
91 }; |
|
92 |
|
93 QDesignerMetaEnum::QDesignerMetaEnum(const QMetaEnum &qEnum) : |
|
94 m_enum(qEnum), |
|
95 m_name(charToQString(m_enum.name())), |
|
96 m_scope(charToQString(m_enum.scope())) |
|
97 { |
|
98 } |
|
99 |
|
100 QString QDesignerMetaEnum::separator() const |
|
101 { |
|
102 static const QString rc = QLatin1String("::"); |
|
103 return rc; |
|
104 } |
|
105 |
|
106 // ------- QDesignerMetaProperty |
|
107 class QDesignerMetaProperty : public QDesignerMetaPropertyInterface { |
|
108 public: |
|
109 QDesignerMetaProperty(const QMetaProperty &property); |
|
110 virtual ~QDesignerMetaProperty(); |
|
111 |
|
112 virtual const QDesignerMetaEnumInterface *enumerator() const { return m_enumerator; } |
|
113 |
|
114 virtual Kind kind() const { return m_kind; } |
|
115 |
|
116 virtual AccessFlags accessFlags() const { return m_access; } |
|
117 virtual Attributes attributes(const QObject *object = 0) const; |
|
118 |
|
119 virtual QVariant::Type type() const { return m_property.type(); } |
|
120 virtual QString name() const { return m_name; } |
|
121 virtual QString typeName() const { return m_typeName; } |
|
122 virtual int userType() const { return m_property.userType(); } |
|
123 virtual bool hasSetter() const { return m_property.hasStdCppSet(); } |
|
124 |
|
125 virtual QVariant read(const QObject *object) const { return m_property.read(object); } |
|
126 virtual bool reset(QObject *object) const { return m_property.reset(object); } |
|
127 virtual bool write(QObject *object, const QVariant &value) const { return m_property.write(object, value); } |
|
128 |
|
129 private: |
|
130 const QMetaProperty m_property; |
|
131 const QString m_name; |
|
132 const QString m_typeName; |
|
133 Kind m_kind; |
|
134 AccessFlags m_access; |
|
135 Attributes m_defaultAttributes; |
|
136 QDesignerMetaEnumInterface *m_enumerator; |
|
137 }; |
|
138 |
|
139 QDesignerMetaProperty::QDesignerMetaProperty(const QMetaProperty &property) : |
|
140 m_property(property), |
|
141 m_name(charToQString(m_property.name())), |
|
142 m_typeName(charToQString(m_property.typeName())), |
|
143 m_kind(OtherKind), |
|
144 m_enumerator(0) |
|
145 { |
|
146 if (m_property.isFlagType() || m_property.isEnumType()) { |
|
147 const QMetaEnum metaEnum = m_property.enumerator(); |
|
148 Q_ASSERT(metaEnum.isValid()); |
|
149 m_enumerator = new QDesignerMetaEnum(metaEnum); |
|
150 } |
|
151 // kind |
|
152 if (m_property.isFlagType()) |
|
153 m_kind = FlagKind; |
|
154 else |
|
155 if (m_property.isEnumType()) |
|
156 m_kind = EnumKind; |
|
157 // flags and attributes |
|
158 if (m_property.isReadable()) |
|
159 m_access |= ReadAccess; |
|
160 if (m_property.isWritable()) |
|
161 m_access |= WriteAccess; |
|
162 if (m_property.isResettable()) |
|
163 m_access |= ResetAccess; |
|
164 |
|
165 if (m_property.isDesignable()) |
|
166 m_defaultAttributes |= DesignableAttribute; |
|
167 if (m_property.isScriptable()) |
|
168 m_defaultAttributes |= ScriptableAttribute; |
|
169 if (m_property.isStored()) |
|
170 m_defaultAttributes |= StoredAttribute; |
|
171 if (m_property.isUser()) |
|
172 m_defaultAttributes |= UserAttribute; |
|
173 } |
|
174 |
|
175 QDesignerMetaProperty::~QDesignerMetaProperty() |
|
176 { |
|
177 delete m_enumerator; |
|
178 } |
|
179 |
|
180 QDesignerMetaProperty::Attributes QDesignerMetaProperty::attributes(const QObject *object) const |
|
181 { |
|
182 if (!object) |
|
183 return m_defaultAttributes; |
|
184 Attributes rc; |
|
185 if (m_property.isDesignable(object)) |
|
186 rc |= DesignableAttribute; |
|
187 if (m_property.isScriptable(object)) |
|
188 rc |= ScriptableAttribute; |
|
189 if (m_property.isStored(object)) |
|
190 rc |= StoredAttribute; |
|
191 if (m_property.isUser(object)) |
|
192 rc |= UserAttribute; |
|
193 return rc; |
|
194 } |
|
195 |
|
196 // -------------- QDesignerMetaMethod |
|
197 |
|
198 class QDesignerMetaMethod : public QDesignerMetaMethodInterface { |
|
199 public: |
|
200 QDesignerMetaMethod(const QMetaMethod &method); |
|
201 |
|
202 virtual Access access() const { return m_access; } |
|
203 virtual MethodType methodType() const { return m_methodType; } |
|
204 virtual QStringList parameterNames() const { return m_parameterNames; } |
|
205 virtual QStringList parameterTypes() const { return m_parameterTypes; } |
|
206 virtual QString signature() const { return m_signature; } |
|
207 virtual QString normalizedSignature() const { return m_normalizedSignature; } |
|
208 virtual QString tag() const { return m_tag; } |
|
209 virtual QString typeName() const { return m_typeName; } |
|
210 |
|
211 private: |
|
212 Access m_access; |
|
213 MethodType m_methodType; |
|
214 const QStringList m_parameterNames; |
|
215 const QStringList m_parameterTypes; |
|
216 const QString m_signature; |
|
217 const QString m_normalizedSignature; |
|
218 const QString m_tag; |
|
219 const QString m_typeName; |
|
220 }; |
|
221 |
|
222 QDesignerMetaMethod::QDesignerMetaMethod(const QMetaMethod &method) : |
|
223 m_parameterNames(byteArrayListToStringList(method.parameterNames())), |
|
224 m_parameterTypes(byteArrayListToStringList(method.parameterTypes())), |
|
225 m_signature(charToQString(method.signature())), |
|
226 m_normalizedSignature(charToQString(QMetaObject::normalizedSignature(method.signature()))), |
|
227 m_tag(charToQString(method.tag())), |
|
228 m_typeName(charToQString(method.typeName())) |
|
229 { |
|
230 switch (method.access()) { |
|
231 case QMetaMethod::Public: |
|
232 m_access = Public; |
|
233 break; |
|
234 case QMetaMethod::Protected: |
|
235 m_access = Protected; |
|
236 break; |
|
237 case QMetaMethod::Private: |
|
238 m_access = Private; |
|
239 break; |
|
240 |
|
241 } |
|
242 switch (method.methodType()) { |
|
243 case QMetaMethod::Constructor: |
|
244 m_methodType = Constructor; |
|
245 break; |
|
246 case QMetaMethod::Method: |
|
247 m_methodType = Method; |
|
248 break; |
|
249 case QMetaMethod::Signal: |
|
250 m_methodType = Signal; |
|
251 break; |
|
252 |
|
253 case QMetaMethod::Slot: |
|
254 m_methodType = Slot; |
|
255 break; |
|
256 } |
|
257 } |
|
258 |
|
259 // ------------- QDesignerMetaObject |
|
260 class QDesignerMetaObject : public QDesignerMetaObjectInterface { |
|
261 public: |
|
262 QDesignerMetaObject(const qdesigner_internal::QDesignerIntrospection *introspection, const QMetaObject *metaObject); |
|
263 virtual ~QDesignerMetaObject(); |
|
264 |
|
265 virtual QString className() const { return m_className; } |
|
266 virtual const QDesignerMetaEnumInterface *enumerator(int index) const { return m_enumerators[index]; } |
|
267 virtual int enumeratorCount() const { return m_enumerators.size(); } |
|
268 virtual int enumeratorOffset() const { return m_metaObject->enumeratorOffset(); } |
|
269 |
|
270 virtual int indexOfEnumerator(const QString &name) const { return m_metaObject->indexOfEnumerator(name.toUtf8()); } |
|
271 virtual int indexOfMethod(const QString &method) const { return m_metaObject->indexOfMethod(method.toUtf8()); } |
|
272 virtual int indexOfProperty(const QString &name) const { return m_metaObject->indexOfProperty(name.toUtf8()); } |
|
273 virtual int indexOfSignal(const QString &signal) const { return m_metaObject->indexOfSignal(signal.toUtf8()); } |
|
274 virtual int indexOfSlot(const QString &slot) const { return m_metaObject->indexOfSlot(slot.toUtf8()); } |
|
275 |
|
276 virtual const QDesignerMetaMethodInterface *method(int index) const { return m_methods[index]; } |
|
277 virtual int methodCount() const { return m_methods.size(); } |
|
278 virtual int methodOffset() const { return m_metaObject->methodOffset(); } |
|
279 |
|
280 virtual const QDesignerMetaPropertyInterface *property(int index) const { return m_properties[index]; } |
|
281 virtual int propertyCount() const { return m_properties.size(); } |
|
282 virtual int propertyOffset() const { return m_metaObject->propertyOffset(); } |
|
283 |
|
284 const QDesignerMetaObjectInterface *superClass() const; |
|
285 virtual const QDesignerMetaPropertyInterface *userProperty() const { return m_userProperty; } |
|
286 |
|
287 private: |
|
288 const QString m_className; |
|
289 const qdesigner_internal::QDesignerIntrospection *m_introspection; |
|
290 const QMetaObject *m_metaObject; |
|
291 |
|
292 typedef QVector<QDesignerMetaEnumInterface *> Enumerators; |
|
293 Enumerators m_enumerators; |
|
294 |
|
295 typedef QVector<QDesignerMetaMethodInterface *> Methods; |
|
296 Methods m_methods; |
|
297 |
|
298 typedef QVector<QDesignerMetaPropertyInterface *> Properties; |
|
299 Properties m_properties; |
|
300 |
|
301 QDesignerMetaPropertyInterface *m_userProperty; |
|
302 }; |
|
303 |
|
304 QDesignerMetaObject::QDesignerMetaObject(const qdesigner_internal::QDesignerIntrospection *introspection, const QMetaObject *metaObject) : |
|
305 m_className(charToQString(metaObject->className())), |
|
306 m_introspection(introspection), |
|
307 m_metaObject(metaObject), |
|
308 m_userProperty(0) |
|
309 { |
|
310 const int numEnumerators = metaObject->enumeratorCount(); |
|
311 m_enumerators.reserve(numEnumerators); |
|
312 for (int i = 0; i < numEnumerators; i++) |
|
313 m_enumerators.push_back(new QDesignerMetaEnum(metaObject->enumerator(i))); |
|
314 const int numMethods = metaObject->methodCount(); |
|
315 m_methods.reserve(numMethods); |
|
316 for (int i = 0; i < numMethods; i++) |
|
317 m_methods.push_back(new QDesignerMetaMethod(metaObject->method(i))); |
|
318 |
|
319 const int numProperties = metaObject->propertyCount(); |
|
320 m_properties.reserve(numProperties); |
|
321 for (int i = 0; i < numProperties; i++) |
|
322 m_properties.push_back(new QDesignerMetaProperty(metaObject->property(i))); |
|
323 |
|
324 const QMetaProperty userProperty = metaObject->userProperty(); |
|
325 if (userProperty.isValid()) |
|
326 m_userProperty = new QDesignerMetaProperty(userProperty); |
|
327 } |
|
328 |
|
329 QDesignerMetaObject::~QDesignerMetaObject() |
|
330 { |
|
331 qDeleteAll(m_enumerators); |
|
332 qDeleteAll(m_methods); |
|
333 qDeleteAll(m_properties); |
|
334 delete m_userProperty; |
|
335 } |
|
336 |
|
337 const QDesignerMetaObjectInterface *QDesignerMetaObject::superClass() const |
|
338 { |
|
339 const QMetaObject *qSuperClass = m_metaObject->superClass(); |
|
340 if (!qSuperClass) |
|
341 return 0; |
|
342 return m_introspection->metaObjectForQMetaObject(qSuperClass); |
|
343 } |
|
344 |
|
345 } |
|
346 |
|
347 namespace qdesigner_internal { |
|
348 |
|
349 QDesignerIntrospection::QDesignerIntrospection() |
|
350 { |
|
351 } |
|
352 |
|
353 QDesignerIntrospection::~QDesignerIntrospection() |
|
354 { |
|
355 qDeleteAll(m_metaObjectMap.values()); |
|
356 } |
|
357 |
|
358 const QDesignerMetaObjectInterface* QDesignerIntrospection::metaObject(const QObject *object) const |
|
359 { |
|
360 return metaObjectForQMetaObject(object->metaObject()); |
|
361 } |
|
362 |
|
363 const QDesignerMetaObjectInterface* QDesignerIntrospection::metaObjectForQMetaObject(const QMetaObject *metaObject) const |
|
364 { |
|
365 MetaObjectMap::iterator it = m_metaObjectMap.find(metaObject); |
|
366 if (it == m_metaObjectMap.end()) |
|
367 it = m_metaObjectMap.insert(metaObject, new QDesignerMetaObject(this, metaObject)); |
|
368 return it.value(); |
|
369 } |
|
370 } |
|
371 |
|
372 QT_END_NAMESPACE |