Merge lp:~mzanetti/unity8/new-lockscreen-design into lp:unity8
- new-lockscreen-design
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michael Terry |
Approved revision: | 1176 |
Merged at revision: | 1193 |
Proposed branch: | lp:~mzanetti/unity8/new-lockscreen-design |
Merge into: | lp:unity8 |
Diff against target: |
1266 lines (+392/-423) 10 files modified
po/unity8.pot (+34/-38) qml/Components/Lockscreen.qml (+35/-77) qml/Components/PassphraseLockscreen.qml (+3/-3) qml/Components/PinLockscreen.qml (+171/-183) qml/Components/PinPadButton.qml (+35/-49) qml/Notifications/NotificationMenuItemFactory.qml (+4/-1) qml/Shell.qml (+11/-7) tests/autopilot/unity8/shell/tests/test_lock_screen.py (+2/-2) tests/qmltests/Greeter/tst_Lockscreen.qml (+65/-46) tests/qmltests/tst_ShellWithPin.qml (+32/-17) |
To merge this branch: | bzr merge lp:~mzanetti/unity8/new-lockscreen-design |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Albert Astals Cid (community) | Abstain | ||
Michał Sawicz | Needs Fixing | ||
Michael Terry | Approve | ||
Andrea Cimitan | Pending | ||
Review via email: mp+230478@code.launchpad.net |
Commit message
Implement new lockscreen designs
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list.
no
* Did you perform an exploratory manual test run of your code change and any related functionality?
yes
* Did you make sure that your branch does not contain spurious tags?
yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
no
* If you changed the UI, has there been a design review?
no
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1143
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1148. By Launchpad Translations on behalf of unity-team
-
Launchpad automatic translations update.
- 1149. By Mirco Müller
-
Allow ENTER/RETURN in a TextField to accept a snap-decision notification. Fixes: 1305885
Approved by: Michael Zanetti - 1150. By Michael Terry
-
* Add --lightdm= argument to ./run.sh that lets developers choose which lightdm backend to use
* Stop letting a user that is immediately denied via PAM into the shell by fixing some assumptions that a user which was not prompted was successfully authenticated. This is not a common situation, you'd have to manually change your PAM config.
* Fix a small console warning
Approved by: Michał Sawicz - 1151. By Michał Sawicz
-
Fix anchor in PreviewListView
.qml.
Approved by: Andrea Cimitan - 1152. By Michael Terry
-
Make wrong-password handling much nicer by showing a pretty spinner while we wait for PAM, by improving the prompt text to match designs, by forcing the user to wait five seconds after every five failed attemps, and by supporting (but not yet enabling) an opt-in "factory-reset your phone after X failed attemps" feature.
Approved by: Michał Sawicz - 1153. By Michał Sawicz
-
Add new horizontal list category layout. Fixes: 1352226
Approved by: Andrea Cimitan - 1154. By Michael Zanetti
-
bring back network caching in dash Fixes: 1355729
Approved by: Pawel Stolowski - 1155. By Michał Sawicz
-
Fix qml tests - loader around PageHeader, more retries for selecting a scope and undefined attributes in mock overview scope.
Approved by: Michael Zanetti - 1156. By Leo Arias
-
Added autopilot helpers and tests for the launcher and dash icon.
Approved by: Michał Sawicz, Brendan Donegan - 1157. By Leo Arias
-
Added an autopilot helper to click a scope item.
Approved by: Michał Sawicz - 1158. By Leo Arias
-
Added an autopilot test for focusing an app clicking the icon on the launcher.
Approved by: Michał Sawicz, Brendan Donegan - 1159. By PS Jenkins bot
-
Releasing 8.00+14.
10.20140814. 1-0ubuntu1 - 1160. By PS Jenkins bot
-
Resync trunk
- 1161. By Launchpad Translations on behalf of unity-team
-
Launchpad automatic translations update.
- 1162. By Michael Zanetti
-
new lockscreen design
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1162
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Terry (mterry) wrote : | # |
Comments inline as well as:
- The errorText is below the infoText, but the spec seems to have it above.
- Spec indicates we should still autoconfirm for device passcode
(This is just a partial review)
- 1163. By Michael Zanetti
-
update shaking behavior as info appeared in spec
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1163
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1163
http://
Executed test runs:
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1163
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
There are QML and autopilot failures.
- 1164. By Michael Zanetti
-
fix qmltests
- 1165. By Michael Zanetti
-
fix ap tests
Michael Zanetti (mzanetti) wrote : | # |
> There are QML and autopilot failures.
fixed
Michael Zanetti (mzanetti) wrote : | # |
> Comments inline as well as:
>
> - The errorText is below the infoText, but the spec seems to have it above.
Spec doesn't work out in this case... See comments in the spec. We don't want to move the infoText around all the time
> - Spec indicates we should still autoconfirm for device passcode
added it back somehow, even though the spec doesn't say anything about how it should look like...
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1165
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1166. By Michael Zanetti
-
update Lockscreen tests for the brought back autoconfirm mode
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1166
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Terry (mterry) wrote : | # |
Some more inline comments.
- 1167. By Michael Zanetti
-
bring back the autoconfirm comment and reset logic
- 1168. By Michael Zanetti
-
revert accidental change
- 1169. By Michael Zanetti
-
fix test
- 1170. By Michael Zanetti
-
cleanup strings and debug print as per review
Michael Zanetti (mzanetti) wrote : | # |
> Some more inline comments.
All fixed. Thanks.
Michael Zanetti (mzanetti) wrote : | # |
found the inline replies again :) Thought they were lost after a wrong click.
Michael Terry (mterry) wrote : | # |
In playing with it, I noticed that if you hit the forced delay and go back to the greeter and then back again to the lockscreen, you lose the errorText that says "too many incorrect attempts"
Michał Sawicz (saviq) : | # |
Michael Terry (mterry) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1170
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1171. By Michael Zanetti
-
make it better translatable
Michael Zanetti (mzanetti) : | # |
- 1172. By Michael Zanetti
-
fix test
- 1173. By Michael Zanetti
-
lock it again when the forcedDelayTimer is running and its recreated
Michael Zanetti (mzanetti) wrote : | # |
> In playing with it, I noticed that if you hit the forced delay and go back to
> the greeter and then back again to the lockscreen, you lose the errorText that
> says "too many incorrect attempts"
fixed that too
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1172
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Terry (mterry) wrote : | # |
Last thing I noticed: when you enter the "too many incorrect attempts" screen, the whole pin pad shifts down a bit. Looks odd. After that, I swear I'll approve :)
- 1174. By Michael Zanetti
-
make sure the retryLabel uses its space even when empty
Michael Zanetti (mzanetti) wrote : | # |
> Last thing I noticed: when you enter the "too many incorrect attempts" screen,
> the whole pin pad shifts down a bit. Looks odd. After that, I swear I'll
> approve :)
Ok. Fixed it by making the retryText label always consume its space... Hope that's fine
Michael Terry (mterry) wrote : | # |
Awesome, thanks! Looks fine to me now.
Michael Terry (mterry) wrote : | # |
* Did you perform an exploratory manual test run of the code change and any related functionality?
- Yes
* Did CI run pass? If not, please explain why.
- Yes
Michał Sawicz (saviq) wrote : | # |
Design comments from Olga:
- unnecessary confirm button
- "Emergency call" should be bigger
- should say "PIN" not "passcode"...
Michael Zanetti (mzanetti) wrote : | # |
> Design comments from Olga:
>
> - unnecessary confirm button
> - "Emergency call" should be bigger
> - should say "PIN" not "passcode"...
done
- 1175. By Michael Zanetti
-
update as per design review
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1173
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1175
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olga Kemmet (olga-kemmet) wrote : | # |
Confirming comments from M. Zanetti.
Michael Terry (mterry) wrote : | # |
@mzanetti, Olga mentioned to me via email that we should just not show the check in autoconfirm mode (rather than this branch's current implementation of disabling the check).
Michael Zanetti (mzanetti) wrote : | # |
@mterry: See rev 1175
Albert Astals Cid (aacid) wrote : | # |
Please update the .pot file
- 1176. By Michael Zanetti
-
update pot
Albert Astals Cid (aacid) wrote : | # |
.pot has been updated.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1176
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'po/unity8.pot' |
2 | --- po/unity8.pot 2014-08-13 18:09:19 +0000 |
3 | +++ po/unity8.pot 2014-08-21 09:36:47 +0000 |
4 | @@ -8,7 +8,7 @@ |
5 | msgstr "" |
6 | "Project-Id-Version: unity8\n" |
7 | "Report-Msgid-Bugs-To: \n" |
8 | -"POT-Creation-Date: 2014-08-13 14:09-0400\n" |
9 | +"POT-Creation-Date: 2014-08-21 11:36+0200\n" |
10 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
12 | "Language-Team: LANGUAGE <LL@li.org>\n" |
13 | @@ -92,19 +92,19 @@ |
14 | "phone<br><br>Tap on the screen to start" |
15 | msgstr "" |
16 | |
17 | -#: qml/Components/Lockscreen.qml:161 |
18 | +#: qml/Components/Lockscreen.qml:167 |
19 | +msgid "Please wait" |
20 | +msgstr "" |
21 | + |
22 | +#: qml/Components/Lockscreen.qml:172 |
23 | msgid "Too many incorrect attempts" |
24 | msgstr "" |
25 | |
26 | -#: qml/Components/Lockscreen.qml:163 |
27 | -msgid "Please wait" |
28 | -msgstr "" |
29 | - |
30 | -#: qml/Components/Lockscreen.qml:245 |
31 | +#: qml/Components/Lockscreen.qml:206 |
32 | msgid "Emergency Call" |
33 | msgstr "" |
34 | |
35 | -#: qml/Components/Lockscreen.qml:268 |
36 | +#: qml/Components/Lockscreen.qml:226 |
37 | msgid "OK" |
38 | msgstr "" |
39 | |
40 | @@ -117,23 +117,15 @@ |
41 | msgid "Hello" |
42 | msgstr "" |
43 | |
44 | -#: qml/Components/PinLockscreen.qml:197 |
45 | -msgid "CANCEL" |
46 | -msgstr "" |
47 | - |
48 | -#: qml/Components/PinLockscreen.qml:215 |
49 | -msgid "DONE" |
50 | -msgstr "" |
51 | - |
52 | -#: qml/Dash/GenericScopeView.qml:360 |
53 | +#: qml/Dash/GenericScopeView.qml:361 |
54 | msgid "See less" |
55 | msgstr "" |
56 | |
57 | -#: qml/Dash/GenericScopeView.qml:360 |
58 | +#: qml/Dash/GenericScopeView.qml:361 |
59 | msgid "See all" |
60 | msgstr "" |
61 | |
62 | -#: qml/Dash/GenericScopeView.qml:423 qml/Panel/SearchIndicator.qml:27 |
63 | +#: qml/Dash/GenericScopeView.qml:424 qml/Panel/SearchIndicator.qml:27 |
64 | msgid "Search" |
65 | msgstr "" |
66 | |
67 | @@ -201,12 +193,16 @@ |
68 | msgid "Speaking..." |
69 | msgstr "" |
70 | |
71 | -#: qml/Notifications/NotificationMenuItemFactory.qml:100 |
72 | +#: qml/Notifications/NotificationMenuItemFactory.qml:105 |
73 | msgid "Show password" |
74 | msgstr "" |
75 | |
76 | -#: qml/Notifications/NotificationMenuItemFactory.qml:115 |
77 | -msgid "Please enter SIM PIN" |
78 | +#: qml/Notifications/NotificationMenuItemFactory.qml:120 |
79 | +msgid "Enter SIM PIN" |
80 | +msgstr "" |
81 | + |
82 | +#: qml/Notifications/NotificationMenuItemFactory.qml:121 qml/Shell.qml:270 |
83 | +msgid "Sorry, incorrect PIN" |
84 | msgstr "" |
85 | |
86 | #: qml/Panel/ActiveCallHint.qml:77 |
87 | @@ -249,47 +245,47 @@ |
88 | msgid "Roaming" |
89 | msgstr "" |
90 | |
91 | -#: qml/Shell.qml:267 |
92 | -msgid "passphrase" |
93 | +#: qml/Shell.qml:266 |
94 | +msgid "Enter your passphrase" |
95 | msgstr "" |
96 | |
97 | #: qml/Shell.qml:267 |
98 | -msgid "passcode" |
99 | +msgid "Sorry, incorrect passphrase" |
100 | msgstr "" |
101 | |
102 | #: qml/Shell.qml:269 |
103 | +msgid "Enter your PIN" |
104 | +msgstr "" |
105 | + |
106 | +#: qml/Shell.qml:273 |
107 | #, qt-format |
108 | msgid "Enter your %1" |
109 | msgstr "" |
110 | |
111 | -#: qml/Shell.qml:270 |
112 | +#: qml/Shell.qml:274 |
113 | #, qt-format |
114 | -msgid "Incorrect %1" |
115 | -msgstr "" |
116 | - |
117 | -#: qml/Shell.qml:272 |
118 | -msgid "Please re-enter" |
119 | -msgstr "" |
120 | - |
121 | -#: qml/Shell.qml:306 |
122 | +msgid "Sorry, incorrect %1" |
123 | +msgstr "" |
124 | + |
125 | +#: qml/Shell.qml:310 |
126 | msgid "Sorry, incorrect passphrase." |
127 | msgstr "" |
128 | |
129 | -#: qml/Shell.qml:307 |
130 | +#: qml/Shell.qml:311 |
131 | msgid "Sorry, incorrect passcode." |
132 | msgstr "" |
133 | |
134 | -#: qml/Shell.qml:308 |
135 | +#: qml/Shell.qml:312 |
136 | msgid "This will be your last attempt." |
137 | msgstr "" |
138 | |
139 | -#: qml/Shell.qml:310 |
140 | +#: qml/Shell.qml:314 |
141 | msgid "" |
142 | "If passphrase is entered incorrectly, your phone will conduct a factory " |
143 | "reset and all personal data will be deleted." |
144 | msgstr "" |
145 | |
146 | -#: qml/Shell.qml:311 |
147 | +#: qml/Shell.qml:315 |
148 | msgid "" |
149 | "If passcode is entered incorrectly, your phone will conduct a factory reset " |
150 | "and all personal data will be deleted." |
151 | |
152 | === modified file 'qml/Components/Lockscreen.qml' |
153 | --- qml/Components/Lockscreen.qml 2014-08-13 13:59:08 +0000 |
154 | +++ qml/Components/Lockscreen.qml 2014-08-21 09:36:47 +0000 |
155 | @@ -24,15 +24,14 @@ |
156 | // Determine if a numeric or alphanumeric pad is used. |
157 | property bool alphaNumeric: false |
158 | |
159 | - // Placeholder text |
160 | - property string placeholderText: "" |
161 | - // Placeholder text while shaking (e.g. Incorrect passprase) |
162 | - property string wrongPlaceholderText: "" |
163 | + // Informational text. (e.g. some text to tell which domain this is pin is entered for) |
164 | + property string infoText: "" |
165 | + |
166 | // Retries text (e.g. 3 retries left) |
167 | property string retryText: "" |
168 | |
169 | - // Informational text. (e.g. some text to tell which domain this is pin is entered for. |
170 | - property string infoText: "" |
171 | + // The text to be displayed in case the login failed |
172 | + property string errorText: "" |
173 | |
174 | // In case the Lockscreen can show a greeter message, this is the username |
175 | property string username: "" |
176 | @@ -110,41 +109,6 @@ |
177 | anchors.fill: root |
178 | } |
179 | |
180 | - Column { |
181 | - spacing: units.gu(2) |
182 | - anchors { |
183 | - left: parent.left |
184 | - right: parent.right |
185 | - bottom: pinPadLoader.top |
186 | - bottomMargin: units.gu(2) |
187 | - } |
188 | - Label { |
189 | - objectName: "retryCountLabel" |
190 | - anchors { |
191 | - left: parent.left |
192 | - right: parent.right |
193 | - } |
194 | - text: root.retryText |
195 | - horizontalAlignment: Text.AlignHCenter |
196 | - color: "#f3f3e7" |
197 | - opacity: 0.6 |
198 | - visible: root.retryText.length > 0 |
199 | - } |
200 | - Label { |
201 | - id: infoTextLabel |
202 | - objectName: "infoTextLabel" |
203 | - anchors { |
204 | - left: parent.left |
205 | - right: parent.right |
206 | - } |
207 | - text: root.infoText |
208 | - horizontalAlignment: Text.AlignHCenter |
209 | - color: "#f3f3e7" |
210 | - opacity: 0.6 |
211 | - visible: root.infoText.length > 0 |
212 | - } |
213 | - } |
214 | - |
215 | Loader { |
216 | id: pinPadLoader |
217 | objectName: "pinPadLoader" |
218 | @@ -152,21 +116,22 @@ |
219 | left: parent.left |
220 | right: parent.right |
221 | verticalCenter: parent.verticalCenter |
222 | - verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : -units.gu(4) |
223 | + verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : 0 |
224 | } |
225 | property bool resetting: false |
226 | property bool waiting: false |
227 | property bool showWrongText: false |
228 | |
229 | - readonly property string forcedDelayText: i18n.tr("Too many incorrect attempts") + |
230 | - "\n" + |
231 | - i18n.tr("Please wait") |
232 | - |
233 | source: (!resetting && root.required) ? (root.alphaNumeric ? "PassphraseLockscreen.qml" : "PinLockscreen.qml") : "" |
234 | onSourceChanged: { |
235 | waiting = false |
236 | showWrongText = false |
237 | } |
238 | + onLoaded: { |
239 | + if (forcedDelayTimer.running) { |
240 | + pinPadLoader.item.clear(true) |
241 | + } |
242 | + } |
243 | |
244 | Connections { |
245 | target: pinPadLoader.item |
246 | @@ -193,10 +158,19 @@ |
247 | } |
248 | Binding { |
249 | target: pinPadLoader.item |
250 | - property: "placeholderText" |
251 | - value: forcedDelayTimer.running ? pinPadLoader.forcedDelayText : |
252 | - (pinPadLoader.showWrongText ? root.wrongPlaceholderText : |
253 | - root.placeholderText) |
254 | + property: "infoText" |
255 | + value: root.infoText |
256 | + } |
257 | + Binding { |
258 | + target: pinPadLoader.item |
259 | + property: "retryText" |
260 | + value: forcedDelayTimer.running ? i18n.tr("Please wait") : root.retryText |
261 | + } |
262 | + Binding { |
263 | + target: pinPadLoader.item |
264 | + property: "errorText" |
265 | + value: forcedDelayTimer.running ? i18n.tr("Too many incorrect attempts") : |
266 | + (pinPadLoader.showWrongText ? root.errorText : "") |
267 | } |
268 | Binding { |
269 | target: pinPadLoader.item |
270 | @@ -210,8 +184,9 @@ |
271 | } |
272 | } |
273 | |
274 | - Column { |
275 | - id: emergencyCallColumn |
276 | + Label { |
277 | + id: emergencyCallLabel |
278 | + objectName: "emergencyCallLabel" |
279 | |
280 | // FIXME: We *should* show emergency dialer if there is a SIM present, |
281 | // regardless of whether the side stage is enabled. But right now, |
282 | @@ -223,37 +198,20 @@ |
283 | visible: !shell.sideStageEnabled |
284 | |
285 | anchors { |
286 | - left: parent.left |
287 | bottom: parent.bottom |
288 | bottomMargin: units.gu(4) |
289 | - right: parent.right |
290 | - } |
291 | - height: childrenRect.height |
292 | - spacing: units.gu(1) |
293 | - |
294 | - Icon { |
295 | - objectName: "emergencyCallIcon" |
296 | - height: units.gu(3) |
297 | - width: height |
298 | - anchors.horizontalCenter: parent.horizontalCenter |
299 | - name: "phone-app-call-symbolic" |
300 | - color: "#f3f3e7" |
301 | - opacity: 0.6 |
302 | - } |
303 | - |
304 | - Label { |
305 | - text: i18n.tr("Emergency Call") |
306 | - color: "#f3f3e7" |
307 | - opacity: 0.6 |
308 | - fontSize: "medium" |
309 | - anchors.horizontalCenter: parent.horizontalCenter |
310 | - } |
311 | + horizontalCenter: parent.horizontalCenter |
312 | + } |
313 | + |
314 | + text: i18n.tr("Emergency Call") |
315 | + color: "#f3f3e7" |
316 | + opacity: 0.6 |
317 | } |
318 | |
319 | MouseArea { |
320 | - anchors.fill: emergencyCallColumn |
321 | + anchors.fill: emergencyCallLabel |
322 | onClicked: root.emergencyCall() |
323 | - enabled: emergencyCallColumn.visible |
324 | + enabled: emergencyCallLabel.visible |
325 | } |
326 | |
327 | Component { |
328 | |
329 | === modified file 'qml/Components/PassphraseLockscreen.qml' |
330 | --- qml/Components/PassphraseLockscreen.qml 2014-08-13 13:59:08 +0000 |
331 | +++ qml/Components/PassphraseLockscreen.qml 2014-08-21 09:36:47 +0000 |
332 | @@ -22,7 +22,7 @@ |
333 | id: root |
334 | height: highlightItem.height |
335 | |
336 | - property string placeholderText |
337 | + property string infoText |
338 | property string username: "" |
339 | property bool entryEnabled: true |
340 | |
341 | @@ -75,8 +75,8 @@ |
342 | echoMode: TextInput.Password |
343 | opacity: 0.9 |
344 | hasClearButton: false |
345 | - enabled: entryEnabled |
346 | - placeholderText: root.placeholderText |
347 | + enabled: root.entryEnabled |
348 | + placeholderText: root.infoText |
349 | |
350 | onAccepted: { |
351 | if (pinentryField.text) { |
352 | |
353 | === modified file 'qml/Components/PinLockscreen.qml' |
354 | --- qml/Components/PinLockscreen.qml 2014-08-13 13:59:08 +0000 |
355 | +++ qml/Components/PinLockscreen.qml 2014-08-21 09:36:47 +0000 |
356 | @@ -22,9 +22,11 @@ |
357 | Column { |
358 | id: root |
359 | anchors.centerIn: parent |
360 | - spacing: units.gu(3.5) |
361 | + spacing: units.gu(2) |
362 | |
363 | - property alias placeholderText: pinentryField.placeholderText |
364 | + property string infoText |
365 | + property string retryText |
366 | + property string errorText |
367 | property int padWidth: units.gu(34) |
368 | property int padHeight: units.gu(28) |
369 | property int minPinLength: -1 |
370 | @@ -35,199 +37,185 @@ |
371 | |
372 | property bool entryEnabled: true |
373 | |
374 | - function clear(playAnimation) { |
375 | + function clear(showAnimation) { |
376 | pinentryField.text = ""; |
377 | - if (playAnimation) { |
378 | + if (showAnimation) { |
379 | + pinentryField.incorrectOverride = true; |
380 | wrongPasswordAnimation.start(); |
381 | } |
382 | } |
383 | |
384 | - QtObject { |
385 | - id: priv |
386 | - property bool autoConfirm: root.minPinLength == root.maxPinLength && root.minPinLength != -1 |
387 | - } |
388 | - |
389 | - UbuntuShape { |
390 | - id: pinentryField |
391 | - objectName: "pinentryField" |
392 | + Column { |
393 | + id: shakeContainer |
394 | anchors.horizontalCenter: parent.horizontalCenter |
395 | - color: "#55000000" |
396 | - width:root.padWidth |
397 | - height: units.gu(5) |
398 | - radius: "medium" |
399 | - property string text: "" |
400 | - property string placeholderText: "" |
401 | - |
402 | - function appendChar(character) { |
403 | - if (root.maxPinLength == -1 || pinentryField.text.length < root.maxPinLength) { |
404 | - pinentryField.text = pinentryField.text + character; |
405 | - } |
406 | - } |
407 | - |
408 | - onTextChanged: { |
409 | - pinentryFieldLabel.text = ""; |
410 | - for (var i = 0; i < text.length; ++i) { |
411 | - pinentryFieldLabel.text += "•"; |
412 | - } |
413 | - if (priv.autoConfirm && text.length === root.maxPinLength) { |
414 | - root.entered(text); |
415 | - } |
416 | - } |
417 | - |
418 | - Label { |
419 | - id: pinentryFieldLabel |
420 | - anchors.centerIn: parent |
421 | - width: parent.width - (backspaceIcon.width + backspaceIcon.anchors.rightMargin) * 2 |
422 | - elide: Text.ElideMiddle |
423 | - horizontalAlignment: Text.AlignHCenter |
424 | - font.pixelSize: units.dp(44) |
425 | - color: "#f3f3e7" |
426 | - opacity: 0.6 |
427 | - } |
428 | - Label { |
429 | - id: pinentryFieldPlaceHolder |
430 | - objectName: "pinentryFieldPlaceHolder" |
431 | - anchors.centerIn: parent |
432 | - horizontalAlignment: Text.AlignHCenter |
433 | - color: "#f3f3e7" |
434 | - opacity: 0.6 |
435 | - text: parent.placeholderText |
436 | - visible: pinentryFieldLabel.text.length == 0 |
437 | - } |
438 | - |
439 | - Icon { |
440 | - id: backspaceIcon |
441 | - objectName: "backspaceIcon" |
442 | - anchors { |
443 | - top: parent.top |
444 | - topMargin: units.gu(1) |
445 | - right: parent.right |
446 | - rightMargin: units.gu(2) |
447 | - bottom: parent.bottom |
448 | - bottomMargin: units.gu(1) |
449 | - } |
450 | - visible: entryEnabled && !priv.autoConfirm |
451 | - width: height |
452 | - name: "erase" |
453 | - color: "#f3f3e7" |
454 | - opacity: 0.6 |
455 | - MouseArea { |
456 | - anchors.fill: parent |
457 | - onClicked: pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1); |
458 | - } |
459 | - } |
460 | - } |
461 | - |
462 | - UbuntuShape { |
463 | - anchors { |
464 | - left: parent.left |
465 | - right: parent.right |
466 | - margins: (parent.width - root.padWidth) / 2 |
467 | - } |
468 | - height: root.padHeight |
469 | - color: "#55000000" |
470 | - radius: "medium" |
471 | - |
472 | - ThinDivider { |
473 | - anchors { |
474 | - left: parent.left |
475 | - right: parent.right |
476 | - top: parent.top |
477 | - topMargin: root.padHeight / 4 |
478 | - } |
479 | - } |
480 | - ThinDivider { |
481 | - anchors { |
482 | - left: parent.left |
483 | - right: parent.right |
484 | - verticalCenter: parent.verticalCenter |
485 | - } |
486 | - } |
487 | - ThinDivider { |
488 | - anchors { |
489 | - left: parent.left |
490 | - right: parent.right |
491 | - bottom: parent.bottom |
492 | - bottomMargin: root.padHeight / 4 |
493 | - } |
494 | - } |
495 | - |
496 | - ThinDivider { |
497 | - anchors.centerIn: parent |
498 | - anchors.horizontalCenterOffset: -root.padWidth / 6 |
499 | - width: root.padHeight |
500 | - rotation: -90 |
501 | - } |
502 | - ThinDivider { |
503 | - anchors.centerIn: parent |
504 | - anchors.horizontalCenterOffset: root.padWidth / 6 |
505 | - width: root.padHeight |
506 | - rotation: -90 |
507 | - } |
508 | - |
509 | - Grid { |
510 | - anchors { |
511 | - left: parent.left |
512 | - right: parent.right |
513 | - margins: (parent.width - root.padWidth) / 2 |
514 | - } |
515 | - |
516 | - columns: 3 |
517 | - |
518 | - Repeater { |
519 | - model: 9 |
520 | - |
521 | - PinPadButton { |
522 | - objectName: "pinPadButton" + (index + 1) |
523 | - width: root.padWidth / 3 |
524 | - height: root.padHeight / 4 |
525 | - text: index + 1 |
526 | - enabled: entryEnabled |
527 | - |
528 | - onClicked: { |
529 | - pinentryField.appendChar(text); |
530 | - } |
531 | - } |
532 | - } |
533 | - |
534 | - PinPadButton { |
535 | - objectName: "pinPadButtonBack" |
536 | - width: root.padWidth / 3 |
537 | - height: root.padHeight / 4 |
538 | - subText: i18n.tr("CANCEL") |
539 | - onClicked: root.cancel(); |
540 | - } |
541 | - |
542 | - PinPadButton { |
543 | - objectName: "pinPadButton0" |
544 | - width: root.padWidth / 3 |
545 | - height: root.padHeight / 4 |
546 | - text: "0" |
547 | - onClicked: pinentryField.appendChar(text); |
548 | - enabled: entryEnabled |
549 | - } |
550 | - |
551 | - PinPadButton { |
552 | - objectName: "pinPadButtonErase" |
553 | - width: root.padWidth / 3 |
554 | - height: root.padHeight / 4 |
555 | - iconName: priv.autoConfirm ? "erase" : "" |
556 | - subText: priv.autoConfirm ? "" : i18n.tr("DONE") |
557 | + width: parent.width |
558 | + spacing: units.gu(2) |
559 | + |
560 | + Label { |
561 | + id: infoField |
562 | + objectName: "infoTextLabel" |
563 | + fontSize: "large" |
564 | + color: "#f3f3e7" |
565 | + anchors.horizontalCenter: parent.horizontalCenter |
566 | + text: root.infoText |
567 | + } |
568 | + |
569 | + Item { |
570 | + id: pinContainer |
571 | + anchors { left: parent.left; right: parent.right; margins: units.gu(2) } |
572 | + height: units.gu(4) |
573 | + |
574 | + Row { |
575 | + id: pinentryField |
576 | + objectName: "pinentryField" |
577 | + anchors.horizontalCenter: parent.horizontalCenter |
578 | + anchors.verticalCenter: parent.verticalCenter |
579 | + spacing: Math.max(0, Math.min(units.gu(3), (parent.width / root.maxPinLength) - units.gu(3))) |
580 | + |
581 | + property string text |
582 | + property bool incorrectOverride: false |
583 | + |
584 | + Repeater { |
585 | + model: pinentryField.text.length |
586 | + delegate: Rectangle { |
587 | + color: "#f3f3e7" |
588 | + width: Math.min(units.gu(2), (pinContainer.width - pinContainer.height*2 ) / (root.maxPinLength >= 0 ? root.maxPinLength : 16)) |
589 | + height: width |
590 | + radius: width / 2 |
591 | + } |
592 | + } |
593 | + |
594 | + function appendNumber(number) { |
595 | + if (incorrectOverride) { |
596 | + incorrectOverride = false; |
597 | + } |
598 | + |
599 | + pinentryField.text = pinentryField.text + number |
600 | + |
601 | + if (root.minPinLength > 0 && root.maxPinLength > 0 |
602 | + && root.minPinLength == root.maxPinLength && pinentryField.text.length == root.minPinLength) { |
603 | + root.entered(pinentryField.text) |
604 | + } |
605 | + } |
606 | + |
607 | + function backspace() { |
608 | + pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1) |
609 | + } |
610 | + } |
611 | + Label { |
612 | + id: wrongNoticeLabel |
613 | + objectName: "wrongNoticeLabel" |
614 | + fontSize: "x-large" |
615 | + color: "#f3f3e7" |
616 | + anchors.horizontalCenter: parent.horizontalCenter |
617 | + text: root.errorText |
618 | + visible: pinentryField.incorrectOverride |
619 | + } |
620 | + |
621 | + AbstractButton { |
622 | + objectName: "backspaceIcon" |
623 | + anchors { right: parent.right; top: parent.top; bottom: parent.bottom } |
624 | + width: height |
625 | + |
626 | + Icon { |
627 | + anchors.fill: parent |
628 | + name: "erase" |
629 | + color: "#f3f3e7" |
630 | + } |
631 | + |
632 | + opacity: (pinentryField.text.length && !pinentryField.incorrectOverride) > 0 ? 1 : 0 |
633 | + |
634 | + Behavior on opacity { |
635 | + UbuntuNumberAnimation {} |
636 | + } |
637 | + |
638 | + onClicked: pinentryField.backspace() |
639 | + } |
640 | + } |
641 | + |
642 | + Label { |
643 | + objectName: "retryLabel" |
644 | + fontSize: "x-small" |
645 | + color: "#f3f3e7" |
646 | + anchors.horizontalCenter: parent.horizontalCenter |
647 | + text: root.retryText || " " |
648 | + } |
649 | + } |
650 | + |
651 | + ThinDivider { |
652 | + anchors { left: parent.left; right: parent.right; margins: units.gu(2) } |
653 | + } |
654 | + |
655 | + Grid { |
656 | + id: numbersGrid |
657 | + anchors { horizontalCenter: parent.horizontalCenter } |
658 | + columns: 3 |
659 | + |
660 | + property int buttonHeight: units.gu(8) |
661 | + property int buttonWidth: units.gu(12) |
662 | + |
663 | + Repeater { |
664 | + model: 9 |
665 | + |
666 | + PinPadButton { |
667 | + objectName: "pinPadButton" + text |
668 | + text: index + 1 |
669 | + height: numbersGrid.buttonHeight |
670 | + width: numbersGrid.buttonWidth |
671 | + enabled: root.entryEnabled && (root.maxPinLength == -1 || |
672 | + pinentryField.text.length < root.maxPinLength || |
673 | + pinentryField.incorrectOverride) |
674 | + |
675 | onClicked: { |
676 | - if (priv.autoConfirm) { |
677 | - pinentryField.text = pinentryField.text.substring(0, pinentryField.text.length-1); |
678 | - } else { |
679 | - root.entered(pinentryField.text); |
680 | - } |
681 | + pinentryField.appendNumber(index + 1) |
682 | } |
683 | - enabled: priv.autoConfirm ? entryEnabled : pinentryField.text.length >= root.minPinLength |
684 | - } |
685 | + } |
686 | + } |
687 | + Item { |
688 | + height: numbersGrid.buttonHeight |
689 | + width: numbersGrid.buttonWidth |
690 | + } |
691 | + PinPadButton { |
692 | + text: "0" |
693 | + height: numbersGrid.buttonHeight |
694 | + width: numbersGrid.buttonWidth |
695 | + enabled: root.entryEnabled && (root.maxPinLength == -1 || |
696 | + pinentryField.text.length < root.maxPinLength || |
697 | + pinentryField.incorrectOverride) |
698 | + |
699 | + onClicked: { |
700 | + pinentryField.appendNumber(0) |
701 | + } |
702 | + } |
703 | + Item { |
704 | + height: numbersGrid.buttonHeight |
705 | + width: numbersGrid.buttonWidth |
706 | + } |
707 | + PinPadButton { |
708 | + iconName: "close" |
709 | + height: numbersGrid.buttonHeight |
710 | + width: numbersGrid.buttonWidth |
711 | + |
712 | + onClicked: root.cancel() |
713 | + } |
714 | + Item { |
715 | + height: numbersGrid.buttonHeight |
716 | + width: numbersGrid.buttonWidth |
717 | + } |
718 | + PinPadButton { |
719 | + iconName: "tick" |
720 | + objectName: "confirmButton" |
721 | + height: numbersGrid.buttonHeight |
722 | + width: numbersGrid.buttonWidth |
723 | + enabled: root.enabled && pinentryField.text.length >= root.minPinLength |
724 | + visible: root.minPinLength == -1 || root.minPinLength !== root.maxPinLength |
725 | + |
726 | + onClicked: root.entered(pinentryField.text) |
727 | } |
728 | } |
729 | - |
730 | WrongPasswordAnimation { |
731 | id: wrongPasswordAnimation |
732 | objectName: "wrongPasswordAnimation" |
733 | - target: pinentryField |
734 | + target: shakeContainer |
735 | } |
736 | } |
737 | |
738 | === modified file 'qml/Components/PinPadButton.qml' |
739 | --- qml/Components/PinPadButton.qml 2014-05-20 11:51:26 +0000 |
740 | +++ qml/Components/PinPadButton.qml 2014-08-21 09:36:47 +0000 |
741 | @@ -15,62 +15,48 @@ |
742 | */ |
743 | |
744 | import QtQuick 2.0 |
745 | -import Ubuntu.Components 0.1 |
746 | +import Ubuntu.Components 1.1 |
747 | |
748 | -Item { |
749 | +AbstractButton { |
750 | id: root |
751 | opacity: enabled ? 1 : 0.6 |
752 | |
753 | property alias text: label.text |
754 | - property alias subText: subTextLabel.text |
755 | property string iconName |
756 | |
757 | - signal clicked() |
758 | - |
759 | - Column { |
760 | - anchors.centerIn: parent |
761 | - width: parent.width |
762 | - height: childrenRect.height |
763 | - |
764 | - Item { |
765 | - anchors { |
766 | - left: parent.left |
767 | - right: parent.right |
768 | - } |
769 | - height: label.visible || icon.visible ? Math.max(label.height, icon.height) : 0 |
770 | - |
771 | - Label { |
772 | - id: label |
773 | - anchors.centerIn: parent |
774 | - width: parent.width |
775 | - horizontalAlignment: Text.AlignHCenter |
776 | - color: "#f3f3e7" |
777 | - fontSize: "large" |
778 | - font.weight: Font.DemiBold |
779 | - visible: text.length > 0 |
780 | - } |
781 | - |
782 | - Icon { |
783 | - id: icon |
784 | - height: units.gu(3) |
785 | - width: height |
786 | - anchors.centerIn: parent |
787 | - name: root.iconName |
788 | - color: "#f3f3e7" |
789 | - visible: name.length > 0 |
790 | - } |
791 | - } |
792 | - Label { |
793 | - id: subTextLabel |
794 | - fontSize: "small" |
795 | - color: "#f3f3e7" |
796 | - anchors.horizontalCenter: parent.horizontalCenter |
797 | - visible: text.length > 0 |
798 | - } |
799 | - } |
800 | - |
801 | - MouseArea { |
802 | + UbuntuShape { |
803 | anchors.fill: parent |
804 | - onClicked: root.clicked() |
805 | + opacity: root.pressed ? 1 : 0 |
806 | + Behavior on opacity { |
807 | + UbuntuNumberAnimation {} |
808 | + } |
809 | + } |
810 | + |
811 | + Label { |
812 | + id: label |
813 | + anchors.centerIn: parent |
814 | + horizontalAlignment: Text.AlignHCenter |
815 | + color: "#f3f3e7" |
816 | + fontSize: "x-large" |
817 | + font.weight: Font.DemiBold |
818 | + visible: text.length > 0 |
819 | + scale: root.pressed ? 0.9 : 1 |
820 | + Behavior on scale { |
821 | + UbuntuNumberAnimation {} |
822 | + } |
823 | + } |
824 | + |
825 | + Icon { |
826 | + id: icon |
827 | + height: units.gu(3) |
828 | + width: height |
829 | + anchors.centerIn: parent |
830 | + name: root.iconName |
831 | + color: "#f3f3e7" |
832 | + visible: name.length > 0 |
833 | + scale: root.pressed ? 0.9 : 1 |
834 | + Behavior on scale { |
835 | + UbuntuNumberAnimation { duration: UbuntuAnimation.SlowDuration } |
836 | + } |
837 | } |
838 | } |
839 | |
840 | === modified file 'qml/Notifications/NotificationMenuItemFactory.qml' |
841 | --- qml/Notifications/NotificationMenuItemFactory.qml 2014-08-14 01:28:23 +0000 |
842 | +++ qml/Notifications/NotificationMenuItemFactory.qml 2014-08-21 09:36:47 +0000 |
843 | @@ -117,7 +117,10 @@ |
844 | right: parent.right |
845 | } |
846 | height: menuFactory.maxHeight |
847 | - placeholderText: i18n.tr("Please enter SIM PIN") |
848 | + infoText: i18n.tr("Enter SIM PIN") |
849 | + errorText: i18n.tr("Sorry, incorrect PIN") |
850 | + minPinLength: 4 |
851 | + maxPinLength: 8 |
852 | background: shell.background |
853 | |
854 | onEntered: { |
855 | |
856 | === modified file 'qml/Shell.qml' |
857 | --- qml/Shell.qml 2014-08-20 09:19:32 +0000 |
858 | +++ qml/Shell.qml 2014-08-21 09:36:47 +0000 |
859 | @@ -273,15 +273,19 @@ |
860 | |
861 | onShowPrompt: { |
862 | if (greeter.narrowMode) { |
863 | - var promptText = text.toLowerCase() |
864 | if (isDefaultPrompt) { |
865 | - promptText = lockscreen.alphaNumeric ? |
866 | - i18n.tr("passphrase") : i18n.tr("passcode") |
867 | + if (lockscreen.alphaNumeric) { |
868 | + lockscreen.infoText = i18n.tr("Enter your passphrase") |
869 | + lockscreen.errorText = i18n.tr("Sorry, incorrect passphrase") |
870 | + } else { |
871 | + lockscreen.infoText = i18n.tr("Enter your PIN") |
872 | + lockscreen.errorText = i18n.tr("Sorry, incorrect PIN") |
873 | + } |
874 | + } else { |
875 | + lockscreen.infoText = i18n.tr("Enter your %1").arg(text.toLowerCase()) |
876 | + lockscreen.errorText = i18n.tr("Sorry, incorrect %1").arg(text.toLowerCase()) |
877 | } |
878 | - lockscreen.placeholderText = i18n.tr("Enter your %1").arg(promptText) |
879 | - lockscreen.wrongPlaceholderText = i18n.tr("Incorrect %1").arg(promptText) + |
880 | - "\n" + |
881 | - i18n.tr("Please re-enter") |
882 | + |
883 | lockscreen.show(); |
884 | } |
885 | } |
886 | |
887 | === modified file 'tests/autopilot/unity8/shell/tests/test_lock_screen.py' |
888 | --- tests/autopilot/unity8/shell/tests/test_lock_screen.py 2014-07-31 21:04:12 +0000 |
889 | +++ tests/autopilot/unity8/shell/tests/test_lock_screen.py 2014-08-21 09:36:47 +0000 |
890 | @@ -54,7 +54,7 @@ |
891 | self.main_window.enter_pin_code("1234") |
892 | self.assertThat(lockscreen.shown, Eventually(Equals(False))) |
893 | else: |
894 | - self._enter_prompt_passphrase("1234") |
895 | + self._enter_prompt_passphrase("1234\n") |
896 | self.assertThat(greeter.shown, Eventually(Equals(False))) |
897 | |
898 | @with_lightdm_mock("single-passphrase") |
899 | @@ -86,7 +86,7 @@ |
900 | self.assertThat(pinentryField.text, Eventually(Equals(""))) |
901 | self.assertThat(lockscreen.shown, Eventually(Equals(True))) |
902 | else: |
903 | - self._enter_prompt_passphrase("4231") |
904 | + self._enter_prompt_passphrase("4231\n") |
905 | prompt = self.main_window.get_greeter().get_prompt() |
906 | self.assertThat(prompt.text, Eventually(Equals(""))) |
907 | self.assertThat(greeter.shown, Eventually(Equals(True))) |
908 | |
909 | === modified file 'tests/qmltests/Greeter/tst_Lockscreen.qml' |
910 | --- tests/qmltests/Greeter/tst_Lockscreen.qml 2014-08-01 10:38:20 +0000 |
911 | +++ tests/qmltests/Greeter/tst_Lockscreen.qml 2014-08-21 09:36:47 +0000 |
912 | @@ -26,22 +26,21 @@ |
913 | Rectangle { |
914 | id: root |
915 | width: units.gu(80) |
916 | - height: units.gu(80) |
917 | + height: units.gu(70) |
918 | color: "orange" |
919 | |
920 | Lockscreen { |
921 | id: lockscreen |
922 | anchors.fill: parent |
923 | - anchors.rightMargin: units.gu(30) |
924 | - placeholderText: "Please enter your PIN" |
925 | - wrongPlaceholderText: "Incorrect PIN" |
926 | + anchors.rightMargin: units.gu(40) |
927 | + infoText: infoTextTextField.text |
928 | retryText: retryCountTextField.text |
929 | + errorText: errorTextTextField.text |
930 | alphaNumeric: pinPadCheckBox.checked |
931 | minPinLength: minPinLengthTextField.text |
932 | maxPinLength: maxPinLengthTextField.text |
933 | username: "Lola" |
934 | background: "../../../qml/graphics/phone_background.jpg" |
935 | - infoText: infoTextTextField.text |
936 | } |
937 | |
938 | Connections { |
939 | @@ -68,7 +67,7 @@ |
940 | } else { |
941 | pinPadCheckBox.checked = true |
942 | } |
943 | - lockscreen.placeholderText = text; |
944 | + lockscreen.infoText = text; |
945 | } |
946 | } |
947 | |
948 | @@ -157,7 +156,14 @@ |
949 | id: infoTextTextField |
950 | width: parent.width |
951 | placeholderText: "Infotext" |
952 | - text: "+49 179 3253553" |
953 | + text: "Enter SIM1 PIN" |
954 | + } |
955 | + |
956 | + TextField { |
957 | + id: errorTextTextField |
958 | + width: parent.width |
959 | + placeholderText: "Error text" |
960 | + text: "Sorry, incorrect PIN" |
961 | } |
962 | |
963 | TextField { |
964 | @@ -223,7 +229,7 @@ |
965 | emergencyCheckBox.checked = false |
966 | pinPadCheckBox.checked = data.alphanumeric |
967 | waitForLockscreenReady(); |
968 | - var emergencyButton = findChild(lockscreen, "emergencyCallIcon") |
969 | + var emergencyButton = findChild(lockscreen, "emergencyCallLabel") |
970 | mouseClick(emergencyButton, units.gu(1), units.gu(1)) |
971 | tryCompare(emergencyCheckBox, "checked", true) |
972 | |
973 | @@ -231,18 +237,20 @@ |
974 | |
975 | function test_labels_data() { |
976 | return [ |
977 | - {tag: "numeric", alphanumeric: false, placeholderText: "Please enter your PIN", username: "foobar" }, |
978 | - {tag: "alphanumeric", alphanumeric: true, placeholderText: "Please enter your password", username: "Lola" } |
979 | + {tag: "numeric", alphanumeric: false, infoText: "Please enter your PIN", username: "foobar" }, |
980 | + {tag: "alphanumeric", alphanumeric: true, infoText: "Please enter your password", username: "Lola" } |
981 | ] |
982 | } |
983 | |
984 | function test_labels(data) { |
985 | pinPadCheckBox.checked = data.alphanumeric |
986 | - lockscreen.placeholderText = data.placeholderText |
987 | + lockscreen.infoText = data.infoText |
988 | waitForLockscreenReady(); |
989 | - compare(findChild(lockscreen, "pinentryField").placeholderText, data.placeholderText, "Placeholdertext is not what it should be") |
990 | if (data.alphanumeric) { |
991 | + compare(findChild(lockscreen, "pinentryField").placeholderText, data.infoText, "Placeholdertext is not what it should be") |
992 | compare(findChild(lockscreen, "greeterLabel").text, "Hello " + data.username, "Greeter is not set correctly") |
993 | + } else { |
994 | + compare(findChild(lockscreen, "infoTextLabel").text, data.infoText, "Placeholdertext is not what it should be") |
995 | } |
996 | } |
997 | |
998 | @@ -276,10 +284,8 @@ |
999 | var button = findChild(lockscreen, "pinPadButton" + character) |
1000 | mouseClick(button, units.gu(1), units.gu(1)) |
1001 | } |
1002 | - if (data.minPinLength !== data.maxPinLength || data.minPinLength == -1) { |
1003 | - var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase"); |
1004 | - mouseClick(pinPadButtonErase, units.gu(1), units.gu(1)); |
1005 | - } |
1006 | + var confirmButton = findChild(lockscreen, "confirmButton"); |
1007 | + mouseClick(confirmButton, units.gu(1), units.gu(1)); |
1008 | } |
1009 | tryCompare(enteredLabel, "text", data.password) |
1010 | } |
1011 | @@ -317,11 +323,9 @@ |
1012 | wait(0) // Trigger event loop to make sure the animation would start running |
1013 | compare(animation.running, data.animation) |
1014 | if (data.animation) { |
1015 | - if (data.alphanumeric) { |
1016 | - tryCompare(inputField, "placeholderText", lockscreen.wrongPlaceholderText) |
1017 | - } else { |
1018 | - var label = findChild(lockscreen, "pinentryFieldPlaceHolder"); |
1019 | - tryCompare(label, "text", lockscreen.wrongPlaceholderText) |
1020 | + if (!data.alphanumeric) { |
1021 | + var label = findChild(lockscreen, "wrongNoticeLabel"); |
1022 | + tryCompare(label, "visible", true) |
1023 | } |
1024 | } |
1025 | |
1026 | @@ -343,24 +347,21 @@ |
1027 | maxPinLengthTextField.text = data.maxPinLength |
1028 | waitForLockscreenReady(); |
1029 | |
1030 | - var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase"); |
1031 | var backspaceIcon = findChild(lockscreen, "backspaceIcon"); |
1032 | var pinEntryField = findChild(lockscreen, "pinentryField"); |
1033 | |
1034 | - var autoConfirmEnabled = data.minPinLength === data.maxPinLength && data.minPinLength !== -1; |
1035 | - compare(pinPadButtonErase.iconName, autoConfirmEnabled ? "erase" : ""); |
1036 | - compare(backspaceIcon.visible, !autoConfirmEnabled); |
1037 | + compare(backspaceIcon.opacity, 0); |
1038 | |
1039 | var pinPadButton5 = findChild(lockscreen, "pinPadButton5"); |
1040 | mouseClick(pinPadButton5, units.gu(1), units.gu(1)); |
1041 | compare(pinEntryField.text, "5"); |
1042 | |
1043 | - if (data.minPinLength !== data.maxPinLength) { |
1044 | - mouseClick(backspaceIcon, units.gu(1), units.gu(1)); |
1045 | - } else { |
1046 | - mouseClick(pinPadButtonErase, units.gu(1), units.gu(1)); |
1047 | - } |
1048 | + tryCompare(backspaceIcon, "opacity", 1); |
1049 | + |
1050 | + mouseClick(backspaceIcon, units.gu(1), units.gu(1)); |
1051 | compare(pinEntryField.text, ""); |
1052 | + |
1053 | + tryCompare(backspaceIcon, "opacity", 0); |
1054 | } |
1055 | |
1056 | function test_minMaxLength_data() { |
1057 | @@ -373,37 +374,55 @@ |
1058 | |
1059 | function test_minMaxLength(data) { |
1060 | pinPadCheckBox.checked = false |
1061 | - minPinLengthTextField.text = data.minPinLength |
1062 | - maxPinLengthTextField.text = data.maxPinLength |
1063 | + minPinLengthTextField.text = data.minPinLength; |
1064 | + maxPinLengthTextField.text = data.maxPinLength; |
1065 | waitForLockscreenReady(); |
1066 | |
1067 | var pinPadButton5 = findChild(lockscreen, "pinPadButton5"); |
1068 | - var pinPadButtonErase = findChild(lockscreen, "pinPadButtonErase"); |
1069 | - var inputField = findChild(lockscreen, "pinentryField") |
1070 | + var backspaceButton = findChild(lockscreen, "backspaceIcon"); |
1071 | + var confirmButton = findChild(lockscreen, "confirmButton"); |
1072 | + var inputField = findChild(lockscreen, "pinentryField"); |
1073 | + |
1074 | + tryCompare(backspaceButton, "opacity", 0); |
1075 | + |
1076 | + tryCompare(confirmButton, "visible", (data.minPinLength != data.maxPinLength) || (data.minPinLength == -1)); |
1077 | |
1078 | for (var i = 0; i < 10; i++) { |
1079 | mouseClick(pinPadButton5, units.gu(1), units.gu(1)); |
1080 | + tryCompare(backspaceButton, "opacity", 1) |
1081 | |
1082 | - if (data.minPinLength == data.maxPinLength && data.minPinLength != -1) { |
1083 | - // auto confirm mode... |
1084 | - compare(inputField.text.length, (i+1) % data.minPinLength); |
1085 | + if (data.maxPinLength == data.minPinLength && data.minPinLength > 0) { |
1086 | + // Autoconfirm mode. This will automatically confirm (and with it reset) |
1087 | + // the textfield every data.minPinLength presses |
1088 | + if (i+1 < data.minPinLength) { |
1089 | + compare(inputField.text.length, i + 1); |
1090 | + } else { |
1091 | + compare(inputField.text.length, (i+1) % data.minPinLength) |
1092 | + } |
1093 | } else { |
1094 | - // manual confirm mode |
1095 | - tryCompare(pinPadButtonErase, "enabled", (i+1) >= data.minPinLength) |
1096 | if (data.maxPinLength == -1) { |
1097 | + // Undefined maxLength... make sure all presses are recorded |
1098 | compare(inputField.text.length, i+1); |
1099 | } else { |
1100 | + // We have a max length. Make sure we're only accepting maxLength presses |
1101 | compare(inputField.text.length, Math.min(data.maxPinLength, i+1)); |
1102 | } |
1103 | |
1104 | + if (data.minPinLength == -1) { |
1105 | + // Undefined minLength. Make sure confirm button is always enabled |
1106 | + compare(confirmButton.enabled, true); |
1107 | + } else { |
1108 | + // We have a min length. Make sure the confirm button is only enabled when met. |
1109 | + compare(confirmButton.enabled, (i+1) >= data.minPinLength); |
1110 | + } |
1111 | } |
1112 | } |
1113 | } |
1114 | |
1115 | function test_retryDisplay_data() { |
1116 | return [ |
1117 | - {tag: "empty", retryText: "", shown: false}, |
1118 | - {tag: "3 retries left", retryText: "3 retries left", shown: true}, |
1119 | + {tag: "empty", retryText: " "}, |
1120 | + {tag: "3 retries left", retryText: "3 retries left"}, |
1121 | ] |
1122 | } |
1123 | |
1124 | @@ -412,8 +431,8 @@ |
1125 | waitForLockscreenReady(); |
1126 | |
1127 | retryCountTextField.text = data.retryText; |
1128 | - var label = findChild(lockscreen, "retryCountLabel") |
1129 | - compare(label.visible, data.shown); |
1130 | + var label = findChild(lockscreen, "retryLabel") |
1131 | + compare(label.text, data.retryText); |
1132 | } |
1133 | |
1134 | function test_infoPopup() { |
1135 | @@ -438,8 +457,8 @@ |
1136 | |
1137 | function test_infoTextDisplay_data() { |
1138 | return [ |
1139 | - {tag: "empty string", text: "", shown: false}, |
1140 | - {tag: "hello world", text: "hello world", shown: true}, |
1141 | + {tag: "empty string", text: ""}, |
1142 | + {tag: "hello world", text: "hello world"}, |
1143 | ] |
1144 | } |
1145 | |
1146 | @@ -449,7 +468,7 @@ |
1147 | |
1148 | infoTextTextField.text = data.text; |
1149 | var label = findChild(lockscreen, "infoTextLabel") |
1150 | - compare(label.visible, data.shown); |
1151 | + compare(label.text, data.text); |
1152 | } |
1153 | } |
1154 | |
1155 | |
1156 | === modified file 'tests/qmltests/tst_ShellWithPin.qml' |
1157 | --- tests/qmltests/tst_ShellWithPin.qml 2014-08-13 18:11:03 +0000 |
1158 | +++ tests/qmltests/tst_ShellWithPin.qml 2014-08-21 09:36:47 +0000 |
1159 | @@ -15,6 +15,7 @@ |
1160 | */ |
1161 | |
1162 | import QtQuick 2.0 |
1163 | +import Ubuntu.Components 1.0 |
1164 | import QtTest 1.0 |
1165 | import AccountsService 0.1 |
1166 | import GSettings 1.0 |
1167 | @@ -28,7 +29,7 @@ |
1168 | |
1169 | Item { |
1170 | id: root |
1171 | - width: shell.width |
1172 | + width: shell.width + units.gu(20) |
1173 | height: shell.height |
1174 | |
1175 | QtObject { |
1176 | @@ -49,6 +50,20 @@ |
1177 | |
1178 | Shell { |
1179 | id: shell |
1180 | + maxFailedLogins: maxRetriesTextField.text |
1181 | + } |
1182 | + Column { |
1183 | + anchors { top: parent.top; right: parent.right; bottom: parent.bottom; margins:units.gu(1) } |
1184 | + width: units.gu(18) |
1185 | + |
1186 | + Label { |
1187 | + text: "Max retries:" |
1188 | + color: "black" |
1189 | + } |
1190 | + TextField { |
1191 | + id: maxRetriesTextField |
1192 | + text: "-1" |
1193 | + } |
1194 | } |
1195 | |
1196 | SignalSpy { |
1197 | @@ -74,7 +89,7 @@ |
1198 | function init() { |
1199 | swipeAwayGreeter() |
1200 | shell.failedLoginsDelayAttempts = -1 |
1201 | - shell.maxFailedLogins = -1 |
1202 | + maxRetriesTextField.text = "-1" |
1203 | } |
1204 | |
1205 | function cleanup() { |
1206 | @@ -139,7 +154,7 @@ |
1207 | function test_emergencyCall() { |
1208 | var greeter = findChild(shell, "greeter") |
1209 | var lockscreen = findChild(shell, "lockscreen") |
1210 | - var emergencyButton = findChild(lockscreen, "emergencyCallIcon") |
1211 | + var emergencyButton = findChild(lockscreen, "emergencyCallLabel") |
1212 | var panel = findChild(shell, "panel") |
1213 | var indicators = findChild(shell, "indicators") |
1214 | var launcher = findChild(shell, "launcher") |
1215 | @@ -170,7 +185,7 @@ |
1216 | |
1217 | function test_emergencyCallCrash() { |
1218 | var lockscreen = findChild(shell, "lockscreen") |
1219 | - var emergencyButton = findChild(lockscreen, "emergencyCallIcon") |
1220 | + var emergencyButton = findChild(lockscreen, "emergencyCallLabel") |
1221 | mouseClick(emergencyButton, units.gu(1), units.gu(1)) |
1222 | |
1223 | tryCompare(lockscreen, "shown", false) |
1224 | @@ -180,7 +195,7 @@ |
1225 | |
1226 | function test_emergencyCallAppLaunch() { |
1227 | var lockscreen = findChild(shell, "lockscreen") |
1228 | - var emergencyButton = findChild(lockscreen, "emergencyCallIcon") |
1229 | + var emergencyButton = findChild(lockscreen, "emergencyCallLabel") |
1230 | mouseClick(emergencyButton, units.gu(1), units.gu(1)) |
1231 | |
1232 | tryCompare(lockscreen, "shown", false) |
1233 | @@ -201,21 +216,21 @@ |
1234 | function test_wrongEntries() { |
1235 | shell.failedLoginsDelayAttempts = 3 |
1236 | |
1237 | - var placeHolder = findChild(shell, "pinentryFieldPlaceHolder") |
1238 | - tryCompare(placeHolder, "text", "Enter your passcode") |
1239 | - |
1240 | - enterPin("1111") |
1241 | - tryCompare(placeHolder, "text", "Incorrect passcode\nPlease re-enter") |
1242 | - |
1243 | - enterPin("1111") |
1244 | - tryCompare(placeHolder, "text", "Incorrect passcode\nPlease re-enter") |
1245 | - |
1246 | - enterPin("1111") |
1247 | - tryCompare(placeHolder, "text", "Too many incorrect attempts\nPlease wait") |
1248 | + var placeHolder = findChild(shell, "wrongNoticeLabel") |
1249 | + tryCompare(placeHolder, "text", "") |
1250 | + |
1251 | + enterPin("1111") |
1252 | + tryCompare(placeHolder, "text", "Sorry, incorrect PIN") |
1253 | + |
1254 | + enterPin("1111") |
1255 | + tryCompare(placeHolder, "text", "Sorry, incorrect PIN") |
1256 | + |
1257 | + enterPin("1111") |
1258 | + tryCompare(placeHolder, "text", "Too many incorrect attempts") |
1259 | } |
1260 | |
1261 | function test_factoryReset() { |
1262 | - shell.maxFailedLogins = 3 |
1263 | + maxRetriesTextField.text = "3" |
1264 | resetSpy.clear() |
1265 | |
1266 | enterPin("1111") |
FAILED: Continuous integration, rev:1141 jenkins. qa.ubuntu. com/job/ unity8- ci/3866/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/3397 jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- utopic/ 868 jenkins. qa.ubuntu. com/job/ unity8- utopic- amd64-ci/ 960 jenkins. qa.ubuntu. com/job/ unity8- utopic- armhf-ci/ 960 jenkins. qa.ubuntu. com/job/ unity8- utopic- armhf-ci/ 960/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ unity8- utopic- i386-ci/ 960 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/3322 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4644 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4644/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 11323
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/3866/ rebuild
http://