From 1bc11bf9ca800edd4469d5e8c8aeb605d3037bc7 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 23 Jul 2006 19:59:43 +0000 Subject: [PATCH] Use GtkPrint instead of GnomePrint when it's available. Fixes bug #348422 2006-07-23 Carlos Garcia Campos * configure.ac: * shell/Makefile.am: * shell/ev-job-queue.c: * shell/ev-jobs.[ch]: * shell/ev-sidebar-links.c: * shell/ev-window.[ch]: Use GtkPrint instead of GnomePrint when it's available. Fixes bug #348422 --- ChangeLog | 12 ++ configure.ac | 65 ++++-- shell/Makefile.am | 3 +- shell/ev-job-queue.c | 16 +- shell/ev-jobs.c | 113 ++++++++++ shell/ev-jobs.h | 44 +++- shell/ev-sidebar-links.c | 2 +- shell/ev-window.c | 439 ++++++++++++++++++++++++++++++++------- shell/ev-window.h | 2 +- 9 files changed, 589 insertions(+), 107 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00b55896..9f2cc8cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-07-23 Carlos Garcia Campos + + * configure.ac: + * shell/Makefile.am: + * shell/ev-job-queue.c: + * shell/ev-jobs.[ch]: + * shell/ev-sidebar-links.c: + * shell/ev-window.[ch]: + + Use GtkPrint instead of GnomePrint when it's available. Fixes bug + #348422 + 2006-07-17 Carlos Garcia Campos * data/evince-toolbar.xml: Add preview toolbar (hidden by default) diff --git a/configure.ac b/configure.ac index 7e061053..6f8e3752 100644 --- a/configure.ac +++ b/configure.ac @@ -49,6 +49,8 @@ KEYRING_REQUIRED=0.4.0 LIBGNOMEUI_REQUIRED=2.14.0 LIBGNOMEPRINTUI_REQUIRED=2.6.0 +GTK_PRINT_REQUIRED=2.10.0 + PKG_CHECK_MODULES(LIB, gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED) PKG_CHECK_MODULES(BACKEND, gtk+-2.0 >= $GTK_REQUIRED gnome-vfs-2.0) PKG_CHECK_MODULES(FRONTEND_CORE, gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED libglade-2.0 poppler-glib >= $POPPLER_REQUIRED) @@ -58,27 +60,54 @@ PKG_CHECK_MODULES(SHELL_CORE, gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGN GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0` AC_SUBST(GLIB_GENMARSHAL) - -dnl ========= Check for libgnomeprintui -AC_ARG_ENABLE(gnome-print, - [AC_HELP_STRING([--disable-gnome-print], [Compile without print support])], - enable_gnome_print="$enableval", - enable_gnome_print=yes) - -if test x$enable_gnome_print = xyes; then - PKG_CHECK_MODULES(GNOME_PRINT, - libgnomeprintui-2.2 >= $LIBGNOMEPRINTUI_REQUIRED, - enable_gnome_print=yes, enable_gnome_print=no) +dnl ========= Print support +AC_ARG_WITH(print, + [AC_HELP_STRING([--with-print=no/gtk/gnome/auto], [Compile with print support [default=auto]])], + PRINT=$withval, + PRINT="auto") + +PKG_CHECK_MODULES(GNOME_PRINT, + libgnomeprintui-2.2 >= $LIBGNOMEPRINTUI_REQUIRED, + enable_gnome_print=yes, enable_gnome_print=no) +PKG_CHECK_MODULES(GTK_PRINT, + gtk+-unix-print-2.0 >= $GTK_PRINT_REQUIRED, + enable_gtk_print=yes, enable_gtk_print=no) +enable_print=no +if test x$PRINT = xgnome -a x$enable_gnome_print = xyes; then + enable_print=gnome +else + if test x$PRINT = xgtk -a x$enable_gtk_print = xyes; then + enable_print=gtk + else + if test x$PRINT = xauto; then + if test x$enable_gtk_print = xyes; then + enable_print=gtk + else + if test x$enable_gnome_print = xyes; then + enable_print=gnome + fi + fi + fi + fi fi -AC_SUBST(GNOME_PRINT_CFLAGS) -AC_SUBST(GNOME_PRINT_LIBS) +if test x$enable_print = xgnome; then + AC_SUBST(GNOME_PRINT_CFLAGS) + AC_SUBST(GNOME_PRINT_LIBS) + AC_DEFINE([WITH_GNOME_PRINT],[1],[Enable GNOME Print Support.]) + AC_DEFINE([WITH_PRINT],[1],[Enable Print Support.]) +fi -if test x$enable_gnome_print = xyes; then - AC_DEFINE([WITH_GNOME_PRINT],[1],[Enable Print Support.]) -fi +if test x$enable_print = xgtk; then + AC_SUBST(GTK_PRINT_CFLAGS) + AC_SUBST(GTK_PRINT_LIBS) + AC_DEFINE([WITH_GTK_PRINT],[1],[Enable GTK Print Support.]) + AC_DEFINE([WITH_PRINT],[1],[Enable Print Support.]) +fi + +AM_CONDITIONAL(WITH_GNOME_PRINT, test x$enable_print = xgnome) +AM_CONDITIONAL(WITH_GTK_PRINT, test x$enable_print = xgtk) -AM_CONDITIONAL(WITH_GNOME_PRINT, test x$enable_gnome_print = xyes) dnl ========= Check for DBUS PKG_CHECK_MODULES([DBUS], [dbus-glib-1 >= $DBUS_GLIB_REQUIRED], @@ -360,7 +389,7 @@ AC_OUTPUT echo " Configure summary: - Print Support......: $enable_gnome_print + Print Support......: $enable_print DBUS Support.......: $enable_dbus Nautilus Plugin....: $HAVE_NAUTILUS diff --git a/shell/Makefile.am b/shell/Makefile.am index 4ce5bce8..4a6c5de5 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -12,7 +12,8 @@ INCLUDES= \ $(SHELL_CFLAGS) \ $(WARN_CFLAGS) \ $(DISABLE_DEPRECATED) \ - $(GNOME_PRINT_CFLAGS) + $(GNOME_PRINT_CFLAGS) \ + $(GTK_PRINT_CFLAGS) bin_PROGRAMS=evince diff --git a/shell/ev-job-queue.c b/shell/ev-job-queue.c index c8c51d8c..09e7bb89 100644 --- a/shell/ev-job-queue.c +++ b/shell/ev-job-queue.c @@ -14,6 +14,7 @@ static GQueue *thumbnail_queue_high = NULL; static GQueue *thumbnail_queue_low = NULL; static GQueue *xfer_queue = NULL; static GQueue *fonts_queue = NULL; +static GQueue *print_queue = NULL; /* Queues used for backends supporting EvAsyncRender interface, they are executed on the main thread */ @@ -101,6 +102,8 @@ handle_job (EvJob *job) ev_job_render_run (EV_JOB_RENDER (job)); else if (EV_IS_JOB_FONTS (job)) ev_job_fonts_run (EV_JOB_FONTS (job)); + else if (EV_IS_JOB_PRINT (job)) + ev_job_print_run (EV_JOB_PRINT (job)); if (!EV_JOB (job)->async) { /* We let the idle own a ref, as we (the queue) are done with the job. */ @@ -144,6 +147,10 @@ search_for_jobs_unlocked (void) if (job) return job; + job = (EvJob *) g_queue_pop_head (print_queue); + if (job) + return job; + return NULL; } @@ -156,7 +163,8 @@ no_jobs_available_unlocked (void) && g_queue_is_empty (xfer_queue) && g_queue_is_empty (thumbnail_queue_high) && g_queue_is_empty (thumbnail_queue_low) - && g_queue_is_empty (fonts_queue); + && g_queue_is_empty (fonts_queue) + && g_queue_is_empty (print_queue); } /* the thread mainloop function */ @@ -220,6 +228,7 @@ ev_job_queue_init (void) thumbnail_queue_high = g_queue_new (); thumbnail_queue_low = g_queue_new (); fonts_queue = g_queue_new (); + print_queue = g_queue_new (); g_thread_create (ev_render_thread, NULL, FALSE, NULL); @@ -256,6 +265,9 @@ find_queue (EvJob *job, } else if (EV_IS_JOB_FONTS (job)) { /* the priority doesn't effect fonts */ return fonts_queue; + } else if (EV_IS_JOB_PRINT (job)) { + /* the priority doesn't effect print */ + return print_queue; } } @@ -395,6 +407,8 @@ ev_job_queue_remove_job (EvJob *job) retval = remove_job_from_queue_locked (xfer_queue, job); } else if (EV_IS_JOB_FONTS (job)) { retval = remove_job_from_queue_locked (fonts_queue, job); + } else if (EV_IS_JOB_PRINT (job)) { + retval = remove_job_from_queue_locked (print_queue, job); } else { g_assert_not_reached (); } diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index bc0a15ac..a2f54034 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -7,7 +7,10 @@ #include "ev-document-fonts.h" #include "ev-selection.h" #include "ev-async-renderer.h" +#include "ev-ps-exporter.h" +#include +#include #include #include #include @@ -23,6 +26,8 @@ static void ev_job_thumbnail_init (EvJobThumbnail *job); static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class); static void ev_job_xfer_init (EvJobXfer *job); static void ev_job_xfer_class_init (EvJobXferClass *class); +static void ev_job_print_init (EvJobPrint *job); +static void ev_job_print_class_init (EvJobPrintClass *class); enum { @@ -38,6 +43,7 @@ G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobXfer, ev_job_xfer, EV_TYPE_JOB) +G_DEFINE_TYPE (EvJobPrint, ev_job_print, EV_TYPE_JOB) static void ev_job_init (EvJob *job) { /* Do Nothing */ } @@ -173,6 +179,39 @@ ev_job_thumbnail_class_init (EvJobThumbnailClass *class) oclass->dispose = ev_job_thumbnail_dispose; } +static void ev_job_print_init (EvJobPrint *job) { /* Do Nothing */ } + +static void +ev_job_print_dispose (GObject *object) +{ + EvJobPrint *job; + + job = EV_JOB_PRINT (object); + + if (job->temp_file) { + g_unlink (job->temp_file); + g_free (job->temp_file); + job->temp_file = NULL; + } + + if (job->error) { + g_error_free (job->error); + job->error = NULL; + } + + (* G_OBJECT_CLASS (ev_job_print_parent_class)->dispose) (object); +} + +static void +ev_job_print_class_init (EvJobPrintClass *class) +{ + GObjectClass *oclass; + + oclass = G_OBJECT_CLASS (class); + + oclass->dispose = ev_job_print_dispose; +} + /* Public functions */ void ev_job_finished (EvJob *job) @@ -480,3 +519,77 @@ ev_job_xfer_run (EvJobXfer *job) return; } +EvJob * +ev_job_print_new (EvDocument *document, + gdouble width, + gdouble height) +{ + EvJobPrint *job; + + job = g_object_new (EV_TYPE_JOB_PRINT, NULL); + + EV_JOB (job)->document = g_object_ref (document); + + job->temp_file = NULL; + job->error = NULL; + + job->width = width; + job->height = height; + + return EV_JOB (job); +} + +void +ev_job_print_run (EvJobPrint *job) +{ + EvDocument *document = EV_JOB (job)->document; + gint fd; + gint last_page; + gint i; + + g_return_if_fail (EV_IS_JOB_PRINT (job)); + + if (job->temp_file) + g_free (job->temp_file); + job->temp_file = NULL; + + if (job->error) + g_error_free (job->error); + job->error = NULL; + + fd = g_file_open_tmp ("evince_print.ps.XXXXXX", &job->temp_file, &job->error); + if (fd <= -1) { + EV_JOB (job)->finished = TRUE; + return; + } + + last_page = ev_document_get_n_pages (document) - 1; + + ev_document_doc_mutex_lock (); + ev_ps_exporter_begin (EV_PS_EXPORTER (document), + job->temp_file, + MIN (0, last_page), + MAX (0, last_page), + job->width, job->height, FALSE); + ev_document_doc_mutex_unlock (); + + for (i = 0; i <= last_page; i++) { + EvRenderContext *rc; + + rc = ev_render_context_new (0, i, 1.0); + + ev_document_doc_mutex_lock (); + ev_ps_exporter_do_page (EV_PS_EXPORTER (document), rc); + ev_document_doc_mutex_unlock (); + + g_object_unref (rc); + } + + ev_document_doc_mutex_lock (); + ev_ps_exporter_end (EV_PS_EXPORTER (document)); + ev_document_doc_mutex_unlock (); + + close (fd); + + EV_JOB (job)->finished = TRUE; +} diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index d57f9c02..22eeb07e 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -44,6 +44,9 @@ typedef struct _EvJobFontsClass EvJobFontsClass; typedef struct _EvJobXfer EvJobXfer; typedef struct _EvJobXferClass EvJobXferClass; +typedef struct _EvJobPrint EvJobPrint; +typedef struct _EvJobPrintClass EvJobPrintClass; + #define EV_TYPE_JOB (ev_job_get_type()) #define EV_JOB(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB, EvJob)) #define EV_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB, EvJobClass)) @@ -74,6 +77,11 @@ typedef struct _EvJobXferClass EvJobXferClass; #define EV_JOB_XFER_CLASS(klass) (G_TYPE_CHACK_CLASS_CAST((klass), EV_TYPE_JOB_XFER, EvJobXferClass)) #define EV_IS_JOB_XFER(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_XFER)) +#define EV_TYPE_JOB_PRINT (ev_job_print_get_type()) +#define EV_JOB_PRINT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_PRINT, EvJobPrint)) +#define EV_JOB_PRINT_CLASS(klass) (G_TYPE_CHACK_CLASS_CAST((klass), EV_TYPE_JOB_PRINT, EvJobPrintClass)) +#define EV_IS_JOB_PRINT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_PRINT)) + typedef enum { EV_JOB_PRIORITY_LOW, EV_JOB_PRIORITY_HIGH, @@ -175,17 +183,32 @@ struct _EvJobXferClass EvJobClass parent_class; }; +struct _EvJobPrint +{ + EvJob parent; + + GError *error; + gchar *temp_file; + gdouble width; + gdouble height; +}; + +struct _EvJobPrintClass +{ + EvJobClass parent_class; +}; + /* Base job class */ -GType ev_job_get_type (void); +GType ev_job_get_type (void) G_GNUC_CONST; void ev_job_finished (EvJob *job); /* EvJobLinks */ -GType ev_job_links_get_type (void); +GType ev_job_links_get_type (void) G_GNUC_CONST; EvJob *ev_job_links_new (EvDocument *document); void ev_job_links_run (EvJobLinks *thumbnail); /* EvJobRender */ -GType ev_job_render_get_type (void); +GType ev_job_render_get_type (void) G_GNUC_CONST; EvJob *ev_job_render_new (EvDocument *document, EvRenderContext *rc, gint width, @@ -199,7 +222,7 @@ EvJob *ev_job_render_new (EvDocument *document, void ev_job_render_run (EvJobRender *thumbnail); /* EvJobThumbnail */ -GType ev_job_thumbnail_get_type (void); +GType ev_job_thumbnail_get_type (void) G_GNUC_CONST; EvJob *ev_job_thumbnail_new (EvDocument *document, gint page, int rotation, @@ -207,16 +230,23 @@ EvJob *ev_job_thumbnail_new (EvDocument *document, void ev_job_thumbnail_run (EvJobThumbnail *thumbnail); /* EvJobFonts */ -GType ev_job_fonts_get_type (void); +GType ev_job_fonts_get_type (void) G_GNUC_CONST; EvJob *ev_job_fonts_new (EvDocument *document); void ev_job_fonts_run (EvJobFonts *fonts); /* EvJobXfer */ -GType ev_job_xfer_get_type (void); +GType ev_job_xfer_get_type (void) G_GNUC_CONST; EvJob *ev_job_xfer_new (const gchar *uri, EvLinkDest *dest, EvWindowRunMode mode); -void ev_job_xfer_run (EvJobXfer *xfer); +void ev_job_xfer_run (EvJobXfer *xfer); + +/* EvJobPrint */ +GType ev_job_print_get_type (void) G_GNUC_CONST; +EvJob *ev_job_print_new (EvDocument *document, + gdouble width, + gdouble height); +void ev_job_print_run (EvJobPrint *print); G_END_DECLS diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c index 5a139aac..9df89cd4 100644 --- a/shell/ev-sidebar-links.c +++ b/shell/ev-sidebar-links.c @@ -332,7 +332,7 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar) window = gtk_widget_get_toplevel (GTK_WIDGET (sidebar)); if (EV_IS_WINDOW (window)) { -#ifdef WITH_GNOME_PRINT +#ifdef WITH_PRINT ev_window_print_range (EV_WINDOW (window), first_page, last_page); #endif diff --git a/shell/ev-window.c b/shell/ev-window.c index 9eab28a3..02422e23 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -70,6 +70,10 @@ #include #endif +#ifdef WITH_GTK_PRINT +#include +#endif + #include #include @@ -115,7 +119,7 @@ struct _EvWindowPrivate { /* Dialogs */ GtkWidget *properties; -#ifdef WITH_GNOME_PRINT +#ifdef WITH_PRINT GtkWidget *print_dialog; #endif GtkWidget *password_dialog; @@ -155,6 +159,14 @@ struct _EvWindowPrivate { #ifdef WITH_GNOME_PRINT GnomePrintJob *print_job; #endif + +#ifdef WITH_GTK_PRINT + EvJob *print_job; + GtkPrintJob *gtk_print_job; + GtkPrinter *printer; + GtkPrintSettings *print_settings; + GtkPageSetup *print_page_setup; +#endif }; static const GtkTargetEntry ev_drop_types[] = { @@ -186,8 +198,10 @@ static void ev_window_sidebar_visibility_changed_cb (EvSidebar *ev_si EvWindow *ev_window); static void ev_window_set_page_mode (EvWindow *window, EvWindowPageMode page_mode); -static void ev_window_xfer_job_cb (EvJobXfer *job, - gpointer data); +static void ev_window_xfer_job_cb (EvJobXfer *job, + gpointer data); +static void ev_window_print_job_cb (EvJobPrint *job, + EvWindow *window); static void ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window); @@ -296,7 +310,7 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) { ok_to_print = FALSE; } -#ifndef WITH_GNOME_PRINT +#ifndef WITH_PRINT ok_to_print = FALSE; #endif g_object_unref (client); @@ -985,16 +999,19 @@ ev_window_close_dialogs (EvWindow *ev_window) if (ev_window->priv->password_dialog) gtk_widget_destroy (ev_window->priv->password_dialog); ev_window->priv->password_dialog = NULL; + +#ifdef WITH_PRINT + if (ev_window->priv->print_dialog) + gtk_widget_destroy (ev_window->priv->print_dialog); + ev_window->priv->print_dialog = NULL; +#endif #ifdef WITH_GNOME_PRINT - if (ev_window->priv->print_dialog) { - gtk_widget_destroy (ev_window->priv->print_dialog); + if (ev_window->priv->print_job) g_object_unref (ev_window->priv->print_job); - } - ev_window->priv->print_dialog = NULL; ev_window->priv->print_job = NULL; #endif - + if (ev_window->priv->properties) gtk_widget_destroy (ev_window->priv->properties); ev_window->priv->properties = NULL; @@ -1181,85 +1198,307 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) gtk_widget_show (fc); } +#ifdef WITH_GTK_PRINT static void -ev_window_print (EvWindow *window) +ev_window_clear_print_job (EvWindow *window) { - EvPageCache *page_cache; - int last_page; + if (window->priv->print_job) { + if (!window->priv->print_job->finished) + ev_job_queue_remove_job (window->priv->print_job); - page_cache = ev_page_cache_get (window->priv->document); - last_page = ev_page_cache_get_n_pages (page_cache); + 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; + } +} -#ifdef WITH_GNOME_PRINT - ev_window_print_range (window, 1, last_page); -#endif +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; + GError *error = NULL; + + if (window->priv->gtk_print_job) + g_object_unref (window->priv->gtk_print_job); + + job = gtk_print_job_new ("evince-print", + window->priv->printer, + window->priv->print_settings, + window->priv->print_page_setup); + + 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) +{ + EvBackend document_type; + gboolean export_to_ps = TRUE; + + 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))); + + document_type = ev_document_factory_get_backend (window->priv->document); + switch (document_type) { + case EV_BACKEND_PDF: + export_to_ps = !gtk_printer_accepts_pdf (window->priv->printer); + break; + case EV_BACKEND_PS: + export_to_ps = FALSE; + break; + default: + export_to_ps = TRUE; + break; + } + + if ((export_to_ps || document_type == EV_BACKEND_PS) && + !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; + } + + if (export_to_ps) { + EvPageCache *page_cache; + gint width; + gint height; + + ev_window_clear_print_job (window); + + page_cache = ev_page_cache_get (window->priv->document); + ev_page_cache_get_size (page_cache, + ev_page_cache_get_current_page (page_cache), + 0, 1.0, &width, &height); + + window->priv->print_job = + ev_job_print_new (window->priv->document, + (gdouble)width, + (gdouble)height); + 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); + } else { + gchar *filename; + + filename = g_filename_from_uri (window->priv->uri, NULL, NULL); + ev_window_print_send (window, filename); + g_free (filename); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); + window->priv->print_dialog = NULL; + + return TRUE; +} + +void +ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) +{ + GtkWidget *dialog; + EvPageCache *page_cache; + gint current_page; + gint document_last_page; + + g_return_if_fail (EV_IS_WINDOW (ev_window)); + g_return_if_fail (ev_window->priv->document != NULL); + + if (ev_window->priv->print_dialog) { + gtk_window_present (GTK_WINDOW (ev_window->priv->print_dialog)); + return; + } + + page_cache = ev_page_cache_get (ev_window->priv->document); + current_page = ev_page_cache_get_current_page (page_cache); + document_last_page = ev_page_cache_get_n_pages (page_cache); + + + if (!ev_window->priv->print_settings) + ev_window->priv->print_settings = gtk_print_settings_new (); + + if (first_page != 1 && last_page != document_last_page) { + GtkPageRange range; + + range.start = first_page; + range.end = last_page; + + gtk_print_settings_set_print_pages (ev_window->priv->print_settings, + GTK_PRINT_PAGES_RANGES); + gtk_print_settings_set_page_ranges (ev_window->priv->print_settings, + &range, 1); + } + + dialog = gtk_print_unix_dialog_new (_("Print"), GTK_WINDOW (ev_window)); + ev_window->priv->print_dialog = dialog; + gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog), + current_page); + + gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog), + ev_window->priv->print_settings); + + if (ev_window->priv->print_page_setup) + gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog), + ev_window->priv->print_page_setup); + + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (ev_window_print_dialog_response_cb), + ev_window); + + gtk_widget_show (dialog); +} +#endif /* WITH_GTK_PRINT */ #ifdef WITH_GNOME_PRINT static gboolean -ev_window_print_dialog_response_cb (GtkDialog *print_dialog, gint response, gpointer data) +ev_window_print_dialog_response_cb (GtkDialog *print_dialog, + gint response, + EvWindow *ev_window) { - EvWindow *ev_window = EV_WINDOW (data); - EvPrintJob *print_job; - GnomePrintConfig *config; + EvPrintJob *print_job; + GnomePrintConfig *config; - if (response != GNOME_PRINT_DIALOG_RESPONSE_PRINT) { - gtk_widget_destroy (GTK_WIDGET (print_dialog)); - ev_window->priv->print_dialog = NULL; - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; - return FALSE; - } + if (response != GNOME_PRINT_DIALOG_RESPONSE_PRINT) { + gtk_widget_destroy (GTK_WIDGET (print_dialog)); + ev_window->priv->print_dialog = NULL; + g_object_unref (ev_window->priv->print_job); + ev_window->priv->print_job = NULL; + + return FALSE; + } - config = gnome_print_dialog_get_config (GNOME_PRINT_DIALOG (print_dialog)); - - /* FIXME: Change this when we have the first backend - * that can print more than postscript - */ - if (using_pdf_printer (config)) { - GtkWidget *dialog; - dialog = gtk_message_dialog_new (GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("Generating PDF is not supported")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - return FALSE; - } else if (!using_postscript_printer (config)) { - GtkWidget *dialog; - - 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_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - return FALSE; - } + config = gnome_print_dialog_get_config (GNOME_PRINT_DIALOG (print_dialog)); - save_print_config_to_file (config); + /* FIXME: Change this when we have the first backend + * that can print more than postscript + */ + if (using_pdf_printer (config)) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (print_dialog), GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + _("Generating PDF is not supported")); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + return FALSE; + } else if (!using_postscript_printer (config)) { + GtkWidget *dialog; + + 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_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + return FALSE; + } + + save_print_config_to_file (config); - print_job = g_object_new (EV_TYPE_PRINT_JOB, - "gnome_print_job", ev_window->priv->print_job, - "document", ev_window->priv->document, - "print_dialog", print_dialog, - NULL); + print_job = g_object_new (EV_TYPE_PRINT_JOB, + "gnome_print_job", ev_window->priv->print_job, + "document", ev_window->priv->document, + "print_dialog", print_dialog, + NULL); - if (print_job != NULL) { - ev_print_job_print (print_job, GTK_WINDOW (ev_window)); - g_object_unref (print_job); - } + if (print_job != NULL) { + ev_print_job_print (print_job, GTK_WINDOW (ev_window)); + g_object_unref (print_job); + } - g_object_unref (config); + g_object_unref (config); - gtk_widget_destroy (GTK_WIDGET (print_dialog)); - ev_window->priv->print_dialog = NULL; - g_object_unref (ev_window->priv->print_job); - ev_window->priv->print_job = NULL; + gtk_widget_destroy (GTK_WIDGET (print_dialog)); + ev_window->priv->print_dialog = NULL; + g_object_unref (ev_window->priv->print_job); + ev_window->priv->print_job = NULL; - return FALSE; + return FALSE; } void @@ -1276,11 +1515,16 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) if (ev_window->priv->print_job == NULL) ev_window->priv->print_job = gnome_print_job_new (config); - if (ev_window->priv->print_dialog == NULL) - ev_window->priv->print_dialog = gnome_print_dialog_new (ev_window->priv->print_job, (guchar *) _("Print"), - (GNOME_PRINT_DIALOG_RANGE | - GNOME_PRINT_DIALOG_COPIES)); - gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->print_dialog), GTK_WINDOW (ev_window)); + if (ev_window->priv->print_dialog == NULL) { + ev_window->priv->print_dialog = + gnome_print_dialog_new (ev_window->priv->print_job, + (guchar *) _("Print"), + (GNOME_PRINT_DIALOG_RANGE | + GNOME_PRINT_DIALOG_COPIES)); + } + + gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->print_dialog), + GTK_WINDOW (ev_window)); g_object_unref (config); pages_label = g_strconcat (_("Pages"), " ", NULL); @@ -1295,12 +1539,27 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) GNOME_PRINT_DIALOG_RESPONSE_PREVIEW, FALSE); - g_signal_connect (G_OBJECT (ev_window->priv->print_dialog), "response", G_CALLBACK (ev_window_print_dialog_response_cb), ev_window); + g_signal_connect (G_OBJECT (ev_window->priv->print_dialog), "response", + G_CALLBACK (ev_window_print_dialog_response_cb), + ev_window); gtk_widget_show (ev_window->priv->print_dialog); - return; } #endif /* WITH_GNOME_PRINT */ - + +static void +ev_window_print (EvWindow *window) +{ + EvPageCache *page_cache; + gint last_page; + + page_cache = ev_page_cache_get (window->priv->document); + last_page = ev_page_cache_get_n_pages (page_cache); + +#ifdef WITH_PRINT + ev_window_print_range (window, 1, last_page); +#endif +} + static void ev_window_cmd_file_print (GtkAction *action, EvWindow *ev_window) { @@ -2765,6 +3024,30 @@ ev_window_dispose (GObject *object) ev_window_close_dialogs (window); +#ifdef WITH_GTK_PRINT + ev_window_clear_print_job (window); + + if (window->priv->gtk_print_job) { + g_object_unref (window->priv->gtk_print_job); + window->priv->gtk_print_job = NULL; + } + + if (window->priv->printer) { + g_object_unref (window->priv->printer); + window->priv->printer = NULL; + } + + if (window->priv->print_settings) { + g_object_unref (window->priv->print_settings); + window->priv->print_settings = NULL; + } + + if (window->priv->print_page_setup) { + g_object_unref (window->priv->print_page_setup); + window->priv->print_page_setup = NULL; + } +#endif + if (priv->link) { g_object_unref (priv->link); priv->link = NULL; diff --git a/shell/ev-window.h b/shell/ev-window.h index d2d58463..9c8d28f3 100644 --- a/shell/ev-window.h +++ b/shell/ev-window.h @@ -69,7 +69,7 @@ void ev_window_open_uri (EvWindow *ev_window, void ev_window_goto_dest (EvWindow *ev_window, EvLinkDest *dest); gboolean ev_window_is_empty (const EvWindow *ev_window); -#ifdef WITH_GNOME_PRINT +#ifdef WITH_PRINT void ev_window_print_range (EvWindow *ev_window, int first_page, int last_page); -- 2.43.5