Unity 8
PassphraseLockscreen.qml
1 /*
2  * Copyright (C) 2013,2014,2015 Canonical, Ltd.
3  *
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.
7  *
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.
12  *
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/>.
15  */
16 
17 import QtQuick 2.4
18 import Ubuntu.Components 1.3
19 import "../Components"
20 
21 FocusScope {
22  id: root
23  y: units.gu(4)
24  height: shakeContainer.height
25  focus: true
26 
27  property string infoText
28  property string errorText
29  property bool entryEnabled: true
30  property color foregroundColor: "#000000"
31 
32  readonly property string passphrase: pinentryField.text
33 
34  signal entered(string passphrase)
35  signal cancel()
36 
37  function clear(playAnimation) {
38  pinentryField.text = "";
39  pinentryField.incorrectOverride = false;
40  pinentryField.forceActiveFocus();
41  if (playAnimation) {
42  wrongPasswordAnimation.start();
43  }
44  }
45 
46  function showText(text) {
47  pinentryField.text = text;
48  }
49 
50  Column {
51  id: shakeContainer
52  anchors.horizontalCenter: parent.horizontalCenter
53  width: parent.width
54  spacing: units.gu(2)
55 
56  Label {
57  id: infoField
58  objectName: "infoTextLabel"
59  fontSize: "x-large"
60  color: root.foregroundColor
61  anchors.horizontalCenter: parent.horizontalCenter
62  text: root.infoText
63  }
64 
65  FocusScope {
66  id: entryContainer
67  anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
68  height: units.gu(4)
69  focus: true
70 
71  TextInput {
72  id: pinentryField
73  objectName: "pinentryField"
74  focus: true
75 
76  property bool incorrectOverride: false
77 
78  anchors {
79  top: parent.top
80  left: parent.left
81  right: parent.right
82  }
83  horizontalAlignment: Text.AlignHCenter
84  font.pixelSize: FontUtils.sizeToPixels("large")
85  echoMode: TextInput.Password
86  inputMethodHints: Qt.ImhHiddenText | Qt.ImhSensitiveData |
87  Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
88  color: root.foregroundColor
89  cursorDelegate: Item {} // disable cursor
90  onCursorPositionChanged: {
91  // And because we don't show the cursor, always position the
92  // cursor at the end of the string (so backspace works like
93  // the user expects, even if they've clicked on us and
94  // thus accidentally moved the cursor)
95  if (cursorPosition !== length) {
96  cursorPosition = length
97  }
98  }
99  clip: true
100 
101  // This is so that we can draw our own dots, for we want
102  // complete control over the pixel sizes. (The ubuntu font
103  // has oddly sized password characters that don't scale right)
104  opacity: 0
105 
106  // simulate being disabled, but without removing OSK focus
107  maximumLength: root.entryEnabled ? 32767 : length
108 
109  onTextChanged: incorrectOverride = true
110 
111  onAccepted: {
112  if (pinentryField.text) {
113  root.entered(pinentryField.text);
114  }
115  }
116  }
117 
118  Row {
119  id: dotRow
120  anchors.centerIn: entryContainer
121 
122  property real dotSize: Math.min(units.gu(2), entryContainer.width / pinentryField.length)
123  spacing: Math.min(units.gu(2), Math.max(0, (entryContainer.width / pinentryField.length) - dotSize))
124 
125  Repeater {
126  model: pinentryField.length
127  delegate: Rectangle {
128  color: root.foregroundColor
129  width: dotRow.dotSize
130  height: width
131  radius: width / 2
132  }
133  }
134  }
135 
136  Label {
137  id: wrongNoticeLabel
138  objectName: "wrongNoticeLabel"
139  fontSize: "large"
140  color: root.foregroundColor
141  anchors.horizontalCenter: parent.horizontalCenter
142  horizontalAlignment: Text.AlignHCenter
143  text: root.errorText
144  visible: pinentryField.text.length == 0 && !pinentryField.incorrectOverride
145  }
146  }
147  }
148 
149  WrongPasswordAnimation {
150  id: wrongPasswordAnimation
151  objectName: "wrongPasswordAnimation"
152  target: shakeContainer
153  }
154 }