home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / UNIX / ARCHIE / CLIENTS / XARCHIE-.1 / FCHOOSER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-22  |  8.2 KB  |  261 lines

  1. /*
  2.  * fchooser.c : Xarchie interface to the FileChooser
  3.  *
  4.  * The FileChooser enforces very little policy. This wrapper adds
  5.  * the following:
  6.  * - The FileChooser is created with several other widgets: a Text
  7.  *   widget, and OK button, and a cancel button. These are created in
  8.  *   the sameparent, but other widgets can also be there.
  9.  * - Selecting a file in the FileChooser just puts the string in the
  10.  *   Text widget. You have to hit Ok to use it.
  11.  * - When ok is clicked or Return typed, the directory from the fileChooser
  12.  *   and the file from the Text are concatenated. If the result is a
  13.  *   directory, the fileChooser is reset to that directory. Otherwise
  14.  *   the callback is called with the filename as call_data.
  15.  * - Leading tildes are expanded in directories entered in the Text widget.
  16.  *
  17.  * Oh yeah, if FILECHOOSER is not defined, ignore all that about it. In that
  18.  * case we just have a Text and two buttons.
  19.  *
  20.  * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  21.  *
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <X11/Intrinsic.h>
  28. #include <X11/StringDefs.h>
  29. #include <X11/keysym.h>
  30. #include <X11/Xaw/Form.h>
  31. #include <X11/Xaw/Label.h>
  32. #include <X11/Xaw/AsciiText.h>
  33. #include <X11/Xaw/Command.h>
  34. #ifdef FILECHOOSER
  35. #include <FChooser.h>
  36. #endif
  37. #include "fchooser.h"
  38. #include "xarchie.h"
  39. #include "xutil.h"
  40. #include "tilde.h"
  41. #include "status.h"
  42. #include "alert.h"
  43. #include "debug.h"
  44.  
  45. /*
  46.  * Functions defined here:
  47.  */
  48. FileChooserInfo *createFileChooser(
  49. #if NeedFunctionPrototypes
  50.     Widget shell,
  51.     Widget parent,
  52.     char *basename,
  53.     FileChooserOkProc okCallback,
  54.     FileChooserCancelProc cancelCallback,
  55.     XtPointer client_data
  56. #endif
  57. );
  58.  
  59. static void fileChooserCallback(),okButtonCallback(),cancelButtonCallback();
  60. static void keyPressEventHandler(),nonmaskableEventHandler();
  61.  
  62. /*    -    -    -    -    -    -    -    -    */
  63.  
  64. FileChooserInfo *
  65. createFileChooser(shell,parent,basename,okCallback,cancelCallback,client_data)
  66. Widget shell,parent;
  67. char *basename;
  68. FileChooserOkProc okCallback;
  69. FileChooserCancelProc cancelCallback;
  70. XtPointer client_data;
  71. {
  72.     FileChooserInfo *info;
  73.     char name[64];
  74.     Arg args[1];
  75.  
  76.     info = XtNew(FileChooserInfo);
  77.     info->shell = shell;
  78.     info->okCallback = okCallback;
  79.     info->cancelCallback = cancelCallback;
  80.     info->client_data = client_data;
  81. #ifdef FILECHOOSER
  82.     status0("Initializing File Selector...");
  83.     sprintf(name,"%sFileChooser",basename);
  84.     info->fcw =
  85.     XtCreateManagedWidget(name,xfwfFileChooserWidgetClass,parent,NULL,0);
  86.     XtAddCallback(info->fcw,XtNcallback,fileChooserCallback,(XtPointer)info);
  87.     status0("Done.");
  88.     XtSetArg(args[0],XtNfromVert,info->fcw);
  89. #else
  90.     XtSetArg(args[0],XtNfromVert,NULL);
  91. #endif
  92.     sprintf(name,"%sTextLabel",basename);
  93.     (void)XtCreateManagedWidget(name,labelWidgetClass,parent,args,1);
  94.     sprintf(name,"%sText",basename);
  95.     info->text =
  96.     XtCreateManagedWidget(name,asciiTextWidgetClass,parent,args,1);
  97.     sprintf(name,"%sOkButton",basename);
  98.     info->okButton =
  99.     XtCreateManagedWidget(name,commandWidgetClass,parent,NULL,0);
  100.     XtAddCallback(info->okButton,XtNcallback,okButtonCallback,(XtPointer)info);
  101.     /* Allow Return in the Text to be Ok */
  102.     XtAddEventHandler(info->text,KeyPressMask,False,
  103.               keyPressEventHandler,(XtPointer)info);
  104.     sprintf(name,"%sCancelButton",basename);
  105.     info->cancelButton =
  106.     XtCreateManagedWidget(name,commandWidgetClass,parent,NULL,0);
  107.     XtAddCallback(info->cancelButton,XtNcallback,
  108.           cancelButtonCallback,(XtPointer)info);
  109.     /* Allow WM_DELETE_WINDOW to the Shell to be Cancel */
  110.     if (info->shell != NULL)
  111.     XtAddEventHandler(info->shell,NoEventMask,True,
  112.               nonmaskableEventHandler,(XtPointer)info);
  113.     return(info);
  114. }
  115.  
  116. /*
  117.  * When a selection is made, put the string in the Text item. If background
  118.  * selected, clear the Text item.
  119.  */
  120. /*ARGSUSED*/
  121. static void
  122. fileChooserCallback(w,client_data,call_data)
  123. Widget w;
  124. XtPointer client_data;    /* info */
  125. XtPointer call_data;    /* return struct */
  126. {
  127.     FileChooserInfo *fcinfo = (FileChooserInfo *)client_data;
  128.     XfwfFileChooserReturnStruct *ret =
  129.     (XfwfFileChooserReturnStruct *)call_data;
  130.     Arg args[1];
  131.  
  132.     DEBUG1("fileChooserCallback: fcinfo=0x%lx\n",fcinfo);
  133.     if (fcinfo == NULL || fcinfo->text == NULL)        /* creating */
  134.     return;
  135.     if (ret->file == NULL) {
  136.     XtSetArg(args[0],XtNstring,"");
  137.     } else {
  138.     XtSetArg(args[0],XtNstring,ret->file);
  139.     }
  140.     XtSetValues(fcinfo->text,args,1);
  141.     DEBUG0("fileChooserCallback: done\n");
  142. }
  143.  
  144. /*
  145.  * If Ok is clicked, get the directory from the FileChooser (if FILECHOOSER)
  146.  * and get the filename from the Text. Do tilde expansion. If result is
  147.  * a directory, use it in the FileChooser, otherwise invoke the callback
  148.  * passing filename and client_data. Finally free the info.
  149.  */
  150. /*ARGSUSED*/
  151. static void
  152. okButtonCallback(w,client_data,call_data)
  153. Widget w;
  154. XtPointer client_data;    /* info */
  155. XtPointer call_data;    /* not used */
  156. {
  157.     FileChooserInfo *fcinfo = (FileChooserInfo *)client_data;
  158.     static char filename[MAXPATHLEN];
  159.     struct stat statbuf;
  160.     char *dir,*file;
  161.  
  162.     DEBUG1("okButtonCallback: fcinfo=0x%lx\n",fcinfo);
  163.     filename[0] = '\0';
  164. #ifdef FILECHOOSER
  165.     dir = XfwfFileChooserCurrentDirectory((XfwfFileChooserWidget)(fcinfo->fcw));
  166.     DEBUG1("okButtonCallback: dir=\"%s\"\n",dir);
  167. #endif
  168.     file = getWidgetString(fcinfo->text);
  169.     if (file == NULL || *file == '\0') {
  170.     alert0("No filename specified!");
  171.     return;
  172.     }
  173.     DEBUG1("okButtonCallback: file=\"%s\"\n",file);
  174.     if (*file == '/') {                    /* absolute path */
  175.     strcpy(filename,file);
  176.     } else if (*file == '~') {                /* tilde path */
  177.     strcpy(filename,tildeExpand(file));
  178.     } else {                        /* relative to fcw */
  179.     sprintf(filename,"%s%s",dir,file);
  180.     }
  181.     DEBUG1("okButtonCallback: filename=\"%s\"\n",filename);
  182. #ifdef FILECHOOSER
  183.     /* If we got a directory, go open it rather than use it */
  184.     if (stat(filename,&statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
  185.     XfwfFileChooserChangeDirectory((XfwfFileChooserWidget)fcinfo->fcw,
  186.                        filename);
  187.     return;
  188.     }
  189. #endif    
  190.     if (fcinfo->okCallback != NULL) {
  191.     DEBUG0("okButtonCallback: calling okCallback...\n");
  192.     (*(fcinfo->okCallback))(fcinfo,filename,fcinfo->client_data);
  193.     }
  194.     DEBUG0("okButtonCallback: done\n");
  195. }
  196.  
  197. /*
  198.  * If Cancel is clicked, invoke the callback passing client_data.
  199.  * Finally free the info.
  200.  */
  201. /*ARGSUSED*/
  202. static void
  203. cancelButtonCallback(w,client_data,call_data)
  204. Widget w;
  205. XtPointer client_data;    /* fcinfo */
  206. XtPointer call_data;    /* not used */
  207. {
  208.     FileChooserInfo *fcinfo = (FileChooserInfo *)client_data;
  209.  
  210.     DEBUG1("cancelButtonCallback: fcinfo=0x%lx\n",fcinfo);
  211.     if (fcinfo->cancelCallback != NULL) {
  212.     DEBUG0("cancelButtonCallback: calling cancelCallback\n");
  213.     (*(fcinfo->cancelCallback))(fcinfo,fcinfo->client_data);
  214.     }
  215.     DEBUG0("cancelButtonCallback: done\n");
  216. }
  217.  
  218. /*
  219.  * KeyPress event handler for Text item: When Return is typed, act as if
  220.  * OK had been clicked. If this event isn't Return, just let it be
  221.  * dispatched normally.
  222.  */
  223. static void
  224. keyPressEventHandler(w,client_data,event,continue_to_dispatch)
  225. Widget w;
  226. XtPointer client_data;
  227. XEvent *event;
  228. Boolean *continue_to_dispatch;
  229. {
  230.     KeySym keysym;
  231.     char str[8];
  232.  
  233.     DEBUG1("keyPressHandler: w=0x%x\n",w);
  234.     (void)XLookupString((XKeyEvent*)event,str,sizeof(str),&keysym,NULL);
  235.     if (keysym == XK_Return) {
  236.     DEBUG0("keyPressHandler: calling okButtonCallback...\n");
  237.     okButtonCallback(NULL,client_data,NULL);
  238.     }
  239.     DEBUG0("keyPressHandler: done\n");
  240. }
  241.  
  242. /*
  243.  * Nonmaskable event handler for Shell: If the event is a ClientMessage
  244.  * of WM_PROTOCOLS then act as if Cancel had been clicked.
  245.  */
  246. static void
  247. nonmaskableEventHandler(w,client_data,event,continue_to_dispatch)
  248. Widget w;
  249. XtPointer client_data;
  250. XEvent *event;
  251. Boolean *continue_to_dispatch;
  252. {
  253.     DEBUG1("nonmaskableHandler: w=0x%x\n",w);
  254.     if (event->type == ClientMessage &&
  255.         event->xclient.data.l[0] == WM_DELETE_WINDOW) {
  256.     DEBUG0("nonmaskableHandler: calling cancelButtonCallback\n");
  257.     cancelButtonCallback(NULL,client_data,NULL);
  258.     }
  259.     DEBUG0("nonmaskableHandler: done\n");
  260. }
  261.