diff options
Diffstat (limited to 'yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py')
-rw-r--r-- | yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py | 903 |
1 files changed, 903 insertions, 0 deletions
diff --git a/yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py b/yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py new file mode 100644 index 0000000000..50df156f4d --- /dev/null +++ b/yocto-poky/bitbake/lib/bb/ui/crumbs/hoblistmodel.py @@ -0,0 +1,903 @@ +# +# 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__ |