summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb
diff options
context:
space:
mode:
authorLiming An <limingx.l.an@intel.com>2012-06-04 18:52:13 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-06-08 12:13:15 +0100
commite91f1e28bc1742f010225c49410e49b1257c15c7 (patch)
treecdeaf695ae78a191e8685ac2c8ac530f3d827be8 /bitbake/lib/bb
parentc0b92702d367466641f88371fbcbc0fdebdbbb96 (diff)
downloadpoky-e91f1e28bc1742f010225c49410e49b1257c15c7.tar.gz
Hob: Change 'run image' work flow and image detail screen as ui design
Added the qemu_image_kernel selection view box to image detail screen GUI, and changed the 'run image' button clicked work flow. [YOCTO #2155] (Bitbake rev: d548eb8a03cfba5c64c018898972bc0a0bdb280c) Signed-off-by: Liming An <limingx.l.an@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb')
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/builder.py118
-rw-r--r--bitbake/lib/bb/ui/crumbs/hig.py2
-rw-r--r--bitbake/lib/bb/ui/crumbs/hobeventhandler.py3
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/imagedetailspage.py201
4 files changed, 211 insertions, 113 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/builder.py b/bitbake/lib/bb/ui/crumbs/builder.py
index 7861a6fbaf..ad9c0f4587 100755
--- a/bitbake/lib/bb/ui/crumbs/builder.py
+++ b/bitbake/lib/bb/ui/crumbs/builder.py
@@ -303,6 +303,7 @@ class Parameters:
303 self.tmpdir = params["tmpdir"] 303 self.tmpdir = params["tmpdir"]
304 self.image_white_pattern = params["image_white_pattern"] 304 self.image_white_pattern = params["image_white_pattern"]
305 self.image_black_pattern = params["image_black_pattern"] 305 self.image_black_pattern = params["image_black_pattern"]
306 self.kernel_image_type = params["kernel_image_type"]
306 # for build log to show 307 # for build log to show
307 self.bb_version = params["bb_version"] 308 self.bb_version = params["bb_version"]
308 self.target_arch = params["target_arch"] 309 self.target_arch = params["target_arch"]
@@ -1160,25 +1161,32 @@ class Builder(gtk.Window):
1160 response = dialog.run() 1161 response = dialog.run()
1161 dialog.destroy() 1162 dialog.destroy()
1162 1163
1163 def get_kernel_file_name(self): 1164 def show_load_kernel_dialog(self):
1164 name_list = [] 1165 dialog = gtk.FileChooserDialog("Load Kernel Files", self,
1165 kernel_name = "" 1166 gtk.FILE_CHOOSER_ACTION_SAVE)
1166 image_path = self.parameters.image_addr 1167 button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
1167 if image_path: 1168 HobAltButton.style_button(button)
1168 files = [f for f in os.listdir(image_path) if f[0] <> '.'] 1169 button = dialog.add_button("Open", gtk.RESPONSE_YES)
1169 for check_file in files: 1170 HobButton.style_button(button)
1170 if check_file.endswith(".bin"): 1171 filter = gtk.FileFilter()
1171 name_splits = check_file.split(".")[0] 1172 filter.set_name("Kernel Files")
1172 if self.configuration.curr_mach in name_splits.split("-"): 1173 filter.add_pattern("*.bin")
1173 kernel_name = check_file 1174 dialog.add_filter(filter)
1174 if not os.path.islink(os.path.join(image_path, check_file)): 1175
1175 name_list.append(check_file) 1176 dialog.set_current_folder(self.parameters.image_addr)
1176 1177
1177 return kernel_name, len(name_list) 1178 response = dialog.run()
1178 1179 kernel_path = ""
1179 def runqemu_image(self, image_name): 1180 if response == gtk.RESPONSE_YES:
1180 if not image_name: 1181 kernel_path = dialog.get_filename()
1181 lbl = "<b>Please select an image to launch in QEMU.</b>" 1182
1183 dialog.destroy()
1184
1185 return kernel_path
1186
1187 def runqemu_image(self, image_name, kernel_name):
1188 if not image_name or not kernel_name:
1189 lbl = "<b>Please select an %s to launch in QEMU.</b>" % ("kernel" if image_name else "image")
1182 dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO) 1190 dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
1183 button = dialog.add_button("Close", gtk.RESPONSE_OK) 1191 button = dialog.add_button("Close", gtk.RESPONSE_OK)
1184 HobButton.style_button(button) 1192 HobButton.style_button(button)
@@ -1186,57 +1194,33 @@ class Builder(gtk.Window):
1186 dialog.destroy() 1194 dialog.destroy()
1187 return 1195 return
1188 1196
1189 kernel_name, kernels_number = self.get_kernel_file_name() 1197 kernel_path = os.path.join(self.parameters.image_addr, kernel_name)
1190 if not kernel_name or kernels_number > 1: 1198 image_path = os.path.join(self.parameters.image_addr, image_name)
1191 dialog = gtk.FileChooserDialog("Load Kernel Files", self,
1192 gtk.FILE_CHOOSER_ACTION_SAVE)
1193 button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
1194 HobAltButton.style_button(button)
1195 button = dialog.add_button("Open", gtk.RESPONSE_YES)
1196 HobButton.style_button(button)
1197 filter = gtk.FileFilter()
1198 filter.set_name("Kernel Files")
1199 filter.add_pattern("*.bin")
1200 dialog.add_filter(filter)
1201
1202 dialog.set_current_folder(self.parameters.image_addr)
1203 1199
1204 response = dialog.run() 1200 source_env_path = os.path.join(self.parameters.core_base, "oe-init-build-env")
1205 if response == gtk.RESPONSE_YES: 1201 tmp_path = self.parameters.tmpdir
1206 kernel_path = dialog.get_filename() 1202 cmdline = bb.ui.crumbs.utils.which_terminal()
1207 image_path = os.path.join(self.parameters.image_addr, image_name) 1203 if os.path.exists(image_path) and os.path.exists(kernel_path) \
1204 and os.path.exists(source_env_path) and os.path.exists(tmp_path) \
1205 and cmdline:
1206 cmdline += "\' bash -c \"export OE_TMPDIR=" + tmp_path + "; "
1207 cmdline += "source " + source_env_path + " " + os.getcwd() + "; "
1208 cmdline += "runqemu " + kernel_path + " " + image_path + "\"\'"
1209 subprocess.Popen(shlex.split(cmdline))
1210 else:
1211 lbl = "<b>Path error</b>\nOne of your paths is wrong,"
1212 lbl = lbl + " please make sure the following paths exist:\n"
1213 lbl = lbl + "image path:" + image_path + "\n"
1214 lbl = lbl + "kernel path:" + kernel_path + "\n"
1215 lbl = lbl + "source environment path:" + source_env_path + "\n"
1216 lbl = lbl + "tmp path: " + tmp_path + "."
1217 lbl = lbl + "You may be missing either xterm or vte for terminal services."
1218 dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_ERROR)
1219 button = dialog.add_button("Close", gtk.RESPONSE_OK)
1220 HobButton.style_button(button)
1221 dialog.run()
1208 dialog.destroy() 1222 dialog.destroy()
1209 1223
1210 elif kernel_name:
1211 kernel_path = os.path.join(self.parameters.image_addr, kernel_name)
1212 image_path = os.path.join(self.parameters.image_addr, image_name)
1213 response = gtk.RESPONSE_YES
1214
1215 if response == gtk.RESPONSE_YES:
1216 source_env_path = os.path.join(self.parameters.core_base, "oe-init-build-env")
1217 tmp_path = self.parameters.tmpdir
1218 cmdline = bb.ui.crumbs.utils.which_terminal()
1219 if os.path.exists(image_path) and os.path.exists(kernel_path) \
1220 and os.path.exists(source_env_path) and os.path.exists(tmp_path) \
1221 and cmdline:
1222 cmdline += "\' bash -c \"export OE_TMPDIR=" + tmp_path + "; "
1223 cmdline += "source " + source_env_path + " " + os.getcwd() + "; "
1224 cmdline += "runqemu " + kernel_path + " " + image_path + "\"\'"
1225 subprocess.Popen(shlex.split(cmdline))
1226 else:
1227 lbl = "<b>Path error</b>\nOne of your paths is wrong,"
1228 lbl = lbl + " please make sure the following paths exist:\n"
1229 lbl = lbl + "image path:" + image_path + "\n"
1230 lbl = lbl + "kernel path:" + kernel_path + "\n"
1231 lbl = lbl + "source environment path:" + source_env_path + "\n"
1232 lbl = lbl + "tmp path: " + tmp_path + "."
1233 lbl = lbl + "You may be missing either xterm or vte for terminal services."
1234 dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_ERROR)
1235 button = dialog.add_button("Close", gtk.RESPONSE_OK)
1236 HobButton.style_button(button)
1237 dialog.run()
1238 dialog.destroy()
1239
1240 def show_packages(self, ask=True): 1224 def show_packages(self, ask=True):
1241 _, selected_recipes = self.recipe_model.get_selected_recipes() 1225 _, selected_recipes = self.recipe_model.get_selected_recipes()
1242 if selected_recipes and ask: 1226 if selected_recipes and ask:
diff --git a/bitbake/lib/bb/ui/crumbs/hig.py b/bitbake/lib/bb/ui/crumbs/hig.py
index 7c9e73fdf9..f64f1be46c 100644
--- a/bitbake/lib/bb/ui/crumbs/hig.py
+++ b/bitbake/lib/bb/ui/crumbs/hig.py
@@ -1210,7 +1210,7 @@ class ImageSelectionDialog (CrumbsDialog):
1210 if f.endswith('.' + real_image_type): 1210 if f.endswith('.' + real_image_type):
1211 imageset.add(f.rsplit('.' + real_image_type)[0].rsplit('.rootfs')[0]) 1211 imageset.add(f.rsplit('.' + real_image_type)[0].rsplit('.rootfs')[0])
1212 self.image_list.append(f) 1212 self.image_list.append(f)
1213 1213
1214 for image in imageset: 1214 for image in imageset:
1215 self.image_store.set(self.image_store.append(), 0, image, 1, False) 1215 self.image_store.set(self.image_store.append(), 0, image, 1, False)
1216 1216
diff --git a/bitbake/lib/bb/ui/crumbs/hobeventhandler.py b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
index 1db9c44295..a00fcd8eda 100644
--- a/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
+++ b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
@@ -347,7 +347,7 @@ class HobHandler(gobject.GObject):
347 self.commands_async.append(self.SUB_PARSE_CONFIG) 347 self.commands_async.append(self.SUB_PARSE_CONFIG)
348 self.commands_async.append(self.SUB_GNERATE_TGTS) 348 self.commands_async.append(self.SUB_GNERATE_TGTS)
349 self.run_next_command(self.GENERATE_RECIPES) 349 self.run_next_command(self.GENERATE_RECIPES)
350 350
351 def generate_packages(self, tgts, default_task="build"): 351 def generate_packages(self, tgts, default_task="build"):
352 targets = [] 352 targets = []
353 targets.extend(tgts) 353 targets.extend(tgts)
@@ -492,6 +492,7 @@ class HobHandler(gobject.GObject):
492 params["runnable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_IMAGE_TYPES"]) or "") 492 params["runnable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_IMAGE_TYPES"]) or "")
493 params["runnable_machine_patterns"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_MACHINE_PATTERNS"]) or "") 493 params["runnable_machine_patterns"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_MACHINE_PATTERNS"]) or "")
494 params["deployable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "DEPLOYABLE_IMAGE_TYPES"]) or "") 494 params["deployable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "DEPLOYABLE_IMAGE_TYPES"]) or "")
495 params["kernel_image_type"] = self.runCommand(["getVariable", "KERNEL_IMAGETYPE"]) or ""
495 params["tmpdir"] = self.runCommand(["getVariable", "TMPDIR"]) or "" 496 params["tmpdir"] = self.runCommand(["getVariable", "TMPDIR"]) or ""
496 params["distro_version"] = self.runCommand(["getVariable", "DISTRO_VERSION"]) or "" 497 params["distro_version"] = self.runCommand(["getVariable", "DISTRO_VERSION"]) or ""
497 params["target_os"] = self.runCommand(["getVariable", "TARGET_OS"]) or "" 498 params["target_os"] = self.runCommand(["getVariable", "TARGET_OS"]) or ""
diff --git a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
index 1ab80f8277..ba0ad7ed47 100755
--- a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
+++ b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
@@ -26,7 +26,7 @@ from bb.ui.crumbs.hobcolor import HobColors
26from bb.ui.crumbs.hobwidget import hic, HobViewTable, HobAltButton, HobButton 26from bb.ui.crumbs.hobwidget import hic, HobViewTable, HobAltButton, HobButton
27from bb.ui.crumbs.hobpages import HobPage 27from bb.ui.crumbs.hobpages import HobPage
28import subprocess 28import subprocess
29 29from bb.ui.crumbs.hig import CrumbsDialog
30# 30#
31# ImageDetailsPage 31# ImageDetailsPage
32# 32#
@@ -101,9 +101,23 @@ class ImageDetailsPage (HobPage):
101 return 101 return
102 self.line_widgets[variable].set_markup(self.format_line(variable, value)) 102 self.line_widgets[variable].set_markup(self.format_line(variable, value))
103 103
104 def wrap_line(self, inputs):
105 # wrap the long text of inputs
106 wrap_width_chars = 75
107 outputs = ""
108 tmps = inputs
109 less_chars = len(inputs)
110 while (less_chars - wrap_width_chars) > 0:
111 less_chars -= wrap_width_chars
112 outputs += tmps[:wrap_width_chars] + "\n "
113 tmps = inputs[less_chars:]
114 outputs += tmps
115 return outputs
116
104 def format_line(self, variable, value): 117 def format_line(self, variable, value):
118 wraped_value = self.wrap_line(value)
105 markup = "<span weight=\'bold\'>%s</span>" % variable 119 markup = "<span weight=\'bold\'>%s</span>" % variable
106 markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % value 120 markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % wraped_value
107 return markup 121 return markup
108 122
109 def text2label(self, variable, value): 123 def text2label(self, variable, value):
@@ -117,7 +131,7 @@ class ImageDetailsPage (HobPage):
117 def __init__(self, builder): 131 def __init__(self, builder):
118 super(ImageDetailsPage, self).__init__(builder, "Image details") 132 super(ImageDetailsPage, self).__init__(builder, "Image details")
119 133
120 self.image_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) 134 self.image_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING)
121 self.button_ids = {} 135 self.button_ids = {}
122 self.details_bottom_buttons = gtk.HBox(False, 6) 136 self.details_bottom_buttons = gtk.HBox(False, 6)
123 self.create_visual_elements() 137 self.create_visual_elements()
@@ -162,10 +176,10 @@ class ImageDetailsPage (HobPage):
162 self.details_bottom_buttons.remove(child) 176 self.details_bottom_buttons.remove(child)
163 177
164 def show_page(self, step): 178 def show_page(self, step):
165 build_succeeded = (step == self.builder.IMAGE_GENERATED) 179 self.build_succeeded = (step == self.builder.IMAGE_GENERATED)
166 image_addr = self.builder.parameters.image_addr 180 image_addr = self.builder.parameters.image_addr
167 image_names = self.builder.parameters.image_names 181 image_names = self.builder.parameters.image_names
168 if build_succeeded: 182 if self.build_succeeded:
169 machine = self.builder.configuration.curr_mach 183 machine = self.builder.configuration.curr_mach
170 base_image = self.builder.recipe_model.get_selected_image() 184 base_image = self.builder.recipe_model.get_selected_image()
171 layers = self.builder.configuration.layers 185 layers = self.builder.configuration.layers
@@ -183,7 +197,7 @@ class ImageDetailsPage (HobPage):
183 self.pack_start(self.group_align, expand=True, fill=True) 197 self.pack_start(self.group_align, expand=True, fill=True)
184 198
185 self.build_result = None 199 self.build_result = None
186 if build_succeeded: 200 if self.build_succeeded:
187 # building is the previous step 201 # building is the previous step
188 icon = gtk.Image() 202 icon = gtk.Image()
189 pixmap_path = hic.ICON_INDI_CONFIRM_FILE 203 pixmap_path = hic.ICON_INDI_CONFIRM_FILE
@@ -196,38 +210,40 @@ class ImageDetailsPage (HobPage):
196 self.box_group_area.pack_start(self.build_result, expand=False, fill=False) 210 self.box_group_area.pack_start(self.build_result, expand=False, fill=False)
197 211
198 # create the buttons at the bottom first because the buttons are used in apply_button_per_image() 212 # create the buttons at the bottom first because the buttons are used in apply_button_per_image()
199 if build_succeeded: 213 if self.build_succeeded:
200 self.buttonlist = ["Build new image", "Save as template", "Run image", "Deploy image"] 214 self.buttonlist = ["Build new image", "Save as template", "Run image", "Deploy image"]
201 else: # get to this page from "My images" 215 else: # get to this page from "My images"
202 self.buttonlist = ["Build new image", "Run image", "Deploy image"] 216 self.buttonlist = ["Build new image", "Run image", "Deploy image"]
203 217
204 # Name 218 # Name
205 self.image_store.clear() 219 self.image_store.clear()
206 default_toggled = "" 220 self.toggled_image = ""
207 default_image_size = 0 221 default_image_size = 0
208 num_toggled = 0 222 self.num_toggled = 0
209 i = 0 223 i = 0
210 for image_name in image_names: 224 for image_name in image_names:
211 image_size = HobPage._size_to_string(os.stat(os.path.join(image_addr, image_name)).st_size) 225 image_size = HobPage._size_to_string(os.stat(os.path.join(image_addr, image_name)).st_size)
212 is_toggled = (self.test_type_runnable(image_name) and self.test_mach_runnable(image_name)) \
213 or self.test_deployable(image_name)
214 226
215 if not default_toggled: 227 image_attr = ("runnable" if (self.test_type_runnable(image_name) and self.test_mach_runnable(image_name)) else \
228 ("deploy" if self.test_deployable(image_name) else ""))
229 is_toggled = (image_attr != "")
230
231 if not self.toggled_image:
216 if i == (len(image_names) - 1): 232 if i == (len(image_names) - 1):
217 is_toggled = True 233 is_toggled = True
218 self.image_store.set(self.image_store.append(), 0, image_name, 1, image_size, 2, is_toggled) 234 self.image_store.set(self.image_store.append(), 0, image_name, 1, image_size, 2, is_toggled, 3, image_attr)
219 if is_toggled: 235 if is_toggled:
220 default_image_size = image_size 236 default_image_size = image_size
221 default_toggled = image_name 237 self.toggled_image = image_name
222 238
223 else: 239 else:
224 self.image_store.set(self.image_store.append(), 0, image_name, 1, image_size, 2, False) 240 self.image_store.set(self.image_store.append(), 0, image_name, 1, image_size, 2, False, 3, image_attr)
225 i = i + 1 241 i = i + 1
226 num_toggled += is_toggled 242 self.num_toggled += is_toggled
227 243
228 self.create_bottom_buttons(self.buttonlist, default_toggled) 244 is_runnable = self.create_bottom_buttons(self.buttonlist, self.toggled_image)
229 245
230 if build_succeeded and (num_toggled < 2): 246 if self.build_succeeded:
231 varlist = ["Name: ", "Directory: "] 247 varlist = ["Name: ", "Directory: "]
232 vallist = [] 248 vallist = []
233 vallist.append(image_name.split('.')[0]) 249 vallist.append(image_name.split('.')[0])
@@ -247,12 +263,27 @@ class ImageDetailsPage (HobPage):
247 self.image_detail = self.DetailBox(widget=image_table, varlist=varlist, vallist=vallist, button=view_files_button) 263 self.image_detail = self.DetailBox(widget=image_table, varlist=varlist, vallist=vallist, button=view_files_button)
248 self.box_group_area.pack_start(self.image_detail, expand=True, fill=True) 264 self.box_group_area.pack_start(self.image_detail, expand=True, fill=True)
249 265
266 # The default kernel box for the qemu images
267 self.sel_kernel = ""
268 if 'qemu' in image_name:
269 self.sel_kernel = self.get_kernel_file_name()
270
271 varlist = ["Kernel: "]
272 vallist = []
273 vallist.append(self.sel_kernel)
274
275 change_kernel_button = HobAltButton("Change")
276 change_kernel_button.connect("clicked", self.change_kernel_cb)
277 change_kernel_button.set_tooltip_text("Change qemu kernel file")
278 self.kernel_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=change_kernel_button)
279 self.box_group_area.pack_start(self.kernel_detail, expand=False, fill=False)
280
250 # Machine, Base image and Layers 281 # Machine, Base image and Layers
251 layer_num_limit = 15 282 layer_num_limit = 15
252 varlist = ["Machine: ", "Base image: ", "Layers: "] 283 varlist = ["Machine: ", "Base image: ", "Layers: "]
253 vallist = [] 284 vallist = []
254 self.setting_detail = None 285 self.setting_detail = None
255 if build_succeeded: 286 if self.build_succeeded:
256 vallist.append(machine) 287 vallist.append(machine)
257 vallist.append(base_image) 288 vallist.append(base_image)
258 i = 0 289 i = 0
@@ -283,7 +314,7 @@ class ImageDetailsPage (HobPage):
283 vallist = [] 314 vallist = []
284 vallist.append(pkg_num) 315 vallist.append(pkg_num)
285 vallist.append(default_image_size) 316 vallist.append(default_image_size)
286 if build_succeeded: 317 if self.build_succeeded:
287 edit_packages_button = HobAltButton("Edit packages") 318 edit_packages_button = HobAltButton("Edit packages")
288 edit_packages_button.set_tooltip_text("Edit the packages included in your image") 319 edit_packages_button.set_tooltip_text("Edit the packages included in your image")
289 edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb) 320 edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
@@ -296,6 +327,8 @@ class ImageDetailsPage (HobPage):
296 self.box_group_area.pack_end(self.details_bottom_buttons, expand=False, fill=False) 327 self.box_group_area.pack_end(self.details_bottom_buttons, expand=False, fill=False)
297 328
298 self.show_all() 329 self.show_all()
330 if not is_runnable:
331 self.kernel_detail.hide()
299 332
300 def view_files_clicked_cb(self, button, image_addr): 333 def view_files_clicked_cb(self, button, image_addr):
301 subprocess.call("xdg-open /%s" % image_addr, shell=True) 334 subprocess.call("xdg-open /%s" % image_addr, shell=True)
@@ -327,24 +360,63 @@ class ImageDetailsPage (HobPage):
327 break 360 break
328 return deployable 361 return deployable
329 362
330 def table_selected_cb(self, selection): 363 def get_kernel_file_name(self, kernel_addr=""):
331 model, paths = selection.get_selected_rows() 364 kernel_name = ""
332 if (not model) or (not paths):
333 return
334 365
335 path = paths[0] 366 if not kernel_addr:
336 columnid = 2 367 kernel_addr = self.builder.parameters.image_addr
337 iter = model.get_iter_first()
338 while iter:
339 rowpath = model.get_path(iter)
340 model[rowpath][columnid] = False
341 iter = model.iter_next(iter)
342 368
343 model[path][columnid] = True 369 files = [f for f in os.listdir(kernel_addr) if f[0] <> '.']
344 self.refresh_package_detail_box(model[path][1]) 370 for check_file in files:
371 if check_file.endswith(".bin"):
372 name_splits = check_file.split(".")[0]
373 if self.builder.parameters.kernel_image_type in name_splits.split("-"):
374 kernel_name = check_file
375 break
345 376
346 image_name = model[path][0] 377 return kernel_name
378
379 def show_builded_images_dialog(self, widget):
380 dialog = CrumbsDialog("Your builded images", self.builder,
381 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
382 dialog.set_size_request(-1, 350)
383
384 label = gtk.Label()
385 label.set_use_markup(True)
386 label.set_alignment(0.0, 0.5)
387 label.set_markup("<span font_desc='12'>Please select a image to run or deploy</span>")
388 dialog.vbox.pack_start(label, expand=False, fill=False)
389
390 image_table = HobViewTable(self.__columns__)
391 image_table.set_model(self.image_store)
392 image_table.connect("row-activated", self.row_activated_cb)
393 image_table.connect_group_selection(self.table_selected_cb)
394 dialog.vbox.pack_start(image_table, expand=True, fill=True)
395
396 button = dialog.add_button(" OK ", gtk.RESPONSE_YES)
397 HobButton.style_button(button)
347 398
399 dialog.show_all()
400
401 response = dialog.run()
402 dialog.destroy()
403
404 if response != gtk.RESPONSE_YES:
405 return
406
407 it = self.image_store.get_iter_first()
408 while it:
409 image_attr = self.image_store.get_value(it, 3)
410 is_select = self.image_store.get_value(it, 2)
411 if is_select:
412 image_name = self.image_store.get_value(it, 0)
413 if image_attr == 'runnable':
414 self.builder.runqemu_image(image_name, self.sel_kernel)
415 elif image_attr == 'deploy':
416 self.builder.deploy_image(image_name)
417 it = self.image_store.iter_next(it)
418
419 def repack_box_group(self, image_name=None):
348 # remove 420 # remove
349 for button_id, button in self.button_ids.items(): 421 for button_id, button in self.button_ids.items():
350 button.disconnect(button_id) 422 button.disconnect(button_id)
@@ -355,27 +427,59 @@ class ImageDetailsPage (HobPage):
355 if self.build_result: 427 if self.build_result:
356 self.box_group_area.pack_start(self.build_result, expand=False, fill=False) 428 self.box_group_area.pack_start(self.build_result, expand=False, fill=False)
357 self.box_group_area.pack_start(self.image_detail, expand=True, fill=True) 429 self.box_group_area.pack_start(self.image_detail, expand=True, fill=True)
430 if self.kernel_detail:
431 self.box_group_area.pack_start(self.kernel_detail, expand=False, fill=False)
358 if self.setting_detail: 432 if self.setting_detail:
359 self.box_group_area.pack_start(self.setting_detail, expand=False, fill=False) 433 self.box_group_area.pack_start(self.setting_detail, expand=False, fill=False)
360 self.box_group_area.pack_start(self.package_detail, expand=False, fill=False) 434 self.box_group_area.pack_start(self.package_detail, expand=False, fill=False)
361 self.create_bottom_buttons(self.buttonlist, image_name) 435 is_runnable = self.create_bottom_buttons(self.buttonlist, image_name)
362 self.box_group_area.pack_end(self.details_bottom_buttons, expand=False, fill=False) 436 self.box_group_area.pack_end(self.details_bottom_buttons, expand=False, fill=False)
363 self.show_all() 437 self.show_all()
438 if not is_runnable:
439 self.kernel_detail.hide()
440
441 def table_selected_cb(self, selection):
442 model, paths = selection.get_selected_rows()
443 if (not model) or (not paths):
444 return
445
446 path = paths[0]
447 columnid = 2
448 iter = model.get_iter_first()
449 while iter:
450 rowpath = model.get_path(iter)
451 model[rowpath][columnid] = False
452 iter = model.iter_next(iter)
453
454 model[path][columnid] = True
455 self.refresh_package_detail_box(model[path][1])
456
457 self.toggled_image = model[path][0]
458 self.repack_box_group(self.toggled_image)
459
460 def change_kernel_cb(self, widget):
461 kernel_path = self.builder.show_load_kernel_dialog()
462 if kernel_path and self.kernel_detail:
463 import os.path
464 self.sel_kernel = os.path.basename(kernel_path)
465 markup = self.kernel_detail.format_line("Kernel: ", self.sel_kernel)
466 label = ((self.kernel_detail.get_children()[0]).get_children()[0]).get_children()[0]
467 label.set_markup(markup)
364 468
365 def row_activated_cb(self, table, model, path): 469 def row_activated_cb(self, table, model, path):
366 if not model: 470 if not model:
367 return 471 return
368 iter = model.get_iter(path) 472 iter = model.get_iter(path)
369 image_name = model[path][0] 473 image_name = model[path][0]
370 if iter and model[path][2] == 'runnable': 474 if iter and model[path][2] == True:
371 kernel_name, kernel_number = self.builder.parameters.get_kernel_file_name() 475 self.builder.runqemu_image(image_name, self.sel_kernel)
372 self.builder.runqemu_image(image_name, kernel_name, kernel_number)
373 476
374 def create_bottom_buttons(self, buttonlist, image_name): 477 def create_bottom_buttons(self, buttonlist, image_name):
375 # Create the buttons at the bottom 478 # Create the buttons at the bottom
376 created = False 479 created = False
377 packed = False 480 packed = False
378 self.button_ids = {} 481 self.button_ids = {}
482 is_runnable = False
379 483
380 # create button "Deploy image" 484 # create button "Deploy image"
381 name = "Deploy image" 485 name = "Deploy image"
@@ -384,7 +488,7 @@ class ImageDetailsPage (HobPage):
384 deploy_button.set_size_request(205, 49) 488 deploy_button.set_size_request(205, 49)
385 deploy_button.set_tooltip_text("Burn a live image to a USB drive or flash memory") 489 deploy_button.set_tooltip_text("Burn a live image to a USB drive or flash memory")
386 deploy_button.set_flags(gtk.CAN_DEFAULT) 490 deploy_button.set_flags(gtk.CAN_DEFAULT)
387 button_id = deploy_button.connect("clicked", self.deploy_button_clicked_cb, image_name) 491 button_id = deploy_button.connect("clicked", self.deploy_button_clicked_cb)
388 self.button_ids[button_id] = deploy_button 492 self.button_ids[button_id] = deploy_button
389 self.details_bottom_buttons.pack_end(deploy_button, expand=False, fill=False) 493 self.details_bottom_buttons.pack_end(deploy_button, expand=False, fill=False)
390 created = True 494 created = True
@@ -406,10 +510,11 @@ class ImageDetailsPage (HobPage):
406 run_button.set_flags(gtk.CAN_DEFAULT) 510 run_button.set_flags(gtk.CAN_DEFAULT)
407 packed = True 511 packed = True
408 run_button.set_tooltip_text("Start up an image with qemu emulator") 512 run_button.set_tooltip_text("Start up an image with qemu emulator")
409 button_id = run_button.connect("clicked", self.run_button_clicked_cb, image_name) 513 button_id = run_button.connect("clicked", self.run_button_clicked_cb)
410 self.button_ids[button_id] = run_button 514 self.button_ids[button_id] = run_button
411 self.details_bottom_buttons.pack_end(run_button, expand=False, fill=False) 515 self.details_bottom_buttons.pack_end(run_button, expand=False, fill=False)
412 created = True 516 created = True
517 is_runnable = True
413 518
414 name = "Save as template" 519 name = "Save as template"
415 if name in buttonlist: 520 if name in buttonlist:
@@ -446,14 +551,22 @@ class ImageDetailsPage (HobPage):
446 button_id = build_new_button.connect("clicked", self.build_new_button_clicked_cb) 551 button_id = build_new_button.connect("clicked", self.build_new_button_clicked_cb)
447 self.button_ids[button_id] = build_new_button 552 self.button_ids[button_id] = build_new_button
448 553
554 return is_runnable
555
449 def save_button_clicked_cb(self, button): 556 def save_button_clicked_cb(self, button):
450 self.builder.show_save_template_dialog() 557 self.builder.show_save_template_dialog()
451 558
452 def deploy_button_clicked_cb(self, button, image_name): 559 def deploy_button_clicked_cb(self, button):
453 self.builder.deploy_image(image_name) 560 if self.build_succeeded and self.num_toggled > 1:
561 self.show_builded_images_dialog()
562 return
563 self.builder.deploy_image(self.toggled_image)
454 564
455 def run_button_clicked_cb(self, button, image_name): 565 def run_button_clicked_cb(self, button):
456 self.builder.runqemu_image(image_name) 566 if self.build_succeeded and self.num_toggled > 1:
567 self.show_builded_images_dialog()
568 return
569 self.builder.runqemu_image(self.toggled_image, self.sel_kernel)
457 570
458 def build_new_button_clicked_cb(self, button): 571 def build_new_button_clicked_cb(self, button):
459 self.builder.initiate_new_build_async() 572 self.builder.initiate_new_build_async()