home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume13 / xcal / part03 / xcal_popup.c < prev   
C/C++ Source or Header  |  1991-05-12  |  9KB  |  428 lines

  1. #ifndef lint
  2. static char *sccsid = "@(#)xcal_popup.c    3.5 (Hillside Systems) 1/16/91";
  3. static char *copyright = "@(#)Copyright 1989,1990 Peter Collinson, Hillside Systems";
  4. #endif  /* lint */
  5. /***
  6.  
  7. * module name:
  8.     xcal_popup.c
  9. * function:
  10.     Deal with various popups for xcal
  11.     There are two main ones:
  12.     a)    the centre button causes a popup date selection popup
  13.     b)    the right button causes an exit popup
  14. * history:
  15.     Written November 1989
  16.     Peter Collinson
  17.     Hillside Systems
  18. * (C) Copyright: 1989 Hillside Systems/Peter Collinson
  19.     
  20.     For full permissions and copyright notice - see xcal.c
  21. ***/
  22. #include <stdio.h>
  23. #include <ctype.h>
  24. #include <X11/Intrinsic.h>
  25. #include <X11/StringDefs.h>
  26. #include <X11/Shell.h>
  27. #include <X11/Xaw/Label.h>
  28. #include <X11/Xaw/Dialog.h>
  29. #include <X11/Xaw/AsciiText.h>
  30. #include "xcal.h"
  31.  
  32. static void AskDialog();
  33. static void NoCal();
  34. static void YesCal();
  35. static char *DateParse();
  36. static int MonScan();
  37. static void LeaveDialog();
  38. static void NoLeave();
  39. static void YesLeave();
  40. static  void NoEdit();
  41.  
  42. /*
  43.  *    This routine deals with most of the work to create
  44.  *    a dialog popup, it is passed a function which is called
  45.  *    to create the dialog box
  46.  *
  47.  *    The widget here is used for positioning, these popups are
  48.  *    always children of the toplevel widget
  49.  */
  50. void
  51. DialogPopup(w, fn, arg)
  52.     Widget    w;
  53.     void (*fn)();
  54.     caddr_t    arg;
  55. {
  56.     Widget    pop;
  57.     Arg    args[5];
  58.     Position x,y;
  59.     Position nx, ny;
  60.     Dimension width, height, border;
  61.     
  62.     /*
  63.      *    Get the position of the toplevel so we can
  64.      *    position the dialog box properly
  65.      */
  66.     XtSetArg(args[0], XtNwidth, &width);
  67.     XtSetArg(args[1], XtNheight, &height);
  68.     XtGetValues(w, args, 2);
  69.     XtTranslateCoords(w, (Position)(width/2),
  70.                           (Position)(height/2), &x, &y);
  71.                           
  72.     /*
  73.      *    Create a popup to hold the dialog
  74.      */
  75.     XtSetArg(args[0], XtNallowShellResize, True);
  76.     XtSetArg(args[1], XtNinput, True);
  77.     XtSetArg(args[2], XtNx, x);
  78.     XtSetArg(args[3], XtNy, y);
  79.     XtSetArg(args[4], XtNsaveUnder, TRUE);
  80.     pop = XtCreatePopupShell("question", transientShellWidgetClass, toplevel, args, 5);
  81.  
  82.     /*
  83.      *    Set up the dialog
  84.      */
  85.     (*fn)(pop, arg);
  86.  
  87.     XtRealizeWidget(pop);
  88.  
  89.     /*
  90.      *    We can now worry if this box is actually off the screen
  91.      */
  92.     XtSetArg(args[0], XtNwidth, &width);
  93.     XtSetArg(args[1], XtNheight, &height);
  94.     XtSetArg(args[2], XtNborderWidth, &border);
  95.     XtGetValues(pop, args, 3);
  96.  
  97.     border <<= 1;
  98.     XtTranslateCoords(pop, (Position)0, (Position)0, &nx, &ny);
  99.  
  100.     if ((nx + width + border) > WidthOfScreen(XtScreen(toplevel)))
  101.         nx = WidthOfScreen(XtScreen(toplevel)) - width - border;
  102.     else nx = x;
  103.  
  104.     if ((ny + height + border) > HeightOfScreen(XtScreen(toplevel)))
  105.         ny = HeightOfScreen(XtScreen(toplevel)) - height - border;
  106.     else ny = y;
  107.  
  108.     if (nx != x || ny != y)
  109.     {    XtSetArg(args[0], XtNx, nx);
  110.         XtSetArg(args[1], XtNy, ny);
  111.         XtSetValues(pop, args, 2);
  112.     }
  113.     XtPopup(pop, XtGrabNone);
  114. }
  115.  
  116. /************************************************************************/
  117. /*                                    */
  118. /*                                    */
  119. /*    Deals with middle button presses - ask for a date        */
  120. /*                                    */
  121. /*                                    */
  122. /************************************************************************/
  123.  
  124. /*
  125.  *    SetDate - ask for a date and start a calendar
  126.  *    This is an action routine
  127.  */
  128. /* ARGSUSED */
  129. void
  130. SetDate(w, event, params, numb)
  131.     Widget w;
  132.     XEvent *event;
  133.     String *params;
  134.     Cardinal *numb;
  135. {
  136.     DialogPopup(toplevel, AskDialog, NULL);
  137. }
  138.  
  139. /* ARGSUSED */
  140. static void
  141. AskDialog(pop, noop)
  142.     Widget pop;
  143.     Cardinal noop;
  144. {
  145.     Widget    dia;
  146.     Arg    args[2];
  147.     WidgetList children;    /* which is Widget children[] */
  148.     Cardinal num_children;
  149.     int    i;
  150.  
  151.     /* Take from args: "Enter mm yyyy?" */
  152.     XtSetArg(args[0], XtNvalue, "");
  153.     dia =  XtCreateManagedWidget("newdate", dialogWidgetClass, pop, args, 1);
  154.     XawDialogAddButton(dia, "ok", YesCal, dia);
  155.     XawDialogAddButton(dia, "cancel", NoCal, pop);
  156.     /*
  157.      *    I would like to add CR translations to the text box
  158.      *    the only way to get the widget seems to be to use
  159.      *    an R4 feature to get the WidgetList
  160.      */
  161.     XtSetArg(args[0], XtNchildren, &children);
  162.     XtSetArg(args[1], XtNnumChildren, &num_children);
  163.     XtGetValues(dia, (ArgList)args, 2);
  164.     for (i = 0; i < num_children; i++)
  165.     {    if (XtClass(children[i]) == asciiTextWidgetClass)
  166.         {    /* Bingo */
  167.             XtOverrideTranslations(
  168.                 children[i],
  169.                     XtParseTranslationTable("<Key>Return: SetDateAction()")
  170.                            );
  171.  
  172.         }
  173.         else
  174.         if (XtClass(children[i]) == labelWidgetClass)
  175.         {    XtSetArg(args[0], XtNresizable, True);
  176.             XtSetValues(children[i], args, 1);
  177.         }
  178.     }
  179.               
  180. }
  181.  
  182. /*
  183.  *    No we don't want a specified date
  184.  *    Closure here is the pop shell
  185.  */
  186. /* ARGSUSED */
  187. static void
  188. NoCal(w, closure, call_data)
  189.     Widget w;
  190.     caddr_t    closure;
  191.     caddr_t call_data;
  192. {
  193.     XtDestroyWidget((Widget)closure);
  194. }
  195.  
  196. /*
  197.  *    Yes we do want a specified date
  198.  *    Closure here is the dialog widget
  199.  */
  200. /* ARGSUSED */
  201. static void
  202. YesCal(w, closure, call_data)
  203.     Widget w;
  204.     caddr_t    closure;
  205.     caddr_t call_data;
  206. {
  207.     Widget    dia;
  208.     Arg    args[2];
  209.     Date    wanted;
  210.     char    *errstr;
  211.     
  212.     dia = (Widget)closure;
  213.     /*
  214.      *    Parse the string
  215.      */
  216.     if (errstr = DateParse(XawDialogGetValueString(dia), &wanted))
  217.     {    /* insert an error message in the widget */
  218.         XtSetArg(args[0], XtNlabel, errstr);
  219.         XtSetValues(dia, args, 1);
  220.         XBell(XtDisplay(toplevel), 0);
  221.         return;
  222.     }
  223.     XtDestroyWidget(XtParent(dia));
  224.     NewMonthStrip(&wanted);
  225. }
  226.  
  227. /*
  228.  *    Action mapped to by CR in the dialog
  229.  */
  230. /* ARGSUSED */
  231. void
  232. TextCal(w, event, params, numb)
  233.     Widget w;
  234.     XEvent *event;
  235.     String *params;
  236.     Cardinal *numb;
  237. {
  238.     YesCal(w, (caddr_t)XtParent(w), 0);    /* parent of text widget is the */
  239.                     /* dialog box */
  240. }
  241.  
  242. /*
  243.  *    Parse a date string
  244.  */
  245. static char *
  246. DateParse(str, da)
  247.     register char *str;
  248.     Date    *da;
  249. {
  250.     register char    *wk;
  251.     int    lastc;
  252.     int    mo;
  253.     
  254.     *da = today;
  255.  
  256.     wk = str;
  257.     while (isspace(*wk)) wk++;
  258.     if (*wk == '\0')
  259.         return("No data found");
  260.     str = wk;
  261.     if (isdigit(*str))
  262.     {    while (isdigit(*str))
  263.             str++;
  264.         lastc = *str;
  265.         *str++ = '\0';
  266.         mo = atoi(wk);
  267.         if (mo < 1 || mo > 12)
  268.             return("Illegal month number");
  269.         da->month = mo - 1;
  270.     }
  271.     else
  272.     if (isalpha(*str))
  273.     {    /* be kind - allow month names */
  274.         while (isalpha(*str))
  275.         {    if (isupper(*str))
  276.                 *str = tolower(*str);
  277.             str++;
  278.         }
  279.         lastc = *str;
  280.         *str++ = '\0';
  281.         mo = MonScan(wk);
  282.         if (mo < 0)
  283.             return("Cannot find month name");
  284.         da->month = mo;
  285.     }
  286.     if (lastc)
  287.     {    wk = str;
  288.         while(isspace(*wk))
  289.             wk++;
  290.         str = wk;
  291.         if (*str)
  292.             da->year = atoi(wk);
  293.     }
  294.     return(NULL);
  295. }
  296.  
  297. /*
  298.  *    Given a string look in our database for a number
  299.  */
  300. static int
  301. MonScan(monstr)
  302. char *monstr;
  303. {
  304.     char *a, *b;
  305.     int ca, cb;
  306.     int    mon;
  307.  
  308.     for (mon = 0; mon < 12; mon++)
  309.     for (a = monstr, b = appResources.mon[mon]; ;)
  310.     {    ca = *a++;
  311.         if(ca == '\0')
  312.             return(mon);
  313.         if (isupper(ca))
  314.             ca = tolower(ca);
  315.         cb = *b++;
  316.         if (cb == '\0')
  317.             break;
  318.         if (isupper(cb))
  319.             cb = tolower(cb);
  320.         if (ca != cb)
  321.             break;
  322.     }
  323.     return(-1);
  324. }
  325.  
  326. /************************************************************************/
  327. /*                                    */
  328. /*                                    */
  329. /*    Deals with right button presses - exit                */
  330. /*                                    */
  331. /*                                    */
  332. /************************************************************************/
  333. /*
  334.  *    Get out - possibly
  335.  */
  336. /* ARGSUSED */
  337. void
  338. AskLeave(w, event, params, numb)
  339.     Widget w;
  340.     XEvent *event;
  341.     String *params;
  342.     Cardinal *numb;
  343. {
  344.  
  345.     DialogPopup(toplevel, LeaveDialog, NULL);
  346. }
  347.  
  348. /* ARGSUSED */
  349. static void
  350. LeaveDialog(pop, noop)
  351.     Widget pop;
  352.     Cardinal noop;
  353. {    Widget    di;
  354.  
  355.     /* Take "Really exit? from resources */
  356.     di =  XtCreateManagedWidget("exit", dialogWidgetClass, pop, NULL, 0);
  357.     XawDialogAddButton(di, "yes", YesLeave, 0);
  358.     XawDialogAddButton(di, "no", NoLeave, pop);
  359. }
  360.  
  361. /* ARGSUSED */
  362. static void
  363. YesLeave(w, closure, call_data)
  364.     Widget w;
  365.     caddr_t    closure;
  366.     caddr_t call_data;
  367. {
  368.     Leave(0);
  369. }
  370.  
  371. /* ARGSUSED */
  372. static void
  373. NoLeave(w, closure, call_data)
  374.     Widget w;
  375.     caddr_t    closure;
  376.     caddr_t call_data;
  377. {
  378.     XtDestroyWidget((Widget)closure);
  379. }
  380.  
  381. /************************************************************************/
  382. /*                                    */
  383. /*                                    */
  384. /*    Deal with an attempt to double edit some data            */
  385. /*                                    */
  386. /*                                    */
  387. /************************************************************************/
  388.  
  389.  
  390. void
  391. NoEditIsPossible(w, da)
  392.     Widget    w;
  393.     Date    *da;
  394. {
  395.     static    char    errmsg[32];    
  396.  
  397.     (void) sprintf(errmsg, "Already editing %d %s %d", da->day, appResources.mon[da->month], da->year);
  398.  
  399.     DialogPopup(w, NoEdit, errmsg);
  400.  
  401. }
  402.  
  403. void
  404. NoDayEditIsPossible(w, day)
  405.     Widget    w;
  406.     Cardinal day;
  407. {
  408.     static    char    errmsg[32];    
  409.  
  410.     (void) sprintf(errmsg, "Already editing %s", appResources.day[day]);
  411.  
  412.     DialogPopup(w, NoEdit, errmsg);
  413.  
  414. }
  415.  
  416. static void
  417. NoEdit(pop, errmsg)
  418.     Widget    pop;
  419.     String    errmsg;
  420. {
  421.     Arg        args[2];
  422.     Widget        dia;
  423.  
  424.     XtSetArg(args[0], XtNlabel, errmsg);
  425.     dia =  XtCreateManagedWidget("noedit", dialogWidgetClass, pop, args, 1);
  426.     XawDialogAddButton(dia, "ok", NoCal, pop);
  427. }
  428.