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 Lomiri.Components 1.3
24 objectName: "promptPassword"
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
35 signal accepted(string response)
40 readonly property color textColor: passwordInput.enabled ? theme.palette.normal.raisedText
41 : theme.palette.disabled.raisedText
42 readonly property color selectedColor: passwordInput.enabled ? theme.palette.normal.raised
43 : theme.palette.disabled.raised
44 readonly property color drawColor: passwordInput.enabled ? theme.palette.normal.raisedSecondaryText
45 : theme.palette.disabled.raisedSecondaryText
46 readonly property color errorColor: passwordInput.enabled ? theme.palette.normal.negative
47 : theme.palette.disabled.negative
54 Behavior on border.color {
58 color: root.loginError ? d.errorColor : d.drawColor
59 width: root.loginError ? units.dp(2): units.dp(1)
65 objectName: "promptField"
69 opacity: fakeLabel.visible ? 0 : 1
70 activeFocusOnTab: true
72 onSelectedTextChanged: passwordInput.deselect()
74 validator: RegExpValidator {
78 inputMethodHints: Qt.ImhSensitiveData | Qt.ImhNoPredictiveText |
79 Qt.ImhMultiLine // so OSK doesn't close on Enter
80 echoMode: root.isSecret ? TextInput.Password : TextInput.Normal
83 passwordCharacter: "●"
86 readonly property real frameSpacing: units.gu(1)
90 styleName: "FocusShape"
92 // Properties needed by TextField
93 readonly property color color: d.textColor
94 readonly property color selectedTextColor: d.selectedColor
95 readonly property color selectionColor: d.textColor
96 readonly property color borderColor: "transparent"
97 readonly property color backgroundColor: "transparent"
98 readonly property color errorColor: d.errorColor
99 readonly property real frameSpacing: styledItem.frameSpacing
101 // Properties needed by FocusShape
102 readonly property bool enabled: styledItem.enabled
103 readonly property bool keyNavigationFocus: styledItem.keyNavigationFocus
104 property bool activeFocusOnTab
110 spacing: passwordInput.frameSpacing
111 anchors.verticalCenter: parent.verticalCenter
113 name: "keyboard-caps-enabled"
117 visible: root.isSecret && false // TODO: detect when caps lock is on
118 anchors.verticalCenter: parent.verticalCenter
121 objectName: "greeterPromptKeyboardButton"
122 name: "input-keyboard-symbolic"
126 visible: !lomiriSettings.alwaysShowOsk && root.hasKeyboard
127 anchors.verticalCenter: parent.verticalCenter
130 onClicked: lomiriSettings.alwaysShowOsk = true
134 name: "dialog-warning-symbolic"
138 visible: root.loginError
139 anchors.verticalCenter: parent.verticalCenter
142 name: "toolkit_chevron-ltr_2gu"
143 height: units.gu(2.5)
146 visible: !root.loginError
147 anchors.verticalCenter: parent.verticalCenter
150 onClicked: root.accepted(passwordInput.text)
156 onDisplayTextChanged: {
157 // We use onDisplayTextChanged instead of onTextChanged because
158 // displayText changes after text and if we did this before it
159 // updated, we would use the wrong displayText for fakeLabel.
160 root.loginError = false;
163 onAccepted: respond()
166 if (root.interactive) {
167 root.accepted(passwordInput.text);
171 Keys.onEscapePressed: {
173 event.accepted = true;
177 // We use our own custom placeholder label instead of the standard
178 // TextField one because the standard one hardcodes baseText as the
179 // palette color, whereas we want raisedSecondaryText.
182 objectName: "promptHint"
184 left: passwordInput ? passwordInput.left : undefined
185 right: passwordInput ? passwordInput.right : undefined
186 verticalCenter: passwordInput ? passwordInput.verticalCenter : undefined
187 leftMargin: units.gu(2)
188 rightMargin: anchors.leftMargin + extraIcons.width
191 visible: passwordInput.text == "" && !passwordInput.inputMethodComposing
194 elide: Text.ElideRight
197 // Have a fake label that covers the text field after the user presses
198 // enter. What we *really* want is a disabled mode that doesn't lose OSK
199 // focus. Because our goal here is simply to keep the OSK up while
200 // we wait for PAM to get back to us, and while waiting, we don't want
201 // the user to be able to edit the field (simply because it would look
202 // weird if we allowed that). But until we have such a disabled mode,
203 // we'll fake it by covering the real text field with a label.
206 anchors.verticalCenter: parent ? parent.verticalCenter : undefined
207 anchors.left: parent ? parent.left : undefined
208 anchors.right: parent ? parent.right : undefined
209 anchors.leftMargin: passwordInput.frameSpacing * 2
210 anchors.rightMargin: passwordInput.frameSpacing * 2 + extraIcons.width
212 text: passwordInput.displayText
213 visible: !root.interactive