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

Proposed by Christopher Lee
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 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

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
=== modified file 'driver/dbus_object.cpp'
--- driver/dbus_object.cpp 2014-03-12 13:26:27 +0000
+++ driver/dbus_object.cpp 2014-04-04 01:00:19 +0000
@@ -303,4 +303,3 @@
303303
304 QDBusConnection::sessionBus().send(msg);304 QDBusConnection::sessionBus().send(msg);
305}305}
306
307306
=== modified file 'driver/introspection.cpp'
--- driver/introspection.cpp 2014-03-12 13:26:27 +0000
+++ driver/introspection.cpp 2014-04-04 01:00:19 +0000
@@ -46,7 +46,8 @@
46QVariant IntrospectNode(QObject* obj);46QVariant IntrospectNode(QObject* obj);
47QString GetNodeName(QObject* obj);47QString GetNodeName(QObject* obj);
48QStringList GetNodeChildNames(QObject* obj);48QStringList GetNodeChildNames(QObject* obj);
49void AddCustomProperties(QObject* obj, QVariantMap& properties);49QVariant GetGlobalRect(QObject* obj);
50QVariant GetChildrenNames(QObject* obj);
5051
51QList<NodeIntrospectionData> Introspect(QString const& query_string)52QList<NodeIntrospectionData> Introspect(QString const& query_string)
52{53{
@@ -58,7 +59,6 @@
58 }59 }
5960
60 return state;61 return state;
61
62}62}
6363
6464
@@ -128,7 +128,7 @@
128 QMetaProperty prop = meta->property(i);128 QMetaProperty prop = meta->property(i);
129 if (!prop.isValid())129 if (!prop.isValid())
130 {130 {
131 qDebug() << "Property at index" << i << "Is not valid!";131 qDebug() << "Property at index" << i << "is not valid!";
132 continue;132 continue;
133 }133 }
134 QVariant object_property = PackProperty(prop.read(obj));134 QVariant object_property = PackProperty(prop.read(obj));
@@ -150,18 +150,59 @@
150 meta = meta->superClass();150 meta = meta->superClass();
151 } while(meta);151 } while(meta);
152152
153 AddCustomProperties(obj, object_properties);153 QVariant global_rect_property = GetNodeProperty(obj, "globalRect");
154 if(global_rect_property.isValid())
155 object_properties["globalRect"] = global_rect_property;
154156
155 // add the 'Children' pseudo-property:157 // add the 'Children' pseudo-property:
158 QVariant children_property = GetNodeProperty(obj, "Children");
159 if(children_property.isValid())
160 object_properties["Children"] = children_property;
161
162 return object_properties;
163}
164
165QVariant GetNodeProperty(QObject* obj, const std::string& property_name)
166{
167 if(property_name == "globalRect")
168 return GetGlobalRect(obj);
169
170 if(property_name == "Children")
171 return GetChildrenNames(obj);
172
173 QVariant dynamic_property = obj->property(property_name.c_str());
174 if (dynamic_property.isValid())
175 {
176 return PackProperty(dynamic_property);
177 }
178 else
179 {
180 const QMetaObject* meta = obj->metaObject();
181 int property_index = meta->indexOfProperty(property_name.c_str());
182 if(property_index != -1)
183 {
184 QMetaProperty prop = meta->property(property_index);
185 if(prop.isValid())
186 return PackProperty(prop.read(obj));
187 else
188 qDebug() << "Property " << QString::fromStdString(property_name)
189 << " is not valid.";
190 }
191 }
192
193 return QVariant();
194}
195
196QVariant GetChildrenNames(QObject* obj)
197{
156 QStringList children = GetNodeChildNames(obj);198 QStringList children = GetNodeChildNames(obj);
157 if (!children.empty())199 if (!children.empty())
158 object_properties["Children"] = PackProperty(children);200 return PackProperty(children);
159201 else
160 return object_properties;202 return QVariant();
161}203}
162204
163205QVariant GetGlobalRect(QObject* obj)
164void AddCustomProperties(QObject* obj, QVariantMap &properties)
165{206{
166 // Add any custom properties we need to the given QObject.207 // Add any custom properties we need to the given QObject.
167 // Add GlobalRect support for QWidget-derived classes208 // Add GlobalRect support for QWidget-derived classes
@@ -170,7 +211,7 @@
170 {211 {
171 QRect r = w->rect();212 QRect r = w->rect();
172 r = QRect(w->mapToGlobal(r.topLeft()), r.size());213 r = QRect(w->mapToGlobal(r.topLeft()), r.size());
173 properties["globalRect"] = PackProperty(r);214 return PackProperty(r);
174 }215 }
175 // ...and support for QGraphicsItem-derived classes.216 // ...and support for QGraphicsItem-derived classes.
176 else if (QGraphicsItem *i = qobject_cast<QGraphicsItem*>(obj))217 else if (QGraphicsItem *i = qobject_cast<QGraphicsItem*>(obj))
@@ -184,19 +225,28 @@
184 QRect global_rect = QRect(225 QRect global_rect = QRect(
185 view->mapToGlobal(scene_rect.topLeft()),226 view->mapToGlobal(scene_rect.topLeft()),
186 scene_rect.size());227 scene_rect.size());
187 properties["globalRect"] = PackProperty(global_rect);228 return PackProperty(global_rect);
188 }229 }
189#ifdef QT5_SUPPORT230#ifdef QT5_SUPPORT
190 // ... and support for QQuickItems (aka. Qt5 Declarative items)231 // ... and support for QQuickItems (aka. Qt5 Declarative items)
191 else if (QQuickItem *i = qobject_cast<QQuickItem*>(obj))232 else if (QQuickItem *i = qobject_cast<QQuickItem*>(obj))
192 {233 {
193 QQuickWindow *view = i->window();234 QQuickWindow *view = i->window();
194 QRectF bounding_rect = i->boundingRect();235 if(view)
195 bounding_rect = i->mapRectToScene(bounding_rect);236 {
196 QRect global_rect = QRect(view->mapToGlobal(bounding_rect.toRect().topLeft()), bounding_rect.size().toSize());237 QRectF bounding_rect = i->boundingRect();
197 properties["globalRect"] = PackProperty(global_rect);238 bounding_rect = i->mapRectToScene(bounding_rect);
239 QRect global_rect = QRect(
240 view->mapToGlobal(bounding_rect.toRect().topLeft()), bounding_rect.size().toSize()
241 );
242
243 return PackProperty(global_rect);
244 }
198 }245 }
199#endif246#endif
247
248 // Default to returning invalid QVariant
249 return QVariant();
200}250}
201251
202QVariant PackProperty(QVariant const& prop)252QVariant PackProperty(QVariant const& prop)
203253
=== modified file 'driver/introspection.h'
--- driver/introspection.h 2014-03-12 13:26:27 +0000
+++ driver/introspection.h 2014-04-04 01:00:19 +0000
@@ -26,5 +26,10 @@
26/// given QObject.26/// given QObject.
27QVariantMap GetNodeProperties(QObject* obj);27QVariantMap GetNodeProperties(QObject* obj);
2828
29/// Return a QVariant containing the requested property
30/// "property_name" or an invalid QVariant if the property is not
31/// found.
32QVariant GetNodeProperty(QObject* obj, const std::string& property_name);
33
2934
30#endif35#endif
3136
=== modified file 'driver/qtnode.cpp'
--- driver/qtnode.cpp 2014-03-12 13:26:27 +0000
+++ driver/qtnode.cpp 2014-04-04 01:00:19 +0000
@@ -18,22 +18,22 @@
18#include <QDBusArgument>18#include <QDBusArgument>
1919
20// Marshall the NodeIntrospectionData data into a D-Bus argument20// Marshall the NodeIntrospectionData data into a D-Bus argument
21 QDBusArgument &operator<<(QDBusArgument &argument, const NodeIntrospectionData &node_data)21QDBusArgument &operator<<(QDBusArgument &argument, const NodeIntrospectionData &node_data)
22 {22{
23 argument.beginStructure();23 argument.beginStructure();
24 argument << node_data.object_path << node_data.state;24 argument << node_data.object_path << node_data.state;
25 argument.endStructure();25 argument.endStructure();
26 return argument;26 return argument;
27 }27}
2828
29 // Retrieve the NodeIntrospectionData data from the D-Bus argument29// Retrieve the NodeIntrospectionData data from the D-Bus argument
30 const QDBusArgument &operator>>(const QDBusArgument &argument, NodeIntrospectionData &node_data)30const QDBusArgument &operator>>(const QDBusArgument &argument, NodeIntrospectionData &node_data)
31 {31{
32 argument.beginStructure();32 argument.beginStructure();
33 argument >> node_data.object_path >> node_data.state;33 argument >> node_data.object_path >> node_data.state;
34 argument.endStructure();34 argument.endStructure();
35 return argument;35 return argument;
36 }36}
3737
38const QByteArray AP_ID_NAME("_autopilot_id");38const QByteArray AP_ID_NAME("_autopilot_id");
3939
@@ -41,6 +41,7 @@
41: object_(obj)41: object_(obj)
42, parent_(parent)42, parent_(parent)
43{43{
44 SetName(obj);
44 std::string parent_path = parent ? parent->GetPath() : "";45 std::string parent_path = parent ? parent->GetPath() : "";
45 full_path_ = parent_path + "/" + GetName();46 full_path_ = parent_path + "/" + GetName();
46}47}
@@ -48,6 +49,7 @@
48QtNode::QtNode(QObject* obj)49QtNode::QtNode(QObject* obj)
49: object_(obj)50: object_(obj)
50{51{
52 SetName(obj);
51 full_path_ = "/" + GetName();53 full_path_ = "/" + GetName();
52}54}
5355
@@ -65,15 +67,18 @@
65 return data;67 return data;
66}68}
6769
68std::string QtNode::GetName() const70void QtNode::SetName(const QObject* object)
69{71{
70 QString name = object_->metaObject()->className();72 QString name = object->metaObject()->className();
71
72 // QML type names get mangled by Qt - they get _QML_N or _QMLTYPE_N appended.73 // QML type names get mangled by Qt - they get _QML_N or _QMLTYPE_N appended.
73 //
74 if (name.contains('_'))74 if (name.contains('_'))
75 name = name.split('_').front();75 name = name.split('_').front();
76 return name.toStdString();76 node_name_ = name.toStdString();
77}
78
79std::string QtNode::GetName() const
80{
81 return node_name_;
77}82}
7883
79std::string QtNode::GetPath() const84std::string QtNode::GetPath() const
@@ -99,13 +104,13 @@
99104
100bool QtNode::MatchStringProperty(const std::string& name, const std::string& value) const105bool QtNode::MatchStringProperty(const std::string& name, const std::string& value) const
101{106{
102 QVariantMap properties = GetNodeProperties(object_);107 QVariant property = GetNodeProperty(object_, name);
103108
104 QString qname = QString::fromStdString(name);109 if(!property.isValid())
105 if (! properties.contains(qname))
106 return false;110 return false;
107111
108 QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);112 // Need the value not the object type id
113 QVariant object_value = qvariant_cast<QVariantList>(property).at(1);
109 QVariant check_value(QString::fromStdString(value));114 QVariant check_value(QString::fromStdString(value));
110 if (check_value.canConvert(object_value.type()))115 if (check_value.canConvert(object_value.type()))
111 {116 {
@@ -121,13 +126,13 @@
121 if (name == "id")126 if (name == "id")
122 return value == GetId();127 return value == GetId();
123128
124 QVariantMap properties = GetNodeProperties(object_);129 QVariant property = GetNodeProperty(object_, name);
125130
126 QString qname = QString::fromStdString(name);131 if(!property.isValid())
127 if (! properties.contains(qname))
128 return false;132 return false;
129133
130 QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);134 // Need the value not the object type id
135 QVariant object_value = qvariant_cast<QVariantList>(property).at(1);
131 QVariant check_value(value);136 QVariant check_value(value);
132 if (check_value.canConvert(object_value.type()))137 if (check_value.canConvert(object_value.type()))
133 {138 {
@@ -140,13 +145,13 @@
140145
141bool QtNode::MatchBooleanProperty(const std::string& name, bool value) const146bool QtNode::MatchBooleanProperty(const std::string& name, bool value) const
142{147{
143 QVariantMap properties = GetNodeProperties(object_);148 QVariant property = GetNodeProperty(object_, name);
144149
145 QString qname = QString::fromStdString(name);150 if(!property.isValid())
146 if (! properties.contains(qname))
147 return false;151 return false;
148152
149 QVariant object_value = qvariant_cast<QVariantList>(properties[qname]).at(1);153 // Need the value not the object type id
154 QVariant object_value = qvariant_cast<QVariantList>(property).at(1);
150 QVariant check_value(value);155 QVariant check_value(value);
151156
152 if (check_value.canConvert(object_value.type()))157 if (check_value.canConvert(object_value.type()))
153158
=== modified file 'driver/qtnode.h'
--- driver/qtnode.h 2014-03-12 13:26:27 +0000
+++ driver/qtnode.h 2014-04-04 01:00:19 +0000
@@ -37,7 +37,6 @@
3737
38 virtual NodeIntrospectionData GetIntrospectionData() const;38 virtual NodeIntrospectionData GetIntrospectionData() const;
3939
40
41 virtual std::string GetName() const;40 virtual std::string GetName() const;
42 virtual std::string GetPath() const;41 virtual std::string GetPath() const;
43 virtual int32_t GetId() const;42 virtual int32_t GetId() const;
@@ -46,8 +45,11 @@
46 virtual bool MatchBooleanProperty(const std::string& name, bool value) const;45 virtual bool MatchBooleanProperty(const std::string& name, bool value) const;
47 virtual xpathselect::NodeVector Children() const;46 virtual xpathselect::NodeVector Children() const;
48private:47private:
48 void SetName(const QObject* object);
49
49 QObject *object_;50 QObject *object_;
50 std::string full_path_;51 std::string full_path_;
52 std::string node_name_;
51 Ptr parent_;53 Ptr parent_;
52};54};
5355
5456
=== modified file 'driver/qttestability.cpp'
--- driver/qttestability.cpp 2014-02-21 00:41:07 +0000
+++ driver/qttestability.cpp 2014-04-04 01:00:19 +0000
@@ -23,7 +23,7 @@
23 qDebug().nospace()23 qDebug().nospace()
24 << "Testability driver loaded. Wire protocol version is "24 << "Testability driver loaded. Wire protocol version is "
25 << AutopilotAdaptor::WIRE_PROTO_VERSION25 << AutopilotAdaptor::WIRE_PROTO_VERSION
26 << ".";26 << ".(non-visual)";
27 qDBusRegisterMetaType<NodeIntrospectionData>();27 qDBusRegisterMetaType<NodeIntrospectionData>();
28 qDBusRegisterMetaType<QList<NodeIntrospectionData> >();28 qDBusRegisterMetaType<QList<NodeIntrospectionData> >();
2929
3030
=== modified file 'tests/unittests/tst_introspection.cpp'
--- tests/unittests/tst_introspection.cpp 2014-03-12 13:26:27 +0000
+++ tests/unittests/tst_introspection.cpp 2014-04-04 01:00:19 +0000
@@ -49,6 +49,8 @@
4949
50 void test_property_matching();50 void test_property_matching();
5151
52 void test_get_node_property();
53
52private:54private:
53 QMainWindow *m_object;55 QMainWindow *m_object;
54};56};
@@ -511,6 +513,31 @@
511 QVERIFY(n.MatchBooleanProperty("visible", true) == true);513 QVERIFY(n.MatchBooleanProperty("visible", true) == true);
512}514}
513515
516void tst_Introspection::test_get_node_property()
517{
518 QVariant property;
519 QVariant unpacked_property;
520
521 property = GetNodeProperty(m_object, "dynamicTestProperty");
522 unpacked_property = qvariant_cast<QVariantList>(property).at(1);
523 QVERIFY(property.isValid() == true);
524 QVERIFY(unpacked_property.isValid() == true);
525 QVERIFY(unpacked_property.toString() == "testValue");
526
527 property = GetNodeProperty(m_object, "myUInt");
528 unpacked_property = qvariant_cast<QVariantList>(property).at(1);
529 QVERIFY(property.isValid() == true);
530 QVERIFY(unpacked_property.isValid() == true);
531 QVERIFY(unpacked_property.toFloat() == 5);
532
533 // Meta Property
534 property = GetNodeProperty(m_object, "fullScreen");
535 unpacked_property = qvariant_cast<QVariantList>(property).at(1);
536 QVERIFY(property.isValid() == true);
537 QVERIFY(unpacked_property.isValid() == true);
538 QVERIFY(unpacked_property.toBool() == false);
539}
540
514QTEST_MAIN(tst_Introspection)541QTEST_MAIN(tst_Introspection)
515542
516#include "tst_introspection.moc"543#include "tst_introspection.moc"

Subscribers

People subscribed via source and target branches