diff src/org/tn5250j/framework/tn5250/ScreenFields.java @ 3:e8d2a24e85c6 tn5250

adding tn5250 files
author Carl Byington <carl@five-ten-sg.com>
date Thu, 22 May 2014 12:11:10 -0700
parents
children 294435151b0c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/tn5250j/framework/tn5250/ScreenFields.java	Thu May 22 12:11:10 2014 -0700
@@ -0,0 +1,724 @@
+/**
+ * Title: tn5250J
+ * Copyright:   Copyright (c) 2001
+ * Company:
+ * @author  Kenneth J. Pouncey
+ * @version 0.5
+ *
+ * Description:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ *
+ */
+package org.tn5250j.framework.tn5250;
+
+import static org.tn5250j.TN5250jConstants.CMD_READ_INPUT_FIELDS;
+import static org.tn5250j.TN5250jConstants.CMD_READ_MDT_FIELDS;
+import static org.tn5250j.TN5250jConstants.CMD_READ_MDT_IMMEDIATE_ALT;
+
+import java.io.ByteArrayOutputStream;
+
+import org.tn5250j.encoding.ICodePage;
+
+public class ScreenFields {
+
+   private ScreenField[] screenFields;
+   private ScreenField currentField;
+   private ScreenField saveCurrent;
+   private int sizeFields;
+   private boolean cpfExists;
+   private int nextField;
+   private int fieldIds;
+   private Screen5250 screen;
+   private boolean masterMDT;
+   protected boolean currentModified;
+
+   public ScreenFields(Screen5250 s) {
+
+      screen = s;
+      screenFields = new ScreenField[256];
+   }
+
+   protected void clearFFT() {
+
+      sizeFields = nextField = fieldIds = 0;
+      cpfExists = false;   // clear the cursor progression fields flag
+      currentField = null;
+      masterMDT = false;
+
+   }
+
+   protected boolean existsAtPos(int lastPos) {
+
+      ScreenField sf = null;
+
+      // from 14.6.12 for Start of Field Order 5940 function manual
+      //  examine the format table for an entry that begins at the current
+      //  starting address plus 1.
+      for (int x = 0;x < sizeFields; x++) {
+         sf = screenFields[x];
+
+         if (lastPos == sf.startPos()) {
+            currentField = sf;
+            currentModified = false;
+            return true;
+         }
+
+      }
+
+      return false;
+   }
+
+   public boolean isMasterMDT() {
+      return masterMDT;
+   }
+
+   protected void setMasterMDT() {
+      masterMDT = true;
+   }
+
+   public boolean isCurrentField() {
+      return currentField == null;
+   }
+
+   public boolean isCurrentFieldFER() {
+      return currentField.isFER();
+   }
+
+   public boolean isCurrentFieldDupEnabled() {
+      return currentField.isDupEnabled();
+   }
+
+   public boolean isCurrentFieldToUpper() {
+      return currentField.isToUpper();
+   }
+
+   public boolean isCurrentFieldBypassField() {
+      return currentField.isBypassField();
+   }
+
+   public boolean isCurrentFieldHighlightedEntry() {
+      if (currentField != null)
+         return currentField.isHiglightedEntry();
+      else
+         return false;
+   }
+
+   public boolean isCurrentFieldAutoEnter() {
+      return currentField.isAutoEnter();
+   }
+
+   public boolean withinCurrentField(int pos) {
+      return currentField.withinField(pos);
+   }
+
+   public boolean isCurrentFieldContinued() {
+      return currentField.isContinued();
+   }
+
+   public boolean isCurrentFieldContinuedFirst() {
+      return currentField.isContinuedFirst();
+   }
+
+   public boolean isCurrentFieldContinuedMiddle() {
+      return currentField.isContinuedMiddle();
+   }
+
+   public boolean isCurrentFieldContinuedLast() {
+      return currentField.isContinuedLast();
+   }
+
+   public boolean isCurrentFieldModified() {
+      return currentModified;
+   }
+
+   /**
+    * This routine is used to check if we can send the Aid key to the host
+    *
+    * Taken from Section  16.2.1.2 Enter/Rec Adv Key
+    *
+    * In the normal unlocked state, when the workstation operator presses the
+    * Enter/Rec Adv key:
+    *
+    * 1. The 5494 checks for the completion of mandatory-fill, self-check, and
+    *    right-adjust fields when in an active field. (An active field is one in
+    *    which the workstation operator has begun entering data.) If the
+    *    requirements of the field have not been satisfied, an error occurs.
+    *
+    * @return
+    *
+    */
+   public boolean isCanSendAid() {
+
+      // We also have to check if we are still in the field.
+      if (currentField != null &&
+            (currentField.getAdjustment() > 0 || currentField.isSignedNumeric())
+             && currentModified && isInField()
+            && !currentField.isCanSend())
+
+         return false;
+      else
+         return true;
+
+   }
+
+   protected void saveCurrentField() {
+      saveCurrent = currentField;
+   }
+
+   protected void restoreCurrentField() {
+      currentField = saveCurrent;
+   }
+
+   protected void setCurrentField(ScreenField sf) {
+      currentField = sf;
+   }
+
+   protected void setCurrentFieldMDT() {
+      currentField.setMDT();
+      currentModified = true;
+      masterMDT = true;
+   }
+
+   protected void setCurrentFieldFFWs(int ffw1, int ffw2) {
+
+      masterMDT = currentField.setFFWs(ffw1,ffw2);
+
+   }
+
+
+   protected ScreenField setField(int attr, int row, int col, int len, int ffw1,
+                           int ffw2, int fcw1, int fcw2) {
+
+      ScreenField sf = null;
+      screenFields[nextField] = new ScreenField(screen);
+      screenFields[nextField].setField(attr,row,col,len,ffw1,ffw2,fcw1,fcw2);
+      sf = screenFields[nextField++];
+
+      sizeFields++;
+
+
+      // set the field id if it is not a bypass field
+      // this is used for cursor progression
+      //  changed this because of problems not allocating field id's for
+      //  all fields.  kjp 2002/10/21
+//      if (!sf.isBypassField())
+      sf.setFieldId(++fieldIds);
+
+      // check if the cursor progression field flag should be set.
+//      if ((fcw1 & 0x88) == 0x88)
+      if (fcw1 == 0x88)
+         cpfExists = true;
+
+      if (currentField != null) {
+         currentField.next = sf;
+         sf.prev = currentField;
+      }
+
+      currentField = sf;
+
+      // check if the Modified Data Tag was set while creating the field
+      if (!masterMDT)
+         masterMDT = currentField.mdt;
+
+      currentModified = false;
+
+      return currentField;
+
+   }
+
+   public ScreenField getField(int index) {
+
+      return screenFields[index];
+   }
+
+   public ScreenField getCurrentField() {
+      return currentField;
+   }
+
+   public int getCurrentFieldPos() {
+      return currentField.getCurrentPos();
+   }
+
+   protected int getCurrentFieldShift() {
+      return currentField.getFieldShift();
+   }
+
+   public String getCurrentFieldText() {
+
+      return currentField.getText();
+   }
+
+   public int getCurrentFieldHighlightedAttr(){
+      return currentField.getHighlightedAttr();
+   }
+
+   public int getSize() {
+
+      return sizeFields;
+   }
+
+   public int getFieldCount() {
+
+      return sizeFields;
+   }
+
+   protected boolean isInField(int pos) {
+      return isInField(pos,true);
+   }
+
+   protected boolean isInField() {
+      return isInField(screen.getLastPos(),true);
+   }
+
+   protected boolean isInField(int pos, boolean chgToField) {
+
+      ScreenField sf;
+
+      for (int x = 0;x < sizeFields; x++) {
+         sf = screenFields[x];
+
+         if (sf.withinField(pos)) {
+
+            if (chgToField) {
+               if (!currentField.equals(sf))
+                  currentModified = false;
+               currentField = sf;
+            }
+            return true;
+         }
+      }
+      return false;
+
+   }
+
+   /**
+    * Searches the collection for the target string and returns the iOhioField
+    * object containing that string.  The string must be totally contained
+    * within the field to be considered a match.
+    *
+    * @param targetString The target string.
+    * @param startPos The row and column where to start the search. The position
+    *                 is inclusive (for example, row 1, col 1 means that
+    *                 position 1,1 will be used as the starting location and
+    *                 1,1 will be included in the search).
+    * @param length The length from startPos to include in the search.
+    * @param dir An OHIO_DIRECTION value:
+    *
+    * <table BORDER COLS=3 WIDTH="50%" >
+    * <tr><th>Constant </th><th>Value</th>
+    *                            <th>Description</th></tr>
+    * <tr><td>OS_OHIO_DIRECTION_FORWARD </td><td>0</td>
+    *                            <td>Forward (beginning towards end)</td></tr>
+    * <tr><td>OS_OHIO_DIRECTION_BACKWARD </td><td>1</td>
+    *                            <td>Backward (end towards beginning)</td></tr>
+    * </table>
+    *       Constant Value Description
+    *       ignoreCase - Indicates whether the search is case sensitive.
+    *       True means that case will be ignored. False means the search will
+    *       be case sensitive.
+    * @return If found, an iOhioField object containing the target string. If
+    *         not found, returns a null.
+    */
+   public ScreenField findByString (String targetString,
+                                             int startPos,
+                                             int length,
+                                             int dir,
+                                             boolean ignoreCase) {
+
+      // first lets check if the string exists in the screen space
+//      iOhioPosition pos = screen.findString(targetString, startPos, length,
+//                                             dir, ignoreCase);
+
+      // if it does exist then lets search the fields by the position that
+      //  was found and return the results of that search.
+//      if (pos != null) {
+         return findByPosition(startPos);
+//      }
+
+      //return null;
+
+   }
+
+   /**
+    * Searches the collection for the target position and returns the ScreenField
+    * object containing that position.
+    *
+    * @param targetPosition The target row and column expressed as a linear
+    *          position within the presentation space.
+    *
+    * @return If found, a ScreenField object containing the target position.
+    *         If not found, returns a null.
+    */
+   public ScreenField findByPosition(int targetPosition) {
+
+      ScreenField sf = null;
+
+      for (int x = 0;x < sizeFields; x++) {
+
+         sf = screenFields[x];
+
+         if (sf.withinField(targetPosition)) {
+            return sf;
+         }
+
+      }
+
+      return null;
+   }
+
+   /**
+    * Searches the collection for the target position and returns the ScreenField
+    * object containing that position.
+    *
+    * @param row The beginning row to start search with in the presentation space.
+    * @param col The beginning column to start search with in the presentation space.
+    *
+    * @return If found, a ScreenField object containing the target position.
+    *         If not found, returns a null.
+    */
+   public ScreenField findByPosition(int row, int col) {
+
+      return findByPosition(screen.getPos(row,col));
+   }
+
+   public ScreenField[] getFields () {
+
+      ScreenField[] fields = new ScreenField[sizeFields];
+      for (int x = 0; x < sizeFields; x++) {
+
+         fields[x] = screenFields[x];
+      }
+
+      return fields;
+   }
+
+   public ScreenField getFirstInputField() {
+
+		if (sizeFields <= 0)
+			return null;
+
+      int f = 0;
+      ScreenField sf = screenFields[f];
+
+      while (sf.isBypassField() && f++ < sizeFields) {
+         sf = screenFields[f];
+      }
+
+      if (sf.isBypassField())
+         return null;
+      else
+         return sf;
+
+   }
+
+   public void gotoFieldNext() {
+
+      // sanity check - we where getting null pointers after a restore of screen
+      //   and cursor was not positioned on a field when returned
+      //   *** Note *** to myself
+      //   maybe this is fixed I will have to check this some time
+      int lastPos = screen.getLastPos();
+
+      if (currentField == null && (sizeFields != 0) && !isInField(lastPos,true)) {
+         int pos = lastPos;
+         screen.setCursorOff();
+         screen.advancePos();
+         lastPos = screen.getLastPos();
+         while (!isInField() && pos != lastPos) {
+            screen.advancePos();
+         }
+         screen.setCursorOn();
+      }
+
+      // if we are still null do nothing
+      if (currentField == null)
+         return;
+
+      ScreenField sf = currentField;
+
+      if (!sf.withinField(lastPos)) {
+         screen.setCursorOff();
+
+         if (sizeFields > 0) {
+
+            // lets get the current position so we can test if we have looped
+            //    the screen and not found a valid field.
+            int pos = lastPos;
+            int savPos = lastPos;
+            boolean done = false;
+            do {
+               screen.advancePos();
+               lastPos = screen.getLastPos();
+               if (isInField(lastPos)
+                   || pos==lastPos) {
+                  if (!currentField.isBypassField()) {
+                     screen.gotoField(currentField);
+                     done = true;
+                  }
+               }
+            }  while ( !done && lastPos != savPos);
+         }
+         currentModified = false;
+         screen.setCursorOn();
+
+      }
+      else {
+         if (!cpfExists) {
+            do {
+
+               sf = sf.next;
+            }
+            while ( sf != null && sf.isBypassField());
+
+         }
+         else {
+            int f = 0;
+            int cp = sf.getCursorProgression();
+
+            if (cp == 0) {
+               do {
+
+                  sf = sf.next;
+               }
+               while ( sf != null && sf.isBypassField());
+
+            }
+            else {
+               ScreenField sf1 = null;
+               boolean found = false;
+               while (!found && f < sizeFields) {
+
+                  sf1 = screenFields[f++];
+                  if (sf1.getFieldId() == cp)
+                     found = true;
+               }
+               if (found)
+                  sf = sf1;
+               else {
+                  do {
+                     sf = sf.next;
+                  }
+                  while ( sf != null && sf.isBypassField());
+
+               }
+               sf1 = null;
+            }
+         }
+         if (sf == null)
+            screen.gotoField(1);
+         else {
+            currentField = sf;
+            screen.gotoField(currentField);
+         }
+
+         currentModified = false;
+
+      }
+   }
+
+   public void gotoFieldPrev() {
+
+      ScreenField sf = currentField;
+      int lastPos = screen.getLastPos();
+
+      if (!sf.withinField(lastPos)) {
+         screen.setCursorOff();
+
+         if (sizeFields > 0) {
+            // lets get the current position so we can test if we have looped
+            //    the screen and not found a valid field.
+            int pos = lastPos;
+            int savPos = lastPos;
+            boolean done = false;
+
+            do {
+               screen.changePos(-1);
+               lastPos = screen.getLastPos();
+
+               if (isInField(lastPos)
+                  || (pos == lastPos)) {
+
+                  if (!currentField.isBypassField()) {
+                     screen.gotoField(currentField);
+                     done = true;
+                  }
+               }
+            } while ( !done && lastPos != savPos);
+         }
+         screen.setCursorOn();
+
+      }
+      else {
+
+         if (sf.startPos() == lastPos) {
+            if (!cpfExists) {
+
+               do {
+                  sf = sf.prev;
+               }
+               while ( sf != null && sf.isBypassField());
+            }
+            else {
+
+               int f = 0;
+               int cp = sf.getFieldId();
+               ScreenField sf1 = null;
+               boolean found = false;
+               while (!found && f < sizeFields) {
+
+                  sf1 = screenFields[f++];
+                  if (sf1.getCursorProgression() == cp)
+                     found = true;
+               }
+               if (found)
+                  sf = sf1;
+               else {
+                  do {
+                     sf = sf.prev;
+                  }
+                  while ( sf != null && sf.isBypassField());
+               }
+               sf1 = null;
+            }
+         }
+
+         if (sf == null) {
+            int size = sizeFields;
+            sf = screenFields[size - 1];
+
+            while (sf.isBypassField() && size-- > 0) {
+               sf = screenFields[size];
+
+            }
+         }
+         currentField = sf;
+         currentModified = false;
+         screen.gotoField(currentField);
+      }
+   }
+
+   protected void readFormatTable(ByteArrayOutputStream baosp,int readType, ICodePage codePage) {
+
+      ScreenField sf;
+      boolean isSigned = false;
+      char c;
+
+      if (masterMDT) {
+
+         StringBuffer sb = new StringBuffer();
+         for (int x = 0; x < sizeFields; x++) {
+            isSigned = false;
+
+            sf = screenFields[x];
+
+            if (sf.mdt || (readType == CMD_READ_INPUT_FIELDS)) {
+
+               sb.setLength(0);
+               sb.append(sf.getText());
+
+
+               if (readType == CMD_READ_MDT_FIELDS ||
+                     readType == CMD_READ_MDT_IMMEDIATE_ALT) {
+                  int len = sb.length() - 1;
+
+                  // we strip out all '\u0020' and less
+                  while (len >= 0 &&
+//                     (sb.charAt(len) <= ' ' || sb.charAt(len) >= '\uff20' )) {
+                     (sb.charAt(len) < ' ' || sb.charAt(len) >= '\uff20')) {
+
+                     // if we have the dup character and dup is enabled then we
+                     //    stop here
+                     if (sb.charAt(len) == 0x1C && sf.isDupEnabled())
+                        break;
+
+                     sb.deleteCharAt(len--);
+                  }
+
+               }
+
+//               System.out.println("field " + sf.toString());
+//               System.out.println(">" + sb.toString() + "<");
+//               System.out.println(" field is all nulls");
+               if (sf.isSignedNumeric() && sb.length() > 0 && sb.charAt(sb.length() - 1) == '-') {
+                  isSigned = true;
+                  sb.setLength(sb.length() - 1);
+               }
+
+               int len3 = sb.length();
+
+               if (len3 > 0 || (readType == CMD_READ_MDT_FIELDS ||
+                       readType == CMD_READ_MDT_IMMEDIATE_ALT)) {
+
+                  if ((readType == CMD_READ_MDT_FIELDS ||
+                       readType == CMD_READ_MDT_IMMEDIATE_ALT)) {
+
+                     baosp.write(17);   // start of field data
+                  if (sf.isSelectionField()) {
+                     baosp.write(screen.getRow(sf.selectionPos)+1);
+                     baosp.write(screen.getCol(sf.selectionPos)+1);
+                  }
+                  else {
+                     baosp.write(sf.startRow()+1);
+                     baosp.write(sf.startCol()+1);
+                  }
+
+                  }
+//                  int len = sb.length();
+                  if (sf.isSelectionField()) {
+                     baosp.write(0);
+                     baosp.write(sf.selectionIndex + 0x1F);
+
+                  }
+                  else {
+                  for (int k = 0; k < len3; k++) {
+                     c = sb.charAt(k);
+                     // here we have to check for special instances of the
+                     //    characters in the string field.  Attribute bytes
+                     //    are encoded with an offset of \uff00
+                     //    This is a hack !!!!!!!!!!!
+                     //    See ScreenField object for a description
+                     if (c < ' ' || c >= '\uff20') {
+
+                        // if it is an offset attribute byte we just pass
+                        //    it straight on to the output stream
+                        if (c >= '\uff20' && c <= '\uff3f') {
+                           baosp.write(c - '\uff00');
+                        }
+                        else
+                           // check for dup character
+                           if (c == 0x1C)
+                              baosp.write(c);
+                           else
+                              baosp.write(codePage.uni2ebcdic(' '));
+                     }
+                     else {
+                        if (isSigned && k == len3 - 1) {
+                           baosp.write(0xd0 | (0x0f & c));
+                        }
+                        else
+                           baosp.write(codePage.uni2ebcdic(c));
+
+                     }
+                  }
+                  }
+               }
+            }
+         }
+      }
+   }
+
+}
\ No newline at end of file