summaryrefslogtreecommitdiffstats
path: root/yocto-poky/bitbake/lib/bb/ui
diff options
context:
space:
mode:
Diffstat (limited to 'yocto-poky/bitbake/lib/bb/ui')
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/buildinfohelper.py367
-rwxr-xr-xyocto-poky/bitbake/lib/bb/ui/crumbs/builddetailspage.py437
-rwxr-xr-xyocto-poky/bitbake/lib/bb/ui/crumbs/builder.py1475
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/buildmanager.py455
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hig/advancedsettingsdialog.py341
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hig/parsingwarningsdialog.py163
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hig/proxydetailsdialog.py90
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hig/retrieveimagedialog.py51
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hig/saveimagedialog.py159
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py891
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hobeventhandler.py645
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py903
-rwxr-xr-xyocto-poky/bitbake/lib/bb/ui/crumbs/hobpages.py128
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py561
-rwxr-xr-xyocto-poky/bitbake/lib/bb/ui/crumbs/imagedetailspage.py669
-rwxr-xr-xyocto-poky/bitbake/lib/bb/ui/crumbs/packageselectionpage.py355
-rwxr-xr-xyocto-poky/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py335
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/crumbs/sanitycheckpage.py85
-rwxr-xr-xyocto-poky/bitbake/lib/bb/ui/hob.py109
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/knotty.py62
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/puccho.py425
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/toasterui.py109
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/uievent.py30
-rw-r--r--yocto-poky/bitbake/lib/bb/ui/uihelper.py41
24 files changed, 366 insertions, 8520 deletions
diff --git a/yocto-poky/bitbake/lib/bb/ui/buildinfohelper.py b/yocto-poky/bitbake/lib/bb/ui/buildinfohelper.py
index 78f1e9274..93979054d 100644
--- a/yocto-poky/bitbake/lib/bb/ui/buildinfohelper.py
+++ b/yocto-poky/bitbake/lib/bb/ui/buildinfohelper.py
@@ -24,6 +24,7 @@ import os
os.environ["DJANGO_SETTINGS_MODULE"] = "toaster.toastermain.settings"
+import django
from django.utils import timezone
@@ -33,20 +34,23 @@ def _configure_toaster():
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'toaster'))
_configure_toaster()
-from toaster.orm.models import Build, Task, Recipe, Layer_Version, Layer, Target, LogMessage, HelpText
-from toaster.orm.models import Target_Image_File, BuildArtifact
-from toaster.orm.models import Variable, VariableHistory
-from toaster.orm.models import Package, Package_File, Target_Installed_Package, Target_File
-from toaster.orm.models import Task_Dependency, Package_Dependency
-from toaster.orm.models import Recipe_Dependency
+django.setup()
+
+from orm.models import Build, Task, Recipe, Layer_Version, Layer, Target, LogMessage, HelpText
+from orm.models import Target_Image_File, BuildArtifact
+from orm.models import Variable, VariableHistory
+from orm.models import Package, Package_File, Target_Installed_Package, Target_File
+from orm.models import Task_Dependency, Package_Dependency
+from orm.models import Recipe_Dependency, Provides
+from orm.models import Project, CustomImagePackage, CustomImageRecipe
-from toaster.orm.models import Project
from bldcontrol.models import BuildEnvironment, BuildRequest
from bb.msg import BBLogFormatter as formatter
from django.db import models
from pprint import pformat
import logging
+from datetime import datetime, timedelta
from django.db import transaction, connection
@@ -117,6 +121,12 @@ class ORMWrapper(object):
return vars(self)[dictname][key]
+ def _timestamp_to_datetime(self, secs):
+ """
+ Convert timestamp in seconds to Python datetime
+ """
+ return datetime(1970, 1, 1) + timedelta(seconds=secs)
+
# pylint: disable=no-self-use
# we disable detection of no self use in functions because the methods actually work on the object
# even if they don't touch self anywhere
@@ -146,7 +156,7 @@ class ORMWrapper(object):
prj = Project.objects.get(pk = project_id)
else: # this build was triggered by a legacy system, or command line interactive mode
- prj = Project.objects.get_default_project()
+ prj = Project.objects.get_or_create_default_project()
logger.debug(1, "buildinfohelper: project is not specified, defaulting to %s" % prj)
@@ -208,6 +218,15 @@ class ORMWrapper(object):
assert isinstance(errors, int)
assert isinstance(warnings, int)
+ if build.outcome == Build.CANCELLED:
+ return
+ try:
+ if build.buildrequest.state == BuildRequest.REQ_CANCELLING:
+ return
+ except AttributeError:
+ # We may not have a buildrequest if this is a command line build
+ pass
+
outcome = Build.SUCCEEDED
if errors or taskfailures:
outcome = Build.FAILED
@@ -220,6 +239,30 @@ class ORMWrapper(object):
target.license_manifest_path = license_manifest_path
target.save()
+ def update_task_object(self, build, task_name, recipe_name, task_stats):
+ """
+ Find the task for build which matches the recipe and task name
+ to be stored
+ """
+ task_to_update = Task.objects.get(
+ build = build,
+ task_name = task_name,
+ recipe__name = recipe_name
+ )
+
+ if 'started' in task_stats and 'ended' in task_stats:
+ task_to_update.started = self._timestamp_to_datetime(task_stats['started'])
+ task_to_update.ended = self._timestamp_to_datetime(task_stats['ended'])
+ task_to_update.elapsed_time = (task_stats['ended'] - task_stats['started'])
+ task_to_update.cpu_time_user = task_stats.get('cpu_time_user')
+ task_to_update.cpu_time_system = task_stats.get('cpu_time_system')
+ if 'disk_io_read' in task_stats and 'disk_io_write' in task_stats:
+ task_to_update.disk_io_read = task_stats['disk_io_read']
+ task_to_update.disk_io_write = task_stats['disk_io_write']
+ task_to_update.disk_io = task_stats['disk_io_read'] + task_stats['disk_io_write']
+
+ task_to_update.save()
+
def get_update_task_object(self, task_information, must_exist = False):
assert 'build' in task_information
assert 'recipe' in task_information
@@ -256,14 +299,6 @@ class ORMWrapper(object):
task_object.sstate_result = Task.SSTATE_FAILED
object_changed = True
- # mark down duration if we have a start time and a current time
- if 'start_time' in task_information.keys() and 'end_time' in task_information.keys():
- duration = task_information['end_time'] - task_information['start_time']
- task_object.elapsed_time = duration
- object_changed = True
- del task_information['start_time']
- del task_information['end_time']
-
if object_changed:
task_object.save()
return task_object
@@ -304,18 +339,27 @@ class ORMWrapper(object):
break
- # If we're in analysis mode then we are wholly responsible for the data
+ # If we're in analysis mode or if this is a custom recipe
+ # then we are wholly responsible for the data
# and therefore we return the 'real' recipe rather than the build
# history copy of the recipe.
if recipe_information['layer_version'].build is not None and \
recipe_information['layer_version'].build.project == \
- Project.objects.get_default_project():
+ Project.objects.get_or_create_default_project():
+ return recipe
+
+ if built_recipe is None:
return recipe
return built_recipe
def get_update_layer_version_object(self, build_obj, layer_obj, layer_version_information):
if isinstance(layer_obj, Layer_Version):
+ # Special case the toaster-custom-images layer which is created
+ # on the fly so don't update the values which may cause the layer
+ # to be duplicated on a future get_or_create
+ if layer_obj.layer.name == CustomImageRecipe.LAYER_NAME:
+ return layer_obj
# We already found our layer version for this build so just
# update it with the new build information
logger.debug("We found our layer from toaster")
@@ -325,12 +369,17 @@ class ORMWrapper(object):
# create a new copy of this layer version as a snapshot for
# historical purposes
- layer_copy, c = Layer_Version.objects.get_or_create(build=build_obj,
- layer=layer_obj.layer,
- commit=layer_version_information['commit'],
- local_path = layer_version_information['local_path'],
- )
- logger.info("created new historical layer version %d", layer_copy.pk)
+ layer_copy, c = Layer_Version.objects.get_or_create(
+ build=build_obj,
+ layer=layer_obj.layer,
+ up_branch=layer_obj.up_branch,
+ branch=layer_version_information['branch'],
+ commit=layer_version_information['commit'],
+ local_path=layer_version_information['local_path'],
+ )
+
+ logger.info("created new historical layer version %d",
+ layer_copy.pk)
self.layer_version_built.append(layer_copy)
@@ -346,7 +395,7 @@ class ORMWrapper(object):
# If we're doing a command line build then associate this new layer with the
# project to avoid it 'contaminating' toaster data
project = None
- if build_obj.project == Project.objects.get_default_project():
+ if build_obj.project == Project.objects.get_or_create_default_project():
project = build_obj.project
layer_version_object, _ = Layer_Version.objects.get_or_create(
@@ -445,7 +494,7 @@ class ORMWrapper(object):
parent_obj = self._cached_get(Target_File, target = target_obj, path = parent_path, inodetype = Target_File.ITYPE_DIRECTORY)
tf_obj = Target_File.objects.create(
target = target_obj,
- path = path,
+ path = unicode(path, 'utf-8'),
size = size,
inodetype = Target_File.ITYPE_DIRECTORY,
permission = permission,
@@ -470,7 +519,7 @@ class ORMWrapper(object):
tf_obj = Target_File.objects.create(
target = target_obj,
- path = path,
+ path = unicode(path, 'utf-8'),
size = size,
inodetype = inodetype,
permission = permission,
@@ -501,7 +550,9 @@ class ORMWrapper(object):
filetarget_path = "/".join(fcpl)
try:
- filetarget_obj = Target_File.objects.get(target = target_obj, path = filetarget_path)
+ filetarget_obj = Target_File.objects.get(
+ target = target_obj,
+ path = unicode(filetarget_path, 'utf-8'))
except Target_File.DoesNotExist:
# we might have an invalid link; no way to detect this. just set it to None
filetarget_obj = None
@@ -510,7 +561,7 @@ class ORMWrapper(object):
tf_obj = Target_File.objects.create(
target = target_obj,
- path = path,
+ path = unicode(path, 'utf-8'),
size = size,
inodetype = Target_File.ITYPE_SYMLINK,
permission = permission,
@@ -520,12 +571,14 @@ class ORMWrapper(object):
sym_target = filetarget_obj)
- def save_target_package_information(self, build_obj, target_obj, packagedict, pkgpnmap, recipes):
+ def save_target_package_information(self, build_obj, target_obj, packagedict, pkgpnmap, recipes, built_package=False):
assert isinstance(build_obj, Build)
assert isinstance(target_obj, Target)
errormsg = ""
for p in packagedict:
+ # Search name swtiches round the installed name vs package name
+ # by default installed name == package name
searchname = p
if p not in pkgpnmap:
logger.warning("Image packages list contains %p, but is"
@@ -536,11 +589,38 @@ class ORMWrapper(object):
if 'OPKGN' in pkgpnmap[p].keys():
searchname = pkgpnmap[p]['OPKGN']
- packagedict[p]['object'], created = Package.objects.get_or_create( build = build_obj, name = searchname )
+ built_recipe = recipes[pkgpnmap[p]['PN']]
+
+ if built_package:
+ packagedict[p]['object'], created = Package.objects.get_or_create( build = build_obj, name = searchname )
+ recipe = built_recipe
+ else:
+ packagedict[p]['object'], created = \
+ CustomImagePackage.objects.get_or_create(name=searchname)
+ # Clear the Package_Dependency objects as we're going to update
+ # the CustomImagePackage with the latest dependency information
+ packagedict[p]['object'].package_dependencies_target.all().delete()
+ packagedict[p]['object'].package_dependencies_source.all().delete()
+ try:
+ recipe = self._cached_get(
+ Recipe,
+ name=built_recipe.name,
+ layer_version__build=None,
+ layer_version__up_branch=
+ built_recipe.layer_version.up_branch,
+ file_path=built_recipe.file_path,
+ version=built_recipe.version
+ )
+ except (Recipe.DoesNotExist,
+ Recipe.MultipleObjectsReturned) as e:
+ logger.info("We did not find one recipe for the"
+ "configuration data package %s %s" % (p, e))
+ continue
+
if created or packagedict[p]['object'].size == -1: # save the data anyway we can, not just if it was not created here; bug [YOCTO #6887]
# fill in everything we can from the runtime-reverse package data
try:
- packagedict[p]['object'].recipe = recipes[pkgpnmap[p]['PN']]
+ packagedict[p]['object'].recipe = recipe
packagedict[p]['object'].version = pkgpnmap[p]['PV']
packagedict[p]['object'].installed_name = p
packagedict[p]['object'].revision = pkgpnmap[p]['PR']
@@ -566,7 +646,8 @@ class ORMWrapper(object):
packagedict[p]['object'].installed_size = packagedict[p]['size']
packagedict[p]['object'].save()
- Target_Installed_Package.objects.create(target = target_obj, package = packagedict[p]['object'])
+ if built_package:
+ Target_Installed_Package.objects.create(target = target_obj, package = packagedict[p]['object'])
packagedeps_objs = []
for p in packagedict:
@@ -627,19 +708,37 @@ class ORMWrapper(object):
return log_object.save()
- def save_build_package_information(self, build_obj, package_info, recipes):
- assert isinstance(build_obj, Build)
+ def save_build_package_information(self, build_obj, package_info, recipes,
+ built_package):
+ # assert isinstance(build_obj, Build)
# create and save the object
pname = package_info['PKG']
+ built_recipe = recipes[package_info['PN']]
if 'OPKGN' in package_info.keys():
pname = package_info['OPKGN']
- bp_object, _ = Package.objects.get_or_create( build = build_obj,
- name = pname )
+ if built_package:
+ bp_object, _ = Package.objects.get_or_create( build = build_obj,
+ name = pname )
+ recipe = built_recipe
+ else:
+ bp_object, created = \
+ CustomImagePackage.objects.get_or_create(name=pname)
+ try:
+ recipe = self._cached_get(Recipe,
+ name=built_recipe.name,
+ layer_version__build=None,
+ file_path=built_recipe.file_path,
+ version=built_recipe.version)
+
+ except (Recipe.DoesNotExist, Recipe.MultipleObjectsReturned):
+ logger.debug("We did not find one recipe for the configuration"
+ "data package %s" % pname)
+ return
bp_object.installed_name = package_info['PKG']
- bp_object.recipe = recipes[package_info['PN']]
+ bp_object.recipe = recipe
bp_object.version = package_info['PKGV']
bp_object.revision = package_info['PKGR']
bp_object.summary = package_info['SUMMARY']
@@ -659,7 +758,12 @@ class ORMWrapper(object):
Package_File.objects.bulk_create(packagefile_objects)
def _po_byname(p):
- pkg, created = Package.objects.get_or_create(build = build_obj, name = p)
+ if built_package:
+ pkg, created = Package.objects.get_or_create(build=build_obj,
+ name=p)
+ else:
+ pkg, created = CustomImagePackage.objects.get_or_create(name=p)
+
if created:
pkg.size = -1
pkg.save()
@@ -700,7 +804,6 @@ class ORMWrapper(object):
def save_build_variables(self, build_obj, vardump):
assert isinstance(build_obj, Build)
- helptext_objects = []
for k in vardump:
desc = vardump[k]['doc']
if desc is None:
@@ -711,10 +814,9 @@ class ORMWrapper(object):
if desc is None:
desc = ''
if len(desc):
- helptext_objects.append(HelpText(build=build_obj,
- area=HelpText.VARIABLE,
- key=k,
- text=desc))
+ HelpText.objects.get_or_create(build=build_obj,
+ area=HelpText.VARIABLE,
+ key=k, text=desc)
if not bool(vardump[k]['func']):
value = vardump[k]['v']
if value is None:
@@ -734,8 +836,6 @@ class ORMWrapper(object):
if len(varhist_objects):
VariableHistory.objects.bulk_create(varhist_objects)
- HelpText.objects.bulk_create(helptext_objects)
-
class MockEvent(object):
""" This object is used to create event, for which normal event-processing methods can
@@ -762,7 +862,7 @@ class BuildInfoHelper(object):
# pylint: disable=bad-continuation
# we do not follow the python conventions for continuation indentation due to long lines here
- def __init__(self, server, has_build_history = False):
+ def __init__(self, server, has_build_history = False, brbe = None):
self.internal_state = {}
self.internal_state['taskdata'] = {}
self.internal_state['targets'] = []
@@ -775,8 +875,13 @@ class BuildInfoHelper(object):
self.orm_wrapper = ORMWrapper()
self.has_build_history = has_build_history
self.tmp_dir = self.server.runCommand(["getVariable", "TMPDIR"])[0]
- self.brbe = self.server.runCommand(["getVariable", "TOASTER_BRBE"])[0]
- self.project = self.server.runCommand(["getVariable", "TOASTER_PROJECT"])[0]
+
+ # this is set for Toaster-triggered builds by localhostbecontroller
+ # via toasterui
+ self.brbe = brbe
+
+ self.project = None
+
logger.debug(1, "buildinfohelper: Build info helper inited %s" % vars(self))
@@ -786,8 +891,6 @@ class BuildInfoHelper(object):
def _get_build_information(self, build_log_path):
build_info = {}
- # Generate an identifier for each new build
-
build_info['machine'] = self.server.runCommand(["getVariable", "MACHINE"])[0]
build_info['distro'] = self.server.runCommand(["getVariable", "DISTRO"])[0]
build_info['distro_version'] = self.server.runCommand(["getVariable", "DISTRO_VERSION"])[0]
@@ -796,7 +899,7 @@ class BuildInfoHelper(object):
build_info['cooker_log_path'] = build_log_path
build_info['build_name'] = self.server.runCommand(["getVariable", "BUILDNAME"])[0]
build_info['bitbake_version'] = self.server.runCommand(["getVariable", "BB_VERSION"])[0]
-
+ build_info['project'] = self.project = self.server.runCommand(["getVariable", "TOASTER_PROJECT"])[0]
return build_info
def _get_task_information(self, event, recipe):
@@ -818,44 +921,15 @@ class BuildInfoHelper(object):
assert path.startswith("/")
assert 'build' in self.internal_state
- if self.brbe is None:
- def _slkey_interactive(layer_version):
- assert isinstance(layer_version, Layer_Version)
- return len(layer_version.local_path)
-
- # Heuristics: we always match recipe to the deepest layer path in the discovered layers
- for lvo in sorted(self.orm_wrapper.layer_version_objects, reverse=True, key=_slkey_interactive):
- # we can match to the recipe file path
- if path.startswith(lvo.local_path):
- return lvo
-
- else:
- br_id, be_id = self.brbe.split(":")
- from bldcontrol.bbcontroller import getBuildEnvironmentController
- bc = getBuildEnvironmentController(pk = be_id)
-
- def _slkey_managed(layer_version):
- return len(bc.getGitCloneDirectory(layer_version.giturl, layer_version.commit) + layer_version.dirpath)
-
- # Heuristics: we match the path to where the layers have been checked out
- for brl in sorted(BuildRequest.objects.get(pk = br_id).brlayer_set.all(), reverse = True, key = _slkey_managed):
- localdirname = os.path.join(bc.getGitCloneDirectory(brl.giturl, brl.commit), brl.dirpath)
- # we get a relative path, unless running in HEAD mode where the path is absolute
- if not localdirname.startswith("/"):
- localdirname = os.path.join(bc.be.sourcedir, localdirname)
- if path.startswith(localdirname):
- # If the build request came from toaster this field
- # should contain the information from the layer_version
- # That created this build request.
- if brl.layer_version:
- return brl.layer_version
-
- #logger.warn("-- managed: matched path %s with layer %s " % (path, localdirname))
- # we matched the BRLayer, but we need the layer_version that generated this br
+ def _slkey_interactive(layer_version):
+ assert isinstance(layer_version, Layer_Version)
+ return len(layer_version.local_path)
- for lvo in self.orm_wrapper.layer_version_objects:
- if brl.name == lvo.layer.name:
- return lvo
+ # Heuristics: we always match recipe to the deepest layer path in the discovered layers
+ for lvo in sorted(self.orm_wrapper.layer_version_objects, reverse=True, key=_slkey_interactive):
+ # we can match to the recipe file path
+ if path.startswith(lvo.local_path):
+ return lvo
#if we get here, we didn't read layers correctly; dump whatever information we have on the error log
logger.warn("Could not match layer version for recipe path %s : %s", path, self.orm_wrapper.layer_version_objects)
@@ -890,12 +964,10 @@ class BuildInfoHelper(object):
def _get_path_information(self, task_object):
assert isinstance(task_object, Task)
- build_stats_format = "{tmpdir}/buildstats/{target}-{machine}/{buildname}/{package}/"
+ build_stats_format = "{tmpdir}/buildstats/{buildname}/{package}/"
build_stats_path = []
for t in self.internal_state['targets']:
- target = t.target
- machine = self.internal_state['build'].machine
buildname = self.internal_state['build'].build_name
pe, pv = task_object.recipe.version.split(":",1)
if len(pe) > 0:
@@ -903,8 +975,8 @@ class BuildInfoHelper(object):
else:
package = task_object.recipe.name + "-" + pv
- build_stats_path.append(build_stats_format.format(tmpdir=self.tmp_dir, target=target,
- machine=machine, buildname=buildname,
+ build_stats_path.append(build_stats_format.format(tmpdir=self.tmp_dir,
+ buildname=buildname,
package=package))
return build_stats_path
@@ -938,6 +1010,9 @@ class BuildInfoHelper(object):
assert '_pkgs' in vars(event)
build_information = self._get_build_information(build_log_path)
+ # Update brbe and project as they can be changed for every build
+ self.project = build_information['project']
+
build_obj = self.orm_wrapper.create_build_object(build_information, self.brbe, self.project)
self.internal_state['build'] = build_obj
@@ -1059,31 +1134,11 @@ class BuildInfoHelper(object):
def store_tasks_stats(self, event):
- for (taskfile, taskname, taskstats, recipename) in BuildInfoHelper._get_data_from_event(event):
- localfilepath = taskfile.split(":")[-1]
- assert localfilepath.startswith("/")
+ task_data = BuildInfoHelper._get_data_from_event(event)
- recipe_information = self._get_recipe_information_from_taskfile(taskfile)
- try:
- if recipe_information['file_path'].startswith(recipe_information['layer_version'].local_path):
- recipe_information['file_path'] = recipe_information['file_path'][len(recipe_information['layer_version'].local_path):].lstrip("/")
-
- recipe_object = Recipe.objects.get(layer_version = recipe_information['layer_version'],
- file_path__endswith = recipe_information['file_path'],
- name = recipename)
- except Recipe.DoesNotExist:
- logger.error("Could not find recipe for recipe_information %s name %s" , pformat(recipe_information), recipename)
- raise
-
- task_information = {}
- task_information['build'] = self.internal_state['build']
- task_information['recipe'] = recipe_object
- task_information['task_name'] = taskname
- task_information['cpu_usage'] = taskstats['cpu_usage']
- task_information['disk_io'] = taskstats['disk_io']
- if 'elapsed_time' in taskstats:
- task_information['elapsed_time'] = taskstats['elapsed_time']
- self.orm_wrapper.get_update_task_object(task_information)
+ for (task_file, task_name, task_stats, recipe_name) in task_data:
+ build = self.internal_state['build']
+ self.orm_wrapper.update_task_object(build, task_name, recipe_name, task_stats)
def update_and_store_task(self, event):
assert 'taskfile' in vars(event)
@@ -1105,13 +1160,6 @@ class BuildInfoHelper(object):
recipe = self.orm_wrapper.get_update_recipe_object(recipe_information, True)
task_information = self._get_task_information(event,recipe)
- if 'time' in vars(event):
- if not 'start_time' in self.internal_state['taskdata'][identifier]:
- self.internal_state['taskdata'][identifier]['start_time'] = event.time
- else:
- task_information['end_time'] = event.time
- task_information['start_time'] = self.internal_state['taskdata'][identifier]['start_time']
-
task_information['outcome'] = self.internal_state['taskdata'][identifier]['outcome']
if 'logfile' in vars(event):
@@ -1185,11 +1233,12 @@ class BuildInfoHelper(object):
for target in self.internal_state['targets']:
if target.is_image:
pkgdata = BuildInfoHelper._get_data_from_event(event)['pkgdata']
- imgdata = BuildInfoHelper._get_data_from_event(event)['imgdata'][target.target]
- filedata = BuildInfoHelper._get_data_from_event(event)['filedata'][target.target]
+ imgdata = BuildInfoHelper._get_data_from_event(event)['imgdata'].get(target.target, {})
+ filedata = BuildInfoHelper._get_data_from_event(event)['filedata'].get(target.target, {})
try:
- self.orm_wrapper.save_target_package_information(self.internal_state['build'], target, imgdata, pkgdata, self.internal_state['recipes'])
+ self.orm_wrapper.save_target_package_information(self.internal_state['build'], target, imgdata, pkgdata, self.internal_state['recipes'], built_package=True)
+ self.orm_wrapper.save_target_package_information(self.internal_state['build'], target, imgdata.copy(), pkgdata, self.internal_state['recipes'], built_package=False)
except KeyError as e:
logger.warn("KeyError in save_target_package_information"
"%s ", e)
@@ -1269,6 +1318,9 @@ class BuildInfoHelper(object):
for cls in event._depgraph['pn'][pn]['inherits']:
if cls.endswith('/image.bbclass'):
recipe.is_image = True
+ recipe_info['is_image'] = True
+ # Save the is_image state to the relevant recipe objects
+ self.orm_wrapper.get_update_recipe_object(recipe_info)
break
if recipe.is_image:
for t in self.internal_state['targets']:
@@ -1285,15 +1337,27 @@ class BuildInfoHelper(object):
# buildtime
recipedeps_objects = []
for recipe in event._depgraph['depends']:
- try:
- target = self.internal_state['recipes'][recipe]
- for dep in event._depgraph['depends'][recipe]:
+ target = self.internal_state['recipes'][recipe]
+ for dep in event._depgraph['depends'][recipe]:
+ if dep in assume_provided:
+ continue
+ via = None
+ if 'providermap' in event._depgraph and dep in event._depgraph['providermap']:
+ deprecipe = event._depgraph['providermap'][dep][0]
+ dependency = self.internal_state['recipes'][deprecipe]
+ via = Provides.objects.get_or_create(name=dep,
+ recipe=dependency)[0]
+ elif dep in self.internal_state['recipes']:
dependency = self.internal_state['recipes'][dep]
- recipedeps_objects.append(Recipe_Dependency( recipe = target,
- depends_on = dependency, dep_type = Recipe_Dependency.TYPE_DEPENDS))
- except KeyError as e:
- if e not in assume_provided and not str(e).startswith("virtual/"):
- errormsg += " stpd: KeyError saving recipe dependency for %s, %s \n" % (recipe, e)
+ else:
+ errormsg += " stpd: KeyError saving recipe dependency for %s, %s \n" % (recipe, dep)
+ continue
+ recipe_dep = Recipe_Dependency(recipe=target,
+ depends_on=dependency,
+ via=via,
+ dep_type=Recipe_Dependency.TYPE_DEPENDS)
+ recipedeps_objects.append(recipe_dep)
+
Recipe_Dependency.objects.bulk_create(recipedeps_objects)
# save all task information
@@ -1333,10 +1397,17 @@ class BuildInfoHelper(object):
def store_build_package_information(self, event):
package_info = BuildInfoHelper._get_data_from_event(event)
- self.orm_wrapper.save_build_package_information(self.internal_state['build'],
- package_info,
- self.internal_state['recipes'],
- )
+ self.orm_wrapper.save_build_package_information(
+ self.internal_state['build'],
+ package_info,
+ self.internal_state['recipes'],
+ built_package=True)
+
+ self.orm_wrapper.save_build_package_information(
+ self.internal_state['build'],
+ package_info,
+ self.internal_state['recipes'],
+ built_package=False)
def _store_build_done(self, errorcode):
logger.info("Build exited with errorcode %d", errorcode)
@@ -1345,9 +1416,18 @@ class BuildInfoHelper(object):
be.lock = BuildEnvironment.LOCK_LOCK
be.save()
br = BuildRequest.objects.get(pk = br_id)
+
+ # if we're 'done' because we got cancelled update the build outcome
+ if br.state == BuildRequest.REQ_CANCELLING:
+ logger.info("Build cancelled")
+ br.build.outcome = Build.CANCELLED
+ br.build.save()
+ self.internal_state['build'] = br.build
+ errorcode = 0
+
if errorcode == 0:
# request archival of the project artifacts
- br.state = BuildRequest.REQ_ARCHIVE
+ br.state = BuildRequest.REQ_COMPLETED
else:
br.state = BuildRequest.REQ_FAILED
br.save()
@@ -1434,3 +1514,8 @@ class BuildInfoHelper(object):
if not connection.features.autocommits_when_autocommit_is_off:
transaction.set_autocommit(True)
+
+ # unset the brbe; this is to prevent subsequent command-line builds
+ # being incorrectly attached to the previous Toaster-triggered build;
+ # see https://bugzilla.yoctoproject.org/show_bug.cgi?id=9021
+ self.brbe = None
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/builddetailspage.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/builddetailspage.py
deleted file mode 100755
index 7fc690e2f..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/builddetailspage.py
+++ /dev/null
@@ -1,437 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2012 Intel Corporation
-#
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import pango
-import gobject
-import bb.process
-from bb.ui.crumbs.progressbar import HobProgressBar
-from bb.ui.crumbs.hobwidget import hic, HobNotebook, HobAltButton, HobWarpCellRendererText, HobButton, HobInfoButton
-from bb.ui.crumbs.runningbuild import RunningBuildTreeView
-from bb.ui.crumbs.runningbuild import BuildFailureTreeView
-from bb.ui.crumbs.hobpages import HobPage
-from bb.ui.crumbs.hobcolor import HobColors
-
-class BuildConfigurationTreeView(gtk.TreeView):
- def __init__ (self):
- gtk.TreeView.__init__(self)
- self.set_rules_hint(False)
- self.set_headers_visible(False)
- self.set_property("hover-expand", True)
- self.get_selection().set_mode(gtk.SELECTION_SINGLE)
-
- # The icon that indicates whether we're building or failed.
- renderer0 = gtk.CellRendererText()
- renderer0.set_property('font-desc', pango.FontDescription('courier bold 12'))
- col0 = gtk.TreeViewColumn ("Name", renderer0, text=0)
- self.append_column (col0)
-
- # The message of configuration.
- renderer1 = HobWarpCellRendererText(col_number=1)
- col1 = gtk.TreeViewColumn ("Values", renderer1, text=1)
- self.append_column (col1)
-
- def set_vars(self, key="", var=[""]):
- d = {}
- if type(var) == str:
- d = {key: [var]}
- elif type(var) == list and len(var) > 1:
- #create the sub item line
- l = []
- text = ""
- for item in var:
- text = " - " + item
- l.append(text)
- d = {key: var}
-
- return d
-
- def set_config_model(self, show_vars):
- listmodel = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- parent = None
- for var in show_vars:
- for subitem in var.items():
- name = subitem[0]
- is_parent = True
- for value in subitem[1]:
- if is_parent:
- parent = listmodel.append(parent, (name, value))
- is_parent = False
- else:
- listmodel.append(parent, (None, value))
- name = " - "
- parent = None
- # renew the tree model after get the configuration messages
- self.set_model(listmodel)
-
- def show(self, src_config_info, src_params):
- vars = []
- vars.append(self.set_vars("BB version:", src_params.bb_version))
- vars.append(self.set_vars("Target arch:", src_params.target_arch))
- vars.append(self.set_vars("Target OS:", src_params.target_os))
- vars.append(self.set_vars("Machine:", src_config_info.curr_mach))
- vars.append(self.set_vars("Distro:", src_config_info.curr_distro))
- vars.append(self.set_vars("Distro version:", src_params.distro_version))
- vars.append(self.set_vars("SDK machine:", src_config_info.curr_sdk_machine))
- vars.append(self.set_vars("Tune features:", src_params.tune_pkgarch))
- vars.append(self.set_vars("Layers:", src_config_info.layers))
-
- for path in src_config_info.layers:
- import os, os.path
- if os.path.exists(path):
- branch = bb.process.run('cd %s; git branch | grep "^* " | tr -d "* "' % path)[0]
- if branch.startswith("fatal:"):
- branch = "(unknown)"
- if branch:
- branch = branch.strip('\n')
- vars.append(self.set_vars("Branch:", branch))
- break
-
- self.set_config_model(vars)
-
- def reset(self):
- self.set_model(None)
-
-#
-# BuildDetailsPage
-#
-
-class BuildDetailsPage (HobPage):
-
- def __init__(self, builder):
- super(BuildDetailsPage, self).__init__(builder, "Building ...")
-
- self.num_of_issues = 0
- self.endpath = (0,)
- # create visual elements
- self.create_visual_elements()
-
- def create_visual_elements(self):
- # create visual elements
- self.vbox = gtk.VBox(False, 12)
-
- self.progress_box = gtk.VBox(False, 12)
- self.task_status = gtk.Label("\n") # to ensure layout is correct
- self.task_status.set_alignment(0.0, 0.5)
- self.progress_box.pack_start(self.task_status, expand=False, fill=False)
- self.progress_hbox = gtk.HBox(False, 6)
- self.progress_box.pack_end(self.progress_hbox, expand=True, fill=True)
- self.progress_bar = HobProgressBar()
- self.progress_hbox.pack_start(self.progress_bar, expand=True, fill=True)
- self.stop_button = HobAltButton("Stop")
- self.stop_button.connect("clicked", self.stop_button_clicked_cb)
- self.stop_button.set_sensitive(False)
- self.progress_hbox.pack_end(self.stop_button, expand=False, fill=False)
-
- self.notebook = HobNotebook()
- self.config_tv = BuildConfigurationTreeView()
- self.scrolled_view_config = gtk.ScrolledWindow ()
- self.scrolled_view_config.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
- self.scrolled_view_config.add(self.config_tv)
- self.notebook.append_page(self.scrolled_view_config, "Build configuration")
-
- self.failure_tv = BuildFailureTreeView()
- self.failure_model = self.builder.handler.build.model.failure_model()
- self.failure_tv.set_model(self.failure_model)
- self.scrolled_view_failure = gtk.ScrolledWindow ()
- self.scrolled_view_failure.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
- self.scrolled_view_failure.add(self.failure_tv)
- self.notebook.append_page(self.scrolled_view_failure, "Issues")
-
- self.build_tv = RunningBuildTreeView(readonly=True, hob=True)
- self.build_tv.set_model(self.builder.handler.build.model)
- self.scrolled_view_build = gtk.ScrolledWindow ()
- self.scrolled_view_build.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
- self.scrolled_view_build.add(self.build_tv)
- self.notebook.append_page(self.scrolled_view_build, "Log")
-
- self.builder.handler.build.model.connect_after("row-changed", self.scroll_to_present_row, self.scrolled_view_build.get_vadjustment(), self.build_tv)
-
- self.button_box = gtk.HBox(False, 6)
- self.back_button = HobAltButton('&lt;&lt; Back')
- self.back_button.connect("clicked", self.back_button_clicked_cb)
- self.button_box.pack_start(self.back_button, expand=False, fill=False)
-
- def update_build_status(self, current, total, task):
- recipe_path, recipe_task = task.split(", ")
- recipe = os.path.basename(recipe_path).rstrip(".bb")
- tsk_msg = "<b>Running task %s of %s:</b> %s\n<b>Recipe:</b> %s" % (current, total, recipe_task, recipe)
- self.task_status.set_markup(tsk_msg)
- self.stop_button.set_sensitive(True)
-
- def reset_build_status(self):
- self.task_status.set_markup("\n") # to ensure layout is correct
- self.endpath = (0,)
-
- def show_issues(self):
- self.num_of_issues += 1
- self.notebook.show_indicator_icon("Issues", self.num_of_issues)
- self.notebook.queue_draw()
-
- def reset_issues(self):
- self.num_of_issues = 0
- self.notebook.hide_indicator_icon("Issues")
-
- def _remove_all_widget(self):
- children = self.vbox.get_children() or []
- for child in children:
- self.vbox.remove(child)
- children = self.box_group_area.get_children() or []
- for child in children:
- self.box_group_area.remove(child)
- children = self.get_children() or []
- for child in children:
- self.remove(child)
-
- def add_build_fail_top_bar(self, actions, log_file=None):
- primary_action = "Edit %s" % actions
-
- color = HobColors.ERROR
- build_fail_top = gtk.EventBox()
- #build_fail_top.set_size_request(-1, 200)
- build_fail_top.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-
- build_fail_tab = gtk.Table(14, 46, True)
- build_fail_top.add(build_fail_tab)
-
- icon = gtk.Image()
- icon_pix_buffer = gtk.gdk.pixbuf_new_from_file(hic.ICON_INDI_ERROR_FILE)
- icon.set_from_pixbuf(icon_pix_buffer)
- build_fail_tab.attach(icon, 1, 4, 0, 6)
-
- label = gtk.Label()
- label.set_alignment(0.0, 0.5)
- label.set_markup("<span size='x-large'><b>%s</b></span>" % self.title)
- build_fail_tab.attach(label, 4, 26, 0, 6)
-
- label = gtk.Label()
- label.set_alignment(0.0, 0.5)
- # Ensure variable disk_full is defined
- if not hasattr(self.builder, 'disk_full'):
- self.builder.disk_full = False
-
- if self.builder.disk_full:
- markup = "<span size='medium'>There is no disk space left, so Hob cannot finish building your image. Free up some disk space\n"
- markup += "and restart the build. Check the \"Issues\" tab for more details</span>"
- label.set_markup(markup)
- else:
- label.set_markup("<span size='medium'>Check the \"Issues\" information for more details</span>")
- build_fail_tab.attach(label, 4, 40, 4, 9)
-
- # create button 'Edit packages'
- action_button = HobButton(primary_action)
- #action_button.set_size_request(-1, 40)
- action_button.set_tooltip_text("Edit the %s parameters" % actions)
- action_button.connect('clicked', self.failure_primary_action_button_clicked_cb, primary_action)
-
- if log_file:
- open_log_button = HobAltButton("Open log")
- open_log_button.set_relief(gtk.RELIEF_HALF)
- open_log_button.set_tooltip_text("Open the build's log file")
- open_log_button.connect('clicked', self.open_log_button_clicked_cb, log_file)
-
- attach_pos = (24 if log_file else 14)
- file_bug_button = HobAltButton('File a bug')
- file_bug_button.set_relief(gtk.RELIEF_HALF)
- file_bug_button.set_tooltip_text("Open the Yocto Project bug tracking website")
- file_bug_button.connect('clicked', self.failure_activate_file_bug_link_cb)
-
- if not self.builder.disk_full:
- build_fail_tab.attach(action_button, 4, 13, 9, 12)
- if log_file:
- build_fail_tab.attach(open_log_button, 14, 23, 9, 12)
- build_fail_tab.attach(file_bug_button, attach_pos, attach_pos + 9, 9, 12)
-
- else:
- restart_build = HobButton("Restart the build")
- restart_build.set_tooltip_text("Restart the build")
- restart_build.connect('clicked', self.restart_build_button_clicked_cb)
-
- build_fail_tab.attach(restart_build, 4, 13, 9, 12)
- build_fail_tab.attach(action_button, 14, 23, 9, 12)
- if log_file:
- build_fail_tab.attach(open_log_button, attach_pos, attach_pos + 9, 9, 12)
-
- self.builder.disk_full = False
- return build_fail_top
-
- def show_fail_page(self, title):
- self._remove_all_widget()
- self.title = "Hob cannot build your %s" % title
-
- self.build_fail_bar = self.add_build_fail_top_bar(title, self.builder.current_logfile)
-
- self.pack_start(self.group_align, expand=True, fill=True)
- self.box_group_area.pack_start(self.build_fail_bar, expand=False, fill=False)
- self.box_group_area.pack_start(self.vbox, expand=True, fill=True)
-
- self.vbox.pack_start(self.notebook, expand=True, fill=True)
- self.show_all()
- self.notebook.set_page("Issues")
- self.back_button.hide()
-
- def add_build_stop_top_bar(self, action, log_file=None):
- color = HobColors.LIGHT_GRAY
- build_stop_top = gtk.EventBox()
- #build_stop_top.set_size_request(-1, 200)
- build_stop_top.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
- build_stop_top.set_flags(gtk.CAN_DEFAULT)
- build_stop_top.grab_default()
-
- build_stop_tab = gtk.Table(11, 46, True)
- build_stop_top.add(build_stop_tab)
-
- icon = gtk.Image()
- icon_pix_buffer = gtk.gdk.pixbuf_new_from_file(hic.ICON_INFO_HOVER_FILE)
- icon.set_from_pixbuf(icon_pix_buffer)
- build_stop_tab.attach(icon, 1, 4, 0, 6)
-
- label = gtk.Label()
- label.set_alignment(0.0, 0.5)
- label.set_markup("<span size='x-large'><b>%s</b></span>" % self.title)
- build_stop_tab.attach(label, 4, 26, 0, 6)
-
- action_button = HobButton("Edit %s" % action)
- action_button.set_size_request(-1, 40)
- if action == "image":
- action_button.set_tooltip_text("Edit the image parameters")
- elif action == "recipes":
- action_button.set_tooltip_text("Edit the included recipes")
- elif action == "packages":
- action_button.set_tooltip_text("Edit the included packages")
- action_button.connect('clicked', self.stop_primary_action_button_clicked_cb, action)
- build_stop_tab.attach(action_button, 4, 13, 6, 9)
-
- if log_file:
- open_log_button = HobAltButton("Open log")
- open_log_button.set_relief(gtk.RELIEF_HALF)
- open_log_button.set_tooltip_text("Open the build's log file")
- open_log_button.connect('clicked', self.open_log_button_clicked_cb, log_file)
- build_stop_tab.attach(open_log_button, 14, 23, 6, 9)
-
- attach_pos = (24 if log_file else 14)
- build_button = HobAltButton("Build new image")
- #build_button.set_size_request(-1, 40)
- build_button.set_tooltip_text("Create a new image from scratch")
- build_button.connect('clicked', self.new_image_button_clicked_cb)
- build_stop_tab.attach(build_button, attach_pos, attach_pos + 9, 6, 9)
-
- return build_stop_top, action_button
-
- def show_stop_page(self, action):
- self._remove_all_widget()
- self.title = "Build stopped"
- self.build_stop_bar, action_button = self.add_build_stop_top_bar(action, self.builder.current_logfile)
-
- self.pack_start(self.group_align, expand=True, fill=True)
- self.box_group_area.pack_start(self.build_stop_bar, expand=False, fill=False)
- self.box_group_area.pack_start(self.vbox, expand=True, fill=True)
-
- self.vbox.pack_start(self.notebook, expand=True, fill=True)
- self.show_all()
- self.back_button.hide()
- return action_button
-
- def show_page(self, step):
- self._remove_all_widget()
- if step == self.builder.PACKAGE_GENERATING or step == self.builder.FAST_IMAGE_GENERATING:
- self.title = "Building packages ..."
- else:
- self.title = "Building image ..."
- self.build_details_top = self.add_onto_top_bar(None)
- self.pack_start(self.build_details_top, expand=False, fill=False)
- self.pack_start(self.group_align, expand=True, fill=True)
-
- self.box_group_area.pack_start(self.vbox, expand=True, fill=True)
-
- self.progress_bar.reset()
- self.config_tv.reset()
- self.vbox.pack_start(self.progress_box, expand=False, fill=False)
-
- self.vbox.pack_start(self.notebook, expand=True, fill=True)
-
- self.box_group_area.pack_end(self.button_box, expand=False, fill=False)
- self.show_all()
- self.notebook.set_page("Log")
- self.back_button.hide()
-
- self.reset_build_status()
- self.reset_issues()
-
- def update_progress_bar(self, title, fraction, status=None):
- self.progress_bar.update(fraction)
- self.progress_bar.set_title(title)
- self.progress_bar.set_rcstyle(status)
-
- def back_button_clicked_cb(self, button):
- self.builder.show_configuration()
-
- def new_image_button_clicked_cb(self, button):
- self.builder.reset()
-
- def show_back_button(self):
- self.back_button.show()
-
- def stop_button_clicked_cb(self, button):
- self.builder.stop_build()
-
- def hide_stop_button(self):
- self.stop_button.set_sensitive(False)
- self.stop_button.hide()
-
- def scroll_to_present_row(self, model, path, iter, v_adj, treeview):
- if treeview and v_adj:
- if path[0] > self.endpath[0]: # check the event is a new row append or not
- self.endpath = path
- # check the gtk.adjustment position is at end boundary or not
- if (v_adj.upper <= v_adj.page_size) or (v_adj.value == v_adj.upper - v_adj.page_size):
- treeview.scroll_to_cell(path)
-
- def show_configurations(self, configurations, params):
- self.config_tv.show(configurations, params)
-
- def failure_primary_action_button_clicked_cb(self, button, action):
- if "Edit recipes" in action:
- self.builder.show_recipes()
- elif "Edit packages" in action:
- self.builder.show_packages()
- elif "Edit image" in action:
- self.builder.show_configuration()
-
- def restart_build_button_clicked_cb(self, button):
- self.builder.just_bake()
-
- def stop_primary_action_button_clicked_cb(self, button, action):
- if "recipes" in action:
- self.builder.show_recipes()
- elif "packages" in action:
- self.builder.show_packages()
- elif "image" in action:
- self.builder.show_configuration()
-
- def open_log_button_clicked_cb(self, button, log_file):
- if log_file:
- log_file = "file:///" + log_file
- gtk.show_uri(screen=button.get_screen(), uri=log_file, timestamp=0)
-
- def failure_activate_file_bug_link_cb(self, button):
- button.child.emit('activate-link', "http://bugzilla.yoctoproject.org")
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/builder.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/builder.py
deleted file mode 100755
index dcc410426..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/builder.py
+++ /dev/null
@@ -1,1475 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011-2012 Intel Corporation
-#
-# Authored by Joshua Lock <josh@linux.intel.com>
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import glib
-import gtk, gobject
-import copy
-import os
-import subprocess
-import shlex
-import re
-import logging
-import sys
-import signal
-import time
-from bb.ui.crumbs.imageconfigurationpage import ImageConfigurationPage
-from bb.ui.crumbs.recipeselectionpage import RecipeSelectionPage
-from bb.ui.crumbs.packageselectionpage import PackageSelectionPage
-from bb.ui.crumbs.builddetailspage import BuildDetailsPage
-from bb.ui.crumbs.imagedetailspage import ImageDetailsPage
-from bb.ui.crumbs.sanitycheckpage import SanityCheckPage
-from bb.ui.crumbs.hobwidget import hwc, HobButton, HobAltButton
-from bb.ui.crumbs.persistenttooltip import PersistentTooltip
-import bb.ui.crumbs.utils
-from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
-from bb.ui.crumbs.hig.simplesettingsdialog import SimpleSettingsDialog
-from bb.ui.crumbs.hig.advancedsettingsdialog import AdvancedSettingsDialog
-from bb.ui.crumbs.hig.deployimagedialog import DeployImageDialog
-from bb.ui.crumbs.hig.layerselectiondialog import LayerSelectionDialog
-from bb.ui.crumbs.hig.imageselectiondialog import ImageSelectionDialog
-from bb.ui.crumbs.hig.parsingwarningsdialog import ParsingWarningsDialog
-from bb.ui.crumbs.hig.propertydialog import PropertyDialog
-
-hobVer = 20120808
-
-class Configuration:
- '''Represents the data structure of configuration.'''
-
- @classmethod
- def parse_proxy_string(cls, proxy):
- pattern = "^\s*((http|https|ftp|socks|cvs)://)?((\S+):(\S+)@)?([^\s:]+)(:(\d+))?/?"
- match = re.search(pattern, proxy)
- if match:
- return match.group(2), match.group(4), match.group(5), match.group(6), match.group(8)
- else:
- return None, None, None, "", ""
-
- @classmethod
- def make_host_string(cls, prot, user, passwd, host, default_prot=""):
- if host == None or host == "":
- return ""
-
- passwd = passwd or ""
-
- if user != None and user != "":
- if prot == None or prot == "":
- prot = default_prot
- return prot + "://" + user + ":" + passwd + "@" + host
- else:
- if prot == None or prot == "":
- return host
- else:
- return prot + "://" + host
-
- @classmethod
- def make_port_string(cls, port):
- port = port or ""
- return port
-
- @classmethod
- def make_proxy_string(cls, prot, user, passwd, host, port, default_prot=""):
- if host == None or host == "":# or port == None or port == "":
- return ""
-
- return Configuration.make_host_string(prot, user, passwd, host, default_prot) + (":" + Configuration.make_port_string(port) if port else "")
-
- def __init__(self):
- self.curr_mach = ""
- self.selected_image = None
- # settings
- self.curr_distro = ""
- self.dldir = self.sstatedir = self.sstatemirror = ""
- self.pmake = self.bbthread = 0
- self.curr_package_format = ""
- self.image_rootfs_size = self.image_extra_size = 0
- self.image_overhead_factor = 1
- self.incompat_license = ""
- self.curr_sdk_machine = ""
- self.conf_version = self.lconf_version = ""
- self.extra_setting = {}
- self.toolchain_build = False
- self.image_fstypes = ""
- self.image_size = None
- self.image_packages = []
- # bblayers.conf
- self.layers = []
- # image/recipes/packages
- self.clear_selection()
-
- self.user_selected_packages = []
-
- self.default_task = "build"
-
- # proxy settings
- self.enable_proxy = None
- self.same_proxy = False
- self.proxies = {
- "http" : [None, None, None, "", ""], # protocol : [prot, user, passwd, host, port]
- "https" : [None, None, None, "", ""],
- "ftp" : [None, None, None, "", ""],
- "socks" : [None, None, None, "", ""],
- "cvs" : [None, None, None, "", ""],
- }
-
- def clear_selection(self):
- self.selected_recipes = []
- self.selected_packages = []
- self.initial_selected_image = None
- self.initial_selected_packages = []
- self.initial_user_selected_packages = []
-
- def split_proxy(self, protocol, proxy):
- entry = []
- prot, user, passwd, host, port = Configuration.parse_proxy_string(proxy)
- entry.append(prot)
- entry.append(user)
- entry.append(passwd)
- entry.append(host)
- entry.append(port)
- self.proxies[protocol] = entry
-
- def combine_proxy(self, protocol):
- entry = self.proxies[protocol]
- return Configuration.make_proxy_string(entry[0], entry[1], entry[2], entry[3], entry[4], protocol)
-
- def combine_host_only(self, protocol):
- entry = self.proxies[protocol]
- return Configuration.make_host_string(entry[0], entry[1], entry[2], entry[3], protocol)
-
- def combine_port_only(self, protocol):
- entry = self.proxies[protocol]
- return Configuration.make_port_string(entry[4])
-
- def update(self, params):
- # settings
- self.curr_distro = params["distro"]
- self.dldir = params["dldir"]
- self.sstatedir = params["sstatedir"]
- self.sstatemirror = params["sstatemirror"]
- self.pmake = int(params["pmake"].split()[1])
- self.bbthread = params["bbthread"]
- self.curr_package_format = " ".join(params["pclass"].split("package_")).strip()
- self.image_rootfs_size = params["image_rootfs_size"]
- self.image_extra_size = params["image_extra_size"]
- self.image_overhead_factor = params['image_overhead_factor']
- self.incompat_license = params["incompat_license"]
- self.curr_sdk_machine = params["sdk_machine"]
- self.conf_version = params["conf_version"]
- self.lconf_version = params["lconf_version"]
- self.image_fstypes = params["image_fstypes"]
- # self.extra_setting/self.toolchain_build
- # bblayers.conf
- self.layers = params["layer"].split()
- self.layers_non_removable = params["layers_non_removable"].split()
- self.default_task = params["default_task"]
-
- # proxy settings
- self.enable_proxy = params["http_proxy"] != "" or params["https_proxy"] != "" \
- or params["ftp_proxy"] != "" or params["socks_proxy"] != "" \
- or params["cvs_proxy_host"] != "" or params["cvs_proxy_port"] != ""
- self.split_proxy("http", params["http_proxy"])
- self.split_proxy("https", params["https_proxy"])
- self.split_proxy("ftp", params["ftp_proxy"])
- self.split_proxy("socks", params["socks_proxy"])
- self.split_proxy("cvs", params["cvs_proxy_host"] + ":" + params["cvs_proxy_port"])
-
- def save(self, handler, defaults=False):
- # bblayers.conf
- handler.set_var_in_file("BBLAYERS", self.layers, "bblayers.conf")
- # local.conf
- if not defaults:
- handler.early_assign_var_in_file("MACHINE", self.curr_mach, "local.conf")
- handler.set_var_in_file("DISTRO", self.curr_distro, "local.conf")
- handler.set_var_in_file("DL_DIR", self.dldir, "local.conf")
- handler.set_var_in_file("SSTATE_DIR", self.sstatedir, "local.conf")
- sstate_mirror_list = self.sstatemirror.split("\\n ")
- sstate_mirror_list_modified = []
- for mirror in sstate_mirror_list:
- if mirror != "":
- mirror = mirror + "\\n"
- sstate_mirror_list_modified.append(mirror)
- handler.set_var_in_file("SSTATE_MIRRORS", sstate_mirror_list_modified, "local.conf")
- handler.set_var_in_file("PARALLEL_MAKE", "-j %s" % self.pmake, "local.conf")
- handler.set_var_in_file("BB_NUMBER_THREADS", self.bbthread, "local.conf")
- handler.set_var_in_file("PACKAGE_CLASSES", " ".join(["package_" + i for i in self.curr_package_format.split()]), "local.conf")
- handler.set_var_in_file("IMAGE_ROOTFS_SIZE", self.image_rootfs_size, "local.conf")
- handler.set_var_in_file("IMAGE_EXTRA_SPACE", self.image_extra_size, "local.conf")
- handler.set_var_in_file("INCOMPATIBLE_LICENSE", self.incompat_license, "local.conf")
- handler.set_var_in_file("SDKMACHINE", self.curr_sdk_machine, "local.conf")
- handler.set_var_in_file("CONF_VERSION", self.conf_version, "local.conf")
- handler.set_var_in_file("LCONF_VERSION", self.lconf_version, "bblayers.conf")
- handler.set_extra_config(self.extra_setting)
- handler.set_var_in_file("TOOLCHAIN_BUILD", self.toolchain_build, "local.conf")
- handler.set_var_in_file("IMAGE_FSTYPES", self.image_fstypes, "local.conf")
- if not defaults:
- # image/recipes/packages
- handler.set_var_in_file("__SELECTED_IMAGE__", self.selected_image, "local.conf")
- handler.set_var_in_file("DEPENDS", self.selected_recipes, "local.conf")
- handler.set_var_in_file("IMAGE_INSTALL", self.user_selected_packages, "local.conf")
- # proxy
- if self.enable_proxy == True:
- handler.set_var_in_file("http_proxy", self.combine_proxy("http"), "local.conf")
- handler.set_var_in_file("https_proxy", self.combine_proxy("https"), "local.conf")
- handler.set_var_in_file("ftp_proxy", self.combine_proxy("ftp"), "local.conf")
- handler.set_var_in_file("all_proxy", self.combine_proxy("socks"), "local.conf")
- handler.set_var_in_file("CVS_PROXY_HOST", self.combine_host_only("cvs"), "local.conf")
- handler.set_var_in_file("CVS_PROXY_PORT", self.combine_port_only("cvs"), "local.conf")
- else:
- handler.set_var_in_file("http_proxy", "", "local.conf")
- handler.set_var_in_file("https_proxy", "", "local.conf")
- handler.set_var_in_file("ftp_proxy", "", "local.conf")
- handler.set_var_in_file("all_proxy", "", "local.conf")
- handler.set_var_in_file("CVS_PROXY_HOST", "", "local.conf")
- handler.set_var_in_file("CVS_PROXY_PORT", "", "local.conf")
-
- def __str__(self):
- s = "VERSION: '%s', BBLAYERS: '%s', MACHINE: '%s', DISTRO: '%s', DL_DIR: '%s'," % \
- (hobVer, " ".join(self.layers), self.curr_mach, self.curr_distro, self.dldir )
- s += "SSTATE_DIR: '%s', SSTATE_MIRROR: '%s', PARALLEL_MAKE: '-j %s', BB_NUMBER_THREADS: '%s', PACKAGE_CLASSES: '%s', " % \
- (self.sstatedir, self.sstatemirror, self.pmake, self.bbthread, " ".join(["package_" + i for i in self.curr_package_format.split()]))
- s += "IMAGE_ROOTFS_SIZE: '%s', IMAGE_EXTRA_SPACE: '%s', INCOMPATIBLE_LICENSE: '%s', SDKMACHINE: '%s', CONF_VERSION: '%s', " % \
- (self.image_rootfs_size, self.image_extra_size, self.incompat_license, self.curr_sdk_machine, self.conf_version)
- s += "LCONF_VERSION: '%s', EXTRA_SETTING: '%s', TOOLCHAIN_BUILD: '%s', IMAGE_FSTYPES: '%s', __SELECTED_IMAGE__: '%s', " % \
- (self.lconf_version, self.extra_setting, self.toolchain_build, self.image_fstypes, self.selected_image)
- s += "DEPENDS: '%s', IMAGE_INSTALL: '%s', enable_proxy: '%s', use_same_proxy: '%s', http_proxy: '%s', " % \
- (self.selected_recipes, self.user_selected_packages, self.enable_proxy, self.same_proxy, self.combine_proxy("http"))
- s += "https_proxy: '%s', ftp_proxy: '%s', all_proxy: '%s', CVS_PROXY_HOST: '%s', CVS_PROXY_PORT: '%s'" % \
- (self.combine_proxy("https"), self.combine_proxy("ftp"), self.combine_proxy("socks"),
- self.combine_host_only("cvs"), self.combine_port_only("cvs"))
- return s
-
-class Parameters:
- '''Represents other variables like available machines, etc.'''
-
- def __init__(self):
- # Variables
- self.max_threads = 65535
- self.core_base = ""
- self.image_addr = ""
- self.image_types = []
- self.runnable_image_types = []
- self.runnable_machine_patterns = []
- self.deployable_image_types = []
- self.tmpdir = ""
-
- self.all_machines = []
- self.all_package_formats = []
- self.all_distros = []
- self.all_sdk_machines = []
- self.all_layers = []
- self.image_names = []
- self.image_white_pattern = ""
- self.image_black_pattern = ""
-
- # for build log to show
- self.bb_version = ""
- self.target_arch = ""
- self.target_os = ""
- self.distro_version = ""
- self.tune_pkgarch = ""
-
- def update(self, params):
- self.max_threads = params["max_threads"]
- self.core_base = params["core_base"]
- self.image_addr = params["image_addr"]
- self.image_types = params["image_types"].split()
- self.runnable_image_types = params["runnable_image_types"].split()
- self.runnable_machine_patterns = params["runnable_machine_patterns"].split()
- self.deployable_image_types = params["deployable_image_types"].split()
- self.tmpdir = params["tmpdir"]
- self.image_white_pattern = params["image_white_pattern"]
- self.image_black_pattern = params["image_black_pattern"]
- self.kernel_image_type = params["kernel_image_type"]
- # for build log to show
- self.bb_version = params["bb_version"]
- self.target_arch = params["target_arch"]
- self.target_os = params["target_os"]
- self.distro_version = params["distro_version"]
- self.tune_pkgarch = params["tune_pkgarch"]
-
-def hob_conf_filter(fn, data):
- if fn.endswith("/local.conf"):
- distro = data.getVar("DISTRO_HOB", False)
- if distro:
- if distro != "defaultsetup":
- data.setVar("DISTRO", distro)
- else:
- data.delVar("DISTRO")
-
- keys = ["MACHINE_HOB", "SDKMACHINE_HOB", "PACKAGE_CLASSES_HOB", \
- "BB_NUMBER_THREADS_HOB", "PARALLEL_MAKE_HOB", "DL_DIR_HOB", \
- "SSTATE_DIR_HOB", "SSTATE_MIRRORS_HOB", "INCOMPATIBLE_LICENSE_HOB"]
- for key in keys:
- var_hob = data.getVar(key, False)
- if var_hob:
- data.setVar(key.split("_HOB")[0], var_hob)
- return
-
- if fn.endswith("/bblayers.conf"):
- layers = data.getVar("BBLAYERS_HOB", False)
- if layers:
- data.setVar("BBLAYERS", layers)
- return
-
-class Builder(gtk.Window):
-
- (INITIAL_CHECKS,
- MACHINE_SELECTION,
- RCPPKGINFO_POPULATING,
- RCPPKGINFO_POPULATED,
- BASEIMG_SELECTED,
- RECIPE_SELECTION,
- PACKAGE_GENERATING,
- PACKAGE_GENERATED,
- PACKAGE_SELECTION,
- FAST_IMAGE_GENERATING,
- IMAGE_GENERATING,
- IMAGE_GENERATED,
- MY_IMAGE_OPENED,
- BACK,
- END_NOOP) = range(15)
-
- (SANITY_CHECK,
- IMAGE_CONFIGURATION,
- RECIPE_DETAILS,
- BUILD_DETAILS,
- PACKAGE_DETAILS,
- IMAGE_DETAILS,
- END_TAB) = range(7)
-
- __step2page__ = {
- INITIAL_CHECKS : SANITY_CHECK,
- MACHINE_SELECTION : IMAGE_CONFIGURATION,
- RCPPKGINFO_POPULATING : IMAGE_CONFIGURATION,
- RCPPKGINFO_POPULATED : IMAGE_CONFIGURATION,
- BASEIMG_SELECTED : IMAGE_CONFIGURATION,
- RECIPE_SELECTION : RECIPE_DETAILS,
- PACKAGE_GENERATING : BUILD_DETAILS,
- PACKAGE_GENERATED : PACKAGE_DETAILS,
- PACKAGE_SELECTION : PACKAGE_DETAILS,
- FAST_IMAGE_GENERATING : BUILD_DETAILS,
- IMAGE_GENERATING : BUILD_DETAILS,
- IMAGE_GENERATED : IMAGE_DETAILS,
- MY_IMAGE_OPENED : IMAGE_DETAILS,
- END_NOOP : None,
- }
-
- SANITY_CHECK_MIN_DISPLAY_TIME = 5
-
- def __init__(self, hobHandler, recipe_model, package_model):
- super(Builder, self).__init__()
-
- self.hob_image = "hob-image"
-
- # handler
- self.handler = hobHandler
-
- # logger
- self.logger = logging.getLogger("BitBake")
- self.consolelog = None
- self.current_logfile = None
-
- # configuration and parameters
- self.configuration = Configuration()
- self.parameters = Parameters()
-
- # build step
- self.current_step = None
- self.previous_step = None
-
- self.stopping = False
-
- # recipe model and package model
- self.recipe_model = recipe_model
- self.package_model = package_model
-
- # Indicate whether user has customized the image
- self.customized = False
-
- # Indicate whether the UI is working
- self.sensitive = True
-
- # Indicate whether the sanity check ran
- self.sanity_checked = False
-
- # save parsing warnings
- self.parsing_warnings = []
-
- # create visual elements
- self.create_visual_elements()
-
- # connect the signals to functions
- self.connect("delete-event", self.destroy_window_cb)
- self.recipe_model.connect ("recipe-selection-changed", self.recipelist_changed_cb)
- self.package_model.connect("package-selection-changed", self.packagelist_changed_cb)
- self.handler.connect("config-updated", self.handler_config_updated_cb)
- self.handler.connect("package-formats-updated", self.handler_package_formats_updated_cb)
- self.handler.connect("parsing-started", self.handler_parsing_started_cb)
- self.handler.connect("parsing", self.handler_parsing_cb)
- self.handler.connect("parsing-completed", self.handler_parsing_completed_cb)
- self.handler.build.connect("build-started", self.handler_build_started_cb)
- self.handler.build.connect("build-succeeded", self.handler_build_succeeded_cb)
- self.handler.build.connect("build-failed", self.handler_build_failed_cb)
- self.handler.build.connect("build-aborted", self.handler_build_aborted_cb)
- self.handler.build.connect("task-started", self.handler_task_started_cb)
- self.handler.build.connect("disk-full", self.handler_disk_full_cb)
- self.handler.build.connect("log-error", self.handler_build_failure_cb)
- self.handler.build.connect("log-warning", self.handler_build_failure_cb)
- self.handler.build.connect("log", self.handler_build_log_cb)
- self.handler.build.connect("no-provider", self.handler_no_provider_cb)
- self.handler.connect("generating-data", self.handler_generating_data_cb)
- self.handler.connect("data-generated", self.handler_data_generated_cb)
- self.handler.connect("command-succeeded", self.handler_command_succeeded_cb)
- self.handler.connect("command-failed", self.handler_command_failed_cb)
- self.handler.connect("parsing-warning", self.handler_parsing_warning_cb)
- self.handler.connect("sanity-failed", self.handler_sanity_failed_cb)
- self.handler.connect("recipe-populated", self.handler_recipe_populated_cb)
- self.handler.connect("package-populated", self.handler_package_populated_cb)
-
- self.handler.append_to_bbfiles("${TOPDIR}/recipes/images/custom/*.bb")
- self.handler.append_to_bbfiles("${TOPDIR}/recipes/images/*.bb")
- self.initiate_new_build_async()
-
- signal.signal(signal.SIGINT, self.event_handle_SIGINT)
-
- def create_visual_elements(self):
- self.set_title("Hob")
- self.set_icon_name("applications-development")
- self.set_resizable(True)
-
- try:
- window_width = self.get_screen().get_width()
- window_height = self.get_screen().get_height()
- except AttributeError:
- print "Please set DISPLAY variable before running Hob."
- sys.exit(1)
-
- if window_width >= hwc.MAIN_WIN_WIDTH:
- window_width = hwc.MAIN_WIN_WIDTH
- window_height = hwc.MAIN_WIN_HEIGHT
- self.set_size_request(window_width, window_height)
-
- self.vbox = gtk.VBox(False, 0)
- self.vbox.set_border_width(0)
- self.add(self.vbox)
-
- # create pages
- self.image_configuration_page = ImageConfigurationPage(self)
- self.recipe_details_page = RecipeSelectionPage(self)
- self.build_details_page = BuildDetailsPage(self)
- self.package_details_page = PackageSelectionPage(self)
- self.image_details_page = ImageDetailsPage(self)
- self.sanity_check_page = SanityCheckPage(self)
- self.display_sanity_check = False
- self.sanity_check_post_func = False
- self.had_network_error = False
-
- self.nb = gtk.Notebook()
- self.nb.set_show_tabs(False)
- self.nb.insert_page(self.sanity_check_page, None, self.SANITY_CHECK)
- self.nb.insert_page(self.image_configuration_page, None, self.IMAGE_CONFIGURATION)
- self.nb.insert_page(self.recipe_details_page, None, self.RECIPE_DETAILS)
- self.nb.insert_page(self.build_details_page, None, self.BUILD_DETAILS)
- self.nb.insert_page(self.package_details_page, None, self.PACKAGE_DETAILS)
- self.nb.insert_page(self.image_details_page, None, self.IMAGE_DETAILS)
- self.vbox.pack_start(self.nb, expand=True, fill=True)
-
- self.show_all()
- self.nb.set_current_page(0)
-
- def sanity_check_timeout(self):
- # The minimum time for showing the 'sanity check' page has passe
- # If someone set the 'sanity_check_post_step' meanwhile, execute it now
- self.display_sanity_check = False
- if self.sanity_check_post_func:
- temp = self.sanity_check_post_func
- self.sanity_check_post_func = None
- temp()
- return False
-
- def show_sanity_check_page(self):
- # This window must stay on screen for at least 5 seconds, according to the design document
- self.nb.set_current_page(self.SANITY_CHECK)
- self.sanity_check_post_step = None
- self.display_sanity_check = True
- self.sanity_check_page.start()
- gobject.timeout_add(self.SANITY_CHECK_MIN_DISPLAY_TIME * 1000, self.sanity_check_timeout)
-
- def execute_after_sanity_check(self, func):
- if not self.display_sanity_check:
- func()
- else:
- self.sanity_check_post_func = func
-
- def generate_configuration(self):
- if not self.sanity_checked:
- self.show_sanity_check_page()
- self.handler.generate_configuration()
-
- def initiate_new_build_async(self):
- self.configuration.selected_image = None
- self.switch_page(self.MACHINE_SELECTION)
- self.handler.init_cooker()
- self.handler.set_extra_inherit("image_types")
- self.generate_configuration()
-
- def update_config_async(self):
- self.set_user_config()
- self.generate_configuration()
- self.switch_page(self.MACHINE_SELECTION)
-
- def sanity_check(self):
- self.handler.trigger_sanity_check()
-
- def populate_recipe_package_info_async(self):
- self.switch_page(self.RCPPKGINFO_POPULATING)
- # Parse recipes
- self.set_user_config()
- self.handler.generate_recipes()
-
- def generate_packages_async(self, log = False):
- self.switch_page(self.PACKAGE_GENERATING)
- if log:
- self.current_logfile = self.handler.get_logfile()
- self.do_log(self.current_logfile)
- # Build packages
- _, all_recipes = self.recipe_model.get_selected_recipes()
- self.set_user_config()
- self.handler.reset_build()
- self.handler.generate_packages(all_recipes, self.configuration.default_task)
-
- def restore_initial_selected_packages(self):
- self.package_model.set_selected_packages(self.configuration.initial_user_selected_packages, True)
- self.package_model.set_selected_packages(self.configuration.initial_selected_packages)
- for package in self.configuration.selected_packages:
- if package not in self.configuration.initial_selected_packages:
- self.package_model.exclude_item(self.package_model.find_path_for_item(package))
-
- def fast_generate_image_async(self, log = False):
- self.switch_page(self.FAST_IMAGE_GENERATING)
- if log:
- self.current_logfile = self.handler.get_logfile()
- self.do_log(self.current_logfile)
- # Build packages
- _, all_recipes = self.recipe_model.get_selected_recipes()
- self.set_user_config()
- self.handler.reset_build()
- self.handler.generate_packages(all_recipes, self.configuration.default_task)
-
- def generate_image_async(self, cont = False):
- self.switch_page(self.IMAGE_GENERATING)
- self.handler.reset_build()
- if not cont:
- self.current_logfile = self.handler.get_logfile()
- self.do_log(self.current_logfile)
- # Build image
- self.set_user_config()
- toolchain_packages = []
- base_image = None
- if self.configuration.toolchain_build:
- toolchain_packages = self.package_model.get_selected_packages_toolchain()
- if self.configuration.selected_image == self.recipe_model.__custom_image__:
- packages = self.package_model.get_selected_packages()
- image = self.hob_image
- base_image = self.configuration.initial_selected_image
- else:
- packages = []
- image = self.configuration.selected_image
- self.handler.generate_image(image,
- base_image,
- packages,
- toolchain_packages,
- self.configuration.default_task)
-
- def generate_new_image(self, image, description):
- base_image = self.configuration.initial_selected_image
- if base_image == self.recipe_model.__custom_image__:
- base_image = None
- packages = self.package_model.get_selected_packages()
- self.handler.generate_new_image(image, base_image, packages, description)
-
- def ensure_dir(self, directory):
- self.handler.ensure_dir(directory)
-
- def get_parameters_sync(self):
- return self.handler.get_parameters()
-
- def request_package_info_async(self):
- self.handler.request_package_info()
-
- def cancel_build_sync(self, force=False):
- self.handler.cancel_build(force)
-
- def cancel_parse_sync(self):
- self.handler.cancel_parse()
-
- def switch_page(self, next_step):
- # Main Workflow (Business Logic)
- self.nb.set_current_page(self.__step2page__[next_step])
-
- if next_step == self.MACHINE_SELECTION: # init step
- self.image_configuration_page.show_machine()
-
- elif next_step == self.RCPPKGINFO_POPULATING:
- # MACHINE CHANGED action or SETTINGS CHANGED
- # show the progress bar
- self.image_configuration_page.show_info_populating()
-
- elif next_step == self.RCPPKGINFO_POPULATED:
- self.image_configuration_page.show_info_populated()
-
- elif next_step == self.BASEIMG_SELECTED:
- self.image_configuration_page.show_baseimg_selected()
-
- elif next_step == self.RECIPE_SELECTION:
- if self.recipe_model.get_selected_image() == self.recipe_model.__custom_image__:
- self.recipe_details_page.set_recipe_curr_tab(self.recipe_details_page.ALL)
- else:
- self.recipe_details_page.set_recipe_curr_tab(self.recipe_details_page.INCLUDED)
-
- elif next_step == self.PACKAGE_SELECTION:
- self.configuration.initial_selected_packages = self.configuration.selected_packages
- self.configuration.initial_user_selected_packages = self.configuration.user_selected_packages
- self.package_details_page.set_title("Edit packages")
- if self.recipe_model.get_selected_image() == self.recipe_model.__custom_image__:
- self.package_details_page.set_packages_curr_tab(self.package_details_page.ALL)
- else:
- self.package_details_page.set_packages_curr_tab(self.package_details_page.INCLUDED)
- self.package_details_page.show_page(self.current_logfile)
-
-
- elif next_step == self.PACKAGE_GENERATING or next_step == self.FAST_IMAGE_GENERATING:
- # both PACKAGE_GENERATING and FAST_IMAGE_GENERATING share the same page
- self.build_details_page.show_page(next_step)
-
- elif next_step == self.PACKAGE_GENERATED:
- self.package_details_page.set_title("Step 2 of 2: Edit packages")
- if self.recipe_model.get_selected_image() == self.recipe_model.__custom_image__:
- self.package_details_page.set_packages_curr_tab(self.package_details_page.ALL)
- else:
- self.package_details_page.set_packages_curr_tab(self.package_details_page.INCLUDED)
- self.package_details_page.show_page(self.current_logfile)
-
- elif next_step == self.IMAGE_GENERATING:
- # after packages are generated, selected_packages need to
- # be updated in package_model per selected_image in recipe_model
- self.build_details_page.show_page(next_step)
-
- elif next_step == self.IMAGE_GENERATED:
- self.image_details_page.show_page(next_step)
-
- elif next_step == self.MY_IMAGE_OPENED:
- self.image_details_page.show_page(next_step)
-
- self.previous_step = self.current_step
- self.current_step = next_step
-
- def set_user_config_proxies(self):
- if self.configuration.enable_proxy == True:
- self.handler.set_http_proxy(self.configuration.combine_proxy("http"))
- self.handler.set_https_proxy(self.configuration.combine_proxy("https"))
- self.handler.set_ftp_proxy(self.configuration.combine_proxy("ftp"))
- self.handler.set_socks_proxy(self.configuration.combine_proxy("socks"))
- self.handler.set_cvs_proxy(self.configuration.combine_host_only("cvs"), self.configuration.combine_port_only("cvs"))
- elif self.configuration.enable_proxy == False:
- self.handler.set_http_proxy("")
- self.handler.set_https_proxy("")
- self.handler.set_ftp_proxy("")
- self.handler.set_socks_proxy("")
- self.handler.set_cvs_proxy("", "")
-
- def set_user_config_extra(self):
- self.handler.set_rootfs_size(self.configuration.image_rootfs_size)
- self.handler.set_extra_size(self.configuration.image_extra_size)
- self.handler.set_incompatible_license(self.configuration.incompat_license)
- self.handler.set_sdk_machine(self.configuration.curr_sdk_machine)
- self.handler.set_image_fstypes(self.configuration.image_fstypes)
- self.handler.set_extra_config(self.configuration.extra_setting)
- self.handler.set_extra_inherit("packageinfo image_types")
- self.set_user_config_proxies()
-
- def set_user_config(self):
- # set bb layers
- self.handler.set_bblayers(self.configuration.layers)
- # set local configuration
- self.handler.set_machine(self.configuration.curr_mach)
- self.handler.set_package_format(self.configuration.curr_package_format)
- self.handler.set_distro(self.configuration.curr_distro)
- self.handler.set_dl_dir(self.configuration.dldir)
- self.handler.set_sstate_dir(self.configuration.sstatedir)
- self.handler.set_sstate_mirrors(self.configuration.sstatemirror)
- self.handler.set_pmake(self.configuration.pmake)
- self.handler.set_bbthreads(self.configuration.bbthread)
- self.set_user_config_extra()
-
- def update_recipe_model(self, selected_image, selected_recipes):
- self.recipe_model.set_selected_image(selected_image)
- self.recipe_model.set_selected_recipes(selected_recipes)
-
- def update_package_model(self, selected_packages, user_selected_packages=None):
- if user_selected_packages:
- left = self.package_model.set_selected_packages(user_selected_packages, True)
- self.configuration.user_selected_packages += left
- left = self.package_model.set_selected_packages(selected_packages)
- self.configuration.selected_packages += left
-
- def update_configuration_parameters(self, params):
- if params:
- self.configuration.update(params)
- self.parameters.update(params)
-
- def set_base_image(self):
- self.configuration.initial_selected_image = self.configuration.selected_image
- if self.configuration.selected_image != self.recipe_model.__custom_image__:
- self.hob_image = self.configuration.selected_image + "-edited"
-
- def reset(self):
- self.configuration.curr_mach = ""
- self.configuration.clear_selection()
- self.image_configuration_page.switch_machine_combo()
- self.switch_page(self.MACHINE_SELECTION)
-
- # Callback Functions
- def handler_config_updated_cb(self, handler, which, values):
- if which == "distro":
- self.parameters.all_distros = values
- elif which == "machine":
- self.parameters.all_machines = values
- self.image_configuration_page.update_machine_combo()
- elif which == "machine-sdk":
- self.parameters.all_sdk_machines = values
-
- def handler_package_formats_updated_cb(self, handler, formats):
- self.parameters.all_package_formats = formats
-
- def switch_to_image_configuration_helper(self):
- self.sanity_check_page.stop()
- self.switch_page(self.IMAGE_CONFIGURATION)
- self.image_configuration_page.switch_machine_combo()
-
- def show_network_error_dialog_helper(self):
- self.sanity_check_page.stop()
- self.show_network_error_dialog()
-
- def handler_command_succeeded_cb(self, handler, initcmd):
- if initcmd == self.handler.GENERATE_CONFIGURATION:
- if not self.configuration.curr_mach:
- self.configuration.curr_mach = self.handler.runCommand(["getVariable", "HOB_MACHINE"]) or ""
- self.update_configuration_parameters(self.get_parameters_sync())
- if not self.sanity_checked:
- self.sanity_check()
- self.sanity_checked = True
- elif initcmd == self.handler.SANITY_CHECK:
- if self.had_network_error:
- self.had_network_error = False
- self.execute_after_sanity_check(self.show_network_error_dialog_helper)
- else:
- # Switch to the 'image configuration' page now, but we might need
- # to wait for the minimum display time of the sanity check page
- self.execute_after_sanity_check(self.switch_to_image_configuration_helper)
- elif initcmd in [self.handler.GENERATE_RECIPES,
- self.handler.GENERATE_PACKAGES,
- self.handler.GENERATE_IMAGE]:
- self.update_configuration_parameters(self.get_parameters_sync())
- self.request_package_info_async()
- elif initcmd == self.handler.POPULATE_PACKAGEINFO:
- if self.current_step == self.RCPPKGINFO_POPULATING:
- self.switch_page(self.RCPPKGINFO_POPULATED)
- self.rcppkglist_populated()
- return
-
- self.rcppkglist_populated()
- if self.current_step == self.FAST_IMAGE_GENERATING:
- self.generate_image_async(True)
-
- def show_error_dialog(self, msg):
- lbl = "<b>Hob found an error</b>"
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- response = dialog.run()
- dialog.destroy()
-
- def show_warning_dialog(self):
- dialog = ParsingWarningsDialog(title = "View warnings",
- warnings = self.parsing_warnings,
- parent = None,
- flags = gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
- response = dialog.run()
- dialog.destroy()
-
- def show_network_error_dialog(self):
- lbl = "<b>Hob cannot connect to the network</b>"
- msg = msg + "Please check your network connection. If you are using a proxy server, please make sure it is configured correctly."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- button = dialog.add_button("Proxy settings", gtk.RESPONSE_CANCEL)
- HobButton.style_button(button)
- res = dialog.run()
- dialog.destroy()
- if res == gtk.RESPONSE_CANCEL:
- res, settings_changed = self.show_simple_settings_dialog(SimpleSettingsDialog.PROXIES_PAGE_ID)
- if not res:
- return
- if settings_changed:
- self.reparse_post_adv_settings()
-
- def handler_command_failed_cb(self, handler, msg):
- if msg:
- self.show_error_dialog(msg)
- self.reset()
-
- def handler_parsing_warning_cb(self, handler, warn_msg):
- self.parsing_warnings.append(warn_msg)
-
- def handler_sanity_failed_cb(self, handler, msg, network_error):
- self.reset()
- if network_error:
- # Mark this in an internal field. The "network error" dialog will be
- # shown later, when a SanityCheckPassed event will be handled
- # (as sent by sanity.bbclass)
- self.had_network_error = True
- else:
- msg = msg.replace("your local.conf", "Settings")
- self.show_error_dialog(msg)
- self.reset()
-
- def window_sensitive(self, sensitive):
- self.image_configuration_page.machine_combo.set_sensitive(sensitive)
- self.image_configuration_page.machine_combo.child.set_sensitive(sensitive)
- self.image_configuration_page.image_combo.set_sensitive(sensitive)
- self.image_configuration_page.image_combo.child.set_sensitive(sensitive)
- self.image_configuration_page.layer_button.set_sensitive(sensitive)
- self.image_configuration_page.layer_info_icon.set_sensitive(sensitive)
- self.image_configuration_page.toolbar.set_sensitive(sensitive)
- self.image_configuration_page.view_adv_configuration_button.set_sensitive(sensitive)
- self.image_configuration_page.config_build_button.set_sensitive(sensitive)
-
- self.recipe_details_page.set_sensitive(sensitive)
- self.package_details_page.set_sensitive(sensitive)
- self.build_details_page.set_sensitive(sensitive)
- self.image_details_page.set_sensitive(sensitive)
-
- if sensitive:
- self.window.set_cursor(None)
- else:
- self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
- self.sensitive = sensitive
-
-
- def handler_generating_data_cb(self, handler):
- self.window_sensitive(False)
-
- def handler_data_generated_cb(self, handler):
- self.window_sensitive(True)
-
- def rcppkglist_populated(self):
- selected_image = self.configuration.selected_image
- selected_recipes = self.configuration.selected_recipes[:]
- selected_packages = self.configuration.selected_packages[:]
- user_selected_packages = self.configuration.user_selected_packages[:]
-
- self.image_configuration_page.update_image_combo(self.recipe_model, selected_image)
- self.image_configuration_page.update_image_desc()
- self.update_recipe_model(selected_image, selected_recipes)
- self.update_package_model(selected_packages, user_selected_packages)
-
- def recipelist_changed_cb(self, recipe_model):
- self.recipe_details_page.refresh_selection()
-
- def packagelist_changed_cb(self, package_model):
- self.package_details_page.refresh_selection()
-
- def handler_recipe_populated_cb(self, handler):
- self.image_configuration_page.update_progress_bar("Populating recipes", 0.99)
-
- def handler_package_populated_cb(self, handler):
- self.image_configuration_page.update_progress_bar("Populating packages", 1.0)
-
- def handler_parsing_started_cb(self, handler, message):
- if self.current_step != self.RCPPKGINFO_POPULATING:
- return
-
- fraction = 0
- if message["eventname"] == "TreeDataPreparationStarted":
- fraction = 0.6 + fraction
- self.image_configuration_page.stop_button.set_sensitive(False)
- self.image_configuration_page.update_progress_bar("Generating dependency tree", fraction)
- else:
- self.image_configuration_page.stop_button.set_sensitive(True)
- self.image_configuration_page.update_progress_bar(message["title"], fraction)
-
- def handler_parsing_cb(self, handler, message):
- if self.current_step != self.RCPPKGINFO_POPULATING:
- return
-
- fraction = message["current"] * 1.0/message["total"]
- if message["eventname"] == "TreeDataPreparationProgress":
- fraction = 0.6 + 0.38 * fraction
- self.image_configuration_page.update_progress_bar("Generating dependency tree", fraction)
- else:
- fraction = 0.6 * fraction
- self.image_configuration_page.update_progress_bar(message["title"], fraction)
-
- def handler_parsing_completed_cb(self, handler, message):
- if self.current_step != self.RCPPKGINFO_POPULATING:
- return
-
- if message["eventname"] == "TreeDataPreparationCompleted":
- fraction = 0.98
- else:
- fraction = 0.6
- self.image_configuration_page.update_progress_bar("Generating dependency tree", fraction)
-
- def handler_build_started_cb(self, running_build):
- if self.current_step == self.FAST_IMAGE_GENERATING:
- fraction = 0
- elif self.current_step == self.IMAGE_GENERATING:
- if self.previous_step == self.FAST_IMAGE_GENERATING:
- fraction = 0.9
- else:
- fraction = 0
- elif self.current_step == self.PACKAGE_GENERATING:
- fraction = 0
- self.build_details_page.update_progress_bar("Build Started: ", fraction)
- self.build_details_page.show_configurations(self.configuration, self.parameters)
-
- def build_succeeded(self):
- if self.current_step == self.FAST_IMAGE_GENERATING:
- fraction = 0.9
- elif self.current_step == self.IMAGE_GENERATING:
- fraction = 1.0
- version = ""
- self.parameters.image_names = []
- selected_image = self.recipe_model.get_selected_image()
- if selected_image == self.recipe_model.__custom_image__:
- if self.configuration.initial_selected_image != selected_image:
- version = self.recipe_model.get_custom_image_version()
- linkname = self.hob_image + version + "-" + self.configuration.curr_mach
- else:
- linkname = selected_image + '-' + self.configuration.curr_mach
- image_extension = self.get_image_extension()
- for image_type in self.parameters.image_types:
- if image_type in image_extension:
- real_types = image_extension[image_type]
- else:
- real_types = [image_type]
- for real_image_type in real_types:
- linkpath = self.parameters.image_addr + '/' + linkname + '.' + real_image_type
- if os.path.exists(linkpath):
- self.parameters.image_names.append(os.readlink(linkpath))
- elif self.current_step == self.PACKAGE_GENERATING:
- fraction = 1.0
- self.build_details_page.update_progress_bar("Build Completed: ", fraction)
- self.handler.build_succeeded_async()
- self.stopping = False
-
- if self.current_step == self.PACKAGE_GENERATING:
- self.switch_page(self.PACKAGE_GENERATED)
- elif self.current_step == self.IMAGE_GENERATING:
- self.switch_page(self.IMAGE_GENERATED)
-
- def build_failed(self):
- if self.stopping:
- status = "stop"
- message = "Build stopped: "
- fraction = self.build_details_page.progress_bar.get_fraction()
- stop_to_next_edit = ""
- if self.current_step == self.FAST_IMAGE_GENERATING:
- stop_to_next_edit = "image configuration"
- elif self.current_step == self.IMAGE_GENERATING:
- if self.previous_step == self.FAST_IMAGE_GENERATING:
- stop_to_next_edit = "image configuration"
- else:
- stop_to_next_edit = "packages"
- elif self.current_step == self.PACKAGE_GENERATING:
- stop_to_next_edit = "recipes"
- button = self.build_details_page.show_stop_page(stop_to_next_edit.split(' ')[0])
- self.set_default(button)
- else:
- fail_to_next_edit = ""
- if self.current_step == self.FAST_IMAGE_GENERATING:
- fail_to_next_edit = "image configuration"
- fraction = 0.9
- elif self.current_step == self.IMAGE_GENERATING:
- if self.previous_step == self.FAST_IMAGE_GENERATING:
- fail_to_next_edit = "image configuration"
- else:
- fail_to_next_edit = "packages"
- fraction = 1.0
- elif self.current_step == self.PACKAGE_GENERATING:
- fail_to_next_edit = "recipes"
- fraction = 1.0
- self.build_details_page.show_fail_page(fail_to_next_edit.split(' ')[0])
- status = "fail"
- message = "Build failed: "
- self.build_details_page.update_progress_bar(message, fraction, status)
- self.build_details_page.show_back_button()
- self.build_details_page.hide_stop_button()
- self.handler.build_failed_async()
- self.stopping = False
-
- def handler_build_succeeded_cb(self, running_build):
- if not self.stopping:
- self.build_succeeded()
- else:
- self.build_failed()
-
-
- def handler_build_failed_cb(self, running_build):
- self.build_failed()
-
- def handler_build_aborted_cb(self, running_build):
- self.build_failed()
-
- def handler_no_provider_cb(self, running_build, msg):
- dialog = CrumbsMessageDialog(self, glib.markup_escape_text(msg), gtk.MESSAGE_INFO)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- dialog.run()
- dialog.destroy()
- self.build_failed()
-
- def handler_task_started_cb(self, running_build, message):
- fraction = message["current"] * 1.0/message["total"]
- title = "Build packages"
- if self.current_step == self.FAST_IMAGE_GENERATING:
- if message["eventname"] == "sceneQueueTaskStarted":
- fraction = 0.27 * fraction
- elif message["eventname"] == "runQueueTaskStarted":
- fraction = 0.27 + 0.63 * fraction
- elif self.current_step == self.IMAGE_GENERATING:
- title = "Build image"
- if self.previous_step == self.FAST_IMAGE_GENERATING:
- if message["eventname"] == "sceneQueueTaskStarted":
- fraction = 0.27 + 0.63 + 0.03 * fraction
- elif message["eventname"] == "runQueueTaskStarted":
- fraction = 0.27 + 0.63 + 0.03 + 0.07 * fraction
- else:
- if message["eventname"] == "sceneQueueTaskStarted":
- fraction = 0.2 * fraction
- elif message["eventname"] == "runQueueTaskStarted":
- fraction = 0.2 + 0.8 * fraction
- elif self.current_step == self.PACKAGE_GENERATING:
- if message["eventname"] == "sceneQueueTaskStarted":
- fraction = 0.2 * fraction
- elif message["eventname"] == "runQueueTaskStarted":
- fraction = 0.2 + 0.8 * fraction
- self.build_details_page.update_progress_bar(title + ": ", fraction)
- self.build_details_page.update_build_status(message["current"], message["total"], message["task"])
-
- def handler_disk_full_cb(self, running_build):
- self.disk_full = True
-
- def handler_build_failure_cb(self, running_build):
- self.build_details_page.show_issues()
-
- def handler_build_log_cb(self, running_build, func, obj):
- if hasattr(self.logger, func):
- getattr(self.logger, func)(obj)
-
- def destroy_window_cb(self, widget, event):
- if not self.sensitive:
- return True
- elif self.handler.building:
- self.stop_build()
- return True
- else:
- gtk.main_quit()
-
- def event_handle_SIGINT(self, signal, frame):
- for w in gtk.window_list_toplevels():
- if w.get_modal():
- w.response(gtk.RESPONSE_DELETE_EVENT)
- sys.exit(0)
-
- def build_packages(self):
- _, all_recipes = self.recipe_model.get_selected_recipes()
- if not all_recipes:
- lbl = "<b>No selections made</b>"
- msg = "You have not made any selections"
- msg = msg + " so there isn't anything to bake at this time."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- dialog.run()
- dialog.destroy()
- return
- self.generate_packages_async(True)
-
- def build_image(self):
- selected_packages = self.package_model.get_selected_packages()
- if not selected_packages:
- lbl = "<b>No selections made</b>"
- msg = "You have not made any selections"
- msg = msg + " so there isn't anything to bake at this time."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- dialog.run()
- dialog.destroy()
- return
- self.generate_image_async(True)
-
- def just_bake(self):
- selected_image = self.recipe_model.get_selected_image()
- selected_packages = self.package_model.get_selected_packages() or []
-
- # If no base image and no selected packages don't build anything
- if not (selected_packages or selected_image != self.recipe_model.__custom_image__):
- lbl = "<b>No selections made</b>"
- msg = "You have not made any selections"
- msg = msg + " so there isn't anything to bake at this time."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- dialog.run()
- dialog.destroy()
- return
-
- self.fast_generate_image_async(True)
-
- def show_recipe_property_dialog(self, properties):
- information = {}
- dialog = PropertyDialog(title = properties["name"] +' '+ "properties",
- parent = self,
- information = properties,
- flags = gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
-
- dialog.set_modal(False)
-
- button = dialog.add_button("Close", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button.connect("clicked", lambda w: dialog.destroy())
-
- dialog.run()
-
- def show_packages_property_dialog(self, properties):
- information = {}
- dialog = PropertyDialog(title = properties["name"] +' '+ "properties",
- parent = self,
- information = properties,
- flags = gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
-
- dialog.set_modal(False)
-
- button = dialog.add_button("Close", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button.connect("clicked", lambda w: dialog.destroy())
-
- dialog.run()
-
- def show_layer_selection_dialog(self):
- dialog = LayerSelectionDialog(title = "Layers",
- layers = copy.deepcopy(self.configuration.layers),
- layers_non_removable = copy.deepcopy(self.configuration.layers_non_removable),
- all_layers = self.parameters.all_layers,
- parent = self,
- flags = gtk.DIALOG_MODAL
- | gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
- button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button = dialog.add_button("OK", gtk.RESPONSE_YES)
- HobButton.style_button(button)
- response = dialog.run()
- if response == gtk.RESPONSE_YES:
- self.configuration.layers = dialog.layers
- # DO refresh layers
- if dialog.layers_changed:
- self.update_config_async()
- dialog.destroy()
-
- def get_image_extension(self):
- image_extension = {}
- for type in self.parameters.image_types:
- ext = self.handler.runCommand(["getVariable", "IMAGE_EXTENSION_%s" % type])
- if ext:
- image_extension[type] = ext.split(' ')
-
- return image_extension
-
- def show_load_my_images_dialog(self):
- image_extension = self.get_image_extension()
- dialog = ImageSelectionDialog(self.parameters.image_addr, self.parameters.image_types,
- "Open My Images", self,
- gtk.FILE_CHOOSER_ACTION_SAVE, None,
- image_extension)
- button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button = dialog.add_button("Open", gtk.RESPONSE_YES)
- HobButton.style_button(button)
- response = dialog.run()
- if response == gtk.RESPONSE_YES:
- if not dialog.image_names:
- lbl = "<b>No selections made</b>"
- msg = "You have not made any selections"
- crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO, msg)
- button = crumbs_dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- crumbs_dialog.run()
- crumbs_dialog.destroy()
- dialog.destroy()
- return
-
- self.parameters.image_addr = dialog.image_folder
- self.parameters.image_names = dialog.image_names[:]
- self.switch_page(self.MY_IMAGE_OPENED)
-
- dialog.destroy()
-
- def show_adv_settings_dialog(self, tab=None):
- dialog = AdvancedSettingsDialog(title = "Advanced configuration",
- configuration = copy.deepcopy(self.configuration),
- all_image_types = self.parameters.image_types,
- all_package_formats = self.parameters.all_package_formats,
- all_distros = self.parameters.all_distros,
- all_sdk_machines = self.parameters.all_sdk_machines,
- max_threads = self.parameters.max_threads,
- parent = self,
- flags = gtk.DIALOG_MODAL
- | gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
- button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button = dialog.add_button("Save", gtk.RESPONSE_YES)
- HobButton.style_button(button)
- dialog.set_save_button(button)
- response = dialog.run()
- settings_changed = False
- if response == gtk.RESPONSE_YES:
- self.configuration = dialog.configuration
- self.configuration.save(self.handler, True) # remember settings
- settings_changed = dialog.settings_changed
- dialog.destroy()
- return response == gtk.RESPONSE_YES, settings_changed
-
- def show_simple_settings_dialog(self, tab=None):
- dialog = SimpleSettingsDialog(title = "Settings",
- configuration = copy.deepcopy(self.configuration),
- all_image_types = self.parameters.image_types,
- all_package_formats = self.parameters.all_package_formats,
- all_distros = self.parameters.all_distros,
- all_sdk_machines = self.parameters.all_sdk_machines,
- max_threads = self.parameters.max_threads,
- parent = self,
- flags = gtk.DIALOG_MODAL
- | gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR,
- handler = self.handler)
- button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button = dialog.add_button("Save", gtk.RESPONSE_YES)
- HobButton.style_button(button)
- if tab:
- dialog.switch_to_page(tab)
- response = dialog.run()
- settings_changed = False
- if response == gtk.RESPONSE_YES:
- self.configuration = dialog.configuration
- self.configuration.save(self.handler, True) # remember settings
- settings_changed = dialog.settings_changed
- if dialog.proxy_settings_changed:
- self.set_user_config_proxies()
- elif dialog.proxy_test_ran:
- # The user might have modified the proxies in the "Proxy"
- # tab, which in turn made the proxy settings modify in bb.
- # If "Cancel" was pressed, restore the previous proxy
- # settings inside bb.
- self.set_user_config_proxies()
- dialog.destroy()
- return response == gtk.RESPONSE_YES, settings_changed
-
- def reparse_post_adv_settings(self):
- if not self.configuration.curr_mach:
- self.update_config_async()
- else:
- self.configuration.clear_selection()
- # DO reparse recipes
- self.populate_recipe_package_info_async()
-
- def deploy_image(self, image_name):
- if not image_name:
- lbl = "<b>Please select an image to deploy.</b>"
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- dialog.run()
- dialog.destroy()
- return
-
- image_path = os.path.join(self.parameters.image_addr, image_name)
- dialog = DeployImageDialog(title = "Usb Image Maker",
- image_path = image_path,
- parent = self,
- flags = gtk.DIALOG_MODAL
- | gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
- button = dialog.add_button("Close", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button = dialog.add_button("Make usb image", gtk.RESPONSE_YES)
- HobButton.style_button(button)
- response = dialog.run()
- dialog.destroy()
-
- def show_load_kernel_dialog(self):
- dialog = gtk.FileChooserDialog("Load Kernel Files", self,
- gtk.FILE_CHOOSER_ACTION_SAVE)
- button = dialog.add_button("Cancel", gtk.RESPONSE_NO)
- HobAltButton.style_button(button)
- button = dialog.add_button("Open", gtk.RESPONSE_YES)
- HobButton.style_button(button)
- filter = gtk.FileFilter()
- filter.set_name("Kernel Files")
- filter.add_pattern("*.bin")
- dialog.add_filter(filter)
-
- dialog.set_current_folder(self.parameters.image_addr)
-
- response = dialog.run()
- kernel_path = ""
- if response == gtk.RESPONSE_YES:
- kernel_path = dialog.get_filename()
-
- dialog.destroy()
-
- return kernel_path
-
- def runqemu_image(self, image_name, kernel_name):
- if not image_name or not kernel_name:
- lbl = "<b>Please select %s to launch in QEMU.</b>" % ("a kernel" if image_name else "an image")
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- dialog.run()
- dialog.destroy()
- return
-
- kernel_path = os.path.join(self.parameters.image_addr, kernel_name)
- image_path = os.path.join(self.parameters.image_addr, image_name)
-
- source_env_path = os.path.join(self.parameters.core_base, "oe-init-build-env")
- tmp_path = self.parameters.tmpdir
- cmdline = bb.ui.crumbs.utils.which_terminal()
- if os.path.exists(image_path) and os.path.exists(kernel_path) \
- and os.path.exists(source_env_path) and os.path.exists(tmp_path) \
- and cmdline:
- cmdline += "\' bash -c \"export OE_TMPDIR=" + tmp_path + "; "
- cmdline += "source " + source_env_path + " " + os.getcwd() + "; "
- cmdline += "runqemu " + kernel_path + " " + image_path + "\"\'"
- subprocess.Popen(shlex.split(cmdline))
- else:
- lbl = "<b>Path error</b>"
- msg = "One of your paths is wrong,"
- msg = msg + " please make sure the following paths exist:\n"
- msg = msg + "image path:" + image_path + "\n"
- msg = msg + "kernel path:" + kernel_path + "\n"
- msg = msg + "source environment path:" + source_env_path + "\n"
- msg = msg + "tmp path: " + tmp_path + "."
- msg = msg + "You may be missing either xterm or vte for terminal services."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- dialog.run()
- dialog.destroy()
-
- def show_packages(self):
- self.package_details_page.refresh_tables()
- self.switch_page(self.PACKAGE_SELECTION)
-
- def show_recipes(self):
- self.switch_page(self.RECIPE_SELECTION)
-
- def show_image_details(self):
- self.switch_page(self.IMAGE_GENERATED)
-
- def show_configuration(self):
- self.switch_page(self.BASEIMG_SELECTED)
-
- def stop_build(self):
- if self.stopping:
- lbl = "<b>Force Stop build?</b>"
- msg = "You've already selected Stop once,"
- msg = msg + " would you like to 'Force Stop' the build?\n\n"
- msg = msg + "This will stop the build as quickly as possible but may"
- msg = msg + " well leave your build directory in an unusable state"
- msg = msg + " that requires manual steps to fix."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_WARNING, msg)
- button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL)
- HobAltButton.style_button(button)
- button = dialog.add_button("Force Stop", gtk.RESPONSE_YES)
- HobButton.style_button(button)
- else:
- lbl = "<b>Stop build?</b>"
- msg = "Are you sure you want to stop this"
- msg = msg + " build?\n\n'Stop' will stop the build as soon as all in"
- msg = msg + " progress build tasks are finished. However if a"
- msg = msg + " lengthy compilation phase is in progress this may take"
- msg = msg + " some time.\n\n"
- msg = msg + "'Force Stop' will stop the build as quickly as"
- msg = msg + " possible but may well leave your build directory in an"
- msg = msg + " unusable state that requires manual steps to fix."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_WARNING, msg)
- button = dialog.add_button("Cancel", gtk.RESPONSE_CANCEL)
- HobAltButton.style_button(button)
- button = dialog.add_button("Force stop", gtk.RESPONSE_YES)
- HobAltButton.style_button(button)
- button = dialog.add_button("Stop", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- response = dialog.run()
- dialog.destroy()
- if response != gtk.RESPONSE_CANCEL:
- self.stopping = True
- if response == gtk.RESPONSE_OK:
- self.build_details_page.progress_bar.set_stop_title("Stopping the build....")
- self.build_details_page.progress_bar.set_rcstyle("stop")
- self.cancel_build_sync()
- elif response == gtk.RESPONSE_YES:
- self.cancel_build_sync(True)
-
- def do_log(self, consolelogfile = None):
- if consolelogfile:
- bb.utils.mkdirhier(os.path.dirname(consolelogfile))
- if self.consolelog:
- self.logger.removeHandler(self.consolelog)
- self.consolelog = None
- self.consolelog = logging.FileHandler(consolelogfile)
- bb.msg.addDefaultlogFilter(self.consolelog)
- format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
- self.consolelog.setFormatter(format)
-
- self.logger.addHandler(self.consolelog)
-
- def get_topdir(self):
- return self.handler.get_topdir()
-
- def wait(self, delay):
- time_start = time.time()
- time_end = time_start + delay
- while time_end > time.time():
- while gtk.events_pending():
- gtk.main_iteration()
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/buildmanager.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/buildmanager.py
deleted file mode 100644
index e858d75e4..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/buildmanager.py
+++ /dev/null
@@ -1,455 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2008 Intel Corporation
-#
-# Authored by Rob Bradford <rob@linux.intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import gobject
-import threading
-import os
-import datetime
-import time
-
-class BuildConfiguration:
- """ Represents a potential *or* historic *or* concrete build. It
- encompasses all the things that we need to tell bitbake to do to make it
- build what we want it to build.
-
- It also stored the metadata URL and the set of possible machines (and the
- distros / images / uris for these. Apart from the metdata URL these are
- not serialised to file (since they may be transient). In some ways this
- functionality might be shifted to the loader class."""
-
- def __init__ (self):
- self.metadata_url = None
-
- # Tuple of (distros, image, urls)
- self.machine_options = {}
-
- self.machine = None
- self.distro = None
- self.image = None
- self.urls = []
- self.extra_urls = []
- self.extra_pkgs = []
-
- def get_machines_model (self):
- model = gtk.ListStore (gobject.TYPE_STRING)
- for machine in self.machine_options.keys():
- model.append ([machine])
-
- return model
-
- def get_distro_and_images_models (self, machine):
- distro_model = gtk.ListStore (gobject.TYPE_STRING)
-
- for distro in self.machine_options[machine][0]:
- distro_model.append ([distro])
-
- image_model = gtk.ListStore (gobject.TYPE_STRING)
-
- for image in self.machine_options[machine][1]:
- image_model.append ([image])
-
- return (distro_model, image_model)
-
- def get_repos (self):
- self.urls = self.machine_options[self.machine][2]
- return self.urls
-
- # It might be a lot lot better if we stored these in like, bitbake conf
- # file format.
- @staticmethod
- def load_from_file (filename):
-
- conf = BuildConfiguration()
- with open(filename, "r") as f:
- for line in f:
- data = line.split (";")[1]
- if (line.startswith ("metadata-url;")):
- conf.metadata_url = data.strip()
- continue
- if (line.startswith ("url;")):
- conf.urls += [data.strip()]
- continue
- if (line.startswith ("extra-url;")):
- conf.extra_urls += [data.strip()]
- continue
- if (line.startswith ("machine;")):
- conf.machine = data.strip()
- continue
- if (line.startswith ("distribution;")):
- conf.distro = data.strip()
- continue
- if (line.startswith ("image;")):
- conf.image = data.strip()
- continue
-
- return conf
-
- # Serialise to a file. This is part of the build process and we use this
- # to be able to repeat a given build (using the same set of parameters)
- # but also so that we can include the details of the image / machine /
- # distro in the build manager tree view.
- def write_to_file (self, filename):
- f = open (filename, "w")
-
- lines = []
-
- if (self.metadata_url):
- lines += ["metadata-url;%s\n" % (self.metadata_url)]
-
- for url in self.urls:
- lines += ["url;%s\n" % (url)]
-
- for url in self.extra_urls:
- lines += ["extra-url;%s\n" % (url)]
-
- if (self.machine):
- lines += ["machine;%s\n" % (self.machine)]
-
- if (self.distro):
- lines += ["distribution;%s\n" % (self.distro)]
-
- if (self.image):
- lines += ["image;%s\n" % (self.image)]
-
- f.writelines (lines)
- f.close ()
-
-class BuildResult(gobject.GObject):
- """ Represents an historic build. Perhaps not successful. But it includes
- things such as the files that are in the directory (the output from the
- build) as well as a deserialised BuildConfiguration file that is stored in
- ".conf" in the directory for the build.
-
- This is GObject so that it can be included in the TreeStore."""
-
- (STATE_COMPLETE, STATE_FAILED, STATE_ONGOING) = \
- (0, 1, 2)
-
- def __init__ (self, parent, identifier):
- gobject.GObject.__init__ (self)
- self.date = None
-
- self.files = []
- self.status = None
- self.identifier = identifier
- self.path = os.path.join (parent, identifier)
-
- # Extract the date, since the directory name is of the
- # format build-<year><month><day>-<ordinal> we can easily
- # pull it out.
- # TODO: Better to stat a file?
- (_, date, revision) = identifier.split ("-")
- print(date)
-
- year = int (date[0:4])
- month = int (date[4:6])
- day = int (date[6:8])
-
- self.date = datetime.date (year, month, day)
-
- self.conf = None
-
- # By default builds are STATE_FAILED unless we find a "complete" file
- # in which case they are STATE_COMPLETE
- self.state = BuildResult.STATE_FAILED
- for file in os.listdir (self.path):
- if (file.startswith (".conf")):
- conffile = os.path.join (self.path, file)
- self.conf = BuildConfiguration.load_from_file (conffile)
- elif (file.startswith ("complete")):
- self.state = BuildResult.STATE_COMPLETE
- else:
- self.add_file (file)
-
- def add_file (self, file):
- # Just add the file for now. Don't care about the type.
- self.files += [(file, None)]
-
-class BuildManagerModel (gtk.TreeStore):
- """ Model for the BuildManagerTreeView. This derives from gtk.TreeStore
- but it abstracts nicely what the columns mean and the setup of the columns
- in the model. """
-
- (COL_IDENT, COL_DESC, COL_MACHINE, COL_DISTRO, COL_BUILD_RESULT, COL_DATE, COL_STATE) = \
- (0, 1, 2, 3, 4, 5, 6)
-
- def __init__ (self):
- gtk.TreeStore.__init__ (self,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_OBJECT,
- gobject.TYPE_INT64,
- gobject.TYPE_INT)
-
-class BuildManager (gobject.GObject):
- """ This class manages the historic builds that have been found in the
- "results" directory but is also used for starting a new build."""
-
- __gsignals__ = {
- 'population-finished' : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- 'populate-error' : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ())
- }
-
- def update_build_result (self, result, iter):
- # Convert the date into something we can sort by.
- date = long (time.mktime (result.date.timetuple()))
-
- # Add a top level entry for the build
-
- self.model.set (iter,
- BuildManagerModel.COL_IDENT, result.identifier,
- BuildManagerModel.COL_DESC, result.conf.image,
- BuildManagerModel.COL_MACHINE, result.conf.machine,
- BuildManagerModel.COL_DISTRO, result.conf.distro,
- BuildManagerModel.COL_BUILD_RESULT, result,
- BuildManagerModel.COL_DATE, date,
- BuildManagerModel.COL_STATE, result.state)
-
- # And then we use the files in the directory as the children for the
- # top level iter.
- for file in result.files:
- self.model.append (iter, (None, file[0], None, None, None, date, -1))
-
- # This function is called as an idle by the BuildManagerPopulaterThread
- def add_build_result (self, result):
- gtk.gdk.threads_enter()
- self.known_builds += [result]
-
- self.update_build_result (result, self.model.append (None))
-
- gtk.gdk.threads_leave()
-
- def notify_build_finished (self):
- # This is a bit of a hack. If we have a running build running then we
- # will have a row in the model in STATE_ONGOING. Find it and make it
- # as if it was a proper historic build (well, it is completed now....)
-
- # We need to use the iters here rather than the Python iterator
- # interface to the model since we need to pass it into
- # update_build_result
-
- iter = self.model.get_iter_first()
-
- while (iter):
- (ident, state) = self.model.get(iter,
- BuildManagerModel.COL_IDENT,
- BuildManagerModel.COL_STATE)
-
- if state == BuildResult.STATE_ONGOING:
- result = BuildResult (self.results_directory, ident)
- self.update_build_result (result, iter)
- iter = self.model.iter_next(iter)
-
- def notify_build_succeeded (self):
- # Write the "complete" file so that when we create the BuildResult
- # object we put into the model
-
- complete_file_path = os.path.join (self.cur_build_directory, "complete")
- f = file (complete_file_path, "w")
- f.close()
- self.notify_build_finished()
-
- def notify_build_failed (self):
- # Without a "complete" file then this will mark the build as failed:
- self.notify_build_finished()
-
- # This function is called as an idle
- def emit_population_finished_signal (self):
- gtk.gdk.threads_enter()
- self.emit ("population-finished")
- gtk.gdk.threads_leave()
-
- class BuildManagerPopulaterThread (threading.Thread):
- def __init__ (self, manager, directory):
- threading.Thread.__init__ (self)
- self.manager = manager
- self.directory = directory
-
- def run (self):
- # For each of the "build-<...>" directories ..
-
- if os.path.exists (self.directory):
- for directory in os.listdir (self.directory):
-
- if not directory.startswith ("build-"):
- continue
-
- build_result = BuildResult (self.directory, directory)
- self.manager.add_build_result (build_result)
-
- gobject.idle_add (BuildManager.emit_population_finished_signal,
- self.manager)
-
- def __init__ (self, server, results_directory):
- gobject.GObject.__init__ (self)
-
- # The builds that we've found from walking the result directory
- self.known_builds = []
-
- # Save out the bitbake server, we need this for issuing commands to
- # the cooker:
- self.server = server
-
- # The TreeStore that we use
- self.model = BuildManagerModel ()
-
- # The results directory is where we create (and look for) the
- # build-<xyz>-<n> directories. We need to populate ourselves from
- # directory
- self.results_directory = results_directory
- self.populate_from_directory (self.results_directory)
-
- def populate_from_directory (self, directory):
- thread = BuildManager.BuildManagerPopulaterThread (self, directory)
- thread.start()
-
- # Come up with the name for the next build ident by combining "build-"
- # with the date formatted as yyyymmdd and then an ordinal. We do this by
- # an optimistic algorithm incrementing the ordinal if we find that it
- # already exists.
- def get_next_build_ident (self):
- today = datetime.date.today ()
- datestr = str (today.year) + str (today.month) + str (today.day)
-
- revision = 0
- test_name = "build-%s-%d" % (datestr, revision)
- test_path = os.path.join (self.results_directory, test_name)
-
- while (os.path.exists (test_path)):
- revision += 1
- test_name = "build-%s-%d" % (datestr, revision)
- test_path = os.path.join (self.results_directory, test_name)
-
- return test_name
-
- # Take a BuildConfiguration and then try and build it based on the
- # parameters of that configuration. S
- def do_build (self, conf):
- server = self.server
-
- # Work out the build directory. Note we actually create the
- # directories here since we need to write the ".conf" file. Otherwise
- # we could have relied on bitbake's builder thread to actually make
- # the directories as it proceeds with the build.
- ident = self.get_next_build_ident ()
- build_directory = os.path.join (self.results_directory,
- ident)
- self.cur_build_directory = build_directory
- os.makedirs (build_directory)
-
- conffile = os.path.join (build_directory, ".conf")
- conf.write_to_file (conffile)
-
- # Add a row to the model representing this ongoing build. It's kinda a
- # fake entry. If this build completes or fails then this gets updated
- # with the real stuff like the historic builds
- date = long (time.time())
- self.model.append (None, (ident, conf.image, conf.machine, conf.distro,
- None, date, BuildResult.STATE_ONGOING))
- try:
- server.runCommand(["setVariable", "BUILD_IMAGES_FROM_FEEDS", 1])
- server.runCommand(["setVariable", "MACHINE", conf.machine])
- server.runCommand(["setVariable", "DISTRO", conf.distro])
- server.runCommand(["setVariable", "PACKAGE_CLASSES", "package_ipk"])
- server.runCommand(["setVariable", "BBFILES", \
- """${OEROOT}/meta/packages/*/*.bb ${OEROOT}/meta-moblin/packages/*/*.bb"""])
- server.runCommand(["setVariable", "TMPDIR", "${OEROOT}/build/tmp"])
- server.runCommand(["setVariable", "IPK_FEED_URIS", \
- " ".join(conf.get_repos())])
- server.runCommand(["setVariable", "DEPLOY_DIR_IMAGE",
- build_directory])
- server.runCommand(["buildTargets", [conf.image], "rootfs"])
-
- except Exception as e:
- print(e)
-
-class BuildManagerTreeView (gtk.TreeView):
- """ The tree view for the build manager. This shows the historic builds
- and so forth. """
-
- # We use this function to control what goes in the cell since we store
- # the date in the model as seconds since the epoch (for sorting) and so we
- # need to make it human readable.
- def date_format_custom_cell_data_func (self, col, cell, model, iter):
- date = model.get (iter, BuildManagerModel.COL_DATE)[0]
- datestr = time.strftime("%A %d %B %Y", time.localtime(date))
- cell.set_property ("text", datestr)
-
- # This format function controls what goes in the cell. We use this to map
- # the integer state to a string and also to colourise the text
- def state_format_custom_cell_data_fun (self, col, cell, model, iter):
- state = model.get (iter, BuildManagerModel.COL_STATE)[0]
-
- if (state == BuildResult.STATE_ONGOING):
- cell.set_property ("text", "Active")
- cell.set_property ("foreground", "#000000")
- elif (state == BuildResult.STATE_FAILED):
- cell.set_property ("text", "Failed")
- cell.set_property ("foreground", "#ff0000")
- elif (state == BuildResult.STATE_COMPLETE):
- cell.set_property ("text", "Complete")
- cell.set_property ("foreground", "#00ff00")
- else:
- cell.set_property ("text", "")
-
- def __init__ (self):
- gtk.TreeView.__init__(self)
-
- # Misc descriptiony thing
- renderer = gtk.CellRendererText ()
- col = gtk.TreeViewColumn (None, renderer,
- text=BuildManagerModel.COL_DESC)
- self.append_column (col)
-
- # Machine
- renderer = gtk.CellRendererText ()
- col = gtk.TreeViewColumn ("Machine", renderer,
- text=BuildManagerModel.COL_MACHINE)
- self.append_column (col)
-
- # distro
- renderer = gtk.CellRendererText ()
- col = gtk.TreeViewColumn ("Distribution", renderer,
- text=BuildManagerModel.COL_DISTRO)
- self.append_column (col)
-
- # date (using a custom function for formatting the cell contents it
- # takes epoch -> human readable string)
- renderer = gtk.CellRendererText ()
- col = gtk.TreeViewColumn ("Date", renderer,
- text=BuildManagerModel.COL_DATE)
- self.append_column (col)
- col.set_cell_data_func (renderer,
- self.date_format_custom_cell_data_func)
-
- # For status.
- renderer = gtk.CellRendererText ()
- col = gtk.TreeViewColumn ("Status", renderer,
- text = BuildManagerModel.COL_STATE)
- self.append_column (col)
- col.set_cell_data_func (renderer,
- self.state_format_custom_cell_data_fun)
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/advancedsettingsdialog.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/advancedsettingsdialog.py
deleted file mode 100644
index e0b3553c2..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/advancedsettingsdialog.py
+++ /dev/null
@@ -1,341 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011-2012 Intel Corporation
-#
-# Authored by Joshua Lock <josh@linux.intel.com>
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import hashlib
-from bb.ui.crumbs.hobwidget import HobInfoButton, HobButton
-from bb.ui.crumbs.progressbar import HobProgressBar
-from bb.ui.crumbs.hig.settingsuihelper import SettingsUIHelper
-from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
-from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
-from bb.ui.crumbs.hig.proxydetailsdialog import ProxyDetailsDialog
-
-"""
-The following are convenience classes for implementing GNOME HIG compliant
-BitBake GUI's
-In summary: spacing = 12px, border-width = 6px
-"""
-
-class AdvancedSettingsDialog (CrumbsDialog, SettingsUIHelper):
-
- def details_cb(self, button, parent, protocol):
- dialog = ProxyDetailsDialog(title = protocol.upper() + " Proxy Details",
- user = self.configuration.proxies[protocol][1],
- passwd = self.configuration.proxies[protocol][2],
- parent = parent,
- flags = gtk.DIALOG_MODAL
- | gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
- dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)
- response = dialog.run()
- if response == gtk.RESPONSE_OK:
- self.configuration.proxies[protocol][1] = dialog.user
- self.configuration.proxies[protocol][2] = dialog.passwd
- self.refresh_proxy_components()
- dialog.destroy()
-
- def set_save_button(self, button):
- self.save_button = button
-
- def rootfs_combo_changed_cb(self, rootfs_combo, all_package_format, check_hbox):
- combo_item = self.rootfs_combo.get_active_text()
- modified = False
- for child in check_hbox.get_children():
- if isinstance(child, gtk.CheckButton):
- check_hbox.remove(child)
- modified = True
- for format in all_package_format:
- if format != combo_item:
- check_button = gtk.CheckButton(format)
- check_hbox.pack_start(check_button, expand=False, fill=False)
- modified = True
- if modified:
- check_hbox.remove(self.pkgfmt_info)
- check_hbox.pack_start(self.pkgfmt_info, expand=False, fill=False)
- check_hbox.show_all()
-
- def gen_pkgfmt_widget(self, curr_package_format, all_package_format, tooltip_combo="", tooltip_extra=""):
- pkgfmt_vbox = gtk.VBox(False, 6)
-
- label = self.gen_label_widget("Root file system package format")
- pkgfmt_vbox.pack_start(label, expand=False, fill=False)
-
- rootfs_format = ""
- if curr_package_format:
- rootfs_format = curr_package_format.split()[0]
-
- rootfs_format_widget, rootfs_combo = self.gen_combo_widget(rootfs_format, all_package_format, tooltip_combo)
- pkgfmt_vbox.pack_start(rootfs_format_widget, expand=False, fill=False)
-
- label = self.gen_label_widget("Additional package formats")
- pkgfmt_vbox.pack_start(label, expand=False, fill=False)
-
- check_hbox = gtk.HBox(False, 12)
- pkgfmt_vbox.pack_start(check_hbox, expand=False, fill=False)
- for format in all_package_format:
- if format != rootfs_format:
- check_button = gtk.CheckButton(format)
- is_active = (format in curr_package_format.split())
- check_button.set_active(is_active)
- check_hbox.pack_start(check_button, expand=False, fill=False)
-
- self.pkgfmt_info = HobInfoButton(tooltip_extra, self)
- check_hbox.pack_start(self.pkgfmt_info, expand=False, fill=False)
-
- rootfs_combo.connect("changed", self.rootfs_combo_changed_cb, all_package_format, check_hbox)
-
- pkgfmt_vbox.show_all()
-
- return pkgfmt_vbox, rootfs_combo, check_hbox
-
- def __init__(self, title, configuration, all_image_types,
- all_package_formats, all_distros, all_sdk_machines,
- max_threads, parent, flags, buttons=None):
- super(AdvancedSettingsDialog, self).__init__(title, parent, flags, buttons)
-
- # class members from other objects
- # bitbake settings from Builder.Configuration
- self.configuration = configuration
- self.image_types = all_image_types
- self.all_package_formats = all_package_formats
- self.all_distros = all_distros[:]
- self.all_sdk_machines = all_sdk_machines
- self.max_threads = max_threads
-
- # class members for internal use
- self.distro_combo = None
- self.dldir_text = None
- self.sstatedir_text = None
- self.sstatemirror_text = None
- self.bb_spinner = None
- self.pmake_spinner = None
- self.rootfs_size_spinner = None
- self.extra_size_spinner = None
- self.gplv3_checkbox = None
- self.sdk_checkbox = None
- self.image_types_checkbuttons = {}
-
- self.md5 = self.config_md5()
- self.settings_changed = False
-
- # create visual elements on the dialog
- self.save_button = None
- self.create_visual_elements()
- self.connect("response", self.response_cb)
-
- def _get_sorted_value(self, var):
- return " ".join(sorted(str(var).split())) + "\n"
-
- def config_md5(self):
- data = ""
- data += ("PACKAGE_CLASSES: " + self.configuration.curr_package_format + '\n')
- data += ("DISTRO: " + self._get_sorted_value(self.configuration.curr_distro))
- data += ("IMAGE_ROOTFS_SIZE: " + self._get_sorted_value(self.configuration.image_rootfs_size))
- data += ("IMAGE_EXTRA_SIZE: " + self._get_sorted_value(self.configuration.image_extra_size))
- data += ("INCOMPATIBLE_LICENSE: " + self._get_sorted_value(self.configuration.incompat_license))
- data += ("SDK_MACHINE: " + self._get_sorted_value(self.configuration.curr_sdk_machine))
- data += ("TOOLCHAIN_BUILD: " + self._get_sorted_value(self.configuration.toolchain_build))
- data += ("IMAGE_FSTYPES: " + self._get_sorted_value(self.configuration.image_fstypes))
- return hashlib.md5(data).hexdigest()
-
- def create_visual_elements(self):
- self.nb = gtk.Notebook()
- self.nb.set_show_tabs(True)
- self.nb.append_page(self.create_image_types_page(), gtk.Label("Image types"))
- self.nb.append_page(self.create_output_page(), gtk.Label("Output"))
- self.nb.set_current_page(0)
- self.vbox.pack_start(self.nb, expand=True, fill=True)
- self.vbox.pack_end(gtk.HSeparator(), expand=True, fill=True)
-
- self.show_all()
-
- def get_num_checked_image_types(self):
- total = 0
- for b in self.image_types_checkbuttons.values():
- if b.get_active():
- total = total + 1
- return total
-
- def set_save_button_state(self):
- if self.save_button:
- self.save_button.set_sensitive(self.get_num_checked_image_types() > 0)
-
- def image_type_checkbutton_clicked_cb(self, button):
- self.set_save_button_state()
- if self.get_num_checked_image_types() == 0:
- # Show an error dialog
- lbl = "<b>Select an image type</b>"
- msg = "You need to select at least one image type."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_WARNING, msg)
- button = dialog.add_button("OK", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- response = dialog.run()
- dialog.destroy()
-
- def create_image_types_page(self):
- main_vbox = gtk.VBox(False, 16)
- main_vbox.set_border_width(6)
-
- advanced_vbox = gtk.VBox(False, 6)
- advanced_vbox.set_border_width(6)
-
- distro_vbox = gtk.VBox(False, 6)
- label = self.gen_label_widget("Distro:")
- tooltip = "Selects the Yocto Project distribution you want"
- try:
- i = self.all_distros.index( "defaultsetup" )
- except ValueError:
- i = -1
- if i != -1:
- self.all_distros[ i ] = "Default"
- if self.configuration.curr_distro == "defaultsetup":
- self.configuration.curr_distro = "Default"
- distro_widget, self.distro_combo = self.gen_combo_widget(self.configuration.curr_distro, self.all_distros,"<b>Distro</b>" + "*" + tooltip)
- distro_vbox.pack_start(label, expand=False, fill=False)
- distro_vbox.pack_start(distro_widget, expand=False, fill=False)
- main_vbox.pack_start(distro_vbox, expand=False, fill=False)
-
-
- rows = (len(self.image_types)+1)/3
- table = gtk.Table(rows + 1, 10, True)
- advanced_vbox.pack_start(table, expand=False, fill=False)
-
- tooltip = "Image file system types you want."
- info = HobInfoButton("<b>Image types</b>" + "*" + tooltip, self)
- label = self.gen_label_widget("Image types:")
- align = gtk.Alignment(0, 0.5, 0, 0)
- table.attach(align, 0, 4, 0, 1)
- align.add(label)
- table.attach(info, 4, 5, 0, 1)
-
- i = 1
- j = 1
- for image_type in sorted(self.image_types):
- self.image_types_checkbuttons[image_type] = gtk.CheckButton(image_type)
- self.image_types_checkbuttons[image_type].connect("toggled", self.image_type_checkbutton_clicked_cb)
- article = ""
- if image_type.startswith(("a", "e", "i", "o", "u")):
- article = "n"
- if image_type == "live":
- self.image_types_checkbuttons[image_type].set_tooltip_text("Build iso and hddimg images")
- else:
- self.image_types_checkbuttons[image_type].set_tooltip_text("Build a%s %s image" % (article, image_type))
- table.attach(self.image_types_checkbuttons[image_type], j - 1, j + 3, i, i + 1)
- if image_type in self.configuration.image_fstypes.split():
- self.image_types_checkbuttons[image_type].set_active(True)
- i += 1
- if i > rows:
- i = 1
- j = j + 4
-
- main_vbox.pack_start(advanced_vbox, expand=False, fill=False)
- self.set_save_button_state()
-
- return main_vbox
-
- def create_output_page(self):
- advanced_vbox = gtk.VBox(False, 6)
- advanced_vbox.set_border_width(6)
-
- advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Package format</span>'), expand=False, fill=False)
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
- tooltip_combo = "Selects the package format used to generate rootfs."
- tooltip_extra = "Selects extra package formats to build"
- pkgfmt_widget, self.rootfs_combo, self.check_hbox = self.gen_pkgfmt_widget(self.configuration.curr_package_format, self.all_package_formats,"<b>Root file system package format</b>" + "*" + tooltip_combo,"<b>Additional package formats</b>" + "*" + tooltip_extra)
- sub_vbox.pack_start(pkgfmt_widget, expand=False, fill=False)
-
- advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Image size</span>'), expand=False, fill=False)
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = self.gen_label_widget("Image basic size (in MB)")
- tooltip = "Defines the size for the generated image. The OpenEmbedded build system determines the final size for the generated image using an algorithm that takes into account the initial disk space used for the generated image, the Image basic size value, and the Additional free space value.\n\nFor more information, check the <a href=\"http://www.yoctoproject.org/docs/current/poky-ref-manual/poky-ref-manual.html#var-IMAGE_ROOTFS_SIZE\">Yocto Project Reference Manual</a>."
- rootfs_size_widget, self.rootfs_size_spinner = self.gen_spinner_widget(int(self.configuration.image_rootfs_size*1.0/1024), 0, 65536,"<b>Image basic size</b>" + "*" + tooltip)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(rootfs_size_widget, expand=False, fill=False)
-
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = self.gen_label_widget("Additional free space (in MB)")
- tooltip = "Sets extra free disk space to be added to the generated image. Use this variable when you want to ensure that a specific amount of free disk space is available on a device after an image is installed and running."
- extra_size_widget, self.extra_size_spinner = self.gen_spinner_widget(int(self.configuration.image_extra_size*1.0/1024), 0, 65536,"<b>Additional free space</b>" + "*" + tooltip)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(extra_size_widget, expand=False, fill=False)
-
- advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Licensing</span>'), expand=False, fill=False)
- self.gplv3_checkbox = gtk.CheckButton("Exclude GPLv3 packages")
- self.gplv3_checkbox.set_tooltip_text("Check this box to prevent GPLv3 packages from being included in your image")
- if "GPLv3" in self.configuration.incompat_license.split():
- self.gplv3_checkbox.set_active(True)
- else:
- self.gplv3_checkbox.set_active(False)
- advanced_vbox.pack_start(self.gplv3_checkbox, expand=False, fill=False)
-
- advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">SDK</span>'), expand=False, fill=False)
- sub_hbox = gtk.HBox(False, 6)
- advanced_vbox.pack_start(sub_hbox, expand=False, fill=False)
- self.sdk_checkbox = gtk.CheckButton("Populate SDK")
- tooltip = "Check this box to generate an SDK tarball that consists of the cross-toolchain and a sysroot that contains development packages for your image."
- self.sdk_checkbox.set_tooltip_text(tooltip)
- self.sdk_checkbox.set_active(self.configuration.toolchain_build)
- sub_hbox.pack_start(self.sdk_checkbox, expand=False, fill=False)
-
- tooltip = "Select the host platform for which you want to run the toolchain contained in the SDK tarball."
- sdk_machine_widget, self.sdk_machine_combo = self.gen_combo_widget(self.configuration.curr_sdk_machine, self.all_sdk_machines,"<b>Populate SDK</b>" + "*" + tooltip)
- sub_hbox.pack_start(sdk_machine_widget, expand=False, fill=False)
-
- return advanced_vbox
-
- def response_cb(self, dialog, response_id):
- package_format = []
- package_format.append(self.rootfs_combo.get_active_text())
- for child in self.check_hbox:
- if isinstance(child, gtk.CheckButton) and child.get_active():
- package_format.append(child.get_label())
- self.configuration.curr_package_format = " ".join(package_format)
-
- distro = self.distro_combo.get_active_text()
- if distro == "Default":
- distro = "defaultsetup"
- self.configuration.curr_distro = distro
- self.configuration.image_rootfs_size = self.rootfs_size_spinner.get_value_as_int() * 1024
- self.configuration.image_extra_size = self.extra_size_spinner.get_value_as_int() * 1024
-
- self.configuration.image_fstypes = ""
- for image_type in self.image_types:
- if self.image_types_checkbuttons[image_type].get_active():
- self.configuration.image_fstypes += (" " + image_type)
- self.configuration.image_fstypes.strip()
-
- if self.gplv3_checkbox.get_active():
- if "GPLv3" not in self.configuration.incompat_license.split():
- self.configuration.incompat_license += " GPLv3"
- else:
- if "GPLv3" in self.configuration.incompat_license.split():
- self.configuration.incompat_license = self.configuration.incompat_license.split().remove("GPLv3")
- self.configuration.incompat_license = " ".join(self.configuration.incompat_license or [])
- self.configuration.incompat_license = self.configuration.incompat_license.strip()
-
- self.configuration.toolchain_build = self.sdk_checkbox.get_active()
- self.configuration.curr_sdk_machine = self.sdk_machine_combo.get_active_text()
- md5 = self.config_md5()
- self.settings_changed = (self.md5 != md5)
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/parsingwarningsdialog.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/parsingwarningsdialog.py
deleted file mode 100644
index 33bac39db..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/parsingwarningsdialog.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011-2012 Intel Corporation
-#
-# Authored by Cristiana Voicu <cristiana.voicu@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import gobject
-from bb.ui.crumbs.hobwidget import HobAltButton
-from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
-
-"""
-The following are convenience classes for implementing GNOME HIG compliant
-BitBake GUI's
-In summary: spacing = 12px, border-width = 6px
-"""
-
-#
-# ParsingWarningsDialog
-#
-class ParsingWarningsDialog (CrumbsDialog):
-
- def __init__(self, title, warnings, parent, flags, buttons=None):
- super(ParsingWarningsDialog, self).__init__(title, parent, flags, buttons)
-
- self.warnings = warnings
- self.warning_on = 0
- self.warn_nb = len(warnings)
-
- # create visual elements on the dialog
- self.create_visual_elements()
-
- def cancel_button_cb(self, button):
- self.destroy()
-
- def previous_button_cb(self, button):
- self.warning_on = self.warning_on - 1
- self.refresh_components()
-
- def next_button_cb(self, button):
- self.warning_on = self.warning_on + 1
- self.refresh_components()
-
- def refresh_components(self):
- lbl = self.warnings[self.warning_on]
- #when the warning text has more than 400 chars, it uses a scroll bar
- if 0<= len(lbl) < 400:
- self.warning_label.set_size_request(320, 230)
- self.warning_label.set_use_markup(True)
- self.warning_label.set_line_wrap(True)
- self.warning_label.set_markup(lbl)
- self.warning_label.set_property("yalign", 0.00)
- else:
- self.textWindow.set_shadow_type(gtk.SHADOW_IN)
- self.textWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.msgView = gtk.TextView()
- self.msgView.set_editable(False)
- self.msgView.set_wrap_mode(gtk.WRAP_WORD)
- self.msgView.set_cursor_visible(False)
- self.msgView.set_size_request(320, 230)
- self.buf = gtk.TextBuffer()
- self.buf.set_text(lbl)
- self.msgView.set_buffer(self.buf)
- self.textWindow.add(self.msgView)
- self.msgView.show()
-
- if self.warning_on==0:
- self.previous_button.set_sensitive(False)
- else:
- self.previous_button.set_sensitive(True)
-
- if self.warning_on==self.warn_nb-1:
- self.next_button.set_sensitive(False)
- else:
- self.next_button.set_sensitive(True)
-
- if self.warn_nb>1:
- self.heading = "Warning " + str(self.warning_on + 1) + " of " + str(self.warn_nb)
- self.heading_label.set_markup('<span weight="bold">%s</span>' % self.heading)
- else:
- self.heading = "Warning"
- self.heading_label.set_markup('<span weight="bold">%s</span>' % self.heading)
-
- self.show_all()
-
- if 0<= len(lbl) < 400:
- self.textWindow.hide()
- else:
- self.warning_label.hide()
-
- def create_visual_elements(self):
- self.set_size_request(350, 350)
- self.heading_label = gtk.Label()
- self.heading_label.set_alignment(0, 0)
- self.warning_label = gtk.Label()
- self.warning_label.set_selectable(True)
- self.warning_label.set_alignment(0, 0)
- self.textWindow = gtk.ScrolledWindow()
-
- table = gtk.Table(1, 10, False)
-
- cancel_button = gtk.Button()
- cancel_button.set_label("Close")
- cancel_button.connect("clicked", self.cancel_button_cb)
- cancel_button.set_size_request(110, 30)
-
- self.previous_button = gtk.Button()
- image1 = gtk.image_new_from_stock(gtk.STOCK_GO_BACK, gtk.ICON_SIZE_BUTTON)
- image1.show()
- box = gtk.HBox(False, 6)
- box.show()
- self.previous_button.add(box)
- lbl = gtk.Label("Previous")
- lbl.show()
- box.pack_start(image1, expand=False, fill=False, padding=3)
- box.pack_start(lbl, expand=True, fill=True, padding=3)
- self.previous_button.connect("clicked", self.previous_button_cb)
- self.previous_button.set_size_request(110, 30)
-
- self.next_button = gtk.Button()
- image2 = gtk.image_new_from_stock(gtk.STOCK_GO_FORWARD, gtk.ICON_SIZE_BUTTON)
- image2.show()
- box = gtk.HBox(False, 6)
- box.show()
- self.next_button.add(box)
- lbl = gtk.Label("Next")
- lbl.show()
- box.pack_start(lbl, expand=True, fill=True, padding=3)
- box.pack_start(image2, expand=False, fill=False, padding=3)
- self.next_button.connect("clicked", self.next_button_cb)
- self.next_button.set_size_request(110, 30)
-
- #when there more than one warning, we need "previous" and "next" button
- if self.warn_nb>1:
- self.vbox.pack_start(self.heading_label, expand=False, fill=False)
- self.vbox.pack_start(self.warning_label, expand=False, fill=False)
- self.vbox.pack_start(self.textWindow, expand=False, fill=False)
- table.attach(cancel_button, 6, 7, 0, 1, xoptions=gtk.SHRINK)
- table.attach(self.previous_button, 7, 8, 0, 1, xoptions=gtk.SHRINK)
- table.attach(self.next_button, 8, 9, 0, 1, xoptions=gtk.SHRINK)
- self.vbox.pack_end(table, expand=False, fill=False)
- else:
- self.vbox.pack_start(self.heading_label, expand=False, fill=False)
- self.vbox.pack_start(self.warning_label, expand=False, fill=False)
- self.vbox.pack_start(self.textWindow, expand=False, fill=False)
- cancel_button = self.add_button("Close", gtk.RESPONSE_CANCEL)
- HobAltButton.style_button(cancel_button)
-
- self.refresh_components()
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/proxydetailsdialog.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/proxydetailsdialog.py
deleted file mode 100644
index 69e7dffb6..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/proxydetailsdialog.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011-2012 Intel Corporation
-#
-# Authored by Joshua Lock <josh@linux.intel.com>
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
-
-"""
-The following are convenience classes for implementing GNOME HIG compliant
-BitBake GUI's
-In summary: spacing = 12px, border-width = 6px
-"""
-
-class ProxyDetailsDialog (CrumbsDialog):
-
- def __init__(self, title, user, passwd, parent, flags, buttons=None):
- super(ProxyDetailsDialog, self).__init__(title, parent, flags, buttons)
- self.connect("response", self.response_cb)
-
- self.auth = not (user == None or passwd == None or user == "")
- self.user = user or ""
- self.passwd = passwd or ""
-
- # create visual elements on the dialog
- self.create_visual_elements()
-
- def create_visual_elements(self):
- self.auth_checkbox = gtk.CheckButton("Use authentication")
- self.auth_checkbox.set_tooltip_text("Check this box to set the username and the password")
- self.auth_checkbox.set_active(self.auth)
- self.auth_checkbox.connect("toggled", self.auth_checkbox_toggled_cb)
- self.vbox.pack_start(self.auth_checkbox, expand=False, fill=False)
-
- hbox = gtk.HBox(False, 6)
- self.user_label = gtk.Label("Username:")
- self.user_text = gtk.Entry()
- self.user_text.set_text(self.user)
- hbox.pack_start(self.user_label, expand=False, fill=False)
- hbox.pack_end(self.user_text, expand=False, fill=False)
- self.vbox.pack_start(hbox, expand=False, fill=False)
-
- hbox = gtk.HBox(False, 6)
- self.passwd_label = gtk.Label("Password:")
- self.passwd_text = gtk.Entry()
- self.passwd_text.set_text(self.passwd)
- hbox.pack_start(self.passwd_label, expand=False, fill=False)
- hbox.pack_end(self.passwd_text, expand=False, fill=False)
- self.vbox.pack_start(hbox, expand=False, fill=False)
-
- self.refresh_auth_components()
- self.show_all()
-
- def refresh_auth_components(self):
- self.user_label.set_sensitive(self.auth)
- self.user_text.set_editable(self.auth)
- self.user_text.set_sensitive(self.auth)
- self.passwd_label.set_sensitive(self.auth)
- self.passwd_text.set_editable(self.auth)
- self.passwd_text.set_sensitive(self.auth)
-
- def auth_checkbox_toggled_cb(self, button):
- self.auth = self.auth_checkbox.get_active()
- self.refresh_auth_components()
-
- def response_cb(self, dialog, response_id):
- if response_id == gtk.RESPONSE_OK:
- if self.auth:
- self.user = self.user_text.get_text()
- self.passwd = self.passwd_text.get_text()
- else:
- self.user = None
- self.passwd = None
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/retrieveimagedialog.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/retrieveimagedialog.py
deleted file mode 100644
index 901713985..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/retrieveimagedialog.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2013 Intel Corporation
-#
-# Authored by Cristiana Voicu <cristiana.voicu@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-
-class RetrieveImageDialog (gtk.FileChooserDialog):
- """
- This class is used to create a dialog that permits to retrieve
- a custom image saved previously from Hob.
- """
- def __init__(self, directory,title, parent, flags, buttons=None):
- super(RetrieveImageDialog, self).__init__(title, None, gtk.FILE_CHOOSER_ACTION_OPEN,
- (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN, gtk.RESPONSE_OK))
- self.directory = directory
-
- # create visual elements on the dialog
- self.create_visual_elements()
-
- def create_visual_elements(self):
- self.set_show_hidden(True)
- self.set_default_response(gtk.RESPONSE_OK)
- self.set_current_folder(self.directory)
-
- vbox = self.get_children()[0].get_children()[0].get_children()[0]
- for child in vbox.get_children()[0].get_children()[0].get_children()[0].get_children():
- vbox.get_children()[0].get_children()[0].get_children()[0].remove(child)
-
- label1 = gtk.Label()
- label1.set_text("File system" + self.directory)
- label1.show()
- vbox.get_children()[0].get_children()[0].get_children()[0].pack_start(label1, expand=False, fill=False, padding=0)
- vbox.get_children()[0].get_children()[1].get_children()[0].hide()
-
- self.get_children()[0].get_children()[1].get_children()[0].set_label("Select")
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/saveimagedialog.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/saveimagedialog.py
deleted file mode 100644
index 4195f70e1..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/saveimagedialog.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2013 Intel Corporation
-#
-# Authored by Cristiana Voicu <cristiana.voicu@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import glib
-from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
-from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
-from bb.ui.crumbs.hobwidget import HobButton
-
-class SaveImageDialog (CrumbsDialog):
- """
- This class is used to create a dialog that permits to save
- a custom image in a predefined directory.
- """
- def __init__(self, directory, name, description, title, parent, flags, buttons=None):
- super(SaveImageDialog, self).__init__(title, parent, flags, buttons)
- self.directory = directory
- self.builder = parent
- self.name_field = name
- self.description_field = description
-
- # create visual elements on the dialog
- self.create_visual_elements()
-
- def create_visual_elements(self):
- self.set_default_response(gtk.RESPONSE_OK)
- self.vbox.set_border_width(6)
-
- sub_vbox = gtk.VBox(False, 12)
- self.vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = gtk.Label()
- label.set_alignment(0, 0)
- label.set_markup("<b>Name</b>")
- sub_label = gtk.Label()
- sub_label.set_alignment(0, 0)
- content = "Image recipe names should be all lowercase and include only alphanumeric\n"
- content += "characters. The only special character you can use is the ASCII hyphen (-)."
- sub_label.set_markup(content)
- self.name_entry = gtk.Entry()
- self.name_entry.set_text(self.name_field)
- self.name_entry.set_size_request(350,30)
- self.name_entry.connect("changed", self.name_entry_changed)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(sub_label, expand=False, fill=False)
- sub_vbox.pack_start(self.name_entry, expand=False, fill=False)
-
- sub_vbox = gtk.VBox(False, 12)
- self.vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = gtk.Label()
- label.set_alignment(0, 0)
- label.set_markup("<b>Description</b> (optional)")
- sub_label = gtk.Label()
- sub_label.set_alignment(0, 0)
- sub_label.set_markup("The description should be less than 150 characters long.")
- self.description_entry = gtk.TextView()
- description_buffer = self.description_entry.get_buffer()
- description_buffer.set_text(self.description_field)
- description_buffer.connect("insert-text", self.limit_description_length)
- self.description_entry.set_wrap_mode(gtk.WRAP_WORD)
- self.description_entry.set_size_request(350,50)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(sub_label, expand=False, fill=False)
- sub_vbox.pack_start(self.description_entry, expand=False, fill=False)
-
- sub_vbox = gtk.VBox(False, 12)
- self.vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = gtk.Label()
- label.set_alignment(0, 0)
- label.set_markup("Your image recipe will be saved to:")
- sub_label = gtk.Label()
- sub_label.set_alignment(0, 0)
- sub_label.set_markup(self.directory)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(sub_label, expand=False, fill=False)
-
- table = gtk.Table(1, 4, True)
-
- cancel_button = gtk.Button()
- cancel_button.set_label("Cancel")
- cancel_button.connect("clicked", self.cancel_button_cb)
- cancel_button.set_size_request(110, 30)
-
- self.save_button = gtk.Button()
- self.save_button.set_label("Save")
- self.save_button.connect("clicked", self.save_button_cb)
- self.save_button.set_size_request(110, 30)
- if self.name_entry.get_text() == '':
- self.save_button.set_sensitive(False)
-
- table.attach(cancel_button, 2, 3, 0, 1)
- table.attach(self.save_button, 3, 4, 0, 1)
- self.vbox.pack_end(table, expand=False, fill=False)
-
- self.show_all()
-
- def limit_description_length(self, textbuffer, iter, text, length):
- buffer_bounds = textbuffer.get_bounds()
- entire_text = textbuffer.get_text(*buffer_bounds)
- entire_text += text
- if len(entire_text)>150 or text=="\n":
- textbuffer.emit_stop_by_name("insert-text")
-
- def name_entry_changed(self, entry):
- text = entry.get_text()
- if text == '':
- self.save_button.set_sensitive(False)
- else:
- self.save_button.set_sensitive(True)
-
- def cancel_button_cb(self, button):
- self.destroy()
-
- def save_button_cb(self, button):
- text = self.name_entry.get_text()
- new_text = text.replace("-","")
- description_buffer = self.description_entry.get_buffer()
- description = description_buffer.get_text(description_buffer.get_start_iter(),description_buffer.get_end_iter())
- if new_text.islower() and new_text.isalnum():
- self.builder.image_details_page.image_saved = True
- self.builder.customized = False
- self.builder.generate_new_image(self.directory+text, description)
- self.builder.recipe_model.set_in_list(text, description)
- self.builder.recipe_model.set_selected_image(text)
- self.builder.image_details_page.show_page(self.builder.IMAGE_GENERATED)
- self.builder.image_details_page.name_field_template = text
- self.builder.image_details_page.description_field_template = description
- self.destroy()
- else:
- self.show_invalid_input_error_dialog()
-
- def show_invalid_input_error_dialog(self):
- lbl = "<b>Invalid characters in image recipe name</b>"
- msg = "Image recipe names should be all lowercase and\n"
- msg += "include only alphanumeric characters. The only\n"
- msg += "special character you can use is the ASCII hyphen (-)."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
-
- res = dialog.run()
- self.name_entry.grab_focus()
- dialog.destroy()
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
deleted file mode 100644
index b5eb3d873..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hig/simplesettingsdialog.py
+++ /dev/null
@@ -1,891 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011-2012 Intel Corporation
-#
-# Authored by Joshua Lock <josh@linux.intel.com>
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import gobject
-import hashlib
-from bb.ui.crumbs.hobwidget import hic, HobInfoButton, HobButton, HobAltButton
-from bb.ui.crumbs.progressbar import HobProgressBar
-from bb.ui.crumbs.hig.settingsuihelper import SettingsUIHelper
-from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
-from bb.ui.crumbs.hig.crumbsmessagedialog import CrumbsMessageDialog
-from bb.ui.crumbs.hig.proxydetailsdialog import ProxyDetailsDialog
-
-"""
-The following are convenience classes for implementing GNOME HIG compliant
-BitBake GUI's
-In summary: spacing = 12px, border-width = 6px
-"""
-
-class SimpleSettingsDialog (CrumbsDialog, SettingsUIHelper):
-
- (BUILD_ENV_PAGE_ID,
- SHARED_STATE_PAGE_ID,
- PROXIES_PAGE_ID,
- OTHERS_PAGE_ID) = range(4)
-
- (TEST_NETWORK_NONE,
- TEST_NETWORK_INITIAL,
- TEST_NETWORK_RUNNING,
- TEST_NETWORK_PASSED,
- TEST_NETWORK_FAILED,
- TEST_NETWORK_CANCELED) = range(6)
-
- TARGETS = [
- ("MY_TREE_MODEL_ROW", gtk.TARGET_SAME_WIDGET, 0),
- ("text/plain", 0, 1),
- ("TEXT", 0, 2),
- ("STRING", 0, 3),
- ]
-
- def __init__(self, title, configuration, all_image_types,
- all_package_formats, all_distros, all_sdk_machines,
- max_threads, parent, flags, handler, buttons=None):
- super(SimpleSettingsDialog, self).__init__(title, parent, flags, buttons)
-
- # class members from other objects
- # bitbake settings from Builder.Configuration
- self.configuration = configuration
- self.image_types = all_image_types
- self.all_package_formats = all_package_formats
- self.all_distros = all_distros
- self.all_sdk_machines = all_sdk_machines
- self.max_threads = max_threads
-
- # class members for internal use
- self.dldir_text = None
- self.sstatedir_text = None
- self.sstatemirrors_list = []
- self.sstatemirrors_changed = 0
- self.bb_spinner = None
- self.pmake_spinner = None
- self.rootfs_size_spinner = None
- self.extra_size_spinner = None
- self.gplv3_checkbox = None
- self.toolchain_checkbox = None
- self.setting_store = None
- self.image_types_checkbuttons = {}
-
- self.md5 = self.config_md5()
- self.proxy_md5 = self.config_proxy_md5()
- self.settings_changed = False
- self.proxy_settings_changed = False
- self.handler = handler
- self.proxy_test_ran = False
- self.selected_mirror_row = 0
- self.new_mirror = False
-
- # create visual elements on the dialog
- self.create_visual_elements()
- self.connect("response", self.response_cb)
-
- def _get_sorted_value(self, var):
- return " ".join(sorted(str(var).split())) + "\n"
-
- def config_proxy_md5(self):
- data = ("ENABLE_PROXY: " + self._get_sorted_value(self.configuration.enable_proxy))
- if self.configuration.enable_proxy:
- for protocol in self.configuration.proxies.keys():
- data += (protocol + ": " + self._get_sorted_value(self.configuration.combine_proxy(protocol)))
- return hashlib.md5(data).hexdigest()
-
- def config_md5(self):
- data = ""
- for key in self.configuration.extra_setting.keys():
- data += (key + ": " + self._get_sorted_value(self.configuration.extra_setting[key]))
- return hashlib.md5(data).hexdigest()
-
- def gen_proxy_entry_widget(self, protocol, parent, need_button=True, line=0):
- label = gtk.Label(protocol.upper() + " proxy")
- self.proxy_table.attach(label, 0, 1, line, line+1, xpadding=24)
-
- proxy_entry = gtk.Entry()
- proxy_entry.set_size_request(300, -1)
- self.proxy_table.attach(proxy_entry, 1, 2, line, line+1, ypadding=4)
-
- self.proxy_table.attach(gtk.Label(":"), 2, 3, line, line+1, xpadding=12, ypadding=4)
-
- port_entry = gtk.Entry()
- port_entry.set_size_request(60, -1)
- self.proxy_table.attach(port_entry, 3, 4, line, line+1, ypadding=4)
-
- details_button = HobAltButton("Details")
- details_button.connect("clicked", self.details_cb, parent, protocol)
- self.proxy_table.attach(details_button, 4, 5, line, line+1, xpadding=4, yoptions=gtk.EXPAND)
-
- return proxy_entry, port_entry, details_button
-
- def refresh_proxy_components(self):
- self.same_checkbox.set_sensitive(self.configuration.enable_proxy)
-
- self.http_proxy.set_text(self.configuration.combine_host_only("http"))
- self.http_proxy.set_editable(self.configuration.enable_proxy)
- self.http_proxy.set_sensitive(self.configuration.enable_proxy)
- self.http_proxy_port.set_text(self.configuration.combine_port_only("http"))
- self.http_proxy_port.set_editable(self.configuration.enable_proxy)
- self.http_proxy_port.set_sensitive(self.configuration.enable_proxy)
- self.http_proxy_details.set_sensitive(self.configuration.enable_proxy)
-
- self.https_proxy.set_text(self.configuration.combine_host_only("https"))
- self.https_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.https_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.https_proxy_port.set_text(self.configuration.combine_port_only("https"))
- self.https_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.https_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.https_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
-
- self.ftp_proxy.set_text(self.configuration.combine_host_only("ftp"))
- self.ftp_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.ftp_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.ftp_proxy_port.set_text(self.configuration.combine_port_only("ftp"))
- self.ftp_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.ftp_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.ftp_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
-
- self.socks_proxy.set_text(self.configuration.combine_host_only("socks"))
- self.socks_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.socks_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.socks_proxy_port.set_text(self.configuration.combine_port_only("socks"))
- self.socks_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.socks_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.socks_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
-
- self.cvs_proxy.set_text(self.configuration.combine_host_only("cvs"))
- self.cvs_proxy.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.cvs_proxy.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.cvs_proxy_port.set_text(self.configuration.combine_port_only("cvs"))
- self.cvs_proxy_port.set_editable(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.cvs_proxy_port.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
- self.cvs_proxy_details.set_sensitive(self.configuration.enable_proxy and (not self.configuration.same_proxy))
-
- if self.configuration.same_proxy:
- if self.http_proxy.get_text():
- [w.set_text(self.http_proxy.get_text()) for w in self.same_proxy_addresses]
- if self.http_proxy_port.get_text():
- [w.set_text(self.http_proxy_port.get_text()) for w in self.same_proxy_ports]
-
- def proxy_checkbox_toggled_cb(self, button):
- self.configuration.enable_proxy = self.proxy_checkbox.get_active()
- if not self.configuration.enable_proxy:
- self.configuration.same_proxy = False
- self.same_checkbox.set_active(self.configuration.same_proxy)
- self.save_proxy_data()
- self.refresh_proxy_components()
-
- def same_checkbox_toggled_cb(self, button):
- self.configuration.same_proxy = self.same_checkbox.get_active()
- self.save_proxy_data()
- self.refresh_proxy_components()
-
- def save_proxy_data(self):
- self.configuration.split_proxy("http", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
- if self.configuration.same_proxy:
- self.configuration.split_proxy("https", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
- self.configuration.split_proxy("ftp", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
- self.configuration.split_proxy("socks", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
- self.configuration.split_proxy("cvs", self.http_proxy.get_text() + ":" + self.http_proxy_port.get_text())
- else:
- self.configuration.split_proxy("https", self.https_proxy.get_text() + ":" + self.https_proxy_port.get_text())
- self.configuration.split_proxy("ftp", self.ftp_proxy.get_text() + ":" + self.ftp_proxy_port.get_text())
- self.configuration.split_proxy("socks", self.socks_proxy.get_text() + ":" + self.socks_proxy_port.get_text())
- self.configuration.split_proxy("cvs", self.cvs_proxy.get_text() + ":" + self.cvs_proxy_port.get_text())
-
- def response_cb(self, dialog, response_id):
- if response_id == gtk.RESPONSE_YES:
- if self.proxy_checkbox.get_active():
- # Check that all proxy entries have a corresponding port
- for proxy, port in zip(self.all_proxy_addresses, self.all_proxy_ports):
- if proxy.get_text() and not port.get_text():
- lbl = "<b>Enter all port numbers</b>"
- msg = "Proxy servers require a port number. Please make sure you have entered a port number for each proxy server."
- dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_WARNING, msg)
- button = dialog.add_button("Close", gtk.RESPONSE_OK)
- HobButton.style_button(button)
- response = dialog.run()
- dialog.destroy()
- self.emit_stop_by_name("response")
- return
-
- self.configuration.dldir = self.dldir_text.get_text()
- self.configuration.sstatedir = self.sstatedir_text.get_text()
- self.configuration.sstatemirror = ""
- for mirror in self.sstatemirrors_list:
- if mirror[1] != "" and mirror[2].startswith("file://"):
- smirror = mirror[2] + " " + mirror[1] + " \\n "
- self.configuration.sstatemirror += smirror
- self.configuration.bbthread = self.bb_spinner.get_value_as_int()
- self.configuration.pmake = self.pmake_spinner.get_value_as_int()
- self.save_proxy_data()
- self.configuration.extra_setting = {}
- it = self.setting_store.get_iter_first()
- while it:
- key = self.setting_store.get_value(it, 0)
- value = self.setting_store.get_value(it, 1)
- self.configuration.extra_setting[key] = value
- it = self.setting_store.iter_next(it)
-
- md5 = self.config_md5()
- self.settings_changed = (self.md5 != md5)
- self.proxy_settings_changed = (self.proxy_md5 != self.config_proxy_md5())
-
- def create_build_environment_page(self):
- advanced_vbox = gtk.VBox(False, 6)
- advanced_vbox.set_border_width(6)
-
- advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Parallel threads</span>'), expand=False, fill=False)
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = self.gen_label_widget("BitBake parallel threads")
- tooltip = "Sets the number of threads that BitBake tasks can simultaneously run. See the <a href=\""
- tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
- tooltip += "poky-ref-manual.html#var-BB_NUMBER_THREADS\">Poky reference manual</a> for information"
- bbthread_widget, self.bb_spinner = self.gen_spinner_widget(self.configuration.bbthread, 1, self.max_threads,"<b>BitBake prallalel threads</b>" + "*" + tooltip)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(bbthread_widget, expand=False, fill=False)
-
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = self.gen_label_widget("Make parallel threads")
- tooltip = "Sets the maximum number of threads the host can use during the build. See the <a href=\""
- tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
- tooltip += "poky-ref-manual.html#var-PARALLEL_MAKE\">Poky reference manual</a> for information"
- pmake_widget, self.pmake_spinner = self.gen_spinner_widget(self.configuration.pmake, 1, self.max_threads,"<b>Make parallel threads</b>" + "*" + tooltip)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(pmake_widget, expand=False, fill=False)
-
- advanced_vbox.pack_start(self.gen_label_widget('<span weight="bold">Downloaded source code</span>'), expand=False, fill=False)
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = self.gen_label_widget("Downloads directory")
- tooltip = "Select a folder that caches the upstream project source code"
- dldir_widget, self.dldir_text = self.gen_entry_widget(self.configuration.dldir, self,"<b>Downloaded source code</b>" + "*" + tooltip)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(dldir_widget, expand=False, fill=False)
-
- return advanced_vbox
-
- def create_shared_state_page(self):
- advanced_vbox = gtk.VBox(False)
- advanced_vbox.set_border_width(12)
-
- sub_vbox = gtk.VBox(False)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False, padding=24)
- content = "<span>Shared state directory</span>"
- tooltip = "Select a folder that caches your prebuilt results"
- label = self.gen_label_info_widget(content,"<b>Shared state directory</b>" + "*" + tooltip)
- sstatedir_widget, self.sstatedir_text = self.gen_entry_widget(self.configuration.sstatedir, self)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False, padding=6)
-
- content = "<span weight=\"bold\">Shared state mirrors</span>"
- tooltip = "URLs pointing to pre-built mirrors that will speed your build. "
- tooltip += "Select the \'Standard\' configuration if the structure of your "
- tooltip += "mirror replicates the structure of your local shared state directory. "
- tooltip += "For more information on shared state mirrors, check the <a href=\""
- tooltip += "http://www.yoctoproject.org/docs/current/poky-ref-manual/"
- tooltip += "poky-ref-manual.html#shared-state\">Yocto Project Reference Manual</a>."
- table = self.gen_label_info_widget(content,"<b>Shared state mirrors</b>" + "*" + tooltip)
- advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
-
- sub_vbox = gtk.VBox(False)
- advanced_vbox.pack_start(sub_vbox, gtk.TRUE, gtk.TRUE, 0)
-
- if self.sstatemirrors_changed == 0:
- self.sstatemirrors_changed = 1
- sstatemirrors = self.configuration.sstatemirror
- if sstatemirrors == "":
- sm_list = ["Standard", "", "file://(.*)"]
- self.sstatemirrors_list.append(sm_list)
- else:
- sstatemirrors = [x for x in sstatemirrors.split('\\n')]
- for sstatemirror in sstatemirrors:
- sstatemirror_fields = [x for x in sstatemirror.split(' ') if x.strip()]
- if len(sstatemirror_fields) == 2:
- if sstatemirror_fields[0] == "file://(.*)" or sstatemirror_fields[0] == "file://.*":
- sm_list = ["Standard", sstatemirror_fields[1], sstatemirror_fields[0]]
- else:
- sm_list = ["Custom", sstatemirror_fields[1], sstatemirror_fields[0]]
- self.sstatemirrors_list.append(sm_list)
-
- sstatemirrors_widget, sstatemirrors_store = self.gen_shared_sstate_widget(self.sstatemirrors_list, self)
- sub_vbox.pack_start(sstatemirrors_widget, expand=True, fill=True)
-
- table = gtk.Table(1, 10, False)
- table.set_col_spacings(6)
- add_mirror_button = HobAltButton("Add mirror")
- add_mirror_button.connect("clicked", self.add_mirror)
- add_mirror_button.set_size_request(120,30)
- table.attach(add_mirror_button, 1, 2, 0, 1, xoptions=gtk.SHRINK)
-
- self.delete_button = HobAltButton("Delete mirror")
- self.delete_button.connect("clicked", self.delete_cb)
- self.delete_button.set_size_request(120, 30)
- table.attach(self.delete_button, 3, 4, 0, 1, xoptions=gtk.SHRINK)
-
- advanced_vbox.pack_start(table, expand=False, fill=False, padding=6)
-
- return advanced_vbox
-
- def gen_shared_sstate_widget(self, sstatemirrors_list, window):
- hbox = gtk.HBox(False)
-
- sstatemirrors_store = gtk.ListStore(str, str, str)
- for sstatemirror in sstatemirrors_list:
- sstatemirrors_store.append(sstatemirror)
-
- self.sstatemirrors_tv = gtk.TreeView()
- self.sstatemirrors_tv.set_rules_hint(True)
- self.sstatemirrors_tv.set_headers_visible(True)
- tree_selection = self.sstatemirrors_tv.get_selection()
- tree_selection.set_mode(gtk.SELECTION_SINGLE)
-
- # Allow enable drag and drop of rows including row move
- self.sstatemirrors_tv.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
- self.TARGETS,
- gtk.gdk.ACTION_DEFAULT|
- gtk.gdk.ACTION_MOVE)
- self.sstatemirrors_tv.enable_model_drag_dest(self.TARGETS,
- gtk.gdk.ACTION_DEFAULT)
- self.sstatemirrors_tv.connect("drag_data_get", self.drag_data_get_cb)
- self.sstatemirrors_tv.connect("drag_data_received", self.drag_data_received_cb)
-
-
- self.scroll = gtk.ScrolledWindow()
- self.scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
- self.scroll.set_shadow_type(gtk.SHADOW_IN)
- self.scroll.connect('size-allocate', self.scroll_changed)
- self.scroll.add(self.sstatemirrors_tv)
-
- #list store for cell renderer
- m = gtk.ListStore(gobject.TYPE_STRING)
- m.append(["Standard"])
- m.append(["Custom"])
-
- cell0 = gtk.CellRendererCombo()
- cell0.set_property("model",m)
- cell0.set_property("text-column", 0)
- cell0.set_property("editable", True)
- cell0.set_property("has-entry", False)
- col0 = gtk.TreeViewColumn("Configuration")
- col0.pack_start(cell0, False)
- col0.add_attribute(cell0, "text", 0)
- col0.set_cell_data_func(cell0, self.configuration_field)
- self.sstatemirrors_tv.append_column(col0)
-
- cell0.connect("edited", self.combo_changed, sstatemirrors_store)
-
- self.cell1 = gtk.CellRendererText()
- self.cell1.set_padding(5,2)
- col1 = gtk.TreeViewColumn('Regex', self.cell1)
- col1.set_cell_data_func(self.cell1, self.regex_field)
- self.sstatemirrors_tv.append_column(col1)
-
- self.cell1.connect("edited", self.regex_changed, sstatemirrors_store)
-
- cell2 = gtk.CellRendererText()
- cell2.set_padding(5,2)
- cell2.set_property("editable", True)
- col2 = gtk.TreeViewColumn('URL', cell2)
- col2.set_cell_data_func(cell2, self.url_field)
- self.sstatemirrors_tv.append_column(col2)
-
- cell2.connect("edited", self.url_changed, sstatemirrors_store)
-
- self.sstatemirrors_tv.set_model(sstatemirrors_store)
- self.sstatemirrors_tv.set_cursor(self.selected_mirror_row)
- hbox.pack_start(self.scroll, expand=True, fill=True)
- hbox.show_all()
-
- return hbox, sstatemirrors_store
-
- def drag_data_get_cb(self, treeview, context, selection, target_id, etime):
- treeselection = treeview.get_selection()
- model, iter = treeselection.get_selected()
- data = model.get_string_from_iter(iter)
- selection.set(selection.target, 8, data)
-
- def drag_data_received_cb(self, treeview, context, x, y, selection, info, etime):
- model = treeview.get_model()
- data = []
- tree_iter = model.get_iter_from_string(selection.data)
- data.append(model.get_value(tree_iter, 0))
- data.append(model.get_value(tree_iter, 1))
- data.append(model.get_value(tree_iter, 2))
-
- drop_info = treeview.get_dest_row_at_pos(x, y)
- if drop_info:
- path, position = drop_info
- iter = model.get_iter(path)
- if (position == gtk.TREE_VIEW_DROP_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
- model.insert_before(iter, data)
- else:
- model.insert_after(iter, data)
- else:
- model.append(data)
- if context.action == gtk.gdk.ACTION_MOVE:
- context.finish(True, True, etime)
- return
-
- def delete_cb(self, button):
- selection = self.sstatemirrors_tv.get_selection()
- tree_model, tree_iter = selection.get_selected()
- index = int(tree_model.get_string_from_iter(tree_iter))
- if index == 0:
- self.selected_mirror_row = index
- else:
- self.selected_mirror_row = index - 1
- self.sstatemirrors_list.pop(index)
- self.refresh_shared_state_page()
- if not self.sstatemirrors_list:
- self.delete_button.set_sensitive(False)
-
- def add_mirror(self, button):
- self.new_mirror = True
- tooltip = "Select the pre-built mirror that will speed your build"
- index = len(self.sstatemirrors_list)
- self.selected_mirror_row = index
- sm_list = ["Standard", "", "file://(.*)"]
- self.sstatemirrors_list.append(sm_list)
- self.refresh_shared_state_page()
-
- def scroll_changed(self, widget, event, data=None):
- if self.new_mirror == True:
- adj = widget.get_vadjustment()
- adj.set_value(adj.upper - adj.page_size)
- self.new_mirror = False
-
- def combo_changed(self, widget, path, text, model):
- model[path][0] = text
- selection = self.sstatemirrors_tv.get_selection()
- tree_model, tree_iter = selection.get_selected()
- index = int(tree_model.get_string_from_iter(tree_iter))
- self.sstatemirrors_list[index][0] = text
-
- def regex_changed(self, cell, path, new_text, user_data):
- user_data[path][2] = new_text
- selection = self.sstatemirrors_tv.get_selection()
- tree_model, tree_iter = selection.get_selected()
- index = int(tree_model.get_string_from_iter(tree_iter))
- self.sstatemirrors_list[index][2] = new_text
- return
-
- def url_changed(self, cell, path, new_text, user_data):
- if new_text!="Enter the mirror URL" and new_text!="Match regex and replace it with this URL":
- user_data[path][1] = new_text
- selection = self.sstatemirrors_tv.get_selection()
- tree_model, tree_iter = selection.get_selected()
- index = int(tree_model.get_string_from_iter(tree_iter))
- self.sstatemirrors_list[index][1] = new_text
- return
-
- def configuration_field(self, column, cell, model, iter):
- cell.set_property('text', model.get_value(iter, 0))
- if model.get_value(iter, 0) == "Standard":
- self.cell1.set_property("sensitive", False)
- self.cell1.set_property("editable", False)
- else:
- self.cell1.set_property("sensitive", True)
- self.cell1.set_property("editable", True)
- return
-
- def regex_field(self, column, cell, model, iter):
- cell.set_property('text', model.get_value(iter, 2))
- return
-
- def url_field(self, column, cell, model, iter):
- text = model.get_value(iter, 1)
- if text == "":
- if model.get_value(iter, 0) == "Standard":
- text = "Enter the mirror URL"
- else:
- text = "Match regex and replace it with this URL"
- cell.set_property('text', text)
- return
-
- def refresh_shared_state_page(self):
- page_num = self.nb.get_current_page()
- self.nb.remove_page(page_num);
- self.nb.insert_page(self.create_shared_state_page(), gtk.Label("Shared state"),page_num)
- self.show_all()
- self.nb.set_current_page(page_num)
-
- def test_proxy_ended(self, passed):
- self.proxy_test_running = False
- self.set_test_proxy_state(self.TEST_NETWORK_PASSED if passed else self.TEST_NETWORK_FAILED)
- self.set_sensitive(True)
- self.refresh_proxy_components()
-
- def timer_func(self):
- self.test_proxy_progress.pulse()
- return self.proxy_test_running
-
- def test_network_button_cb(self, b):
- self.set_test_proxy_state(self.TEST_NETWORK_RUNNING)
- self.set_sensitive(False)
- self.save_proxy_data()
- if self.configuration.enable_proxy == True:
- self.handler.set_http_proxy(self.configuration.combine_proxy("http"))
- self.handler.set_https_proxy(self.configuration.combine_proxy("https"))
- self.handler.set_ftp_proxy(self.configuration.combine_proxy("ftp"))
- self.handler.set_socks_proxy(self.configuration.combine_proxy("socks"))
- self.handler.set_cvs_proxy(self.configuration.combine_host_only("cvs"), self.configuration.combine_port_only("cvs"))
- elif self.configuration.enable_proxy == False:
- self.handler.set_http_proxy("")
- self.handler.set_https_proxy("")
- self.handler.set_ftp_proxy("")
- self.handler.set_socks_proxy("")
- self.handler.set_cvs_proxy("", "")
- self.proxy_test_ran = True
- self.proxy_test_running = True
- gobject.timeout_add(100, self.timer_func)
- self.handler.trigger_network_test()
-
- def test_proxy_focus_event(self, w, direction):
- if self.test_proxy_state in [self.TEST_NETWORK_PASSED, self.TEST_NETWORK_FAILED]:
- self.set_test_proxy_state(self.TEST_NETWORK_INITIAL)
- return False
-
- def http_proxy_changed(self, e):
- if not self.configuration.same_proxy:
- return
- if e == self.http_proxy:
- [w.set_text(self.http_proxy.get_text()) for w in self.same_proxy_addresses]
- else:
- [w.set_text(self.http_proxy_port.get_text()) for w in self.same_proxy_ports]
-
- def proxy_address_focus_out_event(self, w, direction):
- text = w.get_text()
- if not text:
- return False
- if text.find("//") == -1:
- w.set_text("http://" + text)
- return False
-
- def set_test_proxy_state(self, state):
- if self.test_proxy_state == state:
- return
- [self.proxy_table.remove(w) for w in self.test_gui_elements]
- if state == self.TEST_NETWORK_INITIAL:
- self.proxy_table.attach(self.test_network_button, 1, 2, 5, 6)
- self.test_network_button.show()
- elif state == self.TEST_NETWORK_RUNNING:
- self.test_proxy_progress.set_rcstyle("running")
- self.test_proxy_progress.set_text("Testing network configuration")
- self.proxy_table.attach(self.test_proxy_progress, 0, 5, 5, 6, xpadding=4)
- self.test_proxy_progress.show()
- else: # passed or failed
- self.dummy_progress.update(1.0)
- if state == self.TEST_NETWORK_PASSED:
- self.dummy_progress.set_text("Your network is properly configured")
- self.dummy_progress.set_rcstyle("running")
- else:
- self.dummy_progress.set_text("Network test failed")
- self.dummy_progress.set_rcstyle("fail")
- self.proxy_table.attach(self.dummy_progress, 0, 4, 5, 6)
- self.proxy_table.attach(self.retest_network_button, 4, 5, 5, 6, xpadding=4)
- self.dummy_progress.show()
- self.retest_network_button.show()
- self.test_proxy_state = state
-
- def create_network_page(self):
- advanced_vbox = gtk.VBox(False, 6)
- advanced_vbox.set_border_width(6)
- self.same_proxy_addresses = []
- self.same_proxy_ports = []
- self.all_proxy_ports = []
- self.all_proxy_addresses = []
-
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
- label = self.gen_label_widget("<span weight=\"bold\">Set the proxies used when fetching source code</span>")
- tooltip = "Set the proxies used when fetching source code. A blank field uses a direct internet connection."
- info = HobInfoButton("<span weight=\"bold\">Set the proxies used when fetching source code</span>" + "*" + tooltip, self)
- hbox = gtk.HBox(False, 12)
- hbox.pack_start(label, expand=True, fill=True)
- hbox.pack_start(info, expand=False, fill=False)
- sub_vbox.pack_start(hbox, expand=False, fill=False)
-
- proxy_test_focus = []
- self.direct_checkbox = gtk.RadioButton(None, "Direct network connection")
- proxy_test_focus.append(self.direct_checkbox)
- self.direct_checkbox.set_tooltip_text("Check this box to use a direct internet connection with no proxy")
- self.direct_checkbox.set_active(not self.configuration.enable_proxy)
- sub_vbox.pack_start(self.direct_checkbox, expand=False, fill=False)
-
- self.proxy_checkbox = gtk.RadioButton(self.direct_checkbox, "Manual proxy configuration")
- proxy_test_focus.append(self.proxy_checkbox)
- self.proxy_checkbox.set_tooltip_text("Check this box to manually set up a specific proxy")
- self.proxy_checkbox.set_active(self.configuration.enable_proxy)
- sub_vbox.pack_start(self.proxy_checkbox, expand=False, fill=False)
-
- self.same_checkbox = gtk.CheckButton("Use the HTTP proxy for all protocols")
- proxy_test_focus.append(self.same_checkbox)
- self.same_checkbox.set_tooltip_text("Check this box to use the HTTP proxy for all five proxies")
- self.same_checkbox.set_active(self.configuration.same_proxy)
- hbox = gtk.HBox(False, 12)
- hbox.pack_start(self.same_checkbox, expand=False, fill=False, padding=24)
- sub_vbox.pack_start(hbox, expand=False, fill=False)
-
- self.proxy_table = gtk.Table(6, 5, False)
- self.http_proxy, self.http_proxy_port, self.http_proxy_details = self.gen_proxy_entry_widget(
- "http", self, True, 0)
- proxy_test_focus +=[self.http_proxy, self.http_proxy_port]
- self.http_proxy.connect("changed", self.http_proxy_changed)
- self.http_proxy_port.connect("changed", self.http_proxy_changed)
-
- self.https_proxy, self.https_proxy_port, self.https_proxy_details = self.gen_proxy_entry_widget(
- "https", self, True, 1)
- proxy_test_focus += [self.https_proxy, self.https_proxy_port]
- self.same_proxy_addresses.append(self.https_proxy)
- self.same_proxy_ports.append(self.https_proxy_port)
-
- self.ftp_proxy, self.ftp_proxy_port, self.ftp_proxy_details = self.gen_proxy_entry_widget(
- "ftp", self, True, 2)
- proxy_test_focus += [self.ftp_proxy, self.ftp_proxy_port]
- self.same_proxy_addresses.append(self.ftp_proxy)
- self.same_proxy_ports.append(self.ftp_proxy_port)
-
- self.socks_proxy, self.socks_proxy_port, self.socks_proxy_details = self.gen_proxy_entry_widget(
- "socks", self, True, 3)
- proxy_test_focus += [self.socks_proxy, self.socks_proxy_port]
- self.same_proxy_addresses.append(self.socks_proxy)
- self.same_proxy_ports.append(self.socks_proxy_port)
-
- self.cvs_proxy, self.cvs_proxy_port, self.cvs_proxy_details = self.gen_proxy_entry_widget(
- "cvs", self, True, 4)
- proxy_test_focus += [self.cvs_proxy, self.cvs_proxy_port]
- self.same_proxy_addresses.append(self.cvs_proxy)
- self.same_proxy_ports.append(self.cvs_proxy_port)
- self.all_proxy_ports = self.same_proxy_ports + [self.http_proxy_port]
- self.all_proxy_addresses = self.same_proxy_addresses + [self.http_proxy]
- sub_vbox.pack_start(self.proxy_table, expand=False, fill=False)
- self.proxy_table.show_all()
-
- # Create the graphical elements for the network test feature, but don't display them yet
- self.test_network_button = HobAltButton("Test network configuration")
- self.test_network_button.connect("clicked", self.test_network_button_cb)
- self.test_proxy_progress = HobProgressBar()
- self.dummy_progress = HobProgressBar()
- self.retest_network_button = HobAltButton("Retest")
- self.retest_network_button.connect("clicked", self.test_network_button_cb)
- self.test_gui_elements = [self.test_network_button, self.test_proxy_progress, self.dummy_progress, self.retest_network_button]
- # Initialize the network tester
- self.test_proxy_state = self.TEST_NETWORK_NONE
- self.set_test_proxy_state(self.TEST_NETWORK_INITIAL)
- self.proxy_test_passed_id = self.handler.connect("network-passed", lambda h:self.test_proxy_ended(True))
- self.proxy_test_failed_id = self.handler.connect("network-failed", lambda h:self.test_proxy_ended(False))
- [w.connect("focus-in-event", self.test_proxy_focus_event) for w in proxy_test_focus]
- [w.connect("focus-out-event", self.proxy_address_focus_out_event) for w in self.all_proxy_addresses]
-
- self.direct_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
- self.proxy_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
- self.same_checkbox.connect("toggled", self.same_checkbox_toggled_cb)
-
- self.refresh_proxy_components()
- return advanced_vbox
-
- def switch_to_page(self, page_id):
- self.nb.set_current_page(page_id)
-
- def details_cb(self, button, parent, protocol):
- self.save_proxy_data()
- dialog = ProxyDetailsDialog(title = protocol.upper() + " Proxy Details",
- user = self.configuration.proxies[protocol][1],
- passwd = self.configuration.proxies[protocol][2],
- parent = parent,
- flags = gtk.DIALOG_MODAL
- | gtk.DIALOG_DESTROY_WITH_PARENT
- | gtk.DIALOG_NO_SEPARATOR)
- dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)
- response = dialog.run()
- if response == gtk.RESPONSE_OK:
- self.configuration.proxies[protocol][1] = dialog.user
- self.configuration.proxies[protocol][2] = dialog.passwd
- self.refresh_proxy_components()
- dialog.destroy()
-
- def rootfs_combo_changed_cb(self, rootfs_combo, all_package_format, check_hbox):
- combo_item = self.rootfs_combo.get_active_text()
- for child in check_hbox.get_children():
- if isinstance(child, gtk.CheckButton):
- check_hbox.remove(child)
- for format in all_package_format:
- if format != combo_item:
- check_button = gtk.CheckButton(format)
- check_hbox.pack_start(check_button, expand=False, fill=False)
- check_hbox.show_all()
-
- def gen_pkgfmt_widget(self, curr_package_format, all_package_format, tooltip_combo="", tooltip_extra=""):
- pkgfmt_hbox = gtk.HBox(False, 24)
-
- rootfs_vbox = gtk.VBox(False, 6)
- pkgfmt_hbox.pack_start(rootfs_vbox, expand=False, fill=False)
-
- label = self.gen_label_widget("Root file system package format")
- rootfs_vbox.pack_start(label, expand=False, fill=False)
-
- rootfs_format = ""
- if curr_package_format:
- rootfs_format = curr_package_format.split()[0]
-
- rootfs_format_widget, rootfs_combo = self.gen_combo_widget(rootfs_format, all_package_format, tooltip_combo)
- rootfs_vbox.pack_start(rootfs_format_widget, expand=False, fill=False)
-
- extra_vbox = gtk.VBox(False, 6)
- pkgfmt_hbox.pack_start(extra_vbox, expand=False, fill=False)
-
- label = self.gen_label_widget("Additional package formats")
- extra_vbox.pack_start(label, expand=False, fill=False)
-
- check_hbox = gtk.HBox(False, 12)
- extra_vbox.pack_start(check_hbox, expand=False, fill=False)
- for format in all_package_format:
- if format != rootfs_format:
- check_button = gtk.CheckButton(format)
- is_active = (format in curr_package_format.split())
- check_button.set_active(is_active)
- check_hbox.pack_start(check_button, expand=False, fill=False)
-
- info = HobInfoButton(tooltip_extra, self)
- check_hbox.pack_end(info, expand=False, fill=False)
-
- rootfs_combo.connect("changed", self.rootfs_combo_changed_cb, all_package_format, check_hbox)
-
- pkgfmt_hbox.show_all()
-
- return pkgfmt_hbox, rootfs_combo, check_hbox
-
- def editable_settings_cell_edited(self, cell, path_string, new_text, model):
- it = model.get_iter_from_string(path_string)
- column = cell.get_data("column")
- model.set(it, column, new_text)
-
- def editable_settings_add_item_clicked(self, button, model):
- new_item = ["##KEY##", "##VALUE##"]
-
- iter = model.append()
- model.set (iter,
- 0, new_item[0],
- 1, new_item[1],
- )
-
- def editable_settings_remove_item_clicked(self, button, treeview):
- selection = treeview.get_selection()
- model, iter = selection.get_selected()
-
- if iter:
- path = model.get_path(iter)[0]
- model.remove(iter)
-
- def gen_editable_settings(self, setting, tooltip=""):
- setting_hbox = gtk.HBox(False, 12)
-
- vbox = gtk.VBox(False, 12)
- setting_hbox.pack_start(vbox, expand=True, fill=True)
-
- setting_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
- for key in setting.keys():
- setting_store.set(setting_store.append(), 0, key, 1, setting[key])
-
- setting_tree = gtk.TreeView(setting_store)
- setting_tree.set_headers_visible(True)
- setting_tree.set_size_request(300, 100)
-
- col = gtk.TreeViewColumn('Key')
- col.set_min_width(100)
- col.set_max_width(150)
- col.set_resizable(True)
- col1 = gtk.TreeViewColumn('Value')
- col1.set_min_width(100)
- col1.set_max_width(150)
- col1.set_resizable(True)
- setting_tree.append_column(col)
- setting_tree.append_column(col1)
- cell = gtk.CellRendererText()
- cell.set_property('width-chars', 10)
- cell.set_property('editable', True)
- cell.set_data("column", 0)
- cell.connect("edited", self.editable_settings_cell_edited, setting_store)
- cell1 = gtk.CellRendererText()
- cell1.set_property('width-chars', 10)
- cell1.set_property('editable', True)
- cell1.set_data("column", 1)
- cell1.connect("edited", self.editable_settings_cell_edited, setting_store)
- col.pack_start(cell, True)
- col1.pack_end(cell1, True)
- col.set_attributes(cell, text=0)
- col1.set_attributes(cell1, text=1)
-
- scroll = gtk.ScrolledWindow()
- scroll.set_shadow_type(gtk.SHADOW_IN)
- scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- scroll.add(setting_tree)
- vbox.pack_start(scroll, expand=True, fill=True)
-
- # some buttons
- hbox = gtk.HBox(True, 6)
- vbox.pack_start(hbox, False, False)
-
- button = gtk.Button(stock=gtk.STOCK_ADD)
- button.connect("clicked", self.editable_settings_add_item_clicked, setting_store)
- hbox.pack_start(button)
-
- button = gtk.Button(stock=gtk.STOCK_REMOVE)
- button.connect("clicked", self.editable_settings_remove_item_clicked, setting_tree)
- hbox.pack_start(button)
-
- info = HobInfoButton(tooltip, self)
- setting_hbox.pack_start(info, expand=False, fill=False)
-
- return setting_hbox, setting_store
-
- def create_others_page(self):
- advanced_vbox = gtk.VBox(False, 6)
- advanced_vbox.set_border_width(6)
-
- sub_vbox = gtk.VBox(False, 6)
- advanced_vbox.pack_start(sub_vbox, expand=True, fill=True)
- label = self.gen_label_widget("<span weight=\"bold\">Add your own variables:</span>")
- tooltip = "These are key/value pairs for your extra settings. Click \'Add\' and then directly edit the key and the value"
- setting_widget, self.setting_store = self.gen_editable_settings(self.configuration.extra_setting,"<b>Add your own variables</b>" + "*" + tooltip)
- sub_vbox.pack_start(label, expand=False, fill=False)
- sub_vbox.pack_start(setting_widget, expand=True, fill=True)
-
- return advanced_vbox
-
- def create_visual_elements(self):
- self.nb = gtk.Notebook()
- self.nb.set_show_tabs(True)
- self.nb.append_page(self.create_build_environment_page(), gtk.Label("Build environment"))
- self.nb.append_page(self.create_shared_state_page(), gtk.Label("Shared state"))
- self.nb.append_page(self.create_network_page(), gtk.Label("Network"))
- self.nb.append_page(self.create_others_page(), gtk.Label("Others"))
- self.nb.set_current_page(0)
- self.vbox.pack_start(self.nb, expand=True, fill=True)
- self.vbox.pack_end(gtk.HSeparator(), expand=True, fill=True)
-
- self.show_all()
-
- def destroy(self):
- self.handler.disconnect(self.proxy_test_passed_id)
- self.handler.disconnect(self.proxy_test_failed_id)
- super(SimpleSettingsDialog, self).destroy()
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hobeventhandler.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
deleted file mode 100644
index b71fb33d3..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
+++ /dev/null
@@ -1,645 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011 Intel Corporation
-#
-# Authored by Joshua Lock <josh@linux.intel.com>
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gobject
-import logging
-import ast
-from bb.ui.crumbs.runningbuild import RunningBuild
-
-class HobHandler(gobject.GObject):
-
- """
- This object does BitBake event handling for the hob gui.
- """
- __gsignals__ = {
- "package-formats-updated" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT,)),
- "config-updated" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT,)),
- "command-succeeded" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_INT,)),
- "command-failed" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING,)),
- "parsing-warning" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING,)),
- "sanity-failed" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING, gobject.TYPE_INT)),
- "generating-data" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- "data-generated" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- "parsing-started" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT,)),
- "parsing" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT,)),
- "parsing-completed" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_PYOBJECT,)),
- "recipe-populated" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- "package-populated" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- "network-passed" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- "network-failed" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- }
-
- (GENERATE_CONFIGURATION, GENERATE_RECIPES, GENERATE_PACKAGES, GENERATE_IMAGE, POPULATE_PACKAGEINFO, SANITY_CHECK, NETWORK_TEST) = range(7)
- (SUB_PATH_LAYERS, SUB_FILES_DISTRO, SUB_FILES_MACH, SUB_FILES_SDKMACH, SUB_MATCH_CLASS, SUB_PARSE_CONFIG, SUB_SANITY_CHECK,
- SUB_GNERATE_TGTS, SUB_GENERATE_PKGINFO, SUB_BUILD_RECIPES, SUB_BUILD_IMAGE, SUB_NETWORK_TEST) = range(12)
-
- def __init__(self, server, recipe_model, package_model):
- super(HobHandler, self).__init__()
-
- self.build = RunningBuild(sequential=True)
-
- self.recipe_model = recipe_model
- self.package_model = package_model
-
- self.commands_async = []
- self.generating = False
- self.current_phase = None
- self.building = False
- self.recipe_queue = []
- self.package_queue = []
-
- self.server = server
- self.error_msg = ""
- self.initcmd = None
- self.parsing = False
-
- def set_busy(self):
- if not self.generating:
- self.emit("generating-data")
- self.generating = True
-
- def clear_busy(self):
- if self.generating:
- self.emit("data-generated")
- self.generating = False
-
- def runCommand(self, commandline):
- try:
- result, error = self.server.runCommand(commandline)
- if error:
- raise Exception("Error running command '%s': %s" % (commandline, error))
- return result
- except Exception as e:
- self.commands_async = []
- self.clear_busy()
- self.emit("command-failed", "Hob Exception - %s" % (str(e)))
- return None
-
- def run_next_command(self, initcmd=None):
- if initcmd != None:
- self.initcmd = initcmd
-
- if self.commands_async:
- self.set_busy()
- next_command = self.commands_async.pop(0)
- else:
- self.clear_busy()
- if self.initcmd != None:
- self.emit("command-succeeded", self.initcmd)
- return
-
- if next_command == self.SUB_PATH_LAYERS:
- self.runCommand(["findConfigFilePath", "bblayers.conf"])
- elif next_command == self.SUB_FILES_DISTRO:
- self.runCommand(["findConfigFiles", "DISTRO"])
- elif next_command == self.SUB_FILES_MACH:
- self.runCommand(["findConfigFiles", "MACHINE"])
- elif next_command == self.SUB_FILES_SDKMACH:
- self.runCommand(["findConfigFiles", "MACHINE-SDK"])
- elif next_command == self.SUB_MATCH_CLASS:
- self.runCommand(["findFilesMatchingInDir", "rootfs_", "classes"])
- elif next_command == self.SUB_PARSE_CONFIG:
- self.runCommand(["resetCooker"])
- elif next_command == self.SUB_GNERATE_TGTS:
- self.runCommand(["generateTargetsTree", "classes/image.bbclass", []])
- elif next_command == self.SUB_GENERATE_PKGINFO:
- self.runCommand(["triggerEvent", "bb.event.RequestPackageInfo()"])
- elif next_command == self.SUB_SANITY_CHECK:
- self.runCommand(["triggerEvent", "bb.event.SanityCheck()"])
- elif next_command == self.SUB_NETWORK_TEST:
- self.runCommand(["triggerEvent", "bb.event.NetworkTest()"])
- elif next_command == self.SUB_BUILD_RECIPES:
- self.clear_busy()
- self.building = True
- self.runCommand(["buildTargets", self.recipe_queue, self.default_task])
- self.recipe_queue = []
- elif next_command == self.SUB_BUILD_IMAGE:
- self.clear_busy()
- self.building = True
- target = self.image
-
- if self.base_image:
- # Request the build of a custom image
- self.generate_hob_base_image(target)
- self.set_var_in_file("LINGUAS_INSTALL", "", "local.conf")
- hobImage = self.runCommand(["matchFile", target + ".bb"])
- if self.base_image != self.recipe_model.__custom_image__:
- baseImage = self.runCommand(["matchFile", self.base_image + ".bb"])
- version = self.runCommand(["generateNewImage", hobImage, baseImage, self.package_queue, True, ""])
- target += version
- self.recipe_model.set_custom_image_version(version)
-
- targets = [target]
- if self.toolchain_packages:
- self.set_var_in_file("TOOLCHAIN_TARGET_TASK", " ".join(self.toolchain_packages), "local.conf")
- targets.append(target + ":do_populate_sdk")
-
- self.runCommand(["buildTargets", targets, self.default_task])
-
- def display_error(self):
- self.clear_busy()
- self.emit("command-failed", self.error_msg)
- self.error_msg = ""
- if self.building:
- self.building = False
-
- def handle_event(self, event):
- if not event:
- return
- if self.building:
- self.current_phase = "building"
- self.build.handle_event(event)
-
- if isinstance(event, bb.event.PackageInfo):
- self.package_model.populate(event._pkginfolist)
- self.emit("package-populated")
- self.run_next_command()
-
- elif isinstance(event, bb.event.SanityCheckPassed):
- reparse = self.runCommand(["getVariable", "BB_INVALIDCONF"]) or None
- if reparse is True:
- self.set_var_in_file("BB_INVALIDCONF", False, "local.conf")
- self.runCommand(["setPrePostConfFiles", "conf/.hob.conf", ""])
- self.commands_async.prepend(self.SUB_PARSE_CONFIG)
- self.run_next_command()
-
- elif isinstance(event, bb.event.SanityCheckFailed):
- self.emit("sanity-failed", event._msg, event._network_error)
-
- elif isinstance(event, logging.LogRecord):
- if not self.building:
- if event.levelno >= logging.ERROR:
- formatter = bb.msg.BBLogFormatter()
- msg = formatter.format(event)
- self.error_msg += msg + '\n'
- elif event.levelno >= logging.WARNING and self.parsing == True:
- formatter = bb.msg.BBLogFormatter()
- msg = formatter.format(event)
- warn_msg = msg + '\n'
- self.emit("parsing-warning", warn_msg)
-
- elif isinstance(event, bb.event.TargetsTreeGenerated):
- self.current_phase = "data generation"
- if event._model:
- self.recipe_model.populate(event._model)
- self.emit("recipe-populated")
- elif isinstance(event, bb.event.ConfigFilesFound):
- self.current_phase = "configuration lookup"
- var = event._variable
- values = event._values
- values.sort()
- self.emit("config-updated", var, values)
- elif isinstance(event, bb.event.ConfigFilePathFound):
- self.current_phase = "configuration lookup"
- elif isinstance(event, bb.event.FilesMatchingFound):
- self.current_phase = "configuration lookup"
- # FIXME: hard coding, should at least be a variable shared between
- # here and the caller
- if event._pattern == "rootfs_":
- formats = []
- for match in event._matches:
- classname, sep, cls = match.rpartition(".")
- fs, sep, format = classname.rpartition("_")
- formats.append(format)
- formats.sort()
- self.emit("package-formats-updated", formats)
- elif isinstance(event, bb.command.CommandCompleted):
- self.current_phase = None
- self.run_next_command()
- elif isinstance(event, bb.command.CommandFailed):
- if event.error not in ("Forced shutdown", "Stopped build"):
- self.error_msg += event.error
- self.commands_async = []
- self.display_error()
- elif isinstance(event, (bb.event.ParseStarted,
- bb.event.CacheLoadStarted,
- bb.event.TreeDataPreparationStarted,
- )):
- message = {}
- message["eventname"] = bb.event.getName(event)
- message["current"] = 0
- message["total"] = None
- message["title"] = "Parsing recipes"
- self.emit("parsing-started", message)
- if isinstance(event, bb.event.ParseStarted):
- self.parsing = True
- elif isinstance(event, (bb.event.ParseProgress,
- bb.event.CacheLoadProgress,
- bb.event.TreeDataPreparationProgress)):
- message = {}
- message["eventname"] = bb.event.getName(event)
- message["current"] = event.current
- message["total"] = event.total
- message["title"] = "Parsing recipes"
- self.emit("parsing", message)
- elif isinstance(event, (bb.event.ParseCompleted,
- bb.event.CacheLoadCompleted,
- bb.event.TreeDataPreparationCompleted)):
- message = {}
- message["eventname"] = bb.event.getName(event)
- message["current"] = event.total
- message["total"] = event.total
- message["title"] = "Parsing recipes"
- self.emit("parsing-completed", message)
- if isinstance(event, bb.event.ParseCompleted):
- self.parsing = False
- elif isinstance(event, bb.event.NetworkTestFailed):
- self.emit("network-failed")
- self.run_next_command()
- elif isinstance(event, bb.event.NetworkTestPassed):
- self.emit("network-passed")
- self.run_next_command()
-
- if self.error_msg and not self.commands_async:
- self.display_error()
-
- return
-
- def init_cooker(self):
- self.runCommand(["createConfigFile", ".hob.conf"])
-
- def set_extra_inherit(self, bbclass):
- self.append_var_in_file("INHERIT", bbclass, ".hob.conf")
-
- def set_bblayers(self, bblayers):
- self.set_var_in_file("BBLAYERS", " ".join(bblayers), "bblayers.conf")
-
- def set_machine(self, machine):
- if machine:
- self.early_assign_var_in_file("MACHINE", machine, "local.conf")
-
- def set_sdk_machine(self, sdk_machine):
- self.set_var_in_file("SDKMACHINE", sdk_machine, "local.conf")
-
- def set_image_fstypes(self, image_fstypes):
- self.set_var_in_file("IMAGE_FSTYPES", image_fstypes, "local.conf")
-
- def set_distro(self, distro):
- self.set_var_in_file("DISTRO", distro, "local.conf")
-
- def set_package_format(self, format):
- package_classes = ""
- for pkgfmt in format.split():
- package_classes += ("package_%s" % pkgfmt + " ")
- self.set_var_in_file("PACKAGE_CLASSES", package_classes, "local.conf")
-
- def set_bbthreads(self, threads):
- self.set_var_in_file("BB_NUMBER_THREADS", threads, "local.conf")
-
- def set_pmake(self, threads):
- pmake = "-j %s" % threads
- self.set_var_in_file("PARALLEL_MAKE", pmake, "local.conf")
-
- def set_dl_dir(self, directory):
- self.set_var_in_file("DL_DIR", directory, "local.conf")
-
- def set_sstate_dir(self, directory):
- self.set_var_in_file("SSTATE_DIR", directory, "local.conf")
-
- def set_sstate_mirrors(self, url):
- self.set_var_in_file("SSTATE_MIRRORS", url, "local.conf")
-
- def set_extra_size(self, image_extra_size):
- self.set_var_in_file("IMAGE_ROOTFS_EXTRA_SPACE", str(image_extra_size), "local.conf")
-
- def set_rootfs_size(self, image_rootfs_size):
- self.set_var_in_file("IMAGE_ROOTFS_SIZE", str(image_rootfs_size), "local.conf")
-
- def set_incompatible_license(self, incompat_license):
- self.set_var_in_file("INCOMPATIBLE_LICENSE", incompat_license, "local.conf")
-
- def set_extra_setting(self, extra_setting):
- self.set_var_in_file("EXTRA_SETTING", extra_setting, "local.conf")
-
- def set_extra_config(self, extra_setting):
- old_extra_setting = self.runCommand(["getVariable", "EXTRA_SETTING"]) or {}
- old_extra_setting = str(old_extra_setting)
-
- old_extra_setting = ast.literal_eval(old_extra_setting)
- if not type(old_extra_setting) == dict:
- old_extra_setting = {}
-
- # settings not changed
- if old_extra_setting == extra_setting:
- return
-
- # remove the old EXTRA SETTING variable
- self.remove_var_from_file("EXTRA_SETTING")
-
- # remove old settings from conf
- for key in old_extra_setting.keys():
- if key not in extra_setting:
- self.remove_var_from_file(key)
-
- # add new settings
- for key, value in extra_setting.iteritems():
- self.set_var_in_file(key, value, "local.conf")
-
- if extra_setting:
- self.set_var_in_file("EXTRA_SETTING", extra_setting, "local.conf")
-
- def set_http_proxy(self, http_proxy):
- self.set_var_in_file("http_proxy", http_proxy, "local.conf")
-
- def set_https_proxy(self, https_proxy):
- self.set_var_in_file("https_proxy", https_proxy, "local.conf")
-
- def set_ftp_proxy(self, ftp_proxy):
- self.set_var_in_file("ftp_proxy", ftp_proxy, "local.conf")
-
- def set_socks_proxy(self, socks_proxy):
- self.set_var_in_file("all_proxy", socks_proxy, "local.conf")
-
- def set_cvs_proxy(self, host, port):
- self.set_var_in_file("CVS_PROXY_HOST", host, "local.conf")
- self.set_var_in_file("CVS_PROXY_PORT", port, "local.conf")
-
- def request_package_info(self):
- self.commands_async.append(self.SUB_GENERATE_PKGINFO)
- self.run_next_command(self.POPULATE_PACKAGEINFO)
-
- def trigger_sanity_check(self):
- self.commands_async.append(self.SUB_SANITY_CHECK)
- self.run_next_command(self.SANITY_CHECK)
-
- def trigger_network_test(self):
- self.commands_async.append(self.SUB_NETWORK_TEST)
- self.run_next_command(self.NETWORK_TEST)
-
- def generate_configuration(self):
- self.runCommand(["setPrePostConfFiles", "conf/.hob.conf", ""])
- self.commands_async.append(self.SUB_PARSE_CONFIG)
- self.commands_async.append(self.SUB_PATH_LAYERS)
- self.commands_async.append(self.SUB_FILES_DISTRO)
- self.commands_async.append(self.SUB_FILES_MACH)
- self.commands_async.append(self.SUB_FILES_SDKMACH)
- self.commands_async.append(self.SUB_MATCH_CLASS)
- self.run_next_command(self.GENERATE_CONFIGURATION)
-
- def generate_recipes(self):
- self.runCommand(["setPrePostConfFiles", "conf/.hob.conf", ""])
- self.commands_async.append(self.SUB_PARSE_CONFIG)
- self.commands_async.append(self.SUB_GNERATE_TGTS)
- self.run_next_command(self.GENERATE_RECIPES)
-
- def generate_packages(self, tgts, default_task="build"):
- targets = []
- targets.extend(tgts)
- self.recipe_queue = targets
- self.default_task = default_task
- self.runCommand(["setPrePostConfFiles", "conf/.hob.conf", ""])
- self.commands_async.append(self.SUB_PARSE_CONFIG)
- self.commands_async.append(self.SUB_BUILD_RECIPES)
- self.run_next_command(self.GENERATE_PACKAGES)
-
- def generate_image(self, image, base_image, image_packages=None, toolchain_packages=None, default_task="build"):
- self.image = image
- self.base_image = base_image
- if image_packages:
- self.package_queue = image_packages
- else:
- self.package_queue = []
- if toolchain_packages:
- self.toolchain_packages = toolchain_packages
- else:
- self.toolchain_packages = []
- self.default_task = default_task
- self.runCommand(["setPrePostConfFiles", "conf/.hob.conf", ""])
- self.commands_async.append(self.SUB_PARSE_CONFIG)
- self.commands_async.append(self.SUB_BUILD_IMAGE)
- self.run_next_command(self.GENERATE_IMAGE)
-
- def generate_new_image(self, image, base_image, package_queue, description):
- if base_image:
- base_image = self.runCommand(["matchFile", self.base_image + ".bb"])
- self.runCommand(["generateNewImage", image, base_image, package_queue, False, description])
-
- def generate_hob_base_image(self, hob_image):
- image_dir = self.get_topdir() + "/recipes/images/"
- recipe_name = hob_image + ".bb"
- self.ensure_dir(image_dir)
- self.generate_new_image(image_dir + recipe_name, None, [], "")
-
- def ensure_dir(self, directory):
- self.runCommand(["ensureDir", directory])
-
- def build_succeeded_async(self):
- self.building = False
-
- def build_failed_async(self):
- self.initcmd = None
- self.commands_async = []
- self.building = False
-
- def cancel_parse(self):
- self.runCommand(["stateForceShutdown"])
-
- def cancel_build(self, force=False):
- if force:
- # Force the cooker to stop as quickly as possible
- self.runCommand(["stateForceShutdown"])
- else:
- # Wait for tasks to complete before shutting down, this helps
- # leave the workdir in a usable state
- self.runCommand(["stateShutdown"])
-
- def reset_build(self):
- self.build.reset()
-
- def get_logfile(self):
- return self.server.runCommand(["getVariable", "BB_CONSOLELOG"])[0]
-
- def get_topdir(self):
- return self.runCommand(["getVariable", "TOPDIR"]) or ""
-
- def _remove_redundant(self, string):
- ret = []
- for i in string.split():
- if i not in ret:
- ret.append(i)
- return " ".join(ret)
-
- def set_var_in_file(self, var, val, default_file=None):
- self.runCommand(["enableDataTracking"])
- self.server.runCommand(["setVarFile", var, val, default_file, "set"])
- self.runCommand(["disableDataTracking"])
-
- def early_assign_var_in_file(self, var, val, default_file=None):
- self.runCommand(["enableDataTracking"])
- self.server.runCommand(["setVarFile", var, val, default_file, "earlyAssign"])
- self.runCommand(["disableDataTracking"])
-
- def remove_var_from_file(self, var):
- self.server.runCommand(["removeVarFile", var])
-
- def append_var_in_file(self, var, val, default_file=None):
- self.server.runCommand(["setVarFile", var, val, default_file, "append"])
-
- def append_to_bbfiles(self, val):
- bbfiles = self.runCommand(["getVariable", "BBFILES", "False"]) or ""
- bbfiles = bbfiles.split()
- if val not in bbfiles:
- self.append_var_in_file("BBFILES", val, "bblayers.conf")
-
- def get_parameters(self):
- # retrieve the parameters from bitbake
- params = {}
- params["core_base"] = self.runCommand(["getVariable", "COREBASE"]) or ""
- params["layer"] = self.runCommand(["getVariable", "BBLAYERS"]) or ""
- params["layers_non_removable"] = self.runCommand(["getVariable", "BBLAYERS_NON_REMOVABLE"]) or ""
- params["dldir"] = self.runCommand(["getVariable", "DL_DIR"]) or ""
- params["machine"] = self.runCommand(["getVariable", "MACHINE"]) or ""
- params["distro"] = self.runCommand(["getVariable", "DISTRO"]) or "defaultsetup"
- params["pclass"] = self.runCommand(["getVariable", "PACKAGE_CLASSES"]) or ""
- params["sstatedir"] = self.runCommand(["getVariable", "SSTATE_DIR"]) or ""
- params["sstatemirror"] = self.runCommand(["getVariable", "SSTATE_MIRRORS"]) or ""
-
- num_threads = self.runCommand(["getCpuCount"])
- if not num_threads:
- num_threads = 1
- max_threads = 65536
- else:
- try:
- num_threads = int(num_threads)
- max_threads = 16 * num_threads
- except:
- num_threads = 1
- max_threads = 65536
- params["max_threads"] = max_threads
-
- bbthread = self.runCommand(["getVariable", "BB_NUMBER_THREADS"])
- if not bbthread:
- bbthread = num_threads
- else:
- try:
- bbthread = int(bbthread)
- except:
- bbthread = num_threads
- params["bbthread"] = bbthread
-
- pmake = self.runCommand(["getVariable", "PARALLEL_MAKE"])
- if not pmake:
- pmake = num_threads
- elif isinstance(pmake, int):
- pass
- else:
- try:
- pmake = int(pmake.lstrip("-j "))
- except:
- pmake = num_threads
- params["pmake"] = "-j %s" % pmake
-
- params["image_addr"] = self.runCommand(["getVariable", "DEPLOY_DIR_IMAGE"]) or ""
-
- image_extra_size = self.runCommand(["getVariable", "IMAGE_ROOTFS_EXTRA_SPACE"])
- if not image_extra_size:
- image_extra_size = 0
- else:
- try:
- image_extra_size = int(image_extra_size)
- except:
- image_extra_size = 0
- params["image_extra_size"] = image_extra_size
-
- image_rootfs_size = self.runCommand(["getVariable", "IMAGE_ROOTFS_SIZE"])
- if not image_rootfs_size:
- image_rootfs_size = 0
- else:
- try:
- image_rootfs_size = int(image_rootfs_size)
- except:
- image_rootfs_size = 0
- params["image_rootfs_size"] = image_rootfs_size
-
- image_overhead_factor = self.runCommand(["getVariable", "IMAGE_OVERHEAD_FACTOR"])
- if not image_overhead_factor:
- image_overhead_factor = 1
- else:
- try:
- image_overhead_factor = float(image_overhead_factor)
- except:
- image_overhead_factor = 1
- params['image_overhead_factor'] = image_overhead_factor
-
- params["incompat_license"] = self._remove_redundant(self.runCommand(["getVariable", "INCOMPATIBLE_LICENSE"]) or "")
- params["sdk_machine"] = self.runCommand(["getVariable", "SDKMACHINE"]) or self.runCommand(["getVariable", "SDK_ARCH"]) or ""
-
- params["image_fstypes"] = self._remove_redundant(self.runCommand(["getVariable", "IMAGE_FSTYPES"]) or "")
-
- params["image_types"] = self._remove_redundant(self.runCommand(["getVariable", "IMAGE_TYPES"]) or "")
-
- params["conf_version"] = self.runCommand(["getVariable", "CONF_VERSION"]) or ""
- params["lconf_version"] = self.runCommand(["getVariable", "LCONF_VERSION"]) or ""
-
- params["runnable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_IMAGE_TYPES"]) or "")
- params["runnable_machine_patterns"] = self._remove_redundant(self.runCommand(["getVariable", "RUNNABLE_MACHINE_PATTERNS"]) or "")
- params["deployable_image_types"] = self._remove_redundant(self.runCommand(["getVariable", "DEPLOYABLE_IMAGE_TYPES"]) or "")
- params["kernel_image_type"] = self.runCommand(["getVariable", "KERNEL_IMAGETYPE"]) or ""
- params["tmpdir"] = self.runCommand(["getVariable", "TMPDIR"]) or ""
- params["distro_version"] = self.runCommand(["getVariable", "DISTRO_VERSION"]) or ""
- params["target_os"] = self.runCommand(["getVariable", "TARGET_OS"]) or ""
- params["target_arch"] = self.runCommand(["getVariable", "TARGET_ARCH"]) or ""
- params["tune_pkgarch"] = self.runCommand(["getVariable", "TUNE_PKGARCH"]) or ""
- params["bb_version"] = self.runCommand(["getVariable", "BB_MIN_VERSION"]) or ""
-
- params["default_task"] = self.runCommand(["getVariable", "BB_DEFAULT_TASK"]) or "build"
-
- params["socks_proxy"] = self.runCommand(["getVariable", "all_proxy"]) or ""
- params["http_proxy"] = self.runCommand(["getVariable", "http_proxy"]) or ""
- params["ftp_proxy"] = self.runCommand(["getVariable", "ftp_proxy"]) or ""
- params["https_proxy"] = self.runCommand(["getVariable", "https_proxy"]) or ""
-
- params["cvs_proxy_host"] = self.runCommand(["getVariable", "CVS_PROXY_HOST"]) or ""
- params["cvs_proxy_port"] = self.runCommand(["getVariable", "CVS_PROXY_PORT"]) or ""
-
- params["image_white_pattern"] = self.runCommand(["getVariable", "BBUI_IMAGE_WHITE_PATTERN"]) or ""
- params["image_black_pattern"] = self.runCommand(["getVariable", "BBUI_IMAGE_BLACK_PATTERN"]) or ""
- return params
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
deleted file mode 100644
index 50df156f4..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
+++ /dev/null
@@ -1,903 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011 Intel Corporation
-#
-# Authored by Joshua Lock <josh@linux.intel.com>
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import gobject
-from bb.ui.crumbs.hobpages import HobPage
-
-#
-# PackageListModel
-#
-class PackageListModel(gtk.ListStore):
- """
- This class defines an gtk.ListStore subclass which will convert the output
- of the bb.event.TargetsTreeGenerated event into a gtk.ListStore whilst also
- providing convenience functions to access gtk.TreeModel subclasses which
- provide filtered views of the data.
- """
-
- (COL_NAME, COL_VER, COL_REV, COL_RNM, COL_SEC, COL_SUM, COL_RDEP, COL_RPROV, COL_SIZE, COL_RCP, COL_BINB, COL_INC, COL_FADE_INC, COL_FONT, COL_FLIST) = range(15)
-
- __gsignals__ = {
- "package-selection-changed" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- }
-
- __toolchain_required_packages__ = ["packagegroup-core-standalone-sdk-target", "packagegroup-core-standalone-sdk-target-dbg"]
-
- def __init__(self):
- self.rprov_pkg = {}
- gtk.ListStore.__init__ (self,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING)
- self.sort_column_id, self.sort_order = PackageListModel.COL_NAME, gtk.SORT_ASCENDING
-
- """
- Find the model path for the item_name
- Returns the path in the model or None
- """
- def find_path_for_item(self, item_name):
- pkg = item_name
- if item_name not in self.pn_path.keys():
- if item_name not in self.rprov_pkg.keys():
- return None
- pkg = self.rprov_pkg[item_name]
- if pkg not in self.pn_path.keys():
- return None
-
- return self.pn_path[pkg]
-
- def find_item_for_path(self, item_path):
- return self[item_path][self.COL_NAME]
-
- """
- Helper function to determine whether an item is an item specified by filter
- """
- def tree_model_filter(self, model, it, filter):
- name = model.get_value(it, self.COL_NAME)
-
- for key in filter.keys():
- if key == self.COL_NAME:
- if filter[key] != 'Search packages by name':
- if name and filter[key] not in name:
- return False
- else:
- if model.get_value(it, key) not in filter[key]:
- return False
- self.filtered_nb += 1
- return True
-
- """
- Create, if required, and return a filtered gtk.TreeModelSort
- containing only the items specified by filter
- """
- def tree_model(self, filter, excluded_items_ahead=False, included_items_ahead=False, search_data=None, initial=False):
- model = self.filter_new()
- self.filtered_nb = 0
- model.set_visible_func(self.tree_model_filter, filter)
-
- sort = gtk.TreeModelSort(model)
- sort.connect ('sort-column-changed', self.sort_column_changed_cb)
- if initial:
- sort.set_sort_column_id(PackageListModel.COL_NAME, gtk.SORT_ASCENDING)
- sort.set_default_sort_func(None)
- elif excluded_items_ahead:
- sort.set_default_sort_func(self.exclude_item_sort_func, search_data)
- elif included_items_ahead:
- sort.set_default_sort_func(self.include_item_sort_func, search_data)
- else:
- if search_data and search_data!='Search recipes by name' and search_data!='Search package groups by name':
- sort.set_default_sort_func(self.sort_func, search_data)
- else:
- sort.set_sort_column_id(self.sort_column_id, self.sort_order)
- sort.set_default_sort_func(None)
-
- sort.set_sort_func(PackageListModel.COL_INC, self.sort_column, PackageListModel.COL_INC)
- sort.set_sort_func(PackageListModel.COL_SIZE, self.sort_column, PackageListModel.COL_SIZE)
- sort.set_sort_func(PackageListModel.COL_BINB, self.sort_binb_column)
- sort.set_sort_func(PackageListModel.COL_RCP, self.sort_column, PackageListModel.COL_RCP)
- return sort
-
- def sort_column_changed_cb (self, data):
- self.sort_column_id, self.sort_order = data.get_sort_column_id ()
-
- def sort_column(self, model, row1, row2, col):
- value1 = model.get_value(row1, col)
- value2 = model.get_value(row2, col)
- if col==PackageListModel.COL_SIZE:
- value1 = HobPage._string_to_size(value1)
- value2 = HobPage._string_to_size(value2)
-
- cmp_res = cmp(value1, value2)
- if cmp_res!=0:
- if col==PackageListModel.COL_INC:
- return -cmp_res
- else:
- return cmp_res
- else:
- name1 = model.get_value(row1, PackageListModel.COL_NAME)
- name2 = model.get_value(row2, PackageListModel.COL_NAME)
- return cmp(name1,name2)
-
- def sort_binb_column(self, model, row1, row2):
- value1 = model.get_value(row1, PackageListModel.COL_BINB)
- value2 = model.get_value(row2, PackageListModel.COL_BINB)
- value1_list = value1.split(', ')
- value2_list = value2.split(', ')
-
- value1 = value1_list[0]
- value2 = value2_list[0]
-
- cmp_res = cmp(value1, value2)
- if cmp_res==0:
- cmp_size = cmp(len(value1_list), len(value2_list))
- if cmp_size==0:
- name1 = model.get_value(row1, PackageListModel.COL_NAME)
- name2 = model.get_value(row2, PackageListModel.COL_NAME)
- return cmp(name1,name2)
- else:
- return cmp_size
- else:
- return cmp_res
-
- def exclude_item_sort_func(self, model, iter1, iter2, user_data=None):
- if user_data:
- val1 = model.get_value(iter1, PackageListModel.COL_NAME)
- val2 = model.get_value(iter2, PackageListModel.COL_NAME)
- return self.cmp_vals(val1, val2, user_data)
- else:
- val1 = model.get_value(iter1, PackageListModel.COL_FADE_INC)
- val2 = model.get_value(iter2, PackageListModel.COL_INC)
- return ((val1 == True) and (val2 == False))
-
- def include_item_sort_func(self, model, iter1, iter2, user_data=None):
- if user_data:
- val1 = model.get_value(iter1, PackageListModel.COL_NAME)
- val2 = model.get_value(iter2, PackageListModel.COL_NAME)
- return self.cmp_vals(val1, val2, user_data)
- else:
- val1 = model.get_value(iter1, PackageListModel.COL_INC)
- val2 = model.get_value(iter2, PackageListModel.COL_INC)
- return ((val1 == False) and (val2 == True))
-
- def sort_func(self, model, iter1, iter2, user_data):
- val1 = model.get_value(iter1, PackageListModel.COL_NAME)
- val2 = model.get_value(iter2, PackageListModel.COL_NAME)
- return self.cmp_vals(val1, val2, user_data)
-
- def cmp_vals(self, val1, val2, user_data):
- if val1 is None or val2 is None:
- return 0
- elif val1.startswith(user_data) and not val2.startswith(user_data):
- return -1
- elif not val1.startswith(user_data) and val2.startswith(user_data):
- return 1
- else:
- return cmp(val1, val2)
-
- def convert_vpath_to_path(self, view_model, view_path):
- # view_model is the model sorted
- # get the path of the model filtered
- filtered_model_path = view_model.convert_path_to_child_path(view_path)
- # get the model filtered
- filtered_model = view_model.get_model()
- # get the path of the original model
- path = filtered_model.convert_path_to_child_path(filtered_model_path)
- return path
-
- def convert_path_to_vpath(self, view_model, path):
- it = view_model.get_iter_first()
- while it:
- name = self.find_item_for_path(path)
- view_name = view_model.get_value(it, PackageListModel.COL_NAME)
- if view_name == name:
- view_path = view_model.get_path(it)
- return view_path
- it = view_model.iter_next(it)
- return None
-
- """
- The populate() function takes as input the data from a
- bb.event.PackageInfo event and populates the package list.
- """
- def populate(self, pkginfolist):
- # First clear the model, in case repopulating
- self.clear()
-
- def getpkgvalue(pkgdict, key, pkgname, defaultval = None):
- value = pkgdict.get('%s_%s' % (key, pkgname), None)
- if not value:
- value = pkgdict.get(key, defaultval)
- return value
-
- for pkginfo in pkginfolist:
- pn = pkginfo['PN']
- pv = pkginfo['PV']
- pr = pkginfo['PR']
- pkg = pkginfo['PKG']
- pkgv = getpkgvalue(pkginfo, 'PKGV', pkg)
- pkgr = getpkgvalue(pkginfo, 'PKGR', pkg)
- # PKGSIZE is artificial, will always be overridden with the package name if present
- pkgsize = int(pkginfo.get('PKGSIZE_%s' % pkg, "0"))
- # PKG_%s is the renamed version
- pkg_rename = pkginfo.get('PKG_%s' % pkg, "")
- # The rest may be overridden or not
- section = getpkgvalue(pkginfo, 'SECTION', pkg, "")
- summary = getpkgvalue(pkginfo, 'SUMMARY', pkg, "")
- rdep = getpkgvalue(pkginfo, 'RDEPENDS', pkg, "")
- rrec = getpkgvalue(pkginfo, 'RRECOMMENDS', pkg, "")
- rprov = getpkgvalue(pkginfo, 'RPROVIDES', pkg, "")
- files_list = getpkgvalue(pkginfo, 'FILES_INFO', pkg, "")
- for i in rprov.split():
- self.rprov_pkg[i] = pkg
-
- recipe = pn + '-' + pv + '-' + pr
-
- allow_empty = getpkgvalue(pkginfo, 'ALLOW_EMPTY', pkg, "")
-
- if pkgsize == 0 and not allow_empty:
- continue
-
- size = HobPage._size_to_string(pkgsize)
- self.set(self.append(), self.COL_NAME, pkg, self.COL_VER, pkgv,
- self.COL_REV, pkgr, self.COL_RNM, pkg_rename,
- self.COL_SEC, section, self.COL_SUM, summary,
- self.COL_RDEP, rdep + ' ' + rrec,
- self.COL_RPROV, rprov, self.COL_SIZE, size,
- self.COL_RCP, recipe, self.COL_BINB, "",
- self.COL_INC, False, self.COL_FONT, '10', self.COL_FLIST, files_list)
-
- self.pn_path = {}
- it = self.get_iter_first()
- while it:
- pn = self.get_value(it, self.COL_NAME)
- path = self.get_path(it)
- self.pn_path[pn] = path
- it = self.iter_next(it)
-
- """
- Update the model, send out the notification.
- """
- def selection_change_notification(self):
- self.emit("package-selection-changed")
-
- """
- Check whether the item at item_path is included or not
- """
- def path_included(self, item_path):
- return self[item_path][self.COL_INC]
-
- """
- Add this item, and any of its dependencies, to the image contents
- """
- def include_item(self, item_path, binb=""):
- if self.path_included(item_path):
- return
-
- item_name = self[item_path][self.COL_NAME]
- item_deps = self[item_path][self.COL_RDEP]
-
- self[item_path][self.COL_INC] = True
-
- item_bin = self[item_path][self.COL_BINB].split(', ')
- if binb and not binb in item_bin:
- item_bin.append(binb)
- self[item_path][self.COL_BINB] = ', '.join(item_bin).lstrip(', ')
-
- if item_deps:
- # Ensure all of the items deps are included and, where appropriate,
- # add this item to their COL_BINB
- for dep in item_deps.split(" "):
- if dep.startswith('('):
- continue
- # If the contents model doesn't already contain dep, add it
- dep_path = self.find_path_for_item(dep)
- if not dep_path:
- continue
- dep_included = self.path_included(dep_path)
-
- if dep_included and not dep in item_bin:
- # don't set the COL_BINB to this item if the target is an
- # item in our own COL_BINB
- dep_bin = self[dep_path][self.COL_BINB].split(', ')
- if not item_name in dep_bin:
- dep_bin.append(item_name)
- self[dep_path][self.COL_BINB] = ', '.join(dep_bin).lstrip(', ')
- elif not dep_included:
- self.include_item(dep_path, binb=item_name)
-
- def exclude_item(self, item_path):
- if not self.path_included(item_path):
- return
-
- self[item_path][self.COL_INC] = False
-
- item_name = self[item_path][self.COL_NAME]
- item_deps = self[item_path][self.COL_RDEP]
- if item_deps:
- for dep in item_deps.split(" "):
- if dep.startswith('('):
- continue
- dep_path = self.find_path_for_item(dep)
- if not dep_path:
- continue
- dep_bin = self[dep_path][self.COL_BINB].split(', ')
- if item_name in dep_bin:
- dep_bin.remove(item_name)
- self[dep_path][self.COL_BINB] = ', '.join(dep_bin).lstrip(', ')
-
- item_bin = self[item_path][self.COL_BINB].split(', ')
- if item_bin:
- for binb in item_bin:
- binb_path = self.find_path_for_item(binb)
- if not binb_path:
- continue
- self.exclude_item(binb_path)
-
- """
- Empty self.contents by setting the include of each entry to None
- """
- def reset(self):
- it = self.get_iter_first()
- while it:
- self.set(it,
- self.COL_INC, False,
- self.COL_BINB, "")
- it = self.iter_next(it)
-
- self.selection_change_notification()
-
- def get_selected_packages(self):
- packagelist = []
-
- it = self.get_iter_first()
- while it:
- if self.get_value(it, self.COL_INC):
- name = self.get_value(it, self.COL_NAME)
- packagelist.append(name)
- it = self.iter_next(it)
-
- return packagelist
-
- def get_user_selected_packages(self):
- packagelist = []
-
- it = self.get_iter_first()
- while it:
- if self.get_value(it, self.COL_INC):
- binb = self.get_value(it, self.COL_BINB)
- if binb == "User Selected":
- name = self.get_value(it, self.COL_NAME)
- packagelist.append(name)
- it = self.iter_next(it)
-
- return packagelist
-
- def get_selected_packages_toolchain(self):
- packagelist = []
-
- it = self.get_iter_first()
- while it:
- if self.get_value(it, self.COL_INC):
- name = self.get_value(it, self.COL_NAME)
- if name.endswith("-dev") or name.endswith("-dbg"):
- packagelist.append(name)
- it = self.iter_next(it)
-
- return list(set(packagelist + self.__toolchain_required_packages__));
-
- """
- Package model may be incomplete, therefore when calling the
- set_selected_packages(), some packages will not be set included.
- Return the un-set packages list.
- """
- def set_selected_packages(self, packagelist, user_selected=False):
- left = []
- binb = 'User Selected' if user_selected else ''
- for pn in packagelist:
- if pn in self.pn_path.keys():
- path = self.pn_path[pn]
- self.include_item(item_path=path, binb=binb)
- else:
- left.append(pn)
-
- self.selection_change_notification()
- return left
-
- """
- Return the selected package size, unit is B.
- """
- def get_packages_size(self):
- packages_size = 0
- it = self.get_iter_first()
- while it:
- if self.get_value(it, self.COL_INC):
- str_size = self.get_value(it, self.COL_SIZE)
- if not str_size:
- continue
-
- packages_size += HobPage._string_to_size(str_size)
-
- it = self.iter_next(it)
- return packages_size
-
- """
- Resync the state of included items to a backup column before performing the fadeout visible effect
- """
- def resync_fadeout_column(self, model_first_iter=None):
- it = model_first_iter
- while it:
- active = self.get_value(it, self.COL_INC)
- self.set(it, self.COL_FADE_INC, active)
- it = self.iter_next(it)
-
-#
-# RecipeListModel
-#
-class RecipeListModel(gtk.ListStore):
- """
- This class defines an gtk.ListStore subclass which will convert the output
- of the bb.event.TargetsTreeGenerated event into a gtk.ListStore whilst also
- providing convenience functions to access gtk.TreeModel subclasses which
- provide filtered views of the data.
- """
- (COL_NAME, COL_DESC, COL_LIC, COL_GROUP, COL_DEPS, COL_BINB, COL_TYPE, COL_INC, COL_IMG, COL_INSTALL, COL_PN, COL_FADE_INC, COL_SUMMARY, COL_VERSION,
- COL_REVISION, COL_HOMEPAGE, COL_BUGTRACKER, COL_FILE) = range(18)
-
- __custom_image__ = "Start with an empty image recipe"
-
- __gsignals__ = {
- "recipe-selection-changed" : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- }
-
- """
- """
- def __init__(self):
- gtk.ListStore.__init__ (self,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_BOOLEAN,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING,
- gobject.TYPE_STRING)
- self.sort_column_id, self.sort_order = RecipeListModel.COL_NAME, gtk.SORT_ASCENDING
-
- """
- Find the model path for the item_name
- Returns the path in the model or None
- """
- def find_path_for_item(self, item_name):
- if self.non_target_name(item_name) or item_name not in self.pn_path.keys():
- return None
- else:
- return self.pn_path[item_name]
-
- def find_item_for_path(self, item_path):
- return self[item_path][self.COL_NAME]
-
- """
- Helper method to determine whether name is a target pn
- """
- def non_target_name(self, name):
- if name and ('-native' in name):
- return True
- return False
-
- """
- Helper function to determine whether an item is an item specified by filter
- """
- def tree_model_filter(self, model, it, filter):
- name = model.get_value(it, self.COL_NAME)
- if self.non_target_name(name):
- return False
-
- for key in filter.keys():
- if key == self.COL_NAME:
- if filter[key] != 'Search recipes by name' and filter[key] != 'Search package groups by name':
- if filter[key] not in name:
- return False
- else:
- if model.get_value(it, key) not in filter[key]:
- return False
- self.filtered_nb += 1
-
- return True
-
- def exclude_item_sort_func(self, model, iter1, iter2, user_data=None):
- if user_data:
- val1 = model.get_value(iter1, RecipeListModel.COL_NAME)
- val2 = model.get_value(iter2, RecipeListModel.COL_NAME)
- return self.cmp_vals(val1, val2, user_data)
- else:
- val1 = model.get_value(iter1, RecipeListModel.COL_FADE_INC)
- val2 = model.get_value(iter2, RecipeListModel.COL_INC)
- return ((val1 == True) and (val2 == False))
-
- def include_item_sort_func(self, model, iter1, iter2, user_data=None):
- if user_data:
- val1 = model.get_value(iter1, RecipeListModel.COL_NAME)
- val2 = model.get_value(iter2, RecipeListModel.COL_NAME)
- return self.cmp_vals(val1, val2, user_data)
- else:
- val1 = model.get_value(iter1, RecipeListModel.COL_INC)
- val2 = model.get_value(iter2, RecipeListModel.COL_INC)
- return ((val1 == False) and (val2 == True))
-
- def sort_func(self, model, iter1, iter2, user_data):
- val1 = model.get_value(iter1, RecipeListModel.COL_NAME)
- val2 = model.get_value(iter2, RecipeListModel.COL_NAME)
- return self.cmp_vals(val1, val2, user_data)
-
- def cmp_vals(self, val1, val2, user_data):
- if val1 is None or val2 is None:
- return 0
- elif val1.startswith(user_data) and not val2.startswith(user_data):
- return -1
- elif not val1.startswith(user_data) and val2.startswith(user_data):
- return 1
- else:
- return cmp(val1, val2)
-
- """
- Create, if required, and return a filtered gtk.TreeModelSort
- containing only the items specified by filter
- """
- def tree_model(self, filter, excluded_items_ahead=False, included_items_ahead=False, search_data=None, initial=False):
- model = self.filter_new()
- self.filtered_nb = 0
- model.set_visible_func(self.tree_model_filter, filter)
-
- sort = gtk.TreeModelSort(model)
- sort.connect ('sort-column-changed', self.sort_column_changed_cb)
- if initial:
- sort.set_sort_column_id(RecipeListModel.COL_NAME, gtk.SORT_ASCENDING)
- sort.set_default_sort_func(None)
- elif excluded_items_ahead:
- sort.set_default_sort_func(self.exclude_item_sort_func, search_data)
- elif included_items_ahead:
- sort.set_default_sort_func(self.include_item_sort_func, search_data)
- else:
- if search_data and search_data!='Search recipes by name' and search_data!='Search package groups by name':
- sort.set_default_sort_func(self.sort_func, search_data)
- else:
- sort.set_sort_column_id(self.sort_column_id, self.sort_order)
- sort.set_default_sort_func(None)
-
- sort.set_sort_func(RecipeListModel.COL_INC, self.sort_column, RecipeListModel.COL_INC)
- sort.set_sort_func(RecipeListModel.COL_GROUP, self.sort_column, RecipeListModel.COL_GROUP)
- sort.set_sort_func(RecipeListModel.COL_BINB, self.sort_binb_column)
- sort.set_sort_func(RecipeListModel.COL_LIC, self.sort_column, RecipeListModel.COL_LIC)
- return sort
-
- def sort_column_changed_cb (self, data):
- self.sort_column_id, self.sort_order = data.get_sort_column_id ()
-
- def sort_column(self, model, row1, row2, col):
- value1 = model.get_value(row1, col)
- value2 = model.get_value(row2, col)
- cmp_res = cmp(value1, value2)
- if cmp_res!=0:
- if col==RecipeListModel.COL_INC:
- return -cmp_res
- else:
- return cmp_res
- else:
- name1 = model.get_value(row1, RecipeListModel.COL_NAME)
- name2 = model.get_value(row2, RecipeListModel.COL_NAME)
- return cmp(name1,name2)
-
- def sort_binb_column(self, model, row1, row2):
- value1 = model.get_value(row1, RecipeListModel.COL_BINB)
- value2 = model.get_value(row2, RecipeListModel.COL_BINB)
- value1_list = value1.split(', ')
- value2_list = value2.split(', ')
-
- value1 = value1_list[0]
- value2 = value2_list[0]
-
- cmp_res = cmp(value1, value2)
- if cmp_res==0:
- cmp_size = cmp(len(value1_list), len(value2_list))
- if cmp_size==0:
- name1 = model.get_value(row1, RecipeListModel.COL_NAME)
- name2 = model.get_value(row2, RecipeListModel.COL_NAME)
- return cmp(name1,name2)
- else:
- return cmp_size
- else:
- return cmp_res
-
- def convert_vpath_to_path(self, view_model, view_path):
- filtered_model_path = view_model.convert_path_to_child_path(view_path)
- filtered_model = view_model.get_model()
-
- # get the path of the original model
- path = filtered_model.convert_path_to_child_path(filtered_model_path)
- return path
-
- def convert_path_to_vpath(self, view_model, path):
- it = view_model.get_iter_first()
- while it:
- name = self.find_item_for_path(path)
- view_name = view_model.get_value(it, RecipeListModel.COL_NAME)
- if view_name == name:
- view_path = view_model.get_path(it)
- return view_path
- it = view_model.iter_next(it)
- return None
-
- """
- The populate() function takes as input the data from a
- bb.event.TargetsTreeGenerated event and populates the RecipeList.
- """
- def populate(self, event_model):
- # First clear the model, in case repopulating
- self.clear()
-
- # dummy image for prompt
- self.set_in_list(self.__custom_image__, "Use 'Edit image recipe' to customize recipes and packages " \
- "to be included in your image ")
-
- for item in event_model["pn"]:
- name = item
- desc = event_model["pn"][item]["description"]
- lic = event_model["pn"][item]["license"]
- group = event_model["pn"][item]["section"]
- inherits = event_model["pn"][item]["inherits"]
- summary = event_model["pn"][item]["summary"]
- version = event_model["pn"][item]["version"]
- revision = event_model["pn"][item]["prevision"]
- homepage = event_model["pn"][item]["homepage"]
- bugtracker = event_model["pn"][item]["bugtracker"]
- filename = event_model["pn"][item]["filename"]
- install = []
-
- depends = event_model["depends"].get(item, []) + event_model["rdepends-pn"].get(item, [])
-
- if ('packagegroup.bbclass' in " ".join(inherits)):
- atype = 'packagegroup'
- elif ('/image.bbclass' in " ".join(inherits)):
- if "edited" not in name:
- atype = 'image'
- install = event_model["rdepends-pkg"].get(item, []) + event_model["rrecs-pkg"].get(item, [])
- elif ('meta-' in name):
- atype = 'toolchain'
- elif (name == 'dummy-image' or name == 'dummy-toolchain'):
- atype = 'dummy'
- else:
- atype = 'recipe'
-
- self.set(self.append(), self.COL_NAME, item, self.COL_DESC, desc,
- self.COL_LIC, lic, self.COL_GROUP, group,
- self.COL_DEPS, " ".join(depends), self.COL_BINB, "",
- self.COL_TYPE, atype, self.COL_INC, False,
- self.COL_IMG, False, self.COL_INSTALL, " ".join(install), self.COL_PN, item,
- self.COL_SUMMARY, summary, self.COL_VERSION, version, self.COL_REVISION, revision,
- self.COL_HOMEPAGE, homepage, self.COL_BUGTRACKER, bugtracker,
- self.COL_FILE, filename)
-
- self.pn_path = {}
- it = self.get_iter_first()
- while it:
- pn = self.get_value(it, self.COL_NAME)
- path = self.get_path(it)
- self.pn_path[pn] = path
- it = self.iter_next(it)
-
- def set_in_list(self, item, desc):
- self.set(self.append(), self.COL_NAME, item,
- self.COL_DESC, desc,
- self.COL_LIC, "", self.COL_GROUP, "",
- self.COL_DEPS, "", self.COL_BINB, "",
- self.COL_TYPE, "image", self.COL_INC, False,
- self.COL_IMG, False, self.COL_INSTALL, "", self.COL_PN, item,
- self.COL_SUMMARY, "", self.COL_VERSION, "", self.COL_REVISION, "",
- self.COL_HOMEPAGE, "", self.COL_BUGTRACKER, "")
- self.pn_path = {}
- it = self.get_iter_first()
- while it:
- pn = self.get_value(it, self.COL_NAME)
- path = self.get_path(it)
- self.pn_path[pn] = path
- it = self.iter_next(it)
-
- """
- Update the model, send out the notification.
- """
- def selection_change_notification(self):
- self.emit("recipe-selection-changed")
-
- def path_included(self, item_path):
- return self[item_path][self.COL_INC]
-
- """
- Add this item, and any of its dependencies, to the image contents
- """
- def include_item(self, item_path, binb="", image_contents=False):
- if self.path_included(item_path):
- return
-
- item_name = self[item_path][self.COL_NAME]
- item_deps = self[item_path][self.COL_DEPS]
-
- self[item_path][self.COL_INC] = True
-
- item_bin = self[item_path][self.COL_BINB].split(', ')
- if binb and not binb in item_bin:
- item_bin.append(binb)
- self[item_path][self.COL_BINB] = ', '.join(item_bin).lstrip(', ')
-
- # We want to do some magic with things which are brought in by the
- # base image so tag them as so
- if image_contents:
- self[item_path][self.COL_IMG] = True
-
- if item_deps:
- # Ensure all of the items deps are included and, where appropriate,
- # add this item to their COL_BINB
- for dep in item_deps.split(" "):
- # If the contents model doesn't already contain dep, add it
- dep_path = self.find_path_for_item(dep)
- if not dep_path:
- continue
- dep_included = self.path_included(dep_path)
-
- if dep_included and not dep in item_bin:
- # don't set the COL_BINB to this item if the target is an
- # item in our own COL_BINB
- dep_bin = self[dep_path][self.COL_BINB].split(', ')
- if not item_name in dep_bin:
- dep_bin.append(item_name)
- self[dep_path][self.COL_BINB] = ', '.join(dep_bin).lstrip(', ')
- elif not dep_included:
- self.include_item(dep_path, binb=item_name, image_contents=image_contents)
- dep_bin = self[item_path][self.COL_BINB].split(', ')
- if self[item_path][self.COL_NAME] in dep_bin:
- dep_bin.remove(self[item_path][self.COL_NAME])
- self[item_path][self.COL_BINB] = ', '.join(dep_bin).lstrip(', ')
-
- def exclude_item(self, item_path):
- if not self.path_included(item_path):
- return
-
- self[item_path][self.COL_INC] = False
-
- item_name = self[item_path][self.COL_NAME]
- item_deps = self[item_path][self.COL_DEPS]
- if item_deps:
- for dep in item_deps.split(" "):
- dep_path = self.find_path_for_item(dep)
- if not dep_path:
- continue
- dep_bin = self[dep_path][self.COL_BINB].split(', ')
- if item_name in dep_bin:
- dep_bin.remove(item_name)
- self[dep_path][self.COL_BINB] = ', '.join(dep_bin).lstrip(', ')
-
- item_bin = self[item_path][self.COL_BINB].split(', ')
- if item_bin:
- for binb in item_bin:
- binb_path = self.find_path_for_item(binb)
- if not binb_path:
- continue
- self.exclude_item(binb_path)
-
- def reset(self):
- it = self.get_iter_first()
- while it:
- self.set(it,
- self.COL_INC, False,
- self.COL_BINB, "",
- self.COL_IMG, False)
- it = self.iter_next(it)
-
- self.selection_change_notification()
-
- """
- Returns two lists. One of user selected recipes and the other containing
- all selected recipes
- """
- def get_selected_recipes(self):
- allrecipes = []
- userrecipes = []
-
- it = self.get_iter_first()
- while it:
- if self.get_value(it, self.COL_INC):
- name = self.get_value(it, self.COL_PN)
- type = self.get_value(it, self.COL_TYPE)
- if type != "image":
- allrecipes.append(name)
- sel = "User Selected" in self.get_value(it, self.COL_BINB)
- if sel:
- userrecipes.append(name)
- it = self.iter_next(it)
-
- return list(set(userrecipes)), list(set(allrecipes))
-
- def set_selected_recipes(self, recipelist):
- for pn in recipelist:
- if pn in self.pn_path.keys():
- path = self.pn_path[pn]
- self.include_item(item_path=path,
- binb="User Selected")
- self.selection_change_notification()
-
- def get_selected_image(self):
- it = self.get_iter_first()
- while it:
- if self.get_value(it, self.COL_INC):
- name = self.get_value(it, self.COL_PN)
- type = self.get_value(it, self.COL_TYPE)
- if type == "image":
- sel = "User Selected" in self.get_value(it, self.COL_BINB)
- if sel:
- return name
- it = self.iter_next(it)
- return None
-
- def set_selected_image(self, img):
- if not img:
- return
- self.reset()
- path = self.find_path_for_item(img)
- self.include_item(item_path=path,
- binb="User Selected",
- image_contents=True)
- self.selection_change_notification()
-
- def set_custom_image_version(self, version):
- self.custom_image_version = version
-
- def get_custom_image_version(self):
- return self.custom_image_version
-
- def is_custom_image(self):
- return self.get_selected_image() == self.__custom_image__
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hobpages.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hobpages.py
deleted file mode 100755
index 0fd3598c3..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/hobpages.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2012 Intel Corporation
-#
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import hwc
-
-#
-# HobPage: the super class for all Hob-related pages
-#
-class HobPage (gtk.VBox):
-
- def __init__(self, builder, title = None):
- super(HobPage, self).__init__(False, 0)
- self.builder = builder
- self.builder_width, self.builder_height = self.builder.size_request()
-
- if not title:
- self.title = "Hob -- Image Creator"
- else:
- self.title = title
- self.title_label = gtk.Label()
-
- self.box_group_area = gtk.VBox(False, 12)
- self.box_group_area.set_size_request(self.builder_width - 73 - 73, self.builder_height - 88 - 15 - 15)
- self.group_align = gtk.Alignment(xalign = 0, yalign=0.5, xscale=1, yscale=1)
- self.group_align.set_padding(15, 15, 73, 73)
- self.group_align.add(self.box_group_area)
- self.box_group_area.set_homogeneous(False)
-
- def set_title(self, title):
- self.title = title
- self.title_label.set_markup("<span size='x-large'>%s</span>" % self.title)
-
- def add_onto_top_bar(self, widget = None, padding = 0):
- # the top button occupies 1/7 of the page height
- # setup an event box
- eventbox = gtk.EventBox()
- style = eventbox.get_style().copy()
- style.bg[gtk.STATE_NORMAL] = eventbox.get_colormap().alloc_color(HobColors.LIGHT_GRAY, False, False)
- eventbox.set_style(style)
- eventbox.set_size_request(-1, 88)
-
- hbox = gtk.HBox()
-
- self.title_label = gtk.Label()
- self.title_label.set_markup("<span size='x-large'>%s</span>" % self.title)
- hbox.pack_start(self.title_label, expand=False, fill=False, padding=20)
-
- if widget:
- # add the widget in the event box
- hbox.pack_end(widget, expand=False, fill=False, padding=padding)
- eventbox.add(hbox)
-
- return eventbox
-
- def span_tag(self, size="medium", weight="normal", forground="#1c1c1c"):
- span_tag = "weight='%s' foreground='%s' size='%s'" % (weight, forground, size)
- return span_tag
-
- def append_toolbar_button(self, toolbar, buttonname, icon_disp, icon_hovor, tip, cb):
- # Create a button and append it on the toolbar according to button name
- icon = gtk.Image()
- icon_display = icon_disp
- icon_hover = icon_hovor
- pix_buffer = gtk.gdk.pixbuf_new_from_file(icon_display)
- icon.set_from_pixbuf(pix_buffer)
- tip_text = tip
- button = toolbar.append_item(buttonname, tip, None, icon, cb)
- return button
-
- @staticmethod
- def _size_to_string(size):
- try:
- if not size:
- size_str = "0 B"
- else:
- if len(str(int(size))) > 6:
- size_str = '%.1f' % (size*1.0/(1024*1024)) + ' MB'
- elif len(str(int(size))) > 3:
- size_str = '%.1f' % (size*1.0/1024) + ' KB'
- else:
- size_str = str(size) + ' B'
- except:
- size_str = "0 B"
- return size_str
-
- @staticmethod
- def _string_to_size(str_size):
- try:
- if not str_size:
- size = 0
- else:
- unit = str_size.split()
- if len(unit) > 1:
- if unit[1] == 'MB':
- size = float(unit[0])*1024*1024
- elif unit[1] == 'KB':
- size = float(unit[0])*1024
- elif unit[1] == 'B':
- size = float(unit[0])
- else:
- size = 0
- else:
- size = float(unit[0])
- except:
- size = 0
- return size
-
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py
deleted file mode 100644
index 2766bea8c..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py
+++ /dev/null
@@ -1,561 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2012 Intel Corporation
-#
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import glib
-import re
-from bb.ui.crumbs.progressbar import HobProgressBar
-from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import hic, HobImageButton, HobInfoButton, HobAltButton, HobButton
-from bb.ui.crumbs.hoblistmodel import RecipeListModel
-from bb.ui.crumbs.hobpages import HobPage
-from bb.ui.crumbs.hig.retrieveimagedialog import RetrieveImageDialog
-
-#
-# ImageConfigurationPage
-#
-class ImageConfigurationPage (HobPage):
-
- __dummy_machine__ = "--select a machine--"
- __dummy_image__ = "--select an image recipe--"
- __custom_image__ = "Select from my image recipes"
-
- def __init__(self, builder):
- super(ImageConfigurationPage, self).__init__(builder, "Image configuration")
-
- self.image_combo_id = None
- # we use machine_combo_changed_by_manual to identify the machine is changed by code
- # or by manual. If by manual, all user's recipe selection and package selection are
- # cleared.
- self.machine_combo_changed_by_manual = True
- self.stopping = False
- self.warning_shift = 0
- self.custom_image_selected = None
- self.create_visual_elements()
-
- def create_visual_elements(self):
- # create visual elements
- self.toolbar = gtk.Toolbar()
- self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
- self.toolbar.set_style(gtk.TOOLBAR_BOTH)
-
- my_images_button = self.append_toolbar_button(self.toolbar,
- "Images",
- hic.ICON_IMAGES_DISPLAY_FILE,
- hic.ICON_IMAGES_HOVER_FILE,
- "Open previously built images",
- self.my_images_button_clicked_cb)
- settings_button = self.append_toolbar_button(self.toolbar,
- "Settings",
- hic.ICON_SETTINGS_DISPLAY_FILE,
- hic.ICON_SETTINGS_HOVER_FILE,
- "View additional build settings",
- self.settings_button_clicked_cb)
-
- self.config_top_button = self.add_onto_top_bar(self.toolbar)
-
- self.gtable = gtk.Table(40, 40, True)
- self.create_config_machine()
- self.create_config_baseimg()
- self.config_build_button = self.create_config_build_button()
-
- def _remove_all_widget(self):
- children = self.gtable.get_children() or []
- for child in children:
- self.gtable.remove(child)
- children = self.box_group_area.get_children() or []
- for child in children:
- self.box_group_area.remove(child)
- children = self.get_children() or []
- for child in children:
- self.remove(child)
-
- def _pack_components(self, pack_config_build_button = False):
- self._remove_all_widget()
- self.pack_start(self.config_top_button, expand=False, fill=False)
- self.pack_start(self.group_align, expand=True, fill=True)
-
- self.box_group_area.pack_start(self.gtable, expand=True, fill=True)
- if pack_config_build_button:
- self.box_group_area.pack_end(self.config_build_button, expand=False, fill=False)
- else:
- box = gtk.HBox(False, 6)
- box.show()
- subbox = gtk.HBox(False, 0)
- subbox.set_size_request(205, 49)
- subbox.show()
- box.add(subbox)
- self.box_group_area.pack_end(box, False, False)
-
- def show_machine(self):
- self.progress_bar.reset()
- self._pack_components(pack_config_build_button = False)
- self.set_config_machine_layout(show_progress_bar = False)
- self.show_all()
-
- def update_progress_bar(self, title, fraction, status=None):
- if self.stopping == False:
- self.progress_bar.update(fraction)
- self.progress_bar.set_text(title)
- self.progress_bar.set_rcstyle(status)
-
- def show_info_populating(self):
- self._pack_components(pack_config_build_button = False)
- self.set_config_machine_layout(show_progress_bar = True)
- self.show_all()
-
- def show_info_populated(self):
- self.progress_bar.reset()
- self._pack_components(pack_config_build_button = False)
- self.set_config_machine_layout(show_progress_bar = False)
- self.set_config_baseimg_layout()
- self.show_all()
-
- def show_baseimg_selected(self):
- self.progress_bar.reset()
- self._pack_components(pack_config_build_button = True)
- self.set_config_machine_layout(show_progress_bar = False)
- self.set_config_baseimg_layout()
- self.show_all()
- if self.builder.recipe_model.get_selected_image() == self.builder.recipe_model.__custom_image__:
- self.just_bake_button.hide()
-
- def add_warnings_bar(self):
- #create the warnings bar shown when recipes parsing generates warnings
- color = HobColors.KHAKI
- warnings_bar = gtk.EventBox()
- warnings_bar.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
- warnings_bar.set_flags(gtk.CAN_DEFAULT)
- warnings_bar.grab_default()
-
- build_stop_tab = gtk.Table(10, 20, True)
- warnings_bar.add(build_stop_tab)
-
- icon = gtk.Image()
- icon_pix_buffer = gtk.gdk.pixbuf_new_from_file(hic.ICON_INDI_ALERT_FILE)
- icon.set_from_pixbuf(icon_pix_buffer)
- build_stop_tab.attach(icon, 0, 2, 0, 10)
-
- label = gtk.Label()
- label.set_alignment(0.0, 0.5)
- warnings_nb = len(self.builder.parsing_warnings)
- if warnings_nb == 1:
- label.set_markup("<span size='x-large'><b>1 recipe parsing warning</b></span>")
- else:
- label.set_markup("<span size='x-large'><b>%s recipe parsing warnings</b></span>" % warnings_nb)
- build_stop_tab.attach(label, 2, 12, 0, 10)
-
- view_warnings_button = HobButton("View warnings")
- view_warnings_button.connect('clicked', self.view_warnings_button_clicked_cb)
- build_stop_tab.attach(view_warnings_button, 15, 19, 1, 9)
-
- return warnings_bar
-
- def disable_warnings_bar(self):
- if self.builder.parsing_warnings:
- if hasattr(self, 'warnings_bar'):
- self.warnings_bar.hide_all()
- self.builder.parsing_warnings = []
-
- def create_config_machine(self):
- self.machine_title = gtk.Label()
- self.machine_title.set_alignment(0.0, 0.5)
- mark = "<span %s>Select a machine</span>" % self.span_tag('x-large', 'bold')
- self.machine_title.set_markup(mark)
-
- self.machine_title_desc = gtk.Label()
- self.machine_title_desc.set_alignment(0.0, 0.5)
- mark = ("<span %s>Your selection is the profile of the target machine for which you"
- " are building the image.\n</span>") % (self.span_tag('medium'))
- self.machine_title_desc.set_markup(mark)
-
- self.machine_combo = gtk.combo_box_new_text()
- self.machine_combo.connect("changed", self.machine_combo_changed_cb)
-
- icon_file = hic.ICON_LAYERS_DISPLAY_FILE
- hover_file = hic.ICON_LAYERS_HOVER_FILE
- self.layer_button = HobImageButton("Layers", "Add support for machines, software, etc.",
- icon_file, hover_file)
- self.layer_button.connect("clicked", self.layer_button_clicked_cb)
-
- markup = "Layers are a powerful mechanism to extend the Yocto Project "
- markup += "with your own functionality.\n"
- markup += "For more on layers, check the <a href=\""
- markup += "http://www.yoctoproject.org/docs/current/dev-manual/"
- markup += "dev-manual.html#understanding-and-using-layers\">reference manual</a>."
- self.layer_info_icon = HobInfoButton("<b>Layers</b>" + "*" + markup, self.get_parent())
- self.progress_bar = HobProgressBar()
- self.stop_button = HobAltButton("Stop")
- self.stop_button.connect("clicked", self.stop_button_clicked_cb)
- self.machine_separator = gtk.HSeparator()
-
- def set_config_machine_layout(self, show_progress_bar = False):
- self.gtable.attach(self.machine_title, 0, 40, 0, 4)
- self.gtable.attach(self.machine_title_desc, 0, 40, 4, 6)
- self.gtable.attach(self.machine_combo, 0, 12, 7, 10)
- self.gtable.attach(self.layer_button, 14, 36, 7, 12)
- self.gtable.attach(self.layer_info_icon, 36, 40, 7, 11)
- if show_progress_bar:
- #self.gtable.attach(self.progress_box, 0, 40, 15, 18)
- self.gtable.attach(self.progress_bar, 0, 37, 15, 18)
- self.gtable.attach(self.stop_button, 37, 40, 15, 18, 0, 0)
- if self.builder.parsing_warnings:
- self.warnings_bar = self.add_warnings_bar()
- self.gtable.attach(self.warnings_bar, 0, 40, 14, 18)
- self.warning_shift = 4
- else:
- self.warning_shift = 0
- self.gtable.attach(self.machine_separator, 0, 40, 13, 14)
-
- def create_config_baseimg(self):
- self.image_title = gtk.Label()
- self.image_title.set_alignment(0, 1.0)
- mark = "<span %s>Select an image recipe</span>" % self.span_tag('x-large', 'bold')
- self.image_title.set_markup(mark)
-
- self.image_title_desc = gtk.Label()
- self.image_title_desc.set_alignment(0, 0.5)
-
- mark = ("<span %s>Image recipes are a starting point for the type of image you want. "
- "You can build them as \n"
- "they are or edit them to suit your needs.\n</span>") % self.span_tag('medium')
- self.image_title_desc.set_markup(mark)
-
- self.image_combo = gtk.combo_box_new_text()
- self.image_combo.set_row_separator_func(self.combo_separator_func, None)
- self.image_combo_id = self.image_combo.connect("changed", self.image_combo_changed_cb)
-
- self.image_desc = gtk.Label()
- self.image_desc.set_alignment(0.0, 0.5)
- self.image_desc.set_size_request(256, -1)
- self.image_desc.set_justify(gtk.JUSTIFY_LEFT)
- self.image_desc.set_line_wrap(True)
-
- # button to view recipes
- icon_file = hic.ICON_RCIPE_DISPLAY_FILE
- hover_file = hic.ICON_RCIPE_HOVER_FILE
- self.view_adv_configuration_button = HobImageButton("Advanced configuration",
- "Select image types, package formats, etc",
- icon_file, hover_file)
- self.view_adv_configuration_button.connect("clicked", self.view_adv_configuration_button_clicked_cb)
-
- self.image_separator = gtk.HSeparator()
-
- def combo_separator_func(self, model, iter, user_data):
- name = model.get_value(iter, 0)
- if name == "--Separator--":
- return True
-
- def set_config_baseimg_layout(self):
- self.gtable.attach(self.image_title, 0, 40, 15+self.warning_shift, 17+self.warning_shift)
- self.gtable.attach(self.image_title_desc, 0, 40, 18+self.warning_shift, 22+self.warning_shift)
- self.gtable.attach(self.image_combo, 0, 12, 23+self.warning_shift, 26+self.warning_shift)
- self.gtable.attach(self.image_desc, 0, 12, 27+self.warning_shift, 33+self.warning_shift)
- self.gtable.attach(self.view_adv_configuration_button, 14, 36, 23+self.warning_shift, 28+self.warning_shift)
- self.gtable.attach(self.image_separator, 0, 40, 35+self.warning_shift, 36+self.warning_shift)
-
- def create_config_build_button(self):
- # Create the "Build packages" and "Build image" buttons at the bottom
- button_box = gtk.HBox(False, 6)
-
- # create button "Build image"
- self.just_bake_button = HobButton("Build image")
- self.just_bake_button.set_tooltip_text("Build the image recipe as it is")
- self.just_bake_button.connect("clicked", self.just_bake_button_clicked_cb)
- button_box.pack_end(self.just_bake_button, expand=False, fill=False)
-
- # create button "Edit image recipe"
- self.edit_image_button = HobAltButton("Edit image recipe")
- self.edit_image_button.set_tooltip_text("Customize the recipes and packages to be included in your image")
- self.edit_image_button.connect("clicked", self.edit_image_button_clicked_cb)
- button_box.pack_end(self.edit_image_button, expand=False, fill=False)
-
- return button_box
-
- def stop_button_clicked_cb(self, button):
- self.stopping = True
- self.progress_bar.set_text("Stopping recipe parsing")
- self.progress_bar.set_rcstyle("stop")
- self.builder.cancel_parse_sync()
-
- def view_warnings_button_clicked_cb(self, button):
- self.builder.show_warning_dialog()
-
- def machine_combo_changed_idle_cb(self):
- self.builder.window.set_cursor(None)
-
- def machine_combo_changed_cb(self, machine_combo):
- self.stopping = False
- self.builder.parsing_warnings = []
- combo_item = machine_combo.get_active_text()
- if not combo_item or combo_item == self.__dummy_machine__:
- return
-
- self.builder.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
- self.builder.wait(0.1) #wait for combo and cursor to update
-
- # remove __dummy_machine__ item from the store list after first user selection
- # because it is no longer valid
- combo_store = machine_combo.get_model()
- if len(combo_store) and (combo_store[0][0] == self.__dummy_machine__):
- machine_combo.remove_text(0)
-
- self.builder.configuration.curr_mach = combo_item
- if self.machine_combo_changed_by_manual:
- self.builder.configuration.clear_selection()
- # reset machine_combo_changed_by_manual
- self.machine_combo_changed_by_manual = True
-
- self.builder.configuration.selected_image = None
-
- # Do reparse recipes
- self.builder.populate_recipe_package_info_async()
-
- glib.idle_add(self.machine_combo_changed_idle_cb)
-
- def update_machine_combo(self):
- self.disable_warnings_bar()
- all_machines = [self.__dummy_machine__] + self.builder.parameters.all_machines
-
- model = self.machine_combo.get_model()
- model.clear()
- for machine in all_machines:
- self.machine_combo.append_text(machine)
- self.machine_combo.set_active(0)
-
- def switch_machine_combo(self):
- self.disable_warnings_bar()
- self.machine_combo_changed_by_manual = False
- model = self.machine_combo.get_model()
- active = 0
- while active < len(model):
- if model[active][0] == self.builder.configuration.curr_mach:
- self.machine_combo.set_active(active)
- return
- active += 1
-
- if model[0][0] != self.__dummy_machine__:
- self.machine_combo.insert_text(0, self.__dummy_machine__)
-
- self.machine_combo.set_active(0)
-
- def update_image_desc(self):
- desc = ""
- selected_image = self.image_combo.get_active_text()
- if selected_image and selected_image in self.builder.recipe_model.pn_path.keys():
- image_path = self.builder.recipe_model.pn_path[selected_image]
- image_iter = self.builder.recipe_model.get_iter(image_path)
- desc = self.builder.recipe_model.get_value(image_iter, self.builder.recipe_model.COL_DESC)
-
- mark = ("<span %s>%s</span>\n") % (self.span_tag('small'), desc)
- self.image_desc.set_markup(mark)
-
- def image_combo_changed_idle_cb(self, selected_image, selected_recipes, selected_packages):
- self.builder.update_recipe_model(selected_image, selected_recipes)
- self.builder.update_package_model(selected_packages)
- self.builder.window_sensitive(True)
-
- def image_combo_changed_cb(self, combo):
- self.builder.window_sensitive(False)
- selected_image = self.image_combo.get_active_text()
- if selected_image == self.__custom_image__:
- topdir = self.builder.get_topdir()
- images_dir = topdir + "/recipes/images/custom/"
- self.builder.ensure_dir(images_dir)
-
- dialog = RetrieveImageDialog(images_dir, "Select from my image recipes",
- self.builder, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
- response = dialog.run()
- if response == gtk.RESPONSE_OK:
- image_name = dialog.get_filename()
- head, tail = os.path.split(image_name)
- selected_image = os.path.splitext(tail)[0]
- self.custom_image_selected = selected_image
- self.update_image_combo(self.builder.recipe_model, selected_image)
- else:
- selected_image = self.__dummy_image__
- self.update_image_combo(self.builder.recipe_model, None)
- dialog.destroy()
- else:
- if self.custom_image_selected:
- self.custom_image_selected = None
- self.update_image_combo(self.builder.recipe_model, selected_image)
-
- if not selected_image or (selected_image == self.__dummy_image__):
- self.builder.window_sensitive(True)
- self.just_bake_button.hide()
- self.edit_image_button.hide()
- return
-
- # remove __dummy_image__ item from the store list after first user selection
- # because it is no longer valid
- combo_store = combo.get_model()
- if len(combo_store) and (combo_store[0][0] == self.__dummy_image__):
- combo.remove_text(0)
-
- self.builder.customized = False
-
- selected_recipes = []
-
- image_path = self.builder.recipe_model.pn_path[selected_image]
- image_iter = self.builder.recipe_model.get_iter(image_path)
- selected_packages = self.builder.recipe_model.get_value(image_iter, self.builder.recipe_model.COL_INSTALL).split()
- self.update_image_desc()
-
- self.builder.recipe_model.reset()
- self.builder.package_model.reset()
-
- self.show_baseimg_selected()
-
- if selected_image == self.builder.recipe_model.__custom_image__:
- self.just_bake_button.hide()
-
- glib.idle_add(self.image_combo_changed_idle_cb, selected_image, selected_recipes, selected_packages)
-
- def _image_combo_connect_signal(self):
- if not self.image_combo_id:
- self.image_combo_id = self.image_combo.connect("changed", self.image_combo_changed_cb)
-
- def _image_combo_disconnect_signal(self):
- if self.image_combo_id:
- self.image_combo.disconnect(self.image_combo_id)
- self.image_combo_id = None
-
- def update_image_combo(self, recipe_model, selected_image):
- # Update the image combo according to the images in the recipe_model
- # populate image combo
- filter = {RecipeListModel.COL_TYPE : ['image']}
- image_model = recipe_model.tree_model(filter)
- image_model.set_sort_column_id(recipe_model.COL_NAME, gtk.SORT_ASCENDING)
- active = 0
- cnt = 0
-
- white_pattern = []
- if self.builder.parameters.image_white_pattern:
- for i in self.builder.parameters.image_white_pattern.split():
- white_pattern.append(re.compile(i))
-
- black_pattern = []
- if self.builder.parameters.image_black_pattern:
- for i in self.builder.parameters.image_black_pattern.split():
- black_pattern.append(re.compile(i))
- black_pattern.append(re.compile("hob-image"))
- black_pattern.append(re.compile("edited(-[0-9]*)*.bb$"))
-
- it = image_model.get_iter_first()
- self._image_combo_disconnect_signal()
- model = self.image_combo.get_model()
- model.clear()
- # Set a indicator text to combo store when first open
- if not selected_image:
- self.image_combo.append_text(self.__dummy_image__)
- cnt = cnt + 1
-
- self.image_combo.append_text(self.__custom_image__)
- self.image_combo.append_text("--Separator--")
- cnt = cnt + 2
-
- topdir = self.builder.get_topdir()
- # append and set active
- while it:
- path = image_model.get_path(it)
- it = image_model.iter_next(it)
- image_name = image_model[path][recipe_model.COL_NAME]
- if image_name == self.builder.recipe_model.__custom_image__:
- continue
-
- if black_pattern:
- allow = True
- for pattern in black_pattern:
- if pattern.search(image_name):
- allow = False
- break
- elif white_pattern:
- allow = False
- for pattern in white_pattern:
- if pattern.search(image_name):
- allow = True
- break
- else:
- allow = True
-
- file_name = image_model[path][recipe_model.COL_FILE]
- if file_name and topdir in file_name:
- allow = False
-
- if allow:
- self.image_combo.append_text(image_name)
- if image_name == selected_image:
- active = cnt
- cnt = cnt + 1
- self.image_combo.append_text(self.builder.recipe_model.__custom_image__)
-
- if selected_image == self.builder.recipe_model.__custom_image__:
- active = cnt
-
- if self.custom_image_selected:
- self.image_combo.append_text("--Separator--")
- self.image_combo.append_text(self.custom_image_selected)
- cnt = cnt + 2
- if self.custom_image_selected == selected_image:
- active = cnt
-
- self.image_combo.set_active(active)
-
- if active != 0:
- self.show_baseimg_selected()
-
- self._image_combo_connect_signal()
-
- def layer_button_clicked_cb(self, button):
- # Create a layer selection dialog
- self.builder.show_layer_selection_dialog()
-
- def view_adv_configuration_button_clicked_cb(self, button):
- # Create an advanced settings dialog
- response, settings_changed = self.builder.show_adv_settings_dialog()
- if not response:
- return
- if settings_changed:
- self.builder.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
- self.builder.wait(0.1) #wait for adv_settings_dialog to terminate
- self.builder.reparse_post_adv_settings()
- self.builder.window.set_cursor(None)
-
- def just_bake_button_clicked_cb(self, button):
- self.builder.parsing_warnings = []
- self.builder.just_bake()
-
- def edit_image_button_clicked_cb(self, button):
- self.builder.set_base_image()
- self.builder.show_recipes()
-
- def my_images_button_clicked_cb(self, button):
- self.builder.show_load_my_images_dialog()
-
- def settings_button_clicked_cb(self, button):
- # Create an advanced settings dialog
- response, settings_changed = self.builder.show_simple_settings_dialog()
- if not response:
- return
- if settings_changed:
- self.builder.reparse_post_adv_settings()
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/imagedetailspage.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
deleted file mode 100755
index 352e9489f..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
+++ /dev/null
@@ -1,669 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2012 Intel Corporation
-#
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gobject
-import gtk
-from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import hic, HobViewTable, HobAltButton, HobButton
-from bb.ui.crumbs.hobpages import HobPage
-import subprocess
-from bb.ui.crumbs.hig.crumbsdialog import CrumbsDialog
-from bb.ui.crumbs.hig.saveimagedialog import SaveImageDialog
-
-#
-# ImageDetailsPage
-#
-class ImageDetailsPage (HobPage):
-
- class DetailBox (gtk.EventBox):
- def __init__(self, widget = None, varlist = None, vallist = None, icon = None, button = None, button2=None, color = HobColors.LIGHT_GRAY):
- gtk.EventBox.__init__(self)
-
- # set color
- style = self.get_style().copy()
- style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(color, False, False)
- self.set_style(style)
-
- self.row = gtk.Table(1, 2, False)
- self.row.set_border_width(10)
- self.add(self.row)
-
- total_rows = 0
- if widget:
- total_rows = 10
- if varlist and vallist:
- # pack the icon and the text on the left
- total_rows += len(varlist)
- self.table = gtk.Table(total_rows, 20, True)
- self.table.set_row_spacings(6)
- self.table.set_size_request(100, -1)
- self.row.attach(self.table, 0, 1, 0, 1, xoptions=gtk.FILL|gtk.EXPAND, yoptions=gtk.FILL)
-
- colid = 0
- rowid = 0
- self.line_widgets = {}
- if icon:
- self.table.attach(icon, colid, colid + 2, 0, 1)
- colid = colid + 2
- if widget:
- self.table.attach(widget, colid, 20, 0, 10)
- rowid = 10
- if varlist and vallist:
- for row in range(rowid, total_rows):
- index = row - rowid
- self.line_widgets[varlist[index]] = self.text2label(varlist[index], vallist[index])
- self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1)
- # pack the button on the right
- if button:
- self.bbox = gtk.VBox()
- self.bbox.pack_start(button, expand=True, fill=False)
- if button2:
- self.bbox.pack_start(button2, expand=True, fill=False)
- self.bbox.set_size_request(150,-1)
- self.row.attach(self.bbox, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=gtk.EXPAND)
-
- def update_line_widgets(self, variable, value):
- if len(self.line_widgets) == 0:
- return
- if not isinstance(self.line_widgets[variable], gtk.Label):
- return
- self.line_widgets[variable].set_markup(self.format_line(variable, value))
-
- def wrap_line(self, inputs):
- # wrap the long text of inputs
- wrap_width_chars = 75
- outputs = ""
- tmps = inputs
- less_chars = len(inputs)
- while (less_chars - wrap_width_chars) > 0:
- less_chars -= wrap_width_chars
- outputs += tmps[:wrap_width_chars] + "\n "
- tmps = inputs[less_chars:]
- outputs += tmps
- return outputs
-
- def format_line(self, variable, value):
- wraped_value = self.wrap_line(value)
- markup = "<span weight=\'bold\'>%s</span>" % variable
- markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % wraped_value
- return markup
-
- def text2label(self, variable, value):
- # append the name:value to the left box
- # such as "Name: hob-core-minimal-variant-2011-12-15-beagleboard"
- label = gtk.Label()
- label.set_alignment(0.0, 0.5)
- label.set_markup(self.format_line(variable, value))
- return label
-
- class BuildDetailBox (gtk.EventBox):
- def __init__(self, varlist = None, vallist = None, icon = None, color = HobColors.LIGHT_GRAY):
- gtk.EventBox.__init__(self)
-
- # set color
- style = self.get_style().copy()
- style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(color, False, False)
- self.set_style(style)
-
- self.hbox = gtk.HBox()
- self.hbox.set_border_width(10)
- self.add(self.hbox)
-
- total_rows = 0
- if varlist and vallist:
- # pack the icon and the text on the left
- total_rows += len(varlist)
- self.table = gtk.Table(total_rows, 20, True)
- self.table.set_row_spacings(6)
- self.table.set_size_request(100, -1)
- self.hbox.pack_start(self.table, expand=True, fill=True, padding=15)
-
- colid = 0
- rowid = 0
- self.line_widgets = {}
- if icon:
- self.table.attach(icon, colid, colid + 2, 0, 1)
- colid = colid + 2
- if varlist and vallist:
- for row in range(rowid, total_rows):
- index = row - rowid
- self.line_widgets[varlist[index]] = self.text2label(varlist[index], vallist[index])
- self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1)
-
- def update_line_widgets(self, variable, value):
- if len(self.line_widgets) == 0:
- return
- if not isinstance(self.line_widgets[variable], gtk.Label):
- return
- self.line_widgets[variable].set_markup(self.format_line(variable, value))
-
- def wrap_line(self, inputs):
- # wrap the long text of inputs
- wrap_width_chars = 75
- outputs = ""
- tmps = inputs
- less_chars = len(inputs)
- while (less_chars - wrap_width_chars) > 0:
- less_chars -= wrap_width_chars
- outputs += tmps[:wrap_width_chars] + "\n "
- tmps = inputs[less_chars:]
- outputs += tmps
- return outputs
-
- def format_line(self, variable, value):
- wraped_value = self.wrap_line(value)
- markup = "<span weight=\'bold\'>%s</span>" % variable
- markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % wraped_value
- return markup
-
- def text2label(self, variable, value):
- # append the name:value to the left box
- # such as "Name: hob-core-minimal-variant-2011-12-15-beagleboard"
- label = gtk.Label()
- label.set_alignment(0.0, 0.5)
- label.set_markup(self.format_line(variable, value))
- return label
-
- def __init__(self, builder):
- super(ImageDetailsPage, self).__init__(builder, "Image details")
-
- self.image_store = []
- self.button_ids = {}
- self.details_bottom_buttons = gtk.HBox(False, 6)
- self.image_saved = False
- self.create_visual_elements()
- self.name_field_template = ""
- self.description_field_template = ""
-
- def create_visual_elements(self):
- # create visual elements
- # create the toolbar
- self.toolbar = gtk.Toolbar()
- self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
- self.toolbar.set_style(gtk.TOOLBAR_BOTH)
-
- my_images_button = self.append_toolbar_button(self.toolbar,
- "Images",
- hic.ICON_IMAGES_DISPLAY_FILE,
- hic.ICON_IMAGES_HOVER_FILE,
- "Open previously built images",
- self.my_images_button_clicked_cb)
- settings_button = self.append_toolbar_button(self.toolbar,
- "Settings",
- hic.ICON_SETTINGS_DISPLAY_FILE,
- hic.ICON_SETTINGS_HOVER_FILE,
- "View additional build settings",
- self.settings_button_clicked_cb)
-
- self.details_top_buttons = self.add_onto_top_bar(self.toolbar)
-
- def _remove_all_widget(self):
- children = self.get_children() or []
- for child in children:
- self.remove(child)
- children = self.box_group_area.get_children() or []
- for child in children:
- self.box_group_area.remove(child)
- children = self.details_bottom_buttons.get_children() or []
- for child in children:
- self.details_bottom_buttons.remove(child)
-
- def show_page(self, step):
- self.build_succeeded = (step == self.builder.IMAGE_GENERATED)
- image_addr = self.builder.parameters.image_addr
- image_names = self.builder.parameters.image_names
- if self.build_succeeded:
- machine = self.builder.configuration.curr_mach
- base_image = self.builder.recipe_model.get_selected_image()
- layers = self.builder.configuration.layers
- pkg_num = "%s" % len(self.builder.package_model.get_selected_packages())
- log_file = self.builder.current_logfile
- else:
- pkg_num = "N/A"
- log_file = None
-
- # remove
- for button_id, button in self.button_ids.items():
- button.disconnect(button_id)
- self._remove_all_widget()
-
- # repack
- self.pack_start(self.details_top_buttons, expand=False, fill=False)
- self.pack_start(self.group_align, expand=True, fill=True)
-
- self.build_result = None
- if self.image_saved or (self.build_succeeded and self.builder.current_step == self.builder.IMAGE_GENERATING):
- # building is the previous step
- icon = gtk.Image()
- pixmap_path = hic.ICON_INDI_CONFIRM_FILE
- color = HobColors.RUNNING
- pix_buffer = gtk.gdk.pixbuf_new_from_file(pixmap_path)
- icon.set_from_pixbuf(pix_buffer)
- varlist = [""]
- if self.image_saved:
- vallist = ["Your image recipe has been saved"]
- else:
- vallist = ["Your image is ready"]
- self.build_result = self.BuildDetailBox(varlist=varlist, vallist=vallist, icon=icon, color=color)
- self.box_group_area.pack_start(self.build_result, expand=False, fill=False)
-
- self.buttonlist = ["Build new image", "Save image recipe", "Run image", "Deploy image"]
-
- # Name
- self.image_store = []
- self.toggled_image = ""
- default_image_size = 0
- self.num_toggled = 0
- i = 0
- for image_name in image_names:
- image_size = HobPage._size_to_string(os.stat(os.path.join(image_addr, image_name)).st_size)
-
- image_attr = ("run" if (self.test_type_runnable(image_name) and self.test_mach_runnable(image_name)) else \
- ("deploy" if self.test_deployable(image_name) else ""))
- is_toggled = (image_attr != "")
-
- if not self.toggled_image:
- if i == (len(image_names) - 1):
- is_toggled = True
- if is_toggled:
- default_image_size = image_size
- self.toggled_image = image_name
-
- split_stuff = image_name.split('.')
- if "rootfs" in split_stuff:
- image_type = image_name[(len(split_stuff[0]) + len(".rootfs") + 1):]
- else:
- image_type = image_name[(len(split_stuff[0]) + 1):]
-
- self.image_store.append({'name': image_name,
- 'type': image_type,
- 'size': image_size,
- 'is_toggled': is_toggled,
- 'action_attr': image_attr,})
-
- i = i + 1
- self.num_toggled += is_toggled
-
- is_runnable = self.create_bottom_buttons(self.buttonlist, self.toggled_image)
-
- # Generated image files info
- varlist = ["Name: ", "Files created: ", "Directory: "]
- vallist = []
-
- vallist.append(image_name.split('.')[0])
- vallist.append(', '.join(fileitem['type'] for fileitem in self.image_store))
- vallist.append(image_addr)
-
- view_files_button = HobAltButton("View files")
- view_files_button.connect("clicked", self.view_files_clicked_cb, image_addr)
- view_files_button.set_tooltip_text("Open the directory containing the image files")
- open_log_button = None
- if log_file:
- open_log_button = HobAltButton("Open log")
- open_log_button.connect("clicked", self.open_log_clicked_cb, log_file)
- open_log_button.set_tooltip_text("Open the build's log file")
- self.image_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=view_files_button, button2=open_log_button)
- self.box_group_area.pack_start(self.image_detail, expand=False, fill=True)
-
- # The default kernel box for the qemu images
- self.sel_kernel = ""
- self.kernel_detail = None
- if 'qemu' in image_name:
- self.sel_kernel = self.get_kernel_file_name()
-
- # varlist = ["Kernel: "]
- # vallist = []
- # vallist.append(self.sel_kernel)
-
- # change_kernel_button = HobAltButton("Change")
- # change_kernel_button.connect("clicked", self.change_kernel_cb)
- # change_kernel_button.set_tooltip_text("Change qemu kernel file")
- # self.kernel_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=change_kernel_button)
- # self.box_group_area.pack_start(self.kernel_detail, expand=True, fill=True)
-
- # Machine, Image recipe and Layers
- layer_num_limit = 15
- varlist = ["Machine: ", "Image recipe: ", "Layers: "]
- vallist = []
- self.setting_detail = None
- if self.build_succeeded:
- vallist.append(machine)
- if self.builder.recipe_model.is_custom_image():
- if self.builder.configuration.initial_selected_image == self.builder.recipe_model.__custom_image__:
- base_image ="New image recipe"
- else:
- base_image = self.builder.configuration.initial_selected_image + " (edited)"
- vallist.append(base_image)
- i = 0
- for layer in layers:
- if i > layer_num_limit:
- break
- varlist.append(" - ")
- i += 1
- vallist.append("")
- i = 0
- for layer in layers:
- if i > layer_num_limit:
- break
- elif i == layer_num_limit:
- vallist.append("and more...")
- else:
- vallist.append(layer)
- i += 1
-
- edit_config_button = HobAltButton("Edit configuration")
- edit_config_button.set_tooltip_text("Edit machine and image recipe")
- edit_config_button.connect("clicked", self.edit_config_button_clicked_cb)
- self.setting_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_config_button)
- self.box_group_area.pack_start(self.setting_detail, expand=True, fill=True)
-
- # Packages included, and Total image size
- varlist = ["Packages included: ", "Total image size: "]
- vallist = []
- vallist.append(pkg_num)
- vallist.append(default_image_size)
- self.builder.configuration.image_size = default_image_size
- self.builder.configuration.image_packages = self.builder.configuration.selected_packages
- if self.build_succeeded:
- edit_packages_button = HobAltButton("Edit packages")
- edit_packages_button.set_tooltip_text("Edit the packages included in your image")
- edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
- else: # get to this page from "My images"
- edit_packages_button = None
- self.package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
- self.box_group_area.pack_start(self.package_detail, expand=True, fill=True)
-
- # pack the buttons at the bottom, at this time they are already created.
- if self.build_succeeded:
- self.box_group_area.pack_end(self.details_bottom_buttons, expand=False, fill=False)
- else: # for "My images" page
- self.details_separator = gtk.HSeparator()
- self.box_group_area.pack_start(self.details_separator, expand=False, fill=False)
- self.box_group_area.pack_start(self.details_bottom_buttons, expand=False, fill=False)
-
- self.show_all()
- if self.kernel_detail and (not is_runnable):
- self.kernel_detail.hide()
- self.image_saved = False
-
- def view_files_clicked_cb(self, button, image_addr):
- subprocess.call("xdg-open /%s" % image_addr, shell=True)
-
- def open_log_clicked_cb(self, button, log_file):
- if log_file:
- log_file = "file:///" + log_file
- gtk.show_uri(screen=button.get_screen(), uri=log_file, timestamp=0)
-
- def refresh_package_detail_box(self, image_size):
- self.package_detail.update_line_widgets("Total image size: ", image_size)
-
- def test_type_runnable(self, image_name):
- type_runnable = False
- for t in self.builder.parameters.runnable_image_types:
- if image_name.endswith(t):
- type_runnable = True
- break
- return type_runnable
-
- def test_mach_runnable(self, image_name):
- mach_runnable = False
- for t in self.builder.parameters.runnable_machine_patterns:
- if t in image_name:
- mach_runnable = True
- break
- return mach_runnable
-
- def test_deployable(self, image_name):
- if self.builder.configuration.curr_mach.startswith("qemu"):
- return False
- deployable = False
- for t in self.builder.parameters.deployable_image_types:
- if image_name.endswith(t):
- deployable = True
- break
- return deployable
-
- def get_kernel_file_name(self, kernel_addr=""):
- kernel_name = ""
-
- if not kernel_addr:
- kernel_addr = self.builder.parameters.image_addr
-
- files = [f for f in os.listdir(kernel_addr) if f[0] <> '.']
- for check_file in files:
- if check_file.endswith(".bin"):
- name_splits = check_file.split(".")[0]
- if self.builder.parameters.kernel_image_type in name_splits.split("-"):
- kernel_name = check_file
- break
-
- return kernel_name
-
- 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 table_selected_cb(self, tbutton, image):
- image['is_toggled'] = tbutton.get_active()
- if image['is_toggled']:
- self.toggled_image = image['name']
-
- def change_kernel_cb(self, widget):
- kernel_path = self.builder.show_load_kernel_dialog()
- if kernel_path and self.kernel_detail:
- import os.path
- self.sel_kernel = os.path.basename(kernel_path)
- markup = self.kernel_detail.format_line("Kernel: ", self.sel_kernel)
- label = ((self.kernel_detail.get_children()[0]).get_children()[0]).get_children()[0]
- label.set_markup(markup)
-
- def create_bottom_buttons(self, buttonlist, image_name):
- # Create the buttons at the bottom
- created = False
- packed = False
- self.button_ids = {}
- is_runnable = False
-
- # create button "Deploy image"
- name = "Deploy image"
- if name in buttonlist and self.test_deployable(image_name):
- deploy_button = HobButton('Deploy image')
- #deploy_button.set_size_request(205, 49)
- deploy_button.set_tooltip_text("Burn a live image to a USB drive or flash memory")
- deploy_button.set_flags(gtk.CAN_DEFAULT)
- button_id = deploy_button.connect("clicked", self.deploy_button_clicked_cb)
- self.button_ids[button_id] = deploy_button
- self.details_bottom_buttons.pack_end(deploy_button, expand=False, fill=False)
- created = True
- packed = True
-
- name = "Run image"
- if name in buttonlist and self.test_type_runnable(image_name) and self.test_mach_runnable(image_name):
- if created == True:
- # separator
- #label = gtk.Label(" or ")
- #self.details_bottom_buttons.pack_end(label, expand=False, fill=False)
-
- # create button "Run image"
- run_button = HobAltButton("Run image")
- else:
- # create button "Run image" as the primary button
- run_button = HobButton("Run image")
- #run_button.set_size_request(205, 49)
- run_button.set_flags(gtk.CAN_DEFAULT)
- packed = True
- run_button.set_tooltip_text("Start up an image with qemu emulator")
- button_id = run_button.connect("clicked", self.run_button_clicked_cb)
- self.button_ids[button_id] = run_button
- self.details_bottom_buttons.pack_end(run_button, expand=False, fill=False)
- created = True
- is_runnable = True
-
- name = "Save image recipe"
- if name in buttonlist and self.builder.recipe_model.is_custom_image():
- save_button = HobAltButton("Save image recipe")
- save_button.set_tooltip_text("Keep your changes saving them as an image recipe")
- save_button.set_sensitive(not self.image_saved)
- button_id = save_button.connect("clicked", self.save_button_clicked_cb)
- self.button_ids[button_id] = save_button
- self.details_bottom_buttons.pack_end(save_button, expand=False, fill=False)
-
- name = "Build new image"
- if name in buttonlist:
- # create button "Build new image"
- if packed:
- build_new_button = HobAltButton("Build new image")
- else:
- build_new_button = HobButton("Build new image")
- build_new_button.set_flags(gtk.CAN_DEFAULT)
- #build_new_button.set_size_request(205, 49)
- self.details_bottom_buttons.pack_end(build_new_button, expand=False, fill=False)
- build_new_button.set_tooltip_text("Create a new image from scratch")
- button_id = build_new_button.connect("clicked", self.build_new_button_clicked_cb)
- self.button_ids[button_id] = build_new_button
-
- return is_runnable
-
- def deploy_button_clicked_cb(self, button):
- if self.toggled_image:
- if self.num_toggled > 1:
- self.set_sensitive(False)
- self.show_builded_images_dialog(None, "Deploy image")
- self.set_sensitive(True)
- else:
- self.builder.deploy_image(self.toggled_image)
-
- def run_button_clicked_cb(self, button):
- if self.toggled_image:
- if self.num_toggled > 1:
- self.set_sensitive(False)
- self.show_builded_images_dialog(None, "Run image")
- self.set_sensitive(True)
- else:
- self.builder.runqemu_image(self.toggled_image, self.sel_kernel)
-
- def save_button_clicked_cb(self, button):
- topdir = self.builder.get_topdir()
- images_dir = topdir + "/recipes/images/custom/"
- self.builder.ensure_dir(images_dir)
-
- self.name_field_template = self.builder.image_configuration_page.custom_image_selected
- if self.name_field_template:
- image_path = self.builder.recipe_model.pn_path[self.name_field_template]
- image_iter = self.builder.recipe_model.get_iter(image_path)
- self.description_field_template = self.builder.recipe_model.get_value(image_iter, self.builder.recipe_model.COL_DESC)
- else:
- self.name_field_template = ""
-
- dialog = SaveImageDialog(images_dir, self.name_field_template, self.description_field_template,
- "Save image recipe", self.builder, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
- response = dialog.run()
- dialog.destroy()
-
- def build_new_button_clicked_cb(self, button):
- self.builder.initiate_new_build_async()
-
- def edit_config_button_clicked_cb(self, button):
- self.builder.show_configuration()
-
- def edit_packages_button_clicked_cb(self, button):
- self.builder.show_packages()
-
- def my_images_button_clicked_cb(self, button):
- self.builder.show_load_my_images_dialog()
-
- def settings_button_clicked_cb(self, button):
- # Create an advanced settings dialog
- response, settings_changed = self.builder.show_simple_settings_dialog()
- if not response:
- return
- if settings_changed:
- self.builder.reparse_post_adv_settings()
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/packageselectionpage.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
deleted file mode 100755
index 7c62b36e6..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
+++ /dev/null
@@ -1,355 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2012 Intel Corporation
-#
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import glib
-from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook, HobAltButton, HobButton
-from bb.ui.crumbs.hoblistmodel import PackageListModel
-from bb.ui.crumbs.hobpages import HobPage
-
-#
-# PackageSelectionPage
-#
-class PackageSelectionPage (HobPage):
-
- pages = [
- {
- 'name' : 'Included packages',
- 'tooltip' : 'The packages currently included for your image',
- 'filter' : { PackageListModel.COL_INC : [True] },
- 'search' : 'Search packages by name',
- 'searchtip' : 'Enter a package name to find it',
- 'columns' : [{
- 'col_name' : 'Package name',
- 'col_id' : PackageListModel.COL_NAME,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 300,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Size',
- 'col_id' : PackageListModel.COL_SIZE,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 300,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Recipe',
- 'col_id' : PackageListModel.COL_RCP,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 250,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Brought in by (+others)',
- 'col_id' : PackageListModel.COL_BINB,
- 'col_style': 'binb',
- 'col_min' : 100,
- 'col_max' : 350,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Included',
- 'col_id' : PackageListModel.COL_INC,
- 'col_style': 'check toggle',
- 'col_min' : 100,
- 'col_max' : 100
- }]
- }, {
- 'name' : 'All packages',
- 'tooltip' : 'All packages that have been built',
- 'filter' : {},
- 'search' : 'Search packages by name',
- 'searchtip' : 'Enter a package name to find it',
- 'columns' : [{
- 'col_name' : 'Package name',
- 'col_id' : PackageListModel.COL_NAME,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 400,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Size',
- 'col_id' : PackageListModel.COL_SIZE,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 500,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Recipe',
- 'col_id' : PackageListModel.COL_RCP,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 250,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Included',
- 'col_id' : PackageListModel.COL_INC,
- 'col_style': 'check toggle',
- 'col_min' : 100,
- 'col_max' : 100
- }]
- }
- ]
-
- (INCLUDED,
- ALL) = range(2)
-
- def __init__(self, builder):
- super(PackageSelectionPage, self).__init__(builder, "Edit packages")
-
- # set invisible members
- self.recipe_model = self.builder.recipe_model
- self.package_model = self.builder.package_model
-
- # create visual elements
- self.create_visual_elements()
-
- def included_clicked_cb(self, button):
- self.ins.set_current_page(self.INCLUDED)
-
- def create_visual_elements(self):
- self.label = gtk.Label("Packages included: 0\nSelected packages size: 0 MB")
- self.eventbox = self.add_onto_top_bar(self.label, 73)
- self.pack_start(self.eventbox, expand=False, fill=False)
- self.pack_start(self.group_align, expand=True, fill=True)
-
- # set visible members
- self.ins = HobNotebook()
- self.tables = [] # we need to modify table when the dialog is shown
-
- search_names = []
- search_tips = []
- # append the tab
- for page in self.pages:
- columns = page['columns']
- name = page['name']
- tab = HobViewTable(columns, name)
- search_names.append(page['search'])
- search_tips.append(page['searchtip'])
- filter = page['filter']
- sort_model = self.package_model.tree_model(filter, initial=True)
- tab.set_model(sort_model)
- tab.connect("toggled", self.table_toggled_cb, name)
- tab.connect("button-release-event", self.button_click_cb)
- tab.connect("cell-fadeinout-stopped", self.after_fadeout_checkin_include, filter)
- self.ins.append_page(tab, page['name'], page['tooltip'])
- self.tables.append(tab)
-
- self.ins.set_entry(search_names, search_tips)
- self.ins.search.connect("changed", self.search_entry_changed)
-
- # add all into the dialog
- self.box_group_area.pack_start(self.ins, expand=True, fill=True)
-
- self.button_box = gtk.HBox(False, 6)
- self.box_group_area.pack_start(self.button_box, expand=False, fill=False)
-
- self.build_image_button = HobButton('Build image')
- #self.build_image_button.set_size_request(205, 49)
- self.build_image_button.set_tooltip_text("Build target image")
- self.build_image_button.set_flags(gtk.CAN_DEFAULT)
- self.build_image_button.grab_default()
- self.build_image_button.connect("clicked", self.build_image_clicked_cb)
- self.button_box.pack_end(self.build_image_button, expand=False, fill=False)
-
- self.back_button = HobAltButton('Cancel')
- self.back_button.connect("clicked", self.back_button_clicked_cb)
- self.button_box.pack_end(self.back_button, expand=False, fill=False)
-
- def search_entry_changed(self, entry):
- text = entry.get_text()
- if self.ins.search_focus:
- self.ins.search_focus = False
- elif self.ins.page_changed:
- self.ins.page_change = False
- self.filter_search(entry)
- elif text not in self.ins.search_names:
- self.filter_search(entry)
-
- def filter_search(self, entry):
- text = entry.get_text()
- current_tab = self.ins.get_current_page()
- filter = self.pages[current_tab]['filter']
- filter[PackageListModel.COL_NAME] = text
- self.tables[current_tab].set_model(self.package_model.tree_model(filter, search_data=text))
- if self.package_model.filtered_nb == 0:
- if not self.ins.get_nth_page(current_tab).top_bar:
- self.ins.get_nth_page(current_tab).add_no_result_bar(entry)
- self.ins.get_nth_page(current_tab).top_bar.set_no_show_all(True)
- self.ins.get_nth_page(current_tab).top_bar.show()
- self.ins.get_nth_page(current_tab).scroll.hide()
- else:
- if self.ins.get_nth_page(current_tab).top_bar:
- self.ins.get_nth_page(current_tab).top_bar.hide()
- self.ins.get_nth_page(current_tab).scroll.show()
- if entry.get_text() == '':
- entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
- else:
- entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, True)
-
- def button_click_cb(self, widget, event):
- path, col = widget.table_tree.get_cursor()
- tree_model = widget.table_tree.get_model()
- if path and col.get_title() != 'Included': # else activation is likely a removal
- properties = {'binb': '' , 'name': '', 'size':'', 'recipe':'', 'files_list':''}
- properties['binb'] = tree_model.get_value(tree_model.get_iter(path), PackageListModel.COL_BINB)
- properties['name'] = tree_model.get_value(tree_model.get_iter(path), PackageListModel.COL_NAME)
- properties['size'] = tree_model.get_value(tree_model.get_iter(path), PackageListModel.COL_SIZE)
- properties['recipe'] = tree_model.get_value(tree_model.get_iter(path), PackageListModel.COL_RCP)
- properties['files_list'] = tree_model.get_value(tree_model.get_iter(path), PackageListModel.COL_FLIST)
-
- self.builder.show_recipe_property_dialog(properties)
-
- def open_log_clicked_cb(self, button, log_file):
- if log_file:
- log_file = "file:///" + log_file
- gtk.show_uri(screen=button.get_screen(), uri=log_file, timestamp=0)
-
- def show_page(self, log_file):
- children = self.button_box.get_children() or []
- for child in children:
- self.button_box.remove(child)
- # re-packed the buttons as request, add the 'open log' button if build success
- self.button_box.pack_end(self.build_image_button, expand=False, fill=False)
- if log_file:
- open_log_button = HobAltButton("Open log")
- open_log_button.connect("clicked", self.open_log_clicked_cb, log_file)
- open_log_button.set_tooltip_text("Open the build's log file")
- self.button_box.pack_end(open_log_button, expand=False, fill=False)
- self.button_box.pack_end(self.back_button, expand=False, fill=False)
- self.show_all()
-
- def build_image_clicked_cb(self, button):
- self.builder.parsing_warnings = []
- self.builder.build_image()
-
- def refresh_tables(self):
- self.ins.reset_entry(self.ins.search, 0)
- for tab in self.tables:
- index = self.tables.index(tab)
- filter = self.pages[index]['filter']
- tab.set_model(self.package_model.tree_model(filter, initial=True))
-
- def back_button_clicked_cb(self, button):
- if self.builder.previous_step == self.builder.IMAGE_GENERATED:
- self.builder.restore_initial_selected_packages()
- self.refresh_selection()
- self.builder.show_image_details()
- else:
- self.builder.show_configuration()
- self.refresh_tables()
-
- def refresh_selection(self):
- self.builder.configuration.selected_packages = self.package_model.get_selected_packages()
- self.builder.configuration.user_selected_packages = self.package_model.get_user_selected_packages()
- selected_packages_num = len(self.builder.configuration.selected_packages)
- selected_packages_size = self.package_model.get_packages_size()
- selected_packages_size_str = HobPage._size_to_string(selected_packages_size)
-
- if self.builder.configuration.image_packages == self.builder.configuration.selected_packages:
- image_total_size_str = self.builder.configuration.image_size
- else:
- image_overhead_factor = self.builder.configuration.image_overhead_factor
- image_rootfs_size = self.builder.configuration.image_rootfs_size / 1024 # image_rootfs_size is KB
- image_extra_size = self.builder.configuration.image_extra_size / 1024 # image_extra_size is KB
- base_size = image_overhead_factor * selected_packages_size
- image_total_size = max(base_size, image_rootfs_size) + image_extra_size
- if "zypper" in self.builder.configuration.selected_packages:
- image_total_size += (51200 * 1024)
- image_total_size_str = HobPage._size_to_string(image_total_size)
-
- self.label.set_label("Packages included: %s\nSelected packages size: %s\nEstimated image size: %s" %
- (selected_packages_num, selected_packages_size_str, image_total_size_str))
- self.ins.show_indicator_icon("Included packages", selected_packages_num)
-
- def toggle_item_idle_cb(self, path, view_tree, cell, pagename):
- if not self.package_model.path_included(path):
- self.package_model.include_item(item_path=path, binb="User Selected")
- else:
- self.pre_fadeout_checkout_include(view_tree)
- self.package_model.exclude_item(item_path=path)
- self.render_fadeout(view_tree, cell)
-
- self.refresh_selection()
- if not self.builder.customized:
- self.builder.customized = True
- self.builder.set_base_image()
- self.builder.configuration.selected_image = self.recipe_model.__custom_image__
- self.builder.rcppkglist_populated()
-
- self.builder.window_sensitive(True)
- view_model = view_tree.get_model()
- vpath = self.package_model.convert_path_to_vpath(view_model, path)
- view_tree.set_cursor(vpath)
-
- def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree, pagename):
- # Click to include a package
- self.builder.window_sensitive(False)
- view_model = view_tree.get_model()
- path = self.package_model.convert_vpath_to_path(view_model, view_path)
- glib.idle_add(self.toggle_item_idle_cb, path, view_tree, cell, pagename)
-
- def pre_fadeout_checkout_include(self, tree):
- #after the fadeout the table will be sorted as before
- self.sort_column_id = self.package_model.sort_column_id
- self.sort_order = self.package_model.sort_order
-
- self.package_model.resync_fadeout_column(self.package_model.get_iter_first())
- # Check out a model which base on the column COL_FADE_INC,
- # it's save the prev state of column COL_INC before do exclude_item
- filter = { PackageListModel.COL_FADE_INC : [True]}
- new_model = self.package_model.tree_model(filter, excluded_items_ahead=True)
- tree.set_model(new_model)
- tree.expand_all()
-
- def get_excluded_rows(self, to_render_cells, model, it):
- while it:
- path = model.get_path(it)
- prev_cell_is_active = model.get_value(it, PackageListModel.COL_FADE_INC)
- curr_cell_is_active = model.get_value(it, PackageListModel.COL_INC)
- if (prev_cell_is_active == True) and (curr_cell_is_active == False):
- to_render_cells.append(path)
- if model.iter_has_child(it):
- self.get_excluded_rows(to_render_cells, model, model.iter_children(it))
- it = model.iter_next(it)
-
- return to_render_cells
-
- def render_fadeout(self, tree, cell):
- if (not cell) or (not tree):
- return
- to_render_cells = []
- view_model = tree.get_model()
- self.get_excluded_rows(to_render_cells, view_model, view_model.get_iter_first())
-
- cell.fadeout(tree, 1000, to_render_cells)
-
- def after_fadeout_checkin_include(self, table, ctrl, cell, tree, filter):
- self.package_model.sort_column_id = self.sort_column_id
- self.package_model.sort_order = self.sort_order
- tree.set_model(self.package_model.tree_model(filter))
- tree.expand_all()
-
- def set_packages_curr_tab(self, curr_page):
- self.ins.set_current_page(curr_page)
-
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
deleted file mode 100755
index 58db43f70..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
+++ /dev/null
@@ -1,335 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2012 Intel Corporation
-#
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-# Authored by Shane Wang <shane.wang@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import glib
-from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook, HobAltButton, HobButton
-from bb.ui.crumbs.hoblistmodel import RecipeListModel
-from bb.ui.crumbs.hobpages import HobPage
-
-#
-# RecipeSelectionPage
-#
-class RecipeSelectionPage (HobPage):
- pages = [
- {
- 'name' : 'Included recipes',
- 'tooltip' : 'The recipes currently included for your image',
- 'filter' : { RecipeListModel.COL_INC : [True],
- RecipeListModel.COL_TYPE : ['recipe', 'packagegroup'] },
- 'search' : 'Search recipes by name',
- 'searchtip' : 'Enter a recipe name to find it',
- 'columns' : [{
- 'col_name' : 'Recipe name',
- 'col_id' : RecipeListModel.COL_NAME,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 400,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Group',
- 'col_id' : RecipeListModel.COL_GROUP,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 300,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Brought in by (+others)',
- 'col_id' : RecipeListModel.COL_BINB,
- 'col_style': 'binb',
- 'col_min' : 100,
- 'col_max' : 500,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Included',
- 'col_id' : RecipeListModel.COL_INC,
- 'col_style': 'check toggle',
- 'col_min' : 100,
- 'col_max' : 100
- }]
- }, {
- 'name' : 'All recipes',
- 'tooltip' : 'All recipes in your configured layers',
- 'filter' : { RecipeListModel.COL_TYPE : ['recipe'] },
- 'search' : 'Search recipes by name',
- 'searchtip' : 'Enter a recipe name to find it',
- 'columns' : [{
- 'col_name' : 'Recipe name',
- 'col_id' : RecipeListModel.COL_NAME,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 400,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Group',
- 'col_id' : RecipeListModel.COL_GROUP,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 400,
- 'expand' : 'True'
- }, {
- 'col_name' : 'License',
- 'col_id' : RecipeListModel.COL_LIC,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 400,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Included',
- 'col_id' : RecipeListModel.COL_INC,
- 'col_style': 'check toggle',
- 'col_min' : 100,
- 'col_max' : 100
- }]
- }, {
- 'name' : 'Package Groups',
- 'tooltip' : 'All package groups in your configured layers',
- 'filter' : { RecipeListModel.COL_TYPE : ['packagegroup'] },
- 'search' : 'Search package groups by name',
- 'searchtip' : 'Enter a package group name to find it',
- 'columns' : [{
- 'col_name' : 'Package group name',
- 'col_id' : RecipeListModel.COL_NAME,
- 'col_style': 'text',
- 'col_min' : 100,
- 'col_max' : 400,
- 'expand' : 'True'
- }, {
- 'col_name' : 'Included',
- 'col_id' : RecipeListModel.COL_INC,
- 'col_style': 'check toggle',
- 'col_min' : 100,
- 'col_max' : 100
- }]
- }
- ]
-
- (INCLUDED,
- ALL,
- TASKS) = range(3)
-
- def __init__(self, builder = None):
- super(RecipeSelectionPage, self).__init__(builder, "Step 1 of 2: Edit recipes")
-
- # set invisible members
- self.recipe_model = self.builder.recipe_model
-
- # create visual elements
- self.create_visual_elements()
-
- def included_clicked_cb(self, button):
- self.ins.set_current_page(self.INCLUDED)
-
- def create_visual_elements(self):
- self.eventbox = self.add_onto_top_bar(None, 73)
- self.pack_start(self.eventbox, expand=False, fill=False)
- self.pack_start(self.group_align, expand=True, fill=True)
-
- # set visible members
- self.ins = HobNotebook()
- self.tables = [] # we need modify table when the dialog is shown
-
- search_names = []
- search_tips = []
- # append the tabs in order
- for page in self.pages:
- columns = page['columns']
- name = page['name']
- tab = HobViewTable(columns, name)
- search_names.append(page['search'])
- search_tips.append(page['searchtip'])
- filter = page['filter']
- sort_model = self.recipe_model.tree_model(filter, initial=True)
- tab.set_model(sort_model)
- tab.connect("toggled", self.table_toggled_cb, name)
- tab.connect("button-release-event", self.button_click_cb)
- tab.connect("cell-fadeinout-stopped", self.after_fadeout_checkin_include, filter)
- self.ins.append_page(tab, page['name'], page['tooltip'])
- self.tables.append(tab)
-
- self.ins.set_entry(search_names, search_tips)
- self.ins.search.connect("changed", self.search_entry_changed)
-
- # add all into the window
- self.box_group_area.pack_start(self.ins, expand=True, fill=True)
-
- button_box = gtk.HBox(False, 6)
- self.box_group_area.pack_end(button_box, expand=False, fill=False)
-
- self.build_packages_button = HobButton('Build packages')
- #self.build_packages_button.set_size_request(205, 49)
- self.build_packages_button.set_tooltip_text("Build selected recipes into packages")
- self.build_packages_button.set_flags(gtk.CAN_DEFAULT)
- self.build_packages_button.grab_default()
- self.build_packages_button.connect("clicked", self.build_packages_clicked_cb)
- button_box.pack_end(self.build_packages_button, expand=False, fill=False)
-
- self.back_button = HobAltButton('Cancel')
- self.back_button.connect("clicked", self.back_button_clicked_cb)
- button_box.pack_end(self.back_button, expand=False, fill=False)
-
- def search_entry_changed(self, entry):
- text = entry.get_text()
- if self.ins.search_focus:
- self.ins.search_focus = False
- elif self.ins.page_changed:
- self.ins.page_change = False
- self.filter_search(entry)
- elif text not in self.ins.search_names:
- self.filter_search(entry)
-
- def filter_search(self, entry):
- text = entry.get_text()
- current_tab = self.ins.get_current_page()
- filter = self.pages[current_tab]['filter']
- filter[RecipeListModel.COL_NAME] = text
- self.tables[current_tab].set_model(self.recipe_model.tree_model(filter, search_data=text))
- if self.recipe_model.filtered_nb == 0:
- if not self.ins.get_nth_page(current_tab).top_bar:
- self.ins.get_nth_page(current_tab).add_no_result_bar(entry)
- self.ins.get_nth_page(current_tab).top_bar.set_no_show_all(True)
- self.ins.get_nth_page(current_tab).top_bar.show()
- self.ins.get_nth_page(current_tab).scroll.hide()
- else:
- if self.ins.get_nth_page(current_tab).top_bar:
- self.ins.get_nth_page(current_tab).top_bar.hide()
- self.ins.get_nth_page(current_tab).scroll.show()
- if entry.get_text() == '':
- entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
- else:
- entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, True)
-
- def button_click_cb(self, widget, event):
- path, col = widget.table_tree.get_cursor()
- tree_model = widget.table_tree.get_model()
- if path and col.get_title() != 'Included': # else activation is likely a removal
- properties = {'summary': '', 'name': '', 'version': '', 'revision': '', 'binb': '', 'group': '', 'license': '', 'homepage': '', 'bugtracker': '', 'description': ''}
- properties['summary'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_SUMMARY)
- properties['name'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_NAME)
- properties['version'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_VERSION)
- properties['revision'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_REVISION)
- properties['binb'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_BINB)
- properties['group'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_GROUP)
- properties['license'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_LIC)
- properties['homepage'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_HOMEPAGE)
- properties['bugtracker'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_BUGTRACKER)
- properties['description'] = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_DESC)
- self.builder.show_recipe_property_dialog(properties)
-
- def build_packages_clicked_cb(self, button):
- self.refresh_tables()
- self.builder.build_packages()
-
- def refresh_tables(self):
- self.ins.reset_entry(self.ins.search, 0)
- for tab in self.tables:
- index = self.tables.index(tab)
- filter = self.pages[index]['filter']
- tab.set_model(self.recipe_model.tree_model(filter, search_data="", initial=True))
-
- def back_button_clicked_cb(self, button):
- self.builder.recipe_model.set_selected_image(self.builder.configuration.initial_selected_image)
- self.builder.image_configuration_page.update_image_combo(self.builder.recipe_model, self.builder.configuration.initial_selected_image)
- self.builder.image_configuration_page.update_image_desc()
- self.builder.show_configuration()
- self.refresh_tables()
-
- def refresh_selection(self):
- self.builder.configuration.selected_image = self.recipe_model.get_selected_image()
- _, self.builder.configuration.selected_recipes = self.recipe_model.get_selected_recipes()
- self.ins.show_indicator_icon("Included recipes", len(self.builder.configuration.selected_recipes))
-
- def toggle_item_idle_cb(self, path, view_tree, cell, pagename):
- if not self.recipe_model.path_included(path):
- self.recipe_model.include_item(item_path=path, binb="User Selected", image_contents=False)
- else:
- self.pre_fadeout_checkout_include(view_tree, pagename)
- self.recipe_model.exclude_item(item_path=path)
- self.render_fadeout(view_tree, cell)
-
- self.refresh_selection()
- if not self.builder.customized:
- self.builder.customized = True
- self.builder.configuration.selected_image = self.recipe_model.__custom_image__
- self.builder.rcppkglist_populated()
-
- self.builder.window_sensitive(True)
-
- view_model = view_tree.get_model()
- vpath = self.recipe_model.convert_path_to_vpath(view_model, path)
- view_tree.set_cursor(vpath)
-
- def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree, pagename):
- # Click to include a recipe
- self.builder.window_sensitive(False)
- view_model = view_tree.get_model()
- path = self.recipe_model.convert_vpath_to_path(view_model, view_path)
- glib.idle_add(self.toggle_item_idle_cb, path, view_tree, cell, pagename)
-
- def pre_fadeout_checkout_include(self, tree, pagename):
- #after the fadeout the table will be sorted as before
- self.sort_column_id = self.recipe_model.sort_column_id
- self.sort_order = self.recipe_model.sort_order
-
- #resync the included items to a backup fade include column
- it = self.recipe_model.get_iter_first()
- while it:
- active = self.recipe_model.get_value(it, self.recipe_model.COL_INC)
- self.recipe_model.set(it, self.recipe_model.COL_FADE_INC, active)
- it = self.recipe_model.iter_next(it)
- # Check out a model which base on the column COL_FADE_INC,
- # it's save the prev state of column COL_INC before do exclude_item
- filter = { RecipeListModel.COL_FADE_INC:[True] }
- if pagename == "Included recipes":
- filter[RecipeListModel.COL_TYPE] = ['recipe', 'packagegroup']
- elif pagename == "All recipes":
- filter[RecipeListModel.COL_TYPE] = ['recipe']
- else:
- filter[RecipeListModel.COL_TYPE] = ['packagegroup']
-
- new_model = self.recipe_model.tree_model(filter, excluded_items_ahead=True)
- tree.set_model(new_model)
-
- def render_fadeout(self, tree, cell):
- if (not cell) or (not tree):
- return
- to_render_cells = []
- model = tree.get_model()
- it = model.get_iter_first()
- while it:
- path = model.get_path(it)
- prev_cell_is_active = model.get_value(it, RecipeListModel.COL_FADE_INC)
- curr_cell_is_active = model.get_value(it, RecipeListModel.COL_INC)
- if (prev_cell_is_active == True) and (curr_cell_is_active == False):
- to_render_cells.append(path)
- it = model.iter_next(it)
-
- cell.fadeout(tree, 1000, to_render_cells)
-
- def after_fadeout_checkin_include(self, table, ctrl, cell, tree, filter):
- self.recipe_model.sort_column_id = self.sort_column_id
- self.recipe_model.sort_order = self.sort_order
- tree.set_model(self.recipe_model.tree_model(filter))
-
- def set_recipe_curr_tab(self, curr_page):
- self.ins.set_current_page(curr_page)
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/sanitycheckpage.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/sanitycheckpage.py
deleted file mode 100644
index 76ce2ecc2..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/crumbs/sanitycheckpage.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2012 Intel Corporation
-#
-# Authored by Bogdan Marinescu <bogdan.a.marinescu@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk, gobject
-from bb.ui.crumbs.progressbar import HobProgressBar
-from bb.ui.crumbs.hobwidget import hic
-from bb.ui.crumbs.hobpages import HobPage
-
-#
-# SanityCheckPage
-#
-class SanityCheckPage (HobPage):
-
- def __init__(self, builder):
- super(SanityCheckPage, self).__init__(builder)
- self.running = False
- self.create_visual_elements()
- self.show_all()
-
- def make_label(self, text, bold=True):
- label = gtk.Label()
- label.set_alignment(0.0, 0.5)
- mark = "<span %s>%s</span>" % (self.span_tag('x-large', 'bold') if bold else self.span_tag('medium'), text)
- label.set_markup(mark)
- return label
-
- def start(self):
- if not self.running:
- self.running = True
- gobject.timeout_add(100, self.timer_func)
-
- def stop(self):
- self.running = False
-
- def is_running(self):
- return self.running
-
- def timer_func(self):
- self.progress_bar.pulse()
- return self.running
-
- def create_visual_elements(self):
- # Table'd layout. 'rows' and 'cols' give the table size
- rows, cols = 30, 50
- self.table = gtk.Table(rows, cols, True)
- self.pack_start(self.table, expand=False, fill=False)
- sx, sy = 2, 2
- # 'info' icon
- image = gtk.Image()
- image.set_from_file(hic.ICON_INFO_DISPLAY_FILE)
- self.table.attach(image, sx, sx + 2, sy, sy + 3 )
- image.show()
- # 'Checking' message
- label = self.make_label('Hob is checking for correct build system setup')
- self.table.attach(label, sx + 2, cols, sy, sy + 3, xpadding=5 )
- label.show()
- # 'Shouldn't take long' message.
- label = self.make_label("The check shouldn't take long.", False)
- self.table.attach(label, sx + 2, cols, sy + 3, sy + 4, xpadding=5)
- label.show()
- # Progress bar
- self.progress_bar = HobProgressBar()
- self.table.attach(self.progress_bar, sx + 2, cols - 3, sy + 5, sy + 7, xpadding=5)
- self.progress_bar.show()
- # All done
- self.table.show()
-
diff --git a/yocto-poky/bitbake/lib/bb/ui/hob.py b/yocto-poky/bitbake/lib/bb/ui/hob.py
deleted file mode 100755
index da5b41189..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/hob.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/bin/env python
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2011 Intel Corporation
-#
-# Authored by Joshua Lock <josh@linux.intel.com>
-# Authored by Dongxiao Xu <dongxiao.xu@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import sys
-import os
-requirements = "FATAL: Hob requires Gtk+ 2.20.0 or higher, PyGtk 2.21.0 or higher"
-try:
- import gobject
- import gtk
- import pygtk
- pygtk.require('2.0') # to be certain we don't have gtk+ 1.x !?!
- gtkver = gtk.gtk_version
- pygtkver = gtk.pygtk_version
- if gtkver < (2, 20, 0) or pygtkver < (2, 21, 0):
- sys.exit("%s,\nYou have Gtk+ %s and PyGtk %s." % (requirements,
- ".".join(map(str, gtkver)),
- ".".join(map(str, pygtkver))))
-except ImportError as exc:
- sys.exit("%s (%s)." % (requirements, str(exc)))
-sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
-try:
- import bb
-except RuntimeError as exc:
- sys.exit(str(exc))
-from bb.ui import uihelper
-from bb.ui.crumbs.hoblistmodel import RecipeListModel, PackageListModel
-from bb.ui.crumbs.hobeventhandler import HobHandler
-from bb.ui.crumbs.builder import Builder
-
-featureSet = [bb.cooker.CookerFeatures.HOB_EXTRA_CACHES, bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING]
-
-def event_handle_idle_func(eventHandler, hobHandler):
- # Consume as many messages as we can in the time available to us
- if not eventHandler:
- return False
- event = eventHandler.getEvent()
- while event:
- hobHandler.handle_event(event)
- event = eventHandler.getEvent()
- return True
-
-_evt_list = [ "bb.runqueue.runQueueExitWait", "bb.event.LogExecTTY", "logging.LogRecord",
- "bb.build.TaskFailed", "bb.build.TaskBase", "bb.event.ParseStarted",
- "bb.event.ParseProgress", "bb.event.ParseCompleted", "bb.event.CacheLoadStarted",
- "bb.event.CacheLoadProgress", "bb.event.CacheLoadCompleted", "bb.command.CommandFailed",
- "bb.command.CommandExit", "bb.command.CommandCompleted", "bb.cooker.CookerExit",
- "bb.event.MultipleProviders", "bb.event.NoProvider", "bb.runqueue.sceneQueueTaskStarted",
- "bb.runqueue.runQueueTaskStarted", "bb.runqueue.runQueueTaskFailed", "bb.runqueue.sceneQueueTaskFailed",
- "bb.event.BuildBase", "bb.build.TaskStarted", "bb.build.TaskSucceeded", "bb.build.TaskFailedSilent",
- "bb.event.SanityCheckPassed", "bb.event.SanityCheckFailed", "bb.event.PackageInfo",
- "bb.event.TargetsTreeGenerated", "bb.event.ConfigFilesFound", "bb.event.ConfigFilePathFound",
- "bb.event.FilesMatchingFound", "bb.event.NetworkTestFailed", "bb.event.NetworkTestPassed",
- "bb.event.BuildStarted", "bb.event.BuildCompleted", "bb.event.DiskFull"]
-
-def main (server, eventHandler, params):
- params.updateFromServer(server)
- gobject.threads_init()
-
- # That indicates whether the Hob and the bitbake server are
- # running on different machines
- # recipe model and package model
- recipe_model = RecipeListModel()
- package_model = PackageListModel()
-
- llevel, debug_domains = bb.msg.constructLogOptions()
- server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list])
- hobHandler = HobHandler(server, recipe_model, package_model)
- builder = Builder(hobHandler, recipe_model, package_model)
-
- # This timeout function regularly probes the event queue to find out if we
- # have any messages waiting for us.
- gobject.timeout_add(10, event_handle_idle_func, eventHandler, hobHandler)
-
- try:
- gtk.main()
- except EnvironmentError as ioerror:
- # ignore interrupted io
- if ioerror.args[0] == 4:
- pass
- finally:
- hobHandler.cancel_build(force = True)
-
-if __name__ == "__main__":
- try:
- ret = main()
- except Exception:
- ret = 1
- import traceback
- traceback.print_exc(15)
- sys.exit(ret)
diff --git a/yocto-poky/bitbake/lib/bb/ui/knotty.py b/yocto-poky/bitbake/lib/bb/ui/knotty.py
index 90c318376..268562770 100644
--- a/yocto-poky/bitbake/lib/bb/ui/knotty.py
+++ b/yocto-poky/bitbake/lib/bb/ui/knotty.py
@@ -104,10 +104,11 @@ class InteractConsoleLogFilter(logging.Filter):
return True
class TerminalFilter(object):
+ rows = 25
columns = 80
def sigwinch_handle(self, signum, frame):
- self.columns = self.getTerminalColumns()
+ self.rows, self.columns = self.getTerminalColumns()
if self._sigwinch_default:
self._sigwinch_default(signum, frame)
@@ -131,7 +132,7 @@ class TerminalFilter(object):
cr = (env['LINES'], env['COLUMNS'])
except:
cr = (25, 80)
- return cr[1]
+ return cr
def __init__(self, main, helper, console, errconsole, format):
self.main = main
@@ -170,9 +171,13 @@ class TerminalFilter(object):
signal.signal(signal.SIGWINCH, self.sigwinch_handle)
except:
pass
- self.columns = self.getTerminalColumns()
+ self.rows, self.columns = self.getTerminalColumns()
except:
self.cuu = None
+ if not self.cuu:
+ self.interactive = False
+ bb.note("Unable to use interactive mode for this terminal, using fallback")
+ return
console.addFilter(InteractConsoleLogFilter(self, format))
errconsole.addFilter(InteractConsoleLogFilter(self, format))
@@ -207,7 +212,7 @@ class TerminalFilter(object):
content = "Currently %s running tasks (%s of %s):" % (len(activetasks), self.helper.tasknumber_current, self.helper.tasknumber_total)
print(content)
lines = 1 + int(len(content) / (self.columns + 1))
- for tasknum, task in enumerate(tasks):
+ for tasknum, task in enumerate(tasks[:(self.rows - 2)]):
content = "%s: %s" % (tasknum, task)
print(content)
lines = lines + 1 + int(len(content) / (self.columns + 1))
@@ -267,6 +272,8 @@ def main(server, eventHandler, params, tf = TerminalFilter):
logger.addHandler(console)
logger.addHandler(errconsole)
+ bb.utils.set_process_name("KnottyUI")
+
if params.options.remote_server and params.options.kill_server:
server.terminateServer()
return
@@ -282,6 +289,7 @@ def main(server, eventHandler, params, tf = TerminalFilter):
llevel, debug_domains = bb.msg.constructLogOptions()
server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list])
+ universe = False
if not params.observe_only:
params.updateFromServer(server)
params.updateToServer(server, os.environ.copy())
@@ -292,6 +300,8 @@ def main(server, eventHandler, params, tf = TerminalFilter):
if 'msg' in cmdline and cmdline['msg']:
logger.error(cmdline['msg'])
return 1
+ if cmdline['action'][0] == "buildTargets" and "universe" in cmdline['action'][1]:
+ universe = True
ret, error = server.runCommand(cmdline['action'])
if error:
@@ -349,11 +359,20 @@ def main(server, eventHandler, params, tf = TerminalFilter):
return_value = 1
elif event.levelno == format.WARNING:
warnings = warnings + 1
- # For "normal" logging conditions, don't show note logs from tasks
- # but do show them if the user has changed the default log level to
- # include verbose/debug messages
- if event.taskpid != 0 and event.levelno <= format.NOTE and (event.levelno < llevel or (event.levelno == format.NOTE and llevel != format.VERBOSE)):
- continue
+
+ if event.taskpid != 0:
+ # For "normal" logging conditions, don't show note logs from tasks
+ # but do show them if the user has changed the default log level to
+ # include verbose/debug messages
+ if event.levelno <= format.NOTE and (event.levelno < llevel or (event.levelno == format.NOTE and llevel != format.VERBOSE)):
+ continue
+
+ # Prefix task messages with recipe/task
+ if event.taskpid in helper.running_tasks:
+ taskinfo = helper.running_tasks[event.taskpid]
+ event.msg = taskinfo['title'] + ': ' + event.msg
+ if hasattr(event, 'fn'):
+ event.msg = event.fn + ': ' + event.msg
logger.handle(event)
continue
@@ -434,11 +453,12 @@ def main(server, eventHandler, params, tf = TerminalFilter):
logger.info("multiple providers are available for %s%s (%s)", event._is_runtime and "runtime " or "",
event._item,
", ".join(event._candidates))
- logger.info("consider defining a PREFERRED_PROVIDER entry to match %s", event._item)
+ rtime = ""
+ if event._is_runtime:
+ rtime = "R"
+ logger.info("consider defining a PREFERRED_%sPROVIDER entry to match %s" % (rtime, event._item))
continue
if isinstance(event, bb.event.NoProvider):
- return_value = 1
- errors = errors + 1
if event._runtime:
r = "R"
else:
@@ -449,13 +469,20 @@ def main(server, eventHandler, params, tf = TerminalFilter):
if event._close_matches:
extra = ". Close matches:\n %s" % '\n '.join(event._close_matches)
+ # For universe builds, only show these as warnings, not errors
+ h = logger.warning
+ if not universe:
+ return_value = 1
+ errors = errors + 1
+ h = logger.error
+
if event._dependees:
- logger.error("Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)%s", r, event._item, ", ".join(event._dependees), r, extra)
+ h("Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)%s", r, event._item, ", ".join(event._dependees), r, extra)
else:
- logger.error("Nothing %sPROVIDES '%s'%s", r, event._item, extra)
+ h("Nothing %sPROVIDES '%s'%s", r, event._item, extra)
if event._reasons:
for reason in event._reasons:
- logger.error("%s", reason)
+ h("%s", reason)
continue
if isinstance(event, bb.runqueue.sceneQueueTaskStarted):
@@ -475,6 +502,7 @@ def main(server, eventHandler, params, tf = TerminalFilter):
continue
if isinstance(event, bb.runqueue.runQueueTaskFailed):
+ return_value = 1
taskfailures.append(event.taskstring)
logger.error("Task %s (%s) failed with exit code '%s'",
event.taskid, event.taskstring, event.exitcode)
@@ -532,10 +560,12 @@ def main(server, eventHandler, params, tf = TerminalFilter):
main.shutdown = main.shutdown + 1
pass
except Exception as e:
- sys.stderr.write(str(e))
+ import traceback
+ sys.stderr.write(traceback.format_exc())
if not params.observe_only:
_, error = server.runCommand(["stateForceShutdown"])
main.shutdown = 2
+ return_value = 1
try:
summary = ""
if taskfailures:
diff --git a/yocto-poky/bitbake/lib/bb/ui/puccho.py b/yocto-poky/bitbake/lib/bb/ui/puccho.py
deleted file mode 100644
index 3ce4590c1..000000000
--- a/yocto-poky/bitbake/lib/bb/ui/puccho.py
+++ /dev/null
@@ -1,425 +0,0 @@
-#
-# BitBake Graphical GTK User Interface
-#
-# Copyright (C) 2008 Intel Corporation
-#
-# Authored by Rob Bradford <rob@linux.intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-import gtk
-import gobject
-import gtk.glade
-import threading
-import urllib2
-import os
-import contextlib
-
-from bb.ui.crumbs.buildmanager import BuildManager, BuildConfiguration
-from bb.ui.crumbs.buildmanager import BuildManagerTreeView
-
-from bb.ui.crumbs.runningbuild import RunningBuild, RunningBuildTreeView
-
-# The metadata loader is used by the BuildSetupDialog to download the
-# available options to populate the dialog
-class MetaDataLoader(gobject.GObject):
- """ This class provides the mechanism for loading the metadata (the
- fetching and parsing) from a given URL. The metadata encompasses details
- on what machines are available. The distribution and images available for
- the machine and the the uris to use for building the given machine."""
- __gsignals__ = {
- 'success' : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- ()),
- 'error' : (gobject.SIGNAL_RUN_LAST,
- gobject.TYPE_NONE,
- (gobject.TYPE_STRING,))
- }
-
- # We use these little helper functions to ensure that we take the gdk lock
- # when emitting the signal. These functions are called as idles (so that
- # they happen in the gtk / main thread's main loop.
- def emit_error_signal (self, remark):
- gtk.gdk.threads_enter()
- self.emit ("error", remark)
- gtk.gdk.threads_leave()
-
- def emit_success_signal (self):
- gtk.gdk.threads_enter()
- self.emit ("success")
- gtk.gdk.threads_leave()
-
- def __init__ (self):
- gobject.GObject.__init__ (self)
-
- class LoaderThread(threading.Thread):
- """ This class provides an asynchronous loader for the metadata (by
- using threads and signals). This is useful since the metadata may be
- at a remote URL."""
- class LoaderImportException (Exception):
- pass
-
- def __init__(self, loader, url):
- threading.Thread.__init__ (self)
- self.url = url
- self.loader = loader
-
- def run (self):
- result = {}
- try:
- with contextlib.closing (urllib2.urlopen (self.url)) as f:
- # Parse the metadata format. The format is....
- # <machine>;<default distro>|<distro>...;<default image>|<image>...;<type##url>|...
- for line in f:
- components = line.split(";")
- if (len (components) < 4):
- raise MetaDataLoader.LoaderThread.LoaderImportException
- machine = components[0]
- distros = components[1].split("|")
- images = components[2].split("|")
- urls = components[3].split("|")
-
- result[machine] = (distros, images, urls)
-
- # Create an object representing this *potential*
- # configuration. It can become concrete if the machine, distro
- # and image are all chosen in the UI
- configuration = BuildConfiguration()
- configuration.metadata_url = self.url
- configuration.machine_options = result
- self.loader.configuration = configuration
-
- # Emit that we've actually got a configuration
- gobject.idle_add (MetaDataLoader.emit_success_signal,
- self.loader)
-
- except MetaDataLoader.LoaderThread.LoaderImportException as e:
- gobject.idle_add (MetaDataLoader.emit_error_signal, self.loader,
- "Repository metadata corrupt")
- except Exception as e:
- gobject.idle_add (MetaDataLoader.emit_error_signal, self.loader,
- "Unable to download repository metadata")
- print(e)
-
- def try_fetch_from_url (self, url):
- # Try and download the metadata. Firing a signal if successful
- thread = MetaDataLoader.LoaderThread(self, url)
- thread.start()
-
-class BuildSetupDialog (gtk.Dialog):
- RESPONSE_BUILD = 1
-
- # A little helper method that just sets the states on the widgets based on
- # whether we've got good metadata or not.
- def set_configurable (self, configurable):
- if (self.configurable == configurable):
- return
-
- self.configurable = configurable
- for widget in self.conf_widgets:
- widget.set_sensitive (configurable)
-
- if not configurable:
- self.machine_combo.set_active (-1)
- self.distribution_combo.set_active (-1)
- self.image_combo.set_active (-1)
-
- # GTK widget callbacks
- def refresh_button_clicked (self, button):
- # Refresh button clicked.
-
- url = self.location_entry.get_chars (0, -1)
- self.loader.try_fetch_from_url(url)
-
- def repository_entry_editable_changed (self, entry):
- if (len (entry.get_chars (0, -1)) > 0):
- self.refresh_button.set_sensitive (True)
- else:
- self.refresh_button.set_sensitive (False)
- self.clear_status_message()
-
- # If we were previously configurable we are no longer since the
- # location entry has been changed
- self.set_configurable (False)
-
- def machine_combo_changed (self, combobox):
- active_iter = combobox.get_active_iter()
-
- if not active_iter:
- return
-
- model = combobox.get_model()
-
- if model:
- chosen_machine = model.get (active_iter, 0)[0]
-
- (distros_model, images_model) = \
- self.loader.configuration.get_distro_and_images_models (chosen_machine)
-
- self.distribution_combo.set_model (distros_model)
- self.image_combo.set_model (images_model)
-
- # Callbacks from the loader
- def loader_success_cb (self, loader):
- self.status_image.set_from_icon_name ("info",
- gtk.ICON_SIZE_BUTTON)
- self.status_image.show()
- self.status_label.set_label ("Repository metadata successfully downloaded")
-
- # Set the models on the combo boxes based on the models generated from
- # the configuration that the loader has created
-
- # We just need to set the machine here, that then determines the
- # distro and image options. Cunning huh? :-)
-
- self.configuration = self.loader.configuration
- model = self.configuration.get_machines_model ()
- self.machine_combo.set_model (model)
-
- self.set_configurable (True)
-
- def loader_error_cb (self, loader, message):
- self.status_image.set_from_icon_name ("error",
- gtk.ICON_SIZE_BUTTON)
- self.status_image.show()
- self.status_label.set_text ("Error downloading repository metadata")
- for widget in self.conf_widgets:
- widget.set_sensitive (False)
-
- def clear_status_message (self):
- self.status_image.hide()
- self.status_label.set_label (
- """<i>Enter the repository location and press _Refresh</i>""")
-
- def __init__ (self):
- gtk.Dialog.__init__ (self)
-
- # Cancel
- self.add_button (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
-
- # Build
- button = gtk.Button ("_Build", None, True)
- image = gtk.Image ()
- image.set_from_stock (gtk.STOCK_EXECUTE, gtk.ICON_SIZE_BUTTON)
- button.set_image (image)
- self.add_action_widget (button, BuildSetupDialog.RESPONSE_BUILD)
- button.show_all ()
-
- # Pull in *just* the table from the Glade XML data.
- gxml = gtk.glade.XML (os.path.dirname(__file__) + "/crumbs/puccho.glade",
- root = "build_table")
- table = gxml.get_widget ("build_table")
- self.vbox.pack_start (table, True, False, 0)
-
- # Grab all the widgets that we need to turn on/off when we refresh...
- self.conf_widgets = []
- self.conf_widgets += [gxml.get_widget ("machine_label")]
- self.conf_widgets += [gxml.get_widget ("distribution_label")]
- self.conf_widgets += [gxml.get_widget ("image_label")]
- self.conf_widgets += [gxml.get_widget ("machine_combo")]
- self.conf_widgets += [gxml.get_widget ("distribution_combo")]
- self.conf_widgets += [gxml.get_widget ("image_combo")]
-
- # Grab the status widgets
- self.status_image = gxml.get_widget ("status_image")
- self.status_label = gxml.get_widget ("status_label")
-
- # Grab the refresh button and connect to the clicked signal
- self.refresh_button = gxml.get_widget ("refresh_button")
- self.refresh_button.connect ("clicked", self.refresh_button_clicked)
-
- # Grab the location entry and connect to editable::changed
- self.location_entry = gxml.get_widget ("location_entry")
- self.location_entry.connect ("changed",
- self.repository_entry_editable_changed)
-
- # Grab the machine combo and hook onto the changed signal. This then
- # allows us to populate the distro and image combos
- self.machine_combo = gxml.get_widget ("machine_combo")
- self.machine_combo.connect ("changed", self.machine_combo_changed)
-
- # Setup the combo
- cell = gtk.CellRendererText()
- self.machine_combo.pack_start(cell, True)
- self.machine_combo.add_attribute(cell, 'text', 0)
-
- # Grab the distro and image combos. We need these to populate with
- # models once the machine is chosen
- self.distribution_combo = gxml.get_widget ("distribution_combo")
- cell = gtk.CellRendererText()
- self.distribution_combo.pack_start(cell, True)
- self.distribution_combo.add_attribute(cell, 'text', 0)
-
- self.image_combo = gxml.get_widget ("image_combo")
- cell = gtk.CellRendererText()
- self.image_combo.pack_start(cell, True)
- self.image_combo.add_attribute(cell, 'text', 0)
-
- # Put the default descriptive text in the status box
- self.clear_status_message()
-
- # Mark as non-configurable, this is just greys out the widgets the
- # user can't yet use
- self.configurable = False
- self.set_configurable(False)
-
- # Show the table
- table.show_all ()
-
- # The loader and some signals connected to it to update the status
- # area
- self.loader = MetaDataLoader()
- self.loader.connect ("success", self.loader_success_cb)
- self.loader.connect ("error", self.loader_error_cb)
-
- def update_configuration (self):
- """ A poorly named function but it updates the internal configuration
- from the widgets. This can make that configuration concrete and can
- thus be used for building """
- # Extract the chosen machine from the combo
- model = self.machine_combo.get_model()
- active_iter = self.machine_combo.get_active_iter()
- if (active_iter):
- self.configuration.machine = model.get(active_iter, 0)[0]
-
- # Extract the chosen distro from the combo
- model = self.distribution_combo.get_model()
- active_iter = self.distribution_combo.get_active_iter()
- if (active_iter):
- self.configuration.distro = model.get(active_iter, 0)[0]
-
- # Extract the chosen image from the combo
- model = self.image_combo.get_model()
- active_iter = self.image_combo.get_active_iter()
- if (active_iter):
- self.configuration.image = model.get(active_iter, 0)[0]
-
-# This function operates to pull events out from the event queue and then push
-# them into the RunningBuild (which then drives the RunningBuild which then
-# pushes through and updates the progress tree view.)
-#
-# TODO: Should be a method on the RunningBuild class
-def event_handle_timeout (eventHandler, build):
- # Consume as many messages as we can ...
- event = eventHandler.getEvent()
- while event:
- build.handle_event (event)
- event = eventHandler.getEvent()
- return True
-
-class MainWindow (gtk.Window):
-
- # Callback that gets fired when the user hits a button in the
- # BuildSetupDialog.
- def build_dialog_box_response_cb (self, dialog, response_id):
- conf = None
- if (response_id == BuildSetupDialog.RESPONSE_BUILD):
- dialog.update_configuration()
- print(dialog.configuration.machine, dialog.configuration.distro, \
- dialog.configuration.image)
- conf = dialog.configuration
-
- dialog.destroy()
-
- if conf:
- self.manager.do_build (conf)
-
- def build_button_clicked_cb (self, button):
- dialog = BuildSetupDialog ()
-
- # For some unknown reason Dialog.run causes nice little deadlocks ... :-(
- dialog.connect ("response", self.build_dialog_box_response_cb)
- dialog.show()
-
- def __init__ (self):
- gtk.Window.__init__ (self)
-
- # Pull in *just* the main vbox from the Glade XML data and then pack
- # that inside the window
- gxml = gtk.glade.XML (os.path.dirname(__file__) + "/crumbs/puccho.glade",
- root = "main_window_vbox")
- vbox = gxml.get_widget ("main_window_vbox")
- self.add (vbox)
-
- # Create the tree views for the build manager view and the progress view
- self.build_manager_view = BuildManagerTreeView()
- self.running_build_view = RunningBuildTreeView()
-
- # Grab the scrolled windows that we put the tree views into
- self.results_scrolledwindow = gxml.get_widget ("results_scrolledwindow")
- self.progress_scrolledwindow = gxml.get_widget ("progress_scrolledwindow")
-
- # Put the tree views inside ...
- self.results_scrolledwindow.add (self.build_manager_view)
- self.progress_scrolledwindow.add (self.running_build_view)
-
- # Hook up the build button...
- self.build_button = gxml.get_widget ("main_toolbutton_build")
- self.build_button.connect ("clicked", self.build_button_clicked_cb)
-
-# I'm not very happy about the current ownership of the RunningBuild. I have
-# my suspicions that this object should be held by the BuildManager since we
-# care about the signals in the manager
-
-def running_build_succeeded_cb (running_build, manager):
- # Notify the manager that a build has succeeded. This is necessary as part
- # of the 'hack' that we use for making the row in the model / view
- # representing the ongoing build change into a row representing the
- # completed build. Since we know only one build can be running a time then
- # we can handle this.
-
- # FIXME: Refactor all this so that the RunningBuild is owned by the
- # BuildManager. It can then hook onto the signals directly and drive
- # interesting things it cares about.
- manager.notify_build_succeeded ()
- print("build succeeded")
-
-def running_build_failed_cb (running_build, manager):
- # As above
- print("build failed")
- manager.notify_build_failed ()
-
-def main (server, eventHandler):
- # Initialise threading...
- gobject.threads_init()
- gtk.gdk.threads_init()
-
- main_window = MainWindow ()
- main_window.show_all ()
-
- # Set up the build manager stuff in general
- builds_dir = os.path.join (os.getcwd(), "results")
- manager = BuildManager (server, builds_dir)
- main_window.build_manager_view.set_model (manager.model)
-
- # Do the running build setup
- running_build = RunningBuild ()
- main_window.running_build_view.set_model (running_build.model)
- running_build.connect ("build-succeeded", running_build_succeeded_cb,
- manager)
- running_build.connect ("build-failed", running_build_failed_cb, manager)
-
- # We need to save the manager into the MainWindow so that the toolbar
- # button can use it.
- # FIXME: Refactor ?
- main_window.manager = manager
-
- # Use a timeout function for probing the event queue to find out if we
- # have a message waiting for us.
- gobject.timeout_add (200,
- event_handle_timeout,
- eventHandler,
- running_build)
-
- gtk.main()
diff --git a/yocto-poky/bitbake/lib/bb/ui/toasterui.py b/yocto-poky/bitbake/lib/bb/ui/toasterui.py
index 3d261503e..6bf4c1f03 100644
--- a/yocto-poky/bitbake/lib/bb/ui/toasterui.py
+++ b/yocto-poky/bitbake/lib/bb/ui/toasterui.py
@@ -92,6 +92,43 @@ def _close_build_log(build_log):
build_log.close()
logger.removeHandler(build_log)
+_evt_list = [
+ "bb.build.TaskBase",
+ "bb.build.TaskFailed",
+ "bb.build.TaskFailedSilent",
+ "bb.build.TaskStarted",
+ "bb.build.TaskSucceeded",
+ "bb.command.CommandCompleted",
+ "bb.command.CommandExit",
+ "bb.command.CommandFailed",
+ "bb.cooker.CookerExit",
+ "bb.event.BuildCompleted",
+ "bb.event.BuildStarted",
+ "bb.event.CacheLoadCompleted",
+ "bb.event.CacheLoadProgress",
+ "bb.event.CacheLoadStarted",
+ "bb.event.ConfigParsed",
+ "bb.event.DepTreeGenerated",
+ "bb.event.LogExecTTY",
+ "bb.event.MetadataEvent",
+ "bb.event.MultipleProviders",
+ "bb.event.NoProvider",
+ "bb.event.ParseCompleted",
+ "bb.event.ParseProgress",
+ "bb.event.RecipeParsed",
+ "bb.event.SanityCheck",
+ "bb.event.SanityCheckPassed",
+ "bb.event.TreeDataPreparationCompleted",
+ "bb.event.TreeDataPreparationStarted",
+ "bb.runqueue.runQueueTaskCompleted",
+ "bb.runqueue.runQueueTaskFailed",
+ "bb.runqueue.runQueueTaskSkipped",
+ "bb.runqueue.runQueueTaskStarted",
+ "bb.runqueue.sceneQueueTaskCompleted",
+ "bb.runqueue.sceneQueueTaskFailed",
+ "bb.runqueue.sceneQueueTaskStarted",
+ "logging.LogRecord"]
+
def main(server, eventHandler, params):
# set to a logging.FileHandler instance when a build starts;
# see _open_build_log()
@@ -115,6 +152,11 @@ def main(server, eventHandler, params):
console.setFormatter(formatter)
logger.addHandler(console)
logger.setLevel(logging.INFO)
+ llevel, debug_domains = bb.msg.constructLogOptions()
+ result, error = server.runCommand(["setEventMask", server.getEventHandle(), llevel, debug_domains, _evt_list])
+ if not result or error:
+ logger.error("can't set event mask: %s", error)
+ return 1
# verify and warn
build_history_enabled = True
@@ -125,8 +167,23 @@ def main(server, eventHandler, params):
build_history_enabled = False
if not params.observe_only:
- logger.error("ToasterUI can only work in observer mode")
- return 1
+ params.updateFromServer(server)
+ params.updateToServer(server, os.environ.copy())
+ cmdline = params.parseActions()
+ if not cmdline:
+ print("Nothing to do. Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.")
+ return 1
+ if 'msg' in cmdline and cmdline['msg']:
+ logger.error(cmdline['msg'])
+ return 1
+
+ ret, error = server.runCommand(cmdline['action'])
+ if error:
+ logger.error("Command '%s' failed: %s" % (cmdline, error))
+ return 1
+ elif ret != True:
+ logger.error("Command '%s' failed: returned %s" % (cmdline, ret))
+ return 1
# set to 1 when toasterui needs to shut down
main.shutdown = 0
@@ -138,7 +195,8 @@ def main(server, eventHandler, params):
taskfailures = []
first = True
- buildinfohelper = BuildInfoHelper(server, build_history_enabled)
+ buildinfohelper = BuildInfoHelper(server, build_history_enabled,
+ os.getenv('TOASTER_BRBE'))
# write our own log files into bitbake's log directory;
# we're only interested in the path to the parent directory of
@@ -182,12 +240,11 @@ def main(server, eventHandler, params):
continue
if isinstance(event, bb.event.BuildStarted):
- # command-line builds don't fire a ParseStarted event,
- # so we have to start the log file for those on BuildStarted instead
if not (build_log and build_log_file_path):
build_log, build_log_file_path = _open_build_log(log_dir)
buildinfohelper.store_started_build(event, build_log_file_path)
+ continue
if isinstance(event, (bb.build.TaskStarted, bb.build.TaskSucceeded, bb.build.TaskFailedSilent)):
buildinfohelper.update_and_store_task(event)
@@ -315,28 +372,30 @@ def main(server, eventHandler, params):
# update the build info helper on BuildCompleted, not on CommandXXX
buildinfohelper.update_build_information(event, errors, warnings, taskfailures)
+
+ brbe = buildinfohelper.brbe
buildinfohelper.close(errorcode)
- # mark the log output; controllers may kill the toasterUI after seeing this log
- logger.info("ToasterUI build done 1, brbe: %s", buildinfohelper.brbe )
# we start a new build info
- if buildinfohelper.brbe is not None:
- logger.debug("ToasterUI under BuildEnvironment management - exiting after the build")
- server.terminateServer()
- else:
+ if params.observe_only:
logger.debug("ToasterUI prepared for new build")
errors = 0
warnings = 0
taskfailures = []
buildinfohelper = BuildInfoHelper(server, build_history_enabled)
+ else:
+ main.shutdown = 1
- logger.info("ToasterUI build done 2")
+ logger.info("ToasterUI build done, brbe: %s", brbe)
continue
if isinstance(event, (bb.command.CommandCompleted,
bb.command.CommandFailed,
bb.command.CommandExit)):
- errorcode = 0
+ if params.observe_only:
+ errorcode = 0
+ else:
+ main.shutdown = 1
continue
@@ -357,6 +416,10 @@ def main(server, eventHandler, params):
buildinfohelper.update_artifact_image_file(event)
elif event.type == "LicenseManifestPath":
buildinfohelper.store_license_manifest_path(event)
+ elif event.type == "SetBRBE":
+ buildinfohelper.brbe = buildinfohelper._get_data_from_event(event)
+ elif event.type == "OSErrorException":
+ logger.error(event)
else:
logger.error("Unprocessed MetadataEvent %s ", str(event))
continue
@@ -366,19 +429,6 @@ def main(server, eventHandler, params):
main.shutdown = 1
continue
- # ignore
- if isinstance(event, (bb.event.BuildBase,
- bb.event.StampUpdate,
- bb.event.RecipePreFinalise,
- bb.runqueue.runQueueEvent,
- bb.runqueue.runQueueExitWait,
- bb.event.OperationProgress,
- bb.command.CommandFailed,
- bb.command.CommandExit,
- bb.command.CommandCompleted,
- bb.event.ReachableStamps)):
- continue
-
if isinstance(event, bb.event.DepTreeGenerated):
buildinfohelper.store_dependency_information(event)
continue
@@ -399,13 +449,6 @@ def main(server, eventHandler, params):
exception_data = traceback.format_exc()
logger.error("%s\n%s" , e, exception_data)
- _, _, tb = sys.exc_info()
- if tb is not None:
- curr = tb
- while curr is not None:
- logger.error("Error data dump %s\n%s\n" , traceback.format_tb(curr,1), pformat(curr.tb_frame.f_locals))
- curr = curr.tb_next
-
# save them to database, if possible; if it fails, we already logged to console.
try:
buildinfohelper.store_log_exception("%s\n%s" % (str(e), exception_data))
diff --git a/yocto-poky/bitbake/lib/bb/ui/uievent.py b/yocto-poky/bitbake/lib/bb/ui/uievent.py
index 7fc50c759..df093c53c 100644
--- a/yocto-poky/bitbake/lib/bb/ui/uievent.py
+++ b/yocto-poky/bitbake/lib/bb/ui/uievent.py
@@ -24,7 +24,7 @@ server and queue them for the UI to process. This process must be used to avoid
client/server deadlocks.
"""
-import socket, threading, pickle
+import socket, threading, pickle, collections
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
class BBUIEventQueue:
@@ -44,27 +44,32 @@ class BBUIEventQueue:
server.register_function( self.send_event, "event.sendpickle" )
server.socket.settimeout(1)
- self.EventHandler = None
- count_tries = 0
+ self.EventHandle = None
# the event handler registration may fail here due to cooker being in invalid state
# this is a transient situation, and we should retry a couple of times before
# giving up
- while self.EventHandler == None and count_tries < 5:
- self.EventHandle = self.BBServer.registerEventHandler(self.host, self.port)
+ for count_tries in range(5):
+ ret = self.BBServer.registerEventHandler(self.host, self.port)
- if (self.EventHandle != None):
+ if isinstance(ret, collections.Iterable):
+ self.EventHandle, error = ret
+ else:
+ self.EventHandle = ret
+ error = ""
+
+ if self.EventHandle != None:
break
- bb.warn("Could not register UI event handler %s:%d, retry" % (self.host, self.port))
- count_tries += 1
+ errmsg = "Could not register UI event handler. Error: %s, host %s, "\
+ "port %d" % (error, self.host, self.port)
+ bb.warn("%s, retry" % errmsg)
+
import time
time.sleep(1)
-
-
- if self.EventHandle == None:
- raise Exception("Could not register UI event handler")
+ else:
+ raise Exception(errmsg)
self.server = server
@@ -105,6 +110,7 @@ class BBUIEventQueue:
def startCallbackHandler(self):
self.server.timeout = 1
+ bb.utils.set_process_name("UIEventQueue")
while not self.server.quit:
try:
self.server.handle_request()
diff --git a/yocto-poky/bitbake/lib/bb/ui/uihelper.py b/yocto-poky/bitbake/lib/bb/ui/uihelper.py
index a703387fb..db70b763f 100644
--- a/yocto-poky/bitbake/lib/bb/ui/uihelper.py
+++ b/yocto-poky/bitbake/lib/bb/ui/uihelper.py
@@ -57,44 +57,3 @@ class BBUIHelper:
self.needUpdate = False
return (self.running_tasks, self.failed_tasks)
- def findServerDetails(self):
- import sys
- import optparse
- from bb.server.xmlrpc import BitbakeServerInfo, BitBakeServerConnection
- host = ""
- port = 0
- bind = ""
- parser = optparse.OptionParser(
- usage = """%prog -H host -P port -B bindaddr""")
-
- parser.add_option("-H", "--host", help = "Bitbake server's IP address",
- action = "store", dest = "host", default = None)
-
- parser.add_option("-P", "--port", help = "Bitbake server's Port number",
- action = "store", dest = "port", default = None)
-
- parser.add_option("-B", "--bind", help = "Hob2 local bind address",
- action = "store", dest = "bind", default = None)
-
- options, args = parser.parse_args(sys.argv)
- for key, val in options.__dict__.items():
- if key == 'host' and val:
- host = val
- elif key == 'port' and val:
- port = int(val)
- elif key == 'bind' and val:
- bind = val
-
- if not host or not port or not bind:
- parser.print_usage()
- sys.exit(1)
-
- serverinfo = BitbakeServerInfo(host, port)
- clientinfo = (bind, 0)
- connection = BitBakeServerConnection(serverinfo, clientinfo)
-
- server = connection.connection
- eventHandler = connection.events
-
- return server, eventHandler, host, bind
-
OpenPOWER on IntegriCloud