[calendar] Add week numbers in Calendar components

Change-Id: Ie46b9b9c1e6035a9b2933362227d3c8fcd30a10e
REVIEW: 124004
CCBUG: 338195
CHANGELOG: Calendar components can now display week numbers
This commit is contained in:
Martin Klapetek 2015-06-05 14:34:05 +02:00
parent a989a77a0d
commit 5caba3cfaf
4 changed files with 53 additions and 16 deletions

View File

@ -184,7 +184,7 @@ QAbstractListModel *Calendar::daysModel() const
{ {
return m_daysModel; return m_daysModel;
} }
QList<int> Calendar::weeksModel() const QJsonArray Calendar::weeksModel() const
{ {
return m_weekList; return m_weekList;
} }
@ -196,7 +196,7 @@ void Calendar::updateData()
} }
m_dayList.clear(); m_dayList.clear();
m_weekList.clear(); m_weekList = QJsonArray();
int totalDays = m_days * m_weeks; int totalDays = m_days * m_weeks;
@ -261,12 +261,12 @@ void Calendar::updateData()
} }
const int numOfDaysInCalendar = m_dayList.count(); const int numOfDaysInCalendar = m_dayList.count();
// Fill weeksModel (just a QList<int>) with the week numbers. This needs some tweaking! // Fill weeksModel with the week numbers
for (int i = 0; i < numOfDaysInCalendar; i += 7) { for (int i = 0; i < numOfDaysInCalendar; i += 7) {
const DayData &data = m_dayList.at(i); const DayData &data = m_dayList.at(i);
m_weekList << QDate(data.yearNumber, data.monthNumber, data.dayNumber).weekNumber(); m_weekList << QDate(data.yearNumber, data.monthNumber, data.dayNumber).weekNumber();
} }
emit weeksModelChanged();
m_daysModel->update(); m_daysModel->update();
// qDebug() << "---------------------------------------------------------------"; // qDebug() << "---------------------------------------------------------------";

View File

