Warning, /plasma/plasma-workspace/kcms/users/src/ui/FingerprintDialog.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 Copyright 2020 Devin Lin <espidev@gmail.com> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Lesser General Public 0006 License as published by the Free Software Foundation; either 0007 version 2.1 of the License, or (at your option) version 3, or any 0008 later version accepted by the membership of KDE e.V. (or its 0009 successor approved by the membership of KDE e.V.), which shall 0010 act as a proxy defined in Section 6 of version 3 of the license. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Lesser General Public License for more details. 0016 0017 You should have received a copy of the GNU Lesser General Public 0018 License along with this library. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 import QtQuick 2.12 0022 import QtQuick.Layouts 1.3 0023 import QtQuick.Shapes 1.12 0024 import QtQuick.Controls 2.5 as QQC2 0025 0026 import org.kde.kirigami 2.12 as Kirigami 0027 import org.kde.plasma.kcm.users 1.0 as UsersKCM 0028 import FingerprintModel 1.0 0029 0030 Kirigami.OverlaySheet { 0031 id: fingerprintRoot 0032 0033 property var fingerprintModel: kcm.fingerprintModel 0034 property string currentFinger 0035 0036 enum DialogState { 0037 FingerprintList, 0038 PickFinger, 0039 Enrolling, 0040 EnrollComplete 0041 } 0042 0043 title: i18n("Configure Fingerprints") 0044 0045 footer: Kirigami.ActionToolBar { 0046 flat: false 0047 alignment: Qt.AlignRight 0048 0049 actions: [ 0050 // FingerprintList State 0051 Kirigami.Action { 0052 text: i18nc("@action:button 'all' refers to fingerprints", "Clear All") 0053 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.FingerprintList 0054 enabled: fingerprintModel.enrolledFingerprints.length !== 0 0055 icon.name: "delete" 0056 onTriggered: fingerprintModel.clearFingerprints(); 0057 }, 0058 Kirigami.Action { 0059 text: i18n("Add") 0060 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.FingerprintList 0061 enabled: fingerprintModel.availableFingersToEnroll.length !== 0 0062 icon.name: "list-add" 0063 onTriggered: fingerprintModel.dialogState = FingerprintDialog.DialogState.PickFinger 0064 }, 0065 0066 // Enrolling State 0067 Kirigami.Action { 0068 text: i18n("Cancel") 0069 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.Enrolling 0070 icon.name: "dialog-cancel" 0071 onTriggered: fingerprintModel.stopEnrolling(); 0072 }, 0073 0074 // EnrollComplete State 0075 Kirigami.Action { 0076 text: i18n("Done") 0077 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.EnrollComplete 0078 icon.name: "dialog-ok" 0079 onTriggered: fingerprintModel.stopEnrolling(); 0080 } 0081 ] 0082 } 0083 0084 Item { 0085 id: rootPanel 0086 implicitWidth: Kirigami.Units.gridUnit * 20 0087 Layout.maximumWidth: Kirigami.Units.gridUnit * 24 0088 Layout.leftMargin: Kirigami.Units.smallSpacing 0089 Layout.rightMargin: Kirigami.Units.smallSpacing 0090 height: Kirigami.Units.gridUnit * 18 0091 0092 ColumnLayout { 0093 id: enrollFeedback 0094 spacing: Kirigami.Units.largeSpacing * 2 0095 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.Enrolling || fingerprintModel.dialogState === FingerprintDialog.DialogState.EnrollComplete 0096 anchors.fill: parent 0097 0098 Kirigami.Heading { 0099 level: 2 0100 text: i18n("Enrolling Fingerprint") 0101 textFormat: Text.PlainText 0102 Layout.alignment: Qt.AlignHCenter 0103 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.Enrolling 0104 } 0105 0106 QQC2.Label { 0107 text: { 0108 if (fingerprintModel.scanType == FprintDevice.Press) { 0109 if (fingerprintRoot.currentFinger == "right-index-finger") { 0110 return i18n("Please repeatedly press your right index finger on the fingerprint sensor.") 0111 } else if (fingerprintRoot.currentFinger == "right-middle-finger") { 0112 return i18n("Please repeatedly press your right middle finger on the fingerprint sensor.") 0113 } else if (fingerprintRoot.currentFinger == "right-ring-finger") { 0114 return i18n("Please repeatedly press your right ring finger on the fingerprint sensor.") 0115 } else if (fingerprintRoot.currentFinger == "right-little-finger") { 0116 return i18n("Please repeatedly press your right little finger on the fingerprint sensor.") 0117 } else if (fingerprintRoot.currentFinger == "right-thumb") { 0118 return i18n("Please repeatedly press your right thumb on the fingerprint sensor.") 0119 } else if (fingerprintRoot.currentFinger == "left-index-finger") { 0120 return i18n("Please repeatedly press your left index finger on the fingerprint sensor.") 0121 } else if (fingerprintRoot.currentFinger == "left-middle-finger") { 0122 return i18n("Please repeatedly press your left middle finger on the fingerprint sensor.") 0123 } else if (fingerprintRoot.currentFinger == "left-ring-finger") { 0124 return i18n("Please repeatedly press your left ring finger on the fingerprint sensor.") 0125 } else if (fingerprintRoot.currentFinger == "left-little-finger") { 0126 return i18n("Please repeatedly press your left little finger on the fingerprint sensor.") 0127 } else if (fingerprintRoot.currentFinger == "left-thumb") { 0128 return i18n("Please repeatedly press your left thumb on the fingerprint sensor.") 0129 } 0130 } else if (fingerprintModel.scanType == FprintDevice.Swipe) { 0131 if (fingerprintRoot.currentFinger == "right-index-finger") { 0132 return i18n("Please repeatedly swipe your right index finger on the fingerprint sensor.") 0133 } else if (fingerprintRoot.currentFinger == "right-middle-finger") { 0134 return i18n("Please repeatedly swipe your right middle finger on the fingerprint sensor.") 0135 } else if (fingerprintRoot.currentFinger == "right-ring-finger") { 0136 return i18n("Please repeatedly swipe your right ring finger on the fingerprint sensor.") 0137 } else if (fingerprintRoot.currentFinger == "right-little-finger") { 0138 return i18n("Please repeatedly swipe your right little finger on the fingerprint sensor.") 0139 } else if (fingerprintRoot.currentFinger == "right-thumb") { 0140 return i18n("Please repeatedly swipe your right thumb on the fingerprint sensor.") 0141 } else if (fingerprintRoot.currentFinger == "left-index-finger") { 0142 return i18n("Please repeatedly swipe your left index finger on the fingerprint sensor.") 0143 } else if (fingerprintRoot.currentFinger == "left-middle-finger") { 0144 return i18n("Please repeatedly swipe your left middle finger on the fingerprint sensor.") 0145 } else if (fingerprintRoot.currentFinger == "left-ring-finger") { 0146 return i18n("Please repeatedly swipe your left ring finger on the fingerprint sensor.") 0147 } else if (fingerprintRoot.currentFinger == "left-little-finger") { 0148 return i18n("Please repeatedly swipe your left little finger on the fingerprint sensor.") 0149 } else if (fingerprintRoot.currentFinger == "left-thumb") { 0150 return i18n("Please repeatedly swipe your left thumb on the fingerprint sensor.") 0151 } 0152 } 0153 return "" 0154 } 0155 textFormat: Text.PlainText 0156 0157 Layout.alignment: Qt.AlignHCenter 0158 wrapMode: Text.Wrap 0159 horizontalAlignment: Text.AlignHCenter 0160 Layout.maximumWidth: parent.width 0161 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.Enrolling 0162 } 0163 0164 Kirigami.Heading { 0165 level: 2 0166 text: i18n("Finger Enrolled") 0167 textFormat: Text.PlainText 0168 Layout.alignment: Qt.AlignHCenter 0169 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.EnrollComplete 0170 } 0171 0172 // reset from back from whatever color was used before 0173 onVisibleChanged: progressCircle.colorTimer.restart(); 0174 0175 // progress circle 0176 FingerprintProgressCircle { 0177 id: progressCircle 0178 } 0179 0180 QQC2.Label { 0181 text: fingerprintModel.enrollFeedback 0182 textFormat: Text.PlainText 0183 wrapMode: Text.Wrap 0184 Layout.maximumWidth: parent.width 0185 Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter 0186 } 0187 } 0188 0189 ColumnLayout { 0190 id: pickFinger 0191 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.PickFinger 0192 anchors.centerIn: parent 0193 spacing: Kirigami.Units.largeSpacing 0194 width: parent.width 0195 0196 Kirigami.Heading { 0197 level: 2 0198 text: i18n("Pick a finger to enroll") 0199 textFormat: Text.PlainText 0200 Layout.alignment: Qt.AlignHCenter 0201 } 0202 0203 Item { 0204 id: handContainer 0205 implicitHeight: basePalm.height 0206 Layout.fillWidth: true 0207 0208 property string currentFinger: "" 0209 property string currentFingerData: "" 0210 0211 Image { 0212 id: basePalm 0213 source: kcm.recolorSVG(Qt.resolvedUrl("hand-images/palm.svg"), Kirigami.Theme.textColor) 0214 fillMode: Image.PreserveAspectFit 0215 width: handContainer.width 0216 opacity: 0.25 0217 } 0218 0219 Repeater { 0220 model: fingerprintModel.availableFingersToEnroll 0221 delegate: Image { 0222 id: img 0223 activeFocusOnTab: true 0224 source: kcm.recolorSVG(Qt.resolvedUrl(`hand-images/${modelData.internalName}.svg`), color) 0225 readonly property color color: focus ? 0226 Kirigami.Theme.focusColor : 0227 (maskArea.hovered ? Kirigami.Theme.hoverColor : Kirigami.Theme.textColor) 0228 0229 fillMode: Image.PreserveAspectFit 0230 anchors.fill: parent 0231 Accessible.name: modelData.friendlyName 0232 Accessible.focusable: true 0233 Accessible.role: Accessible.RadioButton 0234 Accessible.onPressAction: { 0235 img.activate() 0236 } 0237 Keys.onEnterPressed: { 0238 img.activate() 0239 } 0240 function activate() { 0241 fingerprintRoot.currentFinger = modelData.internalName; 0242 fingerprintModel.startEnrolling(modelData.internalName); 0243 } 0244 UsersKCM.MaskMouseArea { 0245 id: maskArea 0246 anchors.fill: parent 0247 onTapped: { 0248 img.activate() 0249 } 0250 } 0251 } 0252 } 0253 0254 Repeater { 0255 model: fingerprintModel.unavailableFingersToEnroll 0256 delegate: Image { 0257 source: kcm.recolorSVG(Qt.resolvedUrl(`hand-images/${modelData.internalName}.svg`), Kirigami.Theme.textColor) 0258 fillMode: Image.PreserveAspectFit 0259 anchors.fill: parent 0260 opacity: 0.25 0261 } 0262 } 0263 } 0264 } 0265 0266 ColumnLayout { 0267 id: fingerprints 0268 spacing: Kirigami.Units.smallSpacing 0269 visible: fingerprintModel.dialogState === FingerprintDialog.DialogState.FingerprintList 0270 anchors.fill: parent 0271 0272 Kirigami.InlineMessage { 0273 id: errorMessage 0274 type: Kirigami.MessageType.Error 0275 visible: fingerprintModel.currentError !== "" 0276 text: fingerprintModel.currentError 0277 Layout.fillWidth: true 0278 actions: [ 0279 Kirigami.Action { 0280 icon.name: "dialog-close" 0281 onTriggered: fingerprintModel.currentError = "" 0282 } 0283 ] 0284 } 0285 0286 ListView { 0287 id: fingerprintsList 0288 model: kcm.fingerprintModel.deviceFound ? fingerprintModel.enrolledFingerprints : 0 0289 Layout.fillWidth: true 0290 Layout.fillHeight: true 0291 QQC2.ScrollBar.vertical: QQC2.ScrollBar {} 0292 0293 delegate: Kirigami.SwipeListItem { 0294 property Finger finger: modelData 0295 // Don't need a background or hover effect for this use case 0296 hoverEnabled: false 0297 backgroundColor: "transparent" 0298 contentItem: RowLayout { 0299 Kirigami.Icon { 0300 source: "fingerprint" 0301 height: Kirigami.Units.iconSizes.medium 0302 width: Kirigami.Units.iconSizes.medium 0303 } 0304 QQC2.Label { 0305 Layout.fillWidth: true 0306 elide: Text.ElideRight 0307 text: finger.friendlyName 0308 textFormat: Text.PlainText 0309 } 0310 } 0311 actions: [ 0312 Kirigami.Action { 0313 icon.name: "edit-entry" 0314 onTriggered: { 0315 fingerprintRoot.currentFinger = finger.internalName; 0316 fingerprintModel.startEnrolling(finger.internalName); 0317 } 0318 tooltip: i18n("Re-enroll finger") 0319 }, 0320 Kirigami.Action { 0321 icon.name: "entry-delete" 0322 onTriggered: { 0323 fingerprintModel.deleteFingerprint(finger.internalName); 0324 } 0325 tooltip: i18n("Delete fingerprint") 0326 } 0327 ] 0328 } 0329 0330 Kirigami.PlaceholderMessage { 0331 anchors.centerIn: parent 0332 width: parent.width - (Kirigami.Units.largeSpacing * 4) 0333 visible: fingerprintsList.count == 0 0334 text: i18n("No fingerprints added") 0335 icon.name: "fingerprint" 0336 } 0337 } 0338 } 0339 } 0340 0341 Component.onCompleted: { 0342 fingerprintButton.dialog = this; 0343 open(); 0344 } 0345 }