Add TimelineMonthRow and TimelineMonthModel
These are a lot like TimelineDayRow and TimelineDayModel, and are supposed to go in the timeline’s header too, but instead of showing the day number, they show the month name. I still need to know the with of each day, because the month must be as wide as all shown days, that may not be all the days in that month, in the first and last months, at least. Usually i will show two or three months, so i thing is is fair to keep a list of all the months and their days, rather than compute them each time the name or the day count, two times per month, are requested.
This commit is contained in:
parent
94b5faa9d8
commit
66e12d5019
|
@ -14,6 +14,7 @@ qt_add_qml_module(${PROJECT_NAME}
|
|||
timelinedaymodel.cpp timelinedaymodel.h
|
||||
timelinelistmodel.cpp timelinelistmodel.h
|
||||
timelinemodel.cpp timelinemodel.h
|
||||
timelinemonthmodel.cpp timelinemonthmodel.h
|
||||
timelineview.cpp timelineview.h
|
||||
QML_FILES
|
||||
ErrorNotification.qml
|
||||
|
@ -25,6 +26,7 @@ qt_add_qml_module(${PROJECT_NAME}
|
|||
ReservationsPage.qml
|
||||
SelectableLabel.qml
|
||||
TimelineDayRow.qml
|
||||
TimelineMonthRow.qml
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
|
|
|
@ -40,6 +40,7 @@ Page {
|
|||
text: name
|
||||
}
|
||||
header: Pane {
|
||||
height: timelineList.headerItem.height
|
||||
z: 2
|
||||
|
||||
Label {
|
||||
|
@ -89,10 +90,18 @@ Page {
|
|||
rightPadding: 0
|
||||
z: 2
|
||||
|
||||
TimelineDayRow {
|
||||
dayWidth: page.dayWidth
|
||||
fromDate: page.fromDate
|
||||
toDate: page.toDate
|
||||
Column {
|
||||
TimelineMonthRow {
|
||||
dayWidth: page.dayWidth
|
||||
fromDate: page.fromDate
|
||||
toDate: page.toDate
|
||||
}
|
||||
|
||||
TimelineDayRow {
|
||||
dayWidth: page.dayWidth
|
||||
fromDate: page.fromDate
|
||||
toDate: page.toDate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
Control {
|
||||
id: control
|
||||
|
||||
property real dayWidth: 24
|
||||
property alias fromDate: model.fromDate
|
||||
property alias toDate: model.toDate
|
||||
|
||||
contentItem: Row {
|
||||
Repeater {
|
||||
model: model
|
||||
|
||||
delegate: Label {
|
||||
required property int dayCount
|
||||
required property string display
|
||||
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: display
|
||||
width: control.dayWidth * dayCount
|
||||
|
||||
background: Rectangle {
|
||||
border.color: "red"
|
||||
border.width: 1
|
||||
color: "lightgreen"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimelineMonthModel {
|
||||
id: model
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
#include "timelinemonthmodel.h"
|
||||
#include <QVariant>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
namespace {
|
||||
|
||||
void advanceMonth(QCalendar::YearMonthDay &ymd)
|
||||
{
|
||||
if (ymd.month == 12) {
|
||||
ymd.month = 1;
|
||||
ymd.year++;
|
||||
} else {
|
||||
ymd.month++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TimelineMonthModel::TimelineMonthModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
, m_fromDate()
|
||||
, m_toDate()
|
||||
, m_locale()
|
||||
, m_months()
|
||||
{}
|
||||
|
||||
int TimelineMonthModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return m_months.length();
|
||||
}
|
||||
|
||||
QVariant TimelineMonthModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= rowCount()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Month month = m_months.at(index.row());
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return m_locale.standaloneMonthName(month.number);
|
||||
case DayCount:
|
||||
return month.days;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> TimelineMonthModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
|
||||
roles[DayCount] = "dayCount"_ba;
|
||||
return roles;
|
||||
}
|
||||
|
||||
QDate TimelineMonthModel::fromDate() const
|
||||
{
|
||||
return m_fromDate;
|
||||
}
|
||||
|
||||
void TimelineMonthModel::setFromDate(QDate date)
|
||||
{
|
||||
if (date == m_fromDate) {
|
||||
return;
|
||||
}
|
||||
m_fromDate = date;
|
||||
emit fromDateChanged(m_fromDate);
|
||||
updateMonths();
|
||||
}
|
||||
|
||||
QDate TimelineMonthModel::toDate() const
|
||||
{
|
||||
return m_toDate;
|
||||
}
|
||||
|
||||
void TimelineMonthModel::setToDate(QDate date)
|
||||
{
|
||||
if (date == m_toDate) {
|
||||
return;
|
||||
}
|
||||
m_toDate = date;
|
||||
emit toDateChanged(m_toDate);
|
||||
updateMonths();
|
||||
}
|
||||
|
||||
QLocale TimelineMonthModel::locale() const
|
||||
{
|
||||
return m_locale;
|
||||
}
|
||||
|
||||
void TimelineMonthModel::setLocale(const QLocale &locale)
|
||||
{
|
||||
if (locale == m_locale) {
|
||||
return;
|
||||
}
|
||||
m_locale = locale;
|
||||
emit localeChanged(m_locale);
|
||||
if (m_months.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
emit dataChanged(index(0), index(rowCount() - 1), {Qt::DisplayRole});
|
||||
}
|
||||
|
||||
void TimelineMonthModel::updateMonths()
|
||||
{
|
||||
QCalendar gregorian;
|
||||
QCalendar::YearMonthDay fromYMD = gregorian.partsFromDate(std::min(m_fromDate, m_toDate));
|
||||
QCalendar::YearMonthDay toYMD = gregorian.partsFromDate(std::max(m_fromDate, m_toDate));
|
||||
|
||||
if (!fromYMD.isValid() || !toYMD.isValid()) {
|
||||
if (m_months.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
beginResetModel();
|
||||
m_months.clear();
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
m_months.clear();
|
||||
if (fromYMD.year == toYMD.year && fromYMD.month == toYMD.month) {
|
||||
m_months.push_back({fromYMD.month, toYMD.day - fromYMD.day + 1});
|
||||
} else {
|
||||
m_months.push_back(
|
||||
{fromYMD.month, gregorian.daysInMonth(fromYMD.month, fromYMD.year) - fromYMD.day + 1});
|
||||
advanceMonth(fromYMD);
|
||||
for (; fromYMD.month != toYMD.month || fromYMD.year != toYMD.year; advanceMonth(fromYMD)) {
|
||||
m_months.push_back({fromYMD.month, gregorian.daysInMonth(fromYMD.month, fromYMD.year)});
|
||||
}
|
||||
m_months.push_back({toYMD.month, toYMD.day});
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
#include "moc_timelinemonthmodel.cpp"
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef TIMELINEMONTHMODEL_H
|
||||
#define TIMELINEMONTHMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QList>
|
||||
#include <QLocale>
|
||||
#include <QtQmlIntegration>
|
||||
|
||||
class TimelineMonthModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
|
||||
Q_PROPERTY(QDate fromDate READ fromDate WRITE setFromDate NOTIFY fromDateChanged)
|
||||
Q_PROPERTY(QDate toDate READ toDate WRITE setToDate NOTIFY toDateChanged)
|
||||
Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged)
|
||||
|
||||
public:
|
||||
enum {
|
||||
DayCount = Qt::UserRole,
|
||||
};
|
||||
|
||||
explicit TimelineMonthModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
QDate fromDate() const;
|
||||
void setFromDate(QDate date);
|
||||
|
||||
QDate toDate() const;
|
||||
void setToDate(QDate date);
|
||||
|
||||
QLocale locale() const;
|
||||
void setLocale(const QLocale &locale);
|
||||
|
||||
signals:
|
||||
void fromDateChanged(QDate date);
|
||||
void toDateChanged(QDate date);
|
||||
void localeChanged(const QLocale &locale);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY_MOVE(TimelineMonthModel)
|
||||
|
||||
struct Month
|
||||
{
|
||||
int number;
|
||||
int days;
|
||||
};
|
||||
|
||||
void updateMonths();
|
||||
|
||||
QDate m_fromDate;
|
||||
QDate m_toDate;
|
||||
QLocale m_locale;
|
||||
QList<Month> m_months;
|
||||
};
|
||||
|
||||
#endif // TIMELINEMONTHMODEL_H
|
Loading…
Reference in New Issue