home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / FACETV.ZIP / ANNOUNCE.CPP next >
C/C++ Source or Header  |  1994-01-04  |  9KB  |  373 lines

  1. /************************************************************************
  2. **
  3. ** @(#)announce.cpp        05/26/93    Chris Ahlstrom
  4. **
  5. **    C++ version.
  6. **
  7. **    Implements a general and extensible set of error and informational
  8. ** messages.
  9. **
  10. *************************************************************************/
  11.  
  12. #define ANNOUNCE_cpp
  13.  
  14. #include <conio.h>
  15. #include <ctype.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18.  
  19. #include "tinput.h"    // "Variations on TInputLine in C++", Op. 3.10
  20. #include "announce.h"    // generic error-handling on a small budget
  21. #include "boxtools.h"    // helpful support tools for simple monologues
  22.  
  23.  
  24. /************************************************************************
  25. ** UserMessages constructors
  26. **
  27. **    (Eventually) reads a file to obtain a list of messages; these
  28. ** messages are pointed to by errorMessages.
  29. **
  30. **    Actually, we have three versions of the constructor available
  31. ** (eventually):
  32. **
  33. **    1.  Creates a class with no messages available.  All callers
  34. **        of this class must provide their own ad hoc messages and
  35. **        use only the string version of the error handler.
  36. **
  37. **    2.  Creates a class assuming a list of messages has been created
  38. **        at compile-time as an array of strings.  The callers of this
  39. **        class can then use either version of errorHandler().
  40. **
  41. **    3.  Same as 2, but the messages are read in from a text-file.
  42. **        This version is not ready yet.
  43. **
  44. *************************************************************************/
  45.  
  46. UserMessages::UserMessages        // construct messages on the fly
  47. (
  48.     TDeskTop *desk            // the desktop for display
  49. ) :
  50.     deskTop        (desk),
  51.     Error        (ERR_NONE),
  52.     userMessages    (NULL),
  53.     userMessagesLength    (0),
  54.     usedErrorFile    (0)
  55. {
  56. }
  57.  
  58.  
  59. UserMessages::UserMessages        // construct messages from memory
  60. (
  61.     TDeskTop *desk,            // the desktop for display
  62.     char **msg_buffer,            // pointer to array of messages
  63.     unsigned length            // the number of pointers
  64. ) :
  65.     deskTop        (desk),
  66.     Error        (ERR_NONE),
  67.     userMessages    (msg_buffer),
  68.     userMessagesLength    (length),
  69.     usedErrorFile    (0)
  70. {
  71.     if (msg_buffer == NULL)
  72.     {
  73.     Error = ERR_NULL_POINTER;
  74.     deskTop = NULL;
  75.     }
  76. }
  77.  
  78.  
  79. UserMessages::UserMessages        // construct messages from a file
  80. (                    // NOT READY YET
  81.     TDeskTop *desk,
  82.     char *msg_file_name
  83. ) :
  84.     deskTop        (desk),
  85.     Error        (ERR_NONE),
  86.     usedErrorFile    (0)        // will set this to 1 if successful
  87. {
  88.     char **msg_buffer = NULL;
  89.     unsigned length = 0;
  90.  
  91.     /*
  92.     ** We will eventually implement messages in a data file.
  93.     ** For now, though, we'll use only memory
  94.     */
  95.  
  96.     userMessages        = msg_buffer;
  97.     userMessagesLength        = length;
  98.  
  99.     if (msg_buffer == NULL)
  100.     {
  101.     Error = ERR_NULL_POINTER;
  102.     deskTop = NULL;
  103.     }
  104. }
  105.  
  106.  
  107. /************************************************************************
  108. ** UserMessages::errorHandler (2 versions)
  109. **
  110. **    This function interfaces between any kind of code, and
  111. ** Turbo Vision.  If Turbo Vision is available, its resources are used
  112. ** for showing error messages, otherwise straight text output is
  113. ** used.
  114. **
  115. ** ERR_SHOW_NO_MESSAGE    Behavior needs no flagging to user
  116. ** ERR_NONE        Not an error message
  117. ** ERR_BAD_MESSAGE    Not to be used as an error code
  118. **
  119. **    Rather than provide one version, which uses a bogus parameter
  120. ** value (NULL) to indicate that a code is available, we provide
  121. ** two overloaded versions.  One accepts a message-code as a parameter
  122. ** (so the caller doesn't need to know the message contents), and the
  123. ** other uses a message pointers (so the caller provides the text
  124. ** of the message... a little dangerous or inflexible).
  125. **
  126. *************************************************************************/
  127.  
  128. static char *DEFAULT_BAD_MESSAGE =
  129.     "%%Message support erroneous for this part of the program!";
  130.  
  131. void
  132. UserMessages::errorHandler        // a message is provided
  133. (
  134.     char *message
  135. )
  136. {
  137.     if (message == NULL)
  138.     message = DEFAULT_BAD_MESSAGE;
  139.     Error = ERR_USER;
  140.  
  141.     errorBox(message, 0U);
  142. }
  143.  
  144.  
  145. void
  146. UserMessages::errorHandler        // a message code is provided
  147. (
  148.     int message
  149. )
  150. {
  151.     char *messstr;
  152.  
  153.     ErrorCode messagecode = (ErrorCode) message;
  154.     if (messagecode != ERR_SHOW_NO_MESSAGE)
  155.     {
  156.     if (messagecode < 0 || messagecode > userMessagesLength)
  157.         messstr = DEFAULT_BAD_MESSAGE;
  158.     else
  159.         messstr = userMessages[messagecode-1];
  160.     errorBox(messstr, 0U);
  161.     }
  162.     Error = messagecode;            // set this "global"
  163. }
  164.  
  165.  
  166. /************************************************************************
  167. ** UserMessages::errorBox
  168. **
  169. **    Displays a simple dialog box proclaiming an error condition.
  170. ** A single value may be optionally provided, in which case we
  171. ** hope the value and the message string (in the guise of a format
  172. ** string) match up.  If 0, the value is not used.
  173. **
  174. **    Called by errorHandler(), but can be called on its own, too.
  175. **
  176. *************************************************************************/
  177.  
  178. void
  179. UserMessages::errorBox
  180. (
  181.     char *message,
  182.     unsigned value
  183. )
  184. {
  185.     if (message == NULL)
  186.     {
  187.     message = "%Programming error";
  188.     }
  189.     else
  190.     {
  191.     if (strlen(message) > ERR_STRING_SIZE-8)    // for safety
  192.     {
  193.         message = "%Programming error";
  194.     }
  195.     else
  196.     {
  197.         if (value != 0U)
  198.         {
  199.         sprintf(errorString, message, value);
  200.         message = errorString;
  201.         }
  202.     }
  203.     }
  204.     messageBox(message, mfError | mfOKButton);
  205. }
  206.  
  207.  
  208. /************************************************************************
  209. ** UserMessages::confirmation
  210. **
  211. **    Simple way to get yes or no status.
  212. **
  213. *************************************************************************/
  214.  
  215. YesNoType
  216. UserMessages::confirmation
  217. (
  218.     char *string            // short message inside the box
  219. )
  220. {
  221.     ushort action;
  222.     YesNoType code;
  223.  
  224.     code = NO;
  225.  
  226.     action = messageBox(string, mfWarning | mfOKCancel);
  227.     if (action == cmOK)
  228.     code = YES;
  229.     return code;
  230. }
  231.  
  232.  
  233. /************************************************************************
  234. ** UserMessages::lastError()
  235. **
  236. **    Provides access to the private error code for the latest error.
  237. **
  238. *************************************************************************/
  239.  
  240. ErrorCode
  241. UserMessages::lastError ()
  242. {
  243.     return Error;
  244. }
  245.  
  246.  
  247. /************************************************************************
  248. ** UserMessages::prompt
  249. **
  250. **    Simple way to get yes or no status.
  251. **
  252. *************************************************************************/
  253.  
  254. int
  255. UserMessages::prompt
  256. (
  257.     char *string            // short message inside the box
  258. )
  259. {
  260.     ushort action;
  261.     int code;
  262.  
  263.     code = NO;
  264.  
  265.     action = messageBox(string, mfInformation|mfOKCancel);
  266.     if (action == cmOK)
  267.     code = YES;
  268.     return code;
  269. }
  270.  
  271.  
  272. /************************************************************************
  273. ** UserMessages::msgHandler()
  274. **
  275. **    More robust and flexible way to present messages.
  276. **
  277. *************************************************************************/
  278.  
  279. void
  280. UserMessages::msgHandler
  281. (
  282.     char *string
  283. )
  284. {
  285.     if (string == NULL)
  286.     string = "\n%%Programmer: null string passed to msgHandler\n";
  287.  
  288.     (void) messageBox(string, mfInformation|mfOKButton);
  289. }
  290.  
  291.  
  292. /************************************************************************
  293. ** UserMessages::bannerHandler
  294. **
  295. **    Handles banner strings by first determining the width (in
  296. ** characters) and height (in lines) of the banner, then generating
  297. ** the appropriate box.
  298. **
  299. **    The user must click on the OK button to continue.  There
  300. ** is only a return value of non-ERR_NONE if an internal problem
  301. ** occurred.
  302. **
  303. *************************************************************************/
  304.  
  305. ErrorCode
  306. UserMessages::bannerHandler
  307. (
  308.     char *message
  309. )
  310. {
  311.     if (message == NULL)
  312.     {
  313.     message = "%%Programming error";
  314.     }
  315.  
  316.     ErrorCode error = ERR_NONE;
  317.     TPoint banner;            // calculated size of text
  318.     TRect box;                // calculated size of dialog
  319.  
  320.     banner    = banner_size(message);    // dimensions of the banner
  321.     box        = banner_spec(banner);    // box banner fits into
  322.  
  323.     TDialog *pd = new TDialog(box, "Information");
  324.  
  325.     if (pd)                // did it work above?
  326.     {
  327.     TRect text;            // location and extent of text
  328.  
  329.     text.a.x = BOX_MARGIN;        // move to text boundary
  330.     text.a.y = BOX_TOP;        // move to text line
  331.     text.b.x = banner.x;        // width of the text
  332.     text.b.y = banner.y;        // heigth of the text
  333.     text.b  += text.a;        // lower right corner of text
  334.  
  335.     TView *b = new TStaticText(text, message);
  336.     if (b)
  337.     {
  338.         pd->insert(b);        // display the text
  339.  
  340.         TRect button;
  341.  
  342.         button = banner_OK(box);    // location of button in box
  343.         b = new TButton(button, "~O~K", cmOK, bfDefault);
  344.         if (b)
  345.         pd->insert(b);        // display the OK button
  346.  
  347.         ushort control;
  348.         control = deskTop->execView(pd);    // display the whole box
  349.  
  350.         /*
  351.         ** Since there is no Cancel button, the following code
  352.         ** serves no purpose.  Oh, well!
  353.         */
  354.  
  355.         if (control != cmCancel)
  356.         error = ERR_NONE;
  357.         else
  358.         error = ERR_USER_ABORT;
  359.     }
  360.     else
  361.     {
  362.         TView *b = new TStaticText(TRect(4,4,16,5), "DIALOG ERROR");
  363.         if (b)
  364.         pd->insert(b);
  365.         deskTop->execView(pd);
  366.         error = ERR_DIALOG;
  367.     }
  368.     deskTop->destroy(pd);        // remove the box now
  369.     }
  370.     return error;
  371. }
  372.  
  373.