Merge lp:~diegosarmentero/ubuntuone-windows-installer/installer-ui into lp:ubuntuone-windows-installer

Proposed by Diego Sarmentero
Status: Merged
Merged at revision: 21
Proposed branch: lp:~diegosarmentero/ubuntuone-windows-installer/installer-ui
Merge into: lp:ubuntuone-windows-installer
Diff against target: 2064 lines (+1089/-639)
13 files modified
data/qt/choose_sign_in.ui (+12/-6)
data/qt/images.qrc (+17/-0)
data/qt/license.ui (+8/-8)
data/qt/setup_account.ui (+51/-34)
data/qt/side_widget.ui (+238/-64)
data/qt/ubuntuone.qss (+96/-0)
ubuntuone_installer/gui/qt/gui.py (+23/-6)
ubuntuone_installer/gui/qt/local_folders.py (+170/-167)
ubuntuone_installer/gui/qt/main/windows.py (+62/-48)
ubuntuone_installer/gui/qt/setup_account.py (+158/-156)
ubuntuone_installer/gui/qt/side_widget.py (+73/-49)
ubuntuone_installer/gui/qt/tests/test_gui.py (+26/-1)
ubuntuone_installer/gui/qt/tests/test_side_widget.py (+155/-100)
To merge this branch: bzr merge lp:~diegosarmentero/ubuntuone-windows-installer/installer-ui
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Natalia Bidart (community) Approve
Ubuntu One hackers Pending
Review via email: mp+67788@code.launchpad.net

Commit message

Styling for the installer.

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

* We need to avoid adding markup to translatable string, so this line:

 label_text = [_("<b>Your password must contain</b>"), ]

should be:

 label_text = [ "<b>%s</b>" % _("Your password must contain"), ]

* Please replace all occurrences of "Ubuntu One" for the APP_NAME constant imported from ubuntuone.clientdefs

review: Needs Fixing
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

I tried this IRL, and there are a couple of issues. I took screenshots of all of them:

* http://ubuntuone.com/p/14cF/ the side bar icons are cropped when navigating the sign in and login page

* http://ubuntuone.com/p/14cH/ and http://ubuntuone.com/p/14cI/ the test entries are resized so the text in the right fits the screen

* The buttons does not show any indication when they are pressed

review: Needs Fixing
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

The button thingy will be solved with bug #811103.

===============================================================================
[FAIL]
Traceback (most recent call last):
  File "C:\Users\Test\src\installer-ui\ubuntuone_installer\gui\qt\tests\test_gui.py", line 216, in test_current_user_controller_parameters
    'subtitle': gui.SIGN_IN_SUBTITLE}))
twisted.trial.unittest.FailTest: not equal:
a = ((),
 {'subtitle': 'Sign in with your existing Ubuntu One username and password.',
  'title': '<span style="font-size:24px">Sign in to Ubuntu One</span>'})
b = ((),
 {'subtitle': 'Sign in with your existing Ubuntu One username and password.',
  'title': 'Sign in to Ubuntu One'})

ubuntuone_installer.gui.qt.tests.test_gui.MainWindowTestCase.test_current_user_controller_parameters
===============================================================================
[ERROR]
Traceback (most recent call last):
  File "C:\Users\Test\src\installer-ui\ubuntuone_installer\gui\qt\tests\test_gui.py", line 633, in test_side_widget_state
    self.ui.on_currentIdChanged(self.ui.LICENSE_PAGE)
exceptions.AttributeError: 'SetupAccountPage' object has no attribute 'on_currentIdChanged'

ubuntuone_installer.gui.qt.tests.test_gui.SetupAccountTestCase.test_side_widget_state

review: Needs Fixing
Revision history for this message
Natalia Bidart (nataliabidart) :
review: Approve
Revision history for this message
Roberto Alsina (ralsina) wrote :

Looks great (except the disabled buttons, of course).

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

Attempt to merge into lp:ubuntuone-windows-installer failed due to conflicts:

