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 | 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 | 75 | * @brief Get LIB3270 action table; |
| 56 | 76 | * |
| ... | ... | @@ -265,6 +285,62 @@ |
| 265 | 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 | 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 | 79 | if(baddr < 0) |
| 80 | 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 | 83 | return errno = EINVAL; |
| 84 | 84 | } |
| 85 | 85 | ... | ... |
src/core/cursor.c
| ... | ... | @@ -79,8 +79,6 @@ static int cursor_end(H3270 *hSession); |
| 79 | 79 | */ |
| 80 | 80 | LIB3270_EXPORT int lib3270_move_cursor(H3270 *hSession, LIB3270_DIRECTION dir, unsigned char sel) |
| 81 | 81 | { |
| 82 | - int select_from = -1; | |
| 83 | - | |
| 84 | 82 | FAIL_IF_NOT_ONLINE(hSession); |
| 85 | 83 | |
| 86 | 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 | 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 | 110 | int rc = calls[dir].exec(hSession); |
| 114 | 111 | if(rc) |
| 115 | 112 | return rc; |
| 116 | 113 | |
| 117 | 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 | 137 | else if(hSession->selected && !lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_SELECTED)) |
| 138 | + { | |
| 120 | 139 | lib3270_unselect(hSession); |
| 140 | + } | |
| 121 | 141 | |
| 122 | 142 | return 0; |
| 123 | 143 | } | ... | ... |
src/include/internals.h
| ... | ... | @@ -741,7 +741,7 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); |
| 741 | 741 | |
| 742 | 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 | 100 | maxlen = (h->view.rows * h->view.cols); |
| 101 | 101 | |
| 102 | 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 | 104 | return EINVAL; |
| 105 | 105 | |
| 106 | 106 | do_select(h,start,end,lib3270_get_toggle(h,LIB3270_TOGGLE_RECTANGLE_SELECT)); |
| 107 | - cursor_move(h,h->select.end); | |
| 108 | 107 | |
| 109 | 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 | 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 | 177 | // Do we really need to change selection? |
| 176 | 178 | if( ((int) start) == hSession->select.start && ((int) end) == hSession->select.end && hSession->selected) |
| 177 | - return; | |
| 179 | + return 0; | |
| 178 | 180 | |
| 179 | 181 | // Start address is inside the screen? |
| 180 | 182 | hSession->select.start = start; |
| ... | ... | @@ -200,6 +202,7 @@ void do_select(H3270 *hSession, unsigned int start, unsigned int end, unsigned i |
| 200 | 202 | |
| 201 | 203 | hSession->cbk.update_selection(hSession,start,end); |
| 202 | 204 | |
| 205 | + return 0; | |
| 203 | 206 | } |
| 204 | 207 | |
| 205 | 208 | LIB3270_EXPORT unsigned char lib3270_get_selection_flags(H3270 *hSession, int baddr) | ... | ... |