/* * Copyright (C) 2002 Jorn Baayen * Copyright (C) 2003, 2004 Christian Persch * Copyright (C) 2005 Juerg Billeter * * 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, 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. * * $Id$ */ #include "config.h" #include "print-dialog.h" #include "ephy-embed-single.h" #include "ephy-embed-shell.h" #include "ephy-file-chooser.h" #include "ephy-file-helpers.h" #include "ephy-stock-icons.h" #include "eel-gconf-extensions.h" #include "ephy-debug.h" #include "ephy-gui.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #define CONF_PRINT_PAGE_TITLE "/apps/epiphany/dialogs/print_page_title" #define CONF_PRINT_PAGE_URL "/apps/epiphany/dialogs/print_page_url" #define CONF_PRINT_DATE "/apps/epiphany/dialogs/print_date" #define CONF_PRINT_PAGE_NUMBERS "/apps/epiphany/dialogs/print_page_numbers" #define CONF_PRINT_COLOR "/apps/epiphany/dialogs/print_color" #define PRINT_CONFIG_FILENAME "ephy-print-config.xml" enum { SETUP_WINDOW_PROP, PAGE_TITLE_PROP, PAGE_URL_PROP, PAGE_NUMBERS_PROP, DATE_PROP, COLOR_PROP, }; static const EphyDialogProperty setup_props [] = { { "print_setup_dialog", NULL, PT_NORMAL, 0 }, { "print_page_title_checkbutton", CONF_PRINT_PAGE_TITLE, PT_AUTOAPPLY, 0 }, { "print_page_url_checkbutton", CONF_PRINT_PAGE_URL, PT_AUTOAPPLY, 0 }, { "print_page_numbers_checkbutton", CONF_PRINT_PAGE_NUMBERS, PT_AUTOAPPLY, 0 }, { "print_date_checkbutton", CONF_PRINT_DATE, PT_AUTOAPPLY, 0 }, { "print_color_radiobutton", CONF_PRINT_COLOR, PT_AUTOAPPLY, 0 }, { NULL } }; void ephy_print_info_free (EmbedPrintInfo *info) { g_return_if_fail (info != NULL); g_object_unref (info->config); g_free (info->tempfile); if (info->cancel_print_id != 0) g_signal_handler_disconnect (embed_shell, info->cancel_print_id); g_free (info->header_left_string); g_free (info->header_center_string); g_free (info->header_right_string); g_free (info->footer_left_string); g_free (info->footer_center_string); g_free (info->footer_right_string); g_free (info); } static GnomePrintConfig * ephy_print_load_config_from_file (void) { GnomePrintConfig *ephy_print_config = NULL; char *file_name, *contents = NULL; file_name = g_build_filename (ephy_dot_dir (), PRINT_CONFIG_FILENAME, NULL); if (g_file_get_contents (file_name, &contents, NULL, NULL)) { ephy_print_config = gnome_print_config_from_string (contents, 0); g_free (contents); } if (ephy_print_config == NULL) { ephy_print_config = gnome_print_config_default (); } g_free (file_name); return ephy_print_config; } static void ephy_print_save_config_to_file (GnomePrintConfig *config) { char *file_name, *str; g_return_if_fail (config != NULL); str = gnome_print_config_to_string (config, 0); if (str == NULL) return; file_name = g_build_filename (ephy_dot_dir (), PRINT_CONFIG_FILENAME, NULL); g_file_set_contents (file_name, str, -1, NULL); g_free (file_name); g_free (str); } EmbedPrintInfo * ephy_print_get_print_info (void) { EmbedPrintInfo *info; info = g_new0 (EmbedPrintInfo, 1); info->config = ephy_print_load_config_from_file (); info->range = GNOME_PRINT_RANGE_ALL; info->from_page = 1; info->to_page = 1; info->print_color = ! eel_gconf_get_integer (setup_props[COLOR_PROP].pref); info->header_left_string = eel_gconf_get_boolean (setup_props[PAGE_TITLE_PROP].pref) ? g_strdup ("&T") : g_strdup (""); info->header_right_string = eel_gconf_get_boolean (setup_props[PAGE_URL_PROP].pref) ? g_strdup ("&U") : g_strdup (""); info->footer_left_string = eel_gconf_get_boolean (setup_props[PAGE_NUMBERS_PROP].pref) ? g_strdup ("&PT") : g_strdup (""); info->footer_right_string = eel_gconf_get_boolean (setup_props[DATE_PROP].pref) ? g_strdup ("&D") : g_strdup (""); info->header_center_string = g_strdup(""); info->footer_center_string = g_strdup(""); info->frame_type = 0; return info; } static void ephy_print_dialog_response_cb (GtkDialog *dialog, int response, EmbedPrintInfo *info) { if (response == GNOME_PRINT_DIALOG_RESPONSE_PRINT) { ephy_print_save_config_to_file (info->config); info->range = gnome_print_dialog_get_range_page (GNOME_PRINT_DIALOG (dialog), &info->from_page, &info->to_page); } } static gboolean using_pdf_printer (GnomePrintConfig *config) { const guchar *driver; driver = gnome_print_config_get ( config, (const guchar *)"Settings.Engine.Backend.Driver"); if (driver) { if (!strcmp ((const gchar *)driver, "gnome-print-pdf")) return TRUE; else return FALSE; } return FALSE; } static gboolean using_postscript_printer (GnomePrintConfig *config) { const guchar *driver; const guchar *transport; driver = gnome_print_config_get ( config, (const guchar *)"Settings.Engine.Backend.Driver"); transport = gnome_print_config_get ( config, (const guchar *)"Settings.Transport.Backend"); if (driver) { if (strcmp ((const gchar *)driver, "gnome-print-ps") == 0) return TRUE; else return FALSE; } else if (transport) /* these transports default to PostScript */ { if (strcmp ((const gchar *)transport, "CUPS") == 0) return TRUE; else if (strcmp ((const gchar *)transport, "LPD") == 0) return TRUE; } return FALSE; } gboolean ephy_print_verify_postscript (GnomePrintDialog *print_dialog) { GnomePrintConfig *config; GtkWidget *dialog; config = gnome_print_dialog_get_config (print_dialog); if (using_postscript_printer (config)) return TRUE; if (using_pdf_printer (config)) { dialog = gtk_message_dialog_new ( GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Generating PDF is not supported")); } else { dialog = gtk_message_dialog_new ( GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Printing is not supported on this printer")); gtk_message_dialog_format_secondary_text ( GTK_MESSAGE_DIALOG (dialog), _("You were trying to print to a printer using the ā€œ%sā€ driver. This program requires a PostScript printer driver."), gnome_print_config_get ( config, (guchar *)"Settings.Engine.Backend.Driver")); } gtk_window_group_add_window (ephy_gui_ensure_window_group (GTK_WINDOW (print_dialog)), GTK_WINDOW (dialog)); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); return FALSE; } static void cancel_print_cb (EphyEmbedShell *shell, EmbedPrintInfo *info) { g_source_remove (info->print_idle_id); ephy_print_info_free (info); } static gboolean ephy_print_do_print_idle_cb (EmbedPrintInfo *info) { GnomePrintJob *job; /* Sometimes mozilla doesn't even create the temp file!? */ if (g_file_test (info->tempfile, G_FILE_TEST_EXISTS) == FALSE) return FALSE; /* FIXME: is this actually necessary? libc docs say all streams * are flushed when reading from any stream. */ fflush(NULL); job = gnome_print_job_new (info->config); gnome_print_job_set_file (job, info->tempfile); gnome_print_job_print (job); g_object_unref (job); unlink (info->tempfile); ephy_print_info_free (info); return FALSE; } void ephy_print_do_print_and_free (EmbedPrintInfo *info) { /* mozilla printing system hasn't really sent the data * to the printer when reporting that printing is done, it's * just ready to do it now */ info->print_idle_id = g_idle_add ((GSourceFunc) ephy_print_do_print_idle_cb, info); info->cancel_print_id = g_signal_connect (embed_shell, "prepare-close", G_CALLBACK (cancel_print_cb), info); } static void ephy_print_setup_dialog_response_cb (GtkWidget *widget, int response, EphyDialog *dialog) { if (response == GTK_RESPONSE_HELP) { ephy_gui_help (GTK_WINDOW (widget), "epiphany", "using-print-setup"); return; } g_object_unref (dialog); } /* * A variant of gnome_print_dialog_construct_range_page that can be used when * the total page count is unknown. It defaults to 1-1 */ static void ephy_print_dialog_construct_range_page (GnomePrintDialog *gpd, gint flags, const guchar *currentlabel, const guchar *rangelabel) { GtkWidget *hbox; hbox = NULL; if (flags & GNOME_PRINT_RANGE_RANGE) { GtkWidget *l, *sb; GtkObject *a; AtkObject *atko; hbox = gtk_hbox_new (FALSE, 3); gtk_widget_show (hbox); l = gtk_label_new_with_mnemonic (_("_From:")); gtk_widget_show (l); gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0); a = gtk_adjustment_new (1, 1, 9999, 1, 10, 10); g_object_set_data (G_OBJECT (hbox), "from", a); sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1, 0.0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (sb), TRUE); gtk_widget_show (sb); gtk_box_pack_start (GTK_BOX (hbox), sb, FALSE, FALSE, 0); gtk_label_set_mnemonic_widget ((GtkLabel *) l, sb); atko = gtk_widget_get_accessible (sb); atk_object_set_description (atko, _("Sets the start of the range of pages to be printed")); l = gtk_label_new_with_mnemonic (_("_To:")); gtk_widget_show (l); gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0); a = gtk_adjustment_new (1, 1, 9999, 1, 10, 10); g_object_set_data (G_OBJECT (hbox), "to", a); sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1, 0.0); gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (sb), TRUE); gtk_widget_show (sb); gtk_box_pack_start (GTK_BOX (hbox), sb, FALSE, FALSE, 0); gtk_label_set_mnemonic_widget ((GtkLabel *) l, sb); atko = gtk_widget_get_accessible (sb); atk_object_set_description (atko, _("Sets the end of the range of pages to be printed")); } gnome_print_dialog_construct_range_any (gpd, flags, hbox, currentlabel, rangelabel); } GtkWidget * ephy_print_dialog_new (GtkWidget *parent, EmbedPrintInfo *info) { GtkWidget *dialog; dialog = g_object_new (GNOME_TYPE_PRINT_DIALOG, "print_config", info->config, NULL); gnome_print_dialog_construct (GNOME_PRINT_DIALOG (dialog), (const guchar *) _("Print"), GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES); ephy_print_dialog_construct_range_page (GNOME_PRINT_DIALOG (dialog), GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_RANGE | GNOME_PRINT_RANGE_SELECTION, NULL, (const guchar *) _("Pages")); gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GNOME_PRINT_DIALOG_RESPONSE_PREVIEW, FALSE); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (ephy_print_dialog_response_cb), info); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent)); gtk_window_group_add_window (ephy_gui_ensure_window_group (GTK_WINDOW (parent)), GTK_WINDOW (dialog)); return dialog; } EphyDialog * ephy_print_setup_dialog_new (void) { EphyDialog *dialog; GtkWidget *window; dialog = EPHY_DIALOG (g_object_new (EPHY_TYPE_DIALOG, NULL)); ephy_dialog_construct (dialog, setup_props, ephy_file ("print.glade"), "print_setup_dialog", NULL); window = ephy_dialog_get_control (dialog, setup_props[SETUP_WINDOW_PROP].id); g_signal_connect (window, "response", G_CALLBACK (ephy_print_setup_dialog_response_cb), dialog); return dialog; }