Commit 42ca1e0eeb1e9f315dfe9b4129462a6780827cf1
1 parent
66f3ee00
Exists in
master
and in
3 other branches
Fixing selections.
Showing
6 changed files
with
112 additions
and
14 deletions
Show diff stats
src/core/actions/table.c
| @@ -51,6 +51,26 @@ | @@ -51,6 +51,26 @@ | ||
| 51 | return lib3270_reconnect(hSession,0); | 51 | return lib3270_reconnect(hSession,0); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | + static int select_up(H3270 *hSession) | ||
| 55 | + { | ||
| 56 | + return lib3270_move_cursor(hSession,LIB3270_DIR_UP,1); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + static int select_down(H3270 *hSession) | ||
| 60 | + { | ||
| 61 | + return lib3270_move_cursor(hSession,LIB3270_DIR_DOWN,1); | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + static int select_left(H3270 *hSession) | ||
| 65 | + { | ||
| 66 | + return lib3270_move_cursor(hSession,LIB3270_DIR_LEFT,1); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + static int select_right(H3270 *hSession) | ||
| 70 | + { | ||
| 71 | + return lib3270_move_cursor(hSession,LIB3270_DIR_RIGHT,1); | ||
| 72 | + } | ||
| 73 | + | ||
| 54 | /** | 74 | /** |
| 55 | * @brief Get LIB3270 action table; | 75 | * @brief Get LIB3270 action table; |
| 56 | * | 76 | * |
| @@ -265,6 +285,62 @@ | @@ -265,6 +285,62 @@ | ||
| 265 | .activatable = lib3270_is_connected | 285 | .activatable = lib3270_is_connected |
| 266 | }, | 286 | }, |
| 267 | 287 | ||
| 288 | + { | ||
| 289 | + .name = "select-up", | ||
| 290 | + .type = LIB3270_ACTION_TYPE_SELECTION, | ||
| 291 | + | ||
| 292 | + .keys = "<Shift>Up", | ||
| 293 | + .icon = NULL, | ||
| 294 | + .label = N_( "Move cursor up and select" ), | ||
| 295 | + .summary = NULL, | ||
| 296 | + .activate = select_up, | ||
| 297 | + | ||
| 298 | + .group = LIB3270_ACTION_GROUP_ONLINE, | ||
| 299 | + .activatable = lib3270_is_connected | ||
| 300 | + }, | ||
| 301 | + | ||
| 302 | + { | ||
| 303 | + .name = "select-down", | ||
| 304 | + .type = LIB3270_ACTION_TYPE_SELECTION, | ||
| 305 | + | ||
| 306 | + .keys = "<Shift>Down", | ||
| 307 | + .icon = NULL, | ||
| 308 | + .label = N_( "Move cursor down and select" ), | ||
| 309 | + .summary = NULL, | ||
| 310 | + .activate = select_down, | ||
| 311 | + | ||
| 312 | + .group = LIB3270_ACTION_GROUP_ONLINE, | ||
| 313 | + .activatable = lib3270_is_connected | ||
| 314 | + }, | ||
| 315 | + | ||
| 316 | + { | ||
| 317 | + .name = "select-left", | ||
| 318 | + .type = LIB3270_ACTION_TYPE_SELECTION, | ||
| 319 | + | ||
| 320 | + .keys = "<Shift>Left", | ||
| 321 | + .icon = NULL, | ||
| 322 | + .label = N_( "Move cursor left and select" ), | ||
| 323 | + .summary = NULL, | ||
| 324 | + .activate = select_left, | ||
| 325 | + | ||
| 326 | + .group = LIB3270_ACTION_GROUP_ONLINE, | ||
| 327 | + .activatable = lib3270_is_connected | ||
| 328 | + }, | ||
| 329 | + | ||
| 330 | + { | ||
| 331 | + .name = "select-right", | ||
| 332 | + .type = LIB3270_ACTION_TYPE_SELECTION, | ||
| 333 | + | ||
| 334 | + .keys = "<Shift>Right", | ||
| 335 | + .icon = NULL, | ||
| 336 | + .label = N_( "Move cursor rigth and select" ), | ||
| 337 | + .summary = NULL, | ||
| 338 | + .activate = select_right, | ||
| 339 | + | ||
| 340 | + .group = LIB3270_ACTION_GROUP_ONLINE, | ||
| 341 | + .activatable = lib3270_is_connected | ||
| 342 | + }, | ||
| 343 | + | ||
| 268 | // | 344 | // |
| 269 | // Field actions. | 345 | // Field actions. |
| 270 | // | 346 | // |
src/core/bounds.c
| @@ -79,7 +79,7 @@ LIB3270_EXPORT int lib3270_get_word_bounds(H3270 *session, int baddr, int *start | @@ -79,7 +79,7 @@ LIB3270_EXPORT int lib3270_get_word_bounds(H3270 *session, int baddr, int *start | ||
| 79 | if(baddr < 0) | 79 | if(baddr < 0) |
| 80 | baddr = lib3270_get_cursor_address(session); | 80 | baddr = lib3270_get_cursor_address(session); |
| 81 | 81 | ||
| 82 | - if(baddr > lib3270_get_length(session)) { | 82 | + if(baddr > (int) lib3270_get_length(session)) { |
| 83 | return errno = EINVAL; | 83 | return errno = EINVAL; |
| 84 | } | 84 | } |
| 85 | 85 |
src/core/cursor.c
| @@ -79,8 +79,6 @@ static int cursor_end(H3270 *hSession); | @@ -79,8 +79,6 @@ static int cursor_end(H3270 *hSession); | ||
| 79 | */ | 79 | */ |
| 80 | LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, unsigned char sel) | 80 | LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, unsigned char sel) |
| 81 | { | 81 | { |
| 82 | - int select_from = -1; | ||
| 83 | - | ||
| 84 | FAIL_IF_NOT_ONLINE(hSession); | 82 | FAIL_IF_NOT_ONLINE(hSession); |
| 85 | 83 | ||
| 86 | if(dir < 0 || dir >= LIB3270_DIR_COUNT) | 84 | if(dir < 0 || dir >= LIB3270_DIR_COUNT) |
| @@ -106,18 +104,40 @@ LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, u | @@ -106,18 +104,40 @@ LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, u | ||
| 106 | } | 104 | } |
| 107 | } | 105 | } |
| 108 | 106 | ||
| 109 | - if(sel) { | ||
| 110 | - select_from = (hSession->selected ? hSession->select.start : hSession->cursor_addr); | ||
| 111 | - } | 107 | + // Save last cursor position |
| 108 | + int saved_cursor = hSession->cursor_addr; | ||
| 112 | 109 | ||
| 113 | int rc = calls[dir].exec(hSession); | 110 | int rc = calls[dir].exec(hSession); |
| 114 | if(rc) | 111 | if(rc) |
| 115 | return rc; | 112 | return rc; |
| 116 | 113 | ||
| 117 | if(sel) | 114 | if(sel) |
| 118 | - lib3270_select_region(hSession, select_from, hSession->cursor_addr); | 115 | + { |
| 116 | + if(hSession->cursor_addr < saved_cursor) | ||
| 117 | + { | ||
| 118 | + // Moved back | ||
| 119 | + lib3270_select_region( | ||
| 120 | + hSession, | ||
| 121 | + hSession->cursor_addr, | ||
| 122 | + ((hSession->selected ? hSession->select.end : saved_cursor)) | ||
| 123 | + ); | ||
| 124 | + | ||
| 125 | + } | ||
| 126 | + else | ||
| 127 | + { | ||
| 128 | + // Moved forward | ||
| 129 | + lib3270_select_region( | ||
| 130 | + hSession, | ||
| 131 | + ((hSession->selected ? hSession->select.start : saved_cursor)), | ||
| 132 | + hSession->cursor_addr | ||
| 133 | + ); | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + } | ||
| 119 | else if(hSession->selected && !lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_SELECTED)) | 137 | else if(hSession->selected && !lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_SELECTED)) |
| 138 | + { | ||
| 120 | lib3270_unselect(hSession); | 139 | lib3270_unselect(hSession); |
| 140 | + } | ||
| 121 | 141 | ||
| 122 | return 0; | 142 | return 0; |
| 123 | } | 143 | } |
src/include/internals.h
| @@ -741,7 +741,7 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); | @@ -741,7 +741,7 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); | ||
| 741 | 741 | ||
| 742 | LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block); | 742 | LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block); |
| 743 | 743 | ||
| 744 | -LIB3270_INTERNAL void do_select(H3270 *h, unsigned int start, unsigned int end, unsigned int rect); | 744 | +LIB3270_INTERNAL int do_select(H3270 *h, unsigned int start, unsigned int end, unsigned int rect); |
| 745 | 745 | ||
| 746 | 746 | ||
| 747 | /** | 747 | /** |
src/selection/actions.c
| @@ -100,11 +100,10 @@ LIB3270_EXPORT int lib3270_select_region(H3270 *h, int start, int end) | @@ -100,11 +100,10 @@ LIB3270_EXPORT int lib3270_select_region(H3270 *h, int start, int end) | ||
| 100 | maxlen = (h->view.rows * h->view.cols); | 100 | maxlen = (h->view.rows * h->view.cols); |
| 101 | 101 | ||
| 102 | // Check bounds | 102 | // Check bounds |
| 103 | - if(start < 0 || start > maxlen || end < 0 || end > maxlen || start > end) | 103 | + if(start < 0 || start > maxlen || end < 0 || end > maxlen) |
| 104 | return EINVAL; | 104 | return EINVAL; |
| 105 | 105 | ||
| 106 | do_select(h,start,end,lib3270_get_toggle(h,LIB3270_TOGGLE_RECTANGLE_SELECT)); | 106 | do_select(h,start,end,lib3270_get_toggle(h,LIB3270_TOGGLE_RECTANGLE_SELECT)); |
| 107 | - cursor_move(h,h->select.end); | ||
| 108 | 107 | ||
| 109 | return 0; | 108 | return 0; |
| 110 | } | 109 | } |
src/selection/selection.c
| @@ -167,14 +167,16 @@ void toggle_rectselect(H3270 *hSession, const struct lib3270_toggle *t, LIB3270_ | @@ -167,14 +167,16 @@ void toggle_rectselect(H3270 *hSession, const struct lib3270_toggle *t, LIB3270_ | ||
| 167 | update_selected_region(hSession); | 167 | update_selected_region(hSession); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | -void do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned int rect) | 170 | +int do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned int rect) |
| 171 | { | 171 | { |
| 172 | - if(end > (hSession->view.rows * hSession->view.cols)) | ||
| 173 | - return; | 172 | + unsigned int length = (hSession->view.rows * hSession->view.cols); |
| 173 | + | ||
| 174 | + if(end > length || start > length) | ||
| 175 | + return errno = EINVAL; | ||
| 174 | 176 | ||
| 175 | // Do we really need to change selection? | 177 | // Do we really need to change selection? |
| 176 | if( ((int) start) == hSession->select.start && ((int) end) == hSession->select.end && hSession->selected) | 178 | if( ((int) start) == hSession->select.start && ((int) end) == hSession->select.end && hSession->selected) |
| 177 | - return; | 179 | + return 0; |
| 178 | 180 | ||
| 179 | // Start address is inside the screen? | 181 | // Start address is inside the screen? |
| 180 | hSession->select.start = start; | 182 | hSession->select.start = start; |
| @@ -200,6 +202,7 @@ void do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned i | @@ -200,6 +202,7 @@ void do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned i | ||
| 200 | 202 | ||
| 201 | hSession->cbk.update_selection(hSession,start,end); | 203 | hSession->cbk.update_selection(hSession,start,end); |
| 202 | 204 | ||
| 205 | + return 0; | ||
| 203 | } | 206 | } |
| 204 | 207 | ||
| 205 | LIB3270_EXPORT unsigned char lib3270_get_selection_flags(H3270 *hSession, int baddr) | 208 | LIB3270_EXPORT unsigned char lib3270_get_selection_flags(H3270 *hSession, int baddr) |