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 / DATEWIN.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-01  |  6.7 KB  |  277 lines

  1. //    Zinc Interface Library - DATEWIN.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 <dos.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10.  
  11. UIW_DATE::UIW_DATE(int left, int top, int width, UI_DATE *_date,
  12.     const char *_range, USHORT _dtFlags, USHORT _woFlags, int (*_validate)(void *object, int ccode)) :
  13.     UIW_STRING(left, top, width, NULL, 64, STF_NO_FLAGS, _woFlags, _validate),
  14.     dtFlags(_dtFlags)
  15. {
  16.     // Initialize the date information.
  17.     windowID[0] = ID_DATE;
  18.     windowID[1] = ID_STRING;
  19.     search.type = ID_DATE;
  20.  
  21.     if (FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  22.     {
  23.         text = new char[64];
  24.         text[0] = '\0';
  25.         textTail = text + 63;
  26.         *textTail = '\0';
  27.     }
  28.  
  29.     if (!_date)
  30.     {
  31.         date = new UI_DATE();
  32.         woFlags &= ~WOF_NO_ALLOCATE_DATA;
  33.     }
  34.     else if (FlagSet(_woFlags, WOF_NO_ALLOCATE_DATA))
  35.         date = _date;
  36.     else
  37.         date = new UI_DATE(*_date);
  38.     range = ui_strdup(_range);
  39. }
  40.  
  41. UIW_DATE::~UIW_DATE(void)
  42. {
  43.     if (range)
  44.         delete range;
  45.     if (text && FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  46.     {
  47.         delete text;
  48.         text = NULL;
  49.     }
  50. }
  51.  
  52. void UIW_DATE::DataSet(UI_DATE *newDate)
  53. {
  54.     if (newDate)
  55.     {
  56.         if (FlagSet(woFlags, WOF_NO_ALLOCATE_DATA))
  57.             date = newDate;
  58.         else
  59.             *date = *newDate;
  60.     }
  61.     date->Export(text, fieldWidth, dtFlags);
  62.     UI_WINDOW_OBJECT::Redisplay(FALSE);
  63. }
  64.  
  65. int UIW_DATE::Event(const UI_EVENT &event)
  66. {
  67.     /* Switch on the event type */
  68.     int needValidate = NeedsValidation();
  69.     int ccode = event.type;
  70.     if (ccode == S_CREATE)
  71.     {
  72.         if (FlagSet(woStatus, WOS_UNANSWERED))
  73.         {
  74.             date->Import(0, 0, 0);
  75.             *text = '\0';
  76.         }
  77.         else
  78.             date->Export(text, fieldWidth, dtFlags);
  79.     }
  80.     else if (ccode == S_CURRENT)
  81.     {
  82.         if (needValidate)
  83.             (*Validate)(this, ccode);
  84.         woStatus &= ~WOS_UNANSWERED;
  85.         if (!FlagSet(woStatus, WOS_CURRENT))
  86.             date->Export(text, fieldWidth, dtFlags & ~(DTF_DAY_OF_WEEK | DTF_SHORT_DAY));
  87.     }
  88.     else if (ccode == S_NON_CURRENT)
  89.     {
  90.         int result = date->Import(text, dtFlags);
  91.         if (result == DTI_OK)
  92.             result = DateRangeCheck();
  93.         if (result != DTI_OK)
  94.         {
  95.             DateError(result);
  96.             ccode = S_ERROR;
  97.         }
  98.         else
  99.         {
  100.             if (needValidate && (*Validate)(this, ccode) != 0)
  101.                 ccode = S_ERROR;
  102.             else
  103.                 date->Export(text, fieldWidth, dtFlags);
  104.         }
  105.     }
  106.     else if (ccode == S_SIZE)
  107.     {
  108.         ccode = UIW_STRING::Event(event);
  109.         date->Export(text, fieldWidth, dtFlags);
  110.         return (ccode);
  111.     }
  112.     if (ccode != S_ERROR)
  113.     {
  114.         woStatus &= ~WOS_INVALID;
  115.         ccode = UIW_STRING::Event(event);
  116.     }
  117.     else
  118.         woStatus |= WOS_INVALID;
  119.     return(ccode);
  120. }
  121.  
  122. void UIW_DATE::DateError(int errorCode)
  123. {
  124.     static struct
  125.     {
  126.         int code;
  127.         char *msg;
  128.     } errorTable[] =
  129.     {
  130.         { DTI_INVALID,        "The date %s, is in an invalid format."         },
  131.         { DTI_AMBIGUOUS,    "The date %s, has an ambiguous month name."        },
  132.         { DTI_INVALID_NAME,    "The date %s, has an invalid month name."        },
  133.         { DTI_VALUE_MISSING,"A date value must be entered."                    },
  134.         { DTI_OK,            0                                                }
  135.     };
  136.     char formattedString[512];
  137.  
  138.     if (errorCode == DTI_OUT_OF_RANGE)
  139.         DateRangeError(formattedString);
  140.     else
  141.     {
  142.         strcpy(formattedString, "An unknown date error was received.");
  143.         for (int i = 0; errorTable[i].msg; i++)
  144.             if (errorTable[i].code == errorCode)
  145.             {
  146.                 sprintf(formattedString, errorTable[i].msg, text);
  147.                 break;
  148.             }
  149.     }
  150.     _errorSystem->ReportError(windowManager,
  151.         woFlags & (WOF_NO_UNANSWERED | WOF_NO_INVALID), formattedString);
  152. }
  153.  
  154. int UIW_DATE::DateRangeCheck()
  155. {
  156.     char minValue[20];
  157.     char maxValue[20];
  158.     int errorCode = DTI_OK;
  159.     int rangeLength;
  160.     int offset;
  161.  
  162.     /* See if a range exists */
  163.     if (!range || range[0] == '\0')
  164.         return (DTI_OK);
  165.  
  166.     offset = 0;
  167.     rangeLength = (range) ? strlen(range) : 0;
  168.     while (offset < rangeLength)
  169.     {
  170.         offset = ui_parse_range(range, offset, minValue, maxValue);
  171.         UI_DATE minDate(0, 0, 0);
  172.         UI_DATE maxDate(0, 0, 0);
  173.         int minValid = minDate.Import(minValue);
  174.         int maxValid = maxDate.Import(maxValue);
  175.         if (minValid != DTI_OK || maxValid != DTI_OK ||
  176.             *date < minDate || *date > maxDate)
  177.             errorCode = DTI_OUT_OF_RANGE;
  178.         else
  179.         {
  180.             errorCode = DTI_OK;
  181.             break;
  182.         }
  183.     }
  184.     return errorCode;
  185. }
  186.  
  187. void UIW_DATE::DateRangeError(char *fmtStr)
  188. {
  189.     char fmtMin[40];
  190.     char fmtMax[40];
  191.     char tempStr[80];
  192.     static char thruStr[] = "through";
  193.     static char orStr[] = "or";
  194.     int position;
  195.     int offset = 0;
  196.     int count = 0;
  197.     char sep = ',';                            // Separator character.
  198.     char badText[64];
  199.     int rangeLength = (range) ? strlen(range) : 0;
  200.  
  201.     date->Export(badText, sizeof(badText), dtFlags);
  202.     sprintf(fmtStr,
  203.         "The date %s is not valid.  The date must be in the range ", badText);
  204.     while (offset < rangeLength)
  205.     {
  206.         /* Format the current minimum and maximum values */
  207.         if (count == 1)
  208.         {
  209.             if (!strcmp(fmtMin, fmtMax))
  210.                 strcpy(tempStr, fmtMin);
  211.             else
  212.                 sprintf(tempStr, "%s %s %s", fmtMin, thruStr, fmtMax);
  213.             strcat(fmtStr, tempStr);
  214.         }
  215.         else if (count != 0)
  216.         {
  217.             if (!strcmp(fmtMin, fmtMax))
  218.                 sprintf(tempStr, "%c %s", sep, fmtMin);
  219.             else
  220.                 sprintf(tempStr, "%c %s %s %s", sep, fmtMin, thruStr, fmtMax);
  221.             strcat(fmtStr, tempStr);
  222.         }
  223.  
  224.         /* Get a new set of minimum and maximum values */
  225.         count++;
  226.         offset = ui_parse_range(range, offset, fmtMin, fmtMax);
  227.     }
  228.  
  229.     /* Append the final minimum and maximum values on the string */
  230.     if (count > 2 && !strcmp(fmtMin, fmtMax))
  231.         sprintf(tempStr, "%c %s %s.", sep, orStr, fmtMin);
  232.     else if (count > 2)
  233.         sprintf(tempStr, "%c %s %s %s %s.", sep, orStr, fmtMin, thruStr, fmtMax);
  234.     else if (count == 2 && !strcmp(fmtMin, fmtMax))
  235.         sprintf(tempStr, " %s %s.", orStr, fmtMin);
  236.     else if (count == 2)
  237.         sprintf(tempStr, " %s %s %s %s.", orStr, fmtMin, thruStr, fmtMax);
  238.     else if (count > 0)
  239.         sprintf(tempStr, "%s %s %s.", fmtMin, thruStr, fmtMax);
  240.     else
  241.     {
  242.         position = 0;        
  243.         while (fmtStr[position] != '\0' && fmtStr[position] != '.')
  244.             position++;
  245.         fmtStr[++position] = '\0';
  246.     }
  247.     strcat(fmtStr, tempStr);
  248. }
  249.  
  250. #ifdef ZIL_LOAD
  251. UIW_DATE::UIW_DATE(const char *name, UI_STORAGE *file, USHORT loadFlags) :
  252.     UIW_STRING(name, file, loadFlags | L_SUB_LEVEL)
  253. {
  254.     windowID[0] = ID_DATE;
  255.     windowID[1] = ID_STRING;
  256.  
  257.     if (!file)
  258.         file = _storage;
  259.     file->Load(&dtFlags);
  260.     file->Load(&range);
  261.     date = new UI_DATE(text, dtFlags);
  262.     if (!FlagSet(loadFlags, L_SUB_LEVEL) && FlagSet(file->stStatus, STS_TEMPORARY))
  263.         delete file;
  264. }
  265. #endif
  266.  
  267. #ifdef ZIL_STORE
  268. void UIW_DATE::Store(const char *name, UI_STORAGE *file, USHORT storeFlags)
  269. {
  270.     UIW_STRING::Store(name, file, storeFlags | S_SUB_LEVEL);
  271.     file->Store(dtFlags);
  272.     file->Store(range);
  273.     if (!FlagSet(storeFlags, S_SUB_LEVEL))
  274.         file->ObjectSize(name, search);
  275. }
  276. #endif
  277.