Commit 721861e0 authored by Volker Krause's avatar Volker Krause
Browse files

Add today marker to the timeline view

parent 969fc054
......@@ -66,22 +66,27 @@ private slots:
QSignalSpy rmSpy(&model, &TimelineModel::rowsRemoved);
QVERIFY(rmSpy.isValid());
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.rowCount(), 1);
QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::TodayMarker);
mgr.importPass(QUrl::fromLocalFile(QLatin1String(SOURCE_DIR "/data/boardingpass-v1.pkpass")));
QCOMPARE(insertSpy.size(), 1);
QCOMPARE(insertSpy.at(0).at(1).toInt(), 0);
QCOMPARE(insertSpy.at(0).at(2).toInt(), 0);
QVERIFY(updateSpy.isEmpty());
QCOMPARE(model.rowCount(), 1);
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.index(0, 0).data(TimelineModel::ElementTypeRole), TimelineModel::Flight);
mgr.importPass(QUrl::fromLocalFile(QLatin1String(SOURCE_DIR "/data/boardingpass-v2.pkpass")));
QCOMPARE(insertSpy.size(), 1);
QCOMPARE(updateSpy.size(), 1);
QCOMPARE(model.rowCount(), 1);
QCOMPARE(updateSpy.at(0).at(0).toModelIndex().row(), 0);
QCOMPARE(model.rowCount(), 2);
clearReservations(&resMgr);
QCOMPARE(insertSpy.size(), 1);
QCOMPARE(updateSpy.size(), 1);
QCOMPARE(rmSpy.size(), 1);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.rowCount(), 1);
}
};
......
......@@ -55,6 +55,19 @@ Kirigami.ScrollablePage {
id: busDelegate
App.BusDelegate {}
}
Component {
id: todayDelegate
Item {
implicitHeight: visible ? label.implicitHeight : 0
QQC2.Label {
id: label
anchors.fill: parent
text: qsTr("Nothing on the itinerary for today.");
color: Kirigami.Theme.textColor
horizontalAlignment: Qt.AlignHCenter
}
}
}
ListView {
model: _timelineModel
......@@ -72,14 +85,19 @@ Kirigami.ScrollablePage {
case TimelineModel.Hotel: return hotelDelegate;
case TimelineModel.TrainTrip: return trainDelegate;
case TimelineModel.BusTrip: return busDelegate;
case TimelineModel.TodayMarker: return todayDelegate;
}
}
onLoaded: {
item.reservation = Qt.binding(function() { return modelData.reservation; });
item.passId = Qt.binding(function() { return modelData.passId; });
item.pass = Qt.binding(function() { return modelData.pass; });
item.showBoardingPass.connect(onShowBoardingPass);
if (modelData.type != TimelineModel.TodayMarker) {
item.reservation = Qt.binding(function() { return modelData.reservation; });
item.passId = Qt.binding(function() { return modelData.passId; });
item.pass = Qt.binding(function() { return modelData.pass; });
item.showBoardingPass.connect(onShowBoardingPass);
} else {
item.visible = modelData.isTodayEmpty;
}
}
function onShowBoardingPass(pass, passId) {
root.showBoardingPass(pass, passId)
......
......@@ -70,6 +70,10 @@ QVector<QString> ReservationManager::reservations() const
QVariant ReservationManager::reservation(const QString& id) const
{
if (id.isEmpty()) {
return {};
}
const auto it = m_reservations.constFind(id);
if (it != m_reservations.constEnd()) {
return it.value();
......
......@@ -38,7 +38,9 @@ using namespace KItinerary;
// ### the below functions probably should move to KItinerary itself
static QDate relevantDate(const QVariant &res)
{
if (res.userType() == qMetaTypeId<FlightReservation>()) {
if (res.isNull()) {
return QDate::currentDate(); // today marker
} else if (res.userType() == qMetaTypeId<FlightReservation>()) {
return res.value<FlightReservation>().reservationFor().value<Flight>().departureDay();
} else if (res.userType() == qMetaTypeId<LodgingReservation>()) {
return res.value<LodgingReservation>().checkinTime().date();
......@@ -69,16 +71,8 @@ static QDateTime relevantDateTime(const QVariant &res)
static bool isBeforeReservation(const QVariant &lhs, const QVariant &rhs)
{
if (lhs.isNull() && rhs.isNull())
return false;
if (lhs.isNull())
return false;
if (rhs.isNull())
return true;
auto lhsDt = relevantDateTime(lhs);
auto rhsDt = relevantDateTime(rhs);
auto lhsDt = lhs.isNull() ? QDateTime(QDate::currentDate(), QTime(0, 0)) : relevantDateTime(lhs);
auto rhsDt = rhs.isNull() ? QDateTime(QDate::currentDate(), QTime(0, 0)) : relevantDateTime(rhs);
if (!lhsDt.isValid())
lhsDt = QDateTime(relevantDate(lhs), QTime(23, 59, 59));
if (!rhsDt.isValid())
......@@ -113,6 +107,7 @@ void TimelineModel::setReservationManager(ReservationManager* mgr)
beginResetModel();
m_resMgr = mgr;
m_reservationIds = mgr->reservations();
m_reservationIds.push_back({}); // today marker
std::sort(m_reservationIds.begin(), m_reservationIds.end(), [this](const QString &lhs, const QString &rhs) {
return isBeforeReservation(m_resMgr->reservation(lhs), m_resMgr->reservation(rhs));
});
......@@ -151,8 +146,10 @@ QVariant TimelineModel::data(const QModelIndex& index, int role) const
}
case ReservationRole:
return res;
case ReservationTypeRole:
if (res.userType() == qMetaTypeId<FlightReservation>())
case ElementTypeRole:
if (res.isNull())
return TodayMarker;
else if (res.userType() == qMetaTypeId<FlightReservation>())
return Flight;
else if (res.userType() == qMetaTypeId<LodgingReservation>())
return Hotel;
......@@ -160,7 +157,14 @@ QVariant TimelineModel::data(const QModelIndex& index, int role) const
return TrainTrip;
else if (res.userType() == qMetaTypeId<BusReservation>())
return BusTrip;
return QVariant();
return {};
case TodayEmptyRole:
if (res.isNull()) {
return index.row() == (m_reservationIds.size() - 1) || relevantDate(m_resMgr->reservation(m_reservationIds.at(index.row() + 1))) > QDate::currentDate();
}
return {};
case IsTodayRole:
return relevantDate(res) == QDate::currentDate();
}
return {};
}
......@@ -172,7 +176,9 @@ QHash<int, QByteArray> TimelineModel::roleNames() const
names.insert(PassIdRole, "passId");
names.insert(SectionHeader, "sectionHeader");
names.insert(ReservationRole, "reservation");
names.insert(ReservationTypeRole, "type");
names.insert(ElementTypeRole, "type");
names.insert(TodayEmptyRole, "isTodayEmpty");
names.insert(IsTodayRole, "isToday");
return names;
}
......
......@@ -32,16 +32,19 @@ public:
PassIdRole,
SectionHeader,
ReservationRole,
ReservationTypeRole
ElementTypeRole,
TodayEmptyRole,
IsTodayRole
};
enum ReservationType {
enum ElementType {
Flight,
TrainTrip,
BusTrip,
Hotel
Hotel,
TodayMarker
};
Q_ENUM(ReservationType)
Q_ENUM(ElementType)
explicit TimelineModel(QObject *parent = nullptr);
~TimelineModel();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment