├── .clang-tidy ├── .codespellrc ├── .codespellrc.license ├── .craft.ini ├── .craftignore ├── .flatpak-manifest.json ├── .flatpak-manifest.json.license ├── .gitignore ├── .gitlab-ci.yml ├── .kateconfig ├── .kde-ci.yml ├── CMakeLists.txt ├── CMakePresets.json ├── CMakePresets.json.license ├── LICENSES ├── Apache-2.0.txt ├── BSD-3-Clause.txt ├── CC0-1.0.txt └── LGPL-2.0-or-later.txt ├── README.md ├── README.md.license ├── REUSE.toml ├── StaticMessages.sh ├── add_license.sh ├── autotests ├── CMakeLists.txt ├── androidicalconvertertest.cpp ├── androidwrappertest.cpp ├── applicationcontrollertest.cpp ├── apptest.py ├── calendarhelpertest.cpp ├── costaccumulatortest.cpp ├── data │ ├── 4U8465-cancel.json │ ├── 4U8465-v1.json │ ├── 4U8465-v2.json │ ├── 524-135-forecast.xml │ ├── 9euroticket.json │ ├── bahncard.json │ ├── boardingpass-v1.pkpass │ ├── boardingpass-v2.pkpass │ ├── bug455083.json │ ├── cost-accumulator │ │ ├── batch-no-resnum-different-prices.json │ │ ├── batch-no-resnum-same-price.json │ │ ├── batch-resnum-same-price.json │ │ ├── mixed-currency.json │ │ └── single-res-num.json │ ├── empty-backup.itinerary │ ├── flight-txl-lhr-sfo.json │ ├── generic-pass.pkpass │ ├── google-multi-passenger-flight.json │ ├── haus-randa-v1.json │ ├── haus-randa-v2.json │ ├── health-certificates │ │ ├── full-vaccination.txt │ │ ├── full-vaccination.txt.license │ │ ├── negative-pcr-test-fr.pdf │ │ ├── negative-pcr-test-fr.pdf.license │ │ ├── partial-vaccination.divoc │ │ └── partial-vaccination.divoc.license │ ├── iata-bcbp-demo.pdf │ ├── iata-bcbp-demo.pdf.license │ ├── livedata │ │ ├── randa2017-leg1-arrival-vehicle-layout.json │ │ ├── randa2017-leg1-full-journey.json │ │ ├── randa2017-leg1-journey.json │ │ └── randa2017-leg1-partial-journey.json │ ├── mixed-reservation-ticket.json │ ├── publictransport │ │ ├── db-wifi-journey.json │ │ ├── randa-zrh-2-sections.json │ │ └── randa-zrh-3-sections.json │ ├── randa2017.ics │ ├── randa2017.itinerary │ ├── timeline │ │ ├── daychange-r0.model │ │ ├── daychange-r1.model │ │ ├── daychange-r2.model │ │ ├── daychange-r3.model │ │ ├── dst-change.json │ │ ├── dst-change.model │ │ ├── event-multi-day.json │ │ ├── event-multi-day.model │ │ ├── event-until-midnight.json │ │ ├── event-until-midnight.model │ │ ├── flight-cancelation.json │ │ ├── flight-cancelation.model │ │ ├── multi-traveler-merge-with-countryinfo.json │ │ ├── multi-traveler-merge-with-countryinfo.model │ │ ├── no-arrival-time.context.json │ │ ├── no-arrival-time.json │ │ ├── no-arrival-time.model │ │ ├── weather-forecast-with-tz-change.context.json │ │ ├── weather-forecast-with-tz-change.json │ │ └── weather-forecast-with-tz-change.model │ ├── transfer │ │ ├── different-home-locations.json │ │ ├── different-home-locations.json.ref │ │ ├── double-round-trip.json │ │ └── double-round-trip.json.ref │ ├── tripgroup │ │ ├── deutschebahn_two-leg-return.txt.json │ │ ├── flight-direct-return.json │ │ ├── iata-bcbp-no-times.json │ │ ├── imbalanced-return-trip.json │ │ ├── leading-appendix.json │ │ ├── symmetric-two-leg-return-flight.json │ │ ├── time-based-layover-detection.json │ │ ├── train-triangular-different-pnr.json │ │ ├── unidirectional-train-trip.json │ │ └── unidirectional-with-events.json │ ├── updateable-boardingpass.pkpass │ ├── weather-no-location-change.json │ └── weather-no-location-change.model ├── documentmanagertest.cpp ├── documentsmodeltest.cpp ├── downloadjobtest.cpp ├── favoritelocationtest.cpp ├── gpxwritertest.cpp ├── healthcertificatemanagertest.cpp ├── importcontrollertest.cpp ├── itinerarytestcase.py ├── jniarraytest.cpp ├── jnimethodtest.cpp ├── jnipropertytest.cpp ├── jnisignaturetest.cpp ├── journeysectionmodeltest.cpp ├── livedatamanagertest.cpp ├── localizertest.cpp ├── locationinformationtest.cpp ├── mocknetworkaccessmanager.cpp ├── mocknetworkaccessmanager.h ├── modelverificationpoint.cpp ├── modelverificationpoint.h ├── onlineimporttest.py ├── onlineticketretrievaltest.cpp ├── passmanagertest.cpp ├── passtest.py ├── pkpassmanagertest.cpp ├── publictransportmatchertest.cpp ├── publictransporttest.cpp ├── reservationmanagertest.cpp ├── reservationtest.py ├── settingstest.py ├── statisticstest.cpp ├── testhelper.h ├── timelinedelegatecontrollertest.cpp ├── timelinemodeltest.cpp ├── timelinesectiondelegatecontrollertest.cpp ├── transfertest.cpp ├── tripgroupcontrollertest.cpp ├── tripgrouplocationmodeltest.cpp ├── tripgroupmodeltest.cpp ├── tripgroupsplitmodeltest.cpp ├── tripgrouptest.cpp ├── tripgrouptest.py └── weathertest.cpp ├── cmake └── FindLibIcal.cmake ├── doc ├── kde-fdroid-nightly-repository-link.png ├── kde-fdroid-nightly-repository-link.png.license ├── kde-fdroid-release-repository-link.png └── kde-fdroid-release-repository-link.png.license ├── fastlane └── metadata │ └── org.kde.itinerary │ └── en-US │ └── images │ ├── featureGraphic.png │ └── featureGraphic.svg ├── flatpak └── 99-noto-color-emoji.conf ├── po ├── ar │ └── kde-itinerary.po ├── ast │ └── kde-itinerary.po ├── ca │ └── kde-itinerary.po ├── ca@valencia │ └── kde-itinerary.po ├── cs │ └── kde-itinerary.po ├── de │ └── kde-itinerary.po ├── en_GB │ └── kde-itinerary.po ├── eo │ └── kde-itinerary.po ├── es │ └── kde-itinerary.po ├── et │ └── kde-itinerary.po ├── eu │ └── kde-itinerary.po ├── fi │ └── kde-itinerary.po ├── fr │ └── kde-itinerary.po ├── gl │ └── kde-itinerary.po ├── he │ └── kde-itinerary.po ├── hi │ └── kde-itinerary.po ├── hu │ └── kde-itinerary.po ├── ia │ └── kde-itinerary.po ├── it │ └── kde-itinerary.po ├── ja │ └── kde-itinerary.po ├── ka │ └── kde-itinerary.po ├── ko │ └── kde-itinerary.po ├── lt │ └── kde-itinerary.po ├── nl │ └── kde-itinerary.po ├── pl │ └── kde-itinerary.po ├── pt │ └── kde-itinerary.po ├── pt_BR │ └── kde-itinerary.po ├── ru │ └── kde-itinerary.po ├── sa │ └── kde-itinerary.po ├── sk │ └── kde-itinerary.po ├── sl │ └── kde-itinerary.po ├── sv │ └── kde-itinerary.po ├── tr │ └── kde-itinerary.po ├── uk │ └── kde-itinerary.po ├── zh_CN │ └── kde-itinerary.po └── zh_TW │ └── kde-itinerary.po ├── readme-build-ftime.txt ├── readme-build-ftime.txt.license ├── snapcraft.yaml ├── src ├── CMakeLists.txt ├── Messages.sh ├── app │ ├── AboutPage.qml │ ├── ActionsCard.qml │ ├── AlternativeJourneyPage.qml │ ├── BarcodeContainer.qml │ ├── BarcodeScanModeButton.qml │ ├── BarcodeScanModeController.qml │ ├── BarcodeScannerPage.qml │ ├── BoardingPass.qml │ ├── BoatDelegate.qml │ ├── BoatEditor.qml │ ├── BoatPage.qml │ ├── BookingCard.qml │ ├── BookingEditorCard.qml │ ├── BusDelegate.qml │ ├── BusEditor.qml │ ├── BusPage.qml │ ├── CMakeLists.txt │ ├── CalendarSelectionSheet.qml │ ├── CarRentalDelegate.qml │ ├── CarRentalPage.qml │ ├── CardPageTitle.qml │ ├── ContactCard.qml │ ├── ContactEditorCard.qml │ ├── CountryComboBoxDelegate.qml │ ├── DepartureQueryPage.qml │ ├── DetailsPage.qml │ ├── DevelopmentModePage.qml │ ├── DocumentsCard.qml │ ├── EditorPage.qml │ ├── EventDelegate.qml │ ├── EventEditor.qml │ ├── EventPage.qml │ ├── EventTicket.qml │ ├── FavoriteLocationPage.qml │ ├── FlightDelegate.qml │ ├── FlightEditor.qml │ ├── FlightPage.qml │ ├── FormDateTimeEditDelegate.qml │ ├── FormPlaceDelegate.qml │ ├── FormPlaceEditorDelegate.qml │ ├── FormPlatformDelegate.qml │ ├── FormPriceDelegate.qml │ ├── FormPriceEditDelegate.qml │ ├── GenericPass.qml │ ├── GenericPkPassPage.qml │ ├── HealthCertificateBarcode.qml │ ├── HealthCertificatePage.qml │ ├── HealthCertificateRecovery.qml │ ├── HealthCertificateTest.qml │ ├── HealthCertificateVaccination.qml │ ├── HotelDelegate.qml │ ├── HotelEditor.qml │ ├── HotelPage.qml │ ├── ImportPage.qml │ ├── IndoorMapGateSheet.qml │ ├── IndoorMapInfoSheet.qml │ ├── IndoorMapPage.qml │ ├── IndoorMapPlatformSheet.qml │ ├── IntermediateStopSelector.qml │ ├── JourneyDelegateHeader.qml │ ├── JourneyPathPage.qml │ ├── JourneyQueryPage.qml │ ├── JourneyRequestPage.qml │ ├── JourneySectionDelegate.qml │ ├── JourneySectionPage.qml │ ├── JourneySectionStopDelegate.qml │ ├── JourneySectionStopDelegateLineSegment.qml │ ├── JourneySummaryDelegate.qml │ ├── LiveStatusPage.qml │ ├── LocationInfoDelegate.qml │ ├── LocationPicker.qml │ ├── Main.qml │ ├── MapCircle.qml │ ├── MapPin.qml │ ├── MapStopoverInfoSheetDrawer.qml │ ├── MapView.qml │ ├── MatrixKeyVerificationPage.qml │ ├── MatrixRoomSelectionSheet.qml │ ├── MyDataPage.qml │ ├── NavigationBar.qml │ ├── OnlineImportPage.qml │ ├── PassDelegate.qml │ ├── PassPage.qml │ ├── PkPassBarcode.qml │ ├── PkPassPage.qml │ ├── ProgramMembershipCard.qml │ ├── ProgramMembershipEditor.qml │ ├── ProgramMembershipEditorCard.qml │ ├── ProgramMembershipPage.qml │ ├── ReservationDocumentsCard.qml │ ├── RestaurantDelegate.qml │ ├── RestaurantEditor.qml │ ├── RestaurantPage.qml │ ├── SeatRowFormCard.qml │ ├── SettingsPage.qml │ ├── SheetDrawer.qml │ ├── StatisticsDelegate.qml │ ├── StatisticsPage.qml │ ├── StopPickerPage.qml │ ├── StopoverFormDelegate.qml │ ├── StopoverInformationSheet.qml │ ├── TicketEditor.qml │ ├── TicketPage.qml │ ├── TicketTokenDelegate.qml │ ├── TicketTokenEditorCard.qml │ ├── TimelineDelegate.qml │ ├── TimelineDelegateArrivalLayout.qml │ ├── TimelineDelegateDepartureLayout.qml │ ├── TimelineDelegateSeatRow.qml │ ├── TimelineDelegateSeatRowLabel.qml │ ├── TimelineSectionDelegate.qml │ ├── TouristAttractionDelegate.qml │ ├── TouristAttractionPage.qml │ ├── TrainDelegate.qml │ ├── TrainEditor.qml │ ├── TrainPage.qml │ ├── TransferDelegate.qml │ ├── TransferPage.qml │ ├── TripGroupEditorDialog.qml │ ├── TripGroupMapPage.qml │ ├── TripGroupMergeDialog.qml │ ├── TripGroupPage.qml │ ├── TripGroupSelectorCard.qml │ ├── TripGroupSplitPage.qml │ ├── TripGroupsPage.qml │ ├── VehicleLayoutPage.qml │ ├── VerticalNavigationButton.qml │ ├── WeatherForecastDelegate.qml │ ├── WeatherForecastPage.qml │ ├── WelcomePage.qml │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── ic_launcher-playstore.png │ │ ├── itineraryactivity.h │ │ ├── res │ │ │ ├── drawable-v24 │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ │ ├── splash.xml │ │ │ │ ├── splash_logo.png │ │ │ │ └── vendor_logo.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ └── ic_launcher.xml │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── resources.properties │ │ │ ├── values-ast │ │ │ │ └── strings.xml │ │ │ ├── values-ca │ │ │ │ └── strings.xml │ │ │ ├── values-cs │ │ │ │ └── strings.xml │ │ │ ├── values-de │ │ │ │ └── strings.xml │ │ │ ├── values-en-rGB │ │ │ │ └── strings.xml │ │ │ ├── values-eo │ │ │ │ └── strings.xml │ │ │ ├── values-es │ │ │ │ └── strings.xml │ │ │ ├── values-eu │ │ │ │ └── strings.xml │ │ │ ├── values-fi │ │ │ │ └── strings.xml │ │ │ ├── values-fr │ │ │ │ └── strings.xml │ │ │ ├── values-gl │ │ │ │ └── strings.xml │ │ │ ├── values-hi │ │ │ │ └── strings.xml │ │ │ ├── values-hu │ │ │ │ └── strings.xml │ │ │ ├── values-ia │ │ │ │ └── strings.xml │ │ │ ├── values-it │ │ │ │ └── strings.xml │ │ │ ├── values-iw │ │ │ │ └── strings.xml │ │ │ ├── values-ja │ │ │ │ └── strings.xml │ │ │ ├── values-ka │ │ │ │ └── strings.xml │ │ │ ├── values-ko │ │ │ │ └── strings.xml │ │ │ ├── values-lt │ │ │ │ └── strings.xml │ │ │ ├── values-nl │ │ │ │ └── strings.xml │ │ │ ├── values-pl │ │ │ │ └── strings.xml │ │ │ ├── values-pt-rBR │ │ │ │ └── strings.xml │ │ │ ├── values-pt │ │ │ │ └── strings.xml │ │ │ ├── values-ru │ │ │ │ └── strings.xml │ │ │ ├── values-sk │ │ │ │ └── strings.xml │ │ │ ├── values-sl │ │ │ │ └── strings.xml │ │ │ ├── values-sv │ │ │ │ └── strings.xml │ │ │ ├── values-tr │ │ │ │ └── strings.xml │ │ │ ├── values-uk │ │ │ │ └── strings.xml │ │ │ ├── values-zh-rCN │ │ │ │ └── strings.xml │ │ │ ├── values-zh-rTW │ │ │ │ └── strings.xml │ │ │ ├── values │ │ │ │ └── strings.xml │ │ │ └── xml │ │ │ │ ├── file_paths.xml │ │ │ │ └── shortcuts.xml │ │ └── src │ │ │ └── org │ │ │ └── kde │ │ │ └── itinerary │ │ │ ├── Activity.java │ │ │ └── QTimeZone.java │ ├── applicationcontroller.cpp │ ├── applicationcontroller.h │ ├── bundle-constants.h │ ├── calendarhelper.cpp │ ├── calendarhelper.h │ ├── clipboard.cpp │ ├── clipboard.h │ ├── config-itinerary.h.cmake │ ├── constants.h │ ├── costaccumulator.cpp │ ├── costaccumulator.h │ ├── countrysubdivisionmodel.cpp │ ├── countrysubdivisionmodel.h │ ├── developmentmodecontroller.cpp │ ├── developmentmodecontroller.h │ ├── documentmanager.cpp │ ├── documentmanager.h │ ├── documentsmodel.cpp │ ├── documentsmodel.h │ ├── downloadjob.cpp │ ├── downloadjob.h │ ├── factory.cpp │ ├── factory.h │ ├── favoritelocationmodel.cpp │ ├── favoritelocationmodel.h │ ├── filehelper.cpp │ ├── filehelper.h │ ├── genericpkpass.cpp │ ├── genericpkpass.h │ ├── gpxexport.cpp │ ├── gpxexport.h │ ├── healthcertificatemanager.cpp │ ├── healthcertificatemanager.h │ ├── images │ │ ├── arrow.svg │ │ ├── arrow.svg.license │ │ └── images.qrc │ ├── importcontroller.cpp │ ├── importcontroller.h │ ├── importexport.cpp │ ├── importexport.h │ ├── intenthandler.cpp │ ├── intenthandler.h │ ├── itinerary.notifyrc │ ├── itinerary.notifyrc.license │ ├── itinerary_version_detailed.h.cmake │ ├── journeysectionmodel.cpp │ ├── journeysectionmodel.h │ ├── json.cpp │ ├── json.h │ ├── jsonio.cpp │ ├── jsonio.h │ ├── kdeconnect.cpp │ ├── kdeconnect.h │ ├── livedata.cpp │ ├── livedata.h │ ├── livedatamanager.cpp │ ├── livedatamanager.h │ ├── localizer.cpp │ ├── localizer.h │ ├── locationhelper.cpp │ ├── locationhelper.h │ ├── locationinformation.cpp │ ├── locationinformation.h │ ├── main.cpp │ ├── mapdownloadmanager.cpp │ ├── mapdownloadmanager.h │ ├── matrixcontroller.cpp │ ├── matrixcontroller.h │ ├── migrator.cpp │ ├── migrator.h │ ├── navigationcontroller.cpp │ ├── navigationcontroller.h │ ├── nominatimimportjob.cpp │ ├── nominatimimportjob.h │ ├── notificationconfigcontroller.cpp │ ├── notificationconfigcontroller.h │ ├── notificationhelper.cpp │ ├── notificationhelper.h │ ├── notifyrc.qrc │ ├── onlineimport │ │ ├── db.qml │ │ └── sncf.qml │ ├── onlineticketimporter.cpp │ ├── onlineticketimporter.h │ ├── onlineticketretrievaljob.cpp │ ├── onlineticketretrievaljob.h │ ├── org.kde.itinerary.appdata.xml │ ├── org.kde.itinerary.desktop │ ├── org.kde.itinerary.desktop.license │ ├── osmimportjob.cpp │ ├── osmimportjob.h │ ├── passmanager.cpp │ ├── passmanager.h │ ├── permissionmanager.cpp │ ├── permissionmanager.h │ ├── pkpassimageprovider.cpp │ ├── pkpassimageprovider.h │ ├── pkpassmanager.cpp │ ├── pkpassmanager.h │ ├── publictransport.cpp │ ├── publictransport.h │ ├── publictransportmatcher.cpp │ ├── publictransportmatcher.h │ ├── reservationhelper.cpp │ ├── reservationhelper.h │ ├── reservationmanager.cpp │ ├── reservationmanager.h │ ├── sc-apps-org.kde.itinerary.svg │ ├── sc-apps-org.kde.itinerary.svg.license │ ├── settings.cpp │ ├── settings.h │ ├── statisticsmodel.cpp │ ├── statisticsmodel.h │ ├── statisticstimerangemodel.cpp │ ├── statisticstimerangemodel.h │ ├── tickettokenmodel.cpp │ ├── tickettokenmodel.h │ ├── timelinedelegatecontroller.cpp │ ├── timelinedelegatecontroller.h │ ├── timelineelement.cpp │ ├── timelineelement.h │ ├── timelinemodel.cpp │ ├── timelinemodel.h │ ├── timelinesectiondelegatecontroller.cpp │ ├── timelinesectiondelegatecontroller.h │ ├── traewellingcontroller.cpp │ ├── traewellingcontroller.h │ ├── transfer.cpp │ ├── transfer.h │ ├── transferdelegatecontroller.cpp │ ├── transferdelegatecontroller.h │ ├── transfermanager.cpp │ ├── transfermanager.h │ ├── tripgroup.cpp │ ├── tripgroup.h │ ├── tripgroupcontroller.cpp │ ├── tripgroupcontroller.h │ ├── tripgroupfilterproxymodel.cpp │ ├── tripgroupfilterproxymodel.h │ ├── tripgrouplocationmodel.cpp │ ├── tripgrouplocationmodel.h │ ├── tripgroupmanager.cpp │ ├── tripgroupmanager.h │ ├── tripgroupmapmodel.cpp │ ├── tripgroupmapmodel.h │ ├── tripgroupmodel.cpp │ ├── tripgroupmodel.h │ ├── tripgroupsplitmodel.cpp │ ├── tripgroupsplitmodel.h │ ├── unitconversion.cpp │ ├── unitconversion.h │ ├── util.cpp │ ├── util.h │ ├── weatherforecastmodel.cpp │ ├── weatherforecastmodel.h │ ├── weatherinformation.cpp │ └── weatherinformation.h ├── calendarextras │ ├── CMakeLists.txt │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ ├── KCalendarCoreExtras-android-dependencies.xml │ │ ├── build.gradle │ │ ├── calendar.h │ │ ├── calendardata.h │ │ ├── calendarplugin.h │ │ ├── eventdata.h │ │ └── org │ │ │ └── kde │ │ │ └── kcalendarcore │ │ │ ├── AttendeeData.java │ │ │ ├── Calendar.java │ │ │ ├── CalendarData.java │ │ │ ├── CalendarPlugin.java │ │ │ ├── EventData.java │ │ │ ├── ExtendedPropertyData.java │ │ │ └── ReminderData.java │ ├── androidcalendar.cpp │ ├── androidcalendar.h │ ├── androidcalendarplugin.cpp │ ├── androidcalendarplugin.h │ ├── androidicalconverter.cpp │ ├── androidicalconverter.h │ ├── incidencekey_p.h │ └── integration.cpp ├── gpx │ ├── CMakeLists.txt │ ├── gpxreader.cpp │ ├── gpxreader.h │ ├── gpxwriter.cpp │ └── gpxwriter.h ├── kandroidextras │ ├── CMakeLists.txt │ ├── README.md │ ├── README.md.license │ ├── android │ │ ├── activity.cpp │ │ ├── activity.h │ │ ├── android_headers.cpp │ │ ├── androidtypes.h │ │ ├── calendarcontract.h │ │ ├── contentresolver.cpp │ │ ├── contentresolver.h │ │ ├── context.cpp │ │ ├── context.h │ │ ├── intent.cpp │ │ ├── intent.h │ │ ├── manifestpermission.h │ │ ├── openablecolumns.h │ │ ├── settings.h │ │ ├── uri.cpp │ │ └── uri.h │ ├── fake │ │ ├── jni.h │ │ ├── mock_impl.cpp │ │ ├── mock_jnienvironment.h │ │ ├── mock_jniobject.cpp │ │ ├── mock_jniobject.h │ │ └── qt6 │ │ │ ├── QCoreApplication │ │ │ ├── QJniEnvironment │ │ │ ├── QJniObject │ │ │ ├── private │ │ │ └── qandroidextras_p.h │ │ │ └── qjniobject.h │ ├── java │ │ ├── java_headers.cpp │ │ ├── javalocale.cpp │ │ ├── javalocale.h │ │ └── javatypes.h │ └── jni │ │ ├── jni_headers.cpp │ │ ├── jniargument.h │ │ ├── jniarray.h │ │ ├── jnimethod.h │ │ ├── jniobject.h │ │ ├── jnipp.h │ │ ├── jniprimitivetypes.h │ │ ├── jniproperty.h │ │ ├── jnireturnvalue.h │ │ ├── jnisignature.h │ │ ├── jnitypes.h │ │ └── jnitypetraits.h ├── matrix │ ├── CMakeLists.txt │ ├── matrixbeacon.cpp │ ├── matrixbeacon.h │ ├── matrixmanager.cpp │ ├── matrixmanager.h │ ├── matrixroomsmodel.cpp │ ├── matrixroomsmodel.h │ ├── matrixroomssortproxymodel.cpp │ └── matrixroomssortproxymodel.h ├── metadataextractor │ ├── CMakeLists.txt │ ├── itineraryextractor.cpp │ ├── itineraryextractor.h │ ├── itineraryextractor.json │ └── itineraryextractor.json.license ├── solidextras │ ├── CMakeLists.txt │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ ├── SolidExtras-android-dependencies.xml │ │ ├── build.gradle │ │ └── org │ │ │ └── kde │ │ │ └── solidextras │ │ │ └── Solid.java │ ├── androidbrightnessbackend.cpp │ ├── androidbrightnessbackend.h │ ├── androidlockbackend.cpp │ ├── androidlockbackend.h │ ├── brightnessmanager.cpp │ ├── brightnessmanager.h │ ├── freedesktoplockbackend.cpp │ ├── freedesktoplockbackend.h │ ├── lockmanager.cpp │ ├── lockmanager.h │ ├── org.freedesktop.ScreenSaver.xml │ ├── org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml │ ├── qml │ │ ├── CMakeLists.txt │ │ ├── qmldir │ │ ├── qmldir.license │ │ └── solidextrasqmlplugin.cpp │ ├── solidbrightnessbackend.cpp │ └── solidbrightnessbackend.h ├── thumbnailer │ ├── CMakeLists.txt │ ├── itinerarycreator.cpp │ ├── itinerarycreator.h │ ├── itinerarythumbnail.json │ └── itinerarythumbnail.json.license ├── tools │ └── db-online-ticket-dump.py └── weather │ ├── CMakeLists.txt │ ├── weatherforecast.cpp │ ├── weatherforecast.h │ ├── weatherforecastmanager.cpp │ ├── weatherforecastmanager.h │ └── weathertile.h ├── tests ├── CMakeLists.txt ├── akademy2017.json ├── akademy2018-program.json ├── demo-settings.itinerary ├── demo-settings.itinerary.license ├── journeyquerytest.cpp ├── journeyquerytest.qml ├── journeyquerytest.qrc ├── osnabrueck2021.json ├── pkpassviewer.cpp ├── pkpassviewer.qml ├── pkpassviewer.qrc ├── randa2017-flight-cancellation.json ├── randa2017.json ├── sbb-vehicle-layout.json ├── seat-row-test.qml ├── vehiclelayoutviewer.cpp ├── vehiclelayoutviewer.qml └── vehiclelayoutviewer.qrc └── tox.ini /.clang-tidy: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: none 3 | 4 | --- 5 | Checks: > 6 | clang-diagnostic-*, 7 | -clang-diagnostic-gnu-zero-variadic-macro-arguments, 8 | -clang-diagnostic-unknown-warning-option, 9 | clang-analyzer-*, 10 | bugprone-*, 11 | -bugprone-easily-swappable-parameters, 12 | -bugprone-suspicious-include, 13 | misc-*, 14 | -misc-no-recursion, 15 | -misc-use-anonymous-namespace, 16 | modernize-*, 17 | -modernize-avoid-c-arrays, 18 | -modernize-concat-nested-namespaces, 19 | -modernize-use-trailing-return-type, 20 | performance-*, 21 | readability-*, 22 | -readability-function-cognitive-complexity, 23 | -readability-identifier-length, 24 | -readability-implicit-bool-conversion, 25 | -readability-isolate-declaration, 26 | -readability-magic-numbers, 27 | -readability-named-parameter, 28 | -readability-qualified-auto, 29 | -readability-suspicious-call-argument, 30 | -readability-uppercase-literal-suffix 31 | 32 | FormatStyle: none 33 | CheckOptions: 34 | - key: readability-implicit-bool-conversion.AllowIntegerConditions 35 | value: '1' 36 | - key: readability-implicit-bool-conversion.AllowPointerConditions 37 | value: '1' 38 | - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic 39 | value: '1' 40 | - key: modernize-use-override.IgnoreDestructors 41 | value: '1' 42 | ... 43 | -------------------------------------------------------------------------------- /.codespellrc: -------------------------------------------------------------------------------- 1 | [codespell] 2 | skip = ./build*,.git,./po*,*.notifyrc,*.desktop,*.json,*.xml 3 | interactive = 3 4 | ignore-words-list = accessort 5 | -------------------------------------------------------------------------------- /.codespellrc.license: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022-2023 Laurent Montel 2 | # SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /.craft.ini: -------------------------------------------------------------------------------- 1 | ; SPDX-FileCopyrightText: None 2 | ; SPDX-License-Identifier: CC0-1.0 3 | 4 | [BlueprintSettings] 5 | kde/pim.version=master 6 | kde/libs.version=master 7 | libs/qt.qtMajorVersion=6 8 | 9 | ; stripped-down/size-optimized Poppler, KArchive and libxml2 for our needs 10 | data/urw-base35-fonts.ignored=True 11 | data/poppler-data.ignored=True 12 | libs/libarchive.ignored=True 13 | libs/libbzip2.ignored=True 14 | libs/liblzma.ignored=True 15 | libs/libcurl.ignored=True 16 | libs/lcms2.ignored=True 17 | libs/gpgme.ignored=True 18 | libs/nss.ignored=True 19 | libs/tiff.ignored=True 20 | libs/boost.ignored=True 21 | 22 | qt-libs/poppler.buildCppFrontend=False 23 | qt-libs/poppler.buildQtFrontend=False 24 | 25 | libs/freetype.patchLevel=1 26 | libs/libxml2.patchLevel=1 27 | qt-libs/poppler.patchLevel=1 28 | kde/frameworks/tier1/karchive.patchLevel=1 29 | -------------------------------------------------------------------------------- /.craftignore: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: 2023 Volker Krause 3 | 4 | # we use the Breeze style, so anything related to Material or Fluent is unnecessary 5 | qml/QtQuick/Controls/(FluentWinUI3|Material)/.* 6 | lib/qml/org/kde/kirigami/styles/Material/.* 7 | 8 | # data files for ki18n that we don't need 9 | share/iso-codes/json/schema-.* 10 | share/iso-codes/json/iso_(15924|3166-3|4217|639-\d)\.json 11 | share/locale/.*/LC_MESSAGES/iso_(15924|3166-3|4217|639-\d)\.mo 12 | 13 | # other KF6 data files we don't need 14 | share/mime/packages/kde6\.xml 15 | 16 | # unused Kirigami Addons modules 17 | lib/qml/org/kde/kirigamiaddons/(settings|sounds|treeview)/.* 18 | 19 | # unused image formats 20 | plugins/imageformats/.*_qico_.*\.so 21 | 22 | # translation catalogs of dependencies not needed here 23 | share/locale/.*/LC_MESSAGES/(karchive6|kcodecs6|kconfig6|knotifications6|libkmime6)_qt\.qm 24 | share/locale/.*/LC_MESSAGES/(kcontacts6|kcolorscheme6|kiconthemes6)\.mo 25 | share/qt6keychain/translations.*\.qm 26 | 27 | # newer Kirigami Addon versions depend on Qt.labs.platform for ColorDialog, which as a QtWidgets dependency 28 | # remove that the hard way, we don't need a color dialog 29 | qml/Qt/labs/platform/.* 30 | 31 | # unused KConfigWidgets assets pulled in via KIconThemes 32 | share/locale/.*/kf6_entry.desktop 33 | share/locale/.*/LC_MESSAGES/kconfigwidgets6\.mo 34 | share/locale/.*/LC_MESSAGES/(kitemviews6|kwidgetsaddons6)_qt\.qm 35 | 36 | # unused Qt translation catalogs 37 | translations/(qtconnectivity|qtdeclarative|qtlocation|qtmultimedia|qtwebsockets)_.*\.qm 38 | -------------------------------------------------------------------------------- /.flatpak-manifest.json.license: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: None 2 | # SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: none 3 | 4 | *.kdev4 5 | *~ 6 | *.rej 7 | *.orig 8 | *.out 9 | CMakeLists.txt.user 10 | callgrind.* 11 | heaptrack.* 12 | *.qmlc 13 | *.fail 14 | /build* 15 | /.clang-format 16 | /compile_commands.json 17 | .clangd 18 | .cache 19 | .idea 20 | /cmake-build* 21 | .flatpak-builder 22 | /.vscode/ 23 | *.pyc 24 | __pycache__ 25 | .qmlls.ini 26 | .qtcreator/ 27 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: None 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | include: 5 | - project: sysadmin/ci-utilities 6 | file: 7 | - /gitlab-templates/linux-qt6.yml 8 | - /gitlab-templates/linux-qt6-next.yml 9 | - /gitlab-templates/json-validation.yml 10 | - /gitlab-templates/freebsd-qt6.yml 11 | - /gitlab-templates/android-qt6.yml 12 | - /gitlab-templates/reuse-lint.yml 13 | - /gitlab-templates/flatpak.yml 14 | - /gitlab-templates/craft-android-qt6-apks.yml 15 | - /gitlab-templates/craft-android-qt6-googleplay-apks.yml 16 | - /gitlab-templates/cppcheck.yml 17 | -------------------------------------------------------------------------------- /.kateconfig: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | // SPDX-FileCopyrightText: none 3 | // kate: space-indent on; indent-width 4; remove-trailing-spaces modified; 4 | -------------------------------------------------------------------------------- /CMakePresets.json.license: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2021-2022 Laurent Montel 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | -------------------------------------------------------------------------------- /LICENSES/BSD-3-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors 14 | may be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 26 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2018 Volker Krause 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /StaticMessages.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # SPDX-FileCopyrightText: 2021 Volker Krause 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | # The name of catalog we create (without the.pot extension) 6 | # Required by scripty 7 | FILENAME="kde-itinerary-android" 8 | 9 | # relative path to the Android resource folder 10 | ANDROID_RES_DIR="src/app/android/res" 11 | 12 | # Called by scripty for message extraction 13 | # First parameter will be the path of the pot file we have to create, includes $FILENAME 14 | function export_pot_file 15 | { 16 | mkdir outdir 17 | ANSI_COLORS_DISABLED=1 a2po export --android $ANDROID_RES_DIR --gettext outdir 18 | mv outdir/template.pot $1 19 | rm -rf outdir 20 | rm -f rc.cpp 21 | } 22 | 23 | # Called by scripty for merging messages 24 | # First parameter will be a path that will contain several .po files with the format LANG.po 25 | function import_po_files 26 | { 27 | podir=$1 28 | # Android doesn't support languages with an @ 29 | find "$podir" -type f -name "*@*.po" -delete 30 | # drop obsolete messages, as Babel cannot parse them -- see: 31 | # https://github.com/python-babel/babel/issues/206 32 | # https://github.com/python-babel/babel/issues/566 33 | find "$podir" -name '*.po' -exec msgattrib --no-obsolete -o {} {} \; 34 | ANSI_COLORS_DISABLED=1 a2po import --ignore-fuzzy --android $ANDROID_RES_DIR --gettext $podir 35 | } 36 | -------------------------------------------------------------------------------- /add_license.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | find "$@" -name '*.h*' -o -name '*.cpp' -o -name '*.qml' -o -name '*.java'| grep -v /3rdparty/ | while read FILE; do 4 | if grep -qiE "SPDX" "$FILE"; then continue; fi 5 | if grep -qiE "Copyright " "$FILE" ; then continue; fi 6 | thisfile=`basename $FILE` 7 | authorName=`git config user.name` 8 | authorEmail=`git config user.email` 9 | thisYear=`date +%Y` 10 | cat < "$FILE".tmp 11 | /* 12 | SPDX-FileCopyrightText: $thisYear $authorName <$authorEmail> 13 | 14 | SPDX-License-Identifier: LGPL-2.0-or-later 15 | */ 16 | 17 | EOF 18 | cat "$FILE" >> "$FILE".tmp 19 | mv "$FILE".tmp "$FILE" 20 | done 21 | -------------------------------------------------------------------------------- /autotests/data/4U8465-cancel.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "FlightReservation", 5 | "modifiedTime": "2017-04-18T00:00:00Z", 6 | "reservationNumber": "XXX007", 7 | "reservationStatus": "http://schema.org/ReservationCancelled", 8 | "underName": { 9 | "@type": "Person", 10 | "name": "KRAUSE/VOLKER" 11 | } 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /autotests/data/4U8465-v2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "FlightReservation", 5 | "airplaneSeat": "17C", 6 | "reservationFor": { 7 | "@type": "Flight", 8 | "airline": { 9 | "@type": "Airline", 10 | "iataCode": "4U", 11 | "name": "Germanwings" 12 | }, 13 | "arrivalAirport": { 14 | "@type": "Airport", 15 | "geo": { 16 | "@type": "GeoCoordinates", 17 | "latitude": 52.55970001220703, 18 | "longitude": 13.287799835205078 19 | }, 20 | "iataCode": "TXL", 21 | "name": "Berlin-Tegel" 22 | }, 23 | "departureTime": { 24 | "@type": "QDateTime", 25 | "@value": "2017-06-18T19:10:00+01:00", 26 | "timezone": "Europe/London" 27 | }, 28 | "departureAirport": { 29 | "@type": "Airport", 30 | "geo": { 31 | "@type": "GeoCoordinates", 32 | "latitude": 51.477500915527344, 33 | "longitude": -0.4613890051841736 34 | }, 35 | "iataCode": "LHR", 36 | "name": "London Heathrow" 37 | }, 38 | "departureGate": "42", 39 | "flightNumber": "8465" 40 | }, 41 | "reservationNumber": "XXX007" 42 | } 43 | ] 44 | -------------------------------------------------------------------------------- /autotests/data/9euroticket.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "http://schema.org", 3 | "@type": "Ticket", 4 | "issuedBy": { 5 | "@type": "Organization", 6 | "identifier": "uic:0080" 7 | }, 8 | "name": "9-Euro-Ticket", 9 | "ticketNumber": "XXX007", 10 | "ticketToken": "aztec:", 11 | "ticketedSeat": { 12 | "@type": "Seat", 13 | "seatingType": "2" 14 | }, 15 | "underName": { 16 | "@type": "Person", 17 | "name": "Dr Konqui" 18 | }, 19 | "validFrom": "2022-05-01T00:00:00", 20 | "validUntil": "2022-05-31T23:59:59" 21 | } 22 | -------------------------------------------------------------------------------- /autotests/data/bahncard.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "http://schema.org", 3 | "@type": "ProgramMembership", 4 | "member": { 5 | "@type": "Person", 6 | "familyName": "Dragon", 7 | "givenName": "Konqi" 8 | }, 9 | "membershipNumber": "7081123456789012", 10 | "programName": "BahnCard 25 (2. Kl.) (BC25)", 11 | "token": "aztec:dummy_barcode", 12 | "validFrom": "2021-03-25T00:00:00", 13 | "validUntil": "2122-03-24T23:59:59" 14 | } 15 | -------------------------------------------------------------------------------- /autotests/data/boardingpass-v1.pkpass: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/boardingpass-v1.pkpass -------------------------------------------------------------------------------- /autotests/data/boardingpass-v2.pkpass: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/boardingpass-v2.pkpass -------------------------------------------------------------------------------- /autotests/data/bug455083.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "FlightReservation", 5 | "reservationNumber": "XXX007", 6 | "reservationStatus": "http://schema.org/Confirmed", 7 | "reservationFor": { 8 | "@type": "Flight", 9 | "flightNumber": "1234", 10 | "departureAirport": { 11 | "@type": "Airport", 12 | "iataCode": "STR" 13 | }, 14 | "departureTime": "2022-03-04T11:00:00-05:00", 15 | "arrivalAirport": { 16 | "@type": "Airport", 17 | "iataCode": "MUC" 18 | }, 19 | "arrivalTime": "2022-03-05T13:25:00-06:00" 20 | } 21 | }, 22 | { 23 | "@context": "http://schema.org", 24 | "@type": "LodgingReservation", 25 | "checkinDate": "2022-06-13T15:00:00+02:00", 26 | "checkoutDate": "2022-06-17T10:00:00+02:00", 27 | "reservationFor": { 28 | "@type": "LodgingBusiness", 29 | "address": { 30 | "@type": "PostalAddress", 31 | "addressCountry": "DE", 32 | "addressLocality": "Berlin", 33 | "addressRegion": "BE", 34 | "postalCode": "10553" 35 | }, 36 | "name": "Some Hotel" 37 | } 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /autotests/data/empty-backup.itinerary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/empty-backup.itinerary -------------------------------------------------------------------------------- /autotests/data/generic-pass.pkpass: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/generic-pass.pkpass -------------------------------------------------------------------------------- /autotests/data/haus-randa-v1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "LodgingReservation", 5 | "checkinDate": "2017-09-10T15:00:00+02:00", 6 | "checkoutDate": "2017-09-15T10:00:00+02:00", 7 | "reservationFor": { 8 | "@type": "LodgingBusiness", 9 | "address": { 10 | "@type": "PostalAddress", 11 | "addressCountry": "Switzerland", 12 | "addressLocality": "Randa", 13 | "addressRegion": "Wallis", 14 | "postalCode": "3928", 15 | "streetAddress": "Haus Maria am Weg" 16 | }, 17 | "name": "Haus Randa", 18 | "url": "https://randa-meetings.ch/" 19 | } 20 | } 21 | ] 22 | -------------------------------------------------------------------------------- /autotests/data/haus-randa-v2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "LodgingReservation", 5 | "checkinDate": "2017-09-10T15:00:00+02:00", 6 | "checkoutDate": "2017-09-16T10:00:00+02:00", 7 | "reservationFor": { 8 | "@type": "LodgingBusiness", 9 | "address": { 10 | "@type": "PostalAddress", 11 | "addressCountry": "Switzerland", 12 | "addressLocality": "Randa", 13 | "addressRegion": "Wallis", 14 | "postalCode": "3928", 15 | "streetAddress": "Haus Maria am Weg" 16 | }, 17 | "name": "Haus Randa", 18 | "url": "https://randa-meetings.ch/" 19 | } 20 | } 21 | ] 22 | 23 | -------------------------------------------------------------------------------- /autotests/data/health-certificates/full-vaccination.txt: -------------------------------------------------------------------------------- 1 | HC1:6BF+70790T9WJWG.FKY*4GO0.O1CV2 O5 N2FBBRW1*70HS8WY04AC*WIFN0AHCD8KD97TK0F90KECTHGWJC0FDC:5AIA%G7X+AQB9746HS80:54IBQF60R6$A80X6S1BTYACG6M+9XG8KIAWNA91AY%67092L4WJCT3EHS8XJC$+DXJCCWENF6OF63W5NW6WF6%JC QE/IAYJC5LEW34U3ET7DXC9 QE-ED8%E.JCBECB1A-:8$96646AL60A60S6Q$D.UDRYA 96NF6L/5QW6307KQEPD09WEQDD+Q6TW6FA7C466KCN9E%961A6DL6FA7D46JPCT3E5JDLA7$Q6E464W5TG6..DX%DZJC6/DTZ9 QE5$CB$DA/D JC1/D3Z8WED1ECW.CCWE.Y92OAGY8MY9L+9MPCG/D5 C5IA5N9$PC5$CUZCY$5Y$527B+A4KZNQG5TKOWWD9FL%I8U$F7O2IBM85CWOC%LEZU4R/BXHDAHN 11$CA5MRI:AONFN7091K9FKIGIY%VWSSSU9%01FO2*FTPQ3C3F -------------------------------------------------------------------------------- /autotests/data/health-certificates/full-vaccination.txt.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: https://github.com/eu-digital-green-certificates/dgc-testdata 2 | SPDX-License-Identifier: Apache-2.0 3 | -------------------------------------------------------------------------------- /autotests/data/health-certificates/negative-pcr-test-fr.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/health-certificates/negative-pcr-test-fr.pdf -------------------------------------------------------------------------------- /autotests/data/health-certificates/negative-pcr-test-fr.pdf.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: https://github.com/eu-digital-green-certificates/dgc-testdata 2 | SPDX-License-Identifier: Apache-2.0 3 | -------------------------------------------------------------------------------- /autotests/data/health-certificates/partial-vaccination.divoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/health-certificates/partial-vaccination.divoc -------------------------------------------------------------------------------- /autotests/data/health-certificates/partial-vaccination.divoc.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2021 Volker Krause 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /autotests/data/iata-bcbp-demo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/iata-bcbp-demo.pdf -------------------------------------------------------------------------------- /autotests/data/iata-bcbp-demo.pdf.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: none 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /autotests/data/livedata/randa2017-leg1-journey.json: -------------------------------------------------------------------------------- 1 | { 2 | "disruptionEffect": "NormalService", 3 | "expectedArrivalTime": "2017-09-10T14:04:00+02:00", 4 | "expectedArrivalPlatform": "6", 5 | "from": { 6 | "identifier": { 7 | "ibnr": "8503016" 8 | }, 9 | "country": "CH", 10 | "latitude": 47.45029830932617, 11 | "longitude": 8.562219619750977, 12 | "name": "Zürich Flughafen", 13 | "type": "Stop" 14 | }, 15 | "mode": "PublicTransport", 16 | "route": { 17 | "line": { 18 | "mode": "LongDistanceTrain", 19 | "name": "IC 816" 20 | } 21 | }, 22 | "scheduledArrivalTime": "2017-09-10T14:02:00+02:00", 23 | "scheduledArrivalPlatform": "7", 24 | "scheduledDepartureTime": "2017-09-10T11:40:00+02:00", 25 | "scheduledDeparturePlatform": "3", 26 | "to": { 27 | "identifier": { 28 | "ibnr": "8501605" 29 | }, 30 | "latitude": 46.29399871826172, 31 | "locality": "Visp", 32 | "longitude": 7.881460189819336, 33 | "name": "Visp" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /autotests/data/mixed-reservation-ticket.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "Ticket", 5 | "name": "VVT: Einzel-Ticket", 6 | "ticketNumber": "123456", 7 | "ticketToken": "aztec:ticket_token1", 8 | "validFrom": "2022-02-20T11:00:00Z", 9 | "validUntil": "2022-02-20T16:00:00Z" 10 | }, 11 | { 12 | "@context": "http://schema.org", 13 | "@type": "TrainReservation", 14 | "reservationFor": { 15 | "@type": "TrainTrip", 16 | "arrivalStation": { 17 | "@type": "TrainStation", 18 | "name": "MUENCHEN HBF" 19 | }, 20 | "departureDay": "2022-02-20", 21 | "departureStation": { 22 | "@type": "TrainStation", 23 | "name": "WIEN HBF" 24 | } 25 | }, 26 | "reservationNumber": "YYY008", 27 | "reservationStatus": "http://schema.org/ReservationConfirmed", 28 | "reservedTicket": { 29 | "@type": "Ticket", 30 | "ticketToken": "aztec:ticket_token2" 31 | } 32 | } 33 | ] 34 | -------------------------------------------------------------------------------- /autotests/data/randa2017.itinerary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/randa2017.itinerary -------------------------------------------------------------------------------- /autotests/data/timeline/event-multi-day.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "Event", 5 | "endDate": { 6 | "@type": "QDateTime", 7 | "@value": "2023-07-21T17:00:00+03:00", 8 | "timezone": "Europe/Athens" 9 | }, 10 | "location": { 11 | "@type": "Place", 12 | "address": { 13 | "@type": "PostalAddress", 14 | "addressCountry": "GR", 15 | "addressLocality": "Θεσσαλονίκη", 16 | "postalCode": "546 36", 17 | "streetAddress": "Εγνατία 156" 18 | }, 19 | "geo": { 20 | "@type": "GeoCoordinates", 21 | "latitude": 40.625431060791016, 22 | "longitude": 22.96036720275879 23 | }, 24 | "name": "University of Macedonia" 25 | }, 26 | "name": "KDE Akademy 2023", 27 | "startDate": { 28 | "@type": "QDateTime", 29 | "@value": "2023-07-15T09:00:00+03:00", 30 | "timezone": "Europe/Athens" 31 | } 32 | } 33 | ] 34 | -------------------------------------------------------------------------------- /autotests/data/timeline/event-until-midnight.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "Event", 5 | "endDate": { 6 | "@type": "QDateTime", 7 | "@value": "2023-07-15T00:00:00+03:00", 8 | "timezone": "Europe/Athens" 9 | }, 10 | "location": { 11 | "@type": "Place", 12 | "address": { 13 | "@type": "PostalAddress", 14 | "addressCountry": "GR", 15 | "addressLocality": "Θεσσαλονίκη", 16 | "postalCode": "546 38", 17 | "streetAddress": "Λεωφόρος Κωνσταντίνου Καραμανλή 21" 18 | }, 19 | "geo": { 20 | "@type": "GeoCoordinates", 21 | "latitude": 40.620174407958984, 22 | "longitude": 22.9627742767334 23 | }, 24 | "name": "Μπομπονέλλα" 25 | }, 26 | "name": "KDE Akademy 2023 Welcome Event", 27 | "startDate": { 28 | "@type": "QDateTime", 29 | "@value": "2023-07-14T20:00:00+03:00", 30 | "timezone": "Europe/Athens" 31 | }, 32 | "url": "https://akademy.kde.org/2023/welcomeevent/" 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /autotests/data/timeline/flight-cancelation.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "internal-comment": "sample from https://developers.google.com/gmail/markup/reference/flight-reservation#cancel_a_flight", 3 | "@context": "http://schema.org", 4 | "@type": "FlightReservation", 5 | "reservationNumber": "RXJ34P", 6 | "reservationStatus": "http://schema.org/Cancelled", 7 | "underName": { 8 | "@type": "Person", 9 | "name": "Eva Green" 10 | }, 11 | "reservationFor": { 12 | "@type": "Flight", 13 | "flightNumber": "110", 14 | "airline": { 15 | "@type": "Airline", 16 | "name": "United", 17 | "iataCode": "UA" 18 | }, 19 | "departureAirport": { 20 | "@type": "Airport", 21 | "name": "San Francisco Airport", 22 | "iataCode": "SFO" 23 | }, 24 | "departureTime": "1996-10-16T20:15:00-07:00", 25 | "arrivalAirport": { 26 | "@type": "Airport", 27 | "name": "John F. Kennedy International Airport", 28 | "iataCode": "JFK" 29 | }, 30 | "arrivalTime": "1996-10-16T06:30:00-04:00" 31 | }, 32 | "checkinUrl": "http://united.com/onlinecheckin.html", 33 | "modifiedTime": "1996-05-01T08:30:00-08:00", 34 | "modifyReservationUrl": "http://united.com/modifyreservation.html" 35 | }] 36 | -------------------------------------------------------------------------------- /autotests/data/timeline/no-arrival-time.context.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "@context": "http://schema.org", 3 | "@type": "FlightReservation", 4 | "modifiedTime": "1996-06-01T08:30:00-08:00", 5 | "reservationFor": { 6 | "@type": "Flight", 7 | "airline": { 8 | "@type": "Airline", 9 | "iataCode": "AB" 10 | }, 11 | "arrivalAirport": { 12 | "@type": "Airport", 13 | "iataCode": "PDL" 14 | }, 15 | "arrivalTime": { 16 | "@type": "QDateTime", 17 | "@value": "2023-01-01T12:30:00+00:00", 18 | "timezone": "Atlantic/Azores" 19 | }, 20 | "departureAirport": { 21 | "@type": "Airport", 22 | "iataCode": "BER" 23 | }, 24 | "departureTime": { 25 | "@type": "QDateTime", 26 | "@value": "2023-01-01T08:30:00+00:00", 27 | "timezone": "Europe/Berlin" 28 | }, 29 | "departureDay": "2023-01-01", 30 | "flightNumber": "9876" 31 | }, 32 | "reservationNumber": "ABC123", 33 | "reservationStatus": "http://schema.org/ReservationConfirmed" 34 | }] 35 | -------------------------------------------------------------------------------- /autotests/data/timeline/no-arrival-time.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "FlightReservation", 5 | "modifiedTime": "1996-06-01T08:30:00-08:00", 6 | "reservationFor": { 7 | "@type": "Flight", 8 | "airline": { 9 | "@type": "Airline", 10 | "iataCode": "AB" 11 | }, 12 | "arrivalAirport": { 13 | "@type": "Airport", 14 | "iataCode": "LIS", 15 | "name": "LISBON AIRPORT" 16 | }, 17 | "departureAirport": { 18 | "@type": "Airport", 19 | "iataCode": "PDL" 20 | }, 21 | "departureDay": "2023-06-27", 22 | "departureTime": { 23 | "@type": "QDateTime", 24 | "@value": "2023-06-27T15:15:00+00:00", 25 | "timezone": "Atlantic/Azores" 26 | }, 27 | "flightNumber": "123" 28 | }, 29 | "reservationNumber": "XXX007", 30 | "reservationStatus": "http://schema.org/ReservationConfirmed" 31 | }, 32 | { 33 | "@context": "http://schema.org", 34 | "@type": "LodgingReservation", 35 | "modifiedTime": "1996-06-01T08:30:00-08:00", 36 | "checkinTime": "2023-06-27T15:00:00", 37 | "checkoutTime": "2023-06-28T11:00:00", 38 | "reservationFor": { 39 | "@type": "LodgingBusiness", 40 | "address": { 41 | "@type": "PostalAddress", 42 | "addressCountry": "PT", 43 | "addressLocality": "Lissabon" 44 | }, 45 | "name": "A Hotel" 46 | }, 47 | "reservationStatus": "http://schema.org/ReservationConfirmed" 48 | }] 49 | -------------------------------------------------------------------------------- /autotests/data/timeline/weather-forecast-with-tz-change.context.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "FlightReservation", 5 | "modifiedTime": "2020-01-22T00:00:00", 6 | "reservationFor": { 7 | "@type": "Flight", 8 | "airline": { 9 | "@type": "Airline", 10 | "iataCode": "XY" 11 | }, 12 | "arrivalAirport": { 13 | "@type": "Airport", 14 | "iataCode": "TXL", 15 | "name": "Tegel" 16 | }, 17 | "arrivalTime": { 18 | "@type": "QDateTime", 19 | "@value": "1995-10-17T18:35:00+01:00", 20 | "timezone": "Europe/Berlin" 21 | }, 22 | "departureAirport": { 23 | "@type": "Airport", 24 | "iataCode": "FRA" 25 | }, 26 | "departureDay": "1995-10-17", 27 | "departureTime": { 28 | "@type": "QDateTime", 29 | "@value": "1995-10-17T17:35:00+01:00", 30 | "timezone": "Europe/Berlin" 31 | }, 32 | "flightNumber": "1234" 33 | }, 34 | "reservationNumber": "XXX006" 35 | } 36 | ] 37 | -------------------------------------------------------------------------------- /autotests/data/tripgroup/unidirectional-train-trip.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "TrainReservation", 5 | "reservationFor": { 6 | "@type": "TrainTrip", 7 | "arrivalPlatform": "", 8 | "arrivalStation": { 9 | "@type": "TrainStation", 10 | "name": "Frankfurt(Main)Hbf" 11 | }, 12 | "arrivalTime": "2019-09-05T07:36:00", 13 | "departureDay": "2019-09-05", 14 | "departurePlatform": "", 15 | "departureStation": { 16 | "@type": "TrainStation", 17 | "name": "Somewhere Hbf" 18 | }, 19 | "departureTime": "2019-09-05T06:24:00", 20 | "trainNumber": "IC 2028" 21 | } 22 | }, 23 | { 24 | "@context": "http://schema.org", 25 | "@type": "TrainReservation", 26 | "reservationFor": { 27 | "@type": "TrainTrip", 28 | "arrivalPlatform": "", 29 | "arrivalStation": { 30 | "@type": "TrainStation", 31 | "name": "Milano Centrale" 32 | }, 33 | "arrivalTime": "2019-09-05T15:50:00", 34 | "departureDay": "2019-09-05", 35 | "departurePlatform": "", 36 | "departureStation": { 37 | "@type": "TrainStation", 38 | "name": "Frankfurt(Main)Hbf" 39 | }, 40 | "departureTime": "2019-09-05T08:01:00", 41 | "trainNumber": "ECE 451" 42 | } 43 | } 44 | ] 45 | -------------------------------------------------------------------------------- /autotests/data/updateable-boardingpass.pkpass: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/autotests/data/updateable-boardingpass.pkpass -------------------------------------------------------------------------------- /autotests/localizertest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2025 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #include "localizer.h" 7 | 8 | #include 9 | #include 10 | 11 | using namespace Qt::Literals; 12 | 13 | class LocalizerTest : public QObject 14 | { 15 | Q_OBJECT 16 | private Q_SLOTS: 17 | void initTestCase() 18 | { 19 | qputenv("TZ", "UTC"); 20 | qputenv("LANG", "en_US.utf-8"); 21 | QStandardPaths::setTestModeEnabled(true); 22 | } 23 | 24 | void testTemperatureRange() 25 | { 26 | QCOMPARE(Localizer::formatTemperatureRange(20.0, 20.0, false), u"20 °C"_s); 27 | QCOMPARE(Localizer::formatTemperatureRange(20.0, 22.0, false), u"20 °C / 22 °C"_s); 28 | QCOMPARE(Localizer::formatTemperatureRange(19.5, 20.4, false), u"20 °C"_s); 29 | QCOMPARE(Localizer::formatTemperatureRange(19.4, 19.6, false), u"19 °C / 20 °C"_s); 30 | QCOMPARE(Localizer::formatTemperatureRange(-22.0, 18.0, false), u"-21 °C / 18 °C"_s); 31 | 32 | QCOMPARE(Localizer::formatTemperatureRange(19.5, 20.4, true), u"67 °F / 69 °F"_s); 33 | QCOMPARE(Localizer::formatTemperatureRange(19.4, 19.6, true), u"67 °F"_s); 34 | QCOMPARE(Localizer::formatTemperatureRange(-22.0, 18.0, true), u"-7 °F / 64 °F"_s); 35 | } 36 | }; 37 | 38 | QTEST_GUILESS_MAIN(LocalizerTest) 39 | 40 | #include "localizertest.moc" 41 | -------------------------------------------------------------------------------- /autotests/mocknetworkaccessmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | class MockNetworkAccessManager : public QNetworkAccessManager 14 | { 15 | Q_OBJECT 16 | public: 17 | struct Request { 18 | QNetworkAccessManager::Operation op; 19 | QNetworkRequest request; 20 | QByteArray data; 21 | }; 22 | 23 | std::vector requests; 24 | 25 | struct Reply { 26 | QNetworkReply::NetworkError error = QNetworkReply::NetworkSessionFailedError; 27 | int statusCode = 0; 28 | QByteArray data; 29 | QString errorMessage = QStringLiteral("no pending reply available"); 30 | }; 31 | 32 | std::queue replies; 33 | 34 | protected: 35 | QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &originalReq, QIODevice *outgoingData = nullptr) override; 36 | }; 37 | -------------------------------------------------------------------------------- /autotests/modelverificationpoint.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef MODELVERIFICATIONPOINT_H 8 | #define MODELVERIFICATIONPOINT_H 9 | 10 | #include 11 | 12 | #include 13 | 14 | class QAbstractItemModel; 15 | class QJsonValue; 16 | class QVariant; 17 | 18 | /** Compares a model state serialized to JSON with a current model state. */ 19 | class ModelVerificationPoint 20 | { 21 | public: 22 | explicit ModelVerificationPoint(const QString &refFile); 23 | ~ModelVerificationPoint(); 24 | 25 | void setRoleFilter(std::vector &&filter); 26 | void setJsonPropertyFilter(std::vector &&filter); 27 | 28 | bool verify(QAbstractItemModel *model) const; 29 | 30 | private: 31 | QJsonValue variantToJson(const QVariant &v) const; 32 | 33 | QString m_refFile; 34 | std::vector m_roleFilter; 35 | std::vector m_jsonPropertyFilter; 36 | }; 37 | 38 | #endif // MODELVERIFICATIONPOINT_H 39 | -------------------------------------------------------------------------------- /doc/kde-fdroid-nightly-repository-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/doc/kde-fdroid-nightly-repository-link.png -------------------------------------------------------------------------------- /doc/kde-fdroid-nightly-repository-link.png.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: none 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /doc/kde-fdroid-release-repository-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/doc/kde-fdroid-release-repository-link.png -------------------------------------------------------------------------------- /doc/kde-fdroid-release-repository-link.png.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: none 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /fastlane/metadata/org.kde.itinerary/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/fastlane/metadata/org.kde.itinerary/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /flatpak/99-noto-color-emoji.conf: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | serif 10 | 11 | Noto Color Emoji 12 | 13 | 14 | 15 | sans-serif 16 | 17 | Noto Color Emoji 18 | 19 | 20 | 21 | monospace 22 | 23 | Noto Color Emoji 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /readme-build-ftime.txt: -------------------------------------------------------------------------------- 1 | # Analyzing Build Performance 2 | 3 | For debug build time: 4 | We need ClangBuildAnalyzer 5 | ` 6 | git clone https://github.com/aras-p/ClangBuildAnalyzer 7 | mkdir build 8 | cd build 9 | cmake -DCMAKE_INSTALL_PREFIX= ../ 10 | make install 11 | ` 12 | 13 | ## Command line 14 | 15 | cmake -preset ftime-trace 16 | 17 | ClangBuildAnalyzer --start $PWD/build-ftime-trace 18 | cmake --build --preset ftime-trace 19 | 20 | ClangBuildAnalyzer --stop $PWD/build-ftime-trace build-ftime.txt 21 | 22 | ClangBuildAnalyzer --analyze build-ftime.txt > analyze-build-ftime.txt 23 | 24 | 25 | see https://aras-p.info/blog/2019/09/28/Clang-Build-Analyzer/ 26 | 27 | -------------------------------------------------------------------------------- /readme-build-ftime.txt.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2018 Volker Krause 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2018 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_definitions(-DTRANSLATION_DOMAIN=\"kde-itinerary\") 5 | 6 | add_subdirectory(solidextras) 7 | add_subdirectory(weather) 8 | add_subdirectory(kandroidextras) 9 | add_subdirectory(gpx) 10 | add_subdirectory(calendarextras) 11 | add_subdirectory(app) 12 | if (HAVE_MATRIX) 13 | add_subdirectory(matrix) 14 | endif() 15 | 16 | if (TARGET KF6::FileMetaData) 17 | add_subdirectory(metadataextractor) 18 | endif() 19 | if (TARGET KF6::KIOWidgets) 20 | add_subdirectory(thumbnailer) 21 | endif() 22 | -------------------------------------------------------------------------------- /src/Messages.sh: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2018 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | #! /usr/bin/env bash 5 | $XGETTEXT `find -name \*.cpp -o -name \*.qml -o -name \*.js` -o $podir/kde-itinerary.pot 6 | 7 | -------------------------------------------------------------------------------- /src/app/BarcodeScanModeButton.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2022 Volker Krause 2 | // SPDX-FileCopyrightText: 2022 Carl Schwan 3 | // SPDX-License-Identifier: LGPL-2.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Controls as QQC2 7 | import org.kde.kirigami as Kirigami 8 | import org.kde.kirigamiaddons.components as Components 9 | import org.kde.itinerary 10 | 11 | Components.FloatingButton { 12 | id: root 13 | 14 | required property Kirigami.Page page 15 | 16 | icon.name: "view-barcode-qr" 17 | text: i18nc("@action:button", "Barcode Scan Mode") 18 | onClicked: scanModeController.toggle() 19 | checkable: true 20 | checked: scanModeController.enabled 21 | 22 | anchors { 23 | right: parent.right 24 | rightMargin: Kirigami.Units.largeSpacing + (page.contentItem.QQC2.ScrollBar && page.contentItem.QQC2.ScrollBar.vertical ? page.contentItem.QQC2.ScrollBar.vertical.width : 0) 25 | bottom: parent.bottom 26 | bottomMargin: Kirigami.Units.largeSpacing 27 | } 28 | 29 | BarcodeScanModeController { 30 | id: scanModeController 31 | page: root.page 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/app/CalendarSelectionSheet.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | import QtQuick 7 | import QtQuick.Layouts 8 | import QtQuick.Controls as QQC2 9 | import org.kde.kirigami as Kirigami 10 | 11 | Kirigami.Dialog { 12 | id: root 13 | 14 | title: i18nc("@title", "Select Calendar") 15 | 16 | property alias model: calendarSelectorListView.model 17 | 18 | signal calendarSelected(var calendar) 19 | 20 | width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24) 21 | height: Math.min(applicationWindow().height, Kirigami.Units.gridUnit * 32) 22 | 23 | contentItem: ListView { 24 | id: calendarSelectorListView 25 | 26 | delegate: QQC2.ItemDelegate { 27 | required property int index 28 | required property string name 29 | required property var calendar 30 | 31 | text: name 32 | width: ListView.view.width 33 | contentItem: Kirigami.TitleSubtitle { 34 | title: parent.text 35 | } 36 | onClicked: { 37 | root.calendarSelected(calendar); 38 | root.close(); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/app/CardPageTitle.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2023 Carl Schwan 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | import QtQuick 5 | import QtQuick.Layouts 6 | import QtQuick.Controls as QQC2 7 | import org.kde.kirigami as Kirigami 8 | import org.kde.kirigamiaddons.formcard as FormCard 9 | 10 | ColumnLayout { 11 | id: root 12 | 13 | spacing: 0 14 | 15 | required property string emojiIcon 16 | required property string text 17 | 18 | Layout.fillWidth: true 19 | Layout.maximumWidth: Kirigami.Units.gridUnit * 30 20 | Layout.alignment: Qt.AlignHCenter 21 | 22 | QQC2.Label { 23 | text: root.emojiIcon 24 | horizontalAlignment: Text.AlignHCenter 25 | 26 | font { 27 | family: "emoji" 28 | pointSize: 40 29 | } 30 | 31 | Layout.fillWidth: true 32 | Layout.alignment: Qt.AlignHCenter 33 | Accessible.ignored: true 34 | } 35 | 36 | Kirigami.Heading { 37 | text: root.text 38 | wrapMode: Text.WordWrap 39 | horizontalAlignment: Text.AlignHCenter 40 | 41 | leftPadding: Kirigami.Units.smallSpacing 42 | rightPadding: Kirigami.Units.smallSpacing 43 | bottomPadding: Kirigami.Units.smallSpacing 44 | 45 | Layout.fillWidth: true 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/FormDateTimeEditDelegate.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | import QtQuick 7 | import QtQuick.Layouts 8 | import QtQuick.Controls as QQC2 9 | import org.kde.kirigami as Kirigami 10 | import org.kde.kirigamiaddons.formcard as FormCard 11 | import org.kde.kitinerary 12 | import org.kde.itinerary 13 | 14 | FormCard.FormDateTimeDelegate { 15 | id: root 16 | 17 | property variant obj 18 | property string propertyName 19 | value: Util.dateTimeStripTimezone(obj, propertyName) 20 | readonly property bool hasValue: !isNaN(value.getTime()) 21 | property bool isModified: Util.dateTimeStripTimezone(obj, propertyName).getTime() != value.getTime() 22 | // TODO this is not used with KF6 yet! 23 | initialValue: { 24 | let d = new Date(); 25 | d.setTime(d.getTime() + 60 * 60 * 1000 - (d.getTime() % (60 * 60 * 1000))); 26 | return d; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/FormPriceDelegate.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2023 Volker Krause 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | import QtQuick 5 | import QtQuick.Layouts 6 | import QtQuick.Controls as QQC2 7 | import org.kde.kirigami as Kirigami 8 | import org.kde.kirigamiaddons.formcard as FormCard 9 | import org.kde.i18n.localeData 10 | import org.kde.kitinerary 11 | import org.kde.itinerary 12 | 13 | FormCard.FormTextDelegate { 14 | id: root 15 | 16 | /** The element of which the price properties should be shown. */ 17 | required property var item 18 | 19 | text: i18nc("@label", "Price") 20 | visible: PriceUtil.hasPrice(root.item) 21 | 22 | description: { 23 | const price = PriceUtil.price(root.item); 24 | const currency = PriceUtil.currency(root.item); 25 | const homeCurrency = Country.fromAlpha2(Settings.homeCountryIsoCode).currencyCode; 26 | 27 | if (Settings.performCurrencyConversion && homeCurrency != currency) { 28 | const convertedPrice = UnitConversion.convertCurrency(price, currency, homeCurrency); 29 | if (!isNaN(convertedPrice) && convertedPrice != 0.0) { 30 | return i18nc("prices in local and home currency", "%1 (%2)", 31 | Localizer.formatCurrency(price, currency), 32 | Localizer.formatCurrency(convertedPrice, homeCurrency)); 33 | } 34 | } 35 | 36 | return Localizer.formatCurrency(price, currency); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/GenericPkPassPage.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | import QtQuick 7 | import QtQuick.Layouts 8 | import QtQuick.Controls as QQC2 9 | import org.kde.kirigami as Kirigami 10 | import org.kde.itinerary 11 | 12 | PkPassPage { 13 | id: root 14 | property string genericPassId 15 | 16 | Kirigami.PromptDialog { 17 | id: deleteWarningDialog 18 | 19 | title: i18n("Delete Pass") 20 | subtitle: i18n("Do you really want to delete this pass?") 21 | 22 | standardButtons: QQC2.Dialog.Close 23 | customFooterActions: [ 24 | Kirigami.Action { 25 | text: i18n("Delete") 26 | icon.name: "edit-delete" 27 | onTriggered: { 28 | PassManager.remove(genericPassId); 29 | root.QQC2.ApplicationWindow.window.pageStack.pop(); 30 | } 31 | } 32 | ] 33 | } 34 | 35 | actions: [ 36 | Kirigami.Action { 37 | icon.name: "edit-delete" 38 | text: i18n("Delete") 39 | onTriggered: deleteWarningDialog.open() 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /src/app/IndoorMapInfoSheet.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | import QtQuick 8 | import QtQuick.Layouts 9 | import QtQuick.Controls as QQC2 10 | import org.kde.kirigami as Kirigami 11 | import org.kde.kosmindoormap 12 | import org.kde.osm.editorcontroller 13 | import org.kde.itinerary 14 | 15 | OSMElementInformationDialog { 16 | id: elementDetailsSheet 17 | customFooterActions: [ 18 | Kirigami.Action { 19 | visible: Settings.osmContributorMode 20 | icon.name: "document-edit" 21 | text: i18n("Edit with iD") 22 | onTriggered: EditorController.editElement(elementDetailsSheet.model.element.element, Editor.ID) 23 | }, 24 | Kirigami.Action { 25 | visible: Settings.osmContributorMode && EditorController.hasEditor(Editor.JOSM) 26 | icon.name: "org.openstreetmap.josm" 27 | text: i18n("Edit with JOSM") 28 | onTriggered: EditorController.editElement(elementDetailsSheet.model.element.element, Editor.JOSM) 29 | }, 30 | Kirigami.Action { 31 | visible: Settings.osmContributorMode && EditorController.hasEditor(Editor.Vespucci) 32 | icon.name: "document-edit" 33 | text: i18n("Edit with Vespucci") 34 | onTriggered: EditorController.editElement(elementDetailsSheet.model.element.element, Editor.Vespucci) 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /src/app/MapCircle.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2024 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | import QtQuick 7 | import QtLocation as QtLocation 8 | import QtPositioning as QtPositioning 9 | import org.kde.kirigami as Kirigami 10 | import org.kde.itinerary 11 | 12 | /** Circle elements on the map. */ 13 | QtLocation.MapQuickItem { 14 | id: root 15 | 16 | property alias size: circle.height 17 | property alias borderWidth: circle.border.width 18 | property alias color: circle.border.color 19 | property alias textColor: circle.color 20 | property alias iconName: icon.source 21 | 22 | signal clicked() 23 | 24 | anchorPoint.x: sourceItem.width / 2 25 | anchorPoint.y: sourceItem.height / 2 26 | 27 | sourceItem: Rectangle { 28 | id: circle 29 | height: 15 30 | width: circle.height 31 | radius: height / 2 32 | border.width: 2 33 | 34 | Kirigami.Icon { 35 | id: icon 36 | isMask: true 37 | anchors.centerIn: circle 38 | height: root.size - root.borderWidth 39 | width: icon.height 40 | color: root.color 41 | } 42 | 43 | MouseArea { 44 | anchors.fill: parent 45 | scale: Math.max(1, 32 / root.height) 46 | onClicked: root.clicked() 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/app/MapPin.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2024 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | import QtQuick 7 | import QtLocation as QtLocation 8 | import org.kde.kirigami as Kirigami 9 | 10 | /** Icon in pin element for the map. */ 11 | QtLocation.MapQuickItem { 12 | id: root 13 | 14 | property alias color: mainIcon.color 15 | property alias textColor: bgRect.color 16 | property alias iconName: subIcon.source 17 | signal clicked() 18 | 19 | anchorPoint.x: sourceItem.width / 2 20 | anchorPoint.y: sourceItem.height 21 | autoFadeIn: false 22 | 23 | sourceItem: Kirigami.Icon { 24 | id: mainIcon 25 | 26 | height: Kirigami.Units.iconSizes.huge 27 | width: height 28 | source: "map-symbolic" 29 | isMask: true 30 | color: "#232629" 31 | 32 | Rectangle { 33 | id: bgRect 34 | anchors.centerIn: parent 35 | anchors.verticalCenterOffset: -parent.height / 8 36 | width: height 37 | height: parent.height / 3 + 1 38 | radius: height / 2 39 | } 40 | Kirigami.Icon { 41 | id: subIcon 42 | anchors.centerIn: mainIcon 43 | anchors.verticalCenterOffset: -mainIcon.height / 8 44 | width: height 45 | height: parent.height / 3 + 1 46 | isMask: true 47 | color: root.color 48 | } 49 | MouseArea { 50 | anchors.fill: parent 51 | onClicked: root.clicked() 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/app/ReservationDocumentsCard.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | import QtQuick 8 | import QtQuick.Layouts 9 | import QtQuick.Controls as QQC2 10 | import org.kde.kirigami as Kirigami 11 | import org.kde.kitinerary 12 | import org.kde.itinerary 13 | 14 | DocumentsCard { 15 | /// TimelineDelegateController 16 | property QtObject controller: null 17 | 18 | documentIds: controller.documentIds 19 | title: i18n("Documents and Tickets") 20 | 21 | onAddDocument: (file) => { ApplicationController.addDocumentToReservation(controller.batchId, file); } 22 | onRemoveDocument: (docId) => { ApplicationController.removeDocumentFromReservation(controller.batchId, docId); } 23 | } 24 | -------------------------------------------------------------------------------- /src/app/StatisticsDelegate.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FleCopyrightText: 2019 Volker Krause 2 | // SPDX-FileCopyrightText: 2022 Carl Schwan 3 | // SPDX-License-Identifier: LGPL-2.0-or-later 4 | 5 | import QtQuick 6 | import QtQuick.Layouts 7 | import QtQuick.Controls as QQC2 8 | import org.kde.kirigami as Kirigami 9 | import org.kde.itinerary 10 | import org.kde.kirigamiaddons.formcard as FormCard 11 | 12 | FormCard.FormTextDelegate { 13 | id: root 14 | property var statItem 15 | 16 | visible: statItem.hasData 17 | text: statItem.label 18 | description: statItem.value 19 | 20 | trailing: Kirigami.Icon { 21 | source: root.statItem.trend == StatisticsItem.TrendUp ? "go-up-symbolic" : root.statItem.trend == StatisticsItem.TrendDown ? "go-down-symbolic" : "go-next-symbolic" 22 | color: root.statItem.trend == StatisticsItem.TrendUp ? Kirigami.Theme.negativeTextColor : root.statItem.trend == StatisticsItem.TrendDown ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.textColor 23 | isMask: true 24 | Layout.preferredWidth: Kirigami.Units.gridUnit 25 | Layout.preferredHeight: Kirigami.Units.gridUnit 26 | visible: root.statItem.trend != StatisticsItem.TrendUnknown 27 | implicitHeight: Kirigami.Units.gridUnit 28 | implicitWidth: Kirigami.Units.gridUnit 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/StopPickerPage.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | import org.kde.kpublictransport as KPublicTransport 7 | import org.kde.kpublictransport.ui as KPublicTransport 8 | import org.kde.itinerary 9 | 10 | KPublicTransport.StopPickerPage { 11 | id: root 12 | 13 | TripGroupLocationModel { 14 | id: tripGroupLocationModel 15 | tripGroupManager: TripGroupManager 16 | tripGroupId: ApplicationController.contextTripGroupId 17 | onLocationsChanged: { 18 | root.locationHistoryModel.clearPresetLocations(); 19 | for (let i = 0; i < tripGroupLocationModel.rowCount(); ++i) { 20 | const idx = tripGroupLocationModel.index(i, 0); 21 | root.locationHistoryModel.addPresetLocation( 22 | tripGroupLocationModel.data(idx, TripGroupLocationModel.LocationRole), 23 | tripGroupLocationModel.data(idx, TripGroupLocationModel.LastUsedRole), 24 | tripGroupLocationModel.data(idx, TripGroupLocationModel.UseCountRole) 25 | ); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/TimelineDelegateSeatRowLabel.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.0-or-later 2 | // SPDX-FileCopyrightText: Copyright: Mathis Brüchert 3 | 4 | import QtQuick 5 | import QtQuick.Layouts 6 | import QtQuick.Controls as QQC2 7 | 8 | QQC2.Label { 9 | id: root 10 | 11 | /** Prefer hiding this label rather than enabling eliding elsewhere when we run out of space */ 12 | property bool lowPriority: false 13 | 14 | horizontalAlignment: Qt.AlignHCenter 15 | verticalAlignment: Qt.AlignVCenter 16 | Layout.fillWidth: true 17 | Layout.fillHeight: true 18 | 19 | // as long as we have enough space, prefer equally sized labels 20 | Layout.preferredWidth: parent.enableEliding ? implicitWidth : parent.width 21 | // hide low-priority content before resorting to eliding 22 | visible: !parent.hideLowPriorityContent || !root.lowPriority 23 | // when space gets limited, trade in equal sizeing first to avoid eliding 24 | Layout.minimumWidth: parent.enableEliding ? 0 : implicitWidth 25 | // elide as last resort, when there is not enough space for all labels 26 | elide: Text.ElideLeft 27 | } 28 | -------------------------------------------------------------------------------- /src/app/TimelineSectionDelegate.qml: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2018 Volker Krause 2 | // SPDX-FileCopyrightText: 2022 Carl Schwan 3 | // SPDX-License-Identifier: LGPL-2.0-or-later 4 | 5 | import QtQuick 6 | import org.kde.kirigami as Kirigami 7 | import QtQuick.Controls as QQC2 8 | import org.kde.kirigamiaddons.formcard as FormCard 9 | import QtQuick.Layouts 10 | import org.kde.itinerary 11 | 12 | FormCard.FormHeader { 13 | id: root 14 | 15 | property alias day: _controller.date 16 | property QtObject controller: TimelineSectionDelegateController { 17 | id: _controller; 18 | tripGroupModel: TripGroupModel 19 | } 20 | 21 | width: ListView.view.width 22 | title: controller.title 23 | topPadding: Kirigami.Units.smallSpacing 24 | 25 | Accessible.description: controller.subTitle 26 | 27 | trailing: QQC2.Label { 28 | topPadding: root.topPadding 29 | bottomPadding: root.bottomPadding 30 | leftPadding: root.leftPadding 31 | rightPadding: root.rightPadding 32 | 33 | text: controller.subTitle 34 | color: root.controller.isHoliday ? Kirigami.Theme.negativeTextColor : Kirigami.Theme.disabledTextColor 35 | 36 | Accessible.ignored: true 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/TouristAttractionDelegate.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | import QtQuick 8 | import QtQuick.Layouts 9 | import QtQuick.Controls as QQC2 10 | import org.kde.kirigami as Kirigami 11 | import org.kde.itinerary 12 | 13 | TimelineDelegate { 14 | id: root 15 | 16 | readonly property var touristAttraction: ReservationManager.reservation(root.batchId).touristAttraction 17 | 18 | contentItem: ColumnLayout { 19 | spacing: Kirigami.Units.smallSpacing 20 | 21 | RowLayout { 22 | spacing: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing 23 | 24 | Layout.fillWidth: true 25 | 26 | Kirigami.Icon { 27 | Layout.preferredHeight: Kirigami.Units.iconSizes.smallMedium 28 | Layout.preferredWidth: Kirigami.Units.iconSizes.smallMedium 29 | source: "meeting-attending" 30 | } 31 | 32 | Kirigami.Heading { 33 | text: touristAttraction.name 34 | level: 3 35 | Layout.fillWidth: true 36 | } 37 | 38 | Kirigami.Heading { 39 | level: 2 40 | text: Localizer.formatTime(reservation, "arrivalTime") 41 | } 42 | } 43 | 44 | QQC2.Label { 45 | Layout.fillWidth: true 46 | visible: text !== "" 47 | text: Localizer.formatAddressWithContext(touristAttraction.address, null, Settings.homeCountryIsoCode) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/app/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Gabriel Souza Franco 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | android.useAndroidX=true 4 | 5 | # Gradle properties set by Qt 6 | org.gradle.jvmargs=-Xmx2500m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 7 | org.gradle.parallel=true 8 | -------------------------------------------------------------------------------- /src/app/android/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/ic_launcher-playstore.png -------------------------------------------------------------------------------- /src/app/android/itineraryactivity.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef ITINERARY_ACTIVITY_H 7 | #define ITINERARY_ACTIVITY_H 8 | 9 | #include "kandroidextras/androidtypes.h" 10 | #include "kandroidextras/javatypes.h" 11 | #include "kandroidextras/jnimethod.h" 12 | #include "kandroidextras/jniproperty.h" 13 | #include "kandroidextras/jnitypes.h" 14 | #include "kandroidextras/uri.h" 15 | 16 | #include 17 | 18 | JNI_TYPE(org, kde, itinerary, Activity) 19 | 20 | /** Interface to the Java Activity class. */ 21 | class ItineraryActivity 22 | { 23 | JNI_UNMANAGED_OBJECT(ItineraryActivity, org::kde::itinerary::Activity) 24 | public: 25 | JNI_METHOD(KAndroidExtras::Jni::Array, attachmentsForIntent, KAndroidExtras::android::content::Intent) 26 | JNI_METHOD(KAndroidExtras::android::net::Uri, openDocument, KAndroidExtras::java::lang::String) 27 | private: 28 | inline QJniObject jniHandle() const 29 | { 30 | return QNativeInterface::QAndroidApplication::context(); 31 | } 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/app/android/res/drawable/splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/app/android/res/drawable/splash_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/res/drawable/splash_logo.png -------------------------------------------------------------------------------- /src/app/android/res/drawable/vendor_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/res/drawable/vendor_logo.png -------------------------------------------------------------------------------- /src/app/android/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/src/app/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/app/android/res/resources.properties: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | unqualifiedResLocale=en-US 4 | -------------------------------------------------------------------------------- /src/app/android/res/values-ast/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerariu 5 | Estadístiques 6 | 7 | -------------------------------------------------------------------------------- /src/app/android/res/values-ca/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerari 5 | Bitllet actual 6 | Estadístiques 7 | Estat en directe 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-cs/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Itinerář KDE 4 | Itinerář 5 | Současný lístek 6 | Statistika 7 | 8 | -------------------------------------------------------------------------------- /src/app/android/res/values-de/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE-Itinerary 4 | Itinerary 5 | Aktueller Fahrschein 6 | Statistik 7 | Live-Status 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-en-rGB/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Current Ticket 6 | Statistics 7 | Live Status 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-eo/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinero 5 | Aktuala Bileto 6 | Statistikoj 7 | Realtempa Statuso 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-es/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Billete actual 6 | Estadísticas 7 | Estado en directo 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-eu/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Uneko txartela 6 | Estatistikak 7 | Zuzeneko egoera 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-fi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Nykyinen matkalippu 6 | Tilastot 7 | Elävä tila 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-fr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinéraire 5 | Actuel 6 | Statistiques 7 | État en temps réel 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-gl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Billete actual 6 | Estatísticas 7 | Estado en directo 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-hi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | केडीई यात्रा कार्यक्रम 4 | यात्रा कार्यक्रम 5 | वर्तमान टिकट 6 | आंकड़े 7 | लाइव स्थिति 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-hu/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Jelenlegi jegy 6 | Statisztikák 7 | Élő állapot 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-ia/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary (Itinerario) 5 | Billet currente 6 | Statistica 7 | Stato de Vita 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Biglietto attuale 6 | Statistiche 7 | Stato in tempo reale 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-iw/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | לו״ז נסיעה 5 | כרטיס נוכחי 6 | סטטיסטיקה 7 | מצב בזמן אמת 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-ja/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/app/android/res/values-ka/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | მიმდინარე ბილეთი 6 | სტატისტიკა 7 | მიმდინარე სტატუსი 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-ko/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE 여행 정보 4 | 여행 정보 5 | 현재 승차권 6 | 통계 7 | 실시간 상태 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-lt/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/app/android/res/values-nl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Reisroute 5 | Huidige ticket 6 | Statistieken 7 | Actuele status 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-pl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Plan podróży 5 | Bieżący bilet 6 | Statystyki 7 | Stan na żywo 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-pt-rBR/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerário 5 | Bilhete atual 6 | Estatísticas 7 | Status ao vivo 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-pt/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerário 5 | Bilhete Actual 6 | Estatísticas 7 | Estado em Directo 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Маршруты KDE 4 | Маршрут 5 | Текущий билет 6 | Статистика 7 | Текущий статус 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-sk/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerár 4 | Itinerár 5 | Aktuálny ticket 6 | 7 | -------------------------------------------------------------------------------- /src/app/android/res/values-sl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Trenutna vozovnica 6 | Statistika 7 | Stanje v živo 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-sv/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE-resplan 4 | Resplan 5 | Aktuell biljett 6 | Statistik 7 | Realtidsstatus 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-tr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Yol Kılavuzu 4 | Yolcu Belgesi 5 | Geçerli Bilet 6 | İstatistikler 7 | Canlı Durum 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-uk/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE Itinerary 4 | Itinerary 5 | Поточний квиток 6 | Статистика 7 | Інтерактивний стан 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/app/android/res/values-zh-rTW/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | KDE 旅行計劃 4 | 旅行計劃 5 | 目前票券 6 | 統計資料 7 | 實時狀態 8 | 9 | -------------------------------------------------------------------------------- /src/app/android/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | KDE Itinerary 8 | Itinerary 9 | 10 | Current Ticket 11 | Statistics 12 | Live Status 13 | 14 | -------------------------------------------------------------------------------- /src/app/android/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/app/android/res/xml/shortcuts.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 13 | 14 | 15 | 20 | 21 | 22 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/app/android/src/org/kde/itinerary/QTimeZone.java: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | package org.kde.itinerary; 8 | 9 | import android.icu.text.TimeZoneFormat; 10 | import android.icu.util.TimeZone; 11 | import android.os.Build; 12 | 13 | import java.lang.String; 14 | import java.util.Locale; 15 | 16 | public class QTimeZone 17 | { 18 | public static String abbreviation(String tzid, long date, Locale locale, boolean isDaylightTime) 19 | { 20 | // ICU timezone formatting gives the best result, but is only available starting at API level 24 21 | if (Build.VERSION.SDK_INT >= 24) { 22 | TimeZoneFormat format = TimeZoneFormat.getInstance(locale); 23 | TimeZone tz = TimeZone.getTimeZone(tzid); 24 | return format.format(TimeZoneFormat.Style.SPECIFIC_SHORT, tz, date); 25 | } 26 | 27 | // fallback to java.util.TimeZone, this only gives us GMT offsets 28 | java.util.TimeZone tz = java.util.TimeZone.getTimeZone(tzid); 29 | return tz.getDisplayName(isDaylightTime, java.util.TimeZone.SHORT, locale); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/bundle-constants.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef BUNDLE_CONSTANTS_H 8 | #define BUNDLE_CONSTANTS_H 9 | 10 | constexpr inline const char16_t BUNDLE_FAVORITE_LOCATION_DOMAIN[] = u"org.kde.itinerary/favorite-locations"; 11 | constexpr inline const char16_t BUNDLE_HEALTH_CERTIFICATE_DOMAIN[] = u"org.kde.itinerary/health-certificates"; 12 | constexpr inline const char16_t BUNDLE_LIVE_DATA_DOMAIN[] = u"org.kde.itinerary/live-data"; 13 | constexpr inline const char16_t BUNDLE_PASS_DOMAIN[] = u"org.kde.itinerary/programs"; 14 | constexpr inline const char16_t BUNDLE_SETTINGS_DOMAIN[] = u"org.kde.itinerary/settings"; 15 | constexpr inline const char16_t BUNDLE_TRANSFER_DOMAIN[] = u"org.kde.itinerary/transfers"; 16 | constexpr inline const char16_t BUNDLE_TRIPGROUP_DOMAIN[] = u"org.kde.itinerary/trips"; 17 | constexpr inline const char16_t BUNDLE_VERSION_DOMAIN[] = u"org.kde.itinerary/version"; 18 | 19 | constexpr inline const auto BUNDLE_FORMAT_VERSION = 3; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/app/calendarhelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #include "calendarhelper.h" 7 | #include "transfer.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | void CalendarHelper::fillPreTransfer(const KCalendarCore::Event::Ptr &event, const Transfer &transfer) 17 | { 18 | if (transfer.state() != Transfer::Selected) { 19 | return; 20 | } 21 | 22 | // add a reminder 5min before the transfer departure 23 | const auto depDt = transfer.journey().hasExpectedDepartureTime() ? transfer.journey().expectedDepartureTime() : transfer.journey().scheduledDepartureTime(); 24 | if (event->alarms().empty()) { 25 | KCalendarCore::Alarm::Ptr alarm(new KCalendarCore::Alarm(event.data())); 26 | KCalendarCore::Duration alarmDur(-depDt.secsTo(event->dtStart()) - 5 * 60); 27 | alarm->setStartOffset(alarmDur); 28 | alarm->setDisplayAlarm(i18n("Transfer to %1", transfer.toName())); 29 | alarm->setEnabled(true); 30 | event->addAlarm(alarm); 31 | } 32 | 33 | // add Apple travel duration property 34 | KCalendarCore::Duration travelDur(depDt.secsTo(event->dtStart())); 35 | KCalendarCore::ICalFormat format; 36 | event->setNonKDECustomProperty("X-APPLE-TRAVEL-DURATION", format.toString(travelDur), QStringLiteral("VALUE=DURATION")); 37 | 38 | // TODO add X-APPLE-TRAVEL-START property 39 | } 40 | -------------------------------------------------------------------------------- /src/app/calendarhelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef CALENDARHELPER_H 7 | #define CALENDARHELPER_H 8 | 9 | #include 10 | 11 | class Transfer; 12 | 13 | /** Helper functions for dealing with calendar data. */ 14 | namespace CalendarHelper 15 | { 16 | 17 | /** Extension of KItinerary::CalendarHandler::fillEvent for pre-Transfers. */ 18 | void fillPreTransfer(const KCalendarCore::Event::Ptr &event, const Transfer &transfer); 19 | 20 | } 21 | 22 | #endif // CALENDARHELPER_H 23 | -------------------------------------------------------------------------------- /src/app/clipboard.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2023 Carl Schwan 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | class QClipboard; 9 | 10 | /** 11 | * Clipboard proxy 12 | */ 13 | class Clipboard : public QObject 14 | { 15 | Q_OBJECT 16 | /** Clipboard currently holds a text content. */ 17 | Q_PROPERTY(bool hasText READ hasText NOTIFY contentChanged) 18 | /** Clipboard currently holds URLs. */ 19 | Q_PROPERTY(bool hasUrls READ hasUrls NOTIFY contentChanged) 20 | /** Clipboard currently holds binary data. */ 21 | Q_PROPERTY(bool hasBinaryData READ hasBinaryData NOTIFY contentChanged) 22 | 23 | /** Textual clipboard content. */ 24 | Q_PROPERTY(QString text READ text NOTIFY contentChanged) 25 | /** Binary data clipboard content. */ 26 | Q_PROPERTY(QByteArray binaryData READ binaryData NOTIFY contentChanged) 27 | 28 | public: 29 | explicit Clipboard(QObject *parent = nullptr); 30 | 31 | [[nodiscard]] static bool hasText(); 32 | [[nodiscard]] static bool hasUrls(); 33 | [[nodiscard]] static bool hasBinaryData(); 34 | 35 | [[nodiscard]] static QString text(); 36 | [[nodiscard]] static QByteArray binaryData(); 37 | 38 | Q_INVOKABLE static void saveText(const QString &message); 39 | 40 | Q_SIGNALS: 41 | /** Clipboard content changed. */ 42 | void contentChanged(); 43 | }; 44 | -------------------------------------------------------------------------------- /src/app/config-itinerary.h.cmake: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef CONFIG_ITINERARY_H 8 | #define CONFIG_ITINERARY_H 9 | 10 | #cmakedefine01 HAVE_KCRASH 11 | #cmakedefine01 HAVE_KHEALTHCERTIFICATE 12 | #cmakedefine01 HAVE_MATRIX 13 | #cmakedefine01 HAVE_DBUS 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/app/constants.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef CONSTANTS_H 8 | #define CONSTANTS_H 9 | 10 | #include 11 | 12 | namespace Constants 13 | { 14 | constexpr std::chrono::seconds MaximumLayoverTime = std::chrono::hours(4); 15 | constexpr std::chrono::seconds FavoriteLocationAutoTransferThreshold = std::chrono::days(1); 16 | 17 | constexpr auto MaximumFavoriteLocationTransferDistance = 50'000; // in meters 18 | 19 | constexpr std::chrono::seconds CurrentBatchLeadingMargin = std::chrono::hours(48); 20 | constexpr std::chrono::seconds CurrentBatchTrailingMargin = std::chrono::hours(4); 21 | 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/app/costaccumulator.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2024 Volker Krause 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | #ifndef COSTACCUMULATOR_H 5 | #define COSTACCUMULATOR_H 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | class ReservationManager; 12 | 13 | class Price { 14 | Q_GADGET 15 | Q_PROPERTY(double value MEMBER value) 16 | Q_PROPERTY(QString currency MEMBER currency) 17 | 18 | public: 19 | double value = NAN; 20 | QString currency; 21 | 22 | [[nodiscard]] constexpr inline bool isNull() const 23 | { 24 | return std::isnan(value); 25 | } 26 | [[nodiscard]] inline bool operator==(const Price &other) const 27 | { 28 | return value == other.value && currency == other.currency; 29 | } 30 | }; 31 | 32 | /** Determine cost of an entire trip group. */ 33 | class CostAccumulator 34 | { 35 | public: 36 | explicit CostAccumulator(const ReservationManager *resMgr); 37 | ~CostAccumulator(); 38 | 39 | void setTargetCurrency(const QString ¤cy); 40 | 41 | [[nodiscard]] Price totalCost() const; 42 | 43 | void addBatch(const QString &batchId); 44 | 45 | private: 46 | const ReservationManager *m_resMgr = nullptr; 47 | QString m_targetCurrency; 48 | QHash m_resNumCosts; 49 | QHash m_totalCosts; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/app/countrysubdivisionmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef COUNTRYSUBDIVISIONMODEL_H 7 | #define COUNTRYSUBDIVISIONMODEL_H 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | /** Country subdivision model, for a given country. */ 15 | class CountrySubdivisionModel : public QAbstractListModel 16 | { 17 | Q_OBJECT 18 | Q_PROPERTY(KCountry country READ country WRITE setCountry NOTIFY countryChanged) 19 | 20 | public: 21 | enum { 22 | CodeRole = Qt::UserRole, 23 | SubdivisionRole, 24 | }; 25 | 26 | explicit CountrySubdivisionModel(QObject *parent = nullptr); 27 | ~CountrySubdivisionModel(); 28 | 29 | KCountry country() const; 30 | void setCountry(const KCountry &country); 31 | 32 | int rowCount(const QModelIndex &parent) const override; 33 | QVariant data(const QModelIndex &index, int role) const override; 34 | QHash roleNames() const override; 35 | 36 | Q_INVOKABLE int rowForNameOrCode(const QString &input) const; 37 | 38 | Q_SIGNALS: 39 | void countryChanged(); 40 | 41 | private: 42 | KCountry m_country; 43 | QList m_subdivs; 44 | }; 45 | 46 | #endif // COUNTRYSUBDIVISIONMODEL_H 47 | -------------------------------------------------------------------------------- /src/app/developmentmodecontroller.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef DEVELOPMENTMODECONTROLLER_H 8 | #define DEVELOPMENTMODECONTROLLER_H 9 | 10 | #include 11 | #include 12 | 13 | /** Functions for the development mode. */ 14 | class DevelopmentModeController 15 | { 16 | Q_GADGET 17 | public: 18 | Q_INVOKABLE void enablePublicTransportLogging(); 19 | Q_INVOKABLE void importMapCSS(const QUrl &url); 20 | Q_INVOKABLE void purgeMapCSS(); 21 | Q_INVOKABLE void clearOsmTileCache(); 22 | Q_INVOKABLE static void retranslate(const QString &locale); 23 | Q_INVOKABLE void crash(); 24 | Q_INVOKABLE [[nodiscard]] static QString screenInfo(); 25 | Q_INVOKABLE [[nodiscard]] static QString localeInfo(); 26 | }; 27 | 28 | Q_DECLARE_METATYPE(DevelopmentModeController) 29 | 30 | #endif // DEVELOPMENTMODECONTROLLER_H 31 | -------------------------------------------------------------------------------- /src/app/documentmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef DOCUMENTMANAGER_H 8 | #define DOCUMENTMANAGER_H 9 | 10 | #include 11 | 12 | /** Manages documents attached to reservations. */ 13 | class DocumentManager : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit DocumentManager(QObject *parent = nullptr); 18 | ~DocumentManager() override; 19 | 20 | /** Lists all documents in storage. */ 21 | QList documents() const; 22 | /** Returns @c true if a document with the given id is present. */ 23 | bool hasDocument(const QString &id) const; 24 | 25 | /** Returns the document meta data. */ 26 | QVariant documentInfo(const QString &id) const; 27 | /** Returns a file path for opening the document. */ 28 | QString documentFilePath(const QString &id) const; 29 | 30 | /** Add a document from raw data. */ 31 | void addDocument(const QString &id, const QVariant &info, const QByteArray &data); 32 | /** Add a document from an external file. */ 33 | void addDocument(const QString &id, const QVariant &info, const QString &filePath); 34 | /** Remove a document. */ 35 | Q_INVOKABLE void removeDocument(const QString &id); 36 | 37 | Q_SIGNALS: 38 | void documentAdded(const QString &id); 39 | void documentRemoved(const QString &id); 40 | 41 | private: 42 | QString basePath() const; 43 | }; 44 | 45 | #endif // DOCUMENTMANAGER_H 46 | -------------------------------------------------------------------------------- /src/app/factory.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef FACTORY_H 7 | #define FACTORY_H 8 | 9 | #include "qobjectdefs.h" 10 | 11 | class QVariant; 12 | 13 | /** QML factory functions for gadget types. */ 14 | class Factory 15 | { 16 | Q_GADGET 17 | public: 18 | Q_INVOKABLE [[nodiscard]] static QVariant makeFlightReservation(); 19 | Q_INVOKABLE [[nodiscard]] static QVariant makeBoatReservation(); 20 | Q_INVOKABLE [[nodiscard]] static QVariant makeEventReservation(); 21 | Q_INVOKABLE [[nodiscard]] static QVariant makeFoodEstablishmentReservation(); 22 | Q_INVOKABLE [[nodiscard]] static QVariant makeLodgingReservation(); 23 | Q_INVOKABLE [[nodiscard]] static QVariant makePerson(); 24 | Q_INVOKABLE [[nodiscard]] static QVariant makePlace(); 25 | Q_INVOKABLE [[nodiscard]] static QVariant makeProgramMembership(); 26 | Q_INVOKABLE [[nodiscard]] static QVariant makeTicket(); 27 | }; 28 | 29 | #endif // FACTORY_H 30 | -------------------------------------------------------------------------------- /src/app/filehelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "filehelper.h" 8 | 9 | #include 10 | #include 11 | 12 | #ifdef Q_OS_ANDROID 13 | #include 14 | #endif 15 | 16 | #include 17 | 18 | using namespace Qt::Literals::StringLiterals; 19 | 20 | bool FileHelper::isLocalFile(const QUrl &url) 21 | { 22 | return url.isLocalFile() || url.scheme() == QLatin1StringView("content"); 23 | } 24 | 25 | QString FileHelper::toLocalFile(const QUrl &url) 26 | { 27 | return url.isLocalFile() ? url.toLocalFile() : url.toString(QUrl::FullyEncoded); 28 | } 29 | 30 | QString FileHelper::fileName(const QUrl &url) 31 | { 32 | #if defined(Q_OS_ANDROID) 33 | if (url.scheme() == "content"_L1) { 34 | return KAndroidExtras::ContentResolver::fileName(url); 35 | } 36 | #endif 37 | return url.fileName(); 38 | } 39 | 40 | bool FileHelper::hasZipHeader(const QByteArray &data) 41 | { 42 | return data.size() >= 4 && std::strncmp(data.constData(), "PK\x03\x04", 4) == 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/app/filehelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef FILEHELPER_H 8 | #define FILEHELPER_H 9 | 10 | class QByteArray; 11 | class QString; 12 | class QUrl; 13 | 14 | /** File related helper methods. */ 15 | namespace FileHelper 16 | { 17 | 18 | /** Returns whether @p url is a file that can be read by QFile directly without downloading. 19 | * @note This differs from QUrl::isLocalFile in also supporting Android content: URLs. 20 | */ 21 | bool isLocalFile(const QUrl &url); 22 | 23 | /** Returns a path for @p url that QFile can work with. 24 | * @note This differs from QUrl::toLocalFile in also supporting Android content: URLs. 25 | */ 26 | QString toLocalFile(const QUrl &url); 27 | 28 | /** Returns the file name of @p url taking the special case of Android content: URLs into account. */ 29 | QString fileName(const QUrl &url); 30 | 31 | /** Checks whether @p data starts with the magic header of a ZIP file. */ 32 | bool hasZipHeader(const QByteArray &data); 33 | 34 | } 35 | 36 | #endif // FILEHELPER_H 37 | -------------------------------------------------------------------------------- /src/app/genericpkpass.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #include "genericpkpass.h" 7 | 8 | #include 9 | 10 | #include 11 | 12 | class GenericPkPassPrivate : public QSharedData 13 | { 14 | public: 15 | QString name; 16 | QString pkpassPassTypeIdentifier; 17 | QString pkpassSerialNumber; 18 | QDateTime validUntil; 19 | QVariantList subjectOf; 20 | }; 21 | 22 | KITINERARY_MAKE_CLASS(GenericPkPass) 23 | KITINERARY_MAKE_PROPERTY(GenericPkPass, QString, name, setName) 24 | KITINERARY_MAKE_PROPERTY(GenericPkPass, QString, pkpassPassTypeIdentifier, setPkpassPassTypeIdentifier) 25 | KITINERARY_MAKE_PROPERTY(GenericPkPass, QString, pkpassSerialNumber, setPkpassSerialNumber) 26 | KITINERARY_MAKE_PROPERTY(GenericPkPass, QDateTime, validUntil, setValidUntil) 27 | KITINERARY_MAKE_PROPERTY(GenericPkPass, QVariantList, subjectOf, setSubjectOf) 28 | KITINERARY_MAKE_OPERATOR(GenericPkPass) 29 | 30 | #include "moc_genericpkpass.cpp" 31 | -------------------------------------------------------------------------------- /src/app/genericpkpass.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef GENERICPKPASS_H 7 | #define GENERICPKPASS_H 8 | 9 | #include 10 | 11 | class GenericPkPassPrivate; 12 | 13 | /** Pseudo-schema.org wrapper for generic/uninterpreted pkpass files. */ 14 | class GenericPkPass 15 | { 16 | KITINERARY_GADGET(GenericPkPass) 17 | KITINERARY_PROPERTY(QString, name, setName) 18 | KITINERARY_PROPERTY(QString, pkpassPassTypeIdentifier, setPkpassPassTypeIdentifier) 19 | KITINERARY_PROPERTY(QString, pkpassSerialNumber, setPkpassSerialNumber) 20 | KITINERARY_PROPERTY(QDateTime, validUntil, setValidUntil) 21 | KITINERARY_PROPERTY(QVariantList, subjectOf, setSubjectOf) 22 | private: 23 | QExplicitlySharedDataPointer d; 24 | }; 25 | 26 | Q_DECLARE_METATYPE(GenericPkPass) 27 | 28 | #endif // GENERICPKPASS_H 29 | -------------------------------------------------------------------------------- /src/app/gpxexport.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef GPXEXPORT_H 8 | #define GPXEXPORT_H 9 | 10 | #include "gpx/gpxwriter.h" 11 | 12 | namespace KPublicTransport 13 | { 14 | class JourneySection; 15 | } 16 | 17 | class FavoriteLocation; 18 | class Transfer; 19 | 20 | /** Trip group to GPX export. */ 21 | class GpxExport 22 | { 23 | public: 24 | explicit GpxExport(QIODevice *out); 25 | ~GpxExport(); 26 | 27 | void writeReservation(const QVariant &res, const KPublicTransport::JourneySection &journey, const Transfer &before, const Transfer &after); 28 | void writeFavoriteLocation(const FavoriteLocation &fav); 29 | 30 | private: 31 | void writeSelfContainedTransfer(const Transfer &transfer); 32 | void writeTransfer(const Transfer &transfer); 33 | void writeJourneySection(const KPublicTransport::JourneySection §ion); 34 | 35 | Gpx::Writer m_writer; 36 | }; 37 | 38 | #endif // GPXEXPORT_H 39 | -------------------------------------------------------------------------------- /src/app/images/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/app/images/arrow.svg.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2025 Volker Krause 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /src/app/images/images.qrc: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | arrow.svg 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/app/intenthandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2024 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef INTENTHANDLER_H 7 | #define INTENTHANDLER_H 8 | 9 | #include 10 | 11 | class IntentHandlerPrivate; 12 | 13 | namespace KAndroidExtras 14 | { 15 | class Intent; 16 | } 17 | 18 | /** Provides access to incoming Android Intents. */ 19 | class IntentHandler : public QObject 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit IntentHandler(QObject *parent = nullptr); 24 | ~IntentHandler() override; 25 | 26 | Q_SIGNALS: 27 | /** Emitted when a new Intent is received in Android' Activity::onNewIntent. */ 28 | void handleIntent(const KAndroidExtras::Intent &intent); 29 | 30 | private: 31 | friend class IntentHandlerPrivate; 32 | void onNewIntent(const KAndroidExtras::Intent &intent); 33 | static IntentHandler *s_instance; 34 | }; 35 | 36 | #endif // APPLICATIONCONTROLLER_H 37 | -------------------------------------------------------------------------------- /src/app/itinerary.notifyrc.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: none 3 | -------------------------------------------------------------------------------- /src/app/itinerary_version_detailed.h.cmake: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: CC0-1.0 2 | // SPDX-FileCopyrightText: none 3 | 4 | #define ITINERARY_DETAILED_VERSION_STRING "@ITINERARY_DETAILED_VERSION_STRING@" 5 | -------------------------------------------------------------------------------- /src/app/jsonio.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef JSONIO_H 7 | #define JSONIO_H 8 | 9 | class QByteArray; 10 | class QJsonValue; 11 | 12 | /** JSON value to/from (binary) representation conversion for persistent storage. */ 13 | namespace JsonIO 14 | { 15 | /** Read JSON value from textual JSON or CBOR binary. */ 16 | QJsonValue read(const QByteArray &data); 17 | 18 | enum OutputFormat { CBOR, JSON }; 19 | 20 | /** Write JSON value to JSON or CBOR. */ 21 | QByteArray write(const QJsonValue &value, OutputFormat format = CBOR); 22 | 23 | /** Convert binary data to the requested output format. */ 24 | QByteArray convert(const QByteArray &data, OutputFormat format); 25 | } 26 | 27 | #endif // JSONIO_H 28 | -------------------------------------------------------------------------------- /src/app/kdeconnect.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2017-2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KDECONNECT_H 7 | #define KDECONNECT_H 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | class KDEConnectDeviceModel : public QAbstractListModel 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit KDEConnectDeviceModel(QObject *parent = nullptr); 18 | ~KDEConnectDeviceModel(); 19 | 20 | Q_INVOKABLE void refresh(); 21 | 22 | enum { 23 | DeviceNameRole = Qt::DisplayRole, 24 | DeviceIdRole = Qt::UserRole, 25 | }; 26 | 27 | int rowCount(const QModelIndex &parent = {}) const override; 28 | QVariant data(const QModelIndex &index, int role) const override; 29 | QHash roleNames() const override; 30 | 31 | private: 32 | struct Device { 33 | QString deviceId; 34 | QString name; 35 | }; 36 | std::vector m_devices; 37 | }; 38 | 39 | class KDEConnect : public QObject 40 | { 41 | Q_OBJECT 42 | public: 43 | static void sendToDevice(const QString &fileName, const QString &deviceId); 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/app/locationhelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef LOCATIONHELPER_H 8 | #define LOCATIONHELPER_H 9 | 10 | class QString; 11 | class QVariant; 12 | 13 | namespace LocationHelper 14 | { 15 | /** Departing country for location changes, location country otherwise. */ 16 | [[nodiscard]] QString departureCountry(const QVariant &res); 17 | /** Arrival country for location changes, location country otherwise. */ 18 | [[nodiscard]] QString destinationCountry(const QVariant &res); 19 | 20 | /** ISO 3166-1/2 country or region code for @p loc. */ 21 | [[nodiscard]] QString regionCode(const QVariant &loc); 22 | 23 | /** Travel distance for @p res, assuming that is a location change. */ 24 | [[nodiscard]] double distance(const QVariant &res); 25 | } 26 | 27 | #endif // LOCATIONHELPER_H 28 | -------------------------------------------------------------------------------- /src/app/matrixcontroller.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef MATRIXCONTROLLER_H 7 | #define MATRIXCONTROLLER_H 8 | 9 | #include 10 | #include 11 | class MatrixManager; 12 | class MatrixRoomsModel; 13 | class MatrixRoomsSortProxyModel; 14 | 15 | /** Itinerary-specific Matrix integration logic. */ 16 | class MatrixController : public QObject 17 | { 18 | Q_OBJECT 19 | /** Matrix support is built in at all? */ 20 | Q_PROPERTY(bool isAvailable READ isAvailable CONSTANT) 21 | Q_PROPERTY(QObject *manager READ manager CONSTANT) 22 | /** Matrix rooms model. */ 23 | Q_PROPERTY(QAbstractItemModel *roomsModel READ roomsModel CONSTANT) 24 | 25 | public: 26 | explicit MatrixController(QObject *parent = nullptr); 27 | ~MatrixController(); 28 | 29 | static bool isAvailable(); 30 | 31 | QObject *manager() const; 32 | QAbstractItemModel *roomsModel(); 33 | 34 | private: 35 | MatrixManager *m_mgr = nullptr; 36 | MatrixRoomsSortProxyModel *m_roomsModel = nullptr; 37 | }; 38 | 39 | #endif // MATRIXCONTROLLER_H 40 | -------------------------------------------------------------------------------- /src/app/migrator.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2024 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef MIGRATOR_H 7 | 8 | /** Configuration and data format migration. */ 9 | class Migrator 10 | { 11 | public: 12 | /** Perform all necessary migrations. */ 13 | static void run(); 14 | 15 | private: 16 | static void dropTripGroupExpandCollapseState(); 17 | static void moveLiveData(); 18 | }; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/app/navigationcontroller.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef NAVIGATIONCONTROLLER_H 8 | #define NAVIGATIONCONTROLLER_H 9 | 10 | #include 11 | 12 | class QGeoPositionInfo; 13 | class QGeoPositionInfoSource; 14 | class QVariant; 15 | 16 | /** Navigation and map display API for use from QML. */ 17 | class NavigationController 18 | { 19 | Q_GADGET 20 | public: 21 | Q_INVOKABLE void showOnMap(const QVariant &place); 22 | Q_INVOKABLE void showOnMap(double latitude, double longitude, int zoom); 23 | Q_INVOKABLE void showOnWheelmap(double latitude, double longitude); 24 | 25 | Q_INVOKABLE bool canNavigateTo(const QVariant &place); 26 | Q_INVOKABLE void navigateTo(const QVariant &place); 27 | Q_INVOKABLE void navigateTo(const QVariant &from, const QVariant &to); 28 | 29 | private: 30 | #ifndef Q_OS_ANDROID 31 | void navigateTo(const QGeoPositionInfo &from, const QVariant &to); 32 | 33 | QGeoPositionInfoSource *m_positionSource = nullptr; 34 | QMetaObject::Connection m_pendingNavigation; 35 | #endif 36 | }; 37 | 38 | Q_DECLARE_METATYPE(NavigationController) 39 | 40 | #endif // NAVIGATIONCONTROLLER_H 41 | -------------------------------------------------------------------------------- /src/app/nominatimimportjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2025 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef NOMINATIMIMPORTJOB_H 7 | #define NOMINATIMIMPORTJOB_H 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | class QJsonObject; 15 | class QNetworkAccessManager; 16 | class QNetworkReply; 17 | 18 | /** Import restaurants/hotels/etc from OSM data. */ 19 | class NominatimImportJob : public QObject 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit NominatimImportJob(OSM::Type type, OSM::Id id, QNetworkAccessManager *nam, QObject *parent = nullptr); 24 | ~NominatimImportJob(); 25 | 26 | /** Retrieved element. */ 27 | [[nodiscard]] QVariant result() const; 28 | [[nodiscard]] QString errorMessage() const; 29 | 30 | Q_SIGNALS: 31 | /** Emitted when the job finished, regardless of success. 32 | * Deletion of the job afterwards is consumer responsibility. 33 | */ 34 | void finished(); 35 | 36 | private: 37 | void handleReply(QNetworkReply *reply); 38 | 39 | [[nodiscard]] static QVariant convertElement(const QJsonObject &feature); 40 | 41 | OSM::Type m_type = OSM::Type::Null; 42 | OSM::Id m_id = {}; 43 | 44 | QVariant m_result; 45 | QString m_errorMsg; 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/app/notificationconfigcontroller.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "notificationconfigcontroller.h" 8 | 9 | #ifdef Q_OS_ANDROID 10 | #include "kandroidextras/activity.h" 11 | #include "kandroidextras/context.h" 12 | #include "kandroidextras/intent.h" 13 | #include "kandroidextras/settings.h" 14 | #endif 15 | 16 | #include 17 | 18 | bool NotificationConfigController::canConfigureNotification() const 19 | { 20 | #ifdef Q_OS_ANDROID 21 | return true; 22 | #else 23 | return false; // TODO 24 | #endif 25 | } 26 | 27 | bool NotificationConfigController::canShowOnLockScreen() const 28 | { 29 | #if defined(Q_OS_ANDROID) 30 | return true; 31 | #else 32 | return false; 33 | #endif 34 | } 35 | 36 | void NotificationConfigController::configureNotifications() 37 | { 38 | #ifdef Q_OS_ANDROID 39 | using namespace KAndroidExtras; 40 | 41 | Intent intent; 42 | intent.setAction(Settings::ACTION_APP_NOTIFICATION_SETTINGS); 43 | intent.putExtra(Settings::EXTRA_APP_PACKAGE, Context::getPackageName()); 44 | Activity::startActivity(intent, 0); 45 | #else 46 | // TODO 47 | #endif 48 | } 49 | 50 | #include "moc_notificationconfigcontroller.cpp" 51 | -------------------------------------------------------------------------------- /src/app/notificationconfigcontroller.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef NOTIFICATIONCONFIGCONTROLLER_H 8 | #define NOTIFICATIONCONFIGCONTROLLER_H 9 | 10 | #include 11 | 12 | /** QML interface for notification configuration. */ 13 | class NotificationConfigController 14 | { 15 | Q_GADGET 16 | Q_PROPERTY(bool canConfigureNotification READ canConfigureNotification) 17 | Q_PROPERTY(bool canShowOnLockScreen READ canShowOnLockScreen) 18 | public: 19 | /** Notification configuration dialog is available on this platform. */ 20 | bool canConfigureNotification() const; 21 | /** Platform supports lock-screen visibility. */ 22 | bool canShowOnLockScreen() const; 23 | 24 | /** Show notification config dialog. */ 25 | Q_INVOKABLE void configureNotifications(); 26 | }; 27 | 28 | Q_DECLARE_METATYPE(NotificationConfigController) 29 | 30 | #endif // NOTIFICATIONCONFIGCONTROLLER_H 31 | -------------------------------------------------------------------------------- /src/app/notificationhelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef NOTIFICATIONHELPER_H 8 | #define NOTIFICATIONHELPER_H 9 | 10 | #include "livedata.h" 11 | 12 | namespace KPublicTransport 13 | { 14 | class Stopover; 15 | } 16 | 17 | /** Helper methods for generating notifications about itinerary changes. */ 18 | namespace NotificationHelper 19 | { 20 | /** Checks whether something relevant changed and we should notify about this. */ 21 | bool shouldNotify(const KPublicTransport::Stopover &oldStop, const KPublicTransport::Stopover &newStop, LiveData::Type context); 22 | 23 | /** Returns the title string for the disruption notification for @p data. */ 24 | QString title(const LiveData &data); 25 | /** Returns the message text for the disruption notification for @p data. */ 26 | QString message(const LiveData &data); 27 | } 28 | 29 | #endif // NOTIFICATIONHELPER_H 30 | -------------------------------------------------------------------------------- /src/app/notifyrc.qrc: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | itinerary.notifyrc 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/app/onlineimport/sncf.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-FileCopyrightText: 2023 Carl Schwan 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | import QtQuick 8 | import QtQuick.Layouts 9 | import QtQuick.Controls as QQC2 10 | import org.kde.kirigami as Kirigami 11 | import org.kde.kirigamiaddons.formcard as FormCard 12 | import org.kde.itinerary 13 | 14 | ColumnLayout { 15 | id: root 16 | 17 | property var arguments: { 18 | if (nameInput.text === "" || bookingReferenceInput.text.length !== 6) { 19 | return undefined; 20 | } 21 | return { name: nameInput.text, reference: bookingReferenceInput.text }; 22 | } 23 | 24 | signal search() 25 | 26 | FormCard.FormTextFieldDelegate { 27 | id: nameInput 28 | label: i18n("Family name") 29 | // TODO can we prefill this with the user name 30 | text: Settings.read("OnlineImport/Name", "") 31 | onEditingFinished: Settings.write("OnlineImport/Name", nameInput.text) 32 | } 33 | 34 | FormCard.FormDelegateSeparator {} 35 | 36 | FormCard.FormTextFieldDelegate { 37 | id: bookingReferenceInput 38 | label: i18n("Booking reference") 39 | placeholderText: "ABC123" 40 | onAccepted: root.search() 41 | } 42 | 43 | Component.onCompleted: { 44 | if (nameInput.text === "") { 45 | nameInput.forceActiveFocus(); 46 | } else { 47 | bookingReferenceInput.forceActiveFocus(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/app/org.kde.itinerary.desktop.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: none 3 | -------------------------------------------------------------------------------- /src/app/osmimportjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2024 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef OSMIMPORTJOB_H 7 | #define OSMIMPORTJOB_H 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace OSM 15 | { 16 | class Element; 17 | } 18 | 19 | class QNetworkAccessManager; 20 | class QNetworkReply; 21 | 22 | /** Import restaurants/hotels/etc from OSM data. */ 23 | class OsmImportJob : public QObject 24 | { 25 | Q_OBJECT 26 | public: 27 | explicit OsmImportJob(OSM::Type type, OSM::Id id, QNetworkAccessManager *nam, QObject *parent = nullptr); 28 | ~OsmImportJob(); 29 | 30 | /** Retrieved element. */ 31 | [[nodiscard]] QVariant result() const; 32 | [[nodiscard]] QString errorMessage() const; 33 | 34 | Q_SIGNALS: 35 | /** Emitted when the job finished, regardless of success. 36 | * Deletion of the job afterwards is consumer responsibility. 37 | */ 38 | void finished(); 39 | 40 | private: 41 | void handleReply(QNetworkReply *reply); 42 | 43 | [[nodiscard]] static QVariant convertElement(OSM::Element e); 44 | 45 | OSM::Type m_type = OSM::Type::Null; 46 | OSM::Id m_id = {}; 47 | 48 | QVariant m_result; 49 | QString m_errorMsg; 50 | }; 51 | 52 | #endif // OSMIMPORTJOB_H 53 | -------------------------------------------------------------------------------- /src/app/permissionmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef PERMISSIONMANAGER_H 7 | #define PERMISSIONMANAGER_H 8 | 9 | #include 10 | 11 | /** Permission enum for use in QML. */ 12 | namespace Permission 13 | { 14 | Q_NAMESPACE 15 | enum Permission { 16 | InvalidPermission, // captures QML errors resultin in "0" enum values 17 | ReadCalendar, 18 | WriteCalendar, 19 | Camera, 20 | }; 21 | Q_ENUM_NS(Permission) 22 | } 23 | 24 | /** Check and request platform permissions for access to controlled resources (calendar, location, etc). */ 25 | class PermissionManager 26 | { 27 | Q_GADGET 28 | public: 29 | Q_INVOKABLE static bool checkPermission(Permission::Permission permission); 30 | Q_INVOKABLE static void requestPermission(Permission::Permission permission, QJSValue callback); 31 | }; 32 | 33 | #endif // PERMISSIONMANAGER_H 34 | -------------------------------------------------------------------------------- /src/app/pkpassimageprovider.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef PKPASSIMAGEPROVIDER_H 8 | #define PKPASSIMAGEPROVIDER_H 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace KPkPass 16 | { 17 | class Pass; 18 | } 19 | 20 | /** QML image provider for PkPass assets. */ 21 | class PkPassImageProvider : public QQuickImageProvider 22 | { 23 | public: 24 | explicit PkPassImageProvider(); 25 | ~PkPassImageProvider(); 26 | 27 | void registerPassProvider(std::function &&passProvider); 28 | 29 | [[nodiscard]] QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override; 30 | 31 | private: 32 | Q_DISABLE_COPY(PkPassImageProvider) 33 | 34 | std::vector> m_passProviders; 35 | }; 36 | 37 | #endif // PKPASSIMAGEPROVIDER_H 38 | -------------------------------------------------------------------------------- /src/app/sc-apps-org.kde.itinerary.svg.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Mathis Brüchert 2 | SPDX-License-Identifier: LGPL-2.0-or-later 3 | -------------------------------------------------------------------------------- /src/app/statisticstimerangemodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef STATISTICSTIMERANGEMODEL_H 8 | #define STATISTICSTIMERANGEMODEL_H 9 | 10 | #include 11 | 12 | class ReservationManager; 13 | 14 | /** Selectable time ranges for the statistics page. */ 15 | class StatisticsTimeRangeModel : public QAbstractListModel 16 | { 17 | Q_OBJECT 18 | Q_PROPERTY(ReservationManager *reservationManager READ reservationManager WRITE setReservationManager NOTIFY setupChanged) 19 | 20 | public: 21 | explicit StatisticsTimeRangeModel(QObject *parent = nullptr); 22 | ~StatisticsTimeRangeModel() override; 23 | 24 | enum CustomRoles { BeginRole = Qt::UserRole, EndRole }; 25 | Q_ENUM(CustomRoles); 26 | 27 | ReservationManager *reservationManager() const; 28 | void setReservationManager(ReservationManager *resMgr); 29 | 30 | int rowCount(const QModelIndex &parent = {}) const override; 31 | QVariant data(const QModelIndex &index, int role) const override; 32 | QHash roleNames() const override; 33 | 34 | Q_SIGNALS: 35 | void setupChanged(); 36 | 37 | private: 38 | ReservationManager *m_resMgr = nullptr; 39 | std::vector m_years; 40 | }; 41 | 42 | #endif // STATISTICSTIMERANGEMODEL_H 43 | -------------------------------------------------------------------------------- /src/app/transferdelegatecontroller.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef TRANSFERDELEGATECONTROLLER_H 8 | #define TRANSFERDELEGATECONTROLLER_H 9 | 10 | #include "transfer.h" 11 | 12 | #include 13 | #include 14 | 15 | /** Transfer delegate logic. */ 16 | class TransferDelegateController : public QObject 17 | { 18 | Q_OBJECT 19 | Q_PROPERTY(Transfer transfer READ transfer WRITE setTransfer NOTIFY transferChanged) 20 | Q_PROPERTY(bool isCurrent READ isCurrent NOTIFY updated) 21 | Q_PROPERTY(float progress READ progress NOTIFY updated) 22 | 23 | public: 24 | explicit TransferDelegateController(QObject *parent = nullptr); 25 | ~TransferDelegateController(); 26 | 27 | Transfer transfer() const; 28 | void setTransfer(const Transfer &transfer); 29 | 30 | bool isCurrent() const; 31 | float progress() const; 32 | 33 | Q_SIGNALS: 34 | void transferChanged(); 35 | void updated(); 36 | 37 | private: 38 | void scheduleTimer(); 39 | 40 | Transfer m_transfer; 41 | QTimer m_updateTrigger; 42 | }; 43 | 44 | #endif // TRANSFERDELEGATECONTROLLER_H 45 | -------------------------------------------------------------------------------- /src/app/tripgroupfilterproxymodel.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2024 Volker Krause 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | #include "tripgroupfilterproxymodel.h" 5 | 6 | #include "tripgroupmodel.h" 7 | 8 | TripGroupFilterProxyModel::TripGroupFilterProxyModel(QObject *parent) 9 | : QSortFilterProxyModel(parent) 10 | { 11 | } 12 | 13 | TripGroupFilterProxyModel::~TripGroupFilterProxyModel() = default; 14 | 15 | QStringList TripGroupFilterProxyModel::filteredGroupIds() const 16 | { 17 | return m_groupIds; 18 | } 19 | 20 | void TripGroupFilterProxyModel::setFilteredGroupIds(const QStringList &groupIds) 21 | { 22 | if (m_groupIds == groupIds) { 23 | return; 24 | } 25 | 26 | m_groupIds = groupIds; 27 | std::sort(m_groupIds.begin(), m_groupIds.end()); 28 | Q_EMIT filteredGroupIdsChanged(); 29 | invalidateRowsFilter(); 30 | } 31 | 32 | bool TripGroupFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const 33 | { 34 | const auto srcIdx = sourceModel()->index(source_row, 0, source_parent); 35 | const auto tgId = sourceModel()->data(srcIdx, TripGroupModel::TripGroupIdRole).toString(); 36 | return std::binary_search(m_groupIds.begin(), m_groupIds.end(), tgId); 37 | } 38 | 39 | #include "moc_tripgroupfilterproxymodel.cpp" 40 | -------------------------------------------------------------------------------- /src/app/tripgroupfilterproxymodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2024 Volker Krause 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | #ifndef TRIPGROUPFILTERPROXYMODEL_H 5 | #define TRIPGROUPFILTERPROXYMODEL_H 6 | 7 | #include 8 | 9 | /** Filter proxy model to show only a specified set of trip groups. 10 | * Used e.g. for selecting candidates to add to/merge with. 11 | */ 12 | class TripGroupFilterProxyModel : public QSortFilterProxyModel 13 | { 14 | Q_OBJECT 15 | Q_PROPERTY(QStringList filteredGroupIds READ filteredGroupIds WRITE setFilteredGroupIds NOTIFY filteredGroupIdsChanged) 16 | public: 17 | explicit TripGroupFilterProxyModel(QObject *parent = nullptr); 18 | ~TripGroupFilterProxyModel(); 19 | 20 | [[nodiscard]] QStringList filteredGroupIds() const; 21 | void setFilteredGroupIds(const QStringList &groupIds); 22 | 23 | Q_SIGNALS: 24 | void filteredGroupIdsChanged(); 25 | 26 | protected: 27 | [[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; 28 | 29 | private: 30 | QStringList m_groupIds; 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/app/unitconversion.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #include "unitconversion.h" 7 | #include "logging.h" 8 | 9 | #include 10 | 11 | #include 12 | 13 | double UnitConversion::convertCurrency(double price, const QString &fromCurrency, const QString &toCurrency) 14 | { 15 | if (fromCurrency.isEmpty() || toCurrency.isEmpty() || fromCurrency == toCurrency) { 16 | return NAN; 17 | } 18 | 19 | const auto value = KUnitConversion::Value(price, fromCurrency).convertTo(toCurrency); 20 | return value.isValid() ? value.number() : NAN; 21 | } 22 | 23 | #include "moc_unitconversion.cpp" 24 | -------------------------------------------------------------------------------- /src/app/unitconversion.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef UNITCONVERSION_H 7 | #define UNITCONVERSION_H 8 | 9 | #include 10 | 11 | /** QML access to KUnitConversion. */ 12 | class UnitConversion 13 | { 14 | Q_GADGET 15 | public: 16 | Q_INVOKABLE static double convertCurrency(double value, const QString &fromCurrency, const QString &toCurrency); 17 | }; 18 | 19 | #endif // PERMISSIONMANAGER_H 20 | -------------------------------------------------------------------------------- /src/app/weatherforecastmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef WEATHERFORECASTMODEL_H 8 | #define WEATHERFORECASTMODEL_H 9 | 10 | #include "weatherforecast.h" 11 | 12 | #include 13 | 14 | class WeatherForecastManager; 15 | 16 | /** Weather forecast details page model. */ 17 | class WeatherForecastModel : public QAbstractListModel 18 | { 19 | Q_OBJECT 20 | Q_PROPERTY(QObject *weatherForecastManager READ weatherForecastManager WRITE setWeatherForecastManager) 21 | Q_PROPERTY(QVariant weatherForecast READ weatherForecast WRITE setWeatherForecast) 22 | public: 23 | enum Roles { WeatherForecastRole = Qt::UserRole, LocalizedTimeRole }; 24 | 25 | explicit WeatherForecastModel(QObject *parent = nullptr); 26 | ~WeatherForecastModel() override; 27 | 28 | int rowCount(const QModelIndex &parent) const override; 29 | QVariant data(const QModelIndex &index, int role) const override; 30 | QHash roleNames() const override; 31 | 32 | QObject *weatherForecastManager() const; 33 | void setWeatherForecastManager(QObject *mgr); 34 | QVariant weatherForecast() const; 35 | void setWeatherForecast(const QVariant &fc); 36 | 37 | private: 38 | WeatherForecastManager *m_mgr = nullptr; 39 | WeatherForecast m_fc; 40 | }; 41 | 42 | #endif // WEATHERFORECASTMODEL_H 43 | -------------------------------------------------------------------------------- /src/app/weatherinformation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #include "weatherinformation.h" 7 | 8 | #include 9 | #include 10 | 11 | using namespace KItinerary; 12 | 13 | QString WeatherInformation::labelForPlace(const QVariant &place) 14 | { 15 | // TODO add fallbacks to region if we have no better name 16 | const auto addr = LocationUtil::address(place); 17 | if (!addr.addressLocality().isEmpty()) { 18 | return addr.addressLocality(); 19 | } 20 | return LocationUtil::name(place); 21 | } 22 | 23 | #include "moc_weatherinformation.cpp" 24 | -------------------------------------------------------------------------------- /src/app/weatherinformation.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2023 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef WEATHERINFORMATION_H 7 | #define WEATHERINFORMATION_H 8 | 9 | #include "weatherforecast.h" 10 | 11 | #include 12 | 13 | /** Holds weather information for display in the timeline. */ 14 | class WeatherInformation 15 | { 16 | Q_GADGET 17 | Q_PROPERTY(WeatherForecast forecast MEMBER forecast CONSTANT) 18 | Q_PROPERTY(QString locationName MEMBER locationName CONSTANT) 19 | public: 20 | WeatherForecast forecast; 21 | QString locationName; 22 | 23 | static QString labelForPlace(const QVariant &place); 24 | }; 25 | 26 | Q_DECLARE_METATYPE(WeatherInformation) 27 | 28 | #endif // WEATHERINFORMATION_H 29 | -------------------------------------------------------------------------------- /src/calendarextras/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | if (ANDROID) 5 | add_library(KCalendarCoreExtras) 6 | else() 7 | add_library(KCalendarCoreExtras STATIC) 8 | endif() 9 | generate_export_header(KCalendarCoreExtras BASE_NAME KCalendarCoreExtras) 10 | 11 | target_sources(KCalendarCoreExtras PRIVATE 12 | integration.cpp 13 | ) 14 | 15 | if (ANDROID) 16 | add_subdirectory(android) 17 | target_sources(KCalendarCoreExtras PRIVATE 18 | androidcalendar.cpp 19 | androidcalendarplugin.cpp 20 | androidicalconverter.cpp 21 | ) 22 | target_compile_definitions(KCalendarCoreExtras PRIVATE -DQT_STATICPLUGIN) 23 | target_link_libraries(KCalendarCoreExtras PRIVATE KAndroidExtras LibIcal) 24 | endif() 25 | 26 | target_link_libraries(KCalendarCoreExtras PUBLIC KF6::CalendarCore) 27 | 28 | if (ANDROID) 29 | install(TARGETS KCalendarCoreExtras ${KF_INSTALL_TARGETS_DEFAULT_ARGS}) 30 | endif() 31 | -------------------------------------------------------------------------------- /src/calendarextras/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/calendarextras/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | gradle_add_aar(calendarextras_aar BUILDFILE ${CMAKE_CURRENT_SOURCE_DIR}/build.gradle NAME KCalendarCoreExtras) 5 | gradle_install_aar(calendarextras_aar DESTINATION jar) 6 | 7 | configure_file( 8 | ${CMAKE_CURRENT_SOURCE_DIR}/KCalendarCoreExtras-android-dependencies.xml 9 | ${CMAKE_BINARY_DIR}/lib/KCalendarCoreExtras_${CMAKE_ANDROID_ARCH_ABI}-android-dependencies.xml 10 | ) 11 | install(FILES KCalendarCoreExtras-android-dependencies.xml DESTINATION ${KDE_INSTALL_LIBDIR} RENAME KCalendarCoreExtras_${CMAKE_ANDROID_ARCH_ABI}-android-dependencies.xml) 12 | -------------------------------------------------------------------------------- /src/calendarextras/android/KCalendarCoreExtras-android-dependencies.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/calendarextras/android/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | buildscript { 7 | repositories { 8 | google() 9 | jcenter() 10 | } 11 | 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:@Gradle_ANDROID_GRADLE_PLUGIN_VERSION@' 14 | } 15 | } 16 | 17 | repositories { 18 | google() 19 | jcenter() 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | buildToolsVersion '@ANDROID_SDK_BUILD_TOOLS_REVISION@' 26 | compileSdkVersion @ANDROID_SDK_COMPILE_API@ 27 | 28 | sourceSets { 29 | main { 30 | manifest.srcFile '@CMAKE_CURRENT_SOURCE_DIR@/AndroidManifest.xml' 31 | java.srcDirs = ['@CMAKE_CURRENT_SOURCE_DIR@/org'] 32 | } 33 | } 34 | 35 | compileOptions { 36 | sourceCompatibility JavaVersion.VERSION_1_8 37 | targetCompatibility JavaVersion.VERSION_1_8 38 | } 39 | 40 | lintOptions { 41 | abortOnError false 42 | } 43 | 44 | defaultConfig { 45 | minSdkVersion @ANDROID_API_LEVEL@ 46 | targetSdkVersion @ANDROID_SDK_COMPILE_API@ 47 | namespace "org.kde.kcalendarcore" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/calendarextras/android/calendar.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KCALENDARCORE_JNI_CALENDAR_H 7 | #define KCALENDARCORE_JNI_CALENDAR_H 8 | 9 | #include "eventdata.h" 10 | 11 | #include "kandroidextras/androidtypes.h" 12 | #include "kandroidextras/javatypes.h" 13 | #include "kandroidextras/jnimethod.h" 14 | #include "kandroidextras/jniobject.h" 15 | #include "kandroidextras/jniproperty.h" 16 | #include "kandroidextras/jnitypes.h" 17 | 18 | JNI_TYPE(org, kde, kcalendarcore, Calendar) 19 | 20 | /** JNI wrapper for the CalendarPlugin class. */ 21 | class JniCalendar 22 | { 23 | JNI_OBJECT(JniCalendar, org::kde::kcalendarcore::Calendar) 24 | public: 25 | JNI_CONSTRUCTOR(JniCalendar, KAndroidExtras::android::content::Context, jlong) 26 | JNI_METHOD(Jni::Array, rawEvents) 27 | JNI_METHOD(Jni::Array, rawEvents, jlong, jlong, bool) 28 | JNI_METHOD(bool, addEvent, JniEventData) 29 | JNI_METHOD(JniEventData, event, KAndroidExtras::java::lang::String) 30 | JNI_METHOD(JniEventData, event, KAndroidExtras::java::lang::String, jlong) 31 | JNI_METHOD(bool, deleteEvent, KAndroidExtras::java::lang::String) 32 | JNI_METHOD(bool, deleteEvent, KAndroidExtras::java::lang::String, jlong) 33 | JNI_METHOD(bool, deleteEventInstances, KAndroidExtras::java::lang::String) 34 | JNI_METHOD(Jni::Array, eventInstances, KAndroidExtras::java::lang::String) 35 | JNI_METHOD(bool, updateEvent, JniEventData, bool, bool) 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/calendarextras/android/calendardata.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KCALENDARCORE_JNI_CALENDARDATA_H 7 | #define KCALENDARCORE_JNI_CALENDARDATA_H 8 | 9 | #include "kandroidextras/javatypes.h" 10 | #include "kandroidextras/jniobject.h" 11 | #include "kandroidextras/jniproperty.h" 12 | #include "kandroidextras/jnitypes.h" 13 | 14 | JNI_TYPE(org, kde, kcalendarcore, CalendarData) 15 | 16 | /** JNI wrapper for the CalendarPlugin class. */ 17 | class JniCalendarData 18 | { 19 | JNI_OBJECT(JniCalendarData, org::kde::kcalendarcore::CalendarData) 20 | public: 21 | JNI_PROPERTY(jlong, id) 22 | JNI_PROPERTY(KAndroidExtras::java::lang::String, displayName) 23 | JNI_PROPERTY(jint, accessLevel) 24 | JNI_PROPERTY(jint, color) 25 | JNI_PROPERTY(KAndroidExtras::java::lang::String, timezone) 26 | JNI_PROPERTY(KAndroidExtras::java::lang::String, owner) 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/calendarextras/android/calendarplugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KCALENDARCORE_JNI_CALENDARPLUGIN_H 7 | #define KCALENDARCORE_JNI_CALENDARPLUGIN_H 8 | 9 | #include "calendardata.h" 10 | 11 | #include "kandroidextras/androidtypes.h" 12 | #include "kandroidextras/javatypes.h" 13 | #include "kandroidextras/jnimethod.h" 14 | #include "kandroidextras/jniproperty.h" 15 | #include "kandroidextras/jnitypes.h" 16 | 17 | JNI_TYPE(org, kde, kcalendarcore, CalendarPlugin) 18 | 19 | /** JNI wrapper for the CalendarPlugin class. */ 20 | class JniCalendarPlugin 21 | { 22 | JNI_OBJECT(JniCalendarPlugin, org::kde::kcalendarcore::CalendarPlugin) 23 | public: 24 | JNI_CONSTRUCTOR(JniCalendarPlugin, KAndroidExtras::android::content::Context) 25 | JNI_METHOD(KAndroidExtras::Jni::Array, getCalendars) 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/calendarextras/android/org/kde/kcalendarcore/AttendeeData.java: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | package org.kde.kcalendarcore; 7 | 8 | /** Struct for transferring event attendee data over JNI. */ 9 | public class AttendeeData 10 | { 11 | public AttendeeData() {} 12 | 13 | public java.lang.String name; 14 | public java.lang.String email; 15 | int relationship; 16 | int type; 17 | int status; 18 | } 19 | -------------------------------------------------------------------------------- /src/calendarextras/android/org/kde/kcalendarcore/CalendarData.java: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | package org.kde.kcalendarcore; 7 | 8 | /** Struct for transferring calendar data over JNI. */ 9 | public class CalendarData 10 | { 11 | public long id; 12 | public java.lang.String displayName; 13 | public int accessLevel; 14 | public int color; 15 | public java.lang.String timezone; 16 | public java.lang.String owner; 17 | } 18 | -------------------------------------------------------------------------------- /src/calendarextras/android/org/kde/kcalendarcore/ExtendedPropertyData.java: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | package org.kde.kcalendarcore; 7 | 8 | /** Struct for transferring event extended property data over JNI. */ 9 | public class ExtendedPropertyData 10 | { 11 | public ExtendedPropertyData() {} 12 | 13 | public java.lang.String name; 14 | public java.lang.String value; 15 | } 16 | -------------------------------------------------------------------------------- /src/calendarextras/android/org/kde/kcalendarcore/ReminderData.java: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | package org.kde.kcalendarcore; 7 | 8 | /** Struct for transferring event reminder data over JNI. */ 9 | public class ReminderData 10 | { 11 | public ReminderData() {} 12 | 13 | public int minutes; 14 | public int method; 15 | } 16 | -------------------------------------------------------------------------------- /src/calendarextras/androidcalendarplugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KCALENDARCORE_ANDROIDCALENDARPLUGIN_H 7 | #define KCALENDARCORE_ANDROIDCALENDARPLUGIN_H 8 | 9 | #include "android/calendarplugin.h" 10 | 11 | #include 12 | 13 | /** Android system calendar plugin. */ 14 | class AndroidCalendarPlugin : public KCalendarCore::CalendarPlugin 15 | { 16 | Q_OBJECT 17 | Q_PLUGIN_METADATA(IID "org.kde.kcalendarcore.CalendarPlugin") 18 | public: 19 | explicit AndroidCalendarPlugin(QObject *parent = nullptr, const QVariantList &args = {}); 20 | ~AndroidCalendarPlugin(); 21 | 22 | QList calendars() const override; 23 | 24 | private: 25 | void loadCalendars() const; 26 | 27 | mutable QList m_calendars; 28 | JniCalendarPlugin m_jni; 29 | }; 30 | 31 | #endif // KCALENDARCORE_ANDROIDCALENDARPLUGIN_H 32 | -------------------------------------------------------------------------------- /src/calendarextras/incidencekey_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KCALENDARCORE_INCIDENCEKEY_P_H 7 | #define KCALENDARCORE_INCIDENCEKEY_P_H 8 | 9 | #include 10 | #include 11 | 12 | /** A hash key for Incidences containing uid and recurrence id (if present). */ 13 | struct IncidenceKey { 14 | QString uid; 15 | QDateTime recurrenceId; 16 | 17 | inline bool operator==(const IncidenceKey &other) const 18 | { 19 | return uid == other.uid && (recurrenceId.isValid() == other.recurrenceId.isValid()) && (!recurrenceId.isValid() || recurrenceId == other.recurrenceId); 20 | } 21 | }; 22 | 23 | namespace std 24 | { 25 | template<> 26 | class hash 27 | { 28 | public: 29 | std::size_t operator()(const IncidenceKey &key) const 30 | { 31 | return std::hash{}(key.uid) ^ std::hash{}(key.recurrenceId.toSecsSinceEpoch()); 32 | } 33 | }; 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/calendarextras/integration.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #include 7 | 8 | #ifdef Q_OS_ANDROID 9 | #include "androidcalendarplugin.h" 10 | Q_IMPORT_PLUGIN(AndroidCalendarPlugin) 11 | #endif 12 | -------------------------------------------------------------------------------- /src/gpx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2021 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_library(GpxIo STATIC 5 | gpxreader.cpp 6 | gpxwriter.cpp 7 | ) 8 | target_include_directories(GpxIo PUBLIC "$") 9 | target_link_libraries(GpxIo PUBLIC Qt::Core) 10 | -------------------------------------------------------------------------------- /src/gpx/gpxreader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "gpxreader.h" 8 | 9 | bool Gpx::Reader::isRootElement() const 10 | { 11 | return isStartElement() && name() == QLatin1StringView("gpx"); 12 | } 13 | 14 | bool Gpx::Reader::isWaypointStart() const 15 | { 16 | return isStartElement() && name() == QLatin1StringView("wpt"); 17 | } 18 | 19 | bool Gpx::Reader::isWaypointEnd() const 20 | { 21 | return isEndElement() && name() == QLatin1StringView("wpt"); 22 | } 23 | 24 | double Gpx::Reader::latitude() const 25 | { 26 | return attributes().value(QLatin1StringView("lat")).toFloat(); 27 | } 28 | 29 | double Gpx::Reader::longitude() const 30 | { 31 | return attributes().value(QLatin1StringView("lon")).toFloat(); 32 | } 33 | 34 | bool Gpx::Reader::isGpxName() const 35 | { 36 | return isStartElement() && name() == QLatin1StringView("name"); 37 | } 38 | 39 | QString Gpx::Reader::gpxName() 40 | { 41 | return readElementText(); 42 | } 43 | 44 | bool Gpx::Reader::isGpxType() const 45 | { 46 | return isStartElement() && name() == QLatin1StringView("type"); 47 | } 48 | 49 | QString Gpx::Reader::gpxType() 50 | { 51 | return readElementText(); 52 | } 53 | -------------------------------------------------------------------------------- /src/gpx/gpxreader.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef GPX_READER_H 8 | #define GPX_READER_H 9 | 10 | #include 11 | 12 | namespace Gpx 13 | { 14 | 15 | /** GPX reader. */ 16 | class Reader : public QXmlStreamReader 17 | { 18 | public: 19 | using QXmlStreamReader::QXmlStreamReader; 20 | 21 | /** Returns @c true for the top-level element. */ 22 | bool isRootElement() const; 23 | 24 | /** Returns @c true if we are positioned on a waypoint start element. */ 25 | bool isWaypointStart() const; 26 | /** Returns @c true if we are positioned on a waypoint end element. */ 27 | bool isWaypointEnd() const; 28 | 29 | /** Returns the latitude of the current waypoint, route point or track point. */ 30 | double latitude() const; 31 | /** Returns the longitude of the current waypoint, route point or track point. */ 32 | double longitude() const; 33 | 34 | /** Returns @c true if the current element is a name property. */ 35 | bool isGpxName() const; 36 | /** Returns the value of a GPX name property. */ 37 | QString gpxName(); 38 | /** Returns @c true if the current element is a GPX type property. */ 39 | bool isGpxType() const; 40 | /** Returns the value of a GPX type property. */ 41 | QString gpxType(); 42 | }; 43 | 44 | } 45 | 46 | #endif // GPX_READER_H 47 | -------------------------------------------------------------------------------- /src/gpx/gpxwriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef GPX_WRITER_H 8 | #define GPX_WRITER_H 9 | 10 | #include 11 | 12 | class QDateTime; 13 | class QIODevice; 14 | 15 | namespace Gpx 16 | { 17 | 18 | /** GPX file writer. 19 | * @see https://www.topografix.com/GPX/1/1/ 20 | */ 21 | class Writer 22 | { 23 | public: 24 | explicit Writer(QIODevice *device); 25 | ~Writer(); 26 | 27 | void writeStartMetadata(); 28 | void writeEndMetadata(); 29 | 30 | void writeStartRoute(); 31 | void writeEndRoute(); 32 | 33 | void writeStartWaypoint(double latitude, double longitude); 34 | void writeEndWaypoint(); 35 | 36 | void writeStartRoutePoint(double latitude, double longitude); 37 | void writeEndRoutePoint(); 38 | 39 | void writeName(const QString &name); 40 | void writeLink(const QString &href, const QString &text); 41 | void writeTime(const QDateTime &time); 42 | 43 | private: 44 | QXmlStreamWriter m_writer; 45 | }; 46 | 47 | } 48 | 49 | #endif // GPX_WRITER_H 50 | -------------------------------------------------------------------------------- /src/kandroidextras/README.md: -------------------------------------------------------------------------------- 1 | # KAndroidExtras 2 | 3 | Utilities for using Java Native Interface (JNI) to interface with Android platform API. 4 | 5 | ## Java Native Interface (JNI) wrapper 6 | 7 | C++ header-only code for defining compile-time checked JNI wrappers. 8 | 9 | Supported: 10 | - typed `jobject` wrappers (`Jni::Object`) 11 | - wrappers for Java arrays holding primitive or non-primitive content (`Jni::Array`) 12 | - reading static final properties (`JNI_CONSTANT`) 13 | - reading and writing non-static properties (`JNI_PROPERTY`) 14 | - static and non-static method calls, constructors (`JNI_METHOD`, `JNI_STATIC_METHOD`, `JNI_CONSTRUCTOR`) 15 | 16 | Not yet supported: 17 | - registering native methods for Java -> C++ calls 18 | 19 | ## JNI mock implementation 20 | 21 | This is useful for automated testing of JNI code on other platforms than Android. 22 | 23 | ## Wrappers for Java and Android types 24 | 25 | Predefined wrappers for common platform types needed in multiple places. 26 | -------------------------------------------------------------------------------- /src/kandroidextras/README.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2022 Volker Krause 2 | SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /src/kandroidextras/android/activity.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "activity.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "private/qandroidextras_p.h" 14 | #include 15 | #include 16 | 17 | using namespace KAndroidExtras; 18 | 19 | Intent Activity::getIntent() 20 | { 21 | const QJniObject activity = QNativeInterface::QAndroidApplication::context(); 22 | if (!activity.isValid()) 23 | return {}; 24 | 25 | const auto intent = activity.callObjectMethod("getIntent", Jni::signature()); 26 | return Intent(Jni::fromHandle(intent)); 27 | } 28 | 29 | bool Activity::startActivity(const Intent &intent, int receiverRequestCode) 30 | { 31 | QJniEnvironment jniEnv; 32 | QtAndroidPrivate::startActivity(intent, receiverRequestCode); 33 | if (jniEnv->ExceptionCheck()) { 34 | jniEnv->ExceptionClear(); 35 | return false; 36 | } 37 | return true; 38 | } 39 | -------------------------------------------------------------------------------- /src/kandroidextras/android/activity.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_ACTIVITY_H 8 | #define KANDROIDEXTRAS_ACTIVITY_H 9 | 10 | #include "kandroidextras_export.h" 11 | 12 | namespace KAndroidExtras 13 | { 14 | 15 | class Intent; 16 | 17 | /** Methods around android.app.Activity. */ 18 | namespace Activity 19 | { 20 | /** Returns the Intent that started the activity. */ 21 | KANDROIDEXTRAS_EXPORT Intent getIntent(); 22 | 23 | /** Same as QtAndroid::startActivity(), but with exception handling. */ 24 | KANDROIDEXTRAS_EXPORT bool startActivity(const Intent &intent, int receiverRequestCode); // TODO add callback arg 25 | } 26 | 27 | } 28 | 29 | #endif // KANDROIDEXTRAS_ACTIVITY_H 30 | -------------------------------------------------------------------------------- /src/kandroidextras/android/android_headers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | // list all headers here that have no .cpp file 8 | // this only serves as a guarantee that these headers actually compile 9 | #include "androidtypes.h" 10 | #include "calendarcontract.h" 11 | #include "manifestpermission.h" 12 | #include "openablecolumns.h" 13 | #include "settings.h" 14 | -------------------------------------------------------------------------------- /src/kandroidextras/android/androidtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_ANDROIDTYPES_H 8 | #define KANDROIDEXTRAS_ANDROIDTYPES_H 9 | 10 | #include 11 | 12 | namespace KAndroidExtras 13 | { 14 | 15 | JNI_TYPE(android, content, ContentResolver) 16 | JNI_TYPE(android, content, Context) 17 | JNI_TYPE(android, content, Intent) 18 | JNI_TYPE(android, database, Cursor) 19 | JNI_NESTED_TYPE(android, Manifest, permission) 20 | JNI_TYPE(android, net, Uri) 21 | JNI_NESTED_TYPE(android, provider, CalendarContract, AttendeesColumns) 22 | JNI_NESTED_TYPE(android, provider, CalendarContract, CalendarColumns) 23 | JNI_NESTED_TYPE(android, provider, CalendarContract, EventsColumns) 24 | JNI_NESTED_TYPE(android, provider, CalendarContract, RemindersColumns) 25 | JNI_TYPE(android, provider, OpenableColumns) 26 | JNI_TYPE(android, provider, Settings) 27 | 28 | } 29 | 30 | #endif // KANDROIDEXTRAS_ANDROIDTYPES_H 31 | -------------------------------------------------------------------------------- /src/kandroidextras/android/contentresolver.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_CONTENTRESOLVER_H 8 | #define KANDROIDEXTRAS_CONTENTRESOLVER_H 9 | 10 | #include "kandroidextras_export.h" 11 | 12 | #include 13 | class QJniObject; 14 | class QString; 15 | class QUrl; 16 | 17 | namespace KAndroidExtras 18 | { 19 | 20 | /** Methods for working with Android's ContentResolver. */ 21 | namespace ContentResolver 22 | { 23 | /** Get the JNI content resolver. */ 24 | KANDROIDEXTRAS_EXPORT QJniObject get(); 25 | 26 | /** Returns the mime type of the given content: URL. 27 | * @see Android ContentResolver.getType 28 | */ 29 | KANDROIDEXTRAS_EXPORT QString mimeType(const QUrl &url); 30 | 31 | /** File name of a file provided by a content: URL. */ 32 | KANDROIDEXTRAS_EXPORT QString fileName(const QUrl &url); 33 | } 34 | 35 | } 36 | 37 | #endif // KANDROIDEXTRAS_CONTENTRESOLVER_H 38 | -------------------------------------------------------------------------------- /src/kandroidextras/android/context.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "context.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | using namespace KAndroidExtras; 15 | 16 | QJniObject Context::getPackageName() 17 | { 18 | const QJniObject context = QNativeInterface::QAndroidApplication::context(); 19 | return context.callObjectMethod("getPackageName", Jni::signature()); 20 | } 21 | -------------------------------------------------------------------------------- /src/kandroidextras/android/context.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_CONTEXT_H 8 | #define KANDROIDEXTRAS_CONTEXT_H 9 | 10 | #include "kandroidextras_export.h" 11 | 12 | class QJniObject; 13 | 14 | namespace KAndroidExtras 15 | { 16 | 17 | /** Methods around android.content.Context. */ 18 | namespace Context 19 | { 20 | KANDROIDEXTRAS_EXPORT QJniObject getPackageName(); 21 | } 22 | 23 | } 24 | 25 | #endif // KANDROIDEXTRAS_CONTEXT_H 26 | -------------------------------------------------------------------------------- /src/kandroidextras/android/intent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "intent.h" 8 | #include "uri.h" 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace KAndroidExtras; 16 | 17 | Intent::~Intent() = default; 18 | 19 | Intent::operator QJniObject() const 20 | { 21 | return jniHandle(); 22 | } 23 | 24 | template 25 | QJniObject Intent::getObjectExtra(const char *methodName, const QJniObject &name) const 26 | { 27 | return jniHandle().callObjectMethod(methodName, Jni::signature(), name.object()); 28 | } 29 | 30 | QString Intent::getStringExtra(const QJniObject &name) const 31 | { 32 | return getObjectExtra("getStringExtra", name).toString(); 33 | } 34 | 35 | QStringList Intent::getStringArrayExtra(const QJniObject &name) const 36 | { 37 | const auto extra = getObjectExtra>("getStringArrayExtra", name); 38 | return Jni::fromArray(extra); 39 | } 40 | -------------------------------------------------------------------------------- /src/kandroidextras/android/manifestpermission.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_MANIFESTPERMISSIONM_H 8 | #define KANDROIDEXTRAS_MANIFESTPERMISSIONM_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace KAndroidExtras 16 | { 17 | 18 | /** 19 | * Access to manifest permissions. 20 | * @see https://developer.android.com/reference/android/Manifest.permission 21 | */ 22 | class ManifestPermission 23 | { 24 | JNI_UNMANAGED_OBJECT(ManifestPermission, android::Manifest_permission) 25 | public: 26 | JNI_CONSTANT(java::lang::String, READ_CALENDAR) 27 | JNI_CONSTANT(java::lang::String, WRITE_CALENDAR) 28 | JNI_CONSTANT(java::lang::String, READ_EXTERNAL_STORAGE) 29 | JNI_CONSTANT(java::lang::String, WRITE_EXTERNAL_STORAGE) 30 | JNI_CONSTANT(java::lang::String, POST_NOTIFICATIONS) 31 | JNI_CONSTANT(java::lang::String, CAMERA) 32 | }; 33 | 34 | } 35 | 36 | #endif // KANDROIDEXTRAS_MANIFESTPERMISSIONM_H 37 | -------------------------------------------------------------------------------- /src/kandroidextras/android/openablecolumns.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_OPENABLECOLUMNS_H 8 | #define KANDROIDEXTRAS_OPENABLECOLUMNS_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace KAndroidExtras 16 | { 17 | 18 | /** 19 | * Constants for ContentResolver queries. 20 | * @see https://developer.android.com/reference/android/provider/OpenableColumns 21 | */ 22 | class OpenableColumns 23 | { 24 | JNI_UNMANAGED_OBJECT(OpenableColumns, android::provider::OpenableColumns) 25 | public: 26 | JNI_CONSTANT(java::lang::String, DISPLAY_NAME) 27 | JNI_CONSTANT(java::lang::String, SIZE) 28 | }; 29 | 30 | } 31 | 32 | #endif // KANDROIDEXTRAS_OPENABLECOLUMNS_H 33 | -------------------------------------------------------------------------------- /src/kandroidextras/android/settings.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_SETTINGS_H 8 | #define KANDROIDEXTRAS_SETTINGS_H 9 | 10 | #include 11 | #include 12 | 13 | namespace KAndroidExtras 14 | { 15 | 16 | /** Methods around android.provider.Settings. */ 17 | class Settings 18 | { 19 | JNI_UNMANAGED_OBJECT(Settings, android::provider::Settings) 20 | JNI_CONSTANT(java::lang::String, ACTION_APP_NOTIFICATION_SETTINGS) 21 | JNI_CONSTANT(java::lang::String, ACTION_CHANNEL_NOTIFICATION_SETTINGS) 22 | JNI_CONSTANT(java::lang::String, EXTRA_APP_PACKAGE) 23 | JNI_CONSTANT(java::lang::String, EXTRA_CHANNEL_ID) 24 | }; 25 | 26 | } 27 | 28 | #endif // KANDROIDEXTRAS_SETTINGS_H 29 | -------------------------------------------------------------------------------- /src/kandroidextras/android/uri.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "uri.h" 8 | 9 | #include 10 | #include 11 | 12 | using namespace KAndroidExtras; 13 | 14 | QJniObject Uri::fromUrl(const QUrl &url) 15 | { 16 | return QJniObject::callStaticObjectMethod(Jni::typeName(), 17 | "parse", 18 | Jni::signature(), 19 | QJniObject::fromString(url.toString(QUrl::FullyEncoded)).object()); 20 | } 21 | 22 | QUrl Uri::toUrl(const QJniObject &uri) 23 | { 24 | if (!uri.isValid()) { 25 | return QUrl(); 26 | } 27 | return QUrl(uri.callObjectMethod("toString", Jni::signature()).toString()); 28 | } 29 | -------------------------------------------------------------------------------- /src/kandroidextras/android/uri.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_URI_H 8 | #define KANDROIDEXTRAS_URI_H 9 | 10 | #include "kandroidextras_export.h" 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace KAndroidExtras 18 | { 19 | 20 | /** Conversion methods for android.net.Uri. */ 21 | namespace Uri 22 | { 23 | /** Create an android.net.Uri from a QUrl. */ 24 | KANDROIDEXTRAS_EXPORT QJniObject fromUrl(const QUrl &url); 25 | 26 | /** Convert a android.net.Uri to a QUrl. */ 27 | KANDROIDEXTRAS_EXPORT QUrl toUrl(const QJniObject &uri); 28 | } 29 | 30 | JNI_DECLARE_CONVERTER(android::net::Uri, QUrl, (Uri::toUrl(value)), (Uri::fromUrl(value))) 31 | 32 | } 33 | 34 | #endif // KANDROIDEXTRAS_URI_H 35 | -------------------------------------------------------------------------------- /src/kandroidextras/fake/mock_impl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "jni.h" 8 | 9 | int JNIEnv::m_arrayLength = 0; 10 | -------------------------------------------------------------------------------- /src/kandroidextras/fake/mock_jnienvironment.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020-2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KANDROIDEXTRAS_MOCK_JNIENVIRONMENT_H 7 | #define KANDROIDEXTRAS_MOCK_JNIENVIRONMENT_H 8 | 9 | #include "jni.h" 10 | 11 | namespace KAndroidExtras 12 | { 13 | class MockJniEnvironment 14 | { 15 | public: 16 | inline jclass findClass(const char *) 17 | { 18 | return nullptr; 19 | } 20 | inline JNIEnv *operator->() 21 | { 22 | return &m_env; 23 | } 24 | 25 | protected: 26 | mutable JNIEnv m_env; 27 | }; 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/kandroidextras/fake/qt6/QCoreApplication: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KANDROIDEXTRAS_MOCK_QCOREAPPLICATION_H 7 | #define KANDROIDEXTRAS_MOCK_QCOREAPPLICATION_H 8 | 9 | #include_next 10 | 11 | #include 12 | 13 | namespace QNativeInterface { 14 | namespace QAndroidApplication { 15 | inline QJniObject context() 16 | { 17 | QJniObject obj; 18 | obj.addToProtocol(QStringLiteral("global androidContext()")); 19 | return obj; 20 | } 21 | } 22 | } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/kandroidextras/fake/qt6/QJniEnvironment: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020-2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KANDROIDEXTRAS_MOCK_QJNIENVIRONMENT_H 7 | #define KANDROIDEXTRAS_MOCK_QJNIENVIRONMENT_H 8 | 9 | #include "mock_jnienvironment.h" 10 | 11 | class QJniEnvironment : public KAndroidExtras::MockJniEnvironment 12 | { 13 | public: 14 | inline JNIEnv* jniEnv() const { return &m_env; } 15 | }; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/kandroidextras/fake/qt6/QJniObject: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #include "qjniobject.h" 7 | -------------------------------------------------------------------------------- /src/kandroidextras/fake/qt6/private/qandroidextras_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020-2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KANDROIDEXTRAS_MAKE_QTANDROIDEXTRAS_P_H 7 | #define KANDROIDEXTRAS_MAKE_QTANDROIDEXTRAS_P_H 8 | 9 | #include 10 | 11 | /** Mock object for QtAndroid namespace. */ 12 | namespace QtAndroidPrivate 13 | { 14 | inline void startActivity(const QJniObject &, int) 15 | { 16 | } 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/kandroidextras/fake/qt6/qjniobject.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020-2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KANDROIDEXTRAS_MOCK_QJNIOBJECT_H 7 | #define KANDROIDEXTRAS_MOCK_QJNIOBJECT_H 8 | 9 | #include "mock_jniobject.h" 10 | 11 | /** Mock object for QJniObject outside of Android, for automated testing. */ 12 | class KANDROIDEXTRAS_EXPORT QJniObject : public KAndroidExtras::Internal::MockJniObject 13 | { 14 | public: 15 | using MockJniObject::MockJniObject; 16 | }; 17 | 18 | Q_DECLARE_METATYPE(QJniObject) 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/kandroidextras/java/java_headers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | // list all headers here that have no .cpp file 8 | // this only serves as a guarantee that these headers actually compile 9 | #include "javatypes.h" 10 | -------------------------------------------------------------------------------- /src/kandroidextras/java/javalocale.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "javalocale.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | using namespace KAndroidExtras; 15 | 16 | QJniObject Locale::fromLocale(const QLocale &locale) 17 | { 18 | auto lang = QJniObject::fromString(QLocale::languageToString(locale.language())); 19 | auto country = QJniObject::fromString(QLocale::territoryToString(locale.territory())); 20 | auto script = QJniObject::fromString(QLocale::scriptToString(locale.script())); 21 | 22 | return QJniObject(Jni::typeName(), 23 | (const char *)Jni::signature(), 24 | lang.object(), 25 | country.object(), 26 | script.object()); 27 | } 28 | 29 | QJniObject Locale::current() 30 | { 31 | return fromLocale(QLocale()); 32 | } 33 | -------------------------------------------------------------------------------- /src/kandroidextras/java/javalocale.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_LOCALE_H 8 | #define KANDROIDEXTRAS_LOCALE_H 9 | 10 | #include "kandroidextras_export.h" 11 | 12 | class QJniObject; 13 | class QLocale; 14 | 15 | namespace KAndroidExtras 16 | { 17 | 18 | /** Conversion methods between java.util.Locale and QLocale. 19 | * @note Do not rename this file to locale.h, that clashes with POSIX locale.h when your 20 | * include paths are unfortunately set up causing bizarre compilation issues. 21 | */ 22 | namespace Locale 23 | { 24 | /** Create an java.util.Locale object from a QLocale. */ 25 | KANDROIDEXTRAS_EXPORT QJniObject fromLocale(const QLocale &locale); 26 | 27 | /** Create an java.util.Locale object for the current QLocale. */ 28 | KANDROIDEXTRAS_EXPORT QJniObject current(); 29 | } 30 | 31 | } 32 | 33 | #endif // KANDROIDEXTRAS_LOCALE_H 34 | -------------------------------------------------------------------------------- /src/kandroidextras/java/javatypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KANDROIDEXTRAS_JAVATYPES_H 8 | #define KANDROIDEXTRAS_JAVATYPES_H 9 | 10 | #include 11 | #include 12 | 13 | namespace KAndroidExtras 14 | { 15 | 16 | JNI_TYPE(java, io, File) 17 | JNI_TYPE(java, lang, String) 18 | JNI_TYPE(java, util, Locale) 19 | 20 | JNI_DECLARE_CONVERTER(java::lang::String, QString, (value.toString()), (QJniObject::fromString(value))) 21 | 22 | } 23 | 24 | #endif // KANDROIDEXTRAS_JAVATYPES_H 25 | -------------------------------------------------------------------------------- /src/kandroidextras/jni/jni_headers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | // list all headers here that have no .cpp file 8 | // this only serves as a guarantee that these headers actually compile 9 | #include "jniargument.h" 10 | #include "jniarray.h" 11 | #include "jnimethod.h" 12 | #include "jniobject.h" 13 | #include "jnipp.h" 14 | #include "jniprimitivetypes.h" 15 | #include "jniproperty.h" 16 | #include "jnireturnvalue.h" 17 | #include "jnisignature.h" 18 | #include "jnitypes.h" 19 | #include "jnitypetraits.h" 20 | -------------------------------------------------------------------------------- /src/kandroidextras/jni/jnipp.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019-2022 Volker Krause 3 | SPDX-License-Identifier: LGPL-2.0-or-later 4 | */ 5 | 6 | #ifndef KANDROIDEXTRAS_JNIPP_H 7 | #define KANDROIDEXTRAS_JNIPP_H 8 | 9 | /** @file jnipp.h 10 | * Preprocessor macro implementation details. 11 | */ 12 | 13 | ///@cond internal 14 | 15 | // determine how many elements are in __VA_ARGS__ 16 | #define JNI_PP_NARG(...) JNI_PP_NARG_(__VA_ARGS__ __VA_OPT__(, ) JNI_PP_RSEQ_N()) 17 | #define JNI_PP_NARG_(...) JNI_PP_ARG_N(__VA_ARGS__) 18 | #define JNI_PP_ARG_N(_1, _2, _3, _4, _5, _6, _7, N, ...) N 19 | #define JNI_PP_RSEQ_N() 7, 6, 5, 4, 3, 2, 1, 0 20 | 21 | // preprocessor-level token concat 22 | #define JNI_PP_CONCAT(arg1, arg2) JNI_PP_CONCAT1(arg1, arg2) 23 | #define JNI_PP_CONCAT1(arg1, arg2) JNI_PP_CONCAT2(arg1, arg2) 24 | #define JNI_PP_CONCAT2(arg1, arg2) arg1##arg2 25 | 26 | ///@endcond 27 | 28 | #endif // KANDROIDEXTRAS_JNIPP_H 29 | -------------------------------------------------------------------------------- /src/matrix/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Tobias Fella 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_library(KMatrix STATIC) 5 | 6 | target_sources(KMatrix PRIVATE 7 | matrixbeacon.cpp 8 | matrixmanager.cpp 9 | matrixroomsmodel.cpp 10 | matrixroomssortproxymodel.cpp 11 | ) 12 | 13 | generate_export_header(KMatrix BASE_NAME KMatrix) 14 | target_link_libraries(KMatrix PUBLIC Qt::Core QuotientQt6 PRIVATE KF6::I18n) 15 | 16 | ecm_generate_headers(KMatrix_FORWARDING_HEADERS 17 | HEADER_NAMES 18 | MatrixManager 19 | MatrixRoomsModel 20 | PREFIX KMatrix 21 | REQUIRED_HEADERS KMatrix_HEADERS 22 | ) 23 | -------------------------------------------------------------------------------- /src/matrix/matrixroomssortproxymodel.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2023 Volker Krause 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | #include "matrixroomssortproxymodel.h" 5 | #include "matrixroomsmodel.h" 6 | 7 | MatrixRoomsSortProxyModel::MatrixRoomsSortProxyModel(QObject *parent) 8 | : QSortFilterProxyModel(parent) 9 | { 10 | setSortRole(MatrixRoomsModel::DisplayNameRole); 11 | setSortLocaleAware(true); 12 | setSortCaseSensitivity(Qt::CaseInsensitive); 13 | setDynamicSortFilter(true); 14 | } 15 | 16 | MatrixRoomsSortProxyModel::~MatrixRoomsSortProxyModel() = default; 17 | 18 | void MatrixRoomsSortProxyModel::setSourceModel(QAbstractItemModel *sourceModel) 19 | { 20 | QSortFilterProxyModel::setSourceModel(sourceModel); 21 | sort(0); 22 | } 23 | 24 | bool MatrixRoomsSortProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const 25 | { 26 | const auto lhsCategory = source_left.data(MatrixRoomsModel::CategoryRole).toInt(); 27 | const auto rhsCategory = source_right.data(MatrixRoomsModel::CategoryRole).toInt(); 28 | if (lhsCategory == rhsCategory) { 29 | return QSortFilterProxyModel::lessThan(source_left, source_right); 30 | } 31 | 32 | return lhsCategory < rhsCategory; 33 | } 34 | 35 | #include "moc_matrixroomssortproxymodel.cpp" 36 | -------------------------------------------------------------------------------- /src/matrix/matrixroomssortproxymodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2023 Volker Krause 2 | // SPDX-License-Identifier: LGPL-2.0-or-later 3 | 4 | #ifndef MATRIXROOMSSORTPROXYMODEL_H 5 | #define MATRIXROOMSSORTPROXYMODEL_H 6 | 7 | #include 8 | 9 | /** Sorting proxy for matrix rooms. */ 10 | // TODO this probably should have configurable sorting modes (activity, alphabetically, etc) 11 | class MatrixRoomsSortProxyModel : public QSortFilterProxyModel 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit MatrixRoomsSortProxyModel(QObject *parent = nullptr); 16 | ~MatrixRoomsSortProxyModel(); 17 | 18 | void setSourceModel(QAbstractItemModel *sourceModel) override; 19 | bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; 20 | }; 21 | 22 | #endif // MATRIXROOMSSORTPROXYMODEL_H 23 | -------------------------------------------------------------------------------- /src/metadataextractor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Kai Uwe Broulik 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_library(kfilemetadata_itineraryextractor MODULE itineraryextractor.cpp) 5 | 6 | target_link_libraries(kfilemetadata_itineraryextractor 7 | KF6::FileMetaData 8 | KF6::I18n 9 | Qt::Gui 10 | KPim6::Itinerary 11 | KPim6::PkPass 12 | ) 13 | 14 | set_target_properties(kfilemetadata_itineraryextractor PROPERTIES 15 | LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf6/kfilemetadata") 16 | install(TARGETS kfilemetadata_itineraryextractor 17 | DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf6/kfilemetadata) 18 | -------------------------------------------------------------------------------- /src/metadataextractor/itineraryextractor.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2022 Kai Uwe Broulik 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef ITINERARYCREATOR_H 8 | #define ITINERARYCREATOR_H 9 | 10 | #include 11 | 12 | namespace KFileMetaData 13 | { 14 | 15 | class ItineraryExtractor : public ExtractorPlugin 16 | { 17 | Q_OBJECT 18 | Q_PLUGIN_METADATA(IID "org.kde.kf5.kfilemetadata.ExtractorPlugin" FILE "itineraryextractor.json") 19 | Q_INTERFACES(KFileMetaData::ExtractorPlugin) 20 | 21 | public: 22 | explicit ItineraryExtractor(QObject *parent = nullptr); 23 | 24 | public: 25 | void extract(ExtractionResult *result) override; 26 | QStringList mimetypes() const override; 27 | }; 28 | 29 | } 30 | 31 | #endif // ITINERARYCREATOR_H 32 | -------------------------------------------------------------------------------- /src/metadataextractor/itineraryextractor.json: -------------------------------------------------------------------------------- 1 | { 2 | "Name" : "ItineraryExtractor", 3 | "Id" : "org.kde.itineraryextractor", 4 | "MimeTypes" : { 5 | "application/vnd.apple.pkpass": { "Version" : "0.0" } 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/metadataextractor/itineraryextractor.json.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: none 3 | -------------------------------------------------------------------------------- /src/solidextras/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_subdirectory(qml) 5 | 6 | set(solidextras_srcs 7 | brightnessmanager.cpp 8 | lockmanager.cpp 9 | ) 10 | 11 | if (ANDROID) 12 | add_subdirectory(android) 13 | list(APPEND solidextras_srcs 14 | androidbrightnessbackend.cpp 15 | androidlockbackend.cpp 16 | ) 17 | else() 18 | list(APPEND solidextras_srcs 19 | solidbrightnessbackend.cpp 20 | freedesktoplockbackend.cpp 21 | ) 22 | qt_add_dbus_interface(solidextras_srcs org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml brightnesscontroldbusinterface) 23 | qt_add_dbus_interface(solidextras_srcs org.freedesktop.ScreenSaver.xml screensaverdbusinterface) 24 | endif() 25 | 26 | add_library(SolidExtras ${solidextras_srcs}) 27 | generate_export_header(SolidExtras BASE_NAME SolidExtras) 28 | 29 | target_include_directories(SolidExtras PUBLIC "$") 30 | target_link_libraries(SolidExtras PUBLIC Qt::Core) 31 | 32 | if (NOT ANDROID) 33 | target_link_libraries(SolidExtras PRIVATE Qt::DBus) 34 | endif() 35 | 36 | install(TARGETS SolidExtras ${KF_INSTALL_TARGETS_DEFAULT_ARGS}) 37 | -------------------------------------------------------------------------------- /src/solidextras/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/solidextras/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | gradle_add_aar(solidextras_aar BUILDFILE ${CMAKE_CURRENT_SOURCE_DIR}/build.gradle NAME SolidExtras) 5 | gradle_install_aar(solidextras_aar DESTINATION jar) 6 | 7 | configure_file( 8 | ${CMAKE_CURRENT_SOURCE_DIR}/SolidExtras-android-dependencies.xml 9 | ${CMAKE_BINARY_DIR}/lib/SolidExtras_${CMAKE_ANDROID_ARCH_ABI}-android-dependencies.xml 10 | ) 11 | install(FILES SolidExtras-android-dependencies.xml DESTINATION ${KDE_INSTALL_LIBDIR} RENAME SolidExtras_${CMAKE_ANDROID_ARCH_ABI}-android-dependencies.xml) 12 | -------------------------------------------------------------------------------- /src/solidextras/android/SolidExtras-android-dependencies.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/solidextras/android/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | SPDX-License-Identifier: BSD-3-Clause 4 | */ 5 | 6 | buildscript { 7 | repositories { 8 | google() 9 | jcenter() 10 | } 11 | 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:@Gradle_ANDROID_GRADLE_PLUGIN_VERSION@' 14 | } 15 | } 16 | 17 | repositories { 18 | google() 19 | jcenter() 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | buildToolsVersion '@ANDROID_SDK_BUILD_TOOLS_REVISION@' 26 | compileSdkVersion @ANDROID_SDK_COMPILE_API@ 27 | 28 | sourceSets { 29 | main { 30 | manifest.srcFile '@CMAKE_CURRENT_SOURCE_DIR@/AndroidManifest.xml' 31 | java.srcDirs = ['@CMAKE_CURRENT_SOURCE_DIR@/org'] 32 | } 33 | } 34 | 35 | compileOptions { 36 | sourceCompatibility JavaVersion.VERSION_1_8 37 | targetCompatibility JavaVersion.VERSION_1_8 38 | } 39 | 40 | lintOptions { 41 | abortOnError false 42 | } 43 | 44 | defaultConfig { 45 | minSdkVersion @ANDROID_API_LEVEL@ 46 | targetSdkVersion @ANDROID_SDK_COMPILE_API@ 47 | namespace "org.kde.solidextras" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/solidextras/android/org/kde/solidextras/Solid.java: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | package org.kde.solidextras; 8 | 9 | import android.app.Activity; 10 | import android.view.WindowManager; 11 | 12 | public class Solid 13 | { 14 | public static float getBrightness(Activity activity) { 15 | return activity.getWindow().getAttributes().screenBrightness; 16 | } 17 | 18 | public static void setBrightness(Activity activity, final float brightness) { 19 | activity.runOnUiThread(() -> { 20 | WindowManager.LayoutParams layout = activity.getWindow().getAttributes(); 21 | layout.screenBrightness = brightness; 22 | activity.getWindow().setAttributes(layout); 23 | }); 24 | } 25 | 26 | public static void setLockInhibitionOn(Activity activity) { 27 | activity.runOnUiThread(() -> activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)); 28 | } 29 | 30 | public static void setLockInhibitionOff(Activity activity) { 31 | activity.runOnUiThread(() -> activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/solidextras/androidbrightnessbackend.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "androidbrightnessbackend.h" 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | AndroidBrightnessBackend::AndroidBrightnessBackend(QObject *parent) 15 | : BrightnessBackend(parent) 16 | { 17 | } 18 | 19 | AndroidBrightnessBackend::~AndroidBrightnessBackend() 20 | { 21 | } 22 | 23 | float AndroidBrightnessBackend::brightness() const 24 | { 25 | return QJniObject::callStaticMethod("org.kde.solidextras.Solid", 26 | "getBrightness", 27 | "(Landroid/app/Activity;)F", 28 | QNativeInterface::QAndroidApplication::context()); 29 | } 30 | 31 | void AndroidBrightnessBackend::setBrightness(float brightness) 32 | { 33 | QJniObject::callStaticMethod("org.kde.solidextras.Solid", 34 | "setBrightness", 35 | "(Landroid/app/Activity;F)V", 36 | QNativeInterface::QAndroidApplication::context(), 37 | brightness); 38 | } 39 | 40 | float AndroidBrightnessBackend::maxBrightness() const 41 | { 42 | return 1; 43 | } 44 | -------------------------------------------------------------------------------- /src/solidextras/androidbrightnessbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef ANDROIDBRIGHTNESSBACKEND_H 8 | #define ANDROIDBRIGHTNESSBACKEND_H 9 | 10 | #include "brightnessmanager.h" 11 | #include 12 | 13 | class AndroidBrightnessBackend : public BrightnessBackend 14 | { 15 | public: 16 | explicit AndroidBrightnessBackend(QObject *parent = nullptr); 17 | virtual ~AndroidBrightnessBackend(); 18 | 19 | void setBrightness(float brightness) override; 20 | float brightness() const override; 21 | float maxBrightness() const override; 22 | }; 23 | 24 | #endif // ANDROIDBRIGHTNESSBACKEND_H 25 | -------------------------------------------------------------------------------- /src/solidextras/androidlockbackend.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "androidlockbackend.h" 8 | 9 | #include 10 | #include 11 | 12 | AndroidLockBackend::AndroidLockBackend(QObject *parent) 13 | : LockBackend(parent) 14 | { 15 | } 16 | 17 | AndroidLockBackend::~AndroidLockBackend() 18 | { 19 | } 20 | 21 | void AndroidLockBackend::setInhibitionOff() 22 | { 23 | QJniObject::callStaticMethod("org.kde.solidextras.Solid", 24 | "setLockInhibitionOff", 25 | "(Landroid/app/Activity;)V", 26 | QNativeInterface::QAndroidApplication::context()); 27 | } 28 | 29 | void AndroidLockBackend::setInhibitionOn(const QString &explanation) 30 | { 31 | Q_UNUSED(explanation) 32 | QJniObject::callStaticMethod("org.kde.solidextras.Solid", 33 | "setLockInhibitionOn", 34 | "(Landroid/app/Activity;)V", 35 | QNativeInterface::QAndroidApplication::context()); 36 | } 37 | -------------------------------------------------------------------------------- /src/solidextras/androidlockbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef ANDROIDLOCKBACKEND_H 8 | #define ANDROIDLOCKBACKEND_H 9 | 10 | #include "lockmanager.h" 11 | #include 12 | 13 | class AndroidLockBackend : public LockBackend 14 | { 15 | public: 16 | explicit AndroidLockBackend(QObject *parent = nullptr); 17 | virtual ~AndroidLockBackend(); 18 | 19 | void setInhibitionOff() override; 20 | void setInhibitionOn(const QString &explanation) override; 21 | }; 22 | 23 | #endif // ANDROIDBRIGHTNESSBACKEND_H 24 | -------------------------------------------------------------------------------- /src/solidextras/brightnessmanager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "brightnessmanager.h" 8 | 9 | #include 10 | 11 | #if defined(Q_OS_ANDROID) 12 | #include "androidbrightnessbackend.h" 13 | #elif defined(Q_OS_LINUX) 14 | #include "solidbrightnessbackend.h" 15 | #endif 16 | 17 | BrightnessManager::BrightnessManager(QObject *parent) 18 | : QObject(parent) 19 | { 20 | #if defined(Q_OS_ANDROID) 21 | m_backend = new AndroidBrightnessBackend(this); 22 | #elif defined(Q_OS_LINUX) 23 | m_backend = new SolidBrightnessBackend(this); 24 | #endif 25 | } 26 | 27 | BrightnessManager::~BrightnessManager() = default; 28 | 29 | void BrightnessManager::toggleBrightness() 30 | { 31 | if (!m_backend) 32 | return; 33 | 34 | m_backend->toggleBrightness(); 35 | } 36 | 37 | void BrightnessBackend::toggleBrightness() 38 | { 39 | if (m_maximized) { 40 | setBrightness(m_previousValue); 41 | } else { 42 | m_previousValue = brightness(); 43 | setBrightness(maxBrightness()); 44 | } 45 | m_maximized = !m_maximized; 46 | } 47 | 48 | #include "moc_brightnessmanager.cpp" 49 | -------------------------------------------------------------------------------- /src/solidextras/brightnessmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef BRIGHTNESSMANAGER_H 8 | #define BRIGHTNESSMANAGER_H 9 | 10 | #include "solidextras_export.h" 11 | 12 | #include 13 | 14 | class BrightnessBackend : public QObject 15 | { 16 | public: 17 | explicit BrightnessBackend(QObject *parent = nullptr) 18 | : QObject(parent) 19 | , m_maximized() 20 | , m_previousValue() 21 | { 22 | } 23 | ~BrightnessBackend() override = default; 24 | 25 | public: 26 | virtual void toggleBrightness(); 27 | 28 | protected: 29 | virtual void setBrightness(float brightness) = 0; 30 | virtual float brightness() const = 0; 31 | virtual float maxBrightness() const = 0; 32 | 33 | private: 34 | bool m_maximized; 35 | int m_previousValue; 36 | }; 37 | 38 | class SOLIDEXTRAS_EXPORT BrightnessManager : public QObject 39 | { 40 | Q_OBJECT 41 | 42 | public: 43 | explicit BrightnessManager(QObject *parent = nullptr); 44 | ~BrightnessManager() override; 45 | 46 | public Q_SLOTS: 47 | void toggleBrightness(); 48 | 49 | private: 50 | BrightnessBackend *m_backend; 51 | }; 52 | 53 | #endif // BRIGHTNESSMANAGER_H 54 | -------------------------------------------------------------------------------- /src/solidextras/freedesktoplockbackend.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "freedesktoplockbackend.h" 8 | 9 | #include "screensaverdbusinterface.h" 10 | 11 | #include 12 | 13 | FreedesktopLockBackend::FreedesktopLockBackend(QObject *parent) 14 | : LockBackend(parent) 15 | , m_cookie(0) 16 | { 17 | m_iface = new OrgFreedesktopScreenSaverInterface(QStringLiteral("org.freedesktop.ScreenSaver"), 18 | QStringLiteral("/org/freedesktop/ScreenSaver"), 19 | QDBusConnection::sessionBus(), 20 | this); 21 | } 22 | 23 | void FreedesktopLockBackend::setInhibitionOff() 24 | { 25 | m_iface->UnInhibit(m_cookie); 26 | } 27 | 28 | void FreedesktopLockBackend::setInhibitionOn(const QString &explanation) 29 | { 30 | m_cookie = m_iface->Inhibit(QStringLiteral("org.kde.itinerary"), explanation); 31 | } 32 | -------------------------------------------------------------------------------- /src/solidextras/freedesktoplockbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef SOLIDLOCKBACKEND_H 8 | #define SOLIDLOCKBACKEND_H 9 | 10 | #include "lockmanager.h" 11 | #include 12 | 13 | class OrgFreedesktopScreenSaverInterface; 14 | 15 | class FreedesktopLockBackend : public LockBackend 16 | { 17 | public: 18 | explicit FreedesktopLockBackend(QObject *parent = nullptr); 19 | 20 | void setInhibitionOff() override; 21 | void setInhibitionOn(const QString &explanation) override; 22 | 23 | private: 24 | OrgFreedesktopScreenSaverInterface *m_iface; 25 | int m_cookie; 26 | }; 27 | 28 | #endif // SOLIDLOCKBACKEND_H 29 | -------------------------------------------------------------------------------- /src/solidextras/lockmanager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "lockmanager.h" 8 | 9 | #include 10 | 11 | #if defined(Q_OS_ANDROID) 12 | #include "androidlockbackend.h" 13 | #elif defined(Q_OS_LINUX) 14 | #include "freedesktoplockbackend.h" 15 | #endif 16 | 17 | LockManager::LockManager(QObject *parent) 18 | : QObject(parent) 19 | , m_inhibit() 20 | { 21 | #if defined(Q_OS_ANDROID) 22 | m_backend = new AndroidLockBackend(this); 23 | #elif defined(Q_OS_LINUX) 24 | m_backend = new FreedesktopLockBackend(this); 25 | #endif 26 | } 27 | 28 | LockManager::~LockManager() = default; 29 | 30 | void LockManager::toggleInhibitScreenLock(const QString &explanation) 31 | { 32 | if (!m_backend) 33 | return; 34 | 35 | if (m_inhibit) { 36 | m_backend->setInhibitionOff(); 37 | } else { 38 | m_backend->setInhibitionOn(explanation); 39 | } 40 | m_inhibit = !m_inhibit; 41 | } 42 | 43 | #include "moc_lockmanager.cpp" 44 | -------------------------------------------------------------------------------- /src/solidextras/lockmanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef LOCKMANAGER_H 8 | #define LOCKMANAGER_H 9 | 10 | #include "solidextras_export.h" 11 | 12 | #include 13 | 14 | class LockBackend : public QObject 15 | { 16 | public: 17 | explicit LockBackend(QObject *parent = nullptr) 18 | : QObject(parent) 19 | { 20 | } 21 | ~LockBackend() override = default; 22 | virtual void setInhibitionOn(const QString &explanation) = 0; 23 | virtual void setInhibitionOff() = 0; 24 | }; 25 | 26 | class SOLIDEXTRAS_EXPORT LockManager : public QObject 27 | { 28 | Q_OBJECT 29 | 30 | public: 31 | explicit LockManager(QObject *parent = nullptr); 32 | ~LockManager() override; 33 | 34 | public Q_SLOTS: 35 | /** Toggle screen lock inhibition. 36 | * @param explanation A human-readable explanation on why the screen lock is inhibited. 37 | * (not used on all platforms). 38 | */ 39 | void toggleInhibitScreenLock(const QString &explanation); 40 | 41 | private: 42 | LockBackend *m_backend; 43 | bool m_inhibit; 44 | }; 45 | 46 | #endif // LOCKMANAGER_H 47 | -------------------------------------------------------------------------------- /src/solidextras/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/solidextras/qml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_library(solidextrasqmlplugin solidextrasqmlplugin.cpp) 5 | target_link_libraries(solidextrasqmlplugin 6 | Qt::Qml 7 | SolidExtras 8 | ) 9 | 10 | # make examples work without installation 11 | if (NOT CMAKE_VERSION VERSION_LESS 3.14) 12 | set_property(TARGET solidextrasqmlplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/org/kde/solidextras) 13 | file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/org/kde/solidextras/qmldir COPY_ON_ERROR SYMBOLIC) 14 | else() 15 | message(WARNING "CMake is too old, cannot setup QML plugins to work without installation") 16 | endif() 17 | 18 | install(TARGETS solidextrasqmlplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/solidextras) 19 | install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/solidextras) 20 | -------------------------------------------------------------------------------- /src/solidextras/qml/qmldir: -------------------------------------------------------------------------------- 1 | module org.kde.solidextras 2 | plugin solidextrasqmlplugin 3 | classname SolidExtrasQmlPlugin 4 | -------------------------------------------------------------------------------- /src/solidextras/qml/qmldir.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | -------------------------------------------------------------------------------- /src/solidextras/qml/solidextrasqmlplugin.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2020 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "solidextras/brightnessmanager.h" 12 | #include "solidextras/lockmanager.h" 13 | 14 | class SolidExtrasQmlPlugin : public QQmlExtensionPlugin 15 | { 16 | Q_OBJECT 17 | Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") 18 | void registerTypes(const char *uri) override; 19 | }; 20 | 21 | void SolidExtrasQmlPlugin::registerTypes(const char *) 22 | { 23 | qmlRegisterSingletonType("org.kde.solidextras", 1, 0, "BrightnessManager", [](QQmlEngine *, QJSEngine *) -> QObject * { 24 | return new BrightnessManager; 25 | }); 26 | qmlRegisterSingletonType("org.kde.solidextras", 1, 0, "LockManager", [](QQmlEngine *, QJSEngine *) -> QObject * { 27 | return new LockManager; 28 | }); 29 | } 30 | 31 | #include "solidextrasqmlplugin.moc" 32 | -------------------------------------------------------------------------------- /src/solidextras/solidbrightnessbackend.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "solidbrightnessbackend.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | SolidBrightnessBackend::SolidBrightnessBackend(QObject *parent) 14 | : BrightnessBackend(parent) 15 | { 16 | m_iface = new OrgKdeSolidPowerManagementActionsBrightnessControlInterface(QStringLiteral("org.kde.Solid.PowerManagement"), 17 | QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), 18 | QDBusConnection::sessionBus(), 19 | this); 20 | } 21 | 22 | SolidBrightnessBackend::~SolidBrightnessBackend() 23 | { 24 | } 25 | 26 | float SolidBrightnessBackend::brightness() const 27 | { 28 | return m_iface->brightness(); 29 | } 30 | 31 | void SolidBrightnessBackend::setBrightness(float brightness) 32 | { 33 | m_iface->setBrightnessSilent(brightness); 34 | } 35 | 36 | float SolidBrightnessBackend::maxBrightness() const 37 | { 38 | return m_iface->brightnessMax(); 39 | } 40 | -------------------------------------------------------------------------------- /src/solidextras/solidbrightnessbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Nicolas Fella 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef SOLIDBRIGHTNESSBACKEND_H 8 | #define SOLIDBRIGHTNESSBACKEND_H 9 | 10 | #include "brightnessmanager.h" 11 | #include 12 | 13 | class OrgKdeSolidPowerManagementActionsBrightnessControlInterface; 14 | 15 | class SolidBrightnessBackend : public BrightnessBackend 16 | { 17 | public: 18 | explicit SolidBrightnessBackend(QObject *parent = nullptr); 19 | ~SolidBrightnessBackend() override; 20 | 21 | void setBrightness(float brightness) override; 22 | float brightness() const override; 23 | float maxBrightness() const override; 24 | 25 | private: 26 | OrgKdeSolidPowerManagementActionsBrightnessControlInterface *m_iface; 27 | }; 28 | 29 | #endif // SOLIDBRIGHTNESSBACKEND_H 30 | -------------------------------------------------------------------------------- /src/thumbnailer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2021 Kai Uwe Broulik 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | kcoreaddons_add_plugin(itinerarythumbnail SOURCES itinerarycreator.cpp INSTALL_NAMESPACE "kf6/thumbcreator") 5 | 6 | target_link_libraries(itinerarythumbnail 7 | KF6::KIOGui 8 | Qt::Gui 9 | KPim6::PkPass 10 | ) 11 | -------------------------------------------------------------------------------- /src/thumbnailer/itinerarycreator.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Kai Uwe Broulik 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef ITINERARYCREATOR_H 8 | #define ITINERARYCREATOR_H 9 | 10 | #include 11 | 12 | #include 13 | 14 | class ItineraryCreator : public KIO::ThumbnailCreator 15 | { 16 | Q_OBJECT 17 | public: 18 | ItineraryCreator(QObject *parent, const QVariantList &args); 19 | ~ItineraryCreator() override; 20 | 21 | KIO::ThumbnailResult create(const KIO::ThumbnailRequest &request) override; 22 | }; 23 | 24 | #endif // ITINERARYCREATOR_H 25 | -------------------------------------------------------------------------------- /src/thumbnailer/itinerarythumbnail.json.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: none 3 | -------------------------------------------------------------------------------- /src/tools/db-online-ticket-dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # SPDX-FileCopyrightText: 2024 Volker Krause 3 | # SPDX-License-Identifier: LGPL-2.0-or-later 4 | 5 | import argparse 6 | import re 7 | import requests 8 | 9 | parser = argparse.ArgumentParser(description='DB online ticket API response output') 10 | parser.add_argument('--name', type=str, required=True, help='Case-sensitive last name, as on the ticket') 11 | parser.add_argument('--ref', type=str, required=True, help='12 digit Auftragsnummer') 12 | arguments = parser.parse_args() 13 | 14 | postData = f'' 15 | print(f"Request 1:\n{postData}\n") 16 | req = requests.post('https://fahrkarten.bahn.de/mobile/dbc/xs.go?', data=postData.encode()) 17 | print(f"Reply 1:\n{req.text}\n") 18 | 19 | for kwid in re.findall(r'kwid="([^"]*)"', req.text): 20 | postData = f'' 21 | print(f"Request 2:\n{postData}\n") 22 | req = requests.post('https://fahrkarten.bahn.de/mobile/dbc/xs.go?', data=postData.encode()) 23 | print(f"Reply 2:\n{req.text}") 24 | -------------------------------------------------------------------------------- /src/weather/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2018 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_library(itinerary-weather STATIC) 5 | target_sources(itinerary-weather PRIVATE 6 | weatherforecast.cpp 7 | weatherforecastmanager.cpp 8 | ) 9 | 10 | target_link_libraries(itinerary-weather 11 | PUBLIC 12 | Qt::Core 13 | PRIVATE 14 | KF6::Holidays 15 | Qt::Network 16 | ZLIB::ZLIB 17 | ) 18 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2018 Volker Krause 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | add_executable(pkpassviewer pkpassviewer.cpp pkpassviewer.qrc) 5 | target_link_libraries(pkpassviewer PRIVATE itinerary KF6::I18nQml) 6 | 7 | add_executable(journeyquerytest journeyquerytest.cpp journeyquerytest.qrc) 8 | target_link_libraries(journeyquerytest PRIVATE itinerary KF6::I18nQml) 9 | 10 | add_executable(vehiclelayoutviewer vehiclelayoutviewer.cpp vehiclelayoutviewer.qrc) 11 | target_link_libraries(vehiclelayoutviewer PRIVATE itinerary KF6::I18nQml) 12 | -------------------------------------------------------------------------------- /tests/demo-settings.itinerary: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/itinerary/6a4045fe86aa34e5ca12e7ac0148a2c1eb45979c/tests/demo-settings.itinerary -------------------------------------------------------------------------------- /tests/demo-settings.itinerary.license: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: none 2 | # SPDX-License-Identifier: CC0-1.0 3 | -------------------------------------------------------------------------------- /tests/journeyquerytest.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | import QtQuick 8 | import QtQuick.Layouts 9 | import QtQuick.Controls as QQC2 10 | import org.kde.kirigami as Kirigami 11 | import org.kde.kpublictransport as KPT 12 | import org.kde.itinerary 13 | 14 | Kirigami.ApplicationWindow { 15 | title: "Journey Query Test" 16 | 17 | width: 480 18 | height: 720 19 | 20 | pageStack.initialPage: jnyQueryPage 21 | 22 | KPT.Manager { 23 | id: ptMgr; 24 | allowInsecureBackends: true 25 | } 26 | 27 | Component { 28 | id: journeySectionPage 29 | JourneySectionPage {} 30 | } 31 | Component { 32 | id: journeyPathPage 33 | JourneyPathPage {} 34 | } 35 | 36 | Component { 37 | id: jnyQueryPage 38 | JourneyQueryPage { 39 | title: "Journey Query" 40 | journeyRequest: _request 41 | publicTransportManager: ptMgr 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/journeyquerytest.qrc: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | journeyquerytest.qml 8 | ../src/app/JourneyDelegateHeader.qml 9 | ../src/app/JourneyPathPage.qml 10 | ../src/app/JourneyQueryPage.qml 11 | ../src/app/JourneySectionDelegate.qml 12 | ../src/app/JourneySectionPage.qml 13 | ../src/app/JourneySectionStopDelegate.qml 14 | ../src/app/JourneySectionStopDelegateLineSegment.qml 15 | ../src/app/JourneySummaryDelegate.qml 16 | ../src/app/VerticalNavigationButton.qml 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/pkpassviewer.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2018 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | import QtQuick 8 | import QtQuick.Layouts 9 | import QtQuick.Controls as QQC2 10 | import org.kde.kirigami as Kirigami 11 | import org.kde.itinerary 12 | 13 | Kirigami.ApplicationWindow { 14 | title: "PkPass Viewer" 15 | 16 | width: 480 17 | height: 720 18 | 19 | pageStack.initialPage: pkPassPage 20 | 21 | Component { 22 | id: pkPassPage 23 | PkPassPage { 24 | pass: _pass 25 | passId: _passId 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/pkpassviewer.qrc: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | pkpassviewer.qml 8 | ../src/app/BarcodeScanModeButton.qml 9 | ../src/app/BarcodeScanModeController.qml 10 | ../src/app/BoardingPass.qml 11 | ../src/app/EventTicket.qml 12 | ../src/app/GenericPass.qml 13 | ../src/app/PkPassBarcode.qml 14 | ../src/app/PkPassPage.qml 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/randa2017-flight-cancellation.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "@context": "http://schema.org", 4 | "@type": "FlightReservation", 5 | "modifiedTime": "2017-08-22T00:00:00", 6 | "reservationNumber": "XXX007", 7 | "reservationStatus": "ReservationCancelled" 8 | } 9 | ] 10 | -------------------------------------------------------------------------------- /tests/vehiclelayoutviewer.qml: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Volker Krause 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | import QtQuick 8 | import QtQuick.Layouts 9 | import QtQuick.Controls as QQC2 10 | import org.kde.kirigami as Kirigami 11 | import org.kde.kpublictransport as KPT 12 | import "." as App 13 | 14 | Kirigami.ApplicationWindow { 15 | title: "Vehicle Layout Viewer" 16 | 17 | width: 480 18 | height: 720 19 | 20 | pageStack.initialPage: layoutPage 21 | 22 | KPT.Manager { 23 | id: ptMgr; 24 | } 25 | 26 | Component { 27 | id: layoutPage 28 | App.VehicleLayoutPage { 29 | stopover: _stopover 30 | selectedVehicleSection: _coach 31 | seat: _seat 32 | publicTransportManager: ptMgr 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /tests/vehiclelayoutviewer.qrc: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | vehiclelayoutviewer.qml 8 | ../src/app/VehicleLayoutPage.qml 9 | ../src/app/SheetDrawer.qml 10 | 11 | 12 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: none 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | [pycodestyle] 5 | max-line-length = 160 6 | --------------------------------------------------------------------------------