X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-jobs.c;h=416c788fd65839cf7f4995ff3f54540e29faeb70;hb=3f9b326b1e7351aeb08dc70ab78f4fcfda167318;hp=e9f29eb681949ede515e4cf9688bfd1a64d80716;hpb=363996497c9b439597d46f002e995055e368d7a8;p=evince.git diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index e9f29eb6..416c788f 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -7,7 +7,11 @@ #include "ev-document-fonts.h" #include "ev-selection.h" #include "ev-async-renderer.h" +#include "ev-ps-exporter.h" +#include "ev-window.h" +#include +#include #include #include #include @@ -23,6 +27,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 +44,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 +180,45 @@ 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; + } + + if (job->ranges) { + g_free (job->ranges); + job->ranges = NULL; + job->n_ranges = 0; + } + + (* 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) @@ -409,7 +455,7 @@ ev_job_xfer_class_init (EvJobXferClass *class) EvJob * -ev_job_xfer_new (const gchar *uri, EvLinkDest *dest) +ev_job_xfer_new (const gchar *uri, EvLinkDest *dest, EvWindowRunMode mode) { EvJobXfer *job; @@ -419,6 +465,8 @@ ev_job_xfer_new (const gchar *uri, EvLinkDest *dest) if (dest) job->dest = g_object_ref (dest); + job->mode = mode; + return EV_JOB (job); } @@ -434,6 +482,17 @@ ev_job_xfer_run (EvJobXfer *job) g_error_free (job->error); job->error = NULL; } + + /* This job may already have a document even if the job didn't complete + because, e.g., a password is required - if so, just reload rather than + creating a new instance */ + if (EV_JOB (job)->document) { + ev_document_load (EV_JOB (job)->document, + job->local_uri ? job->local_uri : job->uri, + &job->error); + EV_JOB (job)->finished = TRUE; + return; + } source_uri = gnome_vfs_uri_new (job->uri); if (!gnome_vfs_uri_is_local (source_uri) && !job->local_uri) { @@ -467,3 +526,140 @@ ev_job_xfer_run (EvJobXfer *job) return; } +EvJob * +ev_job_print_new (EvDocument *document, + EvPrintRange *ranges, + gint n_ranges, + 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->ranges = ranges; + job->n_ranges = n_ranges; + + job->width = width; + job->height = height; + + 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)); + + 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; + } + + 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 (first_page, last_page), + MAX (first_page, last_page), + job->width, job->height, FALSE); + ev_document_doc_mutex_unlock (); + + for (i = first_page; i <= last_page; i++) { + EvRenderContext *rc; + + 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 (); + + 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; +}