on xenial help sign in
allow SIM PIN entry to have a variable pin length (by adding a done-button). Fixes: https://bugs.launchpad.net/bugs/1240561.

Approved by PS Jenkins bot, Mirco Müller.

commitfb1d1ffdecef1f088ded5e690520773c6255ebbb authorMichael Zanetti <michael.zanetti@canonical.com> dateFri 8 Nov 2013, 01:38 (13 years ago) parented260eb962f4ac
4 files changed+116−26
Components/PinPadButton.qml+40−13 Greeter/PinLockscreen.qml+34−4 Notifications/NotificationMenuItemFactory.qml−5 tests/qmltests/Greeter/tst_Lockscreen.qml+42−4
Components/PinPadButton.qml+40−13
@@ -21,24 +21,51 @@ Item {
2121 id: root
2222
2323 property alias text: label.text
24− property alias iconName: icon.name
24+ property alias subText: subTextLabel.text
25+ property string iconName
2526
2627 signal clicked()
2728
28− Label {
29− id: label
29+ Column {
3030 anchors.centerIn: parent
31− color: "#f3f3e7"
32− fontSize: "large"
33− font.weight: Font.DemiBold
34− }
31+ width: parent.width
32+ height: childrenRect.height
3533
36− Icon {
37− id: icon
38− height: units.gu(3)
39− width: height
40− anchors.centerIn: parent
41− color: "#f3f3e7"
34+ Item {
35+ anchors {
36+ left: parent.left
37+ right: parent.right
38+ }
39+ height: label.visible || icon.visible ? Math.max(label.height, icon.height) : 0
40+
41+ Label {
42+ id: label
43+ anchors.centerIn: parent
44+ width: parent.width
45+ horizontalAlignment: Text.AlignHCenter
46+ color: "#f3f3e7"
47+ fontSize: "large"
48+ font.weight: Font.DemiBold
49+ visible: text.length > 0
50+ }
51+
52+ Icon {
53+ id: icon
54+ height: units.gu(3)
55+ width: height
56+ anchors.centerIn: parent
57+ name: root.iconName
58+ color: "#f3f3e7"
59+ visible: name.length > 0
60+ }
61+ }
62+ Label {
63+ id: subTextLabel
64+ fontSize: "small"
65+ color: "grey"
66+ anchors.horizontalCenter: parent.horizontalCenter
67+ visible: text.length > 0
68+ }
4269 }
4370
4471 MouseArea {
Greeter/PinLockscreen.qml+34−4
@@ -27,7 +27,7 @@ Column {
2727 property alias placeholderText: pinentryField.placeholderText
2828 property int padWidth: units.gu(34)
2929 property int padHeight: units.gu(28)
30− property int pinLength: 4
30+ property int pinLength: -1
3131
3232 signal entered(string passphrase)
3333 signal cancel()
@@ -65,6 +65,9 @@ Column {
6565 Label {
6666 id: pinentryFieldLabel
6767 anchors.centerIn: parent
68+ width: parent.width - (backspaceIcon.width + backspaceIcon.anchors.rightMargin) * 2
69+ elide: Text.ElideMiddle
70+ horizontalAlignment: Text.AlignHCenter
6871 font.pixelSize: units.dp(44)
6972 color: "#f3f3e7"
7073 opacity: 0.6
@@ -76,6 +79,26 @@ Column {
7679 text: parent.placeholderText
7780 visible: pinentryFieldLabel.text.length == 0
7881 }
82+
83+ Icon {
84+ id: backspaceIcon
85+ objectName: "backspaceIcon"
86+ anchors {
87+ top: parent.top
88+ topMargin: units.gu(1)
89+ right: parent.right
90+ rightMargin: units.gu(2)
91+ bottom: parent.bottom
92+ bottomMargin: units.gu(1)
93+ }
94+ visible: root.pinLength == -1
95+ width: height
96+ name: "erase"
97+ MouseArea {
98+ anchors.fill: parent
99+ onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
100+ }
101+ }
79102 }
80103
81104 UbuntuShape {
@@ -154,7 +177,7 @@ Column {
154177 objectName: "pinPadButtonBack"
155178 width: root.padWidth / 3
156179 height: root.padHeight / 4
157− iconName: "back"
180+ subText: "CANCEL"
158181 onClicked: root.cancel();
159182 }
160183
@@ -171,8 +194,15 @@ Column {
171194 objectName: "pinPadButtonErase"
172195 width: root.padWidth / 3
173196 height: root.padHeight / 4
174− iconName: "erase"
175− onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1)
197+ iconName: root.pinLength == -1 ? "" : "erase"
198+ subText: root.pinLength == -1 ? "DONE" : ""
199+ onClicked: {
200+ if (root.pinLength !== -1) {
201+ pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1);
202+ } else {
203+ root.entered(pinentryField.text);
204+ }
205+ }
176206 enabled: entryEnabled
177207 }
178208 }
Notifications/NotificationMenuItemFactory.qml−5
@@ -97,11 +97,6 @@ Loader {
9797 PinLockscreen {
9898 anchors.left: parent.left; anchors.right: parent.right
9999
100− Component.onCompleted: {
101− menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-pin-length': 'int'});
102− pinLength = menuData.ext.xCanonicalPinLength;
103− }
104−
105100 onEntered: {
106101 menuModel.changeState(menuIndex, passphrase);
107102 entryEnabled = false;
tests/qmltests/Greeter/tst_Lockscreen.qml+42−4
@@ -176,15 +176,17 @@ Rectangle {
176176
177177 function test_unlock_data() {
178178 return [
179− {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true},
180− {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", unlockedSignal: true},
181− {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", unlockedSignal: false},
182− {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", unlockedSignal: false},
179+ {tag: "numeric", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true, pinLength: 4},
180+ {tag: "alphanumeric", alphanumeric: true, username: "has-password", password: "password", unlockedSignal: true, pinLength: -1},
181+ {tag: "numeric (wrong)", alphanumeric: false, username: "has-pin", password: "4321", unlockedSignal: false, pinLength: 4},
182+ {tag: "alphanumeric (wrong)", alphanumeric: true, username: "has-password", password: "drowssap", unlockedSignal: false, pinLength: -1},
183+ {tag: "flexible length", alphanumeric: false, username: "has-pin", password: "1234", unlockedSignal: true, pinLength: -1},
183184 ]
184185 }
185186
186187 function test_unlock(data) {
187188 unlockedCheckBox.checked = false
189+ pinLengthTextField.text = data.pinLength
188190 LightDM.Greeter.authenticate(data.username)
189191 waitForRendering(lockscreen)
190192
@@ -199,7 +201,12 @@ Rectangle {
199201 var button = findChild(lockscreen, "pinPadButton" + character)
200202 mouseClick(button, units.gu(1), units.gu(1))
201203 }
204+ if (data.pinLength == -1) {
205+ var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
206+ mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
207+ }
202208 }
209+
203210 tryCompare(unlockedCheckBox, "checked", data.unlockedSignal)
204211 if (!data.unlockedSignal) {
205212 // make sure the input is cleared on wrong input
@@ -208,5 +215,36 @@ Rectangle {
208215 tryCompareFunction(function() {return inputField.text.length > 0}, true)
209216 }
210217 }
218+
219+ function test_backspace_data() {
220+ return [
221+ {tag: "fixed length", pinLength: 4},
222+ {tag: "variable length", pinLength: -1}
223+ ];
224+ }
225+
226+ function test_backspace(data) {
227+ LightDM.Greeter.authenticate("has-pin");
228+ pinLengthTextField.text = data.pinLength
229+ waitForRendering(lockscreen);
230+
231+ var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase");
232+ var backspaceIcon = findChild(lockscreen, "backspaceIcon");
233+ var pinEntryField = findChild(lockscreen, "pinentryField");
234+
235+ compare(pinPadButtonErase.iconName, data.pinLength == -1 ? "" : "erase");
236+ compare(backspaceIcon.visible, data.pinLength == -1);
237+
238+ var pinPadButton5 = findChild(lockscreen, "pinPadButton5");
239+ mouseClick(pinPadButton5, units.gu(1), units.gu(1));
240+ compare(pinEntryField.text, "5");
241+
242+ if (data.pinLength == -1) {
243+ mouseClick(backspaceIcon, units.gu(1), units.gu(1));
244+ } else {
245+ mouseClick(pinPadButtonErase, units.gu(1), units.gu(1));
246+ }
247+ compare(pinEntryField.text, "");
248+ }
211249 }
212250}