aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates/qquickcalendarmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates/qquickcalendarmodel.cpp')
-rw-r--r--src/quicktemplates/qquickcalendarmodel.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/quicktemplates/qquickcalendarmodel.cpp b/src/quicktemplates/qquickcalendarmodel.cpp
new file mode 100644
index 0000000000..bb3e2a7796
--- /dev/null
+++ b/src/quicktemplates/qquickcalendarmodel.cpp
@@ -0,0 +1,228 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qquickcalendarmodel_p.h"
+
+#include <QtCore/private/qabstractitemmodel_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype CalendarModel
+ \inherits QAbstractListModel
+//! \instantiates QQuickCalendarModel
+ \inqmlmodule QtQuick.Controls
+ \brief A calendar model.
+
+ CalendarModel provides a way of creating a range of MonthGrid
+ instances. It is typically used as a model for a ListView that uses
+ MonthGrid as a delegate.
+
+ \snippet qtquickcontrols-calendarmodel.qml 1
+
+ In addition to the \c index property, a list of model data roles
+ are available in the context of each delegate:
+ \table
+ \row \li \b model.month : int \li The number of the month
+ \row \li \b model.year : int \li The number of the year
+ \endtable
+
+ \include zero-based-months.qdocinc
+
+ \sa MonthGrid, Calendar
+*/
+
+class QQuickCalendarModelPrivate : public QAbstractItemModelPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickCalendarModel)
+
+public:
+ QQuickCalendarModelPrivate() : complete(false),
+ from(1,1,1), to(275759, 9, 25), count(0)
+ {
+ }
+
+ static int getCount(QDate from, QDate to);
+
+ void populate(QDate from, QDate to, bool force = false);
+
+ bool complete;
+ QDate from;
+ QDate to;
+ int count;
+};
+
+// Returns the number of months we need to display for both from and to to be shown,
+// or zero if from is in a later month than to, or either is invalid.
+int QQuickCalendarModelPrivate::getCount(QDate from, QDate to)
+{
+ if (!from.isValid() || !to.isValid())
+ return 0;
+
+ const QCalendar gregorian;
+ Q_ASSERT(gregorian.isGregorian());
+ const QCalendar::YearMonthDay &f = gregorian.partsFromDate(from);
+ const QCalendar::YearMonthDay &t = gregorian.partsFromDate(to);
+ Q_ASSERT(f.isValid() && t.isValid()); // ... because from and to are valid.
+ if (f.year > t.year || (f.year == t.year && f.month > t.month))
+ return 0;
+
+ // Count from's month and every subsequent month until to's:
+ return 1 + t.month + 12 * (t.year - f.year) - f.month;
+}
+
+void QQuickCalendarModelPrivate::populate(QDate f, QDate t, bool force)
+{
+ Q_Q(QQuickCalendarModel);
+ if (!force && f == from && t == to)
+ return;
+
+ int c = getCount(from, to);
+ if (c != count) {
+ q->beginResetModel();
+ count = c;
+ q->endResetModel();
+ emit q->countChanged();
+ } else {
+ emit q->dataChanged(q->index(0, 0), q->index(c - 1, 0));
+ }
+}
+
+QQuickCalendarModel::QQuickCalendarModel(QObject *parent) :
+ QAbstractListModel(*(new QQuickCalendarModelPrivate), parent)
+{
+}
+
+/*!
+ \qmlproperty date QtQuick.Controls::CalendarModel::from
+
+ This property holds the start date.
+*/
+QDate QQuickCalendarModel::from() const
+{
+ Q_D(const QQuickCalendarModel);
+ return d->from;
+}
+
+void QQuickCalendarModel::setFrom(QDate from)
+{
+ Q_D(QQuickCalendarModel);
+ if (d->from != from) {
+ if (d->complete)
+ d->populate(from, d->to);
+ d->from = from;
+ emit fromChanged();
+ }
+}
+
+/*!
+ \qmlproperty date QtQuick.Controls::CalendarModel::to
+
+ This property holds the end date.
+*/
+QDate QQuickCalendarModel::to() const
+{
+ Q_D(const QQuickCalendarModel);
+ return d->to;
+}
+
+void QQuickCalendarModel::setTo(QDate to)
+{
+ Q_D(QQuickCalendarModel);
+ if (d->to != to) {
+ if (d->complete)
+ d->populate(d->from, to);
+ d->to = to;
+ emit toChanged();
+ }
+}
+
+/*!
+ \qmlmethod int QtQuick.Controls::CalendarModel::monthAt(int index)
+
+ Returns the month number at the specified model \a index.
+*/
+int QQuickCalendarModel::monthAt(int index) const
+{
+ Q_D(const QQuickCalendarModel);
+ return d->from.addMonths(index).month() - 1;
+}
+
+/*!
+ \qmlmethod int QtQuick.Controls::CalendarModel::yearAt(int index)
+
+ Returns the year number at the specified model \a index.
+*/
+int QQuickCalendarModel::yearAt(int index) const
+{
+ Q_D(const QQuickCalendarModel);
+ return d->from.addMonths(index).year();
+}
+
+/*!
+ \qmlmethod int QtQuick.Controls::CalendarModel::indexOf(Date date)
+
+ Returns the model index of the specified \a date.
+*/
+int QQuickCalendarModel::indexOf(QDate date) const
+{
+ Q_D(const QQuickCalendarModel);
+ return d->getCount(d->from, date) - 1;
+}
+
+/*!
+ \qmlmethod int QtQuick.Controls::CalendarModel::indexOf(int year, int month)
+
+ Returns the model index of the specified \a year and \a month.
+*/
+int QQuickCalendarModel::indexOf(int year, int month) const
+{
+ return indexOf(QDate(year, month + 1, 1));
+}
+
+QVariant QQuickCalendarModel::data(const QModelIndex &index, int role) const
+{
+ Q_D(const QQuickCalendarModel);
+ if (index.isValid() && index.row() < d->count) {
+ switch (role) {
+ case MonthRole:
+ return monthAt(index.row());
+ case YearRole:
+ return yearAt(index.row());
+ default:
+ break;
+ }
+ }
+ return QVariant();
+}
+
+int QQuickCalendarModel::rowCount(const QModelIndex &parent) const
+{
+ Q_D(const QQuickCalendarModel);
+ if (!parent.isValid())
+ return d->count;
+ return 0;
+}
+
+QHash<int, QByteArray> QQuickCalendarModel::roleNames() const
+{
+ QHash<int, QByteArray> roles;
+ roles[MonthRole] = QByteArrayLiteral("month");
+ roles[YearRole] = QByteArrayLiteral("year");
+ return roles;
+}
+
+void QQuickCalendarModel::classBegin()
+{
+}
+
+void QQuickCalendarModel::componentComplete()
+{
+ Q_D(QQuickCalendarModel);
+ d->complete = true;
+ d->populate(d->from, d->to, true);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qquickcalendarmodel_p.cpp"