summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui/crumbs/imagedetailspage.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/imagedetailspage.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/imagedetailspage.py')
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/imagedetailspage.py294
1 files changed, 294 insertions, 0 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
new file mode 100755
index 0000000000..e8419e0ee9
--- /dev/null
+++ b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
@@ -0,0 +1,294 @@
1#!/usr/bin/env python
2#
3# BitBake Graphical GTK User Interface
4#
5# Copyright (C) 2012 Intel Corporation
6#
7# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
8# Authored by Shane Wang <shane.wang@intel.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License along
20# with this program; if not, write to the Free Software Foundation, Inc.,
21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23import gobject
24import gtk
25from bb.ui.crumbs.hobcolor import HobColors
26from bb.ui.crumbs.hobwidget import hic, HobWidget
27from bb.ui.crumbs.hobpages import HobPage
28
29#
30# ImageDetailsPage
31#
32class ImageDetailsPage (HobPage):
33
34 class DetailBox (gtk.EventBox):
35 def __init__(self, varlist, vallist, icon = None, button = None, color = HobColors.LIGHT_GRAY):
36 gtk.EventBox.__init__(self)
37
38 # set color
39 style = self.get_style().copy()
40 style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(color, False, False)
41 self.set_style(style)
42
43 self.hbox = gtk.HBox()
44 self.hbox.set_border_width(15)
45 self.add(self.hbox)
46
47 # pack the icon and the text on the left
48 row = len(varlist)
49 self.table = gtk.Table(row, 20, True)
50 self.table.set_size_request(100, -1)
51 self.hbox.pack_start(self.table, expand=True, fill=True, padding=15)
52
53 colid = 0
54 if icon != None:
55 self.table.attach(icon, colid, colid + 2, 0, 1)
56 colid = colid + 2
57 for line in range(0, row):
58 self.table.attach(self.text2label(varlist[line], vallist[line]), colid, 20, line, line + 1)
59
60 # pack the button on the right
61 if button != None:
62 self.hbox.pack_end(button, expand=False, fill=False)
63
64 def text2label(self, variable, value):
65 # append the name:value to the left box
66 # such as "Name: hob-core-minimal-variant-2011-12-15-beagleboard"
67 markup = "<span weight=\'bold\'>%s</span>" % variable
68 markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % value
69 label = gtk.Label()
70 label.set_alignment(0.0, 0.5)
71 label.set_markup(markup)
72 return label
73
74 def __init__(self, builder):
75 super(ImageDetailsPage, self).__init__(builder, "Image details")
76
77 self.image_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
78 self.create_visual_elements()
79
80 def create_visual_elements(self):
81 # create visual elements
82 # create the toolbar
83 self.toolbar = gtk.Toolbar()
84 self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
85 self.toolbar.set_style(gtk.TOOLBAR_BOTH)
86
87 _, my_images_button = self.append_toolbar_button(self.toolbar,
88 "My images",
89 hic.ICON_IMAGES_DISPLAY_FILE,
90 hic.ICON_IMAGES_HOVER_FILE,
91 "Open images built out previously for running or deployment",
92 self.my_images_button_clicked_cb)
93
94 self.details_top_buttons = self.add_onto_top_bar(self.toolbar)
95
96 def _remove_all_widget(self):
97 children = self.get_children() or []
98 for child in children:
99 self.remove(child)
100 children = self.box_group_area.get_children() or []
101 for child in children:
102 self.box_group_area.remove(child)
103
104 def _size_to_string(self, size):
105 if len(str(int(size))) > 6:
106 size_str = '%.1f' % (size*1.0/(1024*1024)) + ' MB'
107 elif len(str(int(size))) > 3:
108 size_str = '%.1f' % (size*1.0/1024) + ' KB'
109 else:
110 size_str = str(size) + ' B'
111 return size_str
112
113 def show_page(self, step):
114 build_succeeded = (step == self.builder.IMAGE_GENERATED)
115 image_addr = self.builder.parameters.image_addr
116 image_names = self.builder.parameters.image_names
117 if build_succeeded:
118 image_addr = self.builder.parameters.image_addr
119 image_names = self.builder.parameters.image_names
120 machine = self.builder.configuration.curr_mach
121 base_image = self.builder.recipe_model.get_selected_image()
122 layers = self.builder.configuration.layers
123 pkg_num = "%s" % len(self.builder.package_model.get_selected_packages())
124 else:
125 pkg_num = "N/A"
126
127 self._remove_all_widget()
128 self.pack_start(self.details_top_buttons, expand=False, fill=False)
129 self.pack_start(self.group_align, expand=True, fill=True)
130
131 if build_succeeded:
132 # building is the previous step
133 icon = gtk.Image()
134 pixmap_path = hic.ICON_INDI_CONFIRM_FILE
135 color = HobColors.RUNNING
136 pix_buffer = gtk.gdk.pixbuf_new_from_file(pixmap_path)
137 icon.set_from_pixbuf(pix_buffer)
138 varlist = [""]
139 vallist = ["Your image is ready"]
140 build_result = self.DetailBox(varlist=varlist, vallist=vallist, icon=icon, button=None, color=color)
141 self.box_group_area.pack_start(build_result, expand=False, fill=False)
142
143 # Name
144 self.image_store.clear()
145 for image_name in image_names:
146 image_size = self._size_to_string(os.stat(os.path.join(image_addr, image_name)).st_size)
147 self.image_store.set(self.image_store.append(), 0, image_name, 1, image_size, 2, False)
148 images_widget, treeview = HobWidget.gen_images_widget(600, 200, 100)
149 treeview.set_model(self.image_store)
150 self.box_group_area.pack_start(images_widget, expand=False, fill=False)
151
152 # Machine, Base image and Layers
153 layer_num_limit = 15
154 varlist = ["Machine: ", "Base image: ", "Layers: "]
155 vallist = []
156 if build_succeeded:
157 vallist.append(machine)
158 vallist.append(base_image)
159 i = 0
160 for layer in layers:
161 varlist.append(" - ")
162 if i > layer_num_limit:
163 break
164 i += 1
165 vallist.append("")
166 i = 0
167 for layer in layers:
168 if i > layer_num_limit:
169 break
170 elif i == layer_num_limit:
171 vallist.append("and more...")
172 else:
173 vallist.append(layer)
174 i += 1
175
176 edit_config_button = gtk.LinkButton("Changes settings for build", "Edit configuration")
177 edit_config_button.connect("clicked", self.edit_config_button_clicked_cb)
178 setting_detail = self.DetailBox(varlist=varlist, vallist=vallist, icon=None, button=edit_config_button)
179 self.box_group_area.pack_start(setting_detail, expand=False, fill=False)
180
181 # Packages included, and Total image size
182 varlist = ["Packages included: ", "Total image size: "]
183 vallist = []
184 vallist.append(pkg_num)
185 vallist.append(image_size)
186 if build_succeeded:
187 edit_packages_button = gtk.LinkButton("Change package selection for customization", "Edit packages")
188 edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
189 else: # get to this page from "My images"
190 edit_packages_button = None
191 package_detail = self.DetailBox(varlist=varlist, vallist=vallist, icon=None, button=edit_packages_button)
192 self.box_group_area.pack_start(package_detail, expand=False, fill=False)
193 if build_succeeded:
194 buttonlist = ["Build new image", "Save as template", "Run image", "Deploy image"]
195 else: # get to this page from "My images"
196 buttonlist = ["Build new image", "Run image", "Deploy image"]
197 details_bottom_buttons = self.create_bottom_buttons(buttonlist)
198 self.box_group_area.pack_end(details_bottom_buttons, expand=False, fill=False)
199
200 self.show_all()
201
202 def create_bottom_buttons(self, buttonlist):
203 # Create the buttons at the bottom
204 bottom_buttons = gtk.HBox(False, 5)
205 created = False
206
207 # create button "Deploy image"
208 name = "Deploy image"
209 if name in buttonlist:
210 deploy_button = gtk.Button()
211 label = gtk.Label()
212 mark = "<span %s>Deploy image</span>" % self.span_tag('24px', 'bold')
213 label.set_markup(mark)
214 deploy_button.set_image(label)
215 deploy_button.set_size_request(205, 49)
216 deploy_button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.ORANGE))
217 deploy_button.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(HobColors.ORANGE))
218 deploy_button.modify_bg(gtk.STATE_SELECTED, gtk.gdk.Color(HobColors.ORANGE))
219 deploy_button.set_tooltip_text("Deploy image to get your target board")
220 deploy_button.set_flags(gtk.CAN_DEFAULT)
221 deploy_button.grab_default()
222 deploy_button.connect("clicked", self.deploy_button_clicked_cb)
223 bottom_buttons.pack_end(deploy_button, expand=False, fill=False)
224 created = True
225
226 name = "Run image"
227 if name in buttonlist:
228 if created == True:
229 # separator
230 label = gtk.Label(" or ")
231 bottom_buttons.pack_end(label, expand=False, fill=False)
232
233 # create button "Run image"
234 run_button = gtk.LinkButton("Launch and boot the image in the QEMU emulator", "Run image")
235 run_button.connect("clicked", self.run_button_clicked_cb)
236 bottom_buttons.pack_end(run_button, expand=False, fill=False)
237 created = True
238
239 name = "Save as template"
240 if name in buttonlist:
241 if created == True:
242 # separator
243 label = gtk.Label(" or ")
244 bottom_buttons.pack_end(label, expand=False, fill=False)
245
246 # create button "Save as template"
247 save_button = gtk.LinkButton("Save the hob build template for future use", "Save as template")
248 save_button.connect("clicked", self.save_button_clicked_cb)
249 bottom_buttons.pack_end(save_button, expand=False, fill=False)
250 create = True
251
252 name = "Build new image"
253 if name in buttonlist:
254 # create button "Build new image"
255 build_new_button = gtk.LinkButton("Initiate another new build from the beginning", "Build new image")
256 build_new_button.connect("clicked", self.build_new_button_clicked_cb)
257 bottom_buttons.pack_start(build_new_button, expand=False, fill=False)
258
259 return bottom_buttons
260
261 def _get_selected_image(self):
262 image_name = ""
263 iter = self.image_store.get_iter_first()
264 while iter:
265 path = self.image_store.get_path(iter)
266 if self.image_store[path][2]:
267 image_name = self.image_store[path][0]
268 break
269 iter = self.image_store.iter_next(iter)
270
271 return image_name
272
273 def save_button_clicked_cb(self, button):
274 self.builder.show_save_template_dialog()
275
276 def deploy_button_clicked_cb(self, button):
277 image_name = self._get_selected_image()
278 self.builder.deploy_image(image_name)
279
280 def run_button_clicked_cb(self, button):
281 image_name = self._get_selected_image()
282 self.builder.runqemu_image(image_name)
283
284 def build_new_button_clicked_cb(self, button):
285 self.builder.initiate_new_build()
286
287 def edit_config_button_clicked_cb(self, button):
288 self.builder.show_configuration()
289
290 def edit_packages_button_clicked_cb(self, button):
291 self.builder.show_packages(ask=False)
292
293 def my_images_button_clicked_cb(self, button):
294 self.builder.show_load_my_images_dialog()