Remove usage of deprecated qWaitForWindowShown(QWidget *) method.
[profile/ivi/qtbase.git] / tests / auto / other / qfocusevent / tst_qfocusevent.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTest>
44 #include <qapplication.h>
45 #include <qlineedit.h>
46 #include <qmenu.h>
47 #include <qlabel.h>
48 #include <qdialog.h>
49 #include <qevent.h>
50 #include <qlineedit.h>
51 #include <QBoxLayout>
52
53 QT_FORWARD_DECLARE_CLASS(QWidget)
54
55 class FocusLineEdit : public QLineEdit
56 {
57 public:
58     FocusLineEdit( QWidget* parent = 0, const char* name = 0 ) : QLineEdit(name, parent) {}
59     int focusInEventReason;
60     int focusOutEventReason;
61     bool focusInEventRecieved;
62     bool focusInEventGotFocus;
63     bool focusOutEventRecieved;
64     bool focusOutEventLostFocus;
65 protected:
66     virtual void keyPressEvent( QKeyEvent *e )
67     {
68 //        qDebug( QString("keyPressEvent: %1").arg(e->key()) );
69         QLineEdit::keyPressEvent( e );
70     }
71     void focusInEvent( QFocusEvent* e )
72     {
73         QLineEdit::focusInEvent( e );
74         focusInEventReason = e->reason();
75             focusInEventGotFocus = e->gotFocus();
76         focusInEventRecieved = true;
77     }
78     void focusOutEvent( QFocusEvent* e )
79     {
80         QLineEdit::focusOutEvent( e );
81         focusOutEventReason = e->reason();
82             focusOutEventLostFocus = !e->gotFocus();
83         focusOutEventRecieved = true;
84     }
85 };
86
87 class tst_QFocusEvent : public QObject
88 {
89     Q_OBJECT
90
91 public:
92     tst_QFocusEvent();
93     virtual ~tst_QFocusEvent();
94
95
96     void initWidget();
97
98 public slots:
99     void initTestCase();
100     void cleanupTestCase();
101     void init();
102     void cleanup();
103 private slots:
104     void checkReason_Tab();
105     void checkReason_ShiftTab();
106     void checkReason_BackTab();
107     void checkReason_Popup();
108     void checkReason_focusWidget();
109     void checkReason_Shortcut();
110     void checkReason_ActiveWindow();
111
112 private:
113     QWidget* testFocusWidget;
114     FocusLineEdit* childFocusWidgetOne;
115     FocusLineEdit* childFocusWidgetTwo;
116 };
117
118 tst_QFocusEvent::tst_QFocusEvent()
119 {
120 }
121
122 tst_QFocusEvent::~tst_QFocusEvent()
123 {
124
125 }
126
127 void tst_QFocusEvent::initTestCase()
128 {
129     testFocusWidget = new QWidget( 0 );
130     childFocusWidgetOne = new FocusLineEdit( testFocusWidget );
131     childFocusWidgetOne->setGeometry( 10, 10, 180, 20 );
132     childFocusWidgetTwo = new FocusLineEdit( testFocusWidget );
133     childFocusWidgetTwo->setGeometry( 10, 50, 180, 20 );
134
135     //qApp->setMainWidget( testFocusWidget ); Qt4
136     testFocusWidget->resize( 200,100 );
137     testFocusWidget->show();
138     QVERIFY(QTest::qWaitForWindowExposed(testFocusWidget));
139 // Applications don't get focus when launched from the command line on Mac.
140 #ifdef Q_OS_MAC
141     testFocusWidget->raise();
142 #endif
143 }
144
145 void tst_QFocusEvent::cleanupTestCase()
146 {
147     delete testFocusWidget;
148 }
149
150 void tst_QFocusEvent::init()
151 {
152 }
153
154 void tst_QFocusEvent::cleanup()
155 {
156     childFocusWidgetTwo->setGeometry( 10, 50, 180, 20 );
157 }
158
159 void tst_QFocusEvent::initWidget()
160 {
161     // On X11 we have to ensure the event was processed before doing any checking, on Windows
162     // this is processed straight away.
163     QApplication::setActiveWindow(testFocusWidget);
164     childFocusWidgetOne->setFocus(); // The first lineedit should have focus
165     QVERIFY(QTest::qWaitForWindowActive(testFocusWidget));
166     QTRY_VERIFY(childFocusWidgetOne->hasFocus());
167
168     childFocusWidgetOne->focusInEventRecieved = false;
169     childFocusWidgetOne->focusInEventGotFocus = false;
170     childFocusWidgetOne->focusInEventReason = -1;
171     childFocusWidgetOne->focusOutEventRecieved = false;
172     childFocusWidgetOne->focusOutEventLostFocus = false;
173     childFocusWidgetOne->focusOutEventReason = -1;
174     childFocusWidgetTwo->focusInEventRecieved = false;
175     childFocusWidgetTwo->focusInEventGotFocus = false;
176     childFocusWidgetTwo->focusInEventReason = -1;
177     childFocusWidgetTwo->focusOutEventRecieved = false;
178     childFocusWidgetTwo->focusOutEventLostFocus = false;
179     childFocusWidgetTwo->focusOutEventReason = -1;
180 }
181
182 void tst_QFocusEvent::checkReason_Tab()
183 {
184     initWidget();
185
186     // Now test the tab key
187     QTest::keyClick( childFocusWidgetOne, Qt::Key_Tab );
188
189     QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
190     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
191     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
192     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
193
194     QVERIFY( childFocusWidgetTwo->hasFocus() );
195     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int) Qt::TabFocusReason );
196     QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int) Qt::TabFocusReason );
197 }
198
199 void tst_QFocusEvent::checkReason_ShiftTab()
200 {
201     initWidget();
202
203     // Now test the shift + tab key
204     QTest::keyClick( childFocusWidgetOne, Qt::Key_Tab, Qt::ShiftModifier );
205
206     QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
207     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
208     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
209     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
210
211     QVERIFY( childFocusWidgetTwo->hasFocus() );
212     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::BacktabFocusReason );
213     QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int)Qt::BacktabFocusReason );
214
215 }
216
217 /*!
218     In this test we verify that the Qt::KeyBacktab key is handled in a qfocusevent
219 */
220 void tst_QFocusEvent::checkReason_BackTab()
221 {
222 #ifdef Q_OS_WIN32 // key is not supported on Windows
223     QSKIP( "Backtab is not supported on Windows");
224 #else
225     initWidget();
226     QVERIFY( childFocusWidgetOne->hasFocus() );
227
228     // Now test the backtab key
229     QTest::keyClick( childFocusWidgetOne, Qt::Key_Backtab );
230     QTest::qWait(200);
231
232     QTRY_VERIFY(childFocusWidgetOne->focusOutEventRecieved);
233     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
234     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
235     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
236
237     QVERIFY( childFocusWidgetTwo->hasFocus() );
238     QCOMPARE( childFocusWidgetOne->focusOutEventReason, int(Qt::BacktabFocusReason) );
239     QCOMPARE( childFocusWidgetTwo->focusInEventReason, int(Qt::BacktabFocusReason) );
240 #endif
241 }
242
243 void tst_QFocusEvent::checkReason_Popup()
244 {
245     initWidget();
246
247     // Now test the popup reason
248     QMenu* popupMenu = new QMenu( testFocusWidget );
249     popupMenu->addMenu( "Test" );
250     popupMenu->popup( QPoint(0,0) );
251     QTest::qWait(50);
252
253     QTRY_VERIFY(childFocusWidgetOne->focusOutEventLostFocus);
254
255     QTRY_VERIFY( childFocusWidgetOne->hasFocus() );
256     QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
257     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
258     QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
259     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
260     QCOMPARE( childFocusWidgetOne->focusOutEventReason, int(Qt::PopupFocusReason));
261
262     popupMenu->hide();
263
264     QVERIFY(childFocusWidgetOne->focusInEventRecieved);
265     QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
266
267     QVERIFY( childFocusWidgetOne->hasFocus() );
268     QVERIFY( childFocusWidgetOne->focusInEventRecieved );
269     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
270     QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
271     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
272 }
273
274 #ifdef Q_OS_MAC
275 QT_BEGIN_NAMESPACE
276     extern void qt_set_sequence_auto_mnemonic(bool);
277 QT_END_NAMESPACE
278 #endif
279
280 void tst_QFocusEvent::checkReason_Shortcut()
281 {
282     initWidget();
283 #ifdef Q_OS_MAC
284     qt_set_sequence_auto_mnemonic(true);
285 #endif
286     QLabel* label = new QLabel( "&Test", testFocusWidget );
287     label->setBuddy( childFocusWidgetTwo );
288     label->setGeometry( 10, 50, 90, 20 );
289     childFocusWidgetTwo->setGeometry( 105, 50, 95, 20 );
290     label->show();
291
292     QVERIFY( childFocusWidgetOne->hasFocus() );
293     QVERIFY( !childFocusWidgetTwo->hasFocus() );
294
295     QTest::keyClick( label, Qt::Key_T, Qt::AltModifier );
296
297     QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
298     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
299     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
300     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
301
302     QVERIFY( childFocusWidgetTwo->hasFocus() );
303     QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
304     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
305     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::ShortcutFocusReason );
306     QVERIFY( childFocusWidgetTwo->focusInEventRecieved );
307     QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int)Qt::ShortcutFocusReason );
308     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
309
310     label->hide();
311     QVERIFY( childFocusWidgetTwo->hasFocus() );
312     QVERIFY( !childFocusWidgetOne->hasFocus() );
313 #ifdef Q_OS_MAC
314     qt_set_sequence_auto_mnemonic(false);
315 #endif
316 }
317
318 void tst_QFocusEvent::checkReason_focusWidget()
319 {
320     // This test checks that a widget doesn't loose
321     // its focuswidget just because the focuswidget looses focus.
322     QWidget window1;
323     QWidget frame1;
324     QWidget frame2;
325     QLineEdit edit1;
326     QLineEdit edit2;
327
328     QVBoxLayout outerLayout;
329     outerLayout.addWidget(&frame1);
330     outerLayout.addWidget(&frame2);
331     window1.setLayout(&outerLayout);
332
333     QVBoxLayout leftLayout;
334     QVBoxLayout rightLayout;
335     leftLayout.addWidget(&edit1);
336     rightLayout.addWidget(&edit2);
337     frame1.setLayout(&leftLayout);
338     frame2.setLayout(&rightLayout);
339     window1.show();
340
341     edit1.setFocus();
342     QTest::qWait(100);
343     edit2.setFocus();
344
345     QVERIFY(frame1.focusWidget() != 0);
346     QVERIFY(frame2.focusWidget() != 0);
347 }
348
349 void tst_QFocusEvent::checkReason_ActiveWindow()
350 {
351     initWidget();
352
353     QDialog* d = new QDialog( testFocusWidget );
354     d->show();
355     d->activateWindow(); // ### CDE
356     QApplication::setActiveWindow(d);
357     QVERIFY(QTest::qWaitForWindowActive(d));
358
359     QTRY_VERIFY(childFocusWidgetOne->focusOutEventRecieved);
360     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
361
362     QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
363     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
364     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::ActiveWindowFocusReason);
365     QVERIFY( !childFocusWidgetOne->hasFocus() );
366
367     d->hide();
368     QTest::qWait(100);
369
370 #if defined(Q_OS_IRIX)
371     QEXPECT_FAIL("", "IRIX requires explicit activateWindow(), so this test does not make any sense.", Abort);
372 #endif
373 #ifdef Q_OS_MAC
374     QEXPECT_FAIL("", "QTBUG-22815", Abort);
375 #endif
376     if (QGuiApplication::platformName() == QStringLiteral("xcb"))
377         QSKIP("QTBUG-22815 - This test is unstable on this platform");
378     QTRY_VERIFY(childFocusWidgetOne->focusInEventRecieved);
379     QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
380
381     QVERIFY( childFocusWidgetOne->hasFocus() );
382     QVERIFY( childFocusWidgetOne->focusInEventRecieved );
383     QCOMPARE( childFocusWidgetOne->focusInEventReason, (int)Qt::ActiveWindowFocusReason);
384 }
385
386
387 QTEST_MAIN(tst_QFocusEvent)
388 #include "tst_qfocusevent.moc"