diff options
| author | Liming An <limingx.l.an@intel.com> | 2012-06-04 18:52:13 +0800 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2012-06-08 12:13:15 +0100 |
| commit | e91f1e28bc1742f010225c49410e49b1257c15c7 (patch) | |
| tree | cdeaf695ae78a191e8685ac2c8ac530f3d827be8 | |
| parent | c0b92702d367466641f88371fbcbc0fdebdbbb96 (diff) | |
| download | poky-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>
| -rwxr-xr-x | bitbake/lib/bb/ui/crumbs/builder.py | 118 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/hig.py | 2 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/hobeventhandler.py | 3 | ||||
| -rwxr-xr-x | bitbake/lib/bb/ui/crumbs/imagedetailspage.py | 201 |
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 | |||
| 26 | from bb.ui.crumbs.hobwidget import hic, HobViewTable, HobAltButton, HobButton | 26 | from bb.ui.crumbs.hobwidget import hic, HobViewTable, HobAltButton, HobButton |
| 27 | from bb.ui.crumbs.hobpages import HobPage | 27 | from bb.ui.crumbs.hobpages import HobPage |
| 28 | import subprocess | 28 | import subprocess |
| 29 | 29 | from 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() |
