From cac83b6f3bfa361bb2c561675c3247ff88341067 Mon Sep 17 00:00:00 2001 From: "Loo, Tung Lun" Date: Tue, 13 Jul 2021 08:12:08 +0800 Subject: [PATCH] IntelFsp2Pkg: Add search function for Config Editor BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3482 This patch adds a search function in the Config Editor GUI at the top right corner. Once users key in the words to search, it will look for the option containing the string in the same page and display it. It also includes a README for this function. Cc: Maurice Ma Cc: Nate DeSimone Cc: Star Zeng Cc: Chasel Chiu Signed-off-by: Loo Tung Lun Reviewed-by: Chasel Chiu --- .../Tools/ConfigEditor/ConfigEditor.py | 41 ++++++++++++++++- IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py | 44 ++++++++++++++----- .../UserManuals/ConfigEditorUserManual.md | 4 ++ 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py b/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py index a7f79bbc9615..008c7d7a160a 100644 --- a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py +++ b/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py @@ -811,6 +811,8 @@ def __init__(self, master=None): self.org_cfg_data_bin = None self.in_left = state() self.in_right = state() + self.search_text = '' + self.binseg_dict = {} # Check if current directory contains a file with a .yaml extension # if not default self.last_dir to a Platform directory where it is @@ -835,6 +837,23 @@ def __init__(self, master=None): root.geometry("1200x800") + # Search string + fram = tkinter.Frame(root) + # adding label to search box + tkinter.Label(fram, text='Text to find:').pack(side=tkinter.LEFT) + # adding of single line text box + self.edit = tkinter.Entry(fram, width=30) + # positioning of text box + self.edit.pack( + side=tkinter.LEFT, fill=tkinter.BOTH, expand=1, padx=(4, 4)) + # setting focus + self.edit.focus_set() + # adding of search button + butt = tkinter.Button(fram, text='Search', relief=tkinter.GROOVE, + command=self.search_bar) + butt.pack(side=tkinter.RIGHT, padx=(4, 4)) + fram.pack(side=tkinter.TOP, anchor=tkinter.SE) + paned = ttk.Panedwindow(root, orient=tkinter.HORIZONTAL) paned.pack(fill=tkinter.BOTH, expand=True, padx=(4, 4)) @@ -943,6 +962,12 @@ def __init__(self, master=None): "Unsupported file '%s' !" % path) return + def search_bar(self): + # get data from text box + self.search_text = self.edit.get() + # Clear the page and update it according to search value + self.refresh_config_data_page() + def set_object_name(self, widget, name): self.conf_list[id(widget)] = name @@ -976,14 +1001,18 @@ def on_page_scroll(self, event): 'units') def update_visibility_for_widget(self, widget, args): - visible = True item = self.get_config_data_item_from_widget(widget, True) if item is None: return visible elif not item: return visible - + if self.cfg_data_obj.binseg_dict: + str_split = item['path'].split('.') + if self.cfg_data_obj.binseg_dict[str_split[-2]] == -1: + visible = False + widget.grid_remove() + return visible result = 1 if item['condition']: result = self.evaluate_condition(item) @@ -999,6 +1028,12 @@ def update_visibility_for_widget(self, widget, args): widget.grid() widget.configure(state='normal') + if visible and self.search_text != '': + name = item['name'] + if name.lower().find(self.search_text.lower()) == -1: + visible = False + widget.grid_remove() + return visible def update_widgets_visibility_on_page(self): @@ -1134,6 +1169,7 @@ def load_config_data(self, file_name): self.fsp_version = '2.X' else: self.fsp_version = '1.X' + return gen_cfg_data def about(self): @@ -1377,6 +1413,7 @@ def get_config_data_item_from_widget(self, widget, label=False): return None else: path = name + item = self.cfg_data_obj.get_item_by_path(path) return item diff --git a/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py b/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py index 25fd9c547efa..611a9a9c7266 100644 --- a/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py +++ b/IntelFsp2Pkg/Tools/ConfigEditor/GenYamlCfg.py @@ -583,6 +583,8 @@ def __init__(self): self._mode = '' self._debug = False self._macro_dict = {} + self.bin_offset = [] + self.binseg_dict = {} self.initialize() def initialize(self): @@ -1301,10 +1303,15 @@ def _set_field_value(name, cfgs, level): if 'indx' not in cfgs: return act_cfg = self.get_item_by_index(cfgs['indx']) - if force or act_cfg['value'] == '': + actual_offset = act_cfg['offset'] - struct_info['offset'] + set_value = True + for each in self.bin_offset: + if actual_offset in range(each[0], (each[0] + each[2]) * 8): + if each[1] < 0: + set_value = False + if set_value and force or act_cfg['value'] == '': value = get_bits_from_bytes(full_bytes, - act_cfg['offset'] - - struct_info['offset'], + actual_offset, act_cfg['length']) act_val = act_cfg['value'] if act_val == '': @@ -1423,9 +1430,11 @@ def get_bin_segment(self, bin_data): "in binary, the 1st instance will be used !" % seg[0]) bin_segs.append([seg[0], pos, seg[2]]) + self.binseg_dict[seg[0]] = pos else: - raise Exception("Could not find '%s' in binary !" - % seg[0]) + bin_segs.append([seg[0], -1, seg[2]]) + self.binseg_dict[seg[0]] = -1 + continue return bin_segs @@ -1433,8 +1442,17 @@ def extract_cfg_from_bin(self, bin_data): # get cfg bin length cfg_bins = bytearray() bin_segs = self.get_bin_segment(bin_data) + Dummy_offset = 0 for each in bin_segs: - cfg_bins.extend(bin_data[each[1]:each[1] + each[2]]) + if each[1] != -1: + self.bin_offset.append([Dummy_offset, each[1], each[2]]) + cfg_bins.extend(bin_data[each[1]:each[1] + each[2]]) + else: + string = each[0] + ' is not availabe.' + messagebox.showinfo('', string) + self.bin_offset.append([Dummy_offset, each[1], each[2]]) + cfg_bins.extend(bytearray(each[2])) + Dummy_offset += each[2] return cfg_bins def save_current_to_bin(self): @@ -1447,12 +1465,15 @@ def save_current_to_bin(self): cfg_off = 0 for each in bin_segs: length = each[2] - bin_data[each[1]:each[1] + length] = cfg_bins[cfg_off: - cfg_off - + length] - cfg_off += length - print('Patched the loaded binary successfully !') + if each[1] != -1: + bin_data[each[1]:each[1] + length] = cfg_bins[cfg_off: + cfg_off + + length] + cfg_off += length + else: + cfg_off += length + print('Patched the loaded binary successfully !') return bin_data def load_default_from_bin(self, bin_data): @@ -1469,6 +1490,7 @@ def generate_binary_array(self, path=''): if not top: raise Exception("Invalid configuration path '%s' !" % path) + return self.get_field_value(top) def generate_binary(self, bin_file_name, path=''): diff --git a/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md b/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md index 08a815133c3f..da21df243242 100644 --- a/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md +++ b/IntelFsp2Pkg/Tools/UserManuals/ConfigEditorUserManual.md @@ -40,6 +40,10 @@ This option generates a new configuration delta file for the newly changed value ## 8. Save Full Config Data to Delta File This option saves all the changed configuration values into a Delta file. +## 9. Search feature +This feature helps the user to easily find any configuration item they are looking for in ConfigEditor. +A text search box is available on the Top Right Corner of ConfigEditor. To use this feature the user should type the name or a key word of the item they want to search in the text box and then click on the "Search" button. This will display all the items which contains that particular word searched by the user. + ## Running Configuration Editor: **python ConfigEditor.py**