From 1675b0a116c84e603290517c571cec2d951066ec Mon Sep 17 00:00:00 2001 From: Russell Schmidt Date: Tue, 4 Feb 2025 17:34:41 -0600 Subject: [PATCH 1/2] Add channel and node search feature Press Ctrl + / while the nodes or channels window is highlighted to start search Type text to search as you type, first matching item will be selected, starting at current selected index Press Tab to find next match starting from the current index - search wraps around if necessary Press Esc or Enter to exit search mode --- ui/curses_ui.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/ui/curses_ui.py b/ui/curses_ui.py index 0133ee9..34ceb08 100644 --- a/ui/curses_ui.py +++ b/ui/curses_ui.py @@ -374,6 +374,50 @@ def draw_packetlog_win(): packetlog_win.box() packetlog_win.refresh() +def search(win): + start_idx = globals.selected_node + l = globals.node_list + select_func = select_node + + if win == 0: + start_idx = globals.selected_channel + l = globals.channel_list + select_func = select_channel + + search_text = "" + entry_win.erase() + + while True: + draw_centered_text_field(entry_win, f"Search: {search_text}", 0, get_color("input")) + char = entry_win.get_wch() + + if char in (chr(27), chr(curses.KEY_ENTER), chr(10), chr(13)): + break + elif char == "\t": + start_idx = globals.selected_node + 1 if win == 2 else globals.selected_channel + 1 + elif char in (curses.KEY_BACKSPACE, chr(127)): + if search_text: + search_text = search_text[:-1] + y, x = entry_win.getyx() + entry_win.move(y, x - 1) + entry_win.addch(' ') # + entry_win.move(y, x - 1) + entry_win.erase() + entry_win.refresh() + elif isinstance(char, str): + search_text += char + + search_text_caseless = search_text.casefold() + + for i, n in enumerate(l[start_idx:] + l[:start_idx]): + if isinstance(n, int) and search_text_caseless in get_name_from_database(n, 'long').casefold() \ + or isinstance(n, int) and search_text_caseless in get_name_from_database(n, 'short').casefold() \ + or search_text_caseless in str(n).casefold(): + select_func((i + start_idx) % len(l)) + break + + entry_win.erase() + def handle_resize(stdscr, firstrun): global messages_pad, messages_box, nodes_pad, nodes_box, channel_pad, channel_box, function_win, packetlog_win, entry_win @@ -671,6 +715,10 @@ def main_ui(stdscr): draw_channel_list() draw_messages_window() + elif char == chr(31): + if(globals.current_window == 2 or globals.current_window == 0): + search(globals.current_window) + else: # Append typed character to input text if(isinstance(char, str)): From 8382da07a366ae355649ee8ee99d7a8cb0f6b52d Mon Sep 17 00:00:00 2001 From: Russell Schmidt Date: Tue, 4 Feb 2025 19:16:00 -0600 Subject: [PATCH 2/2] Fix indexing if list changes while searching --- ui/curses_ui.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui/curses_ui.py b/ui/curses_ui.py index 34ceb08..9df2e41 100644 --- a/ui/curses_ui.py +++ b/ui/curses_ui.py @@ -376,12 +376,10 @@ def draw_packetlog_win(): def search(win): start_idx = globals.selected_node - l = globals.node_list select_func = select_node if win == 0: start_idx = globals.selected_channel - l = globals.channel_list select_func = select_channel search_text = "" @@ -409,6 +407,7 @@ def search(win): search_text_caseless = search_text.casefold() + l = globals.node_list if win == 2 else globals.channel_list for i, n in enumerate(l[start_idx:] + l[:start_idx]): if isinstance(n, int) and search_text_caseless in get_name_from_database(n, 'long').casefold() \ or isinstance(n, int) and search_text_caseless in get_name_from_database(n, 'short').casefold() \