Merge lp:~dobey/ubuntu/natty/ubuntuone-control-panel/release-0-9-1 into lp:ubuntu/natty/ubuntuone-control-panel
- Natty (11.04)
- release-0-9-1
- Merge into natty
Proposed by
dobey
Status: | Merged |
---|---|
Merged at revision: | 15 |
Proposed branch: | lp:~dobey/ubuntu/natty/ubuntuone-control-panel/release-0-9-1 |
Merge into: | lp:ubuntu/natty/ubuntuone-control-panel |
Diff against target: |
4681 lines (+2189/-1405) 20 files modified
PKG-INFO (+1/-1) bin/ubuntuone-control-panel-gtk (+4/-2) data/dashboard.ui (+5/-138) data/device.ui (+160/-122) data/management.ui (+214/-101) data/overview.ui (+292/-223) data/services.ui (+309/-14) data/volumes.ui (+20/-20) debian/changelog (+24/-0) debian/control (+4/-4) pylintrc (+1/-1) setup.py (+1/-1) ubuntuone/__init__.py (+0/-1) ubuntuone/controlpanel/backend.py (+5/-1) ubuntuone/controlpanel/gtk/gui.py (+215/-90) ubuntuone/controlpanel/gtk/tests/__init__.py (+92/-7) ubuntuone/controlpanel/gtk/tests/test_gui.py (+235/-670) ubuntuone/controlpanel/gtk/tests/test_gui_basic.py (+595/-0) ubuntuone/controlpanel/tests/__init__.py (+11/-8) ubuntuone/controlpanel/tests/test_backend.py (+1/-1) |
To merge this branch: | bzr merge lp:~dobey/ubuntu/natty/ubuntuone-control-panel/release-0-9-1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Holbach (community) | Approve | ||
Review via email: mp+52795@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'PKG-INFO' |
2 | --- PKG-INFO 2011-02-28 15:38:15 +0000 |
3 | +++ PKG-INFO 2011-03-10 03:11:54 +0000 |
4 | @@ -1,6 +1,6 @@ |
5 | Metadata-Version: 1.1 |
6 | Name: ubuntuone-control-panel |
7 | -Version: 0.9.0 |
8 | +Version: 0.9.1 |
9 | Summary: Ubuntu One Control Panel |
10 | Home-page: https://launchpad.net/ubuntuone-control-panel |
11 | Author: Natalia Bidart |
12 | |
13 | === modified file 'bin/ubuntuone-control-panel-gtk' |
14 | --- bin/ubuntuone-control-panel-gtk 2011-01-25 19:08:59 +0000 |
15 | +++ bin/ubuntuone-control-panel-gtk 2011-03-10 03:11:54 +0000 |
16 | @@ -40,12 +40,14 @@ |
17 | help="Start the Ubuntu One Control Panel (GTK) in the " |
18 | "PANEL_NAME tab. Possible values are: " |
19 | "dashboard, volumes, devices, applications") |
20 | + result.add_option("-a", "--alert", dest="alert", action="store_true", |
21 | + help="Start the Ubuntu One Control Panel (GTK) alerting " |
22 | + "the user to its presence.") |
23 | return result |
24 | |
25 | |
26 | if __name__ == "__main__": |
27 | parser = parser_options() |
28 | (options, args) = parser.parse_args(sys.argv) |
29 | - |
30 | - gui = ControlPanelWindow(switch_to=options.switch_to) |
31 | + gui = ControlPanelWindow(switch_to=options.switch_to, alert=options.alert) |
32 | gui.main() |
33 | |
34 | === removed file 'data/banner.png' |
35 | Binary files data/banner.png 2011-02-28 15:38:15 +0000 and data/banner.png 1970-01-01 00:00:00 +0000 differ |
36 | === modified file 'data/contacts.png' |
37 | Binary files data/contacts.png 2011-02-12 03:07:22 +0000 and data/contacts.png 2011-03-10 03:11:54 +0000 differ |
38 | === modified file 'data/dashboard.ui' |
39 | --- data/dashboard.ui 2011-02-28 15:38:15 +0000 |
40 | +++ data/dashboard.ui 2011-03-10 03:11:54 +0000 |
41 | @@ -5,8 +5,6 @@ |
42 | <object class="GtkVBox" id="itself"> |
43 | <property name="visible">True</property> |
44 | <property name="can_focus">False</property> |
45 | - <property name="border_width">10</property> |
46 | - <property name="spacing">10</property> |
47 | <child> |
48 | <object class="GtkHBox" id="account"> |
49 | <property name="visible">True</property> |
50 | @@ -59,12 +57,13 @@ |
51 | </child> |
52 | <child> |
53 | <object class="GtkLinkButton" id="linkbutton3"> |
54 | - <property name="label" translatable="yes">Edit</property> |
55 | + <property name="label" translatable="yes">Edit account details</property> |
56 | <property name="visible">True</property> |
57 | <property name="can_focus">True</property> |
58 | <property name="receives_default">True</property> |
59 | + <property name="tooltip_text" translatable="yes">Edit your account details</property> |
60 | <property name="use_action_appearance">False</property> |
61 | - <property name="relief">none</property> |
62 | + <property name="relief">half</property> |
63 | <property name="uri">http://login.ubuntu.com</property> |
64 | </object> |
65 | <packing> |
66 | @@ -131,8 +130,9 @@ |
67 | <property name="visible">True</property> |
68 | <property name="can_focus">True</property> |
69 | <property name="receives_default">True</property> |
70 | + <property name="tooltip_text" translatable="yes">Upgrade the storage space on your account</property> |
71 | <property name="use_action_appearance">False</property> |
72 | - <property name="relief">none</property> |
73 | + <property name="relief">half</property> |
74 | <property name="uri">https://one.ubuntu.com/plans/</property> |
75 | </object> |
76 | <packing> |
77 | @@ -169,138 +169,5 @@ |
78 | <property name="position">0</property> |
79 | </packing> |
80 | </child> |
81 | - <child> |
82 | - <object class="GtkAlignment" id="alignment5"> |
83 | - <property name="visible">True</property> |
84 | - <property name="can_focus">False</property> |
85 | - <child> |
86 | - <object class="GtkHBox" id="hbox1"> |
87 | - <property name="visible">True</property> |
88 | - <property name="can_focus">False</property> |
89 | - <property name="spacing">20</property> |
90 | - <child> |
91 | - <object class="GtkHButtonBox" id="hbuttonbox3"> |
92 | - <property name="visible">True</property> |
93 | - <property name="can_focus">False</property> |
94 | - <property name="spacing">5</property> |
95 | - <child> |
96 | - <object class="GtkLinkButton" id="linkbutton2"> |
97 | - <property name="label" translatable="yes">Official Support</property> |
98 | - <property name="visible">True</property> |
99 | - <property name="can_focus">True</property> |
100 | - <property name="receives_default">True</property> |
101 | - <property name="tooltip_text" translatable="yes">Get official Ubuntu One support online</property> |
102 | - <property name="use_action_appearance">False</property> |
103 | - <property name="uri">https://one.ubuntu.com/support/</property> |
104 | - </object> |
105 | - <packing> |
106 | - <property name="expand">False</property> |
107 | - <property name="fill">False</property> |
108 | - <property name="position">0</property> |
109 | - </packing> |
110 | - </child> |
111 | - <child> |
112 | - <object class="GtkLinkButton" id="linkbutton4"> |
113 | - <property name="label" translatable="yes">Community Support</property> |
114 | - <property name="visible">True</property> |
115 | - <property name="can_focus">True</property> |
116 | - <property name="receives_default">True</property> |
117 | - <property name="tooltip_text" translatable="yes">View and ask Ubuntu One related questions at AskUbuntu.com</property> |
118 | - <property name="use_action_appearance">False</property> |
119 | - <property name="uri">http://askubuntu.com/questions/tagged/ubuntu-one</property> |
120 | - </object> |
121 | - <packing> |
122 | - <property name="expand">False</property> |
123 | - <property name="fill">False</property> |
124 | - <property name="position">1</property> |
125 | - </packing> |
126 | - </child> |
127 | - </object> |
128 | - <packing> |
129 | - <property name="expand">False</property> |
130 | - <property name="fill">True</property> |
131 | - <property name="position">0</property> |
132 | - </packing> |
133 | - </child> |
134 | - <child> |
135 | - <object class="GtkHBox" id="hbox2"> |
136 | - <property name="visible">True</property> |
137 | - <property name="can_focus">False</property> |
138 | - <child> |
139 | - <object class="GtkLabel" id="label4"> |
140 | - <property name="visible">True</property> |
141 | - <property name="can_focus">False</property> |
142 | - <property name="label" translatable="yes">Talk to us on:</property> |
143 | - </object> |
144 | - <packing> |
145 | - <property name="expand">True</property> |
146 | - <property name="fill">True</property> |
147 | - <property name="position">0</property> |
148 | - </packing> |
149 | - </child> |
150 | - <child> |
151 | - <object class="GtkLinkButton" id="linkbutton5"> |
152 | - <property name="visible">True</property> |
153 | - <property name="can_focus">True</property> |
154 | - <property name="receives_default">True</property> |
155 | - <property name="use_action_appearance">False</property> |
156 | - <property name="relief">none</property> |
157 | - <property name="uri">http://twitter.com/ubuntuone</property> |
158 | - <child> |
159 | - <object class="GtkImage" id="twitter"> |
160 | - <property name="visible">True</property> |
161 | - <property name="can_focus">False</property> |
162 | - <property name="tooltip_text" translatable="yes">http://twitter.com/ubuntuone</property> |
163 | - <property name="pixbuf">twitter.png</property> |
164 | - </object> |
165 | - </child> |
166 | - </object> |
167 | - <packing> |
168 | - <property name="expand">False</property> |
169 | - <property name="fill">False</property> |
170 | - <property name="position">1</property> |
171 | - </packing> |
172 | - </child> |
173 | - <child> |
174 | - <object class="GtkLinkButton" id="linkbutton6"> |
175 | - <property name="visible">True</property> |
176 | - <property name="can_focus">True</property> |
177 | - <property name="receives_default">True</property> |
178 | - <property name="use_action_appearance">False</property> |
179 | - <property name="relief">none</property> |
180 | - <property name="uri">http://www.facebook.com/ubuntuone</property> |
181 | - <child> |
182 | - <object class="GtkImage" id="facebook"> |
183 | - <property name="visible">True</property> |
184 | - <property name="can_focus">False</property> |
185 | - <property name="tooltip_text" translatable="yes">http://www.facebook.com/ubuntuone</property> |
186 | - <property name="pixbuf">facebook.png</property> |
187 | - </object> |
188 | - </child> |
189 | - </object> |
190 | - <packing> |
191 | - <property name="expand">True</property> |
192 | - <property name="fill">True</property> |
193 | - <property name="position">2</property> |
194 | - </packing> |
195 | - </child> |
196 | - </object> |
197 | - <packing> |
198 | - <property name="expand">False</property> |
199 | - <property name="fill">True</property> |
200 | - <property name="pack_type">end</property> |
201 | - <property name="position">1</property> |
202 | - </packing> |
203 | - </child> |
204 | - </object> |
205 | - </child> |
206 | - </object> |
207 | - <packing> |
208 | - <property name="expand">False</property> |
209 | - <property name="fill">True</property> |
210 | - <property name="pack_type">end</property> |
211 | - <property name="position">1</property> |
212 | - </packing> |
213 | - </child> |
214 | </object> |
215 | </interface> |
216 | |
217 | === modified file 'data/device.ui' |
218 | --- data/device.ui 2011-02-23 13:57:42 +0000 |
219 | +++ data/device.ui 2011-03-10 03:11:54 +0000 |
220 | @@ -12,174 +12,203 @@ |
221 | </object> |
222 | <object class="GtkVBox" id="itself"> |
223 | <property name="visible">True</property> |
224 | + <property name="can_focus">False</property> |
225 | <property name="border_width">10</property> |
226 | <property name="spacing">5</property> |
227 | <child> |
228 | <object class="GtkHBox" id="hbox1"> |
229 | <property name="visible">True</property> |
230 | + <property name="can_focus">False</property> |
231 | <property name="spacing">10</property> |
232 | <child> |
233 | <object class="GtkVBox" id="vbox1"> |
234 | <property name="visible">True</property> |
235 | + <property name="can_focus">False</property> |
236 | <property name="spacing">5</property> |
237 | <child> |
238 | <object class="GtkHBox" id="hbox2"> |
239 | <property name="visible">True</property> |
240 | + <property name="can_focus">False</property> |
241 | <child> |
242 | <object class="GtkImage" id="device_type"> |
243 | <property name="visible">True</property> |
244 | + <property name="can_focus">False</property> |
245 | <property name="icon_name">computer</property> |
246 | </object> |
247 | <packing> |
248 | <property name="expand">False</property> |
249 | + <property name="fill">True</property> |
250 | <property name="position">0</property> |
251 | </packing> |
252 | </child> |
253 | <child> |
254 | <object class="GtkLabel" id="device_name"> |
255 | <property name="visible">True</property> |
256 | + <property name="can_focus">False</property> |
257 | <property name="xalign">0</property> |
258 | <property name="xpad">5</property> |
259 | <property name="label">My Laptop</property> |
260 | <property name="wrap">True</property> |
261 | </object> |
262 | <packing> |
263 | + <property name="expand">True</property> |
264 | + <property name="fill">True</property> |
265 | <property name="position">1</property> |
266 | </packing> |
267 | </child> |
268 | </object> |
269 | <packing> |
270 | + <property name="expand">True</property> |
271 | + <property name="fill">True</property> |
272 | <property name="position">0</property> |
273 | </packing> |
274 | </child> |
275 | <child> |
276 | <object class="GtkAlignment" id="alignment1"> |
277 | <property name="visible">True</property> |
278 | + <property name="can_focus">False</property> |
279 | <property name="left_padding">25</property> |
280 | <child> |
281 | - <object class="GtkTable" id="throttling"> |
282 | + <object class="GtkVBox" id="config_settings"> |
283 | <property name="visible">True</property> |
284 | - <property name="n_rows">4</property> |
285 | - <property name="n_columns">3</property> |
286 | - <property name="column_spacing">3</property> |
287 | - <property name="row_spacing">3</property> |
288 | + <property name="can_focus">False</property> |
289 | <child> |
290 | <object class="GtkCheckButton" id="show_all_notifications"> |
291 | - <property name="label" translatable="yes">Show notifications</property> |
292 | - <property name="visible">True</property> |
293 | - <property name="can_focus">True</property> |
294 | - <property name="receives_default">False</property> |
295 | - <property name="draw_indicator">True</property> |
296 | - <signal name="toggled" handler="on_show_all_notifications_toggled"/> |
297 | - </object> |
298 | - </child> |
299 | - <child> |
300 | - <object class="GtkCheckButton" id="limit_bandwidth"> |
301 | - <property name="label" translatable="yes">Limit bandwidth usage</property> |
302 | - <property name="visible">True</property> |
303 | - <property name="can_focus">True</property> |
304 | - <property name="receives_default">False</property> |
305 | - <property name="draw_indicator">True</property> |
306 | - <signal name="toggled" handler="on_limit_bandwidth_toggled"/> |
307 | - </object> |
308 | - <packing> |
309 | - <property name="top_attach">1</property> |
310 | - <property name="bottom_attach">2</property> |
311 | - </packing> |
312 | - </child> |
313 | - <child> |
314 | - <object class="GtkLabel" id="max_upload_speed_label"> |
315 | - <property name="visible">True</property> |
316 | - <property name="xalign">0</property> |
317 | - <property name="label" translatable="yes">Max upload speed:</property> |
318 | - <property name="track_visited_links">False</property> |
319 | - </object> |
320 | - <packing> |
321 | - <property name="top_attach">2</property> |
322 | - <property name="bottom_attach">3</property> |
323 | - </packing> |
324 | - </child> |
325 | - <child> |
326 | - <object class="GtkLabel" id="max_download_speed_label"> |
327 | - <property name="visible">True</property> |
328 | - <property name="xalign">0</property> |
329 | - <property name="label" translatable="yes">Max download speed:</property> |
330 | - </object> |
331 | - <packing> |
332 | - <property name="top_attach">3</property> |
333 | - <property name="bottom_attach">4</property> |
334 | - </packing> |
335 | - </child> |
336 | - <child> |
337 | - <object class="GtkSpinButton" id="max_upload_speed"> |
338 | - <property name="visible">True</property> |
339 | - <property name="can_focus">True</property> |
340 | - <property name="invisible_char">•</property> |
341 | - <property name="activates_default">True</property> |
342 | - <property name="invisible_char_set">True</property> |
343 | - <property name="adjustment">adjustment1</property> |
344 | - <signal name="value_changed" handler="on_max_upload_speed_value_changed"/> |
345 | - </object> |
346 | - <packing> |
347 | - <property name="left_attach">1</property> |
348 | - <property name="right_attach">2</property> |
349 | - <property name="top_attach">2</property> |
350 | - <property name="bottom_attach">3</property> |
351 | - <property name="x_options">GTK_FILL</property> |
352 | - <property name="y_options">GTK_FILL</property> |
353 | - </packing> |
354 | - </child> |
355 | - <child> |
356 | - <object class="GtkSpinButton" id="max_download_speed"> |
357 | - <property name="visible">True</property> |
358 | - <property name="can_focus">True</property> |
359 | - <property name="invisible_char">•</property> |
360 | - <property name="activates_default">True</property> |
361 | - <property name="invisible_char_set">True</property> |
362 | - <property name="adjustment">adjustment2</property> |
363 | - <signal name="value_changed" handler="on_max_download_speed_value_changed"/> |
364 | - </object> |
365 | - <packing> |
366 | - <property name="left_attach">1</property> |
367 | - <property name="right_attach">2</property> |
368 | - <property name="top_attach">3</property> |
369 | - <property name="bottom_attach">4</property> |
370 | - </packing> |
371 | - </child> |
372 | - <child> |
373 | - <placeholder/> |
374 | - </child> |
375 | - <child> |
376 | - <placeholder/> |
377 | - </child> |
378 | - <child> |
379 | - <placeholder/> |
380 | - </child> |
381 | - <child> |
382 | - <placeholder/> |
383 | - </child> |
384 | - <child> |
385 | - <object class="GtkLabel" id="label1"> |
386 | - <property name="visible">True</property> |
387 | - <property name="label" translatable="yes">KiB/s</property> |
388 | - </object> |
389 | - <packing> |
390 | - <property name="left_attach">2</property> |
391 | - <property name="right_attach">3</property> |
392 | - <property name="top_attach">2</property> |
393 | - <property name="bottom_attach">3</property> |
394 | - </packing> |
395 | - </child> |
396 | - <child> |
397 | - <object class="GtkLabel" id="label2"> |
398 | - <property name="visible">True</property> |
399 | - <property name="label" translatable="yes">KiB/s</property> |
400 | - </object> |
401 | - <packing> |
402 | - <property name="left_attach">2</property> |
403 | - <property name="right_attach">3</property> |
404 | - <property name="top_attach">3</property> |
405 | - <property name="bottom_attach">4</property> |
406 | + <property name="label" translatable="yes">Show activity notifications</property> |
407 | + <property name="visible">True</property> |
408 | + <property name="can_focus">True</property> |
409 | + <property name="receives_default">False</property> |
410 | + <property name="use_action_appearance">False</property> |
411 | + <property name="draw_indicator">True</property> |
412 | + <signal name="toggled" handler="on_show_all_notifications_toggled" swapped="no"/> |
413 | + </object> |
414 | + <packing> |
415 | + <property name="expand">True</property> |
416 | + <property name="fill">True</property> |
417 | + <property name="position">0</property> |
418 | + </packing> |
419 | + </child> |
420 | + <child> |
421 | + <object class="GtkVBox" id="throttling"> |
422 | + <property name="visible">True</property> |
423 | + <property name="can_focus">False</property> |
424 | + <child> |
425 | + <object class="GtkCheckButton" id="limit_bandwidth"> |
426 | + <property name="label" translatable="yes">Limit file sync bandwidth usage</property> |
427 | + <property name="visible">True</property> |
428 | + <property name="can_focus">True</property> |
429 | + <property name="receives_default">False</property> |
430 | + <property name="use_action_appearance">False</property> |
431 | + <property name="draw_indicator">True</property> |
432 | + <signal name="toggled" handler="on_limit_bandwidth_toggled" swapped="no"/> |
433 | + </object> |
434 | + <packing> |
435 | + <property name="expand">True</property> |
436 | + <property name="fill">True</property> |
437 | + <property name="position">0</property> |
438 | + </packing> |
439 | + </child> |
440 | + <child> |
441 | + <object class="GtkTable" id="throttling_limits"> |
442 | + <property name="visible">True</property> |
443 | + <property name="can_focus">False</property> |
444 | + <property name="n_rows">2</property> |
445 | + <property name="n_columns">3</property> |
446 | + <property name="column_spacing">3</property> |
447 | + <property name="row_spacing">3</property> |
448 | + <child> |
449 | + <object class="GtkLabel" id="max_upload_speed_label"> |
450 | + <property name="visible">True</property> |
451 | + <property name="can_focus">False</property> |
452 | + <property name="xalign">0</property> |
453 | + <property name="xpad">22</property> |
454 | + <property name="label" translatable="yes">Max upload speed:</property> |
455 | + <property name="track_visited_links">False</property> |
456 | + </object> |
457 | + </child> |
458 | + <child> |
459 | + <object class="GtkLabel" id="max_download_speed_label"> |
460 | + <property name="visible">True</property> |
461 | + <property name="can_focus">False</property> |
462 | + <property name="xalign">0</property> |
463 | + <property name="xpad">22</property> |
464 | + <property name="label" translatable="yes">Max download speed:</property> |
465 | + </object> |
466 | + <packing> |
467 | + <property name="top_attach">1</property> |
468 | + <property name="bottom_attach">2</property> |
469 | + </packing> |
470 | + </child> |
471 | + <child> |
472 | + <object class="GtkSpinButton" id="max_upload_speed"> |
473 | + <property name="visible">True</property> |
474 | + <property name="can_focus">True</property> |
475 | + <property name="invisible_char">•</property> |
476 | + <property name="activates_default">True</property> |
477 | + <property name="invisible_char_set">True</property> |
478 | + <property name="adjustment">adjustment1</property> |
479 | + <signal name="value-changed" handler="on_max_upload_speed_value_changed" swapped="no"/> |
480 | + </object> |
481 | + <packing> |
482 | + <property name="left_attach">1</property> |
483 | + <property name="right_attach">2</property> |
484 | + <property name="x_options">GTK_FILL</property> |
485 | + <property name="y_options">GTK_FILL</property> |
486 | + </packing> |
487 | + </child> |
488 | + <child> |
489 | + <object class="GtkSpinButton" id="max_download_speed"> |
490 | + <property name="visible">True</property> |
491 | + <property name="can_focus">True</property> |
492 | + <property name="invisible_char">•</property> |
493 | + <property name="activates_default">True</property> |
494 | + <property name="invisible_char_set">True</property> |
495 | + <property name="adjustment">adjustment2</property> |
496 | + <signal name="value-changed" handler="on_max_download_speed_value_changed" swapped="no"/> |
497 | + </object> |
498 | + <packing> |
499 | + <property name="left_attach">1</property> |
500 | + <property name="right_attach">2</property> |
501 | + <property name="top_attach">1</property> |
502 | + <property name="bottom_attach">2</property> |
503 | + </packing> |
504 | + </child> |
505 | + <child> |
506 | + <object class="GtkLabel" id="label1"> |
507 | + <property name="visible">True</property> |
508 | + <property name="can_focus">False</property> |
509 | + <property name="label" translatable="yes">KiB/s</property> |
510 | + </object> |
511 | + <packing> |
512 | + <property name="left_attach">2</property> |
513 | + <property name="right_attach">3</property> |
514 | + </packing> |
515 | + </child> |
516 | + <child> |
517 | + <object class="GtkLabel" id="label2"> |
518 | + <property name="visible">True</property> |
519 | + <property name="can_focus">False</property> |
520 | + <property name="label" translatable="yes">KiB/s</property> |
521 | + </object> |
522 | + <packing> |
523 | + <property name="left_attach">2</property> |
524 | + <property name="right_attach">3</property> |
525 | + <property name="top_attach">1</property> |
526 | + <property name="bottom_attach">2</property> |
527 | + </packing> |
528 | + </child> |
529 | + </object> |
530 | + <packing> |
531 | + <property name="expand">True</property> |
532 | + <property name="fill">True</property> |
533 | + <property name="position">1</property> |
534 | + </packing> |
535 | + </child> |
536 | + </object> |
537 | + <packing> |
538 | + <property name="expand">True</property> |
539 | + <property name="fill">True</property> |
540 | + <property name="position">1</property> |
541 | </packing> |
542 | </child> |
543 | </object> |
544 | @@ -187,18 +216,21 @@ |
545 | </object> |
546 | <packing> |
547 | <property name="expand">False</property> |
548 | + <property name="fill">True</property> |
549 | <property name="position">1</property> |
550 | </packing> |
551 | </child> |
552 | </object> |
553 | <packing> |
554 | <property name="expand">False</property> |
555 | + <property name="fill">True</property> |
556 | <property name="position">0</property> |
557 | </packing> |
558 | </child> |
559 | <child> |
560 | <object class="GtkVButtonBox" id="vbuttonbox1"> |
561 | <property name="visible">True</property> |
562 | + <property name="can_focus">False</property> |
563 | <property name="layout_style">start</property> |
564 | <child> |
565 | <object class="GtkButton" id="remove"> |
566 | @@ -206,9 +238,10 @@ |
567 | <property name="visible">True</property> |
568 | <property name="can_focus">True</property> |
569 | <property name="receives_default">True</property> |
570 | + <property name="use_action_appearance">False</property> |
571 | <property name="use_stock">True</property> |
572 | - <signal name="clicked" handler="on_remove_clicked"/> |
573 | - <signal name="activate" handler="on_remove_clicked"/> |
574 | + <signal name="activate" handler="on_remove_clicked" swapped="no"/> |
575 | + <signal name="clicked" handler="on_remove_clicked" swapped="no"/> |
576 | </object> |
577 | <packing> |
578 | <property name="expand">False</property> |
579 | @@ -219,6 +252,7 @@ |
580 | </object> |
581 | <packing> |
582 | <property name="expand">False</property> |
583 | + <property name="fill">True</property> |
584 | <property name="pack_type">end</property> |
585 | <property name="position">1</property> |
586 | </packing> |
587 | @@ -226,14 +260,18 @@ |
588 | </object> |
589 | <packing> |
590 | <property name="expand">False</property> |
591 | + <property name="fill">True</property> |
592 | <property name="position">0</property> |
593 | </packing> |
594 | </child> |
595 | <child> |
596 | <object class="GtkLabel" id="warning_label"> |
597 | <property name="visible">True</property> |
598 | + <property name="can_focus">False</property> |
599 | </object> |
600 | <packing> |
601 | + <property name="expand">True</property> |
602 | + <property name="fill">True</property> |
603 | <property name="position">1</property> |
604 | </packing> |
605 | </child> |
606 | |
607 | === modified file 'data/files.png' |
608 | Binary files data/files.png 2011-02-12 03:07:22 +0000 and data/files.png 2011-03-10 03:11:54 +0000 differ |
609 | === modified file 'data/management.ui' |
610 | --- data/management.ui 2011-02-23 13:57:42 +0000 |
611 | +++ data/management.ui 2011-03-10 03:11:54 +0000 |
612 | @@ -50,143 +50,120 @@ |
613 | </packing> |
614 | </child> |
615 | <child> |
616 | - <object class="GtkVBox" id="vbox1"> |
617 | + <object class="GtkHBox" id="hbox2"> |
618 | <property name="visible">True</property> |
619 | <property name="can_focus">False</property> |
620 | <child> |
621 | - <object class="GtkHBox" id="hbox2"> |
622 | - <property name="visible">True</property> |
623 | - <property name="can_focus">False</property> |
624 | + <object class="GtkHSeparator" id="hseparator1"> |
625 | + <property name="visible">True</property> |
626 | + <property name="can_focus">False</property> |
627 | + </object> |
628 | + <packing> |
629 | + <property name="expand">True</property> |
630 | + <property name="fill">True</property> |
631 | + <property name="position">0</property> |
632 | + </packing> |
633 | + </child> |
634 | + <child> |
635 | + <object class="GtkHButtonBox" id="hbuttonbox1"> |
636 | + <property name="visible">True</property> |
637 | + <property name="can_focus">False</property> |
638 | + <property name="layout_style">center</property> |
639 | <child> |
640 | - <object class="GtkHSeparator" id="hseparator1"> |
641 | + <object class="GtkRadioButton" id="dashboard_button"> |
642 | + <property name="label" translatable="yes">Account</property> |
643 | <property name="visible">True</property> |
644 | - <property name="can_focus">False</property> |
645 | + <property name="can_focus">True</property> |
646 | + <property name="receives_default">False</property> |
647 | + <property name="use_action_appearance">False</property> |
648 | + <property name="active">True</property> |
649 | + <property name="draw_indicator">False</property> |
650 | </object> |
651 | <packing> |
652 | - <property name="expand">True</property> |
653 | - <property name="fill">True</property> |
654 | + <property name="expand">False</property> |
655 | + <property name="fill">False</property> |
656 | <property name="position">0</property> |
657 | </packing> |
658 | </child> |
659 | <child> |
660 | - <object class="GtkHButtonBox" id="hbuttonbox1"> |
661 | + <object class="GtkRadioButton" id="volumes_button"> |
662 | + <property name="label" translatable="yes">Cloud Folders</property> |
663 | <property name="visible">True</property> |
664 | - <property name="can_focus">False</property> |
665 | - <property name="layout_style">center</property> |
666 | - <child> |
667 | - <object class="GtkRadioButton" id="dashboard_button"> |
668 | - <property name="label" translatable="yes">Account</property> |
669 | - <property name="visible">True</property> |
670 | - <property name="can_focus">True</property> |
671 | - <property name="receives_default">False</property> |
672 | - <property name="use_action_appearance">False</property> |
673 | - <property name="active">True</property> |
674 | - <property name="draw_indicator">False</property> |
675 | - </object> |
676 | - <packing> |
677 | - <property name="expand">False</property> |
678 | - <property name="fill">False</property> |
679 | - <property name="position">0</property> |
680 | - </packing> |
681 | - </child> |
682 | - <child> |
683 | - <object class="GtkRadioButton" id="volumes_button"> |
684 | - <property name="label" translatable="yes">Cloud Folders</property> |
685 | - <property name="visible">True</property> |
686 | - <property name="can_focus">True</property> |
687 | - <property name="receives_default">False</property> |
688 | - <property name="use_action_appearance">False</property> |
689 | - <property name="draw_indicator">False</property> |
690 | - <property name="group">dashboard_button</property> |
691 | - </object> |
692 | - <packing> |
693 | - <property name="expand">False</property> |
694 | - <property name="fill">False</property> |
695 | - <property name="position">1</property> |
696 | - </packing> |
697 | - </child> |
698 | - <child> |
699 | - <object class="GtkRadioButton" id="shares_button"> |
700 | - <property name="label" translatable="yes">Shares</property> |
701 | - <property name="can_focus">True</property> |
702 | - <property name="receives_default">False</property> |
703 | - <property name="use_action_appearance">False</property> |
704 | - <property name="draw_indicator">False</property> |
705 | - <property name="group">dashboard_button</property> |
706 | - </object> |
707 | - <packing> |
708 | - <property name="expand">False</property> |
709 | - <property name="fill">False</property> |
710 | - <property name="position">2</property> |
711 | - </packing> |
712 | - </child> |
713 | - <child> |
714 | - <object class="GtkRadioButton" id="devices_button"> |
715 | - <property name="label" translatable="yes">Devices</property> |
716 | - <property name="visible">True</property> |
717 | - <property name="can_focus">True</property> |
718 | - <property name="receives_default">False</property> |
719 | - <property name="use_action_appearance">False</property> |
720 | - <property name="draw_indicator">False</property> |
721 | - <property name="group">dashboard_button</property> |
722 | - </object> |
723 | - <packing> |
724 | - <property name="expand">False</property> |
725 | - <property name="fill">False</property> |
726 | - <property name="position">3</property> |
727 | - </packing> |
728 | - </child> |
729 | - <child> |
730 | - <object class="GtkRadioButton" id="services_button"> |
731 | - <property name="label" translatable="yes">Services</property> |
732 | - <property name="visible">True</property> |
733 | - <property name="can_focus">True</property> |
734 | - <property name="receives_default">False</property> |
735 | - <property name="use_action_appearance">False</property> |
736 | - <property name="draw_indicator">False</property> |
737 | - <property name="group">dashboard_button</property> |
738 | - </object> |
739 | - <packing> |
740 | - <property name="expand">False</property> |
741 | - <property name="fill">False</property> |
742 | - <property name="position">4</property> |
743 | - </packing> |
744 | - </child> |
745 | + <property name="can_focus">True</property> |
746 | + <property name="receives_default">False</property> |
747 | + <property name="use_action_appearance">False</property> |
748 | + <property name="draw_indicator">False</property> |
749 | + <property name="group">dashboard_button</property> |
750 | </object> |
751 | <packing> |
752 | <property name="expand">False</property> |
753 | - <property name="fill">True</property> |
754 | + <property name="fill">False</property> |
755 | <property name="position">1</property> |
756 | </packing> |
757 | </child> |
758 | <child> |
759 | - <object class="GtkHSeparator" id="hseparator2"> |
760 | - <property name="visible">True</property> |
761 | - <property name="can_focus">False</property> |
762 | + <object class="GtkRadioButton" id="shares_button"> |
763 | + <property name="label" translatable="yes">Shares</property> |
764 | + <property name="can_focus">True</property> |
765 | + <property name="receives_default">False</property> |
766 | + <property name="use_action_appearance">False</property> |
767 | + <property name="draw_indicator">False</property> |
768 | + <property name="group">dashboard_button</property> |
769 | </object> |
770 | <packing> |
771 | - <property name="expand">True</property> |
772 | - <property name="fill">True</property> |
773 | + <property name="expand">False</property> |
774 | + <property name="fill">False</property> |
775 | <property name="position">2</property> |
776 | </packing> |
777 | </child> |
778 | + <child> |
779 | + <object class="GtkRadioButton" id="devices_button"> |
780 | + <property name="label" translatable="yes">Devices</property> |
781 | + <property name="visible">True</property> |
782 | + <property name="can_focus">True</property> |
783 | + <property name="receives_default">False</property> |
784 | + <property name="use_action_appearance">False</property> |
785 | + <property name="draw_indicator">False</property> |
786 | + <property name="group">dashboard_button</property> |
787 | + </object> |
788 | + <packing> |
789 | + <property name="expand">False</property> |
790 | + <property name="fill">False</property> |
791 | + <property name="position">3</property> |
792 | + </packing> |
793 | + </child> |
794 | + <child> |
795 | + <object class="GtkRadioButton" id="services_button"> |
796 | + <property name="label" translatable="yes">Services</property> |
797 | + <property name="visible">True</property> |
798 | + <property name="can_focus">True</property> |
799 | + <property name="receives_default">False</property> |
800 | + <property name="use_action_appearance">False</property> |
801 | + <property name="draw_indicator">False</property> |
802 | + <property name="group">dashboard_button</property> |
803 | + </object> |
804 | + <packing> |
805 | + <property name="expand">False</property> |
806 | + <property name="fill">False</property> |
807 | + <property name="position">4</property> |
808 | + </packing> |
809 | + </child> |
810 | </object> |
811 | <packing> |
812 | <property name="expand">False</property> |
813 | <property name="fill">True</property> |
814 | - <property name="position">0</property> |
815 | + <property name="position">1</property> |
816 | </packing> |
817 | </child> |
818 | <child> |
819 | - <object class="GtkImage" id="image1"> |
820 | + <object class="GtkHSeparator" id="hseparator2"> |
821 | <property name="visible">True</property> |
822 | <property name="can_focus">False</property> |
823 | - <property name="pixbuf">banner.png</property> |
824 | </object> |
825 | <packing> |
826 | - <property name="expand">False</property> |
827 | + <property name="expand">True</property> |
828 | <property name="fill">True</property> |
829 | - <property name="position">1</property> |
830 | + <property name="position">2</property> |
831 | </packing> |
832 | </child> |
833 | </object> |
834 | @@ -219,5 +196,141 @@ |
835 | <property name="position">1</property> |
836 | </packing> |
837 | </child> |
838 | + <child> |
839 | + <object class="GtkHBox" id="hbox1"> |
840 | + <property name="visible">True</property> |
841 | + <property name="can_focus">False</property> |
842 | + <property name="border_width">12</property> |
843 | + <child> |
844 | + <object class="GtkAlignment" id="alignment3"> |
845 | + <property name="visible">True</property> |
846 | + <property name="can_focus">False</property> |
847 | + <property name="yalign">1</property> |
848 | + <property name="yscale">0</property> |
849 | + <child> |
850 | + <object class="GtkHButtonBox" id="hbuttonbox3"> |
851 | + <property name="visible">True</property> |
852 | + <property name="can_focus">False</property> |
853 | + <property name="spacing">5</property> |
854 | + <property name="layout_style">start</property> |
855 | + <child> |
856 | + <object class="GtkLinkButton" id="linkbutton2"> |
857 | + <property name="label" translatable="yes">Official Support</property> |
858 | + <property name="visible">True</property> |
859 | + <property name="can_focus">True</property> |
860 | + <property name="receives_default">True</property> |
861 | + <property name="use_action_appearance">False</property> |
862 | + <property name="relief">half</property> |
863 | + <property name="uri">https://one.ubuntu.com/support/</property> |
864 | + </object> |
865 | + <packing> |
866 | + <property name="expand">False</property> |
867 | + <property name="fill">False</property> |
868 | + <property name="position">0</property> |
869 | + </packing> |
870 | + </child> |
871 | + <child> |
872 | + <object class="GtkLinkButton" id="linkbutton4"> |
873 | + <property name="label" translatable="yes">Community Support</property> |
874 | + <property name="visible">True</property> |
875 | + <property name="can_focus">True</property> |
876 | + <property name="receives_default">True</property> |
877 | + <property name="use_action_appearance">False</property> |
878 | + <property name="relief">half</property> |
879 | + <property name="uri">http://askubuntu.com/questions/tagged/ubuntu-one</property> |
880 | + </object> |
881 | + <packing> |
882 | + <property name="expand">False</property> |
883 | + <property name="fill">False</property> |
884 | + <property name="position">1</property> |
885 | + </packing> |
886 | + </child> |
887 | + </object> |
888 | + </child> |
889 | + </object> |
890 | + <packing> |
891 | + <property name="expand">False</property> |
892 | + <property name="fill">True</property> |
893 | + <property name="position">0</property> |
894 | + </packing> |
895 | + </child> |
896 | + <child> |
897 | + <object class="GtkHBox" id="hbox3"> |
898 | + <property name="visible">True</property> |
899 | + <property name="can_focus">False</property> |
900 | + <child> |
901 | + <object class="GtkLabel" id="label4"> |
902 | + <property name="visible">True</property> |
903 | + <property name="can_focus">False</property> |
904 | + <property name="label" translatable="yes">Talk to us on:</property> |
905 | + </object> |
906 | + <packing> |
907 | + <property name="expand">True</property> |
908 | + <property name="fill">True</property> |
909 | + <property name="position">0</property> |
910 | + </packing> |
911 | + </child> |
912 | + <child> |
913 | + <object class="GtkLinkButton" id="linkbutton5"> |
914 | + <property name="visible">True</property> |
915 | + <property name="can_focus">True</property> |
916 | + <property name="receives_default">True</property> |
917 | + <property name="use_action_appearance">False</property> |
918 | + <property name="relief">none</property> |
919 | + <property name="uri">http://twitter.com/ubuntuone</property> |
920 | + <child> |
921 | + <object class="GtkImage" id="twitter"> |
922 | + <property name="visible">True</property> |
923 | + <property name="can_focus">False</property> |
924 | + <property name="tooltip_text" translatable="yes">http://twitter.com/ubuntuone</property> |
925 | + <property name="pixbuf">twitter.png</property> |
926 | + </object> |
927 | + </child> |
928 | + </object> |
929 | + <packing> |
930 | + <property name="expand">False</property> |
931 | + <property name="fill">False</property> |
932 | + <property name="position">1</property> |
933 | + </packing> |
934 | + </child> |
935 | + <child> |
936 | + <object class="GtkLinkButton" id="linkbutton6"> |
937 | + <property name="visible">True</property> |
938 | + <property name="can_focus">True</property> |
939 | + <property name="receives_default">True</property> |
940 | + <property name="use_action_appearance">False</property> |
941 | + <property name="relief">none</property> |
942 | + <property name="uri">http://www.facebook.com/ubuntuone</property> |
943 | + <child> |
944 | + <object class="GtkImage" id="facebook"> |
945 | + <property name="visible">True</property> |
946 | + <property name="can_focus">False</property> |
947 | + <property name="tooltip_text" translatable="yes">http://www.facebook.com/ubuntuone</property> |
948 | + <property name="pixbuf">facebook.png</property> |
949 | + </object> |
950 | + </child> |
951 | + </object> |
952 | + <packing> |
953 | + <property name="expand">True</property> |
954 | + <property name="fill">True</property> |
955 | + <property name="position">2</property> |
956 | + </packing> |
957 | + </child> |
958 | + </object> |
959 | + <packing> |
960 | + <property name="expand">False</property> |
961 | + <property name="fill">True</property> |
962 | + <property name="pack_type">end</property> |
963 | + <property name="position">1</property> |
964 | + </packing> |
965 | + </child> |
966 | + </object> |
967 | + <packing> |
968 | + <property name="expand">False</property> |
969 | + <property name="fill">True</property> |
970 | + <property name="pack_type">end</property> |
971 | + <property name="position">1</property> |
972 | + </packing> |
973 | + </child> |
974 | </object> |
975 | </interface> |
976 | |
977 | === added file 'data/music-store.png' |
978 | Binary files data/music-store.png 1970-01-01 00:00:00 +0000 and data/music-store.png 2011-03-10 03:11:54 +0000 differ |
979 | === added file 'data/music-stream.png' |
980 | Binary files data/music-stream.png 1970-01-01 00:00:00 +0000 and data/music-stream.png 2011-03-10 03:11:54 +0000 differ |
981 | === removed file 'data/music.png' |
982 | Binary files data/music.png 2011-02-12 03:07:22 +0000 and data/music.png 1970-01-01 00:00:00 +0000 differ |
983 | === modified file 'data/notes.png' |
984 | Binary files data/notes.png 2011-02-12 03:07:22 +0000 and data/notes.png 2011-03-10 03:11:54 +0000 differ |
985 | === modified file 'data/overview.png' |
986 | Binary files data/overview.png 2010-12-06 12:27:11 +0000 and data/overview.png 2011-03-10 03:11:54 +0000 differ |
987 | === modified file 'data/overview.ui' |
988 | --- data/overview.ui 2011-02-12 03:07:22 +0000 |
989 | +++ data/overview.ui 2011-03-10 03:11:54 +0000 |
990 | @@ -6,7 +6,7 @@ |
991 | <property name="visible">True</property> |
992 | <property name="can_focus">False</property> |
993 | <child> |
994 | - <object class="GtkEventBox" id="header"> |
995 | + <object class="GtkEventBox" id="banner"> |
996 | <property name="visible">True</property> |
997 | <property name="can_focus">False</property> |
998 | <child> |
999 | @@ -35,247 +35,316 @@ |
1000 | <property name="can_focus">False</property> |
1001 | <property name="shadow_type">none</property> |
1002 | <child> |
1003 | - <object class="GtkHBox" id="hbox1"> |
1004 | + <object class="GtkVBox" id="vbox1"> |
1005 | <property name="visible">True</property> |
1006 | <property name="can_focus">False</property> |
1007 | - <property name="border_width">20</property> |
1008 | - <property name="spacing">5</property> |
1009 | - <child> |
1010 | - <object class="GtkTable" id="table1"> |
1011 | - <property name="visible">True</property> |
1012 | - <property name="can_focus">False</property> |
1013 | - <property name="n_rows">4</property> |
1014 | - <property name="n_columns">2</property> |
1015 | - <property name="column_spacing">10</property> |
1016 | - <property name="row_spacing">10</property> |
1017 | - <child> |
1018 | - <object class="GtkImage" id="image1"> |
1019 | - <property name="visible">True</property> |
1020 | - <property name="can_focus">False</property> |
1021 | - <property name="pixbuf">files.png</property> |
1022 | - </object> |
1023 | - <packing> |
1024 | - <property name="x_options">GTK_FILL</property> |
1025 | - <property name="y_options">GTK_FILL</property> |
1026 | - </packing> |
1027 | - </child> |
1028 | - <child> |
1029 | - <object class="GtkImage" id="image2"> |
1030 | - <property name="visible">True</property> |
1031 | - <property name="can_focus">False</property> |
1032 | - <property name="pixbuf">contacts.png</property> |
1033 | - </object> |
1034 | - <packing> |
1035 | - <property name="top_attach">1</property> |
1036 | - <property name="bottom_attach">2</property> |
1037 | - <property name="x_options">GTK_FILL</property> |
1038 | - <property name="y_options">GTK_FILL</property> |
1039 | - </packing> |
1040 | - </child> |
1041 | - <child> |
1042 | - <object class="GtkImage" id="image3"> |
1043 | - <property name="visible">True</property> |
1044 | - <property name="can_focus">False</property> |
1045 | - <property name="pixbuf">music.png</property> |
1046 | - </object> |
1047 | - <packing> |
1048 | - <property name="top_attach">2</property> |
1049 | - <property name="bottom_attach">3</property> |
1050 | - <property name="x_options">GTK_FILL</property> |
1051 | - <property name="y_options">GTK_FILL</property> |
1052 | - </packing> |
1053 | - </child> |
1054 | - <child> |
1055 | - <object class="GtkImage" id="image4"> |
1056 | - <property name="visible">True</property> |
1057 | - <property name="can_focus">False</property> |
1058 | - <property name="pixbuf">notes.png</property> |
1059 | - </object> |
1060 | - <packing> |
1061 | - <property name="top_attach">3</property> |
1062 | - <property name="bottom_attach">4</property> |
1063 | - <property name="x_options">GTK_FILL</property> |
1064 | - <property name="y_options">GTK_FILL</property> |
1065 | - </packing> |
1066 | - </child> |
1067 | - <child> |
1068 | - <object class="GtkLabel" id="label3"> |
1069 | - <property name="visible">True</property> |
1070 | - <property name="can_focus">False</property> |
1071 | - <property name="xalign">0</property> |
1072 | - <property name="label" translatable="yes">Files Anywhere |
1073 | -<span foreground="#909090">Backup and access your files from Windows, Ubuntu, or Mobile</span></property> |
1074 | - <property name="use_markup">True</property> |
1075 | - <property name="wrap">True</property> |
1076 | - </object> |
1077 | - <packing> |
1078 | - <property name="left_attach">1</property> |
1079 | - <property name="right_attach">2</property> |
1080 | - </packing> |
1081 | - </child> |
1082 | - <child> |
1083 | - <object class="GtkLabel" id="label4"> |
1084 | - <property name="visible">True</property> |
1085 | - <property name="can_focus">False</property> |
1086 | - <property name="xalign">0</property> |
1087 | - <property name="label" translatable="yes">Keep connected |
1088 | -<span foreground="#909090">Unify your contacts accress Desktop, Mobile and Web</span></property> |
1089 | - <property name="use_markup">True</property> |
1090 | - <property name="wrap">True</property> |
1091 | - </object> |
1092 | - <packing> |
1093 | - <property name="left_attach">1</property> |
1094 | - <property name="right_attach">2</property> |
1095 | - <property name="top_attach">1</property> |
1096 | - <property name="bottom_attach">2</property> |
1097 | - </packing> |
1098 | - </child> |
1099 | - <child> |
1100 | - <object class="GtkLabel" id="label5"> |
1101 | - <property name="visible">True</property> |
1102 | - <property name="can_focus">False</property> |
1103 | - <property name="xalign">0</property> |
1104 | - <property name="label" translatable="yes">Rock Out |
1105 | -<span foreground="#909090">Your library at your fingertips with Android, iPhone, and AirPlay |
1106 | -Plus the Ubuntu One Music store to grow your collection</span></property> |
1107 | - <property name="use_markup">True</property> |
1108 | - <property name="wrap">True</property> |
1109 | - </object> |
1110 | - <packing> |
1111 | - <property name="left_attach">1</property> |
1112 | - <property name="right_attach">2</property> |
1113 | - <property name="top_attach">2</property> |
1114 | - <property name="bottom_attach">3</property> |
1115 | - </packing> |
1116 | - </child> |
1117 | - <child> |
1118 | - <object class="GtkLabel" id="label6"> |
1119 | - <property name="visible">True</property> |
1120 | - <property name="can_focus">False</property> |
1121 | - <property name="xalign">0</property> |
1122 | - <property name="label" translatable="yes">Stay Productive |
1123 | + <child> |
1124 | + <object class="GtkLabel" id="label7"> |
1125 | + <property name="visible">True</property> |
1126 | + <property name="can_focus">False</property> |
1127 | + <property name="label" translatable="yes"><span font_size="xx-large" foreground="#4d4d4d">The Power of Your Personal Cloud</span></property> |
1128 | + <property name="use_markup">True</property> |
1129 | + </object> |
1130 | + <packing> |
1131 | + <property name="expand">False</property> |
1132 | + <property name="fill">True</property> |
1133 | + <property name="padding">12</property> |
1134 | + <property name="position">0</property> |
1135 | + </packing> |
1136 | + </child> |
1137 | + <child> |
1138 | + <object class="GtkHBox" id="hbox1"> |
1139 | + <property name="visible">True</property> |
1140 | + <property name="can_focus">False</property> |
1141 | + <property name="border_width">20</property> |
1142 | + <property name="spacing">5</property> |
1143 | + <child> |
1144 | + <object class="GtkTable" id="table1"> |
1145 | + <property name="visible">True</property> |
1146 | + <property name="can_focus">False</property> |
1147 | + <property name="n_rows">4</property> |
1148 | + <property name="n_columns">2</property> |
1149 | + <property name="column_spacing">10</property> |
1150 | + <child> |
1151 | + <object class="GtkImage" id="image1"> |
1152 | + <property name="visible">True</property> |
1153 | + <property name="can_focus">False</property> |
1154 | + <property name="pixbuf">files.png</property> |
1155 | + </object> |
1156 | + <packing> |
1157 | + <property name="x_options">GTK_FILL</property> |
1158 | + <property name="y_options">GTK_FILL</property> |
1159 | + </packing> |
1160 | + </child> |
1161 | + <child> |
1162 | + <object class="GtkImage" id="image2"> |
1163 | + <property name="visible">True</property> |
1164 | + <property name="can_focus">False</property> |
1165 | + <property name="pixbuf">music-stream.png</property> |
1166 | + </object> |
1167 | + <packing> |
1168 | + <property name="top_attach">1</property> |
1169 | + <property name="bottom_attach">2</property> |
1170 | + <property name="x_options">GTK_FILL</property> |
1171 | + <property name="y_options">GTK_FILL</property> |
1172 | + </packing> |
1173 | + </child> |
1174 | + <child> |
1175 | + <object class="GtkImage" id="image3"> |
1176 | + <property name="visible">True</property> |
1177 | + <property name="can_focus">False</property> |
1178 | + <property name="pixbuf">contacts.png</property> |
1179 | + </object> |
1180 | + <packing> |
1181 | + <property name="top_attach">2</property> |
1182 | + <property name="bottom_attach">3</property> |
1183 | + <property name="x_options">GTK_FILL</property> |
1184 | + <property name="y_options">GTK_FILL</property> |
1185 | + </packing> |
1186 | + </child> |
1187 | + <child> |
1188 | + <object class="GtkImage" id="image4"> |
1189 | + <property name="visible">True</property> |
1190 | + <property name="can_focus">False</property> |
1191 | + <property name="pixbuf">notes.png</property> |
1192 | + </object> |
1193 | + <packing> |
1194 | + <property name="top_attach">3</property> |
1195 | + <property name="bottom_attach">4</property> |
1196 | + <property name="x_options">GTK_FILL</property> |
1197 | + <property name="y_options">GTK_FILL</property> |
1198 | + </packing> |
1199 | + </child> |
1200 | + <child> |
1201 | + <object class="GtkLabel" id="label3"> |
1202 | + <property name="visible">True</property> |
1203 | + <property name="can_focus">False</property> |
1204 | + <property name="xalign">0</property> |
1205 | + <property name="label" translatable="yes">Files Anywhere |
1206 | +<span foreground="#909090">Backup and access your files from Ubuntu, Windows or Mobile</span></property> |
1207 | + <property name="use_markup">True</property> |
1208 | + <property name="wrap">True</property> |
1209 | + </object> |
1210 | + <packing> |
1211 | + <property name="left_attach">1</property> |
1212 | + <property name="right_attach">2</property> |
1213 | + </packing> |
1214 | + </child> |
1215 | + <child> |
1216 | + <object class="GtkLabel" id="label4"> |
1217 | + <property name="visible">True</property> |
1218 | + <property name="can_focus">False</property> |
1219 | + <property name="xalign">0</property> |
1220 | + <property name="label" translatable="yes">Keep Connected |
1221 | +<span foreground="#909090">Unify your contacts across Desktop, Mobile and Web</span></property> |
1222 | + <property name="use_markup">True</property> |
1223 | + <property name="wrap">True</property> |
1224 | + </object> |
1225 | + <packing> |
1226 | + <property name="left_attach">1</property> |
1227 | + <property name="right_attach">2</property> |
1228 | + <property name="top_attach">2</property> |
1229 | + <property name="bottom_attach">3</property> |
1230 | + </packing> |
1231 | + </child> |
1232 | + <child> |
1233 | + <object class="GtkLabel" id="label5"> |
1234 | + <property name="visible">True</property> |
1235 | + <property name="can_focus">False</property> |
1236 | + <property name="xalign">0</property> |
1237 | + <property name="label" translatable="yes">Rock Out |
1238 | +<span foreground="#909090">Your entire collection follows you around with music streaming to Android and iPhone</span></property> |
1239 | + <property name="use_markup">True</property> |
1240 | + <property name="wrap">True</property> |
1241 | + </object> |
1242 | + <packing> |
1243 | + <property name="left_attach">1</property> |
1244 | + <property name="right_attach">2</property> |
1245 | + <property name="top_attach">1</property> |
1246 | + <property name="bottom_attach">2</property> |
1247 | + </packing> |
1248 | + </child> |
1249 | + <child> |
1250 | + <object class="GtkLabel" id="label6"> |
1251 | + <property name="visible">True</property> |
1252 | + <property name="can_focus">False</property> |
1253 | + <property name="xalign">0</property> |
1254 | + <property name="label" translatable="yes">Stay Productive |
1255 | <span foreground="#909090">Keep your Firefox bookmarks and Tomboy notes synced</span></property> |
1256 | - <property name="use_markup">True</property> |
1257 | - <property name="wrap">True</property> |
1258 | + <property name="use_markup">True</property> |
1259 | + <property name="wrap">True</property> |
1260 | + </object> |
1261 | + <packing> |
1262 | + <property name="left_attach">1</property> |
1263 | + <property name="right_attach">2</property> |
1264 | + <property name="top_attach">3</property> |
1265 | + <property name="bottom_attach">4</property> |
1266 | + </packing> |
1267 | + </child> |
1268 | </object> |
1269 | <packing> |
1270 | - <property name="left_attach">1</property> |
1271 | - <property name="right_attach">2</property> |
1272 | - <property name="top_attach">3</property> |
1273 | - <property name="bottom_attach">4</property> |
1274 | + <property name="expand">True</property> |
1275 | + <property name="fill">True</property> |
1276 | + <property name="position">0</property> |
1277 | </packing> |
1278 | </child> |
1279 | - </object> |
1280 | - <packing> |
1281 | - <property name="expand">True</property> |
1282 | - <property name="fill">True</property> |
1283 | - <property name="position">0</property> |
1284 | - </packing> |
1285 | - </child> |
1286 | - <child> |
1287 | - <object class="GtkVBox" id="vbox1"> |
1288 | - <property name="visible">True</property> |
1289 | - <property name="can_focus">False</property> |
1290 | <child> |
1291 | - <object class="GtkLabel" id="warning_label"> |
1292 | + <object class="GtkVBox" id="vbox2"> |
1293 | <property name="visible">True</property> |
1294 | <property name="can_focus">False</property> |
1295 | - <property name="label">A warning label that can be long. Possible really long, let's see how it behaves.</property> |
1296 | - <property name="wrap">True</property> |
1297 | + <child> |
1298 | + <object class="GtkLabel" id="warning_label"> |
1299 | + <property name="visible">True</property> |
1300 | + <property name="can_focus">False</property> |
1301 | + <property name="label">A warning label that can be long. Possible really long, let's see how it behaves.</property> |
1302 | + <property name="wrap">True</property> |
1303 | + </object> |
1304 | + <packing> |
1305 | + <property name="expand">False</property> |
1306 | + <property name="fill">True</property> |
1307 | + <property name="position">0</property> |
1308 | + </packing> |
1309 | + </child> |
1310 | + <child> |
1311 | + <object class="GtkAlignment" id="alignment2"> |
1312 | + <property name="visible">True</property> |
1313 | + <property name="can_focus">False</property> |
1314 | + <property name="xscale">0</property> |
1315 | + <property name="yscale">0</property> |
1316 | + <child> |
1317 | + <object class="GtkVBox" id="vbox3"> |
1318 | + <property name="visible">True</property> |
1319 | + <property name="can_focus">False</property> |
1320 | + <property name="spacing">10</property> |
1321 | + <child> |
1322 | + <object class="GtkButton" id="learn_more_button"> |
1323 | + <property name="visible">True</property> |
1324 | + <property name="can_focus">True</property> |
1325 | + <property name="receives_default">True</property> |
1326 | + <property name="use_action_appearance">False</property> |
1327 | + <signal name="clicked" handler="on_learn_more_button_clicked" swapped="no"/> |
1328 | + <child> |
1329 | + <object class="GtkVBox" id="vbox5"> |
1330 | + <property name="visible">True</property> |
1331 | + <property name="can_focus">False</property> |
1332 | + <child> |
1333 | + <object class="GtkImage" id="image5"> |
1334 | + <property name="visible">True</property> |
1335 | + <property name="can_focus">False</property> |
1336 | + <property name="pixel_size">45</property> |
1337 | + <property name="icon_name">ubuntuone</property> |
1338 | + </object> |
1339 | + <packing> |
1340 | + <property name="expand">True</property> |
1341 | + <property name="fill">True</property> |
1342 | + <property name="position">0</property> |
1343 | + </packing> |
1344 | + </child> |
1345 | + <child> |
1346 | + <object class="GtkLabel" id="label8"> |
1347 | + <property name="visible">True</property> |
1348 | + <property name="can_focus">False</property> |
1349 | + <property name="label" translatable="yes"><span foreground="#909090">Learn More</span></property> |
1350 | + <property name="use_markup">True</property> |
1351 | + </object> |
1352 | + <packing> |
1353 | + <property name="expand">True</property> |
1354 | + <property name="fill">True</property> |
1355 | + <property name="position">1</property> |
1356 | + </packing> |
1357 | + </child> |
1358 | + </object> |
1359 | + </child> |
1360 | + </object> |
1361 | + <packing> |
1362 | + <property name="expand">True</property> |
1363 | + <property name="fill">True</property> |
1364 | + <property name="position">0</property> |
1365 | + </packing> |
1366 | + </child> |
1367 | + <child> |
1368 | + <object class="GtkButton" id="join_now_button"> |
1369 | + <property name="visible">True</property> |
1370 | + <property name="can_focus">True</property> |
1371 | + <property name="can_default">True</property> |
1372 | + <property name="receives_default">True</property> |
1373 | + <property name="use_action_appearance">False</property> |
1374 | + <signal name="clicked" handler="on_join_now_button_clicked" swapped="no"/> |
1375 | + <child> |
1376 | + <object class="GtkVBox" id="vbox4"> |
1377 | + <property name="visible">True</property> |
1378 | + <property name="can_focus">False</property> |
1379 | + <property name="spacing">5</property> |
1380 | + <child> |
1381 | + <object class="GtkLabel" id="label1"> |
1382 | + <property name="visible">True</property> |
1383 | + <property name="can_focus">False</property> |
1384 | + <property name="label" translatable="yes"><span font_size="xx-large" foreground="#4d4d4d">Join now</span></property> |
1385 | + <property name="use_markup">True</property> |
1386 | + </object> |
1387 | + <packing> |
1388 | + <property name="expand">True</property> |
1389 | + <property name="fill">True</property> |
1390 | + <property name="position">0</property> |
1391 | + </packing> |
1392 | + </child> |
1393 | + <child> |
1394 | + <object class="GtkLabel" id="label2"> |
1395 | + <property name="visible">True</property> |
1396 | + <property name="can_focus">False</property> |
1397 | + <property name="label" translatable="yes"><span foreground="#909090">2GB of free storage</span></property> |
1398 | + <property name="use_markup">True</property> |
1399 | + </object> |
1400 | + <packing> |
1401 | + <property name="expand">True</property> |
1402 | + <property name="fill">True</property> |
1403 | + <property name="position">1</property> |
1404 | + </packing> |
1405 | + </child> |
1406 | + </object> |
1407 | + </child> |
1408 | + </object> |
1409 | + <packing> |
1410 | + <property name="expand">False</property> |
1411 | + <property name="fill">True</property> |
1412 | + <property name="position">1</property> |
1413 | + </packing> |
1414 | + </child> |
1415 | + <child> |
1416 | + <object class="GtkLinkButton" id="connect_button"> |
1417 | + <property name="label" translatable="yes">I already have an account!</property> |
1418 | + <property name="visible">True</property> |
1419 | + <property name="can_focus">True</property> |
1420 | + <property name="receives_default">True</property> |
1421 | + <property name="use_action_appearance">False</property> |
1422 | + <property name="relief">none</property> |
1423 | + <signal name="clicked" handler="on_connect_button_clicked" swapped="no"/> |
1424 | + </object> |
1425 | + <packing> |
1426 | + <property name="expand">False</property> |
1427 | + <property name="fill">False</property> |
1428 | + <property name="position">2</property> |
1429 | + </packing> |
1430 | + </child> |
1431 | + </object> |
1432 | + </child> |
1433 | + </object> |
1434 | + <packing> |
1435 | + <property name="expand">True</property> |
1436 | + <property name="fill">True</property> |
1437 | + <property name="position">1</property> |
1438 | + </packing> |
1439 | + </child> |
1440 | </object> |
1441 | <packing> |
1442 | <property name="expand">False</property> |
1443 | <property name="fill">True</property> |
1444 | - <property name="position">0</property> |
1445 | - </packing> |
1446 | - </child> |
1447 | - <child> |
1448 | - <object class="GtkAlignment" id="alignment2"> |
1449 | - <property name="visible">True</property> |
1450 | - <property name="can_focus">False</property> |
1451 | - <property name="xscale">0</property> |
1452 | - <property name="yscale">0</property> |
1453 | - <child> |
1454 | - <object class="GtkVBox" id="vbox2"> |
1455 | - <property name="visible">True</property> |
1456 | - <property name="can_focus">False</property> |
1457 | - <property name="spacing">10</property> |
1458 | - <child> |
1459 | - <object class="GtkButton" id="join_now_button"> |
1460 | - <property name="visible">True</property> |
1461 | - <property name="can_focus">True</property> |
1462 | - <property name="can_default">True</property> |
1463 | - <property name="receives_default">True</property> |
1464 | - <property name="use_action_appearance">False</property> |
1465 | - <signal name="clicked" handler="on_join_now_button_clicked" swapped="no"/> |
1466 | - <child> |
1467 | - <object class="GtkVBox" id="vbox3"> |
1468 | - <property name="visible">True</property> |
1469 | - <property name="can_focus">False</property> |
1470 | - <property name="spacing">5</property> |
1471 | - <child> |
1472 | - <object class="GtkLabel" id="label1"> |
1473 | - <property name="visible">True</property> |
1474 | - <property name="can_focus">False</property> |
1475 | - <property name="label" translatable="yes"><span font_size="xx-large">Join now</span></property> |
1476 | - <property name="use_markup">True</property> |
1477 | - </object> |
1478 | - <packing> |
1479 | - <property name="expand">True</property> |
1480 | - <property name="fill">True</property> |
1481 | - <property name="position">0</property> |
1482 | - </packing> |
1483 | - </child> |
1484 | - <child> |
1485 | - <object class="GtkLabel" id="label2"> |
1486 | - <property name="visible">True</property> |
1487 | - <property name="can_focus">False</property> |
1488 | - <property name="label" translatable="yes"><span foreground="#909090">2GB of free storage</span></property> |
1489 | - <property name="use_markup">True</property> |
1490 | - </object> |
1491 | - <packing> |
1492 | - <property name="expand">True</property> |
1493 | - <property name="fill">True</property> |
1494 | - <property name="position">1</property> |
1495 | - </packing> |
1496 | - </child> |
1497 | - </object> |
1498 | - </child> |
1499 | - </object> |
1500 | - <packing> |
1501 | - <property name="expand">False</property> |
1502 | - <property name="fill">True</property> |
1503 | - <property name="position">0</property> |
1504 | - </packing> |
1505 | - </child> |
1506 | - <child> |
1507 | - <object class="GtkLinkButton" id="connect_button"> |
1508 | - <property name="label" translatable="yes">I already have an account!</property> |
1509 | - <property name="visible">True</property> |
1510 | - <property name="can_focus">True</property> |
1511 | - <property name="receives_default">True</property> |
1512 | - <property name="use_action_appearance">False</property> |
1513 | - <property name="relief">none</property> |
1514 | - <signal name="clicked" handler="on_connect_button_clicked" swapped="no"/> |
1515 | - </object> |
1516 | - <packing> |
1517 | - <property name="expand">False</property> |
1518 | - <property name="fill">False</property> |
1519 | - <property name="position">1</property> |
1520 | - </packing> |
1521 | - </child> |
1522 | - </object> |
1523 | - </child> |
1524 | - </object> |
1525 | - <packing> |
1526 | - <property name="expand">True</property> |
1527 | - <property name="fill">True</property> |
1528 | <property name="position">1</property> |
1529 | </packing> |
1530 | </child> |
1531 | </object> |
1532 | <packing> |
1533 | - <property name="expand">False</property> |
1534 | + <property name="expand">True</property> |
1535 | <property name="fill">True</property> |
1536 | <property name="position">1</property> |
1537 | </packing> |
1538 | |
1539 | === added file 'data/services-bookmarks.png' |
1540 | Binary files data/services-bookmarks.png 1970-01-01 00:00:00 +0000 and data/services-bookmarks.png 2011-03-10 03:11:54 +0000 differ |
1541 | === added file 'data/services-contacts.png' |
1542 | Binary files data/services-contacts.png 1970-01-01 00:00:00 +0000 and data/services-contacts.png 2011-03-10 03:11:54 +0000 differ |
1543 | === added file 'data/services-files-example.png' |
1544 | Binary files data/services-files-example.png 1970-01-01 00:00:00 +0000 and data/services-files-example.png 2011-03-10 03:11:54 +0000 differ |
1545 | === added file 'data/services-files.png' |
1546 | Binary files data/services-files.png 1970-01-01 00:00:00 +0000 and data/services-files.png 2011-03-10 03:11:54 +0000 differ |
1547 | === modified file 'data/services.ui' |
1548 | --- data/services.ui 2011-01-25 19:08:59 +0000 |
1549 | +++ data/services.ui 2011-03-10 03:11:54 +0000 |
1550 | @@ -4,8 +4,7 @@ |
1551 | <!-- interface-naming-policy project-wide --> |
1552 | <object class="GtkVBox" id="itself"> |
1553 | <property name="visible">True</property> |
1554 | - <property name="border_width">10</property> |
1555 | - <property name="spacing">10</property> |
1556 | + <property name="can_focus">False</property> |
1557 | <child> |
1558 | <object class="GtkScrolledWindow" id="scrolledwindow1"> |
1559 | <property name="visible">True</property> |
1560 | @@ -15,44 +14,338 @@ |
1561 | <child> |
1562 | <object class="GtkViewport" id="viewport1"> |
1563 | <property name="visible">True</property> |
1564 | + <property name="can_focus">False</property> |
1565 | <property name="resize_mode">queue</property> |
1566 | <property name="shadow_type">none</property> |
1567 | <child> |
1568 | <object class="GtkVBox" id="vbox1"> |
1569 | <property name="visible">True</property> |
1570 | + <property name="can_focus">False</property> |
1571 | + <property name="spacing">5</property> |
1572 | <child> |
1573 | - <object class="GtkAlignment" id="alignment1"> |
1574 | + <object class="GtkAspectFrame" id="files"> |
1575 | <property name="visible">True</property> |
1576 | + <property name="can_focus">False</property> |
1577 | + <property name="label_xalign">0</property> |
1578 | + <property name="shadow_type">out</property> |
1579 | <child> |
1580 | - <object class="GtkVBox" id="replications"> |
1581 | + <object class="GtkHBox" id="hbox2"> |
1582 | <property name="visible">True</property> |
1583 | - <property name="spacing">5</property> |
1584 | - <child> |
1585 | - <placeholder/> |
1586 | + <property name="can_focus">False</property> |
1587 | + <property name="border_width">5</property> |
1588 | + <child> |
1589 | + <object class="GtkTable" id="table1"> |
1590 | + <property name="visible">True</property> |
1591 | + <property name="can_focus">False</property> |
1592 | + <property name="n_rows">3</property> |
1593 | + <property name="n_columns">3</property> |
1594 | + <property name="row_spacing">5</property> |
1595 | + <child> |
1596 | + <object class="GtkCheckButton" id="file_sync_check"> |
1597 | + <property name="visible">True</property> |
1598 | + <property name="can_focus">True</property> |
1599 | + <property name="receives_default">False</property> |
1600 | + <property name="use_action_appearance">False</property> |
1601 | + <property name="draw_indicator">True</property> |
1602 | + </object> |
1603 | + </child> |
1604 | + <child> |
1605 | + <object class="GtkImage" id="image2"> |
1606 | + <property name="visible">True</property> |
1607 | + <property name="can_focus">False</property> |
1608 | + <property name="xpad">5</property> |
1609 | + <property name="pixbuf">services-files.png</property> |
1610 | + </object> |
1611 | + <packing> |
1612 | + <property name="left_attach">1</property> |
1613 | + <property name="right_attach">2</property> |
1614 | + </packing> |
1615 | + </child> |
1616 | + <child> |
1617 | + <object class="GtkLabel" id="label1"> |
1618 | + <property name="visible">True</property> |
1619 | + <property name="can_focus">False</property> |
1620 | + <property name="xalign">0</property> |
1621 | + <property name="label" translatable="yes">Enable File Sync</property> |
1622 | + </object> |
1623 | + <packing> |
1624 | + <property name="left_attach">2</property> |
1625 | + <property name="right_attach">3</property> |
1626 | + </packing> |
1627 | + </child> |
1628 | + <child> |
1629 | + <object class="GtkLabel" id="label2"> |
1630 | + <property name="visible">True</property> |
1631 | + <property name="can_focus">False</property> |
1632 | + <property name="xalign">0</property> |
1633 | + <property name="yalign">0</property> |
1634 | + <property name="label" translatable="yes"><span font_size="small">Enable and then choose which folders you want to access from the Web or any device you connected to Ubuntu One |
1635 | + |
1636 | +Simply drag and drop any file or folder to your Ubuntu One folder on this computer</span></property> |
1637 | + <property name="use_markup">True</property> |
1638 | + <property name="wrap">True</property> |
1639 | + <property name="width_chars">30</property> |
1640 | + </object> |
1641 | + <packing> |
1642 | + <property name="left_attach">2</property> |
1643 | + <property name="right_attach">3</property> |
1644 | + <property name="top_attach">1</property> |
1645 | + <property name="bottom_attach">2</property> |
1646 | + </packing> |
1647 | + </child> |
1648 | + <child> |
1649 | + <object class="GtkHButtonBox" id="hbuttonbox1"> |
1650 | + <property name="visible">True</property> |
1651 | + <property name="can_focus">False</property> |
1652 | + <child> |
1653 | + <object class="GtkButton" id="file_sync_button"> |
1654 | + <property name="label" translatable="yes">_Show me my Ubuntu One folder</property> |
1655 | + <property name="visible">True</property> |
1656 | + <property name="can_focus">True</property> |
1657 | + <property name="receives_default">True</property> |
1658 | + <property name="use_action_appearance">False</property> |
1659 | + <property name="use_underline">True</property> |
1660 | + <signal name="clicked" handler="on_file_sync_button_clicked" swapped="no"/> |
1661 | + </object> |
1662 | + <packing> |
1663 | + <property name="expand">False</property> |
1664 | + <property name="fill">False</property> |
1665 | + <property name="position">0</property> |
1666 | + </packing> |
1667 | + </child> |
1668 | + </object> |
1669 | + <packing> |
1670 | + <property name="left_attach">2</property> |
1671 | + <property name="right_attach">3</property> |
1672 | + <property name="top_attach">2</property> |
1673 | + <property name="bottom_attach">3</property> |
1674 | + </packing> |
1675 | + </child> |
1676 | + <child> |
1677 | + <placeholder/> |
1678 | + </child> |
1679 | + <child> |
1680 | + <placeholder/> |
1681 | + </child> |
1682 | + <child> |
1683 | + <placeholder/> |
1684 | + </child> |
1685 | + <child> |
1686 | + <placeholder/> |
1687 | + </child> |
1688 | + </object> |
1689 | + <packing> |
1690 | + <property name="expand">False</property> |
1691 | + <property name="fill">True</property> |
1692 | + <property name="position">0</property> |
1693 | + </packing> |
1694 | + </child> |
1695 | + <child> |
1696 | + <object class="GtkImage" id="image1"> |
1697 | + <property name="visible">True</property> |
1698 | + <property name="can_focus">False</property> |
1699 | + <property name="xpad">5</property> |
1700 | + <property name="ypad">5</property> |
1701 | + <property name="pixbuf">services-files-example.png</property> |
1702 | + </object> |
1703 | + <packing> |
1704 | + <property name="expand">False</property> |
1705 | + <property name="fill">True</property> |
1706 | + <property name="pack_type">end</property> |
1707 | + <property name="position">1</property> |
1708 | + </packing> |
1709 | </child> |
1710 | </object> |
1711 | </child> |
1712 | </object> |
1713 | <packing> |
1714 | - <property name="expand">False</property> |
1715 | + <property name="expand">True</property> |
1716 | + <property name="fill">True</property> |
1717 | <property name="position">0</property> |
1718 | </packing> |
1719 | </child> |
1720 | <child> |
1721 | - <object class="GtkAlignment" id="alignment2"> |
1722 | + <object class="GtkAspectFrame" id="replications"> |
1723 | <property name="visible">True</property> |
1724 | + <property name="can_focus">False</property> |
1725 | + <property name="label_xalign">0</property> |
1726 | + <property name="shadow_type">out</property> |
1727 | <child> |
1728 | - <object class="GtkVBox" id="files"> |
1729 | + <object class="GtkHBox" id="hbox3"> |
1730 | <property name="visible">True</property> |
1731 | - <property name="spacing">5</property> |
1732 | - <child> |
1733 | - <placeholder/> |
1734 | + <property name="can_focus">False</property> |
1735 | + <property name="border_width">5</property> |
1736 | + <child> |
1737 | + <object class="GtkVBox" id="contacts"> |
1738 | + <property name="visible">True</property> |
1739 | + <property name="can_focus">False</property> |
1740 | + <child> |
1741 | + <object class="GtkTable" id="contacts_sync"> |
1742 | + <property name="visible">True</property> |
1743 | + <property name="can_focus">False</property> |
1744 | + <property name="n_rows">2</property> |
1745 | + <property name="n_columns">3</property> |
1746 | + <property name="row_spacing">5</property> |
1747 | + <child> |
1748 | + <object class="GtkCheckButton" id="contacts_check"> |
1749 | + <property name="visible">True</property> |
1750 | + <property name="can_focus">True</property> |
1751 | + <property name="receives_default">False</property> |
1752 | + <property name="use_action_appearance">False</property> |
1753 | + <property name="draw_indicator">True</property> |
1754 | + </object> |
1755 | + </child> |
1756 | + <child> |
1757 | + <object class="GtkImage" id="image3"> |
1758 | + <property name="visible">True</property> |
1759 | + <property name="can_focus">False</property> |
1760 | + <property name="xpad">5</property> |
1761 | + <property name="pixbuf">services-contacts.png</property> |
1762 | + </object> |
1763 | + <packing> |
1764 | + <property name="left_attach">1</property> |
1765 | + <property name="right_attach">2</property> |
1766 | + </packing> |
1767 | + </child> |
1768 | + <child> |
1769 | + <object class="GtkLabel" id="label4"> |
1770 | + <property name="visible">True</property> |
1771 | + <property name="can_focus">False</property> |
1772 | + <property name="xalign">0</property> |
1773 | + <property name="label" translatable="yes">Enable Contacts Sync</property> |
1774 | + </object> |
1775 | + <packing> |
1776 | + <property name="left_attach">2</property> |
1777 | + <property name="right_attach">3</property> |
1778 | + </packing> |
1779 | + </child> |
1780 | + <child> |
1781 | + <object class="GtkLabel" id="label5"> |
1782 | + <property name="visible">True</property> |
1783 | + <property name="can_focus">True</property> |
1784 | + <property name="xalign">0</property> |
1785 | + <property name="yalign">0</property> |
1786 | + <property name="label" translatable="yes"><span font_size="small">Once enabled, visit the <a href="https://one.ubuntu.com">Ubuntu One website</a> to manage your contacts, including Gmail and Facebook import</span></property> |
1787 | + <property name="use_markup">True</property> |
1788 | + <property name="wrap">True</property> |
1789 | + <property name="width_chars">30</property> |
1790 | + </object> |
1791 | + <packing> |
1792 | + <property name="left_attach">2</property> |
1793 | + <property name="right_attach">3</property> |
1794 | + <property name="top_attach">1</property> |
1795 | + <property name="bottom_attach">2</property> |
1796 | + </packing> |
1797 | + </child> |
1798 | + <child> |
1799 | + <placeholder/> |
1800 | + </child> |
1801 | + <child> |
1802 | + <placeholder/> |
1803 | + </child> |
1804 | + </object> |
1805 | + <packing> |
1806 | + <property name="expand">False</property> |
1807 | + <property name="fill">True</property> |
1808 | + <property name="position">0</property> |
1809 | + </packing> |
1810 | + </child> |
1811 | + </object> |
1812 | + <packing> |
1813 | + <property name="expand">False</property> |
1814 | + <property name="fill">True</property> |
1815 | + <property name="position">0</property> |
1816 | + </packing> |
1817 | + </child> |
1818 | + <child> |
1819 | + <object class="GtkVBox" id="bookmarks"> |
1820 | + <property name="visible">True</property> |
1821 | + <property name="can_focus">False</property> |
1822 | + <child> |
1823 | + <object class="GtkTable" id="bookmarks_sync"> |
1824 | + <property name="visible">True</property> |
1825 | + <property name="can_focus">False</property> |
1826 | + <property name="n_rows">2</property> |
1827 | + <property name="n_columns">3</property> |
1828 | + <property name="row_spacing">5</property> |
1829 | + <child> |
1830 | + <object class="GtkCheckButton" id="bookmarks_check"> |
1831 | + <property name="visible">True</property> |
1832 | + <property name="can_focus">True</property> |
1833 | + <property name="receives_default">False</property> |
1834 | + <property name="use_action_appearance">False</property> |
1835 | + <property name="draw_indicator">True</property> |
1836 | + </object> |
1837 | + </child> |
1838 | + <child> |
1839 | + <object class="GtkImage" id="image4"> |
1840 | + <property name="visible">True</property> |
1841 | + <property name="can_focus">False</property> |
1842 | + <property name="xpad">5</property> |
1843 | + <property name="pixbuf">services-bookmarks.png</property> |
1844 | + </object> |
1845 | + <packing> |
1846 | + <property name="left_attach">1</property> |
1847 | + <property name="right_attach">2</property> |
1848 | + </packing> |
1849 | + </child> |
1850 | + <child> |
1851 | + <object class="GtkLabel" id="label6"> |
1852 | + <property name="visible">True</property> |
1853 | + <property name="can_focus">False</property> |
1854 | + <property name="xalign">0</property> |
1855 | + <property name="label" translatable="yes">Enable Bookmarks Sync</property> |
1856 | + </object> |
1857 | + <packing> |
1858 | + <property name="left_attach">2</property> |
1859 | + <property name="right_attach">3</property> |
1860 | + </packing> |
1861 | + </child> |
1862 | + <child> |
1863 | + <object class="GtkLabel" id="label7"> |
1864 | + <property name="visible">True</property> |
1865 | + <property name="can_focus">False</property> |
1866 | + <property name="xalign">0</property> |
1867 | + <property name="yalign">0</property> |
1868 | + <property name="label" translatable="yes"><span font_size="small">Bookmarks sync works with Firefox. Once enabled, you will need to install a plugin</span></property> |
1869 | + <property name="use_markup">True</property> |
1870 | + <property name="wrap">True</property> |
1871 | + <property name="width_chars">30</property> |
1872 | + </object> |
1873 | + <packing> |
1874 | + <property name="left_attach">2</property> |
1875 | + <property name="right_attach">3</property> |
1876 | + <property name="top_attach">1</property> |
1877 | + <property name="bottom_attach">2</property> |
1878 | + </packing> |
1879 | + </child> |
1880 | + <child> |
1881 | + <placeholder/> |
1882 | + </child> |
1883 | + <child> |
1884 | + <placeholder/> |
1885 | + </child> |
1886 | + </object> |
1887 | + <packing> |
1888 | + <property name="expand">False</property> |
1889 | + <property name="fill">True</property> |
1890 | + <property name="position">0</property> |
1891 | + </packing> |
1892 | + </child> |
1893 | + </object> |
1894 | + <packing> |
1895 | + <property name="expand">False</property> |
1896 | + <property name="fill">True</property> |
1897 | + <property name="pack_type">end</property> |
1898 | + <property name="position">1</property> |
1899 | + </packing> |
1900 | </child> |
1901 | </object> |
1902 | </child> |
1903 | </object> |
1904 | <packing> |
1905 | - <property name="expand">False</property> |
1906 | + <property name="expand">True</property> |
1907 | + <property name="fill">True</property> |
1908 | <property name="position">1</property> |
1909 | </packing> |
1910 | </child> |
1911 | @@ -62,6 +355,8 @@ |
1912 | </child> |
1913 | </object> |
1914 | <packing> |
1915 | + <property name="expand">True</property> |
1916 | + <property name="fill">True</property> |
1917 | <property name="position">0</property> |
1918 | </packing> |
1919 | </child> |
1920 | |
1921 | === modified file 'data/volumes.ui' |
1922 | --- data/volumes.ui 2011-02-12 03:07:22 +0000 |
1923 | +++ data/volumes.ui 2011-03-10 03:11:54 +0000 |
1924 | @@ -2,26 +2,6 @@ |
1925 | <interface> |
1926 | <requires lib="gtk+" version="2.22"/> |
1927 | <!-- interface-naming-policy project-wide --> |
1928 | - <object class="GtkTreeStore" id="volumes_store"> |
1929 | - <columns> |
1930 | - <!-- column-name description --> |
1931 | - <column type="gchararray"/> |
1932 | - <!-- column-name subscribed --> |
1933 | - <column type="gboolean"/> |
1934 | - <!-- column-name icon-name --> |
1935 | - <column type="gchararray"/> |
1936 | - <!-- column-name subscribed-visible --> |
1937 | - <column type="gboolean"/> |
1938 | - <!-- column-name subscribed-sensitive --> |
1939 | - <column type="gboolean"/> |
1940 | - <!-- column-name icon-size --> |
1941 | - <column type="gint"/> |
1942 | - <!-- column-name identifier --> |
1943 | - <column type="gchararray"/> |
1944 | - <!-- column-name path --> |
1945 | - <column type="gchararray"/> |
1946 | - </columns> |
1947 | - </object> |
1948 | <object class="GtkAlignment" id="itself"> |
1949 | <property name="visible">True</property> |
1950 | <property name="can_focus">False</property> |
1951 | @@ -94,4 +74,24 @@ |
1952 | </object> |
1953 | </child> |
1954 | </object> |
1955 | + <object class="GtkTreeStore" id="volumes_store"> |
1956 | + <columns> |
1957 | + <!-- column-name description --> |
1958 | + <column type="gchararray"/> |
1959 | + <!-- column-name subscribed --> |
1960 | + <column type="gboolean"/> |
1961 | + <!-- column-name icon-name --> |
1962 | + <column type="gchararray"/> |
1963 | + <!-- column-name subscribed-visible --> |
1964 | + <column type="gboolean"/> |
1965 | + <!-- column-name subscribed-sensitive --> |
1966 | + <column type="gboolean"/> |
1967 | + <!-- column-name icon-size --> |
1968 | + <column type="gint"/> |
1969 | + <!-- column-name identifier --> |
1970 | + <column type="gchararray"/> |
1971 | + <!-- column-name path --> |
1972 | + <column type="gchararray"/> |
1973 | + </columns> |
1974 | + </object> |
1975 | </interface> |
1976 | |
1977 | === modified file 'debian/changelog' |
1978 | --- debian/changelog 2011-02-28 15:38:15 +0000 |
1979 | +++ debian/changelog 2011-03-10 03:11:54 +0000 |
1980 | @@ -1,3 +1,27 @@ |
1981 | +ubuntuone-control-panel (0.9.1-0ubuntu1) natty; urgency=low |
1982 | + |
1983 | + * New upstream release. |
1984 | + - Display notice when merging volumes (LP: #674462) |
1985 | + - Show visible message when out of space (LP: #701729) |
1986 | + - Move 'get support' button (LP: #706661) |
1987 | + - Purchased Music folder not clearly shown (LP: #720650) |
1988 | + - More UI tweaks (LP: #728663) |
1989 | + - Redesign Services tab (LP: #729361) |
1990 | + - Better icon for folder owner (LP: #706034) |
1991 | + - Center status messages on toolbar (LP: #715715) |
1992 | + - Alter bandwidth throttling layout (LP: #715812) |
1993 | + - Tooltip for 'Edit' is unhelpful (LP: #715822) |
1994 | + - Tooltip for 'Buy more storage' not helpful (LP: #715875) |
1995 | + - Improve off-line experience (LP: #720990) |
1996 | + - Make link buttons in Account tab regular buttons (LP: #725143) |
1997 | + - Typo: 'accress' (LP: #725802) |
1998 | + - Show local device first in devices list (LP: #727996) |
1999 | + - Misc. improvements to GTK+ UI (LP: #727998) |
2000 | + - Service names should use title format (LP: #728027) |
2001 | + * Require new version of ubuntuone-client |
2002 | + |
2003 | + -- Rodney Dawes <rodney.dawes@ubuntu.com> Wed, 09 Mar 2011 21:59:45 -0500 |
2004 | + |
2005 | ubuntuone-control-panel (0.9.0-0ubuntu1) natty; urgency=low |
2006 | |
2007 | * New upstream release: |
2008 | |
2009 | === modified file 'debian/control' |
2010 | --- debian/control 2011-02-28 15:38:15 +0000 |
2011 | +++ debian/control 2011-03-10 03:11:54 +0000 |
2012 | @@ -17,7 +17,7 @@ |
2013 | ${python:Depends}, |
2014 | python, |
2015 | python-ubuntuone-control-panel (= ${binary:Version}), |
2016 | - ubuntuone-client (>= 1.5.4), |
2017 | + ubuntuone-client (>= 1.5.6), |
2018 | Recommends: ubuntuone-control-panel-gui |
2019 | Description: Ubuntu One Control Panel |
2020 | Desktop application to manage a Ubuntu One account. |
2021 | @@ -37,7 +37,7 @@ |
2022 | python-simplejson, |
2023 | python-twisted-core, |
2024 | python-twisted-web, |
2025 | - python-ubuntuone-client (>= 1.5.4), |
2026 | + python-ubuntuone-client (>= 1.5.6), |
2027 | ubuntu-sso-client (>= 1.1.11), |
2028 | Description: Ubuntu One Control Panel Python Libraries |
2029 | Ubuntu One Control Panel provides a Python library to manage an Ubuntu One |
2030 | @@ -54,9 +54,9 @@ |
2031 | python-defer, |
2032 | python-gobject, |
2033 | python-gtk2, |
2034 | - python-ubuntuone-client (>= 1.5.4), |
2035 | + python-ubuntuone-client (>= 1.5.6), |
2036 | ubuntu-sso-client (>= 1.1.11), |
2037 | - ubuntuone-client (>= 1.5.4), |
2038 | + ubuntuone-client (>= 1.5.6), |
2039 | ubuntuone-control-panel (= ${binary:Version}), |
2040 | Provides: ubuntuone-control-panel-gui |
2041 | Description: Ubuntu One Control Panel |
2042 | |
2043 | === modified file 'pylintrc' |
2044 | --- pylintrc 2011-01-07 20:07:39 +0000 |
2045 | +++ pylintrc 2011-03-10 03:11:54 +0000 |
2046 | @@ -49,7 +49,7 @@ |
2047 | # Disable the message(s) with the given id(s) or categories |
2048 | # W0142: Used * or ** magic |
2049 | # W0613: Unused argument 'yyy' |
2050 | -disable=R,I,W0142,W0613 |
2051 | +disable=R,I,W0142,W0613,W0511 |
2052 | |
2053 | |
2054 | [REPORTS] |
2055 | |
2056 | === modified file 'setup.py' |
2057 | --- setup.py 2011-02-28 15:38:15 +0000 |
2058 | +++ setup.py 2011-03-10 03:11:54 +0000 |
2059 | @@ -76,7 +76,7 @@ |
2060 | |
2061 | DistUtilsExtra.auto.setup( |
2062 | name='ubuntuone-control-panel', |
2063 | - version='0.9.0', |
2064 | + version='0.9.1', |
2065 | license='GPL v3', |
2066 | author='Natalia Bidart', |
2067 | author_email='natalia.bidart@canonical.com', |
2068 | |
2069 | === modified file 'ubuntuone/__init__.py' |
2070 | --- ubuntuone/__init__.py 2010-12-06 12:27:11 +0000 |
2071 | +++ ubuntuone/__init__.py 2011-03-10 03:11:54 +0000 |
2072 | @@ -17,5 +17,4 @@ |
2073 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
2074 | |
2075 | """Ubuntuone package.""" |
2076 | - |
2077 | __import__('pkg_resources').declare_namespace(__name__) |
2078 | |
2079 | === modified file 'ubuntuone/controlpanel/backend.py' |
2080 | --- ubuntuone/controlpanel/backend.py 2011-02-23 13:57:42 +0000 |
2081 | +++ ubuntuone/controlpanel/backend.py 2011-03-10 03:11:54 +0000 |
2082 | @@ -195,7 +195,6 @@ |
2083 | devices = yield self.wc.call_api(DEVICES_API) |
2084 | for d in devices: |
2085 | di = {} |
2086 | - result.append(di) |
2087 | di["type"] = d["kind"] |
2088 | di["name"] = d["description"] |
2089 | di["configurable"] = '' |
2090 | @@ -225,6 +224,11 @@ |
2091 | # di["available_services"] = "" |
2092 | # di["enabled_services"] = "" |
2093 | |
2094 | + if is_local: # prepend the local device! |
2095 | + result.insert(0, di) |
2096 | + else: |
2097 | + result.append(di) |
2098 | + |
2099 | returnValue(result) |
2100 | |
2101 | def type_n_id(self, device_id): |
2102 | |
2103 | === modified file 'ubuntuone/controlpanel/gtk/gui.py' |
2104 | --- ubuntuone/controlpanel/gtk/gui.py 2011-02-28 15:38:15 +0000 |
2105 | +++ ubuntuone/controlpanel/gtk/gui.py 2011-03-10 03:11:54 +0000 |
2106 | @@ -210,13 +210,10 @@ |
2107 | |
2108 | CREDENTIALS_ERROR = _('There was a problem while retrieving the ' |
2109 | 'credentials.') |
2110 | - AUTHORIZATION_DENIED = _('The authentication was cancelled.') |
2111 | NETWORK_OFFLINE = _('An internet connection is required to join or sign ' |
2112 | 'in to %(app_name)s.') |
2113 | - NETWORK_UNKNOWN = _('The internet connection state couldn\'t be ' |
2114 | - 'discovered. Maybe NetworkManager is not running?') |
2115 | - |
2116 | CONNECT = _('Connect to Ubuntu One') |
2117 | + LEARN_MORE_LINK = 'https://one.ubuntu.com/' |
2118 | |
2119 | def __init__(self, main_window): |
2120 | GreyableBin.__init__(self) |
2121 | @@ -299,6 +296,10 @@ |
2122 | self.set_property('greyed', True) |
2123 | self.warning_label.set_text('') |
2124 | |
2125 | + def on_learn_more_button_clicked(self, *a, **kw): |
2126 | + """User wants to learn more.""" |
2127 | + uri_hook(self.learn_more_button, self.LEARN_MORE_LINK) |
2128 | + |
2129 | @filter_by_app_name |
2130 | @log_call(logger.info, with_args=False) |
2131 | def on_credentials_found(self, app_name, credentials): |
2132 | @@ -325,23 +326,18 @@ |
2133 | def on_authorization_denied(self, app_name): |
2134 | """SSO backend notifies that user refused auth for 'app_name'.""" |
2135 | self.set_property('greyed', False) |
2136 | - self._set_warning(self.AUTHORIZATION_DENIED) |
2137 | |
2138 | @log_call(logger.info) |
2139 | def on_network_state_changed(self, state): |
2140 | """Network state is reported.""" |
2141 | - msg = None |
2142 | + msg = '' |
2143 | if state is networkstate.OFFLINE: |
2144 | msg = self.NETWORK_OFFLINE % {'app_name': U1_APP_NAME} |
2145 | - elif state is networkstate.UNKNOWN: |
2146 | - msg = self.NETWORK_UNKNOWN |
2147 | - |
2148 | - if msg is not None: |
2149 | self.set_sensitive(False) |
2150 | self._set_warning(msg) |
2151 | else: |
2152 | self.set_sensitive(True) |
2153 | - self.warning_label.set_text('') |
2154 | + self.warning_label.set_text(msg) |
2155 | self.sso_backend.find_credentials(U1_APP_NAME, {}, |
2156 | reply_handler=NO_OP, error_handler=error_handler) |
2157 | |
2158 | @@ -350,6 +346,8 @@ |
2159 | """The dashboard panel. The user can manage the subscription.""" |
2160 | |
2161 | TITLE = _('Welcome to Ubuntu One!') |
2162 | + VALUE_ERROR = _('The information could not be retrieved. ' |
2163 | + 'Maybe your internet connection is down?') |
2164 | |
2165 | def __init__(self, main_window=None): |
2166 | UbuntuOneBin.__init__(self) |
2167 | @@ -380,26 +378,32 @@ |
2168 | @log_call(logger.error) |
2169 | def on_account_info_error(self, error_dict=None): |
2170 | """Backend notifies of an error when fetching account info.""" |
2171 | - self.on_error() |
2172 | + self.on_error(message=self.VALUE_ERROR) |
2173 | self.is_processing = False |
2174 | |
2175 | |
2176 | class VolumesPanel(UbuntuOneBin, ControlPanelMixin): |
2177 | """The volumes panel.""" |
2178 | |
2179 | - TITLE = _('Select the folders from your personal cloud that you want ' |
2180 | - 'synchronized in this device.') |
2181 | + TITLE = _('Select which folders from your cloud you want to sync with ' |
2182 | + 'this computer') |
2183 | MY_FOLDERS = _('My folders') |
2184 | ALWAYS_SUBSCRIBED = _('Always in sync!') |
2185 | FREE_SPACE = _('%(free_space)s available storage') |
2186 | NO_VOLUMES = _('No folders to show.') |
2187 | NAME_NOT_SET = _('[unknown user name]') |
2188 | + CONFIRM_MERGE = _('The contents of your cloud folder will be merged with ' |
2189 | + 'your local folder "%(folder_path)s" when subscribing.\n' |
2190 | + 'Do you want to subscribe to this cloud folder?') |
2191 | + MUSIC_DISPLAY_NAME = _('Purchased Music') |
2192 | + MUSIC_REAL_PATH = '~/.ubuntuone/Purchased from Ubuntu One' |
2193 | |
2194 | MAX_COLS = 8 |
2195 | |
2196 | - CONTACT_ICON_NAME = 'system-users' |
2197 | + CONTACT_ICON_NAME = 'avatar-default' |
2198 | FOLDER_ICON_NAME = 'folder' |
2199 | SHARE_ICON_NAME = 'folder-remote' |
2200 | + MUSIC_ICON_NAME = 'audio-x-generic' |
2201 | ROW_HEADER = '<span font_size="large"><b>%s</b></span> ' \ |
2202 | '<span foreground="grey">%s</span>' |
2203 | ROOT = '%s - <span foreground="%s" font_size="small">%s</span>' |
2204 | @@ -410,6 +414,12 @@ |
2205 | self.add(self.itself) |
2206 | self.show_all() |
2207 | |
2208 | + kw = dict(parent=main_window, |
2209 | + flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, |
2210 | + type=gtk.MESSAGE_WARNING, |
2211 | + buttons=gtk.BUTTONS_YES_NO) |
2212 | + self.confirm_dialog = gtk.MessageDialog(**kw) |
2213 | + |
2214 | # name, subscribed, icon name, show toggle, sensitive, icon size, |
2215 | # id, path |
2216 | self._empty_row = ('', False, '', False, False, gtk.ICON_SIZE_MENU, |
2217 | @@ -427,7 +437,14 @@ |
2218 | def _process_path(self, path): |
2219 | """Trim 'path' so the '~' is removed.""" |
2220 | home = os.path.expanduser('~') |
2221 | - return path.replace(os.path.join(home, ''), '') |
2222 | + music_path = os.path.expanduser(self.MUSIC_REAL_PATH) |
2223 | + |
2224 | + if path == music_path: |
2225 | + result = self.MUSIC_DISPLAY_NAME |
2226 | + else: |
2227 | + result = path.replace(os.path.join(home, ''), '') |
2228 | + |
2229 | + return result |
2230 | |
2231 | def on_volumes_info_ready(self, info): |
2232 | """Backend notifies of volumes info.""" |
2233 | @@ -445,13 +462,10 @@ |
2234 | |
2235 | if name: |
2236 | name = name + "'s" |
2237 | - icon_name = self.SHARE_ICON_NAME |
2238 | - |
2239 | # we already added user folders, let's add an empty row |
2240 | treeiter = self.volumes_store.append(None, self._empty_row) |
2241 | else: |
2242 | name = self.MY_FOLDERS |
2243 | - icon_name = self.FOLDER_ICON_NAME |
2244 | |
2245 | free_bytes_args = {'free_space': self.humanize(int(free_bytes))} |
2246 | row = (self.ROW_HEADER % (name, self.FREE_SPACE % free_bytes_args), |
2247 | @@ -463,6 +477,7 @@ |
2248 | for volume in volumes: |
2249 | sensitive = True |
2250 | name = self._process_path(volume[u'path']) |
2251 | + icon_name = self.FOLDER_ICON_NAME |
2252 | |
2253 | is_root = volume[u'type'] == backend.ControlBackend.ROOT_TYPE |
2254 | is_share = volume[u'type'] == backend.ControlBackend.SHARE_TYPE |
2255 | @@ -472,6 +487,9 @@ |
2256 | name = self.ROOT % (name, ORANGE, self.ALWAYS_SUBSCRIBED) |
2257 | elif is_share: |
2258 | name = volume[u'name'] |
2259 | + icon_name = self.SHARE_ICON_NAME |
2260 | + elif name == self.MUSIC_DISPLAY_NAME: |
2261 | + icon_name = self.MUSIC_ICON_NAME |
2262 | |
2263 | row = (name, bool(volume[u'subscribed']), icon_name, True, |
2264 | sensitive, gtk.ICON_SIZE_MENU, volume['volume_id'], |
2265 | @@ -506,15 +524,24 @@ |
2266 | """The user toggled 'widget'.""" |
2267 | treeiter = self.volumes_store.get_iter(path) |
2268 | volume_id = self.volumes_store.get_value(treeiter, 6) |
2269 | - subscribed = not self.volumes_store.get_value(treeiter, 1) |
2270 | - |
2271 | - self.volumes_store.set_value(treeiter, 1, subscribed) |
2272 | - |
2273 | - self.backend.change_volume_settings(volume_id, |
2274 | - {'subscribed': bool_str(subscribed)}, |
2275 | - reply_handler=NO_OP, error_handler=error_handler) |
2276 | - |
2277 | - self.is_processing = True |
2278 | + volume_path = self.volumes_store.get_value(treeiter, 7) |
2279 | + subscribed = self.volumes_store.get_value(treeiter, 1) |
2280 | + |
2281 | + response = gtk.RESPONSE_YES |
2282 | + if not subscribed and os.path.exists(volume_path): |
2283 | + self.confirm_dialog.set_markup(self.CONFIRM_MERGE % |
2284 | + {'folder_path': volume_path}) |
2285 | + response = self.confirm_dialog.run() |
2286 | + self.confirm_dialog.hide() |
2287 | + |
2288 | + if response == gtk.RESPONSE_YES: |
2289 | + subscribed = not subscribed |
2290 | + self.volumes_store.set_value(treeiter, 1, subscribed) |
2291 | + self.backend.change_volume_settings(volume_id, |
2292 | + {'subscribed': bool_str(subscribed)}, |
2293 | + reply_handler=NO_OP, error_handler=error_handler) |
2294 | + |
2295 | + self.is_processing = True |
2296 | |
2297 | def on_volumes_view_row_activated(self, widget, path, *args, **kwargs): |
2298 | """The user double clicked on a row.""" |
2299 | @@ -607,10 +634,14 @@ |
2300 | return inner |
2301 | |
2302 | on_show_all_notifications_toggled = _change_device_settings |
2303 | - on_limit_bandwidth_toggled = _change_device_settings |
2304 | on_max_upload_speed_value_changed = _change_device_settings |
2305 | on_max_download_speed_value_changed = _change_device_settings |
2306 | |
2307 | + def on_limit_bandwidth_toggled(self, *args, **kwargs): |
2308 | + """The limit bandwidth checkbox was toggled.""" |
2309 | + self.throttling_limits.set_sensitive(self.limit_bandwidth.get_active()) |
2310 | + self._change_device_settings() |
2311 | + |
2312 | def on_remove_clicked(self, widget): |
2313 | """Remove button was clicked or activated.""" |
2314 | response = gtk.RESPONSE_YES |
2315 | @@ -659,14 +690,16 @@ |
2316 | |
2317 | if 'configurable' in kwargs: |
2318 | self.configurable = bool(kwargs['configurable']) |
2319 | - self.throttling.set_visible(self.configurable) |
2320 | + self.config_settings.set_visible(self.configurable) |
2321 | |
2322 | if 'show_all_notifications' in kwargs: |
2323 | value = bool(kwargs['show_all_notifications']) |
2324 | self.show_all_notifications.set_active(value) |
2325 | |
2326 | if 'limit_bandwidth' in kwargs: |
2327 | - self.limit_bandwidth.set_active(bool(kwargs['limit_bandwidth'])) |
2328 | + enabled = bool(kwargs['limit_bandwidth']) |
2329 | + self.limit_bandwidth.set_active(enabled) |
2330 | + self.throttling_limits.set_sensitive(enabled) |
2331 | |
2332 | for speed in ('max_upload_speed', 'max_download_speed'): |
2333 | if speed in kwargs: |
2334 | @@ -821,14 +854,12 @@ |
2335 | } |
2336 | |
2337 | INSTALL_PACKAGE = _('You need to install the package <i>%(package_name)s' |
2338 | - '</i> in order to enable replication.') |
2339 | - INSTALLING = _('The package <i>%(package_name)s</i> is being installed, ' |
2340 | - 'please wait...') |
2341 | - FAILED_INSTALL = _('The installation of <i>%(package_name)s</i> failed.') |
2342 | - SUCCESS_INSTALL = _('The installation of <i>%(package_name)s</i> ' |
2343 | - 'was successful.') |
2344 | + '</i> in order to enable more sync services.') |
2345 | + INSTALLING = _('installation of <i>%(package_name)s</i> in progress') |
2346 | + FAILED_INSTALL = _('<i>%(package_name)s</i> could not be installed') |
2347 | + SUCCESS_INSTALL = _('<i>%(package_name)s</i> was successfully installed') |
2348 | |
2349 | - def __init__(self, package_name): |
2350 | + def __init__(self, package_name, message=None): |
2351 | gtk.VBox.__init__(self) |
2352 | ControlPanelMixin.__init__(self, filename='install.ui') |
2353 | self.add(self.itself) |
2354 | @@ -839,10 +870,23 @@ |
2355 | self.transaction = None |
2356 | |
2357 | self.progress_bar = None |
2358 | - self.install_label.set_markup(self.INSTALL_PACKAGE % self.args) |
2359 | + |
2360 | + self.message = message |
2361 | + if self.message is None: |
2362 | + self.message = self.INSTALL_PACKAGE % self.args |
2363 | + self.reset() |
2364 | |
2365 | self.show() |
2366 | |
2367 | + def reset(self): |
2368 | + """Reset this interface.""" |
2369 | + children = self.itself.get_children() |
2370 | + if self.progress_bar in children: |
2371 | + self.itself.remove(self.progress_bar) |
2372 | + if self.install_button_box not in children: |
2373 | + self.itself.pack_start(self.install_button_box) |
2374 | + self.install_label.set_markup(self.message) |
2375 | + |
2376 | @package_manager.inline_callbacks |
2377 | def on_install_button_clicked(self, button): |
2378 | """The install button was clicked.""" |
2379 | @@ -869,10 +913,14 @@ |
2380 | self.transaction.connect('finished', self.on_install_finished) |
2381 | self.install_label.set_markup(self.INSTALLING % self.args) |
2382 | yield self.transaction.run() |
2383 | + except package_manager.aptdaemon.errors.NotAuthorizedError: |
2384 | + self.reset() |
2385 | except: # pylint: disable=W0702 |
2386 | logger.exception('on_install_button_clicked') |
2387 | self._set_warning(self.FAILED_INSTALL % self.args, |
2388 | self.install_label) |
2389 | + if self.progress_bar is not None: |
2390 | + self.progress_bar.hide() |
2391 | |
2392 | @log_call(logger.info) |
2393 | def on_install_finished(self, transaction, exit_code): |
2394 | @@ -880,6 +928,8 @@ |
2395 | if self.progress_bar is not None: |
2396 | self.progress_bar.set_sensitive(False) |
2397 | |
2398 | + logger.info('on_install_finished: installation of %r was %r', |
2399 | + self.package_name, exit_code) |
2400 | if exit_code != package_manager.aptdaemon.enums.EXIT_SUCCESS: |
2401 | if hasattr(transaction, 'error'): |
2402 | logger.error('transaction failed: %r', transaction.error) |
2403 | @@ -896,10 +946,15 @@ |
2404 | CHANGE_ERROR = _('The settings could not be changed,\n' |
2405 | 'previous values were restored.') |
2406 | |
2407 | - def __init__(self, service_id, name, *args, **kwargs): |
2408 | + def __init__(self, service_id, name, |
2409 | + container=None, check_button=None, action_button=None, |
2410 | + *args, **kwargs): |
2411 | gtk.VBox.__init__(self) |
2412 | ControlPanelMixin.__init__(self) |
2413 | self.id = service_id |
2414 | + self.container = container |
2415 | + self.check_button = check_button |
2416 | + self.action_button = action_button |
2417 | |
2418 | self.warning_label = gtk.Label() |
2419 | self.pack_start(self.warning_label, expand=False) |
2420 | @@ -915,11 +970,14 @@ |
2421 | |
2422 | FILES_SERVICE_NAME = _('File Sync') |
2423 | |
2424 | - def __init__(self): |
2425 | + def __init__(self, container, check_button, action_button): |
2426 | Service.__init__(self, service_id='file-sync', |
2427 | - name=self.FILES_SERVICE_NAME) |
2428 | + name=self.FILES_SERVICE_NAME, |
2429 | + container=container, |
2430 | + check_button=check_button, |
2431 | + action_button=action_button) |
2432 | |
2433 | - self.set_sensitive(False) |
2434 | + self.container.set_sensitive(False) |
2435 | |
2436 | self.backend.connect_to_signal('FileSyncStatusChanged', |
2437 | self.on_file_sync_status_changed) |
2438 | @@ -933,12 +991,15 @@ |
2439 | def on_file_sync_status_changed(self, status): |
2440 | """File Sync status changed.""" |
2441 | enabled = status != backend.FILE_SYNC_DISABLED |
2442 | - self.button.set_active(enabled) |
2443 | + logger.info('FileSyncService: enabled? %r', enabled) |
2444 | + self.check_button.set_active(enabled) |
2445 | + # if service is disabled, disable the action_button |
2446 | + self.action_button.set_sensitive(enabled) |
2447 | |
2448 | - if not self.is_sensitive(): |
2449 | + if not self.container.is_sensitive(): |
2450 | # first time we're getting this event |
2451 | - self.button.connect('toggled', self.on_button_toggled) |
2452 | - self.set_sensitive(True) |
2453 | + self.check_button.connect('toggled', self.on_button_toggled) |
2454 | + self.container.set_sensitive(True) |
2455 | |
2456 | def on_files_enabled(self): |
2457 | """Files service was enabled.""" |
2458 | @@ -951,8 +1012,8 @@ |
2459 | @log_call(logger.debug) |
2460 | def on_button_toggled(self, button): |
2461 | """Button was toggled, exclude/replicate the service properly.""" |
2462 | - logger.info('File Sync enabled? %r', self.button.get_active()) |
2463 | - if self.button.get_active(): |
2464 | + logger.info('File Sync enabled? %r', self.check_button.get_active()) |
2465 | + if self.check_button.get_active(): |
2466 | self.backend.enable_files(reply_handler=NO_OP, |
2467 | error_handler=error_handler) |
2468 | else: |
2469 | @@ -963,38 +1024,49 @@ |
2470 | class DesktopcouchService(Service): |
2471 | """A desktopcouch service.""" |
2472 | |
2473 | - def __init__(self, service_id, name, enabled, dependency=None): |
2474 | - Service.__init__(self, service_id, name) |
2475 | + INSTALL_PACKAGE = _('Install <i>%(plugin_name)s</i> plugin ' |
2476 | + 'for %(service_name)s sync') |
2477 | + |
2478 | + def __init__(self, service_id, name, enabled, |
2479 | + container, check_button, |
2480 | + dependency=None, dependency_name=None): |
2481 | + Service.__init__(self, service_id, name, |
2482 | + container, check_button, action_button=None) |
2483 | |
2484 | self.backend.connect_to_signal('ReplicationSettingsChanged', |
2485 | self.on_replication_settings_changed) |
2486 | self.backend.connect_to_signal('ReplicationSettingsChangeError', |
2487 | self.on_replication_settings_change_error) |
2488 | |
2489 | - self.button.set_active(enabled) |
2490 | + self.check_button.set_active(enabled) |
2491 | |
2492 | self.dependency = None |
2493 | if dependency is not None: |
2494 | - self.dependency = InstallPackage(dependency) |
2495 | + if dependency_name is None: |
2496 | + dependency_name = dependency |
2497 | + args = {'plugin_name': dependency_name, 'service_name': service_id} |
2498 | + message = self.INSTALL_PACKAGE % args |
2499 | + self.dependency = InstallPackage(dependency, message) |
2500 | self.dependency.connect('finished', self.on_depedency_finished) |
2501 | - self.pack_start(self.dependency, expand=False) |
2502 | - self.button.set_sensitive(False) |
2503 | - |
2504 | - self.button.connect('toggled', self.on_button_toggled) |
2505 | + |
2506 | + self.container.pack_end(self.dependency, expand=False) |
2507 | + self.check_button.set_sensitive(False) |
2508 | + |
2509 | + self.check_button.connect('toggled', self.on_button_toggled) |
2510 | |
2511 | def on_depedency_finished(self, widget): |
2512 | """The dependency was installed.""" |
2513 | - self.button.set_sensitive(True) |
2514 | - self.remove(self.dependency) |
2515 | + self.check_button.set_sensitive(True) |
2516 | + self.container.remove(self.dependency) |
2517 | self.dependency = None |
2518 | |
2519 | @log_call(logger.debug) |
2520 | def on_button_toggled(self, button): |
2521 | """Button was toggled, exclude/replicate the service properly.""" |
2522 | logger.info('Starting replication for %r? %r', |
2523 | - self.id, self.button.get_active()) |
2524 | + self.id, self.check_button.get_active()) |
2525 | |
2526 | - args = {'enabled': bool_str(self.button.get_active())} |
2527 | + args = {'enabled': bool_str(self.check_button.get_active())} |
2528 | self.backend.change_replication_settings(self.id, args, |
2529 | reply_handler=NO_OP, error_handler=error_handler) |
2530 | |
2531 | @@ -1011,26 +1083,28 @@ |
2532 | """The change of settings for this replication failed.""" |
2533 | if replication_id != self.id: |
2534 | return |
2535 | - self.button.set_active(not self.button.get_active()) |
2536 | + self.check_button.set_active(not self.check_button.get_active()) |
2537 | self._set_warning(self.CHANGE_ERROR, self.warning_label) |
2538 | |
2539 | |
2540 | class ServicesPanel(UbuntuOneBin, ControlPanelMixin): |
2541 | """The services panel.""" |
2542 | |
2543 | - TITLE = _('Ubuntu One services including data sync are enabled for the ' |
2544 | - 'data types and services listed below.') |
2545 | - CHOOSE_SERVICES = _('Choose services to synchronize with this computer:') |
2546 | + TITLE = _('Enable the sync services for this computer.') |
2547 | DESKTOPCOUCH_PKG = 'desktopcouch-ubuntuone' |
2548 | - BOOKMARKS = _('Bookmarks (Firefox)') |
2549 | - CONTACTS = _('Contacts (Evolution)') |
2550 | + BOOKMARKS = 'Firefox' |
2551 | + CONTACTS = 'Evolution' |
2552 | NO_PAIRING_RECORD = _('There is no Ubuntu One pairing record.') |
2553 | + CONTACTS_LINK = 'https://one.ubuntu.com/' |
2554 | |
2555 | def __init__(self, main_window=None): |
2556 | UbuntuOneBin.__init__(self) |
2557 | ControlPanelMixin.__init__(self, filename='services.ui') |
2558 | self.add(self.itself) |
2559 | |
2560 | + self.plugin_names = {'contacts': self.CONTACTS, |
2561 | + 'bookmarks': self.BOOKMARKS} |
2562 | + |
2563 | self.package_manager = package_manager.PackageManager() |
2564 | self.install_box = None |
2565 | |
2566 | @@ -1039,7 +1113,9 @@ |
2567 | self.backend.connect_to_signal('ReplicationsInfoError', |
2568 | self.on_replications_info_error) |
2569 | |
2570 | - self.files.pack_start(FileSyncService(), expand=False) |
2571 | + self.file_sync_service = FileSyncService(container=self.files, |
2572 | + check_button=self.file_sync_check, |
2573 | + action_button=self.file_sync_button) |
2574 | |
2575 | self.show() |
2576 | |
2577 | @@ -1048,6 +1124,30 @@ |
2578 | """Is desktopcouch installed?""" |
2579 | return self.package_manager.is_installed(self.DESKTOPCOUCH_PKG) |
2580 | |
2581 | + def on_file_sync_button_clicked(self, *args, **kwargs): |
2582 | + """The "Show me my U1 folder" button was clicked. |
2583 | + |
2584 | + XXX: this should be part of the FileSyncService widget. |
2585 | + XXX: the Ubuntu One folder should be the user's root. |
2586 | + |
2587 | + """ |
2588 | + uri_hook(None, FILE_URI_PREFIX + os.path.expanduser('~/Ubuntu One')) |
2589 | + |
2590 | + def on_contacts_button_clicked(self, *args, **kwargs): |
2591 | + """The "Take me to the Ubuntu One website" button was clicked. |
2592 | + |
2593 | + XXX: this should be part of the DesktopcouchService widget. |
2594 | + |
2595 | + """ |
2596 | + uri_hook(None, self.CONTACTS) |
2597 | + |
2598 | + def on_bookmarks_button_clicked(self, *args, **kwargs): |
2599 | + """The bookmarks button was clicked. |
2600 | + |
2601 | + XXX: this should be part of the DesktopcouchService widget. |
2602 | + |
2603 | + """ |
2604 | + |
2605 | @log_call(logger.debug) |
2606 | def load(self): |
2607 | """Load info.""" |
2608 | @@ -1062,7 +1162,7 @@ |
2609 | |
2610 | self.install_box = InstallPackage(self.DESKTOPCOUCH_PKG) |
2611 | self.install_box.connect('finished', self.load_replications) |
2612 | - self.itself.pack_start(self.install_box, expand=False) |
2613 | + self.itself.pack_end(self.install_box, expand=False) |
2614 | self.itself.reorder_child(self.install_box, 0) |
2615 | else: |
2616 | self.load_replications() |
2617 | @@ -1080,7 +1180,7 @@ |
2618 | @log_call(logger.debug) |
2619 | def on_replications_info_ready(self, info): |
2620 | """The replication info is ready.""" |
2621 | - self.on_success(self.CHOOSE_SERVICES) |
2622 | + self.on_success() |
2623 | |
2624 | self.replications.show() |
2625 | |
2626 | @@ -1088,18 +1188,20 @@ |
2627 | self.itself.remove(self.install_box) |
2628 | self.install_box = None |
2629 | |
2630 | - for child in self.replications.get_children(): |
2631 | - self.replications.remove(child) |
2632 | - |
2633 | for item in info: |
2634 | pkg = item['dependency'] |
2635 | if not pkg or self.package_manager.is_installed(pkg): |
2636 | pkg = None |
2637 | - child = DesktopcouchService(service_id=item['replication_id'], |
2638 | - name=item['name'], |
2639 | - enabled=bool(item['enabled']), |
2640 | - dependency=pkg) |
2641 | - self.replications.pack_start(child, expand=False) |
2642 | + |
2643 | + sid = item['replication_id'] |
2644 | + container = getattr(self, sid, None) |
2645 | + check_button = getattr(self, '%s_check' % sid, None) |
2646 | + name = self.plugin_names.get(sid, None) |
2647 | + child = DesktopcouchService(service_id=sid, name=item['name'], |
2648 | + enabled=bool(item['enabled']), container=container, |
2649 | + check_button=check_button, |
2650 | + dependency=pkg, dependency_name=name) |
2651 | + setattr(self, '%s_service' % sid, child) |
2652 | |
2653 | @log_call(logger.error) |
2654 | def on_replications_info_error(self, error_dict=None): |
2655 | @@ -1143,7 +1245,7 @@ |
2656 | ControlPanelMixin.__init__(self) |
2657 | |
2658 | self.label = LabelLoading(LOADING) |
2659 | - self.pack_start(self.label, expand=False) |
2660 | + self.pack_start(self.label, expand=True) |
2661 | |
2662 | self.button = gtk.LinkButton(uri='') |
2663 | self.button.connect('clicked', self._on_button_clicked) |
2664 | @@ -1237,7 +1339,11 @@ |
2665 | @log_call(logger.error) |
2666 | def on_file_sync_status_error(self, error_dict=None): |
2667 | """Backend notifies of an error when fetching file sync status.""" |
2668 | - self._update_status(WARNING_MARKUP % self.FILE_SYNC_ERROR, |
2669 | + msg = self.FILE_SYNC_ERROR |
2670 | + reason = error_dict.get('error_msg', '') if error_dict else '' |
2671 | + if reason: |
2672 | + msg += ' (' + reason + ')' |
2673 | + self._update_status(WARNING_MARKUP % msg, |
2674 | self.RESTART, self.on_restart_clicked, |
2675 | tooltip=self.RESTART_TOOLTIP) |
2676 | |
2677 | @@ -1291,7 +1397,8 @@ |
2678 | gobject.TYPE_NONE, ()), |
2679 | } |
2680 | |
2681 | - QUOTA_LABEL = _('Using %(used)s of %(total)s (%(percentage).1f%%)') |
2682 | + QUOTA_LABEL = _('Using %(used)s of %(total)s (%(percentage).0f%%)') |
2683 | + QUOTA_THRESHOLD = 0.95 |
2684 | DASHBOARD_BUTTON_NAME = 'Account' |
2685 | SERVICES_BUTTON_NAME = 'Devices' # Intentional until the theme is fixed |
2686 | |
2687 | @@ -1321,7 +1428,7 @@ |
2688 | self.quota_box.reorder_child(self.quota_label, 0) |
2689 | |
2690 | self.status_label = FileSyncStatus() |
2691 | - self.status_box.pack_end(self.status_label, expand=False) |
2692 | + self.status_box.pack_end(self.status_label, expand=True) |
2693 | |
2694 | self.dashboard = DashboardPanel(main_window=main_window) |
2695 | self.volumes = VolumesPanel(main_window=main_window) |
2696 | @@ -1352,20 +1459,32 @@ |
2697 | lambda widget: self.emit('local-device-removed')) |
2698 | |
2699 | self.services_button.set_name(self.SERVICES_BUTTON_NAME) |
2700 | - self.services_button.connect('clicked', lambda b: self.services.load()) |
2701 | self.services_button.set_tooltip_text(self.SERVICES_BUTTON_TOOLTIP) |
2702 | + self.services.load() |
2703 | |
2704 | def _update_quota(self, msg, data=None): |
2705 | """Update the quota info.""" |
2706 | - self.quota_label.set_markup(msg) |
2707 | - self.quota_label.stop() |
2708 | - |
2709 | fraction = 0.0 |
2710 | if data is not None: |
2711 | fraction = data.get('percentage', 0.0) / 100 |
2712 | if fraction > 0 and fraction < 0.05: |
2713 | fraction = 0.05 |
2714 | - self.quota_progressbar.set_fraction(fraction) |
2715 | + else: |
2716 | + fraction = round(fraction, 2) |
2717 | + |
2718 | + logger.debug('ManagementPanel: updating quota to %r.', fraction) |
2719 | + if fraction >= self.QUOTA_THRESHOLD: |
2720 | + self.quota_label.set_markup(WARNING_MARKUP % msg) |
2721 | + else: |
2722 | + self.quota_label.set_markup(msg) |
2723 | + self.quota_label.stop() |
2724 | + |
2725 | + if fraction == 0.0: |
2726 | + self.quota_progressbar.set_sensitive(False) |
2727 | + else: |
2728 | + self.quota_progressbar.set_sensitive(True) |
2729 | + |
2730 | + self.quota_progressbar.set_fraction(min(fraction, 1)) |
2731 | |
2732 | def load(self): |
2733 | """Load the account info and file sync status list.""" |
2734 | @@ -1384,7 +1503,7 @@ |
2735 | @log_call(logger.error) |
2736 | def on_account_info_error(self, error_dict=None): |
2737 | """Backend notifies of an error when fetching account info.""" |
2738 | - self._update_quota(WARNING_MARKUP % VALUE_ERROR) |
2739 | + self._update_quota(msg='') |
2740 | |
2741 | |
2742 | class ControlPanel(gtk.Notebook): |
2743 | @@ -1439,7 +1558,7 @@ |
2744 | |
2745 | TITLE = _('%(app_name)s Control Panel') |
2746 | |
2747 | - def __init__(self, switch_to=None): |
2748 | + def __init__(self, switch_to=None, alert=False): |
2749 | super(ControlPanelWindow, self).__init__() |
2750 | |
2751 | self.set_title(self.TITLE % {'app_name': U1_APP_NAME}) |
2752 | @@ -1448,7 +1567,13 @@ |
2753 | self.set_size_request(-1, 525) # bug #683164 |
2754 | |
2755 | self.connect('delete-event', lambda w, e: gtk.main_quit()) |
2756 | - self.show() |
2757 | + if alert: |
2758 | + print "YES" |
2759 | + # NOTE this should prevent focus stealing but it does not :( |
2760 | + self.present_with_time(1) |
2761 | + self.set_urgency_hint(True) |
2762 | + else: |
2763 | + self.present() |
2764 | |
2765 | self.control_panel = ControlPanel(main_window=self) |
2766 | self.add(self.control_panel) |
2767 | |
2768 | === modified file 'ubuntuone/controlpanel/gtk/tests/__init__.py' |
2769 | --- ubuntuone/controlpanel/gtk/tests/__init__.py 2011-02-23 13:57:42 +0000 |
2770 | +++ ubuntuone/controlpanel/gtk/tests/__init__.py 2011-03-10 03:11:54 +0000 |
2771 | @@ -18,11 +18,21 @@ |
2772 | |
2773 | """The test suite for the GTK UI for the control panel for Ubuntu One.""" |
2774 | |
2775 | +import logging |
2776 | + |
2777 | from collections import defaultdict |
2778 | |
2779 | +from ubuntuone.devtools.handlers import MementoHandler |
2780 | + |
2781 | +from ubuntuone.controlpanel.backend import ControlBackend |
2782 | from ubuntuone.controlpanel.gtk import gui |
2783 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( |
2784 | FakedTransaction) |
2785 | +from ubuntuone.controlpanel.tests import TestCase |
2786 | + |
2787 | + |
2788 | +# Attribute 'yyy' defined outside __init__, access to a protected member |
2789 | +# pylint: disable=W0201, W0212 |
2790 | |
2791 | |
2792 | FAKE_ACCOUNT_INFO = {'type': 'Payed', 'name': 'Test me', |
2793 | @@ -32,26 +42,36 @@ |
2794 | |
2795 | ROOT = { |
2796 | u'volume_id': '', u'path': '/home/tester/My Ubuntu', |
2797 | - u'subscribed': 'True', u'type': u'ROOT', |
2798 | + u'subscribed': 'True', u'type': ControlBackend.ROOT_TYPE, |
2799 | +} |
2800 | + |
2801 | +MUSIC_FOLDER = { |
2802 | + u'volume_id': u'58236', u'subscribed': u'True', |
2803 | + u'type': ControlBackend.FOLDER_TYPE, |
2804 | + u'path': u'/home/tester/.ubuntuone/Purchased from Ubuntu One', |
2805 | + u'suggested_path': u'~/.ubuntuone/Purchased from Ubuntu One', |
2806 | } |
2807 | |
2808 | FAKE_FOLDERS_INFO = [ |
2809 | {u'volume_id': u'0', u'path': u'/home/tester/foo', |
2810 | - u'suggested_path': u'~/foo', u'subscribed': u'', u'type': u'UDF'}, |
2811 | + u'suggested_path': u'~/foo', u'subscribed': u'', |
2812 | + u'type': ControlBackend.FOLDER_TYPE}, |
2813 | {u'volume_id': u'1', u'path': u'/home/tester/bar', |
2814 | - u'suggested_path': u'~/bar', u'subscribed': u'True', u'type': u'UDF'}, |
2815 | + u'suggested_path': u'~/bar', u'subscribed': u'True', |
2816 | + u'type': ControlBackend.FOLDER_TYPE}, |
2817 | {u'volume_id': u'2', u'path': u'/home/tester/baz', |
2818 | - u'suggested_path': u'~/baz', u'subscribed': u'True', u'type': u'UDF'}, |
2819 | + u'suggested_path': u'~/baz', u'subscribed': u'True', |
2820 | + u'type': ControlBackend.FOLDER_TYPE}, |
2821 | ] |
2822 | |
2823 | FAKE_SHARES_INFO = [ |
2824 | {u'volume_id': u'1234', u'name': u'do', |
2825 | u'path': u'/home/tester/.local/share/ubuntuone/shares/do from Other User', |
2826 | - u'subscribed': u'', u'type': u'SHARE'}, |
2827 | + u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE}, |
2828 | |
2829 | {u'volume_id': u'5678', u'name': u're', |
2830 | u'path': u'/home/tester/.local/share/ubuntuone/shares/re from Other User', |
2831 | - u'subscribed': u'True', u'type': u'SHARE'}, |
2832 | + u'subscribed': u'True', u'type': ControlBackend.SHARE_TYPE}, |
2833 | ] |
2834 | |
2835 | FAKE_VOLUMES_INFO = [ |
2836 | @@ -207,7 +227,8 @@ |
2837 | self._args = args |
2838 | self._kwargs = kwargs |
2839 | self.was_run = False |
2840 | - self.is_visible = True |
2841 | + self.is_visible = False |
2842 | + self.markup = kwargs.get('message_format', None) |
2843 | self.show = lambda: setattr(self, 'is_visible', True) |
2844 | self.hide = lambda: setattr(self, 'is_visible', False) |
2845 | self.response_code = None |
2846 | @@ -216,3 +237,67 @@ |
2847 | """Set flag and return 'self.response_code'.""" |
2848 | self.was_run = True |
2849 | return self.response_code |
2850 | + |
2851 | + def set_markup(self, msg): |
2852 | + """Set the markup.""" |
2853 | + self.markup = msg |
2854 | + |
2855 | + |
2856 | +class BaseTestCase(TestCase): |
2857 | + """Basics for testing.""" |
2858 | + |
2859 | + # self.klass is not callable |
2860 | + # pylint: disable=E1102 |
2861 | + klass = None |
2862 | + kwargs = {} |
2863 | + |
2864 | + def setUp(self): |
2865 | + super(BaseTestCase, self).setUp() |
2866 | + self.patch(gui.os.path, 'expanduser', |
2867 | + lambda path: path.replace('~', USER_HOME)) |
2868 | + self.patch(gui.gtk, 'main', lambda: None) |
2869 | + self.patch(gui.gtk, 'MessageDialog', FakedConfirmDialog) |
2870 | + self.patch(gui.dbus, 'SessionBus', FakedSessionBus) |
2871 | + self.patch(gui.dbus, 'Interface', FakedInterface) |
2872 | + self.patch(gui.networkstate, 'NetworkManagerState', FakedNMState) |
2873 | + self.patch(gui.package_manager, 'PackageManager', FakedPackageManager) |
2874 | + |
2875 | + if self.klass is not None: |
2876 | + self.ui = self.klass(**self.kwargs) |
2877 | + |
2878 | + self.memento = MementoHandler() |
2879 | + self.memento.setLevel(logging.DEBUG) |
2880 | + gui.logger.addHandler(self.memento) |
2881 | + |
2882 | + def tearDown(self): |
2883 | + try: |
2884 | + self.ui.hide() |
2885 | + del self.ui |
2886 | + self.ui = None |
2887 | + except AttributeError: |
2888 | + pass |
2889 | + super(BaseTestCase, self).tearDown() |
2890 | + |
2891 | + def assert_image_equal(self, image, filename): |
2892 | + """Check that expected and actual represent the same image.""" |
2893 | + pb = gui.gtk.gdk.pixbuf_new_from_file(gui.get_data_file(filename)) |
2894 | + self.assertEqual(image.get_pixbuf().get_pixels(), pb.get_pixels()) |
2895 | + |
2896 | + def assert_backend_called(self, method_name, args, backend=None): |
2897 | + """Check that the control panel backend 'method_name' was called.""" |
2898 | + if backend is None: |
2899 | + backend = self.ui.backend |
2900 | + self.assertIn(method_name, backend._called) |
2901 | + kwargs = {'reply_handler': gui.NO_OP, |
2902 | + 'error_handler': gui.error_handler} |
2903 | + self.assertEqual(backend._called[method_name], (args, kwargs)) |
2904 | + |
2905 | + def assert_warning_correct(self, warning, text): |
2906 | + """Check that 'warning' is visible, showing 'text'.""" |
2907 | + self.assertTrue(warning.get_visible(), 'Must be visible.') |
2908 | + self.assertEqual(warning.get_label(), gui.WARNING_MARKUP % text) |
2909 | + |
2910 | + def assert_function_decorated(self, decorator, func): |
2911 | + """Check that 'func' is decorated with 'decorator'.""" |
2912 | + expected = decorator(lambda: None) |
2913 | + self.assertEqual(expected.func_code, func.im_func.func_code) |
2914 | |
2915 | === modified file 'ubuntuone/controlpanel/gtk/tests/test_gui.py' |
2916 | --- ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-02-28 15:38:15 +0000 |
2917 | +++ ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-03-10 03:11:54 +0000 |
2918 | @@ -20,645 +20,25 @@ |
2919 | |
2920 | from __future__ import division |
2921 | |
2922 | -import logging |
2923 | - |
2924 | -from ubuntuone.devtools.handlers import MementoHandler |
2925 | - |
2926 | from ubuntuone.controlpanel.gtk import gui |
2927 | from ubuntuone.controlpanel.gtk.tests import (FAKE_ACCOUNT_INFO, |
2928 | - FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, |
2929 | - FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO, ROOT, USER_HOME, |
2930 | - FakedNMState, FakedSSOBackend, FakedSessionBus, FakedInterface, |
2931 | - FakedPackageManager, FakedConfirmDialog, |
2932 | -) |
2933 | -from ubuntuone.controlpanel.tests import TOKEN, TestCase |
2934 | + FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, FAKE_FOLDERS_INFO, |
2935 | + FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO, |
2936 | + MUSIC_FOLDER, ROOT, USER_HOME, |
2937 | + FakedConfirmDialog, |
2938 | +) |
2939 | +from ubuntuone.controlpanel.gtk.tests.test_gui_basic import ( |
2940 | + ControlPanelMixinTestCase, |
2941 | +) |
2942 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( |
2943 | SUCCESS, FAILURE) |
2944 | |
2945 | |
2946 | # Attribute 'yyy' defined outside __init__, access to a protected member |
2947 | # pylint: disable=W0201, W0212 |
2948 | -# Too many lines in module |
2949 | -# pylint: disable=C0302 |
2950 | - |
2951 | - |
2952 | -class BaseTestCase(TestCase): |
2953 | - """Basics for testing.""" |
2954 | - |
2955 | - # self.klass is not callable |
2956 | - # pylint: disable=E1102 |
2957 | - klass = None |
2958 | - kwargs = {} |
2959 | - |
2960 | - def setUp(self): |
2961 | - super(BaseTestCase, self).setUp() |
2962 | - self.patch(gui.os.path, 'expanduser', |
2963 | - lambda path: path.replace('~', USER_HOME)) |
2964 | - self.patch(gui.gtk, 'main', lambda: None) |
2965 | - self.patch(gui.gtk, 'MessageDialog', FakedConfirmDialog) |
2966 | - self.patch(gui.dbus, 'SessionBus', FakedSessionBus) |
2967 | - self.patch(gui.dbus, 'Interface', FakedInterface) |
2968 | - self.patch(gui.networkstate, 'NetworkManagerState', FakedNMState) |
2969 | - self.patch(gui.package_manager, 'PackageManager', FakedPackageManager) |
2970 | - |
2971 | - if self.klass is not None: |
2972 | - self.ui = self.klass(**self.kwargs) |
2973 | - |
2974 | - self.memento = MementoHandler() |
2975 | - self.memento.setLevel(logging.DEBUG) |
2976 | - gui.logger.addHandler(self.memento) |
2977 | - |
2978 | - def tearDown(self): |
2979 | - try: |
2980 | - self.ui.hide() |
2981 | - del self.ui |
2982 | - self.ui = None |
2983 | - except AttributeError: |
2984 | - pass |
2985 | - super(BaseTestCase, self).tearDown() |
2986 | - |
2987 | - def assert_image_equal(self, image, filename): |
2988 | - """Check that expected and actual represent the same image.""" |
2989 | - pb = gui.gtk.gdk.pixbuf_new_from_file(gui.get_data_file(filename)) |
2990 | - self.assertEqual(image.get_pixbuf().get_pixels(), pb.get_pixels()) |
2991 | - |
2992 | - def assert_backend_called(self, method_name, args, backend=None): |
2993 | - """Check that the control panel backend 'method_name' was called.""" |
2994 | - if backend is None: |
2995 | - backend = self.ui.backend |
2996 | - self.assertIn(method_name, backend._called) |
2997 | - kwargs = {'reply_handler': gui.NO_OP, |
2998 | - 'error_handler': gui.error_handler} |
2999 | - self.assertEqual(backend._called[method_name], (args, kwargs)) |
3000 | - |
3001 | - def assert_warning_correct(self, warning, text): |
3002 | - """Check that 'warning' is visible, showing 'text'.""" |
3003 | - self.assertTrue(warning.get_visible(), 'Must be visible.') |
3004 | - self.assertEqual(warning.get_label(), gui.WARNING_MARKUP % text) |
3005 | - |
3006 | - def assert_function_decorated(self, decorator, func): |
3007 | - """Check that 'func' is decorated with 'decorator'.""" |
3008 | - expected = decorator(lambda: None) |
3009 | - self.assertEqual(expected.func_code, func.im_func.func_code) |
3010 | - |
3011 | - |
3012 | -class ControlPanelMixinTestCase(BaseTestCase): |
3013 | - """The test suite for the control panel widget.""" |
3014 | - |
3015 | - klass = gui.ControlPanelMixin |
3016 | - ui_filename = None |
3017 | - |
3018 | - def test_is_a_control_panel_mixin(self): |
3019 | - """Inherits from ControlPanelMixin.""" |
3020 | - self.assertIsInstance(self.ui, gui.ControlPanelMixin) |
3021 | - |
3022 | - def test_ui_can_be_created(self): |
3023 | - """UI main class exists and can be created.""" |
3024 | - self.assertTrue(self.ui is not None) |
3025 | - |
3026 | - |
3027 | -class ControlPanelWindowTestCase(BaseTestCase): |
3028 | - """The test suite for the control panel window.""" |
3029 | - |
3030 | - klass = gui.ControlPanelWindow |
3031 | - |
3032 | - def test_is_a_window(self): |
3033 | - """Inherits from gtk.Window.""" |
3034 | - self.assertIsInstance(self.ui, gui.gtk.Window) |
3035 | - |
3036 | - def test_startup_visibility(self): |
3037 | - """The widget is visible at startup.""" |
3038 | - self.assertTrue(self.ui.get_visible(), 'must be visible at startup.') |
3039 | - |
3040 | - def test_main_start_gtk_main_loop(self): |
3041 | - """The GTK main loop is started when calling main().""" |
3042 | - self.patch(gui.gtk, 'main', self._set_called) |
3043 | - self.ui.main() |
3044 | - self.assertEqual(self._called, ((), {}), 'gtk.main was called.') |
3045 | - |
3046 | - def test_closing_stops_the_main_lopp(self): |
3047 | - """The GTK main loop is stopped when closing the window.""" |
3048 | - self.patch(gui.gtk, 'main_quit', self._set_called) |
3049 | - self.ui.emit('delete-event', None) |
3050 | - self.assertEqual(self._called, ((), {}), 'gtk.main_quit was called.') |
3051 | - |
3052 | - def test_title_is_correct(self): |
3053 | - """The window title is correct.""" |
3054 | - expected = self.ui.TITLE % {'app_name': gui.U1_APP_NAME} |
3055 | - self.assertEqual(self.ui.get_title(), expected) |
3056 | - |
3057 | - def test_control_panel_is_the_only_child(self): |
3058 | - """The control panel is the window's content.""" |
3059 | - children = self.ui.get_children() |
3060 | - self.assertEqual(1, len(children)) |
3061 | - |
3062 | - control_panel = self.ui.get_children()[0] |
3063 | - self.assertTrue(control_panel is self.ui.control_panel) |
3064 | - self.assertIsInstance(self.ui.control_panel, gui.ControlPanel) |
3065 | - self.assertTrue(self.ui.control_panel.get_visible()) |
3066 | - |
3067 | - def test_main_window_is_passed_to_child(self): |
3068 | - """The child gets the main_window.""" |
3069 | - self.assertEqual(self.ui.control_panel.main_window, self.ui) |
3070 | - |
3071 | - def test_icon_name_is_correct(self): |
3072 | - """The icon name is correct.""" |
3073 | - self.assertEqual(self.ui.get_icon_name(), 'ubuntuone') |
3074 | - |
3075 | - def test_max_size(self): |
3076 | - """Max size is not bigger than 736x525 (LP: #645526, LP: #683164).""" |
3077 | - self.assertTrue(self.ui.get_size_request() <= (736, 525)) |
3078 | - |
3079 | - |
3080 | -class ControlPanelWindowParamsTestCase(ControlPanelWindowTestCase): |
3081 | - """The test suite for the control panel window when passing params.""" |
3082 | - |
3083 | - kwargs = {'switch_to': 'devices'} |
3084 | - |
3085 | - def test_switch_to(self): |
3086 | - """Can pass a 'switch_to' parameter to start on a particular tab.""" |
3087 | - actual = self.ui.control_panel.management.notebook.get_current_page() |
3088 | - self.assertEqual(actual, self.ui.control_panel.management.DEVICES_PAGE) |
3089 | - |
3090 | - |
3091 | -class ControlPanelWindowParamsNoneTestCase(ControlPanelWindowTestCase): |
3092 | - """The suite for the control panel window when passing None params.""" |
3093 | - |
3094 | - kwargs = {'switch_to': None} |
3095 | - |
3096 | - def test_switch_to(self): |
3097 | - """Can pass a 'switch_to' being None. Should default to dashboard.""" |
3098 | - actual = self.ui.control_panel.management.notebook.get_current_page() |
3099 | - expected = self.ui.control_panel.management.DASHBOARD_PAGE |
3100 | - self.assertEqual(actual, expected) |
3101 | - |
3102 | - |
3103 | -class ControlPanelWindowInvalidParamsTestCase(ControlPanelWindowTestCase): |
3104 | - """The suite for the control panel window when passing invalid params.""" |
3105 | - |
3106 | - kwargs = {'switch_to': 'yadda-yadda'} |
3107 | - |
3108 | - def test_switch_to(self): |
3109 | - """Can pass an invalid 'switch_to'. Should default to dashboard.""" |
3110 | - actual = self.ui.control_panel.management.notebook.get_current_page() |
3111 | - expected = self.ui.control_panel.management.DASHBOARD_PAGE |
3112 | - self.assertEqual(actual, expected) |
3113 | - |
3114 | - |
3115 | -class ControlPanelTestCase(BaseTestCase): |
3116 | - """The test suite for the control panel itself.""" |
3117 | - |
3118 | - klass = gui.ControlPanel |
3119 | - kwargs = {'main_window': object()} |
3120 | - |
3121 | - def assert_current_tab_correct(self, expected_tab): |
3122 | - """Check that the wiget 'expected_tab' is the current page.""" |
3123 | - actual = self.ui.get_nth_page(self.ui.get_current_page()) |
3124 | - self.assertTrue(expected_tab is actual) |
3125 | - |
3126 | - def test_is_a_notebook(self): |
3127 | - """Inherits from gtk.VBox.""" |
3128 | - self.assertIsInstance(self.ui, gui.gtk.Notebook) |
3129 | - |
3130 | - def test_startup_visibility(self): |
3131 | - """The widget is visible at startup.""" |
3132 | - self.assertTrue(self.ui.get_visible(), |
3133 | - 'must be visible at startup.') |
3134 | - |
3135 | - def test_startup_props(self): |
3136 | - """The tabs and border are not shown.""" |
3137 | - self.assertFalse(self.ui.get_show_border(), 'must not show border.') |
3138 | - self.assertFalse(self.ui.get_show_tabs(), 'must not show tabs.') |
3139 | - |
3140 | - def test_overview_is_shown_at_startup(self): |
3141 | - """The overview is shown at startup.""" |
3142 | - self.assertIsInstance(self.ui.overview, gui.OverviewPanel) |
3143 | - self.assert_current_tab_correct(self.ui.overview) |
3144 | - |
3145 | - def test_main_window_is_passed_to_child(self): |
3146 | - """The child gets the main_window.""" |
3147 | - self.assertEqual(self.ui.overview.main_window, |
3148 | - self.kwargs['main_window']) |
3149 | - |
3150 | - def test_on_show_management_panel(self): |
3151 | - """A ManagementPanel is shown when the callback is executed.""" |
3152 | - self.ui.on_show_management_panel() |
3153 | - self.assert_current_tab_correct(self.ui.management) |
3154 | - |
3155 | - def test_on_show_management_panel_is_idempotent(self): |
3156 | - """Only one ManagementPanel is shown.""" |
3157 | - self.ui.on_show_management_panel() |
3158 | - self.ui.on_show_management_panel() |
3159 | - |
3160 | - self.assert_current_tab_correct(self.ui.management) |
3161 | - |
3162 | - def test_credentials_found_shows_dashboard_management_panel(self): |
3163 | - """On 'credentials-found' signal, the management panel is shown. |
3164 | - |
3165 | - If first signal parameter is False, visible tab should be dashboard. |
3166 | - |
3167 | - """ |
3168 | - self.patch(self.ui.management, 'load', self._set_called) |
3169 | - self.ui.overview.emit('credentials-found', False, object()) |
3170 | - |
3171 | - self.assert_current_tab_correct(self.ui.management) |
3172 | - self.assertEqual(self.ui.management.notebook.get_current_page(), |
3173 | - self.ui.management.DASHBOARD_PAGE) |
3174 | - self.assertEqual(self._called, ((), {})) |
3175 | - |
3176 | - def test_credentials_found_shows_volumes_management_panel(self): |
3177 | - """On 'credentials-found' signal, the management panel is shown. |
3178 | - |
3179 | - If first signal parameter is True, visible tab should be volumes. |
3180 | - |
3181 | - """ |
3182 | - a_token = object() |
3183 | - self.ui.overview.emit('credentials-found', True, a_token) |
3184 | - |
3185 | - self.assert_current_tab_correct(self.ui.management) |
3186 | - self.assertEqual(self.ui.management.notebook.get_current_page(), |
3187 | - self.ui.management.VOLUMES_PAGE) |
3188 | - |
3189 | - def test_local_device_removed_shows_overview_panel(self): |
3190 | - """On 'local-device-removed' signal, the overview panel is shown.""" |
3191 | - self.ui.overview.emit('credentials-found', True, object()) |
3192 | - self.ui.management.emit('local-device-removed') |
3193 | - |
3194 | - self.assert_current_tab_correct(self.ui.overview) |
3195 | - |
3196 | - |
3197 | -class UbuntuOneBinTestCase(BaseTestCase): |
3198 | - """The test suite for a Ubuntu One panel.""" |
3199 | - |
3200 | - klass = gui.UbuntuOneBin |
3201 | - kwargs = {'title': 'Something old, something new and something blue.'} |
3202 | - |
3203 | - def test_is_a_vbox(self): |
3204 | - """Inherits from proper gtk widget.""" |
3205 | - self.assertIsInstance(self.ui, gui.gtk.VBox) |
3206 | - |
3207 | - def test_startup_visibility(self): |
3208 | - """The widget is visible at startup.""" |
3209 | - self.assertTrue(self.ui.get_visible(), |
3210 | - 'must be visible at startup.') |
3211 | - for child in self.ui.get_children(): |
3212 | - self.assertTrue(child.get_visible()) |
3213 | - |
3214 | - def test_title_is_a_panel_title(self): |
3215 | - """Title is the correct widget.""" |
3216 | - self.assertIsInstance(self.ui.title, gui.PanelTitle) |
3217 | - self.assertIn(self.ui.title, self.ui.get_children()) |
3218 | - |
3219 | - def test_title_markup_is_correct(self): |
3220 | - """The title markup is correctly set when passed as argument.""" |
3221 | - self.assertEqual(self.ui.title.label.get_text(), self.kwargs['title']) |
3222 | - |
3223 | - def test_title_is_correct(self): |
3224 | - """The title markup is correctly set when defined at class level.""" |
3225 | - ui = self.klass() # no title given |
3226 | - self.assertEqual(ui.title.label.get_text(), '') |
3227 | - |
3228 | - def test_message_is_a_label_loading(self): |
3229 | - """Message is the correct widget.""" |
3230 | - self.assertIsInstance(self.ui.message, gui.LabelLoading) |
3231 | - self.assertIn(self.ui.message, self.ui.get_children()) |
3232 | - |
3233 | - def test_on_success(self): |
3234 | - """Callback to stop the Loading and clear messages.""" |
3235 | - self.ui.on_success() |
3236 | - self.assertEqual(self.ui.message.get_label(), '') |
3237 | - self.assertFalse(self.ui.message.active) |
3238 | - |
3239 | - def test_on_success_with_message(self): |
3240 | - """Callback to stop the Loading and show a info message.""" |
3241 | - msg = 'WOW! <i>this rocks</i>' |
3242 | - self.ui.on_success(message=msg) |
3243 | - self.assertEqual(self.ui.message.get_label(), msg) |
3244 | - self.assertFalse(self.ui.message.active) |
3245 | - |
3246 | - def test_on_error(self): |
3247 | - """Callback to stop the Loading and clear messages.""" |
3248 | - self.ui.on_error() |
3249 | - self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
3250 | - self.assertFalse(self.ui.message.active) |
3251 | - |
3252 | - def test_on_error_with_message(self): |
3253 | - """Callback to stop the Loading and show a info message.""" |
3254 | - msg = 'WOW! <i>this does not rock</i> :-/' |
3255 | - self.ui.on_error(message=msg) |
3256 | - self.assert_warning_correct(self.ui.message, msg) |
3257 | - self.assertFalse(self.ui.message.active) |
3258 | - |
3259 | - def test_is_processing(self): |
3260 | - """The flag 'is_processing' is False on start.""" |
3261 | - self.assertFalse(self.ui.is_processing) |
3262 | - self.assertTrue(self.ui.is_sensitive()) |
3263 | - |
3264 | - def test_set_is_processing(self): |
3265 | - """When setting 'is_processing', the spinner is shown.""" |
3266 | - self.ui.is_processing = False |
3267 | - self.ui.is_processing = True |
3268 | - |
3269 | - self.assertTrue(self.ui.message.get_visible()) |
3270 | - self.assertTrue(self.ui.message.active) |
3271 | - self.assertFalse(self.ui.is_sensitive()) |
3272 | - |
3273 | - def test_unset_is_processing(self): |
3274 | - """When unsetting 'is_processing', the spinner is not shown.""" |
3275 | - self.ui.is_processing = True |
3276 | - self.ui.is_processing = False |
3277 | - |
3278 | - self.assertTrue(self.ui.message.get_visible()) |
3279 | - self.assertFalse(self.ui.message.active) |
3280 | - self.assertTrue(self.ui.is_sensitive()) |
3281 | - |
3282 | - |
3283 | -class OverwiewPanelTestCase(ControlPanelMixinTestCase): |
3284 | - """The test suite for the overview panel.""" |
3285 | - |
3286 | - klass = gui.OverviewPanel |
3287 | - kwargs = {'main_window': gui.gtk.Window()} |
3288 | - ui_filename = 'overview.ui' |
3289 | - |
3290 | - def test_is_a_greyable_bin(self): |
3291 | - """Inherits from GreyableBin.""" |
3292 | - self.assertIsInstance(self.ui, gui.GreyableBin) |
3293 | - |
3294 | - def test_inner_widget_is_packed(self): |
3295 | - """The 'itself' vbox is packed into the widget.""" |
3296 | - self.assertIn(self.ui.itself, self.ui.get_children()) |
3297 | - |
3298 | - def test_join_now_is_default(self): |
3299 | - """The 'join_now' button is the default widget.""" |
3300 | - self.assertTrue(self.ui.join_now_button.get_property('can-default')) |
3301 | - |
3302 | - def test_sso_backend(self): |
3303 | - """Has a correct SSO backend.""" |
3304 | - self.assertIsInstance(self.ui.sso_backend, FakedSSOBackend) |
3305 | - |
3306 | - def test_sso_backend_signals(self): |
3307 | - """The proper signals are connected to the backend.""" |
3308 | - self.assertEqual(self.ui.sso_backend._signals['CredentialsFound'], |
3309 | - [self.ui.on_credentials_found]) |
3310 | - self.assertEqual(self.ui.sso_backend._signals['CredentialsNotFound'], |
3311 | - [self.ui.on_credentials_not_found]) |
3312 | - self.assertEqual(self.ui.sso_backend._signals['CredentialsError'], |
3313 | - [self.ui.on_credentials_error]) |
3314 | - self.assertEqual(self.ui.sso_backend._signals['AuthorizationDenied'], |
3315 | - [self.ui.on_authorization_denied]) |
3316 | - |
3317 | - |
3318 | -class OverwiewNetworkStatePanelTestCase(OverwiewPanelTestCase): |
3319 | - """The test suite for the overview panel regarding network state.""" |
3320 | - |
3321 | - def test_network_state_is_created(self): |
3322 | - """The network state is created.""" |
3323 | - self.assertIsInstance(self.ui.network_manager_state, |
3324 | - gui.networkstate.NetworkManagerState) |
3325 | - self.assertEqual(self.ui.network_manager_state._kwargs['result_cb'], |
3326 | - self.ui.on_network_state_changed) |
3327 | - |
3328 | - def test_network_state_is_queried_at_startup(self): |
3329 | - """The network state is asked to the NetworkManagerState.""" |
3330 | - self.assertTrue('find_online_state' in |
3331 | - self.ui.network_manager_state._called) |
3332 | - |
3333 | - def test_state_online(self): |
3334 | - """Network connection is online.""" |
3335 | - self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
3336 | - # all green, no warning |
3337 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
3338 | - self.assertTrue(self.ui.get_sensitive()) |
3339 | - |
3340 | - def test_state_offline(self): |
3341 | - """Network connection is offline.""" |
3342 | - self.ui.on_network_state_changed(gui.networkstate.OFFLINE) |
3343 | - msg = self.ui.NETWORK_OFFLINE % {'app_name': gui.U1_APP_NAME} |
3344 | - |
3345 | - self.assert_warning_correct(self.ui.warning_label, msg) |
3346 | - self.assertFalse(self.ui.get_sensitive()) |
3347 | - |
3348 | - def test_state_unknown(self): |
3349 | - """Network connection is unknown.""" |
3350 | - self.ui.on_network_state_changed(gui.networkstate.UNKNOWN) |
3351 | - |
3352 | - self.assert_warning_correct(self.ui.warning_label, |
3353 | - self.ui.NETWORK_UNKNOWN) |
3354 | - self.assertFalse(self.ui.get_sensitive()) |
3355 | - |
3356 | - |
3357 | -class OverwiewPanelOnlineTestCase(OverwiewPanelTestCase): |
3358 | - """The test suite for the overview panel.""" |
3359 | - |
3360 | - def setUp(self): |
3361 | - super(OverwiewPanelOnlineTestCase, self).setUp() |
3362 | - self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
3363 | - |
3364 | - def test_find_credentials_is_called(self): |
3365 | - """Credentials are asked to SSO backend.""" |
3366 | - self.assertFalse(self.ui._credentials_are_new) |
3367 | - self.assert_backend_called('find_credentials', (gui.U1_APP_NAME, {}), |
3368 | - backend=self.ui.sso_backend) |
3369 | - |
3370 | - def test_on_credentials_found(self): |
3371 | - """Callback 'on_credentials_found' is correct.""" |
3372 | - self.ui.connect('credentials-found', self._set_called) |
3373 | - |
3374 | - self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
3375 | - |
3376 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
3377 | - # assume credentials were in local keyring |
3378 | - self.assertEqual(self._called, ((self.ui, False, TOKEN), {})) |
3379 | - |
3380 | - def test_on_credentials_found_when_creds_are_not_new(self): |
3381 | - """Callback 'on_credentials_found' distinguish if creds are new.""" |
3382 | - self.ui.connect('credentials-found', self._set_called) |
3383 | - |
3384 | - # credentials weren't in the system |
3385 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
3386 | - # now they are! |
3387 | - self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
3388 | - |
3389 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
3390 | - # assume credentials were not in local keyring |
3391 | - self.assertEqual(self._called, ((self.ui, True, TOKEN), {})) |
3392 | - |
3393 | - def test_on_credentials_not_found(self): |
3394 | - """Callback 'on_credentials_not_found' is correct.""" |
3395 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
3396 | - self.assertTrue(self.ui.get_visible()) |
3397 | - self.assertTrue(self.ui._credentials_are_new) |
3398 | - |
3399 | - def test_on_credentials_error(self): |
3400 | - """Callback 'on_credentials_error' is correct.""" |
3401 | - self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
3402 | - self.assertTrue(self.ui.get_visible()) |
3403 | - self.assert_warning_correct(self.ui.warning_label, |
3404 | - self.ui.CREDENTIALS_ERROR) |
3405 | - |
3406 | - def test_on_authorization_denied(self): |
3407 | - """Callback 'on_authorization_denied' is correct.""" |
3408 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) |
3409 | - self.assertTrue(self.ui.get_visible()) |
3410 | - self.assert_warning_correct(self.ui.warning_label, |
3411 | - self.ui.AUTHORIZATION_DENIED) |
3412 | - |
3413 | - |
3414 | -class OverwiewPanelAppNameMismatchTestCase(OverwiewPanelTestCase): |
3415 | - """The test suite for the overview panel when the app_name won't match.""" |
3416 | - |
3417 | - NOT_U1_APP = 'Not ' + gui.U1_APP_NAME |
3418 | - |
3419 | - def test_filter_by_app_name(self): |
3420 | - """The filter_by_app_name decorator is correct.""" |
3421 | - f = gui.filter_by_app_name(self._set_called) |
3422 | - f(self.ui, self.NOT_U1_APP) |
3423 | - self.assertFalse(self._called) |
3424 | - self.assertTrue(self.memento.check_info('ignoring', self.NOT_U1_APP)) |
3425 | - |
3426 | - args = ('test', object()) |
3427 | - kwargs = {'really': 'AWESOME'} |
3428 | - f(self.ui, gui.U1_APP_NAME, *args, **kwargs) |
3429 | - self.assertEqual(self._called, |
3430 | - ((self.ui, gui.U1_APP_NAME,) + args, kwargs)) |
3431 | - |
3432 | - def test_on_credentials_found(self): |
3433 | - """Callback 'on_credentials_found' is not executed.""" |
3434 | - self.assert_function_decorated(gui.filter_by_app_name, |
3435 | - self.ui.on_credentials_found) |
3436 | - |
3437 | - def test_on_credentials_not_found(self): |
3438 | - """Callback 'on_credentials_not_found' is not executed.""" |
3439 | - self.assert_function_decorated(gui.filter_by_app_name, |
3440 | - self.ui.on_credentials_not_found) |
3441 | - |
3442 | - def test_on_credentials_error(self): |
3443 | - """Callback 'on_credentials_error' is not executed.""" |
3444 | - self.assert_function_decorated(gui.filter_by_app_name, |
3445 | - self.ui.on_credentials_error) |
3446 | - |
3447 | - def test_on_authorization_denied(self): |
3448 | - """Callback 'on_authorization_denied' is not executed.""" |
3449 | - self.assert_function_decorated(gui.filter_by_app_name, |
3450 | - self.ui.on_authorization_denied) |
3451 | - |
3452 | - |
3453 | -class OverwiewPanelNoCredsTestCase(OverwiewPanelTestCase): |
3454 | - """The test suite for the overview panel when no credentials are found.""" |
3455 | - |
3456 | - def setUp(self): |
3457 | - super(OverwiewPanelNoCredsTestCase, self).setUp() |
3458 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
3459 | - |
3460 | - def test_startup_visibility(self): |
3461 | - """The widget is visible at startup.""" |
3462 | - self.assertTrue(self.ui.get_visible(), |
3463 | - 'must be visible at startup if credentials not found.') |
3464 | - |
3465 | - def test_warning_label_is_hidden(self): |
3466 | - """The warning label is not shown by default.""" |
3467 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
3468 | - |
3469 | - def test_image_is_correct(self): |
3470 | - """There is an image attribute and is correct.""" |
3471 | - self.assert_image_equal(self.ui.image, 'overview.png') |
3472 | - |
3473 | - def test_join_now_is_default_widget(self): |
3474 | - """The join now button is the default widget.""" |
3475 | - self.assertTrue(self.ui.join_now_button.get_property('can_default')) |
3476 | - |
3477 | - def test_join_now_button_clicked(self): |
3478 | - """Test the 'join now' button callback.""" |
3479 | - self.kwargs['main_window'].show() # ensure parent window is realized |
3480 | - self.addCleanup(self.kwargs['main_window'].hide) |
3481 | - |
3482 | - self.ui.join_now_button.clicked() |
3483 | - |
3484 | - window_id = self.kwargs['main_window'].window.xid |
3485 | - args = (gui.U1_APP_NAME, |
3486 | - {gui.TC_URL_KEY: gui.U1_TC_URL, |
3487 | - gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
3488 | - gui.WINDOW_ID_KEY: str(window_id), |
3489 | - gui.PING_URL_KEY: gui.U1_PING_URL}) |
3490 | - self.assert_backend_called('register', args, |
3491 | - backend=self.ui.sso_backend) |
3492 | - |
3493 | - def test_connect_button_clicked(self): |
3494 | - """Test the 'join now' button callback.""" |
3495 | - self.kwargs['main_window'].show() # ensure parent window is realized |
3496 | - self.addCleanup(self.kwargs['main_window'].hide) |
3497 | - |
3498 | - self.ui.connect_button.clicked() |
3499 | - |
3500 | - window_id = self.kwargs['main_window'].window.xid |
3501 | - args = (gui.U1_APP_NAME, |
3502 | - {gui.TC_URL_KEY: gui.U1_TC_URL, |
3503 | - gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
3504 | - gui.WINDOW_ID_KEY: str(window_id), |
3505 | - gui.PING_URL_KEY: gui.U1_PING_URL}) |
3506 | - self.assert_backend_called('login', args, |
3507 | - backend=self.ui.sso_backend) |
3508 | - |
3509 | - def test_join_now_button_clicked_set_greyed(self): |
3510 | - """Clicking on 'join_now' self is greyed.""" |
3511 | - self.ui.join_now_button.clicked() |
3512 | - self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
3513 | - |
3514 | - def test_join_now_button_clicked_removes_warning(self): |
3515 | - """Clicking on 'join_now' the warnings are removed.""" |
3516 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
3517 | - self.ui.join_now_button.clicked() |
3518 | - |
3519 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
3520 | - |
3521 | - def test_connect_button_clicked_set_greyed(self): |
3522 | - """Clicking on 'connect' self is greyed.""" |
3523 | - self.ui.connect_button.clicked() |
3524 | - self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
3525 | - |
3526 | - def test_connect_button_clicked_removes_warning(self): |
3527 | - """Clicking on 'connect' the warnings are removed.""" |
3528 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
3529 | - self.ui.connect_button.clicked() |
3530 | - |
3531 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
3532 | - |
3533 | - def test_on_credentials_not_found_unset_greyed(self): |
3534 | - """Callback 'on_credentials_not_found' unsets the 'greyed' prop.""" |
3535 | - self.ui.connect_button.clicked() |
3536 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
3537 | - |
3538 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
3539 | - |
3540 | - def test_on_credentials_error_unset_greyed(self): |
3541 | - """Callback 'on_credentials_error' unsets the 'greyed' prop.""" |
3542 | - self.ui.connect_button.clicked() |
3543 | - self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
3544 | - |
3545 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
3546 | - |
3547 | - def test_on_authorization_denied_unset_greyed(self): |
3548 | - """Callback 'on_authorization_denied' unsets the 'greyed' prop.""" |
3549 | - self.ui.connect_button.clicked() |
3550 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) |
3551 | - |
3552 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
3553 | - |
3554 | - def test_buttons_disabled_when_greyed(self): |
3555 | - """Buttons should be disabled when widget is greyed.""" |
3556 | - self.ui.set_sensitive(True) |
3557 | - self.ui.set_property('greyed', True) |
3558 | - |
3559 | - self.assertFalse(self.ui.join_now_button.is_sensitive()) |
3560 | - self.assertFalse(self.ui.connect_button.is_sensitive()) |
3561 | - |
3562 | - def test_buttons_enabled_when_not_greyed(self): |
3563 | - """Buttons should be enabled when widget is not greyed.""" |
3564 | - self.ui.set_sensitive(False) |
3565 | - self.ui.set_property('greyed', False) |
3566 | - |
3567 | - self.assertTrue(self.ui.join_now_button.is_sensitive()) |
3568 | - self.assertTrue(self.ui.connect_button.is_sensitive()) |
3569 | + |
3570 | +# Unused variable 'skip' |
3571 | +#pylint: disable=W0612 |
3572 | |
3573 | |
3574 | class DashboardTestCase(ControlPanelMixinTestCase): |
3575 | @@ -727,7 +107,7 @@ |
3576 | self.ui.on_account_info_error() |
3577 | |
3578 | self.assertFalse(self.ui.account.get_visible()) |
3579 | - self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
3580 | + self.assert_warning_correct(self.ui.message, self.ui.VALUE_ERROR) |
3581 | |
3582 | |
3583 | class VolumesTestCase(ControlPanelMixinTestCase): |
3584 | @@ -896,10 +276,61 @@ |
3585 | self.test_on_volumes_info_error() |
3586 | self.test_on_volumes_info_ready_with_no_volumes() |
3587 | |
3588 | + def test_clicking_on_row_opens_folder(self): |
3589 | + """The folder activated is opened.""" |
3590 | + self.patch(gui, 'uri_hook', self._set_called) |
3591 | + self.ui.on_volumes_info_ready(FAKE_VOLUMES_INFO) |
3592 | + |
3593 | + self.ui.volumes_view.row_activated('0:0', |
3594 | + self.ui.volumes_view.get_column(0)) |
3595 | + |
3596 | + self.assertEqual(self._called, |
3597 | + ((None, gui.FILE_URI_PREFIX + ROOT['path']), {})) |
3598 | + |
3599 | + def test_on_volumes_info_ready_with_music_folder(self): |
3600 | + """The volumes info is processed when ready.""" |
3601 | + info = [(u'', u'147852369', [ROOT] + [MUSIC_FOLDER])] |
3602 | + |
3603 | + self.ui.on_volumes_info_ready(info) |
3604 | + |
3605 | + treeiter = self.ui.volumes_store.get_iter_root() |
3606 | + row = self.ui.volumes_store.get(treeiter, *xrange(self.ui.MAX_COLS)) |
3607 | + |
3608 | + # walk 'Mine' folders children |
3609 | + treeiter = self.ui.volumes_store.iter_children(treeiter) |
3610 | + |
3611 | + # grab next row since first one is root |
3612 | + treeiter = self.ui.volumes_store.iter_next(treeiter) |
3613 | + row = self.ui.volumes_store.get(treeiter, *xrange(self.ui.MAX_COLS)) |
3614 | + |
3615 | + volume = MUSIC_FOLDER |
3616 | + expected_path = volume['path'].replace(USER_HOME, '~') |
3617 | + expected_path = expected_path.replace(self.ui.MUSIC_REAL_PATH, |
3618 | + self.ui.MUSIC_DISPLAY_NAME) |
3619 | + self.assertEqual(row[0], expected_path) |
3620 | + self.assertEqual(row[1], bool(volume['subscribed'])) |
3621 | + self.assertEqual(row[2], self.ui.MUSIC_ICON_NAME) |
3622 | + self.assertTrue(row[3], 'toggle should be shown on child!') |
3623 | + self.assertTrue(row[4], 'toggle should be sensitive') |
3624 | + self.assertEqual(row[5], gui.gtk.ICON_SIZE_MENU) |
3625 | + self.assertEqual(row[6], volume['volume_id']) |
3626 | + self.assertEqual(row[7], volume['path']) |
3627 | + |
3628 | + |
3629 | +class VolumesSubscriptionTestCase(VolumesTestCase): |
3630 | + """The test suite for the volumes panel.""" |
3631 | + |
3632 | + kwargs = {'main_window': object()} |
3633 | + tree_path = '0:3' # this is the /home/tester/foo folder, not subscribed |
3634 | + |
3635 | + def setUp(self): |
3636 | + super(VolumesSubscriptionTestCase, self).setUp() |
3637 | + self.patch(gui.os.path, 'exists', lambda path: True) |
3638 | + self.ui.confirm_dialog.response_code = gui.gtk.RESPONSE_YES |
3639 | + self.ui.on_volumes_info_ready(FAKE_VOLUMES_INFO) |
3640 | + |
3641 | def test_on_subscribed_toggled(self): |
3642 | """Clicking on 'subscribed' updates the folder subscription.""" |
3643 | - self.ui.on_volumes_info_ready(FAKE_VOLUMES_INFO) |
3644 | - |
3645 | real_rows = len(FAKE_VOLUMES_INFO) |
3646 | data = zip(range(real_rows)[::2], FAKE_VOLUMES_INFO) # skip emtpy rows |
3647 | for parent, (_, _, volumes) in data: |
3648 | @@ -930,8 +361,7 @@ |
3649 | |
3650 | def test_on_volume_setting_changed(self): |
3651 | """The setting for a volume was successfully changed.""" |
3652 | - self.ui.on_volumes_info_ready(FAKE_VOLUMES_INFO) |
3653 | - self.ui.on_subscribed_toggled(None, "0:0") |
3654 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3655 | |
3656 | self.ui.on_volume_settings_changed(volume_id=None) # id not used |
3657 | |
3658 | @@ -940,8 +370,7 @@ |
3659 | |
3660 | def test_on_volume_setting_change_error(self): |
3661 | """The setting for a volume was not successfully changed.""" |
3662 | - self.ui.on_volumes_info_ready(FAKE_VOLUMES_INFO) |
3663 | - self.ui.on_subscribed_toggled(None, "0:0") |
3664 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3665 | |
3666 | self.patch(self.ui, 'load', self._set_called) |
3667 | self.ui.on_volume_settings_change_error(volume_id=None, |
3668 | @@ -949,16 +378,66 @@ |
3669 | # reload folders list to sanitize the info in volumes_store |
3670 | self.assertTrue(self._called, ((), {})) |
3671 | |
3672 | - def test_clicking_on_row_opens_folder(self): |
3673 | - """The folder activated is opened.""" |
3674 | - self.patch(gui, 'uri_hook', self._set_called) |
3675 | - self.ui.on_volumes_info_ready(FAKE_VOLUMES_INFO) |
3676 | - |
3677 | - self.ui.volumes_view.row_activated('0:0', |
3678 | - self.ui.volumes_view.get_column(0)) |
3679 | - |
3680 | - self.assertEqual(self._called, |
3681 | - ((None, gui.FILE_URI_PREFIX + ROOT['path']), {})) |
3682 | + def test_confirm_dialog(self): |
3683 | + """The confirmation dialog is correct.""" |
3684 | + dialog = self.ui.confirm_dialog |
3685 | + |
3686 | + self.assertEqual(dialog._args, ()) |
3687 | + flags = gui.gtk.DIALOG_MODAL | gui.gtk.DIALOG_DESTROY_WITH_PARENT |
3688 | + kwargs = dict(parent=self.kwargs['main_window'], |
3689 | + flags=flags, type=gui.gtk.MESSAGE_WARNING, |
3690 | + buttons=gui.gtk.BUTTONS_YES_NO) |
3691 | + self.assertEqual(dialog._kwargs, kwargs) |
3692 | + |
3693 | + def test_subscribe_shows_confirmation_dialog(self): |
3694 | + """Clicking on subscribe displays a confirmation dialog.""" |
3695 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3696 | + |
3697 | + path = FAKE_FOLDERS_INFO[0]['path'] |
3698 | + self.assertTrue(self.ui.confirm_dialog.was_run, 'dialog was run') |
3699 | + self.assertEqual(self.ui.confirm_dialog.markup, |
3700 | + self.ui.CONFIRM_MERGE % {'folder_path': path}) |
3701 | + self.assertFalse(self.ui.confirm_dialog.is_visible, 'dialog was hid') |
3702 | + |
3703 | + def test_subscribe_does_not_call_backend_if_dialog_closed(self): |
3704 | + """Backend is not called if users closes the confirmation dialog.""" |
3705 | + self.ui.confirm_dialog.response_code = gui.gtk.RESPONSE_DELETE_EVENT |
3706 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3707 | + |
3708 | + self.assertNotIn('change_volume_settings', self.ui.backend._called) |
3709 | + self.assertFalse(self.ui.is_processing) |
3710 | + |
3711 | + def test_subscribe_does_not_call_backend_if_answer_is_no(self): |
3712 | + """Backend is not called if users clicks on 'No'.""" |
3713 | + self.ui.confirm_dialog.response_code = gui.gtk.RESPONSE_NO |
3714 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3715 | + |
3716 | + self.assertNotIn('change_volume_settings', self.ui.backend._called) |
3717 | + self.assertFalse(self.ui.is_processing) |
3718 | + |
3719 | + def test_no_confirmation_if_no_local_folder(self): |
3720 | + """The confirmation dialog is not shown if local folder not present.""" |
3721 | + self.patch(gui.os.path, 'exists', lambda path: False) |
3722 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3723 | + |
3724 | + self.assertFalse(self.ui.confirm_dialog.was_run, 'dialog was not run') |
3725 | + self.assertFalse(self.ui.confirm_dialog.is_visible, 'dialog was hid') |
3726 | + |
3727 | + def test_no_confirmation_if_unsubscribing(self): |
3728 | + """The confirmation dialog is not shown if unsubscribing.""" |
3729 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3730 | + |
3731 | + treeiter = self.ui.volumes_store.get_iter(self.tree_path) |
3732 | + assert self.ui.volumes_store.get_value(treeiter, 1) |
3733 | + |
3734 | + # reset flags |
3735 | + self.ui.confirm_dialog.was_run = False |
3736 | + self.ui.confirm_dialog.is_visible = False |
3737 | + |
3738 | + self.ui.on_subscribed_toggled(None, self.tree_path) |
3739 | + |
3740 | + self.assertFalse(self.ui.confirm_dialog.was_run, 'dialog was not run') |
3741 | + self.assertFalse(self.ui.confirm_dialog.is_visible, 'dialog was hid') |
3742 | |
3743 | |
3744 | class DeviceTestCase(ControlPanelMixinTestCase): |
3745 | @@ -984,6 +463,12 @@ |
3746 | self.assertEqual(device.limit_bandwidth.get_active(), |
3747 | bool(expected['limit_bandwidth'])) |
3748 | |
3749 | + config_enabled = self.ui.config_settings.get_sensitive() |
3750 | + self.assertEqual(device.configurable, config_enabled) |
3751 | + |
3752 | + limit_enabled = self.ui.throttling_limits.get_sensitive() |
3753 | + self.assertEqual(device.limit_bandwidth.get_active(), limit_enabled) |
3754 | + |
3755 | value = int(expected['max_upload_speed']) // gui.KILOBYTES |
3756 | self.assertEqual(device.max_upload_speed.get_value_as_int(), value) |
3757 | value = int(expected['max_download_speed']) // gui.KILOBYTES |
3758 | @@ -996,6 +481,9 @@ |
3759 | (self.ui.id, expected)) |
3760 | self.assertEqual(self.ui.warning_label.get_text(), '') |
3761 | |
3762 | + limit_enabled = self.ui.throttling_limits.get_sensitive() |
3763 | + self.assertEqual(self.ui.limit_bandwidth.get_active(), limit_enabled) |
3764 | + |
3765 | def modify_settings(self): |
3766 | """Modify settings so values actually change.""" |
3767 | new_val = not self.ui.show_all_notifications.get_active() |
3768 | @@ -1087,13 +575,13 @@ |
3769 | """A device can be updated from a dict.""" |
3770 | self.ui.update(configurable='') |
3771 | self.assertFalse(self.ui.configurable) |
3772 | - self.assertFalse(self.ui.throttling.get_visible()) |
3773 | + self.assertFalse(self.ui.config_settings.get_visible()) |
3774 | |
3775 | def test_update_configurable(self): |
3776 | """A device can be updated from a dict.""" |
3777 | self.ui.update(configurable='True') |
3778 | self.assertTrue(self.ui.configurable) |
3779 | - self.assertTrue(self.ui.throttling.get_visible()) |
3780 | + self.assertTrue(self.ui.config_settings.get_visible()) |
3781 | |
3782 | def test_update_show_all_notifications(self): |
3783 | """A device can be updated from a dict.""" |
3784 | @@ -1107,9 +595,11 @@ |
3785 | """A device can be updated from a dict.""" |
3786 | self.ui.update(limit_bandwidth='') |
3787 | self.assertFalse(self.ui.limit_bandwidth.get_active()) |
3788 | + self.assertFalse(self.ui.throttling_limits.get_sensitive()) |
3789 | |
3790 | self.ui.update(limit_bandwidth='True') |
3791 | self.assertTrue(self.ui.limit_bandwidth.get_active()) |
3792 | + self.assertTrue(self.ui.throttling_limits.get_sensitive()) |
3793 | |
3794 | def test_update_upload_speed(self): |
3795 | """A device can be updated from a dict.""" |
3796 | @@ -1610,7 +1100,8 @@ |
3797 | klass = gui.Service |
3798 | service_id = 'dc_test' |
3799 | name = u'Qué lindo test!' |
3800 | - kwargs = {'service_id': service_id, 'name': name} |
3801 | + kwargs = {'service_id': service_id, 'name': name, |
3802 | + 'container': None, 'check_button': None} |
3803 | |
3804 | def test_is_an_box(self): |
3805 | """Inherits from gtk.VBox.""" |
3806 | @@ -1647,7 +1138,7 @@ |
3807 | klass = gui.FileSyncService |
3808 | service_id = 'file-sync' |
3809 | name = gui.FileSyncService.FILES_SERVICE_NAME |
3810 | - kwargs = {} |
3811 | + kwargs = {'container': None, 'check_button': None, 'action_button': None} |
3812 | |
3813 | def test_backend_account_signals(self): |
3814 | """The proper signals are connected to the backend.""" |
3815 | @@ -1708,6 +1199,8 @@ |
3816 | self.ui.on_files_disabled() |
3817 | self.assertFalse(self.ui.button.get_active()) |
3818 | |
3819 | +FileSyncServiceTestCase.skip = 'LP: #729349' |
3820 | + |
3821 | |
3822 | class DesktopcouchServiceTestCase(ServiceTestCase): |
3823 | """The test suite for a desktopcouch service.""" |
3824 | @@ -1812,6 +1305,8 @@ |
3825 | |
3826 | self.assertEqual(self.ui.warning_label.get_text(), '') |
3827 | |
3828 | +DesktopcouchServiceTestCase.skip = 'LP: #729349' |
3829 | + |
3830 | |
3831 | class DesktopcouchServiceDisabledAtStartupTestCase(ServiceTestCase): |
3832 | """The test suite for a desktopcouch service when enabled=False.""" |
3833 | @@ -1854,6 +1349,8 @@ |
3834 | self.assertEqual(sorted(self.ui.get_children()), |
3835 | sorted([self.ui.button, self.ui.warning_label])) |
3836 | |
3837 | +DesktopcouchServiceWithDependencyTestCase.skip = 'LP: #729349' |
3838 | + |
3839 | |
3840 | class ServicesTestCase(ControlPanelMixinTestCase): |
3841 | """The test suite for the services panel.""" |
3842 | @@ -1902,6 +1399,8 @@ |
3843 | child, = self.ui.files.get_children() |
3844 | self.assertIsInstance(child, gui.FileSyncService) |
3845 | |
3846 | + test_files_is_a_file_sync_service.skip = 'LP: #729349' |
3847 | + |
3848 | |
3849 | class ServicesWithoutDesktopcouchTestCase(ServicesTestCase): |
3850 | """The test suite for the services panel when DC is not installed.""" |
3851 | @@ -2004,6 +1503,30 @@ |
3852 | self.ui.on_replications_info_ready(info=FAKE_REPLICATIONS_INFO) |
3853 | self.test_replications() |
3854 | |
3855 | + def test_service_name_in_mapping(self): |
3856 | + """If available, use a user-friendly, translatable service name.""" |
3857 | + for sid, name in self.ui.service_names.iteritems(): |
3858 | + info = [{'replication_id': sid, 'name': 'Bar', |
3859 | + 'enabled': 'True', 'dependency': ''}] |
3860 | + self.ui.on_replications_info_ready(info=info) |
3861 | + |
3862 | + child, = self.ui.replications.get_children() |
3863 | + self.assertEqual(child.button.get_label(), name) |
3864 | + |
3865 | + def test_service_name_not_in_mapping(self): |
3866 | + """If available, use a user-friendly, translatable service name.""" |
3867 | + sid = 'not-in-mapping' |
3868 | + assert sid not in self.ui.service_names |
3869 | + |
3870 | + info = [{'replication_id': sid, 'name': 'Bar', |
3871 | + 'enabled': 'True', 'dependency': ''}] |
3872 | + self.ui.on_replications_info_ready(info=info) |
3873 | + |
3874 | + child, = self.ui.replications.get_children() |
3875 | + self.assertEqual(child.button.get_label(), info[0]['name']) |
3876 | + |
3877 | +ServicesWithDesktopcouchTestCase.skip = 'LP: #729349' |
3878 | + |
3879 | |
3880 | class ServicesWithDesktopcouchErrorTestCase(ServicesTestCase): |
3881 | """The test suite for the services panel.""" |
3882 | @@ -2046,6 +1569,8 @@ |
3883 | self.assertFalse(self.ui.message.active) |
3884 | self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
3885 | |
3886 | +ServicesWithDesktopcouchErrorTestCase.skip = 'LP: #729349' |
3887 | + |
3888 | |
3889 | class FileSyncStatusTestCase(ControlPanelMixinTestCase): |
3890 | """Test case for a file sync status widget.""" |
3891 | @@ -2065,7 +1590,8 @@ |
3892 | """ |
3893 | self.assertTrue(self.ui.label.get_visible()) |
3894 | self.assertFalse(self.ui.label.active) |
3895 | - self.assertTrue(self.ui.label.get_label().endswith(status)) |
3896 | + msg = '%r does not end with %r' % (self.ui.label.get_label(), status) |
3897 | + self.assertTrue(self.ui.label.get_label().endswith(status), msg) |
3898 | |
3899 | self.assertTrue(self.ui.button.is_sensitive()) |
3900 | self.assertFalse(self.ui.button.get_visited()) |
3901 | @@ -2212,10 +1738,21 @@ |
3902 | action=self.ui.DISCONNECT, |
3903 | tooltip=self.ui.DISCONNECT_TOOLTIP) |
3904 | |
3905 | - def test_on_file_sync_status_error(self): |
3906 | - """The file sync status couldn't be retrieved.""" |
3907 | - self.patch(self.ui, 'on_restart_clicked', self._set_called) |
3908 | - self.ui.on_file_sync_status_error({'error_msg': 'error msg'}) |
3909 | + def test_on_file_sync_status_error_with_error_msg(self): |
3910 | + """The file sync status couldn't be retrieved.""" |
3911 | + self.patch(self.ui, 'on_restart_clicked', self._set_called) |
3912 | + msg = 'error message' |
3913 | + self.ui.on_file_sync_status_error({'error_msg': msg}) |
3914 | + |
3915 | + msg = gui.WARNING_MARKUP % (self.ui.FILE_SYNC_ERROR + ' (' + msg + ')') |
3916 | + self.assert_status_correct(msg, |
3917 | + action=self.ui.RESTART, |
3918 | + tooltip=self.ui.RESTART_TOOLTIP) |
3919 | + |
3920 | + def test_on_file_sync_status_error_without_error_msg(self): |
3921 | + """The file sync status couldn't be retrieved.""" |
3922 | + self.patch(self.ui, 'on_restart_clicked', self._set_called) |
3923 | + self.ui.on_file_sync_status_error() |
3924 | |
3925 | msg = gui.WARNING_MARKUP % self.ui.FILE_SYNC_ERROR |
3926 | self.assert_status_correct(msg, |
3927 | @@ -2276,17 +1813,21 @@ |
3928 | """Check that the displayed account info matches 'info'.""" |
3929 | used = int(info['quota_used']) |
3930 | total = int(info['quota_total']) |
3931 | - percentage = (used / total) * 100 |
3932 | + percentage = round((used / total) * 100, 2) |
3933 | expected = {'used': self.ui.humanize(used), |
3934 | 'total': self.ui.humanize(total), |
3935 | 'percentage': percentage} |
3936 | - self.assertEqual(self.ui.quota_label.get_text(), |
3937 | - self.ui.QUOTA_LABEL % expected) |
3938 | + msg = self.ui.QUOTA_LABEL % expected |
3939 | + self.assertEqual(self.ui.quota_label.get_text(), msg) |
3940 | + |
3941 | + if percentage >= self.ui.QUOTA_THRESHOLD * 100: |
3942 | + self.assert_warning_correct(self.ui.quota_label, msg) |
3943 | |
3944 | if progressbar_fraction is None: |
3945 | - progressbar_fraction = percentage / 100 |
3946 | + progressbar_fraction = min(percentage / 100, 1) |
3947 | self.assertEqual(self.ui.quota_progressbar.get_fraction(), |
3948 | progressbar_fraction) |
3949 | + self.assertTrue(self.ui.quota_progressbar.get_sensitive()) |
3950 | |
3951 | def test_is_a_vbox(self): |
3952 | """Inherits from gtk.VBox.""" |
3953 | @@ -2386,13 +1927,13 @@ |
3954 | |
3955 | self.assertEqual(self._called, ((), {})) |
3956 | |
3957 | - def test_entering_services_tab_loads_content(self): |
3958 | - """The services info is loaded when entering the Devices tab.""" |
3959 | + def test_entering_services_tab_does_not_load_content(self): |
3960 | + """The services info is not loaded when entering the Services tab.""" |
3961 | self.patch(self.ui.services, 'load', self._set_called) |
3962 | # clean backend calls |
3963 | self.ui.services_button.clicked() |
3964 | |
3965 | - self.assertEqual(self._called, ((), {})) |
3966 | + self.assertEqual(self._called, False) |
3967 | |
3968 | def test_quota_placeholder_is_loading(self): |
3969 | """Placeholders for quota label is a Loading widget.""" |
3970 | @@ -2403,16 +1944,20 @@ |
3971 | """The account info is processed when ready.""" |
3972 | self.ui.on_account_info_ready(FAKE_ACCOUNT_INFO) |
3973 | self.assert_account_info_correct(FAKE_ACCOUNT_INFO) |
3974 | - |
3975 | - for widget in (self.ui.quota_label,): |
3976 | - self.assertFalse(widget.active) |
3977 | + self.assertFalse(self.ui.quota_label.active) |
3978 | |
3979 | def test_on_account_info_error(self): |
3980 | """The account info couldn't be retrieved.""" |
3981 | self.ui.on_account_info_error() |
3982 | - for widget in (self.ui.quota_label,): |
3983 | - self.assert_warning_correct(widget, gui.VALUE_ERROR) |
3984 | - self.assertFalse(widget.active) |
3985 | + self.assertEqual(self.ui.quota_label.get_text(), '') |
3986 | + self.assertEqual(self.ui.quota_progressbar.get_fraction(), 0) |
3987 | + self.assertFalse(self.ui.quota_progressbar.get_sensitive()) |
3988 | + self.assertFalse(self.ui.quota_label.active) |
3989 | + |
3990 | + def test_on_account_info_error_after_success(self): |
3991 | + """The account info couldn't be retrieved.""" |
3992 | + self.test_on_account_info_ready() |
3993 | + self.test_on_account_info_error() |
3994 | |
3995 | def test_on_account_info_ready_quota_unused(self): |
3996 | """The used quota is correct when unused.""" |
3997 | @@ -2429,6 +1974,26 @@ |
3998 | |
3999 | self.assert_account_info_correct(info, progressbar_fraction=0.05) |
4000 | |
4001 | + def test_on_account_info_ready_quota_used_at_threshold(self): |
4002 | + """Show red notification when quota usage is same as threshold.""" |
4003 | + info = FAKE_ACCOUNT_INFO.copy() |
4004 | + |
4005 | + info['quota_total'] = '12345678' |
4006 | + info['quota_used'] = str(int(int(info['quota_total']) * |
4007 | + self.ui.QUOTA_THRESHOLD)) |
4008 | + self.ui.on_account_info_ready(info) |
4009 | + |
4010 | + self.assert_account_info_correct(info) |
4011 | + |
4012 | + def test_on_account_info_ready_quota_over_threshold(self): |
4013 | + """Show red notification when quota usage is higher than threshold.""" |
4014 | + info = FAKE_ACCOUNT_INFO.copy() |
4015 | + info['quota_total'] = '12345678' |
4016 | + info['quota_used'] = info['quota_total'] + '0' |
4017 | + self.ui.on_account_info_ready(info) |
4018 | + |
4019 | + self.assert_account_info_correct(info) |
4020 | + |
4021 | def test_file_sync_status(self): |
4022 | """The file sync status is shown correctly.""" |
4023 | self.assertIsInstance(self.ui.status_label, gui.FileSyncStatus) |
4024 | |
4025 | === added file 'ubuntuone/controlpanel/gtk/tests/test_gui_basic.py' |
4026 | --- ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 1970-01-01 00:00:00 +0000 |
4027 | +++ ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 2011-03-10 03:11:54 +0000 |
4028 | @@ -0,0 +1,595 @@ |
4029 | +# -*- coding: utf-8 -*- |
4030 | + |
4031 | +# Authors: Natalia B Bidart <natalia.bidart@canonical.com> |
4032 | +# |
4033 | +# Copyright 2010 Canonical Ltd. |
4034 | +# |
4035 | +# This program is free software: you can redistribute it and/or modify it |
4036 | +# under the terms of the GNU General Public License version 3, as published |
4037 | +# by the Free Software Foundation. |
4038 | +# |
4039 | +# This program is distributed in the hope that it will be useful, but |
4040 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
4041 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4042 | +# PURPOSE. See the GNU General Public License for more details. |
4043 | +# |
4044 | +# You should have received a copy of the GNU General Public License along |
4045 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
4046 | + |
4047 | +"""The test suite for the control panel user interface (basics).""" |
4048 | + |
4049 | +from __future__ import division |
4050 | + |
4051 | +from ubuntuone.controlpanel.gtk import gui |
4052 | +from ubuntuone.controlpanel.gtk.tests import BaseTestCase, FakedSSOBackend |
4053 | +from ubuntuone.controlpanel.tests import TOKEN |
4054 | + |
4055 | + |
4056 | +# Attribute 'yyy' defined outside __init__, access to a protected member |
4057 | +# pylint: disable=W0201, W0212 |
4058 | + |
4059 | + |
4060 | +class ControlPanelMixinTestCase(BaseTestCase): |
4061 | + """The test suite for the control panel widget.""" |
4062 | + |
4063 | + klass = gui.ControlPanelMixin |
4064 | + ui_filename = None |
4065 | + |
4066 | + def test_is_a_control_panel_mixin(self): |
4067 | + """Inherits from ControlPanelMixin.""" |
4068 | + self.assertIsInstance(self.ui, gui.ControlPanelMixin) |
4069 | + |
4070 | + def test_ui_can_be_created(self): |
4071 | + """UI main class exists and can be created.""" |
4072 | + self.assertTrue(self.ui is not None) |
4073 | + |
4074 | + |
4075 | +class ControlPanelWindowTestCase(BaseTestCase): |
4076 | + """The test suite for the control panel window.""" |
4077 | + |
4078 | + klass = gui.ControlPanelWindow |
4079 | + |
4080 | + def test_is_a_window(self): |
4081 | + """Inherits from gtk.Window.""" |
4082 | + self.assertIsInstance(self.ui, gui.gtk.Window) |
4083 | + |
4084 | + def test_startup_visibility(self): |
4085 | + """The widget is visible at startup.""" |
4086 | + self.assertTrue(self.ui.get_visible(), 'must be visible at startup.') |
4087 | + |
4088 | + def test_main_start_gtk_main_loop(self): |
4089 | + """The GTK main loop is started when calling main().""" |
4090 | + self.patch(gui.gtk, 'main', self._set_called) |
4091 | + self.ui.main() |
4092 | + self.assertEqual(self._called, ((), {}), 'gtk.main was called.') |
4093 | + |
4094 | + def test_closing_stops_the_main_lopp(self): |
4095 | + """The GTK main loop is stopped when closing the window.""" |
4096 | + self.patch(gui.gtk, 'main_quit', self._set_called) |
4097 | + self.ui.emit('delete-event', None) |
4098 | + self.assertEqual(self._called, ((), {}), 'gtk.main_quit was called.') |
4099 | + |
4100 | + def test_title_is_correct(self): |
4101 | + """The window title is correct.""" |
4102 | + expected = self.ui.TITLE % {'app_name': gui.U1_APP_NAME} |
4103 | + self.assertEqual(self.ui.get_title(), expected) |
4104 | + |
4105 | + def test_control_panel_is_the_only_child(self): |
4106 | + """The control panel is the window's content.""" |
4107 | + children = self.ui.get_children() |
4108 | + self.assertEqual(1, len(children)) |
4109 | + |
4110 | + control_panel = self.ui.get_children()[0] |
4111 | + self.assertTrue(control_panel is self.ui.control_panel) |
4112 | + self.assertIsInstance(self.ui.control_panel, gui.ControlPanel) |
4113 | + self.assertTrue(self.ui.control_panel.get_visible()) |
4114 | + |
4115 | + def test_main_window_is_passed_to_child(self): |
4116 | + """The child gets the main_window.""" |
4117 | + self.assertEqual(self.ui.control_panel.main_window, self.ui) |
4118 | + |
4119 | + def test_icon_name_is_correct(self): |
4120 | + """The icon name is correct.""" |
4121 | + self.assertEqual(self.ui.get_icon_name(), 'ubuntuone') |
4122 | + |
4123 | + def test_max_size(self): |
4124 | + """Max size is not bigger than 736x525 (LP: #645526, LP: #683164).""" |
4125 | + self.assertTrue(self.ui.get_size_request() <= (736, 525)) |
4126 | + |
4127 | + |
4128 | +class ControlPanelWindowParamsTestCase(ControlPanelWindowTestCase): |
4129 | + """The test suite for the control panel window when passing params.""" |
4130 | + |
4131 | + kwargs = {'switch_to': 'devices'} |
4132 | + |
4133 | + def test_switch_to(self): |
4134 | + """Can pass a 'switch_to' parameter to start on a particular tab.""" |
4135 | + actual = self.ui.control_panel.management.notebook.get_current_page() |
4136 | + self.assertEqual(actual, self.ui.control_panel.management.DEVICES_PAGE) |
4137 | + |
4138 | + |
4139 | +class ControlPanelWindowParamsNoneTestCase(ControlPanelWindowTestCase): |
4140 | + """The suite for the control panel window when passing None params.""" |
4141 | + |
4142 | + kwargs = {'switch_to': None} |
4143 | + |
4144 | + def test_switch_to(self): |
4145 | + """Can pass a 'switch_to' being None. Should default to dashboard.""" |
4146 | + actual = self.ui.control_panel.management.notebook.get_current_page() |
4147 | + expected = self.ui.control_panel.management.DASHBOARD_PAGE |
4148 | + self.assertEqual(actual, expected) |
4149 | + |
4150 | + |
4151 | +class ControlPanelWindowInvalidParamsTestCase(ControlPanelWindowTestCase): |
4152 | + """The suite for the control panel window when passing invalid params.""" |
4153 | + |
4154 | + kwargs = {'switch_to': 'yadda-yadda'} |
4155 | + |
4156 | + def test_switch_to(self): |
4157 | + """Can pass an invalid 'switch_to'. Should default to dashboard.""" |
4158 | + actual = self.ui.control_panel.management.notebook.get_current_page() |
4159 | + expected = self.ui.control_panel.management.DASHBOARD_PAGE |
4160 | + self.assertEqual(actual, expected) |
4161 | + |
4162 | + |
4163 | +class ControlPanelTestCase(BaseTestCase): |
4164 | + """The test suite for the control panel itself.""" |
4165 | + |
4166 | + klass = gui.ControlPanel |
4167 | + kwargs = {'main_window': object()} |
4168 | + |
4169 | + def assert_current_tab_correct(self, expected_tab): |
4170 | + """Check that the wiget 'expected_tab' is the current page.""" |
4171 | + actual = self.ui.get_nth_page(self.ui.get_current_page()) |
4172 | + self.assertTrue(expected_tab is actual) |
4173 | + |
4174 | + def test_is_a_notebook(self): |
4175 | + """Inherits from gtk.VBox.""" |
4176 | + self.assertIsInstance(self.ui, gui.gtk.Notebook) |
4177 | + |
4178 | + def test_startup_visibility(self): |
4179 | + """The widget is visible at startup.""" |
4180 | + self.assertTrue(self.ui.get_visible(), |
4181 | + 'must be visible at startup.') |
4182 | + |
4183 | + def test_startup_props(self): |
4184 | + """The tabs and border are not shown.""" |
4185 | + self.assertFalse(self.ui.get_show_border(), 'must not show border.') |
4186 | + self.assertFalse(self.ui.get_show_tabs(), 'must not show tabs.') |
4187 | + |
4188 | + def test_overview_is_shown_at_startup(self): |
4189 | + """The overview is shown at startup.""" |
4190 | + self.assertIsInstance(self.ui.overview, gui.OverviewPanel) |
4191 | + self.assert_current_tab_correct(self.ui.overview) |
4192 | + |
4193 | + def test_main_window_is_passed_to_child(self): |
4194 | + """The child gets the main_window.""" |
4195 | + self.assertEqual(self.ui.overview.main_window, |
4196 | + self.kwargs['main_window']) |
4197 | + |
4198 | + def test_on_show_management_panel(self): |
4199 | + """A ManagementPanel is shown when the callback is executed.""" |
4200 | + self.ui.on_show_management_panel() |
4201 | + self.assert_current_tab_correct(self.ui.management) |
4202 | + |
4203 | + def test_on_show_management_panel_is_idempotent(self): |
4204 | + """Only one ManagementPanel is shown.""" |
4205 | + self.ui.on_show_management_panel() |
4206 | + self.ui.on_show_management_panel() |
4207 | + |
4208 | + self.assert_current_tab_correct(self.ui.management) |
4209 | + |
4210 | + def test_credentials_found_shows_dashboard_management_panel(self): |
4211 | + """On 'credentials-found' signal, the management panel is shown. |
4212 | + |
4213 | + If first signal parameter is False, visible tab should be dashboard. |
4214 | + |
4215 | + """ |
4216 | + self.patch(self.ui.management, 'load', self._set_called) |
4217 | + self.ui.overview.emit('credentials-found', False, object()) |
4218 | + |
4219 | + self.assert_current_tab_correct(self.ui.management) |
4220 | + self.assertEqual(self.ui.management.notebook.get_current_page(), |
4221 | + self.ui.management.DASHBOARD_PAGE) |
4222 | + self.assertEqual(self._called, ((), {})) |
4223 | + |
4224 | + def test_credentials_found_shows_volumes_management_panel(self): |
4225 | + """On 'credentials-found' signal, the management panel is shown. |
4226 | + |
4227 | + If first signal parameter is True, visible tab should be volumes. |
4228 | + |
4229 | + """ |
4230 | + a_token = object() |
4231 | + self.ui.overview.emit('credentials-found', True, a_token) |
4232 | + |
4233 | + self.assert_current_tab_correct(self.ui.management) |
4234 | + self.assertEqual(self.ui.management.notebook.get_current_page(), |
4235 | + self.ui.management.VOLUMES_PAGE) |
4236 | + |
4237 | + def test_local_device_removed_shows_overview_panel(self): |
4238 | + """On 'local-device-removed' signal, the overview panel is shown.""" |
4239 | + self.ui.overview.emit('credentials-found', True, object()) |
4240 | + self.ui.management.emit('local-device-removed') |
4241 | + |
4242 | + self.assert_current_tab_correct(self.ui.overview) |
4243 | + |
4244 | + |
4245 | +class UbuntuOneBinTestCase(BaseTestCase): |
4246 | + """The test suite for a Ubuntu One panel.""" |
4247 | + |
4248 | + klass = gui.UbuntuOneBin |
4249 | + kwargs = {'title': 'Something old, something new and something blue.'} |
4250 | + |
4251 | + def test_is_a_vbox(self): |
4252 | + """Inherits from proper gtk widget.""" |
4253 | + self.assertIsInstance(self.ui, gui.gtk.VBox) |
4254 | + |
4255 | + def test_startup_visibility(self): |
4256 | + """The widget is visible at startup.""" |
4257 | + self.assertTrue(self.ui.get_visible(), |
4258 | + 'must be visible at startup.') |
4259 | + for child in self.ui.get_children(): |
4260 | + self.assertTrue(child.get_visible()) |
4261 | + |
4262 | + def test_title_is_a_panel_title(self): |
4263 | + """Title is the correct widget.""" |
4264 | + self.assertIsInstance(self.ui.title, gui.PanelTitle) |
4265 | + self.assertIn(self.ui.title, self.ui.get_children()) |
4266 | + |
4267 | + def test_title_markup_is_correct(self): |
4268 | + """The title markup is correctly set when passed as argument.""" |
4269 | + self.assertEqual(self.ui.title.label.get_text(), self.kwargs['title']) |
4270 | + |
4271 | + def test_title_is_correct(self): |
4272 | + """The title markup is correctly set when defined at class level.""" |
4273 | + ui = self.klass() # no title given |
4274 | + self.assertEqual(ui.title.label.get_text(), '') |
4275 | + |
4276 | + def test_message_is_a_label_loading(self): |
4277 | + """Message is the correct widget.""" |
4278 | + self.assertIsInstance(self.ui.message, gui.LabelLoading) |
4279 | + self.assertIn(self.ui.message, self.ui.get_children()) |
4280 | + |
4281 | + def test_on_success(self): |
4282 | + """Callback to stop the Loading and clear messages.""" |
4283 | + self.ui.on_success() |
4284 | + self.assertEqual(self.ui.message.get_label(), '') |
4285 | + self.assertFalse(self.ui.message.active) |
4286 | + |
4287 | + def test_on_success_with_message(self): |
4288 | + """Callback to stop the Loading and show a info message.""" |
4289 | + msg = 'WOW! <i>this rocks</i>' |
4290 | + self.ui.on_success(message=msg) |
4291 | + self.assertEqual(self.ui.message.get_label(), msg) |
4292 | + self.assertFalse(self.ui.message.active) |
4293 | + |
4294 | + def test_on_error(self): |
4295 | + """Callback to stop the Loading and clear messages.""" |
4296 | + self.ui.on_error() |
4297 | + self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
4298 | + self.assertFalse(self.ui.message.active) |
4299 | + |
4300 | + def test_on_error_with_message(self): |
4301 | + """Callback to stop the Loading and show a info message.""" |
4302 | + msg = 'WOW! <i>this does not rock</i> :-/' |
4303 | + self.ui.on_error(message=msg) |
4304 | + self.assert_warning_correct(self.ui.message, msg) |
4305 | + self.assertFalse(self.ui.message.active) |
4306 | + |
4307 | + def test_is_processing(self): |
4308 | + """The flag 'is_processing' is False on start.""" |
4309 | + self.assertFalse(self.ui.is_processing) |
4310 | + self.assertTrue(self.ui.is_sensitive()) |
4311 | + |
4312 | + def test_set_is_processing(self): |
4313 | + """When setting 'is_processing', the spinner is shown.""" |
4314 | + self.ui.is_processing = False |
4315 | + self.ui.is_processing = True |
4316 | + |
4317 | + self.assertTrue(self.ui.message.get_visible()) |
4318 | + self.assertTrue(self.ui.message.active) |
4319 | + self.assertFalse(self.ui.is_sensitive()) |
4320 | + |
4321 | + def test_unset_is_processing(self): |
4322 | + """When unsetting 'is_processing', the spinner is not shown.""" |
4323 | + self.ui.is_processing = True |
4324 | + self.ui.is_processing = False |
4325 | + |
4326 | + self.assertTrue(self.ui.message.get_visible()) |
4327 | + self.assertFalse(self.ui.message.active) |
4328 | + self.assertTrue(self.ui.is_sensitive()) |
4329 | + |
4330 | + |
4331 | +class OverwiewPanelTestCase(ControlPanelMixinTestCase): |
4332 | + """The test suite for the overview panel.""" |
4333 | + |
4334 | + klass = gui.OverviewPanel |
4335 | + kwargs = {'main_window': gui.gtk.Window()} |
4336 | + ui_filename = 'overview.ui' |
4337 | + |
4338 | + def test_is_a_greyable_bin(self): |
4339 | + """Inherits from GreyableBin.""" |
4340 | + self.assertIsInstance(self.ui, gui.GreyableBin) |
4341 | + |
4342 | + def test_inner_widget_is_packed(self): |
4343 | + """The 'itself' vbox is packed into the widget.""" |
4344 | + self.assertIn(self.ui.itself, self.ui.get_children()) |
4345 | + |
4346 | + def test_join_now_is_default(self): |
4347 | + """The 'join_now' button is the default widget.""" |
4348 | + self.assertTrue(self.ui.join_now_button.get_property('can-default')) |
4349 | + |
4350 | + def test_sso_backend(self): |
4351 | + """Has a correct SSO backend.""" |
4352 | + self.assertIsInstance(self.ui.sso_backend, FakedSSOBackend) |
4353 | + |
4354 | + def test_sso_backend_signals(self): |
4355 | + """The proper signals are connected to the backend.""" |
4356 | + self.assertEqual(self.ui.sso_backend._signals['CredentialsFound'], |
4357 | + [self.ui.on_credentials_found]) |
4358 | + self.assertEqual(self.ui.sso_backend._signals['CredentialsNotFound'], |
4359 | + [self.ui.on_credentials_not_found]) |
4360 | + self.assertEqual(self.ui.sso_backend._signals['CredentialsError'], |
4361 | + [self.ui.on_credentials_error]) |
4362 | + self.assertEqual(self.ui.sso_backend._signals['AuthorizationDenied'], |
4363 | + [self.ui.on_authorization_denied]) |
4364 | + |
4365 | + |
4366 | +class OverwiewNetworkStatePanelTestCase(OverwiewPanelTestCase): |
4367 | + """The test suite for the overview panel regarding network state.""" |
4368 | + |
4369 | + def test_network_state_is_created(self): |
4370 | + """The network state is created.""" |
4371 | + self.assertIsInstance(self.ui.network_manager_state, |
4372 | + gui.networkstate.NetworkManagerState) |
4373 | + self.assertEqual(self.ui.network_manager_state._kwargs['result_cb'], |
4374 | + self.ui.on_network_state_changed) |
4375 | + |
4376 | + def test_network_state_is_queried_at_startup(self): |
4377 | + """The network state is asked to the NetworkManagerState.""" |
4378 | + self.assertTrue('find_online_state' in |
4379 | + self.ui.network_manager_state._called) |
4380 | + |
4381 | + def test_state_online(self): |
4382 | + """Network connection is online.""" |
4383 | + self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
4384 | + # all green, no warning |
4385 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
4386 | + self.assertTrue(self.ui.get_sensitive()) |
4387 | + |
4388 | + def test_state_offline(self): |
4389 | + """Network connection is offline.""" |
4390 | + self.ui.on_network_state_changed(gui.networkstate.OFFLINE) |
4391 | + msg = self.ui.NETWORK_OFFLINE % {'app_name': gui.U1_APP_NAME} |
4392 | + |
4393 | + self.assert_warning_correct(self.ui.warning_label, msg) |
4394 | + self.assertFalse(self.ui.get_sensitive()) |
4395 | + |
4396 | + def test_state_unknown(self): |
4397 | + """Network connection is unknown. Assume that connection is present.""" |
4398 | + self.ui.on_network_state_changed(gui.networkstate.UNKNOWN) |
4399 | + |
4400 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
4401 | + self.assertTrue(self.ui.get_sensitive()) |
4402 | + |
4403 | + |
4404 | +class OverwiewPanelOnlineTestCase(OverwiewPanelTestCase): |
4405 | + """The test suite for the overview panel.""" |
4406 | + |
4407 | + def setUp(self): |
4408 | + super(OverwiewPanelOnlineTestCase, self).setUp() |
4409 | + self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
4410 | + |
4411 | + def test_find_credentials_is_called(self): |
4412 | + """Credentials are asked to SSO backend.""" |
4413 | + self.assertFalse(self.ui._credentials_are_new) |
4414 | + self.assert_backend_called('find_credentials', (gui.U1_APP_NAME, {}), |
4415 | + backend=self.ui.sso_backend) |
4416 | + |
4417 | + def test_on_credentials_found(self): |
4418 | + """Callback 'on_credentials_found' is correct.""" |
4419 | + self.ui.connect('credentials-found', self._set_called) |
4420 | + |
4421 | + self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
4422 | + |
4423 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
4424 | + # assume credentials were in local keyring |
4425 | + self.assertEqual(self._called, ((self.ui, False, TOKEN), {})) |
4426 | + |
4427 | + def test_on_credentials_found_when_creds_are_not_new(self): |
4428 | + """Callback 'on_credentials_found' distinguish if creds are new.""" |
4429 | + self.ui.connect('credentials-found', self._set_called) |
4430 | + |
4431 | + # credentials weren't in the system |
4432 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
4433 | + # now they are! |
4434 | + self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
4435 | + |
4436 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
4437 | + # assume credentials were not in local keyring |
4438 | + self.assertEqual(self._called, ((self.ui, True, TOKEN), {})) |
4439 | + |
4440 | + def test_on_credentials_not_found(self): |
4441 | + """Callback 'on_credentials_not_found' is correct.""" |
4442 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
4443 | + self.assertTrue(self.ui.get_visible()) |
4444 | + self.assertTrue(self.ui._credentials_are_new) |
4445 | + |
4446 | + def test_on_credentials_error(self): |
4447 | + """Callback 'on_credentials_error' is correct.""" |
4448 | + self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
4449 | + self.assertTrue(self.ui.get_visible()) |
4450 | + self.assert_warning_correct(self.ui.warning_label, |
4451 | + self.ui.CREDENTIALS_ERROR) |
4452 | + |
4453 | + def test_on_authorization_denied(self): |
4454 | + """Callback 'on_authorization_denied' is correct.""" |
4455 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) |
4456 | + self.assertTrue(self.ui.get_visible()) |
4457 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
4458 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
4459 | + |
4460 | + |
4461 | +class OverwiewPanelAppNameMismatchTestCase(OverwiewPanelTestCase): |
4462 | + """The test suite for the overview panel when the app_name won't match.""" |
4463 | + |
4464 | + NOT_U1_APP = 'Not ' + gui.U1_APP_NAME |
4465 | + |
4466 | + def test_filter_by_app_name(self): |
4467 | + """The filter_by_app_name decorator is correct.""" |
4468 | + f = gui.filter_by_app_name(self._set_called) |
4469 | + f(self.ui, self.NOT_U1_APP) |
4470 | + self.assertFalse(self._called) |
4471 | + self.assertTrue(self.memento.check_info('ignoring', self.NOT_U1_APP)) |
4472 | + |
4473 | + args = ('test', object()) |
4474 | + kwargs = {'really': 'AWESOME'} |
4475 | + f(self.ui, gui.U1_APP_NAME, *args, **kwargs) |
4476 | + self.assertEqual(self._called, |
4477 | + ((self.ui, gui.U1_APP_NAME,) + args, kwargs)) |
4478 | + |
4479 | + def test_on_credentials_found(self): |
4480 | + """Callback 'on_credentials_found' is not executed.""" |
4481 | + self.assert_function_decorated(gui.filter_by_app_name, |
4482 | + self.ui.on_credentials_found) |
4483 | + |
4484 | + def test_on_credentials_not_found(self): |
4485 | + """Callback 'on_credentials_not_found' is not executed.""" |
4486 | + self.assert_function_decorated(gui.filter_by_app_name, |
4487 | + self.ui.on_credentials_not_found) |
4488 | + |
4489 | + def test_on_credentials_error(self): |
4490 | + """Callback 'on_credentials_error' is not executed.""" |
4491 | + self.assert_function_decorated(gui.filter_by_app_name, |
4492 | + self.ui.on_credentials_error) |
4493 | + |
4494 | + def test_on_authorization_denied(self): |
4495 | + """Callback 'on_authorization_denied' is not executed.""" |
4496 | + self.assert_function_decorated(gui.filter_by_app_name, |
4497 | + self.ui.on_authorization_denied) |
4498 | + |
4499 | + |
4500 | +class OverwiewPanelNoCredsTestCase(OverwiewPanelTestCase): |
4501 | + """The test suite for the overview panel when no credentials are found.""" |
4502 | + |
4503 | + def setUp(self): |
4504 | + super(OverwiewPanelNoCredsTestCase, self).setUp() |
4505 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
4506 | + |
4507 | + def test_startup_visibility(self): |
4508 | + """The widget is visible at startup.""" |
4509 | + self.assertTrue(self.ui.get_visible(), |
4510 | + 'must be visible at startup if credentials not found.') |
4511 | + |
4512 | + def test_warning_label_is_hidden(self): |
4513 | + """The warning label is not shown by default.""" |
4514 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
4515 | + |
4516 | + def test_image_is_correct(self): |
4517 | + """There is an image attribute and is correct.""" |
4518 | + self.assert_image_equal(self.ui.image, 'overview.png') |
4519 | + |
4520 | + def test_join_now_is_default_widget(self): |
4521 | + """The join now button is the default widget.""" |
4522 | + self.assertTrue(self.ui.join_now_button.get_property('can_default')) |
4523 | + |
4524 | + def test_join_now_button_clicked(self): |
4525 | + """Test the 'join now' button callback.""" |
4526 | + self.kwargs['main_window'].show() # ensure parent window is realized |
4527 | + self.addCleanup(self.kwargs['main_window'].hide) |
4528 | + |
4529 | + self.ui.join_now_button.clicked() |
4530 | + |
4531 | + window_id = self.kwargs['main_window'].window.xid |
4532 | + args = (gui.U1_APP_NAME, |
4533 | + {gui.TC_URL_KEY: gui.U1_TC_URL, |
4534 | + gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
4535 | + gui.WINDOW_ID_KEY: str(window_id), |
4536 | + gui.PING_URL_KEY: gui.U1_PING_URL}) |
4537 | + self.assert_backend_called('register', args, |
4538 | + backend=self.ui.sso_backend) |
4539 | + |
4540 | + def test_connect_button_clicked(self): |
4541 | + """Test the 'join now' button callback.""" |
4542 | + self.kwargs['main_window'].show() # ensure parent window is realized |
4543 | + self.addCleanup(self.kwargs['main_window'].hide) |
4544 | + |
4545 | + self.ui.connect_button.clicked() |
4546 | + |
4547 | + window_id = self.kwargs['main_window'].window.xid |
4548 | + args = (gui.U1_APP_NAME, |
4549 | + {gui.TC_URL_KEY: gui.U1_TC_URL, |
4550 | + gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
4551 | + gui.WINDOW_ID_KEY: str(window_id), |
4552 | + gui.PING_URL_KEY: gui.U1_PING_URL}) |
4553 | + self.assert_backend_called('login', args, |
4554 | + backend=self.ui.sso_backend) |
4555 | + |
4556 | + def test_join_now_button_clicked_set_greyed(self): |
4557 | + """Clicking on 'join_now' self is greyed.""" |
4558 | + self.ui.join_now_button.clicked() |
4559 | + self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
4560 | + |
4561 | + def test_join_now_button_clicked_removes_warning(self): |
4562 | + """Clicking on 'join_now' the warnings are removed.""" |
4563 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
4564 | + self.ui.join_now_button.clicked() |
4565 | + |
4566 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
4567 | + |
4568 | + def test_connect_button_clicked_set_greyed(self): |
4569 | + """Clicking on 'connect' self is greyed.""" |
4570 | + self.ui.connect_button.clicked() |
4571 | + self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
4572 | + |
4573 | + def test_connect_button_clicked_removes_warning(self): |
4574 | + """Clicking on 'connect' the warnings are removed.""" |
4575 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
4576 | + self.ui.connect_button.clicked() |
4577 | + |
4578 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
4579 | + |
4580 | + def test_learn_more_button_clicked(self): |
4581 | + """Test the 'learn more' button callback.""" |
4582 | + self.patch(gui, 'uri_hook', self._set_called) |
4583 | + self.ui.learn_more_button.clicked() |
4584 | + |
4585 | + expected = (self.ui.learn_more_button, self.ui.LEARN_MORE_LINK) |
4586 | + self.assertEqual(self._called, (expected, {})) |
4587 | + |
4588 | + def test_on_credentials_not_found_unset_greyed(self): |
4589 | + """Callback 'on_credentials_not_found' unsets the 'greyed' prop.""" |
4590 | + self.ui.connect_button.clicked() |
4591 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
4592 | + |
4593 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
4594 | + |
4595 | + def test_on_credentials_error_unset_greyed(self): |
4596 | + """Callback 'on_credentials_error' unsets the 'greyed' prop.""" |
4597 | + self.ui.connect_button.clicked() |
4598 | + self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
4599 | + |
4600 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
4601 | + |
4602 | + def test_on_authorization_denied_unset_greyed(self): |
4603 | + """Callback 'on_authorization_denied' unsets the 'greyed' prop.""" |
4604 | + self.ui.connect_button.clicked() |
4605 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) |
4606 | + |
4607 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
4608 | + |
4609 | + def test_buttons_disabled_when_greyed(self): |
4610 | + """Buttons should be disabled when widget is greyed.""" |
4611 | + self.ui.set_sensitive(True) |
4612 | + self.ui.set_property('greyed', True) |
4613 | + |
4614 | + self.assertFalse(self.ui.join_now_button.is_sensitive()) |
4615 | + self.assertFalse(self.ui.connect_button.is_sensitive()) |
4616 | + |
4617 | + def test_buttons_enabled_when_not_greyed(self): |
4618 | + """Buttons should be enabled when widget is not greyed.""" |
4619 | + self.ui.set_sensitive(False) |
4620 | + self.ui.set_property('greyed', False) |
4621 | + |
4622 | + self.assertTrue(self.ui.join_now_button.is_sensitive()) |
4623 | + self.assertTrue(self.ui.connect_button.is_sensitive()) |
4624 | |
4625 | === modified file 'ubuntuone/controlpanel/tests/__init__.py' |
4626 | --- ubuntuone/controlpanel/tests/__init__.py 2011-02-23 13:57:42 +0000 |
4627 | +++ ubuntuone/controlpanel/tests/__init__.py 2011-03-10 03:11:54 +0000 |
4628 | @@ -88,6 +88,8 @@ |
4629 | "email": "andrewpz@protocultura.net", |
4630 | } |
4631 | |
4632 | + |
4633 | +# note that local computer is not first, do not change! |
4634 | SAMPLE_DEVICES_JSON = """ |
4635 | [ |
4636 | { |
4637 | @@ -108,15 +110,9 @@ |
4638 | ] |
4639 | """ |
4640 | |
4641 | +# note that local computer should be first, do not change! |
4642 | EXPECTED_DEVICES_INFO = [ |
4643 | { |
4644 | - "device_id": "ComputerABCDEF01234token", |
4645 | - "name": "Ubuntu One @ darkstar", |
4646 | - "type": "Computer", |
4647 | - "is_local": '', |
4648 | - "configurable": '', |
4649 | - }, |
4650 | - { |
4651 | 'is_local': 'True', |
4652 | 'configurable': 'True', |
4653 | 'device_id': 'ComputerABCDEF01234-localtoken', |
4654 | @@ -125,7 +121,14 @@ |
4655 | 'max_download_speed': '-1', |
4656 | 'max_upload_speed': '-1', |
4657 | 'name': 'Ubuntu One @ localhost', |
4658 | - 'type': 'Computer' |
4659 | + 'type': 'Computer', |
4660 | + }, |
4661 | + { |
4662 | + "device_id": "ComputerABCDEF01234token", |
4663 | + "name": "Ubuntu One @ darkstar", |
4664 | + "type": "Computer", |
4665 | + "is_local": '', |
4666 | + "configurable": '', |
4667 | }, |
4668 | { |
4669 | "device_id": "Phone1000", |
4670 | |
4671 | === modified file 'ubuntuone/controlpanel/tests/test_backend.py' |
4672 | --- ubuntuone/controlpanel/tests/test_backend.py 2011-02-23 13:57:42 +0000 |
4673 | +++ ubuntuone/controlpanel/tests/test_backend.py 2011-03-10 03:11:54 +0000 |
4674 | @@ -274,7 +274,7 @@ |
4675 | result = yield self.be.device_is_local(self.local_token) |
4676 | self.assertTrue(result) |
4677 | |
4678 | - did = EXPECTED_DEVICES_INFO[0]['device_id'] |
4679 | + did = EXPECTED_DEVICES_INFO[-1]['device_id'] |
4680 | result = yield self.be.device_is_local(did) |
4681 | self.assertFalse(result) |
4682 |
Good work!