diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04c0481..edab1bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ qt_add_qml_module(${PROJECT_NAME} calendarlistmodel.cpp calendarlistmodel.h database.cpp database.h mnemonicattached.cpp mnemonicattached.h + timelinedaymodel.cpp timelinedaymodel.h timelineview.cpp timelineview.h QML_FILES ErrorNotification.qml @@ -22,6 +23,7 @@ qt_add_qml_module(${PROJECT_NAME} MnemonicLabel.qml ReservationsPage.qml SelectableLabel.qml + TimelineDayRow.qml ) set_target_properties(${PROJECT_NAME} PROPERTIES diff --git a/src/ReservationsPage.qml b/src/ReservationsPage.qml index 006d802..0e8f0a6 100644 --- a/src/ReservationsPage.qml +++ b/src/ReservationsPage.qml @@ -5,6 +5,12 @@ import QtQuick.Layouts import Camper Page { + id: page + + property real dayWidth: 24 + property date fromDate: "2024-11-01" + property date toDate: "2025-01-31" + title: qsTr("Reservations") header: ToolBar { @@ -50,7 +56,7 @@ Page { anchors.right: parent.right anchors.top: parent.top clip: true - contentWidth: 2184 + contentWidth: headerItem.implicitWidth flickableDirection: Flickable.AutoFlickDirection headerPositioning: ListView.OverlayHeader model: calendarList @@ -62,9 +68,10 @@ Page { } delegate: TimelineView { - fromDate: "2024-11-01" + dayWidth: page.dayWidth + fromDate: page.fromDate height: 16 - toDate: "2025-01-31" + toDate: page.toDate viewportWidth: ListView.view.width viewportX: ListView.view.contentX @@ -75,10 +82,14 @@ Page { } } header: Pane { + leftPadding: 0 + rightPadding: 0 z: 2 - Label { - text: qsTr("Calendar") + TimelineDayRow { + dayWidth: page.dayWidth + fromDate: page.fromDate + toDate: page.toDate } } } diff --git a/src/TimelineDayRow.qml b/src/TimelineDayRow.qml new file mode 100644 index 0000000..26f029c --- /dev/null +++ b/src/TimelineDayRow.qml @@ -0,0 +1,35 @@ +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 string display + + text: display + width: control.dayWidth + + background: Rectangle { + border.color: "red" + border.width: 1 + color: "yellow" + } + } + } + } + + TimelineDayModel { + id: model + + } +} diff --git a/src/calendarlistmodel.cpp b/src/calendarlistmodel.cpp deleted file mode 100644 index 60faf1e..0000000 --- a/src/calendarlistmodel.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "calendarlistmodel.h" -#include -#include -#include "database.h" - -struct CalendarListModel::Calendar -{ - QString name; -}; - -CalendarListModel::CalendarListModel(QObject *parent) - : QAbstractListModel{parent} - , m_calendars{} -{ - fetch(); -} - -CalendarListModel::~CalendarListModel() -{ - qDeleteAll(m_calendars); -} - -QVariant CalendarListModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role != Qt::DisplayRole) { - return {}; - } - return section; -} - -int CalendarListModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) { - return 0; - } - - return m_calendars.count(); -} - -QHash CalendarListModel::roleNames() const -{ - QHash roles = QAbstractItemModel::roleNames(); - roles[Name] = "name"; - return roles; -} - -void CalendarListModel::fetch() -{ - Database::query([]() { - QSqlQuery query("select label from campsite order by label"); - QVector calendars; - while (query.next()) { - Calendar calendar{query.value(0).toString()}; - calendars.append(calendar); - } - return calendars; - }).then([this](const QVector &calendars) { - if (calendars.empty()) { - return; - } - beginInsertRows(QModelIndex(), 0, calendars.count() - 1); - for (const Calendar &calendar : calendars) { - m_calendars.append(new Calendar(calendar)); - } - endInsertRows(); - }); -} - -QVariant CalendarListModel::data(const QModelIndex &index, int role) const -{ - if (!checkIndex(index, - QAbstractItemModel::CheckIndexOption::IndexIsValid - | QAbstractItemModel::CheckIndexOption::ParentIsInvalid)) { - return {}; - } - - Calendar *calendar = m_calendars.at(index.row()); - switch (role) { - case Name: - return calendar->name; - } - - return {}; -} - -#include "moc_calendarlistmodel.cpp" diff --git a/src/calendarlistmodel.h b/src/calendarlistmodel.h deleted file mode 100644 index 7b32c51..0000000 --- a/src/calendarlistmodel.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef CALENDARLISTMODEL_H -#define CALENDARLISTMODEL_H - -#include -#include - -class CalendarListModel : public QAbstractListModel -{ - Q_OBJECT - QML_ELEMENT - -public: - enum Roles { - Name = Qt::UserRole, - }; - - explicit CalendarListModel(QObject *parent = nullptr); - ~CalendarListModel() override; - - QVariant headerData(int section, - Qt::Orientation orientation, - int role = Qt::DisplayRole) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - QHash roleNames() const override; - -private: - struct Calendar; - - Q_DISABLE_COPY_MOVE(CalendarListModel) - - void fetch(); - - QVector m_calendars; -}; - -#endif // CALENDARLISTMODEL_H diff --git a/src/timelinedaymodel.cpp b/src/timelinedaymodel.cpp new file mode 100644 index 0000000..21758c6 --- /dev/null +++ b/src/timelinedaymodel.cpp @@ -0,0 +1,65 @@ +#include "timelinedaymodel.h" +#include + +TimelineDayModel::TimelineDayModel(QObject *parent) + : QAbstractListModel(parent) + , m_fromDate() + , m_toDate() +{} + +int TimelineDayModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) { + return 0; + } + return m_fromDate.daysTo(m_toDate) + 1; +} + +QVariant TimelineDayModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return {}; + } + + QDate date = m_fromDate.addDays(index.row()); + switch (role) { + case Qt::DisplayRole: + return QString::number(date.day()); + } + + return {}; +} + +QDate TimelineDayModel::fromDate() const +{ + return m_fromDate; +} + +void TimelineDayModel::setFromDate(QDate date) +{ + if (date == m_fromDate) { + return; + } + beginResetModel(); + m_fromDate = date; + endResetModel(); + emit fromDateChanged(m_fromDate); +} + +QDate TimelineDayModel::toDate() const +{ + return m_toDate; +} + +void TimelineDayModel::setToDate(QDate date) +{ + if (date == m_toDate) { + return; + } + beginResetModel(); + m_toDate = date; + endResetModel(); + emit toDateChanged(m_toDate); +} + +#include "moc_timelinedaymodel.cpp" diff --git a/src/timelinedaymodel.h b/src/timelinedaymodel.h new file mode 100644 index 0000000..09a6c1c --- /dev/null +++ b/src/timelinedaymodel.h @@ -0,0 +1,38 @@ +#ifndef TIMELINEDAYMODEL_H +#define TIMELINEDAYMODEL_H + +#include +#include + +class TimelineDayModel : 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) + +public: + explicit TimelineDayModel(QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + QDate fromDate() const; + void setFromDate(QDate date); + + QDate toDate() const; + void setToDate(QDate date); + +signals: + void fromDateChanged(QDate date); + void toDateChanged(QDate date); + +private: + Q_DISABLE_COPY_MOVE(TimelineDayModel) + + QDate m_fromDate; + QDate m_toDate; +}; + +#endif // TIMELINEDAYMODEL_H