Fix binary incompatibility between openssl versions
[profile/ivi/qtbase.git] / src / testlib / qtestaccessible.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtTest module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QTESTACCESSIBLE_H
43 #define QTESTACCESSIBLE_H
44
45 #if 0
46 // inform syncqt
47 #pragma qt_no_master_include
48 #endif
49
50 #ifndef QT_NO_ACCESSIBILITY
51
52 #define QVERIFY_EVENT(event) \
53     QVERIFY(QTestAccessibility::verifyEvent(event))
54
55 #include <QtCore/qlist.h>
56 #include <QtCore/qdebug.h>
57 #include <QtGui/qaccessible.h>
58 #include <QtGui/qguiapplication.h>
59
60 QT_BEGIN_HEADER
61
62 QT_BEGIN_NAMESPACE
63
64
65 class QObject;
66
67 // Use pointers since we subclass QAccessibleEvent
68 typedef QList<QAccessibleEvent*> EventList;
69
70 bool operator==(const QAccessibleEvent &l, const QAccessibleEvent &r)
71 {
72     if (l.type() != r.type()) {
73 //        qDebug() << "QAccessibleEvent with wrong type: " << qAccessibleEventString(l.type()) << " and " << qAccessibleEventString(r.type());
74         return false;
75     }
76     if (l.object() != r.object() ||
77             l.child() != r.child()) {
78 //        qDebug() << "QAccessibleEvent for wrong object: " << l.object() << " and " << r.object() << " child: " << l.child() << " and " << r.child();
79         return false;
80     }
81
82     if (l.type() == QAccessible::StateChanged) {
83         return static_cast<const QAccessibleStateChangeEvent*>(&l)->changedStates()
84                 == static_cast<const QAccessibleStateChangeEvent*>(&r)->changedStates();
85     } else if (l.type() == QAccessible::TextCaretMoved) {
86         return static_cast<const QAccessibleTextCursorEvent*>(&l)->cursorPosition()
87                 == static_cast<const QAccessibleTextCursorEvent*>(&r)->cursorPosition();
88     } else if (l.type() == QAccessible::TextSelectionChanged) {
89         const QAccessibleTextSelectionEvent *le = static_cast<const QAccessibleTextSelectionEvent*>(&l);
90         const QAccessibleTextSelectionEvent *re = static_cast<const QAccessibleTextSelectionEvent*>(&r);
91         return  le->cursorPosition() == re->cursorPosition() &&
92                 le->selectionStart() == re->selectionStart() &&
93                 le->selectionEnd() == re->selectionEnd();
94     } else if (l.type() == QAccessible::TextInserted) {
95         const QAccessibleTextInsertEvent *le = static_cast<const QAccessibleTextInsertEvent*>(&l);
96         const QAccessibleTextInsertEvent *re = static_cast<const QAccessibleTextInsertEvent*>(&r);
97         return  le->cursorPosition() == re->cursorPosition() &&
98                 le->changePosition() == re->changePosition() &&
99                 le->textInserted() == re->textInserted();
100     } else if (l.type() == QAccessible::TextRemoved) {
101         const QAccessibleTextRemoveEvent *le = static_cast<const QAccessibleTextRemoveEvent*>(&l);
102         const QAccessibleTextRemoveEvent *re = static_cast<const QAccessibleTextRemoveEvent*>(&r);
103         return  le->cursorPosition() == re->cursorPosition() &&
104                 le->changePosition() == re->changePosition() &&
105                 le->textRemoved() == re->textRemoved();
106     } else if (l.type() == QAccessible::TextUpdated) {
107         const QAccessibleTextUpdateEvent *le = static_cast<const QAccessibleTextUpdateEvent*>(&l);
108         const QAccessibleTextUpdateEvent *re = static_cast<const QAccessibleTextUpdateEvent*>(&r);
109         return  le->cursorPosition() == re->cursorPosition() &&
110                 le->changePosition() == re->changePosition() &&
111                 le->textInserted() == re->textInserted() &&
112                 le->textRemoved() == re->textRemoved();
113     } else if (l.type() == QAccessible::ValueChanged) {
114         const QAccessibleValueChangeEvent *le = static_cast<const QAccessibleValueChangeEvent*>(&l);
115         const QAccessibleValueChangeEvent *re = static_cast<const QAccessibleValueChangeEvent*>(&r);
116         return le->value() == re->value();
117     }
118     return true;
119 }
120
121 class QTestAccessibility
122 {
123 public:
124     static void initialize()
125     {
126         if (!instance()) {
127             instance() = new QTestAccessibility;
128             qAddPostRoutine(cleanup);
129         }
130     }
131
132     static void cleanup()
133     {
134         delete instance();
135         instance() = 0;
136     }
137     static void clearEvents() { eventList().clear(); }
138     static EventList events() { return eventList(); }
139     static bool verifyEvent(QAccessibleEvent *ev)
140     {
141         for (int i = 0; eventList().isEmpty() && i < 5; ++i)
142             QTest::qWait(50);
143         if (eventList().isEmpty()) {
144             qWarning("%s: Timeout waiting for accessibility event.", Q_FUNC_INFO);
145             return false;
146         }
147         const bool res = *eventList().first() == *ev;
148         if (!res)
149             qWarning("%s: %s", Q_FUNC_INFO,
150                      qPrintable(msgAccessibilityEventListMismatch(eventList(), ev)));
151         delete eventList().takeFirst();
152         return res;
153     }
154     static bool containsEvent(QAccessibleEvent *event) {
155         Q_FOREACH (const QAccessibleEvent *ev, eventList()) {
156             if (*ev == *event)
157                 return true;
158         }
159         return false;
160     }
161
162 private:
163     QTestAccessibility()
164     {
165         QAccessible::installUpdateHandler(updateHandler);
166         QAccessible::installRootObjectHandler(rootObjectHandler);
167     }
168
169     ~QTestAccessibility()
170     {
171         QAccessible::installUpdateHandler(0);
172         QAccessible::installRootObjectHandler(0);
173     }
174
175     static void rootObjectHandler(QObject *object)
176     {
177         //    qDebug("rootObjectHandler called %p", object);
178         if (object) {
179             QGuiApplication* app = qobject_cast<QGuiApplication*>(object);
180             if ( !app )
181                 qWarning("%s: root Object is not a QGuiApplication!", Q_FUNC_INFO);
182         } else {
183             qWarning("%s: root Object called with 0 pointer", Q_FUNC_INFO);
184         }
185     }
186
187     static void updateHandler(QAccessibleEvent *event)
188     {
189         eventList().append(copyEvent(event));
190     }
191     static QAccessibleEvent *copyEvent(QAccessibleEvent *event)
192     {
193         QAccessibleEvent *ev;
194         if (event->type() == QAccessible::StateChanged) {
195             ev = new QAccessibleStateChangeEvent(event->object(),
196                         static_cast<QAccessibleStateChangeEvent*>(event)->changedStates());
197         } else if (event->type() == QAccessible::TextCaretMoved) {
198             ev =  new QAccessibleTextCursorEvent(event->object(), static_cast<QAccessibleTextCursorEvent*>(event)->cursorPosition());
199         } else if (event->type() == QAccessible::TextSelectionChanged) {
200             const QAccessibleTextSelectionEvent *original = static_cast<QAccessibleTextSelectionEvent*>(event);
201             QAccessibleTextSelectionEvent *sel = new QAccessibleTextSelectionEvent(event->object(), original->selectionStart(), original->selectionEnd());
202             sel->setCursorPosition(original->cursorPosition());
203             ev = sel;
204         } else if (event->type() == QAccessible::TextInserted) {
205             const QAccessibleTextInsertEvent *original = static_cast<QAccessibleTextInsertEvent*>(event);
206             QAccessibleTextInsertEvent *ins = new QAccessibleTextInsertEvent(event->object(), original->changePosition(), original->textInserted());
207             ins->setCursorPosition(original->cursorPosition());
208             ev = ins;
209         } else if (event->type() == QAccessible::TextRemoved) {
210             const QAccessibleTextRemoveEvent *original = static_cast<QAccessibleTextRemoveEvent*>(event);
211             QAccessibleTextRemoveEvent *rem = new QAccessibleTextRemoveEvent(event->object(), original->changePosition(), original->textRemoved());
212             rem->setCursorPosition(original->cursorPosition());
213             ev = rem;
214         } else if (event->type() == QAccessible::TextUpdated) {
215             const QAccessibleTextUpdateEvent *original = static_cast<QAccessibleTextUpdateEvent*>(event);
216             QAccessibleTextUpdateEvent *upd = new QAccessibleTextUpdateEvent(event->object(), original->changePosition(), original->textRemoved(), original->textInserted());
217             upd->setCursorPosition(original->cursorPosition());
218             ev = upd;
219         } else if (event->type() == QAccessible::ValueChanged) {
220             ev = new QAccessibleValueChangeEvent(event->object(), static_cast<QAccessibleValueChangeEvent*>(event)->value());
221         } else if (event->type() == QAccessible::TableModelChanged) {
222             QAccessibleTableModelChangeEvent *oldEvent = static_cast<QAccessibleTableModelChangeEvent*>(event);
223             QAccessibleTableModelChangeEvent *newEvent = new QAccessibleTableModelChangeEvent(event->object(), oldEvent->modelChangeType());
224             newEvent->setFirstRow(oldEvent->firstRow());
225             newEvent->setFirstColumn(oldEvent->firstColumn());
226             newEvent->setLastRow(oldEvent->lastRow());
227             newEvent->setLastColumn(oldEvent->lastColumn());
228             ev = newEvent;
229         } else {
230             ev = new QAccessibleEvent(event->object(), event->type());
231         }
232         ev->setChild(event->child());
233         return ev;
234     }
235
236     static EventList &eventList()
237     {
238         static EventList list;
239         return list;
240     }
241
242     static QTestAccessibility *&instance()
243     {
244         static QTestAccessibility *ta = 0;
245         return ta;
246     }
247
248 private:
249     static QString msgAccessibilityEventListMismatch(const EventList &haystack,
250                                                      const QAccessibleEvent *needle)
251     {
252         QString rc;
253         QDebug str = QDebug(&rc).nospace();
254         str << "Event " << needle->object() <<  ", type: "
255            << needle->type() << ", child: " << needle->child()
256            <<  " not found at head of event list of size " << haystack.size() << " :";
257         foreach (const QAccessibleEvent *e, haystack)
258             str << ' ' << e->object() << ", type: "
259                 << e->type() << ", child: " << e->child();
260         return rc;
261     }
262
263 };
264
265 QT_END_NAMESPACE
266
267 QT_END_HEADER
268
269 #endif // QT_NO_ACCESSIBILITY
270 #endif // QTESTACCESSIBLE_H