diff options
author | Cristiana Voicu <cristiana.voicu@intel.com> | 2013-03-20 14:35:06 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-03-22 16:54:39 +0000 |
commit | 860f826753cab81b1d1d9b2ecafa630a96676d9e (patch) | |
tree | 6f5da66864b05ded2f96c76ce9299a3386fa9c1f /bitbake | |
parent | ab7d8bd172f61e14266a020bd6633d33d79e3d8f (diff) | |
download | poky-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')
-rw-r--r-- | bitbake/lib/bb/ui/crumbs/hoblistmodel.py | 118 | ||||
-rw-r--r-- | bitbake/lib/bb/ui/crumbs/hobwidget.py | 75 | ||||
-rwxr-xr-x | bitbake/lib/bb/ui/crumbs/packageselectionpage.py | 57 | ||||
-rwxr-xr-x | bitbake/lib/bb/ui/crumbs/recipeselectionpage.py | 67 |
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 | |||
33 | class RecipeSelectionPage (HobPage): | 33 | class 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() |