1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
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** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include "window.h"
52
53#include <QCalendarWidget>
54#include <QCheckBox>
55#include <QComboBox>
56#include <QDateEdit>
57#include <QGridLayout>
58#include <QGroupBox>
59#include <QLabel>
60#include <QLocale>
61#include <QTextCharFormat>
62
63//! [0]
64Window::Window(QWidget *parent)
65 : QWidget(parent)
66{
67 createPreviewGroupBox();
68 createGeneralOptionsGroupBox();
69 createDatesGroupBox();
70 createTextFormatsGroupBox();
71
72 QGridLayout *layout = new QGridLayout;
73 layout->addWidget(previewGroupBox, row: 0, column: 0);
74 layout->addWidget(generalOptionsGroupBox, row: 0, column: 1);
75 layout->addWidget(datesGroupBox, row: 1, column: 0);
76 layout->addWidget(textFormatsGroupBox, row: 1, column: 1);
77 layout->setSizeConstraint(QLayout::SetFixedSize);
78 setLayout(layout);
79
80 previewLayout->setRowMinimumHeight(row: 0, minSize: calendar->sizeHint().height());
81 previewLayout->setColumnMinimumWidth(column: 0, minSize: calendar->sizeHint().width());
82
83 setWindowTitle(tr(s: "Calendar Widget"));
84}
85//! [0]
86
87void Window::localeChanged(int index)
88{
89 const QLocale newLocale(localeCombo->itemData(index).toLocale());
90 calendar->setLocale(newLocale);
91 int newLocaleFirstDayIndex = firstDayCombo->findData(data: newLocale.firstDayOfWeek());
92 firstDayCombo->setCurrentIndex(newLocaleFirstDayIndex);
93}
94
95//! [1]
96void Window::firstDayChanged(int index)
97{
98 calendar->setFirstDayOfWeek(Qt::DayOfWeek(
99 firstDayCombo->itemData(index).toInt()));
100}
101//! [1]
102
103void Window::selectionModeChanged(int index)
104{
105 calendar->setSelectionMode(QCalendarWidget::SelectionMode(
106 selectionModeCombo->itemData(index).toInt()));
107}
108
109void Window::horizontalHeaderChanged(int index)
110{
111 calendar->setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat(
112 horizontalHeaderCombo->itemData(index).toInt()));
113}
114
115void Window::verticalHeaderChanged(int index)
116{
117 calendar->setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat(
118 verticalHeaderCombo->itemData(index).toInt()));
119}
120
121//! [2]
122void Window::selectedDateChanged()
123{
124 currentDateEdit->setDate(calendar->selectedDate());
125}
126//! [2]
127
128//! [3]
129void Window::minimumDateChanged(QDate date)
130{
131 calendar->setMinimumDate(date);
132 maximumDateEdit->setDate(calendar->maximumDate());
133}
134//! [3]
135
136//! [4]
137void Window::maximumDateChanged(QDate date)
138{
139 calendar->setMaximumDate(date);
140 minimumDateEdit->setDate(calendar->minimumDate());
141}
142//! [4]
143
144//! [5]
145void Window::weekdayFormatChanged()
146{
147 QTextCharFormat format;
148
149 format.setForeground(qvariant_cast<QColor>(
150 v: weekdayColorCombo->itemData(index: weekdayColorCombo->currentIndex())));
151 calendar->setWeekdayTextFormat(dayOfWeek: Qt::Monday, format);
152 calendar->setWeekdayTextFormat(dayOfWeek: Qt::Tuesday, format);
153 calendar->setWeekdayTextFormat(dayOfWeek: Qt::Wednesday, format);
154 calendar->setWeekdayTextFormat(dayOfWeek: Qt::Thursday, format);
155 calendar->setWeekdayTextFormat(dayOfWeek: Qt::Friday, format);
156}
157//! [5]
158
159//! [6]
160void Window::weekendFormatChanged()
161{
162 QTextCharFormat format;
163
164 format.setForeground(qvariant_cast<QColor>(
165 v: weekendColorCombo->itemData(index: weekendColorCombo->currentIndex())));
166 calendar->setWeekdayTextFormat(dayOfWeek: Qt::Saturday, format);
167 calendar->setWeekdayTextFormat(dayOfWeek: Qt::Sunday, format);
168}
169//! [6]
170
171//! [7]
172void Window::reformatHeaders()
173{
174 QString text = headerTextFormatCombo->currentText();
175 QTextCharFormat format;
176
177 if (text == tr(s: "Bold"))
178 format.setFontWeight(QFont::Bold);
179 else if (text == tr(s: "Italic"))
180 format.setFontItalic(true);
181 else if (text == tr(s: "Green"))
182 format.setForeground(Qt::green);
183 calendar->setHeaderTextFormat(format);
184}
185//! [7]
186
187//! [8]
188void Window::reformatCalendarPage()
189{
190 QTextCharFormat mayFirstFormat;
191 const QDate mayFirst(calendar->yearShown(), 5, 1);
192
193 QTextCharFormat firstFridayFormat;
194 QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1);
195 while (firstFriday.dayOfWeek() != Qt::Friday)
196 firstFriday = firstFriday.addDays(days: 1);
197
198 if (firstFridayCheckBox->isChecked()) {
199 firstFridayFormat.setForeground(Qt::blue);
200 } else { // Revert to regular colour for this day of the week.
201 Qt::DayOfWeek dayOfWeek(static_cast<Qt::DayOfWeek>(firstFriday.dayOfWeek()));
202 firstFridayFormat.setForeground(calendar->weekdayTextFormat(dayOfWeek).foreground());
203 }
204
205 calendar->setDateTextFormat(date: firstFriday, format: firstFridayFormat);
206
207 // When it is checked, "May First in Red" always takes precedence over "First Friday in Blue".
208 if (mayFirstCheckBox->isChecked()) {
209 mayFirstFormat.setForeground(Qt::red);
210 } else if (!firstFridayCheckBox->isChecked() || firstFriday != mayFirst) {
211 // We can now be certain we won't be resetting "May First in Red" when we restore
212 // may 1st's regular colour for this day of the week.
213 Qt::DayOfWeek dayOfWeek(static_cast<Qt::DayOfWeek>(mayFirst.dayOfWeek()));
214 calendar->setDateTextFormat(date: mayFirst, format: calendar->weekdayTextFormat(dayOfWeek));
215 }
216
217 calendar->setDateTextFormat(date: mayFirst, format: mayFirstFormat);
218}
219//! [8]
220
221//! [9]
222void Window::createPreviewGroupBox()
223{
224 previewGroupBox = new QGroupBox(tr(s: "Preview"));
225
226 calendar = new QCalendarWidget;
227 calendar->setMinimumDate(QDate(1900, 1, 1));
228 calendar->setMaximumDate(QDate(3000, 1, 1));
229 calendar->setGridVisible(true);
230
231 connect(sender: calendar, signal: &QCalendarWidget::currentPageChanged,
232 receiver: this, slot: &Window::reformatCalendarPage);
233
234 previewLayout = new QGridLayout;
235 previewLayout->addWidget(calendar, row: 0, column: 0, Qt::AlignCenter);
236 previewGroupBox->setLayout(previewLayout);
237}
238//! [9]
239
240//! [10]
241void Window::createGeneralOptionsGroupBox()
242{
243 generalOptionsGroupBox = new QGroupBox(tr(s: "General Options"));
244
245 localeCombo = new QComboBox;
246 int curLocaleIndex = -1;
247 int index = 0;
248 for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) {
249 QLocale::Language lang = static_cast<QLocale::Language>(_lang);
250 QList<QLocale::Country> countries = QLocale::countriesForLanguage(lang);
251 for (int i = 0; i < countries.count(); ++i) {
252 QLocale::Country country = countries.at(i);
253 QString label = QLocale::languageToString(language: lang);
254 label += QLatin1Char('/');
255 label += QLocale::countryToString(country);
256 QLocale locale(lang, country);
257 if (this->locale().language() == lang && this->locale().country() == country)
258 curLocaleIndex = index;
259 localeCombo->addItem(atext: label, auserData: locale);
260 ++index;
261 }
262 }
263 if (curLocaleIndex != -1)
264 localeCombo->setCurrentIndex(curLocaleIndex);
265 localeLabel = new QLabel(tr(s: "&Locale"));
266 localeLabel->setBuddy(localeCombo);
267
268 firstDayCombo = new QComboBox;
269 firstDayCombo->addItem(atext: tr(s: "Sunday"), auserData: Qt::Sunday);
270 firstDayCombo->addItem(atext: tr(s: "Monday"), auserData: Qt::Monday);
271 firstDayCombo->addItem(atext: tr(s: "Tuesday"), auserData: Qt::Tuesday);
272 firstDayCombo->addItem(atext: tr(s: "Wednesday"), auserData: Qt::Wednesday);
273 firstDayCombo->addItem(atext: tr(s: "Thursday"), auserData: Qt::Thursday);
274 firstDayCombo->addItem(atext: tr(s: "Friday"), auserData: Qt::Friday);
275 firstDayCombo->addItem(atext: tr(s: "Saturday"), auserData: Qt::Saturday);
276
277 firstDayLabel = new QLabel(tr(s: "Wee&k starts on:"));
278 firstDayLabel->setBuddy(firstDayCombo);
279//! [10]
280
281 selectionModeCombo = new QComboBox;
282 selectionModeCombo->addItem(atext: tr(s: "Single selection"),
283 auserData: QCalendarWidget::SingleSelection);
284 selectionModeCombo->addItem(atext: tr(s: "None"), auserData: QCalendarWidget::NoSelection);
285
286 selectionModeLabel = new QLabel(tr(s: "&Selection mode:"));
287 selectionModeLabel->setBuddy(selectionModeCombo);
288
289 gridCheckBox = new QCheckBox(tr(s: "&Grid"));
290 gridCheckBox->setChecked(calendar->isGridVisible());
291
292 navigationCheckBox = new QCheckBox(tr(s: "&Navigation bar"));
293 navigationCheckBox->setChecked(true);
294
295 horizontalHeaderCombo = new QComboBox;
296 horizontalHeaderCombo->addItem(atext: tr(s: "Single letter day names"),
297 auserData: QCalendarWidget::SingleLetterDayNames);
298 horizontalHeaderCombo->addItem(atext: tr(s: "Short day names"),
299 auserData: QCalendarWidget::ShortDayNames);
300 horizontalHeaderCombo->addItem(atext: tr(s: "None"),
301 auserData: QCalendarWidget::NoHorizontalHeader);
302 horizontalHeaderCombo->setCurrentIndex(1);
303
304 horizontalHeaderLabel = new QLabel(tr(s: "&Horizontal header:"));
305 horizontalHeaderLabel->setBuddy(horizontalHeaderCombo);
306
307 verticalHeaderCombo = new QComboBox;
308 verticalHeaderCombo->addItem(atext: tr(s: "ISO week numbers"),
309 auserData: QCalendarWidget::ISOWeekNumbers);
310 verticalHeaderCombo->addItem(atext: tr(s: "None"), auserData: QCalendarWidget::NoVerticalHeader);
311
312 verticalHeaderLabel = new QLabel(tr(s: "&Vertical header:"));
313 verticalHeaderLabel->setBuddy(verticalHeaderCombo);
314
315//! [11]
316 connect(sender: localeCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
317 receiver: this, slot: &Window::localeChanged);
318 connect(sender: firstDayCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
319 receiver: this, slot: &Window::firstDayChanged);
320 connect(sender: selectionModeCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
321 receiver: this, slot: &Window::selectionModeChanged);
322 connect(sender: gridCheckBox, signal: &QCheckBox::toggled,
323 receiver: calendar, slot: &QCalendarWidget::setGridVisible);
324 connect(sender: navigationCheckBox, signal: &QCheckBox::toggled,
325 receiver: calendar, slot: &QCalendarWidget::setNavigationBarVisible);
326 connect(sender: horizontalHeaderCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
327 receiver: this, slot: &Window::horizontalHeaderChanged);
328 connect(sender: verticalHeaderCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
329 receiver: this, slot: &Window::verticalHeaderChanged);
330//! [11]
331
332 QHBoxLayout *checkBoxLayout = new QHBoxLayout;
333 checkBoxLayout->addWidget(gridCheckBox);
334 checkBoxLayout->addStretch();
335 checkBoxLayout->addWidget(navigationCheckBox);
336
337 QGridLayout *outerLayout = new QGridLayout;
338 outerLayout->addWidget(localeLabel, row: 0, column: 0);
339 outerLayout->addWidget(localeCombo, row: 0, column: 1);
340 outerLayout->addWidget(firstDayLabel, row: 1, column: 0);
341 outerLayout->addWidget(firstDayCombo, row: 1, column: 1);
342 outerLayout->addWidget(selectionModeLabel, row: 2, column: 0);
343 outerLayout->addWidget(selectionModeCombo, row: 2, column: 1);
344 outerLayout->addLayout(checkBoxLayout, row: 3, column: 0, rowSpan: 1, columnSpan: 2);
345 outerLayout->addWidget(horizontalHeaderLabel, row: 4, column: 0);
346 outerLayout->addWidget(horizontalHeaderCombo, row: 4, column: 1);
347 outerLayout->addWidget(verticalHeaderLabel, row: 5, column: 0);
348 outerLayout->addWidget(verticalHeaderCombo, row: 5, column: 1);
349 generalOptionsGroupBox->setLayout(outerLayout);
350
351//! [12]
352 firstDayChanged(index: firstDayCombo->currentIndex());
353 selectionModeChanged(index: selectionModeCombo->currentIndex());
354 horizontalHeaderChanged(index: horizontalHeaderCombo->currentIndex());
355 verticalHeaderChanged(index: verticalHeaderCombo->currentIndex());
356}
357//! [12]
358
359//! [13]
360void Window::createDatesGroupBox()
361{
362 datesGroupBox = new QGroupBox(tr(s: "Dates"));
363
364 minimumDateEdit = new QDateEdit;
365 minimumDateEdit->setDisplayFormat("MMM d yyyy");
366 minimumDateEdit->setDateRange(min: calendar->minimumDate(),
367 max: calendar->maximumDate());
368 minimumDateEdit->setDate(calendar->minimumDate());
369
370 minimumDateLabel = new QLabel(tr(s: "&Minimum Date:"));
371 minimumDateLabel->setBuddy(minimumDateEdit);
372
373 currentDateEdit = new QDateEdit;
374 currentDateEdit->setDisplayFormat("MMM d yyyy");
375 currentDateEdit->setDate(calendar->selectedDate());
376 currentDateEdit->setDateRange(min: calendar->minimumDate(),
377 max: calendar->maximumDate());
378
379 currentDateLabel = new QLabel(tr(s: "&Current Date:"));
380 currentDateLabel->setBuddy(currentDateEdit);
381
382 maximumDateEdit = new QDateEdit;
383 maximumDateEdit->setDisplayFormat("MMM d yyyy");
384 maximumDateEdit->setDateRange(min: calendar->minimumDate(),
385 max: calendar->maximumDate());
386 maximumDateEdit->setDate(calendar->maximumDate());
387
388 maximumDateLabel = new QLabel(tr(s: "Ma&ximum Date:"));
389 maximumDateLabel->setBuddy(maximumDateEdit);
390
391//! [13] //! [14]
392 connect(sender: currentDateEdit, signal: &QDateEdit::dateChanged,
393 receiver: calendar, slot: &QCalendarWidget::setSelectedDate);
394 connect(sender: calendar, signal: &QCalendarWidget::selectionChanged,
395 receiver: this, slot: &Window::selectedDateChanged);
396 connect(sender: minimumDateEdit, signal: &QDateEdit::dateChanged,
397 receiver: this, slot: &Window::minimumDateChanged);
398 connect(sender: maximumDateEdit, signal: &QDateEdit::dateChanged,
399 receiver: this, slot: &Window::maximumDateChanged);
400
401//! [14]
402 QGridLayout *dateBoxLayout = new QGridLayout;
403 dateBoxLayout->addWidget(currentDateLabel, row: 1, column: 0);
404 dateBoxLayout->addWidget(currentDateEdit, row: 1, column: 1);
405 dateBoxLayout->addWidget(minimumDateLabel, row: 0, column: 0);
406 dateBoxLayout->addWidget(minimumDateEdit, row: 0, column: 1);
407 dateBoxLayout->addWidget(maximumDateLabel, row: 2, column: 0);
408 dateBoxLayout->addWidget(maximumDateEdit, row: 2, column: 1);
409 dateBoxLayout->setRowStretch(row: 3, stretch: 1);
410
411 datesGroupBox->setLayout(dateBoxLayout);
412//! [15]
413}
414//! [15]
415
416//! [16]
417void Window::createTextFormatsGroupBox()
418{
419 textFormatsGroupBox = new QGroupBox(tr(s: "Text Formats"));
420
421 weekdayColorCombo = createColorComboBox();
422 weekdayColorCombo->setCurrentIndex(
423 weekdayColorCombo->findText(text: tr(s: "Black")));
424
425 weekdayColorLabel = new QLabel(tr(s: "&Weekday color:"));
426 weekdayColorLabel->setBuddy(weekdayColorCombo);
427
428 weekendColorCombo = createColorComboBox();
429 weekendColorCombo->setCurrentIndex(
430 weekendColorCombo->findText(text: tr(s: "Red")));
431
432 weekendColorLabel = new QLabel(tr(s: "Week&end color:"));
433 weekendColorLabel->setBuddy(weekendColorCombo);
434
435//! [16] //! [17]
436 headerTextFormatCombo = new QComboBox;
437 headerTextFormatCombo->addItem(atext: tr(s: "Bold"));
438 headerTextFormatCombo->addItem(atext: tr(s: "Italic"));
439 headerTextFormatCombo->addItem(atext: tr(s: "Plain"));
440
441 headerTextFormatLabel = new QLabel(tr(s: "&Header text:"));
442 headerTextFormatLabel->setBuddy(headerTextFormatCombo);
443
444 firstFridayCheckBox = new QCheckBox(tr(s: "&First Friday in blue"));
445
446 mayFirstCheckBox = new QCheckBox(tr(s: "May &1 in red"));
447
448//! [17] //! [18]
449 connect(sender: weekdayColorCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
450 receiver: this, slot: &Window::weekdayFormatChanged);
451 connect(sender: weekdayColorCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
452 receiver: this, slot: &Window::reformatCalendarPage);
453 connect(sender: weekendColorCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
454 receiver: this, slot: &Window::weekendFormatChanged);
455 connect(sender: weekendColorCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
456 receiver: this, slot: &Window::reformatCalendarPage);
457 connect(sender: headerTextFormatCombo, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
458 receiver: this, slot: &Window::reformatHeaders);
459 connect(sender: firstFridayCheckBox, signal: &QCheckBox::toggled,
460 receiver: this, slot: &Window::reformatCalendarPage);
461 connect(sender: mayFirstCheckBox, signal: &QCheckBox::toggled,
462 receiver: this, slot: &Window::reformatCalendarPage);
463
464//! [18]
465 QHBoxLayout *checkBoxLayout = new QHBoxLayout;
466 checkBoxLayout->addWidget(firstFridayCheckBox);
467 checkBoxLayout->addStretch();
468 checkBoxLayout->addWidget(mayFirstCheckBox);
469
470 QGridLayout *outerLayout = new QGridLayout;
471 outerLayout->addWidget(weekdayColorLabel, row: 0, column: 0);
472 outerLayout->addWidget(weekdayColorCombo, row: 0, column: 1);
473 outerLayout->addWidget(weekendColorLabel, row: 1, column: 0);
474 outerLayout->addWidget(weekendColorCombo, row: 1, column: 1);
475 outerLayout->addWidget(headerTextFormatLabel, row: 2, column: 0);
476 outerLayout->addWidget(headerTextFormatCombo, row: 2, column: 1);
477 outerLayout->addLayout(checkBoxLayout, row: 3, column: 0, rowSpan: 1, columnSpan: 2);
478 textFormatsGroupBox->setLayout(outerLayout);
479
480 weekdayFormatChanged();
481 weekendFormatChanged();
482//! [19]
483 reformatHeaders();
484 reformatCalendarPage();
485}
486//! [19]
487
488//! [20]
489QComboBox *Window::createColorComboBox()
490{
491 QComboBox *comboBox = new QComboBox;
492 comboBox->addItem(atext: tr(s: "Red"), auserData: QColor(Qt::red));
493 comboBox->addItem(atext: tr(s: "Blue"), auserData: QColor(Qt::blue));
494 comboBox->addItem(atext: tr(s: "Black"), auserData: QColor(Qt::black));
495 comboBox->addItem(atext: tr(s: "Magenta"), auserData: QColor(Qt::magenta));
496 return comboBox;
497}
498//! [20]
499

source code of qtbase/examples/widgets/widgets/calendarwidget/window.cpp