1/****************************************************************************
2**
3** Copyright (C) 2021 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31#include <qapplication.h>
32#include <qgroupbox.h>
33#include <qlineedit.h>
34
35
36
37#include <qdatetimeedit.h>
38#include <qlocale.h>
39#include <qlayout.h>
40#include <qeventloop.h>
41#include <qstyle.h>
42#include <qstyle.h>
43#include <QStyleOptionSpinBox>
44#include <QDate>
45#include <QDateTime>
46#include <QTime>
47#include <QList>
48#include <QDateTimeEdit>
49#include <QCalendarWidget>
50#include <QWidget>
51#include <QLineEdit>
52#include <QObject>
53#include <QLocale>
54#include <QString>
55#include <QVariantList>
56#include <QVariant>
57#include <QApplication>
58#include <QPoint>
59#include <QVBoxLayout>
60#include <QRect>
61#include <QCursor>
62#include <QEventLoop>
63#include <QStyle>
64#include <QStyleOptionComboBox>
65#include <QTimeEdit>
66#include <QMetaType>
67#include <QDebug>
68#include <QWheelEvent>
69#include <QTest>
70#include <QSignalSpy>
71#include <QTestEventList>
72#include <QDateEdit>
73#include <QProxyStyle>
74
75#include <private/qdatetimeedit_p.h>
76
77#ifdef Q_OS_WIN
78# include <windows.h>
79# undef min
80# undef max
81#endif
82
83
84Q_DECLARE_METATYPE(Qt::Key);
85Q_DECLARE_METATYPE(Qt::KeyboardModifiers);
86Q_DECLARE_METATYPE(Qt::KeyboardModifier);
87
88class EditorDateEdit : public QDateTimeEdit
89{
90 Q_OBJECT
91public:
92 EditorDateEdit(QWidget *parent = 0) : QDateTimeEdit(parent) {}
93 QLineEdit *lineEdit() { return QDateTimeEdit::lineEdit(); }
94 friend class tst_QDateTimeEdit;
95};
96
97class PressAndHoldStyle : public QProxyStyle
98{
99 Q_OBJECT
100public:
101 using QProxyStyle::QProxyStyle;
102
103 int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
104 const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
105 {
106 switch (hint) {
107 case QStyle::SH_SpinBox_ClickAutoRepeatRate:
108 return 5;
109 case QStyle::SH_SpinBox_ClickAutoRepeatThreshold:
110 return 10;
111 default:
112 return QProxyStyle::styleHint(hint, option, widget, returnData);
113 }
114 }
115};
116
117class StepModifierStyle : public QProxyStyle
118{
119 Q_OBJECT
120public:
121 using QProxyStyle::QProxyStyle;
122
123 int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
124 const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
125 {
126 switch (hint) {
127 case QStyle::SH_SpinBox_StepModifier:
128 return stepModifier;
129 default:
130 return QProxyStyle::styleHint(hint, option, widget, returnData);
131 }
132 }
133
134 Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
135};
136
137class tst_QDateTimeEdit : public QObject
138{
139 Q_OBJECT
140
141private slots:
142 void initTestCase();
143 void init();
144 void cleanup();
145 void cleanupTestCase();
146
147 void cachedDayTest();
148 void getSetCheck();
149 void constructor_qwidget();
150 void constructor_qdatetime_data();
151 void constructor_qdatetime();
152 void constructor_qdate_data();
153 void constructor_qdate();
154 void constructor_qtime_data();
155 void constructor_qtime();
156
157 void sectionText_data();
158 void sectionText();
159 void dateTimeSignalChecking_data();
160 void dateTimeSignalChecking();
161 void mousePress();
162 void stepHourAMPM_data();
163
164 void stepHourAMPM();
165 void displayedSections_data();
166 void displayedSections();
167 void currentSection_data();
168 void currentSection();
169
170 void setCurrentSection();
171 void setCurrentSection_data();
172
173 void minimumDate_data();
174 void minimumDate();
175 void maximumDate_data();
176 void maximumDate();
177 void clearMinimumDate_data();
178 void clearMinimumDate();
179 void clearMaximumDate_data();
180 void clearMaximumDate();
181
182 void minimumDateTime_data();
183 void minimumDateTime();
184 void maximumDateTime_data();
185 void maximumDateTime();
186
187 void clearMinimumDateTime_data();
188 void clearMinimumDateTime();
189 void clearMaximumDateTime_data();
190 void clearMaximumDateTime();
191
192 void displayFormat_data();
193 void displayFormat();
194
195 void specialValueText();
196 void setRange_data();
197 void setRange();
198 void editingRanged_data();
199 void editingRanged();
200
201 void selectAndScrollWithKeys();
202 void backspaceKey();
203 void deleteKey();
204 void tabKeyNavigation();
205 void tabKeyNavigationWithPrefix();
206 void tabKeyNavigationWithSuffix();
207 void enterKey();
208
209 void readOnly();
210
211 void wrappingDate_data();
212 void wrappingDate();
213
214 void dateSignalChecking_data();
215 void dateSignalChecking();
216
217 void wrappingTime_data();
218 void wrappingTime();
219
220 void userKeyPress_Time_data();
221 void userKeyPress_Time();
222
223 void timeSignalChecking_data();
224 void timeSignalChecking();
225
226 void weirdCase();
227 void newCase();
228 void newCase2();
229 void newCase3();
230 void newCase4();
231 void newCase5();
232 void newCase6();
233
234 void task98554();
235 void task149097();
236
237 void cursorPos();
238 void calendarPopup();
239
240 void hour12Test();
241 void yyTest();
242 void task108572();
243
244 void task148725();
245 void task148522();
246
247 void setSelectedSection();
248 void reverseTest();
249
250 void ddMMMMyyyy();
251 void wheelEvent_data();
252 void wheelEvent();
253
254 void specialValueCornerCase();
255 void cursorPositionOnInit();
256
257 void task118867();
258
259 void nextPrevSection_data();
260 void nextPrevSection();
261
262 void dateEditTimeEditFormats();
263 void timeSpec_data();
264 void timeSpec();
265 void timeSpecBug();
266 void timeSpecInit();
267
268 void monthEdgeCase();
269 void setLocale();
270
271 void potentialYYValueBug();
272 void textSectionAtEnd();
273
274 void keypadAutoAdvance_data();
275 void keypadAutoAdvance();
276
277 void task196924();
278 void focusNextPrevChild();
279
280 void taskQTBUG_12384_timeSpecShowTimeOnly();
281
282 void deleteCalendarWidget();
283
284 void setLocaleOnCalendarWidget();
285
286#ifdef QT_BUILD_INTERNAL
287 void dateEditCorrectSectionSize_data();
288 void dateEditCorrectSectionSize();
289#endif
290
291 void stepModifierKeys_data();
292 void stepModifierKeys();
293
294 void stepModifierButtons_data();
295 void stepModifierButtons();
296
297 void stepModifierPressAndHold_data();
298 void stepModifierPressAndHold();
299
300 void springForward_data();
301 void springForward();
302
303 void stepIntoDSTGap_data();
304 void stepIntoDSTGap();
305
306private:
307 EditorDateEdit* testWidget;
308 QWidget *testFocusWidget;
309};
310
311typedef QList<QDate> DateList;
312typedef QList<QTime> TimeList;
313typedef QList<Qt::Key> KeyList;
314
315static QLatin1String modifierToName(Qt::KeyboardModifier modifier)
316{
317 switch (modifier) {
318 case Qt::NoModifier:
319 return QLatin1String("No");
320 break;
321 case Qt::ControlModifier:
322 return QLatin1String("Ctrl");
323 break;
324 case Qt::ShiftModifier:
325 return QLatin1String("Shift");
326 break;
327 case Qt::AltModifier:
328 return QLatin1String("Alt");
329 break;
330 case Qt::MetaModifier:
331 return QLatin1String("Meta");
332 break;
333 default:
334 qFatal(msg: "Unexpected keyboard modifier");
335 return QLatin1String();
336 }
337}
338
339static QLatin1String sectionToName(const QDateTimeEdit::Section section)
340{
341 switch (section) {
342 case QDateTimeEdit::SecondSection:
343 return QLatin1String("Second");
344 case QDateTimeEdit::MinuteSection:
345 return QLatin1String("Minute");
346 case QDateTimeEdit::HourSection:
347 return QLatin1String("Hours");
348 case QDateTimeEdit::DaySection:
349 return QLatin1String("Day");
350 case QDateTimeEdit::MonthSection:
351 return QLatin1String("Month");
352 case QDateTimeEdit::YearSection:
353 return QLatin1String("Year");
354 default:
355 qFatal(msg: "Unexpected section");
356 return QLatin1String();
357 }
358}
359
360static QDate stepDate(QDate startDate, const QDateTimeEdit::Section section, const int steps)
361{
362 switch (section) {
363 case QDateTimeEdit::DaySection:
364 return startDate.addDays(days: steps);
365 case QDateTimeEdit::MonthSection:
366 return startDate.addMonths(months: steps);
367 case QDateTimeEdit::YearSection:
368 return startDate.addYears(years: steps);
369 default:
370 qFatal(msg: "Unexpected section");
371 return QDate();
372 }
373}
374
375static QTime stepTime(QTime startTime, const QDateTimeEdit::Section section, const int steps)
376{
377 switch (section) {
378 case QDateTimeEdit::SecondSection:
379 return startTime.addSecs(secs: steps);
380 case QDateTimeEdit::MinuteSection:
381 return QTime(startTime.hour(),
382 startTime.minute() + steps,
383 startTime.second());
384 case QDateTimeEdit::HourSection:
385 return QTime(startTime.hour() + steps,
386 startTime.minute(),
387 startTime.second());
388 default:
389 qFatal(msg: "Unexpected section");
390 return QTime();
391 }
392}
393
394// Testing get/set functions
395void tst_QDateTimeEdit::getSetCheck()
396{
397 QDateTimeEdit obj1;
398 QCOMPARE(obj1.inputMethodQuery(Qt::ImHints), QVariant(int(Qt::ImhPreferNumbers)));
399 obj1.setDisplayFormat("dd/MM/yyyy hh:mm:ss.zzz d/M/yy h:m:s.z AP");
400 // Section QDateTimeEdit::currentSection()
401 // void QDateTimeEdit::setCurrentSection(Section)
402 obj1.setCurrentSection(QDateTimeEdit::NoSection);
403 QVERIFY(obj1.currentSection() != QDateTimeEdit::NoSection);
404 obj1.setCurrentSection(QDateTimeEdit::AmPmSection);
405 QCOMPARE(QDateTimeEdit::AmPmSection, obj1.currentSection());
406 obj1.setCurrentSection(QDateTimeEdit::MSecSection);
407 QCOMPARE(QDateTimeEdit::MSecSection, obj1.currentSection());
408 obj1.setCurrentSection(QDateTimeEdit::SecondSection);
409 QCOMPARE(QDateTimeEdit::SecondSection, obj1.currentSection());
410 obj1.setCurrentSection(QDateTimeEdit::MinuteSection);
411 QCOMPARE(QDateTimeEdit::MinuteSection, obj1.currentSection());
412 obj1.setCurrentSection(QDateTimeEdit::HourSection);
413 QCOMPARE(QDateTimeEdit::HourSection, obj1.currentSection());
414 obj1.setCurrentSection(QDateTimeEdit::DaySection);
415 QCOMPARE(QDateTimeEdit::DaySection, obj1.currentSection());
416 obj1.setCurrentSection(QDateTimeEdit::MonthSection);
417 QCOMPARE(QDateTimeEdit::MonthSection, obj1.currentSection());
418 obj1.setCurrentSection(QDateTimeEdit::YearSection);
419 QCOMPARE(QDateTimeEdit::YearSection, obj1.currentSection());
420
421 QDateEdit dateEdit;
422 QCOMPARE(dateEdit.inputMethodQuery(Qt::ImHints), QVariant(int(Qt::ImhPreferNumbers)));
423 QTimeEdit timeEdit;
424 QCOMPARE(timeEdit.inputMethodQuery(Qt::ImHints), QVariant(int(Qt::ImhPreferNumbers)));
425}
426
427void tst_QDateTimeEdit::initTestCase()
428{
429 QLocale system = QLocale::system();
430 if (system.language() != QLocale::C && system.language() != QLocale::English)
431 qWarning(msg: "Running under locale %s/%s -- this test may generate failures due to language differences",
432 qPrintable(QLocale::languageToString(system.language())),
433 qPrintable(QLocale::countryToString(system.country())));
434 testWidget = new EditorDateEdit(0);
435 testFocusWidget = new QWidget(0);
436 testFocusWidget->resize(w: 200, h: 100);
437 testFocusWidget->show();
438}
439
440void tst_QDateTimeEdit::cleanupTestCase()
441{
442 delete testFocusWidget;
443 testFocusWidget = 0;
444 delete testWidget;
445 testWidget = 0;
446}
447
448void tst_QDateTimeEdit::init()
449{
450 QLocale::setDefault(QLocale(QLocale::C));
451#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
452 SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
453#endif
454 testWidget->setDisplayFormat("dd/MM/yyyy"); // Nice default to have
455 testWidget->setDateTime(QDateTime(QDate(2000, 1, 1), QTime(0, 0)));
456 testWidget->show();
457 testFocusWidget->move(ax: -1000, ay: -1000);
458}
459
460void tst_QDateTimeEdit::cleanup()
461{
462 testWidget->clearMinimumDateTime();
463 testWidget->clearMaximumDateTime();
464 testWidget->setTimeSpec(Qt::LocalTime);
465 testWidget->setSpecialValueText(QString());
466 testWidget->setWrapping(false);
467 // Restore the default.
468 testWidget->setCalendarPopup(false);
469}
470
471void tst_QDateTimeEdit::constructor_qwidget()
472{
473 testWidget->hide();
474 QDateTimeEdit dte(0);
475 dte.show();
476 QCOMPARE(dte.dateTime(), QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0)));
477 QCOMPARE(dte.minimumDate(), QDate(1752, 9, 14));
478 QCOMPARE(dte.minimumTime(), QTime(0, 0, 0, 0));
479 QCOMPARE(dte.maximumDate(), QDate(9999, 12, 31));
480 QCOMPARE(dte.maximumTime(), QTime(23, 59, 59, 999));
481}
482
483void tst_QDateTimeEdit::constructor_qdatetime_data()
484{
485 QTest::addColumn<QDateTime>(name: "parameter");
486 QTest::addColumn<QDateTime>(name: "displayDateTime");
487 QTest::addColumn<QDate>(name: "minimumDate");
488 QTest::addColumn<QTime>(name: "minimumTime");
489 QTest::addColumn<QDate>(name: "maximumDate");
490 QTest::addColumn<QTime>(name: "maximumTime");
491
492 QTest::newRow(dataTag: "normal") << QDateTime(QDate(2004, 6, 16), QTime(13, 46, 32, 764))
493 << QDateTime(QDate(2004, 6, 16), QTime(13, 46, 32, 764))
494 << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
495 << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
496
497 QTest::newRow(dataTag: "invalid") << QDateTime(QDate(9999, 99, 99), QTime(13, 46, 32, 764))
498 << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0))
499 << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
500 << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
501}
502
503void tst_QDateTimeEdit::constructor_qdatetime()
504{
505 QFETCH(QDateTime, parameter);
506 QFETCH(QDateTime, displayDateTime);
507 QFETCH(QDate, minimumDate);
508 QFETCH(QTime, minimumTime);
509 QFETCH(QDate, maximumDate);
510 QFETCH(QTime, maximumTime);
511
512 testWidget->hide();
513
514 QDateTimeEdit dte(parameter);
515 dte.show();
516 QCOMPARE(dte.dateTime(), displayDateTime);
517 QCOMPARE(dte.minimumDate(), minimumDate);
518 QCOMPARE(dte.minimumTime(), minimumTime);
519 QCOMPARE(dte.maximumDate(), maximumDate);
520 QCOMPARE(dte.maximumTime(), maximumTime);
521}
522
523void tst_QDateTimeEdit::constructor_qdate_data()
524{
525 QTest::addColumn<QDate>(name: "parameter");
526 QTest::addColumn<QDateTime>(name: "displayDateTime");
527 QTest::addColumn<QDate>(name: "minimumDate");
528 QTest::addColumn<QTime>(name: "minimumTime");
529 QTest::addColumn<QDate>(name: "maximumDate");
530 QTest::addColumn<QTime>(name: "maximumTime");
531
532 QTest::newRow(dataTag: "normal") << QDate(2004, 6, 16)
533 << QDateTime(QDate(2004, 6, 16), QTime(0, 0, 0, 0))
534 << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
535 << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
536
537 QTest::newRow(dataTag: "invalid") << QDate(9999, 99, 99)
538 << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0))
539 << QDate(1752, 9, 14) << QTime(0, 0, 0, 0)
540 << QDate(9999, 12, 31) << QTime(23, 59, 59, 999);
541}
542
543void tst_QDateTimeEdit::constructor_qdate()
544{
545 QFETCH(QDate, parameter);
546 QFETCH(QDateTime, displayDateTime);
547 QFETCH(QDate, minimumDate);
548 QFETCH(QTime, minimumTime);
549 QFETCH(QDate, maximumDate);
550 QFETCH(QTime, maximumTime);
551
552 testWidget->hide();
553
554 QDateTimeEdit dte(parameter);
555 dte.show();
556 QCOMPARE(dte.dateTime(), displayDateTime);
557 QCOMPARE(dte.minimumDate(), minimumDate);
558 QCOMPARE(dte.minimumTime(), minimumTime);
559 QCOMPARE(dte.maximumDate(), maximumDate);
560 QCOMPARE(dte.maximumTime(), maximumTime);
561}
562
563void tst_QDateTimeEdit::constructor_qtime_data()
564{
565 QTest::addColumn<QTime>(name: "parameter");
566 QTest::addColumn<QDateTime>(name: "displayDateTime");
567 QTest::addColumn<QDate>(name: "minimumDate");
568 QTest::addColumn<QTime>(name: "minimumTime");
569 QTest::addColumn<QDate>(name: "maximumDate");
570 QTest::addColumn<QTime>(name: "maximumTime");
571
572 QTest::newRow(dataTag: "normal") << QTime(13, 46, 32, 764)
573 << QDateTime(QDate(2000, 1, 1), QTime(13, 46, 32, 764))
574 << QDate(2000, 1, 1) << QTime(0, 0, 0, 0)
575 << QDate(2000, 1, 1) << QTime(23, 59, 59, 999);
576
577 QTest::newRow(dataTag: "invalid") << QTime(99, 99, 99, 5000)
578 << QDateTime(QDate(2000, 1, 1), QTime(0, 0, 0, 0))
579 << QDate(2000, 1, 1) << QTime(0, 0, 0, 0)
580 << QDate(2000, 1, 1) << QTime(23, 59, 59, 999);
581}
582
583void tst_QDateTimeEdit::constructor_qtime()
584{
585 QFETCH(QTime, parameter);
586 QFETCH(QDateTime, displayDateTime);
587 QFETCH(QDate, minimumDate);
588 QFETCH(QTime, minimumTime);
589 QFETCH(QDate, maximumDate);
590 QFETCH(QTime, maximumTime);
591
592 testWidget->hide();
593
594 QDateTimeEdit dte(parameter);
595 dte.show();
596 QCOMPARE(dte.dateTime(), displayDateTime);
597 QCOMPARE(dte.minimumDate(), minimumDate);
598 QCOMPARE(dte.minimumTime(), minimumTime);
599 QCOMPARE(dte.maximumDate(), maximumDate);
600 QCOMPARE(dte.maximumTime(), maximumTime);
601}
602
603void tst_QDateTimeEdit::minimumDate_data()
604{
605 QTest::addColumn<QDate>(name: "minimumDate");
606 QTest::addColumn<QDate>(name: "expectedMinDate");
607
608 QTest::newRow(dataTag: "normal-0") << QDate(2004, 5, 10) << QDate(2004, 5, 10);
609 QTest::newRow(dataTag: "normal-1") << QDate(2002, 3, 15) << QDate(2002, 3, 15);
610 QTest::newRow(dataTag: "normal-2") << QDate(9999, 12, 31) << QDate(9999, 12, 31);
611 QTest::newRow(dataTag: "normal-3") << QDate(1753, 1, 1) << QDate(1753, 1, 1);
612 QTest::newRow(dataTag: "invalid-0") << QDate(0, 0, 0) << QDate(1752, 9, 14);
613 QTest::newRow(dataTag: "old") << QDate(1492, 8, 3) << QDate(1492, 8, 3);
614}
615
616void tst_QDateTimeEdit::minimumDate()
617{
618 QFETCH(QDate, minimumDate);
619 QFETCH(QDate, expectedMinDate);
620
621 testWidget->setMinimumDate(minimumDate);
622 QCOMPARE(testWidget->minimumDate(), expectedMinDate);
623}
624
625void tst_QDateTimeEdit::minimumDateTime_data()
626{
627 QTest::addColumn<QDateTime>(name: "minimumDateTime");
628 QTest::addColumn<QDateTime>(name: "expectedMinDateTime");
629
630 QTest::newRow(dataTag: "normal-0") << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14))
631 << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14));
632
633 QTest::newRow(dataTag: "normal-1") << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1))
634 << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1));
635 QTest::newRow(dataTag: "normal-2") << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23))
636 << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23));
637 QTest::newRow(dataTag: "normal-3") << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23))
638 << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23));
639 QTest::newRow(dataTag: "normal-4") << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1))
640 << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1));
641 QTest::newRow(dataTag: "invalid-0") << QDateTime() << QDateTime(QDate(1752, 9, 14), QTime(0, 0, 0));
642 QTest::newRow(dataTag: "old") << QDateTime(QDate(1492, 8, 3), QTime(2, 3, 1))
643 << QDateTime(QDate(1492, 8, 3), QTime(2, 3, 1));
644}
645
646void tst_QDateTimeEdit::minimumDateTime()
647{
648 QFETCH(QDateTime, minimumDateTime);
649 QFETCH(QDateTime, expectedMinDateTime);
650
651 testWidget->setMinimumDateTime(minimumDateTime);
652 QCOMPARE(testWidget->minimumDateTime(), expectedMinDateTime);
653}
654
655void tst_QDateTimeEdit::maximumDateTime_data()
656{
657 QTest::addColumn<QDateTime>(name: "maximumDateTime");
658 QTest::addColumn<QDateTime>(name: "expectedMinDateTime");
659
660 QTest::newRow(dataTag: "normal-0") << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14))
661 << QDateTime(QDate(2004, 5, 10), QTime(2, 3, 14));
662
663 QTest::newRow(dataTag: "normal-1") << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1))
664 << QDateTime(QDate(2005, 5, 10), QTime(22, 33, 1));
665 QTest::newRow(dataTag: "normal-2") << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23))
666 << QDateTime(QDate(2006, 5, 10), QTime(13, 31, 23));
667 QTest::newRow(dataTag: "normal-3") << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23))
668 << QDateTime(QDate(2007, 5, 10), QTime(22, 23, 23));
669 QTest::newRow(dataTag: "normal-4") << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1))
670 << QDateTime(QDate(2008, 5, 10), QTime(2, 3, 1));
671 QTest::newRow(dataTag: "invalid-0") << QDateTime() << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
672}
673
674void tst_QDateTimeEdit::maximumDateTime()
675{
676 QFETCH(QDateTime, maximumDateTime);
677 QFETCH(QDateTime, expectedMinDateTime);
678
679 testWidget->setMaximumDateTime(maximumDateTime);
680 QCOMPARE(testWidget->maximumDateTime(), expectedMinDateTime);
681}
682
683void tst_QDateTimeEdit::maximumDate_data()
684{
685 QTest::addColumn<QDate>(name: "maximumDate");
686 QTest::addColumn<QDate>(name: "expectedMaxDate");
687
688 QTest::newRow(dataTag: "normal-0") << QDate(2004, 05, 10) << QDate(2004, 5, 10);
689 QTest::newRow(dataTag: "normal-1") << QDate(2002, 03, 15) << QDate(2002, 3, 15);
690 QTest::newRow(dataTag: "normal-2") << QDate(9999, 12, 31) << QDate(9999, 12, 31);
691 QTest::newRow(dataTag: "normal-3") << QDate(1753, 1, 1) << QDate(1753, 1, 1);
692 QTest::newRow(dataTag: "invalid-0") << QDate(0, 0, 0) << QDate(9999, 12, 31);
693}
694
695void tst_QDateTimeEdit::maximumDate()
696{
697 QFETCH(QDate, maximumDate);
698 QFETCH(QDate, expectedMaxDate);
699
700 testWidget->setMaximumDate(maximumDate);
701 QCOMPARE(testWidget->maximumDate(), expectedMaxDate);
702}
703
704void tst_QDateTimeEdit::clearMinimumDate_data()
705{
706 QTest::addColumn<QDate>(name: "minimumDate");
707 QTest::addColumn<bool>(name: "valid");
708 QTest::addColumn<QDate>(name: "expectedMinDateAfterClear");
709
710 QTest::newRow(dataTag: "normal-0") << QDate(2004, 05, 10) << true << QDate(1752, 9, 14);
711 QTest::newRow(dataTag: "normal-1") << QDate(2002, 3, 15) << true << QDate(1752, 9, 14);
712 QTest::newRow(dataTag: "normal-2") << QDate(9999, 12, 31) << true << QDate(1752, 9, 14);
713 QTest::newRow(dataTag: "normal-3") << QDate(1753, 1, 1) << true << QDate(1752, 9, 14);
714 QTest::newRow(dataTag: "invalid-0") << QDate(0, 0, 0) << false << QDate(1752, 9, 14);
715}
716
717void tst_QDateTimeEdit::clearMinimumDate()
718{
719 QFETCH(QDate, minimumDate);
720 QFETCH(bool, valid);
721 QFETCH(QDate, expectedMinDateAfterClear);
722
723 testWidget->setMinimumDate(minimumDate);
724 if (valid)
725 QCOMPARE(testWidget->minimumDate(), minimumDate);
726 testWidget->clearMinimumDate();
727 QCOMPARE(testWidget->minimumDate(), expectedMinDateAfterClear);
728}
729
730void tst_QDateTimeEdit::clearMinimumDateTime_data()
731{
732 QTest::addColumn<QDateTime>(name: "minimumDateTime");
733 QTest::addColumn<bool>(name: "valid");
734 QTest::addColumn<QDateTime>(name: "expectedMinDateTimeAfterClear");
735
736 QTest::newRow(dataTag: "normal-0") << QDateTime(QDate(2004, 05, 10), QTime(12, 12, 12))
737 << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0));
738 QTest::newRow(dataTag: "normal-1") << QDateTime(QDate(2002, 3, 15), QTime(13, 13, 13))
739 << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0));
740 QTest::newRow(dataTag: "normal-2") << QDateTime(QDate(9999, 12, 31), QTime(14, 14, 14))
741 << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0));
742 QTest::newRow(dataTag: "normal-3") << QDateTime(QDate(1753, 1, 1), QTime(15, 15, 15))
743 << true << QDateTime(QDate(1752, 9, 14), QTime(0, 0));
744 QTest::newRow(dataTag: "invalid-0") << QDateTime() << false << QDateTime(QDate(1752, 9, 14), QTime(0, 0));
745 QTest::newRow(dataTag: "old") << QDateTime(QDate(1492, 8, 3), QTime(2, 3, 1)) << true
746 << QDateTime(QDate(1752, 9, 14), QTime(0, 0));
747}
748
749void tst_QDateTimeEdit::clearMinimumDateTime()
750{
751 QFETCH(QDateTime, minimumDateTime);
752 QFETCH(bool, valid);
753 QFETCH(QDateTime, expectedMinDateTimeAfterClear);
754
755 testWidget->setMinimumDateTime(minimumDateTime);
756 if (valid)
757 QCOMPARE(testWidget->minimumDateTime(), minimumDateTime);
758 testWidget->clearMinimumDateTime();
759 QCOMPARE(testWidget->minimumDateTime(), expectedMinDateTimeAfterClear);
760}
761
762void tst_QDateTimeEdit::clearMaximumDateTime_data()
763{
764 QTest::addColumn<QDateTime>(name: "maximumDateTime");
765 QTest::addColumn<bool>(name: "valid");
766 QTest::addColumn<QDateTime>(name: "expectedMinDateTimeAfterClear");
767
768 QTest::newRow(dataTag: "normal-0") << QDateTime(QDate(2004, 05, 10), QTime(12, 12, 12))
769 << true << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
770 QTest::newRow(dataTag: "normal-1") << QDateTime(QDate(2002, 3, 15), QTime(13, 13, 13))
771 << true << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
772 QTest::newRow(dataTag: "normal-2") << QDateTime(QDate(9999, 12, 31), QTime(14, 14, 14))
773 << true << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
774 QTest::newRow(dataTag: "normal-3") << QDateTime(QDate(1753, 1, 1), QTime(15, 15, 15))
775 << true << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
776 QTest::newRow(dataTag: "invalid-0") << QDateTime()
777 << false << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));
778}
779
780void tst_QDateTimeEdit::clearMaximumDateTime()
781{
782 QFETCH(QDateTime, maximumDateTime);
783 QFETCH(bool, valid);
784 QFETCH(QDateTime, expectedMinDateTimeAfterClear);
785
786 testWidget->setMaximumDateTime(maximumDateTime);
787 if (valid)
788 QCOMPARE(testWidget->maximumDateTime(), maximumDateTime);
789 testWidget->clearMaximumDateTime();
790 QCOMPARE(testWidget->maximumDateTime(), expectedMinDateTimeAfterClear);
791}
792
793void tst_QDateTimeEdit::clearMaximumDate_data()
794{
795 QTest::addColumn<QDate>(name: "maximumDate");
796 QTest::addColumn<bool>(name: "valid");
797 QTest::addColumn<QDate>(name: "expectedMaxDateAfterClear");
798
799 QTest::newRow(dataTag: "normal-0") << QDate(2004, 05, 10) << true << QDate(9999, 12, 31);
800 QTest::newRow(dataTag: "normal-1") << QDate(2002, 03, 15) << true << QDate(9999, 12, 31);
801 QTest::newRow(dataTag: "normal-2") << QDate(9999, 12, 31) << true << QDate(9999, 12, 31);
802 QTest::newRow(dataTag: "normal-3") << QDate(2000, 1, 1) << true << QDate(9999, 12, 31);
803 QTest::newRow(dataTag: "invalid-0") << QDate(0, 0, 0) << false << QDate(9999, 12, 31);
804}
805
806void tst_QDateTimeEdit::clearMaximumDate()
807{
808 QFETCH(QDate, maximumDate);
809 QFETCH(bool, valid);
810 QFETCH(QDate, expectedMaxDateAfterClear);
811
812 testWidget->setMaximumDate(maximumDate);
813 if (valid)
814 QCOMPARE(testWidget->maximumDate(), maximumDate);
815 testWidget->clearMaximumDate();
816 QCOMPARE(testWidget->maximumDate(), expectedMaxDateAfterClear);
817}
818
819void tst_QDateTimeEdit::displayFormat_data()
820{
821 QTest::addColumn<QString>(name: "format");
822 QTest::addColumn<bool>(name: "valid");
823 QTest::addColumn<QString>(name: "text");
824 QTest::addColumn<QDateTime>(name: "date");
825
826 const QDateTime dt(QDate(2999, 12, 31), QTime(3, 59, 59, 999));
827
828 QTest::newRow(dataTag: "valid-0") << QString("yyyy MM dd") << true << QString("2999 12 31") << dt;
829 QTest::newRow(dataTag: "valid-1") << QString("dd MM yyyy::ss:mm:hh") << true
830 << QString("31 12 2999::59:59:03") << dt;
831 QTest::newRow(dataTag: "valid-2") << QString("hh-dd-mm-MM-yy") << true << QString("03-31-59-12-99") << dt;
832 QTest::newRow(dataTag: "valid-3") << QString("ddd MM d yyyy::ss:mm:hh") << true
833 << QLocale::system().dayName(2, format: QLocale::ShortFormat) + " 12 31 2999::59:59:03" << dt;
834 QTest::newRow(dataTag: "valid-4") << QString("hh-dd-mm-MM-yyyy") << true << QString("03-31-59-12-2999") << dt;
835 QTest::newRow(dataTag: "invalid-0") << QString("yyyy.MM.yy") << true << QString("2999.12.99") << dt;
836 QTest::newRow(dataTag: "invalid-1") << QString("y") << false << QString() << dt;
837 QTest::newRow(dataTag: "invalid-2") << QString("") << false << QString() << dt;
838 QTest::newRow(dataTag: "quoted-1") << QString("'Midday is at:' dd") << true << QString("Midday is at: 31") << dt;
839 QTest::newRow(dataTag: "leading1") << QString("h:hh:hhh") << true << QString("3:03:033") << dt;
840 QTest::newRow(dataTag: "H1") << QString("HH:hh:ap") << true << QString("03:03:am") << dt;
841 QTest::newRow(dataTag: "H2") << QString("HH:hh:ap") << true << QString("23:11:pm")
842 << QDateTime(dt.date(), QTime(23, 0, 0));
843}
844
845void tst_QDateTimeEdit::displayFormat()
846{
847 QFETCH(QString, format);
848 QFETCH(bool, valid);
849 QFETCH(QString, text);
850 QFETCH(QDateTime, date);
851
852 testWidget->setDateTime(date);
853
854 QString compareFormat = format;
855 if (!valid)
856 compareFormat = testWidget->displayFormat();
857 testWidget->setDisplayFormat(format);
858 QCOMPARE(testWidget->displayFormat(), compareFormat);
859 if (valid)
860 QCOMPARE(testWidget->text(), text);
861}
862
863void tst_QDateTimeEdit::selectAndScrollWithKeys()
864{
865#ifdef Q_OS_MAC
866 QSKIP("QTBUG-23674");
867 return;
868#endif
869
870 qApp->setActiveWindow(testWidget);
871 testWidget->setDate(QDate(2004, 05, 11));
872 testWidget->setDisplayFormat("dd/MM/yyyy");
873 testWidget->show();
874#ifdef Q_OS_MAC
875 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
876#else
877 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
878#endif
879 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
880 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("1"));
881 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
882 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
883 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
884 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/"));
885 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
886 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/0"));
887 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
888 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05"));
889 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
890 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/"));
891 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
892 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2"));
893 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
894 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/20"));
895 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
896 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/200"));
897 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
898 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004"));
899 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
900 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004"));
901
902 // Now the year part should be selected
903 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
904 QCOMPARE(testWidget->date(), QDate(2005, 5, 11));
905 QCOMPARE(testWidget->currentSection(), QDateTimeEdit::YearSection);
906 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2005"));
907 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
908 QCOMPARE(testWidget->date(), QDate(2004, 5, 11));
909 QCOMPARE(testWidget->currentSection(), QDateTimeEdit::YearSection);
910 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004"));
911
912
913#ifdef Q_OS_MAC
914 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
915#else
916 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
917#endif
918 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
919 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("4"));
920 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
921 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("04"));
922 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
923 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("004"));
924 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
925 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004"));
926 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
927 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("/2004"));
928 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
929 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("5/2004"));
930 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
931 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05/2004"));
932 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
933 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("/05/2004"));
934 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
935 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("1/05/2004"));
936 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
937 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004"));
938 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
939 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11/05/2004"));
940#ifdef Q_OS_MAC
941 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
942#else
943 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
944#endif
945
946 // Now the day part should be selected
947 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
948 QCOMPARE(testWidget->date(), QDate(2004, 5, 12));
949 QCOMPARE(testWidget->currentSection(), QDateTimeEdit::DaySection);
950 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("12"));
951 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
952 QCOMPARE(testWidget->date(), QDate(2004, 5, 11));
953 QCOMPARE(testWidget->currentSection(), QDateTimeEdit::DaySection);
954 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
955
956#ifdef Q_OS_MAC
957 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
958#else
959 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
960#endif
961
962 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
963 QTest::keyClick(widget: testWidget, key: Qt::Key_Right, modifier: Qt::ShiftModifier);
964 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
965 // Now the day part should be selected
966 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
967 QCOMPARE(testWidget->date(), QDate(2004, 05, 12));
968}
969
970void tst_QDateTimeEdit::backspaceKey()
971{
972 qApp->setActiveWindow(testWidget);
973 testWidget->setDate(QDate(2004, 05, 11));
974 testWidget->setDisplayFormat("d/MM/yyyy");
975 testWidget->show();
976#ifdef Q_OS_MAC
977 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
978#else
979 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
980#endif
981 QCOMPARE(testWidget->text(), QString("11/05/2004"));
982 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
983#ifdef Q_OS_MAC
984 QEXPECT_FAIL("", "QTBUG-23674", Abort);
985#endif
986 QCOMPARE(testWidget->text(), QString("11/05/200"));
987 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
988 QCOMPARE(testWidget->text(), QString("11/05/20"));
989 // Check that moving into another field reverts it
990 for (int i=0;i<3;i++)
991 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
992 QCOMPARE(testWidget->text(), QString("11/05/2004"));
993#ifdef Q_OS_MAC
994 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
995#else
996 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
997#endif
998 for (int i=0;i<4;i++)
999 QTest::keyClick(widget: testWidget, key: Qt::Key_Left, modifier: Qt::ShiftModifier);
1000
1001 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1002 QCOMPARE(testWidget->text(), QString("11/05/"));
1003 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
1004 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1005 QCOMPARE(testWidget->text(), QString("11/0/2004"));
1006 testWidget->interpretText();
1007#ifdef Q_OS_MAC
1008 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
1009#else
1010 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
1011#endif
1012 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1013 QCOMPARE(testWidget->text(), QString("11/05/200"));
1014 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1015 QCOMPARE(testWidget->text(), QString("11/05/20"));
1016 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1017 QCOMPARE(testWidget->text(), QString("11/05/2"));
1018 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1019 QCOMPARE(testWidget->text(), QString("11/05/"));
1020 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
1021 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1022 QCOMPARE(testWidget->text(), QString("11/0/2004"));
1023 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1024 QCOMPARE(testWidget->text(), QString("11//2004"));
1025 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
1026 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1027 QCOMPARE(testWidget->text(), QString("1/05/2004"));
1028 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1029 QCOMPARE(testWidget->text(), QString("/05/2004"));
1030 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1031 QCOMPARE(testWidget->text(), QString("/05/2004"));
1032 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1033 QCOMPARE(testWidget->text(), QString("1/05/2004"));
1034}
1035
1036void tst_QDateTimeEdit::deleteKey()
1037{
1038 qApp->setActiveWindow(testWidget);
1039 testWidget->setDate(QDate(2004, 05, 11));
1040 testWidget->setDisplayFormat("d/MM/yyyy");
1041#ifdef Q_OS_MAC
1042 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
1043#else
1044 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
1045#endif
1046 QTest::keyClick(widget: testWidget, key: Qt::Key_Delete);
1047 QCOMPARE(testWidget->text(), QString("1/05/2004"));
1048 QTest::keyClick(widget: testWidget, key: Qt::Key_Delete);
1049 QCOMPARE(testWidget->text(), QString("/05/2004"));
1050 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
1051 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
1052 QCOMPARE(testWidget->text(), QString("1/05/2004"));
1053}
1054
1055void tst_QDateTimeEdit::tabKeyNavigation()
1056{
1057 qApp->setActiveWindow(testWidget);
1058 testWidget->setDate(QDate(2004, 05, 11));
1059 testWidget->setDisplayFormat("dd/MM/yyyy");
1060 testWidget->show();
1061 testWidget->setCurrentSection(QDateTimeEdit::DaySection);
1062
1063 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1064 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05"));
1065 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1066 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004"));
1067 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab, modifier: Qt::ShiftModifier);
1068 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05"));
1069 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab, modifier: Qt::ShiftModifier);
1070 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
1071}
1072
1073void tst_QDateTimeEdit::tabKeyNavigationWithPrefix()
1074{
1075 qApp->setActiveWindow(testWidget);
1076 testWidget->setDate(QDate(2004, 05, 11));
1077 testWidget->setDisplayFormat("prefix dd/MM/yyyy");
1078
1079 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1080 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
1081 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1082 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05"));
1083 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1084 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004"));
1085 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab, modifier: Qt::ShiftModifier);
1086 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05"));
1087 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab, modifier: Qt::ShiftModifier);
1088 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
1089}
1090
1091void tst_QDateTimeEdit::tabKeyNavigationWithSuffix()
1092{
1093 qApp->setActiveWindow(testWidget);
1094 testWidget->setDate(QDate(2004, 05, 11));
1095 testWidget->setDisplayFormat("dd/MM/yyyy 'suffix'");
1096
1097 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1098 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05"));
1099 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1100 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2004"));
1101 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab, modifier: Qt::ShiftModifier);
1102 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("05"));
1103 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab, modifier: Qt::ShiftModifier);
1104 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
1105}
1106
1107void tst_QDateTimeEdit::enterKey()
1108{
1109 qApp->setActiveWindow(testWidget);
1110 testWidget->setDate(QDate(2004, 5, 11));
1111 testWidget->setDisplayFormat("prefix d/MM/yyyy 'suffix'");
1112 testWidget->lineEdit()->setFocus();
1113
1114#ifdef Q_OS_MAC
1115 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
1116#else
1117 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
1118#endif
1119 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1120#ifdef Q_OS_MAC
1121 QEXPECT_FAIL("", "QTBUG-23674", Abort);
1122#endif
1123 QVERIFY(!testWidget->lineEdit()->hasSelectedText());
1124#ifdef Q_OS_MAC
1125 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
1126#else
1127 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
1128#endif
1129 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1130 QVERIFY(!testWidget->lineEdit()->hasSelectedText());
1131#ifdef Q_OS_MAC
1132 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
1133#else
1134 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
1135#endif
1136 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
1137 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1138 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
1139 QTest::keyClick(widget: testWidget, key: Qt::Key_1);
1140 QTest::keyClick(widget: testWidget, key: Qt::Key_5);
1141
1142 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
1143 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
1144
1145 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1146 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("15"));
1147 QCOMPARE(testWidget->date(), QDate(2004, 5, 15));
1148
1149 QTest::keyClick(widget: testWidget, key: Qt::Key_9);
1150 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab, modifier: Qt::ShiftModifier);
1151 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1152 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("9"));
1153 QCOMPARE(testWidget->date(), QDate(2004, 5, 9));
1154
1155 QTest::keyClick(widget: testWidget, key: Qt::Key_0);
1156 QTest::keyClick(widget: testWidget, key: Qt::Key_0);
1157 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1158 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("9"));
1159 QCOMPARE(testWidget->date(), QDate(2004, 5, 9));
1160
1161 // Current behaviour is that pressing the Enter key in a QDateTimeEdit
1162 // causes the dateChanged() signal to be emitted, even if the date
1163 // wasn't actually changed. While this behaviour is questionable,
1164 // we include this test so a change to the behaviour can't go unnoticed.
1165 QSignalSpy enterSpy(testWidget, SIGNAL(dateChanged(QDate)));
1166 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1167 QCOMPARE(enterSpy.count(), 1);
1168 QVariantList list = enterSpy.takeFirst();
1169 QCOMPARE(list.at(0).toDate(), QDate(2004, 5, 9));
1170}
1171
1172void tst_QDateTimeEdit::specialValueText()
1173{
1174 testWidget->setDisplayFormat("dd/MM/yyyy");
1175 testWidget->setDateRange(min: QDate(2000, 1, 1), max: QDate(2001, 1, 1));
1176 testWidget->setDate(QDate(2000, 1, 2));
1177 testWidget->setSpecialValueText("fOo");
1178 testWidget->setCurrentSection(QDateTimeEdit::DaySection);
1179 QCOMPARE(testWidget->date(), QDate(2000, 1, 2));
1180 QCOMPARE(testWidget->text(), QString("02/01/2000"));
1181 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
1182 QCOMPARE(testWidget->date(), QDate(2000, 1, 1));
1183 QCOMPARE(testWidget->text(), QString("fOo"));
1184 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
1185 QCOMPARE(testWidget->date(), QDate(2000, 1, 1));
1186 QCOMPARE(testWidget->text(), QString("fOo"));
1187 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
1188 QCOMPARE(testWidget->date(), QDate(2000, 1, 2));
1189 QCOMPARE(testWidget->text(), QString("02/01/2000"));
1190 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
1191 QCOMPARE(testWidget->date(), QDate(2000, 1, 1));
1192 QCOMPARE(testWidget->text(), QString("fOo"));
1193
1194#ifdef Q_OS_MAC
1195 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
1196#else
1197 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
1198#endif
1199 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
1200 QCOMPARE(testWidget->date(), QDate(2000, 1, 2));
1201 QCOMPARE(testWidget->text(), QString("02/01/2000"));
1202 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
1203 QCOMPARE(testWidget->text(), QString("fOo"));
1204
1205#ifdef Q_OS_MAC
1206 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
1207#else
1208 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
1209#endif
1210 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1211 QCOMPARE(testWidget->text(), QString("fO"));
1212 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1213 QCOMPARE(testWidget->text(), QString("f"));
1214 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
1215 QCOMPARE(testWidget->text(), QString());
1216 QTest::keyClick(widget: testWidget, key: Qt::Key_F);
1217 QCOMPARE(testWidget->text(), QString("f"));
1218 QTest::keyClick(widget: testWidget, key: Qt::Key_O); // will automatically uppercase
1219 QCOMPARE(testWidget->text(), QString("fO"));
1220 QTest::keyClick(widget: testWidget, key: Qt::Key_O);
1221 QCOMPARE(testWidget->text(), QString("fOo"));
1222}
1223
1224void tst_QDateTimeEdit::setRange_data()
1225{
1226 QTest::addColumn<QTime>(name: "minTime");
1227 QTest::addColumn<QTime>(name: "maxTime");
1228 QTest::addColumn<QDate>(name: "minDate");
1229 QTest::addColumn<QDate>(name: "maxDate");
1230 QTest::addColumn<QDateTime>(name: "expectedMin");
1231 QTest::addColumn<QDateTime>(name: "expectedMax");
1232
1233 const QDate cdt = QDate::currentDate();
1234
1235 QTest::newRow(dataTag: "data0") << QTime(0, 0) << QTime(14, 12, 0)
1236 << cdt << cdt
1237 << QDateTime(cdt, QTime(0, 0))
1238 << QDateTime(cdt, QTime(14, 12, 0));
1239
1240 QTest::newRow(dataTag: "data1") << QTime(10, 0) << QTime(1, 12, 0) << cdt.addDays(days: -1)
1241 << cdt
1242 << QDateTime(cdt.addDays(days: -1), QTime(10, 0))
1243 << QDateTime(cdt, QTime(1, 12, 0));
1244}
1245
1246void tst_QDateTimeEdit::setRange()
1247{
1248 QFETCH(QTime, minTime);
1249 QFETCH(QTime, maxTime);
1250 QFETCH(QDate, minDate);
1251 QFETCH(QDate, maxDate);
1252 QFETCH(QDateTime, expectedMin);
1253 QFETCH(QDateTime, expectedMax);
1254 testWidget->hide();
1255
1256 {
1257 QDateTimeEdit dte(0);
1258 dte.setTimeRange(min: minTime, max: maxTime);
1259 QCOMPARE(dte.minimumTime(), expectedMin.time());
1260 QCOMPARE(dte.maximumTime(), expectedMax.time());
1261 dte.setDateRange(min: minDate, max: maxDate);
1262 QCOMPARE(dte.minimumDate(), expectedMin.date());
1263 QCOMPARE(dte.minimumDateTime(), expectedMin);
1264 QCOMPARE(dte.maximumDate(), expectedMax.date());
1265 QCOMPARE(dte.maximumDateTime(), expectedMax);
1266 QCOMPARE(dte.minimumTime(), expectedMin.time());
1267 QCOMPARE(dte.maximumTime(), expectedMax.time());
1268 dte.setDateTimeRange(min: QDateTime(minDate, minTime), max: QDateTime(maxDate, maxTime));
1269 QCOMPARE(dte.minimumDate(), expectedMin.date());
1270 QCOMPARE(dte.minimumDateTime(), expectedMin);
1271 QCOMPARE(dte.maximumDate(), expectedMax.date());
1272 QCOMPARE(dte.maximumDateTime(), expectedMax);
1273 QCOMPARE(dte.minimumTime(), expectedMin.time());
1274 QCOMPARE(dte.maximumTime(), expectedMax.time());
1275 }
1276 {
1277
1278 QDateTimeEdit dte2(0);
1279 dte2.setDateRange(min: minDate, max: maxDate);
1280 dte2.setTimeRange(min: minTime, max: maxTime);
1281
1282 QCOMPARE(dte2.minimumDate(), expectedMin.date());
1283 QCOMPARE(dte2.maximumDate(), expectedMax.date());
1284 QCOMPARE(dte2.minimumTime(), expectedMin.time());
1285 QCOMPARE(dte2.maximumTime(), expectedMax.time());
1286 }
1287
1288 {
1289 QDateTimeEdit dte3(0);
1290 dte3.setMinimumTime(minTime);
1291 dte3.setMaximumTime(maxTime);
1292 dte3.setMinimumDate(minDate);
1293 dte3.setMaximumDate(maxDate);
1294
1295 QCOMPARE(dte3.minimumDate(), expectedMin.date());
1296 QCOMPARE(dte3.maximumDate(), expectedMax.date());
1297 QCOMPARE(dte3.minimumTime(), expectedMin.time());
1298 QCOMPARE(dte3.maximumTime(), expectedMax.time());
1299 }
1300
1301 {
1302 QDateTimeEdit dte4(0);
1303 dte4.setMinimumDate(minDate);
1304 dte4.setMaximumDate(maxDate);
1305 dte4.setMinimumTime(minTime);
1306 dte4.setMaximumTime(maxTime);
1307
1308 QCOMPARE(dte4.minimumDate(), expectedMin.date());
1309 QCOMPARE(dte4.maximumDate(), expectedMax.date());
1310 QCOMPARE(dte4.minimumTime(), expectedMin.time());
1311 QCOMPARE(dte4.maximumTime(), expectedMax.time());
1312 }
1313}
1314
1315/*
1316 Test that a user can input a date into a ranged QDateTimeEdit or QDateEdit
1317 where a part of date is larger than the respective part of the maximum, or
1318 smaller than the respective part of the minimum of the range.
1319
1320 This test is expected to fail unless keyboard tracking of the edit is set
1321 to off. Otherwise the changed-signal would be emitted with values outside
1322 of the allowed range as the user types.
1323*/
1324void tst_QDateTimeEdit::editingRanged_data()
1325{
1326 QTest::addColumn<QDate>(name: "minDate");
1327 QTest::addColumn<QTime>(name: "minTime");
1328 QTest::addColumn<QDate>(name: "maxDate");
1329 QTest::addColumn<QTime>(name: "maxTime");
1330 QTest::addColumn<QString>(name: "userInput");
1331 QTest::addColumn<QDateTime>(name: "expected");
1332
1333 QTest::addRow(format: "trivial")
1334 << QDate(2010, 1, 1) << QTime(9, 0)
1335 << QDate(2011, 12, 31) << QTime(16, 0)
1336 << QString::fromLatin1(str: "311220101600")
1337 << QDateTime(QDate(2010, 12, 31), QTime(16, 0));
1338
1339 QTest::addRow(format: "data0")
1340 << QDate(2010, 12, 30) << QTime(16, 0)
1341 << QDate(2011, 1, 2) << QTime(9, 0)
1342 << QString::fromLatin1(str: "311220102359")
1343 << QDateTime(QDate(2010, 12, 31), QTime(23, 59));
1344
1345 QTest::addRow(format: "data1")
1346 << QDate(2010, 12, 30) << QTime(16, 0)
1347 << QDate(2011, 1, 2) << QTime(9, 0)
1348 << QString::fromLatin1(str: "010120111823")
1349 << QDateTime(QDate(2011, 1, 1), QTime(18, 23));
1350
1351 QTest::addRow(format: "Out of range")
1352 << QDate(2010, 12, 30) << QTime(16, 0)
1353 << QDate(2011, 1, 2) << QTime(9, 0)
1354 << QString::fromLatin1(str: "090920111823")
1355 << QDateTime(QDate(2011, 1, 2), QTime(9, 0));
1356
1357 QTest::addRow(format: "only date")
1358 << QDate(2010, 12, 30) << QTime()
1359 << QDate(2011, 1, 2) << QTime()
1360 << QString::fromLatin1(str: "01012011")
1361 << QDateTime(QDate(2011, 1, 1), QTime());
1362}
1363
1364void tst_QDateTimeEdit::editingRanged()
1365{
1366 QFETCH(QDate, minDate);
1367 QFETCH(QTime, minTime);
1368 QFETCH(QDate, maxDate);
1369 QFETCH(QTime, maxTime);
1370 QFETCH(QString, userInput);
1371 QFETCH(QDateTime, expected);
1372
1373 QScopedPointer<QDateTimeEdit> edit;
1374 if (minTime.isValid()) {
1375 edit.reset(other: new QDateTimeEdit);
1376 edit->setDisplayFormat("dd.MM.yyyy hh:mm");
1377 edit->setDateTimeRange(min: QDateTime(minDate, minTime), max: QDateTime(maxDate, maxTime));
1378 } else {
1379 edit.reset(other: new QDateEdit);
1380 edit->setDisplayFormat("dd.MM.yyyy");
1381 edit->setDateRange(min: minDate, max: maxDate);
1382 }
1383
1384 int callCount = 0;
1385 connect(sender: edit.get(), signal: &QDateTimeEdit::dateTimeChanged, slot: [&](const QDateTime &dateTime) {
1386 ++callCount;
1387 if (minTime.isValid()) {
1388 QVERIFY(dateTime >= QDateTime(minDate, minTime));
1389 QVERIFY(dateTime <= QDateTime(maxDate, maxTime));
1390 } else {
1391 QVERIFY(dateTime.date() >= minDate);
1392 QVERIFY(dateTime.date() <= maxDate);
1393 }
1394 });
1395
1396 edit->show();
1397 QApplication::setActiveWindow(edit.get());
1398 if (!QTest::qWaitForWindowActive(widget: edit.get()))
1399 QSKIP("Failed to make window active, aborting");
1400 edit->setFocus();
1401
1402 // with keyboard tracking, never get a signal with an out-of-range value
1403 edit->setKeyboardTracking(true);
1404 QTest::keyClicks(widget: edit.get(), sequence: userInput);
1405 QTest::keyClick(widget: edit.get(), key: Qt::Key_Return);
1406 QVERIFY(callCount > 0);
1407
1408 // QDateTimeEdit blocks these dates from being entered - see QTBUG-65
1409 QEXPECT_FAIL("data0", "Can't enter this date", Continue);
1410 QEXPECT_FAIL("data1", "Can't enter this date", Continue);
1411 QEXPECT_FAIL("Out of range", "Can't enter this date", Continue);
1412 QEXPECT_FAIL("only date", "Can't enter this date", Continue);
1413 QCOMPARE(edit->dateTime(), expected);
1414
1415 // reset
1416 edit->clearFocus();
1417 edit->setFocus();
1418 callCount = 0;
1419
1420 edit->setKeyboardTracking(false);
1421 QTest::keyClicks(widget: edit.get(), sequence: userInput);
1422 QTest::keyClick(widget: edit.get(), key: Qt::Key_Return);
1423 QCOMPARE(edit->dateTime(), expected);
1424 QCOMPARE(callCount, 1);
1425}
1426
1427void tst_QDateTimeEdit::wrappingTime_data()
1428{
1429 QTest::addColumn<bool>(name: "startWithMin");
1430 QTest::addColumn<QTime>(name: "minimumTime");
1431 QTest::addColumn<QTime>(name: "maximumTime");
1432 QTest::addColumn<uint>(name: "section");
1433 QTest::addColumn<QTime>(name: "newTime");
1434
1435 QTest::newRow(dataTag: "data0") << false << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::HourSection
1436 << QTime(0,2,2);
1437 QTest::newRow(dataTag: "data1") << true << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::HourSection
1438 << QTime(2,0,0);
1439 QTest::newRow(dataTag: "data2") << false << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::MinuteSection
1440 << QTime(2,0,2);
1441 QTest::newRow(dataTag: "data3") << true << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::MinuteSection
1442 << QTime(0,59,0);
1443 QTest::newRow(dataTag: "data4") << false << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::SecondSection
1444 << QTime(2,2,0);
1445 QTest::newRow(dataTag: "data5") << true << QTime(0,0,0) << QTime(2,2,2) << (uint)QDateTimeEdit::SecondSection
1446 << QTime(0,0,59);
1447 QTest::newRow(dataTag: "data6") << false << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::HourSection
1448 << QTime(1,22,22);
1449 QTest::newRow(dataTag: "data7") << true << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::HourSection
1450 << QTime(22,1,1);
1451 QTest::newRow(dataTag: "data8") << false << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::MinuteSection
1452 << QTime(22,0,22);
1453 QTest::newRow(dataTag: "data9") << true << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::MinuteSection
1454 << QTime(1,59,1);
1455 QTest::newRow(dataTag: "data10") << false << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::SecondSection
1456 << QTime(22,22,0);
1457 QTest::newRow(dataTag: "data11") << true << QTime(1,1,1) << QTime(22,22,22) << (uint)QDateTimeEdit::SecondSection
1458 << QTime(1,1,59);
1459 QTest::newRow(dataTag: "data12") << false << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::HourSection
1460 << QTime(1,2,1);
1461 QTest::newRow(dataTag: "data13") << true << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::HourSection
1462 << QTime(1,1,1);
1463 QTest::newRow(dataTag: "data14") << false << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::MinuteSection
1464 << QTime(1,1,1);
1465 QTest::newRow(dataTag: "data15") << true << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::MinuteSection
1466 << QTime(1,2,1);
1467 QTest::newRow(dataTag: "data16") << false << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::SecondSection
1468 << QTime(1,2,0);
1469 QTest::newRow(dataTag: "data17") << true << QTime(1,1,1) << QTime(1,2,1) << (uint)QDateTimeEdit::SecondSection
1470 << QTime(1,1,59);
1471}
1472
1473void tst_QDateTimeEdit::wrappingTime()
1474{
1475 QFETCH(bool, startWithMin);
1476 QFETCH(QTime, minimumTime);
1477 QFETCH(QTime, maximumTime);
1478 QFETCH(uint, section);
1479 QFETCH(QTime, newTime);
1480
1481 testWidget->setDisplayFormat("hh:mm:ss");
1482 testWidget->setMinimumTime(minimumTime);
1483 testWidget->setMaximumTime(maximumTime);
1484 testWidget->setWrapping(true);
1485 testWidget->setCurrentSection((QDateTimeEdit::Section)section);
1486 if (startWithMin) {
1487 testWidget->setTime(minimumTime);
1488 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
1489 } else {
1490 testWidget->setTime(maximumTime);
1491 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
1492 }
1493 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
1494 QCOMPARE(testWidget->time(), newTime);
1495}
1496
1497void tst_QDateTimeEdit::userKeyPress_Time_data()
1498{
1499 QTest::addColumn<bool>(name: "ampm");
1500 QTest::addColumn<QTestEventList>(name: "keys");
1501 QTest::addColumn<QTime>(name: "expected_time");
1502
1503 // ***************** test the hours ***************
1504
1505 // use up/down keys to change hour in 12 h mode
1506 {
1507 QTestEventList keys;
1508 keys.addKeyClick( qtKey: Qt::Key_Down );
1509 QTime expected( 10, 0, 0 );
1510 QTest::newRow( dataTag: "data0" ) << bool(true) << keys << expected;
1511 }
1512 {
1513 QTestEventList keys;
1514 for (uint i=0; i<5; i++)
1515 keys.addKeyClick( qtKey: Qt::Key_Down );
1516 QTime expected( 6, 0, 0 );
1517 QTest::newRow( dataTag: "data1" ) << bool(true) << keys << expected;
1518 }
1519 {
1520 QTestEventList keys;
1521 for (uint i=0; i<10; i++)
1522 keys.addKeyClick( qtKey: Qt::Key_Down );
1523 QTime expected( 1, 0, 0 );
1524 QTest::newRow( dataTag: "data2" ) << bool(true) << keys << expected;
1525 }
1526 {
1527 QTestEventList keys;
1528 for (uint i=0; i<12; i++)
1529 keys.addKeyClick( qtKey: Qt::Key_Down );
1530 QTime expected( 23, 0, 0 );
1531 QTest::newRow( dataTag: "data3" ) << bool(true) << keys << expected;
1532 }
1533 {
1534 QTestEventList keys;
1535 keys.addKeyClick( qtKey: Qt::Key_Up );
1536 QTime expected( 12, 0, 0 );
1537 QTest::newRow( dataTag: "data4" ) << bool(true) << keys << expected;
1538 }
1539 {
1540 QTestEventList keys;
1541 for (uint i=0; i<2; i++)
1542 keys.addKeyClick( qtKey: Qt::Key_Up );
1543 QTime expected( 13, 0, 0 );
1544 QTest::newRow( dataTag: "data5" ) << bool(true) << keys << expected;
1545 }
1546
1547 // use up/down keys to change hour in 24 h mode
1548 {
1549 QTestEventList keys;
1550 keys.addKeyClick( qtKey: Qt::Key_Down );
1551 QTime expected( 10, 0, 0 );
1552 QTest::newRow( dataTag: "data6" ) << bool(false) << keys << expected;
1553 }
1554 {
1555 QTestEventList keys;
1556 for (uint i=0; i<5; i++)
1557 keys.addKeyClick( qtKey: Qt::Key_Down );
1558 QTime expected( 6, 0, 0 );
1559 QTest::newRow( dataTag: "data7" ) << bool(false) << keys << expected;
1560 }
1561 {
1562 QTestEventList keys;
1563 for (uint i=0; i<10; i++)
1564 keys.addKeyClick( qtKey: Qt::Key_Down );
1565 QTime expected( 1, 0, 0 );
1566 QTest::newRow( dataTag: "data8" ) << bool(false) << keys << expected;
1567 }
1568 {
1569 QTestEventList keys;
1570 for (uint i=0; i<12; i++)
1571 keys.addKeyClick( qtKey: Qt::Key_Down );
1572 QTime expected( 23, 0, 0 );
1573 QTest::newRow( dataTag: "data9" ) << bool(false) << keys << expected;
1574 }
1575 {
1576 QTestEventList keys;
1577 keys.addKeyClick( qtKey: Qt::Key_Up );
1578 QTime expected( 12, 0, 0 );
1579 QTest::newRow( dataTag: "data10" ) << bool(false) << keys << expected;
1580 }
1581 {
1582 QTestEventList keys;
1583 for (uint i=0; i<2; i++)
1584 keys.addKeyClick( qtKey: Qt::Key_Up );
1585 QTime expected( 13, 0, 0 );
1586 QTest::newRow( dataTag: "data11" ) << bool(false) << keys << expected;
1587 }
1588
1589 // enter a one digit valid hour
1590 {
1591 QTestEventList keys;
1592 keys.addKeyClick( ascii: '5' );
1593 QTime expected( 5, 0, 0 );
1594 QTest::newRow( dataTag: "data12" ) << bool(true) << keys << expected;
1595 }
1596
1597 // entering a two digit valid hour
1598 {
1599 QTestEventList keys;
1600 keys.addKeyClick( ascii: '1' );
1601 keys.addKeyClick( ascii: '1' );
1602 QTime expected( 11, 0, 0 );
1603 QTest::newRow( dataTag: "data13" ) << bool(true) << keys << expected;
1604 }
1605
1606 // entering an invalid hour
1607 {
1608 QTestEventList keys;
1609 keys.addKeyClick( ascii: '2' );
1610 // the '5' creates an invalid hour (25) so it must be ignored
1611 keys.addKeyClick( ascii: '5' );
1612 QTime expected( 2, 0, 0 );
1613 QTest::newRow( dataTag: "data14" ) << bool(true) << keys << expected;
1614 }
1615
1616 // enter a value, in hour which causes a field change
1617 {
1618 QTestEventList keys;
1619 keys.addKeyClick( ascii: '0' );
1620 keys.addKeyClick( ascii: '2' );
1621 keys.addKeyClick( ascii: '1' );
1622 QTime expected( 2, 1, 0 );
1623 QTest::newRow( dataTag: "data15" ) << bool(true) << keys << expected;
1624 }
1625
1626 // enter a one digit valid hour in 24 h mode
1627 {
1628 QTestEventList keys;
1629 keys.addKeyClick( ascii: '5' );
1630 QTime expected( 5, 0, 0 );
1631 QTest::newRow( dataTag: "data16" ) << bool(false) << keys << expected;
1632 }
1633
1634 // enter a two digit valid hour in 24 h mode
1635 {
1636 QTestEventList keys;
1637 keys.addKeyClick( ascii: '1' );
1638 keys.addKeyClick( ascii: '1' );
1639 QTime expected( 11, 0, 0 );
1640 QTest::newRow( dataTag: "data17" ) << bool(false) << keys << expected;
1641 }
1642
1643 // enter a two digit valid hour (>12) in 24 h mode
1644 {
1645 QTestEventList keys;
1646 keys.addKeyClick( ascii: '1' );
1647 keys.addKeyClick( ascii: '5' );
1648 QTime expected( 15, 0, 0 );
1649 QTest::newRow( dataTag: "data18" ) << bool(false) << keys << expected;
1650 }
1651
1652 // enter a two digit valid hour (>20) in 24 h mode
1653 {
1654 QTestEventList keys;
1655 keys.addKeyClick( ascii: '2' );
1656 keys.addKeyClick( ascii: '1' );
1657 QTime expected( 21, 0, 0 );
1658 QTest::newRow( dataTag: "data19" ) << bool(false) << keys << expected;
1659 }
1660
1661 // enter a two digit invalid hour (>23) in 24 h mode
1662 {
1663 QTestEventList keys;
1664 keys.addKeyClick( ascii: '2' );
1665 keys.addKeyClick( ascii: '4' );
1666 QTime expected( 2, 0, 0 );
1667 QTest::newRow( dataTag: "data20" ) << bool(false) << keys << expected;
1668 }
1669
1670 // ***************** test the minutes ***************
1671
1672 // use up/down keys to change the minutes in 12 hour mode
1673 { // test a valid value
1674 QTestEventList keys;
1675 keys.addKeyClick( qtKey: Qt::Key_Tab );
1676 for (uint i=0; i<2; i++)
1677 keys.addKeyClick( qtKey: Qt::Key_Up );
1678 QTime expected( 11, 2, 0 );
1679 QTest::newRow( dataTag: "data21" ) << bool(true) << keys << expected;
1680 }
1681 { // test a valid value
1682 QTestEventList keys;
1683 keys.addKeyClick( qtKey: Qt::Key_Tab );
1684 for (uint i=0; i<16; i++)
1685 keys.addKeyClick( qtKey: Qt::Key_Up );
1686 QTime expected( 11, 16, 0 );
1687 QTest::newRow( dataTag: "data22" ) << bool(true) << keys << expected;
1688 }
1689 { // test maximum value
1690 QTestEventList keys;
1691 keys.addKeyClick( qtKey: Qt::Key_Tab );
1692 for (uint i=0; i<59; i++)
1693 keys.addKeyClick( qtKey: Qt::Key_Up );
1694 QTime expected( 11, 59, 0 );
1695 QTest::newRow( dataTag: "data23" ) << bool(true) << keys << expected;
1696 }
1697 { // test 'overflow'
1698 QTestEventList keys;
1699 keys.addKeyClick( qtKey: Qt::Key_Tab );
1700 for (uint i=0; i<60; i++)
1701 keys.addKeyClick( qtKey: Qt::Key_Up );
1702 QTime expected( 11, 0, 0 );
1703 QTest::newRow( dataTag: "data24" ) << bool(true) << keys << expected;
1704 }
1705 { // test 'underflow'
1706 QTestEventList keys;
1707 keys.addKeyClick( qtKey: Qt::Key_Tab );
1708 keys.addKeyClick( qtKey: Qt::Key_Down );
1709 QTime expected( 11, 59, 0 );
1710 QTest::newRow( dataTag: "data25" ) << bool(true) << keys << expected;
1711 }
1712 { // test valid value
1713 QTestEventList keys;
1714 keys.addKeyClick( qtKey: Qt::Key_Tab );
1715 for (uint i=0; i<2; i++)
1716 keys.addKeyClick( qtKey: Qt::Key_Down );
1717 QTime expected( 11, 58, 0 );
1718 QTest::newRow( dataTag: "data26" ) << bool(true) << keys << expected;
1719 }
1720
1721 // use up/down keys to change the minutes in 24 hour mode
1722
1723 { // test a valid value
1724 QTestEventList keys;
1725 keys.addKeyClick( qtKey: Qt::Key_Tab );
1726 for (uint i=0; i<2; i++)
1727 keys.addKeyClick( qtKey: Qt::Key_Up );
1728 QTime expected( 11, 2, 0 );
1729 QTest::newRow( dataTag: "data27" ) << bool(false) << keys << expected;
1730 }
1731 { // test a valid value
1732 QTestEventList keys;
1733 keys.addKeyClick( qtKey: Qt::Key_Tab );
1734 for (uint i=0; i<16; i++)
1735 keys.addKeyClick( qtKey: Qt::Key_Up );
1736 QTime expected( 11, 16, 0 );
1737 QTest::newRow( dataTag: "data28" ) << bool(false) << keys << expected;
1738 }
1739 { // test maximum value
1740 QTestEventList keys;
1741 keys.addKeyClick( qtKey: Qt::Key_Tab );
1742 for (uint i=0; i<59; i++)
1743 keys.addKeyClick( qtKey: Qt::Key_Up );
1744 QTime expected( 11, 59, 0 );
1745 QTest::newRow( dataTag: "data29" ) << bool(false) << keys << expected;
1746 }
1747 { // test 'overflow'
1748 QTestEventList keys;
1749 keys.addKeyClick( qtKey: Qt::Key_Tab );
1750 for (uint i=0; i<60; i++)
1751 keys.addKeyClick( qtKey: Qt::Key_Up );
1752 QTime expected( 11, 0, 0 );
1753 QTest::newRow( dataTag: "data30" ) << bool(false) << keys << expected;
1754 }
1755 { // test 'underflow'
1756 QTestEventList keys;
1757 keys.addKeyClick( qtKey: Qt::Key_Tab );
1758 keys.addKeyClick( qtKey: Qt::Key_Down );
1759 QTime expected( 11, 59, 0 );
1760 QTest::newRow( dataTag: "data31" ) << bool(false) << keys << expected;
1761 }
1762 { // test valid value
1763 QTestEventList keys;
1764 keys.addKeyClick( qtKey: Qt::Key_Tab );
1765 for (uint i=0; i<2; i++)
1766 keys.addKeyClick( qtKey: Qt::Key_Down );
1767 QTime expected( 11, 58, 0 );
1768 QTest::newRow( dataTag: "data32" ) << bool(false) << keys << expected;
1769 }
1770
1771 // enter a valid one digit minute in 12 h mode
1772 {
1773 QTestEventList keys;
1774 keys.addKeyClick(qtKey: Qt::Key_Tab);
1775 keys.addKeyClick( ascii: '2' );
1776 QTime expected( 11, 2, 0 );
1777 QTest::newRow( dataTag: "data33" ) << bool(true) << keys << expected;
1778 }
1779
1780 // enter a valid two digit minutes in 12 h mode
1781 {
1782 QTestEventList keys;
1783 keys.addKeyClick(qtKey: Qt::Key_Tab);
1784 keys.addKeyClick( ascii: '2' );
1785 keys.addKeyClick( ascii: '4' );
1786 QTime expected( 11, 24, 0 );
1787 QTest::newRow( dataTag: "data34" ) << bool(true) << keys << expected;
1788 }
1789
1790 // check the lower limit of the minutes in 12 h mode
1791 {
1792 QTestEventList keys;
1793 keys.addKeyClick(qtKey: Qt::Key_Tab);
1794 keys.addKeyClick( ascii: '0' );
1795 QTime expected( 11, 0, 0 );
1796 QTest::newRow( dataTag: "data35" ) << bool(true) << keys << expected;
1797 }
1798
1799 // check the upper limit of the minutes in 12 h mode
1800 {
1801 QTestEventList keys;
1802 keys.addKeyClick(qtKey: Qt::Key_Tab);
1803 keys.addKeyClick( ascii: '5' );
1804 keys.addKeyClick( ascii: '9' );
1805 QTime expected( 11, 59, 0 );
1806 QTest::newRow( dataTag: "data36" ) << bool(true) << keys << expected;
1807 }
1808
1809 // enter an invalid two digit minutes in 12 h mode
1810 {
1811 QTestEventList keys;
1812 keys.addKeyClick( qtKey: Qt::Key_Tab );
1813 keys.addKeyClick( ascii: '6' );
1814 keys.addKeyClick( ascii: '0' );
1815 QTime expected( 11, 6, 0 );
1816 QTest::newRow( dataTag: "data37" ) << bool(true) << keys << expected;
1817 }
1818
1819 // test minutes in 24 hour motestWidget-> Behaviour should be exactly the same
1820
1821 // enter a valid one digit minute in 24 h mode
1822 {
1823 QTestEventList keys;
1824 keys.addKeyClick( qtKey: Qt::Key_Tab );
1825 keys.addKeyClick( ascii: '2' );
1826 QTime expected( 11, 2, 0 );
1827 QTest::newRow( dataTag: "data38" ) << bool(false) << keys << expected;
1828 }
1829
1830 // enter a valid two digit minutes in 24 h mode
1831 {
1832 QTestEventList keys;
1833 keys.addKeyClick( qtKey: Qt::Key_Tab );
1834 keys.addKeyClick( ascii: '2' );
1835 keys.addKeyClick( ascii: '4' );
1836 QTime expected( 11, 24, 0 );
1837 QTest::newRow( dataTag: "data39" ) << bool(false) << keys << expected;
1838 }
1839
1840 // check the lower limit of the minutes in 24 h mode
1841 {
1842 QTestEventList keys;
1843 keys.addKeyClick( qtKey: Qt::Key_Tab );
1844 keys.addKeyClick( ascii: '0' );
1845 QTime expected( 11, 0, 0 );
1846 QTest::newRow( dataTag: "data40" ) << bool(false) << keys << expected;
1847 }
1848
1849 // check the upper limit of the minutes in 24 h mode
1850 {
1851 QTestEventList keys;
1852 keys.addKeyClick( qtKey: Qt::Key_Tab );
1853 keys.addKeyClick( ascii: '5' );
1854 keys.addKeyClick( ascii: '9' );
1855 QTime expected( 11, 59, 0 );
1856 QTest::newRow( dataTag: "data41" ) << bool(false) << keys << expected;
1857 }
1858
1859 // enter an invalid two digit minutes in 24 h mode
1860 {
1861 QTestEventList keys;
1862 keys.addKeyClick( qtKey: Qt::Key_Tab );
1863 keys.addKeyClick( ascii: '6' );
1864 keys.addKeyClick( ascii: '0' );
1865 QTime expected( 11, 6, 0 );
1866 QTest::newRow( dataTag: "data42" ) << bool(false) << keys << expected;
1867 }
1868
1869 // ***************** test the seconds ***************
1870
1871 // use up/down to edit the seconds...
1872
1873 // use up/down keys to change the seconds in 12 hour mode
1874 { // test a valid value
1875 QTestEventList keys;
1876 keys.addKeyClick( qtKey: Qt::Key_Tab );
1877 keys.addKeyClick( qtKey: Qt::Key_Tab );
1878 for (uint i=0; i<2; i++)
1879 keys.addKeyClick( qtKey: Qt::Key_Up );
1880 QTime expected( 11, 0, 2 );
1881 QTest::newRow( dataTag: "data43" ) << bool(true) << keys << expected;
1882 }
1883 { // test a valid value
1884 QTestEventList keys;
1885 keys.addKeyClick( qtKey: Qt::Key_Tab );
1886 keys.addKeyClick( qtKey: Qt::Key_Tab );
1887 for (uint i=0; i<16; i++)
1888 keys.addKeyClick( qtKey: Qt::Key_Up );
1889 QTime expected( 11, 0, 16 );
1890 QTest::newRow( dataTag: "data44" ) << bool(true) << keys << expected;
1891 }
1892 { // test maximum value
1893 QTestEventList keys;
1894 keys.addKeyClick( qtKey: Qt::Key_Tab );
1895 keys.addKeyClick( qtKey: Qt::Key_Tab );
1896 for (uint i=0; i<59; i++)
1897 keys.addKeyClick( qtKey: Qt::Key_Up );
1898 QTime expected( 11, 0, 59 );
1899 QTest::newRow( dataTag: "data45" ) << bool(true) << keys << expected;
1900 }
1901 { // test 'overflow'
1902 QTestEventList keys;
1903 keys.addKeyClick( qtKey: Qt::Key_Tab );
1904 keys.addKeyClick( qtKey: Qt::Key_Tab );
1905 for (uint i=0; i<60; i++)
1906 keys.addKeyClick( qtKey: Qt::Key_Up );
1907 QTime expected( 11, 0, 0 );
1908 QTest::newRow( dataTag: "data46" ) << bool(true) << keys << expected;
1909 }
1910 { // test 'underflow'
1911 QTestEventList keys;
1912 keys.addKeyClick( qtKey: Qt::Key_Tab );
1913 keys.addKeyClick( qtKey: Qt::Key_Tab );
1914 keys.addKeyClick( qtKey: Qt::Key_Down );
1915 QTime expected( 11, 0, 59 );
1916 QTest::newRow( dataTag: "data47" ) << bool(true) << keys << expected;
1917 }
1918 { // test valid value
1919 QTestEventList keys;
1920 keys.addKeyClick( qtKey: Qt::Key_Tab );
1921 keys.addKeyClick( qtKey: Qt::Key_Tab );
1922 for (uint i=0; i<2; i++)
1923 keys.addKeyClick( qtKey: Qt::Key_Down );
1924 QTime expected( 11, 0, 58 );
1925 QTest::newRow( dataTag: "data48" ) << bool(true) << keys << expected;
1926 }
1927
1928 // use up/down keys to change the seconds in 24 hour mode
1929
1930 { // test a valid value
1931 QTestEventList keys;
1932 keys.addKeyClick( qtKey: Qt::Key_Tab );
1933 keys.addKeyClick( qtKey: Qt::Key_Tab );
1934 for (uint i=0; i<2; i++)
1935 keys.addKeyClick( qtKey: Qt::Key_Up );
1936 QTime expected( 11, 0, 2 );
1937 QTest::newRow( dataTag: "data49" ) << bool(false) << keys << expected;
1938 }
1939 { // test a valid value
1940 QTestEventList keys;
1941 keys.addKeyClick( qtKey: Qt::Key_Tab );
1942 keys.addKeyClick( qtKey: Qt::Key_Tab );
1943 for (uint i=0; i<16; i++)
1944 keys.addKeyClick( qtKey: Qt::Key_Up );
1945 QTime expected( 11, 0, 16 );
1946 QTest::newRow( dataTag: "data50" ) << bool(false) << keys << expected;
1947 }
1948 { // test maximum value
1949 QTestEventList keys;
1950 keys.addKeyClick( qtKey: Qt::Key_Tab );
1951 keys.addKeyClick( qtKey: Qt::Key_Tab );
1952 for (uint i=0; i<59; i++)
1953 keys.addKeyClick( qtKey: Qt::Key_Up );
1954 QTime expected( 11, 0, 59 );
1955 QTest::newRow( dataTag: "data51" ) << bool(false) << keys << expected;
1956 }
1957 { // test 'overflow'
1958 QTestEventList keys;
1959 keys.addKeyClick( qtKey: Qt::Key_Tab );
1960 keys.addKeyClick( qtKey: Qt::Key_Tab );
1961 for (uint i=0; i<60; i++)
1962 keys.addKeyClick( qtKey: Qt::Key_Up );
1963 QTime expected( 11, 0, 0 );
1964 QTest::newRow( dataTag: "data52" ) << bool(false) << keys << expected;
1965 }
1966 { // test 'underflow'
1967 QTestEventList keys;
1968 keys.addKeyClick( qtKey: Qt::Key_Tab );
1969 keys.addKeyClick( qtKey: Qt::Key_Tab );
1970 keys.addKeyClick( qtKey: Qt::Key_Down );
1971 QTime expected( 11, 0, 59 );
1972 QTest::newRow( dataTag: "data53" ) << bool(false) << keys << expected;
1973 }
1974 { // test valid value
1975 QTestEventList keys;
1976 keys.addKeyClick( qtKey: Qt::Key_Tab );
1977 keys.addKeyClick( qtKey: Qt::Key_Tab );
1978 for (uint i=0; i<2; i++)
1979 keys.addKeyClick( qtKey: Qt::Key_Down );
1980 QTime expected( 11, 0, 58 );
1981 QTest::newRow( dataTag: "data54" ) << bool(false) << keys << expected;
1982 }
1983
1984 // enter a valid one digit second in 12 h mode
1985 {
1986 QTestEventList keys;
1987 keys.addKeyClick( qtKey: Qt::Key_Tab );
1988 keys.addKeyClick( qtKey: Qt::Key_Tab );
1989 keys.addKeyClick( ascii: '2' );
1990 QTime expected( 11, 0, 2 );
1991 QTest::newRow( dataTag: "data55" ) << bool(true) << keys << expected;
1992 }
1993
1994 // enter a valid two digit seconds in 12 h mode
1995 {
1996 QTestEventList keys;
1997 keys.addKeyClick( qtKey: Qt::Key_Tab );
1998 keys.addKeyClick( qtKey: Qt::Key_Tab );
1999 keys.addKeyClick( ascii: '2' );
2000 keys.addKeyClick( ascii: '4' );
2001 QTime expected( 11, 0, 24 );
2002 QTest::newRow( dataTag: "data56" ) << bool(true) << keys << expected;
2003 }
2004
2005 // check the lower limit of the seconds in 12 h mode
2006 {
2007 QTestEventList keys;
2008 keys.addKeyClick( qtKey: Qt::Key_Tab );
2009 keys.addKeyClick( qtKey: Qt::Key_Tab );
2010 keys.addKeyClick( ascii: '0' );
2011 QTime expected( 11, 0, 0 );
2012 QTest::newRow( dataTag: "data57" ) << bool(true) << keys << expected;
2013 }
2014
2015 // check the upper limit of the seconds in 12 h mode
2016 {
2017 QTestEventList keys;
2018 keys.addKeyClick( qtKey: Qt::Key_Tab );
2019 keys.addKeyClick( qtKey: Qt::Key_Tab );
2020 keys.addKeyClick( ascii: '5' );
2021 keys.addKeyClick( ascii: '9' );
2022 QTime expected( 11, 0, 59 );
2023 QTest::newRow( dataTag: "data58" ) << bool(true) << keys << expected;
2024 }
2025
2026 // enter an invalid two digit seconds in 12 h mode
2027 {
2028 QTestEventList keys;
2029 keys.addKeyClick( qtKey: Qt::Key_Tab );
2030 keys.addKeyClick( qtKey: Qt::Key_Tab );
2031 keys.addKeyClick( ascii: '6' );
2032 keys.addKeyClick( ascii: '0' );
2033 QTime expected( 11, 0, 6 );
2034 QTest::newRow( dataTag: "data59" ) << bool(true) << keys << expected;
2035 }
2036
2037 // test seconds in 24 hour mode. Behaviour should be exactly the same
2038
2039 // enter a valid one digit minute in 24 h mode
2040 {
2041 QTestEventList keys;
2042 keys.addKeyClick( qtKey: Qt::Key_Tab );
2043 keys.addKeyClick( qtKey: Qt::Key_Tab );
2044 keys.addKeyClick( ascii: '2' );
2045 QTime expected( 11, 0, 2 );
2046 QTest::newRow( dataTag: "data60" ) << bool(false) << keys << expected;
2047 }
2048
2049 // enter a valid two digit seconds in 24 h mode
2050 {
2051 QTestEventList keys;
2052 keys.addKeyClick( qtKey: Qt::Key_Tab );
2053 keys.addKeyClick( qtKey: Qt::Key_Tab );
2054 keys.addKeyClick( ascii: '2' );
2055 keys.addKeyClick( ascii: '4' );
2056 QTime expected( 11, 0, 24 );
2057 QTest::newRow( dataTag: "data61" ) << bool(false) << keys << expected;
2058 }
2059
2060 // check the lower limit of the seconds in 24 h mode
2061 {
2062 QTestEventList keys;
2063 keys.addKeyClick( qtKey: Qt::Key_Tab );
2064 keys.addKeyClick( qtKey: Qt::Key_Tab );
2065 keys.addKeyClick( ascii: '0' );
2066 QTime expected( 11, 0, 0 );
2067 QTest::newRow( dataTag: "data62" ) << bool(false) << keys << expected;
2068 }
2069
2070 // check the upper limit of the seconds in 24 h mode
2071 {
2072 QTestEventList keys;
2073 keys.addKeyClick( qtKey: Qt::Key_Tab );
2074 keys.addKeyClick( qtKey: Qt::Key_Tab );
2075 keys.addKeyClick( ascii: '5' );
2076 keys.addKeyClick( ascii: '9' );
2077 QTime expected( 11, 0, 59 );
2078 QTest::newRow( dataTag: "data63" ) << bool(false) << keys << expected;
2079 }
2080
2081 // enter an invalid two digit seconds in 24 h mode
2082 {
2083 QTestEventList keys;
2084 keys.addKeyClick( qtKey: Qt::Key_Tab );
2085 keys.addKeyClick( qtKey: Qt::Key_Tab );
2086 keys.addKeyClick( ascii: '6' );
2087 keys.addKeyClick( ascii: '0' );
2088 QTime expected( 11, 0, 6 );
2089 QTest::newRow( dataTag: "data64" ) << bool(false) << keys << expected;
2090 }
2091
2092 // Test the AMPM indicator
2093 {
2094 QTestEventList keys;
2095 keys.addKeyClick( qtKey: Qt::Key_Tab );
2096 keys.addKeyClick( qtKey: Qt::Key_Tab );
2097 keys.addKeyClick( qtKey: Qt::Key_Tab );
2098 keys.addKeyClick( qtKey: Qt::Key_Up );
2099 QTime expected( 23, 0, 0 );
2100 QTest::newRow( dataTag: "data65" ) << bool(true) << keys << expected;
2101 }
2102 // Test the AMPM indicator
2103 {
2104 QTestEventList keys;
2105 keys.addKeyClick( qtKey: Qt::Key_Tab );
2106 keys.addKeyClick( qtKey: Qt::Key_Tab );
2107 keys.addKeyClick( qtKey: Qt::Key_Tab );
2108 keys.addKeyClick( qtKey: Qt::Key_Down );
2109 QTime expected( 23, 0, 0 );
2110 QTest::newRow( dataTag: "data66" ) << bool(true) << keys << expected;
2111 }
2112 // Test the AMPM indicator
2113 {
2114 QTestEventList keys;
2115 keys.addKeyClick( qtKey: Qt::Key_Tab );
2116 keys.addKeyClick( qtKey: Qt::Key_Tab );
2117 keys.addKeyClick( qtKey: Qt::Key_Tab );
2118 keys.addKeyClick( qtKey: Qt::Key_Down );
2119 keys.addKeyClick( qtKey: Qt::Key_Down );
2120 QTime expected( 11, 0, 0 );
2121 QTest::newRow( dataTag: "data67" ) << bool(true) << keys << expected;
2122 }
2123 // Test the AMPM indicator
2124 {
2125 QTestEventList keys;
2126 keys.addKeyClick( qtKey: Qt::Key_Tab );
2127 keys.addKeyClick( qtKey: Qt::Key_Tab );
2128 keys.addKeyClick( qtKey: Qt::Key_Tab );
2129 keys.addKeyClick( qtKey: Qt::Key_Up );
2130 keys.addKeyClick( qtKey: Qt::Key_Down );
2131 QTime expected( 11, 0, 0 );
2132 QTest::newRow( dataTag: "data68" ) << bool(true) << keys << expected;
2133 }
2134}
2135
2136void tst_QDateTimeEdit::userKeyPress_Time()
2137{
2138 QFETCH(bool, ampm);
2139 QFETCH(QTestEventList, keys);
2140 QFETCH(QTime, expected_time);
2141
2142 if (ampm)
2143 testWidget->setDisplayFormat("hh:mm:ss ap");
2144 else
2145 testWidget->setDisplayFormat("hh:mm:ss");
2146
2147 testWidget->setTime(QTime(11, 0, 0));
2148 testWidget->setFocus();
2149
2150 testWidget->setWrapping(true);
2151
2152 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter); // Make sure the first section is now focused
2153 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("11"));
2154 keys.simulate(w: testWidget);
2155 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
2156
2157 QCOMPARE(testWidget->time(), expected_time);
2158}
2159
2160void tst_QDateTimeEdit::wrappingDate_data()
2161{
2162 QTest::addColumn<bool>(name: "startWithMin");
2163 QTest::addColumn<QDate>(name: "minimumDate");
2164 QTest::addColumn<QDate>(name: "maximumDate");
2165 QTest::addColumn<uint>(name: "section");
2166 QTest::addColumn<QDate>(name: "newDate");
2167
2168 QTest::newRow(dataTag: "data0") << false << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::DaySection
2169 << QDate(1999, 1, 1);
2170 QTest::newRow(dataTag: "data1") << true << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::DaySection
2171 << QDate(1999, 1, 31);
2172 QTest::newRow(dataTag: "data2") << false << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::MonthSection
2173 << QDate(1999, 1, 31);
2174 QTest::newRow(dataTag: "data3") << true << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::MonthSection
2175 << QDate(1999, 1, 1);
2176 QTest::newRow(dataTag: "data4") << false << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::YearSection
2177 << QDate(1999, 1, 31);
2178 QTest::newRow(dataTag: "data5") << true << QDate(1999, 1, 1) << QDate(1999, 1, 31) << (uint)QDateTimeEdit::YearSection
2179 << QDate(1999, 1, 1);
2180 QTest::newRow(dataTag: "data6") << false << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::DaySection
2181 << QDate(2000, 1, 1);
2182 QTest::newRow(dataTag: "data7") << true << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::DaySection
2183 << QDate(1999, 1, 31);
2184 QTest::newRow(dataTag: "data8") << false << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::MonthSection
2185 << QDate(2000, 1, 31);
2186 QTest::newRow(dataTag: "data9") << true << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::MonthSection
2187 << QDate(1999, 12, 1);
2188 QTest::newRow(dataTag: "data10") << false << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::YearSection
2189 << QDate(1999, 1, 31);
2190 QTest::newRow(dataTag: "data11") << true << QDate(1999, 1, 1) << QDate(2000, 1, 31) << (uint)QDateTimeEdit::YearSection
2191 << QDate(2000, 1, 1);
2192}
2193
2194void tst_QDateTimeEdit::wrappingDate()
2195{
2196 QFETCH(bool, startWithMin);
2197 QFETCH(QDate, minimumDate);
2198 QFETCH(QDate, maximumDate);
2199 QFETCH(uint, section);
2200 QFETCH(QDate, newDate);
2201
2202 testWidget->setDisplayFormat("dd/MM/yyyy");
2203 testWidget->setMinimumDate(minimumDate);
2204 testWidget->setMaximumDate(maximumDate);
2205 testWidget->setWrapping(true);
2206 testWidget->setCurrentSection((QDateTimeEdit::Section)section);
2207
2208 if (startWithMin) {
2209 testWidget->setDate(minimumDate);
2210 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
2211 } else {
2212 testWidget->setDate(maximumDate);
2213 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
2214 }
2215 if (testWidget->currentSection() == QDateTimeEdit::MonthSection)
2216 QCOMPARE(testWidget->date(), newDate);
2217}
2218
2219void tst_QDateTimeEdit::dateSignalChecking_data()
2220{
2221 QTest::addColumn<QDate>(name: "originalDate");
2222 QTest::addColumn<QDate>(name: "newDate");
2223 QTest::addColumn<int>(name: "timesEmitted");
2224
2225 QTest::newRow(dataTag: "data0") << QDate(2004, 06, 22) << QDate(2004, 07, 23) << 1;
2226 QTest::newRow(dataTag: "data1") << QDate(2004, 06, 22) << QDate(2004, 06, 22) << 0;
2227}
2228
2229void tst_QDateTimeEdit::dateSignalChecking()
2230{
2231 QFETCH(QDate, originalDate);
2232 QFETCH(QDate, newDate);
2233 QFETCH(int, timesEmitted);
2234
2235 testWidget->setDate(originalDate);
2236
2237 QSignalSpy dateSpy(testWidget, SIGNAL(dateChanged(QDate)));
2238 QSignalSpy dateTimeSpy(testWidget, SIGNAL(dateTimeChanged(QDateTime)));
2239 QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(QTime)));
2240
2241 testWidget->setDate(newDate);
2242 QCOMPARE(dateSpy.count(), timesEmitted);
2243
2244 if (timesEmitted > 0) {
2245 QList<QVariant> list = dateSpy.takeFirst();
2246 QDate d;
2247 d = qvariant_cast<QDate>(v: list.at(i: 0));
2248 QCOMPARE(d, newDate);
2249 }
2250 QCOMPARE(dateTimeSpy.count(), timesEmitted);
2251 QCOMPARE(timeSpy.count(), 0);
2252}
2253
2254void tst_QDateTimeEdit::timeSignalChecking_data()
2255{
2256 QTest::addColumn<QTime>(name: "originalTime");
2257 QTest::addColumn<QTime>(name: "newTime");
2258 QTest::addColumn<int>(name: "timesEmitted");
2259
2260 QTest::newRow(dataTag: "data0") << QTime(15, 55, 00) << QTime(15, 17, 12) << 1;
2261 QTest::newRow(dataTag: "data1") << QTime(15, 55, 00) << QTime(15, 55, 00) << 0;
2262}
2263
2264void tst_QDateTimeEdit::timeSignalChecking()
2265{
2266 QFETCH(QTime, originalTime);
2267 QFETCH(QTime, newTime);
2268 QFETCH(int, timesEmitted);
2269
2270 testWidget->setTime(originalTime);
2271
2272 testWidget->setDisplayFormat("hh:mm:ss");
2273 QSignalSpy dateSpy(testWidget, SIGNAL(dateChanged(QDate)));
2274 QSignalSpy dateTimeSpy(testWidget, SIGNAL(dateTimeChanged(QDateTime)));
2275 QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(QTime)));
2276
2277 testWidget->setTime(newTime);
2278 QCOMPARE(timeSpy.count(), timesEmitted);
2279
2280 if (timesEmitted > 0) {
2281 QList<QVariant> list = timeSpy.takeFirst();
2282 QTime t;
2283 t = qvariant_cast<QTime>(v: list.at(i: 0));
2284 QCOMPARE(t, newTime);
2285 }
2286 QCOMPARE(dateTimeSpy.count(), timesEmitted);
2287 QCOMPARE(dateSpy.count(), 0);
2288}
2289
2290void tst_QDateTimeEdit::dateTimeSignalChecking_data()
2291{
2292 QTest::addColumn<QDateTime>(name: "originalDateTime");
2293 QTest::addColumn<QDateTime>(name: "newDateTime");
2294 QTest::addColumn<int>(name: "timesDateEmitted");
2295 QTest::addColumn<int>(name: "timesTimeEmitted");
2296 QTest::addColumn<int>(name: "timesDateTimeEmitted");
2297
2298 QTest::newRow(dataTag: "data0") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0))
2299 << QDateTime(QDate(2004, 7, 23), QTime(15, 17, 12))
2300 << 1 << 1 << 1;
2301 QTest::newRow(dataTag: "data1") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0))
2302 << QDateTime(QDate(2004, 6, 22), QTime(15, 17, 12))
2303 << 0 << 1 << 1;
2304 QTest::newRow(dataTag: "data2") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0))
2305 << QDateTime(QDate(2004, 7, 23), QTime(15, 55, 0))
2306 << 1 << 0 << 1;
2307 QTest::newRow(dataTag: "data3") << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0))
2308 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 0))
2309 << 0 << 0 << 0;
2310}
2311
2312void tst_QDateTimeEdit::dateTimeSignalChecking()
2313{
2314 QFETCH(QDateTime, originalDateTime);
2315 QFETCH(QDateTime, newDateTime);
2316 QFETCH(int, timesDateEmitted);
2317 QFETCH(int, timesTimeEmitted);
2318 QFETCH(int, timesDateTimeEmitted);
2319
2320 testWidget->setDisplayFormat("dd/MM/yyyy hh:mm:ss");
2321 testWidget->setDateTime(originalDateTime);
2322
2323 QSignalSpy dateSpy(testWidget, SIGNAL(dateChanged(QDate)));
2324 QSignalSpy timeSpy(testWidget, SIGNAL(timeChanged(QTime)));
2325 QSignalSpy dateTimeSpy(testWidget, SIGNAL(dateTimeChanged(QDateTime)));
2326
2327 testWidget->setDateTime(newDateTime);
2328 QCOMPARE(dateSpy.count(), timesDateEmitted);
2329 if (timesDateEmitted > 0) {
2330 QCOMPARE(timesDateEmitted, 1);
2331 QList<QVariant> list = dateSpy.takeFirst();
2332 QDate d;
2333 d = qvariant_cast<QDate>(v: list.at(i: 0));
2334 QCOMPARE(d, newDateTime.date());
2335 }
2336 QCOMPARE(timeSpy.count(), timesTimeEmitted);
2337 if (timesTimeEmitted > 0) {
2338 QList<QVariant> list = timeSpy.takeFirst();
2339 QTime t;
2340 t = qvariant_cast<QTime>(v: list.at(i: 0));
2341 QCOMPARE(t, newDateTime.time());
2342 }
2343 QCOMPARE(dateTimeSpy.count(), timesDateTimeEmitted);
2344 if (timesDateTimeEmitted > 0) {
2345 QList<QVariant> list = dateTimeSpy.takeFirst();
2346 QDateTime dt;
2347 dt = qvariant_cast<QDateTime>(v: list.at(i: 0));
2348 QCOMPARE(dt, newDateTime);
2349 }
2350}
2351
2352void tst_QDateTimeEdit::sectionText_data()
2353{
2354 QTest::addColumn<QString>(name: "format");
2355 QTest::addColumn<QDateTime>(name: "dateTime");
2356 QTest::addColumn<uint>(name: "section");
2357 QTest::addColumn<QString>(name: "sectionText");
2358
2359 QTest::newRow(dataTag: "data0") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2360 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2361 << (uint)QDateTimeEdit::NoSection << QString();
2362 QTest::newRow(dataTag: "data1") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2363 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2364 << (uint)QDateTimeEdit::AmPmSection << QString("pm");
2365 QTest::newRow(dataTag: "data2") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2366 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2367 << (uint)QDateTimeEdit::MSecSection << QString("789");
2368 QTest::newRow(dataTag: "data3") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2369 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2370 << (uint)QDateTimeEdit::SecondSection << QString("03");
2371 QTest::newRow(dataTag: "data4") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2372 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2373 << (uint)QDateTimeEdit::MinuteSection << QString("55");
2374 QTest::newRow(dataTag: "data5") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2375 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2376 << (uint)QDateTimeEdit::HourSection << QString("03");
2377 QTest::newRow(dataTag: "data6") << QString("dd/MM/yyyy hh:mm:ss zzz")
2378 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2379 << (uint)QDateTimeEdit::HourSection << QString("15");
2380 QTest::newRow(dataTag: "data7") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2381 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2382 << (uint)QDateTimeEdit::DaySection << QString("22");
2383 QTest::newRow(dataTag: "data8") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2384 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2385 << (uint)QDateTimeEdit::MonthSection << QString("06");
2386 QTest::newRow(dataTag: "data9") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2387 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2388 << (uint)QDateTimeEdit::YearSection << QString("2004");
2389 QTest::newRow(dataTag: "data10") << QString("dd/MM/yyyy hh:mm:ss zzz AP")
2390 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2391 << (uint)QDateTimeEdit::AmPmSection << QString("PM");
2392 QTest::newRow(dataTag: "data11") << QString("dd/MM/yyyy hh:mm:ss ap")
2393 << QDateTime(QDate(2004, 6, 22), QTime(15, 55, 3, 789))
2394 << (uint)QDateTimeEdit::MSecSection << QString();
2395}
2396
2397void tst_QDateTimeEdit::sectionText()
2398{
2399 QFETCH(QString, format);
2400 QFETCH(QDateTime, dateTime);
2401 QFETCH(uint, section);
2402 QFETCH(QString, sectionText);
2403
2404 testWidget->setDisplayFormat(format);
2405 testWidget->setDateTime(dateTime);
2406 QCOMPARE(testWidget->sectionText((QDateTimeEdit::Section)section), sectionText);
2407// QApplication::setLayoutDirection(Qt::RightToLeft);
2408// testWidget->setDisplayFormat(format);
2409// QCOMPARE(format, testWidget->displayFormat());
2410// testWidget->setDateTime(dateTime);
2411// QCOMPARE(testWidget->sectionText((QDateTimeEdit::Section)section), sectionText);
2412// QApplication::setLayoutDirection(Qt::LeftToRight);
2413}
2414
2415void tst_QDateTimeEdit::mousePress()
2416{
2417 testWidget->setDate(QDate(2004, 6, 23));
2418 testWidget->setCurrentSection(QDateTimeEdit::YearSection);
2419 QCOMPARE(testWidget->currentSection(), QDateTimeEdit::YearSection);
2420
2421 // Ask the SC_SpinBoxUp button location from style
2422 QStyleOptionSpinBox so;
2423 so.rect = testWidget->rect();
2424 QRect rectUp = testWidget->style()->subControlRect(cc: QStyle::CC_SpinBox, opt: &so, sc: QStyle::SC_SpinBoxUp, widget: testWidget);
2425
2426 // Send mouseClick to center of SC_SpinBoxUp
2427 QTest::mouseClick(widget: testWidget, button: Qt::LeftButton, stateKey: {}, pos: rectUp.center());
2428 QCOMPARE(testWidget->date().year(), 2005);
2429}
2430
2431void tst_QDateTimeEdit::stepHourAMPM_data()
2432{
2433 QTest::addColumn<QString>(name: "format");
2434 QTest::addColumn<KeyList>(name: "keys");
2435 QTest::addColumn<TimeList>(name: "expected");
2436 QTest::addColumn<QTime>(name: "start");
2437 QTest::addColumn<QTime>(name: "min");
2438 QTest::addColumn<QTime>(name: "max");
2439
2440 {
2441 KeyList keys;
2442 TimeList expected;
2443 keys << Qt::Key_Up;
2444 expected << QTime(1, 0, 0);
2445 keys << Qt::Key_Up;
2446 expected << QTime(2, 0, 0);
2447 keys << Qt::Key_Up;
2448 expected << QTime(3, 0, 0);
2449 keys << Qt::Key_Up;
2450 expected << QTime(4, 0, 0);
2451 keys << Qt::Key_Up;
2452 expected << QTime(5, 0, 0);
2453 keys << Qt::Key_Up;
2454 expected << QTime(6, 0, 0);
2455 keys << Qt::Key_Up;
2456 expected << QTime(7, 0, 0);
2457 keys << Qt::Key_Up;
2458 expected << QTime(8, 0, 0);
2459 keys << Qt::Key_Up;
2460 expected << QTime(9, 0, 0);
2461 keys << Qt::Key_Up;
2462 expected << QTime(10, 0, 0);
2463 keys << Qt::Key_Up;
2464 expected << QTime(11, 0, 0);
2465 keys << Qt::Key_Up;
2466 expected << QTime(12, 0, 0);
2467 keys << Qt::Key_Up;
2468 expected << QTime(13, 0, 0);
2469 keys << Qt::Key_Up;
2470 expected << QTime(14, 0, 0);
2471 keys << Qt::Key_Up;
2472 expected << QTime(15, 0, 0);
2473 keys << Qt::Key_Up;
2474 expected << QTime(16, 0, 0);
2475 keys << Qt::Key_Up;
2476 expected << QTime(17, 0, 0);
2477 keys << Qt::Key_Up;
2478 expected << QTime(18, 0, 0);
2479 keys << Qt::Key_Up;
2480 expected << QTime(19, 0, 0);
2481 keys << Qt::Key_Up;
2482 expected << QTime(20, 0, 0);
2483 keys << Qt::Key_Up;
2484 expected << QTime(21, 0, 0);
2485 keys << Qt::Key_Up;
2486 expected << QTime(22, 0, 0);
2487 keys << Qt::Key_Up;
2488 expected << QTime(23, 0, 0);
2489 keys << Qt::Key_Down;
2490 expected << QTime(22, 0, 0);
2491 keys << Qt::Key_Down;
2492 expected << QTime(21, 0, 0);
2493 keys << Qt::Key_Down;
2494 expected << QTime(20, 0, 0);
2495 keys << Qt::Key_Down;
2496 expected << QTime(19, 0, 0);
2497 keys << Qt::Key_Down;
2498 expected << QTime(18, 0, 0);
2499 keys << Qt::Key_Down;
2500 expected << QTime(17, 0, 0);
2501 keys << Qt::Key_Down;
2502 expected << QTime(16, 0, 0);
2503 keys << Qt::Key_Down;
2504 expected << QTime(15, 0, 0);
2505 keys << Qt::Key_Down;
2506 expected << QTime(14, 0, 0);
2507 keys << Qt::Key_Down;
2508 expected << QTime(13, 0, 0);
2509 keys << Qt::Key_Down;
2510 expected << QTime(12, 0, 0);
2511 keys << Qt::Key_Down;
2512 expected << QTime(11, 0, 0);
2513 keys << Qt::Key_Down;
2514 expected << QTime(10, 0, 0);
2515 keys << Qt::Key_Down;
2516 expected << QTime(9, 0, 0);
2517 keys << Qt::Key_Down;
2518 expected << QTime(8, 0, 0);
2519 keys << Qt::Key_Down;
2520 expected << QTime(7, 0, 0);
2521 keys << Qt::Key_Down;
2522 expected << QTime(6, 0, 0);
2523 keys << Qt::Key_Down;
2524 expected << QTime(5, 0, 0);
2525 keys << Qt::Key_Down;
2526 expected << QTime(4, 0, 0);
2527 keys << Qt::Key_Down;
2528 expected << QTime(3, 0, 0);
2529 keys << Qt::Key_Down;
2530 expected << QTime(2, 0, 0);
2531 keys << Qt::Key_Down;
2532 expected << QTime(1, 0, 0);
2533 keys << Qt::Key_Down;
2534 expected << QTime(0, 0, 0);
2535
2536 QTest::newRow(dataTag: "hh 1") << QString("hh") << keys << expected << QTime(0, 0)
2537 << QTime(0, 0) << QTime(23, 59, 59);
2538 QTest::newRow(dataTag: "hh:ap 1") << QString("hh:ap") << keys << expected
2539 << QTime(0, 0) << QTime(0, 0)
2540 << QTime(23, 59, 59);
2541
2542 QTest::newRow(dataTag: "HH:ap 2") << QString("HH:ap") << keys << expected
2543 << QTime(0, 0) << QTime(0, 0)
2544 << QTime(23, 59, 59);
2545 }
2546 {
2547 KeyList keys;
2548 TimeList expected;
2549 keys << Qt::Key_Down;
2550 expected << QTime(2, 0, 0);
2551 QTest::newRow(dataTag: "hh 2") << QString("hh") << keys << expected << QTime(0, 0) << QTime(2, 0, 0) << QTime(23, 59, 59);
2552 QTest::newRow(dataTag: "hh:ap 2") << QString("hh:ap") << keys << expected << QTime(0, 0) << QTime(2, 0, 0) << QTime(23, 59, 59);
2553 }
2554 {
2555 KeyList keys;
2556 TimeList expected;
2557 keys << Qt::Key_Up;
2558 expected << QTime(23, 0, 0);
2559 keys << Qt::Key_Up;
2560 expected << QTime(23, 0, 0);
2561 QTest::newRow(dataTag: "hh 3") << QString("hh") << keys << expected << QTime(0, 0) << QTime(22, 0, 0)
2562 << QTime(23, 59, 59);
2563 QTest::newRow(dataTag: "hh:ap 3") << QString("hh:ap") << keys << expected << QTime(0, 0)
2564 << QTime(22, 0, 0) << QTime(23, 59, 59);
2565 }
2566 {
2567 KeyList keys;
2568 TimeList expected;
2569 keys << Qt::Key_Up;
2570 expected << QTime(15, 31, 0);
2571 QTest::newRow(dataTag: "hh:mm:ap 3") << QString("hh:mm:ap") << keys << expected << QTime(15, 31, 0)
2572 << QTime(9, 0, 0) << QTime(16, 0, 0);
2573 QTest::newRow(dataTag: "hh:mm 3") << QString("hh:mm") << keys << expected << QTime(15, 31, 0)
2574 << QTime(9, 0, 0) << QTime(16, 0, 0);
2575 }
2576}
2577
2578void tst_QDateTimeEdit::stepHourAMPM()
2579{
2580 QFETCH(QString, format);
2581 QFETCH(KeyList, keys);
2582 QFETCH(TimeList, expected);
2583 QFETCH(QTime, start);
2584 QFETCH(QTime, min);
2585 QFETCH(QTime, max);
2586
2587 testWidget->setDisplayFormat(format);
2588 testWidget->setTime(start);
2589 testWidget->setMinimumTime(min);
2590 testWidget->setMaximumTime(max);
2591 if (keys.size() != expected.size()) {
2592 qWarning(msg: "%s:%d Test broken", __FILE__, __LINE__);
2593 QCOMPARE(keys.size(), expected.size());
2594 }
2595
2596 for (int i=0; i<keys.size(); ++i) {
2597 QTest::keyClick(widget: testWidget, key: keys.at(i));
2598 QCOMPARE(testWidget->time(), expected.at(i));
2599 }
2600}
2601
2602void tst_QDateTimeEdit::displayedSections_data()
2603{
2604 QTest::addColumn<QString>(name: "format");
2605 QTest::addColumn<uint>(name: "section");
2606
2607 QTest::newRow(dataTag: "data0") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2608 << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::MonthSection
2609 | QDateTimeEdit::YearSection | QDateTimeEdit::HourSection
2610 | QDateTimeEdit::MinuteSection | QDateTimeEdit::SecondSection
2611 | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection);
2612 QTest::newRow(dataTag: "data1") << QString("dd/yyyy hh:mm:ss zzz ap")
2613 << (uint)(QDateTimeEdit::DaySection
2614 | QDateTimeEdit::YearSection | QDateTimeEdit::HourSection
2615 | QDateTimeEdit::MinuteSection | QDateTimeEdit::SecondSection
2616 | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection);
2617 QTest::newRow(dataTag: "data2") << QString("dd/MM/yyyy mm zzz ap")
2618 << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::MonthSection
2619 | QDateTimeEdit::YearSection
2620 | QDateTimeEdit::MinuteSection
2621 | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection);
2622 QTest::newRow(dataTag: "data3") << QString("dd/MM/yyyy")
2623 << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::MonthSection
2624 | QDateTimeEdit::YearSection);
2625 QTest::newRow(dataTag: "data4") << QString("hh:mm:ss zzz ap")
2626 << (uint)(QDateTimeEdit::HourSection
2627 | QDateTimeEdit::MinuteSection | QDateTimeEdit::SecondSection
2628 | QDateTimeEdit::MSecSection | QDateTimeEdit::AmPmSection);
2629 QTest::newRow(dataTag: "data5") << QString("dd ap")
2630 << (uint)(QDateTimeEdit::DaySection | QDateTimeEdit::AmPmSection);
2631 QTest::newRow(dataTag: "data6") << QString("zzz")
2632 << (uint)QDateTimeEdit::MSecSection;
2633}
2634
2635void tst_QDateTimeEdit::displayedSections()
2636{
2637 QFETCH(QString, format);
2638 QFETCH(uint, section);
2639
2640 testWidget->setDisplayFormat(format);
2641 QCOMPARE(QDateTimeEdit::Sections(section), testWidget->displayedSections());
2642}
2643
2644void tst_QDateTimeEdit::currentSection_data()
2645{
2646 QTest::addColumn<QString>(name: "format");
2647 QTest::addColumn<uint>(name: "section");
2648 QTest::addColumn<uint>(name: "currentSection");
2649
2650 // First is deliberate, this way we can make sure that it is not reset by specifying no section.
2651 QTest::newRow(dataTag: "data0") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2652 << (uint)QDateTimeEdit::NoSection << (uint)QDateTimeEdit::YearSection;
2653 QTest::newRow(dataTag: "data1") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2654 << (uint)QDateTimeEdit::AmPmSection << (uint)QDateTimeEdit::AmPmSection;
2655 QTest::newRow(dataTag: "data2") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2656 << (uint)QDateTimeEdit::MSecSection << (uint)QDateTimeEdit::MSecSection;
2657 QTest::newRow(dataTag: "data3") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2658 << (uint)QDateTimeEdit::SecondSection << (uint)QDateTimeEdit::SecondSection;
2659 QTest::newRow(dataTag: "data4") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2660 << (uint)QDateTimeEdit::MinuteSection << (uint)QDateTimeEdit::MinuteSection;
2661 QTest::newRow(dataTag: "data5") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2662 << (uint)QDateTimeEdit::HourSection << (uint)QDateTimeEdit::HourSection;
2663 QTest::newRow(dataTag: "data6") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2664 << (uint)QDateTimeEdit::DaySection << (uint)QDateTimeEdit::DaySection;
2665 QTest::newRow(dataTag: "data7") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2666 << (uint)QDateTimeEdit::MonthSection << (uint)QDateTimeEdit::MonthSection;
2667 QTest::newRow(dataTag: "data8") << QString("dd/MM/yyyy hh:mm:ss zzz ap")
2668 << (uint)QDateTimeEdit::YearSection << (uint)QDateTimeEdit::YearSection;
2669 QTest::newRow(dataTag: "data9") << QString("dd/MM/yyyy hh:mm:ss zzz AP")
2670 << (uint)QDateTimeEdit::AmPmSection << (uint)QDateTimeEdit::AmPmSection;
2671 QTest::newRow(dataTag: "data10") << QString("dd/MM/yyyy hh:mm:ss ap")
2672 << (uint)QDateTimeEdit::MSecSection << (uint)QDateTimeEdit::DaySection;
2673}
2674
2675void tst_QDateTimeEdit::currentSection()
2676{
2677 QFETCH(QString, format);
2678 QFETCH(uint, section);
2679 QFETCH(uint, currentSection);
2680
2681 testWidget->setDisplayFormat(format);
2682 if ((QDateTimeEdit::Section)section == QDateTimeEdit::NoSection)
2683 testWidget->setCurrentSection(QDateTimeEdit::YearSection); // Ensure it's not reset (see above)
2684 testWidget->setCurrentSection((QDateTimeEdit::Section)section);
2685 QCOMPARE((QDateTimeEdit::Section)currentSection, testWidget->currentSection());
2686}
2687
2688void tst_QDateTimeEdit::readOnly()
2689{
2690 testWidget->hide();
2691 QDateTimeEdit dt(QDate(2000, 2, 1));
2692 dt.setDisplayFormat("yyyy.MM.dd");
2693 dt.show();
2694 dt.setCurrentSection(QDateTimeEdit::DaySection);
2695 QTest::keyClick(widget: &dt, key: Qt::Key_Up);
2696 QCOMPARE(dt.date(), QDate(2000, 2, 2));
2697 dt.setReadOnly(true);
2698 QTest::keyClick(widget: &dt, key: Qt::Key_Up);
2699 QCOMPARE(dt.date(), QDate(2000, 2, 2));
2700 dt.stepBy(steps: 1); // stepBy should still work
2701 QCOMPARE(dt.date(), QDate(2000, 2, 3));
2702 dt.setReadOnly(false);
2703 QTest::keyClick(widget: &dt, key: Qt::Key_Up);
2704 QCOMPARE(dt.date(), QDate(2000, 2, 4));
2705}
2706
2707void tst_QDateTimeEdit::weirdCase()
2708{
2709 testWidget->lineEdit()->setCursorPosition(0);
2710 testWidget->setDateRange(min: QDate(2005, 1, 1), max: QDate(2010, 12, 31));
2711 testWidget->setDisplayFormat("dd//MM//yyyy");
2712 testWidget->setDate(testWidget->minimumDate());
2713 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
2714 QVERIFY(!testWidget->lineEdit()->hasSelectedText());
2715 QCOMPARE(testWidget->lineEdit()->cursorPosition(), 0);
2716 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2717 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2718 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2719 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2720 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2721 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2722 QVERIFY(!testWidget->lineEdit()->hasSelectedText());
2723 QCOMPARE(testWidget->lineEdit()->cursorPosition(), 8);
2724
2725 QTest::keyClick(widget: testWidget, key: Qt::Key_Delete);
2726 QCOMPARE(testWidget->text(), QString("01//01//005"));
2727 QTest::keyClick(widget: testWidget, key: Qt::Key_4);
2728 QCOMPARE(testWidget->text(), QString("01//01//005"));
2729}
2730
2731void tst_QDateTimeEdit::newCase()
2732{
2733 const auto locale = QLocale::system();
2734 if (locale.monthName(6, format: QLocale::ShortFormat) != "Jun" ||
2735 locale.monthName(7, format: QLocale::ShortFormat) != "Jul" ||
2736 locale.monthName(6, format: QLocale::LongFormat) != "June" ||
2737 locale.monthName(7, format: QLocale::LongFormat) != "July") {
2738 QSKIP("This test only works in English");
2739 }
2740
2741 testWidget->setDisplayFormat("MMMM'a'MbMMMcMM");
2742 testWidget->setDate(QDate(2005, 6, 1));
2743 QCOMPARE(testWidget->text(), QString("Junea6bJunc06"));
2744#ifdef Q_OS_MAC
2745 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
2746#else
2747 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
2748#endif
2749 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
2750 QCOMPARE(testWidget->text(), QString("Julya7bJulc07"));
2751 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("July"));
2752#ifdef Q_OS_MAC
2753 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
2754#else
2755 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
2756#endif
2757#ifdef Q_OS_MAC
2758 QEXPECT_FAIL("", "QTBUG-23674", Abort);
2759#endif
2760 QCOMPARE(testWidget->lineEdit()->selectedText(), QString());
2761 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2762 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2763 QTest::keyClick(widget: testWidget, key: Qt::Key_Right);
2764 QTest::keyClick(widget: testWidget, key: Qt::Key_Delete);
2765 QTest::keyClick(widget: testWidget, key: Qt::Key_Left);
2766
2767 QCOMPARE(testWidget->text(), QString("Jula7bJulc07"));
2768 QTest::keyClick(widget: testWidget, key: Qt::Key_Delete);
2769 QCOMPARE(testWidget->text(), QString("Jua7bJulc07"));
2770 QTest::keyClick(widget: testWidget, key: Qt::Key_N);
2771 QCOMPARE(testWidget->text(), QString("Juna7bJulc07"));
2772 QTest::keyClick(widget: testWidget, key: Qt::Key_E);
2773 QCOMPARE(testWidget->text(), QString("Junea6bJunc06"));
2774}
2775
2776void tst_QDateTimeEdit::newCase2()
2777{
2778 testWidget->setDisplayFormat("MMMM yyyy-MM-dd MMMM");
2779 testWidget->setDate(QDate(2005, 8, 8));
2780 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
2781 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
2782 QCOMPARE(testWidget->text(), QString(" 2005-08-08 ") + QLocale::system().monthName(8, QLocale::LongFormat));
2783}
2784
2785void tst_QDateTimeEdit::newCase3()
2786{
2787 if (!QLocale::system().monthName(1, format: QLocale::LongFormat).startsWith(s: "Januar"))
2788 QSKIP("This test does not work in this locale");
2789
2790 testWidget->setDisplayFormat("dd MMMM yyyy");
2791 testWidget->setDate(QDate(2000, 1, 1));
2792 testWidget->setGeometry(QRect(QPoint(0, 0), testWidget->sizeHint()));
2793 testWidget->setCurrentSection(QDateTimeEdit::MonthSection);
2794 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
2795 QTest::keyClick(widget: testWidget, key: Qt::Key_J);
2796 QCOMPARE(testWidget->lineEdit()->displayText(), QString("01 J 2000"));
2797 QCOMPARE(testWidget->lineEdit()->cursorPosition(), 4);
2798 QTest::keyClick(widget: testWidget, key: Qt::Key_A);
2799 QTest::keyClick(widget: testWidget, key: Qt::Key_N);
2800 QTest::keyClick(widget: testWidget, key: Qt::Key_U);
2801 QTest::keyClick(widget: testWidget, key: Qt::Key_A);
2802 QTest::keyClick(widget: testWidget, key: Qt::Key_R);
2803}
2804
2805void tst_QDateTimeEdit::cursorPos()
2806{
2807 if (QLocale::system().monthName(1, format: QLocale::LongFormat) != "January")
2808 QSKIP("This test only works in English");
2809
2810 testWidget->setDisplayFormat("dd MMMM yyyy");
2811 //testWidget->setGeometry(0, 0, 200, 200);
2812 testWidget->setCurrentSection(QDateTimeEdit::MonthSection);
2813 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
2814 QCOMPARE(testWidget->lineEdit()->cursorPosition(), 10);
2815 QTest::keyClick(widget: testWidget, key: Qt::Key_J);
2816 QTest::keyClick(widget: testWidget, key: Qt::Key_A);
2817 QTest::keyClick(widget: testWidget, key: Qt::Key_N);
2818 QTest::keyClick(widget: testWidget, key: Qt::Key_U);
2819 QTest::keyClick(widget: testWidget, key: Qt::Key_A);
2820 QTest::keyClick(widget: testWidget, key: Qt::Key_R);
2821 //QCursor::setPos(20, 20);
2822 //QEventLoop l;
2823 //l.exec();
2824 QTest::keyClick(widget: testWidget, key: Qt::Key_Y);
2825 QCOMPARE(testWidget->lineEdit()->cursorPosition(), 11);
2826#ifdef Q_OS_MAC
2827 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
2828#else
2829 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
2830#endif
2831 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
2832 QTest::keyClick(widget: testWidget, key: Qt::Key_3);
2833 QTest::keyClick(widget: testWidget, key: Qt::Key_1);
2834#ifdef Q_OS_MAC
2835 QEXPECT_FAIL("", "QTBUG-23674", Abort);
2836#endif
2837 QCOMPARE(testWidget->lineEdit()->cursorPosition(), 3);
2838}
2839
2840void tst_QDateTimeEdit::newCase4()
2841{
2842 testWidget->setDisplayFormat("hh:mm");
2843 testWidget->setMinimumTime(QTime(3, 3, 0));
2844 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
2845 QTest::keyClick(widget: testWidget, key: Qt::Key_0);
2846 QCOMPARE(testWidget->lineEdit()->displayText(), QString("0:03"));
2847 QTest::keyClick(widget: testWidget, key: Qt::Key_2);
2848 QCOMPARE(testWidget->lineEdit()->displayText(), QString("0:03"));
2849 QTest::keyClick(widget: testWidget, key: Qt::Key_4);
2850 QCOMPARE(testWidget->lineEdit()->displayText(), QString("04:03"));
2851}
2852
2853void tst_QDateTimeEdit::newCase5()
2854{
2855 testWidget->setDisplayFormat("yyyy-MM-dd hh:mm:ss zzz 'ms'");
2856 testWidget->setDateTime(QDateTime(QDate(2005, 10, 7), QTime(17, 44, 13, 100)));
2857 testWidget->show();
2858 QCOMPARE(testWidget->lineEdit()->displayText(), QString("2005-10-07 17:44:13 100 ms"));
2859#ifdef Q_OS_MAC
2860 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
2861#else
2862 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
2863#endif
2864 QTest::keyClick(widget: testWidget, key: Qt::Key_Backtab, modifier: Qt::ShiftModifier);
2865
2866 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
2867 QTest::keyClick(widget: testWidget, key: Qt::Key_1);
2868 QTest::keyClick(widget: testWidget, key: Qt::Key_2);
2869 QTest::keyClick(widget: testWidget, key: Qt::Key_4);
2870#ifdef Q_OS_MAC
2871 QEXPECT_FAIL("", "QTBUG-23674", Abort);
2872#endif
2873 QCOMPARE(testWidget->lineEdit()->displayText(), QString("2005-10-07 17:44:13 124 ms"));
2874
2875 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
2876 QCOMPARE(testWidget->lineEdit()->displayText(), QString("2005-10-07 17:44:13 12 ms"));
2877}
2878
2879void tst_QDateTimeEdit::newCase6()
2880{
2881 testWidget->setDisplayFormat("d-yyyy-MM-dd");
2882 testWidget->setDate(QDate(2005, 10, 7));
2883 testWidget->show();
2884 QCOMPARE(testWidget->lineEdit()->displayText(), QString("7-2005-10-07"));
2885#ifdef Q_OS_MAC
2886 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
2887#else
2888 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
2889#endif
2890 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
2891 QTest::keyClick(widget: testWidget, key: Qt::Key_1);
2892 QTest::keyClick(widget: testWidget, key: Qt::Key_2);
2893 QCOMPARE(testWidget->lineEdit()->displayText(), QString("12-2005-10-12"));
2894}
2895
2896void tst_QDateTimeEdit::task98554()
2897{
2898 testWidget->setDisplayFormat("mm.ss.zzz(ms)");
2899 testWidget->setTime(QTime(0, 0, 9));
2900 testWidget->setCurrentSection(QDateTimeEdit::SecondSection);
2901 testWidget->show();
2902 QCOMPARE(testWidget->lineEdit()->displayText(), QString("00.09.000(09)"));
2903 QCOMPARE(testWidget->time(), QTime(0, 0, 9, 0));
2904 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
2905 QCOMPARE(testWidget->lineEdit()->displayText(), QString("00.10.000(010)"));
2906 QCOMPARE(testWidget->time(), QTime(0, 0, 10, 0));
2907}
2908
2909static QList<int> makeList(int val1, int val2, int val3)
2910{
2911 QList<int> ret;
2912 ret << val1 << val2 << val3;
2913 return ret;
2914}
2915
2916void tst_QDateTimeEdit::setCurrentSection_data()
2917{
2918 QTest::addColumn<QString>(name: "format");
2919 QTest::addColumn<QDateTime>(name: "dateTime");
2920 QTest::addColumn<QList<int> >(name: "setCurrentSections");
2921 QTest::addColumn<QList<int> >(name: "expectedCursorPositions");
2922
2923 QTest::newRow(dataTag: "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))
2924 << makeList(val1: QDateTimeEdit::DaySection, val2: QDateTimeEdit::DaySection, val3: QDateTimeEdit::DaySection)
2925 << makeList(val1: 24, val2: 0, val3: 24);
2926 QTest::newRow(dataTag: "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))
2927 << makeList(val1: QDateTimeEdit::MonthSection, val2: QDateTimeEdit::MonthSection, val3: QDateTimeEdit::MonthSection)
2928 << makeList(val1: 3, val2: 26, val3: 3);
2929 QTest::newRow(dataTag: "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))
2930 << makeList(val1: QDateTimeEdit::YearSection, val2: QDateTimeEdit::YearSection, val3: QDateTimeEdit::YearSection)
2931 << makeList(val1: 6, val2: 28, val3: 6);
2932 QTest::newRow(dataTag: "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))
2933 << makeList(val1: QDateTimeEdit::HourSection, val2: QDateTimeEdit::HourSection, val3: QDateTimeEdit::HourSection)
2934 << makeList(val1: 11, val2: 31, val3: 11);
2935 QTest::newRow(dataTag: "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))
2936 << makeList(val1: QDateTimeEdit::MinuteSection, val2: QDateTimeEdit::MinuteSection, val3: QDateTimeEdit::MinuteSection)
2937 << makeList(val1: 14, val2: 33, val3: 14);
2938 QTest::newRow(dataTag: "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))
2939 << makeList(val1: QDateTimeEdit::SecondSection, val2: QDateTimeEdit::SecondSection, val3: QDateTimeEdit::SecondSection)
2940 << makeList(val1: 17, val2: 35, val3: 17);
2941 QTest::newRow(dataTag: "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))
2942 << makeList(val1: QDateTimeEdit::MSecSection, val2: QDateTimeEdit::MSecSection, val3: QDateTimeEdit::MSecSection)
2943 << makeList(val1: 20, val2: 37, val3: 20);
2944}
2945
2946void tst_QDateTimeEdit::setCurrentSection()
2947{
2948 QFETCH(QString, format);
2949 QFETCH(QDateTime, dateTime);
2950 QFETCH(QList<int>, setCurrentSections);
2951 QFETCH(QList<int>, expectedCursorPositions);
2952
2953 QCOMPARE(setCurrentSections.size(), expectedCursorPositions.size());
2954 testWidget->setDisplayFormat(format);
2955 testWidget->setDateTime(dateTime);
2956#ifdef Q_OS_MAC
2957 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
2958#else
2959 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
2960#endif
2961
2962 testWidget->resize(w: 400, h: 100);
2963 for (int i=0; i<setCurrentSections.size(); ++i) {
2964 testWidget->setCurrentSection((QDateTimeEdit::Section)setCurrentSections.at(i));
2965 QCOMPARE(testWidget->currentSection(), (QDateTimeEdit::Section)setCurrentSections.at(i));
2966 QCOMPARE(testWidget->lineEdit()->cursorPosition(), expectedCursorPositions.at(i));
2967 }
2968}
2969
2970void tst_QDateTimeEdit::setSelectedSection()
2971{
2972 testWidget->setDisplayFormat("mm.ss.zzz('ms') m");
2973 testWidget->setTime(QTime(0, 0, 9));
2974 testWidget->show();
2975#ifdef Q_OS_MAC
2976 QTest::keyClick(testWidget, Qt::Key_Left, Qt::ControlModifier);
2977#else
2978 QTest::keyClick(widget: testWidget, key: Qt::Key_Home);
2979#endif
2980#ifdef Q_OS_MAC
2981 QEXPECT_FAIL("", "QTBUG-23674", Abort);
2982#endif
2983 QVERIFY(!testWidget->lineEdit()->hasSelectedText());
2984 testWidget->setSelectedSection(QDateTimeEdit::MinuteSection);
2985 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("00"));
2986 testWidget->setCurrentSection(QDateTimeEdit::MinuteSection);
2987 testWidget->setSelectedSection(QDateTimeEdit::MinuteSection);
2988 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("0"));
2989 testWidget->setSelectedSection(QDateTimeEdit::SecondSection);
2990 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("09"));
2991 testWidget->setSelectedSection(QDateTimeEdit::NoSection);
2992 QVERIFY(!testWidget->lineEdit()->hasSelectedText());
2993}
2994
2995void tst_QDateTimeEdit::calendarPopup()
2996{
2997 {
2998 QDateEdit edit;
2999 QVERIFY(!edit.calendarWidget());
3000 edit.setCalendarPopup(true);
3001 QVERIFY(edit.calendarWidget());
3002 }
3003
3004 {
3005 QTimeEdit edit;
3006 QVERIFY(!edit.calendarWidget());
3007 edit.setCalendarPopup(true);
3008 QVERIFY(!edit.calendarWidget());
3009 }
3010
3011 {
3012 QDateEdit edit;
3013 QVERIFY(!edit.calendarWidget());
3014 QCalendarWidget *cw = new QCalendarWidget;
3015 edit.setCalendarWidget(cw);
3016 QVERIFY(!edit.calendarWidget());
3017 edit.setCalendarPopup(true);
3018 edit.setCalendarWidget(cw);
3019 QCOMPARE(edit.calendarWidget(), cw);
3020 edit.setDateRange(min: QDate(1980, 1, 5), max: QDate(1980, 2, 11));
3021 QCOMPARE(cw->minimumDate(), edit.minimumDate());
3022 QCOMPARE(cw->maximumDate(), edit.maximumDate());
3023 edit.setDate(QDate(1980, 1, 31));
3024 QCOMPARE(edit.date(), cw->selectedDate());
3025 cw->setSelectedDate(QDate(1980, 1, 30));
3026 QCOMPARE(edit.date(), cw->selectedDate());
3027 }
3028
3029 testWidget->setDisplayFormat("dd/MM/yyyy");
3030 testWidget->setDateTime(QDateTime(QDate(2000, 1, 1), QTime(0, 0)));
3031 testWidget->show();
3032 testWidget->setCalendarPopup(true);
3033 QCOMPARE(testWidget->calendarPopup(), true);
3034 QStyle *style = testWidget->style();
3035 QStyleOptionComboBox opt;
3036 opt.initFrom(w: testWidget);
3037 opt.editable = true;
3038 opt.subControls = QStyle::SC_ComboBoxArrow;
3039 QRect rect = style->subControlRect(cc: QStyle::CC_ComboBox, opt: &opt, sc: QStyle::SC_ComboBoxArrow, widget: testWidget);
3040 QTest::mouseClick(widget: testWidget, button: Qt::LeftButton, stateKey: {},
3041 pos: QPoint(rect.left() + rect.width() / 2, rect.top() + rect.height() / 2));
3042 QWidget *wid = testWidget->findChild<QWidget *>(aName: "qt_datetimedit_calendar");
3043 QVERIFY(wid != 0);
3044 testWidget->hide();
3045
3046 QTimeEdit timeEdit;
3047 timeEdit.setCalendarPopup(true);
3048 timeEdit.show();
3049
3050 opt.initFrom(w: &timeEdit);
3051 opt.subControls = QStyle::SC_ComboBoxArrow;
3052 rect = style->subControlRect(cc: QStyle::CC_ComboBox, opt: &opt, sc: QStyle::SC_ComboBoxArrow, widget: &timeEdit);
3053 QTest::mouseClick(widget: &timeEdit, button: Qt::LeftButton, stateKey: {},
3054 pos: QPoint(rect.left() + rect.width() / 2, rect.top() + rect.height() / 2));
3055 QWidget *wid2 = timeEdit.findChild<QWidget *>(aName: "qt_datetimedit_calendar");
3056 QVERIFY(!wid2);
3057 timeEdit.hide();
3058
3059
3060 QDateEdit dateEdit;
3061 dateEdit.setCalendarPopup(true);
3062 dateEdit.setReadOnly(true);
3063 dateEdit.show();
3064
3065 opt.initFrom(w: &dateEdit);
3066 opt.subControls = QStyle::SC_ComboBoxArrow;
3067 rect = style->subControlRect(cc: QStyle::CC_ComboBox, opt: &opt, sc: QStyle::SC_ComboBoxArrow, widget: &dateEdit);
3068 QTest::mouseClick(widget: &dateEdit, button: Qt::LeftButton, stateKey: {},
3069 pos: QPoint(rect.left() + rect.width() / 2, rect.top() + rect.height() / 2));
3070 QWidget *wid3 = dateEdit.findChild<QWidget *>(aName: "qt_datetimedit_calendar");
3071 QVERIFY(!wid3);
3072 dateEdit.hide();
3073}
3074
3075class RestoreLayoutDirectioner
3076{
3077public:
3078 RestoreLayoutDirectioner(Qt::LayoutDirection was)
3079 : old(was)
3080 {}
3081
3082 ~RestoreLayoutDirectioner()
3083 {
3084 QApplication::setLayoutDirection(old);
3085 }
3086private:
3087 const Qt::LayoutDirection old;
3088};
3089
3090void tst_QDateTimeEdit::reverseTest()
3091{
3092 const RestoreLayoutDirectioner restorer(QApplication::layoutDirection());
3093 QApplication::setLayoutDirection(Qt::RightToLeft);
3094 testWidget->setDisplayFormat("dd/MM/yyyy");
3095 testWidget->setDate(QDate(2001, 3, 30));
3096 QCOMPARE(testWidget->lineEdit()->displayText(), QString("2001/03/30"));
3097#ifdef Q_OS_MAC
3098 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
3099#else
3100 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
3101#endif
3102#ifdef Q_OS_MAC
3103 QEXPECT_FAIL("", "QTBUG-23674", Abort);
3104#endif
3105 QCOMPARE(testWidget->currentSection(), QDateTimeEdit::DaySection);
3106 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3107 QCOMPARE(testWidget->date(), QDate(2001, 3, 31));
3108 QCOMPARE(testWidget->lineEdit()->displayText(), QString("2001/03/31"));
3109}
3110
3111void tst_QDateTimeEdit::hour12Test()
3112{
3113 testWidget->setDisplayFormat("hh a");
3114 testWidget->setTime(QTime(0, 0, 0));
3115 QCOMPARE(testWidget->lineEdit()->displayText(), QString("12 am"));
3116 for (int i=0; i<11; ++i) {
3117 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3118 }
3119 QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 am"));
3120 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3121 QCOMPARE(testWidget->lineEdit()->displayText(), QString("12 pm"));
3122 for (int i=0; i<11; ++i) {
3123 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3124 }
3125 QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 pm"));
3126 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3127 QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 pm"));
3128 for (int i=0; i<12; ++i) {
3129 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
3130 }
3131 QCOMPARE(testWidget->lineEdit()->displayText(), QString("11 am"));
3132 QTest::keyClick(widget: testWidget, key: Qt::Key_1);
3133 QCOMPARE(testWidget->lineEdit()->displayText(), QString("1 am"));
3134 QTest::keyClick(widget: testWidget, key: Qt::Key_3);
3135 QCOMPARE(testWidget->lineEdit()->displayText(), QString("1 am"));
3136}
3137
3138void tst_QDateTimeEdit::yyTest()
3139{
3140 testWidget->setDisplayFormat("dd-MMM-yy");
3141 testWidget->setTime(QTime(0, 0, 0));
3142 testWidget->setDateRange(min: QDate(2005, 1, 1), max: QDate(2010, 12, 31));
3143 testWidget->setDate(testWidget->minimumDate());
3144 testWidget->setCurrentSection(QDateTimeEdit::YearSection);
3145
3146 QString jan = QLocale::system().monthName(1, format: QLocale::ShortFormat);
3147 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-05");
3148 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3149 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-06");
3150 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3151 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-07");
3152 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3153 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-08");
3154 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3155 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-09");
3156 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3157 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-10");
3158 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3159 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-10");
3160 testWidget->setWrapping(true);
3161 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3162 QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-05");
3163
3164 testWidget->setDateRange(min: QDate(100, 1, 1), max: QDate(8000, 12, 31));
3165 testWidget->setDate(QDate(2000, 1, 1));
3166 testWidget->setCurrentSection(QDateTimeEdit::YearSection);
3167 testWidget->setWrapping(false);
3168 for (int i=0; i<10; ++i) {
3169 for (int j=0; j<50; ++j) {
3170 testWidget->stepBy(steps: -1);
3171 }
3172 testWidget->stepBy(steps: -50);
3173 QCOMPARE(testWidget->sectionText(QDateTimeEdit::YearSection), QString("00"));
3174 QCOMPARE(testWidget->date(), QDate(2000 - ((i + 1) * 100), 1, 1));
3175 }
3176}
3177
3178void tst_QDateTimeEdit::task108572()
3179{
3180 testWidget->setDisplayFormat("hh:mm:ss.zzz");
3181 testWidget->setTime(QTime(0, 1, 2, 0));
3182 QCOMPARE(testWidget->lineEdit()->displayText(), QString("00:01:02.000"));
3183
3184 testWidget->setCurrentSection(QDateTimeEdit::MSecSection);
3185 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
3186 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("000"));
3187 QTest::keyClick(widget: testWidget, key: Qt::Key_2);
3188 QCOMPARE(testWidget->lineEdit()->displayText(), QString("00:01:02.2"));
3189 QTest::keyClick(widget: testWidget, key: Qt::Key_Return);
3190 QCOMPARE(testWidget->lineEdit()->displayText(), QString("00:01:02.200"));
3191 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("200"));
3192 QCOMPARE(testWidget->time(), QTime(0, 1, 2, 200));
3193}
3194
3195void tst_QDateTimeEdit::task149097()
3196{
3197 QSignalSpy dtSpy(testWidget, SIGNAL(dateTimeChanged(QDateTime)));
3198 QSignalSpy dSpy(testWidget, SIGNAL(dateChanged(QDate)));
3199 QSignalSpy tSpy(testWidget, SIGNAL(timeChanged(QTime)));
3200
3201 testWidget->setDisplayFormat("yyyy/MM/dd hh:mm:ss");
3202 testWidget->setDateTime(QDateTime(QDate(2001, 02, 03), QTime(5, 1, 2)));
3203// QTest::keyClick(testWidget, Qt::Key_Enter);
3204 QCOMPARE(dtSpy.count(), 1);
3205 QCOMPARE(dSpy.count(), 1);
3206 QCOMPARE(tSpy.count(), 1);
3207 testWidget->setCurrentSection(QDateTimeEdit::YearSection);
3208 testWidget->stepBy(steps: 1);
3209
3210 QCOMPARE(dtSpy.count(), 2);
3211 QCOMPARE(dSpy.count(), 2);
3212 QCOMPARE(tSpy.count(), 1);
3213
3214 testWidget->setCurrentSection(QDateTimeEdit::MinuteSection);
3215 testWidget->stepBy(steps: 1);
3216
3217 QCOMPARE(dtSpy.count(), 3);
3218 QCOMPARE(dSpy.count(), 2);
3219 QCOMPARE(tSpy.count(), 2);
3220}
3221
3222void tst_QDateTimeEdit::task148725()
3223{
3224 testWidget->setDisplayFormat("dd/MM");
3225 testWidget->setDate(QDate(2001, 2, 27));
3226 testWidget->stepBy(steps: 1);
3227 QCOMPARE(testWidget->date(), QDate(2001, 2, 28));
3228 testWidget->stepBy(steps: 1);
3229 QCOMPARE(testWidget->date(), QDate(2001, 2, 28));
3230 testWidget->setWrapping(true);
3231 testWidget->stepBy(steps: 1);
3232 QCOMPARE(testWidget->date(), QDate(2001, 2, 1));
3233}
3234
3235void tst_QDateTimeEdit::task148522()
3236{
3237 QTimeEdit edit;
3238 const QDateTime dt(QDate(2000, 12, 12), QTime(12, 13, 14, 15));
3239 edit.setDateTime(dt);
3240 QCOMPARE(edit.dateTime(), dt);
3241}
3242
3243void tst_QDateTimeEdit::ddMMMMyyyy()
3244{
3245 testWidget->setDisplayFormat("dd.MMMM.yyyy");
3246 testWidget->setDate(QDate(2000, 1, 1));
3247 testWidget->setCurrentSection(QDateTimeEdit::YearSection);
3248 QTest::keyClick(widget: testWidget, key: Qt::Key_Enter);
3249 QCOMPARE(testWidget->lineEdit()->selectedText(), QString("2000"));
3250#ifdef Q_OS_MAC
3251 QTest::keyClick(testWidget, Qt::Key_Right, Qt::ControlModifier);
3252#else
3253 QTest::keyClick(widget: testWidget, key: Qt::Key_End);
3254#endif
3255 QTest::keyClick(widget: testWidget, key: Qt::Key_Backspace);
3256#ifdef Q_OS_MAC
3257 QEXPECT_FAIL("", "QTBUG-23674", Abort);
3258#endif
3259 QCOMPARE(testWidget->lineEdit()->text(), "01." + QLocale::system().monthName(1, QLocale::LongFormat) + ".200");
3260}
3261
3262void tst_QDateTimeEdit::wheelEvent_data()
3263{
3264#if QT_CONFIG(wheelevent)
3265 QTest::addColumn<QPoint>(name: "angleDelta");
3266 QTest::addColumn<int>(name: "stepModifier");
3267 QTest::addColumn<Qt::KeyboardModifiers>(name: "modifiers");
3268 QTest::addColumn<Qt::MouseEventSource>(name: "source");
3269 QTest::addColumn<QDateTimeEdit::Section>(name: "section");
3270 QTest::addColumn<QDate>(name: "startDate");
3271 QTest::addColumn<DateList>(name: "expectedDates");
3272
3273 const auto fractions = {false, true};
3274
3275 const auto directions = {true, false};
3276
3277 const auto modifierList = {Qt::NoModifier,
3278 Qt::ShiftModifier,
3279 Qt::ControlModifier,
3280 Qt::AltModifier,
3281 Qt::MetaModifier};
3282
3283 const auto validStepModifierList = {Qt::NoModifier,
3284 Qt::ControlModifier,
3285 Qt::ShiftModifier};
3286
3287 const auto sources = {Qt::MouseEventNotSynthesized,
3288 Qt::MouseEventSynthesizedBySystem,
3289 Qt::MouseEventSynthesizedByQt,
3290 Qt::MouseEventSynthesizedByApplication};
3291
3292 const auto sections = {QDateTimeEdit::DaySection,
3293 QDateTimeEdit::MonthSection,
3294 QDateTimeEdit::YearSection};
3295
3296 for (auto fraction : fractions) {
3297 for (auto up : directions) {
3298
3299 const QDate startDate(2000, up ? 2 : 12, 17);
3300
3301 const int units = (fraction ? 60 : 120) * (up ? 1 : -1);
3302
3303 for (auto modifier : modifierList) {
3304
3305 const Qt::KeyboardModifiers modifiers(modifier);
3306
3307 const auto modifierName = modifierToName(modifier);
3308 if (modifierName.isEmpty())
3309 continue;
3310
3311 for (auto stepModifier : validStepModifierList) {
3312
3313 const auto stepModifierName = modifierToName(modifier: stepModifier);
3314 if (stepModifierName.isEmpty())
3315 continue;
3316
3317 const int steps = (modifier & stepModifier ? 10 : 1)
3318 * (up ? 1 : -1);
3319
3320 for (auto source : sources) {
3321
3322#ifdef Q_OS_MACOS
3323 QPoint angleDelta;
3324 if ((modifier & Qt::ShiftModifier) &&
3325 source == Qt::MouseEventNotSynthesized) {
3326 // On macOS the Shift modifier converts vertical
3327 // mouse wheel events to horizontal.
3328 angleDelta = { units, 0 };
3329 } else {
3330 // However, this is not the case for trackpad scroll
3331 // events.
3332 angleDelta = { 0, units };
3333 }
3334#else
3335 const QPoint angleDelta(0, units);
3336#endif
3337
3338 QLatin1String sourceName;
3339 switch (source) {
3340 case Qt::MouseEventNotSynthesized:
3341 sourceName = QLatin1String("NotSynthesized");
3342 break;
3343 case Qt::MouseEventSynthesizedBySystem:
3344 sourceName = QLatin1String("SynthesizedBySystem");
3345 break;
3346 case Qt::MouseEventSynthesizedByQt:
3347 sourceName = QLatin1String("SynthesizedByQt");
3348 break;
3349 case Qt::MouseEventSynthesizedByApplication:
3350 sourceName = QLatin1String("SynthesizedByApplication");
3351 break;
3352 default:
3353 qFatal(msg: "Unexpected wheel event source");
3354 continue;
3355 }
3356
3357 for (const auto section : sections) {
3358
3359 DateList expectedDates;
3360 if (fraction)
3361 expectedDates << startDate;
3362
3363 const auto expectedDate = stepDate(startDate, section, steps);
3364 if (!expectedDate.isValid())
3365 continue;
3366
3367 expectedDates << expectedDate;
3368
3369 const QLatin1String sectionName = sectionToName(section);
3370
3371 QTest::addRow(format: "%s%s%s%sWith%sKeyboardModifier%s",
3372 fraction ? "half" : "full",
3373 up ? "Up" : "Down",
3374 stepModifierName.latin1(),
3375 sectionName.latin1(),
3376 modifierName.latin1(),
3377 sourceName.latin1())
3378 << angleDelta
3379 << static_cast<int>(stepModifier)
3380 << modifiers
3381 << source
3382 << section
3383 << startDate
3384 << expectedDates;
3385 }
3386 }
3387 }
3388 }
3389 }
3390 }
3391#else
3392 QSKIP("Built with --no-feature-wheelevent");
3393#endif
3394}
3395
3396void tst_QDateTimeEdit::wheelEvent()
3397{
3398#if QT_CONFIG(wheelevent)
3399 QFETCH(QPoint, angleDelta);
3400 QFETCH(int, stepModifier);
3401 QFETCH(Qt::KeyboardModifiers, modifiers);
3402 QFETCH(Qt::MouseEventSource, source);
3403 QFETCH(QDateTimeEdit::Section, section);
3404 QFETCH(QDate, startDate);
3405 QFETCH(DateList, expectedDates);
3406
3407 EditorDateEdit edit(0);
3408 edit.setDate(startDate);
3409 edit.setCurrentSection(section);
3410
3411 QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
3412 new StepModifierStyle);
3413 style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
3414 edit.setStyle(style.data());
3415
3416 QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta,
3417 Qt::NoButton, modifiers, Qt::NoScrollPhase, false, source);
3418
3419 QCOMPARE(edit.date(), startDate);
3420 for (QDate expected : expectedDates) {
3421 qApp->sendEvent(receiver: &edit, event: &event);
3422 QCOMPARE(edit.date(), expected);
3423 }
3424#else
3425 QSKIP("Built with --no-feature-wheelevent");
3426#endif // QT_CONFIG(wheelevent)
3427}
3428
3429void tst_QDateTimeEdit::specialValueCornerCase()
3430{
3431 // if you set minimum to value it won't update since value won't
3432 // be bounded to anything. If you have a specialValueText it needs
3433 // to call updateEdit to make sure the text is changed
3434
3435 QDateTimeEdit edit;
3436 edit.setSpecialValueText("foobar");
3437 edit.setMinimumDate(edit.date());
3438 QCOMPARE(edit.minimumDate(), edit.date());
3439 QCOMPARE(edit.text(), QString("foobar"));
3440}
3441
3442void tst_QDateTimeEdit::cursorPositionOnInit()
3443{
3444 {
3445 EditorDateEdit edit;
3446 edit.setDisplayFormat("dd/MM");
3447 edit.show();
3448 QCOMPARE(edit.lineEdit()->cursorPosition(), 0);
3449 }
3450
3451 {
3452 EditorDateEdit edit;
3453 edit.setDisplayFormat("dd/MM");
3454 edit.setSpecialValueText("special");
3455 edit.setMinimumDate(edit.date());
3456 edit.show();
3457 QCOMPARE(edit.lineEdit()->cursorPosition(), 7);
3458 // ### legacy behavior. Keep it like this rather than changing
3459 // ### but add a test none-the-less
3460 }
3461}
3462
3463void tst_QDateTimeEdit::task118867()
3464{
3465 EditorDateEdit edit;
3466 edit.setDisplayFormat("hh:mm");
3467 edit.setMinimumTime(QTime(5, 30));
3468 edit.setMaximumTime(QTime(6, 30));
3469 QCOMPARE(edit.text(), QString("05:30"));
3470 edit.lineEdit()->setCursorPosition(5);
3471 QTest::keyClick(widget: &edit, key: Qt::Key_Backspace);
3472 QCOMPARE(edit.text(), QString("05:3"));
3473 QTest::keyClick(widget: &edit, key: Qt::Key_Backspace);
3474 QCOMPARE(edit.text(), QString("05:"));
3475 QTest::keyClick(widget: &edit, key: Qt::Key_1);
3476 QCOMPARE(edit.text(), QString("05:"));
3477 QTest::keyClick(widget: &edit, key: Qt::Key_2);
3478 QCOMPARE(edit.text(), QString("05:"));
3479 QTest::keyClick(widget: &edit, key: Qt::Key_3);
3480 QCOMPARE(edit.text(), QString("05:3"));
3481 QTest::keyClick(widget: &edit, key: Qt::Key_3);
3482 QCOMPARE(edit.text(), QString("05:33"));
3483}
3484
3485void tst_QDateTimeEdit::nextPrevSection_data()
3486{
3487 QTest::addColumn<Qt::Key>(name: "key");
3488 QTest::addColumn<Qt::KeyboardModifiers>(name: "modifiers");
3489 QTest::addColumn<QString>(name: "selectedText");
3490
3491 QTest::newRow(dataTag: "tab") << Qt::Key_Tab << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56");
3492 QTest::newRow(dataTag: "backtab") << Qt::Key_Backtab << (Qt::KeyboardModifiers)Qt::NoModifier << QString("12");
3493 QTest::newRow(dataTag: "shift-tab") << Qt::Key_Tab << (Qt::KeyboardModifiers)Qt::ShiftModifier << QString("12");
3494 QTest::newRow(dataTag: "/") << Qt::Key_Slash << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56");
3495 QTest::newRow(dataTag: "b") << Qt::Key_B << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56");
3496 QTest::newRow(dataTag: "c") << Qt::Key_C << (Qt::KeyboardModifiers)Qt::NoModifier << QString("56");
3497
3498 // 1. mac doesn't do these,
3499 // 2. some WinCE devices do not have modifiers
3500#if !defined(Q_OS_DARWIN)
3501 QTest::newRow(dataTag: "ctrl-right") << Qt::Key_Right << (Qt::KeyboardModifiers)Qt::ControlModifier << QString("56");
3502 QTest::newRow(dataTag: "ctrl-left") << Qt::Key_Left << (Qt::KeyboardModifiers)Qt::ControlModifier << QString("12");
3503#endif
3504}
3505
3506void tst_QDateTimeEdit::nextPrevSection()
3507{
3508 QFETCH(Qt::Key, key);
3509 QFETCH(Qt::KeyboardModifiers, modifiers);
3510 QFETCH(QString, selectedText);
3511
3512 EditorDateEdit edit;
3513 edit.setDisplayFormat("hh/mm/bc9ss");
3514 edit.setTime(QTime(12, 34, 56));
3515 edit.show();
3516 edit.setSelectedSection(QDateTimeEdit::MinuteSection);
3517 QCOMPARE(edit.lineEdit()->selectedText(), QString("34")); // selftest
3518 QTest::keyClick(widget: &edit, key, modifier: modifiers);
3519 QCOMPARE(edit.lineEdit()->selectedText(), selectedText);
3520}
3521
3522void tst_QDateTimeEdit::dateEditTimeEditFormats()
3523{
3524 QTimeEdit t;
3525 t.setDisplayFormat("hh yyyy");
3526 QCOMPARE(t.displayedSections(), QDateTimeEdit::HourSection);
3527
3528 QDateEdit d;
3529 d.setDisplayFormat("hh yyyy");
3530 QCOMPARE(d.displayedSections(), QDateTimeEdit::YearSection);
3531}
3532
3533void tst_QDateTimeEdit::timeSpec_data()
3534{
3535 QTest::addColumn<bool>(name: "useSetProperty");
3536 QTest::newRow(dataTag: "setProperty") << true;
3537 QTest::newRow(dataTag: "setTimeSpec") << false;
3538}
3539
3540void tst_QDateTimeEdit::timeSpec()
3541{
3542 QFETCH(bool, useSetProperty);
3543
3544 QDateTimeEdit edit;
3545 QCOMPARE(edit.dateTime().timeSpec(), edit.timeSpec());
3546 QCOMPARE(edit.minimumDateTime().timeSpec(), edit.timeSpec());
3547 QCOMPARE(edit.maximumDateTime().timeSpec(), edit.timeSpec());
3548 if (useSetProperty) {
3549 edit.setProperty(name: "timeSpec", value: Qt::UTC);
3550 } else {
3551 edit.setTimeSpec(Qt::UTC);
3552 }
3553 QCOMPARE(edit.minimumDateTime().timeSpec(), edit.timeSpec());
3554 QCOMPARE(edit.maximumDateTime().timeSpec(), edit.timeSpec());
3555 QCOMPARE(edit.dateTime().timeSpec(), edit.timeSpec());
3556 if (useSetProperty) {
3557 edit.setProperty(name: "timeSpec", value: Qt::LocalTime);
3558 } else {
3559 edit.setTimeSpec(Qt::LocalTime);
3560 }
3561 const QDateTime dt = edit.dateTime();
3562 QCOMPARE(edit.timeSpec(), Qt::LocalTime);
3563 const QDateTime utc = dt.toUTC();
3564 if (dt.time() != utc.time()) {
3565 const QDateTime min(QDate(1999, 1, 1), QTime(1, 0, 0), Qt::LocalTime);
3566 edit.setMinimumDateTime(min);
3567 QCOMPARE(edit.minimumTime(), min.time());
3568 if (useSetProperty) {
3569 edit.setProperty(name: "timeSpec", value: Qt::UTC);
3570 } else {
3571 edit.setTimeSpec(Qt::UTC);
3572 }
3573 QVERIFY(edit.minimumTime() != min.time());
3574 QVERIFY(edit.minimumDateTime().timeSpec() != min.timeSpec());
3575 QCOMPARE(edit.minimumDateTime().toSecsSinceEpoch(), min.toSecsSinceEpoch());
3576 } else {
3577 QSKIP("Not tested in the GMT timezone");
3578 }
3579}
3580
3581void tst_QDateTimeEdit::timeSpecBug()
3582{
3583 testWidget->setTimeSpec(Qt::UTC);
3584 testWidget->setDisplayFormat("hh:mm");
3585 testWidget->setTime(QTime(2, 2));
3586 const QString oldText = testWidget->text();
3587 const QDateTime oldDateTime = testWidget->dateTime();
3588 QTest::keyClick(widget: testWidget, key: Qt::Key_Tab);
3589 QCOMPARE(oldDateTime, testWidget->dateTime());
3590 QCOMPARE(oldText, testWidget->text());
3591}
3592
3593void tst_QDateTimeEdit::timeSpecInit()
3594{
3595 QDateTime utc(QDate(2000, 1, 1), QTime(12, 0, 0), Qt::UTC);
3596 QDateTimeEdit widget(utc);
3597 QCOMPARE(widget.dateTime(), utc);
3598}
3599
3600void tst_QDateTimeEdit::cachedDayTest()
3601{
3602 testWidget->setDisplayFormat("MM/dd");
3603 testWidget->setDate(QDate(2007, 1, 30));
3604 testWidget->setCurrentSection(QDateTimeEdit::DaySection);
3605 //QTest::keyClick(testWidget->lineEdit(), Qt::Key_Up); // this doesn't work
3606 //on Mac. Qt Test bug? ###
3607 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3608 testWidget->setCurrentSection(QDateTimeEdit::MonthSection);
3609 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3610 QCOMPARE(testWidget->date(), QDate(2007, 2, 28));
3611 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3612 QCOMPARE(testWidget->date(), QDate(2007, 3, 31));
3613 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
3614 QCOMPARE(testWidget->date(), QDate(2007, 2, 28));
3615 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
3616 QCOMPARE(testWidget->date(), QDate(2007, 1, 31));
3617
3618 testWidget->setCurrentSection(QDateTimeEdit::DaySection);
3619 QTest::keyClick(widget: testWidget, key: Qt::Key_Down);
3620 QCOMPARE(testWidget->date(), QDate(2007, 1, 30));
3621 testWidget->setCurrentSection(QDateTimeEdit::MonthSection);
3622 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3623 QCOMPARE(testWidget->date(), QDate(2007, 2, 28));
3624 testWidget->setCurrentSection(QDateTimeEdit::MonthSection);
3625 QTest::keyClick(widget: testWidget, key: Qt::Key_Up);
3626 QCOMPARE(testWidget->date(), QDate(2007, 3, 30));
3627}
3628
3629void tst_QDateTimeEdit::monthEdgeCase()
3630{
3631 EditorDateEdit edit;
3632 edit.setLocale(QLocale("fr_FR"));
3633 edit.setDisplayFormat("MMM d");
3634 edit.setDate(QDate(2000, 1, 1));
3635 QCOMPARE(edit.text(), QString("janv. 1"));
3636 edit.lineEdit()->setCursorPosition(5);
3637 QTest::keyClick(widget: &edit, key: Qt::Key_Backspace);
3638 QCOMPARE(edit.text(), QString("janv 1"));
3639}
3640
3641class RestoreLocaler
3642{
3643public:
3644 RestoreLocaler()
3645 : old(QLocale())
3646 {}
3647
3648 ~RestoreLocaler()
3649 {
3650 QLocale::setDefault(old);
3651 }
3652private:
3653 const QLocale old;
3654};
3655
3656void tst_QDateTimeEdit::setLocale()
3657{
3658 RestoreLocaler r;
3659 QLocale::setDefault(QLocale("en_US"));
3660 {
3661 EditorDateEdit edit;
3662 edit.setDisplayFormat("MMMM d");
3663 edit.setDate(QDate(2000, 1, 1));
3664 QCOMPARE(edit.text(), QString("January 1"));
3665 }
3666 QLocale::setDefault(QLocale("no_NO"));
3667 {
3668 EditorDateEdit edit;
3669 edit.setDisplayFormat("MMMM d");
3670 edit.setDate(QDate(2000, 1, 1));
3671 QCOMPARE(edit.text().toLower(), QString("januar 1"));
3672 // I get Januar on Mac and januar on linux
3673 }
3674 QLocale::setDefault(QLocale("en_US"));
3675 {
3676 EditorDateEdit edit;
3677 edit.setDisplayFormat("MMMM d");
3678 edit.setDate(QDate(2000, 1, 1));
3679 QCOMPARE(edit.text(), QString("January 1"));
3680 edit.setLocale(QLocale("no_NO"));
3681 QCOMPARE(edit.text().toLower(), QString("januar 1"));
3682 edit.setLocale(QLocale("no_NO"));
3683 }
3684}
3685
3686void tst_QDateTimeEdit::potentialYYValueBug()
3687{
3688 EditorDateEdit edit;
3689 edit.setDisplayFormat("dd/MM/yy");
3690 QCOMPARE(edit.minimumDate(), QDate(1752, 9, 14));
3691 edit.setDate(edit.minimumDate());
3692 edit.lineEdit()->setFocus();
3693
3694#ifdef Q_OS_MAC
3695 QTest::keyClick(&edit, Qt::Key_Right, Qt::ControlModifier);
3696#else
3697 QTest::keyClick(widget: &edit, key: Qt::Key_End);
3698#endif
3699 QTest::keyClick(widget: &edit, key: Qt::Key_Backspace);
3700#ifdef Q_OS_MAC
3701 QEXPECT_FAIL("", "QTBUG-23674", Abort);
3702#endif
3703 QCOMPARE(edit.text(), QString("14/09/5"));
3704}
3705
3706void tst_QDateTimeEdit::textSectionAtEnd()
3707{
3708 EditorDateEdit edit;
3709 edit.setDisplayFormat("MMMM");
3710 edit.setDate(QDate(2000, 1, 1));
3711 edit.lineEdit()->setFocus();
3712#ifdef Q_OS_MAC
3713 QTest::keyClick(&edit, Qt::Key_Right, Qt::ControlModifier);
3714#else
3715 QTest::keyClick(widget: &edit, key: Qt::Key_End);
3716#endif
3717 QTest::keyClick(widget: &edit, key: Qt::Key_Backspace);
3718#ifdef Q_OS_MAC
3719 QEXPECT_FAIL("", "QTBUG-23674", Abort);
3720#endif
3721 QCOMPARE(edit.text(), QString("Januar"));
3722}
3723
3724void tst_QDateTimeEdit::keypadAutoAdvance_data()
3725{
3726 QTest::addColumn<Qt::KeyboardModifiers>(name: "modifiers");
3727 QTest::newRow(dataTag: "None") << (Qt::KeyboardModifiers)Qt::NoModifier;
3728 QTest::newRow(dataTag: "Keypad") << (Qt::KeyboardModifiers)Qt::KeypadModifier;
3729 // QTBUG-7842: Using KeyPad with shift (numlock off)
3730 QTest::newRow(dataTag: "Keypad+Shift") << (Qt::KeyboardModifiers)(Qt::KeypadModifier|Qt::ShiftModifier);
3731}
3732
3733void tst_QDateTimeEdit::keypadAutoAdvance()
3734{
3735 QFETCH(Qt::KeyboardModifiers, modifiers);
3736
3737 EditorDateEdit edit;
3738 edit.setDate(QDate(2000, 2, 1));
3739 edit.setDisplayFormat("dd/MM");
3740#ifdef Q_OS_MAC
3741 QTest::keyClick(&edit, Qt::Key_Left, Qt::ControlModifier);
3742#else
3743 QTest::keyClick(widget: &edit, key: Qt::Key_Home);
3744#endif
3745 QTest::keyClick(widget: &edit, key: Qt::Key_Return);
3746 QCOMPARE(edit.lineEdit()->selectedText(), QString("01"));
3747 QTest::keyClick(widget: &edit, key: Qt::Key_1, modifier: modifiers);
3748 QTest::keyClick(widget: &edit, key: Qt::Key_2, modifier: modifiers);
3749 QCOMPARE(edit.lineEdit()->selectedText(), QString("02"));
3750}
3751
3752void tst_QDateTimeEdit::task196924()
3753{
3754 EditorDateEdit edit;
3755 edit.setDisplayFormat("dd/M/yyyy");
3756 edit.setDate(QDate(2345, 6, 17));
3757 QCOMPARE(edit.text(), QString("17/6/2345"));
3758 QTest::keyClick(widget: &edit, key: Qt::Key_Tab);
3759 QCOMPARE(edit.lineEdit()->selectedText(), QString("6"));
3760 QTest::keyClick(widget: &edit, key: Qt::Key_3);
3761 QCOMPARE(edit.lineEdit()->selectedText(), QString("2345"));
3762 QCOMPARE(edit.text(), QString("17/3/2345"));
3763
3764 edit.setDisplayFormat("dd/MM/yyyy");
3765 edit.setDate(QDate(2345, 6, 17));
3766 edit.lineEdit()->setCursorPosition(0);
3767 QCOMPARE(edit.text(), QString("17/06/2345"));
3768 QTest::keyClick(widget: &edit, key: Qt::Key_Tab);
3769 QCOMPARE(edit.lineEdit()->selectedText(), QString("06"));
3770 QTest::keyClick(widget: &edit, key: Qt::Key_3);
3771 QCOMPARE(edit.lineEdit()->selectedText(), QString("2345"));
3772 QCOMPARE(edit.text(), QString("17/03/2345"));
3773}
3774
3775void tst_QDateTimeEdit::focusNextPrevChild()
3776{
3777 EditorDateEdit edit;
3778 edit.setDisplayFormat("dd/MM/yyyy");
3779
3780 edit.show();
3781 edit.setFocus();
3782 edit.setCurrentSection(QDateTimeEdit::DaySection);
3783
3784 QCOMPARE(edit.currentSection(), QDateTimeEdit::DaySection);
3785 edit.focusNextPrevChild(next: true);
3786 QCOMPARE(edit.currentSection(), QDateTimeEdit::MonthSection);
3787}
3788
3789void tst_QDateTimeEdit::taskQTBUG_12384_timeSpecShowTimeOnly()
3790{
3791 QDateTime time = QDateTime::fromString(s: "20100723 04:02:40", format: "yyyyMMdd hh:mm:ss");
3792 time.setTimeSpec(Qt::UTC);
3793
3794 EditorDateEdit edit;
3795 edit.setDisplayFormat("hh:mm:ss");
3796 edit.setTimeSpec(Qt::UTC);
3797 edit.setDateTime(time);
3798
3799 QCOMPARE(edit.minimumTime(), QTime(0, 0, 0, 0));
3800 QCOMPARE(edit.maximumTime(), QTime(23, 59, 59, 999));
3801 QCOMPARE(edit.time(), time.time());
3802}
3803
3804void tst_QDateTimeEdit::deleteCalendarWidget()
3805{
3806 {
3807 // setup
3808 QDateEdit edit;
3809 QVERIFY(!edit.calendarWidget());
3810 edit.setCalendarPopup(true);
3811 QVERIFY(edit.calendarWidget());
3812 edit.calendarWidget()->setObjectName("cw1");;
3813
3814 // delete
3815 delete edit.calendarWidget();
3816
3817 // it should create a new widget
3818 QVERIFY(edit.calendarWidget());
3819 QVERIFY(edit.calendarWidget()->objectName() != QLatin1String("cw1"));
3820 }
3821}
3822
3823void tst_QDateTimeEdit::setLocaleOnCalendarWidget()
3824{
3825 QDateEdit dateEdit;
3826 QList<QLocale> allLocales = QLocale::matchingLocales(
3827 language: QLocale::AnyLanguage,
3828 script: QLocale::AnyScript,
3829 country: QLocale::AnyCountry);
3830 QLocale c = QLocale::c();
3831 dateEdit.setCalendarPopup(true);
3832 dateEdit.setLocale(c);
3833 for (const QLocale& l : allLocales) {
3834 dateEdit.setLocale(l);
3835 const QLocale locCal = dateEdit.calendarWidget()->locale();
3836 const QLocale locEdit = dateEdit.locale();
3837 QCOMPARE(locCal.name(), locEdit.name());
3838 QVERIFY(locCal == locEdit);
3839 }
3840}
3841
3842#ifdef QT_BUILD_INTERNAL
3843
3844typedef QPair<Qt::Key, Qt::KeyboardModifier> KeyPair;
3845typedef QList<KeyPair> KeyPairList;
3846
3847Q_DECLARE_METATYPE(KeyPair)
3848
3849static inline KeyPair key(Qt::Key key, Qt::KeyboardModifier modifier = Qt::NoModifier) {
3850 return KeyPair(key, modifier);
3851}
3852
3853/*
3854When a QDateEdit has its display format set to 'yyyy/MM/dd', its day
3855set to 31 and its month set to 2, it will display 291 as the day until
3856the cursor is moved or the focus changed. This is because
3857QDateTimeParser::parse calls sectionSize() for the day section, which
3858returns 1 when it should return 2.
3859
3860This test verifies that QDateTimeEditPrivate has the correct text,
3861which is the text that is displayed until the cursor is moved or the
3862focus changed.
3863*/
3864
3865void tst_QDateTimeEdit::dateEditCorrectSectionSize_data()
3866{
3867 QTest::addColumn<QLocale>(name: "locale");
3868 QTest::addColumn<QDate>(name: "defaultDate");
3869 QTest::addColumn<QString>(name: "displayFormat");
3870 QTest::addColumn<KeyPairList>(name: "keyPresses");
3871 QTest::addColumn<QString>(name: "expectedDisplayString");
3872
3873 const QDate defaultDate(2000, 1, 1);
3874 const QLocale defaultLocale(QLocale::English, QLocale::Australia);
3875
3876 KeyPairList thirtyUpKeypresses;
3877 thirtyUpKeypresses.reserve(alloc: 30);
3878 for (int i = 0; i < 30; ++i) {
3879 thirtyUpKeypresses << key(key: Qt::Key_Up);
3880 }
3881
3882 // Make day the current section, set day to 31st (invalid for february),
3883 // move to month field, set month to february (2).
3884 KeyPairList threeDigitDayIssueKeypresses;
3885 threeDigitDayIssueKeypresses << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab)
3886 << key(key: Qt::Key_3) << key(key: Qt::Key_1) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_2);
3887
3888 // Same as above, except day-year-month format.
3889 KeyPairList threeDigitDayIssueKeypresses_DayYearMonth;
3890 threeDigitDayIssueKeypresses_DayYearMonth << key(key: Qt::Key_3) << key(key: Qt::Key_1) << key(key: Qt::Key_Tab)
3891 << key(key: Qt::Key_2);
3892
3893 // Same as threeDigitDayIssueKeypresses, except doesn't require the day to be corrected.
3894 KeyPairList threeDigitDayIssueKeypresses_Nofixday;
3895 threeDigitDayIssueKeypresses_Nofixday << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab)
3896 << key(key: Qt::Key_2) << key(key: Qt::Key_8) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_2);
3897
3898 // Set day to 31st (invalid for february), set month to february (2).
3899 KeyPairList reverseThreeDigitDayIssueKeypresses;
3900 reverseThreeDigitDayIssueKeypresses
3901 << key(key: Qt::Key_3) << key(key: Qt::Key_1) << key(key: Qt::Key_2);
3902
3903 // Make day the current section, set day to 31st, move to month field, set month to november (11).
3904 KeyPairList threeDigitDayIssueKeypresses_TwoDigitMonth;
3905 threeDigitDayIssueKeypresses_TwoDigitMonth << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab) << key(key: Qt::Key_3)
3906 << key(key: Qt::Key_1) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_1) << key(key: Qt::Key_1);
3907
3908 // Make day the current section, set day to 3rd, move to month field, set month to february (2).
3909 KeyPairList threeDigitDayIssueKeypresses_OneDigitDay;
3910 threeDigitDayIssueKeypresses_OneDigitDay << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab)
3911 << key(key: Qt::Key_3) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_2);
3912
3913 // Make day the current section, set day to 31st (invalid for february), move to month field,
3914 // set month to february (2).
3915 KeyPairList threeDigitDayIssueKeypresses_ShortMonthName;
3916 threeDigitDayIssueKeypresses_ShortMonthName << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab)
3917 << key(key: Qt::Key_3) << key(key: Qt::Key_1) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_Up);
3918
3919 // Make day the current section, set day to 31st (Monday), move to month field, set month to february (2).
3920 // Will probably never see this display format in a QDateTimeEdit, but it's good to test it anyway.
3921 KeyPairList threeDigitDayIssueKeypresses_DayName;
3922 threeDigitDayIssueKeypresses_DayName << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab) << thirtyUpKeypresses
3923 << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_2);
3924
3925 KeyPairList threeDigitDayIssueKeypresses_DayName_DayYearMonth;
3926 threeDigitDayIssueKeypresses_DayName_DayYearMonth << thirtyUpKeypresses << key(key: Qt::Key_Tab)
3927 << key(key: Qt::Key_Tab) << key(key: Qt::Key_2);
3928
3929 KeyPairList threeDigitDayIssueKeypresses_DayName_YearDayMonth;
3930 threeDigitDayIssueKeypresses_DayName_YearDayMonth << key(key: Qt::Key_Tab) << thirtyUpKeypresses
3931 << key(key: Qt::Key_Tab) << key(key: Qt::Key_2);
3932
3933 KeyPairList threeDigitDayIssueKeypresses_DayName_DayMonthYear;
3934 threeDigitDayIssueKeypresses_DayName_DayMonthYear << thirtyUpKeypresses << key(key: Qt::Key_Tab)
3935 << key(key: Qt::Key_2);
3936
3937 KeyPairList threeDigitDayIssueKeypresses_DayName_MonthDayYear;
3938 threeDigitDayIssueKeypresses_DayName_MonthDayYear << key(key: Qt::Key_Tab) << thirtyUpKeypresses
3939 << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_2);
3940
3941 // Make day the current section, set day to 31st (invalid for february), move to month field,
3942 // set month to february (2).
3943 KeyPairList threeDigitDayIssueKeypresses_YearDayMonth;
3944 threeDigitDayIssueKeypresses_YearDayMonth << key(key: Qt::Key_Tab) << key(key: Qt::Key_3) << key(key: Qt::Key_1)
3945 << key(key: Qt::Key_Tab) << key(key: Qt::Key_2);
3946
3947 // Make day the current section, set day to 31st, move to month field, set month to february (2).
3948 KeyPairList threeDigitDayIssueKeypresses_MonthDayYear;
3949 threeDigitDayIssueKeypresses_MonthDayYear << key(key: Qt::Key_Tab) << key(key: Qt::Key_3) << key(key: Qt::Key_1)
3950 << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_2);
3951
3952 // Same as above, except month-year-day format.
3953 KeyPairList threeDigitDayIssueKeypresses_MonthYearDay;
3954 threeDigitDayIssueKeypresses_MonthYearDay << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab) << key(key: Qt::Key_3)
3955 << key(key: Qt::Key_1) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier)
3956 << key(key: Qt::Key_2);
3957
3958 // Same as above, except short month name.
3959 KeyPairList threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay;
3960 threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << key(key: Qt::Key_Tab) << key(key: Qt::Key_Tab)
3961 << key(key: Qt::Key_3) << key(key: Qt::Key_1) << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier)
3962 << key(key: Qt::Key_Tab, modifier: Qt::ShiftModifier) << key(key: Qt::Key_Up);
3963
3964 KeyPairList shortAndLongNameIssueKeypresses;
3965 shortAndLongNameIssueKeypresses << key(key: Qt::Key_Tab) << key(key: Qt::Key_3) << key(key: Qt::Key_1) << key(key: Qt::Key_Up);
3966
3967 QTest::newRow(dataTag: "no fixday, leap, yy/M/dddd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yy/M/dddd")
3968 << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1(str: "00/2/Tuesday");
3969
3970 QTest::newRow(dataTag: "no fixday, leap, yy/M/ddd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yy/M/ddd")
3971 << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1(str: "00/2/Tue");
3972
3973 QTest::newRow(dataTag: "no fixday, leap, yy/MM/dddd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yy/MM/dddd")
3974 << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1(str: "00/02/Tuesday");
3975
3976 QTest::newRow(dataTag: "fixday, leap, yy/MM/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yy/MM/dd")
3977 << threeDigitDayIssueKeypresses << QString::fromLatin1(str: "00/02/29");
3978
3979 QTest::newRow(dataTag: "fixday, leap, yy/MM/d") << defaultLocale << defaultDate << QString::fromLatin1(str: "yy/MM/d")
3980 << threeDigitDayIssueKeypresses << QString::fromLatin1(str: "00/02/29");
3981
3982 QTest::newRow(dataTag: "fixday, leap, yyyy/M/d") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/M/d")
3983 << threeDigitDayIssueKeypresses << QString::fromLatin1(str: "2000/2/29");
3984
3985 QTest::newRow(dataTag: "no fixday, yyyy/M/d") << defaultLocale << defaultDate.addYears(years: 1) << QString::fromLatin1(str: "yyyy/M/d")
3986 << threeDigitDayIssueKeypresses_Nofixday << QString::fromLatin1(str: "2001/2/28");
3987
3988 QTest::newRow(dataTag: "fixday, leap, 2-digit month, yyyy/M/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/M/dd")
3989 << threeDigitDayIssueKeypresses_TwoDigitMonth << QString::fromLatin1(str: "2000/11/30");
3990
3991 QTest::newRow(dataTag: "no fixday, leap, 1-digit day, yyyy/M/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/M/dd")
3992 << threeDigitDayIssueKeypresses_OneDigitDay << QString::fromLatin1(str: "2000/2/03");
3993
3994 QTest::newRow(dataTag: "fixday, leap, yyyy/MM/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/MM/dd")
3995 << threeDigitDayIssueKeypresses << QString::fromLatin1(str: "2000/02/29");
3996
3997 QTest::newRow(dataTag: "no fixday, yyyy/MM/dd") << defaultLocale << defaultDate.addYears(years: 1) << QString::fromLatin1(str: "yyyy/MM/dd")
3998 << threeDigitDayIssueKeypresses_Nofixday << QString::fromLatin1(str: "2001/02/28");
3999
4000 QTest::newRow(dataTag: "fixday, leap, 2-digit month, yyyy/MM/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/MM/dd")
4001 << threeDigitDayIssueKeypresses_TwoDigitMonth << QString::fromLatin1(str: "2000/11/30");
4002
4003 QTest::newRow(dataTag: "no fixday, leap, yyyy/M/dddd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/M/dddd")
4004 << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1(str: "2000/2/Tuesday");
4005
4006 QTest::newRow(dataTag: "no fixday, leap, yyyy/MM/dddd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/MM/dddd")
4007 << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1(str: "2000/02/Tuesday");
4008
4009 QTest::newRow(dataTag: "fixday, leap, yyyy/dd/MM") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/dd/MM")
4010 << threeDigitDayIssueKeypresses_YearDayMonth << QString::fromLatin1(str: "2000/29/02");
4011
4012 QTest::newRow(dataTag: "fixday, leap, yyyy/dd/M") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/dd/M")
4013 << threeDigitDayIssueKeypresses_YearDayMonth << QString::fromLatin1(str: "2000/29/2");
4014
4015 QTest::newRow(dataTag: "fixday, leap, yyyy/d/M") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/d/M")
4016 << threeDigitDayIssueKeypresses_YearDayMonth << QString::fromLatin1(str: "2000/29/2");
4017
4018 QTest::newRow(dataTag: "fixday, leap, yyyy/MMM/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/MMM/dd")
4019 << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1(str: "2000/Feb/29");
4020
4021 QTest::newRow(dataTag: "fixday, leap, yyyy/MMM/d") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/MMM/d")
4022 << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1(str: "2000/Feb/29");
4023
4024 QTest::newRow(dataTag: "fixday, leap, yy/MMM/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "yy/MMM/dd")
4025 << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1(str: "00/Feb/29");
4026
4027 QTest::newRow(dataTag: "fixday, leap, yyyy/dddd/M") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/dddd/M")
4028 << threeDigitDayIssueKeypresses_DayName_YearDayMonth << QString::fromLatin1(str: "2000/Tuesday/2");
4029
4030 QTest::newRow(dataTag: "fixday, leap, yyyy/dddd/MM") << defaultLocale << defaultDate << QString::fromLatin1(str: "yyyy/dddd/MM")
4031 << threeDigitDayIssueKeypresses_DayName_YearDayMonth << QString::fromLatin1(str: "2000/Tuesday/02");
4032
4033 QTest::newRow(dataTag: "fixday, leap, d/M/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "d/M/yyyy")
4034 << reverseThreeDigitDayIssueKeypresses << QString::fromLatin1(str: "29/2/2000");
4035
4036 QTest::newRow(dataTag: "fixday, leap, dd/MM/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "dd/MM/yyyy")
4037 << reverseThreeDigitDayIssueKeypresses << QString::fromLatin1(str: "29/02/2000");
4038
4039 QTest::newRow(dataTag: "fixday, dd/MM/yyyy") << defaultLocale << defaultDate.addYears(years: 1) << QString::fromLatin1(str: "dd/MM/yyyy")
4040 << reverseThreeDigitDayIssueKeypresses << QString::fromLatin1(str: "28/02/2001");
4041
4042 QTest::newRow(dataTag: "fixday, leap, dddd/MM/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "dddd/MM/yyyy")
4043 << threeDigitDayIssueKeypresses_DayName_DayMonthYear << QString::fromLatin1(str: "Tuesday/02/2000");
4044
4045 QTest::newRow(dataTag: "fixday, leap, d/yy/M") << defaultLocale << defaultDate << QString::fromLatin1(str: "d/yy/M")
4046 << threeDigitDayIssueKeypresses_DayYearMonth << QString::fromLatin1(str: "29/00/2");
4047
4048 QTest::newRow(dataTag: "fixday, leap, d/yyyy/M") << defaultLocale << defaultDate << QString::fromLatin1(str: "d/yyyy/M")
4049 << threeDigitDayIssueKeypresses_DayYearMonth << QString::fromLatin1(str: "29/2000/2");
4050
4051 QTest::newRow(dataTag: "fixday, leap, d/yyyy/MM") << defaultLocale << defaultDate << QString::fromLatin1(str: "d/yyyy/MM")
4052 << threeDigitDayIssueKeypresses_DayYearMonth << QString::fromLatin1(str: "29/2000/02");
4053
4054 QTest::newRow(dataTag: "fixday, leap, dd/yy/MM") << defaultLocale << defaultDate << QString::fromLatin1(str: "dd/yy/MM")
4055 << threeDigitDayIssueKeypresses_DayYearMonth << QString::fromLatin1(str: "29/00/02");
4056
4057 QTest::newRow(dataTag: "fixday, leap, dd/yyyy/M") << defaultLocale << defaultDate << QString::fromLatin1(str: "dd/yyyy/M")
4058 << threeDigitDayIssueKeypresses_DayYearMonth << QString::fromLatin1(str: "29/2000/2");
4059
4060 QTest::newRow(dataTag: "fixday, leap, dd/yyyy/MM") << defaultLocale << defaultDate << QString::fromLatin1(str: "dd/yyyy/MM")
4061 << threeDigitDayIssueKeypresses_DayYearMonth << QString::fromLatin1(str: "29/2000/02");
4062
4063 QTest::newRow(dataTag: "fixday, leap, dddd/yy/M") << defaultLocale << defaultDate << QString::fromLatin1(str: "dddd/yy/M")
4064 << threeDigitDayIssueKeypresses_DayName_DayYearMonth << QString::fromLatin1(str: "Tuesday/00/2");
4065
4066 QTest::newRow(dataTag: "fixday, leap, dddd/yy/MM") << defaultLocale << defaultDate << QString::fromLatin1(str: "dddd/yy/MM")
4067 << threeDigitDayIssueKeypresses_DayName_DayYearMonth << QString::fromLatin1(str: "Tuesday/00/02");
4068
4069 QTest::newRow(dataTag: "fixday, leap, M/d/yy") << defaultLocale << defaultDate << QString::fromLatin1(str: "M/d/yy")
4070 << threeDigitDayIssueKeypresses_MonthDayYear << QString::fromLatin1(str: "2/29/00");
4071
4072 QTest::newRow(dataTag: "fixday, leap, M/d/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "M/d/yyyy")
4073 << threeDigitDayIssueKeypresses_MonthDayYear << QString::fromLatin1(str: "2/29/2000");
4074
4075 QTest::newRow(dataTag: "fixday, leap, M/dd/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "M/dd/yyyy")
4076 << threeDigitDayIssueKeypresses_MonthDayYear << QString::fromLatin1(str: "2/29/2000");
4077
4078 QTest::newRow(dataTag: "fixday, leap, M/dddd/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "M/dddd/yyyy")
4079 << threeDigitDayIssueKeypresses_DayName_MonthDayYear << QString::fromLatin1(str: "2/Tuesday/2000");
4080
4081 QTest::newRow(dataTag: "fixday, leap, MM/dd/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "MM/dd/yyyy")
4082 << threeDigitDayIssueKeypresses_MonthDayYear << QString::fromLatin1(str: "02/29/2000");
4083
4084 QTest::newRow(dataTag: "fixday, leap, MM/dddd/yyyy") << defaultLocale << defaultDate << QString::fromLatin1(str: "MM/dddd/yyyy")
4085 << threeDigitDayIssueKeypresses_DayName_MonthDayYear << QString::fromLatin1(str: "02/Tuesday/2000");
4086
4087 QTest::newRow(dataTag: "fixday, leap, M/yyyy/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "M/yyyy/dd")
4088 << threeDigitDayIssueKeypresses_MonthYearDay << QString::fromLatin1(str: "2/2000/29");
4089
4090 QTest::newRow(dataTag: "fixday, leap, M/yy/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "M/yy/dd")
4091 << threeDigitDayIssueKeypresses_MonthYearDay << QString::fromLatin1(str: "2/00/29");
4092
4093 QTest::newRow(dataTag: "fixday, leap, M/yy/d") << defaultLocale << defaultDate << QString::fromLatin1(str: "M/yy/d")
4094 << threeDigitDayIssueKeypresses_MonthYearDay << QString::fromLatin1(str: "2/00/29");
4095
4096 QTest::newRow(dataTag: "fixday, leap, MM/yyyy/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "MM/yyyy/dd")
4097 << threeDigitDayIssueKeypresses_MonthYearDay << QString::fromLatin1(str: "02/2000/29");
4098
4099 QTest::newRow(dataTag: "fixday, leap, MMM/yy/d") << defaultLocale << defaultDate << QString::fromLatin1(str: "MMM/yy/d")
4100 << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1(str: "Feb/00/29");
4101
4102 QTest::newRow(dataTag: "fixday, leap, MMM/yyyy/d") << defaultLocale << defaultDate << QString::fromLatin1(str: "MMM/yyyy/d")
4103 << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1(str: "Feb/2000/29");
4104
4105 QTest::newRow(dataTag: "fixday, MMM/yyyy/d") << defaultLocale << defaultDate.addYears(years: 1) << QString::fromLatin1(str: "MMM/yyyy/d")
4106 << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1(str: "Feb/2001/28");
4107
4108 QTest::newRow(dataTag: "fixday, leap, MMM/yyyy/dd") << defaultLocale << defaultDate << QString::fromLatin1(str: "MMM/yyyy/dd")
4109 << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1(str: "Feb/2000/29");
4110
4111 QTest::newRow(dataTag: "fixday, leap, dddd, dd. MMMM yyyy") << defaultLocale
4112 << defaultDate << QString::fromLatin1(str: "dddd, dd. MMMM yyyy")
4113 << shortAndLongNameIssueKeypresses << QString::fromLatin1(str: "Tuesday, 29. February 2000");
4114
4115 QTest::newRow(dataTag: "fixday, leap, german, dddd, dd. MMMM yyyy") << QLocale(QLocale::German, QLocale::Germany)
4116 << defaultDate << QString::fromLatin1(str: "dddd, dd. MMMM yyyy")
4117 << shortAndLongNameIssueKeypresses << QString::fromLatin1(str: "Dienstag, 29. Februar 2000");
4118}
4119
4120void tst_QDateTimeEdit::dateEditCorrectSectionSize()
4121{
4122 QFETCH(QLocale, locale);
4123 QFETCH(QDate, defaultDate);
4124 QFETCH(QString, displayFormat);
4125 QFETCH(KeyPairList, keyPresses);
4126 QFETCH(QString, expectedDisplayString);
4127
4128 QDateEdit edit;
4129 edit.setLocale(locale);
4130 edit.setDate(defaultDate);
4131 edit.setDisplayFormat(displayFormat);
4132 edit.show();
4133 edit.setFocus();
4134 // For some reason, we need to set the selected section for the dd/MM/yyyy tests,
4135 // otherwise the 3 is inserted at the front of 01/01/2000 (301/01/2000), instead of the
4136 // selected text being replaced. This is not an issue for the yyyy/MM/dd format though...
4137 edit.setSelectedSection(edit.sectionAt(index: 0));
4138
4139 foreach (const KeyPair &keyPair, keyPresses)
4140 QTest::keyClick(widget: &edit, key: keyPair.first, modifier: keyPair.second);
4141
4142 QDateTimeEditPrivate* edit_d_ptr(static_cast<QDateTimeEditPrivate*>(qt_widget_private(widget: &edit)));
4143 QCOMPARE(edit_d_ptr->QDateTimeParser::displayText(), expectedDisplayString);
4144}
4145#endif
4146
4147void tst_QDateTimeEdit::stepModifierKeys_data()
4148{
4149 QTest::addColumn<QDate>(name: "startDate");
4150 QTest::addColumn<int>(name: "stepModifier");
4151 QTest::addColumn<QDateTimeEdit::Section>(name: "section");
4152 QTest::addColumn<QTestEventList>(name: "keys");
4153 QTest::addColumn<QDate>(name: "expectedDate");
4154
4155 const auto keyList = {Qt::Key_Up, Qt::Key_Down};
4156
4157 const auto modifierList = {Qt::NoModifier,
4158 Qt::ShiftModifier,
4159 Qt::ControlModifier,
4160 Qt::AltModifier,
4161 Qt::MetaModifier};
4162
4163 const auto validStepModifierList = {Qt::NoModifier,
4164 Qt::ControlModifier,
4165 Qt::ShiftModifier};
4166
4167 const auto sections = {QDateTimeEdit::DaySection,
4168 QDateTimeEdit::MonthSection,
4169 QDateTimeEdit::YearSection};
4170
4171 for (auto key : keyList) {
4172
4173 const bool up = key == Qt::Key_Up;
4174 Q_ASSERT(up || key == Qt::Key_Down);
4175
4176 const QDate startDate(2000, up ? 2 : 12, 17);
4177
4178 for (auto modifier : modifierList) {
4179
4180 QTestEventList keys;
4181 keys.addKeyClick(qtKey: key, modifiers: modifier);
4182
4183 const auto modifierName = modifierToName(modifier);
4184 if (modifierName.isEmpty())
4185 continue;
4186
4187 for (auto stepModifier : validStepModifierList) {
4188
4189 const auto stepModifierName = modifierToName(modifier: stepModifier);
4190 if (stepModifierName.isEmpty())
4191 continue;
4192
4193 const int steps = (modifier & stepModifier ? 10 : 1)
4194 * (up ? 1 : -1);
4195
4196 for (const auto section : sections) {
4197
4198 const auto expectedDate = stepDate(startDate, section, steps);
4199 if (!expectedDate.isValid())
4200 continue;
4201
4202 const auto sectionName = sectionToName(section);
4203
4204 QTest::addRow(format: "%s%s%sWith%sKeyboardModifier",
4205 up ? "up" : "down",
4206 stepModifierName.latin1(),
4207 sectionName.latin1(),
4208 modifierName.latin1())
4209 << startDate
4210 << static_cast<int>(stepModifier)
4211 << section
4212 << keys
4213 << expectedDate;
4214 }
4215 }
4216 }
4217 }
4218}
4219
4220void tst_QDateTimeEdit::stepModifierKeys()
4221{
4222 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
4223 QSKIP("Wayland: This fails. Figure out why.");
4224
4225 QFETCH(QDate, startDate);
4226 QFETCH(int, stepModifier);
4227 QFETCH(QDateTimeEdit::Section, section);
4228 QFETCH(QTestEventList, keys);
4229 QFETCH(QDate, expectedDate);
4230
4231 // This can interfere with our stuff.
4232 testWidget->hide();
4233
4234 QDateTimeEdit edit(0);
4235 edit.setDate(startDate);
4236 edit.show();
4237 QVERIFY(QTest::qWaitForWindowActive(&edit));
4238 edit.setCurrentSection(section);
4239
4240 QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
4241 new StepModifierStyle);
4242 style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
4243 edit.setStyle(style.data());
4244
4245 QCOMPARE(edit.date(), startDate);
4246 keys.simulate(w: &edit);
4247 QCOMPARE(edit.date(), expectedDate);
4248}
4249
4250void tst_QDateTimeEdit::stepModifierButtons_data()
4251{
4252 QTest::addColumn<QStyle::SubControl>(name: "subControl");
4253 QTest::addColumn<int>(name: "stepModifier");
4254 QTest::addColumn<Qt::KeyboardModifiers>(name: "modifiers");
4255 QTest::addColumn<QDateTimeEdit::Section>(name: "section");
4256 QTest::addColumn<QTime>(name: "startTime");
4257 QTest::addColumn<QTime>(name: "expectedTime");
4258
4259 const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
4260
4261 const auto modifierList = {Qt::NoModifier,
4262 Qt::ShiftModifier,
4263 Qt::ControlModifier,
4264 Qt::AltModifier,
4265 Qt::MetaModifier};
4266
4267 const auto validStepModifierList = {Qt::NoModifier,
4268 Qt::ControlModifier,
4269 Qt::ShiftModifier};
4270
4271 const auto sections = {QDateTimeEdit::SecondSection,
4272 QDateTimeEdit::MinuteSection,
4273 QDateTimeEdit::HourSection};
4274
4275 const QTime startTime(12, 36, 24);
4276
4277 for (auto subControl : subControls) {
4278
4279 const bool up = subControl == QStyle::SC_SpinBoxUp;
4280 Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
4281
4282 for (auto modifier : modifierList) {
4283
4284 const Qt::KeyboardModifiers modifiers(modifier);
4285
4286 const auto modifierName = modifierToName(modifier);
4287 if (modifierName.isEmpty())
4288 continue;
4289
4290 for (auto stepModifier : validStepModifierList) {
4291
4292 const auto stepModifierName = modifierToName(modifier: stepModifier);
4293 if (stepModifierName.isEmpty())
4294 continue;
4295
4296 const int steps = (modifier & stepModifier ? 10 : 1)
4297 * (up ? 1 : -1);
4298
4299 for (const auto section : sections) {
4300
4301 const auto expectedTime = stepTime(startTime, section, steps);
4302 if (!expectedTime.isValid())
4303 continue;
4304
4305 const auto sectionName = sectionToName(section);
4306
4307 QTest::addRow(format: "%s%s%sWith%sKeyboardModifier",
4308 up ? "up" : "down",
4309 stepModifierName.latin1(),
4310 sectionName.latin1(),
4311 modifierName.latin1())
4312 << subControl
4313 << static_cast<int>(stepModifier)
4314 << modifiers
4315 << section
4316 << startTime
4317 << expectedTime;
4318 }
4319 }
4320 }
4321 }
4322}
4323
4324void tst_QDateTimeEdit::stepModifierButtons()
4325{
4326 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
4327 QSKIP("Wayland: This fails. Figure out why.");
4328
4329 QFETCH(QStyle::SubControl, subControl);
4330 QFETCH(int, stepModifier);
4331 QFETCH(Qt::KeyboardModifiers, modifiers);
4332 QFETCH(QDateTimeEdit::Section, section);
4333 QFETCH(QTime, startTime);
4334 QFETCH(QTime, expectedTime);
4335
4336 testWidget->hide();
4337
4338 EditorDateEdit edit(0);
4339 edit.setTime(startTime);
4340 edit.show();
4341 QVERIFY(QTest::qWaitForWindowActive(&edit));
4342 edit.setCurrentSection(section);
4343
4344 QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
4345 new StepModifierStyle);
4346 style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
4347 edit.setStyle(style.data());
4348
4349 QStyleOptionSpinBox spinBoxStyleOption;
4350 edit.initStyleOption(option: &spinBoxStyleOption);
4351
4352 const QRect buttonRect = edit.style()->subControlRect(
4353 cc: QStyle::CC_SpinBox, opt: &spinBoxStyleOption, sc: subControl, widget: &edit);
4354
4355 QCOMPARE(edit.time(), startTime);
4356 QTest::mouseClick(widget: &edit, button: Qt::LeftButton, stateKey: modifiers, pos: buttonRect.center());
4357 QCOMPARE(edit.time(), expectedTime);
4358}
4359
4360void tst_QDateTimeEdit::stepModifierPressAndHold_data()
4361{
4362 QTest::addColumn<QStyle::SubControl>(name: "subControl");
4363 QTest::addColumn<int>(name: "stepModifier");
4364 QTest::addColumn<Qt::KeyboardModifiers>(name: "modifiers");
4365 QTest::addColumn<int>(name: "expectedStepModifier");
4366
4367 const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
4368
4369 const auto modifierList = {Qt::NoModifier,
4370 Qt::ShiftModifier,
4371 Qt::ControlModifier,
4372 Qt::AltModifier,
4373 Qt::MetaModifier};
4374
4375 const auto validStepModifierList = {Qt::NoModifier,
4376 Qt::ControlModifier,
4377 Qt::ShiftModifier};
4378
4379 for (auto subControl : subControls) {
4380
4381 const bool up = subControl == QStyle::SC_SpinBoxUp;
4382 Q_ASSERT(up || subControl == QStyle::SC_SpinBoxDown);
4383
4384 for (auto modifier : modifierList) {
4385
4386 const Qt::KeyboardModifiers modifiers(modifier);
4387
4388 const auto modifierName = modifierToName(modifier);
4389 if (modifierName.isEmpty())
4390 continue;
4391
4392 for (auto stepModifier : validStepModifierList) {
4393
4394 const auto stepModifierName = modifierToName(modifier: stepModifier);
4395 if (stepModifierName.isEmpty())
4396 continue;
4397
4398 const int steps = (modifier & stepModifier ? 10 : 1)
4399 * (up ? 1 : -1);
4400
4401 QTest::addRow(format: "%s%sWith%sKeyboardModifier",
4402 up ? "up" : "down",
4403 stepModifierName.latin1(),
4404 modifierName.latin1())
4405 << subControl
4406 << static_cast<int>(stepModifier)
4407 << modifiers
4408 << steps;
4409 }
4410 }
4411 }
4412}
4413
4414void tst_QDateTimeEdit::stepModifierPressAndHold()
4415{
4416 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
4417 QSKIP("Wayland: This fails. Figure out why.");
4418
4419 QFETCH(QStyle::SubControl, subControl);
4420 QFETCH(int, stepModifier);
4421 QFETCH(Qt::KeyboardModifiers, modifiers);
4422 QFETCH(int, expectedStepModifier);
4423
4424 const QDate startDate(2000, 1, 1);
4425
4426 testWidget->hide();
4427
4428 EditorDateEdit edit(0);
4429 edit.setDate(startDate);
4430
4431 QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
4432 new StepModifierStyle(new PressAndHoldStyle));
4433 stepModifierStyle->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
4434 edit.setStyle(stepModifierStyle.data());
4435
4436 QSignalSpy spy(&edit, &EditorDateEdit::dateChanged);
4437
4438 edit.show();
4439 QVERIFY(QTest::qWaitForWindowActive(&edit));
4440 edit.setCurrentSection(QDateTimeEdit::YearSection);
4441
4442 QStyleOptionSpinBox spinBoxStyleOption;
4443 edit.initStyleOption(option: &spinBoxStyleOption);
4444
4445 const QRect buttonRect = edit.style()->subControlRect(
4446 cc: QStyle::CC_SpinBox, opt: &spinBoxStyleOption, sc: subControl, widget: &edit);
4447
4448 QTest::mousePress(widget: &edit, button: Qt::LeftButton, stateKey: modifiers, pos: buttonRect.center());
4449 QTRY_VERIFY(spy.length() >= 3);
4450 QTest::mouseRelease(widget: &edit, button: Qt::LeftButton, stateKey: modifiers, pos: buttonRect.center());
4451
4452 const auto value = spy.last().at(i: 0);
4453 QVERIFY(value.type() == QVariant::Date);
4454 const QDate expectedDate = startDate.addYears(years: spy.length() *
4455 expectedStepModifier);
4456 QCOMPARE(value.toDate(), expectedDate);
4457}
4458
4459#if QT_CONFIG(timezone)
4460/*
4461 The following tests verify correct handling of the spring forward gap; which
4462 hour is skipped, and on which day, depends on the local time zone. We try to
4463 make it reasonably robust by discovering the first day of spring in a given
4464 year, but we won't try to handle every situation.
4465
4466 If this function returns an invalid QDateTime, then the tests should be skipped.
4467*/
4468static QDateTime findSpring(int year, const QTimeZone &timeZone)
4469{
4470 if (!timeZone.hasTransitions())
4471 return QDateTime();
4472
4473 // Southern hemisphere spring is after midsummer
4474 const QDateTime midSummer = QDate(year, 6, 21).startOfDay(zone: timeZone);
4475 const QTimeZone::OffsetData transition =
4476 midSummer.isDaylightTime() ? timeZone.previousTransition(beforeDateTime: midSummer)
4477 : timeZone.nextTransition(afterDateTime: midSummer);
4478 const QDateTime spring = transition.atUtc.toLocalTime();
4479 // there might have been DST at some point, but not in the year we care about
4480 if (spring.date().year() != year || !spring.isDaylightTime())
4481 return QDateTime();
4482
4483 return spring;
4484};
4485#endif
4486
4487/*!
4488 Test that typing in a time that is invalid due to spring forward gap
4489 produces reasonable results.
4490*/
4491void tst_QDateTimeEdit::springForward_data()
4492{
4493#if QT_CONFIG(timezone)
4494 QTest::addColumn<QDateTime>(name: "start");
4495 QTest::addColumn<QAbstractSpinBox::CorrectionMode>(name: "correctionMode");
4496 QTest::addColumn<QTime>(name: "inputTime");
4497 QTest::addColumn<QDateTime>(name: "expected");
4498
4499 const QTimeZone timeZone = QTimeZone::systemTimeZone();
4500 if (!timeZone.hasDaylightTime())
4501 QSKIP("This test needs to run in a timezone that observes DST!");
4502
4503 const QDateTime springTransition = findSpring(year: 2019, timeZone);
4504 if (!springTransition.isValid())
4505 QSKIP("Failed to obtain valid spring forward datetime for 2019!");
4506
4507 const QDate springDate = springTransition.date();
4508 const int gapWidth = timeZone.daylightTimeOffset(atDateTime: springTransition.addDays(days: 1));
4509 const QTime springGap = springTransition.time().addSecs(secs: -gapWidth);
4510 const QTime springGapMiddle = springTransition.time().addSecs(secs: -gapWidth/2);
4511
4512 QTest::addRow(format: "forward to %s, correct to previous", qPrintable(springGap.toString("hh:mm")))
4513 << QDateTime(springDate, springGap.addSecs(secs: -gapWidth))
4514 << QAbstractSpinBox::CorrectToPreviousValue
4515 << springGap
4516 << QDateTime(springDate, springGap.addSecs(secs: -gapWidth));
4517
4518 QTest::addRow(format: "back to %s, correct to previous", qPrintable(springGap.toString("hh:mm")))
4519 << springTransition
4520 << QAbstractSpinBox::CorrectToPreviousValue
4521 << springGap
4522 << springTransition;
4523
4524 QTest::addRow(format: "forward to %s, correct to nearest", qPrintable(springGap.toString("hh:mm")))
4525 << QDateTime(springDate, springGap.addSecs(secs: -gapWidth))
4526 << QAbstractSpinBox::CorrectToNearestValue
4527 << springGapMiddle
4528 << springTransition;
4529
4530 QTest::addRow(format: "back to %s, correct to nearest", qPrintable(springGap.toString("hh:mm")))
4531 << springTransition
4532 << QAbstractSpinBox::CorrectToNearestValue
4533 << springGapMiddle
4534 << springTransition;
4535
4536 QTest::addRow(format: "jump to %s, correct to nearest", qPrintable(springGapMiddle.toString("hh:mm")))
4537 << QDateTime(QDate(1980, 5, 10), springGap)
4538 << QAbstractSpinBox::CorrectToNearestValue
4539 << springGapMiddle
4540 << springTransition;
4541#else
4542 QSKIP("Needs timezone feature enabled");
4543#endif
4544}
4545
4546void tst_QDateTimeEdit::springForward()
4547{
4548#if QT_CONFIG(timezone)
4549 QFETCH(QDateTime, start);
4550 QFETCH(QAbstractSpinBox::CorrectionMode, correctionMode);
4551 QFETCH(QTime, inputTime);
4552 QFETCH(QDateTime, expected);
4553
4554 QDateTimeEdit edit;
4555 edit.setDisplayFormat(QLatin1String("dd.MM.yyyy hh:mm"));
4556 edit.setCorrectionMode(correctionMode);
4557
4558 // we always want to start with a valid time
4559 QVERIFY(start.isValid());
4560 edit.setDateTime(start);
4561
4562 edit.setSelectedSection(QDateTimeEdit::DaySection);
4563 const QDate date = expected.date();
4564 const QString day = QString::number(date.day()).rightJustified(width: 2, fill: QLatin1Char('0'));
4565 const QString month = QString::number(date.month()).rightJustified(width: 2, fill: QLatin1Char('0'));
4566 const QString year = QString::number(date.year());
4567 const QString hour = QString::number(inputTime.hour()).rightJustified(width: 2, fill: QLatin1Char('0'));
4568 const QString minute = QString::number(inputTime.minute()).rightJustified(width: 2, fill: QLatin1Char('0'));
4569 QTest::keyClicks(widget: &edit, sequence: day);
4570 QTest::keyClicks(widget: &edit, sequence: month);
4571 QTest::keyClicks(widget: &edit, sequence: year);
4572 QTest::keyClicks(widget: &edit, sequence: hour);
4573 QTest::keyClicks(widget: &edit, sequence: minute);
4574 QTest::keyClick(widget: &edit, key: Qt::Key_Return, modifier: {});
4575
4576 QCOMPARE(edit.dateTime(), expected);
4577#endif
4578}
4579
4580/*!
4581 Test that using the up/down spinners to modify a valid time into a time that
4582 is invalid due to daylight-saving changes produces reasonable results.
4583
4584 2007 is a year in which the DST transition in most tested places was not on the
4585 last or first day of the month, which allows us to test the various steps.
4586*/
4587void tst_QDateTimeEdit::stepIntoDSTGap_data()
4588{
4589#if QT_CONFIG(timezone)
4590 QTest::addColumn<QDateTime>(name: "start");
4591 QTest::addColumn<QDateTimeEdit::Section>(name: "section");
4592 QTest::addColumn<int>(name: "steps");
4593 QTest::addColumn<QDateTime>(name: "end");
4594
4595 const QTimeZone timeZone = QTimeZone("Europe/Oslo");
4596 if (!timeZone.hasDaylightTime())
4597 QSKIP("This test needs to run in a timezone that observes DST!");
4598
4599 const QDateTime springTransition = findSpring(year: 2007, timeZone);
4600 if (!springTransition.isValid())
4601 QSKIP("Failed to obtain valid spring forward datetime for 2007!");
4602
4603 const QDate spring = springTransition.date();
4604 const int gapWidth = timeZone.daylightTimeOffset(atDateTime: springTransition.addDays(days: 1));
4605 const QTime springGap = springTransition.time().addSecs(secs: -gapWidth);
4606
4607 // change hour
4608 if (springGap.hour() != 0) {
4609 QTest::addRow(format: "hour up into %s gap", qPrintable(springGap.toString("hh:mm")))
4610 << QDateTime(spring, springGap.addSecs(secs: -3600), timeZone)
4611 << QDateTimeEdit::HourSection
4612 << +1
4613 << springTransition;
4614
4615 // 3:00:10 into 2:00:10 should get us to 1:00:10
4616 QTest::addRow(format: "hour down into %s gap", qPrintable(springGap.toString("hh:mm")))
4617 << QDateTime(spring, springGap.addSecs(secs: 3610), timeZone)
4618 << QDateTimeEdit::HourSection
4619 << -1
4620 << QDateTime(spring, springGap.addSecs(secs: -3590));
4621 }
4622
4623 // change day
4624 if (spring.day() != 1) {
4625 // today's 2:05 is tomorrow's 3:05
4626 QTest::addRow(format: "day up into %s gap", qPrintable(springGap.toString("hh:mm")))
4627 << QDateTime(spring.addDays(days: -1), springGap.addSecs(secs: 300), timeZone)
4628 << QDateTimeEdit::DaySection
4629 << +1
4630 << springTransition.addSecs(secs: 300);
4631 }
4632
4633 if (spring.day() != spring.daysInMonth()) {
4634 QTest::addRow(format: "day down into %s gap", qPrintable(springGap.toString("hh:mm")))
4635 << QDateTime(spring.addDays(days: 1), springGap, timeZone)
4636 << QDateTimeEdit::DaySection
4637 << -1
4638 << springTransition;
4639 }
4640
4641 // 2018-03-25 - change month
4642 QTest::addRow(format: "month up into %s gap", qPrintable(springGap.toString("hh:mm")))
4643 << QDateTime(spring.addMonths(months: -1), springGap, timeZone)
4644 << QDateTimeEdit::MonthSection
4645 << +1
4646 << springTransition;
4647 QTest::addRow(format: "month down into %s gap", qPrintable(springGap.toString("hh:mm")))
4648 << QDateTime(spring.addMonths(months: 1), springGap, timeZone)
4649 << QDateTimeEdit::MonthSection
4650 << -1
4651 << springTransition;
4652
4653 // 2018-03-25 - change year
4654 QTest::addRow(format: "year up into %s gap", qPrintable(springGap.toString("hh:mm")))
4655 << QDateTime(spring.addYears(years: -1), springGap, timeZone)
4656 << QDateTimeEdit::YearSection
4657 << +1
4658 << springTransition;
4659 QTest::addRow(format: "year down into %s gap", qPrintable(springGap.toString("hh:mm")))
4660 << QDateTime(spring.addYears(years: 1), springGap, timeZone)
4661 << QDateTimeEdit::YearSection
4662 << -1
4663 << springTransition;
4664#else
4665 QSKIP("Needs timezone feature enabled");
4666#endif
4667}
4668
4669void tst_QDateTimeEdit::stepIntoDSTGap()
4670{
4671#if QT_CONFIG(timezone)
4672 QFETCH(QDateTime, start);
4673 QFETCH(QDateTimeEdit::Section, section);
4674 QFETCH(int, steps);
4675 QFETCH(QDateTime, end);
4676
4677 QDateTimeEdit edit;
4678 edit.setDisplayFormat(QLatin1String("dd.MM.yyyy hh:mm"));
4679
4680 // we always want to start with a valid time
4681 QVERIFY(start.isValid());
4682 edit.setDateTime(start);
4683
4684 edit.setSelectedSection(section);
4685
4686 // we want to end with a valid value
4687 QVERIFY(end.isValid());
4688
4689 const auto stepCount = qAbs(t: steps);
4690 for (int step = 0; step < stepCount; ++step)
4691 QTest::keyClick(widget: &edit, key: steps > 0 ? Qt::Key_Up : Qt::Key_Down, modifier: {});
4692
4693 QCOMPARE(edit.dateTime(), end);
4694#endif
4695}
4696
4697QTEST_MAIN(tst_QDateTimeEdit)
4698#include "tst_qdatetimeedit.moc"
4699

source code of qtbase/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp