+static void
+ev_window_cmd_file_print_setup (GtkAction *action, EvWindow *ev_window)
+{
+#ifdef WITH_GTK_PRINT
+ gtk_print_run_page_setup_dialog_async (
+ GTK_WINDOW (ev_window),
+ ev_window->priv->print_page_setup,
+ ev_window->priv->print_settings,
+ (GtkPageSetupDoneFunc) ev_window_print_page_setup_done_cb,
+ ev_window);
+#endif /* WITH_GTK_PRINT */
+}
+
+#ifdef WITH_GTK_PRINT
+static void
+ev_window_clear_print_job (EvWindow *window)
+{
+ if (window->priv->print_job) {
+ if (!window->priv->print_job->finished)
+ ev_job_queue_remove_job (window->priv->print_job);
+
+ g_signal_handlers_disconnect_by_func (window->priv->print_job,
+ ev_window_print_job_cb,
+ window);
+ g_object_unref (window->priv->print_job);
+ window->priv->print_job = NULL;
+ }
+}
+
+static void
+ev_window_print_finished (GtkPrintJob *print_job,
+ EvWindow *window,
+ GError *error)
+{
+ ev_window_clear_print_job (window);
+
+ if (error) {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Failed to print document"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ error->message);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+}
+
+static void
+ev_window_print_send (EvWindow *window,
+ const gchar *filename)
+{
+ GtkPrintJob *job;
+ GtkPrintSettings *settings;
+ GError *error = NULL;
+
+ if (window->priv->gtk_print_job)
+ g_object_unref (window->priv->gtk_print_job);
+
+ /* Some printers take into account some print settings,
+ * and others don't. However we have exported the document
+ * to a ps or pdf file according to such print settings. So,
+ * we want to send the exported file to printer with those
+ * settings set to default values.
+ */
+ settings = gtk_print_settings_copy (window->priv->print_settings);
+ gtk_print_settings_set_n_copies (settings, 1);
+ gtk_print_settings_set_page_ranges (settings, NULL, 0);
+ gtk_print_settings_set_page_set (settings, GTK_PAGE_SET_ALL);
+ gtk_print_settings_set_print_pages (settings, GTK_PRINT_PAGES_ALL);
+ gtk_print_settings_set_scale (settings, 1.0);
+ gtk_print_settings_set_collate (settings, FALSE);
+ gtk_print_settings_set_reverse (settings, FALSE);
+
+ job = gtk_print_job_new ("evince-print",
+ window->priv->printer,
+ settings,
+ window->priv->print_page_setup);
+
+ g_object_unref (settings);
+
+ window->priv->gtk_print_job = job;
+
+ if (gtk_print_job_set_source_file (job, filename, &error)) {
+ gtk_print_job_send (job,
+ (GtkPrintJobCompleteFunc)ev_window_print_finished,
+ window, NULL);
+ } else {
+ ev_window_clear_print_job (window);
+ g_warning (error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+ev_window_print_job_cb (EvJobPrint *job,
+ EvWindow *window)
+{
+ if (job->error) {
+ g_warning (job->error->message);
+ ev_window_clear_print_job (window);
+ return;
+ }
+
+ g_assert (job->temp_file != NULL);
+
+ ev_window_print_send (window, job->temp_file);
+}
+
+static gboolean
+ev_window_print_dialog_response_cb (GtkDialog *dialog,
+ gint response,
+ EvWindow *window)
+{
+ EvPrintRange *ranges = NULL;
+ EvPrintPageSet page_set;
+ gint n_ranges = 0;
+ gint copies;
+ gboolean collate;
+ gboolean reverse;
+ gdouble scale;
+ gint current_page;
+ gdouble width;
+ gdouble height;
+ GtkPrintPages print_pages;
+ const gchar *file_format;
+
+ if (response != GTK_RESPONSE_OK) {
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ window->priv->print_dialog = NULL;
+
+ return FALSE;
+ }
+
+ if (window->priv->printer)
+ g_object_unref (window->priv->printer);
+ if (window->priv->print_settings)
+ g_object_unref (window->priv->print_settings);
+ if (window->priv->print_page_setup)
+ g_object_unref (window->priv->print_page_setup);
+
+ window->priv->printer = g_object_ref (
+ gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog)));
+ window->priv->print_settings = g_object_ref (
+ gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog)));
+ window->priv->print_page_setup = g_object_ref (
+ gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog)));
+
+ file_format = gtk_print_settings_get (window->priv->print_settings,
+ GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
+
+ if (!gtk_printer_accepts_ps (window->priv->printer)) {
+ GtkWidget *msgdialog;
+
+ msgdialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Printing is not supported on this printer."));
+
+ gtk_dialog_run (GTK_DIALOG (msgdialog));
+ gtk_widget_destroy (msgdialog);
+
+ return FALSE;
+ }
+
+ ev_window_clear_print_job (window);
+
+ current_page = gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog));
+ print_pages = gtk_print_settings_get_print_pages (window->priv->print_settings);
+
+ switch (print_pages) {
+ case GTK_PRINT_PAGES_CURRENT:
+ ranges = g_new0 (EvPrintRange, 1);
+
+ ranges->start = current_page;
+ ranges->end = current_page;
+ n_ranges = 1;
+
+ break;
+ case GTK_PRINT_PAGES_RANGES: {
+ GtkPageRange *page_range;
+
+ page_range = gtk_print_settings_get_page_ranges (window->priv->print_settings,
+ &n_ranges);
+ if (n_ranges > 0)
+ ranges = g_memdup (page_range, n_ranges * sizeof (GtkPageRange));
+ }
+ break;
+ default:
+ break;
+ }
+
+ page_set = (EvPrintPageSet)gtk_print_settings_get_page_set (window->priv->print_settings);
+
+ scale = gtk_print_settings_get_scale (window->priv->print_settings) * 0.01;
+
+ width = gtk_page_setup_get_paper_width (window->priv->print_page_setup,
+ GTK_UNIT_PIXEL);
+ height = gtk_page_setup_get_paper_height (window->priv->print_page_setup,
+ GTK_UNIT_PIXEL);
+
+ if (scale != 1.0) {
+ width *= scale;
+ height *= scale;
+ }
+
+ copies = gtk_print_settings_get_n_copies (window->priv->print_settings);
+ collate = gtk_print_settings_get_collate (window->priv->print_settings);
+ reverse = gtk_print_settings_get_reverse (window->priv->print_settings);
+
+ window->priv->print_job = ev_job_print_new (window->priv->document,
+ file_format ? file_format : "ps",
+ width, height,
+ ranges, n_ranges,
+ page_set,
+ copies, collate,
+ reverse);
+
+ g_signal_connect (window->priv->print_job, "finished",
+ G_CALLBACK (ev_window_print_job_cb),
+ window);
+ /* The priority doesn't matter for this job */
+ ev_job_queue_add_job (window->priv->print_job, EV_JOB_PRIORITY_LOW);
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ window->priv->print_dialog = NULL;
+
+ return TRUE;