Merge lp:~veebers/autopilot-qt/non-visual-components-take2 into lp:autopilot-qt

Proposed by Christopher Lee on 2014-04-04
Status: Work in progress
Proposed branch: lp:~veebers/autopilot-qt/non-visual-components-take2
Merge into: lp:autopilot-qt
Diff against target: 381 lines (+138/-50)
7 files modified
driver/dbus_object.cpp (+0/-1)
driver/introspection.cpp (+65/-15)
driver/introspection.h (+5/-0)
driver/qtnode.cpp (+37/-32)
driver/qtnode.h (+3/-1)
driver/qttestability.cpp (+1/-1)
tests/unittests/tst_introspection.cpp (+27/-0)
To merge this branch: bzr merge lp:~veebers/autopilot-qt/non-visual-components-take2
Reviewer Review Type Date Requested Status
Autopilot Hackers 2014-04-04 Pending
Review via email: mp+214143@code.launchpad.net

Commit message

Re-introduce non-visual introspection of components.

Description of the change

Re-introduce code to introspect non-visual components, the tests and some optimisations too that make it all possible.

To post a comment you must log in.

Unmerged revisions

83. By Christopher Lee on 2014-04-04

Re-introduce backed out non-visual code, optimisations and tests.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'driver/dbus_object.cpp'
2--- driver/dbus_object.cpp 2014-03-12 13:26:27 +0000
3+++ driver/dbus_object.cpp 2014-04-04 01:00:19 +0000
4@@ -303,4 +303,3 @@
5
6 QDBusConnection::sessionBus().send(msg);
7 }
8-
9
10=== modified file 'driver/introspection.cpp'
11--- driver/introspection.cpp 2014-03-12 13:26:27 +0000
12+++ driver/introspection.cpp 2014-04-04 01:00:19 +0000
13@@ -46,7 +46,8 @@
14 QVariant IntrospectNode(QObject* obj);
15 QString GetNodeName(QObject* obj);
16 QStringList GetNodeChildNames(QObject* obj);
17-void AddCustomProperties(QObject* obj, QVariantMap& properties);
18+QVariant GetGlobalRect(QObject* obj);
19+QVariant GetChildrenNames(QObject* obj);
20
21 QList<NodeIntrospectionData> Introspect(QString const& query_string)
22 {
23@@ -58,7 +59,6 @@
24 }
25
26 return state;
27-
28 }
29
30
31@@ -128,7 +128,7 @@
32 QMetaProperty prop = meta->property(i);
33 if (!prop.isValid())
34 {
35- qDebug() << "Property at index" << i << "Is not valid!";
36+ qDebug() << "Property at index" << i << "is not valid!";
37 continue;
38 }
39 QVariant object_property = PackProperty(prop.read(obj));
40@@ -150,18 +150,59 @@
41 meta = meta->superClass();
42 } while(meta);
43
44- AddCustomProperties(obj, object_properties);
45+ QVariant global_rect_property = GetNodeProperty(obj, "globalRect");
46+ if(global_rect_property.isValid())
47+ object_properties["globalRect"] = global_rect_property;
48
49 // add the 'Children' pseudo-property:
50+ QVariant children_property = GetNodeProperty(obj, "Children");
51+ if(children_property.isValid())
52+ object_properties["Children"] = children_property;
53+
54+ return object_properties;
55+}
56+
57+QVariant GetNodeProperty(QObject* obj, const std::string& property_name)
58+{
59+ if(property_name == "globalRect")
60+ return GetGlobalRect(obj);
61+
62+ if(property_name == "Children")
63+ return GetChildrenNames(obj);
64+
65+ QVariant dynamic_property = obj->property(property_name.c_str());
66+ if (dynamic_property.isValid())
67+ {
68+ return PackProperty(dynamic_property);
69+ }
70+ else
71+ {
72+ const QMetaObject* meta = obj->metaObject();
73+ int property_index = meta->indexOfProperty(property_name.c_str());
74+ if(property_index != -1)
75+ {
76+ QMetaProperty prop = meta->property(property_index);
77+ if(prop.isValid())
78+ return PackProperty(prop.read(obj));
79+ else
80+ qDebug() << "Property " << QString::fromStdString(property_name)
81+ << " is not valid.";
82+ }
83+ }
84+
85+ return QVariant();
86+}
87+
88+QVariant GetChildrenNames(QObject* obj)
89+{
90 QStringList children = GetNodeChildNames(obj);
91 if (!children.empty())
92- object_properties["Children"] = PackProperty(children);
93-
94- return object_properties;
95+ return PackProperty(children);
96+ else
97+ return QVariant();
98 }
99
100-
101-void AddCustomProperties(QObject* obj, QVariantMap &properties)
102+QVariant GetGlobalRect(QObject* obj)
103 {
104 // Add any custom properties we need to the given QObject.
105 // Add GlobalRect support for QWidget-derived classes
106@@ -170,7 +211,7 @@
107 {
108 QRect r = w->rect();
109 r = QRect(w->mapToGlobal(r.topLeft()), r.size());
110- properties["globalRect"] = PackProperty(r);
111+ return PackProperty(r);
112 }
113 // ...and support for QGraphicsItem-derived classes.
114 else if (QGraphicsItem *i = qobject_cast<QGraphicsItem*>(obj))
115@@ -184,19 +225,28 @@
116 QRect global_rect = QRect(
117 view->mapToGlobal(scene_rect.topLeft()),
118 scene_rect.size());
119- properties["globalRect"] = PackProperty(global_rect);
120+ return PackProperty(global_rect);
121 }
122 #ifdef QT5_SUPPORT
123 // ... and support for QQuickItems (aka. Qt5 Declarative items)
124 else if (QQuickItem *i = qobject_cast<QQuickItem*>(obj))
125 {
126 QQuickWindow *view = i->window();
127- QRectF bounding_rect = i->boundingRect();
128- bounding_rect = i->mapRectToScene(bounding_rect);
129- QRect global_rect = QRect(view->mapToGlobal(bounding_rect.toRect().topLeft()), bounding_rect.size().toSize());
130- properties["globalRect"] = PackProperty(global_rect);
131+ if(view)
132+ {
133+ QRectF bounding_rect = i->boundingRect();
134+ bounding_rect = i->mapRectToScene(bounding_rect);
135+ QRect global_rect = QRect(
136+ view->mapToGlobal(bounding_rect.toRect().topLeft()), bounding_rect.size().toSize()
137+ );
138+
139+ return PackProperty(global_rect);
140+ }
141 }
142 #endif
143+
144+ // Default to returning invalid QVariant
145+ return QVariant();
146 }
147
148 QVariant PackProperty(QVariant const& prop)
149
150=== modified file 'driver/introspection.h'
151--- driver/introspection.h 2014-03-12 13:26:27 +0000
152+++ driver/introspection.h 2014-04-04 01:00:19 +0000
153@@ -26,5 +26,10 @@
154 /// given QObject.
155 QVariantMap GetNodeProperties(QObject* obj);
156
157+/// Return a QVariant containing the requested property
158+/// "property_name" or an invalid QVariant if the property is not
159+/// found.
160+QVariant GetNodeProperty(QObject* obj, const std::string& property_name);
161+
162
163 #endif
164
165=== modified file 'driver/qtnode.cpp'
166--- driver/qtnode.cpp 2014-03-12 13:26:27 +0000
167+++ driver/qtnode.cpp 2014-04-04 01:00:19 +0000
168@@ -18,22 +18,22 @@
169 #include <QDBusArgument>
170
171 // Marshall the NodeIntrospectionData data into a D-Bus argument
172- QDBusArgument &operator<<(QDBusArgument &argument, const NodeIntrospectionData &node_data)
173- {
174- argument.beginStructure();
175- argument << node_data.object_path << node_data.state;
176- argument.endStructure();
177- return argument;
178- }
179+QDBusArgument &operator<<(QDBusArgument &argument, const NodeIntrospectionData &node_data)
180+{
181+ argument.beginStructure();
182+ argument << node_data.object_path << node_data.state;
183+ argument.endStructure();
184+ return argument;
185+}
186
187- // Retrieve the NodeIntrospectionData data from the D-Bus argument
188- const QDBusArgument &operator>>(const QDBusArgument &argument, NodeIntrospectionData &node_data)
189- {
190- argument.beginStructure();
191- argument >> node_data.object_path >> node_data.state;
192- argument.endStructure();
193- return argument;
194- }
195+// Retrieve the NodeIntrospectionData data from the D-Bus argument
196+const QDBusArgument &operator>>(const QDBusArgument &argument, NodeIntrospectionData &node_data)
197+{
198+ argument.beginStructure();
199+ argument >> node_data.object_path >> node_data.state;
200+ argument.endStructure();
201+ return argument;
202+}
203
204 const QByteArray AP_ID_NAME("_autopilot_id");
205
206@@ -41,6 +41,7 @@
207 : object_(obj)
208 , parent_(parent)
209 {
210+ SetName(obj);
211 std::string parent_path = parent ? parent->GetPath() : "";
212 full_path_ = parent_path + "/" + GetName();
213 }
214@@ -48,6 +49,7 @@
215 QtNode::QtNode(QObject* obj)
216 : object_(obj)
217 {
218+ SetName(obj);
219 full_path_ = "/" + GetName();
220 }
221
222@@ -65,15 +67,18 @@
223 return data;
224 }
225
226-std::string QtNode::GetName() const
227+void QtNode::SetName(const QObject* object)
228 {
229- QString name = object_->metaObject()->className();
230-
231+ QString name = object->metaObject()->className();
232 // QML type names get mangled by Qt - they get _QML_N or _QMLTYPE_N appended.
233- //
234 if (name.contains('_'))
235 name = name.split('_').front();
236- return name.toStdString();
237+ node_name_ = name.toStdString();
238+}
239+
240+std::string QtNode::GetName() const
241+{
242+ return node_name_;
243 }
244
245 std::string QtNode::GetPath() const
246@@ -99,13 +104,13 @@
247
248 bool QtNode::MatchStringProperty(const std::string& name, const std::string& value) const
249 {
250- QVariantMap properties = GetNodeProperties(object_);
251+ QVariant property = GetNodeProperty(object_, name);
252
253- QString qname = QString::fromStdString(name);
254- if (! properties.contains(qname))
255+ if(!property.isValid())
256 return false;
257
258- QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);
259+ // Need the value not the object type id
260+ QVariant object_value = qvariant_cast<QVariantList>(property).at(1);
261 QVariant check_value(QString::fromStdString(value));
262 if (check_value.canConvert(object_value.type()))
263 {
264@@ -121,13 +126,13 @@
265 if (name == "id")
266 return value == GetId();
267
268- QVariantMap properties = GetNodeProperties(object_);
269+ QVariant property = GetNodeProperty(object_, name);
270
271- QString qname = QString::fromStdString(name);
272- if (! properties.contains(qname))
273+ if(!property.isValid())
274 return false;
275
276- QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);
277+ // Need the value not the object type id
278+ QVariant object_value = qvariant_cast<QVariantList>(property).at(1);
279 QVariant check_value(value);
280 if (check_value.canConvert(object_value.type()))
281 {
282@@ -140,13 +145,13 @@
283
284 bool QtNode::MatchBooleanProperty(const std::string& name, bool value) const
285 {
286- QVariantMap properties = GetNodeProperties(object_);
287+ QVariant property = GetNodeProperty(object_, name);
288
289- QString qname = QString::fromStdString(name);
290- if (! properties.contains(qname))
291+ if(!property.isValid())
292 return false;
293
294- QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);
295+ // Need the value not the object type id
296+ QVariant object_value = qvariant_cast<QVariantList>(property).at(1);
297 QVariant check_value(value);
298
299 if (check_value.canConvert(object_value.type()))
300
301=== modified file 'driver/qtnode.h'
302--- driver/qtnode.h 2014-03-12 13:26:27 +0000
303+++ driver/qtnode.h 2014-04-04 01:00:19 +0000
304@@ -37,7 +37,6 @@
305
306 virtual NodeIntrospectionData GetIntrospectionData() const;
307
308-
309 virtual std::string GetName() const;
310 virtual std::string GetPath() const;
311 virtual int32_t GetId() const;
312@@ -46,8 +45,11 @@
313 virtual bool MatchBooleanProperty(const std::string& name, bool value) const;
314 virtual xpathselect::NodeVector Children() const;
315 private:
316+ void SetName(const QObject* object);
317+
318 QObject *object_;
319 std::string full_path_;
320+ std::string node_name_;
321 Ptr parent_;
322 };
323
324
325=== modified file 'driver/qttestability.cpp'
326--- driver/qttestability.cpp 2014-02-21 00:41:07 +0000
327+++ driver/qttestability.cpp 2014-04-04 01:00:19 +0000
328@@ -23,7 +23,7 @@
329 qDebug().nospace()
330 << "Testability driver loaded. Wire protocol version is "
331 << AutopilotAdaptor::WIRE_PROTO_VERSION
332- << ".";
333+ << ".(non-visual)";
334 qDBusRegisterMetaType<NodeIntrospectionData>();
335 qDBusRegisterMetaType<QList<NodeIntrospectionData> >();
336
337
338=== modified file 'tests/unittests/tst_introspection.cpp'
339--- tests/unittests/tst_introspection.cpp 2014-03-12 13:26:27 +0000
340+++ tests/unittests/tst_introspection.cpp 2014-04-04 01:00:19 +0000
341@@ -49,6 +49,8 @@
342
343 void test_property_matching();
344
345+ void test_get_node_property();
346+
347 private:
348 QMainWindow *m_object;
349 };
350@@ -511,6 +513,31 @@
351 QVERIFY(n.MatchBooleanProperty("visible", true) == true);
352 }
353
354+void tst_Introspection::test_get_node_property()
355+{
356+ QVariant property;
357+ QVariant unpacked_property;
358+
359+ property = GetNodeProperty(m_object, "dynamicTestProperty");
360+ unpacked_property = qvariant_cast<QVariantList>(property).at(1);
361+ QVERIFY(property.isValid() == true);
362+ QVERIFY(unpacked_property.isValid() == true);
363+ QVERIFY(unpacked_property.toString() == "testValue");
364+
365+ property = GetNodeProperty(m_object, "myUInt");
366+ unpacked_property = qvariant_cast<QVariantList>(property).at(1);
367+ QVERIFY(property.isValid() == true);
368+ QVERIFY(unpacked_property.isValid() == true);
369+ QVERIFY(unpacked_property.toFloat() == 5);
370+
371+ // Meta Property
372+ property = GetNodeProperty(m_object, "fullScreen");
373+ unpacked_property = qvariant_cast<QVariantList>(property).at(1);
374+ QVERIFY(property.isValid() == true);
375+ QVERIFY(unpacked_property.isValid() == true);
376+ QVERIFY(unpacked_property.toBool() == false);
377+}
378+
379 QTEST_MAIN(tst_Introspection)
380
381 #include "tst_introspection.moc"

Subscribers

People subscribed via source and target branches