Logo Search packages:      
Sourcecode: xcal version File versions  Download package

xcal_popup.c

#ifndef lint
static char    *sccsid = "@(#)xcal_popup.c      3.13 (Hillside Systems) 10/29/93";
static char    *copyright = "@(#)Copyright 1989,1990,1993 Peter Collinson, Hillside Systems";
#endif                        /* lint */
/***

* module name:
      xcal_popup.c
* function:
      Deal with various popups for xcal
      There are two main ones:
      a)    the centre button causes a popup date selection popup
      b)    the right button causes an exit popup
* history:
      Written November 1989
      Peter Collinson
      Hillside Systems
* (C) Copyright: 1989 Hillside Systems/Peter Collinson
      
      For full permissions and copyright notice - see xcal.c
***/
#include <stdio.h>
#include <ctype.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Command.h>
#include "xcal.h"

static void     AskDialog();
static void     NoCal();
static void     YesCal();
static char    *DateParse();
static int      MonScan();
static void     LeaveDialog();
static void     NoLeave();
static void     YesLeave();
static void     NoEdit();

#define argLD(N,V) { XtSetArg(args[nargs], N, V); nargs++; }

/*
 * This routine deals with most of the work to create a dialog popup, it is
 * passed a function which is called to create the dialog box
 * 
 * The widget here is used for positioning, these popups are always children of
 * the toplevel widget
 *
 * These widgets are generally called from a Command widget button.
 * if this is the case, we make that button non-sensitive and
 * use the pop-down callback to turn them on again (see xcal_buts.c)
 */
void
DialogPopup(w, fn, arg, but)
      Widget          w;
      void            (*fn) ();
      caddr_t         arg;
      Widget            but;
{
      Widget          pop;
      Arg             args[10];
      int         nargs;
      Position        x, y;
      Position        nx, ny;
      Dimension       width, height, border;

      /*
       * Get the position of the toplevel so we 
       * can position the dialog box properly
       */
      XtSetArg(args[0], XtNwidth, &width);
      XtSetArg(args[1], XtNheight, &height);
      XtGetValues(w, args, 2);
      XtTranslateCoords(w, (Position) (width / 2),
                    (Position) (height / 2), &x, &y);

      /*
       * Create a popup to hold the dialog
       */
      nargs = 0;
      argLD(XtNallowShellResize, True);
      argLD(XtNinput, True);
      argLD(XtNx, x);
      argLD(XtNy, y);
      argLD(XtNsaveUnder, FALSE);   /* was true but this caused */
                              /* me problems on OpenWindows */

      pop = XtCreatePopupShell("question", transientShellWidgetClass, toplevel, args, nargs);

      if (but && XtIsSubclass(but, commandWidgetClass))
            ButtonOff(but, pop);

      /*
       * Set up the dialog
       */
      (*fn) (pop, arg);

      XtRealizeWidget(pop);

      /*
       * We can now worry if this box is actually off the screen
       */
      XtSetArg(args[0], XtNwidth, &width);
      XtSetArg(args[1], XtNheight, &height);
      XtSetArg(args[2], XtNborderWidth, &border);
      XtGetValues(pop, args, 3);

      border <<= 1;
      XtTranslateCoords(pop, (Position) 0, (Position) 0, &nx, &ny);

      if ((int)(nx + width + border) > WidthOfScreen(XtScreen(toplevel)))
            nx = WidthOfScreen(XtScreen(toplevel)) - width - border;
      else
            nx = x;

      if ((int)(ny + height + border) > HeightOfScreen(XtScreen(toplevel)))
            ny = HeightOfScreen(XtScreen(toplevel)) - height - border;
      else
            ny = y;

      if (nx != x || ny != y) {
            XtSetArg(args[0], XtNx, nx);
            XtSetArg(args[1], XtNy, ny);
            XtSetValues(pop, args, 2);
      }
      XtPopup(pop, XtGrabNone);
}

/************************************************************************/
/*                                                    */
/*                                                    */
/*    Deals with middle button presses - ask for a date           */
/*                                                    */
/*                                                    */
/************************************************************************/

/*
 * SetDate - ask for a date and start a calendar
 * This is an action routine
 */
/* ARGSUSED */
void
SetDate(w, event, params, numb)
      Widget          w;
      XEvent         *event;
      String         *params;
      Cardinal       *numb;
{
      DialogPopup(toplevel, AskDialog, NULL, w);
}

/* ARGSUSED */
static void
AskDialog(pop, noop)
      Widget          pop;
      Cardinal        noop;
{
      Widget          dia;
      Arg             args[2];
      WidgetList      children;     /* which is Widget children[] */
      Cardinal        num_children;
      int             i;

      /* Take from args: "Enter mm yyyy?" */
      XtSetArg(args[0], XtNvalue, "");
      dia = XtCreateManagedWidget("newdate", dialogWidgetClass, pop, args, 1);
      XawDialogAddButton(dia, "ok", YesCal, dia);
      XawDialogAddButton(dia, "cancel", NoCal, pop);
      /*
       * I would like to add CR translations to the text box the only way
       * to get the widget seems to be to use an R4 feature to get the
       * WidgetList
       */
      XtSetArg(args[0], XtNchildren, &children);
      XtSetArg(args[1], XtNnumChildren, &num_children);
      XtGetValues(dia, (ArgList) args, 2);
      for (i = 0; i < num_children; i++) {
            if (XtClass(children[i]) == asciiTextWidgetClass) {
                  /* Bingo */
                  XtOverrideTranslations(
                                     children[i],
                                     XtParseTranslationTable("<Key>Return: SetDateAction()")
                        );

            } else
            if (XtClass(children[i]) == labelWidgetClass) {
                  XtSetArg(args[0], XtNresizable, True);
                  XtSetValues(children[i], args, 1);
            }
      }

}

