From 42ca1e0eeb1e9f315dfe9b4129462a6780827cf1 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Tue, 28 Apr 2020 07:44:32 -0300 Subject: [PATCH] Fixing selections. --- src/core/actions/table.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/bounds.c | 2 +- src/core/cursor.c | 32 ++++++++++++++++++++++++++------ src/include/internals.h | 2 +- src/selection/actions.c | 3 +-- src/selection/selection.c | 11 +++++++---- 6 files changed, 112 insertions(+), 14 deletions(-) diff --git a/src/core/actions/table.c b/src/core/actions/table.c index 7a3c5a9..5d391a8 100644 --- a/src/core/actions/table.c +++ b/src/core/actions/table.c @@ -51,6 +51,26 @@ return lib3270_reconnect(hSession,0); } + static int select_up(H3270 *hSession) + { + return lib3270_move_cursor(hSession,LIB3270_DIR_UP,1); + } + + static int select_down(H3270 *hSession) + { + return lib3270_move_cursor(hSession,LIB3270_DIR_DOWN,1); + } + + static int select_left(H3270 *hSession) + { + return lib3270_move_cursor(hSession,LIB3270_DIR_LEFT,1); + } + + static int select_right(H3270 *hSession) + { + return lib3270_move_cursor(hSession,LIB3270_DIR_RIGHT,1); + } + /** * @brief Get LIB3270 action table; * @@ -265,6 +285,62 @@ .activatable = lib3270_is_connected }, + { + .name = "select-up", + .type = LIB3270_ACTION_TYPE_SELECTION, + + .keys = "Up", + .icon = NULL, + .label = N_( "Move cursor up and select" ), + .summary = NULL, + .activate = select_up, + + .group = LIB3270_ACTION_GROUP_ONLINE, + .activatable = lib3270_is_connected + }, + + { + .name = "select-down", + .type = LIB3270_ACTION_TYPE_SELECTION, + + .keys = "Down", + .icon = NULL, + .label = N_( "Move cursor down and select" ), + .summary = NULL, + .activate = select_down, + + .group = LIB3270_ACTION_GROUP_ONLINE, + .activatable = lib3270_is_connected + }, + + { + .name = "select-left", + .type = LIB3270_ACTION_TYPE_SELECTION, + + .keys = "Left", + .icon = NULL, + .label = N_( "Move cursor left and select" ), + .summary = NULL, + .activate = select_left, + + .group = LIB3270_ACTION_GROUP_ONLINE, + .activatable = lib3270_is_connected + }, + + { + .name = "select-right", + .type = LIB3270_ACTION_TYPE_SELECTION, + + .keys = "Right", + .icon = NULL, + .label = N_( "Move cursor rigth and select" ), + .summary = NULL, + .activate = select_right, + + .group = LIB3270_ACTION_GROUP_ONLINE, + .activatable = lib3270_is_connected + }, + // // Field actions. // diff --git a/src/core/bounds.c b/src/core/bounds.c index 1adc221..578bc8a 100644 --- a/src/core/bounds.c +++ b/src/core/bounds.c @@ -79,7 +79,7 @@ LIB3270_EXPORT int lib3270_get_word_bounds(H3270 *session, int baddr, int *start if(baddr < 0) baddr = lib3270_get_cursor_address(session); - if(baddr > lib3270_get_length(session)) { + if(baddr > (int) lib3270_get_length(session)) { return errno = EINVAL; } diff --git a/src/core/cursor.c b/src/core/cursor.c index adb1929..03b040c 100644 --- a/src/core/cursor.c +++ b/src/core/cursor.c @@ -79,8 +79,6 @@ static int cursor_end(H3270 *hSession); */ LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, unsigned char sel) { - int select_from = -1; - FAIL_IF_NOT_ONLINE(hSession); if(dir < 0 || dir >= LIB3270_DIR_COUNT) @@ -106,18 +104,40 @@ LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, u } } - if(sel) { - select_from = (hSession->selected ? hSession->select.start : hSession->cursor_addr); - } + // Save last cursor position + int saved_cursor = hSession->cursor_addr; int rc = calls[dir].exec(hSession); if(rc) return rc; if(sel) - lib3270_select_region(hSession, select_from, hSession->cursor_addr); + { + if(hSession->cursor_addr < saved_cursor) + { + // Moved back + lib3270_select_region( + hSession, + hSession->cursor_addr, + ((hSession->selected ? hSession->select.end : saved_cursor)) + ); + + } + else + { + // Moved forward + lib3270_select_region( + hSession, + ((hSession->selected ? hSession->select.start : saved_cursor)), + hSession->cursor_addr + ); + } + + } else if(hSession->selected && !lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_SELECTED)) + { lib3270_unselect(hSession); + } return 0; } diff --git a/src/include/internals.h b/src/include/internals.h index af58e53..d43e332 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -741,7 +741,7 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block); -LIB3270_INTERNAL void do_select(H3270 *h, unsigned int start, unsigned int end, unsigned int rect); +LIB3270_INTERNAL int do_select(H3270 *h, unsigned int start, unsigned int end, unsigned int rect); /** diff --git a/src/selection/actions.c b/src/selection/actions.c index 164c777..cdf3f7c 100644 --- a/src/selection/actions.c +++ b/src/selection/actions.c @@ -100,11 +100,10 @@ LIB3270_EXPORT int lib3270_select_region(H3270 *h, int start, int end) maxlen = (h->view.rows * h->view.cols); // Check bounds - if(start < 0 || start > maxlen || end < 0 || end > maxlen || start > end) + if(start < 0 || start > maxlen || end < 0 || end > maxlen) return EINVAL; do_select(h,start,end,lib3270_get_toggle(h,LIB3270_TOGGLE_RECTANGLE_SELECT)); - cursor_move(h,h->select.end); return 0; } diff --git a/src/selection/selection.c b/src/selection/selection.c index de8ec73..5794914 100644 --- a/src/selection/selection.c +++ b/src/selection/selection.c @@ -167,14 +167,16 @@ void toggle_rectselect(H3270 *hSession, const struct lib3270_toggle *t, LIB3270_ update_selected_region(hSession); } -void do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned int rect) +int do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned int rect) { - if(end > (hSession->view.rows * hSession->view.cols)) - return; + unsigned int length = (hSession->view.rows * hSession->view.cols); + + if(end > length || start > length) + return errno = EINVAL; // Do we really need to change selection? if( ((int) start) == hSession->select.start && ((int) end) == hSession->select.end && hSession->selected) - return; + return 0; // Start address is inside the screen? hSession->select.start = start; @@ -200,6 +202,7 @@ void do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned i hSession->cbk.update_selection(hSession,start,end); + return 0; } LIB3270_EXPORT unsigned char lib3270_get_selection_flags(H3270 *hSession, int baddr) -- libgit2 0.21.2