Merge lp:~nataliabidart/ubuntuone-control-panel/stable-3-0-update-2.99.91.1 into lp:ubuntuone-control-panel/stable-3-0

Proposed by Natalia Bidart
Status: Merged
Approved by: dobey
Approved revision: 257
Merged at revision: 256
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/stable-3-0-update-2.99.91.1
Merge into: lp:ubuntuone-control-panel/stable-3-0
Diff against target: 1286 lines (+425/-177)
22 files modified
data/qt/images.qrc (+1/-0)
data/qt/linux.qss (+16/-0)
data/qt/preferences.ui (+3/-0)
data/qt/side_widget.ui (+22/-1)
data/qt/ubuntuone.qss (+71/-102)
data/qt/windows.qss (+11/-0)
ubuntuone/controlpanel/gui/qt/__init__.py (+33/-5)
ubuntuone/controlpanel/gui/qt/controlpanel.py (+8/-0)
ubuntuone/controlpanel/gui/qt/gui.py (+10/-4)
ubuntuone/controlpanel/gui/qt/main/__init__.py (+7/-2)
ubuntuone/controlpanel/gui/qt/main/tests/test_main.py (+10/-4)
ubuntuone/controlpanel/gui/qt/tests/__init__.py (+14/-6)
ubuntuone/controlpanel/gui/qt/tests/test_common.py (+3/-2)
ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py (+11/-3)
ubuntuone/controlpanel/gui/qt/tests/test_folders.py (+23/-4)
ubuntuone/controlpanel/gui/qt/tests/test_gui.py (+16/-0)
ubuntuone/controlpanel/gui/qt/tests/test_start.py (+1/-1)
ubuntuone/controlpanel/gui/qt/tests/test_wizard.py (+33/-24)
ubuntuone/controlpanel/gui/qt/wizard.py (+22/-19)
ubuntuone/controlpanel/utils/__init__.py (+2/-0)
ubuntuone/controlpanel/utils/tests/test_windows.py (+88/-0)
ubuntuone/controlpanel/utils/windows.py (+20/-0)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/stable-3-0-update-2.99.91.1
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+99551@code.launchpad.net

Commit message

[ Natalia B. Bidart <email address hidden> ]
  - Isolate linux specific styling hacks to avoid weird side effects
    on windows (LP: #961229).
  - Handle errors from backend on the signin wizard page (LP: #945078).
  - Avoid the 'show/hide details' button to grow when focused (LP: #961348).
  - Modified stylesheet to use the new colours from brand, and to also ease
    the reading of white text (LP: #956077).
  - Fixed the gap tab outlines (LP: #822629).

[ Brian Curtin <email address hidden> ]
  - Add Ubuntu One to the Windows auto-start registry key.
  - Made the creation of symlinks a separated test case so it can be
    skipped on Windows.
  - Better cleanup in tests -- allow the rest of the test suite to
    complete. Fix courtesy of Natalia Bidart.

[ Roberto Alsina <email address hidden> ]
  - Made the license page from the wizard be shown (only when called
    with --installer) (LP: #933697).
  - Forced white background (LP: #961346).

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

review: Approve
Revision history for this message
Manuel de la Peña (mandel) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/external_icon_dark_grey.png'
0Binary files data/external_icon_dark_grey.png 1970-01-01 00:00:00 +0000 and data/external_icon_dark_grey.png 2012-03-27 15:50:42 +0000 differ0Binary files data/external_icon_dark_grey.png 1970-01-01 00:00:00 +0000 and data/external_icon_dark_grey.png 2012-03-27 15:50:42 +0000 differ
=== modified file 'data/qt/images.qrc'
--- data/qt/images.qrc 2012-03-15 01:25:08 +0000
+++ data/qt/images.qrc 2012-03-27 15:50:42 +0000
@@ -2,6 +2,7 @@
2 <qresource prefix="/">2 <qresource prefix="/">
3 <file>../banner.png</file>3 <file>../banner.png</file>
4 <file>../computer.png</file>4 <file>../computer.png</file>
5 <file>../external_icon_dark_grey.png</file>
5 <file>../external_icon_orange.png</file>6 <file>../external_icon_orange.png</file>
6 <file>../external_icon_white.png</file>7 <file>../external_icon_white.png</file>
7 <file>../icon.png</file>8 <file>../icon.png</file>
89
=== modified file 'data/qt/linux.qss'
--- data/qt/linux.qss 2012-03-16 21:10:54 +0000
+++ data/qt/linux.qss 2012-03-27 15:50:42 +0000
@@ -1,2 +1,18 @@
1/* Styles specific to the linux platform */1/* Styles specific to the linux platform */
22
3QPushButton:focus,
4GoToWebButton#help_button:focus,
5GoToWebButton#share_publish_button:focus {
6 /* hack to make the mild-orange focused box dissapear */
7 padding-top: 100%;
8 padding-bottom: 100%;
9 /* end of hack */
10}
11
12QTabBar::tab:hover,
13QTabBar::tab:focus {
14 /* hack to make the mild-orange focused box dissapear */
15 padding-left: 1000px;
16 padding-right: 1000px;
17 /* end of hack */
18}
319
=== modified file 'data/qt/preferences.ui'
--- data/qt/preferences.ui 2012-03-14 18:37:40 +0000
+++ data/qt/preferences.ui 2012-03-27 15:50:42 +0000
@@ -95,6 +95,9 @@
95 <property name="orientation">95 <property name="orientation">
96 <enum>Qt::Vertical</enum>96 <enum>Qt::Vertical</enum>
97 </property>97 </property>
98 <property name="sizeType">
99 <enum>QSizePolicy::Minimum</enum>
100 </property>
98 <property name="sizeHint" stdset="0">101 <property name="sizeHint" stdset="0">
99 <size>102 <size>
100 <width>40</width>103 <width>40</width>
101104
=== modified file 'data/qt/side_widget.ui'
--- data/qt/side_widget.ui 2012-03-14 15:11:19 +0000
+++ data/qt/side_widget.ui 2012-03-27 15:50:42 +0000
@@ -20,7 +20,16 @@
20 <property name="spacing">20 <property name="spacing">
21 <number>40</number>21 <number>40</number>
22 </property>22 </property>
23 <property name="margin">23 <property name="leftMargin">
24 <number>0</number>
25 </property>
26 <property name="topMargin">
27 <number>0</number>
28 </property>
29 <property name="rightMargin">
30 <number>10</number>
31 </property>
32 <property name="bottomMargin">
24 <number>0</number>33 <number>0</number>
25 </property>34 </property>
26 <item>35 <item>
@@ -83,6 +92,9 @@
83 <property name="text">92 <property name="text">
84 <string notr="true">Install</string>93 <string notr="true">Install</string>
85 </property>94 </property>
95 <property name="wordWrap">
96 <bool>true</bool>
97 </property>
86 </widget>98 </widget>
87 </item>99 </item>
88 </layout>100 </layout>
@@ -125,6 +137,9 @@
125 <property name="text">137 <property name="text">
126 <string notr="true">Sign In</string>138 <string notr="true">Sign In</string>
127 </property>139 </property>
140 <property name="wordWrap">
141 <bool>true</bool>
142 </property>
128 </widget>143 </widget>
129 </item>144 </item>
130 </layout>145 </layout>
@@ -164,6 +179,9 @@
164 <property name="text">179 <property name="text">
165 <string notr="true">Select sync folders</string>180 <string notr="true">Select sync folders</string>
166 </property>181 </property>
182 <property name="wordWrap">
183 <bool>true</bool>
184 </property>
167 </widget>185 </widget>
168 </item>186 </item>
169 </layout>187 </layout>
@@ -203,6 +221,9 @@
203 <property name="text">221 <property name="text">
204 <string notr="true">Sync, stream, share!</string>222 <string notr="true">Sync, stream, share!</string>
205 </property>223 </property>
224 <property name="wordWrap">
225 <bool>true</bool>
226 </property>
206 </widget>227 </widget>
207 </item>228 </item>
208 </layout>229 </layout>
209230
=== modified file 'data/qt/ubuntuone.qss'
--- data/qt/ubuntuone.qss 2012-03-20 13:05:20 +0000
+++ data/qt/ubuntuone.qss 2012-03-27 15:50:42 +0000
@@ -7,7 +7,7 @@
7*/7*/
88
9QMainWindow {9QMainWindow {
10 background-color: #aea79f;10 background-color: #adadad;
11}11}
1212
13QWidget {13QWidget {
@@ -16,6 +16,7 @@
1616
17QFrame {17QFrame {
18 border: none;18 border: none;
19 border-color: #333333;
19}20}
2021
21UbuntuOneWizard,22UbuntuOneWizard,
@@ -23,13 +24,12 @@
23 background: white;24 background: white;
24 border-radius: 5px;25 border-radius: 5px;
25 border-style: solid;26 border-style: solid;
26 border-color: #939389;
27 border-width: 1px;27 border-width: 1px;
28 min-height: 90px;28 min-height: 90px;
29}29}
3030
31QFrame#frame_greeting {31QFrame#frame_greeting {
32 margin 0px;32 margin: 0px;
33 padding-left: 15px;33 padding-left: 15px;
34 padding-top: 10px;34 padding-top: 10px;
35 padding-right: 10px;35 padding-right: 10px;
@@ -39,7 +39,6 @@
39QFrame#frame_status,39QFrame#frame_status,
40QFrame#frame_storage {40QFrame#frame_storage {
41 border-style: dotted;41 border-style: dotted;
42 border-color: #939389;
43 border-left-width: 1px;42 border-left-width: 1px;
44 padding: 10px;43 padding: 10px;
45 min-width: 40px;44 min-width: 40px;
@@ -47,24 +46,21 @@
4746
48QFrame#account_separator {47QFrame#account_separator {
49 border-style: dotted;48 border-style: dotted;
50 border-color: #939389;
51 border-bottom-width: 1px;49 border-bottom-width: 1px;
52}50}
5351
54QFrame#frm_box { /*The Loading Overlay frame.*/52QFrame#frm_box { /*The Loading Overlay frame.*/
55 background: #ffffff;53 background: white;
56 border-radius: 5px;54 border-radius: 5px;
57 border-style: solid;55 border-style: solid;
58 border-color: #939389;
59 border-width: 1px;56 border-width: 1px;
60 color: white;57 color: white;
61 min-height: 100px;58 min-height: 100px;
62}59}
6360
64SideWidget {61SideWidget { /* is a QFrame, so border color is already set */
65 background-color: white;62 background-color: white;
66 border-style: dotted;63 border-style: dotted;
67 border-color: #939389;
68 border-right-width: 1px;64 border-right-width: 1px;
69 color: white;65 color: white;
70 min-height: 100px;66 min-height: 100px;
@@ -85,10 +81,6 @@
85 padding: 5px;81 padding: 5px;
86 padding-left: 19px;82 padding-left: 19px;
87 padding-right: 19px;83 padding-right: 19px;
88 /* hack to make the mild-orange focused box dissapear */
89 padding-top: 100%;
90 padding-bottom: 100%;
91 /* end of hack */
92}84}
9385
94QPushButton:disabled {86QPushButton:disabled {
@@ -100,7 +92,7 @@
10092
101QPushButton:enabled {93QPushButton:enabled {
102 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,94 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
103 stop: 0 #ffffff,stop: 1.0 #e6e6e6);95 stop: 0 white, stop: 1.0 #e6e6e6);
104 color: #333333;96 color: #333333;
105 border-color: #999999;97 border-color: #999999;
106}98}
@@ -111,7 +103,7 @@
111103
112QPushButton:enabled:hover {104QPushButton:enabled:hover {
113 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,105 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
114 stop: 0 #ffffff,stop: 1.0 #ededed);106 stop: 0 white, stop: 1.0 #ededed);
115}107}
116108
117QPushButton:enabled:pressed {109QPushButton:enabled:pressed {
@@ -169,10 +161,9 @@
169 background: transparent;161 background: transparent;
170 border: none;162 border: none;
171 text-decoration: underline;163 text-decoration: underline;
172 color: white;164 padding-left: 2px; /* 2px border buffer when focused */
173 padding-left: 10px;165 padding-right: 15px;
174 padding-right: 25px;166 background-image: url(:/external_icon_dark_grey.png);
175 background-image: url(:/external_icon_white.png);
176 background-repeat: no-repeat;167 background-repeat: no-repeat;
177 background-position: right;168 background-position: right;
178 background-origin: margin;169 background-origin: margin;
@@ -180,13 +171,9 @@
180171
181GoToWebButton#help_button:focus {172GoToWebButton#help_button:focus {
182 border: 2px solid #dd4814;173 border: 2px solid #dd4814;
183 /* hack to make the mild-orange focused box dissapear */
184 padding-top: 100%;
185 padding-bottom: 100%;
186 /* end of hack */
187 /* Compensate for border so text doesn't move */174 /* Compensate for border so text doesn't move */
188 padding-left: 8px;175 padding-left: 0px;
189 padding-right: 23px;176 padding-right: 13px;
190}177}
191178
192GoToWebButton#share_publish_button {179GoToWebButton#share_publish_button {
@@ -204,84 +191,72 @@
204191
205GoToWebButton#share_publish_button:focus {192GoToWebButton#share_publish_button:focus {
206 border: 2px solid #aea79f;193 border: 2px solid #aea79f;
207 /* hack to make the mild-orange focused box dissapear */
208 padding-top: 100%;
209 padding-bottom: 100%;
210 /* end of hack */
211 /* Compensate for border so text doesn't move */194 /* Compensate for border so text doesn't move */
212 padding-left: 8px;195 padding-left: 8px;
213 padding-right: 23px;196 padding-right: 23px;
214}197}
215198
199GoToWebButton#edit_profile_button,
200GoToWebButton#edit_services_button,
201GoToWebButton#get_more_space_button {
202 padding-left: 8px;
203 padding-right: 25px;
204 background-image: url(:/external_icon_white.png);
205 background-repeat: no-repeat;
206 background-position: right;
207 background-origin: margin;
208}
209
210QTabWidget {
211 border-bottom-left-radius: 5px;
212 border-bottom-right-radius: 5px;
213 border-style: solid;
214 padding: 10px;
215}
216
217QTabWidget::pane {
218 border-bottom-left-radius: 5px;
219 border-bottom-right-radius: 5px;
220 border-top-right-radius: 5px;
221 border-style: solid;
222 border-color: #333333;
223 border-width: 1px;
224 background: white;
225 position: absolute;
226 top: -2px;
227}
228
216QTabBar::tab {229QTabBar::tab {
217 height: 15px;230 background-color: #e3e0dd;
218 color: #333333;
219 background-color: #e4e0dd;
220 border-top-left-radius: 5px;231 border-top-left-radius: 5px;
221 border-top-right-radius: 5px;232 border-top-right-radius: 5px;
233 border-bottom-right-radius: 1px;
234 border-bottom-left-radius: 1px;
222 border-style: solid;235 border-style: solid;
223 padding: 12px;236 padding: 12px;
224 border-top-color: #939389;237 border-color: #898989;
225 border-right-color: #939389;238 border-left-color: #e3e0dd; /* same as background */
226 border-left-color: white;
227 border-bottom-color: #939389;
228 border-width: 1px;239 border-width: 1px;
240 margin-bottom: 1px; /* to be able to override the QTabWidget border */
241 border-bottom-color: #333333; /* same as background for QTabWidget */
242}
243
244QTabBar::tab:first {
245 border-left-color: #898989; /* same as border-color */
246 border-bottom-left-radius: 0px;
229}247}
230248
231QTabBar::tab:selected {249QTabBar::tab:selected {
232 background-color: white;250 background-color: white;
233 border-top-left-radius: 5px;251 border-color: #333333;
234 border-top-right-radius: 5px;252 border-bottom-color: white; /* same as background for selected */
235 border-style: solid;253 border-bottom-right-radius: 0px;
236 padding: 12px;254 border-bottom-left-radius: 0px;
237 border-top-color: #939389;255}
238 border-right-color: #939389;256
239 border-left-color: white;257QTabBar::tab:hover,
240 border-bottom-color: white;
241 border-width: 1px;
242}
243
244QTabBar::tab:first {
245 border-left-color: #939389;
246}
247
248QTabBar::tab:middle:!selected {
249 border-left-color: #e4e0dd;
250}
251
252QTabBar::tab:last:!selected {
253 border-left-color: #e4e0dd;
254}
255
256QTabBar::tab:hover {
257 background: #f6f6f6;
258 text-decoration: underline;
259}
260
261QTabBar::tab:focus {258QTabBar::tab:focus {
262 text-decoration: underline;259 text-decoration: underline;
263 /* hack to make the mild-orange focused box dissapear */
264 padding-left: 1000px;
265 padding-right: 1000px;
266 /* end of hack */
267}
268
269QTabWidget {
270 border-bottom-left-radius: 5px;
271 border-bottom-right-radius: 5px;
272 border-style: solid;
273 padding: 10px;
274}
275
276QTabWidget::pane {
277 border-bottom-left-radius: 5px;
278 border-bottom-right-radius: 5px;
279 border-top-right-radius: 5px;
280 border-style: solid;
281 border-color: #939389;
282 border-width: 1px;
283 background: white;
284 border-top: 2px solid white;
285}260}
286261
287QGroupBox {262QGroupBox {
@@ -332,10 +307,6 @@
332 margin-top: -4px;307 margin-top: -4px;
333}308}
334309
335QLabel#follow_us_label {
336 color: white;
337}
338
339QLabel[OverQuota="true"],310QLabel[OverQuota="true"],
340QLabel#warning_label {311QLabel#warning_label {
341 color: #df2d1f;312 color: #df2d1f;
@@ -343,7 +314,6 @@
343314
344QAbstractItemView {315QAbstractItemView {
345 border-style: solid;316 border-style: solid;
346 border-color: #898989;
347 border-top-width: 1px;317 border-top-width: 1px;
348 border-bottom-width: 1px;318 border-bottom-width: 1px;
349 alternate-background-color: #f7f6f5;319 alternate-background-color: #f7f6f5;
@@ -363,19 +333,9 @@
363 padding-right: 0px;333 padding-right: 0px;
364}334}
365335
366GoToWebButton#edit_profile_button,
367GoToWebButton#edit_services_button,
368GoToWebButton#get_more_space_button {
369 padding-left: 8px;
370 padding-right: 25px;
371 background-image: url(:/external_icon_white.png);
372 background-repeat: no-repeat;
373 background-position: right;
374 background-origin: margin;
375}
376
377QSpinBox {336QSpinBox {
378 padding: 3px;337 padding: 3px;
338 background-color: white;
379}339}
380340
381QSpinBox:focus {341QSpinBox:focus {
@@ -389,3 +349,12 @@
389 background: #fcece7;349 background: #fcece7;
390 color: black;350 color: black;
391}351}
352
353
354QMessageBox > QWidget > QPushButton:focus {
355 /* use the same padding from the original QPushButton:focus setting */
356 /* hack to make the mild-orange focused box dissapear */
357 padding-top: 5px;
358 padding-bottom: 5px;
359 /* end of hack */
360}
392361
=== modified file 'data/qt/windows.qss'
--- data/qt/windows.qss 2012-03-15 01:25:08 +0000
+++ data/qt/windows.qss 2012-03-27 15:50:42 +0000
@@ -3,3 +3,14 @@
3QWidget {3QWidget {
4 font-family: "Ubuntu";4 font-family: "Ubuntu";
5}5}
6
7QTabBar::tab:hover,
8QTabBar::tab:focus {
9 padding-left: 0px;
10 padding-right: 0px;
11}
12
13QPushButton#twitter_button:focus,
14QPushButton#facebook_button:focus {
15 padding: 0px;
16}
617
=== modified file 'ubuntuone/controlpanel/gui/qt/__init__.py'
--- ubuntuone/controlpanel/gui/qt/__init__.py 2012-03-02 13:53:24 +0000
+++ ubuntuone/controlpanel/gui/qt/__init__.py 2012-03-27 15:50:42 +0000
@@ -70,6 +70,12 @@
70 return icon70 return icon
7171
7272
73# Invalid name "box"
74# pylint: disable=C0103
75box = None
76# pylint: enable=C0103
77
78
73def handle_errors(error_handler=None, logger=None):79def handle_errors(error_handler=None, logger=None):
74 """Decorator to handle errors when calling a function.80 """Decorator to handle errors when calling a function.
7581
@@ -107,13 +113,35 @@
107 else:113 else:
108 msgs = [e.__class__.__name__] + map(repr, e.args)114 msgs = [e.__class__.__name__] + map(repr, e.args)
109 msg = '\n'.join(msgs)115 msg = '\n'.join(msgs)
116
117 # hack to avoid the QMessageBox being gargabe-collected too soon
118 # Using the global statement, pylint: disable=W0603
119 global box
120 # pylint: enable=W0603
110 box = QtGui.QMessageBox(QtGui.QMessageBox.Critical,121 box = QtGui.QMessageBox(QtGui.QMessageBox.Critical,
111 GENERAL_ERROR_TITLE, GENERAL_ERROR_MSG,122 GENERAL_ERROR_TITLE, GENERAL_ERROR_MSG,
112 QtGui.QMessageBox.Close,123 QtGui.QMessageBox.Close, parent=None)
113 parent=None)124 box.setDefaultButton(QtGui.QMessageBox.Close)
114 box.setDetailedText(msg)125 box.setDetailedText(msg)
115 box.setDefaultButton(QtGui.QMessageBox.Close)126
116 box.exec_()127 # can not exec_() on the QMessageBox since that will block the Qt
128 # mainloop
129
130 d = defer.Deferred()
131
132 def box_finished(result):
133 """The QMessageBox finished."""
134 logger.info('The warning dialog was shown and also closed '
135 '(message was %r).', msg)
136 box.finished.disconnect(box_finished)
137 box.hide()
138 box.deleteLater()
139 d.callback(result)
140
141 box.finished.connect(box_finished)
142 box.show()
143
144 yield d
117145
118 return inner146 return inner
119147
120148
=== modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py'
--- ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-19 20:55:52 +0000
+++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-27 15:50:42 +0000
@@ -170,3 +170,11 @@
170 def on_wizard_finished(self, status):170 def on_wizard_finished(self, status):
171 """Move to controlpanel if wizard ended successfully."""171 """Move to controlpanel if wizard ended successfully."""
172 self.on_credentials_found()172 self.on_credentials_found()
173
174 @log_call(logger.info)
175 def start_from_license(self):
176 """Use the license page as first page."""
177 # license
178 self.ui.wizard.setStartId(self.ui.wizard.pages[
179 self.ui.wizard.license_page])
180 self.ui.wizard.restart()
173181
=== modified file 'ubuntuone/controlpanel/gui/qt/gui.py'
--- ubuntuone/controlpanel/gui/qt/gui.py 2012-03-06 21:33:23 +0000
+++ ubuntuone/controlpanel/gui/qt/gui.py 2012-03-27 15:50:42 +0000
@@ -20,6 +20,7 @@
2020
21from ubuntuone.controlpanel.gui.qt.systray import TrayIcon21from ubuntuone.controlpanel.gui.qt.systray import TrayIcon
22from ubuntuone.controlpanel.gui.qt.ui import mainwindow_ui22from ubuntuone.controlpanel.gui.qt.ui import mainwindow_ui
23from ubuntuone.controlpanel.utils import add_to_autostart
2324
24# pylint: disable=E061125# pylint: disable=E0611
25try:26try:
@@ -35,7 +36,7 @@
35class MainWindow(QtGui.QMainWindow):36class MainWindow(QtGui.QMainWindow):
36 """The Main Window of the Control Panel."""37 """The Main Window of the Control Panel."""
3738
38 def __init__(self, close_callback=None):39 def __init__(self, close_callback=None, installer=False):
39 """Initialize this instance with the UI layout."""40 """Initialize this instance with the UI layout."""
40 super(MainWindow, self).__init__()41 super(MainWindow, self).__init__()
41 self.ui = mainwindow_ui.Ui_MainWindow()42 self.ui = mainwindow_ui.Ui_MainWindow()
@@ -46,6 +47,10 @@
46 triggered=self.close)47 triggered=self.close)
47 self.quit_action.setShortcuts(["Ctrl+q", "Ctrl+w"])48 self.quit_action.setShortcuts(["Ctrl+q", "Ctrl+w"])
48 self.addAction(self.quit_action)49 self.addAction(self.quit_action)
50 self.installer = installer
51 if installer:
52 self.ui.control_panel.start_from_license()
53 add_to_autostart()
49 if USE_LIBUNITY:54 if USE_LIBUNITY:
50 self.entry = Unity.LauncherEntry.get_for_desktop_id(U1_DOTDESKTOP)55 self.entry = Unity.LauncherEntry.get_for_desktop_id(U1_DOTDESKTOP)
51 else:56 else:
@@ -84,14 +89,15 @@
84 # pylint: enable=C010389 # pylint: enable=C0103
8590
8691
87def start(close_callback, minimized=False, with_icon=False):92def start(close_callback, minimized=False, with_icon=False, installer=False):
88 """Show the UI elements."""93 """Show the UI elements."""
89 # pylint: disable=W0404, F040194 # pylint: disable=W0404, F0401
90 if not minimized:95 if not minimized:
91 if with_icon or minimized:96 if with_icon or minimized:
92 window = MainWindow()97 window = MainWindow(installer=installer)
93 else:98 else:
94 window = MainWindow(close_callback=close_callback)99 window = MainWindow(close_callback=close_callback,
100 installer=installer)
95 app = QtGui.QApplication.instance()101 app = QtGui.QApplication.instance()
96 style = QtGui.QStyle.alignedRect(102 style = QtGui.QStyle.alignedRect(
97 QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter,103 QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter,
98104
=== modified file 'ubuntuone/controlpanel/gui/qt/main/__init__.py'
--- ubuntuone/controlpanel/gui/qt/main/__init__.py 2012-03-16 21:09:40 +0000
+++ ubuntuone/controlpanel/gui/qt/main/__init__.py 2012-03-27 15:50:42 +0000
@@ -55,6 +55,9 @@
55 default=False,55 default=False,
56 help="Start Ubuntu One "56 help="Start Ubuntu One "
57 "with an icon in the notification area.")57 "with an icon in the notification area.")
58 result.add_argument("--installer", dest="installer", action="store_true",
59 default=False,
60 help="Show the license agreement page first.")
58 return result61 return result
5962
6063
@@ -82,17 +85,19 @@
82 switch_to = args.switch_to85 switch_to = args.switch_to
83 minimized = args.minimized86 minimized = args.minimized
84 with_icon = args.with_icon87 with_icon = args.with_icon
88 installer = args.installer
85 source.main(app)89 source.main(app)
8690
87 data = []91 data = []
88 for qss_name in (source.PLATFORM_QSS, ":/ubuntuone.qss"):92 for qss_name in (":/ubuntuone.qss", source.PLATFORM_QSS):
89 qss = QtCore.QResource(qss_name)93 qss = QtCore.QResource(qss_name)
90 data.append(unicode(qss.data()))94 data.append(unicode(qss.data()))
91 app.setStyleSheet('\n'.join(data))95 app.setStyleSheet('\n'.join(data))
9296
93 # Unused variable 'window', 'icon', pylint: disable=W061297 # Unused variable 'window', 'icon', pylint: disable=W0612
94 icon, window = start(lambda: source.main_quit(app),98 icon, window = start(lambda: source.main_quit(app),
95 minimized=minimized, with_icon=with_icon)99 minimized=minimized, with_icon=with_icon,
100 installer=installer)
96 window.switch_to(switch_to)101 window.switch_to(switch_to)
97 # pylint: enable=W0612102 # pylint: enable=W0612
98 if icon:103 if icon:
99104
=== modified file 'ubuntuone/controlpanel/gui/qt/main/tests/test_main.py'
--- ubuntuone/controlpanel/gui/qt/main/tests/test_main.py 2012-03-16 21:14:20 +0000
+++ ubuntuone/controlpanel/gui/qt/main/tests/test_main.py 2012-03-27 15:50:42 +0000
@@ -132,25 +132,25 @@
132 """Ensure the binary name is not given to argparse."""132 """Ensure the binary name is not given to argparse."""
133 main.main(["foo", "bar", sys.argv[0], "--minimized"])133 main.main(["foo", "bar", sys.argv[0], "--minimized"])
134 self.assertEqual(self.start.args[1],134 self.assertEqual(self.start.args[1],
135 {'minimized': True, 'with_icon': False})135 {'minimized': True, 'with_icon': False, 'installer': False})
136136
137 def test_minimized_option(self):137 def test_minimized_option(self):
138 """Ensure the --minimized option is parsed and passed correctly."""138 """Ensure the --minimized option is parsed and passed correctly."""
139 main.main([sys.argv[0], "--minimized"])139 main.main([sys.argv[0], "--minimized"])
140 self.assertEqual(self.start.args[1],140 self.assertEqual(self.start.args[1],
141 {'minimized': True, 'with_icon': False})141 {'minimized': True, 'with_icon': False, 'installer': False})
142142
143 def test_with_icon_option(self):143 def test_with_icon_option(self):
144 """Ensure the --minimized option is parsed and passed correctly."""144 """Ensure the --minimized option is parsed and passed correctly."""
145 main.main([sys.argv[0], "--with-icon"])145 main.main([sys.argv[0], "--with-icon"])
146 self.assertEqual(self.start.args[1],146 self.assertEqual(self.start.args[1],
147 {'minimized': False, 'with_icon': True})147 {'minimized': False, 'with_icon': True, 'installer': False})
148148
149 def test_all_styles_load(self):149 def test_all_styles_load(self):
150 """Ensure the platform style is loaded."""150 """Ensure the platform style is loaded."""
151 main.main([sys.argv[0]])151 main.main([sys.argv[0]])
152 data = []152 data = []
153 for qss_name in (main.source.PLATFORM_QSS, ":/ubuntuone.qss"):153 for qss_name in (":/ubuntuone.qss", main.source.PLATFORM_QSS):
154 qss = QtCore.QResource(qss_name)154 qss = QtCore.QResource(qss_name)
155 data.append(unicode(qss.data()))155 data.append(unicode(qss.data()))
156 self.assertEqual((('\n'.join(data),), {}), self.app.style)156 self.assertEqual((('\n'.join(data),), {}), self.app.style)
@@ -160,6 +160,12 @@
160 main.main([sys.argv[0], "--switch-to", "folders"])160 main.main([sys.argv[0], "--switch-to", "folders"])
161 self.assertEqual(self.start.window.tabname, "folders")161 self.assertEqual(self.start.window.tabname, "folders")
162162
163 def test_installer_option(self):
164 """Ensure the --installer option is parsed and passed correctly."""
165 main.main([sys.argv[0], "--installer"])
166 self.assertEqual(self.start.args[1],
167 {'minimized': False, 'with_icon': False, 'installer': True})
168
163 def test_translator(self):169 def test_translator(self):
164 """Ensure the Qt translator is loaded."""170 """Ensure the Qt translator is loaded."""
165 main.main([sys.argv[0]])171 main.main([sys.argv[0]])
166172
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py'
--- ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-03-08 20:46:13 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-03-27 15:50:42 +0000
@@ -187,17 +187,16 @@
187 return inner187 return inner
188188
189189
190class FakedDialog(object):190class FakedDialog(QtGui.QMessageBox):
191 """Fake a confirmation dialog."""191 """Fake a confirmation dialog."""
192192
193 Close = object()
194 Critical = object()
195 properties = response = args = kwargs = None193 properties = response = args = kwargs = None
196194
197 def __init__(self, *a, **kw):195 def __init__(self, *a, **kw):
196 super(FakedDialog, self).__init__(*a, **kw)
198 FakedDialog.args = a197 FakedDialog.args = a
199 FakedDialog.kwargs = kw198 FakedDialog.kwargs = kw
200 FakedDialog.properties = {'exec_': 0}199 FakedDialog.properties = {'shown': 0}
201200
202 @classmethod201 @classmethod
203 def reset(cls, *a, **kw):202 def reset(cls, *a, **kw):
@@ -216,17 +215,24 @@
216215
217 def setDetailedText(self, text):216 def setDetailedText(self, text):
218 """Fake the setDetailedText."""217 """Fake the setDetailedText."""
218 super(FakedDialog, self).setDetailedText(text)
219 FakedDialog.properties['detailed_text'] = text219 FakedDialog.properties['detailed_text'] = text
220220
221 def setDefaultButton(self, button):221 def setDefaultButton(self, button):
222 """Fake the setDefaultButton."""222 """Fake the setDefaultButton."""
223 super(FakedDialog, self).setDefaultButton(button)
223 FakedDialog.properties['default_button'] = button224 FakedDialog.properties['default_button'] = button
224225
225 # pylint: enable=C0103226 # pylint: enable=C0103
226227
228 def show(self):
229 """Fake show."""
230 FakedDialog.properties['shown'] += 1
231 self.finished.emit(0)
232
227 def exec_(self):233 def exec_(self):
228 """Fake exec_."""234 """Fake exec_."""
229 FakedDialog.properties['exec_'] += 1235 FakedDialog.properties['shown'] += 1
230236
231237
232class FakedFileDialog(object):238class FakedFileDialog(object):
@@ -275,7 +281,9 @@
275 self.ui = self.class_ui(**self.kwargs)281 self.ui = self.class_ui(**self.kwargs)
276 # pylint: enable=E1102282 # pylint: enable=E1102
277 self.ui.show()283 self.ui.show()
278 self.addCleanup(self.ui.destroy)284 self.addCleanup(self.ui.hide)
285 self.addCleanup(self.ui.deleteLater)
286 self.addCleanup(QtCore.QCoreApplication.instance().processEvents)
279287
280 if getattr(self.ui, 'backend', None) is not None:288 if getattr(self.ui, 'backend', None) is not None:
281 self.addCleanup(self.ui.backend._called.clear)289 self.addCleanup(self.ui.backend._called.clear)
282290
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_common.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_common.py 2011-10-05 16:35:59 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_common.py 2012-03-27 15:50:42 +0000
@@ -132,7 +132,8 @@
132 yield self.decorate_me()132 yield self.decorate_me()
133133
134 logged = self.memento.check_exception(self.failure.__class__, msg)134 logged = self.memento.check_exception(self.failure.__class__, msg)
135 recs = '\n'.join(rec.exc_text for rec in self.memento.records)135 recs = '\n'.join(rec.exc_text for rec in self.memento.records
136 if rec.exc_text is not None)
136 self.assertTrue(logged, 'Exception must be logged, got:\n%s' % recs)137 self.assertTrue(logged, 'Exception must be logged, got:\n%s' % recs)
137138
138 @defer.inlineCallbacks139 @defer.inlineCallbacks
@@ -147,7 +148,7 @@
147 QtGui.QMessageBox.Close)148 QtGui.QMessageBox.Close)
148 self.assertEqual(FakedDialog.args, args)149 self.assertEqual(FakedDialog.args, args)
149 self.assertEqual(FakedDialog.kwargs, {'parent': None})150 self.assertEqual(FakedDialog.kwargs, {'parent': None})
150 self.assertEqual(FakedDialog.properties['exec_'], 1)151 self.assertEqual(FakedDialog.properties['shown'], 1)
151152
152 @defer.inlineCallbacks153 @defer.inlineCallbacks
153 def test_show_error_message_default_button(self):154 def test_show_error_message_default_button(self):
154155
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-19 15:50:31 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-27 15:50:42 +0000
@@ -1,8 +1,6 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2
3# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
4#2#
5# Copyright 2011 Canonical Ltd.3# Copyright 2011-2012 Canonical Ltd.
6#4#
7# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -186,6 +184,16 @@
186 remote = self.ui.ui.folders_tab.remote_folders184 remote = self.ui.ui.folders_tab.remote_folders
187 self.assertFalse(remote)185 self.assertFalse(remote)
188186
187 def test_start_from_license(self):
188 """Ensure we change the starting page correctly."""
189 # Before, we start on sign_in
190 self.assertEqual(self.ui.ui.wizard.startId(),
191 self.ui.ui.wizard.pages[self.ui.ui.wizard.signin_page])
192 # After, we start on license_page
193 self.ui.start_from_license()
194 self.assertEqual(self.ui.ui.wizard.startId(),
195 self.ui.ui.wizard.pages[self.ui.ui.wizard.license_page])
196
189197
190class ExternalLinkButtonsTestCase(ControlPanelTestCase):198class ExternalLinkButtonsTestCase(ControlPanelTestCase):
191 """The link in the go-to-web buttons are correct."""199 """The link in the go-to-web buttons are correct."""
192200
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_folders.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-19 20:51:26 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-27 15:50:42 +0000
@@ -26,6 +26,7 @@
26from PyQt4 import QtGui26from PyQt4 import QtGui
27from twisted.internet import defer27from twisted.internet import defer
28from ubuntuone.devtools.handlers import MementoHandler28from ubuntuone.devtools.handlers import MementoHandler
29from ubuntuone.devtools.testcases import skipIfOS
2930
30from ubuntuone.controlpanel.tests import helper_fail31from ubuntuone.controlpanel.tests import helper_fail
31from ubuntuone.controlpanel.gui.tests import (32from ubuntuone.controlpanel.gui.tests import (
@@ -694,10 +695,6 @@
694 empty_dir = os.path.join(dir_path, 'empty')695 empty_dir = os.path.join(dir_path, 'empty')
695 os.mkdir(empty_dir)696 os.mkdir(empty_dir)
696697
697 # add a symlink to confirm those are avoided
698 a_link = os.path.join(dir_path, 'some_link')
699 os.symlink(a_file, a_link)
700
701 return total_size698 return total_size
702699
703700
@@ -733,6 +730,28 @@
733 self.assertRaises(Queue.Empty, self.queue.get, block=True, timeout=0.5)730 self.assertRaises(Queue.Empty, self.queue.get, block=True, timeout=0.5)
734731
735732
733@skipIfOS("win32", "Windows does not easily support symlinks")
734class CalculateSizeWithSymlinksTestCase(BaseLocalFoldersTestCase):
735 """Test suite for the CalculateSize thread implementation."""
736
737 def build_test_dir(self, dir_path):
738 """Build a testing directory hierarchy."""
739 total_size = super(CalculateSizeWithSymlinksTestCase,
740 self).build_test_dir(dir_path)
741
742 a_file = os.path.join(dir_path, 'to_be_symlinked')
743 with open(a_file, 'wb') as f:
744 f.write('y' * 5000)
745
746 total_size += os.path.getsize(a_file)
747
748 # add a symlink to confirm those are avoided
749 a_link = os.path.join(dir_path, 'some_link')
750 os.symlink(a_file, a_link)
751
752 return total_size
753
754
736class FakedCalculateSize(object):755class FakedCalculateSize(object):
737 """A faked CalculateSize thread."""756 """A faked CalculateSize thread."""
738757
739758
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_gui.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-03-09 01:05:49 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-03-27 15:50:42 +0000
@@ -18,6 +18,8 @@
1818
19"""Tests for the Qt UI."""19"""Tests for the Qt UI."""
2020
21from twisted.internet import defer
22
21from ubuntuone.controlpanel.gui.qt import gui23from ubuntuone.controlpanel.gui.qt import gui
22from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase24from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
2325
@@ -115,3 +117,17 @@
115 self.patch(self.ui, "entry", entry)117 self.patch(self.ui, "entry", entry)
116 self.ui.set_urgent("foo")118 self.ui.set_urgent("foo")
117 self.assertEqual(entry.called, (('urgent', "foo"), {}))119 self.assertEqual(entry.called, (('urgent', "foo"), {}))
120
121
122class AutoStartTestCase(MainWindowTestCase):
123 """Test the add_to_autostart call."""
124
125 @defer.inlineCallbacks
126 def setUp(self):
127 # Be sure to patch add_to_autostart *before* class_ui creation occurs.
128 self.patch(gui, "add_to_autostart", self._set_called)
129 yield super(AutoStartTestCase, self).setUp()
130
131 def test_add_to_autostart(self):
132 """Test that the add_to_autostart function is called when CP opens."""
133 self.assertTrue(self._called)
118134
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_start.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_start.py 2012-02-17 14:42:57 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_start.py 2012-03-27 15:50:42 +0000
@@ -78,7 +78,7 @@
78 gui.start(close_callback=self.close_cb,78 gui.start(close_callback=self.close_cb,
79 with_icon=True, minimized=False)79 with_icon=True, minimized=False)
80 kwargs = {'close_callback': self.close_cb, 'window': self.main_window}80 kwargs = {'close_callback': self.close_cb, 'window': self.main_window}
81 self.assertEqual(self.main_window.args, [((), {})])81 self.assertEqual(self.main_window.args, [((), {'installer': False})])
82 self.assertEqual(self.tray_icon.args, [((), kwargs)])82 self.assertEqual(self.tray_icon.args, [((), kwargs)])
8383
84 def test_both_false(self):84 def test_both_false(self):
8585
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_wizard.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-20 15:14:24 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-27 15:50:42 +0000
@@ -89,7 +89,7 @@
89 # Finish button is visible (and enabled if isComplete() returns true).89 # Finish button is visible (and enabled if isComplete() returns true).
9090
91 # After calling setFinalPage(false), isFinalPage() returns true if91 # After calling setFinalPage(false), isFinalPage() returns true if
92 #nextId() returns -1; otherwise, it returns false.92 # nextId() returns -1; otherwise, it returns false.
9393
94 self.patch(self.ui, 'nextId', lambda *a: 0)94 self.patch(self.ui, 'nextId', lambda *a: 0)
95 self.assertFalse(self.ui.isFinalPage())95 self.assertFalse(self.ui.isFinalPage())
@@ -153,11 +153,9 @@
153153
154 class_ui = gui.UbuntuOneWizard154 class_ui = gui.UbuntuOneWizard
155 confirm_response = gui.QtGui.QDialog.Accepted155 confirm_response = gui.QtGui.QDialog.Accepted
156 show_license = False
157156
158 @defer.inlineCallbacks157 @defer.inlineCallbacks
159 def setUp(self):158 def setUp(self):
160 self.patch(self.class_ui, 'show_license', self.show_license)
161 yield super(UbuntuOneWizardTestCase, self).setUp()159 yield super(UbuntuOneWizardTestCase, self).setUp()
162 self.patch(self.ui.confirm_dialog, 'exec_',160 self.patch(self.ui.confirm_dialog, 'exec_',
163 lambda: self.confirm_response)161 lambda: self.confirm_response)
@@ -186,11 +184,7 @@
186184
187 def test_first_page(self):185 def test_first_page(self):
188 """The first page is the correct one."""186 """The first page is the correct one."""
189 if self.show_license:187 expected = self.ui.pages[self.ui.signin_page]
190 expected = self.ui.pages[self.ui.license_page]
191 else:
192 expected = self.ui.pages[self.ui.signin_page]
193
194 self.assertEqual(self.ui.startId(), expected)188 self.assertEqual(self.ui.startId(), expected)
195189
196 def test_done_accepted(self):190 def test_done_accepted(self):
@@ -202,12 +196,6 @@
202 self.assertEqual(self._called, ((gui.QtGui.QDialog.Accepted,), {}))196 self.assertEqual(self._called, ((gui.QtGui.QDialog.Accepted,), {}))
203197
204198
205class LicensedUbuntuOneWizardTestCase(UbuntuOneWizardTestCase):
206 """Test the LicensedUbuntuOneWizard."""
207
208 show_license = True
209
210
211class UbuntuOneWizardSignInTestCase(UbuntuOneWizardTestCase):199class UbuntuOneWizardSignInTestCase(UbuntuOneWizardTestCase):
212 """Test the SignInPage wizard page."""200 """Test the SignInPage wizard page."""
213201
@@ -267,12 +255,13 @@
267 if text is not None:255 if text is not None:
268 self.assertEqual(unicode(button.text()), text)256 self.assertEqual(unicode(button.text()), text)
269257
270 getattr(self.ui, signal).connect(self._set_called)258 if signal:
271 button.click()259 getattr(self.ui, signal).connect(self._set_called)
260 button.click()
272261
273 self.assertEqual(self._called, (signal_args, {}),262 self.assertEqual(self._called, (signal_args, {}),
274 msg % (name, signal, signal_args))263 msg % (name, signal, signal_args))
275 self._called = False264 self._called = False
276265
277 def test_done_rejected(self):266 def test_done_rejected(self):
278 """When the wizard was cancelled and user confirmed, finish."""267 """When the wizard was cancelled and user confirmed, finish."""
@@ -300,7 +289,7 @@
300class UbuntuOneWizardCloudToComputerTestCase(UbuntuOneWizardSignInTestCase):289class UbuntuOneWizardCloudToComputerTestCase(UbuntuOneWizardSignInTestCase):
301 """Test the CloudToComputerPage wizard page."""290 """Test the CloudToComputerPage wizard page."""
302291
303 buttons = {'NextButton': (None, 'currentIdChanged', (3,))}292 buttons = {'NextButton': (None, 'currentIdChanged', (4,))}
304 page_name = 'cloud_folders'293 page_name = 'cloud_folders'
305 stage_name = 'folders'294 stage_name = 'folders'
306295
@@ -308,7 +297,7 @@
308class UbuntuOneWizardSettingsTestCase(UbuntuOneWizardSignInTestCase):297class UbuntuOneWizardSettingsTestCase(UbuntuOneWizardSignInTestCase):
309 """Test the CloudToComputerPage wizard page."""298 """Test the CloudToComputerPage wizard page."""
310299
311 buttons = {'BackButton': (None, 'currentIdChanged', (0,))}300 buttons = {'BackButton': (None, 'currentIdChanged', (1,))}
312 page_name = 'settings'301 page_name = 'settings'
313 stage_name = 'folders'302 stage_name = 'folders'
314303
@@ -318,7 +307,7 @@
318307
319 buttons = {308 buttons = {
320 'FinishButton': (None, 'finished', (gui.QtGui.QDialog.Accepted,)),309 'FinishButton': (None, 'finished', (gui.QtGui.QDialog.Accepted,)),
321 'BackButton': (None, 'currentIdChanged', (0,)),310 'BackButton': (None, 'currentIdChanged', (1,)),
322 }311 }
323 page_name = 'local_folders'312 page_name = 'local_folders'
324 stage_name = 'sync'313 stage_name = 'sync'
@@ -341,11 +330,10 @@
341 """Test the LicensePage wizard page."""330 """Test the LicensePage wizard page."""
342331
343 buttons = {332 buttons = {
344 'NextButton': (gui.LICENSE_AGREE, 'currentIdChanged', (1,)),333 'CommitButton': (gui.LICENSE_AGREE, None, ()),
345 'CancelButton': (gui.LICENSE_DISAGREE, 'rejected', ()),334 'CancelButton': (gui.LICENSE_DISAGREE, 'rejected', ()),
346 }335 }
347 page_name = 'license'336 page_name = 'license'
348 show_license = True
349 stage_name = 'install'337 stage_name = 'install'
350338
351339
@@ -397,6 +385,27 @@
397 self.assertTrue(self.ui.signin_page.isEnabled())385 self.assertTrue(self.ui.signin_page.isEnabled())
398 self.assertFalse(self._called)386 self.assertFalse(self._called)
399387
388 @defer.inlineCallbacks
389 def test_with_error(self):
390 """Wizard is enabled after an error was handled."""
391 self.ui.currentIdChanged.connect(self._set_called)
392 d = defer.fail(ValueError())
393
394 def check():
395 """Confirm the ui is disabled while processing."""
396 self.assertFalse(self.ui.signin_page.isEnabled())
397 return d
398
399 self.patch(self.ui.backend, self.method, check)
400 button = getattr(self.ui.signin_page.panel.ui,
401 '%s_button' % self.method)
402 button.click()
403
404 yield d
405
406 self.assertTrue(self.ui.signin_page.isEnabled())
407 self.assertFalse(self._called) # the wizard page was not changed
408
400409
401class UbuntuOneWizardRegisterTestCase(UbuntuOneWizardLoginTestCase):410class UbuntuOneWizardRegisterTestCase(UbuntuOneWizardLoginTestCase):
402 """Test the register through the wizard."""411 """Test the register through the wizard."""
403412
=== modified file 'ubuntuone/controlpanel/gui/qt/wizard.py'
--- ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-20 15:11:56 +0000
+++ ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-27 15:50:42 +0000
@@ -44,6 +44,7 @@
44 LICENSE_LINK,44 LICENSE_LINK,
45 UBUNTUONE_LINK,45 UBUNTUONE_LINK,
46)46)
47from ubuntuone.controlpanel.gui.qt import handle_errors
47from ubuntuone.controlpanel.gui.qt.folders import (48from ubuntuone.controlpanel.gui.qt.folders import (
48 RemoteFoldersPanel,49 RemoteFoldersPanel,
49 LocalFoldersPanel,50 LocalFoldersPanel,
@@ -167,8 +168,6 @@
167class UbuntuOneWizard(cache.Cache, QtGui.QWizard):168class UbuntuOneWizard(cache.Cache, QtGui.QWizard):
168 """The Ubuntu One wizard."""169 """The Ubuntu One wizard."""
169170
170 show_license = False # do not change unless you know what you're doing
171
172 def __init__(self, *args, **kwargs):171 def __init__(self, *args, **kwargs):
173 super(UbuntuOneWizard, self).__init__(*args, **kwargs)172 super(UbuntuOneWizard, self).__init__(*args, **kwargs)
174 self.pages = {}173 self.pages = {}
@@ -185,9 +184,8 @@
185184
186 # license185 # license
187 self.license_page = LicensePage()186 self.license_page = LicensePage()
188 self.next_button_text = self.button(self.NextButton).text()187 self.license_page.setCommitPage(True)
189 if self.show_license:188 self.addPage(self.license_page)
190 self.addPage(self.license_page)
191189
192 # sign in190 # sign in
193 self.signin_page = SignInPage()191 self.signin_page = SignInPage()
@@ -213,7 +211,7 @@
213 self.addPage(self.local_folders_page)211 self.addPage(self.local_folders_page)
214212
215 self._next_id = self.pages[self.signin_page]213 self._next_id = self.pages[self.signin_page]
216 self.next()214 self.setStartId(self._next_id)
217215
218 # pylint: disable=C0103216 # pylint: disable=C0103
219217
@@ -231,12 +229,14 @@
231 button_layout = button_to = button = stage = None229 button_layout = button_to = button = stage = None
232230
233 if page is self.license_page:231 if page is self.license_page:
234 button_layout = [self.Stretch, self.CancelButton, self.NextButton]232 button_layout = [self.Stretch, self.CancelButton,
235 button = self.button(self.NextButton)233 self.CommitButton]
234 button = self.button(self.CommitButton)
236 button_to = self.button(self.CancelButton)235 button_to = self.button(self.CancelButton)
237 stage = self.side_widget.install_stage236 stage = self.side_widget.install_stage
237 self._next_id = self.pages[self.signin_page]
238238
239 self.setButtonText(self.NextButton, LICENSE_AGREE)239 self.setButtonText(self.CommitButton, LICENSE_AGREE)
240 self.setButtonText(self.CancelButton, LICENSE_DISAGREE)240 self.setButtonText(self.CancelButton, LICENSE_DISAGREE)
241241
242 elif page is self.signin_page:242 elif page is self.signin_page:
@@ -250,8 +250,6 @@
250 self.setTabOrder(self.signin_page.panel.ui.login_button, button)250 self.setTabOrder(self.signin_page.panel.ui.login_button, button)
251251
252 elif page is self.cloud_folders_page:252 elif page is self.cloud_folders_page:
253 self.setButtonText(self.NextButton, self.next_button_text)
254
255 button_layout = [self.Stretch, self.NextButton]253 button_layout = [self.Stretch, self.NextButton]
256 button = self.cloud_folders_page.panel.ui.check_settings_button254 button = self.cloud_folders_page.panel.ui.check_settings_button
257 button_to = self.button(self.NextButton)255 button_to = self.button(self.NextButton)
@@ -303,22 +301,28 @@
303 self.next()301 self.next()
304302
305 @QtCore.pyqtSlot()303 @QtCore.pyqtSlot()
304 @handle_errors(logger=logger)
306 @defer.inlineCallbacks305 @defer.inlineCallbacks
307 def login(self):306 def login(self):
308 """Show the login dialog."""307 """Show the login dialog."""
309 self.setEnabled(False)308 self.setEnabled(False)
310 credentials = yield self.backend.login()309 try:
311 self._process_credentials(credentials)310 credentials = yield self.backend.login()
312 self.setEnabled(True)311 self._process_credentials(credentials)
312 finally:
313 self.setEnabled(True)
313314
314 @QtCore.pyqtSlot()315 @QtCore.pyqtSlot()
316 @handle_errors(logger=logger)
315 @defer.inlineCallbacks317 @defer.inlineCallbacks
316 def register(self):318 def register(self):
317 """Show the register dialog."""319 """Show the register dialog."""
318 self.setEnabled(False)320 self.setEnabled(False)
319 credentials = yield self.backend.register()321 try:
320 self._process_credentials(credentials)322 credentials = yield self.backend.register()
321 self.setEnabled(True)323 self._process_credentials(credentials)
324 finally:
325 self.setEnabled(True)
322326
323 @QtCore.pyqtSlot()327 @QtCore.pyqtSlot()
324 def check_settings(self):328 def check_settings(self):
@@ -339,8 +343,7 @@
339 if response == QtGui.QDialog.Accepted:343 if response == QtGui.QDialog.Accepted:
340 logger.warning('UbuntuOneWizard: user canceled setup.')344 logger.warning('UbuntuOneWizard: user canceled setup.')
341 self.rejected.emit()345 self.rejected.emit()
342 elif (self.show_license and346 elif (self.currentId() == self.pages[self.license_page]):
343 self.currentId() == self.pages[self.license_page]):
344 response = self.confirm_dialog.exec_()347 response = self.confirm_dialog.exec_()
345 if response == QtGui.QDialog.Accepted:348 if response == QtGui.QDialog.Accepted:
346 logger.warning('UbuntuOneWizard: user wants to uninstall.')349 logger.warning('UbuntuOneWizard: user wants to uninstall.')
347350
=== modified file 'ubuntuone/controlpanel/utils/__init__.py'
--- ubuntuone/controlpanel/utils/__init__.py 2012-03-16 16:40:27 +0000
+++ ubuntuone/controlpanel/utils/__init__.py 2012-03-27 15:50:42 +0000
@@ -38,11 +38,13 @@
38 are_updates_present = windows.are_updates_present38 are_updates_present = windows.are_updates_present
39 default_folders = windows.default_folders39 default_folders = windows.default_folders
40 perform_update = windows.perform_update40 perform_update = windows.perform_update
41 add_to_autostart = windows.add_to_autostart
41else:42else:
42 from ubuntuone.controlpanel.utils import linux43 from ubuntuone.controlpanel.utils import linux
43 are_updates_present = lambda *args, **kwargs: False44 are_updates_present = lambda *args, **kwargs: False
44 default_folders = linux.default_folders45 default_folders = linux.default_folders
45 perform_update = lambda *args, **kwargs: None46 perform_update = lambda *args, **kwargs: None
47 add_to_autostart = lambda *args, **kwargs: None
4648
47# pylint: enable=C010349# pylint: enable=C0103
4850
4951
=== modified file 'ubuntuone/controlpanel/utils/tests/test_windows.py'
--- ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-16 19:55:22 +0000
+++ ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-27 15:50:42 +0000
@@ -18,6 +18,7 @@
18"""Test the windows utils functions."""18"""Test the windows utils functions."""
1919
20import os20import os
21import sys
2122
22from twisted.internet import defer23from twisted.internet import defer
2324
@@ -87,6 +88,93 @@
87 self.assertEqual(0, self._called[0][5])88 self.assertEqual(0, self._called[0][5])
8889
8990
91class FakeOpenKey(object):
92
93 """A Fake OpenKey class.
94
95 This class becomes a method-like callable on FakeRegistry, allowing
96 FakeRegistry.OpenKey to operate as a context manager."""
97
98 def __init__(self):
99 self.openkey_args = None
100 super(FakeOpenKey, self).__init__()
101
102 def __call__(self, *args, **kwargs):
103 self.openkey_args = (args, kwargs)
104 return self
105
106 def __enter__(self, *args, **kwargs):
107 #self.openkey_args = (args, kwargs)
108 return self
109
110 def __exit__(self, *args):
111 pass
112
113
114class FakeRegistry(object):
115
116 """A fake registry."""
117
118 # pylint: disable=C0103
119 HKEY_CURRENT_USER = 2
120 KEY_ALL_ACCESS = 4
121 REG_SZ = 1
122
123 def __init__(self):
124 self.HKEY_CURRENT_USER = 2
125 self.KEY_ALL_ACCESS = 4
126 self.openkey_args = None
127 self.query_args = None
128 self.set_args = []
129
130 self.OpenKey = FakeOpenKey()
131
132 def QueryValueEx(self, *args, **kwargs):
133 """Fake QueryValueEx."""
134 self.query_args = (args, kwargs)
135
136 def SetValueEx(self, *args, **kwargs):
137 """Fake SetValueEx."""
138 self.set_args.append((args, kwargs))
139
140
141class AutostartTestCase(TestCase):
142
143 """Test add_syncdaemon_to_autostart."""
144
145 @defer.inlineCallbacks
146 def setUp(self):
147 """Initialize this test instance."""
148 self.registry = FakeRegistry()
149 self.patch(utils.windows, "_winreg", self.registry)
150 yield super(AutostartTestCase, self).setUp()
151
152 def test_add_syncdaemon_to_autostart(self):
153 """Check that the registry is updated correctly."""
154 # I can't patch sys because frozen is not there by default
155 sys.frozen = True
156 self.addCleanup(delattr, sys, 'frozen')
157 utils.windows.add_to_autostart()
158 self.assertEqual(self.registry.OpenKey.openkey_args,
159 ((self.registry.HKEY_CURRENT_USER, utils.windows.AUTORUN_KEY, 0,
160 self.registry.KEY_ALL_ACCESS), {}))
161 self.assertEqual(self.registry.query_args, None)
162 path = os.path.dirname(os.path.abspath(sys.executable))
163 self.assertEqual(self.registry.set_args,
164 [((self.registry.OpenKey, 'Ubuntu One', 0, 1,
165 '"%s\\ubuntuone-syncdaemon.exe"' % path), {}),
166 ((self.registry.OpenKey, 'Ubuntu One Icon', 0, 1,
167 '"%s\\ubuntuone-control-panel-qt.exe" --minimized' % path),
168 {})])
169
170 def test_not_added_if_not_frozen(self):
171 """Not frozen binaries are not added to the registry."""
172 utils.windows.add_to_autostart()
173 self.assertEqual(self.registry.openkey_args, None)
174 self.assertEqual(self.registry.query_args, None)
175 self.assertEqual(self.registry.set_args, [])
176
177
90class DefaultFoldersTestCase(TestCase):178class DefaultFoldersTestCase(TestCase):
91 """Test the default_folders method."""179 """Test the default_folders method."""
92180
93181
=== modified file 'ubuntuone/controlpanel/utils/windows.py'
--- ubuntuone/controlpanel/utils/windows.py 2012-03-16 19:55:22 +0000
+++ ubuntuone/controlpanel/utils/windows.py 2012-03-27 15:50:42 +0000
@@ -23,6 +23,7 @@
23# Avoid pylint error on Linux23# Avoid pylint error on Linux
24# pylint: disable=F040124# pylint: disable=F0401
25import win32api25import win32api
26import _winreg
2627
27from win32com.shell import shell, shellcon28from win32com.shell import shell, shellcon
28# pylint: enable=F040129# pylint: enable=F0401
@@ -33,6 +34,7 @@
3334
34logger = setup_logging('utils.windows')35logger = setup_logging('utils.windows')
35AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe'36AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe'
37AUTORUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"
3638
3739
38def _get_update_path():40def _get_update_path():
@@ -96,3 +98,21 @@
96 win32api.ShellExecute(None, 'runas',98 win32api.ShellExecute(None, 'runas',
97 update_path,99 update_path,
98 '--unattendedmodeui none', '', 0)100 '--unattendedmodeui none', '', 0)
101
102
103def add_to_autostart():
104 """Add syncdaemon to the session's autostart."""
105 if getattr(sys, "frozen", False):
106 sd_path = '"%s"' % os.path.join(os.path.dirname(
107 os.path.abspath(sys.executable)),
108 "ubuntuone-syncdaemon.exe")
109 u1cp_path = '"%s"' % os.path.join(os.path.dirname(
110 os.path.abspath(sys.executable)),
111 "ubuntuone-control-panel-qt.exe")
112
113 with _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, AUTORUN_KEY,
114 0, _winreg.KEY_ALL_ACCESS) as key:
115 # pylint: disable=E0602
116 _winreg.SetValueEx(key, "Ubuntu One", 0, _winreg.REG_SZ, sd_path)
117 _winreg.SetValueEx(key, "Ubuntu One Icon", 0, _winreg.REG_SZ,
118 u1cp_path + " --minimized --with-icon")

Subscribers

People subscribed via source and target branches