Mercurial > 510Connectbot
comparison app/src/main/java/org/tn5250j/framework/tn5250/ScreenFields.java @ 438:d29cce60f393
migrate from Eclipse to Android Studio
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 03 Dec 2015 11:23:55 -0800 |
parents | src/org/tn5250j/framework/tn5250/ScreenFields.java@77ac18bc1b2f |
children |
comparison
equal
deleted
inserted
replaced
437:208b31032318 | 438:d29cce60f393 |
---|---|
1 /** | |
2 * Title: tn5250J | |
3 * Copyright: Copyright (c) 2001 | |
4 * Company: | |
5 * @author Kenneth J. Pouncey | |
6 * @version 0.5 | |
7 * | |
8 * Description: | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2, or (at your option) | |
13 * any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this software; see the file COPYING. If not, write to | |
22 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |
23 * Boston, MA 02111-1307 USA | |
24 * | |
25 */ | |
26 package org.tn5250j.framework.tn5250; | |
27 | |
28 import static org.tn5250j.TN5250jConstants.CMD_READ_INPUT_FIELDS; | |
29 import static org.tn5250j.TN5250jConstants.CMD_READ_MDT_FIELDS; | |
30 import static org.tn5250j.TN5250jConstants.CMD_READ_MDT_IMMEDIATE_ALT; | |
31 | |
32 import java.io.ByteArrayOutputStream; | |
33 | |
34 import org.tn5250j.encoding.ICodePage; | |
35 | |
36 public class ScreenFields { | |
37 | |
38 private ScreenField[] screenFields; | |
39 private ScreenField currentField; | |
40 private ScreenField saveCurrent; | |
41 private int sizeFields; | |
42 private boolean cpfExists; | |
43 private int nextField; | |
44 private int fieldIds; | |
45 private Screen5250 screen; | |
46 private boolean masterMDT; | |
47 protected boolean currentModified; | |
48 | |
49 public ScreenFields(Screen5250 s) { | |
50 screen = s; | |
51 screenFields = new ScreenField[256]; | |
52 } | |
53 | |
54 protected void clearFFT() { | |
55 sizeFields = nextField = fieldIds = 0; | |
56 cpfExists = false; // clear the cursor progression fields flag | |
57 currentField = null; | |
58 masterMDT = false; | |
59 } | |
60 | |
61 protected boolean existsAtPos(int lastPos) { | |
62 ScreenField sf = null; | |
63 | |
64 // from 14.6.12 for Start of Field Order 5940 function manual | |
65 // examine the format table for an entry that begins at the current | |
66 // starting address plus 1. | |
67 for (int x = 0; x < sizeFields; x++) { | |
68 sf = screenFields[x]; | |
69 | |
70 if (lastPos == sf.startPos()) { | |
71 currentField = sf; | |
72 currentModified = false; | |
73 return true; | |
74 } | |
75 } | |
76 | |
77 return false; | |
78 } | |
79 | |
80 public boolean isMasterMDT() { | |
81 return masterMDT; | |
82 } | |
83 | |
84 protected void setMasterMDT() { | |
85 masterMDT = true; | |
86 } | |
87 | |
88 public boolean isCurrentField() { | |
89 return currentField == null; | |
90 } | |
91 | |
92 public boolean isCurrentFieldFER() { | |
93 return currentField.isFER(); | |
94 } | |
95 | |
96 public boolean isCurrentFieldDupEnabled() { | |
97 return currentField.isDupEnabled(); | |
98 } | |
99 | |
100 public boolean isCurrentFieldToUpper() { | |
101 return currentField.isToUpper(); | |
102 } | |
103 | |
104 public boolean isCurrentFieldBypassField() { | |
105 return currentField.isBypassField(); | |
106 } | |
107 | |
108 public boolean isCurrentFieldHighlightedEntry() { | |
109 if (currentField != null) | |
110 return currentField.isHiglightedEntry(); | |
111 else | |
112 return false; | |
113 } | |
114 | |
115 public boolean isCurrentFieldAutoEnter() { | |
116 return currentField.isAutoEnter(); | |
117 } | |
118 | |
119 public boolean withinCurrentField(int pos) { | |
120 return currentField.withinField(pos); | |
121 } | |
122 | |
123 public boolean isCurrentFieldContinued() { | |
124 return currentField.isContinued(); | |
125 } | |
126 | |
127 public boolean isCurrentFieldContinuedFirst() { | |
128 return currentField.isContinuedFirst(); | |
129 } | |
130 | |
131 public boolean isCurrentFieldContinuedMiddle() { | |
132 return currentField.isContinuedMiddle(); | |
133 } | |
134 | |
135 public boolean isCurrentFieldContinuedLast() { | |
136 return currentField.isContinuedLast(); | |
137 } | |
138 | |
139 public boolean isCurrentFieldModified() { | |
140 return currentModified; | |
141 } | |
142 | |
143 /** | |
144 * This routine is used to check if we can send the Aid key to the host | |
145 * | |
146 * Taken from Section 16.2.1.2 Enter/Rec Adv Key | |
147 * | |
148 * In the normal unlocked state, when the workstation operator presses the | |
149 * Enter/Rec Adv key: | |
150 * | |
151 * 1. The 5494 checks for the completion of mandatory-fill, self-check, and | |
152 * right-adjust fields when in an active field. (An active field is one in | |
153 * which the workstation operator has begun entering data.) If the | |
154 * requirements of the field have not been satisfied, an error occurs. | |
155 * | |
156 * @return | |
157 * | |
158 */ | |
159 public boolean isCanSendAid() { | |
160 // We also have to check if we are still in the field. | |
161 if (currentField != null && | |
162 (currentField.getAdjustment() > 0 || currentField.isSignedNumeric()) | |
163 && currentModified && isInField() | |
164 && !currentField.isCanSend()) | |
165 return false; | |
166 else | |
167 return true; | |
168 } | |
169 | |
170 protected void saveCurrentField() { | |
171 saveCurrent = currentField; | |
172 } | |
173 | |
174 protected void restoreCurrentField() { | |
175 currentField = saveCurrent; | |
176 } | |
177 | |
178 protected void setCurrentField(ScreenField sf) { | |
179 currentField = sf; | |
180 } | |
181 | |
182 protected void setCurrentFieldMDT() { | |
183 currentField.setMDT(); | |
184 currentModified = true; | |
185 masterMDT = true; | |
186 } | |
187 | |
188 protected void setCurrentFieldFFWs(int ffw1, int ffw2) { | |
189 masterMDT = currentField.setFFWs(ffw1, ffw2); | |
190 } | |
191 | |
192 | |
193 protected ScreenField setField(int attr, int row, int col, int len, int ffw1, | |
194 int ffw2, int fcw1, int fcw2) { | |
195 ScreenField sf = null; | |
196 screenFields[nextField] = new ScreenField(screen); | |
197 screenFields[nextField].setField(attr, row, col, len, ffw1, ffw2, fcw1, fcw2); | |
198 sf = screenFields[nextField++]; | |
199 sizeFields++; | |
200 // set the field id if it is not a bypass field | |
201 // this is used for cursor progression | |
202 // changed this because of problems not allocating field id's for | |
203 // all fields. kjp 2002/10/21 | |
204 // if (!sf.isBypassField()) | |
205 sf.setFieldId(++fieldIds); | |
206 | |
207 // check if the cursor progression field flag should be set. | |
208 // if ((fcw1 & 0x88) == 0x88) | |
209 if (fcw1 == 0x88) | |
210 cpfExists = true; | |
211 | |
212 if (currentField != null) { | |
213 currentField.next = sf; | |
214 sf.prev = currentField; | |
215 } | |
216 | |
217 currentField = sf; | |
218 | |
219 // check if the Modified Data Tag was set while creating the field | |
220 if (!masterMDT) | |
221 masterMDT = currentField.mdt; | |
222 | |
223 currentModified = false; | |
224 return currentField; | |
225 } | |
226 | |
227 public ScreenField getField(int index) { | |
228 return screenFields[index]; | |
229 } | |
230 | |
231 public ScreenField getCurrentField() { | |
232 return currentField; | |
233 } | |
234 | |
235 public int getCurrentFieldPos() { | |
236 return currentField.getCurrentPos(); | |
237 } | |
238 | |
239 protected int getCurrentFieldShift() { | |
240 return currentField.getFieldShift(); | |
241 } | |
242 | |
243 public String getCurrentFieldText() { | |
244 return currentField.getText(); | |
245 } | |
246 | |
247 public int getCurrentFieldHighlightedAttr() { | |
248 return currentField.getHighlightedAttr(); | |
249 } | |
250 | |
251 public int getSize() { | |
252 return sizeFields; | |
253 } | |
254 | |
255 public int getFieldCount() { | |
256 return sizeFields; | |
257 } | |
258 | |
259 protected boolean isInField(int pos) { | |
260 return isInField(pos, true); | |
261 } | |
262 | |
263 protected boolean isInField() { | |
264 return isInField(screen.getLastPos(), true); | |
265 } | |
266 | |
267 protected boolean isInField(int pos, boolean chgToField) { | |
268 ScreenField sf; | |
269 | |
270 for (int x = 0; x < sizeFields; x++) { | |
271 sf = screenFields[x]; | |
272 | |
273 if (sf.withinField(pos)) { | |
274 if (chgToField) { | |
275 if (!currentField.equals(sf)) | |
276 currentModified = false; | |
277 | |
278 currentField = sf; | |
279 } | |
280 | |
281 return true; | |
282 } | |
283 } | |
284 | |
285 return false; | |
286 } | |
287 | |
288 /** | |
289 * Searches the collection for the target string and returns the iOhioField | |
290 * object containing that string. The string must be totally contained | |
291 * within the field to be considered a match. | |
292 * | |
293 * @param targetString The target string. | |
294 * @param startPos The row and column where to start the search. The position | |
295 * is inclusive (for example, row 1, col 1 means that | |
296 * position 1,1 will be used as the starting location and | |
297 * 1,1 will be included in the search). | |
298 * @param length The length from startPos to include in the search. | |
299 * @param dir An OHIO_DIRECTION value: | |
300 * | |
301 * <table BORDER COLS=3 WIDTH="50%" > | |
302 * <tr><th>Constant </th><th>Value</th> | |
303 * <th>Description</th></tr> | |
304 * <tr><td>OS_OHIO_DIRECTION_FORWARD </td><td>0</td> | |
305 * <td>Forward (beginning towards end)</td></tr> | |
306 * <tr><td>OS_OHIO_DIRECTION_BACKWARD </td><td>1</td> | |
307 * <td>Backward (end towards beginning)</td></tr> | |
308 * </table> | |
309 * Constant Value Description | |
310 * ignoreCase - Indicates whether the search is case sensitive. | |
311 * True means that case will be ignored. False means the search will | |
312 * be case sensitive. | |
313 * @return If found, an iOhioField object containing the target string. If | |
314 * not found, returns a null. | |
315 */ | |
316 public ScreenField findByString(String targetString, | |
317 int startPos, | |
318 int length, | |
319 int dir, | |
320 boolean ignoreCase) { | |
321 // first lets check if the string exists in the screen space | |
322 // iOhioPosition pos = screen.findString(targetString, startPos, length, | |
323 // dir, ignoreCase); | |
324 // if it does exist then lets search the fields by the position that | |
325 // was found and return the results of that search. | |
326 // if (pos != null) { | |
327 return findByPosition(startPos); | |
328 // } | |
329 //return null; | |
330 } | |
331 | |
332 /** | |
333 * Searches the collection for the target position and returns the ScreenField | |
334 * object containing that position. | |
335 * | |
336 * @param targetPosition The target row and column expressed as a linear | |
337 * position within the presentation space. | |
338 * | |
339 * @return If found, a ScreenField object containing the target position. | |
340 * If not found, returns a null. | |
341 */ | |
342 public ScreenField findByPosition(int targetPosition) { | |
343 ScreenField sf = null; | |
344 | |
345 for (int x = 0; x < sizeFields; x++) { | |
346 sf = screenFields[x]; | |
347 | |
348 if (sf.withinField(targetPosition)) { | |
349 return sf; | |
350 } | |
351 } | |
352 | |
353 return null; | |
354 } | |
355 | |
356 /** | |
357 * Searches the collection for the target position and returns the ScreenField | |
358 * object containing that position. | |
359 * | |
360 * @param row The beginning row to start search with in the presentation space. | |
361 * @param col The beginning column to start search with in the presentation space. | |
362 * | |
363 * @return If found, a ScreenField object containing the target position. | |
364 * If not found, returns a null. | |
365 */ | |
366 public ScreenField findByPosition(int row, int col) { | |
367 return findByPosition(screen.getPos(row, col)); | |
368 } | |
369 | |
370 public ScreenField[] getFields() { | |
371 ScreenField[] fields = new ScreenField[sizeFields]; | |
372 | |
373 for (int x = 0; x < sizeFields; x++) { | |
374 fields[x] = screenFields[x]; | |
375 } | |
376 | |
377 return fields; | |
378 } | |
379 | |
380 public ScreenField getFirstInputField() { | |
381 if (sizeFields <= 0) | |
382 return null; | |
383 | |
384 int f = 0; | |
385 ScreenField sf = screenFields[f]; | |
386 | |
387 while (sf.isBypassField() && f++ < sizeFields) { | |
388 sf = screenFields[f]; | |
389 } | |
390 | |
391 if (sf.isBypassField()) | |
392 return null; | |
393 else | |
394 return sf; | |
395 } | |
396 | |
397 public void gotoFieldNext() { | |
398 // sanity check - we were getting null pointers after a restore of screen | |
399 // and cursor was not positioned on a field when returned | |
400 // *** Note *** to myself | |
401 // maybe this is fixed I will have to check this some time | |
402 int lastPos = screen.getLastPos(); | |
403 | |
404 if (currentField == null && (sizeFields != 0) && !isInField(lastPos, true)) { | |
405 int pos = lastPos; | |
406 screen.setCursorOff(); | |
407 screen.advancePos(); | |
408 lastPos = screen.getLastPos(); | |
409 | |
410 while (!isInField() && pos != lastPos) { | |
411 screen.advancePos(); | |
412 } | |
413 | |
414 screen.setCursorOn(); | |
415 } | |
416 | |
417 // if we are still null do nothing | |
418 if (currentField == null) | |
419 return; | |
420 | |
421 ScreenField sf = currentField; | |
422 | |
423 if (!sf.withinField(lastPos)) { | |
424 screen.setCursorOff(); | |
425 | |
426 if (sizeFields > 0) { | |
427 // lets get the current position so we can test if we have looped | |
428 // the screen and not found a valid field. | |
429 int pos = lastPos; | |
430 int savPos = lastPos; | |
431 boolean done = false; | |
432 | |
433 do { | |
434 screen.advancePos(); | |
435 lastPos = screen.getLastPos(); | |
436 | |
437 if (isInField(lastPos) | |
438 || pos == lastPos) { | |
439 if (!currentField.isBypassField()) { | |
440 screen.gotoField(currentField); | |
441 done = true; | |
442 } | |
443 } | |
444 } | |
445 while (!done && lastPos != savPos); | |
446 } | |
447 | |
448 currentModified = false; | |
449 screen.setCursorOn(); | |
450 } | |
451 else { | |
452 if (!cpfExists) { | |
453 do { | |
454 sf = sf.next; | |
455 } | |
456 while (sf != null && sf.isBypassField()); | |
457 } | |
458 else { | |
459 int f = 0; | |
460 int cp = sf.getCursorProgression(); | |
461 | |
462 if (cp == 0) { | |
463 do { | |
464 sf = sf.next; | |
465 } | |
466 while (sf != null && sf.isBypassField()); | |
467 } | |
468 else { | |
469 ScreenField sf1 = null; | |
470 boolean found = false; | |
471 | |
472 while (!found && f < sizeFields) { | |
473 sf1 = screenFields[f++]; | |
474 | |
475 if (sf1.getFieldId() == cp) | |
476 found = true; | |
477 } | |
478 | |
479 if (found) | |
480 sf = sf1; | |
481 else { | |
482 do { | |
483 sf = sf.next; | |
484 } | |
485 while (sf != null && sf.isBypassField()); | |
486 } | |
487 | |
488 sf1 = null; | |
489 } | |
490 } | |
491 | |
492 if (sf == null) | |
493 screen.gotoField(1); | |
494 else { | |
495 currentField = sf; | |
496 screen.gotoField(currentField); | |
497 } | |
498 | |
499 currentModified = false; | |
500 } | |
501 } | |
502 | |
503 public void gotoFieldPrev() { | |
504 ScreenField sf = currentField; | |
505 int lastPos = screen.getLastPos(); | |
506 | |
507 if (!sf.withinField(lastPos)) { | |
508 screen.setCursorOff(); | |
509 | |
510 if (sizeFields > 0) { | |
511 // lets get the current position so we can test if we have looped | |
512 // the screen and not found a valid field. | |
513 int pos = lastPos; | |
514 int savPos = lastPos; | |
515 boolean done = false; | |
516 | |
517 do { | |
518 screen.changePos(-1); | |
519 lastPos = screen.getLastPos(); | |
520 | |
521 if (isInField(lastPos) | |
522 || (pos == lastPos)) { | |
523 if (!currentField.isBypassField()) { | |
524 screen.gotoField(currentField); | |
525 done = true; | |
526 } | |
527 } | |
528 } | |
529 while (!done && lastPos != savPos); | |
530 } | |
531 | |
532 screen.setCursorOn(); | |
533 } | |
534 else { | |
535 if (sf.startPos() == lastPos) { | |
536 if (!cpfExists) { | |
537 do { | |
538 sf = sf.prev; | |
539 } | |
540 while (sf != null && sf.isBypassField()); | |
541 } | |
542 else { | |
543 int f = 0; | |
544 int cp = sf.getFieldId(); | |
545 ScreenField sf1 = null; | |
546 boolean found = false; | |
547 | |
548 while (!found && f < sizeFields) { | |
549 sf1 = screenFields[f++]; | |
550 | |
551 if (sf1.getCursorProgression() == cp) | |
552 found = true; | |
553 } | |
554 | |
555 if (found) | |
556 sf = sf1; | |
557 else { | |
558 do { | |
559 sf = sf.prev; | |
560 } | |
561 while (sf != null && sf.isBypassField()); | |
562 } | |
563 | |
564 sf1 = null; | |
565 } | |
566 } | |
567 | |
568 if (sf == null) { | |
569 int size = sizeFields; | |
570 sf = screenFields[size - 1]; | |
571 | |
572 while (sf.isBypassField() && size-- > 0) { | |
573 sf = screenFields[size]; | |
574 } | |
575 } | |
576 | |
577 currentField = sf; | |
578 currentModified = false; | |
579 screen.gotoField(currentField); | |
580 } | |
581 } | |
582 | |
583 protected void readFormatTable(ByteArrayOutputStream baosp, int readType, ICodePage codePage) { | |
584 ScreenField sf; | |
585 boolean isSigned = false; | |
586 char c; | |
587 | |
588 if (masterMDT) { | |
589 StringBuffer sb = new StringBuffer(); | |
590 | |
591 for (int x = 0; x < sizeFields; x++) { | |
592 isSigned = false; | |
593 sf = screenFields[x]; | |
594 | |
595 if (sf.mdt || (readType == CMD_READ_INPUT_FIELDS)) { | |
596 sb.setLength(0); | |
597 sb.append(sf.getText()); | |
598 | |
599 if (readType == CMD_READ_MDT_FIELDS || | |
600 readType == CMD_READ_MDT_IMMEDIATE_ALT) { | |
601 int len = sb.length() - 1; | |
602 | |
603 // we strip out all '\u0020' and less | |
604 while (len >= 0 && | |
605 // (sb.charAt(len) <= ' ' || sb.charAt(len) >= '\uff20' )) { | |
606 (sb.charAt(len) < ' ' || sb.charAt(len) >= '\uff20')) { | |
607 // if we have the dup character and dup is enabled then we | |
608 // stop here | |
609 if (sb.charAt(len) == 0x1C && sf.isDupEnabled()) | |
610 break; | |
611 | |
612 sb.deleteCharAt(len--); | |
613 } | |
614 } | |
615 | |
616 // System.out.println("field " + sf.toString()); | |
617 // System.out.println(">" + sb.toString() + "<"); | |
618 // System.out.println(" field is all nulls"); | |
619 if (sf.isSignedNumeric() && sb.length() > 0 && sb.charAt(sb.length() - 1) == '-') { | |
620 isSigned = true; | |
621 sb.setLength(sb.length() - 1); | |
622 } | |
623 | |
624 int len3 = sb.length(); | |
625 | |
626 if (len3 > 0 || (readType == CMD_READ_MDT_FIELDS || | |
627 readType == CMD_READ_MDT_IMMEDIATE_ALT)) { | |
628 if ((readType == CMD_READ_MDT_FIELDS || | |
629 readType == CMD_READ_MDT_IMMEDIATE_ALT)) { | |
630 baosp.write(17); // start of field data | |
631 | |
632 if (sf.isSelectionField()) { | |
633 baosp.write(screen.getRow(sf.selectionPos) + 1); | |
634 baosp.write(screen.getCol(sf.selectionPos) + 1); | |
635 } | |
636 else { | |
637 baosp.write(sf.startRow() + 1); | |
638 baosp.write(sf.startCol() + 1); | |
639 } | |
640 } | |
641 | |
642 // int len = sb.length(); | |
643 if (sf.isSelectionField()) { | |
644 baosp.write(0); | |
645 baosp.write(sf.selectionIndex + 0x1F); | |
646 } | |
647 else { | |
648 for (int k = 0; k < len3; k++) { | |
649 c = sb.charAt(k); | |
650 | |
651 // here we have to check for special instances of the | |
652 // characters in the string field. Attribute bytes | |
653 // are encoded with an offset of \uff00 | |
654 // This is a hack !!!!!!!!!!! | |
655 // See ScreenField object for a description | |
656 if (c < ' ' || c >= '\uff20') { | |
657 // if it is an offset attribute byte we just pass | |
658 // it straight on to the output stream | |
659 if (c >= '\uff20' && c <= '\uff3f') { | |
660 baosp.write(c - '\uff00'); | |
661 } | |
662 else | |
663 | |
664 // check for dup character | |
665 if (c == 0x1C) | |
666 baosp.write(c); | |
667 else | |
668 baosp.write(codePage.uni2ebcdic(' ')); | |
669 } | |
670 else { | |
671 if (isSigned && k == len3 - 1) { | |
672 baosp.write(0xd0 | (0x0f & c)); | |
673 } | |
674 else | |
675 baosp.write(codePage.uni2ebcdic(c)); | |
676 } | |
677 } | |
678 } | |
679 } | |
680 } | |
681 } | |
682 } | |
683 } | |
684 | |
685 } |