Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \title Calendar Widget Example
++ \examplecategory {User Interface Components}
++ \example widgets/calendarwidget
++ \ingroup examples-widgets
++ \ingroup examples-layout
++ \brief The Calendar Widget example shows use of QCalendarWidget.
++
++ \image calendarwidgetexample.png
++ {Calendar widget showing various calendar settings}
++
++ QCalendarWidget displays one calendar month
++ at a time and lets the user select a date.
++ The calendar consists of four components: a navigation
++ bar that lets the user change the month that is
++ displayed, a grid where each cell represents one day
++ in the month, and two headers that display weekday names
++ and week numbers.
++
++ The Calendar Widget example displays a QCalendarWidget and lets the user
++ configure its appearance and behavior using
++ \l{QComboBox}es, \l{QCheckBox}es, and \l{QDateEdit}s. In
++ addition, the user can influence the formatting of individual dates
++ and headers.
++
++ The properties of the QCalendarWidget are summarized in the table
++ below.
++
++ \table
++ \header \li Property
++ \li Description
++ \row \li \l{QCalendarWidget::}{selectedDate}
++ \li The currently selected date.
++ \row \li \l{QCalendarWidget::}{minimumDate}
++ \li The earliest date that can be selected.
++ \row \li \l{QCalendarWidget::}{maximumDate}
++ \li The latest date that can be selected.
++ \row \li \l{QCalendarWidget::}{firstDayOfWeek}
++ \li The day that is displayed as the first day of the week
++ (usually Sunday or Monday).
++ \row \li \l{QCalendarWidget::}{gridVisible}
++ \li Whether the grid should be shown.
++ \row \li \l{QCalendarWidget::}{selectionMode}
++ \li Whether the user can select a date or not.
++ \row \li \l{QCalendarWidget::}{horizontalHeaderFormat}
++ \li The format of the day names in the horizontal header
++ (e.g., "M", "Mon", or "Monday").
++ \row \li \l{QCalendarWidget::}{verticalHeaderFormat}
++ \li The format of the vertical header.
++ \row \li \l{QCalendarWidget::}{navigationBarVisible}
++ \li Whether the navigation bar at the top of the calendar
++ widget is shown.
++ \endtable
++
++ The example consists of one class, \c Window, which creates and
++ lays out the QCalendarWidget and the other widgets that let the
++ user configure the QCalendarWidget.
++
++ \section1 Window Class Definition
++
++ Here is the definition of the \c Window class:
++
++ \snippet widgets/calendarwidget/window.h 0
++ \dots
++ \snippet widgets/calendarwidget/window.h 1
++
++ As is often the case with classes that represent self-contained
++ windows, most of the API is private. We will review the private
++ members as we stumble upon them in the implementation.
++
++ \section1 Window Class Implementation
++
++ Let's now review the class implementation, starting with the constructor:
++
++ \snippet widgets/calendarwidget/window.cpp 0
++
++ We start by creating the four \l{QGroupBox}es and their child
++ widgets (including the QCalendarWidget) using four private \c
++ create...GroupBox() functions, described below. Then we arrange
++ the group boxes in a QGridLayout.
++
++ We set the grid layout's resize policy to QLayout::SetFixedSize to
++ prevent the user from resizing the window. In that mode, the
++ window's size is set automatically by QGridLayout based on the
++ size hints of its contents widgets.
++
++ To ensure that the window isn't automatically resized every time
++ we change a property of the QCalendarWidget (for example, hiding the
++ navigation bar, the vertical header, or the grid), we set the
++ minimum height of row 0 and the minimum width of column 0 to the
++ initial size of the QCalendarWidget.
++
++ Let's move on to the \c createPreviewGroupBox() function:
++
++ \snippet widgets/calendarwidget/window.cpp 9
++
++ The \uicontrol Preview group box contains only one widget: the
++ QCalendarWidget. We set it up, connect its
++ \l{QCalendarWidget::}{currentPageChanged()} signal to our \c
++ reformatCalendarPage() slot to make sure that every new page gets
++ the formatting specified by the user.
++
++ The \c createGeneralOptionsGroupBox() function is somewhat large
++ and several widgets are set up in the same way. We will look at
++ parts of its implementation here and skip the rest:
++
++ \snippet widgets/calendarwidget/window.cpp 10
++ \dots
++
++ We start with the setup of the \uicontrol{Week starts on} combobox.
++ This combobox controls which day should be displayed as the first
++ day of the week.
++
++ The QComboBox class lets us attach user data as a QVariant to
++ each item. The data can later be retrieved with QComboBox's
++ \l{QComboBox::}{itemData()} function. QVariant doesn't directly
++ support the Qt::DayOfWeek data type, but it supports \c int, and
++ C++ will happily convert any enum value to \c int.
++
++ \dots
++ \snippet widgets/calendarwidget/window.cpp 11
++ \dots
++
++ After having created the widgets, we connect the signals and slots. We
++ connect the comboboxes to private slots of \c Window or to
++ public slots provided by QComboBox.
++
++ \dots
++ \snippet widgets/calendarwidget/window.cpp 12
++
++ At the end of the function, we call the slots that update the calendar to ensure
++ that the QCalendarWidget is synchronized with the other widgets on startup.
++
++ Let's now take a look at the \c createDatesGroupBox() private function:
++
++ \snippet widgets/calendarwidget/window.cpp 13
++
++ In this function, we create the \uicontrol {Minimum Date}, \uicontrol {Maximum Date},
++ and \uicontrol {Current Date} editor widgets,
++ which control the calendar's minimum, maximum, and selected dates.
++ The calendar's minimum and maximum dates have already been
++ set in \c createPrivewGroupBox(); we can then set the widgets
++ default values to the calendars values.
++
++ \snippet widgets/calendarwidget/window.cpp 14
++ \dots
++ \snippet widgets/calendarwidget/window.cpp 15
++
++ We connect the \c currentDateEdit's
++ \l{QDateEdit::}{dateChanged()} signal directly to the calendar's
++ \l{QCalendarWidget::}{setSelectedDate()} slot. When the calendar's
++ selected date changes, either as a result of a user action or
++ programmatically, our \c selectedDateChanged() slot updates
++ the \uicontrol {Current Date} editor. We also need to react when the user
++ changes the \uicontrol{Minimum Date} and \uicontrol{Maximum Date} editors.
++
++ Here is the \c createTextFormatsGroup() function:
++
++ \snippet widgets/calendarwidget/window.cpp 16
++
++ We set up the \uicontrol {Weekday Color} and \uicontrol {Weekend Color} comboboxes
++ using \c createColorCombo(), which instantiates a QComboBox and
++ populates it with colors ("Red", "Blue", etc.).
++
++ \snippet widgets/calendarwidget/window.cpp 17
++
++ The \uicontrol {Header Text Format} combobox lets the user change the
++ text format (bold, italic, or plain) used for horizontal and
++ vertical headers. The \uicontrol {First Friday in blue} and \uicontrol {May 1
++ in red} check box affect the rendering of specific dates.
++
++ \snippet widgets/calendarwidget/window.cpp 18
++
++ We connect the check boxes and comboboxes to various private
++ slots. The \uicontrol {First Friday in blue} and \uicontrol {May 1 in red}
++ check boxes are both connected to \c reformatCalendarPage(),
++ which is also called when the calendar switches month.
++
++ \dots
++ \snippet widgets/calendarwidget/window.cpp 19
++
++ At the end of \c createTextFormatsGroupBox(), we call private
++ slots to synchronize the QCalendarWidget with the other widgets.
++
++ We're now done reviewing the four \c create...GroupBox()
++ functions. Let's now take a look at the other private functions
++ and slots.
++
++ \snippet widgets/calendarwidget/window.cpp 20
++
++ In \c createColorCombo(), we create a combobox and populate it with
++ standard colors. The second argument to QComboBox::addItem()
++ is a QVariant storing user data (in this case, QColor objects).
++
++ This function was used to set up the \uicontrol {Weekday Color}
++ and \uicontrol {Weekend Color} comboboxes.
++
++ \snippet widgets/calendarwidget/window.cpp 1
++
++ When the user changes the \uicontrol {Week starts on} combobox's
++ value, \c firstDayChanged() is invoked with the index of the
++ combobox's new value. We retrieve the custom data item
++ associated with the new current item using
++ \l{QComboBox::}{itemData()} and cast it to a Qt::DayOfWeek.
++
++ \c selectionModeChanged(), \c horizontalHeaderChanged(), and \c
++ verticalHeaderChanged() are very similar to \c firstDayChanged(),
++ so they are omitted.
++
++ \snippet widgets/calendarwidget/window.cpp 2
++
++ The \c selectedDateChanged() updates the \uicontrol{Current Date}
++ editor to reflect the current state of the QCalendarWidget.
++
++ \snippet widgets/calendarwidget/window.cpp 3
++
++ When the user changes the minimum date, we tell the
++ QCalenderWidget. We also update the \uicontrol {Maximum Date} editor,
++ because if the new minimum date is later than the current maximum
++ date, QCalendarWidget will automatically adapt its maximum date
++ to avoid a contradicting state.
++
++ \snippet widgets/calendarwidget/window.cpp 4
++
++ \c maximumDateChanged() is implemented similarly to \c
++ minimumDateChanged().
++
++ \snippet widgets/calendarwidget/window.cpp 5
++
++ Each combobox item has a QColor object as user data corresponding to the
++ item's text. After fetching the colors from the comboboxes, we
++ set the text format of each day of the week.
++
++ The text format of a column in the calendar is given as a
++ QTextCharFormat, which besides the foreground color lets us
++ specify various character formatting information. In this
++ example, we only show a subset of the possibilities.
++
++ \snippet widgets/calendarwidget/window.cpp 6
++
++ \c weekendFormatChanged() is the same as \c
++ weekdayFormatChanged(), except that it affects Saturday and
++ Sunday instead of Monday to Friday.
++
++ \snippet widgets/calendarwidget/window.cpp 7
++
++ The \c reformatHeaders() slot is called when the user
++ changes the text format of
++ the headers. We compare the current text of the \uicontrol {Header Text Format}
++ combobox to determine which format to apply. (An alternative would
++ have been to store \l{QTextCharFormat} values alongside the combobox
++ items.)
++
++ \snippet widgets/calendarwidget/window.cpp 8
++
++ In \c reformatCalendarPage(), we set the text format of the first
++ Friday in the month and May 1 in the current year. The text
++ formats that are actually used depend on which check boxes are
++ checked and what the weekday/weekend formats are.
++
++ QCalendarWidget lets us set the text format of individual dates
++ with the \l{QCalendarWidget::}{setDateTextFormat()}. We chose to
++ set the date formats when the calendar page changes - i.e. a new month is
++ displayed - and when the weekday/weekend format is changed.
++ We check which of the \c mayFirstCheckBox and \c firstDayCheckBox, if any,
++ are checked and set the text formats accordingly.
++ */