@ -23,6 +23,7 @@
#include <QObject> #include <QObject>
#include <QDate> #include <QDate>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QJsonArray>
#include "daydata.h" #include "daydata.h"
#include "daysmodel.h" #include "daysmodel.h"
@ -53,7 +54,7 @@ class Calendar : public QObject
/** /**
* This model contains the week numbers for the given date grid. * This model contains the week numbers for the given date grid.
*/ */
Q_PROPERTY(QList<int> weeksModel READ weeksModel CONSTANT) Q_PROPERTY(QJsonArray weeksModel READ weeksModel NOTIFY weeksModelChanged)
/** /**
* The number of days a week contains. * The number of days a week contains.
@ -163,7 +164,7 @@ public:
// Models // Models
QAbstractListModel *daysModel() const; QAbstractListModel *daysModel() const;
QList<int> weeksModel() const; QJsonArray weeksModel() const;
// QML invokables // QML invokables
Q_INVOKABLE void nextMonth(); Q_INVOKABLE void nextMonth();
@ -184,6 +185,7 @@ Q_SIGNALS:
void errorMessageChanged(); void errorMessageChanged();
void monthNameChanged(); void monthNameChanged();
void yearChanged(); void yearChanged();
void weeksModelChanged();
public Q_SLOTS: public Q_SLOTS:
void updateData(); void updateData();
@ -194,7 +196,7 @@ private:
Types m_types; Types m_types;
QList<DayData> m_dayList; QList<DayData> m_dayList;
DaysModel *m_daysModel; DaysModel *m_daysModel;
QList<int> m_weekList; QJsonArray m_weekList;
int m_days; int m_days;
int m_weeks; int m_weeks;

View File

@ -23,13 +23,15 @@ import org.kde.plasma.extras 2.0 as PlasmaExtras
Item { Item {
id: daysCalendar id: daysCalendar
readonly property int gridColumns: root.showWeekNumbers ? calendarGrid.columns + 1 : calendarGrid.columns
// This is to ensure that the inner grid.width is always aligned to be divisible by 7, // This is to ensure that the inner grid.width is always aligned to be divisible by 7,
// fixes wrong side margins because of the rounding of cell size // fixes wrong side margins because of the rounding of cell size
// (consider the parent.width to be 404, the cell width would be 56, // (consider the parent.width to be 404, the cell width would be 56,
// but 56*7 + 6 (the inner spacing) is 398, so we split the remaining 6 to avoid // but 56*7 + 6 (the inner spacing) is 398, so we split the remaining 6 to avoid
// wrong alignment) // wrong alignment)
anchors { anchors {
leftMargin: Math.floor(((parent.width - (root.columns + 1) * borderWidth) % root.columns) / 2) leftMargin: Math.floor(((parent.width - (gridColumns + 1) * borderWidth) % gridColumns) / 2)
rightMargin: anchors.leftMargin rightMargin: anchors.leftMargin
bottomMargin: anchors.leftMargin bottomMargin: anchors.leftMargin
} }
@ -56,7 +58,7 @@ Item {
// This isn't the real width/height, but rather the X coord where the line will stop // This isn't the real width/height, but rather the X coord where the line will stop
// and as the coord system starts from (0,0), we need to do "-1" to not get off-by-1 errors // and as the coord system starts from (0,0), we need to do "-1" to not get off-by-1 errors
var rectWidth = (root.cellWidth + root.borderWidth) * calendarGrid.columns + root.borderWidth - 1 var rectWidth = (root.cellWidth + root.borderWidth) * gridColumns + root.borderWidth - 1
var rectHeight = (root.cellHeight + root.borderWidth) * calendarGrid.rows + root.borderWidth - 1 var rectHeight = (root.cellHeight + root.borderWidth) * calendarGrid.rows + root.borderWidth - 1
// the outer frame // the outer frame
@ -64,15 +66,15 @@ Item {
// horizontal lines // horizontal lines
for (var i = 0; i < calendarGrid.rows - 1; i++) { for (var i = 0; i < calendarGrid.rows - 1; i++) {
var lineY = (rectHeight / calendarGrid.columns) * (i + 1); var lineY = (rectHeight / calendarGrid.rows) * (i + 1);
ctx.moveTo(0, lineY); ctx.moveTo(root.showWeekNumbers ? root.cellWidth + root.borderWidth : root.borderWidth, lineY);
ctx.lineTo(rectWidth, lineY); ctx.lineTo(rectWidth, lineY);
} }
// vertical lines // vertical lines
for (var i = 0; i < calendarGrid.columns - 1; i++) { for (var i = 0; i < gridColumns - 1; i++) {
var lineX = (rectWidth / calendarGrid.rows) * (i + 1); var lineX = (rectWidth / gridColumns) * (i + 1);
ctx.moveTo(lineX, root.borderWidth + root.cellHeight); ctx.moveTo(lineX, root.borderWidth + root.cellHeight);
ctx.lineTo(lineX, rectHeight); ctx.lineTo(lineX, rectHeight);
@ -84,10 +86,42 @@ Item {
} }
} }
Column {
id: weeksColumn
visible: root.showWeekNumbers
anchors {
top: canvas.top
left: parent.left
bottom: canvas.bottom
// The borderWidth needs to be counted twice here because it goes
// in fact through two lines - the topmost one (the outer edge)
// and then the one below weekday strings
topMargin: root.cellHeight + root.borderWidth + root.borderWidth
}
spacing: root.borderWidth
Repeater {
model: root.showWeekNumbers ? calendarBackend.weeksModel : []
Components.Label {
height: root.cellHeight
width: root.cellWidth
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
opacity: 0.4
text: modelData
font.pixelSize: Math.max(theme.smallestFont.pixelSize, root.cellHeight / 6)
}
}
}
Grid { Grid {
id: calendarGrid id: calendarGrid
// Pad the grid to not overlap with the top and left frame // Pad the grid to not overlap with the top and left frame
x: root.borderWidth // When week numbers are shown, the border needs to be counted twice
// because there's one more cell to count with and therefore also
// another border to add
x: root.showWeekNumbers ? 2 * root.borderWidth + root.cellWidth: root.borderWidth
y: root.borderWidth y: root.borderWidth
columns: calendarBackend.days columns: calendarBackend.days
rows: calendarBackend.weeks + 1 rows: calendarBackend.weeks + 1
@ -129,4 +163,4 @@ Item {
DayDelegate {} DayDelegate {}
} }
} }
} }

View File

@ -47,13 +47,14 @@ Item {
property int week; property int week;
property int firstDay: new Date(showDate.getFullYear(), showDate.getMonth(), 1).getDay() property int firstDay: new Date(showDate.getFullYear(), showDate.getMonth(), 1).getDay()
property date today property date today
property bool showWeekNumbers: true
function prefCellWidth() { function prefCellWidth() {
return Math.min( return Math.min(
Math.max( Math.max(
mWidth * 3, mWidth * 3,
// Take the calendar width, subtract the inner and outer spacings and divide by number of columns (==days in week) // Take the calendar width, subtract the inner and outer spacings and divide by number of columns (==days in week)
Math.floor((calendar.width - (root.columns + 1) * borderWidth) / root.columns) Math.floor((calendar.width - (root.columns + 1) * borderWidth) / (root.columns + (root.showWeekNumbers ? 1 : 0)))
), ),
mWidth * 100 mWidth * 100
) )