2 * Copyright (C) 2021 Capsia
3 * Copyright (C) 2016 Canonical, Ltd.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 3.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19import AccountsService 0.1
20import Lomiri.Components 1.3
27 property bool isSecret
28 property bool interactive: true
29 property bool loginError: false
30 property bool hasKeyboard: false
31 property alias enteredText: passwordInput.text
32 property int pincodeLength: AccountsService.pincodeLength
36 signal accepted(string response)
41 readonly property color textColor: passwordInput.enabled ? theme.palette.normal.raisedText
42 : theme.palette.disabled.raisedText
43 readonly property color selectedColor: passwordInput.enabled ? theme.palette.normal.raised
44 : theme.palette.disabled.raised
45 readonly property color drawColor: passwordInput.enabled ? theme.palette.normal.raisedSecondaryText
46 : theme.palette.disabled.raisedSecondaryText
47 readonly property color errorColor: passwordInput.enabled ? theme.palette.normal.negative
48 : theme.palette.disabled.negative
53 objectName: "promptField"
54 anchors.left: extraIcons.left
55 anchors.right: extraIcons.right
58 opacity: fakeLabel.visible ? 0 : 1
59 activeFocusOnTab: true
60 onActiveFocusChanged: if (activeFocus) Qt.inputMethod.show()
62 onSelectedTextChanged: passwordInput.deselect()
63 onCursorPositionChanged: cursorPosition = length
65 validator: RegExpValidator {
69 inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText |
70 Qt.ImhMultiLine | // so OSK doesn't close on Enter
72 echoMode: TextInput.Password
75 cursorDelegate: Item {}
77 passwordCharacter: "●"
80 readonly property real letterSpacing: units.gu(1.75)
81 readonly property real frameSpacing: letterSpacing
83 font.pixelSize: units.gu(3)
84 font.letterSpacing: letterSpacing
88 styleName: "FocusShape"
90 // Properties needed by TextField
91 readonly property color color: d.textColor
92 readonly property color selectedTextColor: d.selectedColor
93 readonly property color selectionColor: d.textColor
94 readonly property color borderColor: "transparent"
95 readonly property color backgroundColor: "transparent"
96 readonly property color errorColor: d.errorColor
97 readonly property real frameSpacing: 0
99 // Properties needed by FocusShape
100 readonly property bool enabled: styledItem.enabled
101 readonly property bool keyNavigationFocus: styledItem.keyNavigationFocus
102 property bool activeFocusOnTab
105 onDisplayTextChanged: {
106 // We use onDisplayTextChanged instead of onTextChanged because
107 // displayText changes after text and if we did this before it
108 // updated, we would use the wrong displayText for fakeLabel.
109 root.loginError = false;
110 if (text.length === root.pincodeLength) {
115 onAccepted: respond()
118 if (root.interactive) {
119 root.accepted(passwordInput.text);
123 Keys.onEscapePressed: {
124 lomiriSettings.alwaysShowOsk = false
126 event.accepted = true;
132 spacing: passwordInput.frameSpacing
134 horizontalCenter: parent ? parent.horizontalCenter : undefined
135 horizontalCenterOffset: passwordInput.letterSpacing / 2
136 verticalCenter: passwordInput ? passwordInput.verticalCenter : undefined
141 objectName: "promptPinHint"
143 text: Array(root.pincodeLength).fill('○').join("")
147 pixelSize: units.gu(3)
148 letterSpacing: units.gu(1.75)
150 elide: Text.ElideRight
153 name: "keyboard-caps-enabled"
157 visible: false // TODO: detect when caps lock is on
158 anchors.verticalCenter: parent.verticalCenter
161 objectName: "greeterPromptKeyboardButton"
162 name: "input-keyboard-symbolic"
166 visible: !lomiriSettings.alwaysShowOsk && root.hasKeyboard
167 anchors.verticalCenter: parent.verticalCenter
170 onClicked: lomiriSettings.alwaysShowOsk = true
174 name: "dialog-warning-symbolic"
178 visible: root.loginError
179 anchors.verticalCenter: parent.verticalCenter
183 // Have a fake label that covers the text field after the user presses
184 // enter. What we *really* want is a disabled mode that doesn't lose OSK
185 // focus. Because our goal here is simply to keep the OSK up while
186 // we wait for PAM to get back to us, and while waiting, we don't want
187 // the user to be able to edit the field (simply because it would look
188 // weird if we allowed that). But until we have such a disabled mode,
189 // we'll fake it by covering the real text field with a label.
192 anchors.verticalCenter: extraIcons ? extraIcons.verticalCenter : undefined
193 anchors.left: extraIcons ? extraIcons.left : undefined
194 anchors.right: parent ? parent.right : undefined
195 anchors.rightMargin: passwordInput.frameSpacing * 2 + extraIcons.width
198 pixelSize: pinHint.font.pixelSize
199 letterSpacing: pinHint.font.letterSpacing
201 text: passwordInput.displayText
202 visible: !root.interactive