Warning, /plasma/kdeplasma-addons/applets/weather/package/contents/ui/config/ConfigWeatherStation.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2016, 2018 Friedrich W. H. Kossebau <kossebau@kde.org> 0003 * SPDX-FileCopyrightText: 2022 Ismael Asensio <isma.af@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 import QtQuick 0009 import QtQuick.Controls as QQC2 0010 import QtQuick.Layouts 0011 0012 import org.kde.kirigami as Kirigami 0013 import org.kde.plasma.plasmoid 0014 import org.kde.plasma.private.weather 0015 import org.kde.kcmutils as KCM 0016 0017 KCM.ScrollViewKCM { 0018 id: weatherStationConfigPage 0019 0020 property string cfg_source 0021 property alias cfg_updateInterval: updateIntervalSpin.value 0022 0023 readonly property var providers: Plasmoid.providers 0024 0025 readonly property var sourceDetails: cfg_source ? cfg_source.split('|') : "" 0026 readonly property bool hasSource: sourceDetails.length > 2 0027 readonly property bool canSearch: !!searchStringEdit.text && Object.keys(providers).length 0028 0029 // The model property `isValidatingInput` doesn't account for the timer delay 0030 // We use a custom property to provide a more responsive feedback 0031 property bool isSearching: false 0032 0033 LocationListModel { 0034 id: locationListModel 0035 onLocationSearchDone: { 0036 isSearching = false; 0037 } 0038 } 0039 0040 header: ColumnLayout { 0041 0042 spacing: Kirigami.Units.smallSpacing 0043 0044 Kirigami.FormLayout { 0045 id: formLayout 0046 0047 QQC2.SpinBox { 0048 id: updateIntervalSpin 0049 0050 Kirigami.FormData.label: i18nc("@label:spinbox", "Update every:") 0051 0052 textFromValue: function(value) { 0053 return (i18np("%1 minute", "%1 minutes", value)); 0054 } 0055 valueFromText: function(text) { 0056 return parseInt(text); 0057 } 0058 0059 from: 30 0060 to: 3600 0061 editable: true 0062 } 0063 0064 QQC2.Label { 0065 Kirigami.FormData.label: i18nc("@label", "Location:") 0066 0067 Layout.fillWidth: true 0068 elide: Text.ElideRight 0069 opacity: hasSource ? 1 : 0.7 0070 0071 text: hasSource ? sourceDetails[2] : i18nc("No location is currently selected", "None selected") 0072 textFormat: Text.PlainText 0073 } 0074 0075 QQC2.Label { 0076 Kirigami.FormData.label: hasSource ? i18nc("@label", "Provider:") : "" 0077 0078 Layout.fillWidth: true 0079 elide: Text.ElideRight 0080 // Keep it visible to avoid height changes which can confuse AppletConfigurationPage 0081 opacity: hasSource ? 1 : 0 0082 0083 text: hasSource ? providers[sourceDetails[0]] : "" 0084 textFormat: Text.PlainText 0085 } 0086 0087 Item { 0088 // This dummy item adds some spacing and makes the form layout less jumpy 0089 Kirigami.FormData.isSection: true 0090 implicitWidth: Math.min(Kirigami.Units.gridUnit * 15, weatherStationConfigPage.width - Kirigami.Units.gridUnit) 0091 } 0092 } 0093 0094 Kirigami.SearchField { 0095 id: searchStringEdit 0096 0097 Layout.fillWidth: true 0098 0099 focus: true 0100 enabled: Object.keys(providers).length > 0 0101 placeholderText: hasSource ? i18nc("@info:placeholder", "Enter new location") : i18nc("@info:placeholder", "Enter location") 0102 0103 Timer { 0104 id: searchDelayTimer 0105 interval: 500 0106 onTriggered: { 0107 if (!canSearch) { 0108 locationListModel.clear(); 0109 return; 0110 } 0111 locationListModel.searchLocations(searchStringEdit.text, Object.keys(providers)); 0112 } 0113 } 0114 0115 onTextChanged: { 0116 isSearching = text.length > 0 0117 searchDelayTimer.restart(); 0118 } 0119 0120 Keys.onUpPressed: { 0121 if (locationListView.currentIndex != 0) { 0122 locationListView.currentIndex--; 0123 } 0124 event.accepted = true; 0125 } 0126 Keys.onDownPressed: { 0127 if (locationListView.currentIndex != locationListView.count - 1) { 0128 locationListView.currentIndex++; 0129 } 0130 event.accepted = true; 0131 } 0132 Keys.onEscapePressed: { 0133 if (searchStringEdit.text.length === 0) { 0134 event.accepted = false; 0135 return; 0136 } 0137 searchStringEdit.clear(); 0138 event.accepted = true; 0139 } 0140 } 0141 } 0142 0143 view: ListView { 0144 id: locationListView 0145 model: locationListModel 0146 focus: true 0147 activeFocusOnTab: true 0148 keyNavigationEnabled: true 0149 enabled: Object.keys(providers).length > 0 0150 0151 onCurrentIndexChanged: { 0152 const source = locationListModel.valueForListIndex(locationListView.currentIndex); 0153 if (source) { 0154 weatherStationConfigPage.cfg_source = source; 0155 } 0156 } 0157 0158 delegate: QQC2.ItemDelegate { 0159 width: locationListView.width 0160 text: model.display 0161 highlighted: ListView.isCurrentItem 0162 0163 onClicked: { 0164 locationListView.forceActiveFocus(); 0165 locationListView.currentIndex = index; 0166 } 0167 } 0168 0169 // To avoid start with a highlighted item on the next search 0170 onCountChanged: { 0171 if (count === 0) { 0172 currentIndex = -1; 0173 } 0174 } 0175 0176 Keys.forwardTo: searchStringEdit 0177 0178 Kirigami.PlaceholderMessage { 0179 id: listViewPlaceholder 0180 anchors.centerIn: parent 0181 width: parent.width - Kirigami.Units.gridUnit 0182 visible: locationListView.count === 0 && !isSearching 0183 text: { 0184 if (canSearch) { // There is a search text 0185 return i18nc("@info", "No weather stations found for '%1'", searchStringEdit.text); 0186 } else if (hasSource) { 0187 return i18nc("@info", "Search for a weather station to change your location"); 0188 } else { 0189 return i18nc("@info", "Search for a weather station to set your location"); 0190 } 0191 } 0192 0193 } 0194 0195 QQC2.BusyIndicator { 0196 id: busy 0197 anchors.centerIn: parent 0198 visible: locationListView.count === 0 && isSearching 0199 } 0200 } 0201 }