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 }