/*
 * No we don't want a specified date
 * Closure here is the pop shell
 */
/* ARGSUSED */
static void
NoCal(w, closure, call_data)
      Widget          w;
      caddr_t         closure;
      caddr_t         call_data;
{
      XtDestroyWidget((Widget) closure);
}

/*
 * Yes we do want a specified date
 * Closure here is the dialog widget
 */
/* ARGSUSED */
static void
YesCal(w, closure, call_data)
      Widget          w;
      caddr_t         closure;
      caddr_t         call_data;
{
      Widget          dia;
      Arg             args[2];
      Date            wanted;
      char           *errstr;

      dia = (Widget) closure;
      /*
       * Parse the string
       */
      if (errstr = DateParse(XawDialogGetValueString(dia), &wanted)) {
            /*
             * insert an error                                           * message in the widget
             */
            XtSetArg(args[0], XtNlabel, errstr);
            XtSetValues(dia, args, 1);
            XBell(XtDisplay(toplevel), 0);
            return;
      }
      XtDestroyWidget(XtParent(dia));
      NewMonthStrip(&wanted, NULL);
}

/*
 * Action mapped to by CR in the dialog
 */
/* ARGSUSED */
void
TextCal(w, event, params, numb)
      Widget          w;
      XEvent         *event;
      String         *params;
      Cardinal       *numb;
{
      YesCal(w, (caddr_t) XtParent(w), 0);      /* parent of text widget is */
                                    /* the dialog box */
}

/*
 * Parse a date string
 */
static char    *
DateParse(str, da)
      register char  *str;
      Date           *da;
{
      register char  *wk;
      int             lastc;
      int             mo;

      *da = today;

      wk = str;
      while (isspace(*wk))
            wk++;
      if (*wk == '\0')
            return ("No data found");
      str = wk;
      if (isdigit(*str)) {
            while (isdigit(*str))
                  str++;
            lastc = *str;
            *str++ = '\0';
            mo = atoi(wk);
            if (mo < 1 || mo > 12)
                  return ("Illegal month number");
            da->month = mo - 1;
      } else if (isalpha(*str)) {   /* be kind - allow month names */
            while (isalpha(*str)) {
                  if (isupper(*str))
                        *str = tolower(*str);
                  str++;
            }
            lastc = *str;
            *str++ = '\0';
            mo = MonScan(wk);
            if (mo < 0)
                  return ("Cannot find month name");
            if (mo < da->month)
                  da->year++;
            da->month = mo;
      }
      if (lastc) {
            wk = str;
            while (isspace(*wk))
                  wk++;
            str = wk;
            if (*str)
                  da->year = atoi(wk);
      }
      return (NULL);
}

/*
 * Given a string look in our database for a number
 */
static int
MonScan(monstr)
      char           *monstr;
{
      char           *a, *b;
      int             ca, cb;
      int             mon;

      for (mon = 0; mon < 12; mon++)
            for (a = monstr, b = appResources.mon[mon];;) {
                  ca = *a++;
                  if (ca == '\0')
                        return (mon);
                  if (isupper(ca))
                        ca = tolower(ca);
                  cb = *b++;
                  if (cb == '\0')
                        break;
                  if (isupper(cb))
                        cb = tolower(cb);
                  if (ca != cb)
                        break;
            }
      return (-1);
}

/************************************************************************/
/*                                                    */
/*                                                    */
/*          Deals with right button presses - exit                */
/*                                                    */
/*                                                    */
/************************************************************************/
/*
 * Get out - possibly
 */
/* ARGSUSED */
void
AskLeave(w, event, params, numb)
      Widget          w;
      XEvent         *event;
      String         *params;
      Cardinal       *numb;
{

      DialogPopup(toplevel, LeaveDialog, NULL, w);
}

/* ARGSUSED */
static void
LeaveDialog(pop, noop)
      Widget          pop;
      Cardinal        noop;
{
      Widget          di;

      /* Take "Really exit? from resources */
      di = XtCreateManagedWidget("exit", dialogWidgetClass, pop, NULL, 0);
      XawDialogAddButton(di, "yes", YesLeave, pop);
      XawDialogAddButton(di, "no", NoLeave, pop);
}

/* ARGSUSED */
static void
YesLeave(w, closure, call_data)
      Widget          w;
      caddr_t         closure;
      caddr_t         call_data;
{
      Leave(0);
}

/* ARGSUSED */
static void
NoLeave(w, closure, call_data)
      Widget          w;
      caddr_t         closure;
      caddr_t         call_data;
{
      XtDestroyWidget((Widget) closure);
}

/************************************************************************/
/* */
/* */
/* Deal with an attempt to double edit some data                   */
/* */
/* */
/************************************************************************/


void
NoEditIsPossible(w, da)
      Widget          w;
      Date           *da;
{
      static char     errmsg[256];

      FmtDate(da, errmsg, sizeof errmsg, appResources.already);

      DialogPopup(w, NoEdit, errmsg, w);

}

void
NoDayEditIsPossible(w, da)
      Widget          w;
      Date           *da;
{
      static char     errmsg[256];

      FmtDate(da, errmsg, sizeof errmsg, appResources.alreadyWeekly);

      DialogPopup(w, NoEdit, errmsg, w);

}

static void
NoEdit(pop, errmsg)
      Widget          pop;
      String          errmsg;
{
      Arg             args[2];
      Widget          dia;

      XtSetArg(args[0], XtNlabel, errmsg);
      dia = XtCreateManagedWidget("noedit", dialogWidgetClass, pop, args, 1);
      XawDialogAddButton(dia, "ok", NoCal, pop);
}

Generated by  Doxygen 1.6.0   Back to index