home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / ZINC_6.ZIP / DOSSRC.ZIP / STRING.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  9.4 KB  |  428 lines

  1. //    Zinc Interface Library - STRING.CPP
  2. //    COPYRIGHT (C) 1990, 1991.  All Rights Reserved.
  3. //    Zinc Software Incorporated.  Pleasant Grove, Utah  USA
  4.  
  5. #include "ui_win.hpp"
  6. #include <ctype.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. UIW_STRING::UIW_STRING(int left, int top, int width, char *a_text,
  11.     short maxLength, USHORT a_stFlags, USHORT woFlags,
  12.     int (*a_Validate)(void *object, int ccode)) :
  13.     UI_WINDOW_OBJECT(left, top, width, 1, woFlags, WOAF_NO_FLAGS)
  14. {
  15.     windowID[0] = ID_STRING;
  16.     search.type = ID_STRING;
  17.     stFlags = a_stFlags;
  18.  
  19.     Validate = a_Validate;
  20.     originalWidth = fieldWidth = width;
  21.     // NOTE: in-field scrolling is not currently supported for right-justified
  22.     // and center-justified strings.  The following line enforces that by
  23.     // disallowing the "maxLength" from being larger than the field width in
  24.     // those cases.
  25.     if (FlagSet(woFlags, WOF_JUSTIFY_RIGHT | WOF_JUSTIFY_CENTER))
  26.         maxLength = Min(maxLength, width);
  27.     if (FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  28.         text = a_text;
  29.     else
  30.     {
  31.         text = new char[maxLength];
  32.         if (a_text)
  33.         {
  34.             int srcLen = strlen(a_text) + 1;
  35.             memcpy(text, a_text, Min(srcLen, maxLength));
  36.         }
  37.         else
  38.             text[0] = '\0';
  39.     }
  40.     insertMode = (width <= 2) ? FALSE : TRUE;
  41.     textTail = text + maxLength - 1;
  42.     *textTail = '\0';                        // Insure trailing null.
  43.     screen = 0;
  44.     screenSize = 0;
  45.     screenMarkStart = 0;
  46.     screenMarkTail = 0;
  47. }
  48.  
  49. UIW_STRING::~UIW_STRING()
  50. {
  51.     if (!FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  52.         delete text;
  53.     if (screen)
  54.         delete screen;
  55. }
  56.  
  57. int UIW_STRING::Event(const UI_EVENT &event)
  58. {
  59.     int viewOnly = FlagSet(woFlags, WOF_VIEW_ONLY) ||
  60.         FlagSet(woAdvancedStatus, WOAS_TOO_SMALL) ? TRUE : FALSE;
  61.     int ccode = UI_WINDOW_OBJECT::LogicalEvent(event, ID_STRING);
  62.     UI_REGION region;
  63.     UI_WINDOW_OBJECT::Border(0, region, 0);
  64.     USHORT key;
  65.     short cellWidth = display->TextWidth("W");
  66.     short width = (region.right + 1 - region.left) / cellWidth;
  67.     UCHAR reDisplay = TRUE;
  68.     UCHAR displayCheckRegion = FALSE;
  69.     int needValidate = NeedsValidation();
  70.  
  71.     if (ccode == S_SIZE)
  72.     {
  73.         int width = (relative.right - relative.left + 1) / display->cellWidth;
  74.         if (width != originalWidth)
  75.         {
  76.             originalWidth = width;
  77.             ccode = S_CREATE;
  78.         }
  79.     }
  80.     if (ccode == S_CREATE)
  81.     {
  82.         markedBlock = 0;
  83.         screenTop = text;
  84.         cursor = text;
  85.         if (FlagSet(woFlags, WOF_BORDER))
  86.             fieldWidth = display->isText ? originalWidth - 2 : originalWidth - 1;
  87.         else
  88.             fieldWidth = originalWidth;
  89.         // NOTE: Prevent in-field scrolling in right-justified and center-
  90.         // justified fields by limiting maximum size of string to fit in
  91.         // the field width in those cases.
  92.         if (FlagSet(woFlags, WOF_JUSTIFY_RIGHT | WOF_JUSTIFY_CENTER) &&
  93.             textTail + 1 - text > fieldWidth)
  94.             textTail = text + fieldWidth - 1;
  95.     }
  96.     textNull = strchr(text, '\0');
  97.     if (textNull < cursor)
  98.         cursor = textNull;
  99.  
  100.     /* Switch on the event type */
  101.     switch (ccode)
  102.     {
  103.     case E_KEY:
  104.         key = event.rawCode & 0xFF;
  105.         if (!viewOnly)
  106.         {
  107.             if (key == '\b')
  108.                 BackspaceKey();
  109.             else if (FlagSet(stFlags, STF_VARIABLE_NAME))
  110.                 RegularKey((key == ' ') ? '_' : toupper(key));
  111.             else
  112.                 RegularKey(key);
  113.         }
  114.         else
  115.         {
  116.             reDisplay = FALSE;
  117.             ccode = S_UNKNOWN;
  118.         }
  119.         break;
  120.  
  121.     case L_LEFT:
  122.         if (cursor == text)
  123.         {
  124.             ccode = S_UNKNOWN;
  125.             reDisplay = FALSE;
  126.         }
  127.         else
  128.         {
  129.             MoveOperation();
  130.             LeftArrow();
  131.             CheckLeftScroll();
  132.         }
  133.         break;
  134.  
  135.     case L_RIGHT:
  136.         if (*cursor)
  137.         {
  138.             MoveOperation();
  139.             cursor++;
  140.             CheckRightScroll();
  141.         }
  142.         else
  143.         {
  144.             ccode = S_UNKNOWN;
  145.             reDisplay = FALSE;
  146.         }
  147.         break;
  148.  
  149.     case L_BOL:
  150.         MoveOperation();
  151.         screenTop = text;
  152.         cursor = text;
  153.         break;
  154.  
  155.     case L_EOL:
  156.         if (*cursor)
  157.         {
  158.             MoveOperation();
  159.             cursor = textNull;
  160.             if (textNull < text + fieldWidth)
  161.                 screenTop = text;
  162.             else
  163.                 screenTop = textNull - fieldWidth + 1;
  164.         }
  165.         break;
  166.  
  167.     case L_WORD_LEFT:
  168.         MoveOperation();
  169.         WordTabLeft();
  170.         CheckLeftScroll();
  171.         break;
  172.  
  173.     case L_WORD_RIGHT:
  174.         if (*cursor)
  175.         {
  176.             MoveOperation();
  177.             while ( NonWhiteSpace(*cursor) )
  178.                 cursor++;
  179.             while (*cursor && WhiteSpace(*cursor) )
  180.                 cursor++;
  181.             CheckRightScroll();
  182.         }
  183.         break;
  184.  
  185.     case L_INSERT_TOGGLE:
  186.         MoveOperation();
  187.         insertMode = !insertMode;
  188.         break;
  189.  
  190.     case L_DELETE:
  191.         if (!viewOnly)
  192.         {
  193.             SetMark();
  194.             if (markStart)
  195.             {
  196.                 pasteLength = (USHORT) (markTail - markStart);
  197.                 DeleteBlock(markStart, pasteLength);
  198.             }
  199.             else if (*cursor)
  200.                 DeleteBlock(cursor, 1);
  201.         }
  202.         break;
  203.  
  204.     case L_DELETE_EOL:
  205.         if (!viewOnly)
  206.             DeleteEol();
  207.         break;
  208.  
  209.     case L_DELETE_WORD:
  210.         if (!viewOnly)
  211.             DeleteWord();
  212.         break;
  213.  
  214.     case L_MARK:
  215.         if (markedBlock)
  216.             markedBlock = 0;        // Toggle mark off if its on.
  217.         else
  218.             markedBlock = cursor;    // Or turn it on if its off.
  219.         break;
  220.  
  221.     case L_VIEW:
  222.         eventManager->DeviceState(event.type, DM_EDIT);
  223.         reDisplay = FALSE;
  224.         break;
  225.  
  226.     case L_CUT:
  227.         if (!viewOnly)
  228.         {
  229.             SetMark();
  230.             if (markStart)
  231.             {
  232.                 pasteLength = (USHORT) (markTail - markStart);
  233.                 DeleteBlock(markStart, pasteLength);
  234.             }
  235.             else
  236.                 reDisplay = FALSE;
  237.             break;
  238.         }
  239.         // If view only, treat a CUT as a copy.
  240.  
  241.     case L_COPY_MARK:
  242.         SetMark();
  243.         if (markStart)
  244.             CopyBlock();
  245.         else
  246.             reDisplay = FALSE;
  247.         break;
  248.  
  249.     case L_CUT_PASTE:
  250.         SetMark();
  251.         if (markStart)
  252.         {
  253.             if (viewOnly)
  254.                 CopyBlock();
  255.             else
  256.             {
  257.                 pasteLength = (USHORT) (markTail - markStart);
  258.                 DeleteBlock(markStart, pasteLength);
  259.             }
  260.             break;
  261.         }
  262.         /*** else fall through to paste code. ***/
  263.     case L_PASTE:
  264.         if (!viewOnly)
  265.         {
  266.             if (event.type != E_KEY)
  267.             {
  268.                 MoveOperation();
  269.                 int leading = CalcLeading(width);
  270.                 int fieldColumn = (event.position.column - region.left) / cellWidth;
  271.                 cursor = screenTop + fieldColumn - leading;
  272.                 if (cursor > textNull)
  273.                     cursor = textNull;
  274.                 else if (cursor < text)
  275.                     cursor = text;
  276.                 UpdateCursor(region, width);
  277.             }
  278.             PasteBlock();
  279.         }
  280.         break;
  281.  
  282.     case L_END_MARK:
  283.         if (cursor == markedBlock)
  284.             markedBlock = 0;            // Eliminate zero-length mark.
  285.         reDisplay = FALSE;
  286.         break;
  287.  
  288.     case L_CONTINUE_MARK:
  289.         if (markedBlock)
  290.         {
  291.             MoveOperation();
  292.             int leading = CalcLeading(width);
  293.             if (event.position.column > region.left)
  294.                 cursor = screenTop + (event.position.column - region.left) / cellWidth - leading;
  295.             else
  296.                 cursor = screenTop;
  297.             if (cursor > textNull)
  298.                 cursor = textNull;
  299.             else if (cursor < text)
  300.                 cursor = text;
  301.             UpdateCursor(region, width);
  302.             break;
  303.         }
  304.         /*** Else fall through to code that begins the mark. */
  305.     case L_BEGIN_MARK:
  306.         {
  307.             int leading = CalcLeading(width);
  308.             int fieldColumn = (event.position.column - region.left) / cellWidth;
  309.             cursor = screenTop + fieldColumn - leading;
  310.             if (cursor > textNull)
  311.                 cursor = textNull;
  312.             else if (cursor < text)
  313.                 cursor = text;
  314.             if (fieldColumn == 0)
  315.                 CheckLeftScroll();
  316.             else if (fieldColumn >= fieldWidth - 1 && cursor < textNull)
  317.             {
  318.                 cursor++;
  319.                 CheckRightScroll();
  320.             }
  321.             UpdateCursor(region, width);
  322.             markedBlock = cursor;            // Throw away possible old mark.
  323.         }
  324.         break;
  325.  
  326.     case S_ERROR_RESPONSE:
  327.         woStatus |= event.rawCode;
  328.         break;
  329.  
  330.     case S_CURRENT:
  331.         if (needValidate)
  332.             (*Validate)(this, ccode);
  333.         // Clear the WOS_UNANSWERED and WOS_NO_AUTO_CLEAR bits
  334.         woStatus &= ~(WOS_UNANSWERED | WOS_NO_AUTO_CLEAR);
  335.         // Fall through.
  336.  
  337.     case S_DISPLAY_ACTIVE:
  338.         displayCheckRegion = TRUE;
  339.         break;
  340.  
  341.     case S_NON_CURRENT:
  342.         if (needValidate && (*Validate)(this, ccode) != 0 )
  343.         {
  344.             ccode = S_ERROR;
  345.             woStatus |= WOS_INVALID;
  346.             break;
  347.         }
  348.         woStatus &= ~WOS_INVALID;            // Clear invalid status bit.
  349.         // else fall through.
  350.     case S_DISPLAY_INACTIVE:
  351.         markedBlock = 0;                    // Throw away marked block.
  352.         displayCheckRegion = TRUE;
  353.         break;
  354.  
  355.     default:
  356.         ccode = UI_WINDOW_OBJECT::Event(event);
  357.         reDisplay = FALSE;
  358.         break;
  359.     }
  360.     if (displayCheckRegion)
  361.     {
  362.         if ( !UI_WINDOW_OBJECT::NeedsUpdate(event, ccode) )
  363.         {
  364.             reDisplay = FALSE;
  365.             if (ccode == S_CURRENT)
  366.                 UpdateCursor(region, width);
  367.         }
  368.         else
  369.         {
  370.             screenInvalid = TRUE;
  371.             UI_WINDOW_OBJECT::Border(ccode, region, lastPalette);
  372.         }
  373.     }
  374.     if (reDisplay)
  375.     {
  376.         SetMark();
  377.         if (cursor - screenTop >= fieldWidth)
  378.             screenTop = cursor - fieldWidth + 1;
  379.         else if (cursor < screenTop)
  380.             screenTop = cursor;
  381.         Redisplay(ccode);
  382.     }
  383.     return (ccode);
  384. }
  385.  
  386. #ifdef ZIL_LOAD
  387. UIW_STRING::UIW_STRING(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  388.     UI_WINDOW_OBJECT(name, file, loadFlags | L_SUB_LEVEL)
  389. {
  390.     windowID[0] = ID_STRING;
  391.  
  392.     if (!file)
  393.         file = _storage;
  394.     originalWidth = fieldWidth = relative.right - relative.left + 1;
  395.     file->Load(&stFlags);
  396.     short maxLength;
  397.     file->Load(&maxLength);
  398.     text = new char[maxLength];
  399.     short size;
  400.     file->Load(&size);
  401.     if (size)
  402.         file->Load(text, size);
  403.     text[size] = '\0';
  404.     textTail = text + maxLength - 1;
  405.     insertMode = TRUE;
  406.     *textTail = '\0';
  407.     screen = 0;
  408.     screenSize = 0;
  409.     screenMarkStart = 0;
  410.     screenMarkTail = 0;
  411.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  412.         delete file;
  413. }
  414. #endif
  415.  
  416. #ifdef ZIL_STORE
  417. void UIW_STRING::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  418. {
  419.     UI_WINDOW_OBJECT::Store(name, file, storeFlags | S_SUB_LEVEL);
  420.     file->Store(stFlags);
  421.     short maxLength = (short)(textTail - text + 1);
  422.     file->Store(maxLength);
  423.     file->Store(text);
  424.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  425.         file->ObjectSize(name, search);
  426. }
  427. #endif
  428.