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 }