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 /bitbake | |
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>
Diffstat (limited to 'bitbake')
-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() |