Warning, /pim/itinerary/src/app/FormPlaceEditorDelegate.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 import QtQuick
0008 import QtQuick.Layouts
0009 import QtQuick.Controls as QQC2
0010 import QtLocation as QtLocation
0011 import QtPositioning
0012 import org.kde.kirigami as Kirigami
0013 import org.kde.kirigamiaddons.formcard as FormCard
0014 import org.kde.i18n.localeData
0015 import org.kde.contacts
0016 import org.kde.kitinerary
0017 import org.kde.itinerary
0018 
0019 ColumnLayout {
0020     id: root
0021     property variant place
0022 
0023     property double latitude: place.geo.latitude;
0024     property double longitude: place.geo.longitude;
0025 
0026     /** Currently selected country code. */
0027     readonly property string currentCountry: addressCountry.currentValue
0028 
0029     function save(place) {
0030         var addr = place.address;
0031         addr.streetAddress = streetAddress.text;
0032         addr.postalCode = postalCode.text;
0033         addr.addressLocality = addressLocality.text;
0034         if (addressRegion.visible) {
0035             addr.addressRegion = addressRegion.currentIndex < 0 ? addressRegion.editText : addressRegion.currentValue.substr(3);
0036         } else {
0037             addr.addressRegion = '';
0038         }
0039         addr.addressCountry = addressCountry.currentValue;
0040         var geo = place.geo;
0041         geo.latitude = latitude;
0042         geo.longitude = longitude;
0043         var newPlace = place;
0044         newPlace.address = addr;
0045         newPlace.geo = geo;
0046         return newPlace;
0047     }
0048 
0049     readonly property var addressFormat: AddressFormatRepository.formatForCountry(addressCountry.currentValue, KContacts.AddressFormatScriptPreference.Local)
0050 
0051     spacing: 0
0052 
0053     Component {
0054         id: locationPickerPage
0055         LocationPicker {
0056             title: i18n("Pick Location")
0057             coordinate: QtPositioning.coordinate(root.latitude, root.longitude)
0058             onCoordinateChanged: {
0059                 root.latitude = coordinate.latitude;
0060                 root.longitude = coordinate.longitude;
0061             }
0062         }
0063     }
0064 
0065     FormCard.FormTextFieldDelegate {
0066         id: streetAddress
0067         label: i18n("Street")
0068         text: place.address.streetAddress
0069     }
0070     FormCard.FormDelegateSeparator {}
0071 
0072     FormCard.FormTextFieldDelegate {
0073         id: postalCode
0074         label: ("Postal Code")
0075         text: place.address.postalCode
0076 
0077         readonly property bool validFormat: root.addressFormat.postalCodeRegularExpression === '' || text.match('^' + root.addressFormat.postalCodeRegularExpression + '$')
0078         status: validFormat ? Kirigami.MessageType.Positive : Kirigami.MessageType.Warning
0079         statusMessage: postalCode.text && !validFormat ? i18n("Invalid postal code format for this country.") : "";
0080     }
0081     FormCard.FormDelegateSeparator {}
0082 
0083     FormCard.FormTextFieldDelegate {
0084         id: addressLocality
0085         label: i18n("City")
0086         text: place.address.addressLocality
0087     }
0088     FormCard.FormDelegateSeparator {}
0089 
0090     CountrySubdivisionModel {
0091         id: regionModel
0092         country: addressCountry.currentCountry
0093         onCountryChanged: {
0094             if (addressRegion.currentIndex < 0) {
0095                 addressRegion.tryFindRegion(addressRegion.editText != '' ? addressRegion.editText : place.address.addressRegion);
0096             } else {
0097                 addressRegion.currentIndex = -1;
0098             }
0099         }
0100     }
0101     FormCard.FormComboBoxDelegate {
0102         id: addressRegion
0103         text: i18n("Region")
0104         editable: true
0105         model: regionModel
0106         textRole: "display"
0107         valueRole: "code"
0108         visible: (root.addressFormat.usedFields & KContacts.AddressFormatField.Region) || editText
0109 
0110         function tryFindRegion(input) {
0111             const i = regionModel.rowForNameOrCode(input)
0112             if (i >= 0) {
0113                 currentIndex = i;
0114             } else if (input) {
0115                 editText = input;
0116             } else {
0117                 currentIndex = -1;
0118                 editText = '';
0119             }
0120         }
0121 
0122         Component.onCompleted: tryFindRegion(place.address.addressRegion)
0123         onAccepted: tryFindRegion(editText)
0124     }
0125     FormCard.FormDelegateSeparator { visible: addressRegion.visible }
0126 
0127     CountryComboBoxDelegate {
0128         id: addressCountry
0129         text: i18n("Country")
0130         model: Country.allCountries.map(c => c.alpha2).sort((lhs, rhs) => {
0131             return Country.fromAlpha2(lhs).name.localeCompare(Country.fromAlpha2(rhs).name);
0132         })
0133         initialCountry: place.address.addressCountry
0134     }
0135 
0136     QtLocation.GeocodeModel {
0137         id: geocodeModel
0138         plugin: applicationWindow().osmPlugin()
0139         autoUpdate: false
0140         limit: 1
0141 
0142         query: Address {
0143             id: geocodeAddr
0144         }
0145 
0146         onLocationsChanged: {
0147             if (count >= 1) {
0148                 root.latitude = geocodeModel.get(0).coordinate.latitude;
0149                 root.longitude = geocodeModel.get(0).coordinate.longitude;
0150             }
0151         }
0152         onErrorStringChanged: showPassiveNotification(geocodeModel.errorString, "short")
0153     }
0154     QtLocation.GeocodeModel {
0155         id: reverseGeocodeModel
0156         plugin: applicationWindow().osmPlugin()
0157         autoUpdate: false
0158         limit: 1
0159         onLocationsChanged: {
0160             if (count >= 1) {
0161                 const loc = reverseGeocodeModel.get(0).address;
0162                 streetAddress.text = loc.street;
0163                 postalCode.text = loc.postalCode
0164                 addressLocality.text = loc.city;
0165                 // countryCode is supposed to be the code already, but isn't always...
0166                 addressCountry.currentIndex = addressCountry.indexOfValue(Country.fromName(loc.countryCode).alpha2);
0167                 // only apply region if the new country actually needs that
0168                 if (root.addressFormat.usedFields & KContacts.AddressFormatField.Region) {
0169                     addressRegion.tryFindRegion(loc.state);
0170                 } else {
0171                     addressRegion.currentIndex = -1;
0172                     addressRegion.editText = '';
0173                 }
0174             }
0175         }
0176         onErrorStringChanged: showPassiveNotification(geocodeModel.errorString, "short")
0177     }
0178 
0179     FormCard.FormButtonDelegate {
0180         text: i18n("Coordinate")
0181         description: !Number.isNaN(root.latitude) && !Number.isNaN(root.longitude) ? i18n("%1°, %2°", root.latitude.toFixed(2), root.longitude.toFixed(2)) : i18n("Pick...");
0182         icon.name: "crosshairs"
0183         onClicked: applicationWindow().pageStack.push(locationPickerPage)
0184         // TODO we can autofill country/region using KCountry[Subdivision] here?
0185     }
0186 
0187     FormCard.FormDelegateSeparator {
0188         visible: addressToCoordinateAction.visible || coordinateToAddressAction.visible
0189     }
0190 
0191     FormCard.AbstractFormDelegate {
0192         visible: addressToCoordinateAction.visible || coordinateToAddressAction.visible
0193 
0194         contentItem: Kirigami.ActionToolBar {
0195             actions: [
0196                 Kirigami.Action {
0197                     id: addressToCoordinateAction
0198 
0199                     text: i18n("Address to coordinate")
0200                     icon.name: "go-down-symbolic"
0201                     enabled: geocodeModel.status !== QtLocation.GeocodeModel.Loading
0202                     visible: addressLocality.text
0203                     onTriggered: {
0204                         geocodeAddr.street = streetAddress.text;
0205                         geocodeAddr.postalCode = postalCode.text;
0206                         geocodeAddr.city = addressLocality.text;
0207                         geocodeAddr.state = addressRegion.currentValue ? addressRegion.currentValue : "";
0208                         geocodeAddr.countryCode = addressCountry.currentValue;
0209                         geocodeModel.update();
0210                     }
0211                 },
0212                 Kirigami.Action {
0213                     id: coordinateToAddressAction
0214 
0215                     text: i18n("Coordinate to address")
0216                     icon.name: "go-up-symbolic"
0217                     enabled: reverseGeocodeModel.status !== QtLocation.GeocodeModel.Loading
0218                     visible: !Number.isNaN(root.latitude) && !Number.isNaN(root.longitude)
0219                     onTriggered: {
0220                         reverseGeocodeModel.query = QtPositioning.coordinate(root.latitude, root.longitude)
0221                         reverseGeocodeModel.update();
0222                     }
0223                 }
0224             ]
0225         }
0226     }
0227 }