Merge lp:~nataliabidart/ubuntu-sso-client/stable-3-0-update-2.99.4 into lp:ubuntu-sso-client/stable-3-0
- stable-3-0-update-2.99.4
- Merge into stable-3-0
Status: | Merged |
---|---|
Approved by: | Natalia Bidart |
Approved revision: | 825 |
Merged at revision: | 824 |
Proposed branch: | lp:~nataliabidart/ubuntu-sso-client/stable-3-0-update-2.99.4 |
Merge into: | lp:ubuntu-sso-client/stable-3-0 |
Diff against target: |
18990 lines (+9079/-5903) 104 files modified
.bzrignore (+4/-11) bin/ubuntu-sso-login-gtk (+2/-1) bin/ubuntu-sso-login-qt (+32/-0) bin/ubuntu-sso-proxy-creds-qt (+33/-0) data/gtk/ui.glade (+314/-180) data/qt/choose_sign_in.ui (+105/-61) data/qt/loadingoverlay.ui (+103/-0) data/qt/network_detection.ui (+142/-0) data/qt/proxy_credentials_dialog.ui (+316/-0) data/qt/setup_account.ui (+640/-253) run-tests (+23/-19) setup.py (+29/-14) ubuntu_sso/__init__.py (+10/-6) ubuntu_sso/account.py (+95/-76) ubuntu_sso/constants.py.in (+28/-0) ubuntu_sso/credentials.py (+91/-203) ubuntu_sso/gtk/__init__.py (+1/-3) ubuntu_sso/gtk/gui.py (+134/-86) ubuntu_sso/gtk/main.py (+5/-25) ubuntu_sso/gtk/tests/__init__.py (+1/-3) ubuntu_sso/gtk/tests/test_gui.py (+110/-110) ubuntu_sso/gtk/tests/test_main.py (+39/-0) ubuntu_sso/keyring/__init__.py (+17/-9) ubuntu_sso/keyring/tests/test_common.py (+4/-5) ubuntu_sso/keyring/tests/test_linux.py (+1/-1) ubuntu_sso/logger.py (+22/-6) ubuntu_sso/main/__init__.py (+80/-67) ubuntu_sso/main/glib.py (+45/-0) ubuntu_sso/main/linux.py (+43/-38) ubuntu_sso/main/qt.py (+49/-0) ubuntu_sso/main/tests/__init__.py (+8/-3) ubuntu_sso/main/tests/test_clients.py (+8/-24) ubuntu_sso/main/tests/test_common.py (+274/-176) ubuntu_sso/main/windows.py (+21/-18) ubuntu_sso/qt/__init__.py (+59/-1) ubuntu_sso/qt/common.py (+7/-9) ubuntu_sso/qt/controllers.py (+0/-980) ubuntu_sso/qt/current_user_sign_in_page.py (+170/-0) ubuntu_sso/qt/email_verification_page.py (+140/-0) ubuntu_sso/qt/enhanced_check_box.py (+50/-0) ubuntu_sso/qt/error_page.py (+29/-0) ubuntu_sso/qt/forgotten_password_page.py (+182/-0) ubuntu_sso/qt/gui.py (+70/-397) ubuntu_sso/qt/loadingoverlay.py (+123/-0) ubuntu_sso/qt/main.py (+31/-0) ubuntu_sso/qt/network_detection_page.py (+79/-0) ubuntu_sso/qt/proxy_dialog.py (+155/-0) ubuntu_sso/qt/reset_password_page.py (+200/-0) ubuntu_sso/qt/setup_account_page.py (+524/-0) ubuntu_sso/qt/sign_in_page.py (+99/-0) ubuntu_sso/qt/success_page.py (+30/-0) ubuntu_sso/qt/tests/__init__.py (+294/-5) ubuntu_sso/qt/tests/login_u_p.py (+16/-5) ubuntu_sso/qt/tests/show_gui.py (+14/-13) ubuntu_sso/qt/tests/test_controllers.py (+0/-2113) ubuntu_sso/qt/tests/test_current_user_sign_in_page.py (+244/-0) ubuntu_sso/qt/tests/test_email_verification.py (+211/-0) ubuntu_sso/qt/tests/test_enchanced_line_edit.py (+3/-2) ubuntu_sso/qt/tests/test_enhanced_check_box.py (+49/-0) ubuntu_sso/qt/tests/test_forgotten_password.py (+239/-0) ubuntu_sso/qt/tests/test_loadingoverlay.py (+36/-0) ubuntu_sso/qt/tests/test_main.py (+42/-0) ubuntu_sso/qt/tests/test_network_detection.py (+95/-0) ubuntu_sso/qt/tests/test_proxy_dialog.py (+338/-0) ubuntu_sso/qt/tests/test_qt_views.py (+15/-101) ubuntu_sso/qt/tests/test_reset_password.py (+12/-6) ubuntu_sso/qt/tests/test_setup_account.py (+385/-0) ubuntu_sso/qt/tests/test_sign_in_page.py (+69/-0) ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py (+94/-0) ubuntu_sso/qt/ubuntu_sso_wizard.py (+367/-0) ubuntu_sso/qt/ui/__init__.py (+17/-0) ubuntu_sso/tests/__init__.py (+4/-4) ubuntu_sso/tests/bin/show_gui (+0/-58) ubuntu_sso/tests/bin/show_nm_state (+0/-41) ubuntu_sso/tests/test_account.py (+162/-134) ubuntu_sso/tests/test_credentials.py (+181/-401) ubuntu_sso/utils/__init__.py (+100/-4) ubuntu_sso/utils/ipc.py (+12/-6) ubuntu_sso/utils/runner/__init__.py (+99/-0) ubuntu_sso/utils/runner/glib.py (+76/-0) ubuntu_sso/utils/runner/qt.py (+71/-0) ubuntu_sso/utils/runner/tests/__init__.py (+17/-0) ubuntu_sso/utils/runner/tests/test_qt.py (+136/-0) ubuntu_sso/utils/runner/tests/test_runner.py (+81/-0) ubuntu_sso/utils/runner/tx.py (+93/-0) ubuntu_sso/utils/tcpactivation.py (+1/-3) ubuntu_sso/utils/tests/test_common.py (+209/-6) ubuntu_sso/utils/tests/test_ipc.py (+4/-3) ubuntu_sso/utils/tests/test_parse_args.py (+9/-18) ubuntu_sso/utils/tests/test_txsecrets.py (+3/-0) ubuntu_sso/utils/ui.py (+63/-38) ubuntu_sso/utils/webclient/__init__.py (+2/-4) ubuntu_sso/utils/webclient/common.py (+34/-7) ubuntu_sso/utils/webclient/gsettings.py (+19/-4) ubuntu_sso/utils/webclient/libsoup.py (+2/-1) ubuntu_sso/utils/webclient/qtnetwork.py (+5/-0) ubuntu_sso/utils/webclient/restful.py (+6/-1) ubuntu_sso/utils/webclient/tests/__init__.py (+60/-0) ubuntu_sso/utils/webclient/tests/test_gsettings.py (+108/-0) ubuntu_sso/utils/webclient/tests/test_restful.py (+16/-2) ubuntu_sso/utils/webclient/tests/test_timestamp.py (+16/-32) ubuntu_sso/utils/webclient/tests/test_webclient.py (+145/-94) ubuntu_sso/utils/webclient/timestamp.py (+16/-10) ubuntu_sso/utils/webclient/txweb.py (+12/-2) |
To merge this branch: | bzr merge lp:~nataliabidart/ubuntu-sso-client/stable-3-0-update-2.99.4 |
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Review via email:
|
Commit message
- Updating from trunk up to revno 874:
[ Alejandro J. Cura <email address hidden> ]
- Use parameters set in the url for the OAuth signature (LP: #927664).
- libsoup bindings need flattening to work around nul bytes in content
(LP: #921822).
- Replace urllib2.Request with common web-client (LP: #884972).
- Replace urllib2.urlopen with common web-client (LP: #884975).
- Fix tests failing in sso with test_webclient (LP: #920591).
[ Diego Sarmentero <email address hidden> ]
- Fixed: Qt UI: after clicking on "I've forgotten my password",
and entering an email, nothing happens (LP: #931577).
- Fixed: Qt UI must return ubuntu_
ubuntu_
- Fixed: Qt UI: congratulations page is empty (LP: #930720).
- Fixed: Qt UI: "I've forgotten my password" button can not be
clicked (LP: #930722)
- Fixed: Qt UI must return ubuntu_
ubuntu_
- Fixed: Qt UI: when calling login or validate_email,
should pass the ping_url (LP: #930724).
- Added signals for the different pages, letting the wizard decide
what to do in each case.
- Refactor the pages and controller in sso (LP: #929686).
- Migrate SSO Pages from the Wizard to SSO (LP: #925531).
[ Manuel de la Pena <email address hidden> ]
- Adds the code that will load the creds from the keyring when we retry.
- Adds the script that allows to launch the creds dialog.
Adds tests for main.
- Allows the creds dialog to store the credentials in the keyring
(LP: #929451).
- Adds the credentials dialog with nearly no functionality to the project
(LP: #916029).
- Adds support for username:
of the webclient.
[ Natalia B. Bidart <email address hidden> ]
- Proper name in setup.py for the proxy credentials executable
(LP: #932328).
- No more 'Congratulations, app_name has installed' message since
we're not installing (LP: #931574).
- Refactored logic on setup_account_
privacy links properly (LP: #931589).
- Unified UI parse_args and have them accepting a policy_url param
(LP: #931464).
- Make the UI runner use the absolute path to the UI executables
(LP: #930651).
- Allow callers pass a 'policy_url' parameter to use in the UIs
(LP: #930142).
- Execute the UI as a separated process from the sso main thread
(LP: #919330).
- Hold on to the Qprocess instance to avoid garbage collection
(LP: #930140).
- Move the ping method from the credentials module to the
UserManagement interface (LP: #929670).
- The Gtk UI must handle errors from dbus when calling the backend
(LP: #929820).
- Provide a helper to spawn programs from the main loop that is being
used by the SSO Service (LP: #920949).
- Install ui files consitently between Gtk and Qt (part of LP: #927994).
- Remove unused "thread_execute" function (LP: #928581).
- Delay twisted.
ReactorAlre
- Added a dedicated logger for the gui module.
- Migrated the GTK UI to use GI bindings (LP: #801111).
- Enabled libsoup backend for webclient so the GTK UI will work.
- Enabled the running of all the tests using the single command
./run-tests.
- Added an initial version of GLib and Qt mainloop integration
(needed to run all the tests).
- Provide a QT UI executable (LP: #925073).
- Add a method to obtain an OAuth signed uri.
[ Rodney Dawes <email address hidden> ]
- Connect the activate-link button by hand to avoid Gtk-WARNING messages.
Description of the change
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2011-04-11 09:38:16 +0000 |
3 | +++ .bzrignore 2012-02-14 22:04:20 +0000 |
4 | @@ -1,16 +1,9 @@ |
5 | _trial_temp |
6 | data/*.service |
7 | +MANIFEST |
8 | build/ |
9 | dist/ |
10 | -MANIFEST |
11 | po/ubuntu-sso-client.pot |
12 | -ubuntu_sso/qt/captcha_ui.py |
13 | -ubuntu_sso/qt/choose_sign_in_ui.py |
14 | -ubuntu_sso/qt/current_user_sign_in_ui.py |
15 | -ubuntu_sso/qt/email_verification_ui.py |
16 | -ubuntu_sso/qt/setup_account_ui.py |
17 | -ubuntu_sso/qt/terms_and_conditions_ui.py |
18 | -ubuntu_sso/qt/success_message_ui.py |
19 | -ubuntu_sso/qt/error_message_ui.py |
20 | -ubuntu_sso/qt/forgotten_password_ui.py |
21 | -ubuntu_sso/qt/reset_password_ui.py |
22 | +ubuntu_sso/constants.py |
23 | +ubuntu_sso/qt/ui/*_ui.py |
24 | +ubuntu_sso/qt/ui/*_rc.py |
25 | |
26 | === modified file 'bin/ubuntu-sso-login-gtk' |
27 | --- bin/ubuntu-sso-login-gtk 2012-01-16 21:10:12 +0000 |
28 | +++ bin/ubuntu-sso-login-gtk 2012-02-14 22:04:20 +0000 |
29 | @@ -20,7 +20,8 @@ |
30 | # Invalid name "ubuntu-sso-login-gtk", pylint: disable=C0103 |
31 | # Access to a protected member, pylint: disable=W0212 |
32 | |
33 | -from ubuntu_sso.gtk.main import parse_args, main |
34 | +from ubuntu_sso.gtk.main import main |
35 | +from ubuntu_sso.utils.ui import parse_args |
36 | |
37 | from dbus.mainloop.glib import DBusGMainLoop |
38 | DBusGMainLoop(set_as_default=True) |
39 | |
40 | === added file 'bin/ubuntu-sso-login-qt' |
41 | --- bin/ubuntu-sso-login-qt 1970-01-01 00:00:00 +0000 |
42 | +++ bin/ubuntu-sso-login-qt 2012-02-14 22:04:20 +0000 |
43 | @@ -0,0 +1,32 @@ |
44 | +#!/usr/bin/env python |
45 | +# -*- coding: utf-8 -*- |
46 | +# |
47 | +# Copyright 2012 Canonical Ltd. |
48 | +# |
49 | +# This program is free software: you can redistribute it and/or modify it |
50 | +# under the terms of the GNU General Public License version 3, as published |
51 | +# by the Free Software Foundation. |
52 | +# |
53 | +# This program is distributed in the hope that it will be useful, but |
54 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
55 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
56 | +# PURPOSE. See the GNU General Public License for more details. |
57 | +# |
58 | +# You should have received a copy of the GNU General Public License along |
59 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
60 | + |
61 | +"""Start the sso GTK UI.""" |
62 | + |
63 | +# Invalid name "ubuntu-sso-login-qt", pylint: disable=C0103 |
64 | +# Access to a protected member, pylint: disable=W0212 |
65 | + |
66 | +from ubuntu_sso.qt.main import main |
67 | +from ubuntu_sso.utils.ui import parse_args |
68 | + |
69 | +from dbus.mainloop.qt import DBusQtMainLoop |
70 | +DBusQtMainLoop(set_as_default=True) |
71 | + |
72 | + |
73 | +if __name__ == "__main__": |
74 | + args = parse_args() |
75 | + main(**dict(args._get_kwargs())) |
76 | |
77 | === added file 'bin/ubuntu-sso-proxy-creds-qt' |
78 | --- bin/ubuntu-sso-proxy-creds-qt 1970-01-01 00:00:00 +0000 |
79 | +++ bin/ubuntu-sso-proxy-creds-qt 2012-02-14 22:04:20 +0000 |
80 | @@ -0,0 +1,33 @@ |
81 | +#!/usr/bin/env python |
82 | +# -*- coding: utf-8 -*- |
83 | +# |
84 | +# Copyright 2012 Canonical Ltd. |
85 | +# |
86 | +# This program is free software: you can redistribute it and/or modify it |
87 | +# under the terms of the GNU General Public License version 3, as published |
88 | +# by the Free Software Foundation. |
89 | +# |
90 | +# This program is distributed in the hope that it will be useful, but |
91 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
92 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
93 | +# PURPOSE. See the GNU General Public License for more details. |
94 | +# |
95 | +# You should have received a copy of the GNU General Public License along |
96 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
97 | + |
98 | +"""Start the QT proxy creds dialog.""" |
99 | + |
100 | +# Invalid name, pylint: disable=C0103 |
101 | + |
102 | +import os |
103 | +# HACK: At the moment we need to do that until sso is refactored |
104 | +os.environ['USE_QT_MAINLOOP'] = '1' |
105 | + |
106 | +# set the dbus main loop to be used |
107 | +from dbus.mainloop.qt import DBusQtMainLoop |
108 | +DBusQtMainLoop(set_as_default=True) |
109 | + |
110 | +from ubuntu_sso.qt.proxy_dialog import main |
111 | + |
112 | +if __name__ == "__main__": |
113 | + main() |
114 | |
115 | === modified file 'data/gtk/ui.glade' |
116 | --- data/gtk/ui.glade 2011-09-19 13:09:46 +0000 |
117 | +++ data/gtk/ui.glade 2012-02-14 22:04:20 +0000 |
118 | @@ -1,72 +1,14 @@ |
119 | <?xml version="1.0" encoding="UTF-8"?> |
120 | <interface> |
121 | <requires lib="gtk+" version="2.16"/> |
122 | - <!-- interface-naming-policy project-wide --> |
123 | - <object class="GtkWindow" id="window"> |
124 | - <property name="border_width">10</property> |
125 | - <property name="window_position">center</property> |
126 | - <signal name="delete_event" handler="on_close_clicked"/> |
127 | - <child> |
128 | - <object class="GtkVBox" id="window_vbox"> |
129 | - <property name="visible">True</property> |
130 | - <property name="spacing">5</property> |
131 | - <child> |
132 | - <object class="GtkLabel" id="header_label"> |
133 | - <property name="visible">True</property> |
134 | - <property name="xalign">0</property> |
135 | - <property name="label" translatable="yes">Header Label </property> |
136 | - <property name="wrap">True</property> |
137 | - </object> |
138 | - <packing> |
139 | - <property name="expand">False</property> |
140 | - <property name="padding">5</property> |
141 | - <property name="position">0</property> |
142 | - </packing> |
143 | - </child> |
144 | - <child> |
145 | - <object class="GtkLabel" id="help_label"> |
146 | - <property name="visible">True</property> |
147 | - <property name="xalign">0</property> |
148 | - <property name="label" translatable="yes">help label</property> |
149 | - <property name="wrap">True</property> |
150 | - </object> |
151 | - <packing> |
152 | - <property name="expand">False</property> |
153 | - <property name="position">1</property> |
154 | - </packing> |
155 | - </child> |
156 | - <child> |
157 | - <object class="GtkLabel" id="warning_label"> |
158 | - <property name="visible">True</property> |
159 | - <property name="xalign">0</property> |
160 | - <property name="label" translatable="yes">warning label</property> |
161 | - <property name="wrap">True</property> |
162 | - </object> |
163 | - <packing> |
164 | - <property name="expand">False</property> |
165 | - <property name="position">2</property> |
166 | - </packing> |
167 | - </child> |
168 | - <child> |
169 | - <object class="GtkNotebook" id="content"> |
170 | - <property name="visible">True</property> |
171 | - <property name="can_focus">True</property> |
172 | - <property name="show_tabs">False</property> |
173 | - <property name="show_border">False</property> |
174 | - </object> |
175 | - <packing> |
176 | - <property name="position">3</property> |
177 | - </packing> |
178 | - </child> |
179 | - </object> |
180 | - </child> |
181 | - </object> |
182 | <object class="GtkVBox" id="enter_details_vbox"> |
183 | <property name="visible">True</property> |
184 | + <property name="can_focus">False</property> |
185 | <property name="spacing">5</property> |
186 | <child> |
187 | <object class="GtkHBox" id="emails_hbox"> |
188 | <property name="visible">True</property> |
189 | + <property name="can_focus">False</property> |
190 | <property name="spacing">5</property> |
191 | <property name="homogeneous">True</property> |
192 | <child> |
193 | @@ -78,12 +20,14 @@ |
194 | </object> |
195 | <packing> |
196 | <property name="expand">False</property> |
197 | + <property name="fill">True</property> |
198 | <property name="position">0</property> |
199 | </packing> |
200 | </child> |
201 | <child> |
202 | <object class="GtkHBox" id="passwords_hbox"> |
203 | <property name="visible">True</property> |
204 | + <property name="can_focus">False</property> |
205 | <property name="spacing">5</property> |
206 | <property name="homogeneous">True</property> |
207 | <child> |
208 | @@ -95,38 +39,45 @@ |
209 | </object> |
210 | <packing> |
211 | <property name="expand">False</property> |
212 | + <property name="fill">True</property> |
213 | <property name="position">1</property> |
214 | </packing> |
215 | </child> |
216 | <child> |
217 | <object class="GtkLabel" id="password_help_label"> |
218 | <property name="visible">True</property> |
219 | + <property name="can_focus">False</property> |
220 | <property name="label">password help</property> |
221 | <property name="wrap">True</property> |
222 | </object> |
223 | <packing> |
224 | <property name="expand">False</property> |
225 | + <property name="fill">True</property> |
226 | <property name="position">2</property> |
227 | </packing> |
228 | </child> |
229 | <child> |
230 | <object class="GtkAlignment" id="alignment5"> |
231 | <property name="visible">True</property> |
232 | + <property name="can_focus">False</property> |
233 | <property name="xscale">0</property> |
234 | <property name="yscale">0</property> |
235 | <child> |
236 | <object class="GtkHBox" id="hbox1"> |
237 | <property name="visible">True</property> |
238 | + <property name="can_focus">False</property> |
239 | <child> |
240 | <object class="GtkVBox" id="captcha_vbox"> |
241 | <property name="width_request">300</property> |
242 | <property name="height_request">60</property> |
243 | <property name="visible">True</property> |
244 | + <property name="can_focus">False</property> |
245 | <child> |
246 | <object class="GtkEventBox" id="captcha_loading"> |
247 | <property name="width_request">300</property> |
248 | <property name="height_request">60</property> |
249 | <property name="visible">True</property> |
250 | + <property name="can_focus">False</property> |
251 | <child> |
252 | <placeholder/> |
253 | </child> |
254 | @@ -141,9 +92,12 @@ |
255 | <object class="GtkImage" id="captcha_image"> |
256 | <property name="width_request">300</property> |
257 | <property name="visible">True</property> |
258 | + <property name="can_focus">False</property> |
259 | <property name="stock">gtk-missing-image</property> |
260 | </object> |
261 | <packing> |
262 | + <property name="expand">True</property> |
263 | + <property name="fill">True</property> |
264 | <property name="position">1</property> |
265 | </packing> |
266 | </child> |
267 | @@ -157,23 +111,28 @@ |
268 | <child> |
269 | <object class="GtkVBox" id="vbox1"> |
270 | <property name="visible">True</property> |
271 | + <property name="can_focus">False</property> |
272 | <child> |
273 | <object class="GtkButton" id="captcha_reload_button"> |
274 | + <property name="use_action_appearance">False</property> |
275 | <property name="visible">True</property> |
276 | <property name="can_focus">True</property> |
277 | <property name="receives_default">True</property> |
278 | + <property name="use_action_appearance">False</property> |
279 | <property name="relief">none</property> |
280 | <property name="focus_on_click">False</property> |
281 | - <signal name="clicked" handler="on_captcha_reload_button_clicked"/> |
282 | + <signal name="clicked" handler="on_captcha_reload_button_clicked" swapped="no"/> |
283 | <child> |
284 | <object class="GtkImage" id="image1"> |
285 | <property name="visible">True</property> |
286 | + <property name="can_focus">False</property> |
287 | <property name="icon_name">reload</property> |
288 | </object> |
289 | </child> |
290 | </object> |
291 | <packing> |
292 | <property name="expand">False</property> |
293 | + <property name="fill">True</property> |
294 | <property name="position">0</property> |
295 | </packing> |
296 | </child> |
297 | @@ -186,6 +145,7 @@ |
298 | </object> |
299 | <packing> |
300 | <property name="expand">False</property> |
301 | + <property name="fill">True</property> |
302 | <property name="position">1</property> |
303 | </packing> |
304 | </child> |
305 | @@ -194,64 +154,76 @@ |
306 | </object> |
307 | <packing> |
308 | <property name="expand">False</property> |
309 | + <property name="fill">True</property> |
310 | <property name="position">3</property> |
311 | </packing> |
312 | </child> |
313 | <child> |
314 | <object class="GtkVBox" id="captcha_solution_vbox"> |
315 | <property name="visible">True</property> |
316 | + <property name="can_focus">False</property> |
317 | <child> |
318 | <placeholder/> |
319 | </child> |
320 | </object> |
321 | <packing> |
322 | <property name="expand">False</property> |
323 | + <property name="fill">True</property> |
324 | <property name="position">4</property> |
325 | </packing> |
326 | </child> |
327 | <child> |
328 | <object class="GtkCheckButton" id="yes_to_updates_checkbutton"> |
329 | <property name="label" translatable="yes">yes to updates</property> |
330 | + <property name="use_action_appearance">False</property> |
331 | <property name="visible">True</property> |
332 | <property name="can_focus">True</property> |
333 | <property name="receives_default">False</property> |
334 | + <property name="use_action_appearance">False</property> |
335 | <property name="active">True</property> |
336 | <property name="draw_indicator">True</property> |
337 | </object> |
338 | <packing> |
339 | <property name="expand">False</property> |
340 | + <property name="fill">True</property> |
341 | <property name="position">5</property> |
342 | </packing> |
343 | </child> |
344 | <child> |
345 | <object class="GtkVBox" id="tc_vbox"> |
346 | <property name="visible">True</property> |
347 | + <property name="can_focus">False</property> |
348 | <property name="spacing">5</property> |
349 | <child> |
350 | <object class="GtkCheckButton" id="yes_to_tc_checkbutton"> |
351 | <property name="label" translatable="yes">yes to tc</property> |
352 | + <property name="use_action_appearance">False</property> |
353 | <property name="visible">True</property> |
354 | <property name="can_focus">True</property> |
355 | <property name="receives_default">False</property> |
356 | - <property name="active">False</property> |
357 | + <property name="use_action_appearance">False</property> |
358 | <property name="draw_indicator">True</property> |
359 | </object> |
360 | <packing> |
361 | <property name="expand">False</property> |
362 | + <property name="fill">True</property> |
363 | <property name="position">0</property> |
364 | </packing> |
365 | </child> |
366 | <child> |
367 | <object class="GtkHButtonBox" id="hbuttonbox3"> |
368 | <property name="visible">True</property> |
369 | + <property name="can_focus">False</property> |
370 | <property name="layout_style">start</property> |
371 | <child> |
372 | <object class="GtkButton" id="tc_button"> |
373 | <property name="label">show tc</property> |
374 | + <property name="use_action_appearance">False</property> |
375 | <property name="visible">True</property> |
376 | <property name="can_focus">True</property> |
377 | <property name="receives_default">True</property> |
378 | - <signal name="clicked" handler="on_tc_button_clicked"/> |
379 | + <property name="use_action_appearance">False</property> |
380 | + <signal name="clicked" handler="on_tc_button_clicked" swapped="no"/> |
381 | </object> |
382 | <packing> |
383 | <property name="expand">False</property> |
384 | @@ -262,42 +234,53 @@ |
385 | </object> |
386 | <packing> |
387 | <property name="expand">False</property> |
388 | + <property name="fill">True</property> |
389 | <property name="position">1</property> |
390 | </packing> |
391 | </child> |
392 | <child> |
393 | <object class="GtkLabel" id="tc_warning_label"> |
394 | <property name="visible">True</property> |
395 | + <property name="can_focus">False</property> |
396 | <property name="xalign">0</property> |
397 | <property name="label">tc warning</property> |
398 | <property name="wrap">True</property> |
399 | </object> |
400 | <packing> |
401 | + <property name="expand">True</property> |
402 | + <property name="fill">True</property> |
403 | <property name="position">2</property> |
404 | </packing> |
405 | </child> |
406 | </object> |
407 | <packing> |
408 | <property name="expand">False</property> |
409 | + <property name="fill">True</property> |
410 | <property name="position">6</property> |
411 | </packing> |
412 | </child> |
413 | <child> |
414 | <object class="GtkHBox" id="hbox2"> |
415 | <property name="visible">True</property> |
416 | + <property name="can_focus">False</property> |
417 | <property name="spacing">5</property> |
418 | <child> |
419 | <object class="GtkHButtonBox" id="hbuttonbox9"> |
420 | <property name="visible">True</property> |
421 | + <property name="can_focus">False</property> |
422 | <property name="layout_style">start</property> |
423 | <child> |
424 | <object class="GtkLinkButton" id="login_button"> |
425 | <property name="label">login button</property> |
426 | + <property name="use_action_appearance">False</property> |
427 | <property name="visible">True</property> |
428 | <property name="can_focus">True</property> |
429 | <property name="receives_default">True</property> |
430 | + <property name="use_action_appearance">False</property> |
431 | <property name="relief">none</property> |
432 | - <signal name="clicked" handler="on_sign_in_button_clicked"/> |
433 | + <property name="uri">foo</property> |
434 | + <signal name="activate-link" handler="on_activate_link" swapped="no"/> |
435 | + <signal name="clicked" handler="on_sign_in_button_clicked" swapped="no"/> |
436 | </object> |
437 | <packing> |
438 | <property name="expand">False</property> |
439 | @@ -308,20 +291,24 @@ |
440 | </object> |
441 | <packing> |
442 | <property name="expand">False</property> |
443 | + <property name="fill">True</property> |
444 | <property name="position">0</property> |
445 | </packing> |
446 | </child> |
447 | <child> |
448 | <object class="GtkHButtonBox" id="hbuttonbox1"> |
449 | <property name="visible">True</property> |
450 | + <property name="can_focus">False</property> |
451 | <property name="spacing">5</property> |
452 | <property name="layout_style">end</property> |
453 | <child> |
454 | <object class="GtkButton" id="join_cancel_button"> |
455 | <property name="label">gtk-cancel</property> |
456 | + <property name="use_action_appearance">False</property> |
457 | <property name="visible">True</property> |
458 | <property name="can_focus">True</property> |
459 | <property name="receives_default">True</property> |
460 | + <property name="use_action_appearance">False</property> |
461 | <property name="use_stock">True</property> |
462 | </object> |
463 | <packing> |
464 | @@ -333,11 +320,13 @@ |
465 | <child> |
466 | <object class="GtkButton" id="join_ok_button"> |
467 | <property name="label">gtk-go-forward</property> |
468 | + <property name="use_action_appearance">False</property> |
469 | <property name="visible">True</property> |
470 | <property name="can_focus">True</property> |
471 | <property name="receives_default">True</property> |
472 | + <property name="use_action_appearance">False</property> |
473 | <property name="use_stock">True</property> |
474 | - <signal name="clicked" handler="on_join_ok_button_clicked"/> |
475 | + <signal name="clicked" handler="on_join_ok_button_clicked" swapped="no"/> |
476 | </object> |
477 | <packing> |
478 | <property name="expand">False</property> |
479 | @@ -348,6 +337,7 @@ |
480 | </object> |
481 | <packing> |
482 | <property name="expand">False</property> |
483 | + <property name="fill">True</property> |
484 | <property name="pack_type">end</property> |
485 | <property name="position">1</property> |
486 | </packing> |
487 | @@ -355,122 +345,72 @@ |
488 | </object> |
489 | <packing> |
490 | <property name="expand">False</property> |
491 | + <property name="fill">True</property> |
492 | <property name="pack_type">end</property> |
493 | <property name="position">7</property> |
494 | </packing> |
495 | </child> |
496 | </object> |
497 | - <object class="GtkVBox" id="processing_vbox"> |
498 | - <property name="visible">True</property> |
499 | - <property name="spacing">10</property> |
500 | - <child> |
501 | - <placeholder/> |
502 | - </child> |
503 | - </object> |
504 | - <object class="GtkVBox" id="verify_email_vbox"> |
505 | - <property name="visible">True</property> |
506 | - <property name="spacing">10</property> |
507 | - <child> |
508 | - <object class="GtkAlignment" id="alignment4"> |
509 | - <property name="visible">True</property> |
510 | - <property name="xscale">0</property> |
511 | - <property name="yscale">0</property> |
512 | - <child> |
513 | - <object class="GtkVBox" id="verify_email_details_vbox"> |
514 | - <property name="visible">True</property> |
515 | - <child> |
516 | - <placeholder/> |
517 | - </child> |
518 | - </object> |
519 | - </child> |
520 | - </object> |
521 | - <packing> |
522 | - <property name="position">0</property> |
523 | - </packing> |
524 | - </child> |
525 | - <child> |
526 | - <object class="GtkHButtonBox" id="hbuttonbox2"> |
527 | - <property name="visible">True</property> |
528 | - <property name="spacing">5</property> |
529 | - <property name="layout_style">end</property> |
530 | - <child> |
531 | - <object class="GtkButton" id="verify_token_button"> |
532 | - <property name="label">gtk-ok</property> |
533 | - <property name="visible">True</property> |
534 | - <property name="can_focus">True</property> |
535 | - <property name="receives_default">True</property> |
536 | - <property name="use_stock">True</property> |
537 | - <signal name="clicked" handler="on_verify_token_button_clicked"/> |
538 | - </object> |
539 | - <packing> |
540 | - <property name="expand">False</property> |
541 | - <property name="fill">False</property> |
542 | - <property name="position">0</property> |
543 | - </packing> |
544 | - </child> |
545 | - </object> |
546 | - <packing> |
547 | - <property name="expand">False</property> |
548 | - <property name="position">1</property> |
549 | - </packing> |
550 | - </child> |
551 | - </object> |
552 | - <object class="GtkVBox" id="tc_browser_vbox"> |
553 | - <property name="visible">True</property> |
554 | - <signal name="hide" handler="on_tc_browser_vbox_hide"/> |
555 | - <child> |
556 | - <object class="GtkScrolledWindow" id="tc_browser_window"> |
557 | - <property name="visible">True</property> |
558 | - <property name="can_focus">True</property> |
559 | - <property name="border_width">10</property> |
560 | - <property name="hscrollbar_policy">never</property> |
561 | - <property name="vscrollbar_policy">automatic</property> |
562 | - <property name="shadow_type">in</property> |
563 | - <child> |
564 | - <placeholder/> |
565 | - </child> |
566 | - </object> |
567 | - <packing> |
568 | - <property name="position">0</property> |
569 | - </packing> |
570 | - </child> |
571 | - <child> |
572 | - <object class="GtkHButtonBox" id="hbuttonbox4"> |
573 | - <property name="visible">True</property> |
574 | - <property name="layout_style">end</property> |
575 | - <child> |
576 | - <object class="GtkButton" id="tc_back_button"> |
577 | - <property name="label">gtk-go-back</property> |
578 | - <property name="visible">True</property> |
579 | - <property name="can_focus">True</property> |
580 | - <property name="receives_default">True</property> |
581 | - <property name="use_stock">True</property> |
582 | - <signal name="clicked" handler="on_tc_back_button_clicked"/> |
583 | - </object> |
584 | - <packing> |
585 | - <property name="expand">False</property> |
586 | - <property name="fill">False</property> |
587 | - <property name="position">0</property> |
588 | - </packing> |
589 | - </child> |
590 | - </object> |
591 | - <packing> |
592 | - <property name="expand">False</property> |
593 | + <object class="GtkVBox" id="finish_vbox"> |
594 | + <property name="visible">True</property> |
595 | + <property name="can_focus">False</property> |
596 | + <property name="spacing">10</property> |
597 | + <child> |
598 | + <object class="GtkLabel" id="finish_label"> |
599 | + <property name="visible">True</property> |
600 | + <property name="can_focus">False</property> |
601 | + <property name="wrap">True</property> |
602 | + </object> |
603 | + <packing> |
604 | + <property name="expand">True</property> |
605 | + <property name="fill">True</property> |
606 | + <property name="position">0</property> |
607 | + </packing> |
608 | + </child> |
609 | + <child> |
610 | + <object class="GtkHButtonBox" id="hbuttonbox8"> |
611 | + <property name="visible">True</property> |
612 | + <property name="can_focus">False</property> |
613 | + <property name="layout_style">end</property> |
614 | + <child> |
615 | + <object class="GtkButton" id="finish_close_button"> |
616 | + <property name="label">gtk-close</property> |
617 | + <property name="use_action_appearance">False</property> |
618 | + <property name="visible">True</property> |
619 | + <property name="can_focus">True</property> |
620 | + <property name="receives_default">True</property> |
621 | + <property name="use_action_appearance">False</property> |
622 | + <property name="use_stock">True</property> |
623 | + <signal name="clicked" handler="on_close_clicked" swapped="no"/> |
624 | + </object> |
625 | + <packing> |
626 | + <property name="expand">False</property> |
627 | + <property name="fill">False</property> |
628 | + <property name="position">0</property> |
629 | + </packing> |
630 | + </child> |
631 | + </object> |
632 | + <packing> |
633 | + <property name="expand">False</property> |
634 | + <property name="fill">True</property> |
635 | <property name="position">1</property> |
636 | </packing> |
637 | </child> |
638 | </object> |
639 | <object class="GtkVBox" id="login_vbox"> |
640 | <property name="visible">True</property> |
641 | + <property name="can_focus">False</property> |
642 | <property name="spacing">10</property> |
643 | <child> |
644 | <object class="GtkAlignment" id="alignment3"> |
645 | <property name="visible">True</property> |
646 | + <property name="can_focus">False</property> |
647 | <property name="xscale">0</property> |
648 | <property name="yscale">0</property> |
649 | <child> |
650 | <object class="GtkVBox" id="login_details_vbox"> |
651 | <property name="visible">True</property> |
652 | + <property name="can_focus">False</property> |
653 | <property name="spacing">5</property> |
654 | <child> |
655 | <placeholder/> |
656 | @@ -482,26 +422,34 @@ |
657 | </child> |
658 | </object> |
659 | <packing> |
660 | + <property name="expand">True</property> |
661 | + <property name="fill">True</property> |
662 | <property name="position">0</property> |
663 | </packing> |
664 | </child> |
665 | <child> |
666 | <object class="GtkHBox" id="hbox3"> |
667 | <property name="visible">True</property> |
668 | + <property name="can_focus">False</property> |
669 | <property name="spacing">5</property> |
670 | <child> |
671 | <object class="GtkHButtonBox" id="hbuttonbox10"> |
672 | <property name="visible">True</property> |
673 | + <property name="can_focus">False</property> |
674 | <property name="layout_style">start</property> |
675 | <child> |
676 | <object class="GtkLinkButton" id="forgotten_password_button"> |
677 | - <property name="label" translatable="yes">button</property> |
678 | + <property name="label" translatable="yes">forgot password button</property> |
679 | + <property name="use_action_appearance">False</property> |
680 | <property name="visible">True</property> |
681 | <property name="can_focus">True</property> |
682 | <property name="receives_default">True</property> |
683 | <property name="has_tooltip">True</property> |
684 | + <property name="use_action_appearance">False</property> |
685 | <property name="relief">none</property> |
686 | - <signal name="clicked" handler="on_forgotten_password_button_clicked"/> |
687 | + <property name="uri">foo</property> |
688 | + <signal name="activate-link" handler="on_activate_link" swapped="no"/> |
689 | + <signal name="clicked" handler="on_forgotten_password_button_clicked" swapped="no"/> |
690 | </object> |
691 | <packing> |
692 | <property name="expand">False</property> |
693 | @@ -513,20 +461,24 @@ |
694 | </object> |
695 | <packing> |
696 | <property name="expand">False</property> |
697 | + <property name="fill">True</property> |
698 | <property name="position">0</property> |
699 | </packing> |
700 | </child> |
701 | <child> |
702 | <object class="GtkHButtonBox" id="hbuttonbox5"> |
703 | <property name="visible">True</property> |
704 | + <property name="can_focus">False</property> |
705 | <property name="spacing">5</property> |
706 | <property name="layout_style">end</property> |
707 | <child> |
708 | <object class="GtkButton" id="login_cancel_button"> |
709 | <property name="label">gtk-cancel</property> |
710 | + <property name="use_action_appearance">False</property> |
711 | <property name="visible">True</property> |
712 | <property name="can_focus">True</property> |
713 | <property name="receives_default">True</property> |
714 | + <property name="use_action_appearance">False</property> |
715 | <property name="use_stock">True</property> |
716 | </object> |
717 | <packing> |
718 | @@ -538,11 +490,13 @@ |
719 | <child> |
720 | <object class="GtkButton" id="login_back_button"> |
721 | <property name="label">gtk-go-back</property> |
722 | + <property name="use_action_appearance">False</property> |
723 | <property name="visible">True</property> |
724 | <property name="can_focus">True</property> |
725 | <property name="receives_default">True</property> |
726 | + <property name="use_action_appearance">False</property> |
727 | <property name="use_stock">True</property> |
728 | - <signal name="clicked" handler="on_login_back_button_clicked"/> |
729 | + <signal name="clicked" handler="on_login_back_button_clicked" swapped="no"/> |
730 | </object> |
731 | <packing> |
732 | <property name="expand">False</property> |
733 | @@ -553,11 +507,13 @@ |
734 | <child> |
735 | <object class="GtkButton" id="login_ok_button"> |
736 | <property name="label">gtk-connect</property> |
737 | + <property name="use_action_appearance">False</property> |
738 | <property name="visible">True</property> |
739 | <property name="can_focus">True</property> |
740 | <property name="receives_default">True</property> |
741 | + <property name="use_action_appearance">False</property> |
742 | <property name="use_stock">True</property> |
743 | - <signal name="clicked" handler="on_login_connect_button_clicked"/> |
744 | + <signal name="clicked" handler="on_login_connect_button_clicked" swapped="no"/> |
745 | </object> |
746 | <packing> |
747 | <property name="expand">False</property> |
748 | @@ -568,6 +524,7 @@ |
749 | </object> |
750 | <packing> |
751 | <property name="expand">False</property> |
752 | + <property name="fill">True</property> |
753 | <property name="pack_type">end</property> |
754 | <property name="position">1</property> |
755 | </packing> |
756 | @@ -575,21 +532,33 @@ |
757 | </object> |
758 | <packing> |
759 | <property name="expand">False</property> |
760 | + <property name="fill">True</property> |
761 | <property name="position">1</property> |
762 | </packing> |
763 | </child> |
764 | </object> |
765 | + <object class="GtkVBox" id="processing_vbox"> |
766 | + <property name="visible">True</property> |
767 | + <property name="can_focus">False</property> |
768 | + <property name="spacing">10</property> |
769 | + <child> |
770 | + <placeholder/> |
771 | + </child> |
772 | + </object> |
773 | <object class="GtkVBox" id="request_password_token_vbox"> |
774 | <property name="visible">True</property> |
775 | + <property name="can_focus">False</property> |
776 | <property name="spacing">10</property> |
777 | <child> |
778 | <object class="GtkAlignment" id="alignment2"> |
779 | <property name="visible">True</property> |
780 | + <property name="can_focus">False</property> |
781 | <property name="xscale">0</property> |
782 | <property name="yscale">0</property> |
783 | <child> |
784 | <object class="GtkVBox" id="request_password_token_details_vbox"> |
785 | <property name="visible">True</property> |
786 | + <property name="can_focus">False</property> |
787 | <property name="spacing">5</property> |
788 | <child> |
789 | <placeholder/> |
790 | @@ -598,20 +567,25 @@ |
791 | </child> |
792 | </object> |
793 | <packing> |
794 | + <property name="expand">True</property> |
795 | + <property name="fill">True</property> |
796 | <property name="position">0</property> |
797 | </packing> |
798 | </child> |
799 | <child> |
800 | <object class="GtkHButtonBox" id="hbuttonbox7"> |
801 | <property name="visible">True</property> |
802 | + <property name="can_focus">False</property> |
803 | <property name="spacing">5</property> |
804 | <property name="layout_style">end</property> |
805 | <child> |
806 | <object class="GtkButton" id="request_password_token_cancel_button"> |
807 | <property name="label">gtk-cancel</property> |
808 | + <property name="use_action_appearance">False</property> |
809 | <property name="visible">True</property> |
810 | <property name="can_focus">True</property> |
811 | <property name="receives_default">True</property> |
812 | + <property name="use_action_appearance">False</property> |
813 | <property name="use_stock">True</property> |
814 | </object> |
815 | <packing> |
816 | @@ -623,11 +597,13 @@ |
817 | <child> |
818 | <object class="GtkButton" id="request_password_token_back_button"> |
819 | <property name="label">gtk-go-back</property> |
820 | + <property name="use_action_appearance">False</property> |
821 | <property name="visible">True</property> |
822 | <property name="can_focus">True</property> |
823 | <property name="receives_default">True</property> |
824 | + <property name="use_action_appearance">False</property> |
825 | <property name="use_stock">True</property> |
826 | - <signal name="clicked" handler="on_request_password_token_back_button_clicked"/> |
827 | + <signal name="clicked" handler="on_request_password_token_back_button_clicked" swapped="no"/> |
828 | </object> |
829 | <packing> |
830 | <property name="expand">False</property> |
831 | @@ -638,11 +614,13 @@ |
832 | <child> |
833 | <object class="GtkButton" id="request_password_token_ok_button"> |
834 | <property name="label">gtk-ok</property> |
835 | + <property name="use_action_appearance">False</property> |
836 | <property name="visible">True</property> |
837 | <property name="can_focus">True</property> |
838 | <property name="receives_default">True</property> |
839 | + <property name="use_action_appearance">False</property> |
840 | <property name="use_stock">True</property> |
841 | - <signal name="clicked" handler="on_request_password_token_ok_button_clicked"/> |
842 | + <signal name="clicked" handler="on_request_password_token_ok_button_clicked" swapped="no"/> |
843 | </object> |
844 | <packing> |
845 | <property name="expand">False</property> |
846 | @@ -653,35 +631,42 @@ |
847 | </object> |
848 | <packing> |
849 | <property name="expand">False</property> |
850 | + <property name="fill">True</property> |
851 | <property name="position">1</property> |
852 | </packing> |
853 | </child> |
854 | </object> |
855 | <object class="GtkVBox" id="set_new_password_vbox"> |
856 | <property name="visible">True</property> |
857 | + <property name="can_focus">False</property> |
858 | <property name="spacing">10</property> |
859 | <child> |
860 | <object class="GtkVBox" id="vbox2"> |
861 | <property name="visible">True</property> |
862 | + <property name="can_focus">False</property> |
863 | <child> |
864 | <object class="GtkLabel" id="reset_password_help_label"> |
865 | <property name="visible">True</property> |
866 | + <property name="can_focus">False</property> |
867 | <property name="label">label</property> |
868 | <property name="wrap">True</property> |
869 | </object> |
870 | <packing> |
871 | <property name="expand">False</property> |
872 | + <property name="fill">True</property> |
873 | <property name="position">0</property> |
874 | </packing> |
875 | </child> |
876 | <child> |
877 | <object class="GtkAlignment" id="alignment1"> |
878 | <property name="visible">True</property> |
879 | + <property name="can_focus">False</property> |
880 | <property name="xscale">0</property> |
881 | <property name="yscale">0</property> |
882 | <child> |
883 | <object class="GtkVBox" id="set_new_password_details_vbox"> |
884 | <property name="visible">True</property> |
885 | + <property name="can_focus">False</property> |
886 | <property name="spacing">5</property> |
887 | <child> |
888 | <placeholder/> |
889 | @@ -696,25 +681,32 @@ |
890 | </child> |
891 | </object> |
892 | <packing> |
893 | + <property name="expand">True</property> |
894 | + <property name="fill">True</property> |
895 | <property name="position">1</property> |
896 | </packing> |
897 | </child> |
898 | </object> |
899 | <packing> |
900 | + <property name="expand">True</property> |
901 | + <property name="fill">True</property> |
902 | <property name="position">0</property> |
903 | </packing> |
904 | </child> |
905 | <child> |
906 | <object class="GtkHButtonBox" id="hbuttonbox6"> |
907 | <property name="visible">True</property> |
908 | + <property name="can_focus">False</property> |
909 | <property name="spacing">5</property> |
910 | <property name="layout_style">end</property> |
911 | <child> |
912 | <object class="GtkButton" id="set_new_password_cancel_button"> |
913 | <property name="label">gtk-cancel</property> |
914 | + <property name="use_action_appearance">False</property> |
915 | <property name="visible">True</property> |
916 | <property name="can_focus">True</property> |
917 | <property name="receives_default">True</property> |
918 | + <property name="use_action_appearance">False</property> |
919 | <property name="use_stock">True</property> |
920 | </object> |
921 | <packing> |
922 | @@ -726,11 +718,13 @@ |
923 | <child> |
924 | <object class="GtkButton" id="set_new_password_ok_button"> |
925 | <property name="label">gtk-ok</property> |
926 | + <property name="use_action_appearance">False</property> |
927 | <property name="visible">True</property> |
928 | <property name="can_focus">True</property> |
929 | <property name="receives_default">True</property> |
930 | + <property name="use_action_appearance">False</property> |
931 | <property name="use_stock">True</property> |
932 | - <signal name="clicked" handler="on_set_new_password_ok_button_clicked"/> |
933 | + <signal name="clicked" handler="on_set_new_password_ok_button_clicked" swapped="no"/> |
934 | </object> |
935 | <packing> |
936 | <property name="expand">False</property> |
937 | @@ -741,34 +735,104 @@ |
938 | </object> |
939 | <packing> |
940 | <property name="expand">False</property> |
941 | - <property name="position">1</property> |
942 | - </packing> |
943 | - </child> |
944 | - </object> |
945 | - <object class="GtkVBox" id="finish_vbox"> |
946 | - <property name="visible">True</property> |
947 | + <property name="fill">True</property> |
948 | + <property name="position">1</property> |
949 | + </packing> |
950 | + </child> |
951 | + </object> |
952 | + <object class="GtkVBox" id="tc_browser_vbox"> |
953 | + <property name="visible">True</property> |
954 | + <property name="can_focus">False</property> |
955 | + <signal name="hide" handler="on_tc_browser_vbox_hide" swapped="no"/> |
956 | + <child> |
957 | + <object class="GtkScrolledWindow" id="tc_browser_window"> |
958 | + <property name="visible">True</property> |
959 | + <property name="can_focus">True</property> |
960 | + <property name="border_width">10</property> |
961 | + <property name="hscrollbar_policy">never</property> |
962 | + <property name="shadow_type">in</property> |
963 | + <child> |
964 | + <placeholder/> |
965 | + </child> |
966 | + </object> |
967 | + <packing> |
968 | + <property name="expand">True</property> |
969 | + <property name="fill">True</property> |
970 | + <property name="position">0</property> |
971 | + </packing> |
972 | + </child> |
973 | + <child> |
974 | + <object class="GtkHButtonBox" id="hbuttonbox4"> |
975 | + <property name="visible">True</property> |
976 | + <property name="can_focus">False</property> |
977 | + <property name="layout_style">end</property> |
978 | + <child> |
979 | + <object class="GtkButton" id="tc_back_button"> |
980 | + <property name="label">gtk-go-back</property> |
981 | + <property name="use_action_appearance">False</property> |
982 | + <property name="visible">True</property> |
983 | + <property name="can_focus">True</property> |
984 | + <property name="receives_default">True</property> |
985 | + <property name="use_action_appearance">False</property> |
986 | + <property name="use_stock">True</property> |
987 | + <signal name="clicked" handler="on_tc_back_button_clicked" swapped="no"/> |
988 | + </object> |
989 | + <packing> |
990 | + <property name="expand">False</property> |
991 | + <property name="fill">False</property> |
992 | + <property name="position">0</property> |
993 | + </packing> |
994 | + </child> |
995 | + </object> |
996 | + <packing> |
997 | + <property name="expand">False</property> |
998 | + <property name="fill">True</property> |
999 | + <property name="position">1</property> |
1000 | + </packing> |
1001 | + </child> |
1002 | + </object> |
1003 | + <object class="GtkVBox" id="verify_email_vbox"> |
1004 | + <property name="visible">True</property> |
1005 | + <property name="can_focus">False</property> |
1006 | <property name="spacing">10</property> |
1007 | <child> |
1008 | - <object class="GtkLabel" id="finish_label"> |
1009 | + <object class="GtkAlignment" id="alignment4"> |
1010 | <property name="visible">True</property> |
1011 | - <property name="wrap">True</property> |
1012 | + <property name="can_focus">False</property> |
1013 | + <property name="xscale">0</property> |
1014 | + <property name="yscale">0</property> |
1015 | + <child> |
1016 | + <object class="GtkVBox" id="verify_email_details_vbox"> |
1017 | + <property name="visible">True</property> |
1018 | + <property name="can_focus">False</property> |
1019 | + <child> |
1020 | + <placeholder/> |
1021 | + </child> |
1022 | + </object> |
1023 | + </child> |
1024 | </object> |
1025 | <packing> |
1026 | + <property name="expand">True</property> |
1027 | + <property name="fill">True</property> |
1028 | <property name="position">0</property> |
1029 | </packing> |
1030 | </child> |
1031 | <child> |
1032 | - <object class="GtkHButtonBox" id="hbuttonbox8"> |
1033 | + <object class="GtkHButtonBox" id="hbuttonbox2"> |
1034 | <property name="visible">True</property> |
1035 | + <property name="can_focus">False</property> |
1036 | + <property name="spacing">5</property> |
1037 | <property name="layout_style">end</property> |
1038 | <child> |
1039 | - <object class="GtkButton" id="finish_close_button"> |
1040 | - <property name="label">gtk-close</property> |
1041 | + <object class="GtkButton" id="verify_token_button"> |
1042 | + <property name="label">gtk-ok</property> |
1043 | + <property name="use_action_appearance">False</property> |
1044 | <property name="visible">True</property> |
1045 | <property name="can_focus">True</property> |
1046 | <property name="receives_default">True</property> |
1047 | + <property name="use_action_appearance">False</property> |
1048 | <property name="use_stock">True</property> |
1049 | - <signal name="clicked" handler="on_close_clicked"/> |
1050 | + <signal name="clicked" handler="on_verify_token_button_clicked" swapped="no"/> |
1051 | </object> |
1052 | <packing> |
1053 | <property name="expand">False</property> |
1054 | @@ -779,8 +843,78 @@ |
1055 | </object> |
1056 | <packing> |
1057 | <property name="expand">False</property> |
1058 | + <property name="fill">True</property> |
1059 | <property name="position">1</property> |
1060 | </packing> |
1061 | </child> |
1062 | </object> |
1063 | + <object class="GtkWindow" id="window"> |
1064 | + <property name="can_focus">False</property> |
1065 | + <property name="border_width">10</property> |
1066 | + <property name="window_position">center</property> |
1067 | + <signal name="delete-event" handler="on_close_clicked" swapped="no"/> |
1068 | + <child> |
1069 | + <object class="GtkVBox" id="window_vbox"> |
1070 | + <property name="visible">True</property> |
1071 | + <property name="can_focus">False</property> |
1072 | + <property name="spacing">5</property> |
1073 | + <child> |
1074 | + <object class="GtkLabel" id="header_label"> |
1075 | + <property name="visible">True</property> |
1076 | + <property name="can_focus">False</property> |
1077 | + <property name="xalign">0</property> |
1078 | + <property name="label" translatable="yes">Header Label </property> |
1079 | + <property name="wrap">True</property> |
1080 | + </object> |
1081 | + <packing> |
1082 | + <property name="expand">False</property> |
1083 | + <property name="fill">True</property> |
1084 | + <property name="padding">5</property> |
1085 | + <property name="position">0</property> |
1086 | + </packing> |
1087 | + </child> |
1088 | + <child> |
1089 | + <object class="GtkLabel" id="help_label"> |
1090 | + <property name="visible">True</property> |
1091 | + <property name="can_focus">False</property> |
1092 | + <property name="xalign">0</property> |
1093 | + <property name="label" translatable="yes">help label</property> |
1094 | + <property name="wrap">True</property> |
1095 | + </object> |
1096 | + <packing> |
1097 | + <property name="expand">False</property> |
1098 | + <property name="fill">True</property> |
1099 | + <property name="position">1</property> |
1100 | + </packing> |
1101 | + </child> |
1102 | + <child> |
1103 | + <object class="GtkLabel" id="warning_label"> |
1104 | + <property name="visible">True</property> |
1105 | + <property name="can_focus">False</property> |
1106 | + <property name="xalign">0</property> |
1107 | + <property name="label" translatable="yes">warning label</property> |
1108 | + <property name="wrap">True</property> |
1109 | + </object> |
1110 | + <packing> |
1111 | + <property name="expand">False</property> |
1112 | + <property name="fill">True</property> |
1113 | + <property name="position">2</property> |
1114 | + </packing> |
1115 | + </child> |
1116 | + <child> |
1117 | + <object class="GtkNotebook" id="content"> |
1118 | + <property name="visible">True</property> |
1119 | + <property name="can_focus">True</property> |
1120 | + <property name="show_tabs">False</property> |
1121 | + <property name="show_border">False</property> |
1122 | + </object> |
1123 | + <packing> |
1124 | + <property name="expand">True</property> |
1125 | + <property name="fill">True</property> |
1126 | + <property name="position">3</property> |
1127 | + </packing> |
1128 | + </child> |
1129 | + </object> |
1130 | + </child> |
1131 | + </object> |
1132 | </interface> |
1133 | |
1134 | === modified file 'data/qt/choose_sign_in.ui' |
1135 | --- data/qt/choose_sign_in.ui 2011-04-05 14:04:50 +0000 |
1136 | +++ data/qt/choose_sign_in.ui 2012-02-14 22:04:20 +0000 |
1137 | @@ -1,32 +1,103 @@ |
1138 | <?xml version="1.0" encoding="UTF-8"?> |
1139 | <ui version="4.0"> |
1140 | <class>ChooseSignInPage</class> |
1141 | - <widget class="QWizardPage" name="ChooseSingInPage"> |
1142 | + <widget class="QWizardPage" name="ChooseSignInPage"> |
1143 | <property name="geometry"> |
1144 | <rect> |
1145 | <x>0</x> |
1146 | <y>0</y> |
1147 | - <width>400</width> |
1148 | - <height>300</height> |
1149 | + <width>432</width> |
1150 | + <height>387</height> |
1151 | </rect> |
1152 | </property> |
1153 | <property name="windowTitle"> |
1154 | <string>WizardPage</string> |
1155 | </property> |
1156 | - <layout class="QHBoxLayout" name="horizontalLayout"> |
1157 | - <item> |
1158 | - <layout class="QHBoxLayout" name="horizontalLayout_3"> |
1159 | + <layout class="QVBoxLayout" name="verticalLayout_2"> |
1160 | + <property name="leftMargin"> |
1161 | + <number>0</number> |
1162 | + </property> |
1163 | + <property name="topMargin"> |
1164 | + <number>0</number> |
1165 | + </property> |
1166 | + <property name="rightMargin"> |
1167 | + <number>0</number> |
1168 | + </property> |
1169 | + <item> |
1170 | + <layout class="QHBoxLayout" name="horizontalLayout_2"> |
1171 | + <item> |
1172 | + <widget class="QLabel" name="image_label"> |
1173 | + <property name="sizePolicy"> |
1174 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1175 | + <horstretch>0</horstretch> |
1176 | + <verstretch>0</verstretch> |
1177 | + </sizepolicy> |
1178 | + </property> |
1179 | + <property name="minimumSize"> |
1180 | + <size> |
1181 | + <width>400</width> |
1182 | + <height>150</height> |
1183 | + </size> |
1184 | + </property> |
1185 | + <property name="text"> |
1186 | + <string/> |
1187 | + </property> |
1188 | + <property name="textFormat"> |
1189 | + <enum>Qt::PlainText</enum> |
1190 | + </property> |
1191 | + <property name="alignment"> |
1192 | + <set>Qt::AlignCenter</set> |
1193 | + </property> |
1194 | + <property name="wordWrap"> |
1195 | + <bool>true</bool> |
1196 | + </property> |
1197 | + </widget> |
1198 | + </item> |
1199 | + </layout> |
1200 | + </item> |
1201 | + <item> |
1202 | + <widget class="QLabel" name="message_label"> |
1203 | + <property name="font"> |
1204 | + <font> |
1205 | + <pointsize>11</pointsize> |
1206 | + <weight>50</weight> |
1207 | + <bold>false</bold> |
1208 | + </font> |
1209 | + </property> |
1210 | + <property name="text"> |
1211 | + <string>Congratulations, app_name is installed!</string> |
1212 | + </property> |
1213 | + <property name="alignment"> |
1214 | + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> |
1215 | + </property> |
1216 | + </widget> |
1217 | + </item> |
1218 | + <item> |
1219 | + <spacer name="verticalSpacer_3"> |
1220 | + <property name="orientation"> |
1221 | + <enum>Qt::Vertical</enum> |
1222 | + </property> |
1223 | + <property name="sizeType"> |
1224 | + <enum>QSizePolicy::Fixed</enum> |
1225 | + </property> |
1226 | + <property name="sizeHint" stdset="0"> |
1227 | + <size> |
1228 | + <width>20</width> |
1229 | + <height>30</height> |
1230 | + </size> |
1231 | + </property> |
1232 | + </spacer> |
1233 | + </item> |
1234 | + <item> |
1235 | + <layout class="QHBoxLayout" name="horizontalLayout"> |
1236 | <item> |
1237 | <spacer name="horizontalSpacer_2"> |
1238 | <property name="orientation"> |
1239 | <enum>Qt::Horizontal</enum> |
1240 | </property> |
1241 | - <property name="sizeType"> |
1242 | - <enum>QSizePolicy::Expanding</enum> |
1243 | - </property> |
1244 | <property name="sizeHint" stdset="0"> |
1245 | <size> |
1246 | - <width>40</width> |
1247 | + <width>20</width> |
1248 | <height>20</height> |
1249 | </size> |
1250 | </property> |
1251 | @@ -35,44 +106,11 @@ |
1252 | <item> |
1253 | <layout class="QVBoxLayout" name="verticalLayout"> |
1254 | <item> |
1255 | - <spacer name="verticalSpacer_3"> |
1256 | - <property name="orientation"> |
1257 | - <enum>Qt::Vertical</enum> |
1258 | - </property> |
1259 | - <property name="sizeHint" stdset="0"> |
1260 | - <size> |
1261 | - <width>20</width> |
1262 | - <height>40</height> |
1263 | - </size> |
1264 | - </property> |
1265 | - </spacer> |
1266 | - </item> |
1267 | - <item> |
1268 | - <layout class="QHBoxLayout" name="horizontalLayout_2"> |
1269 | - <item> |
1270 | - <widget class="QPushButton" name="existing_account_button"> |
1271 | - <property name="text"> |
1272 | - <string/> |
1273 | - </property> |
1274 | - </widget> |
1275 | - </item> |
1276 | - </layout> |
1277 | - </item> |
1278 | - <item> |
1279 | - <spacer name="verticalSpacer"> |
1280 | - <property name="orientation"> |
1281 | - <enum>Qt::Vertical</enum> |
1282 | - </property> |
1283 | - <property name="sizeType"> |
1284 | - <enum>QSizePolicy::Fixed</enum> |
1285 | - </property> |
1286 | - <property name="sizeHint" stdset="0"> |
1287 | - <size> |
1288 | - <width>20</width> |
1289 | - <height>10</height> |
1290 | - </size> |
1291 | - </property> |
1292 | - </spacer> |
1293 | + <widget class="QPushButton" name="existing_account_button"> |
1294 | + <property name="text"> |
1295 | + <string/> |
1296 | + </property> |
1297 | + </widget> |
1298 | </item> |
1299 | <item> |
1300 | <widget class="QPushButton" name="setup_account_button"> |
1301 | @@ -82,17 +120,11 @@ |
1302 | </widget> |
1303 | </item> |
1304 | <item> |
1305 | - <spacer name="verticalSpacer_2"> |
1306 | - <property name="orientation"> |
1307 | - <enum>Qt::Vertical</enum> |
1308 | - </property> |
1309 | - <property name="sizeHint" stdset="0"> |
1310 | - <size> |
1311 | - <width>20</width> |
1312 | - <height>40</height> |
1313 | - </size> |
1314 | - </property> |
1315 | - </spacer> |
1316 | + <widget class="QPushButton" name="cancel_button"> |
1317 | + <property name="text"> |
1318 | + <string/> |
1319 | + </property> |
1320 | + </widget> |
1321 | </item> |
1322 | </layout> |
1323 | </item> |
1324 | @@ -106,7 +138,7 @@ |
1325 | </property> |
1326 | <property name="sizeHint" stdset="0"> |
1327 | <size> |
1328 | - <width>40</width> |
1329 | + <width>20</width> |
1330 | <height>20</height> |
1331 | </size> |
1332 | </property> |
1333 | @@ -114,8 +146,20 @@ |
1334 | </item> |
1335 | </layout> |
1336 | </item> |
1337 | + <item> |
1338 | + <spacer name="verticalSpacer_2"> |
1339 | + <property name="orientation"> |
1340 | + <enum>Qt::Vertical</enum> |
1341 | + </property> |
1342 | + <property name="sizeHint" stdset="0"> |
1343 | + <size> |
1344 | + <width>20</width> |
1345 | + <height>50</height> |
1346 | + </size> |
1347 | + </property> |
1348 | + </spacer> |
1349 | + </item> |
1350 | </layout> |
1351 | </widget> |
1352 | - <resources/> |
1353 | <connections/> |
1354 | </ui> |
1355 | |
1356 | === added file 'data/qt/loadingoverlay.ui' |
1357 | --- data/qt/loadingoverlay.ui 1970-01-01 00:00:00 +0000 |
1358 | +++ data/qt/loadingoverlay.ui 2012-02-14 22:04:20 +0000 |
1359 | @@ -0,0 +1,103 @@ |
1360 | +<?xml version="1.0" encoding="UTF-8"?> |
1361 | +<ui version="4.0"> |
1362 | + <class>Form</class> |
1363 | + <widget class="QFrame" name="Form"> |
1364 | + <property name="geometry"> |
1365 | + <rect> |
1366 | + <x>0</x> |
1367 | + <y>0</y> |
1368 | + <width>702</width> |
1369 | + <height>230</height> |
1370 | + </rect> |
1371 | + </property> |
1372 | + <property name="windowTitle"> |
1373 | + <string>Frame</string> |
1374 | + </property> |
1375 | + <layout class="QVBoxLayout" name="verticalLayout"> |
1376 | + <property name="topMargin"> |
1377 | + <number>30</number> |
1378 | + </property> |
1379 | + <item> |
1380 | + <layout class="QHBoxLayout" name="horizontalLayout_2"> |
1381 | + <item> |
1382 | + <spacer name="horizontalSpacer_2"> |
1383 | + <property name="orientation"> |
1384 | + <enum>Qt::Horizontal</enum> |
1385 | + </property> |
1386 | + <property name="sizeHint" stdset="0"> |
1387 | + <size> |
1388 | + <width>40</width> |
1389 | + <height>20</height> |
1390 | + </size> |
1391 | + </property> |
1392 | + </spacer> |
1393 | + </item> |
1394 | + <item> |
1395 | + <widget class="QFrame" name="frm_box"> |
1396 | + <property name="minimumSize"> |
1397 | + <size> |
1398 | + <width>0</width> |
1399 | + <height>102</height> |
1400 | + </size> |
1401 | + </property> |
1402 | + <layout class="QHBoxLayout" name="horizontalLayout"> |
1403 | + <property name="topMargin"> |
1404 | + <number>0</number> |
1405 | + </property> |
1406 | + <property name="bottomMargin"> |
1407 | + <number>30</number> |
1408 | + </property> |
1409 | + <item> |
1410 | + <widget class="QLabel" name="label"> |
1411 | + <property name="sizePolicy"> |
1412 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1413 | + <horstretch>0</horstretch> |
1414 | + <verstretch>0</verstretch> |
1415 | + </sizepolicy> |
1416 | + </property> |
1417 | + <property name="font"> |
1418 | + <font> |
1419 | + <pointsize>14</pointsize> |
1420 | + </font> |
1421 | + </property> |
1422 | + <property name="text"> |
1423 | + <string>Getting information, please wait...</string> |
1424 | + </property> |
1425 | + </widget> |
1426 | + </item> |
1427 | + </layout> |
1428 | + </widget> |
1429 | + </item> |
1430 | + <item> |
1431 | + <spacer name="horizontalSpacer"> |
1432 | + <property name="orientation"> |
1433 | + <enum>Qt::Horizontal</enum> |
1434 | + </property> |
1435 | + <property name="sizeHint" stdset="0"> |
1436 | + <size> |
1437 | + <width>40</width> |
1438 | + <height>20</height> |
1439 | + </size> |
1440 | + </property> |
1441 | + </spacer> |
1442 | + </item> |
1443 | + </layout> |
1444 | + </item> |
1445 | + <item> |
1446 | + <spacer name="verticalSpacer"> |
1447 | + <property name="orientation"> |
1448 | + <enum>Qt::Vertical</enum> |
1449 | + </property> |
1450 | + <property name="sizeHint" stdset="0"> |
1451 | + <size> |
1452 | + <width>20</width> |
1453 | + <height>20</height> |
1454 | + </size> |
1455 | + </property> |
1456 | + </spacer> |
1457 | + </item> |
1458 | + </layout> |
1459 | + </widget> |
1460 | + <resources/> |
1461 | + <connections/> |
1462 | +</ui> |
1463 | |
1464 | === added file 'data/qt/network_detection.ui' |
1465 | --- data/qt/network_detection.ui 1970-01-01 00:00:00 +0000 |
1466 | +++ data/qt/network_detection.ui 2012-02-14 22:04:20 +0000 |
1467 | @@ -0,0 +1,142 @@ |
1468 | +<?xml version="1.0" encoding="UTF-8"?> |
1469 | +<ui version="4.0"> |
1470 | + <class>Form</class> |
1471 | + <widget class="QWizardPage" name="Form"> |
1472 | + <property name="geometry"> |
1473 | + <rect> |
1474 | + <x>0</x> |
1475 | + <y>0</y> |
1476 | + <width>541</width> |
1477 | + <height>365</height> |
1478 | + </rect> |
1479 | + </property> |
1480 | + <property name="windowTitle"> |
1481 | + <string>WizardPage</string> |
1482 | + </property> |
1483 | + <layout class="QVBoxLayout" name="verticalLayout"> |
1484 | + <item> |
1485 | + <layout class="QHBoxLayout" name="horizontalLayout_2"> |
1486 | + <item> |
1487 | + <spacer name="horizontalSpacer_3"> |
1488 | + <property name="orientation"> |
1489 | + <enum>Qt::Horizontal</enum> |
1490 | + </property> |
1491 | + <property name="sizeHint" stdset="0"> |
1492 | + <size> |
1493 | + <width>40</width> |
1494 | + <height>20</height> |
1495 | + </size> |
1496 | + </property> |
1497 | + </spacer> |
1498 | + </item> |
1499 | + <item> |
1500 | + <widget class="QLabel" name="image_label"> |
1501 | + <property name="sizePolicy"> |
1502 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1503 | + <horstretch>0</horstretch> |
1504 | + <verstretch>0</verstretch> |
1505 | + </sizepolicy> |
1506 | + </property> |
1507 | + <property name="minimumSize"> |
1508 | + <size> |
1509 | + <width>400</width> |
1510 | + <height>150</height> |
1511 | + </size> |
1512 | + </property> |
1513 | + <property name="text"> |
1514 | + <string/> |
1515 | + </property> |
1516 | + <property name="textFormat"> |
1517 | + <enum>Qt::PlainText</enum> |
1518 | + </property> |
1519 | + <property name="alignment"> |
1520 | + <set>Qt::AlignCenter</set> |
1521 | + </property> |
1522 | + <property name="wordWrap"> |
1523 | + <bool>true</bool> |
1524 | + </property> |
1525 | + </widget> |
1526 | + </item> |
1527 | + <item> |
1528 | + <spacer name="horizontalSpacer_4"> |
1529 | + <property name="orientation"> |
1530 | + <enum>Qt::Horizontal</enum> |
1531 | + </property> |
1532 | + <property name="sizeHint" stdset="0"> |
1533 | + <size> |
1534 | + <width>40</width> |
1535 | + <height>20</height> |
1536 | + </size> |
1537 | + </property> |
1538 | + </spacer> |
1539 | + </item> |
1540 | + </layout> |
1541 | + </item> |
1542 | + <item> |
1543 | + <widget class="QLabel" name="message_label"> |
1544 | + <property name="alignment"> |
1545 | + <set>Qt::AlignCenter</set> |
1546 | + </property> |
1547 | + </widget> |
1548 | + </item> |
1549 | + <item> |
1550 | + <layout class="QHBoxLayout" name="horizontalLayout"> |
1551 | + <item> |
1552 | + <spacer name="horizontalSpacer"> |
1553 | + <property name="orientation"> |
1554 | + <enum>Qt::Horizontal</enum> |
1555 | + </property> |
1556 | + <property name="sizeHint" stdset="0"> |
1557 | + <size> |
1558 | + <width>40</width> |
1559 | + <height>20</height> |
1560 | + </size> |
1561 | + </property> |
1562 | + </spacer> |
1563 | + </item> |
1564 | + <item> |
1565 | + <widget class="QLabel" name="label"> |
1566 | + <property name="text"> |
1567 | + <string>Are you online? We can't detect an internet connection - you will need to be connected to set up Ubuntu Single Sign On</string> |
1568 | + </property> |
1569 | + <property name="textFormat"> |
1570 | + <enum>Qt::PlainText</enum> |
1571 | + </property> |
1572 | + <property name="wordWrap"> |
1573 | + <bool>true</bool> |
1574 | + </property> |
1575 | + </widget> |
1576 | + </item> |
1577 | + <item> |
1578 | + <spacer name="horizontalSpacer_2"> |
1579 | + <property name="orientation"> |
1580 | + <enum>Qt::Horizontal</enum> |
1581 | + </property> |
1582 | + <property name="sizeHint" stdset="0"> |
1583 | + <size> |
1584 | + <width>40</width> |
1585 | + <height>20</height> |
1586 | + </size> |
1587 | + </property> |
1588 | + </spacer> |
1589 | + </item> |
1590 | + </layout> |
1591 | + </item> |
1592 | + <item> |
1593 | + <spacer name="verticalSpacer"> |
1594 | + <property name="orientation"> |
1595 | + <enum>Qt::Vertical</enum> |
1596 | + </property> |
1597 | + <property name="sizeHint" stdset="0"> |
1598 | + <size> |
1599 | + <width>20</width> |
1600 | + <height>76</height> |
1601 | + </size> |
1602 | + </property> |
1603 | + </spacer> |
1604 | + </item> |
1605 | + </layout> |
1606 | + </widget> |
1607 | + <resources/> |
1608 | + <connections/> |
1609 | +</ui> |
1610 | |
1611 | === added file 'data/qt/proxy_credentials_dialog.ui' |
1612 | --- data/qt/proxy_credentials_dialog.ui 1970-01-01 00:00:00 +0000 |
1613 | +++ data/qt/proxy_credentials_dialog.ui 2012-02-14 22:04:20 +0000 |
1614 | @@ -0,0 +1,316 @@ |
1615 | +<?xml version="1.0" encoding="UTF-8"?> |
1616 | +<ui version="4.0"> |
1617 | + <class>ProxyCredsDialog</class> |
1618 | + <widget class="QDialog" name="ProxyCredsDialog"> |
1619 | + <property name="windowModality"> |
1620 | + <enum>Qt::NonModal</enum> |
1621 | + </property> |
1622 | + <property name="geometry"> |
1623 | + <rect> |
1624 | + <x>0</x> |
1625 | + <y>0</y> |
1626 | + <width>550</width> |
1627 | + <height>364</height> |
1628 | + </rect> |
1629 | + </property> |
1630 | + <property name="sizePolicy"> |
1631 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1632 | + <horstretch>0</horstretch> |
1633 | + <verstretch>0</verstretch> |
1634 | + </sizepolicy> |
1635 | + </property> |
1636 | + <property name="minimumSize"> |
1637 | + <size> |
1638 | + <width>502</width> |
1639 | + <height>0</height> |
1640 | + </size> |
1641 | + </property> |
1642 | + <property name="windowTitle"> |
1643 | + <string>Add proxy settings</string> |
1644 | + </property> |
1645 | + <property name="sizeGripEnabled"> |
1646 | + <bool>false</bool> |
1647 | + </property> |
1648 | + <layout class="QHBoxLayout" name="horizontalLayout"> |
1649 | + <property name="sizeConstraint"> |
1650 | + <enum>QLayout::SetFixedSize</enum> |
1651 | + </property> |
1652 | + <item> |
1653 | + <layout class="QVBoxLayout" name="verticalLayout"> |
1654 | + <property name="spacing"> |
1655 | + <number>24</number> |
1656 | + </property> |
1657 | + <item> |
1658 | + <layout class="QHBoxLayout" name="horizontalLayout_4"> |
1659 | + <property name="spacing"> |
1660 | + <number>12</number> |
1661 | + </property> |
1662 | + <item> |
1663 | + <layout class="QVBoxLayout" name="verticalLayout_4"> |
1664 | + <property name="spacing"> |
1665 | + <number>0</number> |
1666 | + </property> |
1667 | + <property name="sizeConstraint"> |
1668 | + <enum>QLayout::SetDefaultConstraint</enum> |
1669 | + </property> |
1670 | + <item> |
1671 | + <widget class="QLabel" name="logo_label"> |
1672 | + <property name="sizePolicy"> |
1673 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1674 | + <horstretch>0</horstretch> |
1675 | + <verstretch>0</verstretch> |
1676 | + </sizepolicy> |
1677 | + </property> |
1678 | + <property name="minimumSize"> |
1679 | + <size> |
1680 | + <width>48</width> |
1681 | + <height>48</height> |
1682 | + </size> |
1683 | + </property> |
1684 | + <property name="maximumSize"> |
1685 | + <size> |
1686 | + <width>48</width> |
1687 | + <height>48</height> |
1688 | + </size> |
1689 | + </property> |
1690 | + <property name="text"> |
1691 | + <string>TextLabel</string> |
1692 | + </property> |
1693 | + </widget> |
1694 | + </item> |
1695 | + <item> |
1696 | + <spacer name="verticalSpacer_4"> |
1697 | + <property name="orientation"> |
1698 | + <enum>Qt::Vertical</enum> |
1699 | + </property> |
1700 | + <property name="sizeType"> |
1701 | + <enum>QSizePolicy::Expanding</enum> |
1702 | + </property> |
1703 | + <property name="sizeHint" stdset="0"> |
1704 | + <size> |
1705 | + <width>0</width> |
1706 | + <height>20</height> |
1707 | + </size> |
1708 | + </property> |
1709 | + </spacer> |
1710 | + </item> |
1711 | + </layout> |
1712 | + </item> |
1713 | + <item> |
1714 | + <layout class="QVBoxLayout" name="verticalLayout_3"> |
1715 | + <property name="spacing"> |
1716 | + <number>24</number> |
1717 | + </property> |
1718 | + <item> |
1719 | + <layout class="QVBoxLayout" name="verticalLayout_2"> |
1720 | + <property name="spacing"> |
1721 | + <number>24</number> |
1722 | + </property> |
1723 | + <item> |
1724 | + <widget class="QLabel" name="title_label"> |
1725 | + <property name="sizePolicy"> |
1726 | + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
1727 | + <horstretch>0</horstretch> |
1728 | + <verstretch>0</verstretch> |
1729 | + </sizepolicy> |
1730 | + </property> |
1731 | + <property name="font"> |
1732 | + <font> |
1733 | + <pointsize>14</pointsize> |
1734 | + <weight>75</weight> |
1735 | + <bold>true</bold> |
1736 | + </font> |
1737 | + </property> |
1738 | + <property name="text"> |
1739 | + <string>You are connection through a proxy.</string> |
1740 | + </property> |
1741 | + <property name="wordWrap"> |
1742 | + <bool>true</bool> |
1743 | + </property> |
1744 | + </widget> |
1745 | + </item> |
1746 | + <item> |
1747 | + <widget class="QLabel" name="explanation_label"> |
1748 | + <property name="text"> |
1749 | + <string>Please provide the login details below, or check your system settings</string> |
1750 | + </property> |
1751 | + <property name="wordWrap"> |
1752 | + <bool>true</bool> |
1753 | + </property> |
1754 | + </widget> |
1755 | + </item> |
1756 | + </layout> |
1757 | + </item> |
1758 | + <item> |
1759 | + <widget class="QFrame" name="frame"> |
1760 | + <property name="frameShape"> |
1761 | + <enum>QFrame::NoFrame</enum> |
1762 | + </property> |
1763 | + <property name="frameShadow"> |
1764 | + <enum>QFrame::Plain</enum> |
1765 | + </property> |
1766 | + <layout class="QGridLayout" name="gridLayout_2"> |
1767 | + <property name="spacing"> |
1768 | + <number>12</number> |
1769 | + </property> |
1770 | + <item row="0" column="0"> |
1771 | + <widget class="QLabel" name="connection_label"> |
1772 | + <property name="sizePolicy"> |
1773 | + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
1774 | + <horstretch>0</horstretch> |
1775 | + <verstretch>0</verstretch> |
1776 | + </sizepolicy> |
1777 | + </property> |
1778 | + <property name="text"> |
1779 | + <string>Connecting to:</string> |
1780 | + </property> |
1781 | + <property name="alignment"> |
1782 | + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> |
1783 | + </property> |
1784 | + </widget> |
1785 | + </item> |
1786 | + <item row="0" column="1"> |
1787 | + <widget class="QLabel" name="domain_label"> |
1788 | + <property name="text"> |
1789 | + <string/> |
1790 | + </property> |
1791 | + </widget> |
1792 | + </item> |
1793 | + <item row="4" column="0"> |
1794 | + <widget class="QLabel" name="username_label"> |
1795 | + <property name="text"> |
1796 | + <string>Proxy username:</string> |
1797 | + </property> |
1798 | + <property name="alignment"> |
1799 | + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> |
1800 | + </property> |
1801 | + </widget> |
1802 | + </item> |
1803 | + <item row="4" column="1"> |
1804 | + <widget class="QLineEdit" name="username_entry"> |
1805 | + <property name="text"> |
1806 | + <string/> |
1807 | + </property> |
1808 | + </widget> |
1809 | + </item> |
1810 | + <item row="5" column="0"> |
1811 | + <widget class="QLabel" name="password_label"> |
1812 | + <property name="text"> |
1813 | + <string>Proxy password:</string> |
1814 | + </property> |
1815 | + <property name="alignment"> |
1816 | + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> |
1817 | + </property> |
1818 | + </widget> |
1819 | + </item> |
1820 | + <item row="5" column="1"> |
1821 | + <widget class="QLineEdit" name="password_entry"> |
1822 | + <property name="echoMode"> |
1823 | + <enum>QLineEdit::Password</enum> |
1824 | + </property> |
1825 | + </widget> |
1826 | + </item> |
1827 | + <item row="1" column="0"> |
1828 | + <spacer name="verticalSpacer"> |
1829 | + <property name="orientation"> |
1830 | + <enum>Qt::Vertical</enum> |
1831 | + </property> |
1832 | + <property name="sizeType"> |
1833 | + <enum>QSizePolicy::Fixed</enum> |
1834 | + </property> |
1835 | + <property name="sizeHint" stdset="0"> |
1836 | + <size> |
1837 | + <width>24</width> |
1838 | + <height>12</height> |
1839 | + </size> |
1840 | + </property> |
1841 | + </spacer> |
1842 | + </item> |
1843 | + <item row="2" column="0" colspan="2"> |
1844 | + <widget class="QLabel" name="error_label"> |
1845 | + <property name="text"> |
1846 | + <string>TextLabel</string> |
1847 | + </property> |
1848 | + <property name="wordWrap"> |
1849 | + <bool>false</bool> |
1850 | + </property> |
1851 | + </widget> |
1852 | + </item> |
1853 | + <item row="3" column="0"> |
1854 | + <spacer name="verticalSpacer_2"> |
1855 | + <property name="orientation"> |
1856 | + <enum>Qt::Vertical</enum> |
1857 | + </property> |
1858 | + <property name="sizeType"> |
1859 | + <enum>QSizePolicy::Fixed</enum> |
1860 | + </property> |
1861 | + <property name="sizeHint" stdset="0"> |
1862 | + <size> |
1863 | + <width>24</width> |
1864 | + <height>12</height> |
1865 | + </size> |
1866 | + </property> |
1867 | + </spacer> |
1868 | + </item> |
1869 | + </layout> |
1870 | + </widget> |
1871 | + </item> |
1872 | + </layout> |
1873 | + </item> |
1874 | + </layout> |
1875 | + </item> |
1876 | + <item> |
1877 | + <layout class="QHBoxLayout" name="horizontalLayout_5"> |
1878 | + <item> |
1879 | + <widget class="QPushButton" name="help_button"> |
1880 | + <property name="text"> |
1881 | + <string>Get Help With Proxies</string> |
1882 | + </property> |
1883 | + </widget> |
1884 | + </item> |
1885 | + <item> |
1886 | + <spacer name="horizontalSpacer"> |
1887 | + <property name="orientation"> |
1888 | + <enum>Qt::Horizontal</enum> |
1889 | + </property> |
1890 | + <property name="sizeHint" stdset="0"> |
1891 | + <size> |
1892 | + <width>40</width> |
1893 | + <height>20</height> |
1894 | + </size> |
1895 | + </property> |
1896 | + </spacer> |
1897 | + </item> |
1898 | + <item> |
1899 | + <widget class="QPushButton" name="cancel_button"> |
1900 | + <property name="text"> |
1901 | + <string>Cancel and Close</string> |
1902 | + </property> |
1903 | + </widget> |
1904 | + </item> |
1905 | + <item> |
1906 | + <widget class="QPushButton" name="save_button"> |
1907 | + <property name="text"> |
1908 | + <string>Save</string> |
1909 | + </property> |
1910 | + <property name="default"> |
1911 | + <bool>true</bool> |
1912 | + </property> |
1913 | + </widget> |
1914 | + </item> |
1915 | + </layout> |
1916 | + </item> |
1917 | + </layout> |
1918 | + </item> |
1919 | + </layout> |
1920 | + </widget> |
1921 | + <tabstops> |
1922 | + <tabstop>username_entry</tabstop> |
1923 | + <tabstop>password_entry</tabstop> |
1924 | + <tabstop>save_button</tabstop> |
1925 | + <tabstop>cancel_button</tabstop> |
1926 | + <tabstop>help_button</tabstop> |
1927 | + </tabstops> |
1928 | + <resources/> |
1929 | + <connections/> |
1930 | +</ui> |
1931 | |
1932 | === modified file 'data/qt/setup_account.ui' |
1933 | --- data/qt/setup_account.ui 2011-09-02 12:53:55 +0000 |
1934 | +++ data/qt/setup_account.ui 2012-02-14 22:04:20 +0000 |
1935 | @@ -6,275 +6,662 @@ |
1936 | <rect> |
1937 | <x>0</x> |
1938 | <y>0</y> |
1939 | - <width>407</width> |
1940 | - <height>572</height> |
1941 | + <width>543</width> |
1942 | + <height>523</height> |
1943 | </rect> |
1944 | </property> |
1945 | + <property name="sizePolicy"> |
1946 | + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> |
1947 | + <horstretch>0</horstretch> |
1948 | + <verstretch>0</verstretch> |
1949 | + </sizepolicy> |
1950 | + </property> |
1951 | + <property name="maximumSize"> |
1952 | + <size> |
1953 | + <width>16777215</width> |
1954 | + <height>16777215</height> |
1955 | + </size> |
1956 | + </property> |
1957 | <property name="windowTitle"> |
1958 | <string>WizardPage</string> |
1959 | </property> |
1960 | - <layout class="QVBoxLayout" name="verticalLayout_5"> |
1961 | + <layout class="QVBoxLayout" name="verticalLayout"> |
1962 | + <property name="spacing"> |
1963 | + <number>0</number> |
1964 | + </property> |
1965 | + <property name="leftMargin"> |
1966 | + <number>0</number> |
1967 | + </property> |
1968 | <property name="topMargin"> |
1969 | <number>0</number> |
1970 | </property> |
1971 | + <property name="rightMargin"> |
1972 | + <number>3</number> |
1973 | + </property> |
1974 | + <property name="bottomMargin"> |
1975 | + <number>0</number> |
1976 | + </property> |
1977 | <item> |
1978 | - <layout class="QVBoxLayout" name="verticalLayout"> |
1979 | - <item> |
1980 | - <widget class="QFrame" name="_signInFrame"> |
1981 | - <property name="frameShape"> |
1982 | - <enum>QFrame::NoFrame</enum> |
1983 | - </property> |
1984 | - <layout class="QVBoxLayout" name="verticalLayout_3"> |
1985 | - <item> |
1986 | - <layout class="QVBoxLayout" name="verticalLayout_2"> |
1987 | - <item> |
1988 | - <widget class="QLabel" name="password_info_label"> |
1989 | - <property name="sizePolicy"> |
1990 | - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> |
1991 | - <horstretch>0</horstretch> |
1992 | - <verstretch>0</verstretch> |
1993 | - </sizepolicy> |
1994 | - </property> |
1995 | - <property name="text"> |
1996 | - <string/> |
1997 | - </property> |
1998 | - <property name="wordWrap"> |
1999 | - <bool>true</bool> |
2000 | - </property> |
2001 | - </widget> |
2002 | - </item> |
2003 | - <item> |
2004 | - <layout class="QVBoxLayout" name="verticalLayout_4"> |
2005 | - <item> |
2006 | - <widget class="QLabel" name="name_label"> |
2007 | - <property name="text"> |
2008 | - <string/> |
2009 | - </property> |
2010 | - </widget> |
2011 | - </item> |
2012 | - <item> |
2013 | - <widget class="QLineEdit" name="name_edit"> |
2014 | - <property name="placeholderText"> |
2015 | - <string/> |
2016 | - </property> |
2017 | - </widget> |
2018 | - </item> |
2019 | - <item> |
2020 | - <widget class="QLabel" name="email_label"> |
2021 | - <property name="text"> |
2022 | - <string/> |
2023 | - </property> |
2024 | - </widget> |
2025 | - </item> |
2026 | - <item> |
2027 | - <widget class="QLineEdit" name="email_edit"> |
2028 | - <property name="placeholderText"> |
2029 | - <string/> |
2030 | - </property> |
2031 | - </widget> |
2032 | - </item> |
2033 | - <item> |
2034 | - <widget class="QLabel" name="confirm_email_label"> |
2035 | - <property name="text"> |
2036 | - <string/> |
2037 | - </property> |
2038 | - </widget> |
2039 | - </item> |
2040 | - <item> |
2041 | - <widget class="QLineEdit" name="confirm_email_edit"> |
2042 | - <property name="placeholderText"> |
2043 | - <string/> |
2044 | - </property> |
2045 | - </widget> |
2046 | - </item> |
2047 | - <item> |
2048 | - <widget class="QLabel" name="password_label"> |
2049 | - <property name="text"> |
2050 | - <string/> |
2051 | - </property> |
2052 | - </widget> |
2053 | - </item> |
2054 | - <item> |
2055 | - <widget class="QLineEdit" name="password_edit"> |
2056 | - <property name="toolTip"> |
2057 | - <string>Your password must be at least 8 characters long and at least contain one number and one upper later.</string> |
2058 | - </property> |
2059 | - <property name="statusTip"> |
2060 | - <string/> |
2061 | - </property> |
2062 | - <property name="echoMode"> |
2063 | - <enum>QLineEdit::Password</enum> |
2064 | - </property> |
2065 | - <property name="placeholderText"> |
2066 | - <string/> |
2067 | - </property> |
2068 | - </widget> |
2069 | - </item> |
2070 | - <item> |
2071 | - <widget class="QLabel" name="confirm_password_label"> |
2072 | - <property name="text"> |
2073 | - <string/> |
2074 | - </property> |
2075 | - </widget> |
2076 | - </item> |
2077 | - <item> |
2078 | - <widget class="QLineEdit" name="confirm_password_edit"> |
2079 | - <property name="echoMode"> |
2080 | - <enum>QLineEdit::Password</enum> |
2081 | - </property> |
2082 | - <property name="placeholderText"> |
2083 | - <string/> |
2084 | - </property> |
2085 | - </widget> |
2086 | - </item> |
2087 | - </layout> |
2088 | - </item> |
2089 | - <item> |
2090 | - <layout class="QVBoxLayout" name="verticalLayout_9"> |
2091 | - <item> |
2092 | - <widget class="QFrame" name="frame_2"> |
2093 | - <property name="sizePolicy"> |
2094 | - <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> |
2095 | - <horstretch>0</horstretch> |
2096 | - <verstretch>0</verstretch> |
2097 | - </sizepolicy> |
2098 | - </property> |
2099 | - <property name="frameShape"> |
2100 | - <enum>QFrame::StyledPanel</enum> |
2101 | - </property> |
2102 | - <property name="frameShadow"> |
2103 | - <enum>QFrame::Raised</enum> |
2104 | - </property> |
2105 | - <layout class="QHBoxLayout" name="horizontalLayout_16"> |
2106 | - <property name="leftMargin"> |
2107 | - <number>0</number> |
2108 | - </property> |
2109 | - <item> |
2110 | - <widget class="QLabel" name="captcha_view"> |
2111 | - <property name="minimumSize"> |
2112 | - <size> |
2113 | - <width>0</width> |
2114 | - <height>57</height> |
2115 | - </size> |
2116 | - </property> |
2117 | - <property name="frameShape"> |
2118 | - <enum>QFrame::Box</enum> |
2119 | - </property> |
2120 | - <property name="text"> |
2121 | - <string/> |
2122 | - </property> |
2123 | - </widget> |
2124 | - </item> |
2125 | - <item> |
2126 | - <widget class="QLabel" name="refresh_label"> |
2127 | - <property name="sizePolicy"> |
2128 | - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
2129 | - <horstretch>0</horstretch> |
2130 | - <verstretch>0</verstretch> |
2131 | - </sizepolicy> |
2132 | - </property> |
2133 | - <property name="locale"> |
2134 | - <locale language="English" country="UnitedStates"/> |
2135 | - </property> |
2136 | - <property name="text"> |
2137 | - <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> |
2138 | -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> |
2139 | -p, li { white-space: pre-wrap; } |
2140 | -</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> |
2141 | -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">If you can't read this then </span><a href="example.com"><span style=" text-decoration: underline; color:#0000ff;">refresh</span></a><span style=" font-size:8pt;"> this page</span></p></body></html></string> |
2142 | - </property> |
2143 | - <property name="wordWrap"> |
2144 | - <bool>true</bool> |
2145 | - </property> |
2146 | - </widget> |
2147 | - </item> |
2148 | - </layout> |
2149 | - </widget> |
2150 | - </item> |
2151 | - <item> |
2152 | - <widget class="QLineEdit" name="captcha_solution_edit"> |
2153 | - <property name="locale"> |
2154 | - <locale language="English" country="UnitedStates"/> |
2155 | - </property> |
2156 | - <property name="inputMask"> |
2157 | - <string/> |
2158 | - </property> |
2159 | - <property name="text"> |
2160 | - <string/> |
2161 | - </property> |
2162 | - <property name="placeholderText"> |
2163 | - <string/> |
2164 | - </property> |
2165 | - </widget> |
2166 | - </item> |
2167 | - </layout> |
2168 | - </item> |
2169 | - <item> |
2170 | - <widget class="QCheckBox" name="terms_checkbox"> |
2171 | - <property name="text"> |
2172 | - <string/> |
2173 | - </property> |
2174 | - </widget> |
2175 | - </item> |
2176 | - <item> |
2177 | - <layout class="QHBoxLayout" name="horizontalLayout_4"> |
2178 | - <property name="spacing"> |
2179 | - <number>0</number> |
2180 | - </property> |
2181 | - <item> |
2182 | - <widget class="QPushButton" name="terms_button"> |
2183 | - <property name="text"> |
2184 | - <string/> |
2185 | - </property> |
2186 | - </widget> |
2187 | - </item> |
2188 | - <item> |
2189 | - <spacer name="horizontalSpacer_3"> |
2190 | - <property name="orientation"> |
2191 | - <enum>Qt::Horizontal</enum> |
2192 | - </property> |
2193 | - <property name="sizeHint" stdset="0"> |
2194 | - <size> |
2195 | - <width>40</width> |
2196 | - <height>20</height> |
2197 | - </size> |
2198 | - </property> |
2199 | - </spacer> |
2200 | - </item> |
2201 | - <item> |
2202 | - <widget class="QPushButton" name="set_up_button"> |
2203 | - <property name="enabled"> |
2204 | - <bool>false</bool> |
2205 | - </property> |
2206 | - <property name="text"> |
2207 | - <string/> |
2208 | - </property> |
2209 | - </widget> |
2210 | - </item> |
2211 | - </layout> |
2212 | - </item> |
2213 | - </layout> |
2214 | - </item> |
2215 | - </layout> |
2216 | - </widget> |
2217 | - </item> |
2218 | - <item> |
2219 | + <layout class="QGridLayout" name="gridLayout" columnminimumwidth="310,220"> |
2220 | + <item row="0" column="0"> |
2221 | + <widget class="QLabel" name="password_info_label"> |
2222 | + <property name="sizePolicy"> |
2223 | + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> |
2224 | + <horstretch>0</horstretch> |
2225 | + <verstretch>0</verstretch> |
2226 | + </sizepolicy> |
2227 | + </property> |
2228 | + <property name="text"> |
2229 | + <string>If you can't read this then <a href="example.com"><span style=" text-decoration: underline; color:#dd4814;">refresh</span></a> this page</span></string> |
2230 | + </property> |
2231 | + <property name="wordWrap"> |
2232 | + <bool>true</bool> |
2233 | + </property> |
2234 | + </widget> |
2235 | + </item> |
2236 | + <item row="1" column="0"> |
2237 | + <layout class="QVBoxLayout" name="verticalLayout"> |
2238 | + <property name="spacing"> |
2239 | + <number>3</number> |
2240 | + </property> |
2241 | + <item> |
2242 | + <widget class="QLabel" name="name_label"> |
2243 | + <property name="font"> |
2244 | + <font> |
2245 | + <weight>75</weight> |
2246 | + <bold>true</bold> |
2247 | + </font> |
2248 | + </property> |
2249 | + <property name="text"> |
2250 | + <string>name_label</string> |
2251 | + </property> |
2252 | + </widget> |
2253 | + </item> |
2254 | + <item> |
2255 | + <widget class="QLineEdit" name="name_edit"> |
2256 | + <property name="sizePolicy"> |
2257 | + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
2258 | + <horstretch>0</horstretch> |
2259 | + <verstretch>0</verstretch> |
2260 | + </sizepolicy> |
2261 | + </property> |
2262 | + <property name="minimumSize"> |
2263 | + <size> |
2264 | + <width>300</width> |
2265 | + <height>0</height> |
2266 | + </size> |
2267 | + </property> |
2268 | + <property name="maximumSize"> |
2269 | + <size> |
2270 | + <width>300</width> |
2271 | + <height>16777215</height> |
2272 | + </size> |
2273 | + </property> |
2274 | + <property name="font"> |
2275 | + <font> |
2276 | + <pointsize>11</pointsize> |
2277 | + </font> |
2278 | + </property> |
2279 | + <property name="formError" stdset="0"> |
2280 | + <bool>false</bool> |
2281 | + </property> |
2282 | + </widget> |
2283 | + </item> |
2284 | + </layout> |
2285 | + </item> |
2286 | + <item row="3" column="0"> |
2287 | + <layout class="QVBoxLayout" name="verticalLayout"> |
2288 | + <property name="spacing"> |
2289 | + <number>3</number> |
2290 | + </property> |
2291 | + <item> |
2292 | + <widget class="QLabel" name="email_label"> |
2293 | + <property name="font"> |
2294 | + <font> |
2295 | + <weight>75</weight> |
2296 | + <bold>true</bold> |
2297 | + </font> |
2298 | + </property> |
2299 | + <property name="text"> |
2300 | + <string>email_label</string> |
2301 | + </property> |
2302 | + </widget> |
2303 | + </item> |
2304 | + <item> |
2305 | + <widget class="QLineEdit" name="email_edit"> |
2306 | + <property name="sizePolicy"> |
2307 | + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
2308 | + <horstretch>0</horstretch> |
2309 | + <verstretch>0</verstretch> |
2310 | + </sizepolicy> |
2311 | + </property> |
2312 | + <property name="minimumSize"> |
2313 | + <size> |
2314 | + <width>300</width> |
2315 | + <height>0</height> |
2316 | + </size> |
2317 | + </property> |
2318 | + <property name="maximumSize"> |
2319 | + <size> |
2320 | + <width>300</width> |
2321 | + <height>16777215</height> |
2322 | + </size> |
2323 | + </property> |
2324 | + <property name="font"> |
2325 | + <font> |
2326 | + <pointsize>11</pointsize> |
2327 | + </font> |
2328 | + </property> |
2329 | + <property name="placeholderText"> |
2330 | + <string/> |
2331 | + </property> |
2332 | + <property name="formError" stdset="0"> |
2333 | + <bool>false</bool> |
2334 | + </property> |
2335 | + </widget> |
2336 | + </item> |
2337 | + </layout> |
2338 | + </item> |
2339 | + <item row="4" column="0"> |
2340 | + <layout class="QVBoxLayout" name="verticalLayout"> |
2341 | + <property name="spacing"> |
2342 | + <number>3</number> |
2343 | + </property> |
2344 | + <item> |
2345 | + <widget class="QLabel" name="confirm_email_label"> |
2346 | + <property name="font"> |
2347 | + <font> |
2348 | + <weight>75</weight> |
2349 | + <bold>true</bold> |
2350 | + </font> |
2351 | + </property> |
2352 | + <property name="text"> |
2353 | + <string>confirm_email_label</string> |
2354 | + </property> |
2355 | + </widget> |
2356 | + </item> |
2357 | + <item> |
2358 | + <widget class="QLineEdit" name="confirm_email_edit"> |
2359 | + <property name="sizePolicy"> |
2360 | + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
2361 | + <horstretch>0</horstretch> |
2362 | + <verstretch>0</verstretch> |
2363 | + </sizepolicy> |
2364 | + </property> |
2365 | + <property name="minimumSize"> |
2366 | + <size> |
2367 | + <width>300</width> |
2368 | + <height>0</height> |
2369 | + </size> |
2370 | + </property> |
2371 | + <property name="maximumSize"> |
2372 | + <size> |
2373 | + <width>300</width> |
2374 | + <height>16777215</height> |
2375 | + </size> |
2376 | + </property> |
2377 | + <property name="font"> |
2378 | + <font> |
2379 | + <pointsize>11</pointsize> |
2380 | + </font> |
2381 | + </property> |
2382 | + <property name="placeholderText"> |
2383 | + <string/> |
2384 | + </property> |
2385 | + <property name="formError" stdset="0"> |
2386 | + <bool>false</bool> |
2387 | + </property> |
2388 | + </widget> |
2389 | + </item> |
2390 | + </layout> |
2391 | + </item> |
2392 | + <item row="6" column="0"> |
2393 | + <layout class="QVBoxLayout" name="verticalLayout"> |
2394 | + <property name="spacing"> |
2395 | + <number>3</number> |
2396 | + </property> |
2397 | + <item> |
2398 | + <widget class="QLabel" name="password_label"> |
2399 | + <property name="font"> |
2400 | + <font> |
2401 | + <weight>75</weight> |
2402 | + <bold>true</bold> |
2403 | + </font> |
2404 | + </property> |
2405 | + <property name="text"> |
2406 | + <string>password_label</string> |
2407 | + </property> |
2408 | + </widget> |
2409 | + </item> |
2410 | + <item> |
2411 | + <widget class="QLineEdit" name="password_edit"> |
2412 | + <property name="sizePolicy"> |
2413 | + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
2414 | + <horstretch>0</horstretch> |
2415 | + <verstretch>0</verstretch> |
2416 | + </sizepolicy> |
2417 | + </property> |
2418 | + <property name="minimumSize"> |
2419 | + <size> |
2420 | + <width>300</width> |
2421 | + <height>0</height> |
2422 | + </size> |
2423 | + </property> |
2424 | + <property name="maximumSize"> |
2425 | + <size> |
2426 | + <width>300</width> |
2427 | + <height>16777215</height> |
2428 | + </size> |
2429 | + </property> |
2430 | + <property name="font"> |
2431 | + <font> |
2432 | + <pointsize>11</pointsize> |
2433 | + </font> |
2434 | + </property> |
2435 | + <property name="toolTip"> |
2436 | + <string>Your password must be at least 8 characters long and at least contain one number and one upper later.</string> |
2437 | + </property> |
2438 | + <property name="statusTip"> |
2439 | + <string/> |
2440 | + </property> |
2441 | + <property name="echoMode"> |
2442 | + <enum>QLineEdit::Password</enum> |
2443 | + </property> |
2444 | + <property name="placeholderText"> |
2445 | + <string/> |
2446 | + </property> |
2447 | + <property name="formError" stdset="0"> |
2448 | + <bool>false</bool> |
2449 | + </property> |
2450 | + </widget> |
2451 | + </item> |
2452 | + </layout> |
2453 | + </item> |
2454 | + <item row="7" column="0"> |
2455 | + <layout class="QVBoxLayout" name="verticalLayout"> |
2456 | + <property name="spacing"> |
2457 | + <number>3</number> |
2458 | + </property> |
2459 | + <item> |
2460 | + <widget class="QLabel" name="confirm_password_label"> |
2461 | + <property name="font"> |
2462 | + <font> |
2463 | + <weight>75</weight> |
2464 | + <bold>true</bold> |
2465 | + </font> |
2466 | + </property> |
2467 | + <property name="text"> |
2468 | + <string>confirm_password_label</string> |
2469 | + </property> |
2470 | + </widget> |
2471 | + </item> |
2472 | + <item> |
2473 | + <widget class="QLineEdit" name="confirm_password_edit"> |
2474 | + <property name="sizePolicy"> |
2475 | + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
2476 | + <horstretch>0</horstretch> |
2477 | + <verstretch>0</verstretch> |
2478 | + </sizepolicy> |
2479 | + </property> |
2480 | + <property name="minimumSize"> |
2481 | + <size> |
2482 | + <width>300</width> |
2483 | + <height>0</height> |
2484 | + </size> |
2485 | + </property> |
2486 | + <property name="maximumSize"> |
2487 | + <size> |
2488 | + <width>300</width> |
2489 | + <height>16777215</height> |
2490 | + </size> |
2491 | + </property> |
2492 | + <property name="font"> |
2493 | + <font> |
2494 | + <pointsize>11</pointsize> |
2495 | + </font> |
2496 | + </property> |
2497 | + <property name="echoMode"> |
2498 | + <enum>QLineEdit::Password</enum> |
2499 | + </property> |
2500 | + <property name="placeholderText"> |
2501 | + <string/> |
2502 | + </property> |
2503 | + <property name="formError" stdset="0"> |
2504 | + <bool>false</bool> |
2505 | + </property> |
2506 | + </widget> |
2507 | + </item> |
2508 | + </layout> |
2509 | + </item> |
2510 | + <item row="9" column="0"> |
2511 | + <layout class="QVBoxLayout" name="verticalLayout"> |
2512 | + <property name="spacing"> |
2513 | + <number>3</number> |
2514 | + </property> |
2515 | + <item> |
2516 | + <widget class="QLabel" name="captcha_view"> |
2517 | + <property name="sizePolicy"> |
2518 | + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
2519 | + <horstretch>0</horstretch> |
2520 | + <verstretch>0</verstretch> |
2521 | + </sizepolicy> |
2522 | + </property> |
2523 | + <property name="minimumSize"> |
2524 | + <size> |
2525 | + <width>300</width> |
2526 | + <height>57</height> |
2527 | + </size> |
2528 | + </property> |
2529 | + <property name="maximumSize"> |
2530 | + <size> |
2531 | + <width>300</width> |
2532 | + <height>16777215</height> |
2533 | + </size> |
2534 | + </property> |
2535 | + <property name="styleSheet"> |
2536 | + <string notr="true">background-color: white</string> |
2537 | + </property> |
2538 | + <property name="frameShape"> |
2539 | + <enum>QFrame::Box</enum> |
2540 | + </property> |
2541 | + <property name="text"> |
2542 | + <string>If you can't read this then <a href="example.com"><span style=" text-decoration: underline; color:#dd4814;">refresh</span></a> this page</span></string> |
2543 | + </property> |
2544 | + </widget> |
2545 | + </item> |
2546 | + <item> |
2547 | + <widget class="QLineEdit" name="captcha_solution_edit"> |
2548 | + <property name="sizePolicy"> |
2549 | + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> |
2550 | + <horstretch>0</horstretch> |
2551 | + <verstretch>0</verstretch> |
2552 | + </sizepolicy> |
2553 | + </property> |
2554 | + <property name="minimumSize"> |
2555 | + <size> |
2556 | + <width>300</width> |
2557 | + <height>0</height> |
2558 | + </size> |
2559 | + </property> |
2560 | + <property name="maximumSize"> |
2561 | + <size> |
2562 | + <width>300</width> |
2563 | + <height>16777215</height> |
2564 | + </size> |
2565 | + </property> |
2566 | + <property name="font"> |
2567 | + <font> |
2568 | + <pointsize>11</pointsize> |
2569 | + </font> |
2570 | + </property> |
2571 | + <property name="locale"> |
2572 | + <locale language="English" country="UnitedStates"/> |
2573 | + </property> |
2574 | + <property name="inputMask"> |
2575 | + <string/> |
2576 | + </property> |
2577 | + <property name="text"> |
2578 | + <string/> |
2579 | + </property> |
2580 | + <property name="placeholderText"> |
2581 | + <string/> |
2582 | + </property> |
2583 | + <property name="formError" stdset="0"> |
2584 | + <bool>false</bool> |
2585 | + </property> |
2586 | + </widget> |
2587 | + </item> |
2588 | + </layout> |
2589 | + </item> |
2590 | + <item row="9" column="1"> |
2591 | + <widget class="QLabel" name="refresh_label"> |
2592 | + <property name="sizePolicy"> |
2593 | + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> |
2594 | + <horstretch>0</horstretch> |
2595 | + <verstretch>0</verstretch> |
2596 | + </sizepolicy> |
2597 | + </property> |
2598 | + <property name="minimumSize"> |
2599 | + <size> |
2600 | + <width>220</width> |
2601 | + <height>0</height> |
2602 | + </size> |
2603 | + </property> |
2604 | + <property name="maximumSize"> |
2605 | + <size> |
2606 | + <width>220</width> |
2607 | + <height>16777215</height> |
2608 | + </size> |
2609 | + </property> |
2610 | + <property name="locale"> |
2611 | + <locale language="English" country="UnitedStates"/> |
2612 | + </property> |
2613 | + <property name="text"> |
2614 | + <string>If you can't read this then <a href="example.com"><span style=" text-decoration: underline; color:#dd4814;">refresh</span></a> this page</span></string> |
2615 | + </property> |
2616 | + <property name="wordWrap"> |
2617 | + <bool>true</bool> |
2618 | + </property> |
2619 | + <property name="indent"> |
2620 | + <number>0</number> |
2621 | + </property> |
2622 | + </widget> |
2623 | + </item> |
2624 | + <item row="1" column="1"> |
2625 | + <layout class="QVBoxLayout" name="verticalLayout_7"> |
2626 | + <property name="spacing"> |
2627 | + <number>0</number> |
2628 | + </property> |
2629 | + <property name="leftMargin"> |
2630 | + <number>0</number> |
2631 | + </property> |
2632 | + <item> |
2633 | + <widget class="QLabel" name="name_assistance"> |
2634 | + <property name="sizePolicy"> |
2635 | + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> |
2636 | + <horstretch>0</horstretch> |
2637 | + <verstretch>0</verstretch> |
2638 | + </sizepolicy> |
2639 | + </property> |
2640 | + <property name="minimumSize"> |
2641 | + <size> |
2642 | + <width>220</width> |
2643 | + <height>0</height> |
2644 | + </size> |
2645 | + </property> |
2646 | + <property name="maximumSize"> |
2647 | + <size> |
2648 | + <width>220</width> |
2649 | + <height>16777215</height> |
2650 | + </size> |
2651 | + </property> |
2652 | + <property name="text"> |
2653 | + <string>name_assistance</string> |
2654 | + </property> |
2655 | + <property name="alignment"> |
2656 | + <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
2657 | + </property> |
2658 | + <property name="wordWrap"> |
2659 | + <bool>true</bool> |
2660 | + </property> |
2661 | + </widget> |
2662 | + </item> |
2663 | + </layout> |
2664 | + </item> |
2665 | + <item row="3" column="1"> |
2666 | + <layout class="QVBoxLayout" name="verticalLayout_8"> |
2667 | + <property name="spacing"> |
2668 | + <number>0</number> |
2669 | + </property> |
2670 | + <property name="leftMargin"> |
2671 | + <number>0</number> |
2672 | + </property> |
2673 | + <item> |
2674 | + <widget class="QLabel" name="email_assistance"> |
2675 | + <property name="sizePolicy"> |
2676 | + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> |
2677 | + <horstretch>0</horstretch> |
2678 | + <verstretch>0</verstretch> |
2679 | + </sizepolicy> |
2680 | + </property> |
2681 | + <property name="minimumSize"> |
2682 | + <size> |
2683 | + <width>220</width> |
2684 | + <height>0</height> |
2685 | + </size> |
2686 | + </property> |
2687 | + <property name="maximumSize"> |
2688 | + <size> |
2689 | + <width>220</width> |
2690 | + <height>16777215</height> |
2691 | + </size> |
2692 | + </property> |
2693 | + <property name="text"> |
2694 | + <string>email_assistance</string> |
2695 | + </property> |
2696 | + <property name="alignment"> |
2697 | + <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
2698 | + </property> |
2699 | + <property name="wordWrap"> |
2700 | + <bool>true</bool> |
2701 | + </property> |
2702 | + </widget> |
2703 | + </item> |
2704 | + </layout> |
2705 | + </item> |
2706 | + <item row="4" column="1"> |
2707 | + <layout class="QVBoxLayout" name="verticalLayout_9"> |
2708 | + <property name="spacing"> |
2709 | + <number>0</number> |
2710 | + </property> |
2711 | + <property name="leftMargin"> |
2712 | + <number>0</number> |
2713 | + </property> |
2714 | + <item> |
2715 | + <widget class="QLabel" name="confirm_email_assistance"> |
2716 | + <property name="sizePolicy"> |
2717 | + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> |
2718 | + <horstretch>0</horstretch> |
2719 | + <verstretch>0</verstretch> |
2720 | + </sizepolicy> |
2721 | + </property> |
2722 | + <property name="minimumSize"> |
2723 | + <size> |
2724 | + <width>220</width> |
2725 | + <height>0</height> |
2726 | + </size> |
2727 | + </property> |
2728 | + <property name="maximumSize"> |
2729 | + <size> |
2730 | + <width>220</width> |
2731 | + <height>16777215</height> |
2732 | + </size> |
2733 | + </property> |
2734 | + <property name="text"> |
2735 | + <string>confirm_email_assistance</string> |
2736 | + </property> |
2737 | + <property name="alignment"> |
2738 | + <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> |
2739 | + </property> |
2740 | + <property name="wordWrap"> |
2741 | + <bool>true</bool> |
2742 | + </property> |
2743 | + <property name="indent"> |
2744 | + <number>0</number> |
2745 | + </property> |
2746 | + </widget> |
2747 | + </item> |
2748 | + </layout> |
2749 | + </item> |
2750 | + <item row="6" column="1" rowspan="2"> |
2751 | + <widget class="QLabel" name="password_assistance"> |
2752 | + <property name="sizePolicy"> |
2753 | + <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> |
2754 | + <horstretch>0</horstretch> |
2755 | + <verstretch>0</verstretch> |
2756 | + </sizepolicy> |
2757 | + </property> |
2758 | + <property name="minimumSize"> |
2759 | + <size> |
2760 | + <width>220</width> |
2761 | + <height>0</height> |
2762 | + </size> |
2763 | + </property> |
2764 | + <property name="maximumSize"> |
2765 | + <size> |
2766 | + <width>220</width> |
2767 | + <height>16777215</height> |
2768 | + </size> |
2769 | + </property> |
2770 | + <property name="text"> |
2771 | + <string>password_assistance</string> |
2772 | + </property> |
2773 | + <property name="wordWrap"> |
2774 | + <bool>true</bool> |
2775 | + </property> |
2776 | + <property name="indent"> |
2777 | + <number>17</number> |
2778 | + </property> |
2779 | + </widget> |
2780 | + </item> |
2781 | + <item row="2" column="1"> |
2782 | + <spacer name="verticalSpacer"> |
2783 | + <property name="orientation"> |
2784 | + <enum>Qt::Vertical</enum> |
2785 | + </property> |
2786 | + <property name="sizeType"> |
2787 | + <enum>QSizePolicy::Fixed</enum> |
2788 | + </property> |
2789 | + <property name="sizeHint" stdset="0"> |
2790 | + <size> |
2791 | + <width>20</width> |
2792 | + <height>15</height> |
2793 | + </size> |
2794 | + </property> |
2795 | + </spacer> |
2796 | + </item> |
2797 | + <item row="5" column="1"> |
2798 | <spacer name="verticalSpacer_2"> |
2799 | <property name="orientation"> |
2800 | <enum>Qt::Vertical</enum> |
2801 | </property> |
2802 | - <property name="sizeHint" stdset="0"> |
2803 | - <size> |
2804 | - <width>20</width> |
2805 | - <height>40</height> |
2806 | - </size> |
2807 | - </property> |
2808 | - </spacer> |
2809 | - </item> |
2810 | + <property name="sizeType"> |
2811 | + <enum>QSizePolicy::Fixed</enum> |
2812 | + </property> |
2813 | + <property name="sizeHint" stdset="0"> |
2814 | + <size> |
2815 | + <width>20</width> |
2816 | + <height>15</height> |
2817 | + </size> |
2818 | + </property> |
2819 | + </spacer> |
2820 | + </item> |
2821 | + <item row="8" column="1"> |
2822 | + <spacer name="verticalSpacer_3"> |
2823 | + <property name="orientation"> |
2824 | + <enum>Qt::Vertical</enum> |
2825 | + </property> |
2826 | + <property name="sizeType"> |
2827 | + <enum>QSizePolicy::Fixed</enum> |
2828 | + </property> |
2829 | + <property name="sizeHint" stdset="0"> |
2830 | + <size> |
2831 | + <width>20</width> |
2832 | + <height>15</height> |
2833 | + </size> |
2834 | + </property> |
2835 | + </spacer> |
2836 | + </item> |
2837 | + </layout> |
2838 | + </item> |
2839 | + <item> |
2840 | + <layout class="QHBoxLayout" name="hlayout_check"> |
2841 | + <property name="spacing"> |
2842 | + <number>0</number> |
2843 | + </property> |
2844 | </layout> |
2845 | </item> |
2846 | </layout> |
2847 | </widget> |
2848 | - <resources/> |
2849 | <connections/> |
2850 | </ui> |
2851 | |
2852 | === modified file 'run-tests' |
2853 | --- run-tests 2011-12-09 14:07:38 +0000 |
2854 | +++ run-tests 2012-02-14 22:04:20 +0000 |
2855 | @@ -18,16 +18,10 @@ |
2856 | |
2857 | QT_TESTS_PATH=ubuntu_sso/qt/tests |
2858 | GTK_TESTS_PATH=ubuntu_sso/gtk/tests |
2859 | +WINDOWS_TESTS=test_windows.py |
2860 | |
2861 | set -e |
2862 | |
2863 | -if [ "$1" == "-qt" ]; then |
2864 | - USE_QT=1 |
2865 | - shift |
2866 | -else |
2867 | - USE_QT=0 |
2868 | -fi |
2869 | - |
2870 | if [ $# -ne 0 ]; then |
2871 | # run specific module given by the caller |
2872 | MODULE="$@" |
2873 | @@ -37,24 +31,34 @@ |
2874 | fi |
2875 | |
2876 | style_check() { |
2877 | - ./setup.py clean |
2878 | - u1lint |
2879 | + u1lint --ignore ubuntu_sso/qt/ui |
2880 | if [ -x `which pep8` ]; then |
2881 | - pep8 --repeat . |
2882 | + pep8 --exclude '.svn,CVS,.bzr,.hg,.git,*_ui.py,*_rc.py' --repeat . bin/* |
2883 | else |
2884 | echo "Please install the 'pep8' package." |
2885 | fi |
2886 | } |
2887 | - |
2888 | unset GTK_MODULES |
2889 | |
2890 | -echo "Running test suite for ""$MODULE" |
2891 | -if [ "$USE_QT" -eq 0 ]; then |
2892 | - `which xvfb-run` u1trial -p "$QT_TESTS_PATH" -i "test_windows.py" "$MODULE" |
2893 | -else |
2894 | - ./setup.py build |
2895 | - `which xvfb-run` u1trial -p "$GTK_TESTS_PATH" -i "test_windows.py" --reactor=qt4 --gui "$MODULE" |
2896 | +XVFB_CMDLINE="" |
2897 | +XVFB=$(which xvfb-run) |
2898 | +if [ $XVFB ]; then |
2899 | + XVFB_CMDLINE="$XVFB -a" |
2900 | fi |
2901 | + |
2902 | +echo "*** Running GTK test suite for ""$MODULE"" ***" |
2903 | +$XVFB_CMDLINE u1trial --reactor=gi --gui -p "$QT_TESTS_PATH" -i "test_windows.py" "$MODULE" |
2904 | +rm -rf _trial_temp |
2905 | + |
2906 | +# hack to avoid: |
2907 | +# g_dbus_connection_real_closed: Remote peer vanished with error: Underlying |
2908 | +# GIOStream returned 0 bytes on an async read (g-io-error-quark, 0). Exiting. |
2909 | +sleep 3 |
2910 | + |
2911 | +echo "*** Running QT test suite for ""$MODULE"" ***" |
2912 | +./setup.py build |
2913 | +USE_QT_MAINLOOP=True $XVFB_CMDLINE u1trial --reactor=qt4 --gui -p "$GTK_TESTS_PATH" -i "test_windows.py" "$MODULE" |
2914 | +rm -rf _trial_temp |
2915 | +rm -rf build |
2916 | + |
2917 | style_check |
2918 | -rm -rf _trial_temp |
2919 | -rm -rf build |
2920 | |
2921 | === modified file 'setup.py' |
2922 | --- setup.py 2012-02-02 13:37:55 +0000 |
2923 | +++ setup.py 2012-02-14 22:04:20 +0000 |
2924 | @@ -1,11 +1,7 @@ |
2925 | #!/usr/bin/env python |
2926 | # setup.py - Build system for Ubuntu SSO Client package |
2927 | # |
2928 | -# Authors: Natalia B. Bidart <natalia.bidart@canonical.com> |
2929 | -# Manuel de la Pena <manuel@canonical.com> |
2930 | -# Alejandro J. Cura <alecu@canonical.com> |
2931 | -# |
2932 | -# Copyright 2010-2011 Canonical Ltd. |
2933 | +# Copyright 2010-2012 Canonical Ltd. |
2934 | # |
2935 | # This program is free software: you can redistribute it and/or modify it |
2936 | # under the terms of the GNU General Public License version 3, as published |
2937 | @@ -40,15 +36,16 @@ |
2938 | |
2939 | POT_FILE = 'po/ubuntu-sso-client.pot' |
2940 | SERVICE_FILE = 'data/com.ubuntu.sso.service' |
2941 | +CONSTANTS = 'ubuntu_sso/constants.py' |
2942 | |
2943 | -CLEANFILES = [SERVICE_FILE, POT_FILE, 'MANIFEST'] |
2944 | -QT_UI_DIR = os.path.join('ubuntu_sso', 'qt') |
2945 | +CLEANFILES = [SERVICE_FILE, POT_FILE, CONSTANTS, 'MANIFEST'] |
2946 | +QT_UI_DIR = os.path.join('ubuntu_sso', 'qt', 'ui') |
2947 | |
2948 | |
2949 | def replace_prefix(prefix): |
2950 | """Replace every '@prefix@' with prefix within 'filename' content.""" |
2951 | - # replace .service file |
2952 | - for filename in (SERVICE_FILE,): |
2953 | + # replace .service file, DATA_DIR constant |
2954 | + for filename in (SERVICE_FILE, CONSTANTS): |
2955 | with open(filename + '.in') as in_file: |
2956 | content = in_file.read() |
2957 | with open(filename, 'w') as out_file: |
2958 | @@ -112,7 +109,8 @@ |
2959 | path = os.getenv('PATH') |
2960 | os.putenv('PATH', path + os.path.pathsep + os.path.join( |
2961 | os.path.dirname(PyQt4.__file__), 'bin')) |
2962 | - if os.system('pyrcc4 "%s" -o "%s"' % (qrc_file, py_file)) > 0: |
2963 | + if os.system('pyrcc4 -no-compress "%s" -o "%s"' % |
2964 | + (qrc_file, py_file)) > 0: |
2965 | self.warn('Unable to generate python module {py_file}' |
2966 | ' for resource file {qrc_file}'.format( |
2967 | py_file=py_file, qrc_file=qrc_file)) |
2968 | @@ -313,6 +311,14 @@ |
2969 | } |
2970 | |
2971 | |
2972 | +sso_executables = [ |
2973 | + 'bin/ubuntu-sso-login', |
2974 | + 'bin/ubuntu-sso-login-gtk', |
2975 | + 'bin/ubuntu-sso-login-qt', |
2976 | + 'bin/ubuntu-sso-proxy-creds-qt', |
2977 | +] |
2978 | + |
2979 | + |
2980 | class dummy_build_i18n(distutils.cmd.Command): |
2981 | |
2982 | """Dummy for windows.""" |
2983 | @@ -326,6 +332,7 @@ |
2984 | def run(self, *args): |
2985 | """Dummy.""" |
2986 | |
2987 | + |
2988 | if sys.platform == 'win32': |
2989 | cmdclass['build_i18n'] = dummy_build_i18n |
2990 | |
2991 | @@ -349,7 +356,7 @@ |
2992 | }, |
2993 | }, |
2994 | # add the console script so that py2exe compiles it |
2995 | - 'console': ['bin/ubuntu-sso-login'], |
2996 | + 'console': sso_executables, |
2997 | 'zipfile': None, |
2998 | } |
2999 | return _data_files, _extra |
3000 | @@ -358,10 +365,8 @@ |
3001 | data_files, extra = setup_windows() |
3002 | else: |
3003 | data_files = [ |
3004 | - ('lib/ubuntu-sso-client', ['bin/ubuntu-sso-login']), |
3005 | - ('lib/ubuntu-sso-client', ['bin/ubuntu-sso-login-gtk']), |
3006 | + ('lib/ubuntu-sso-client', sso_executables), |
3007 | ('share/dbus-1/services', ['data/com.ubuntu.sso.service']), |
3008 | - ('share/ubuntu-sso-client/data/gtk', ['data/gtk/ui.glade']), |
3009 | ] |
3010 | extra = {} |
3011 | |
3012 | @@ -379,14 +384,24 @@ |
3013 | data_files=data_files, |
3014 | packages=[ |
3015 | 'ubuntu_sso', |
3016 | + 'ubuntu_sso.tests', |
3017 | 'ubuntu_sso.gtk', |
3018 | 'ubuntu_sso.keyring', |
3019 | + 'ubuntu_sso.keyring.tests', |
3020 | 'ubuntu_sso.main', |
3021 | + 'ubuntu_sso.main.tests', |
3022 | 'ubuntu_sso.networkstate', |
3023 | + 'ubuntu_sso.networkstate.tests', |
3024 | 'ubuntu_sso.qt', |
3025 | + 'ubuntu_sso.qt.ui', |
3026 | 'ubuntu_sso.utils', |
3027 | + 'ubuntu_sso.utils.tests', |
3028 | + 'ubuntu_sso.utils.runner', |
3029 | + 'ubuntu_sso.utils.runner.tests', |
3030 | 'ubuntu_sso.utils.webclient', |
3031 | + 'ubuntu_sso.utils.webclient.tests', |
3032 | 'ubuntu_sso.xdg_base_directory', |
3033 | + 'ubuntu_sso.xdg_base_directory.tests', |
3034 | ], |
3035 | cmdclass=cmdclass, |
3036 | **extra) |
3037 | |
3038 | === modified file 'ubuntu_sso/__init__.py' |
3039 | --- ubuntu_sso/__init__.py 2010-10-07 21:09:01 +0000 |
3040 | +++ ubuntu_sso/__init__.py 2012-02-14 22:04:20 +0000 |
3041 | @@ -15,17 +15,21 @@ |
3042 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
3043 | """Ubuntu Single Sign On client code.""" |
3044 | |
3045 | -# constants |
3046 | +# DBus constants |
3047 | DBUS_BUS_NAME = "com.ubuntu.sso" |
3048 | -DBUS_PATH = "/sso" # deprecated! |
3049 | -DBUS_CRED_PATH = "/credentials" # deprecated! |
3050 | + |
3051 | DBUS_ACCOUNT_PATH = "/com/ubuntu/sso/accounts" |
3052 | - |
3053 | -DBUS_IFACE_AUTH_NAME = "com.ubuntu.sso" |
3054 | DBUS_IFACE_USER_NAME = "com.ubuntu.sso.UserManagement" |
3055 | -DBUS_IFACE_CRED_NAME = "com.ubuntu.sso.ApplicationCredentials" |
3056 | |
3057 | DBUS_CREDENTIALS_PATH = "/com/ubuntu/sso/credentials" |
3058 | DBUS_CREDENTIALS_IFACE = "com.ubuntu.sso.CredentialsManagement" |
3059 | |
3060 | NO_OP = lambda *args, **kwargs: None |
3061 | + |
3062 | +# return codes for UIs |
3063 | +USER_SUCCESS = 0 |
3064 | +USER_CANCELLATION = 10 |
3065 | + |
3066 | +# available UIs |
3067 | +UI_EXECUTABLE_GTK = 'ubuntu-sso-login-gtk' |
3068 | +UI_EXECUTABLE_QT = 'ubuntu-sso-login-qt' |
3069 | |
3070 | === modified file 'ubuntu_sso/account.py' |
3071 | --- ubuntu_sso/account.py 2011-12-15 20:52:32 +0000 |
3072 | +++ ubuntu_sso/account.py 2012-02-14 22:04:20 +0000 |
3073 | @@ -16,27 +16,27 @@ |
3074 | # |
3075 | # You should have received a copy of the GNU General Public License along |
3076 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
3077 | -"""Single Sign On account management.""" |
3078 | +"""Single Sign On account management. |
3079 | + |
3080 | +All the methods in Account expect unicode as parameters. |
3081 | + |
3082 | +""" |
3083 | |
3084 | import os |
3085 | import re |
3086 | -import urllib2 |
3087 | |
3088 | -# Unable to import 'lazr.restfulclient.*' |
3089 | -# pylint: disable=F0401 |
3090 | -from lazr.restfulclient.authorize import BasicHttpAuthorizer |
3091 | from lazr.restfulclient.authorize.oauth import OAuthAuthorizer |
3092 | -from lazr.restfulclient.errors import HTTPError |
3093 | -from lazr.restfulclient.resource import ServiceRoot |
3094 | -# pylint: enable=F0401 |
3095 | from oauth import oauth |
3096 | +from twisted.internet import defer |
3097 | |
3098 | from ubuntu_sso.logger import setup_logging |
3099 | -from ubuntu_sso.utils import timestamp_checker |
3100 | +from ubuntu_sso.utils import webclient |
3101 | +from ubuntu_sso.utils.webclient import restful |
3102 | +from ubuntu_sso.utils.webclient.common import WebClientError |
3103 | |
3104 | |
3105 | logger = setup_logging("ubuntu_sso.account") |
3106 | -SERVICE_URL = "https://login.ubuntu.com/api/1.0" |
3107 | +SERVICE_URL = u"https://login.ubuntu.com/api/1.0/" |
3108 | SSO_STATUS_OK = 'ok' |
3109 | SSO_STATUS_ERROR = 'error' |
3110 | |
3111 | @@ -102,8 +102,9 @@ |
3112 | self.service_url = service_url |
3113 | else: |
3114 | self.service_url = os.environ.get('USSOC_SERVICE_URL', SERVICE_URL) |
3115 | - logger.info('Created a new SSO access layer for service url %r', |
3116 | + logger.info('Creating a new SSO access layer for service url %r', |
3117 | self.service_url) |
3118 | + assert self.service_url.endswith("/") |
3119 | |
3120 | def _valid_email(self, email): |
3121 | """Validate the given email.""" |
3122 | @@ -127,46 +128,57 @@ |
3123 | result[key] = "\n".join(val) |
3124 | return result |
3125 | |
3126 | + @defer.inlineCallbacks |
3127 | def generate_captcha(self, filename): |
3128 | """Generate a captcha using the SSO service.""" |
3129 | logger.debug('generate_captcha: requesting captcha, filename: %r', |
3130 | filename) |
3131 | - sso_service = ServiceRoot(None, self.service_url) |
3132 | - captcha = sso_service.captchas.new() |
3133 | + restful_client = restful.RestfulClient(self.service_url) |
3134 | + try: |
3135 | + captcha = yield restful_client.restcall(u"captchas.new") |
3136 | + finally: |
3137 | + restful_client.shutdown() |
3138 | |
3139 | # download captcha and save to 'filename' |
3140 | logger.debug('generate_captcha: server answered: %r', captcha) |
3141 | + wc = webclient.webclient_factory() |
3142 | try: |
3143 | - res = urllib2.urlopen(captcha['image_url']) |
3144 | + response = yield wc.request(captcha['image_url']) |
3145 | with open(filename, 'wb') as f: |
3146 | - f.write(res.read()) |
3147 | + f.write(response.content) |
3148 | except: |
3149 | msg = 'generate_captcha crashed while downloading the image.' |
3150 | logger.exception(msg) |
3151 | raise |
3152 | - |
3153 | - return captcha['captcha_id'] |
3154 | - |
3155 | + finally: |
3156 | + wc.shutdown() |
3157 | + |
3158 | + defer.returnValue(captcha['captcha_id']) |
3159 | + |
3160 | + @defer.inlineCallbacks |
3161 | def register_user(self, email, password, displayname, |
3162 | captcha_id, captcha_solution): |
3163 | """Register a new user with 'email' and 'password'.""" |
3164 | logger.debug('register_user: email: %r password: <hidden>, ' |
3165 | 'displayname: %r, captcha_id: %r, captcha_solution: %r', |
3166 | email, displayname, captcha_id, captcha_solution) |
3167 | - sso_service = ServiceRoot(None, self.service_url) |
3168 | - if not self._valid_email(email): |
3169 | - logger.error('register_user: InvalidEmailError for email: %r', |
3170 | - email) |
3171 | - raise InvalidEmailError() |
3172 | - if not self._valid_password(password): |
3173 | - logger.error('register_user: InvalidPasswordError') |
3174 | - raise InvalidPasswordError() |
3175 | + restful_client = restful.RestfulClient(self.service_url) |
3176 | + try: |
3177 | + if not self._valid_email(email): |
3178 | + logger.error('register_user: InvalidEmailError for email: %r', |
3179 | + email) |
3180 | + raise InvalidEmailError() |
3181 | + if not self._valid_password(password): |
3182 | + logger.error('register_user: InvalidPasswordError') |
3183 | + raise InvalidPasswordError() |
3184 | |
3185 | - result = sso_service.registrations.register( |
3186 | - email=email, password=password, |
3187 | - displayname=displayname, |
3188 | - captcha_id=captcha_id, |
3189 | - captcha_solution=captcha_solution) |
3190 | + result = yield restful_client.restcall(u"registration.register", |
3191 | + email=email, password=password, |
3192 | + displayname=displayname, |
3193 | + captcha_id=captcha_id, |
3194 | + captcha_solution=captcha_solution) |
3195 | + finally: |
3196 | + restful_client.shutdown() |
3197 | logger.info('register_user: email: %r result: %r', email, result) |
3198 | |
3199 | if result['status'].lower() == SSO_STATUS_ERROR: |
3200 | @@ -175,87 +187,91 @@ |
3201 | elif result['status'].lower() != SSO_STATUS_OK: |
3202 | raise RegistrationError('Received unknown status: %s' % result) |
3203 | else: |
3204 | - return email |
3205 | + defer.returnValue(email) |
3206 | |
3207 | + @defer.inlineCallbacks |
3208 | def login(self, email, password, token_name): |
3209 | """Login a user with 'email' and 'password'.""" |
3210 | logger.debug('login: email: %r password: <hidden>, token_name: %r', |
3211 | email, token_name) |
3212 | - basic = BasicHttpAuthorizer(email, password) |
3213 | - sso_service = ServiceRoot(basic, self.service_url) |
3214 | - service = sso_service.authentications.authenticate |
3215 | - |
3216 | + restful_client = restful.RestfulClient(self.service_url, |
3217 | + username=email, |
3218 | + password=password) |
3219 | try: |
3220 | - credentials = service(token_name=token_name) |
3221 | - except HTTPError: |
3222 | + credentials = yield restful_client.restcall( |
3223 | + u"authentications.authenticate", |
3224 | + token_name=token_name) |
3225 | + except WebClientError: |
3226 | logger.exception('login failed with:') |
3227 | raise AuthenticationError() |
3228 | + finally: |
3229 | + restful_client.shutdown() |
3230 | |
3231 | logger.debug('login: authentication successful! consumer_key: %r, ' \ |
3232 | 'token_name: %r', credentials['consumer_key'], token_name) |
3233 | - return credentials |
3234 | + defer.returnValue(credentials) |
3235 | |
3236 | - def is_validated(self, token, sso_service=None): |
3237 | + @defer.inlineCallbacks |
3238 | + def is_validated(self, token): |
3239 | """Return if user with 'email' and 'password' is validated.""" |
3240 | logger.debug('is_validated: requesting accounts.me() info.') |
3241 | - if sso_service is None: |
3242 | - oauth_token = oauth.OAuthToken(token['token'], |
3243 | - token['token_secret']) |
3244 | - authorizer = TimestampedAuthorizer( |
3245 | - timestamp_checker.get_faithful_time, |
3246 | - token['consumer_key'], |
3247 | - token['consumer_secret'], |
3248 | - oauth_token) |
3249 | - sso_service = ServiceRoot(authorizer, self.service_url) |
3250 | - |
3251 | - me_info = sso_service.accounts.me() |
3252 | + restful_client = restful.RestfulClient(self.service_url, |
3253 | + oauth_credentials=token) |
3254 | + try: |
3255 | + me_info = yield restful_client.restcall(u"accounts.me") |
3256 | + finally: |
3257 | + restful_client.shutdown() |
3258 | key = 'preferred_email' |
3259 | result = key in me_info and me_info[key] != None |
3260 | |
3261 | logger.info('is_validated: consumer_key: %r, result: %r.', |
3262 | token['consumer_key'], result) |
3263 | - return result |
3264 | + defer.returnValue(result) |
3265 | |
3266 | + @defer.inlineCallbacks |
3267 | def validate_email(self, email, password, email_token, token_name): |
3268 | """Validate an email token for user with 'email' and 'password'.""" |
3269 | logger.debug('validate_email: email: %r password: <hidden>, ' |
3270 | 'email_token: %r, token_name: %r.', |
3271 | email, email_token, token_name) |
3272 | - token = self.login(email=email, password=password, |
3273 | - token_name=token_name) |
3274 | - |
3275 | - oauth_token = oauth.OAuthToken(token['token'], token['token_secret']) |
3276 | - authorizer = TimestampedAuthorizer(timestamp_checker.get_faithful_time, |
3277 | - token['consumer_key'], |
3278 | - token['consumer_secret'], |
3279 | - oauth_token) |
3280 | - sso_service = ServiceRoot(authorizer, self.service_url) |
3281 | - result = sso_service.accounts.validate_email(email_token=email_token) |
3282 | + credentials = yield self.login(email=email, password=password, |
3283 | + token_name=token_name) |
3284 | + restful_client = restful.RestfulClient(self.service_url, |
3285 | + oauth_credentials=credentials) |
3286 | + try: |
3287 | + result = yield restful_client.restcall(u"accounts.validate_email", |
3288 | + email_token=email_token) |
3289 | + finally: |
3290 | + restful_client.shutdown() |
3291 | logger.info('validate_email: email: %r result: %r', email, result) |
3292 | if 'errors' in result: |
3293 | errorsdict = self._format_webservice_errors(result['errors']) |
3294 | raise EmailTokenError(errorsdict) |
3295 | elif 'email' in result: |
3296 | - return token |
3297 | + defer.returnValue(credentials) |
3298 | else: |
3299 | raise EmailTokenError('Received invalid reply: %s' % result) |
3300 | |
3301 | + @defer.inlineCallbacks |
3302 | def request_password_reset_token(self, email): |
3303 | """Request a token to reset the password for the account 'email'.""" |
3304 | - sso_service = ServiceRoot(None, self.service_url) |
3305 | - service = sso_service.registrations.request_password_reset_token |
3306 | + restful_client = restful.RestfulClient(self.service_url) |
3307 | try: |
3308 | - result = service(email=email) |
3309 | - except HTTPError, e: |
3310 | + operation = u"registration.request_password_reset_token" |
3311 | + result = yield restful_client.restcall(operation, email=email) |
3312 | + except WebClientError, e: |
3313 | logger.exception('request_password_reset_token failed with:') |
3314 | - raise ResetPasswordTokenError(e.content.split('\n')[0]) |
3315 | + raise ResetPasswordTokenError(e[1].split('\n')[0]) |
3316 | + finally: |
3317 | + restful_client.shutdown() |
3318 | |
3319 | if result['status'].lower() == SSO_STATUS_OK: |
3320 | - return email |
3321 | + defer.returnValue(email) |
3322 | else: |
3323 | raise ResetPasswordTokenError('Received invalid reply: %s' % |
3324 | result) |
3325 | |
3326 | + @defer.inlineCallbacks |
3327 | def set_new_password(self, email, token, new_password): |
3328 | """Set a new password for the account 'email' to be 'new_password'. |
3329 | |
3330 | @@ -263,16 +279,19 @@ |
3331 | 'request_password_reset_token'. |
3332 | |
3333 | """ |
3334 | - sso_service = ServiceRoot(None, self.service_url) |
3335 | - service = sso_service.registrations.set_new_password |
3336 | + restful_client = restful.RestfulClient(self.service_url) |
3337 | try: |
3338 | - result = service(email=email, token=token, |
3339 | - new_password=new_password) |
3340 | - except HTTPError, e: |
3341 | + result = yield restful_client.restcall( |
3342 | + u"registration.set_new_password", |
3343 | + email=email, token=token, |
3344 | + new_password=new_password) |
3345 | + except WebClientError, e: |
3346 | logger.exception('set_new_password failed with:') |
3347 | - raise NewPasswordError(e.content.split('\n')[0]) |
3348 | + raise NewPasswordError(e[1].split('\n')[0]) |
3349 | + finally: |
3350 | + restful_client.shutdown() |
3351 | |
3352 | if result['status'].lower() == SSO_STATUS_OK: |
3353 | - return email |
3354 | + defer.returnValue(email) |
3355 | else: |
3356 | raise NewPasswordError('Received invalid reply: %s' % result) |
3357 | |
3358 | === added file 'ubuntu_sso/constants.py.in' |
3359 | --- ubuntu_sso/constants.py.in 1970-01-01 00:00:00 +0000 |
3360 | +++ ubuntu_sso/constants.py.in 2012-02-14 22:04:20 +0000 |
3361 | @@ -0,0 +1,28 @@ |
3362 | +# -*- coding: utf-8 -*- |
3363 | +# |
3364 | +# Copyright 2012 Canonical Ltd. |
3365 | +# |
3366 | +# This program is free software: you can redistribute it and/or modify it |
3367 | +# under the terms of the GNU General Public License version 3, as published |
3368 | +# by the Free Software Foundation. |
3369 | +# |
3370 | +# This program is distributed in the hope that it will be useful, but |
3371 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
3372 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
3373 | +# PURPOSE. See the GNU General Public License for more details. |
3374 | +# |
3375 | +# You should have received a copy of the GNU General Public License along |
3376 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
3377 | + |
3378 | +"""Some generated constants. |
3379 | + |
3380 | +DO NO EDIT! This is a generated file. It will be built at installation time. |
3381 | + |
3382 | +""" |
3383 | + |
3384 | +import os |
3385 | + |
3386 | + |
3387 | +PROJECT_NAME = 'ubuntu-sso-client' |
3388 | +PROJECT_DIR = os.path.join('@prefix@', 'share', PROJECT_NAME) |
3389 | +BIN_DIR = os.path.join('@prefix@', 'lib', PROJECT_NAME) |
3390 | |
3391 | === modified file 'ubuntu_sso/credentials.py' |
3392 | --- ubuntu_sso/credentials.py 2012-01-17 15:09:12 +0000 |
3393 | +++ ubuntu_sso/credentials.py 2012-02-14 22:04:20 +0000 |
3394 | @@ -1,9 +1,6 @@ |
3395 | # -*- coding: utf-8 -*- |
3396 | - |
3397 | -# Author: Natalia Bidart <natalia.bidart@canonical.com> |
3398 | -# Author: Alejandro J. Cura <alecu@canonical.com> |
3399 | # |
3400 | -# Copyright 2010 Canonical Ltd. |
3401 | +# Copyright 2010-2012 Canonical Ltd. |
3402 | # |
3403 | # This program is free software: you can redistribute it and/or modify it |
3404 | # under the terms of the GNU General Public License version 3, as published |
3405 | @@ -26,28 +23,24 @@ |
3406 | * register |
3407 | * login |
3408 | |
3409 | -The first three return a Deferred that will be fired when the operation was |
3410 | +All the methods return a Deferred that will be fired when the operation was |
3411 | completed. |
3412 | |
3413 | -The second two use the 'success_cb', 'error_cb' and 'denial_cb' to signal the |
3414 | -caller when the credentials were retrieved successfully, when there was an |
3415 | -error or when the user denied the access to the application, respectively. |
3416 | - |
3417 | For details, please read the Credentials class documentation. |
3418 | |
3419 | """ |
3420 | |
3421 | -import sys |
3422 | -import traceback |
3423 | -import urllib2 |
3424 | +import os |
3425 | |
3426 | from functools import wraps |
3427 | |
3428 | from twisted.internet import defer |
3429 | |
3430 | -from ubuntu_sso import NO_OP, utils |
3431 | +from ubuntu_sso import UI_EXECUTABLE_GTK, USER_CANCELLATION, USER_SUCCESS |
3432 | from ubuntu_sso.keyring import Keyring |
3433 | from ubuntu_sso.logger import setup_logging |
3434 | +from ubuntu_sso.utils import get_bin_dir, runner |
3435 | + |
3436 | |
3437 | logger = setup_logging('ubuntu_sso.credentials') |
3438 | |
3439 | @@ -57,44 +50,20 @@ |
3440 | HELP_TEXT_KEY = 'help_text' |
3441 | WINDOW_ID_KEY = 'window_id' |
3442 | PING_URL_KEY = 'ping_url' |
3443 | -UI_MODULE_KEY = 'ui_module' |
3444 | -UI_CLASS_KEY = 'ui_class' |
3445 | -SUCCESS_CB_KEY = 'success_cb' |
3446 | -ERROR_CB_KEY = 'error_cb' |
3447 | -DENIAL_CB_KEY = 'denial_cb' |
3448 | -ERROR_KEY = 'error_message' |
3449 | -ERROR_DETAIL_KEY = 'detailed_error' |
3450 | - |
3451 | - |
3452 | -def handle_exceptions(msg): |
3453 | - """Handle exceptions using 'msg' as error message.""" |
3454 | - |
3455 | - def middle(f): |
3456 | - """Decorate 'f' to catch all errors.""" |
3457 | - |
3458 | - @wraps(f) |
3459 | - def inner(self, *a, **kw): |
3460 | - """Call 'f' within a try-except block. |
3461 | - |
3462 | - If any exception occurs, self.error_cb is called and the exception |
3463 | - is logged. |
3464 | - """ |
3465 | - result = None |
3466 | - try: |
3467 | - result = f(self, *a, **kw) |
3468 | - except: # pylint: disable=W0702 |
3469 | - logger.exception('%s (app_name: %s): %s.', |
3470 | - f.__name__, self.app_name, msg) |
3471 | - logger.error('%s (app_name: %s): Calling error_cb at %r.', |
3472 | - f.__name__, self.app_name, self.error_cb) |
3473 | - error_dict = {ERROR_KEY: msg, |
3474 | - ERROR_DETAIL_KEY: traceback.format_exc()} |
3475 | - self.error_cb(error_dict) |
3476 | - return result |
3477 | - |
3478 | - return inner |
3479 | - |
3480 | - return middle |
3481 | +POLICY_URL_KEY = 'policy_url' |
3482 | +UI_EXECUTABLE_KEY = 'ui_executable' |
3483 | + |
3484 | + |
3485 | +class CredentialsError(Exception): |
3486 | + """Generic credentials error.""" |
3487 | + |
3488 | + |
3489 | +class UserCancellationError(CredentialsError): |
3490 | + """The user cancelled the process of authentication.""" |
3491 | + |
3492 | + |
3493 | +class UserNotValidatedError(CredentialsError): |
3494 | + """The user is not validated.""" |
3495 | |
3496 | |
3497 | def handle_failures(msg): |
3498 | @@ -108,20 +77,17 @@ |
3499 | def inner(self, *a, **kw): |
3500 | """Call 'f' within a try-except block. |
3501 | |
3502 | - If any exception occurs, self.error_cb is called and the exception |
3503 | - is logged. |
3504 | + If any exception occurs, the exception is logged and re-raised. |
3505 | + |
3506 | """ |
3507 | result = None |
3508 | try: |
3509 | result = yield f(self, *a, **kw) |
3510 | - except Exception: # pylint: disable=W0703 |
3511 | + except: |
3512 | logger.exception('%s (app_name: %s): %s.', |
3513 | f.__name__, self.app_name, msg) |
3514 | - logger.error('%s (app_name: %s): Calling error_cb at %r.', |
3515 | - f.__name__, self.app_name, self.error_cb) |
3516 | - error_dict = {ERROR_KEY: msg, |
3517 | - ERROR_DETAIL_KEY: traceback.format_exc()} |
3518 | - self.error_cb(error_dict) |
3519 | + raise |
3520 | + |
3521 | defer.returnValue(result) |
3522 | |
3523 | return inner |
3524 | @@ -133,14 +99,13 @@ |
3525 | """Credentials management gateway.""" |
3526 | |
3527 | def __init__(self, app_name, tc_url=None, help_text='', |
3528 | - window_id=0, ping_url=None, |
3529 | - ui_module='ubuntu_sso.gtk.gui', ui_class='UbuntuSSOClientGUI', |
3530 | - success_cb=NO_OP, error_cb=NO_OP, denial_cb=NO_OP): |
3531 | + window_id=0, ping_url=None, policy_url=None, |
3532 | + ui_executable=UI_EXECUTABLE_GTK): |
3533 | """Return a Credentials management object. |
3534 | |
3535 | 'app_name' is the application name to be displayed in the GUI. |
3536 | |
3537 | - 'tc_url' is the URL pointing to Terms & Conditions. If None, no |
3538 | + 'tc_url' is the url pointing to Terms & Conditions. If None, no |
3539 | TOS agreement will be displayed. |
3540 | |
3541 | 'help_text' is an explanatory text for the end-users, will be shown |
3542 | @@ -152,9 +117,11 @@ |
3543 | 'ping_url' is the url that will be pinged when a user registers/logins |
3544 | successfully. The user email will be attached to 'ping_url'. |
3545 | |
3546 | - 'success_cb' will be called when the credentials were retrieved |
3547 | - successfully. Two params will be passed: the app_name and the |
3548 | - credentials per se. The credentials is a dictionary of the form: |
3549 | + 'policy_url' is the url pointing to the privacy policy. If None, no |
3550 | + privacy policy agreement will be displayed. |
3551 | + |
3552 | + When the credentials are retrieved successfully, a dictionary like the |
3553 | + one below is returned: |
3554 | |
3555 | {'token': <value>, |
3556 | 'token_secret': <value>, |
3557 | @@ -162,106 +129,44 @@ |
3558 | 'consumer_secret': <value>, |
3559 | 'name': <the token name, matches "[app_name] @ [host name]">} |
3560 | |
3561 | - 'error_cb' will be called when the credentials retrieval failed. Two |
3562 | - params will be passed: the app_name, and an error dict with 2 keys: |
3563 | - the error message (user friendly, not translatable so far), and |
3564 | - the detailed error (usually the traceback). |
3565 | - |
3566 | - 'denial_cb' will be called when the user denied the credentials to the |
3567 | - caller. A single param is passed: the app_name. |
3568 | - |
3569 | """ |
3570 | self.app_name = app_name |
3571 | self.help_text = help_text |
3572 | self.window_id = window_id |
3573 | self.ping_url = ping_url |
3574 | self.tc_url = tc_url |
3575 | - self.ui_module = ui_module |
3576 | - self.ui_class = ui_class |
3577 | - self._success_cb = success_cb |
3578 | - self._error_cb = error_cb |
3579 | - self.denial_cb = denial_cb |
3580 | - self.inner = None # will hold the GUI or SSOLoginRoot instance |
3581 | + self.policy_url = policy_url |
3582 | + self.ui_executable = ui_executable |
3583 | |
3584 | - @handle_failures(msg='Problem while retrieving credentials') |
3585 | @defer.inlineCallbacks |
3586 | - def _login_success_cb(self, app_name, email): |
3587 | - """Store credentials when the login/registration succeeded. |
3588 | - |
3589 | - Also, open self.ping_url/email to notify about this new token. If any |
3590 | - error occur, self.error_cb is called. Otherwise, self.success_cb is |
3591 | - called. |
3592 | - |
3593 | - Return 0 on success, and a non-zero value (or None) on error. |
3594 | - |
3595 | - """ |
3596 | - logger.info('Login/registration was successful for app %r, email %r', |
3597 | - app_name, email) |
3598 | - creds = yield self.find_credentials() |
3599 | - if creds is not None: |
3600 | - assert len(creds) > 0, 'Creds are empty! This should not happen' |
3601 | - # ping a server with the credentials if we were requested to |
3602 | - if self.ping_url is not None: |
3603 | - status = yield self._ping_url(app_name, email, creds) |
3604 | - if status is None: |
3605 | - yield self.clear_credentials() |
3606 | - return |
3607 | - |
3608 | - self.success_cb(creds) |
3609 | - defer.returnValue(0) |
3610 | - |
3611 | - def _auth_denial_cb(self, app_name): |
3612 | - """The user decided not to allow the registration or login.""" |
3613 | - logger.warning('Login/registration was denied to app %r', app_name) |
3614 | - self.denial_cb(app_name) |
3615 | - |
3616 | - @handle_failures(msg='Problem opening the ping_url') |
3617 | - def _ping_url(self, app_name, email, credentials): |
3618 | - """Ping the self.ping_url with the email attached. |
3619 | - |
3620 | - Sign the request with the user credentials. The self.ping_url must be |
3621 | - defined if this method is being called. |
3622 | - |
3623 | - """ |
3624 | - logger.info('Pinging server for app_name %r, ping_url: %r, ' |
3625 | - 'email %r.', app_name, self.ping_url, email) |
3626 | - try: |
3627 | - url = self.ping_url.format(email=email) |
3628 | - except IndexError: # tuple index out of range |
3629 | - url = self.ping_url.format(email) # format the first substitution |
3630 | - |
3631 | - if url == self.ping_url: |
3632 | - logger.debug('Original url (%r) could not be formatted, ' |
3633 | - 'appending email (%r).', self.ping_url, email) |
3634 | - url = self.ping_url + email |
3635 | - |
3636 | - headers = utils.oauth_headers(url, credentials) |
3637 | - request = urllib2.Request(url, headers=headers) |
3638 | - logger.debug('Opening the url %r with urllib2.urlopen.', |
3639 | - request.get_full_url()) |
3640 | - # This code is blocking, we should change this. |
3641 | - # I've tried with deferToThread an twisted.web.client.getPage |
3642 | - # but the returned deferred will never be fired (nataliabidart). |
3643 | - response = urllib2.urlopen(request) |
3644 | - logger.debug('Url opened. Response: %s.', response.code) |
3645 | - return defer.succeed(response) |
3646 | - |
3647 | - @handle_exceptions(msg='Problem opening the Ubuntu SSO user interface') |
3648 | def _show_ui(self, login_only): |
3649 | """Shows the UI, connect outcome signals.""" |
3650 | - |
3651 | - __import__(self.ui_module) |
3652 | - gui = sys.modules[self.ui_module] |
3653 | - |
3654 | - self.inner = getattr(gui, self.ui_class)(app_name=self.app_name, |
3655 | - tc_url=self.tc_url, help_text=self.help_text, |
3656 | - window_id=self.window_id, login_only=login_only) |
3657 | - |
3658 | - self.inner.login_success_callback = self._login_success_cb |
3659 | - self.inner.registration_success_callback = self._login_success_cb |
3660 | - self.inner.user_cancellation_callback = self._auth_denial_cb |
3661 | - |
3662 | - @handle_exceptions(msg='Problem logging with email and password.') |
3663 | + ui_exe_path = os.path.join(get_bin_dir(), self.ui_executable) |
3664 | + args = [ui_exe_path] |
3665 | + for arg in ('app_name', 'help_text', 'ping_url', 'policy_url', |
3666 | + 'tc_url', 'window_id'): |
3667 | + value = getattr(self, arg) |
3668 | + if value: |
3669 | + args.append('--%s' % arg) |
3670 | + args.append("%s" % str(value)) |
3671 | + |
3672 | + if login_only: |
3673 | + args.append('--login_only') |
3674 | + |
3675 | + return_code = yield runner.spawn_program(args) |
3676 | + logger.info('_show_ui: received from the ui return code %r.', |
3677 | + return_code) |
3678 | + |
3679 | + credentials = None |
3680 | + if return_code == USER_SUCCESS: |
3681 | + credentials = yield self.find_credentials() |
3682 | + elif return_code == USER_CANCELLATION: |
3683 | + raise UserCancellationError() |
3684 | + else: |
3685 | + raise CredentialsError(return_code) |
3686 | + |
3687 | + defer.returnValue(credentials) |
3688 | + |
3689 | def _do_login(self, email, password): |
3690 | """Login using email/password, connect outcome signals.""" |
3691 | from ubuntu_sso.main import SSOLogin |
3692 | @@ -279,62 +184,43 @@ |
3693 | |
3694 | def LoginError(self, app_name, error): |
3695 | """There was an error on login.""" |
3696 | + error = CredentialsError(error['errtype']) |
3697 | d.errback(error) |
3698 | |
3699 | def UserNotValidated(self, app_name, email): |
3700 | """User is not validated.""" |
3701 | - d.callback(None) |
3702 | + d.errback(UserNotValidatedError(email)) |
3703 | |
3704 | # pylint: enable=C0103 |
3705 | |
3706 | - self.inner = SSOLogin(proxy=DummyProxy()) |
3707 | - self.inner.login(app_name=self.app_name, |
3708 | - email=email, password=password) |
3709 | - |
3710 | - def _success(result): |
3711 | - """Check if 'result' is a valid token, and callback properly.""" |
3712 | - if result is not None: |
3713 | - return self._login_success_cb(self.app_name, email) |
3714 | - else: |
3715 | - error_dict = { |
3716 | - 'errtype': 'UserNotValidated', |
3717 | - 'message': email, |
3718 | - } |
3719 | - self._error_cb(self.app_name, error_dict) |
3720 | - |
3721 | - d.addCallback(_success) |
3722 | - d.addErrback(lambda f: self._error_cb(self.app_name, f.value)) |
3723 | - |
3724 | - @handle_failures(msg='Problem while retrieving credentials') |
3725 | + inner = SSOLogin(proxy=DummyProxy()) |
3726 | + inner.login(app_name=self.app_name, |
3727 | + email=email, password=password, |
3728 | + ping_url=self.ping_url) |
3729 | + |
3730 | + d.addCallback(lambda _: self.find_credentials()) |
3731 | + return d |
3732 | + |
3733 | @defer.inlineCallbacks |
3734 | def _login_or_register(self, login_only, email=None, password=None): |
3735 | - """Get credentials if found else prompt the GUI.""" |
3736 | + """Get credentials if found else prompt the GUI. |
3737 | + |
3738 | + Will return either the credentials, or will raise UserCancellationError |
3739 | + if the user aborted the operation when the UI was opened. |
3740 | + |
3741 | + """ |
3742 | logger.info("_login_or_register: login_only=%r email=%r.", |
3743 | - login_only, email) |
3744 | + login_only, email) |
3745 | token = yield self.find_credentials() |
3746 | - if token is not None and len(token) > 0: |
3747 | - self.success_cb(token) |
3748 | - elif token == {}: |
3749 | + if not token: |
3750 | if email and password: |
3751 | - self._do_login(email, password) |
3752 | + token = yield self._do_login(email, password) |
3753 | else: |
3754 | - self._show_ui(login_only) |
3755 | - else: |
3756 | - # something went wrong with find_credentials, already handled. |
3757 | - logger.info('_login_or_register: call to "find_credentials" went ' |
3758 | - 'wrong, and was already handled.') |
3759 | - |
3760 | - def error_cb(self, error_dict): |
3761 | - """Handle error and notify the caller.""" |
3762 | - logger.error('Calling error callback at %r (error is %r).', |
3763 | - self._error_cb, error_dict) |
3764 | - self._error_cb(self.app_name, error_dict) |
3765 | - |
3766 | - def success_cb(self, creds): |
3767 | - """Handle success and notify the caller.""" |
3768 | - logger.debug('Calling success callback at %r.', self._success_cb) |
3769 | - self._success_cb(self.app_name, creds) |
3770 | - |
3771 | + token = yield self._show_ui(login_only) |
3772 | + |
3773 | + defer.returnValue(token) |
3774 | + |
3775 | + @handle_failures(msg='Problem while getting credentials from the keyring') |
3776 | @defer.inlineCallbacks |
3777 | def find_credentials(self): |
3778 | """Get the credentials for 'self.app_name'. Return {} if not there.""" |
3779 | @@ -343,20 +229,22 @@ |
3780 | 'result is {}? %s', self.app_name, creds is None) |
3781 | defer.returnValue(creds if creds is not None else {}) |
3782 | |
3783 | - @defer.inlineCallbacks |
3784 | + @handle_failures(msg='Problem while clearing credentials in the keyring') |
3785 | def clear_credentials(self): |
3786 | """Clear the credentials for 'self.app_name'.""" |
3787 | - yield Keyring().delete_credentials(self.app_name) |
3788 | + return Keyring().delete_credentials(self.app_name) |
3789 | |
3790 | - @defer.inlineCallbacks |
3791 | + @handle_failures(msg='Problem while storing credentials in the keyring') |
3792 | def store_credentials(self, token): |
3793 | """Store the credentials for 'self.app_name'.""" |
3794 | - yield Keyring().set_credentials(self.app_name, token) |
3795 | + return Keyring().set_credentials(self.app_name, token) |
3796 | |
3797 | + @handle_failures(msg='Problem while performing register') |
3798 | def register(self): |
3799 | """Get credentials if found else prompt the GUI to register.""" |
3800 | return self._login_or_register(login_only=False) |
3801 | |
3802 | + @handle_failures(msg='Problem while performing login') |
3803 | def login(self, email=None, password=None): |
3804 | """Get credentials if found else prompt the GUI to login. |
3805 | |
3806 | |
3807 | === modified file 'ubuntu_sso/gtk/__init__.py' |
3808 | --- ubuntu_sso/gtk/__init__.py 2010-11-19 19:53:22 +0000 |
3809 | +++ ubuntu_sso/gtk/__init__.py 2012-02-14 22:04:20 +0000 |
3810 | @@ -1,8 +1,6 @@ |
3811 | # -*- coding: utf-8 -*- |
3812 | # |
3813 | -# Author: Natalia Bidart <natalia.bidart@canonical.com> |
3814 | -# |
3815 | -# Copyright 2009-2010 Canonical Ltd. |
3816 | +# Copyright 2009-2012 Canonical Ltd. |
3817 | # |
3818 | # This program is free software: you can redistribute it and/or modify it |
3819 | # under the terms of the GNU General Public License version 3, as published |
3820 | |
3821 | === modified file 'ubuntu_sso/gtk/gui.py' |
3822 | --- ubuntu_sso/gtk/gui.py 2012-01-31 19:02:36 +0000 |
3823 | +++ ubuntu_sso/gtk/gui.py 2012-02-14 22:04:20 +0000 |
3824 | @@ -1,6 +1,6 @@ |
3825 | # -*- coding: utf-8 -*- |
3826 | # |
3827 | -# Copyright 2010 Canonical Ltd. |
3828 | +# Copyright 2010-2012 Canonical Ltd. |
3829 | # |
3830 | # This program is free software: you can redistribute it and/or modify it |
3831 | # under the terms of the GNU General Public License version 3, as published |
3832 | @@ -22,18 +22,23 @@ |
3833 | import tempfile |
3834 | import webbrowser |
3835 | |
3836 | -from functools import wraps |
3837 | - |
3838 | -import gtk |
3839 | - |
3840 | +from functools import wraps, partial |
3841 | + |
3842 | +# pylint: disable=E0611,F0401 |
3843 | +from gi.repository import Gdk, Gtk |
3844 | +from gi.repository.GdkX11 import X11Window |
3845 | +# pylint: enable=E0611,F0401 |
3846 | from twisted.internet import defer |
3847 | |
3848 | from ubuntu_sso import ( |
3849 | main, |
3850 | NO_OP, |
3851 | + USER_CANCELLATION, |
3852 | + USER_SUCCESS, |
3853 | utils, |
3854 | ) |
3855 | -from ubuntu_sso.logger import setup_logging |
3856 | +from ubuntu_sso.logger import setup_gui_logging |
3857 | +from ubuntu_sso.utils import get_data_file |
3858 | from ubuntu_sso.utils.ui import ( |
3859 | CAPTCHA_LOAD_ERROR, |
3860 | CAPTCHA_RELOAD_TOOLTIP, |
3861 | @@ -43,7 +48,7 @@ |
3862 | ERROR, |
3863 | FIELD_REQUIRED, |
3864 | FORGOTTEN_PASSWORD_BUTTON, |
3865 | - get_data_file, |
3866 | + GENERIC_BACKEND_ERROR, |
3867 | is_min_required_password, |
3868 | is_correct_email, |
3869 | JOIN_HEADER_LABEL, |
3870 | @@ -72,7 +77,19 @@ |
3871 | # pylint: disable=E1101 |
3872 | |
3873 | |
3874 | -logger = setup_logging('ubuntu_sso.gui') |
3875 | +logger = setup_gui_logging('ubuntu_sso.gui.gtk') |
3876 | + |
3877 | + |
3878 | +# pylint: disable=C0103 |
3879 | +def parse_color(color): |
3880 | + """Parse a string color into Gdk.Color.""" |
3881 | + c = Gdk.RGBA() |
3882 | + result = c.parse(color) |
3883 | + if not result: |
3884 | + logger.warning('Could not parse color %r.', color) |
3885 | + return c |
3886 | +# pylint: enable=C0103 |
3887 | + |
3888 | |
3889 | # To be removed when Python bindings provide these constants |
3890 | # as per http://code.google.com/p/pywebkitgtk/issues/detail?id=44 |
3891 | @@ -92,11 +109,8 @@ |
3892 | |
3893 | DEFAULT_WIDTH = 30 |
3894 | # To be replaced by values from the theme (LP: #616526) |
3895 | -HELP_TEXT_COLOR = gtk.gdk.Color("#bfbfbf") |
3896 | -WARNING_TEXT_COLOR = gtk.gdk.Color("red") |
3897 | - |
3898 | -USER_CANCELLATION = 10 |
3899 | -LOGIN_SUCCESS = REGISTRATION_SUCCESS = 0 |
3900 | +HELP_TEXT_COLOR = parse_color("#bfbfbf") |
3901 | +WARNING_TEXT_COLOR = parse_color("red") |
3902 | |
3903 | |
3904 | def log_call(f): |
3905 | @@ -111,9 +125,12 @@ |
3906 | return inner |
3907 | |
3908 | |
3909 | -class LabeledEntry(gtk.Entry): |
3910 | +class LabeledEntry(Gtk.Entry): |
3911 | """An entry that displays the label within itself ina grey color.""" |
3912 | |
3913 | + # Use of super on an old style class |
3914 | + # pylint: disable=E1002 |
3915 | + |
3916 | def __init__(self, label, is_password=False, *args, **kwargs): |
3917 | self.label = label |
3918 | self.is_password = is_password |
3919 | @@ -133,7 +150,8 @@ |
3920 | """Clear text and restore text color.""" |
3921 | self.set_text(self.get_text()) |
3922 | |
3923 | - self.modify_text(gtk.STATE_NORMAL, None) # restore to theme's default |
3924 | + # restore to theme's default |
3925 | + self.override_color(Gtk.StateFlags.NORMAL, None) |
3926 | |
3927 | if self.is_password: |
3928 | self.set_visibility(False) |
3929 | @@ -146,7 +164,7 @@ |
3930 | return |
3931 | |
3932 | self.set_text(self.label) |
3933 | - self.modify_text(gtk.STATE_NORMAL, HELP_TEXT_COLOR) |
3934 | + self.override_color(Gtk.StateFlags.NORMAL, HELP_TEXT_COLOR) |
3935 | |
3936 | if self.is_password: |
3937 | self.set_visibility(True) |
3938 | @@ -163,7 +181,7 @@ |
3939 | def set_warning(self, warning_msg): |
3940 | """Display warning as secondary icon, set 'warning_msg' as tooltip.""" |
3941 | self.warning = warning_msg |
3942 | - self.set_property('secondary-icon-stock', gtk.STOCK_DIALOG_WARNING) |
3943 | + self.set_property('secondary-icon-stock', Gtk.STOCK_DIALOG_WARNING) |
3944 | self.set_property('secondary-icon-sensitive', True) |
3945 | self.set_property('secondary-icon-activatable', False) |
3946 | self.set_property('secondary-icon-tooltip-text', warning_msg) |
3947 | @@ -185,8 +203,6 @@ |
3948 | logger.debug('UbuntuSSOClientGUI: app_name %r, kwargs %r.', |
3949 | app_name, kwargs) |
3950 | |
3951 | - gtk.link_button_set_uri_hook(NO_OP) |
3952 | - |
3953 | self._captcha_filename = tempfile.mktemp() |
3954 | self._captcha_id = None |
3955 | self._signals_receivers = {} |
3956 | @@ -201,29 +217,22 @@ |
3957 | window_id = kwargs.get('window_id', 0) |
3958 | self.close_callback = kwargs.get('close_callback', NO_OP) |
3959 | self.backend = None |
3960 | - # the following 3 callbacks will be removed as soon as |
3961 | - # the backend stop using them |
3962 | - self.login_success_callback = NO_OP |
3963 | - self.registration_success_callback = NO_OP |
3964 | - self.user_cancellation_callback = NO_OP |
3965 | - |
3966 | self.user_email = None |
3967 | self.user_password = None |
3968 | |
3969 | ui_filename = get_data_file('gtk', 'ui.glade') |
3970 | - builder = gtk.Builder() |
3971 | + builder = Gtk.Builder() |
3972 | builder.add_from_file(ui_filename) |
3973 | builder.connect_signals(self) |
3974 | |
3975 | self.widgets = [] |
3976 | self.warnings = [] |
3977 | self.cancels = [] |
3978 | - self.labels = [] |
3979 | for obj in builder.get_objects(): |
3980 | name = getattr(obj, 'name', None) |
3981 | - if name is None and isinstance(obj, gtk.Buildable): |
3982 | + if name is None and isinstance(obj, Gtk.Buildable): |
3983 | # work around bug lp:507739 |
3984 | - name = gtk.Buildable.get_name(obj) |
3985 | + name = Gtk.Buildable.get_name(obj) |
3986 | if name is None: |
3987 | logging.warn("%s has no name (??)", obj) |
3988 | else: |
3989 | @@ -235,9 +244,12 @@ |
3990 | if 'cancel_button' in name: |
3991 | obj.connect('clicked', self.on_close_clicked) |
3992 | self.cancels.append(obj) |
3993 | - if 'label' in name: |
3994 | - obj.connect('size-allocate', self.on_size_allocate) |
3995 | - self.labels.append(obj) |
3996 | + |
3997 | + # Connect the activate-link signal here |
3998 | + # GtkBuilder in GTK 3 seems to not do this |
3999 | + self.login_button.connect('activate-link', self.on_activate_link) |
4000 | + self.forgotten_password_button.connect('activate-link', |
4001 | + self.on_activate_link) |
4002 | |
4003 | self.entries = (u'name_entry', u'email1_entry', u'email2_entry', |
4004 | u'password1_entry', u'password2_entry', |
4005 | @@ -297,7 +309,10 @@ |
4006 | # still do everything as a standalone window. Also, |
4007 | # window_foreign_new may return None breaking set_transient_for. |
4008 | try: |
4009 | - win = gtk.gdk.window_foreign_new(window_id) |
4010 | + display = Gdk.Display.get_default() |
4011 | + # this is not working, we need to create a XLib.window |
4012 | + # as a second parameter to foreign_new_for_display |
4013 | + win = X11Window.foreign_new_for_display(display, None) |
4014 | self.window.realize() |
4015 | self.window.window.set_transient_for(win) |
4016 | except: # pylint: disable=W0702 |
4017 | @@ -366,20 +381,21 @@ |
4018 | |
4019 | def _add_spinner_to_container(self, container, legend=None): |
4020 | """Add a spinner to 'container'.""" |
4021 | - spinner = gtk.Spinner() |
4022 | + spinner = Gtk.Spinner() |
4023 | spinner.start() |
4024 | |
4025 | - label = gtk.Label() |
4026 | + label = Gtk.Label() |
4027 | if legend: |
4028 | label.set_text(legend) |
4029 | else: |
4030 | label.set_text(LOADING) |
4031 | |
4032 | - hbox = gtk.HBox(spacing=5) |
4033 | - hbox.pack_start(spinner, expand=False) |
4034 | - hbox.pack_start(label, expand=False) |
4035 | + hbox = Gtk.HBox(spacing=5) |
4036 | + hbox.pack_start(spinner, expand=False, fill=True, padding=0) |
4037 | + hbox.pack_start(label, expand=False, fill=True, padding=0) |
4038 | |
4039 | - alignment = gtk.Alignment(xalign=0.5, yalign=0.5) |
4040 | + alignment = Gtk.Alignment(xalign=0.5, yalign=0.5, |
4041 | + xscale=0, yscale=0) |
4042 | alignment.add(hbox) |
4043 | alignment.show_all() |
4044 | |
4045 | @@ -394,7 +410,7 @@ |
4046 | def _set_warning_message(self, widget, message): |
4047 | """Set 'message' as text for 'widget'.""" |
4048 | widget.set_text(message) |
4049 | - widget.modify_fg(gtk.STATE_NORMAL, WARNING_TEXT_COLOR) |
4050 | + widget.override_color(Gtk.StateFlags.NORMAL, WARNING_TEXT_COLOR) |
4051 | widget.show() |
4052 | |
4053 | def _clear_warnings(self): |
4054 | @@ -409,6 +425,12 @@ |
4055 | text = widget.get_text() |
4056 | return bool(text and not text.isspace()) |
4057 | |
4058 | + def _handle_error(self, remote_call, handler, error): |
4059 | + """Handle any error when calling the remote backend.""" |
4060 | + logger.error('Remote call %r failed with: %r', remote_call, error) |
4061 | + errordict = {'message': GENERIC_BACKEND_ERROR} |
4062 | + handler(self.app_name, errordict) |
4063 | + |
4064 | # build pages |
4065 | |
4066 | def _append_pages(self): |
4067 | @@ -433,7 +455,7 @@ |
4068 | |
4069 | def _append_page(self, page): |
4070 | """Append 'page' to the 'window'.""" |
4071 | - self.content.append_page(page) |
4072 | + self.content.append_page(page, None) |
4073 | |
4074 | def _set_header(self, header): |
4075 | """Set 'header' as the window title and header.""" |
4076 | @@ -464,16 +486,19 @@ |
4077 | logger.info('Calling generate_captcha with filename path at %r', |
4078 | self._captcha_filename) |
4079 | self.warning_label.set_text('') |
4080 | - self.backend.generate_captcha(self.app_name, self._captcha_filename, |
4081 | - reply_handler=NO_OP, error_handler=NO_OP) |
4082 | + f = self.backend.generate_captcha |
4083 | + error_handler = partial(self._handle_error, f, |
4084 | + self.on_captcha_generation_error) |
4085 | + f(self.app_name, self._captcha_filename, |
4086 | + reply_handler=NO_OP, error_handler=error_handler) |
4087 | self._set_captcha_loading() |
4088 | |
4089 | def _set_captcha_loading(self): |
4090 | """Present a spinner to the user while the captcha is downloaded.""" |
4091 | self.captcha_image.hide() |
4092 | self._add_spinner_to_container(self.captcha_loading) |
4093 | - white = gtk.gdk.Color('white') |
4094 | - self.captcha_loading.modify_bg(gtk.STATE_NORMAL, white) |
4095 | + self.captcha_loading.override_background_color(Gtk.StateFlags.NORMAL, |
4096 | + parse_color('white')) |
4097 | self.captcha_loading.show_all() |
4098 | self.join_ok_button.set_sensitive(False) |
4099 | |
4100 | @@ -490,20 +515,26 @@ |
4101 | self.enter_details_vbox.header = JOIN_HEADER_LABEL % d |
4102 | self.enter_details_vbox.help_text = self.help_text |
4103 | self.enter_details_vbox.default_widget = self.join_ok_button |
4104 | - self.join_ok_button.set_flags(gtk.CAN_DEFAULT) |
4105 | + self.join_ok_button.set_can_default(True) |
4106 | |
4107 | - self.enter_details_vbox.pack_start(self.name_entry, expand=False) |
4108 | + self.enter_details_vbox.pack_start(self.name_entry, |
4109 | + expand=False, fill=True, padding=0) |
4110 | self.enter_details_vbox.reorder_child(self.name_entry, 0) |
4111 | entry = self.captcha_solution_entry |
4112 | - self.captcha_solution_vbox.pack_start(entry, expand=False) |
4113 | + self.captcha_solution_vbox.pack_start(entry, |
4114 | + expand=False, fill=True, padding=0) |
4115 | msg = CAPTCHA_RELOAD_TOOLTIP |
4116 | self.captcha_reload_button.set_tooltip_text(msg) |
4117 | |
4118 | - self.emails_hbox.pack_start(self.email1_entry, expand=False) |
4119 | - self.emails_hbox.pack_start(self.email2_entry, expand=False) |
4120 | + self.emails_hbox.pack_start(self.email1_entry, |
4121 | + expand=False, fill=True, padding=0) |
4122 | + self.emails_hbox.pack_start(self.email2_entry, |
4123 | + expand=False, fill=True, padding=0) |
4124 | |
4125 | - self.passwords_hbox.pack_start(self.password1_entry, expand=False) |
4126 | - self.passwords_hbox.pack_start(self.password2_entry, expand=False) |
4127 | + self.passwords_hbox.pack_start(self.password1_entry, |
4128 | + expand=False, fill=True, padding=0) |
4129 | + self.passwords_hbox.pack_start(self.password2_entry, |
4130 | + expand=False, fill=True, padding=0) |
4131 | help_msg = '<small>%s</small>' % PASSWORD_HELP |
4132 | self.password_help_label.set_markup(help_msg) |
4133 | |
4134 | @@ -519,7 +550,7 @@ |
4135 | self.yes_to_tc_checkbutton.set_label(msg) |
4136 | self.tc_button.set_label(TC_BUTTON) |
4137 | else: |
4138 | - self.tc_vbox.hide_all() |
4139 | + self.tc_vbox.hide() |
4140 | self.login_button.set_label(LOGIN_BUTTON_LABEL) |
4141 | |
4142 | return self.enter_details_vbox |
4143 | @@ -528,7 +559,7 @@ |
4144 | """Build the Terms & Conditions page.""" |
4145 | self.tc_browser_vbox.help_text = '' |
4146 | self.tc_browser_vbox.default_widget = self.tc_back_button |
4147 | - self.tc_browser_vbox.default_widget.set_flags(gtk.CAN_DEFAULT) |
4148 | + self.tc_browser_vbox.default_widget.set_can_default(True) |
4149 | return self.tc_browser_vbox |
4150 | |
4151 | def _build_processing_page(self): |
4152 | @@ -541,17 +572,16 @@ |
4153 | def _build_verify_email_page(self): |
4154 | """Build the verify email page.""" |
4155 | self.verify_email_vbox.default_widget = self.verify_token_button |
4156 | - self.verify_email_vbox.default_widget.set_flags(gtk.CAN_DEFAULT) |
4157 | + self.verify_email_vbox.default_widget.set_can_default(True) |
4158 | |
4159 | self.verify_email_details_vbox.pack_start(self.email_token_entry, |
4160 | - expand=False) |
4161 | - |
4162 | + expand=False, fill=True, padding=0) |
4163 | return self.verify_email_vbox |
4164 | |
4165 | def _build_finish_page(self): |
4166 | """Build the success page.""" |
4167 | self.finish_vbox.default_widget = self.finish_close_button |
4168 | - self.finish_vbox.default_widget.set_flags(gtk.CAN_DEFAULT) |
4169 | + self.finish_vbox.default_widget.set_can_default(True) |
4170 | self.finish_vbox.label = self.finish_label |
4171 | return self.finish_vbox |
4172 | |
4173 | @@ -561,11 +591,13 @@ |
4174 | self.login_vbox.header = LOGIN_HEADER_LABEL % d |
4175 | self.login_vbox.help_text = CONNECT_HELP_LABEL % d |
4176 | self.login_vbox.default_widget = self.login_ok_button |
4177 | - self.login_vbox.default_widget.set_flags(gtk.CAN_DEFAULT) |
4178 | + self.login_vbox.default_widget.set_can_default(True) |
4179 | |
4180 | - self.login_details_vbox.pack_start(self.login_email_entry) |
4181 | + self.login_details_vbox.pack_start(self.login_email_entry, |
4182 | + expand=True, fill=True, padding=0) |
4183 | self.login_details_vbox.reorder_child(self.login_email_entry, 0) |
4184 | - self.login_details_vbox.pack_start(self.login_password_entry) |
4185 | + self.login_details_vbox.pack_start(self.login_password_entry, |
4186 | + expand=True, fill=True, padding=0) |
4187 | self.login_details_vbox.reorder_child(self.login_password_entry, 1) |
4188 | |
4189 | msg = FORGOTTEN_PASSWORD_BUTTON |
4190 | @@ -580,12 +612,12 @@ |
4191 | text = REQUEST_PASSWORD_TOKEN_LABEL % {'app_name': self.app_label} |
4192 | self.request_password_token_vbox.help_text = text |
4193 | btn = self.request_password_token_ok_button |
4194 | - btn.set_flags(gtk.CAN_DEFAULT) |
4195 | + btn.set_can_default(True) |
4196 | self.request_password_token_vbox.default_widget = btn |
4197 | |
4198 | entry = self.reset_email_entry |
4199 | self.request_password_token_details_vbox.pack_start(entry, |
4200 | - expand=False) |
4201 | + expand=False, fill=True, padding=0) |
4202 | cb = self.on_reset_email_entry_changed |
4203 | self.reset_email_entry.connect('changed', cb) |
4204 | self.request_password_token_ok_button.set_label(NEXT) |
4205 | @@ -598,13 +630,14 @@ |
4206 | self.set_new_password_vbox.header = RESET_PASSWORD |
4207 | self.set_new_password_vbox.help_text = SET_NEW_PASSWORD_LABEL |
4208 | btn = self.set_new_password_ok_button |
4209 | - btn.set_flags(gtk.CAN_DEFAULT) |
4210 | + btn.set_can_default(True) |
4211 | self.set_new_password_vbox.default_widget = btn |
4212 | |
4213 | for entry in (self.reset_code_entry, |
4214 | self.reset_password1_entry, |
4215 | self.reset_password2_entry): |
4216 | - self.set_new_password_details_vbox.pack_start(entry, expand=False) |
4217 | + self.set_new_password_details_vbox.pack_start(entry, |
4218 | + expand=False, fill=True, padding=0) |
4219 | |
4220 | cb = self.on_set_new_password_entries_changed |
4221 | self.reset_code_entry.connect('changed', cb) |
4222 | @@ -645,6 +678,11 @@ |
4223 | |
4224 | # GTK callbacks |
4225 | |
4226 | + def destroy(self): |
4227 | + """Destroy this UI.""" |
4228 | + self.window.hide() |
4229 | + self.window.destroy() |
4230 | + |
4231 | def connect(self, signal_name, handler, *args, **kwargs): |
4232 | """Connect 'signal_name' with 'handler'.""" |
4233 | logger.debug('connect: signal %r, handler %r, args %r, kwargs, %r', |
4234 | @@ -661,9 +699,9 @@ |
4235 | self._done = True |
4236 | self._set_current_page(self.error_vbox) |
4237 | |
4238 | - def on_size_allocate(self, widget, allocation): |
4239 | - """The widget can re rezised, embrase it!.""" |
4240 | - widget.set_size_request(allocation.width - 2, -1) |
4241 | + def on_activate_link(self, button): |
4242 | + """Do nothing, used for LinkButtons that are used as regular ones.""" |
4243 | + return True |
4244 | |
4245 | def on_close_clicked(self, *args, **kwargs): |
4246 | """Call self.close_callback if defined.""" |
4247 | @@ -678,16 +716,16 @@ |
4248 | self.window.hide() |
4249 | |
4250 | # process any pending events before callbacking with result |
4251 | - while gtk.events_pending(): |
4252 | - gtk.main_iteration() |
4253 | + while Gtk.events_pending(): |
4254 | + Gtk.main_iteration() |
4255 | |
4256 | - return_code = LOGIN_SUCCESS |
4257 | + return_code = USER_SUCCESS |
4258 | if not self._done: |
4259 | - self.user_cancellation_callback(self.app_name) |
4260 | return_code = USER_CANCELLATION |
4261 | + logger.info('Return code will be %r.', return_code) |
4262 | |
4263 | # call user defined callback |
4264 | - logger.info('Calling custom close_callback %r with params %r, %r', |
4265 | + logger.debug('Calling custom close_callback %r with params %r, %r', |
4266 | self.close_callback, args, kwargs) |
4267 | self.close_callback(*args, **kwargs) |
4268 | |
4269 | @@ -750,10 +788,14 @@ |
4270 | logger.info('Calling register_user with email %r, password <hidden>,' \ |
4271 | ' name %r, captcha_id %r and captcha_solution %r.', email1, |
4272 | name, self._captcha_id, captcha_solution) |
4273 | + |
4274 | f = self.backend.register_user |
4275 | - f(self.app_name, email1, password1, name, |
4276 | - self._captcha_id, captcha_solution, |
4277 | - reply_handler=NO_OP, error_handler=NO_OP) |
4278 | + error_handler = partial(self._handle_error, f, |
4279 | + self.on_user_registration_error) |
4280 | + f(unicode(self.app_name), email1.decode('utf8'), |
4281 | + password1.decode('utf8'), name.decode('utf8'), |
4282 | + unicode(self._captcha_id), captcha_solution.decode('utf8'), |
4283 | + reply_handler=NO_OP, error_handler=error_handler) |
4284 | |
4285 | def on_verify_token_button_clicked(self, *args, **kwargs): |
4286 | """The user entered the email token, let's verify!""" |
4287 | @@ -772,7 +814,7 @@ |
4288 | |
4289 | args = (self.app_name, email, password, email_token) |
4290 | if self.ping_url: |
4291 | - f = self.backend.validate_email_with_ping |
4292 | + f = self.backend.validate_email_and_ping |
4293 | args = args + (self.ping_url,) |
4294 | else: |
4295 | f = self.backend.validate_email |
4296 | @@ -780,7 +822,9 @@ |
4297 | logger.info('Calling validate_email with email %r, password <hidden>, ' |
4298 | 'app_name %r and email_token %r.', email, self.app_name, |
4299 | email_token) |
4300 | - f(*args, reply_handler=NO_OP, error_handler=NO_OP) |
4301 | + error_handler = partial(self._handle_error, f, |
4302 | + self.on_email_validation_error) |
4303 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
4304 | |
4305 | self._set_current_page(self.processing_vbox) |
4306 | |
4307 | @@ -809,12 +853,13 @@ |
4308 | |
4309 | args = (self.app_name, email, password) |
4310 | if self.ping_url: |
4311 | - f = self.backend.login_with_ping |
4312 | + f = self.backend.login_and_ping |
4313 | args = args + (self.ping_url,) |
4314 | else: |
4315 | f = self.backend.login |
4316 | |
4317 | - f(*args, reply_handler=NO_OP, error_handler=NO_OP) |
4318 | + error_handler = partial(self._handle_error, f, self.on_login_error) |
4319 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
4320 | |
4321 | self._set_current_page(self.processing_vbox) |
4322 | self.user_email = email |
4323 | @@ -843,7 +888,10 @@ |
4324 | |
4325 | logger.info('Calling request_password_reset_token with %r.', email) |
4326 | f = self.backend.request_password_reset_token |
4327 | - f(self.app_name, email, reply_handler=NO_OP, error_handler=NO_OP) |
4328 | + error_handler = partial(self._handle_error, f, |
4329 | + self.on_password_reset_error) |
4330 | + f(self.app_name, email, |
4331 | + reply_handler=NO_OP, error_handler=error_handler) |
4332 | |
4333 | self._set_current_page(self.processing_vbox) |
4334 | |
4335 | @@ -894,16 +942,18 @@ |
4336 | logger.info('Calling set_new_password with email %r, token %r and ' \ |
4337 | 'new password: <hidden>.', email, token) |
4338 | f = self.backend.set_new_password |
4339 | + error_handler = partial(self._handle_error, f, |
4340 | + self.on_password_change_error) |
4341 | f(self.app_name, email, token, password1, |
4342 | - reply_handler=NO_OP, error_handler=NO_OP) |
4343 | + reply_handler=NO_OP, error_handler=error_handler) |
4344 | |
4345 | self._set_current_page(self.processing_vbox) |
4346 | |
4347 | def on_tc_button_clicked(self, *args, **kwargs): |
4348 | """The T&C button was clicked, create the browser and load terms.""" |
4349 | # delay the import of webkit to be able to build without it |
4350 | - import webkit |
4351 | - browser = webkit.WebView() |
4352 | + from gi.repository import WebKit # pylint: disable=E0611 |
4353 | + browser = WebKit.WebView() |
4354 | |
4355 | # The signal WebKitWebView::load-finished is deprecated and should not |
4356 | # be used in newly-written code. Use the "load-status" property |
4357 | @@ -1023,7 +1073,6 @@ |
4358 | @log_call |
4359 | def on_email_validated(self, app_name, email, *args, **kwargs): |
4360 | """User email was successfully verified.""" |
4361 | - self.registration_success_callback(self.app_name, email) |
4362 | self.finish_success() |
4363 | |
4364 | @log_call |
4365 | @@ -1039,7 +1088,6 @@ |
4366 | @log_call |
4367 | def on_logged_in(self, app_name, email, *args, **kwargs): |
4368 | """User was successfully logged in.""" |
4369 | - self.login_success_callback(self.app_name, email) |
4370 | self.finish_success() |
4371 | |
4372 | @log_call |
4373 | |
4374 | === modified file 'ubuntu_sso/gtk/main.py' |
4375 | --- ubuntu_sso/gtk/main.py 2012-01-16 21:10:12 +0000 |
4376 | +++ ubuntu_sso/gtk/main.py 2012-02-14 22:04:20 +0000 |
4377 | @@ -16,34 +16,14 @@ |
4378 | |
4379 | """Main module to open the GTK UI.""" |
4380 | |
4381 | -import argparse |
4382 | - |
4383 | -import gtk |
4384 | +# pylint: disable=E0611 |
4385 | +from gi.repository import Gtk |
4386 | +# pylint: enable=E0611 |
4387 | |
4388 | from ubuntu_sso.gtk.gui import UbuntuSSOClientGUI |
4389 | |
4390 | |
4391 | -def parse_args(): |
4392 | - """Parse sys.argv options.""" |
4393 | - parser = argparse.ArgumentParser(description='Open the GTK SSO UI.') |
4394 | - parser.add_argument('--app_name', required=True, |
4395 | - help='the name of the application to retrieve credentials for') |
4396 | - parser.add_argument('--ping_url', default='', |
4397 | - help='a link to be used as the ping url (to notify about new tokens)') |
4398 | - parser.add_argument('--tc_url', default='', |
4399 | - help='a link to be used as Terms & Conditions url') |
4400 | - parser.add_argument('--help_text', default='', |
4401 | - help='extra text that will be shown below the headers') |
4402 | - parser.add_argument('--window_id', type=int, default=0, |
4403 | - help='the window id to be set transient for the SSO GTK dialogs') |
4404 | - parser.add_argument('--login_only', action='store_true', default=False, |
4405 | - help='whether the SSO GTK UI should only offer login or not') |
4406 | - |
4407 | - args = parser.parse_args() |
4408 | - return args |
4409 | - |
4410 | - |
4411 | def main(**kwargs): |
4412 | """Start the GTK mainloop and open the main window.""" |
4413 | - UbuntuSSOClientGUI(close_callback=gtk.main_quit, **kwargs) |
4414 | - gtk.main() |
4415 | + UbuntuSSOClientGUI(close_callback=Gtk.main_quit, **kwargs) |
4416 | + Gtk.main() |
4417 | |
4418 | === modified file 'ubuntu_sso/gtk/tests/__init__.py' |
4419 | --- ubuntu_sso/gtk/tests/__init__.py 2010-11-19 19:53:22 +0000 |
4420 | +++ ubuntu_sso/gtk/tests/__init__.py 2012-02-14 22:04:20 +0000 |
4421 | @@ -1,8 +1,6 @@ |
4422 | # -*- coding: utf-8 -*- |
4423 | # |
4424 | -# Author: Natalia Bidart <natalia.bidart@canonical.com> |
4425 | -# |
4426 | -# Copyright 2009 Canonical Ltd. |
4427 | +# Copyright 2009-2012 Canonical Ltd. |
4428 | # |
4429 | # This program is free software: you can redistribute it and/or modify it |
4430 | # under the terms of the GNU General Public License version 3, as published |
4431 | |
4432 | === modified file 'ubuntu_sso/gtk/tests/test_gui.py' |
4433 | --- ubuntu_sso/gtk/tests/test_gui.py 2012-01-31 19:02:36 +0000 |
4434 | +++ ubuntu_sso/gtk/tests/test_gui.py 2012-02-14 22:04:20 +0000 |
4435 | @@ -21,8 +21,9 @@ |
4436 | |
4437 | from collections import defaultdict |
4438 | |
4439 | -import gtk |
4440 | -import webkit |
4441 | +# pylint: disable=E0611 |
4442 | +from gi.repository import Gdk, Gtk, WebKit |
4443 | +# pylint: enable=E0611 |
4444 | |
4445 | from twisted.internet import defer |
4446 | from twisted.trial.unittest import TestCase |
4447 | @@ -42,6 +43,9 @@ |
4448 | # Instance of 'UbuntuSSOClientGUI' has no 'yyy' member |
4449 | # pylint: disable=E1101,E1103 |
4450 | |
4451 | +# Use of super on an old style class |
4452 | +# pylint: disable=E1002 |
4453 | + |
4454 | |
4455 | class FakedSSOBackend(object): |
4456 | """Fake a SSO Backend.""" |
4457 | @@ -52,9 +56,9 @@ |
4458 | self._called = {} |
4459 | self.callbacks = defaultdict(list) |
4460 | |
4461 | - for i in ('generate_captcha', 'login', 'login_with_ping', |
4462 | + for i in ('generate_captcha', 'login', 'login_and_ping', |
4463 | 'register_user', 'validate_email', |
4464 | - 'validate_email_with_ping', |
4465 | + 'validate_email_and_ping', |
4466 | 'request_password_reset_token', |
4467 | 'set_new_password'): |
4468 | setattr(self, i, self._record_call(i)) |
4469 | @@ -99,7 +103,7 @@ |
4470 | self[prop_name] = newval |
4471 | |
4472 | |
4473 | -class FakedEmbeddedBrowser(gtk.TextView): |
4474 | +class FakedEmbeddedBrowser(Gtk.TextView): |
4475 | """Faked an embedded browser.""" |
4476 | |
4477 | def __init__(self): |
4478 | @@ -156,6 +160,29 @@ |
4479 | """Set _called to True.""" |
4480 | self._called = (args, kwargs) |
4481 | |
4482 | + def assert_color_equal(self, rgba_color, gdk_color): |
4483 | + """Check that 'rgba_color' is the same as 'gdk_color'.""" |
4484 | + tmp = Gdk.RGBA() |
4485 | + assert tmp.parse(gdk_color.to_string()) |
4486 | + |
4487 | + msg = 'Text color must be "%s" (got "%s" instead).' |
4488 | + self.assertEqual(rgba_color, tmp, msg % (rgba_color, tmp)) |
4489 | + |
4490 | + def assert_backend_called(self, method, *args, **kwargs): |
4491 | + """Check that 'method(*args, **kwargs)' was called in the backend.""" |
4492 | + self.assertIn(method, self.ui.backend._called) |
4493 | + |
4494 | + call = self.ui.backend._called[method] |
4495 | + self.assertEqual(call[0], args) |
4496 | + |
4497 | + reply_handler = call[1].pop('reply_handler') |
4498 | + self.assertEqual(reply_handler, gui.NO_OP) |
4499 | + |
4500 | + error_handler = call[1].pop('error_handler') |
4501 | + self.assertEqual(error_handler.func, self.ui._handle_error) |
4502 | + |
4503 | + self.assertEqual(call[1], kwargs) |
4504 | + |
4505 | |
4506 | class LabeledEntryTestCase(BasicTestCase): |
4507 | """Test suite for the labeled entry.""" |
4508 | @@ -168,9 +195,11 @@ |
4509 | self.entry = gui.LabeledEntry(label=self.label) |
4510 | |
4511 | # we need a window to be able to realize ourselves |
4512 | - window = gtk.Window() |
4513 | + window = Gtk.Window() |
4514 | window.add(self.entry) |
4515 | window.show_all() |
4516 | + self.addCleanup(window.hide) |
4517 | + self.addCleanup(window.destroy) |
4518 | |
4519 | def grab_focus(self, focus_in=True): |
4520 | """Grab focus on widget, if None use self.entry.""" |
4521 | @@ -188,10 +217,9 @@ |
4522 | self.assertEqual(expected, actual, msg % (expected, actual)) |
4523 | |
4524 | # text color is correct |
4525 | - msg = 'Text color must be "%s" (got "%s" instead).' |
4526 | expected = gui.HELP_TEXT_COLOR |
4527 | - actual = self.entry.style.text[gtk.STATE_NORMAL] |
4528 | - self.assertEqual(expected, actual, msg % (expected, actual)) |
4529 | + actual = self.entry.get_style().text[Gtk.StateFlags.NORMAL] |
4530 | + self.assert_color_equal(expected, actual) |
4531 | |
4532 | def test_initial_text(self): |
4533 | """Entry have the correct text at startup.""" |
4534 | @@ -218,11 +246,11 @@ |
4535 | |
4536 | def test_text_defaults_to_theme_color_when_focus_in(self): |
4537 | """Entry restore its text color when focused in.""" |
4538 | - self.patch(self.entry, 'modify_text', self._set_called) |
4539 | + self.patch(self.entry, 'override_color', self._set_called) |
4540 | |
4541 | self.grab_focus() |
4542 | |
4543 | - self.assertEqual(((gtk.STATE_NORMAL, None), {}), self._called, |
4544 | + self.assertEqual(((Gtk.StateFlags.NORMAL, None), {}), self._called, |
4545 | 'Entry text color must be restore on focus in.') |
4546 | |
4547 | def test_refill_entry_on_focus_out_if_no_input(self): |
4548 | @@ -305,7 +333,7 @@ |
4549 | self.entry.set_warning(msg) |
4550 | self.assertEqual(self.entry.warning, msg) |
4551 | self.assertEqual(self.entry.get_property('secondary-icon-stock'), |
4552 | - gtk.STOCK_DIALOG_WARNING) |
4553 | + Gtk.STOCK_DIALOG_WARNING) |
4554 | self.assertEqual(self.entry.get_property('secondary-icon-sensitive'), |
4555 | True) |
4556 | self.assertEqual(self.entry.get_property('secondary-icon-activatable'), |
4557 | @@ -371,6 +399,7 @@ |
4558 | 'tc_browser', 'login', 'request_password_token', |
4559 | 'set_new_password') |
4560 | self.ui = self.gui_class(**self.kwargs) |
4561 | + self.addCleanup(self.ui.destroy) |
4562 | self.error = {'message': UNKNOWN_ERROR} |
4563 | |
4564 | def assert_entries_are_packed_to_ui(self, container_name, entries): |
4565 | @@ -405,8 +434,8 @@ |
4566 | |
4567 | # content color is correct |
4568 | expected = gui.WARNING_TEXT_COLOR |
4569 | - actual = label.style.fg[gtk.STATE_NORMAL] |
4570 | - self.assertEqual(expected, actual) # until realized this will fail |
4571 | + actual = label.get_style().fg[Gtk.StateFlags.NORMAL] |
4572 | + self.assert_color_equal(expected, actual) |
4573 | |
4574 | def assert_correct_entry_warning(self, entry, message): |
4575 | """Check that a warning is shown displaying 'message'.""" |
4576 | @@ -533,16 +562,6 @@ |
4577 | entry = getattr(self.ui, name) |
4578 | self.assertTrue(entry.get_activates_default(), msg % (name,)) |
4579 | |
4580 | - def test_label_size_allocated_is_connected(self): |
4581 | - """Labels have the size-allocate signal connected.""" |
4582 | - msg = 'Label %r must have size-allocate connected.' |
4583 | - labels = [i for i in self.ui.widgets if 'label' in i] |
4584 | - for label in labels: |
4585 | - widget = getattr(self.ui, label) |
4586 | - widget.emit('size-allocate', gtk.gdk.Rectangle(1, 2, 3, 4)) |
4587 | - self.assertEqual(widget.get_size_request(), (3 - 2, -1), |
4588 | - msg % (label,)) |
4589 | - |
4590 | def test_password_fields_are_password(self): |
4591 | """Password fields have the is_password flag set.""" |
4592 | msg = '"%s" should be a password LabeledEntry instance.' |
4593 | @@ -573,28 +592,6 @@ |
4594 | """Main window has the proper icon.""" |
4595 | self.assertEqual('ubuntu-logo', self.ui.window.get_icon_name()) |
4596 | |
4597 | - def test_transient_window_is_none_if_window_id_is_zero(self): |
4598 | - """The transient window is correct.""" |
4599 | - self.patch(gtk.gdk, 'window_foreign_new', self._set_called) |
4600 | - self.gui_class(window_id=0, **self.kwargs) |
4601 | - self.assertFalse(self._called, 'set_transient_for must not be called.') |
4602 | - |
4603 | - def test_transient_window_is_correct(self): |
4604 | - """The transient window is correct.""" |
4605 | - xid = 5 |
4606 | - self.patch(gtk.gdk, 'window_foreign_new', self._set_called) |
4607 | - self.gui_class(window_id=xid, **self.kwargs) |
4608 | - self.assertTrue(self.memento.check(logging.ERROR, 'set_transient_for')) |
4609 | - self.assertTrue(self.memento.check(logging.ERROR, str(xid))) |
4610 | - self.assertEqual(self._called, ((xid,), {})) |
4611 | - |
4612 | - def test_transient_window_accepts_negative_id(self): |
4613 | - """The transient window accepts a negative window id.""" |
4614 | - xid = -5 |
4615 | - self.patch(gtk.gdk, 'window_foreign_new', self._set_called) |
4616 | - self.gui_class(window_id=xid, **self.kwargs) |
4617 | - self.assertEqual(self._called, ((xid,), {})) |
4618 | - |
4619 | def test_finish_success_shows_success_page(self): |
4620 | """When calling 'finish_success' the success page is shown.""" |
4621 | self.ui.finish_success() |
4622 | @@ -611,6 +608,42 @@ |
4623 | self.assertEqual(gui.ERROR, self.ui.finish_vbox.label.get_text()) |
4624 | |
4625 | |
4626 | +class SetTransientForTestCase(UbuntuSSOClientTestCase): |
4627 | + """Test suite for setting the window as transient for another one.""" |
4628 | + |
4629 | + def test_transient_window_is_none_if_window_id_is_zero(self): |
4630 | + """The transient window is correct.""" |
4631 | + self.patch(gui.X11Window, 'foreign_new_for_display', self._set_called) |
4632 | + ui = self.gui_class(window_id=0, **self.kwargs) |
4633 | + self.addCleanup(ui.destroy) |
4634 | + |
4635 | + self.assertFalse(self._called, 'set_transient_for must not be called.') |
4636 | + |
4637 | + def test_transient_window_is_correct(self): |
4638 | + """The transient window is correct.""" |
4639 | + xid = 5 |
4640 | + self.patch(gui.X11Window, 'foreign_new_for_display', self._set_called) |
4641 | + ui = self.gui_class(window_id=xid, **self.kwargs) |
4642 | + self.addCleanup(ui.destroy) |
4643 | + |
4644 | + self.assertTrue(self.memento.check(logging.ERROR, 'set_transient_for')) |
4645 | + self.assertTrue(self.memento.check(logging.ERROR, str(xid))) |
4646 | + self.assertEqual(self._called, ((xid,), {})) |
4647 | + |
4648 | + def test_transient_window_accepts_negative_id(self): |
4649 | + """The transient window accepts a negative window id.""" |
4650 | + xid = -5 |
4651 | + self.patch(gui.X11Window, 'foreign_new_for_display', self._set_called) |
4652 | + ui = self.gui_class(window_id=xid, **self.kwargs) |
4653 | + self.addCleanup(ui.destroy) |
4654 | + |
4655 | + self.assertEqual(self._called, ((xid,), {})) |
4656 | + |
4657 | + |
4658 | +SetTransientForTestCase.skip = "Apparently, so far we can't use XLib " \ |
4659 | +"dynamic bindings to complete the call to X11Window.foreign_new_for_display." |
4660 | + |
4661 | + |
4662 | class EnterDetailsTestCase(UbuntuSSOClientTestCase): |
4663 | """Test suite for the user registration (enter details page).""" |
4664 | |
4665 | @@ -670,13 +703,8 @@ |
4666 | self.click_join_with_valid_data() |
4667 | |
4668 | # assert register_user was called |
4669 | - expected = 'register_user' |
4670 | - self.assertIn(expected, self.ui.backend._called) |
4671 | - self.assertEqual(self.ui.backend._called[expected], |
4672 | - ((APP_NAME, EMAIL, PASSWORD, NAME, CAPTCHA_ID, |
4673 | - CAPTCHA_SOLUTION), |
4674 | - dict(reply_handler=gui.NO_OP, |
4675 | - error_handler=gui.NO_OP))) |
4676 | + self.assert_backend_called('register_user', |
4677 | + APP_NAME, EMAIL, PASSWORD, NAME, CAPTCHA_ID, CAPTCHA_SOLUTION) |
4678 | |
4679 | def test_join_ok_button_clicked_morphs_to_processing_page(self): |
4680 | """Clicking 'join_ok_button' presents the processing vbox.""" |
4681 | @@ -695,8 +723,8 @@ |
4682 | 'processing_vbox must have two children.') |
4683 | |
4684 | spinner, label = box.get_children() |
4685 | - self.assertIsInstance(spinner, gtk.Spinner) |
4686 | - self.assertIsInstance(label, gtk.Label) |
4687 | + self.assertIsInstance(spinner, Gtk.Spinner) |
4688 | + self.assertIsInstance(label, Gtk.Label) |
4689 | |
4690 | self.assertTrue(spinner.get_property('visible'), |
4691 | 'the processing spinner should be visible.') |
4692 | @@ -715,6 +743,8 @@ |
4693 | def test_captcha_filename_is_different_each_time(self): |
4694 | """The captcha image is different each time.""" |
4695 | ui = self.gui_class(**self.kwargs) |
4696 | + self.addCleanup(ui.destroy) |
4697 | + |
4698 | self.assertNotEqual(self.ui._captcha_filename, ui._captcha_filename) |
4699 | |
4700 | def test_captcha_image_is_removed_when_exiting(self): |
4701 | @@ -736,8 +766,8 @@ |
4702 | 'captcha_loading must have two children.') |
4703 | |
4704 | spinner, label = box.get_children() |
4705 | - self.assertIsInstance(spinner, gtk.Spinner) |
4706 | - self.assertIsInstance(label, gtk.Label) |
4707 | + self.assertIsInstance(spinner, Gtk.Spinner) |
4708 | + self.assertIsInstance(label, Gtk.Label) |
4709 | |
4710 | self.assertTrue(spinner.get_property('visible'), |
4711 | 'the captcha_loading spinner should be visible.') |
4712 | @@ -771,12 +801,8 @@ |
4713 | def test_captcha_image_is_requested_as_startup(self): |
4714 | """The captcha image is requested at startup.""" |
4715 | # assert generate_captcha was called |
4716 | - expected = 'generate_captcha' |
4717 | - self.assertIn(expected, self.ui.backend._called) |
4718 | - self.assertEqual(self.ui.backend._called[expected], |
4719 | - ((APP_NAME, self.ui._captcha_filename), |
4720 | - dict(reply_handler=gui.NO_OP, |
4721 | - error_handler=gui.NO_OP))) |
4722 | + self.assert_backend_called('generate_captcha', |
4723 | + APP_NAME, self.ui._captcha_filename) |
4724 | |
4725 | def test_captcha_is_shown_when_available(self): |
4726 | """The captcha image is shown when available.""" |
4727 | @@ -872,7 +898,7 @@ |
4728 | @defer.inlineCallbacks |
4729 | def setUp(self): |
4730 | yield super(TermsAndConditionsBrowserTestCase, self).setUp() |
4731 | - self.patch(webkit, 'WebView', FakedEmbeddedBrowser) |
4732 | + self.patch(WebKit, 'WebView', FakedEmbeddedBrowser) |
4733 | |
4734 | self.ui.tc_button.clicked() |
4735 | self.addCleanup(self.ui.tc_browser_vbox.hide) |
4736 | @@ -968,10 +994,10 @@ |
4737 | |
4738 | def test_navigation_requested_succeeds_for_no_clicking(self): |
4739 | """The navigation request succeeds when user hasn't clicked a link.""" |
4740 | - action = webkit.WebNavigationAction() |
4741 | + action = WebKit.WebNavigationAction() |
4742 | action.set_reason(gui.WEBKIT_WEB_NAVIGATION_REASON_OTHER) |
4743 | |
4744 | - decision = webkit.WebPolicyDecision() |
4745 | + decision = WebKit.WebPolicyDecision() |
4746 | decision.use = self._set_called |
4747 | |
4748 | kwargs = dict(browser=self.browser, frame=None, request=None, |
4749 | @@ -981,10 +1007,10 @@ |
4750 | |
4751 | def test_navigation_requested_ignores_clicked_links(self): |
4752 | """The navigation request is ignored if a link was clicked.""" |
4753 | - action = webkit.WebNavigationAction() |
4754 | + action = WebKit.WebNavigationAction() |
4755 | action.set_reason(gui.WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED) |
4756 | |
4757 | - decision = webkit.WebPolicyDecision() |
4758 | + decision = WebKit.WebPolicyDecision() |
4759 | decision.ignore = self._set_called |
4760 | |
4761 | self.patch(gui.webbrowser, 'open', lambda *args, **kwargs: None) |
4762 | @@ -1007,11 +1033,11 @@ |
4763 | |
4764 | """ |
4765 | url = 'http://something.com/yadda' |
4766 | - action = webkit.WebNavigationAction() |
4767 | + action = WebKit.WebNavigationAction() |
4768 | action.set_reason(gui.WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED) |
4769 | action.set_original_uri(url) |
4770 | |
4771 | - decision = webkit.WebPolicyDecision() |
4772 | + decision = WebKit.WebPolicyDecision() |
4773 | decision.ignore = gui.NO_OP |
4774 | |
4775 | self.patch(gui.webbrowser, 'open', self._set_called) |
4776 | @@ -1098,12 +1124,7 @@ |
4777 | def test_on_verify_token_button_clicked_calls_backend(self): |
4778 | """Verify token button triggers call to backend.""" |
4779 | self.click_verify_email_with_valid_data() |
4780 | - expected = self.method |
4781 | - self.assertIn(expected, self.ui.backend._called) |
4782 | - self.assertEqual(self.ui.backend._called[expected], |
4783 | - (self.method_args, |
4784 | - dict(reply_handler=gui.NO_OP, |
4785 | - error_handler=gui.NO_OP))) |
4786 | + self.assert_backend_called(self.method, *self.method_args) |
4787 | |
4788 | def test_on_verify_token_button_clicked(self): |
4789 | """Verify token uses cached user_email and user_password.""" |
4790 | @@ -1117,10 +1138,7 @@ |
4791 | self.ui.email_token_entry.set_text(EMAIL_TOKEN) |
4792 | |
4793 | self.ui.on_verify_token_button_clicked() |
4794 | - self.assertEqual(self.ui.backend._called[self.method], |
4795 | - (tuple(method_args), |
4796 | - dict(reply_handler=gui.NO_OP, |
4797 | - error_handler=gui.NO_OP))) |
4798 | + self.assert_backend_called(self.method, *tuple(method_args)) |
4799 | |
4800 | def test_on_verify_token_button_shows_processing_page(self): |
4801 | """Verify token button triggers call to backend.""" |
4802 | @@ -1211,7 +1229,7 @@ |
4803 | |
4804 | kwargs = dict(app_name=APP_NAME, tc_url=TC_URL, help_text=HELP_TEXT, |
4805 | ping_url=PING_URL) |
4806 | - method = 'validate_email_with_ping' |
4807 | + method = 'validate_email_and_ping' |
4808 | method_args = (APP_NAME, EMAIL, PASSWORD, EMAIL_TOKEN, PING_URL) |
4809 | |
4810 | |
4811 | @@ -1455,13 +1473,7 @@ |
4812 | def test_on_login_connect_button_clicked(self): |
4813 | """Clicking login_ok_button calls backend.login.""" |
4814 | self.click_connect_with_valid_data() |
4815 | - |
4816 | - expected = self.method |
4817 | - self.assertIn(expected, self.ui.backend._called) |
4818 | - self.assertEqual(self.ui.backend._called[expected], |
4819 | - (self.method_args, |
4820 | - dict(reply_handler=gui.NO_OP, |
4821 | - error_handler=gui.NO_OP))) |
4822 | + self.assert_backend_called(self.method, *self.method_args) |
4823 | |
4824 | def test_on_login_connect_button_clicked_morphs_to_processing_page(self): |
4825 | """Clicking login_ok_button morphs to the processing page.""" |
4826 | @@ -1543,7 +1555,7 @@ |
4827 | |
4828 | kwargs = dict(app_name=APP_NAME, tc_url=TC_URL, help_text=HELP_TEXT, |
4829 | ping_url=PING_URL) |
4830 | - method = 'login_with_ping' |
4831 | + method = 'login_and_ping' |
4832 | method_args = (APP_NAME, EMAIL, PASSWORD, PING_URL) |
4833 | |
4834 | |
4835 | @@ -1665,12 +1677,8 @@ |
4836 | def test_on_request_password_token_ok_button_clicked_calls_backend(self): |
4837 | """Clicking request_password_token_ok_button the backend is called.""" |
4838 | self.click_request_password_token_with_valid_data() |
4839 | - expected = 'request_password_reset_token' |
4840 | - self.assertIn(expected, self.ui.backend._called) |
4841 | - self.assertEqual(self.ui.backend._called[expected], |
4842 | - ((APP_NAME, EMAIL), |
4843 | - dict(reply_handler=gui.NO_OP, |
4844 | - error_handler=gui.NO_OP))) |
4845 | + self.assert_backend_called('request_password_reset_token', |
4846 | + APP_NAME, EMAIL) |
4847 | |
4848 | def test_on_password_reset_token_sent_morphs_window(self): |
4849 | """When the reset token was sent, the reset password page is shown.""" |
4850 | @@ -1805,12 +1813,8 @@ |
4851 | def test_on_set_new_password_ok_button_clicked_calls_backend(self): |
4852 | """Clicking set_new_password_ok_button the backend is called.""" |
4853 | self.click_set_new_password_with_valid_data() |
4854 | - expected = 'set_new_password' |
4855 | - self.assertIn(expected, self.ui.backend._called) |
4856 | - self.assertEqual(self.ui.backend._called[expected], |
4857 | - ((APP_NAME, EMAIL, RESET_PASSWORD_TOKEN, PASSWORD), |
4858 | - dict(reply_handler=gui.NO_OP, |
4859 | - error_handler=gui.NO_OP))) |
4860 | + self.assert_backend_called('set_new_password', |
4861 | + APP_NAME, EMAIL, RESET_PASSWORD_TOKEN, PASSWORD) |
4862 | |
4863 | def test_on_password_changed_shows_login_page(self): |
4864 | """When password was successfuly changed the login page is shown.""" |
4865 | @@ -2070,10 +2074,6 @@ |
4866 | class ReturnCodeTestCase(UbuntuSSOClientTestCase): |
4867 | """Test the return codes.""" |
4868 | |
4869 | - LOGIN_SUCCESS = gui.LOGIN_SUCCESS |
4870 | - REGISTRATION_SUCCESS = gui.REGISTRATION_SUCCESS |
4871 | - USER_CANCELLATION = gui.USER_CANCELLATION |
4872 | - |
4873 | @defer.inlineCallbacks |
4874 | def setUp(self): |
4875 | yield super(ReturnCodeTestCase, self).setUp() |
4876 | @@ -2081,7 +2081,7 @@ |
4877 | |
4878 | def test_closing_main_window(self): |
4879 | """When closing the main window, USER_CANCELLATION is called.""" |
4880 | - self.ui.window.emit('delete-event', gtk.gdk.Event(gtk.gdk.DELETE)) |
4881 | + self.ui.window.emit('delete-event', Gdk.Event()) |
4882 | self.assertEqual(self._called, ((gui.USER_CANCELLATION,), {})) |
4883 | |
4884 | def test_every_cancel_calls_proper_callback(self): |
4885 | @@ -2108,7 +2108,7 @@ |
4886 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) |
4887 | self.ui.on_close_clicked() |
4888 | |
4889 | - self.assertEqual(self._called, ((gui.REGISTRATION_SUCCESS,), {})) |
4890 | + self.assertEqual(self._called, ((gui.USER_SUCCESS,), {})) |
4891 | |
4892 | def test_on_email_validation_error_proper_callback_is_called(self): |
4893 | """On EmailValidationError, USER_CANCELLATION is called.""" |
4894 | @@ -2122,7 +2122,7 @@ |
4895 | self.ui.on_logged_in(app_name=APP_NAME, email=EMAIL) |
4896 | self.ui.on_close_clicked() |
4897 | |
4898 | - self.assertEqual(self._called, ((gui.LOGIN_SUCCESS,), {})) |
4899 | + self.assertEqual(self._called, ((gui.USER_SUCCESS,), {})) |
4900 | |
4901 | def test_on_login_error_proper_callback_is_called(self): |
4902 | """On LoginError, USER_CANCELLATION is called.""" |
4903 | @@ -2145,7 +2145,7 @@ |
4904 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) |
4905 | self.ui.on_close_clicked() |
4906 | |
4907 | - self.assertEqual(self._called, ((gui.REGISTRATION_SUCCESS,), {})) |
4908 | + self.assertEqual(self._called, ((gui.USER_SUCCESS,), {})) |
4909 | |
4910 | def test_login_success_even_if_prior_login_error(self): |
4911 | """Only one callback is called with the final outcome. |
4912 | @@ -2160,7 +2160,7 @@ |
4913 | self.ui.on_logged_in(app_name=APP_NAME, email=EMAIL) |
4914 | self.ui.on_close_clicked() |
4915 | |
4916 | - self.assertEqual(self._called, ((gui.LOGIN_SUCCESS,), {})) |
4917 | + self.assertEqual(self._called, ((gui.USER_SUCCESS,), {})) |
4918 | |
4919 | def test_user_cancelation_even_if_prior_registration_error(self): |
4920 | """Only one callback is called with the final outcome. |
4921 | |
4922 | === added file 'ubuntu_sso/gtk/tests/test_main.py' |
4923 | --- ubuntu_sso/gtk/tests/test_main.py 1970-01-01 00:00:00 +0000 |
4924 | +++ ubuntu_sso/gtk/tests/test_main.py 2012-02-14 22:04:20 +0000 |
4925 | @@ -0,0 +1,39 @@ |
4926 | +# -*- coding: utf-8 -*- |
4927 | +# |
4928 | +# Copyright 2012 Canonical Ltd. |
4929 | +# |
4930 | +# This program is free software: you can redistribute it and/or modify it |
4931 | +# under the terms of the GNU General Public License version 3, as published |
4932 | +# by the Free Software Foundation. |
4933 | +# |
4934 | +# This program is distributed in the hope that it will be useful, but |
4935 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
4936 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4937 | +# PURPOSE. See the GNU General Public License for more details. |
4938 | +# |
4939 | +# You should have received a copy of the GNU General Public License along |
4940 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
4941 | + |
4942 | +"""Tests for the main module.""" |
4943 | + |
4944 | +from twisted.trial.unittest import TestCase |
4945 | + |
4946 | +from ubuntu_sso.gtk import main |
4947 | + |
4948 | + |
4949 | +class BasicTestCase(TestCase): |
4950 | + """Test case with a helper tracker.""" |
4951 | + |
4952 | + def test_main(self): |
4953 | + """Calling main.main() a UI instance is created.""" |
4954 | + called = [] |
4955 | + self.patch(main, 'UbuntuSSOClientGUI', |
4956 | + lambda **kw: called.append(('GUI', kw))) |
4957 | + self.patch(main.Gtk, 'main', |
4958 | + lambda: called.append('main')) |
4959 | + |
4960 | + kwargs = dict(foo='foo', bar='bar', baz='yadda', yadda=0) |
4961 | + main.main(**kwargs) |
4962 | + |
4963 | + kwargs['close_callback'] = main.Gtk.main_quit |
4964 | + self.assertEqual(called, [('GUI', kwargs), 'main']) |
4965 | |
4966 | === modified file 'ubuntu_sso/keyring/__init__.py' |
4967 | --- ubuntu_sso/keyring/__init__.py 2011-10-17 18:24:55 +0000 |
4968 | +++ ubuntu_sso/keyring/__init__.py 2012-02-14 22:04:20 +0000 |
4969 | @@ -29,8 +29,8 @@ |
4970 | |
4971 | logger = setup_logging("ubuntu_sso.keyring") |
4972 | |
4973 | -TOKEN_SEPARATOR = ' @ ' |
4974 | -SEPARATOR_REPLACEMENT = ' AT ' |
4975 | +TOKEN_SEPARATOR = u' @ ' |
4976 | +SEPARATOR_REPLACEMENT = u' AT ' |
4977 | |
4978 | U1_APP_NAME = "Ubuntu One" |
4979 | U1_KEY_NAME = "UbuntuOne token for https://ubuntuone.com" |
4980 | @@ -41,26 +41,34 @@ |
4981 | |
4982 | |
4983 | def gethostname(): |
4984 | - """Get the hostname, encoded in utf-8.""" |
4985 | + """Get the hostname, return the name as unicode.""" |
4986 | sys_encoding = sys.getfilesystemencoding() |
4987 | hostname = socket.gethostname().decode(sys_encoding) |
4988 | - return hostname.encode("utf-8") |
4989 | + return hostname |
4990 | |
4991 | |
4992 | def get_old_token_name(app_name): |
4993 | - """Build the token name (old style).""" |
4994 | + """Build the token name (old style). Return an unicode.""" |
4995 | quoted_app_name = urllib.quote(app_name) |
4996 | computer_name = gethostname() |
4997 | quoted_computer_name = urllib.quote(computer_name) |
4998 | - return "%s - %s" % (quoted_app_name, quoted_computer_name) |
4999 | + |
5000 | + assert isinstance(computer_name, unicode) |
+1