2 * Copyright (C) 2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 import Ubuntu.Components 1.3
19 import "../Components"
23 implicitHeight: units.gu(5)
26 property bool isPrompt
27 property bool isAlphanumeric
29 property bool isSecret
33 signal responded(string text)
36 passwordInput.text = "";
41 function showFakePassword() {
42 // Just a silly hack for looking like 4 pin numbers got entered, if
43 // a fingerprint was used and we happen to be using a pin. This was
44 // a request from Design.
45 if (isSecret && isPrompt && !isAlphanumeric) {
47 text = "...."; // actual text doesn't matter
54 property bool enabled: true
55 readonly property color textColor: passwordInput.enabled ? theme.palette.normal.raisedText
56 : theme.palette.disabled.raisedText
57 readonly property color selectedColor: passwordInput.enabled ? theme.palette.normal.raised
58 : theme.palette.disabled.raised
59 readonly property color drawColor: passwordInput.enabled ? theme.palette.normal.raisedSecondaryText
60 : theme.palette.disabled.raisedSecondaryText
61 readonly property color errorColor: passwordInput.enabled ? theme.palette.normal.negative
62 : theme.palette.disabled.negative
66 fakeLabel.text = passwordInput.displayText;
73 border.width: units.dp(1)
74 border.color: d.drawColor
79 Component.onCompleted: updateFocus()
80 onIsPromptChanged: updateFocus()
81 function updateFocus() {
83 passwordInput.focus = true;
85 promptButton.focus = true;
91 objectName: "promptButton"
93 visible: !root.isPrompt
95 function triggered() {
103 height: parent.height;
112 Keys.onReturnPressed: triggered();
113 Keys.onEnterPressed: triggered();
116 onClicked: parent.triggered();
120 anchors.centerIn: parent
128 objectName: "promptField"
130 visible: root.isPrompt
131 opacity: fakeLabel.visible ? 0 : 1
133 validator: RegExpValidator {
134 regExp: root.isAlphanumeric ? /^.*$/ : /^\d{4}$/
137 inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText |
138 Qt.ImhMultiLine | // so OSK doesn't close on Enter
139 (root.isAlphanumeric ? Qt.ImhNone : Qt.ImhDigitsOnly)
140 echoMode: root.isSecret ? TextInput.Password : TextInput.Normal
141 hasClearButton: false
143 readonly property real frameSpacing: units.gu(0.5)
146 property color color: d.textColor
147 property color selectedTextColor: d.selectedColor
148 property color selectionColor: d.textColor
149 property color borderColor: "transparent"
150 property color backgroundColor: "transparent"
151 property color errorColor: d.errorColor
152 property real frameSpacing: passwordInput.frameSpacing
159 name: "keyboard-caps-enabled"
163 visible: root.isSecret && false // TODO: detect when caps lock is on
164 readonly property real visibleWidth: visible ? width + passwordInput.frameSpacing : 0
168 onDisplayTextChanged: {
169 // We use onDisplayTextChanged instead of onTextChanged because
170 // displayText changes after text and if we did this before it
171 // updated, we would use the wrong displayText for fakeLabel.
172 if (!isAlphanumeric && text.length >= 4) {
173 // hard limit of 4 for passcodes right now
178 onAccepted: respond()
183 root.responded(text);
187 Keys.onEscapePressed: {
189 event.accepted = true;
192 // We use our own custom placeholder label instead of the standard
193 // TextField one because the standard one hardcodes baseText as the
194 // palette color, whereas we want raisedSecondaryText.
200 verticalCenter: parent.verticalCenter
201 leftMargin: units.gu(1.5)
202 rightMargin: anchors.leftMargin + capsIcon.visibleWidth
205 visible: passwordInput.text == "" && !passwordInput.inputMethodComposing
207 elide: Text.ElideRight
211 // Have a fake label that covers the text field after the user presses
212 // enter. What we *really* want is a disabled mode that doesn't lose OSK
213 // focus. Because our goal here is simply to keep the OSK up while
214 // we wait for PAM to get back to us, and while waiting, we don't want
215 // the user to be able to edit the field (simply because it would look
216 // weird if we allowed that). But until we have such a disabled mode,
217 // we'll fake it by covering the real text field with a label.
220 anchors.verticalCenter: parent.verticalCenter
221 anchors.left: parent.left
222 anchors.right: parent.right
223 anchors.leftMargin: passwordInput.frameSpacing * 2
224 anchors.rightMargin: passwordInput.frameSpacing * 2 + capsIcon.visibleWidth
226 visible: root.isPrompt && !d.enabled