Back to index

tetex-bin  3.0
print-dialog.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2002-2004 Paul Vojta and the xdvik development team
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   SU: Adapted from non-k xdvi's popups.c
00025 
00026   This implements a print popup (and a `save to file' popup).  My idea
00027   was to use the same window layout framework for both tasks, since
00028   there's a big overlap in the widgets needed.  However after looking
00029   at the mess I've created, I'm no longer convinced this was a good
00030   idea. (I reckon it's slightly better than the code duplication when
00031   doing it in separate files, but only *slightly* ...)
00032   
00033   We need a more intelligent approach that bans this ugly kind of
00034   `data proliferation' (those global arrays of widgets and helper
00035   structures).  Custom Widgets? Factory methods? Needs investigation.
00036 
00037   Also, in the long run, I guess we want the `Save' window to be more
00038   similar to the file browser (i.e. to contain a file browser e.g.
00039   in the upper part); in that case, the code will be moved into another
00040   module anyway.
00041 
00042   Moreover, the GUI code should be completely separated from the backend
00043   code.  
00044 */
00045 
00046 #include <string.h>
00047 #include "xdvi-config.h"
00048 #include "xdvi.h"
00049 #include "my-vsnprintf.h"
00050 #include <ctype.h>
00051 
00052 #include "print-dialog.h"
00053 #include "print-log.h"
00054 #include "print-internal.h"
00055 #include "events.h"
00056 #include "dvi-init.h"
00057 #include "string-utils.h"
00058 #include "util.h"
00059 #include "x_util.h"
00060 #include "message-window.h"
00061 #include "pagesel.h"
00062 #include "my-snprintf.h"
00063 #include "sfSelFile.h"
00064 #include "dvisel.h" /* for select_marked_pages() */
00065 #include "xlwradio.h"
00066 #include "statusline.h"
00067 #include "search-dialog.h"
00068 #include "search-internal.h"
00069 #include "special.h"
00070 
00071 /* Xlib and Xutil are already included */
00072 
00073 
00074 #include <X11/Xatom.h>
00075 #include <X11/StringDefs.h>
00076 
00077 #ifdef MOTIF
00078 # include <Xm/BulletinB.h>
00079 # include <Xm/DialogS.h>
00080 # include <Xm/PanedW.h>
00081 # include <Xm/MessageB.h>
00082 # include <Xm/LabelG.h>
00083 # include <Xm/Form.h>
00084 # include <Xm/Frame.h>
00085 # include <Xm/ToggleBG.h>
00086 # include <Xm/Text.h>
00087 # include <Xm/TextF.h>
00088 # include <Xm/PushB.h>
00089 # include <Xm/Protocols.h>
00090 # include <Xm/AtomMgr.h>
00091 #define XTranslations XmNtranslations
00092 #else /* MOTIF */
00093 # include <X11/Shell.h>
00094 # include <X11/Xaw/Paned.h>
00095 # include <X11/Xaw/Box.h>
00096 # include <X11/Xaw/Form.h>
00097 # include <X11/Xaw/Label.h>
00098 # include <X11/Xaw/Command.h>
00099 # include <X11/Xaw/Toggle.h>
00100 # include <X11/Xaw/AsciiText.h>
00101 # include <X11/Xaw/SimpleMenu.h>
00102 # include <X11/Xaw/MenuButton.h>
00103 # include <X11/Xaw/Sme.h>
00104 # include <X11/Xaw/SmeBSB.h>
00105 #if 0
00106 #include "xaw_bitmaps.h"
00107 static Pixmap menu_double_arrow_bitmap;
00108 #endif
00109 #define XTranslations XtNtranslations
00110 #endif /* MOTIF */
00111 
00112 struct output_format_mapping {
00113     const char *fmt_string;
00114     outputFormatT fmt;
00115     const char *extension;
00116 } output_format_mapping[] = {
00117     { "Postscript",         FMT_PS ,      ".ps"  },
00118     { "PDF",                FMT_PS2PDF,   ".pdf" },
00119     { "DVI",                FMT_DVI,      ".dvi" },
00120     { "Plain Text (ISO_8859-1)",FMT_ISO_8859_1,  ".txt" },
00121     { "Plain Text (UTF-8)", FMT_UTF8,     ".txt" },
00122     { NULL,                 FMT_NONE,     NULL   }
00123 };
00124 
00125 typedef enum printRadioT_ {
00126     NO_PRINT_VAL = -1,
00127     PRINT_TO_PRINTER = 1,
00128     PRINT_TO_FILE,
00129     SAVE_TO_FILE
00130 } printRadioT;
00131 
00132 
00133 typedef enum pageRadioT_ {
00134     NO_PAGE_VAL = -1,
00135     PRINT_ALL = 1,
00136     PRINT_MARKED,
00137     PRINT_RANGE,
00138     SAVE_ALL,
00139     SAVE_MARKED,
00140     SAVE_RANGE
00141 } pageRadioT;
00142 
00143 static Boolean is_print_button(pageRadioT flag) {
00144     return (flag <= PRINT_RANGE);
00145 }
00146 
00147 struct dialog_info {
00148     char *printer_name;
00149     char *file_name;
00150     /* fully canonicalized filename, not visible in window, but used in error messages.
00151        It is either NULL, or a malloc()ed buffer (which is free()d immediately before use). */
00152     char *expanded_filename;
00153     char *dvips_options;
00154     char *from_page;
00155     char *to_page;
00156     printRadioT print_radio;
00157     pageRadioT range_radio;
00158     outputFormatT output_format;
00159 };
00160 
00161 /*
00162   global widgets, and arrays of global widgets (mosly, one
00163   for the printing and one for the saving dialog). Needs
00164   cleanup!
00165 */
00166 
00167 #define FORMAT_SEL_CNT 5
00168 
00169 /* top-level widgets: one for printing, one for saving to file */
00170 static Widget print_shell = NULL;
00171 static Widget save_shell = NULL;
00172 
00173 /* global structures for saving print info between invocations */
00174 static struct dialog_info save_pr_info = {
00175     NULL, NULL, NULL, NULL, NULL, NULL, NO_PRINT_VAL, NO_PAGE_VAL, FMT_NONE
00176 };
00177 static struct dialog_info save_save_info = {
00178     NULL, NULL, NULL, NULL, NULL, NULL, NO_PRINT_VAL, NO_PAGE_VAL, FMT_NONE
00179 };
00180 
00181 /*
00182   these contain the currently selected values, or defaults;
00183   used in communication between callbacks
00184 */
00185 static struct dialog_info curr_pr_info = {
00186     NULL, NULL, NULL, NULL, NULL, NULL, PRINT_TO_PRINTER, PRINT_ALL, FMT_NONE
00187 };
00188 static struct dialog_info curr_save_info = {
00189     NULL, NULL, NULL, NULL, NULL, NULL, SAVE_TO_FILE, SAVE_ALL, FMT_NONE
00190 };
00191 
00192 static void print_precheck1(XtPointer info);
00193 static void print_precheck2(XtPointer info);
00194 
00195 /* access methods ... */
00196 const char *
00197 get_printer_options(void)
00198 {
00199     return save_pr_info.printer_name;
00200 }
00201 
00202 char *
00203 get_dvips_options(printOrSaveActionT act)
00204 {
00205     if (act == FILE_PRINT)
00206        return save_pr_info.dvips_options;
00207     else
00208        return save_save_info.dvips_options;
00209 }
00210 
00211 #ifdef MOTIF
00212 static Widget from_label[FILE_ALL] = { None, None };
00213 static Widget format_selection_option;
00214 XmString format_selection_texts[FORMAT_SEL_CNT];
00215 
00216 #else /* MOTIF */
00217 
00218 static Widget format_selection_label;
00219 static Widget format_selection_button;
00220 #if 0
00221 static Widget format_selection_b1;
00222 #endif
00223 static Widget format_selection_popup;
00224 static Widget format_selection_menu[FORMAT_SEL_CNT];
00225 
00226 static void xaw_print_save_act_go(Widget, XEvent *, String *, Cardinal *);
00227 
00228 #endif /* MOTIF */
00229 
00230 static void print_cancel(Widget, XEvent *, String *, Cardinal *);
00231 static void save_cancel(Widget, XEvent *, String *, Cardinal *);
00232 
00233 static Widget to_printer_radio;
00234 static Widget to_file_radio_or_label[FILE_ALL] = { None, None };
00235 static Widget to_label[FILE_ALL] = { None, None };
00236 static Widget of_label[FILE_ALL] = { None, None };
00237 static Widget range_all_radio[FILE_ALL] = { None, None };
00238 static Widget range_marked_radio[FILE_ALL] = { None, None };
00239 static Widget range_from_to_radio[FILE_ALL] = { None, None };
00240 static Widget cancel_button[FILE_ALL] = { None, None };
00241 static Widget ok_button[FILE_ALL] = { None, None };
00242 static Widget print_to_printer_text;
00243 static Widget print_to_file_text[FILE_ALL] = { None, None };
00244 static Widget print_to_file_button[FILE_ALL] = { None, None };
00245 static Widget dvips_options_text[FILE_ALL] = { None, None };
00246 static Widget page_from_text[FILE_ALL] = { None, None };
00247 static Widget page_to_text[FILE_ALL] = { None, None };
00248 
00249 static int print_is_active = False;       /* False if window is unmanaged or not created yet, True if managed */
00250 static int save_is_active = False; /* False if window is unmanaged or not created yet, True if managed */
00251 
00252 
00253 static XtActionsRec print_actions[] = {
00254 #ifndef MOTIF
00255     {"saveInternal",        xaw_print_save_act_go },
00256     {"printInternal",              xaw_print_save_act_go},
00257 #endif
00258     {"WM_print_cancel",            print_cancel },
00259     {"WM_save_cancel",             save_cancel  },
00260 };
00261 
00262 /*
00263   ============================================================
00264   generic utility functions
00265   ============================================================
00266 */
00267 
00268 /*
00269   Return the printer name, eventually followed by `-P$PRINTER',
00270   since the `-o' option of dvips doesn't evaluate the environment
00271   variable.
00272 */
00273 static char *
00274 get_printer_name(void)
00275 {
00276     char *printcmd, *printer;
00277 
00278     if (resource.dvips_printer_str != NULL && strlen(resource.dvips_printer_str) > 0) {
00279        return xstrdup(resource.dvips_printer_str);
00280     }
00281     printcmd = xstrdup("lpr");
00282     printer = getenv("PRINTER");
00283     if (printer != NULL) {
00284        printcmd = xstrcat(printcmd, " -P");
00285        printcmd = xstrcat(printcmd, printer);
00286     }
00287     return printcmd;
00288 }
00289 
00290 /* return basename of `old_name' with `old_ext' replaced by `new_ext', in fresh memory */
00291 static char *
00292 get_new_file_name(const char *old_name, const char *old_ext, const char *new_ext)
00293 {
00294     /* old_name contains the normalized DVI file name, with path and extension */
00295     char *basename, *new_name;
00296     size_t len;
00297     
00298     basename = strrchr(old_name, DIR_SEPARATOR);
00299                      
00300     if (basename != NULL) {
00301        basename++;
00302        new_name = xmalloc(strlen(basename) + strlen(new_ext) + 1);
00303        new_name = strcpy(new_name, basename);
00304     }
00305     else {
00306        new_name = xmalloc(strlen(old_name) + strlen(new_ext) + 1);
00307        new_name = strcpy(new_name, old_name);
00308     }
00309 
00310     len = strlen(new_name);
00311     strcpy(new_name + len - strlen(old_ext), new_ext);
00312     return new_name;
00313 }
00314 
00315 /*
00316  * Translate `non-standard' paper sizes for xdvi into options suitable
00317  * for dvips. We don't do this always, since it would override the papersize
00318  * specials inserted by e.g.
00319  * \usepackage[dvips]{geometry}
00320  * which is the preferred way to specify the papersize. If the papersize
00321  * has been explicitly set by such a special, this function returns NULL.
00322  * Else it returns the value of the `paper' resource, without the trailing
00323  * `r', and sets the `landscape' argument to True if a trailing `r' was
00324  * present.
00325  *
00326  * Note that we don't check/warn about whether the current paper
00327  * resource is valid for dvips; dvips will ignore invalid paper sizes.
00328  */
00329 static char *
00330 get_dvips_papersize(Boolean *landscape)
00331 {
00332     char *papersize;
00333     if (have_papersize_special())
00334        return NULL;
00335     
00336     papersize = xstrdup(resource.paper);
00337     *landscape = False;
00338     if (papersize[strlen(papersize) - 1] == 'r') { /* landscape size */
00339        papersize[strlen(papersize) - 1] = '\0';
00340        *landscape = True;
00341     }
00342     TRACE_GUI((stderr, "Using dvips arguments: `%s', %s", papersize, *landscape ? "landscape" : "portrait"));
00343     return papersize;
00344 }
00345 
00346 static void
00347 set_outfile_name(struct dialog_info *info, struct dialog_info *save_info, printOrSaveActionT act)
00348 {
00349     free(info->file_name);
00350     if (act == FILE_PRINT) {
00351        info->file_name = get_new_file_name(globals.dvi_name, ".dvi", ".ps");
00352     }
00353     else { /* saving to file */
00354        if (save_info->range_radio == SAVE_ALL) {
00355            info->file_name = get_new_file_name(globals.dvi_name, ".dvi",
00356                                           output_format_mapping[resource.default_saving_format].extension);
00357        }
00358        else {
00359            char *tmp = xstrdup("_pp");
00360            tmp = xstrcat(tmp, output_format_mapping[resource.default_saving_format].extension);
00361            
00362            info->file_name = get_new_file_name(globals.dvi_name, ".dvi", tmp);
00363            free(tmp);
00364        }
00365     }
00366 }
00367 
00368 /* get initial values for dialog texts */
00369 static void
00370 get_initial_dialog_values(struct dialog_info *info, printOrSaveActionT act)
00371 {
00372     if (act == FILE_PRINT && info->printer_name == NULL)
00373            info->printer_name = get_printer_name();
00374 
00375     if (info->dvips_options == NULL) {
00376        info->dvips_options = xstrdup("");
00377        
00378        /* add -t option if not already present */
00379        if (resource.dvips_options_str != NULL
00380            && strstr(resource.dvips_options_str, "-t ") == NULL) {
00381            Boolean dvips_landscape = False;
00382            char *dvips_paper_size = get_dvips_papersize(&dvips_landscape);
00383            if (dvips_paper_size != NULL) {
00384               info->dvips_options = xstrdup("-t ");
00385               info->dvips_options = xstrcat(info->dvips_options, dvips_paper_size);
00386               free(dvips_paper_size);
00387               if (dvips_landscape) {
00388                   info->dvips_options = xstrcat(info->dvips_options, " -t landscape");
00389               }
00390            }
00391        }
00392        
00393        if (resource.dvips_options_str != NULL) {
00394            if (strlen(info->dvips_options) > 0)
00395               info->dvips_options = xstrcat(info->dvips_options, " ");
00396            info->dvips_options = xstrcat(info->dvips_options, resource.dvips_options_str);
00397        }
00398     }
00399     
00400     if (info->from_page == NULL) {
00401        info->from_page = xmalloc(LENGTH_OF_INT + 1);
00402        sprintf(info->from_page, "%d", current_page + globals.pageno_correct);
00403     }
00404 
00405     if (info->to_page == NULL) {
00406        info->to_page = xmalloc(LENGTH_OF_INT + 1);
00407        sprintf(info->to_page, "%d", current_page + globals.pageno_correct);
00408     }
00409 }
00410 
00411 
00412 #if MOTIF
00413 static void
00414 set_sensitivity(int i)
00415 {
00416     Boolean sensitivity;
00417     
00418 /*     if (i == curr_pr_info.print_radio) /\* if no change *\/ */
00419 /*     return; */
00420 
00421     curr_pr_info.print_radio = i;
00422 
00423     sensitivity = (i == PRINT_TO_PRINTER);
00424     XtSetSensitive(print_to_printer_text, sensitivity);
00425 
00426 /*     sensitivity ^= (True ^ False); */
00427     XtSetSensitive(print_to_file_text[FILE_PRINT], !sensitivity);
00428     XtSetSensitive(print_to_file_button[FILE_PRINT], !sensitivity);
00429 }
00430 #endif /* MOTIF */
00431 
00432 static void
00433 update_dvips_options_sensitivity(int idx, Widget top)
00434 {
00435     Widget dvips_label;
00436 
00437 #if MOTIF    
00438     Widget dvips_options;
00439 
00440     if (get_widget_by_name(&dvips_label, top, "dvips_options_name", True) &&
00441        get_widget_by_name(&dvips_options, top, "dvips_options_text", True)) {
00442        if (output_format_mapping[idx].fmt == FMT_PS ||
00443            output_format_mapping[idx].fmt == FMT_PS2PDF) {
00444            XtSetSensitive(dvips_label, True);
00445            XtSetSensitive(dvips_options, True);
00446        }
00447        else {
00448            XtSetSensitive(dvips_label, False);
00449            XtSetSensitive(dvips_options, False);
00450        }
00451     }
00452 #else
00453     if (get_widget_by_name(&dvips_label, top, "dvips_options_name", True)) {
00454        XtSetSensitive(XtParent(dvips_label),
00455                      output_format_mapping[idx].fmt == FMT_PS ||
00456                      output_format_mapping[idx].fmt == FMT_PS2PDF);
00457     }
00458 #endif
00459 }
00460 
00461 /* callbacks */
00462 
00463 static void
00464 select_format_cb(Widget w, XtPointer client_data, XtPointer call_data)
00465 {
00466     Widget file_text, top;
00467     
00468     char *filename;
00469     int i;
00470 #ifdef MOTIF
00471     Widget f1, f2;
00472     char *ptr;
00473     
00474     i = (int)client_data;
00475     UNUSED(call_data);
00476     f1 = XtParent(w);
00477     ASSERT(f1 != 0, "Parent of widget musn't be NULL!\n");
00478     f2 = XtParent(f1);
00479     ASSERT(f2 != 0, "Parent of f1 musn't be NULL!\n");
00480     top = XtParent(f2);
00481     ASSERT(top != 0, "Parent of f2 musn't be NULL!\n");
00482 
00483     if ((file_text = XtNameToWidget(top, "*file_text")) == 0) {
00484        XDVI_WARNING((stderr, "Couldn't find \"file_text\" widget!"));
00485        return;
00486     }
00487     XtVaGetValues(file_text, XmNvalue, &filename, NULL);
00488     if ((ptr = strrchr(filename, '.')) != NULL) {
00489        char buf[1024];
00490        replace_extension(filename, output_format_mapping[i].extension, buf, sizeof buf);
00491        XtVaSetValues(file_text, XmNvalue, buf, NULL);
00492     }
00493 #else /* MOTIF */
00494     
00495     Widget popup, button;
00496     char *ptr1, *ptr2;
00497     char buf[1024];
00498     
00499     UNUSED(call_data);
00500     popup = XtParent(w);
00501     ASSERT(popup != 0, "Parent of menu musn't be NULL!\n");
00502     button = XtParent(popup);
00503     ASSERT(button != 0, "Parent of popup musn't be NULL!\n");
00504 
00505     top = (Widget)client_data;
00506 
00507     if ((file_text = XtNameToWidget(top, "*file_text")) == 0) {
00508        XDVI_WARNING((stderr, "Couldn't find \"file_text\" widget!"));
00509        return;
00510     }
00511 
00512     XtVaGetValues(file_text, XtNstring, &filename, NULL);
00513 /*     fprintf(stderr, "file text: |%s|\n", filename); */
00514 
00515     /* swap title strings */
00516     XtVaGetValues(button, XtNlabel, &ptr1, NULL);
00517     XtVaGetValues(w, XtNlabel, &ptr2, NULL);
00518     strncpy(buf, ptr1, sizeof buf);
00519 
00520     for (i = 0; output_format_mapping[i].fmt_string != NULL; i++) {
00521        if (strcmp(ptr2, output_format_mapping[i].fmt_string) == 0) {
00522            char buf2[1024];
00523            replace_extension(filename, output_format_mapping[i].extension, buf2, sizeof buf2);
00524            XtVaSetValues(file_text, XtNstring, buf2, NULL);
00525            
00526            break;
00527        }
00528     }
00529     if (output_format_mapping[i].fmt_string == NULL) {
00530        popup_message(get_matching_parent(w, globals.widgets.top_level, "print_popup", "save_popup", NULL),
00531                     MSG_WARN,
00532                     REPORT_XDVI_BUG_TEMPLATE,
00533                     "Unrecognized string in format selector: |%s|", ptr2);
00534     }
00535     XtVaSetValues(button, XtNlabel, ptr2, NULL);
00536     XtVaSetValues(w, XtNlabel, buf, NULL);
00537 
00538 #endif /* MOTIF */
00539 
00540     save_save_info.output_format = curr_save_info.output_format = output_format_mapping[i].fmt;
00541 
00542     update_dvips_options_sensitivity(i, save_shell);
00543     
00544     resource.default_saving_format = save_save_info.output_format;
00545     set_outfile_name(&save_save_info, &curr_save_info, FILE_SAVE);
00546 }
00547 
00548 static void
00549 cb_print_cancel(Widget w, XtPointer client_data, XtPointer call_data)
00550 {
00551     struct save_or_print_info *info = (struct save_or_print_info *)client_data;
00552     UNUSED(w);
00553     UNUSED(call_data);
00554 
00555     ASSERT(info != NULL, "client_data in cb_print_cancel musn't be NULL!");
00556     if (info->message_popup != 0) {
00557        kill_message_window(info->message_popup);
00558     }
00559     XtPopdown(print_shell);
00560     print_is_active = False;
00561 }
00562 
00563 static void
00564 cb_save_cancel(Widget w, XtPointer client_data, XtPointer call_data)
00565 {
00566     struct save_or_print_info *info = (struct save_or_print_info *)client_data;
00567     UNUSED(w);
00568     UNUSED(call_data);
00569     
00570     ASSERT(info != NULL, "client_data in cb_save_cancel musn't be NULL!");
00571     if (info->message_popup != 0) {
00572        kill_message_window(info->message_popup);
00573     }
00574     XtPopdown(save_shell);
00575     save_is_active = False;
00576 }
00577 
00578 static void
00579 cb_print_or_save(Widget w, XtPointer client_data, XtPointer call_data)
00580 {
00581     struct save_or_print_info *info = (struct save_or_print_info *)client_data;
00582     UNUSED(w);
00583     UNUSED(call_data);
00584 
00585     print_precheck1((XtPointer)info);
00586 }
00587 
00588 /* access from outside the module */
00589 void
00590 cancel_saving(struct save_or_print_info *info)
00591 {
00592     cb_save_cancel(NULL, info, NULL);
00593 }
00594 
00595 
00596 static void
00597 print_cancel(Widget w, XEvent *event, String *params, Cardinal *num_params)
00598 {
00599     struct save_or_print_info *info = NULL;
00600     void *ptr;
00601     
00602     UNUSED(w);
00603     UNUSED(event);
00604 
00605     ASSERT(*num_params > 0, "params in print_cancel must be > 0!");
00606     ASSERT(*params != NULL, "params in print_cancel mustn't be NULL!");
00607 
00608     TRACE_GUI((stderr, "Pointer string value: |%s|", *params));
00609     sscanf(*params, "%p", &ptr);
00610     info = (struct save_or_print_info *)ptr;
00611 
00612     cb_print_cancel(NULL, info, NULL);
00613 }
00614     
00615 static void
00616 save_cancel(Widget w, XEvent *event, String *params, Cardinal *num_params)
00617 {
00618     struct save_or_print_info *info = NULL;
00619     void *ptr;
00620     
00621     UNUSED(w);
00622     UNUSED(event);
00623 
00624     ASSERT(*num_params > 0, "params in save_cancel must be > 0!");
00625     ASSERT(*params != NULL, "params in save_cancel mustn't be NULL!");
00626 
00627     TRACE_GUI((stderr, "Pointer string value: |%s|", *params));
00628     sscanf(*params, "%p", &ptr);
00629     info = (struct save_or_print_info *)ptr;
00630 
00631     cb_save_cancel(NULL, info, NULL);
00632 }
00633 
00634 #ifndef MOTIF
00635 
00636 /*
00637   enable the `print to' button if user presses key or mouse button
00638   inside that input field
00639 */
00640 static void
00641 xaw_print_handle_key(Widget widget, XtPointer closure, XEvent *ev, Boolean *cont)
00642 {
00643     char *number;
00644     int i;
00645 
00646     number = (char *)closure;
00647     i = atoi(number);
00648     ASSERT(i == 2 || i == 3, "Button index should be 2 or 3");
00649     UNUSED(widget);
00650     UNUSED(ev);
00651     UNUSED(cont);
00652 
00653     if (i == 2) {
00654        XawToggleSetCurrent(to_printer_radio, (XtPointer)PRINT_TO_PRINTER);
00655     }
00656     else {
00657        ASSERT(to_file_radio_or_label[FILE_PRINT] != NULL, "");
00658        XawToggleSetCurrent(to_file_radio_or_label[FILE_PRINT], (XtPointer)PRINT_TO_FILE);
00659     }
00660 }
00661 
00662 /*
00663   enable the `print range' button if user presses key or mouse button
00664   inside that input field
00665 */
00666 static void
00667 xaw_range_handle_key(Widget widget, XtPointer closure, XEvent *ev, Boolean *cont)
00668 {
00669     printOrSaveActionT act = (printOrSaveActionT)closure;
00670     UNUSED(widget);
00671     UNUSED(ev);
00672     UNUSED(cont);
00673     
00674     if (act == FILE_PRINT && curr_pr_info.range_radio != PRINT_RANGE) {
00675        ASSERT(range_all_radio[act] != NULL, "button should have been initialized");
00676        XawToggleSetCurrent(range_all_radio[act], (XtPointer)PRINT_RANGE);
00677     }
00678     else if (act == FILE_SAVE && curr_save_info.range_radio != SAVE_RANGE) {
00679        ASSERT(range_all_radio[act] != NULL, "button should have been initialized");
00680        XawToggleSetCurrent(range_all_radio[act], (XtPointer)SAVE_RANGE);
00681     }
00682 }
00683 
00684 
00685 static void
00686 xaw_print_save_act_go(Widget w, XEvent *event, String *params, Cardinal *num_params)
00687 {
00688     struct save_or_print_info *info = NULL;
00689     void *ptr;
00690     
00691     UNUSED(w);
00692     UNUSED(event);
00693 
00694     ASSERT(*num_params > 0, "params in search_cancel must be > 0!");
00695     ASSERT(*params != NULL, "params in search_cancel mustn't be NULL!");
00696 
00697     TRACE_GUI((stderr, "Pointer string value: |%s|", *params));
00698     sscanf(*params, "%p", &ptr);
00699     info = (struct save_or_print_info *)ptr;
00700 
00701     print_precheck1((XtPointer)info);
00702 }
00703 
00704 #if 0
00705 static void
00706 xaw_popup_menu_cb(Widget w, XtPointer client_data, XtPointer call_data)
00707 {
00708     Position x, y;
00709     Dimension h;
00710     int pos_x, pos_y;
00711     Window dummy;
00712     
00713     Widget popup = (Widget)client_data;
00714     fprintf(stderr, "popup: %p\n", popup);
00715     XtVaGetValues(w, XtNx, &x, XtNy, &y, XtNheight, &h, NULL);
00716     fprintf(stderr, "x: %d, y: %d, h: %d\n", x, y, h);
00717     XTranslateCoordinates(DISP, XtWindow(w), RootWindowOfScreen(SCRN),
00718                        x, y, &pos_x, &pos_y, &dummy);
00719     XtRealizeWidget(popup);
00720     /* WRONG - would need to use x position of its left widget ... */
00721     XtVaSetValues(popup, XtNx, pos_x, XtNy, pos_y + h + 1, NULL);
00722     XtPopup(popup, XtGrabNone);
00723 }
00724 #endif /* 0 */
00725 
00726 #endif /* not MOTIF */
00727 
00728 static void
00729 cb_print_vs_file(Widget w, XtPointer client_data, XtPointer call_data)
00730 {
00731 #ifdef MOTIF
00732     Boolean to_printer = False, to_file = False;
00733     if (((XmToggleButtonCallbackStruct *)call_data)->set) {
00734        if (w == to_printer_radio)
00735            to_printer = True;
00736        else
00737            to_file = True;
00738        
00739     }
00740     else {
00741        if (w == to_printer_radio)
00742            to_file = True;
00743        else
00744            to_printer = True;
00745     }
00746 
00747     XmToggleButtonGadgetSetState(to_file_radio_or_label[FILE_PRINT], to_file, False);
00748     XmToggleButtonGadgetSetState(to_printer_radio, to_printer, False);
00749     
00750     set_sensitivity((int)client_data);
00751     XmProcessTraversal(curr_pr_info.print_radio == PRINT_TO_PRINTER
00752                      ? print_to_printer_text
00753                      : print_to_file_text[FILE_PRINT],
00754                      XmTRAVERSE_CURRENT);
00755 #else /* MOTIF */
00756     int i = (int) XawToggleGetCurrent(to_printer_radio);
00757 
00758     UNUSED(w);
00759     UNUSED(client_data);
00760     UNUSED(call_data);
00761 
00762     /*
00763       NOTE: Unlike non-k xdvi, we don't use set_sensitivity for the
00764       Xaw version, since the text inside the textfield cannot be made
00765       insensitive, so it won't be obvious to users why they cannot
00766       change the text.  Also, the page range isn't set insensitive
00767       either.
00768     */
00769     if (i != 0)
00770        curr_pr_info.print_radio = i;
00771 #endif /* MOTIF */
00772     
00773 }
00774 
00775 
00776 
00777 static void
00778 cb_range(Widget w, XtPointer client_data, XtPointer call_data)
00779 {
00780     pageRadioT flag = (pageRadioT)client_data;
00781     printOrSaveActionT act;
00782     
00783 #ifdef MOTIF
00784     
00785     Boolean sensitivity;
00786     UNUSED(call_data);
00787     ASSERT(flag != PRINT_MARKED || flag != SAVE_MARKED || pageinfo_have_marked_pages(),
00788           "PRINT_MARKED or SAVE_MARKED shouldn't be togglable if there are no marked pages!");
00789 
00790     if (is_print_button(flag)) {
00791        curr_pr_info.range_radio = (int)client_data;
00792        sensitivity = (curr_pr_info.range_radio == PRINT_RANGE);
00793        act = FILE_PRINT;
00794     }
00795     else {
00796        curr_save_info.range_radio = (int)client_data;
00797        sensitivity = (curr_save_info.range_radio == SAVE_RANGE);
00798        act = FILE_SAVE;
00799     }
00800 
00801     /* switch off other radio buttons, switch on current one */
00802     XmToggleButtonGadgetSetState(range_all_radio[act], False, False);
00803     XmToggleButtonGadgetSetState(range_marked_radio[act], False, False);
00804     XmToggleButtonGadgetSetState(range_from_to_radio[act], False, False);
00805     XmToggleButtonGadgetSetState(w, True, False);
00806 
00807     /* set from-to range to sensitive if appropriate */
00808     XtSetSensitive(from_label[act], sensitivity);
00809     XtSetSensitive(page_from_text[act], sensitivity);
00810     XtSetSensitive(to_label[act], sensitivity);
00811     XtSetSensitive(page_to_text[act], sensitivity);
00812     XtSetSensitive(of_label[act], sensitivity);
00813     
00814 #else /* MOTIF */
00815     
00816     int i;
00817     UNUSED(call_data);
00818     if (is_print_button(flag)) {
00819        act = FILE_PRINT;
00820     }
00821     else {
00822        act = FILE_SAVE;
00823     }
00824 
00825     UNUSED(w);
00826 
00827     i = (int) XawToggleGetCurrent(range_all_radio[act]);
00828 
00829     if (i != 0) {
00830        ASSERT(i != PRINT_MARKED || i != SAVE_MARKED || pageinfo_have_marked_pages(),
00831               "PRINT_MARKED or SAVE_MARKED shouldn't be togglable if there are no marked pages!");
00832 
00833        if (act == FILE_PRINT)
00834            curr_pr_info.range_radio = i;
00835        else
00836            curr_save_info.range_radio = i;
00837     }
00838     
00839 #endif /* MOTIF */
00840 }
00841 
00842 static void
00843 set_filename_callback(const char *fname, void *data)
00844 {
00845     if (fname != NULL) {
00846        Widget w = (Widget)data;
00847        XtVaSetValues(w,
00848 #ifdef MOTIF
00849                     XmNvalue, fname,
00850                     XmNcursorPosition, strlen(fname),
00851 #else
00852                     XtNstring, fname,
00853 #endif
00854                     NULL);
00855     }
00856 }
00857 
00858 
00859 static void
00860 cb_browse(Widget w, XtPointer client_data, XtPointer call_data)
00861 {
00862 /*      char *fname; */
00863     struct save_or_print_info *info = (struct save_or_print_info *)client_data;
00864     printOrSaveActionT act = info->act;
00865 /*      Widget ret_widget; */
00866     Widget parent;
00867     
00868     UNUSED(call_data);
00869 #ifdef MOTIF
00870     UNUSED(w);
00871 #else
00872     if (act == FILE_PRINT)
00873        xaw_print_handle_key(w, (XtPointer)"3", NULL, NULL);
00874 #endif
00875     
00876     if (act == FILE_SAVE) {
00877        static struct filesel_callback cb; /* static so that we can pass its address */
00878        cb.title = "Xdvi: Save to file";
00879        cb.prompt = "Save to file:";
00880        cb.ok = "OK";
00881        cb.cancel = "Cancel";
00882        cb.init_path = NULL;
00883        cb.filemask = "*.dvi";
00884        cb.must_exist = False;
00885        cb.exit_on_cancel = False;
00886        cb.func_ptr = set_filename_callback;
00887        cb.data = print_to_file_text[act];
00888        
00889        if (!get_widget_by_name(&parent, globals.widgets.top_level, Xdvi_SAVE_SHELL_NAME, True))
00890            parent = globals.widgets.top_level;
00891        XsraSelFile(parent, &cb);
00892 /*     fprintf(stderr, "done saving: return widget = %p\n", ret_widget); */
00893     }
00894     else {
00895        static struct filesel_callback cb; /* static so that we can pass its address */
00896        cb.title = "Xdvi: Print to file";
00897        cb.prompt = "Print to file:";
00898        cb.ok = "OK";
00899        cb.cancel = "Cancel";
00900        cb.init_path = NULL;
00901        cb.filemask = "*.ps";
00902        cb.must_exist = False;
00903        cb.exit_on_cancel = False;
00904        cb.func_ptr = set_filename_callback;
00905        cb.data = print_to_file_text[act];
00906        
00907        if (!get_widget_by_name(&parent, globals.widgets.top_level, Xdvi_PRINT_SHELL_NAME, True))
00908            parent = globals.widgets.top_level;
00909        XsraSelFile(parent, &cb);
00910 /*     fname = XsraSelFile(parent, "Xdvi: Print to file", "Print to file:", */
00911 /*                       "OK", "Cancel", */
00912 /*                       NULL, */
00913 /*                       "*.ps", False, &ret_widget); */
00914 /*     fprintf(stderr, "done printing: return widget = %p\n", ret_widget); */
00915     }
00916     
00917 /*      if (fname != NULL) { */
00918 /*     XtVaSetValues(print_to_file_text[act], */
00919 /*  #ifdef MOTIF */
00920 /*                  XmNvalue, fname, XmNcursorPosition, strlen(fname), */
00921 /*  #else */
00922 /*                  XtNstring, fname, */
00923 /*  #endif */
00924 /*                  NULL); */
00925 /*      } */
00926 /*      free(fname); */
00927 }
00928 
00929 /* create a popup dialog for printing a DVI file OR saving pages from a DVI file */
00930 static Widget
00931 create_print_or_save_window(struct save_or_print_info *info, char *ofstring)
00932 {
00933     printOrSaveActionT act = info->act;
00934     Widget top_level_shell;
00935     Atom WM_DELETE_WINDOW;
00936 #ifndef MOTIF
00937     Widget form, paned, box;
00938     Widget f01form, f02form; /* dummy forms to get indentation consistent */
00939     Widget r1form;
00940     Widget r1label;
00941     Widget r2form, r3form, r4form = 0;
00942     Widget r4label;
00943     Widget r5label;
00944     Widget r6form;
00945     Widget r61form;
00946     Widget r7form;
00947     char *str;
00948 
00949     XtTranslations xlats, xlats2, wm_translations;
00950     XtAccelerators accels2;
00951     int ddist;
00952 
00953     static Dimension w_avg = 220;
00954     Dimension w_curr;
00955     
00956     /* handy abbrevs */
00957 #define HORIZONTAL_RESIZING_NO     XtNleft, XtChainLeft, XtNright, XtChainLeft
00958 #define HORIZONTAL_RESIZING_YES XtNleft, XtChainLeft, XtNright, XtChainRight
00959 #define VERTICAL_RESIZING_NO       XtNtop, XtChainTop, XtNbottom, XtChainTop
00960 
00961     XtAddActions(print_actions, XtNumber(print_actions));
00962 
00963     if (act == FILE_SAVE) {
00964        str = get_string_va("<Message>WM_PROTOCOLS: WM_save_cancel(%p)\n"
00965                          "<Key>Escape:WM_save_cancel(%p)\n"
00966                          "<Key>q:WM_save_cancel(%p)",
00967                          info, info, info);
00968        wm_translations = XtParseTranslationTable(str);
00969        free(str);
00970     }
00971     else {
00972        str = get_string_va("<Message>WM_PROTOCOLS: WM_print_cancel(%p)\n"
00973                          "<Key>Escape:WM_print_cancel(%p)\n"
00974                          "<Key>q:WM_print_cancel(%p)",
00975                          info, info, info);
00976        wm_translations = XtParseTranslationTable(str);
00977        free(str);
00978     }
00979 
00980     top_level_shell = XtVaCreatePopupShell(act == FILE_SAVE ? Xdvi_SAVE_SHELL_NAME : Xdvi_PRINT_SHELL_NAME,
00981                                       transientShellWidgetClass,
00982                                       globals.widgets.top_level,
00983                                       XtNtitle, act == FILE_SAVE ? "xdvik: Save file" : "xdvik: Print DVI file",
00984                                       XtNmappedWhenManaged, False,
00985                                       XtNtransientFor, globals.widgets.top_level,
00986                                       XtNallowShellResize, True,
00987                                       XtNtranslations, wm_translations,
00988                                       NULL);
00989 
00990     WM_DELETE_WINDOW = XInternAtom(XtDisplay(top_level_shell), "WM_DELETE_WINDOW", False);
00991 
00992     paned = XtVaCreateManagedWidget(act == FILE_SAVE ? "save_paned" : "print_paned",
00993                                 panedWidgetClass, top_level_shell, NULL);
00994        
00995     form = XtVaCreateManagedWidget("form", formWidgetClass,
00996                                paned,
00997                                XtNallowResize, True,
00998                                NULL);
00999     XtVaGetValues(form, XtNdefaultDistance, &ddist, NULL);
01000 /*     fprintf(stderr, "form1: %ld\n", (long)form); */
01001     
01002     xlats = XtParseTranslationTable("<EnterWindow>:highlight(Always)\n"
01003                                 "<LeaveWindow>:unhighlight()\n"
01004                                 "<Btn1Down>,<Btn1Up>:set()notify()");
01005 
01006     if (act == FILE_PRINT) {
01007        str = get_string_va("<Key>Return:printInternal(%p)", info);
01008        xlats2 = XtParseTranslationTable(str);
01009     }
01010     else {
01011        str = get_string_va("<Key>Return:saveInternal(%p)", info);
01012        xlats2 = XtParseTranslationTable(str);
01013     }
01014     free(str);
01015 
01016     if (act == FILE_PRINT) { /* selection `to printer/to file' */
01017        /* FIXME: set real sizes here */
01018 /*     Dimension w_curr; */
01019        f01form = XtVaCreateManagedWidget("dummy_print_to_label_form", formWidgetClass,
01020                                      form,
01021                                      XtNresizable, True,
01022                                      XtNborderWidth, 0,
01023                                      /*                                 XtNvertDistance, 10, */
01024                                      HORIZONTAL_RESIZING_YES,
01025                                      NULL);
01026        r1label = XtVaCreateManagedWidget("print_to", labelWidgetClass,
01027                                      f01form,
01028                                      XtNlabel, "Print to: ",
01029                                      XtNborderWidth, 0,
01030                                      HORIZONTAL_RESIZING_NO,
01031                                      NULL);
01032        
01033        r2form = XtVaCreateManagedWidget("print_to_printer_form", formWidgetClass,
01034                                     form,
01035                                     XtNresizable, True,
01036                                     XtNborderWidth, 0,
01037                                     XtNvertDistance, 0,
01038                                     XtNfromVert, f01form,
01039                                     HORIZONTAL_RESIZING_YES,
01040                                     XtNallowResize, True,
01041                                     NULL);
01042        
01043        accels2 = XtParseAcceleratorTable("<Btn1Down>,<Btn1Up>:set()notify()");
01044 
01045        to_printer_radio = XtVaCreateManagedWidget("to_printer",
01046 #ifdef XAW
01047                                              radioWidgetClass,
01048 #else
01049                                              toggleWidgetClass,
01050 #endif
01051                                              r2form,
01052                                              XtNlabel, "Printer: ",
01053                                              XtNborderWidth, 0,
01054                                              XtNhighlightThickness, 1,
01055                                              XtNradioData, PRINT_TO_PRINTER,
01056                                              XtNstate, resource.default_printing_target == PRINT_TO_PRINTER,
01057                                              XtNtranslations, xlats,
01058                                              XtNaccelerators, accels2,
01059                                              HORIZONTAL_RESIZING_NO,
01060                                              VERTICAL_RESIZING_NO,
01061                                              NULL);
01062        
01063        XtAddCallback(to_printer_radio, XtNcallback, cb_print_vs_file, NULL);
01064        XtInstallAccelerators(r2form, to_printer_radio);
01065        
01066        print_to_printer_text = XtVaCreateManagedWidget("printer_text", asciiTextWidgetClass,
01067                                                  r2form,
01068                                                  XtNwidth, w_avg,
01069                                                  XtNdataCompression, False,
01070                                                  XtNeditType, XawtextEdit,
01071                                                  /*  XtNresize, XawtextResizeWidth, */
01072                                                  XtNfromHoriz, to_printer_radio,
01073                                                  HORIZONTAL_RESIZING_YES,
01074                                                  VERTICAL_RESIZING_NO,
01075                                                  /*  XtNscrollHorizontal, XawtextScrollAlways, */
01076                                                  NULL);
01077        XtOverrideTranslations(print_to_printer_text, xlats2);
01078        XtAddEventHandler(print_to_printer_text, KeyPressMask | ButtonPressMask, False,
01079                        xaw_print_handle_key, (XtPointer)"2");
01080        
01081        adjust_vertically(to_printer_radio, print_to_printer_text, ddist);
01082        
01083        r3form = XtVaCreateManagedWidget("print_to_file_form", formWidgetClass,
01084                                     form,
01085                                     XtNborderWidth, 0,
01086                                     XtNvertDistance, 0,
01087                                     XtNfromVert, r2form,
01088                                     HORIZONTAL_RESIZING_YES,
01089                                     NULL);
01090 
01091        to_file_radio_or_label[act] = XtVaCreateManagedWidget("to_file",
01092 #ifdef XAW
01093                                                        radioWidgetClass,
01094 #else
01095                                                        toggleWidgetClass,
01096 #endif
01097                                                        r3form,
01098                                                        XtNhighlightThickness, 1,
01099                                                        XtNborderWidth, 0,
01100                                                        XtNlabel, "File: ",
01101                                                        XtNstate, resource.default_printing_target == PRINT_TO_FILE,
01102                                                        XtNradioGroup, to_printer_radio,
01103                                                        XtNradioData, PRINT_TO_FILE,
01104                                                        XtNtranslations, xlats,
01105                                                        XtNaccelerators, accels2,
01106                                                        HORIZONTAL_RESIZING_NO,
01107                                                        VERTICAL_RESIZING_NO,
01108                                                        NULL);
01109        XtAddCallback(to_file_radio_or_label[act], XtNcallback, cb_print_vs_file, NULL);
01110        XtInstallAccelerators(r3form, to_file_radio_or_label[act]);
01111 
01112        print_to_file_text[act] = XtVaCreateManagedWidget("file_text", asciiTextWidgetClass,
01113                                                    r3form,
01114                                                    XtNwidth, w_avg,
01115                                                    XtNdataCompression, False,
01116                                                    XtNeditType, XawtextEdit,
01117                                                    XtNfromHoriz, to_file_radio_or_label[act],
01118                                                    HORIZONTAL_RESIZING_YES,
01119                                                    VERTICAL_RESIZING_NO,
01120                                                    NULL);
01121        XtOverrideTranslations(print_to_file_text[act], xlats2);
01122        XtAddEventHandler(print_to_file_text[act], KeyPressMask | ButtonPressMask, False,
01123                        xaw_print_handle_key, (XtPointer)"3");
01124     }
01125     else { /* not printing, but saving */
01126        int i;
01127        Dimension max_entry_width = 0;
01128        f01form = XtVaCreateManagedWidget("dummy_save_as_form", formWidgetClass,
01129                                      form,
01130                                      XtNresizable, True,
01131                                      XtNborderWidth, 0,
01132                                      /* XtNvertDistance, 10, */
01133                                      HORIZONTAL_RESIZING_YES,
01134                                      NULL);
01135        r1label = XtVaCreateManagedWidget("save_as", labelWidgetClass,
01136                                      f01form,
01137                                      XtNlabel, "Save as: ",
01138                                      XtNborderWidth, 0,
01139                                      HORIZONTAL_RESIZING_NO,
01140                                      NULL);
01141        r1form = XtVaCreateManagedWidget("save_to_file_form", formWidgetClass,
01142                                     form,
01143                                     XtNborderWidth, 0,
01144                                     XtNfromVert, f01form,
01145                                     HORIZONTAL_RESIZING_YES,
01146                                     VERTICAL_RESIZING_NO,
01147                                     NULL);
01148 /*     fprintf(stderr, "formr1: %ld\n", (long)r1form); */
01149 #if 0
01150        menu_double_arrow_bitmap
01151            = XCreateBitmapFromData(XtDisplay(globals.widgets.top_level),
01152                                 RootWindowOfScreen(XtScreen(globals.widgets.top_level)),
01153                                 (char *)menu_double_arrow_bits, MENU_DOUBLE_ARROW_W, MENU_DOUBLE_ARROW_H);
01154 #endif
01155        format_selection_label = XtVaCreateManagedWidget("format_selection_label", labelWidgetClass,
01156                                                   r1form,
01157                                                   XtNlabel, "Format: ",
01158                                                   XtNborderWidth, 0,
01159                                                   HORIZONTAL_RESIZING_NO,
01160                                                   VERTICAL_RESIZING_NO,
01161                                                   NULL);
01162        format_selection_button = XtVaCreateManagedWidget("format_selection_button", menuButtonWidgetClass,
01163                                                    r1form,
01164                                                    XtNmenuName, "format_selection_popup",
01165                                                    XtNlabel, output_format_mapping[resource.default_saving_format].fmt_string,
01166                                                    XtNjustify, XtJustifyLeft,
01167                                                    XtNborderWidth, resource.btn_border_width,
01168                                                    XtNfromHoriz, format_selection_label,
01169 #if 0
01170                                                    XtNhighlightThickness, 0,
01171 #endif
01172                                                    NULL);
01173 #if 0 /* Hack for arrow - menuButtonWidget cannot have a XtNrightBitmap!!! */
01174        format_selection_b1 = XtVaCreateManagedWidget("format_selection_b1", commandWidgetClass,
01175                                                 r1form,
01176                                                 XtNborderWidth, resource.btn_border_width,
01177                                                 XtNfromHoriz, format_selection_button,
01178                                                 XtNhorizDistance, -1,
01179                                                 XtNhighlightThickness, 0,
01180                                                 XtNbitmap, menu_double_arrow_bitmap,
01181                                                 NULL);
01182        adjust_heights(format_selection_button, format_selection_b1, NULL);
01183 #endif
01184        format_selection_popup = XtCreatePopupShell("format_selection_popup", simpleMenuWidgetClass,
01185                                               format_selection_button,
01186 /*                                            globals.widgets.top_level, */
01187                                               NULL, 0);
01188 #if 0
01189        XtAddCallback(format_selection_b1, XtNcallback, xaw_popup_menu_cb, format_selection_popup);
01190 #endif
01191        for (i = 1; i < FORMAT_SEL_CNT; i++) {
01192            char name[1024];
01193            Dimension curr_entry_width;
01194            SNPRINTF(name, sizeof name, "format_selection_pulldown_%d", i);
01195            format_selection_menu[i] = XtVaCreateManagedWidget(name, smeBSBObjectClass,
01196                                                         format_selection_popup,
01197                                                         XtNjustify, XtJustifyLeft,
01198                                                         XtNlabel,
01199                                                         i == resource.default_saving_format
01200                                                         ? output_format_mapping[0].fmt_string
01201                                                         : output_format_mapping[i].fmt_string,
01202                                                         NULL);
01203            XtVaGetValues(format_selection_menu[i], XtNwidth, &curr_entry_width, NULL);
01204            if (curr_entry_width > max_entry_width)
01205               max_entry_width = curr_entry_width;
01206            XtAddCallback(format_selection_menu[i], XtNcallback, select_format_cb, form);
01207        }
01208        XtVaSetValues(format_selection_button, XtNwidth, max_entry_width, NULL);
01209        
01210        r3form = XtVaCreateManagedWidget("to_file_form", formWidgetClass,
01211                                     form,
01212                                     XtNborderWidth, 0,
01213                                     XtNfromVert, r1form,
01214                                     HORIZONTAL_RESIZING_YES,
01215                                     VERTICAL_RESIZING_NO,
01216                                     NULL);
01217        to_file_radio_or_label[act] = XtVaCreateManagedWidget("to_file", labelWidgetClass,
01218                                                        r3form,
01219                                                        XtNlabel, "File name: ",
01220                                                        XtNborderWidth, 0,
01221                                                        HORIZONTAL_RESIZING_NO,
01222                                                        VERTICAL_RESIZING_NO,
01223                                                        NULL);
01224        print_to_file_text[act] = XtVaCreateManagedWidget("file_text", asciiTextWidgetClass,
01225                                                    r3form,
01226                                                    XtNwidth, w_avg,
01227                                                    XtNdataCompression, False,
01228                                                    /*                                               XtNvertDistance, ddist + 5, */
01229                                                    XtNeditType, XawtextEdit,
01230                                                    XtNfromHoriz, to_file_radio_or_label[act],
01231                                                    HORIZONTAL_RESIZING_YES,
01232                                                    VERTICAL_RESIZING_NO,
01233                                                    NULL);
01234        XtOverrideTranslations(print_to_file_text[act], xlats2);
01235        
01236        
01237        { /* align left edges of format selection pulldown and filename field */
01238            Dimension w1, w2, w_max;
01239            XtVaGetValues(format_selection_label, XtNwidth, &w1, NULL);
01240            XtVaGetValues(to_file_radio_or_label[act], XtNwidth, &w2, NULL);
01241            w_max = MAX(w1, w2);
01242            XtVaSetValues(format_selection_button, XtNhorizDistance, ddist + (w_max - w1), NULL);
01243            XtVaSetValues(print_to_file_text[act], XtNhorizDistance, ddist + (w_max - w2), NULL);
01244        }
01245     }
01246     
01247 #define DIST_1 8 /* FIXME */
01248     print_to_file_button[act] = XtVaCreateManagedWidget("file_button", commandWidgetClass,
01249                                                  r3form,
01250                                                  XtNlabel, "Browse ...",
01251                                                  XtNfromHoriz, print_to_file_text[act],
01252                                                  XtNhorizDistance, DIST_1,
01253                                                  /* attach to right of form, no resizing: */
01254                                                  XtNleft, XtChainRight, XtNright, XtChainRight,
01255                                                  VERTICAL_RESIZING_NO,
01256                                                  NULL);
01257     
01258     XtVaGetValues(print_to_file_button[act], XtNwidth, &w_curr, NULL);
01259     XtVaSetValues(print_to_file_text[act], XtNwidth, w_avg - w_curr - DIST_1 - 2, NULL);
01260 #undef DIST_1
01261 
01262     adjust_vertically(to_file_radio_or_label[act], print_to_file_text[act], ddist + 5);
01263     adjust_vertically(print_to_file_text[act], to_file_radio_or_label[act], ddist + 5);
01264     adjust_vertically(print_to_file_button[act], to_file_radio_or_label[act], ddist + 5);
01265     
01266     XtAddCallback(print_to_file_button[act], XtNcallback, cb_browse, (XtPointer)info);
01267     
01268     /* other dvips options */
01269     r4form = XtVaCreateManagedWidget("dvips_options_form", formWidgetClass,
01270                                     form,
01271                                     XtNborderWidth, 0,
01272                                     XtNfromVert, r3form,
01273                                     XtNvertDistance, 0,
01274                                     HORIZONTAL_RESIZING_YES,
01275                                     NULL);
01276     
01277     r4label = XtVaCreateManagedWidget("dvips_options_name", labelWidgetClass,
01278                                   r4form,
01279                                   XtNlabel, "Dvips Options:",
01280                                   XtNborderWidth, 0,
01281                                   HORIZONTAL_RESIZING_NO,
01282                                   VERTICAL_RESIZING_NO,
01283                                   NULL);
01284     
01285     dvips_options_text[act] = XtVaCreateManagedWidget("dvips_options_text", asciiTextWidgetClass,
01286                                                 r4form,
01287                                                 XtNwidth, w_avg,
01288                                                 XtNdataCompression, False,
01289                                                 XtNeditType, XawtextEdit,
01290                                                 XtNfromHoriz, r4label,
01291                                                 HORIZONTAL_RESIZING_YES,
01292                                                 VERTICAL_RESIZING_NO,
01293                                                 NULL);
01294     XtOverrideTranslations(dvips_options_text[act], xlats2);
01295 
01296     { /* align left edges of input fields */
01297        Dimension w1, w2, w3, w_max;
01298 
01299        if (act == FILE_PRINT)
01300            XtVaGetValues(to_printer_radio, XtNwidth, &w1, NULL);
01301        else
01302            XtVaGetValues(format_selection_label, XtNwidth, &w1, NULL);
01303 
01304        XtVaGetValues(to_file_radio_or_label[act], XtNwidth, &w2, NULL);
01305        XtVaGetValues(r4label, XtNwidth, &w3, NULL);
01306        
01307        w_max = MAX(MAX(w1, w2), w3);
01308 
01309        if (act == FILE_PRINT)
01310            XtVaSetValues(print_to_printer_text, XtNhorizDistance, ddist + (w_max - w1), NULL);
01311        else
01312             XtVaSetValues(format_selection_button, XtNhorizDistance, ddist + (w_max - w1), NULL);
01313        
01314        XtVaSetValues(print_to_file_text[act], XtNhorizDistance, ddist + (w_max - w2), NULL);
01315        XtVaSetValues(dvips_options_text[act], XtNhorizDistance, ddist + (w_max - w3), NULL);
01316     }
01317 
01318     /* page selection */
01319 
01320     f02form = XtVaCreateManagedWidget("dummy_pages_form", formWidgetClass,
01321                                   form,
01322                                   XtNfromVert, r4form,
01323                                   XtNresizable, True,
01324                                   XtNborderWidth, 0,
01325                                   /*                                 XtNvertDistance, 10, */
01326                                   HORIZONTAL_RESIZING_NO,
01327                                   NULL);
01328     
01329     r5label = XtVaCreateManagedWidget("range_lab", labelWidgetClass,
01330                                   f02form,
01331                                   XtNlabel, "Pages:",
01332                                   XtNborderWidth, 0,
01333                                   HORIZONTAL_RESIZING_NO,
01334                                   NULL);
01335 
01336     r6form = XtVaCreateManagedWidget("page_range_form", formWidgetClass,
01337                                  form,
01338                                  XtNborderWidth, 0,
01339                                  XtNfromVert, f02form,
01340                                  /*                                 XtNvertDistance, 0, */
01341                                  HORIZONTAL_RESIZING_NO,
01342                                  NULL);
01343 
01344     accels2 = XtParseAcceleratorTable("<Btn1Down>,<Btn1Up>:set()notify()");
01345     range_all_radio[act] = XtVaCreateManagedWidget("range_all",
01346 #ifdef XAW
01347                                              radioWidgetClass,
01348 #else
01349                                              toggleWidgetClass,
01350 #endif
01351                                              r6form,
01352                                              XtNlabel, "All ",
01353                                              XtNborderWidth, 0,
01354                                              XtNhighlightThickness, 1,
01355                                              XtNradioData, act == FILE_PRINT ? PRINT_ALL : SAVE_ALL,
01356                                              XtNstate, True, /* enable this button by default */
01357                                              XtNtranslations, xlats,
01358                                              XtNaccelerators, accels2,
01359                                              /*                                        XtNvertDistance, 0, */
01360                                              HORIZONTAL_RESIZING_NO,
01361                                              VERTICAL_RESIZING_NO,
01362                                              NULL);
01363     if (act == FILE_PRINT)
01364        XtAddCallback(range_all_radio[act], XtNcallback, cb_range, (XtPointer)PRINT_ALL);
01365     else
01366        XtAddCallback(range_all_radio[act], XtNcallback, cb_range, (XtPointer)SAVE_ALL);
01367     XtInstallAccelerators(r6form, range_all_radio[act]);
01368 
01369     r61form = XtVaCreateManagedWidget("range_marked_form", formWidgetClass,
01370                                   form,
01371                                   XtNborderWidth, 0,
01372                                   XtNfromVert, r6form,
01373                                   /*                                 XtNvertDistance, 0, */
01374                                   HORIZONTAL_RESIZING_NO,
01375                                   NULL);
01376 
01377     range_marked_radio[act] = XtVaCreateManagedWidget("range_marked",
01378 #ifdef XAW
01379                                                 radioWidgetClass,
01380 #else
01381                                                 toggleWidgetClass,
01382 #endif
01383 
01384                                                 r61form,
01385                                                 XtNlabel, "Marked ",
01386                                                 XtNborderWidth, 0,
01387                                                 XtNhighlightThickness, 1,
01388                                                 XtNradioGroup, range_all_radio[act],
01389                                                 XtNradioData, act == FILE_PRINT ? PRINT_MARKED : SAVE_MARKED,
01390                                                 XtNtranslations, xlats,
01391                                                 XtNaccelerators, accels2,
01392                                                 /*                                               XtNvertDistance, 0, */
01393                                                 HORIZONTAL_RESIZING_NO,
01394                                                 VERTICAL_RESIZING_NO,
01395                                                 NULL);
01396     if (act == FILE_PRINT)
01397        XtAddCallback(range_marked_radio[act], XtNcallback, cb_range, (XtPointer)PRINT_RANGE);
01398     else
01399        XtAddCallback(range_marked_radio[act], XtNcallback, cb_range, (XtPointer)SAVE_RANGE);
01400     XtInstallAccelerators(r61form, range_marked_radio[act]);
01401 
01402     r7form = XtVaCreateManagedWidget("range_from_to_form", formWidgetClass,
01403                                  form,
01404                                  XtNborderWidth, 0,
01405                                  XtNfromVert, r61form,
01406                                  /*                                 XtNvertDistance, 0, */
01407                                  XtNresizable, True,
01408                                  /*  HORIZONTAL_RESIZING_NO, */
01409                                  NULL);
01410 
01411     range_from_to_radio[act] = XtVaCreateManagedWidget("range_from_to",
01412 #ifdef XAW
01413                                                  radioWidgetClass,
01414 #else
01415                                                  toggleWidgetClass,
01416 #endif
01417                                                  r7form,
01418                                                  XtNlabel, "From: ",
01419                                                  XtNborderWidth, 0,
01420                                                  XtNhighlightThickness, 1,
01421                                                  XtNradioGroup, range_all_radio[act],
01422                                                  XtNradioData, act == FILE_PRINT ? PRINT_RANGE : SAVE_RANGE,
01423                                                  XtNtranslations, xlats,
01424                                                  XtNaccelerators, accels2,
01425                                                  /*                                               XtNvertDistance, 0, */
01426                                                  HORIZONTAL_RESIZING_NO,
01427                                                  VERTICAL_RESIZING_NO,
01428                                                  NULL);
01429     if (act == FILE_PRINT)
01430        XtAddCallback(range_from_to_radio[act], XtNcallback, cb_range, (XtPointer)PRINT_RANGE);
01431     else
01432        XtAddCallback(range_from_to_radio[act], XtNcallback, cb_range, (XtPointer)SAVE_RANGE);
01433     XtInstallAccelerators(r7form, range_from_to_radio[act]);
01434 
01435     page_from_text[act] = XtVaCreateManagedWidget("range_from", asciiTextWidgetClass,
01436                                             r7form,
01437                                             XtNdataCompression, False,
01438                                             XtNeditType, XawtextEdit,
01439                                             XtNwidth, 50,
01440                                             XtNfromHoriz, range_from_to_radio[act],
01441                                             HORIZONTAL_RESIZING_NO,
01442                                             VERTICAL_RESIZING_NO,
01443                                             NULL);
01444     XtOverrideTranslations(page_from_text[act], xlats2);
01445     XtAddEventHandler(page_from_text[act], KeyPressMask | ButtonPressMask, False,
01446                     xaw_range_handle_key, (XtPointer)act);
01447 
01448     to_label[act] = XtVaCreateManagedWidget("range_to_lab", labelWidgetClass,
01449                                        r7form,
01450                                        XtNlabel, "to: ",
01451                                        XtNborderWidth, 0,
01452                                        XtNfromHoriz, page_from_text[act],
01453                                        HORIZONTAL_RESIZING_NO,
01454                                        VERTICAL_RESIZING_NO,
01455                                        NULL);
01456 
01457     page_to_text[act] = XtVaCreateManagedWidget("range_to", asciiTextWidgetClass,
01458                                           r7form,
01459                                           XtNdataCompression, False,
01460                                           XtNeditType, XawtextEdit,
01461                                           XtNwidth, 50,
01462                                           XtNfromHoriz, to_label[act],
01463                                           HORIZONTAL_RESIZING_NO,
01464                                           VERTICAL_RESIZING_NO,
01465                                           NULL);
01466     XtOverrideTranslations(page_to_text[act], xlats2);
01467     XtAddEventHandler(page_to_text[act], KeyPressMask | ButtonPressMask, False,
01468                     xaw_range_handle_key, (XtPointer)act);
01469 
01470     of_label[act] = XtVaCreateManagedWidget("range_of", labelWidgetClass,
01471                                        r7form,
01472                                        XtNlabel, ofstring,
01473                                        XtNborderWidth, 0,
01474                                        XtNresizable, True,
01475                                        XtNfromHoriz, page_to_text[act],
01476                                        /*  HORIZONTAL_RESIZING_NO, */
01477                                        XtNleft, XtChainLeft,
01478                                        VERTICAL_RESIZING_NO,
01479                                        NULL);
01480 
01481     adjust_vertically(range_from_to_radio[act], page_from_text[act], ddist);
01482     adjust_vertically(to_label[act], page_from_text[act], ddist);
01483     adjust_vertically(of_label[act], page_from_text[act], ddist);
01484 
01485     /* box for the OK/Cancel button */
01486     box = XtVaCreateManagedWidget("box", formWidgetClass,
01487                               paned,
01488                               /* resizing by user isn't needed */
01489                               XtNshowGrip, False,
01490                               XtNdefaultDistance, 6, /* some padding */
01491                               /* resizing the window shouldn't influence this box,
01492                                * but only the pane widget
01493                                */
01494                               XtNskipAdjust, True,
01495                               XtNaccelerators, G_accels_cr,
01496                               NULL);
01497        
01498     ok_button[act] = XtVaCreateManagedWidget(act == FILE_PRINT ? "print_button" : "save_button",
01499                                         commandWidgetClass, box,
01500                                         XtNlabel, act == FILE_PRINT ? "Print" : "Save",
01501                                         XtNaccelerators, G_accels_cr,
01502                                         XtNtop, XtChainTop,
01503                                         XtNbottom, XtChainBottom,
01504                                         HORIZONTAL_RESIZING_NO,
01505                                         NULL);
01506     if (act == FILE_PRINT)
01507        XtAddCallback(ok_button[act], XtNcallback, cb_print_or_save, (XtPointer)info);
01508     else
01509        XtAddCallback(ok_button[act], XtNcallback, cb_print_or_save, (XtPointer)info);
01510     
01511     XtInstallAccelerators(form, ok_button[act]);
01512     if (act == FILE_PRINT)
01513        XtInstallAccelerators(print_to_printer_text, ok_button[act]);
01514     XtInstallAccelerators(print_to_file_text[act], ok_button[act]);
01515 
01516     cancel_button[act] = XtVaCreateManagedWidget("cancel", commandWidgetClass,
01517                                            box,
01518                                            XtNlabel, "Cancel",
01519                                            XtNfromHoriz, ok_button[act],
01520                                            XtNbottom, XtChainBottom,
01521                                            XtNjustify, XtJustifyRight,
01522                                            XtNleft, XtChainRight,
01523                                            XtNright, XtChainRight,
01524                                            NULL);
01525     if (act == FILE_PRINT)
01526        XtAddCallback(cancel_button[act], XtNcallback, cb_print_cancel, (XtPointer)info);
01527     else
01528        XtAddCallback(cancel_button[act], XtNcallback, cb_save_cancel, (XtPointer)info);
01529 
01530     XtManageChild(top_level_shell);
01531     center_window(top_level_shell, globals.widgets.top_level);
01532     XtMapWidget(top_level_shell);
01533     XSetWMProtocols(XtDisplay(top_level_shell), XtWindow(top_level_shell), &WM_DELETE_WINDOW, 1);
01534 
01535     if (pageinfo_have_marked_pages()) {
01536        XawToggleSetCurrent(range_all_radio[act],
01537                          act == FILE_PRINT ? (XtPointer)PRINT_MARKED : (XtPointer)SAVE_MARKED);
01538     }
01539     else if ((act == FILE_PRINT && save_pr_info.range_radio == PRINT_MARKED)
01540             || (act == FILE_SAVE && save_save_info.range_radio == SAVE_MARKED)) {
01541        XawToggleSetCurrent(range_all_radio[act],
01542                          act == FILE_PRINT ? (XtPointer)PRINT_ALL : (XtPointer)SAVE_ALL);
01543     }
01544     
01545 #else /* not MOTIF */
01546     Widget form, pane, box;
01547     Widget frame1, f1label, f1child;
01548     Widget r4label;
01549     Widget frame2, f2label, f2child;
01550     XmString str;
01551     XtTranslations xlats;
01552     
01553     XtAddActions(print_actions, XtNumber(print_actions));
01554 
01555     if (act == FILE_SAVE) {
01556        char *ptr = get_string_va("#override \n<Key>osfCancel:WM_save_cancel(%p)", info);
01557        xlats = XtParseTranslationTable(ptr);
01558        free(ptr);
01559     }
01560     else {
01561        char *ptr = get_string_va("#override \n<Key>osfCancel:WM_print_cancel(%p)", info);
01562        xlats = XtParseTranslationTable(ptr);
01563        free(ptr);
01564     }
01565     
01566     top_level_shell = XtVaCreatePopupShell(act == FILE_SAVE ? "save_popup" : "print_popup",
01567                                       xmDialogShellWidgetClass, globals.widgets.top_level,
01568                                       XmNtitle, act == FILE_SAVE ? "Save file" : "Print DVI file",
01569                                       XmNallowShellResize, True,
01570                                       XmNdeleteResponse, XmDO_NOTHING, /* we'll take care of that ourselves */
01571                                       XmNmappedWhenManaged, False, /* so that we can center it first */
01572                                       NULL);
01573 
01574     /* make the window manager destroy action just pop down the dialog */
01575     WM_DELETE_WINDOW = XmInternAtom(XtDisplay(top_level_shell), "WM_DELETE_WINDOW", False);
01576     if (act == FILE_SAVE)
01577        XmAddWMProtocolCallback(top_level_shell, WM_DELETE_WINDOW, cb_save_cancel, (XtPointer)info);
01578     else
01579        XmAddWMProtocolCallback(top_level_shell, WM_DELETE_WINDOW, cb_print_cancel, (XtPointer)info);
01580 
01581 
01582     pane = XtVaCreateWidget(act == FILE_SAVE ? "save_paned" : "print_paned",
01583                          xmPanedWindowWidgetClass, top_level_shell,
01584                          /* make sashes invisible */
01585                          XmNsashWidth, 1,
01586                          XmNsashHeight, 1,
01587                          /* turn separator off, since it gives visual noise with the frames */
01588                          XmNseparatorOn, False,
01589                          NULL);
01590 
01591     
01592     form = XtVaCreateWidget("form", xmFormWidgetClass,
01593                          pane,
01594                          XmNhorizontalSpacing, DDIST_MAJOR,
01595                          XmNverticalSpacing, DDIST_MAJOR,
01596                          XmNautoUnmanage, False,
01597                          XTranslations, xlats,
01598                          NULL);
01599 
01600     if (act == FILE_PRINT) {
01601        /*  First frame:  print to printer or file */
01602 
01603        frame1 = XtVaCreateWidget("print_to_frame", xmFrameWidgetClass, form,
01604                               XmNmarginWidth, DDIST,
01605                               XmNmarginHeight, DDIST,
01606                               XmNtopAttachment, XmATTACH_FORM,
01607                               XmNleftAttachment, XmATTACH_FORM,
01608                               XmNrightAttachment, XmATTACH_FORM,
01609                               XTranslations, xlats,
01610                               NULL);
01611 
01612        str = XmStringCreateLocalized("Print to:");
01613        f1label = XtVaCreateManagedWidget("title", xmLabelGadgetClass,
01614                                      frame1,
01615                                      XmNchildType, XmFRAME_TITLE_CHILD,
01616                                      XmNlabelString, str,
01617                                      NULL);
01618        XmStringFree(str);
01619 
01620        f1child = XtVaCreateWidget("form", xmFormWidgetClass, frame1,
01621                                XmNhorizontalSpacing, DDIST,
01622                                XmNverticalSpacing, DDIST,
01623                                XmNtopAttachment, XmATTACH_FORM,
01624                                XmNleftAttachment, XmATTACH_FORM,
01625                                XmNrightAttachment, XmATTACH_FORM,
01626                                XTranslations, xlats,
01627                                NULL);
01628 
01629        str = XmStringCreateLocalized("Printer:");
01630        to_printer_radio = XtVaCreateManagedWidget("to_printer",
01631                                              xmToggleButtonGadgetClass, f1child,
01632                                              XmNlabelString, str,
01633                                              XmNindicatorType, XmONE_OF_MANY,
01634                                              XmNset, resource.default_printing_target == PRINT_TO_PRINTER,
01635                                              XmNtopAttachment, XmATTACH_FORM,
01636                                              XmNtopOffset, 0,
01637                                              XmNleftAttachment, XmATTACH_FORM,
01638                                              XmNleftOffset, 0,
01639                                              NULL);
01640        XmStringFree(str);
01641        XtAddCallback(to_printer_radio, XmNvalueChangedCallback, cb_print_vs_file, (XtPointer)1);
01642 
01643        XtOverrideTranslations(to_printer_radio, xlats);
01644 
01645        print_to_printer_text = XtVaCreateManagedWidget("print_text", xmTextFieldWidgetClass,
01646                                                  f1child,
01647                                                  XmNtopAttachment, XmATTACH_FORM,
01648                                                  XmNtopOffset, 0,
01649                                                  XmNleftAttachment, XmATTACH_WIDGET,
01650                                                  XmNrightAttachment, XmATTACH_FORM,
01651                                                  XmNleftWidget, to_printer_radio,
01652                                                  XTranslations, xlats,
01653                                                  NULL);
01654        XtAddCallback(print_to_printer_text, XmNactivateCallback, cb_print_or_save, info);
01655 
01656        adjust_heights(to_printer_radio, print_to_printer_text, NULL);
01657 
01658        str = XmStringCreateLocalized("File:");
01659        to_file_radio_or_label[act] = XtVaCreateManagedWidget("to_file", xmToggleButtonGadgetClass,
01660                                                        f1child,
01661                                                        XmNlabelString, str,
01662                                                        XmNindicatorType, XmONE_OF_MANY,
01663                                                        XmNtopAttachment, XmATTACH_WIDGET,
01664                                                        XmNtopWidget, print_to_printer_text,
01665                                                        XmNleftAttachment, XmATTACH_FORM,
01666                                                        XmNset, resource.default_printing_target == PRINT_TO_FILE,
01667                                                        XmNleftOffset, 0,
01668                                                        NULL);
01669        XmStringFree(str);
01670        XtAddCallback(to_file_radio_or_label[act], XmNvalueChangedCallback, cb_print_vs_file, (XtPointer)2);
01671 
01672        str = XmStringCreateLocalized("Browse ...");
01673        print_to_file_button[act] = XtVaCreateManagedWidget("file_button", xmPushButtonWidgetClass,
01674                                                      f1child,
01675                                                      XmNlabelString, str,
01676                                                      XmNsensitive, resource.default_printing_target == PRINT_TO_FILE,
01677                                                      XmNtopAttachment, XmATTACH_WIDGET,
01678                                                      XmNtopWidget, print_to_printer_text,
01679                                                      XmNrightAttachment, XmATTACH_FORM,
01680                                                      NULL);
01681        XmStringFree(str);   
01682 
01683        XtOverrideTranslations(to_file_radio_or_label[act], xlats);
01684        XtOverrideTranslations(print_to_file_button[act], xlats);
01685 
01686        print_to_file_text[act] = XtVaCreateManagedWidget("file_text", xmTextFieldWidgetClass,
01687                                                    f1child,
01688                                                    XmNsensitive, resource.default_printing_target == PRINT_TO_FILE,
01689                                                    XmNtopAttachment, XmATTACH_WIDGET,
01690                                                    XmNtopWidget, print_to_printer_text,
01691                                                    XmNrightAttachment, XmATTACH_WIDGET,
01692                                                    XmNrightWidget, print_to_file_button[act],
01693                                                    XmNleftAttachment, XmATTACH_WIDGET,
01694                                                    XmNleftWidget, to_file_radio_or_label[act],
01695                                                    XTranslations, xlats,
01696                                                    NULL);
01697 
01698        adjust_heights(to_file_radio_or_label[act], print_to_file_button[act], print_to_file_text[act], NULL);
01699 
01700        XtAddCallback(print_to_file_text[act], XmNactivateCallback, cb_print_or_save, (XtPointer)info);
01701        XtAddCallback(print_to_file_button[act], XmNactivateCallback, cb_browse, (XtPointer)info);
01702 
01703        XtManageChild(f1child);
01704        XtManageChild(frame1);
01705 
01706     } /* saving, not printing */
01707     else {
01708        frame1 = XtVaCreateWidget("save_as_frame", xmFrameWidgetClass,
01709                               form,
01710                               XmNmarginWidth, DDIST,
01711                               XmNmarginHeight, DDIST,
01712                               XmNtopAttachment, XmATTACH_FORM,
01713                               XmNleftAttachment, XmATTACH_FORM,
01714                               XmNrightAttachment, XmATTACH_FORM,
01715                               NULL);
01716 
01717        str = XmStringCreateLocalized("Save as:");
01718        f1label = XtVaCreateManagedWidget("title", xmLabelGadgetClass,
01719                                      frame1,
01720                                      XmNchildType, XmFRAME_TITLE_CHILD,
01721                                      XmNlabelString, str,
01722                                      NULL);
01723        XmStringFree(str);
01724 
01725        f1child = XtVaCreateWidget("form", xmFormWidgetClass, frame1,
01726                                XmNhorizontalSpacing, DDIST,
01727                                XmNverticalSpacing, DDIST,
01728                                XmNtopAttachment, XmATTACH_FORM,
01729                                XmNleftAttachment, XmATTACH_FORM,
01730                                XmNrightAttachment, XmATTACH_FORM,
01731                                XTranslations, xlats,
01732                                NULL);
01733 /*     fprintf(stderr, "CHILD: 0x%x\n", (long)f1child); */
01734        str = XmStringCreateLocalized("Format:");
01735        format_selection_texts[0] = XmStringCreateLocalized((char *)output_format_mapping[0].fmt_string);
01736        format_selection_texts[1] = XmStringCreateLocalized((char *)output_format_mapping[1].fmt_string);
01737        format_selection_texts[2] = XmStringCreateLocalized((char *)output_format_mapping[2].fmt_string);
01738        format_selection_texts[3] = XmStringCreateLocalized((char *)output_format_mapping[3].fmt_string);
01739        format_selection_texts[4] = XmStringCreateLocalized((char *)output_format_mapping[4].fmt_string);
01740        format_selection_option
01741            = XmVaCreateSimpleOptionMenu(f1child, "format_selection_option",
01742                                     str,  'F',
01743                                     resource.default_saving_format, /*initial menu selection*/
01744                                     select_format_cb, /* callback */
01745                                     XmVaPUSHBUTTON, format_selection_texts[0], 'P', NULL, NULL,
01746                                     XmVaPUSHBUTTON, format_selection_texts[1], 'F', NULL, NULL,
01747                                     XmVaPUSHBUTTON, format_selection_texts[2], 'D', NULL, NULL,
01748                                     XmVaPUSHBUTTON, format_selection_texts[3], 'T', NULL, NULL,
01749                                     XmVaPUSHBUTTON, format_selection_texts[4], 'U', NULL, NULL,
01750                                     NULL);
01751        
01752        XmStringFree(str);
01753        XmStringFree(format_selection_texts[0]);
01754        XmStringFree(format_selection_texts[1]);
01755        XmStringFree(format_selection_texts[2]);
01756        XmStringFree(format_selection_texts[3]);
01757        XmStringFree(format_selection_texts[4]);
01758        
01759        str = XmStringCreateLocalized("File name:");
01760        to_file_radio_or_label[act] = XtVaCreateManagedWidget("to_file", xmLabelGadgetClass,
01761                                                        f1child,
01762                                                        XmNtopAttachment, XmATTACH_WIDGET,
01763                                                        XmNtopWidget, format_selection_option,
01764                                                        XmNleftAttachment, XmATTACH_FORM,
01765                                                        /* XmNchildType, XmFRAME_TITLE_CHILD, */
01766                                                        XmNlabelString, str,
01767                                                        NULL);
01768        XmStringFree(str);
01769        str = XmStringCreateLocalized("Browse ...");
01770        print_to_file_button[act] = XtVaCreateManagedWidget("file_button", xmPushButtonWidgetClass,
01771                                                      f1child,
01772                                                      XmNlabelString, str,
01773                                                      XmNtopAttachment, XmATTACH_WIDGET,
01774                                                      XmNtopWidget, format_selection_option,
01775                                                      XmNrightAttachment, XmATTACH_FORM,
01776                                                      XTranslations, xlats,
01777                                                      NULL);
01778        print_to_file_text[act] = XtVaCreateManagedWidget("file_text", xmTextFieldWidgetClass,
01779                                                    f1child,
01780                                                    XmNtopAttachment, XmATTACH_WIDGET,
01781                                                    XmNtopWidget, format_selection_option,
01782                                                    XmNleftAttachment, XmATTACH_WIDGET,
01783                                                    XmNleftWidget, to_file_radio_or_label[act],
01784                                                    XmNrightAttachment, XmATTACH_WIDGET,
01785                                                    XmNrightWidget, print_to_file_button[act],
01786                                                    XTranslations, xlats,
01787                                                    NULL);
01788 
01789        adjust_heights(to_file_radio_or_label[act], print_to_file_button[act], print_to_file_text[act], NULL);
01790        XtAddCallback(print_to_file_button[act], XmNactivateCallback, cb_browse, (XtPointer)info);
01791     }
01792     
01793 #if 1
01794     { /* align left edges of widgets */
01795        Dimension w1, w2;
01796 
01797        XtVaGetValues(to_file_radio_or_label[act], XmNwidth, &w2, NULL);
01798        if (act == FILE_PRINT)
01799            XtVaGetValues(to_printer_radio, XmNwidth, &w1, NULL);
01800        else {
01801            Widget w;
01802            if (get_widget_by_name(&w, format_selection_option, "OptionLabel", True)) {
01803               XtVaGetValues(w, XmNwidth, &w1, NULL);
01804            }
01805            else {
01806               w1 = w2;
01807            }
01808        }
01809        
01810        if (w1 > w2) {
01811            Dimension offset = DDIST;
01812            offset += w1 - w2;
01813            XtVaSetValues(print_to_file_text[act], XmNleftOffset, offset, NULL);
01814        }
01815        else if (w2 > w1) {
01816            Dimension offset = DDIST;
01817            offset += w2 - w1;
01818            if (act == FILE_PRINT)
01819               XtVaSetValues(print_to_printer_text, XmNleftOffset, offset, NULL);
01820            else {
01821               Widget w;
01822               if (get_widget_by_name(&w, format_selection_option, "OptionLabel", True)) {
01823                   /* FIXME: Setting width would be cleaner, but it doesn't work ...?
01824                      Dimension curr_w;
01825                      XtVaGetValues(w, XmNwidth, &curr_w, NULL);
01826                      XtVaSetValues(w, XmNwidth, curr_w + offset, NULL);
01827                    */
01828                   /*  fprintf(stderr, "Setting width from %d to: %d\n", curr_w, curr_w + offset); */
01829                   XtVaSetValues(w,
01830                               XmNmarginRight, offset,
01831                               XmNalignment, XmALIGNMENT_BEGINNING,
01832                               NULL);
01833               }
01834 
01835            }                      
01836        }
01837     }
01838 #endif /* 0 */
01839 
01840     if (act == FILE_SAVE) {
01841        XtManageChild(format_selection_option);
01842        XtManageChild(f1child);
01843        XtManageChild(frame1);
01844     }
01845     
01846     /* additional dvips options */
01847     str = XmStringCreateLocalized("Dvips Options:");
01848     r4label = XtVaCreateManagedWidget("dvips_options_name", xmLabelGadgetClass,
01849                                   form,
01850                                   XmNlabelString, str,
01851                                   XmNtopAttachment, XmATTACH_WIDGET,
01852                                   XmNtopWidget, frame1,
01853                                   XmNleftAttachment, XmATTACH_FORM,
01854                                   NULL);
01855     XmStringFree(str);
01856     
01857     dvips_options_text[act] = XtVaCreateManagedWidget("dvips_options_text", xmTextFieldWidgetClass,
01858                                                 form,
01859                                                 XmNtopAttachment, XmATTACH_WIDGET,
01860                                                 XmNtopWidget, frame1,
01861                                                 XmNleftAttachment, XmATTACH_WIDGET,
01862                                                 XmNrightAttachment, XmATTACH_FORM,
01863                                                 XmNleftWidget, r4label,
01864                                                 XmNcolumns, 20,
01865                                                 XTranslations, xlats,
01866                                                 NULL);
01867     XtAddCallback(dvips_options_text[act], XmNactivateCallback, cb_print_or_save, (XtPointer)info);
01868     adjust_heights(r4label, dvips_options_text[act], NULL);
01869     
01870     /* page selection */
01871     frame2 = XtVaCreateWidget(act == FILE_PRINT ? "print_page_frame" : "save_page_frame", xmFrameWidgetClass,
01872                            form,
01873                            XmNmarginWidth, DDIST,
01874                            XmNmarginHeight, DDIST,
01875                            XmNresizable, True,
01876                            XmNtopAttachment, XmATTACH_WIDGET,
01877                            XmNtopWidget, dvips_options_text[act],
01878                            XmNleftAttachment, XmATTACH_FORM,
01879                            XmNrightAttachment, XmATTACH_FORM,
01880                            XTranslations, xlats,
01881                            NULL);
01882 
01883     str = XmStringCreateLocalized("Pages:");
01884     f2label = XtVaCreateManagedWidget("title", xmLabelGadgetClass,
01885                                   frame2,
01886                                   XmNchildType, XmFRAME_TITLE_CHILD,
01887                                   XmNlabelString, str,
01888                                   NULL);
01889     XmStringFree(str);
01890 
01891     f2child = XtVaCreateWidget("form", xmFormWidgetClass, frame2,
01892                             XmNhorizontalSpacing, DDIST,
01893                             XmNverticalSpacing, DDIST,
01894                             XmNresizable, True,
01895                             XTranslations, xlats,
01896                             XTranslations, xlats,
01897                             NULL);
01898 
01899     str = XmStringCreateLocalized("All");
01900     range_all_radio[act] = XtVaCreateManagedWidget("all",
01901                                              xmToggleButtonGadgetClass, f2child,
01902                                              XmNlabelString, str,
01903                                              XmNindicatorType, XmONE_OF_MANY,
01904                                              XmNset, True,
01905                                              XmNtopAttachment, XmATTACH_FORM,
01906                                              XmNtopOffset, 0,
01907                                              XmNleftAttachment, XmATTACH_FORM,
01908                                              XmNleftOffset, 0,
01909                                              XTranslations, xlats,
01910                                              NULL);
01911     XmStringFree(str);
01912     if (act == FILE_PRINT) {
01913        XtAddCallback(range_all_radio[act], XmNvalueChangedCallback, cb_range, (XtPointer)PRINT_ALL);
01914     }
01915     else {
01916        XtAddCallback(range_all_radio[act], XmNvalueChangedCallback, cb_range, (XtPointer)SAVE_ALL);
01917     }
01918 
01919     str = XmStringCreateLocalized("Marked");
01920     range_marked_radio[act] =  XtVaCreateManagedWidget("marked",
01921                                                  xmToggleButtonGadgetClass, f2child,
01922                                                  XmNlabelString, str,
01923                                                  XmNindicatorType, XmONE_OF_MANY,
01924                                                  XmNtopAttachment, XmATTACH_WIDGET,
01925                                                  XmNtopWidget, range_all_radio[act],
01926                                                  XmNleftAttachment, XmATTACH_FORM,
01927                                                  XmNleftOffset, 0,
01928                                                  XTranslations, xlats,
01929                                                  NULL);
01930     XmStringFree(str);
01931     if (act == FILE_PRINT) {
01932        XtAddCallback(range_marked_radio[act], XmNvalueChangedCallback, cb_range, (XtPointer)PRINT_MARKED);
01933     }
01934     else {
01935        XtAddCallback(range_marked_radio[act], XmNvalueChangedCallback, cb_range, (XtPointer)SAVE_MARKED);
01936     }
01937        
01938     str = XmStringCreateLocalized("Range:");
01939     range_from_to_radio[act] = XtVaCreateManagedWidget("range",
01940                                                  xmToggleButtonGadgetClass, f2child,
01941                                                  XmNlabelString, str,
01942                                                  XmNindicatorType, XmONE_OF_MANY,
01943                                                  XmNtopAttachment, XmATTACH_WIDGET,
01944                                                  XmNtopWidget, range_marked_radio[act],
01945                                                  XmNleftAttachment, XmATTACH_FORM,
01946                                                  XmNleftOffset, 0,
01947                                                  XTranslations, xlats,
01948                                                  NULL);
01949     XmStringFree(str);
01950 
01951     if (act == FILE_PRINT) {
01952        XtAddCallback(range_from_to_radio[act], XmNvalueChangedCallback, cb_range, (XtPointer)PRINT_RANGE);
01953     }
01954     else {
01955        XtAddCallback(range_from_to_radio[act], XmNvalueChangedCallback, cb_range, (XtPointer)SAVE_RANGE);
01956     }
01957     str = XmStringCreateLocalized("From");
01958     from_label[act] = XtVaCreateManagedWidget("from", xmLabelGadgetClass,
01959                                          f2child,
01960                                          XmNlabelString, str,
01961                                          XmNsensitive, False,
01962                                          XmNtopAttachment, XmATTACH_WIDGET,
01963                                          XmNtopWidget, range_marked_radio[act],
01964                                          XmNleftAttachment, XmATTACH_WIDGET,
01965                                          XmNleftWidget, range_from_to_radio[act],
01966                                          NULL);
01967     XmStringFree(str);
01968 
01969     page_from_text[act] = XtVaCreateManagedWidget("from_page",
01970                                             xmTextFieldWidgetClass, f2child,
01971                                             XmNcolumns, 5,
01972                                             XmNsensitive, False,
01973                                             XmNtopAttachment, XmATTACH_WIDGET,
01974                                             XmNtopWidget, range_marked_radio[act],
01975                                             XmNleftAttachment, XmATTACH_WIDGET,
01976                                             XmNleftWidget, from_label[act],
01977                                             XTranslations, xlats,
01978                                             NULL);
01979     XtAddCallback(page_from_text[act], XmNactivateCallback, cb_print_or_save, (XtPointer)info);
01980 
01981     str = XmStringCreateLocalized("to");
01982     to_label[act] = XtVaCreateManagedWidget("to", xmLabelGadgetClass,
01983                                        f2child,
01984                                        XmNlabelString, str,
01985                                        XmNsensitive, False,
01986                                        XmNtopAttachment, XmATTACH_WIDGET,
01987                                        XmNtopWidget, range_marked_radio[act],
01988                                        XmNleftAttachment, XmATTACH_WIDGET,
01989                                        XmNleftWidget, page_from_text[act],
01990                                        NULL);
01991     XmStringFree(str);
01992 
01993     page_to_text[act] = XtVaCreateManagedWidget("to_page", xmTextFieldWidgetClass,
01994                                           f2child,
01995                                           XmNcolumns, 5,
01996                                           XmNsensitive, False,
01997                                           XmNtopAttachment, XmATTACH_WIDGET,
01998                                           XmNtopWidget, range_marked_radio[act],
01999                                           XmNleftAttachment, XmATTACH_WIDGET,
02000                                           XmNleftWidget, to_label[act],
02001                                           XTranslations, xlats,
02002                                           NULL);
02003     XtAddCallback(page_to_text[act], XmNactivateCallback, cb_print_or_save, (XtPointer)info);
02004 
02005     str = XmStringCreateLocalized(ofstring);
02006     of_label[act] = XtVaCreateManagedWidget("of", xmLabelGadgetClass,
02007                                        f2child,
02008                                        XmNlabelString, str,
02009                                        XmNsensitive, False,
02010                                        XmNresizable, True,
02011                                        XmNtopAttachment, XmATTACH_WIDGET,
02012                                        XmNtopWidget, range_marked_radio[act],
02013                                        XmNleftAttachment, XmATTACH_WIDGET,
02014                                        XmNleftWidget, page_to_text[act],
02015                                        NULL);
02016     XmStringFree(str);
02017 
02018     adjust_heights(range_from_to_radio[act],
02019                  from_label[act], page_from_text[act],
02020                  to_label[act], page_to_text[act],
02021                  of_label[act],
02022                  NULL);
02023 
02024     XtManageChild(f2child);
02025     XtManageChild(frame2);
02026 
02027     /* box for the OK/Cancel button */
02028     box = XtVaCreateManagedWidget("box", xmFormWidgetClass,
02029                               pane,
02030                               XmNskipAdjust, True, /* don't resize this area */
02031                               XTranslations, xlats,
02032                               NULL);
02033                               
02034     if (act == FILE_PRINT)
02035        str = XmStringCreateLocalized("Print");
02036     else
02037        str = XmStringCreateLocalized("Save");
02038     ok_button[act] = XtVaCreateManagedWidget(act == FILE_PRINT ? "print_button" : "save_button",
02039                                         xmPushButtonWidgetClass, box,
02040                                         XmNlabelString, str,
02041                                         XmNshowAsDefault, True,
02042                                         XmNdefaultButtonShadowThickness, 1,
02043                                         XmNtopAttachment, XmATTACH_FORM,
02044                                         XmNbottomAttachment, XmATTACH_FORM,
02045                                         XmNleftAttachment, XmATTACH_FORM,
02046                                         /* to mimick appearance of native dialog buttons: */
02047                                         XmNmarginWidth, 6,
02048                                         XmNmarginHeight, 4,
02049                                         XmNtopOffset, 10,
02050                                         XmNbottomOffset, 10,
02051                                         XmNleftOffset, 10,
02052                                         NULL);
02053     XmStringFree(str);
02054     if (act == FILE_PRINT)
02055        XtAddCallback(ok_button[act], XmNactivateCallback, cb_print_or_save, (XtPointer)info);
02056     else
02057        XtAddCallback(ok_button[act], XmNactivateCallback, cb_print_or_save, (XtPointer)info);
02058     
02059     XtOverrideTranslations(ok_button[act], XtParseTranslationTable("<Key>Return:ArmAndActivate()"));
02060 
02061     str = XmStringCreateLocalized("Cancel");
02062     cancel_button[act] = XtVaCreateManagedWidget("cancel",
02063                                            xmPushButtonWidgetClass, box,
02064                                            XmNlabelString, str,
02065                                            XmNdefaultButtonShadowThickness, 1,
02066                                            XmNtopAttachment, XmATTACH_FORM,
02067                                            XmNbottomAttachment, XmATTACH_FORM,
02068                                            XmNrightAttachment, XmATTACH_FORM,
02069                                            /* to mimick appearance of native dialog buttons: */
02070                                            XmNmarginWidth, 6,
02071                                            XmNmarginHeight, 4,
02072                                            XmNtopOffset, 10,
02073                                            XmNbottomOffset, 10,
02074                                            XmNrightOffset, 10,
02075                                            NULL);
02076     XmStringFree(str);
02077 
02078     XtOverrideTranslations(range_all_radio[act], xlats);
02079     XtOverrideTranslations(range_marked_radio[act], xlats);
02080     XtOverrideTranslations(range_from_to_radio[act], xlats);
02081     XtOverrideTranslations(ok_button[act], xlats);
02082     XtOverrideTranslations(cancel_button[act], xlats);
02083 
02084     if (act == FILE_PRINT)
02085        XtAddCallback(cancel_button[act], XmNactivateCallback, cb_print_cancel, (XtPointer)info);
02086     else
02087        XtAddCallback(cancel_button[act], XmNactivateCallback, cb_save_cancel, (XtPointer)info);
02088     
02089     { /* make the buttons the same size: */
02090        Dimension w1, w2;
02091        XtVaGetValues(ok_button[act], XtNwidth, &w1, NULL);
02092        XtVaGetValues(cancel_button[act], XtNwidth, &w2, NULL);
02093        if (w1 < w2)
02094            XtVaSetValues(ok_button[act], XtNwidth, w2, NULL);
02095        else if (w2 > w1)
02096            XtVaSetValues(cancel_button[act], XtNwidth, w1, NULL);
02097     }
02098     
02099     if (pageinfo_have_marked_pages()) {
02100        XmToggleButtonGadgetSetState(range_marked_radio[act], True, True);
02101     }
02102     else if (save_pr_info.range_radio == PRINT_MARKED) {
02103        XmToggleButtonGadgetSetState(range_all_radio[act], True, True);
02104     }
02105 
02106     XtManageChild(form);
02107     XtManageChild(pane);
02108     center_window(top_level_shell, globals.widgets.top_level);
02109     XtMapWidget(top_level_shell);
02110     XmProcessTraversal(ok_button[act], XmTRAVERSE_CURRENT);
02111 #endif /* not MOTIF */
02112 
02113     /* set default output format */
02114     save_save_info.output_format = curr_save_info.output_format =
02115        output_format_mapping[resource.default_saving_format].fmt;
02116 
02117     if (act == FILE_SAVE)
02118        update_dvips_options_sensitivity(resource.default_saving_format, top_level_shell);
02119     
02120     return top_level_shell;
02121 }
02122 #undef HORIZONTAL_RESIZING_NO
02123 #undef HORIZONTAL_RESIZING_YES
02124 #undef VERTICAL_RESIZING_NO
02125     
02126 
02127 static void
02128 set_target_radio(struct dialog_info *save_info, struct dialog_info *curr_info, printOrSaveActionT act)
02129 {
02130 #ifdef MOTIF
02131     if (save_info->print_radio > 0 && save_info->print_radio != curr_info->print_radio) {
02132        XmToggleButtonGadgetSetState(save_info->print_radio == PRINT_TO_PRINTER
02133                                  ? to_printer_radio
02134                                  : to_file_radio_or_label[act], True, True);
02135     }
02136 #else /* MOTIF */
02137     UNUSED(act);
02138     UNUSED(curr_info);
02139     XawToggleSetCurrent(to_printer_radio, (XtPointer)save_info->print_radio);
02140 #endif /* MOTIF */
02141 }
02142 
02143 static void
02144 set_range_radio(struct dialog_info *save_info, struct dialog_info *curr_info, printOrSaveActionT act)
02145 {
02146 #ifdef MOTIF
02147     if (save_info->range_radio > 0 && save_info->range_radio != curr_info->range_radio) {
02148        Widget selected = 0;
02149        switch (save_info->range_radio) {
02150        case PRINT_ALL:
02151        case SAVE_ALL:
02152            selected = range_all_radio[act];
02153            break;
02154        case PRINT_MARKED:
02155        case SAVE_MARKED:
02156            selected = range_marked_radio[act];
02157            break;
02158        case PRINT_RANGE:
02159        case SAVE_RANGE:
02160            selected = range_from_to_radio[act];
02161            break;
02162        default:
02163            ASSERT(0, "wrong button type in set_range_radio()");
02164        }
02165        XmToggleButtonGadgetSetState(selected, True, True);
02166     }
02167 #else /* MOTIF */
02168     UNUSED(curr_info);
02169     XawToggleSetCurrent(range_all_radio[act], (XtPointer)save_info->range_radio);
02170 #endif /* MOTIF */
02171 }
02172 
02173 void
02174 save_or_print_callback(struct save_or_print_info *info)
02175 {
02176     printOrSaveActionT act = info->act;
02177     static char ofstring[1024]; /* should be ample */
02178     struct dialog_info *save_info = NULL, *curr_info = NULL;
02179 
02180     if (act == FILE_PRINT) {
02181        save_info = &save_pr_info;
02182        curr_info = &curr_pr_info;
02183        if (print_is_active) {
02184            XBell(DISP, 0);
02185            XRaiseWindow(DISP, XtWindow(print_shell));
02186            return;
02187        }
02188 
02189        if (printlog_raise_active()) {
02190            XBell(DISP, 0);
02191            return;
02192        }
02193     }
02194     else if (act == FILE_SAVE) {
02195        save_info = &save_save_info;
02196        curr_info = &curr_save_info;
02197        if (save_is_active) {
02198            XBell(DISP, 0);
02199            XRaiseWindow(DISP, XtWindow(save_shell));
02200            return;
02201        }
02202     }
02203     else {
02204        ASSERT(0, "wrong action type in save_or_print_callback()");
02205     }
02206 
02207     if (globals.dvi_file.bak_fp == NULL) {
02208        popup_message(globals.widgets.top_level,
02209                     MSG_ERR,
02210                     NULL,
02211                     "Empty or incomplete DVI file. "
02212                     "Please select a new DVI file via File -> Open.");
02213        return;
02214     }
02215 
02216     if (globals.pageno_correct == 1)
02217        sprintf(ofstring, "of %d physical pages", total_pages);
02218     else
02219        sprintf(ofstring, "of %d to %d pages", globals.pageno_correct, total_pages + globals.pageno_correct - 1);
02220 
02221     if (act == FILE_PRINT && print_shell == NULL) {
02222        curr_info->print_radio = resource.default_printing_target;
02223        print_shell = create_print_or_save_window(info, ofstring);
02224 #ifdef MOTIF
02225        set_sensitivity(resource.default_printing_target);
02226 #endif
02227     }
02228     else if (act == FILE_SAVE && save_shell == NULL)
02229        save_shell = create_print_or_save_window(info, ofstring);
02230     else { /* if the window was already created */
02231 #ifdef MOTIF
02232        XmString str;
02233 #endif
02234        /* XXX: is this actually needed??? */
02235        /* XXX: To test, remove the following */
02236        if (!pageinfo_have_marked_pages()) {
02237            if (act == FILE_PRINT && save_pr_info.range_radio == PRINT_MARKED) {
02238               save_pr_info.range_radio = PRINT_ALL;
02239            }
02240            else if (act == FILE_SAVE && save_save_info.range_radio == SAVE_MARKED) {
02241               save_save_info.range_radio = SAVE_ALL;
02242            }
02243        }
02244        
02245        if (act == FILE_PRINT)
02246            set_target_radio(save_info, curr_info, act);
02247        set_range_radio(save_info, curr_info, act);
02248 #ifdef MOTIF
02249        str = XmStringCreateLocalized(ofstring);
02250        XtVaSetValues(of_label[act], XmNlabelString, str, NULL);
02251        XmStringFree(str);
02252 
02253        /* FIXME: this seems neccessary, otherwise labels are misaligned
02254           again if window is closed and opened a second time? */
02255        adjust_heights(range_from_to_radio[act],
02256                      from_label[act], page_from_text[act],
02257                      to_label[act], page_to_text[act],
02258                      of_label[act],
02259                      NULL);
02260        
02261        if (save_info->dvips_options != NULL) {
02262            XtVaSetValues(dvips_options_text[act], XmNvalue, save_info->dvips_options,
02263                        XmNcursorPosition, strlen(save_info->dvips_options), NULL);
02264        }
02265        else {
02266            XtVaSetValues(dvips_options_text[act], XmNvalue, "", NULL);
02267        }
02268 #else /* MOTIF */
02269        XtVaSetValues(of_label[act], XtNlabel, ofstring, NULL);
02270            
02271        if (save_info->dvips_options != NULL) {
02272            XtVaSetValues(dvips_options_text[act], XtNstring, save_info->dvips_options, NULL);
02273            XawTextSetInsertionPoint(dvips_options_text[act], strlen(save_info->dvips_options));
02274        }
02275        else {
02276            XtVaSetValues(dvips_options_text[act], XtNstring, "", NULL);
02277        }
02278 #endif /* MOTIF */
02279     }
02280 
02281     get_initial_dialog_values(save_info, act);
02282     
02283 #ifdef MOTIF
02284     if (act == FILE_PRINT)
02285        XtVaSetValues(print_to_printer_text, XmNvalue, save_info->printer_name,
02286                     XmNcursorPosition, strlen(save_info->printer_name), NULL);
02287 
02288     XtVaSetValues(dvips_options_text[act], XmNvalue, save_info->dvips_options,
02289                 XmNcursorPosition, strlen(save_info->dvips_options), NULL);
02290 
02291     XtVaSetValues(page_from_text[act], XmNvalue, save_info->from_page,
02292                 XmNcursorPosition, strlen(save_info->from_page), NULL);
02293 
02294     XtVaSetValues(page_to_text[act], XmNvalue, save_info->to_page,
02295                 XmNcursorPosition, strlen(save_info->to_page),  NULL);
02296 #else /* MOTIF */
02297     if (act == FILE_PRINT) {
02298        XtVaSetValues(print_to_printer_text, XtNstring, save_info->printer_name, NULL);
02299        XawTextSetInsertionPoint(print_to_printer_text, strlen(save_info->printer_name));
02300     }
02301 
02302     XtVaSetValues(dvips_options_text[act], XtNstring, save_info->dvips_options, NULL);
02303     XawTextSetInsertionPoint(dvips_options_text[act], strlen(save_info->dvips_options));
02304         
02305     XtVaSetValues(page_from_text[act], XtNstring, save_info->from_page, NULL);
02306     XawTextSetInsertionPoint(page_from_text[act], strlen(save_info->from_page));
02307 
02308     XtVaSetValues(page_to_text[act], XtNstring, save_info->to_page, NULL);
02309     XawTextSetInsertionPoint(page_to_text[act], strlen(save_info->to_page));
02310 #endif /* MOTIF */
02311 
02312     if (act == FILE_PRINT) {
02313        if (pageinfo_have_marked_pages()) {
02314            XtSetSensitive(range_marked_radio[FILE_PRINT], True);
02315        }
02316        else {
02317            XtSetSensitive(range_marked_radio[FILE_PRINT], False);
02318        }
02319        ASSERT(save_pr_info.range_radio != PRINT_MARKED || pageinfo_have_marked_pages(),
02320               "PRINT_MARKED shouldn't be togglable if there are no marked pages!");
02321     }
02322     else if (act == FILE_SAVE) {
02323        if (pageinfo_have_marked_pages()) {
02324            XtSetSensitive(range_marked_radio[FILE_SAVE], True);
02325        }
02326        else {
02327            XtSetSensitive(range_marked_radio[FILE_SAVE], False);
02328        }
02329        ASSERT(save_save_info.range_radio != SAVE_MARKED || pageinfo_have_marked_pages(),
02330               "SAVE_MARKED shouldn't be togglable if there are no marked pages!");
02331     }
02332 
02333     set_outfile_name(save_info, &curr_save_info, act);
02334 
02335 #ifdef MOTIF
02336     XtVaSetValues(print_to_file_text[act], XmNvalue, save_info->file_name,
02337                 XmNcursorPosition, strlen(save_info->file_name), NULL);
02338 #else /* MOTIF */
02339     XtVaSetValues(print_to_file_text[act], XtNstring, save_info->file_name, NULL);
02340     XawTextSetInsertionPoint(print_to_file_text[act], strlen(save_info->file_name));
02341 #endif /* MOTIF */
02342 
02343     if (act == FILE_PRINT) {
02344        XtPopup(print_shell, XtGrabNone);
02345        print_is_active = True;
02346     }
02347     else {
02348        XtPopup(save_shell, XtGrabNone);
02349        save_is_active = True;
02350     }
02351 }
02352 
02353 static int
02354 getpageno(Widget w)
02355 {
02356     char *s, *p;
02357     int pageno;
02358 #ifndef MOTIF
02359     XtVaGetValues(w, XtNstring, &s, NULL);
02360 #else /* MOTIF */
02361     s = XmTextFieldGetString(w);
02362 #endif
02363     p = s;
02364     if (*p == '-')
02365        ++p;
02366     if (!isdigit((int)*p)) {
02367        return 0;
02368     }
02369     do {
02370        ++p;
02371     } while (isdigit((int)*p));
02372     if (*p != '\0')
02373        return 0;
02374 
02375     pageno = atoi(s) - globals.pageno_correct;
02376 #ifdef MOTIF
02377     XtFree(s);
02378 #endif
02379     return pageno;
02380 }
02381 
02382 
02383 /*
02384   return text value of Widget w in newly allocated memory,
02385   free()ing old_val as appropriate. Returns NULL if
02386   text value starts with '\0'.
02387 */
02388 static char *
02389 get_saved_command(char **old_val, Widget w)
02390 {
02391     char *val = NULL;
02392     
02393     if (*old_val != NULL) {
02394 #if MOTIF
02395        XtFree((char *)*old_val);
02396 #else
02397        free((char*)*old_val);
02398 #endif
02399        *old_val = NULL;
02400     }
02401 #if MOTIF
02402     val = XmTextFieldGetString(w);
02403     if (*val == '\0') {
02404        XtFree((char *)val);
02405        val = NULL;
02406     }
02407 #else
02408     XtVaGetValues(w, XtNstring, &val, NULL);
02409     if (*val == '\0') {
02410        val = NULL;
02411     }
02412     else {
02413        val = xstrdup(val);
02414     }
02415 #endif
02416     return val;
02417 }
02418 
02419 /* fill curr_print_info and save_print_info with current values */
02420 static void
02421 get_save_window_state(struct dialog_info *save_info, struct dialog_info *curr_info, printOrSaveActionT act)
02422 {
02423     save_info->print_radio = curr_info->print_radio;
02424     save_info->range_radio = curr_info->range_radio;
02425 
02426     if (act == FILE_PRINT) {
02427        save_info->printer_name = get_saved_command(&(save_info->printer_name), print_to_printer_text);
02428        curr_info->printer_name = get_saved_command(&(curr_info->printer_name), print_to_printer_text);
02429     }
02430     save_info->file_name = get_saved_command(&(save_info->file_name), print_to_file_text[act]);
02431     curr_info->file_name = get_saved_command(&(curr_info->file_name), print_to_file_text[act]);
02432 
02433     save_info->dvips_options = get_saved_command(&(save_info->dvips_options), dvips_options_text[act]);
02434     curr_info->dvips_options = get_saved_command(&(curr_info->dvips_options), dvips_options_text[act]);
02435 
02436     save_info->from_page = get_saved_command(&(save_info->from_page), page_from_text[act]);
02437     save_info->to_page = get_saved_command(&(save_info->to_page), page_to_text[act]);
02438     
02439     TRACE_GUI((stderr, "saved options:\nprinter: |%s|, file: |%s|, dvips: |%s|, from: |%s|, to: |%s|\n",
02440               save_info->printer_name ? save_info->printer_name : "<NULL>", 
02441               save_info->file_name ? save_info->file_name : "<NULL>",
02442               save_info->dvips_options ? save_info->dvips_options : "<NULL>",
02443               save_info->from_page ? save_info->from_page : "<NULL>",
02444               save_info->to_page ? save_info->to_page : "<NULL>"));
02445 }
02446 
02447 static void
02448 popdown_dialog_and_print_or_save(XtPointer myinfo)
02449 {
02450     struct save_or_print_info *info = (struct save_or_print_info *)myinfo;
02451     struct select_pages_info *pinfo = (struct select_pages_info *)info->pinfo;
02452     struct dialog_info *curr_info = NULL;
02453     
02454     /* pop down the dialog */
02455     if (pinfo->act == FILE_PRINT) {
02456        curr_info = &save_pr_info;
02457        cb_print_cancel(NULL, info, NULL);
02458        /* when printing to file, set ps_out.fname to non-NULL; this will
02459           notify called routines that printing should go to the file */
02460        if (curr_info->print_radio == PRINT_TO_FILE) {
02461            pinfo->finfo->ps_out.fname = xstrdup(curr_info->expanded_filename);
02462        }
02463     }
02464     else {
02465        curr_info = &save_save_info;
02466        cb_save_cancel(NULL, info, NULL);
02467     }
02468     
02469     if (globals.dvi_file.bak_fp == NULL) { /* shouldn't happen */
02470        info->message_popup = popup_message(globals.widgets.top_level,
02471                                        MSG_ERR, NULL,
02472                                        "No active DVI file");
02473        return;
02474     }
02475 
02476     ASSERT(pinfo->finfo->dvi_in.fp != NULL, "DVI input FILE * must have been set!");
02477 
02478     /* when saving, set the final file names */
02479     if (curr_info->range_radio == SAVE_RANGE
02480        || curr_info->range_radio == SAVE_MARKED
02481        || curr_info->range_radio == SAVE_ALL) {
02482        switch (curr_info->output_format) {
02483        case FMT_DVI:
02484            pinfo->finfo->dvi_out.fname = xstrdup(curr_info->expanded_filename);
02485            TRACE_GUI((stderr, "DVI out_name: |%s|", pinfo->finfo->dvi_out.fname));
02486            break;
02487        case FMT_PS:
02488            pinfo->finfo->ps_out.fname = xstrdup(curr_info->expanded_filename);
02489            TRACE_GUI((stderr, "PS out_name: |%s|", pinfo->finfo->ps_out.fname));
02490            break;
02491        case FMT_PS2PDF:
02492            pinfo->finfo->pdf_out.fname = xstrdup(curr_info->expanded_filename);
02493            TRACE_GUI((stderr, "PDF out_name: |%s|", pinfo->finfo->pdf_out.fname));
02494            break;
02495        case FMT_ISO_8859_1:
02496        case FMT_UTF8:
02497            pinfo->finfo->txt_out.fname = xstrdup(curr_info->expanded_filename);
02498            TRACE_GUI((stderr, "TXT out_name: |%s|", pinfo->finfo->txt_out.fname));
02499            break;
02500        case FMT_NONE:
02501            break;
02502        }
02503     }
02504     
02505     /* add info about page ranges */
02506     switch (curr_info->range_radio) {
02507     case SAVE_RANGE:
02508     case PRINT_RANGE:
02509        /* convert from 1-based to 0-based */
02510        pinfo->from = strtoul(curr_info->from_page, (char **)NULL, 10) - 1;
02511        pinfo->to = strtoul(curr_info->to_page, (char **)NULL, 10) - 1;
02512        pinfo->callback = check_pagerange;
02513        break;
02514     case SAVE_MARKED:
02515     case PRINT_MARKED:
02516        pinfo->callback = check_marked;
02517        break;
02518     case SAVE_ALL:
02519     case PRINT_ALL:
02520        pinfo->callback = NULL;
02521        break;
02522     case NO_PAGE_VAL:
02523        ASSERT(0, "Shouldn't happen: NO_PAGE_VAL passed to popdown_dialog_and_print_or_save()");
02524        break;
02525     }
02526 
02527     store_preference(NULL, "dvipsOptionsString", "%s", save_pr_info.dvips_options ? save_pr_info.dvips_options : "");
02528     if (pinfo->act == FILE_PRINT) {
02529        store_preference(NULL, "defaultPrintingTarget", "%d", save_pr_info.print_radio);
02530        store_preference(NULL, "dvipsPrinterString", "%s", save_pr_info.printer_name ? save_pr_info.printer_name : "");
02531        internal_print(pinfo);
02532     }
02533     else {
02534        store_preference(NULL, "defaultSavingFormat", "%d", save_save_info.output_format);
02535        internal_save(pinfo, curr_info->output_format);
02536     }
02537 }
02538 
02539 /* Clean up after user has aborted printing/saving */
02540 static void
02541 do_cleanup(XtPointer arg)
02542 {
02543     struct save_or_print_info *info = (struct save_or_print_info *)arg;
02544     struct select_pages_info *pinfo = (struct select_pages_info *)info->pinfo;
02545     struct file_info *finfo = pinfo->finfo;
02546 
02547     cancel_saving(info);
02548     unlink(finfo->dvi_tmp.fname);
02549 }
02550 
02551 /* XXX: is the save_* stuff actually *needed*??? */
02552 static Boolean
02553 validate_and_save_values(struct save_or_print_info *info)
02554 {
02555     int page_range_begin, page_range_end;
02556     printOrSaveActionT act = info->act;
02557     
02558     if ((act == FILE_PRINT && curr_pr_info.range_radio == PRINT_RANGE)
02559        || (act == FILE_SAVE && curr_save_info.range_radio == SAVE_RANGE)) {
02560               page_range_begin = getpageno(page_from_text[act]);
02561        page_range_end = getpageno(page_to_text[act]);
02562        if (page_range_begin + 1 < 1) {
02563            info->message_popup =
02564               popup_message(act == FILE_PRINT ? print_shell : save_shell,
02565                            MSG_ERR,
02566                            "Please specify a valid page range.",
02567                            "Invalid page range: start (%d) < 1.",
02568                            page_range_begin + 1);
02569            return False;
02570        }
02571        else if (page_range_begin > page_range_end) {
02572            info->message_popup =
02573               popup_message(act == FILE_PRINT ? print_shell : save_shell,
02574                            MSG_ERR,
02575                            "Please specify a valid page range.",
02576                            "Invalid page range: start (%d) > end (%d).",
02577                            page_range_begin + 1, page_range_end + 1);
02578            return False;
02579        }
02580        else if (page_range_end + 1 > total_pages) {
02581            info->message_popup =
02582               popup_message(act == FILE_PRINT ? print_shell : save_shell,
02583                            MSG_ERR,
02584                            "Please specify a valid page range.",
02585                            "Invalid page range: end (%d) > total_pages (%d).",
02586                            page_range_end + 1, total_pages);
02587            return False;
02588        }
02589 
02590        if (act == FILE_PRINT) {
02591            curr_pr_info.from_page = xrealloc(curr_pr_info.from_page, LENGTH_OF_INT + 1);
02592            curr_pr_info.to_page = xrealloc(curr_pr_info.to_page, LENGTH_OF_INT + 1);
02593            sprintf(curr_pr_info.from_page, "%d", page_range_begin);
02594            sprintf(curr_pr_info.to_page, "%d", page_range_end);
02595        }
02596        else {
02597            curr_save_info.from_page = xrealloc(curr_save_info.from_page, LENGTH_OF_INT + 1);
02598            curr_save_info.to_page = xrealloc(curr_save_info.to_page, LENGTH_OF_INT + 1);
02599            sprintf(curr_save_info.from_page, "%d", page_range_begin);
02600            sprintf(curr_save_info.to_page, "%d", page_range_end);
02601        }
02602     }
02603     
02604     if (act == FILE_PRINT)
02605        get_save_window_state(&save_pr_info, &curr_pr_info, act);
02606     else
02607        get_save_window_state(&save_save_info, &curr_save_info, act);
02608 
02609     return True;
02610 }
02611 
02612 /*
02613  * Routines for freeing allocated resources in file_info:
02614  * close file pointers, and free file name memory.
02615  */
02616 static void
02617 free_file_info(struct file_IO *info)
02618 {
02619     if (info->fp != NULL) {
02620        fclose(info->fp);
02621        info->fp = NULL;
02622     }
02623     free(info->fname);
02624     info->fname = NULL;
02625 }
02626 
02627 static void
02628 reset_file_info(struct file_info *finfo)
02629 {
02630     free_file_info(&(finfo->dvi_in));
02631     free_file_info(&(finfo->dvi_tmp));
02632     free_file_info(&(finfo->dvi_out));
02633     free_file_info(&(finfo->ps_out));
02634     free_file_info(&(finfo->pdf_out));
02635     free_file_info(&(finfo->txt_out));
02636 }
02637 
02638 /*
02639   First round of sanity checks. Note the use of curr_pr_info here;
02640   this is before the values are saved to save_pr_info.
02641 */
02642 static void
02643 print_precheck1(XtPointer myinfo)
02644 {
02645     /* Initialize structures with defaults. Note: structures are
02646        static, so that they survive between calls, and to make memory
02647        management with callbacks (and all the stuff in print-internal.c)
02648        easier.
02649     */
02650     struct save_or_print_info *info = (struct save_or_print_info *)myinfo;
02651     printOrSaveActionT act = info->act;
02652     static struct select_pages_info pinfo = {
02653        FILE_ALL, 0, 0, NULL, check_marked, { 0, NULL }, NO_ERROR
02654     };
02655     static struct file_info finfo = {
02656        { NULL, NULL },
02657        { NULL, NULL },
02658        { NULL, NULL },
02659        { NULL, NULL },
02660        { NULL, NULL },
02661        { NULL, NULL }
02662     };
02663     char *ok_button_str = NULL;
02664     FILE *fin = NULL;
02665 
02666     /* Return if there are active popups; otherwise, the print process
02667        may get messed up */
02668     if (raise_message_windows()) {
02669        XBell(DISP, 0);
02670 /*     popup_message(pinfo.act == FILE_PRINT ? print_shell : save_shell, */
02671 /*                  MSG_WARN, NULL, */
02672 /*                  "Please close other open message windows first!"); */
02673        return;
02674     }
02675 
02676     /* free all pointers in case we've been called again */
02677     reset_file_info(&finfo);
02678 
02679     pinfo.finfo= &finfo; /* pass finfo in data field of pinfo to callbacks etc. */
02680     pinfo.act = act;
02681     info->pinfo = &pinfo;
02682     
02683     /* Validate page ranges, and if they are correct, save them to the
02684      * appropriate save_save_info/save_print_info structure.
02685      * NOTE: From here on, always use the save_* variants to retrieve values!
02686      */
02687     if (!validate_and_save_values(info))
02688        return;
02689     
02690     /* We need to create a temporary DVI file containing the selected or all pages
02691        if we want to do one of the following:
02692        - print the marked pages
02693        - save to a DVI file
02694        - print only the marked pages to a PS or a PDF file.
02695      */
02696     if ((pinfo.act == FILE_PRINT && curr_pr_info.range_radio == PRINT_MARKED)
02697        || (pinfo.act == FILE_SAVE
02698            && (save_save_info.output_format == FMT_DVI
02699               || ((save_save_info.output_format == FMT_PS || save_save_info.output_format == FMT_PS2PDF)
02700                   && save_save_info.range_radio == SAVE_MARKED)))) {
02701        /* need to create a temporary DVI file containing the selected pages */
02702        int tmp_fd = xdvi_temp_fd(&(finfo.dvi_tmp.fname)); /* this allocates finfo.dvi_tmp.fname */
02703 
02704        if (tmp_fd == -1) {
02705            info->message_popup =
02706               popup_message(pinfo.act == FILE_PRINT ? print_shell : save_shell,
02707                            MSG_ERR, NULL,
02708                            "Couldn't create temporary DVI file for printing: %s", strerror(errno));
02709            return;
02710        }
02711        /* don't use XFOPEN here, since we don't want to treat an error in opening the file as fatal. */
02712        /* `b' in mode won't hurt ... */
02713        if ((finfo.dvi_tmp.fp = try_fdopen(tmp_fd, "wb+")) == NULL) { /* failure */
02714            info->message_popup =
02715               popup_message(pinfo.act == FILE_PRINT ? print_shell : save_shell,
02716                            MSG_ERR,
02717                            "Xdvi needs to create a temporary file containing the "
02718                            "currently marked pages, but creating that file failed. "
02719                            "Try to fix the cause of the problem, or choose "
02720                            "\"Print selected pages\" as a workaround.",
02721                            "Could not open temp file for writing: %s.\n",
02722                            strerror(errno));
02723            return;
02724        }
02725     }
02726     /* We try to use the original DVI file unless it's corrupted, in which case
02727        we ask the user if they want to save the cached copy instead */
02728     if ((fin = fopen(globals.dvi_name, "rb")) == NULL
02729        || !find_postamble(fin, &(pinfo.errflag))) {
02730        Boolean could_not_open = False;
02731        if (fin == NULL)
02732            could_not_open = True;
02733        if (fin)
02734            fclose(fin);
02735        
02736        /* if we can't use the temporary file as source for our copy, this is a fatal error */
02737        if (!resource.use_temp_fp) {
02738            info->message_popup =
02739               popup_message(pinfo.act == FILE_PRINT ? print_shell : save_shell,
02740                            MSG_ERR, NULL,
02741                            "Could not copy DVI file %s: The file %s",
02742                            globals.dvi_name, could_not_open ? "doesn't exist any more" : "seems to be corrupted");
02743            return;
02744        }
02745        
02746        /* else, we'll try to use the cached copy of the DVI file */
02747        if ((fin = fopen(get_tmp_dvi_name(), "rb")) == NULL) {
02748            info->message_popup =
02749               popup_message(pinfo.act == FILE_PRINT ? print_shell : save_shell,
02750                            MSG_ERR, NULL,
02751                            "Something's very wrong here - opening of both the "
02752                            "original DVI file and the cached copy failed!");
02753            return;
02754        }
02755        
02756        if (!find_postamble(fin, &(pinfo.errflag))) {
02757            info->message_popup =
02758               popup_message(pinfo.act == FILE_PRINT ? print_shell : save_shell,
02759                            MSG_ERR, NULL,
02760                            "Shouldn't happen: Cached copy of the DVI file seems corrupted!");
02761            return;
02762        }
02763        finfo.dvi_in.fp = fin;
02764        
02765        /* tell user about it */
02766        if (pinfo.act == FILE_PRINT)
02767            ok_button_str = "Print Copy";
02768        else
02769            ok_button_str = "Save Copy";
02770        
02771        info->message_popup =
02772            choice_dialog(pinfo.act == FILE_PRINT ? print_shell : save_shell,
02773                        MSG_QUESTION, NULL,
02774 #ifndef MOTIF
02775                        NULL, /* TODO: binding for RET? */
02776 #endif /* MOTIF */
02777                        NULL, NULL, /* no pre_callbacks */
02778                        ok_button_str, print_precheck2, (XtPointer)info,
02779                        "Cancel", do_cleanup, (XtPointer)info,
02780                        "The DVI file %s %s. Do you want to %s a cached copy of the file?",
02781                        globals.dvi_name,
02782                        could_not_open ? "doesn't exist any more" : "seems to be corrupted",
02783                        pinfo.act == FILE_PRINT ? "print" : "save");
02784     }
02785     else { /* original DVI file is OK, copy it */
02786        finfo.dvi_in.fp = fin;
02787        print_precheck2((XtPointer)info);
02788     }
02789 }
02790 
02791 static void
02792 print_precheck2(XtPointer myinfo)
02793 {
02794     struct save_or_print_info *info = (struct save_or_print_info *)myinfo;
02795     char *expanded_filename = NULL;
02796     struct select_pages_info *pinfo = (struct select_pages_info *)info->pinfo;
02797     printOrSaveActionT act = pinfo->act;
02798     const char *fname;
02799     
02800     /* Return if there are active popups; otherwise, the print process
02801        will be messed up. */
02802     if (raise_message_windows()) {
02803        XBell(DISP, 0);
02804        return;
02805     }
02806 
02807     /* expand and canonicalize path name */
02808     if (act == FILE_PRINT)
02809        fname = save_pr_info.file_name;
02810     else
02811        fname = save_save_info.file_name;
02812 
02813     if (fname == NULL) {
02814        info->message_popup =
02815            popup_message(act == FILE_PRINT ? print_shell : save_shell,
02816                        MSG_WARN,
02817                        NULL,
02818                        "No filename specified!");
02819        return;
02820     }
02821     expanded_filename = expand_homedir(fname); /* this allocates expanded_filename */
02822     if (expanded_filename == NULL) {
02823        info->message_popup =
02824            popup_message(act == FILE_PRINT ? print_shell : save_shell,
02825                        MSG_WARN,
02826                        "Please specify either a filename or a full path, without using \"~\" or \"~user\".",
02827                        "Couldn't expand filename \"%s\" to a full path.",
02828                        fname);
02829        return;
02830     }
02831     
02832     if (act == FILE_PRINT) {
02833        free(save_pr_info.expanded_filename);
02834        save_pr_info.expanded_filename = expanded_filename;
02835     }
02836     else {
02837        free(save_save_info.expanded_filename);
02838        save_save_info.expanded_filename = expanded_filename;
02839     }
02840     
02841 
02842     if (act == FILE_SAVE && save_save_info.output_format == FMT_DVI) { /* canonicalize filename */
02843        char *tmp = expand_filename_append_dvi(save_save_info.expanded_filename, USE_CWD_PATH, False);
02844        if (strcmp(tmp, globals.dvi_name) == 0) {
02845            info->message_popup =
02846               popup_message(act == FILE_PRINT ? print_shell : save_shell,
02847                            MSG_ERR,
02848                            NULL,
02849                            "Cannot overwrite the current DVI file (%s). "
02850                            "Please select a different file name.",
02851                            save_save_info.expanded_filename);
02852            free(tmp);
02853            return;
02854        }
02855        free(save_save_info.expanded_filename);
02856        save_save_info.expanded_filename = tmp;
02857     }
02858     if (act == FILE_SAVE || (act == FILE_PRINT && curr_pr_info.print_radio == PRINT_TO_FILE)) {
02859        /* check whether to clobber existing file */
02860        struct stat statbuf;
02861 
02862        if ((act == FILE_SAVE
02863             && stat(save_save_info.expanded_filename, &statbuf) == 0
02864             && S_ISREG(statbuf.st_mode))
02865            || (act == FILE_PRINT
02866               && stat(save_pr_info.expanded_filename, &statbuf) == 0
02867               && S_ISREG(statbuf.st_mode))) {
02868 
02869            info->message_popup =
02870               choice_dialog(act == FILE_PRINT ? print_shell : save_shell,
02871                            MSG_QUESTION, NULL,
02872 #ifndef MOTIF
02873                            NULL, /* TODO: binding for RET */
02874 #endif
02875                            NULL, NULL, /* no pre_callbacks */
02876                            "Replace", popdown_dialog_and_print_or_save, (XtPointer)info,
02877                            /*
02878                             do nothing if user selects `cancel'; this will return to the
02879                             printing dialog, since user hasn't changed their mind about
02880                             printing, but would probably just like to choose another filename
02881                            */
02882                            "Cancel", NULL, (XtPointer)NULL,
02883                            "%s already exists.\nDo you want to replace it?",
02884                            act == FILE_SAVE
02885                            ? save_save_info.expanded_filename
02886                            : save_pr_info.expanded_filename);
02887            return;
02888        }
02889        else {
02890            popdown_dialog_and_print_or_save(info);
02891        }
02892     }
02893     else {
02894        popdown_dialog_and_print_or_save(info);
02895     }
02896 }
02897 
02898 /* called from pagesel.c if user marks or unmarks a page in the page list */
02899 void
02900 notify_print_dialog_have_marked(Boolean flag)
02901 {
02902     /* Note: check for *both* windows, save and print: */
02903 
02904     static pageRadioT old_value = NO_PAGE_VAL;
02905     
02906     if (save_is_active) {
02907        if (!flag && curr_save_info.range_radio == SAVE_MARKED) {
02908            /* switch button from `marked' to its previous value */
02909            switch (old_value) {
02910            case SAVE_ALL:
02911 #ifdef MOTIF
02912               XmToggleButtonGadgetSetState(range_all_radio[FILE_SAVE], True, True);
02913 #else
02914               XawToggleSetCurrent(range_all_radio[FILE_SAVE], (XtPointer)old_value);
02915 #endif
02916               break;
02917            case SAVE_RANGE:
02918 #ifdef MOTIF
02919               XmToggleButtonGadgetSetState(range_from_to_radio[FILE_SAVE], True, True);
02920 #else
02921               XawToggleSetCurrent(range_from_to_radio[FILE_SAVE], (XtPointer)old_value);
02922 #endif
02923               break;
02924            default: break;
02925            }
02926        }
02927        else if (flag) {
02928            /* switch button to `marked', saving the current value */
02929            if (curr_save_info.range_radio != SAVE_MARKED) /* guard for second invocation on mouse release */
02930               old_value = curr_save_info.range_radio;
02931 #ifdef MOTIF
02932            XmToggleButtonGadgetSetState(range_marked_radio[FILE_SAVE], True, True);
02933 #else
02934            XawToggleSetCurrent(range_marked_radio[FILE_SAVE], (XtPointer)SAVE_MARKED);
02935 #endif /* MOTIF */
02936        }
02937        XtSetSensitive(range_marked_radio[FILE_SAVE], flag);
02938     }
02939     
02940     if (print_is_active) {
02941        if (!flag && curr_pr_info.range_radio == PRINT_MARKED) {
02942            /* switch button from `marked' to its previous value */
02943            switch (old_value) {
02944            case PRINT_ALL:
02945 #ifdef MOTIF
02946               XmToggleButtonGadgetSetState(range_all_radio[FILE_PRINT], True, True);
02947 #else
02948               XawToggleSetCurrent(range_all_radio[FILE_PRINT], (XtPointer)old_value);
02949 #endif
02950               break;
02951            case PRINT_RANGE:
02952 #ifdef MOTIF
02953               XmToggleButtonGadgetSetState(range_from_to_radio[FILE_PRINT], True, True);
02954 #else
02955               XawToggleSetCurrent(range_from_to_radio[FILE_PRINT], (XtPointer)old_value);
02956 #endif
02957               break;
02958            default: break;
02959            }
02960        }
02961        else if (flag) {
02962            /* switch button to `marked', saving the current value */
02963            if (curr_pr_info.range_radio != PRINT_MARKED) /* guard for second invocation on mouse release */
02964               old_value = curr_pr_info.range_radio;
02965 #ifdef MOTIF
02966            XmToggleButtonGadgetSetState(range_marked_radio[FILE_PRINT], True, True);
02967 #else
02968            XawToggleSetCurrent(range_marked_radio[FILE_PRINT], (XtPointer)PRINT_MARKED);
02969 #endif /* MOTIF */
02970        }
02971        XtSetSensitive(range_marked_radio[FILE_PRINT], flag);
02972     }
02973 }