]> www.fi.muni.cz Git - evince.git/commitdiff
Use GtkPrint instead of GnomePrint when it's available. Fixes bug #348422
authorCarlos Garcia Campos <carlosgc@gnome.org>
Sun, 23 Jul 2006 19:59:43 +0000 (19:59 +0000)
committerCarlos Garcia Campos <carlosgc@src.gnome.org>
Sun, 23 Jul 2006 19:59:43 +0000 (19:59 +0000)
2006-07-23  Carlos Garcia Campos  <carlosgc@gnome.org>
* 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
configure.ac
shell/Makefile.am
shell/ev-job-queue.c
shell/ev-jobs.c
shell/ev-jobs.h
shell/ev-sidebar-links.c
shell/ev-window.c
shell/ev-window.h

index 00b55896cb085f66220d4be0a71ff16e0ba054e5..9f2cc8cff772690255ff660284a80eb5f38b6a0a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-07-23  Carlos Garcia Campos  <carlosgc@gnome.org>
+
+       * 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  <carlosgc@gnome.org>
 
        * data/evince-toolbar.xml: Add preview toolbar (hidden by default)
index 7e06105372d422b7b6631a8a6db69221fda84162..6f8e375293ae3086a9ff94153aae2ed3d2cedb75 100644 (file)
@@ -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
 
index 4ce5bce8147b418d20603dbfa55e23765808cdaa..4a6c5de5e7c44e0e411cb684c1fea1b12414e52e 100644 (file)
@@ -12,7 +12,8 @@ INCLUDES=                                             \
        $(SHELL_CFLAGS)                                 \
        $(WARN_CFLAGS)                                  \
        $(DISABLE_DEPRECATED)                           \
-       $(GNOME_PRINT_CFLAGS)
+       $(GNOME_PRINT_CFLAGS)                           \
+       $(GTK_PRINT_CFLAGS)
 
 bin_PROGRAMS=evince
 
index c8c51d8cc15f1cf0fb0304ffa79bd364042d934e..09e7bb895606c190955b2b1cc5c75d60c7caa510 100644 (file)
@@ -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 ();
                }
index bc0a15ac6351193beea5a160ea0c8b42119bb1ca..a2f54034e8bcce44a3469619473503acb58e1dd2 100644 (file)
@@ -7,7 +7,10 @@
 #include "ev-document-fonts.h"
 #include "ev-selection.h"
 #include "ev-async-renderer.h"
+#include "ev-ps-exporter.h"
 
+#include <glib/gstdio.h>
+#include <unistd.h>
 #include <libgnomevfs/gnome-vfs-uri.h>
 #include <libgnomevfs/gnome-vfs-utils.h>
 #include <libgnomevfs/gnome-vfs-ops.h>
@@ -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;
+}
index d57f9c02ba45022cd9167c126250b982c4305130..22eeb07e53bdde2fc7582f4840f1df263481e77c 100644 (file)
@@ -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
 
index 5a139aac6bb5d6867fe37f35a15c37a504c4a22f..9df89cd49cb1c79d10923ffb55380257cd11476a 100644 (file)
@@ -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
index 9eab28a3a40d7a2147e28f312665a5b3162e88a9..02422e231538ba3474865e42fc64063b4f46dbc8 100644 (file)
 #include <libgnomeprintui/gnome-print-dialog.h>
 #endif
 
+#ifdef WITH_GTK_PRINT
+#include <gtk/gtkprintunixdialog.h>
+#endif
+
 #include <poppler.h>
 
 #include <glib/gi18n.h>
@@ -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;
index d2d58463c670d6a9e5c1d076ea94eb7571e21615..9c8d28f37bccf2e0c6a71644bce1dfc922d0c7b5 100644 (file)
@@ -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);