diff options
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/builder.py')
| -rwxr-xr-x | bitbake/lib/bb/ui/crumbs/builder.py | 873 | 
1 files changed, 873 insertions, 0 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/builder.py b/bitbake/lib/bb/ui/crumbs/builder.py new file mode 100755 index 0000000000..007167337f --- /dev/null +++ b/bitbake/lib/bb/ui/crumbs/builder.py  | |||
| @@ -0,0 +1,873 @@ | |||
| 1 | #!/usr/bin/env python | ||
| 2 | # | ||
| 3 | # BitBake Graphical GTK User Interface | ||
| 4 | # | ||
| 5 | # Copyright (C) 2011-2012 Intel Corporation | ||
| 6 | # | ||
| 7 | # Authored by Joshua Lock <josh@linux.intel.com> | ||
| 8 | # Authored by Dongxiao Xu <dongxiao.xu@intel.com> | ||
| 9 | # Authored by Shane Wang <shane.wang@intel.com> | ||
| 10 | # | ||
| 11 | # This program is free software; you can redistribute it and/or modify | ||
| 12 | # it under the terms of the GNU General Public License version 2 as | ||
| 13 | # published by the Free Software Foundation. | ||
| 14 | # | ||
| 15 | # This program is distributed in the hope that it will be useful, | ||
| 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | # GNU General Public License for more details. | ||
| 19 | # | ||
| 20 | # You should have received a copy of the GNU General Public License along | ||
| 21 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
| 22 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 23 | |||
| 24 | import gtk | ||
| 25 | import copy | ||
| 26 | import os | ||
| 27 | import subprocess | ||
| 28 | import shlex | ||
| 29 | from bb.ui.crumbs.template import TemplateMgr | ||
| 30 | from bb.ui.crumbs.imageconfigurationpage import ImageConfigurationPage | ||
| 31 | from bb.ui.crumbs.recipeselectionpage import RecipeSelectionPage | ||
| 32 | from bb.ui.crumbs.packageselectionpage import PackageSelectionPage | ||
| 33 | from bb.ui.crumbs.builddetailspage import BuildDetailsPage | ||
| 34 | from bb.ui.crumbs.imagedetailspage import ImageDetailsPage | ||
| 35 | from bb.ui.crumbs.hobwidget import hwc | ||
| 36 | from bb.ui.crumbs.hig import CrumbsDialog, BinbDialog, \ | ||
| 37 | AdvancedSettingDialog, LayerSelectionDialog, \ | ||
| 38 | DeployImageDialog, ImageSelectionDialog | ||
| 39 | |||
| 40 | class Configuration: | ||
| 41 | '''Represents the data structure of configuration.''' | ||
| 42 | |||
| 43 | def __init__(self, params): | ||
| 44 | # Settings | ||
| 45 | self.curr_mach = "" | ||
| 46 | self.curr_distro = params["distro"] | ||
| 47 | self.dldir = params["dldir"] | ||
| 48 | self.sstatedir = params["sstatedir"] | ||
| 49 | self.sstatemirror = params["sstatemirror"] | ||
| 50 | self.pmake = params["pmake"] | ||
| 51 | self.bbthread = params["bbthread"] | ||
| 52 | self.curr_package_format = " ".join(params["pclass"].split("package_")).strip() | ||
| 53 | self.image_rootfs_size = params["image_rootfs_size"] | ||
| 54 | self.image_extra_size = params["image_extra_size"] | ||
| 55 | self.image_overhead_factor = params['image_overhead_factor'] | ||
| 56 | self.incompat_license = params["incompat_license"] | ||
| 57 | self.curr_sdk_machine = params["sdk_machine"] | ||
| 58 | self.extra_setting = {} | ||
| 59 | self.toolchain_build = False | ||
| 60 | self.image_fstypes = params["image_fstypes"].split() | ||
| 61 | # bblayers.conf | ||
| 62 | self.layers = params["layer"].split() | ||
| 63 | # image/recipes/packages | ||
| 64 | self.selected_image = None | ||
| 65 | self.selected_recipes = [] | ||
| 66 | self.selected_packages = [] | ||
| 67 | |||
| 68 | def load(self, template): | ||
| 69 | self.curr_mach = template.getVar("MACHINE") | ||
| 70 | self.curr_package_format = " ".join(template.getVar("PACKAGE_CLASSES").split("package_")).strip() | ||
| 71 | self.curr_distro = template.getVar("DISTRO") | ||
| 72 | self.dldir = template.getVar("DL_DIR") | ||
| 73 | self.sstatedir = template.getVar("SSTATE_DIR") | ||
| 74 | self.sstatemirror = template.getVar("SSTATE_MIRROR") | ||
| 75 | self.pmake = int(template.getVar("PARALLEL_MAKE").split()[1]) | ||
| 76 | self.bbthread = int(template.getVar("BB_NUMBER_THREAD")) | ||
| 77 | self.image_rootfs_size = int(template.getVar("IMAGE_ROOTFS_SIZE")) | ||
| 78 | self.image_extra_size = int(template.getVar("IMAGE_EXTRA_SPACE")) | ||
| 79 | # image_overhead_factor is read-only. | ||
| 80 | self.incompat_license = template.getVar("INCOMPATIBLE_LICENSE") | ||
| 81 | self.curr_sdk_machine = template.getVar("SDKMACHINE") | ||
| 82 | self.extra_setting = eval(template.getVar("EXTRA_SETTING")) | ||
| 83 | self.toolchain_build = eval(template.getVar("TOOLCHAIN_BUILD")) | ||
| 84 | self.image_fstypes = template.getVar("IMAGE_FSTYPES").split() | ||
| 85 | # bblayers.conf | ||
| 86 | self.layers = template.getVar("BBLAYERS").split() | ||
| 87 | # image/recipes/packages | ||
| 88 | self.selected_image = template.getVar("__SELECTED_IMAGE__") | ||
| 89 | self.selected_recipes = template.getVar("DEPENDS").split() | ||
| 90 | self.selected_packages = template.getVar("IMAGE_INSTALL").split() | ||
| 91 | |||
| 92 | def save(self, template, filename): | ||
| 93 | # bblayers.conf | ||
| 94 | template.setVar("BBLAYERS", " ".join(self.layers)) | ||
| 95 | # local.conf | ||
| 96 | template.setVar("MACHINE", self.curr_mach) | ||
| 97 | template.setVar("DISTRO", self.curr_distro) | ||
| 98 | template.setVar("DL_DIR", self.dldir) | ||
| 99 | template.setVar("SSTATE_DIR", self.sstatedir) | ||
| 100 | template.setVar("SSTATE_MIRROR", self.sstatemirror) | ||
| 101 | template.setVar("PARALLEL_MAKE", "-j %s" % self.pmake) | ||
| 102 | template.setVar("BB_NUMBER_THREAD", self.bbthread) | ||
| 103 | template.setVar("PACKAGE_CLASSES", " ".join(["package_" + i for i in self.curr_package_format.split()])) | ||
| 104 | template.setVar("IMAGE_ROOTFS_SIZE", self.image_rootfs_size) | ||
| 105 | template.setVar("IMAGE_EXTRA_SPACE", self.image_extra_size) | ||
| 106 | template.setVar("INCOMPATIBLE_LICENSE", self.incompat_license) | ||
| 107 | template.setVar("SDKMACHINE", self.curr_sdk_machine) | ||
| 108 | template.setVar("EXTRA_SETTING", self.extra_setting) | ||
| 109 | template.setVar("TOOLCHAIN_BUILD", self.toolchain_build) | ||
| 110 | template.setVar("IMAGE_FSTYPES", " ".join(self.image_fstypes).lstrip(" ")) | ||
| 111 | # image/recipes/packages | ||
| 112 | self.selected_image = filename | ||
| 113 | template.setVar("__SELECTED_IMAGE__", self.selected_image) | ||
| 114 | template.setVar("DEPENDS", self.selected_recipes) | ||
| 115 | template.setVar("IMAGE_INSTALL", self.selected_packages) | ||
| 116 | |||
| 117 | class Parameters: | ||
| 118 | '''Represents other variables like available machines, etc.''' | ||
| 119 | |||
| 120 | def __init__(self, params): | ||
| 121 | # Variables | ||
| 122 | self.all_machines = [] | ||
| 123 | self.all_package_formats = [] | ||
| 124 | self.all_distros = [] | ||
| 125 | self.all_sdk_machines = [] | ||
| 126 | self.max_threads = params["max_threads"] | ||
| 127 | self.all_layers = [] | ||
| 128 | self.core_base = params["core_base"] | ||
| 129 | self.image_names = [] | ||
| 130 | self.image_addr = params["image_addr"] | ||
| 131 | self.image_types = params["image_types"].split() | ||
| 132 | |||
| 133 | class Builder(gtk.Window): | ||
| 134 | |||
| 135 | (MACHINE_SELECTION, | ||
| 136 | LAYER_CHANGED, | ||
| 137 | RCPPKGINFO_POPULATING, | ||
| 138 | RCPPKGINFO_POPULATED, | ||
| 139 | RECIPE_SELECTION, | ||
| 140 | PACKAGE_GENERATING, | ||
| 141 | PACKAGE_GENERATED, | ||
| 142 | PACKAGE_SELECTION, | ||
| 143 | FAST_IMAGE_GENERATING, | ||
| 144 | IMAGE_GENERATING, | ||
| 145 | IMAGE_GENERATED, | ||
| 146 | MY_IMAGE_OPENED, | ||
| 147 | BACK, | ||
| 148 | END_NOOP) = range(14) | ||
| 149 | |||
| 150 | (IMAGE_CONFIGURATION, | ||
| 151 | RECIPE_DETAILS, | ||
| 152 | BUILD_DETAILS, | ||
| 153 | PACKAGE_DETAILS, | ||
| 154 | IMAGE_DETAILS, | ||
| 155 | END_TAB) = range(6) | ||
| 156 | |||
| 157 | __step2page__ = { | ||
| 158 | MACHINE_SELECTION : IMAGE_CONFIGURATION, | ||
| 159 | LAYER_CHANGED : IMAGE_CONFIGURATION, | ||
| 160 | RCPPKGINFO_POPULATING : IMAGE_CONFIGURATION, | ||
| 161 | RCPPKGINFO_POPULATED : IMAGE_CONFIGURATION, | ||
| 162 | RECIPE_SELECTION : RECIPE_DETAILS, | ||
| 163 | PACKAGE_GENERATING : BUILD_DETAILS, | ||
| 164 | PACKAGE_GENERATED : PACKAGE_DETAILS, | ||
| 165 | PACKAGE_SELECTION : PACKAGE_DETAILS, | ||
| 166 | FAST_IMAGE_GENERATING : BUILD_DETAILS, | ||
| 167 | IMAGE_GENERATING : BUILD_DETAILS, | ||
| 168 | IMAGE_GENERATED : IMAGE_DETAILS, | ||
| 169 | MY_IMAGE_OPENED : IMAGE_DETAILS, | ||
| 170 | END_NOOP : None, | ||
| 171 | } | ||
| 172 | |||
| 173 | def __init__(self, hobHandler, recipe_model, package_model): | ||
| 174 | super(Builder, self).__init__() | ||
| 175 | |||
| 176 | # handler | ||
| 177 | self.handler = hobHandler | ||
| 178 | |||
| 179 | self.template = None | ||
| 180 | |||
| 181 | # settings | ||
| 182 | params = self.handler.get_parameters() | ||
| 183 | self.configuration = Configuration(params) | ||
| 184 | self.parameters = Parameters(params) | ||
| 185 | |||
| 186 | # build step | ||
| 187 | self.current_step = None | ||
| 188 | self.previous_step = None | ||
| 189 | |||
| 190 | self.stopping = False | ||
| 191 | self.build_succeeded = True | ||
| 192 | |||
| 193 | # recipe model and package model | ||
| 194 | self.recipe_model = recipe_model | ||
| 195 | self.package_model = package_model | ||
| 196 | |||
| 197 | # create visual elements | ||
| 198 | self.create_visual_elements() | ||
| 199 | |||
| 200 | # connect the signals to functions | ||
| 201 | #self.connect("configure-event", self.resize_window_cb) | ||
| 202 | self.connect("delete-event", self.destroy_window_cb) | ||
| 203 | self.recipe_model.connect ("recipe-selection-changed", self.recipelist_changed_cb) | ||
| 204 | self.package_model.connect("package-selection-changed", self.packagelist_changed_cb) | ||
| 205 | self.recipe_model.connect ("recipelist-populated", self.recipelist_populated_cb) | ||
| 206 | self.package_model.connect("packagelist-populated", self.packagelist_populated_cb) | ||
| 207 | self.handler.connect("config-updated", self.handler_config_updated_cb) | ||
| 208 | self.handler.connect("package-formats-updated", self.handler_package_formats_updated_cb) | ||
| 209 | self.handler.connect("layers-updated", self.handler_layers_updated_cb) | ||
| 210 | self.handler.connect("parsing-started", self.handler_parsing_started_cb) | ||
| 211 | self.handler.connect("parsing", self.handler_parsing_cb) | ||
| 212 | self.handler.connect("parsing-completed", self.handler_parsing_completed_cb) | ||
| 213 | self.handler.build.connect("build-started", self.handler_build_started_cb) | ||
| 214 | self.handler.build.connect("build-succeeded", self.handler_build_succeeded_cb) | ||
| 215 | self.handler.build.connect("build-failed", self.handler_build_failed_cb) | ||
| 216 | self.handler.build.connect("task-started", self.handler_task_started_cb) | ||
| 217 | self.handler.connect("generating-data", self.handler_generating_data_cb) | ||
| 218 | self.handler.connect("data-generated", self.handler_data_generated_cb) | ||
| 219 | self.handler.connect("command-succeeded", self.handler_command_succeeded_cb) | ||
| 220 | self.handler.connect("command-failed", self.handler_command_failed_cb) | ||
| 221 | |||
| 222 | self.switch_page(self.MACHINE_SELECTION) | ||
| 223 | |||
| 224 | def create_visual_elements(self): | ||
| 225 | self.set_title("HOB -- Image Creator") | ||
| 226 | self.set_icon_name("applications-development") | ||
| 227 | self.set_position(gtk.WIN_POS_CENTER_ALWAYS) | ||
| 228 | self.set_resizable(True) | ||
| 229 | window_width = self.get_screen().get_width() | ||
| 230 | window_height = self.get_screen().get_height() | ||
| 231 | if window_width >= hwc.MAIN_WIN_WIDTH: | ||
| 232 | window_width = hwc.MAIN_WIN_WIDTH | ||
| 233 | window_height = hwc.MAIN_WIN_HEIGHT | ||
| 234 | else: | ||
| 235 | lbl = "<b>Screen dimension mismatched</b>\nfor better usability and visual effects," | ||
| 236 | lbl = lbl + " the screen dimension should be 1024x768 or above." | ||
| 237 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 238 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 239 | dialog.run() | ||
| 240 | dialog.destroy() | ||
| 241 | self.set_size_request(window_width, window_height) | ||
| 242 | |||
| 243 | self.vbox = gtk.VBox(False, 0) | ||
| 244 | self.vbox.set_border_width(0) | ||
| 245 | self.add(self.vbox) | ||
| 246 | |||
| 247 | # create pages | ||
| 248 | self.image_configuration_page = ImageConfigurationPage(self) | ||
| 249 | self.recipe_details_page = RecipeSelectionPage(self) | ||
| 250 | self.build_details_page = BuildDetailsPage(self) | ||
| 251 | self.package_details_page = PackageSelectionPage(self) | ||
| 252 | self.image_details_page = ImageDetailsPage(self) | ||
| 253 | |||
| 254 | self.nb = gtk.Notebook() | ||
| 255 | self.nb.set_show_tabs(False) | ||
| 256 | self.nb.insert_page(self.image_configuration_page, None, self.IMAGE_CONFIGURATION) | ||
| 257 | self.nb.insert_page(self.recipe_details_page, None, self.RECIPE_DETAILS) | ||
| 258 | self.nb.insert_page(self.build_details_page, None, self.BUILD_DETAILS) | ||
| 259 | self.nb.insert_page(self.package_details_page, None, self.PACKAGE_DETAILS) | ||
| 260 | self.nb.insert_page(self.image_details_page, None, self.IMAGE_DETAILS) | ||
| 261 | self.vbox.pack_start(self.nb, expand=True, fill=True) | ||
| 262 | |||
| 263 | self.show_all() | ||
| 264 | self.nb.set_current_page(0) | ||
| 265 | |||
| 266 | def get_split_model(self): | ||
| 267 | return self.handler.split_model | ||
| 268 | |||
| 269 | def load_template(self, path): | ||
| 270 | self.template = TemplateMgr() | ||
| 271 | self.template.load(path) | ||
| 272 | self.configuration.load(self.template) | ||
| 273 | |||
| 274 | if self.get_split_model(): | ||
| 275 | if not set(self.configuration.layers) <= set(self.parameters.all_layers): | ||
| 276 | return False | ||
| 277 | else: | ||
| 278 | for layer in self.configuration.layers: | ||
| 279 | if not os.path.exists(layer+'/conf/layer.conf'): | ||
| 280 | return False | ||
| 281 | |||
| 282 | self.switch_page(self.LAYER_CHANGED) | ||
| 283 | |||
| 284 | self.template.destroy() | ||
| 285 | self.template = None | ||
| 286 | |||
| 287 | def save_template(self, path): | ||
| 288 | if path.rfind("/") == -1: | ||
| 289 | filename = "default" | ||
| 290 | path = "." | ||
| 291 | else: | ||
| 292 | filename = path[path.rfind("/") + 1:len(path)] | ||
| 293 | path = path[0:path.rfind("/")] | ||
| 294 | |||
| 295 | self.template = TemplateMgr() | ||
| 296 | self.template.open(filename, path) | ||
| 297 | self.configuration.save(self.template, filename) | ||
| 298 | |||
| 299 | self.template.save() | ||
| 300 | self.template.destroy() | ||
| 301 | self.template = None | ||
| 302 | |||
| 303 | def switch_page(self, next_step): | ||
| 304 | # Main Workflow (Business Logic) | ||
| 305 | self.nb.set_current_page(self.__step2page__[next_step]) | ||
| 306 | |||
| 307 | if next_step == self.MACHINE_SELECTION: # init step | ||
| 308 | self.image_configuration_page.show_machine() | ||
| 309 | |||
| 310 | elif next_step == self.LAYER_CHANGED: | ||
| 311 | # after layers is changd by users | ||
| 312 | self.image_configuration_page.show_machine() | ||
| 313 | self.handler.refresh_layers(self.configuration.layers) | ||
| 314 | |||
| 315 | elif next_step == self.RCPPKGINFO_POPULATING: | ||
| 316 | # MACHINE CHANGED action or SETTINGS CHANGED | ||
| 317 | # show the progress bar | ||
| 318 | self.image_configuration_page.show_info_populating() | ||
| 319 | self.generate_recipes() | ||
| 320 | |||
| 321 | elif next_step == self.RCPPKGINFO_POPULATED: | ||
| 322 | self.image_configuration_page.show_info_populated() | ||
| 323 | |||
| 324 | elif next_step == self.RECIPE_SELECTION: | ||
| 325 | pass | ||
| 326 | |||
| 327 | elif next_step == self.PACKAGE_SELECTION: | ||
| 328 | pass | ||
| 329 | |||
| 330 | elif next_step == self.PACKAGE_GENERATING or next_step == self.FAST_IMAGE_GENERATING: | ||
| 331 | # both PACKAGE_GENEATING and FAST_IMAGE_GENERATING share the same page | ||
| 332 | self.build_details_page.show_page(next_step) | ||
| 333 | self.generate_packages() | ||
| 334 | |||
| 335 | elif next_step == self.PACKAGE_GENERATED: | ||
| 336 | pass | ||
| 337 | |||
| 338 | elif next_step == self.IMAGE_GENERATING: | ||
| 339 | # after packages are generated, selected_packages need to | ||
| 340 | # be updated in package_model per selected_image in recipe_model | ||
| 341 | self.build_details_page.show_page(next_step) | ||
| 342 | self.generate_image() | ||
| 343 | |||
| 344 | elif next_step == self.IMAGE_GENERATED: | ||
| 345 | self.image_details_page.show_page(next_step) | ||
| 346 | |||
| 347 | elif next_step == self.MY_IMAGE_OPENED: | ||
| 348 | self.image_details_page.show_page(next_step) | ||
| 349 | |||
| 350 | self.previous_step = self.current_step | ||
| 351 | self.current_step = next_step | ||
| 352 | |||
| 353 | def set_user_config(self): | ||
| 354 | self.handler.init_cooker() | ||
| 355 | # set bb layers | ||
| 356 | self.handler.set_bblayers(self.configuration.layers) | ||
| 357 | # set local configuration | ||
| 358 | self.handler.set_machine(self.configuration.curr_mach) | ||
| 359 | self.handler.set_package_format(self.configuration.curr_package_format) | ||
| 360 | self.handler.set_distro(self.configuration.curr_distro) | ||
| 361 | self.handler.set_dl_dir(self.configuration.dldir) | ||
| 362 | self.handler.set_sstate_dir(self.configuration.sstatedir) | ||
| 363 | self.handler.set_sstate_mirror(self.configuration.sstatemirror) | ||
| 364 | self.handler.set_pmake(self.configuration.pmake) | ||
| 365 | self.handler.set_bbthreads(self.configuration.bbthread) | ||
| 366 | self.handler.set_rootfs_size(self.configuration.image_rootfs_size) | ||
| 367 | self.handler.set_extra_size(self.configuration.image_extra_size) | ||
| 368 | self.handler.set_incompatible_license(self.configuration.incompat_license) | ||
| 369 | self.handler.set_sdk_machine(self.configuration.curr_sdk_machine) | ||
| 370 | self.handler.set_image_fstypes(self.configuration.image_fstypes) | ||
| 371 | self.handler.set_extra_config(self.configuration.extra_setting) | ||
| 372 | self.handler.set_extra_inherit("packageinfo") | ||
| 373 | |||
| 374 | def reset_recipe_model(self): | ||
| 375 | self.recipe_model.reset() | ||
| 376 | |||
| 377 | def reset_package_model(self): | ||
| 378 | self.package_model.reset() | ||
| 379 | |||
| 380 | def update_recipe_model(self, selected_image, selected_recipes): | ||
| 381 | self.recipe_model.set_selected_image(selected_image) | ||
| 382 | self.recipe_model.set_selected_recipes(selected_recipes) | ||
| 383 | |||
| 384 | def update_package_model(self, selected_packages): | ||
| 385 | left = self.package_model.set_selected_packages(selected_packages) | ||
| 386 | self.configuration.selected_packages += left | ||
| 387 | |||
| 388 | def generate_packages(self): | ||
| 389 | # Build packages | ||
| 390 | _, all_recipes = self.recipe_model.get_selected_recipes() | ||
| 391 | self.set_user_config() | ||
| 392 | self.handler.reset_build() | ||
| 393 | self.handler.generate_packages(all_recipes) | ||
| 394 | |||
| 395 | def generate_recipes(self): | ||
| 396 | # Parse recipes | ||
| 397 | self.set_user_config() | ||
| 398 | self.handler.generate_recipes() | ||
| 399 | |||
| 400 | def generate_image(self): | ||
| 401 | # Build image | ||
| 402 | self.set_user_config() | ||
| 403 | all_packages = self.package_model.get_selected_packages() | ||
| 404 | self.handler.reset_build() | ||
| 405 | self.handler.generate_image(all_packages, self.configuration.toolchain_build) | ||
| 406 | |||
| 407 | |||
| 408 | # Callback Functions | ||
| 409 | def handler_config_updated_cb(self, handler, which, values): | ||
| 410 | if which == "distro": | ||
| 411 | self.parameters.all_distros = values | ||
| 412 | elif which == "machine": | ||
| 413 | self.parameters.all_machines = values | ||
| 414 | self.image_configuration_page.update_machine_combo() | ||
| 415 | elif which == "machine-sdk": | ||
| 416 | self.parameters.all_sdk_machines = values | ||
| 417 | |||
| 418 | def handler_package_formats_updated_cb(self, handler, formats): | ||
| 419 | self.parameters.all_package_formats = formats | ||
| 420 | |||
| 421 | def handler_layers_updated_cb(self, handler, layers): | ||
| 422 | self.parameters.all_layers = layers | ||
| 423 | |||
| 424 | def handler_command_succeeded_cb(self, handler, initcmd): | ||
| 425 | if initcmd == self.handler.LAYERS_REFRESH: | ||
| 426 | self.image_configuration_page.switch_machine_combo() | ||
| 427 | elif initcmd in [self.handler.GENERATE_RECIPES, | ||
| 428 | self.handler.GENERATE_PACKAGES, | ||
| 429 | self.handler.GENERATE_IMAGE]: | ||
| 430 | self.handler.request_package_info_async() | ||
| 431 | elif initcmd == self.handler.POPULATE_PACKAGEINFO: | ||
| 432 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
| 433 | self.switch_page(self.IMAGE_GENERATING) | ||
| 434 | elif self.current_step == self.RCPPKGINFO_POPULATING: | ||
| 435 | self.switch_page(self.RCPPKGINFO_POPULATED) | ||
| 436 | elif self.current_step == self.PACKAGE_GENERATING: | ||
| 437 | self.switch_page(self.PACKAGE_GENERATED) | ||
| 438 | elif self.current_step == self.IMAGE_GENERATING: | ||
| 439 | self.switch_page(self.IMAGE_GENERATED) | ||
| 440 | |||
| 441 | def handler_command_failed_cb(self, handler, msg): | ||
| 442 | lbl = "<b>Error</b>\n" | ||
| 443 | lbl = lbl + "%s\n\n" % msg | ||
| 444 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) | ||
| 445 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 446 | response = dialog.run() | ||
| 447 | dialog.destroy() | ||
| 448 | self.handler.clear_busy() | ||
| 449 | self.configuration.curr_mach = None | ||
| 450 | self.image_configuration_page.switch_machine_combo() | ||
| 451 | self.switch_page(self.MACHINE_SELECTION) | ||
| 452 | |||
| 453 | def window_sensitive(self, sensitive): | ||
| 454 | self.set_sensitive(sensitive) | ||
| 455 | if sensitive: | ||
| 456 | self.get_root_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) | ||
| 457 | else: | ||
| 458 | self.get_root_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) | ||
| 459 | |||
| 460 | |||
| 461 | def handler_generating_data_cb(self, handler): | ||
| 462 | self.window_sensitive(False) | ||
| 463 | |||
| 464 | def handler_data_generated_cb(self, handler): | ||
| 465 | self.window_sensitive(True) | ||
| 466 | |||
| 467 | def recipelist_populated_cb(self, recipe_model): | ||
| 468 | selected_image = self.configuration.selected_image | ||
| 469 | selected_recipes = self.configuration.selected_recipes[:] | ||
| 470 | selected_packages = self.configuration.selected_packages[:] | ||
| 471 | |||
| 472 | self.recipe_model.image_list_append(selected_image, | ||
| 473 | " ".join(selected_recipes), | ||
| 474 | " ".join(selected_packages)) | ||
| 475 | |||
| 476 | self.image_configuration_page.update_image_combo(self.recipe_model, selected_image) | ||
| 477 | |||
| 478 | self.update_recipe_model(selected_image, selected_recipes) | ||
| 479 | |||
| 480 | def packagelist_populated_cb(self, package_model): | ||
| 481 | selected_packages = self.configuration.selected_packages[:] | ||
| 482 | self.update_package_model(selected_packages) | ||
| 483 | |||
| 484 | def recipelist_changed_cb(self, recipe_model): | ||
| 485 | self.recipe_details_page.refresh_selection() | ||
| 486 | |||
| 487 | def packagelist_changed_cb(self, package_model): | ||
| 488 | self.package_details_page.refresh_selection() | ||
| 489 | |||
| 490 | def handler_parsing_started_cb(self, handler, message): | ||
| 491 | if self.current_step != self.RCPPKGINFO_POPULATING: | ||
| 492 | return | ||
| 493 | |||
| 494 | fraction = 0 | ||
| 495 | if message["eventname"] == "TreeDataPreparationStarted": | ||
| 496 | fraction = 0.6 + fraction | ||
| 497 | self.image_configuration_page.update_progress_bar(message["title"], fraction) | ||
| 498 | |||
| 499 | def handler_parsing_cb(self, handler, message): | ||
| 500 | if self.current_step != self.RCPPKGINFO_POPULATING: | ||
| 501 | return | ||
| 502 | |||
| 503 | fraction = message["current"] * 1.0/message["total"] | ||
| 504 | if message["eventname"] == "TreeDataPreparationProgress": | ||
| 505 | fraction = 0.6 + 0.4 * fraction | ||
| 506 | else: | ||
| 507 | fraction = 0.6 * fraction | ||
| 508 | self.image_configuration_page.update_progress_bar(message["title"], fraction) | ||
| 509 | |||
| 510 | def handler_parsing_completed_cb(self, handler, message): | ||
| 511 | if self.current_step != self.RCPPKGINFO_POPULATING: | ||
| 512 | return | ||
| 513 | |||
| 514 | if message["eventname"] == "TreeDataPreparationCompleted": | ||
| 515 | fraction = 1.0 | ||
| 516 | else: | ||
| 517 | fraction = 0.6 | ||
| 518 | self.image_configuration_page.update_progress_bar(message["title"], fraction) | ||
| 519 | |||
| 520 | def handler_build_started_cb(self, running_build): | ||
| 521 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
| 522 | fraction = 0 | ||
| 523 | elif self.current_step == self.IMAGE_GENERATING: | ||
| 524 | if self.previous_step == self.FAST_IMAGE_GENERATING: | ||
| 525 | fraction = 0.9 | ||
| 526 | else: | ||
| 527 | fraction = 0 | ||
| 528 | elif self.current_step == self.PACKAGE_GENERATING: | ||
| 529 | fraction = 0 | ||
| 530 | self.build_details_page.update_progress_bar("Build Started: ", fraction) | ||
| 531 | |||
| 532 | def handler_build_succeeded_cb(self, running_build): | ||
| 533 | self.build_succeeded = True | ||
| 534 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
| 535 | fraction = 0.9 | ||
| 536 | elif self.current_step == self.IMAGE_GENERATING: | ||
| 537 | fraction = 1.0 | ||
| 538 | self.parameters.image_names = [] | ||
| 539 | linkname = 'hob-image-' + self.configuration.curr_mach | ||
| 540 | for image_type in self.parameters.image_types: | ||
| 541 | linkpath = self.parameters.image_addr + '/' + linkname + '.' + image_type | ||
| 542 | if os.path.exists(linkpath): | ||
| 543 | self.parameters.image_names.append(os.readlink(linkpath)) | ||
| 544 | elif self.current_step == self.PACKAGE_GENERATING: | ||
| 545 | fraction = 1.0 | ||
| 546 | self.build_details_page.update_progress_bar("Build Completed: ", fraction) | ||
| 547 | |||
| 548 | def handler_build_failed_cb(self, running_build): | ||
| 549 | self.build_succeeded = False | ||
| 550 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
| 551 | fraction = 0.9 | ||
| 552 | elif self.current_step == self.IMAGE_GENERATING: | ||
| 553 | fraction = 1.0 | ||
| 554 | elif self.current_step == self.PACKAGE_GENERATING: | ||
| 555 | fraction = 1.0 | ||
| 556 | self.build_details_page.update_progress_bar("Build Failed: ", fraction, False) | ||
| 557 | self.build_details_page.show_back_button() | ||
| 558 | self.build_details_page.hide_stop_button() | ||
| 559 | self.handler.build_failed_async() | ||
| 560 | self.stopping = False | ||
| 561 | |||
| 562 | def handler_task_started_cb(self, running_build, message): | ||
| 563 | fraction = message["current"] * 1.0/message["total"] | ||
| 564 | title = "Build packages" | ||
| 565 | if self.current_step == self.FAST_IMAGE_GENERATING: | ||
| 566 | if message["eventname"] == "sceneQueueTaskStarted": | ||
| 567 | fraction = 0.27 * fraction | ||
| 568 | elif message["eventname"] == "runQueueTaskStarted": | ||
| 569 | fraction = 0.27 + 0.63 * fraction | ||
| 570 | elif self.current_step == self.IMAGE_GENERATING: | ||
| 571 | title = "Build image" | ||
| 572 | if self.previous_step == self.FAST_IMAGE_GENERATING: | ||
| 573 | if message["eventname"] == "sceneQueueTaskStarted": | ||
| 574 | fraction = 0.27 + 0.63 + 0.03 * fraction | ||
| 575 | elif message["eventname"] == "runQueueTaskStarted": | ||
| 576 | fraction = 0.27 + 0.63 + 0.03 + 0.07 * fraction | ||
| 577 | else: | ||
| 578 | if message["eventname"] == "sceneQueueTaskStarted": | ||
| 579 | fraction = 0.2 * fraction | ||
| 580 | elif message["eventname"] == "runQueueTaskStarted": | ||
| 581 | fraction = 0.2 + 0.8 * fraction | ||
| 582 | elif self.current_step == self.PACKAGE_GENERATING: | ||
| 583 | if message["eventname"] == "sceneQueueTaskStarted": | ||
| 584 | fraction = 0.2 * fraction | ||
| 585 | elif message["eventname"] == "runQueueTaskStarted": | ||
| 586 | fraction = 0.2 + 0.8 * fraction | ||
| 587 | self.build_details_page.update_progress_bar(title + ": ", fraction) | ||
| 588 | |||
| 589 | def destroy_window_cb(self, widget, event): | ||
| 590 | lbl = "<b>Do you really want to exit the Hob image creator?</b>" | ||
| 591 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 592 | dialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES) | ||
| 593 | dialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO) | ||
| 594 | dialog.set_default_response(gtk.RESPONSE_NO) | ||
| 595 | response = dialog.run() | ||
| 596 | dialog.destroy() | ||
| 597 | if response == gtk.RESPONSE_YES: | ||
| 598 | gtk.main_quit() | ||
| 599 | return False | ||
| 600 | else: | ||
| 601 | return True | ||
| 602 | |||
| 603 | def build_packages(self): | ||
| 604 | _, all_recipes = self.recipe_model.get_selected_recipes() | ||
| 605 | if not all_recipes: | ||
| 606 | lbl = "<b>No selections made</b>\nYou have not made any selections" | ||
| 607 | lbl = lbl + " so there isn't anything to bake at this time." | ||
| 608 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 609 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 610 | dialog.run() | ||
| 611 | dialog.destroy() | ||
| 612 | return | ||
| 613 | self.switch_page(self.PACKAGE_GENERATING) | ||
| 614 | |||
| 615 | def build_image(self): | ||
| 616 | selected_packages = self.package_model.get_selected_packages() | ||
| 617 | if not selected_packages: | ||
| 618 | lbl = "<b>No selections made</b>\nYou have not made any selections" | ||
| 619 | lbl = lbl + " so there isn't anything to bake at this time." | ||
| 620 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 621 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 622 | dialog.run() | ||
| 623 | dialog.destroy() | ||
| 624 | return | ||
| 625 | self.switch_page(self.IMAGE_GENERATING) | ||
| 626 | |||
| 627 | def just_bake(self): | ||
| 628 | selected_image = self.recipe_model.get_selected_image() | ||
| 629 | selected_packages = self.package_model.get_selected_packages() or [] | ||
| 630 | |||
| 631 | # If no base image and no selected packages don't build anything | ||
| 632 | if not (selected_packages or selected_image != self.recipe_model.__dummy_image__): | ||
| 633 | lbl = "<b>No selections made</b>\nYou have not made any selections" | ||
| 634 | lbl = lbl + " so there isn't anything to bake at this time." | ||
| 635 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 636 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 637 | dialog.run() | ||
| 638 | dialog.destroy() | ||
| 639 | return | ||
| 640 | |||
| 641 | self.switch_page(self.FAST_IMAGE_GENERATING) | ||
| 642 | |||
| 643 | def show_binb_dialog(self, binb): | ||
| 644 | binb_dialog = BinbDialog("Brought in by:", binb, self) | ||
| 645 | binb_dialog.run() | ||
| 646 | binb_dialog.destroy() | ||
| 647 | |||
| 648 | def show_layer_selection_dialog(self): | ||
| 649 | dialog = LayerSelectionDialog(title = "Layer Selection", | ||
| 650 | layers = copy.deepcopy(self.configuration.layers), | ||
| 651 | all_layers = self.parameters.all_layers, | ||
| 652 | split_model = self.get_split_model(), | ||
| 653 | parent = self, | ||
| 654 | flags = gtk.DIALOG_MODAL | ||
| 655 | | gtk.DIALOG_DESTROY_WITH_PARENT | ||
| 656 | | gtk.DIALOG_NO_SEPARATOR, | ||
| 657 | buttons = (gtk.STOCK_OK, gtk.RESPONSE_YES, | ||
| 658 | gtk.STOCK_CANCEL, gtk.RESPONSE_NO)) | ||
| 659 | response = dialog.run() | ||
| 660 | if response == gtk.RESPONSE_YES: | ||
| 661 | self.configuration.layers = dialog.layers | ||
| 662 | # DO refresh layers | ||
| 663 | if dialog.layers_changed: | ||
| 664 | self.switch_page(self.LAYER_CHANGED) | ||
| 665 | dialog.destroy() | ||
| 666 | |||
| 667 | def show_load_template_dialog(self): | ||
| 668 | dialog = gtk.FileChooserDialog("Load Template Files", self, | ||
| 669 | gtk.FILE_CHOOSER_ACTION_SAVE, | ||
| 670 | (gtk.STOCK_OPEN, gtk.RESPONSE_YES, | ||
| 671 | gtk.STOCK_CANCEL, gtk.RESPONSE_NO)) | ||
| 672 | filter = gtk.FileFilter() | ||
| 673 | filter.set_name("HOB Files") | ||
| 674 | filter.add_pattern("*.hob") | ||
| 675 | dialog.add_filter(filter) | ||
| 676 | |||
| 677 | response = dialog.run() | ||
| 678 | if response == gtk.RESPONSE_YES: | ||
| 679 | path = dialog.get_filename() | ||
| 680 | self.load_template(path) | ||
| 681 | dialog.destroy() | ||
| 682 | |||
| 683 | def show_save_template_dialog(self): | ||
| 684 | dialog = gtk.FileChooserDialog("Save Template Files", self, | ||
| 685 | gtk.FILE_CHOOSER_ACTION_SAVE, | ||
| 686 | (gtk.STOCK_SAVE, gtk.RESPONSE_YES, | ||
| 687 | gtk.STOCK_CANCEL, gtk.RESPONSE_NO)) | ||
| 688 | dialog.set_current_name("hob") | ||
| 689 | response = dialog.run() | ||
| 690 | if response == gtk.RESPONSE_YES: | ||
| 691 | path = dialog.get_filename() | ||
| 692 | self.save_template(path) | ||
| 693 | dialog.destroy() | ||
| 694 | |||
| 695 | def show_load_my_images_dialog(self): | ||
| 696 | dialog = ImageSelectionDialog(self.parameters.image_addr, self.parameters.image_types, | ||
| 697 | "Open My Images", self, | ||
| 698 | gtk.FILE_CHOOSER_ACTION_SAVE, | ||
| 699 | (gtk.STOCK_OPEN, gtk.RESPONSE_YES, | ||
| 700 | gtk.STOCK_CANCEL, gtk.RESPONSE_NO)) | ||
| 701 | |||
| 702 | response = dialog.run() | ||
| 703 | if response == gtk.RESPONSE_YES: | ||
| 704 | if not dialog.image_names: | ||
| 705 | lbl = "<b>No selections made</b>\nYou have not made any selections" | ||
| 706 | crumbs_dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 707 | crumbs_dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 708 | crumbs_dialog.run() | ||
| 709 | crumbs_dialog.destroy() | ||
| 710 | dialog.destroy() | ||
| 711 | return | ||
| 712 | |||
| 713 | self.parameters.image_addr = dialog.image_folder | ||
| 714 | self.parameters.image_names = dialog.image_names[:] | ||
| 715 | self.switch_page(self.MY_IMAGE_OPENED) | ||
| 716 | |||
| 717 | dialog.destroy() | ||
| 718 | |||
| 719 | def show_adv_settings_dialog(self): | ||
| 720 | dialog = AdvancedSettingDialog(title = "Settings", | ||
| 721 | configuration = copy.deepcopy(self.configuration), | ||
| 722 | all_image_types = self.parameters.image_types, | ||
| 723 | all_package_formats = self.parameters.all_package_formats, | ||
| 724 | all_distros = self.parameters.all_distros, | ||
| 725 | all_sdk_machines = self.parameters.all_sdk_machines, | ||
| 726 | max_threads = self.parameters.max_threads, | ||
| 727 | split_model = self.get_split_model(), | ||
| 728 | parent = self, | ||
| 729 | flags = gtk.DIALOG_MODAL | ||
| 730 | | gtk.DIALOG_DESTROY_WITH_PARENT | ||
| 731 | | gtk.DIALOG_NO_SEPARATOR, | ||
| 732 | buttons = ("Save", gtk.RESPONSE_YES, | ||
| 733 | gtk.STOCK_CANCEL, gtk.RESPONSE_NO)) | ||
| 734 | response = dialog.run() | ||
| 735 | if response == gtk.RESPONSE_YES: | ||
| 736 | self.configuration = dialog.configuration | ||
| 737 | # DO reparse recipes | ||
| 738 | if dialog.settings_changed: | ||
| 739 | if self.configuration.curr_mach == "": | ||
| 740 | self.switch_page(self.MACHINE_SELECTION) | ||
| 741 | else: | ||
| 742 | self.switch_page(self.RCPPKGINFO_POPULATING) | ||
| 743 | dialog.destroy() | ||
| 744 | |||
| 745 | def deploy_image(self, image_name): | ||
| 746 | if not image_name: | ||
| 747 | lbl = "<b>Please select an image to deploy.</b>" | ||
| 748 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 749 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 750 | dialog.run() | ||
| 751 | dialog.destroy() | ||
| 752 | return | ||
| 753 | |||
| 754 | image_path = os.path.join(self.parameters.image_addr, image_name) | ||
| 755 | dialog = DeployImageDialog(title = "Usb Image Maker", | ||
| 756 | image_path = image_path, | ||
| 757 | parent = self, | ||
| 758 | flags = gtk.DIALOG_MODAL | ||
| 759 | | gtk.DIALOG_DESTROY_WITH_PARENT | ||
| 760 | | gtk.DIALOG_NO_SEPARATOR, | ||
| 761 | buttons = ("Close", gtk.RESPONSE_NO, | ||
| 762 | "Make usb image", gtk.RESPONSE_YES)) | ||
| 763 | response = dialog.run() | ||
| 764 | dialog.destroy() | ||
| 765 | |||
| 766 | def runqemu_image(self, image_name): | ||
| 767 | if not image_name: | ||
| 768 | lbl = "<b>Please select an image to launch in QEMU.</b>" | ||
| 769 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 770 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 771 | dialog.run() | ||
| 772 | dialog.destroy() | ||
| 773 | return | ||
| 774 | |||
| 775 | dialog = gtk.FileChooserDialog("Load Kernel Files", self, | ||
| 776 | gtk.FILE_CHOOSER_ACTION_SAVE, | ||
| 777 | (gtk.STOCK_OPEN, gtk.RESPONSE_YES, | ||
| 778 | gtk.STOCK_CANCEL, gtk.RESPONSE_NO)) | ||
| 779 | filter = gtk.FileFilter() | ||
| 780 | filter.set_name("Kernel Files") | ||
| 781 | filter.add_pattern("*.bin") | ||
| 782 | dialog.add_filter(filter) | ||
| 783 | |||
| 784 | dialog.set_current_folder(self.parameters.image_addr) | ||
| 785 | |||
| 786 | response = dialog.run() | ||
| 787 | if response == gtk.RESPONSE_YES: | ||
| 788 | kernel_path = dialog.get_filename() | ||
| 789 | image_path = os.path.join(self.parameters.image_addr, image_name) | ||
| 790 | dialog.destroy() | ||
| 791 | |||
| 792 | if response == gtk.RESPONSE_YES: | ||
| 793 | source_env_path = os.path.join(self.parameters.core_base, "oe-init-build-env") | ||
| 794 | tmp_path = os.path.join(os.getcwd(), "tmp") | ||
| 795 | if os.path.exists(image_path) and os.path.exists(kernel_path) \ | ||
| 796 | and os.path.exists(source_env_path) and os.path.exists(tmp_path): | ||
| 797 | cmdline = "/usr/bin/xterm -e " | ||
| 798 | cmdline += "\" export OE_TMPDIR=" + tmp_path + "; " | ||
| 799 | cmdline += "source " + source_env_path + " " + os.getcwd() + "; " | ||
| 800 | cmdline += "runqemu " + kernel_path + " " + image_path + "; bash\"" | ||
| 801 | subprocess.Popen(shlex.split(cmdline)) | ||
| 802 | else: | ||
| 803 | lbl = "<b>Path error</b>\nOne of your paths is wrong," | ||
| 804 | lbl = lbl + " please make sure the following paths exist:\n" | ||
| 805 | lbl = lbl + "image path:" + image_path + "\n" | ||
| 806 | lbl = lbl + "kernel path:" + kernel_path + "\n" | ||
| 807 | lbl = lbl + "source environment path:" + source_env_path + "\n" | ||
| 808 | lbl = lbl + "tmp path: " + tmp_path + "." | ||
| 809 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 810 | dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) | ||
| 811 | dialog.run() | ||
| 812 | dialog.destroy() | ||
| 813 | |||
| 814 | def show_packages(self, ask=True): | ||
| 815 | _, selected_recipes = self.recipe_model.get_selected_recipes() | ||
| 816 | if selected_recipes and ask: | ||
| 817 | lbl = "<b>Package list may be incomplete!</b>\nDo you want to build selected recipes" | ||
| 818 | lbl = lbl + " to get a full list (Yes) or just view the existing packages (No)?" | ||
| 819 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO) | ||
| 820 | dialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES) | ||
| 821 | dialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO) | ||
| 822 | dialog.set_default_response(gtk.RESPONSE_YES) | ||
| 823 | response = dialog.run() | ||
| 824 | dialog.destroy() | ||
| 825 | if response == gtk.RESPONSE_YES: | ||
| 826 | self.switch_page(self.PACKAGE_GENERATING) | ||
| 827 | else: | ||
| 828 | self.switch_page(self.PACKAGE_SELECTION) | ||
| 829 | else: | ||
| 830 | self.switch_page(self.PACKAGE_SELECTION) | ||
| 831 | |||
| 832 | def show_recipes(self): | ||
| 833 | self.switch_page(self.RECIPE_SELECTION) | ||
| 834 | |||
| 835 | def initiate_new_build(self): | ||
| 836 | self.configuration.curr_mach = "" | ||
| 837 | self.image_configuration_page.switch_machine_combo() | ||
| 838 | self.switch_page(self.MACHINE_SELECTION) | ||
| 839 | |||
| 840 | def show_configuration(self): | ||
| 841 | self.switch_page(self.RCPPKGINFO_POPULATED) | ||
| 842 | |||
| 843 | def stop_build(self): | ||
| 844 | if self.stopping: | ||
| 845 | lbl = "<b>Force Stop build?</b>\nYou've already selected Stop once," | ||
| 846 | lbl = lbl + " would you like to 'Force Stop' the build?\n\n" | ||
| 847 | lbl = lbl + "This will stop the build as quickly as possible but may" | ||
| 848 | lbl = lbl + " well leave your build directory in an unusable state" | ||
| 849 | lbl = lbl + " that requires manual steps to fix.\n" | ||
| 850 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) | ||
| 851 | dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) | ||
| 852 | dialog.add_button("Force Stop", gtk.RESPONSE_YES) | ||
| 853 | else: | ||
| 854 | lbl = "<b>Stop build?</b>\n\nAre you sure you want to stop this" | ||
| 855 | lbl = lbl + " build?\n\n'Force Stop' will stop the build as quickly as" | ||
| 856 | lbl = lbl + " possible but may well leave your build directory in an" | ||
| 857 | lbl = lbl + " unusable state that requires manual steps to fix.\n\n" | ||
| 858 | lbl = lbl + "'Stop' will stop the build as soon as all in" | ||
| 859 | lbl = lbl + " progress build tasks are finished. However if a" | ||
| 860 | lbl = lbl + " lengthy compilation phase is in progress this may take" | ||
| 861 | lbl = lbl + " some time." | ||
| 862 | dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING) | ||
| 863 | dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) | ||
| 864 | dialog.add_button("Stop", gtk.RESPONSE_OK) | ||
| 865 | dialog.add_button("Force Stop", gtk.RESPONSE_YES) | ||
| 866 | response = dialog.run() | ||
| 867 | dialog.destroy() | ||
| 868 | if response != gtk.RESPONSE_CANCEL: | ||
| 869 | self.stopping = True | ||
| 870 | if response == gtk.RESPONSE_OK: | ||
| 871 | self.handler.cancel_build() | ||
| 872 | elif response == gtk.RESPONSE_YES: | ||
| 873 | self.handler.cancel_build(True) | ||
