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, 0, 0);
74 layout->addWidget(generalOptionsGroupBox, 0, 1);
75 layout->addWidget(datesGroupBox, 1, 0);
76 layout->addWidget(textFormatsGroupBox, 1, 1);
77 layout->setSizeConstraint(QLayout::SetFixedSize);
78 setLayout(layout);
79
80 previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height());
81 previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width());
82
83 setWindowTitle(tr("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(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 weekdayColorCombo->itemData(weekdayColorCombo->currentIndex())));
151 calendar->setWeekdayTextFormat(Qt::Monday, format);
152 calendar->setWeekdayTextFormat(Qt::Tuesday, format);
153 calendar->setWeekdayTextFormat(Qt::Wednesday, format);
154 calendar->setWeekdayTextFormat(Qt::Thursday, format);
155 calendar->setWeekdayTextFormat(Qt::Friday, format);
156}
157//! [5]
158
159//! [6]
160void Window::weekendFormatChanged()
161{
162 QTextCharFormat format;
163
164 format.setForeground(qvariant_cast<QColor>(
165 weekendColorCombo->itemData(weekendColorCombo->currentIndex())));
166 calendar->setWeekdayTextFormat(Qt::Saturday, format);
167 calendar->setWeekdayTextFormat(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("Bold"))
178 format.setFontWeight(QFont::Bold);
179 else if (text == tr("Italic"))
180 format.setFontItalic(true);
181 else if (text == tr("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(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(firstFriday, 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(mayFirst, calendar->weekdayTextFormat(dayOfWeek));
215 }
216
217 calendar->setDateTextFormat(mayFirst, mayFirstFormat);
218}
219//! [8]
220
221//! [9]
222void Window::createPreviewGroupBox()
223{
224 previewGroupBox = new QGroupBox(tr("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(calendar, &QCalendarWidget::currentPageChanged,
232 this, &Window::reformatCalendarPage);
233
234 previewLayout = new QGridLayout;
235 previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter);
236 previewGroupBox->setLayout(previewLayout);
237}
238//! [9]
239
240//! [10]
241void Window::createGeneralOptionsGroupBox()
242{
243 generalOptionsGroupBox = new QGroupBox(tr("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(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(label, locale);
260 ++index;
261 }
262 }
263 if (curLocaleIndex != -1)
264 localeCombo->setCurrentIndex(curLocaleIndex);
265 localeLabel = new QLabel(tr("&Locale"));
266 localeLabel->setBuddy(localeCombo);
267
268 firstDayCombo = new QComboBox;
269 firstDayCombo->addItem(tr("Sunday"), Qt::Sunday);
270 firstDayCombo->addItem(tr("Monday"), Qt::Monday);
271 firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday);
272 firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday);
273 firstDayCombo->addItem(tr("Thursday"), Qt::Thursday);
274 firstDayCombo->addItem(tr("Friday"), Qt::Friday);
275 firstDayCombo->addItem(tr("Saturday"), Qt::Saturday);
276
277 firstDayLabel = new QLabel(tr("Wee&k starts on:"));
278 firstDayLabel->setBuddy(firstDayCombo);
279//! [10]
280
281 selectionModeCombo = new QComboBox;
282 selectionModeCombo->addItem(tr("Single selection"),
283 QCalendarWidget::SingleSelection);
284 selectionModeCombo->addItem(tr("None"), QCalendarWidget::NoSelection);
285
286 selectionModeLabel = new QLabel(tr("&Selection mode:"));
287 selectionModeLabel->setBuddy(selectionModeCombo);
288
289 gridCheckBox = new QCheckBox(tr("&Grid"));
290 gridCheckBox->setChecked(calendar->isGridVisible());
291
292 navigationCheckBox = new QCheckBox(tr("&Navigation bar"));
293 navigationCheckBox->setChecked(true);
294
295 horizontalHeaderCombo = new QComboBox;
296 horizontalHeaderCombo->addItem(tr("Single letter day names"),
297 QCalendarWidget::SingleLetterDayNames);
298 horizontalHeaderCombo->addItem(tr("Short day names"),
299 QCalendarWidget::ShortDayNames);
300 horizontalHeaderCombo->addItem(tr("None"),
301 QCalendarWidget::NoHorizontalHeader);
302 horizontalHeaderCombo->setCurrentIndex(1);
303
304 horizontalHeaderLabel = new QLabel(tr("&Horizontal header:"));
305 horizontalHeaderLabel->setBuddy(horizontalHeaderCombo);
306
307 verticalHeaderCombo = new QComboBox;
308 verticalHeaderCombo->addItem(tr("ISO week numbers"),
309 QCalendarWidget::ISOWeekNumbers);
310 verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader);
311
312 verticalHeaderLabel = new QLabel(tr("&Vertical header:"));
313 verticalHeaderLabel->setBuddy(verticalHeaderCombo);
314
315//! [11]
316 connect(localeCombo, &QComboBox::currentIndexChanged,
317 this, &Window::localeChanged);
318 connect(firstDayCombo, &QComboBox::currentIndexChanged,
319 this, &Window::firstDayChanged);
320 connect(selectionModeCombo, &QComboBox::currentIndexChanged,
321 this, &Window::selectionModeChanged);
322 connect(gridCheckBox, &QCheckBox::toggled,
323 calendar, &QCalendarWidget::setGridVisible);
324 connect(navigationCheckBox, &QCheckBox::toggled,
325 calendar, &QCalendarWidget::setNavigationBarVisible);
326 connect(horizontalHeaderCombo, &QComboBox::currentIndexChanged,
327 this, &Window::horizontalHeaderChanged);
328 connect(verticalHeaderCombo, &QComboBox::currentIndexChanged,
329 this, &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, 0, 0);
339 outerLayout->addWidget(localeCombo, 0, 1);
340 outerLayout->addWidget(firstDayLabel, 1, 0);
341 outerLayout->addWidget(firstDayCombo, 1, 1);
342 outerLayout->addWidget(selectionModeLabel, 2, 0);
343 outerLayout->addWidget(selectionModeCombo, 2, 1);
344 outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
345 outerLayout->addWidget(horizontalHeaderLabel, 4, 0);
346 outerLayout->addWidget(horizontalHeaderCombo, 4, 1);
347 outerLayout->addWidget(verticalHeaderLabel, 5, 0);
348 outerLayout->addWidget(verticalHeaderCombo, 5, 1);
349 generalOptionsGroupBox->setLayout(outerLayout);
350
351//! [12]
352 firstDayChanged(firstDayCombo->currentIndex());
353 selectionModeChanged(selectionModeCombo->currentIndex());
354 horizontalHeaderChanged(horizontalHeaderCombo->currentIndex());
355 verticalHeaderChanged(verticalHeaderCombo->currentIndex());
356}
357//! [12]
358
359//! [13]
360void Window::createDatesGroupBox()
361{
362 datesGroupBox = new QGroupBox(tr("Dates"));
363
364 minimumDateEdit = new QDateEdit;
365 minimumDateEdit->setDisplayFormat("MMM d yyyy");
366 minimumDateEdit->setDateRange(calendar->minimumDate(),
367 calendar->maximumDate());
368 minimumDateEdit->setDate(calendar->minimumDate());
369
370 minimumDateLabel = new QLabel(tr("&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(calendar->minimumDate(),
377 calendar->maximumDate());
378
379 currentDateLabel = new QLabel(tr("&Current Date:"));
380 currentDateLabel->setBuddy(currentDateEdit);
381
382 maximumDateEdit = new QDateEdit;
383 maximumDateEdit->setDisplayFormat("MMM d yyyy");
384 maximumDateEdit->setDateRange(calendar->minimumDate(),
385 calendar->maximumDate());
386 maximumDateEdit->setDate(calendar->maximumDate());
387
388 maximumDateLabel = new QLabel(tr("Ma&ximum Date:"));
389 maximumDateLabel->setBuddy(maximumDateEdit);
390
391//! [13] //! [14]
392 connect(currentDateEdit, &QDateEdit::dateChanged,
393 calendar, &QCalendarWidget::setSelectedDate);
394 connect(calendar, &QCalendarWidget::selectionChanged,
395 this, &Window::selectedDateChanged);
396 connect(minimumDateEdit, &QDateEdit::dateChanged,
397 this, &Window::minimumDateChanged);
398 connect(maximumDateEdit, &QDateEdit::dateChanged,
399 this, &Window::maximumDateChanged);
400
401//! [14]
402 QGridLayout *dateBoxLayout = new QGridLayout;
403 dateBoxLayout->addWidget(currentDateLabel, 1, 0);
404 dateBoxLayout->addWidget(currentDateEdit, 1, 1);
405 dateBoxLayout->addWidget(minimumDateLabel, 0, 0);
406 dateBoxLayout->addWidget(minimumDateEdit, 0, 1);
407 dateBoxLayout->addWidget(maximumDateLabel, 2, 0);
408 dateBoxLayout->addWidget(maximumDateEdit, 2, 1);
409 dateBoxLayout->setRowStretch(3, 1);
410
411 datesGroupBox->setLayout(dateBoxLayout);
412//! [15]
413}
414//! [15]
415
416//! [16]
417void Window::createTextFormatsGroupBox()
418{
419 textFormatsGroupBox = new QGroupBox(tr("Text Formats"));
420
421 weekdayColorCombo = createColorComboBox();
422 weekdayColorCombo->setCurrentIndex(
423 weekdayColorCombo->findText(tr("Black")));
424
425 weekdayColorLabel = new QLabel(tr("&Weekday color:"));
426 weekdayColorLabel->setBuddy(weekdayColorCombo);
427
428 weekendColorCombo = createColorComboBox();
429 weekendColorCombo->setCurrentIndex(
430 weekendColorCombo->findText(tr("Red")));
431
432 weekendColorLabel = new QLabel(tr("Week&end color:"));
433 weekendColorLabel->setBuddy(weekendColorCombo);
434
435//! [16] //! [17]
436 headerTextFormatCombo = new QComboBox;
437 headerTextFormatCombo->addItem(tr("Bold"));
438 headerTextFormatCombo->addItem(tr("Italic"));
439 headerTextFormatCombo->addItem(tr("Plain"));
440
441 headerTextFormatLabel = new QLabel(tr("&Header text:"));
442 headerTextFormatLabel->setBuddy(headerTextFormatCombo);
443
444 firstFridayCheckBox = new QCheckBox(tr("&First Friday in blue"));
445
446 mayFirstCheckBox = new QCheckBox(tr("May &1 in red"));
447
448//! [17] //! [18]
449 connect(weekdayColorCombo, &QComboBox::currentIndexChanged,
450 this, &Window::weekdayFormatChanged);
451 connect(weekdayColorCombo, &QComboBox::currentIndexChanged,
452 this, &Window::reformatCalendarPage);
453 connect(weekendColorCombo, &QComboBox::currentIndexChanged,
454 this, &Window::weekendFormatChanged);
455 connect(weekendColorCombo, &QComboBox::currentIndexChanged,
456 this, &Window::reformatCalendarPage);
457 connect(headerTextFormatCombo, &QComboBox::currentIndexChanged,
458 this, &Window::reformatHeaders);
459 connect(firstFridayCheckBox, &QCheckBox::toggled,
460 this, &Window::reformatCalendarPage);
461 connect(mayFirstCheckBox, &QCheckBox::toggled,
462 this, &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, 0, 0);
472 outerLayout->addWidget(weekdayColorCombo, 0, 1);
473 outerLayout->addWidget(weekendColorLabel, 1, 0);
474 outerLayout->addWidget(weekendColorCombo, 1, 1);
475 outerLayout->addWidget(headerTextFormatLabel, 2, 0);
476 outerLayout->addWidget(headerTextFormatCombo, 2, 1);
477 outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 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(tr("Red"), QColor(Qt::red));
493 comboBox->addItem(tr("Blue"), QColor(Qt::blue));
494 comboBox->addItem(tr("Black"), QColor(Qt::black));
495 comboBox->addItem(tr("Magenta"), QColor(Qt::magenta));
496 return comboBox;
497}
498//! [20]
499