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) |