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