Back to index

tetex-bin  3.0
xm_filesel.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 Marcin Dalecki and others
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00017  * PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
00018  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  */
00023 
00024 /*
00025  * Implementation of the File selection dialogue for the Motif GUI.
00026  */
00027 
00028 #include "xdvi-config.h"
00029 #include "xdvi.h"
00030 #include "sfSelFile.h"
00031 
00032 #include "dvi.h"
00033 #include "string-utils.h"
00034 #include "util.h"
00035 #include "events.h"
00036 #include "message-window.h"
00037 #include "dvi-init.h" /* for dviErrFlagT */
00038 
00039 #if defined(MOTIF) /* entire file */
00040 
00041 #include <Xm/FileSB.h>
00042 
00043 static Widget dialog = NULL;
00044 static char *browse_fname = NULL;
00045 
00046 /*
00047  * Process callback from Dialog cancel actions.
00048  */
00049 static void
00050 cancel_callback(Widget w,
00051               XtPointer client_data,
00052               XtPointer call_data)
00053 {
00054     struct filesel_callback *callback = (struct filesel_callback *)client_data;
00055 
00056     UNUSED(w);
00057     UNUSED(call_data);
00058 #if 0
00059     /* DON'T reset browse_fname, so that user gets the current
00060        value as default next time when he cancels now */
00061     if (browse_fname != NULL)
00062     {
00063        XtFree(browse_fname);
00064        browse_fname = NULL;
00065     }
00066 #endif
00067 
00068     XtUnmanageChild(dialog);
00069     if (callback->exit_on_cancel) {
00070        exit(0);
00071     }
00072 }
00073 
00074 /*
00075  * Process callback from Dialog actions.
00076  */
00077 
00078 static void
00079 accept_callback(Widget w,
00080               XtPointer client_data,
00081               XtPointer call_data)
00082 {
00083     XmFileSelectionBoxCallbackStruct *fcb;
00084     struct filesel_callback *callback;
00085     
00086     UNUSED(w);
00087 
00088     ASSERT(client_data != NULL, "struct filesel_callback pointer expected in client data");
00089     callback = (struct filesel_callback *)client_data;
00090 
00091     if (browse_fname != NULL) {
00092        XtFree(browse_fname);
00093        browse_fname = NULL;
00094     }
00095     fcb = (XmFileSelectionBoxCallbackStruct *)call_data;
00096 
00097     /* get the filename from the file selection box */
00098     XmStringGetLtoR(fcb->value, G_charset, &browse_fname);
00099 
00100     if (callback->must_exist) {
00101        FILE *tmp_fp = XFOPEN(browse_fname, "r");
00102        dviErrFlagT errflag = NO_ERROR;
00103        if (tmp_fp == NULL) {
00104            popup_message(XtParent(dialog),
00105                        MSG_ERR, NULL, "Could not open %s: %s.\n",
00106                        browse_fname, strerror(errno));
00107            /* leave file selection box open */
00108            return;
00109        }
00110        else if (!process_preamble(tmp_fp, &errflag)
00111                || !find_postamble(tmp_fp, &errflag)
00112                || !read_postamble(tmp_fp, &errflag, True)) {
00113            popup_message(XtParent(dialog),
00114                        MSG_ERR, NULL, "Error opening %s:\n%s.",
00115                        browse_fname, get_dvi_error(errflag));
00116            fclose(tmp_fp);
00117            /* leave file selection box open */
00118            return;
00119        }
00120        else { /* file is OK */
00121            fclose(tmp_fp);
00122        }
00123     }
00124 
00125     /* success; close dialog, and call our callback */
00126     XtUnmanageChild(dialog);
00127     callback->func_ptr(browse_fname, callback->data);
00128 }
00129 
00130 void raise_file_selector(void)
00131 {
00132     /* dummy */
00133     return;
00134 }
00135 
00136 void
00137 XsraSelFile(Widget parent, struct filesel_callback *callback)
00138 {
00139 #define ARG_CNT 4
00140     XmString filemask = NULL;
00141     XmString directory = NULL;
00142     Arg args[ARG_CNT];
00143     int i = 0;
00144 
00145     if (dialog == NULL) {
00146        dialog = XmCreateFileSelectionDialog(parent, "file", NULL, 0);
00147        /* Set ret_dialog to the DialogShell parent, not the command widget
00148           returned by the Motif routines.  We need the DialogShell, otherwise
00149           Motif will crash if ret_dialog is used as parent for popup_message()
00150           windows!!!
00151        */
00152        XtVaSetValues(XtParent(dialog), XmNtitle, callback->title, NULL);
00153        
00154        /*      my_must_exist = must_exist; */
00155        /*      XtAddCallback(dialog, XmNokCallback, accept_callback, (XtPointer)&my_must_exist); */
00156        XtAddCallback(dialog, XmNokCallback, accept_callback, (XtPointer)callback);
00157        XtAddCallback(dialog, XmNcancelCallback, cancel_callback, (XtPointer)callback);
00158        /* We have no help in this window, so hide help button */
00159        XtUnmanageChild(XmFileSelectionBoxGetChild(dialog, (unsigned char)XmDIALOG_HELP_BUTTON));
00160     }
00161     else if (XtIsManaged(dialog)) {
00162        XBell(DISP, 10);
00163        XRaiseWindow(DISP, XtWindow(dialog));
00164        return;
00165     }
00166 
00167     /* only show files matching our mask */
00168     filemask = XmStringCreateLtoR((char *)callback->filemask, G_charset);
00169     XtSetArg(args[i], XmNpattern, filemask); i++;
00170     
00171     /* set directory to last directory used */
00172     if (browse_fname != NULL) {
00173        char *path = xstrdup(browse_fname);
00174        char *ptr = strrchr(path, '/');
00175        if (ptr != NULL)
00176            *ptr = '\0';
00177        directory = XmStringCreateLtoR(path, G_charset);
00178        XtSetArg(args[i], XmNdirectory, directory); i++;
00179        free(path);
00180     }
00181     
00182     ASSERT(i < ARG_CNT, "args list too short");
00183     XtSetValues(dialog, args, (Cardinal)i);
00184 
00185     free(filemask);
00186     free(directory);
00187     
00188     XtManageChild(dialog);
00189 #undef ARG_CNT
00190 }
00191 
00192 #else
00193 /* silence `empty compilation unit' warnings */
00194 static void bar(void); static void foo() { bar(); } static void bar(void) { foo(); }
00195 #endif /* defined(MOTIF) */