summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui/crumbs/hig.py
diff options
context:
space:
mode:
authorDongxiao Xu <dongxiao.xu@intel.com>2011-11-28 14:32:40 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-02-24 18:04:27 +0000
commit656f9a07588cc00704825a78de9649ca4a1552b8 (patch)
tree653c7941689599994d5876162c540fb7ee22736e /bitbake/lib/bb/ui/crumbs/hig.py
parent14df6d53b6856ec78322b9c0ef01e26c0406fe28 (diff)
downloadpoky-656f9a07588cc00704825a78de9649ca4a1552b8.tar.gz
Hob: A new implemetation (v2)
This commit implements a new design for hob Some of the new features: - Friendly new designed GUI. Quick response to user actions. - Two step builds support package generation and image generation. - Support running GUI seprarately from bitbake server. - Recipe/package selection and deselection. - Accurate customization for image contents and size. - Progress bars showing the parsing and build status. - Load/save user configurations from/into templates. (Bitbake rev: 4dacd29f9c957d20f4583330b51e5420f9c3338d) Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com> Signed-off-by: Shane Wang <shane.wang@intel.com> Signed-off-by: Liming An <limingx.l.an@intel.com> Signed-off-by: Fengxia Hua <fengxia.hua@intel.com> Designed-by: Belen Barros Pena <belen.barros.pena@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/hig.py')
-rw-r--r--bitbake/lib/bb/ui/crumbs/hig.py589
1 files changed, 586 insertions, 3 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hig.py b/bitbake/lib/bb/ui/crumbs/hig.py
index b3b3c7a72e..89dfe03608 100644
--- a/bitbake/lib/bb/ui/crumbs/hig.py
+++ b/bitbake/lib/bb/ui/crumbs/hig.py
@@ -1,9 +1,11 @@
1# 1#
2# BitBake Graphical GTK User Interface 2# BitBake Graphical GTK User Interface
3# 3#
4# Copyright (C) 2011 Intel Corporation 4# Copyright (C) 2011-2012 Intel Corporation
5# 5#
6# Authored by Joshua Lock <josh@linux.intel.com> 6# Authored by Joshua Lock <josh@linux.intel.com>
7# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
8# Authored by Shane Wang <shane.wang@intel.com>
7# 9#
8# This program is free software; you can redistribute it and/or modify 10# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as 11# it under the terms of the GNU General Public License version 2 as
@@ -18,21 +20,33 @@
18# with this program; if not, write to the Free Software Foundation, Inc., 20# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 22
21import gobject
22import gtk 23import gtk
24import gobject
25import hashlib
26import os
27import re
28import subprocess
29import shlex
30from bb.ui.crumbs.hobcolor import HobColors
31from bb.ui.crumbs.hobwidget import HobWidget
32from bb.ui.crumbs.progressbar import HobProgressBar
33
23""" 34"""
24The following are convenience classes for implementing GNOME HIG compliant 35The following are convenience classes for implementing GNOME HIG compliant
25BitBake GUI's 36BitBake GUI's
26In summary: spacing = 12px, border-width = 6px 37In summary: spacing = 12px, border-width = 6px
27""" 38"""
28 39
40#
41# CrumbsDialog
42#
29class CrumbsDialog(gtk.Dialog): 43class CrumbsDialog(gtk.Dialog):
30 """ 44 """
31 A GNOME HIG compliant dialog widget. 45 A GNOME HIG compliant dialog widget.
32 Add buttons with gtk.Dialog.add_button or gtk.Dialog.add_buttons 46 Add buttons with gtk.Dialog.add_button or gtk.Dialog.add_buttons
33 """ 47 """
34 def __init__(self, parent=None, label="", icon=gtk.STOCK_INFO): 48 def __init__(self, parent=None, label="", icon=gtk.STOCK_INFO):
35 gtk.Dialog.__init__(self, "", parent, gtk.DIALOG_DESTROY_WITH_PARENT) 49 super(CrumbsDialog, self).__init__("", parent, gtk.DIALOG_DESTROY_WITH_PARENT)
36 50
37 #self.set_property("has-separator", False) # note: deprecated in 2.22 51 #self.set_property("has-separator", False) # note: deprecated in 2.22
38 52
@@ -59,3 +73,572 @@ class CrumbsDialog(gtk.Dialog):
59 self.label.set_property("yalign", 0.00) 73 self.label.set_property("yalign", 0.00)
60 self.label.show() 74 self.label.show()
61 first_row.add(self.label) 75 first_row.add(self.label)
76
77#
78# Brought-in-by Dialog
79#
80class BinbDialog(gtk.Dialog):
81 """
82 A dialog widget to show "brought in by" info when a recipe/package is clicked.
83 """
84
85 def __init__(self, title, content, parent=None):
86 super(BinbDialog, self).__init__(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, None)
87
88 self.set_position(gtk.WIN_POS_MOUSE)
89 self.set_resizable(False)
90 self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.DARK))
91
92 hbox = gtk.HBox(False, 0)
93 self.vbox.pack_start(hbox, expand=False, fill=False, padding=10)
94
95 label = gtk.Label(content)
96 label.set_alignment(0, 0)
97 label.set_line_wrap(True)
98 label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.WHITE))
99
100 hbox.pack_start(label, expand=False, fill=False, padding=10)
101 self.vbox.show_all()
102
103#
104# AdvancedSettings Dialog
105#
106class AdvancedSettingDialog (gtk.Dialog):
107
108 def __init__(self, title, configuration, all_image_types,
109 all_package_formats, all_distros, all_sdk_machines,
110 max_threads, split_model, parent, flags, buttons):
111 super(AdvancedSettingDialog, self).__init__(title, parent, flags, buttons)
112
113 # class members from other objects
114 # bitbake settings from Builder.Configuration
115 self.configuration = configuration
116 self.image_types = all_image_types
117 self.all_package_formats = all_package_formats
118 self.all_distros = all_distros
119 self.all_sdk_machines = all_sdk_machines
120 self.max_threads = max_threads
121 self.split_model = split_model
122
123 # class members for internal use
124 self.pkgfmt_store = None
125 self.distro_combo = None
126 self.dldir_text = None
127 self.sstatedir_text = None
128 self.sstatemirror_text = None
129 self.bb_spinner = None
130 self.pmake_spinner = None
131 self.rootfs_size_spinner = None
132 self.extra_size_spinner = None
133 self.gplv3_checkbox = None
134 self.toolchain_checkbox = None
135 self.setting_store = None
136 self.image_types_checkbuttons = {}
137
138 self.variables = {}
139 self.variables["PACKAGE_FORMAT"] = self.configuration.curr_package_format
140 self.variables["INCOMPATIBLE_LICENSE"] = self.configuration.incompat_license
141 self.variables["IMAGE_FSTYPES"] = self.configuration.image_fstypes
142 self.md5 = hashlib.md5(str(sorted(self.variables.items()))).hexdigest()
143 self.settings_changed = False
144
145 # create visual elements on the dialog
146 self.create_visual_elements()
147 self.connect("response", self.response_cb)
148
149 def create_visual_elements(self):
150 self.set_size_request(500, 500)
151
152 self.nb = gtk.Notebook()
153 self.nb.set_show_tabs(True)
154 self.nb.append_page(self.create_image_types_page(), gtk.Label("Image types"))
155 self.nb.append_page(self.create_output_page(), gtk.Label("Output"))
156 self.nb.append_page(self.create_build_environment_page(), gtk.Label("Build environment"))
157 self.nb.append_page(self.create_others_page(), gtk.Label("Others"))
158 self.nb.set_current_page(0)
159 self.vbox.pack_start(self.nb, expand=True, fill=True)
160 self.vbox.pack_end(gtk.HSeparator(), expand=True, fill=True)
161
162 self.show_all()
163
164 def create_image_types_page(self):
165 advanced_vbox = gtk.VBox(False, 15)
166 advanced_vbox.set_border_width(20)
167
168 rows = (len(self.image_types)+1)/2
169 table = gtk.Table(rows + 1, 10, True)
170 advanced_vbox.pack_start(table, expand=False, fill=False)
171
172 tooltip = "Select image file system types that will be used."
173 image = gtk.Image()
174 image.show()
175 image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
176 image.set_tooltip_text(tooltip)
177 label = HobWidget.gen_label_widget("<span weight=\"bold\">Select image types:</span>")
178 table.attach(label, 0, 9, 0, 1)
179 table.attach(image, 9, 10, 0, 1)
180
181 i = 1
182 j = 1
183 for image_type in self.image_types:
184 self.image_types_checkbuttons[image_type] = gtk.CheckButton(image_type)
185 self.image_types_checkbuttons[image_type].set_tooltip_text("Build an %s image" % image_type)
186 table.attach(self.image_types_checkbuttons[image_type], j, j + 4, i, i + 1)
187 if image_type in self.configuration.image_fstypes:
188 self.image_types_checkbuttons[image_type].set_active(True)
189 i += 1
190 if i > rows:
191 i = 1
192 j = j + 4
193
194 return advanced_vbox
195
196 def create_output_page(self):
197 advanced_vbox = gtk.VBox(False, 15)
198 advanced_vbox.set_border_width(20)
199
200 sub_vbox = gtk.VBox(False, 5)
201 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
202 label = HobWidget.gen_label_widget("<span weight=\"bold\">Packaging Format:</span>")
203 tooltip = "Select package formats that will be used. "
204 tooltip += "The first format will be used for final image"
205 pkgfmt_widget, self.pkgfmt_store = HobWidget.gen_pkgfmt_widget(self.configuration.curr_package_format, self.all_package_formats, tooltip)
206 sub_vbox.pack_start(label, expand=False, fill=False)
207 sub_vbox.pack_start(pkgfmt_widget, expand=False, fill=False)
208
209 sub_vbox = gtk.VBox(False, 5)
210 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
211 label = HobWidget.gen_label_widget("<span weight=\"bold\">Image Rootfs Size: (MB)</span>")
212 tooltip = "Sets the size of your target image.\nThis is the basic size of your target image, unless your selected package size exceeds this value, or you set value to \"Image Extra Size\"."
213 rootfs_size_widget, self.rootfs_size_spinner = HobWidget.gen_spinner_widget(int(self.configuration.image_rootfs_size*1.0/1024), 0, 1024, tooltip)
214 sub_vbox.pack_start(label, expand=False, fill=False)
215 sub_vbox.pack_start(rootfs_size_widget, expand=False, fill=False)
216
217 sub_vbox = gtk.VBox(False, 5)
218 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
219 label = HobWidget.gen_label_widget("<span weight=\"bold\">Image Extra Size: (MB)</span>")
220 tooltip = "Sets the extra free space of your target image.\nDefaultly, system will reserve 30% of your image size as your free space. If your image contains zypper, it will bring in 50MB more space. The maximum free space is 1024MB."
221 extra_size_widget, self.extra_size_spinner = HobWidget.gen_spinner_widget(int(self.configuration.image_extra_size*1.0/1024), 0, 1024, tooltip)
222 sub_vbox.pack_start(label, expand=False, fill=False)
223 sub_vbox.pack_start(extra_size_widget, expand=False, fill=False)
224
225 self.gplv3_checkbox = gtk.CheckButton("Exclude GPLv3 packages")
226 self.gplv3_checkbox.set_tooltip_text("Check this box to prevent GPLv3 packages from being included in your image")
227 if "GPLv3" in self.configuration.incompat_license.split():
228 self.gplv3_checkbox.set_active(True)
229 else:
230 self.gplv3_checkbox.set_active(False)
231 advanced_vbox.pack_start(self.gplv3_checkbox, expand=False, fill=False)
232
233 sub_hbox = gtk.HBox(False, 5)
234 advanced_vbox.pack_start(sub_hbox, expand=False, fill=False)
235 self.toolchain_checkbox = gtk.CheckButton("Build Toolchain")
236 self.toolchain_checkbox.set_tooltip_text("Check this box to build the related toolchain with your image")
237 self.toolchain_checkbox.set_active(self.configuration.toolchain_build)
238 sub_hbox.pack_start(self.toolchain_checkbox, expand=False, fill=False)
239
240 tooltip = "This is the Host platform you would like to run the toolchain"
241 sdk_machine_widget, self.sdk_machine_combo = HobWidget.gen_combo_widget(self.configuration.curr_sdk_machine, self.all_sdk_machines, tooltip)
242 sub_hbox.pack_start(sdk_machine_widget, expand=False, fill=False)
243
244 return advanced_vbox
245
246 def create_build_environment_page(self):
247 advanced_vbox = gtk.VBox(False, 15)
248 advanced_vbox.set_border_width(20)
249
250 sub_vbox = gtk.VBox(False, 5)
251 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
252 label = HobWidget.gen_label_widget("<span weight=\"bold\">Select Distro:</span>")
253 tooltip = "This is the Yocto distribution you would like to use"
254 distro_widget, self.distro_combo = HobWidget.gen_combo_widget(self.configuration.curr_distro, self.all_distros, tooltip)
255 sub_vbox.pack_start(label, expand=False, fill=False)
256 sub_vbox.pack_start(distro_widget, expand=False, fill=False)
257
258 sub_vbox = gtk.VBox(False, 5)
259 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
260 label = HobWidget.gen_label_widget("<span weight=\"bold\">BB_NUMBER_THREADS:</span>")
261 tooltip = "Sets the number of threads that bitbake tasks can run simultaneously"
262 bbthread_widget, self.bb_spinner = HobWidget.gen_spinner_widget(self.configuration.bbthread, 1, self.max_threads, tooltip)
263 sub_vbox.pack_start(label, expand=False, fill=False)
264 sub_vbox.pack_start(bbthread_widget, expand=False, fill=False)
265
266 sub_vbox = gtk.VBox(False, 5)
267 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
268 label = HobWidget.gen_label_widget("<span weight=\"bold\">PARALLEL_MAKE:</span>")
269 tooltip = "Sets the make parallism, as known as 'make -j'"
270 pmake_widget, self.pmake_spinner = HobWidget.gen_spinner_widget(self.configuration.pmake, 1, self.max_threads, tooltip)
271 sub_vbox.pack_start(label, expand=False, fill=False)
272 sub_vbox.pack_start(pmake_widget, expand=False, fill=False)
273
274 sub_vbox = gtk.VBox(False, 5)
275 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
276 label = HobWidget.gen_label_widget("<span weight=\"bold\">Set Download Directory:</span>")
277 tooltip = "Select a folder that caches the upstream project source code"
278 dldir_widget, self.dldir_text = HobWidget.gen_entry_widget(self.split_model, self.configuration.dldir, self, tooltip)
279 sub_vbox.pack_start(label, expand=False, fill=False)
280 sub_vbox.pack_start(dldir_widget, expand=False, fill=False)
281
282 sub_vbox = gtk.VBox(False, 5)
283 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
284 label = HobWidget.gen_label_widget("<span weight=\"bold\">Select SSTATE Directory:</span>")
285 tooltip = "Select a folder that caches your prebuilt results"
286 sstatedir_widget, self.sstatedir_text = HobWidget.gen_entry_widget(self.split_model, self.configuration.sstatedir, self, tooltip)
287 sub_vbox.pack_start(label, expand=False, fill=False)
288 sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False)
289
290 sub_vbox = gtk.VBox(False, 5)
291 advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
292 label = HobWidget.gen_label_widget("<span weight=\"bold\">Select SSTATE Mirror:</span>")
293 tooltip = "Select the prebuilt mirror that will fasten your build speed"
294 sstatemirror_widget, self.sstatemirror_text = HobWidget.gen_entry_widget(self.split_model, self.configuration.sstatemirror, self, tooltip)
295 sub_vbox.pack_start(label, expand=False, fill=False)
296 sub_vbox.pack_start(sstatemirror_widget, expand=False, fill=False)
297
298 return advanced_vbox
299
300 def create_others_page(self):
301 advanced_vbox = gtk.VBox(False, 15)
302 advanced_vbox.set_border_width(20)
303
304 sub_vbox = gtk.VBox(False, 5)
305 advanced_vbox.pack_start(sub_vbox, expand=True, fill=True)
306 label = HobWidget.gen_label_widget("<span weight=\"bold\">Add your own variables:</span>")
307 tooltip = "This is the key/value pair for your extra settings"
308 setting_widget, self.setting_store = HobWidget.gen_editable_settings(self.configuration.extra_setting, tooltip)
309 sub_vbox.pack_start(label, expand=False, fill=False)
310 sub_vbox.pack_start(setting_widget, expand=True, fill=True)
311
312 return advanced_vbox
313
314 def response_cb(self, dialog, response_id):
315 self.variables = {}
316
317 self.configuration.curr_package_format = ""
318 it = self.pkgfmt_store.get_iter_first()
319 while it:
320 value = self.pkgfmt_store.get_value(it, 2)
321 if value:
322 self.configuration.curr_package_format += (self.pkgfmt_store.get_value(it, 1) + " ")
323 it = self.pkgfmt_store.iter_next(it)
324 self.configuration.curr_package_format = self.configuration.curr_package_format.strip()
325 self.variables["PACKAGE_FORMAT"] = self.configuration.curr_package_format
326
327 self.configuration.curr_distro = self.distro_combo.get_active_text()
328 self.configuration.dldir = self.dldir_text.get_text()
329 self.configuration.sstatedir = self.sstatedir_text.get_text()
330 self.configuration.sstatemirror = self.sstatemirror_text.get_text()
331 self.configuration.bbthread = self.bb_spinner.get_value_as_int()
332 self.configuration.pmake = self.pmake_spinner.get_value_as_int()
333 self.configuration.image_rootfs_size = self.rootfs_size_spinner.get_value_as_int() * 1024
334 self.configuration.image_extra_size = self.extra_size_spinner.get_value_as_int() * 1024
335
336 self.configuration.image_fstypes = []
337 for image_type in self.image_types:
338 if self.image_types_checkbuttons[image_type].get_active():
339 self.configuration.image_fstypes.append(image_type)
340 self.variables["IMAGE_FSTYPES"] = self.configuration.image_fstypes
341
342 if self.gplv3_checkbox.get_active():
343 if "GPLv3" not in self.configuration.incompat_license.split():
344 self.configuration.incompat_license += " GPLv3"
345 else:
346 if "GPLv3" in self.configuration.incompat_license.split():
347 self.configuration.incompat_license = self.configuration.incompat_license.split().remove("GPLv3")
348 self.configuration.incompat_license = " ".join(self.configuration.incompat_license or [])
349 self.configuration.incompat_license = self.configuration.incompat_license.strip()
350 self.variables["INCOMPATIBLE_LICENSE"] = self.configuration.incompat_license
351
352 self.configuration.toolchain_build = self.toolchain_checkbox.get_active()
353
354 self.configuration.extra_setting = {}
355 it = self.setting_store.get_iter_first()
356 while it:
357 key = self.setting_store.get_value(it, 0)
358 value = self.setting_store.get_value(it, 1)
359 self.configuration.extra_setting[key] = value
360 self.variables[key] = value
361 it = self.setting_store.iter_next(it)
362
363 md5 = hashlib.md5(str(sorted(self.variables.items()))).hexdigest()
364 self.settings_changed = (self.md5 != md5)
365
366#
367# DeployImageDialog
368#
369class DeployImageDialog (gtk.Dialog):
370
371 __dummy_usb__ = "--select a usb drive--"
372
373 def __init__(self, title, image_path, parent, flags, buttons):
374 super(DeployImageDialog, self).__init__(title, parent, flags, buttons)
375
376 self.image_path = image_path
377
378 self.create_visual_elements()
379 self.connect("response", self.response_cb)
380
381 def create_visual_elements(self):
382 self.set_border_width(20)
383 self.set_default_size(500, 250)
384
385 label = gtk.Label()
386 label.set_alignment(0.0, 0.5)
387 markup = "<span font_desc='12'>The image to be written into usb drive:</span>"
388 label.set_markup(markup)
389 self.vbox.pack_start(label, expand=False, fill=False, padding=2)
390
391 scroll = gtk.ScrolledWindow()
392 scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
393 scroll.set_shadow_type(gtk.SHADOW_IN)
394 tv = gtk.TextView()
395 tv.set_editable(False)
396 tv.set_wrap_mode(gtk.WRAP_WORD)
397 tv.set_cursor_visible(False)
398 buf = gtk.TextBuffer()
399 buf.set_text(self.image_path)
400 tv.set_buffer(buf)
401 scroll.add(tv)
402 self.vbox.pack_start(scroll, expand=True, fill=True)
403
404 self.usb_desc = gtk.Label()
405 self.usb_desc.set_alignment(0.0, 0.5)
406 markup = "<span font_desc='12'>You haven't chosen any USB drive.</span>"
407 self.usb_desc.set_markup(markup)
408
409 self.usb_combo = gtk.combo_box_new_text()
410 self.usb_combo.connect("changed", self.usb_combo_changed_cb)
411 model = self.usb_combo.get_model()
412 model.clear()
413 self.usb_combo.append_text(self.__dummy_usb__)
414 for usb in self.find_all_usb_devices():
415 self.usb_combo.append_text("/dev/" + usb)
416 self.usb_combo.set_active(0)
417 self.vbox.pack_start(self.usb_combo, expand=True, fill=True)
418 self.vbox.pack_start(self.usb_desc, expand=False, fill=False, padding=2)
419
420 self.progress_bar = HobProgressBar()
421 self.vbox.pack_start(self.progress_bar, expand=False, fill=False)
422 separator = gtk.HSeparator()
423 self.vbox.pack_start(separator, expand=False, fill=True, padding=10)
424
425 self.vbox.show_all()
426 self.progress_bar.hide()
427
428 def popen_read(self, cmd):
429 return os.popen("%s 2>/dev/null" % cmd).read().strip()
430
431 def find_all_usb_devices(self):
432 usb_devs = [ os.readlink(u)
433 for u in self.popen_read('ls /dev/disk/by-id/usb*').split()
434 if not re.search(r'part\d+', u) ]
435 return [ '%s' % u[u.rfind('/')+1:] for u in usb_devs ]
436
437 def get_usb_info(self, dev):
438 return "%s %s" % \
439 (self.popen_read('cat /sys/class/block/%s/device/vendor' % dev),
440 self.popen_read('cat /sys/class/block/%s/device/model' % dev))
441
442 def usb_combo_changed_cb(self, usb_combo):
443 combo_item = self.usb_combo.get_active_text()
444 if not combo_item or combo_item == self.__dummy_usb__:
445 markup = "<span font_desc='12'>You haven't chosen any USB drive.</span>"
446 self.usb_desc.set_markup(markup)
447 else:
448 markup = "<span font_desc='12'>" + self.get_usb_info(combo_item.lstrip("/dev/")) + "</span>"
449 self.usb_desc.set_markup(markup)
450
451 def response_cb(self, dialog, response_id):
452 if response_id == gtk.RESPONSE_YES:
453 combo_item = self.usb_combo.get_active_text()
454 if combo_item and combo_item != self.__dummy_usb__:
455 cmdline = "/usr/bin/xterm -e "
456 cmdline += "\"sudo dd if=" + self.image_path + " of=" + combo_item + "; bash\""
457 subprocess.Popen(args=shlex.split(cmdline))
458
459 def update_progress_bar(self, title, fraction, status=True):
460 self.progress_bar.update(fraction)
461 self.progress_bar.set_title(title)
462 self.progress_bar.set_rcstyle(status)
463
464 def write_file(self, ifile, ofile):
465 self.progress_bar.reset()
466 self.progress_bar.show()
467
468 f_from = os.open(ifile, os.O_RDONLY)
469 f_to = os.open(ofile, os.O_WRONLY)
470
471 total_size = os.stat(ifile).st_size
472 written_size = 0
473
474 while True:
475 buf = os.read(f_from, 1024*1024)
476 if not buf:
477 break
478 os.write(f_to, buf)
479 written_size += 1024*1024
480 self.update_progress_bar("Writing to usb:", written_size * 1.0/total_size)
481
482 self.update_progress_bar("Writing completed:", 1.0)
483 os.close(f_from)
484 os.close(f_to)
485 self.progress_bar.hide()
486#
487# LayerSelectionDialog
488#
489class LayerSelectionDialog (gtk.Dialog):
490
491 def __init__(self, title, layers, all_layers, split_model,
492 parent, flags, buttons):
493 super(LayerSelectionDialog, self).__init__(title, parent, flags, buttons)
494
495 # class members from other objects
496 self.layers = layers
497 self.all_layers = all_layers
498 self.split_model = split_model
499 self.layers_changed = False
500
501 # class members for internal use
502 self.layer_store = None
503
504 # create visual elements on the dialog
505 self.create_visual_elements()
506 self.connect("response", self.response_cb)
507
508 def create_visual_elements(self):
509 self.set_border_width(20)
510 self.set_default_size(400, 250)
511
512 hbox_top = gtk.HBox()
513 self.set_border_width(12)
514 self.vbox.pack_start(hbox_top, expand=False, fill=False)
515
516 if self.split_model:
517 label = HobWidget.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>\n(Available layers under '${COREBASE}/layers/' directory)")
518 else:
519 label = HobWidget.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>")
520 hbox_top.pack_start(label, expand=False, fill=False)
521
522 tooltip = "Layer is a collection of bb files and conf files"
523 image = gtk.Image()
524 image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
525 image.set_tooltip_text(tooltip)
526 hbox_top.pack_end(image, expand=False, fill=False)
527
528 layer_widget, self.layer_store = HobWidget.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
529
530 self.vbox.pack_start(layer_widget, expand=True, fill=True)
531
532 separator = gtk.HSeparator()
533 self.vbox.pack_start(separator, False, True, 5)
534 separator.show()
535
536 hbox_button = gtk.HBox()
537 self.vbox.pack_end(hbox_button, expand=False, fill=False)
538 hbox_button.show()
539
540 label = HobWidget.gen_label_widget("<i>'meta' is Core layer for Yocto images</i>\n"
541 "<span weight=\"bold\">Please do not remove it</span>")
542 hbox_button.pack_start(label, expand=False, fill=False)
543
544 self.show_all()
545
546 def response_cb(self, dialog, response_id):
547 model = self.layer_store
548 it = model.get_iter_first()
549 layers = []
550 while it:
551 if self.split_model:
552 inc = model.get_value(it, 1)
553 if inc:
554 layers.append(model.get_value(it, 0))
555 else:
556 layers.append(model.get_value(it, 0))
557 it = model.iter_next(it)
558
559 self.layers_changed = (self.layers != layers)
560 self.layers = layers
561
562class ImageSelectionDialog (gtk.Dialog):
563
564 def __init__(self, image_folder, image_types, title, parent, flags, buttons):
565 super(ImageSelectionDialog, self).__init__(title, parent, flags, buttons)
566 self.connect("response", self.response_cb)
567
568 self.image_folder = image_folder
569 self.image_types = image_types
570 self.image_names = []
571
572 # create visual elements on the dialog
573 self.create_visual_elements()
574
575 self.image_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
576 self.fill_image_store()
577
578 def create_visual_elements(self):
579 self.set_border_width(20)
580 self.set_default_size(600, 300)
581 self.vbox.set_spacing(10)
582
583 hbox = gtk.HBox(False, 10)
584 self.vbox.pack_start(hbox, expand=False, fill=False)
585
586 entry = gtk.Entry()
587 entry.set_text(self.image_folder)
588 table = gtk.Table(1, 10, True)
589 table.set_size_request(560, -1)
590 hbox.pack_start(table, expand=False, fill=False)
591 table.attach(entry, 0, 9, 0, 1)
592 image = gtk.Image()
593 image.set_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)
594 open_button = gtk.Button()
595 open_button.set_image(image)
596 open_button.connect("clicked", self.select_path_cb, self, entry)
597 table.attach(open_button, 9, 10, 0, 1)
598
599 imgtv_widget, self.imgsel_tv = HobWidget.gen_imgtv_widget(400, 160)
600 self.vbox.pack_start(imgtv_widget, expand=True, fill=True)
601
602 self.show_all()
603
604 def select_path_cb(self, action, parent, entry):
605 dialog = gtk.FileChooserDialog("", parent,
606 gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
607 (gtk.STOCK_OK, gtk.RESPONSE_YES,
608 gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
609 response = dialog.run()
610 if response == gtk.RESPONSE_YES:
611 path = dialog.get_filename()
612 entry.set_text(path)
613 self.image_folder = path
614 self.fill_image_store()
615
616 dialog.destroy()
617
618 def fill_image_store(self):
619 self.image_store.clear()
620 imageset = set()
621 for root, dirs, files in os.walk(self.image_folder):
622 for f in files:
623 for image_type in self.image_types:
624 if f.endswith('.' + image_type):
625 imageset.add(f.rsplit('.' + image_type)[0])
626
627 for image in imageset:
628 self.image_store.set(self.image_store.append(), 0, image, 1, False)
629
630 self.imgsel_tv.set_model(self.image_store)
631
632 def response_cb(self, dialog, response_id):
633 self.image_names = []
634 if response_id == gtk.RESPONSE_YES:
635 iter = self.image_store.get_iter_first()
636 while iter:
637 path = self.image_store.get_path(iter)
638 if self.image_store[path][1]:
639 for root, dirs, files in os.walk(self.image_folder):
640 for f in files:
641 if f.startswith(self.image_store[path][0] + '.'):
642 self.image_names.append(f)
643 break
644 iter = self.image_store.iter_next(iter)