/* Glimmer = print.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * Authors: * Chema Celorio * Chris Phelps */ #include #include #include #include #include "print.h" #include "print-doc.h" #include "print-util.h" /** * glimmer_print_calculate_pages: * @pji: * * Calculates the number of pages that we need to print **/ static void glimmer_print_calculate_pages (PrintJobInfo * pji) { pji->total_lines = glimmer_print_document_determine_lines (pji, FALSE); pji->total_lines_real = glimmer_print_document_determine_lines (pji, TRUE); pji->pages = ((int) (pji->total_lines_real - 1) / pji->lines_per_page) + 1; pji->page_first = 1; pji->page_last = pji->pages; } /** * glimmer_print_job_info_new: * @void: * * Create and fill the PrintJobInfo struct * * Return Value: **/ static PrintJobInfo * glimmer_print_job_info_new (void) { PrintJobInfo *pji; const gchar *family_name; GnomeFontWeight weight; gdouble font_size; pji = g_new0 (PrintJobInfo, 1); pji->file = cur_file; g_return_val_if_fail (GDS_IS_FILE (pji->file), NULL); pji->preview = FALSE; pji->filename = cur_file->filename; /* GnomePrint Master and Context */ pji->master = gnome_print_master_new (); pji->pc = gnome_print_master_get_context (pji->master); pji->printer = NULL; g_return_val_if_fail (GNOME_IS_PRINT_MASTER (pji->master), NULL); g_return_val_if_fail (GNOME_IS_PRINT_CONTEXT (pji->pc), NULL); /* Buffer */ pji->buffer = gds_editor_get_chars (GDS_EDITOR (cur_file->text), 0, GTK_EXTEXT (cur_file->text)->length); g_return_val_if_fail (pji->buffer != NULL, NULL); pji->buffer_size = strlen (pji->buffer); /* Paper and Orientation */ pji->paper = gnome_paper_with_name ("A4"); gnome_print_master_set_paper (pji->master, pji->paper); g_return_val_if_fail (pji->paper != NULL, NULL); pji->orientation = general_preferences. print_landscape ? PRINT_ORIENT_LANDSCAPE : PRINT_ORIENT_PORTRAIT; if (pji->orientation == PRINT_ORIENT_LANDSCAPE) { pji->page_width = gnome_paper_psheight (pji->paper); pji->page_height = gnome_paper_pswidth (pji->paper); } else { pji->page_width = gnome_paper_pswidth (pji->paper); pji->page_height = gnome_paper_psheight (pji->paper); } /* Fonts */ pji->font_body = gnome_font_new_from_full_name (general_preferences.print_font); g_return_val_if_fail (GNOME_IS_FONT (pji->font_body), NULL); family_name = gnome_font_get_family_name (pji->font_body); font_size = gnome_font_get_size (pji->font_body); weight = gnome_font_get_weight_code (pji->font_body); pji->font_header = gnome_font_new_closest (family_name, weight <= 7 ? weight + 2 : weight, FALSE, font_size + 2.0); g_return_val_if_fail (GNOME_IS_FONT (pji->font_header), NULL); pji->font_numbers = gnome_font_new_closest (family_name, weight <= 4 ? weight : weight - 2, FALSE, font_size >= 6 ? font_size - 2 : font_size); g_return_val_if_fail (GNOME_IS_FONT (pji->font_numbers), NULL); pji->font_char_height = (float) ((font_size / 100) * 72) + 1; font_size = gnome_font_get_width_string (pji->font_body, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); pji->font_char_width = (float) (font_size / 36); /* Margins and printable area */ pji->margin_numbers = gnome_font_get_width_string (pji->font_numbers, "00000 "); pji->margin_top = .75 * 72; /* Printer margins, not page margins */ pji->margin_bottom = .75 * 72; /* We should "pull" this from gnome-print when */ pji->margin_left = .75 * 72; /* gnome-print implements them */ pji->margin_right = .75 * 72; pji->header_height = .50 * 72; if (general_preferences.print_header) pji->header_height += (2 * gnome_font_get_size (pji->font_header)); if (general_preferences.print_numbers) pji->margin_left += pji->margin_numbers; pji->printable_width = pji->page_width - pji->margin_left - pji->margin_right; pji->printable_height = pji->page_height - pji->margin_top - pji->margin_bottom; /* Chars, lines and pages */ pji->wrapping = general_preferences.print_with_wrap; // check settings here pji->print_line_numbers = general_preferences.print_numbers ? general_preferences. print_every_n_lines : 0; pji->print_header = general_preferences.print_header; pji->chars_per_line = (gint) (pji->printable_width / pji->font_char_width); pji->lines_per_page = ((pji->printable_height - pji->header_height) / pji->font_char_height - 1); pji->tab_size = GTK_EXTEXT (pji->file->text)->default_tab_width; pji->range = GNOME_PRINT_RANGE_ALL; pji->copies = 1; pji->collate = 0; glimmer_print_calculate_pages (pji); pji->canceled = FALSE; return pji; } /** * glimmer_print_job_info_destroy: * @pji: * * Destroy and free the internals of a PrintJobInfo stucture **/ static void glimmer_print_job_info_destroy (PrintJobInfo * pji) { gnome_print_master_close (pji->master); g_free (pji->buffer); pji->buffer = NULL; gnome_font_unref (pji->font_body); gnome_font_unref (pji->font_header); gnome_font_unref (pji->font_numbers); g_free (pji); } /** * glimmer_print_range_is_selection: * @pji: * * The user has chosen range = selection. Modify the relevant * fields inside pji to print only the selected text **/ static void glimmer_print_range_is_selection (PrintJobInfo * pji, guint start, guint end) { g_free (pji->buffer); pji->buffer = gds_editor_get_chars (GDS_EDITOR (pji->file->text), start, end); g_return_if_fail (pji->buffer != NULL); pji->buffer_size = end - start; glimmer_print_calculate_pages (pji); pji->page_first = 1; pji->page_last = pji->pages; } /** * glimmer_print_run_dialog: * @pji: * * Run the print dialog * * Return Value: TRUE if the printing was canceled by the user **/ static gboolean glimmer_print_run_dialog (PrintJobInfo * pji) { GnomeDialog *dialog; gint start_pos = 0; gint end_pos = 0; gint selection_flag = 0; if (GTK_EXTEXT (pji->file->text)->selection_start_pos != -1 && GTK_EXTEXT (pji->file->text)->selection_end_pos != -1) { selection_flag = GNOME_PRINT_RANGE_SELECTION; start_pos = GTK_EXTEXT (pji->file->text)->selection_start_pos; end_pos = GTK_EXTEXT (pji->file->text)->selection_end_pos; } else { selection_flag = GNOME_PRINT_RANGE_SELECTION_UNSENSITIVE; } dialog = (GnomeDialog *) gnome_print_dialog_new ((const char *) _("Print Document"), GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES); gnome_print_dialog_construct_range_page ((GnomePrintDialog *) dialog, GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_RANGE | selection_flag, 1, pji->pages, "A", _("Pages")); switch (gnome_dialog_run (GNOME_DIALOG (dialog))) { case GNOME_PRINT_PRINT: break; case GNOME_PRINT_PREVIEW: pji->preview = TRUE; break; case -1: return TRUE; default: gnome_dialog_close (GNOME_DIALOG (dialog)); return TRUE; } pji->printer = gnome_print_dialog_get_printer (GNOME_PRINT_DIALOG (dialog)); /* If preview, do not set the printer so that the print button in the preview * window will pop another print dialog */ if (pji->printer && !pji->preview) gnome_print_master_set_printer (pji->master, pji->printer); pji->range = gnome_print_dialog_get_range_page (GNOME_PRINT_DIALOG (dialog), &pji->page_first, &pji->page_last); gnome_print_dialog_get_copies (GNOME_PRINT_DIALOG (dialog), &pji->copies, &pji->collate); if (pji->range == GNOME_PRINT_RANGE_SELECTION) glimmer_print_range_is_selection (pji, start_pos, end_pos); gnome_dialog_close (GNOME_DIALOG (dialog)); return FALSE; } /** * glimmer_print_preview_real: * @pji: * * Create and show the print preview window **/ static void glimmer_print_preview_real (PrintJobInfo * pji) { GnomePrintMasterPreview *gpmp; gchar *title; title = g_strdup_printf (_("Print Preview\n")); gpmp = gnome_print_master_preview_new (pji->master, title); g_free (title); gtk_widget_show (GTK_WIDGET (gpmp)); } /** * glimmer_print: * @preview: * * The main printing function **/ static void glimmer_print (gboolean preview) { PrintJobInfo *pji; gboolean cancel = FALSE; if (!glimmer_print_verify_fonts ()) return; pji = glimmer_print_job_info_new (); pji->preview = preview; if (!pji->preview) cancel = glimmer_print_run_dialog (pji); /* The canceled button on the dialog was clicked */ if (cancel) { glimmer_print_job_info_destroy (pji); return; } glimmer_print_document (pji); /* The printing was canceled while in progress */ if (pji->canceled) { glimmer_print_job_info_destroy (pji); return; } if (pji->preview) { glimmer_print_preview_real (pji); } else { gnome_print_master_set_copies (pji->master, pji->copies, (gboolean) pji->collate); gnome_print_master_print (pji->master); } glimmer_print_job_info_destroy (pji); } /** * glimmer_print_cb: * @widget: * @notused: * * A callback for the menu/toolbar for printing **/ void glimmer_print_cb (GtkWidget * widget, gpointer notused) { glimmer_print (FALSE); } /** * glimmer_print_preview_cb: * @widget: * @notused: * * A callback for the menus/toolbars for print previewing **/ void glimmer_print_preview_cb (GtkWidget * widget, gpointer notused) { glimmer_print (TRUE); }