summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/imagedetailspage.py')
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/imagedetailspage.py705
1 files changed, 0 insertions, 705 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
deleted file mode 100755
index 32d4854166..0000000000
--- a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
+++ /dev/null
@@ -1,705 +0,0 @@
1#!/usr/bin/env python
2#
3# BitBake Graphical GTK User Interface
4#
5# Copyright (C) 2012 Intel Corporation
6#
7# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
8# Authored by Shane Wang <shane.wang@intel.com>
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License version 2 as
12# published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License along
20# with this program; if not, write to the Free Software Foundation, Inc.,
21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23import gobject
24import gtk
25from bb.ui.crumbs.hobcolor import HobColors
26from bb.ui.crumbs.hobwidget import hic, HobViewTable, HobAltButton, HobButton
27from bb.ui.crumbs.hobpages import HobPage
28import subprocess
29from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
30from bb.ui.crumbs.hig.saveimagedialog import SaveImageDialog
31
32#
33# ImageDetailsPage
34#
35class ImageDetailsPage (HobPage):
36
37 class DetailBox (gtk.EventBox):
38 def __init__(self, widget = None, varlist = None, vallist = None, icon = None, button = None, button2=None, color = HobColors.LIGHT_GRAY):
39 gtk.EventBox.__init__(self)
40
41 # set color
42 style = self.get_style().copy()
43 style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(color, False, False)
44 self.set_style(style)
45
46 self.row = gtk.Table(1, 2, False)
47 self.row.set_border_width(10)
48 self.add(self.row)
49
50 total_rows = 0
51 if widget:
52 total_rows = 10
53 if varlist and vallist:
54 # pack the icon and the text on the left
55 total_rows += len(varlist)
56 self.table = gtk.Table(total_rows, 20, True)
57 self.table.set_row_spacings(6)
58 self.table.set_size_request(100, -1)
59 self.row.attach(self.table, 0, 1, 0, 1, xoptions=gtk.FILL|gtk.EXPAND, yoptions=gtk.FILL)
60
61 colid = 0
62 rowid = 0
63 self.line_widgets = {}
64 if icon:
65 self.table.attach(icon, colid, colid + 2, 0, 1)
66 colid = colid + 2
67 if widget:
68 self.table.attach(widget, colid, 20, 0, 10)
69 rowid = 10
70 if varlist and vallist:
71 for row in range(rowid, total_rows):
72 index = row - rowid
73 self.line_widgets[varlist[index]] = self.text2label(varlist[index], vallist[index])
74 self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1)
75 # pack the button on the right
76 if button:
77 self.bbox = gtk.VBox()
78 self.bbox.pack_start(button, expand=True, fill=False)
79 if button2:
80 self.bbox.pack_start(button2, expand=True, fill=False)
81 self.bbox.set_size_request(150,-1)
82 self.row.attach(self.bbox, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=gtk.EXPAND)
83
84 def update_line_widgets(self, variable, value):
85 if len(self.line_widgets) == 0:
86 return
87 if not isinstance(self.line_widgets[variable], gtk.Label):
88 return
89 self.line_widgets[variable].set_markup(self.format_line(variable, value))
90
91 def wrap_line(self, inputs):
92 # wrap the long text of inputs
93 wrap_width_chars = 75
94 outputs = ""
95 tmps = inputs
96 less_chars = len(inputs)
97 while (less_chars - wrap_width_chars) > 0:
98 less_chars -= wrap_width_chars
99 outputs += tmps[:wrap_width_chars] + "\n "
100 tmps = inputs[less_chars:]
101 outputs += tmps
102 return outputs
103
104 def format_line(self, variable, value):
105 wraped_value = self.wrap_line(value)
106 markup = "<span weight=\'bold\'>%s</span>" % variable
107 markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % wraped_value
108 return markup
109
110 def text2label(self, variable, value):
111 # append the name:value to the left box
112 # such as "Name: hob-core-minimal-variant-2011-12-15-beagleboard"
113 label = gtk.Label()
114 label.set_alignment(0.0, 0.5)
115 label.set_markup(self.format_line(variable, value))
116 return label
117
118 class BuildDetailBox (gtk.EventBox):
119 def __init__(self, varlist = None, vallist = None, icon = None, color = HobColors.LIGHT_GRAY):
120 gtk.EventBox.__init__(self)
121
122 # set color
123 style = self.get_style().copy()
124 style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(color, False, False)
125 self.set_style(style)
126
127 self.hbox = gtk.HBox()
128 self.hbox.set_border_width(10)
129 self.add(self.hbox)
130
131 total_rows = 0
132 if varlist and vallist:
133 # pack the icon and the text on the left
134 total_rows += len(varlist)
135 self.table = gtk.Table(total_rows, 20, True)
136 self.table.set_row_spacings(6)
137 self.table.set_size_request(100, -1)
138 self.hbox.pack_start(self.table, expand=True, fill=True, padding=15)
139
140 colid = 0
141 rowid = 0
142 self.line_widgets = {}
143 if icon:
144 self.table.attach(icon, colid, colid + 2, 0, 1)
145 colid = colid + 2
146 if varlist and vallist:
147 for row in range(rowid, total_rows):
148 index = row - rowid
149 self.line_widgets[varlist[index]] = self.text2label(varlist[index], vallist[index])
150 self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1)
151
152 def update_line_widgets(self, variable, value):
153 if len(self.line_widgets) == 0:
154 return
155 if not isinstance(self.line_widgets[variable], gtk.Label):
156 return
157 self.line_widgets[variable].set_markup(self.format_line(variable, value))
158
159 def wrap_line(self, inputs):
160 # wrap the long text of inputs
161 wrap_width_chars = 75
162 outputs = ""
163 tmps = inputs
164 less_chars = len(inputs)
165 while (less_chars - wrap_width_chars) > 0:
166 less_chars -= wrap_width_chars
167 outputs += tmps[:wrap_width_chars] + "\n "
168 tmps = inputs[less_chars:]
169 outputs += tmps
170 return outputs
171
172 def format_line(self, variable, value):
173 wraped_value = self.wrap_line(value)
174 markup = "<span weight=\'bold\'>%s</span>" % variable
175 markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % wraped_value
176 return markup
177
178 def text2label(self, variable, value):
179 # append the name:value to the left box
180 # such as "Name: hob-core-minimal-variant-2011-12-15-beagleboard"
181 label = gtk.Label()
182 label.set_alignment(0.0, 0.5)
183 label.set_markup(self.format_line(variable, value))
184 return label
185
186 def __init__(self, builder):
187 super(ImageDetailsPage, self).__init__(builder, "Image details")
188
189 self.image_store = []
190 self.button_ids = {}
191 self.details_bottom_buttons = gtk.HBox(False, 6)
192 self.image_saved = False
193 self.create_visual_elements()
194 self.name_field_template = ""
195 self.description_field_template = ""
196
197 def create_visual_elements(self):
198 # create visual elements
199 # create the toolbar
200 self.toolbar = gtk.Toolbar()
201 self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
202 self.toolbar.set_style(gtk.TOOLBAR_BOTH)
203
204 my_images_button = self.append_toolbar_button(self.toolbar,
205 "Images",
206 hic.ICON_IMAGES_DISPLAY_FILE,
207 hic.ICON_IMAGES_HOVER_FILE,
208 "Open previously built images",
209 self.my_images_button_clicked_cb)
210 settings_button = self.append_toolbar_button(self.toolbar,
211 "Settings",
212 hic.ICON_SETTINGS_DISPLAY_FILE,
213 hic.ICON_SETTINGS_HOVER_FILE,
214 "View additional build settings",
215 self.settings_button_clicked_cb)
216
217 self.details_top_buttons = self.add_onto_top_bar(self.toolbar)
218
219 def _remove_all_widget(self):
220 children = self.get_children() or []
221 for child in children:
222 self.remove(child)
223 children = self.box_group_area.get_children() or []
224 for child in children:
225 self.box_group_area.remove(child)
226 children = self.details_bottom_buttons.get_children() or []
227 for child in children:
228 self.details_bottom_buttons.remove(child)
229
230 def show_page(self, step):
231 self.build_succeeded = (step == self.builder.IMAGE_GENERATED)
232 image_addr = self.builder.parameters.image_addr
233 image_names = self.builder.parameters.image_names
234 if self.build_succeeded:
235 machine = self.builder.configuration.curr_mach
236 base_image = self.builder.recipe_model.get_selected_image()
237 layers = self.builder.configuration.layers
238 pkg_num = "%s" % len(self.builder.package_model.get_selected_packages())
239 log_file = self.builder.current_logfile
240 else:
241 pkg_num = "N/A"
242 log_file = None
243
244 # remove
245 for button_id, button in self.button_ids.items():
246 button.disconnect(button_id)
247 self._remove_all_widget()
248
249 # repack
250 self.pack_start(self.details_top_buttons, expand=False, fill=False)
251 self.pack_start(self.group_align, expand=True, fill=True)
252
253 self.build_result = None
254 if self.image_saved or (self.build_succeeded and self.builder.current_step == self.builder.IMAGE_GENERATING):
255 # building is the previous step
256 icon = gtk.Image()
257 pixmap_path = hic.ICON_INDI_CONFIRM_FILE
258 color = HobColors.RUNNING
259 pix_buffer = gtk.gdk.pixbuf_new_from_file(pixmap_path)
260 icon.set_from_pixbuf(pix_buffer)
261 varlist = [""]
262 if self.image_saved:
263 vallist = ["Your image recipe has been saved"]
264 else:
265 vallist = ["Your image is ready"]
266 self.build_result = self.BuildDetailBox(varlist=varlist, vallist=vallist, icon=icon, color=color)
267 self.box_group_area.pack_start(self.build_result, expand=False, fill=False)
268
269 self.buttonlist = ["Build new image", "Save image recipe", "Run image", "Deploy image"]
270
271 # Name
272 self.image_store = []
273 self.toggled_image = ""
274 default_image_size = 0
275 self.num_toggled = 0
276 i = 0
277 for image_name in image_names:
278 image_size = HobPage._size_to_string(os.stat(os.path.join(image_addr, image_name)).st_size)
279
280 image_attr = ("run" if (self.test_type_runnable(image_name) and self.test_mach_runnable(image_name)) else \
281 ("deploy" if self.test_deployable(image_name) else ""))
282 is_toggled = (image_attr != "")
283
284 if not self.toggled_image:
285 if i == (len(image_names) - 1):
286 is_toggled = True
287 if is_toggled:
288 default_image_size = image_size
289 self.toggled_image = image_name
290
291 split_stuff = image_name.split('.')
292 if "rootfs" in split_stuff:
293 image_type = image_name[(len(split_stuff[0]) + len(".rootfs") + 1):]
294 else:
295 image_type = image_name[(len(split_stuff[0]) + 1):]
296
297 self.image_store.append({'name': image_name,
298 'type': image_type,
299 'size': image_size,
300 'is_toggled': is_toggled,
301 'action_attr': image_attr,})
302
303 i = i + 1
304 self.num_toggled += is_toggled
305
306 self.is_runnable = self.create_bottom_buttons(self.buttonlist, self.toggled_image)
307
308 # Generated image files info
309 varlist = ["Name: ", "Files created: ", "Directory: "]
310 vallist = []
311
312 vallist.append(image_name.split('.')[0])
313 vallist.append(', '.join(fileitem['type'] for fileitem in self.image_store))
314 vallist.append(image_addr)
315
316 view_files_button = HobAltButton("View files")
317 view_files_button.connect("clicked", self.view_files_clicked_cb, image_addr)
318 view_files_button.set_tooltip_text("Open the directory containing the image files")
319 open_log_button = None
320 if log_file:
321 open_log_button = HobAltButton("Open log")
322 open_log_button.connect("clicked", self.open_log_clicked_cb, log_file)
323 open_log_button.set_tooltip_text("Open the build's log file")
324 self.image_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=view_files_button, button2=open_log_button)
325 self.box_group_area.pack_start(self.image_detail, expand=False, fill=True)
326
327 # The default script path to run the image (runqemu)
328 self.run_script_path = os.path.join(self.builder.parameters.core_base, "scripts/runqemu")
329 self.run_script_detail = None
330 varlist = ["Run script: "]
331 vallist = []
332 vallist.append(self.run_script_path)
333
334 change_run_script_button = HobAltButton("Change")
335 change_run_script_button.connect("clicked", self.change_run_script_cb)
336 change_run_script_button.set_tooltip_text("Change run script")
337 self.run_script_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=change_run_script_button)
338 self.box_group_area.pack_start(self.run_script_detail, expand=False, fill=True)
339
340 # The default kernel box for the qemu images
341 self.sel_kernel = ""
342 self.kernel_detail = None
343 if self.test_mach_runnable(image_name):
344 self.sel_kernel = self.get_kernel_file_name()
345
346 # varlist = ["Kernel: "]
347 # vallist = []
348 # vallist.append(self.sel_kernel)
349
350 # change_kernel_button = HobAltButton("Change")
351 # change_kernel_button.connect("clicked", self.change_kernel_cb)
352 # change_kernel_button.set_tooltip_text("Change qemu kernel file")
353 # self.kernel_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=change_kernel_button)
354 # self.box_group_area.pack_start(self.kernel_detail, expand=True, fill=True)
355
356 # Machine, Image recipe and Layers
357 layer_num_limit = 15
358 varlist = ["Machine: ", "Image recipe: ", "Layers: "]
359 vallist = []
360 self.setting_detail = None
361 if self.build_succeeded:
362 vallist.append(machine)
363 if self.builder.recipe_model.is_custom_image():
364 if self.builder.configuration.initial_selected_image == self.builder.recipe_model.__custom_image__:
365 base_image ="New image recipe"
366 else:
367 base_image = self.builder.configuration.initial_selected_image + " (edited)"
368 vallist.append(base_image)
369 i = 0
370 for layer in layers:
371 if i > layer_num_limit:
372 break
373 varlist.append(" - ")
374 i += 1
375 vallist.append("")
376 i = 0
377 for layer in layers:
378 if i > layer_num_limit:
379 break
380 elif i == layer_num_limit:
381 vallist.append("and more...")
382 else:
383 vallist.append(layer)
384 i += 1
385
386 edit_config_button = HobAltButton("Edit configuration")
387 edit_config_button.set_tooltip_text("Edit machine and image recipe")
388 edit_config_button.connect("clicked", self.edit_config_button_clicked_cb)
389 self.setting_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_config_button)
390 self.box_group_area.pack_start(self.setting_detail, expand=True, fill=True)
391
392 # Packages included, and Total image size
393 varlist = ["Packages included: ", "Total image size: "]
394 vallist = []
395 vallist.append(pkg_num)
396 vallist.append(default_image_size)
397 self.builder.configuration.image_size = default_image_size
398 self.builder.configuration.image_packages = self.builder.configuration.selected_packages
399 if self.build_succeeded:
400 edit_packages_button = HobAltButton("Edit packages")
401 edit_packages_button.set_tooltip_text("Edit the packages included in your image")
402 edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
403 else: # get to this page from "My images"
404 edit_packages_button = None
405 self.package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
406 self.box_group_area.pack_start(self.package_detail, expand=True, fill=True)
407
408 # pack the buttons at the bottom, at this time they are already created.
409 if self.build_succeeded:
410 self.box_group_area.pack_end(self.details_bottom_buttons, expand=False, fill=False)
411 else: # for "My images" page
412 self.details_separator = gtk.HSeparator()
413 self.box_group_area.pack_start(self.details_separator, expand=False, fill=False)
414 self.box_group_area.pack_start(self.details_bottom_buttons, expand=False, fill=False)
415
416 self.show_all()
417 if self.kernel_detail and (not self.is_runnable):
418 self.kernel_detail.hide()
419 if self.run_script_detail and self.is_runnable:
420 self.run_script_detail.hide()
421 self.image_saved = False
422
423 def view_files_clicked_cb(self, button, image_addr):
424 subprocess.call("xdg-open /%s" % image_addr, shell=True)
425
426 def open_log_clicked_cb(self, button, log_file):
427 if log_file:
428 log_file = "file:///" + log_file
429 gtk.show_uri(screen=button.get_screen(), uri=log_file, timestamp=0)
430
431 def refresh_package_detail_box(self, image_size):
432 self.package_detail.update_line_widgets("Total image size: ", image_size)
433
434 def test_type_runnable(self, image_name):
435 type_runnable = False
436 for t in self.builder.parameters.runnable_image_types:
437 if image_name.endswith(t):
438 type_runnable = True
439 break
440 return type_runnable
441
442 def test_mach_runnable(self, image_name):
443 mach_runnable = False
444 for t in self.builder.parameters.runnable_machine_patterns:
445 if t in image_name:
446 mach_runnable = True
447 break
448 return mach_runnable
449
450 def test_deployable(self, image_name):
451 if self.builder.configuration.curr_mach.startswith("qemu"):
452 return False
453 deployable = False
454 for t in self.builder.parameters.deployable_image_types:
455 if image_name.endswith(t):
456 deployable = True
457 break
458 return deployable
459
460 def get_kernel_file_name(self, kernel_addr=""):
461 kernel_name = ""
462
463 if not kernel_addr:
464 kernel_addr = self.builder.parameters.image_addr
465
466 files = [f for f in os.listdir(kernel_addr) if f[0] <> '.']
467 for check_file in files:
468 if check_file.endswith(".bin"):
469 name_splits = check_file.split(".")[0]
470 if self.builder.parameters.kernel_image_type in name_splits.split("-"):
471 kernel_name = check_file
472 break
473
474 return kernel_name
475
476 def show_builded_images_dialog(self, widget, primary_action=""):
477 title = primary_action if primary_action else "Your builded images"
478 dialog = CrumbsDialog(title, self.builder,
479 gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
480 dialog.set_border_width(12)
481
482 label = gtk.Label()
483 label.set_use_markup(True)
484 label.set_alignment(0.0, 0.5)
485 label.set_padding(12,0)
486 if primary_action == "Run image":
487 label.set_markup("<span font_desc='12'>Select the image file you want to run:</span>")
488 elif primary_action == "Deploy image":
489 label.set_markup("<span font_desc='12'>Select the image file you want to deploy:</span>")
490 else:
491 label.set_markup("<span font_desc='12'>Select the image file you want to %s</span>" % primary_action)
492 dialog.vbox.pack_start(label, expand=False, fill=False)
493
494 # filter created images as action attribution (deploy or run)
495 action_attr = ""
496 action_images = []
497 for fileitem in self.image_store:
498 action_attr = fileitem['action_attr']
499 if (action_attr == 'run' and primary_action == "Run image") \
500 or (action_attr == 'deploy' and primary_action == "Deploy image"):
501 action_images.append(fileitem)
502 if (len(action_images) == 0 and primary_action == "Run image"):
503 # if there are no qemu runnable images, let the user choose any of the existing images for custom run
504 action_images = self.image_store
505 # pack the corresponding 'runnable' or 'deploy' radio_buttons, if there has no more than one file.
506 # assume that there does not both have 'deploy' and 'runnable' files in the same building result
507 # in possible as design.
508 curr_row = 0
509 rows = (len(action_images)) if len(action_images) < 10 else 10
510 table = gtk.Table(rows, 10, True)
511 table.set_row_spacings(6)
512 table.set_col_spacing(0, 12)
513 table.set_col_spacing(5, 12)
514
515 sel_parent_btn = None
516 for fileitem in action_images:
517 sel_btn = gtk.RadioButton(sel_parent_btn, fileitem['type'])
518 sel_parent_btn = sel_btn if not sel_parent_btn else sel_parent_btn
519 if curr_row == 0:
520 sel_btn.set_active(True)
521 self.toggled_image = fileitem['name']
522 sel_btn.connect('toggled', self.table_selected_cb, fileitem)
523 if curr_row < 10:
524 table.attach(sel_btn, 0, 4, curr_row, curr_row + 1, xpadding=24)
525 else:
526 table.attach(sel_btn, 5, 9, curr_row - 10, curr_row - 9, xpadding=24)
527 curr_row += 1
528
529 dialog.vbox.pack_start(table, expand=False, fill=False, padding=6)
530
531 button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL)
532 HobAltButton.style_button(button)
533
534 if primary_action:
535 button = dialog.add_button(primary_action, gtk.RESPONSE_YES)
536 HobButton.style_button(button)
537
538 dialog.show_all()
539
540 response = dialog.run()
541 dialog.destroy()
542
543 if response != gtk.RESPONSE_YES:
544 return
545 # perform the primary action on the image selected by the user
546 for fileitem in self.image_store:
547 if fileitem['name'] == self.toggled_image:
548 if (fileitem['action_attr'] == 'run' and primary_action == "Run image"):
549 self.builder.runqemu_image(fileitem['name'], self.sel_kernel)
550 elif (fileitem['action_attr'] == 'deploy' and primary_action == "Deploy image"):
551 self.builder.deploy_image(fileitem['name'])
552 elif (primary_action == "Run image"):
553 self.builder.run_custom_image(fileitem['name'], self.run_script_path)
554
555 def table_selected_cb(self, tbutton, image):
556 image['is_toggled'] = tbutton.get_active()
557 if image['is_toggled']:
558 self.toggled_image = image['name']
559
560 def change_kernel_cb(self, widget):
561 kernel_path = self.builder.show_load_kernel_dialog()
562 if kernel_path and self.kernel_detail:
563 import os.path
564 self.sel_kernel = os.path.basename(kernel_path)
565 self.kernel_detail.update_line_widgets("Kernel: ", self.sel_kernel);
566
567 def change_run_script_cb(self, widget):
568 self.run_script_path = self.builder.show_load_run_script_dialog()
569 if self.run_script_path and self.run_script_detail:
570 import os.path
571 self.sel_run_script = os.path.basename(self.run_script_path)
572 self.run_script_detail.update_line_widgets("Run script: ", self.run_script_path)
573
574 def create_bottom_buttons(self, buttonlist, image_name):
575 # Create the buttons at the bottom
576 created = False
577 packed = False
578 self.button_ids = {}
579 is_runnable = False
580
581 # create button "Deploy image"
582 name = "Deploy image"
583 if name in buttonlist and self.test_deployable(image_name):
584 deploy_button = HobButton('Deploy image')
585 #deploy_button.set_size_request(205, 49)
586 deploy_button.set_tooltip_text("Burn a live image to a USB drive or flash memory")
587 deploy_button.set_flags(gtk.CAN_DEFAULT)
588 button_id = deploy_button.connect("clicked", self.deploy_button_clicked_cb)
589 self.button_ids[button_id] = deploy_button
590 self.details_bottom_buttons.pack_end(deploy_button, expand=False, fill=False)
591 created = True
592 packed = True
593
594 name = "Run image"
595 if name in buttonlist:
596 name = "Run qemu image"
597 is_runnable = True
598 if not (self.test_type_runnable(image_name) and self.test_mach_runnable(image_name)):
599 name = "Run custom image"
600 is_runnable = False
601 if created == True:
602 # separator
603 #label = gtk.Label(" or ")
604 #self.details_bottom_buttons.pack_end(label, expand=False, fill=False)
605
606 # create button "Run image"
607 run_button = HobAltButton(name)
608 else:
609 # create button "Run image" as the primary button
610 run_button = HobButton(name)
611 #run_button.set_size_request(205, 49)
612 run_button.set_flags(gtk.CAN_DEFAULT)
613 packed = True
614 if is_runnable:
615 run_button.set_tooltip_text("Start up an image with qemu emulator")
616 else:
617 run_button.set_tooltip_text("Start up an image with custom simulator")
618 button_id = run_button.connect("clicked", self.run_button_clicked_cb)
619 self.button_ids[button_id] = run_button
620 self.details_bottom_buttons.pack_end(run_button, expand=False, fill=False)
621 created = True
622
623 name = "Save image recipe"
624 if name in buttonlist and self.builder.recipe_model.is_custom_image():
625 save_button = HobAltButton("Save image recipe")
626 save_button.set_tooltip_text("Keep your changes saving them as an image recipe")
627 save_button.set_sensitive(not self.image_saved)
628 button_id = save_button.connect("clicked", self.save_button_clicked_cb)
629 self.button_ids[button_id] = save_button
630 self.details_bottom_buttons.pack_end(save_button, expand=False, fill=False)
631
632 name = "Build new image"
633 if name in buttonlist:
634 # create button "Build new image"
635 if packed:
636 build_new_button = HobAltButton("Build new image")
637 else:
638 build_new_button = HobButton("Build new image")
639 build_new_button.set_flags(gtk.CAN_DEFAULT)
640 #build_new_button.set_size_request(205, 49)
641 self.details_bottom_buttons.pack_end(build_new_button, expand=False, fill=False)
642 build_new_button.set_tooltip_text("Create a new image from scratch")
643 button_id = build_new_button.connect("clicked", self.build_new_button_clicked_cb)
644 self.button_ids[button_id] = build_new_button
645
646 return is_runnable
647
648 def deploy_button_clicked_cb(self, button):
649 if self.toggled_image:
650 if self.num_toggled > 1:
651 self.set_sensitive(False)
652 self.show_builded_images_dialog(None, "Deploy image")
653 self.set_sensitive(True)
654 else:
655 self.builder.deploy_image(self.toggled_image)
656
657 def run_button_clicked_cb(self, button):
658 if self.toggled_image:
659 if self.num_toggled > 1:
660 self.set_sensitive(False)
661 self.show_builded_images_dialog(None, "Run image")
662 self.set_sensitive(True)
663 else:
664 if self.is_runnable:
665 self.builder.runqemu_image(self.toggled_image, self.sel_kernel)
666 else:
667 self.builder.run_custom_image(self.toggled_image, self.run_script_path)
668
669 def save_button_clicked_cb(self, button):
670 topdir = self.builder.get_topdir()
671 images_dir = topdir + "/recipes/images/custom/"
672 self.builder.ensure_dir(images_dir)
673
674 self.name_field_template = self.builder.image_configuration_page.custom_image_selected
675 if self.name_field_template:
676 image_path = self.builder.recipe_model.pn_path[self.name_field_template]
677 image_iter = self.builder.recipe_model.get_iter(image_path)
678 self.description_field_template = self.builder.recipe_model.get_value(image_iter, self.builder.recipe_model.COL_DESC)
679 else:
680 self.name_field_template = ""
681
682 dialog = SaveImageDialog(images_dir, self.name_field_template, self.description_field_template,
683 "Save image recipe", self.builder, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
684 response = dialog.run()
685 dialog.destroy()
686
687 def build_new_button_clicked_cb(self, button):
688 self.builder.initiate_new_build_async()
689
690 def edit_config_button_clicked_cb(self, button):
691 self.builder.show_configuration()
692
693 def edit_packages_button_clicked_cb(self, button):
694 self.builder.show_packages()
695
696 def my_images_button_clicked_cb(self, button):
697 self.builder.show_load_my_images_dialog()
698
699 def settings_button_clicked_cb(self, button):
700 # Create an advanced settings dialog
701 response, settings_changed = self.builder.show_simple_settings_dialog()
702 if not response:
703 return
704 if settings_changed:
705 self.builder.reparse_post_adv_settings()