laurapons
laurapons

Reputation: 1103

QML Calendar: list of visible days

Is there a way to get a list of visible days for the current month view (including the ones from previous/next month that are also visible)

Upvotes: 0

Views: 891

Answers (2)

laurapons
laurapons

Reputation: 1103

I found a quicker workaround if anyone is interested. The following code considers week starting on Monday or Sunday.

I check what day is the first day of the month, and get the Monday/Sunday of the first week, and then I check through day = firstDay + X where X goes from 0 to 42.

function checkMonthlyCases(currentYear, currentMonth){
    var firstMonthDay = new Date(currentYear,currentMonth,1,0)
    var firstVisibleDay = new Date(firstMonthDay.getTime() - (((firstMonthDay.getDay() === Locale.Sunday) ? Qt.Sunday : firstMonthDay.getDay()) - 1) * 86400000 )

    if( startDay == Qt.Sunday){
        firstVisibleDay = new Date(firstVisibleDay.getTime() - 86400000);
    }

    for(var i=0; i< 42; i++){ // 42: number of visible days
        var checkDay = new Date(firstVisibleDay.getTime() + i*86400000)
        var count = getDayCaseCount(checkDay)
    }
}

Upvotes: 0

derM
derM

Reputation: 13711

If we inspect the code of the Calendar here we can find a suspicious property __model. We find, it has always a count of 42 - which is the amount of days that are visible.

The problem is, that in QML we can't really access descendants of QAbstractItemModels, as we need a QModelIndex to fetch data, struggle with int instead of roleNames to identify the roles e.t.c.
So we need to introduce a little helper, that offers a get(index) function to us, as known from the ListModel. As base for this, we can use the QIdentityProxyModel that we'll extend by the missing, exposed method.

qmlproxymodel.h

#ifndef QMLPROXYMODEL_H
#define QMLPROXYMODEL_H

#include <QObject>
#include <QIdentityProxyModel>
#include <QMap>

class QMLProxyModel : public QIdentityProxyModel
{
    Q_OBJECT
public:
    QMLProxyModel(QObject* parent = nullptr);

public slots:
    QMap<QString, QVariant> get(int row_index) const;
};

#endif // QMLPROXYMODEL_H

qmlproxymodel.cpp

#include "qmlproxymodel.h"

QMLProxyModel::QMLProxyModel(QObject* parent)
    : QIdentityProxyModel(parent)
{

}

QMap<QString, QVariant> QMLProxyModel::get(int row_index) const
{
    QMap<QString, QVariant> ret;
    QModelIndex ind = index(row_index, 0);
    QHash<int, QByteArray> roles = roleNames();

    // for some reason the itemData-method always throw a index-out-of-range exception
    for (int e : roles.keys()) {
        ret.insert(roles.value(e), data(ind, e));
    }

    return ret;
}

Then we register this new type to QML in our main.cpp

qmlRegisterType<QMLProxyModel>("QMLProxyModel", 1, 0, "QMLProxyModel");

Finally we use it in QML:

Calendar {
    id: cal
    anchors.fill: parent
}

QMLProxyModel {
    id: pm
    sourceModel: cal.__model
    onDataChanged: console.log("Some Data has changed", pm.get(0).date)
}

Here I output the date of the first displayed date whenever the data of the model changes - that is, when the next month is selected.
It should be easy for you, to write a JS function to iterate over all (42) elements of the QMLProxyModel to add the content to any data structure, you desire.

Upvotes: 2

Related Questions