diff options
author | Jo Asplin <jo.asplin@nokia.com> | 2011-10-20 13:17:26 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-10-20 19:45:41 +0200 |
commit | 9f1aa866bda7678261f2f441d4cfd5bb524c2411 (patch) | |
tree | 5028f578122e7feb9200d571405494c73d96db89 /tests/auto/widgets/widgets | |
parent | 78d02e93aca5325fc5be9bfd275862795207abaa (diff) |
Moved tests into integrationtests/ and widgets/
Task-number: QTBUG-19013
Change-Id: Ibb776f5967c0645ce6d22ef7afdc40657c575461
Reviewed-by: Holger Ihrig <holger.ihrig@nokia.com>
Diffstat (limited to 'tests/auto/widgets/widgets')
252 files changed, 54144 insertions, 0 deletions
diff --git a/tests/auto/widgets/widgets/qabstractbutton/.gitignore b/tests/auto/widgets/widgets/qabstractbutton/.gitignore new file mode 100644 index 0000000000..82f669574c --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractbutton/.gitignore @@ -0,0 +1 @@ +tst_qabstractbutton diff --git a/tests/auto/widgets/widgets/qabstractbutton/qabstractbutton.pro b/tests/auto/widgets/widgets/qabstractbutton/qabstractbutton.pro new file mode 100644 index 0000000000..15d90ed4e1 --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractbutton/qabstractbutton.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qabstractbutton.cpp + + diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp new file mode 100644 index 0000000000..f5f60c8fd3 --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp @@ -0,0 +1,650 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + + + +#include <qapplication.h> +#include <qpainter.h> +#include <qstyleoption.h> +#include <qkeysequence.h> +#include <qevent.h> +#include <qgridlayout.h> + + + +#include <qabstractbutton.h> + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QAbstractButton : public QObject +{ + Q_OBJECT + +public: + tst_QAbstractButton(); + virtual ~tst_QAbstractButton(); + + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void setAutoRepeat_data(); + void setAutoRepeat(); + + void pressed(); + void released(); + void setText(); + void setIcon(); + + void setShortcut(); + + void animateClick(); + + void isCheckable(); + void setDown(); + void isChecked(); + void toggled(); + void setEnabled(); + void shortcutEvents(); + void stopRepeatTimer(); + + void keyNavigation(); + +protected slots: + void onClicked(); + void onToggled( bool on ); + void onPressed(); + void onReleased(); + void resetValues(); + +private: + uint click_count; + uint toggle_count; + uint press_count; + uint release_count; + + QAbstractButton *testWidget; +}; + +// QAbstractButton is an abstract class in 4.0 +class MyButton : public QAbstractButton +{ +public: + MyButton(QWidget *p = 0) : QAbstractButton(p) {} + void paintEvent(QPaintEvent *) + { + QPainter p(this); + QRect r = rect(); + p.fillRect(r, isDown() ? Qt::black : (isChecked() ? Qt::lightGray : Qt::white)); + p.setPen(isDown() ? Qt::white : Qt::black); + p.drawRect(r); + p.drawText(r, Qt::AlignCenter | Qt::TextShowMnemonic, text()); + if (hasFocus()) { + r.adjust(2, 2, -2, -2); + QStyleOptionFocusRect opt; + opt.rect = r; + opt.palette = palette(); + opt.state = QStyle::State_None; + style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &p, this); +#ifdef Q_WS_MAC + p.setPen(Qt::red); + p.drawRect(r); +#endif + } + } + QSize sizeHint() const + { + QSize sh(8, 8); + if (!text().isEmpty()) + sh += fontMetrics().boundingRect(text()).size(); + return sh; + } + + void resetTimerEvents() { timerEvents = 0; } + int timerEventCount() const { return timerEvents; } + +private: + + int timerEvents; + + void timerEvent(QTimerEvent *event) + { + ++timerEvents; + QAbstractButton::timerEvent(event); + } +}; + +tst_QAbstractButton::tst_QAbstractButton() +{ +} + +tst_QAbstractButton::~tst_QAbstractButton() +{ +} + +void tst_QAbstractButton::initTestCase() +{ + testWidget = new MyButton(0); + testWidget->setObjectName("testObject"); + testWidget->resize( 200, 200 ); + testWidget->show(); + + connect( testWidget, SIGNAL(clicked()), this, SLOT(onClicked()) ); + connect( testWidget, SIGNAL(pressed()), this, SLOT(onPressed()) ); + connect( testWidget, SIGNAL(released()), this, SLOT(onReleased()) ); + connect( testWidget, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)) ); +} + +void tst_QAbstractButton::cleanupTestCase() +{ + delete testWidget; +} + +void tst_QAbstractButton::init() +{ + testWidget->setText("Test"); + testWidget->setEnabled( TRUE ); + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QKeySequence seq; + testWidget->setShortcut( seq ); + + toggle_count = 0; + press_count = 0; + release_count = 0; + click_count = 0; +} + +void tst_QAbstractButton::cleanup() +{ +} + +void tst_QAbstractButton::resetValues() +{ + toggle_count = 0; + press_count = 0; + release_count = 0; + click_count = 0; +} + +void tst_QAbstractButton::onClicked() +{ + click_count++; +} + +void tst_QAbstractButton::onToggled( bool /*on*/ ) +{ + toggle_count++; +} + +void tst_QAbstractButton::onPressed() +{ + press_count++; +} + +void tst_QAbstractButton::onReleased() +{ + release_count++; +} + +void tst_QAbstractButton::setAutoRepeat_data() +{ + QTest::addColumn<int>("mode"); + QTest::newRow( "" ) << 0; + QTest::newRow( "" ) << 1; + QTest::newRow( "" ) << 2; + QTest::newRow( "" ) << 3; + QTest::newRow( "" ) << 4; + QTest::newRow( "" ) << 5; + QTest::newRow( "" ) << 6; +} + +#define REPEAT_DELAY 1000 + +int test_count = 0; +int last_mode = 0; + +void tst_QAbstractButton::setAutoRepeat() +{ + QFETCH( int, mode ); + + //FIXME: temp code to check that the test fails consistenly + //retest( 3 ); + + switch (mode) + { + case 0: + QVERIFY( !testWidget->isCheckable() ); + break; + case 1: + // check if we can toggle the mode + testWidget->setAutoRepeat( TRUE ); + QVERIFY( testWidget->autoRepeat() ); + + testWidget->setAutoRepeat( FALSE ); + QVERIFY( !testWidget->autoRepeat() ); + break; + case 2: + // check that the button is down if we press space and not in autorepeat + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QTest::keyPress( testWidget, Qt::Key_Space ); + + QTest::qWait( REPEAT_DELAY ); + + QVERIFY( release_count == 0 ); + QVERIFY( testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 1 ); + QVERIFY( click_count == 0 ); + + QTest::keyRelease( testWidget, Qt::Key_Space ); + QVERIFY( click_count == 1 ); + QVERIFY( release_count == 1 ); + break; + case 3: + // check that the button is down if we press space while in autorepeat + testWidget->setDown(false); + testWidget->setAutoRepeat(true); + QTest::keyPress(testWidget, Qt::Key_Space); + QTest::qWait(REPEAT_DELAY); + QVERIFY(testWidget->isDown()); + QTest::keyRelease(testWidget, Qt::Key_Space); + QVERIFY(release_count == press_count); + QVERIFY(toggle_count == 0); + QVERIFY(press_count == click_count); + QVERIFY(click_count > 1); + break; + case 4: + // check that pressing ENTER has no effect when autorepeat is FALSE + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QTest::keyPress( testWidget, Qt::Key_Enter ); + + QTest::qWait( REPEAT_DELAY ); + + QVERIFY( !testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 0 ); + QVERIFY( release_count == 0 ); + QVERIFY( click_count == 0 ); + QTest::keyRelease( testWidget, Qt::Key_Enter ); + + QVERIFY( click_count == 0 ); + break; + case 5: + // check that pressing ENTER has no effect when autorepeat is TRUE + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( TRUE ); + QTest::keyPress( testWidget, Qt::Key_Enter ); + + QTest::qWait( REPEAT_DELAY ); + + QVERIFY( !testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 0 ); + QVERIFY( release_count == 0 ); + QVERIFY( click_count == 0 ); + + QTest::keyRelease( testWidget, Qt::Key_Enter ); + + QVERIFY( click_count == 0 ); + break; + case 6: + // verify autorepeat is off by default. + MyButton tmp( 0); + tmp.setObjectName("tmp" ); + QVERIFY( !tmp.autoRepeat() ); + break; + } +} + +void tst_QAbstractButton::pressed() +{ + // pressed/released signals expected for a QAbstractButton + QTest::keyPress( testWidget, ' ' ); + QCOMPARE( press_count, (uint)1 ); +} + +void tst_QAbstractButton::released() +{ + // pressed/released signals expected for a QAbstractButton + QTest::keyPress( testWidget, ' ' ); + QTest::keyRelease( testWidget, ' ' ); + QCOMPARE( release_count, (uint)1 ); +} + +void tst_QAbstractButton::setText() +{ + testWidget->setText(""); + QCOMPARE( testWidget->text(), QString("") ); + testWidget->setText("simple"); + QCOMPARE( testWidget->text(), QString("simple") ); + testWidget->setText("&ersand"); + QCOMPARE( testWidget->text(), QString("&ersand") ); +#ifndef Q_WS_MAC // no mneonics on Mac. + QCOMPARE( testWidget->shortcut(), QKeySequence("ALT+A")); +#endif + testWidget->setText("te&st"); + QCOMPARE( testWidget->text(), QString("te&st") ); +#ifndef Q_WS_MAC // no mneonics on Mac. + QCOMPARE( testWidget->shortcut(), QKeySequence("ALT+S")); +#endif + testWidget->setText("foo"); + QCOMPARE( testWidget->text(), QString("foo") ); +#ifndef Q_WS_MAC // no mneonics on Mac. + QCOMPARE( testWidget->shortcut(), QKeySequence()); +#endif +} + +void tst_QAbstractButton::setIcon() +{ + const char *test1_xpm[] = { + "12 8 2 1", + ". c None", + "c c #ff0000", + ".........ccc", + "........ccc.", + ".......ccc..", + "ccc...ccc...", + ".ccc.ccc....", + "..ccccc.....", + "...ccc......", + "....c.......", + }; + + QPixmap p(test1_xpm); + testWidget->setIcon( p ); + QCOMPARE( testWidget->icon().pixmap(12, 8), p ); + + // Test for #14793 + + const char *test2_xpm[] = { + "12 8 2 1", + ". c None", + "c c #ff0000", + "ccc......ccc", + ".ccc....ccc.", + "..ccc..ccc..", + "....cc.cc...", + ".....ccc....", + "....cc.cc...", + "...ccc.ccc..", + "..ccc...ccc.", + }; + + int currentHeight = testWidget->height(); + int currentWidth = testWidget->width(); + + QPixmap p2( test2_xpm ); + for ( int a = 0; a<5; a++ ) + testWidget->setIcon( p2 ); + + QCOMPARE( testWidget->icon().pixmap(12, 8), p2 ); + + QCOMPARE( testWidget->height(), currentHeight ); + QCOMPARE( testWidget->width(), currentWidth ); +} + +void tst_QAbstractButton::setEnabled() +{ + testWidget->setEnabled( FALSE ); + QVERIFY( !testWidget->isEnabled() ); +// QTEST( testWidget, "disabled" ); + + testWidget->setEnabled( TRUE ); + QVERIFY( testWidget->isEnabled() ); +// QTEST( testWidget, "enabled" ); +} + +void tst_QAbstractButton::isCheckable() +{ + QVERIFY( !testWidget->isCheckable() ); +} + +void tst_QAbstractButton::setDown() +{ + testWidget->setDown( FALSE ); + QVERIFY( !testWidget->isDown() ); + + testWidget->setDown( TRUE ); + QTest::qWait(300); + QVERIFY( testWidget->isDown() ); + + testWidget->setDown( TRUE ); + + // add some debugging stuff + QWidget *grab = QWidget::keyboardGrabber(); + if (grab != 0 && grab != testWidget) + qDebug( "testWidget != keyboardGrabber" ); + grab = qApp->focusWidget(); + if (grab != 0 && grab != testWidget) + qDebug( "testWidget != focusWidget" ); + + QTest::keyClick( testWidget, Qt::Key_Escape ); + QVERIFY( !testWidget->isDown() ); +} + +void tst_QAbstractButton::isChecked() +{ + testWidget->setDown( FALSE ); + QVERIFY( !testWidget->isChecked() ); + + testWidget->setDown( TRUE ); + QVERIFY( !testWidget->isChecked() ); + + testWidget->setDown( FALSE ); + testWidget->toggle(); + QVERIFY( testWidget->isChecked() == testWidget->isCheckable() ); +} + +void tst_QAbstractButton::toggled() +{ + testWidget->toggle(); + QVERIFY( toggle_count == 0 ); + + QTest::mousePress( testWidget, Qt::LeftButton ); + QVERIFY( toggle_count == 0 ); + QVERIFY( click_count == 0 ); + + QTest::mouseRelease( testWidget, Qt::LeftButton ); + QVERIFY( click_count == 1 ); +} + +void tst_QAbstractButton::setShortcut() +{ + QKeySequence seq( Qt::Key_A ); + testWidget->setShortcut( seq ); + QApplication::setActiveWindow(testWidget); + + // must be active to get shortcuts + for (int i = 0; !testWidget->isActiveWindow() && i < 100; ++i) { + testWidget->activateWindow(); + QApplication::instance()->processEvents(); + QTest::qWait(100); + } + QVERIFY(testWidget->isActiveWindow()); + + QTest::keyClick( testWidget, 'A' ); + QTest::qWait(300); // Animate click takes time + QCOMPARE(click_count, (uint)1); + QCOMPARE(press_count, (uint)1); // Press is part of a click + QCOMPARE(release_count,(uint)1); // Release is part of a click + + QVERIFY( toggle_count == 0 ); + +// resetValues(); +// QTest::keyPress( testWidget, 'A' ); +// QTest::qWait(10000); +// QTest::keyRelease( testWidget, 'A' ); +// QCOMPARE(click_count, (uint)1); +// QCOMPARE(press_count, (uint)1); +// QCOMPARE(release_count,(uint)1); + +// qDebug() << click_count; + +} + +void tst_QAbstractButton::animateClick() +{ + testWidget->animateClick(); + QVERIFY( testWidget->isDown() ); + qApp->processEvents(); + QVERIFY( testWidget->isDown() ); + QTest::qWait(200); + qApp->processEvents(); + QVERIFY( !testWidget->isDown() ); +} + +void tst_QAbstractButton::shortcutEvents() +{ + MyButton button; + QSignalSpy pressedSpy(&button, SIGNAL(pressed())); + QSignalSpy releasedSpy(&button, SIGNAL(released())); + QSignalSpy clickedSpy(&button, SIGNAL(clicked(bool))); + + for (int i = 0; i < 4; ++i) { + QKeySequence sequence; + QShortcutEvent event(sequence, false); + QApplication::sendEvent(&button, &event); + if (i < 2) + QTest::qWait(500); + } + + QTest::qWait(1000); // ensure animate timer is expired + + QCOMPARE(pressedSpy.count(), 3); + QCOMPARE(releasedSpy.count(), 3); + QCOMPARE(clickedSpy.count(), 3); +} + +void tst_QAbstractButton::stopRepeatTimer() +{ + MyButton button; + button.setAutoRepeat(true); + + // Mouse trigger case: + button.resetTimerEvents(); + QTest::mousePress(&button, Qt::LeftButton); + QTest::qWait(1000); + QVERIFY(button.timerEventCount() > 0); + + QTest::mouseRelease(&button, Qt::LeftButton); + button.resetTimerEvents(); + QTest::qWait(1000); + QCOMPARE(button.timerEventCount(), 0); + + // Key trigger case: + button.resetTimerEvents(); + QTest::keyPress(&button, Qt::Key_Space); + QTest::qWait(1000); + QVERIFY(button.timerEventCount() > 0); + + QTest::keyRelease(&button, Qt::Key_Space); + button.resetTimerEvents(); + QTest::qWait(1000); + QCOMPARE(button.timerEventCount(), 0); +} + +void tst_QAbstractButton::keyNavigation() +{ + QSKIP("Key navigation in QAbstractButton will be fixed/improved as part of task 194373", SkipSingle); + + QWidget widget; + QGridLayout *layout = new QGridLayout(&widget); + QAbstractButton *buttons[3][3]; + for(int y = 0; y < 3; y++) { + for(int x = 0; x < 3; x++) { + buttons[y][x] = new MyButton(&widget); + buttons[y][x]->setFocusPolicy(Qt::StrongFocus); + layout->addWidget(buttons[y][x], y, x); + } + } + + widget.show(); + qApp->setActiveWindow(&widget); + widget.activateWindow(); + QTest::qWait(30); + + buttons[1][1]->setFocus(); + QTest::qWait(400); + QVERIFY(buttons[1][1]->hasFocus()); + QTest::keyPress(buttons[1][1], Qt::Key_Up); + QTest::qWait(100); + QVERIFY(buttons[0][1]->hasFocus()); + QTest::keyPress(buttons[0][1], Qt::Key_Down); + QTest::qWait(100); + QVERIFY(buttons[1][1]->hasFocus()); + QTest::keyPress(buttons[1][1], Qt::Key_Left); + QTest::qWait(100); + QVERIFY(buttons[1][0]->hasFocus()); + QTest::keyPress(buttons[1][0], Qt::Key_Down); + QTest::qWait(100); + QVERIFY(buttons[2][0]->hasFocus()); + QTest::keyPress(buttons[2][0], Qt::Key_Right); + QTest::qWait(100); + QVERIFY(buttons[2][1]->hasFocus()); + QTest::keyPress(buttons[2][1], Qt::Key_Right); + QTest::qWait(100); + QVERIFY(buttons[2][2]->hasFocus()); + QTest::keyPress(buttons[2][2], Qt::Key_Up); + QTest::qWait(100); + QVERIFY(buttons[1][2]->hasFocus()); + QTest::keyPress(buttons[1][2], Qt::Key_Up); + QTest::qWait(100); + QVERIFY(buttons[0][2]->hasFocus()); + buttons[0][1]->hide(); + QTest::keyPress(buttons[0][2], Qt::Key_Left); + QTest::qWait(100); + QVERIFY(buttons[0][0]->hasFocus()); + + +} + +QTEST_MAIN(tst_QAbstractButton) +#include "tst_qabstractbutton.moc" diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/.gitignore b/tests/auto/widgets/widgets/qabstractscrollarea/.gitignore new file mode 100644 index 0000000000..ab753b8a0a --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractscrollarea/.gitignore @@ -0,0 +1 @@ +tst_qabstractscrollarea diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/qabstractscrollarea.pro b/tests/auto/widgets/widgets/qabstractscrollarea/qabstractscrollarea.pro new file mode 100644 index 0000000000..e4bc3f6495 --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractscrollarea/qabstractscrollarea.pro @@ -0,0 +1,9 @@ +############################################################ +# Project file for autotest for file qabstractscrollarea.h +############################################################ + +load(qttest_p4) +QT += widgets +SOURCES += tst_qabstractscrollarea.cpp + + diff --git a/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp new file mode 100644 index 0000000000..5c9a33cdc6 --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractscrollarea/tst_qabstractscrollarea.cpp @@ -0,0 +1,390 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <qcoreapplication.h> +#include <qdebug.h> +#include <qabstractscrollarea.h> +#include <qscrollarea.h> +#include <qscrollbar.h> +#include <qlabel.h> +#include <qwidget.h> +#include <qdialog.h> + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QAbstractScrollArea : public QObject +{ +Q_OBJECT + +public: + tst_QAbstractScrollArea(); + virtual ~tst_QAbstractScrollArea(); +private slots: + void scrollBarWidgets(); + void setScrollBars(); + void setScrollBars2(); + void objectNaming(); + void patternBackground(); + + void viewportCrash(); + void task214488_layoutDirection_data(); + void task214488_layoutDirection(); +}; + +tst_QAbstractScrollArea::tst_QAbstractScrollArea() +{ +} + +tst_QAbstractScrollArea::~tst_QAbstractScrollArea() +{ +} + +void tst_QAbstractScrollArea::scrollBarWidgets() +{ + QWidget *w1 = new QWidget(0); + QWidget *w2 = new QWidget(0); + QWidget *w3 = new QWidget(0); + + Qt::Alignment all = Qt::AlignLeft | Qt::AlignRight | Qt::AlignTop | Qt::AlignBottom; + + QWidgetList w1List = QWidgetList() << w1; + QWidgetList w2List = QWidgetList() << w2; + QWidgetList w3List = QWidgetList() << w3; + + QWidgetList w1w2List = w1List + w2List; + QWidgetList allList = w1List + w2List + w3List; + + QAbstractScrollArea area; + area.show(); + QCOMPARE(area.scrollBarWidgets(all), QWidgetList()); + + area.addScrollBarWidget(w1, Qt::AlignLeft); + QCOMPARE(area.scrollBarWidgets(all), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignLeft), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignRight), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignTop), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignBottom), QWidgetList()); + + area.addScrollBarWidget(w2, Qt::AlignBottom); + QCOMPARE(area.scrollBarWidgets(all), w1w2List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignLeft), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignRight), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignTop), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignBottom), w2List); + + // duplicate add + area.addScrollBarWidget(w2, Qt::AlignBottom); + QCOMPARE(area.scrollBarWidgets(all), w1w2List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignLeft), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignRight), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignTop), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignBottom), w2List); + + //reparent + w2->setParent(w1); + QCOMPARE(area.scrollBarWidgets(all), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignLeft), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignRight), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignTop), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignBottom), QWidgetList()); + + // add after reparent + area.addScrollBarWidget(w2, Qt::AlignBottom); + QCOMPARE(area.scrollBarWidgets(all), w1w2List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignLeft), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignRight), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignTop), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignBottom), w2List); + + // two widgets at Bottom. + area.addScrollBarWidget(w3, Qt::AlignBottom); + QCOMPARE(area.scrollBarWidgets(all).toSet(), allList.toSet()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignLeft), w1List); + QCOMPARE(area.scrollBarWidgets(Qt::AlignRight), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignTop), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignBottom).toSet(), (w2List + w3List).toSet()); + + //delete + delete w1; + delete w2; + delete w3; + + QCOMPARE(area.scrollBarWidgets(all), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignLeft), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignRight), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignTop), QWidgetList()); + QCOMPARE(area.scrollBarWidgets(Qt::AlignBottom), QWidgetList()); +} + +void tst_QAbstractScrollArea::setScrollBars() +{ + QScrollArea scrollArea; + scrollArea.resize(300, 300); + scrollArea.show(); + + QPointer<QScrollBar> vbar = scrollArea.verticalScrollBar(); + QPointer<QScrollBar> hbar = scrollArea.horizontalScrollBar(); + + // Now set properties on the scroll bars + scrollArea.verticalScrollBar()->setInvertedAppearance(true); + scrollArea.verticalScrollBar()->setInvertedControls(true); + scrollArea.verticalScrollBar()->setTracking(true); + scrollArea.verticalScrollBar()->setRange(-100, 100); + scrollArea.verticalScrollBar()->setPageStep(42); + scrollArea.verticalScrollBar()->setSingleStep(3); + scrollArea.verticalScrollBar()->setValue(43); + scrollArea.horizontalScrollBar()->setInvertedAppearance(true); + scrollArea.horizontalScrollBar()->setInvertedControls(true); + scrollArea.horizontalScrollBar()->setTracking(true); + scrollArea.horizontalScrollBar()->setRange(-100, 100); + scrollArea.horizontalScrollBar()->setPageStep(42); + scrollArea.horizontalScrollBar()->setSingleStep(3); + scrollArea.horizontalScrollBar()->setValue(43); + + qApp->processEvents(); + + // Then replace the scroll bars + scrollArea.setVerticalScrollBar(new QScrollBar); + scrollArea.setHorizontalScrollBar(new QScrollBar); + + // Check that the old ones were deleted + QVERIFY(!vbar); + QVERIFY(!hbar); + + qApp->processEvents(); + + // Check that all properties have been populated + QVERIFY(scrollArea.verticalScrollBar()->invertedAppearance()); + QVERIFY(scrollArea.verticalScrollBar()->invertedControls()); + QVERIFY(scrollArea.verticalScrollBar()->hasTracking()); + QVERIFY(scrollArea.verticalScrollBar()->isVisible()); + QCOMPARE(scrollArea.verticalScrollBar()->minimum(), -100); + QCOMPARE(scrollArea.verticalScrollBar()->maximum(), 100); + QCOMPARE(scrollArea.verticalScrollBar()->pageStep(), 42); + QCOMPARE(scrollArea.verticalScrollBar()->singleStep(), 3); + QCOMPARE(scrollArea.verticalScrollBar()->value(), 43); + QVERIFY(scrollArea.horizontalScrollBar()->invertedAppearance()); + QVERIFY(scrollArea.horizontalScrollBar()->invertedControls()); + QVERIFY(scrollArea.horizontalScrollBar()->hasTracking()); + QVERIFY(scrollArea.horizontalScrollBar()->isVisible()); + QCOMPARE(scrollArea.horizontalScrollBar()->minimum(), -100); + QCOMPARE(scrollArea.horizontalScrollBar()->maximum(), 100); + QCOMPARE(scrollArea.horizontalScrollBar()->pageStep(), 42); + QCOMPARE(scrollArea.horizontalScrollBar()->singleStep(), 3); + QCOMPARE(scrollArea.horizontalScrollBar()->value(), 43); +} + +void tst_QAbstractScrollArea::setScrollBars2() +{ + QAbstractScrollArea scrollArea; + scrollArea.resize(300, 300); + + QScrollBar *hbar = new QScrollBar; + scrollArea.setHorizontalScrollBar(hbar); + qApp->processEvents(); + QCOMPARE(scrollArea.horizontalScrollBar(), hbar); + + QScrollBar *vbar = new QScrollBar; + scrollArea.setVerticalScrollBar(vbar); + qApp->processEvents(); + QCOMPARE(scrollArea.verticalScrollBar(), vbar); + + scrollArea.horizontalScrollBar()->setRange(0, 100); + scrollArea.verticalScrollBar()->setRange(0, 100); + scrollArea.show(); + + // Make sure scroll bars are not explicitly hidden by QAbstractScrollArea itself. + QVERIFY(hbar->isVisible()); + QVERIFY(vbar->isVisible()); + + // Hide the OLD scroll bar and ensure that the NEW one is hidden. + hbar->hide(); + scrollArea.setHorizontalScrollBar(new QScrollBar); + qApp->processEvents(); + QVERIFY(!scrollArea.horizontalScrollBar()->isVisible()); + + vbar->hide(); + scrollArea.setVerticalScrollBar(new QScrollBar); + qApp->processEvents(); + QVERIFY(!scrollArea.verticalScrollBar()->isVisible()); + + scrollArea.verticalScrollBar()->show(); + scrollArea.horizontalScrollBar()->show(); + + // Hide the NEW scroll bar and ensure that it's visible + // (because the OLD one is visible). + hbar = new QScrollBar; + hbar->hide(); + scrollArea.setHorizontalScrollBar(hbar); + qApp->processEvents(); + QVERIFY(hbar->isVisible()); + + vbar = new QScrollBar; + vbar->hide(); + scrollArea.setVerticalScrollBar(vbar); + qApp->processEvents(); + QVERIFY(vbar->isVisible()); + + vbar->setRange(0, 0); + qApp->processEvents(); + QVERIFY(!vbar->isVisible()); + + hbar->setRange(0, 0); + qApp->processEvents(); + QVERIFY(!hbar->isVisible()); +} + +// we need to make sure the viewport internal widget is named +// qt_scrollarea_viewport, otherwise we're going to confuse Squish +// and friends. +void tst_QAbstractScrollArea::objectNaming() +{ + QScrollArea area; + QCOMPARE(area.viewport()->objectName(), QString("qt_scrollarea_viewport")); +} + +class ViewportCrashWidget : public QDialog +{ +public: + ViewportCrashWidget() + { + // temprorary set PaintOnScreen to set the nativeChildrenForced flag. + setAttribute(Qt::WA_PaintOnScreen, true); + setAttribute(Qt::WA_PaintOnScreen, false); + + setAttribute(Qt::WA_DropSiteRegistered, true); + + startTimer(2000); + } + + void timerEvent(QTimerEvent * /* event */) + { + // should not crash. + (void)new QScrollArea(this); + accept(); + } +}; + +void tst_QAbstractScrollArea::viewportCrash() +{ + ViewportCrashWidget w; + // should not crash + w.exec(); +} + +Q_DECLARE_METATYPE(Qt::LayoutDirection); +Q_DECLARE_METATYPE(Qt::Key); + +void tst_QAbstractScrollArea::task214488_layoutDirection_data() +{ + QTest::addColumn<Qt::LayoutDirection>("dir"); + QTest::addColumn<Qt::Key>("key"); + QTest::addColumn<bool>("lessThan"); + + QTest::newRow("LTR left") << Qt::LeftToRight << Qt::Key_Left << true; + QTest::newRow("LTR right") << Qt::LeftToRight << Qt::Key_Right << false; + QTest::newRow("RTL left") << Qt::RightToLeft << Qt::Key_Left << false; + QTest::newRow("RTL right") << Qt::RightToLeft << Qt::Key_Right << true; +} + +void tst_QAbstractScrollArea::task214488_layoutDirection() +{ + QScrollArea scrollArea; + scrollArea.resize(200, 200); + QWidget widget; + widget.resize(600, 600); + scrollArea.setWidget(&widget); + scrollArea.show(); + QScrollBar *hbar = scrollArea.horizontalScrollBar(); + hbar->setValue((hbar->minimum() + hbar->maximum()) / 2); + + QFETCH(Qt::LayoutDirection, dir); + QFETCH(Qt::Key, key); + QFETCH(bool, lessThan); + + scrollArea.setLayoutDirection(dir); + + int refValue = hbar->value(); + qApp->sendEvent(&scrollArea, new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier)); + QVERIFY(lessThan ? (hbar->value() < refValue) : (hbar->value() > refValue)); +} + +void tst_QAbstractScrollArea::patternBackground() +{ + QWidget topLevel; + QScrollArea scrollArea(&topLevel); + scrollArea.resize(200, 200); + QWidget widget; + widget.resize(600, 600); + scrollArea.setWidget(&widget); + topLevel.show(); + + QLinearGradient linearGrad(QPointF(250, 250), QPointF(300, 300)); + linearGrad.setColorAt(0, Qt::yellow); + linearGrad.setColorAt(1, Qt::red); + QBrush bg(linearGrad); + scrollArea.viewport()->setPalette(QPalette(Qt::black, bg, bg, bg, bg, bg, bg, bg, bg)); + widget.setPalette(Qt::transparent); + + QTest::qWait(50); + + QImage image(200, 200, QImage::Format_ARGB32); + scrollArea.render(&image); + + QCOMPARE(image.pixel(QPoint(20,20)) , QColor(Qt::yellow).rgb()); + + QScrollBar *hbar = scrollArea.horizontalScrollBar(); + hbar->setValue(hbar->maximum()); + QScrollBar *vbar = scrollArea.verticalScrollBar(); + vbar->setValue(vbar->maximum()); + + QTest::qWait(50); + + scrollArea.render(&image); + QCOMPARE(image.pixel(QPoint(20,20)) , QColor(Qt::red).rgb()); +} + +QTEST_MAIN(tst_QAbstractScrollArea) +#include "tst_qabstractscrollarea.moc" diff --git a/tests/auto/widgets/widgets/qabstractslider/.gitignore b/tests/auto/widgets/widgets/qabstractslider/.gitignore new file mode 100644 index 0000000000..cdbb891214 --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractslider/.gitignore @@ -0,0 +1 @@ +tst_qabstractslider diff --git a/tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro b/tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro new file mode 100644 index 0000000000..4507859ace --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractslider/qabstractslider.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qabstractslider.cpp + + diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp new file mode 100644 index 0000000000..e78844524e --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp @@ -0,0 +1,1247 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QAbstractSlider> +#include <QScrollBar> +#include <QSlider> +#include <QStyle> +#include <QStyleOption> +#include <QTime> +#include <QDebug> + +// defined to be 120 by the wheel mouse vendors according to the docs +#define WHEEL_DELTA 120 + +class Slider : public QAbstractSlider +{ + public: + Slider(QWidget *parent) + : QAbstractSlider(parent) {} + using QAbstractSlider::setRepeatAction; + using QAbstractSlider::repeatAction; +}; + +class tst_QAbstractSlider: public QObject +{ + Q_OBJECT +public slots: + void initTestCase(); + void cleanupTestCase(); + void actionTriggered(int action); + void rangeChanged(int min, int max); + void valueChanged(int value); + void sliderMoved(int value); + +private slots: + void triggerAction_data(); + void triggerAction(); + void minimum_maximum_data(); + void minimum_maximum(); + void keyPressed_data(); + void keyPressed(); + void wheelEvent_data(); + void wheelEvent(); + void sliderPressedReleased_data(); + void sliderPressedReleased(); + void setOrientation(); + void sliderMoved_data(); + void sliderMoved(); + void rangeChanged_data(); + void rangeChanged(); + void setSliderPosition_data(); + void setSliderPosition(); + void setValue_data(); + void setValue(); + void setRepeatAction(); + +private: + void waitUntilTimeElapsed(const QTime& t, int ms); + + QWidget *topLevel; + Slider *slider; + int previousAction; + int reportedMinimum; + int reportedMaximum; + int reportedValue; + int reportedSliderPosition; + qint64 timeStamp; + qint64 actionTriggeredTimeStamp; + qint64 valueChangedTimeStamp; + qint64 rangeChangedTimeStamp; + qint64 sliderMovedTimeStamp; +}; + +Q_DECLARE_METATYPE(QList<Qt::Key>) +Q_DECLARE_METATYPE(QPoint) + +void tst_QAbstractSlider::initTestCase() +{ + topLevel = new QWidget; + slider = new Slider(topLevel); + slider->setObjectName("testWidget"); + slider->resize(100,100); + slider->show(); + + previousAction = QAbstractSlider::SliderNoAction; + timeStamp = 0; + + connect(slider,SIGNAL(actionTriggered(int)),this,SLOT(actionTriggered(int))); + connect(slider,SIGNAL(rangeChanged(int,int)),this,SLOT(rangeChanged(int,int))); + connect(slider,SIGNAL(valueChanged(int)),this,SLOT(valueChanged(int))); + connect(slider,SIGNAL(sliderMoved(int)),this,SLOT(sliderMoved(int))); +} + +void tst_QAbstractSlider::cleanupTestCase() +{ + delete topLevel; +} + +void tst_QAbstractSlider::actionTriggered(int action) +{ + previousAction = action; + actionTriggeredTimeStamp = timeStamp++; +} + +void tst_QAbstractSlider::rangeChanged(int min,int max) +{ + reportedMinimum = min; + reportedMaximum = max; + rangeChangedTimeStamp = timeStamp++; +} + +void tst_QAbstractSlider::valueChanged(int value) +{ + reportedValue = value; + valueChangedTimeStamp = timeStamp++; +} + +void tst_QAbstractSlider::sliderMoved(int value) +{ + reportedSliderPosition = value; + sliderMovedTimeStamp = timeStamp++; +} + +void tst_QAbstractSlider::triggerAction_data() +{ + QTest::addColumn<int>("sliderAction"); + QTest::addColumn<int>("maximum"); + QTest::addColumn<int>("minimum"); + QTest::addColumn<int>("initialSliderPosition"); + QTest::addColumn<int>("singleStep"); + QTest::addColumn<int>("pageStep"); + QTest::addColumn<int>("expectedSliderPosition"); + + QTest::newRow("No action") << int(QAbstractSlider::SliderNoAction) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 237 // single step size + << 234 // page step size + << 987; // expected position after + + QTest::newRow("Move action") << int(QAbstractSlider::SliderMove) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 237 // single step size + << 234 // page step size + << 988; // expected position after + + QTest::newRow("Empty step add") << int(QAbstractSlider::SliderSingleStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 0 // single step size + << 234 // page step size + << 988; // expected position after + + QTest::newRow("Empty step sub") << int(QAbstractSlider::SliderSingleStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 0 // single step size + << 234 // page step size + << 987; // expected position after + + QTest::newRow("Empty page add") << int(QAbstractSlider::SliderPageStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 234 // single step size + << 0 // page step size + << 988; // expected position after + + QTest::newRow("Empty page sub") << int(QAbstractSlider::SliderPageStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 234 // single step size + << 0 // page step size + << 987; // expected position after + + QTest::newRow("Legal step add") << int(QAbstractSlider::SliderSingleStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 5 // single step size + << 234 // page step size + << 993; // expected position after + + QTest::newRow("Legal step sub") << int(QAbstractSlider::SliderSingleStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 5 // single step size + << 234 // page step size + << 982; // expected position after + + QTest::newRow("Legal page add") << int(QAbstractSlider::SliderPageStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 234 // single step size + << 5 // page step size + << 993; // expected position after + + QTest::newRow("Legal page sub") << int(QAbstractSlider::SliderPageStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 234 // single step size + << 5 // page step size + << 982; // expected position after + + QTest::newRow("Illegal step add") << int(QAbstractSlider::SliderSingleStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 500 // single step size + << 234 // page step size + << 1000; // expected position after + + QTest::newRow("Illegal step sub") << int(QAbstractSlider::SliderSingleStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 500 // single step size + << 234 // page step size + << 900; // expected position after + + QTest::newRow("Illegal page add") << int(QAbstractSlider::SliderPageStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 234 // single step size + << 500 // page step size + << 1000; // expected position after + + QTest::newRow("Illegal page sub") << int(QAbstractSlider::SliderPageStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 234 // single step size + << 500 // page step size + << 900; // expected position after + + // Negative steps will also be abs()'d so, check that case. + QTest::newRow("Negative step add") << int(QAbstractSlider::SliderSingleStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << -1 // single step size + << 234 // page step size + << 989; // expected position after + + QTest::newRow("Negative step sub") << int(QAbstractSlider::SliderSingleStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << -1 // single step size + << 234 // page step size + << 986; // expected position after + + QTest::newRow("Negative page add") << int(QAbstractSlider::SliderPageStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 234 // single step size + << -1 // page step size + << 989; // expected position after + + QTest::newRow("Negative page sub") << int(QAbstractSlider::SliderPageStepSub) // sliderAction + << 1000 // max + << 900 // min + << 987 // initial position + << 234 // single step size + << -1 // page step size + << 986; // expected position after + + QTest::newRow("Illegal negative step add") << int(QAbstractSlider::SliderSingleStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << -500 // single step size + << 234 // page step size + << 1000; // expected position after + + + QTest::newRow("Illegal negative step sub") << int(QAbstractSlider::SliderSingleStepSub) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << -500 // single step size + << 234 // page step size + << 900; // expected position after + + QTest::newRow("Illegal negative page add") << int(QAbstractSlider::SliderPageStepAdd) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 234 // single step size + << -500 // page step size + << 1000; // expected position after + + QTest::newRow("Illegal negative page sub") << int(QAbstractSlider::SliderPageStepSub) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 245 // single step size + << -500 // page step size + << 900; // expected position after + + QTest::newRow("Slider to minimum") << int(QAbstractSlider::SliderToMinimum) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 245 // single step size + << 1 // page step size + << 900; // expected position after + + QTest::newRow("Slider to maximum") << int(QAbstractSlider::SliderToMaximum) // sliderAction + << 1000 // max + << 900 // min + << 988 // initial position + << 245 // single step size + << 1 // page step size + << 1000; // expected position after + +} + +void tst_QAbstractSlider::triggerAction() +{ + QFETCH(int,sliderAction); + QFETCH(int,maximum); + QFETCH(int,minimum); + QFETCH(int,initialSliderPosition); + QFETCH(int,singleStep); + QFETCH(int,pageStep); + QFETCH(int,expectedSliderPosition); + + slider->setTracking(true); + slider->setRange(minimum,maximum); + slider->setSingleStep(singleStep); + slider->setPageStep(pageStep); + QCOMPARE(slider->singleStep(), qAbs(singleStep)); + QCOMPARE(slider->pageStep(), qAbs(pageStep)); + + int oldPosition = slider->sliderPosition(); + slider->setSliderPosition(initialSliderPosition); + + QVERIFY( (oldPosition == initialSliderPosition && previousAction == int(QAbstractSlider::SliderNoAction)) || + (oldPosition != initialSliderPosition && previousAction == int(QAbstractSlider::SliderMove))); + previousAction = int(QAbstractSlider::SliderNoAction); + + QAbstractSlider::SliderAction *action = reinterpret_cast<QAbstractSlider::SliderAction*>(&sliderAction); + QVERIFY(action != 0); + + slider->triggerAction(*action); + QCOMPARE(previousAction,sliderAction); // previousAction set in the actionTriggered() slot + QCOMPARE(slider->sliderPosition(),expectedSliderPosition); + QCOMPARE(slider->value(),expectedSliderPosition); + QCOMPARE(reportedValue,expectedSliderPosition); + previousAction = int(QAbstractSlider::SliderNoAction); + if (initialSliderPosition != expectedSliderPosition) + QVERIFY(actionTriggeredTimeStamp < valueChangedTimeStamp); +} + +void tst_QAbstractSlider::minimum_maximum_data() +{ + QTest::addColumn<int>("minimum"); + QTest::addColumn<int>("maximum"); + QTest::addColumn<int>("expectedMinimum"); + QTest::addColumn<int>("expectedMaximum"); + + QTest::newRow("Normal range") << 100 << 200 << 100 << 200; + QTest::newRow("Minimum higher") << 100 << 0 << 100 << 100; + QTest::newRow("Negative minimum") << -100 << 100 << -100 << 100; + QTest::newRow("Negative range") << -100 << -50 << -100 << -50; +} + +void tst_QAbstractSlider::minimum_maximum() +{ + QFETCH(int, minimum); + QFETCH(int, maximum); + QFETCH(int, expectedMinimum); + QFETCH(int, expectedMaximum); + + slider->setRange(minimum,maximum); + QCOMPARE(slider->minimum(),expectedMinimum); + QCOMPARE(slider->maximum(),expectedMaximum); + QCOMPARE(reportedMinimum,expectedMinimum); + QCOMPARE(reportedMaximum,expectedMaximum); + + slider->setRange(minimum,maximum); + slider->setMaximum(slider->minimum() - 1); + QCOMPARE(slider->maximum(),slider->minimum()); + QCOMPARE(reportedMinimum,slider->minimum()); + QCOMPARE(reportedMaximum,slider->maximum()); + + slider->setRange(minimum,maximum); + slider->setMinimum(slider->maximum() + 1); + QCOMPARE(slider->minimum(),slider->maximum()); + QCOMPARE(reportedMinimum,slider->minimum()); + QCOMPARE(reportedMaximum,slider->maximum()); + + slider->setRange(minimum,maximum); + slider->setSliderPosition(slider->maximum() + 1); + QCOMPARE(slider->sliderPosition(), slider->maximum()); + QCOMPARE(slider->value(), slider->maximum()); + QCOMPARE(reportedValue, slider->maximum()); + + slider->setRange(minimum,maximum); + slider->setSliderPosition(slider->minimum() - 1); + QCOMPARE(slider->sliderPosition(), slider->minimum()); + QCOMPARE(slider->value(), slider->minimum()); + QCOMPARE(reportedValue, slider->minimum()); + + slider->setRange(minimum,maximum); + int oldPosition = slider->sliderPosition(); + slider->setMaximum(oldPosition - 1); + QCOMPARE(slider->sliderPosition(),oldPosition - 1); + + slider->setRange(minimum,maximum); + oldPosition = slider->sliderPosition(); + slider->setMinimum(oldPosition + 1); + QCOMPARE(slider->sliderPosition(), oldPosition + 1); +} + +void tst_QAbstractSlider::keyPressed_data() +{ + QTest::addColumn<int>("initialSliderPosition"); + QTest::addColumn<int>("minimum"); + QTest::addColumn<int>("maximum"); + QTest::addColumn<int>("stepSize"); + QTest::addColumn<int>("pageSize"); + QTest::addColumn<QList<Qt::Key> >("keySequence"); + QTest::addColumn<int>("expectedSliderPositionHorizontal"); + QTest::addColumn<int>("expectedSliderPositionVertical"); + QTest::addColumn<int>("expectedSliderPositionHorizontalInverted"); // :) + QTest::addColumn<int>("expectedSliderPositionVerticalInverted"); + + + QList<Qt::Key> list; + + list << Qt::Key_Down; + QTest::newRow("Step down once") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << list // key sequence + << 7 // result in case of horizontal slider + << 7 // result in case of vertical slider + << 13 // result in case of inverted horiz. slider + << 13; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_Up; + QTest::newRow("Step down once") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << list // key sequence + << 13 // result in case of horizontal slider + << 13 // result in case of vertical slider + << 7 // result in case of inverted horiz. slider + << 7; // result in case of inverted vertical slider + + + list = QList<Qt::Key>(); + list << Qt::Key_Left; + QTest::newRow("Step left once") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << list // key sequence + << 7 // result in case of horizontal slider + << 7 // result in case of vertical slider + << 13 // result in case of inverted horiz. slider + << 13; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_Right; + QTest::newRow("Step right once") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << list // key sequence + << 13 // result in case of horizontal slider + << 13 // result in case of vertical slider + << 7 // result in case of inverted horiz. slider + << 7; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_PageDown; + QTest::newRow("Page down once") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << list // key sequence + << 7 // result in case of horizontal slider + << 7 // result in case of vertical slider + << 13 // result in case of inverted horiz. slider + << 13; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_PageUp; + QTest::newRow("Page up once") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << list // key sequence + << 13 // result in case of horizontal slider + << 13 // result in case of vertical slider + << 7 // result in case of inverted horiz. slider + << 7; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_Up << Qt::Key_Up << Qt::Key_PageDown << Qt::Key_PageDown << Qt::Key_Left << Qt::Key_Left + << Qt::Key_Right << Qt::Key_Down << Qt::Key_PageUp << Qt::Key_PageUp << Qt::Key_Down << Qt::Key_Right; + QTest::newRow("Symmetric seq") << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << list // key sequence + << 50 // result in case of horizontal slider + << 50 // result in case of vertical slider + << 50 // result in case of inverted horiz. slider + << 50; // result in case of inverted vertical slider + + + list = QList<Qt::Key>(); + list << Qt::Key_Home; + QTest::newRow("Home") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << list // key sequence + << 0 // result in case of horizontal slider + << 0 // result in case of vertical slider + << 0 // result in case of inverted horiz. slider + << 0; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_End; + QTest::newRow("End") << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << list // key sequence + << 100 // result in case of horizontal slider + << 100 // result in case of vertical slider + << 100 // result in case of inverted horiz. slider + << 100; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_End << Qt::Key_Up; + QTest::newRow("Past end")<< 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << list // key sequence + << 100 // result in case of horizontal slider + << 100 // result in case of vertical slider + << 97 // result in case of inverted horiz. slider + << 97; // result in case of inverted vertical slider + + list = QList<Qt::Key>(); + list << Qt::Key_Home << Qt::Key_Down; + QTest::newRow("Past home")<< 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << list // key sequence + << 0 // result in case of horizontal slider + << 0 // result in case of vertical slider + << 3 // result in case of inverted horiz. slider + << 3; // result in case of inverted vertical slider + +} + +void tst_QAbstractSlider::keyPressed() +{ + QFETCH(int, initialSliderPosition); + QFETCH(int, minimum); + QFETCH(int, maximum); + QFETCH(int, stepSize); + QFETCH(int, pageSize); + QFETCH(QList<Qt::Key>, keySequence); + QFETCH(int, expectedSliderPositionHorizontal); + QFETCH(int, expectedSliderPositionVertical); + QFETCH(int, expectedSliderPositionHorizontalInverted); + QFETCH(int, expectedSliderPositionVerticalInverted); + + // Horizontal non-inverted + slider->setRange(minimum,maximum); + slider->setSliderPosition(initialSliderPosition); + slider->setSingleStep(stepSize); + slider->setPageStep(pageSize); + slider->setOrientation(Qt::Horizontal); + slider->setInvertedAppearance(false); + slider->setInvertedControls(false); + for (int i=0;i<keySequence.count();i++) { + QTest::keyClick(slider, keySequence.at(i)); + } + QCOMPARE(slider->sliderPosition(), expectedSliderPositionHorizontal); + + // Horizontal inverted + slider->setRange(minimum,maximum); + slider->setSliderPosition(initialSliderPosition); + slider->setSingleStep(stepSize); + slider->setPageStep(pageSize); + slider->setOrientation(Qt::Horizontal); + slider->setInvertedAppearance(true); + slider->setInvertedControls(true); + for (int i=0;i<keySequence.count();i++) + QTest::keyPress(slider, keySequence.at(i)); + QCOMPARE(slider->sliderPosition(), expectedSliderPositionHorizontalInverted); + + // Vertical non-inverted + slider->setRange(minimum,maximum); + slider->setSliderPosition(initialSliderPosition); + slider->setSingleStep(stepSize); + slider->setPageStep(pageSize); + slider->setOrientation(Qt::Vertical); + slider->setInvertedAppearance(false); + slider->setInvertedControls(false); + for (int i=0;i<keySequence.count();i++) + QTest::keyPress(slider, keySequence.at(i)); + QCOMPARE(slider->sliderPosition(), expectedSliderPositionVertical); + + // Vertical inverted + slider->setRange(minimum,maximum); + slider->setSliderPosition(initialSliderPosition); + slider->setSingleStep(stepSize); + slider->setPageStep(pageSize); + slider->setOrientation(Qt::Vertical); + slider->setInvertedAppearance(true); + slider->setInvertedControls(true); + for (int i=0;i<keySequence.count();i++) + QTest::keyPress(slider, keySequence.at(i)); + QCOMPARE(slider->sliderPosition(), expectedSliderPositionVerticalInverted); +} + +void tst_QAbstractSlider::wheelEvent_data() +{ + QTest::addColumn<int>("initialSliderPosition"); + QTest::addColumn<int>("minimum"); + QTest::addColumn<int>("maximum"); + QTest::addColumn<int>("singleStep"); + QTest::addColumn<int>("pageStep"); + QTest::addColumn<bool>("invertedControls"); + QTest::addColumn<int>("wheelScrollLines"); + QTest::addColumn<bool>("withModifiers"); // use keyboard modifiers while scrolling? (CTRL and SHIFT) + QTest::addColumn<int>("deltaMultiple"); // multiples of WHEEL_DELTA + QTest::addColumn<int>("sliderOrientation"); + QTest::addColumn<int>("wheelOrientation"); + QTest::addColumn<int>("expectedSliderPosition"); + QTest::addColumn<QPoint>("distanceFromBottomRight"); // mpointer's distance from bottom-right corner of widget + + QTest::newRow("Normal data step") << 0 // initial position + << 0 // minimum + << 100 // maximum + << 1 // single step + << 100 // page step + << false // inverted controls + << 20 // wheel scroll lines + << false // with modifiers + << 1 // delta + << int(Qt::Vertical) // orientation of slider + << int(Qt::Vertical) // orientation of wheel + << 20 // expected position after + << QPoint(0,0); + + QTest::newRow("Normal data page") << 0 // initial position + << 0 // minimum + << 100 // maximum + << 100 // single step + << 1 // page step + << false // inverted controls + << 20 // wheel scroll lines + << false // with modifiers + << 1 // delta + << int(Qt::Vertical) // orientation of slider + << int(Qt::Vertical) // orientation of wheel +#ifndef Q_WS_MAC + << 1 // expected position after +#else + // We don't restrict scrolling to pageStep on Mac + << 100 // expected position after +#endif + << QPoint(1,1); + QTest::newRow("Different orientation") << 0 // initial position + << 0 // minimum + << 100 // maximum + << 100 // single step + << 1 // page step + << false // inverted controls + << 20 // wheel scroll lines + << false // with modifiers + << 1 // delta + << int(Qt::Horizontal) // orientation of slider + << int(Qt::Vertical) // orientation of wheel +#ifndef Q_WS_MAC + << 1 // expected position after +#else + // We don't restrict scrolling to pageStep on Mac + << 100 // expected position after +#endif + << QPoint(1,1); + + QTest::newRow("Different orientation2")<< 0 // initial position + << 0 // minimum + << 100 // maximum + << 100 // single step + << 1 // page step + << false // inverted controls + << 20 // wheel scroll lines + << false // with modifiers + << 1 // delta + << int(Qt::Horizontal) // orientation of slider + << int(Qt::Vertical) // orientation of wheel +#ifndef Q_WS_MAC + << 1 // expected position after +#else + // We don't restrict scrolling to pageStep on Mac + << 100 // expected position after +#endif + << QPoint(0,0); + + QTest::newRow("Inverted controls") << 50 // initial position + << 0 // minimum + << 100 // maximum + << 1 // single step + << 100 // page step + << true // inverted controls + << 20 // wheel scroll lines + << false // with modifiers + << -1 // delta + << int(Qt::Horizontal) // orientation of slider + << int(Qt::Horizontal) // orientation of wheel + << 30 // expected position after + << QPoint(1,1); + + QTest::newRow("Past end") << 50 // initial position + << 0 // minimum + << 100 // maximum + << 26 // single step + << 100 // page step + << false // inverted controls + << 1 // wheel scroll lines + << false // with modifiers + << -2 // delta + << int(Qt::Horizontal) // orientation of slider + << int(Qt::Horizontal) // orientation of wheel + << 100 // expected position after + << QPoint(0,0); + + QTest::newRow("Past start") << 50 // initial position + << 0 // minimum + << 100 // maximum + << 26 // single step + << 100 // page step + << false // inverted controls + << 1 // wheel scroll lines + << false // with modifiers + << 2 // delta + << int(Qt::Horizontal) // orientation of slider + << int(Qt::Horizontal) // orientation of wheel + << 0 // expected position after + << QPoint(0,0); + + QTest::newRow("With modifiers") << 50 // initial position + << 0 // minimum + << 100 // maximum + << 1 // single step + << 40 // page step + << false // inverted controls + << 20 // wheel scroll lines + << true // with modifiers + << -1 // delta + << int(Qt::Horizontal) // orientation of slider + << int(Qt::Horizontal) // orientation of wheel + << 90 // expected position after + << QPoint(0,0); + +} + +void tst_QAbstractSlider::wheelEvent() +{ + QFETCH(int,initialSliderPosition); + QFETCH(int,minimum); + QFETCH(int,maximum); + QFETCH(int,singleStep); + QFETCH(int,pageStep); + QFETCH(bool,invertedControls); + QFETCH(int,wheelScrollLines); + QFETCH(bool,withModifiers); + QFETCH(int,deltaMultiple); + QFETCH(int,sliderOrientation); + QFETCH(int,wheelOrientation); + QFETCH(int,expectedSliderPosition); + QFETCH(QPoint,distanceFromBottomRight); + + QCoreApplication *applicationInstance = QCoreApplication::instance(); + QVERIFY(applicationInstance != 0); + QApplication::setWheelScrollLines(wheelScrollLines); + + Qt::Orientation orientation = *reinterpret_cast<Qt::Orientation*>(&sliderOrientation); + slider->setRange(minimum,maximum); + slider->setSliderPosition(initialSliderPosition); + slider->setSingleStep(singleStep); + slider->setPageStep(pageStep); + slider->setInvertedControls(invertedControls); + slider->setOrientation(orientation); + + Qt::KeyboardModifier k = withModifiers ? Qt::ControlModifier : Qt::NoModifier; + orientation = *reinterpret_cast<Qt::Orientation*>(&wheelOrientation); + QWheelEvent event(slider->rect().bottomRight() + distanceFromBottomRight, WHEEL_DELTA * deltaMultiple, + Qt::NoButton, k, orientation); + QVERIFY(applicationInstance->sendEvent(slider,&event)); + QCOMPARE(slider->sliderPosition(),expectedSliderPosition); + + slider->setSliderPosition(initialSliderPosition); + k = withModifiers ? Qt::ShiftModifier : Qt::NoModifier; + event = QWheelEvent(slider->rect().bottomRight() + distanceFromBottomRight, WHEEL_DELTA * deltaMultiple, + Qt::NoButton, k, orientation); + QSignalSpy spy1(slider, SIGNAL(actionTriggered(int))); + QSignalSpy spy2(slider, SIGNAL(valueChanged(int))); + QVERIFY(applicationInstance->sendEvent(slider,&event)); + QCOMPARE(slider->sliderPosition(),expectedSliderPosition); + int expectedSignalCount = (initialSliderPosition == expectedSliderPosition) ? 0 : 1; + QCOMPARE(spy1.count(), expectedSignalCount); + QCOMPARE(spy2.count(), expectedSignalCount); + if (expectedSignalCount) + QVERIFY(actionTriggeredTimeStamp < valueChangedTimeStamp); +} + +void tst_QAbstractSlider::sliderPressedReleased_data() +{ + QTest::addColumn<int>("control"); + QTest::addColumn<int>("minimum"); + QTest::addColumn<int>("maximum"); + QTest::addColumn<uint>("subControl"); + QTest::addColumn<int>("expectedCount"); + + QTest::newRow("slider on the handle") << int(QStyle::CC_Slider) + << 0 + << 20 + << uint(QStyle::SC_SliderHandle) + << 1; + + QTest::newRow("slider on the groove") << int(QStyle::CC_Slider) + << 0 + << 20 + << uint(QStyle::SC_SliderGroove) + << ((qApp->style()->styleHint(QStyle::SH_Slider_AbsoluteSetButtons) & Qt::LeftButton) ? 1 : 0); + + QTest::newRow("scrollbar on the handle") << int(QStyle::CC_ScrollBar) + << 0 + << 20 + << uint(QStyle::SC_ScrollBarSlider) + << 1; + + QTest::newRow("scrollbar on the groove") << int(QStyle::CC_ScrollBar) + << 0 + << 20 + << uint(QStyle::SC_ScrollBarGroove) + << 0; +} + +void tst_QAbstractSlider::sliderPressedReleased() +{ + QFETCH(int, control); + QFETCH(int, minimum); + QFETCH(int, maximum); + QFETCH(uint, subControl); + QFETCH(int, expectedCount); + + QWidget topLevel; + QAbstractSlider *slider; + switch (control) { + default: + qWarning("Bad input into test, leaving"); + return; + break; + case QStyle::CC_Slider: + slider = new QSlider(&topLevel); + slider->setLayoutDirection(Qt::LeftToRight); // Makes "upside down" much easier to compute + break; + case QStyle::CC_ScrollBar: + slider = new QScrollBar(&topLevel); + break; + } + + + slider->setMinimum(minimum); + slider->setMaximum(maximum); + slider->setValue(0); + slider->setOrientation(Qt::Vertical); + slider->resize(slider->sizeHint().width(), slider->sizeHint().height() + 100); + QSignalSpy spy1(slider, SIGNAL(sliderPressed())); + QSignalSpy spy2(slider, SIGNAL(sliderReleased())); + + // Mac Style requires the control to be active to get the correct values... + topLevel.show(); + slider->activateWindow(); + + QStyleOptionSlider option; + option.init(slider); + option.upsideDown = control == QStyle::CC_Slider ? !slider->invertedAppearance() + : slider->invertedAppearance(); + option.subControls = QStyle::SC_None; + option.activeSubControls = QStyle::SC_None; + option.orientation = slider->orientation(); + option.maximum = maximum; + option.minimum = minimum; + option.sliderPosition = slider->value(); + option.sliderValue = slider->value(); + option.singleStep = slider->singleStep(); + option.pageStep = slider->pageStep(); + QRect rect = slider->style()->subControlRect(QStyle::ComplexControl(control), &option, + QStyle::SubControl(subControl), slider); + + QTest::mousePress(slider, Qt::LeftButton, 0, QPoint(rect.center().x() + 2, rect.center().y() + 2)); + QCOMPARE(spy1.count(), expectedCount); + QTest::mouseRelease(slider, Qt::LeftButton, 0, rect.center()); + QCOMPARE(spy2.count(), expectedCount); + + delete slider; +} + +void tst_QAbstractSlider::sliderMoved_data() +{ + QTest::addColumn<int>("control"); + QTest::addColumn<int>("minimum"); + QTest::addColumn<int>("maximum"); + QTest::addColumn<int>("position"); + QTest::addColumn<bool>("sliderDown"); + QTest::addColumn<int>("expectedCount"); + + QTest::newRow("slider pressed") << int(QStyle::CC_Slider) + << 0 + << 20 + << 10 + << true + << 1; + + QTest::newRow("slider not pressed") << int(QStyle::CC_Slider) + << 0 + << 20 + << 10 + << false + << 0; + + QTest::newRow("scrollbar pressed") << int(QStyle::CC_ScrollBar) + << 0 + << 20 + << 10 + << true + << 1; + + QTest::newRow("scrollbar not pressed") << int(QStyle::CC_ScrollBar) + << 0 + << 20 + << 10 + << false + << 0; +} + +void tst_QAbstractSlider::sliderMoved() +{ + QFETCH(int, control); + QFETCH(int, minimum); + QFETCH(int, maximum); + QFETCH(int, position); + QFETCH(bool, sliderDown); + QFETCH(int, expectedCount); + QAbstractSlider *slider; + switch (control) { + default: + slider = 0; + break; + case QStyle::CC_Slider: + slider = new QSlider; + break; + case QStyle::CC_ScrollBar: + slider = new QScrollBar; + break; + } + QSignalSpy spy(slider, SIGNAL(sliderMoved(int))); + + slider->setMinimum(minimum); + slider->setMaximum(maximum); + slider->setSliderDown(sliderDown); + slider->setSliderPosition(position); + QCOMPARE(spy.count(), expectedCount); + + delete slider; +} + +void tst_QAbstractSlider::setOrientation() +{ + QSlider slider(0); + + QSizePolicy sp = slider.sizePolicy(); + slider.setOrientation(slider.orientation()); + QSizePolicy sp2 = slider.sizePolicy(); + QCOMPARE(sp, sp2); + + slider.setOrientation(Qt::Horizontal); + sp = slider.sizePolicy(); + slider.setOrientation(Qt::Vertical); + sp2 = slider.sizePolicy(); + + QVERIFY(sp != sp2); + sp2.transpose(); + QCOMPARE(sp, sp2); +} + + +void tst_QAbstractSlider::rangeChanged_data() +{ + QTest::addColumn<int>("minimum"); + QTest::addColumn<int>("maximum"); + QTest::addColumn<int>("newMin"); + QTest::addColumn<int>("newMax"); + QTest::addColumn<int>("expectedCount"); + + QTest::newRow("no change") + << 0 + << 20 + << 0 + << 20 + << 0; + + QTest::newRow("min change") + << 0 + << 20 + << 10 + << 20 + << 1; + QTest::newRow("max change") + << 0 + << 20 + << 0 + << 30 + << 1; + + QTest::newRow("both change") + << 0 + << 20 + << 10 + << 30 + << 1; +} + +void tst_QAbstractSlider::rangeChanged() +{ + QFETCH(int, minimum); + QFETCH(int, maximum); + QFETCH(int, newMin); + QFETCH(int, newMax); + QFETCH(int, expectedCount); + QSlider slider; + slider.setRange(minimum, maximum); + QSignalSpy spy(&slider, SIGNAL(rangeChanged(int, int))); + slider.setRange(newMin, newMax); + QCOMPARE(spy.count(), expectedCount); +} + +void tst_QAbstractSlider::setSliderPosition_data() +{ + QTest::addColumn<bool>("tracking"); + QTest::addColumn<bool>("down"); + + QTest::newRow("tracking, slider down") + << true + << true; + QTest::newRow("tracking, slider not down") + << true + << false; + QTest::newRow("no tracking, slider down") + << false + << true; + QTest::newRow("no tracking, slider not down") + << false + << false; +} + +void tst_QAbstractSlider::setSliderPosition() +{ + QFETCH(bool, tracking); + QFETCH(bool, down); + const int minimum = 0; + const int maximum = 100; + const int initialValue = 50; + const int targetPosition = 75; + slider->setRange(minimum, maximum); + slider->setTracking(tracking); + slider->setSliderDown(down); + slider->setValue(initialValue); + QCOMPARE(slider->sliderPosition(), initialValue); + QSignalSpy spy1(slider, SIGNAL(sliderMoved(int))); + QSignalSpy spy2(slider, SIGNAL(valueChanged(int))); + slider->setSliderPosition(targetPosition); + QCOMPARE(slider->sliderPosition(), targetPosition); + QCOMPARE(spy1.count(), down ? 1 : 0); + QCOMPARE(spy2.count(), tracking ? 1 : 0); + QCOMPARE(slider->value(), tracking ? targetPosition : initialValue); + if (tracking && down) + QVERIFY(sliderMovedTimeStamp < valueChangedTimeStamp); +} + +void tst_QAbstractSlider::setValue_data() +{ + QTest::addColumn<bool>("down"); + + QTest::newRow("slider down") + << true; + QTest::newRow("slider not down") + << false; +} + +void tst_QAbstractSlider::setValue() +{ + QFETCH(bool, down); + const int minimum = 0; + const int maximum = 100; + slider->setRange(minimum, maximum); + slider->setSliderDown(down); + slider->setValue(49); // to force a valueChanged() below + QSignalSpy spy1(slider, SIGNAL(sliderMoved(int))); + QSignalSpy spy2(slider, SIGNAL(valueChanged(int))); + QSignalSpy spy3(slider, SIGNAL(actionTriggered(int))); + slider->setValue(50); + QCOMPARE(spy1.count(), down ? 1 : 0); + QCOMPARE(spy2.count(), 1); + QCOMPARE(spy3.count(), 0); + QCOMPARE(slider->value(), reportedValue); + QCOMPARE(slider->sliderPosition(), reportedSliderPosition); + if (down) + QVERIFY(sliderMovedTimeStamp < valueChangedTimeStamp); +} + +void tst_QAbstractSlider::waitUntilTimeElapsed(const QTime& t, int ms) +{ + const int eps = 80; + while (t.elapsed() < ms + eps) + QTest::qWait(qMax(ms - t.elapsed() + eps, 25)); +} + +void tst_QAbstractSlider::setRepeatAction() +{ + slider->setRange(0, 1000); + slider->setValue(55); + slider->setPageStep(10); + QSignalSpy spy(slider, SIGNAL(actionTriggered(int))); + + // Start repeat action with initial delay of 500 ms, and then repeating + // every 250 ms. + slider->setRepeatAction(QAbstractSlider::SliderPageStepAdd, 500, 250); + QCOMPARE(spy.count(), 0); + QCOMPARE(slider->value(), 55); + + QTime t; + t.start(); + QTest::qWait(300); + QCOMPARE(spy.count(), 0); + QCOMPARE(slider->value(), 55); + + waitUntilTimeElapsed(t, 550); + QCOMPARE(spy.count(), 1); + QCOMPARE(slider->value(), 65); + QCOMPARE(spy.at(0).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd); + + waitUntilTimeElapsed(t, 790); + QCOMPARE(spy.count(), 2); + QCOMPARE(slider->value(), 75); + QCOMPARE(spy.at(1).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd); + + waitUntilTimeElapsed(t, 1790); + QCOMPARE(spy.count(), 6); + QCOMPARE(slider->value(), 115); + QCOMPARE(spy.at(4).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd); + QCOMPARE(spy.at(5).at(0).toUInt(), (uint)QAbstractSlider::SliderPageStepAdd); + + slider->setRepeatAction(QAbstractSlider::SliderNoAction); + QCOMPARE(spy.count(), 6); + QCOMPARE(slider->value(), 115); + + QTest::qWait(300); + QCOMPARE(spy.count(), 6); + QCOMPARE(slider->value(), 115); +} + +QTEST_MAIN(tst_QAbstractSlider) +#include "tst_qabstractslider.moc" diff --git a/tests/auto/widgets/widgets/qabstractspinbox/.gitignore b/tests/auto/widgets/widgets/qabstractspinbox/.gitignore new file mode 100644 index 0000000000..07d1d652ee --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractspinbox/.gitignore @@ -0,0 +1 @@ +tst_qabstractspinbox diff --git a/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro new file mode 100644 index 0000000000..e156b2493d --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro @@ -0,0 +1,9 @@ +############################################################ +# Project file for autotest for file qabstractspinbox.h +############################################################ + +load(qttest_p4) +QT += widgets +SOURCES += tst_qabstractspinbox.cpp + + diff --git a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp new file mode 100644 index 0000000000..d14c75bbac --- /dev/null +++ b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <qcoreapplication.h> +#include <qdebug.h> +#include <qabstractspinbox.h> +#include <qlineedit.h> +#include <qspinbox.h> + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QAbstractSpinBox : public QObject +{ +Q_OBJECT + +public: + tst_QAbstractSpinBox(); + virtual ~tst_QAbstractSpinBox(); + +private slots: + void getSetCheck(); + + // task-specific tests below me: + void task183108_clear(); + void task228728_cssselector(); +}; + +tst_QAbstractSpinBox::tst_QAbstractSpinBox() +{ +} + +tst_QAbstractSpinBox::~tst_QAbstractSpinBox() +{ +} + +class MyAbstractSpinBox : public QAbstractSpinBox +{ +public: + MyAbstractSpinBox() : QAbstractSpinBox() {} + QLineEdit *lineEdit() { return QAbstractSpinBox::lineEdit(); } + void setLineEdit(QLineEdit *le) { QAbstractSpinBox::setLineEdit(le); } +}; + +// Testing get/set functions +void tst_QAbstractSpinBox::getSetCheck() +{ + MyAbstractSpinBox obj1; + // ButtonSymbols QAbstractSpinBox::buttonSymbols() + // void QAbstractSpinBox::setButtonSymbols(ButtonSymbols) + obj1.setButtonSymbols(QAbstractSpinBox::ButtonSymbols(QAbstractSpinBox::UpDownArrows)); + QCOMPARE(QAbstractSpinBox::ButtonSymbols(QAbstractSpinBox::UpDownArrows), obj1.buttonSymbols()); + obj1.setButtonSymbols(QAbstractSpinBox::ButtonSymbols(QAbstractSpinBox::PlusMinus)); + QCOMPARE(QAbstractSpinBox::ButtonSymbols(QAbstractSpinBox::PlusMinus), obj1.buttonSymbols()); + + // bool QAbstractSpinBox::wrapping() + // void QAbstractSpinBox::setWrapping(bool) + obj1.setWrapping(false); + QCOMPARE(false, obj1.wrapping()); + obj1.setWrapping(true); + QCOMPARE(true, obj1.wrapping()); + + // QLineEdit * QAbstractSpinBox::lineEdit() + // void QAbstractSpinBox::setLineEdit(QLineEdit *) + QLineEdit *var3 = new QLineEdit(0); + obj1.setLineEdit(var3); + QCOMPARE(var3, obj1.lineEdit()); +#ifndef QT_DEBUG + obj1.setLineEdit((QLineEdit *)0); // Will assert in debug, so only test in release + QCOMPARE(var3, obj1.lineEdit()); // Setting 0 should keep the current editor +#endif + // delete var3; // No delete, since QAbstractSpinBox takes ownership +} + +void tst_QAbstractSpinBox::task183108_clear() +{ + QAbstractSpinBox *sbox; + + sbox = new QSpinBox; + sbox->clear(); + sbox->show(); + qApp->processEvents(); + QVERIFY(sbox->text().isEmpty()); + + delete sbox; + sbox = new QSpinBox; + sbox->clear(); + sbox->show(); + sbox->hide(); + qApp->processEvents(); + QCOMPARE(sbox->text(), QString()); + + delete sbox; + sbox = new QSpinBox; + sbox->show(); + sbox->clear(); + qApp->processEvents(); + QCOMPARE(sbox->text(), QString()); + + delete sbox; + sbox = new QSpinBox; + sbox->show(); + sbox->clear(); + sbox->hide(); + qApp->processEvents(); + QCOMPARE(sbox->text(), QString()); + + delete sbox; +} + +void tst_QAbstractSpinBox::task228728_cssselector() +{ + //QAbstractSpinBox does some call to stylehint into his constructor. + //so while the stylesheet want to access property, it should not crash + qApp->setStyleSheet("[alignement=\"1\"], [text=\"foo\"] { color:black; }" ); + QSpinBox box; +} + + +QTEST_MAIN(tst_QAbstractSpinBox) +#include "tst_qabstractspinbox.moc" diff --git a/tests/auto/widgets/widgets/qbuttongroup/.gitignore b/tests/auto/widgets/widgets/qbuttongroup/.gitignore new file mode 100644 index 0000000000..898b2276b0 --- /dev/null +++ b/tests/auto/widgets/widgets/qbuttongroup/.gitignore @@ -0,0 +1 @@ +tst_qbuttongroup diff --git a/tests/auto/widgets/widgets/qbuttongroup/qbuttongroup.pro b/tests/auto/widgets/widgets/qbuttongroup/qbuttongroup.pro new file mode 100644 index 0000000000..6f506e8f06 --- /dev/null +++ b/tests/auto/widgets/widgets/qbuttongroup/qbuttongroup.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qbuttongroup.cpp + + + diff --git a/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp new file mode 100644 index 0000000000..f9f6ec0a54 --- /dev/null +++ b/tests/auto/widgets/widgets/qbuttongroup/tst_qbuttongroup.cpp @@ -0,0 +1,525 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + + +#include "qbuttongroup.h" +#include <qaction.h> +#include <qapplication.h> +#include <qdialog.h> +#include <qlayout.h> +#include <qgroupbox.h> +#include <qradiobutton.h> +#include <qpushbutton.h> +#include <qlineedit.h> +#include <qtoolbutton.h> +#ifdef Q_WS_MAC +#include <qsettings.h> +#endif + +class SpecialRadioButton: public QRadioButton +{ +public: + SpecialRadioButton(QWidget *parent) : QRadioButton(parent) + { } + +protected: + void focusInEvent(QFocusEvent *) + { + QCoreApplication::postEvent(this, new QKeyEvent(QEvent::KeyPress, + Qt::Key_Down, Qt::NoModifier)); + } +}; + +#include <qbuttongroup.h> + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QButtonGroup : public QObject +{ +Q_OBJECT +public: + tst_QButtonGroup(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void arrowKeyNavigation(); + void exclusive(); + void exclusiveWithActions(); + void testSignals(); + void checkedButton(); + + void task106609(); + + void autoIncrementId(); + + void task209485_removeFromGroupInEventHandler_data(); + void task209485_removeFromGroupInEventHandler(); +}; + +tst_QButtonGroup::tst_QButtonGroup() +{ +} + + +void tst_QButtonGroup::initTestCase() +{ +} + +void tst_QButtonGroup::cleanupTestCase() +{ +} + +void tst_QButtonGroup::init() +{ +} + +void tst_QButtonGroup::cleanup() +{ +} + +QT_BEGIN_NAMESPACE +extern bool Q_GUI_EXPORT qt_tab_all_widgets; +QT_END_NAMESPACE + + +void tst_QButtonGroup::arrowKeyNavigation() +{ + if (!qt_tab_all_widgets) + QSKIP("This test requires full keyboard control to be enabled.", SkipAll); + + QDialog dlg(0); + QHBoxLayout layout(&dlg); + QGroupBox g1("1", &dlg); + QHBoxLayout g1layout(&g1); + QRadioButton bt1("Radio1", &g1); + QPushButton pb("PB", &g1); + QLineEdit le(&g1); + QRadioButton bt2("Radio2", &g1); + g1layout.addWidget(&bt1); + g1layout.addWidget(&pb); + g1layout.addWidget(&le); + g1layout.addWidget(&bt2); + + // create a mixed button group with radion buttons and push + // buttons. Not very useful, but it tests borderline cases wrt + // focus handling. + QButtonGroup bgrp1(&g1); + bgrp1.addButton(&bt1); + bgrp1.addButton(&pb); + bgrp1.addButton(&bt2); + + QGroupBox g2("2", &dlg); + QVBoxLayout g2layout(&g2); + // we don't need a button group here, because radio buttons are + // auto exclusive, i.e. they group themselves in he same parent + // widget. + QRadioButton bt3("Radio3", &g2); + QRadioButton bt4("Radio4", &g2); + g2layout.addWidget(&bt3); + g2layout.addWidget(&bt4); + + layout.addWidget(&g1); + layout.addWidget(&g2); + + dlg.show(); + qApp->setActiveWindow(&dlg); + QTest::qWaitForWindowShown(&dlg); + + bt1.setFocus(); + + QTRY_VERIFY(bt1.hasFocus()); + + QTest::keyClick(&bt1, Qt::Key_Right); + QVERIFY(pb.hasFocus()); + QTest::keyClick(&pb, Qt::Key_Right); + QVERIFY(bt2.hasFocus()); + QTest::keyClick(&bt2, Qt::Key_Right); + QVERIFY(bt2.hasFocus()); + QTest::keyClick(&bt2, Qt::Key_Left); + QVERIFY(pb.hasFocus()); + QTest::keyClick(&pb, Qt::Key_Left); + QVERIFY(bt1.hasFocus()); + + QTest::keyClick(&bt1, Qt::Key_Tab); + QVERIFY(pb.hasFocus()); + QTest::keyClick(&pb, Qt::Key_Tab); + + QVERIFY(le.hasFocus()); + QCOMPARE(le.selectedText(), le.text()); + QTest::keyClick(&le, Qt::Key_Tab); + + QVERIFY(bt2.hasFocus()); + QTest::keyClick(&bt2, Qt::Key_Tab); + QVERIFY(bt3.hasFocus()); + + QTest::keyClick(&bt3, Qt::Key_Down); + QVERIFY(bt4.hasFocus()); + QTest::keyClick(&bt4, Qt::Key_Down); + QVERIFY(bt4.hasFocus()); + + QTest::keyClick(&bt4, Qt::Key_Up); + QVERIFY(bt3.hasFocus()); + QTest::keyClick(&bt3, Qt::Key_Up); + QVERIFY(bt3.hasFocus()); +} + +void tst_QButtonGroup::exclusiveWithActions() +{ + QDialog dlg(0); + QHBoxLayout layout(&dlg); + QAction *action1 = new QAction("Action 1", &dlg); + action1->setCheckable(true); + QAction *action2 = new QAction("Action 2", &dlg); + action2->setCheckable(true); + QAction *action3 = new QAction("Action 3", &dlg); + action3->setCheckable(true); + QToolButton *toolButton1 = new QToolButton(&dlg); + QToolButton *toolButton2 = new QToolButton(&dlg); + QToolButton *toolButton3 = new QToolButton(&dlg); + toolButton1->setDefaultAction(action1); + toolButton2->setDefaultAction(action2); + toolButton3->setDefaultAction(action3); + layout.addWidget(toolButton1); + layout.addWidget(toolButton2); + layout.addWidget(toolButton3); + QButtonGroup *buttonGroup = new QButtonGroup( &dlg ); + buttonGroup->setExclusive(true); + buttonGroup->addButton(toolButton1, 1); + buttonGroup->addButton(toolButton2, 2); + buttonGroup->addButton(toolButton3, 3); + dlg.show(); + + QTest::mouseClick(toolButton1, Qt::LeftButton); + QVERIFY(toolButton1->isChecked()); + QVERIFY(action1->isChecked()); + QVERIFY(!toolButton2->isChecked()); + QVERIFY(!toolButton3->isChecked()); + QVERIFY(!action2->isChecked()); + QVERIFY(!action3->isChecked()); + + QTest::mouseClick(toolButton2, Qt::LeftButton); + QVERIFY(toolButton2->isChecked()); + QVERIFY(action2->isChecked()); + QVERIFY(!toolButton1->isChecked()); + QVERIFY(!toolButton3->isChecked()); + QVERIFY(!action1->isChecked()); + QVERIFY(!action3->isChecked()); + + QTest::mouseClick(toolButton3, Qt::LeftButton); + QVERIFY(toolButton3->isChecked()); + QVERIFY(action3->isChecked()); + QVERIFY(!toolButton1->isChecked()); + QVERIFY(!toolButton2->isChecked()); + QVERIFY(!action1->isChecked()); + QVERIFY(!action2->isChecked()); + + QTest::mouseClick(toolButton2, Qt::LeftButton); + QVERIFY(toolButton2->isChecked()); + QVERIFY(action2->isChecked()); + QVERIFY(!toolButton1->isChecked()); + QVERIFY(!toolButton3->isChecked()); + QVERIFY(!action1->isChecked()); + QVERIFY(!action3->isChecked()); +} + +void tst_QButtonGroup::exclusive() +{ + QDialog dlg(0); + QHBoxLayout layout(&dlg); + QPushButton *pushButton1 = new QPushButton(&dlg); + QPushButton *pushButton2 = new QPushButton(&dlg); + QPushButton *pushButton3 = new QPushButton(&dlg); + pushButton1->setCheckable(true); + pushButton2->setCheckable(true); + pushButton3->setCheckable(true); + layout.addWidget(pushButton1); + layout.addWidget(pushButton2); + layout.addWidget(pushButton3); + QButtonGroup *buttonGroup = new QButtonGroup( &dlg ); + buttonGroup->setExclusive(true); + buttonGroup->addButton(pushButton1, 1); + buttonGroup->addButton(pushButton2, 2); + buttonGroup->addButton(pushButton3, 3); + dlg.show(); + + QTest::mouseClick(pushButton1, Qt::LeftButton); + QVERIFY(pushButton1->isChecked()); + QVERIFY(!pushButton2->isChecked()); + QVERIFY(!pushButton3->isChecked()); + + QTest::mouseClick(pushButton2, Qt::LeftButton); + QVERIFY(pushButton2->isChecked()); + QVERIFY(!pushButton1->isChecked()); + QVERIFY(!pushButton3->isChecked()); + + QTest::mouseClick(pushButton3, Qt::LeftButton); + QVERIFY(pushButton3->isChecked()); + QVERIFY(!pushButton1->isChecked()); + QVERIFY(!pushButton2->isChecked()); + + QTest::mouseClick(pushButton2, Qt::LeftButton); + QVERIFY(pushButton2->isChecked()); + QVERIFY(!pushButton1->isChecked()); + QVERIFY(!pushButton3->isChecked()); +} + +void tst_QButtonGroup::testSignals() +{ + QButtonGroup buttons; + QPushButton pb1; + QPushButton pb2; + QPushButton pb3; + buttons.addButton(&pb1); + buttons.addButton(&pb2, 23); + buttons.addButton(&pb3); + + qRegisterMetaType<QAbstractButton *>("QAbstractButton *"); + QSignalSpy clickedSpy(&buttons, SIGNAL(buttonClicked(QAbstractButton *))); + QSignalSpy clickedIdSpy(&buttons, SIGNAL(buttonClicked(int))); + QSignalSpy pressedSpy(&buttons, SIGNAL(buttonPressed(QAbstractButton *))); + QSignalSpy pressedIdSpy(&buttons, SIGNAL(buttonPressed(int))); + QSignalSpy releasedSpy(&buttons, SIGNAL(buttonReleased(QAbstractButton *))); + QSignalSpy releasedIdSpy(&buttons, SIGNAL(buttonReleased(int))); + + pb1.animateClick(); + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(clickedSpy.count(), 1); + QCOMPARE(clickedIdSpy.count(), 1); + + int expectedId = -2; + + QVERIFY(clickedIdSpy.takeFirst().at(0).toInt() == expectedId); + QCOMPARE(pressedSpy.count(), 1); + QCOMPARE(pressedIdSpy.count(), 1); + QVERIFY(pressedIdSpy.takeFirst().at(0).toInt() == expectedId); + QCOMPARE(releasedSpy.count(), 1); + QCOMPARE(releasedIdSpy.count(), 1); + QVERIFY(releasedIdSpy.takeFirst().at(0).toInt() == expectedId); + + clickedSpy.clear(); + clickedIdSpy.clear(); + pressedSpy.clear(); + pressedIdSpy.clear(); + releasedSpy.clear(); + releasedIdSpy.clear(); + + pb2.animateClick(); + QTestEventLoop::instance().enterLoop(1); + + QCOMPARE(clickedSpy.count(), 1); + QCOMPARE(clickedIdSpy.count(), 1); + QVERIFY(clickedIdSpy.takeFirst().at(0).toInt() == 23); + QCOMPARE(pressedSpy.count(), 1); + QCOMPARE(pressedIdSpy.count(), 1); + QVERIFY(pressedIdSpy.takeFirst().at(0).toInt() == 23); + QCOMPARE(releasedSpy.count(), 1); + QCOMPARE(releasedIdSpy.count(), 1); + QVERIFY(releasedIdSpy.takeFirst().at(0).toInt() == 23); +} + +void tst_QButtonGroup::task106609() +{ + // task is: + // sometimes, only one of the two signals in QButtonGroup get emitted + // they get emitted when using the mouse, but when using the keyboard, only one is + // + + QDialog dlg(0); + QButtonGroup *buttons = new QButtonGroup(&dlg); + QVBoxLayout *vbox = new QVBoxLayout(&dlg); + + SpecialRadioButton *radio1 = new SpecialRadioButton(&dlg); + radio1->setText("radio1"); + SpecialRadioButton *radio2 = new SpecialRadioButton(&dlg); + radio2->setText("radio2"); + QRadioButton *radio3 = new QRadioButton(&dlg); + radio3->setText("radio3"); + + buttons->addButton(radio1, 1); + vbox->addWidget(radio1); + buttons->addButton(radio2, 2); + vbox->addWidget(radio2); + buttons->addButton(radio3, 3); + vbox->addWidget(radio3); + dlg.show(); + QTest::qWaitForWindowShown(&dlg); + + qRegisterMetaType<QAbstractButton*>("QAbstractButton*"); + QSignalSpy spy1(buttons, SIGNAL(buttonClicked(QAbstractButton*))); + QSignalSpy spy2(buttons, SIGNAL(buttonClicked(int))); + + QApplication::setActiveWindow(&dlg); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&dlg)); + + radio1->setFocus(); + radio1->setChecked(true); + QTestEventLoop::instance().enterLoop(1); + + //qDebug() << "int:" << spy2.count() << "QAbstractButton*:" << spy1.count(); + QCOMPARE(spy2.count(), 2); + QCOMPARE(spy1.count(), 2); +} + +void tst_QButtonGroup::checkedButton() +{ + QButtonGroup buttons; + buttons.setExclusive(false); + QPushButton pb1; + pb1.setCheckable(true); + QPushButton pb2; + pb2.setCheckable(true); + buttons.addButton(&pb1); + buttons.addButton(&pb2, 23); + + QVERIFY(buttons.checkedButton() == 0); + pb1.setChecked(true); + QVERIFY(buttons.checkedButton() == &pb1); + pb2.setChecked(true); + QVERIFY(buttons.checkedButton() == &pb2); + pb2.setChecked(false); + QVERIFY(buttons.checkedButton() == &pb1); + pb1.setChecked(false); + QVERIFY(buttons.checkedButton() == 0); + + buttons.setExclusive(true); + QVERIFY(buttons.checkedButton() == 0); + pb1.setChecked(true); + QVERIFY(buttons.checkedButton() == &pb1); + pb2.setChecked(true); + QVERIFY(buttons.checkedButton() == &pb2); + // checked button cannot be unchecked + pb2.setChecked(false); + QVERIFY(buttons.checkedButton() == &pb2); +} + +class task209485_ButtonDeleter : public QObject +{ + Q_OBJECT + +public: + task209485_ButtonDeleter(QButtonGroup *group, bool deleteButton) + : group(group) + , deleteButton(deleteButton) + { + connect(group, SIGNAL(buttonClicked(int)), SLOT(buttonClicked(int))); + } + +private slots: + void buttonClicked(int) + { + if (deleteButton) + group->removeButton(group->buttons().first()); + } + +private: + QButtonGroup *group; + bool deleteButton; +}; + +void tst_QButtonGroup::task209485_removeFromGroupInEventHandler_data() +{ + QTest::addColumn<bool>("deleteButton"); + QTest::addColumn<int>("signalCount"); + QTest::newRow("buttonPress 1") << true << 1; + QTest::newRow("buttonPress 2") << false << 2; +} + +void tst_QButtonGroup::task209485_removeFromGroupInEventHandler() +{ + QFETCH(bool, deleteButton); + QFETCH(int, signalCount); + qRegisterMetaType<QAbstractButton *>("QAbstractButton *"); + + QPushButton *button = new QPushButton; + QButtonGroup group; + group.addButton(button); + + task209485_ButtonDeleter buttonDeleter(&group, deleteButton); + + QSignalSpy spy1(&group, SIGNAL(buttonClicked(QAbstractButton *))); + QSignalSpy spy2(&group, SIGNAL(buttonClicked(int))); + + // NOTE: Reintroducing the bug of this task will cause the following line to crash: + QTest::mouseClick(button, Qt::LeftButton); + + QCOMPARE(spy1.count() + spy2.count(), signalCount); +} + +void tst_QButtonGroup::autoIncrementId() +{ + QDialog dlg(0); + QButtonGroup *buttons = new QButtonGroup(&dlg); + QVBoxLayout *vbox = new QVBoxLayout(&dlg); + + QRadioButton *radio1 = new QRadioButton(&dlg); + radio1->setText("radio1"); + QRadioButton *radio2 = new QRadioButton(&dlg); + radio2->setText("radio2"); + QRadioButton *radio3 = new QRadioButton(&dlg); + radio3->setText("radio3"); + + buttons->addButton(radio1); + vbox->addWidget(radio1); + buttons->addButton(radio2); + vbox->addWidget(radio2); + buttons->addButton(radio3); + vbox->addWidget(radio3); + + radio1->setChecked(true); + + QVERIFY(buttons->id(radio1) == -2); + QVERIFY(buttons->id(radio2) == -3); + QVERIFY(buttons->id(radio3) == -4); + + dlg.show(); +} + +QTEST_MAIN(tst_QButtonGroup) +#include "tst_qbuttongroup.moc" diff --git a/tests/auto/widgets/widgets/qcalendarwidget/.gitignore b/tests/auto/widgets/widgets/qcalendarwidget/.gitignore new file mode 100644 index 0000000000..db8a381e0d --- /dev/null +++ b/tests/auto/widgets/widgets/qcalendarwidget/.gitignore @@ -0,0 +1 @@ +tst_qcalendarwidget diff --git a/tests/auto/widgets/widgets/qcalendarwidget/qcalendarwidget.pro b/tests/auto/widgets/widgets/qcalendarwidget/qcalendarwidget.pro new file mode 100644 index 0000000000..d250b83537 --- /dev/null +++ b/tests/auto/widgets/widgets/qcalendarwidget/qcalendarwidget.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qcalendarwidget.cpp + + diff --git a/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp new file mode 100644 index 0000000000..50dc6a1d1c --- /dev/null +++ b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp @@ -0,0 +1,368 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <qcalendarwidget.h> +#include <qtoolbutton.h> +#include <qspinbox.h> +#include <qmenu.h> +#include <qdebug.h> +#include <qdatetime.h> +#include <qtextformat.h> + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QCalendarWidget : public QObject +{ + Q_OBJECT + +public: + tst_QCalendarWidget(); + virtual ~tst_QCalendarWidget(); +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void getSetCheck(); + void buttonClickCheck(); + + void setTextFormat(); + void resetTextFormat(); + + void setWeekdayFormat(); + void showPrevNext_data(); + void showPrevNext(); +}; + +// Testing get/set functions +void tst_QCalendarWidget::getSetCheck() +{ + QWidget topLevel; + QCalendarWidget object(&topLevel); + + //horizontal header formats + object.setHorizontalHeaderFormat(QCalendarWidget::NoHorizontalHeader); + QCOMPARE(QCalendarWidget::NoHorizontalHeader, object.horizontalHeaderFormat()); + object.setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames); + QCOMPARE(QCalendarWidget::SingleLetterDayNames, object.horizontalHeaderFormat()); + object.setHorizontalHeaderFormat(QCalendarWidget::ShortDayNames); + QCOMPARE(QCalendarWidget::ShortDayNames, object.horizontalHeaderFormat()); + object.setHorizontalHeaderFormat(QCalendarWidget::LongDayNames); + QCOMPARE(QCalendarWidget::LongDayNames, object.horizontalHeaderFormat()); + //vertical header formats + object.setVerticalHeaderFormat(QCalendarWidget::ISOWeekNumbers); + QCOMPARE(QCalendarWidget::ISOWeekNumbers, object.verticalHeaderFormat()); + object.setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); + QCOMPARE(QCalendarWidget::NoVerticalHeader, object.verticalHeaderFormat()); + //maximum Date + QDate maxDate(2006, 7, 3); + object.setMaximumDate(maxDate); + QCOMPARE(maxDate, object.maximumDate()); + //minimum date + QDate minDate(2004, 7, 3); + object.setMinimumDate(minDate); + QCOMPARE(minDate, object.minimumDate()); + //day of week + object.setFirstDayOfWeek(Qt::Thursday); + QCOMPARE(Qt::Thursday, object.firstDayOfWeek()); + //grid visible + object.setGridVisible(true); + QVERIFY(object.isGridVisible()); + object.setGridVisible(false); + QVERIFY(!object.isGridVisible()); + //header visible + object.setNavigationBarVisible(true); + QVERIFY(object.isNavigationBarVisible()); + object.setNavigationBarVisible(false); + QVERIFY(!object.isNavigationBarVisible()); + //selection mode + QCOMPARE(QCalendarWidget::SingleSelection, object.selectionMode()); + object.setSelectionMode(QCalendarWidget::NoSelection); + QCOMPARE(QCalendarWidget::NoSelection, object.selectionMode()); + object.setSelectionMode(QCalendarWidget::SingleSelection); + QCOMPARE(QCalendarWidget::SingleSelection, object.selectionMode()); + //selected date + QDate selectedDate(2005, 7, 3); + QSignalSpy spy(&object, SIGNAL(selectionChanged())); + object.setSelectedDate(selectedDate); + QCOMPARE(spy.count(), 1); + QCOMPARE(selectedDate, object.selectedDate()); + //month and year + object.setCurrentPage(2004, 1); + QCOMPARE(1, object.monthShown()); + QCOMPARE(2004, object.yearShown()); + object.showNextMonth(); + QCOMPARE(2, object.monthShown()); + object.showPreviousMonth(); + QCOMPARE(1, object.monthShown()); + object.showNextYear(); + QCOMPARE(2005, object.yearShown()); + object.showPreviousYear(); + QCOMPARE(2004, object.yearShown()); + //date range + minDate = QDate(2006,1,1); + maxDate = QDate(2010,12,31); + object.setDateRange(minDate, maxDate); + QCOMPARE(maxDate, object.maximumDate()); + QCOMPARE(minDate, object.minimumDate()); + + //date should not go beyond the minimum. + selectedDate = minDate.addDays(-10); + object.setSelectedDate(selectedDate); + QCOMPARE(minDate, object.selectedDate()); + QVERIFY(selectedDate != object.selectedDate()); + //date should not go beyond the maximum. + selectedDate = maxDate.addDays(10); + object.setSelectedDate(selectedDate); + QCOMPARE(maxDate, object.selectedDate()); + QVERIFY(selectedDate != object.selectedDate()); + //show today + QDate today = QDate::currentDate(); + object.showToday(); + QCOMPARE(today.month(), object.monthShown()); + QCOMPARE(today.year(), object.yearShown()); + //slect a different date and move. + object.setSelectedDate(minDate); + object.showSelectedDate(); + QCOMPARE(minDate.month(), object.monthShown()); + QCOMPARE(minDate.year(), object.yearShown()); +} + +void tst_QCalendarWidget::buttonClickCheck() +{ + QCalendarWidget object; + QSize size = object.sizeHint(); + object.setGeometry(0,0,size.width(), size.height()); + object.show(); + + QRect rect = object.geometry(); + QDate selectedDate(2005, 1, 1); + //click on the month buttons + int month = object.monthShown(); + QToolButton *button = qFindChild<QToolButton *>(&object, "qt_calendar_prevmonth"); + QTest::mouseClick(button, Qt::LeftButton); + QCOMPARE(month > 1 ? month-1 : 12, object.monthShown()); + button = qFindChild<QToolButton *>(&object, "qt_calendar_nextmonth"); + QTest::mouseClick(button, Qt::LeftButton); + QCOMPARE(month, object.monthShown()); + + button = qFindChild<QToolButton *>(&object, "qt_calendar_yearbutton"); + QTest::mouseClick(button, Qt::LeftButton, Qt::NoModifier, button->rect().center(), 2); + QVERIFY(!button->isVisible()); + QSpinBox *spinbox = qFindChild<QSpinBox *>(&object, "qt_calendar_yearedit"); + QTest::qWait(500); + QTest::keyClick(spinbox, '2'); + QTest::keyClick(spinbox, '0'); + QTest::keyClick(spinbox, '0'); + QTest::keyClick(spinbox, '6'); + QTest::qWait(500); + QWidget *widget = qFindChild<QWidget *>(&object, "qt_calendar_calendarview"); + QTest::mouseMove(widget); + QTest::mouseClick(widget, Qt::LeftButton); + QCOMPARE(2006, object.yearShown()); + object.setSelectedDate(selectedDate); + object.showSelectedDate(); + QTest::keyClick(widget, Qt::Key_Down); + QVERIFY(selectedDate != object.selectedDate()); + + object.setDateRange(QDate(2006,1,1), QDate(2006,2,28)); + object.setSelectedDate(QDate(2006,1,1)); + object.showSelectedDate(); + button = qFindChild<QToolButton *>(&object, "qt_calendar_prevmonth"); + QTest::mouseClick(button, Qt::LeftButton); + QCOMPARE(1, object.monthShown()); + + button = qFindChild<QToolButton *>(&object, "qt_calendar_nextmonth"); + QTest::mouseClick(button, Qt::LeftButton); + QCOMPARE(2, object.monthShown()); + QTest::mouseClick(button, Qt::LeftButton); + QCOMPARE(2, object.monthShown()); + +} + +void tst_QCalendarWidget::setTextFormat() +{ + QCalendarWidget calendar; + QTextCharFormat format; + format.setFontItalic(true); + format.setForeground(Qt::green); + + const QDate date(1984, 10, 20); + calendar.setDateTextFormat(date, format); + QCOMPARE(calendar.dateTextFormat(date), format); +} + +void tst_QCalendarWidget::resetTextFormat() +{ + QCalendarWidget calendar; + QTextCharFormat format; + format.setFontItalic(true); + format.setForeground(Qt::green); + + const QDate date(1984, 10, 20); + calendar.setDateTextFormat(date, format); + + calendar.setDateTextFormat(QDate(), QTextCharFormat()); + QCOMPARE(calendar.dateTextFormat(date), QTextCharFormat()); +} + +void tst_QCalendarWidget::setWeekdayFormat() +{ + QCalendarWidget calendar; + + QTextCharFormat format; + format.setFontItalic(true); + format.setForeground(Qt::green); + + calendar.setWeekdayTextFormat(Qt::Wednesday, format); + + // check the format of the a given month + for (int i = 1; i <= 31; ++i) { + const QDate date(1984, 10, i); + const Qt::DayOfWeek dayOfWeek = static_cast<Qt::DayOfWeek>(date.dayOfWeek()); + if (dayOfWeek == Qt::Wednesday) + QCOMPARE(calendar.weekdayTextFormat(dayOfWeek), format); + else + QVERIFY(calendar.weekdayTextFormat(dayOfWeek) != format); + } +} + +tst_QCalendarWidget::tst_QCalendarWidget() +{ +} + +tst_QCalendarWidget::~tst_QCalendarWidget() +{ +} + +void tst_QCalendarWidget::initTestCase() +{ +} + +void tst_QCalendarWidget::cleanupTestCase() +{ +} + +void tst_QCalendarWidget::init() +{ +} + +void tst_QCalendarWidget::cleanup() +{ +} + + +typedef void (QCalendarWidget::*ShowFunc)(); +Q_DECLARE_METATYPE(ShowFunc) + +void tst_QCalendarWidget::showPrevNext_data() +{ + QTest::addColumn<ShowFunc>("function"); + QTest::addColumn<QDate>("dateOrigin"); + QTest::addColumn<QDate>("expectedDate"); + + QTest::newRow("showNextMonth") << &QCalendarWidget::showNextMonth << QDate(1984,7,30) << QDate(1984,8,30); + QTest::newRow("showPrevMonth") << &QCalendarWidget::showPreviousMonth << QDate(1984,7,30) << QDate(1984,6,30); + QTest::newRow("showNextYear") << &QCalendarWidget::showNextYear << QDate(1984,7,30) << QDate(1985,7,30); + QTest::newRow("showPrevYear") << &QCalendarWidget::showPreviousYear << QDate(1984,7,30) << QDate(1983,7,30); + + QTest::newRow("showNextMonth limit") << &QCalendarWidget::showNextMonth << QDate(2007,12,4) << QDate(2008,1,4); + QTest::newRow("showPreviousMonth limit") << &QCalendarWidget::showPreviousMonth << QDate(2006,1,23) << QDate(2005,12,23); + + QTest::newRow("showNextMonth now") << &QCalendarWidget::showNextMonth << QDate() << QDate::currentDate().addMonths(1); + QTest::newRow("showNextYear now") << &QCalendarWidget::showNextYear << QDate() << QDate::currentDate().addYears(1); + QTest::newRow("showPrevieousMonth now") << &QCalendarWidget::showPreviousMonth << QDate() << QDate::currentDate().addMonths(-1); + QTest::newRow("showPreviousYear now") << &QCalendarWidget::showPreviousYear << QDate() << QDate::currentDate().addYears(-1); + + QTest::newRow("showToday now") << &QCalendarWidget::showToday << QDate(2000,1,31) << QDate::currentDate(); + QTest::newRow("showNextMonth 31") << &QCalendarWidget::showNextMonth << QDate(2000,1,31) << QDate(2000,2,28); + QTest::newRow("selectedDate") << &QCalendarWidget::showSelectedDate << QDate(2008,2,29) << QDate(2008,2,29); + +} + +void tst_QCalendarWidget::showPrevNext() +{ + QFETCH(ShowFunc, function); + QFETCH(QDate, dateOrigin); + QFETCH(QDate, expectedDate); + + QCalendarWidget calWidget; + calWidget.show(); + QTest::qWaitForWindowShown(&calWidget); + if(!dateOrigin.isNull()) { + calWidget.setSelectedDate(dateOrigin); + calWidget.setCurrentPage(dateOrigin.year(), dateOrigin.month()); + + QCOMPARE(calWidget.yearShown(), dateOrigin.year()); + QCOMPARE(calWidget.monthShown(), dateOrigin.month()); + } else { + QCOMPARE(calWidget.yearShown(), QDate::currentDate().year()); + QCOMPARE(calWidget.monthShown(), QDate::currentDate().month()); + } + + (calWidget.*function)(); + + QCOMPARE(calWidget.yearShown(), expectedDate.year()); + QCOMPARE(calWidget.monthShown(), expectedDate.month()); + + // QTBUG-4058 + QTest::qWait(20); + QToolButton *button = qFindChild<QToolButton *>(&calWidget, "qt_calendar_prevmonth"); + QTest::mouseClick(button, Qt::LeftButton); + expectedDate = expectedDate.addMonths(-1); + QCOMPARE(calWidget.yearShown(), expectedDate.year()); + QCOMPARE(calWidget.monthShown(), expectedDate.month()); + + if(!dateOrigin.isNull()) { + //the selectedDate should not have changed + QCOMPARE(calWidget.selectedDate(), dateOrigin); + } +} + +QTEST_MAIN(tst_QCalendarWidget) +#include "tst_qcalendarwidget.moc" diff --git a/tests/auto/widgets/widgets/qcheckbox/.gitignore b/tests/auto/widgets/widgets/qcheckbox/.gitignore new file mode 100644 index 0000000000..b838802077 --- /dev/null +++ b/tests/auto/widgets/widgets/qcheckbox/.gitignore @@ -0,0 +1 @@ +tst_qcheckbox diff --git a/tests/auto/widgets/widgets/qcheckbox/qcheckbox.pro b/tests/auto/widgets/widgets/qcheckbox/qcheckbox.pro new file mode 100644 index 0000000000..aa1f35b3c9 --- /dev/null +++ b/tests/auto/widgets/widgets/qcheckbox/qcheckbox.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qcheckbox.cpp + + + diff --git a/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp b/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp new file mode 100644 index 0000000000..33f5af4d0b --- /dev/null +++ b/tests/auto/widgets/widgets/qcheckbox/tst_qcheckbox.cpp @@ -0,0 +1,358 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + + +#include "qcheckbox.h" +#include <qapplication.h> +#include <qpixmap.h> +#include <qdatetime.h> +#include <qcheckbox.h> + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QCheckBox : public QObject +{ +Q_OBJECT + +public: + tst_QCheckBox(); + virtual ~tst_QCheckBox(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void setChecked(); + void setTriState(); + void setText_data(); + void setText(); + void isToggleButton(); + void setDown(); + void setAutoRepeat(); + void toggle(); + void pressed(); + void toggled(); + void stateChanged(); + void foregroundRole(); + void minimumSizeHint(); + +protected slots: + void onClicked(); + void onToggled( bool on ); + void onPressed(); + void onReleased(); + void onStateChanged( int state ); + +private: + uint click_count; + uint toggle_count; + uint press_count; + uint release_count; + int cur_state; + uint tmp; + QCheckBox *testWidget; + uint tmp2; +}; + +tst_QCheckBox::tst_QCheckBox() +{ +} + +tst_QCheckBox::~tst_QCheckBox() +{ +} + +void tst_QCheckBox::initTestCase() +{ + // Create the test class + testWidget = new QCheckBox(0); + testWidget->setObjectName("testObject"); + testWidget->resize( 200, 200 ); + testWidget->show(); +} + +void tst_QCheckBox::cleanupTestCase() +{ + delete testWidget; + testWidget = 0; +} + +void tst_QCheckBox::init() +{ + testWidget->setTristate( FALSE ); + testWidget->setChecked( FALSE ); + testWidget->setAutoRepeat( FALSE ); +} + +void tst_QCheckBox::cleanup() +{ + disconnect(testWidget, SIGNAL(pressed()), this, SLOT(onPressed())); + disconnect(testWidget, SIGNAL(released()), this, SLOT(onReleased())); + disconnect(testWidget, SIGNAL(clicked()), this, SLOT(onClicked())); + disconnect(testWidget, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool))); +} + +void tst_QCheckBox::onClicked() +{ + click_count++; +} + +void tst_QCheckBox::onPressed() +{ + press_count++; +} + +void tst_QCheckBox::onReleased() +{ + release_count++; +} + +void tst_QCheckBox::onToggled( bool /*on*/ ) +{ + toggle_count++; +} + +// *************************************************** + +void tst_QCheckBox::setChecked() +{ + testWidget->setChecked( TRUE ); + QVERIFY( testWidget->isChecked() ); + QVERIFY( testWidget->isChecked() ); + QVERIFY( testWidget->checkState() == Qt::Checked ); + + testWidget->setChecked( FALSE ); + QVERIFY( !testWidget->isChecked() ); + QVERIFY( !testWidget->isChecked() ); + QVERIFY( testWidget->checkState() == Qt::Unchecked ); + + testWidget->setChecked( FALSE ); + QTest::keyClick( testWidget, ' ' ); + QVERIFY( testWidget->isChecked() ); + + QTest::keyClick( testWidget, ' ' ); + QVERIFY( !testWidget->isChecked() ); +} + +void tst_QCheckBox::setTriState() +{ + testWidget->setTristate( TRUE ); + QVERIFY( testWidget->isTristate() ); + QVERIFY( testWidget->checkState() == Qt::Unchecked ); + + testWidget->setCheckState(Qt::PartiallyChecked); + QVERIFY( testWidget->checkState() == Qt::PartiallyChecked ); + + testWidget->setChecked( TRUE ); + QVERIFY( testWidget->isChecked() ); + QVERIFY( testWidget->checkState() == Qt::Checked ); + + testWidget->setChecked( FALSE ); + QVERIFY( !testWidget->isChecked() ); + QVERIFY( testWidget->checkState() == Qt::Unchecked ); + + testWidget->setCheckState(Qt::PartiallyChecked); + QVERIFY( testWidget->checkState() == Qt::PartiallyChecked ); + + testWidget->setTristate( FALSE ); + QVERIFY( !testWidget->isTristate() ); + + testWidget->setCheckState(Qt::PartiallyChecked); + QVERIFY( testWidget->checkState() == Qt::PartiallyChecked ); + + testWidget->setChecked( TRUE ); + QVERIFY( testWidget->checkState() == Qt::Checked ); + + testWidget->setChecked( FALSE ); + QVERIFY( testWidget->checkState() == Qt::Unchecked ); +} + +void tst_QCheckBox::setText_data() +{ + QTest::addColumn<QString>("s1"); + +#ifdef Q_OS_WIN32 + QTest::newRow( "win32_data0" ) << QString("This is a text"); + QTest::newRow( "win32_data1" ) << QString("A"); + QTest::newRow( "win32_data2" ) << QString("ABCDEFG "); + QTest::newRow( "win32_data3" ) << QString("Text\nwith a cr-lf"); + QTest::newRow( "win32_data4" ) << QString(""); +#else + QTest::newRow( "data0" ) << QString("This is a text"); + QTest::newRow( "data1" ) << QString("A"); + QTest::newRow( "data2" ) << QString("ABCDEFG "); + QTest::newRow( "data3" ) << QString("Text\nwith a cr-lf"); + QTest::newRow( "data4" ) << QString(""); +#endif +} + +void tst_QCheckBox::setText() +{ + QFETCH( QString, s1 ); + testWidget->setText( s1 ); + QCOMPARE( testWidget->text(), s1 ); +} + +void tst_QCheckBox::setDown() +{ + testWidget->setDown( TRUE ); + QVERIFY( testWidget->isDown() ); + + testWidget->setDown( FALSE ); + QVERIFY( !testWidget->isDown() ); +} + +void tst_QCheckBox::setAutoRepeat() +{ + // setAutoRepeat has no effect on toggle buttons + QVERIFY( testWidget->isCheckable() ); +} + +void tst_QCheckBox::toggle() +{ + bool cur_state; + cur_state = testWidget->isChecked(); + testWidget->toggle(); + QVERIFY( cur_state != testWidget->isChecked() ); + + cur_state = testWidget->isChecked(); + testWidget->toggle(); + QVERIFY( cur_state != testWidget->isChecked() ); + + cur_state = testWidget->isChecked(); + testWidget->toggle(); + QVERIFY( cur_state != testWidget->isChecked() ); +} + +void tst_QCheckBox::pressed() +{ + connect(testWidget, SIGNAL(pressed()), this, SLOT(onPressed())); + connect(testWidget, SIGNAL(released()), this, SLOT(onReleased())); + press_count = 0; + release_count = 0; + testWidget->setDown(FALSE); + QVERIFY( !testWidget->isChecked() ); + + QTest::keyPress( testWidget, Qt::Key_Space ); + QTest::qWait(100); + QVERIFY( press_count == 1 ); + QVERIFY( release_count == 0 ); + QVERIFY( !testWidget->isChecked() ); + + QTest::keyRelease( testWidget, Qt::Key_Space ); + QTest::qWait(100); + QVERIFY( press_count == 1 ); + QVERIFY( release_count == 1 ); + QVERIFY( testWidget->isChecked() ); +} + +void tst_QCheckBox::toggled() +{ + connect(testWidget, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool))); + click_count = 0; + toggle_count = 0; + testWidget->toggle(); + QCOMPARE( toggle_count, (uint)1 ); + + testWidget->toggle(); + QCOMPARE( toggle_count, (uint)2 ); + + testWidget->toggle(); + QCOMPARE( toggle_count, (uint)3 ); + + QCOMPARE( click_count, (uint)0 ); +} + +void tst_QCheckBox::onStateChanged( int state ) +{ + cur_state = state; +} + +void tst_QCheckBox::stateChanged() +{ + QSignalSpy stateChangedSpy(testWidget, SIGNAL(stateChanged(int))); + connect(testWidget, SIGNAL(stateChanged(int)), this, SLOT(onStateChanged(int))); + cur_state = -1; + testWidget->setChecked( TRUE ); + qApp->processEvents(); + QCOMPARE( cur_state, (int)2 ); + + cur_state = -1; + testWidget->setChecked( FALSE ); + qApp->processEvents(); + QCOMPARE( cur_state, (int)0 ); + + cur_state = -1; + testWidget->setCheckState(Qt::PartiallyChecked); + qApp->processEvents(); + QCOMPARE( cur_state, (int)1 ); + + QCOMPARE(stateChangedSpy.count(), 3); + testWidget->setCheckState(Qt::PartiallyChecked); + qApp->processEvents(); + QCOMPARE(stateChangedSpy.count(), 3); +} + +void tst_QCheckBox::isToggleButton() +{ + QVERIFY( testWidget->isCheckable() ); +} + +void tst_QCheckBox::foregroundRole() +{ + QVERIFY(testWidget->foregroundRole() == QPalette::WindowText); +} + +void tst_QCheckBox::minimumSizeHint() +{ + QCheckBox box(tr("CheckBox's sizeHint is the same as it's minimumSizeHint")); + QCOMPARE(box.sizeHint(), box.minimumSizeHint()); +} + +QTEST_MAIN(tst_QCheckBox) +#include "tst_qcheckbox.moc" diff --git a/tests/auto/widgets/widgets/qcombobox/.gitignore b/tests/auto/widgets/widgets/qcombobox/.gitignore new file mode 100644 index 0000000000..0db112206b --- /dev/null +++ b/tests/auto/widgets/widgets/qcombobox/.gitignore @@ -0,0 +1 @@ +tst_qcombobox diff --git a/tests/auto/widgets/widgets/qcombobox/qcombobox.pro b/tests/auto/widgets/widgets/qcombobox/qcombobox.pro new file mode 100644 index 0000000000..7f5b57c237 --- /dev/null +++ b/tests/auto/widgets/widgets/qcombobox/qcombobox.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +QT += widgets widgets-private gui-private core-private +SOURCES += tst_qcombobox.cpp diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp new file mode 100644 index 0000000000..cb4468f6f4 --- /dev/null +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -0,0 +1,2579 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include "qcombobox.h" +#include <private/qcombobox_p.h> + +#include <qfontcombobox.h> +#include <qdesktopwidget.h> +#include <qapplication.h> +#include <qpushbutton.h> +#include <qdialog.h> +#include <qevent.h> +#include <qlineedit.h> +#include <qlistview.h> +#include <qheaderview.h> +#include <qlistwidget.h> +#include <qtreewidget.h> +#include <qtablewidget.h> +#include <qscrollbar.h> +#include <qboxlayout.h> +#ifdef Q_WS_MAC +#include <qmacstyle_mac.h> +#elif defined Q_WS_X11 +#include <private/qt_x11_p.h> +#endif + +#include <qstandarditemmodel.h> +#include <qstringlistmodel.h> +#include <qcombobox.h> +#include <qpushbutton.h> +#include <qdialog.h> +#include <qstringlist.h> +#include <qvalidator.h> +#include <qcompleter.h> +#ifndef QT_NO_STYLE_CLEANLOOKS +#include <qcleanlooksstyle.h> +#endif +#include <qabstractitemview.h> +#include <qstyleditemdelegate.h> +#ifndef QT_NO_STYLE_WINDOWS +#include <qwindowsstyle.h> +#endif + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QComboBox : public QObject +{ + Q_OBJECT + +public: + tst_QComboBox(); + ~tst_QComboBox(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void getSetCheck(); + void ensureReturnIsIgnored(); + void setEditable(); + void setPalette(); + void sizeAdjustPolicy(); + void clear(); + void insertPolicy_data(); + void insertPolicy(); + void virtualAutocompletion(); + void autoCompletionCaseSensitivity(); + void hide(); + void currentIndex_data(); + void currentIndex(); + void insertItems_data(); + void insertItems(); + void insertItem_data(); + void insertItem(); + void insertOnCurrentIndex(); + void textpixmapdata_data(); + void textpixmapdata(); + void editTextChanged(); + void setModel(); + void modelDeleted(); + void setMaxCount(); + void setCurrentIndex(); + void convenienceViews(); + void findText_data(); + void findText(); + void flaggedItems_data(); + void flaggedItems(); + void pixmapIcon(); + void mouseWheel_data(); + void mouseWheel(); + void layoutDirection(); + void itemListPosition(); + void separatorItem_data(); + void separatorItem(); +#ifndef QT_NO_STYLE_CLEANLOOKS + void task190351_layout(); + void task191329_size(); +#endif + void task166349_setEditableOnReturn(); + void task190205_setModelAdjustToContents(); + void task248169_popupWithMinimalSize(); + void task247863_keyBoardSelection(); + void task220195_keyBoardSelection2(); + void setModelColumn(); + void noScrollbar_data(); + void noScrollbar(); + void setItemDelegate(); + void task253944_itemDelegateIsReset(); + void subControlRectsWithOffset_data(); + void subControlRectsWithOffset(); +#ifndef QT_NO_STYLE_WINDOWS + void task260974_menuItemRectangleForComboBoxPopup(); +#endif + void removeItem(); + void resetModel(); + void keyBoardNavigationWithMouse(); + void task_QTBUG_1071_changingFocusEmitsActivated(); + void maxVisibleItems(); + void task_QTBUG_10491_currentIndexAndModelColumn(); + +protected slots: + void onEditTextChanged( const QString &newString ); + +private: + QComboBox *testWidget; + QWidget *parent; + QPushButton* ok; + int editTextCount; + QString editText; +}; + +class MyAbstractItemDelegate : public QAbstractItemDelegate +{ +public: + MyAbstractItemDelegate() : QAbstractItemDelegate() {}; + void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const {} + QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(); } +}; + +class MyAbstractItemModel: public QAbstractItemModel +{ +public: + MyAbstractItemModel() : QAbstractItemModel() {}; + QModelIndex index(int, int, const QModelIndex &) const { return QModelIndex(); } + QModelIndex parent(const QModelIndex &) const { return QModelIndex(); } + int rowCount(const QModelIndex &) const { return 0; } + int columnCount(const QModelIndex &) const { return 0; } + bool hasChildren(const QModelIndex &) const { return false; } + QVariant data(const QModelIndex &, int) const { return QVariant(); } + bool setData(const QModelIndex &, const QVariant &, int) { return false; } + bool insertRows(int, int, const QModelIndex &) { return false; } + bool insertColumns(int, int, const QModelIndex &) { return false; } + void setPersistent(const QModelIndex &, const QModelIndex &) {} + bool removeRows (int, int, const QModelIndex &) { return false; } + bool removeColumns(int, int, const QModelIndex &) { return false; } + void reset() {} +}; + +class MyAbstractItemView : public QAbstractItemView +{ +public: + MyAbstractItemView() : QAbstractItemView() {} + QRect visualRect(const QModelIndex &) const { return QRect(); } + void scrollTo(const QModelIndex &, ScrollHint) {} + QModelIndex indexAt(const QPoint &) const { return QModelIndex(); } +protected: + QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers) { return QModelIndex(); } + int horizontalOffset() const { return 0; } + int verticalOffset() const { return 0; } + bool isIndexHidden(const QModelIndex &) const { return false; } + void setSelection(const QRect &, QItemSelectionModel::SelectionFlags) {} + QRegion visualRegionForSelection(const QItemSelection &) const { return QRegion(); } +}; + +// Testing get/set functions +void tst_QComboBox::getSetCheck() +{ + QComboBox obj1; + // int QComboBox::maxVisibleItems() + // void QComboBox::setMaxVisibleItems(int) + obj1.setMaxVisibleItems(100); + QCOMPARE(100, obj1.maxVisibleItems()); + obj1.setMaxVisibleItems(0); + QCOMPARE(obj1.maxVisibleItems(), 0); + QTest::ignoreMessage(QtWarningMsg, "QComboBox::setMaxVisibleItems: " + "Invalid max visible items (-2147483648) must be >= 0"); + obj1.setMaxVisibleItems(INT_MIN); + QCOMPARE(obj1.maxVisibleItems(), 0); // Cannot be set to something negative => old value + obj1.setMaxVisibleItems(INT_MAX); + QCOMPARE(INT_MAX, obj1.maxVisibleItems()); + + // int QComboBox::maxCount() + // void QComboBox::setMaxCount(int) + obj1.setMaxCount(0); + QCOMPARE(0, obj1.maxCount()); +#ifndef QT_DEBUG + QTest::ignoreMessage(QtWarningMsg, "QComboBox::setMaxCount: Invalid count (-2147483648) must be >= 0"); + obj1.setMaxCount(INT_MIN); + QCOMPARE(0, obj1.maxCount()); // Setting a value below 0 makes no sense, and shouldn't be allowed +#endif + obj1.setMaxCount(INT_MAX); + QCOMPARE(INT_MAX, obj1.maxCount()); + + // bool QComboBox::autoCompletion() + // void QComboBox::setAutoCompletion(bool) + obj1.setAutoCompletion(false); + QCOMPARE(false, obj1.autoCompletion()); + obj1.setAutoCompletion(true); + QCOMPARE(true, obj1.autoCompletion()); + + // bool QComboBox::duplicatesEnabled() + // void QComboBox::setDuplicatesEnabled(bool) + obj1.setDuplicatesEnabled(false); + QCOMPARE(false, obj1.duplicatesEnabled()); + obj1.setDuplicatesEnabled(true); + QCOMPARE(true, obj1.duplicatesEnabled()); + + // InsertPolicy QComboBox::insertPolicy() + // void QComboBox::setInsertPolicy(InsertPolicy) + obj1.setInsertPolicy(QComboBox::InsertPolicy(QComboBox::NoInsert)); + QCOMPARE(QComboBox::InsertPolicy(QComboBox::NoInsert), obj1.insertPolicy()); + obj1.setInsertPolicy(QComboBox::InsertPolicy(QComboBox::InsertAtTop)); + QCOMPARE(QComboBox::InsertPolicy(QComboBox::InsertAtTop), obj1.insertPolicy()); + obj1.setInsertPolicy(QComboBox::InsertPolicy(QComboBox::InsertAtCurrent)); + QCOMPARE(QComboBox::InsertPolicy(QComboBox::InsertAtCurrent), obj1.insertPolicy()); + obj1.setInsertPolicy(QComboBox::InsertPolicy(QComboBox::InsertAtBottom)); + QCOMPARE(QComboBox::InsertPolicy(QComboBox::InsertAtBottom), obj1.insertPolicy()); + obj1.setInsertPolicy(QComboBox::InsertPolicy(QComboBox::InsertAfterCurrent)); + QCOMPARE(QComboBox::InsertPolicy(QComboBox::InsertAfterCurrent), obj1.insertPolicy()); + obj1.setInsertPolicy(QComboBox::InsertPolicy(QComboBox::InsertBeforeCurrent)); + QCOMPARE(QComboBox::InsertPolicy(QComboBox::InsertBeforeCurrent), obj1.insertPolicy()); + obj1.setInsertPolicy(QComboBox::InsertPolicy(QComboBox::InsertAlphabetically)); + QCOMPARE(QComboBox::InsertPolicy(QComboBox::InsertAlphabetically), obj1.insertPolicy()); + + // SizeAdjustPolicy QComboBox::sizeAdjustPolicy() + // void QComboBox::setSizeAdjustPolicy(SizeAdjustPolicy) + obj1.setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToContents)); + QCOMPARE(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToContents), obj1.sizeAdjustPolicy()); + obj1.setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow)); + QCOMPARE(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToContentsOnFirstShow), obj1.sizeAdjustPolicy()); + obj1.setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength)); + QCOMPARE(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength), obj1.sizeAdjustPolicy()); + obj1.setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon)); + QCOMPARE(QComboBox::SizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon), obj1.sizeAdjustPolicy()); + + // int QComboBox::minimumContentsLength() + // void QComboBox::setMinimumContentsLength(int) + obj1.setMinimumContentsLength(0); + QCOMPARE(0, obj1.minimumContentsLength()); + obj1.setMinimumContentsLength(100); + QCOMPARE(100, obj1.minimumContentsLength()); + obj1.setMinimumContentsLength(INT_MIN); + QCOMPARE(100, obj1.minimumContentsLength()); // Cannot be set to something negative => old value + obj1.setMinimumContentsLength(INT_MAX); + QCOMPARE(INT_MAX, obj1.minimumContentsLength()); + + // QLineEdit * QComboBox::lineEdit() + // void QComboBox::setLineEdit(QLineEdit *) + QLineEdit *var8 = new QLineEdit(0); + obj1.setLineEdit(var8); + QCOMPARE(var8, obj1.lineEdit()); + QTest::ignoreMessage(QtWarningMsg, "QComboBox::setLineEdit: cannot set a 0 line edit"); + obj1.setLineEdit((QLineEdit *)0); + QCOMPARE(var8, obj1.lineEdit()); + // delete var8; // No delete, since QComboBox takes ownership + + // const QValidator * QComboBox::validator() + // void QComboBox::setValidator(const QValidator *) + QIntValidator *var9 = new QIntValidator(0); + obj1.setValidator(var9); + QCOMPARE(obj1.validator(), (const QValidator *)var9); + obj1.setValidator((QValidator *)0); + QCOMPARE(obj1.validator(), (const QValidator *)0); + delete var9; + + // QAbstractItemDelegate * QComboBox::itemDelegate() + // void QComboBox::setItemDelegate(QAbstractItemDelegate *) + MyAbstractItemDelegate *var10 = new MyAbstractItemDelegate; + obj1.setItemDelegate(var10); + QCOMPARE(obj1.itemDelegate(), (QAbstractItemDelegate *)var10); + QTest::ignoreMessage(QtWarningMsg, "QComboBox::setItemDelegate: cannot set a 0 delegate"); + obj1.setItemDelegate((QAbstractItemDelegate *)0); + QCOMPARE(obj1.itemDelegate(), (QAbstractItemDelegate *)var10); + // delete var10; // No delete, since QComboBox takes ownership + + // QAbstractItemModel * QComboBox::model() + // void QComboBox::setModel(QAbstractItemModel *) + MyAbstractItemModel *var11 = new MyAbstractItemModel; + obj1.setModel(var11); + QCOMPARE(obj1.model(), (QAbstractItemModel *)var11); + QTest::ignoreMessage(QtWarningMsg, "QComboBox::setModel: cannot set a 0 model"); + obj1.setModel((QAbstractItemModel *)0); + QCOMPARE(obj1.model(), (QAbstractItemModel *)var11); + delete var11; + obj1.model(); + + // int QComboBox::modelColumn() + // void QComboBox::setModelColumn(int) + obj1.setModelColumn(0); + QCOMPARE(0, obj1.modelColumn()); + obj1.setModelColumn(INT_MIN); +// QCOMPARE(0, obj1.modelColumn()); // Cannot be set to something negative => column 0 + obj1.setModelColumn(INT_MAX); + QCOMPARE(INT_MAX, obj1.modelColumn()); + obj1.setModelColumn(0); // back to normal + + // QAbstractItemView * QComboBox::view() + // void QComboBox::setView(QAbstractItemView *) + MyAbstractItemView *var13 = new MyAbstractItemView; + obj1.setView(var13); + QCOMPARE(obj1.view(), (QAbstractItemView *)var13); + QTest::ignoreMessage(QtWarningMsg, "QComboBox::setView: cannot set a 0 view"); + obj1.setView((QAbstractItemView *)0); + QCOMPARE(obj1.view(), (QAbstractItemView *)var13); + delete var13; + + // int QComboBox::currentIndex() + // void QComboBox::setCurrentIndex(int) + obj1.setEditable(false); + obj1.setCurrentIndex(0); + QCOMPARE(-1, obj1.currentIndex()); + obj1.setCurrentIndex(INT_MIN); + QCOMPARE(-1, obj1.currentIndex()); + obj1.setCurrentIndex(INT_MAX); + QCOMPARE(-1, obj1.currentIndex()); + obj1.addItems(QStringList() << "1" << "2" << "3" << "4" << "5"); + obj1.setCurrentIndex(0); + QCOMPARE(0, obj1.currentIndex()); // Valid + obj1.setCurrentIndex(INT_MIN); + QCOMPARE(-1, obj1.currentIndex()); // Invalid => -1 + obj1.setCurrentIndex(4); + QCOMPARE(4, obj1.currentIndex()); // Valid + obj1.setCurrentIndex(INT_MAX); + QCOMPARE(-1, obj1.currentIndex()); // Invalid => -1 +} + +typedef QList<QVariant> VariantList; +typedef QList<QIcon> IconList; + +Q_DECLARE_METATYPE(VariantList) +Q_DECLARE_METATYPE(IconList) +Q_DECLARE_METATYPE(QComboBox::InsertPolicy) + +tst_QComboBox::tst_QComboBox() +{ + qRegisterMetaType<QModelIndex>("QModelIndex"); + parent = 0; +} + +tst_QComboBox::~tst_QComboBox() +{ +} + + +void tst_QComboBox::initTestCase() +{ + // Create the test class + parent = new QWidget(0, Qt::Window); + parent->setObjectName("parent"); + parent->resize(400, 400); + testWidget = new QComboBox(parent); + testWidget->setObjectName("testObject"); + testWidget->setGeometry(0, 0, 100, 100); + editTextCount = 0; + editText.clear(); + connect(testWidget, SIGNAL(editTextChanged(const QString&)), + this, SLOT(onEditTextChanged(const QString&))); + parent->show(); +} + +void tst_QComboBox::cleanupTestCase() +{ + delete parent; + parent = 0; +} + + +void tst_QComboBox::init() +{ + // all tests starts with a clean non-editable combobox + testWidget->setEditable(false); + testWidget->clear(); +#ifdef Q_OS_WINCE //disable magic for WindowsCE + qApp->setAutoMaximizeThreshold(-1); +#endif +} + +void tst_QComboBox::cleanup() +{ + //nothing +} + + +void tst_QComboBox::setEditable() +{ + // make sure we have no lineedit + QVERIFY(!testWidget->lineEdit()); + // test setEditable(true) + testWidget->setEditable(true); + QVERIFY(testWidget->lineEdit()); + testWidget->addItem("foo"); + QCOMPARE(testWidget->lineEdit()->text(), QString("foo")); + // test setEditable(false) + + QLineEdit *lineEdit = testWidget->lineEdit(); + // line edit is visible when combobox is editable + QVERIFY(lineEdit->isVisible()); + testWidget->setEditable(false); + QVERIFY(!testWidget->lineEdit()); + // line edit should have been explicitly hidden when editable was turned off + QVERIFY(!lineEdit->isVisible()); +} + + +void tst_QComboBox::setPalette() +{ +#ifdef Q_WS_MAC + if (qobject_cast<QMacStyle *>(testWidget->style())) { + QSKIP("This test doesn't make sense for pixmap-based styles", SkipAll); + } +#endif + QPalette pal = testWidget->palette(); + pal.setColor(QPalette::Base, Qt::red); + testWidget->setPalette(pal); + testWidget->setEditable(!testWidget->isEditable()); + + pal.setColor(QPalette::Base, Qt::blue); + testWidget->setPalette(pal); + + const QObjectList comboChildren = testWidget->children(); + for (int i = 0; i < comboChildren.size(); ++i) { + QObject *o = comboChildren.at(i); + if (o->isWidgetType()) { + QVERIFY(((QWidget*)o)->palette() == pal); + } + } + + testWidget->setEditable(true); + pal.setColor(QPalette::Base, Qt::red); + //Setting it on the lineedit should be separate form the combo + testWidget->lineEdit()->setPalette(pal); + QVERIFY(testWidget->palette() != pal); + QVERIFY(testWidget->lineEdit()->palette() == pal); + pal.setColor(QPalette::Base, Qt::green); + //Setting it on the combo directly should override lineedit + testWidget->setPalette(pal); + QVERIFY(testWidget->palette() == pal); + QVERIFY(testWidget->lineEdit()->palette() == pal); +} + +void tst_QComboBox::sizeAdjustPolicy() +{ + // test that adding new items will not change the sizehint for AdjustToContentsOnFirstShow + QVERIFY(!testWidget->count()); + QVERIFY(testWidget->sizeAdjustPolicy() == QComboBox::AdjustToContentsOnFirstShow); + QVERIFY(testWidget->isVisible()); + QSize firstShow = testWidget->sizeHint(); + testWidget->addItem("normal item"); + QCOMPARE(testWidget->sizeHint(), firstShow); + + // check that with minimumContentsLength/AdjustToMinimumContentsLength sizehint changes + testWidget->setMinimumContentsLength(30); + QCOMPARE(testWidget->sizeHint(), firstShow); + testWidget->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength); + QSize minimumContentsLength = testWidget->sizeHint(); + QVERIFY(minimumContentsLength.width() > firstShow.width()); + testWidget->setMinimumContentsLength(60); + QVERIFY(minimumContentsLength.width() < testWidget->sizeHint().width()); + + // check that with minimumContentsLength/AdjustToMinimumContentsLengthWithIcon sizehint changes + testWidget->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); + testWidget->setMinimumContentsLength(30); + minimumContentsLength = testWidget->sizeHint(); + QVERIFY(minimumContentsLength.width() > firstShow.width()); + testWidget->setMinimumContentsLength(60); + QVERIFY(minimumContentsLength.width() < testWidget->sizeHint().width()); + minimumContentsLength = testWidget->sizeHint(); + testWidget->setIconSize(QSize(128,128)); + QVERIFY(minimumContentsLength.width() < testWidget->sizeHint().width()); + + // check AdjustToContents changes with content + testWidget->setSizeAdjustPolicy(QComboBox::AdjustToContents); + QSize content = testWidget->sizeHint(); + testWidget->addItem("small"); + QCOMPARE(testWidget->sizeHint(), content); + testWidget->addItem("looooooooooooooooooooooong item"); + // minimumContentsLength() > sizeof("looooooooooooooooooooooong item"), so the sizeHint() + // stays the same + QCOMPARE(testWidget->sizeHint(), content); + // over 60 characters (cf. setMinimumContentsLength() call above) + testWidget->addItem("loooooooooooooooooooooooooooooooooooooooooooooo" + "ooooooooooooooooooooooooooooooooooooooooooooooo" + "ooooooooooooooooooooooooooooong item"); + QVERIFY(testWidget->sizeHint().width() > content.width()); + + // check AdjustToContents also shrinks when item changes + content = testWidget->sizeHint(); + for (int i=0; i<testWidget->count(); ++i) + testWidget->setItemText(i, "XXXXXXXXXX"); + QVERIFY(testWidget->sizeHint().width() < content.width()); + + // check AdjustToContents shrinks when items are removed + content = testWidget->sizeHint(); + while (testWidget->count()) + testWidget->removeItem(0); + QCOMPARE(testWidget->sizeHint(), content); + testWidget->setMinimumContentsLength(0); + QVERIFY(testWidget->sizeHint().width() < content.width()); +} + +void tst_QComboBox::clear() +{ + // first non editable combobox + testWidget->addItem("foo"); + testWidget->addItem("bar"); + QVERIFY(testWidget->count() > 0); + QCOMPARE(testWidget->currentIndex(), 0); + + testWidget->clear(); + QCOMPARE(testWidget->count(), 0); + QCOMPARE(testWidget->currentIndex(), -1); + QVERIFY(testWidget->currentText().isEmpty()); + + // then editable combobox + testWidget->clear(); + testWidget->setEditable(true); + testWidget->addItem("foo"); + testWidget->addItem("bar"); + QVERIFY(testWidget->count() > 0); + QCOMPARE(testWidget->currentIndex(), 0); + QVERIFY(testWidget->lineEdit()); + QVERIFY(!testWidget->lineEdit()->text().isEmpty()); + testWidget->clear(); + QCOMPARE(testWidget->count(), 0); + QCOMPARE(testWidget->currentIndex(), -1); + QVERIFY(testWidget->currentText().isEmpty()); + QVERIFY(testWidget->lineEdit()->text().isEmpty()); +} + +void tst_QComboBox::insertPolicy_data() +{ + QTest::addColumn<QStringList>("initialEntries"); + QTest::addColumn<QComboBox::InsertPolicy>("insertPolicy"); + QTest::addColumn<int>("currentIndex"); + QTest::addColumn<QString>("userInput"); + QTest::addColumn<QStringList>("result"); + + /* Each insertPolicy should test at least: + no initial entries + one initial entry + five initial entries, current is first item + five initial entries, current is third item + five initial entries, current is last item + */ + + /* QComboBox::NoInsert - the string will not be inserted into the combobox. + QComboBox::InsertAtTop - insert the string as the first item in the combobox. + QComboBox::InsertAtCurrent - replace the previously selected item with the string the user has entered. + QComboBox::InsertAtBottom - insert the string as the last item in the combobox. + QComboBox::InsertAfterCurrent - insert the string after the previously selected item. + QComboBox::InsertBeforeCurrent - insert the string before the previously selected item. + QComboBox::InsertAlphabetically - insert the string at the alphabetic position. + */ + QStringList initial; + QStringList oneEntry("One"); + QStringList fiveEntries; + fiveEntries << "One" << "Two" << "Three" << "Four" << "Five"; + QString input("insert"); + + { + QTest::newRow("NoInsert-NoInitial") << initial << QComboBox::NoInsert << 0 << input << initial; + QTest::newRow("NoInsert-OneInitial") << oneEntry << QComboBox::NoInsert << 0 << input << oneEntry; + QTest::newRow("NoInsert-FiveInitial-FirstCurrent") << fiveEntries << QComboBox::NoInsert << 0 << input << fiveEntries; + QTest::newRow("NoInsert-FiveInitial-ThirdCurrent") << fiveEntries << QComboBox::NoInsert << 2 << input << fiveEntries; + QTest::newRow("NoInsert-FiveInitial-LastCurrent") << fiveEntries << QComboBox::NoInsert << 4 << input << fiveEntries; + } + + { + QStringList initialAtTop("insert"); + QStringList oneAtTop; + oneAtTop << "insert" << "One"; + QStringList fiveAtTop; + fiveAtTop << "insert" << "One" << "Two" << "Three" << "Four" << "Five"; + + QTest::newRow("AtTop-NoInitial") << initial << QComboBox::InsertAtTop << 0 << input << initialAtTop; + QTest::newRow("AtTop-OneInitial") << oneEntry << QComboBox::InsertAtTop << 0 << input << oneAtTop; + QTest::newRow("AtTop-FiveInitial-FirstCurrent") << fiveEntries << QComboBox::InsertAtTop << 0 << input << fiveAtTop; + QTest::newRow("AtTop-FiveInitial-ThirdCurrent") << fiveEntries << QComboBox::InsertAtTop << 2 << input << fiveAtTop; + QTest::newRow("AtTop-FiveInitial-LastCurrent") << fiveEntries << QComboBox::InsertAtTop << 4 << input << fiveAtTop; + } + + { + QStringList initialAtCurrent("insert"); + QStringList oneAtCurrent("insert"); + QStringList fiveAtCurrentFirst; + fiveAtCurrentFirst << "insert" << "Two" << "Three" << "Four" << "Five"; + QStringList fiveAtCurrentThird; + fiveAtCurrentThird << "One" << "Two" << "insert" << "Four" << "Five"; + QStringList fiveAtCurrentLast; + fiveAtCurrentLast << "One" << "Two" << "Three" << "Four" << "insert"; + + QTest::newRow("AtCurrent-NoInitial") << initial << QComboBox::InsertAtCurrent << 0 << input << initialAtCurrent; + QTest::newRow("AtCurrent-OneInitial") << oneEntry << QComboBox::InsertAtCurrent << 0 << input << oneAtCurrent; + QTest::newRow("AtCurrent-FiveInitial-FirstCurrent") << fiveEntries << QComboBox::InsertAtCurrent << 0 << input << fiveAtCurrentFirst; + QTest::newRow("AtCurrent-FiveInitial-ThirdCurrent") << fiveEntries << QComboBox::InsertAtCurrent << 2 << input << fiveAtCurrentThird; + QTest::newRow("AtCurrent-FiveInitial-LastCurrent") << fiveEntries << QComboBox::InsertAtCurrent << 4 << input << fiveAtCurrentLast; + } + + { + QStringList initialAtBottom("insert"); + QStringList oneAtBottom; + oneAtBottom << "One" << "insert"; + QStringList fiveAtBottom; + fiveAtBottom << "One" << "Two" << "Three" << "Four" << "Five" << "insert"; + + QTest::newRow("AtBottom-NoInitial") << initial << QComboBox::InsertAtBottom << 0 << input << initialAtBottom; + QTest::newRow("AtBottom-OneInitial") << oneEntry << QComboBox::InsertAtBottom << 0 << input << oneAtBottom; + QTest::newRow("AtBottom-FiveInitial-FirstCurrent") << fiveEntries << QComboBox::InsertAtBottom << 0 << input << fiveAtBottom; + QTest::newRow("AtBottom-FiveInitial-ThirdCurrent") << fiveEntries << QComboBox::InsertAtBottom << 2 << input << fiveAtBottom; + QTest::newRow("AtBottom-FiveInitial-LastCurrent") << fiveEntries << QComboBox::InsertAtBottom << 4 << input << fiveAtBottom; + } + + { + QStringList initialAfterCurrent("insert"); + QStringList oneAfterCurrent; + oneAfterCurrent << "One" << "insert"; + QStringList fiveAfterCurrentFirst; + fiveAfterCurrentFirst << "One" << "insert" << "Two" << "Three" << "Four" << "Five"; + QStringList fiveAfterCurrentThird; + fiveAfterCurrentThird << "One" << "Two" << "Three" << "insert" << "Four" << "Five"; + QStringList fiveAfterCurrentLast; + fiveAfterCurrentLast << "One" << "Two" << "Three" << "Four" << "Five" << "insert"; + + QTest::newRow("AfterCurrent-NoInitial") << initial << QComboBox::InsertAfterCurrent << 0 << input << initialAfterCurrent; + QTest::newRow("AfterCurrent-OneInitial") << oneEntry << QComboBox::InsertAfterCurrent << 0 << input << oneAfterCurrent; + QTest::newRow("AfterCurrent-FiveInitial-FirstCurrent") << fiveEntries << QComboBox::InsertAfterCurrent << 0 << input << fiveAfterCurrentFirst; + QTest::newRow("AfterCurrent-FiveInitial-ThirdCurrent") << fiveEntries << QComboBox::InsertAfterCurrent << 2 << input << fiveAfterCurrentThird; + QTest::newRow("AfterCurrent-FiveInitial-LastCurrent") << fiveEntries << QComboBox::InsertAfterCurrent << 4 << input << fiveAfterCurrentLast; + } + + { + QStringList initialBeforeCurrent("insert"); + QStringList oneBeforeCurrent; + oneBeforeCurrent << "insert" << "One"; + QStringList fiveBeforeCurrentFirst; + fiveBeforeCurrentFirst << "insert" << "One" << "Two" << "Three" << "Four" << "Five"; + QStringList fiveBeforeCurrentThird; + fiveBeforeCurrentThird << "One" << "Two" << "insert" << "Three" << "Four" << "Five"; + QStringList fiveBeforeCurrentLast; + fiveBeforeCurrentLast << "One" << "Two" << "Three" << "Four" << "insert" << "Five"; + + QTest::newRow("BeforeCurrent-NoInitial") << initial << QComboBox::InsertBeforeCurrent << 0 << input << initialBeforeCurrent; + QTest::newRow("BeforeCurrent-OneInitial") << oneEntry << QComboBox::InsertBeforeCurrent << 0 << input << oneBeforeCurrent; + QTest::newRow("BeforeCurrent-FiveInitial-FirstCurrent") << fiveEntries << QComboBox::InsertBeforeCurrent << 0 << input << fiveBeforeCurrentFirst; + QTest::newRow("BeforeCurrent-FiveInitial-ThirdCurrent") << fiveEntries << QComboBox::InsertBeforeCurrent << 2 << input << fiveBeforeCurrentThird; + QTest::newRow("BeforeCurrent-FiveInitial-LastCurrent") << fiveEntries << QComboBox::InsertBeforeCurrent << 4 << input << fiveBeforeCurrentLast; + } + + { + oneEntry.clear(); + oneEntry << "foobar"; + fiveEntries.clear(); + fiveEntries << "bar" << "foo" << "initial" << "Item" << "stamp"; + + QStringList initialAlphabetically("insert"); + QStringList oneAlphabetically; + oneAlphabetically << "foobar" << "insert"; + QStringList fiveAlphabetically; + fiveAlphabetically << "bar" << "foo" << "initial" << "insert" << "Item" << "stamp"; + + QTest::newRow("Alphabetically-NoInitial") << initial << QComboBox::InsertAlphabetically << 0 << input << initialAlphabetically; + QTest::newRow("Alphabetically-OneInitial") << oneEntry << QComboBox::InsertAlphabetically << 0 << input << oneAlphabetically; + QTest::newRow("Alphabetically-FiveInitial-FirstCurrent") << fiveEntries << QComboBox::InsertAlphabetically << 0 << input << fiveAlphabetically; + QTest::newRow("Alphabetically-FiveInitial-ThirdCurrent") << fiveEntries << QComboBox::InsertAlphabetically << 2 << input << fiveAlphabetically; + QTest::newRow("Alphabetically-FiveInitial-LastCurrent") << fiveEntries << QComboBox::InsertAlphabetically << 4 << input << fiveAlphabetically; + } +} + +void tst_QComboBox::insertPolicy() +{ + QFETCH(QStringList, initialEntries); + QFETCH(QComboBox::InsertPolicy, insertPolicy); + QFETCH(int, currentIndex); + QFETCH(QString, userInput); + QFETCH(QStringList, result); + + testWidget->clear(); + testWidget->setInsertPolicy(insertPolicy); + testWidget->addItems(initialEntries); + testWidget->setEditable(true); + if (initialEntries.count() > 0) + testWidget->setCurrentIndex(currentIndex); + + // clear + QTest::mouseDClick(testWidget->lineEdit(), Qt::LeftButton); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Delete); + + QTest::keyClicks(testWidget->lineEdit(), userInput); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Return); + + // First check that there is the right number of entries, or + // we may unwittingly pass + QVERIFY((int)result.count() == testWidget->count()); + + // No need to compare if there are no strings to compare + if (result.count() > 0) { + for (int i=0; i<testWidget->count(); ++i) { + QCOMPARE(testWidget->itemText(i), result.at(i)); + } + } +} + +// Apps running with valgrind are not fast enough. +void tst_QComboBox::virtualAutocompletion() +{ + testWidget->clear(); + testWidget->setAutoCompletion(true); + testWidget->addItem("Foo"); + testWidget->addItem("Bar"); + testWidget->addItem("Boat"); + testWidget->addItem("Boost"); + testWidget->clearEditText(); + + // We need to set the keyboard input interval to a higher value + // as the processEvent() call takes too much time, so it restarts + // the keyboard search then +#if defined(QT_ARCH_ARM) || defined(QT_ARCH_MIPS) + int oldInterval = QApplication::keyboardInputInterval(); + QApplication::setKeyboardInputInterval(1500); +#endif + + // NOTE: + // Cannot use keyClick for this test, as it simulates keyclicks too well + // The virtual keyboards we're trying to catch here, do not perform that + // well, and send a keypress & keyrelease right after each other. + // This provokes the actual error, as there's no events in between to do + // the text completion. + QKeyEvent kp1(QEvent::KeyPress, Qt::Key_B, 0, "b"); + QKeyEvent kr1(QEvent::KeyRelease, Qt::Key_B, 0, "b"); + QApplication::sendEvent(testWidget, &kp1); + QApplication::sendEvent(testWidget, &kr1); + + qApp->processEvents(); // Process events to trigger autocompletion + QTRY_VERIFY(testWidget->currentIndex() == 1); + + QKeyEvent kp2(QEvent::KeyPress, Qt::Key_O, 0, "o"); + QKeyEvent kr2(QEvent::KeyRelease, Qt::Key_O, 0, "o"); + + QApplication::sendEvent(testWidget, &kp2); + QApplication::sendEvent(testWidget, &kr2); + + qApp->processEvents(); // Process events to trigger autocompletion + QTRY_COMPARE(testWidget->currentIndex(), 2); + + QApplication::sendEvent(testWidget, &kp2); + QApplication::sendEvent(testWidget, &kr2); + qApp->processEvents(); // Process events to trigger autocompletion + QTRY_COMPARE(testWidget->currentIndex(), 3); +#if defined(QT_ARCH_ARM) || defined(QT_ARCH_MIPS) + QApplication::setKeyboardInputInterval(oldInterval); +#endif +} + +void tst_QComboBox::autoCompletionCaseSensitivity() +{ + //we have put the focus because the completer + //is only used when the widget actually has the focus + testWidget->setFocus(); + qApp->setActiveWindow(testWidget); + QTRY_COMPARE(qApp->focusWidget(), (QWidget *)testWidget); + + testWidget->clear(); + testWidget->setAutoCompletion(true); + testWidget->addItem("Cow"); + testWidget->addItem("irrelevant1"); + testWidget->addItem("aww"); + testWidget->addItem("A*"); + testWidget->addItem("irrelevant2"); + testWidget->addItem("aBCDEF"); + testWidget->addItem("irrelevant3"); + testWidget->addItem("abcdef"); + testWidget->addItem("abCdef"); + testWidget->setEditable(true); + + // case insensitive + testWidget->clearEditText(); + QSignalSpy spyReturn(testWidget, SIGNAL(activated(int))); + testWidget->setAutoCompletionCaseSensitivity(Qt::CaseInsensitive); + QVERIFY(testWidget->autoCompletionCaseSensitivity() == Qt::CaseInsensitive); + + QTest::keyClick(testWidget->lineEdit(), Qt::Key_A); + qApp->processEvents(); + QCOMPARE(testWidget->currentText(), QString("aww")); + QCOMPARE(spyReturn.count(), 0); + + QTest::keyClick(testWidget->lineEdit(), Qt::Key_B); + qApp->processEvents(); + // autocompletions preserve userkey-case from 4.2 + QCOMPARE(testWidget->currentText(), QString("abCDEF")); + QCOMPARE(spyReturn.count(), 0); + + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Enter); + qApp->processEvents(); + QCOMPARE(testWidget->currentText(), QString("aBCDEF")); // case restored to item's case + QCOMPARE(spyReturn.count(), 1); + + testWidget->clearEditText(); + QTest::keyClick(testWidget->lineEdit(), 'c'); + QCOMPARE(testWidget->currentText(), QString("cow")); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Enter); + QCOMPARE(testWidget->currentText(), QString("Cow")); // case restored to item's case + + testWidget->clearEditText(); + QTest::keyClick(testWidget->lineEdit(), 'a'); + QTest::keyClick(testWidget->lineEdit(), '*'); + QCOMPARE(testWidget->currentText(), QString("a*")); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Enter); + QCOMPARE(testWidget->currentText(), QString("A*")); + + // case sensitive + testWidget->clearEditText(); + testWidget->setAutoCompletionCaseSensitivity(Qt::CaseSensitive); + QVERIFY(testWidget->autoCompletionCaseSensitivity() == Qt::CaseSensitive); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_A); + qApp->processEvents(); + QCOMPARE(testWidget->currentText(), QString("aww")); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_B); + qApp->processEvents(); + QCOMPARE(testWidget->currentText(), QString("abcdef")); + + testWidget->setCurrentIndex(0); // to reset the completion's "start" + testWidget->clearEditText(); + QTest::keyClick(testWidget->lineEdit(), 'a'); + QTest::keyClick(testWidget->lineEdit(), 'b'); + QCOMPARE(testWidget->currentText(), QString("abcdef")); + QTest::keyClick(testWidget->lineEdit(), 'C'); + qApp->processEvents(); + QCOMPARE(testWidget->currentText(), QString("abCdef")); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Enter); + qApp->processEvents(); + QCOMPARE(testWidget->currentText(), QString("abCdef")); // case restored to item's case + + testWidget->clearEditText(); + QTest::keyClick(testWidget->lineEdit(), 'c'); + QCOMPARE(testWidget->currentText(), QString("c")); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Backspace); + QTest::keyClick(testWidget->lineEdit(), 'C'); + QCOMPARE(testWidget->currentText(), QString("Cow")); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Enter); + QCOMPARE(testWidget->currentText(), QString("Cow")); + + testWidget->clearEditText(); + QTest::keyClick(testWidget->lineEdit(), 'a'); + QTest::keyClick(testWidget->lineEdit(), '*'); + QCOMPARE(testWidget->currentText(), QString("a*")); + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Enter); + QCOMPARE(testWidget->currentText(), QString("a*")); // A* not matched +} + +void tst_QComboBox::hide() +{ + testWidget->addItem("foo"); + testWidget->showPopup(); + //allow combobox effect to complete + QTRY_VERIFY(testWidget->view()); + QTRY_VERIFY(testWidget->view()->isVisible()); + testWidget->hidePopup(); + //allow combobox effect to complete + QTRY_VERIFY(!testWidget->view()->isVisible()); + testWidget->hide(); + QVERIFY(!testWidget->isVisible()); +} + + + +void tst_QComboBox::currentIndex_data() +{ + QTest::addColumn<QStringList>("initialItems"); + QTest::addColumn<int>("setCurrentIndex"); + QTest::addColumn<int>("removeIndex"); + QTest::addColumn<int>("insertIndex"); + QTest::addColumn<QString>("insertText"); + QTest::addColumn<int>("expectedCurrentIndex"); + QTest::addColumn<QString>("expectedCurrentText"); + QTest::addColumn<int>("expectedSignalCount"); + + QStringList initialItems; + int setCurrentIndex; + int removeIndex; + int insertIndex; + QString insertText; + int expectedCurrentIndex; + QString expectedCurrentText; + int expectedSignalCount; + + { + initialItems.clear(); + initialItems << "foo" << "bar"; + setCurrentIndex = -2; + removeIndex = -1; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = 0; + expectedCurrentText = "foo"; + expectedSignalCount = 1; + QTest::newRow("first added item is set to current if there is no current") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } + { + initialItems.clear(); + initialItems << "foo" << "bar"; + setCurrentIndex = 1; + removeIndex = -1; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = 1; + expectedCurrentText = "bar"; + expectedSignalCount = 2; + QTest::newRow("check that setting the index works") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + + } + { + initialItems.clear(); + initialItems << "foo" << "bar"; + setCurrentIndex = -1; // will invalidate the currentIndex + removeIndex = -1; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = -1; + expectedCurrentText = ""; + expectedSignalCount = 2; + QTest::newRow("check that isetting the index to -1 works") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + + } + { + initialItems.clear(); + initialItems << "foo"; + setCurrentIndex = 0; + removeIndex = 0; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = -1; + expectedCurrentText = ""; + expectedSignalCount = 2; + QTest::newRow("check that current index is invalid when removing the only item") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } + { + initialItems.clear(); + initialItems << "foo" << "bar"; + setCurrentIndex = 1; + removeIndex = 0; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = 0; + expectedCurrentText = "bar"; + expectedSignalCount = 3; + QTest::newRow("check that the current index follows the item when removing an item above") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + + } + { + initialItems.clear(); + initialItems << "foo" << "bar" << "baz"; + setCurrentIndex = 1; + removeIndex = 1; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = 1; + expectedCurrentText = "baz"; + expectedSignalCount = 3; + QTest::newRow("check that the current index uses the next item if current is removed") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } + { + initialItems.clear(); + initialItems << "foo" << "bar" << "baz"; + setCurrentIndex = 2; + removeIndex = 2; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = 1; + expectedCurrentText = "bar"; + expectedSignalCount = 3; + QTest::newRow("check that the current index is moved to the one before if current is removed") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } + { + initialItems.clear(); + initialItems << "foo" << "bar" << "baz"; + setCurrentIndex = 1; + removeIndex = 2; + insertIndex = -1; + insertText = ""; + expectedCurrentIndex = 1; + expectedCurrentText = "bar"; + expectedSignalCount = 2; + QTest::newRow("check that the current index is unchanged if you remove an item after") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } + { + initialItems.clear(); + initialItems << "foo" << "bar"; + setCurrentIndex = 1; + removeIndex = -1; + insertIndex = 0; + insertText = "baz"; + expectedCurrentIndex = 2; + expectedCurrentText = "bar"; + expectedSignalCount = 3; + QTest::newRow("check that the current index follows the item if you insert before current") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } + { + initialItems.clear(); + initialItems << "foo"; + setCurrentIndex = 0; + removeIndex = -1; + insertIndex = 0; + insertText = "bar"; + expectedCurrentIndex = 1; + expectedCurrentText = "foo"; + expectedSignalCount = 2; + QTest::newRow("check that the current index follows the item if you insert on the current") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } + { + initialItems.clear(); + initialItems << "foo"; + setCurrentIndex = 0; + removeIndex = -1; + insertIndex = 1; + insertText = "bar"; + expectedCurrentIndex = 0; + expectedCurrentText = "foo"; + expectedSignalCount = 1; + QTest::newRow("check that the current index stays the same if you insert after the current") + << initialItems << setCurrentIndex << removeIndex + << insertIndex << insertText << expectedCurrentIndex << expectedCurrentText + << expectedSignalCount; + } +} + +void tst_QComboBox::currentIndex() +{ + QFETCH(QStringList, initialItems); + QFETCH(int, setCurrentIndex); + QFETCH(int, removeIndex); + QFETCH(int, insertIndex); + QFETCH(QString, insertText); + QFETCH(int, expectedCurrentIndex); + QFETCH(QString, expectedCurrentText); + QFETCH(int, expectedSignalCount); + + // test both editable/non-editable combobox + for (int edit = 0; edit < 2; ++edit) { + testWidget->clear(); + testWidget->setEditable(edit ? true : false); + if (edit) + QVERIFY(testWidget->lineEdit()); + + // verify it is empty, has no current index and no current text + QCOMPARE(testWidget->count(), 0); + QCOMPARE(testWidget->currentIndex(), -1); + QVERIFY(testWidget->currentText().isEmpty()); + + // spy on currentIndexChanged + QSignalSpy indexChangedInt(testWidget, SIGNAL(currentIndexChanged(int))); + QSignalSpy indexChangedString(testWidget, SIGNAL(currentIndexChanged(const QString&))); + + // stuff items into it + foreach(QString text, initialItems) { + testWidget->addItem(text); + } + QCOMPARE(testWidget->count(), initialItems.count()); + + // set current index, remove and/or insert + if (setCurrentIndex >= -1) { + testWidget->setCurrentIndex(setCurrentIndex); + QCOMPARE(testWidget->currentIndex(), setCurrentIndex); + } + + if (removeIndex >= 0) + testWidget->removeItem(removeIndex); + if (insertIndex >= 0) + testWidget->insertItem(insertIndex, insertText); + + // compare with expected index and text + QCOMPARE(testWidget->currentIndex(), expectedCurrentIndex); + QCOMPARE(testWidget->currentText(), expectedCurrentText); + + // check that signal count is correct + QCOMPARE(indexChangedInt.count(), expectedSignalCount); + QCOMPARE(indexChangedString.count(), expectedSignalCount); + + // compare with last sent signal values + if (indexChangedInt.count()) + QCOMPARE(indexChangedInt.at(indexChangedInt.count() - 1).at(0).toInt(), + testWidget->currentIndex()); + if (indexChangedString.count()) + QCOMPARE(indexChangedString.at(indexChangedString.count() - 1).at(0).toString(), + testWidget->currentText()); + + if (edit) { + testWidget->setCurrentIndex(-1); + testWidget->setInsertPolicy(QComboBox::InsertAtBottom); + QTest::keyPress(testWidget, 'a'); + QTest::keyPress(testWidget, 'b'); + QCOMPARE(testWidget->currentText(), QString("ab")); + QCOMPARE(testWidget->currentIndex(), -1); + int numItems = testWidget->count(); + QTest::keyPress(testWidget, Qt::Key_Return); + QCOMPARE(testWidget->count(), numItems + 1); + QCOMPARE(testWidget->currentIndex(), numItems); + testWidget->setCurrentIndex(-1); + QTest::keyPress(testWidget, 'a'); + QTest::keyPress(testWidget, 'b'); + QCOMPARE(testWidget->currentIndex(), -1); + } + } +} + +void tst_QComboBox::insertItems_data() +{ + QTest::addColumn<QStringList>("initialItems"); + QTest::addColumn<QStringList>("insertedItems"); + QTest::addColumn<int>("insertIndex"); + QTest::addColumn<int>("expectedIndex"); + + QStringList initialItems; + QStringList insertedItems; + + initialItems << "foo" << "bar"; + insertedItems << "mongo"; + + QTest::newRow("prepend") << initialItems << insertedItems << 0 << 0; + QTest::newRow("prepend with negative value") << initialItems << insertedItems << -1 << 0; + QTest::newRow("append") << initialItems << insertedItems << initialItems.count() << initialItems.count(); + QTest::newRow("append with too high value") << initialItems << insertedItems << 999 << initialItems.count(); + QTest::newRow("insert") << initialItems << insertedItems << 1 << 1; +} + +void tst_QComboBox::insertItems() +{ + QFETCH(QStringList, initialItems); + QFETCH(QStringList, insertedItems); + QFETCH(int, insertIndex); + QFETCH(int, expectedIndex); + + testWidget->insertItems(0, initialItems); + QCOMPARE(testWidget->count(), initialItems.count()); + + testWidget->insertItems(insertIndex, insertedItems); + + QCOMPARE(testWidget->count(), initialItems.count() + insertedItems.count()); + for (int i=0; i<insertedItems.count(); ++i) + QCOMPARE(testWidget->itemText(expectedIndex + i), insertedItems.at(i)); +} + +void tst_QComboBox::insertItem_data() +{ + QTest::addColumn<QStringList>("initialItems"); + QTest::addColumn<int>("insertIndex"); + QTest::addColumn<QString>("itemLabel"); + QTest::addColumn<int>("expectedIndex"); + QTest::addColumn<bool>("editable"); + + QStringList initialItems; + initialItems << "foo" << "bar"; + for(int e = 0 ; e<2 ; e++) { + bool editable = (e==0); + QTest::newRow("Insert less then 0") << initialItems << -1 << "inserted" << 0 << editable; + QTest::newRow("Insert at 0") << initialItems << 0 << "inserted" << 0 << editable; + QTest::newRow("Insert beyond count") << initialItems << 3 << "inserted" << 2 << editable; + QTest::newRow("Insert at count") << initialItems << 2 << "inserted" << 2 << editable; + QTest::newRow("Insert in the middle") << initialItems << 1 << "inserted" << 1 << editable; + } +} + +void tst_QComboBox::insertItem() +{ + QFETCH(QStringList, initialItems); + QFETCH(int, insertIndex); + QFETCH(QString, itemLabel); + QFETCH(int, expectedIndex); + QFETCH(bool, editable); + + testWidget->insertItems(0, initialItems); + QCOMPARE(testWidget->count(), initialItems.count()); + + testWidget->setEditable(true); + if (editable) + testWidget->setEditText("FOO"); + testWidget->insertItem(insertIndex, itemLabel); + + QCOMPARE(testWidget->count(), initialItems.count() + 1); + QCOMPARE(testWidget->itemText(expectedIndex), itemLabel); + + if (editable) + QCOMPARE(testWidget->currentText(), QString("FOO")); +} + +void tst_QComboBox::insertOnCurrentIndex() +{ + testWidget->setEditable(true); + testWidget->addItem("first item"); + testWidget->setCurrentIndex(0); + testWidget->insertItem(0, "second item"); + QCOMPARE(testWidget->lineEdit()->text(), QString::fromAscii("first item")); +} + +void tst_QComboBox::textpixmapdata_data() +{ + QTest::addColumn<QStringList>("text"); + QTest::addColumn<IconList>("icons"); + QTest::addColumn<VariantList>("variant"); + + QStringList text; + IconList icon; + VariantList variant; + + { + text.clear(); icon.clear(); variant.clear(); + text << "foo" << "bar"; + icon << QIcon() << QIcon(); + variant << QVariant() << QVariant(); + QTest::newRow("just text") << text << icon << variant; + } + { + text.clear(); icon.clear(); variant.clear(); + text << QString() << QString(); + icon << QIcon(QPixmap("qtlogo.png")) << QIcon(QPixmap("qtlogoinverted.png")); + variant << QVariant() << QVariant(); + QTest::newRow("just icons") << text << icon << variant; + } + { + text.clear(); icon.clear(); variant.clear(); + text << QString() << QString(); + icon << QIcon() << QIcon(); + variant << 12 << "bingo"; + QTest::newRow("just user data") << text << icon << variant; + } + { + text.clear(); icon.clear(); variant.clear(); + text << "foo" << "bar"; + icon << QIcon(QPixmap("qtlogo.png")) << QIcon(QPixmap("qtlogoinverted.png")); + variant << 12 << "bingo"; + QTest::newRow("text, icons and user data") << text << icon << variant; + } +} + +void tst_QComboBox::textpixmapdata() +{ + QFETCH(QStringList, text); + QFETCH(IconList, icons); + QFETCH(VariantList, variant); + + QVERIFY(text.count() == icons.count() && text.count() == variant.count()); + + for (int i = 0; i<text.count(); ++i) { + testWidget->insertItem(i, text.at(i)); + testWidget->setItemIcon(i, icons.at(i)); + testWidget->setItemData(i, variant.at(i), Qt::UserRole); + } + + QCOMPARE(testWidget->count(), text.count()); + + for (int i = 0; i<text.count(); ++i) { + QIcon icon = testWidget->itemIcon(i); + QVERIFY(icon.serialNumber() == icons.at(i).serialNumber()); + QPixmap original = icons.at(i).pixmap(1024); + QPixmap pixmap = icon.pixmap(1024); + QVERIFY(pixmap.toImage() == original.toImage()); + } + + for (int i = 0; i<text.count(); ++i) { + QCOMPARE(testWidget->itemText(i), text.at(i)); + // ### we should test icons/pixmap as well, but I need to fix the api mismatch first + QCOMPARE(testWidget->itemData(i, Qt::UserRole), variant.at(i)); + } +} + +void tst_QComboBox::setCurrentIndex() +{ + QCOMPARE(testWidget->count(), 0); + testWidget->addItem("foo"); + testWidget->addItem("bar"); + QCOMPARE(testWidget->count(), 2); + + QCOMPARE(testWidget->currentIndex(), 0); + testWidget->setCurrentIndex(0); + QCOMPARE(testWidget->currentText(), QString("foo")); + + testWidget->setCurrentIndex(1); + QCOMPARE(testWidget->currentText(), QString("bar")); + + testWidget->setCurrentIndex(0); + QCOMPARE(testWidget->currentText(), QString("foo")); +} + +void tst_QComboBox::editTextChanged() +{ + QCOMPARE(testWidget->count(), 0); + testWidget->addItem("foo"); + testWidget->addItem("bar"); + QCOMPARE(testWidget->count(), 2); + + // first we test non editable + testWidget->setEditable(false); + QCOMPARE(testWidget->isEditable(), false); + + // no signal should be sent when current is set to the same + QCOMPARE(testWidget->currentIndex(), 0); + editTextCount = 0; + editText.clear(); + testWidget->setCurrentIndex(0); + QCOMPARE(testWidget->currentIndex(), 0); + QCOMPARE(editTextCount, 0); + QCOMPARE(editText.isEmpty(), true); + + // no signal should be sent when changing to other index because we are not editable + QCOMPARE(testWidget->currentIndex(), 0); + editTextCount = 0; + editText.clear(); + testWidget->setCurrentIndex(1); + QCOMPARE(testWidget->currentIndex(), 1); + QCOMPARE(editTextCount, 0); + QCOMPARE(editText.isEmpty(), true); + + // now set to editable and reset current index + testWidget->setEditable(true); + QCOMPARE(testWidget->isEditable(), true); + testWidget->setCurrentIndex(0); + + // no signal should be sent when current is set to the same + QCOMPARE(testWidget->currentIndex(), 0); + editTextCount = 0; + editText.clear(); + testWidget->setCurrentIndex(0); + QCOMPARE(testWidget->currentIndex(), 0); + QCOMPARE(editTextCount, 0); + QCOMPARE(editText.isEmpty(), true); + + // signal should be sent when changing to other index + QCOMPARE(testWidget->currentIndex(), 0); + editTextCount = 0; + editText.clear(); + testWidget->setCurrentIndex(1); + QCOMPARE(testWidget->currentIndex(), 1); + QCOMPARE(editTextCount, 1); + QCOMPARE(editText, QString("bar")); + + // insert some keys and notice they are all signaled + editTextCount = 0; + editText.clear(); + QTest::keyClicks(testWidget, "bingo"); + QCOMPARE(editTextCount, 5); + QCOMPARE(editText, QString("barbingo")); +} + +void tst_QComboBox::onEditTextChanged(const QString &text) +{ + editTextCount++; + editText = text; +} + +void tst_QComboBox::setModel() +{ + QComboBox box; + QCOMPARE(box.currentIndex(), -1); + box.addItems((QStringList() << "foo" << "bar")); + QCOMPARE(box.currentIndex(), 0); + box.setCurrentIndex(1); + QCOMPARE(box.currentIndex(), 1); + + // check that currentIndex is set to invalid + QAbstractItemModel *oldModel = box.model(); + box.setModel(new QStandardItemModel(&box)); + QCOMPARE(box.currentIndex(), -1); + QVERIFY(box.model() != oldModel); + + // check that currentIndex is set to first item + oldModel = box.model(); + box.setModel(new QStandardItemModel(2,1, &box)); + QCOMPARE(box.currentIndex(), 0); + QVERIFY(box.model() != oldModel); +} + +void tst_QComboBox::modelDeleted() +{ + QComboBox box; + QStandardItemModel *model = new QStandardItemModel; + box.setModel(model); + QCOMPARE(box.model(), static_cast<QAbstractItemModel *>(model)); + delete model; + QVERIFY(box.model()); + QCOMPARE(box.findText("bubu"), -1); + + delete box.model(); + QVERIFY(box.model()); + delete box.model(); + QVERIFY(box.model()); +} + +void tst_QComboBox::setMaxCount() +{ + QStringList items; + items << "1" << "2" << "3" << "4" << "5"; + + QComboBox box; + box.addItems(items); + QCOMPARE(box.count(), 5); + + box.setMaxCount(4); + QCOMPARE(box.count(), 4); + QCOMPARE(box.itemText(0), QString("1")); + QCOMPARE(box.itemText(1), QString("2")); + QCOMPARE(box.itemText(2), QString("3")); + QCOMPARE(box.itemText(3), QString("4")); + + // appending should do nothing + box.addItem("foo"); + QCOMPARE(box.count(), 4); + QCOMPARE(box.findText("foo"), -1); + + // inserting one item at top should remove the last + box.insertItem(0, "0"); + QCOMPARE(box.count(), 4); + QCOMPARE(box.itemText(0), QString("0")); + QCOMPARE(box.itemText(1), QString("1")); + QCOMPARE(box.itemText(2), QString("2")); + QCOMPARE(box.itemText(3), QString("3")); + + // insert 5 items in a box with maxCount 4 + box.insertItems(0, items); + QCOMPARE(box.count(), 4); + QCOMPARE(box.itemText(0), QString("1")); + QCOMPARE(box.itemText(1), QString("2")); + QCOMPARE(box.itemText(2), QString("3")); + QCOMPARE(box.itemText(3), QString("4")); + + // insert 5 items at pos 2. Make sure only two get inserted + QSignalSpy spy(box.model(), SIGNAL(rowsInserted(QModelIndex,int,int))); + box.insertItems(2, items); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(1).toInt(), 2); + QCOMPARE(spy.at(0).at(2).toInt(), 3); + + QCOMPARE(box.count(), 4); + QCOMPARE(box.itemText(0), QString("1")); + QCOMPARE(box.itemText(1), QString("2")); + QCOMPARE(box.itemText(2), QString("1")); + QCOMPARE(box.itemText(3), QString("2")); + + box.insertItems(0, QStringList()); + QCOMPARE(box.count(), 4); + + box.setMaxCount(0); + QCOMPARE(box.count(), 0); + box.addItem("foo"); + QCOMPARE(box.count(), 0); + box.addItems(items); + QCOMPARE(box.count(), 0); +} + +void tst_QComboBox::convenienceViews() +{ + // QListWidget + QComboBox listCombo; + QListWidget *list = new QListWidget(); + listCombo.setModel(list->model()); + listCombo.setView(list); + // add items + list->addItem("list0"); + listCombo.addItem("list1"); + QCOMPARE(listCombo.count(), 2); + QCOMPARE(listCombo.itemText(0), QString("list0")); + QCOMPARE(listCombo.itemText(1), QString("list1")); + + // QTreeWidget + QComboBox treeCombo; + QTreeWidget *tree = new QTreeWidget(); + tree->setColumnCount(1); + tree->header()->hide(); + treeCombo.setModel(tree->model()); + treeCombo.setView(tree); + // add items + tree->addTopLevelItem(new QTreeWidgetItem(QStringList("tree0"))); + treeCombo.addItem("tree1"); + QCOMPARE(treeCombo.count(), 2); + QCOMPARE(treeCombo.itemText(0), QString("tree0")); + QCOMPARE(treeCombo.itemText(1), QString("tree1")); + + // QTableWidget + QComboBox tableCombo; + QTableWidget *table = new QTableWidget(0,1); + table->verticalHeader()->hide(); + table->horizontalHeader()->hide(); + tableCombo.setModel(table->model()); + tableCombo.setView(table); + // add items + table->setRowCount(table->rowCount() + 1); + table->setItem(0, table->rowCount() - 1, new QTableWidgetItem("table0")); + tableCombo.addItem("table1"); + QCOMPARE(tableCombo.count(), 2); + QCOMPARE(tableCombo.itemText(0), QString("table0")); + QCOMPARE(tableCombo.itemText(1), QString("table1")); +} + +class ReturnClass : public QWidget +{ + Q_OBJECT +public: + ReturnClass(QWidget *parent = 0) + : QWidget(parent), received(false) + { + QComboBox *box = new QComboBox(this); + box->setEditable(true); + edit = box->lineEdit(); + box->setGeometry(rect()); + } + + void keyPressEvent(QKeyEvent *e) + { + received = (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter); + } + + QLineEdit *edit; + + bool received; + +}; + + + +void tst_QComboBox::ensureReturnIsIgnored() +{ + ReturnClass r; + r.show(); + + QTest::keyClick(r.edit, Qt::Key_Return); + QVERIFY(r.received); + r.received = false; + QTest::keyClick(r.edit, Qt::Key_Enter); + QVERIFY(r.received); +} + + +void tst_QComboBox::findText_data() +{ + QTest::addColumn<QStringList>("items"); + QTest::addColumn<int>("matchflags"); + QTest::addColumn<QString>("search"); + QTest::addColumn<int>("result"); + + QStringList list; + list << "One" << "Two" << "Three" << "Four" << "Five" << "Six" << "one"; + QTest::newRow("CaseSensitive_1") << list << (int)(Qt::MatchExactly|Qt::MatchCaseSensitive) + << QString("Two") << 1; + QTest::newRow("CaseSensitive_2") << list << (int)(Qt::MatchExactly|Qt::MatchCaseSensitive) + << QString("two") << -1; + QTest::newRow("CaseSensitive_3") << list << (int)(Qt::MatchExactly|Qt::MatchCaseSensitive) + << QString("One") << 0; + QTest::newRow("CaseSensitive_4") << list << (int)(Qt::MatchExactly|Qt::MatchCaseSensitive) + << QString("one") << 6; + QTest::newRow("CaseInsensitive_1") << list << (int)(Qt::MatchExactly) << QString("Two") << 1; + QTest::newRow("CaseInsensitive_2") << list << (int)(Qt::MatchExactly) << QString("two") << -1; + QTest::newRow("CaseInsensitive_3") << list << (int)(Qt::MatchExactly) << QString("One") << 0; + QTest::newRow("CaseInsensitive_4") << list << (int)(Qt::MatchExactly) << QString("one") << 6; +} +void tst_QComboBox::findText() +{ + QFETCH(QStringList, items); + QFETCH(int, matchflags); + QFETCH(QString, search); + QFETCH(int, result); + + testWidget->clear(); + testWidget->addItems(items); + + QCOMPARE(testWidget->findText(search, (Qt::MatchFlags)matchflags), result); +} + +typedef QList<int> IntList; +typedef QList<Qt::Key> KeyList; +Q_DECLARE_METATYPE(IntList) +Q_DECLARE_METATYPE(KeyList) + +void tst_QComboBox::flaggedItems_data() +{ + QTest::addColumn<QStringList>("itemList"); + QTest::addColumn<IntList>("deselectFlagList"); + QTest::addColumn<IntList>("disableFlagList"); + QTest::addColumn<KeyList>("keyMovementList"); + QTest::addColumn<bool>("editable"); + QTest::addColumn<int>("expectedIndex"); + + for (int editable=0;editable<2;editable++) { + QString testCase = editable ? "editable:" : "non-editable:"; + QStringList itemList; + itemList << "One" << "Two" << "Three" << "Four" << "Five" << "Six" << "Seven" << "Eight"; + IntList deselectFlagList; + IntList disableFlagList; + KeyList keyMovementList; + + keyMovementList << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down; + QTest::newRow(testCase.toAscii() + "normal") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 4; + + deselectFlagList.clear(); + disableFlagList.clear(); + deselectFlagList << 1 << 3; + QTest::newRow(testCase.toAscii() + "non-selectable") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 4; + + deselectFlagList.clear(); + disableFlagList.clear(); + disableFlagList << 2; + QTest::newRow(testCase.toAscii() + "disabled") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 5; + + deselectFlagList.clear(); + disableFlagList.clear(); + deselectFlagList << 1 << 3; + disableFlagList << 2 << 3; + QTest::newRow(testCase.toAscii() + "mixed") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 6; + deselectFlagList.clear(); + disableFlagList.clear(); + disableFlagList << 0 << 1 << 2 << 3 << 4 << 5 << 6; + QTest::newRow(testCase.toAscii() + "nearly-empty") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 7; + + deselectFlagList.clear(); + disableFlagList.clear(); + disableFlagList << 0 << 1 << 2 << 3 << 5 << 6 << 7; + keyMovementList.clear(); + QTest::newRow(testCase.toAscii() + "only one enabled") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 4; + + if (!editable) { + deselectFlagList.clear(); + disableFlagList.clear(); + keyMovementList.clear(); + disableFlagList << 0 << 2 << 3; + keyMovementList << Qt::Key_Down << Qt::Key_Home; + QTest::newRow(testCase.toAscii() + "home-disabled") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 1; + + keyMovementList.clear(); + keyMovementList << Qt::Key_End; + QTest::newRow(testCase.toAscii() + "end-key") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 7; + + disableFlagList.clear(); + disableFlagList << 1 ; + keyMovementList << Qt::Key_T; + QTest::newRow(testCase.toAscii() + "keyboard-search") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2; + + itemList << "nine" << "ten"; + keyMovementList << Qt::Key_T; + QTest::newRow(testCase.toAscii() + "search same start letter") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 9; + + keyMovementList.clear(); + keyMovementList << Qt::Key_T << Qt::Key_H; + QTest::newRow(testCase.toAscii() + "keyboard search item") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2; + + disableFlagList.clear(); + disableFlagList << 1 << 3 << 5 << 7 << 9; + keyMovementList.clear(); + keyMovementList << Qt::Key_End << Qt::Key_Up << Qt::Key_Up << Qt::Key_PageDown << Qt::Key_PageUp << Qt::Key_PageUp << Qt::Key_Down; + QTest::newRow(testCase.toAscii() + "all key combinations") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 4; + } else { + deselectFlagList.clear(); + disableFlagList.clear(); + disableFlagList << 1; + keyMovementList.clear(); + keyMovementList << Qt::Key_T << Qt::Key_Enter; + QTest::newRow(testCase.toAscii() + "disabled") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2; + QTest::newRow(testCase.toAscii() + "broken autocompletion") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2; + } + } +} + +void tst_QComboBox::flaggedItems() +{ + QFETCH(QStringList, itemList); + QFETCH(IntList, deselectFlagList); + QFETCH(IntList, disableFlagList); + QFETCH(KeyList, keyMovementList); + QFETCH(bool, editable); + QFETCH(int, expectedIndex); + + QComboBox comboBox; + QListWidget listWidget; + listWidget.addItems(itemList); + + comboBox.setEditable(editable); + foreach (int index, deselectFlagList) + listWidget.item(index)->setFlags(listWidget.item(index)->flags() & ~Qt::ItemIsSelectable); + + foreach (int index, disableFlagList) + listWidget.item(index)->setFlags(listWidget.item(index)->flags() & ~Qt::ItemIsEnabled); + + comboBox.setModel(listWidget.model()); + comboBox.setView(&listWidget); + comboBox.show(); + QApplication::setActiveWindow(&comboBox); + comboBox.activateWindow(); + comboBox.setFocus(); + QTRY_VERIFY(comboBox.isVisible()); + QTRY_VERIFY(comboBox.hasFocus()); + + if (editable) + comboBox.lineEdit()->selectAll(); + + QSignalSpy indexChangedInt(&comboBox, SIGNAL(currentIndexChanged(int))); + for (int i = 0; i < keyMovementList.count(); ++i) { + Qt::Key key = keyMovementList[i]; + QTest::keyClick(&comboBox, key); + if (indexChangedInt.count() != i + 1) { + QTest::qWait(400); + } + } + + QCOMPARE(comboBox.currentIndex() , expectedIndex); +} + +void tst_QComboBox::pixmapIcon() +{ + QComboBox box; + QStandardItemModel *model = new QStandardItemModel(2, 1, &box); + + QPixmap pix(10, 10); + pix.fill(Qt::red); + model->setData(model->index(0, 0), "Element 1"); + model->setData(model->index(0, 0), pix, Qt::DecorationRole); + + QIcon icon(pix); + model->setData(model->index(1, 0), "Element 2"); + model->setData(model->index(1, 0), icon, Qt::DecorationRole); + + box.setModel(model); + + QCOMPARE( box.itemIcon(0).isNull(), false ); + QCOMPARE( box.itemIcon(1).isNull(), false ); +} + +// defined to be 120 by the wheel mouse vendors according to the docs +#define WHEEL_DELTA 120 + +void tst_QComboBox::mouseWheel_data() +{ + QTest::addColumn<IntList>("disabledItems"); + QTest::addColumn<int>("startIndex"); + QTest::addColumn<int>("wheelDirection"); + QTest::addColumn<int>("expectedIndex"); + + IntList disabled; + disabled << 0 << 1 << 2 << 4; + int start = 3; + int wheel = 1; + int expected = 3; + QTest::newRow("upper locked") << disabled << start << wheel << expected; + + wheel = -1; + expected = 5; + QTest::newRow("jump over") << disabled << start << wheel << expected; + + disabled.clear(); + disabled << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9; + start = 0; + wheel = -1; + expected = 0; + QTest::newRow("single Item enabled") << disabled << start << wheel << expected; +} + +void tst_QComboBox::mouseWheel() +{ + QFETCH(IntList, disabledItems); + QFETCH(int, startIndex); + QFETCH(int, wheelDirection); + QFETCH(int, expectedIndex); + + QCoreApplication *applicationInstance = QCoreApplication::instance(); + QVERIFY(applicationInstance != 0); + + QComboBox box; + QStringList list; + list << "one" << "two" << "three" << "four" << "five" << "six" << "seven" << "eight" << "nine" << "ten"; + + QListWidget listWidget; + listWidget.addItems(list); + + foreach (int index, disabledItems) + listWidget.item(index)->setFlags(listWidget.item(index)->flags() & ~Qt::ItemIsEnabled); + + box.setModel(listWidget.model()); + box.setView(&listWidget); + for (int i=0; i < 2; ++i) { + box.setEditable(i==0?false:true); + box.setCurrentIndex(startIndex); + + QWheelEvent event = QWheelEvent(box.rect().bottomRight() , WHEEL_DELTA * wheelDirection, Qt::NoButton, Qt::NoModifier); + QVERIFY(applicationInstance->sendEvent(&box,&event)); + + QCOMPARE(box.currentIndex(), expectedIndex); + } +} + +void tst_QComboBox::layoutDirection() +{ + QComboBox box; + Qt::LayoutDirection dir; + QLineEdit *lineEdit; + + // RTL + box.setLayoutDirection(Qt::RightToLeft); + QStyleOptionComboBox opt; + opt.direction = Qt::RightToLeft; + dir = (Qt::LayoutDirection)box.style()->styleHint(QStyle::SH_ComboBox_LayoutDirection, &opt, &box); + + QCOMPARE(box.view()->layoutDirection(), dir); + box.setEditable(true); + QCOMPARE(box.lineEdit()->layoutDirection(), dir); + lineEdit = new QLineEdit; + QCOMPARE(lineEdit->layoutDirection(), qApp->layoutDirection()); + box.setLineEdit(lineEdit); + QCOMPARE(lineEdit->layoutDirection(), dir); + + // LTR + box.setLayoutDirection(Qt::LeftToRight); + qApp->setLayoutDirection(Qt::RightToLeft); + + opt.direction = Qt::LeftToRight; + dir = (Qt::LayoutDirection)box.style()->styleHint(QStyle::SH_ComboBox_LayoutDirection, &opt, &box); + + QCOMPARE(box.view()->layoutDirection(), dir); + box.setEditable(true); + QCOMPARE(box.lineEdit()->layoutDirection(), dir); + lineEdit = new QLineEdit; + QCOMPARE(lineEdit->layoutDirection(), qApp->layoutDirection()); + box.setLineEdit(lineEdit); + QCOMPARE(lineEdit->layoutDirection(), dir); + +} + +void tst_QComboBox::itemListPosition() +{ + //tests that the list is not out of the screen boundaries + + //put the QApplication layout back + QApplication::setLayoutDirection(Qt::LeftToRight); + + //we test QFontComboBox because it has the specific behaviour to set a fixed size + //to the list view + QWidget topLevel; + QFontComboBox combo(&topLevel); + + //the code to get the avaialbe screen space is copied from QComboBox code + const int scrNumber = QApplication::desktop()->screenNumber(&combo); + QRect screen; +#ifdef Q_WS_WIN + screen = QApplication::desktop()->screenGeometry(scrNumber); +#elif defined Q_WS_X11 + if (X11->desktopEnvironment == DE_KDE) + screen = QApplication::desktop()->screenGeometry(scrNumber); + else + screen = QApplication::desktop()->availableGeometry(scrNumber); +#else + screen = QApplication::desktop()->availableGeometry(scrNumber); +#endif + + combo.move(screen.width()-combo.sizeHint().width(), 0); //puts the combo to the top-right corner + + topLevel.show(); + //wait because the window manager can move the window if there is a right panel + QTRY_VERIFY(combo.isVisible()); + combo.showPopup(); + QTRY_VERIFY(combo.view()); + QTRY_VERIFY(combo.view()->isVisible()); + QVERIFY( combo.view()->window()->x() + combo.view()->window()->width() <= screen.x() + screen.width() ); +} + +void tst_QComboBox::separatorItem_data() +{ + QTest::addColumn<QStringList>("items"); + QTest::addColumn<IntList>("separators"); + + QTest::newRow("test") << (QStringList() << "one" << "two" << "three" << "other...") + << (IntList() << 4); +} + +void tst_QComboBox::separatorItem() +{ + QFETCH(QStringList, items); + QFETCH(IntList, separators); + + QComboBox box; + box.addItems(items); + foreach(int index, separators) + box.insertSeparator(index); + QCOMPARE(box.count(), (items.count() + separators.count())); + for (int i = 0, s = 0; i < box.count(); ++i) { + if (i == separators.at(s)) { + QCOMPARE(box.itemText(i), QString()); + ++s; + } else { + QCOMPARE(box.itemText(i), items.at(i - s)); + } + } +} + +// This test requires the Cleanlooks style +#ifndef QT_NO_STYLE_CLEANLOOKS +void tst_QComboBox::task190351_layout() +{ + const QString oldStyle = QApplication::style()->objectName(); + QApplication::setStyle(new QCleanlooksStyle); + + QComboBox listCombo; + QListWidget *list = new QListWidget(); + listCombo.setModel(list->model()); + listCombo.setView(list); + for(int i = 1; i < 150; i++) + list->addItem(QLatin1String("list") + QString::number(i)); + + listCombo.show(); + QTest::qWaitForWindowShown(&listCombo); + QTRY_VERIFY(listCombo.isVisible()); + listCombo.setCurrentIndex(70); + listCombo.showPopup(); + QTRY_VERIFY(listCombo.view()); + QTest::qWaitForWindowShown(listCombo.view()); + QTRY_VERIFY(listCombo.view()->isVisible()); + QApplication::processEvents(); + +#ifdef QT_BUILD_INTERNAL + QFrame *container = qFindChild<QComboBoxPrivateContainer *>(&listCombo); + QVERIFY(container); + QCOMPARE(static_cast<QAbstractItemView *>(list), qFindChild<QAbstractItemView *>(container)); + QWidget *top = qFindChild<QComboBoxPrivateScroller *>(container); + QVERIFY(top); + QVERIFY(top->isVisible()); + QCOMPARE(top->mapToGlobal(QPoint(0, top->height())).y(), list->mapToGlobal(QPoint()).y()); +#endif + + QApplication::setStyle(oldStyle); +} +#endif + +class task166349_ComboBox : public QComboBox +{ + Q_OBJECT +public: + task166349_ComboBox(QWidget *parent = 0) : QComboBox(parent) + { + QStringList list; + list << "one" << "two"; + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); + addItems(list); + } +public slots: + void onCurrentIndexChanged(int index) + { + setEditable(index % 2 == 1); + } +}; + +void tst_QComboBox::task166349_setEditableOnReturn() +{ + task166349_ComboBox comboBox; + QTest::keyClick(&comboBox, Qt::Key_Down); + QTest::keyClick(&comboBox, Qt::Key_1); + QTest::keyClick(&comboBox, Qt::Key_Enter); + QCOMPARE(QLatin1String("two1"), comboBox.itemText(comboBox.count() - 1)); +} + +// This test requires the Cleanlooks style. +#ifndef QT_NO_STYLE_CLEANLOOKS +void tst_QComboBox::task191329_size() +{ + const QString oldStyle = QApplication::style()->objectName(); + QApplication::setStyle(new QCleanlooksStyle); + + QComboBox tableCombo; + int rows; + if (QApplication::desktop()->screenGeometry().height() < 480) + rows = 8; + else + rows = 15; + + QStandardItemModel model(rows, 2); + for (int row = 0; row < model.rowCount(); ++row) { + for (int column = 0; column < model.columnCount(); ++column) { + QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column)); + model.setItem(row, column, item); + } + } + QTableView *table = new QTableView(); + table->verticalHeader()->hide(); + table->horizontalHeader()->hide(); + tableCombo.setView(table); + tableCombo.setModel(&model); + + tableCombo.show(); + QTRY_VERIFY(tableCombo.isVisible()); + tableCombo.showPopup(); + QTRY_VERIFY(tableCombo.view()); + QTRY_VERIFY(tableCombo.view()->isVisible()); + +#ifdef QT_BUILD_INTERNAL + QFrame *container = qFindChild<QComboBoxPrivateContainer *>(&tableCombo); + QVERIFY(container); + QCOMPARE(static_cast<QAbstractItemView *>(table), qFindChild<QAbstractItemView *>(container)); + foreach (QWidget *button, qFindChildren<QComboBoxPrivateScroller *>(container)) { + //the popup should be large enough to contains everithing so the top and left button are hidden + QVERIFY(!button->isVisible()); + } +#endif + + QApplication::setStyle(oldStyle); +} +#endif + +void tst_QComboBox::task190205_setModelAdjustToContents() +{ + QStringList initialContent; + QStringList finalContent; + initialContent << "foo" << "bar"; + finalContent << "bar" << "foooooooobar"; + + QComboBox box; + box.setSizeAdjustPolicy(QComboBox::AdjustToContents); + box.addItems(initialContent); + box.show(); + + //wait needed in order to get the combo initial size + QTRY_VERIFY(box.isVisible()); + + box.setModel(new QStringListModel(finalContent)); + + QComboBox correctBox; + correctBox.addItems(finalContent); + correctBox.show(); + + QCoreApplication::processEvents(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&box); + qt_x11_wait_for_window_manager(&correctBox); +#endif + + // box should be resized to the same size as correctBox + QTRY_COMPARE(box.size(), correctBox.size()); +} + +void tst_QComboBox::task248169_popupWithMinimalSize() +{ + QStringList initialContent; + initialContent << "foo" << "bar" << "foobar"; + + QComboBox comboBox; + comboBox.addItems(initialContent); + QDesktopWidget desktop; + QRect desktopSize = desktop.availableGeometry(); + comboBox.view()->setMinimumWidth(desktopSize.width() / 2); + + comboBox.setGeometry(desktopSize.width() - (desktopSize.width() / 4), (desktopSize.width() / 4), (desktopSize.width() / 2), (desktopSize.width() / 4)); + + comboBox.show(); + QTest::qWaitForWindowShown(&comboBox); + QTRY_VERIFY(comboBox.isVisible()); + comboBox.showPopup(); + QTRY_VERIFY(comboBox.view()); + QTest::qWaitForWindowShown(comboBox.view()); + QTRY_VERIFY(comboBox.view()->isVisible()); + +#ifdef QT_BUILD_INTERNAL + QFrame *container = qFindChild<QComboBoxPrivateContainer *>(&comboBox); + QVERIFY(container); + QTRY_VERIFY(desktop.screenGeometry(container).contains(container->geometry())); +#endif +} + +void tst_QComboBox::task247863_keyBoardSelection() +{ + QComboBox combo; + combo.setEditable(false); + combo.addItem( QLatin1String("111")); + combo.addItem( QLatin1String("222")); + combo.show(); + QApplication::setActiveWindow(&combo); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&combo)); + + QSignalSpy spy(&combo, SIGNAL(activated(const QString &))); + qApp->setEffectEnabled(Qt::UI_AnimateCombo, false); + QTest::keyClick(&combo, Qt::Key_Space); + qApp->setEffectEnabled(Qt::UI_AnimateCombo, true); + QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down); + QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter); + QCOMPARE(combo.currentText(), QLatin1String("222")); + QCOMPARE(spy.count(), 1); +} + +void tst_QComboBox::task220195_keyBoardSelection2() +{ + QComboBox combo; + combo.setEditable(false); + combo.addItem( QLatin1String("foo1")); + combo.addItem( QLatin1String("foo2")); + combo.addItem( QLatin1String("foo3")); + combo.show(); + QApplication::setActiveWindow(&combo); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&combo)); + + combo.setCurrentIndex(-1); + QVERIFY(combo.currentText().isNull()); + + QTest::keyClick(&combo, 'f'); + QCOMPARE(combo.currentText(), QLatin1String("foo1")); + QTest::qWait(QApplication::keyboardInputInterval() + 30); + QTest::keyClick(&combo, 'f'); + QCOMPARE(combo.currentText(), QLatin1String("foo2")); + QTest::qWait(QApplication::keyboardInputInterval() + 30); + QTest::keyClick(&combo, 'f'); + QCOMPARE(combo.currentText(), QLatin1String("foo3")); + QTest::qWait(QApplication::keyboardInputInterval() + 30); + QTest::keyClick(&combo, 'f'); + QCOMPARE(combo.currentText(), QLatin1String("foo1")); + QTest::qWait(QApplication::keyboardInputInterval() + 30); + + combo.setCurrentIndex(1); + QCOMPARE(combo.currentText(), QLatin1String("foo2")); + QTest::keyClick(&combo, 'f'); + QCOMPARE(combo.currentText(), QLatin1String("foo3")); +} + + +void tst_QComboBox::setModelColumn() +{ + QStandardItemModel model(5,3); + model.setItem(0,0, new QStandardItem("0")); + model.setItem(1,0, new QStandardItem("1")); + model.setItem(2,0, new QStandardItem("2")); + model.setItem(3,0, new QStandardItem("3")); + model.setItem(4,0, new QStandardItem("4")); + model.setItem(0,1, new QStandardItem("zero")); + model.setItem(1,1, new QStandardItem("un")); + model.setItem(2,1, new QStandardItem("deux")); + model.setItem(3,1, new QStandardItem("trois")); + model.setItem(4,1, new QStandardItem("quatre")); + model.setItem(0,2, new QStandardItem("a")); + model.setItem(1,2, new QStandardItem("b")); + model.setItem(2,2, new QStandardItem("c")); + model.setItem(3,2, new QStandardItem("d")); + model.setItem(4,2, new QStandardItem("e")); + + QComboBox box; + box.setModel(&model); + QCOMPARE(box.currentText(), QString("0")); + box.setModelColumn(1); + QCOMPARE(box.currentText(), QString("zero")); +} + +void tst_QComboBox::noScrollbar_data() +{ + QTest::addColumn<QString>("stylesheet"); + + QTest::newRow("normal") << QString(); + QTest::newRow("border") << QString::fromLatin1("QAbstractItemView { border: 12px solid blue;}"); + QTest::newRow("margin") << QString::fromLatin1("QAbstractItemView { margin: 12px 15px 13px 10px; }"); + QTest::newRow("padding") << QString::fromLatin1("QAbstractItemView { padding: 12px 15px 13px 10px;}"); + QTest::newRow("everything") << QString::fromLatin1("QAbstractItemView { border: 12px solid blue; " + " padding: 12px 15px 13px 10px; margin: 12px 15px 13px 10px; }"); + QTest::newRow("everything and more") << QString::fromLatin1("QAbstractItemView { border: 1px 3px 5px 1px solid blue; " + " padding: 2px 5px 3px 1px; margin: 2px 5px 3px 1px; } " + " QAbstractItemView::item { border: 2px solid green; " + " padding: 1px 1px 2px 2px; margin: 1px; } " ); +} + +void tst_QComboBox::noScrollbar() +{ + QStringList initialContent; + initialContent << "foo" << "bar" << "foobar" << "moo"; + QFETCH(QString, stylesheet); + QString oldCss = qApp->styleSheet(); + qApp->setStyleSheet(stylesheet); + + { + QWidget topLevel; + QComboBox comboBox(&topLevel); + comboBox.addItems(initialContent); + topLevel.show(); + comboBox.resize(200, comboBox.height()); + QTRY_VERIFY(comboBox.isVisible()); + comboBox.showPopup(); + QTRY_VERIFY(comboBox.view()); + QTRY_VERIFY(comboBox.view()->isVisible()); + + QVERIFY(!comboBox.view()->horizontalScrollBar()->isVisible()); + QVERIFY(!comboBox.view()->verticalScrollBar()->isVisible()); + } + + { + QTableWidget *table = new QTableWidget(2,2); + QComboBox comboBox; + comboBox.setModel(table->model()); + comboBox.setView(table); + comboBox.show(); + QTRY_VERIFY(comboBox.isVisible()); + comboBox.resize(200, comboBox.height()); + comboBox.showPopup(); + QTRY_VERIFY(comboBox.view()); + QTRY_VERIFY(comboBox.view()->isVisible()); + + QVERIFY(!comboBox.view()->horizontalScrollBar()->isVisible()); + QVERIFY(!comboBox.view()->verticalScrollBar()->isVisible()); + } + + qApp->setStyleSheet(oldCss); +} + +void tst_QComboBox::setItemDelegate() +{ + QComboBox comboBox; + QStyledItemDelegate *itemDelegate = new QStyledItemDelegate; + comboBox.setItemDelegate(itemDelegate); + // the cast is a workaround for the XLC and Metrowerks compilers + QCOMPARE(static_cast<QStyledItemDelegate *>(comboBox.itemDelegate()), itemDelegate); +} + +void tst_QComboBox::task253944_itemDelegateIsReset() +{ + QComboBox comboBox; + QStyledItemDelegate *itemDelegate = new QStyledItemDelegate; + comboBox.setItemDelegate(itemDelegate); + + // the casts are workarounds for the XLC and Metrowerks compilers + + comboBox.setEditable(true); + QCOMPARE(static_cast<QStyledItemDelegate *>(comboBox.itemDelegate()), itemDelegate); + + comboBox.setStyleSheet("QComboBox { border: 1px solid gray; }"); + QCOMPARE(static_cast<QStyledItemDelegate *>(comboBox.itemDelegate()), itemDelegate); +} + + +void tst_QComboBox::subControlRectsWithOffset_data() +{ + QTest::addColumn<bool>("editable"); + + QTest::newRow("editable = true") << true; + QTest::newRow("editable = false") << false; +} + +void tst_QComboBox::subControlRectsWithOffset() +{ + // The sub control rect relative position should not depends + // on the position of the combobox + + class FriendlyCombo : public QComboBox { + public: + void styleOption(QStyleOptionComboBox *optCombo) { + initStyleOption(optCombo); + } + } combo; + QStyleOptionComboBox optCombo; + combo.styleOption(&optCombo); + + + const QRect rectAtOrigin(0, 0, 80, 30); + const QPoint offset(25, 50); + const QRect rectWithOffset = rectAtOrigin.translated(offset); + + QStyle *style = combo.style(); + + QFETCH(bool, editable); + optCombo.editable = editable; + + optCombo.rect = rectAtOrigin; + QRect editFieldRect = style->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxEditField, 0); + QRect arrowRect = style->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxArrow, 0); + QRect listboxRect = style->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxListBoxPopup, 0); + + optCombo.rect = rectWithOffset; + QRect editFieldRectWithOffset = style->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxEditField, 0); + QRect arrowRectWithOffset = style->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxArrow, 0); + QRect listboxRectWithOffset = style->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxListBoxPopup, 0); + + QCOMPARE(editFieldRect, editFieldRectWithOffset.translated(-offset)); + QCOMPARE(arrowRect, arrowRectWithOffset.translated(-offset)); + QCOMPARE(listboxRect, listboxRectWithOffset.translated(-offset)); + +} + +// This test depends on Windows style. +#ifndef QT_NO_STYLE_WINDOWS +void tst_QComboBox::task260974_menuItemRectangleForComboBoxPopup() +{ + class TestStyle: public QWindowsStyle + { + public: + int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *ret) const + { + if (hint == SH_ComboBox_Popup) return 1; + else return QCommonStyle::styleHint(hint, option, widget, ret); + } + + void drawControl(ControlElement element, const QStyleOption *option, QPainter *, const QWidget *) const + { + if (element == CE_MenuItem) + discoveredRect = option->rect; + } + + mutable QRect discoveredRect; + } style; + + + { + QComboBox comboBox; + comboBox.setStyle(&style); + comboBox.addItem("Item 1"); + + comboBox.show(); + QTRY_VERIFY(comboBox.isVisible()); + comboBox.showPopup(); + QTRY_VERIFY(comboBox.view()); + QTRY_VERIFY(comboBox.view()->isVisible()); + + QTRY_VERIFY(style.discoveredRect.width() <= comboBox.width()); + } +} +#endif + +void tst_QComboBox::removeItem() +{ + QComboBox cb; + cb.removeItem(-1); + cb.removeItem(1); + cb.removeItem(0); + QCOMPARE(cb.count(), 0); + + cb.addItem("foo"); + cb.removeItem(-1); + QCOMPARE(cb.count(), 1); + cb.removeItem(1); + QCOMPARE(cb.count(), 1); + cb.removeItem(0); + QCOMPARE(cb.count(), 0); +} + +void tst_QComboBox::resetModel() +{ + class StringListModel : public QStringListModel + { + public: + StringListModel(const QStringList &list) : QStringListModel(list) + { + } + + void reset() + { + QStringListModel::reset(); + } + }; + QComboBox cb; + StringListModel model( QStringList() << "1" << "2"); + QSignalSpy spy(&cb, SIGNAL(currentIndexChanged(int))); + QCOMPARE(spy.count(), 0); + QCOMPARE(cb.currentIndex(), -1); //no selection + + cb.setModel(&model); + + QCOMPARE(spy.count(), 1); + QCOMPARE(cb.currentIndex(), 0); //first item selected + + model.reset(); + QCOMPARE(spy.count(), 2); + QCOMPARE(cb.currentIndex(), -1); //no selection + +} + +void tst_QComboBox::keyBoardNavigationWithMouse() +{ + QComboBox combo; + combo.setEditable(false); + for (int i = 0; i < 80; i++) + combo.addItem( QString::number(i)); + combo.show(); + QApplication::setActiveWindow(&combo); + QTest::qWaitForWindowShown(&combo); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&combo)); + + QCOMPARE(combo.currentText(), QLatin1String("0")); + + combo.setFocus(); + QTRY_VERIFY(combo.hasFocus()); + + QTest::keyClick(testWidget->lineEdit(), Qt::Key_Space); + QTest::qWait(30); + QTRY_VERIFY(combo.view()); + QTRY_VERIFY(combo.view()->isVisible()); + QTest::qWait(130); + + QCOMPARE(combo.currentText(), QLatin1String("0")); + + // When calling cursor function, Windows CE responds with: This function is not supported on this system. +#ifndef Q_OS_WINCE + // Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA: + const QPoint target(combo.view()->mapToGlobal(combo.view()->rect().center())); + QCursor::setPos(QPoint(target.x() + 1, target.y())); + QCursor::setPos(target); + + QTest::qWait(200); + +#define GET_SELECTION(SEL) \ + QCOMPARE(combo.view()->selectionModel()->selection().count(), 1); \ + QCOMPARE(combo.view()->selectionModel()->selection().indexes().count(), 1); \ + SEL = combo.view()->selectionModel()->selection().indexes().first().row() + + int selection; + GET_SELECTION(selection); + + //since we moved the mouse is in the middle it should even be around 5; + QVERIFY(selection > 3); + + static const int final = 40; + for (int i = selection + 1; i <= final; i++) + { + QTest::keyClick(combo.view(), Qt::Key_Down); + QTest::qWait(20); + GET_SELECTION(selection); + QCOMPARE(selection, i); + } + + QTest::keyClick(combo.view(), Qt::Key_Enter); + QTRY_COMPARE(combo.currentText(), QString::number(final)); +#endif +} + +void tst_QComboBox::task_QTBUG_1071_changingFocusEmitsActivated() +{ + QWidget w; + QVBoxLayout layout(&w); + QComboBox cb; + cb.setEditable(true); + QSignalSpy spy(&cb, SIGNAL(activated(int))); + cb.addItem("0"); + cb.addItem("1"); + cb.addItem("2"); + QLineEdit edit; + layout.addWidget(&cb); + layout.addWidget(&edit); + + w.show(); + QApplication::setActiveWindow(&w); + QTest::qWaitForWindowShown(&w); + cb.clearEditText(); + cb.setFocus(); + QApplication::processEvents(); + QTRY_VERIFY(cb.hasFocus()); + QTest::keyClick(static_cast<QWidget *>(0), '1'); + QCOMPARE(spy.count(), 0); + edit.setFocus(); + QTRY_VERIFY(edit.hasFocus()); + QTRY_COMPARE(spy.count(), 1); +} + +void tst_QComboBox::maxVisibleItems() +{ + QComboBox comboBox; + QCOMPARE(comboBox.maxVisibleItems(), 10); //default value. + + QStringList content; + for(int i = 1; i < 50; i++) + content += QString::number(i); + + comboBox.addItems(content); + comboBox.show(); + comboBox.resize(200, comboBox.height()); + QTRY_VERIFY(comboBox.isVisible()); + + comboBox.setMaxVisibleItems(5); + QCOMPARE(comboBox.maxVisibleItems(), 5); + + comboBox.showPopup(); + QTRY_VERIFY(comboBox.view()); + QTRY_VERIFY(comboBox.view()->isVisible()); + + QAbstractItemView *v = comboBox.view(); + int itemHeight = v->visualRect(v->model()->index(0,0)).height(); + QListView *lv = qobject_cast<QListView*>(v); + if (lv) + itemHeight += lv->spacing(); + QStyleOptionComboBox opt; + opt.initFrom(&comboBox); + if (!comboBox.style()->styleHint(QStyle::SH_ComboBox_Popup, &opt)) + QCOMPARE(v->viewport()->height(), itemHeight * comboBox.maxVisibleItems()); +} + +void tst_QComboBox::task_QTBUG_10491_currentIndexAndModelColumn() +{ + QComboBox comboBox; + + QStandardItemModel model(4, 4, &comboBox); + for (int i = 0; i < 4; i++){ + model.setItem(i, 0, new QStandardItem(QString("Employee Nr %1").arg(i))); + model.setItem(i, 1, new QStandardItem(QString("Street Nr %1").arg(i))); + model.setItem(i, 2, new QStandardItem(QString("Town Nr %1").arg(i))); + model.setItem(i, 3, new QStandardItem(QString("Phone Nr %1").arg(i))); + } + comboBox.setModel(&model); + comboBox.setModelColumn(0); + + QComboBoxPrivate *d = static_cast<QComboBoxPrivate *>(QComboBoxPrivate::get(&comboBox)); + d->setCurrentIndex(model.index(2, 2)); + QCOMPARE(QModelIndex(d->currentIndex), model.index(2, comboBox.modelColumn())); +} + +QTEST_MAIN(tst_QComboBox) +#include "tst_qcombobox.moc" diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/.gitignore b/tests/auto/widgets/widgets/qcommandlinkbutton/.gitignore new file mode 100644 index 0000000000..878121e2e6 --- /dev/null +++ b/tests/auto/widgets/widgets/qcommandlinkbutton/.gitignore @@ -0,0 +1 @@ +tst_qcommandlinkbutton diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro b/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro new file mode 100644 index 0000000000..497b8298a2 --- /dev/null +++ b/tests/auto/widgets/widgets/qcommandlinkbutton/qcommandlinkbutton.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qcommandlinkbutton.cpp + + + diff --git a/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp new file mode 100644 index 0000000000..6a51bf4bba --- /dev/null +++ b/tests/auto/widgets/widgets/qcommandlinkbutton/tst_qcommandlinkbutton.cpp @@ -0,0 +1,590 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + + +#include "qcommandlinkbutton.h" +#include <qapplication.h> + +#include <qcommandlinkbutton.h> +#include <qmenu.h> +#include <qtimer.h> +#include <QDialog> +#include <QGridLayout> +#include <QPainter> + +Q_DECLARE_METATYPE(QCommandLinkButton*) + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QCommandLinkButton : public QObject +{ +Q_OBJECT +public: + tst_QCommandLinkButton(); + virtual ~tst_QCommandLinkButton(); + + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void getSetCheck(); + void pressed(); + void setAccel(); + void isCheckable(); + void setDown(); + void popupCrash(); + void isChecked(); + void animateClick(); + void toggle(); + void clicked(); + void toggled(); + void defaultAndAutoDefault(); + void setAutoRepeat(); + void heightForWithWithIcon(); + +protected slots: + void resetCounters(); + void onClicked(); + void onToggled( bool on ); + void onPressed(); + void onReleased(); + void helperSlotDelete(); + +private: + uint click_count; + uint toggle_count; + uint press_count; + uint release_count; + + QCommandLinkButton *testWidget; +}; + +// Testing get/set functions +void tst_QCommandLinkButton::getSetCheck() +{ + QCommandLinkButton obj1; + + QString text("mytext"); + QVERIFY(obj1.description().isEmpty()); + obj1.setDescription(text); + QVERIFY(obj1.description() == text); + + QVERIFY(obj1.text().isEmpty()); + obj1.setText(text); + QVERIFY(obj1.text() == text); + + + QMenu *var1 = new QMenu; + obj1.setMenu(var1); + QCOMPARE(var1, obj1.menu()); + obj1.setMenu((QMenu *)0); + QCOMPARE((QMenu *)0, obj1.menu()); + delete var1; +} + +tst_QCommandLinkButton::tst_QCommandLinkButton() +{ +} + +tst_QCommandLinkButton::~tst_QCommandLinkButton() +{ +} + +void tst_QCommandLinkButton::initTestCase() +{ + // Create the test class + testWidget = new QCommandLinkButton( "&Start", 0 ); + testWidget->setObjectName("testWidget"); + testWidget->resize( 200, 200 ); + testWidget->show(); + + connect( testWidget, SIGNAL(clicked()), this, SLOT(onClicked()) ); + connect( testWidget, SIGNAL(pressed()), this, SLOT(onPressed()) ); + connect( testWidget, SIGNAL(released()), this, SLOT(onReleased()) ); + connect( testWidget, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)) ); +} + +void tst_QCommandLinkButton::cleanupTestCase() +{ + delete testWidget; + testWidget = 0; +} + +void tst_QCommandLinkButton::init() +{ + testWidget->setAutoRepeat( FALSE ); + testWidget->setDown( FALSE ); + testWidget->setText("Test"); + testWidget->setDescription("Description text."); + testWidget->setEnabled( TRUE ); + QKeySequence seq; + testWidget->setShortcut( seq ); + + resetCounters(); +} + +void tst_QCommandLinkButton::cleanup() +{ +} + + +void tst_QCommandLinkButton::resetCounters() +{ + toggle_count = 0; + press_count = 0; + release_count = 0; + click_count = 0; +} + +void tst_QCommandLinkButton::onClicked() +{ + click_count++; +} + +void tst_QCommandLinkButton::onToggled( bool /*on*/ ) +{ + toggle_count++; +} + +void tst_QCommandLinkButton::onPressed() +{ + press_count++; +} + +void tst_QCommandLinkButton::onReleased() +{ + release_count++; +} + +void tst_QCommandLinkButton::setAutoRepeat() +{ + // Give the last tests time to finish - i.e., wait for the window close + // and deactivate to avoid a race condition here. We can't add this to the + // end of the defaultAndAutoDefault test, since any failure in that test + // will return out of that function. + QTest::qWait( 1000 ); + + // If this changes, this test must be completely revised. + QVERIFY( !testWidget->isCheckable() ); + + // verify autorepeat is off by default. + QCommandLinkButton tmp( 0 ); + tmp.setObjectName("tmp"); + QVERIFY( !tmp.autoRepeat() ); + + // check if we can toggle the mode + testWidget->setAutoRepeat( TRUE ); + QVERIFY( testWidget->autoRepeat() ); + + testWidget->setAutoRepeat( FALSE ); + QVERIFY( !testWidget->autoRepeat() ); + + resetCounters(); + + // check that the button is down if we press space and not in autorepeat + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QTest::keyPress( testWidget, Qt::Key_Space ); + + QTest::qWait( 300 ); + + QVERIFY( testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 1 ); + QVERIFY( release_count == 0 ); + QVERIFY( click_count == 0 ); + + QTest::keyRelease( testWidget, Qt::Key_Space ); + resetCounters(); + + // check that the button is down if we press space while in autorepeat + // we can't actually confirm how many times it is fired, more than 1 is enough. + + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( TRUE ); + QTest::keyPress( testWidget, Qt::Key_Space ); + QTest::qWait(900); + QVERIFY( testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QTest::keyRelease( testWidget, Qt::Key_Space ); + QVERIFY(press_count == release_count); + QVERIFY(release_count == click_count); + QVERIFY(press_count > 1); + + // #### shouldn't I check here to see if multiple signals have been fired??? + + // check that pressing ENTER has no effect + resetCounters(); + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( FALSE ); + QTest::keyPress( testWidget, Qt::Key_Enter ); + + QTest::qWait( 300 ); + + QVERIFY( !testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 0 ); + QVERIFY( release_count == 0 ); + QVERIFY( click_count == 0 ); + QTest::keyRelease( testWidget, Qt::Key_Enter ); + + // check that pressing ENTER has no effect + resetCounters(); + testWidget->setDown( FALSE ); + testWidget->setAutoRepeat( TRUE ); + QTest::keyClick( testWidget, Qt::Key_Enter ); + QTest::qWait( 300 ); + QVERIFY( !testWidget->isDown() ); + QVERIFY( toggle_count == 0 ); + QVERIFY( press_count == 0 ); + QVERIFY( release_count == 0 ); + QVERIFY( click_count == 0 ); +} + +void tst_QCommandLinkButton::pressed() +{ + QTest::keyPress( testWidget, ' ' ); +// QTest::qWait( 300 ); + QCOMPARE( press_count, (uint)1 ); + QCOMPARE( release_count, (uint)0 ); + + QTest::keyRelease( testWidget, ' ' ); +// QTest::qWait( 300 ); + QCOMPARE( press_count, (uint)1 ); + QCOMPARE( release_count, (uint)1 ); + + QTest::keyPress( testWidget,Qt::Key_Enter ); +// QTest::qWait( 300 ); + QCOMPARE( press_count, (uint)1 ); + QCOMPARE( release_count, (uint)1 ); + + testWidget->setAutoDefault(true); + QTest::keyPress( testWidget,Qt::Key_Enter ); +// QTest::qWait( 300 ); + QCOMPARE( press_count, (uint)2 ); + QCOMPARE( release_count, (uint)2 ); + testWidget->setAutoDefault(false); + +} + + + +void tst_QCommandLinkButton::isCheckable() +{ + QVERIFY( !testWidget->isCheckable() ); +} + +void tst_QCommandLinkButton::setDown() +{ + testWidget->setDown( FALSE ); + QVERIFY( !testWidget->isDown() ); + + testWidget->setDown( TRUE ); + QVERIFY( testWidget->isDown() ); + + testWidget->setDown( TRUE ); + QTest::keyClick( testWidget, Qt::Key_Escape ); + QVERIFY( !testWidget->isDown() ); +} + +void tst_QCommandLinkButton::isChecked() +{ + testWidget->setDown( FALSE ); + QVERIFY( !testWidget->isChecked() ); + + testWidget->setDown( TRUE ); + QVERIFY( !testWidget->isChecked() ); + + testWidget->setDown( FALSE ); + testWidget->toggle(); + QVERIFY( testWidget->isChecked() == testWidget->isCheckable() ); +} + +void tst_QCommandLinkButton::toggle() +{ + // the pushbutton shouldn't toggle the button. + testWidget->toggle(); + QVERIFY( testWidget->isChecked() == FALSE ); +} + +void tst_QCommandLinkButton::toggled() +{ + // the pushbutton shouldn't send a toggled signal when we call the toggle slot. + QVERIFY( !testWidget->isCheckable() ); + + testWidget->toggle(); + QVERIFY( toggle_count == 0 ); + + // do it again, just to be sure + resetCounters(); + testWidget->toggle(); + QVERIFY( toggle_count == 0 ); + + // finally check that we can toggle using the mouse + resetCounters(); + QTest::mousePress( testWidget, Qt::LeftButton ); + QVERIFY( toggle_count == 0 ); + QVERIFY( click_count == 0 ); + + QTest::mouseRelease( testWidget, Qt::LeftButton ); + QVERIFY( click_count == 1 ); +} + +/* + If we press an accelerator key we ONLY get a pressed signal and + NOT a released or clicked signal. +*/ + +void tst_QCommandLinkButton::setAccel() +{ + testWidget->setText("&AccelTest"); + QKeySequence seq( Qt::ALT + Qt::Key_A ); + testWidget->setShortcut( seq ); + + // The shortcut will not be activated unless the button is in a active + // window and has focus + testWidget->setFocus(); + for (int i = 0; !testWidget->isActiveWindow() && i < 1000; ++i) { + testWidget->activateWindow(); + QApplication::instance()->processEvents(); + QTest::qWait(100); + } + + QVERIFY(testWidget->isActiveWindow()); + + QTest::keyClick( testWidget, 'A', Qt::AltModifier ); + QTest::qWait( 500 ); + QVERIFY( click_count == 1 ); + QVERIFY( press_count == 1 ); + QVERIFY( release_count == 1 ); + QVERIFY( toggle_count == 0 ); + + // wait 200 ms because setAccel uses animateClick. + // if we don't wait this may screw up a next test. + QTest::qWait(200); +} + +void tst_QCommandLinkButton::animateClick() +{ + QVERIFY( !testWidget->isDown() ); + testWidget->animateClick(); + QVERIFY( testWidget->isDown() ); + QTest::qWait( 200 ); + QVERIFY( !testWidget->isDown() ); + + QVERIFY( click_count == 1 ); + QVERIFY( press_count == 1 ); + QVERIFY( release_count == 1 ); + QVERIFY( toggle_count == 0 ); +} + +void tst_QCommandLinkButton::clicked() +{ + QTest::mousePress( testWidget, Qt::LeftButton ); + QVERIFY( press_count == 1 ); + QVERIFY( release_count == 0 ); + + QTest::mouseRelease( testWidget, Qt::LeftButton ); + QCOMPARE( press_count, (uint)1 ); + QCOMPARE( release_count, (uint)1 ); + + press_count = 0; + release_count = 0; + testWidget->setDown(FALSE); + for (uint i=0; i<10; i++) + QTest::mouseClick( testWidget, Qt::LeftButton ); + QCOMPARE( press_count, (uint)10 ); + QCOMPARE( release_count, (uint)10 ); +} + +QCommandLinkButton *pb = 0; +void tst_QCommandLinkButton::helperSlotDelete() +{ + delete pb; + pb = 0; +} + +void tst_QCommandLinkButton::popupCrash() +{ + pb = new QCommandLinkButton("foo", "description"); + QMenu *menu = new QMenu("bar", pb); + pb->setMenu(menu); + QTimer::singleShot(1000, this, SLOT(helperSlotDelete())); + pb->show(); + pb->click(); +} + +void tst_QCommandLinkButton::defaultAndAutoDefault() +{ + { + // Adding buttons directly to QDialog + QDialog dialog; + + QCommandLinkButton button1(&dialog); + QVERIFY(button1.autoDefault()); + QVERIFY(!button1.isDefault()); + + QCommandLinkButton button2(&dialog); + QVERIFY(button2.autoDefault()); + QVERIFY(!button2.isDefault()); + + button1.setDefault(true); + QVERIFY(button1.autoDefault()); + QVERIFY(button1.isDefault()); + QVERIFY(button2.autoDefault()); + QVERIFY(!button2.isDefault()); + + dialog.show(); + QVERIFY(dialog.isVisible()); + + QObject::connect(&button1, SIGNAL(clicked()), &dialog, SLOT(hide())); + QKeyEvent event(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); + QApplication::sendEvent(&dialog, &event); + QVERIFY(!dialog.isVisible()); + } + + { + // Adding buttons to QDialog through a layout + QDialog dialog; + + QCommandLinkButton button3; + button3.setAutoDefault(false); + + QCommandLinkButton button1; + QVERIFY(!button1.autoDefault()); + QVERIFY(!button1.isDefault()); + + QCommandLinkButton button2; + QVERIFY(!button2.autoDefault()); + QVERIFY(!button2.isDefault()); + + button1.setDefault(true); + QVERIFY(!button1.autoDefault()); + QVERIFY(button1.isDefault()); + QVERIFY(!button2.autoDefault()); + QVERIFY(!button2.isDefault()); + + QGridLayout layout; + layout.addWidget(&button3, 0, 3); + layout.addWidget(&button2, 0, 2); + layout.addWidget(&button1, 0, 1); + dialog.setLayout(&layout); + button3.setFocus(); + QVERIFY(button1.autoDefault()); + QVERIFY(button1.isDefault()); + QVERIFY(button2.autoDefault()); + QVERIFY(!button2.isDefault()); + + dialog.show(); + QVERIFY(dialog.isVisible()); + + QObject::connect(&button1, SIGNAL(clicked()), &dialog, SLOT(hide())); + QKeyEvent event(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); + QApplication::sendEvent(&dialog, &event); + QVERIFY(!dialog.isVisible()); + } + + { + // autoDefault behavior. + QDialog dialog; + QCommandLinkButton button2(&dialog); + QCommandLinkButton button1(&dialog); + dialog.show(); + QVERIFY(dialog.isVisible()); + + // No default button is set, and button2 is the first autoDefault button + // that is next in the tab order + QObject::connect(&button2, SIGNAL(clicked()), &dialog, SLOT(hide())); + QKeyEvent event(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier); + QApplication::sendEvent(&dialog, &event); + QVERIFY(!dialog.isVisible()); + + // Reparenting + QVERIFY(button2.autoDefault()); + button2.setParent(0); + QVERIFY(!button2.autoDefault()); + button2.setAutoDefault(false); + button2.setParent(&dialog); + QVERIFY(!button2.autoDefault()); + + button1.setAutoDefault(true); + button1.setParent(0); + QVERIFY(button1.autoDefault()); + } +} + +void tst_QCommandLinkButton::heightForWithWithIcon() +{ + QWidget mainWin; + + QPixmap pixmap(64, 64); + { + pixmap.fill(Qt::white); + QPainter painter(&pixmap); + painter.setBrush(Qt::black); + painter.drawEllipse(0, 0, 63, 63); + } + + QCommandLinkButton *largeIconButton = new QCommandLinkButton(QString("Large Icon"), + QString("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Mauris nibh lectus, adipiscing eu."), + &mainWin); + largeIconButton->setIconSize(QSize(64, 64)); + largeIconButton->setIcon(pixmap); + + QVBoxLayout *layout = new QVBoxLayout(); + layout->addWidget(largeIconButton); + layout->addStretch(); + mainWin.setLayout(layout); + mainWin.showMaximized(); + QTest::qWaitForWindowShown(&mainWin); + QVERIFY(largeIconButton->height() > 68); //enough room for the icon + +} + +QTEST_MAIN(tst_QCommandLinkButton) +#include "tst_qcommandlinkbutton.moc" diff --git a/tests/auto/widgets/widgets/qdatetimeedit/.gitignore b/tests/auto/widgets/widgets/qdatetimeedit/.gitignore new file mode 100644 index 0000000000..a68e3269d2 --- /dev/null +++ b/tests/auto/widgets/widgets/qdatetimeedit/.gitignore @@ -0,0 +1 @@ +tst_qdatetimeedit diff --git a/tests/auto/widgets/widgets/qdatetimeedit/qdatetimeedit.pro b/tests/auto/widgets/widgets/qdatetimeedit/qdatetimeedit.pro new file mode 100644 index 0000000000..47356d448c --- /dev/null +++ b/tests/auto/widgets/widgets/qdatetimeedit/qdatetimeedit.pro @@ -0,0 +1,8 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qdatetimeedit.cpp + +wincewm50smart-msvc2005: DEFINES += WINCE_NO_MODIFIER_KEYS + + + diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp new file mode 100644 index 0000000000..c64c9e7019 --- /dev/null +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -0,0 +1,3458 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <qapplication.h> +#include <qgroupbox.h> +#include <qlineedit.h> +#include <qwindowsstyle.h> + + + +#include <qdatetimeedit.h> +#include <qlocale.h> +#include <qlayout.h> +#include <qeventloop.h> +#include <qstyle.h> +#include <qstyle.h> +#include <QStyleOptionSpinBox> +#include <QDate> +#include <QDateTime> +#include <QTime> +#include <QList> +#include <QDateTimeEdit> +#include <QCalendarWidget> +#include <QWidget> +#include <QLineEdit> +#include <QObject> +#include <QLocale> +#include <QString> +#include <QVariantList> +#include <QVariant> +#include <QApplication> +#include <QPoint> +#include <QVBoxLayout> +#include <QRect> +#include <QCursor> +#include <QEventLoop> +#include <QStyle> +#include <QStyleOptionComboBox> +#include <QTimeEdit> +#include <QMetaType> +#include <QDebug> +#include <QWheelEvent> +#include <QTest> +#include <QSignalSpy> +#include <QTestEventList> +#include <QDateEdit> + +#ifdef Q_OS_WIN +# include <windows.h> +# undef min +# undef max +#endif + + +Q_DECLARE_METATYPE(QDate); +Q_DECLARE_METATYPE(Qt::Key); +Q_DECLARE_METATYPE(Qt::KeyboardModifiers); +Q_DECLARE_METATYPE(Qt::KeyboardModifier); +Q_DECLARE_METATYPE(QDateTime); +Q_DECLARE_METATYPE(QTime); +Q_DECLARE_METATYPE(QList<int>); + +#if defined(Q_OS_WINCE) +bool qt_wince_is_platform(const QString &platformString) { + wchar_t tszPlatform[64]; + if (SystemParametersInfo(SPI_GETPLATFORMTYPE, + sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0)) + if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform)) + return true; + return false; +} +bool qt_wince_is_pocket_pc() { + return qt_wince_is_platform(QString::fromLatin1("PocketPC")); +} +bool qt_wince_is_smartphone() { + return qt_wince_is_platform(QString::fromLatin1("Smartphone")); +} +bool qt_wince_is_mobile() { + return (qt_wince_is_smartphone() || qt_wince_is_pocket_pc()); +} +#endif + + +//TESTED_CLASS= +//TESTED_FILES= + +class EditorDateEdit : public QDateTimeEdit +{ + Q_OBJECT +public: + EditorDateEdit(QWidget *parent = 0) : QDateTimeEdit(parent) {} + QLineEdit *lineEdit() { return QDateTimeEdit::lineEdit(); } + friend class tst_QDateTimeEdit; +}; + +class tst_QDateTimeEdit : public QObject +{ + Q_OBJECT +public: + tst_QDateTimeEdit(); + virtual ~tst_QDateTimeEdit(); +public slots: + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); +private slots: + void cachedDayTest(); + void getSetCheck(); + void constructor_qwidget(); + void constructor_qdatetime_data(); + void constructor_qdatetime(); + void constructor_qdate_data(); + void constructor_qdate(); + void constructor_qtime_data(); + void constructor_qtime(); + + void sectionText_data(); + void sectionText(); + void dateTimeSignalChecking_data(); + void dateTimeSignalChecking(); + void mousePress(); + void stepHourAMPM_data(); + + void stepHourAMPM(); + void displayedSections_data(); + void displayedSections(); + void currentSection_data(); + void currentSection(); + + void setCurrentSection(); + void setCurrentSection_data(); + + void minimumDate_data(); + void minimumDate(); + void maximumDate_data(); + void maximumDate(); + void clearMinimumDate_data(); + void clearMinimumDate(); + void clearMaximumDate_data(); + void clearMaximumDate(); + + void minimumDateTime_data(); + void minimumDateTime(); + void maximumDateTime_data(); + void maximumDateTime(); + + void clearMinimumDateTime_data(); + void clearMinimumDateTime(); + void clearMaximumDateTime_data(); + void clearMaximumDateTime(); + + void displayFormat_data(); + void displayFormat(); + + void specialValueText(); + void setRange_data(); + void setRange(); + + void selectAndScrollWithKeys(); + void backspaceKey(); + void deleteKey(); + void tabKeyNavigation(); + void tabKeyNavigationWithPrefix(); + void tabKeyNavigationWithSuffix(); + void enterKey(); + + void readOnly(); + + void wrappingDate_data(); + void wrappingDate(); + + void dateSignalChecking_data(); + void dateSignalChecking(); + + void wrappingTime_data(); + void wrappingTime(); + + void userKeyPress_Time_data(); + void userKeyPress_Time(); + + void timeSignalChecking_data(); + void timeSignalChecking(); + + void weirdCase(); + void newCase(); + void newCase2(); + void newCase3(); + void newCase4(); + void newCase5(); + void newCase6(); + + void task98554(); + void task149097(); + + void cursorPos(); + void calendarPopup(); + + void hour12Test(); + void yyTest(); + void task108572(); + + void task148725(); + void task148522(); + + void setSelectedSection(); + void reverseTest(); + + void ddMMMMyyyy(); + void wheelEvent(); + + void specialValueCornerCase(); + void cursorPositionOnInit(); + + void task118867(); + + void nextPrevSection_data(); + void nextPrevSection(); + + void dateEditTimeEditFormats(); + void timeSpec_data(); + void timeSpec(); + void timeSpecBug(); + + void monthEdgeCase(); + void setLocale(); + + void potentialYYValueBug(); + void textSectionAtEnd(); + + void keypadAutoAdvance_data(); + void keypadAutoAdvance(); + + void task196924(); + void focusNextPrevChild(); + + void taskQTBUG_12384_timeSpecShowTimeOnly(); + + void deleteCalendarWidget(); + +private: + EditorDateEdit* testWidget; + QWidget *testFocusWidget; +}; + +typedef QList<QTime> TimeList; +typedef QList<Qt::Key> KeyList; + +Q_DECLARE_METATYPE(TimeList) +Q_DECLARE_METATYPE(KeyList) + +// Testing get/set functions +void tst_QDateTimeEdit::getSetCheck() +{ + QDateTimeEdit obj1; + obj1.setDisplayFormat("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z AP"); + // Section QDateTimeEdit::currentSection() + // void QDateTimeEdit::setCurrentSection(Section) + obj1.setCurrentSection(QDateTimeEdit::NoSection); + QVERIFY(obj1.currentSection() != QDateTimeEdit::NoSection); + obj1.setCurrentSection(QDateTimeEdit::AmPmSection); + QCOMPARE(QDateTimeEdit::AmPmSection, obj1.currentSection()); + obj1.setCurrentSection(QDateTimeEdit::MSecSection); + QCOMPARE(QDateTimeEdit::MSecSection, obj1.currentSection()); + obj1.setCurrentSection(QDateTimeEdit::SecondSection); + QCOMPARE(QDateTimeEdit::SecondSection, obj1.currentSection()); + obj1.setCurrentSection(QDateTimeEdit::MinuteSection); + QCOMPARE(QDateTimeEdit::MinuteSection, obj1.currentSection()); + obj1.setCurrentSection(QDateTimeEdit::HourSection); + QCOMPARE(QDateTimeEdit::HourSection, obj1.currentSection()); + obj1.setCurrentSection(QDateTimeEdit::DaySection); + QCOMPARE(QDateTimeEdit::DaySection, obj1.currentSection()); + obj1.setCurrentSection(QDateTimeEdit::MonthSection); + QCOMPARE(QDateTimeEdit::MonthSection, obj1.currentSection()); + obj1.setCurrentSection(QDateTimeEdit::YearSection); + QCOMPARE(QDateTimeEdit::YearSection, obj1.currentSection()); +} + +tst_QDateTimeEdit::tst_QDateTimeEdit() +{ + qRegisterMetaType<QDate>("QDate"); + qRegisterMetaType<QTime>("QTime"); + qRegisterMetaType<QDateTime>("QDateTime"); + qRegisterMetaType<QList<int> >("QList<int>"); +} + +tst_QDateTimeEdit::~tst_QDateTimeEdit() +{ + +} + +void tst_QDateTimeEdit::initTestCase() +{ + QLocale system = QLocale::system(); + if (system.language() != QLocale::C && system.language() != QLocale::English) + qWarning("Running under locale %s/%s -- this test may generate failures due to language differences", + qPrintable(QLocale::languageToString(system.language())), + qPrintable(QLocale::countryToString(system.country()))); + testWidget = new EditorDateEdit(0); + testFocusWidget = new QWidget(0); + testFocusWidget->resize(200, 100); + testFocusWidget->show(); +} + +void tst_QDateTimeEdit::cleanupTestCase() +{ + delete testFocusWidget; + testFocusWidget = 0; + delete testWidget; + testWidget = 0; +} + + +void tst_QDateTimeEdit::init() +{ + QLocale::setDefault(QLocale(QLocale::C)); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)); +#endif + testWidget->setDisplayFormat("dd/MM/yyyy"); // Nice default to have + testWidget->setDateTime(QDateTime(QDate(2000, 1, 1), QTime(0, 0))); + testWidget->show(); + testFocusWidget->move(-1000, -1000); +} + +void tst_QDateTimeEdit::cleanup() +{ + testWidget->clearMinimumDateTime(); + testWidget->clearMaximumDateTime(); + testWidget->setTimeSpec(Qt::LocalTime); + testWidget->setSpecialValueText(QString()); + testWidget->setWrapping(false); +} + +void tst_QDateTimeEdit::constructor_qwidget() +{ + testWidget->hide(); + QDateTimeEdit dte(0); + dte.show(); + QCOMPARE(dte.dateTime(), QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0))); + QCOMPARE(dte.minimumDate(), QDate(1752, 9, 14)); + QCOMPARE(dte.minimumTime(), QTime(0, 0, 0, 0)); + QCOMPARE(dte.maximumDate(), QDate(7999, 12, 31)); + QCOMPARE(dte.maximumTime(), QTime(23, 59, 59, 999)); +} + +void tst_QDateTimeEdit::constructor_qdatetime_data() +{ + QTest::addColumn<QDateTime>("parameter"); + QTest::addColumn<QDateTime>("displayDateTime"); + QTest::addColumn<QDate>("minimumDate"); + QTest::addColumn<QTime>("minimumTime"); + QTest::addColumn<QDate>("maximumDate"); + QTest::addColumn<QTime>("maximumTime"); + + QTest::newRow("normal") << QDateTime(QDate(2004, 6, 16), QTime(13, 46, 32, 764)) + << QDateTime(QDate(2004, 6, 16), QTime(13, 46, 32, 764)) + << QDate(1752, 9, 14) << QTime(0, 0, 0, 0) + << QDate(7999, 12, 31) << QTime(23, 59, 59, 999); + + QTest::newRow("invalid") << QDateTime(QDate(9999, 99, 99), QTime(13, 46, 32, 764)) + << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0)) + << QDate(1752, 9, 14) << QTime(0, 0, 0, 0) + << QDate(7999, 12, 31) << QTime(23, 59, 59, 999); +} + + + +void tst_QDateTimeEdit::constructor_qdatetime() +{ + QFETCH(QDateTime, parameter); + QFETCH(QDateTime, displayDateTime); + QFETCH(QDate, minimumDate); + QFETCH(QTime, minimumTime); + QFETCH(QDate, maximumDate); + QFETCH(QTime, maximumTime); + + testWidget->hide(); + + QDateTimeEdit dte(parameter); + dte.show(); + QCOMPARE(dte.dateTime(), displayDateTime); + QCOMPARE(dte.minimumDate(), minimumDate); + QCOMPARE(dte.minimumTime(), minimumTime); + QCOMPARE(dte.maximumDate(), maximumDate); + QCOMPARE(dte.maximumTime(), maximumTime); +} + +void tst_QDateTimeEdit::constructor_qdate_data() +{ + QTest::addColumn<QDate>("parameter"); + QTest::addColumn<QDateTime>("displayDateTime"); + QTest::addColumn<QDate>("minimumDate"); + QTest::addColumn<QTime>("minimumTime"); + QTest::addColumn<QDate>("maximumDate"); + QTest::addColumn<QTime>("maximumTime"); + + QTest::newRow("normal") << QDate(2004, 6, 16) + << QDateTime(QDate(2004, 6, 16), QTime(0, 0, 0, 0)) + << QDate(1752, 9, 14) << QTime(0, 0, 0, 0) + << QDate(7999, 12, 31) << QTime(23, 59, 59, 999); + + QTest::newRow("invalid") << QDate(9999, 99, 99) + << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0)) + << QDate(1752, 9, 14) << QTime(0, 0, 0, 0) + << QDate(7999, 12, 31) << QTime(23, 59, 59, 999); +} + + + +void tst_QDateTimeEdit::constructor_qdate() +{ + QFETCH(QDate, parameter); + QFETCH(QDateTime, displayDateTime); + QFETCH(QDate, minimumDate); + QFETCH(QTime, minimumTime); + QFETCH(QDate, maximumDate); + QFETCH(QTime, maximumTime); + + testWidget->hide(); + + QDateTimeEdit dte(parameter); + dte.show(); + QCOMPARE(dte.dateTime(), displayDateTime); + QCOMPARE(dte.minimumDate(), minimumDate); + QCOMPARE(dte.minimumTime(), minimumTime); + QCOMPARE(dte.maximumDate(), maximumDate); + QCOMPARE(dte.maximumTime(), maximumTime); +} + +void tst_QDateTimeEdit::constructor_qtime_data() +{ + QTest::addColumn<QTime>("parameter"); + QTest::addColumn<QDateTime>("displayDateTime"); + QTest::addColumn<QDate>("minimumDate"); + QTest::addColumn<QTime>("minimumTime"); + QTest::addColumn<QDate>("maximumDate"); + QTest::addColumn<QTime>("maximumTime"); + + QTest::newRow("normal") << QTime(13, 46, 32, 764) + << QDateTime(QDate(2000, 1, 1), QTime(13, 46, 32, 764)) + << QDate(2000, 1, 1) << QTime(0, 0, 0, 0) + << QDate(2000, 1, 1) << QTime(23, 59, 59, 999); + + QTest::newRow("invalid") << QTime(99, 99, 99, 5000) + << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0)) + << QDate(2000, 1, 1) << QTime(0, 0, 0, 0) + << QDate(2000, 1, 1) << QTime(23, 59, 59, 999); +} + + + +void tst_QDateTimeEdit::constructor_qtime() +{ + QFETCH(QTime, parameter); + QFETCH(QDateTime, displayDateTime); + QFETCH(QDate, minimumDate); + QFETCH(QTime, minimumTime); + QFETCH(QDate, maximumDate); + QFETCH(QTime, maximumTime); + + testWidget->hide(); + + QDateTimeEdit dte(parameter); + dte.show(); + QCOMPARE(dte.dateTime(), displayDateTime); + QCOMPARE(dte.minimumDate(), minimumDate); + QCOMPARE(dte.minimumTime(), minimumTime); + QCOMPARE(dte.maximumDate(), maximumDate); + QCOMPARE(dte.maximumTime(), maximumTime); +} + +void tst_QDateTimeEdit::minimumDate_data() +{ + QTest::addColumn<QDate>("minimumDate"); + QTest::addColumn<QDate>("expectedMinDate"); + + QTest::newRow("normal-0") << QDate(2004, 5, 10) << QDate(2004, 5, 10); + QTest::newRow("normal-1") << QDate(2002, 3, 15) << QDate(2002, 3, 15); + QTest::newRow("normal-2") << QDate(7999, 12, 31) << QDate(7999, 12, 31); + QTest::newRow("normal-3") << QDate(1753, 1, 1) << QDate(1753, 1, 1); + QTest::newRow("invalid-0") << QDate(0, 0, 0) << QDate(1752, 9, 14); + QTest::newRow("old") << QDate(1492, 8, 3) << QDate(1492, 8, 3); +} + +void tst_QDateTimeEdit::minimumDate() +{ + QFETCH(QDate, minimumDate); + QFETCH(QDate, expectedMinDate); + + testWidget->setMinimumDate(minimumDate); + QCOMPARE(testWidget->minimumDate(), expectedMinDate); +} + +void tst_QDateTimeEdit::minimumDateTime_data() +{ + QTest::addColumn<QDateTime>("minimumDateTime"); + QTest::addColumn<QDateTime>("expectedMinDateTime"); + + QTest::newRow("normal-0") << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14)) + << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14)); + + QTest::newRow("normal-1") << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1)) + << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1)); + QTest::newRow("normal-2") << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23)) + << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23)); + QTest::newRow("normal-3") << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23)) + << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23)); + QTest::newRow("normal-4") << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1)) + << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1)); + QTest::newRow("invalid-0") << QDateTime() << QDateTime(QDate(1752, 9, 14), QTime(0, 0, 0)); + QTest::newRow("old") << QDateTime(QDate(1492, 8, 3), QTime(2, 3, 1)) + << QDateTime(QDate(1492, 8, 3), QTime(2, 3, 1)); +} + +void tst_QDateTimeEdit::minimumDateTime() +{ + QFETCH(QDateTime, minimumDateTime); + QFETCH(QDateTime, expectedMinDateTime); + + testWidget->setMinimumDateTime(minimumDateTime); + QCOMPARE(testWidget->minimumDateTime(), expectedMinDateTime); +} + + +void tst_QDateTimeEdit::maximumDateTime_data() +{ + QTest::addColumn<QDateTime>("maximumDateTime"); + QTest::addColumn<QDateTime>("expectedMinDateTime"); + + QTest::newRow("normal-0") << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14)) + << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14)); + + QTest::newRow("normal-1") << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1)) + << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1)); + QTest::newRow("normal-2") << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23)) + << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23)); + QTest::newRow("normal-3") << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23)) + << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23)); + QTest::newRow("normal-4") << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1)) + << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1)); + QTest::newRow("invalid-0") << QDateTime() << QDateTime(QDate(7999, 12, 31), QTime(23, 59, 59, 999)); +} + +void tst_QDateTimeEdit::maximumDateTime() +{ + QFETCH(QDateTime, maximumDateTime); + QFETCH(QDateTime, expectedMinDateTime); + + testWidget->setMaximumDateTime(maximumDateTime); + QCOMPARE(testWidget->maximumDateTime(), expectedMinDateTime); +} + +void tst_QDateTimeEdit::maximumDate_data() +{ + QTest::addColumn<QDate>("maximumDate"); + QTest::addColumn<QDate>("expectedMaxDate"); + + QTest::newRow("normal-0") << QDate(2004, 05, 10) << QDate(2004, 5, 10); + QTest::newRow("normal-1") << QDate(2002, 03, 15) << QDate(2002, 3, 15); + QTest::newRow("normal-2") << QDate(7999, 12, 31) << QDate(7999, 12, 31); + QTest::newRow("normal-3") << QDate(1753, 1, 1) << QDate(1753, 1, 1); + QTest::newRow("invalid-0") << QDate(0, 0, 0) << QDate(7999, 12, 31); +} + +void tst_QDateTimeEdit::maximumDate() +{ + QFETCH(QDate, maximumDate); + QFETCH(QDate, expectedMaxDate); + + testWidget->setMaximumDate(maximumDate); + QCOMPARE(testWidget->maximumDate(), expectedMaxDate); +} + +void tst_QDateTimeEdit::clearMinimumDate_data() +{ + QTest::addColumn<QDate>("minimumDate"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<QDate>("expectedMinDateAfterClear"); + + QTest::newRow("normal-0") << QDate(2004, 05, 10) << true << QDate(1752, 9, 14); + QTest::newRow("normal-1") << QDate(2002, 3, 15) << true << QDate(1752, 9, 14); + QTest::newRow("normal-2") << QDate(7999, 12, 31) << true << QDate(1752, 9, 14); + QTest::newRow("normal-3") << QDate(1753, 1, 1) << true << QDate(1752, 9, 14); + QTest::newRow("invalid-0") << QDate(0, 0, 0) << false << QDate(1752, 9, 14); +} + +void tst_QDateTimeEdit::clearMinimumDate() +{ + QFETCH(QDate, minimumDate); + QFETCH(bool, valid); + QFETCH(QDate, expectedMinDateAfterClear); + + testWidget->setMinimumDate(minimumDate); + if (valid) { + QCOMPARE(testWidget->minimumDate(), minimumDate); + } + testWidget->clearMinimumDate(); + QCOMPARE(testWidget->minimumDate(), expectedMinDateAfterClear); +} + +void tst_QDateTimeEdit::clearMinimumDateTime_data() +{ + QTest::addColumn<QDateTime>("minimumDateTime"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<QDateTime>("expectedMinDateTimeAfterClear"); + + QTest::newRow("normal-0") << QDateTime(QDate(2004, 05, 10), QTime(12, 12, 12)) + << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0)); + QTest::newRow("normal-1") << QDateTime(QDate(2002, 3, 15), QTime(13, 13, 13)) + << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0)); + QTest::newRow("normal-2") << QDateTime(QDate(7999, 12, 31), QTime(14, 14, 14)) + << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0)); + QTest::newRow("normal-3") << QDateTime(QDate(1753, 1, 1), QTime(15, 15, 15)) + << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0)); + QTest::newRow("invalid-0") << QDateTime() << false << QDateTime(QDate(1752, 9, 14), QTime(0, 0)); + QTest::newRow("old") << QDateTime(QDate(1492, 8, 3), QTime(2, 3, 1)) << true + << QDateTime(QDate(1752, 9, 14), QTime(0, 0)); + +} + +void tst_QDateTimeEdit::clearMinimumDateTime() +{ + QFETCH(QDateTime, minimumDateTime); + QFETCH(bool, valid); + QFETCH(QDateTime, expectedMinDateTimeAfterClear); + + testWidget->setMinimumDateTime(minimumDateTime); + if (valid) { + QCOMPARE(testWidget->minimumDateTime(), minimumDateTime); + } + testWidget->clearMinimumDateTime(); + QCOMPARE(testWidget->minimumDateTime(), expectedMinDateTimeAfterClear); +} + + +void tst_QDateTimeEdit::clearMaximumDateTime_data() +{ + QTest::addColumn<QDateTime>("maximumDateTime"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<QDateTime>("expectedMinDateTimeAfterClear"); + + QTest::newRow("normal-0") << QDateTime(QDate(2004, 05, 10), QTime(12, 12, 12)) + << true << QDateTime(QDate(7999, 12, 31), QTime(23, 59, 59, 999)); + QTest::newRow("normal-1") << QDateTime(QDate(2002, 3, 15), QTime(13, 13, 13)) + << true << QDateTime(QDate(7999, 12, 31), QTime(23, 59, 59, 999)); + QTest::newRow("normal-2") << QDateTime(QDate(7999, 12, 31), QTime(14, 14, 14)) + << true << QDateTime(QDate(7999, 12, 31), QTime(23, 59, 59, 999)); + QTest::newRow("normal-3") << QDateTime(QDate(1753, 1, 1), QTime(15, 15, 15)) + << true << QDateTime(QDate(7999, 12, 31), QTime(23, 59, 59, 999)); + QTest::newRow("invalid-0") << QDateTime() + << false << QDateTime(QDate(7999, 12, 31), QTime(23, 59, 59, 999)); +} + +void tst_QDateTimeEdit::clearMaximumDateTime() +{ + QFETCH(QDateTime, maximumDateTime); + QFETCH(bool, valid); + QFETCH(QDateTime, expectedMinDateTimeAfterClear); + + testWidget->setMaximumDateTime(maximumDateTime); + if (valid) { + QCOMPARE(testWidget->maximumDateTime(), maximumDateTime); + } + testWidget->clearMaximumDateTime(); + QCOMPARE(testWidget->maximumDateTime(), expectedMinDateTimeAfterClear); +} + + +void tst_QDateTimeEdit::clearMaximumDate_data() +{ + QTest::addColumn<QDate>("maximumDate"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<QDate>("expectedMaxDateAfterClear"); + + QTest::newRow("normal-0") << QDate(2004, 05, 10) << true << QDate(7999, 12, 31); + QTest::newRow("normal-1") << QDate(2002, 03, 15) << true << QDate(7999, 12, 31); + QTest::newRow("normal-2") << QDate(7999, 12, 31) << true << QDate(7999, 12, 31); + QTest::newRow("normal-3") << QDate(2000, 1, 1) << true << QDate(7999, 12, 31); + QTest::newRow("invalid-0") << QDate(0, 0, 0) << false << QDate(7999, 12, 31); +} + +void tst_QDateTimeEdit::clearMaximumDate() +{ + QFETCH(QDate, maximumDate); + QFETCH(bool, valid); + QFETCH(QDate, expectedMaxDateAfterClear); + + testWidget->setMaximumDate(maximumDate); + if (valid) { + QCOMPARE(testWidget->maximumDate(), maximumDate); + } + testWidget->clearMaximumDate(); + QCOMPARE(testWidget->maximumDate(), expectedMaxDateAfterClear); +} + +void tst_QDateTimeEdit::displayFormat_data() +{ + QTest::addColumn<QString>("format"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<QString>("text"); + QTest::addColumn<QDateTime>("date"); + + const QDateTime dt(QDate(2999, 12, 31), QTime(3, 59, 59, 999)); + + QTest::newRow("valid-0") << QString("yyyy MM dd") << true << QString("2999 12 31") << dt; + QTest::newRow("valid-1") << QString("dd MM yyyy::ss:mm:hh") << true + << QString("31 12 2999::59:59:03") << dt; + QTest::newRow("valid-2") << QString("hh-dd-mm-MM-yy") << true << QString("03-31-59-12-99") << dt; + QTest::newRow("valid-3") << QString("ddd MM d yyyy::ss:mm:hh") << true + << QDate::shortDayName(2) + " 12 31 2999::59:59:03" << dt; + QTest::newRow("valid-4") << QString("hh-dd-mm-MM-yyyy") << true << QString("03-31-59-12-2999") << dt; + QTest::newRow("invalid-0") << QString("yyyy.MM.yy") << true << QString("2999.12.99") << dt; + QTest::newRow("invalid-1") << QString("y") << false << QString() << dt; + QTest::newRow("invalid-2") << QString("") << false << QString() << dt; + QTest::newRow("quoted-1") << QString("'Midday is at:' dd") << true << QString("Midday is at: 31") << dt; + QTest::newRow("leading1") << QString("h:hh:hhh") << true << QString("3:03:033") << dt; + QTest::newRow("H1") << QString("HH:hh:ap") << true << QString("03:03:am") << dt; + QTest::newRow("H2") << QString("HH:hh:ap") << true << QString("23:11:pm") + << QDateTime(dt.date(), QTime(23, 0, 0)); +} + +void tst_QDateTimeEdit::displayFormat() +{ + QFETCH(QString, format); + QFETCH(bool, valid); + QFETCH(QString, text); + QFETCH(QDateTime, date); + + testWidget->setDateTime(date); + + QString compareFormat = format; + if (!valid) + compareFormat = testWidget->displayFormat(); + testWidget->setDisplayFormat(format); + QCOMPARE(testWidget->displayFormat(), compareFormat); + if (valid) + QCOMPARE(testWidget->text(), text); +} + +void tst_QDateTimeEdit::selectAndScrollWithKeys() +{ + qApp->setActiveWindow(testWidget); + testWidget->setDate(QDate(2004, 05, 11)); + testWidget->setDisplayFormat("dd/MM/yyyy"); + testWidget->show(); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("1")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/0")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/20")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/200")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004")); + + // Now the year part should be selected + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2005, 5, 11)); + QCOMPARE(testWidget->currentSection(), QDateTimeEdit::YearSection); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2005")); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2004, 5, 11)); + QCOMPARE(testWidget->currentSection(), QDateTimeEdit::YearSection); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004")); + + +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("4")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("04")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("/2004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("5/2004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05/2004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("1/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + + // Now the day part should be selected + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2004, 5, 12)); + QCOMPARE(testWidget->currentSection(), QDateTimeEdit::DaySection); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("12")); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2004, 5, 11)); + QCOMPARE(testWidget->currentSection(), QDateTimeEdit::DaySection); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); + +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); + // Now the day part should be selected + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2004, 05, 12)); +} + +void tst_QDateTimeEdit::backspaceKey() +{ + qApp->setActiveWindow(testWidget); + testWidget->setDate(QDate(2004, 05, 11)); + testWidget->setDisplayFormat("d/MM/yyyy"); + testWidget->show(); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QCOMPARE(testWidget->text(), QString("11/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/05/200")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/05/20")); + // Check that moving into another field reverts it + for (int i=0;i<3;i++) + QTest::keyClick(testWidget, Qt::Key_Left); + QCOMPARE(testWidget->text(), QString("11/05/2004")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + for (int i=0;i<4;i++) { + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ShiftModifier); + } + + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/05/")); + QTest::keyClick(testWidget, Qt::Key_Left); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/0/2004")); + testWidget->interpretText(); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/05/200")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/05/20")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/05/2")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/05/")); + QTest::keyClick(testWidget, Qt::Key_Left); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11/0/2004")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("11//2004")); + QTest::keyClick(testWidget, Qt::Key_Left); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("1/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(testWidget->text(), QString("1/05/2004")); +} + +void tst_QDateTimeEdit::deleteKey() +{ + qApp->setActiveWindow(testWidget); + testWidget->setDate(QDate(2004, 05, 11)); + testWidget->setDisplayFormat("d/MM/yyyy"); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QTest::keyClick(testWidget, Qt::Key_Delete); + QCOMPARE(testWidget->text(), QString("1/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Delete); + QCOMPARE(testWidget->text(), QString("/05/2004")); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QCOMPARE(testWidget->text(), QString("1/05/2004")); +} + +void tst_QDateTimeEdit::tabKeyNavigation() +{ + qApp->setActiveWindow(testWidget); + testWidget->setDate(QDate(2004, 05, 11)); + testWidget->setDisplayFormat("dd/MM/yyyy"); + testWidget->show(); + testWidget->setCurrentSection(QDateTimeEdit::DaySection); + + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05")); + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004")); + QTest::keyClick(testWidget, Qt::Key_Tab, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05")); + QTest::keyClick(testWidget, Qt::Key_Tab, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); +} + +void tst_QDateTimeEdit::tabKeyNavigationWithPrefix() +{ + qApp->setActiveWindow(testWidget); + testWidget->setDate(QDate(2004, 05, 11)); + testWidget->setDisplayFormat("prefix dd/MM/yyyy"); + + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05")); + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004")); + QTest::keyClick(testWidget, Qt::Key_Tab, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05")); + QTest::keyClick(testWidget, Qt::Key_Tab, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); +} + +void tst_QDateTimeEdit::tabKeyNavigationWithSuffix() +{ + qApp->setActiveWindow(testWidget); + testWidget->setDate(QDate(2004, 05, 11)); + testWidget->setDisplayFormat("dd/MM/yyyy 'suffix'"); + + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05")); + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004")); + QTest::keyClick(testWidget, Qt::Key_Tab, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05")); + QTest::keyClick(testWidget, Qt::Key_Tab, Qt::ShiftModifier); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); +} + + +void tst_QDateTimeEdit::enterKey() +{ + qApp->setActiveWindow(testWidget); + testWidget->setDate(QDate(2004, 5, 11)); + testWidget->setDisplayFormat("prefix d/MM/yyyy 'suffix'"); + testWidget->lineEdit()->setFocus(); + +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QTest::keyClick(testWidget, Qt::Key_Enter); + QVERIFY(!testWidget->lineEdit()->hasSelectedText()); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QTest::keyClick(testWidget, Qt::Key_Enter); + QVERIFY(!testWidget->lineEdit()->hasSelectedText()); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QTest::keyClick(testWidget, Qt::Key_Tab); + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); + QTest::keyClick(testWidget, Qt::Key_1); + QTest::keyClick(testWidget, Qt::Key_5); + + QTest::keyClick(testWidget, Qt::Key_Left); + QTest::keyClick(testWidget, Qt::Key_Left); + + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("15")); + QCOMPARE(testWidget->date(), QDate(2004, 5, 15)); + + QTest::keyClick(testWidget, Qt::Key_9); + QTest::keyClick(testWidget, Qt::Key_Tab, Qt::ShiftModifier); + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("9")); + QCOMPARE(testWidget->date(), QDate(2004, 5, 9)); + + QTest::keyClick(testWidget, Qt::Key_0); + QTest::keyClick(testWidget, Qt::Key_0); + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("9")); + QCOMPARE(testWidget->date(), QDate(2004, 5, 9)); + + QSignalSpy enterSpy(testWidget, SIGNAL(dateChanged(const QDate &))); + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(enterSpy.count(), 1); + +#if 0 + QVariantList list = enterSpy.takeFirst(); + QCOMPARE(list.at(0).toDate(), QDate(2004, 9, 15)); +#endif + +} + +void tst_QDateTimeEdit::specialValueText() +{ + testWidget->setDisplayFormat("dd/MM/yyyy"); + testWidget->setDateRange(QDate(2000, 1, 1), QDate(2001, 1, 1)); + testWidget->setDate(QDate(2000, 1, 2)); + testWidget->setSpecialValueText("fOo"); + testWidget->setCurrentSection(QDateTimeEdit::DaySection); + QCOMPARE(testWidget->date(), QDate(2000, 1, 2)); + QCOMPARE(testWidget->text(), QString("02/01/2000")); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2000, 1, 1)); + QCOMPARE(testWidget->text(), QString("fOo")); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2000, 1, 1)); + QCOMPARE(testWidget->text(), QString("fOo")); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2000, 1, 2)); + QCOMPARE(testWidget->text(), QString("02/01/2000")); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2000, 1, 1)); + QCOMPARE(testWidget->text(), QString("fOo")); + +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2000, 1, 2)); + QCOMPARE(testWidget->text(), QString("02/01/2000")); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->text(), QString("fOo")); + +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("fO")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString("f")); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString()); + QTest::keyClick(testWidget, Qt::Key_F); + QCOMPARE(testWidget->text(), QString("f")); + QTest::keyClick(testWidget, Qt::Key_O); // will automatically uppercase + QCOMPARE(testWidget->text(), QString("fO")); + QTest::keyClick(testWidget, Qt::Key_O); + QCOMPARE(testWidget->text(), QString("fOo")); +} + + +void tst_QDateTimeEdit::setRange_data() +{ + QTest::addColumn<QTime>("minTime"); + QTest::addColumn<QTime>("maxTime"); + QTest::addColumn<QDate>("minDate"); + QTest::addColumn<QDate>("maxDate"); + QTest::addColumn<QDateTime>("expectedMin"); + QTest::addColumn<QDateTime>("expectedMax"); + + const QDate cdt = QDate::currentDate(); + + QTest::newRow("data0") << QTime(0, 0) << QTime(14, 12, 0) + << cdt << cdt + << QDateTime(cdt, QTime(0, 0)) + << QDateTime(cdt, QTime(14, 12, 0)); + + QTest::newRow("data1") << QTime(10, 0) << QTime(1, 12, 0) << cdt.addDays(-1) + << cdt + << QDateTime(cdt.addDays(-1), QTime(10, 0)) + << QDateTime(cdt, QTime(1, 12, 0)); +} + +void tst_QDateTimeEdit::setRange() +{ + QFETCH(QTime, minTime); + QFETCH(QTime, maxTime); + QFETCH(QDate, minDate); + QFETCH(QDate, maxDate); + QFETCH(QDateTime, expectedMin); + QFETCH(QDateTime, expectedMax); + testWidget->hide(); + + { + QDateTimeEdit dte(0); + dte.setTimeRange(minTime, maxTime); + QCOMPARE(dte.minimumTime(), expectedMin.time()); + QCOMPARE(dte.maximumTime(), expectedMax.time()); + dte.setDateRange(minDate, maxDate); + QCOMPARE(dte.minimumDate(), expectedMin.date()); + QCOMPARE(dte.minimumDateTime(), expectedMin); + QCOMPARE(dte.maximumDate(), expectedMax.date()); + QCOMPARE(dte.maximumDateTime(), expectedMax); + QCOMPARE(dte.minimumTime(), expectedMin.time()); + QCOMPARE(dte.maximumTime(), expectedMax.time()); + dte.setDateTimeRange(QDateTime(minDate, minTime), QDateTime(maxDate, maxTime)); + QCOMPARE(dte.minimumDate(), expectedMin.date()); + QCOMPARE(dte.minimumDateTime(), expectedMin); + QCOMPARE(dte.maximumDate(), expectedMax.date()); + QCOMPARE(dte.maximumDateTime(), expectedMax); + QCOMPARE(dte.minimumTime(), expectedMin.time()); + QCOMPARE(dte.maximumTime(), expectedMax.time()); + } + { + + QDateTimeEdit dte2(0); + dte2.setDateRange(minDate, maxDate); + dte2.setTimeRange(minTime, maxTime); + + QCOMPARE(dte2.minimumDate(), expectedMin.date()); + QCOMPARE(dte2.maximumDate(), expectedMax.date()); + QCOMPARE(dte2.minimumTime(), expectedMin.time()); + QCOMPARE(dte2.maximumTime(), expectedMax.time()); + } + + { + QDateTimeEdit dte3(0); + dte3.setMinimumTime(minTime); + dte3.setMaximumTime(maxTime); + dte3.setMinimumDate(minDate); + dte3.setMaximumDate(maxDate); + + QCOMPARE(dte3.minimumDate(), expectedMin.date()); + QCOMPARE(dte3.maximumDate(), expectedMax.date()); + QCOMPARE(dte3.minimumTime(), expectedMin.time()); + QCOMPARE(dte3.maximumTime(), expectedMax.time()); + } + + { + QDateTimeEdit dte4(0); + dte4.setMinimumDate(minDate); + dte4.setMaximumDate(maxDate); + dte4.setMinimumTime(minTime); + dte4.setMaximumTime(maxTime); + + QCOMPARE(dte4.minimumDate(), expectedMin.date()); + QCOMPARE(dte4.maximumDate(), expectedMax.date()); + QCOMPARE(dte4.minimumTime(), expectedMin.time()); + QCOMPARE(dte4.maximumTime(), expectedMax.time()); + } +} + +void tst_QDateTimeEdit::wrappingTime_data() +{ + QTest::addColumn<bool>("startWithMin"); + QTest::addColumn<QTime>("minimumTime"); + QTest::addColumn<QTime>("maximumTime"); + QTest::addColumn<uint>("section"); + QTest::addColumn<QTime>("newTime"); + + QTest::newRow("data0") << false << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::HourSection + << QTime(0,2,2); + QTest::newRow("data1") << true << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::HourSection + << QTime(2,0,0); + QTest::newRow("data2") << false << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::MinuteSection + << QTime(2,0,2); + QTest::newRow("data3") << true << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::MinuteSection + << QTime(0,59,0); + QTest::newRow("data4") << false << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::SecondSection + << QTime(2,2,0); + QTest::newRow("data5") << true << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::SecondSection + << QTime(0,0,59); + QTest::newRow("data6") << false << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::HourSection + << QTime(1,22,22); + QTest::newRow("data7") << true << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::HourSection + << QTime(22,1,1); + QTest::newRow("data8") << false << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::MinuteSection + << QTime(22,0,22); + QTest::newRow("data9") << true << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::MinuteSection + << QTime(1,59,1); + QTest::newRow("data10") << false << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::SecondSection + << QTime(22,22,0); + QTest::newRow("data11") << true << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::SecondSection + << QTime(1,1,59); + QTest::newRow("data12") << false << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::HourSection + << QTime(1,2,1); + QTest::newRow("data13") << true << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::HourSection + << QTime(1,1,1); + QTest::newRow("data14") << false << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::MinuteSection + << QTime(1,1,1); + QTest::newRow("data15") << true << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::MinuteSection + << QTime(1,2,1); + QTest::newRow("data16") << false << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::SecondSection + << QTime(1,2,0); + QTest::newRow("data17") << true << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::SecondSection + << QTime(1,1,59); +} + + +void tst_QDateTimeEdit::wrappingTime() +{ + QFETCH(bool, startWithMin); + QFETCH(QTime, minimumTime); + QFETCH(QTime, maximumTime); + QFETCH(uint, section); + QFETCH(QTime, newTime); + + testWidget->setDisplayFormat("hh:mm:ss"); + testWidget->setMinimumTime(minimumTime); + testWidget->setMaximumTime(maximumTime); + testWidget->setWrapping(true); + testWidget->setCurrentSection((QDateTimeEdit::Section)section); + if (startWithMin) { + testWidget->setTime(minimumTime); + QTest::keyClick(testWidget, Qt::Key_Down); + } else { + testWidget->setTime(maximumTime); + QTest::keyClick(testWidget, Qt::Key_Up); + } + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(testWidget->time(), newTime); +} + +void tst_QDateTimeEdit::userKeyPress_Time_data() +{ + QTest::addColumn<bool>("ampm"); + QTest::addColumn<QTestEventList>("keys"); + QTest::addColumn<QTime>("expected_time"); + + // ***************** test the hours *************** + + // use up/down keys to change hour in 12 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 10, 0, 0 ); + QTest::newRow( "data0" ) << bool(true) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<5; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 6, 0, 0 ); + QTest::newRow( "data1" ) << bool(true) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<10; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 1, 0, 0 ); + QTest::newRow( "data2" ) << bool(true) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<12; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 23, 0, 0 ); + QTest::newRow( "data3" ) << bool(true) << keys << expected; + } + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 12, 0, 0 ); + QTest::newRow( "data4" ) << bool(true) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 13, 0, 0 ); + QTest::newRow( "data5" ) << bool(true) << keys << expected; + } + + // use up/down keys to change hour in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 10, 0, 0 ); + QTest::newRow( "data6" ) << bool(false) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<5; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 6, 0, 0 ); + QTest::newRow( "data7" ) << bool(false) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<10; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 1, 0, 0 ); + QTest::newRow( "data8" ) << bool(false) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<12; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 23, 0, 0 ); + QTest::newRow( "data9" ) << bool(false) << keys << expected; + } + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 12, 0, 0 ); + QTest::newRow( "data10" ) << bool(false) << keys << expected; + } + { + QTestEventList keys; + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 13, 0, 0 ); + QTest::newRow( "data11" ) << bool(false) << keys << expected; + } + + // enter a one digit valid hour + { + QTestEventList keys; + keys.addKeyClick( '5' ); + QTime expected( 5, 0, 0 ); + QTest::newRow( "data12" ) << bool(true) << keys << expected; + } + + // entering a two digit valid hour + { + QTestEventList keys; + keys.addKeyClick( '1' ); + keys.addKeyClick( '1' ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data13" ) << bool(true) << keys << expected; + } + + // entering an invalid hour + { + QTestEventList keys; + keys.addKeyClick( '2' ); + // the '5' creates an invalid hour (25) so it must be ignored + keys.addKeyClick( '5' ); + QTime expected( 2, 0, 0 ); + QTest::newRow( "data14" ) << bool(true) << keys << expected; + } + + // enter a value, in hour which causes a field change + { + QTestEventList keys; + keys.addKeyClick( '0' ); + keys.addKeyClick( '2' ); + keys.addKeyClick( '1' ); + QTime expected( 2, 1, 0 ); + QTest::newRow( "data15" ) << bool(true) << keys << expected; + } + + // enter a one digit valid hour in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( '5' ); + QTime expected( 5, 0, 0 ); + QTest::newRow( "data16" ) << bool(false) << keys << expected; + } + + // enter a two digit valid hour in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( '1' ); + keys.addKeyClick( '1' ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data17" ) << bool(false) << keys << expected; + } + + // enter a two digit valid hour (>12) in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( '1' ); + keys.addKeyClick( '5' ); + QTime expected( 15, 0, 0 ); + QTest::newRow( "data18" ) << bool(false) << keys << expected; + } + + // enter a two digit valid hour (>20) in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( '2' ); + keys.addKeyClick( '1' ); + QTime expected( 21, 0, 0 ); + QTest::newRow( "data19" ) << bool(false) << keys << expected; + } + + // enter a two digit invalid hour (>23) in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( '2' ); + keys.addKeyClick( '4' ); + QTime expected( 2, 0, 0 ); + QTest::newRow( "data20" ) << bool(false) << keys << expected; + } + + // ***************** test the minutes *************** + + // use up/down keys to change the minutes in 12 hour mode + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 2, 0 ); + QTest::newRow( "data21" ) << bool(true) << keys << expected; + } + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<16; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 16, 0 ); + QTest::newRow( "data22" ) << bool(true) << keys << expected; + } + { // test maximum value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<59; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 59, 0 ); + QTest::newRow( "data23" ) << bool(true) << keys << expected; + } + { // test 'overflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<60; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data24" ) << bool(true) << keys << expected; + } + { // test 'underflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 59, 0 ); + QTest::newRow( "data25" ) << bool(true) << keys << expected; + } + { // test valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 58, 0 ); + QTest::newRow( "data26" ) << bool(true) << keys << expected; + } + + // use up/down keys to change the minutes in 24 hour mode + + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 2, 0 ); + QTest::newRow( "data27" ) << bool(false) << keys << expected; + } + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<16; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 16, 0 ); + QTest::newRow( "data28" ) << bool(false) << keys << expected; + } + { // test maximum value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<59; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 59, 0 ); + QTest::newRow( "data29" ) << bool(false) << keys << expected; + } + { // test 'overflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<60; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data30" ) << bool(false) << keys << expected; + } + { // test 'underflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 59, 0 ); + QTest::newRow( "data31" ) << bool(false) << keys << expected; + } + { // test valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 58, 0 ); + QTest::newRow( "data32" ) << bool(false) << keys << expected; + } + + // enter a valid one digit minute in 12 h mode + { + QTestEventList keys; + keys.addKeyClick(Qt::Key_Tab); + keys.addKeyClick( '2' ); + QTime expected( 11, 2, 0 ); + QTest::newRow( "data33" ) << bool(true) << keys << expected; + } + + // enter a valid two digit minutes in 12 h mode + { + QTestEventList keys; + keys.addKeyClick(Qt::Key_Tab); + keys.addKeyClick( '2' ); + keys.addKeyClick( '4' ); + QTime expected( 11, 24, 0 ); + QTest::newRow( "data34" ) << bool(true) << keys << expected; + } + + // check the lower limit of the minutes in 12 h mode + { + QTestEventList keys; + keys.addKeyClick(Qt::Key_Tab); + keys.addKeyClick( '0' ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data35" ) << bool(true) << keys << expected; + } + + // check the upper limit of the minutes in 12 h mode + { + QTestEventList keys; + keys.addKeyClick(Qt::Key_Tab); + keys.addKeyClick( '5' ); + keys.addKeyClick( '9' ); + QTime expected( 11, 59, 0 ); + QTest::newRow( "data36" ) << bool(true) << keys << expected; + } + + // enter an invalid two digit minutes in 12 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '6' ); + keys.addKeyClick( '0' ); + QTime expected( 11, 6, 0 ); + QTest::newRow( "data37" ) << bool(true) << keys << expected; + } + + // test minutes in 24 hour motestWidget-> Behaviour should be exactly the same + + // enter a valid one digit minute in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '2' ); + QTime expected( 11, 2, 0 ); + QTest::newRow( "data38" ) << bool(false) << keys << expected; + } + + // enter a valid two digit minutes in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '2' ); + keys.addKeyClick( '4' ); + QTime expected( 11, 24, 0 ); + QTest::newRow( "data39" ) << bool(false) << keys << expected; + } + + // check the lower limit of the minutes in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '0' ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data40" ) << bool(false) << keys << expected; + } + + // check the upper limit of the minutes in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '5' ); + keys.addKeyClick( '9' ); + QTime expected( 11, 59, 0 ); + QTest::newRow( "data41" ) << bool(false) << keys << expected; + } + + // enter an invalid two digit minutes in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '6' ); + keys.addKeyClick( '0' ); + QTime expected( 11, 6, 0 ); + QTest::newRow( "data42" ) << bool(false) << keys << expected; + } + + // ***************** test the seconds *************** + + // use up/down to edit the seconds... + + // use up/down keys to change the seconds in 12 hour mode + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 2 ); + QTest::newRow( "data43" ) << bool(true) << keys << expected; + } + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<16; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 16 ); + QTest::newRow( "data44" ) << bool(true) << keys << expected; + } + { // test maximum value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<59; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 59 ); + QTest::newRow( "data45" ) << bool(true) << keys << expected; + } + { // test 'overflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<60; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data46" ) << bool(true) << keys << expected; + } + { // test 'underflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 0, 59 ); + QTest::newRow( "data47" ) << bool(true) << keys << expected; + } + { // test valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 0, 58 ); + QTest::newRow( "data48" ) << bool(true) << keys << expected; + } + + // use up/down keys to change the seconds in 24 hour mode + + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 2 ); + QTest::newRow( "data49" ) << bool(false) << keys << expected; + } + { // test a valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<16; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 16 ); + QTest::newRow( "data50" ) << bool(false) << keys << expected; + } + { // test maximum value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<59; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 59 ); + QTest::newRow( "data51" ) << bool(false) << keys << expected; + } + { // test 'overflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<60; i++) + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data52" ) << bool(false) << keys << expected; + } + { // test 'underflow' + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 0, 59 ); + QTest::newRow( "data53" ) << bool(false) << keys << expected; + } + { // test valid value + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + for (uint i=0; i<2; i++) + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 0, 58 ); + QTest::newRow( "data54" ) << bool(false) << keys << expected; + } + + // enter a valid one digit second in 12 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '2' ); + QTime expected( 11, 0, 2 ); + QTest::newRow( "data55" ) << bool(true) << keys << expected; + } + + // enter a valid two digit seconds in 12 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '2' ); + keys.addKeyClick( '4' ); + QTime expected( 11, 0, 24 ); + QTest::newRow( "data56" ) << bool(true) << keys << expected; + } + + // check the lower limit of the seconds in 12 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '0' ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data57" ) << bool(true) << keys << expected; + } + + // check the upper limit of the seconds in 12 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '5' ); + keys.addKeyClick( '9' ); + QTime expected( 11, 0, 59 ); + QTest::newRow( "data58" ) << bool(true) << keys << expected; + } + + // enter an invalid two digit seconds in 12 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '6' ); + keys.addKeyClick( '0' ); + QTime expected( 11, 0, 6 ); + QTest::newRow( "data59" ) << bool(true) << keys << expected; + } + + // test seconds in 24 hour mode. Behaviour should be exactly the same + + // enter a valid one digit minute in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '2' ); + QTime expected( 11, 0, 2 ); + QTest::newRow( "data60" ) << bool(false) << keys << expected; + } + + // enter a valid two digit seconds in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '2' ); + keys.addKeyClick( '4' ); + QTime expected( 11, 0, 24 ); + QTest::newRow( "data61" ) << bool(false) << keys << expected; + } + + // check the lower limit of the seconds in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '0' ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data62" ) << bool(false) << keys << expected; + } + + // check the upper limit of the seconds in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '5' ); + keys.addKeyClick( '9' ); + QTime expected( 11, 0, 59 ); + QTest::newRow( "data63" ) << bool(false) << keys << expected; + } + + // enter an invalid two digit seconds in 24 h mode + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( '6' ); + keys.addKeyClick( '0' ); + QTime expected( 11, 0, 6 ); + QTest::newRow( "data64" ) << bool(false) << keys << expected; + } + + // Test the AMPM indicator + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Up ); + QTime expected( 23, 0, 0 ); + QTest::newRow( "data65" ) << bool(true) << keys << expected; + } + // Test the AMPM indicator + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 23, 0, 0 ); + QTest::newRow( "data66" ) << bool(true) << keys << expected; + } + // Test the AMPM indicator + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Down ); + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data67" ) << bool(true) << keys << expected; + } + // Test the AMPM indicator + { + QTestEventList keys; + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Tab ); + keys.addKeyClick( Qt::Key_Up ); + keys.addKeyClick( Qt::Key_Down ); + QTime expected( 11, 0, 0 ); + QTest::newRow( "data68" ) << bool(true) << keys << expected; + } +} + +void tst_QDateTimeEdit::userKeyPress_Time() +{ + QFETCH(bool, ampm); + QFETCH(QTestEventList, keys); + QFETCH(QTime, expected_time); + + if (ampm) + testWidget->setDisplayFormat("hh:mm:ss ap"); + else + testWidget->setDisplayFormat("hh:mm:ss"); + + testWidget->setTime(QTime(11, 0, 0)); + testWidget->setFocus(); + + testWidget->setWrapping(true); + + QTest::keyClick(testWidget, Qt::Key_Enter); // Make sure the first section is now focused + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11")); + keys.simulate(testWidget); + QTest::keyClick(testWidget, Qt::Key_Enter); + + QCOMPARE(testWidget->time(), expected_time); +} + +void tst_QDateTimeEdit::wrappingDate_data() +{ + QTest::addColumn<bool>("startWithMin"); + QTest::addColumn<QDate>("minimumDate"); + QTest::addColumn<QDate>("maximumDate"); + QTest::addColumn<uint>("section"); + QTest::addColumn<QDate>("newDate"); + + QTest::newRow("data0") << false << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::DaySection + << QDate(1999, 1, 1); + QTest::newRow("data1") << true << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::DaySection + << QDate(1999, 1, 31); + QTest::newRow("data2") << false << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::MonthSection + << QDate(1999, 1, 31); + QTest::newRow("data3") << true << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::MonthSection + << QDate(1999, 1, 1); + QTest::newRow("data4") << false << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::YearSection + << QDate(1999, 1, 31); + QTest::newRow("data5") << true << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::YearSection + << QDate(1999, 1, 1); + QTest::newRow("data6") << false << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::DaySection + << QDate(2000, 1, 1); + QTest::newRow("data7") << true << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::DaySection + << QDate(1999, 1, 31); + QTest::newRow("data8") << false << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::MonthSection + << QDate(2000, 1, 31); + QTest::newRow("data9") << true << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::MonthSection + << QDate(1999, 12, 1); + QTest::newRow("data10") << false << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::YearSection + << QDate(1999, 1, 31); + QTest::newRow("data11") << true << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::YearSection + << QDate(2000, 1, 1); +} + + +void tst_QDateTimeEdit::wrappingDate() +{ + QFETCH(bool, startWithMin); + QFETCH(QDate, minimumDate); + QFETCH(QDate, maximumDate); + QFETCH(uint, section); + QFETCH(QDate, newDate); + + testWidget->setDisplayFormat("dd/MM/yyyy"); + testWidget->setMinimumDate(minimumDate); + testWidget->setMaximumDate(maximumDate); + testWidget->setWrapping(true); + testWidget->setCurrentSection((QDateTimeEdit::Section)section); + + if (startWithMin) { + testWidget->setDate(minimumDate); + QTest::keyClick(testWidget, Qt::Key_Down); + } else { + testWidget->setDate(maximumDate); + QTest::keyClick(testWidget, Qt::Key_Up); + } + if (testWidget->currentSection() == QDateTimeEdit::MonthSection) + QCOMPARE(testWidget->date(), newDate); +} + +void tst_QDateTimeEdit::dateSignalChecking_data() +{ + QTest::addColumn<QDate>("originalDate"); + QTest::addColumn<QDate>("newDate"); + QTest::addColumn<int>("timesEmitted"); + + QTest::newRow("data0") << QDate(2004, 06, 22) << QDate(2004, 07, 23) << 1; + QTest::newRow("data1") << QDate(2004, 06, 22) << QDate(2004, 06, 22) << 0; +} + +void tst_QDateTimeEdit::dateSignalChecking() +{ + QFETCH(QDate, originalDate); + QFETCH(QDate, newDate); + QFETCH(int, timesEmitted); + + testWidget->setDate(originalDate); + + QSignalSpy dateSpy(testWidget, SIGNAL(dateChanged(const QDate &))); + QSignalSpy dateTimeSpy(testWidget, SIGNAL(dateTimeChanged(const QDateTime &))); + QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(const QTime &))); + + testWidget->setDate(newDate); + QCOMPARE(dateSpy.count(), timesEmitted); + + if (timesEmitted > 0) { + QList<QVariant> list = dateSpy.takeFirst(); + QDate d; + d = qVariantValue<QDate>(list.at(0)); + QCOMPARE(d, newDate); + } + QCOMPARE(dateTimeSpy.count(), timesEmitted); + QCOMPARE(timeSpy.count(), 0); +} + +void tst_QDateTimeEdit::timeSignalChecking_data() +{ + QTest::addColumn<QTime>("originalTime"); + QTest::addColumn<QTime>("newTime"); + QTest::addColumn<int>("timesEmitted"); + + QTest::newRow("data0") << QTime(15, 55, 00) << QTime(15, 17, 12) << 1; + QTest::newRow("data1") << QTime(15, 55, 00) << QTime(15, 55, 00) << 0; +} + +void tst_QDateTimeEdit::timeSignalChecking() +{ + QFETCH(QTime, originalTime); + QFETCH(QTime, newTime); + QFETCH(int, timesEmitted); + + testWidget->setTime(originalTime); + + testWidget->setDisplayFormat("hh:mm:ss"); + QSignalSpy dateSpy(testWidget, SIGNAL(dateChanged(const QDate &))); + QSignalSpy dateTimeSpy(testWidget, SIGNAL(dateTimeChanged(const QDateTime &))); + QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(const QTime &))); + + testWidget->setTime(newTime); + QCOMPARE(timeSpy.count(), timesEmitted); + + if (timesEmitted > 0) { + QList<QVariant> list = timeSpy.takeFirst(); + QTime t; + t = qVariantValue<QTime>(list.at(0)); + QCOMPARE(t, newTime); + } + QCOMPARE(dateTimeSpy.count(), timesEmitted); + QCOMPARE(dateSpy.count(), 0); +} + +void tst_QDateTimeEdit::dateTimeSignalChecking_data() +{ + QTest::addColumn<QDateTime>("originalDateTime"); + QTest::addColumn<QDateTime>("newDateTime"); + QTest::addColumn<int>("timesDateEmitted"); + QTest::addColumn<int>("timesTimeEmitted"); + QTest::addColumn<int>("timesDateTimeEmitted"); + + QTest::newRow("data0") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0)) + << QDateTime(QDate(2004, 7, 23), QTime(15, 17, 12)) + << 1 << 1 << 1; + QTest::newRow("data1") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0)) + << QDateTime(QDate(2004, 6, 22), QTime(15, 17, 12)) + << 0 << 1 << 1; + QTest::newRow("data2") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0)) + << QDateTime(QDate(2004, 7, 23), QTime(15, 55, 0)) + << 1 << 0 << 1; + QTest::newRow("data3") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0)) + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0)) + << 0 << 0 << 0; +} + +void tst_QDateTimeEdit::dateTimeSignalChecking() +{ + QFETCH(QDateTime, originalDateTime); + QFETCH(QDateTime, newDateTime); + QFETCH(int, timesDateEmitted); + QFETCH(int, timesTimeEmitted); + QFETCH(int, timesDateTimeEmitted); + + testWidget->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); + testWidget->setDateTime(originalDateTime); + + QSignalSpy dateSpy(testWidget, SIGNAL(dateChanged(const QDate &))); + QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(const QTime &))); + QSignalSpy dateTimeSpy(testWidget, SIGNAL(dateTimeChanged(const QDateTime &))); + + testWidget->setDateTime(newDateTime); + QCOMPARE(dateSpy.count(), timesDateEmitted); + if (timesDateEmitted > 0) { + QCOMPARE(timesDateEmitted, 1); + QList<QVariant> list = dateSpy.takeFirst(); + QDate d; + d = qVariantValue<QDate>(list.at(0)); + QCOMPARE(d, newDateTime.date()); + } + QCOMPARE(timeSpy.count(), timesTimeEmitted); + if (timesTimeEmitted > 0) { + QList<QVariant> list = timeSpy.takeFirst(); + QTime t; + t = qVariantValue<QTime>(list.at(0)); + QCOMPARE(t, newDateTime.time()); + } + QCOMPARE(dateTimeSpy.count(), timesDateTimeEmitted); + if (timesDateTimeEmitted > 0) { + QList<QVariant> list = dateTimeSpy.takeFirst(); + QDateTime dt; + dt = qVariantValue<QDateTime>(list.at(0)); + QCOMPARE(dt, newDateTime); + } +} + + +void tst_QDateTimeEdit::sectionText_data() +{ + QTest::addColumn<QString>("format"); + QTest::addColumn<QDateTime>("dateTime"); + QTest::addColumn<uint>("section"); + QTest::addColumn<QString>("sectionText"); + + QTest::newRow("data0") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::NoSection << QString(); + QTest::newRow("data1") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::AmPmSection << QString("pm"); + QTest::newRow("data2") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::MSecSection << QString("789"); + QTest::newRow("data3") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::SecondSection << QString("03"); + QTest::newRow("data4") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::MinuteSection << QString("55"); + QTest::newRow("data5") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::HourSection << QString("03"); + QTest::newRow("data6") << QString("dd/MM/yyyy hh:mm:ss zzz") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::HourSection << QString("15"); + QTest::newRow("data7") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::DaySection << QString("22"); + QTest::newRow("data8") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::MonthSection << QString("06"); + QTest::newRow("data9") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::YearSection << QString("2004"); + QTest::newRow("data10") << QString("dd/MM/yyyy hh:mm:ss zzz AP") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::AmPmSection << QString("PM"); + QTest::newRow("data11") << QString("dd/MM/yyyy hh:mm:ss ap") + << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789)) + << (uint)QDateTimeEdit::MSecSection << QString(); +} + +void tst_QDateTimeEdit::sectionText() +{ + QFETCH(QString, format); + QFETCH(QDateTime, dateTime); + QFETCH(uint, section); + QFETCH(QString, sectionText); + + testWidget->setDisplayFormat(format); + testWidget->setDateTime(dateTime); + QCOMPARE(testWidget->sectionText((QDateTimeEdit::Section)section), sectionText); +// QApplication::setLayoutDirection(Qt::RightToLeft); +// testWidget->setDisplayFormat(format); +// QCOMPARE(format, testWidget->displayFormat()); +// testWidget->setDateTime(dateTime); +// QCOMPARE(testWidget->sectionText((QDateTimeEdit::Section)section), sectionText); +// QApplication::setLayoutDirection(Qt::LeftToRight); +} + +void tst_QDateTimeEdit::mousePress() +{ + testWidget->setDate(QDate(2004, 6, 23)); + testWidget->setCurrentSection(QDateTimeEdit::YearSection); + QCOMPARE(testWidget->currentSection(), QDateTimeEdit::YearSection); + + // Ask the SC_SpinBoxUp button location from style + QStyleOptionSpinBox so; + so.rect = testWidget->rect(); + QRect rectUp = testWidget->style()->subControlRect(QStyle::CC_SpinBox, &so, QStyle::SC_SpinBoxUp, testWidget); + + // Send mouseClick to center of SC_SpinBoxUp + QTest::mouseClick(testWidget, Qt::LeftButton, 0, rectUp.center()); + QCOMPARE(testWidget->date().year(), 2005); + +} + +void tst_QDateTimeEdit::stepHourAMPM_data() +{ + QTest::addColumn<QString>("format"); + QTest::addColumn<KeyList>("keys"); + QTest::addColumn<TimeList>("expected"); + QTest::addColumn<QTime>("start"); + QTest::addColumn<QTime>("min"); + QTest::addColumn<QTime>("max"); + + { + KeyList keys; + TimeList expected; + keys << Qt::Key_Up; + expected << QTime(1, 0, 0); + keys << Qt::Key_Up; + expected << QTime(2, 0, 0); + keys << Qt::Key_Up; + expected << QTime(3, 0, 0); + keys << Qt::Key_Up; + expected << QTime(4, 0, 0); + keys << Qt::Key_Up; + expected << QTime(5, 0, 0); + keys << Qt::Key_Up; + expected << QTime(6, 0, 0); + keys << Qt::Key_Up; + expected << QTime(7, 0, 0); + keys << Qt::Key_Up; + expected << QTime(8, 0, 0); + keys << Qt::Key_Up; + expected << QTime(9, 0, 0); + keys << Qt::Key_Up; + expected << QTime(10, 0, 0); + keys << Qt::Key_Up; + expected << QTime(11, 0, 0); + keys << Qt::Key_Up; + expected << QTime(12, 0, 0); + keys << Qt::Key_Up; + expected << QTime(13, 0, 0); + keys << Qt::Key_Up; + expected << QTime(14, 0, 0); + keys << Qt::Key_Up; + expected << QTime(15, 0, 0); + keys << Qt::Key_Up; + expected << QTime(16, 0, 0); + keys << Qt::Key_Up; + expected << QTime(17, 0, 0); + keys << Qt::Key_Up; + expected << QTime(18, 0, 0); + keys << Qt::Key_Up; + expected << QTime(19, 0, 0); + keys << Qt::Key_Up; + expected << QTime(20, 0, 0); + keys << Qt::Key_Up; + expected << QTime(21, 0, 0); + keys << Qt::Key_Up; + expected << QTime(22, 0, 0); + keys << Qt::Key_Up; + expected << QTime(23, 0, 0); + keys << Qt::Key_Down; + expected << QTime(22, 0, 0); + keys << Qt::Key_Down; + expected << QTime(21, 0, 0); + keys << Qt::Key_Down; + expected << QTime(20, 0, 0); + keys << Qt::Key_Down; + expected << QTime(19, 0, 0); + keys << Qt::Key_Down; + expected << QTime(18, 0, 0); + keys << Qt::Key_Down; + expected << QTime(17, 0, 0); + keys << Qt::Key_Down; + expected << QTime(16, 0, 0); + keys << Qt::Key_Down; + expected << QTime(15, 0, 0); + keys << Qt::Key_Down; + expected << QTime(14, 0, 0); + keys << Qt::Key_Down; + expected << QTime(13, 0, 0); + keys << Qt::Key_Down; + expected << QTime(12, 0, 0); + keys << Qt::Key_Down; + expected << QTime(11, 0, 0); + keys << Qt::Key_Down; + expected << QTime(10, 0, 0); + keys << Qt::Key_Down; + expected << QTime(9, 0, 0); + keys << Qt::Key_Down; + expected << QTime(8, 0, 0); + keys << Qt::Key_Down; + expected << QTime(7, 0, 0); + keys << Qt::Key_Down; + expected << QTime(6, 0, 0); + keys << Qt::Key_Down; + expected << QTime(5, 0, 0); + keys << Qt::Key_Down; + expected << QTime(4, 0, 0); + keys << Qt::Key_Down; + expected << QTime(3, 0, 0); + keys << Qt::Key_Down; + expected << QTime(2, 0, 0); + keys << Qt::Key_Down; + expected << QTime(1, 0, 0); + keys << Qt::Key_Down; + expected << QTime(0, 0, 0); + + QTest::newRow("hh 1") << QString("hh") << keys << expected << QTime(0, 0) + << QTime(0, 0) << QTime(23, 59, 59); + QTest::newRow("hh:ap 1") << QString("hh:ap") << keys << expected + << QTime(0, 0) << QTime(0, 0) + << QTime(23, 59, 59); + + QTest::newRow("HH:ap 2") << QString("HH:ap") << keys << expected + << QTime(0, 0) << QTime(0, 0) + << QTime(23, 59, 59); + + } + { + KeyList keys; + TimeList expected; + keys << Qt::Key_Down; + expected << QTime(2, 0, 0); + QTest::newRow("hh 2") << QString("hh") << keys << expected << QTime(0, 0) << QTime(2, 0, 0) << QTime(23, 59, 59); + QTest::newRow("hh:ap 2") << QString("hh:ap") << keys << expected << QTime(0, 0) << QTime(2, 0, 0) << QTime(23, 59, 59); + } + { + KeyList keys; + TimeList expected; + keys << Qt::Key_Up; + expected << QTime(23, 0, 0); + keys << Qt::Key_Up; + expected << QTime(23, 0, 0); + QTest::newRow("hh 3") << QString("hh") << keys << expected << QTime(0, 0) << QTime(22, 0, 0) + << QTime(23, 59, 59); + QTest::newRow("hh:ap 3") << QString("hh:ap") << keys << expected << QTime(0, 0) + << QTime(22, 0, 0) << QTime(23, 59, 59); + } + { + KeyList keys; + TimeList expected; + keys << Qt::Key_Up; + expected << QTime(15, 31, 0); + QTest::newRow("hh:mm:ap 3") << QString("hh:mm:ap") << keys << expected << QTime(15, 31, 0) + << QTime(9, 0, 0) << QTime(16, 0, 0); + QTest::newRow("hh:mm 3") << QString("hh:mm") << keys << expected << QTime(15, 31, 0) + << QTime(9, 0, 0) << QTime(16, 0, 0); + } +} + +void tst_QDateTimeEdit::stepHourAMPM() +{ + QFETCH(QString, format); + QFETCH(KeyList, keys); + QFETCH(TimeList, expected); + QFETCH(QTime, start); + QFETCH(QTime, min); + QFETCH(QTime, max); + + + testWidget->setDisplayFormat(format); + testWidget->setTime(start); + testWidget->setMinimumTime(min); + testWidget->setMaximumTime(max); + if (keys.size() != expected.size()) { + qWarning("%s:%d Test broken", __FILE__, __LINE__); + QCOMPARE(keys.size(), expected.size()); + } + + for (int i=0; i<keys.size(); ++i) { + QTest::keyClick(testWidget, keys.at(i)); + QCOMPARE(testWidget->time(), expected.at(i)); + } +} + + +void tst_QDateTimeEdit::displayedSections_data() +{ + QTest::addColumn<QString>("format"); + QTest::addColumn<uint>("section"); + + QTest::newRow("data0") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::MonthSection + | QDateTimeEdit::YearSection | QDateTimeEdit::HourSection + | QDateTimeEdit::MinuteSection | QDateTimeEdit::SecondSection + | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection); + QTest::newRow("data1") << QString("dd/yyyy hh:mm:ss zzz ap") + << (uint)(QDateTimeEdit::DaySection + | QDateTimeEdit::YearSection | QDateTimeEdit::HourSection + | QDateTimeEdit::MinuteSection | QDateTimeEdit::SecondSection + | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection); + QTest::newRow("data2") << QString("dd/MM/yyyy mm zzz ap") + << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::MonthSection + | QDateTimeEdit::YearSection + | QDateTimeEdit::MinuteSection + | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection); + QTest::newRow("data3") << QString("dd/MM/yyyy") + << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::MonthSection + | QDateTimeEdit::YearSection); + QTest::newRow("data4") << QString("hh:mm:ss zzz ap") + << (uint)(QDateTimeEdit::HourSection + | QDateTimeEdit::MinuteSection | QDateTimeEdit::SecondSection + | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection); + QTest::newRow("data5") << QString("dd ap") + << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::AmPmSection); + QTest::newRow("data6") << QString("zzz") + << (uint)QDateTimeEdit::MSecSection; +} + +void tst_QDateTimeEdit::displayedSections() +{ + QFETCH(QString, format); + QFETCH(uint, section); + + testWidget->setDisplayFormat(format); + QVERIFY((QDateTimeEdit::Section)section == testWidget->displayedSections()); +} + +void tst_QDateTimeEdit::currentSection_data() +{ + QTest::addColumn<QString>("format"); + QTest::addColumn<uint>("section"); + QTest::addColumn<uint>("currentSection"); + + // First is deliberate, this way we can make sure that it is not reset by specifying no section. + QTest::newRow("data0") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::NoSection << (uint)QDateTimeEdit::YearSection; + QTest::newRow("data1") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::AmPmSection << (uint)QDateTimeEdit::AmPmSection; + QTest::newRow("data2") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::MSecSection << (uint)QDateTimeEdit::MSecSection; + QTest::newRow("data3") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::SecondSection << (uint)QDateTimeEdit::SecondSection; + QTest::newRow("data4") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::MinuteSection << (uint)QDateTimeEdit::MinuteSection; + QTest::newRow("data5") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::HourSection << (uint)QDateTimeEdit::HourSection; + QTest::newRow("data6") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::DaySection << (uint)QDateTimeEdit::DaySection; + QTest::newRow("data7") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::MonthSection << (uint)QDateTimeEdit::MonthSection; + QTest::newRow("data8") << QString("dd/MM/yyyy hh:mm:ss zzz ap") + << (uint)QDateTimeEdit::YearSection << (uint)QDateTimeEdit::YearSection; + QTest::newRow("data9") << QString("dd/MM/yyyy hh:mm:ss zzz AP") + << (uint)QDateTimeEdit::AmPmSection << (uint)QDateTimeEdit::AmPmSection; + QTest::newRow("data10") << QString("dd/MM/yyyy hh:mm:ss ap") + << (uint)QDateTimeEdit::MSecSection << (uint)QDateTimeEdit::DaySection; +} + +void tst_QDateTimeEdit::currentSection() +{ + QFETCH(QString, format); + QFETCH(uint, section); + QFETCH(uint, currentSection); + + testWidget->setDisplayFormat(format); + if ((QDateTimeEdit::Section)section == QDateTimeEdit::NoSection) + testWidget->setCurrentSection(QDateTimeEdit::YearSection); // Ensure it's not reset (see above) + testWidget->setCurrentSection((QDateTimeEdit::Section)section); + QVERIFY((QDateTimeEdit::Section)currentSection == testWidget->currentSection()); +} + +void tst_QDateTimeEdit::readOnly() +{ + testWidget->hide(); + QDateTimeEdit dt(QDate(2000, 2, 1)); + dt.setDisplayFormat("yyyy.MM.dd"); + dt.show(); + dt.setCurrentSection(QDateTimeEdit::DaySection); + QTest::keyClick(&dt, Qt::Key_Up); + QCOMPARE(dt.date(), QDate(2000, 2, 2)); + dt.setReadOnly(true); + QTest::keyClick(&dt, Qt::Key_Up); + QCOMPARE(dt.date(), QDate(2000, 2, 2)); + dt.stepBy(1); // stepBy should still work + QCOMPARE(dt.date(), QDate(2000, 2, 3)); + dt.setReadOnly(false); + QTest::keyClick(&dt, Qt::Key_Up); + QCOMPARE(dt.date(), QDate(2000, 2, 4)); +} + +void tst_QDateTimeEdit::weirdCase() +{ + testWidget->lineEdit()->setCursorPosition(0); + testWidget->setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31)); + testWidget->setDisplayFormat("dd//MM//yyyy"); + testWidget->setDate(testWidget->minimumDate()); + QTest::keyClick(testWidget, Qt::Key_Left); + QVERIFY(!testWidget->lineEdit()->hasSelectedText()); + QCOMPARE(testWidget->lineEdit()->cursorPosition(), 0); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QVERIFY(!testWidget->lineEdit()->hasSelectedText()); + QCOMPARE(testWidget->lineEdit()->cursorPosition(), 8); + + QTest::keyClick(testWidget, Qt::Key_Delete); + QCOMPARE(testWidget->text(), QString("01//01//005")); + QTest::keyClick(testWidget, Qt::Key_4); + QCOMPARE(testWidget->text(), QString("01//01//005")); +} + +void tst_QDateTimeEdit::newCase() +{ + if (QDate::shortMonthName(6) != "Jun" || QDate::shortMonthName(7) != "Jul" || + QDate::longMonthName(6) != "June" || QDate::longMonthName(7) != "July") + QSKIP("This test only works in English", SkipAll); + + testWidget->setDisplayFormat("MMMM'a'MbMMMcMM"); + testWidget->setDate(QDate(2005, 6, 1)); + QCOMPARE(testWidget->text(), QString("Junea6bJunc06")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->text(), QString("Julya7bJulc07")); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("July")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QCOMPARE(testWidget->lineEdit()->selectedText(), QString()); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Right); + QTest::keyClick(testWidget, Qt::Key_Delete); + QTest::keyClick(testWidget, Qt::Key_Left); + + + QCOMPARE(testWidget->text(), QString("Jula7bJulc07")); + QTest::keyClick(testWidget, Qt::Key_Delete); + QCOMPARE(testWidget->text(), QString("Jua7bJulc07")); + QTest::keyClick(testWidget, Qt::Key_N); + QCOMPARE(testWidget->text(), QString("Juna7bJulc07")); + QTest::keyClick(testWidget, Qt::Key_E); + QCOMPARE(testWidget->text(), QString("Junea6bJunc06")); +} + +void tst_QDateTimeEdit::newCase2() +{ + testWidget->setDisplayFormat("MMMM yyyy-MM-dd MMMM"); + testWidget->setDate(QDate(2005, 8, 8)); + QTest::keyClick(testWidget, Qt::Key_Return); + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->text(), QString(" 2005-08-08 ") + QDate::longMonthName(8)); +} + +void tst_QDateTimeEdit::newCase3() +{ + if (!QDate::longMonthName(1).startsWith("Januar")) + QSKIP("This test does not work in this locale", SkipAll); + + testWidget->setDisplayFormat("dd MMMM yyyy"); + testWidget->setDate(QDate(2000, 1, 1)); + testWidget->setGeometry(QRect(QPoint(0, 0), testWidget->sizeHint())); + testWidget->setCurrentSection(QDateTimeEdit::MonthSection); + QTest::keyClick(testWidget, Qt::Key_Return); + QTest::keyClick(testWidget, Qt::Key_J); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("01 J 2000")); + QCOMPARE(testWidget->lineEdit()->cursorPosition(), 4); + QTest::keyClick(testWidget, Qt::Key_A); + QTest::keyClick(testWidget, Qt::Key_N); + QTest::keyClick(testWidget, Qt::Key_U); + QTest::keyClick(testWidget, Qt::Key_A); + QTest::keyClick(testWidget, Qt::Key_R); +} + + +void tst_QDateTimeEdit::cursorPos() +{ + if (QDate::longMonthName(1) != "January") + QSKIP("This test only works in English", SkipAll); + + testWidget->setDisplayFormat("dd MMMM yyyy"); + //testWidget->setGeometry(0, 0, 200, 200); + testWidget->setCurrentSection(QDateTimeEdit::MonthSection); + QTest::keyClick(testWidget, Qt::Key_Return); + QCOMPARE(testWidget->lineEdit()->cursorPosition(), 10); + QTest::keyClick(testWidget, Qt::Key_J); + QTest::keyClick(testWidget, Qt::Key_A); + QTest::keyClick(testWidget, Qt::Key_N); + QTest::keyClick(testWidget, Qt::Key_U); + QTest::keyClick(testWidget, Qt::Key_A); + QTest::keyClick(testWidget, Qt::Key_R); + //QCursor::setPos(20, 20); + //QEventLoop l; + //l.exec(); + QTest::keyClick(testWidget, Qt::Key_Y); + QCOMPARE(testWidget->lineEdit()->cursorPosition(), 11); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QTest::keyClick(testWidget, Qt::Key_Return); + QTest::keyClick(testWidget, Qt::Key_3); + QTest::keyClick(testWidget, Qt::Key_1); + QCOMPARE(testWidget->lineEdit()->cursorPosition(), 3); +} + +void tst_QDateTimeEdit::newCase4() +{ + testWidget->setDisplayFormat("hh:mm"); + testWidget->setMinimumTime(QTime(3, 3, 0)); + QTest::keyClick(testWidget, Qt::Key_Return); + QTest::keyClick(testWidget, Qt::Key_0); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("0:03")); + QTest::keyClick(testWidget, Qt::Key_2); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("0:03")); + QTest::keyClick(testWidget, Qt::Key_4); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("04:03")); +} + +void tst_QDateTimeEdit::newCase5() +{ + testWidget->setDisplayFormat("yyyy-MM-dd hh:mm:ss zzz 'ms'"); + testWidget->setDateTime(QDateTime(QDate(2005, 10, 7), QTime(17, 44, 13, 100))); + testWidget->show(); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("2005-10-07 17:44:13 100 ms")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QTest::keyClick(testWidget, Qt::Key_Backtab, Qt::ShiftModifier); + + QTest::keyClick(testWidget, Qt::Key_Return); + QTest::keyClick(testWidget, Qt::Key_1); + QTest::keyClick(testWidget, Qt::Key_2); + QTest::keyClick(testWidget, Qt::Key_4); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("2005-10-07 17:44:13 124 ms")); + + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("2005-10-07 17:44:13 12 ms")); +} + +void tst_QDateTimeEdit::newCase6() +{ + testWidget->setDisplayFormat("d-yyyy-MM-dd"); + testWidget->setDate(QDate(2005, 10, 7)); + testWidget->show(); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("7-2005-10-07")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QTest::keyClick(testWidget, Qt::Key_Return); + QTest::keyClick(testWidget, Qt::Key_1); + QTest::keyClick(testWidget, Qt::Key_2); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("12-2005-10-12")); +} + + +void tst_QDateTimeEdit::task98554() +{ + testWidget->setDisplayFormat("mm.ss.zzz(ms)"); + testWidget->setTime(QTime(0, 0, 9)); + testWidget->setCurrentSection(QDateTimeEdit::SecondSection); + testWidget->show(); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("00.09.000(09)")); + QCOMPARE(testWidget->time(), QTime(0, 0, 9, 0)); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("00.10.000(010)")); + QCOMPARE(testWidget->time(), QTime(0, 0, 10, 0)); +} + +static QList<int> makeList(int val1, int val2, int val3) +{ + QList<int> ret; + ret << val1 << val2 << val3; + return ret; +} + + +void tst_QDateTimeEdit::setCurrentSection_data() +{ + QTest::addColumn<QString>("format"); + QTest::addColumn<QDateTime>("dateTime"); + QTest::addColumn<QList<int> >("setCurrentSections"); + QTest::addColumn<QList<int> >("expectedCursorPositions"); + + QTest::newRow("Day") << QString("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z") << QDateTime(QDate(2001, 1, 1), QTime(1, 2, 3, 4)) + << makeList(QDateTimeEdit::DaySection, QDateTimeEdit::DaySection, QDateTimeEdit::DaySection) + << makeList(24, 0, 24); + QTest::newRow("Month") << QString("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z") << QDateTime(QDate(2001, 1, 1), QTime(1, 2, 3, 4)) + << makeList(QDateTimeEdit::MonthSection, QDateTimeEdit::MonthSection, QDateTimeEdit::MonthSection) + << makeList(3, 26, 3); + QTest::newRow("Year") << QString("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z") << QDateTime(QDate(2001, 1, 1), QTime(1, 2, 3, 4)) + << makeList(QDateTimeEdit::YearSection, QDateTimeEdit::YearSection, QDateTimeEdit::YearSection) + << makeList(6, 28, 6); + QTest::newRow("Hour") << QString("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z") << QDateTime(QDate(2001, 1, 1), QTime(1, 2, 3, 4)) + << makeList(QDateTimeEdit::HourSection, QDateTimeEdit::HourSection, QDateTimeEdit::HourSection) + << makeList(11, 31, 11); + QTest::newRow("Minute") << QString("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z") << QDateTime(QDate(2001, 1, 1), QTime(1, 2, 3, 4)) + << makeList(QDateTimeEdit::MinuteSection, QDateTimeEdit::MinuteSection, QDateTimeEdit::MinuteSection) + << makeList(14, 33, 14); + QTest::newRow("Second") << QString("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z") << QDateTime(QDate(2001, 1, 1), QTime(1, 2, 3, 4)) + << makeList(QDateTimeEdit::SecondSection, QDateTimeEdit::SecondSection, QDateTimeEdit::SecondSection) + << makeList(17, 35, 17); + QTest::newRow("MSec") << QString("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z") << QDateTime(QDate(2001, 1, 1), QTime(1, 2, 3, 4)) + << makeList(QDateTimeEdit::MSecSection, QDateTimeEdit::MSecSection, QDateTimeEdit::MSecSection) + << makeList(20, 37, 20); +} + +void tst_QDateTimeEdit::setCurrentSection() +{ + QFETCH(QString, format); + QFETCH(QDateTime, dateTime); + QFETCH(QList<int>, setCurrentSections); + QFETCH(QList<int>, expectedCursorPositions); + + QCOMPARE(setCurrentSections.size(), expectedCursorPositions.size()); + testWidget->setDisplayFormat(format); + testWidget->setDateTime(dateTime); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + + testWidget->resize(400, 100); + for (int i=0; i<setCurrentSections.size(); ++i) { + testWidget->setCurrentSection((QDateTimeEdit::Section)setCurrentSections.at(i)); + QCOMPARE(testWidget->currentSection(), (QDateTimeEdit::Section)setCurrentSections.at(i)); + QCOMPARE(testWidget->lineEdit()->cursorPosition(), expectedCursorPositions.at(i)); + } +} + + +void tst_QDateTimeEdit::setSelectedSection() +{ + testWidget->setDisplayFormat("mm.ss.zzz('ms') m"); + testWidget->setTime(QTime(0, 0, 9)); + testWidget->show(); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_Home); +#endif + QVERIFY(!testWidget->lineEdit()->hasSelectedText()); + testWidget->setSelectedSection(QDateTimeEdit::MinuteSection); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("00")); + testWidget->setCurrentSection(QDateTimeEdit::MinuteSection); + testWidget->setSelectedSection(QDateTimeEdit::MinuteSection); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("0")); + testWidget->setSelectedSection(QDateTimeEdit::SecondSection); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("09")); + testWidget->setSelectedSection(QDateTimeEdit::NoSection); + QVERIFY(!testWidget->lineEdit()->hasSelectedText()); +} + +void tst_QDateTimeEdit::calendarPopup() +{ + { + QDateEdit edit; + QVERIFY(!edit.calendarWidget()); + edit.setCalendarPopup(true); + QVERIFY(edit.calendarWidget()); + } + + { + QTimeEdit edit; + QVERIFY(!edit.calendarWidget()); + edit.setCalendarPopup(true); + QVERIFY(!edit.calendarWidget()); + } + + { + QDateEdit edit; + QVERIFY(!edit.calendarWidget()); + QCalendarWidget *cw = new QCalendarWidget; + edit.setCalendarWidget(cw); + QVERIFY(!edit.calendarWidget()); + edit.setCalendarPopup(true); + edit.setCalendarWidget(cw); + QCOMPARE(edit.calendarWidget(), cw); + edit.setDateRange(QDate(1980, 1, 5), QDate(1980, 2, 11)); + QCOMPARE(cw->minimumDate(), edit.minimumDate()); + QCOMPARE(cw->maximumDate(), edit.maximumDate()); + edit.setDate(QDate(1980, 1, 31)); + QCOMPARE(edit.date(), cw->selectedDate()); + cw->setSelectedDate(QDate(1980, 1, 30)); + QCOMPARE(edit.date(), cw->selectedDate()); + } + + testWidget->setDisplayFormat("dd/MM/yyyy"); + testWidget->setDateTime(QDateTime(QDate(2000, 1, 1), QTime(0, 0))); + testWidget->show(); + testWidget->setCalendarPopup(true); + QCOMPARE(testWidget->calendarPopup(), true); + QStyle *style = testWidget->style(); + QStyleOptionComboBox opt; + opt.initFrom(testWidget); + opt.editable = true; + opt.subControls = QStyle::SC_ComboBoxArrow; + QRect rect = style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, testWidget); + QTest::mouseClick(testWidget, Qt::LeftButton, 0, QPoint(rect.left()+rect.width()/2, rect.top()+rect.height()/2)); + QWidget *wid = qFindChild<QWidget *>(testWidget, "qt_datetimedit_calendar"); + QVERIFY(wid != 0); + testWidget->hide(); + + QTimeEdit timeEdit; + timeEdit.setCalendarPopup(true); + timeEdit.show(); + + opt.initFrom(&timeEdit); + opt.subControls = QStyle::SC_ComboBoxArrow; + rect = style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, &timeEdit); + QTest::mouseClick(&timeEdit, Qt::LeftButton, 0, QPoint(rect.left()+rect.width()/2, rect.top()+rect.height()/2)); + QWidget *wid2 = qFindChild<QWidget *>(&timeEdit, "qt_datetimedit_calendar"); + QVERIFY(wid2 == 0); + timeEdit.hide(); + + + QDateEdit dateEdit; + dateEdit.setCalendarPopup(true); + dateEdit.setReadOnly(true); + dateEdit.show(); + + opt.initFrom(&dateEdit); + opt.subControls = QStyle::SC_ComboBoxArrow; + rect = style->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, &dateEdit); + QTest::mouseClick(&dateEdit, Qt::LeftButton, 0, QPoint(rect.left()+rect.width()/2, rect.top()+rect.height()/2)); + QWidget *wid3 = qFindChild<QWidget *>(&dateEdit, "qt_datetimedit_calendar"); + QVERIFY(wid3 == 0); + dateEdit.hide(); + +} + +class RestoreLayoutDirectioner +{ +public: + RestoreLayoutDirectioner(Qt::LayoutDirection was) + : old(was) + {} + + ~RestoreLayoutDirectioner() + { + QApplication::setLayoutDirection(old); + } +private: + const Qt::LayoutDirection old; +}; + +void tst_QDateTimeEdit::reverseTest() +{ + const RestoreLayoutDirectioner restorer(QApplication::layoutDirection()); + QApplication::setLayoutDirection(Qt::RightToLeft); + testWidget->setDisplayFormat("dd/MM/yyyy"); + testWidget->setDate(QDate(2001, 3, 30)); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("2001/03/30")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QCOMPARE(testWidget->currentSection(), QDateTimeEdit::DaySection); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2001, 3, 31)); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("2001/03/31")); +} + + +void tst_QDateTimeEdit::hour12Test() +{ + testWidget->setDisplayFormat("hh a"); + testWidget->setTime(QTime(0, 0, 0)); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("12 am")); + for (int i=0; i<11; ++i) { + QTest::keyClick(testWidget, Qt::Key_Up); + } + QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 am")); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("12 pm")); + for (int i=0; i<11; ++i) { + QTest::keyClick(testWidget, Qt::Key_Up); + } + QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 pm")); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 pm")); + for (int i=0; i<12; ++i) { + QTest::keyClick(testWidget, Qt::Key_Down); + } + QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 am")); + QTest::keyClick(testWidget, Qt::Key_1); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("1 am")); + QTest::keyClick(testWidget, Qt::Key_3); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("1 am")); +} + +void tst_QDateTimeEdit::yyTest() +{ + testWidget->setDisplayFormat("dd-MMM-yy"); + testWidget->setTime(QTime(0, 0, 0)); + testWidget->setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31)); + testWidget->setDate(testWidget->minimumDate()); + testWidget->setCurrentSection(QDateTimeEdit::YearSection); + + QString jan = QDate::shortMonthName(1); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-05"); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-06"); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-07"); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-08"); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-09"); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-10"); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-10"); + testWidget->setWrapping(true); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-05"); + + testWidget->setDateRange(QDate(100, 1, 1), QDate(8000, 12, 31)); + testWidget->setDate(QDate(2000, 1, 1)); + testWidget->setCurrentSection(QDateTimeEdit::YearSection); + testWidget->setWrapping(false); + for (int i=0; i<10; ++i) { + for (int j=0; j<50; ++j) { + testWidget->stepBy(-1); + } + testWidget->stepBy(-50); + QCOMPARE(testWidget->sectionText(QDateTimeEdit::YearSection), QString("00")); + QCOMPARE(testWidget->date(), QDate(2000 - ((i + 1) * 100), 1, 1)); + } +} + +void tst_QDateTimeEdit::task108572() +{ + testWidget->setDisplayFormat("hh:mm:ss.zzz"); + testWidget->setTime(QTime(0, 1, 2, 0)); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("00:01:02.000")); + + testWidget->setCurrentSection(QDateTimeEdit::MSecSection); + QTest::keyClick(testWidget, Qt::Key_Return); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("000")); + QTest::keyClick(testWidget, Qt::Key_2); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("00:01:02.2")); + QTest::keyClick(testWidget, Qt::Key_Return); + QCOMPARE(testWidget->lineEdit()->displayText(), QString("00:01:02.200")); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("200")); + QCOMPARE(testWidget->time(), QTime(0, 1, 2, 200)); +} + +void tst_QDateTimeEdit::task149097() +{ + QSignalSpy dtSpy(testWidget, SIGNAL(dateTimeChanged(const QDateTime &))); + QSignalSpy dSpy(testWidget, SIGNAL(dateChanged(const QDate &))); + QSignalSpy tSpy(testWidget, SIGNAL(timeChanged(const QTime &))); + + testWidget->setDisplayFormat("yyyy/MM/dd hh:mm:ss"); + testWidget->setDateTime(QDateTime(QDate(2001, 02, 03), QTime(5, 1, 2))); +// QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(dtSpy.count(), 1); + QCOMPARE(dSpy.count(), 1); + QCOMPARE(tSpy.count(), 1); + testWidget->setCurrentSection(QDateTimeEdit::YearSection); + testWidget->stepBy(1); + + QCOMPARE(dtSpy.count(), 2); + QCOMPARE(dSpy.count(), 2); + QCOMPARE(tSpy.count(), 1); + + testWidget->setCurrentSection(QDateTimeEdit::MinuteSection); + testWidget->stepBy(1); + + QCOMPARE(dtSpy.count(), 3); + QCOMPARE(dSpy.count(), 2); + QCOMPARE(tSpy.count(), 2); +} + +void tst_QDateTimeEdit::task148725() +{ + testWidget->setDisplayFormat("dd/MM"); + testWidget->setDate(QDate(2001, 2, 27)); + testWidget->stepBy(1); + QCOMPARE(testWidget->date(), QDate(2001, 2, 28)); + testWidget->stepBy(1); + QCOMPARE(testWidget->date(), QDate(2001, 2, 28)); + testWidget->setWrapping(true); + testWidget->stepBy(1); + QCOMPARE(testWidget->date(), QDate(2001, 2, 1)); +} + +void tst_QDateTimeEdit::task148522() +{ + QTimeEdit edit; + const QDateTime dt(QDate(2000, 12, 12), QTime(12, 13, 14, 15)); + edit.setDateTime(dt); + QCOMPARE(edit.dateTime(), dt); +} + +void tst_QDateTimeEdit::ddMMMMyyyy() +{ + testWidget->setDisplayFormat("dd.MMMM.yyyy"); + testWidget->setDate(QDate(2000, 1, 1)); + testWidget->setCurrentSection(QDateTimeEdit::YearSection); + QTest::keyClick(testWidget, Qt::Key_Enter); + QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2000")); +#ifdef Q_WS_MAC + QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(testWidget, Qt::Key_End); +#endif + QTest::keyClick(testWidget, Qt::Key_Backspace); + QCOMPARE(testWidget->lineEdit()->text(), "01." + QDate::longMonthName(1) + ".200"); +} + +void tst_QDateTimeEdit::wheelEvent() +{ + testWidget->setDisplayFormat("dddd/MM"); + testWidget->setDate(QDate(2000, 2, 21)); + testWidget->setCurrentSection(QDateTimeEdit::DaySection); + QWheelEvent w(testWidget->lineEdit()->geometry().center(), 120, 0, 0); + qApp->sendEvent(testWidget, &w); + QCOMPARE(testWidget->date(), QDate(2000, 2, 22)); + testWidget->setCurrentSection(QDateTimeEdit::MonthSection); + qApp->sendEvent(testWidget, &w); + QCOMPARE(testWidget->date(), QDate(2000, 3, 22)); +} + +void tst_QDateTimeEdit::specialValueCornerCase() +{ + // if you set minimum to value it won't update since value won't + // be bounded to anything. If you have a specialValueText it needs + // to call updateEdit to make sure the text is changed + + QDateTimeEdit edit; + edit.setSpecialValueText("foobar"); + edit.setMinimumDate(edit.date()); + QCOMPARE(edit.minimumDate(), edit.date()); + QCOMPARE(edit.text(), QString("foobar")); +} + +void tst_QDateTimeEdit::cursorPositionOnInit() +{ + { + EditorDateEdit edit; + edit.setDisplayFormat("dd/MM"); + edit.show(); + QCOMPARE(edit.lineEdit()->cursorPosition(), 0); + } + + { + EditorDateEdit edit; + edit.setDisplayFormat("dd/MM"); + edit.setSpecialValueText("special"); + edit.setMinimumDate(edit.date()); + edit.show(); + QCOMPARE(edit.lineEdit()->cursorPosition(), 7); + // ### legacy behavior. Keep it like this rather than changing + // ### but add a test none-the-less + } +} + +void tst_QDateTimeEdit::task118867() +{ + EditorDateEdit edit; + edit.setDisplayFormat("hh:mm"); + edit.setMinimumTime(QTime(5, 30)); + edit.setMaximumTime(QTime(6, 30)); + QCOMPARE(edit.text(), QString("05:30")); + edit.lineEdit()->setCursorPosition(5); + QTest::keyClick(&edit, Qt::Key_Backspace); + QCOMPARE(edit.text(), QString("05:3")); + QTest::keyClick(&edit, Qt::Key_Backspace); + QCOMPARE(edit.text(), QString("05:")); + QTest::keyClick(&edit, Qt::Key_1); + QCOMPARE(edit.text(), QString("05:")); + QTest::keyClick(&edit, Qt::Key_2); + QCOMPARE(edit.text(), QString("05:")); + QTest::keyClick(&edit, Qt::Key_3); + QCOMPARE(edit.text(), QString("05:3")); + QTest::keyClick(&edit, Qt::Key_3); + QCOMPARE(edit.text(), QString("05:33")); +} + +void tst_QDateTimeEdit::nextPrevSection_data() +{ + QTest::addColumn<Qt::Key>("key"); + QTest::addColumn<Qt::KeyboardModifiers>("modifiers"); + QTest::addColumn<QString>("selectedText"); + + QTest::newRow("tab") << Qt::Key_Tab << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56"); + QTest::newRow("backtab") << Qt::Key_Backtab << (Qt::KeyboardModifiers)Qt::NoModifier << QString("12"); + QTest::newRow("shift-tab") << Qt::Key_Tab << (Qt::KeyboardModifiers)Qt::ShiftModifier << QString("12"); + QTest::newRow("/") << Qt::Key_Slash << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56"); + QTest::newRow("b") << Qt::Key_B << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56"); + QTest::newRow("c") << Qt::Key_C << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56"); + + // 1. mac doesn't do these, + // 2. some WinCE devices do not have modifiers +#if !defined(Q_OS_MAC) && !defined(WINCE_NO_MODIFIER_KEYS) + QTest::newRow("ctrl-right") << Qt::Key_Right << (Qt::KeyboardModifiers)Qt::ControlModifier << QString("56"); + QTest::newRow("ctrl-left") << Qt::Key_Left << (Qt::KeyboardModifiers)Qt::ControlModifier << QString("12"); +#endif +} + + +void tst_QDateTimeEdit::nextPrevSection() +{ + QFETCH(Qt::Key, key); + QFETCH(Qt::KeyboardModifiers, modifiers); + QFETCH(QString, selectedText); + + EditorDateEdit edit; + edit.setDisplayFormat("hh/mm/bc9ss"); + edit.setTime(QTime(12, 34, 56)); + edit.show(); + edit.setSelectedSection(QDateTimeEdit::MinuteSection); + QCOMPARE(edit.lineEdit()->selectedText(), QString("34")); // selftest + QTest::keyClick(&edit, key, modifiers); + QCOMPARE(edit.lineEdit()->selectedText(), selectedText); +} + +void tst_QDateTimeEdit::dateEditTimeEditFormats() +{ + QTimeEdit t; + t.setDisplayFormat("hh yyyy"); + QCOMPARE(t.displayedSections(), QDateTimeEdit::HourSection); + + QDateEdit d; + d.setDisplayFormat("hh yyyy"); + QCOMPARE(d.displayedSections(), QDateTimeEdit::YearSection); +} + + +void tst_QDateTimeEdit::timeSpec_data() +{ + QTest::addColumn<bool>("useSetProperty"); + QTest::newRow("setProperty") << true; + QTest::newRow("setTimeSpec") << false; +} + + +void tst_QDateTimeEdit::timeSpec() +{ + QFETCH(bool, useSetProperty); + + QDateTimeEdit edit; + QCOMPARE(edit.dateTime().timeSpec(), edit.timeSpec()); + QCOMPARE(edit.minimumDateTime().timeSpec(), edit.timeSpec()); + QCOMPARE(edit.maximumDateTime().timeSpec(), edit.timeSpec()); + if (useSetProperty) { + edit.setProperty("timeSpec", Qt::UTC); + } else { + edit.setTimeSpec(Qt::UTC); + } + QCOMPARE(edit.minimumDateTime().timeSpec(), edit.timeSpec()); + QCOMPARE(edit.maximumDateTime().timeSpec(), edit.timeSpec()); + QCOMPARE(edit.dateTime().timeSpec(), edit.timeSpec()); + if (useSetProperty) { + edit.setProperty("timeSpec", Qt::LocalTime); + } else { + edit.setTimeSpec(Qt::LocalTime); + } + const QDateTime dt = edit.dateTime(); + QCOMPARE(edit.timeSpec(), Qt::LocalTime); + const QDateTime utc = dt.toUTC(); + if (dt.time() != utc.time()) { + const QDateTime min(QDate(1999, 1, 1), QTime(1, 0, 0), Qt::LocalTime); + edit.setMinimumDateTime(min); + QCOMPARE(edit.minimumTime(), min.time()); + if (useSetProperty) { + edit.setProperty("timeSpec", Qt::UTC); + } else { + edit.setTimeSpec(Qt::UTC); + } + QVERIFY(edit.minimumTime() != min.time()); + QVERIFY(edit.minimumDateTime().timeSpec() != min.timeSpec()); + QCOMPARE(edit.minimumDateTime().toTime_t(), min.toTime_t()); + } else { + QSKIP("Not tested in the GMT timezone", SkipAll); + } +} + +void tst_QDateTimeEdit::timeSpecBug() +{ + testWidget->setTimeSpec(Qt::UTC); + testWidget->setDisplayFormat("hh:mm"); + testWidget->setTime(QTime(2, 2)); + const QString oldText = testWidget->text(); + const QDateTime oldDateTime = testWidget->dateTime(); + QTest::keyClick(testWidget, Qt::Key_Tab); + QCOMPARE(oldDateTime, testWidget->dateTime()); + QCOMPARE(oldText, testWidget->text()); +} + + +void tst_QDateTimeEdit::cachedDayTest() +{ + testWidget->setDisplayFormat("MM/dd"); + testWidget->setDate(QDate(2007, 1, 30)); + testWidget->setCurrentSection(QDateTimeEdit::DaySection); + //QTest::keyClick(testWidget->lineEdit(), Qt::Key_Up); // this doesn't work + //on Mac. QTestLib bug? ### + QTest::keyClick(testWidget, Qt::Key_Up); + testWidget->setCurrentSection(QDateTimeEdit::MonthSection); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2007, 2, 28)); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2007, 3, 31)); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2007, 2, 28)); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2007, 1, 31)); + + testWidget->setCurrentSection(QDateTimeEdit::DaySection); + QTest::keyClick(testWidget, Qt::Key_Down); + QCOMPARE(testWidget->date(), QDate(2007, 1, 30)); + testWidget->setCurrentSection(QDateTimeEdit::MonthSection); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2007, 2, 28)); + testWidget->setCurrentSection(QDateTimeEdit::MonthSection); + QTest::keyClick(testWidget, Qt::Key_Up); + QCOMPARE(testWidget->date(), QDate(2007, 3, 30)); + +} + +void tst_QDateTimeEdit::monthEdgeCase() +{ + EditorDateEdit edit; + edit.setLocale(QLocale("fr_FR")); + edit.setDisplayFormat("MMM d"); + edit.setDate(QDate(2000, 1, 1)); + QCOMPARE(edit.text(), QString("janv. 1")); + edit.lineEdit()->setCursorPosition(5); + QTest::keyClick(&edit, Qt::Key_Backspace); + QCOMPARE(edit.text(), QString("janv 1")); +} + +class RestoreLocaler +{ +public: + RestoreLocaler() + : old(QLocale()) + {} + + ~RestoreLocaler() + { + QLocale::setDefault(old); + } +private: + const QLocale old; +}; + + + + +void tst_QDateTimeEdit::setLocale() +{ + RestoreLocaler r; + QLocale::setDefault(QLocale("en_US")); + { + EditorDateEdit edit; + edit.setDisplayFormat("MMMM d"); + edit.setDate(QDate(2000, 1, 1)); + QCOMPARE(edit.text(), QString("January 1")); + } + QLocale::setDefault(QLocale("no_NO")); + { + EditorDateEdit edit; + edit.setDisplayFormat("MMMM d"); + edit.setDate(QDate(2000, 1, 1)); + QCOMPARE(edit.text().toLower(), QString("januar 1")); + // I get Januar on Mac and januar on linux + } + QLocale::setDefault(QLocale("en_US")); + { + EditorDateEdit edit; + edit.setDisplayFormat("MMMM d"); + edit.setDate(QDate(2000, 1, 1)); + QCOMPARE(edit.text(), QString("January 1")); + edit.setLocale(QLocale("no_NO")); + QCOMPARE(edit.text().toLower(), QString("januar 1")); + edit.setLocale(QLocale("no_NO")); + } +} + + +void tst_QDateTimeEdit::potentialYYValueBug() +{ + EditorDateEdit edit; + edit.setDisplayFormat("dd/MM/yy"); + QCOMPARE(edit.minimumDate(), QDate(1752, 9, 14)); + edit.setDate(edit.minimumDate()); + edit.lineEdit()->setFocus(); + +#ifdef Q_WS_MAC + QTest::keyClick(&edit, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(&edit, Qt::Key_End); +#endif + QTest::keyClick(&edit, Qt::Key_Backspace); + QCOMPARE(edit.text(), QString("14/09/5")); +} + +void tst_QDateTimeEdit::textSectionAtEnd() +{ + EditorDateEdit edit; + edit.setDisplayFormat("MMMM"); + edit.setDate(QDate(2000, 1, 1)); + edit.lineEdit()->setFocus(); +#ifdef Q_WS_MAC + QTest::keyClick(&edit, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(&edit, Qt::Key_End); +#endif + QTest::keyClick(&edit, Qt::Key_Backspace); + QCOMPARE(edit.text(), QString("Januar")); +} + +void tst_QDateTimeEdit::keypadAutoAdvance_data() +{ + QTest::addColumn<Qt::KeyboardModifiers>("modifiers"); + QTest::newRow("None") << (Qt::KeyboardModifiers)Qt::NoModifier; + QTest::newRow("Keypad") << (Qt::KeyboardModifiers)Qt::KeypadModifier; + // QTBUG-7842: Using KeyPad with shift (numlock off) + QTest::newRow("Keypad+Shift") << (Qt::KeyboardModifiers)(Qt::KeypadModifier|Qt::ShiftModifier); +} + + +void tst_QDateTimeEdit::keypadAutoAdvance() +{ + QFETCH(Qt::KeyboardModifiers, modifiers); + + EditorDateEdit edit; + edit.setDate(QDate(2000, 2, 1)); + edit.setDisplayFormat("dd/MM"); +#ifdef Q_WS_MAC + QTest::keyClick(&edit, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(&edit, Qt::Key_Home); +#endif + QTest::keyClick(&edit, Qt::Key_Return); + QCOMPARE(edit.lineEdit()->selectedText(), QString("01")); + QTest::keyClick(&edit, Qt::Key_1, modifiers); + QTest::keyClick(&edit, Qt::Key_2, modifiers); + QCOMPARE(edit.lineEdit()->selectedText(), QString("02")); +} + + +void tst_QDateTimeEdit::task196924() +{ + EditorDateEdit edit; + edit.setDisplayFormat("dd/M/yyyy"); + edit.setDate(QDate(2345, 6, 17)); + QCOMPARE(edit.text(), QString("17/6/2345")); + QTest::keyClick(&edit, Qt::Key_Tab); + QCOMPARE(edit.lineEdit()->selectedText(), QString("6")); + QTest::keyClick(&edit, Qt::Key_3); + QCOMPARE(edit.lineEdit()->selectedText(), QString("2345")); + QCOMPARE(edit.text(), QString("17/3/2345")); + + edit.setDisplayFormat("dd/MM/yyyy"); + edit.setDate(QDate(2345, 6, 17)); + edit.lineEdit()->setCursorPosition(0); + QCOMPARE(edit.text(), QString("17/06/2345")); + QTest::keyClick(&edit, Qt::Key_Tab); + QCOMPARE(edit.lineEdit()->selectedText(), QString("06")); + QTest::keyClick(&edit, Qt::Key_3); + QCOMPARE(edit.lineEdit()->selectedText(), QString("2345")); + QCOMPARE(edit.text(), QString("17/03/2345")); + +} + +void tst_QDateTimeEdit::focusNextPrevChild() +{ + EditorDateEdit edit; + edit.setDisplayFormat("dd/MM/yyyy"); + + edit.show(); + edit.setFocus(); + edit.setCurrentSection(QDateTimeEdit::DaySection); + + QCOMPARE(edit.currentSection(), QDateTimeEdit::DaySection); + edit.focusNextPrevChild(true); + QCOMPARE(edit.currentSection(), QDateTimeEdit::MonthSection); +} + +void tst_QDateTimeEdit::taskQTBUG_12384_timeSpecShowTimeOnly() +{ + QDateTime time = QDateTime::fromString("20100723 04:02:40", "yyyyMMdd hh:mm:ss"); + time.setTimeSpec(Qt::UTC); + + EditorDateEdit edit; + edit.setDisplayFormat("hh:mm:ss"); + edit.setTimeSpec(Qt::UTC); + edit.setDateTime(time); + + QCOMPARE(edit.minimumTime(), QTime(0, 0, 0, 0)); + QCOMPARE(edit.maximumTime(), QTime(23, 59, 59, 999)); + QCOMPARE(edit.time(), time.time()); +} + +void tst_QDateTimeEdit::deleteCalendarWidget() +{ + { + // setup + QCalendarWidget *cw = 0; + QDateEdit edit; + QVERIFY(!edit.calendarWidget()); + edit.setCalendarPopup(true); + QVERIFY(edit.calendarWidget()); + edit.calendarWidget()->setObjectName("cw1");; + + // delete + cw = edit.calendarWidget(); + delete cw; + + // it should create a new widget + QVERIFY(edit.calendarWidget()); + QVERIFY(edit.calendarWidget()->objectName() != "cw1"); + } +} + +QTEST_MAIN(tst_QDateTimeEdit) +#include "tst_qdatetimeedit.moc" diff --git a/tests/auto/widgets/widgets/qdial/.gitignore b/tests/auto/widgets/widgets/qdial/.gitignore new file mode 100644 index 0000000000..3a640cf1a1 --- /dev/null +++ b/tests/auto/widgets/widgets/qdial/.gitignore @@ -0,0 +1 @@ +tst_qdial diff --git a/tests/auto/widgets/widgets/qdial/qdial.pro b/tests/auto/widgets/widgets/qdial/qdial.pro new file mode 100644 index 0000000000..acf66de430 --- /dev/null +++ b/tests/auto/widgets/widgets/qdial/qdial.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qdial.cpp + + diff --git a/tests/auto/widgets/widgets/qdial/tst_qdial.cpp b/tests/auto/widgets/widgets/qdial/tst_qdial.cpp new file mode 100644 index 0000000000..568b82d28b --- /dev/null +++ b/tests/auto/widgets/widgets/qdial/tst_qdial.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <QDial> + +class tst_QDial : public QObject +{ + Q_OBJECT +public: + tst_QDial(); + +private slots: + void getSetCheck(); + void valueChanged(); + void sliderMoved(); + void wrappingCheck(); +}; + +// Testing get/set functions +void tst_QDial::getSetCheck() +{ + QDial obj1; + // bool QDial::notchesVisible() + // void QDial::setNotchesVisible(bool) + obj1.setNotchesVisible(false); + QCOMPARE(false, obj1.notchesVisible()); + obj1.setNotchesVisible(true); + QCOMPARE(true, obj1.notchesVisible()); + + // bool QDial::wrapping() + // void QDial::setWrapping(bool) + obj1.setWrapping(false); + QCOMPARE(false, obj1.wrapping()); + obj1.setWrapping(true); + QCOMPARE(true, obj1.wrapping()); +} + +tst_QDial::tst_QDial() +{ +} + +void tst_QDial::valueChanged() +{ + QDial dial; + dial.setMinimum(0); + dial.setMaximum(100); + QSignalSpy spy(&dial, SIGNAL(valueChanged(int))); + dial.setValue(50); + QCOMPARE(spy.count(), 1); + spy.clear(); + dial.setValue(25); + QCOMPARE(spy.count(), 1); + spy.clear(); + // repeat! + dial.setValue(25); + QCOMPARE(spy.count(), 0); +} + +void tst_QDial::sliderMoved() +{ + //this tests that when dragging the arrow that the sliderMoved signal is emitted + //even if tracking is set to false + QDial dial; + dial.setTracking(false); + dial.setMinimum(0); + dial.setMaximum(100); + + dial.show(); + + QPoint init(dial.width()/4, dial.height()/2); + + QMouseEvent pressevent(QEvent::MouseButtonPress, init, + Qt::LeftButton, Qt::LeftButton, 0); + qApp->sendEvent(&dial, &pressevent); + + QSignalSpy sliderspy(&dial, SIGNAL(sliderMoved(int))); + QSignalSpy valuespy(&dial, SIGNAL(valueChanged(int))); + + + { //move on top of the slider + init = QPoint(dial.width()/2, dial.height()/4); + QMouseEvent moveevent(QEvent::MouseMove, init, + Qt::LeftButton, Qt::LeftButton, 0); + qApp->sendEvent(&dial, &moveevent); + QCOMPARE( sliderspy.count(), 1); + QCOMPARE( valuespy.count(), 0); + } + + + { //move on the right of the slider + init = QPoint(dial.width()*3/4, dial.height()/2); + QMouseEvent moveevent(QEvent::MouseMove, init, + Qt::LeftButton, Qt::LeftButton, 0); + qApp->sendEvent(&dial, &moveevent); + QCOMPARE( sliderspy.count(), 2); + QCOMPARE( valuespy.count(), 0); + } + + QMouseEvent releaseevent(QEvent::MouseButtonRelease, init, + Qt::LeftButton, Qt::LeftButton, 0); + qApp->sendEvent(&dial, &releaseevent); + QCOMPARE( valuespy.count(), 1); // valuechanged signal should be called at this point + +} + +void tst_QDial::wrappingCheck() +{ + //This tests if dial will wrap past the maximum value back to the minimum + //and vice versa when changing the value with a keypress + QDial dial; + dial.setMinimum(0); + dial.setMaximum(100); + dial.setSingleStep(1); + dial.setWrapping(true); + dial.setValue(99); + dial.show(); + + { //set value to maximum but do not wrap + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 100); + } + + { //step up once more and wrap clockwise to minimum + 1 + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 1); + } + + { //step down once, and wrap anti-clockwise to minimum, then again to maximum - 1 + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 0); + + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 99); + } + + { //when wrapping property is false no wrapping will occur + dial.setWrapping(false); + dial.setValue(100); + + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 100); + + dial.setValue(0); + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 0); + } + + { //When the step is really big or small, wrapping should still behave + dial.setWrapping(true); + dial.setValue(dial.minimum()); + dial.setSingleStep(305); + + QTest::keyPress(&dial, Qt::Key_Up); + QCOMPARE( dial.value(), 5); + + dial.setValue(dial.minimum()); + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), 95); + + dial.setMinimum(-30); + dial.setMaximum(-4); + dial.setSingleStep(200); + dial.setValue(dial.minimum()); + QTest::keyPress(&dial, Qt::Key_Down); + QCOMPARE( dial.value(), -22); + } +} + +QTEST_MAIN(tst_QDial) +#include "tst_qdial.moc" diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/.gitignore b/tests/auto/widgets/widgets/qdialogbuttonbox/.gitignore new file mode 100644 index 0000000000..edf08554d4 --- /dev/null +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/.gitignore @@ -0,0 +1 @@ +tst_qdialogbuttonbox diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/qdialogbuttonbox.pro b/tests/auto/widgets/widgets/qdialogbuttonbox/qdialogbuttonbox.pro new file mode 100644 index 0000000000..efbeca0c1b --- /dev/null +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/qdialogbuttonbox.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qdialogbuttonbox.cpp + +TARGET = tst_qdialogbuttonbox + + diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp new file mode 100644 index 0000000000..449cc5e44d --- /dev/null +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -0,0 +1,810 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QtTest/QtTest> +#include <QtWidgets/QPushButton> +#include <QtWidgets/QStyle> +#include <QtWidgets/QLayout> +#include <QtWidgets/QDialog> +#include <QtWidgets/QAction> +#include <qdialogbuttonbox.h> +#include <limits.h> + +//TESTED_CLASS= +//TESTED_FILES= + +Q_DECLARE_METATYPE(QList<int>) +Q_DECLARE_METATYPE(QDialogButtonBox::ButtonRole) +Q_DECLARE_METATYPE(QDialogButtonBox::StandardButton) +Q_DECLARE_METATYPE(QDialogButtonBox::StandardButtons) +Q_DECLARE_METATYPE(QAbstractButton*) + +class tst_QDialogButtonBox : public QObject +{ + Q_OBJECT +public: + tst_QDialogButtonBox(); + ~tst_QDialogButtonBox(); + + +public slots: + void buttonClicked1(QAbstractButton *); + void acceptClicked(); + void rejectClicked(); + void helpRequestedClicked(); + +private slots: + void standardButtons(); + void testConstructor1(); + void testConstrurtor2(); + void testConstrurtor2_data(); + void testConstructor3(); + void testConstructor3_data(); + void setOrientation_data(); + void setOrientation(); + void addButton1_data(); + void addButton1(); + void addButton2_data(); + void addButton2(); + void addButton3_data(); + void addButton3(); + void clear_data(); + void clear(); + void removeButton_data(); + void removeButton(); + void buttonRole_data(); + void buttonRole(); + void setStandardButtons_data(); + void setStandardButtons(); + void layoutReuse(); + + + // Skip these tests, buttons is used in every test thus far. +// void buttons_data(); +// void buttons(); + + void testDelete(); + void testRemove(); + void testMultipleAdd(); + void testStandardButtonMapping_data(); + void testStandardButtonMapping(); + void testSignals_data(); + void testSignals(); + void testSignalOrder(); + void testDefaultButton_data(); + void testDefaultButton(); +#ifdef QT_SOFTKEYS_ENABLED + void testSoftKeyReparenting(); +#endif + + void task191642_default(); +private: + qint64 timeStamp; + qint64 buttonClicked1TimeStamp; + qint64 acceptTimeStamp; + qint64 rejectTimeStamp; + qint64 helpRequestedTimeStamp; +}; + +tst_QDialogButtonBox::tst_QDialogButtonBox() +{ +} + +tst_QDialogButtonBox::~tst_QDialogButtonBox() +{ +} + +void tst_QDialogButtonBox::testConstructor1() +{ + QDialogButtonBox buttonbox; + QCOMPARE(buttonbox.orientation(), Qt::Horizontal); + + QCOMPARE(buttonbox.buttons().count(), 0); +} + +void tst_QDialogButtonBox::layoutReuse() +{ + QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok); + QPointer<QLayout> layout = box->layout(); + box->setCenterButtons(!box->centerButtons()); + QVERIFY(layout == box->layout()); + QEvent event(QEvent::StyleChange); + QApplication::sendEvent(box, &event); + QVERIFY(layout == box->layout()); + box->setOrientation(box->orientation() == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal); + QVERIFY(layout == 0); + QVERIFY(layout != box->layout()); + delete box; +} + +void tst_QDialogButtonBox::testConstrurtor2_data() +{ + QTest::addColumn<int>("orientation"); + + QTest::newRow("horizontal") << int(Qt::Horizontal); + QTest::newRow("vertical") << int(Qt::Vertical); +} + +void tst_QDialogButtonBox::testConstrurtor2() +{ + QFETCH(int, orientation); + Qt::Orientation orient = Qt::Orientation(orientation); + QDialogButtonBox buttonBox(orient); + + QCOMPARE(buttonBox.orientation(), orient); + QCOMPARE(buttonBox.buttons().count(), 0); +} + +void tst_QDialogButtonBox::testConstructor3_data() +{ + QTest::addColumn<int>("orientation"); + QTest::addColumn<QDialogButtonBox::StandardButtons>("buttons"); + QTest::addColumn<int>("buttonCount"); + + QTest::newRow("nothing") << int(Qt::Horizontal) << (QDialogButtonBox::StandardButtons)0 << 0; + QTest::newRow("only 1") << int(Qt::Horizontal) << QDialogButtonBox::StandardButtons(QDialogButtonBox::Ok) << 1; + QTest::newRow("only 1.. twice") << int(Qt::Horizontal) + << (QDialogButtonBox::Ok | QDialogButtonBox::Ok) + << 1; + QTest::newRow("only 2") << int(Qt::Horizontal) + << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel) + << 2; + QTest::newRow("two different things") << int(Qt::Horizontal) + << (QDialogButtonBox::Save | QDialogButtonBox::Close) + << 2; + QTest::newRow("three") << int(Qt::Horizontal) + << (QDialogButtonBox::Ok + | QDialogButtonBox::Cancel + | QDialogButtonBox::Help) + << 3; + QTest::newRow("everything") << int(Qt::Vertical) + << (QDialogButtonBox::StandardButtons)UINT_MAX + << 18; +} + +void tst_QDialogButtonBox::testConstructor3() +{ + QFETCH(int, orientation); + QFETCH(QDialogButtonBox::StandardButtons, buttons); + + QDialogButtonBox buttonBox(buttons, (Qt::Orientation)orientation); + QCOMPARE(int(buttonBox.orientation()), orientation); + QTEST(buttonBox.buttons().count(), "buttonCount"); +} + +void tst_QDialogButtonBox::setOrientation_data() +{ + QTest::addColumn<int>("orientation"); + + QTest::newRow("Horizontal") << int(Qt::Horizontal); + QTest::newRow("Vertical") << int(Qt::Vertical); +} + +void tst_QDialogButtonBox::setOrientation() +{ + QFETCH(int, orientation); + QDialogButtonBox buttonBox; + QCOMPARE(int(buttonBox.orientation()), int(Qt::Horizontal)); + + buttonBox.setOrientation(Qt::Orientation(orientation)); + QCOMPARE(int(buttonBox.orientation()), orientation); +} + +/* +void tst_QDialogButtonBox::setLayoutPolicy_data() +{ + QTest::addColumn<int>("layoutPolicy"); + + QTest::newRow("win") << int(QDialogButtonBox::WinLayout); + QTest::newRow("mac") << int(QDialogButtonBox::MacLayout); + QTest::newRow("kde") << int(QDialogButtonBox::KdeLayout); + QTest::newRow("gnome") << int(QDialogButtonBox::GnomeLayout); + +} + +void tst_QDialogButtonBox::setLayoutPolicy() +{ + QFETCH(int, layoutPolicy); + + QDialogButtonBox buttonBox; + QCOMPARE(int(buttonBox.layoutPolicy()), + int(buttonBox.style()->styleHint(QStyle::SH_DialogButtonLayout))); + buttonBox.setLayoutPolicy(QDialogButtonBox::ButtonLayout(layoutPolicy)); + QCOMPARE(int(buttonBox.layoutPolicy()), layoutPolicy); +} +*/ + +void tst_QDialogButtonBox::addButton1_data() +{ + QTest::addColumn<QDialogButtonBox::ButtonRole>("role"); + QTest::addColumn<int>("totalCount"); + + QTest::newRow("InvalidRole") << QDialogButtonBox::InvalidRole << 0; + QTest::newRow("AcceptRole") << QDialogButtonBox::AcceptRole << 1; + QTest::newRow("RejectRole") << QDialogButtonBox::RejectRole << 1; + QTest::newRow("DestructiveRole") << QDialogButtonBox::DestructiveRole << 1; + QTest::newRow("ActionRole") << QDialogButtonBox::ActionRole << 1; + QTest::newRow("HelpRole") << QDialogButtonBox::HelpRole << 1; + QTest::newRow("WackyValue") << (QDialogButtonBox::ButtonRole)-1 << 0; +} + +void tst_QDialogButtonBox::addButton1() +{ + QFETCH(QDialogButtonBox::ButtonRole, role); + QDialogButtonBox buttonBox; + QCOMPARE(buttonBox.buttons().count(), 0); + QPushButton *button = new QPushButton(); + buttonBox.addButton(button, role); + QTEST(buttonBox.buttons().count(), "totalCount"); + QList<QAbstractButton *> children = qFindChildren<QAbstractButton *>(&buttonBox); + QTEST(children.count(), "totalCount"); + delete button; +} + +void tst_QDialogButtonBox::addButton2_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QDialogButtonBox::ButtonRole>("role"); + QTest::addColumn<int>("totalCount"); + QTest::newRow("InvalidRole") << QString("foo") << QDialogButtonBox::InvalidRole << 0; + QTest::newRow("AcceptRole") << QString("foo") << QDialogButtonBox::AcceptRole << 1; + QTest::newRow("RejectRole") << QString("foo") << QDialogButtonBox::RejectRole << 1; + QTest::newRow("DestructiveRole") << QString("foo") << QDialogButtonBox::DestructiveRole << 1; + QTest::newRow("ActionRole") << QString("foo") << QDialogButtonBox::ActionRole << 1; + QTest::newRow("HelpRole") << QString("foo") << QDialogButtonBox::HelpRole << 1; + QTest::newRow("WackyValue") << QString("foo") << (QDialogButtonBox::ButtonRole)-1 << 0; +} + +void tst_QDialogButtonBox::addButton2() +{ + QFETCH(QString, text); + QFETCH(QDialogButtonBox::ButtonRole, role); + QDialogButtonBox buttonBox; + QCOMPARE(buttonBox.buttons().count(), 0); + buttonBox.addButton(text, role); + QTEST(buttonBox.buttons().count(), "totalCount"); + QList<QAbstractButton *> children = qFindChildren<QAbstractButton *>(&buttonBox); + QTEST(children.count(), "totalCount"); +} + +void tst_QDialogButtonBox::addButton3_data() +{ + QTest::addColumn<QDialogButtonBox::StandardButton>("button"); + QTest::addColumn<int>("totalCount"); + QTest::newRow("Ok") << QDialogButtonBox::Ok << 1; + QTest::newRow("Open") << QDialogButtonBox::Open << 1; + QTest::newRow("Save") << QDialogButtonBox::Save << 1; + QTest::newRow("Cancel") << QDialogButtonBox::Cancel << 1; + QTest::newRow("Close") << QDialogButtonBox::Close << 1; + QTest::newRow("Discard") << QDialogButtonBox::Discard << 1; + QTest::newRow("Apply") << QDialogButtonBox::Apply << 1; + QTest::newRow("Reset") << QDialogButtonBox::Reset << 1; + QTest::newRow("Help") << QDialogButtonBox::Help << 1; + QTest::newRow("noButton") << (QDialogButtonBox::StandardButton)0 << 0; +} + +void tst_QDialogButtonBox::addButton3() +{ + QFETCH(QDialogButtonBox::StandardButton, button); + QDialogButtonBox buttonBox; + QCOMPARE(buttonBox.buttons().count(), 0); + buttonBox.addButton(button); + QTEST(buttonBox.buttons().count(), "totalCount"); + QList<QAbstractButton *> children = qFindChildren<QAbstractButton *>(&buttonBox); + QTEST(children.count(), "totalCount"); +} + +void tst_QDialogButtonBox::clear_data() +{ + QTest::addColumn<int>("rolesToAdd"); + + QTest::newRow("nothing") << 0; + QTest::newRow("one") << 1; + QTest::newRow("all") << int(QDialogButtonBox::NRoles); +} + +void tst_QDialogButtonBox::clear() +{ + QFETCH(int, rolesToAdd); + + QDialogButtonBox buttonBox; + for (int i = 1; i < rolesToAdd; ++i) + buttonBox.addButton("Happy", QDialogButtonBox::ButtonRole(i)); + buttonBox.clear(); + QCOMPARE(buttonBox.buttons().count(), 0); + QList<QAbstractButton *> children = qFindChildren<QAbstractButton *>(&buttonBox); + QCOMPARE(children.count(), 0); +} + +void tst_QDialogButtonBox::removeButton_data() +{ + QTest::addColumn<QDialogButtonBox::ButtonRole>("roleToAdd"); + QTest::addColumn<int>("expectedCount"); + QTest::newRow("no button added") << QDialogButtonBox::InvalidRole << 0; + QTest::newRow("a button") << QDialogButtonBox::AcceptRole << 1; +} + +void tst_QDialogButtonBox::removeButton() +{ + QFETCH(QDialogButtonBox::ButtonRole, roleToAdd); + + QDialogButtonBox buttonBox; + QCOMPARE(buttonBox.buttons().count(), 0); + QPushButton *button = new QPushButton("RemoveButton test"); + buttonBox.addButton(button, roleToAdd); + QTEST(buttonBox.buttons().count(), "expectedCount"); + + buttonBox.removeButton(button); + QCOMPARE(buttonBox.buttons().count(), 0); + delete button; +} + +void tst_QDialogButtonBox::testDelete() +{ + QDialogButtonBox buttonBox; + QCOMPARE(buttonBox.buttons().count(), 0); + + QPushButton *deleteMe = new QPushButton("Happy"); + buttonBox.addButton(deleteMe, QDialogButtonBox::HelpRole); + QCOMPARE(buttonBox.buttons().count(), 1); + QList<QAbstractButton *> children = qFindChildren<QAbstractButton *>(&buttonBox); + QCOMPARE(children.count(), 1); + + delete deleteMe; + children = qFindChildren<QAbstractButton *>(&buttonBox); + QCOMPARE(children.count(), 0); + QCOMPARE(buttonBox.buttons().count(), 0); +} + +void tst_QDialogButtonBox::testMultipleAdd() +{ + // Add a button into the thing multiple times. + QDialogButtonBox buttonBox; + QCOMPARE(buttonBox.buttons().count(), 0); + + QPushButton *button = new QPushButton("Foo away"); + buttonBox.addButton(button, QDialogButtonBox::AcceptRole); + QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole); + buttonBox.addButton(button, QDialogButtonBox::AcceptRole); + QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole); + + // Add it again with a different role + buttonBox.addButton(button, QDialogButtonBox::RejectRole); + QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole); + + // Add it as an "invalid" role + buttonBox.addButton(button, QDialogButtonBox::InvalidRole); + QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole); +} + +void tst_QDialogButtonBox::buttonRole_data() +{ + QTest::addColumn<QDialogButtonBox::ButtonRole>("roleToAdd"); + QTest::addColumn<QDialogButtonBox::ButtonRole>("expectedRole"); + + QTest::newRow("AcceptRole stuff") << QDialogButtonBox::AcceptRole + << QDialogButtonBox::AcceptRole; + QTest::newRow("Nothing") << QDialogButtonBox::InvalidRole << QDialogButtonBox::InvalidRole; + QTest::newRow("bad stuff") << (QDialogButtonBox::ButtonRole)-1 << QDialogButtonBox::InvalidRole; +} + +void tst_QDialogButtonBox::buttonRole() +{ + QFETCH(QDialogButtonBox::ButtonRole, roleToAdd); + QDialogButtonBox buttonBox; + QAbstractButton *button = buttonBox.addButton("Here's a button", roleToAdd); + QTEST(buttonBox.buttonRole(button), "expectedRole"); +} + +void tst_QDialogButtonBox::testStandardButtonMapping_data() +{ + QTest::addColumn<QDialogButtonBox::StandardButton>("button"); + QTest::addColumn<QDialogButtonBox::ButtonRole>("expectedRole"); + QTest::addColumn<QString>("expectedText"); + + int layoutPolicy = qApp->style()->styleHint(QStyle::SH_DialogButtonLayout); + + QTest::newRow("QDialogButtonBox::Ok") << QDialogButtonBox::Ok + << QDialogButtonBox::AcceptRole + << QDialogButtonBox::tr("OK"); + QTest::newRow("QDialogButtonBox::Open") << QDialogButtonBox::Open + << QDialogButtonBox::AcceptRole + << QDialogButtonBox::tr("Open"); + QTest::newRow("QDialogButtonBox::Save") << QDialogButtonBox::Save + << QDialogButtonBox::AcceptRole + << QDialogButtonBox::tr("Save"); + QTest::newRow("QDialogButtonBox::Cancel") << QDialogButtonBox::Cancel + << QDialogButtonBox::RejectRole + << QDialogButtonBox::tr("Cancel"); + QTest::newRow("QDialogButtonBox::Close") << QDialogButtonBox::Close + << QDialogButtonBox::RejectRole + << QDialogButtonBox::tr("Close"); + if (layoutPolicy == QDialogButtonBox::MacLayout) { + QTest::newRow("QDialogButtonBox::Discard") << QDialogButtonBox::Discard + << QDialogButtonBox::DestructiveRole + << QDialogButtonBox::tr("Don't Save"); + } else if (layoutPolicy == QDialogButtonBox::GnomeLayout) { + QTest::newRow("QDialogButtonBox::Discard") + << QDialogButtonBox::Discard + << QDialogButtonBox::DestructiveRole + << QDialogButtonBox::tr("Close without Saving"); + } else { + QTest::newRow("QDialogButtonBox::Discard") << QDialogButtonBox::Discard + << QDialogButtonBox::DestructiveRole + << QDialogButtonBox::tr("Discard"); + } + QTest::newRow("QDialogButtonBox::Apply") << QDialogButtonBox::Apply + << QDialogButtonBox::ApplyRole + << QDialogButtonBox::tr("Apply"); + QTest::newRow("QDialogButtonBox::Reset") << QDialogButtonBox::Reset + << QDialogButtonBox::ResetRole + << QDialogButtonBox::tr("Reset"); + QTest::newRow("QDialogButtonBox::Help") << QDialogButtonBox::Help + << QDialogButtonBox::HelpRole + << QDialogButtonBox::tr("Help"); +} + +void tst_QDialogButtonBox::testStandardButtonMapping() +{ + QFETCH(QDialogButtonBox::StandardButton, button); + QDialogButtonBox buttonBox; + + QAbstractButton *theButton = buttonBox.addButton(button); + QTEST(buttonBox.buttonRole(theButton), "expectedRole"); + QString textWithoutMnemonic = theButton->text().remove("&"); + QTEST(textWithoutMnemonic, "expectedText"); +} + +void tst_QDialogButtonBox::testSignals_data() +{ + QTest::addColumn<QDialogButtonBox::ButtonRole>("buttonToClick"); + QTest::addColumn<int>("clicked2Count"); + QTest::addColumn<int>("acceptCount"); + QTest::addColumn<int>("rejectCount"); + QTest::addColumn<int>("helpRequestedCount"); + + QTest::newRow("nothing") << QDialogButtonBox::InvalidRole << 0 << 0 << 0 << 0; + QTest::newRow("accept") << QDialogButtonBox::AcceptRole << 1 << 1 << 0 << 0; + QTest::newRow("reject") << QDialogButtonBox::RejectRole << 1 << 0 << 1 << 0; + QTest::newRow("destructive") << QDialogButtonBox::DestructiveRole << 1 << 0 << 0 << 0; + QTest::newRow("Action") << QDialogButtonBox::ActionRole << 1 << 0 << 0 << 0; + QTest::newRow("Help") << QDialogButtonBox::HelpRole << 1 << 0 << 0 << 1; +} + +void tst_QDialogButtonBox::testSignals() +{ + QFETCH(QDialogButtonBox::ButtonRole, buttonToClick); + QDialogButtonBox buttonBox; + qRegisterMetaType<QAbstractButton *>("QAbstractButton*"); + QSignalSpy clicked2(&buttonBox, SIGNAL(clicked(QAbstractButton*))); + QSignalSpy accept(&buttonBox, SIGNAL(accepted())); + QSignalSpy reject(&buttonBox, SIGNAL(rejected())); + QSignalSpy helpRequested(&buttonBox, SIGNAL(helpRequested())); + + QPushButton *clickMe = 0; + for (int i = QDialogButtonBox::AcceptRole; i < QDialogButtonBox::NRoles; ++i) { + QPushButton *button = buttonBox.addButton(QString::number(i), + QDialogButtonBox::ButtonRole(i)); + + if (i == buttonToClick) + clickMe = button; + } + if (clickMe) { + clickMe->animateClick(0); + QTest::qWait(100); + } + + QTEST(clicked2.count(), "clicked2Count"); + if (clicked2.count() > 0) + QCOMPARE(qvariant_cast<QAbstractButton *>(clicked2.at(0).at(0)), (QAbstractButton *)clickMe); + + QTEST(accept.count(), "acceptCount"); + QTEST(reject.count(), "rejectCount"); + QTEST(helpRequested.count(), "helpRequestedCount"); +} + +void tst_QDialogButtonBox::testSignalOrder() +{ + const qint64 longLongZero = 0; + buttonClicked1TimeStamp = acceptTimeStamp + = rejectTimeStamp = helpRequestedTimeStamp = timeStamp = 0; + QDialogButtonBox buttonBox; + connect(&buttonBox, SIGNAL(clicked(QAbstractButton *)), + this, SLOT(buttonClicked1(QAbstractButton *))); + connect(&buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked())); + connect(&buttonBox, SIGNAL(rejected()), this, SLOT(rejectClicked())); + connect(&buttonBox, SIGNAL(helpRequested()), this, SLOT(helpRequestedClicked())); + + QPushButton *acceptButton = buttonBox.addButton("OK", QDialogButtonBox::AcceptRole); + QPushButton *rejectButton = buttonBox.addButton("Cancel", QDialogButtonBox::RejectRole); + QPushButton *actionButton = buttonBox.addButton("Action This", QDialogButtonBox::ActionRole); + QPushButton *helpButton = buttonBox.addButton("Help Me!", QDialogButtonBox::HelpRole); + + // Try accept + acceptButton->animateClick(0); + QTest::qWait(100); + QCOMPARE(rejectTimeStamp, longLongZero); + QCOMPARE(helpRequestedTimeStamp, longLongZero); + + QVERIFY(buttonClicked1TimeStamp < acceptTimeStamp); + acceptTimeStamp = 0; + + rejectButton->animateClick(0); + QTest::qWait(100); + QCOMPARE(acceptTimeStamp, longLongZero); + QCOMPARE(helpRequestedTimeStamp, longLongZero); + QVERIFY(buttonClicked1TimeStamp < rejectTimeStamp); + + rejectTimeStamp = 0; + actionButton->animateClick(0); + QTest::qWait(100); + QCOMPARE(acceptTimeStamp, longLongZero); + QCOMPARE(rejectTimeStamp, longLongZero); + QCOMPARE(helpRequestedTimeStamp, longLongZero); + + helpButton->animateClick(0); + QTest::qWait(100); + QCOMPARE(acceptTimeStamp, longLongZero); + QCOMPARE(rejectTimeStamp, longLongZero); + QVERIFY(buttonClicked1TimeStamp < helpRequestedTimeStamp); +} + +void tst_QDialogButtonBox::buttonClicked1(QAbstractButton *) +{ + buttonClicked1TimeStamp = ++timeStamp; +} + +void tst_QDialogButtonBox::acceptClicked() +{ + acceptTimeStamp = ++timeStamp; +} + +void tst_QDialogButtonBox::rejectClicked() +{ + rejectTimeStamp = ++timeStamp; +} + +void tst_QDialogButtonBox::helpRequestedClicked() +{ + helpRequestedTimeStamp = ++timeStamp; +} + +void tst_QDialogButtonBox::setStandardButtons_data() +{ + QTest::addColumn<QDialogButtonBox::StandardButtons>("buttonsToAdd"); + QTest::addColumn<QDialogButtonBox::StandardButtons>("expectedResult"); + + QTest::newRow("Nothing") << QDialogButtonBox::StandardButtons(QDialogButtonBox::NoButton) + << QDialogButtonBox::StandardButtons(QDialogButtonBox::NoButton); + QTest::newRow("Everything") << (QDialogButtonBox::StandardButtons)0xffffffff + << (QDialogButtonBox::Ok + | QDialogButtonBox::Open + | QDialogButtonBox::Save + | QDialogButtonBox::Cancel + | QDialogButtonBox::Close + | QDialogButtonBox::Discard + | QDialogButtonBox::Apply + | QDialogButtonBox::Reset + | QDialogButtonBox::Help + | QDialogButtonBox::Yes + | QDialogButtonBox::YesToAll + | QDialogButtonBox::No + | QDialogButtonBox::NoToAll + | QDialogButtonBox::SaveAll + | QDialogButtonBox::Abort + | QDialogButtonBox::Retry + | QDialogButtonBox::Ignore + | QDialogButtonBox::RestoreDefaults + ); + QTest::newRow("Simple thing") << QDialogButtonBox::StandardButtons(QDialogButtonBox::Help) + << QDialogButtonBox::StandardButtons(QDialogButtonBox::Help); + QTest::newRow("Standard thing") << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel) + << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); +} + +void tst_QDialogButtonBox::setStandardButtons() +{ + QFETCH(QDialogButtonBox::StandardButtons, buttonsToAdd); + QDialogButtonBox buttonBox; + buttonBox.setStandardButtons(buttonsToAdd); + QTEST(buttonBox.standardButtons(), "expectedResult"); +} + +void tst_QDialogButtonBox::standardButtons() +{ + // Test various cases of setting StandardButtons + QDialogButtonBox buttonBox; + + QCOMPARE(buttonBox.standardButtons(), + QDialogButtonBox::StandardButtons(QDialogButtonBox::NoButton)); + + // Set some buttons + buttonBox.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + // Now add a button + buttonBox.addButton(QDialogButtonBox::Apply); + QCOMPARE(buttonBox.standardButtons(), + QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Apply); + + // Set the standard buttons to other things + buttonBox.setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel + | QDialogButtonBox::Discard); + QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Save | QDialogButtonBox::Cancel + | QDialogButtonBox::Discard); + QCOMPARE(buttonBox.buttons().size(), 3); + + // Add another button (not a standard one) + buttonBox.addButton(QLatin1String("Help"), QDialogButtonBox::HelpRole); + QCOMPARE(buttonBox.standardButtons(), QDialogButtonBox::Save | QDialogButtonBox::Cancel + | QDialogButtonBox::Discard); + QCOMPARE(buttonBox.buttons().size(), 4); + + // Finally, check if we construct with standard buttons that they show up. + QDialogButtonBox buttonBox2(QDialogButtonBox::Open | QDialogButtonBox::Reset); + QCOMPARE(buttonBox2.standardButtons(), QDialogButtonBox::Open | QDialogButtonBox::Reset); +} + +void tst_QDialogButtonBox::testRemove() +{ + // Make sure that removing a button and clicking it, doesn't trigger any latent signals + QDialogButtonBox buttonBox; + QSignalSpy clicked(&buttonBox, SIGNAL(clicked(QAbstractButton*))); + + QAbstractButton *button = buttonBox.addButton(QDialogButtonBox::Ok); + + buttonBox.removeButton(button); + + button->animateClick(0); + QTest::qWait(100); + QCOMPARE(clicked.count(), 0); + delete button; +} + +void tst_QDialogButtonBox::testDefaultButton_data() +{ + QTest::addColumn<int>("whenToSetDefault"); // -1 Do nothing, 0 after accept, 1 before accept + QTest::addColumn<int>("buttonToBeDefault"); + QTest::addColumn<int>("indexThatIsDefault"); + + QTest::newRow("do nothing First Accept implicit") << -1 << -1 << 0; + QTest::newRow("First accept explicit before add") << 1 << 0 << 0; + QTest::newRow("First accept explicit after add") << 0 << 0 << 0; + QTest::newRow("second accept explicit before add") << 1 << 1 << 1; + QTest::newRow("second accept explicit after add") << 0 << 1 << 1; + QTest::newRow("third accept explicit befare add") << 1 << 2 << 2; + QTest::newRow("third accept explicit after add") << 0 << 2 << 2; +} + +static int softKeyCount(QWidget *widget) +{ + int softkeyCount = 0; +#ifndef QT_NO_ACTION + QList<QAction *> actions = widget->actions(); + foreach (QAction *action, actions) { + if (action->softKeyRole() != QAction::NoSoftKey) + softkeyCount++; + } +#endif + return softkeyCount; +} + +#ifdef QT_SOFTKEYS_ENABLED +void tst_QDialogButtonBox::testSoftKeyReparenting() +{ + QDialog dialog; + QDialogButtonBox *buttonBox = new QDialogButtonBox; + buttonBox->addButton(QDialogButtonBox::Ok); + buttonBox->addButton(QDialogButtonBox::Cancel); + +#ifndef QT_NO_ACTION + QCOMPARE(softKeyCount(&dialog), 0); + QCOMPARE(softKeyCount(buttonBox), 2); +#endif + + // Were the softkeys re-parented correctly? + dialog.setLayout(new QVBoxLayout); + dialog.layout()->addWidget(buttonBox); +#ifndef QT_NO_ACTION + QCOMPARE(softKeyCount(&dialog), 2); + QCOMPARE(softKeyCount(buttonBox), 0); +#endif + + // Softkeys are only added to QDialog, not QWidget + QWidget *nested = new QWidget; + nested->setLayout(new QVBoxLayout); + nested->layout()->addWidget(buttonBox); +#ifndef QT_NO_ACTION + QCOMPARE(softKeyCount(nested), 0); + QCOMPARE(softKeyCount(buttonBox), 2); +#endif +} +#endif + +void tst_QDialogButtonBox::testDefaultButton() +{ + QFETCH(int, whenToSetDefault); + QFETCH(int, buttonToBeDefault); + QFETCH(int, indexThatIsDefault); + QDialogButtonBox buttonBox; + QPushButton *buttonArray[] = { new QPushButton("Foo"), new QPushButton("Bar"), new QPushButton("Baz") }; + + for (int i = 0; i < 3; ++i) { + if (whenToSetDefault == 1 && i == buttonToBeDefault) + buttonArray[i]->setDefault(true); + buttonBox.addButton(buttonArray[i], QDialogButtonBox::AcceptRole); + if (whenToSetDefault == 0 && i == buttonToBeDefault) + buttonArray[i]->setDefault(true); + } + buttonBox.show(); + + for (int i = 0; i < 3; ++i) { + if (i == indexThatIsDefault) + QVERIFY(buttonArray[i]->isDefault()); + else + QVERIFY(!buttonArray[i]->isDefault()); + } +} + +void tst_QDialogButtonBox::task191642_default() +{ + QDialog dlg; + QPushButton *def = new QPushButton(&dlg); + QSignalSpy clicked(def, SIGNAL(clicked(bool))); + def->setDefault(true); + QDialogButtonBox *bb = new QDialogButtonBox(&dlg); + bb->addButton(QDialogButtonBox::Ok); + bb->addButton(QDialogButtonBox::Cancel); + bb->addButton(QDialogButtonBox::Help); + + dlg.show(); + QTest::qWait(10); + QVERIFY(def->isDefault()); + QTest::keyPress( &dlg, Qt::Key_Enter ); + QTest::qWait(100); + QCOMPARE(clicked.count(), 1); +} + +QTEST_MAIN(tst_QDialogButtonBox) +#include "tst_qdialogbuttonbox.moc" diff --git a/tests/auto/widgets/widgets/qdockwidget/.gitignore b/tests/auto/widgets/widgets/qdockwidget/.gitignore new file mode 100644 index 0000000000..7c79145a67 --- /dev/null +++ b/tests/auto/widgets/widgets/qdockwidget/.gitignore @@ -0,0 +1 @@ +tst_qdockwidget diff --git a/tests/auto/widgets/widgets/qdockwidget/qdockwidget.pro b/tests/auto/widgets/widgets/qdockwidget/qdockwidget.pro new file mode 100644 index 0000000000..e59728207f --- /dev/null +++ b/tests/auto/widgets/widgets/qdockwidget/qdockwidget.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +QT += widgets widgets-private +QT += core-private gui-private + +SOURCES += tst_qdockwidget.cpp + +CONFIG += insignificant_test # QTBUG-21402 diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp new file mode 100644 index 0000000000..2c1f7c0954 --- /dev/null +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -0,0 +1,877 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + + +#include <QtTest/QtTest> + + +#include <qaction.h> +#include <qdockwidget.h> +#include <qmainwindow.h> +#include <qlineedit.h> +#include <QDesktopWidget> +#include <QtGui/QPainter> +#include "private/qdockwidget_p.h" + +bool hasFeature(QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature) +{ return (dockwidget->features() & feature) == feature; } + +void setFeature(QDockWidget *dockwidget, QDockWidget::DockWidgetFeature feature, bool on = true) +{ + const QDockWidget::DockWidgetFeatures features = dockwidget->features(); + dockwidget->setFeatures(on ? features | feature : features & ~feature); +} + +//TESTED_FILES= + +class tst_QDockWidget : public QObject +{ + Q_OBJECT + +public: + tst_QDockWidget(); + +private slots: + void getSetCheck(); + void widget(); + void features(); + void setFloating(); + void allowedAreas(); + void toggleViewAction(); + void visibilityChanged(); + void dockLocationChanged(); + void setTitleBarWidget(); + void titleBarDoubleClick(); + void restoreStateOfFloating(); + // task specific tests: + void task165177_deleteFocusWidget(); + void task169808_setFloating(); + void task237438_setFloatingCrash(); + void task248604_infiniteResize(); + void task258459_visibilityChanged(); + void taskQTBUG_1665_closableChanged(); + void taskQTBUG_9758_undockedGeometry(); +}; + +// Testing get/set functions +void tst_QDockWidget::getSetCheck() +{ + QDockWidget obj1; + // QWidget * QDockWidget::widget() + // void QDockWidget::setWidget(QWidget *) + QWidget *var1 = new QWidget(); + obj1.setWidget(var1); + QCOMPARE(var1, obj1.widget()); + obj1.setWidget((QWidget *)0); + QCOMPARE((QWidget *)0, obj1.widget()); + delete var1; + + // DockWidgetFeatures QDockWidget::features() + // void QDockWidget::setFeatures(DockWidgetFeatures) + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetClosable)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetClosable), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetMovable)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetMovable), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetFloatable)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::DockWidgetFloatable), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::AllDockWidgetFeatures)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::AllDockWidgetFeatures), obj1.features()); + obj1.setFeatures(QDockWidget::DockWidgetFeatures(QDockWidget::NoDockWidgetFeatures)); + QCOMPARE(QDockWidget::DockWidgetFeatures(QDockWidget::NoDockWidgetFeatures), obj1.features()); +} + +tst_QDockWidget::tst_QDockWidget() +{ + qRegisterMetaType<QDockWidget::DockWidgetFeatures>("QDockWidget::DockWidgetFeatures"); + qRegisterMetaType<Qt::DockWidgetAreas>("Qt::DockWidgetAreas"); +} + +void tst_QDockWidget::widget() +{ + { + QDockWidget dw; + QVERIFY(dw.widget() == 0); + } + + { + QDockWidget dw; + QWidget *w1 = new QWidget; + QWidget *w2 = new QWidget; + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + dw.setWidget(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + dw.setWidget(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + dw.setWidget(0); + QVERIFY(dw.widget() == 0); + } + + { + QDockWidget dw; + QWidget *w1 = new QWidget; + QWidget *w2 = new QWidget; + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + w1->setParent(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + w2->setParent(0); + QVERIFY(dw.widget() == 0); + + dw.setWidget(w1); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w1); + QCOMPARE(w1->parentWidget(), (QWidget*)&dw); + + dw.setWidget(w2); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + w1->setParent(0); + QVERIFY(dw.widget() != 0); + QVERIFY(dw.widget() == w2); + QCOMPARE(w2->parentWidget(), (QWidget*)&dw); + + w2->setParent(0); + QVERIFY(dw.widget() == 0); + delete w1; + delete w2; + } +} + +void tst_QDockWidget::features() +{ + QDockWidget dw; + + QSignalSpy spy(&dw, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures))); + + // default features for dock widgets + int allDockWidgetFeatures = QDockWidget::DockWidgetClosable | + QDockWidget::DockWidgetMovable | + QDockWidget::DockWidgetFloatable; + + // defaults + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + + // test individual setting + setFeature(&dw, QDockWidget::DockWidgetClosable, false); + QCOMPARE(dw.features(), QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*(static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData())), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetClosable); + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetMovable, false); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetMovable); + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetFloatable, false); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + setFeature(&dw, QDockWidget::DockWidgetFloatable); + QCOMPARE(dw.features(), allDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + // set all at once + dw.setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + dw.setFeatures(QDockWidget::DockWidgetClosable); + QCOMPARE(dw.features(), QDockWidget::DockWidgetClosable); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(!hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + dw.setFeatures(QDockWidget::AllDockWidgetFeatures); + QCOMPARE(dw.features(), QDockWidget::AllDockWidgetFeatures); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetClosable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetMovable)); + QVERIFY(hasFeature(&dw, QDockWidget::DockWidgetFloatable)); + QCOMPARE(spy.count(), 1); + QCOMPARE((int)*static_cast<const QDockWidget::DockWidgetFeature *>(spy.at(0).value(0).constData()), + (int)dw.features()); + spy.clear(); + dw.setFeatures(dw.features()); + QCOMPARE(spy.count(), 0); + spy.clear(); +} + +void tst_QDockWidget::setFloating() +{ + QMainWindow mw; + QDockWidget dw; + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + + mw.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + + QVERIFY(!dw.isFloating()); + + QSignalSpy spy(&dw, SIGNAL(topLevelChanged(bool))); + + dw.setFloating(true); + QVERIFY(dw.isFloating()); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).value(0).toBool(), dw.isFloating()); + spy.clear(); + dw.setFloating(dw.isFloating()); + QCOMPARE(spy.count(), 0); + spy.clear(); + + dw.setFloating(false); + QVERIFY(!dw.isFloating()); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).value(0).toBool(), dw.isFloating()); + spy.clear(); + dw.setFloating(dw.isFloating()); + QCOMPARE(spy.count(), 0); + spy.clear(); +} + +void tst_QDockWidget::allowedAreas() +{ + QDockWidget dw; + + QSignalSpy spy(&dw, SIGNAL(allowedAreasChanged(Qt::DockWidgetAreas))); + + // default + QCOMPARE(dw.allowedAreas(), Qt::AllDockWidgetAreas); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + + // a single dock window area + dw.setAllowedAreas(Qt::LeftDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::LeftDockWidgetArea); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::RightDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::RightDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::TopDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::BottomDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::BottomDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + // multiple dock window areas + dw.setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::TopDockWidgetArea | Qt::LeftDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::TopDockWidgetArea | Qt::LeftDockWidgetArea); + QVERIFY(dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); + + dw.setAllowedAreas(Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea); + QCOMPARE(dw.allowedAreas(), Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea); + QVERIFY(!dw.isAreaAllowed(Qt::LeftDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::RightDockWidgetArea)); + QVERIFY(!dw.isAreaAllowed(Qt::TopDockWidgetArea)); + QVERIFY(dw.isAreaAllowed(Qt::BottomDockWidgetArea)); + QCOMPARE(spy.count(), 1); + QCOMPARE(*static_cast<const Qt::DockWidgetAreas *>(spy.at(0).value(0).constData()), + dw.allowedAreas()); + spy.clear(); + dw.setAllowedAreas(dw.allowedAreas()); + QCOMPARE(spy.count(), 0); +} + +void tst_QDockWidget::toggleViewAction() +{ + QMainWindow mw; + QDockWidget dw(&mw); + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + mw.show(); + QAction *toggleViewAction = dw.toggleViewAction(); + QVERIFY(!dw.isHidden()); + toggleViewAction->trigger(); + QVERIFY(dw.isHidden()); + toggleViewAction->trigger(); + QVERIFY(!dw.isHidden()); + toggleViewAction->trigger(); + QVERIFY(dw.isHidden()); +} + +void tst_QDockWidget::visibilityChanged() +{ + QMainWindow mw; + QDockWidget dw; + QSignalSpy spy(&dw, SIGNAL(visibilityChanged(bool))); + + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + mw.show(); + + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw.hide(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw.hide(); + QCOMPARE(spy.count(), 0); + + dw.show(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw.show(); + QCOMPARE(spy.count(), 0); + + QDockWidget dw2; + mw.tabifyDockWidget(&dw, &dw2); + dw2.show(); + dw2.raise(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw2.hide(); + qApp->processEvents(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw2.show(); + dw2.raise(); + qApp->processEvents(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw.raise(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); + spy.clear(); + + dw.raise(); + QCOMPARE(spy.count(), 0); + + dw2.raise(); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), false); + spy.clear(); + + dw2.raise(); + QCOMPARE(spy.count(), 0); + + mw.addDockWidget(Qt::RightDockWidgetArea, &dw2); + QTest::qWait(200); + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.at(0).at(0).toBool(), true); +} + +Q_DECLARE_METATYPE(Qt::DockWidgetArea) + +void tst_QDockWidget::dockLocationChanged() +{ + qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea"); + + QMainWindow mw; + QDockWidget dw; + dw.setObjectName("dock1"); + QSignalSpy spy(&dw, SIGNAL(dockLocationChanged(Qt::DockWidgetArea))); + + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), + Qt::LeftDockWidgetArea); + spy.clear(); + + mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), + Qt::LeftDockWidgetArea); + spy.clear(); + + mw.addDockWidget(Qt::RightDockWidgetArea, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), + Qt::RightDockWidgetArea); + spy.clear(); + + mw.removeDockWidget(&dw); + QCOMPARE(spy.count(), 0); + + QDockWidget dw2; + dw2.setObjectName("dock2"); + mw.addDockWidget(Qt::TopDockWidgetArea, &dw2); + mw.tabifyDockWidget(&dw2, &dw); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), + Qt::TopDockWidgetArea); + spy.clear(); + + mw.splitDockWidget(&dw2, &dw, Qt::Horizontal); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), + Qt::TopDockWidgetArea); + spy.clear(); + + dw.setFloating(true); + QTest::qWait(100); + dw.setFloating(false); + QTest::qWait(100); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), + Qt::TopDockWidgetArea); + spy.clear(); + + QByteArray ba = mw.saveState(); + mw.restoreState(ba); + QCOMPARE(spy.count(), 1); + QCOMPARE(qvariant_cast<Qt::DockWidgetArea>(spy.at(0).at(0)), + Qt::TopDockWidgetArea); +} + +void tst_QDockWidget::setTitleBarWidget() +{ + //test the successive usage of setTitleBarWidget + + QDockWidget dock; + QWidget w, w2; + + dock.show(); + qApp->processEvents(); + + dock.setTitleBarWidget(&w); + qApp->processEvents(); + QCOMPARE(w.isVisible(), true); + + //set another widget as the titlebar widget + dock.setTitleBarWidget(&w2); // this used to crash (task 184668) + qApp->processEvents(); + QCOMPARE(w.isVisible(), false); + QCOMPARE(w2.isVisible(), true); + + //tries to reset the titlebarwidget to none + dock.setTitleBarWidget(0); + qApp->processEvents(); + QCOMPARE(w.isVisible(), false); + QCOMPARE(w2.isVisible(), false); +} + +void tst_QDockWidget::titleBarDoubleClick() +{ + QMainWindow win; + QDockWidget dock(&win); + win.show(); + dock.setFloating(true); + + QEvent e(QEvent::NonClientAreaMouseButtonDblClick); + QApplication::sendEvent(&dock, &e); + QVERIFY(dock.isFloating()); + QCOMPARE(win.dockWidgetArea(&dock), Qt::NoDockWidgetArea); + + win.addDockWidget(Qt::TopDockWidgetArea, &dock); + dock.setFloating(true); + QApplication::sendEvent(&dock, &e); + QVERIFY(!dock.isFloating()); + QCOMPARE(win.dockWidgetArea(&dock), Qt::TopDockWidgetArea); +} + +void tst_QDockWidget::restoreStateOfFloating() +{ + QMainWindow mw; + QDockWidget dock; + dock.setObjectName("dock1"); + mw.addDockWidget(Qt::TopDockWidgetArea, &dock); + QVERIFY(!dock.isFloating()); + QByteArray ba = mw.saveState(); + dock.setFloating(true); + QVERIFY(dock.isFloating()); + QVERIFY(mw.restoreState(ba)); + QVERIFY(!dock.isFloating()); +} + + +void tst_QDockWidget::task165177_deleteFocusWidget() +{ + QMainWindow mw; + QDockWidget *dw = new QDockWidget(&mw); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw); + QLineEdit *ledit = new QLineEdit; + dw->setWidget(ledit); + mw.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + qApp->processEvents(); + dw->setFloating(true); + delete ledit; + QCOMPARE(mw.focusWidget(), (QWidget *)0); + QCOMPARE(dw->focusWidget(), (QWidget *)0); +} + +void tst_QDockWidget::task169808_setFloating() +{ + //we try to test if the sizeHint of the dock widget widget is taken into account + + class MyWidget : public QWidget + { + public: + QSize sizeHint() const + { + const QRect& deskRect = qApp->desktop()->availableGeometry(); + return QSize(qMin(300, deskRect.width()), 300); + } + + QSize minimumSizeHint() const + { + return QSize(20,20); + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.fillRect(rect(), Qt::red); + } + }; + QMainWindow mw; + mw.setCentralWidget(new MyWidget); + QDockWidget *dw = new QDockWidget("my dock"); + dw->setWidget(new MyWidget); + mw.addDockWidget(Qt::LeftDockWidgetArea, dw); + dw->setFloating(true); + mw.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + + QCOMPARE(dw->widget()->size(), dw->widget()->sizeHint()); + + //and now we try to test if the contents margin is taken into account + dw->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + dw->setFloating(false); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + QTest::qWait(100); //leave time processing events + + + const QSize oldSize = dw->size(); + const int margin = 20; + + dw->setContentsMargins(margin, margin, margin, margin); + +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&mw); +#endif + QTest::qWait(100); //leave time processing events + + //widget size shouldn't have changed + QCOMPARE(dw->widget()->size(), dw->widget()->sizeHint()); + //dockwidget should be bigger + QCOMPARE(dw->size(), oldSize + QSize(margin * 2, margin * 2)); + + +} + +void tst_QDockWidget::task237438_setFloatingCrash() +{ + //should not crash + QDockWidget pqdwDock; + pqdwDock.setFloating(false); + pqdwDock.show(); +} + +void tst_QDockWidget::task248604_infiniteResize() +{ + QDockWidget d; + QTabWidget *t = new QTabWidget; + t->addTab(new QWidget, "Foo"); + d.setWidget(t); + d.setContentsMargins(2, 2, 2, 2); + d.setMinimumSize(320, 240); + d.show(); + QTest::qWait(400); + QCOMPARE(d.size(), QSize(320, 240)); +} + + +void tst_QDockWidget::task258459_visibilityChanged() +{ + QMainWindow win; + QDockWidget dock1, dock2; + win.addDockWidget(Qt::RightDockWidgetArea, &dock1); + win.tabifyDockWidget(&dock1, &dock2); + QSignalSpy spy1(&dock1, SIGNAL(visibilityChanged(bool))); + QSignalSpy spy2(&dock2, SIGNAL(visibilityChanged(bool))); + win.show(); + QTest::qWait(200); + QCOMPARE(spy1.count(), 1); + QCOMPARE(spy1.first().first().toBool(), false); //dock1 is invisible + QCOMPARE(spy2.count(), 1); + QCOMPARE(spy2.first().first().toBool(), true); //dock1 is visible +} + +void tst_QDockWidget::taskQTBUG_1665_closableChanged() +{ + QDockWidget dock; + dock.show(); + QTest::qWaitForWindowShown(&dock); + + QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(dock.layout()); + + if (l && !l->nativeWindowDeco()) + QSKIP("this machine doesn't support native dock widget", SkipAll); + + QVERIFY(dock.windowFlags() & Qt::WindowCloseButtonHint); + + //now let's remove the closable attribute + dock.setFeatures(dock.features() ^ QDockWidget::DockWidgetClosable); + QVERIFY(!(dock.windowFlags() & Qt::WindowCloseButtonHint)); +} + +void tst_QDockWidget::taskQTBUG_9758_undockedGeometry() +{ + QMainWindow window; + QDockWidget dock1(&window); + QDockWidget dock2(&window); + window.addDockWidget(Qt::RightDockWidgetArea, &dock1); + window.addDockWidget(Qt::RightDockWidgetArea, &dock2); + window.tabifyDockWidget(&dock1, &dock2); + dock1.hide(); + dock2.hide(); + window.show(); + QTest::qWaitForWindowShown(&window); + dock1.setFloating(true); + dock1.show(); + QTest::qWaitForWindowShown(&dock1); + + QVERIFY(dock1.x() >= 0); + QVERIFY(dock1.y() >= 0); +} + + + +QTEST_MAIN(tst_QDockWidget) +#include "tst_qdockwidget.moc" diff --git a/tests/auto/widgets/widgets/qdoublespinbox/.gitignore b/tests/auto/widgets/widgets/qdoublespinbox/.gitignore new file mode 100644 index 0000000000..7704132e98 --- /dev/null +++ b/tests/auto/widgets/widgets/qdoublespinbox/.gitignore @@ -0,0 +1 @@ +tst_qdoublespinbox diff --git a/tests/auto/widgets/widgets/qdoublespinbox/qdoublespinbox.pro b/tests/auto/widgets/widgets/qdoublespinbox/qdoublespinbox.pro new file mode 100644 index 0000000000..ff0eb2edae --- /dev/null +++ b/tests/auto/widgets/widgets/qdoublespinbox/qdoublespinbox.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qdoublespinbox.cpp + +CONFIG += insignificant_test # QTBUG-21402 diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp new file mode 100644 index 0000000000..15f38e3334 --- /dev/null +++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp @@ -0,0 +1,1111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <qapplication.h> +#include <limits.h> + +#include <float.h> + +#include <qspinbox.h> +#include <qlocale.h> +#include <qlayout.h> + +#include <qlineedit.h> +#include <qdebug.h> + +//TESTED_CLASS= +//TESTED_FILES=gui/widgets/qspinbox.h gui/widgets/qspinbox.cpp gui/widgets/qabstractspinbox.cpp gui/widgets/qabstractspinbox_p.h gui/widgets/qabstractspinbox.h + + +class DoubleSpinBox : public QDoubleSpinBox +{ + Q_OBJECT +public: + DoubleSpinBox(QWidget *parent = 0) + : QDoubleSpinBox(parent) + { /*connect(this, SIGNAL(valueChanged(double)), this, SLOT(foo(double)));*/ } + QString textFromValue(double v) const + { + return QDoubleSpinBox::textFromValue(v); + } + QValidator::State validate(QString &text, int &pos) const + { + return QDoubleSpinBox::validate(text, pos); + } + double valueFromText(const QString &text) const + { + return QDoubleSpinBox::valueFromText(text); + } + + QLineEdit* lineEdit() const { return QDoubleSpinBox::lineEdit(); } +public slots: + void foo(double vla) + { + qDebug() << vla; + } +}; + + +class tst_QDoubleSpinBox : public QObject +{ + Q_OBJECT +public: + tst_QDoubleSpinBox(); + virtual ~tst_QDoubleSpinBox(); +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + +private slots: + void germanTest(); + + void task54433(); + + void setValue_data(); + void setValue(); + + void setPrefixSuffix_data(); + void setPrefixSuffix(); + + void setTracking_data(); + void setTracking(); + + void setWrapping_data(); + void setWrapping(); + + void setSpecialValueText_data(); + void setSpecialValueText(); + + void setSingleStep_data(); + void setSingleStep(); + + void setMinMax_data(); + void setMinMax(); + + void setDecimals_data(); + void setDecimals(); + + void doubleDot(); + + void undoRedo(); + + void valueFromTextAndValidate_data(); + void valueFromTextAndValidate(); + + void setReadOnly(); + + void editingFinished(); + + void removeAll(); + + void task199226_stateAfterEnter(); + void task224497_fltMax(); + + void task221221(); + void task255471_decimalsValidation(); + + void taskQTBUG_5008_textFromValueAndValidate(); + void taskQTBUG_6670_selectAllWithPrefix(); + void taskQTBUG_6496_fiddlingWithPrecision(); + +public slots: + void valueChangedHelper(const QString &); + void valueChangedHelper(double); +private: + QStringList actualTexts; + QList<double> actualValues; + QWidget *testFocusWidget; +}; + +typedef QList<double> DoubleList; +Q_DECLARE_METATYPE(DoubleList) + +tst_QDoubleSpinBox::tst_QDoubleSpinBox() + +{ +} + +tst_QDoubleSpinBox::~tst_QDoubleSpinBox() +{ + +} + +void tst_QDoubleSpinBox::initTestCase() +{ + testFocusWidget = new QWidget(0); + testFocusWidget->resize(200, 100); + testFocusWidget->show(); +} + +void tst_QDoubleSpinBox::cleanupTestCase() +{ + delete testFocusWidget; + testFocusWidget = 0; +} + +void tst_QDoubleSpinBox::init() +{ + QLocale::setDefault(QLocale(QLocale::C)); +} + +void tst_QDoubleSpinBox::setValue_data() +{ + QTest::addColumn<double>("val"); + + QTest::newRow("data0") << 0.0; + QTest::newRow("data1") << 100.5; + QTest::newRow("data2") << -100.5; + QTest::newRow("data3") << -DBL_MAX; + QTest::newRow("data4") << DBL_MAX; +} + +void tst_QDoubleSpinBox::setValue() +{ + QFETCH(double, val); + QDoubleSpinBox spin(0); + spin.setRange(-DBL_MAX, DBL_MAX); + spin.setValue(val); + QCOMPARE(spin.value(), val); +} + +void tst_QDoubleSpinBox::setPrefixSuffix_data() +{ + QTest::addColumn<QString>("prefix"); + QTest::addColumn<QString>("suffix"); + QTest::addColumn<double>("value"); + QTest::addColumn<int>("decimals"); + QTest::addColumn<QString>("expectedText"); + QTest::addColumn<QString>("expectedCleanText"); + QTest::addColumn<bool>("show"); + + QTest::newRow("data0") << QString() << QString() << 10.5 << 1 << "10.5" << "10.5" << false; + QTest::newRow("data1") << QString() << "cm" << 10.5 << 2 << "10.50cm" << "10.50" << false; + QTest::newRow("data2") << "cm: " << QString() << 10.5 << 0 << "cm: 10" << "10" << false; + QTest::newRow("data3") << "length: " << "cm" << 10.5 << 3 << "length: 10.500cm" << "10.500" << false; + + QTest::newRow("data4") << QString() << QString() << 10.5 << 1 << "10.5" << "10.5" << true; + QTest::newRow("data5") << QString() << "cm" << 10.5 << 2 << "10.50cm" << "10.50" << true; + QTest::newRow("data6") << "cm: " << QString() << 10.5 << 0 << "cm: 10" << "10" << true; + QTest::newRow("data7") << "length: " << "cm" << 10.5 << 3 << "length: 10.500cm" << "10.500" << true; +} + +void tst_QDoubleSpinBox::setPrefixSuffix() +{ + QFETCH(QString, prefix); + QFETCH(QString, suffix); + QFETCH(double, value); + QFETCH(int, decimals); + QFETCH(QString, expectedText); + QFETCH(QString, expectedCleanText); + QFETCH(bool, show); + + QDoubleSpinBox spin(0); + spin.setDecimals(decimals); + spin.setPrefix(prefix); + spin.setSuffix(suffix); + spin.setValue(value); + if (show) + spin.show(); + + QCOMPARE(spin.text(), expectedText); + QCOMPARE(spin.cleanText(), expectedCleanText); +} + +void tst_QDoubleSpinBox::valueChangedHelper(const QString &text) +{ + actualTexts << text; +} + +void tst_QDoubleSpinBox::valueChangedHelper(double value) +{ + actualValues << value; +} + +void tst_QDoubleSpinBox::setTracking_data() +{ + QTest::addColumn<int>("decimals"); + QTest::addColumn<QTestEventList>("keys"); + QTest::addColumn<QStringList>("texts"); + QTest::addColumn<bool>("tracking"); + + QTestEventList keys; + QStringList texts1; + QStringList texts2; +#ifdef Q_WS_MAC + keys.addKeyClick(Qt::Key_Right, Qt::ControlModifier); +#else + keys.addKeyClick(Qt::Key_End); +#endif + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick('7'); + keys.addKeyClick('.'); + keys.addKeyClick('9'); + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick('2'); + keys.addKeyClick(Qt::Key_Enter); + keys.addKeyClick(Qt::Key_Enter); + keys.addKeyClick(Qt::Key_Enter); + texts1 << "7" << "7.9" << "7." << "7.2" << "7.200" << "7.200" << "7.200"; + texts2 << "7.200"; + QTest::newRow("data1") << 3 << keys << texts1 << true; + QTest::newRow("data2") << 3 << keys << texts2 << false; + +} + +void tst_QDoubleSpinBox::setTracking() +{ + QLocale::setDefault(QLocale(QLocale::C)); + + actualTexts.clear(); + QFETCH(int, decimals); + QFETCH(QTestEventList, keys); + QFETCH(QStringList, texts); + QFETCH(bool, tracking); + + QDoubleSpinBox spin(0); + spin.setKeyboardTracking(tracking); + spin.setDecimals(decimals); + spin.show(); + + connect(&spin, SIGNAL(valueChanged(QString)), this, SLOT(valueChangedHelper(const QString &))); + + keys.simulate(&spin); + QCOMPARE(actualTexts, texts); +} + +void tst_QDoubleSpinBox::setWrapping_data() +{ + QTest::addColumn<bool>("wrapping"); + QTest::addColumn<double>("minimum"); + QTest::addColumn<double>("maximum"); + QTest::addColumn<double>("startValue"); + QTest::addColumn<QTestEventList>("keys"); + QTest::addColumn<DoubleList>("expected"); + + QTestEventList keys; + DoubleList values; + keys.addKeyClick(Qt::Key_Up); + values << 10; + keys.addKeyClick(Qt::Key_Up); + QTest::newRow("data0") << false << 0.0 << 10.0 << 9.0 << keys << values; + + keys.clear(); + values.clear(); + keys.addKeyClick(Qt::Key_Up); + values << 10; + keys.addKeyClick(Qt::Key_Up); + values << 0; + QTest::newRow("data1") << true << 0.0 << 10.0 << 9.0 << keys << values; + + keys.clear(); + values.clear(); +#ifdef Q_WS_MAC + keys.addKeyClick(Qt::Key_Right, Qt::ControlModifier); +#else + keys.addKeyClick(Qt::Key_End); +#endif + keys.addKeyClick(Qt::Key_Backspace); + keys.addKeyClick('1'); + keys.addKeyClick(Qt::Key_Down); + keys.addKeyClick(Qt::Key_Down); + keys.addKeyClick(Qt::Key_PageDown); + values << 9.01 << 8.01 << 7.01 << 0.0; + QTest::newRow("data2") << false << 0.0 << 10.0 << 9.0 << keys << values; + + keys.clear(); + values.clear(); +#ifdef Q_WS_MAC + keys.addKeyClick(Qt::Key_Left, Qt::ControlModifier); +#else + keys.addKeyClick(Qt::Key_Home); +#endif + keys.addKeyClick(Qt::Key_Delete); + keys.addKeyClick(Qt::Key_Delete); + keys.addKeyClick(Qt::Key_Delete); + keys.addKeyClick(Qt::Key_Delete); + keys.addKeyClick(Qt::Key_Delete); + keys.addKeyClick(Qt::Key_Delete); + keys.addKeyClick(Qt::Key_Delete); + keys.addKeyClick('1'); + keys.addKeyClick(Qt::Key_Down); + keys.addKeyClick(Qt::Key_Down); + values << 0 << 1 << 0 << 10; + QTest::newRow("data3") << true << 0.0 << 10.0 << 9.0 << keys << values; + + keys.clear(); + values.clear(); + keys.addKeyClick(Qt::Key_PageDown); + keys.addKeyClick(Qt::Key_Down); + values << 0; + QTest::newRow("data4") << false << 0.0 << 10.0 << 6.0 << keys << values; + + keys.clear(); + values.clear(); + keys.addKeyClick(Qt::Key_PageDown); + keys.addKeyClick(Qt::Key_Down); + values << 0 << 10; + QTest::newRow("data5") << true << 0.0 << 10.0 << 6.0 << keys << values; + + keys.clear(); + values.clear(); + keys.addKeyClick(Qt::Key_PageUp); + keys.addKeyClick(Qt::Key_PageDown); + keys.addKeyClick(Qt::Key_Down); + keys.addKeyClick(Qt::Key_Up); + keys.addKeyClick(Qt::Key_PageDown); + keys.addKeyClick(Qt::Key_PageDown); + values << 10 << 0 << 10 << 0 << 10 << 0; + QTest::newRow("data6") << true << 0.0 << 10.0 << 6.0 << keys << values; + +} + + +void tst_QDoubleSpinBox::setWrapping() +{ + QLocale::setDefault(QLocale(QLocale::C)); + QFETCH(bool, wrapping); + QFETCH(double, minimum); + QFETCH(double, maximum); + QFETCH(double, startValue); + QFETCH(QTestEventList, keys); + QFETCH(DoubleList, expected); + + QDoubleSpinBox spin(0); + spin.setMinimum(minimum); + spin.setMaximum(maximum); + spin.setValue(startValue); + spin.setWrapping(wrapping); + spin.show(); + actualValues.clear(); + connect(&spin, SIGNAL(valueChanged(double)), this, SLOT(valueChangedHelper(double))); + + keys.simulate(&spin); + + QCOMPARE(actualValues.size(), expected.size()); + for (int i=0; i<qMin(actualValues.size(), expected.size()); ++i) { + QCOMPARE(actualValues.at(i), expected.at(i)); + } +} + +void tst_QDoubleSpinBox::setSpecialValueText_data() +{ + QTest::addColumn<QString>("specialValueText"); + QTest::addColumn<double>("minimum"); + QTest::addColumn<double>("maximum"); + QTest::addColumn<double>("value"); + QTest::addColumn<int>("decimals"); + QTest::addColumn<QString>("expected"); + QTest::addColumn<bool>("show"); + + QTest::newRow("data0") << QString() << 0.0 << 10.0 << 1.0 << 4 << "1.0000" << false; + QTest::newRow("data1") << QString() << 0.0 << 10.0 << 1.0 << 4 << "1.0000" << true; + QTest::newRow("data2") << "foo" << 0.0 << 10.0 << 0.0 << 2 << "foo" << false; + QTest::newRow("data3") << "foo" << 0.0 << 10.0 << 0.0 << 2 << "foo" << true; +} + +void tst_QDoubleSpinBox::setSpecialValueText() +{ + QFETCH(QString, specialValueText); + QFETCH(double, minimum); + QFETCH(double, maximum); + QFETCH(double, value); + QFETCH(int, decimals); + QFETCH(QString, expected); + QFETCH(bool, show); + + QDoubleSpinBox spin(0); + spin.setSpecialValueText(specialValueText); + spin.setMinimum(minimum); + spin.setMaximum(maximum); + spin.setValue(value); + spin.setDecimals(decimals); + if (show) + spin.show(); + + QCOMPARE(spin.text(), expected); +} + +void tst_QDoubleSpinBox::setSingleStep_data() +{ + QTest::addColumn<double>("singleStep"); + QTest::addColumn<double>("startValue"); + QTest::addColumn<QTestEventList>("keys"); + QTest::addColumn<DoubleList>("expected"); + QTest::addColumn<bool>("show"); + + QTestEventList keys; + DoubleList values; + keys.addKeyClick(Qt::Key_Up); + keys.addKeyClick(Qt::Key_Down); + keys.addKeyClick(Qt::Key_Up); + values << 11 << 10 << 11; + QTest::newRow("data0") << 1.0 << 10.0 << keys << values << false; + QTest::newRow("data1") << 1.0 << 10.0 << keys << values << true; + + keys.clear(); + values.clear(); + keys.addKeyClick(Qt::Key_Up); + keys.addKeyClick(Qt::Key_Down); + keys.addKeyClick(Qt::Key_Up); + values << 12.5 << 10.0 << 12.5; + QTest::newRow("data2") << 2.5 << 10.0 << keys << values << false; + QTest::newRow("data3") << 2.5 << 10.0 << keys << values << true; +} + +void tst_QDoubleSpinBox::setSingleStep() +{ + QFETCH(double, singleStep); + QFETCH(double, startValue); + QFETCH(QTestEventList, keys); + QFETCH(DoubleList, expected); + QFETCH(bool, show); + + QDoubleSpinBox spin(0); + actualValues.clear(); + spin.setSingleStep(singleStep); + spin.setValue(startValue); + if (show) + spin.show(); + connect(&spin, SIGNAL(valueChanged(double)), this, SLOT(valueChangedHelper(double))); + + QCOMPARE(actualValues.size(), 0); + keys.simulate(&spin); + QCOMPARE(actualValues.size(), expected.size()); + for (int i=0; i<qMin(actualValues.size(), expected.size()); ++i) { + QCOMPARE(actualValues.at(i), expected.at(i)); + } +} + +void tst_QDoubleSpinBox::setMinMax_data() +{ + QTest::addColumn<double>("startValue"); + QTest::addColumn<double>("minimum"); + QTest::addColumn<double>("maximum"); + QTest::addColumn<QTestEventList>("keys"); + QTest::addColumn<double>("expected"); + QTest::addColumn<bool>("show"); + + QTestEventList keys; + keys.addKeyClick(Qt::Key_Up); + keys.addKeyClick(Qt::Key_Up); + keys.addKeyClick(Qt::Key_Up); + keys.addKeyClick(Qt::Key_Up); + keys.addKeyClick(Qt::Key_Up); + QTest::newRow("data0") << 1.0 << -DBL_MAX << 2.0 << keys << 2.0 << false; + QTest::newRow("data1") << 1.0 << -DBL_MAX << 2.0 << keys << 2.0 << true; + QTest::newRow("data2") << -20000.0 << -15000.0 << -13000.0 << keys << -14995.0 << false; + QTest::newRow("data3") << -20000.0 << -15000.0 << -13000.0 << keys << -14995.0 << true; + QTest::newRow("data4") << 20.0 << -101.2 << -102.0 << QTestEventList() << -102.0 << false; + QTest::newRow("data5") << 20.0 << -101.2 << -102.0 << QTestEventList() << -102.0 << true; +} + +void tst_QDoubleSpinBox::setMinMax() +{ + QFETCH(double, startValue); + QFETCH(double, minimum); + QFETCH(double, maximum); + QFETCH(QTestEventList, keys); + QFETCH(double, expected); + QFETCH(bool, show); + + { + QDoubleSpinBox spin(0); + spin.setMinimum(minimum); + spin.setMaximum(maximum); + spin.setValue(startValue); + + if (show) + spin.show(); + keys.simulate(&spin); + QCOMPARE(spin.value(), expected); + } + + { + QDoubleSpinBox spin(0); + spin.setMaximum(maximum); + spin.setMinimum(minimum); + spin.setValue(startValue); + + if (show) + spin.show(); + keys.simulate(&spin); + } + + { + QDoubleSpinBox spin(0); + spin.setRange(minimum, maximum); + spin.setValue(startValue); + + if (show) + spin.show(); + keys.simulate(&spin); + } + + +} + +void tst_QDoubleSpinBox::setDecimals_data() +{ + QTest::addColumn<int>("decimals"); + QTest::addColumn<int>("expectedDecimals"); + QTest::addColumn<double>("startValue"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("data0") << 4 << 4 << 1.0 << "1.0000"; + QTest::newRow("data1") << 1 << 1 << 1.243443 << "1.2"; + QTest::newRow("data2") << 6 << 6 << 1.29 << "1.290000"; + QTest::newRow("data3") << 8 << 8 << 9.1234567809 << "9.12345678"; + QTest::newRow("data4") << 13 << 13 << 0.12345678901237 << "0.1234567890124"; + QTest::newRow("data5") << 13 << 13 << -0.12345678901237 << "-0.1234567890124"; + QTest::newRow("data6") << 13 << 13 << -0.12345678901237 << "-0.1234567890124"; + QTest::newRow("data7") << -1 << 0 << 0.1 << "0"; + QTest::newRow("data8") << 120 << 120 << -0.12345678901237 << "-0.123456789012370005131913330842508003115653991699218750000000000000000000000000000000000000000000000000000000000000000000"; + +} + +void tst_QDoubleSpinBox::setDecimals() +{ + QFETCH(int, decimals); + QFETCH(int, expectedDecimals); + QFETCH(double, startValue); + QFETCH(QString, expected); + + QDoubleSpinBox spin(0); + spin.setRange(-DBL_MAX, DBL_MAX); + spin.setDecimals(decimals); + spin.setValue(startValue); + QCOMPARE(spin.decimals(), expectedDecimals); + if (sizeof(qreal) == sizeof(float)) + QCOMPARE(spin.text().left(17), expected.left(17)); + else + QCOMPARE(spin.text(), expected); + + if (spin.decimals() > 0) { +#ifdef Q_WS_MAC + QTest::keyClick(&spin, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(&spin, Qt::Key_End); +#endif + QTest::keyClick(&spin, Qt::Key_1); // just make sure we can't input more decimals than what is specified + QTest::keyClick(&spin, Qt::Key_1); + QTest::keyClick(&spin, Qt::Key_1); + QTest::keyClick(&spin, Qt::Key_1); + QTest::keyClick(&spin, Qt::Key_1); + if (sizeof(qreal) == sizeof(float)) + QCOMPARE(spin.text().left(17), expected.left(17)); + else + QCOMPARE(spin.text(), expected); + } +} + +static QString stateName(int state) +{ + switch (state) { + case QValidator::Acceptable: return QString("Acceptable"); + case QValidator::Intermediate: return QString("Intermediate"); + case QValidator::Invalid: return QString("Invalid"); + default: break; + } + qWarning("%s %d: this should never happen", __FILE__, __LINE__); + return QString(); +} + +void tst_QDoubleSpinBox::valueFromTextAndValidate_data() +{ + const int Intermediate = QValidator::Intermediate; + const int Invalid = QValidator::Invalid; + const int Acceptable = QValidator::Acceptable; + + QTest::addColumn<QString>("txt"); + QTest::addColumn<int>("state"); + QTest::addColumn<double>("mini"); + QTest::addColumn<double>("maxi"); + QTest::addColumn<int>("language"); + QTest::addColumn<QString>("expectedText"); // if empty we don't check + + QTest::newRow("data0") << QString("2.2") << Intermediate << 3.0 << 5.0 << (int)QLocale::C << QString(); + QTest::newRow("data1") << QString() << Intermediate << 0.0 << 100.0 << (int)QLocale::C << QString(); + QTest::newRow("data2") << QString("asd") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString(); + QTest::newRow("data3") << QString("2.2") << Acceptable << 0.0 << 100.0 << (int)QLocale::C << QString(); + QTest::newRow("data4") << QString(" ") << Intermediate << 0.0 << 100.0 << (int)QLocale::Norwegian << QString(); + QTest::newRow("data5") << QString(" ") << Intermediate << 0.0 << 100.0 << (int)QLocale::C << QString(); + QTest::newRow("data6") << QString(",") << Intermediate << 0.0 << 100.0 << (int)QLocale::Norwegian << QString(); + QTest::newRow("data7") << QString(",") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString(); + QTest::newRow("data8") << QString("1 ") << Acceptable << 0.0 << 1000.0 << (int)QLocale::Norwegian << QString("1"); + QTest::newRow("data9") << QString("1 ") << Acceptable << 0.0 << 100.0 << (int)QLocale::C << QString("1"); + QTest::newRow("data10") << QString(" 1") << Acceptable << 0.0 << 100.0 << (int)QLocale::Norwegian << QString("1"); + QTest::newRow("data11") << QString(" 1") << Acceptable << 0.0 << 100.0 << (int)QLocale::C << QString("1"); + QTest::newRow("data12") << QString("1,") << Acceptable << 0.0 << 100.0 << (int)QLocale::Norwegian << QString(); + QTest::newRow("data13") << QString("1,") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString(); + QTest::newRow("data14") << QString("1, ") << Acceptable << 0.0 << 100.0 << (int)QLocale::Norwegian << QString("1,"); + QTest::newRow("data15") << QString("1, ") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString(); + QTest::newRow("data16") << QString("2") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString(); + QTest::newRow("data17") << QString("22.0") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString(); + QTest::newRow("data18") << QString("12.0") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString(); + QTest::newRow("data19") << QString("12.2") << Intermediate << 100. << 102.0 << (int)QLocale::C << QString(); + QTest::newRow("data20") << QString("21.") << Intermediate << 100.0 << 102.0 << (int)QLocale::C << QString(); + QTest::newRow("data21") << QString("-21.") << Intermediate << -102.0 << -100.0 << (int)QLocale::C << QString(); + QTest::newRow("data22") << QString("-12.") << Intermediate << -102.0 << -100.0 << (int)QLocale::C << QString(); + QTest::newRow("data23") << QString("-11.11") << Intermediate << -102.0 << -101.2 << (int)QLocale::C << QString(); + QTest::newRow("data24") << QString("-11.4") << Intermediate << -102.0 << -101.3 << (int)QLocale::C << QString(); + QTest::newRow("data25") << QString("11.400") << Invalid << 0.0 << 100.0 << (int)QLocale::C << QString(); + QTest::newRow("data26") << QString(".4") << Intermediate << 0.45 << 0.5 << (int)QLocale::C << QString(); + QTest::newRow("data27") << QString("+.4") << Intermediate << 0.45 << 0.5 << (int)QLocale::C << QString(); + QTest::newRow("data28") << QString("-.4") << Intermediate << -0.5 << -0.45 << (int)QLocale::C << QString(); + QTest::newRow("data29") << QString(".4") << Intermediate << 1.0 << 2.4 << (int)QLocale::C << QString(); + QTest::newRow("data30") << QString("-.4") << Intermediate << -2.3 << -1.9 << (int)QLocale::C << QString(); + QTest::newRow("data31") << QString("-42") << Invalid << -2.43 << -1.0 << (int)QLocale::C << QString(); + QTest::newRow("data32") << QString("-4") << Invalid << -1.4 << -1.0 << (int)QLocale::C << QString(); + QTest::newRow("data33") << QString("-42") << Invalid << -1.4 << -1.0 << (int)QLocale::C << QString(); + QTest::newRow("data34") << QString("1000000000000") << Invalid << -140.0 << -120.2 << (int)QLocale::C << QString(); + QTest::newRow("data35") << QString("+.12") << Invalid << -5.0 << -3.2 << (int)QLocale::C << QString(); + QTest::newRow("data36") << QString("-.12") << Invalid << 5.0 << 33.2 << (int)QLocale::C << QString(); + QTest::newRow("data37") << QString("12.2") << Intermediate << 100. << 103.0 << (int)QLocale::C << QString(); + QTest::newRow("data38") << QString("12.2") << Intermediate << 100. << 102.3 << (int)QLocale::C << QString(); + QTest::newRow("data39") << QString("-12.") << Acceptable << -102.0 << 102.0 << (int)QLocale::C << QString(); + QTest::newRow("data40") << QString("12.") << Invalid << -102.0 << 11.0 << (int)QLocale::C << QString(); + QTest::newRow("data41") << QString("103.") << Invalid << -102.0 << 11.0 << (int)QLocale::C << QString(); + QTest::newRow("data42") << QString("122") << Invalid << 10.0 << 12.2 << (int)QLocale::C << QString(); + QTest::newRow("data43") << QString("-2.2") << Intermediate << -12.2 << -3.2 << (int)QLocale::C << QString(); + QTest::newRow("data44") << QString("-2.20") << Intermediate << -12.1 << -3.2 << (int)QLocale::C << QString(); + QTest::newRow("data45") << QString("200,2") << Invalid << 0.0 << 1000.0 << (int)QLocale::C << QString(); + QTest::newRow("data46") << QString("200,2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::German << QString(); + QTest::newRow("data47") << QString("2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString(); + QTest::newRow("data48") << QString("2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::German << QString(); + QTest::newRow("data49") << QString("2.2,00") << Acceptable << 0.0 << 1000.0 << (int)QLocale::German << QString(); + QTest::newRow("data50") << QString("2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString(); + QTest::newRow("data51") << QString("2.2,00") << Invalid << 0.0 << 1000.0 << (int)QLocale::C << QString(); + QTest::newRow("data52") << QString("2..2,00") << Invalid << 0.0 << 1000.0 << (int)QLocale::German << QString(); + QTest::newRow("data53") << QString("2.2") << Invalid << 0.0 << 1000.0 << (int)QLocale::Norwegian << QString(); + QTest::newRow("data54") << QString(" 2.2") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString(); + QTest::newRow("data55") << QString("2.2 ") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString("2.2"); + QTest::newRow("data56") << QString(" 2.2 ") << Acceptable << 0.0 << 1000.0 << (int)QLocale::C << QString("2.2"); + QTest::newRow("data57") << QString("2 2") << Invalid << 0.0 << 1000.0 << (int)QLocale::C << QString(); +} + +void tst_QDoubleSpinBox::valueFromTextAndValidate() +{ + QFETCH(QString, txt); + QFETCH(int, state); + QFETCH(double, mini); + QFETCH(double, maxi); + QFETCH(int, language); + QFETCH(QString, expectedText); + QLocale::setDefault(QLocale((QLocale::Language)language)); + + DoubleSpinBox sb(0); + sb.show(); + sb.setRange(mini, maxi); + + int unused = 0; + QCOMPARE(stateName(sb.validate(txt, unused)), stateName(state)); + if (!expectedText.isEmpty()) + QCOMPARE(txt, expectedText); +} + +void tst_QDoubleSpinBox::setReadOnly() +{ + QDoubleSpinBox spin(0); + spin.setValue(0.2); + spin.show(); + QCOMPARE(spin.value(), 0.2); + QTest::keyClick(&spin, Qt::Key_Up); + QCOMPARE(spin.value(), 1.2); + spin.setReadOnly(true); + QTest::keyClick(&spin, Qt::Key_Up); + QCOMPARE(spin.value(), 1.2); + spin.stepBy(1); + QCOMPARE(spin.value(), 2.2); + spin.setReadOnly(false); + QTest::keyClick(&spin, Qt::Key_Up); + QCOMPARE(spin.value(), 3.2); +} + +void tst_QDoubleSpinBox::editingFinished() +{ + QVBoxLayout *layout = new QVBoxLayout(testFocusWidget); + QDoubleSpinBox *box = new QDoubleSpinBox(testFocusWidget); + layout->addWidget(box); + QDoubleSpinBox *box2 = new QDoubleSpinBox(testFocusWidget); + layout->addWidget(box2); + + testFocusWidget->show(); + QApplication::setActiveWindow(testFocusWidget); + QTest::qWait(10); + QTRY_VERIFY(testFocusWidget->isActiveWindow()); + box->setFocus(); + QTRY_VERIFY(box->hasFocus()); + + QSignalSpy editingFinishedSpy1(box, SIGNAL(editingFinished())); + QSignalSpy editingFinishedSpy2(box2, SIGNAL(editingFinished())); + + box->setFocus(); + QTest::keyClick(box, Qt::Key_Up); + QTest::keyClick(box, Qt::Key_Up); + + + QCOMPARE(editingFinishedSpy1.count(), 0); + QCOMPARE(editingFinishedSpy2.count(), 0); + + QTest::keyClick(box2, Qt::Key_Up); + QTest::keyClick(box2, Qt::Key_Up); + box2->setFocus(); + QCOMPARE(editingFinishedSpy1.count(), 1); + box->setFocus(); + QCOMPARE(editingFinishedSpy1.count(), 1); + QCOMPARE(editingFinishedSpy2.count(), 1); + QTest::keyClick(box, Qt::Key_Up); + QCOMPARE(editingFinishedSpy1.count(), 1); + QCOMPARE(editingFinishedSpy2.count(), 1); + QTest::keyClick(box, Qt::Key_Enter); + QCOMPARE(editingFinishedSpy1.count(), 2); + QCOMPARE(editingFinishedSpy2.count(), 1); + QTest::keyClick(box, Qt::Key_Return); + QCOMPARE(editingFinishedSpy1.count(), 3); + QCOMPARE(editingFinishedSpy2.count(), 1); + box2->setFocus(); + QCOMPARE(editingFinishedSpy1.count(), 4); + QCOMPARE(editingFinishedSpy2.count(), 1); + QTest::keyClick(box2, Qt::Key_Enter); + QCOMPARE(editingFinishedSpy1.count(), 4); + QCOMPARE(editingFinishedSpy2.count(), 2); + QTest::keyClick(box2, Qt::Key_Return); + QCOMPARE(editingFinishedSpy1.count(), 4); + QCOMPARE(editingFinishedSpy2.count(), 3); + testFocusWidget->hide(); + QCOMPARE(editingFinishedSpy1.count(), 4); + QCOMPARE(editingFinishedSpy2.count(), 4); + +} + +void tst_QDoubleSpinBox::removeAll() +{ + DoubleSpinBox spin(0); + spin.setPrefix("foo"); + spin.setSuffix("bar"); + spin.setValue(0.2); + spin.setDecimals(1); + spin.show(); +#ifdef Q_WS_MAC + QTest::keyClick(&spin, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(&spin, Qt::Key_Home); +#endif + +#ifdef Q_WS_MAC + QTest::keyClick(&spin, Qt::Key_Right, Qt::ControlModifier|Qt::ShiftModifier); +#else + QTest::keyClick(&spin, Qt::Key_End, Qt::ShiftModifier); +#endif + + QCOMPARE(spin.lineEdit()->selectedText(), QString("foo0.2bar")); + QTest::keyClick(&spin, Qt::Key_1); + QCOMPARE(spin.text(), QString("foo1bar")); +} + +void tst_QDoubleSpinBox::task54433() +{ + DoubleSpinBox priceSpinBox; + priceSpinBox.show(); + priceSpinBox.setRange(0.0, 999.99); + priceSpinBox.setDecimals(2); + priceSpinBox.setValue(999.99); + QCOMPARE(priceSpinBox.text(), QString("999.99")); + QCOMPARE(priceSpinBox.value(), 999.99); + QCOMPARE(priceSpinBox.maximum(), 999.99); + priceSpinBox.setDecimals(1); + QCOMPARE(priceSpinBox.value(), 1000.0); + QCOMPARE(priceSpinBox.maximum(), 1000.0); + QCOMPARE(priceSpinBox.text(), QString("1000.0")); + + priceSpinBox.setDecimals(2); + priceSpinBox.setRange(-999.99, 0.0); + priceSpinBox.setValue(-999.99); + QCOMPARE(priceSpinBox.text(), QString("-999.99")); + QCOMPARE(priceSpinBox.value(), -999.99); + QCOMPARE(priceSpinBox.minimum(), -999.99); + priceSpinBox.setDecimals(1); + QCOMPARE(priceSpinBox.value(), -1000.0); + QCOMPARE(priceSpinBox.minimum(), -1000.0); + QCOMPARE(priceSpinBox.text(), QString("-1000.0")); +} + + + +void tst_QDoubleSpinBox::germanTest() +{ + QLocale::setDefault(QLocale(QLocale::German)); + DoubleSpinBox spin; + spin.show(); + spin.setValue(2.12); +#ifdef Q_WS_MAC + QTest::keyClick(&spin, Qt::Key_Right, Qt::ControlModifier); +#else + QTest::keyClick(&spin, Qt::Key_End); +#endif + QTest::keyClick(&spin, Qt::Key_Backspace); + QCOMPARE(spin.text(), QString("2,1")); + QTest::keyClick(&spin, Qt::Key_Enter); + QCOMPARE(spin.text(), QString("2,10")); +} + +void tst_QDoubleSpinBox::doubleDot() +{ + DoubleSpinBox spin; + spin.show(); + spin.setValue(2.12); + QTest::keyClick(&spin, Qt::Key_Backspace); + QCOMPARE(spin.text(), QString("2.12")); +#ifdef Q_WS_MAC + QTest::keyClick(&spin, Qt::Key_Left, Qt::ControlModifier); +#else + QTest::keyClick(&spin, Qt::Key_Home); +#endif + QTest::keyClick(&spin, Qt::Key_Right, Qt::ShiftModifier); + QCOMPARE(spin.lineEdit()->selectedText(), QString("2")); + QTest::keyClick(&spin, Qt::Key_1); + QCOMPARE(spin.text(), QString("1.12")); + QCOMPARE(spin.lineEdit()->cursorPosition(), 1); + QTest::keyClick(&spin, Qt::Key_Period); + QCOMPARE(spin.text(), QString("1.12")); + QCOMPARE(spin.lineEdit()->cursorPosition(), 2); +} + +void tst_QDoubleSpinBox::undoRedo() +{ + //test undo/redo feature (in conjunction with the "undoRedoEnabled" property) + DoubleSpinBox spin(0); + spin.show(); + + //the undo/redo is disabled by default + + QCOMPARE(spin.value(), 0.0); //this is the default value + QVERIFY(!spin.lineEdit()->isUndoAvailable()); + QVERIFY(!spin.lineEdit()->isRedoAvailable()); + + spin.lineEdit()->selectAll(); //ensures everything is selected and will be cleared by typing a key + QTest::keyClick(&spin, Qt::Key_1); //we put 1 into the spinbox + QCOMPARE(spin.value(), 1.0); + QVERIFY(spin.lineEdit()->isUndoAvailable()); + + //testing CTRL+Z (undo) + int val = QKeySequence(QKeySequence::Undo)[0]; + if (val != 0) { + Qt::KeyboardModifiers mods = (Qt::KeyboardModifiers)(val & Qt::KeyboardModifierMask); + QTest::keyClick(&spin, val & ~mods, mods); + QCOMPARE(spin.value(), 0.0); + QVERIFY(!spin.lineEdit()->isUndoAvailable()); + QVERIFY(spin.lineEdit()->isRedoAvailable()); + } else { + QWARN("Undo not tested because no key sequence associated to QKeySequence::Redo"); + } + + + //testing CTRL+Y (redo) + val = QKeySequence(QKeySequence::Redo)[0]; + if (val != 0) { + Qt::KeyboardModifiers mods = (Qt::KeyboardModifiers)(val & Qt::KeyboardModifierMask); + QTest::keyClick(&spin, val & ~mods, mods); + QCOMPARE(spin.value(), 1.0); + QVERIFY(!spin.lineEdit()->isRedoAvailable()); + QVERIFY(spin.lineEdit()->isUndoAvailable()); + } else { + QWARN("Redo not tested because no key sequence associated to QKeySequence::Redo"); + } + + + spin.setValue(55.0); + QVERIFY(!spin.lineEdit()->isUndoAvailable()); + QVERIFY(!spin.lineEdit()->isRedoAvailable()); +} + +struct task199226_DoubleSpinBox : public QDoubleSpinBox +{ + task199226_DoubleSpinBox(QWidget *parent = 0) : QDoubleSpinBox(parent) {} + QLineEdit *lineEdit() { return QAbstractSpinBox::lineEdit(); } +}; + +void tst_QDoubleSpinBox::task199226_stateAfterEnter() +{ + task199226_DoubleSpinBox spin; + spin.setMinimum(0); + spin.setMaximum(10); + spin.setDecimals(0); + spin.show(); + QTest::mouseDClick(spin.lineEdit(), Qt::LeftButton); + QTest::keyClick(spin.lineEdit(), Qt::Key_3); + QVERIFY(spin.lineEdit()->isModified()); + QVERIFY(spin.lineEdit()->isUndoAvailable()); + QTest::keyClick(spin.lineEdit(), Qt::Key_Enter); + QVERIFY(!spin.lineEdit()->isModified()); + QVERIFY(!spin.lineEdit()->isUndoAvailable()); +} + +class task224497_fltMax_DoubleSpinBox : public QDoubleSpinBox +{ +public: + QLineEdit * lineEdit () const { return QDoubleSpinBox::lineEdit(); } +}; + +void tst_QDoubleSpinBox::task224497_fltMax() +{ + task224497_fltMax_DoubleSpinBox *dspin = new task224497_fltMax_DoubleSpinBox; + dspin->setMinimum(3); + dspin->setMaximum(FLT_MAX); + dspin->show(); + QTest::qWait(1000); + dspin->lineEdit()->selectAll(); + QTest::keyClick(dspin->lineEdit(), Qt::Key_Delete); + QTest::keyClick(dspin->lineEdit(), Qt::Key_1); + QCOMPARE(dspin->cleanText(), QLatin1String("1")); +} + +void tst_QDoubleSpinBox::task221221() +{ + QDoubleSpinBox spin; + QTest::keyClick(&spin, Qt::Key_1); + QCOMPARE(spin.text(), QLatin1String("1")); + spin.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&spin); +#endif + QVERIFY(spin.isVisible()); + QCOMPARE(spin.text(), QLatin1String("1")); +} + +void tst_QDoubleSpinBox::task255471_decimalsValidation() +{ + // QDoubleSpinBox shouldn't crash with large numbers of decimals. Even if + // the results are useless ;-) + for (int i = 0; i < 32; ++i) + { + QDoubleSpinBox spinBox; + spinBox.setDecimals(i); + spinBox.setMinimum(0.3); + spinBox.setMaximum(12); + + spinBox.show(); + QTRY_VERIFY(spinBox.isVisible()); + spinBox.setFocus(); + QTRY_VERIFY(spinBox.hasFocus()); + + QTest::keyPress(&spinBox, Qt::Key_Right); + QTest::keyPress(&spinBox, Qt::Key_Right); + QTest::keyPress(&spinBox, Qt::Key_Delete); + + // Don't crash! + QTest::keyPress(&spinBox, Qt::Key_2); + } +} + +void tst_QDoubleSpinBox::taskQTBUG_5008_textFromValueAndValidate() +{ + class DecoratedSpinBox : public QDoubleSpinBox + { + public: + DecoratedSpinBox() + { + setLocale(QLocale::French); + setMaximum(100000000); + setValue(1000); + } + + QLineEdit *lineEdit() const + { + return QDoubleSpinBox::lineEdit(); + } + + //we use the French delimiters here + QString textFromValue (double value) const + { + return locale().toString(value); + } + } spinbox; + spinbox.show(); + spinbox.activateWindow(); + spinbox.setFocus(); + QApplication::setActiveWindow(&spinbox); + QTest::qWaitForWindowShown(&spinbox); + QTRY_VERIFY(spinbox.hasFocus()); + QTRY_COMPARE(static_cast<QWidget *>(&spinbox), QApplication::activeWindow()); + QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value())); + spinbox.lineEdit()->setCursorPosition(2); //just after the first thousand separator + QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_0); // let's insert a 0 + QCOMPARE(spinbox.value(), 10000.); + spinbox.clearFocus(); //make sure the value is correctly formatted + QCOMPARE(spinbox.text(), spinbox.locale().toString(spinbox.value())); +} + +void tst_QDoubleSpinBox::taskQTBUG_6670_selectAllWithPrefix() +{ + DoubleSpinBox spin; + spin.setPrefix("$ "); + spin.lineEdit()->selectAll(); + QTest::keyClick(spin.lineEdit(), Qt::Key_1); + QCOMPARE(spin.value(), 1.); + QTest::keyClick(spin.lineEdit(), Qt::Key_2); + QCOMPARE(spin.value(), 12.); +} + +void tst_QDoubleSpinBox::taskQTBUG_6496_fiddlingWithPrecision() +{ + QDoubleSpinBox dsb; + dsb.setRange(0, 0.991); + dsb.setDecimals(1); + QCOMPARE(dsb.maximum(), 1.0); + dsb.setDecimals(2); + QCOMPARE(dsb.maximum(), 0.99); + dsb.setDecimals(3); + QCOMPARE(dsb.maximum(), 0.991); +} + +QTEST_MAIN(tst_QDoubleSpinBox) +#include "tst_qdoublespinbox.moc" diff --git a/tests/auto/widgets/widgets/qdoublevalidator/.gitignore b/tests/auto/widgets/widgets/qdoublevalidator/.gitignore new file mode 100644 index 0000000000..95c97bbc30 --- /dev/null +++ b/tests/auto/widgets/widgets/qdoublevalidator/.gitignore @@ -0,0 +1 @@ +tst_qdoublevalidator diff --git a/tests/auto/widgets/widgets/qdoublevalidator/qdoublevalidator.pro b/tests/auto/widgets/widgets/qdoublevalidator/qdoublevalidator.pro new file mode 100644 index 0000000000..7fbb72bb7f --- /dev/null +++ b/tests/auto/widgets/widgets/qdoublevalidator/qdoublevalidator.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qdoublevalidator.cpp + + diff --git a/tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp new file mode 100644 index 0000000000..6014ce5165 --- /dev/null +++ b/tests/auto/widgets/widgets/qdoublevalidator/tst_qdoublevalidator.cpp @@ -0,0 +1,387 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + + +#include <qvalidator.h> + +class tst_QDoubleValidator : public QObject +{ + Q_OBJECT +private slots: + void validate_data(); + void validate(); + void validateThouSep_data(); + void validateThouSep(); + void validateIntEquiv_data(); + void validateIntEquiv(); + void notifySignals(); +}; + +Q_DECLARE_METATYPE(QValidator::State); +#define INV QValidator::Invalid +#define ITM QValidator::Intermediate +#define ACC QValidator::Acceptable + +void tst_QDoubleValidator::validateThouSep_data() +{ + QTest::addColumn<QString>("localeName"); + QTest::addColumn<QString>("value"); + QTest::addColumn<QValidator::State>("result"); + + QTest::newRow("1,000C") << "C" << QString("1,000") << ACC; + QTest::newRow("1.000C") << "C" << QString("1.000") << ACC; + + QTest::newRow("1,000de") << "de" << QString("1,000") << ACC; + QTest::newRow("1.000de") << "de" << QString("1.000") << ACC; + + QTest::newRow(".C") << "C" << QString(".") << ITM; + QTest::newRow(".de") << "de" << QString(".") << ITM; + QTest::newRow(",C") << "C" << QString(",") << INV; + QTest::newRow(",de") << "de" << QString(",") << ITM; +} + +void tst_QDoubleValidator::validateThouSep() +{ + QFETCH(QString, localeName); + QFETCH(QString, value); + QFETCH(QValidator::State, result); + int dummy = 0; + + QDoubleValidator iv(-10000, 10000, 3, 0); + iv.setNotation(QDoubleValidator::ScientificNotation); + iv.setLocale(QLocale(localeName)); + + QCOMPARE(iv.validate(value, dummy), result); +} + +void tst_QDoubleValidator::validate_data() +{ + QTest::addColumn<QString>("localeName"); + QTest::addColumn<double>("minimum"); + QTest::addColumn<double>("maximum"); + QTest::addColumn<int>("decimals"); + QTest::addColumn<QString>("value"); + QTest::addColumn<QValidator::State>("scientific_state"); + QTest::addColumn<QValidator::State>("standard_state"); + + QTest::newRow("data0") << "C" << 0.0 << 100.0 << 1 << QString("50.0") << ACC << ACC; + QTest::newRow("data1") << "C" << 00.0 << 100.0 << 1 << QString("500.0") << ITM << ITM; + QTest::newRow("data1a") << "C" << 00.0 << 100.0 << 1 << QString("5001.0") << ITM << INV; + QTest::newRow("data2") << "C" << 00.0 << 100.0 << 1 << QString("-35.0") << INV << INV; + QTest::newRow("data3") << "C" << 00.0 << 100.0 << 1 << QString("a") << INV << INV; + QTest::newRow("data4") << "C" << 0.0 << 100.0 << 1 << QString("-") << INV << INV; + QTest::newRow("data5") << "C" << 0.0 << 100.0 << 1 << QString("100.0") << ACC << ACC; + QTest::newRow("data6") << "C" << -100.0 << 100.0 << 1 << QString("-") << ITM << ITM; + QTest::newRow("data7") << "C" << -100.0 << 100.0 << 1 << QString("-500.0") << ITM << ITM; + QTest::newRow("data8") << "C" << -100.0 << 100.0 << 1 << QString("-100") << ACC << ACC; + QTest::newRow("data9") << "C" << -100.0 << -10.0 << 1 << QString("10") << ITM << ITM; + QTest::newRow("data10") << "C" << 0.3 << 0.5 << 5 << QString("0.34567") << ACC << ACC; + QTest::newRow("data11") << "C" << -0.3 << -0.5 << 5 << QString("-0.345678") << INV << INV; + QTest::newRow("data12") << "C" << -0.32 << 0.32 << 1 << QString("0") << ACC << ACC; + QTest::newRow("data13") << "C" << 0.0 << 100.0 << 1 << QString("3456a") << INV << INV; + QTest::newRow("data14") << "C" << -100.0 << 100.0 << 1 << QString("-3456a") << INV << INV; + QTest::newRow("data15") << "C" << -100.0 << 100.0 << 1 << QString("a-3456") << INV << INV; + QTest::newRow("data16") << "C" << -100.0 << 100.0 << 1 << QString("a-3456a") << INV << INV; + QTest::newRow("data17") << "C" << 1229.0 << 1231.0 << 0 << QString("123e") << ITM << INV; + QTest::newRow("data18") << "C" << 1229.0 << 1231.0 << 0 << QString("123e+") << ITM << INV; + QTest::newRow("data19") << "C" << 1229.0 << 1231.0 << 0 << QString("123e+1") << ACC << INV; + QTest::newRow("data20") << "C" << 12290.0 << 12310.0 << 0 << QString("123e+2") << ACC << INV; + QTest::newRow("data21") << "C" << 12.290 << 12.310 << 2 << QString("123e-") << ITM << INV; + QTest::newRow("data22") << "C" << 12.290 << 12.310 << 2 << QString("123e-1") << ACC << INV; + QTest::newRow("data23") << "C" << 1.2290 << 1.2310 << 3 << QString("123e-2") << ACC << INV; + QTest::newRow("data24") << "C" << 1229.0 << 1231.0 << 0 << QString("123E") << ITM << INV; + QTest::newRow("data25") << "C" << 1229.0 << 1231.0 << 0 << QString("123E+") << ITM << INV; + QTest::newRow("data26") << "C" << 1229.0 << 1231.0 << 0 << QString("123E+1") << ACC << INV; + QTest::newRow("data27") << "C" << 12290.0 << 12310.0 << 0 << QString("123E+2") << ACC << INV; + QTest::newRow("data28") << "C" << 12.290 << 12.310 << 2 << QString("123E-") << ITM << INV; + QTest::newRow("data29") << "C" << 12.290 << 12.310 << 2 << QString("123E-1") << ACC << INV; + QTest::newRow("data30") << "C" << 1.2290 << 1.2310 << 3 << QString("123E-2") << ACC << INV; + QTest::newRow("data31") << "C" << 1.2290 << 1.2310 << 3 << QString("e") << ITM << INV; + QTest::newRow("data32") << "C" << 1.2290 << 1.2310 << 3 << QString("e+") << ITM << INV; + QTest::newRow("data33") << "C" << 1.2290 << 1.2310 << 3 << QString("e+1") << ITM << INV; + QTest::newRow("data34") << "C" << 1.2290 << 1.2310 << 3 << QString("e-") << ITM << INV; + QTest::newRow("data35") << "C" << 1.2290 << 1.2310 << 3 << QString("e-1") << ITM << INV; + QTest::newRow("data36") << "C" << 1.2290 << 1.2310 << 3 << QString("E") << ITM << INV; + QTest::newRow("data37") << "C" << 1.2290 << 1.2310 << 3 << QString("E+") << ITM << INV; + QTest::newRow("data38") << "C" << 1.2290 << 1.2310 << 3 << QString("E+1") << ITM << INV; + QTest::newRow("data39") << "C" << 1.2290 << 1.2310 << 3 << QString("E-") << ITM << INV; + QTest::newRow("data40") << "C" << 1.2290 << 1.2310 << 3 << QString("E-1") << ITM << INV; + QTest::newRow("data41") << "C" << -100.0 << 100.0 << 0 << QString("10e") << ITM << INV; + QTest::newRow("data42") << "C" << -100.0 << 100.0 << 0 << QString("10e+") << ITM << INV; + QTest::newRow("data43") << "C" << 0.01 << 0.09 << 2 << QString("0") << ITM << ITM; + QTest::newRow("data44") << "C" << 0.0 << 10.0 << 1 << QString("11") << ITM << ITM; + QTest::newRow("data45") << "C" << 0.0 << 10.0 << 2 << QString("11") << ITM << ITM; + QTest::newRow("data46") << "C" << 0.0 << 100.0 << 0 << QString("0.") << ACC << ACC; + QTest::newRow("data47") << "C" << 0.0 << 100.0 << 0 << QString("0.0") << INV << INV; + QTest::newRow("data48") << "C" << 0.0 << 100.0 << 1 << QString("0.0") << ACC << ACC; + QTest::newRow("data49") << "C" << 0.0 << 100.0 << 0 << QString(".") << ITM << ITM; + QTest::newRow("data50") << "C" << 0.0 << 100.0 << 1 << QString(".") << ITM << ITM; + + QTest::newRow("data_de0") << "de" << 0.0 << 100.0 << 1 << QString("50,0") << ACC << ACC; + QTest::newRow("data_de1") << "de" << 00.0 << 100.0 << 1 << QString("500,0") << ITM << ITM; + QTest::newRow("data_de1a") << "de" << 00.0 << 100.0 << 1 << QString("5001,0") << ITM << INV; + QTest::newRow("data_de0C") << "de" << 0.0 << 100.0 << 1 << QString("50,0") << ACC << ACC; + QTest::newRow("data_de1C") << "de" << 00.0 << 100.0 << 1 << QString("500,0") << ITM << ITM; + QTest::newRow("data_de1aC") << "de" << 00.0 << 100.0 << 1 << QString("5001,0") << ITM << INV; + QTest::newRow("data_de2") << "de" << 00.0 << 100.0 << 1 << QString("-35,0") << INV << INV; + QTest::newRow("data_de3") << "de" << 00.0 << 100.0 << 1 << QString("a") << INV << INV; + QTest::newRow("data_de4") << "de" << 0.0 << 100.0 << 1 << QString("-") << INV << INV; + QTest::newRow("data_de5") << "de" << 0.0 << 100.0 << 1 << QString("100,0") << ACC << ACC; + QTest::newRow("data_de6") << "de" << -100.0 << 100.0 << 1 << QString("-") << ITM << ITM; + QTest::newRow("data_de7") << "de" << -100.0 << 100.0 << 1 << QString("-500,0") << ITM << ITM; + QTest::newRow("data_de8") << "de" << -100.0 << 100.0 << 1 << QString("-100") << ACC << ACC; + QTest::newRow("data_de9") << "de" << -100.0 << -10.0 << 1 << QString("10") << ITM << ITM; + QTest::newRow("data_de10") << "de" << 0.3 << 0.5 << 5 << QString("0,34567") << ACC << ACC; + QTest::newRow("data_de11") << "de" << -0.3 << -0.5 << 5 << QString("-0,345678") << ITM << INV; + QTest::newRow("data_de12") << "de" << -0.32 << 0.32 << 1 << QString("0") << ACC << ACC; + QTest::newRow("data_de13") << "de" << 0.0 << 100.0 << 1 << QString("3456a") << INV << INV; + QTest::newRow("data_de14") << "de" << -100.0 << 100.0 << 1 << QString("-3456a") << INV << INV; + QTest::newRow("data_de15") << "de" << -100.0 << 100.0 << 1 << QString("a-3456") << INV << INV; + QTest::newRow("data_de16") << "de" << -100.0 << 100.0 << 1 << QString("a-3456a") << INV << INV; + QTest::newRow("data_de17") << "de" << 1229.0 << 1231.0 << 0 << QString("123e") << ITM << INV; + QTest::newRow("data_de18") << "de" << 1229.0 << 1231.0 << 0 << QString("123e+") << ITM << INV; + QTest::newRow("data_de19") << "de" << 1229.0 << 1231.0 << 0 << QString("123e+1") << ACC << INV; + QTest::newRow("data_de20") << "de" << 12290.0 << 12310.0 << 0 << QString("123e+2") << ACC << INV; + QTest::newRow("data_de21") << "de" << 12.290 << 12.310 << 2 << QString("123e-") << ITM << INV; + QTest::newRow("data_de22") << "de" << 12.290 << 12.310 << 2 << QString("123e-1") << ACC << INV; + QTest::newRow("data_de23") << "de" << 1.2290 << 1.2310 << 3 << QString("123e-2") << ACC << INV; + QTest::newRow("data_de24") << "de" << 1229.0 << 1231.0 << 0 << QString("123E") << ITM << INV; + QTest::newRow("data_de25") << "de" << 1229.0 << 1231.0 << 0 << QString("123E+") << ITM << INV; + QTest::newRow("data_de26") << "de" << 1229.0 << 1231.0 << 0 << QString("123E+1") << ACC << INV; + QTest::newRow("data_de27") << "de" << 12290.0 << 12310.0 << 0 << QString("123E+2") << ACC << INV; + QTest::newRow("data_de28") << "de" << 12.290 << 12.310 << 2 << QString("123E-") << ITM << INV; + QTest::newRow("data_de29") << "de" << 12.290 << 12.310 << 2 << QString("123E-1") << ACC << INV; + QTest::newRow("data_de30") << "de" << 1.2290 << 1.2310 << 3 << QString("123E-2") << ACC << INV; + QTest::newRow("data_de31") << "de" << 1.2290 << 1.2310 << 3 << QString("e") << ITM << INV; + QTest::newRow("data_de32") << "de" << 1.2290 << 1.2310 << 3 << QString("e+") << ITM << INV; + QTest::newRow("data_de33") << "de" << 1.2290 << 1.2310 << 3 << QString("e+1") << ITM << INV; + QTest::newRow("data_de34") << "de" << 1.2290 << 1.2310 << 3 << QString("e-") << ITM << INV; + QTest::newRow("data_de35") << "de" << 1.2290 << 1.2310 << 3 << QString("e-1") << ITM << INV; + QTest::newRow("data_de36") << "de" << 1.2290 << 1.2310 << 3 << QString("E") << ITM << INV; + QTest::newRow("data_de37") << "de" << 1.2290 << 1.2310 << 3 << QString("E+") << ITM << INV; + QTest::newRow("data_de38") << "de" << 1.2290 << 1.2310 << 3 << QString("E+1") << ITM << INV; + QTest::newRow("data_de39") << "de" << 1.2290 << 1.2310 << 3 << QString("E-") << ITM << INV; + QTest::newRow("data_de40") << "de" << 1.2290 << 1.2310 << 3 << QString("E-1") << ITM << INV; + QTest::newRow("data_de41") << "de" << -100.0 << 100.0 << 0 << QString("10e") << ITM << INV; + QTest::newRow("data_de42") << "de" << -100.0 << 100.0 << 0 << QString("10e+") << ITM << INV; + QTest::newRow("data_de43") << "de" << 0.01 << 0.09 << 2 << QString("0") << ITM << ITM; + QTest::newRow("data_de44") << "de" << 0.0 << 10.0 << 1 << QString("11") << ITM << ITM; + QTest::newRow("data_de45") << "de" << 0.0 << 10.0 << 2 << QString("11") << ITM << ITM; + + QString arabicNum; + arabicNum += QChar(1633); // "18.4" in arabic + arabicNum += QChar(1640); + arabicNum += QChar(1643); + arabicNum += QChar(1636); + QTest::newRow("arabic") << "ar" << 0.0 << 20.0 << 2 << arabicNum << ACC << ACC; + + QTest::newRow("data_QTBUG_14935-1") << "de" << 0.0 << 1.0 << 5 << QString("0.31") << ACC << ACC; + QTest::newRow("data_QTBUG_14935-2") << "de" << 0.0 << 1000000.0 << 5 << QString("3.123") << ACC << ACC; + QTest::newRow("data_QTBUG_14935-3") << "de" << 0.0 << 1000000.0 << 5 << QString("123,345.678") << ACC << ACC; + + QTest::newRow("data_de_problem-1") << "de" << 0.0 << 10.0 << 0 << QString("1.0") << ITM << ITM; + QTest::newRow("data_de_problem-2") << "de" << 0.0 << 10.0 << 0 << QString("0.1") << INV << INV; +} + +void tst_QDoubleValidator::validate() +{ + QFETCH(QString, localeName); + QFETCH(double, minimum); + QFETCH(double, maximum); + QFETCH(int, decimals); + QFETCH(QString, value); + QFETCH(QValidator::State, scientific_state); + QFETCH(QValidator::State, standard_state); + + QEXPECT_FAIL("data_de_problem-1", "To be fixed. See QTBUG-15210.", Abort); + QEXPECT_FAIL("data_de_problem-2", "To be fixed. See QTBUG-15210.", Abort); + + QLocale::setDefault(QLocale(localeName)); + + QDoubleValidator dv(minimum, maximum, decimals, 0); + int dummy; + QCOMPARE((int)dv.validate(value, dummy), (int)scientific_state); + dv.setNotation(QDoubleValidator::StandardNotation); + QCOMPARE((int)dv.validate(value, dummy), (int)standard_state); +} +void tst_QDoubleValidator::notifySignals() +{ + QDoubleValidator dv(0.1, 0.9, 10, 0); + QSignalSpy topSpy(&dv, SIGNAL(topChanged(double))); + QSignalSpy bottomSpy(&dv, SIGNAL(bottomChanged(double))); + QSignalSpy decSpy(&dv, SIGNAL(decimalsChanged(int))); + + qRegisterMetaType<QDoubleValidator::Notation>("QDoubleValidator::Notation"); + QSignalSpy notSpy(&dv, SIGNAL(notationChanged(QDoubleValidator::Notation))); + + dv.setTop(0.8); + QCOMPARE(topSpy.count(), 1); + QVERIFY(dv.top() == 0.8); + dv.setBottom(0.2); + QCOMPARE(bottomSpy.count(), 1); + QVERIFY(dv.bottom() == 0.2); + + dv.setRange(0.2, 0.7); + QCOMPARE(topSpy.count(), 2); + QCOMPARE(bottomSpy.count(), 1); + QCOMPARE(decSpy.count(), 1); + QVERIFY(dv.bottom() == 0.2); + QVERIFY(dv.top() == 0.7); + QVERIFY(dv.decimals() == 0.); + + dv.setRange(0.3, 0.7); + QCOMPARE(topSpy.count(), 2); + QCOMPARE(bottomSpy.count(), 2); + QVERIFY(dv.bottom() == 0.3); + QVERIFY(dv.top() == 0.7); + QVERIFY(dv.decimals() == 0.); + + dv.setRange(0.4, 0.6); + QCOMPARE(topSpy.count(), 3); + QCOMPARE(bottomSpy.count(), 3); + QVERIFY(dv.bottom() == 0.4); + QVERIFY(dv.top() == 0.6); + QVERIFY(dv.decimals() == 0.); + + dv.setDecimals(10); + QCOMPARE(decSpy.count(), 2); + QVERIFY(dv.decimals() == 10.); + + + dv.setRange(0.4, 0.6, 100); + QCOMPARE(topSpy.count(), 3); + QCOMPARE(bottomSpy.count(), 3); + QCOMPARE(decSpy.count(), 3); + QVERIFY(dv.bottom() == 0.4); + QVERIFY(dv.top() == 0.6); + QVERIFY(dv.decimals() == 100.); + + dv.setNotation(QDoubleValidator::StandardNotation); + QCOMPARE(notSpy.count(), 1); + QVERIFY(dv.notation() == QDoubleValidator::StandardNotation); +} + +void tst_QDoubleValidator::validateIntEquiv_data() +{ + QTest::addColumn<double>("minimum"); + QTest::addColumn<double>("maximum"); + QTest::addColumn<QString>("input"); + QTest::addColumn<QValidator::State>("state"); + + QTest::newRow("1.1") << 0.0 << 10.0 << QString("") << ITM; + QTest::newRow("1.2") << 10.0 << 0.0 << QString("") << ITM; + + QTest::newRow("2.1") << 0.0 << 10.0 << QString("-") << INV; + QTest::newRow("2.2") << 0.0 << 10.0 << QString("-0") << INV; + QTest::newRow("2.3") << -10.0 << -1.0 << QString("+") << INV; + QTest::newRow("2.4") << -10.0 << 10.0 << QString("-") << ITM; + QTest::newRow("2.5") << -10.0 << 10.0 << QString("+") << ITM; + QTest::newRow("2.5a") << -10.0 << -9.0 << QString("+") << INV; + QTest::newRow("2.6") << -10.0 << 10.0 << QString("+0") << ACC; + QTest::newRow("2.7") << -10.0 << 10.0 << QString("+1") << ACC; + QTest::newRow("2.8") << -10.0 << 10.0 << QString("+-") << INV; + QTest::newRow("2.9") << -10.0 << 10.0 << QString("-+") << INV; + + QTest::newRow("3.1") << 0.0 << 10.0 << QString("12345678901234567890") << INV; + QTest::newRow("3.2") << 0.0 << 10.0 << QString("-12345678901234567890") << INV; + QTest::newRow("3.3") << 0.0 << 10.0 << QString("000000000000000000000") << ACC; + QTest::newRow("3.4") << 1.0 << 10.0 << QString("000000000000000000000") << ITM; + QTest::newRow("3.5") << 0.0 << 10.0 << QString("-000000000000000000000") << INV; + QTest::newRow("3.6") << -10.0 << -1.0 << QString("-000000000000000000000") << ITM; + QTest::newRow("3.7") << -10.0 << -1.0 << QString("-0000000000000000000001") << ACC; + + QTest::newRow("4.1") << 0.0 << 10.0 << QString(" ") << INV; + QTest::newRow("4.2") << 0.0 << 10.0 << QString(" 1") << INV; + QTest::newRow("4.3") << 0.0 << 10.0 << QString("1 ") << INV; + QTest::newRow("4.4") << 0.0 << 10.0 << QString("1.0") << INV; + QTest::newRow("4.5") << 0.0 << 10.0 << QString("0.1") << INV; + QTest::newRow("4.6") << 0.0 << 10.0 << QString(".1") << INV; + QTest::newRow("4.7") << 0.0 << 10.0 << QString("-1.0") << INV; + + QTest::newRow("5.1") << 6.0 << 8.0 << QString("5") << ITM; + QTest::newRow("5.1") << 6.0 << 8.0 << QString("56") << INV; + QTest::newRow("5.2") << 6.0 << 8.0 << QString("7") << ACC; + QTest::newRow("5.3") << 6.0 << 8.0 << QString("9") << ITM; + QTest::newRow("5.3") << 6.0 << 8.0 << QString("-") << INV; + QTest::newRow("5.4a") << -8.0 << -6.0 << QString("+") << INV; + QTest::newRow("5.4b") << -8.0 << -6.0 << QString("+5") << INV; + QTest::newRow("5.4c") << -8.0 << -6.0 << QString("-5") << ITM; + QTest::newRow("5.5") << -8.0 << -6.0 << QString("-7") << ACC; + QTest::newRow("5.6") << -8.0 << -6.0 << QString("-9") << ITM; + QTest::newRow("5.7") << -8.0 << -6.0 << QString("5") << ITM; + QTest::newRow("5.8") << -8.0 << -6.0 << QString("7") << ITM; + QTest::newRow("5.9") << -8.0 << -6.0 << QString("9") << ITM; + QTest::newRow("5.10") << -6.0 << 8.0 << QString("-5") << ACC; + QTest::newRow("5.11") << -6.0 << 8.0 << QString("5") << ACC; + QTest::newRow("5.12") << -6.0 << 8.0 << QString("-7") << ITM; + QTest::newRow("5.13") << -6.0 << 8.0 << QString("7") << ACC; + QTest::newRow("5.14") << -6.0 << 8.0 << QString("-9") << ITM; + QTest::newRow("5.15") << -6.0 << 8.0 << QString("9") << ITM; + + QTest::newRow("6.1") << 100.0 << 102.0 << QString("11") << ITM; + QTest::newRow("6.2") << 100.0 << 102.0 << QString("-11") << INV; + + QTest::newRow("7.1") << 0.0 << 10.0 << QString("100") << INV; + QTest::newRow("7.2") << 0.0 << -10.0 << QString("100") << INV; + QTest::newRow("7.3") << 0.0 << -10.0 << QString("-100") << INV; + QTest::newRow("7.4") << -100.0 << 10.0 << QString("100") << ITM; +} + +void tst_QDoubleValidator::validateIntEquiv() +{ + QFETCH(double, minimum); + QFETCH(double, maximum); + QFETCH(QString, input); + QFETCH(QValidator::State, state); + + QLocale::setDefault(QLocale("C")); + + QDoubleValidator dv(minimum, maximum, 0, 0); + dv.setNotation(QDoubleValidator::StandardNotation); + int dummy; + QCOMPARE(dv.validate(input, dummy), state); +} + +QTEST_APPLESS_MAIN(tst_QDoubleValidator) +#include "tst_qdoublevalidator.moc" diff --git a/tests/auto/widgets/widgets/qfocusframe/.gitignore b/tests/auto/widgets/widgets/qfocusframe/.gitignore new file mode 100644 index 0000000000..7a6e000227 --- /dev/null +++ b/tests/auto/widgets/widgets/qfocusframe/.gitignore @@ -0,0 +1 @@ +tst_qfocusframe diff --git a/tests/auto/widgets/widgets/qfocusframe/qfocusframe.pro b/tests/auto/widgets/widgets/qfocusframe/qfocusframe.pro new file mode 100644 index 0000000000..0fcc9bf23d --- /dev/null +++ b/tests/auto/widgets/widgets/qfocusframe/qfocusframe.pro @@ -0,0 +1,9 @@ +############################################################ +# Project file for autotest for file qfocusframe.h +############################################################ + +load(qttest_p4) +QT += widgets +SOURCES += tst_qfocusframe.cpp + + diff --git a/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp b/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp new file mode 100644 index 0000000000..1658cf3fe5 --- /dev/null +++ b/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <qcoreapplication.h> +#include <qdebug.h> +#include <qfocusframe.h> + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QFocusFrame : public QObject +{ +Q_OBJECT + +public: + tst_QFocusFrame(); + virtual ~tst_QFocusFrame(); + +private slots: + void getSetCheck(); +}; + +tst_QFocusFrame::tst_QFocusFrame() +{ +} + +tst_QFocusFrame::~tst_QFocusFrame() +{ +} + +// Testing get/set functions +void tst_QFocusFrame::getSetCheck() +{ + QFocusFrame *obj1 = new QFocusFrame(); + // QWidget * QFocusFrame::widget() + // void QFocusFrame::setWidget(QWidget *) + QWidget var1; + QWidget *var2 = new QWidget(&var1); + obj1->setWidget(var2); + QCOMPARE(var2, obj1->widget()); + obj1->setWidget((QWidget *)0); + QCOMPARE((QWidget *)0, obj1->widget()); + delete obj1; +} + +QTEST_MAIN(tst_QFocusFrame) +#include "tst_qfocusframe.moc" diff --git a/tests/auto/widgets/widgets/qfontcombobox/.gitignore b/tests/auto/widgets/widgets/qfontcombobox/.gitignore new file mode 100644 index 0000000000..acc19de07e --- /dev/null +++ b/tests/auto/widgets/widgets/qfontcombobox/.gitignore @@ -0,0 +1 @@ +tst_qfontcombobox diff --git a/tests/auto/widgets/widgets/qfontcombobox/qfontcombobox.pro b/tests/auto/widgets/widgets/qfontcombobox/qfontcombobox.pro new file mode 100644 index 0000000000..7faa0e36bd --- /dev/null +++ b/tests/auto/widgets/widgets/qfontcombobox/qfontcombobox.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qfontcombobox.cpp + +CONFIG += insignificant_test # QTBUG-21402 diff --git a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp new file mode 100644 index 0000000000..72b3dfe8ca --- /dev/null +++ b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp @@ -0,0 +1,303 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <qfontcombobox.h> + +class tst_QFontComboBox : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void qfontcombobox_data(); + void qfontcombobox(); + void currentFont_data(); + void currentFont(); + void fontFilters_data(); + void fontFilters(); + void sizeHint(); + void writingSystem_data(); + void writingSystem(); + void currentFontChanged(); +}; + +// Subclass that exposes the protected functions. +class SubQFontComboBox : public QFontComboBox +{ +public: + void call_currentFontChanged(QFont const& f) + { return SubQFontComboBox::currentFontChanged(f); } + + bool call_event(QEvent* e) + { return SubQFontComboBox::event(e); } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_QFontComboBox::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_QFontComboBox::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_QFontComboBox::init() +{ +} + +// This will be called after every test function. +void tst_QFontComboBox::cleanup() +{ +} + +void tst_QFontComboBox::qfontcombobox_data() +{ +} + +void tst_QFontComboBox::qfontcombobox() +{ + SubQFontComboBox box; + QCOMPARE(box.currentFont(), QFont()); + QCOMPARE(box.fontFilters(), QFontComboBox::AllFonts); + box.setCurrentFont(QFont()); + box.setFontFilters(QFontComboBox::AllFonts); + box.setWritingSystem(QFontDatabase::Any); + QVERIFY(box.sizeHint() != QSize()); + QCOMPARE(box.writingSystem(), QFontDatabase::Any); + box.call_currentFontChanged(QFont()); + QEvent event(QEvent::None); + QCOMPARE(box.call_event(&event), false); +} + +void tst_QFontComboBox::currentFont_data() +{ + QTest::addColumn<QFont>("currentFont"); + // Normalize the names + QFont defaultFont; + QFontInfo fi(defaultFont); + defaultFont = QFont(fi.family()); // make sure we have a real font name and not something like 'Sans Serif'. + QTest::newRow("default") << defaultFont; + defaultFont.setPointSize(defaultFont.pointSize() + 10); + QTest::newRow("default2") << defaultFont; + QFontDatabase db; + QStringList list = db.families(); + for (int i = 0; i < list.count(); ++i) { + QFont f = QFont(QFontInfo(QFont(list.at(i))).family()); + QTest::newRow(qPrintable(list.at(i))) << f; + } +} + +// public QFont currentFont() const +void tst_QFontComboBox::currentFont() +{ + QFETCH(QFont, currentFont); + + SubQFontComboBox box; + QSignalSpy spy0(&box, SIGNAL(currentFontChanged(QFont const&))); + QFont oldCurrentFont = box.currentFont(); + + box.setCurrentFont(currentFont); + QRegExp foundry(" \\[.*\\]"); + if (!box.currentFont().family().contains(foundry)) { + QCOMPARE(box.currentFont(), currentFont); + } + QString boxFontFamily = QFontInfo(box.currentFont()).family(); + if (!currentFont.family().contains(foundry)) + boxFontFamily.remove(foundry); + QCOMPARE(boxFontFamily, currentFont.family()); + + if (oldCurrentFont != box.currentFont()) { + //the signal may be emit twice if there is a foundry into brackets + QCOMPARE(spy0.count(),1); + } +} + +Q_DECLARE_METATYPE(QFontComboBox::FontFilters) +void tst_QFontComboBox::fontFilters_data() +{ + QTest::addColumn<QFontComboBox::FontFilters>("fontFilters"); + QTest::newRow("AllFonts") + << QFontComboBox::FontFilters(QFontComboBox::AllFonts); + QTest::newRow("ScalableFonts") + << QFontComboBox::FontFilters(QFontComboBox::ScalableFonts); + QTest::newRow("NonScalableFonts") + << QFontComboBox::FontFilters(QFontComboBox::NonScalableFonts); + QTest::newRow("MonospacedFonts") + << QFontComboBox::FontFilters(QFontComboBox::MonospacedFonts); + QTest::newRow("ProportionalFonts") + << QFontComboBox::FontFilters(QFontComboBox::ProportionalFonts); + + // combine two + QTest::newRow("ProportionalFonts | NonScalableFonts") + << QFontComboBox::FontFilters(QFontComboBox::ProportionalFonts | QFontComboBox::NonScalableFonts); + + // i.e. all + QTest::newRow("ScalableFonts | NonScalableFonts") + << QFontComboBox::FontFilters(QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts); + +} + +// public QFontComboBox::FontFilters fontFilters() const +void tst_QFontComboBox::fontFilters() +{ + QFETCH(QFontComboBox::FontFilters, fontFilters); + + SubQFontComboBox box; + QSignalSpy spy0(&box, SIGNAL(currentFontChanged(QFont const&))); + QFont currentFont = box.currentFont(); + + box.setFontFilters(fontFilters); + QCOMPARE(box.fontFilters(), fontFilters); + + QFontDatabase db; + QStringList list = db.families(); + int c = 0; + const int scalableMask = (QFontComboBox::ScalableFonts | QFontComboBox::NonScalableFonts); + const int spacingMask = (QFontComboBox::ProportionalFonts | QFontComboBox::MonospacedFonts); + if((fontFilters & scalableMask) == scalableMask) + fontFilters &= ~scalableMask; + if((fontFilters & spacingMask) == spacingMask) + fontFilters &= ~spacingMask; + + for (int i = 0; i < list.count(); ++i) { + if (fontFilters & QFontComboBox::ScalableFonts) { + if (!db.isSmoothlyScalable(list[i])) + continue; + } else if (fontFilters & QFontComboBox::NonScalableFonts) { + if (db.isSmoothlyScalable(list[i])) + continue; + } + if (fontFilters & QFontComboBox::MonospacedFonts) { + if (!db.isFixedPitch(list[i])) + continue; + } else if (fontFilters & QFontComboBox::ProportionalFonts) { + if (db.isFixedPitch(list[i])) + continue; + } + c++; + } + + QCOMPARE(box.model()->rowCount(), c); + + if (c == 0) + QCOMPARE(box.currentFont(), QFont()); + + QCOMPARE(spy0.count(), (currentFont != box.currentFont()) ? 1 : 0); +} + +// public QSize sizeHint() const +void tst_QFontComboBox::sizeHint() +{ + SubQFontComboBox box; + QSize sizeHint = box.QComboBox::sizeHint(); + QFontMetrics fm(box.font()); + sizeHint.setWidth(qMax(sizeHint.width(), fm.width(QLatin1Char('m'))*14)); + QCOMPARE(box.sizeHint(), sizeHint); +} + +Q_DECLARE_METATYPE(QFontDatabase::WritingSystem) +void tst_QFontComboBox::writingSystem_data() +{ + QTest::addColumn<QFontDatabase::WritingSystem>("writingSystem"); + QTest::newRow("Any") << QFontDatabase::Any; + QTest::newRow("Latin") << QFontDatabase::Latin; + QTest::newRow("Lao") << QFontDatabase::Lao; + QTest::newRow("TraditionalChinese") << QFontDatabase::TraditionalChinese; + QTest::newRow("Ogham") << QFontDatabase::Ogham; + QTest::newRow("Runic") << QFontDatabase::Runic; + + for (int i = 0; i < 31; ++i) + QTest::newRow("enum") << (QFontDatabase::WritingSystem)i; +} + +// public QFontDatabase::WritingSystem writingSystem() const +void tst_QFontComboBox::writingSystem() +{ + QFETCH(QFontDatabase::WritingSystem, writingSystem); + + SubQFontComboBox box; + QSignalSpy spy0(&box, SIGNAL(currentFontChanged(QFont const&))); + QFont currentFont = box.currentFont(); + + box.setWritingSystem(writingSystem); + QCOMPARE(box.writingSystem(), writingSystem); + + QFontDatabase db; + QStringList list = db.families(writingSystem); + QCOMPARE(box.model()->rowCount(), list.count()); + + if (list.count() == 0) + QCOMPARE(box.currentFont(), QFont()); + + QCOMPARE(spy0.count(), (currentFont != box.currentFont()) ? 1 : 0); +} + +// protected void currentFontChanged(QFont const& f) +void tst_QFontComboBox::currentFontChanged() +{ + SubQFontComboBox box; + QSignalSpy spy0(&box, SIGNAL(currentFontChanged(QFont const&))); + + if (box.model()->rowCount() > 2) { + QTest::keyPress(&box, Qt::Key_Down); + QCOMPARE(spy0.count(), 1); + + QFont f( "Sans Serif" ); + box.setCurrentFont(f); + QCOMPARE(spy0.count(), 2); + } else + qWarning("Not enough fonts installed on test system. Consider adding some"); +} + +QTEST_MAIN(tst_QFontComboBox) +#include "tst_qfontcombobox.moc" + diff --git a/tests/auto/widgets/widgets/qgroupbox/.gitignore b/tests/auto/widgets/widgets/qgroupbox/.gitignore new file mode 100644 index 0000000000..16dc39494e --- /dev/null +++ b/tests/auto/widgets/widgets/qgroupbox/.gitignore @@ -0,0 +1 @@ +tst_qgroupbox diff --git a/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro b/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro new file mode 100644 index 0000000000..f4181a33ed --- /dev/null +++ b/tests/auto/widgets/widgets/qgroupbox/qgroupbox.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +QT += widgets +SOURCES += tst_qgroupbox.cpp + + + diff --git a/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp new file mode 100644 index 0000000000..8568ef01d1 --- /dev/null +++ b/tests/auto/widgets/widgets/qgroupbox/tst_qgroupbox.cpp @@ -0,0 +1,475 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QLineEdit> +#include <QStyle> +#include <QStyleOptionGroupBox> +#include <QVBoxLayout> +#include <QRadioButton> + +#include "qgroupbox.h" + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QGroupBox : public QObject +{ + Q_OBJECT + +public: + tst_QGroupBox(); + virtual ~tst_QGroupBox(); + +public slots: + void toggledHelperSlot(bool on); + void init(); + void clickTimestampSlot(); + void toggleTimestampSlot(); + +private slots: + void setTitle_data(); + void setTitle(); + void setCheckable_data(); + void setCheckable(); + void setChecked_data(); + void setChecked(); + void enabledPropagation(); + void sizeHint(); + void toggled(); + void clicked_data(); + void clicked(); + void toggledVsClicked(); + void childrenAreDisabled(); + void propagateFocus(); + +private: + bool checked; + qint64 timeStamp; + qint64 clickTimeStamp; + qint64 toggleTimeStamp; + +}; + +tst_QGroupBox::tst_QGroupBox() +{ + checked = true; +} + +tst_QGroupBox::~tst_QGroupBox() +{ + +} + +void tst_QGroupBox::init() +{ + checked = true; +} + +void tst_QGroupBox::setTitle_data() +{ + QTest::addColumn<QString>("title"); + QTest::addColumn<QString>("expectedTitle"); + QTest::newRow( "empty_title" ) << QString("") << QString(""); + QTest::newRow( "normal_title" ) << QString("Whatisthematrix") << QString("Whatisthematrix"); + QTest::newRow( "special_chars_title" ) << QString("<>%&#/()=") << QString("<>%&#/()="); + QTest::newRow( "spaces_title" ) << QString(" Hello ") << QString(" Hello "); +} + +void tst_QGroupBox::setCheckable_data() +{ + QTest::addColumn<bool>("checkable"); + QTest::addColumn<bool>("expectedCheckable"); + QTest::newRow( "checkable_true" ) << true << true; + QTest::newRow( "checkable_false" ) << false << false; +} + +void tst_QGroupBox::setChecked_data() +{ + QTest::addColumn<bool>("checkable"); + QTest::addColumn<bool>("checked"); + QTest::addColumn<bool>("expectedChecked"); + QTest::newRow( "checkable_false_checked_true" ) << false << true << false; + QTest::newRow( "checkable_true_checked_true" ) << true << true << true; + QTest::newRow( "checkable_true_checked_false" ) << true << false << false; +} + +void tst_QGroupBox::setTitle() +{ + QFETCH( QString, title ); + QFETCH( QString, expectedTitle ); + + QGroupBox groupBox; + + groupBox.setTitle( title ); + + QCOMPARE( groupBox.title() , expectedTitle ); +} + +void tst_QGroupBox::setCheckable() +{ + QFETCH( bool, checkable ); + QFETCH( bool, expectedCheckable ); + + QGroupBox groupBox; + + groupBox.setCheckable( checkable ); + QCOMPARE( groupBox.isCheckable() , expectedCheckable ); +} + + +void tst_QGroupBox::setChecked() +{ + QFETCH( bool, checkable ); + QFETCH( bool, checked ); + QFETCH( bool, expectedChecked ); + + QGroupBox groupBox; + + groupBox.setCheckable( checkable ); + groupBox.setChecked( checked ); + QCOMPARE( groupBox.isChecked(), expectedChecked ); +} + +void tst_QGroupBox::enabledPropagation() +{ + QGroupBox *testWidget = new QGroupBox(0); + testWidget->setCheckable(true); + testWidget->setChecked(true); + QWidget* childWidget = new QWidget( testWidget ); + childWidget->show(); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( childWidget->isEnabled() ); + + testWidget->setEnabled( false ); + QVERIFY( !testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + + testWidget->setDisabled( false ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( childWidget->isEnabled() ); + + QWidget* grandChildWidget = new QWidget( childWidget ); + QVERIFY( grandChildWidget->isEnabled() ); + + testWidget->setDisabled( true ); + QVERIFY( !testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + grandChildWidget->setEnabled( false ); + testWidget->setEnabled( true ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + grandChildWidget->setEnabled( true ); + testWidget->setEnabled( false ); + childWidget->setDisabled( true ); + testWidget->setEnabled( true ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + // Reset state + testWidget->setEnabled( true ); + childWidget->setEnabled( true ); + grandChildWidget->setEnabled( true ); + + // Now check when it's disabled + testWidget->setChecked(false); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + + testWidget->setEnabled( false ); + QVERIFY( !testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + + testWidget->setDisabled( false ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + + QVERIFY( !grandChildWidget->isEnabled() ); + + testWidget->setDisabled( true ); + QVERIFY( !testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + grandChildWidget->setEnabled( false ); + testWidget->setEnabled( true ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + grandChildWidget->setEnabled( true ); + testWidget->setEnabled( false ); + childWidget->setDisabled( true ); + testWidget->setEnabled( true ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + // Reset state + testWidget->setEnabled( true ); + childWidget->setEnabled( true ); + grandChildWidget->setEnabled( true ); + + // Finally enable it again + testWidget->setChecked(true); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( childWidget->isEnabled() ); + + testWidget->setEnabled( false ); + QVERIFY( !testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + + testWidget->setDisabled( false ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( childWidget->isEnabled() ); + QVERIFY( grandChildWidget->isEnabled() ); + + testWidget->setDisabled( true ); + QVERIFY( !testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + grandChildWidget->setEnabled( false ); + testWidget->setEnabled( true ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + grandChildWidget->setEnabled( true ); + testWidget->setEnabled( false ); + childWidget->setDisabled( true ); + testWidget->setEnabled( true ); + QVERIFY( testWidget->isEnabled() ); + QVERIFY( !childWidget->isEnabled() ); + QVERIFY( !grandChildWidget->isEnabled() ); + + delete testWidget; +} + + +void tst_QGroupBox::sizeHint() +{ + QGroupBox testWidget1(0); + testWidget1.setTitle("&0&0&0&0&0&0&0&0&0&0"); + + QGroupBox testWidget2(0); + testWidget2.setTitle("0000000000"); + + QCOMPARE(testWidget1.sizeHint().width(), testWidget2.sizeHint().width()); + + // if the above fails one should maybe test to see like underneath. + // QVERIFY((QABS(testWidget1->sizeHint().width() - testWidget2->sizeHint().width()) < 10)); +} + +void tst_QGroupBox::toggledHelperSlot(bool on) +{ + checked = on; +} + + +void tst_QGroupBox::toggled() +{ + QGroupBox testWidget1(0); + testWidget1.setCheckable(true); + connect(&testWidget1, SIGNAL(toggled(bool)), this, SLOT(toggledHelperSlot(bool))); + QLineEdit *edit = new QLineEdit(&testWidget1); + QVERIFY(checked); + testWidget1.setChecked(true); + QVERIFY(checked); + QVERIFY(edit->isEnabled()); + testWidget1.setChecked(false); + QVERIFY(!checked); + QVERIFY(!edit->isEnabled()); +} + +void tst_QGroupBox::clicked_data() +{ + QTest::addColumn<bool>("checkable"); + QTest::addColumn<bool>("initialCheck"); + QTest::addColumn<int>("areaToHit"); + QTest::addColumn<int>("clickedCount"); + QTest::addColumn<bool>("finalCheck"); + + QTest::newRow("hit nothing, not checkable") << false << false << int(QStyle::SC_None) << 0 << false; + QTest::newRow("hit frame, not checkable") << false << false << int(QStyle::SC_GroupBoxFrame) << 0 << false; + QTest::newRow("hit content, not checkable") << false << false << int(QStyle::SC_GroupBoxContents) << 0 << false; + QTest::newRow("hit label, not checkable") << false << false << int(QStyle::SC_GroupBoxLabel) << 0 << false; + QTest::newRow("hit checkbox, not checkable") << false << false << int(QStyle::SC_GroupBoxCheckBox) << 0 << false; + + QTest::newRow("hit nothing, checkable") << true << true << int(QStyle::SC_None) << 0 << true; + QTest::newRow("hit frame, checkable") << true << true << int(QStyle::SC_GroupBoxFrame) << 0 << true; + QTest::newRow("hit content, checkable") << true << true << int(QStyle::SC_GroupBoxContents) << 0 << true; + QTest::newRow("hit label, checkable") << true << true << int(QStyle::SC_GroupBoxLabel) << 1 << false; + QTest::newRow("hit checkbox, checkable") << true << true << int(QStyle::SC_GroupBoxCheckBox) << 1 << false; + + QTest::newRow("hit nothing, checkable, but unchecked") << true << false << int(QStyle::SC_None) << 0 << false; + QTest::newRow("hit frame, checkable, but unchecked") << true << false << int(QStyle::SC_GroupBoxFrame) << 0 << false; + QTest::newRow("hit content, checkable, but unchecked") << true << false << int(QStyle::SC_GroupBoxContents) << 0 << false; + QTest::newRow("hit label, checkable, but unchecked") << true << false << int(QStyle::SC_GroupBoxLabel) << 1 << true; + QTest::newRow("hit checkbox, checkable, but unchecked") << true << false << int(QStyle::SC_GroupBoxCheckBox) << 1 << true; +} + +void tst_QGroupBox::clicked() +{ + QFETCH(bool, checkable); + QFETCH(bool, initialCheck); + QFETCH(int, areaToHit); + QGroupBox testWidget(QLatin1String("Testing Clicked")); + testWidget.setCheckable(checkable); + testWidget.setChecked(initialCheck); + QCOMPARE(testWidget.isChecked(), initialCheck); + testWidget.resize(200, 200); + QSignalSpy spy(&testWidget, SIGNAL(clicked(bool))); + + QStyleOptionGroupBox option; + option.initFrom(&testWidget); + option.subControls = checkable ? QStyle::SubControls(QStyle::SC_All) : QStyle::SubControls(QStyle::SC_All & ~QStyle::SC_GroupBoxCheckBox); + option.text = testWidget.title(); + option.textAlignment = testWidget.alignment(); + + QRect rect = testWidget.style()->subControlRect(QStyle::CC_GroupBox, &option, + QStyle::SubControl(areaToHit), &testWidget); + + if (rect.isValid()) + QTest::mouseClick(&testWidget, Qt::LeftButton, 0, rect.center()); + else + QTest::mouseClick(&testWidget, Qt::LeftButton); + + QTEST(spy.count(), "clickedCount"); + if (spy.count() > 0) + QTEST(spy.at(0).at(0).toBool(), "finalCheck"); + QTEST(testWidget.isChecked(), "finalCheck"); +} + +void tst_QGroupBox::toggledVsClicked() +{ + timeStamp = clickTimeStamp = toggleTimeStamp = 0; + QGroupBox groupBox; + groupBox.setCheckable(true); + QSignalSpy toggleSpy(&groupBox, SIGNAL(toggled(bool))); + QSignalSpy clickSpy(&groupBox, SIGNAL(clicked(bool))); + + groupBox.setChecked(!groupBox.isChecked()); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(toggleSpy.count(), 1); + if (toggleSpy.count() > 0) + QCOMPARE(toggleSpy.at(0).at(0).toBool(), groupBox.isChecked()); + + connect(&groupBox, SIGNAL(clicked(bool)), this, SLOT(clickTimestampSlot())); + connect(&groupBox, SIGNAL(toggled(bool)), this, SLOT(toggleTimestampSlot())); + + QStyleOptionGroupBox option; + option.initFrom(&groupBox); + option.subControls = QStyle::SubControls(QStyle::SC_All); + QRect rect = groupBox.style()->subControlRect(QStyle::CC_GroupBox, &option, + QStyle::SC_GroupBoxCheckBox, &groupBox); + + QTest::mouseClick(&groupBox, Qt::LeftButton, 0, rect.center()); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(toggleSpy.count(), 2); + QVERIFY(toggleTimeStamp < clickTimeStamp); +} + +void tst_QGroupBox::clickTimestampSlot() +{ + clickTimeStamp = ++timeStamp; +} + +void tst_QGroupBox::toggleTimestampSlot() +{ + toggleTimeStamp = ++timeStamp; +} + +void tst_QGroupBox::childrenAreDisabled() +{ + QGroupBox box; + box.setCheckable(true); + box.setChecked(false); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(new QRadioButton); + layout->addWidget(new QRadioButton); + layout->addWidget(new QRadioButton); + box.setLayout(layout); + + foreach (QObject *object, box.children()) { + if (QWidget *widget = qobject_cast<QWidget *>(object)) { + QVERIFY(!widget->isEnabled()); + QVERIFY(!widget->testAttribute(Qt::WA_ForceDisabled)); + } + } + + box.setChecked(true); + foreach (QObject *object, box.children()) { + if (QWidget *widget = qobject_cast<QWidget *>(object)) { + QVERIFY(widget->isEnabled()); + QVERIFY(!widget->testAttribute(Qt::WA_ForceDisabled)); + } + } + + box.setChecked(false); + foreach (QObject *object, box.children()) { + if (QWidget *widget = qobject_cast<QWidget *>(object)) { + QVERIFY(!widget->isEnabled()); + QVERIFY(!widget->testAttribute(Qt::WA_ForceDisabled)); + } + } +} + +void tst_QGroupBox::propagateFocus() +{ + QGroupBox box; + QLineEdit lineEdit(&box); + box.show(); + QApplication::setActiveWindow(&box); + box.setFocus(); + QTest::qWait(250); + QTRY_COMPARE(qApp->focusWidget(), static_cast<QWidget*>(&lineEdit)); +} + +QTEST_MAIN(tst_QGroupBox) +#include "tst_qgroupbox.moc" diff --git a/tests/auto/widgets/widgets/qintvalidator/.gitignore b/tests/auto/widgets/widgets/qintvalidator/.gitignore new file mode 100644 index 0000000000..c6d5c989f0 --- /dev/null +++ b/tests/auto/widgets/widgets/qintvalidator/.gitignore @@ -0,0 +1 @@ +tst_qintvalidator diff --git a/tests/auto/widgets/widgets/qintvalidator/qintvalidator.pro b/tests/auto/widgets/widgets/qintvalidator/qintvalidator.pro new file mode 100644 index 0000000000..576621a08b --- /dev/null +++ b/tests/auto/widgets/widgets/qintvalidator/qintvalidator.pro @@ -0,0 +1,4 @@ +load(qttest_p4) +SOURCES += tst_qintvalidator.cpp + + diff --git a/tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp b/tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp new file mode 100644 index 0000000000..369e3254e8 --- /dev/null +++ b/tests/auto/widgets/widgets/qintvalidator/tst_qintvalidator.cpp @@ -0,0 +1,255 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). |