tests/auto/qfocusevent/tst_qfocusevent.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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 test suite 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 
       
    43 #include <QtTest/QtTest>
       
    44 #include <qapplication.h>
       
    45 #include <qlineedit.h>
       
    46 
       
    47 #if defined (QT3_SUPPORT)
       
    48 #include <q3popupmenu.h>
       
    49 #else
       
    50 #include <qmenu.h>
       
    51 #endif
       
    52 
       
    53 #include <qlabel.h>
       
    54 #include <qdialog.h>
       
    55 #include <qevent.h>
       
    56 #include <qlineedit.h>
       
    57 #include <QBoxLayout>
       
    58 
       
    59 #include "../../shared/util.h"
       
    60 
       
    61 QT_FORWARD_DECLARE_CLASS(QWidget)
       
    62 
       
    63 //TESTED_CLASS=
       
    64 //TESTED_FILES=gui/kernel/qevent.h gui/kernel/qevent.cpp
       
    65 
       
    66 class FocusLineEdit : public QLineEdit
       
    67 {
       
    68 public:
       
    69     FocusLineEdit( QWidget* parent = 0, const char* name = 0 ) : QLineEdit(name, parent) {}
       
    70     int focusInEventReason;
       
    71     int focusOutEventReason;
       
    72     bool focusInEventRecieved;
       
    73     bool focusInEventGotFocus;
       
    74     bool focusOutEventRecieved;
       
    75     bool focusOutEventLostFocus;
       
    76 protected:
       
    77     virtual void keyPressEvent( QKeyEvent *e )
       
    78     {
       
    79 //        qDebug( QString("keyPressEvent: %1").arg(e->key()) );
       
    80         QLineEdit::keyPressEvent( e );
       
    81     }
       
    82     void focusInEvent( QFocusEvent* e )
       
    83     {
       
    84         QLineEdit::focusInEvent( e );
       
    85         focusInEventReason = e->reason();
       
    86 	    focusInEventGotFocus = e->gotFocus();
       
    87         focusInEventRecieved = TRUE;
       
    88     }
       
    89     void focusOutEvent( QFocusEvent* e )
       
    90     {
       
    91         QLineEdit::focusOutEvent( e );
       
    92         focusOutEventReason = e->reason();
       
    93 	    focusOutEventLostFocus = !e->gotFocus();
       
    94         focusOutEventRecieved = TRUE;
       
    95     }
       
    96 };
       
    97 
       
    98 class tst_QFocusEvent : public QObject
       
    99 {
       
   100     Q_OBJECT
       
   101 
       
   102 public:
       
   103     tst_QFocusEvent();
       
   104     virtual ~tst_QFocusEvent();
       
   105 
       
   106 
       
   107     void initWidget();
       
   108 
       
   109 public slots:
       
   110     void initTestCase();
       
   111     void cleanupTestCase();
       
   112     void init();
       
   113     void cleanup();
       
   114 private slots:
       
   115     void checkReason_Tab();
       
   116     void checkReason_ShiftTab();
       
   117     void checkReason_BackTab();
       
   118     void checkReason_Popup();
       
   119     void checkReason_focusWidget();
       
   120     void checkReason_Shortcut();
       
   121     void checkReason_ActiveWindow();
       
   122 
       
   123 private:
       
   124     QWidget* testFocusWidget;
       
   125     FocusLineEdit* childFocusWidgetOne;
       
   126     FocusLineEdit* childFocusWidgetTwo;
       
   127 };
       
   128 
       
   129 tst_QFocusEvent::tst_QFocusEvent()
       
   130 {
       
   131 }
       
   132 
       
   133 tst_QFocusEvent::~tst_QFocusEvent()
       
   134 {
       
   135 
       
   136 }
       
   137 
       
   138 void tst_QFocusEvent::initTestCase()
       
   139 {
       
   140     testFocusWidget = new QWidget( 0 );
       
   141     childFocusWidgetOne = new FocusLineEdit( testFocusWidget );
       
   142     childFocusWidgetOne->setGeometry( 10, 10, 180, 20 );
       
   143     childFocusWidgetTwo = new FocusLineEdit( testFocusWidget );
       
   144     childFocusWidgetTwo->setGeometry( 10, 50, 180, 20 );
       
   145 
       
   146     //qApp->setMainWidget( testFocusWidget ); Qt4
       
   147     testFocusWidget->resize( 200,100 );
       
   148     testFocusWidget->show();
       
   149 // Applications don't get focus when launched from the command line on Mac.
       
   150 #ifdef Q_WS_MAC
       
   151     testFocusWidget->raise();
       
   152 #endif
       
   153 }
       
   154 
       
   155 void tst_QFocusEvent::cleanupTestCase()
       
   156 {
       
   157     delete testFocusWidget;
       
   158 }
       
   159 
       
   160 void tst_QFocusEvent::init()
       
   161 {
       
   162 }
       
   163 
       
   164 void tst_QFocusEvent::cleanup()
       
   165 {
       
   166     childFocusWidgetTwo->setGeometry( 10, 50, 180, 20 );
       
   167 }
       
   168 
       
   169 void tst_QFocusEvent::initWidget()
       
   170 {
       
   171     // On X11 we have to ensure the event was processed before doing any checking, on Windows
       
   172     // this is processed straight away.
       
   173     QApplication::setActiveWindow(childFocusWidgetOne);
       
   174 
       
   175     for (int i = 0; i < 1000; ++i) {
       
   176 	if (childFocusWidgetOne->isActiveWindow() && childFocusWidgetOne->hasFocus())
       
   177 	    break;
       
   178 	childFocusWidgetOne->activateWindow();
       
   179 	childFocusWidgetOne->setFocus();
       
   180 	qApp->processEvents();
       
   181 	QTest::qWait(100);
       
   182     }
       
   183 
       
   184     // The first lineedit should have focus
       
   185     QVERIFY( childFocusWidgetOne->hasFocus() );
       
   186 
       
   187     childFocusWidgetOne->focusInEventRecieved = FALSE;
       
   188     childFocusWidgetOne->focusInEventGotFocus = FALSE;
       
   189     childFocusWidgetOne->focusInEventReason = -1;
       
   190     childFocusWidgetOne->focusOutEventRecieved = FALSE;
       
   191     childFocusWidgetOne->focusOutEventLostFocus = FALSE;
       
   192     childFocusWidgetOne->focusOutEventReason = -1;
       
   193     childFocusWidgetTwo->focusInEventRecieved = FALSE;
       
   194     childFocusWidgetTwo->focusInEventGotFocus = FALSE;
       
   195     childFocusWidgetTwo->focusInEventReason = -1;
       
   196     childFocusWidgetTwo->focusOutEventRecieved = FALSE;
       
   197     childFocusWidgetTwo->focusOutEventLostFocus = FALSE;
       
   198     childFocusWidgetTwo->focusOutEventReason = -1;
       
   199 }
       
   200 
       
   201 void tst_QFocusEvent::checkReason_Tab()
       
   202 {
       
   203     initWidget();
       
   204 
       
   205     // Now test the tab key
       
   206     QTest::keyClick( childFocusWidgetOne, Qt::Key_Tab );
       
   207 
       
   208     QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
       
   209     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
       
   210     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
       
   211     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
       
   212 
       
   213     QVERIFY( childFocusWidgetTwo->hasFocus() );
       
   214     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int) Qt::TabFocusReason );
       
   215     QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int) Qt::TabFocusReason );
       
   216 }
       
   217 
       
   218 void tst_QFocusEvent::checkReason_ShiftTab()
       
   219 {
       
   220     initWidget();
       
   221 
       
   222     // Now test the shift + tab key
       
   223     QTest::keyClick( childFocusWidgetOne, Qt::Key_Tab, Qt::ShiftModifier );
       
   224 
       
   225     QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
       
   226     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
       
   227     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
       
   228     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
       
   229 
       
   230     QVERIFY( childFocusWidgetTwo->hasFocus() );
       
   231     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::BacktabFocusReason );
       
   232     QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int)Qt::BacktabFocusReason );
       
   233 
       
   234 }
       
   235 
       
   236 /*!
       
   237     In this test we verify that the Qt::KeyBacktab key is handled in a qfocusevent
       
   238 */
       
   239 void tst_QFocusEvent::checkReason_BackTab()
       
   240 {
       
   241 #ifdef Q_OS_WIN32 // key is not supported on Windows
       
   242     QSKIP( "Backtab is not supported on Windows", SkipAll );
       
   243 #else
       
   244     initWidget();
       
   245     QVERIFY( childFocusWidgetOne->hasFocus() );
       
   246 
       
   247     // Now test the backtab key
       
   248     QTest::keyClick( childFocusWidgetOne, Qt::Key_Backtab );
       
   249     QTest::qWait(200);
       
   250 
       
   251     QTRY_VERIFY(childFocusWidgetOne->focusOutEventRecieved);
       
   252     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
       
   253     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
       
   254     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
       
   255 
       
   256     QVERIFY( childFocusWidgetTwo->hasFocus() );
       
   257     QCOMPARE( childFocusWidgetOne->focusOutEventReason, int(Qt::BacktabFocusReason) );
       
   258     QCOMPARE( childFocusWidgetTwo->focusInEventReason, int(Qt::BacktabFocusReason) );
       
   259 #endif
       
   260 }
       
   261 
       
   262 void tst_QFocusEvent::checkReason_Popup()
       
   263 {
       
   264     initWidget();
       
   265 
       
   266     // Now test the popup reason
       
   267 #if defined (QT3_SUPPORT)
       
   268     Q3PopupMenu* popupMenu = new Q3PopupMenu( testFocusWidget );
       
   269     popupMenu->insertItem( "Test" );
       
   270     popupMenu->popup( QPoint(0,0) );
       
   271     QTest::qWait(50);
       
   272 
       
   273     QTRY_VERIFY(childFocusWidgetOne->focusOutEventLostFocus);
       
   274 
       
   275     QVERIFY( childFocusWidgetOne->hasFocus() );
       
   276     QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
       
   277     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
       
   278     QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
       
   279     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
       
   280     QCOMPARE( childFocusWidgetOne->focusOutEventReason, int(Qt::PopupFocusReason));
       
   281 
       
   282     popupMenu->hide();
       
   283 
       
   284     QVERIFY(childFocusWidgetOne->focusInEventRecieved);
       
   285     QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
       
   286 
       
   287     QVERIFY( childFocusWidgetOne->hasFocus() );
       
   288     QVERIFY( childFocusWidgetOne->focusInEventRecieved );
       
   289     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
       
   290     QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
       
   291     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
       
   292 #else
       
   293     QMenu* popupMenu = new QMenu( testFocusWidget );
       
   294     popupMenu->addMenu( "Test" );
       
   295     popupMenu->popup( QPoint(0,0) );
       
   296     QTest::qWait(50);
       
   297 
       
   298     QTRY_VERIFY(childFocusWidgetOne->focusOutEventLostFocus);
       
   299 
       
   300     QTRY_VERIFY( childFocusWidgetOne->hasFocus() );
       
   301     QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
       
   302     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
       
   303     QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
       
   304     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
       
   305     QCOMPARE( childFocusWidgetOne->focusOutEventReason, int(Qt::PopupFocusReason));
       
   306 
       
   307     popupMenu->hide();
       
   308 
       
   309     QVERIFY(childFocusWidgetOne->focusInEventRecieved);
       
   310     QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
       
   311 
       
   312     QVERIFY( childFocusWidgetOne->hasFocus() );
       
   313     QVERIFY( childFocusWidgetOne->focusInEventRecieved );
       
   314     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
       
   315     QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
       
   316     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
       
   317 #endif
       
   318 }
       
   319 
       
   320 #ifdef Q_WS_MAC
       
   321 QT_BEGIN_NAMESPACE
       
   322     extern void qt_set_sequence_auto_mnemonic(bool);
       
   323 QT_END_NAMESPACE
       
   324 #endif
       
   325 
       
   326 void tst_QFocusEvent::checkReason_Shortcut()
       
   327 {
       
   328     initWidget();
       
   329 #ifdef Q_WS_MAC
       
   330     qt_set_sequence_auto_mnemonic(true);
       
   331 #endif
       
   332     QLabel* label = new QLabel( "&Test", testFocusWidget );
       
   333     label->setBuddy( childFocusWidgetTwo );
       
   334     label->setGeometry( 10, 50, 90, 20 );
       
   335     childFocusWidgetTwo->setGeometry( 105, 50, 95, 20 );
       
   336     label->show();
       
   337 
       
   338     QVERIFY( childFocusWidgetOne->hasFocus() );
       
   339     QVERIFY( !childFocusWidgetTwo->hasFocus() );
       
   340 
       
   341     QTest::keyClick( label, Qt::Key_T, Qt::AltModifier );
       
   342 
       
   343     QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
       
   344     QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
       
   345     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
       
   346     QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
       
   347 
       
   348     QVERIFY( childFocusWidgetTwo->hasFocus() );
       
   349     QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
       
   350     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
       
   351     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::ShortcutFocusReason );
       
   352     QVERIFY( childFocusWidgetTwo->focusInEventRecieved );
       
   353     QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int)Qt::ShortcutFocusReason );
       
   354     QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
       
   355 
       
   356     label->hide();
       
   357     QVERIFY( childFocusWidgetTwo->hasFocus() );
       
   358     QVERIFY( !childFocusWidgetOne->hasFocus() );
       
   359 #ifdef Q_WS_MAC
       
   360     qt_set_sequence_auto_mnemonic(false);
       
   361 #endif
       
   362 }
       
   363 
       
   364 void tst_QFocusEvent::checkReason_focusWidget()
       
   365 {
       
   366     // This test checks that a widget doesn't loose
       
   367     // its focuswidget just because the focuswidget looses focus.
       
   368     QWidget window1;
       
   369     QWidget frame1;
       
   370     QWidget frame2;
       
   371     QLineEdit edit1;
       
   372     QLineEdit edit2;
       
   373 
       
   374     QVBoxLayout outerLayout;
       
   375     outerLayout.addWidget(&frame1);
       
   376     outerLayout.addWidget(&frame2);
       
   377     window1.setLayout(&outerLayout);
       
   378 
       
   379     QVBoxLayout leftLayout;
       
   380     QVBoxLayout rightLayout;
       
   381     leftLayout.addWidget(&edit1);
       
   382     rightLayout.addWidget(&edit2);
       
   383     frame1.setLayout(&leftLayout);
       
   384     frame2.setLayout(&rightLayout);
       
   385     window1.show();
       
   386 
       
   387     edit1.setFocus();
       
   388     QTest::qWait(100);
       
   389     edit2.setFocus();
       
   390 
       
   391     QVERIFY(frame1.focusWidget() != 0);
       
   392     QVERIFY(frame2.focusWidget() != 0);
       
   393 }
       
   394 
       
   395 void tst_QFocusEvent::checkReason_ActiveWindow()
       
   396 {
       
   397     initWidget();
       
   398 
       
   399     QDialog* d = new QDialog( testFocusWidget );
       
   400     d->show();
       
   401     d->activateWindow(); // ### CDE
       
   402     QApplication::setActiveWindow(d);
       
   403     QTest::qWaitForWindowShown(d);
       
   404 
       
   405     QTRY_VERIFY(childFocusWidgetOne->focusOutEventRecieved);
       
   406     QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
       
   407 
       
   408     QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
       
   409     QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
       
   410     QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::ActiveWindowFocusReason);
       
   411     QVERIFY( !childFocusWidgetOne->hasFocus() );
       
   412 
       
   413     d->hide();
       
   414     QTest::qWait(100);
       
   415 
       
   416 #if defined(Q_OS_IRIX)
       
   417     QEXPECT_FAIL("", "IRIX requires explicit activateWindow(), so this test does not make any sense.", Abort);
       
   418 #endif
       
   419     QTRY_VERIFY(childFocusWidgetOne->focusInEventRecieved);
       
   420     QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
       
   421 
       
   422     QVERIFY( childFocusWidgetOne->hasFocus() );
       
   423     QVERIFY( childFocusWidgetOne->focusInEventRecieved );
       
   424     QCOMPARE( childFocusWidgetOne->focusInEventReason, (int)Qt::ActiveWindowFocusReason);
       
   425 }
       
   426 
       
   427 
       
   428 QTEST_MAIN(tst_QFocusEvent)
       
   429 #include "tst_qfocusevent.moc"