/*********************************************************************** * * TITLE: * selectfile.c * * AUTHOR: * Kevin J. Miller, Ana Maria Guerrero * * DESCRIPTION: * A generic OEL module. It contains routines which initailize * and control a popup use to select files for input and output. * * CHANGE HISTORY * * $Log: selectfile.c,v $ * Revision 1.18 1996/12/19 22:39:22 kevin * fixed compiler warnings * * Revision 1.17 1995/03/15 00:31:07 jeffb * prepend current working directory if default file name does not start * with a / * * Revision 1.16 1995/03/14 23:53:27 jeffb * add new function that is the same as FileSelect except allows caller * to specify default filename * * Revision 1.15 1994/11/22 17:52:06 jeffb * add a new function to change the title of the file selection box * traverse to the file name text widget if using explicit keyboardFocusPolicy * * Revision 1.14 1994/01/06 21:42:08 kevin * updates after SGI test * * Revision 1.13 1994/01/06 05:12:06 kevin * port for V20 * * Revision 1.12 1993/11/19 06:29:53 kevin * changed XmDIALOG_PRIMARY_APPLICATION_MODAL to * XmDIALOG_FULL_APPLICATION_MODAL * * Revision 1.11 1993/04/15 04:47:59 kevin * standardized and added new mesage functions * * Revision 1.10 1993/03/02 02:40:08 kevin * added shell management functions * * Revision 1.9 1992/08/05 21:02:12 kevin * added comments and standardized naming of functions * * Revision 1.8 1992/08/04 20:33:24 kevin * made extract_normal_string local * * Revision 1.7 1992/01/03 00:15:04 kevin * now use APPLICATION_PRIMARY_MODAL to allow focus to shift to help * dialogs * * Revision 1.6 1991/11/14 17:13:43 ana * Added help feature * * Revision 1.5 1991/10/04 16:54:32 ana * Added a warning for overwriting files. * * Revision 1.4 1991/06/15 00:39:20 kevin * put titles on dialog shells * * Revision 1.3 1991/06/10 20:57:15 kevin * set to return new filter value * * Revision 1.2 1991/04/12 01:11:31 kevin * added standard SFOC header * * Revision 1.1 1991/03/04 21:49:17 kevin * Initial revision * *********************************************************************** * * WARNINGS: * * EXTERNAL CALLABLE COMPONENTS (PUBLIC): * * GLOBALS: * * WAIVERS: * * NOTES: * * MANPAGE: * * NAME * InitFileSelect, FileSelect - pops up modal file * selection dialog box, and returns selected filename * * SYNOPSIS * InitFileSelect(parent, title) * Widget parent; * char *title; * * FileSelect(txtptr, filter, bewareFlagP, token) * FileSelectDefault(txtptr, filter, bewareFlagP, token) * char *txtptr; * char *filter; * int bewareFlagP; * char *token; * * FileSelectTitle(title) * char *title; * * DESCRIPTION * InitFileSelect is called once at the beginning of the * program to initialize the dialog box. Parent is the * application shell returned by the XtAppCreateShell function. * Title is the title on the mwm outline. Filter is the default * filter code. BewareFlagP will cause the Beware dialog to * appear if TRUE. Token is used for to look up help. This * function does not return a value. * * FileSelect will pop up the modal dialog box defined by the * InitFileSelect function. Txtptr is the returned file * name. If the user selected "Cancel" or closed the dialog, * the array txtptr points to is unchanged. Filter is a text * string used to set directories or select specific file naming * conventions. Filter is returned back to the caller (the user * can change the filter). Selectfile returns TRUE if a file was * selected (The "OK" button was pressed), and FALSE otherwise. * * FileSelectDefault is the same as FileSelect, but txtptr is also * an input parameter specifying the default file name. * * FileSelectTitle is used to change the title set by InitFileSelect. * ***********************************************************************/ #ifndef lint static const char rcsid[] = "$Id: selectfile.c,v 1.18 1996/12/19 22:39:22 kevin OEL $"; #endif #include #include #include #include #include #include #include #include #include #include #include "selectfile.h" #include "shellmgmt.h" #include "message.h" #include "beware.h" #include "help.h" /* * local function prototypes */ static void fileSelectOK(Widget, char *, XmSelectionBoxCallbackStruct *); static void fileSelectCancel(Widget, char *, XmSelectionBoxCallbackStruct *); static char *extractNormalString(XmString); /* * local variables */ static Widget fileSelect; /* FileSelectionBox widget */ static char *filename = NULL; /* string containing file name */ static int flag = FALSE; /* stay in this local event loop */ static int bewareFlag; /* flag for beware box */ static XtAppContext app; /* application context */ /*********************************************************************** * * FUNCTION: * InitFileSelect * * INPUTS: * parent - (Widget) the application shell * title - (char *) title for this popup * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * fileSelect - (Widget) created and set by this function * app - (XtAppContext) set by this function * * DESCRIPTION: * This fuction creates a FileSelectionBox widget and sets the * callbacks and WM Close behavior. */ void InitFileSelect(Widget parent, char *title) { XmString tmpString; /* title of widget */ Arg args[4]; Cardinal n; app = XtWidgetToApplicationContext(parent); tmpString = XmStringCreateSimple(title); n = 0; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++; XtSetArg(args[n], XmNdialogTitle, tmpString); n++; fileSelect = XmCreateFileSelectionDialog(parent, "fileSelectionBox", args, n); XtAddCallback(fileSelect, XmNokCallback, (XtCallbackProc)fileSelectOK, NULL); XtAddCallback(fileSelect, XmNcancelCallback, (XtCallbackProc)fileSelectCancel, NULL); XmStringFree(tmpString); /* * make MWM Close call the Cancel callback */ ShellAddClose(fileSelect, (XtCallbackProc)fileSelectCancel, NULL); } /*********************************************************************** * * FUNCTION: * FileSelect * FileSelectDefault * * INPUTS: * txtptr - (char *) default filename (for FileSelectDefault) * filter - (char *) filename filter * bewareFlagP - (int) use beware box if TRUE * token - (char *) lookup token for help * * OUTPUTS: * txtptr - (char *) returned filename * filter - (char *) filename filter * * RETURNS: * TRUE - on OK * FALSE - on Cancel * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: */ int FileSelect(char *txtptr, char *filter, int bewareFlagP, char *token) { *txtptr = '\0'; return FileSelectDefault(txtptr,filter,bewareFlagP,token); } int FileSelectDefault(char *txtptr, char *filter, int bewareFlagP, char *token) { XEvent event; /* event structure for loop */ XmString tmpString; /* Motif compound string */ char *ptr; /* temporary character pointer */ int value; /* return value */ Arg args[1]; /* Xt argument list */ Cardinal n; /* number of arguments */ Widget fileText; fileText = XmFileSelectionBoxGetChild(fileSelect, XmDIALOG_TEXT); /* * set up help */ XtRemoveAllCallbacks(fileSelect, XmNhelpCallback); XtAddCallback(fileSelect, XmNhelpCallback, (XtCallbackProc)ShowHelp, token); /* * set beware flag */ bewareFlag = bewareFlagP; /* * set filter */ tmpString = XmStringCreateSimple(filter); n = 0; XtSetArg(args[n], XmNdirMask, tmpString); n++; XtSetValues(fileSelect, args, n); ShellModalManage(fileSelect); XmStringFree(tmpString); /* * set default */ if (*txtptr != '\0') { char buf[1024]; int len; strncpy(buf,txtptr,sizeof(buf)); buf[sizeof(buf)-1] = '\0'; if (*txtptr != '/' && getcwd(buf,sizeof(buf)) != NULL) { len = strlen(buf); strncpy(buf+len,"/",sizeof(buf)-len); len++; strncpy(buf+len,txtptr,sizeof(buf)-len); buf[sizeof(buf)-1] = '\0'; } XmTextSetString(fileText, buf); XmTextSetInsertionPosition(fileText, (int)strlen(buf)); } /* * go directly to file name text widget if keyboardFocusPolicy is explicit */ XmProcessTraversal(fileText, XmTRAVERSE_CURRENT); /* * loop until OK or Cancel */ flag = TRUE; while (flag) { /* local event loop for popup */ XtAppNextEvent(app, &event); XtDispatchEvent(&event); } /* * return answer */ if (filename != NULL) { /* OK */ /* * copy filename */ ptr = filename; while ((*(txtptr++) = *(ptr++))); /* strcpy */ /* * copy filter */ n = 0; XtSetArg(args[n], XmNdirMask, &tmpString); n++; XtGetValues(fileSelect, args, n); ptr = extractNormalString(tmpString); XmStringFree(tmpString); while ((*(filter++) = *(ptr++))); /* strcpy */ value = TRUE; } else { /* cancel */ value = FALSE; } return value; } /*********************************************************************** * * FUNCTION: * FileSelectTitle * * INPUTS: * title - (char *) new title for dialog box * * OUTPUTS: * None * * RETURNS: * None * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Change title of file selection dialog box */ void FileSelectTitle(char *title) { XmString tmpString; /* title of widget */ Arg args[4]; Cardinal n; tmpString = XmStringCreateSimple(title); n = 0; XtSetArg(args[n], XmNdialogTitle, tmpString); n++; XtSetValues(fileSelect, args, n); XmStringFree(tmpString); } /*********************************************************************** * * FUNCTION: * fileSelectOK * * INPUTS: * w - (Widget) not used * client_data - (char *) not used * callback_data - (XmSelectionBoxCallbackStruct *) for filename * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * fileSelect - (Widget) to unmanage * bewareFlag - (static int) if TRUE use beware box * * EXTERNALLY MODIFIED: * flag - (static int) set to FALSE * * DESCRIPTION: * Callback for OK button. */ static void fileSelectOK(Widget w, char *client_data, XmSelectionBoxCallbackStruct *callback_data) { char buf[256]; struct stat statbuf; #if defined(spr) && defined(DEBUG) (void)w; /* parameter not used */ (void)client_data; /* parameter not used */ #endif if (filename != NULL) { XtFree(filename); filename = NULL; } filename = extractNormalString(callback_data->value); if (bewareFlag) { sprintf(buf, "File %s exists.\nDo you wish to overwrite?", filename); if ((stat(filename, &statbuf)) || (Beware(buf))) { ShellModalUnmanage(fileSelect); flag = FALSE; /* exit local loop */ } } else { ShellModalUnmanage(fileSelect); flag = FALSE; /* exit local loop */ } } /*********************************************************************** * * FUNCTION: * fileSelectCancel * * INPUTS: * w - (Widget) not used * client_data - (char *) not used * callback_data - (XmSelectionBoxCallbackStruct *) not used * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * fileSelect - (Widget) to unmanage * * EXTERNALLY MODIFIED: * flag - (static int) set to FALSE * * DESCRIPTION: * Callback for Cancel button. */ static void fileSelectCancel(Widget w, char *client_data, XmSelectionBoxCallbackStruct *callback_data) { #if defined(spr) && defined(DEBUG) (void)client_data; /* parameter not used */ (void)callback_data; /* parameter not used */ #endif if (!ShellValidateClose(w)) { Warning("Illegal attempt to close File Select"); return; } if (filename != NULL) { /* set to NULL -> no file selected */ XtFree(filename); filename = NULL; } ShellModalUnmanage(fileSelect); flag = FALSE; /* exit local loop */ } /*********************************************************************** * * FUNCTION: * extractNormalString * * INPUTS: * cs - (XmString) Motif compound string * * OUTPUTS: * none * * RETURNS: * primitiveString - (char *) standard string * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * Extracts the first component from a Motif compound string as * a character string. */ static char * extractNormalString(XmString cs) { XmStringContext context; XmStringCharSet charset; XmStringDirection direction; Boolean separator; static char *primitiveString; XmStringInitContext(&context, cs); XmStringGetNextSegment (context, &primitiveString, &charset, &direction, &separator); XmStringFreeContext (context); return primitiveString; }