text conflict in ubuntuone_installer/gui/qt/local_folders.py
text conflict in ubuntuone_installer/gui/qt/main/windows.py

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/Ubuntu-R.ttf'
2Binary files data/Ubuntu-R.ttf 1970-01-01 00:00:00 +0000 and data/Ubuntu-R.ttf 2011-07-19 02:28:34 +0000 differ
3=== added file 'data/balloon_shape.png'
4Binary files data/balloon_shape.png 1970-01-01 00:00:00 +0000 and data/balloon_shape.png 2011-07-19 02:28:34 +0000 differ
5=== added file 'data/password_hint_ok.png'
6Binary files data/password_hint_ok.png 1970-01-01 00:00:00 +0000 and data/password_hint_ok.png 2011-07-19 02:28:34 +0000 differ
7=== added file 'data/password_hint_warning.png'
8Binary files data/password_hint_warning.png 1970-01-01 00:00:00 +0000 and data/password_hint_warning.png 2011-07-19 02:28:34 +0000 differ
9=== added file 'data/progress_arrow_grey.png'
10Binary files data/progress_arrow_grey.png 1970-01-01 00:00:00 +0000 and data/progress_arrow_grey.png 2011-07-19 02:28:34 +0000 differ
11=== added file 'data/progress_arrow_orange.png'
12Binary files data/progress_arrow_orange.png 1970-01-01 00:00:00 +0000 and data/progress_arrow_orange.png 2011-07-19 02:28:34 +0000 differ
13=== added file 'data/progress_finish_grey.png'
14Binary files data/progress_finish_grey.png 1970-01-01 00:00:00 +0000 and data/progress_finish_grey.png 2011-07-19 02:28:34 +0000 differ
15=== added file 'data/progress_finish_orange.png'
16Binary files data/progress_finish_orange.png 1970-01-01 00:00:00 +0000 and data/progress_finish_orange.png 2011-07-19 02:28:34 +0000 differ
17=== added file 'data/progress_tick.png'
18Binary files data/progress_tick.png 1970-01-01 00:00:00 +0000 and data/progress_tick.png 2011-07-19 02:28:34 +0000 differ
19=== modified file 'data/qt/choose_sign_in.ui'
20--- data/qt/choose_sign_in.ui 2011-07-02 01:20:51 +0000
21+++ data/qt/choose_sign_in.ui 2011-07-19 02:28:34 +0000
22@@ -44,13 +44,14 @@
23 </size>
24 </property>
25 <property name="text">
26- <string>image
27-
28-[This will be the same image as appears on Ubuntu One Home page on the web - in production]</string>
29+ <string/>
30 </property>
31 <property name="textFormat">
32 <enum>Qt::PlainText</enum>
33 </property>
34+ <property name="pixmap">
35+ <pixmap resource="images.qrc">:/win_install_img_placeholder.png</pixmap>
36+ </property>
37 <property name="alignment">
38 <set>Qt::AlignCenter</set>
39 </property>
40@@ -93,7 +94,7 @@
41 </property>
42 <property name="sizeHint" stdset="0">
43 <size>
44- <width>40</width>
45+ <width>20</width>
46 <height>20</height>
47 </size>
48 </property>
49@@ -129,9 +130,12 @@
50 <property name="orientation">
51 <enum>Qt::Horizontal</enum>
52 </property>
53+ <property name="sizeType">
54+ <enum>QSizePolicy::Expanding</enum>
55+ </property>
56 <property name="sizeHint" stdset="0">
57 <size>
58- <width>40</width>
59+ <width>20</width>
60 <height>20</height>
61 </size>
62 </property>
63@@ -154,6 +158,8 @@
64 </item>
65 </layout>
66 </widget>
67- <resources/>
68+ <resources>
69+ <include location="images.qrc"/>
70+ </resources>
71 <connections/>
72 </ui>
73
74=== added file 'data/qt/images.qrc'
75--- data/qt/images.qrc 1970-01-01 00:00:00 +0000
76+++ data/qt/images.qrc 2011-07-19 02:28:34 +0000
77@@ -0,0 +1,17 @@
78+<RCC>
79+ <qresource prefix="/">
80+ <file>../balloon_shape.png</file>
81+ <file>../password_hint_ok.png</file>
82+ <file>../password_hint_warning.png</file>
83+ <file>../Ubuntu-R.ttf</file>
84+ <file>ubuntuone.qss</file>
85+ <file>../progress_arrow_grey.png</file>
86+ <file>../u1_logo.png</file>
87+ <file>../progress_arrow_orange.png</file>
88+ <file>../progress_finish_grey.png</file>
89+ <file>../progress_finish_orange.png</file>
90+ <file>../progress_tick.png</file>
91+ <file>../u1icon.png</file>
92+ <file>../win_install_img_placeholder.png</file>
93+ </qresource>
94+</RCC>
95
96=== modified file 'data/qt/license.ui'
97--- data/qt/license.ui 2011-06-21 18:45:09 +0000
98+++ data/qt/license.ui 2011-07-19 02:28:34 +0000
99@@ -20,14 +20,14 @@
100 <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
101 &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
102 p, li { white-space: pre-wrap; }
103-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
104-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:14pt; font-weight:600;&quot;&gt;License Agreement&lt;/span&gt;&lt;/p&gt;
105-&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;&lt;/p&gt;
106-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation.&lt;/span&gt;&lt;/p&gt;
107-&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;&lt;/p&gt;
108-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Ubuntu One Basic is free, while additional service add-ons may be paid for services.&lt;/span&gt;&lt;/p&gt;
109-&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;&lt;/p&gt;
110-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;As free software, this programme is distributed without warranty. See the GNU General Public License for more details at &lt;/span&gt;&lt;a href=&quot;http://www.gnu.org/licenses&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.gnu.org/licenses&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
111+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
112+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600;&quot;&gt;License Agreement&lt;/span&gt;&lt;/p&gt;
113+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;/p&gt;
114+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation.&lt;/span&gt;&lt;/p&gt;
115+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;/p&gt;
116+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Ubuntu One Basic is free, while additional service add-ons may be paid for services.&lt;/span&gt;&lt;/p&gt;
117+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;/p&gt;
118+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;As free software, this programme is distributed without warranty. See the GNU General Public License for more details at &lt;/span&gt;&lt;a href=&quot;http://www.gnu.org/licenses&quot;&gt;&lt;span style=&quot; font-size:8pt; text-decoration: underline; color:#dd4814;&quot;&gt;http://www.gnu.org/licenses&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
119 </property>
120 <property name="openExternalLinks">
121 <bool>true</bool>
122
123=== modified file 'data/qt/setup_account.ui'
124--- data/qt/setup_account.ui 2011-07-01 20:33:17 +0000
125+++ data/qt/setup_account.ui 2011-07-19 02:28:34 +0000
126@@ -6,8 +6,8 @@
127 <rect>
128 <x>0</x>
129 <y>0</y>
130- <width>482</width>
131- <height>514</height>
132+ <width>631</width>
133+ <height>527</height>
134 </rect>
135 </property>
136 <property name="windowTitle">
137@@ -15,7 +15,7 @@
138 </property>
139 <layout class="QVBoxLayout" name="verticalLayout">
140 <item>
141- <layout class="QGridLayout" name="gridLayout">
142+ <layout class="QGridLayout" name="gridLayout" columnminimumwidth="1,250">
143 <item row="0" column="0">
144 <widget class="QLabel" name="password_info_label">
145 <property name="sizePolicy">
146@@ -25,7 +25,7 @@
147 </sizepolicy>
148 </property>
149 <property name="text">
150- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
151+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
152 </property>
153 <property name="wordWrap">
154 <bool>true</bool>
155@@ -35,7 +35,7 @@
156 <item row="1" column="0">
157 <widget class="QLabel" name="name_label">
158 <property name="text">
159- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
160+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
161 </property>
162 </widget>
163 </item>
164@@ -49,14 +49,17 @@
165 <item row="2" column="1">
166 <widget class="QLabel" name="name_assistance">
167 <property name="text">
168- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
169+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
170+ </property>
171+ <property name="indent">
172+ <number>20</number>
173 </property>
174 </widget>
175 </item>
176 <item row="3" column="0">
177 <widget class="QLabel" name="email_label">
178 <property name="text">
179- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
180+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
181 </property>
182 </widget>
183 </item>
184@@ -70,14 +73,17 @@
185 <item row="4" column="1">
186 <widget class="QLabel" name="email_assistance">
187 <property name="text">
188- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
189+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
190+ </property>
191+ <property name="indent">
192+ <number>20</number>
193 </property>
194 </widget>
195 </item>
196 <item row="5" column="0">
197 <widget class="QLabel" name="confirm_email_label">
198 <property name="text">
199- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
200+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
201 </property>
202 </widget>
203 </item>
204@@ -91,14 +97,17 @@
205 <item row="6" column="1">
206 <widget class="QLabel" name="confirm_email_assistance">
207 <property name="text">
208- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
209+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
210+ </property>
211+ <property name="indent">
212+ <number>20</number>
213 </property>
214 </widget>
215 </item>
216 <item row="7" column="0">
217 <widget class="QLabel" name="password_label">
218 <property name="text">
219- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
220+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
221 </property>
222 </widget>
223 </item>
224@@ -121,14 +130,17 @@
225 <item row="9" column="0">
226 <widget class="QLabel" name="confirm_password_label">
227 <property name="text">
228- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
229+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
230 </property>
231 </widget>
232 </item>
233 <item row="8" column="1" rowspan="3">
234 <widget class="QLabel" name="password_assistance">
235 <property name="text">
236- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
237+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
238+ </property>
239+ <property name="indent">
240+ <number>20</number>
241 </property>
242 </widget>
243 </item>
244@@ -163,26 +175,7 @@
245 <enum>QFrame::Box</enum>
246 </property>
247 <property name="text">
248- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
249- </property>
250- </widget>
251- </item>
252- <item row="11" column="1">
253- <widget class="QLabel" name="refresh_label">
254- <property name="sizePolicy">
255- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
256- <horstretch>0</horstretch>
257- <verstretch>0</verstretch>
258- </sizepolicy>
259- </property>
260- <property name="locale">
261- <locale language="English" country="UnitedStates"/>
262- </property>
263- <property name="text">
264- <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
265- </property>
266- <property name="wordWrap">
267- <bool>true</bool>
268+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
269 </property>
270 </widget>
271 </item>
272@@ -202,6 +195,28 @@
273 </property>
274 </widget>
275 </item>
276+ <item row="11" column="1">
277+ <widget class="QLabel" name="refresh_label">
278+ <property name="sizePolicy">
279+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
280+ <horstretch>0</horstretch>
281+ <verstretch>0</verstretch>
282+ </sizepolicy>
283+ </property>
284+ <property name="locale">
285+ <locale language="English" country="UnitedStates"/>
286+ </property>
287+ <property name="text">
288+ <string>If you can't read this then &lt;a href=&quot;example.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#dd4814;&quot;&gt;refresh&lt;/span&gt;&lt;/a&gt; this page&lt;/span&gt;</string>
289+ </property>
290+ <property name="wordWrap">
291+ <bool>true</bool>
292+ </property>
293+ <property name="indent">
294+ <number>20</number>
295+ </property>
296+ </widget>
297+ </item>
298 </layout>
299 </item>
300 <item>
301@@ -250,6 +265,8 @@
302 </item>
303 </layout>
304 </widget>
305- <resources/>
306+ <resources>
307+ <include location="images.qrc"/>
308+ </resources>
309 <connections/>
310 </ui>
311
312=== modified file 'data/qt/side_widget.ui'
313--- data/qt/side_widget.ui 2011-07-04 17:39:31 +0000
314+++ data/qt/side_widget.ui 2011-07-19 02:28:34 +0000
315@@ -1,77 +1,249 @@
316 <?xml version="1.0" encoding="UTF-8"?>
317 <ui version="4.0">
318- <class>Form</class>
319- <widget class="QWidget" name="Form">
320+ <class>SideWidget</class>
321+ <widget class="QFrame" name="SideWidget">
322 <property name="geometry">
323 <rect>
324 <x>0</x>
325 <y>0</y>
326- <width>185</width>
327- <height>511</height>
328+ <width>200</width>
329+ <height>563</height>
330 </rect>
331 </property>
332+ <property name="sizePolicy">
333+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
334+ <horstretch>0</horstretch>
335+ <verstretch>0</verstretch>
336+ </sizepolicy>
337+ </property>
338+ <property name="minimumSize">
339+ <size>
340+ <width>200</width>
341+ <height>0</height>
342+ </size>
343+ </property>
344 <property name="windowTitle">
345- <string>Form</string>
346+ <string>Frame</string>
347+ </property>
348+ <property name="frameShape">
349+ <enum>QFrame::StyledPanel</enum>
350+ </property>
351+ <property name="frameShadow">
352+ <enum>QFrame::Raised</enum>
353 </property>
354 <layout class="QVBoxLayout" name="verticalLayout">
355 <property name="spacing">
356- <number>20</number>
357- </property>
358- <item>
359- <widget class="QLabel" name="label">
360- <property name="text">
361- <string>Ubuntu One logo</string>
362- </property>
363- </widget>
364- </item>
365- <item>
366- <widget class="QLabel" name="install_label">
367- <property name="enabled">
368- <bool>true</bool>
369- </property>
370- <property name="text">
371- <string>Install</string>
372- </property>
373- </widget>
374- </item>
375- <item>
376- <widget class="QLabel" name="sign_in_label">
377- <property name="enabled">
378- <bool>true</bool>
379- </property>
380- <property name="text">
381- <string>Sign In</string>
382- </property>
383- </widget>
384- </item>
385- <item>
386- <widget class="QLabel" name="choose_services_label">
387- <property name="enabled">
388- <bool>true</bool>
389- </property>
390- <property name="text">
391- <string>Choose services</string>
392- </property>
393- </widget>
394- </item>
395- <item>
396- <widget class="QLabel" name="select_folders_label">
397- <property name="enabled">
398- <bool>true</bool>
399- </property>
400- <property name="text">
401- <string>Select sync folders</string>
402- </property>
403- </widget>
404- </item>
405- <item>
406- <widget class="QLabel" name="sync_label">
407- <property name="enabled">
408- <bool>true</bool>
409- </property>
410- <property name="text">
411- <string>Sync, stream, share!</string>
412- </property>
413+ <number>40</number>
414+ </property>
415+ <property name="margin">
416+ <number>10</number>
417+ </property>
418+ <item>
419+ <widget class="QLabel" name="ubuntu_one_logo_label">
420+ <property name="sizePolicy">
421+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
422+ <horstretch>0</horstretch>
423+ <verstretch>0</verstretch>
424+ </sizepolicy>
425+ </property>
426+ <property name="text">
427+ <string/>
428+ </property>
429+ <property name="pixmap">
430+ <pixmap resource="images.qrc">:/u1_logo.png</pixmap>
431+ </property>
432+ </widget>
433+ </item>
434+ <item>
435+ <widget class="QFrame" name="states_frame">
436+ <property name="sizePolicy">
437+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
438+ <horstretch>0</horstretch>
439+ <verstretch>0</verstretch>
440+ </sizepolicy>
441+ </property>
442+ <property name="frameShape">
443+ <enum>QFrame::StyledPanel</enum>
444+ </property>
445+ <property name="frameShadow">
446+ <enum>QFrame::Raised</enum>
447+ </property>
448+ <layout class="QVBoxLayout" name="verticalLayout_2">
449+ <property name="spacing">
450+ <number>20</number>
451+ </property>
452+ <property name="margin">
453+ <number>0</number>
454+ </property>
455+ <item>
456+ <layout class="QHBoxLayout" name="horizontalLayout">
457+ <property name="spacing">
458+ <number>7</number>
459+ </property>
460+ <item>
461+ <widget class="QLabel" name="install_icon_label">
462+ <property name="sizePolicy">
463+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
464+ <horstretch>0</horstretch>
465+ <verstretch>0</verstretch>
466+ </sizepolicy>
467+ </property>
468+ <property name="text">
469+ <string/>
470+ </property>
471+ <property name="pixmap">
472+ <pixmap resource="images.qrc">:/progress_arrow_grey.png</pixmap>
473+ </property>
474+ </widget>
475+ </item>
476+ <item>
477+ <widget class="QLabel" name="install_label">
478+ <property name="enabled">
479+ <bool>true</bool>
480+ </property>
481+ <property name="text">
482+ <string>Install</string>
483+ </property>
484+ </widget>
485+ </item>
486+ </layout>
487+ </item>
488+ <item>
489+ <layout class="QHBoxLayout" name="horizontalLayout_2">
490+ <property name="spacing">
491+ <number>7</number>
492+ </property>
493+ <property name="sizeConstraint">
494+ <enum>QLayout::SetDefaultConstraint</enum>
495+ </property>
496+ <item>
497+ <widget class="QLabel" name="sign_icon_label">
498+ <property name="sizePolicy">
499+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
500+ <horstretch>0</horstretch>
501+ <verstretch>0</verstretch>
502+ </sizepolicy>
503+ </property>
504+ <property name="text">
505+ <string/>
506+ </property>
507+ <property name="pixmap">
508+ <pixmap resource="images.qrc">:/progress_arrow_grey.png</pixmap>
509+ </property>
510+ </widget>
511+ </item>
512+ <item>
513+ <widget class="QLabel" name="sign_in_label">
514+ <property name="enabled">
515+ <bool>true</bool>
516+ </property>
517+ <property name="text">
518+ <string>Sign In</string>
519+ </property>
520+ </widget>
521+ </item>
522+ </layout>
523+ </item>
524+ <item>
525+ <layout class="QHBoxLayout" name="horizontalLayout_3">
526+ <property name="spacing">
527+ <number>7</number>
528+ </property>
529+ <item>
530+ <widget class="QLabel" name="choose_icon_label">
531+ <property name="sizePolicy">
532+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
533+ <horstretch>0</horstretch>
534+ <verstretch>0</verstretch>
535+ </sizepolicy>
536+ </property>
537+ <property name="text">
538+ <string/>
539+ </property>
540+ <property name="pixmap">
541+ <pixmap resource="images.qrc">:/progress_arrow_grey.png</pixmap>
542+ </property>
543+ </widget>
544+ </item>
545+ <item>
546+ <widget class="QLabel" name="choose_services_label">
547+ <property name="enabled">
548+ <bool>true</bool>
549+ </property>
550+ <property name="text">
551+ <string>Choose services</string>
552+ </property>
553+ </widget>
554+ </item>
555+ </layout>
556+ </item>
557+ <item>
558+ <layout class="QHBoxLayout" name="horizontalLayout_4">
559+ <property name="spacing">
560+ <number>7</number>
561+ </property>
562+ <item>
563+ <widget class="QLabel" name="folders_icon_label">
564+ <property name="sizePolicy">
565+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
566+ <horstretch>0</horstretch>
567+ <verstretch>0</verstretch>
568+ </sizepolicy>
569+ </property>
570+ <property name="text">
571+ <string/>
572+ </property>
573+ <property name="pixmap">
574+ <pixmap resource="images.qrc">:/progress_arrow_grey.png</pixmap>
575+ </property>
576+ </widget>
577+ </item>
578+ <item>
579+ <widget class="QLabel" name="select_folders_label">
580+ <property name="enabled">
581+ <bool>true</bool>
582+ </property>
583+ <property name="text">
584+ <string>Select sync folders</string>
585+ </property>
586+ </widget>
587+ </item>
588+ </layout>
589+ </item>
590+ <item>
591+ <layout class="QHBoxLayout" name="horizontalLayout_5">
592+ <property name="spacing">
593+ <number>7</number>
594+ </property>
595+ <item>
596+ <widget class="QLabel" name="sync_icon_label">
597+ <property name="sizePolicy">
598+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
599+ <horstretch>0</horstretch>
600+ <verstretch>0</verstretch>
601+ </sizepolicy>
602+ </property>
603+ <property name="text">
604+ <string/>
605+ </property>
606+ <property name="pixmap">
607+ <pixmap resource="images.qrc">:/progress_finish_grey.png</pixmap>
608+ </property>
609+ </widget>
610+ </item>
611+ <item>
612+ <widget class="QLabel" name="sync_label">
613+ <property name="enabled">
614+ <bool>true</bool>
615+ </property>
616+ <property name="text">
617+ <string>Sync, stream, share!</string>
618+ </property>
619+ </widget>
620+ </item>
621+ </layout>
622+ </item>
623+ </layout>
624 </widget>
625 </item>
626 <item>
627@@ -82,13 +254,15 @@
628 <property name="sizeHint" stdset="0">
629 <size>
630 <width>20</width>
631- <height>292</height>
632+ <height>40</height>
633 </size>
634 </property>
635 </spacer>
636 </item>
637 </layout>
638 </widget>
639- <resources/>
640+ <resources>
641+ <include location="images.qrc"/>
642+ </resources>
643 <connections/>
644 </ui>
645
646=== added file 'data/qt/ubuntuone.qss'
647--- data/qt/ubuntuone.qss 1970-01-01 00:00:00 +0000
648+++ data/qt/ubuntuone.qss 2011-07-19 02:28:34 +0000
649@@ -0,0 +1,96 @@
650+QFrame#SideWidget {
651+ background-color: white;
652+ border-style: dotted;
653+ border-color: #939389;
654+ border-right-width: 1px;
655+ color: white;
656+ min-height: 100px;
657+ margin-left: 10px;
658+}
659+
660+QWizard,
661+QDialog{
662+ background-color: white;
663+}
664+
665+QLabel#name_assistance,
666+QLabel#email_assistance,
667+QLabel#confirm_email_assistance,
668+QLabel#password_assistance,
669+QLabel#refresh_label{
670+ border-image: url(":/balloon_shape.png");
671+ padding-right: 2px;
672+}
673+
674+QLabel#install_label,
675+QLabel#sign_in_label,
676+QLabel#choose_services_label,
677+QLabel#select_folders_label,
678+QLabel#sync_label{
679+ font-size: 14px;
680+}
681+
682+QTextEdit{
683+ background-color: #ffffff;
684+ border: none;
685+}
686+
687+QPushButton[enabled="false"] {
688+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
689+ stop: 0 #fecfc2,stop: 1.0 #df4d1a);
690+ border-radius: 5px;
691+ border-style: solid;
692+ padding: 6px;
693+ padding-left: 20px;
694+ padding-right: 20px;
695+ color: white;
696+ border-color: #939389;
697+ border-width: 1px;
698+ height: 14px;
699+ font-size: 12px;
700+}
701+
702+QPushButton[enabled="true"] {
703+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
704+ stop: 0 #eaeaea, stop: 1.0 #cacaca);
705+ border-radius: 5px;
706+ border-style: solid;
707+ padding: 6px;
708+ padding-left: 20px;
709+ padding-right: 20px;
710+ color: #595959;
711+ border-color: #939389;
712+ border-width: 1px;
713+ height: 14px;
714+ font-size: 12px;
715+}
716+
717+QPushButton:hover {
718+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
719+ stop: 0 #feae99,stop: 1.0 #df4e1c);
720+ border-radius: 5px;
721+ border-style: solid;
722+ padding: 6px;
723+ color: white;
724+ border-color: #939389;
725+ border-width: 1px;
726+ height: 12px;
727+}
728+
729+QPushButton:pressed {
730+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
731+ stop: 0 #ba3f14,stop: 1.0 #db4714);
732+ border-radius: 5px;
733+ border-style: solid;
734+ padding: 6px;
735+ color: white;
736+ border-color: #939389;
737+ border-width: 1px;
738+ height: 12px;
739+}
740+
741+QWidget{
742+ font-family: "Ubuntu";
743+ color: #333333;
744+ font-size: 12px;
745+}
746
747=== added file 'data/u1_logo.png'
748Binary files data/u1_logo.png 1970-01-01 00:00:00 +0000 and data/u1_logo.png 2011-07-19 02:28:34 +0000 differ
749=== added file 'data/u1icon.png'
750Binary files data/u1icon.png 1970-01-01 00:00:00 +0000 and data/u1icon.png 2011-07-19 02:28:34 +0000 differ
751=== added file 'data/win_install_img_placeholder.png'
752Binary files data/win_install_img_placeholder.png 1970-01-01 00:00:00 +0000 and data/win_install_img_placeholder.png 2011-07-19 02:28:34 +0000 differ
753=== modified file 'ubuntuone_installer/gui/qt/gui.py'
754--- ubuntuone_installer/gui/qt/gui.py 2011-07-15 18:45:17 +0000
755+++ ubuntuone_installer/gui/qt/gui.py 2011-07-19 02:28:34 +0000
756@@ -69,6 +69,12 @@
757 license_ui,
758 setup_account_ui,
759 )
760+
761+# Module used to include the resources into this file
762+# pylint: disable=W0611
763+from ubuntuone_installer.gui.qt.ui import images_rc
764+# pylint: enable=W0611
765+
766 from ubuntuone_installer.gui.qt.are_you_sure import AreYouSure
767 from ubuntuone_installer.gui.qt.local_folders import LocalFoldersPage
768 from ubuntuone_installer.gui.qt.sync_now_or_later import SyncNowOrLaterPage
769@@ -80,6 +86,7 @@
770 SIGN_IN = _("Sign in to Ubuntu One")
771 SIGN_IN_SUBTITLE = _("Sign in with your existing Ubuntu One"
772 " username and password.")
773+TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
774
775 # Invalid name logger
776 # pylint: disable=C0103
777@@ -117,9 +124,9 @@
778 self.wizard().customButtonClicked.connect(self.print_document)
779
780 self.wizard().setButtonLayout([
781+ QtGui.QWizard.CancelButton,
782+ QtGui.QWizard.Stretch,
783 QtGui.QWizard.CustomButton1,
784- QtGui.QWizard.Stretch,
785- QtGui.QWizard.CancelButton,
786 QtGui.QWizard.BackButton,
787 QtGui.QWizard.NextButton,
788 QtGui.QWizard.FinishButton,
789@@ -197,9 +204,9 @@
790 # Layout without custom button 1,
791 # without finish button
792 self.wizard().setButtonLayout([
793+ QtGui.QWizard.CancelButton,
794 QtGui.QWizard.Stretch,
795 QtGui.QWizard.BackButton,
796- QtGui.QWizard.CancelButton,
797 ])
798
799
800@@ -289,6 +296,10 @@
801 self.ping_url = PING_URL
802
803 super(MainWindow, self).__init__()
804+ self.setWindowTitle(APP_NAME)
805+ self.setMinimumHeight(630)
806+ self.setMinimumWidth(800)
807+ self.setTitleFormat(QtCore.Qt.RichText)
808 self.setWizardStyle(self.ModernStyle)
809 self.close_callback = close_callback
810
811@@ -309,7 +320,9 @@
812 self.LICENSE_PAGE = self.addPage(LicensePage())
813
814 #SSO Pages
815- self.sign_in_controller = ChooseSignInController(title=SIGN_IN)
816+ title_page = TITLE_STYLE % SIGN_IN
817+ self.sign_in_controller = ChooseSignInController(
818+ title=title_page)
819 self.sign_in_page = SignInPage(
820 ui=choose_sign_in_ui.Ui_ChooseSignInPage(),
821 controller=self.sign_in_controller,
822@@ -319,15 +332,17 @@
823 setup_account_ui.Ui_SetUpAccountPage(),
824 self.setup_controller,
825 parent=self)
826+ title_page = TITLE_STYLE % _("Ubuntu One Terms of Service")
827 self.tos = TosPage(Ui_TosPage(),
828 TosController(tos_url=TC_URL,
829- title=_("Ubuntu One Terms of Service")),
830+ title=title_page),
831 parent=self)
832 self.email_verification = EmailVerificationPage(
833 Ui_EmailVerificationPage(),
834 EmailVerificationController())
835+ title_page = TITLE_STYLE % SIGN_IN
836 self.current_user_controller = CurrentUserController(
837- title=SIGN_IN, subtitle=SIGN_IN_SUBTITLE)
838+ title=title_page, subtitle=SIGN_IN_SUBTITLE)
839 self.current_user = CurrentUserSignInPage(Ui_CurrentUserSignInPage(),
840 self.current_user_controller,
841 parent=self)
842@@ -404,8 +419,10 @@
843 def on_currentIdChanged(self, page_id):
844 """The current page changed."""
845 if page_id < self.SIGNIN_PAGE:
846+ self.sideWidget().ui.states_frame.hide()
847 self.sideWidget().set_stage(0)
848 elif page_id < self.local_folders_page_id:
849+ self.sideWidget().ui.states_frame.show()
850 self.sideWidget().set_stage(1)
851 elif page_id < self.CONGRATULATIONS_PAGE:
852 self.sideWidget().set_stage(3)
853
854=== modified file 'ubuntuone_installer/gui/qt/local_folders.py'
855--- ubuntuone_installer/gui/qt/local_folders.py 2011-07-07 20:32:17 +0000
856+++ ubuntuone_installer/gui/qt/local_folders.py 2011-07-19 02:28:34 +0000
857@@ -1,167 +1,170 @@
858-# -*- coding: utf-8 -*-
859-
860-# Authors: Roberto Alsina <roberto.alsina@canonical.com>
861-#
862-# Copyright 2011 Canonical Ltd.
863-#
864-# This program is free software: you can redistribute it and/or modify it
865-# under the terms of the GNU General Public License version 3, as published
866-# by the Free Software Foundation.
867-#
868-# This program is distributed in the hope that it will be useful, but
869-# WITHOUT ANY WARRANTY; without even the implied warranties of
870-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
871-# PURPOSE. See the GNU General Public License for more details.
872-#
873-# You should have received a copy of the GNU General Public License along
874-# with this program. If not, see <http://www.gnu.org/licenses/>.
875-
876-"""Widget to create UDFs in the Windows Install Wizard."""
877-
878-import ctypes
879-import os
880-import threading
881-import Queue
882-
883-from PyQt4 import QtCore, QtGui
884-
885-from ubuntuone.controlpanel.gui import humanize
886-
887-from ubuntuone_installer.gui.qt.ui import local_folders_ui
888-from ubuntuone_installer.gui import (
889- LOCAL_FOLDERS_TITLE,
890- LOCAL_FOLDERS_SPACE_HEADER,
891- LOCAL_FOLDERS_OFFER_LABEL,
892- LOCAL_FOLDERS_CALCULATING,
893-)
894-
895-
896-class FolderItem(QtGui.QTreeWidgetItem):
897- """Class representing a folder in the folder list UI."""
898- def __init__(self, strings, path=None, queue=None):
899- super(FolderItem, self).__init__(strings)
900- self.thread = CalculateSize(path, queue)
901- self.thread.start()
902- self.size = None
903- self.path = path
904-
905-
906-class CalculateSize(threading.Thread):
907- """Class to calculate the size of a folder in the background."""
908- def __init__(self, path_name, queue):
909- self.path_name = path_name
910- self.queue = queue
911- self._stop = False
912- super(CalculateSize, self).__init__()
913- self.daemon = True
914-
915- def run(self):
916- total_size = 0
917- for dirpath, _, filenames in os.walk(self.path_name):
918- for f in filenames:
919- fp = os.path.join(dirpath, f)
920- total_size += os.path.getsize(fp)
921- self.queue.put([self.path_name, total_size])
922-
923-
924-class LocalFoldersPage(QtGui.QWizardPage):
925- """Wizard page to create UDFs in the Windows Installer."""
926- def __init__(self, parent=None):
927- super(LocalFoldersPage, self).__init__(parent)
928- self.setTitle(LOCAL_FOLDERS_TITLE)
929- self.ui = local_folders_ui.Ui_Form()
930- self.ui.setupUi(self)
931-
932- header_view = self.ui.folder_list.header()
933- header_view.setResizeMode(0, header_view.Stretch)
934-
935- self.queue = Queue.Queue()
936- self.timer = QtCore.QTimer()
937- self.items = {}
938- for folder_name in self.default_folders():
939- self.add_folder(folder_name)
940- self.update_sizes()
941- self.timer.start(2000)
942- self.timer.timeout.connect(self.update_sizes)
943-
944- # initializePage is inherited
945- # pylint: disable=C0103
946- def initializePage(self):
947- """UI details."""
948- self.wizard()._next_id = None
949-
950- def quota(self):
951- """The quota available to the user."""
952- # FIXME: get this from real life
953- return 2 * 1024 * 1024
954-
955- def default_folders(self):
956- """Return a list of the folders to add by default."""
957- # Special Folder "My Documents"
958- dll = ctypes.windll.shell32
959- buf = ctypes.create_string_buffer(300)
960- dll.SHGetSpecialFolderPathA(None, buf, 0x0005, False)
961- return [buf.value, ]
962-
963- def add_folder(self, path):
964- """Add a folder to the list."""
965- if path in self.items:
966- return None
967- # FIXME: the path should actually be sent to u1cp to verify as valid
968- item = FolderItem([path, "", "remove"], path=path, queue=self.queue)
969- self.ui.folder_list.addTopLevelItem(item)
970- self.items[path] = item
971- return item
972-
973- def update_sizes(self):
974- """Poll the queue were the threads put the size info."""
975- try:
976- path, size = self.queue.get(False)
977- item = self.items.get(path)
978- if item:
979- item.size = size
980- item.setText(1, humanize(size))
981- except Queue.Empty:
982- pass
983- total = 0
984- for path, item in self.items.items():
985- if item.size is None:
986- total = LOCAL_FOLDERS_CALCULATING
987- break
988- total += item.size
989-
990- if isinstance(total, long):
991- self.show_hide_offer(total)
992- total = humanize(total)
993- else:
994- self.show_hide_offer(0)
995- self.ui.folder_list.headerItem().setText(
996- 1, LOCAL_FOLDERS_SPACE_HEADER % total)
997-
998- def show_hide_offer(self, cur_size):
999- """Show or hide the offer to buy space according to the total size."""
1000- quota = self.quota()
1001-
1002- if cur_size > quota:
1003- self.ui.offer_frame.setVisible(True)
1004- else:
1005- self.ui.offer_frame.setVisible(False)
1006-
1007- self.ui.offer_label.setText(LOCAL_FOLDERS_OFFER_LABEL %
1008- {"quota": humanize(quota)})
1009-
1010- def stop_threads(self):
1011- """Stop all pending threads."""
1012- for _, item in self.items:
1013- item.thread._stop = True
1014-
1015- # itemClicked is a Qt signal name.
1016- # pylint: disable=C0103
1017- def on_folder_list_itemClicked(self, item, column):
1018- """Delete folder from the list."""
1019- if column == 2:
1020- del(self.items[item.path])
1021- item.thread._stop = True
1022- self.ui.folder_list.takeTopLevelItem(
1023- self.ui.folder_list.indexOfTopLevelItem(item))
1024- self.update_sizes()
1025+# -*- coding: utf-8 -*-
1026+
1027+# Authors: Roberto Alsina <roberto.alsina@canonical.com>
1028+#
1029+# Copyright 2011 Canonical Ltd.
1030+#
1031+# This program is free software: you can redistribute it and/or modify it
1032+# under the terms of the GNU General Public License version 3, as published
1033+# by the Free Software Foundation.
1034+#
1035+# This program is distributed in the hope that it will be useful, but
1036+# WITHOUT ANY WARRANTY; without even the implied warranties of
1037+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1038+# PURPOSE. See the GNU General Public License for more details.
1039+#
1040+# You should have received a copy of the GNU General Public License along
1041+# with this program. If not, see <http://www.gnu.org/licenses/>.
1042+
1043+"""Widget to create UDFs in the Windows Install Wizard."""
1044+
1045+import ctypes
1046+import os
1047+import threading
1048+import Queue
1049+
1050+from PyQt4 import QtCore, QtGui
1051+
1052+from ubuntuone.controlpanel.gui import humanize
1053+
1054+from ubuntuone_installer.gui.qt.ui import local_folders_ui
1055+from ubuntuone_installer.gui import (
1056+ LOCAL_FOLDERS_TITLE,
1057+ LOCAL_FOLDERS_SPACE_HEADER,
1058+ LOCAL_FOLDERS_OFFER_LABEL,
1059+ LOCAL_FOLDERS_CALCULATING,
1060+)
1061+
1062+TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
1063+
1064+
1065+class FolderItem(QtGui.QTreeWidgetItem):
1066+ """Class representing a folder in the folder list UI."""
1067+ def __init__(self, strings, path=None, queue=None):
1068+ super(FolderItem, self).__init__(strings)
1069+ self.thread = CalculateSize(path, queue)
1070+ self.thread.start()
1071+ self.size = None
1072+ self.path = path
1073+
1074+
1075+class CalculateSize(threading.Thread):
1076+ """Class to calculate the size of a folder in the background."""
1077+ def __init__(self, path_name, queue):
1078+ self.path_name = path_name
1079+ self.queue = queue
1080+ self._stop = False
1081+ super(CalculateSize, self).__init__()
1082+ self.daemon = True
1083+
1084+ def run(self):
1085+ total_size = 0
1086+ for dirpath, _, filenames in os.walk(self.path_name):
1087+ for f in filenames:
1088+ fp = os.path.join(dirpath, f)
1089+ total_size += os.path.getsize(fp)
1090+ self.queue.put([self.path_name, total_size])
1091+
1092+
1093+class LocalFoldersPage(QtGui.QWizardPage):
1094+ """Wizard page to create UDFs in the Windows Installer."""
1095+ def __init__(self, parent=None):
1096+ super(LocalFoldersPage, self).__init__(parent)
1097+ title_page = TITLE_STYLE % LOCAL_FOLDERS_TITLE
1098+ self.setTitle(title_page)
1099+ self.ui = local_folders_ui.Ui_Form()
1100+ self.ui.setupUi(self)
1101+
1102+ header_view = self.ui.folder_list.header()
1103+ header_view.setResizeMode(0, header_view.Stretch)
1104+
1105+ self.queue = Queue.Queue()
1106+ self.timer = QtCore.QTimer()
1107+ self.items = {}
1108+ for folder_name in self.default_folders():
1109+ self.add_folder(folder_name)
1110+ self.update_sizes()
1111+ self.timer.start(2000)
1112+ self.timer.timeout.connect(self.update_sizes)
1113+
1114+ # initializePage is inherited
1115+ # pylint: disable=C0103
1116+ def initializePage(self):
1117+ """UI details."""
1118+ self.wizard()._next_id = None
1119+
1120+ def quota(self):
1121+ """The quota available to the user."""
1122+ # FIXME: get this from real life
1123+ return 2 * 1024 * 1024
1124+
1125+ def default_folders(self):
1126+ """Return a list of the folders to add by default."""
1127+ # Special Folder "My Documents"
1128+ dll = ctypes.windll.shell32
1129+ buf = ctypes.create_string_buffer(300)
1130+ dll.SHGetSpecialFolderPathA(None, buf, 0x0005, False)
1131+ return [buf.value, ]
1132+
1133+ def add_folder(self, path):
1134+ """Add a folder to the list."""
1135+ if path in self.items:
1136+ return None
1137+ # FIXME: the path should actually be sent to u1cp to verify as valid
1138+ item = FolderItem([path, "", "remove"], path=path, queue=self.queue)
1139+ self.ui.folder_list.addTopLevelItem(item)
1140+ self.items[path] = item
1141+ return item
1142+
1143+ def update_sizes(self):
1144+ """Poll the queue were the threads put the size info."""
1145+ try:
1146+ path, size = self.queue.get(False)
1147+ item = self.items.get(path)
1148+ if item:
1149+ item.size = size
1150+ item.setText(1, humanize(size))
1151+ except Queue.Empty:
1152+ pass
1153+ total = 0
1154+ for path, item in self.items.items():
1155+ if item.size is None:
1156+ total = LOCAL_FOLDERS_CALCULATING
1157+ break
1158+ total += item.size
1159+
1160+ if isinstance(total, long):
1161+ self.show_hide_offer(total)
1162+ total = humanize(total)
1163+ else:
1164+ self.show_hide_offer(0)
1165+ self.ui.folder_list.headerItem().setText(
1166+ 1, LOCAL_FOLDERS_SPACE_HEADER % total)
1167+
1168+ def show_hide_offer(self, cur_size):
1169+ """Show or hide the offer to buy space according to the total size."""
1170+ quota = self.quota()
1171+
1172+ if cur_size > quota:
1173+ self.ui.offer_frame.setVisible(True)
1174+ else:
1175+ self.ui.offer_frame.setVisible(False)
1176+
1177+ self.ui.offer_label.setText(LOCAL_FOLDERS_OFFER_LABEL %
1178+ {"quota": humanize(quota)})
1179+
1180+ def stop_threads(self):
1181+ """Stop all pending threads."""
1182+ for _, item in self.items:
1183+ item.thread._stop = True
1184+
1185+ # itemClicked is a Qt signal name.
1186+ # pylint: disable=C0103
1187+ def on_folder_list_itemClicked(self, item, column):
1188+ """Delete folder from the list."""
1189+ if column == 2:
1190+ del(self.items[item.path])
1191+ item.thread._stop = True
1192+ self.ui.folder_list.takeTopLevelItem(
1193+ self.ui.folder_list.indexOfTopLevelItem(item))
1194+ self.update_sizes()
1195
1196=== modified file 'ubuntuone_installer/gui/qt/main/windows.py'
1197--- ubuntuone_installer/gui/qt/main/windows.py 2011-06-30 17:53:23 +0000
1198+++ ubuntuone_installer/gui/qt/main/windows.py 2011-07-19 02:28:34 +0000
1199@@ -1,48 +1,62 @@
1200-# -*- coding: utf-8 -*-
1201-
1202-# Authors: Manuel de la Pena <manuel@canonical.com>
1203-#
1204-# Copyright 2011 Canonical Ltd.
1205-#
1206-# This program is free software: you can redistribute it and/or modify it
1207-# under the terms of the GNU General Public License version 3, as published
1208-# by the Free Software Foundation.
1209-#
1210-# This program is distributed in the hope that it will be useful, but
1211-# WITHOUT ANY WARRANTY; without even the implied warranties of
1212-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1213-# PURPOSE. See the GNU General Public License for more details.
1214-#
1215-# You should have received a copy of the GNU General Public License along
1216-# with this program. If not, see <http://www.gnu.org/licenses/>.
1217-"""Reactor installation for windows."""
1218-
1219-import sys
1220-
1221-from PyQt4 import Qt
1222-
1223-# pylint: disable=E1101, F0401, W0404
1224-
1225-
1226-def main():
1227- """Start the txnamedpipes reactor and open the main window."""
1228-
1229- # The following cannot be imported outside this function
1230- # because u1trial already provides a reactor.
1231- # pylint: disable=W0404, F0401
1232-
1233- app = Qt.QApplication(sys.argv)
1234- import qtreactor.qt4reactor
1235- qtreactor.qt4reactor.install()
1236-
1237- from ubuntuone_installer.gui.qt.gui import MainWindow
1238- from twisted.internet import reactor
1239-
1240- def really_quit():
1241- """Close the application and cleanup."""
1242- reactor.stop()
1243-
1244- window = MainWindow(close_callback=really_quit)
1245- app.window = window
1246- window.show()
1247- reactor.run()
1248+# -*- coding: utf-8 -*-
1249+
1250+# Authors: Manuel de la Pena <manuel@canonical.com>
1251+#
1252+# Copyright 2011 Canonical Ltd.
1253+#
1254+# This program is free software: you can redistribute it and/or modify it
1255+# under the terms of the GNU General Public License version 3, as published
1256+# by the Free Software Foundation.
1257+#
1258+# This program is distributed in the hope that it will be useful, but
1259+# WITHOUT ANY WARRANTY; without even the implied warranties of
1260+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1261+# PURPOSE. See the GNU General Public License for more details.
1262+#
1263+# You should have received a copy of the GNU General Public License along
1264+# with this program. If not, see <http://www.gnu.org/licenses/>.
1265+"""Reactor installation for windows."""
1266+
1267+import sys
1268+
1269+from PyQt4 import Qt, QtCore, QtGui
1270+
1271+# Module used ti include the resources into this file
1272+# pylint: disable=W0611
1273+from ubuntuone_installer.gui.qt.ui import images_rc
1274+# pylint: enable=W0611
1275+
1276+# pylint: disable=E1101, F0401, W0404
1277+
1278+
1279+def main():
1280+ """Start the txnamedpipes reactor and open the main window."""
1281+
1282+ # The following cannot be imported outside this function
1283+ # because u1trial already provides a reactor.
1284+ # pylint: disable=W0404, F0401
1285+
1286+ app = Qt.QApplication(sys.argv)
1287+ # Apply Style Sheet
1288+ qss_file = QtCore.QFile(":/ubuntuone.qss")
1289+ qss_file.open(QtCore.QFile.ReadOnly)
1290+ stylesheet = QtCore.QLatin1String(qss_file.readAll())
1291+ app.setStyleSheet(stylesheet)
1292+ # Apply font to the entire application
1293+ QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-R.ttf')
1294+
1295+ import qtreactor.qt4reactor
1296+ qtreactor.qt4reactor.install()
1297+
1298+ from ubuntuone_installer.gui.qt.gui import MainWindow
1299+ from twisted.internet import reactor
1300+
1301+ def really_quit():
1302+ """Close the application and cleanup."""
1303+ reactor.stop()
1304+
1305+ window = MainWindow(close_callback=really_quit)
1306+ app.window = window
1307+ app.setWindowIcon(QtGui.QIcon(":/u1icon.png"))
1308+ window.show()
1309+ reactor.run()
1310
1311=== modified file 'ubuntuone_installer/gui/qt/setup_account.py'
1312--- ubuntuone_installer/gui/qt/setup_account.py 2011-07-07 20:32:17 +0000
1313+++ ubuntuone_installer/gui/qt/setup_account.py 2011-07-19 02:28:34 +0000
1314@@ -1,156 +1,158 @@
1315-# -*- coding: utf-8 -*-
1316-
1317-# Authors: Roberto Alsina <roberto.alsina@canonical.com>
1318-#
1319-# Copyright 2011 Canonical Ltd.
1320-#
1321-# This program is free software: you can redistribute it and/or modify it
1322-# under the terms of the GNU General Public License version 3, as published
1323-# by the Free Software Foundation.
1324-#
1325-# This program is distributed in the hope that it will be useful, but
1326-# WITHOUT ANY WARRANTY; without even the implied warranties of
1327-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1328-# PURPOSE. See the GNU General Public License for more details.
1329-#
1330-# You should have received a copy of the GNU General Public License along
1331-# with this program. If not, see <http://www.gnu.org/licenses/>.
1332-
1333-"""Customized Setup Account page for SSO."""
1334-
1335-import gettext
1336-import re
1337-
1338-from PyQt4 import QtGui
1339-
1340-from ubuntu_sso.qt import gui as sso_gui
1341-
1342-_ = gettext.gettext
1343-
1344-# pylint: disable=C0103
1345-BAD = u'<font color="red"> %s </font>'
1346-GOOD = u'<font color="green"> %s </font>'
1347-
1348-EMPTY_NAME = _("Please enter your name")
1349-INVALID_EMAIL = _("Please enter a valid email address")
1350-EMAIL_MATCH = _("The email addresses do not match")
1351-PASSWORD_LENGTH = _("At least 8 characters")
1352-PASSWORD_DIGIT = _("At least one number")
1353-PASSWORD_UPPER = _("At least one uppercase letter")
1354-PASSWORD_MATCH = _("Passwords don't match")
1355-
1356-
1357-class SetupAccountPage(sso_gui.SetupAccountPage):
1358-
1359- """Customized Setup Account page for SSO"""
1360-
1361- def initializePage(self):
1362- """Setup UI details."""
1363- # We need to override some texts from SSO
1364- # to match our spec
1365- self.setTitle(_("Sign Up to Ubuntu One"))
1366- self.setSubTitle(_("You only need to set up your account "
1367- "once to get access to Ubuntu One across your devices."))
1368-
1369- self.ui.name_label.setText(_("Name"))
1370- self.ui.email_label.setText(_("Email"))
1371- self.ui.confirm_email_label.setText(_("Retype email"))
1372- self.ui.password_label.setText(_("Create a password"))
1373- self.ui.confirm_password_label.setText(_("Retype password"))
1374- self.ui.terms_checkbox.setText(
1375- _("By signing up to Ubuntu One you agree to our Terms "
1376- "of Service and Privacy Policy"))
1377- self.ui.terms_button.setText(_("Show Terms of Service"))
1378- self.ui.password_info_label.hide()
1379-
1380- # Button setup
1381- self.wizard().setButtonLayout([
1382- QtGui.QWizard.Stretch,
1383- QtGui.QWizard.BackButton,
1384- QtGui.QWizard.CancelButton,
1385- ])
1386-
1387- self.ui.name_edit.textEdited.connect(self.name_assistance)
1388- self.name_assistance()
1389- self.ui.email_edit.textEdited.connect(self.email_assistance)
1390- self.ui.email_edit.textEdited.connect(self.confirm_email_assistance)
1391- self.email_assistance()
1392- self.ui.confirm_email_edit.textEdited.connect(
1393- self.confirm_email_assistance)
1394- self.confirm_email_assistance()
1395- self.ui.password_edit.textEdited.connect(self.password_assistance)
1396- self.ui.confirm_password_edit.textEdited.connect(
1397- self.password_assistance)
1398- self.password_assistance()
1399-
1400- def name_assistance(self):
1401- """Show help for the name field."""
1402- text = unicode(self.ui.name_edit.text())
1403- if not text.strip():
1404- self.ui.name_assistance.setVisible(True)
1405- self.ui.name_assistance.setText(BAD % EMPTY_NAME)
1406- else:
1407- self.ui.name_assistance.setVisible(False)
1408-
1409- def email_assistance(self):
1410- """Show help for the email field."""
1411- text = unicode(self.ui.email_edit.text())
1412- if not is_correct_email(text):
1413- self.ui.email_assistance.setText(BAD % INVALID_EMAIL)
1414- self.ui.email_assistance.setVisible(True)
1415- else:
1416- self.ui.email_assistance.setVisible(False)
1417-
1418- def confirm_email_assistance(self):
1419- """Show help for the confirm email field."""
1420- text1 = unicode(self.ui.email_edit.text())
1421- text2 = unicode(self.ui.confirm_email_edit.text())
1422- if text1 != text2:
1423- self.ui.confirm_email_assistance.setText(BAD % EMAIL_MATCH)
1424- self.ui.confirm_email_assistance.setVisible(True)
1425- else:
1426- self.ui.confirm_email_assistance.setVisible(False)
1427-
1428- def password_assistance(self):
1429- """Show help for the password field."""
1430- text1 = unicode(self.ui.password_edit.text())
1431- text2 = unicode(self.ui.confirm_password_edit.text())
1432- label_text = [_("Your password must contain"), ]
1433-
1434- if len(text1) < 8:
1435- sign = BAD
1436- else:
1437- sign = GOOD
1438- label_text.append(sign % PASSWORD_LENGTH)
1439-
1440- if re.search('[A-Z]', text1) is None:
1441- sign = BAD
1442- else:
1443- sign = GOOD
1444- label_text.append(sign % PASSWORD_UPPER)
1445-
1446- if re.search('[\d+]', text1) is None:
1447- sign = BAD
1448- else:
1449- sign = GOOD
1450- label_text.append(sign % PASSWORD_DIGIT)
1451-
1452- if text1 != text2:
1453- label_text.append(BAD % PASSWORD_MATCH)
1454-
1455- self.ui.password_assistance.setText("<br>".join(label_text))
1456-
1457-
1458-def is_min_required_password(password):
1459- """Return if the password meets the minimum requirements."""
1460- if (len(password) < 8 or
1461- re.search('[A-Z]', password) is None or
1462- re.search('\d+', password) is None):
1463- return False
1464- return True
1465-
1466-
1467-# FIXME: this should do the same check as SSO's server side
1468-def is_correct_email(email_address):
1469- """Return if the email is correct."""
1470- return '@' in email_address
1471+# -*- coding: utf-8 -*-
1472+
1473+# Authors: Roberto Alsina <roberto.alsina@canonical.com>
1474+#
1475+# Copyright 2011 Canonical Ltd.
1476+#
1477+# This program is free software: you can redistribute it and/or modify it
1478+# under the terms of the GNU General Public License version 3, as published
1479+# by the Free Software Foundation.
1480+#
1481+# This program is distributed in the hope that it will be useful, but
1482+# WITHOUT ANY WARRANTY; without even the implied warranties of
1483+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1484+# PURPOSE. See the GNU General Public License for more details.
1485+#
1486+# You should have received a copy of the GNU General Public License along
1487+# with this program. If not, see <http://www.gnu.org/licenses/>.
1488+
1489+"""Customized Setup Account page for SSO."""
1490+
1491+import gettext
1492+import re
1493+
1494+from PyQt4 import QtGui
1495+
1496+from ubuntu_sso.qt import gui as sso_gui
1497+
1498+_ = gettext.gettext
1499+
1500+# pylint: disable=C0103
1501+BAD = u'<img src=":/password_hint_warning.png" /><font color="red"> %s </font>'
1502+GOOD = u'<img src=":/password_hint_ok.png" /><font color="green"> %s </font>'
1503+TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
1504+
1505+EMPTY_NAME = _("Please enter your name")
1506+INVALID_EMAIL = _("Please enter a valid email address")
1507+EMAIL_MATCH = _("The email addresses do not match")
1508+PASSWORD_LENGTH = _("At least 8 characters")
1509+PASSWORD_DIGIT = _("At least one number")
1510+PASSWORD_UPPER = _("At least one uppercase letter")
1511+PASSWORD_MATCH = _("Passwords don't match")
1512+
1513+
1514+class SetupAccountPage(sso_gui.SetupAccountPage):
1515+
1516+ """Customized Setup Account page for SSO"""
1517+
1518+ def initializePage(self):
1519+ """Setup UI details."""
1520+ # We need to override some texts from SSO
1521+ # to match our spec
1522+ title_page = TITLE_STYLE % _("Sign Up to Ubuntu One")
1523+ self.setTitle(title_page)
1524+ self.setSubTitle(_("You only need to set up your account "
1525+ "once to get access to Ubuntu One across your devices."))
1526+
1527+ self.ui.name_label.setText(_("Name"))
1528+ self.ui.email_label.setText(_("Email"))
1529+ self.ui.confirm_email_label.setText(_("Retype email"))
1530+ self.ui.password_label.setText(_("Create a password"))
1531+ self.ui.confirm_password_label.setText(_("Retype password"))
1532+ self.ui.terms_checkbox.setText(
1533+ _("By signing up to Ubuntu One you agree to our Terms "
1534+ "of Service and Privacy Policy"))
1535+ self.ui.terms_button.setText(_("Show Terms of Service"))
1536+ self.ui.password_info_label.hide()
1537+
1538+ # Button setup
1539+ self.wizard().setButtonLayout([
1540+ QtGui.QWizard.Stretch,
1541+ QtGui.QWizard.BackButton,
1542+ QtGui.QWizard.CancelButton,
1543+ ])
1544+
1545+ self.ui.name_edit.textEdited.connect(self.name_assistance)
1546+ self.name_assistance()
1547+ self.ui.email_edit.textEdited.connect(self.email_assistance)
1548+ self.ui.email_edit.textEdited.connect(self.confirm_email_assistance)
1549+ self.email_assistance()
1550+ self.ui.confirm_email_edit.textEdited.connect(
1551+ self.confirm_email_assistance)
1552+ self.confirm_email_assistance()
1553+ self.ui.password_edit.textEdited.connect(self.password_assistance)
1554+ self.ui.confirm_password_edit.textEdited.connect(
1555+ self.password_assistance)
1556+ self.password_assistance()
1557+
1558+ def name_assistance(self):
1559+ """Show help for the name field."""
1560+ text = unicode(self.ui.name_edit.text())
1561+ if not text.strip():
1562+ self.ui.name_assistance.setVisible(True)
1563+ self.ui.name_assistance.setText(BAD % EMPTY_NAME)
1564+ else:
1565+ self.ui.name_assistance.setVisible(False)
1566+
1567+ def email_assistance(self):
1568+ """Show help for the email field."""
1569+ text = unicode(self.ui.email_edit.text())
1570+ if not is_correct_email(text):
1571+ self.ui.email_assistance.setText(BAD % INVALID_EMAIL)
1572+ self.ui.email_assistance.setVisible(True)
1573+ else:
1574+ self.ui.email_assistance.setVisible(False)
1575+
1576+ def confirm_email_assistance(self):
1577+ """Show help for the confirm email field."""
1578+ text1 = unicode(self.ui.email_edit.text())
1579+ text2 = unicode(self.ui.confirm_email_edit.text())
1580+ if text1 != text2:
1581+ self.ui.confirm_email_assistance.setText(BAD % EMAIL_MATCH)
1582+ self.ui.confirm_email_assistance.setVisible(True)
1583+ else:
1584+ self.ui.confirm_email_assistance.setVisible(False)
1585+
1586+ def password_assistance(self):
1587+ """Show help for the password field."""
1588+ text1 = unicode(self.ui.password_edit.text())
1589+ text2 = unicode(self.ui.confirm_password_edit.text())
1590+ label_text = ["<b>%s</b>" % _("Your password must contain"), ]
1591+
1592+ if len(text1) < 8:
1593+ sign = BAD
1594+ else:
1595+ sign = GOOD
1596+ label_text.append(sign % PASSWORD_LENGTH)
1597+
1598+ if re.search('[A-Z]', text1) is None:
1599+ sign = BAD
1600+ else:
1601+ sign = GOOD
1602+ label_text.append(sign % PASSWORD_UPPER)
1603+
1604+ if re.search('[\d+]', text1) is None:
1605+ sign = BAD
1606+ else:
1607+ sign = GOOD
1608+ label_text.append(sign % PASSWORD_DIGIT)
1609+
1610+ if text1 != text2:
1611+ label_text.append(BAD % PASSWORD_MATCH)
1612+
1613+ self.ui.password_assistance.setText("<br>".join(label_text))
1614+
1615+
1616+def is_min_required_password(password):
1617+ """Return if the password meets the minimum requirements."""
1618+ if (len(password) < 8 or
1619+ re.search('[A-Z]', password) is None or
1620+ re.search('\d+', password) is None):
1621+ return False
1622+ return True
1623+
1624+
1625+# FIXME: this should do the same check as SSO's server side
1626+def is_correct_email(email_address):
1627+ """Return if the email is correct."""
1628+ return '@' in email_address
1629
1630=== modified file 'ubuntuone_installer/gui/qt/side_widget.py'
1631--- ubuntuone_installer/gui/qt/side_widget.py 2011-07-04 18:15:56 +0000
1632+++ ubuntuone_installer/gui/qt/side_widget.py 2011-07-19 02:28:34 +0000
1633@@ -1,49 +1,73 @@
1634-# -*- coding: utf-8 -*-
1635-
1636-# Authors: Roberto Alsina <roberto.alsina@canonical.com>
1637-#
1638-# Copyright 2011 Canonical Ltd.
1639-#
1640-# This program is free software: you can redistribute it and/or modify it
1641-# under the terms of the GNU General Public License version 3, as published
1642-# by the Free Software Foundation.
1643-#
1644-# This program is distributed in the hope that it will be useful, but
1645-# WITHOUT ANY WARRANTY; without even the implied warranties of
1646-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1647-# PURPOSE. See the GNU General Public License for more details.
1648-#
1649-# You should have received a copy of the GNU General Public License along
1650-# with this program. If not, see <http://www.gnu.org/licenses/>.
1651-
1652-"""Wizard's side widget."""
1653-
1654-from PyQt4 import QtGui
1655-
1656-from ubuntuone_installer.gui.qt.ui import side_widget_ui
1657-
1658-
1659-class SideWidget(QtGui.QWidget):
1660-
1661- """Wizard's side widget."""
1662-
1663- install_stage = 0
1664- signin_stage = 1
1665- choose_services_stage = 2
1666- select_sync_folders_stage = 3
1667- sync_stage = 4
1668-
1669- def __init__(self, *args, **kwargs):
1670- super(SideWidget, self).__init__(*args, **kwargs)
1671- self.ui = side_widget_ui.Ui_Form()
1672- self.ui.setupUi(self)
1673- self.stage = 0
1674-
1675- def set_stage(self, stage):
1676- """Switch to the desired stage."""
1677- self.stage = stage
1678- self.ui.install_label.setEnabled(stage >= 0)
1679- self.ui.sign_in_label.setEnabled(stage >= 1)
1680- self.ui.choose_services_label.setEnabled(stage >= 2)
1681- self.ui.select_folders_label.setEnabled(stage >= 3)
1682- self.ui.sync_label.setEnabled(stage >= 4)
1683+# -*- coding: utf-8 -*-
1684+
1685+# Authors: Roberto Alsina <roberto.alsina@canonical.com>
1686+#
1687+# Copyright 2011 Canonical Ltd.
1688+#
1689+# This program is free software: you can redistribute it and/or modify it
1690+# under the terms of the GNU General Public License version 3, as published
1691+# by the Free Software Foundation.
1692+#
1693+# This program is distributed in the hope that it will be useful, but
1694+# WITHOUT ANY WARRANTY; without even the implied warranties of
1695+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1696+# PURPOSE. See the GNU General Public License for more details.
1697+#
1698+# You should have received a copy of the GNU General Public License along
1699+# with this program. If not, see <http://www.gnu.org/licenses/>.
1700+
1701+"""Wizard's side widget."""
1702+
1703+from PyQt4 import QtGui
1704+
1705+from ubuntuone_installer.gui.qt.ui import side_widget_ui
1706+# Module used ti include the resources into this file
1707+# pylint: disable=W0611
1708+from ubuntuone_installer.gui.qt.ui import images_rc
1709+# pylint: enable=W0611
1710+
1711+
1712+class SideWidget(QtGui.QFrame):
1713+
1714+ """Wizard's side widget."""
1715+
1716+ install_stage = 0
1717+ signin_stage = 1
1718+ choose_services_stage = 2
1719+ select_sync_folders_stage = 3
1720+ sync_stage = 4
1721+
1722+ def __init__(self, *args, **kwargs):
1723+ super(SideWidget, self).__init__(*args, **kwargs)
1724+ self.ui = side_widget_ui.Ui_SideWidget()
1725+ self.ui.setupUi(self)
1726+ self.stage = 0
1727+
1728+ def set_stage(self, stage):
1729+ """Switch to the desired stage."""
1730+ self.stage = stage
1731+ self.ui.install_label.setEnabled(stage >= 0)
1732+ self.ui.sign_in_label.setEnabled(stage >= 1)
1733+ self.ui.choose_services_label.setEnabled(stage >= 2)
1734+ self.ui.select_folders_label.setEnabled(stage >= 3)
1735+ self.ui.sync_label.setEnabled(stage >= 4)
1736+ self.set_stage_icon(self.ui.install_icon_label, self.install_stage)
1737+ self.set_stage_icon(self.ui.sign_icon_label, self.signin_stage)
1738+ self.set_stage_icon(self.ui.choose_icon_label,
1739+ self.choose_services_stage)
1740+ self.set_stage_icon(self.ui.folders_icon_label,
1741+ self.select_sync_folders_stage)
1742+ self.set_stage_icon(self.ui.sync_icon_label, self.sync_stage)
1743+
1744+ def set_stage_icon(self, label, label_stage):
1745+ """Set the label icon depending on the proper state."""
1746+ if self.stage == label_stage and label == self.ui.sync_icon_label:
1747+ label.setPixmap(QtGui.QPixmap(":/progress_finish_orange.png"))
1748+ elif self.stage == label_stage:
1749+ label.setPixmap(QtGui.QPixmap(":/progress_arrow_orange.png"))
1750+ elif self.stage > label_stage:
1751+ label.setPixmap(QtGui.QPixmap(":/progress_tick.png"))
1752+ elif label == self.ui.sync_icon_label:
1753+ label.setPixmap(QtGui.QPixmap(":/progress_finish_grey.png"))
1754+ else:
1755+ label.setPixmap(QtGui.QPixmap(":/progress_arrow_grey.png"))
1756
1757=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
1758--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-07-15 18:47:24 +0000
1759+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-07-19 02:28:34 +0000
1760@@ -125,6 +125,10 @@
1761 self.ui.done(result=0)
1762 # world did not explode
1763
1764+ def test_main_window_general_config(self):
1765+ """Check if the main properties of the windows are set."""
1766+ self.assertEqual(self.ui.windowTitle(), APP_NAME)
1767+
1768 def test_start_control_panel_on_finishing(self):
1769 """Calling done with result=1, the control panel should be called."""
1770 gui.AreYouSure.result = 0
1771@@ -208,7 +212,7 @@
1772 def test_current_user_controller_parameters(self):
1773 """Compare controller parameters with expected values."""
1774 self.assertEqual(self.ui.current_user_controller.args,
1775- ((), {'title': gui.SIGN_IN,
1776+ ((), {'title': gui.TITLE_STYLE % gui.SIGN_IN,
1777 'subtitle': gui.SIGN_IN_SUBTITLE}))
1778
1779 def test_stage_progression_1(self):
1780@@ -623,3 +627,24 @@
1781 setup_account.BAD % setup_account.PASSWORD_MATCH in
1782 unicode(self.ui.ui.password_assistance.text()),
1783 )
1784+
1785+ def test_side_widget_state(self):
1786+ """Test if the side widget of the wizard has state frame visible."""
1787+ if type(self.ui) != gui.MainWindow:
1788+ return
1789+ self.ui.on_currentIdChanged(self.ui.LICENSE_PAGE)
1790+ self.assertEqual(
1791+ True,
1792+ sideWidget().ui.states_frame.isVisible())
1793+ self.ui.on_currentIdChanged(self.ui.SIGNIN_PAGE)
1794+ self.assertEqual(
1795+ True,
1796+ sideWidget().ui.states_frame.isVisible())
1797+ self.ui.on_currentIdChanged(self.ui.local_folders_page_id)
1798+ self.assertEqual(
1799+ True,
1800+ sideWidget().ui.states_frame.isVisible())
1801+ self.ui.on_currentIdChanged(self.ui.CONGRATULATIONS_PAGE)
1802+ self.assertEqual(
1803+ True,
1804+ sideWidget().ui.states_frame.isVisible())
1805
1806=== modified file 'ubuntuone_installer/gui/qt/tests/test_side_widget.py'
1807--- ubuntuone_installer/gui/qt/tests/test_side_widget.py 2011-07-07 13:08:24 +0000
1808+++ ubuntuone_installer/gui/qt/tests/test_side_widget.py 2011-07-19 02:28:34 +0000
1809@@ -1,100 +1,155 @@
1810-# -*- coding: utf-8 -*-
1811-
1812-# Authors: Alejandro J. Cura <alecu@canonical.com>
1813-# Roberto Alsina <roberto.alsina@canonical.com>
1814-#
1815-# Copyright 2011 Canonical Ltd.
1816-#
1817-# This program is free software: you can redistribute it and/or modify it
1818-# under the terms of the GNU General Public License version 3, as published
1819-# by the Free Software Foundation.
1820-#
1821-# This program is distributed in the hope that it will be useful, but
1822-# WITHOUT ANY WARRANTY; without even the implied warranties of
1823-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1824-# PURPOSE. See the GNU General Public License for more details.
1825-#
1826-# You should have received a copy of the GNU General Public License along
1827-# with this program. If not, see <http://www.gnu.org/licenses/>.
1828-
1829-"""Tests for the Qt UI."""
1830-
1831-from ubuntuone_installer.gui.qt.tests import BaseTestCase
1832-from ubuntuone_installer.gui.qt.side_widget import SideWidget
1833-
1834-
1835-class SideWidgetTestCase(BaseTestCase):
1836-
1837- """Test the qt main window."""
1838-
1839- class_ui = SideWidget
1840-
1841- def test_stage_0(self):
1842- """Check that each stage in the widget enables the right labels."""
1843- self.ui.set_stage(0)
1844- self.assertEqual(
1845- self.ui.ui.install_label.isEnabled(), True)
1846- self.assertEqual(
1847- self.ui.ui.sign_in_label.isEnabled(), False)
1848- self.assertEqual(
1849- self.ui.ui.choose_services_label.isEnabled(), False)
1850- self.assertEqual(
1851- self.ui.ui.select_folders_label.isEnabled(), False)
1852- self.assertEqual(
1853- self.ui.ui.sync_label.isEnabled(), False)
1854-
1855- def test_stage_1(self):
1856- """Check that each stage in the widget enables the right labels."""
1857- self.ui.set_stage(1)
1858- self.assertEqual(
1859- self.ui.ui.install_label.isEnabled(), True)
1860- self.assertEqual(
1861- self.ui.ui.sign_in_label.isEnabled(), True)
1862- self.assertEqual(
1863- self.ui.ui.choose_services_label.isEnabled(), False)
1864- self.assertEqual(
1865- self.ui.ui.select_folders_label.isEnabled(), False)
1866- self.assertEqual(
1867- self.ui.ui.sync_label.isEnabled(), False)
1868-
1869- def test_stage_2(self):
1870- """Check that each stage in the widget enables the right labels."""
1871- self.ui.set_stage(2)
1872- self.assertEqual(
1873- self.ui.ui.install_label.isEnabled(), True)
1874- self.assertEqual(
1875- self.ui.ui.sign_in_label.isEnabled(), True)
1876- self.assertEqual(
1877- self.ui.ui.choose_services_label.isEnabled(), True)
1878- self.assertEqual(
1879- self.ui.ui.select_folders_label.isEnabled(), False)
1880- self.assertEqual(
1881- self.ui.ui.sync_label.isEnabled(), False)
1882-
1883- def test_stage_3(self):
1884- """Check that each stage in the widget enables the right labels."""
1885- self.ui.set_stage(3)
1886- self.assertEqual(
1887- self.ui.ui.install_label.isEnabled(), True)
1888- self.assertEqual(
1889- self.ui.ui.sign_in_label.isEnabled(), True)
1890- self.assertEqual(
1891- self.ui.ui.choose_services_label.isEnabled(), True)
1892- self.assertEqual(
1893- self.ui.ui.select_folders_label.isEnabled(), True)
1894- self.assertEqual(
1895- self.ui.ui.sync_label.isEnabled(), False)
1896-
1897- def test_stage_4(self):
1898- """Check that each stage in the widget enables the right labels."""
1899- self.ui.set_stage(4)
1900- self.assertEqual(
1901- self.ui.ui.install_label.isEnabled(), True)
1902- self.assertEqual(
1903- self.ui.ui.sign_in_label.isEnabled(), True)
1904- self.assertEqual(
1905- self.ui.ui.choose_services_label.isEnabled(), True)
1906- self.assertEqual(
1907- self.ui.ui.select_folders_label.isEnabled(), True)
1908- self.assertEqual(
1909- self.ui.ui.sync_label.isEnabled(), True)
1910+# -*- coding: utf-8 -*-
1911+
1912+# Authors: Alejandro J. Cura <alecu@canonical.com>
1913+# Roberto Alsina <roberto.alsina@canonical.com>
1914+#
1915+# Copyright 2011 Canonical Ltd.
1916+#
1917+# This program is free software: you can redistribute it and/or modify it
1918+# under the terms of the GNU General Public License version 3, as published
1919+# by the Free Software Foundation.
1920+#
1921+# This program is distributed in the hope that it will be useful, but
1922+# WITHOUT ANY WARRANTY; without even the implied warranties of
1923+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1924+# PURPOSE. See the GNU General Public License for more details.
1925+#
1926+# You should have received a copy of the GNU General Public License along
1927+# with this program. If not, see <http://www.gnu.org/licenses/>.
1928+
1929+"""Tests for the Qt UI."""
1930+
1931+from PyQt4 import QtGui, QtCore
1932+
1933+from ubuntuone_installer.gui.qt.tests import BaseTestCase
1934+from ubuntuone_installer.gui.qt.side_widget import SideWidget
1935+# Module used ti include the resources into this file
1936+# pylint: disable=W0611
1937+from ubuntuone_installer.gui.qt.ui import images_rc
1938+# pylint: enable=W0611
1939+
1940+
1941+class SideWidgetTestCase(BaseTestCase):
1942+
1943+ """Test the qt main window."""
1944+
1945+ class_ui = SideWidget
1946+
1947+ def test_stage_0(self):
1948+ """Check that each stage in the widget enables the right labels."""
1949+ self.ui.set_stage(0)
1950+ self.assertEqual(
1951+ self.ui.ui.install_label.isEnabled(), True)
1952+ self.assertEqual(
1953+ self.ui.ui.sign_in_label.isEnabled(), False)
1954+ self.assertEqual(
1955+ self.ui.ui.choose_services_label.isEnabled(), False)
1956+ self.assertEqual(
1957+ self.ui.ui.select_folders_label.isEnabled(), False)
1958+ self.assertEqual(
1959+ self.ui.ui.sync_label.isEnabled(), False)
1960+ self.check_state_pixmap(0)
1961+
1962+ def test_stage_1(self):
1963+ """Check that each stage in the widget enables the right labels."""
1964+ self.ui.set_stage(1)
1965+ self.assertEqual(
1966+ self.ui.ui.install_label.isEnabled(), True)
1967+ self.assertEqual(
1968+ self.ui.ui.sign_in_label.isEnabled(), True)
1969+ self.assertEqual(
1970+ self.ui.ui.choose_services_label.isEnabled(), False)
1971+ self.assertEqual(
1972+ self.ui.ui.select_folders_label.isEnabled(), False)
1973+ self.assertEqual(
1974+ self.ui.ui.sync_label.isEnabled(), False)
1975+ self.check_state_pixmap(1)
1976+
1977+ def test_stage_2(self):
1978+ """Check that each stage in the widget enables the right labels."""
1979+ self.ui.set_stage(2)
1980+ self.assertEqual(
1981+ self.ui.ui.install_label.isEnabled(), True)
1982+ self.assertEqual(
1983+ self.ui.ui.sign_in_label.isEnabled(), True)
1984+ self.assertEqual(
1985+ self.ui.ui.choose_services_label.isEnabled(), True)
1986+ self.assertEqual(
1987+ self.ui.ui.select_folders_label.isEnabled(), False)
1988+ self.assertEqual(
1989+ self.ui.ui.sync_label.isEnabled(), False)
1990+ self.check_state_pixmap(2)
1991+
1992+ def test_stage_3(self):
1993+ """Check that each stage in the widget enables the right labels."""
1994+ self.ui.set_stage(3)
1995+ self.assertEqual(
1996+ self.ui.ui.install_label.isEnabled(), True)
1997+ self.assertEqual(
1998+ self.ui.ui.sign_in_label.isEnabled(), True)
1999+ self.assertEqual(
2000+ self.ui.ui.choose_services_label.isEnabled(), True)
2001+ self.assertEqual(
2002+ self.ui.ui.select_folders_label.isEnabled(), True)
2003+ self.assertEqual(
2004+ self.ui.ui.sync_label.isEnabled(), False)
2005+ self.check_state_pixmap(3)
2006+
2007+ def test_stage_4(self):
2008+ """Check that each stage in the widget enables the right labels."""
2009+ self.ui.set_stage(4)
2010+ self.assertEqual(
2011+ self.ui.ui.install_label.isEnabled(), True)
2012+ self.assertEqual(
2013+ self.ui.ui.sign_in_label.isEnabled(), True)
2014+ self.assertEqual(
2015+ self.ui.ui.choose_services_label.isEnabled(), True)
2016+ self.assertEqual(
2017+ self.ui.ui.select_folders_label.isEnabled(), True)
2018+ self.assertEqual(
2019+ self.ui.ui.sync_label.isEnabled(), True)
2020+ self.check_state_pixmap(4)
2021+
2022+ def get_pixmap_data(self, pixmap):
2023+ """Get the raw data of a QPixmap."""
2024+ byte_array = QtCore.QByteArray()
2025+ array_buffer = QtCore.QBuffer(byte_array)
2026+ pixmap.save(array_buffer, "PNG")
2027+ return byte_array
2028+
2029+ # Invalid name "assertEqualPixmap"
2030+ # pylint: disable=C0103
2031+
2032+ def assertEqualPixmaps(self, pixmap1, pixmap2):
2033+ """Compare two Qt pixmaps."""
2034+ d1 = self.get_pixmap_data(pixmap1)
2035+ d2 = self.get_pixmap_data(pixmap2)
2036+ self.assertEqual(d1, d2)
2037+
2038+ def check_state_pixmap(self, stage):
2039+ """Check if each label has the proper pixmap depending on the state."""
2040+ print stage
2041+ active_pixmap = QtGui.QPixmap(":/progress_arrow_orange.png")
2042+ no_active_pixmap = QtGui.QPixmap(":/progress_arrow_grey.png")
2043+ complete_pixmap = QtGui.QPixmap(":/progress_tick.png")
2044+ sync_active_pixmap = QtGui.QPixmap(":/progress_finish_orange.png")
2045+ sync_no_active_pixmap = QtGui.QPixmap(":/progress_finish_grey.png")
2046+ labels = (
2047+ self.ui.ui.install_icon_label,
2048+ self.ui.ui.sign_icon_label,
2049+ self.ui.ui.choose_icon_label,
2050+ self.ui.ui.folders_icon_label,
2051+ self.ui.ui.sync_icon_label)
2052+
2053+ for item in labels[:stage]:
2054+ self.assertEqualPixmaps(complete_pixmap, item.pixmap())
2055+
2056+ if stage != 4:
2057+ self.assertEqualPixmaps(active_pixmap, labels[stage].pixmap())
2058+ else:
2059+ self.assertEqualPixmaps(sync_active_pixmap, labels[4].pixmap())
2060+
2061+ if stage < 4:
2062+ for item in labels[stage + 1:len(labels) - 1]:
2063+ self.assertEqualPixmaps(no_active_pixmap, item.pixmap())
2064+ self.assertEqualPixmaps(sync_no_active_pixmap, labels[4].pixmap())

Subscribers

People subscribed via source and target branches