From 3b80f256bac0842f4470f9d5361426d7cff88ea9 Mon Sep 17 00:00:00 2001 From: Chris Davis Date: Sun, 10 Aug 2014 18:26:14 -0700 Subject: [PATCH] regedit: handle pgup/pgdn/home/end keys on lists Signed-off-by: Chris Davis Reviewed-by: Andreas Schneider Reviewed-by: Michael Adam --- source3/utils/regedit.c | 28 +++++++++++++++ source3/utils/regedit_list.c | 69 +++++++++++++++++++++++++++++++++--- source3/utils/regedit_list.h | 6 +++- 3 files changed, 98 insertions(+), 5 deletions(-) diff --git a/source3/utils/regedit.c b/source3/utils/regedit.c index 34a63d74fd2..9cb4fca3405 100644 --- a/source3/utils/regedit.c +++ b/source3/utils/regedit.c @@ -378,6 +378,22 @@ static void handle_tree_input(struct regedit *regedit, int c) tree_view_driver(regedit->keys, ML_CURSOR_UP); load_values(regedit); break; + case KEY_NPAGE: + tree_view_driver(regedit->keys, ML_CURSOR_PGDN); + load_values(regedit); + break; + case KEY_PPAGE: + tree_view_driver(regedit->keys, ML_CURSOR_PGUP); + load_values(regedit); + break; + case KEY_HOME: + tree_view_driver(regedit->keys, ML_CURSOR_HOME); + load_values(regedit); + break; + case KEY_END: + tree_view_driver(regedit->keys, ML_CURSOR_END); + load_values(regedit); + break; case '\n': case KEY_ENTER: case KEY_RIGHT: @@ -476,6 +492,18 @@ static void handle_value_input(struct regedit *regedit, int c) case KEY_UP: value_list_driver(regedit->vl, ML_CURSOR_UP); break; + case KEY_NPAGE: + value_list_driver(regedit->vl, ML_CURSOR_PGDN); + break; + case KEY_PPAGE: + value_list_driver(regedit->vl, ML_CURSOR_PGUP); + break; + case KEY_HOME: + value_list_driver(regedit->vl, ML_CURSOR_HOME); + break; + case KEY_END: + value_list_driver(regedit->vl, ML_CURSOR_END); + break; case 'b': case 'B': binmode = true; diff --git a/source3/utils/regedit_list.c b/source3/utils/regedit_list.c index ac4e24091c9..c2b37052848 100644 --- a/source3/utils/regedit_list.c +++ b/source3/utils/regedit_list.c @@ -405,21 +405,33 @@ WERROR multilist_set_data(struct multilist *list, const void *data) return WERR_OK; } +static int get_window_height(struct multilist *list) +{ + int height; + + height = list->window_height; + if (list->cb->get_column_header) { + height--; + } + + return height; +} + static void fix_start_row(struct multilist *list) { int height; /* adjust start_row so that the cursor appears on the screen */ - height = list->window_height; - if (list->cb->get_column_header) { - height--; - } + height = get_window_height(list); if (list->cursor_row < list->start_row) { list->start_row = list->cursor_row; } else if (list->cursor_row >= list->start_row + height) { list->start_row = list->cursor_row - height + 1; } + if (list->nrows > height && list->nrows - list->start_row < height) { + list->start_row = list->nrows - height; + } } WERROR multilist_set_window(struct multilist *list, WINDOW *window) @@ -457,6 +469,10 @@ void multilist_refresh(struct multilist *list) { int window_start_row, height; + if (list->nrows == 0) { + return; + } + /* copy from pad, starting at start_row, to the window, accounting for the column header (if present). */ height = MIN(list->window_height, list->nrows); @@ -474,6 +490,7 @@ void multilist_refresh(struct multilist *list) void multilist_driver(struct multilist *list, int c) { + unsigned page; const void *tmp; if (list->nrows == 0) { @@ -497,6 +514,50 @@ void multilist_driver(struct multilist *list, int c) list->cursor_row++; tmp = data_get_next_row(list, list->current_row); break; + case ML_CURSOR_PGUP: + if (list->cursor_row == 0) { + return; + } + unhighlight_current_row(list); + page = get_window_height(list); + if (page > list->cursor_row) { + list->cursor_row = 0; + } else { + list->cursor_row -= page; + list->start_row -= page; + } + tmp = data_get_row_n(list, list->cursor_row); + break; + case ML_CURSOR_PGDN: + if (list->cursor_row == list->nrows - 1) { + return; + } + unhighlight_current_row(list); + page = get_window_height(list); + if (page > list->nrows - list->cursor_row - 1) { + list->cursor_row = list->nrows - 1; + } else { + list->cursor_row += page; + list->start_row += page; + } + tmp = data_get_row_n(list, list->cursor_row); + break; + case ML_CURSOR_HOME: + if (list->cursor_row == 0) { + return; + } + unhighlight_current_row(list); + list->cursor_row = 0; + tmp = data_get_row_n(list, list->cursor_row); + break; + case ML_CURSOR_END: + if (list->cursor_row == list->nrows - 1) { + return; + } + unhighlight_current_row(list); + list->cursor_row = list->nrows - 1; + tmp = data_get_row_n(list, list->cursor_row); + break; } SMB_ASSERT(tmp); diff --git a/source3/utils/regedit_list.h b/source3/utils/regedit_list.h index 4b1840adfad..abd6ffd23e6 100644 --- a/source3/utils/regedit_list.h +++ b/source3/utils/regedit_list.h @@ -69,7 +69,11 @@ void multilist_refresh(struct multilist *list); enum { ML_CURSOR_UP, - ML_CURSOR_DOWN + ML_CURSOR_DOWN, + ML_CURSOR_PGUP, + ML_CURSOR_PGDN, + ML_CURSOR_HOME, + ML_CURSOR_END }; void multilist_driver(struct multilist *list, int c); const void *multilist_get_current_row(struct multilist *list);