summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb
diff options
context:
space:
mode:
authorCristiana Voicu <cristiana.voicu@intel.com>2013-03-20 14:35:06 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-03-22 16:54:39 +0000
commit860f826753cab81b1d1d9b2ecafa630a96676d9e (patch)
tree6f5da66864b05ded2f96c76ce9299a3386fa9c1f /bitbake/lib/bb
parentab7d8bd172f61e14266a020bd6633d33d79e3d8f (diff)
downloadpoky-860f826753cab81b1d1d9b2ecafa630a96676d9e.tar.gz
bitbake: hob: implementation of search functionality in Hob
Implemented the search functionality for recipes and packages using filters on the listmodel. I have used the design which can be found in bugzilla. [YOCTO #3529] (Bitbake rev: b77166ad7b8571895f73a84f7789d93fbd4f6d04) Signed-off-by: Cristiana Voicu <cristiana.voicu@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb')
-rw-r--r--bitbake/lib/bb/ui/crumbs/hoblistmodel.py118
-rw-r--r--bitbake/lib/bb/ui/crumbs/hobwidget.py75
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/packageselectionpage.py57
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/recipeselectionpage.py67
4 files changed, 234 insertions, 83 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hoblistmodel.py b/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
index 0f37a068c6..9b8db23c79 100644
--- a/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
+++ b/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
@@ -85,34 +85,67 @@ class PackageListModel(gtk.ListStore):
85 Helper function to determine whether an item is an item specified by filter 85 Helper function to determine whether an item is an item specified by filter
86 """ 86 """
87 def tree_model_filter(self, model, it, filter): 87 def tree_model_filter(self, model, it, filter):
88 for key in filter.keys(): 88 name = model.get_value(it, self.COL_NAME)
89 if model.get_value(it, key) not in filter[key]:
90 return False
91 89
90 for key in filter.keys():
91 if key == self.COL_NAME:
92 if filter[key] != 'Search packages by name':
93 if filter[key] not in name:
94 return False
95 else:
96 if model.get_value(it, key) not in filter[key]:
97 return False
98 self.filtered_nb += 1
92 return True 99 return True
93 100
94 """ 101 """
95 Create, if required, and return a filtered gtk.TreeModelSort 102 Create, if required, and return a filtered gtk.TreeModelSort
96 containing only the items specified by filter 103 containing only the items specified by filter
97 """ 104 """
98 def tree_model(self, filter): 105 def tree_model(self, filter, excluded_items_ahead=False, included_items_ahead=True, search_data=None):
99 model = self.filter_new() 106 model = self.filter_new()
107 self.filtered_nb = 0
100 model.set_visible_func(self.tree_model_filter, filter) 108 model.set_visible_func(self.tree_model_filter, filter)
101 109
102 sort = gtk.TreeModelSort(model) 110 sort = gtk.TreeModelSort(model)
103 sort.set_sort_column_id(RecipeListModel.COL_NAME, gtk.SORT_ASCENDING) 111 if excluded_items_ahead:
104 sort.set_default_sort_func(None) 112 sort.set_default_sort_func(self.exclude_item_sort_func, search_data)
113 elif included_items_ahead:
114 sort.set_default_sort_func(self.include_item_sort_func, search_data)
115 else:
116 sort.set_sort_column_id(RecipeListModel.COL_NAME, gtk.SORT_ASCENDING)
117 sort.set_default_sort_func(None)
105 return sort 118 return sort
106 119
107 def exclude_item_sort_func(self, model, iter1, iter2): 120 def exclude_item_sort_func(self, model, iter1, iter2, user_data=None):
108 val1 = model.get_value(iter1, RecipeListModel.COL_FADE_INC) 121 if user_data:
109 val2 = model.get_value(iter2, RecipeListModel.COL_INC) 122 val1 = model.get_value(iter1, RecipeListModel.COL_NAME)
110 return ((val1 == True) and (val2 == False)) 123 val2 = model.get_value(iter2, RecipeListModel.COL_NAME)
111 124 if val1.startswith(user_data) and not val2.startswith(user_data):
112 def include_item_sort_func(self, model, iter1, iter2): 125 return -1
113 val1 = model.get_value(iter1, RecipeListModel.COL_INC) 126 elif not val1.startswith(user_data) and val2.startswith(user_data):
114 val2 = model.get_value(iter2, RecipeListModel.COL_INC) 127 return 1
115 return ((val1 == False) and (val2 == True)) 128 else:
129 return 0
130 else:
131 val1 = model.get_value(iter1, RecipeListModel.COL_FADE_INC)
132 val2 = model.get_value(iter2, RecipeListModel.COL_INC)
133 return ((val1 == True) and (val2 == False))
134
135 def include_item_sort_func(self, model, iter1, iter2, user_data=None):
136 if user_data:
137 val1 = model.get_value(iter1, RecipeListModel.COL_NAME)
138 val2 = model.get_value(iter2, RecipeListModel.COL_NAME)
139 if val1.startswith(user_data) and not val2.startswith(user_data):
140 return -1
141 elif not val1.startswith(user_data) and val2.startswith(user_data):
142 return 1
143 else:
144 return 0
145 else:
146 val1 = model.get_value(iter1, RecipeListModel.COL_INC)
147 val2 = model.get_value(iter2, RecipeListModel.COL_INC)
148 return ((val1 == False) and (val2 == True))
116 149
117 def convert_vpath_to_path(self, view_model, view_path): 150 def convert_vpath_to_path(self, view_model, view_path):
118 # view_model is the model sorted 151 # view_model is the model sorted
@@ -444,34 +477,61 @@ class RecipeListModel(gtk.ListStore):
444 return False 477 return False
445 478
446 for key in filter.keys(): 479 for key in filter.keys():
447 if model.get_value(it, key) not in filter[key]: 480 if key == self.COL_NAME:
448 return False 481 if filter[key] != 'Search recipes by name' and filter[key] != 'Search package groups by name':
482 if filter[key] not in name:
483 return False
484 else:
485 if model.get_value(it, key) not in filter[key]:
486 return False
487 self.filtered_nb += 1
449 488
450 return True 489 return True
451 490
452 def exclude_item_sort_func(self, model, iter1, iter2): 491 def exclude_item_sort_func(self, model, iter1, iter2, user_data=None):
453 val1 = model.get_value(iter1, RecipeListModel.COL_FADE_INC) 492 if user_data:
454 val2 = model.get_value(iter2, RecipeListModel.COL_INC) 493 val1 = model.get_value(iter1, RecipeListModel.COL_NAME)
455 return ((val1 == True) and (val2 == False)) 494 val2 = model.get_value(iter2, RecipeListModel.COL_NAME)
456 495 if val1.startswith(user_data) and not val2.startswith(user_data):
457 def include_item_sort_func(self, model, iter1, iter2): 496 return -1
458 val1 = model.get_value(iter1, RecipeListModel.COL_INC) 497 elif not val1.startswith(user_data) and val2.startswith(user_data):
459 val2 = model.get_value(iter2, RecipeListModel.COL_INC) 498 return 1
460 return ((val1 == False) and (val2 == True)) 499 else:
500 return 0
501 else:
502 val1 = model.get_value(iter1, RecipeListModel.COL_FADE_INC)
503 val2 = model.get_value(iter2, RecipeListModel.COL_INC)
504 return ((val1 == True) and (val2 == False))
505
506 def include_item_sort_func(self, model, iter1, iter2, user_data=None):
507 if user_data:
508 val1 = model.get_value(iter1, RecipeListModel.COL_NAME)
509 val2 = model.get_value(iter2, RecipeListModel.COL_NAME)
510 if val1.startswith(user_data) and not val2.startswith(user_data):
511 return -1
512 elif not val1.startswith(user_data) and val2.startswith(user_data):
513 return 1
514 else:
515 return 0
516 else:
517 val1 = model.get_value(iter1, RecipeListModel.COL_INC)
518 val2 = model.get_value(iter2, RecipeListModel.COL_INC)
519 return ((val1 == False) and (val2 == True))
461 520
462 """ 521 """
463 Create, if required, and return a filtered gtk.TreeModelSort 522 Create, if required, and return a filtered gtk.TreeModelSort
464 containing only the items specified by filter 523 containing only the items specified by filter
465 """ 524 """
466 def tree_model(self, filter, excluded_items_ahead=False, included_items_ahead=True): 525 def tree_model(self, filter, excluded_items_ahead=False, included_items_ahead=True, search_data=None):
467 model = self.filter_new() 526 model = self.filter_new()
527 self.filtered_nb = 0
468 model.set_visible_func(self.tree_model_filter, filter) 528 model.set_visible_func(self.tree_model_filter, filter)
469 529
470 sort = gtk.TreeModelSort(model) 530 sort = gtk.TreeModelSort(model)
471 if excluded_items_ahead: 531 if excluded_items_ahead:
472 sort.set_default_sort_func(self.exclude_item_sort_func) 532 sort.set_default_sort_func(self.exclude_item_sort_func, search_data)
473 elif included_items_ahead: 533 elif included_items_ahead:
474 sort.set_default_sort_func(self.include_item_sort_func) 534 sort.set_default_sort_func(self.include_item_sort_func, search_data)
475 else: 535 else:
476 sort.set_sort_column_id(RecipeListModel.COL_NAME, gtk.SORT_ASCENDING) 536 sort.set_sort_column_id(RecipeListModel.COL_NAME, gtk.SORT_ASCENDING)
477 sort.set_default_sort_func(None) 537 sort.set_default_sort_func(None)
diff --git a/bitbake/lib/bb/ui/crumbs/hobwidget.py b/bitbake/lib/bb/ui/crumbs/hobwidget.py
index 9a00e941e9..17d9cee138 100644
--- a/bitbake/lib/bb/ui/crumbs/hobwidget.py
+++ b/bitbake/lib/bb/ui/crumbs/hobwidget.py
@@ -88,12 +88,12 @@ class HobViewTable (gtk.VBox):
88 self.table_tree = gtk.TreeView() 88 self.table_tree = gtk.TreeView()
89 self.table_tree.set_headers_visible(True) 89 self.table_tree.set_headers_visible(True)
90 self.table_tree.set_headers_clickable(True) 90 self.table_tree.set_headers_clickable(True)
91 self.table_tree.set_enable_search(True)
92 self.table_tree.set_rules_hint(True) 91 self.table_tree.set_rules_hint(True)
93 self.table_tree.set_enable_tree_lines(True) 92 self.table_tree.set_enable_tree_lines(True)
94 self.table_tree.get_selection().set_mode(gtk.SELECTION_SINGLE) 93 self.table_tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
95 self.toggle_columns = [] 94 self.toggle_columns = []
96 self.table_tree.connect("row-activated", self.row_activated_cb) 95 self.table_tree.connect("row-activated", self.row_activated_cb)
96 self.top_bar = None
97 97
98 for i, column in enumerate(columns): 98 for i, column in enumerate(columns):
99 col = gtk.TreeViewColumn(column['col_name']) 99 col = gtk.TreeViewColumn(column['col_name'])
@@ -141,10 +141,41 @@ class HobViewTable (gtk.VBox):
141 if 'col_t_id' in column.keys(): 141 if 'col_t_id' in column.keys():
142 col.add_attribute(cell, 'font', column['col_t_id']) 142 col.add_attribute(cell, 'font', column['col_t_id'])
143 143
144 scroll = gtk.ScrolledWindow() 144 self.scroll = gtk.ScrolledWindow()
145 scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) 145 self.scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
146 scroll.add(self.table_tree) 146 self.scroll.add(self.table_tree)
147 self.pack_start(scroll, True, True, 0) 147
148 self.pack_end(self.scroll, True, True, 0)
149
150 def add_no_result_bar(self, entry):
151 color = HobColors.KHAKI
152 self.top_bar = gtk.EventBox()
153 self.top_bar.set_size_request(-1, 70)
154 self.top_bar.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
155 self.top_bar.set_flags(gtk.CAN_DEFAULT)
156 self.top_bar.grab_default()
157
158 no_result_tab = gtk.Table(5, 20, True)
159 self.top_bar.add(no_result_tab)
160
161 label = gtk.Label()
162 label.set_alignment(0.0, 0.5)
163 title = "No results matching your search"
164 label.set_markup("<span size='x-large'><b>%s</b></span>" % title)
165 no_result_tab.attach(label, 1, 14, 1, 4)
166
167 clear_button = HobButton("Clear search")
168 clear_button.connect('clicked', self.set_search_entry_clear_cb, entry)
169 no_result_tab.attach(clear_button, 16, 19, 1, 4)
170
171 self.pack_start(self.top_bar, False, True, 12)
172 self.top_bar.show_all()
173
174 def set_search_entry_clear_cb(self, button, search):
175 if search.get_editable() == True:
176 search.set_text("")
177 search.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
178 search.grab_focus()
148 179
149 def display_binb_cb(self, col, cell, model, it, col_id): 180 def display_binb_cb(self, col, cell, model, it, col_id):
150 binb = model.get_value(it, col_id) 181 binb = model.get_value(it, col_id)
@@ -170,10 +201,6 @@ class HobViewTable (gtk.VBox):
170 def set_model(self, tree_model): 201 def set_model(self, tree_model):
171 self.table_tree.set_model(tree_model) 202 self.table_tree.set_model(tree_model)
172 203
173 def set_search_entry(self, search_column_id, entry):
174 self.table_tree.set_search_column(search_column_id)
175 self.table_tree.set_search_entry(entry)
176
177 def toggle_default(self): 204 def toggle_default(self):
178 model = self.table_tree.get_model() 205 model = self.table_tree.get_model()
179 if not model: 206 if not model:
@@ -453,7 +480,6 @@ class HobNotebook(gtk.Notebook):
453 self.pages = [] 480 self.pages = []
454 481
455 self.search = None 482 self.search = None
456 self.search_name = ""
457 483
458 self.connect("switch-page", self.page_changed_cb) 484 self.connect("switch-page", self.page_changed_cb)
459 485
@@ -466,6 +492,9 @@ class HobNotebook(gtk.Notebook):
466 else: 492 else:
467 lbl.set_active(False) 493 lbl.set_active(False)
468 494
495 if self.search:
496 self.reset_entry(self.search, page_num)
497
469 def append_page(self, child, tab_label, tab_tooltip=None): 498 def append_page(self, child, tab_label, tab_tooltip=None):
470 label = HobTabLabel(tab_label) 499 label = HobTabLabel(tab_label)
471 if tab_tooltip: 500 if tab_tooltip:
@@ -474,16 +503,22 @@ class HobNotebook(gtk.Notebook):
474 self.pages.append(label) 503 self.pages.append(label)
475 gtk.Notebook.append_page(self, child, label) 504 gtk.Notebook.append_page(self, child, label)
476 505
477 def set_entry(self, name="Search:"): 506 def set_entry(self, names, tips):
478 self.search = gtk.Entry() 507 self.search = gtk.Entry()
479 self.search_name = name 508 self.search_names = names
509 self.search_tips = tips
480 style = self.search.get_style() 510 style = self.search.get_style()
481 style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) 511 style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False)
482 self.search.set_style(style) 512 self.search.set_style(style)
483 self.search.set_text(name) 513 self.search.set_text(names[0])
514 self.search.set_tooltip_text(self.search_tips[0])
515 self.search.props.has_tooltip = True
516
484 self.search.set_editable(False) 517 self.search.set_editable(False)
485 self.search.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, gtk.STOCK_CLEAR) 518 self.search.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, gtk.STOCK_CLEAR)
519 self.search.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
486 self.search.connect("icon-release", self.set_search_entry_clear_cb) 520 self.search.connect("icon-release", self.set_search_entry_clear_cb)
521 self.search.set_width_chars(30)
487 self.search.show() 522 self.search.show()
488 523
489 self.search.connect("focus-in-event", self.set_search_entry_editable_cb) 524 self.search.connect("focus-in-event", self.set_search_entry_editable_cb)
@@ -507,19 +542,23 @@ class HobNotebook(gtk.Notebook):
507 style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False) 542 style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False)
508 search.set_style(style) 543 search.set_style(style)
509 544
510 def reset_entry(self, entry): 545 def set_search_entry_reset_cb(self, search, event):
546 page_num = self.get_current_page()
547 self.reset_entry(search, page_num)
548
549 def reset_entry(self, entry, page_num):
511 style = entry.get_style() 550 style = entry.get_style()
512 style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) 551 style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False)
513 entry.set_style(style) 552 entry.set_style(style)
514 entry.set_text(self.search_name) 553 entry.set_text(self.search_names[page_num])
554 entry.set_tooltip_text(self.search_tips[page_num])
515 entry.set_editable(False) 555 entry.set_editable(False)
516 556 entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
517 def set_search_entry_reset_cb(self, search, event):
518 self.reset_entry(search)
519 557
520 def set_search_entry_clear_cb(self, search, icon_pos, event): 558 def set_search_entry_clear_cb(self, search, icon_pos, event):
521 if search.get_editable() == True: 559 if search.get_editable() == True:
522 search.set_text("") 560 search.set_text("")
561 search.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
523 562
524 def set_page(self, title): 563 def set_page(self, title):
525 for child in self.pages: 564 for child in self.pages:
diff --git a/bitbake/lib/bb/ui/crumbs/packageselectionpage.py b/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
index 6f9a4e2a7a..ce2deabb89 100755
--- a/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
+++ b/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
@@ -34,10 +34,12 @@ class PackageSelectionPage (HobPage):
34 34
35 pages = [ 35 pages = [
36 { 36 {
37 'name' : 'Included packages', 37 'name' : 'Included packages',
38 'tooltip' : 'The packages currently included for your image', 38 'tooltip' : 'The packages currently included for your image',
39 'filter' : { PackageListModel.COL_INC : [True] }, 39 'filter' : { PackageListModel.COL_INC : [True] },
40 'columns' : [{ 40 'search' : 'Search packages by name',
41 'searchtip' : 'Enter a package name to find it',
42 'columns' : [{
41 'col_name' : 'Package name', 43 'col_name' : 'Package name',
42 'col_id' : PackageListModel.COL_NAME, 44 'col_id' : PackageListModel.COL_NAME,
43 'col_style': 'text', 45 'col_style': 'text',
@@ -73,10 +75,12 @@ class PackageSelectionPage (HobPage):
73 'col_max' : 100 75 'col_max' : 100
74 }] 76 }]
75 }, { 77 }, {
76 'name' : 'All packages', 78 'name' : 'All packages',
77 'tooltip' : 'All packages that have been built', 79 'tooltip' : 'All packages that have been built',
78 'filter' : {}, 80 'filter' : {},
79 'columns' : [{ 81 'search' : 'Search packages by name',
82 'searchtip' : 'Enter a package name to find it',
83 'columns' : [{
80 'col_name' : 'Package name', 84 'col_name' : 'Package name',
81 'col_id' : PackageListModel.COL_NAME, 85 'col_id' : PackageListModel.COL_NAME,
82 'col_style': 'text', 86 'col_style': 'text',
@@ -132,12 +136,18 @@ class PackageSelectionPage (HobPage):
132 # set visible members 136 # set visible members
133 self.ins = HobNotebook() 137 self.ins = HobNotebook()
134 self.tables = [] # we need to modify table when the dialog is shown 138 self.tables = [] # we need to modify table when the dialog is shown
139
140 search_names = []
141 search_tips = []
135 # append the tab 142 # append the tab
136 for page in self.pages: 143 for page in self.pages:
137 columns = page['columns'] 144 columns = page['columns']
138 tab = HobViewTable(columns) 145 tab = HobViewTable(columns)
146 search_names.append(page['search'])
147 search_tips.append(page['searchtip'])
139 filter = page['filter'] 148 filter = page['filter']
140 tab.set_model(self.package_model.tree_model(filter)) 149 sort_model = self.package_model.tree_model(filter)
150 tab.set_model(sort_model)
141 tab.connect("toggled", self.table_toggled_cb, page['name']) 151 tab.connect("toggled", self.table_toggled_cb, page['name'])
142 if page['name'] == "Included packages": 152 if page['name'] == "Included packages":
143 tab.connect("button-release-event", self.button_click_cb) 153 tab.connect("button-release-event", self.button_click_cb)
@@ -148,13 +158,8 @@ class PackageSelectionPage (HobPage):
148 self.ins.append_page(tab, page['name'], page['tooltip']) 158 self.ins.append_page(tab, page['name'], page['tooltip'])
149 self.tables.append(tab) 159 self.tables.append(tab)
150 160
151 self.ins.set_entry("Search packages:") 161 self.ins.set_entry(search_names, search_tips)
152 # set the search entry for each table 162 self.ins.search.connect("changed", self.search_entry_changed)
153 for tab in self.tables:
154 search_tip = "Enter a package name to find it"
155 self.ins.search.set_tooltip_text(search_tip)
156 self.ins.search.props.has_tooltip = True
157 tab.set_search_entry(0, self.ins.search)
158 163
159 # add all into the dialog 164 # add all into the dialog
160 self.box_group_area.pack_start(self.ins, expand=True, fill=True) 165 self.box_group_area.pack_start(self.ins, expand=True, fill=True)
@@ -174,6 +179,26 @@ class PackageSelectionPage (HobPage):
174 self.back_button.connect("clicked", self.back_button_clicked_cb) 179 self.back_button.connect("clicked", self.back_button_clicked_cb)
175 self.button_box.pack_end(self.back_button, expand=False, fill=False) 180 self.button_box.pack_end(self.back_button, expand=False, fill=False)
176 181
182 def search_entry_changed(self, entry):
183 current_tab = self.ins.get_current_page()
184 filter = self.pages[current_tab]['filter']
185 text = entry.get_text()
186 filter[PackageListModel.COL_NAME] = text
187 self.tables[current_tab].set_model(self.package_model.tree_model(filter, search_data=text))
188 if self.package_model.filtered_nb == 0:
189 if not self.ins.get_nth_page(current_tab).top_bar:
190 self.ins.get_nth_page(current_tab).add_no_result_bar(entry)
191 self.ins.get_nth_page(current_tab).top_bar.show()
192 self.ins.get_nth_page(current_tab).scroll.hide()
193 else:
194 if self.ins.get_nth_page(current_tab).top_bar:
195 self.ins.get_nth_page(current_tab).top_bar.hide()
196 self.ins.get_nth_page(current_tab).scroll.show()
197 if entry.get_text() == '':
198 entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
199 else:
200 entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, True)
201
177 def button_click_cb(self, widget, event): 202 def button_click_cb(self, widget, event):
178 path, col = widget.table_tree.get_cursor() 203 path, col = widget.table_tree.get_cursor()
179 tree_model = widget.table_tree.get_model() 204 tree_model = widget.table_tree.get_model()
diff --git a/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py b/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
index 636762e40c..aa0cd60c3f 100755
--- a/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
+++ b/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
@@ -33,11 +33,13 @@ from bb.ui.crumbs.hobpages import HobPage
33class RecipeSelectionPage (HobPage): 33class RecipeSelectionPage (HobPage):
34 pages = [ 34 pages = [
35 { 35 {
36 'name' : 'Included recipes', 36 'name' : 'Included recipes',
37 'tooltip' : 'The recipes currently included for your image', 37 'tooltip' : 'The recipes currently included for your image',
38 'filter' : { RecipeListModel.COL_INC : [True], 38 'filter' : { RecipeListModel.COL_INC : [True],
39 RecipeListModel.COL_TYPE : ['recipe', 'packagegroup'] }, 39 RecipeListModel.COL_TYPE : ['recipe', 'packagegroup'] },
40 'columns' : [{ 40 'search' : 'Search recipes by name',
41 'searchtip' : 'Enter a recipe name to find it',
42 'columns' : [{
41 'col_name' : 'Recipe name', 43 'col_name' : 'Recipe name',
42 'col_id' : RecipeListModel.COL_NAME, 44 'col_id' : RecipeListModel.COL_NAME,
43 'col_style': 'text', 45 'col_style': 'text',
@@ -66,10 +68,12 @@ class RecipeSelectionPage (HobPage):
66 'col_max' : 100 68 'col_max' : 100
67 }] 69 }]
68 }, { 70 }, {
69 'name' : 'All recipes', 71 'name' : 'All recipes',
70 'tooltip' : 'All recipes in your configured layers', 72 'tooltip' : 'All recipes in your configured layers',
71 'filter' : { RecipeListModel.COL_TYPE : ['recipe'] }, 73 'filter' : { RecipeListModel.COL_TYPE : ['recipe'] },
72 'columns' : [{ 74 'search' : 'Search recipes by name',
75 'searchtip' : 'Enter a recipe name to find it',
76 'columns' : [{
73 'col_name' : 'Recipe name', 77 'col_name' : 'Recipe name',
74 'col_id' : RecipeListModel.COL_NAME, 78 'col_id' : RecipeListModel.COL_NAME,
75 'col_style': 'text', 79 'col_style': 'text',
@@ -98,10 +102,12 @@ class RecipeSelectionPage (HobPage):
98 'col_max' : 100 102 'col_max' : 100
99 }] 103 }]
100 }, { 104 }, {
101 'name' : 'Package Groups', 105 'name' : 'Package Groups',
102 'tooltip' : 'All package groups in your configured layers', 106 'tooltip' : 'All package groups in your configured layers',
103 'filter' : { RecipeListModel.COL_TYPE : ['packagegroup'] }, 107 'filter' : { RecipeListModel.COL_TYPE : ['packagegroup'] },
104 'columns' : [{ 108 'search' : 'Search package groups by name',
109 'searchtip' : 'Enter a package group name to find it',
110 'columns' : [{
105 'col_name' : 'Package group name', 111 'col_name' : 'Package group name',
106 'col_id' : RecipeListModel.COL_NAME, 112 'col_id' : RecipeListModel.COL_NAME,
107 'col_style': 'text', 113 'col_style': 'text',
@@ -142,12 +148,18 @@ class RecipeSelectionPage (HobPage):
142 # set visible members 148 # set visible members
143 self.ins = HobNotebook() 149 self.ins = HobNotebook()
144 self.tables = [] # we need modify table when the dialog is shown 150 self.tables = [] # we need modify table when the dialog is shown
151
152 search_names = []
153 search_tips = []
145 # append the tabs in order 154 # append the tabs in order
146 for page in self.pages: 155 for page in self.pages:
147 columns = page['columns'] 156 columns = page['columns']
148 tab = HobViewTable(columns) 157 tab = HobViewTable(columns)
158 search_names.append(page['search'])
159 search_tips.append(page['searchtip'])
149 filter = page['filter'] 160 filter = page['filter']
150 tab.set_model(self.recipe_model.tree_model(filter)) 161 sort_model = self.recipe_model.tree_model(filter)
162 tab.set_model(sort_model)
151 tab.connect("toggled", self.table_toggled_cb, page['name']) 163 tab.connect("toggled", self.table_toggled_cb, page['name'])
152 if page['name'] == "Included recipes": 164 if page['name'] == "Included recipes":
153 tab.connect("button-release-event", self.button_click_cb) 165 tab.connect("button-release-event", self.button_click_cb)
@@ -161,13 +173,8 @@ class RecipeSelectionPage (HobPage):
161 self.ins.append_page(tab, page['name'], page['tooltip']) 173 self.ins.append_page(tab, page['name'], page['tooltip'])
162 self.tables.append(tab) 174 self.tables.append(tab)
163 175
164 self.ins.set_entry("Search recipes:") 176 self.ins.set_entry(search_names, search_tips)
165 # set the search entry for each table 177 self.ins.search.connect("changed", self.search_entry_changed)
166 for tab in self.tables:
167 search_tip = "Enter a recipe's or task's name to find it"
168 self.ins.search.set_tooltip_text(search_tip)
169 self.ins.search.props.has_tooltip = True
170 tab.set_search_entry(0, self.ins.search)
171 178
172 # add all into the window 179 # add all into the window
173 self.box_group_area.pack_start(self.ins, expand=True, fill=True) 180 self.box_group_area.pack_start(self.ins, expand=True, fill=True)
@@ -187,6 +194,26 @@ class RecipeSelectionPage (HobPage):
187 self.back_button.connect("clicked", self.back_button_clicked_cb) 194 self.back_button.connect("clicked", self.back_button_clicked_cb)
188 button_box.pack_end(self.back_button, expand=False, fill=False) 195 button_box.pack_end(self.back_button, expand=False, fill=False)
189 196
197 def search_entry_changed(self, entry):
198 current_tab = self.ins.get_current_page()
199 filter = self.pages[current_tab]['filter']
200 text = entry.get_text()
201 filter[RecipeListModel.COL_NAME] = text
202 self.tables[current_tab].set_model(self.recipe_model.tree_model(filter, search_data=text))
203 if self.recipe_model.filtered_nb == 0:
204 if not self.ins.get_nth_page(current_tab).top_bar:
205 self.ins.get_nth_page(current_tab).add_no_result_bar(entry)
206 self.ins.get_nth_page(current_tab).top_bar.show()
207 self.ins.get_nth_page(current_tab).scroll.hide()
208 else:
209 if self.ins.get_nth_page(current_tab).top_bar:
210 self.ins.get_nth_page(current_tab).top_bar.hide()
211 self.ins.get_nth_page(current_tab).scroll.show()
212 if entry.get_text() == '':
213 entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, False)
214 else:
215 entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, True)
216
190 def button_click_cb(self, widget, event): 217 def button_click_cb(self, widget, event):
191 path, col = widget.table_tree.get_cursor() 218 path, col = widget.table_tree.get_cursor()
192 tree_model = widget.table_tree.get_model() 219 tree_model = widget.table_tree.get_model()