def bake_clicked_cb(self, button): rep = self.model.get_build_rep() if not rep.base_image: lbl = "<b>Build only packages?</b>\n\nAn image has not been selected, so only the selected packages will be built." dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button("Build", gtk.RESPONSE_YES) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_CANCEL: return else: # TODO: show a confirmation dialog ? if not self.save_path: import tempfile, datetime image_name = "hob-%s-variant-%s.bb" % (rep.base_image, datetime.date.today().isoformat()) image_dir = os.path.join(tempfile.gettempdir(), 'hob-images') bb.utils.mkdirhier(image_dir) recipepath = os.path.join(image_dir, image_name) else: recipepath = self.save_path rep.writeRecipe(recipepath, self.model) # In the case where we saved the file for the purpose of building # it we should then delete it so that the users workspace doesn't # contain files they haven't explicitly saved there. if not self.save_path: self.files_to_clean.append(recipepath) self.handler.queue_image_recipe_path(recipepath) self.handler.build_packages(rep.allpkgs.split(" ")) self.nb.set_current_page(1)
def toggle_package(self, path, model, image=False): inc = model[path][self.model.COL_INC] # Warn user before removing included packages if inc: pn = model[path][self.model.COL_NAME] revdeps = self.model.find_reverse_depends(pn) if len(revdeps): lbl = "<b>Remove %s?</b>\n\nThis action cannot be undone and all packages which depend on this will be removed\nPackages which depend on %s include %s." % (pn, pn, ", ".join(revdeps).rstrip(",")) else: lbl = "<b>Remove %s?</b>\n\nThis action cannot be undone." % pn dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button("Remove", gtk.RESPONSE_OK) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_CANCEL: return self.set_busy_cursor() # Convert path to path in original model opath = model.convert_path_to_child_path(path) # This is a potentially length call which can block the # main loop, therefore do the work in an idle func to keep # the UI responsive glib.idle_add(self.toggle_package_idle_cb, opath, image) self.dirty = True
def info_button_clicked_cb(self, button): info = "We cannot accurately predict the image contents before they are built so instead a best" info = info + " attempt at estimating what the image will contain is listed." dialog = CrumbsDialog(self, info, gtk.STOCK_DIALOG_INFO) dialog.add_buttons(gtk.STOCK_CLOSE, gtk.RESPONSE_OK) resp = dialog.run() dialog.destroy()
def build_complete_cb(self, running_build): # Have the handler process BB events again self.handler.building = False self.stopping = False self.back.connect("clicked", self.back_button_clicked_cb) self.back.set_sensitive(True) self.cancel.set_sensitive(False) for f in self.files_to_clean: try: os.remove(f) except OSError: pass self.files_to_clean.remove(f) self.files_to_clean = [] lbl = "<b>Build completed</b>\n\nClick 'Edit Image' to start another build or 'View Messages' to view the messages output during the build." if self.handler.build_type == "image" and self.build_succeeded: deploy = self.handler.get_image_deploy_dir() lbl = lbl + "\n<a href=\"file://%s\" title=\"%s\">Browse folder of built images</a>." % (deploy, deploy) dialog = CrumbsDialog(self, lbl) dialog.add_button("View Messages", gtk.RESPONSE_CANCEL) dialog.add_button("Edit Image", gtk.RESPONSE_OK) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_OK: self.toggle_createview()
def cancel_build(self, button): if self.stopping: lbl = "<b>Force Stop build?</b>\nYou've already selected Stop once," lbl = lbl + " would you like to 'Force Stop' the build?\n\n" lbl = lbl + "This will stop the build as quickly as possible but may" lbl = lbl + " well leave your build directory in an unusable state" lbl = lbl + " that requires manual steps to fix.\n" dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button("Force Stop", gtk.RESPONSE_YES) else: lbl = "<b>Stop build?</b>\n\nAre you sure you want to stop this" lbl = lbl + " build?\n\n'Force Stop' will stop the build as quickly as" lbl = lbl + " possible but may well leave your build directory in an" lbl = lbl + " unusable state that requires manual steps to fix.\n\n" lbl = lbl + "'Stop' will stop the build as soon as all in" lbl = lbl + " progress build tasks are finished. However if a" lbl = lbl + " lengthy compilation phase is in progress this may take" lbl = lbl + " some time." dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button("Stop", gtk.RESPONSE_OK) dialog.add_button("Force Stop", gtk.RESPONSE_YES) response = dialog.run() dialog.destroy() if response != gtk.RESPONSE_CANCEL: self.stopping = True if response == gtk.RESPONSE_OK: self.handler.cancel_build() elif response == gtk.RESPONSE_YES: self.handler.cancel_build(True)
def build_complete_cb(self, running_build): # Have the handler process BB events again self.handler.building = False self.stopping = False self.back.connect("clicked", self.back_button_clicked_cb) self.back.set_sensitive(True) self.cancel.set_sensitive(False) for f in self.files_to_clean: try: os.remove(f) except OSError: pass self.files_to_clean.remove(f) self.files_to_clean = [] lbl = "<b>Build completed</b>\n\nClick 'Edit Image' to start another build or 'View Messages' to view the messages output during the build." if self.handler.build_type == "image" and self.build_succeeded: deploy = self.handler.get_image_deploy_dir() lbl = lbl + "\n<a href=\"file://%s\" title=\"%s\">Browse folder of built images</a>." % ( deploy, deploy) dialog = CrumbsDialog(self, lbl) dialog.add_button("View Messages", gtk.RESPONSE_CANCEL) dialog.add_button("Edit Image", gtk.RESPONSE_OK) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_OK: self.toggle_createview()
def reset_clicked_cb(self, button): lbl = "<b>Reset your selections?</b>\n\nAny new changes you have made will be lost" dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button("Reset", gtk.RESPONSE_OK) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_OK: self.reset_build() return
def fatal_error_cb(self, handler, errormsg, phase): lbl = "<b>Error!</b>\nThere was an unrecoverable error during the" lbl = lbl + " <i>%s</i> phase of BitBake. This must be" % phase lbl = lbl + " rectified before the GUI will function. The error" lbl = lbl + " message which which caused this is:\n\n\"%s\"" % errormsg dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_ERROR) dialog.add_button("Exit", gtk.RESPONSE_OK) response = dialog.run() dialog.destroy() self.set_busy_cursor(False) gtk.main_quit()
def cancel_build(self, button): lbl = "<b>Stop build?</b>\n\nAre you sure you want to stop this build?" dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button("Stop", gtk.RESPONSE_OK) dialog.add_button("Force Stop", gtk.RESPONSE_YES) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_OK: self.handler.cancel_build() elif response == gtk.RESPONSE_YES: self.handler.cancel_build(True)
def quit(self): if self.dirty and len(self.model.contents): question = "Would you like to save your customisations?" dialog = CrumbsDialog(self, question, gtk.STOCK_DIALOG_WARNING) dialog.add_buttons(gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES) resp = dialog.run() dialog.destroy() if resp == gtk.RESPONSE_YES: if not self.save_path: self.get_save_path() if self.save_path: self.save_recipe_file() rep = self.model.get_build_rep() rep.writeRecipe(self.save_path, self.model) gtk.main_quit()
def build_complete_cb(self, running_build): self.back.connect("clicked", self.back_button_clicked_cb) self.back.set_sensitive(True) self.cancel.set_sensitive(False) for f in self.files_to_clean: os.remove(f) lbl = "<b>Build completed</b>\n\nClick 'Edit Image' to start another build or 'View Log' to view the build log." if self.handler.building == "image": deploy = self.handler.get_image_deploy_dir() lbl = lbl + "\n<a href=\"file://%s\" title=\"%s\">Browse folder of built images</a>." % (deploy, deploy) dialog = CrumbsDialog(self, lbl) dialog.add_button("View Log", gtk.RESPONSE_CANCEL) dialog.add_button("Edit Image", gtk.RESPONSE_OK) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_OK: self.toggle_createview()
def quit(self): if self.dirty and len(self.model.contents): question = "Would you like to save your customisations?" dialog = CrumbsDialog(self, question, gtk.STOCK_DIALOG_WARNING) dialog.add_buttons(gtk.STOCK_NO, gtk.RESPONSE_NO, gtk.STOCK_YES, gtk.RESPONSE_YES) resp = dialog.run() dialog.destroy() if resp == gtk.RESPONSE_YES: if not self.save_path: self.get_save_path() if self.save_path: self.save_recipe_file() rep = self.model.get_build_rep() rep.writeRecipe(self.save_path, self.model) # Prevent the busy cursor being shown after hob exits if quit is called # whilst the busy cursor is set self.set_busy_cursor(False) self.handler.remove_temp_dir() gtk.main_quit()
def conf_error(parent, lbl): dialog = CrumbsDialog(parent, lbl) dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) response = dialog.run() dialog.destroy()
def show_builded_images_dialog(self, widget, primary_action=""): title = primary_action if primary_action else "Your builded images" dialog = CrumbsDialog( title, self.builder, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) dialog.set_border_width(12) label = gtk.Label() label.set_use_markup(True) label.set_alignment(0.0, 0.5) label.set_padding(12, 0) if primary_action == "Run image": label.set_markup( "<span font_desc='12'>Select the image file you want to run:</span>" ) elif primary_action == "Deploy image": label.set_markup( "<span font_desc='12'>Select the image file you want to deploy:</span>" ) else: label.set_markup( "<span font_desc='12'>Select the image file you want to %s</span>" % primary_action) dialog.vbox.pack_start(label, expand=False, fill=False) # filter created images as action attribution (deploy or run) action_attr = "" action_images = [] for fileitem in self.image_store: action_attr = fileitem['action_attr'] if (action_attr == 'run' and primary_action == "Run image") \ or (action_attr == 'deploy' and primary_action == "Deploy image"): action_images.append(fileitem) # pack the corresponding 'runnable' or 'deploy' radio_buttons, if there has no more than one file. # assume that there does not both have 'deploy' and 'runnable' files in the same building result # in possible as design. curr_row = 0 rows = (len(action_images)) if len(action_images) < 10 else 10 table = gtk.Table(rows, 10, True) table.set_row_spacings(6) table.set_col_spacing(0, 12) table.set_col_spacing(5, 12) sel_parent_btn = None for fileitem in action_images: sel_btn = gtk.RadioButton(sel_parent_btn, fileitem['type']) sel_parent_btn = sel_btn if not sel_parent_btn else sel_parent_btn sel_btn.set_active(fileitem['is_toggled']) sel_btn.connect('toggled', self.table_selected_cb, fileitem) if curr_row < 10: table.attach(sel_btn, 0, 4, curr_row, curr_row + 1, xpadding=24) else: table.attach(sel_btn, 5, 9, curr_row - 10, curr_row - 9, xpadding=24) curr_row += 1 dialog.vbox.pack_start(table, expand=False, fill=False, padding=6) button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL) HobAltButton.style_button(button) if primary_action: button = dialog.add_button(primary_action, gtk.RESPONSE_YES) HobButton.style_button(button) dialog.show_all() response = dialog.run() dialog.destroy() if response != gtk.RESPONSE_YES: return for fileitem in self.image_store: if fileitem['is_toggled']: if fileitem['action_attr'] == 'run': self.builder.runqemu_image(fileitem['name'], self.sel_kernel) elif fileitem['action_attr'] == 'deploy': self.builder.deploy_image(fileitem['name'])
def bake_clicked_cb(self, button): build_image = True rep = self.model.get_build_rep() # If no base image and no user selected packages don't build anything if not self.selected_image and not len(rep.userpkgs): lbl = "<b>No selections made</b>\nYou have not made any selections" lbl = lbl + " so there isn't anything to bake at this time." dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) dialog.run() dialog.destroy() return # Else if no base image, ask whether to just build packages or whether # to build a rootfs with the selected packages in elif not self.selected_image: lbl = "<b>Build empty image or only packages?</b>\nA base image" lbl = lbl + " has not been selected.\n\'Empty image' will build" lbl = lbl + " an image with only the selected packages as its" lbl = lbl + " contents.\n'Packages Only' will build only the" lbl = lbl + " selected packages, no image will be created" dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button("Empty Image", gtk.RESPONSE_OK) dialog.add_button("Packages Only", gtk.RESPONSE_YES) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_CANCEL: return elif response == gtk.RESPONSE_YES: build_image = False elif response == gtk.RESPONSE_OK: rep.base_image = "empty" # Ensure at least one value is set in IMAGE_FSTYPES. have_selected_fstype = False if (len(self.prefs.selected_image_types) and len(self.prefs.selected_image_types[0])): have_selected_fstype = True if build_image and not have_selected_fstype: lbl = "<b>No image output type selected</b>\nThere is no image output" lbl = lbl + " selected for the build. Please set an output image type" lbl = lbl + " in the preferences (Edit -> Preferences)." dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) dialog.run() dialog.destroy() return elif build_image: self.handler.make_temp_dir() recipepath = self.handler.get_temp_recipe_path(rep.base_image) image_name = recipepath.rstrip(".bb") path, sep, image_name = image_name.rpartition("/") image = [] image.append(image_name) rep.writeRecipe(recipepath, self.model) # In the case where we saved the file for the purpose of building # it we should then delete it so that the users workspace doesn't # contain files they haven't explicitly saved there. if not self.save_path: self.files_to_clean.append(recipepath) self.handler.build_targets(image, self.configurator) else: self.handler.build_targets(self.model.get_selected_pn(), self.configurator, "packages") # Disable parts of the menu which shouldn't be used whilst building self.set_menus_sensitive(False) self.nb.set_current_page(1)
def show_builded_images_dialog(self, widget, primary_action=""): title = primary_action if primary_action else "Your builded images" dialog = CrumbsDialog(title, self.builder, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) dialog.set_border_width(12) label = gtk.Label() label.set_use_markup(True) label.set_alignment(0.0, 0.5) label.set_markup("<span font_desc='12'>Select the image file you want to %s</span>" % primary_action) dialog.vbox.pack_start(label, expand=False, fill=False) # filter created images as action attribution (deploy or run) action_attr = "" action_images = [] for fileitem in self.image_store: action_attr = fileitem['action_attr'] if (action_attr == 'run' and primary_action == "Run image") \ or (action_attr == 'deploy' and primary_action == "Deploy image"): action_images.append(fileitem) # pack the corresponding 'runnable' or 'deploy' radio_buttons, if there has no more than one file. # assume that there does not both have 'deploy' and 'runnable' files in the same building result # in possible as design. curr_row = 0 rows = (len(action_images)) if len(action_images) < 10 else 10 table = gtk.Table(rows, 10, True) table.set_row_spacings(6) table.set_col_spacing(0, 12) table.set_col_spacing(5, 12) sel_parent_btn = None for fileitem in action_images: sel_btn = gtk.RadioButton(sel_parent_btn, fileitem['type']) sel_parent_btn = sel_btn if not sel_parent_btn else sel_parent_btn sel_btn.set_active(fileitem['is_toggled']) sel_btn.connect('toggled', self.table_selected_cb, fileitem) if curr_row < 10: table.attach(sel_btn, 2, 5, curr_row, curr_row + 1) else: table.attach(sel_btn, 7, 10, curr_row - 10, curr_row - 9) curr_row += 1 dialog.vbox.pack_start(table, expand=False, fill=False, padding = 6) button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL) HobAltButton.style_button(button) if primary_action: button = dialog.add_button(primary_action, gtk.RESPONSE_YES) HobButton.style_button(button) dialog.show_all() response = dialog.run() dialog.destroy() if response != gtk.RESPONSE_YES: return for fileitem in self.image_store: if fileitem['is_toggled']: if fileitem['action_attr'] == 'run': self.builder.runqemu_image(fileitem['name'], self.sel_kernel) elif fileitem['action_attr'] == 'deploy': self.builder.deploy_image(fileitem['name'])