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
61 onSelectedTextChanged: passwordInput.deselect()
62 onCursorPositionChanged: cursorPosition = length
64 validator: RegExpValidator {
68 inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText |
69 Qt.ImhMultiLine | // so OSK doesn't close on Enter
71 echoMode: TextInput.Password
74 cursorDelegate: Item {}
76 passwordCharacter: "●"
79 readonly property real letterSpacing: units.gu(1.75)
80 readonly property real frameSpacing: letterSpacing
82 font.pixelSize: units.gu(3)
83 font.letterSpacing: letterSpacing
87 styleName: "FocusShape"
89 // Properties needed by TextField
90 readonly property color color: d.textColor
91 readonly property color selectedTextColor: d.selectedColor
92 readonly property color selectionColor: d.textColor
93 readonly property color borderColor: "transparent"
94 readonly property color backgroundColor: "transparent"
95 readonly property color errorColor: d.errorColor
96 readonly property real frameSpacing: 0
98 // Properties needed by FocusShape
99 readonly property bool enabled: styledItem.enabled
100 readonly property bool keyNavigationFocus: styledItem.keyNavigationFocus
101 property bool activeFocusOnTab
104 onDisplayTextChanged: {
105 // We use onDisplayTextChanged instead of onTextChanged because
106 // displayText changes after text and if we did this before it
107 // updated, we would use the wrong displayText for fakeLabel.
108 root.loginError = false;
109 if (text.length === root.pincodeLength) {
114 onAccepted: respond()
117 if (root.interactive) {
118 root.accepted(passwordInput.text);
122 Keys.onEscapePressed: {
124 event.accepted = true;
130 spacing: passwordInput.frameSpacing
132 horizontalCenter: parent ? parent.horizontalCenter : undefined
133 horizontalCenterOffset: passwordInput.letterSpacing / 2
134 verticalCenter: passwordInput ? passwordInput.verticalCenter : undefined
139 objectName: "promptPinHint"
141 text: Array(root.pincodeLength).fill('○').join("")
145 pixelSize: units.gu(3)
146 letterSpacing: units.gu(1.75)
148 elide: Text.ElideRight
151 name: "keyboard-caps-enabled"
155 visible: false // TODO: detect when caps lock is on
156 anchors.verticalCenter: parent.verticalCenter
159 objectName: "greeterPromptKeyboardButton"
160 name: "input-keyboard-symbolic"
164 visible: !lomiriSettings.alwaysShowOsk && root.hasKeyboard
165 anchors.verticalCenter: parent.verticalCenter
168 onClicked: lomiriSettings.alwaysShowOsk = true
172 name: "dialog-warning-symbolic"
176 visible: root.loginError
177 anchors.verticalCenter: parent.verticalCenter
181 // Have a fake label that covers the text field after the user presses
182 // enter. What we *really* want is a disabled mode that doesn't lose OSK
183 // focus. Because our goal here is simply to keep the OSK up while
184 // we wait for PAM to get back to us, and while waiting, we don't want
185 // the user to be able to edit the field (simply because it would look
186 // weird if we allowed that). But until we have such a disabled mode,
187 // we'll fake it by covering the real text field with a label.
190 anchors.verticalCenter: extraIcons ? extraIcons.verticalCenter : undefined
191 anchors.left: extraIcons ? extraIcons.left : undefined
192 anchors.right: parent ? parent.right : undefined
193 anchors.rightMargin: passwordInput.frameSpacing * 2 + extraIcons.width
196 pixelSize: pinHint.font.pixelSize
197 letterSpacing: pinHint.font.letterSpacing
199 text: passwordInput.displayText
200 visible: !root.interactive