Merge lp:~dobey/ubuntuone-installer/install-pages into lp:ubuntuone-installer

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 5
Merged at revision: 6
Proposed branch: lp:~dobey/ubuntuone-installer/install-pages
Merge into: lp:ubuntuone-installer
Diff against target: 299 lines (+210/-37)
2 files modified
ubuntuone/installer/gui.py (+194/-29)
ubuntuone/installer/tests/test_gui.py (+16/-8)
To merge this branch: bzr merge lp:~dobey/ubuntuone-installer/install-pages
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+70346@code.launchpad.net

Commit message

Add the header image, and infrastructure for installing the Ubuntu One packages
Handle doing all the install work and updating the progress bar
Launch the control panel when installation is finished

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) wrote :

Looks good

review: Approve
Revision history for this message
Roberto Alsina (ralsina) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'data'
2=== added file 'data/header.png'
3Binary files data/header.png 1970-01-01 00:00:00 +0000 and data/header.png 2011-08-03 18:07:09 +0000 differ
4=== modified file 'ubuntuone/installer/gui.py'
5--- ubuntuone/installer/gui.py 2011-07-29 14:31:29 +0000
6+++ ubuntuone/installer/gui.py 2011-08-03 18:07:09 +0000
7@@ -15,51 +15,216 @@
8 # with this program. If not, see <http://www.gnu.org/licenses/>.
9 """The GUI of the Ubuntu One Installer."""
10
11-from gi.repository import Gtk
12-
13-
14-class Window(Gtk.Dialog):
15+import aptdaemon.gtk3widgets as aptgtk
16+import aptdaemon.client as aptclient
17+import os
18+
19+from gi.repository import Gtk, GObject, GLib, Gdk
20+
21+# Some shenanigans to deal with pyflakes complaining
22+inline_callbacks = None
23+try:
24+ from defer import inline_callbacks
25+except ImportError:
26+ from aptdaemon.defer import inline_callbacks as old_callbacks
27+
28+if inline_callbacks is None:
29+ inline_callbacks = old_callbacks
30+
31+
32+class Window(Gtk.Window):
33 """The main dialog to use."""
34
35+ __gsignals__ = {'response': (GObject.SIGNAL_RUN_LAST,
36+ GObject.TYPE_NONE,
37+ (GObject.TYPE_INT,)),
38+ }
39+
40 def __init__(self):
41- Gtk.Dialog.__init__(self)
42+ Gtk.Window.__init__(self)
43 self.set_title('Ubuntu One')
44- self.set_default_size(800, 480)
45- self.notebook = Gtk.Notebook()
46- self.notebook.set_show_tabs(False)
47- self.notebook.set_show_border(False)
48- self.notebook.set_scrollable(False)
49- self.notebook.popup_disable()
50-
51- self.get_content_area().add(self.notebook)
52- self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
53- "Install", Gtk.ResponseType.OK)
54-
55- self.set_default_response(Gtk.ResponseType.OK)
56- # No functionality yet.
57- self.get_widget_for_response(Gtk.ResponseType.OK).set_sensitive(False)
58+ self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
59+ self.set_position(Gtk.WindowPosition.CENTER)
60+
61+ vbox = Gtk.VBox()
62+ self.add(vbox)
63+ vbox.show()
64+
65+ self.__header = Gtk.Image()
66+ self.__header.set_size_request(734, 162)
67+ vbox.pack_start(self.__header, False, False, 0)
68+ self.__header.show()
69+
70+ header = self.__find_data_file('header.png')
71+ if header:
72+ self.__header.set_from_file(header)
73+
74+ self.__notebook = Gtk.Notebook()
75+ self.__notebook.set_show_tabs(False)
76+ self.__notebook.set_show_border(False)
77+ self.__notebook.set_scrollable(False)
78+ self.__notebook.popup_disable()
79+ self.__notebook.set_size_request(734, 240)
80+
81+ self.__info_page = self.__construct_info_page()
82+ self.__notebook.append_page(self.__info_page, None)
83+ self.__info_page.show()
84+
85+ # Our progressbar widget
86+ self.__apt_progress = aptgtk.AptProgressBar()
87+
88+ self.__progress_page = self.__construct_progress_page()
89+ self.__notebook.append_page(self.__progress_page, None)
90+ self.__progress_page.show()
91+
92+ vbox.add(self.__notebook)
93+ self.__notebook.show()
94+
95+ self.__action_area = Gtk.HButtonBox()
96+ self.__action_area.set_border_width(12)
97+ self.__action_area.set_spacing(12)
98+ self.__action_area.set_layout(Gtk.ButtonBoxStyle.END)
99+ vbox.pack_end(self.__action_area, False, True, 0)
100+ self.__action_area.show()
101+
102+ self.__cancel_button = Gtk.Button.new_from_stock(Gtk.STOCK_CANCEL)
103+ self.__cancel_button.connect('clicked', lambda x: self.emit(
104+ 'response', Gtk.ResponseType.CANCEL))
105+ self.__action_area.add(self.__cancel_button)
106+ self.__cancel_button.show()
107+
108+ self.__main_button = Gtk.Button.new_with_mnemonic(
109+ 'I_nstall Ubuntu One')
110+ self.__main_button.set_image(Gtk.Image.new_from_stock(
111+ Gtk.STOCK_OK, Gtk.IconSize.BUTTON))
112+ self.__main_button.connect('clicked', lambda x: self.emit(
113+ 'response', Gtk.ResponseType.OK))
114+ self.__action_area.add(self.__main_button)
115+ self.__main_button.grab_focus()
116+ self.__main_button.show()
117
118 self.connect('destroy', self.destroyed)
119- self.connect('response', self.__response)
120- self.notebook.connect('switch-page', self.__page_switched)
121-
122- def __page_switched(self, notebook, page, page_num):
123- """Handle the notebook page changing."""
124-
125- def __response(self, dialog, response):
126+ self.connect('response', self.__got_response)
127+ self.connect('delete-event', lambda x, y: self.emit(
128+ 'response', Gtk.ResponseType.DELETE_EVENT))
129+
130+ self.client = aptclient.AptClient()
131+
132+ def __find_data_file(self, filename):
133+ """Find the full path for the specified data file."""
134+ path = os.path.join(os.getcwd(), 'data', filename)
135+ if os.path.exists(path):
136+ return path
137+
138+ path = os.path.join(os.getcwd(), os.path.pardir, 'data', filename)
139+ if os.path.exists(path):
140+ return os.path.abspath(path)
141+
142+ for folder in GLib.get_system_data_dirs():
143+ path = os.path.join(folder, 'ubuntuone-installer', filename)
144+ if os.path.exists(path):
145+ return path
146+
147+ def __got_response(self, dialog, response):
148 """Handle the dialog response actions."""
149 if response in [Gtk.ResponseType.CANCEL,
150 Gtk.ResponseType.DELETE_EVENT]:
151 self.destroy()
152 Gtk.main_quit()
153 return
154-
155- self.notebook.next_page()
156+ elif response == Gtk.ResponseType.OK:
157+ self.__do_install()
158+
159+ def __construct_info_page(self):
160+ """Build the initial info page."""
161+ page = Gtk.VBox()
162+ page.set_border_width(12)
163+ page.show()
164+
165+ label = Gtk.Label('')
166+ page.add(label)
167+ label.show()
168+
169+ return page
170+
171+ def __construct_progress_page(self):
172+ """Build the install progress page."""
173+ page = Gtk.VBox()
174+ page.set_border_width(12)
175+ page.show()
176+
177+ page.pack_start(self.__apt_progress, True, False, 0)
178+ self.__apt_progress.show()
179+
180+ return page
181+
182+ def __get_series(self):
183+ """Get the series we're running on."""
184+ return 'natty'
185+
186+ def __got_error(self, error):
187+ """Got an error trying to set up Ubuntu One."""
188+ Gtk.main_quit()
189+
190+ @inline_callbacks
191+ def __install_u1(self, *args, **kwargs):
192+ """Install the packages."""
193+ self.__apt_progress.set_fraction(0.0)
194+
195+ def finished(*args, **kwargs):
196+ GLib.spawn_command_line_async('ubuntuone-control-panel-gtk')
197+ Gtk.main_quit()
198+
199+ transaction = yield self.client.install_packages(
200+ package_names=['ubuntuone-control-panel-gtk',
201+ ])
202+ transaction.connect('finished', finished)
203+ self.__apt_progress.set_transaction(transaction)
204+ transaction.run()
205+
206+ @inline_callbacks
207+ def __update_cache(self, *args, **kwargs):
208+ """Update the cache."""
209+ self.__apt_progress.set_fraction(0.0)
210+ transaction = yield self.client.update_cache(
211+ sources_list='ubuntuone-stable-ppa.list')
212+ transaction.connect('finished', self.__install_u1)
213+ self.__apt_progress.set_transaction(transaction)
214+ transaction.run()
215+
216+ @inline_callbacks
217+ def __add_stable_ppa(self):
218+ """Add the Ubuntu One 'stable' PPA to apt."""
219+ transaction = yield self.client.add_repository(
220+ src_type='deb',
221+ uri='http://ppa.launchpad.net/ubuntuone/stable/ubuntu',
222+ dist=self.__get_series(),
223+ comps=['main'],
224+ comment='added by Ubuntu One installer',
225+ sourcesfile='ubuntuone-stable-ppa.list')
226+ transaction.connect('finished', self.__update_cache)
227+ self.__apt_progress.set_transaction(transaction)
228+ transaction.run()
229+
230+ def __do_install(self):
231+ """Do the install."""
232+ # Hide the buttons
233+ self.__cancel_button.hide()
234+ self.__main_button.hide()
235+
236+ # Switch to the progress page
237+ self.__notebook.set_current_page(1)
238+
239+ self.__add_stable_ppa()
240
241 @property
242 def active_page(self):
243 """Get the active page."""
244- return self.notebook.get_current_page()
245+ return self.__notebook.get_current_page()
246+
247+ def response(self, response):
248+ """Emit the response signal with the value response."""
249+ self.emit('response', int(response))
250
251 def run(self):
252 """Show the dialog and do what's necessary."""
253
254=== modified file 'ubuntuone/installer/tests/test_gui.py'
255--- ubuntuone/installer/tests/test_gui.py 2011-07-29 14:31:29 +0000
256+++ ubuntuone/installer/tests/test_gui.py 2011-08-03 18:07:09 +0000
257@@ -15,13 +15,12 @@
258 # with this program. If not, see <http://www.gnu.org/licenses/>.
259 """Tests for the GUI of the Ubuntu One Installer."""
260
261-import unittest
262-
263 from gi.repository import Gtk
264+from ubuntuone.devtools.testcase import DBusTestCase
265 from ubuntuone.installer import gui
266
267
268-class GUITestCase(unittest.TestCase):
269+class GUITestCase(DBusTestCase):
270 """Main class tests."""
271
272 def setUp(self):
273@@ -32,12 +31,21 @@
274 def tearDown(self):
275 self.dlg.destroy()
276
277- def test_response(self):
278+ def test_response_cancel(self):
279 """Test the response callback."""
280- self.dlg.response(Gtk.ResponseType.CLOSE)
281+ self.dlg.response(Gtk.ResponseType.CANCEL)
282
283 def test_page_switched(self):
284 """Test the page switching."""
285- self.assertEquals(self.dlg.active_page, -1)
286- self.dlg.response(Gtk.ResponseType.OK)
287- self.assertEquals(self.dlg.active_page, -1)
288+ #self.assertEquals(self.dlg.active_page, 0)
289+ self.dlg.response(Gtk.ResponseType.OK)
290+ self.assertEquals(self.dlg.active_page, 1)
291+
292+ def test_initial_page(self):
293+ """Test the initial info page."""
294+ self.assertEquals(self.dlg.active_page, 0)
295+
296+ def test_progress_page(self):
297+ """Test the install progresss page."""
298+ self.dlg.response(Gtk.ResponseType.OK)
299+ self.assertEquals(self.dlg.active_page, 1)

Subscribers

People subscribed via source and target branches

to all changes: