Skip to contentSkip to conversation

Hob related fixes

PATCH In review Shane Wang 5 participants 81 messages Feb 29, 2012 – Mar 8, 2012 Arm STM32

lore
Share & tools
lore

Shane Wang

author
#0 lore raw

cover Hob related fixes

The following patches are going to fix the following problems:

* Enable HobNotebook to make notebook more like the design video;
* Improve and enhance the GUI;
* Rebase the patches Josh has sent out before with the title "Hob tweaks";
* Address some tricky issues we found in the bitbake;
* Revise Hob according to the comments on the previous patch set;
* Fix some bugs we found when testing Hob;
* and some temporary walkarounds we have to find a way to solve in Hob or in the bitbake later.

The following changes since commit 927bec5f72230be4f2452d9ef5a747b2c00cb781:

bitbake.conf: Create a new filter variable BB_HASHCONFIG_WHITELIST (2012-02-27 20:10:41 +0000)

are available in the git repository at:
git://git.pokylinux.org/poky-contrib shane/hob2-v0.68
http://git.pokylinux.org/cgit.cgi/poky-contrib/log/?h=shane/hob2-v0.68

Dongxiao Xu (10):
command.py: remove the resolve parameter in generateTargetsTree cooker.py: Fix a bug due to variable name
cooker: fix calculating of depends and rdepends Hob(crumbs/hoblistmodel.py): Fix recipe's populate() function Hob(crumbs/hoblistmodel.py): Add mapping for rprovides and pkg
Hob: Add an extra 50M space if zypper is selected
Hob: add "OK" button to "BinbDialog"
Hob: Fix pressing "stop" build
runqueue.py: initialize rqexe at RunQueue's init function
Hob: Disable the handling of "NoProvider" event

Shane Wang (22):
Hob: make HobViewTable more general in hob and make the image
selection dialog and the image details page reuse it.
Hob: avoid the image selection dialog to walk through all directories
and its sub-directories, when users click "My images".
Hob: cleanup those class methods in HobWidget
Hob: fixed the issue in the brought-in-by dialog.
Hob: include hddimg and iso into image types.
Hob: implement a self-defined notebook visual component for Hob
Hob: use HobNotebook to enable a notebook in build details page
Hob: image configuration page doesn't need dialogs any more
Hob: fix a bug in builder.configuration.curr_mach
Hob: add ignore_all_errors to avoid showing error dialog multiple
times
Hob: make the image configuration page not to flash the progress bar
Hob: enable indicators on the "Included" tab in the recipe selection
page and the package selection page
crumbs: Factor common dialogue configuration out crumbs/builder: use the name Hob consistently
crumbs: move towards more standard dialogue spacing
crumbs: fix button order in several dialogues
hig: try to avoid setting explicit dialogue sizes crumbs/hig: tweak UI and layout of LayerSelectionDialog Hob(crumbs/builder.py): remove the code commented out in the
builder.py
Hob: fix a bug that the image size is shown incorrectly in the image
details page.
Hob: allow users to setup the proxy Hob(crumbs/builder.py): adjust the main window's position and ignore

    the case lower than 1024x768.
 bitbake/lib/bb/command.py                          |   14 +-
 bitbake/lib/bb/cooker.py                           |   74 +-
 bitbake/lib/bb/runqueue.py                         |    5 +
 bitbake/lib/bb/ui/crumbs/builddetailspage.py       |   40 +-
 bitbake/lib/bb/ui/crumbs/builder.py                |  138 ++-
 bitbake/lib/bb/ui/crumbs/hig.py                    |  672 ++++++++++--
 bitbake/lib/bb/ui/crumbs/hobcolor.py               |    1 +
 bitbake/lib/bb/ui/crumbs/hobeventhandler.py        |   48 +-
 bitbake/lib/bb/ui/crumbs/hoblistmodel.py           |   60 +-
 bitbake/lib/bb/ui/crumbs/hobwidget.py              | 1135 ++++++++------------
 bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py |   34 +-
 bitbake/lib/bb/ui/crumbs/imagedetailspage.py       |   93 ++-
 bitbake/lib/bb/ui/crumbs/packageselectionpage.py   |   56 +-
 bitbake/lib/bb/ui/crumbs/recipeselectionpage.py    |   55 +-
 bitbake/lib/bb/ui/crumbs/runningbuild.py           |   69 ++
 15 files changed, 1457 insertions(+), 1037 deletions(-)
Signature · 1 line
1.7.6
author
#2 lore raw

PATCH 2/32 Hob: avoid the image selection dialog to walk through all directories and its sub-directories, when users click "My images".

In reply to Shane Wang

The current implementation of the image selection dialog walks through all directories and its sub-directories, when users click "My images" to choose a directory. If the directory is /, the system becomes slow. This patch is to avoid walking through all directories but the child directories only, given a directory.

---
 bitbake/lib/bb/ui/crumbs/hig.py |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +8 -4
index 8f4f7cd..9aa6fdf 100644
@@ -582,6 +582,7 @@ class ImageSelectionDialog (gtk.Dialog):
 
         self.image_folder = image_folder
         self.image_types  = image_types
+        self.image_list = []
         self.image_names = []
 
         # create visual elements on the dialog
@@ -645,13 +646,17 @@ class ImageSelectionDialog (gtk.Dialog):
         dialog.destroy()
 
     def fill_image_store(self):
+        self.image_list = []
         self.image_store.clear()
         imageset = set()
         for root, dirs, files in os.walk(self.image_folder):
+            # ignore the sub directories
+            dirs[:] = []
             for f in files:
                 for image_type in self.image_types:
                     if f.endswith('.' + image_type):
                         imageset.add(f.rsplit('.' + image_type)[0])
+                        self.image_list.append(f)
         
         for image in imageset:
             self.image_store.set(self.image_store.append(), 0, image, 1, False)
@@ -665,9 +670,8 @@ class ImageSelectionDialog (gtk.Dialog):
             while iter:
                 path = self.image_store.get_path(iter)
                 if self.image_store[path][1]:
-                    for root, dirs, files in os.walk(self.image_folder):
-                        for f in files:
-                            if f.startswith(self.image_store[path][0] + '.'):
-                                self.image_names.append(f)
+                    for f in self.image_list:
+                        if f.startswith(self.image_store[path][0] + '.'):
+                            self.image_names.append(f)
                     break            
                 iter = self.image_store.iter_next(iter)
Signature · 1 line
1.7.6
author
#1 lore raw

PATCH 1/32 Hob: make HobViewTable more general in hob and make the image selection dialog and the image details page reuse it.

In reply to Shane Wang

This patch is to make the class HobViewTable more general as a tree view in Hob.
Now the recipe selection page and the package selection page are using it.
And we have tree views in the image selection dialog and the image details page, which used the class methods in HobWidget to create the tree views. That is not good in OO.

So, make them reuse HobViewTable to create its instances.

---
 bitbake/lib/bb/ui/crumbs/hig.py                  |   37 +++++-
 bitbake/lib/bb/ui/crumbs/hobwidget.py            |  168 +++++++---------------
 bitbake/lib/bb/ui/crumbs/imagedetailspage.py     |   65 +++++++--
 bitbake/lib/bb/ui/crumbs/packageselectionpage.py |   28 +++--
 bitbake/lib/bb/ui/crumbs/recipeselectionpage.py  |   30 +++--
 5 files changed, 176 insertions(+), 152 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +33 -4
index 89dfe03..8f4f7cd 100644
@@ -28,7 +28,7 @@ import re
 import subprocess
 import shlex
 from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobWidget
+from bb.ui.crumbs.hobwidget import HobWidget, HobViewTable
 from bb.ui.crumbs.progressbar import HobProgressBar
 
 """
@@ -561,6 +561,21 @@ class LayerSelectionDialog (gtk.Dialog):
 
 class ImageSelectionDialog (gtk.Dialog):
 
+    __columns__ = [{
+            'col_name' : 'Image name',
+            'col_id'   : 0,
+            'col_style': 'text',
+            'col_min'  : 400,
+            'col_max'  : 400
+        }, {
+            'col_name' : 'Select',
+            'col_id'   : 1,
+            'col_style': 'radio toggle',
+            'col_min'  : 160,
+            'col_max'  : 160
+    }]
+
+
     def __init__(self, image_folder, image_types, title, parent, flags, buttons):
         super(ImageSelectionDialog, self).__init__(title, parent, flags, buttons)
         self.connect("response", self.response_cb)
@@ -596,11 +611,25 @@ class ImageSelectionDialog (gtk.Dialog):
         open_button.connect("clicked", self.select_path_cb, self, entry)
         table.attach(open_button, 9, 10, 0, 1)
 
-        imgtv_widget, self.imgsel_tv = HobWidget.gen_imgtv_widget(400, 160)
-        self.vbox.pack_start(imgtv_widget, expand=True, fill=True)
+        self.image_table = HobViewTable(self.__columns__)
+        self.image_table.connect("toggled", self.toggled_cb)
+        self.vbox.pack_start(self.image_table, expand=True, fill=True)
 
         self.show_all()
 
+    def toggled_cb(self, table, cell, path, columnid, tree):
+        model = tree.get_model()
+        if not model:
+            return
+        iter = model.get_iter_first()
+        while iter:
+            rowpath = model.get_path(iter)
+            model[rowpath][columnid] = False
+            iter = model.iter_next(iter)
+
+        model[path][columnid] = True
+
+        
     def select_path_cb(self, action, parent, entry):
         dialog = gtk.FileChooserDialog("", parent,
                                        gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
@@ -627,7 +656,7 @@ class ImageSelectionDialog (gtk.Dialog):
         for image in imageset:
             self.image_store.set(self.image_store.append(), 0, image, 1, False)
 
-        self.imgsel_tv.set_model(self.image_store)
+        self.image_table.set_model(self.image_store)
 
     def response_cb(self, dialog, response_id):
         self.image_names = []
bitbake/lib/bb/ui/crumbs/hobwidget.py +55 -113

205 lines not on this page · raw message

bitbake/lib/bb/ui/crumbs/imagedetailspage.py +53 -12

120 lines not on this page · raw message

bitbake/lib/bb/ui/crumbs/packageselectionpage.py +17 -11
index 8a8ab75..280d480 100755
@@ -51,7 +51,7 @@ class PackageSelectionPage (HobPage):
                       }, {
                        'col_name' : 'Included',
                        'col_id'   : PackageListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                        'col_min'  : 50,
                        'col_max'  : 50
                       }]
@@ -79,7 +79,7 @@ class PackageSelectionPage (HobPage):
                       }, {
                        'col_name' : 'Included',
                        'col_id'   : PackageListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                        'col_min'  : 50,
                        'col_max'  : 50
                      }]
@@ -111,9 +111,19 @@ class PackageSelectionPage (HobPage):
         # append the tab
         for i in range(len(self.pages)):
             columns = self.pages[i]['columns']
-            tab = HobViewTable(columns, self.reset_clicked_cb, self.table_toggled_cb)
+            tab = HobViewTable(columns)
             filter = self.pages[i]['filter']
-            tab.table_tree.set_model(self.package_model.tree_model(filter))
+            tab.set_model(self.package_model.tree_model(filter))
+            tab.connect("toggled", self.table_toggled_cb)
+            if self.pages[i]['name'] == "Included":
+                tab.connect("changed", self.tree_selection_cb)
+
+            reset_button = gtk.Button("Reset")
+            reset_button.connect("clicked", self.reset_clicked_cb)
+            hbox = gtk.HBox(False, 5)
+            hbox.pack_end(reset_button, expand=False, fill=False)
+            tab.pack_start(hbox, expand=False, fill=False)
+
             label = gtk.Label(self.pages[i]['name'])
             self.ins.append_page(tab, label)
             self.tables.append(tab)
@@ -124,11 +134,7 @@ class PackageSelectionPage (HobPage):
         self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
         # set the search entry for each table
         for tab in self.tables:
-            tab.table_tree.set_search_entry(self.topbar.search)
-
-        inctab_tree_view = self.tables[len(self.pages)-1].table_tree
-        inctab_tree_selection = inctab_tree_view.get_selection()
-        inctab_tree_selection.connect("changed", self.tree_selection_cb, inctab_tree_view)
+            tab.set_search_entry(0, self.topbar.search)
 
         # add all into the dialog
         self.box_group_area.add(self.grid)
@@ -155,7 +161,7 @@ class PackageSelectionPage (HobPage):
         self.back_button.connect("clicked", self.back_button_clicked_cb)
         button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, tree_selection, tree_view):
+    def tree_selection_cb(self, table, tree_selection, tree_view):
         tree_model = tree_view.get_model()
         path, column = tree_view.get_cursor()
         if not path or column == tree_view.get_column(2):
@@ -218,7 +224,7 @@ class PackageSelectionPage (HobPage):
 
         self.builder.window_sensitive(True)
 
-    def table_toggled_cb(self, cell, view_path, view_tree):
+    def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree):
         # Click to include a package
         self.builder.window_sensitive(False)
         view_model = view_tree.get_model()
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +18 -12
index 73b8a1e..93540b2 100755
@@ -56,7 +56,7 @@ class RecipeSelectionPage (HobPage):
                       }, {
                        'col_name' : 'Included',
                        'col_id'   : RecipeListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                        'col_min'  : 50,
                        'col_max'  : 50
                       }]
@@ -78,7 +78,7 @@ class RecipeSelectionPage (HobPage):
                       }, {
                        'col_name' : 'Included',
                        'col_id'   : RecipeListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                        'col_min'  : 50,
                        'col_max'  : 50
                       }]
@@ -101,7 +101,7 @@ class RecipeSelectionPage (HobPage):
                       }, {
                        'col_name' : 'Included',
                        'col_id'   : RecipeListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                        'col_min'  : 50,
                        'col_max'  : 50
                       }]
@@ -135,9 +135,19 @@ class RecipeSelectionPage (HobPage):
         # append the tabs in order
         for i in range(len(self.pages)):
             columns = self.pages[i]['columns']
-            tab = HobViewTable(columns, self.reset_clicked_cb, self.table_toggled_cb)
+            tab = HobViewTable(columns)
             filter = self.pages[i]['filter']
-            tab.table_tree.set_model(self.recipe_model.tree_model(filter))
+            tab.set_model(self.recipe_model.tree_model(filter))
+            tab.connect("toggled", self.table_toggled_cb)
+            if self.pages[i]['name'] == "Included":
+                tab.connect("changed", self.tree_selection_cb)
+
+            reset_button = gtk.Button("Reset")
+            reset_button.connect("clicked", self.reset_clicked_cb)
+            hbox = gtk.HBox(False, 5)
+            hbox.pack_end(reset_button, expand=False, fill=False)
+            tab.pack_start(hbox, expand=False, fill=False)
+
             label = gtk.Label(self.pages[i]['name'])
             self.ins.append_page(tab, label)
             self.tables.append(tab)
@@ -148,11 +158,7 @@ class RecipeSelectionPage (HobPage):
         self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
         # set the search entry for each table
         for tab in self.tables:
-            tab.table_tree.set_search_entry(self.topbar.search)
-
-        inctab_tree_view = self.tables[len(self.pages)-1].table_tree
-        inctab_tree_selection = inctab_tree_view.get_selection()
-        inctab_tree_selection.connect("changed", self.tree_selection_cb, inctab_tree_view)
+            tab.set_search_entry(0, self.topbar.search)
 
         # add all into the window
         self.box_group_area.add(self.grid)
@@ -179,7 +185,7 @@ class RecipeSelectionPage (HobPage):
         self.back_button.connect("clicked", self.back_button_clicked_cb)
         button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, tree_selection, tree_view):
+    def tree_selection_cb(self, table, tree_selection, tree_view):
         tree_model = tree_view.get_model()
         path, column = tree_view.get_cursor()
         if not path or column == tree_view.get_column(2):
@@ -213,7 +219,7 @@ class RecipeSelectionPage (HobPage):
 
         self.builder.window_sensitive(True)
 
-    def table_toggled_cb(self, cell, view_path, view_tree):
+    def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree):
         # Click to include a recipe
         self.builder.window_sensitive(False)
         view_model = view_tree.get_model()
Signature · 1 line
1.7.6
author
#11 lore raw

PATCH 5/32 Hob: include hddimg and iso into image types.

For image types, so far we don't include hddimg and iso. Then those files can not be deployed because they are filtered out in the image selection dialog. This patch is to include hddimg and iso (which are "live" in image types).

Again, we have a TODO in the code for the future, that is to retrieve image types from the bitbake server instead of to use the walkaround.

---
 bitbake/lib/bb/ui/crumbs/builder.py         |    4 ++--
 bitbake/lib/bb/ui/crumbs/hig.py             |    9 +++++----
 bitbake/lib/bb/ui/crumbs/hobeventhandler.py |    9 ++++-----
 bitbake/lib/bb/ui/crumbs/hobwidget.py       |   27 +++++++++++++++++++++++++++
 4 files changed, 38 insertions(+), 11 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +2 -2
index 0071673..eb38819 100755
@@ -758,8 +758,8 @@ class Builder(gtk.Window):
             flags = gtk.DIALOG_MODAL
                     | gtk.DIALOG_DESTROY_WITH_PARENT
                     | gtk.DIALOG_NO_SEPARATOR,
-            buttons = ("Close", gtk.RESPONSE_NO,
-                       "Make usb image", gtk.RESPONSE_YES))
+            buttons = ("Make usb image", gtk.RESPONSE_YES,
+                       "Close", gtk.RESPONSE_NO))
         response = dialog.run()
         dialog.destroy()
 
bitbake/lib/bb/ui/crumbs/hig.py +5 -4
index 74f4f7b..cbad899 100644
@@ -28,7 +28,7 @@ import re
 import subprocess
 import shlex
 from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewTable
+from bb.ui.crumbs.hobwidget import hcc, HobViewTable
 from bb.ui.crumbs.progressbar import HobProgressBar
 
 """
@@ -1083,9 +1083,10 @@ class ImageSelectionDialog (gtk.Dialog):
             dirs[:] = []
             for f in files:
                 for image_type in self.image_types:
-                    if f.endswith('.' + image_type):
-                        imageset.add(f.rsplit('.' + image_type)[0])
-                        self.image_list.append(f)
+                    for real_image_type in hcc.SUPPORTED_IMAGE_TYPES[image_type]:
+                        if f.endswith('.' + real_image_type):
+                            imageset.add(f.rsplit('.' + real_image_type)[0])
+                            self.image_list.append(f)
         
         for image in imageset:
             self.image_store.set(self.image_store.append(), 0, image, 1, False)
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +4 -5
index b071ad4..2bf4ed8 100644
@@ -22,6 +22,7 @@
 import gobject
 import logging
 from bb.ui.crumbs.runningbuild import RunningBuild
+from bb.ui.crumbs.hobwidget import hcc
 
 class HobHandler(gobject.GObject):
 
@@ -450,10 +451,8 @@ class HobHandler(gobject.GObject):
         params["incompat_license"] = self.server.runCommand(["getVariable", "INCOMPATIBLE_LICENSE"]) or ""
         params["sdk_machine"] = self.server.runCommand(["getVariable", "SDKMACHINE"]) or self.server.runCommand(["getVariable", "SDK_ARCH"]) or ""
 
-        #params["image_types"] = self.server.runCommand(["getVariable", "IMAGE_TYPES"]) or ""
         params["image_fstypes"] = self.server.runCommand(["getVariable", "IMAGE_FSTYPES"]) or ""
-        """
-        A workaround
-        """
-        params["image_types"] = "jffs2 sum.jffs2 cramfs ext2 ext2.gz ext2.bz2 ext3 ext3.gz ext2.lzma btrfs live squashfs squashfs-lzma ubi tar tar.gz tar.bz2 tar.xz cpio cpio.gz cpio.xz cpio.lzma"
+
+        # walkaround
+        params["image_types"] = " ".join(hcc.SUPPORTED_IMAGE_TYPES.keys()).lstrip(" ")
         return params
bitbake/lib/bb/ui/crumbs/hobwidget.py +27 -0
index 664bf25..9afbfdb 100644
@@ -50,6 +50,33 @@ class hic:
     ICON_INDI_CONFIRM_FILE        = os.path.join(HOB_ICON_BASE_DIR, ('indicators/confirmation.png'))
     ICON_INDI_ERROR_FILE          = os.path.join(HOB_ICON_BASE_DIR, ('indicators/error.png'))
 
+class hcc:
+
+    SUPPORTED_IMAGE_TYPES = {
+        "jffs2"         : ["jffs2"],
+        "sum.jffs2"     : ["sum.jffs2"],
+        "cramfs"        : ["cramfs"],
+        "ext2"          : ["ext2"],
+        "ext2.gz"       : ["ext2.gz"],
+        "ext2.bz2"      : ["ext2.bz2"],
+        "ext3"          : ["ext3"],
+        "ext3.gz"       : ["ext3.gz"],
+        "ext2.lzma"     : ["ext2.lzma"],
+        "btrfs"         : ["btrfs"],
+        "live"          : ["hddimg", "iso"],
+        "squashfs"      : ["squashfs"],
+        "squashfs-lzma" : ["squashfs-lzma"],
+        "ubi"           : ["ubi"],
+        "tar"           : ["tar"],
+        "tar.gz"        : ["tar.gz"],
+        "tar.bz2"       : ["tar.bz2"],
+        "tar.xz"        : ["tar.xz"],
+        "cpio"          : ["cpio"],
+        "cpio.gz"       : ["cpio.gz"],
+        "cpio.xz"       : ["cpio.xz"],
+        "cpio.lzma"     : ["cpio.lzma"],
+    }
+
 class HobViewTable (gtk.VBox):
     """
     A VBox to contain the table for different recipe views and package view
Signature · 1 line
1.7.6
author
#20 lore raw

PATCH 8/32 Hob: image configuration page doesn't need dialogs any more

In reply to Shane Wang

The dialog references are all in builder.py. We remove the useless "import" in image configuration page.

---
 bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)
bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py +0 -3
index d3a9ffd..4083360 100644
@@ -28,9 +28,6 @@ from bb.ui.crumbs.hobwidget import hic, HobXpmLabelButtonBox
 from bb.ui.crumbs.hoblistmodel import RecipeListModel
 from bb.ui.crumbs.hobpages import HobPage
 
-from bb.ui.crumbs.hig import CrumbsDialog, BinbDialog, \
-                             AdvancedSettingDialog, LayerSelectionDialog
-
 #
 # ImageConfigurationPage
 #
Signature · 1 line
1.7.6
author
#4 lore raw

PATCH 3/32 Hob: cleanup those class methods in HobWidget

In reply to Shane Wang

Some dialogs like advanced settings dialog, and layer selection dialog are using the class methods in HobWidget to create widgets for themselves, which is not a good design for OO.

Clean up the code, and split the functions into the separate classes which use them actually. Finally, remove the class HobWidget.

---
 bitbake/lib/bb/ui/crumbs/hig.py                 |  486 +++++++++++++++++++++--
 bitbake/lib/bb/ui/crumbs/hobwidget.py           |  465 ----------------------
 bitbake/lib/bb/ui/crumbs/recipeselectionpage.py |    2 +-
 3 files changed, 460 insertions(+), 493 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +459 -27
index 9aa6fdf..2de7b2a 100644
@@ -28,7 +28,7 @@ import re
 import subprocess
 import shlex
 from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobWidget, HobViewTable
+from bb.ui.crumbs.hobwidget import HobViewTable
 from bb.ui.crumbs.progressbar import HobProgressBar
 
 """
@@ -105,6 +105,317 @@ class BinbDialog(gtk.Dialog):
 #
 class AdvancedSettingDialog (gtk.Dialog):
 
+    def gen_label_widget(self, content):
+        label = gtk.Label()
+        label.set_alignment(0, 0)
+        label.set_markup(content)
+        label.show()
+        return label
+
+    def gen_spinner_widget(self, content, lower, upper, tooltip=""):
+        hbox = gtk.HBox(False, 10)
+        adjust = gtk.Adjustment(value=content, lower=lower, upper=upper, step_incr=1)
+        spinner = gtk.SpinButton(adjustment=adjust, climb_rate=1, digits=0)
+
+        spinner.set_value(content)
+        hbox.pack_start(spinner, expand=False, fill=False)
+
+        image = gtk.Image()
+        image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
+        image.set_tooltip_text(tooltip)
+        hbox.pack_start(image, expand=False, fill=False)
+
+        hbox.show_all()
+        return hbox, spinner
+
+    def gen_combo_widget(self, curr_item, all_item, tooltip=""):
+        hbox = gtk.HBox(False, 10)
+        combo = gtk.combo_box_new_text()
+        hbox.pack_start(combo, expand=False, fill=False)
+
+        index = 0
+        for item in all_item or []:
+            combo.append_text(item)
+            if item == curr_item:
+                combo.set_active(index)
+            index += 1
+
+        image = gtk.Image()
+        image.show()
+        image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
+        image.set_tooltip_text(tooltip)
+        hbox.pack_start(image, expand=False, fill=False)
+
+        hbox.show_all()
+        return hbox, combo
+
+    def entry_widget_select_path_cb(self, action, parent, entry):
+        dialog = gtk.FileChooserDialog("", parent,
+                                       gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
+                                       (gtk.STOCK_OK, gtk.RESPONSE_YES,
+                                        gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+        response = dialog.run()
+        if response == gtk.RESPONSE_YES:
+            path = dialog.get_filename()
+            entry.set_text(path)
+
+        dialog.destroy()
+
+    def gen_entry_widget(self, split_model, content, parent, tooltip=""):
+        hbox = gtk.HBox(False, 10)
+        entry = gtk.Entry()
+        entry.set_text(content)
+
+        if split_model:
+            hbox.pack_start(entry, expand=True, fill=True)
+        else:
+            table = gtk.Table(1, 10, True)
+            hbox.pack_start(table, expand=True, fill=True)
+            table.attach(entry, 0, 9, 0, 1)
+            image = gtk.Image()
+            image.set_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)
+            open_button = gtk.Button()
+            open_button.set_image(image)
+            open_button.connect("clicked", self.entry_widget_select_path_cb, parent, entry)
+            table.attach(open_button, 9, 10, 0, 1)
+
+        image = gtk.Image()
+        image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
+        image.set_tooltip_text(tooltip)
+        hbox.pack_start(image, expand=False, fill=False)
+
+        hbox.show_all()
+        return hbox, entry
+
+    def pkgfmt_widget_sort_func(self, model, iter1, iter2, data):
+        val1 = model.get_value(iter1, 0)
+        val2 = model.get_value(iter2, 0)
+        inc1 = model.get_value(iter1, 2)
+        inc2 = model.get_value(iter2, 2)
+        if inc1 != inc2:
+            return inc2 - inc1
+        else:
+            return val1 - val2
+
+    def pkgfmt_widget_tree_selection_changed_cb(self, tree_selection, button1, button2):
+        (model, it) = tree_selection.get_selected()
+        inc = model.get_value(it, 2)
+        if inc:
+            button1.set_sensitive(True)
+            button2.set_sensitive(True)
+        else:
+            button1.set_sensitive(False)
+            button2.set_sensitive(False)
+
+    def pkgfmt_widget_up_clicked_cb(self, button, tree_selection):
+        (model, it) = tree_selection.get_selected()
+        if not it:
+            return
+        path = model.get_path(it)
+        if path[0] <= 0:
+            return
+
+        pre_it = model.get_iter_first()
+        if not pre_it:
+            return
+        else:
+            while model.iter_next(pre_it) :
+                if model.get_value(model.iter_next(pre_it), 1) != model.get_value(it, 1):
+                    pre_it = model.iter_next(pre_it)
+                else:
+                    break
+
+            cur_index = model.get_value(it, 0)
+            pre_index = cur_index
+            if pre_it:
+                model.set(pre_it, 0, pre_index)
+            cur_index = cur_index - 1
+            model.set(it, 0, cur_index)
+
+    def pkgfmt_widget_down_clicked_cb(self, button, tree_selection):
+        (model, it) = tree_selection.get_selected()
+        if not it:
+            return
+        next_it = model.iter_next(it)
+        if not next_it:
+            return
+        cur_index = model.get_value(it, 0)
+        next_index = cur_index
+        model.set(next_it, 0, next_index)
+        cur_index = cur_index + 1
+        model.set(it, 0, cur_index)
+
+    def pkgfmt_widget_toggle_cb(self, cell, path, model, column):
+        it = model.get_iter(path)
+        val = model.get_value(it, column)
+        val = not val
+        model.set(it, column, val)
+
+    def gen_pkgfmt_widget(self, curr_package_format, all_package_format, tooltip=""):
+        pkgfmt_hbox = gtk.HBox(False, 15)
+
+        pkgfmt_store = gtk.ListStore(int, str, gobject.TYPE_BOOLEAN)
+        for format in curr_package_format.split():
+            pkgfmt_store.set(pkgfmt_store.append(), 1, format, 2, True)
+        for format in all_package_format:
+            if format not in curr_package_format:
+                pkgfmt_store.set(pkgfmt_store.append(), 1, format, 2, False)
+        pkgfmt_tree = gtk.TreeView(pkgfmt_store)
+        pkgfmt_tree.set_headers_clickable(True)
+        pkgfmt_tree.set_headers_visible(False)
+        tree_selection = pkgfmt_tree.get_selection()
+        tree_selection.set_mode(gtk.SELECTION_SINGLE)
+
+        col = gtk.TreeViewColumn('NO')
+        col.set_sort_column_id(0)
+        col.set_sort_order(gtk.SORT_ASCENDING)
+        col.set_clickable(False)
+        col1 = gtk.TreeViewColumn('TYPE')
+        col1.set_min_width(130)
+        col1.set_max_width(140)
+        col2 = gtk.TreeViewColumn('INCLUDED')
+        col2.set_min_width(60)
+        col2.set_max_width(70)
+        pkgfmt_tree.append_column(col1)
+        pkgfmt_tree.append_column(col2)
+        cell = gtk.CellRendererText()
+        cell1 = gtk.CellRendererText()
+        cell1.set_property('width-chars', 10)
+        cell2 = gtk.CellRendererToggle()
+        cell2.set_property('activatable', True)
+        cell2.connect("toggled", self.pkgfmt_widget_toggle_cb, pkgfmt_store, 2)
+        col.pack_start(cell, True)
+        col1.pack_start(cell1, True)
+        col2.pack_end(cell2, True)
+        col.set_attributes(cell, text=0)
+        col1.set_attributes(cell1, text=1)
+        col2.set_attributes(cell2, active=2)
+
+        pkgfmt_store.set_sort_func(0, self.pkgfmt_widget_sort_func, None)
+        pkgfmt_store.set_sort_column_id(0, gtk.SORT_ASCENDING)
+
+        scroll = gtk.ScrolledWindow()
+        scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        scroll.set_shadow_type(gtk.SHADOW_IN)
+        scroll.add(pkgfmt_tree)
+        scroll.set_size_request(200,60)
+        pkgfmt_hbox.pack_start(scroll, False, False, 0)
+
+        vbox = gtk.VBox(False, 5)
+        pkgfmt_hbox.pack_start(vbox, False, False, 15)
+
+        up = gtk.Button()
+        image = gtk.Image()
+        image.set_from_stock(gtk.STOCK_GO_UP, gtk.ICON_SIZE_MENU)
+        up.set_image(image)
+        up.set_size_request(50,30)
+        up.connect("clicked", self.pkgfmt_widget_up_clicked_cb, tree_selection)
+        vbox.pack_start(up, False, False, 5)
+
+        down = gtk.Button()
+        image = gtk.Image()
+        image.set_from_stock(gtk.STOCK_GO_DOWN, gtk.ICON_SIZE_MENU)
+        down.set_image(image)
+        down.set_size_request(50,30)
+        down.connect("clicked", self.pkgfmt_widget_down_clicked_cb, tree_selection)
+        vbox.pack_start(down, False, False, 5)
+        tree_selection.connect("changed", self.pkgfmt_widget_tree_selection_changed_cb, up, down)
+
+        image = gtk.Image()
+        image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
+        image.set_tooltip_text(tooltip)
+        pkgfmt_hbox.pack_start(image, expand=False, fill=False)
+
+        pkgfmt_hbox.show_all()
+
+        return pkgfmt_hbox, pkgfmt_store
+
+    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, 10)
+
+        vbox = gtk.VBox(False, 10)
+        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, 4)
+        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)
+
+        image = gtk.Image()
+        image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
+        image.set_tooltip_text(tooltip)
+        setting_hbox.pack_start(image, expand=False, fill=False)
+
+        return setting_hbox, setting_store
+
     def __init__(self, title, configuration, all_image_types,
             all_package_formats, all_distros, all_sdk_machines,
             max_threads, split_model, parent, flags, buttons):
@@ -174,7 +485,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         image.show()
         image.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_BUTTON)
         image.set_tooltip_text(tooltip)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Select image types:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Select image types:</span>")
         table.attach(label, 0, 9, 0, 1)
         table.attach(image, 9, 10, 0, 1)
 
@@ -199,26 +510,26 @@ class AdvancedSettingDialog (gtk.Dialog):
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Packaging Format:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Packaging Format:</span>")
         tooltip = "Select package formats that will be used. "
         tooltip += "The first format will be used for final image"
-        pkgfmt_widget, self.pkgfmt_store = HobWidget.gen_pkgfmt_widget(self.configuration.curr_package_format, self.all_package_formats, tooltip)
+        pkgfmt_widget, self.pkgfmt_store = self.gen_pkgfmt_widget(self.configuration.curr_package_format, self.all_package_formats, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(pkgfmt_widget, expand=False, fill=False)
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Image Rootfs Size: (MB)</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Image Rootfs Size: (MB)</span>")
         tooltip = "Sets the size of your target image.\nThis is the basic size of your target image, unless your selected package size exceeds this value, or you set value to \"Image Extra Size\"."
-        rootfs_size_widget, self.rootfs_size_spinner = HobWidget.gen_spinner_widget(int(self.configuration.image_rootfs_size*1.0/1024), 0, 1024, tooltip)
+        rootfs_size_widget, self.rootfs_size_spinner = self.gen_spinner_widget(int(self.configuration.image_rootfs_size*1.0/1024), 0, 1024, 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, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Image Extra Size: (MB)</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Image Extra Size: (MB)</span>")
         tooltip = "Sets the extra free space of your target image.\nDefaultly, system will reserve 30% of your image size as your free space. If your image contains zypper, it will bring in 50MB more space. The maximum free space is 1024MB."
-        extra_size_widget, self.extra_size_spinner = HobWidget.gen_spinner_widget(int(self.configuration.image_extra_size*1.0/1024), 0, 1024, tooltip)
+        extra_size_widget, self.extra_size_spinner = self.gen_spinner_widget(int(self.configuration.image_extra_size*1.0/1024), 0, 1024, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(extra_size_widget, expand=False, fill=False)
 
@@ -238,7 +549,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         sub_hbox.pack_start(self.toolchain_checkbox, expand=False, fill=False)
 
         tooltip = "This is the Host platform you would like to run the toolchain"
-        sdk_machine_widget, self.sdk_machine_combo = HobWidget.gen_combo_widget(self.configuration.curr_sdk_machine, self.all_sdk_machines, tooltip)
+        sdk_machine_widget, self.sdk_machine_combo = self.gen_combo_widget(self.configuration.curr_sdk_machine, self.all_sdk_machines, tooltip)
         sub_hbox.pack_start(sdk_machine_widget, expand=False, fill=False)
 
         return advanced_vbox
@@ -249,49 +560,49 @@ class AdvancedSettingDialog (gtk.Dialog):
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Select Distro:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Select Distro:</span>")
         tooltip = "This is the Yocto distribution you would like to use"
-        distro_widget, self.distro_combo = HobWidget.gen_combo_widget(self.configuration.curr_distro, self.all_distros, tooltip)
+        distro_widget, self.distro_combo = self.gen_combo_widget(self.configuration.curr_distro, self.all_distros, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(distro_widget, expand=False, fill=False)
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">BB_NUMBER_THREADS:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">BB_NUMBER_THREADS:</span>")
         tooltip = "Sets the number of threads that bitbake tasks can run simultaneously"
-        bbthread_widget, self.bb_spinner = HobWidget.gen_spinner_widget(self.configuration.bbthread, 1, self.max_threads, tooltip)
+        bbthread_widget, self.bb_spinner = self.gen_spinner_widget(self.configuration.bbthread, 1, self.max_threads, 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, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">PARALLEL_MAKE:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">PARALLEL_MAKE:</span>")
         tooltip = "Sets the make parallism, as known as 'make -j'"
-        pmake_widget, self.pmake_spinner = HobWidget.gen_spinner_widget(self.configuration.pmake, 1, self.max_threads, tooltip)
+        pmake_widget, self.pmake_spinner = self.gen_spinner_widget(self.configuration.pmake, 1, self.max_threads, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(pmake_widget, expand=False, fill=False)
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Set Download Directory:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Set Download Directory:</span>")
         tooltip = "Select a folder that caches the upstream project source code"
-        dldir_widget, self.dldir_text = HobWidget.gen_entry_widget(self.split_model, self.configuration.dldir, self, tooltip)
+        dldir_widget, self.dldir_text = self.gen_entry_widget(self.split_model, self.configuration.dldir, self, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(dldir_widget, expand=False, fill=False)
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Select SSTATE Directory:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Select SSTATE Directory:</span>")
         tooltip = "Select a folder that caches your prebuilt results"
-        sstatedir_widget, self.sstatedir_text = HobWidget.gen_entry_widget(self.split_model, self.configuration.sstatedir, self, tooltip)
+        sstatedir_widget, self.sstatedir_text = self.gen_entry_widget(self.split_model, self.configuration.sstatedir, self, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False)
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Select SSTATE Mirror:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Select SSTATE Mirror:</span>")
         tooltip = "Select the prebuilt mirror that will fasten your build speed"
-        sstatemirror_widget, self.sstatemirror_text = HobWidget.gen_entry_widget(self.split_model, self.configuration.sstatemirror, self, tooltip)
+        sstatemirror_widget, self.sstatemirror_text = self.gen_entry_widget(self.split_model, self.configuration.sstatemirror, self, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(sstatemirror_widget, expand=False, fill=False)
 
@@ -303,9 +614,9 @@ class AdvancedSettingDialog (gtk.Dialog):
 
         sub_vbox = gtk.VBox(False, 5)
         advanced_vbox.pack_start(sub_vbox, expand=True, fill=True)
-        label = HobWidget.gen_label_widget("<span weight=\"bold\">Add your own variables:</span>")
+        label = self.gen_label_widget("<span weight=\"bold\">Add your own variables:</span>")
         tooltip = "This is the key/value pair for your extra settings"
-        setting_widget, self.setting_store = HobWidget.gen_editable_settings(self.configuration.extra_setting, tooltip)
+        setting_widget, self.setting_store = self.gen_editable_settings(self.configuration.extra_setting, tooltip)
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(setting_widget, expand=True, fill=True)
 
@@ -488,6 +799,127 @@ class DeployImageDialog (gtk.Dialog):
 #
 class LayerSelectionDialog (gtk.Dialog):
 
+    def gen_label_widget(self, content):
+        label = gtk.Label()
+        label.set_alignment(0, 0)
+        label.set_markup(content)
+        label.show()
+        return label
+
+    def layer_widget_toggled_cb(self, cell, path, layer_store):
+        name = layer_store[path][0]
+        toggle = not layer_store[path][1]
+        layer_store[path][1] = toggle
+
+    def layer_widget_add_clicked_cb(self, action, layer_store, parent):
+        dialog = gtk.FileChooserDialog("Add new layer", parent,
+                                       gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
+                                       (gtk.STOCK_OK, gtk.RESPONSE_YES,
+                                        gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+        label = gtk.Label("Select the layer you wish to add")
+        label.show()
+        dialog.set_extra_widget(label)
+        response = dialog.run()
+        path = dialog.get_filename()
+        dialog.destroy()
+
+        lbl = "<b>Error</b>\nUnable to load layer <i>%s</i> because " % path
+        if response == gtk.RESPONSE_YES:
+            import os
+            import os.path
+            layers = []
+            it = layer_store.get_iter_first()
+            while it:
+                layers.append(layer_store.get_value(it, 0))
+                it = layer_store.iter_next(it)
+
+            if not path:
+                lbl += "it is an invalid path."
+            elif not os.path.exists(path+"/conf/layer.conf"):
+                lbl += "there is no layer.conf inside the directory."
+            elif path in layers:
+                lbl += "it is already in loaded layers."
+            else:
+                layer_store.append([path])
+                return
+            dialog = CrumbsDialog(parent, lbl)
+            dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
+            response = dialog.run()
+            dialog.destroy()
+
+    def layer_widget_del_clicked_cb(self, action, tree_selection, layer_store):
+        model, iter = tree_selection.get_selected()
+        if iter:
+            layer_store.remove(iter)
+
+
+    def gen_layer_widget(self, split_model, layers, layers_avail, window, tooltip=""):
+        hbox = gtk.HBox(False, 10)
+
+        layer_tv = gtk.TreeView()
+        layer_tv.set_rules_hint(True)
+        layer_tv.set_headers_visible(False)
+        tree_selection = layer_tv.get_selection()
+        tree_selection.set_mode(gtk.SELECTION_SINGLE)
+
+        col0= gtk.TreeViewColumn('Path')
+        cell0 = gtk.CellRendererText()
+        cell0.set_padding(5,2)
+        col0.pack_start(cell0, True)
+        col0.set_attributes(cell0, text=0)
+        layer_tv.append_column(col0)
+
+        scroll = gtk.ScrolledWindow()
+        scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        scroll.set_shadow_type(gtk.SHADOW_IN)
+        scroll.add(layer_tv)
+
+        table_layer = gtk.Table(2, 10, False)
+        hbox.pack_start(table_layer, expand=True, fill=True)
+
+        if split_model:
+            table_layer.attach(scroll, 0, 10, 0, 2)
+
+            layer_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
+            for layer in layers:
+                layer_store.set(layer_store.append(), 0, layer, 1, True)
+            for layer in layers_avail:
+                if layer not in layers:
+                    layer_store.set(layer_store.append(), 0, layer, 1, False)
+
+            col1 = gtk.TreeViewColumn('Included')
+            layer_tv.append_column(col1)
+
+            cell1 = gtk.CellRendererToggle()
+            cell1.connect("toggled", self.layer_widget_toggled_cb, layer_store)
+            col1.pack_start(cell1, True)
+            col1.set_attributes(cell1, active=1)
+
+        else:
+            table_layer.attach(scroll, 0, 10, 0, 1)
+
+            layer_store = gtk.ListStore(gobject.TYPE_STRING)
+            for layer in layers:
+                layer_store.set(layer_store.append(), 0, layer)
+
+            image = gtk.Image()
+            image.set_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_MENU)
+            add_button = gtk.Button()
+            add_button.set_image(image)
+            add_button.connect("clicked", self.layer_widget_add_clicked_cb, layer_store, window)
+            table_layer.attach(add_button, 0, 5, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 0)
+            image = gtk.Image()
+            image.set_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_MENU)
+            del_button = gtk.Button()
+            del_button.set_image(image)
+            del_button.connect("clicked", self.layer_widget_del_clicked_cb, tree_selection, layer_store)
+            table_layer.attach(del_button, 5, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 0)
+        layer_tv.set_model(layer_store)
+
+        hbox.show_all()
+
+        return hbox, layer_store
+
     def __init__(self, title, layers, all_layers, split_model,
             parent, flags, buttons):
         super(LayerSelectionDialog, self).__init__(title, parent, flags, buttons)
@@ -514,9 +946,9 @@ class LayerSelectionDialog (gtk.Dialog):
         self.vbox.pack_start(hbox_top, expand=False, fill=False)
 
         if self.split_model:
-            label = HobWidget.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>\n(Available layers under '${COREBASE}/layers/' directory)")
+            label = self.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>\n(Available layers under '${COREBASE}/layers/' directory)")
         else:
-            label = HobWidget.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>")
+            label = self.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>")
         hbox_top.pack_start(label, expand=False, fill=False)
 
         tooltip = "Layer is a collection of bb files and conf files"
@@ -525,7 +957,7 @@ class LayerSelectionDialog (gtk.Dialog):
         image.set_tooltip_text(tooltip)
         hbox_top.pack_end(image, expand=False, fill=False)
 
-        layer_widget, self.layer_store = HobWidget.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
+        layer_widget, self.layer_store = self.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
 
         self.vbox.pack_start(layer_widget, expand=True, fill=True)
 
@@ -537,7 +969,7 @@ class LayerSelectionDialog (gtk.Dialog):
         self.vbox.pack_end(hbox_button, expand=False, fill=False)
         hbox_button.show()
 
-        label = HobWidget.gen_label_widget("<i>'meta' is Core layer for Yocto images</i>\n"
+        label = self.gen_label_widget("<i>'meta' is Core layer for Yocto images</i>\n"
         "<span weight=\"bold\">Please do not remove it</span>")
         hbox_button.pack_start(label, expand=False, fill=False)
 
bitbake/lib/bb/ui/crumbs/hobwidget.py +0 -465

471 lines not on this page · raw message

bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +1 -1
index 93540b2..cf8504a 100755
@@ -23,7 +23,7 @@
 import gtk
 import glib
 from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobWidget, HobViewBar, HobViewTable
+from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable
 from bb.ui.crumbs.hoblistmodel import RecipeListModel
 from bb.ui.crumbs.hobpages import HobPage
 
Signature · 1 line
1.7.6
author
#5 lore raw

PATCH 4/32 Hob: fixed the issue in the brought-in-by dialog.

In reply to Shane Wang

When typing any thing in the search entry, the brough-in-by dialog will be shown. That is because we call back "selection-changed" signal to pop up the dialog, which is not correct. This patch is to fix the problem by using "row-activated" signal.

---
 bitbake/lib/bb/ui/crumbs/hig.py                  |    5 +---
 bitbake/lib/bb/ui/crumbs/hobwidget.py            |   30 ++++++++++++---------
 bitbake/lib/bb/ui/crumbs/packageselectionpage.py |   12 ++------
 bitbake/lib/bb/ui/crumbs/recipeselectionpage.py  |   13 ++-------
 4 files changed, 24 insertions(+), 36 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +1 -4
index 2de7b2a..74f4f7b 100644
@@ -89,15 +89,12 @@ class BinbDialog(gtk.Dialog):
         self.set_resizable(False)
         self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.DARK))
 
-        hbox = gtk.HBox(False, 0)
-        self.vbox.pack_start(hbox, expand=False, fill=False, padding=10)
-
         label = gtk.Label(content)
         label.set_alignment(0, 0)
         label.set_line_wrap(True)
         label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.WHITE))
 
-        hbox.pack_start(label, expand=False, fill=False, padding=10)
+        self.vbox.pack_start(label, expand=True, fill=True, padding=10)
         self.vbox.show_all()
 
 #
bitbake/lib/bb/ui/crumbs/hobwidget.py +17 -13
index 4bbbed6..664bf25 100644
@@ -55,16 +55,16 @@ class HobViewTable (gtk.VBox):
     A VBox to contain the table for different recipe views and package view
     """
     __gsignals__ = {
-         "toggled"      : (gobject.SIGNAL_RUN_LAST,
-                           gobject.TYPE_NONE,
-                          (gobject.TYPE_PYOBJECT,
-                           gobject.TYPE_STRING,
-                           gobject.TYPE_INT,
-                           gobject.TYPE_PYOBJECT,)),
-         "changed"      : (gobject.SIGNAL_RUN_LAST,
-                           gobject.TYPE_NONE,
-                          (gobject.TYPE_PYOBJECT,
-                           gobject.TYPE_PYOBJECT,)),
+         "toggled"       : (gobject.SIGNAL_RUN_LAST,
+                            gobject.TYPE_NONE,
+                           (gobject.TYPE_PYOBJECT,
+                            gobject.TYPE_STRING,
+                            gobject.TYPE_INT,
+                            gobject.TYPE_PYOBJECT,)),
+         "row-activated" : (gobject.SIGNAL_RUN_LAST,
+                            gobject.TYPE_NONE,
+                           (gobject.TYPE_PYOBJECT,
+                            gobject.TYPE_PYOBJECT,)),
     }
 
     def __init__(self, columns):
@@ -75,7 +75,8 @@ class HobViewTable (gtk.VBox):
         self.table_tree.set_enable_search(True)
         self.table_tree.set_rules_hint(True)
         self.table_tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
-        self.table_tree.get_selection().connect("changed", self.selection_changed_cb, self.table_tree)
+        self.toggle_columns = []
+        self.table_tree.connect("row-activated", self.row_activated_cb)
 
         for i in range(len(columns)):
             col = gtk.TreeViewColumn(columns[i]['col_name'])
@@ -99,6 +100,7 @@ class HobViewTable (gtk.VBox):
                 self.toggle_id = i
                 col.pack_end(cell, True)
                 col.set_attributes(cell, active=columns[i]['col_id'])
+                self.toggle_columns.append(columns[i]['col_name'])
             elif columns[i]['col_style'] == 'radio toggle':
                 cell = gtk.CellRendererToggle()
                 cell.set_property('activatable', True)
@@ -107,6 +109,7 @@ class HobViewTable (gtk.VBox):
                 self.toggle_id = i
                 col.pack_end(cell, True)
                 col.set_attributes(cell, active=columns[i]['col_id'])
+                self.toggle_columns.append(columns[i]['col_name'])
 
         scroll = gtk.ScrolledWindow()
         scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
@@ -133,8 +136,9 @@ class HobViewTable (gtk.VBox):
     def toggled_cb(self, cell, path, columnid, tree):
         self.emit("toggled", cell, path, columnid, tree)
 
-    def selection_changed_cb(self, selection, tree):
-        self.emit("changed", selection, tree)
+    def row_activated_cb(self, tree, path, view_column):
+        if not view_column.get_title() in self.toggle_columns:
+            self.emit("row-activated", tree.get_model(), path)
 
 class HobViewBar (gtk.EventBox):
     """
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +3 -9
index 280d480..a3c4acd 100755
@@ -116,7 +116,7 @@ class PackageSelectionPage (HobPage):
             tab.set_model(self.package_model.tree_model(filter))
             tab.connect("toggled", self.table_toggled_cb)
             if self.pages[i]['name'] == "Included":
-                tab.connect("changed", self.tree_selection_cb)
+                tab.connect("row-activated", self.tree_row_activated_cb)
 
             reset_button = gtk.Button("Reset")
             reset_button.connect("clicked", self.reset_clicked_cb)
@@ -161,14 +161,8 @@ class PackageSelectionPage (HobPage):
         self.back_button.connect("clicked", self.back_button_clicked_cb)
         button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, table, tree_selection, tree_view):
-        tree_model = tree_view.get_model()
-        path, column = tree_view.get_cursor()
-        if not path or column == tree_view.get_column(2):
-            return
-
-        it = tree_model.get_iter(path)
-        binb = tree_model.get_value(it, PackageListModel.COL_BINB)
+    def tree_row_activated_cb(self, table, tree_model, path):
+        binb = tree_model.get_value(tree_model.get_iter(path), PackageListModel.COL_BINB)
         if binb:
             self.builder.show_binb_dialog(binb)
 
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +3 -10
index cf8504a..ee36f8c 100755
@@ -140,8 +140,7 @@ class RecipeSelectionPage (HobPage):
             tab.set_model(self.recipe_model.tree_model(filter))
             tab.connect("toggled", self.table_toggled_cb)
             if self.pages[i]['name'] == "Included":
-                tab.connect("changed", self.tree_selection_cb)
-
+                tab.connect("row-activated", self.tree_row_activated_cb)
             reset_button = gtk.Button("Reset")
             reset_button.connect("clicked", self.reset_clicked_cb)
             hbox = gtk.HBox(False, 5)
@@ -185,14 +184,8 @@ class RecipeSelectionPage (HobPage):
         self.back_button.connect("clicked", self.back_button_clicked_cb)
         button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, table, tree_selection, tree_view):
-        tree_model = tree_view.get_model()
-        path, column = tree_view.get_cursor()
-        if not path or column == tree_view.get_column(2):
-            return
-
-        it = tree_model.get_iter(path)
-        binb = tree_model.get_value(it, RecipeListModel.COL_BINB)
+    def tree_row_activated_cb(self, table, tree_model, path):
+        binb = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_BINB)
         if binb:
             self.builder.show_binb_dialog(binb)
 
Signature · 1 line
1.7.6
author
#17 lore raw

PATCH 7/32 Hob: use HobNotebook to enable a notebook in build details page

In reply to Shane Wang

This patch is to use HobNotebook we defined to implement the notebook in the build details page.
And more the "build configuration" tab and the "issues" tab use more tree views which we implemented in runningbuild.py.

---
 bitbake/lib/bb/ui/crumbs/builddetailspage.py |   40 +++++++++++++--
 bitbake/lib/bb/ui/crumbs/builder.py          |    5 ++
 bitbake/lib/bb/ui/crumbs/hobwidget.py        |   14 +++++
 bitbake/lib/bb/ui/crumbs/runningbuild.py     |   69 ++++++++++++++++++++++++++
 4 files changed, 123 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/builddetailspage.py +35 -5
index 941f1e3..4a9f658 100755
@@ -22,8 +22,10 @@
 
 import gtk
 from bb.ui.crumbs.progressbar import HobProgressBar
-from bb.ui.crumbs.hobwidget import hic
+from bb.ui.crumbs.hobwidget import hic, HobNotebook
 from bb.ui.crumbs.runningbuild import RunningBuildTreeView
+from bb.ui.crumbs.runningbuild import BuildConfigurationTreeView
+from bb.ui.crumbs.runningbuild import BuildFailureTreeView
 from bb.ui.crumbs.hobpages import HobPage
 
 #
@@ -35,6 +37,8 @@ class BuildDetailsPage (HobPage):
     def __init__(self, builder):
         super(BuildDetailsPage, self).__init__(builder, "Building ...")
 
+        self.num_of_issues = 0
+
         # create visual elements
         self.create_visual_elements()
 
@@ -49,17 +53,43 @@ class BuildDetailsPage (HobPage):
         self.stop_button.connect("clicked", self.stop_button_clicked_cb)
         self.progress_box.pack_end(self.stop_button, expand=False, fill=False)
 
+        self.notebook = HobNotebook()
+        self.config_tv = BuildConfigurationTreeView()
+        self.config_model = self.builder.handler.build.model.config_model()
+        self.config_tv.set_model(self.config_model)
+        self.scrolled_view_config = gtk.ScrolledWindow ()
+        self.scrolled_view_config.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.scrolled_view_config.add(self.config_tv)
+        self.notebook.append_page(self.scrolled_view_config, gtk.Label("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_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.scrolled_view_failure.add(self.failure_tv)
+        self.notebook.append_page(self.scrolled_view_failure, gtk.Label("Issues"))
+
         self.build_tv = RunningBuildTreeView(readonly=True)
         self.build_tv.set_model(self.builder.handler.build.model)
-        self.scrolled_view = gtk.ScrolledWindow ()
-        self.scrolled_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        self.scrolled_view.add(self.build_tv)
+        self.scrolled_view_build = gtk.ScrolledWindow ()
+        self.scrolled_view_build.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.scrolled_view_build.add(self.build_tv)
+        self.notebook.append_page(self.scrolled_view_build, gtk.Label("Log"))
 
         self.button_box = gtk.HBox(False, 5)
         self.back_button = gtk.LinkButton("Go back to Image Configuration screen", "<< Back to image configuration")
         self.back_button.connect("clicked", self.back_button_clicked_cb)
         self.button_box.pack_start(self.back_button, expand=False, fill=False)
 
+    def show_issues(self):
+        self.num_of_issues += 1
+        self.notebook.show_indicator_icon("Issues", self.num_of_issues)
+
+    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:
@@ -86,7 +116,7 @@ class BuildDetailsPage (HobPage):
         self.progress_bar.reset()
         self.vbox.pack_start(self.progress_box, expand=False, fill=False)
 
-        self.vbox.pack_start(self.scrolled_view, expand=True, fill=True)
+        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()
bitbake/lib/bb/ui/crumbs/builder.py +5 -0
index eb38819..819b79f 100755
@@ -214,6 +214,7 @@ class Builder(gtk.Window):
         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("task-started",       self.handler_task_started_cb)
+        self.handler.build.connect("log-error",          self.handler_build_failure_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)
@@ -528,6 +529,7 @@ class Builder(gtk.Window):
         elif self.current_step == self.PACKAGE_GENERATING:
             fraction = 0
         self.build_details_page.update_progress_bar("Build Started: ", fraction)
+        self.build_details_page.reset_issues()
 
     def handler_build_succeeded_cb(self, running_build):
         self.build_succeeded = True
@@ -586,6 +588,9 @@ class Builder(gtk.Window):
                 fraction = 0.2 + 0.8 * fraction
         self.build_details_page.update_progress_bar(title + ": ", fraction)
 
+    def handler_build_failure_cb(self, running_build):
+        self.build_details_page.show_issues()
+
     def destroy_window_cb(self, widget, event):
         lbl = "<b>Do you really want to exit the Hob image creator?</b>"
         dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
bitbake/lib/bb/ui/crumbs/hobwidget.py +14 -0
index a2d99a2..c4a0513 100644
@@ -569,6 +569,20 @@ class HobNotebook(gtk.VBox):
  
         self.tb.show()
 
+    def show_indicator_icon(self, title, number):
+        for i in range(len(self.tabbar.children)):
+            if self.tabbar.children[i]["toggled_page"] == -1:
+                continue
+            if self.tabbar.children[i]["title"] == title:
+                self.tabbar.show_indicator_icon(i, number)
+
+    def hide_indicator_icon(self, title):
+        for i in range(len(self.tabbar.children)):
+            if self.tabbar.children[i]["toggled_page"] == -1:
+                continue
+            if self.tabbar.children[i]["title"] == title:
+                self.tabbar.hide_indicator_icon(i)
+
     def tab_switched_cb(self, widget, page):
         self.notebook.set_current_page(page)
 
bitbake/lib/bb/ui/crumbs/runningbuild.py +69 -0

96 lines not on this page · raw message

Signature · 1 line
1.7.6
author
#13 lore raw

PATCH 6/32 Hob: implement a self-defined notebook visual component for Hob

In reply to Shane Wang

In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video. We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page.

---
 bitbake/lib/bb/ui/crumbs/hobcolor.py             |    1 +
 bitbake/lib/bb/ui/crumbs/hobwidget.py            |  467 ++++++++++++++++++----
 bitbake/lib/bb/ui/crumbs/packageselectionpage.py |   19 +-
 bitbake/lib/bb/ui/crumbs/recipeselectionpage.py  |   19 +-
 4 files changed, 394 insertions(+), 112 deletions(-)
bitbake/lib/bb/ui/crumbs/hobcolor.py +1 -0
index 9d67d5c..402f022 100644
@@ -28,6 +28,7 @@ class HobColors:
     DARK         = "#3c3b37"
     BLACK        = "#000000"
     LIGHT_ORANGE = "#f7a787"
+    YELLOW       = "#ffff00"
 
     OK = WHITE
     RUNNING = PALE_GREEN
bitbake/lib/bb/ui/crumbs/hobwidget.py +382 -85

486 lines not on this page · raw message

bitbake/lib/bb/ui/crumbs/packageselectionpage.py +6 -13
index a3c4acd..dab90ec 100755
@@ -23,7 +23,7 @@
 import gtk
 import glib
 from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable
+from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook
 from bb.ui.crumbs.hoblistmodel import PackageListModel
 from bb.ui.crumbs.hobpages import HobPage
 
@@ -102,11 +102,7 @@ class PackageSelectionPage (HobPage):
         self.pack_start(self.group_align, expand=True, fill=True)
 
         # set visiable members
-        self.grid = gtk.Table(10, 1, True)
-        self.grid.set_col_spacings(3)
-
-        self.ins = gtk.Notebook()
-        self.ins.set_show_tabs(False)
+        self.ins = HobNotebook()
         self.tables = [] # we need to modify table when the dialog is shown
         # append the tab
         for i in range(len(self.pages)):
@@ -128,19 +124,16 @@ class PackageSelectionPage (HobPage):
             self.ins.append_page(tab, label)
             self.tables.append(tab)
 
-        self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
-        # a black bar associated with the notebook
-        self.topbar = HobViewBar(self.ins) 
-        self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
+        self.ins.set_entry("Search packages:")
         # set the search entry for each table
         for tab in self.tables:
-            tab.set_search_entry(0, self.topbar.search)
+            tab.set_search_entry(0, self.ins.search)
 
         # add all into the dialog
-        self.box_group_area.add(self.grid)
+        self.box_group_area.pack_start(self.ins, expand=True, fill=True)
 
         button_box = gtk.HBox(False, 5)
-        self.box_group_area.pack_start(button_box, expand=False, fill=False)
+        self.box_group_area.pack_end(button_box, expand=False, fill=False)
 
         self.build_image_button = gtk.Button()
         label = gtk.Label()
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +5 -14
index ee36f8c..416c613 100755
@@ -23,7 +23,7 @@
 import gtk
 import glib
 from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable
+from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook
 from bb.ui.crumbs.hoblistmodel import RecipeListModel
 from bb.ui.crumbs.hobpages import HobPage
 
@@ -124,13 +124,7 @@ class RecipeSelectionPage (HobPage):
         self.pack_start(self.group_align, expand=True, fill=True)
 
         # set visiable members
-        self.grid = gtk.Table(10, 1, True)
-        self.grid.set_col_spacings(3)
-
-        # draw the left part of the window
-        # a notebook
-        self.ins = gtk.Notebook()
-        self.ins.set_show_tabs(False)
+        self.ins = HobNotebook()
         self.tables = [] # we need modify table when the dialog is shown
         # append the tabs in order
         for i in range(len(self.pages)):
@@ -151,16 +145,13 @@ class RecipeSelectionPage (HobPage):
             self.ins.append_page(tab, label)
             self.tables.append(tab)
 
-        self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
-        # a black bar associated with the notebook
-        self.topbar = HobViewBar(self.ins)
-        self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
+        self.ins.set_entry("Search recipes:")
         # set the search entry for each table
         for tab in self.tables:
-            tab.set_search_entry(0, self.topbar.search)
+            tab.set_search_entry(0, self.ins.search)
 
         # add all into the window
-        self.box_group_area.add(self.grid)
+        self.box_group_area.pack_start(self.ins, expand=True, fill=True)
 
         button_box = gtk.HBox(False, 5)
         self.box_group_area.pack_end(button_box, expand=False, fill=False)
Signature · 1 line
1.7.6
author
#24 lore raw

PATCH 10/32 Hob: add ignore_all_errors to avoid showing error dialog multiple times

In reply to Shane Wang

when parsing recipes, if there are some errors, the error dialog will be shown again and again for each error, add "Ignore All" to allow users to ignore those errors.

---
 bitbake/lib/bb/ui/crumbs/builder.py |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +14 -6
index 819b79f..fc231ef 100755
@@ -178,6 +178,8 @@ class Builder(gtk.Window):
 
         self.template = None
 
+        self.ignore_all_errors = False
+
         # settings
         params = self.handler.get_parameters()
         self.configuration = Configuration(params)
@@ -315,6 +317,8 @@ class Builder(gtk.Window):
 
         elif next_step == self.RCPPKGINFO_POPULATING:
             # MACHINE CHANGED action or SETTINGS CHANGED
+            # reset the "ignore all errors" var
+            self.ignore_all_errors = False
             # show the progress bar
             self.image_configuration_page.show_info_populating()
             self.generate_recipes()
@@ -440,12 +444,16 @@ class Builder(gtk.Window):
                 self.switch_page(self.IMAGE_GENERATED)
 
     def handler_command_failed_cb(self, handler, msg):
-        lbl = "<b>Error</b>\n"
-        lbl = lbl + "%s\n\n" % msg
-        dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
-        dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
-        response = dialog.run()
-        dialog.destroy()
+        if self.ignore_all_errors == False:
+            lbl = "<b>Error</b>\n"
+            lbl = lbl + "%s\n\n" % msg
+            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
+            dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
+            dialog.add_button("Ignore All", gtk.RESPONSE_REJECT)
+            response = dialog.run()
+            if response == gtk.RESPONSE_REJECT:
+                self.ignore_all_errors = True
+            dialog.destroy()
         self.handler.clear_busy()
         self.configuration.curr_mach = None
         self.image_configuration_page.switch_machine_combo()
Signature · 1 line
1.7.6
author
#29 lore raw

PATCH 12/32 Hob: enable indicators on the "Included" tab in the recipe selection page and the package selection page

In reply to Shane Wang
---
 bitbake/lib/bb/ui/crumbs/packageselectionpage.py |    1 +
 bitbake/lib/bb/ui/crumbs/recipeselectionpage.py  |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +1 -0
index dab90ec..5459743 100755
@@ -186,6 +186,7 @@ class PackageSelectionPage (HobPage):
 
         self.label.set_text("Packages included: %s\nSelected packages size: %s\nTotal image size: %s" %
                             (selected_packages_num, selected_packages_size_str, image_total_size_str))
+        self.ins.show_indicator_icon("Included", selected_packages_num)
 
     """
     Helper function to convert the package size to string format.
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +1 -0
index 416c613..8423714 100755
@@ -190,6 +190,7 @@ class RecipeSelectionPage (HobPage):
         self.builder.configuration.selected_image = self.recipe_model.get_selected_image()
         _, self.builder.configuration.selected_recipes = self.recipe_model.get_selected_recipes()
         self.label.set_text("Recipes included: %s" % len(self.builder.configuration.selected_recipes))
+        self.ins.show_indicator_icon("Included", len(self.builder.configuration.selected_recipes))
 
     # Callback functions
     def reset_clicked_cb(self, button):
Signature · 1 line
1.7.6
author
#27 lore raw

PATCH 11/32 Hob: make the image configuration page not to flash the progress bar

In reply to Shane Wang

Sometimes the image configuration page flashes the progress bar, that is because we show_all() and then hide() the progress bar. For this case, the patch doesn't add the progress bar onto the gtable. Then, it will not be flashed any more.

---
 bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py |   30 +++++++++----------
 1 files changed, 14 insertions(+), 16 deletions(-)
bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py +14 -16
index cd86606..db54d79 100644
@@ -84,21 +84,20 @@ class ImageConfigurationPage (HobPage):
         for child in children:
             self.remove(child)
 
-    def _pack_components(self):
+    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)
-        self.box_group_area.pack_end(self.config_build_button, expand=False, fill=False)
+        if pack_config_build_button == True:
+            self.box_group_area.pack_end(self.config_build_button, expand=False, fill=False)
 
     def show_machine(self):
-        self._pack_components()
-        self.set_config_machine_layout()
-        self.show_all()
         self.progress_bar.reset()
-        self.progress_bar.hide()
-        self.config_build_button.hide_all()
+        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=True):
         self.progress_bar.update(fraction)
@@ -106,18 +105,16 @@ class ImageConfigurationPage (HobPage):
         self.progress_bar.set_rcstyle(status)
 
     def show_info_populating(self):
-        self._pack_components()
-        self.set_config_machine_layout()
+        self._pack_components(pack_config_build_button = False)
+        self.set_config_machine_layout(show_progress_bar = True)
         self.show_all()
-        self.config_build_button.hide_all()
 
     def show_info_populated(self):
-        self._pack_components()
-        self.set_config_machine_layout()
+        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()
-        self.progress_bar.reset()
-        self.progress_bar.hide()
 
     def create_config_machine(self):
         self.machine_title = gtk.Label()
@@ -154,13 +151,14 @@ class ImageConfigurationPage (HobPage):
         self.progress_bar = HobProgressBar()
         self.machine_separator = gtk.HSeparator()
 
-    def set_config_machine_layout(self):
+    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, 6, 9)
         self.gtable.attach(self.layer_button, 12, 36, 6, 10)
         self.gtable.attach(self.layer_info_icon, 36, 40, 6, 9)
-        self.gtable.attach(self.progress_bar, 0, 40, 13, 17)
+        if show_progress_bar == True:
+            self.gtable.attach(self.progress_bar, 0, 40, 13, 17)
         self.gtable.attach(self.machine_separator, 0, 40, 12, 13)
 
     def create_config_baseimg(self):
Signature · 1 line
1.7.6
author
#30 lore raw

PATCH 13/32 crumbs: Factor common dialogue configuration out

In reply to Shane Wang

Factor out the base dialogue configuration into CrumbsDialog and create a new CrumbsMessageDialog which acts as the CrumbsDialog did to handle dialogues with buttons.

Adopt CrumbsMessageDialog wherever CrumbsDialog was used.

---
 bitbake/lib/bb/ui/crumbs/builder.py |   28 ++++++++++++++--------------
 bitbake/lib/bb/ui/crumbs/hig.py     |   21 +++++++++++++++++----
 2 files changed, 31 insertions(+), 18 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +14 -14
index fc231ef..8573213 100755
@@ -33,7 +33,7 @@ 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.hobwidget import hwc
-from bb.ui.crumbs.hig import CrumbsDialog, BinbDialog, \
+from bb.ui.crumbs.hig import CrumbsMessageDialog, BinbDialog, \
                              AdvancedSettingDialog, LayerSelectionDialog, \
                              DeployImageDialog, ImageSelectionDialog
 
@@ -237,7 +237,7 @@ class Builder(gtk.Window):
         else:
             lbl = "<b>Screen dimension mismatched</b>\nfor better usability and visual effects,"
             lbl = lbl + " the screen dimension should be 1024x768 or above."
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             dialog.run()
             dialog.destroy()
@@ -447,7 +447,7 @@ class Builder(gtk.Window):
         if self.ignore_all_errors == False:
             lbl = "<b>Error</b>\n"
             lbl = lbl + "%s\n\n" % msg
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             dialog.add_button("Ignore All", gtk.RESPONSE_REJECT)
             response = dialog.run()
@@ -601,7 +601,7 @@ class Builder(gtk.Window):
 
     def destroy_window_cb(self, widget, event):
         lbl = "<b>Do you really want to exit the Hob image creator?</b>"
-        dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+        dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
         dialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES)
         dialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO)
         dialog.set_default_response(gtk.RESPONSE_NO)
@@ -618,7 +618,7 @@ class Builder(gtk.Window):
         if not all_recipes:
             lbl = "<b>No selections made</b>\nYou have not made any selections"
             lbl = lbl + " so there isn't anything to bake at this time."
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             dialog.run()
             dialog.destroy()
@@ -630,7 +630,7 @@ class Builder(gtk.Window):
         if not selected_packages:      
             lbl = "<b>No selections made</b>\nYou have not made any selections"
             lbl = lbl + " so there isn't anything to bake at this time."
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             dialog.run()
             dialog.destroy()
@@ -645,7 +645,7 @@ class Builder(gtk.Window):
         if not (selected_packages or selected_image != self.recipe_model.__dummy_image__):
             lbl = "<b>No selections made</b>\nYou have not made any selections"
             lbl = lbl + " so there isn't anything to bake at this time."
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             dialog.run()
             dialog.destroy()
@@ -716,7 +716,7 @@ class Builder(gtk.Window):
         if response == gtk.RESPONSE_YES:
             if not dialog.image_names:
                 lbl = "<b>No selections made</b>\nYou have not made any selections"
-                crumbs_dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+                crumbs_dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
                 crumbs_dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
                 crumbs_dialog.run()
                 crumbs_dialog.destroy()
@@ -758,7 +758,7 @@ class Builder(gtk.Window):
     def deploy_image(self, image_name):
         if not image_name:
             lbl = "<b>Please select an image to deploy.</b>"
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             dialog.run()
             dialog.destroy()
@@ -779,7 +779,7 @@ class Builder(gtk.Window):
     def runqemu_image(self, image_name):
         if not image_name:
             lbl = "<b>Please select an image to launch in QEMU.</b>"
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             dialog.run()
             dialog.destroy()
@@ -819,7 +819,7 @@ class Builder(gtk.Window):
                 lbl = lbl + "kernel path:" + kernel_path + "\n"
                 lbl = lbl + "source environment path:" + source_env_path + "\n"
                 lbl = lbl + "tmp path: " + tmp_path + "."
-                dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+                dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
                 dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
                 dialog.run()
                 dialog.destroy()
@@ -829,7 +829,7 @@ class Builder(gtk.Window):
         if selected_recipes and ask:
             lbl = "<b>Package list may be incomplete!</b>\nDo you want to build selected recipes"
             lbl = lbl + " to get a full list (Yes) or just view the existing packages (No)?"
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
             dialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES)
             dialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO)
             dialog.set_default_response(gtk.RESPONSE_YES)
@@ -860,7 +860,7 @@ class Builder(gtk.Window):
             lbl = lbl + "This will stop the build as quickly as possible but may"
             lbl = lbl + " well leave your build directory in an  unusable state"
             lbl = lbl + " that requires manual steps to fix.\n"
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
             dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
             dialog.add_button("Force Stop", gtk.RESPONSE_YES)
         else:
@@ -872,7 +872,7 @@ class Builder(gtk.Window):
             lbl = lbl + " progress build tasks are finished. However if a"
             lbl = lbl + " lengthy compilation phase is in progress this may take"
             lbl = lbl + " some time."
-            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
+            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
             dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
             dialog.add_button("Stop", gtk.RESPONSE_OK)
             dialog.add_button("Force Stop", gtk.RESPONSE_YES)
bitbake/lib/bb/ui/crumbs/hig.py +17 -4
index cbad899..85efbe6 100644
@@ -45,11 +45,24 @@ class CrumbsDialog(gtk.Dialog):
     A GNOME HIG compliant dialog widget.
     Add buttons with gtk.Dialog.add_button or gtk.Dialog.add_buttons
     """
+    def __init__(self, title="", parent=None, flags=0, buttons=None):
+        super(CrumbsDialog, self).__init__(title, parent, flags, buttons)
+
+        self.set_property("has-separator", False) # note: deprecated in 2.22
+
+        self.set_border_width(6)
+        self.vbox.set_property("spacing", 12)
+        self.action_area.set_property("spacing", 12)
+        self.action_area.set_property("border-width", 6)
+
+class CrumbsMessageDialog(CrumbsDialog):
+    """
+    A GNOME HIG compliant dialog widget.
+    Add buttons with gtk.Dialog.add_button or gtk.Dialog.add_buttons
+    """
     def __init__(self, parent=None, label="", icon=gtk.STOCK_INFO):
-        super(CrumbsDialog, self).__init__("", parent, gtk.DIALOG_DESTROY_WITH_PARENT)
+        super(CrumbsMessageDialog, self).__init__("", parent, gtk.DIALOG_DESTROY_WITH_PARENT)
         
-        #self.set_property("has-separator", False) # note: deprecated in 2.22
-
         self.set_border_width(6)
         self.vbox.set_property("spacing", 12)
         self.action_area.set_property("spacing", 12)
@@ -839,7 +852,7 @@ class LayerSelectionDialog (gtk.Dialog):
             else:
                 layer_store.append([path])
                 return
-            dialog = CrumbsDialog(parent, lbl)
+            dialog = CrumbsMessageDialog(parent, lbl)
             dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
             response = dialog.run()
             dialog.destroy()
Signature · 1 line
1.7.6
author
#22 lore raw

PATCH 9/32 Hob: fix a bug in builder.configuration.curr_mach

In reply to Shane Wang

When the user changes the machine to be "--select a machine--", the builder.configuration.curr_mach should be set to empty. Otherwise, if the user adds more layers after the above, the action will trigger recipe parsing, which is not correct.

---
 bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py +1 -0
index 4083360..cd86606 100644
@@ -243,6 +243,7 @@ class ImageConfigurationPage (HobPage):
     def machine_combo_changed_cb(self, machine_combo):
         combo_item = machine_combo.get_active_text()
         if not combo_item or combo_item == self.__dummy_machine__:
+            self.builder.configuration.curr_mach = ""
             self.builder.switch_page(self.builder.MACHINE_SELECTION)
         else:
             self.builder.configuration.curr_mach = combo_item
Signature · 1 line
1.7.6
author
#31 lore raw

PATCH 14/32 crumbs/builder: use the name Hob consistently

In reply to Shane Wang

We have mentions of HOB and Hob, the approved name is Hob.

"the name's Hob, BitBake Hob"
- Surly BitBake GUI

---
 bitbake/lib/bb/ui/crumbs/builder.py |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +2 -2
index 8573213..3daa677 100755
@@ -225,7 +225,7 @@ class Builder(gtk.Window):
         self.switch_page(self.MACHINE_SELECTION)
 
     def create_visual_elements(self):
-        self.set_title("HOB -- Image Creator")
+        self.set_title("Hob - Image Creator")
         self.set_icon_name("applications-development")
         self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
         self.set_resizable(True)
@@ -683,7 +683,7 @@ class Builder(gtk.Window):
                                       (gtk.STOCK_OPEN, gtk.RESPONSE_YES,
                                        gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
         filter = gtk.FileFilter()
-        filter.set_name("HOB Files")
+        filter.set_name("Hob Files")
         filter.add_pattern("*.hob")
         dialog.add_filter(filter)
 
Signature · 1 line
1.7.6
author
#32 lore raw

PATCH 15/32 crumbs: move towards more standard dialogue spacing

In reply to Shane Wang

Inherit from the base CrumbsDialog class which implements standard border and spacing.

Switch all explicitly set dialogue spacings to 6 to converge towards GNOME HIG.

---
 bitbake/lib/bb/ui/crumbs/hig.py |   66 +++++++++++++++++----------------------
 1 files changed, 29 insertions(+), 37 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +29 -37
index 85efbe6..fdff10b 100644
@@ -113,7 +113,7 @@ class BinbDialog(gtk.Dialog):
 #
 # AdvancedSettings Dialog
 #
-class AdvancedSettingDialog (gtk.Dialog):
+class AdvancedSettingDialog (CrumbsDialog):
 
     def gen_label_widget(self, content):
         label = gtk.Label()
@@ -311,7 +311,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         scroll.set_size_request(200,60)
         pkgfmt_hbox.pack_start(scroll, False, False, 0)
 
-        vbox = gtk.VBox(False, 5)
+        vbox = gtk.VBox(False, 6)
         pkgfmt_hbox.pack_start(vbox, False, False, 15)
 
         up = gtk.Button()
@@ -483,8 +483,8 @@ class AdvancedSettingDialog (gtk.Dialog):
         self.show_all()
 
     def create_image_types_page(self):
-        advanced_vbox = gtk.VBox(False, 15)
-        advanced_vbox.set_border_width(20)
+        advanced_vbox = gtk.VBox(False, 6)
+        advanced_vbox.set_border_width(6)
 
         rows = (len(self.image_types)+1)/2
         table = gtk.Table(rows + 1, 10, True)
@@ -515,10 +515,10 @@ class AdvancedSettingDialog (gtk.Dialog):
         return advanced_vbox
 
     def create_output_page(self):
-        advanced_vbox = gtk.VBox(False, 15)
-        advanced_vbox.set_border_width(20)
+        advanced_vbox = gtk.VBox(False, 6)
+        advanced_vbox.set_border_width(6)
 
-        sub_vbox = gtk.VBox(False, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">Packaging Format:</span>")
         tooltip = "Select package formats that will be used. "
@@ -527,7 +527,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(pkgfmt_widget, expand=False, fill=False)
 
-        sub_vbox = gtk.VBox(False, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">Image Rootfs Size: (MB)</span>")
         tooltip = "Sets the size of your target image.\nThis is the basic size of your target image, unless your selected package size exceeds this value, or you set value to \"Image Extra Size\"."
@@ -535,7 +535,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         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, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">Image Extra Size: (MB)</span>")
         tooltip = "Sets the extra free space of your target image.\nDefaultly, system will reserve 30% of your image size as your free space. If your image contains zypper, it will bring in 50MB more space. The maximum free space is 1024MB."
@@ -551,7 +551,7 @@ class AdvancedSettingDialog (gtk.Dialog):
             self.gplv3_checkbox.set_active(False)
         advanced_vbox.pack_start(self.gplv3_checkbox, expand=False, fill=False)
 
-        sub_hbox = gtk.HBox(False, 5)
+        sub_hbox = gtk.HBox(False, 6)
         advanced_vbox.pack_start(sub_hbox, expand=False, fill=False)
         self.toolchain_checkbox = gtk.CheckButton("Build Toolchain")
         self.toolchain_checkbox.set_tooltip_text("Check this box to build the related toolchain with your image")
@@ -565,10 +565,10 @@ class AdvancedSettingDialog (gtk.Dialog):
         return advanced_vbox
 
     def create_build_environment_page(self):
-        advanced_vbox = gtk.VBox(False, 15)
-        advanced_vbox.set_border_width(20)
+        advanced_vbox = gtk.VBox(False, 6)
+        advanced_vbox.set_border_width(6)
 
-        sub_vbox = gtk.VBox(False, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">Select Distro:</span>")
         tooltip = "This is the Yocto distribution you would like to use"
@@ -576,7 +576,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(distro_widget, expand=False, fill=False)
 
-        sub_vbox = gtk.VBox(False, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">BB_NUMBER_THREADS:</span>")
         tooltip = "Sets the number of threads that bitbake tasks can run simultaneously"
@@ -584,7 +584,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(bbthread_widget, expand=False, fill=False)
 
-        sub_vbox = gtk.VBox(False, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">PARALLEL_MAKE:</span>")
         tooltip = "Sets the make parallism, as known as 'make -j'"
@@ -592,7 +592,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(pmake_widget, expand=False, fill=False)
 
-        sub_vbox = gtk.VBox(False, 5)
+        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 Download Directory:</span>")
         tooltip = "Select a folder that caches the upstream project source code"
@@ -600,7 +600,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(dldir_widget, expand=False, fill=False)
 
-        sub_vbox = gtk.VBox(False, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">Select SSTATE Directory:</span>")
         tooltip = "Select a folder that caches your prebuilt results"
@@ -608,7 +608,7 @@ class AdvancedSettingDialog (gtk.Dialog):
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(sstatedir_widget, expand=False, fill=False)
 
-        sub_vbox = gtk.VBox(False, 5)
+        sub_vbox = gtk.VBox(False, 6)
         advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
         label = self.gen_label_widget("<span weight=\"bold\">Select SSTATE Mirror:</span>")
         tooltip = "Select the prebuilt mirror that will fasten your build speed"
@@ -619,10 +619,10 @@ class AdvancedSettingDialog (gtk.Dialog):
         return advanced_vbox
 
     def create_others_page(self):
-        advanced_vbox = gtk.VBox(False, 15)
-        advanced_vbox.set_border_width(20)
+        advanced_vbox = gtk.VBox(False, 6)
+        advanced_vbox.set_border_width(6)
 
-        sub_vbox = gtk.VBox(False, 5)
+        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 = "This is the key/value pair for your extra settings"
@@ -687,7 +687,7 @@ class AdvancedSettingDialog (gtk.Dialog):
 #
 # DeployImageDialog
 #
-class DeployImageDialog (gtk.Dialog):
+class DeployImageDialog (CrumbsDialog):
 
     __dummy_usb__ = "--select a usb drive--"
 
@@ -700,7 +700,6 @@ class DeployImageDialog (gtk.Dialog):
         self.connect("response", self.response_cb)
 
     def create_visual_elements(self):
-        self.set_border_width(20)
         self.set_default_size(500, 250)
 
         label = gtk.Label()
@@ -807,7 +806,7 @@ class DeployImageDialog (gtk.Dialog):
 #
 # LayerSelectionDialog
 #
-class LayerSelectionDialog (gtk.Dialog):
+class LayerSelectionDialog (CrumbsDialog):
 
     def gen_label_widget(self, content):
         label = gtk.Label()
@@ -864,7 +863,7 @@ class LayerSelectionDialog (gtk.Dialog):
 
 
     def gen_layer_widget(self, split_model, layers, layers_avail, window, tooltip=""):
-        hbox = gtk.HBox(False, 10)
+        hbox = gtk.HBox(False, 6)
 
         layer_tv = gtk.TreeView()
         layer_tv.set_rules_hint(True)
@@ -917,13 +916,13 @@ class LayerSelectionDialog (gtk.Dialog):
             add_button = gtk.Button()
             add_button.set_image(image)
             add_button.connect("clicked", self.layer_widget_add_clicked_cb, layer_store, window)
-            table_layer.attach(add_button, 0, 5, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 0)
+            table_layer.attach(add_button, 0, 5, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
             image = gtk.Image()
             image.set_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_MENU)
             del_button = gtk.Button()
             del_button.set_image(image)
             del_button.connect("clicked", self.layer_widget_del_clicked_cb, tree_selection, layer_store)
-            table_layer.attach(del_button, 5, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 0)
+            table_layer.attach(del_button, 5, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
         layer_tv.set_model(layer_store)
 
         hbox.show_all()
@@ -948,11 +947,8 @@ class LayerSelectionDialog (gtk.Dialog):
         self.connect("response", self.response_cb)
                 
     def create_visual_elements(self):
-        self.set_border_width(20)
         self.set_default_size(400, 250)
-
         hbox_top = gtk.HBox()
-        self.set_border_width(12)
         self.vbox.pack_start(hbox_top, expand=False, fill=False)
 
         if self.split_model:
@@ -1001,7 +997,7 @@ class LayerSelectionDialog (gtk.Dialog):
         self.layers_changed = (self.layers != layers)
         self.layers = layers
 
-class ImageSelectionDialog (gtk.Dialog):
+class ImageSelectionDialog (CrumbsDialog):
 
     __columns__ = [{
             'col_name' : 'Image name',
@@ -1034,11 +1030,7 @@ class ImageSelectionDialog (gtk.Dialog):
         self.fill_image_store()
 
     def create_visual_elements(self):
-        self.set_border_width(20)
-        self.set_default_size(600, 300)
-        self.vbox.set_spacing(10)
-
-        hbox = gtk.HBox(False, 10)
+        hbox = gtk.HBox(False, 6)
         self.vbox.pack_start(hbox, expand=False, fill=False)
 
         entry = gtk.Entry()
@@ -1048,7 +1040,7 @@ class ImageSelectionDialog (gtk.Dialog):
         hbox.pack_start(table, expand=False, fill=False)
         table.attach(entry, 0, 9, 0, 1)
         image = gtk.Image()
-        image.set_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)
+        image.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON)
         open_button = gtk.Button()
         open_button.set_image(image)
         open_button.connect("clicked", self.select_path_cb, self, entry)
Signature · 1 line
1.7.6
author
#33 lore raw

PATCH 16/32 crumbs: fix button order in several dialogues

In reply to Shane Wang

GNOME HIG and Gtk+ convention is for the buttons to be ordered <secondary action> <primary action> so that the primary action can be selected easily by navigating to the bottom right of the dialogue.

We should try and match the convention and the HIG standard so that we aren't contrasting the rest of the users applications.

---
 bitbake/lib/bb/ui/crumbs/builder.py |   39 +++++++++++++++++------------------
 bitbake/lib/bb/ui/crumbs/hig.py     |   12 +++++-----
 2 files changed, 25 insertions(+), 26 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +19 -20
index 3daa677..7772f56 100755
@@ -602,9 +602,9 @@ class Builder(gtk.Window):
     def destroy_window_cb(self, widget, event):
         lbl = "<b>Do you really want to exit the Hob image creator?</b>"
         dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
-        dialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES)
-        dialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO)
-        dialog.set_default_response(gtk.RESPONSE_NO)
+        dialog.add_button("Keep using Hob", gtk.RESPONSE_NO)
+        dialog.add_button("Exit Hob", gtk.RESPONSE_YES)
+        dialog.set_default_response(gtk.RESPONSE_YES)
         response = dialog.run()
         dialog.destroy()
         if response == gtk.RESPONSE_YES:
@@ -667,8 +667,8 @@ class Builder(gtk.Window):
                      flags = gtk.DIALOG_MODAL
                          | gtk.DIALOG_DESTROY_WITH_PARENT
                          | gtk.DIALOG_NO_SEPARATOR,
-                     buttons = (gtk.STOCK_OK, gtk.RESPONSE_YES,
-                                gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+                     buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                gtk.STOCK_OK, gtk.RESPONSE_YES))
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             self.configuration.layers = dialog.layers
@@ -679,9 +679,9 @@ class Builder(gtk.Window):
 
     def show_load_template_dialog(self):
         dialog = gtk.FileChooserDialog("Load Template Files", self,
-                                       gtk.FILE_CHOOSER_ACTION_SAVE,
-                                      (gtk.STOCK_OPEN, gtk.RESPONSE_YES,
-                                       gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+                                       gtk.FILE_CHOOSER_ACTION_OPEN,
+                                      (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                       gtk.STOCK_OPEN, gtk.RESPONSE_YES))
         filter = gtk.FileFilter()
         filter.set_name("Hob Files")
         filter.add_pattern("*.hob")
@@ -696,8 +696,8 @@ class Builder(gtk.Window):
     def show_save_template_dialog(self):
         dialog = gtk.FileChooserDialog("Save Template Files", self,
                                        gtk.FILE_CHOOSER_ACTION_SAVE,
-                                      (gtk.STOCK_SAVE, gtk.RESPONSE_YES,
-                                       gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+                                      (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                       gtk.STOCK_SAVE, gtk.RESPONSE_YES))
         dialog.set_current_name("hob")
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
@@ -709,9 +709,8 @@ class Builder(gtk.Window):
         dialog = ImageSelectionDialog(self.parameters.image_addr, self.parameters.image_types,
                                       "Open My Images", self,
                                        gtk.FILE_CHOOSER_ACTION_SAVE,
-                                      (gtk.STOCK_OPEN, gtk.RESPONSE_YES,
-                                       gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
-
+                                      (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                       gtk.STOCK_OPEN, gtk.RESPONSE_YES))
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             if not dialog.image_names:
@@ -742,8 +741,8 @@ class Builder(gtk.Window):
             flags = gtk.DIALOG_MODAL
                     | gtk.DIALOG_DESTROY_WITH_PARENT
                     | gtk.DIALOG_NO_SEPARATOR,
-            buttons = ("Save", gtk.RESPONSE_YES,
-                       gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+            buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                       "Save", gtk.RESPONSE_YES))
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             self.configuration = dialog.configuration
@@ -771,8 +770,8 @@ class Builder(gtk.Window):
             flags = gtk.DIALOG_MODAL
                     | gtk.DIALOG_DESTROY_WITH_PARENT
                     | gtk.DIALOG_NO_SEPARATOR,
-            buttons = ("Make usb image", gtk.RESPONSE_YES,
-                       "Close", gtk.RESPONSE_NO))
+            buttons = ("Close", gtk.RESPONSE_NO,
+                       "Make usb image", gtk.RESPONSE_YES))
         response = dialog.run()
         dialog.destroy()
 
@@ -787,8 +786,8 @@ class Builder(gtk.Window):
 
         dialog = gtk.FileChooserDialog("Load Kernel Files", self,
                                        gtk.FILE_CHOOSER_ACTION_SAVE,
-                                      (gtk.STOCK_OPEN, gtk.RESPONSE_YES,
-                                       gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+                                      (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                       gtk.STOCK_OPEN, gtk.RESPONSE_YES))
         filter = gtk.FileFilter()
         filter.set_name("Kernel Files")
         filter.add_pattern("*.bin")
@@ -830,8 +829,8 @@ class Builder(gtk.Window):
             lbl = "<b>Package list may be incomplete!</b>\nDo you want to build selected recipes"
             lbl = lbl + " to get a full list (Yes) or just view the existing packages (No)?"
             dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
-            dialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES)
             dialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO)
+            dialog.add_button(gtk.STOCK_YES, gtk.RESPONSE_YES)
             dialog.set_default_response(gtk.RESPONSE_YES)
             response = dialog.run()
             dialog.destroy()
bitbake/lib/bb/ui/crumbs/hig.py +6 -6
index fdff10b..ec9dbec 100644
@@ -162,8 +162,8 @@ class AdvancedSettingDialog (CrumbsDialog):
     def entry_widget_select_path_cb(self, action, parent, entry):
         dialog = gtk.FileChooserDialog("", parent,
                                        gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                                       (gtk.STOCK_OK, gtk.RESPONSE_YES,
-                                        gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+                                       (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                        gtk.STOCK_OPEN, gtk.RESPONSE_YES))
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             path = dialog.get_filename()
@@ -823,8 +823,8 @@ class LayerSelectionDialog (CrumbsDialog):
     def layer_widget_add_clicked_cb(self, action, layer_store, parent):
         dialog = gtk.FileChooserDialog("Add new layer", parent,
                                        gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                                       (gtk.STOCK_OK, gtk.RESPONSE_YES,
-                                        gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+                                       (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                        gtk.STOCK_OPEN, gtk.RESPONSE_YES))
         label = gtk.Label("Select the layer you wish to add")
         label.show()
         dialog.set_extra_widget(label)
@@ -1068,8 +1068,8 @@ class ImageSelectionDialog (CrumbsDialog):
     def select_path_cb(self, action, parent, entry):
         dialog = gtk.FileChooserDialog("", parent,
                                        gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
-                                       (gtk.STOCK_OK, gtk.RESPONSE_YES,
-                                        gtk.STOCK_CANCEL, gtk.RESPONSE_NO))
+                                       (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
+                                        gtk.STOCK_OPEN, gtk.RESPONSE_YES))
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             path = dialog.get_filename()
Signature · 1 line
1.7.6
author
#36 lore raw

PATCH 19/32 Hob(crumbs/builder.py): remove the code commented out in the builder.py

In reply to Shane Wang
---
 bitbake/lib/bb/ui/crumbs/builder.py |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +0 -1
index 7772f56..0d7f1c1 100755
@@ -200,7 +200,6 @@ class Builder(gtk.Window):
         self.create_visual_elements()
 
         # connect the signals to functions
-        #self.connect("configure-event", self.resize_window_cb)
         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)
Signature · 1 line
1.7.6
author
#34 lore raw

PATCH 17/32 hig: try to avoid setting explicit dialogue sizes

In reply to Shane Wang

Gtk+ does a good job of creating dialogues which fit all of the packed widgets and respect the spacing. Let it do its job.

---
 bitbake/lib/bb/ui/crumbs/hig.py |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +2 -5
index ec9dbec..6776b3d 100644
@@ -468,8 +468,6 @@ class AdvancedSettingDialog (CrumbsDialog):
         self.connect("response", self.response_cb)
 
     def create_visual_elements(self):
-        self.set_size_request(500, 500)
-
         self.nb = gtk.Notebook()
         self.nb.set_show_tabs(True)
         self.nb.append_page(self.create_image_types_page(), gtk.Label("Image types"))
@@ -700,8 +698,6 @@ class DeployImageDialog (CrumbsDialog):
         self.connect("response", self.response_cb)
 
     def create_visual_elements(self):
-        self.set_default_size(500, 250)
-
         label = gtk.Label()
         label.set_alignment(0.0, 0.5)
         markup = "<span font_desc='12'>The image to be written into usb drive:</span>"
@@ -947,7 +943,6 @@ class LayerSelectionDialog (CrumbsDialog):
         self.connect("response", self.response_cb)
                 
     def create_visual_elements(self):
-        self.set_default_size(400, 250)
         hbox_top = gtk.HBox()
         self.vbox.pack_start(hbox_top, expand=False, fill=False)
 
@@ -964,6 +959,7 @@ class LayerSelectionDialog (CrumbsDialog):
         hbox_top.pack_end(image, expand=False, fill=False)
 
         layer_widget, self.layer_store = self.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
+        layer_widget.set_size_request(-1, 180)
 
         self.vbox.pack_start(layer_widget, expand=True, fill=True)
 
@@ -1031,6 +1027,7 @@ class ImageSelectionDialog (CrumbsDialog):
 
     def create_visual_elements(self):
         hbox = gtk.HBox(False, 6)
+
         self.vbox.pack_start(hbox, expand=False, fill=False)
 
         entry = gtk.Entry()
Signature · 1 line
1.7.6
author
#35 lore raw

PATCH 18/32 crumbs/hig: tweak UI and layout of LayerSelectionDialog

In reply to Shane Wang

Several minor tweaks for appearance:
* Try to rework the labels so that the English flows better
* Fix spacing
* Remove the separator - it's not needed

---
 bitbake/lib/bb/ui/crumbs/hig.py |   19 +++++--------------
 1 files changed, 5 insertions(+), 14 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +5 -14
index 6776b3d..9b96d8d 100644
@@ -947,9 +947,9 @@ class LayerSelectionDialog (CrumbsDialog):
         self.vbox.pack_start(hbox_top, expand=False, fill=False)
 
         if self.split_model:
-            label = self.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>\n(Available layers under '${COREBASE}/layers/' directory)")
+            label = self.gen_label_widget("<b>Select Layers:</b>\n(Available layers under '${COREBASE}/layers/' directory)")
         else:
-            label = self.gen_label_widget("<span weight=\"bold\" font_desc='12'>Select Layers:</span>")
+            label = self.gen_label_widget("<b>Select Layers:</b>")
         hbox_top.pack_start(label, expand=False, fill=False)
 
         tooltip = "Layer is a collection of bb files and conf files"
@@ -960,20 +960,11 @@ class LayerSelectionDialog (CrumbsDialog):
 
         layer_widget, self.layer_store = self.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
         layer_widget.set_size_request(-1, 180)
-
         self.vbox.pack_start(layer_widget, expand=True, fill=True)
 
-        separator = gtk.HSeparator()
-        self.vbox.pack_start(separator, False, True, 5)
-        separator.show()
-
-        hbox_button = gtk.HBox()
-        self.vbox.pack_end(hbox_button, expand=False, fill=False)
-        hbox_button.show()
-
-        label = self.gen_label_widget("<i>'meta' is Core layer for Yocto images</i>\n"
-        "<span weight=\"bold\">Please do not remove it</span>")
-        hbox_button.pack_start(label, expand=False, fill=False)
+        label = self.gen_label_widget("<b>Note:</b> '<i>meta</i>' is the Core layer for Yocto images please do not remove it.")
+        label.show()
+        self.vbox.pack_end(label, expand=False, fill=False)
 
         self.show_all()
 
Signature · 1 line
1.7.6
author
#38 lore raw

PATCH 20/32 command.py: remove the resolve parameter in generateTargetsTree

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

Remove the "resolve" parameter since the original resolve=False option is no longer be used.

---
 bitbake/lib/bb/command.py                   |   14 +---------
 bitbake/lib/bb/cooker.py                    |   33 +++++++++++---------------
 bitbake/lib/bb/ui/crumbs/hobeventhandler.py |    2 +-
 3 files changed, 17 insertions(+), 32 deletions(-)
bitbake/lib/bb/command.py +2 -12
index 06e8869..1799f1c 100644
@@ -242,21 +242,11 @@ class CommandsAsync:
         included in the package list.
         If pkg_list provided use that list (plus any extras brought in by
         klass) rather than generating a tree for all packages.
-
-        Add a new option "resolve" to indicate if we need to resolve the
-        replacement for "virtual/xxx" like pn.
         """
         klass = params[0]
-        resolve = False
-        if len(params) > 2:
-            pkg_list = params[1]
-            resolve = params[2]
-        elif len(params) > 1:
-            pkg_list = params[1]
-        else:
-            pkg_list = []
+        pkg_list = params[1]
 
-        command.cooker.generateTargetsTree(klass, pkg_list, resolve)
+        command.cooker.generateTargetsTree(klass, pkg_list)
         command.finishAsyncCommand()
     generateTargetsTree.needcache = True
 
bitbake/lib/bb/cooker.py +14 -19
index 12b526b..2e4a1ba 100644
@@ -451,7 +451,7 @@ class BBCooker:
                 depend_tree_package[package]["filename"] = fn
                 depend_tree_package[package]["version"] = version
 
-    def generatePkgDepTreeData(self, pkgs_to_build, task, resolve=False):
+    def generatePkgDepTreeData(self, pkgs_to_build, task):
         """
         Create a dependency tree of pkgs_to_build, returning the data.
         """
@@ -497,19 +497,16 @@ class BBCooker:
 
                 depend_tree["depends"][pn] = []
                 for dep in taskdata.depids[fnid]:
-                    if resolve:
-                        item = taskdata.build_names_index[dep]
-                        pn_provider = ""
-                        targetid = taskdata.getbuild_id(item)
-                        if targetid in taskdata.build_targets and taskdata.build_targets[targetid]:
-                            fnid = taskdata.build_targets[targetid][0]
-                            fn_provider = taskdata.fn_index[fnid]
-                            pn_provider = self.status.pkg_fn[fn_provider]
-                        else:
-                            pn_provider = item
-                        depend_tree["depends"][pn].append(pn_provider)
+                    item = taskdata.build_names_index[dep]
+                    pn_provider = ""
+                    targetid = taskdata.getbuild_id(item)
+                    if targetid in taskdata.build_targets and taskdata.build_targets[targetid]:
+                        fnid = taskdata.build_targets[targetid][0]
+                        fn_provider = taskdata.fn_index[fnid]
+                        pn_provider = self.status.pkg_fn[fn_provider]
                     else:
-                        depend_tree["depends"][pn].append(taskdata.build_names_index[dep])
+                        pn_provider = item
+                    depend_tree["depends"][pn].append(pn_provider)
 
                 depend_tree["rdepends-pn"][pn] = []
                 for rdep in taskdata.rdepids[fnid]:
@@ -519,8 +516,7 @@ class BBCooker:
                     depend_tree["rdepends-pkg"][package] = []
                     for rdepend in rdepends[package]:
                         depend_tree["rdepends-pkg"][package].append(rdepend)
-                        if resolve:
-                            self.append_package(taskdata, depend_tree["packages"], rdepend)
+                        self.append_package(taskdata, depend_tree["packages"], rdepend)
                     if not package in packages:
                         packages.append(package)
 
@@ -528,8 +524,7 @@ class BBCooker:
                     depend_tree["rrecs-pkg"][package] = []
                     for rrec in rrecs[package]:
                         depend_tree["rrecs-pkg"][package].append(rrec)
-                        if resolve:
-                            self.append_package(taskdata, depend_tree["packages"], rrec)
+                        self.append_package(taskdata, depend_tree["packages"], rrec)
                     if not package in packages:
                         packages.append(package)
 
@@ -780,7 +775,7 @@ class BBCooker:
 
         return pkg_list
 
-    def generateTargetsTree(self, klass=None, pkgs=[], resolve=False):
+    def generateTargetsTree(self, klass=None, pkgs=[]):
         """
         Generate a dependency tree of buildable targets
         Generate an event with the result
@@ -795,7 +790,7 @@ class BBCooker:
             pkgs = pkgs + extra_pkgs
 
         # generate a dependency tree for all our packages
-        tree = self.generatePkgDepTreeData(pkgs, 'build', resolve)
+        tree = self.generatePkgDepTreeData(pkgs, 'build')
         bb.event.fire(bb.event.TargetsTreeGenerated(tree), self.configuration.data)
 
     def buildWorldTargetList(self):
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +1 -1
index 2bf4ed8..6c109fc 100644
@@ -148,7 +148,7 @@ class HobHandler(gobject.GObject):
         elif next_command == self.PARSE_BBFILES:
             self.server.runCommand(["parseFiles"])
         elif next_command == self.GENERATE_TGTS:
-            self.server.runCommand(["generateTargetsTree", "classes/image.bbclass", [], True])
+            self.server.runCommand(["generateTargetsTree", "classes/image.bbclass", []])
         elif next_command == self.GENERATE_PACKAGEINFO:
             self.server.runCommand(["triggerEvent", "bb.event.RequestPackageInfo()"])
         elif next_command == self.BUILD_TARGET_RECIPES:
Signature · 1 line
1.7.6
author
#42 lore raw

PATCH 22/32 cooker: fix calculating of depends and rdepends

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

Remove part of the original logic that stores pkg dependency and pkg recomends, which will not be used in Hob.

Add the judgement for preferred fn provider of a certain package, which maps package name to its providing recipe name.

The above approaches correct the build dependency calculation, and they also reduced the total depend_tree size, which speed up the tree data generation time.

---
 bitbake/lib/bb/cooker.py |   45 ++++++++++-----------------------------------
 1 files changed, 10 insertions(+), 35 deletions(-)
bitbake/lib/bb/cooker.py +10 -35
index b23b569..e71f72b 100644
@@ -438,19 +438,6 @@ class BBCooker:
 
         return depend_tree
 
-    def append_package(self, taskdata, depend_tree_package, package):
-        if package not in depend_tree_package:
-            targetid = taskdata.getrun_id(package)
-            if targetid in taskdata.run_targets and taskdata.run_targets[targetid]:
-                fnid = taskdata.run_targets[targetid][0]
-                fn = taskdata.fn_index[fnid]
-                pn = self.status.pkg_fn[fn]
-                version  = "%s:%s-%s" % self.status.pkg_pepvpr[fn]
-                depend_tree_package[package] = {}
-                depend_tree_package[package]["pn"] = pn
-                depend_tree_package[package]["filename"] = fn
-                depend_tree_package[package]["version"] = version
-
     def generatePkgDepTreeData(self, pkgs_to_build, task):
         """
         Create a dependency tree of pkgs_to_build, returning the data.
@@ -466,7 +453,6 @@ class BBCooker:
         depend_tree["depends"] = {}
         depend_tree["pn"] = {}
         depend_tree["rdepends-pn"] = {}
-        depend_tree["packages"] = {}
         depend_tree["rdepends-pkg"] = {}
         depend_tree["rrecs-pkg"] = {}
 
@@ -493,7 +479,6 @@ class BBCooker:
 
             if fnid not in seen_fnids:
                 seen_fnids.append(fnid)
-                packages = []
 
                 depend_tree["depends"][pn] = []
                 for dep in taskdata.depids[fnid]:
@@ -510,26 +495,16 @@ class BBCooker:
 
                 depend_tree["rdepends-pn"][pn] = []
                 for rdep in taskdata.rdepids[fnid]:
-                    depend_tree["rdepends-pn"][pn].append(taskdata.run_names_index[rdep])
-
-                for package in rdepends:
-                    depend_tree["rdepends-pkg"][package] = []
-                    for rdepend in rdepends[package]:
-                        depend_tree["rdepends-pkg"][package].append(rdepend)
-                        self.append_package(taskdata, depend_tree["packages"], rdepend)
-                    if not package in packages:
-                        packages.append(package)
-
-                for package in rrecs:
-                    depend_tree["rrecs-pkg"][package] = []
-                    for rrec in rrecs[package]:
-                        depend_tree["rrecs-pkg"][package].append(rrec)
-                        self.append_package(taskdata, depend_tree["packages"], rrec)
-                    if not package in packages:
-                        packages.append(package)
-
-                for package in packages:
-                    self.append_package(taskdata, depend_tree["packages"], package)
+                    item = taskdata.run_names_index[rdep]
+                    pn_rprovider = ""
+                    targetid = taskdata.getrun_id(item)
+                    if targetid in taskdata.run_targets and taskdata.run_targets[targetid]:
+                        id = taskdata.run_targets[targetid][0]
+                        fn_rprovider = taskdata.fn_index[id]
+                        pn_rprovider = self.status.pkg_fn[fn_rprovider]
+                    else:
+                        pn_rprovider = item
+                    depend_tree["rdepends-pn"][pn].append(pn_rprovider)
 
         return depend_tree
 
Signature · 1 line
1.7.6
author
#40 lore raw

PATCH 21/32 cooker.py: Fix a bug due to variable name

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

fnid is an outer variable and shouldn't be overrided, change the inner variable name from 'fnid' to 'id'.

---
 bitbake/lib/bb/cooker.py |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
bitbake/lib/bb/cooker.py +2 -2
index 2e4a1ba..b23b569 100644
@@ -501,8 +501,8 @@ class BBCooker:
                     pn_provider = ""
                     targetid = taskdata.getbuild_id(item)
                     if targetid in taskdata.build_targets and taskdata.build_targets[targetid]:
-                        fnid = taskdata.build_targets[targetid][0]
-                        fn_provider = taskdata.fn_index[fnid]
+                        id = taskdata.build_targets[targetid][0]
+                        fn_provider = taskdata.fn_index[id]
                         pn_provider = self.status.pkg_fn[fn_provider]
                     else:
                         pn_provider = item
Signature · 1 line
1.7.6
author
#44 lore raw

PATCH 23/32 Hob(crumbs/hoblistmodel.py): Fix recipe's populate() function

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

According to the cooker's change, this commit fixes the way to getting recipe's build dependency.

---
 bitbake/lib/bb/ui/crumbs/hoblistmodel.py |   42 +++--------------------------
 1 files changed, 5 insertions(+), 37 deletions(-)
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +5 -37
index 227ae4b..e440979 100644
@@ -512,27 +512,6 @@ class RecipeListModel(gtk.ListStore):
             it = view_model.iter_next(it)
         return None
 
-    def map_runtime(self, event_model, runtime, rdep_type, name):
-        if rdep_type not in ['pkg', 'pn'] or runtime not in ['rdepends', 'rrecs']:
-            return
-        package_depends = event_model["%s-%s" % (runtime, rdep_type)].get(name, [])
-        pn_depends = []
-        for package_depend in package_depends:
-            if 'task-' not in package_depend and package_depend in event_model["packages"].keys():
-                pn_depends.append(event_model["packages"][package_depend]["pn"])
-            else:
-                pn_depends.append(package_depend)
-        return list(set(pn_depends))
-
-    def subpkg_populate(self, event_model, pkg, desc, lic, group, atype, pn):
-        pn_depends = self.map_runtime(event_model, "rdepends", "pkg", pkg)
-        pn_depends += self.map_runtime(event_model, "rrecs", "pkg", pkg)
-        self.set(self.append(), self.COL_NAME, pkg, self.COL_DESC, desc,
-                 self.COL_LIC, lic, self.COL_GROUP, group,
-                 self.COL_DEPS, " ".join(pn_depends), self.COL_BINB, "",
-                 self.COL_TYPE, atype, self.COL_INC, False,
-                 self.COL_IMG, False, self.COL_INSTALL, "", self.COL_PN, pn)
-
     """
     The populate() function takes as input the data from a
     bb.event.TargetsTreeGenerated event and populates the RecipeList.
@@ -558,38 +537,27 @@ class RecipeListModel(gtk.ListStore):
             group = event_model["pn"][item]["section"]
             install = []
 
+            depends = event_model["depends"].get(item, [])
+            rdepends = event_model["rdepends-pn"].get(item, [])
+            depends = depends + rdepends
+
             if ('task-' in name):
                 if ('lib32-' in name or 'lib64-' in name):
                     atype = 'mltask'
                 else:
                     atype = 'task'
-                for pkg in event_model["pn"][name]["packages"]:
-                    self.subpkg_populate(event_model, pkg, desc, lic, group, atype, name)
-                continue
-
             elif ('-image-' in name):
                 atype = 'image'
-                depends = event_model["depends"].get(item, [])
-                rdepends = self.map_runtime(event_model, 'rdepends', 'pn', name)
-                depends = depends + rdepends
-                install = event_model["rdepends-pn"].get(item, [])
-
+                install = rdepends
             elif ('meta-' in name):
                 atype = 'toolchain'
-
             elif (name == 'dummy-image' or name == 'dummy-toolchain'):
                 atype = 'dummy'
-
             else:
                 if ('lib32-' in name or 'lib64-' in name):
                     atype = 'mlrecipe'
                 else:
                     atype = 'recipe'
-                depends = event_model["depends"].get(item, [])
-                depends += self.map_runtime(event_model, 'rdepends', 'pn', item)
-                for pkg in event_model["pn"][name]["packages"]:
-                    depends += self.map_runtime(event_model, 'rdepends', 'pkg', item)
-                    depends += self.map_runtime(event_model, 'rrecs', 'pkg', item)
 
             self.set(self.append(), self.COL_NAME, item, self.COL_DESC, desc,
                      self.COL_LIC, lic, self.COL_GROUP, group,
Signature · 1 line
1.7.6
author
#46 lore raw

PATCH 24/32 Hob(crumbs/hoblistmodel.py): Add mapping for rprovides and pkg

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

When checking the package's RDEPENDS information, we will see some case like A RDEPENDS virtual-b, and B RPROVIDES virtual-b, we need to reflect this relationship in packaging selection.

---
 bitbake/lib/bb/ui/crumbs/hoblistmodel.py |   18 +++++++++++++++---
 1 files changed, 15 insertions(+), 3 deletions(-)
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +15 -3
index e440979..e910944 100644
@@ -51,6 +51,7 @@ class PackageListModel(gtk.TreeStore):
         self.pkgs_size = 0
         self.pn_path = {}
         self.pkg_path = {}
+        self.rprov_pkg = {}
         
         gtk.TreeStore.__init__ (self,
                                 gobject.TYPE_STRING,
@@ -71,10 +72,18 @@ class PackageListModel(gtk.TreeStore):
     Returns the path in the model or None
     """
     def find_path_for_item(self, item_name):
+        pkg = item_name
+        if item_name == "virtual-locale-en-gb":
+            print("xdx: item name in pkg_path.keys: %s" % (item_name in self.pkg_path.keys()))
+            print("xdx: item name in rprov_pkg.keys: %s" % (item_name in self.rprov_pkg.keys()))
         if item_name not in self.pkg_path.keys():
-            return None
-        else:
-            return self.pkg_path[item_name]
+            if item_name not in self.rprov_pkg.keys():
+                return None
+            pkg = self.rprov_pkg[item_name]
+            if pkg not in self.pkg_path.keys():
+                return None
+
+        return self.pkg_path[pkg]
 
     def find_item_for_path(self, item_path):
         return self[item_path][self.COL_NAME]
@@ -137,6 +146,7 @@ class PackageListModel(gtk.TreeStore):
         self.pkgs_size = 0
         self.pn_path = {}
         self.pkg_path = {}
+        self.rprov_pkg = {}
 
         for pkginfo in pkginfolist:
             pn = pkginfo['PN']
@@ -160,6 +170,8 @@ class PackageListModel(gtk.TreeStore):
             rdep = pkginfo['RDEPENDS_%s' % pkg] if 'RDEPENDS_%s' % pkg in pkginfo.keys() else ""
             rrec = pkginfo['RRECOMMENDS_%s' % pkg] if 'RRECOMMENDS_%s' % pkg in pkginfo.keys() else ""
             rprov = pkginfo['RPROVIDES_%s' % pkg] if 'RPROVIDES_%s' % pkg in pkginfo.keys() else ""
+            for i in rprov.split():
+                self.rprov_pkg[i] = pkg
 
             if 'ALLOW_EMPTY_%s' % pkg in pkginfo.keys():
                 allow_empty = pkginfo['ALLOW_EMPTY_%s' % pkg]
Signature · 1 line
1.7.6
author
#54 lore raw

PATCH 26/32 Hob: fix a bug that the image size is shown incorrectly in the image details page.

In reply to Shane Wang

Originally, the image size shows the last item in the image tree view in the image details page. That is not correct. We need to show the size of the image which the user chooses.

---
 bitbake/lib/bb/ui/crumbs/hig.py              |    2 +-
 bitbake/lib/bb/ui/crumbs/imagedetailspage.py |   32 +++++++++++++++++++------
 2 files changed, 25 insertions(+), 9 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +1 -1
index 9b96d8d..c5bd27a 100644
@@ -1035,6 +1035,7 @@ class ImageSelectionDialog (CrumbsDialog):
         table.attach(open_button, 9, 10, 0, 1)
 
         self.image_table = HobViewTable(self.__columns__)
+        self.image_table.set_size_request(-1, 300)
         self.image_table.connect("toggled", self.toggled_cb)
         self.vbox.pack_start(self.image_table, expand=True, fill=True)
 
@@ -1052,7 +1053,6 @@ class ImageSelectionDialog (CrumbsDialog):
 
         model[path][columnid] = True
 
-        
     def select_path_cb(self, action, parent, entry):
         dialog = gtk.FileChooserDialog("", parent,
                                        gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +24 -8
index 7f93db7..833c149 100755
@@ -74,6 +74,7 @@ class ImageDetailsPage (HobPage):
             self.hbox.pack_start(self.table, expand=True, fill=True, padding=15)
 
             colid = 0
+            self.line_widgets = {}
             if icon != None:
                 self.table.attach(icon, colid, colid + 2, 0, 1)
                 colid = colid + 2
@@ -81,20 +82,31 @@ class ImageDetailsPage (HobPage):
                 self.table.attach(widget, colid, 20, 0, 1)
             elif varlist != None and vallist != None:
                 for line in range(0, row):
-                    self.table.attach(self.text2label(varlist[line], vallist[line]), colid, 20, line, line + 1)
+                    self.line_widgets[varlist[line]] = self.text2label(varlist[line], vallist[line])
+                    self.table.attach(self.line_widgets[varlist[line]], colid, 20, line, line + 1)
 
             # pack the button on the right
             if button != None:
                 self.hbox.pack_end(button, expand=False, fill=False)
 
+        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 format_line(self, variable, value):
+            markup = "<span weight=\'bold\'>%s</span>" % variable
+            markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % 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"
-            markup = "<span weight=\'bold\'>%s</span>" % variable
-            markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % value
             label = gtk.Label()
             label.set_alignment(0.0, 0.5)
-            label.set_markup(markup)
+            label.set_markup(self.format_line(variable, value))
             return label
 
     def __init__(self, builder):
@@ -141,8 +153,6 @@ class ImageDetailsPage (HobPage):
         image_addr = self.builder.parameters.image_addr
         image_names = self.builder.parameters.image_names
         if build_succeeded:
-            image_addr = self.builder.parameters.image_addr
-            image_names = self.builder.parameters.image_names
             machine = self.builder.configuration.curr_mach
             base_image = self.builder.recipe_model.get_selected_image()
             layers = self.builder.configuration.layers
@@ -174,6 +184,7 @@ class ImageDetailsPage (HobPage):
         image_table = HobViewTable(self.__columns__)
         image_table.set_model(self.image_store)
         image_table.toggle_default()
+        image_size = self._size_to_string(os.stat(os.path.join(image_addr, image_names[0])).st_size)
         image_table.connect("toggled", self.toggled_cb)
         view_files_button = gtk.LinkButton("file://%s" % image_addr, "View files")
         self.box_group_area.pack_start(self.DetailBox(widget=image_table, button=view_files_button), expand=True, fill=True)
@@ -217,8 +228,9 @@ class ImageDetailsPage (HobPage):
             edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
         else: # get to this page from "My images"
             edit_packages_button = None
-        package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
-        self.box_group_area.pack_start(package_detail, expand=False, fill=False)
+        self.package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
+        self.box_group_area.pack_start(self.package_detail, expand=False, fill=False)
+
         if build_succeeded:
             buttonlist = ["Build new image", "Save as template", "Run image", "Deploy image"]
         else: # get to this page from "My images"
@@ -228,6 +240,9 @@ class ImageDetailsPage (HobPage):
 
         self.show_all()
 
+    def refresh_package_detail_box(self, image_size):
+        self.package_detail.update_line_widgets("Total image size: ", image_size)
+
     def toggled_cb(self, table, cell, path, columnid, tree):
         model = tree.get_model()
         if not model:
@@ -239,6 +254,7 @@ class ImageDetailsPage (HobPage):
             iter = model.iter_next(iter)
 
         model[path][columnid] = True
+        self.refresh_package_detail_box(model[path][1])
 
     def create_bottom_buttons(self, buttonlist):
         # Create the buttons at the bottom
Signature · 1 line
1.7.6
author
#50 lore raw

PATCH 25/32 Hob: Add an extra 50M space if zypper is selected

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

An workaround to judge if zypper is selected, we will add an extra 51200 KB to image size.

---
 bitbake/lib/bb/ui/crumbs/packageselectionpage.py |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +2 -0
index 5459743..89487c1 100755
@@ -180,6 +180,8 @@ class PackageSelectionPage (HobPage):
         image_overhead_factor = self.builder.configuration.image_overhead_factor
         image_rootfs_size = self.builder.configuration.image_rootfs_size
         image_extra_size = self.builder.configuration.image_extra_size
+        if "zypper" in self.builder.configuration.selected_packages:
+            image_extra_size += 51200
         base_size = image_overhead_factor * selected_packages_size
         image_total_size = max(base_size, image_rootfs_size) + image_extra_size
         image_total_size_str = self._size_to_string(image_total_size)
Signature · 1 line
1.7.6
author
#56 lore raw

PATCH 27/32 Hob: add "OK" button to "BinbDialog"

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

For certain distributions, like FC16, it doesn't have close button in sub-windows or dialogs. Therefore we need to add an "OK" button to "BinbDialog" to close the dialog.

Besides, let BinbDialog inherits the CrumbsDialog instead of gtk.Dialog

---
 bitbake/lib/bb/ui/crumbs/hig.py |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +2 -2
index c5bd27a..20585b7 100644
@@ -90,13 +90,13 @@ class CrumbsMessageDialog(CrumbsDialog):
 #
 # Brought-in-by Dialog
 #
-class BinbDialog(gtk.Dialog):
+class BinbDialog(CrumbsDialog):
     """
     A dialog widget to show "brought in by" info when a recipe/package is clicked.
     """
 
     def __init__(self, title, content, parent=None):
-        super(BinbDialog, self).__init__(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, None)
+        super(BinbDialog, self).__init__(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, ("OK", gtk.RESPONSE_OK))
 
         self.set_position(gtk.WIN_POS_MOUSE)
         self.set_resizable(False)
Signature · 1 line
1.7.6
author
#64 lore raw

PATCH 29/32 Hob(crumbs/builder.py): adjust the main window's position and ignore the case lower than 1024x768.

In reply to Shane Wang

* don't set the position of the main window to the center always
* don't show the message to users if their screen dimensions are lower than 1024x768

---
 bitbake/lib/bb/ui/crumbs/builder.py |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +0 -8
index e9853f2..f41b6a4 100755
@@ -229,20 +229,12 @@ class Builder(gtk.Window):
     def create_visual_elements(self):
         self.set_title("Hob - Image Creator")
         self.set_icon_name("applications-development")
-        self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
         self.set_resizable(True)
         window_width = self.get_screen().get_width()
         window_height = self.get_screen().get_height()
         if window_width >= hwc.MAIN_WIN_WIDTH:
             window_width = hwc.MAIN_WIN_WIDTH
             window_height = hwc.MAIN_WIN_HEIGHT
-        else:
-            lbl = "<b>Screen dimension mismatched</b>\nfor better usability and visual effects,"
-            lbl = lbl + " the screen dimension should be 1024x768 or above."
-            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
-            dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
-            dialog.run()
-            dialog.destroy()
         self.set_size_request(window_width, window_height)
 
         self.vbox = gtk.VBox(False, 0)
Signature · 1 line
1.7.6
author
#60 lore raw

PATCH 28/32 Hob: allow users to setup the proxy

In reply to Shane Wang

This patch is to set os.environ to allow users to set the environment variables for http_proxy, https_proxy and ftp_proxy.

---
 bitbake/lib/bb/ui/crumbs/builder.py |   23 +++++++++++++++++++++++
 bitbake/lib/bb/ui/crumbs/hig.py     |   26 +++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 1 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +23 -0
index 0d7f1c1..e9853f2 100755
@@ -116,6 +116,7 @@ class Configuration:
 
 class Parameters:
     '''Represents other variables like available machines, etc.'''
+    __dummy_proxy__ = "myproxy.example.com:8010"
 
     def __init__(self, params):
         # Variables
@@ -129,6 +130,8 @@ class Parameters:
         self.image_names = []
         self.image_addr = params["image_addr"]
         self.image_types = params["image_types"].split()
+        self.proxy = self.__dummy_proxy__
+        self.enable_proxy = False
 
 class Builder(gtk.Window):
 
@@ -727,6 +730,19 @@ class Builder(gtk.Window):
 
         dialog.destroy()
 
+    def _setup_proxy(self):
+        if self.parameters.proxy == Parameters.__dummy_proxy__ or self.parameters.proxy.lstrip() == "":
+            if "http_proxy" in os.environ.keys():
+                del os.environ["http_proxy"]
+            if "https_proxy" in os.environ.keys():
+                del os.environ["https_proxy"]
+            if "ftp_proxy" in os.environ.keys():
+                del os.environ["ftp_proxy"]
+        else:
+            os.environ["http_proxy"] = self.parameters.proxy
+            os.environ["https_proxy"] = self.parameters.proxy
+            os.environ["ftp_proxy"] = self.parameters.proxy
+
     def show_adv_settings_dialog(self):
         dialog = AdvancedSettingDialog(title = "Settings",
             configuration = copy.deepcopy(self.configuration),
@@ -735,6 +751,8 @@ class Builder(gtk.Window):
             all_distros = self.parameters.all_distros,
             all_sdk_machines = self.parameters.all_sdk_machines,
             max_threads = self.parameters.max_threads,
+            proxy = self.parameters.proxy,
+            enable_proxy = self.parameters.enable_proxy,
             split_model = self.get_split_model(),
             parent = self,
             flags = gtk.DIALOG_MODAL
@@ -745,6 +763,11 @@ class Builder(gtk.Window):
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             self.configuration = dialog.configuration
+            # setup the proxy
+            self.parameters.enable_proxy = dialog.enable_proxy
+            if self.parameters.enable_proxy == True:
+                self.parameters.proxy = dialog.proxy
+                self._setup_proxy()
             # DO reparse recipes
             if dialog.settings_changed:
                 if self.configuration.curr_mach == "":
bitbake/lib/bb/ui/crumbs/hig.py +25 -1
index 20585b7..7e1c1ff 100644
@@ -428,7 +428,7 @@ class AdvancedSettingDialog (CrumbsDialog):
 
     def __init__(self, title, configuration, all_image_types,
             all_package_formats, all_distros, all_sdk_machines,
-            max_threads, split_model, parent, flags, buttons):
+            max_threads, proxy, enable_proxy, split_model, parent, flags, buttons):
         super(AdvancedSettingDialog, self).__init__(title, parent, flags, buttons)
 
         # class members from other objects
@@ -439,6 +439,8 @@ class AdvancedSettingDialog (CrumbsDialog):
         self.all_distros = all_distros
         self.all_sdk_machines = all_sdk_machines
         self.max_threads = max_threads
+        self.enable_proxy = enable_proxy
+        self.proxy = proxy
         self.split_model = split_model 
 
         # class members for internal use
@@ -614,6 +616,21 @@ class AdvancedSettingDialog (CrumbsDialog):
         sub_vbox.pack_start(label, expand=False, fill=False)
         sub_vbox.pack_start(sstatemirror_widget, expand=False, fill=False)
 
+        sub_vbox = gtk.VBox(False, 6)
+        advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
+        self.proxy_checkbox = gtk.CheckButton("Enable Proxy")
+        self.proxy_checkbox.set_tooltip_text("Check this box to setup the proxy you specified")
+        self.proxy_checkbox.set_active(self.enable_proxy)
+        self.proxy_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
+        label = self.gen_label_widget("<span weight=\"bold\">Select Proxy:</span>")
+        tooltip = "Select the proxy that will be used in do_fetch() source code"
+        proxy_widget, self.proxy_text = self.gen_entry_widget(self.split_model, self.proxy, self, tooltip)
+        self.proxy_text.set_editable(self.enable_proxy)
+        self.proxy_text.set_sensitive(self.enable_proxy)
+        sub_vbox.pack_start(self.proxy_checkbox, expand=False, fill=False)
+        sub_vbox.pack_start(label, expand=False, fill=False)
+        sub_vbox.pack_start(proxy_widget, expand=False, fill=False)
+
         return advanced_vbox
 
     def create_others_page(self):
@@ -630,6 +647,11 @@ class AdvancedSettingDialog (CrumbsDialog):
 
         return advanced_vbox
 
+    def proxy_checkbox_toggled_cb(self, button):
+        self.enable_proxy = self.proxy_checkbox.get_active()
+        self.proxy_text.set_editable(self.enable_proxy)
+        self.proxy_text.set_sensitive(self.enable_proxy)
+
     def response_cb(self, dialog, response_id):
         self.variables = {}
 
@@ -679,6 +701,8 @@ class AdvancedSettingDialog (CrumbsDialog):
             self.variables[key] = value
             it = self.setting_store.iter_next(it)
 
+        self.proxy = self.proxy_text.get_text()
+
         md5 = hashlib.md5(str(sorted(self.variables.items()))).hexdigest()
         self.settings_changed = (self.md5 != md5)
 
Signature · 1 line
1.7.6
author
#68 lore raw

PATCH 31/32 runqueue.py: initialize rqexe at RunQueue's init function

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

Sometimes user stops the build before runqueue is established, for example, at the stage of running add_unresolved() function. This will cause RunQueue to use rqexe field in finish_runqeue() before initialized. This will cause endless print of "Running idle function" if use process server.

This commit initialize rqexe variable in RunQueue's init function, and add a judgement in finish_runqueue().

---
 bitbake/lib/bb/runqueue.py |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
bitbake/lib/bb/runqueue.py +5 -0
index f08f93a..0615ab4 100644
@@ -779,6 +779,8 @@ class RunQueue:
         # For disk space monitor
         self.dm = monitordisk.diskMonitor(cfgData)
 
+        self.rqexe = None
+
     def check_stamps(self):
         unchecked = {}
         current = []
@@ -996,6 +998,9 @@ class RunQueue:
         return retval
 
     def finish_runqueue(self, now = False):
+        if not self.rqexe:
+            return
+
         if now:
             self.rqexe.finish_now()
         else:
Signature · 1 line
1.7.6
author
#66 lore raw

PATCH 30/32 Hob: Fix pressing "stop" build

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

This commit fixes the behavior of clicking stop build button, it will stay in the build detail screen and show build is failed.

---
 bitbake/lib/bb/ui/crumbs/builder.py |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +13 -5
index f41b6a4..a04d6fa 100755
@@ -193,7 +193,6 @@ class Builder(gtk.Window):
         self.previous_step = None
 
         self.stopping = False
-        self.build_succeeded = True
 
         # recipe model and package model
         self.recipe_model = recipe_model
@@ -533,8 +532,7 @@ class Builder(gtk.Window):
         self.build_details_page.update_progress_bar("Build Started: ", fraction)
         self.build_details_page.reset_issues()
 
-    def handler_build_succeeded_cb(self, running_build):
-        self.build_succeeded = True
+    def build_succeeded(self):
         if self.current_step == self.FAST_IMAGE_GENERATING:
             fraction = 0.9
         elif self.current_step == self.IMAGE_GENERATING:
@@ -548,9 +546,9 @@ class Builder(gtk.Window):
         elif self.current_step == self.PACKAGE_GENERATING:
             fraction = 1.0
         self.build_details_page.update_progress_bar("Build Completed: ", fraction)
+        self.stopping = False
 
-    def handler_build_failed_cb(self, running_build):
-        self.build_succeeded = False
+    def build_failed(self):
         if self.current_step == self.FAST_IMAGE_GENERATING:
             fraction = 0.9
         elif self.current_step == self.IMAGE_GENERATING:
@@ -563,6 +561,16 @@ class Builder(gtk.Window):
         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_task_started_cb(self, running_build, message): 
         fraction = message["current"] * 1.0/message["total"]
         title = "Build packages"
Signature · 1 line
1.7.6
author
#70 lore raw

PATCH 32/32 Hob: Disable the handling of "NoProvider" event

In reply to Shane Wang

From: Dongxiao Xu <[email protected]>

Currently for non-x86 architecture, there are un-resolved dependency issue when generate universe dependency tree. Therefore disable the handling of "NoProvider" event in Hob to enable the build for non-x86 architectures. After we resolved the dependency for universe, we still need to handle this event in Hob.

---
 bitbake/lib/bb/ui/crumbs/hobeventhandler.py |   37 ++++++++++++++------------
 1 files changed, 20 insertions(+), 17 deletions(-)
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +20 -17
index 6c109fc..9c82bfe 100644
@@ -215,23 +215,26 @@ class HobHandler(gobject.GObject):
         elif isinstance(event, bb.command.CommandCompleted):
             self.current_phase = None
             self.run_next_command()
-
-        elif isinstance(event, bb.event.NoProvider):
-            if event._runtime:
-                r = "R"
-            else:
-                r = ""
-            if event._dependees:
-                self.error_msg += " Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)" % (r, event._item, ", ".join(event._dependees), r)
-            else:
-                self.error_msg += " Nothing %sPROVIDES '%s'" % (r, event._item)
-            if event._reasons:
-                for reason in event._reasons:
-                    self.error_msg += " %s" % reason
-
-            self.commands_async = []
-            self.emit("command-failed", self.error_msg)
-            self.error_msg = ""
+        # TODO: Currently there are NoProvider issues when generate
+        # universe tree dependency for non-x86 architecture.
+        # Comment the follow code to enable the build of non-x86
+        # architectures in Hob.
+        #elif isinstance(event, bb.event.NoProvider):
+        #    if event._runtime:
+        #        r = "R"
+        #    else:
+        #        r = ""
+        #    if event._dependees:
+        #        self.error_msg += " Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)" % (r, event._item, ", ".join(event._dependees), r)
+        #    else:
+        #        self.error_msg += " Nothing %sPROVIDES '%s'" % (r, event._item)
+        #    if event._reasons:
+        #        for reason in event._reasons:
+        #            self.error_msg += " %s" % reason
+
+        #    self.commands_async = []
+        #    self.emit("command-failed", self.error_msg)
+        #    self.error_msg = ""
 
         elif isinstance(event, bb.command.CommandFailed):
             self.commands_async = []
Signature · 1 line
1.7.6
#75 lore raw
In reply to Shane Wang

Hi,

Quoted 10 lines · Shane Wang

The following patches are going to fix the following problems:

* Enable HobNotebook to make notebook more like the design video;
* Improve and enhance the GUI;
* Rebase the patches Josh has sent out before with the title "Hob tweaks";
* Address some tricky issues we found in the bitbake;
* Revise Hob according to the comments on the previous patch set;
* Fix some bugs we found when testing Hob;
* and some temporary walkarounds we have to find a way to solve in Hob or in the bitbake later.

Quoted 3 lines

The following changes since commit 927bec5f72230be4f2452d9ef5a747b2c00cb781:

   bitbake.conf: Create a new filter variable BB_HASHCONFIG_WHITELIST (2012-02-27 20:10:41 +0000)

This is a pretty decent series. I'd appreciate smaller ones in future as they're easier to review.

I've tried to comment on each patch with SOB's for the ones that I'm OK with and comments for the rest.

One thing I did notice whilst reviewing this series is that there's a lot of this anti-pattern in the hob 2 code:
for i in range(len(mylist)):
rather than:
for item in list:

Can we make an effort to tidy those up?

Cheers,
Joshua

Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#12 lore raw

Re: [PATCH 05/32] Hob: include hddimg and iso into image types.

In reply to Shane Wang
Quoted 6 lines · Shane Wang

For image types, so far we don't include hddimg and iso. Then those files can not be deployed because they are filtered out in the image selection dialog. This patch is to include hddimg and iso (which are "live" in image types).

Again, we have a TODO in the code for the future, that is to retrieve image types from the bitbake server instead of to use the walkaround.

Could use a more useful comment in the code, see below, but other than that:

Quoted 63 lines
---
  bitbake/lib/bb/ui/crumbs/builder.py         |    4 ++--
  bitbake/lib/bb/ui/crumbs/hig.py             |    9 +++++----
  bitbake/lib/bb/ui/crumbs/hobeventhandler.py |    9 ++++-----
  bitbake/lib/bb/ui/crumbs/hobwidget.py       |   27 +++++++++++++++++++++++++++
  4 files changed, 38 insertions(+), 11 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +2 -2
index 0071673..eb38819 100755
@@ -758,8 +758,8 @@ class Builder(gtk.Window):
              flags = gtk.DIALOG_MODAL
                      | gtk.DIALOG_DESTROY_WITH_PARENT
                      | gtk.DIALOG_NO_SEPARATOR,
-            buttons = ("Close", gtk.RESPONSE_NO,
-                       "Make usb image", gtk.RESPONSE_YES))
+            buttons = ("Make usb image", gtk.RESPONSE_YES,
+                       "Close", gtk.RESPONSE_NO))
          response = dialog.run()
          dialog.destroy()
 
bitbake/lib/bb/ui/crumbs/hig.py +5 -4
index 74f4f7b..cbad899 100644
@@ -28,7 +28,7 @@ import re
  import subprocess
  import shlex
  from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewTable
+from bb.ui.crumbs.hobwidget import hcc, HobViewTable
  from bb.ui.crumbs.progressbar import HobProgressBar
 
  """
@@ -1083,9 +1083,10 @@ class ImageSelectionDialog (gtk.Dialog):
              dirs[:] = []
              for f in files:
                  for image_type in self.image_types:
-                    if f.endswith('.' + image_type):
-                        imageset.add(f.rsplit('.' + image_type)[0])
-                        self.image_list.append(f)
+                    for real_image_type in hcc.SUPPORTED_IMAGE_TYPES[image_type]:
+                        if f.endswith('.' + real_image_type):
+                            imageset.add(f.rsplit('.' + real_image_type)[0])
+                            self.image_list.append(f)
 
          for image in imageset:
              self.image_store.set(self.image_store.append(), 0, image, 1, False)
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +1 -0
index b071ad4..2bf4ed8 100644
@@ -22,6 +22,7 @@
  import gobject
  import logging
  from bb.ui.crumbs.runningbuild import RunningBuild
+from bb.ui.crumbs.hobwidget import hcc
 
  class HobHandler(gobject.GObject):
 
@@ -450,10 +451,8 @@ class HobHandler(gobject.GObject):
          params["incompat_license"] = self.server.runCommand(["getVariable", "INCOMPATIBLE_LICENSE"]) or ""

bitbake/lib/bb/ui/crumbs/hobeventhandler.py class HobHandler(gobject.GObject): · line 456

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +2 -5
          params["sdk_machine"] = self.server.runCommand(["getVariable", "SDKMACHINE"]) or self.server.runCommand(["getVariable", "SDK_ARCH"]) or ""
 
-        #params["image_types"] = self.server.runCommand(["getVariable", "IMAGE_TYPES"]) or ""
          params["image_fstypes"] = self.server.runCommand(["getVariable", "IMAGE_FSTYPES"]) or ""
-        """
-        A workaround
-        """
-        params["image_types"] = "jffs2 sum.jffs2 cramfs ext2 ext2.gz ext2.bz2 ext3 ext3.gz ext2.lzma btrfs live squashfs squashfs-lzma ubi tar tar.gz tar.bz2 tar.xz cpio cpio.gz cpio.xz cpio.lzma"
+
+        # walkaround

It's nice that you point this out but you don't really tell us what you're working around.

Quoted 40 lines
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +1 -0
+        params["image_types"] = " ".join(hcc.SUPPORTED_IMAGE_TYPES.keys()).lstrip(" ")
          return params
bitbake/lib/bb/ui/crumbs/hobwidget.py +27 -0
index 664bf25..9afbfdb 100644
@@ -50,6 +50,33 @@ class hic:
      ICON_INDI_CONFIRM_FILE        = os.path.join(HOB_ICON_BASE_DIR, ('indicators/confirmation.png'))
      ICON_INDI_ERROR_FILE          = os.path.join(HOB_ICON_BASE_DIR, ('indicators/error.png'))
 
+class hcc:
+
+    SUPPORTED_IMAGE_TYPES = {
+        "jffs2"         : ["jffs2"],
+        "sum.jffs2"     : ["sum.jffs2"],
+        "cramfs"        : ["cramfs"],
+        "ext2"          : ["ext2"],
+        "ext2.gz"       : ["ext2.gz"],
+        "ext2.bz2"      : ["ext2.bz2"],
+        "ext3"          : ["ext3"],
+        "ext3.gz"       : ["ext3.gz"],
+        "ext2.lzma"     : ["ext2.lzma"],
+        "btrfs"         : ["btrfs"],
+        "live"          : ["hddimg", "iso"],
+        "squashfs"      : ["squashfs"],
+        "squashfs-lzma" : ["squashfs-lzma"],
+        "ubi"           : ["ubi"],
+        "tar"           : ["tar"],
+        "tar.gz"        : ["tar.gz"],
+        "tar.bz2"       : ["tar.bz2"],
+        "tar.xz"        : ["tar.xz"],
+        "cpio"          : ["cpio"],
+        "cpio.gz"       : ["cpio.gz"],
+        "cpio.xz"       : ["cpio.xz"],
+        "cpio.lzma"     : ["cpio.lzma"],
+    }
+
  class HobViewTable (gtk.VBox):
      """
      A VBox to contain the table for different recipe views and package view
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#14 lore raw

Re: [PATCH 06/32] Hob: implement a self-defined notebook visual component for Hob

In reply to Shane Wang
Quoted 5 lines · Shane Wang

In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video. We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page.

Code style comments below.

More importantly, have we made sure we can't use the stock notebook before we've implemented our own? The commit log tells me that we aren't using gtk.Notebook but doesn't tell me why?

The implemented notebook is a reasonable start but it needs a lot of polish before I'd want to see it shipped.
i.e. the green flashed border around the selected tabs is strange, the drawing looks a little jaggy, especially the orange circle (not a graphics guy so I don't know the right term) and I'm pretty certain the number in the circle isn't centred. Finally (for now) once I get to three digits the numbers don't fit in the circle.

I think the rationale would be useful as a comment in the class file too.

Cheers,
Joshua

Quoted 183 lines
---
  bitbake/lib/bb/ui/crumbs/hobcolor.py             |    1 +
  bitbake/lib/bb/ui/crumbs/hobwidget.py            |  467 ++++++++++++++++++----
  bitbake/lib/bb/ui/crumbs/packageselectionpage.py |   19 +-
  bitbake/lib/bb/ui/crumbs/recipeselectionpage.py  |   19 +-
  4 files changed, 394 insertions(+), 112 deletions(-)
bitbake/lib/bb/ui/crumbs/hobcolor.py +1 -0
index 9d67d5c..402f022 100644
@@ -28,6 +28,7 @@ class HobColors:
      DARK         = "#3c3b37"
      BLACK        = "#000000"
      LIGHT_ORANGE = "#f7a787"
+    YELLOW       = "#ffff00"
 
      OK = WHITE
      RUNNING = PALE_GREEN
bitbake/lib/bb/ui/crumbs/hobwidget.py +53 -85
index 9afbfdb..a2d99a2 100644
@@ -17,11 +17,14 @@
  # 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 os
  import os.path
+import sys
+import pango, pangocairo
+import math
+
  from bb.ui.crumbs.hobcolor import HobColors
 
  class hwc:
@@ -167,90 +170,6 @@ class HobViewTable (gtk.VBox):
          if not view_column.get_title() in self.toggle_columns:
              self.emit("row-activated", tree.get_model(), path)
 
-class HobViewBar (gtk.EventBox):
-    """
-    A EventBox with the specified gray background color is associated with a notebook.
-    And the toolbar to simulate the tabs.
-    """
-
-    def __init__(self, notebook):
-        if not notebook:
-            return
-        self.notebook = notebook
-
-        # setup an event box
-        gtk.EventBox.__init__(self)
-        self.set_border_width(2)
-        style = self.get_style().copy()
-        style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color (HobColors.GRAY, False, False)
-        self.set_style(style)
-
-        hbox = gtk.HBox()
-        self.add(hbox)
-
-        # setup a tool bar in the event box
-        self.toolbar = gtk.Toolbar()
-        self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
-        self.toolbar.set_style(gtk.TOOLBAR_TEXT)
-        self.toolbar.set_border_width(5)
-
-        self.toolbuttons = []
-        for index in range(self.notebook.get_n_pages()):
-            child = self.notebook.get_nth_page(index)
-            label = self.notebook.get_tab_label_text(child)
-            tip_text = 'switch to ' + label + ' page'
-            toolbutton = self.toolbar.append_element(gtk.TOOLBAR_CHILD_RADIOBUTTON, None,
-                                label, tip_text, "Private text", None,
-                                self.toolbutton_cb, index)
-            toolbutton.set_size_request(200, 100)
-            self.toolbuttons.append(toolbutton)
-
-        # set the default current page
-        self.modify_toolbuttons_bg(0)
-        self.notebook.set_current_page(0)
-
-        self.toolbar.append_space()
-
-        # add the tool bar into the event box
-        hbox.pack_start(self.toolbar, expand=False, fill=False)
-
-        self.search = gtk.Entry()
-        self.align = gtk.Alignment(xalign=0.5, yalign=0.5)
-        self.align.add(self.search)
-        hbox.pack_end(self.align, expand=False, fill=False)
-
-        self.label = gtk.Label(" Search: ")
-        self.label.set_alignment(0.5, 0.5)
-        hbox.pack_end(self.label, expand=False, fill=False)
-
-    def toolbutton_cb(self, widget, index):
-        if index>= self.notebook.get_n_pages():
-            return
-        self.notebook.set_current_page(index)
-        self.modify_toolbuttons_bg(index)
-
-    def modify_toolbuttons_bg(self, index):
-        if index>= len(self.toolbuttons):
-            return
-        for i in range(0, len(self.toolbuttons)):
-            toolbutton = self.toolbuttons[i]
-            if i == index:
-                self.modify_toolbutton_bg(toolbutton, True)
-            else:
-                self.modify_toolbutton_bg(toolbutton)
-
-    def modify_toolbutton_bg(self, toolbutton, active=False):
-        if active:
-            toolbutton.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.WHITE))
-            toolbutton.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(HobColors.WHITE))
-            toolbutton.modify_bg(gtk.STATE_SELECTED, gtk.gdk.Color(HobColors.WHITE))
-            toolbutton.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(HobColors.WHITE))
-        else:
-            toolbutton.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.GRAY))
-            toolbutton.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(HobColors.GRAY))
-            toolbutton.modify_bg(gtk.STATE_SELECTED, gtk.gdk.Color(HobColors.GRAY))
-            toolbutton.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(HobColors.GRAY))
-
  class HobXpmLabelButtonBox(gtk.EventBox):
      """ label: name of buttonbox
          description: the simple  description
@@ -311,3 +230,381 @@ class HobXpmLabelButtonBox(gtk.EventBox):
          """ Hide items - first time """
          pass
 
+class HobTabBar(gtk.DrawingArea):
+    __gsignals__ = {
+        "blank-area-changed" : (gobject.SIGNAL_RUN_LAST,
+                                gobject.TYPE_NONE,
+                               (gobject.TYPE_INT,
+                                gobject.TYPE_INT,
+                                gobject.TYPE_INT,
+                                gobject.TYPE_INT,)),
+
+        "tab-switched" : (gobject.SIGNAL_RUN_LAST,
+                          gobject.TYPE_NONE,
+                         (gobject.TYPE_INT,)),
+    }
+
+    def __init__(self):
+        gtk.DrawingArea.__init__(self)
+        self.children = []
+
+        self.tab_width = 140
+        self.tab_height = 52
+        self.tab_x = 10
+        self.tab_y = 0
+
+        self.width = 500
+        self.height = 53
+        self.tab_w_ratio = 140 * 1.0/500
+        self.tab_h_ratio = 52 * 1.0/53
+        self.set_size_request(self.width, self.height)
+
+        self.current_child = 0
+        self.font = self.get_style().font_desc
+        self.font.set_size(pango.SCALE * 13)
+        self.update_children_text_layout_and_bg_color()
+
+        self.blank_rectangle = None
+        self.tab_pressed = False
+
+        self.set_property('can-focus', True)
+        self.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.POINTER_MOTION_MASK |
+                        gtk.gdk.BUTTON1_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK |
+                        gtk.gdk.BUTTON_RELEASE_MASK)
+
+        self.connect("expose-event", self.on_draw)
+        self.connect("button-press-event", self.button_pressed_cb)
+        self.connect("button-release-event", self.button_released_cb)
+        self.show_all()
+
+    def button_released_cb(self, widget, event):
+        self.tab_pressed = False

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobXpmLabelButtonBox(gtk.EventBox): · line 291

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10 -0
+        self.queue_draw()
+
+    def button_pressed_cb(self, widget, event):
+        if event.type == gtk.gdk._2BUTTON_PRESS:
+            return
+
+        result = False
+        if self.is_focus() or event.type == gtk.gdk.BUTTON_PRESS:
+            x, y = event.get_coords()
+            # check which tab be clicked

Why don't we just iterate the list here?
for child in self.children:
if child["x"] < x and etc.

Quoted 14 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +14 -0
+            for i in range(len(self.children)):
+               if      (self.children[i]["x"]<  x) and (x<  self.children[i]["x"] + self.tab_width) \
+                   and (self.children[i]["y"]<  y) and (y<  self.children[i]["y"] + self.tab_height):
+                   self.current_child = i
+                   result = True
+                   break
+
+            # check the blank area is focus in or not
+            if (self.blank_rectangle) and (self.blank_rectangle.x>  0) and (self.blank_rectangle.y>  0):
+                if      (self.blank_rectangle.x<  x) and (x<  self.blank_rectangle.x + self.blank_rectangle.width) \
+                    and (self.blank_rectangle.y<  y) and (y<  self.blank_rectangle.y + self.blank_rectangle.height):
+                   self.grab_focus()
+
+        if result == True:

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobXpmLabelButtonBox(gtk.EventBox): · line 315

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10 -0
+            page = self.children[self.current_child]["toggled_page"]
+            self.emit("tab-switched", page)
+            self.tab_pressed = True
+            self.queue_draw()
+
+    def update_children_size(self):
+        # calculate the size of tabs
+        self.tab_width = int(self.width * self.tab_w_ratio)
+        self.tab_height = int(self.height * self.tab_h_ratio)
+        for i in range(len(self.children)):

Again, can't we just iterate the list here?
for child in self.children:

Quoted 7 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +7 -0
+            self.children[i]["x"] = self.tab_x + i * self.tab_width
+            self.children[i]["y"] = self.tab_y
+
+        if self.blank_rectangle != None:
+            self.resize_blank_rectangle()
+
+    def resize_blank_rectangle(self):

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobXpmLabelButtonBox(gtk.EventBox): · line 332

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10 -0
+        width = self.width - self.tab_width * len(self.children) - self.tab_x
+        x = self.tab_x + self.tab_width * len(self.children)
+        hpadding = vpadding = 5
+        self.blank_rectangle = self.set_blank_size(x + hpadding, self.tab_y + vpadding,
+            width - 2 * hpadding, self.tab_height - 2 * vpadding)
+
+    def update_children_text_layout_and_bg_color(self):
+        style = self.get_style().copy()
+        color = style.base[gtk.STATE_NORMAL]
+        for i in range(len(self.children)):

Again,
for child in self.children:

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobXpmLabelButtonBox(gtk.EventBox): · line 345

Quoted 13 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +13 -0
+            pangolayout = self.create_pango_layout(self.children[i]["title"])
+            pangolayout.set_font_description(self.font)
+            self.children[i]["title_layout"] = pangolayout
+            self.children[i]["r"] = color.red
+            self.children[i]["g"] = color.green
+            self.children[i]["b"] = color.blue
+
+    def append_tab_child(self, title, page):
+        num = len(self.children) + 1
+        self.tab_width = self.tab_width * len(self.children) / num
+
+        i = 0
+        for child in self.children:

Just like this!

Quoted 25 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +25 -0
+            child["x"] = self.tab_x + i * self.tab_width
+            i += 1
+
+        x = self.tab_x + i * self.tab_width
+        y = self.tab_y
+        pangolayout = self.create_pango_layout(title)
+        pangolayout.set_font_description(self.font)
+        color = self.style.base[gtk.STATE_NORMAL]
+        new_one = {
+            "x" : x,
+            "y" : y,
+            "r" : color.red,
+            "g" : color.green,
+            "b" : color.blue,
+            "title_layout" : pangolayout,
+            "toggled_page" : page,
+            "title"        : title,
+            "indicator_show"   : False,
+            "indicator_number" : 0,
+        }
+        self.children.append(new_one)
+
+    def on_draw(self, widget, event):
+        cr = widget.window.cairo_create()
+

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobXpmLabelButtonBox(gtk.EventBox): · line 380

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10 -0
+        self.width = self.allocation.width
+        self.height = self.allocation.height
+
+        self.update_children_size()
+
+        self.draw_background(cr)
+        self.draw_toggled_tab(cr)
+        self.draw_tab_text(cr)
+
+        for i in range(len(self.children)):

See above:
for child in self.children:

Quoted 16 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +16 -0
+            if self.children[i]["indicator_show"] == True:
+                self.draw_indicator(cr, i)
+
+    def draw_background(self, cr):
+        style = self.get_style()
+
+        if self.is_focus():
+            cr.set_source_color(style.base[gtk.STATE_SELECTED])
+        else:
+            cr.set_source_color(style.base[gtk.STATE_NORMAL])
+
+        y = 6
+        h = self.height - 6 - 1
+        gap = 1
+
+        w = self.children[0]["x"]

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobXpmLabelButtonBox(gtk.EventBox): · line 406

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10 -0
+        cr.set_source_color(gtk.gdk.color_parse(HobColors.GRAY))
+        cr.rectangle(0, y, w - gap, h) # start rectangle
+        cr.fill()
+
+        cr.set_source_color(style.base[gtk.STATE_NORMAL])
+        cr.rectangle(w - gap, y, w, h) #first gap
+        cr.fill()
+
+        w = self.tab_width
+        for i in range(len(self.children)):

for child in self.children:

Quoted 6 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +6 -0
+            x = self.children[i]["x"]
+            cr.set_source_color(gtk.gdk.color_parse(HobColors.GRAY))
+            cr.rectangle(x, y, w - gap, h) # tab rectangle
+            cr.fill()
+            cr.set_source_color(style.base[gtk.STATE_NORMAL])
+            cr.rectangle(x + w - gap, y, w, h) # gap

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobXpmLabelButtonBox(gtk.EventBox): · line 422

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10 -0
+            cr.fill()
+
+        cr.set_source_color(gtk.gdk.color_parse(HobColors.GRAY))
+        cr.rectangle(x + w, y, self.width - x - w, h) # last rectangle
+        cr.fill()
+
+    def draw_tab_text(self, cr):
+        style = self.get_style()
+
+        for i in range(len(self.children)):

for child in self.children:

Quoted 286 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +188 -0
+            pangolayout = self.children[i]["title_layout"]
+            if pangolayout:
+                fontw, fonth = pangolayout.get_pixel_size()
+                # center pos
+                off_x = (self.tab_width - fontw) / 2
+                off_y = (self.tab_height - fonth) / 2
+                x = self.children[i]["x"] + off_x
+                y = self.children[i]["y"] + off_y
+                self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), pangolayout)
+
+    def draw_toggled_tab(self, cr):
+        i = self.current_child
+        x = self.children[i]["x"]
+        y = self.children[i]["y"]
+        width = self.tab_width
+        height = self.tab_height
+        style = self.get_style()
+        color = style.base[gtk.STATE_NORMAL]
+
+        r = height / 10
+        if self.tab_pressed == True:
+            for xoff, yoff in [(1, 0), (2, 0)]:
+                cr.set_source_color(gtk.gdk.color_parse(HobColors.PALE_GREEN))
+                cr.move_to(x + r + xoff, y + yoff)
+                cr.line_to(x + width - r + xoff, y + yoff)
+                cr.arc(x + width - r+ xoff, y + r + yoff, r, 1.5*math.pi, 2*math.pi)
+                cr.move_to(x + width + xoff, r + yoff)
+                cr.line_to(x + width + xoff, y + height + yoff)
+                cr.line_to(x + xoff, y + height + yoff)
+                cr.line_to(x + xoff, r + yoff)
+                cr.arc(x + r + xoff, y + r + yoff, r, math.pi, 1.5*math.pi)
+                cr.stroke()
+            x = x + 2
+            y = y + 2
+        cr.set_source_rgba(color.red, color.green, color.blue, 1)
+        cr.move_to(x + r, y)
+        cr.line_to(x + width - r , y)
+        cr.arc(x + width - r, y + r, r, 1.5*math.pi, 2*math.pi)
+        cr.move_to(x + width, r)
+        cr.line_to(x + width, y + height)
+        cr.line_to(x, y + height)
+        cr.line_to(x, r)
+        cr.arc(x + r, y + r, r, math.pi, 1.5*math.pi)
+        cr.fill()
+
+    def draw_indicator(self, cr, i):
+        style = self.get_style()
+        tab_x = self.children[i]["x"]
+        tab_y = self.children[i]["y"]
+        number = self.children[i]["indicator_number"]
+        dest_w = int(32 * self.tab_w_ratio)
+        dest_h = int(32 * self.tab_h_ratio)
+        if dest_h<  self.tab_height:
+            dest_w = dest_h
+
+        # x position is offset(tab_width*3/4 - icon_width/2) + start_pos(tab_x)
+        x = tab_x + self.tab_width * 3/4 - dest_w/2
+        y = tab_y + self.tab_height/2 - dest_h/2
+        cr.move_to(tab_x, tab_y)
+        r = min(dest_w, dest_h)/2
+        color = cr.set_source_color(gtk.gdk.color_parse(HobColors.ORANGE))
+        cr.arc(x + r, y + r, r, 0, 2*math.pi)
+        cr.fill()
+
+        text = ("%d" % number)
+        layout = self.create_pango_layout(text)
+        layout.set_font_description(self.font)
+        textw, texth = layout.get_pixel_size()
+        x = x + (dest_w/2)-(textw/2)
+        y = y + (dest_h/2) - (texth/2)
+        cr.move_to(x, y)
+        self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), layout)
+
+    def show_indicator_icon(self, i, number):
+        self.children[i]["indicator_show"] = True
+        self.children[i]["indicator_number"] = number
+        self.queue_draw()
+
+    def hide_indicator_icon(self, i):
+        self.children[i]["indicator_show"] = False
+        self.queue_draw()
+
+    def set_blank_size(self, x, y, w, h):
+        if self.blank_rectangle == None or self.blank_rectangle.x != x or self.blank_rectangle.width != w:
+            self.emit("blank-area-changed", x, y, w, h)
+
+        return gtk.gdk.Rectangle(x, y, w, h)
+
+class HobNotebook(gtk.VBox):
+
+    def __init__(self):
+        gtk.VBox.__init__(self, False, 0)
+
+        self.notebook = gtk.Notebook()
+        self.notebook.set_property('homogeneous', True)
+        self.notebook.set_property('show-tabs', False)
+
+        self.tabbar = HobTabBar()
+        self.tabbar.connect("tab-switched",   self.tab_switched_cb)
+        self.notebook.connect("page-added",   self.page_added_cb)
+        self.notebook.connect("page-removed", self.page_removed_cb)
+
+        self.search = None
+        self.search_name = ""
+
+        self.tb = gtk.Table(1, 100, False)
+        self.hbox= gtk.HBox(False, 0)
+        self.hbox.pack_start(self.tabbar, True, True)
+        self.tb.attach(self.hbox, 0, 100, 0, 1)
+
+        self.pack_start(self.tb, False, False)
+        self.pack_start(self.notebook)
+
+        self.show_all()
+
+    def append_page(self, child, tab_label):
+        self.notebook.set_current_page(self.notebook.append_page(child, tab_label))
+
+    def set_entry(self, name="Search:"):
+        for child in self.tb.get_children():
+            if child:
+                self.tb.remove(child)
+
+        hbox_entry = gtk.HBox(False, 0)
+        hbox_entry.show()
+
+        self.search = gtk.Entry()
+        self.search_name = name
+        style = self.search.get_style()
+        style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False)
+        self.search.set_style(style)
+        self.search.set_text(name)
+        self.search.set_editable(False)
+        self.search.show()
+        self.align = gtk.Alignment(xalign=1.0, yalign=0.7)
+        self.align.add(self.search)
+        self.align.show()
+        hbox_entry.pack_end(self.align, False, False)
+        self.tabbar.resize_blank_rectangle()
+
+        self.tb.attach(hbox_entry, 75, 100, 0, 1, xpadding=5)
+        self.tb.attach(self.hbox, 0, 100, 0, 1)
+
+        self.tabbar.connect("blank-area-changed", self.blank_area_resize_cb)
+        self.search.connect("focus-in-event", self.set_search_entry_editable_cb)
+        self.search.connect("focus-out-event", self.set_search_entry_reset_cb)
+
+        self.tb.show()
+
+    def tab_switched_cb(self, widget, page):
+        self.notebook.set_current_page(page)
+
+    def page_added_cb(self, notebook, notebook_child, page):
+        if not notebook:
+            return
+        title = notebook.get_tab_label_text(notebook_child)
+        if title == None:
+            return
+        for i in range(len(self.tabbar.children)):
+            if self.tabbar.children[i]["title"] == title:
+                self.tabbar.children[i]["toggled_page"] = page
+                return
+        self.tabbar.append_tab_child(title, page)
+
+    def page_removed_cb(self, notebook, notebook_child, page, title=""):
+        for i in range(len(self.tabbar.children)):
+            if self.tabbar.children[i] == title:
+                self.tabbar.children[i]["toggled_page"] = -1
+
+    def blank_area_resize_cb(self, widget, request_x, request_y, request_width, request_height):
+        self.search.set_size_request(request_width, request_height)
+        widget.modify_bg(gtk.STATE_SELECTED, gtk.gdk.color_parse(HobColors.YELLOW))
+
+    def set_search_entry_editable_cb(self, widget, event):
+        if self.search:
+            self.search.set_editable(True)
+            self.search.set_text("")
+            style = self.search.get_style()
+            style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False)
+            self.search.set_style(style)
+
+    def set_search_entry_reset_cb(self, widget, event):
+        if self.search:
+            style = self.search.get_style()
+            style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False)
+            self.search.set_style(style)
+            self.search.set_text(self.search_name)
+            self.search.set_editable(False)
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +6 -13
index a3c4acd..dab90ec 100755
@@ -23,7 +23,7 @@
  import gtk
  import glib
  from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable
+from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook
  from bb.ui.crumbs.hoblistmodel import PackageListModel
  from bb.ui.crumbs.hobpages import HobPage
 
@@ -102,11 +102,7 @@ class PackageSelectionPage (HobPage):
          self.pack_start(self.group_align, expand=True, fill=True)
 
          # set visiable members
-        self.grid = gtk.Table(10, 1, True)
-        self.grid.set_col_spacings(3)
-
-        self.ins = gtk.Notebook()
-        self.ins.set_show_tabs(False)
+        self.ins = HobNotebook()
          self.tables = [] # we need to modify table when the dialog is shown
          # append the tab
          for i in range(len(self.pages)):
@@ -128,19 +124,16 @@ class PackageSelectionPage (HobPage):
              self.ins.append_page(tab, label)
              self.tables.append(tab)
 
-        self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
-        # a black bar associated with the notebook
-        self.topbar = HobViewBar(self.ins)
-        self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
+        self.ins.set_entry("Search packages:")
          # set the search entry for each table
          for tab in self.tables:
-            tab.set_search_entry(0, self.topbar.search)
+            tab.set_search_entry(0, self.ins.search)
 
          # add all into the dialog
-        self.box_group_area.add(self.grid)
+        self.box_group_area.pack_start(self.ins, expand=True, fill=True)
 
          button_box = gtk.HBox(False, 5)
-        self.box_group_area.pack_start(button_box, expand=False, fill=False)
+        self.box_group_area.pack_end(button_box, expand=False, fill=False)
 
          self.build_image_button = gtk.Button()
          label = gtk.Label()
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +5 -14
index ee36f8c..416c613 100755
@@ -23,7 +23,7 @@
  import gtk
  import glib
  from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable
+from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook
  from bb.ui.crumbs.hoblistmodel import RecipeListModel
  from bb.ui.crumbs.hobpages import HobPage
 
@@ -124,13 +124,7 @@ class RecipeSelectionPage (HobPage):
          self.pack_start(self.group_align, expand=True, fill=True)
 
          # set visiable members
-        self.grid = gtk.Table(10, 1, True)
-        self.grid.set_col_spacings(3)
-
-        # draw the left part of the window
-        # a notebook
-        self.ins = gtk.Notebook()
-        self.ins.set_show_tabs(False)
+        self.ins = HobNotebook()
          self.tables = [] # we need modify table when the dialog is shown
          # append the tabs in order
          for i in range(len(self.pages)):
@@ -151,16 +145,13 @@ class RecipeSelectionPage (HobPage):
              self.ins.append_page(tab, label)
              self.tables.append(tab)
 
-        self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
-        # a black bar associated with the notebook
-        self.topbar = HobViewBar(self.ins)
-        self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
+        self.ins.set_entry("Search recipes:")
          # set the search entry for each table
          for tab in self.tables:
