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