Warning, /plasma/plasma-nm/applet/contents/ui/ConnectionItem.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2013-2017 Jan Grulich <jgrulich@redhat.com> 0003 SPDX-FileCopyrightText: 2020 Nate Graham <nate@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 0008 import QtQuick 2.15 0009 import QtQuick.Layouts 1.15 0010 import QtQuick.Controls 2.15 0011 0012 import org.kde.kcoreaddons 1.0 as KCoreAddons 0013 import org.kde.kquickcontrolsaddons 2.0 0014 0015 import org.kde.plasma.core 2.0 as PlasmaCore 0016 import org.kde.plasma.components 3.0 as PlasmaComponents3 0017 import org.kde.plasma.extras 2.0 as PlasmaExtras 0018 import org.kde.plasma.networkmanagement 0.2 as PlasmaNM 0019 0020 PlasmaExtras.ExpandableListItem { 0021 id: connectionItem 0022 0023 property bool activating: ConnectionState == PlasmaNM.Enums.Activating 0024 property bool deactivated: ConnectionState === PlasmaNM.Enums.Deactivated 0025 property bool passwordIsStatic: (SecurityType == PlasmaNM.Enums.StaticWep || SecurityType == PlasmaNM.Enums.WpaPsk || 0026 SecurityType == PlasmaNM.Enums.Wpa2Psk || SecurityType == PlasmaNM.Enums.SAE) 0027 property bool predictableWirelessPassword: !Uuid && Type == PlasmaNM.Enums.Wireless && passwordIsStatic 0028 property bool showSpeed: plasmoid.expanded && 0029 ConnectionState == PlasmaNM.Enums.Activated && 0030 (Type == PlasmaNM.Enums.Wired || 0031 Type == PlasmaNM.Enums.Wireless || 0032 Type == PlasmaNM.Enums.Gsm || 0033 Type == PlasmaNM.Enums.Cdma) 0034 0035 property real rxBytes: 0 0036 property real txBytes: 0 0037 0038 icon: model.ConnectionIcon 0039 title: model.ItemUniqueName 0040 subtitle: itemText() 0041 iconUsesPlasmaSVG: true // We want the nice detailed network SVGs from the Plasma theme 0042 isBusy: plasmoid.expanded && model.ConnectionState == PlasmaNM.Enums.Activating 0043 isDefault: ConnectionState == PlasmaNM.Enums.Activated 0044 defaultActionButtonAction: Action { 0045 id: stateChangeButton 0046 0047 readonly property bool isDeactivated: model.ConnectionState === PlasmaNM.Enums.Deactivated 0048 0049 enabled: { 0050 if (!connectionItem.expanded) { 0051 return true; 0052 } 0053 if (connectionItem.customExpandedViewContent === passwordDialogComponent) { 0054 return connectionItem.customExpandedViewContentItem.passwordField.acceptableInput; 0055 } 0056 return true; 0057 } 0058 0059 icon.name: isDeactivated ? "network-connect" : "network-disconnect" 0060 text: isDeactivated ? i18n("Connect") : i18n("Disconnect") 0061 onTriggered: changeState() 0062 } 0063 showDefaultActionButtonWhenBusy: true 0064 0065 Keys.onPressed: { 0066 if (!connectionItem.expanded) { 0067 event.accepted = false; 0068 return; 0069 } 0070 0071 if ((customExpandedViewContent == detailsComponent) && showSpeed) { 0072 if (event.key == Qt.Key_Right) { 0073 customExpandedViewContentItem.detailsTabBar.currentIndex = 1; 0074 event.accepted = true; 0075 } else if (event.key == Qt.Key_Left) { 0076 customExpandedViewContentItem.detailsTabBar.currentIndex = 0; 0077 event.accepted = true; 0078 } 0079 } 0080 } 0081 0082 contextualActionsModel: [ 0083 Action { 0084 enabled: Uuid && Type === PlasmaNM.Enums.Wireless && passwordIsStatic 0085 text: i18n("Show Network's QR Code") 0086 icon.name: "view-barcode-qr" 0087 onTriggered: handler.requestWifiCode(ConnectionPath, Ssid, SecurityType, connectionItem.title); 0088 }, 0089 Action { 0090 text: i18n("Configure…") 0091 icon.name: "configure" 0092 onTriggered: KCMShell.openSystemSettings(mainWindow.kcm, ["--args", "Uuid=" + Uuid]) 0093 } 0094 ] 0095 0096 customExpandedViewContent: detailsComponent 0097 0098 Accessible.description: `${model.AccessibleDescription} ${subtitle}` 0099 0100 Component { 0101 id: detailsComponent 0102 0103 Column { 0104 spacing: PlasmaCore.Units.smallSpacing 0105 property Item detailsTabBar: detailsTabBar 0106 0107 PlasmaComponents3.TabBar { 0108 id: detailsTabBar 0109 0110 anchors { 0111 left: parent.left 0112 right: parent.right 0113 } 0114 height: visible ? implicitHeight : 0 0115 implicitHeight: contentHeight 0116 position: PlasmaComponents3.TabBar.Header 0117 visible: showSpeed 0118 0119 PlasmaComponents3.TabButton { 0120 id: speedTabButton 0121 text: i18n("Speed") 0122 } 0123 0124 PlasmaComponents3.TabButton { 0125 id: detailsTabButton 0126 text: i18n("Details") 0127 } 0128 0129 Component.onCompleted: { 0130 if (!showSpeed) { 0131 currentIndex = 1; 0132 } 0133 } 0134 } 0135 0136 DetailsText { 0137 id: detailsTextColumn 0138 0139 width: parent.width 0140 visible: detailsTabBar.currentIndex == 1 0141 0142 activeFocusOnTab: details.length > 0 0143 details: ConnectionDetails 0144 0145 Accessible.description: details.join(" ") 0146 0147 Loader { 0148 anchors.fill: parent 0149 active: parent.activeFocus 0150 asynchronous: true 0151 z: -1 0152 0153 sourceComponent: PlasmaExtras.Highlight { 0154 hovered: true 0155 } 0156 } 0157 } 0158 0159 FocusScope { 0160 anchors { 0161 left: parent.left 0162 right: parent.right 0163 } 0164 height: trafficMonitorGraph.implicitHeight 0165 visible: detailsTabBar.currentIndex == 0 0166 0167 activeFocusOnTab: true 0168 0169 Accessible.description: i18nc("@info:tooltip", "Current download speed is %1 kibibytes per second; current upload speed is %2 kibibytes per second", Math.round(rxBytes / 1024), Math.round(txBytes / 1024)) 0170 0171 Loader { 0172 anchors.fill: parent 0173 active: parent.activeFocus 0174 asynchronous: true 0175 z: -1 0176 0177 sourceComponent: PlasmaExtras.Highlight { 0178 hovered: true 0179 } 0180 } 0181 0182 TrafficMonitor { 0183 id: trafficMonitorGraph 0184 width: parent.width 0185 downloadSpeed: rxBytes 0186 uploadSpeed: txBytes 0187 } 0188 } 0189 0190 } 0191 } 0192 0193 Component { 0194 id: passwordDialogComponent 0195 0196 ColumnLayout { 0197 property alias password: passwordField.text 0198 property alias passwordField: passwordField 0199 0200 PasswordField { 0201 id: passwordField 0202 0203 Layout.fillWidth: true 0204 Layout.leftMargin: PlasmaCore.Units.gridUnit 0205 Layout.rightMargin: PlasmaCore.Units.gridUnit 0206 0207 securityType: SecurityType 0208 0209 onAccepted: { 0210 stateChangeButton.trigger() 0211 connectionItem.customExpandedViewContent = detailsComponent 0212 } 0213 0214 Component.onCompleted: { 0215 passwordField.forceActiveFocus() 0216 setDelayModelUpdates(true) 0217 } 0218 } 0219 } 0220 } 0221 0222 Timer { 0223 id: timer 0224 repeat: true 0225 interval: 2000 0226 running: showSpeed 0227 triggeredOnStart: true 0228 property real prevRxBytes 0229 property real prevTxBytes 0230 Component.onCompleted: { 0231 prevRxBytes = 0 0232 prevTxBytes = 0 0233 } 0234 onTriggered: { 0235 rxBytes = prevRxBytes == 0 ? 0 : (RxBytes - prevRxBytes) * 1000 / interval 0236 txBytes = prevTxBytes == 0 ? 0 : (TxBytes - prevTxBytes) * 1000 / interval 0237 prevRxBytes = RxBytes 0238 prevTxBytes = TxBytes 0239 } 0240 } 0241 0242 function changeState() { 0243 if (Uuid || !predictableWirelessPassword || connectionItem.customExpandedViewContent == passwordDialogComponent) { 0244 if (ConnectionState == PlasmaNM.Enums.Deactivated) { 0245 if (!predictableWirelessPassword && !Uuid) { 0246 handler.addAndActivateConnection(DevicePath, SpecificPath) 0247 } else if (connectionItem.customExpandedViewContent == passwordDialogComponent) { 0248 if (connectionItem.customExpandedViewContentItem.password != "") { 0249 handler.addAndActivateConnection(DevicePath, SpecificPath, connectionItem.customExpandedViewContentItem.password) 0250 connectionItem.customExpandedViewContent = detailsComponent 0251 connectionItem.collapse() 0252 } else { 0253 connectionItem.expand() 0254 } 0255 } else { 0256 handler.activateConnection(ConnectionPath, DevicePath, SpecificPath) 0257 } 0258 } else { 0259 handler.deactivateConnection(ConnectionPath, DevicePath) 0260 } 0261 } else if (predictableWirelessPassword) { 0262 setDelayModelUpdates(true) 0263 connectionItem.customExpandedViewContent = passwordDialogComponent 0264 connectionItem.expand() 0265 } 0266 } 0267 0268 /* This generates the formatted text under the connection name 0269 in the popup where the connections can be "Connect"ed and 0270 "Disconnect"ed. */ 0271 function itemText() { 0272 if (ConnectionState == PlasmaNM.Enums.Activating) { 0273 if (Type == PlasmaNM.Enums.Vpn) 0274 return VpnState 0275 else 0276 return DeviceState 0277 } else if (ConnectionState == PlasmaNM.Enums.Deactivating) { 0278 if (Type == PlasmaNM.Enums.Vpn) 0279 return VpnState 0280 else 0281 return DeviceState 0282 } else if (Uuid && ConnectionState == PlasmaNM.Enums.Deactivated) { 0283 return LastUsed 0284 } else if (ConnectionState == PlasmaNM.Enums.Activated) { 0285 if (showSpeed) { 0286 return i18n("Connected, ⬇ %1/s, ⬆ %2/s", 0287 KCoreAddons.Format.formatByteSize(rxBytes), 0288 KCoreAddons.Format.formatByteSize(txBytes)) 0289 } else { 0290 return i18n("Connected") 0291 } 0292 } 0293 return "" 0294 } 0295 0296 function setDelayModelUpdates(delay: bool) { 0297 appletProxyModel.setData(appletProxyModel.index(index, 0), delay, PlasmaNM.NetworkModel.DelayModelUpdatesRole); 0298 } 0299 0300 onShowSpeedChanged: { 0301 connectionModel.setDeviceStatisticsRefreshRateMs(DevicePath, showSpeed ? 2000 : 0) 0302 } 0303 0304 onActivatingChanged: { 0305 if (ConnectionState == PlasmaNM.Enums.Activating) { 0306 ListView.view.positionViewAtBeginning() 0307 } 0308 } 0309 0310 onDeactivatedChanged: { 0311 /* Separator is part of section, which is visible only when available connections exist. Need to determine 0312 if there is a connection in use, to show Separator. Otherwise need to hide it from the top of the list. 0313 Connections in use are always on top, only need to check the first one. */ 0314 if (appletProxyModel.data(appletProxyModel.index(0, 0), PlasmaNM.NetworkModel.SectionRole) !== "Available connections") { 0315 if (connectionView.showSeparator != true) { 0316 connectionView.showSeparator = true 0317 } 0318 return 0319 } 0320 connectionView.showSeparator = false 0321 return 0322 } 0323 0324 onItemCollapsed: { 0325 connectionItem.customExpandedViewContent = detailsComponent; 0326 setDelayModelUpdates(false); 0327 } 0328 Component.onDestruction: { 0329 setDelayModelUpdates(false); 0330 } 0331 }