-            tab.set_search_entry(0, self.topbar.search)
+            tab.set_search_entry(0, self.ins.search)
 
          # add all into the window
-        self.box_group_area.add(self.grid)
+        self.box_group_area.pack_start(self.ins, expand=True, fill=True)
 
          button_box = gtk.HBox(False, 5)
          self.box_group_area.pack_end(button_box, expand=False, fill=False)
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#43 lore raw

Re: [PATCH 22/32] cooker: fix calculating of depends and rdepends

In reply to Shane Wang
Quoted 5 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

Remove part of the original logic that stores pkg dependency and pkg recomends, which will not be used in Hob.

Quoted 8 lines

Add the judgement for preferred fn provider of a certain package, which maps package name to its providing recipe name.

The above approaches correct the build dependency calculation, and they also reduced the total depend_tree size, which speed up the tree data generation time.

Quoted 81 lines
---
  bitbake/lib/bb/cooker.py |   45 ++++++++++-----------------------------------
  1 files changed, 10 insertions(+), 35 deletions(-)
bitbake/lib/bb/cooker.py +10 -35
index b23b569..e71f72b 100644
@@ -438,19 +438,6 @@ class BBCooker:
 
          return depend_tree
 
-    def append_package(self, taskdata, depend_tree_package, package):
-        if package not in depend_tree_package:
-            targetid = taskdata.getrun_id(package)
-            if targetid in taskdata.run_targets and taskdata.run_targets[targetid]:
-                fnid = taskdata.run_targets[targetid][0]
-                fn = taskdata.fn_index[fnid]
-                pn = self.status.pkg_fn[fn]
-                version  = "%s:%s-%s" % self.status.pkg_pepvpr[fn]
-                depend_tree_package[package] = {}
-                depend_tree_package[package]["pn"] = pn
-                depend_tree_package[package]["filename"] = fn
-                depend_tree_package[package]["version"] = version
-
      def generatePkgDepTreeData(self, pkgs_to_build, task):
          """
          Create a dependency tree of pkgs_to_build, returning the data.
@@ -466,7 +453,6 @@ class BBCooker:
          depend_tree["depends"] = {}
          depend_tree["pn"] = {}
          depend_tree["rdepends-pn"] = {}
-        depend_tree["packages"] = {}
          depend_tree["rdepends-pkg"] = {}
          depend_tree["rrecs-pkg"] = {}
 
@@ -493,7 +479,6 @@ class BBCooker:
 
              if fnid not in seen_fnids:
                  seen_fnids.append(fnid)
-                packages = []
 
                  depend_tree["depends"][pn] = []
                  for dep in taskdata.depids[fnid]:
@@ -510,26 +495,16 @@ class BBCooker:
 
                  depend_tree["rdepends-pn"][pn] = []
                  for rdep in taskdata.rdepids[fnid]:
-                    depend_tree["rdepends-pn"][pn].append(taskdata.run_names_index[rdep])
-
-                for package in rdepends:
-                    depend_tree["rdepends-pkg"][package] = []
-                    for rdepend in rdepends[package]:
-                        depend_tree["rdepends-pkg"][package].append(rdepend)
-                        self.append_package(taskdata, depend_tree["packages"], rdepend)
-                    if not package in packages:
-                        packages.append(package)
-
-                for package in rrecs:
-                    depend_tree["rrecs-pkg"][package] = []
-                    for rrec in rrecs[package]:
-                        depend_tree["rrecs-pkg"][package].append(rrec)
-                        self.append_package(taskdata, depend_tree["packages"], rrec)
-                    if not package in packages:
-                        packages.append(package)
-
-                for package in packages:
-                    self.append_package(taskdata, depend_tree["packages"], package)
+                    item = taskdata.run_names_index[rdep]
+                    pn_rprovider = ""
+                    targetid = taskdata.getrun_id(item)
+                    if targetid in taskdata.run_targets and taskdata.run_targets[targetid]:
+                        id = taskdata.run_targets[targetid][0]
+                        fn_rprovider = taskdata.fn_index[id]
+                        pn_rprovider = self.status.pkg_fn[fn_rprovider]
+                    else:
+                        pn_rprovider = item
+                    depend_tree["rdepends-pn"][pn].append(pn_rprovider)
 
          return depend_tree
 
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#73 lore raw

Re: [PATCH 01/32] Hob: make HobViewTable more general in hob and make the image selection dialog and the image details page reuse it.

In reply to Shane Wang
Quoted 7 lines · Shane Wang

This patch is to make the class HobViewTable more general as a tree view in Hob.
Now the recipe selection page and the package selection page are using it.
And we have tree views in the image selection dialog and the image details page, which used the class methods in HobWidget to create the tree views. That is not good in OO.

So, make them reuse HobViewTable to create its instances.

This is a decent set of changes, there are some minor stylistic comments but I'll be happy to see them addressed in a future patch.

Quoted 215 lines
---
  bitbake/lib/bb/ui/crumbs/hig.py                  |   37 +++++-
  bitbake/lib/bb/ui/crumbs/hobwidget.py            |  168 +++++++---------------
  bitbake/lib/bb/ui/crumbs/imagedetailspage.py     |   65 +++++++--
  bitbake/lib/bb/ui/crumbs/packageselectionpage.py |   28 +++--
  bitbake/lib/bb/ui/crumbs/recipeselectionpage.py  |   30 +++--
  5 files changed, 176 insertions(+), 152 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +33 -4
index 89dfe03..8f4f7cd 100644
@@ -28,7 +28,7 @@ import re
  import subprocess
  import shlex
  from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import HobWidget
+from bb.ui.crumbs.hobwidget import HobWidget, HobViewTable
  from bb.ui.crumbs.progressbar import HobProgressBar
 
  """
@@ -561,6 +561,21 @@ class LayerSelectionDialog (gtk.Dialog):
 
  class ImageSelectionDialog (gtk.Dialog):
 
+    __columns__ = [{
+            'col_name' : 'Image name',
+            'col_id'   : 0,
+            'col_style': 'text',
+            'col_min'  : 400,
+            'col_max'  : 400
+        }, {
+            'col_name' : 'Select',
+            'col_id'   : 1,
+            'col_style': 'radio toggle',
+            'col_min'  : 160,
+            'col_max'  : 160
+    }]
+
+
      def __init__(self, image_folder, image_types, title, parent, flags, buttons):
          super(ImageSelectionDialog, self).__init__(title, parent, flags, buttons)
          self.connect("response", self.response_cb)
@@ -596,11 +611,25 @@ class ImageSelectionDialog (gtk.Dialog):
          open_button.connect("clicked", self.select_path_cb, self, entry)
          table.attach(open_button, 9, 10, 0, 1)
 
-        imgtv_widget, self.imgsel_tv = HobWidget.gen_imgtv_widget(400, 160)
-        self.vbox.pack_start(imgtv_widget, expand=True, fill=True)
+        self.image_table = HobViewTable(self.__columns__)
+        self.image_table.connect("toggled", self.toggled_cb)
+        self.vbox.pack_start(self.image_table, expand=True, fill=True)
 
          self.show_all()
 
