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