/* * Copyright (c) 2002-2004 Paul Vojta and the xdvik development team * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* SU: Adapted from non-k xdvi's popups.c and added saving functionality. */ #include #include "xdvi-config.h" #include "xdvi.h" #include "my-vsnprintf.h" #include #include "print-dialog.h" #include "print-internal.h" #include "print-log.h" #include "print-internal.h" #include "events.h" #include "dvi-init.h" #include "string-utils.h" #include "util.h" #include "x_util.h" #include "message-window.h" #include "pagesel.h" #include "my-snprintf.h" #include "sfSelFile.h" #include "dvisel.h" /* for select_marked_pages() */ #include "xlwradio.h" #include "statusline.h" #include "search-dialog.h" #include "search-internal.h" #include "special.h" /* Xlib and Xutil are already included */ #include #include #ifdef MOTIF # include # include # include # include # include # include # include # include # include # include # include # include # include #define XTranslations XmNtranslations #else /* MOTIF */ # include # include # include # include # include # include # include # include # include # include # include # include #if 0 #include "xaw_bitmaps.h" static Pixmap menu_double_arrow_bitmap; #endif #define XTranslations XtNtranslations #endif /* MOTIF */ struct output_format_mapping { const char *fmt_string; outputFormatT fmt; const char *extension; } output_format_mapping[] = { { "Postscript", FMT_PS , ".ps" }, { "PDF", FMT_PS2PDF, ".pdf" }, { "DVI", FMT_DVI, ".dvi" }, { "Plain Text (ISO_8859-1)",FMT_ISO_8859_1, ".txt" }, { "Plain Text (UTF-8)", FMT_UTF8, ".txt" }, { NULL, FMT_NONE, NULL } }; /* Widget names that are used in callbacks ... */ #define Xdvi_SAVE_SHELL_NAME "save_popup" #define Xdvi_PRINT_SHELL_NAME "print_popup" #define Xdvi_PAGE_RANGE_FORM_NAME "page_range_form" #define Xdvi_PAGES_ALL_RADIO_NAME "pages_all" #define Xdvi_PAGES_MARKED_RADIO_NAME "pages_marked" #define Xdvi_PAGES_RANGE_RADIO_NAME "pages_range" #define Xdvi_PAGES_RANGE_FROM_LABEL_NAME "range_from_lab" #define Xdvi_PAGES_RANGE_FROM_TEXT_NAME "range_from_text" #define Xdvi_PAGES_RANGE_TO_LABEL_NAME "range_to_lab" #define Xdvi_PAGES_RANGE_TO_TEXT_NAME "range_to_text" #define Xdvi_PAGES_RANGE_OF_LABEL_NAME "range_of_lab" #define Xdvi_TO_PRINTER_NAME "to_printer" #define Xdvi_TO_PRINTER_TEXT "printer_text" #define Xdvi_TO_FILE_NAME "to_file" #define Xdvi_TO_FILE_TEXT "file_text" #define Xdvi_BROWSE_BUTTON "file_button" #define Xdvi_DVIPS_OPTIONS_NAME "dvips_options_name" #define Xdvi_DVIPS_OPTIONS_TEXT "dvips_options_text" #define Xdvi_FORMAT_SELECTION_BUTTON_NAME "format_selection_button" /* number of items in `format' pulldown menu */ #define FORMAT_SEL_CNT 5 static void print_check_page_values(struct save_or_print_info *info); static void print_check_dvi_file(struct save_or_print_info *info); static void print_check_target_file(XtPointer info); #ifndef MOTIF static void xaw_print_save_act_go(Widget, XEvent *, String *, Cardinal *); #endif /* not MOTIF */ static void wm_cancel(Widget, XEvent *, String *, Cardinal *); static XtActionsRec print_actions[] = { #ifndef MOTIF {"xaw_print_or_save", xaw_print_save_act_go }, #endif {"WM_cancel", wm_cancel }, }; /* ============================================================ generic utility functions ============================================================ */ /* return basename of `old_name' with `old_ext' replaced by `new_ext', in fresh memory */ static char * get_new_file_name(const char *old_name, const char *old_ext, const char *new_ext) { /* old_name contains the normalized DVI file name, with path and extension */ char *basename, *new_name; size_t len; basename = strrchr(old_name, DIR_SEPARATOR); if (basename != NULL) { basename++; new_name = xmalloc(strlen(basename) + strlen(new_ext) + 1); new_name = strcpy(new_name, basename); } else { new_name = xmalloc(strlen(old_name) + strlen(new_ext) + 1); new_name = strcpy(new_name, old_name); } len = strlen(new_name); if (old_ext == NULL) { strcpy(new_name + len, new_ext); } else { strcpy(new_name + len - strlen(old_ext), new_ext); } return new_name; } /* * Translate `non-standard' paper sizes for xdvi into options suitable * for dvips. We don't do this always, since it would override the papersize * specials inserted by e.g. * \usepackage[dvips]{geometry} * which is the preferred way to specify the papersize. If the papersize * has been explicitly set by such a special, this function returns NULL. * Else it returns the value of the `paper' resource, without the trailing * `r', and sets the `landscape' argument to True if a trailing `r' was * present. * * Note that we don't check/warn about whether the current paper * resource is valid for dvips; dvips will ignore invalid paper sizes. */ static char * get_dvips_papersize(Boolean *landscape) { char *papersize; if (have_papersize_special()) return NULL; papersize = xstrdup(resource.paper); /* fprintf(stderr, "PAPERSIZE: |%s|\n", papersize); */ *landscape = False; if (papersize[strlen(papersize) - 1] == 'r') { /* landscape size */ papersize[strlen(papersize) - 1] = '\0'; *landscape = True; } TRACE_GUI((stderr, "Using dvips arguments: `%s', %s", papersize, *landscape ? "landscape" : "portrait")); return papersize; } static void update_dvips_options_sensitivity(int idx, Widget top) { Widget dvips_label; #if MOTIF Widget dvips_options; if (get_widget_by_name(&dvips_label, top, Xdvi_DVIPS_OPTIONS_NAME, True) && get_widget_by_name(&dvips_options, top, Xdvi_DVIPS_OPTIONS_TEXT, True)) { if (output_format_mapping[idx].fmt == FMT_PS || output_format_mapping[idx].fmt == FMT_PS2PDF) { XtSetSensitive(dvips_label, True); XtSetSensitive(dvips_options, True); } else { XtSetSensitive(dvips_label, False); XtSetSensitive(dvips_options, False); } } #else if (get_widget_by_name(&dvips_label, top, Xdvi_DVIPS_OPTIONS_NAME, True)) { XtSetSensitive(XtParent(dvips_label), output_format_mapping[idx].fmt == FMT_PS || output_format_mapping[idx].fmt == FMT_PS2PDF); } #endif } /* callbacks */ static void cb_select_format(Widget w, XtPointer client_data, XtPointer call_data) { struct save_or_print_info *info = NULL; Widget file_text; char *filename; int i = 0; #ifndef MOTIF Widget button; char *old_label, *new_label; char tmp_label[1024]; #endif UNUSED(call_data); #ifdef MOTIF i = (int)client_data; XtVaGetValues(XtParent(w), XmNuserData, &info, NULL); ASSERT(info != NULL, "Expected struct save_or_print_info * in XmNuserData of button!"); if (get_widget_by_name(&file_text, info->shell, Xdvi_TO_FILE_TEXT, True)) { XtVaGetValues(file_text, XmNvalue, &filename, NULL); if (strrchr(filename, '.') != NULL) { char buf[1024]; replace_extension(filename, output_format_mapping[i].extension, buf, sizeof buf); XtVaSetValues(file_text, XmNvalue, buf, XmNcursorPosition, strlen(buf), NULL); } } #else /* MOTIF */ info = (struct save_or_print_info *)client_data; if (get_widget_by_name(&file_text, info->shell, Xdvi_TO_FILE_TEXT, True) && get_widget_by_name(&button, info->shell, Xdvi_FORMAT_SELECTION_BUTTON_NAME, True)) { XtVaGetValues(file_text, XtNstring, &filename, NULL); /* swap title strings */ XtVaGetValues(button, XtNlabel, &old_label, NULL); XtVaGetValues(w, XtNlabel, &new_label, NULL); strncpy(tmp_label, old_label, sizeof tmp_label); /* update the filename with new format */ for (i = 0; output_format_mapping[i].fmt_string != NULL; i++) { if (strcmp(new_label, output_format_mapping[i].fmt_string) == 0) { char buf[1024]; replace_extension(filename, output_format_mapping[i].extension, buf, sizeof buf); XtVaSetValues(file_text, XtNstring, buf, NULL); XawTextSetInsertionPoint(file_text, strlen(buf)); break; } } /* format not found, complain: */ if (output_format_mapping[i].fmt_string == NULL) { popup_message(info->shell, MSG_WARN, REPORT_XDVI_BUG_TEMPLATE, "Unrecognized string in format selector: |%s|", new_label); } XtVaSetValues(button, XtNlabel, new_label, NULL); XtVaSetValues(w, XtNlabel, tmp_label, NULL); } #endif /* MOTIF */ update_dvips_options_sensitivity(i, info->shell); info->fmt = resource.default_saving_format = output_format_mapping[i].fmt; } static void cb_popdown(Widget w, XtPointer client_data, XtPointer call_data) { struct save_or_print_info *info = (struct save_or_print_info *)client_data; UNUSED(w); UNUSED(call_data); ASSERT(info != NULL, "client_data in cb_popdown musn't be NULL!"); if (info->message_popup != 0) { kill_message_window(info->message_popup); } /* fprintf(stderr, "Popping down shell: %p\n", (void *)info->shell); */ XtPopdown(info->shell); } static void cb_print_or_save(Widget w, XtPointer client_data, XtPointer call_data) { struct save_or_print_info *info = (struct save_or_print_info *)client_data; UNUSED(w); UNUSED(call_data); print_check_page_values(info); } /* access from outside the module */ void cancel_saving(struct save_or_print_info *info) { cb_popdown(NULL, info, NULL); } static void wm_cancel(Widget w, XEvent *event, String *params, Cardinal *num_params) { struct save_or_print_info *info = NULL; void *ptr; UNUSED(w); UNUSED(event); ASSERT(*num_params > 0, "params in wm_cancel must be > 0!"); ASSERT(*params != NULL, "params in wm_cancel mustn't be NULL!"); TRACE_GUI((stderr, "Pointer string value: |%s|", *params)); sscanf(*params, "%p", &ptr); info = (struct save_or_print_info *)ptr; cb_popdown(NULL, info, NULL); } /* * Callbacks to enable the corresponding radio button if the user clicks on a text field to * edit it. This is more user-friendly than making the text field insensitive * until the radio button has been clicked. There are 2 separate callbacks, one for * printing vs. saving (only used when actually printing), and one for the page range. */ static void text_print_vs_save_callback(Widget widget, XtPointer closure, XEvent *ev, Boolean *cont) { struct save_or_print_info *info = (struct save_or_print_info *)closure; Widget to_printer; /* used to check where we have been called from */ Widget radio_printer, radio_file; UNUSED(ev); UNUSED(cont); if (get_widget_by_name(&to_printer, info->shell, Xdvi_TO_PRINTER_TEXT, True) && get_widget_by_name(&radio_printer, info->shell, Xdvi_TO_PRINTER_NAME, True) && get_widget_by_name(&radio_file, info->shell, Xdvi_TO_FILE_NAME, True)) { #ifdef MOTIF XmToggleButtonGadgetSetState(radio_printer, widget == to_printer, True); XmToggleButtonGadgetSetState(radio_file, widget != to_printer, True); #else XawToggleSetCurrent(radio_printer, widget == to_printer ? cast_int_to_XtPointer(TO_PRINTER) : cast_int_to_XtPointer(TO_FILE)); #endif } } /* This case is slightly simpler, since the callback only needs to enable * the radio button for the page range, never disable it. */ static void text_page_range_callback(Widget widget, XtPointer closure, XEvent *ev, Boolean *cont) { struct save_or_print_info *info = (struct save_or_print_info *)closure; Widget radio_all, radio_selected, radio_range; UNUSED(ev); UNUSED(cont); UNUSED(widget); if (get_widget_by_name(&radio_all, info->shell, Xdvi_PAGES_ALL_RADIO_NAME, True) && get_widget_by_name(&radio_selected, info->shell, Xdvi_PAGES_MARKED_RADIO_NAME, True) && get_widget_by_name(&radio_range, info->shell, Xdvi_PAGES_RANGE_RADIO_NAME, True)) { #ifdef MOTIF XmToggleButtonGadgetSetState(radio_all, False, True); XmToggleButtonGadgetSetState(radio_selected, False, True); XmToggleButtonGadgetSetState(radio_range, True, True); #else XawToggleSetCurrent(radio_all, cast_int_to_XtPointer(PAGE_RANGE)); #endif } } #ifdef MOTIF /* Motif type callbacks for the above. */ static void cb_text_print_vs_save(Widget w, XtPointer client_data, XtPointer call_data) { UNUSED(call_data); /* fprintf(stderr, "************ cb_text_print_vs_save!\n"); */ text_print_vs_save_callback(w, client_data, NULL, NULL); } static void cb_text_page_range(Widget w, XtPointer client_data, XtPointer call_data) { UNUSED(call_data); text_page_range_callback(w, client_data, NULL, NULL); } #else /* MOTIF */ static void xaw_print_save_act_go(Widget w, XEvent *event, String *params, Cardinal *num_params) { struct save_or_print_info *info = NULL; void *ptr; UNUSED(w); UNUSED(event); ASSERT(*num_params > 0, "params in xaw_print_save_act_go must be > 0!"); ASSERT(*params != NULL, "params in xaw_print_save_act_go mustn't be NULL!"); TRACE_GUI((stderr, "Pointer string value: |%s|", *params)); sscanf(*params, "%p", &ptr); info = (struct save_or_print_info *)ptr; print_check_page_values(info); } #endif /* MOTIF */ static void cb_print_vs_save(Widget w, XtPointer client_data, XtPointer call_data) { struct save_or_print_info *info = (struct save_or_print_info *)client_data; Widget radio_printer, radio_file; /* Widget file_button; */ UNUSED(call_data); if (get_widget_by_name(&radio_printer, info->shell, Xdvi_TO_PRINTER_NAME, True) && get_widget_by_name(&radio_file, info->shell, Xdvi_TO_FILE_NAME, True)) { #ifdef MOTIF Widget text; if (radio_printer == w) { XmToggleButtonGadgetSetState(radio_printer, True, False); XmToggleButtonGadgetSetState(radio_file, False, False); if (get_widget_by_name(&text, info->shell, Xdvi_TO_PRINTER_TEXT, True)) XmProcessTraversal(text, XmTRAVERSE_CURRENT); } else { XmToggleButtonGadgetSetState(radio_printer, False, False); XmToggleButtonGadgetSetState(radio_file, True, False); if (get_widget_by_name(&text, info->shell, Xdvi_TO_FILE_TEXT, True)) XmProcessTraversal(text, XmTRAVERSE_CURRENT); } #endif if (radio_printer == w) info->print_target = TO_PRINTER; else info->print_target = TO_FILE; } } static void cb_range(Widget w, XtPointer client_data, XtPointer call_data) { struct save_or_print_info *info = (struct save_or_print_info *)client_data; Widget radio_all, radio_selected, radio_range; UNUSED(call_data); #ifndef MOTIF UNUSED(w); #endif if (get_widget_by_name(&radio_all, info->shell, Xdvi_PAGES_ALL_RADIO_NAME, True) && get_widget_by_name(&radio_selected, info->shell, Xdvi_PAGES_MARKED_RADIO_NAME, True) && get_widget_by_name(&radio_range, info->shell, Xdvi_PAGES_RANGE_RADIO_NAME, True)) { #ifdef MOTIF XmToggleButtonGadgetSetState(radio_all, radio_all == w, False); XmToggleButtonGadgetSetState(radio_selected, radio_selected == w, False); XmToggleButtonGadgetSetState(radio_range, radio_range == w, False); #endif } /* update_page_range_sensitivity(info->shell, radio_range == w); */ } static void set_filename_callback(const char *fname, void *data) { /* fprintf(stderr, "Filename: |%s|; widget: %p\n", fname, data); */ if (fname != NULL) { Widget w = (Widget)data; #ifdef MOTIF XtVaSetValues(w, XmNvalue, fname, XmNcursorPosition, strlen(fname), NULL); #else XtVaSetValues(w, XtNstring, fname, NULL); XawTextSetInsertionPoint(w, strlen(fname)); #endif } } static void cb_browse(Widget w, XtPointer client_data, XtPointer call_data) { struct save_or_print_info *info = (struct save_or_print_info *)client_data; printOrSaveActionT act = info->act; Widget file_text; /* static so that we can pass its address */ static struct filesel_callback cb[2] = { { NULL, NULL, "xdvik: Save to file", "Save to file:", "OK", "Cancel", NULL, NULL, False, False, NULL, NULL }, { NULL, NULL, "xdvik: Print to file", "Print to file:", "OK", "Cancel", NULL, "*.ps", False, False, NULL, NULL } }; UNUSED(call_data); /* switch on `to file' radio button */ if (act == FILE_PRINT) text_print_vs_save_callback(w, (XtPointer)info, NULL, NULL); if (!get_widget_by_name(&file_text, info->shell, Xdvi_TO_FILE_TEXT, True)) return; if (act == FILE_SAVE) { if (resource.default_saving_format == FMT_PS) cb[0].filemask = "*.ps"; else if (resource.default_saving_format == FMT_PS2PDF) cb[0].filemask = "*.pdf"; else if (resource.default_saving_format == FMT_DVI) cb[0].filemask = "*.dvi"; else cb[0].filemask = "*.txt"; cb[0].func_ptr = set_filename_callback; cb[0].data = file_text; cb[0].browse_fname = xt_strdup(globals.cwd); /* fprintf(stderr, "==== text widget save: %p; shell: %p\n", (void *)file_text, (void *)info->shell); */ if (cb[0].shell == NULL) cb[0].shell = XsraSelFile(info->shell, &cb[0]); XsraSelFilePopup(&cb[0]); /* fprintf(stderr, "done saving: return widget = %p\n", ret_widget); */ } else { cb[1].func_ptr = set_filename_callback; cb[1].data = file_text; cb[1].init_path = globals.cwd; /* fprintf(stderr, "==== text widget print: %p; shell: %p\n", (void *)file_text, (void *)info->shell); */ /* if (!get_widget_by_name(&parent, globals.widgets.top_level, Xdvi_PRINT_SHELL_NAME, True)) */ /* parent = globals.widgets.top_level; */ if (cb[1].shell == NULL) cb[1].shell = XsraSelFile(info->shell, &cb[1]); XsraSelFilePopup(&cb[1]); } } /* create a dialog for printing OR saving */ #ifdef MOTIF static void motif_create_dialog(struct save_or_print_info *info) { printOrSaveActionT act = info->act; Atom WM_DELETE_WINDOW; char *ptr; char ofstring[1024]; Widget form, pane, box; Widget print_or_save_frame, destination_label, destination_form; Widget dvips_options_label; Widget pages_frame, pages_label, pages_form; Widget print_to_file_text, to_file_radio_or_label; Widget dvips_options_text; Widget print_to_file_button; Widget range_marked_radio, range_from_to_radio, to_printer_radio = NULL, print_to_printer_text = NULL, format_selection_option = NULL, print_or_save_range_all_radio, page_from_text, to_label, page_to_text, of_label, ok_button, cancel_button; Widget from_label; XmString str; XmString format_selection_texts[FORMAT_SEL_CNT]; XtTranslations xlats; XtAddActions(print_actions, XtNumber(print_actions)); ptr = get_string_va("#override \nosfCancel:WM_cancel(%p)", info); xlats = XtParseTranslationTable(ptr); free(ptr); if (globals.pageno_correct == 1) sprintf(ofstring, "of %d physical pages", total_pages); else sprintf(ofstring, "of %d to %d pages", globals.pageno_correct, total_pages + globals.pageno_correct - 1); info->shell = XtVaCreatePopupShell(act == FILE_SAVE ? "save_popup" : "print_popup", xmDialogShellWidgetClass, globals.widgets.top_level, XmNtitle, act == FILE_SAVE ? "xdvik: Save File" : "xdvik: Print File", XmNallowShellResize, True, XmNdeleteResponse, XmDO_NOTHING, /* we'll take care of that ourselves */ XmNmappedWhenManaged, False, /* so that we can center it first */ NULL); /* make the window manager destroy action just pop down the dialog */ WM_DELETE_WINDOW = XmInternAtom(XtDisplay(info->shell), "WM_DELETE_WINDOW", False); XmAddWMProtocolCallback(info->shell, WM_DELETE_WINDOW, cb_popdown, (XtPointer)info); pane = XtVaCreateWidget(act == FILE_SAVE ? "save_paned" : "print_paned", xmPanedWindowWidgetClass, info->shell, /* make sashes invisible */ XmNsashWidth, 1, XmNsashHeight, 1, /* turn separator off, since it gives visual noise with the frames */ XmNseparatorOn, False, NULL); form = XtVaCreateWidget("form", xmFormWidgetClass, pane, XmNhorizontalSpacing, DDIST_MAJOR, XmNverticalSpacing, DDIST_MAJOR, XmNautoUnmanage, False, XTranslations, xlats, NULL); if (act == FILE_PRINT) { /* First frame: print to printer or file */ print_or_save_frame = XtVaCreateWidget("print_to_frame", xmFrameWidgetClass, form, XmNmarginWidth, DDIST, XmNmarginHeight, DDIST, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XTranslations, xlats, NULL); str = XmStringCreateLocalized("Print to:"); destination_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, print_or_save_frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNlabelString, str, NULL); XmStringFree(str); destination_form = XtVaCreateWidget("destination_form", xmFormWidgetClass, print_or_save_frame, XmNhorizontalSpacing, DDIST, XmNverticalSpacing, DDIST, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XTranslations, xlats, NULL); str = XmStringCreateLocalized("Printer:"); to_printer_radio = XtVaCreateManagedWidget(Xdvi_TO_PRINTER_NAME, xmToggleButtonGadgetClass, destination_form, XmNlabelString, str, XmNindicatorType, XmONE_OF_MANY, XmNset, resource.default_printing_target == TO_PRINTER, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 0, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 0, NULL); XmStringFree(str); XtAddCallback(to_printer_radio, XmNvalueChangedCallback, cb_print_vs_save, (XtPointer)info); XtOverrideTranslations(to_printer_radio, xlats); print_to_printer_text = XtVaCreateManagedWidget(Xdvi_TO_PRINTER_TEXT, xmTextFieldWidgetClass, destination_form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 0, XmNleftAttachment, XmATTACH_WIDGET, XmNrightAttachment, XmATTACH_FORM, XmNleftWidget, to_printer_radio, /* XmNsensitive, resource.default_printing_target == TO_PRINTER, */ XTranslations, xlats, NULL); XtAddCallback(print_to_printer_text, XmNactivateCallback, cb_print_or_save, (XtPointer)info); XtAddCallback(print_to_printer_text, XmNfocusCallback, cb_text_print_vs_save, (XtPointer)info); adjust_heights(to_printer_radio, print_to_printer_text, NULL); str = XmStringCreateLocalized("PS File:"); to_file_radio_or_label = XtVaCreateManagedWidget(Xdvi_TO_FILE_NAME, xmToggleButtonGadgetClass, destination_form, XmNlabelString, str, XmNindicatorType, XmONE_OF_MANY, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, print_to_printer_text, XmNleftAttachment, XmATTACH_FORM, XmNset, resource.default_printing_target == TO_FILE, XmNleftOffset, 0, NULL); XmStringFree(str); XtAddCallback(to_file_radio_or_label, XmNvalueChangedCallback, cb_print_vs_save, (XtPointer)info); str = XmStringCreateLocalized("Browse ..."); print_to_file_button = XtVaCreateManagedWidget(Xdvi_BROWSE_BUTTON, xmPushButtonWidgetClass, destination_form, XmNlabelString, str, /* XmNsensitive, resource.default_printing_target == TO_FILE, */ XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, print_to_printer_text, XmNrightAttachment, XmATTACH_FORM, NULL); XmStringFree(str); XtOverrideTranslations(to_file_radio_or_label, xlats); XtOverrideTranslations(print_to_file_button, xlats); print_to_file_text = XtVaCreateManagedWidget(Xdvi_TO_FILE_TEXT, xmTextFieldWidgetClass, destination_form, /* XmNsensitive, resource.default_printing_target == TO_FILE, */ XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, print_to_printer_text, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, print_to_file_button, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, to_file_radio_or_label, XTranslations, xlats, NULL); adjust_heights(to_file_radio_or_label, print_to_file_button, print_to_file_text, NULL); XtAddCallback(print_to_file_text, XmNactivateCallback, cb_print_or_save, (XtPointer)info); XtAddCallback(print_to_file_text, XmNfocusCallback, cb_text_print_vs_save, (XtPointer)info); XtAddCallback(print_to_file_button, XmNactivateCallback, cb_browse, (XtPointer)info); XtManageChild(destination_form); XtManageChild(print_or_save_frame); /* initial value for printer name */ XtVaSetValues(print_to_printer_text, XmNvalue, info->printer_options, XmNcursorPosition, strlen(info->printer_options), NULL); } else { /* saving, not printing */ print_or_save_frame = XtVaCreateWidget("save_as_frame", xmFrameWidgetClass, form, XmNmarginWidth, DDIST, XmNmarginHeight, DDIST, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); str = XmStringCreateLocalized("Save as:"); destination_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, print_or_save_frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNlabelString, str, NULL); XmStringFree(str); destination_form = XtVaCreateWidget("destination_form", xmFormWidgetClass, print_or_save_frame, XmNhorizontalSpacing, DDIST, XmNverticalSpacing, DDIST, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XTranslations, xlats, NULL); /* fprintf(stderr, "CHILD: 0x%x\n", (long)destination_form); */ str = XmStringCreateLocalized("Format:"); format_selection_texts[0] = XmStringCreateLocalized((char *)output_format_mapping[0].fmt_string); format_selection_texts[1] = XmStringCreateLocalized((char *)output_format_mapping[1].fmt_string); format_selection_texts[2] = XmStringCreateLocalized((char *)output_format_mapping[2].fmt_string); format_selection_texts[3] = XmStringCreateLocalized((char *)output_format_mapping[3].fmt_string); format_selection_texts[4] = XmStringCreateLocalized((char *)output_format_mapping[4].fmt_string); format_selection_option = XmVaCreateSimpleOptionMenu(destination_form, "format_selection_option", str, 'F', resource.default_saving_format, /*initial menu selection*/ cb_select_format, /* callback */ XmVaPUSHBUTTON, format_selection_texts[0], 'P', NULL, NULL, XmVaPUSHBUTTON, format_selection_texts[1], 'F', NULL, NULL, XmVaPUSHBUTTON, format_selection_texts[2], 'D', NULL, NULL, XmVaPUSHBUTTON, format_selection_texts[3], 'T', NULL, NULL, XmVaPUSHBUTTON, format_selection_texts[4], 'U', NULL, NULL, XmNuserData, (XtPointer)info, NULL); XmStringFree(str); XmStringFree(format_selection_texts[0]); XmStringFree(format_selection_texts[1]); XmStringFree(format_selection_texts[2]); XmStringFree(format_selection_texts[3]); XmStringFree(format_selection_texts[4]); str = XmStringCreateLocalized("File name:"); to_file_radio_or_label = XtVaCreateManagedWidget(Xdvi_TO_FILE_NAME, xmLabelGadgetClass, destination_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, format_selection_option, XmNleftAttachment, XmATTACH_FORM, /* XmNchildType, XmFRAME_TITLE_CHILD, */ XmNlabelString, str, NULL); XmStringFree(str); str = XmStringCreateLocalized("Browse ..."); print_to_file_button = XtVaCreateManagedWidget(Xdvi_BROWSE_BUTTON, xmPushButtonWidgetClass, destination_form, XmNlabelString, str, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, format_selection_option, XmNrightAttachment, XmATTACH_FORM, XTranslations, xlats, NULL); print_to_file_text = XtVaCreateManagedWidget(Xdvi_TO_FILE_TEXT, xmTextFieldWidgetClass, destination_form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, format_selection_option, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, to_file_radio_or_label, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, print_to_file_button, XTranslations, xlats, NULL); adjust_heights(to_file_radio_or_label, print_to_file_button, print_to_file_text, NULL); XtAddCallback(print_to_file_button, XmNactivateCallback, cb_browse, (XtPointer)info); } /* initial value for filename */ XtVaSetValues(print_to_file_text, XmNvalue, info->finfo->out_file, XmNcursorPosition, strlen(info->finfo->out_file), NULL); { /* align left edges of widgets */ Dimension w1, w2; XtVaGetValues(to_file_radio_or_label, XmNwidth, &w2, NULL); if (act == FILE_PRINT) XtVaGetValues(to_printer_radio, XmNwidth, &w1, NULL); else { Widget w; if (get_widget_by_name(&w, format_selection_option, "OptionLabel", True)) { XtVaGetValues(w, XmNwidth, &w1, NULL); } else { w1 = w2; } } if (w1 > w2) { Dimension offset = DDIST; offset += w1 - w2; XtVaSetValues(print_to_file_text, XmNleftOffset, offset, NULL); } else if (w2 > w1) { Dimension offset = DDIST; offset += w2 - w1; if (act == FILE_PRINT) XtVaSetValues(print_to_printer_text, XmNleftOffset, offset, NULL); else { Widget w; if (get_widget_by_name(&w, format_selection_option, "OptionLabel", True)) { /* FIXME: Setting width would be cleaner, but it doesn't work ...? Dimension curr_w; XtVaGetValues(w, XmNwidth, &curr_w, NULL); XtVaSetValues(w, XmNwidth, curr_w + offset, NULL); */ /* fprintf(stderr, "Setting width from %d to: %d\n", curr_w, curr_w + offset); */ XtVaSetValues(w, XmNmarginRight, offset, XmNalignment, XmALIGNMENT_BEGINNING, NULL); } } } } if (act == FILE_SAVE) { XtManageChild(format_selection_option); XtManageChild(destination_form); XtManageChild(print_or_save_frame); } /* additional dvips options */ str = XmStringCreateLocalized("Dvips Options:"); dvips_options_label = XtVaCreateManagedWidget(Xdvi_DVIPS_OPTIONS_NAME, xmLabelGadgetClass, form, XmNlabelString, str, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, print_or_save_frame, XmNleftAttachment, XmATTACH_FORM, NULL); XmStringFree(str); dvips_options_text = XtVaCreateManagedWidget(Xdvi_DVIPS_OPTIONS_TEXT, xmTextFieldWidgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, print_or_save_frame, XmNleftAttachment, XmATTACH_WIDGET, XmNrightAttachment, XmATTACH_FORM, XmNleftWidget, dvips_options_label, XmNcolumns, 20, XTranslations, xlats, NULL); XtAddCallback(dvips_options_text, XmNactivateCallback, cb_print_or_save, (XtPointer)info); adjust_heights(dvips_options_label, dvips_options_text, NULL); /* initial value for dvips options */ XtVaSetValues(dvips_options_text, XmNvalue, info->dvips_options, XmNcursorPosition, strlen(info->dvips_options), NULL); /* page selection */ pages_frame = XtVaCreateWidget(act == FILE_PRINT ? "print_page_frame" : "save_page_frame", xmFrameWidgetClass, form, XmNmarginWidth, DDIST, XmNmarginHeight, DDIST, XmNresizable, True, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, dvips_options_text, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XTranslations, xlats, NULL); str = XmStringCreateLocalized("Pages:"); pages_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, pages_frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNlabelString, str, NULL); XmStringFree(str); pages_form = XtVaCreateWidget("pages_form", xmFormWidgetClass, pages_frame, XmNhorizontalSpacing, DDIST, XmNverticalSpacing, DDIST, XmNresizable, True, XTranslations, xlats, NULL); str = XmStringCreateLocalized("All"); print_or_save_range_all_radio = XtVaCreateManagedWidget(Xdvi_PAGES_ALL_RADIO_NAME, xmToggleButtonGadgetClass, pages_form, XmNlabelString, str, XmNindicatorType, XmONE_OF_MANY, XmNset, True, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 0, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 0, XTranslations, xlats, NULL); XmStringFree(str); XtAddCallback(print_or_save_range_all_radio, XmNvalueChangedCallback, cb_range, (XtPointer)info); str = XmStringCreateLocalized("Marked"); range_marked_radio = XtVaCreateManagedWidget(Xdvi_PAGES_MARKED_RADIO_NAME, xmToggleButtonGadgetClass, pages_form, XmNlabelString, str, XmNindicatorType, XmONE_OF_MANY, XmNtopAttachment, XmATTACH_WIDGET, XmNsensitive, pageinfo_have_marked_pages(), XmNtopWidget, print_or_save_range_all_radio, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 0, XTranslations, xlats, NULL); XmStringFree(str); XtAddCallback(range_marked_radio, XmNvalueChangedCallback, cb_range, (XtPointer)info); str = XmStringCreateLocalized("Range:"); range_from_to_radio = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_RADIO_NAME, xmToggleButtonGadgetClass, pages_form, XmNlabelString, str, XmNindicatorType, XmONE_OF_MANY, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, range_marked_radio, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 0, XTranslations, xlats, NULL); XmStringFree(str); XtAddCallback(range_from_to_radio, XmNvalueChangedCallback, cb_range, (XtPointer)info); str = XmStringCreateLocalized("From"); from_label = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_FROM_LABEL_NAME, xmLabelGadgetClass, pages_form, XmNlabelString, str, /* XmNsensitive, info->page_selection == PAGE_RANGE, */ XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, range_marked_radio, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, range_from_to_radio, NULL); XmStringFree(str); page_from_text = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_FROM_TEXT_NAME, xmTextFieldWidgetClass, pages_form, XmNcolumns, 5, /* XmNsensitive, info->page_selection == PAGE_RANGE, */ XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, range_marked_radio, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, from_label, XTranslations, xlats, NULL); XtAddCallback(page_from_text, XmNactivateCallback, cb_print_or_save, (XtPointer)info); XtAddCallback(page_from_text, XmNfocusCallback, cb_text_page_range, (XtPointer)info); str = XmStringCreateLocalized("to"); to_label = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_TO_LABEL_NAME, xmLabelGadgetClass, pages_form, XmNlabelString, str, /* XmNsensitive, info->page_selection == PAGE_RANGE, */ XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, range_marked_radio, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, page_from_text, NULL); XmStringFree(str); page_to_text = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_TO_TEXT_NAME, xmTextFieldWidgetClass, pages_form, XmNcolumns, 5, /* XmNsensitive, info->page_selection == PAGE_RANGE, */ XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, range_marked_radio, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, to_label, XTranslations, xlats, NULL); XtAddCallback(page_to_text, XmNactivateCallback, cb_print_or_save, (XtPointer)info); XtAddCallback(page_to_text, XmNfocusCallback, cb_text_page_range, (XtPointer)info); str = XmStringCreateLocalized(ofstring); of_label = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_OF_LABEL_NAME, xmLabelGadgetClass, pages_form, XmNlabelString, str, /* XmNsensitive, info->page_selection == PAGE_RANGE, */ XmNresizable, True, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, range_marked_radio, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, page_to_text, NULL); XmStringFree(str); adjust_heights(range_from_to_radio, from_label, page_from_text, to_label, page_to_text, of_label, NULL); XtManageChild(pages_form); XtManageChild(pages_frame); /* box for the OK/Cancel button */ box = XtVaCreateManagedWidget("box", xmFormWidgetClass, pane, XmNskipAdjust, True, /* don't resize this area */ XTranslations, xlats, NULL); str = XmStringCreateLocalized(act == FILE_PRINT ? "Print" : "Save"); ok_button = XtVaCreateManagedWidget(act == FILE_PRINT ? "print_button" : "save_button", xmPushButtonWidgetClass, box, XmNlabelString, str, XmNshowAsDefault, True, XmNdefaultButtonShadowThickness, 1, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, /* to mimick appearance of native dialog buttons: */ XmNmarginWidth, 6, XmNmarginHeight, 4, XmNtopOffset, 10, XmNbottomOffset, 10, XmNleftOffset, 10, NULL); XmStringFree(str); XtAddCallback(ok_button, XmNactivateCallback, cb_print_or_save, (XtPointer)info); XtOverrideTranslations(ok_button, XtParseTranslationTable("Return:ArmAndActivate()")); str = XmStringCreateLocalized("Cancel"); cancel_button = XtVaCreateManagedWidget("cancel", xmPushButtonWidgetClass, box, XmNlabelString, str, XmNdefaultButtonShadowThickness, 1, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, /* to mimick appearance of native dialog buttons: */ XmNmarginWidth, 6, XmNmarginHeight, 4, XmNtopOffset, 10, XmNbottomOffset, 10, XmNrightOffset, 10, NULL); XmStringFree(str); XtOverrideTranslations(print_or_save_range_all_radio, xlats); XtOverrideTranslations(range_marked_radio, xlats); XtOverrideTranslations(range_from_to_radio, xlats); XtOverrideTranslations(ok_button, xlats); XtOverrideTranslations(cancel_button, xlats); XtAddCallback(cancel_button, XmNactivateCallback, cb_popdown, (XtPointer)info); { /* make the buttons the same size: */ Dimension w1, w2; XtVaGetValues(ok_button, XtNwidth, &w1, NULL); XtVaGetValues(cancel_button, XtNwidth, &w2, NULL); if (w1 < w2) XtVaSetValues(ok_button, XtNwidth, w2, NULL); else if (w2 > w1) XtVaSetValues(cancel_button, XtNwidth, w1, NULL); } if (pageinfo_have_marked_pages()) { XmToggleButtonGadgetSetState(range_marked_radio, True, True); } else if (info->page_selection == PAGE_MARKED) { XmToggleButtonGadgetSetState(print_or_save_range_all_radio, True, True); } XtManageChild(form); XtManageChild(pane); center_window(info->shell, globals.widgets.top_level); XtMapWidget(info->shell); XmProcessTraversal(ok_button, XmTRAVERSE_CURRENT); /* if (act == FILE_PRINT) { */ /* if (resource.default_printing_target == TO_PRINTER) */ /* XmProcessTraversal(print_to_printer_text, XmTRAVERSE_CURRENT); */ /* else */ /* XmProcessTraversal(print_to_file_text, XmTRAVERSE_CURRENT); */ /* } */ } #else /* MOTIF */ static void xaw_create_dialog(struct save_or_print_info *info) { printOrSaveActionT act = info->act; Atom WM_DELETE_WINDOW; char *ptr; char ofstring[1024]; Widget form, paned, box; Widget dummy_label_form, dummy_pages_form; /* dummy forms to get indentation consistent */ Widget save_to_file_form; Widget dest_label; Widget print_to_printer_form, print_to_file_form, dvips_options_form; Widget dvips_options_label; Widget range_label; Widget page_range_form; Widget range_marked_form; Widget range_from_to_form; Widget print_to_file_text, to_file_radio_or_label; Widget dvips_options_text; Widget print_to_file_button; Widget format_selection_menu[FORMAT_SEL_CNT]; Widget format_selection_label = NULL, format_selection_button = NULL, format_selection_popup; Widget range_marked_radio, range_from_to_radio, to_printer_radio = NULL, print_to_printer_text = NULL, print_or_save_range_all_radio, page_from_text, to_label, page_to_text, of_label, ok_button, cancel_button; XtTranslations xlats, xlats2, wm_translations; XtAccelerators accels2; int ddist; static Dimension w_avg = 220; Dimension w_curr; /* handy abbrevs */ #define HORIZONTAL_RESIZING_NO XtNleft, XtChainLeft, XtNright, XtChainLeft #define HORIZONTAL_RESIZING_YES XtNleft, XtChainLeft, XtNright, XtChainRight #define VERTICAL_RESIZING_NO XtNtop, XtChainTop, XtNbottom, XtChainTop XtAddActions(print_actions, XtNumber(print_actions)); if (globals.pageno_correct == 1) sprintf(ofstring, "of %d physical pages", total_pages); else sprintf(ofstring, "of %d to %d pages", globals.pageno_correct, total_pages + globals.pageno_correct - 1); ptr = get_string_va("WM_PROTOCOLS: WM_cancel(%p)\n" "Escape:WM_cancel(%p)\n" "q:WM_cancel(%p)", info, info, info); wm_translations = XtParseTranslationTable(ptr); free(ptr); info->shell = XtVaCreatePopupShell(act == FILE_SAVE ? Xdvi_SAVE_SHELL_NAME : Xdvi_PRINT_SHELL_NAME, transientShellWidgetClass, globals.widgets.top_level, XtNtitle, act == FILE_SAVE ? "xdvik: Save File" : "xdvik: Print File", XtNmappedWhenManaged, False, XtNtransientFor, globals.widgets.top_level, XtNallowShellResize, True, XtNtranslations, wm_translations, NULL); WM_DELETE_WINDOW = XInternAtom(XtDisplay(info->shell), "WM_DELETE_WINDOW", False); paned = XtVaCreateManagedWidget("paned", panedWidgetClass, info->shell, NULL); form = XtVaCreateManagedWidget("save_or_print_form", formWidgetClass, paned, XtNallowResize, True, NULL); XtVaGetValues(form, XtNdefaultDistance, &ddist, NULL); /* fprintf(stderr, "form1: %ld\n", (long)form); */ xlats = XtParseTranslationTable(":highlight(Always)\n" ":unhighlight()\n" ",:set()notify()"); ptr = get_string_va("Return:xaw_print_or_save(%p)", info); xlats2 = XtParseTranslationTable(ptr); free(ptr); if (act == FILE_PRINT) { /* selection `to printer/to file' */ /* FIXME: set real sizes here */ /* Dimension w_curr; */ dummy_label_form = XtVaCreateManagedWidget("dummy_print_to_label_form", formWidgetClass, form, XtNresizable, True, XtNborderWidth, 0, HORIZONTAL_RESIZING_YES, NULL); dest_label = XtVaCreateManagedWidget("print_to", labelWidgetClass, dummy_label_form, XtNlabel, "Print to: ", XtNborderWidth, 0, HORIZONTAL_RESIZING_NO, NULL); print_to_printer_form = XtVaCreateManagedWidget("print_to_printer_form", formWidgetClass, form, XtNresizable, True, XtNborderWidth, 0, XtNvertDistance, 0, XtNfromVert, dummy_label_form, HORIZONTAL_RESIZING_YES, XtNallowResize, True, NULL); accels2 = XtParseAcceleratorTable(",:set()notify()"); to_printer_radio = XtVaCreateManagedWidget(Xdvi_TO_PRINTER_NAME, #ifdef XAW radioWidgetClass, #else toggleWidgetClass, #endif print_to_printer_form, XtNlabel, "Printer: ", XtNborderWidth, 0, XtNhighlightThickness, 1, XtNradioData, TO_PRINTER, XtNstate, resource.default_printing_target == TO_PRINTER, XtNtranslations, xlats, XtNaccelerators, accels2, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); XtAddCallback(to_printer_radio, XtNcallback, cb_print_vs_save, (XtPointer)info); XtInstallAccelerators(print_to_printer_form, to_printer_radio); print_to_printer_text = XtVaCreateManagedWidget(Xdvi_TO_PRINTER_TEXT, asciiTextWidgetClass, print_to_printer_form, XtNwidth, w_avg, XtNdataCompression, False, XtNeditType, XawtextEdit, /* XtNresize, XawtextResizeWidth, */ XtNfromHoriz, to_printer_radio, HORIZONTAL_RESIZING_YES, VERTICAL_RESIZING_NO, /* XtNscrollHorizontal, XawtextScrollAlways, */ NULL); XtOverrideTranslations(print_to_printer_text, xlats2); XtAddEventHandler(print_to_printer_text, KeyPressMask | ButtonPressMask, False, text_print_vs_save_callback, (XtPointer)info); adjust_vertically(to_printer_radio, print_to_printer_text, ddist); print_to_file_form = XtVaCreateManagedWidget("print_to_file_form", formWidgetClass, form, XtNborderWidth, 0, XtNvertDistance, -ddist, XtNfromVert, print_to_printer_form, HORIZONTAL_RESIZING_YES, NULL); to_file_radio_or_label = XtVaCreateManagedWidget(Xdvi_TO_FILE_NAME, #ifdef XAW radioWidgetClass, #else toggleWidgetClass, #endif print_to_file_form, XtNhighlightThickness, 1, XtNborderWidth, 0, XtNlabel, "PS File: ", XtNstate, resource.default_printing_target == TO_FILE, XtNradioGroup, to_printer_radio, XtNradioData, TO_FILE, XtNtranslations, xlats, XtNaccelerators, accels2, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); XtAddCallback(to_file_radio_or_label, XtNcallback, cb_print_vs_save, (XtPointer)info); XtInstallAccelerators(print_to_file_form, to_file_radio_or_label); print_to_file_text = XtVaCreateManagedWidget(Xdvi_TO_FILE_TEXT, asciiTextWidgetClass, print_to_file_form, XtNwidth, w_avg, XtNdataCompression, False, XtNeditType, XawtextEdit, XtNfromHoriz, to_file_radio_or_label, HORIZONTAL_RESIZING_YES, VERTICAL_RESIZING_NO, NULL); XtOverrideTranslations(print_to_file_text, xlats2); XtAddEventHandler(print_to_file_text, KeyPressMask | ButtonPressMask, False, text_print_vs_save_callback, (XtPointer)info); /* initial value for printer name */ XtVaSetValues(print_to_printer_text, XtNstring, info->printer_options, NULL); XawTextSetInsertionPoint(print_to_printer_text, strlen(info->printer_options)); } else { /* not printing, but saving */ int i; Dimension max_entry_width = 0; dummy_label_form = XtVaCreateManagedWidget("dummy_save_as_form", formWidgetClass, form, XtNresizable, True, XtNborderWidth, 0, HORIZONTAL_RESIZING_YES, NULL); dest_label = XtVaCreateManagedWidget("save_as", labelWidgetClass, dummy_label_form, XtNlabel, "Save as: ", XtNborderWidth, 0, HORIZONTAL_RESIZING_NO, NULL); save_to_file_form = XtVaCreateManagedWidget("save_to_file_form", formWidgetClass, form, XtNborderWidth, 0, XtNfromVert, dummy_label_form, HORIZONTAL_RESIZING_YES, VERTICAL_RESIZING_NO, NULL); /* fprintf(stderr, "formr1: %ld\n", (long)save_to_file_form); */ #if 0 menu_double_arrow_bitmap = XCreateBitmapFromData(XtDisplay(globals.widgets.top_level), RootWindowOfScreen(XtScreen(globals.widgets.top_level)), (char *)menu_double_arrow_bits, MENU_DOUBLE_ARROW_W, MENU_DOUBLE_ARROW_H); #endif format_selection_label = XtVaCreateManagedWidget("format_selection_label", labelWidgetClass, save_to_file_form, XtNlabel, "Format: ", XtNborderWidth, 0, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); format_selection_button = XtVaCreateManagedWidget(Xdvi_FORMAT_SELECTION_BUTTON_NAME, menuButtonWidgetClass, save_to_file_form, XtNmenuName, "format_selection_popup", XtNlabel, output_format_mapping[resource.default_saving_format].fmt_string, XtNjustify, XtJustifyLeft, XtNborderWidth, resource.btn_border_width, XtNfromHoriz, format_selection_label, #if 0 XtNhighlightThickness, 0, #endif NULL); #if 0 /* Hack for arrow - menuButtonWidget cannot have a XtNrightBitmap!!! */ format_selection_b1 = XtVaCreateManagedWidget("format_selection_b1", commandWidgetClass, save_to_file_form, XtNborderWidth, resource.btn_border_width, XtNfromHoriz, format_selection_button, XtNhorizDistance, -1, XtNhighlightThickness, 0, XtNbitmap, menu_double_arrow_bitmap, NULL); adjust_heights(format_selection_button, format_selection_b1, NULL); #endif format_selection_popup = XtCreatePopupShell("format_selection_popup", simpleMenuWidgetClass, format_selection_button, /* globals.widgets.top_level, */ NULL, 0); #if 0 XtAddCallback(format_selection_b1, XtNcallback, xaw_popup_menu_cb, format_selection_popup); #endif for (i = 1; i < FORMAT_SEL_CNT; i++) { char name[1024]; Dimension curr_entry_width; SNPRINTF(name, sizeof name, "format_selection_pulldown_%d", i); format_selection_menu[i] = XtVaCreateManagedWidget(name, smeBSBObjectClass, format_selection_popup, XtNjustify, XtJustifyLeft, XtNlabel, i == resource.default_saving_format ? output_format_mapping[0].fmt_string : output_format_mapping[i].fmt_string, NULL); XtVaGetValues(format_selection_menu[i], XtNwidth, &curr_entry_width, NULL); if (curr_entry_width > max_entry_width) max_entry_width = curr_entry_width; XtAddCallback(format_selection_menu[i], XtNcallback, cb_select_format, (XtPointer)info); } XtVaSetValues(format_selection_button, XtNwidth, max_entry_width, NULL); print_to_file_form = XtVaCreateManagedWidget("to_file_form", formWidgetClass, form, XtNborderWidth, 0, XtNfromVert, save_to_file_form, XtNvertDistance, -ddist, HORIZONTAL_RESIZING_YES, VERTICAL_RESIZING_NO, NULL); to_file_radio_or_label = XtVaCreateManagedWidget(Xdvi_TO_FILE_NAME, labelWidgetClass, print_to_file_form, XtNlabel, "File name: ", XtNborderWidth, 0, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); print_to_file_text = XtVaCreateManagedWidget(Xdvi_TO_FILE_TEXT, asciiTextWidgetClass, print_to_file_form, XtNwidth, w_avg, XtNdataCompression, False, XtNeditType, XawtextEdit, XtNfromHoriz, to_file_radio_or_label, HORIZONTAL_RESIZING_YES, VERTICAL_RESIZING_NO, NULL); XtOverrideTranslations(print_to_file_text, xlats2); { /* align left edges of format selection pulldown and filename field */ Dimension w1, w2, w_max; XtVaGetValues(format_selection_label, XtNwidth, &w1, NULL); XtVaGetValues(to_file_radio_or_label, XtNwidth, &w2, NULL); w_max = MAX(w1, w2); XtVaSetValues(format_selection_button, XtNhorizDistance, ddist + (w_max - w1), NULL); XtVaSetValues(print_to_file_text, XtNhorizDistance, ddist + (w_max - w2), NULL); } } /* initial value for filename */ XtVaSetValues(print_to_file_text, XtNstring, info->finfo->out_file, NULL); XawTextSetInsertionPoint(print_to_file_text, strlen(info->finfo->out_file)); #define DIST_1 8 /* FIXME */ print_to_file_button = XtVaCreateManagedWidget(Xdvi_BROWSE_BUTTON, commandWidgetClass, print_to_file_form, XtNlabel, "Browse ...", XtNfromHoriz, print_to_file_text, XtNhorizDistance, DIST_1, /* XtNsensitive, act == FILE_PRINT ? resource.default_printing_target == TO_FILE : True, */ /* attach to right of form, no resizing: */ XtNleft, XtChainRight, XtNright, XtChainRight, VERTICAL_RESIZING_NO, NULL); XtVaGetValues(print_to_file_button, XtNwidth, &w_curr, NULL); XtVaSetValues(print_to_file_text, XtNwidth, w_avg - w_curr - DIST_1 - 2, NULL); #undef DIST_1 adjust_vertically(to_file_radio_or_label, print_to_file_text, ddist + 5); adjust_vertically(print_to_file_text, to_file_radio_or_label, ddist + 5); adjust_vertically(print_to_file_button, to_file_radio_or_label, ddist + 5); XtAddCallback(print_to_file_button, XtNcallback, cb_browse, (XtPointer)info); /* other dvips options */ dvips_options_form = XtVaCreateManagedWidget("dvips_options_form", formWidgetClass, form, XtNborderWidth, 0, XtNfromVert, print_to_file_form, XtNvertDistance, 3 * ddist, HORIZONTAL_RESIZING_YES, NULL); dvips_options_label = XtVaCreateManagedWidget(Xdvi_DVIPS_OPTIONS_NAME, labelWidgetClass, dvips_options_form, XtNlabel, "Dvips Options:", XtNborderWidth, 0, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); dvips_options_text = XtVaCreateManagedWidget(Xdvi_DVIPS_OPTIONS_TEXT, asciiTextWidgetClass, dvips_options_form, XtNwidth, w_avg, XtNdataCompression, False, XtNeditType, XawtextEdit, XtNfromHoriz, dvips_options_label, HORIZONTAL_RESIZING_YES, VERTICAL_RESIZING_NO, NULL); XtOverrideTranslations(dvips_options_text, xlats2); { /* align left edges of input fields */ Dimension w1, w2, w3, w_max; if (act == FILE_PRINT) XtVaGetValues(to_printer_radio, XtNwidth, &w1, NULL); else XtVaGetValues(format_selection_label, XtNwidth, &w1, NULL); XtVaGetValues(to_file_radio_or_label, XtNwidth, &w2, NULL); XtVaGetValues(dvips_options_label, XtNwidth, &w3, NULL); w_max = MAX(MAX(w1, w2), w3); if (act == FILE_PRINT) XtVaSetValues(print_to_printer_text, XtNhorizDistance, ddist + (w_max - w1), NULL); else XtVaSetValues(format_selection_button, XtNhorizDistance, ddist + (w_max - w1), NULL); XtVaSetValues(print_to_file_text, XtNhorizDistance, ddist + (w_max - w2), NULL); XtVaSetValues(dvips_options_text, XtNhorizDistance, ddist + (w_max - w3), NULL); } /* initial value for dvips options */ XtVaSetValues(dvips_options_text, XtNstring, info->dvips_options, NULL); XawTextSetInsertionPoint(dvips_options_text, strlen(info->dvips_options)); /* page selection */ dummy_pages_form = XtVaCreateManagedWidget("dummy_pages_form", formWidgetClass, form, XtNfromVert, dvips_options_form, XtNresizable, True, XtNborderWidth, 0, XtNvertDistance, 3 * ddist, HORIZONTAL_RESIZING_NO, NULL); range_label = XtVaCreateManagedWidget("range_lab", labelWidgetClass, dummy_pages_form, XtNlabel, "Pages:", XtNborderWidth, 0, HORIZONTAL_RESIZING_NO, NULL); page_range_form = XtVaCreateManagedWidget(Xdvi_PAGE_RANGE_FORM_NAME, formWidgetClass, form, XtNborderWidth, 0, XtNfromVert, dummy_pages_form, XtNvertDistance, 0, HORIZONTAL_RESIZING_NO, NULL); accels2 = XtParseAcceleratorTable(",:set()notify()"); print_or_save_range_all_radio = XtVaCreateManagedWidget(Xdvi_PAGES_ALL_RADIO_NAME, #ifdef XAW radioWidgetClass, #else toggleWidgetClass, #endif page_range_form, XtNlabel, "All ", XtNborderWidth, 0, XtNhighlightThickness, 1, XtNradioData, PAGE_ALL, /* enable this button by default */ XtNstate, True, XtNtranslations, xlats, XtNaccelerators, accels2, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); XtAddCallback(print_or_save_range_all_radio, XtNcallback, cb_range, (XtPointer)info); XtInstallAccelerators(page_range_form, print_or_save_range_all_radio); range_marked_form = XtVaCreateManagedWidget("range_marked_form", formWidgetClass, form, XtNborderWidth, 0, XtNfromVert, page_range_form, XtNvertDistance, 0, HORIZONTAL_RESIZING_NO, NULL); range_marked_radio = XtVaCreateManagedWidget(Xdvi_PAGES_MARKED_RADIO_NAME, #ifdef XAW radioWidgetClass, #else toggleWidgetClass, #endif range_marked_form, XtNlabel, "Marked ", XtNsensitive, pageinfo_have_marked_pages(), XtNborderWidth, 0, XtNhighlightThickness, 1, XtNradioGroup, print_or_save_range_all_radio, XtNradioData, PAGE_MARKED, XtNtranslations, xlats, XtNaccelerators, accels2, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); XtAddCallback(range_marked_radio, XtNcallback, cb_range, (XtPointer)info); XtInstallAccelerators(range_marked_form, range_marked_radio); range_from_to_form = XtVaCreateManagedWidget("range_from_to_form", formWidgetClass, form, XtNborderWidth, 0, XtNfromVert, range_marked_form, XtNvertDistance, 0, XtNresizable, True, /* HORIZONTAL_RESIZING_NO, */ NULL); range_from_to_radio = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_RADIO_NAME, #ifdef XAW radioWidgetClass, #else toggleWidgetClass, #endif range_from_to_form, XtNlabel, "From: ", XtNborderWidth, 0, XtNhighlightThickness, 1, XtNradioGroup, print_or_save_range_all_radio, XtNradioData, PAGE_RANGE, XtNtranslations, xlats, XtNaccelerators, accels2, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); XtAddCallback(range_from_to_radio, XtNcallback, cb_range, (XtPointer)info); XtInstallAccelerators(range_from_to_form, range_from_to_radio); page_from_text = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_FROM_TEXT_NAME, asciiTextWidgetClass, range_from_to_form, XtNdataCompression, False, XtNeditType, XawtextEdit, XtNwidth, 50, XtNfromHoriz, range_from_to_radio, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); XtOverrideTranslations(page_from_text, xlats2); XtAddEventHandler(page_from_text, KeyPressMask | ButtonPressMask, False, text_page_range_callback, (XtPointer)info); to_label = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_TO_LABEL_NAME, labelWidgetClass, range_from_to_form, XtNlabel, "to: ", XtNborderWidth, 0, XtNfromHoriz, page_from_text, /* XtNsensitive, info->page_selection == PAGE_RANGE, */ HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); page_to_text = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_TO_TEXT_NAME, asciiTextWidgetClass, range_from_to_form, XtNdataCompression, False, XtNeditType, XawtextEdit, XtNwidth, 50, XtNfromHoriz, to_label, HORIZONTAL_RESIZING_NO, VERTICAL_RESIZING_NO, NULL); XtOverrideTranslations(page_to_text, xlats2); XtAddEventHandler(page_to_text, KeyPressMask | ButtonPressMask, False, text_page_range_callback, (XtPointer)info); of_label = XtVaCreateManagedWidget(Xdvi_PAGES_RANGE_OF_LABEL_NAME, labelWidgetClass, range_from_to_form, XtNlabel, ofstring, XtNborderWidth, 0, /* XtNsensitive, info->page_selection == PAGE_RANGE, */ XtNresizable, True, XtNfromHoriz, page_to_text, /* HORIZONTAL_RESIZING_NO, */ XtNleft, XtChainLeft, VERTICAL_RESIZING_NO, NULL); adjust_vertically(range_from_to_radio, page_from_text, ddist); adjust_vertically(to_label, page_from_text, ddist); adjust_vertically(of_label, page_from_text, ddist); /* box for the OK/Cancel button */ box = XtVaCreateManagedWidget("box", formWidgetClass, paned, /* resizing by user isn't needed */ XtNshowGrip, False, XtNdefaultDistance, 6, /* some padding */ /* resizing the window shouldn't influence this box, * but only the pane widget */ XtNskipAdjust, True, XtNaccelerators, G_accels_cr, NULL); ok_button = XtVaCreateManagedWidget(act == FILE_PRINT ? "print_button" : "save_button", commandWidgetClass, box, XtNlabel, act == FILE_PRINT ? "Print" : "Save", XtNaccelerators, G_accels_cr, XtNtop, XtChainTop, XtNbottom, XtChainBottom, HORIZONTAL_RESIZING_NO, NULL); XtAddCallback(ok_button, XtNcallback, cb_print_or_save, (XtPointer)info); XtInstallAccelerators(form, ok_button); if (act == FILE_PRINT) XtInstallAccelerators(print_to_printer_text, ok_button); XtInstallAccelerators(print_to_file_text, ok_button); cancel_button = XtVaCreateManagedWidget("cancel", commandWidgetClass, box, XtNlabel, "Cancel", XtNfromHoriz, ok_button, XtNbottom, XtChainBottom, XtNjustify, XtJustifyRight, XtNleft, XtChainRight, XtNright, XtChainRight, NULL); XtAddCallback(cancel_button, XtNcallback, cb_popdown, (XtPointer)info); XtManageChild(info->shell); center_window(info->shell, globals.widgets.top_level); XtMapWidget(info->shell); XSetWMProtocols(XtDisplay(info->shell), XtWindow(info->shell), &WM_DELETE_WINDOW, 1); if (pageinfo_have_marked_pages()) { XawToggleSetCurrent(print_or_save_range_all_radio, cast_int_to_XtPointer(PAGE_MARKED)); } else if (info->page_selection == PAGE_MARKED) { XawToggleSetCurrent(print_or_save_range_all_radio, cast_int_to_XtPointer(PAGE_ALL)); } #undef HORIZONTAL_RESIZING_NO #undef HORIZONTAL_RESIZING_YES #undef VERTICAL_RESIZING_NO } #endif /* MOTIF */ static void get_initial_values(struct save_or_print_info *info) { const char *extension = NULL; char *tmp = NULL; info->finfo->tmp_dvi_file = NULL; info->finfo->tmp_ps_file = NULL; info->finfo->tmp_dvi_fp = NULL; /* info->finfo->out_fp = NULL; */ info->message_popup = NULL; info->dvips_options = info->printer_options = NULL; /* * dvips options */ info->dvips_options = xstrdup(resource.dvips_options_str ? resource.dvips_options_str : ""); /* add -t options if needed */ if (info->dvips_options == NULL || info->dvips_options[0] == '\0' || strstr(info->dvips_options, "-t ") == NULL) { Boolean landscape = False; char *paper = get_dvips_papersize(&landscape); if (paper != NULL) { if (info->dvips_options == NULL) info->dvips_options = xstrdup("-t "); else info->dvips_options = xstrcat(info->dvips_options, " -t "); info->dvips_options = xstrcat(info->dvips_options, paper); free(paper); if (landscape) { info->dvips_options = xstrcat(info->dvips_options, " -t landscape"); } } } /* * printer options */ if (resource.dvips_printer_str != NULL) info->printer_options = xstrdup(resource.dvips_printer_str); else { /* initialize with default. We add the $PRINTER environment variable * since dvips otherwise doesn't use it. */ char *printer = getenv("PRINTER"); info->printer_options = xstrdup("lpr"); if (printer != NULL) { info->printer_options = xstrcat(info->printer_options, " -P"); info->printer_options = xstrcat(info->printer_options, printer); } } info->print_target = resource.default_printing_target; info->fmt = resource.default_saving_format; if (pageinfo_have_marked_pages()) { info->page_selection = PAGE_MARKED; } else { info->page_selection = PAGE_ALL; } if (info->act == FILE_SAVE) extension = output_format_mapping[resource.default_saving_format].extension; else extension = ".ps"; tmp = get_new_file_name(globals.dvi_name, get_extension(globals.dvi_name), extension); info->finfo->out_file = xmalloc(strlen(globals.cwd) + strlen(tmp) + 2); /* 1 extra for dir separator */ sprintf(info->finfo->out_file, "%s/%s", globals.cwd, tmp); free(tmp); TRACE_FILES((stderr, "OUTFILE: |%s|\n", info->finfo->out_file)); } static int textfield_to_int(Widget w) { char *s, *p; int pageno; #ifndef MOTIF XtVaGetValues(w, XtNstring, &s, NULL); #else /* MOTIF */ s = XmTextFieldGetString(w); #endif p = s; if (*p == '-') ++p; if (!isdigit((int)*p)) { return 0; } do { ++p; } while (isdigit((int)*p)); if (*p != '\0') return 0; pageno = atoi(s) - globals.pageno_correct; #ifdef MOTIF XtFree(s); #endif return pageno; } /* Return a copy of the text value of Widget w in malloc'ed memory, or NULL if the text is empty. */ static char * widgets_get_textfield(Widget w) { char *ptr = NULL; XtVaGetValues(w, #if MOTIF XmNvalue, #else XtNstring, #endif &ptr, NULL); if (ptr == NULL || *ptr == '\0') return NULL; else return xstrdup(ptr); } static char * widgets_get_textfield_by_name(const struct save_or_print_info *info, const char *widget_name) { Widget w; if (get_widget_by_name(&w, info->shell, widget_name, True)) { return widgets_get_textfield(w); } return NULL; } static pageRadioT widgets_get_page_selection(struct save_or_print_info *info) { Widget radio_all; #ifdef MOTIF Widget radio_marked; #endif if (get_widget_by_name(&radio_all, info->shell, Xdvi_PAGES_ALL_RADIO_NAME, True) #ifdef MOTIF && get_widget_by_name(&radio_marked, info->shell, Xdvi_PAGES_MARKED_RADIO_NAME, True) #endif ) { #ifdef MOTIF if (XmToggleButtonGadgetGetState(radio_all)) return PAGE_ALL; else if (XmToggleButtonGadgetGetState(radio_marked)) return PAGE_MARKED; else return PAGE_RANGE; #else return (pageRadioT)XawToggleGetCurrent(radio_all); #endif } return NO_PAGE_VAL; /* dummy */ } static int widgets_get_from_page(struct save_or_print_info *info) { Widget w; if (get_widget_by_name(&w, info->shell, Xdvi_PAGES_RANGE_FROM_TEXT_NAME, True)) { return textfield_to_int(w); } return 0; } static int widgets_get_to_page(struct save_or_print_info *info) { Widget w; if (get_widget_by_name(&w, info->shell, Xdvi_PAGES_RANGE_TO_TEXT_NAME, True)) { return textfield_to_int(w); } return 0; } static void set_check_page_range(struct save_or_print_info *info, Boolean check) { Widget text_from, text_to; if (get_widget_by_name(&text_from, info->shell, Xdvi_PAGES_RANGE_FROM_TEXT_NAME, True) && get_widget_by_name(&text_to, info->shell, Xdvi_PAGES_RANGE_TO_TEXT_NAME, True)) { char page_string[LENGTH_OF_INT]; if (check) { /* check validity of current values */ int curr_from = textfield_to_int(text_from); int curr_to = textfield_to_int(text_to); if (curr_from < total_pages && curr_to < total_pages) /* values are OK */ return; } sprintf(page_string, "%d", current_page + globals.pageno_correct); #ifdef MOTIF XtVaSetValues(text_from, XmNvalue, page_string, XmNcursorPosition, strlen(page_string), NULL); XtVaSetValues(text_to, XmNvalue, page_string, XmNcursorPosition, strlen(page_string), NULL); #else XtVaSetValues(text_from, XtNstring, page_string, NULL); XtVaSetValues(text_to, XtNstring, page_string, NULL); XawTextSetInsertionPoint(text_from, strlen(page_string)); XawTextSetInsertionPoint(text_to, strlen(page_string)); #endif } } static void popdown_dialog_and_print_or_save(XtPointer myinfo) { struct save_or_print_info *info = (struct save_or_print_info *)myinfo; cb_popdown(NULL, info, NULL); if (globals.dvi_file.bak_fp == NULL) { /* shouldn't happen */ info->message_popup = popup_message(globals.widgets.top_level, MSG_ERR, NULL, "No active DVI file"); return; } ASSERT(info->finfo->in_fp != NULL, "DVI input FILE * must have been set!"); store_preference(NULL, "dvipsOptionsString", "%s", info->dvips_options ? info->dvips_options : ""); if (info->act == FILE_PRINT) { store_preference(NULL, "defaultPrintingTarget", "%d", info->print_target); store_preference(NULL, "dvipsPrinterString", "%s", info->printer_options ? info->printer_options : ""); internal_print(info); } else { store_preference(NULL, "defaultSavingFormat", "%d", info->fmt); internal_save(info); } } /* Clean up after user has aborted printing/saving */ static void do_cleanup(XtPointer arg) { struct save_or_print_info *info = (struct save_or_print_info *)arg; cancel_saving(info); if (info->finfo->tmp_dvi_file != NULL) { unlink(info->finfo->tmp_dvi_file); info->finfo->tmp_dvi_file = NULL; } if (info->finfo->tmp_ps_file != NULL) { unlink(info->finfo->tmp_ps_file); info->finfo->tmp_ps_file = NULL; } } /* * First round of sanity checks for page range etc. */ static void print_check_page_values(struct save_or_print_info *info) { struct select_pages_info *pinfo = info->pinfo; /* get current dvips and printer options */ free(info->dvips_options); free(info->printer_options); info->dvips_options = info->printer_options = NULL; info->dvips_options = widgets_get_textfield_by_name(info, Xdvi_DVIPS_OPTIONS_TEXT); if (info->act == FILE_PRINT) info->printer_options = widgets_get_textfield_by_name(info, Xdvi_TO_PRINTER_TEXT); info->page_selection = widgets_get_page_selection(info); /* fprintf(stderr, "page selection: %d\n", info->page_selection); */ if (info->page_selection == PAGE_ALL) { /* fprintf(stderr, "ALL!!!\n"); */ pinfo->callback = NULL; } else if (info->page_selection == PAGE_MARKED) { /* fprintf(stderr, "MARKED!!!\n"); */ pinfo->callback = check_marked; } else { /* PAGE_RANGE */ /* fprintf(stderr, "RANGE!!!\n"); */ pinfo->from = widgets_get_from_page(info); pinfo->to = widgets_get_to_page(info); pinfo->callback = check_pagerange; if (pinfo->from + 1 < 1) { info->message_popup = popup_message(info->shell, MSG_ERR, "Please specify a valid page range.", "Invalid page range: start (%d) < 1.", pinfo->from + 1); return; } else if (pinfo->from > pinfo->to) { info->message_popup = popup_message(info->shell, MSG_ERR, "Please specify a valid page range.", "Invalid page range: start (%d) > end (%d).", pinfo->from + 1, pinfo->to + 1); return; } else if (pinfo->to + 1 > total_pages) { info->message_popup = popup_message(info->shell, MSG_ERR, "Please specify a valid page range.", "Invalid page range: end (%d) > total_pages (%d).", pinfo->to + 1, total_pages); return; } } print_check_dvi_file(info); } /* Second round of sanity checks. */ static void print_check_dvi_file(struct save_or_print_info *info) { FILE *fin = NULL; /* Return if there are active popups; otherwise, the print process may get messed up */ if (raise_message_windows()) { XBell(DISP, 0); #if 0 popup_message(info->shell, MSG_WARN, NULL, "Please close other open message windows first!"); #endif return; } /* If we want to print/save the marked pages, or save to a DVI file, we need to create a temporary DVI file containing the selected or all pages. */ if (info->page_selection == PAGE_MARKED || info->fmt == FMT_DVI) { int tmp_fd; free(info->finfo->tmp_dvi_file); info->finfo->tmp_dvi_file = NULL; tmp_fd = xdvi_temp_fd(&(info->finfo->tmp_dvi_file)); /* this allocates info->finfo->tmp_dvi_file */ if (tmp_fd == -1) { info->message_popup = popup_message(info->shell, MSG_ERR, NULL, "Couldn't create temporary DVI file for printing: %s", strerror(errno)); return; } /* don't use XFOPEN here, since we don't want to treat an error in opening the file as fatal. */ /* `b' in mode won't hurt ... */ if ((info->finfo->tmp_dvi_fp = try_fdopen(tmp_fd, "wb+")) == NULL) { /* failure */ info->message_popup = popup_message(info->shell, MSG_ERR, "Xdvi needs to create a temporary file containing the " "currently marked pages, but creating that file failed. " "Try to fix the cause of the problem, or choose " "\"Print selected pages\" as a workaround.", "Could not open temp file for writing: %s.\n", strerror(errno)); return; } } /* We try to use the original DVI file unless it's corrupted, in which case we ask the user if they want to save the cached copy instead */ if ((fin = fopen(globals.dvi_name, "rb")) == NULL || !find_postamble(fin, &(info->pinfo->errflag))) { Boolean could_not_open = False; if (fin == NULL) could_not_open = True; if (fin) fclose(fin); /* if we can't use the temporary file as source for our copy, this is a fatal error */ if (!resource.use_temp_fp) { info->message_popup = popup_message(info->shell, MSG_ERR, NULL, "Could not copy DVI file %s: The file %s", globals.dvi_name, could_not_open ? "doesn't exist any more" : "seems to be corrupted"); return; } /* else, we'll try to use the cached copy of the DVI file */ if ((fin = fopen(get_tmp_dvi_name(), "rb")) == NULL) { info->message_popup = popup_message(info->shell, MSG_ERR, NULL, "Something's very wrong here - opening of both the " "original DVI file and the cached copy failed!"); return; } if (!find_postamble(fin, &(info->pinfo->errflag))) { info->message_popup = popup_message(info->shell, MSG_ERR, NULL, "Shouldn't happen: Cached copy of the DVI file seems corrupted!"); return; } info->finfo->in_fp = fin; /* tell user about it */ info->message_popup = choice_dialog(info->shell, MSG_QUESTION, NULL, #ifndef MOTIF NULL, /* TODO: binding for RET? */ #endif /* MOTIF */ NULL, NULL, /* no pre_callbacks */ info->act == FILE_PRINT ? "Print Copy" : "Save Copy", print_check_target_file, (XtPointer)info, "Cancel", do_cleanup, (XtPointer)info, "The DVI file %s %s. Do you want to %s a cached copy of the file?", globals.dvi_name, could_not_open ? "doesn't exist any more" : "seems to be corrupted", info->act == FILE_PRINT ? "print" : "save"); } else { /* original DVI file is OK, copy it */ info->finfo->in_fp = fin; print_check_target_file((XtPointer)info); } } static void print_check_target_file(XtPointer myinfo) { struct save_or_print_info *info = (struct save_or_print_info *)myinfo; char *filename = widgets_get_textfield_by_name(info, Xdvi_TO_FILE_TEXT); char *expanded_filename; /* Return if there are active popups; otherwise, the print process will be messed up. */ if (raise_message_windows()) { XBell(DISP, 0); return; } /* if we're just printing to printer, go ahead */ if (!(info->act == FILE_SAVE || (info->act == FILE_PRINT && info->print_target == TO_FILE))) { popdown_dialog_and_print_or_save(info); return; } /* expand and canonicalize filename */ if (filename == NULL) { info->message_popup = popup_message(info->shell, MSG_WARN, NULL, "No filename specified!"); return; } expanded_filename = expand_homedir(filename); /* this allocates expanded_filename */ if (expanded_filename == NULL) { info->message_popup = popup_message(info->shell, MSG_WARN, "Please specify either a filename or a full path, without using \"~\" or \"~user\".", "Couldn't expand filename \"%s\" to a full path.", filename); free(filename); return; } free(filename); free(info->finfo->out_file); info->finfo->out_file = expanded_filename; if (info->act == FILE_SAVE && info->fmt == FMT_DVI) { /* canonicalize filename */ char *tmp = expand_filename_append_dvi(info->finfo->out_file, USE_CWD_PATH, False); /* this mallocs tmp */ if (strcmp(tmp, globals.dvi_name) == 0) { info->message_popup = popup_message(info->shell, MSG_ERR, NULL, "Cannot overwrite the current DVI file (%s). " "Please choose a different file name.", info->finfo->out_file); free(tmp); free(info->finfo->out_file); info->finfo->out_file = NULL; return; } free(info->finfo->out_file); info->finfo->out_file = tmp; } if (info->act == FILE_SAVE || (info->act == FILE_PRINT && info->print_target == TO_FILE)) { /* check whether to clobber existing file */ struct stat statbuf; if (stat(info->finfo->out_file, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) { info->message_popup = choice_dialog(info->shell, MSG_QUESTION, NULL, #ifndef MOTIF NULL, /* TODO: binding for RET */ #endif NULL, NULL, /* no pre_callbacks */ "Replace", popdown_dialog_and_print_or_save, (XtPointer)info, /* do nothing if user selects `cancel'; this will return to the printing dialog, since user hasn't changed their mind about printing, but would probably just like to choose another filename */ "Cancel", NULL, (XtPointer)NULL, "The file %s already exists.\nDo you want to replace it?", info->finfo->out_file); return; } else { popdown_dialog_and_print_or_save(info); } } else { popdown_dialog_and_print_or_save(info); } } static void notify_dialog(Widget w, pageRadioT *value_bak) { Widget radio_all, radio_marked; #ifdef MOTIF Widget radio_range; #endif Boolean have_marked = pageinfo_have_marked_pages(); pageRadioT value_curr; /* fprintf(stderr, "have_marked: %d\n", have_marked); */ if (get_widget_by_name(&radio_all, w, Xdvi_PAGES_ALL_RADIO_NAME, True) && get_widget_by_name(&radio_marked, w, Xdvi_PAGES_MARKED_RADIO_NAME, True) #ifdef MOTIF && get_widget_by_name(&radio_range, w, Xdvi_PAGES_RANGE_RADIO_NAME, True) #endif ) { /* get the current value */ #ifdef MOTIF if (XmToggleButtonGadgetGetState(radio_all)) value_curr = PAGE_ALL; else if (XmToggleButtonGadgetGetState(radio_marked)) value_curr = PAGE_MARKED; else value_curr = PAGE_RANGE; #else value_curr = (pageRadioT)XawToggleGetCurrent(radio_all); #endif /* fprintf(stderr, "current value: %d\n", value_curr); */ if (value_curr == PAGE_MARKED && have_marked) return; if (value_curr != PAGE_MARKED && !have_marked) { XtVaSetValues(radio_marked, #ifdef MOTIF XmNsensitive, #else XtNsensitive, #endif False, NULL); return; } /* otherwise, if we have marked pages now, we want to switch from the current value to `marked', saving the current value in *value_bak. */ /* XXX FIXME: There's a bug with OpenMotif 2.1 if the following order is used: - without marked pages, open dialog - mark a page; button `marked' is selected - select button `all' - select button `range' - unmark page; `marked' becomes insensitive - mark page, `marked' becomes sensitive and is selected, `range' is unselected - up to here, everything is as expected, but if you now select `range', it doesn't work, no button changes its state. As a workaround, if you select `marked' again and then `range', it works. Strangely, the callback when unsetting `range' is invoked correctly, so the button should be in the correct internal state ... I think this is an OpenMotif bug. */ if (have_marked) { *value_bak = value_curr; #ifdef MOTIF if (value_curr == PAGE_ALL) { XmToggleButtonGadgetSetState(radio_all, False, True); } else { XmToggleButtonGadgetSetState(radio_range, False, True); } XmToggleButtonGadgetSetState(radio_marked, True, True); XtVaSetValues(radio_marked, XmNsensitive, True, NULL); XmProcessTraversal(radio_marked, XmTRAVERSE_CURRENT); #else XawToggleSetCurrent(radio_all, cast_int_to_XtPointer(PAGE_MARKED)); XtVaSetValues(radio_marked, XtNsensitive, True, NULL); #endif } else { /* no marked pages now; switch back to the value from *value_bak. */ /* fprintf(stderr, "switching back to button %d\n", *value_bak); */ #ifdef MOTIF if (*value_bak == PAGE_ALL) { XmToggleButtonGadgetSetState(radio_all, True, True); XmProcessTraversal(radio_all, XmTRAVERSE_CURRENT); } else { XmToggleButtonGadgetSetState(radio_range, True, True); XmProcessTraversal(radio_range, XmTRAVERSE_CURRENT); } XmToggleButtonGadgetSetState(radio_marked, False, True); XtVaSetValues(radio_marked, XmNsensitive, False, NULL); #else XawToggleSetCurrent(radio_all, (XtPointer)*value_bak); XtVaSetValues(radio_marked, XtNsensitive, *value_bak == PAGE_MARKED, NULL); #endif } } } /* access from pagesel.c if user marks or unmarks a page in the page list */ void notify_print_dialog_have_marked(void) { Widget print_shell, save_shell; static pageRadioT save_value_bak = PAGE_ALL; static pageRadioT print_value_bak = PAGE_ALL; /* notify *both* windows, save and print, but only if they already exist */ if (get_widget_by_name(&print_shell, globals.widgets.top_level, Xdvi_PRINT_SHELL_NAME, False)) notify_dialog(print_shell, &save_value_bak); if (get_widget_by_name(&save_shell, globals.widgets.top_level, Xdvi_SAVE_SHELL_NAME, False)) notify_dialog(save_shell, &print_value_bak); } /* main entry point: pop up the dialog */ void save_or_print_callback(struct save_or_print_info *info) { if (info->shell != NULL && window_is_mapped(XtWindow(info->shell), DISP)) { XBell(DISP, 0); XRaiseWindow(DISP, XtWindow(info->shell)); return; } if (info->act == FILE_PRINT && printlog_raise_active(info)) { XBell(DISP, 0); return; } if (globals.dvi_file.bak_fp == NULL) { popup_message(globals.widgets.top_level, MSG_ERR, NULL, "Empty or incomplete DVI file. " "Please select a new DVI file via File -> Open."); return; } if (info->shell == NULL) { /* first time */ get_initial_values(info); #ifdef MOTIF motif_create_dialog(info); #else xaw_create_dialog(info); #endif /* fprintf(stderr, "SHELL IS: %p\n", (void *)info->shell); */ set_check_page_range(info, False); /* set initial values */ if (info->act == FILE_SAVE) update_dvips_options_sensitivity(resource.default_saving_format, info->shell); } else { set_check_page_range(info, False); /* was: True, use False to reset values to current page */ } /* map the dialog */ XtPopup(info->shell, XtGrabNone); }