diff --git a/src/models/itinerarymodel.cpp b/src/models/itinerarymodel.cpp index af1153dd0..afdb7c88d 100644 --- a/src/models/itinerarymodel.cpp +++ b/src/models/itinerarymodel.cpp @@ -26,20 +26,68 @@ QVariant ItineraryModel::data(const QModelIndex &index, int role) const auto data = m_data[row]; if (role == NameRole) { if (data[QStringLiteral("@type")] == QStringLiteral("TrainReservation")) { - return data[QStringLiteral("reservationFor")][QStringLiteral("trainNumber")]; + auto trainName = QStringLiteral("%1 %2").arg(data[QStringLiteral("reservationFor")][QStringLiteral("trainName")].toString(), + data[QStringLiteral("reservationFor")][QStringLiteral("trainNumber")].toString()); + if (trainName.trimmed().isEmpty()) { + return QStringLiteral("%1 to %2") + .arg(data[QStringLiteral("reservationFor")][QStringLiteral("departureStation")][QStringLiteral("name")].toString(), + data[QStringLiteral("reservationFor")][QStringLiteral("arrivalStation")][QStringLiteral("name")].toString()); + ; + } + return trainName; } if (data[QStringLiteral("@type")] == QStringLiteral("LodgingReservation")) { return data[QStringLiteral("reservationFor")][QStringLiteral("name")]; } + if (data[QStringLiteral("@type")] == QStringLiteral("FoodEstablishmentReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("name")]; + } + if (data[QStringLiteral("@type")] == QStringLiteral("FlightReservation")) { + return QStringLiteral("%1 %2 %3 → %4") + .arg(data[QStringLiteral("reservationFor")][QStringLiteral("airline")][QStringLiteral("iataCode")].toString(), + data[QStringLiteral("reservationFor")][QStringLiteral("flightNumber")].toString(), + data[QStringLiteral("reservationFor")][QStringLiteral("departureAirport")][QStringLiteral("iataCode")].toString(), + data[QStringLiteral("reservationFor")][QStringLiteral("arrivalAirport")][QStringLiteral("iataCode")].toString()); + } } if (role == TypeRole) { return data[QStringLiteral("@type")]; } - if (role == DepartureStationRole) { - return data[QStringLiteral("reservationFor")][QStringLiteral("departureStation")][QStringLiteral("name")]; + if (role == DepartureLocationRole) { + if (data[QStringLiteral("@type")] == QStringLiteral("TrainReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("departureStation")][QStringLiteral("name")]; + } + if (data[QStringLiteral("@type")] == QStringLiteral("FlightReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("departureAirport")][QStringLiteral("iataCode")]; + } } - if (role == ArrivalStationRole) { - return data[QStringLiteral("reservationFor")][QStringLiteral("arrivalStation")][QStringLiteral("name")]; + if (role == DepartureAddressRole) { + if (data[QStringLiteral("@type")] == QStringLiteral("TrainReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("departureStation")][QStringLiteral("address")][QStringLiteral("addressCountry")] + .toString(); + } + if (data[QStringLiteral("@type")] == QStringLiteral("FlightReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("departureAirport")][QStringLiteral("address")][QStringLiteral("addressCountry")] + .toString(); + } + } + if (role == ArrivalLocationRole) { + if (data[QStringLiteral("@type")] == QStringLiteral("TrainReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("arrivalStation")][QStringLiteral("name")]; + } + if (data[QStringLiteral("@type")] == QStringLiteral("FlightReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("arrivalAirport")][QStringLiteral("iataCode")]; + } + } + if (role == ArrivalAddressRole) { + if (data[QStringLiteral("@type")] == QStringLiteral("TrainReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("arrivalStation")][QStringLiteral("address")][QStringLiteral("addressCountry")] + .toString(); + } + if (data[QStringLiteral("@type")] == QStringLiteral("FlightReservation")) { + return data[QStringLiteral("reservationFor")][QStringLiteral("arrivalAirport")][QStringLiteral("address")][QStringLiteral("addressCountry")] + .toString(); + } } if (role == DepartureTimeRole) { const auto &time = data[QStringLiteral("reservationFor")][QStringLiteral("departureTime")]; @@ -66,7 +114,16 @@ QVariant ItineraryModel::data(const QModelIndex &index, int role) const addressData[QStringLiteral("addressCountry")].toString()); } if (role == StartTimeRole) { - auto dateTime = data[QStringLiteral("checkinTime")][QStringLiteral("@value")].toVariant().toDateTime(); + QDateTime dateTime; + if (data[QStringLiteral("@type")] == QStringLiteral("LodgingReservation")) { + dateTime = data[QStringLiteral("checkinTime")][QStringLiteral("@value")].toVariant().toDateTime(); + } + if (data[QStringLiteral("@type")] == QStringLiteral("FoodEstablishmentReservation")) { + dateTime = data[QStringLiteral("startTime")][QStringLiteral("@value")].toVariant().toDateTime(); + } + if (data[QStringLiteral("@type")] == QStringLiteral("FlightReservation")) { + dateTime = data[QStringLiteral("reservationFor")][QStringLiteral("boardingTime")][QStringLiteral("@value")].toVariant().toDateTime(); + } return dateTime.toString(QLocale::system().dateTimeFormat(QLocale::ShortFormat)); } if (role == EndTimeRole) { @@ -99,8 +156,10 @@ QHash ItineraryModel::roleNames() const return { {NameRole, "name"}, {TypeRole, "type"}, - {DepartureStationRole, "departureStation"}, - {ArrivalStationRole, "arrivalStation"}, + {DepartureLocationRole, "departureLocation"}, + {DepartureAddressRole, "departureAddress"}, + {ArrivalLocationRole, "arrivalLocation"}, + {ArrivalAddressRole, "arrivalAddress"}, {DepartureTimeRole, "departureTime"}, {ArrivalTimeRole, "arrivalTime"}, {AddressRole, "address"}, diff --git a/src/models/itinerarymodel.h b/src/models/itinerarymodel.h index 5b018c72e..d5caff454 100644 --- a/src/models/itinerarymodel.h +++ b/src/models/itinerarymodel.h @@ -19,10 +19,12 @@ public: enum Roles { NameRole = Qt::DisplayRole, TypeRole, - DepartureStationRole, - ArrivalStationRole, + DepartureLocationRole, + ArrivalLocationRole, DepartureTimeRole, + DepartureAddressRole, ArrivalTimeRole, + ArrivalAddressRole, AddressRole, StartTimeRole, EndTimeRole, diff --git a/src/timeline/CMakeLists.txt b/src/timeline/CMakeLists.txt index c72215c9b..52f188bad 100644 --- a/src/timeline/CMakeLists.txt +++ b/src/timeline/CMakeLists.txt @@ -23,6 +23,13 @@ qt_add_qml_module(timeline FileComponent.qml ImageComponent.qml ItineraryComponent.qml + ItineraryReservationComponent.qml + JourneySectionStopDelegateLineSegment.qml + TransportIcon.qml + FoodReservationComponent.qml + TrainReservationComponent.qml + FlightReservationComponent.qml + HotelReservationComponent.qml LinkPreviewComponent.qml LiveLocationComponent.qml LoadComponent.qml @@ -36,4 +43,30 @@ qt_add_qml_module(timeline StateComponent.qml TextComponent.qml VideoComponent.qml + RESOURCES + images/bike.svg + images/bus.svg + images/cablecar.svg + images/car.svg + images/coach.svg + images/couchettecar.svg + images/elevator.svg + images/escalator.svg + images/ferry.svg + images/flight.svg + images/foodestablishment.svg + images/funicular.svg + images/longdistancetrain.svg + images/rapidtransit.svg + images/seat.svg + images/shuttle.svg + images/sleepingcar.svg + images/stairs.svg + images/subway.svg + images/taxi.svg + images/train.svg + images/tramway.svg + images/transfer.svg + images/wait.svg + images/walk.svg ) diff --git a/src/timeline/FlightReservationComponent.qml b/src/timeline/FlightReservationComponent.qml new file mode 100644 index 000000000..2add79316 --- /dev/null +++ b/src/timeline/FlightReservationComponent.qml @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: 2024 James Graham +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.formcard as FormCard + +/** + * @brief A component for a flight itinerary reservation. + */ +ItineraryReservationComponent { + id: root + + /** + * @brief The name of the reservation. + */ + required property string name + + /** + * @brief The boarding time of the flight. + * + * Includes date. + */ + required property string startTime + + /** + * @brief The departure airport of the flight. + */ + required property string departureLocation + + /** + * @brief The address of the departure airport of the flight. + */ + required property string departureAddress + + /** + * @brief The arrival airport of the flight. + */ + required property string arrivalLocation + + /** + * @brief The address of the arrival airport of the flight. + */ + required property string arrivalAddress + + headerItem: RowLayout { + TransportIcon { + source: "qrc:/qt/qml/org/kde/neochat/timeline/images/flight.svg" + isMask: true + size: Kirigami.Units.iconSizes.smallMedium + } + QQC2.Label { + Layout.fillWidth: true + text: root.name + elide: Text.ElideRight + + Accessible.ignored: true + } + QQC2.Label { + text: root.startTime + } + } + + contentItem: ColumnLayout { + id: topLayout + spacing: Kirigami.Units.smallSpacing + + QQC2.Label { + Layout.fillWidth: true + text: i18nc("flight departure, %1 is airport, %2 is time", "Departure from %1", + root.departureLocation) + color: Kirigami.Theme.textColor + wrapMode: Text.WordWrap + } + QQC2.Label { + Layout.fillWidth: true + visible: text !== "" + text: root.departureAddress + } + + Kirigami.Separator { + Layout.fillWidth: true + } + + QQC2.Label { + Layout.fillWidth: true + text: i18nc("flight arrival, %1 is airport, %2 is time", "Arrival at %1", + root.arrivalLocation) + color: Kirigami.Theme.textColor + wrapMode: Text.WordWrap + } + QQC2.Label { + Layout.fillWidth: true + visible: text !== "" + text: root.arrivalAddress + } + } +} diff --git a/src/timeline/FoodReservationComponent.qml b/src/timeline/FoodReservationComponent.qml new file mode 100644 index 000000000..f59f670e2 --- /dev/null +++ b/src/timeline/FoodReservationComponent.qml @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2024 James Graham +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.formcard as FormCard + +/** + * @brief A component for a food itinerary reservation. + */ +ItineraryReservationComponent { + id: root + + /** + * @brief The name of the reservation. + */ + required property string name + + /** + * @brief The start time of the reservation. + * + * Includes date. + */ + required property string startTime + + /** + * @brief The address of the hotel. + */ + required property string address + + headerItem: RowLayout { + TransportIcon { + source: "qrc:/qt/qml/org/kde/neochat/timeline/images/foodestablishment.svg" + isMask: true + size: Kirigami.Units.iconSizes.smallMedium + } + QQC2.Label { + Layout.fillWidth: true + text: root.name + elide: Text.ElideRight + + Accessible.ignored: true + } + QQC2.Label { + text: root.startTime + } + } + + contentItem: QQC2.Label { + visible: text !== "" + text: root.address + wrapMode: Text.Wrap + } +} diff --git a/src/timeline/HotelReservationComponent.qml b/src/timeline/HotelReservationComponent.qml new file mode 100644 index 000000000..1fce7b368 --- /dev/null +++ b/src/timeline/HotelReservationComponent.qml @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: 2024 James Graham +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.formcard as FormCard + +/** + * @brief A component for a hotel itinerary reservation. + */ +ItineraryReservationComponent { + id: root + + /** + * @brief The name of the reservation. + */ + required property string name + + /** + * @brief The check-in time at the hotel. + * + * Includes date. + */ + required property string startTime + + /** + * @brief The check-out time at the hotel. + * + * Includes date. + */ + required property string endTime + + /** + * @brief The address of the hotel. + */ + required property string address + + headerItem: RowLayout { + TransportIcon { + source: "go-home-symbolic" + isMask: true + size: Kirigami.Units.iconSizes.smallMedium + } + QQC2.Label { + text: root.name + elide: Text.ElideRight + + Accessible.ignored: true + } + } + + contentItem: ColumnLayout { + spacing: Kirigami.Units.smallSpacing + + QQC2.Label { + Layout.fillWidth: true + visible: text !== "" + text: root.address + wrapMode: Text.WordWrap + } + QQC2.Label { + text: i18n("Check-in time: %1", root.startTime) + color: Kirigami.Theme.textColor + } + QQC2.Label { + text: i18n("Check-out time: %1", root.endTime) + color: Kirigami.Theme.textColor + } + + } +} diff --git a/src/timeline/ItineraryComponent.qml b/src/timeline/ItineraryComponent.qml index 12f0cc7c8..82fe6fe4f 100644 --- a/src/timeline/ItineraryComponent.qml +++ b/src/timeline/ItineraryComponent.qml @@ -36,63 +36,19 @@ ColumnLayout { role: "type" DelegateChoice { roleValue: "TrainReservation" - delegate: ColumnLayout { - Kirigami.Separator { - Layout.fillWidth: true - } - RowLayout { - QQC2.Label { - text: model.name - } - QQC2.Label { - text: model.coach ? i18n("Coach: %1, Seat: %2", model.coach, model.seat) : "" - visible: model.coach - opacity: 0.7 - } - } - RowLayout { - Layout.fillWidth: true - ColumnLayout { - QQC2.Label { - text: model.departureStation + (model.departurePlatform ? (" [" + model.departurePlatform + "]") : "") - } - QQC2.Label { - text: model.departureTime - opacity: 0.7 - } - } - Item { - Layout.fillWidth: true - } - ColumnLayout { - QQC2.Label { - text: model.arrivalStation + (model.arrivalPlatform ? (" [" + model.arrivalPlatform + "]") : "") - } - QQC2.Label { - text: model.arrivalTime - opacity: 0.7 - Layout.alignment: Qt.AlignRight - } - } - } - } + delegate: TrainReservationComponent {} } DelegateChoice { roleValue: "LodgingReservation" - delegate: ColumnLayout { - Kirigami.Separator { - Layout.fillWidth: true - } - QQC2.Label { - text: model.name - } - QQC2.Label { - text: i18nc(" - ", "%1 - %2", model.startTime, model.endTime) - } - QQC2.Label { - text: model.address - } - } + delegate: HotelReservationComponent {} + } + DelegateChoice { + roleValue: "FoodEstablishmentReservation" + delegate: FoodReservationComponent {} + } + DelegateChoice { + roleValue: "FlightReservation" + delegate: FlightReservationComponent {} } } } diff --git a/src/timeline/ItineraryReservationComponent.qml b/src/timeline/ItineraryReservationComponent.qml new file mode 100644 index 000000000..50d00a33b --- /dev/null +++ b/src/timeline/ItineraryReservationComponent.qml @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2024 James Graham +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +import QtQuick +import QtQuick.Layouts + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.formcard as FormCard + +/** + * @brief A base component for an itinerary reservation. + */ +FormCard.FormCard { + id: root + + /** + * @brief An item with the header content. + */ + property alias headerItem: headerDelegate.contentItem + + /** + * @brief An item with the main body content. + */ + property alias contentItem: content.contentItem + + Layout.fillWidth: true + implicitWidth: Math.max(headerDelegate.implicitWidth, content.implicitWidth) + + Component.onCompleted: children[0].radius = Kirigami.Units.smallSpacing + + FormCard.AbstractFormDelegate { + id: headerDelegate + Layout.fillWidth: true + background: Rectangle { + color: Kirigami.Theme.backgroundColor + Kirigami.Theme.colorSet: Kirigami.Theme.Header + Kirigami.Theme.inherit: false + } + } + FormCard.AbstractFormDelegate { + id: content + Layout.fillWidth: true + background: null + } +} + diff --git a/src/timeline/JourneySectionStopDelegateLineSegment.qml b/src/timeline/JourneySectionStopDelegateLineSegment.qml new file mode 100644 index 000000000..926afe557 --- /dev/null +++ b/src/timeline/JourneySectionStopDelegateLineSegment.qml @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: 2020 Volker Krause +// SPDX-License-Identifier: LGPL-2.0-or-later + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 + +import org.kde.kirigami as Kirigami + +/** + * @brief Line segment drawn on the left in the journey section view. + * + * Can be used in a fully drawn form, or partially drawn as a progress + * overlay over the full variant. + */ +Item { + id: root + + /** + * @brief Whether the segment is representing the start of the journey. + * + * I.e. this will show a segment rounded at the top with a stop marker. + */ + property bool isDeparture: false + + /** + * @brief Whether the segment is representing the end of the journey. + * + * I.e. this will show a segment rounded at the bottom with a stop marker. + */ + property bool isArrival: false + + /** + * @brief The color of the segment. + */ + property color lineColor: Kirigami.Theme.textColor + + /** + * @brief The width of the segment. + */ + property int lineWidth: Kirigami.Units.smallSpacing *4 + + implicitWidth: root.lineWidth * 2 + clip: true + + Kirigami.ShadowedRectangle { + id: line + x: root.lineWidth / 2 + y: isDeparture? parent.height-height:0 + width: root.lineWidth + color: root.lineColor + + corners { + topRightRadius: isDeparture ? Math.round(width / 2) : 0 + topLeftRadius: isDeparture ? Math.round(width / 2) : 0 + + bottomRightRadius: isArrival ? Math.round(width / 2) : 0 + bottomLeftRadius: isArrival ? Math.round(width / 2) : 0 + } + height: + if (isArrival) { + Math.round(parent.height / 2) + root.lineWidth / 2 + } else if (isDeparture) { + Math.round(parent.height / 2) + root.lineWidth / 2 + } else { + parent.height + } + } + + Rectangle { + id: stopDot + x: line.x + (line.width - width) / 2 + y: parent.height / 2 - width / 2 + radius: width / 2 + width: root.lineWidth * 0.6 + height: width + color: Kirigami.Theme.backgroundColor + visible: root.isArrival || root.isDeparture + } +} diff --git a/src/timeline/TrainReservationComponent.qml b/src/timeline/TrainReservationComponent.qml new file mode 100644 index 000000000..11edadca1 --- /dev/null +++ b/src/timeline/TrainReservationComponent.qml @@ -0,0 +1,214 @@ +// SPDX-FileCopyrightText: 2024 James Graham +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls as QQC2 + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.formcard as FormCard + +/** + * @brief A component for a train itinerary reservation component. + */ +ItineraryReservationComponent { + id: root + + /** + * @brief The name of the reservation. + */ + required property string name + + /** + * @brief The departure time of the train. + */ + required property string departureTime + + /** + * @brief The departure station of the train. + */ + required property string departureLocation + + /** + * @brief The address of the departure station of the train. + */ + required property string departureAddress + + /** + * @brief The departure platform of the train. + */ + required property string departurePlatform + + /** + * @brief The arrival time of the train. + */ + required property string arrivalTime + + /** + * @brief The arrival station of the train. + */ + required property string arrivalLocation + + /** + * @brief The address of the arrival station of the train. + */ + required property string arrivalAddress + + /** + * @brief The arrival platform of the train. + */ + required property string arrivalPlatform + + headerItem: RowLayout { + TransportIcon { + source: "qrc:/qt/qml/org/kde/neochat/timeline/images/train.svg" + isMask: true + size: Kirigami.Units.iconSizes.smallMedium + } + QQC2.Label { + Layout.fillWidth: true + text: root.name + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + + Accessible.ignored: true + } + QQC2.Label { + text: root.departureTime + } + } + + contentItem: ColumnLayout { + spacing: 0 + + RowLayout { + Layout.fillWidth: true + ColumnLayout{ + id: lineSectionColumn + spacing: 0 + JourneySectionStopDelegateLineSegment { + Layout.fillHeight: true + isDeparture: true + } + JourneySectionStopDelegateLineSegment { + visible: departureCountryLayout.visible + Layout.fillHeight: true + } + } + + ColumnLayout{ + Layout.bottomMargin: Kirigami.Units.largeSpacing + + spacing:0 + Layout.fillHeight: true + Layout.fillWidth: true + RowLayout { + Layout.fillHeight: true + Layout.fillWidth: true + QQC2.Label { + id: depTime + text: root.departureTime + } + QQC2.Label { + Layout.fillWidth: true + font.bold: true + text: root.departureLocation + elide: Text.ElideRight + } + QQC2.Label { + Layout.alignment: Qt.AlignRight + text: { + let platform = root.departurePlatform; + + if (platform) { + return i18n("Pl. %1", platform); + } else { + return ""; + } + } + } + } + RowLayout{ + id: departureCountryLayout + visible: departureCountryLabel.text.length > 0 + Item{ + Layout.minimumWidth: depTime.width + } + QQC2.Label { + id: departureCountryLabel + Layout.fillWidth: true + text: root.departureAddress + } + } + } + } + RowLayout{ + Layout.fillWidth: true + JourneySectionStopDelegateLineSegment { + Layout.fillHeight: true + } + Kirigami.Separator { + Layout.fillWidth: true + } + } + RowLayout { + Layout.fillWidth: true + ColumnLayout { + spacing: 0 + JourneySectionStopDelegateLineSegment { + visible: arrivalCountryLayout.visible + Layout.fillHeight: true + } + JourneySectionStopDelegateLineSegment { + Layout.fillHeight: true + isArrival: true + } + } + ColumnLayout{ + Layout.topMargin: Kirigami.Units.largeSpacing + + spacing:0 + Layout.fillHeight: true + Layout.fillWidth: true + RowLayout { + Layout.fillHeight: true + Layout.fillWidth: true + QQC2.Label { + text: root.arrivalTime + } + QQC2.Label { + Layout.fillWidth: true + font.bold: true + text: root.arrivalLocation + elide: Text.ElideRight + } + QQC2.Label { + Layout.alignment: Qt.AlignRight + text: { + let platform = root.arrivalPlatform; + + if (platform) { + return i18n("Pl. %1", platform); + } else { + return ""; + } + } + } + } + RowLayout { + id: arrivalCountryLayout + visible: arrivalCountryLabel.text.length > 0 + Item{ + Layout.minimumWidth: depTime.width + } + QQC2.Label { + id: arrivalCountryLabel + Layout.fillWidth: true + text: root.arrivalAddress + } + } + } + } + } +} + diff --git a/src/timeline/TransportIcon.qml b/src/timeline/TransportIcon.qml new file mode 100644 index 000000000..298e18a89 --- /dev/null +++ b/src/timeline/TransportIcon.qml @@ -0,0 +1,46 @@ +/* + SPDX-FileCopyrightText: 2023 Volker Krause + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +import QtQuick +import QtQuick.Layouts +import org.kde.kirigami as Kirigami + +/** Displays a transport line or mode logo/icon. + * Mainly to hide ugly implementation details of Icon not + * handling non-square SVG assets in the way we need it here. + */ +Item { + id: root + // properties match those of Icon + property string source + property alias isMask: __icon.isMask + property alias color: __icon.color + + // icon size (height for non-square ones) + property int size: Kirigami.Units.iconSizes.small + + property bool __isIcon: !source.startsWith("file:") + + + implicitWidth: __isIcon ? root.size : Math.round(root.size * __image.implicitWidth / __image.implicitHeight) + implicitHeight: root.size + + Layout.preferredWidth: root.implicitWidth + Layout.preferredHeight: root.implicitHeight + + Kirigami.Icon { + id: __icon + source: root.__isIcon ? root.source : "" + visible: source !== "" + anchors.fill: parent + } + Image { + id: __image + source: root.__isIcon ? "" : root.source + visible: source !== "" + anchors.fill: parent + fillMode: Image.PreserveAspectFit + } +} diff --git a/src/timeline/images/bike.svg b/src/timeline/images/bike.svg new file mode 100644 index 000000000..4a22acc59 --- /dev/null +++ b/src/timeline/images/bike.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/src/timeline/images/bike.svg.license b/src/timeline/images/bike.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/bike.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/bus.svg b/src/timeline/images/bus.svg new file mode 100644 index 000000000..3355de268 --- /dev/null +++ b/src/timeline/images/bus.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/bus.svg.license b/src/timeline/images/bus.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/bus.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/cablecar.svg b/src/timeline/images/cablecar.svg new file mode 100644 index 000000000..5353d0660 --- /dev/null +++ b/src/timeline/images/cablecar.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/cablecar.svg.license b/src/timeline/images/cablecar.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/cablecar.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/car.svg b/src/timeline/images/car.svg new file mode 100644 index 000000000..6b7899d95 --- /dev/null +++ b/src/timeline/images/car.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/timeline/images/car.svg.license b/src/timeline/images/car.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/car.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/coach.svg b/src/timeline/images/coach.svg new file mode 100644 index 000000000..20e06ded8 --- /dev/null +++ b/src/timeline/images/coach.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/coach.svg.license b/src/timeline/images/coach.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/coach.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/couchettecar.svg b/src/timeline/images/couchettecar.svg new file mode 100644 index 000000000..5ccb6bc8a --- /dev/null +++ b/src/timeline/images/couchettecar.svg @@ -0,0 +1,11 @@ + + + + + diff --git a/src/timeline/images/couchettecar.svg.license b/src/timeline/images/couchettecar.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/couchettecar.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/elevator.svg b/src/timeline/images/elevator.svg new file mode 100644 index 000000000..55746434e --- /dev/null +++ b/src/timeline/images/elevator.svg @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/timeline/images/elevator.svg.license b/src/timeline/images/elevator.svg.license new file mode 100644 index 000000000..ce29e347b --- /dev/null +++ b/src/timeline/images/elevator.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: https://github.com/gravitystorm/openstreetmap-carto diff --git a/src/timeline/images/escalator.svg b/src/timeline/images/escalator.svg new file mode 100644 index 000000000..f8ca91b6b --- /dev/null +++ b/src/timeline/images/escalator.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/timeline/images/escalator.svg.license b/src/timeline/images/escalator.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/escalator.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/ferry.svg b/src/timeline/images/ferry.svg new file mode 100644 index 000000000..7b7990cb1 --- /dev/null +++ b/src/timeline/images/ferry.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/ferry.svg.license b/src/timeline/images/ferry.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/ferry.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/flight.svg b/src/timeline/images/flight.svg new file mode 100644 index 000000000..86fd874af --- /dev/null +++ b/src/timeline/images/flight.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/timeline/images/flight.svg.license b/src/timeline/images/flight.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/flight.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/foodestablishment.svg b/src/timeline/images/foodestablishment.svg new file mode 100644 index 000000000..ea090c3f5 --- /dev/null +++ b/src/timeline/images/foodestablishment.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/timeline/images/foodestablishment.svg.license b/src/timeline/images/foodestablishment.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/foodestablishment.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/funicular.svg b/src/timeline/images/funicular.svg new file mode 100644 index 000000000..9c83746ba --- /dev/null +++ b/src/timeline/images/funicular.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/funicular.svg.license b/src/timeline/images/funicular.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/funicular.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/longdistancetrain.svg b/src/timeline/images/longdistancetrain.svg new file mode 100644 index 000000000..52b82244b --- /dev/null +++ b/src/timeline/images/longdistancetrain.svg @@ -0,0 +1,15 @@ + + + + + + + diff --git a/src/timeline/images/longdistancetrain.svg.license b/src/timeline/images/longdistancetrain.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/longdistancetrain.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/rapidtransit.svg b/src/timeline/images/rapidtransit.svg new file mode 100644 index 000000000..5a0d3bcf7 --- /dev/null +++ b/src/timeline/images/rapidtransit.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/timeline/images/rapidtransit.svg.license b/src/timeline/images/rapidtransit.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/rapidtransit.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/seat.svg b/src/timeline/images/seat.svg new file mode 100644 index 000000000..91566330c --- /dev/null +++ b/src/timeline/images/seat.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/src/timeline/images/seat.svg.license b/src/timeline/images/seat.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/seat.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/shuttle.svg b/src/timeline/images/shuttle.svg new file mode 100644 index 000000000..9b396b92b --- /dev/null +++ b/src/timeline/images/shuttle.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/shuttle.svg.license b/src/timeline/images/shuttle.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/shuttle.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/sleepingcar.svg b/src/timeline/images/sleepingcar.svg new file mode 100644 index 000000000..9a64cf5f9 --- /dev/null +++ b/src/timeline/images/sleepingcar.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/src/timeline/images/sleepingcar.svg.license b/src/timeline/images/sleepingcar.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/sleepingcar.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/stairs.svg b/src/timeline/images/stairs.svg new file mode 100644 index 000000000..c9e530df4 --- /dev/null +++ b/src/timeline/images/stairs.svg @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/timeline/images/stairs.svg.license b/src/timeline/images/stairs.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/stairs.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/subway.svg b/src/timeline/images/subway.svg new file mode 100644 index 000000000..b0d5f7610 --- /dev/null +++ b/src/timeline/images/subway.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/timeline/images/subway.svg.license b/src/timeline/images/subway.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/subway.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/taxi.svg b/src/timeline/images/taxi.svg new file mode 100644 index 000000000..f500b0adf --- /dev/null +++ b/src/timeline/images/taxi.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/taxi.svg.license b/src/timeline/images/taxi.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/taxi.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/train.svg b/src/timeline/images/train.svg new file mode 100644 index 000000000..3bcbe23f2 --- /dev/null +++ b/src/timeline/images/train.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/timeline/images/train.svg.license b/src/timeline/images/train.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/train.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/tramway.svg b/src/timeline/images/tramway.svg new file mode 100644 index 000000000..1c650dcd1 --- /dev/null +++ b/src/timeline/images/tramway.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/tramway.svg.license b/src/timeline/images/tramway.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/tramway.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/transfer.svg b/src/timeline/images/transfer.svg new file mode 100644 index 000000000..f5761f25e --- /dev/null +++ b/src/timeline/images/transfer.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/transfer.svg.license b/src/timeline/images/transfer.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/transfer.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/wait.svg b/src/timeline/images/wait.svg new file mode 100644 index 000000000..f83700543 --- /dev/null +++ b/src/timeline/images/wait.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/wait.svg.license b/src/timeline/images/wait.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/wait.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause diff --git a/src/timeline/images/walk.svg b/src/timeline/images/walk.svg new file mode 100644 index 000000000..3906dc38a --- /dev/null +++ b/src/timeline/images/walk.svg @@ -0,0 +1,16 @@ + + + + + + + diff --git a/src/timeline/images/walk.svg.license b/src/timeline/images/walk.svg.license new file mode 100644 index 000000000..f3b402b5d --- /dev/null +++ b/src/timeline/images/walk.svg.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: Volker Krause