Commit 42ca1e0eeb1e9f315dfe9b4129462a6780827cf1

Authored by Perry Werneck
1 parent 66f3ee00

Fixing selections.

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