1/****************************************************************************
2**
3** Copyright (C) 2016 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
32#include <qcalendarwidget.h>
33#include <qtoolbutton.h>
34#include <qspinbox.h>
35#include <qmenu.h>
36#include <qdebug.h>
37#include <qdatetime.h>
38#include <qtextformat.h>
39
40class tst_QCalendarWidget : public QObject
41{
42 Q_OBJECT
43
44private slots:
45 void getSetCheck();
46 void buttonClickCheck();
47
48 void setTextFormat();
49 void resetTextFormat();
50
51 void setWeekdayFormat();
52 void showPrevNext_data();
53 void showPrevNext();
54
55 void firstDayOfWeek();
56
57 void contentsMargins();
58};
59
60// Testing get/set functions
61void tst_QCalendarWidget::getSetCheck()
62{
63 QWidget topLevel;
64 QCalendarWidget object(&topLevel);
65
66 //horizontal header formats
67 object.setHorizontalHeaderFormat(QCalendarWidget::NoHorizontalHeader);
68 QCOMPARE(QCalendarWidget::NoHorizontalHeader, object.horizontalHeaderFormat());
69 object.setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);
70 QCOMPARE(QCalendarWidget::SingleLetterDayNames, object.horizontalHeaderFormat());
71 object.setHorizontalHeaderFormat(QCalendarWidget::ShortDayNames);
72 QCOMPARE(QCalendarWidget::ShortDayNames, object.horizontalHeaderFormat());
73 object.setHorizontalHeaderFormat(QCalendarWidget::LongDayNames);
74 QCOMPARE(QCalendarWidget::LongDayNames, object.horizontalHeaderFormat());
75 //vertical header formats
76 object.setVerticalHeaderFormat(QCalendarWidget::ISOWeekNumbers);
77 QCOMPARE(QCalendarWidget::ISOWeekNumbers, object.verticalHeaderFormat());
78 object.setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
79 QCOMPARE(QCalendarWidget::NoVerticalHeader, object.verticalHeaderFormat());
80 //maximum Date
81 QDate maxDate(2006, 7, 3);
82 object.setMaximumDate(maxDate);
83 QCOMPARE(maxDate, object.maximumDate());
84 //minimum date
85 QDate minDate(2004, 7, 3);
86 object.setMinimumDate(minDate);
87 QCOMPARE(minDate, object.minimumDate());
88 //day of week
89 object.setFirstDayOfWeek(Qt::Thursday);
90 QCOMPARE(Qt::Thursday, object.firstDayOfWeek());
91 //grid visible
92 object.setGridVisible(true);
93 QVERIFY(object.isGridVisible());
94 object.setGridVisible(false);
95 QVERIFY(!object.isGridVisible());
96 //header visible
97 object.setNavigationBarVisible(true);
98 QVERIFY(object.isNavigationBarVisible());
99 object.setNavigationBarVisible(false);
100 QVERIFY(!object.isNavigationBarVisible());
101 //selection mode
102 QCOMPARE(QCalendarWidget::SingleSelection, object.selectionMode());
103 object.setSelectionMode(QCalendarWidget::NoSelection);
104 QCOMPARE(QCalendarWidget::NoSelection, object.selectionMode());
105 object.setSelectionMode(QCalendarWidget::SingleSelection);
106 QCOMPARE(QCalendarWidget::SingleSelection, object.selectionMode());
107 //selected date
108 QDate selectedDate(2005, 7, 3);
109 QSignalSpy spy(&object, SIGNAL(selectionChanged()));
110 object.setSelectedDate(selectedDate);
111 QCOMPARE(spy.count(), 1);
112 QCOMPARE(selectedDate, object.selectedDate());
113 //month and year
114 object.setCurrentPage(year: 2004, month: 1);
115 QCOMPARE(1, object.monthShown());
116 QCOMPARE(2004, object.yearShown());
117 object.showNextMonth();
118 QCOMPARE(2, object.monthShown());
119 object.showPreviousMonth();
120 QCOMPARE(1, object.monthShown());
121 object.showNextYear();
122 QCOMPARE(2005, object.yearShown());
123 object.showPreviousYear();
124 QCOMPARE(2004, object.yearShown());
125 //date range
126 minDate = QDate(2006,1,1);
127 maxDate = QDate(2010,12,31);
128 object.setDateRange(min: minDate, max: maxDate);
129 QCOMPARE(maxDate, object.maximumDate());
130 QCOMPARE(minDate, object.minimumDate());
131
132 //date should not go beyond the minimum.
133 selectedDate = minDate.addDays(days: -10);
134 object.setSelectedDate(selectedDate);
135 QCOMPARE(minDate, object.selectedDate());
136 QVERIFY(selectedDate != object.selectedDate());
137 //date should not go beyond the maximum.
138 selectedDate = maxDate.addDays(days: 10);
139 object.setSelectedDate(selectedDate);
140 QCOMPARE(maxDate, object.selectedDate());
141 QVERIFY(selectedDate != object.selectedDate());
142 //show today
143 QDate today = QDate::currentDate();
144 object.showToday();
145 QCOMPARE(today.month(), object.monthShown());
146 QCOMPARE(today.year(), object.yearShown());
147 //slect a different date and move.
148 object.setSelectedDate(minDate);
149 object.showSelectedDate();
150 QCOMPARE(minDate.month(), object.monthShown());
151 QCOMPARE(minDate.year(), object.yearShown());
152}
153
154void tst_QCalendarWidget::buttonClickCheck()
155{
156#ifdef Q_OS_WINRT
157 QSKIP("Fails on WinRT - QTBUG-68297");
158#endif
159 if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland"), cs: Qt::CaseInsensitive))
160 QSKIP("Wayland: This fails. Figure out why.");
161
162 QCalendarWidget object;
163 QSize size = object.sizeHint();
164 object.setGeometry(ax: 0,ay: 0,aw: size.width(), ah: size.height());
165 object.show();
166 object.activateWindow();
167 QVERIFY(QTest::qWaitForWindowActive(&object));
168
169 QDate selectedDate(2005, 1, 1);
170 //click on the month buttons
171 int month = object.monthShown();
172 QToolButton *button = object.findChild<QToolButton *>(aName: "qt_calendar_prevmonth");
173 QTest::mouseClick(widget: button, button: Qt::LeftButton);
174 QCOMPARE(month > 1 ? month-1 : 12, object.monthShown());
175 button = object.findChild<QToolButton *>(aName: "qt_calendar_nextmonth");
176 QTest::mouseClick(widget: button, button: Qt::LeftButton);
177 QCOMPARE(month, object.monthShown());
178
179 button = object.findChild<QToolButton *>(aName: "qt_calendar_yearbutton");
180 QTest::mouseClick(widget: button, button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: button->rect().center(), delay: 2);
181 QVERIFY(!button->isVisible());
182 QSpinBox *spinbox = object.findChild<QSpinBox *>(aName: "qt_calendar_yearedit");
183 QTest::keyClick(widget: spinbox, key: '2');
184 QTest::keyClick(widget: spinbox, key: '0');
185 QTest::keyClick(widget: spinbox, key: '0');
186 QTest::keyClick(widget: spinbox, key: '6');
187 QWidget *widget = object.findChild<QWidget *>(aName: "qt_calendar_calendarview");
188 QTest::mouseMove(widget);
189 QTest::mouseClick(widget, button: Qt::LeftButton);
190 QCOMPARE(2006, object.yearShown());
191 QTest::mouseClick(widget: button, button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: button->rect().center(), delay: 2);
192 QTest::mouseMove(widget);
193 QTest::mouseClick(widget, button: Qt::LeftButton);
194 QCOMPARE(button->text(), "2006"); // Check that it is shown as a year should be
195 object.setSelectedDate(selectedDate);
196 object.showSelectedDate();
197 QTest::keyClick(widget, key: Qt::Key_Down);
198 QVERIFY(selectedDate != object.selectedDate());
199
200 object.setDateRange(min: QDate(2006,1,1), max: QDate(2006,2,28));
201 object.setSelectedDate(QDate(2006,1,1));
202 object.showSelectedDate();
203 button = object.findChild<QToolButton *>(aName: "qt_calendar_prevmonth");
204 QTest::mouseClick(widget: button, button: Qt::LeftButton);
205 QCOMPARE(1, object.monthShown());
206
207 button = object.findChild<QToolButton *>(aName: "qt_calendar_nextmonth");
208 QTest::mouseClick(widget: button, button: Qt::LeftButton);
209 QCOMPARE(2, object.monthShown());
210 QTest::mouseClick(widget: button, button: Qt::LeftButton);
211 QCOMPARE(2, object.monthShown());
212
213}
214
215void tst_QCalendarWidget::setTextFormat()
216{
217 QCalendarWidget calendar;
218 QTextCharFormat format;
219 format.setFontItalic(true);
220 format.setForeground(Qt::green);
221
222 const QDate date(1984, 10, 20);
223 calendar.setDateTextFormat(date, format);
224 QCOMPARE(calendar.dateTextFormat(date), format);
225}
226
227void tst_QCalendarWidget::resetTextFormat()
228{
229 QCalendarWidget calendar;
230 QTextCharFormat format;
231 format.setFontItalic(true);
232 format.setForeground(Qt::green);
233
234 const QDate date(1984, 10, 20);
235 calendar.setDateTextFormat(date, format);
236
237 calendar.setDateTextFormat(date: QDate(), format: QTextCharFormat());
238 QCOMPARE(calendar.dateTextFormat(date), QTextCharFormat());
239}
240
241void tst_QCalendarWidget::setWeekdayFormat()
242{
243 QCalendarWidget calendar;
244
245 QTextCharFormat format;
246 format.setFontItalic(true);
247 format.setForeground(Qt::green);
248
249 calendar.setWeekdayTextFormat(dayOfWeek: Qt::Wednesday, format);
250
251 // check the format of the a given month
252 for (int i = 1; i <= 31; ++i) {
253 const QDate date(1984, 10, i);
254 const Qt::DayOfWeek dayOfWeek = static_cast<Qt::DayOfWeek>(date.dayOfWeek());
255 if (dayOfWeek == Qt::Wednesday)
256 QCOMPARE(calendar.weekdayTextFormat(dayOfWeek), format);
257 else
258 QVERIFY(calendar.weekdayTextFormat(dayOfWeek) != format);
259 }
260}
261
262typedef void (QCalendarWidget::*ShowFunc)();
263Q_DECLARE_METATYPE(ShowFunc)
264
265void tst_QCalendarWidget::showPrevNext_data()
266{
267 QTest::addColumn<ShowFunc>(name: "function");
268 QTest::addColumn<QDate>(name: "dateOrigin");
269 QTest::addColumn<QDate>(name: "expectedDate");
270
271 QTest::newRow(dataTag: "showNextMonth") << &QCalendarWidget::showNextMonth << QDate(1984,7,30) << QDate(1984,8,30);
272 QTest::newRow(dataTag: "showPrevMonth") << &QCalendarWidget::showPreviousMonth << QDate(1984,7,30) << QDate(1984,6,30);
273 QTest::newRow(dataTag: "showNextYear") << &QCalendarWidget::showNextYear << QDate(1984,7,30) << QDate(1985,7,30);
274 QTest::newRow(dataTag: "showPrevYear") << &QCalendarWidget::showPreviousYear << QDate(1984,7,30) << QDate(1983,7,30);
275
276 QTest::newRow(dataTag: "showNextMonth limit") << &QCalendarWidget::showNextMonth << QDate(2007,12,4) << QDate(2008,1,4);
277 QTest::newRow(dataTag: "showPreviousMonth limit") << &QCalendarWidget::showPreviousMonth << QDate(2006,1,23) << QDate(2005,12,23);
278
279 QTest::newRow(dataTag: "showNextMonth now") << &QCalendarWidget::showNextMonth << QDate() << QDate::currentDate().addMonths(months: 1);
280 QTest::newRow(dataTag: "showNextYear now") << &QCalendarWidget::showNextYear << QDate() << QDate::currentDate().addYears(years: 1);
281 QTest::newRow(dataTag: "showPrevieousMonth now") << &QCalendarWidget::showPreviousMonth << QDate() << QDate::currentDate().addMonths(months: -1);
282 QTest::newRow(dataTag: "showPreviousYear now") << &QCalendarWidget::showPreviousYear << QDate() << QDate::currentDate().addYears(years: -1);
283
284 QTest::newRow(dataTag: "showToday now") << &QCalendarWidget::showToday << QDate(2000,1,31) << QDate::currentDate();
285 QTest::newRow(dataTag: "showNextMonth 31") << &QCalendarWidget::showNextMonth << QDate(2000,1,31) << QDate(2000,2,28);
286 QTest::newRow(dataTag: "selectedDate") << &QCalendarWidget::showSelectedDate << QDate(2008,2,29) << QDate(2008,2,29);
287
288}
289
290void tst_QCalendarWidget::showPrevNext()
291{
292 QFETCH(ShowFunc, function);
293 QFETCH(QDate, dateOrigin);
294 QFETCH(QDate, expectedDate);
295
296#ifdef Q_OS_WINRT
297 QSKIP("Fails on WinRT - QTBUG-68297");
298#endif
299
300 QCalendarWidget calWidget;
301 calWidget.show();
302 QVERIFY(QTest::qWaitForWindowExposed(&calWidget));
303 if(!dateOrigin.isNull()) {
304 calWidget.setSelectedDate(dateOrigin);
305 calWidget.setCurrentPage(year: dateOrigin.year(), month: dateOrigin.month());
306
307 QCOMPARE(calWidget.yearShown(), dateOrigin.year());
308 QCOMPARE(calWidget.monthShown(), dateOrigin.month());
309 } else {
310 QCOMPARE(calWidget.yearShown(), QDate::currentDate().year());
311 QCOMPARE(calWidget.monthShown(), QDate::currentDate().month());
312 }
313
314 (calWidget.*function)();
315
316 QCOMPARE(calWidget.yearShown(), expectedDate.year());
317 QCOMPARE(calWidget.monthShown(), expectedDate.month());
318
319 // QTBUG-4058
320 QToolButton *button = calWidget.findChild<QToolButton *>(aName: "qt_calendar_prevmonth");
321 QTest::mouseClick(widget: button, button: Qt::LeftButton);
322 expectedDate = expectedDate.addMonths(months: -1);
323 QCOMPARE(calWidget.yearShown(), expectedDate.year());
324 QCOMPARE(calWidget.monthShown(), expectedDate.month());
325
326 if(!dateOrigin.isNull()) {
327 //the selectedDate should not have changed
328 QCOMPARE(calWidget.selectedDate(), dateOrigin);
329 }
330}
331
332void tst_QCalendarWidget::firstDayOfWeek()
333{
334 // Ensure the default locale is chosen.
335 QCalendarWidget calendar;
336 QLocale locale;
337 QCOMPARE(calendar.firstDayOfWeek(), locale.firstDayOfWeek());
338
339 QLocale germanLocale(QLocale::German);
340 QLocale::setDefault(germanLocale);
341 QCalendarWidget germanLocaleCalendar;
342 QCOMPARE(germanLocaleCalendar.firstDayOfWeek(), germanLocale.firstDayOfWeek());
343
344 // Ensure calling setLocale works as well.
345 QLocale frenchLocale(QLocale::French);
346 calendar.setLocale(frenchLocale);
347 QCOMPARE(calendar.firstDayOfWeek(), frenchLocale.firstDayOfWeek());
348
349 // Ensure that widget-specific locale takes precedence over default.
350 QLocale::setDefault(QLocale::English);
351 QCOMPARE(calendar.firstDayOfWeek(), frenchLocale.firstDayOfWeek());
352
353 // Ensure that setting the locale of parent widget has an effect.
354 QWidget* parent = new QWidget;
355 calendar.setParent(parent);
356 QLocale hausaLocale(QLocale::Hausa);
357 parent->setLocale(hausaLocale);
358 QCOMPARE(calendar.firstDayOfWeek(), hausaLocale.firstDayOfWeek());
359
360 // Ensure that widget-specific locale takes precedence over parent.
361 calendar.setLocale(germanLocale);
362 // Sanity check...
363 QCOMPARE(calendar.locale(), germanLocale);
364 QCOMPARE(parent->locale(), hausaLocale);
365 QCOMPARE(calendar.firstDayOfWeek(), germanLocale.firstDayOfWeek());
366}
367
368void tst_QCalendarWidget::contentsMargins()
369{
370 QCalendarWidget calendar1;
371 QCalendarWidget calendar2;
372 calendar2.setContentsMargins(left: 10, top: 5, right: 20, bottom: 30);
373 QCOMPARE(calendar1.minimumSizeHint() + QSize(30, 35), calendar2.minimumSizeHint());
374}
375
376QTEST_MAIN(tst_QCalendarWidget)
377#include "tst_qcalendarwidget.moc"
378

source code of qtbase/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp