From 19eb9bd4a84d54e7af3eaf8c8f58037bf5437a97 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Wed, 26 Jul 2006 15:27:37 +0000 Subject: [PATCH] GtkPrintJob doesn't support print ranges or current page, so we export to 2006-07-26 Carlos Garcia Campos * shell/ev-jobs.[ch]: * shell/ev-sidebar-links.c: * shell/ev-window.[ch]: GtkPrintJob doesn't support print ranges or current page, so we export to a ps file now when printing ranges or current page. --- ChangeLog | 9 ++++ shell/ev-jobs.c | 88 ++++++++++++++++++++++++++++++++++---- shell/ev-jobs.h | 4 ++ shell/ev-sidebar-links.c | 2 +- shell/ev-window.c | 92 +++++++++++++++++++++++++++++++--------- shell/ev-window.h | 5 +++ 6 files changed, 169 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9aa4d01..1679877f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-07-26 Carlos Garcia Campos + + * shell/ev-jobs.[ch]: + * shell/ev-sidebar-links.c: + * shell/ev-window.[ch]: + + GtkPrintJob doesn't support print ranges or current page, so we export + to a ps file now when printing ranges or current page. + 2006-07-26 Nickolay V. Shmyrev * pdf/ev-poppler.cc: diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index a2f54034..416c788f 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -8,6 +8,7 @@ #include "ev-selection.h" #include "ev-async-renderer.h" #include "ev-ps-exporter.h" +#include "ev-window.h" #include #include @@ -199,6 +200,12 @@ ev_job_print_dispose (GObject *object) job->error = NULL; } + if (job->ranges) { + g_free (job->ranges); + job->ranges = NULL; + job->n_ranges = 0; + } + (* G_OBJECT_CLASS (ev_job_print_parent_class)->dispose) (object); } @@ -520,9 +527,11 @@ ev_job_xfer_run (EvJobXfer *job) } EvJob * -ev_job_print_new (EvDocument *document, - gdouble width, - gdouble height) +ev_job_print_new (EvDocument *document, + EvPrintRange *ranges, + gint n_ranges, + gdouble width, + gdouble height) { EvJobPrint *job; @@ -532,6 +541,9 @@ ev_job_print_new (EvDocument *document, job->temp_file = NULL; job->error = NULL; + + job->ranges = ranges; + job->n_ranges = n_ranges; job->width = width; job->height = height; @@ -539,12 +551,65 @@ ev_job_print_new (EvDocument *document, return EV_JOB (job); } +static gint +ev_print_job_get_first_page (EvJobPrint *job) +{ + gint i; + gint first_page = G_MAXINT; + + if (job->n_ranges == 0) + return 0; + + for (i = 0; i < job->n_ranges; i++) { + if (job->ranges[i].start < first_page) + first_page = job->ranges[i].start; + } + + return MAX (0, first_page); +} + +static gint +ev_print_job_get_last_page (EvJobPrint *job) +{ + gint i; + gint last_page = G_MININT; + gint max_page; + + max_page = ev_document_get_n_pages (EV_JOB (job)->document) - 1; + + if (job->n_ranges == 0) + return max_page; + + for (i = 0; i < job->n_ranges; i++) { + if (job->ranges[i].end > last_page) + last_page = job->ranges[i].end; + } + + return MIN (max_page, last_page); +} + +static gboolean +ev_print_job_print_page (EvJobPrint *job, + gint page) +{ + gint i; + + for (i = 0; i < job->n_ranges; i++) { + if (page >= job->ranges[i].start && + page <= job->ranges[i].end) + return TRUE; + } + + return FALSE; +} + void ev_job_print_run (EvJobPrint *job) { EvDocument *document = EV_JOB (job)->document; gint fd; gint last_page; + gint first_page; gint i; g_return_if_fail (EV_IS_JOB_PRINT (job)); @@ -563,21 +628,26 @@ ev_job_print_run (EvJobPrint *job) return; } - last_page = ev_document_get_n_pages (document) - 1; - + first_page = ev_print_job_get_first_page (job); + last_page = ev_print_job_get_last_page (job); + ev_document_doc_mutex_lock (); ev_ps_exporter_begin (EV_PS_EXPORTER (document), job->temp_file, - MIN (0, last_page), - MAX (0, last_page), + MIN (first_page, last_page), + MAX (first_page, last_page), job->width, job->height, FALSE); ev_document_doc_mutex_unlock (); - for (i = 0; i <= last_page; i++) { + for (i = first_page; i <= last_page; i++) { EvRenderContext *rc; - rc = ev_render_context_new (0, i, 1.0); + if (job->n_ranges > 0 && + !ev_print_job_print_page (job, i)) + continue; + 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 (); diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index 22eeb07e..e4497f28 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -189,6 +189,8 @@ struct _EvJobPrint GError *error; gchar *temp_file; + EvPrintRange *ranges; + gint n_ranges; gdouble width; gdouble height; }; @@ -244,6 +246,8 @@ 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, + EvPrintRange *ranges, + gint n_ranges, gdouble width, gdouble height); void ev_job_print_run (EvJobPrint *print); diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c index 9df89cd4..46394019 100644 --- a/shell/ev-sidebar-links.c +++ b/shell/ev-sidebar-links.c @@ -305,7 +305,7 @@ print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar) if (!link) return; - first_page = get_page_from_link (link) + 1; + first_page = get_page_from_link (link); if (first_page == -1) { g_object_unref (link); return; diff --git a/shell/ev-window.c b/shell/ev-window.c index 65d05fd4..6b80ed5c 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -1285,8 +1285,9 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog, gint response, EvWindow *window) { - EvBackend document_type; - gboolean export_to_ps = TRUE; + EvBackend document_type; + gboolean export_to_ps = TRUE; + GtkPrintPages print_pages; if (response != GTK_RESPONSE_OK) { gtk_widget_destroy (GTK_WIDGET (dialog)); @@ -1310,16 +1311,27 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog, 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; + print_pages = gtk_print_settings_get_print_pages (window->priv->print_settings); + + if (print_pages == GTK_PRINT_PAGES_ALL) { + switch (document_type) { + case EV_BACKEND_PDF: + /* Export to ps when printing to file */ + if (gtk_print_settings_has_key (window->priv->print_settings, + GTK_PRINT_SETTINGS_OUTPUT_URI)) { + export_to_ps = TRUE; + } else { + 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) && @@ -1339,21 +1351,52 @@ ev_window_print_dialog_response_cb (GtkDialog *dialog, } if (export_to_ps) { - EvPageCache *page_cache; - gint width; - gint height; + EvPrintRange *ranges = NULL; + EvPageCache *page_cache; + gint n_ranges = 0; + gint current_page; + gint width; + gint height; ev_window_clear_print_job (window); + current_page = + gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog)); + + 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_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); + current_page, + 0, 1.0, + &width, &height); window->priv->print_job = ev_job_print_new (window->priv->document, + ranges, n_ranges, (gdouble)width, (gdouble)height); + g_signal_connect (window->priv->print_job, "finished", G_CALLBACK (ev_window_print_job_cb), window); @@ -1393,15 +1436,15 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) 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) { + if (first_page != 1 || last_page != document_last_page) { GtkPageRange range; - range.start = first_page; - range.end = last_page; + /* Ranges in GtkPrint are 0 - N */ + range.start = first_page - 1; + range.end = last_page - 1; gtk_print_settings_set_print_pages (ev_window->priv->print_settings, GTK_PRINT_PAGES_RANGES); @@ -1411,6 +1454,13 @@ ev_window_print_range (EvWindow *ev_window, int first_page, int last_page) dialog = gtk_print_unix_dialog_new (_("Print"), GTK_WINDOW (ev_window)); ev_window->priv->print_dialog = dialog; + gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog), + GTK_PRINT_CAPABILITY_PAGE_SET | + GTK_PRINT_CAPABILITY_COPIES | + GTK_PRINT_CAPABILITY_COLLATE | + GTK_PRINT_CAPABILITY_REVERSE | + GTK_PRINT_CAPABILITY_SCALE | + GTK_PRINT_CAPABILITY_GENERATE_PS); gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog), current_page); diff --git a/shell/ev-window.h b/shell/ev-window.h index 9c8d28f3..4119965e 100644 --- a/shell/ev-window.h +++ b/shell/ev-window.h @@ -38,6 +38,11 @@ typedef enum { EV_WINDOW_MODE_PREVIEW } EvWindowRunMode; +typedef struct { + gint start; + gint end; +} EvPrintRange; + typedef struct _EvWindow EvWindow; typedef struct _EvWindowClass EvWindowClass; typedef struct _EvWindowPrivate EvWindowPrivate; -- 2.43.5