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