KOSMIndoorMap

OSMElementInformationDialogOpeningHoursDelegate.qml
1/*
2 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6import QtQuick
7import QtQuick.Layouts
8import QtQuick.Controls as QQC2
9import org.kde.kirigami as Kirigami
10import org.kde.kopeninghours
12/** OSM element info dialog delegate for graphically displaying opening hours. */
13ColumnLayout {
14 id: root
15
16 /** The opening hours expression to display. */
17 property string openingHours
18 /** The ISO 3166-1/2 region code of the location the opening hours expression should be evaluated. */
19 property string regionCode
20 /** The IANA timezone identifier of the timezone in which the opening hours expression should be evaluated. */
21 property string timeZoneId
22 /** The latitude of the location the opening hours expression refers to. */
23 property double latitude: NaN
24 /** The longitude of the location the opening hours expression refers to. */
25 property double longitude: NaN
26
27 // internal
28 readonly property var oh: {
29 var v = OpeningHoursParser.parse(root.openingHours);
30 v.region = root.regionCode;
31 v.timeZone = root.timeZoneId;
32 v.setLocation(root.latitude, root.longitude);
33 if (v.error != OpeningHours.NoError && root.openingHours !== "") {
34 console.log("Opening hours parsing error:", v.error, root.regionCode, root.timeZoneId)
35 }
36 return v;
37 }
38
39 QQC2.Label {
40 property var currentInterval: root.oh.interval(new Date())
41
42 id: currentState
43 text: intervalModel.currentState // TODO we could update this every minute
44 color: {
45 switch (currentInterval.state) {
46 case Interval.Open: return Kirigami.Theme.positiveTextColor;
47 case Interval.Closed: return Kirigami.Theme.negativeTextColor;
48 default: return Kirigami.Theme.textColor;
49 }
50 }
51 visible: text !== ""
52 }
53
54 Component {
55 id: intervalDelegate
56 Item {
57 id: delegateRoot
58 property var dayData: model
59 implicitHeight: row.implicitHeight
60 Row {
61 id: row
62 QQC2.Label {
63 text: dayData.shortDayName
64 width: delegateRoot.ListView.view.labelWidth + Kirigami.Units.smallSpacing
65 Component.onCompleted: delegateRoot.ListView.view.labelWidth = Math.max(delegateRoot.ListView.view.labelWidth, implicitWidth)
66 font.bold: dayData.isToday
67 }
68 Repeater {
69 model: dayData.intervals
70 Rectangle {
71 id: intervalBox
72 property var interval: modelData
73 property var closeColor: Kirigami.Theme.negativeBackgroundColor;
74 color: {
75 switch (interval.state) {
76 case Interval.Open: return Kirigami.Theme.positiveBackgroundColor;
77 case Interval.Closed: return intervalBox.closeColor;
78 case Interval.Unknown: return Kirigami.Theme.neutralBackgroundColor;
79 }
80 return "transparent";
81 }
82 width: {
83 const ratio = (interval.estimatedEnd - interval.begin + interval.dstOffset * 1000) / (24 * 60 * 60 * 1000);
84 return ratio * (delegateRoot.ListView.view.width - delegateRoot.ListView.view.labelWidth - Kirigami.Units.smallSpacing);
85 }
86 height: Kirigami.Units.gridUnit
87 gradient: Gradient {
88 orientation: Gradient.Horizontal
89 GradientStop { position: 0.0; color: intervalBox.color }
90 GradientStop { position: (interval.end - interval.begin) / (interval.estimatedEnd - interval.begin); color: intervalBox.color }
91 GradientStop { position: 1.0; color: interval.hasOpenEndTime ? intervalBox.closeColor : intervalBox.color }
92 }
93
94 QQC2.Label {
95 id: commentLabel
96 text: interval.comment
97 anchors.centerIn: parent
98 visible: commentLabel.implicitWidth < intervalBox.width
99 font.italic: true
100 }
101 }
102 }
103 }
104 Rectangle {
105 id: nowMarker
106 property double position: (Date.now() - dayData.dayBegin) / (24 * 60 * 60 * 1000)
107 visible: position >= 0.0 && position < 1.0
108 color: Kirigami.Theme.textColor
109 width: 2
110 height: Kirigami.Units.gridUnit
111 x: position * (delegateRoot.ListView.view.width - delegateRoot.ListView.view.labelWidth - Kirigami.Units.smallSpacing)
112 + delegateRoot.ListView.view.labelWidth + Kirigami.Units.smallSpacing
113 }
114 }
115 }
116
117 IntervalModel {
118 id: intervalModel
119 openingHours: root.oh
120 // TODO we could use the layover time here, if available and in the future
121 beginDate: intervalModel.beginOfWeek(new Date())
122 endDate: new Date(intervalModel.beginDate.getTime() + 7 * 24 * 3600 * 1000)
123 }
124
125 FontMetrics {
126 id: fm
127 }
128
129 ListView {
130 id: intervalView
131 width: parent.width
132 height: contentHeight
133 boundsBehavior: Flickable.StopAtBounds
134 visible: root.oh.error == OpeningHours.NoError
135 model: intervalModel
136 delegate: intervalDelegate
137 property int labelWidth: 0
138 spacing: Kirigami.Units.smallSpacing
139 clip: true
140 header: Row {
141 id: intervalHeader
142 property int colCount: (intervalView.width - Kirigami.Units.smallSpacing - intervalView.labelWidth) / fm.advanceWidth(intervalModel.formatTimeColumnHeader(12, 59)) < 8 ? 4 : 8
143 property int itemWidth: (intervalHeader.ListView.view.width - intervalHeader.ListView.view.labelWidth - Kirigami.Units.smallSpacing) / colCount
144 x: intervalHeader.ListView.view.labelWidth + Kirigami.Units.smallSpacing + intervalHeader.itemWidth/2
145 Repeater {
146 // TODO we might need to use less when space constrained horizontally
147 model: colCount - 1
148 QQC2.Label {
149 text: intervalModel.formatTimeColumnHeader((modelData + 1) * 24/colCount, 0)
150 width: intervalHeader.itemWidth
151 horizontalAlignment: Qt.AlignHCenter
152 }
153 }
154 }
155 }
156
157 QQC2.Label {
158 id: fallbackLabel
159 visible: !intervalView.visible
160 text: root.openingHours.replace(/;\s*/g, "\n")
161 }
162}
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QAction * replace(const QObject *recvr, const char *slot, QObject *parent)
AlignHCenter
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 26 2024 11:57:46 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.