qt5base-lts/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
Sergio Ahumada 48e0c4df23 Update copyright year in Digia's license headers
Change-Id: Ic804938fc352291d011800d21e549c10acac66fb
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
2013-01-18 09:07:35 +01:00

389 lines
12 KiB
C++

/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <qapplication.h>
#include <qlineedit.h>
#include <qmenu.h>
#include <qlabel.h>
#include <qdialog.h>
#include <qevent.h>
#include <qlineedit.h>
#include <QBoxLayout>
QT_FORWARD_DECLARE_CLASS(QWidget)
class FocusLineEdit : public QLineEdit
{
public:
FocusLineEdit( QWidget* parent = 0, const char* name = 0 ) : QLineEdit(name, parent) {}
int focusInEventReason;
int focusOutEventReason;
bool focusInEventRecieved;
bool focusInEventGotFocus;
bool focusOutEventRecieved;
bool focusOutEventLostFocus;
protected:
virtual void keyPressEvent( QKeyEvent *e )
{
// qDebug( QString("keyPressEvent: %1").arg(e->key()) );
QLineEdit::keyPressEvent( e );
}
void focusInEvent( QFocusEvent* e )
{
QLineEdit::focusInEvent( e );
focusInEventReason = e->reason();
focusInEventGotFocus = e->gotFocus();
focusInEventRecieved = true;
}
void focusOutEvent( QFocusEvent* e )
{
QLineEdit::focusOutEvent( e );
focusOutEventReason = e->reason();
focusOutEventLostFocus = !e->gotFocus();
focusOutEventRecieved = true;
}
};
class tst_QFocusEvent : public QObject
{
Q_OBJECT
public:
tst_QFocusEvent();
virtual ~tst_QFocusEvent();
void initWidget();
public slots:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
private slots:
void checkReason_Tab();
void checkReason_ShiftTab();
void checkReason_BackTab();
void checkReason_Popup();
void checkReason_focusWidget();
void checkReason_Shortcut();
void checkReason_ActiveWindow();
private:
QWidget* testFocusWidget;
FocusLineEdit* childFocusWidgetOne;
FocusLineEdit* childFocusWidgetTwo;
};
tst_QFocusEvent::tst_QFocusEvent()
{
}
tst_QFocusEvent::~tst_QFocusEvent()
{
}
void tst_QFocusEvent::initTestCase()
{
testFocusWidget = new QWidget( 0 );
childFocusWidgetOne = new FocusLineEdit( testFocusWidget );
childFocusWidgetOne->setGeometry( 10, 10, 180, 20 );
childFocusWidgetTwo = new FocusLineEdit( testFocusWidget );
childFocusWidgetTwo->setGeometry( 10, 50, 180, 20 );
//qApp->setMainWidget( testFocusWidget ); Qt4
testFocusWidget->resize( 200,100 );
testFocusWidget->show();
QVERIFY(QTest::qWaitForWindowExposed(testFocusWidget));
// Applications don't get focus when launched from the command line on Mac.
#ifdef Q_OS_MAC
testFocusWidget->raise();
#endif
}
void tst_QFocusEvent::cleanupTestCase()
{
delete testFocusWidget;
}
void tst_QFocusEvent::init()
{
}
void tst_QFocusEvent::cleanup()
{
childFocusWidgetTwo->setGeometry( 10, 50, 180, 20 );
}
void tst_QFocusEvent::initWidget()
{
// On X11 we have to ensure the event was processed before doing any checking, on Windows
// this is processed straight away.
QApplication::setActiveWindow(testFocusWidget);
childFocusWidgetOne->setFocus(); // The first lineedit should have focus
QVERIFY(QTest::qWaitForWindowActive(testFocusWidget));
QTRY_VERIFY(childFocusWidgetOne->hasFocus());
childFocusWidgetOne->focusInEventRecieved = false;
childFocusWidgetOne->focusInEventGotFocus = false;
childFocusWidgetOne->focusInEventReason = -1;
childFocusWidgetOne->focusOutEventRecieved = false;
childFocusWidgetOne->focusOutEventLostFocus = false;
childFocusWidgetOne->focusOutEventReason = -1;
childFocusWidgetTwo->focusInEventRecieved = false;
childFocusWidgetTwo->focusInEventGotFocus = false;
childFocusWidgetTwo->focusInEventReason = -1;
childFocusWidgetTwo->focusOutEventRecieved = false;
childFocusWidgetTwo->focusOutEventLostFocus = false;
childFocusWidgetTwo->focusOutEventReason = -1;
}
void tst_QFocusEvent::checkReason_Tab()
{
initWidget();
// Now test the tab key
QTest::keyClick( childFocusWidgetOne, Qt::Key_Tab );
QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
QVERIFY( childFocusWidgetTwo->hasFocus() );
QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int) Qt::TabFocusReason );
QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int) Qt::TabFocusReason );
}
void tst_QFocusEvent::checkReason_ShiftTab()
{
initWidget();
// Now test the shift + tab key
QTest::keyClick( childFocusWidgetOne, Qt::Key_Tab, Qt::ShiftModifier );
QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
QVERIFY( childFocusWidgetTwo->hasFocus() );
QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::BacktabFocusReason );
QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int)Qt::BacktabFocusReason );
}
/*!
In this test we verify that the Qt::KeyBacktab key is handled in a qfocusevent
*/
void tst_QFocusEvent::checkReason_BackTab()
{
#ifdef Q_OS_WIN32 // key is not supported on Windows
QSKIP( "Backtab is not supported on Windows");
#else
initWidget();
QVERIFY( childFocusWidgetOne->hasFocus() );
// Now test the backtab key
QTest::keyClick( childFocusWidgetOne, Qt::Key_Backtab );
QTest::qWait(200);
QTRY_VERIFY(childFocusWidgetOne->focusOutEventRecieved);
QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
QVERIFY( childFocusWidgetTwo->hasFocus() );
QCOMPARE( childFocusWidgetOne->focusOutEventReason, int(Qt::BacktabFocusReason) );
QCOMPARE( childFocusWidgetTwo->focusInEventReason, int(Qt::BacktabFocusReason) );
#endif
}
void tst_QFocusEvent::checkReason_Popup()
{
initWidget();
// Now test the popup reason
QMenu* popupMenu = new QMenu( testFocusWidget );
popupMenu->addMenu( "Test" );
popupMenu->popup( QPoint(0,0) );
QTest::qWait(50);
QTRY_VERIFY(childFocusWidgetOne->focusOutEventLostFocus);
QTRY_VERIFY( childFocusWidgetOne->hasFocus() );
QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
QCOMPARE( childFocusWidgetOne->focusOutEventReason, int(Qt::PopupFocusReason));
popupMenu->hide();
QVERIFY(childFocusWidgetOne->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
QVERIFY( childFocusWidgetOne->hasFocus() );
QVERIFY( childFocusWidgetOne->focusInEventRecieved );
QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
QVERIFY( !childFocusWidgetTwo->focusInEventRecieved );
QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
}
#ifdef Q_OS_MAC
QT_BEGIN_NAMESPACE
extern void qt_set_sequence_auto_mnemonic(bool);
QT_END_NAMESPACE
#endif
void tst_QFocusEvent::checkReason_Shortcut()
{
initWidget();
#ifdef Q_OS_MAC
qt_set_sequence_auto_mnemonic(true);
#endif
QLabel* label = new QLabel( "&Test", testFocusWidget );
label->setBuddy( childFocusWidgetTwo );
label->setGeometry( 10, 50, 90, 20 );
childFocusWidgetTwo->setGeometry( 105, 50, 95, 20 );
label->show();
QVERIFY( childFocusWidgetOne->hasFocus() );
QVERIFY( !childFocusWidgetTwo->hasFocus() );
QTest::keyClick( label, Qt::Key_T, Qt::AltModifier );
QVERIFY(childFocusWidgetOne->focusOutEventRecieved);
QVERIFY(childFocusWidgetTwo->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
QVERIFY(childFocusWidgetTwo->focusInEventGotFocus);
QVERIFY( childFocusWidgetTwo->hasFocus() );
QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::ShortcutFocusReason );
QVERIFY( childFocusWidgetTwo->focusInEventRecieved );
QCOMPARE( childFocusWidgetTwo->focusInEventReason, (int)Qt::ShortcutFocusReason );
QVERIFY( !childFocusWidgetTwo->focusOutEventRecieved );
label->hide();
QVERIFY( childFocusWidgetTwo->hasFocus() );
QVERIFY( !childFocusWidgetOne->hasFocus() );
#ifdef Q_OS_MAC
qt_set_sequence_auto_mnemonic(false);
#endif
}
void tst_QFocusEvent::checkReason_focusWidget()
{
// This test checks that a widget doesn't loose
// its focuswidget just because the focuswidget looses focus.
QWidget window1;
QWidget frame1;
QWidget frame2;
QLineEdit edit1;
QLineEdit edit2;
QVBoxLayout outerLayout;
outerLayout.addWidget(&frame1);
outerLayout.addWidget(&frame2);
window1.setLayout(&outerLayout);
QVBoxLayout leftLayout;
QVBoxLayout rightLayout;
leftLayout.addWidget(&edit1);
rightLayout.addWidget(&edit2);
frame1.setLayout(&leftLayout);
frame2.setLayout(&rightLayout);
window1.show();
edit1.setFocus();
QTest::qWait(100);
edit2.setFocus();
QVERIFY(frame1.focusWidget() != 0);
QVERIFY(frame2.focusWidget() != 0);
}
void tst_QFocusEvent::checkReason_ActiveWindow()
{
initWidget();
QDialog* d = new QDialog( testFocusWidget );
d->show();
QVERIFY(QTest::qWaitForWindowExposed(d));
d->activateWindow(); // ### CDE
QApplication::setActiveWindow(d);
QVERIFY(QTest::qWaitForWindowActive(d));
QTRY_VERIFY(childFocusWidgetOne->focusOutEventRecieved);
QVERIFY(childFocusWidgetOne->focusOutEventLostFocus);
QVERIFY( !childFocusWidgetOne->focusInEventRecieved );
QVERIFY( childFocusWidgetOne->focusOutEventRecieved );
QCOMPARE( childFocusWidgetOne->focusOutEventReason, (int)Qt::ActiveWindowFocusReason);
QVERIFY( !childFocusWidgetOne->hasFocus() );
d->hide();
QTest::qWait(100);
#if defined(Q_OS_IRIX)
QEXPECT_FAIL("", "IRIX requires explicit activateWindow(), so this test does not make any sense.", Abort);
#endif
#ifdef Q_OS_MAC
QEXPECT_FAIL("", "QTBUG-22815", Abort);
#endif
QTRY_VERIFY(childFocusWidgetOne->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
QVERIFY( childFocusWidgetOne->hasFocus() );
QVERIFY( childFocusWidgetOne->focusInEventRecieved );
QCOMPARE( childFocusWidgetOne->focusInEventReason, (int)Qt::ActiveWindowFocusReason);
}
QTEST_MAIN(tst_QFocusEvent)
#include "tst_qfocusevent.moc"