summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@digia.com>2014-02-03 12:17:03 +0100
committerMitch Curtis <mitch.curtis@digia.com>2014-02-03 15:19:56 +0100
commit9e9c84a67c543a887289a02f00e32451d72b45bc (patch)
tree6425d139945800458b3bbdb8c835414c5724fd6e
parent562daca758d3fce16f262b2de00573d4843d8043 (diff)
downloadqtquickcontrols-9e9c84a67c543a887289a02f00e32451d72b45bc.tar.gz
Add week numbers.
Change-Id: Ib413019da88c24bebf6169b60b2088b1920f1ae4 Reviewed-by: Mitch Curtis <mitch.curtis@digia.com>
-rw-r--r--src/controls/Calendar.qml10
-rw-r--r--src/controls/Private/qquickcalendarmodel.cpp15
-rw-r--r--src/controls/Private/qquickcalendarmodel_p.h3
-rw-r--r--src/controls/Styles/Base/CalendarStyle.qml254
4 files changed, 186 insertions, 96 deletions
diff --git a/src/controls/Calendar.qml b/src/controls/Calendar.qml
index 5d6fc3e4..58272d4e 100644
--- a/src/controls/Calendar.qml
+++ b/src/controls/Calendar.qml
@@ -64,6 +64,9 @@ import QtQuick.Controls.Private 1.0
Localization is supported through the \l locale property. The selected date
is displayed according to \l locale, and it can be accessed through the
\l selectedDateText property.
+
+ Week numbers can be displayed by setting the weekNumbersVisible property to
+ \c true.
*/
Control {
@@ -129,6 +132,13 @@ Control {
property bool gridVisible: true
/*!
+ This property determines the visibility of week numbers.
+
+ The default value is \c false.
+ */
+ property bool weekNumbersVisible: false
+
+ /*!
\qmlproperty enum Calendar::dayOfWeekFormat
The format in which the days of the week (in the header) are displayed.
diff --git a/src/controls/Private/qquickcalendarmodel.cpp b/src/controls/Private/qquickcalendarmodel.cpp
index afaca713..4c72b2a0 100644
--- a/src/controls/Private/qquickcalendarmodel.cpp
+++ b/src/controls/Private/qquickcalendarmodel.cpp
@@ -197,6 +197,20 @@ int QQuickCalendarModel::indexAt(const QDate &date)
}
/*!
+ Returns the week number for the first day of the week corresponding to \a row,
+ or -1 if \a row is outside of our range.
+*/
+int QQuickCalendarModel::weekNumberAt(int row) const
+{
+ const int index = row * daysInAWeek;
+ const QDate date = dateAt(index);
+ if (date.isValid()) {
+ return date.weekNumber();
+ }
+ return -1;
+}
+
+/*!
Called before selectedDateChanged() is emitted.
This function is called even when just the day has changed, in which case
@@ -238,5 +252,6 @@ void QQuickCalendarModel::populateFromSelectedDate(const QDate &previousDate)
emit dataChanged(index(0, 0), index(rowCount() - 1, 0));
} else {
endResetModel();
+ emit countChanged(rowCount());
}
}
diff --git a/src/controls/Private/qquickcalendarmodel_p.h b/src/controls/Private/qquickcalendarmodel_p.h
index 67239972..02f40a77 100644
--- a/src/controls/Private/qquickcalendarmodel_p.h
+++ b/src/controls/Private/qquickcalendarmodel_p.h
@@ -53,6 +53,7 @@ class QQuickCalendarModel : public QAbstractListModel
Q_OBJECT
Q_PROPERTY(QDate selectedDate READ selectedDate WRITE setSelectedDate NOTIFY selectedDateChanged)
Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged)
+ Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
explicit QQuickCalendarModel(QObject *parent = 0);
@@ -75,9 +76,11 @@ public:
Q_INVOKABLE QDate dateAt(int index) const;
Q_INVOKABLE int indexAt(const QDate &selectedDate);
+ Q_INVOKABLE int weekNumberAt(int row) const;
signals:
void selectedDateChanged(const QDate &selectedDate);
void localeChanged(const QLocale &locale);
+ void countChanged(int count);
protected:
void populateFromSelectedDate(const QDate &previousDate);
diff --git a/src/controls/Styles/Base/CalendarStyle.qml b/src/controls/Styles/Base/CalendarStyle.qml
index 527f72cf..220e5161 100644
--- a/src/controls/Styles/Base/CalendarStyle.qml
+++ b/src/controls/Styles/Base/CalendarStyle.qml
@@ -201,7 +201,6 @@ Style {
Label {
id: dayDelegateText
text: styleData.date.getDate()
- font.pixelSize: 14
anchors.centerIn: parent
horizontalAlignment: Text.AlignRight
color: {
@@ -231,6 +230,17 @@ Style {
}
}
+ /*!
+ The delegate that styles each week number.
+ */
+ property Component weekNumberDelegate: Rectangle {
+ color: "white"
+ Label {
+ text: styleData.weekNumber
+ anchors.centerIn: parent
+ }
+ }
+
/*! \internal */
property Component panel: Item {
id: panel
@@ -259,7 +269,7 @@ Style {
spacing: (control.gridVisible ? __gridLineWidth : 0)
anchors.top: navigationBarLoader.bottom
anchors.left: parent.left
- anchors.leftMargin: (control.gridVisible ? __gridLineWidth : 0)
+ anchors.leftMargin: (control.weekNumbersVisible ? weekNumbersItem.width : 0) + (control.gridVisible ? __gridLineWidth : 0)
anchors.right: parent.right
height: 40
@@ -284,122 +294,174 @@ Style {
}
}
- // Contains the grid lines and the grid itself.
- Item {
- id: viewContainer
- width: panel.width
- height: panel.height - navigationBarLoader.height - weekdayHeaderRow.height
+ Row {
+ id: gridRow
+ width: weekNumbersItem.width + viewContainer.width
+ height: viewContainer.height
anchors.top: weekdayHeaderRow.bottom
- Repeater {
- id: verticalGridLineRepeater
- model: view.columns + 1
- delegate: Rectangle {
- // The last line will be an invalid index, so we must handle it
- x: index < view.columns
- ? CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).x
- : CalendarUtils.cellRectAt(view.columns - 1, view.columns, view.rows, view.availableWidth, view.availableHeight).x
- + CalendarUtils.cellRectAt(view.columns - 1, view.columns, view.rows, view.availableWidth, view.availableHeight).width
- y: 0
- width: __gridLineWidth
- height: viewContainer.height
- color: gridColor
- visible: control.gridVisible
- }
- }
+ Item {
+ id: weekNumbersItem
+ visible: control.weekNumbersVisible
+ width: 30
+ height: viewContainer.height
+
+ Repeater {
+ id: weekNumberRepeater
+ model: view.weeksToShow
+
+ Loader {
+ id: weekNumberDelegateLoader
+ y: CalendarUtils.cellRectAt(index * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).y
+ + (calendar.gridVisible ? __gridLineWidth : 0)
+ width: weekNumbersItem.width
+ // TODO: It seems the column doesn't reposition the items
+ // after the height recovers from being negative
+// height: view.cellRects[index * view.columns].height
+ height: CalendarUtils.cellRectAt(index * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).height
+ - (calendar.gridVisible ? __gridLineWidth : 0)
+ sourceComponent: weekNumberDelegate
+
+ readonly property int __index: index
+ property int __weekNumber: control.__model.weekNumberAt(index)
+
+ // Must handle this ourselves since it's not a notifiable property, but an invokable function.
+ // This will be called every time the selected date changes, but not the first time the calendar is loaded.
+ Connections {
+ target: control
+ onSelectedDateChanged: __weekNumber = control.__model.weekNumberAt(index)
+ }
- Repeater {
- id: horizontalGridLineRepeater
- model: view.rows + 1
- delegate: Rectangle {
- x: 0
- // The last line will be an invalid index, so we must handle it
- y: index < view.columns - 1
- ? CalendarUtils.cellRectAt(index * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).y
- : CalendarUtils.cellRectAt((view.rows - 1) * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).y
- + CalendarUtils.cellRectAt((view.rows - 1) * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).height
- width: viewContainer.width
- height: __gridLineWidth
- color: gridColor
- visible: control.gridVisible
- }
- }
+ // This handles the first time the calendar is shown.
+ Connections {
+ target: control.__model
+ onCountChanged: __weekNumber = control.__model.weekNumberAt(index)
+ }
- Connections {
- target: control
- onSelectedDateChanged: view.dateChanged()
+ property QtObject styleData: QtObject {
+ readonly property alias index: weekNumberDelegateLoader.__index
+ readonly property int weekNumber: weekNumberDelegateLoader.__weekNumber
+ }
+ }
+ }
}
- Repeater {
- id: view
+ // Contains the grid lines and the grid itself.
+ Item {
+ id: viewContainer
+ width: panel.width - (control.weekNumbersVisible ? weekNumbersItem.width : 0)
+ height: panel.height - navigationBarLoader.height - weekdayHeaderRow.height
+
+ Repeater {
+ id: verticalGridLineRepeater
+ model: view.columns + 1
+ delegate: Rectangle {
+ // The last line will be an invalid index, so we must handle it
+ x: index < view.columns
+ ? CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).x
+ : CalendarUtils.cellRectAt(view.columns - 1, view.columns, view.rows, view.availableWidth, view.availableHeight).x
+ + CalendarUtils.cellRectAt(view.columns - 1, view.columns, view.rows, view.availableWidth, view.availableHeight).width
+ y: 0
+ width: __gridLineWidth
+ height: viewContainer.height
+ color: gridColor
+ visible: control.gridVisible
+ }
+ }
- property int currentIndex: -1
+ Repeater {
+ id: horizontalGridLineRepeater
+ model: view.rows + 1
+ delegate: Rectangle {
+ x: 0
+ // The last line will be an invalid index, so we must handle it
+ y: index < view.columns - 1
+ ? CalendarUtils.cellRectAt(index * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).y
+ : CalendarUtils.cellRectAt((view.rows - 1) * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).y
+ + CalendarUtils.cellRectAt((view.rows - 1) * view.columns, view.columns, view.rows, view.availableWidth, view.availableHeight).height
+ width: viewContainer.width
+ height: __gridLineWidth
+ color: gridColor
+ visible: control.gridVisible
+ }
+ }
- readonly property int weeksToShow: 6
- readonly property int rows: weeksToShow
- readonly property int columns: CalendarUtils.daysInAWeek
+ Connections {
+ target: control
+ onSelectedDateChanged: view.dateChanged()
+ }
- model: control.__model
+ Repeater {
+ id: view
- Component.onCompleted: dateChanged()
+ property int currentIndex: -1
- function dateChanged() {
- if (model !== undefined && model.locale !== undefined) {
- model.selectedDate = control.selectedDate;
- currentIndex = model.indexAt(control.selectedDate);
- }
- }
+ readonly property int weeksToShow: 6
+ readonly property int rows: weeksToShow
+ readonly property int columns: CalendarUtils.daysInAWeek
- // The combined available width and height to be shared amongst each cell.
- readonly property real availableWidth: (viewContainer.width - (control.gridVisible ? __gridLineWidth : 0))
- readonly property real availableHeight: (viewContainer.height - (control.gridVisible ? __gridLineWidth : 0))
+ model: control.__model
- delegate: Loader {
- id: delegateLoader
+ Component.onCompleted: dateChanged()
- x: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).x
- + (control.gridVisible ? __gridLineWidth : 0)
- y: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).y
- + (control.gridVisible ? __gridLineWidth : 0)
- width: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).width
- - (control.gridVisible ? __gridLineWidth : 0)
- height: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).height
- - (control.gridVisible ? __gridLineWidth : 0)
+ function dateChanged() {
+ if (model !== undefined && model.locale !== undefined) {
+ model.selectedDate = control.selectedDate;
+ currentIndex = model.indexAt(control.selectedDate);
+ }
+ }
- sourceComponent: dateDelegate
+ // The combined available width and height to be shared amongst each cell.
+ readonly property real availableWidth: (viewContainer.width - (control.gridVisible ? __gridLineWidth : 0))
+ readonly property real availableHeight: (viewContainer.height - (control.gridVisible ? __gridLineWidth : 0))
- readonly property int __index: index
- readonly property var __model: model
+ delegate: Loader {
+ id: delegateLoader
- property QtObject styleData: QtObject {
- readonly property alias index: delegateLoader.__index
- readonly property alias model: delegateLoader.__model
- readonly property bool selected: view.currentIndex == index
- readonly property date date: model.date
- }
+ x: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).x
+ + (control.gridVisible ? __gridLineWidth : 0)
+ y: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).y
+ + (control.gridVisible ? __gridLineWidth : 0)
+ width: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).width
+ - (control.gridVisible ? __gridLineWidth : 0)
+ height: CalendarUtils.cellRectAt(index, view.columns, view.rows, view.availableWidth, view.availableHeight).height
+ - (control.gridVisible ? __gridLineWidth : 0)
- MouseArea {
- anchors.fill: parent
+ sourceComponent: dateDelegate
- function setDateIfValid(date) {
- if (control.isValidDate(date)) {
- control.selectedDate = date;
- }
- }
+ readonly property int __index: index
+ readonly property var __model: model
- onClicked: {
- setDateIfValid(date)
+ property QtObject styleData: QtObject {
+ readonly property alias index: delegateLoader.__index
+ readonly property alias model: delegateLoader.__model
+ readonly property bool selected: view.currentIndex == index
+ readonly property date date: model.date
}
- onDoubleClicked: {
- if (date.getTime() === control.selectedDate.getTime()) {
- // Only accept double clicks if the first click does not
- // change the month displayed. This is because double-
- // clicking on a date in the next month will first cause
- // a single click which will change the month and the
- // the release will be triggered on the same index but a
- // different date (the date in the next month).
- control.doubleClicked(date);
+ MouseArea {
+ anchors.fill: parent
+
+ function setDateIfValid(date) {
+ if (control.isValidDate(date)) {
+ control.selectedDate = date;
+ }
+
+ onClicked: {
+ setDateIfValid(date)
+ }
+
+ onDoubleClicked: {
+ if (date.getTime() === control.selectedDate.getTime()) {
+ // Only accept double clicks if the first click does not
+ // change the month displayed. This is because double-
+ // clicking on a date in the next month will first cause
+ // a single click which will change the month and the
+ // the release will be triggered on the same index but a
+ // different date (the date in the next month).
+ control.doubleClicked(date);
+ }
+ }
}
}
}