+    def toggled_cb(self, table, cell, path, columnid, tree):
+        model = tree.get_model()
+        if not model:
+            return
+        iter = model.get_iter_first()
+        while iter:
+            rowpath = model.get_path(iter)
+            model[rowpath][columnid] = False
+            iter = model.iter_next(iter)
+
+        model[path][columnid] = True
+
+
      def select_path_cb(self, action, parent, entry):
          dialog = gtk.FileChooserDialog("", parent,
                                         gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
@@ -627,7 +656,7 @@ class ImageSelectionDialog (gtk.Dialog):
          for image in imageset:
              self.image_store.set(self.image_store.append(), 0, image, 1, False)
 
-        self.imgsel_tv.set_model(self.image_store)
+        self.image_table.set_model(self.image_store)
 
      def response_cb(self, dialog, response_id):
          self.image_names = []
bitbake/lib/bb/ui/crumbs/hobwidget.py +15 -100
index 890151d..141c4ef 100644
@@ -423,104 +423,6 @@ class HobWidget:
          return hbox, layer_store
 
      @classmethod
-    def _toggle_single_cb(cls, cell, select_path, treeview, toggle_column):
-        model = treeview.get_model()
-        if not model:
-            return
-        iter = model.get_iter_first()
-        while iter:
-            path = model.get_path(iter)
-            model[path][toggle_column] = False
-            iter = model.iter_next(iter)
-
-        model[select_path][toggle_column] = True
-
-    @classmethod
-    def gen_imgtv_widget(cls, col0_width, col1_width):
-        vbox = gtk.VBox(False, 10)
-
-        imgsel_tv = gtk.TreeView()
-        imgsel_tv.set_rules_hint(True)
-        imgsel_tv.set_headers_visible(False)
-        tree_selection = imgsel_tv.get_selection()
-        tree_selection.set_mode(gtk.SELECTION_SINGLE)
-
-        col0= gtk.TreeViewColumn('Image name')
-        cell0 = gtk.CellRendererText()
-        cell0.set_padding(5,2)
-        col0.pack_start(cell0, True)
-        col0.set_attributes(cell0, text=0)
-        col0.set_max_width(col0_width)
-        col0.set_min_width(col0_width)
-        imgsel_tv.append_column(col0)
-
-        col1= gtk.TreeViewColumn('Select')
-        cell1 = gtk.CellRendererToggle()
-        cell1.set_padding(5,2)
-        cell1.connect("toggled", cls._toggle_single_cb, imgsel_tv, 1)
-        col1.pack_start(cell1, True)
-        col1.set_attributes(cell1, active=1)
-        col1.set_max_width(col1_width)
-        col1.set_min_width(col1_width)
-        imgsel_tv.append_column(col1)
-
-        scroll = gtk.ScrolledWindow()
-        scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        scroll.set_shadow_type(gtk.SHADOW_IN)
-        scroll.add(imgsel_tv)
-
-        vbox.pack_start(scroll, expand=True, fill=True)
-
-        return vbox, imgsel_tv
-
-    @classmethod
-    def gen_images_widget(cls, col0_width, col1_width, col2_width):
-        vbox = gtk.VBox(False, 10)
-
-        imgsel_tv = gtk.TreeView()
-        imgsel_tv.set_rules_hint(True)
-        imgsel_tv.set_headers_visible(False)
-        tree_selection = imgsel_tv.get_selection()
-        tree_selection.set_mode(gtk.SELECTION_SINGLE)
-
-        col0= gtk.TreeViewColumn('Image name')
-        cell0 = gtk.CellRendererText()
-        cell0.set_padding(5,2)
-        col0.pack_start(cell0, True)
-        col0.set_attributes(cell0, text=0)
-        col0.set_max_width(col0_width)
-        col0.set_min_width(col0_width)
-        imgsel_tv.append_column(col0)
-
-        col1= gtk.TreeViewColumn('Image size')
-        cell1 = gtk.CellRendererText()
-        cell1.set_padding(5,2)
-        col1.pack_start(cell1, True)
-        col1.set_attributes(cell1, text=1)
-        col1.set_max_width(col1_width)
-        col1.set_min_width(col1_width)
-        imgsel_tv.append_column(col1)
-
-        col2= gtk.TreeViewColumn('Select')
-        cell2 = gtk.CellRendererToggle()
-        cell2.set_padding(5,2)
-        cell2.connect("toggled", cls._toggle_single_cb, imgsel_tv, 2)
-        col2.pack_start(cell2, True)
-        col2.set_attributes(cell2, active=2)
-        col2.set_max_width(col2_width)
-        col2.set_min_width(col2_width)
-        imgsel_tv.append_column(col2)
-
-        scroll = gtk.ScrolledWindow()
-        scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        scroll.set_shadow_type(gtk.SHADOW_IN)
-        scroll.add(imgsel_tv)
-
-        vbox.pack_start(scroll, expand=True, fill=True)
-
-        return vbox, imgsel_tv
-
-    @classmethod
      def _on_add_item_clicked(cls, button, model):
          new_item = ["##KEY##", "##VALUE##"]
 
@@ -617,34 +519,59 @@ class HobViewTable (gtk.VBox):
      """
      A VBox to contain the table for different recipe views and package view
      """
-    def __init__(self, columns, reset_clicked_cb=None, toggled_cb=None):
+    __gsignals__ = {
+         "toggled"      : (gobject.SIGNAL_RUN_LAST,
+                           gobject.TYPE_NONE,
+                          (gobject.TYPE_PYOBJECT,
+                           gobject.TYPE_STRING,
+                           gobject.TYPE_INT,
+                           gobject.TYPE_PYOBJECT,)),
+         "changed"      : (gobject.SIGNAL_RUN_LAST,
+                           gobject.TYPE_NONE,
+                          (gobject.TYPE_PYOBJECT,
+                           gobject.TYPE_PYOBJECT,)),
+    }
+
+    def __init__(self, columns):
          gtk.VBox.__init__(self, False, 6)
          self.table_tree = gtk.TreeView()
          self.table_tree.set_headers_visible(True)
          self.table_tree.set_headers_clickable(True)
          self.table_tree.set_enable_search(True)
-        self.table_tree.set_search_column(0)
+        self.table_tree.set_rules_hint(True)

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobViewTable (gtk.VBox): · line 635

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +1 -2
          self.table_tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
+        self.table_tree.get_selection().connect("changed", self.selection_changed_cb, self.table_tree)
 
          for i in range(len(columns)):
              col = gtk.TreeViewColumn(columns[i]['col_name'])
              col.set_clickable(True)
              col.set_resizable(True)
              col.set_sort_column_id(columns[i]['col_id'])
-            col.set_min_width(columns[i]['col_min'])
-            col.set_max_width(columns[i]['col_max'])

There are a few calls to columns[i].keys() below, I'd recommend making the call once per iteration and assigning it to a variable.
col_keys = columns[i].keys()

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobViewTable (gtk.VBox): · line 550

Quoted 1 line
bitbake/lib/bb/ui/crumbs/hobwidget.py +1 -0
+            if 'col_min' in columns[i].keys():

if 'col_min' in col_keys:

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobViewTable (gtk.VBox): · line 552

Quoted 2 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +2 -0
+                col.set_min_width(columns[i]['col_min'])
+            if 'col_max' in columns[i].keys():

if 'col_max' in col_keys:

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobViewTable (gtk.VBox): · line 556

Quoted 5 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +2 -1
+                col.set_max_width(columns[i]['col_max'])
              self.table_tree.append_column(col)
 
-            if columns[i]['col_style'] == 'toggle':
+            if (not 'col_style' in columns[i].keys()) or columns[i]['col_style'] == 'text':

if (not 'col_style' in col_keys) or
columns[i]['col_style'] == 'text':

Quoted 103 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +34 -10
+                cell = gtk.CellRendererText()
+                col.pack_start(cell, True)
+                col.set_attributes(cell, text=columns[i]['col_id'])
+            elif columns[i]['col_style'] == 'check toggle':
                  cell = gtk.CellRendererToggle()
                  cell.set_property('activatable', True)
-                cell.connect("toggled", toggled_cb, self.table_tree)
+                cell.connect("toggled", self.toggled_cb, i, self.table_tree)
+                self.toggle_id = i
+                col.pack_end(cell, True)
+                col.set_attributes(cell, active=columns[i]['col_id'])
+            elif columns[i]['col_style'] == 'radio toggle':
+                cell = gtk.CellRendererToggle()
+                cell.set_property('activatable', True)
+                cell.set_radio(True)
+                cell.connect("toggled", self.toggled_cb, i, self.table_tree)
+                self.toggle_id = i
                  col.pack_end(cell, True)
                  col.set_attributes(cell, active=columns[i]['col_id'])
-            elif columns[i]['col_style'] == 'text':
-                cell = gtk.CellRendererText()
-                col.pack_start(cell, True)
-                col.set_attributes(cell, text=columns[i]['col_id'])
 
          scroll = gtk.ScrolledWindow()
          scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
@@ -652,12 +579,27 @@ class HobViewTable (gtk.VBox):
          scroll.add(self.table_tree)
          self.pack_start(scroll, True, True, 0)
 
-        hbox = gtk.HBox(False, 5)
-        button = gtk.Button("Reset")
-        button.connect('clicked', reset_clicked_cb)
-        hbox.pack_end(button, False, False, 0)
+    def set_model(self, tree_model):
+        self.table_tree.set_model(tree_model)
+
+    def set_search_entry(self, search_column_id, entry):
+        self.table_tree.set_search_column(search_column_id)
+        self.table_tree.set_search_entry(entry)
+
+    def toggle_default(self):
+        model = self.table_tree.get_model()
+        if not model:
+            return
+        iter = model.get_iter_first()
+        if iter:
+            rowpath = model.get_path(iter)
+            model[rowpath][self.toggle_id] = True
+
+    def toggled_cb(self, cell, path, columnid, tree):
+        self.emit("toggled", cell, path, columnid, tree)
 
-        self.pack_start(hbox, False, False, 0)
+    def selection_changed_cb(self, selection, tree):
+        self.emit("changed", selection, tree)
 
  class HobViewBar (gtk.EventBox):
      """
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +22 -2
index e8419e0..7f93db7 100755
@@ -23,7 +23,7 @@
  import gobject
  import gtk
  from bb.ui.crumbs.hobcolor import HobColors
-from bb.ui.crumbs.hobwidget import hic, HobWidget
+from bb.ui.crumbs.hobwidget import hic, HobViewTable
  from bb.ui.crumbs.hobpages import HobPage
 
  #
@@ -31,8 +31,28 @@ from bb.ui.crumbs.hobpages import HobPage
  #
  class ImageDetailsPage (HobPage):
 
+    __columns__ = [{
+            'col_name' : 'Image name',
+            'col_id'   : 0,
+            'col_style': 'text',
+            'col_min'  : 500,
+            'col_max'  : 500
+        }, {
+            'col_name' : 'Image size',
+            'col_id'   : 1,
+            'col_style': 'text',
+            'col_min'  : 100,
+            'col_max'  : 100
+        }, {
+            'col_name' : 'Select',
+            'col_id'   : 2,
+            'col_style': 'radio toggle',
+            'col_min'  : 100,
+            'col_max'  : 100
+    }]
+
      class DetailBox (gtk.EventBox):
-        def __init__(self, varlist, vallist, icon = None, button = None, color = HobColors.LIGHT_GRAY):
+        def __init__(self, widget = None, varlist = None, vallist = None, icon = None, button = None, color = HobColors.LIGHT_GRAY):
              gtk.EventBox.__init__(self)
 
              # set color

bitbake/lib/bb/ui/crumbs/imagedetailspage.py class ImageDetailsPage (HobPage): · line 71

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +5 -2
@@ -44,8 +64,11 @@ class ImageDetailsPage (HobPage):
              self.hbox.set_border_width(15)
              self.add(self.hbox)
 
-            # pack the icon and the text on the left
-            row = len(varlist)
+            if widget != None:
+                row = 1
+            elif varlist != None and vallist != None:
+                # pack the icon and the text on the left
+                row = len(varlist)

Usually in Python we'd just do a boolean test on the object like:

if widget:
row = 1
elif varlist and vallist:
row = len(varlist)

bitbake/lib/bb/ui/crumbs/imagedetailspage.py class ImageDetailsPage (HobPage): · line 80

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +1 -2
              self.table = gtk.Table(row, 20, True)
              self.table.set_size_request(100, -1)
              self.hbox.pack_start(self.table, expand=True, fill=True, padding=15)
@@ -54,8 +77,11 @@ class ImageDetailsPage (HobPage):
              if icon != None:
                  self.table.attach(icon, colid, colid + 2, 0, 1)
                  colid = colid + 2
-            for line in range(0, row):
-                self.table.attach(self.text2label(varlist[line], vallist[line]), colid, 20, line, line + 1)
+            if widget != None:

same here,
if widget:

bitbake/lib/bb/ui/crumbs/imagedetailspage.py class ImageDetailsPage (HobPage): · line 82

Quoted 2 lines
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +2 -0
+                self.table.attach(widget, colid, 20, 0, 1)
+            elif varlist != None and vallist != None:

and here,
elif varlist and vallist:

Quoted 179 lines
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +23 -6
+                for line in range(0, row):
+                    self.table.attach(self.text2label(varlist[line], vallist[line]), colid, 20, line, line + 1)
 
              # pack the button on the right
              if button != None:
@@ -137,7 +163,7 @@ class ImageDetailsPage (HobPage):
              icon.set_from_pixbuf(pix_buffer)
              varlist = [""]
              vallist = ["Your image is ready"]
-            build_result = self.DetailBox(varlist=varlist, vallist=vallist, icon=icon, button=None, color=color)
+            build_result = self.DetailBox(varlist=varlist, vallist=vallist, icon=icon, color=color)
              self.box_group_area.pack_start(build_result, expand=False, fill=False)
 
          # Name
@@ -145,9 +171,12 @@ class ImageDetailsPage (HobPage):
          for image_name in image_names:
              image_size = self._size_to_string(os.stat(os.path.join(image_addr, image_name)).st_size)
              self.image_store.set(self.image_store.append(), 0, image_name, 1, image_size, 2, False)
-        images_widget, treeview = HobWidget.gen_images_widget(600, 200, 100)
-        treeview.set_model(self.image_store)
-        self.box_group_area.pack_start(images_widget, expand=False, fill=False)
+        image_table = HobViewTable(self.__columns__)
+        image_table.set_model(self.image_store)
+        image_table.toggle_default()
+        image_table.connect("toggled", self.toggled_cb)
+        view_files_button = gtk.LinkButton("file://%s" % image_addr, "View files")
+        self.box_group_area.pack_start(self.DetailBox(widget=image_table, button=view_files_button), expand=True, fill=True)
 
          # Machine, Base image and Layers
          layer_num_limit = 15
@@ -175,7 +204,7 @@ class ImageDetailsPage (HobPage):
 
              edit_config_button = gtk.LinkButton("Changes settings for build", "Edit configuration")
              edit_config_button.connect("clicked", self.edit_config_button_clicked_cb)
-            setting_detail = self.DetailBox(varlist=varlist, vallist=vallist, icon=None, button=edit_config_button)
+            setting_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_config_button)
              self.box_group_area.pack_start(setting_detail, expand=False, fill=False)
 
          # Packages included, and Total image size
@@ -188,7 +217,7 @@ class ImageDetailsPage (HobPage):
              edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
          else: # get to this page from "My images"
              edit_packages_button = None
-        package_detail = self.DetailBox(varlist=varlist, vallist=vallist, icon=None, button=edit_packages_button)
+        package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
          self.box_group_area.pack_start(package_detail, expand=False, fill=False)
          if build_succeeded:
              buttonlist = ["Build new image", "Save as template", "Run image", "Deploy image"]
@@ -199,6 +228,18 @@ class ImageDetailsPage (HobPage):
 
          self.show_all()
 
+    def toggled_cb(self, table, cell, path, columnid, tree):
+        model = tree.get_model()
+        if not model:
+            return
+        iter = model.get_iter_first()
+        while iter:
+            rowpath = model.get_path(iter)
+            model[rowpath][columnid] = False
+            iter = model.iter_next(iter)
+
+        model[path][columnid] = True
+
      def create_bottom_buttons(self, buttonlist):
          # Create the buttons at the bottom
          bottom_buttons = gtk.HBox(False, 5)
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +17 -11
index 8a8ab75..280d480 100755
@@ -51,7 +51,7 @@ class PackageSelectionPage (HobPage):
                        }, {
                         'col_name' : 'Included',
                         'col_id'   : PackageListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                         'col_min'  : 50,
                         'col_max'  : 50
                        }]
@@ -79,7 +79,7 @@ class PackageSelectionPage (HobPage):
                        }, {
                         'col_name' : 'Included',
                         'col_id'   : PackageListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                         'col_min'  : 50,
                         'col_max'  : 50
                       }]
@@ -111,9 +111,19 @@ class PackageSelectionPage (HobPage):
          # append the tab
          for i in range(len(self.pages)):
              columns = self.pages[i]['columns']
-            tab = HobViewTable(columns, self.reset_clicked_cb, self.table_toggled_cb)
+            tab = HobViewTable(columns)
              filter = self.pages[i]['filter']
-            tab.table_tree.set_model(self.package_model.tree_model(filter))
+            tab.set_model(self.package_model.tree_model(filter))
+            tab.connect("toggled", self.table_toggled_cb)
+            if self.pages[i]['name'] == "Included":
+                tab.connect("changed", self.tree_selection_cb)
+
+            reset_button = gtk.Button("Reset")
+            reset_button.connect("clicked", self.reset_clicked_cb)
+            hbox = gtk.HBox(False, 5)
+            hbox.pack_end(reset_button, expand=False, fill=False)
+            tab.pack_start(hbox, expand=False, fill=False)
+
              label = gtk.Label(self.pages[i]['name'])
              self.ins.append_page(tab, label)
              self.tables.append(tab)
@@ -124,11 +134,7 @@ class PackageSelectionPage (HobPage):
          self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
          # set the search entry for each table
          for tab in self.tables:
-            tab.table_tree.set_search_entry(self.topbar.search)
-
-        inctab_tree_view = self.tables[len(self.pages)-1].table_tree
-        inctab_tree_selection = inctab_tree_view.get_selection()
-        inctab_tree_selection.connect("changed", self.tree_selection_cb, inctab_tree_view)
+            tab.set_search_entry(0, self.topbar.search)
 
          # add all into the dialog
          self.box_group_area.add(self.grid)
@@ -155,7 +161,7 @@ class PackageSelectionPage (HobPage):
          self.back_button.connect("clicked", self.back_button_clicked_cb)
          button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, tree_selection, tree_view):
+    def tree_selection_cb(self, table, tree_selection, tree_view):
          tree_model = tree_view.get_model()
          path, column = tree_view.get_cursor()
          if not path or column == tree_view.get_column(2):
@@ -218,7 +224,7 @@ class PackageSelectionPage (HobPage):
 
          self.builder.window_sensitive(True)
 
-    def table_toggled_cb(self, cell, view_path, view_tree):
+    def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree):
          # Click to include a package
          self.builder.window_sensitive(False)
          view_model = view_tree.get_model()
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +4 -4
index 73b8a1e..93540b2 100755
@@ -56,7 +56,7 @@ class RecipeSelectionPage (HobPage):
                        }, {
                         'col_name' : 'Included',
                         'col_id'   : RecipeListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                         'col_min'  : 50,
                         'col_max'  : 50
                        }]
@@ -78,7 +78,7 @@ class RecipeSelectionPage (HobPage):
                        }, {
                         'col_name' : 'Included',
                         'col_id'   : RecipeListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                         'col_min'  : 50,
                         'col_max'  : 50
                        }]
@@ -101,7 +101,7 @@ class RecipeSelectionPage (HobPage):
                        }, {
                         'col_name' : 'Included',
                         'col_id'   : RecipeListModel.COL_INC,
-                       'col_style': 'toggle',
+                       'col_style': 'check toggle',
                         'col_min'  : 50,
                         'col_max'  : 50
                        }]
@@ -135,9 +135,19 @@ class RecipeSelectionPage (HobPage):
          # append the tabs in order
          for i in range(len(self.pages)):
              columns = self.pages[i]['columns']
-            tab = HobViewTable(columns, self.reset_clicked_cb, self.table_toggled_cb)
+            tab = HobViewTable(columns)

bitbake/lib/bb/ui/crumbs/recipeselectionpage.py class RecipeSelectionPage (HobPage): · line 147

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +8 -1
              filter = self.pages[i]['filter']
-            tab.table_tree.set_model(self.recipe_model.tree_model(filter))
+            tab.set_model(self.recipe_model.tree_model(filter))
+            tab.connect("toggled", self.table_toggled_cb)
+            if self.pages[i]['name'] == "Included":
+                tab.connect("changed", self.tree_selection_cb)
+
+            reset_button = gtk.Button("Reset")
+            reset_button.connect("clicked", self.reset_clicked_cb)
+            hbox = gtk.HBox(False, 5)

*Beep* 5 for padding? :-)

Quoted 37 lines
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +6 -7
+            hbox.pack_end(reset_button, expand=False, fill=False)
+            tab.pack_start(hbox, expand=False, fill=False)
+
              label = gtk.Label(self.pages[i]['name'])
              self.ins.append_page(tab, label)
              self.tables.append(tab)
@@ -148,11 +158,7 @@ class RecipeSelectionPage (HobPage):
          self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
          # set the search entry for each table
          for tab in self.tables:
-            tab.table_tree.set_search_entry(self.topbar.search)
-
-        inctab_tree_view = self.tables[len(self.pages)-1].table_tree
-        inctab_tree_selection = inctab_tree_view.get_selection()
-        inctab_tree_selection.connect("changed", self.tree_selection_cb, inctab_tree_view)
+            tab.set_search_entry(0, self.topbar.search)
 
          # add all into the window
          self.box_group_area.add(self.grid)
@@ -179,7 +185,7 @@ class RecipeSelectionPage (HobPage):
          self.back_button.connect("clicked", self.back_button_clicked_cb)
          button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, tree_selection, tree_view):
+    def tree_selection_cb(self, table, tree_selection, tree_view):
          tree_model = tree_view.get_model()
          path, column = tree_view.get_cursor()
          if not path or column == tree_view.get_column(2):
@@ -213,7 +219,7 @@ class RecipeSelectionPage (HobPage):
 
          self.builder.window_sensitive(True)
 
-    def table_toggled_cb(self, cell, view_path, view_tree):
+    def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree):
          # Click to include a recipe
          self.builder.window_sensitive(False)
          view_model = view_tree.get_model()
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#6 lore raw

Re: [PATCH 04/32] Hob: fixed the issue in the brought-in-by dialog.

In reply to Shane Wang
Quoted 5 lines · Shane Wang

When typing any thing in the search entry, the brough-in-by dialog will be shown. That is because we call back "selection-changed" signal to pop up the dialog, which is not correct. This patch is to fix the problem by using "row-activated" signal.

I point out some incorrect padding below but other than that:

Quoted 15 lines
---
  bitbake/lib/bb/ui/crumbs/hig.py                  |    5 +---
  bitbake/lib/bb/ui/crumbs/hobwidget.py            |   30 ++++++++++++---------
  bitbake/lib/bb/ui/crumbs/packageselectionpage.py |   12 ++------
  bitbake/lib/bb/ui/crumbs/recipeselectionpage.py  |   13 ++-------
  4 files changed, 24 insertions(+), 36 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +0 -0
index 2de7b2a..74f4f7b 100644
@@ -89,15 +89,12 @@ class BinbDialog(gtk.Dialog):
          self.set_resizable(False)
          self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.DARK))
 

bitbake/lib/bb/ui/crumbs/hig.py class BinbDialog(gtk.Dialog): · line 97

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hig.py +1 -4
-        hbox = gtk.HBox(False, 0)
-        self.vbox.pack_start(hbox, expand=False, fill=False, padding=10)
-
          label = gtk.Label(content)
          label.set_alignment(0, 0)
          label.set_line_wrap(True)
          label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.WHITE))
 
-        hbox.pack_start(label, expand=False, fill=False, padding=10)
+        self.vbox.pack_start(label, expand=True, fill=True, padding=10)

Padding needs fixing at some point. Perhaps one series can focus on that?

Quoted 133 lines
bitbake/lib/bb/ui/crumbs/hig.py +0 -0
          self.vbox.show_all()
 
  #
bitbake/lib/bb/ui/crumbs/hobwidget.py +17 -13
index 4bbbed6..664bf25 100644
@@ -55,16 +55,16 @@ class HobViewTable (gtk.VBox):
      A VBox to contain the table for different recipe views and package view
      """
      __gsignals__ = {
-         "toggled"      : (gobject.SIGNAL_RUN_LAST,
-                           gobject.TYPE_NONE,
-                          (gobject.TYPE_PYOBJECT,
-                           gobject.TYPE_STRING,
-                           gobject.TYPE_INT,
-                           gobject.TYPE_PYOBJECT,)),
-         "changed"      : (gobject.SIGNAL_RUN_LAST,
-                           gobject.TYPE_NONE,
-                          (gobject.TYPE_PYOBJECT,
-                           gobject.TYPE_PYOBJECT,)),
+         "toggled"       : (gobject.SIGNAL_RUN_LAST,
+                            gobject.TYPE_NONE,
+                           (gobject.TYPE_PYOBJECT,
+                            gobject.TYPE_STRING,
+                            gobject.TYPE_INT,
+                            gobject.TYPE_PYOBJECT,)),
+         "row-activated" : (gobject.SIGNAL_RUN_LAST,
+                            gobject.TYPE_NONE,
+                           (gobject.TYPE_PYOBJECT,
+                            gobject.TYPE_PYOBJECT,)),
      }
 
      def __init__(self, columns):
@@ -75,7 +75,8 @@ class HobViewTable (gtk.VBox):
          self.table_tree.set_enable_search(True)
          self.table_tree.set_rules_hint(True)
          self.table_tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
-        self.table_tree.get_selection().connect("changed", self.selection_changed_cb, self.table_tree)
+        self.toggle_columns = []
+        self.table_tree.connect("row-activated", self.row_activated_cb)
 
          for i in range(len(columns)):
              col = gtk.TreeViewColumn(columns[i]['col_name'])
@@ -99,6 +100,7 @@ class HobViewTable (gtk.VBox):
                  self.toggle_id = i
                  col.pack_end(cell, True)
                  col.set_attributes(cell, active=columns[i]['col_id'])
+                self.toggle_columns.append(columns[i]['col_name'])
              elif columns[i]['col_style'] == 'radio toggle':
                  cell = gtk.CellRendererToggle()
                  cell.set_property('activatable', True)
@@ -107,6 +109,7 @@ class HobViewTable (gtk.VBox):
                  self.toggle_id = i
                  col.pack_end(cell, True)
                  col.set_attributes(cell, active=columns[i]['col_id'])
+                self.toggle_columns.append(columns[i]['col_name'])
 
          scroll = gtk.ScrolledWindow()
          scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
@@ -133,8 +136,9 @@ class HobViewTable (gtk.VBox):
      def toggled_cb(self, cell, path, columnid, tree):
          self.emit("toggled", cell, path, columnid, tree)
 
-    def selection_changed_cb(self, selection, tree):
-        self.emit("changed", selection, tree)
+    def row_activated_cb(self, tree, path, view_column):
+        if not view_column.get_title() in self.toggle_columns:
+            self.emit("row-activated", tree.get_model(), path)
 
  class HobViewBar (gtk.EventBox):
      """
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +3 -9
index 280d480..a3c4acd 100755
@@ -116,7 +116,7 @@ class PackageSelectionPage (HobPage):
              tab.set_model(self.package_model.tree_model(filter))
              tab.connect("toggled", self.table_toggled_cb)
              if self.pages[i]['name'] == "Included":
-                tab.connect("changed", self.tree_selection_cb)
+                tab.connect("row-activated", self.tree_row_activated_cb)
 
              reset_button = gtk.Button("Reset")
              reset_button.connect("clicked", self.reset_clicked_cb)
@@ -161,14 +161,8 @@ class PackageSelectionPage (HobPage):
          self.back_button.connect("clicked", self.back_button_clicked_cb)
          button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, table, tree_selection, tree_view):
-        tree_model = tree_view.get_model()
-        path, column = tree_view.get_cursor()
-        if not path or column == tree_view.get_column(2):
-            return
-
-        it = tree_model.get_iter(path)
-        binb = tree_model.get_value(it, PackageListModel.COL_BINB)
+    def tree_row_activated_cb(self, table, tree_model, path):
+        binb = tree_model.get_value(tree_model.get_iter(path), PackageListModel.COL_BINB)
          if binb:
              self.builder.show_binb_dialog(binb)
 
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +3 -10
index cf8504a..ee36f8c 100755
@@ -140,8 +140,7 @@ class RecipeSelectionPage (HobPage):
              tab.set_model(self.recipe_model.tree_model(filter))
              tab.connect("toggled", self.table_toggled_cb)
              if self.pages[i]['name'] == "Included":
-                tab.connect("changed", self.tree_selection_cb)
-
+                tab.connect("row-activated", self.tree_row_activated_cb)
              reset_button = gtk.Button("Reset")
              reset_button.connect("clicked", self.reset_clicked_cb)
              hbox = gtk.HBox(False, 5)
@@ -185,14 +184,8 @@ class RecipeSelectionPage (HobPage):
          self.back_button.connect("clicked", self.back_button_clicked_cb)
          button_box.pack_start(self.back_button, expand=False, fill=False)
 
-    def tree_selection_cb(self, table, tree_selection, tree_view):
-        tree_model = tree_view.get_model()
-        path, column = tree_view.get_cursor()
-        if not path or column == tree_view.get_column(2):
-            return
-
-        it = tree_model.get_iter(path)
-        binb = tree_model.get_value(it, RecipeListModel.COL_BINB)
+    def tree_row_activated_cb(self, table, tree_model, path):
+        binb = tree_model.get_value(tree_model.get_iter(path), RecipeListModel.COL_BINB)
          if binb:
              self.builder.show_binb_dialog(binb)
 
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#41 lore raw

Re: [PATCH 21/32] cooker.py: Fix a bug due to variable name

In reply to Shane Wang
Quoted 6 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

fnid is an outer variable and shouldn't be overrided, change the inner variable name from 'fnid' to 'id'.

Quoted 19 lines
---
  bitbake/lib/bb/cooker.py |    4 ++--
  1 files changed, 2 insertions(+), 2 deletions(-)
bitbake/lib/bb/cooker.py +2 -2
index 2e4a1ba..b23b569 100644
@@ -501,8 +501,8 @@ class BBCooker:
                      pn_provider = ""
                      targetid = taskdata.getbuild_id(item)
                      if targetid in taskdata.build_targets and taskdata.build_targets[targetid]:
-                        fnid = taskdata.build_targets[targetid][0]
-                        fn_provider = taskdata.fn_index[fnid]
+                        id = taskdata.build_targets[targetid][0]
+                        fn_provider = taskdata.fn_index[id]
                          pn_provider = self.status.pkg_fn[fn_provider]
                      else:
                          pn_provider = item
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#39 lore raw

Re: [PATCH 20/32] command.py: remove the resolve parameter in generateTargetsTree

In reply to Shane Wang
Quoted 6 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

Remove the "resolve" parameter since the original resolve=False option is no longer be used.

Quoted 127 lines
---
  bitbake/lib/bb/command.py                   |   14 +---------
  bitbake/lib/bb/cooker.py                    |   33 +++++++++++---------------
  bitbake/lib/bb/ui/crumbs/hobeventhandler.py |    2 +-
  3 files changed, 17 insertions(+), 32 deletions(-)
bitbake/lib/bb/command.py +2 -12
index 06e8869..1799f1c 100644
@@ -242,21 +242,11 @@ class CommandsAsync:
          included in the package list.
          If pkg_list provided use that list (plus any extras brought in by
          klass) rather than generating a tree for all packages.
-
-        Add a new option "resolve" to indicate if we need to resolve the
-        replacement for "virtual/xxx" like pn.
          """
          klass = params[0]
-        resolve = False
-        if len(params)>  2:
-            pkg_list = params[1]
-            resolve = params[2]
-        elif len(params)>  1:
-            pkg_list = params[1]
-        else:
-            pkg_list = []
+        pkg_list = params[1]
 
-        command.cooker.generateTargetsTree(klass, pkg_list, resolve)
+        command.cooker.generateTargetsTree(klass, pkg_list)
          command.finishAsyncCommand()
      generateTargetsTree.needcache = True
 
bitbake/lib/bb/cooker.py +14 -19
index 12b526b..2e4a1ba 100644
@@ -451,7 +451,7 @@ class BBCooker:
                  depend_tree_package[package]["filename"] = fn
                  depend_tree_package[package]["version"] = version
 
-    def generatePkgDepTreeData(self, pkgs_to_build, task, resolve=False):
+    def generatePkgDepTreeData(self, pkgs_to_build, task):
          """
          Create a dependency tree of pkgs_to_build, returning the data.
          """
@@ -497,19 +497,16 @@ class BBCooker:
 
                  depend_tree["depends"][pn] = []
                  for dep in taskdata.depids[fnid]:
-                    if resolve:
-                        item = taskdata.build_names_index[dep]
-                        pn_provider = ""
-                        targetid = taskdata.getbuild_id(item)
-                        if targetid in taskdata.build_targets and taskdata.build_targets[targetid]:
-                            fnid = taskdata.build_targets[targetid][0]
-                            fn_provider = taskdata.fn_index[fnid]
-                            pn_provider = self.status.pkg_fn[fn_provider]
-                        else:
-                            pn_provider = item
-                        depend_tree["depends"][pn].append(pn_provider)
+                    item = taskdata.build_names_index[dep]
+                    pn_provider = ""
+                    targetid = taskdata.getbuild_id(item)
+                    if targetid in taskdata.build_targets and taskdata.build_targets[targetid]:
+                        fnid = taskdata.build_targets[targetid][0]
+                        fn_provider = taskdata.fn_index[fnid]
+                        pn_provider = self.status.pkg_fn[fn_provider]
                      else:
-                        depend_tree["depends"][pn].append(taskdata.build_names_index[dep])
+                        pn_provider = item
+                    depend_tree["depends"][pn].append(pn_provider)
 
                  depend_tree["rdepends-pn"][pn] = []
                  for rdep in taskdata.rdepids[fnid]:
@@ -519,8 +516,7 @@ class BBCooker:
                      depend_tree["rdepends-pkg"][package] = []
                      for rdepend in rdepends[package]:
                          depend_tree["rdepends-pkg"][package].append(rdepend)
-                        if resolve:
-                            self.append_package(taskdata, depend_tree["packages"], rdepend)
+                        self.append_package(taskdata, depend_tree["packages"], rdepend)
                      if not package in packages:
                          packages.append(package)
 
@@ -528,8 +524,7 @@ class BBCooker:
                      depend_tree["rrecs-pkg"][package] = []
                      for rrec in rrecs[package]:
                          depend_tree["rrecs-pkg"][package].append(rrec)
-                        if resolve:
-                            self.append_package(taskdata, depend_tree["packages"], rrec)
+                        self.append_package(taskdata, depend_tree["packages"], rrec)
                      if not package in packages:
                          packages.append(package)
 
@@ -780,7 +775,7 @@ class BBCooker:
 
          return pkg_list
 
-    def generateTargetsTree(self, klass=None, pkgs=[], resolve=False):
+    def generateTargetsTree(self, klass=None, pkgs=[]):
          """
          Generate a dependency tree of buildable targets
          Generate an event with the result
@@ -795,7 +790,7 @@ class BBCooker:
              pkgs = pkgs + extra_pkgs
 
          # generate a dependency tree for all our packages
-        tree = self.generatePkgDepTreeData(pkgs, 'build', resolve)
+        tree = self.generatePkgDepTreeData(pkgs, 'build')
          bb.event.fire(bb.event.TargetsTreeGenerated(tree), self.configuration.data)
 
      def buildWorldTargetList(self):
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +1 -1
index 2bf4ed8..6c109fc 100644
@@ -148,7 +148,7 @@ class HobHandler(gobject.GObject):
          elif next_command == self.PARSE_BBFILES:
              self.server.runCommand(["parseFiles"])
          elif next_command == self.GENERATE_TGTS:
-            self.server.runCommand(["generateTargetsTree", "classes/image.bbclass", [], True])
+            self.server.runCommand(["generateTargetsTree", "classes/image.bbclass", []])
          elif next_command == self.GENERATE_PACKAGEINFO:
              self.server.runCommand(["triggerEvent", "bb.event.RequestPackageInfo()"])
          elif next_command == self.BUILD_TARGET_RECIPES:
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#21 lore raw

Re: [PATCH 08/32] Hob: image configuration page doesn't need dialogs any more

In reply to Shane Wang
Quoted 3 lines · Shane Wang

The dialog references are all in builder.py. We remove the useless "import" in image configuration page.

Quoted 18 lines
---
  bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py |    3 ---
  1 files changed, 0 insertions(+), 3 deletions(-)
bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py +0 -3
index d3a9ffd..4083360 100644
@@ -28,9 +28,6 @@ from bb.ui.crumbs.hobwidget import hic, HobXpmLabelButtonBox
  from bb.ui.crumbs.hoblistmodel import RecipeListModel
  from bb.ui.crumbs.hobpages import HobPage
 
-from bb.ui.crumbs.hig import CrumbsDialog, BinbDialog, \
-                             AdvancedSettingDialog, LayerSelectionDialog
-
  #
  # ImageConfigurationPage
  #
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#28 lore raw

Re: [PATCH 11/32] Hob: make the image configuration page not to flash the progress bar

In reply to Shane Wang
Quoted 3 lines · Shane Wang

Sometimes the image configuration page flashes the progress bar, that is because we show_all() and then hide() the progress bar. For this case, the patch doesn't add the progress bar onto the gtable. Then, it will not be flashed any more.

I'm not a fan of show_all() but this looks fine:

Quoted 77 lines
---
  bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py |   30 +++++++++----------
  1 files changed, 14 insertions(+), 16 deletions(-)
bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py +14 -16
index cd86606..db54d79 100644
@@ -84,21 +84,20 @@ class ImageConfigurationPage (HobPage):
          for child in children:
              self.remove(child)
 
-    def _pack_components(self):
+    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)
-        self.box_group_area.pack_end(self.config_build_button, expand=False, fill=False)
+        if pack_config_build_button == True:
+            self.box_group_area.pack_end(self.config_build_button, expand=False, fill=False)
 
      def show_machine(self):
-        self._pack_components()
-        self.set_config_machine_layout()
-        self.show_all()
          self.progress_bar.reset()
-        self.progress_bar.hide()
-        self.config_build_button.hide_all()
+        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=True):
          self.progress_bar.update(fraction)
@@ -106,18 +105,16 @@ class ImageConfigurationPage (HobPage):
          self.progress_bar.set_rcstyle(status)
 
      def show_info_populating(self):
-        self._pack_components()
-        self.set_config_machine_layout()
+        self._pack_components(pack_config_build_button = False)
+        self.set_config_machine_layout(show_progress_bar = True)
          self.show_all()
-        self.config_build_button.hide_all()
 
      def show_info_populated(self):
-        self._pack_components()
-        self.set_config_machine_layout()
+        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()
-        self.progress_bar.reset()
-        self.progress_bar.hide()
 
      def create_config_machine(self):
          self.machine_title = gtk.Label()
@@ -154,13 +151,14 @@ class ImageConfigurationPage (HobPage):
          self.progress_bar = HobProgressBar()
          self.machine_separator = gtk.HSeparator()
 
-    def set_config_machine_layout(self):
+    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, 6, 9)
          self.gtable.attach(self.layer_button, 12, 36, 6, 10)
          self.gtable.attach(self.layer_info_icon, 36, 40, 6, 9)
-        self.gtable.attach(self.progress_bar, 0, 40, 13, 17)
+        if show_progress_bar == True:
+            self.gtable.attach(self.progress_bar, 0, 40, 13, 17)
          self.gtable.attach(self.machine_separator, 0, 40, 12, 13)
 
      def create_config_baseimg(self):
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#37 lore raw

Re: [PATCH 19/32] Hob(crumbs/builder.py): remove the code commented out in the builder.py

In reply to Shane Wang
Quoted 1 line · Shane Wang
Quoted 16 lines
---
  bitbake/lib/bb/ui/crumbs/builder.py |    1 -
  1 files changed, 0 insertions(+), 1 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +0 -1
index 7772f56..0d7f1c1 100755
@@ -200,7 +200,6 @@ class Builder(gtk.Window):
          self.create_visual_elements()
 
          # connect the signals to functions
-        #self.connect("configure-event", self.resize_window_cb)
          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)
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#23 lore raw

Re: [PATCH 09/32] Hob: fix a bug in builder.configuration.curr_mach

In reply to Shane Wang
Quoted 4 lines · Shane Wang

When the user changes the machine to be "--select a machine--", the builder.configuration.curr_mach should be set to empty. Otherwise, if the user adds more layers after the above, the action will trigger recipe parsing, which is not correct.

Quoted 16 lines
---
  bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py |    1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
bitbake/lib/bb/ui/crumbs/imageconfigurationpage.py +1 -0
index 4083360..cd86606 100644
@@ -243,6 +243,7 @@ class ImageConfigurationPage (HobPage):
      def machine_combo_changed_cb(self, machine_combo):
          combo_item = machine_combo.get_active_text()
          if not combo_item or combo_item == self.__dummy_machine__:
+            self.builder.configuration.curr_mach = ""
              self.builder.switch_page(self.builder.MACHINE_SELECTION)
          else:
              self.builder.configuration.curr_mach = combo_item
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#25 lore raw

Re: [PATCH 10/32] Hob: add ignore_all_errors to avoid showing error dialog multiple times

In reply to Shane Wang
Quoted 1 line · Shane Wang

when parsing recipes, if there are some errors, the error dialog will be shown again and again for each error, add "Ignore All" to allow users to ignore those errors.

I'm not so sure about this. I don't think ignoring all parse errors is the right thing, collecting them up into one dialogue seems like a better first step.

What if I add some layers which introduce different parsing errors after I've clicked 'Ignore All' once?

Cheers,
Joshua

Quoted 51 lines
---
  bitbake/lib/bb/ui/crumbs/builder.py |   20 ++++++++++++++------
  1 files changed, 14 insertions(+), 6 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +14 -6
index 819b79f..fc231ef 100755
@@ -178,6 +178,8 @@ class Builder(gtk.Window):
 
          self.template = None
 
+        self.ignore_all_errors = False
+
          # settings
          params = self.handler.get_parameters()
          self.configuration = Configuration(params)
@@ -315,6 +317,8 @@ class Builder(gtk.Window):
 
          elif next_step == self.RCPPKGINFO_POPULATING:
              # MACHINE CHANGED action or SETTINGS CHANGED
+            # reset the "ignore all errors" var
+            self.ignore_all_errors = False
              # show the progress bar
              self.image_configuration_page.show_info_populating()
              self.generate_recipes()
@@ -440,12 +444,16 @@ class Builder(gtk.Window):
                  self.switch_page(self.IMAGE_GENERATED)
 
      def handler_command_failed_cb(self, handler, msg):
-        lbl = "<b>Error</b>\n"
-        lbl = lbl + "%s\n\n" % msg
-        dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
-        dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
-        response = dialog.run()
-        dialog.destroy()
+        if self.ignore_all_errors == False:
+            lbl = "<b>Error</b>\n"
+            lbl = lbl + "%s\n\n" % msg
+            dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_WARNING)
+            dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
+            dialog.add_button("Ignore All", gtk.RESPONSE_REJECT)
+            response = dialog.run()
+            if response == gtk.RESPONSE_REJECT:
+                self.ignore_all_errors = True
+            dialog.destroy()
          self.handler.clear_busy()
          self.configuration.curr_mach = None
          self.image_configuration_page.switch_machine_combo()
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#61 lore raw

Re: [PATCH 28/32] Hob: allow users to setup the proxy

In reply to Shane Wang
Quoted 1 line · Shane Wang

This patch is to set os.environ to allow users to set the environment variables for http_proxy, https_proxy and ftp_proxy.

I think this needs more work, I have a text entry with an attached button that spawns a file chooser. What file would I choose here?

What about if my http, ftp and socks proxy are different?

Cheers,
Joshua

Quoted 133 lines
---
  bitbake/lib/bb/ui/crumbs/builder.py |   23 +++++++++++++++++++++++
  bitbake/lib/bb/ui/crumbs/hig.py     |   26 +++++++++++++++++++++++++-
  2 files changed, 48 insertions(+), 1 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +23 -0
index 0d7f1c1..e9853f2 100755
@@ -116,6 +116,7 @@ class Configuration:
 
  class Parameters:
      '''Represents other variables like available machines, etc.'''
+    __dummy_proxy__ = "myproxy.example.com:8010"
 
      def __init__(self, params):
          # Variables
@@ -129,6 +130,8 @@ class Parameters:
          self.image_names = []
          self.image_addr = params["image_addr"]
          self.image_types = params["image_types"].split()
+        self.proxy = self.__dummy_proxy__
+        self.enable_proxy = False
 
  class Builder(gtk.Window):
 
@@ -727,6 +730,19 @@ class Builder(gtk.Window):
 
          dialog.destroy()
 
+    def _setup_proxy(self):
+        if self.parameters.proxy == Parameters.__dummy_proxy__ or self.parameters.proxy.lstrip() == "":
+            if "http_proxy" in os.environ.keys():
+                del os.environ["http_proxy"]
+            if "https_proxy" in os.environ.keys():
+                del os.environ["https_proxy"]
+            if "ftp_proxy" in os.environ.keys():
+                del os.environ["ftp_proxy"]
+        else:
+            os.environ["http_proxy"] = self.parameters.proxy
+            os.environ["https_proxy"] = self.parameters.proxy
+            os.environ["ftp_proxy"] = self.parameters.proxy
+
      def show_adv_settings_dialog(self):
          dialog = AdvancedSettingDialog(title = "Settings",
              configuration = copy.deepcopy(self.configuration),
@@ -735,6 +751,8 @@ class Builder(gtk.Window):
              all_distros = self.parameters.all_distros,
              all_sdk_machines = self.parameters.all_sdk_machines,
              max_threads = self.parameters.max_threads,
+            proxy = self.parameters.proxy,
+            enable_proxy = self.parameters.enable_proxy,
              split_model = self.get_split_model(),
              parent = self,
              flags = gtk.DIALOG_MODAL
@@ -745,6 +763,11 @@ class Builder(gtk.Window):
          response = dialog.run()
          if response == gtk.RESPONSE_YES:
              self.configuration = dialog.configuration
+            # setup the proxy
+            self.parameters.enable_proxy = dialog.enable_proxy
+            if self.parameters.enable_proxy == True:
+                self.parameters.proxy = dialog.proxy
+                self._setup_proxy()
              # DO reparse recipes
              if dialog.settings_changed:
                  if self.configuration.curr_mach == "":
bitbake/lib/bb/ui/crumbs/hig.py +25 -1
index 20585b7..7e1c1ff 100644
@@ -428,7 +428,7 @@ class AdvancedSettingDialog (CrumbsDialog):
 
      def __init__(self, title, configuration, all_image_types,
              all_package_formats, all_distros, all_sdk_machines,
-            max_threads, split_model, parent, flags, buttons):
+            max_threads, proxy, enable_proxy, split_model, parent, flags, buttons):
          super(AdvancedSettingDialog, self).__init__(title, parent, flags, buttons)
 
          # class members from other objects
@@ -439,6 +439,8 @@ class AdvancedSettingDialog (CrumbsDialog):
          self.all_distros = all_distros
          self.all_sdk_machines = all_sdk_machines
          self.max_threads = max_threads
+        self.enable_proxy = enable_proxy
+        self.proxy = proxy
          self.split_model = split_model
 
          # class members for internal use
@@ -614,6 +616,21 @@ class AdvancedSettingDialog (CrumbsDialog):
          sub_vbox.pack_start(label, expand=False, fill=False)
          sub_vbox.pack_start(sstatemirror_widget, expand=False, fill=False)
 
+        sub_vbox = gtk.VBox(False, 6)
+        advanced_vbox.pack_start(sub_vbox, expand=False, fill=False)
+        self.proxy_checkbox = gtk.CheckButton("Enable Proxy")
+        self.proxy_checkbox.set_tooltip_text("Check this box to setup the proxy you specified")
+        self.proxy_checkbox.set_active(self.enable_proxy)
+        self.proxy_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb)
+        label = self.gen_label_widget("<span weight=\"bold\">Select Proxy:</span>")
+        tooltip = "Select the proxy that will be used in do_fetch() source code"
+        proxy_widget, self.proxy_text = self.gen_entry_widget(self.split_model, self.proxy, self, tooltip)
+        self.proxy_text.set_editable(self.enable_proxy)
+        self.proxy_text.set_sensitive(self.enable_proxy)
+        sub_vbox.pack_start(self.proxy_checkbox, expand=False, fill=False)
+        sub_vbox.pack_start(label, expand=False, fill=False)
+        sub_vbox.pack_start(proxy_widget, expand=False, fill=False)
+
          return advanced_vbox
 
      def create_others_page(self):
@@ -630,6 +647,11 @@ class AdvancedSettingDialog (CrumbsDialog):
 
          return advanced_vbox
 
+    def proxy_checkbox_toggled_cb(self, button):
+        self.enable_proxy = self.proxy_checkbox.get_active()
+        self.proxy_text.set_editable(self.enable_proxy)
+        self.proxy_text.set_sensitive(self.enable_proxy)
+
      def response_cb(self, dialog, response_id):
          self.variables = {}
 
@@ -679,6 +701,8 @@ class AdvancedSettingDialog (CrumbsDialog):
              self.variables[key] = value
              it = self.setting_store.iter_next(it)
 
+        self.proxy = self.proxy_text.get_text()
+
          md5 = hashlib.md5(str(sorted(self.variables.items()))).hexdigest()
          self.settings_changed = (self.md5 != md5)
 
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#65 lore raw

Re: [PATCH 29/32] Hob(crumbs/builder.py): adjust the main window's position and ignore the case lower than 1024x768.

In reply to Shane Wang
Quoted 4 lines · Shane Wang

* don't set the position of the main window to the center always
* don't show the message to users if their screen dimensions are lower than 1024x768

Thanks!

Joshua

Quoted 29 lines
---
  bitbake/lib/bb/ui/crumbs/builder.py |    8 --------
  1 files changed, 0 insertions(+), 8 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +0 -8
index e9853f2..f41b6a4 100755
@@ -229,20 +229,12 @@ class Builder(gtk.Window):
      def create_visual_elements(self):
          self.set_title("Hob - Image Creator")
          self.set_icon_name("applications-development")
-        self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
          self.set_resizable(True)
          window_width = self.get_screen().get_width()
          window_height = self.get_screen().get_height()
          if window_width>= hwc.MAIN_WIN_WIDTH:
              window_width = hwc.MAIN_WIN_WIDTH
              window_height = hwc.MAIN_WIN_HEIGHT
-        else:
-            lbl = "<b>Screen dimension mismatched</b>\nfor better usability and visual effects,"
-            lbl = lbl + " the screen dimension should be 1024x768 or above."
-            dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
-            dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
-            dialog.run()
-            dialog.destroy()
          self.set_size_request(window_width, window_height)
 
          self.vbox = gtk.VBox(False, 0)
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#67 lore raw

Re: [PATCH 30/32] Hob: Fix pressing "stop" build

In reply to Shane Wang
Quoted 6 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

This commit fixes the behavior of clicking stop build button, it will stay in the build detail screen and show build is failed.

Quoted 55 lines
---
  bitbake/lib/bb/ui/crumbs/builder.py |   18 +++++++++++++-----
  1 files changed, 13 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +13 -5
index f41b6a4..a04d6fa 100755
@@ -193,7 +193,6 @@ class Builder(gtk.Window):
          self.previous_step = None
 
          self.stopping = False
-        self.build_succeeded = True
 
          # recipe model and package model
          self.recipe_model = recipe_model
@@ -533,8 +532,7 @@ class Builder(gtk.Window):
          self.build_details_page.update_progress_bar("Build Started: ", fraction)
          self.build_details_page.reset_issues()
 
-    def handler_build_succeeded_cb(self, running_build):
-        self.build_succeeded = True
+    def build_succeeded(self):
          if self.current_step == self.FAST_IMAGE_GENERATING:
              fraction = 0.9
          elif self.current_step == self.IMAGE_GENERATING:
@@ -548,9 +546,9 @@ class Builder(gtk.Window):
          elif self.current_step == self.PACKAGE_GENERATING:
              fraction = 1.0
          self.build_details_page.update_progress_bar("Build Completed: ", fraction)
+        self.stopping = False
 
-    def handler_build_failed_cb(self, running_build):
-        self.build_succeeded = False
+    def build_failed(self):
          if self.current_step == self.FAST_IMAGE_GENERATING:
              fraction = 0.9
          elif self.current_step == self.IMAGE_GENERATING:
@@ -563,6 +561,16 @@ class Builder(gtk.Window):
          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_task_started_cb(self, running_build, message):
          fraction = message["current"] * 1.0/message["total"]
          title = "Build packages"
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#69 lore raw

Re: [PATCH 31/32] runqueue.py: initialize rqexe at RunQueue's init function

In reply to Shane Wang
Quoted 8 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

Sometimes user stops the build before runqueue is established, for example, at the stage of running add_unresolved() function. This will cause RunQueue to use rqexe field in finish_runqeue() before initialized. This will cause endless print of "Running idle function" if use process server.

Quoted 4 lines

This commit initialize rqexe variable in RunQueue's init function, and add a judgement in finish_runqueue().

Quoted 27 lines
---
  bitbake/lib/bb/runqueue.py |    5 +++++
  1 files changed, 5 insertions(+), 0 deletions(-)
bitbake/lib/bb/runqueue.py +5 -0
index f08f93a..0615ab4 100644
@@ -779,6 +779,8 @@ class RunQueue:
          # For disk space monitor
          self.dm = monitordisk.diskMonitor(cfgData)
 
+        self.rqexe = None
+
      def check_stamps(self):
          unchecked = {}
          current = []
@@ -996,6 +998,9 @@ class RunQueue:
          return retval
 
      def finish_runqueue(self, now = False):
+        if not self.rqexe:
+            return
+
          if now:
              self.rqexe.finish_now()
          else:
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#45 lore raw

Re: [PATCH 23/32] Hob(crumbs/hoblistmodel.py): Fix recipe's populate() function

In reply to Shane Wang
Quoted 6 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

According to the cooker's change, this commit fixes the way to getting recipe's build dependency.

Quoted 80 lines
---
  bitbake/lib/bb/ui/crumbs/hoblistmodel.py |   42 +++--------------------------
  1 files changed, 5 insertions(+), 37 deletions(-)
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +5 -37
index 227ae4b..e440979 100644
@@ -512,27 +512,6 @@ class RecipeListModel(gtk.ListStore):
              it = view_model.iter_next(it)
          return None
 
-    def map_runtime(self, event_model, runtime, rdep_type, name):
-        if rdep_type not in ['pkg', 'pn'] or runtime not in ['rdepends', 'rrecs']:
-            return
-        package_depends = event_model["%s-%s" % (runtime, rdep_type)].get(name, [])
-        pn_depends = []
-        for package_depend in package_depends:
-            if 'task-' not in package_depend and package_depend in event_model["packages"].keys():
-                pn_depends.append(event_model["packages"][package_depend]["pn"])
-            else:
-                pn_depends.append(package_depend)
-        return list(set(pn_depends))
-
-    def subpkg_populate(self, event_model, pkg, desc, lic, group, atype, pn):
-        pn_depends = self.map_runtime(event_model, "rdepends", "pkg", pkg)
-        pn_depends += self.map_runtime(event_model, "rrecs", "pkg", pkg)
-        self.set(self.append(), self.COL_NAME, pkg, self.COL_DESC, desc,
-                 self.COL_LIC, lic, self.COL_GROUP, group,
-                 self.COL_DEPS, " ".join(pn_depends), self.COL_BINB, "",
-                 self.COL_TYPE, atype, self.COL_INC, False,
-                 self.COL_IMG, False, self.COL_INSTALL, "", self.COL_PN, pn)
-
      """
      The populate() function takes as input the data from a
      bb.event.TargetsTreeGenerated event and populates the RecipeList.
@@ -558,38 +537,27 @@ class RecipeListModel(gtk.ListStore):
              group = event_model["pn"][item]["section"]
              install = []
 
+            depends = event_model["depends"].get(item, [])
+            rdepends = event_model["rdepends-pn"].get(item, [])
+            depends = depends + rdepends
+
              if ('task-' in name):
                  if ('lib32-' in name or 'lib64-' in name):
                      atype = 'mltask'
                  else:
                      atype = 'task'
-                for pkg in event_model["pn"][name]["packages"]:
-                    self.subpkg_populate(event_model, pkg, desc, lic, group, atype, name)
-                continue
-
              elif ('-image-' in name):
                  atype = 'image'
-                depends = event_model["depends"].get(item, [])
-                rdepends = self.map_runtime(event_model, 'rdepends', 'pn', name)
-                depends = depends + rdepends
-                install = event_model["rdepends-pn"].get(item, [])
-
+                install = rdepends
              elif ('meta-' in name):
                  atype = 'toolchain'
-
              elif (name == 'dummy-image' or name == 'dummy-toolchain'):
                  atype = 'dummy'
-
              else:
                  if ('lib32-' in name or 'lib64-' in name):
                      atype = 'mlrecipe'
                  else:
                      atype = 'recipe'
-                depends = event_model["depends"].get(item, [])
-                depends += self.map_runtime(event_model, 'rdepends', 'pn', item)
-                for pkg in event_model["pn"][name]["packages"]:
-                    depends += self.map_runtime(event_model, 'rdepends', 'pkg', item)
-                    depends += self.map_runtime(event_model, 'rrecs', 'pkg', item)
 
              self.set(self.append(), self.COL_NAME, item, self.COL_DESC, desc,
                       self.COL_LIC, lic, self.COL_GROUP, group,
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#57 lore raw

Re: [PATCH 27/32] Hob: add "OK" button to "BinbDialog"

In reply to Shane Wang
Quoted 5 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

For certain distributions, like FC16, it doesn't have close button in sub-windows or dialogs. Therefore we need to add an "OK" button to "BinbDialog" to close the dialog.

If it exists for closing the dialogue it should be a 'Close' button.

Cheers,
Joshua

Quoted 28 lines

Besides, let BinbDialog inherits the CrumbsDialog instead of gtk.Dialog

---
  bitbake/lib/bb/ui/crumbs/hig.py |    4 ++--
  1 files changed, 2 insertions(+), 2 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +2 -2
index c5bd27a..20585b7 100644
@@ -90,13 +90,13 @@ class CrumbsMessageDialog(CrumbsDialog):
  #
  # Brought-in-by Dialog
  #
-class BinbDialog(gtk.Dialog):
+class BinbDialog(CrumbsDialog):
      """
      A dialog widget to show "brought in by" info when a recipe/package is clicked.
      """
 
      def __init__(self, title, content, parent=None):
-        super(BinbDialog, self).__init__(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, None)
+        super(BinbDialog, self).__init__(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, ("OK", gtk.RESPONSE_OK))
 
          self.set_position(gtk.WIN_POS_MOUSE)
          self.set_resizable(False)
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#55 lore raw

Re: [PATCH 26/32] Hob: fix a bug that the image size is shown incorrectly in the image details page.

In reply to Shane Wang
Quoted 4 lines · Shane Wang

Originally, the image size shows the last item in the image tree view in the image details page. That is not correct. We need to show the size of the image which the user chooses.

Quoted 120 lines
---
  bitbake/lib/bb/ui/crumbs/hig.py              |    2 +-
  bitbake/lib/bb/ui/crumbs/imagedetailspage.py |   32 +++++++++++++++++++------
  2 files changed, 25 insertions(+), 9 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +1 -1
index 9b96d8d..c5bd27a 100644
@@ -1035,6 +1035,7 @@ class ImageSelectionDialog (CrumbsDialog):
          table.attach(open_button, 9, 10, 0, 1)
 
          self.image_table = HobViewTable(self.__columns__)
+        self.image_table.set_size_request(-1, 300)
          self.image_table.connect("toggled", self.toggled_cb)
          self.vbox.pack_start(self.image_table, expand=True, fill=True)
 
@@ -1052,7 +1053,6 @@ class ImageSelectionDialog (CrumbsDialog):
 
          model[path][columnid] = True
 
-
      def select_path_cb(self, action, parent, entry):
          dialog = gtk.FileChooserDialog("", parent,
                                         gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +24 -8
index 7f93db7..833c149 100755
@@ -74,6 +74,7 @@ class ImageDetailsPage (HobPage):
              self.hbox.pack_start(self.table, expand=True, fill=True, padding=15)
 
              colid = 0
+            self.line_widgets = {}
              if icon != None:
                  self.table.attach(icon, colid, colid + 2, 0, 1)
                  colid = colid + 2
@@ -81,20 +82,31 @@ class ImageDetailsPage (HobPage):
                  self.table.attach(widget, colid, 20, 0, 1)
              elif varlist != None and vallist != None:
                  for line in range(0, row):
-                    self.table.attach(self.text2label(varlist[line], vallist[line]), colid, 20, line, line + 1)
+                    self.line_widgets[varlist[line]] = self.text2label(varlist[line], vallist[line])
+                    self.table.attach(self.line_widgets[varlist[line]], colid, 20, line, line + 1)
 
              # pack the button on the right
              if button != None:
                  self.hbox.pack_end(button, expand=False, fill=False)
 
+        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 format_line(self, variable, value):
+            markup = "<span weight=\'bold\'>%s</span>" % variable
+            markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % 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"
-            markup = "<span weight=\'bold\'>%s</span>" % variable
-            markup += "<span weight=\'normal\' foreground=\'#1c1c1c\' font_desc=\'14px\'>%s</span>" % value
              label = gtk.Label()
              label.set_alignment(0.0, 0.5)
-            label.set_markup(markup)
+            label.set_markup(self.format_line(variable, value))
              return label
 
      def __init__(self, builder):
@@ -141,8 +153,6 @@ class ImageDetailsPage (HobPage):
          image_addr = self.builder.parameters.image_addr
          image_names = self.builder.parameters.image_names
          if build_succeeded:
-            image_addr = self.builder.parameters.image_addr
-            image_names = self.builder.parameters.image_names
              machine = self.builder.configuration.curr_mach
              base_image = self.builder.recipe_model.get_selected_image()
              layers = self.builder.configuration.layers
@@ -174,6 +184,7 @@ class ImageDetailsPage (HobPage):
          image_table = HobViewTable(self.__columns__)
          image_table.set_model(self.image_store)
          image_table.toggle_default()
+        image_size = self._size_to_string(os.stat(os.path.join(image_addr, image_names[0])).st_size)
          image_table.connect("toggled", self.toggled_cb)
          view_files_button = gtk.LinkButton("file://%s" % image_addr, "View files")
          self.box_group_area.pack_start(self.DetailBox(widget=image_table, button=view_files_button), expand=True, fill=True)
@@ -217,8 +228,9 @@ class ImageDetailsPage (HobPage):
              edit_packages_button.connect("clicked", self.edit_packages_button_clicked_cb)
          else: # get to this page from "My images"
              edit_packages_button = None
-        package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
-        self.box_group_area.pack_start(package_detail, expand=False, fill=False)
+        self.package_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=edit_packages_button)
+        self.box_group_area.pack_start(self.package_detail, expand=False, fill=False)
+
          if build_succeeded:
              buttonlist = ["Build new image", "Save as template", "Run image", "Deploy image"]
          else: # get to this page from "My images"
@@ -228,6 +240,9 @@ class ImageDetailsPage (HobPage):
 
          self.show_all()
 
+    def refresh_package_detail_box(self, image_size):
+        self.package_detail.update_line_widgets("Total image size: ", image_size)
+
      def toggled_cb(self, table, cell, path, columnid, tree):
          model = tree.get_model()
          if not model:
@@ -239,6 +254,7 @@ class ImageDetailsPage (HobPage):
              iter = model.iter_next(iter)
 
          model[path][columnid] = True
+        self.refresh_package_detail_box(model[path][1])
 
      def create_bottom_buttons(self, buttonlist):
          # Create the buttons at the bottom
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#51 lore raw

Re: [PATCH 25/32] Hob: Add an extra 50M space if zypper is selected

In reply to Shane Wang
Quoted 4 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

An workaround to judge if zypper is selected, we will add an extra 51200 KB to image size.

This sort of change sets alarms off, especially as we already have variables in the core metadata to affect image size (one of which is employed for this very reason) - are we not honouring those variables in hob?

Cheers,
Joshua

Quoted 19 lines
---
  bitbake/lib/bb/ui/crumbs/packageselectionpage.py |    2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +2 -0
index 5459743..89487c1 100755
@@ -180,6 +180,8 @@ class PackageSelectionPage (HobPage):
          image_overhead_factor = self.builder.configuration.image_overhead_factor
          image_rootfs_size = self.builder.configuration.image_rootfs_size
          image_extra_size = self.builder.configuration.image_extra_size
+        if "zypper" in self.builder.configuration.selected_packages:
+            image_extra_size += 51200
          base_size = image_overhead_factor * selected_packages_size
          image_total_size = max(base_size, image_rootfs_size) + image_extra_size
          image_total_size_str = self._size_to_string(image_total_size)
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#47 lore raw

Re: [PATCH 24/32] Hob(crumbs/hoblistmodel.py): Add mapping for rprovides and pkg

In reply to Shane Wang
Quoted 24 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

When checking the package's RDEPENDS information, we will see some case like A RDEPENDS virtual-b, and B RPROVIDES virtual-b, we need to reflect this relationship in packaging selection.

---
  bitbake/lib/bb/ui/crumbs/hoblistmodel.py |   18 +++++++++++++++---
  1 files changed, 15 insertions(+), 3 deletions(-)
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +1 -0
index e440979..e910944 100644
@@ -51,6 +51,7 @@ class PackageListModel(gtk.TreeStore):
          self.pkgs_size = 0
          self.pn_path = {}
          self.pkg_path = {}
+        self.rprov_pkg = {}
 
          gtk.TreeStore.__init__ (self,
                                  gobject.TYPE_STRING,

bitbake/lib/bb/ui/crumbs/hoblistmodel.py class PackageListModel(gtk.TreeStore): · line 78

Quoted 7 lines
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +4 -0
@@ -71,10 +72,18 @@ class PackageListModel(gtk.TreeStore):
      Returns the path in the model or None
      """
      def find_path_for_item(self, item_name):
+        pkg = item_name
+        if item_name == "virtual-locale-en-gb":
+            print("xdx: item name in pkg_path.keys: %s" % (item_name in self.pkg_path.keys()))
+            print("xdx: item name in rprov_pkg.keys: %s" % (item_name in self.rprov_pkg.keys()))

Was this left in on purpose?

Quoted 31 lines
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +10 -3
          if item_name not in self.pkg_path.keys():
-            return None
-        else:
-            return self.pkg_path[item_name]
+            if item_name not in self.rprov_pkg.keys():
+                return None
+            pkg = self.rprov_pkg[item_name]
+            if pkg not in self.pkg_path.keys():
+                return None
+
+        return self.pkg_path[pkg]
 
      def find_item_for_path(self, item_path):
          return self[item_path][self.COL_NAME]
@@ -137,6 +146,7 @@ class PackageListModel(gtk.TreeStore):
          self.pkgs_size = 0
          self.pn_path = {}
          self.pkg_path = {}
+        self.rprov_pkg = {}
 
          for pkginfo in pkginfolist:
              pn = pkginfo['PN']
@@ -160,6 +170,8 @@ class PackageListModel(gtk.TreeStore):
              rdep = pkginfo['RDEPENDS_%s' % pkg] if 'RDEPENDS_%s' % pkg in pkginfo.keys() else ""
              rrec = pkginfo['RRECOMMENDS_%s' % pkg] if 'RRECOMMENDS_%s' % pkg in pkginfo.keys() else ""
              rprov = pkginfo['RPROVIDES_%s' % pkg] if 'RPROVIDES_%s' % pkg in pkginfo.keys() else ""
+            for i in rprov.split():
+                self.rprov_pkg[i] = pkg
 
              if 'ALLOW_EMPTY_%s' % pkg in pkginfo.keys():
                  allow_empty = pkginfo['ALLOW_EMPTY_%s' % pkg]
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#3 lore raw

Re: [PATCH 02/32] Hob: avoid the image selection dialog to walk through all directories and its sub-directories, when users click "My images".

In reply to Shane Wang
Quoted 3 lines · Shane Wang

The current implementation of the image selection dialog walks through all directories and its sub-directories, when users click "My images" to choose a directory. If the directory is /, the system becomes slow. This patch is to avoid walking through all directories but the child directories only, given a directory.

Quoted 47 lines
---
  bitbake/lib/bb/ui/crumbs/hig.py |   12 ++++++++----
  1 files changed, 8 insertions(+), 4 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +8 -4
index 8f4f7cd..9aa6fdf 100644
@@ -582,6 +582,7 @@ class ImageSelectionDialog (gtk.Dialog):
 
          self.image_folder = image_folder
          self.image_types  = image_types
+        self.image_list = []
          self.image_names = []
 
          # create visual elements on the dialog
@@ -645,13 +646,17 @@ class ImageSelectionDialog (gtk.Dialog):
          dialog.destroy()
 
      def fill_image_store(self):
+        self.image_list = []
          self.image_store.clear()
          imageset = set()
          for root, dirs, files in os.walk(self.image_folder):
+            # ignore the sub directories
+            dirs[:] = []
              for f in files:
                  for image_type in self.image_types:
                      if f.endswith('.' + image_type):
                          imageset.add(f.rsplit('.' + image_type)[0])
+                        self.image_list.append(f)
 
          for image in imageset:
              self.image_store.set(self.image_store.append(), 0, image, 1, False)
@@ -665,9 +670,8 @@ class ImageSelectionDialog (gtk.Dialog):
              while iter:
                  path = self.image_store.get_path(iter)
                  if self.image_store[path][1]:
-                    for root, dirs, files in os.walk(self.image_folder):
-                        for f in files:
-                            if f.startswith(self.image_store[path][0] + '.'):
-                                self.image_names.append(f)
+                    for f in self.image_list:
+                        if f.startswith(self.image_store[path][0] + '.'):
+                            self.image_names.append(f)
                      break
                  iter = self.image_store.iter_next(iter)
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#18 lore raw

Re: [PATCH 07/32] Hob: use HobNotebook to enable a notebook in build details page

In reply to Shane Wang
Quoted 2 lines · Shane Wang

This patch is to use HobNotebook we defined to implement the notebook in the build details page.
And more the "build configuration" tab and the "issues" tab use more tree views which we implemented in runningbuild.py.

This should probably be two patches? I've raised concerns about the HobNoteBook in the patch introducing it.

Cheers,
Joshua

Quoted 251 lines
---
  bitbake/lib/bb/ui/crumbs/builddetailspage.py |   40 +++++++++++++--
  bitbake/lib/bb/ui/crumbs/builder.py          |    5 ++
  bitbake/lib/bb/ui/crumbs/hobwidget.py        |   14 +++++
  bitbake/lib/bb/ui/crumbs/runningbuild.py     |   69 ++++++++++++++++++++++++++
  4 files changed, 123 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/builddetailspage.py +35 -5
index 941f1e3..4a9f658 100755
@@ -22,8 +22,10 @@
 
  import gtk
  from bb.ui.crumbs.progressbar import HobProgressBar
-from bb.ui.crumbs.hobwidget import hic
+from bb.ui.crumbs.hobwidget import hic, HobNotebook
  from bb.ui.crumbs.runningbuild import RunningBuildTreeView
+from bb.ui.crumbs.runningbuild import BuildConfigurationTreeView
+from bb.ui.crumbs.runningbuild import BuildFailureTreeView
  from bb.ui.crumbs.hobpages import HobPage
 
  #
@@ -35,6 +37,8 @@ class BuildDetailsPage (HobPage):
      def __init__(self, builder):
          super(BuildDetailsPage, self).__init__(builder, "Building ...")
 
+        self.num_of_issues = 0
+
          # create visual elements
          self.create_visual_elements()
 
@@ -49,17 +53,43 @@ class BuildDetailsPage (HobPage):
          self.stop_button.connect("clicked", self.stop_button_clicked_cb)
          self.progress_box.pack_end(self.stop_button, expand=False, fill=False)
 
+        self.notebook = HobNotebook()
+        self.config_tv = BuildConfigurationTreeView()
+        self.config_model = self.builder.handler.build.model.config_model()
+        self.config_tv.set_model(self.config_model)
+        self.scrolled_view_config = gtk.ScrolledWindow ()
+        self.scrolled_view_config.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.scrolled_view_config.add(self.config_tv)
+        self.notebook.append_page(self.scrolled_view_config, gtk.Label("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_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.scrolled_view_failure.add(self.failure_tv)
+        self.notebook.append_page(self.scrolled_view_failure, gtk.Label("Issues"))
+
          self.build_tv = RunningBuildTreeView(readonly=True)
          self.build_tv.set_model(self.builder.handler.build.model)
-        self.scrolled_view = gtk.ScrolledWindow ()
-        self.scrolled_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        self.scrolled_view.add(self.build_tv)
+        self.scrolled_view_build = gtk.ScrolledWindow ()
+        self.scrolled_view_build.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.scrolled_view_build.add(self.build_tv)
+        self.notebook.append_page(self.scrolled_view_build, gtk.Label("Log"))
 
          self.button_box = gtk.HBox(False, 5)
          self.back_button = gtk.LinkButton("Go back to Image Configuration screen", "<<  Back to image configuration")
          self.back_button.connect("clicked", self.back_button_clicked_cb)
          self.button_box.pack_start(self.back_button, expand=False, fill=False)
 
+    def show_issues(self):
+        self.num_of_issues += 1
+        self.notebook.show_indicator_icon("Issues", self.num_of_issues)
+
+    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:
@@ -86,7 +116,7 @@ class BuildDetailsPage (HobPage):
          self.progress_bar.reset()
          self.vbox.pack_start(self.progress_box, expand=False, fill=False)
 
-        self.vbox.pack_start(self.scrolled_view, expand=True, fill=True)
+        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()
bitbake/lib/bb/ui/crumbs/builder.py +5 -0
index eb38819..819b79f 100755
@@ -214,6 +214,7 @@ class Builder(gtk.Window):
          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("task-started",       self.handler_task_started_cb)
+        self.handler.build.connect("log-error",          self.handler_build_failure_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)
@@ -528,6 +529,7 @@ class Builder(gtk.Window):
          elif self.current_step == self.PACKAGE_GENERATING:
              fraction = 0
          self.build_details_page.update_progress_bar("Build Started: ", fraction)
+        self.build_details_page.reset_issues()
 
      def handler_build_succeeded_cb(self, running_build):
          self.build_succeeded = True
@@ -586,6 +588,9 @@ class Builder(gtk.Window):
                  fraction = 0.2 + 0.8 * fraction
          self.build_details_page.update_progress_bar(title + ": ", fraction)
 
+    def handler_build_failure_cb(self, running_build):
+        self.build_details_page.show_issues()
+
      def destroy_window_cb(self, widget, event):
          lbl = "<b>Do you really want to exit the Hob image creator?</b>"
          dialog = CrumbsDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
bitbake/lib/bb/ui/crumbs/hobwidget.py +14 -0
index a2d99a2..c4a0513 100644
@@ -569,6 +569,20 @@ class HobNotebook(gtk.VBox):
 
          self.tb.show()
 
+    def show_indicator_icon(self, title, number):
+        for i in range(len(self.tabbar.children)):
+            if self.tabbar.children[i]["toggled_page"] == -1:
+                continue
+            if self.tabbar.children[i]["title"] == title:
+                self.tabbar.show_indicator_icon(i, number)
+
+    def hide_indicator_icon(self, title):
+        for i in range(len(self.tabbar.children)):
+            if self.tabbar.children[i]["toggled_page"] == -1:
+                continue
+            if self.tabbar.children[i]["title"] == title:
+                self.tabbar.hide_indicator_icon(i)
+
      def tab_switched_cb(self, widget, page):
          self.notebook.set_current_page(page)
 
bitbake/lib/bb/ui/crumbs/runningbuild.py +69 -0
index 718f692..ddac232 100644
@@ -25,6 +25,7 @@ import logging
  import time
  import urllib
  import urllib2
+import pango
  from bb.ui.crumbs.hobcolor import HobColors
 
  class RunningBuildModel (gtk.TreeStore):
@@ -40,6 +41,32 @@ class RunningBuildModel (gtk.TreeStore):
                                  gobject.TYPE_STRING,
                                  gobject.TYPE_INT)
 
+    def config_model_filter(self, model, it):
+        msg = model.get(it, self.COL_MESSAGE)[0]
+        if msg == None or type(msg) != str:
+            return False
+        if msg.startswith("\nOE Build Configuration:\n"):
+            return True
+        return False
+
+    def failure_model_filter(self, model, it):
+        color = model.get(it, self.COL_COLOR)[0]
+        if color == None:
+            return False
+        if color == HobColors.ERROR:
+            return True
+        return False
+
+    def config_model(self):
+        model = self.filter_new()
+        model.set_visible_func(self.config_model_filter)
+        return model
+
+    def failure_model(self):
+        model = self.filter_new()
+        model.set_visible_func(self.failure_model_filter)
+        return model
+
  class RunningBuild (gobject.GObject):
      __gsignals__ = {
            'build-started' : (gobject.SIGNAL_RUN_LAST,
@@ -57,6 +84,9 @@ class RunningBuild (gobject.GObject):
            'task-started'   : (gobject.SIGNAL_RUN_LAST,
                                gobject.TYPE_NONE,
                                (gobject.TYPE_PYOBJECT,)),
+          'log-error'      : (gobject.SIGNAL_RUN_LAST,
+                              gobject.TYPE_NONE,
+                              ()),
            }
      pids_to_task = {}
      tasks_to_iter = {}
@@ -107,6 +137,7 @@ class RunningBuild (gobject.GObject):
              if event.levelno>= logging.ERROR:
                  icon = "dialog-error"
                  color = HobColors.ERROR
+                self.emit("log-error")
              elif event.levelno>= logging.WARNING:
                  icon = "dialog-warning"
                  color = HobColors.WARNING
@@ -376,3 +407,41 @@ class RunningBuildTreeView (gtk.TreeView):
          message = model.get(it, model.COL_MESSAGE)[0]
 
          self._add_to_clipboard(message)
+
+
+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 message of the build.
+        self.message_renderer = gtk.CellRendererText ()
+        self.message_column = gtk.TreeViewColumn ("Message", self.message_renderer, text=RunningBuildModel.COL_MESSAGE, background=RunningBuildModel.COL_COLOR)
+        font = self.get_style().font_desc
+        font.set_size(pango.SCALE * 13)
+        self.message_renderer.set_property('font-desc', font)
+        self.append_column (self.message_column)
+
+
+class BuildFailureTreeView(gtk.TreeView):
+
+    def __init__ (self):
+        gtk.TreeView.__init__(self)
+        self.set_rules_hint(False)
+        self.set_headers_visible(False)
+        self.get_selection().set_mode(gtk.SELECTION_SINGLE)
+
+        # The icon that indicates whether we're building or failed.
+        renderer = gtk.CellRendererPixbuf ()
+        col = gtk.TreeViewColumn ("Status", renderer)
+        col.add_attribute (renderer, "icon-name", RunningBuildModel.COL_ICON)
+        self.append_column (col)
+
+        # The message of the build.
+        self.message_renderer = gtk.CellRendererText ()
+        self.message_column = gtk.TreeViewColumn ("Message", self.message_renderer, text=RunningBuildModel.COL_MESSAGE, background=RunningBuildModel.COL_COLOR)
+        self.append_column (self.message_column)
Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#52 lore raw

Re: [PATCH 25/32] Hob: Add an extra 50M space if zypper is selected

In reply to Joshua Lock
Quoted 10 lines · Joshua Lock
Quoted 4 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

An workaround to judge if zypper is selected, we will add an extra 51200 KB to image size.

This sort of change sets alarms off, especially as we already have variables in the core metadata to affect image size (one of which is employed for this very reason) - are we not honouring those variables in hob?

Thanks Josh for the suggestion.

The situation we are facing is that, Hob could only query the variable values from bb.configuration.data, which doesn't include the image_types.bbclass and rootfs_rpm.bbclass. Therefore it is not able to get those variable's updated value in these classes.

Thanks,
Dongxiao

Quoted 23 lines

Cheers,
Joshua

Quoted 19 lines
---
  bitbake/lib/bb/ui/crumbs/packageselectionpage.py |    2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +2 -0
index 5459743..89487c1 100755
@@ -180,6 +180,8 @@ class PackageSelectionPage (HobPage):
          image_overhead_factor = self.builder.configuration.image_overhead_factor
          image_rootfs_size = self.builder.configuration.image_rootfs_size
          image_extra_size = self.builder.configuration.image_extra_size
+        if "zypper" in self.builder.configuration.selected_packages:
+            image_extra_size += 51200
          base_size = image_overhead_factor * selected_packages_size
          image_total_size = max(base_size, image_rootfs_size) + image_extra_size
          image_total_size_str = self._size_to_string(image_total_size)
#48 lore raw

Re: [PATCH 24/32] Hob(crumbs/hoblistmodel.py): Add mapping for rprovides and pkg

In reply to Joshua Lock
Quoted 23 lines · Joshua Lock
Quoted 21 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

When checking the package's RDEPENDS information, we will see some case like A RDEPENDS virtual-b, and B RPROVIDES virtual-b, we need to reflect this relationship in packaging selection.

---
  bitbake/lib/bb/ui/crumbs/hoblistmodel.py |   18 +++++++++++++++---
  1 files changed, 15 insertions(+), 3 deletions(-)
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +1 -0
index e440979..e910944 100644
@@ -51,6 +51,7 @@ class PackageListModel(gtk.TreeStore):
          self.pkgs_size = 0
          self.pn_path = {}
          self.pkg_path = {}
+        self.rprov_pkg = {}
 
Quoted 12 lines

bitbake/lib/bb/ui/crumbs/hoblistmodel.py class PackageListModel(gtk.TreeStore): · line 78

Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +4 -0
          gtk.TreeStore.__init__ (self,
                                  gobject.TYPE_STRING,
@@ -71,10 +72,18 @@ class PackageListModel(gtk.TreeStore):
      Returns the path in the model or None
      """
      def find_path_for_item(self, item_name):
+        pkg = item_name
+        if item_name == "virtual-locale-en-gb":
+            print("xdx: item name in pkg_path.keys: %s" % (item_name in self.pkg_path.keys()))
+            print("xdx: item name in rprov_pkg.keys: %s" % (item_name in self.rprov_pkg.keys()))

Was this left in on purpose?

Oops... I should check it carefully.

Thanks,
Dongxiao

Quoted 33 lines
Quoted 32 lines
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +10 -3
          if item_name not in self.pkg_path.keys():
-            return None
-        else:
-            return self.pkg_path[item_name]
+            if item_name not in self.rprov_pkg.keys():
+                return None
+            pkg = self.rprov_pkg[item_name]
+            if pkg not in self.pkg_path.keys():
+                return None
+
+        return self.pkg_path[pkg]
 
      def find_item_for_path(self, item_path):
          return self[item_path][self.COL_NAME]
@@ -137,6 +146,7 @@ class PackageListModel(gtk.TreeStore):
          self.pkgs_size = 0
          self.pn_path = {}
          self.pkg_path = {}
+        self.rprov_pkg = {}
 
          for pkginfo in pkginfolist:
              pn = pkginfo['PN']
@@ -160,6 +170,8 @@ class PackageListModel(gtk.TreeStore):
              rdep = pkginfo['RDEPENDS_%s' % pkg] if 'RDEPENDS_%s' % pkg in pkginfo.keys() else ""
              rrec = pkginfo['RRECOMMENDS_%s' % pkg] if 'RRECOMMENDS_%s' % pkg in pkginfo.keys() else ""
              rprov = pkginfo['RPROVIDES_%s' % pkg] if 'RPROVIDES_%s' % pkg in pkginfo.keys() else ""
+            for i in rprov.split():
+                self.rprov_pkg[i] = pkg
 
              if 'ALLOW_EMPTY_%s' % pkg in pkginfo.keys():
                  allow_empty = pkginfo['ALLOW_EMPTY_%s' % pkg]
#58 lore raw

Re: [PATCH 27/32] Hob: add "OK" button to "BinbDialog"

In reply to Joshua Lock
Quoted 8 lines · Joshua Lock
Quoted 5 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

For certain distributions, like FC16, it doesn't have close button in sub-windows or dialogs. Therefore we need to add an "OK" button to "BinbDialog" to close the dialog.

If it exists for closing the dialogue it should be a 'Close' button.

Thanks, it makes sense to use "close" button.

Thanks,
Dongxiao

Quoted 33 lines

Cheers,
Joshua

Quoted 28 lines

Besides, let BinbDialog inherits the CrumbsDialog instead of gtk.Dialog

---
  bitbake/lib/bb/ui/crumbs/hig.py |    4 ++--
  1 files changed, 2 insertions(+), 2 deletions(-)
bitbake/lib/bb/ui/crumbs/hig.py +2 -2
index c5bd27a..20585b7 100644
@@ -90,13 +90,13 @@ class CrumbsMessageDialog(CrumbsDialog):
  #
  # Brought-in-by Dialog
  #
-class BinbDialog(gtk.Dialog):
+class BinbDialog(CrumbsDialog):
      """
      A dialog widget to show "brought in by" info when a recipe/package is clicked.
      """
 
      def __init__(self, title, content, parent=None):
-        super(BinbDialog, self).__init__(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, None)
+        super(BinbDialog, self).__init__(title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, ("OK", gtk.RESPONSE_OK))
 
          self.set_position(gtk.WIN_POS_MOUSE)
          self.set_resizable(False)
#71 lore raw

Re: [PATCH 32/32] Hob: Disable the handling of "NoProvider" event

In reply to Shane Wang
Quoted 8 lines · Shane Wang

From: Dongxiao Xu <[email protected]>

Currently for non-x86 architecture, there are un-resolved dependency issue when generate universe dependency tree. Therefore disable the handling of "NoProvider" event in Hob to enable the build for non-x86 architectures. After we resolved the dependency for universe, we still need to handle this event in Hob.

Quoted 4 lines
---
 bitbake/lib/bb/ui/crumbs/hobeventhandler.py |   37 ++++++++++++++------------
 1 files changed, 20 insertions(+), 17 deletions(-)

Shouldn't you be using world and not universe for this?

I suspect world shouldn't show the NoProvider issues?

Cheers,

Richard

#78 lore raw
In reply to Shane Wang
Quoted 59 lines · Shane Wang

The following patches are going to fix the following problems:

* Enable HobNotebook to make notebook more like the design video;
* Improve and enhance the GUI;
* Rebase the patches Josh has sent out before with the title "Hob tweaks";
* Address some tricky issues we found in the bitbake;
* Revise Hob according to the comments on the previous patch set;
* Fix some bugs we found when testing Hob;
* and some temporary walkarounds we have to find a way to solve in Hob or in the bitbake later.

The following changes since commit 927bec5f72230be4f2452d9ef5a747b2c00cb781:

bitbake.conf: Create a new filter variable BB_HASHCONFIG_WHITELIST (2012-02-27 20:10:41 +0000)

are available in the git repository at:
git://git.pokylinux.org/poky-contrib shane/hob2-v0.68
http://git.pokylinux.org/cgit.cgi/poky-contrib/log/?h=shane/hob2-v0.68

Dongxiao Xu (10):
command.py: remove the resolve parameter in generateTargetsTree cooker.py: Fix a bug due to variable name
cooker: fix calculating of depends and rdepends Hob(crumbs/hoblistmodel.py): Fix recipe's populate() function Hob(crumbs/hoblistmodel.py): Add mapping for rprovides and pkg
Hob: Add an extra 50M space if zypper is selected
Hob: add "OK" button to "BinbDialog"
Hob: Fix pressing "stop" build
runqueue.py: initialize rqexe at RunQueue's init function
Hob: Disable the handling of "NoProvider" event

Shane Wang (22):
Hob: make HobViewTable more general in hob and make the image
selection dialog and the image details page reuse it.
Hob: avoid the image selection dialog to walk through all directories
and its sub-directories, when users click "My images".
Hob: cleanup those class methods in HobWidget
Hob: fixed the issue in the brought-in-by dialog.
Hob: include hddimg and iso into image types.
Hob: implement a self-defined notebook visual component for Hob
Hob: use HobNotebook to enable a notebook in build details page
Hob: image configuration page doesn't need dialogs any more
Hob: fix a bug in builder.configuration.curr_mach
Hob: add ignore_all_errors to avoid showing error dialog multiple
times
Hob: make the image configuration page not to flash the progress bar
Hob: enable indicators on the "Included" tab in the recipe selection
page and the package selection page
crumbs: Factor common dialogue configuration out crumbs/builder: use the name Hob consistently
crumbs: move towards more standard dialogue spacing
crumbs: fix button order in several dialogues
hig: try to avoid setting explicit dialogue sizes crumbs/hig: tweak UI and layout of LayerSelectionDialog Hob(crumbs/builder.py): remove the code commented out in the
builder.py
Hob: fix a bug that the image size is shown incorrectly in the image
details page.
Hob: allow users to setup the proxy Hob(crumbs/builder.py): adjust the main window's position and ignore

Quoted 1 line
    the case lower than 1024x768.

I also just realised some of these patches were authored by Joshua. Please ensure there is a:

From: XXX <xxx>

at the head of such patches so the author information gets correctly recorded. Unfortunately I realised to late with this push to be able to correct it :(

Cheers,

Richard

#80 lore raw
In reply to Shane Wang
Quoted 59 lines · Shane Wang

The following patches are going to fix the following problems:

* Enable HobNotebook to make notebook more like the design video;
* Improve and enhance the GUI;
* Rebase the patches Josh has sent out before with the title "Hob tweaks";
* Address some tricky issues we found in the bitbake;
* Revise Hob according to the comments on the previous patch set;
* Fix some bugs we found when testing Hob;
* and some temporary walkarounds we have to find a way to solve in Hob or in the bitbake later.

The following changes since commit 927bec5f72230be4f2452d9ef5a747b2c00cb781:

bitbake.conf: Create a new filter variable BB_HASHCONFIG_WHITELIST (2012-02-27 20:10:41 +0000)

are available in the git repository at:
git://git.pokylinux.org/poky-contrib shane/hob2-v0.68
http://git.pokylinux.org/cgit.cgi/poky-contrib/log/?h=shane/hob2-v0.68

Dongxiao Xu (10):
command.py: remove the resolve parameter in generateTargetsTree cooker.py: Fix a bug due to variable name
cooker: fix calculating of depends and rdepends Hob(crumbs/hoblistmodel.py): Fix recipe's populate() function Hob(crumbs/hoblistmodel.py): Add mapping for rprovides and pkg **** Hob: Add an extra 50M space if zypper is selected **** Hob: add "OK" button to "BinbDialog"
Hob: Fix pressing "stop" build
runqueue.py: initialize rqexe at RunQueue's init function **** Hob: Disable the handling of "NoProvider" event

Shane Wang (22):
Hob: make HobViewTable more general in hob and make the image
selection dialog and the image details page reuse it.
Hob: avoid the image selection dialog to walk through all directories
and its sub-directories, when users click "My images".
Hob: cleanup those class methods in HobWidget
Hob: fixed the issue in the brought-in-by dialog.
Hob: include hddimg and iso into image types.
**** Hob: implement a self-defined notebook visual component for Hob **** Hob: use HobNotebook to enable a notebook in build details page
Hob: image configuration page doesn't need dialogs any more
Hob: fix a bug in builder.configuration.curr_mach
**** Hob: add ignore_all_errors to avoid showing error dialog multiple
times
Hob: make the image configuration page not to flash the progress bar
Hob: enable indicators on the "Included" tab in the recipe selection
page and the package selection page
crumbs: Factor common dialogue configuration out crumbs/builder: use the name Hob consistently
crumbs: move towards more standard dialogue spacing
crumbs: fix button order in several dialogues
hig: try to avoid setting explicit dialogue sizes crumbs/hig: tweak UI and layout of LayerSelectionDialog Hob(crumbs/builder.py): remove the code commented out in the
builder.py
Hob: fix a bug that the image size is shown incorrectly in the image
details page.
**** Hob: allow users to setup the proxy Hob(crumbs/builder.py): adjust the main window's position and ignore

Quoted 1 line
    the case lower than 1024x768.

I pulled the above except where marked with "****". In those cases there is feedback on the patches which needs discussion.

I removed one piece of debug Joshua noticed and had to manually tweak one patch to get it to apply due to other patches not being applied. I'll expect an new pull request for the remaining patches.

Cheers,

Richard

#53 lore raw

Re: [PATCH 25/32] Hob: Add an extra 50M space if zypper is selected

In reply to Xu, Dongxiao
Quoted 12 lines · Dongxiao
Quoted 10 lines · Joshua Lock
Quoted 4 lines · Shane Wang

From: Dongxiao Xu<[email protected]>

An workaround to judge if zypper is selected, we will add an extra 51200 KB to image size.

This sort of change sets alarms off, especially as we already have variables in the core metadata to affect image size (one of which is employed for this very reason) - are we not honouring those variables in hob?

Quoted 6 lines

Thanks Josh for the suggestion.

The situation we are facing is that, Hob could only query the variable values from bb.configuration.data, which doesn't include the image_types.bbclass and rootfs_rpm.bbclass. Therefore it is not able to get those variable's updated value in these classes.

I understand the problem, that's why the old hob forced a pre-conf which included INHERIT += "image_types" - not the cleanest solution but arguably better than hard coding values as at least this way we respect user settings.

Cheers,
Joshua

Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#72 lore raw

Re: [PATCH 32/32] Hob: Disable the handling of "NoProvider" event

In reply to Richard Purdie
Quoted 9 lines · Richard Purdie
Quoted 8 lines · Shane Wang

From: Dongxiao Xu <[email protected]>

Currently for non-x86 architecture, there are un-resolved dependency issue when generate universe dependency tree. Therefore disable the handling of "NoProvider" event in Hob to enable the build for non-x86 architectures. After we resolved the dependency for universe, we still need to handle this event in Hob.

Quoted 8 lines
Quoted 4 lines
---
 bitbake/lib/bb/ui/crumbs/hobeventhandler.py |   37 ++++++++++++++------------
 1 files changed, 20 insertions(+), 17 deletions(-)

Shouldn't you be using world and not universe for this?

I suspect world shouldn't show the NoProvider issues?

Unluckily world also has the same issue, since core-image-minimal-initramfs and initramfs-live-install recipes are all contained in world area.

Thanks,
Dongxiao

Quoted 10 lines

Cheers,

Richard

_______________________________________________
bitbake-devel mailing list
[email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/bitbake-devel

#79 lore raw
In reply to Richard Purdie

Josh, I am sorry for missing to add From: XXX<xxx> in your six patches. I originally think "Signed-off-by: Josh" is enough.

Because I have some cleanups to remove class methods for HobWidget for clean Object Oriented design, which changed the code a lot. So, some of my patches jumped the queue to save merging and rebasing efforts.

Sorry for that.
--
Shane

Richard Purdie wrote on 2012-03-01:

Quoted 13 lines

I also just realised some of these patches were authored by Joshua. Please ensure there is a:

From: XXX <xxx>

at the head of such patches so the author information gets correctly recorded. Unfortunately I realised to late with this push to be able to correct it :(

Cheers,

Richard

#76 lore raw
In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 7 lines

One thing I did notice whilst reviewing this series is that there's a lot of this anti-pattern in the hob 2 code:
for i in range(len(mylist)):
rather than:
for item in list:

Can we make an effort to tidy those up?

I will check those later. I went through them quickly. Some of them are because the code refers to the index i.

Otherwise, we would have the code.
i = 0
for item in list:
XXXXX
XXX = i
i += 1

which also looks not perfect. But anyway, I will check all of them later and send another patch for improvement. If there is no reference to the index, I will replace with your style.

--
Shane

Quoted 3 lines

Cheers,
Joshua

#15 lore raw

Re: [PATCH 06/32] Hob: implement a self-defined notebook visual component for Hob

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 10 lines · Shane Wang
Quoted 1 line

In recipe selection page, package selection page, and build details page,

etc, there is a notebook component which is not gtk.Notebook in the design video.

Quoted 1 line

We implement the visual component with a drawing area, and use it to

replace the old notebook in recipe selection page and package selection page.

Quoted 1 line
Quoted 8 lines
Quoted 2 lines

Code style comments below.

More importantly, have we made sure we can't use the stock notebook before we've implemented our own? The commit log tells me that we aren't using gtk.Notebook but doesn't tell me why?

1) General speaking, gtk.Notebook doesn't look like the design Belen worked out.
2) And we all agree Belen's design looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward. But technically, gtk.Notebook can't implement that. As far as we know, it can't.

3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us. Regarding those, we give up gtk.Notebook and use our own.

Quoted 8 lines

The implemented notebook is a reasonable start but it needs a lot of polish before I'd want to see it shipped.
i.e. the green flashed border around the selected tabs is strange, the drawing looks a little jaggy, especially the orange circle (not a graphics guy so I don't know the right term) and I'm pretty certain the number in the circle isn't centred. Finally (for now) once I get to three digits the numbers don't fit in the circle.

I agree we also have some to improve our Notebook, say, the border and the circle. If there is a jaggy, we can make it a rectangle instead of circle. But to be frank, I don't think gtk.Notebook looks better.

Quoted 10 lines

I think the rationale would be useful as a comment in the class file too.

Cheers,
Joshua

+ # check which tab be clicked
Why don't we just iterate the list here?
for child in self.children:
if child["x"] < x and etc.

Because we have
self.current_child = i

Or we can do self.current_child = child (to an object)? Do you like this more?

--
Shane

#74 lore raw

Re: [PATCH 01/32] Hob: make HobViewTable more general in hob and make the image selection dialog and the image details page reuse it.

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 10 lines

bitbake/lib/bb/ui/crumbs/hobwidget.py class HobViewTable (gtk.VBox): · line 635

Quoted 7 lines

for i in range(len(columns)):
col = gtk.TreeViewColumn(columns[i]['col_name']) col.set_clickable(True) col.set_resizable(True) col.set_sort_column_id(columns[i]['col_id'])

bitbake/lib/bb/ui/crumbs/hobwidget.py +0 -2
-            col.set_min_width(columns[i]['col_min'])
-            col.set_max_width(columns[i]['col_max'])

There are a few calls to columns[i].keys() below, I'd recommend making the call once per iteration and assigning it to a variable.

OK, will address that later in a separate patch.

Quoted 8 lines

Usually in Python we'd just do a boolean test on the object like:

if widget:
row = 1
elif varlist and vallist:
row = len(varlist)

If it is the style, I can change that some time later.
But I have to say, using "if widget:" is not save enough.
I have even used "if var:" to test "if var != None" but unfortunately var != None but = 0, since var is an integer in that case. Python is so free without type checking than C++.

Quoted 3 lines
Quoted 1 line

hbox = gtk.HBox(False, 5)

*Beep* 5 for padding? :-)

OK, 6

--
Shane

#7 lore raw

Re: [PATCH 04/32] Hob: fixed the issue in the brought-in-by dialog.

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 13 lines · Shane Wang
Quoted 1 line

When typing any thing in the search entry, the brough-in-by dialog will be

shown. That is because we call back "selection-changed" signal to pop up the dialog, which is not correct.

Quoted 4 lines

This patch is to fix the problem by using "row-activated" signal.

I point out some incorrect padding below but other than that:

OK, Got it. May I know why padding=6 only conforms to hig?

--
Shane

#26 lore raw

Re: [PATCH 10/32] Hob: add ignore_all_errors to avoid showing error dialog multiple times

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 10 lines · Shane Wang
Quoted 1 line

when parsing recipes, if there are some errors, the error dialog will be

shown again and again for each error, add "Ignore All" to allow users to ignore those errors.

I'm not so sure about this. I don't think ignoring all parse errors is the right thing, collecting them up into one dialogue seems like a better first step.

OK, UX improvement.

Quoted 3 lines

What if I add some layers which introduce different parsing errors after I've clicked 'Ignore All' once?

"Ignore All" can't be reset. It only takes effect on the parsing this time.
That is: if you change layers which causes different parsing errors, and you ignore all.
Next time, if you change some layers which also causes some parsing errors, the dialog will also show until you click "ignore all".

--
Shane

Quoted 3 lines

Cheers,
Joshua

#59 lore raw

Re: [PATCH 27/32] Hob: add "OK" button to "BinbDialog"

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 12 lines · Shane Wang
Quoted 5 lines

From: Dongxiao Xu<[email protected]>

For certain distributions, like FC16, it doesn't have close button in sub-windows or dialogs. Therefore we need to add an "OK" button to "BinbDialog" to close the dialog.

If it exists for closing the dialogue it should be a 'Close' button.

Cheers,
Joshua

Agree.

--
Shane

#62 lore raw

Re: [PATCH 28/32] Hob: allow users to setup the proxy

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 6 lines · Shane Wang
Quoted 1 line

This patch is to set os.environ to allow users to set the environment

variables for http_proxy, https_proxy and ftp_proxy.

I think this needs more work, I have a text entry with an attached button that spawns a file chooser. What file would I choose here?

Josh, I don't understand why this is related to a file chooser.

Quoted 2 lines

What about if my http, ftp and socks proxy are different?

Yes, the patch doesn't work for this case. I admit the proxy patch needs more work. Again, this patch doesn't support git, either.
The initial requirement is from Saul and from build appliance for users behind a firewall to use proxy. For what you mentioned to set up different proxies, it is easy to fix.
But for git, I also need to investigate, do you have more hints?

--
Shane

Quoted 4 lines

Cheers,
Joshua

#49 lore raw

Re: [PATCH 24/32] Hob(crumbs/hoblistmodel.py): Add mapping for rprovides and pkg

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 35 lines · Shane Wang
Quoted 27 lines

From: Dongxiao Xu<[email protected]>

When checking the package's RDEPENDS information, we will see some case like A RDEPENDS virtual-b, and B RPROVIDES virtual-b, we need to reflect this relationship in packaging selection.

---
  bitbake/lib/bb/ui/crumbs/hoblistmodel.py |   18 +++++++++++++++---
  1 files changed, 15 insertions(+), 3 deletions(-)
(quoted diff) +0 -0

b/bitbake/lib/bb/ui/crumbs/hoblistmodel.py index e440979..e910944 100644 --- a/bitbake/lib/bb/ui/crumbs/hoblistmodel.py +++ b/bitbake/lib/bb/ui/crumbs/hoblistmodel.py @@ -51,6 +51,7 @@ class PackageListModel(gtk.TreeStore):

          self.pkgs_size = 0
          self.pn_path = {}
          self.pkg_path = {}
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +2 -0
+        self.rprov_pkg = {}
 
          gtk.TreeStore.__init__ (self,
                                  gobject.TYPE_STRING,
@@ -71,10 +72,18 @@ class PackageListModel(gtk.TreeStore):
      Returns the path in the model or None
      """
      def find_path_for_item(self, item_name):
+        pkg = item_name +        if item_name ==
Quoted 3 lines

"virtual-locale-en-gb": + print("xdx: item name in
pkg_path.keys: %s" % (item_name in self.pkg_path.keys())) + print("xdx: item name in rprov_pkg.keys: %s" %

(item_name in self.rprov_pkg.keys()))

Quoted 2 lines

Was this left in on purpose?

Dongxiao, I guess you forgot to remove debug information;-)

--
Shane

#19 lore raw

Re: [PATCH 07/32] Hob: use HobNotebook to enable a notebook in build details page

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-01:

Quoted 13 lines · Shane Wang
Quoted 3 lines

This patch is to use HobNotebook we defined to implement the notebook in the build details page. And more the "build configuration" tab and the "issues" tab use more tree

views which we implemented in runningbuild.py.

This should probably be two patches? I've raised concerns about the HobNoteBook in the patch introducing it.

Cheers,
Joshua

We should evaluate it.

--
Shane

#8 lore raw

Re: [PATCH 04/32] Hob: fixed the issue in the brought-in-by dialog.

In reply to Wang, Shane
Quoted 7 lines · Shane

Joshua Lock wrote on 2012-03-01:

Quoted 6 lines · Shane Wang
Quoted 1 line

When typing any thing in the search entry, the brough-in-by dialog will be

shown. That is because we call back "selection-changed" signal to pop up the dialog, which is not correct.

Quoted 2 lines

This patch is to fix the problem by using "row-activated" signal.

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

I point out some incorrect padding below but other than that:

OK, Got it. May I know why padding=6 only conforms to hig?

Of course, but you should really read it though rather than asking me to quote it for you.

"As a basic rule of thumb, leave space between user interface components in increments of 6 pixels, going up as the relationship between related elements becomes more distant."

http://developer.gnome.org/hig-book/3.0/design-window.html.en#window-layout-spacing

I've volunteered to work through Hob and make it more HIG conformant but the HIG for a platform really is a document you should at least be aware of when developing for it.

Cheers,
Joshua

Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#16 lore raw

Re: [PATCH 06/32] Hob: implement a self-defined notebook visual component for Hob

In reply to Wang, Shane
Quoted 20 lines · Shane

Joshua Lock wrote on 2012-03-01:

Quoted 10 lines · Shane Wang
Quoted 1 line

In recipe selection page, package selection page, and build details page,

etc, there is a notebook component which is not gtk.Notebook in the design video.

Quoted 1 line

We implement the visual component with a drawing area, and use it to

replace the old notebook in recipe selection page and package selection page.

Quoted 1 line
Quoted 8 lines
Quoted 2 lines

Code style comments below.

More importantly, have we made sure we can't use the stock notebook before we've implemented our own? The commit log tells me that we aren't using gtk.Notebook but doesn't tell me why?

Quoted 6 lines

1) General speaking, gtk.Notebook doesn't look like the design Belen worked out.
2) And we all agree Belen's design looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward. But technically, gtk.Notebook can't implement that. As far as we know, it can't.

3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us. Regarding those, we give up gtk.Notebook and use our own.

This all seems reasonable but is the sort of information I'd expect to see documented in the code and the commit logs. :-)

Quoted 11 lines
Quoted 8 lines

The implemented notebook is a reasonable start but it needs a lot of polish before I'd want to see it shipped.
i.e. the green flashed border around the selected tabs is strange, the drawing looks a little jaggy, especially the orange circle (not a graphics guy so I don't know the right term) and I'm pretty certain the number in the circle isn't centred. Finally (for now) once I get to three digits the numbers don't fit in the circle.

I agree we also have some to improve our Notebook, say, the border and the circle. If there is a jaggy, we can make it a rectangle instead of circle. But to be frank, I don't think gtk.Notebook looks better.

That's fine, and I'm not disagreeing - I'm just trying to follow what's happening and by reading the logs and code as is I don't see any of the rationale.

Cheers,

Joshua

Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#63 lore raw

Re: [PATCH 28/32] Hob: allow users to setup the proxy

In reply to Wang, Shane
Quoted 9 lines · Shane

Joshua Lock wrote on 2012-03-01:

Quoted 6 lines · Shane Wang
Quoted 1 line

This patch is to set os.environ to allow users to set the environment

variables for http_proxy, https_proxy and ftp_proxy.

I think this needs more work, I have a text entry with an attached button that spawns a file chooser. What file would I choose here?

Josh, I don't understand why this is related to a file chooser.

That's pretty much what I'm asking you. When I run the Hob from your shane/hob2-v0.68 branch I get the attached Settings->Build Environment dialogue.

Next to the entry for the proxy information there's a file chooser - I don't understand what it's for?

From looking at the code I'm assuming it's not supposed to be there and is a by-product of the way you've called gen_entry_widget()

Cheers,
Joshua

Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#77 lore raw
In reply to Wang, Shane

Shane,

As I understand it, if you need keep track of indices as you go through a list, then enumerate() is the python way to do it.
http://docs.python.org/library/functions.html#enumerate

So you would have:

for i, item in enumerate(list):
... etc

Best regards,

Oren

Quoted 33 lines · Shane

Joshua Lock wrote on 2012-03-01:

Quoted 7 lines

One thing I did notice whilst reviewing this series is that there's a lot of this anti-pattern in the hob 2 code:
      for i in range(len(mylist)):
rather than:
      for item in list:

Can we make an effort to tidy those up?

I will check those later. I went through them quickly. Some of them are because the code refers to the index i.

Otherwise, we would have the code.
i = 0
for item in list:
 XXXXX
 XXX = i
 i += 1

which also looks not perfect. But anyway, I will check all of them later and send another patch for improvement. If there is no reference to the index, I will replace with your style.

--
Shane

Quoted 3 lines

Cheers,
Joshua

_______________________________________________
bitbake-devel mailing list
[email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/bitbake-devel

#9 lore raw

Re: [PATCH 04/32] Hob: fixed the issue in the brought-in-by dialog.

In reply to Joshua Lock

Joshua Lock wrote on 2012-03-02:

Quoted 24 lines · Shane
Quoted 3 lines

Joshua Lock wrote on 2012-03-01:

Quoted 2 lines · Shane Wang
Quoted 1 line

When typing any thing in the search entry, the brough-in-by dialog will

be

Quoted 11 lines
Quoted 9 lines

shown. That is because we call back "selection-changed" signal to pop up the dialog, which is not correct.

Quoted 4 lines

This patch is to fix the problem by using "row-activated" signal.

I point out some incorrect padding below but other than that:

OK, Got it. May I know why padding=6 only conforms to hig?

Of course, but you should really read it though rather than asking me to quote it for you.

"As a basic rule of thumb, leave space between user interface components in increments of 6 pixels, going up as the relationship between related elements becomes more distant."

Quoted 6 lines

http://developer.gnome.org/hig-book/3.0/design-window.html.en#window-la
yout-spacing

I've volunteered to work through Hob and make it more HIG conformant but the HIG for a platform really is a document you should at least be aware of when developing for it.

Thank you for pointing out why 6, and volunteering to make the spacing 6. We all just follow and are going to follow the design in the video. And as well, make the build process go correctly and UI be friendly.

Again, there is no requirement to follow Hig at the beginning. There are a lot of hig specs
http://en.wikipedia.org/wiki/Human_interface_guidelines#Examples_of_HIG.

But regarding you raise the Gnome hig issue, I agree with you to make them conformant.

--
Shane

Quoted 3 lines

Cheers,
Joshua

#10 lore raw

Re: [PATCH 04/32] Hob: fixed the issue in the brought-in-by dialog.

Quoted 29 lines · Shane

Joshua Lock wrote on 2012-03-02:

Quoted 27 lines · Shane
Quoted 3 lines

Joshua Lock wrote on 2012-03-01:

Quoted 2 lines · Shane Wang
Quoted 1 line

When typing any thing in the search entry, the brough-in-by dialog will

be

Quoted 11 lines
Quoted 9 lines

shown. That is because we call back "selection-changed" signal to pop up the dialog, which is not correct.

Quoted 4 lines

This patch is to fix the problem by using "row-activated" signal.

I point out some incorrect padding below but other than that:

OK, Got it. May I know why padding=6 only conforms to hig?

Of course, but you should really read it though rather than asking me to quote it for you.

"As a basic rule of thumb, leave space between user interface components in increments of 6 pixels, going up as the relationship between related elements becomes more distant."

http://developer.gnome.org/hig-book/3.0/design-window.html.en#window-la
yout-spacing

Quoted 7 lines
Quoted 3 lines

I've volunteered to work through Hob and make it more HIG conformant but the HIG for a platform really is a document you should at least be aware of when developing for it.

Thank you for pointing out why 6, and volunteering to make the spacing 6. We all just follow and are going to follow the design in the video. And as well, make the build process go correctly and UI be friendly.

Understood.

Quoted 4 lines

Again, there is no requirement to follow Hig at the beginning. There are a lot of hig specs
http://en.wikipedia.org/wiki/Human_interface_guidelines#Examples_of_HIG.

But regarding you raise the Gnome hig issue, I agree with you to make them conformant.

Great.

Joshua

Signature · 3 lines
Joshua Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre