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
1=== added file 'data/external_icon_dark_grey.png'
2Binary 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
3=== modified file 'data/qt/images.qrc'
4--- data/qt/images.qrc 2012-03-15 01:25:08 +0000
5+++ data/qt/images.qrc 2012-03-27 15:50:42 +0000
6@@ -2,6 +2,7 @@
7 <qresource prefix="/">
8 <file>../banner.png</file>
9 <file>../computer.png</file>
10+ <file>../external_icon_dark_grey.png</file>
11 <file>../external_icon_orange.png</file>
12 <file>../external_icon_white.png</file>
13 <file>../icon.png</file>
14
15=== modified file 'data/qt/linux.qss'
16--- data/qt/linux.qss 2012-03-16 21:10:54 +0000
17+++ data/qt/linux.qss 2012-03-27 15:50:42 +0000
18@@ -1,2 +1,18 @@
19 /* Styles specific to the linux platform */
20
21+QPushButton:focus,
22+GoToWebButton#help_button:focus,
23+GoToWebButton#share_publish_button:focus {
24+ /* hack to make the mild-orange focused box dissapear */
25+ padding-top: 100%;
26+ padding-bottom: 100%;
27+ /* end of hack */
28+}
29+
30+QTabBar::tab:hover,
31+QTabBar::tab:focus {
32+ /* hack to make the mild-orange focused box dissapear */
33+ padding-left: 1000px;
34+ padding-right: 1000px;
35+ /* end of hack */
36+}
37
38=== modified file 'data/qt/preferences.ui'
39--- data/qt/preferences.ui 2012-03-14 18:37:40 +0000
40+++ data/qt/preferences.ui 2012-03-27 15:50:42 +0000
41@@ -95,6 +95,9 @@
42 <property name="orientation">
43 <enum>Qt::Vertical</enum>
44 </property>
45+ <property name="sizeType">
46+ <enum>QSizePolicy::Minimum</enum>
47+ </property>
48 <property name="sizeHint" stdset="0">
49 <size>
50 <width>40</width>
51
52=== modified file 'data/qt/side_widget.ui'
53--- data/qt/side_widget.ui 2012-03-14 15:11:19 +0000
54+++ data/qt/side_widget.ui 2012-03-27 15:50:42 +0000
55@@ -20,7 +20,16 @@
56 <property name="spacing">
57 <number>40</number>
58 </property>
59- <property name="margin">
60+ <property name="leftMargin">
61+ <number>0</number>
62+ </property>
63+ <property name="topMargin">
64+ <number>0</number>
65+ </property>
66+ <property name="rightMargin">
67+ <number>10</number>
68+ </property>
69+ <property name="bottomMargin">
70 <number>0</number>
71 </property>
72 <item>
73@@ -83,6 +92,9 @@
74 <property name="text">
75 <string notr="true">Install</string>
76 </property>
77+ <property name="wordWrap">
78+ <bool>true</bool>
79+ </property>
80 </widget>
81 </item>
82 </layout>
83@@ -125,6 +137,9 @@
84 <property name="text">
85 <string notr="true">Sign In</string>
86 </property>
87+ <property name="wordWrap">
88+ <bool>true</bool>
89+ </property>
90 </widget>
91 </item>
92 </layout>
93@@ -164,6 +179,9 @@
94 <property name="text">
95 <string notr="true">Select sync folders</string>
96 </property>
97+ <property name="wordWrap">
98+ <bool>true</bool>
99+ </property>
100 </widget>
101 </item>
102 </layout>
103@@ -203,6 +221,9 @@
104 <property name="text">
105 <string notr="true">Sync, stream, share!</string>
106 </property>
107+ <property name="wordWrap">
108+ <bool>true</bool>
109+ </property>
110 </widget>
111 </item>
112 </layout>
113
114=== modified file 'data/qt/ubuntuone.qss'
115--- data/qt/ubuntuone.qss 2012-03-20 13:05:20 +0000
116+++ data/qt/ubuntuone.qss 2012-03-27 15:50:42 +0000
117@@ -7,7 +7,7 @@
118 */
119
120 QMainWindow {
121- background-color: #aea79f;
122+ background-color: #adadad;
123 }
124
125 QWidget {
126@@ -16,6 +16,7 @@
127
128 QFrame {
129 border: none;
130+ border-color: #333333;
131 }
132
133 UbuntuOneWizard,
134@@ -23,13 +24,12 @@
135 background: white;
136 border-radius: 5px;
137 border-style: solid;
138- border-color: #939389;
139 border-width: 1px;
140 min-height: 90px;
141 }
142
143 QFrame#frame_greeting {
144- margin 0px;
145+ margin: 0px;
146 padding-left: 15px;
147 padding-top: 10px;
148 padding-right: 10px;
149@@ -39,7 +39,6 @@
150 QFrame#frame_status,
151 QFrame#frame_storage {
152 border-style: dotted;
153- border-color: #939389;
154 border-left-width: 1px;
155 padding: 10px;
156 min-width: 40px;
157@@ -47,24 +46,21 @@
158
159 QFrame#account_separator {
160 border-style: dotted;
161- border-color: #939389;
162 border-bottom-width: 1px;
163 }
164
165 QFrame#frm_box { /*The Loading Overlay frame.*/
166- background: #ffffff;
167+ background: white;
168 border-radius: 5px;
169 border-style: solid;
170- border-color: #939389;
171 border-width: 1px;
172 color: white;
173 min-height: 100px;
174 }
175
176-SideWidget {
177+SideWidget { /* is a QFrame, so border color is already set */
178 background-color: white;
179 border-style: dotted;
180- border-color: #939389;
181 border-right-width: 1px;
182 color: white;
183 min-height: 100px;
184@@ -85,10 +81,6 @@
185 padding: 5px;
186 padding-left: 19px;
187 padding-right: 19px;
188- /* hack to make the mild-orange focused box dissapear */
189- padding-top: 100%;
190- padding-bottom: 100%;
191- /* end of hack */
192 }
193
194 QPushButton:disabled {
195@@ -100,7 +92,7 @@
196
197 QPushButton:enabled {
198 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
199- stop: 0 #ffffff,stop: 1.0 #e6e6e6);
200+ stop: 0 white, stop: 1.0 #e6e6e6);
201 color: #333333;
202 border-color: #999999;
203 }
204@@ -111,7 +103,7 @@
205
206 QPushButton:enabled:hover {
207 background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
208- stop: 0 #ffffff,stop: 1.0 #ededed);
209+ stop: 0 white, stop: 1.0 #ededed);
210 }
211
212 QPushButton:enabled:pressed {
213@@ -169,10 +161,9 @@
214 background: transparent;
215 border: none;
216 text-decoration: underline;
217- color: white;
218- padding-left: 10px;
219- padding-right: 25px;
220- background-image: url(:/external_icon_white.png);
221+ padding-left: 2px; /* 2px border buffer when focused */
222+ padding-right: 15px;
223+ background-image: url(:/external_icon_dark_grey.png);
224 background-repeat: no-repeat;
225 background-position: right;
226 background-origin: margin;
227@@ -180,13 +171,9 @@
228
229 GoToWebButton#help_button:focus {
230 border: 2px solid #dd4814;
231- /* hack to make the mild-orange focused box dissapear */
232- padding-top: 100%;
233- padding-bottom: 100%;
234- /* end of hack */
235 /* Compensate for border so text doesn't move */
236- padding-left: 8px;
237- padding-right: 23px;
238+ padding-left: 0px;
239+ padding-right: 13px;
240 }
241
242 GoToWebButton#share_publish_button {
243@@ -204,84 +191,72 @@
244
245 GoToWebButton#share_publish_button:focus {
246 border: 2px solid #aea79f;
247- /* hack to make the mild-orange focused box dissapear */
248- padding-top: 100%;
249- padding-bottom: 100%;
250- /* end of hack */
251 /* Compensate for border so text doesn't move */
252 padding-left: 8px;
253 padding-right: 23px;
254 }
255
256+GoToWebButton#edit_profile_button,
257+GoToWebButton#edit_services_button,
258+GoToWebButton#get_more_space_button {
259+ padding-left: 8px;
260+ padding-right: 25px;
261+ background-image: url(:/external_icon_white.png);
262+ background-repeat: no-repeat;
263+ background-position: right;
264+ background-origin: margin;
265+}
266+
267+QTabWidget {
268+ border-bottom-left-radius: 5px;
269+ border-bottom-right-radius: 5px;
270+ border-style: solid;
271+ padding: 10px;
272+}
273+
274+QTabWidget::pane {
275+ border-bottom-left-radius: 5px;
276+ border-bottom-right-radius: 5px;
277+ border-top-right-radius: 5px;
278+ border-style: solid;
279+ border-color: #333333;
280+ border-width: 1px;
281+ background: white;
282+ position: absolute;
283+ top: -2px;
284+}
285+
286 QTabBar::tab {
287- height: 15px;
288- color: #333333;
289- background-color: #e4e0dd;
290+ background-color: #e3e0dd;
291 border-top-left-radius: 5px;
292 border-top-right-radius: 5px;
293+ border-bottom-right-radius: 1px;
294+ border-bottom-left-radius: 1px;
295 border-style: solid;
296 padding: 12px;
297- border-top-color: #939389;
298- border-right-color: #939389;
299- border-left-color: white;
300- border-bottom-color: #939389;
301+ border-color: #898989;
302+ border-left-color: #e3e0dd; /* same as background */
303 border-width: 1px;
304+ margin-bottom: 1px; /* to be able to override the QTabWidget border */
305+ border-bottom-color: #333333; /* same as background for QTabWidget */
306+}
307+
308+QTabBar::tab:first {
309+ border-left-color: #898989; /* same as border-color */
310+ border-bottom-left-radius: 0px;
311 }
312
313 QTabBar::tab:selected {
314 background-color: white;
315- border-top-left-radius: 5px;
316- border-top-right-radius: 5px;
317- border-style: solid;
318- padding: 12px;
319- border-top-color: #939389;
320- border-right-color: #939389;
321- border-left-color: white;
322- border-bottom-color: white;
323- border-width: 1px;
324-}
325-
326-QTabBar::tab:first {
327- border-left-color: #939389;
328-}
329-
330-QTabBar::tab:middle:!selected {
331- border-left-color: #e4e0dd;
332-}
333-
334-QTabBar::tab:last:!selected {
335- border-left-color: #e4e0dd;
336-}
337-
338-QTabBar::tab:hover {
339- background: #f6f6f6;
340- text-decoration: underline;
341-}
342-
343+ border-color: #333333;
344+ border-bottom-color: white; /* same as background for selected */
345+ border-bottom-right-radius: 0px;
346+ border-bottom-left-radius: 0px;
347+}
348+
349+QTabBar::tab:hover,
350 QTabBar::tab:focus {
351 text-decoration: underline;
352- /* hack to make the mild-orange focused box dissapear */
353- padding-left: 1000px;
354- padding-right: 1000px;
355- /* end of hack */
356-}
357-
358-QTabWidget {
359- border-bottom-left-radius: 5px;
360- border-bottom-right-radius: 5px;
361- border-style: solid;
362- padding: 10px;
363-}
364-
365-QTabWidget::pane {
366- border-bottom-left-radius: 5px;
367- border-bottom-right-radius: 5px;
368- border-top-right-radius: 5px;
369- border-style: solid;
370- border-color: #939389;
371- border-width: 1px;
372- background: white;
373- border-top: 2px solid white;
374 }
375
376 QGroupBox {
377@@ -332,10 +307,6 @@
378 margin-top: -4px;
379 }
380
381-QLabel#follow_us_label {
382- color: white;
383-}
384-
385 QLabel[OverQuota="true"],
386 QLabel#warning_label {
387 color: #df2d1f;
388@@ -343,7 +314,6 @@
389
390 QAbstractItemView {
391 border-style: solid;
392- border-color: #898989;
393 border-top-width: 1px;
394 border-bottom-width: 1px;
395 alternate-background-color: #f7f6f5;
396@@ -363,19 +333,9 @@
397 padding-right: 0px;
398 }
399
400-GoToWebButton#edit_profile_button,
401-GoToWebButton#edit_services_button,
402-GoToWebButton#get_more_space_button {
403- padding-left: 8px;
404- padding-right: 25px;
405- background-image: url(:/external_icon_white.png);
406- background-repeat: no-repeat;
407- background-position: right;
408- background-origin: margin;
409-}
410-
411 QSpinBox {
412 padding: 3px;
413+ background-color: white;
414 }
415
416 QSpinBox:focus {
417@@ -389,3 +349,12 @@
418 background: #fcece7;
419 color: black;
420 }
421+
422+
423+QMessageBox > QWidget > QPushButton:focus {
424+ /* use the same padding from the original QPushButton:focus setting */
425+ /* hack to make the mild-orange focused box dissapear */
426+ padding-top: 5px;
427+ padding-bottom: 5px;
428+ /* end of hack */
429+}
430
431=== modified file 'data/qt/windows.qss'
432--- data/qt/windows.qss 2012-03-15 01:25:08 +0000
433+++ data/qt/windows.qss 2012-03-27 15:50:42 +0000
434@@ -3,3 +3,14 @@
435 QWidget {
436 font-family: "Ubuntu";
437 }
438+
439+QTabBar::tab:hover,
440+QTabBar::tab:focus {
441+ padding-left: 0px;
442+ padding-right: 0px;
443+}
444+
445+QPushButton#twitter_button:focus,
446+QPushButton#facebook_button:focus {
447+ padding: 0px;
448+}
449
450=== modified file 'ubuntuone/controlpanel/gui/qt/__init__.py'
451--- ubuntuone/controlpanel/gui/qt/__init__.py 2012-03-02 13:53:24 +0000
452+++ ubuntuone/controlpanel/gui/qt/__init__.py 2012-03-27 15:50:42 +0000
453@@ -70,6 +70,12 @@
454 return icon
455
456
457+# Invalid name "box"
458+# pylint: disable=C0103
459+box = None
460+# pylint: enable=C0103
461+
462+
463 def handle_errors(error_handler=None, logger=None):
464 """Decorator to handle errors when calling a function.
465
466@@ -107,13 +113,35 @@
467 else:
468 msgs = [e.__class__.__name__] + map(repr, e.args)
469 msg = '\n'.join(msgs)
470+
471+ # hack to avoid the QMessageBox being gargabe-collected too soon
472+ # Using the global statement, pylint: disable=W0603
473+ global box
474+ # pylint: enable=W0603
475 box = QtGui.QMessageBox(QtGui.QMessageBox.Critical,
476- GENERAL_ERROR_TITLE, GENERAL_ERROR_MSG,
477- QtGui.QMessageBox.Close,
478- parent=None)
479+ GENERAL_ERROR_TITLE, GENERAL_ERROR_MSG,
480+ QtGui.QMessageBox.Close, parent=None)
481+ box.setDefaultButton(QtGui.QMessageBox.Close)
482 box.setDetailedText(msg)
483- box.setDefaultButton(QtGui.QMessageBox.Close)
484- box.exec_()
485+
486+ # can not exec_() on the QMessageBox since that will block the Qt
487+ # mainloop
488+
489+ d = defer.Deferred()
490+
491+ def box_finished(result):
492+ """The QMessageBox finished."""
493+ logger.info('The warning dialog was shown and also closed '
494+ '(message was %r).', msg)
495+ box.finished.disconnect(box_finished)
496+ box.hide()
497+ box.deleteLater()
498+ d.callback(result)
499+
500+ box.finished.connect(box_finished)
501+ box.show()
502+
503+ yield d
504
505 return inner
506
507
508=== modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py'
509--- ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-19 20:55:52 +0000
510+++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-27 15:50:42 +0000
511@@ -170,3 +170,11 @@
512 def on_wizard_finished(self, status):
513 """Move to controlpanel if wizard ended successfully."""
514 self.on_credentials_found()
515+
516+ @log_call(logger.info)
517+ def start_from_license(self):
518+ """Use the license page as first page."""
519+ # license
520+ self.ui.wizard.setStartId(self.ui.wizard.pages[
521+ self.ui.wizard.license_page])
522+ self.ui.wizard.restart()
523
524=== modified file 'ubuntuone/controlpanel/gui/qt/gui.py'
525--- ubuntuone/controlpanel/gui/qt/gui.py 2012-03-06 21:33:23 +0000
526+++ ubuntuone/controlpanel/gui/qt/gui.py 2012-03-27 15:50:42 +0000
527@@ -20,6 +20,7 @@
528
529 from ubuntuone.controlpanel.gui.qt.systray import TrayIcon
530 from ubuntuone.controlpanel.gui.qt.ui import mainwindow_ui
531+from ubuntuone.controlpanel.utils import add_to_autostart
532
533 # pylint: disable=E0611
534 try:
535@@ -35,7 +36,7 @@
536 class MainWindow(QtGui.QMainWindow):
537 """The Main Window of the Control Panel."""
538
539- def __init__(self, close_callback=None):
540+ def __init__(self, close_callback=None, installer=False):
541 """Initialize this instance with the UI layout."""
542 super(MainWindow, self).__init__()
543 self.ui = mainwindow_ui.Ui_MainWindow()
544@@ -46,6 +47,10 @@
545 triggered=self.close)
546 self.quit_action.setShortcuts(["Ctrl+q", "Ctrl+w"])
547 self.addAction(self.quit_action)
548+ self.installer = installer
549+ if installer:
550+ self.ui.control_panel.start_from_license()
551+ add_to_autostart()
552 if USE_LIBUNITY:
553 self.entry = Unity.LauncherEntry.get_for_desktop_id(U1_DOTDESKTOP)
554 else:
555@@ -84,14 +89,15 @@
556 # pylint: enable=C0103
557
558
559-def start(close_callback, minimized=False, with_icon=False):
560+def start(close_callback, minimized=False, with_icon=False, installer=False):
561 """Show the UI elements."""
562 # pylint: disable=W0404, F0401
563 if not minimized:
564 if with_icon or minimized:
565- window = MainWindow()
566+ window = MainWindow(installer=installer)
567 else:
568- window = MainWindow(close_callback=close_callback)
569+ window = MainWindow(close_callback=close_callback,
570+ installer=installer)
571 app = QtGui.QApplication.instance()
572 style = QtGui.QStyle.alignedRect(
573 QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter,
574
575=== modified file 'ubuntuone/controlpanel/gui/qt/main/__init__.py'
576--- ubuntuone/controlpanel/gui/qt/main/__init__.py 2012-03-16 21:09:40 +0000
577+++ ubuntuone/controlpanel/gui/qt/main/__init__.py 2012-03-27 15:50:42 +0000
578@@ -55,6 +55,9 @@
579 default=False,
580 help="Start Ubuntu One "
581 "with an icon in the notification area.")
582+ result.add_argument("--installer", dest="installer", action="store_true",
583+ default=False,
584+ help="Show the license agreement page first.")
585 return result
586
587
588@@ -82,17 +85,19 @@
589 switch_to = args.switch_to
590 minimized = args.minimized
591 with_icon = args.with_icon
592+ installer = args.installer
593 source.main(app)
594
595 data = []
596- for qss_name in (source.PLATFORM_QSS, ":/ubuntuone.qss"):
597+ for qss_name in (":/ubuntuone.qss", source.PLATFORM_QSS):
598 qss = QtCore.QResource(qss_name)
599 data.append(unicode(qss.data()))
600 app.setStyleSheet('\n'.join(data))
601
602 # Unused variable 'window', 'icon', pylint: disable=W0612
603 icon, window = start(lambda: source.main_quit(app),
604- minimized=minimized, with_icon=with_icon)
605+ minimized=minimized, with_icon=with_icon,
606+ installer=installer)
607 window.switch_to(switch_to)
608 # pylint: enable=W0612
609 if icon:
610
611=== modified file 'ubuntuone/controlpanel/gui/qt/main/tests/test_main.py'
612--- ubuntuone/controlpanel/gui/qt/main/tests/test_main.py 2012-03-16 21:14:20 +0000
613+++ ubuntuone/controlpanel/gui/qt/main/tests/test_main.py 2012-03-27 15:50:42 +0000
614@@ -132,25 +132,25 @@
615 """Ensure the binary name is not given to argparse."""
616 main.main(["foo", "bar", sys.argv[0], "--minimized"])
617 self.assertEqual(self.start.args[1],
618- {'minimized': True, 'with_icon': False})
619+ {'minimized': True, 'with_icon': False, 'installer': False})
620
621 def test_minimized_option(self):
622 """Ensure the --minimized option is parsed and passed correctly."""
623 main.main([sys.argv[0], "--minimized"])
624 self.assertEqual(self.start.args[1],
625- {'minimized': True, 'with_icon': False})
626+ {'minimized': True, 'with_icon': False, 'installer': False})
627
628 def test_with_icon_option(self):
629 """Ensure the --minimized option is parsed and passed correctly."""
630 main.main([sys.argv[0], "--with-icon"])
631 self.assertEqual(self.start.args[1],
632- {'minimized': False, 'with_icon': True})
633+ {'minimized': False, 'with_icon': True, 'installer': False})
634
635 def test_all_styles_load(self):
636 """Ensure the platform style is loaded."""
637 main.main([sys.argv[0]])
638 data = []
639- for qss_name in (main.source.PLATFORM_QSS, ":/ubuntuone.qss"):
640+ for qss_name in (":/ubuntuone.qss", main.source.PLATFORM_QSS):
641 qss = QtCore.QResource(qss_name)
642 data.append(unicode(qss.data()))
643 self.assertEqual((('\n'.join(data),), {}), self.app.style)
644@@ -160,6 +160,12 @@
645 main.main([sys.argv[0], "--switch-to", "folders"])
646 self.assertEqual(self.start.window.tabname, "folders")
647
648+ def test_installer_option(self):
649+ """Ensure the --installer option is parsed and passed correctly."""
650+ main.main([sys.argv[0], "--installer"])
651+ self.assertEqual(self.start.args[1],
652+ {'minimized': False, 'with_icon': False, 'installer': True})
653+
654 def test_translator(self):
655 """Ensure the Qt translator is loaded."""
656 main.main([sys.argv[0]])
657
658=== modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py'
659--- ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-03-08 20:46:13 +0000
660+++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-03-27 15:50:42 +0000
661@@ -187,17 +187,16 @@
662 return inner
663
664
665-class FakedDialog(object):
666+class FakedDialog(QtGui.QMessageBox):
667 """Fake a confirmation dialog."""
668
669- Close = object()
670- Critical = object()
671 properties = response = args = kwargs = None
672
673 def __init__(self, *a, **kw):
674+ super(FakedDialog, self).__init__(*a, **kw)
675 FakedDialog.args = a
676 FakedDialog.kwargs = kw
677- FakedDialog.properties = {'exec_': 0}
678+ FakedDialog.properties = {'shown': 0}
679
680 @classmethod
681 def reset(cls, *a, **kw):
682@@ -216,17 +215,24 @@
683
684 def setDetailedText(self, text):
685 """Fake the setDetailedText."""
686+ super(FakedDialog, self).setDetailedText(text)
687 FakedDialog.properties['detailed_text'] = text
688
689 def setDefaultButton(self, button):
690 """Fake the setDefaultButton."""
691+ super(FakedDialog, self).setDefaultButton(button)
692 FakedDialog.properties['default_button'] = button
693
694 # pylint: enable=C0103
695
696+ def show(self):
697+ """Fake show."""
698+ FakedDialog.properties['shown'] += 1
699+ self.finished.emit(0)
700+
701 def exec_(self):
702 """Fake exec_."""
703- FakedDialog.properties['exec_'] += 1
704+ FakedDialog.properties['shown'] += 1
705
706
707 class FakedFileDialog(object):
708@@ -275,7 +281,9 @@
709 self.ui = self.class_ui(**self.kwargs)
710 # pylint: enable=E1102
711 self.ui.show()
712- self.addCleanup(self.ui.destroy)
713+ self.addCleanup(self.ui.hide)
714+ self.addCleanup(self.ui.deleteLater)
715+ self.addCleanup(QtCore.QCoreApplication.instance().processEvents)
716
717 if getattr(self.ui, 'backend', None) is not None:
718 self.addCleanup(self.ui.backend._called.clear)
719
720=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_common.py'
721--- ubuntuone/controlpanel/gui/qt/tests/test_common.py 2011-10-05 16:35:59 +0000
722+++ ubuntuone/controlpanel/gui/qt/tests/test_common.py 2012-03-27 15:50:42 +0000
723@@ -132,7 +132,8 @@
724 yield self.decorate_me()
725
726 logged = self.memento.check_exception(self.failure.__class__, msg)
727- recs = '\n'.join(rec.exc_text for rec in self.memento.records)
728+ recs = '\n'.join(rec.exc_text for rec in self.memento.records
729+ if rec.exc_text is not None)
730 self.assertTrue(logged, 'Exception must be logged, got:\n%s' % recs)
731
732 @defer.inlineCallbacks
733@@ -147,7 +148,7 @@
734 QtGui.QMessageBox.Close)
735 self.assertEqual(FakedDialog.args, args)
736 self.assertEqual(FakedDialog.kwargs, {'parent': None})
737- self.assertEqual(FakedDialog.properties['exec_'], 1)
738+ self.assertEqual(FakedDialog.properties['shown'], 1)
739
740 @defer.inlineCallbacks
741 def test_show_error_message_default_button(self):
742
743=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py'
744--- ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-19 15:50:31 +0000
745+++ ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-27 15:50:42 +0000
746@@ -1,8 +1,6 @@
747 # -*- coding: utf-8 -*-
748-
749-# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
750 #
751-# Copyright 2011 Canonical Ltd.
752+# Copyright 2011-2012 Canonical Ltd.
753 #
754 # This program is free software: you can redistribute it and/or modify it
755 # under the terms of the GNU General Public License version 3, as published
756@@ -186,6 +184,16 @@
757 remote = self.ui.ui.folders_tab.remote_folders
758 self.assertFalse(remote)
759
760+ def test_start_from_license(self):
761+ """Ensure we change the starting page correctly."""
762+ # Before, we start on sign_in
763+ self.assertEqual(self.ui.ui.wizard.startId(),
764+ self.ui.ui.wizard.pages[self.ui.ui.wizard.signin_page])
765+ # After, we start on license_page
766+ self.ui.start_from_license()
767+ self.assertEqual(self.ui.ui.wizard.startId(),
768+ self.ui.ui.wizard.pages[self.ui.ui.wizard.license_page])
769+
770
771 class ExternalLinkButtonsTestCase(ControlPanelTestCase):
772 """The link in the go-to-web buttons are correct."""
773
774=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_folders.py'
775--- ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-19 20:51:26 +0000
776+++ ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2012-03-27 15:50:42 +0000
777@@ -26,6 +26,7 @@
778 from PyQt4 import QtGui
779 from twisted.internet import defer
780 from ubuntuone.devtools.handlers import MementoHandler
781+from ubuntuone.devtools.testcases import skipIfOS
782
783 from ubuntuone.controlpanel.tests import helper_fail
784 from ubuntuone.controlpanel.gui.tests import (
785@@ -694,10 +695,6 @@
786 empty_dir = os.path.join(dir_path, 'empty')
787 os.mkdir(empty_dir)
788
789- # add a symlink to confirm those are avoided
790- a_link = os.path.join(dir_path, 'some_link')
791- os.symlink(a_file, a_link)
792-
793 return total_size
794
795
796@@ -733,6 +730,28 @@
797 self.assertRaises(Queue.Empty, self.queue.get, block=True, timeout=0.5)
798
799
800+@skipIfOS("win32", "Windows does not easily support symlinks")
801+class CalculateSizeWithSymlinksTestCase(BaseLocalFoldersTestCase):
802+ """Test suite for the CalculateSize thread implementation."""
803+
804+ def build_test_dir(self, dir_path):
805+ """Build a testing directory hierarchy."""
806+ total_size = super(CalculateSizeWithSymlinksTestCase,
807+ self).build_test_dir(dir_path)
808+
809+ a_file = os.path.join(dir_path, 'to_be_symlinked')
810+ with open(a_file, 'wb') as f:
811+ f.write('y' * 5000)
812+
813+ total_size += os.path.getsize(a_file)
814+
815+ # add a symlink to confirm those are avoided
816+ a_link = os.path.join(dir_path, 'some_link')
817+ os.symlink(a_file, a_link)
818+
819+ return total_size
820+
821+
822 class FakedCalculateSize(object):
823 """A faked CalculateSize thread."""
824
825
826=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_gui.py'
827--- ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-03-09 01:05:49 +0000
828+++ ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-03-27 15:50:42 +0000
829@@ -18,6 +18,8 @@
830
831 """Tests for the Qt UI."""
832
833+from twisted.internet import defer
834+
835 from ubuntuone.controlpanel.gui.qt import gui
836 from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
837
838@@ -115,3 +117,17 @@
839 self.patch(self.ui, "entry", entry)
840 self.ui.set_urgent("foo")
841 self.assertEqual(entry.called, (('urgent', "foo"), {}))
842+
843+
844+class AutoStartTestCase(MainWindowTestCase):
845+ """Test the add_to_autostart call."""
846+
847+ @defer.inlineCallbacks
848+ def setUp(self):
849+ # Be sure to patch add_to_autostart *before* class_ui creation occurs.
850+ self.patch(gui, "add_to_autostart", self._set_called)
851+ yield super(AutoStartTestCase, self).setUp()
852+
853+ def test_add_to_autostart(self):
854+ """Test that the add_to_autostart function is called when CP opens."""
855+ self.assertTrue(self._called)
856
857=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_start.py'
858--- ubuntuone/controlpanel/gui/qt/tests/test_start.py 2012-02-17 14:42:57 +0000
859+++ ubuntuone/controlpanel/gui/qt/tests/test_start.py 2012-03-27 15:50:42 +0000
860@@ -78,7 +78,7 @@
861 gui.start(close_callback=self.close_cb,
862 with_icon=True, minimized=False)
863 kwargs = {'close_callback': self.close_cb, 'window': self.main_window}
864- self.assertEqual(self.main_window.args, [((), {})])
865+ self.assertEqual(self.main_window.args, [((), {'installer': False})])
866 self.assertEqual(self.tray_icon.args, [((), kwargs)])
867
868 def test_both_false(self):
869
870=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_wizard.py'
871--- ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-20 15:14:24 +0000
872+++ ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-27 15:50:42 +0000
873@@ -89,7 +89,7 @@
874 # Finish button is visible (and enabled if isComplete() returns true).
875
876 # After calling setFinalPage(false), isFinalPage() returns true if
877- #nextId() returns -1; otherwise, it returns false.
878+ # nextId() returns -1; otherwise, it returns false.
879
880 self.patch(self.ui, 'nextId', lambda *a: 0)
881 self.assertFalse(self.ui.isFinalPage())
882@@ -153,11 +153,9 @@
883
884 class_ui = gui.UbuntuOneWizard
885 confirm_response = gui.QtGui.QDialog.Accepted
886- show_license = False
887
888 @defer.inlineCallbacks
889 def setUp(self):
890- self.patch(self.class_ui, 'show_license', self.show_license)
891 yield super(UbuntuOneWizardTestCase, self).setUp()
892 self.patch(self.ui.confirm_dialog, 'exec_',
893 lambda: self.confirm_response)
894@@ -186,11 +184,7 @@
895
896 def test_first_page(self):
897 """The first page is the correct one."""
898- if self.show_license:
899- expected = self.ui.pages[self.ui.license_page]
900- else:
901- expected = self.ui.pages[self.ui.signin_page]
902-
903+ expected = self.ui.pages[self.ui.signin_page]
904 self.assertEqual(self.ui.startId(), expected)
905
906 def test_done_accepted(self):
907@@ -202,12 +196,6 @@
908 self.assertEqual(self._called, ((gui.QtGui.QDialog.Accepted,), {}))
909
910
911-class LicensedUbuntuOneWizardTestCase(UbuntuOneWizardTestCase):
912- """Test the LicensedUbuntuOneWizard."""
913-
914- show_license = True
915-
916-
917 class UbuntuOneWizardSignInTestCase(UbuntuOneWizardTestCase):
918 """Test the SignInPage wizard page."""
919
920@@ -267,12 +255,13 @@
921 if text is not None:
922 self.assertEqual(unicode(button.text()), text)
923
924- getattr(self.ui, signal).connect(self._set_called)
925- button.click()
926+ if signal:
927+ getattr(self.ui, signal).connect(self._set_called)
928+ button.click()
929
930- self.assertEqual(self._called, (signal_args, {}),
931- msg % (name, signal, signal_args))
932- self._called = False
933+ self.assertEqual(self._called, (signal_args, {}),
934+ msg % (name, signal, signal_args))
935+ self._called = False
936
937 def test_done_rejected(self):
938 """When the wizard was cancelled and user confirmed, finish."""
939@@ -300,7 +289,7 @@
940 class UbuntuOneWizardCloudToComputerTestCase(UbuntuOneWizardSignInTestCase):
941 """Test the CloudToComputerPage wizard page."""
942
943- buttons = {'NextButton': (None, 'currentIdChanged', (3,))}
944+ buttons = {'NextButton': (None, 'currentIdChanged', (4,))}
945 page_name = 'cloud_folders'
946 stage_name = 'folders'
947
948@@ -308,7 +297,7 @@
949 class UbuntuOneWizardSettingsTestCase(UbuntuOneWizardSignInTestCase):
950 """Test the CloudToComputerPage wizard page."""
951
952- buttons = {'BackButton': (None, 'currentIdChanged', (0,))}
953+ buttons = {'BackButton': (None, 'currentIdChanged', (1,))}
954 page_name = 'settings'
955 stage_name = 'folders'
956
957@@ -318,7 +307,7 @@
958
959 buttons = {
960 'FinishButton': (None, 'finished', (gui.QtGui.QDialog.Accepted,)),
961- 'BackButton': (None, 'currentIdChanged', (0,)),
962+ 'BackButton': (None, 'currentIdChanged', (1,)),
963 }
964 page_name = 'local_folders'
965 stage_name = 'sync'
966@@ -341,11 +330,10 @@
967 """Test the LicensePage wizard page."""
968
969 buttons = {
970- 'NextButton': (gui.LICENSE_AGREE, 'currentIdChanged', (1,)),
971+ 'CommitButton': (gui.LICENSE_AGREE, None, ()),
972 'CancelButton': (gui.LICENSE_DISAGREE, 'rejected', ()),
973 }
974 page_name = 'license'
975- show_license = True
976 stage_name = 'install'
977
978
979@@ -397,6 +385,27 @@
980 self.assertTrue(self.ui.signin_page.isEnabled())
981 self.assertFalse(self._called)
982
983+ @defer.inlineCallbacks
984+ def test_with_error(self):
985+ """Wizard is enabled after an error was handled."""
986+ self.ui.currentIdChanged.connect(self._set_called)
987+ d = defer.fail(ValueError())
988+
989+ def check():
990+ """Confirm the ui is disabled while processing."""
991+ self.assertFalse(self.ui.signin_page.isEnabled())
992+ return d
993+
994+ self.patch(self.ui.backend, self.method, check)
995+ button = getattr(self.ui.signin_page.panel.ui,
996+ '%s_button' % self.method)
997+ button.click()
998+
999+ yield d
1000+
1001+ self.assertTrue(self.ui.signin_page.isEnabled())
1002+ self.assertFalse(self._called) # the wizard page was not changed
1003+
1004
1005 class UbuntuOneWizardRegisterTestCase(UbuntuOneWizardLoginTestCase):
1006 """Test the register through the wizard."""
1007
1008=== modified file 'ubuntuone/controlpanel/gui/qt/wizard.py'
1009--- ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-20 15:11:56 +0000
1010+++ ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-27 15:50:42 +0000
1011@@ -44,6 +44,7 @@
1012 LICENSE_LINK,
1013 UBUNTUONE_LINK,
1014 )
1015+from ubuntuone.controlpanel.gui.qt import handle_errors
1016 from ubuntuone.controlpanel.gui.qt.folders import (
1017 RemoteFoldersPanel,
1018 LocalFoldersPanel,
1019@@ -167,8 +168,6 @@
1020 class UbuntuOneWizard(cache.Cache, QtGui.QWizard):
1021 """The Ubuntu One wizard."""
1022
1023- show_license = False # do not change unless you know what you're doing
1024-
1025 def __init__(self, *args, **kwargs):
1026 super(UbuntuOneWizard, self).__init__(*args, **kwargs)
1027 self.pages = {}
1028@@ -185,9 +184,8 @@
1029
1030 # license
1031 self.license_page = LicensePage()
1032- self.next_button_text = self.button(self.NextButton).text()
1033- if self.show_license:
1034- self.addPage(self.license_page)
1035+ self.license_page.setCommitPage(True)
1036+ self.addPage(self.license_page)
1037
1038 # sign in
1039 self.signin_page = SignInPage()
1040@@ -213,7 +211,7 @@
1041 self.addPage(self.local_folders_page)
1042
1043 self._next_id = self.pages[self.signin_page]
1044- self.next()
1045+ self.setStartId(self._next_id)
1046
1047 # pylint: disable=C0103
1048
1049@@ -231,12 +229,14 @@
1050 button_layout = button_to = button = stage = None
1051
1052 if page is self.license_page:
1053- button_layout = [self.Stretch, self.CancelButton, self.NextButton]
1054- button = self.button(self.NextButton)
1055+ button_layout = [self.Stretch, self.CancelButton,
1056+ self.CommitButton]
1057+ button = self.button(self.CommitButton)
1058 button_to = self.button(self.CancelButton)
1059 stage = self.side_widget.install_stage
1060+ self._next_id = self.pages[self.signin_page]
1061
1062- self.setButtonText(self.NextButton, LICENSE_AGREE)
1063+ self.setButtonText(self.CommitButton, LICENSE_AGREE)
1064 self.setButtonText(self.CancelButton, LICENSE_DISAGREE)
1065
1066 elif page is self.signin_page:
1067@@ -250,8 +250,6 @@
1068 self.setTabOrder(self.signin_page.panel.ui.login_button, button)
1069
1070 elif page is self.cloud_folders_page:
1071- self.setButtonText(self.NextButton, self.next_button_text)
1072-
1073 button_layout = [self.Stretch, self.NextButton]
1074 button = self.cloud_folders_page.panel.ui.check_settings_button
1075 button_to = self.button(self.NextButton)
1076@@ -303,22 +301,28 @@
1077 self.next()
1078
1079 @QtCore.pyqtSlot()
1080+ @handle_errors(logger=logger)
1081 @defer.inlineCallbacks
1082 def login(self):
1083 """Show the login dialog."""
1084 self.setEnabled(False)
1085- credentials = yield self.backend.login()
1086- self._process_credentials(credentials)
1087- self.setEnabled(True)
1088+ try:
1089+ credentials = yield self.backend.login()
1090+ self._process_credentials(credentials)
1091+ finally:
1092+ self.setEnabled(True)
1093
1094 @QtCore.pyqtSlot()
1095+ @handle_errors(logger=logger)
1096 @defer.inlineCallbacks
1097 def register(self):
1098 """Show the register dialog."""
1099 self.setEnabled(False)
1100- credentials = yield self.backend.register()
1101- self._process_credentials(credentials)
1102- self.setEnabled(True)
1103+ try:
1104+ credentials = yield self.backend.register()
1105+ self._process_credentials(credentials)
1106+ finally:
1107+ self.setEnabled(True)
1108
1109 @QtCore.pyqtSlot()
1110 def check_settings(self):
1111@@ -339,8 +343,7 @@
1112 if response == QtGui.QDialog.Accepted:
1113 logger.warning('UbuntuOneWizard: user canceled setup.')
1114 self.rejected.emit()
1115- elif (self.show_license and
1116- self.currentId() == self.pages[self.license_page]):
1117+ elif (self.currentId() == self.pages[self.license_page]):
1118 response = self.confirm_dialog.exec_()
1119 if response == QtGui.QDialog.Accepted:
1120 logger.warning('UbuntuOneWizard: user wants to uninstall.')
1121
1122=== modified file 'ubuntuone/controlpanel/utils/__init__.py'
1123--- ubuntuone/controlpanel/utils/__init__.py 2012-03-16 16:40:27 +0000
1124+++ ubuntuone/controlpanel/utils/__init__.py 2012-03-27 15:50:42 +0000
1125@@ -38,11 +38,13 @@
1126 are_updates_present = windows.are_updates_present
1127 default_folders = windows.default_folders
1128 perform_update = windows.perform_update
1129+ add_to_autostart = windows.add_to_autostart
1130 else:
1131 from ubuntuone.controlpanel.utils import linux
1132 are_updates_present = lambda *args, **kwargs: False
1133 default_folders = linux.default_folders
1134 perform_update = lambda *args, **kwargs: None
1135+ add_to_autostart = lambda *args, **kwargs: None
1136
1137 # pylint: enable=C0103
1138
1139
1140=== modified file 'ubuntuone/controlpanel/utils/tests/test_windows.py'
1141--- ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-16 19:55:22 +0000
1142+++ ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-27 15:50:42 +0000
1143@@ -18,6 +18,7 @@
1144 """Test the windows utils functions."""
1145
1146 import os
1147+import sys
1148
1149 from twisted.internet import defer
1150
1151@@ -87,6 +88,93 @@
1152 self.assertEqual(0, self._called[0][5])
1153
1154
1155+class FakeOpenKey(object):
1156+
1157+ """A Fake OpenKey class.
1158+
1159+ This class becomes a method-like callable on FakeRegistry, allowing
1160+ FakeRegistry.OpenKey to operate as a context manager."""
1161+
1162+ def __init__(self):
1163+ self.openkey_args = None
1164+ super(FakeOpenKey, self).__init__()
1165+
1166+ def __call__(self, *args, **kwargs):
1167+ self.openkey_args = (args, kwargs)
1168+ return self
1169+
1170+ def __enter__(self, *args, **kwargs):
1171+ #self.openkey_args = (args, kwargs)
1172+ return self
1173+
1174+ def __exit__(self, *args):
1175+ pass
1176+
1177+
1178+class FakeRegistry(object):
1179+
1180+ """A fake registry."""
1181+
1182+ # pylint: disable=C0103
1183+ HKEY_CURRENT_USER = 2
1184+ KEY_ALL_ACCESS = 4
1185+ REG_SZ = 1
1186+
1187+ def __init__(self):
1188+ self.HKEY_CURRENT_USER = 2
1189+ self.KEY_ALL_ACCESS = 4
1190+ self.openkey_args = None
1191+ self.query_args = None
1192+ self.set_args = []
1193+
1194+ self.OpenKey = FakeOpenKey()
1195+
1196+ def QueryValueEx(self, *args, **kwargs):
1197+ """Fake QueryValueEx."""
1198+ self.query_args = (args, kwargs)
1199+
1200+ def SetValueEx(self, *args, **kwargs):
1201+ """Fake SetValueEx."""
1202+ self.set_args.append((args, kwargs))
1203+
1204+
1205+class AutostartTestCase(TestCase):
1206+
1207+ """Test add_syncdaemon_to_autostart."""
1208+
1209+ @defer.inlineCallbacks
1210+ def setUp(self):
1211+ """Initialize this test instance."""
1212+ self.registry = FakeRegistry()
1213+ self.patch(utils.windows, "_winreg", self.registry)
1214+ yield super(AutostartTestCase, self).setUp()
1215+
1216+ def test_add_syncdaemon_to_autostart(self):
1217+ """Check that the registry is updated correctly."""
1218+ # I can't patch sys because frozen is not there by default
1219+ sys.frozen = True
1220+ self.addCleanup(delattr, sys, 'frozen')
1221+ utils.windows.add_to_autostart()
1222+ self.assertEqual(self.registry.OpenKey.openkey_args,
1223+ ((self.registry.HKEY_CURRENT_USER, utils.windows.AUTORUN_KEY, 0,
1224+ self.registry.KEY_ALL_ACCESS), {}))
1225+ self.assertEqual(self.registry.query_args, None)
1226+ path = os.path.dirname(os.path.abspath(sys.executable))
1227+ self.assertEqual(self.registry.set_args,
1228+ [((self.registry.OpenKey, 'Ubuntu One', 0, 1,
1229+ '"%s\\ubuntuone-syncdaemon.exe"' % path), {}),
1230+ ((self.registry.OpenKey, 'Ubuntu One Icon', 0, 1,
1231+ '"%s\\ubuntuone-control-panel-qt.exe" --minimized' % path),
1232+ {})])
1233+
1234+ def test_not_added_if_not_frozen(self):
1235+ """Not frozen binaries are not added to the registry."""
1236+ utils.windows.add_to_autostart()
1237+ self.assertEqual(self.registry.openkey_args, None)
1238+ self.assertEqual(self.registry.query_args, None)
1239+ self.assertEqual(self.registry.set_args, [])
1240+
1241+
1242 class DefaultFoldersTestCase(TestCase):
1243 """Test the default_folders method."""
1244
1245
1246=== modified file 'ubuntuone/controlpanel/utils/windows.py'
1247--- ubuntuone/controlpanel/utils/windows.py 2012-03-16 19:55:22 +0000
1248+++ ubuntuone/controlpanel/utils/windows.py 2012-03-27 15:50:42 +0000
1249@@ -23,6 +23,7 @@
1250 # Avoid pylint error on Linux
1251 # pylint: disable=F0401
1252 import win32api
1253+import _winreg
1254
1255 from win32com.shell import shell, shellcon
1256 # pylint: enable=F0401
1257@@ -33,6 +34,7 @@
1258
1259 logger = setup_logging('utils.windows')
1260 AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe'
1261+AUTORUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"
1262
1263
1264 def _get_update_path():
1265@@ -96,3 +98,21 @@
1266 win32api.ShellExecute(None, 'runas',
1267 update_path,
1268 '--unattendedmodeui none', '', 0)
1269+
1270+
1271+def add_to_autostart():
1272+ """Add syncdaemon to the session's autostart."""
1273+ if getattr(sys, "frozen", False):
1274+ sd_path = '"%s"' % os.path.join(os.path.dirname(
1275+ os.path.abspath(sys.executable)),
1276+ "ubuntuone-syncdaemon.exe")
1277+ u1cp_path = '"%s"' % os.path.join(os.path.dirname(
1278+ os.path.abspath(sys.executable)),
1279+ "ubuntuone-control-panel-qt.exe")
1280+
1281+ with _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, AUTORUN_KEY,
1282+ 0, _winreg.KEY_ALL_ACCESS) as key:
1283+ # pylint: disable=E0602
1284+ _winreg.SetValueEx(key, "Ubuntu One", 0, _winreg.REG_SZ, sd_path)
1285+ _winreg.SetValueEx(key, "Ubuntu One Icon", 0, _winreg.REG_SZ,
1286+ u1cp_path + " --minimized --with-icon")

Subscribers

People subscribed via source and target branches