1 /* this file is part of evince, a gnome document viewer
3 * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
5 * Evince is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * Evince is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22 #include "ev-print-operation.h"
24 #include <gtk/gtkunixprint.h>
25 #include <glib/gi18n.h>
26 #include <glib/gstdio.h>
29 #include "ev-page-cache.h"
30 #include "ev-file-exporter.h"
32 #include "ev-job-scheduler.h"
33 #include "ev-application.h"
34 #include "ev-file-helpers.h"
48 static guint signals[LAST_SIGNAL] = { 0 };
50 struct _EvPrintOperation {
60 struct _EvPrintOperationClass {
61 GObjectClass parent_class;
63 void (* set_current_page) (EvPrintOperation *op,
65 void (* set_print_settings) (EvPrintOperation *op,
66 GtkPrintSettings *print_settings);
67 GtkPrintSettings *(* get_print_settings) (EvPrintOperation *op);
68 void (* set_default_page_setup) (EvPrintOperation *op,
69 GtkPageSetup *page_setup);
70 GtkPageSetup *(* get_default_page_setup) (EvPrintOperation *op);
71 void (* set_job_name) (EvPrintOperation *op,
72 const gchar *job_name);
73 const gchar *(* get_job_name) (EvPrintOperation *op);
74 void (* run) (EvPrintOperation *op,
76 void (* cancel) (EvPrintOperation *op);
77 void (* get_error) (EvPrintOperation *op,
81 void (* done) (EvPrintOperation *op,
82 GtkPrintOperationResult result);
83 void (* begin_print) (EvPrintOperation *op);
84 void (* status_changed) (EvPrintOperation *op);
88 G_DEFINE_ABSTRACT_TYPE (EvPrintOperation, ev_print_operation, G_TYPE_OBJECT)
91 ev_print_operation_finalize (GObject *object)
93 EvPrintOperation *op = EV_PRINT_OPERATION (object);
96 g_object_unref (op->document);
105 (* G_OBJECT_CLASS (ev_print_operation_parent_class)->finalize) (object);
109 ev_print_operation_set_property (GObject *object,
114 EvPrintOperation *op = EV_PRINT_OPERATION (object);
118 op->document = g_value_dup_object (value);
121 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126 ev_print_operation_init (EvPrintOperation *op)
131 ev_print_operation_class_init (EvPrintOperationClass *klass)
133 GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
135 g_object_class->set_property = ev_print_operation_set_property;
136 g_object_class->finalize = ev_print_operation_finalize;
138 g_object_class_install_property (g_object_class,
140 g_param_spec_object ("document",
142 "The document to print",
145 G_PARAM_CONSTRUCT_ONLY));
147 g_signal_new ("done",
148 G_TYPE_FROM_CLASS (g_object_class),
150 G_STRUCT_OFFSET (EvPrintOperationClass, done),
152 g_cclosure_marshal_VOID__ENUM,
154 GTK_TYPE_PRINT_OPERATION_RESULT);
155 signals[BEGIN_PRINT] =
156 g_signal_new ("begin_print",
157 G_TYPE_FROM_CLASS (g_object_class),
159 G_STRUCT_OFFSET (EvPrintOperationClass, begin_print),
161 g_cclosure_marshal_VOID__VOID,
163 signals[STATUS_CHANGED] =
164 g_signal_new ("status_changed",
165 G_TYPE_FROM_CLASS (g_object_class),
167 G_STRUCT_OFFSET (EvPrintOperationClass, status_changed),
169 g_cclosure_marshal_VOID__VOID,
175 ev_print_operation_set_current_page (EvPrintOperation *op,
178 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
180 g_return_if_fail (EV_IS_PRINT_OPERATION (op));
181 g_return_if_fail (current_page >= 0);
183 class->set_current_page (op, current_page);
187 ev_print_operation_set_print_settings (EvPrintOperation *op,
188 GtkPrintSettings *print_settings)
190 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
192 g_return_if_fail (EV_IS_PRINT_OPERATION (op));
193 g_return_if_fail (GTK_IS_PRINT_SETTINGS (print_settings));
195 class->set_print_settings (op, print_settings);
199 ev_print_operation_get_print_settings (EvPrintOperation *op)
201 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
203 g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
205 return class->get_print_settings (op);
209 ev_print_operation_set_default_page_setup (EvPrintOperation *op,
210 GtkPageSetup *page_setup)
212 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
214 g_return_if_fail (EV_IS_PRINT_OPERATION (op));
215 g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup));
217 class->set_default_page_setup (op, page_setup);
221 ev_print_operation_get_default_page_setup (EvPrintOperation *op)
223 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
225 g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
227 return class->get_default_page_setup (op);
231 ev_print_operation_set_job_name (EvPrintOperation *op,
232 const gchar *job_name)
234 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
236 g_return_if_fail (EV_IS_PRINT_OPERATION (op));
237 g_return_if_fail (job_name != NULL);
239 class->set_job_name (op, job_name);
243 ev_print_operation_get_job_name (EvPrintOperation *op)
245 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
247 g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
249 return class->get_job_name (op);
253 ev_print_operation_run (EvPrintOperation *op,
256 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
258 g_return_if_fail (EV_IS_PRINT_OPERATION (op));
260 class->run (op, parent);
264 ev_print_operation_cancel (EvPrintOperation *op)
266 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
268 g_return_if_fail (EV_IS_PRINT_OPERATION (op));
274 ev_print_operation_get_error (EvPrintOperation *op,
277 EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
279 g_return_if_fail (EV_IS_PRINT_OPERATION (op));
281 class->get_error (op, error);
285 ev_print_operation_get_status (EvPrintOperation *op)
287 g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
289 return op->status ? op->status : "";
293 ev_print_operation_get_progress (EvPrintOperation *op)
295 g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), 0.0);
301 ev_print_operation_update_status (EvPrintOperation *op,
306 if (op->status && op->progress == progress)
313 op->status = g_strdup (_("Preparing to print ..."));
314 } else if (page > n_pages) {
315 op->status = g_strdup (_("Finishing..."));
317 op->status = g_strdup_printf (_("Printing page %d of %d..."),
321 op->progress = MIN (1.0, progress);
323 g_signal_emit (op, signals[STATUS_CHANGED], 0);
326 /* Export interface */
327 #define EV_TYPE_PRINT_OPERATION_EXPORT (ev_print_operation_export_get_type())
328 #define EV_PRINT_OPERATION_EXPORT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_EXPORT, EvPrintOperationExport))
329 #define EV_PRINT_OPERATION_EXPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PRINT_OPERATION_EXPORT, EvPrintOperationExportClass))
330 #define EV_IS_PRINT_OPERATION_EXPORT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PRINT_OPERATION_EXPORT))
332 typedef struct _EvPrintOperationExport EvPrintOperationExport;
333 typedef struct _EvPrintOperationExportClass EvPrintOperationExportClass;
335 GType ev_print_operation_export_get_type (void) G_GNUC_CONST;
337 static void ev_print_operation_export_begin (EvPrintOperationExport *export);
338 static gboolean export_print_page (EvPrintOperationExport *export);
339 static void export_cancel (EvPrintOperationExport *export);
341 struct _EvPrintOperationExport {
342 EvPrintOperation parent;
344 GtkWindow *parent_window;
348 gboolean print_preview;
352 GtkPageSetup *page_setup;
353 GtkPrintSettings *print_settings;
358 gint pages_per_sheet;
366 EvFileExporterContext fc;
367 gint n_pages_to_print;
368 gint uncollated_copies;
369 gint collated_copies;
370 gint uncollated, collated, total;
372 gint range, n_ranges;
373 GtkPageRange *ranges;
374 GtkPageRange one_range;
376 gint page, start, end, inc;
379 struct _EvPrintOperationExportClass {
380 EvPrintOperationClass parent_class;
383 G_DEFINE_TYPE (EvPrintOperationExport, ev_print_operation_export, EV_TYPE_PRINT_OPERATION)
385 /* Internal print queue */
386 static GHashTable *print_queue = NULL;
389 queue_free (GQueue *queue)
391 g_queue_foreach (queue, (GFunc)g_object_unref, NULL);
392 g_queue_free (queue);
396 ev_print_queue_init (void)
398 if (G_UNLIKELY (print_queue == NULL)) {
399 print_queue = g_hash_table_new_full (g_direct_hash,
402 (GDestroyNotify)queue_free);
407 remove_document_queue (gpointer data,
411 g_hash_table_remove (print_queue, document);
415 ev_print_queue_is_empty (EvDocument *document)
419 queue = g_hash_table_lookup (print_queue, document);
420 return (!queue || g_queue_is_empty (queue));
424 ev_print_queue_push (EvPrintOperation *op)
428 queue = g_hash_table_lookup (print_queue, op->document);
430 queue = g_queue_new ();
431 g_hash_table_insert (print_queue,
434 g_object_weak_ref (G_OBJECT (op->document),
435 (GWeakNotify)remove_document_queue,
439 g_queue_push_head (queue, g_object_ref (op));
442 static EvPrintOperation *
443 ev_print_queue_pop (EvDocument *document)
445 EvPrintOperation *op;
448 queue = g_hash_table_lookup (print_queue, document);
449 if (!queue || g_queue_is_empty (queue))
452 op = g_queue_pop_tail (queue);
458 static EvPrintOperation *
459 ev_print_queue_peek (EvDocument *document)
463 queue = g_hash_table_lookup (print_queue, document);
464 if (!queue || g_queue_is_empty (queue))
467 return g_queue_peek_tail (queue);
471 ev_print_operation_export_set_current_page (EvPrintOperation *op,
474 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
476 g_return_if_fail (current_page < export->n_pages);
478 export->current_page = current_page;
482 ev_print_operation_export_set_print_settings (EvPrintOperation *op,
483 GtkPrintSettings *print_settings)
485 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
487 if (print_settings == export->print_settings)
490 g_object_ref (print_settings);
491 if (export->print_settings)
492 g_object_unref (export->print_settings);
493 export->print_settings = print_settings;
496 static GtkPrintSettings *
497 ev_print_operation_export_get_print_settings (EvPrintOperation *op)
499 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
501 return export->print_settings;
505 ev_print_operation_export_set_default_page_setup (EvPrintOperation *op,
506 GtkPageSetup *page_setup)
508 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
510 if (page_setup == export->page_setup)
513 g_object_ref (page_setup);
514 if (export->page_setup)
515 g_object_unref (export->page_setup);
516 export->page_setup = page_setup;
519 static GtkPageSetup *
520 ev_print_operation_export_get_default_page_setup (EvPrintOperation *op)
522 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
524 return export->page_setup;
528 ev_print_operation_export_set_job_name (EvPrintOperation *op,
529 const gchar *job_name)
531 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
533 g_free (export->job_name);
534 export->job_name = g_strdup (job_name);
538 ev_print_operation_export_get_job_name (EvPrintOperation *op)
540 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
542 return export->job_name;
546 ev_print_operation_export_set_printer (EvPrintOperationExport *export,
549 if (printer == export->printer)
552 g_object_ref (printer);
554 g_object_unref (export->printer);
555 export->printer = printer;
559 find_range (EvPrintOperationExport *export)
563 range = &export->ranges[export->range];
565 if (export->inc < 0) {
566 export->start = range->end;
567 export->end = range->start - 1;
569 export->start = range->start;
570 export->end = range->end + 1;
575 clamp_ranges (EvPrintOperationExport *export)
577 gint num_of_correct_ranges = 0;
578 gint n_pages_to_print = 0;
580 gboolean null_flag = FALSE;
582 for (i = 0; i < export->n_ranges; i++) {
585 if ((export->ranges[i].start >= 0) &&
586 (export->ranges[i].start < export->n_pages) &&
587 (export->ranges[i].end >= 0) &&
588 (export->ranges[i].end < export->n_pages)) {
589 export->ranges[num_of_correct_ranges] = export->ranges[i];
590 num_of_correct_ranges++;
591 } else if ((export->ranges[i].start >= 0) &&
592 (export->ranges[i].start < export->n_pages) &&
593 (export->ranges[i].end >= export->n_pages)) {
594 export->ranges[i].end = export->n_pages - 1;
595 export->ranges[num_of_correct_ranges] = export->ranges[i];
596 num_of_correct_ranges++;
597 } else if ((export->ranges[i].end >= 0) &&
598 (export->ranges[i].end < export->n_pages) &&
599 (export->ranges[i].start < 0)) {
600 export->ranges[i].start = 0;
601 export->ranges[num_of_correct_ranges] = export->ranges[i];
602 num_of_correct_ranges++;
605 n_pages = export->ranges[i].end - export->ranges[i].start + 1;
606 if (export->page_set == GTK_PAGE_SET_ALL) {
607 n_pages_to_print += n_pages;
608 } else if (n_pages % 2 == 0) {
609 n_pages_to_print += n_pages / 2;
610 } else if (export->page_set == GTK_PAGE_SET_EVEN) {
611 if (n_pages==1 && export->ranges[i].start % 2 == 0)
614 n_pages_to_print += export->ranges[i].start % 2 == 0 ?
615 n_pages / 2 : (n_pages / 2) + 1;
616 } else if (export->page_set == GTK_PAGE_SET_ODD) {
617 if (n_pages==1 && export->ranges[i].start % 2 != 0)
620 n_pages_to_print += export->ranges[i].start % 2 == 0 ?
621 (n_pages / 2) + 1 : n_pages / 2;
625 if (null_flag && !n_pages_to_print) {
628 export->n_ranges = num_of_correct_ranges;
629 export->n_pages_to_print = n_pages_to_print;
635 get_first_and_last_page (EvPrintOperationExport *export,
640 gint first_page = G_MAXINT;
641 gint last_page = G_MININT;
642 gint max_page = export->n_pages - 1;
644 if (export->n_ranges == 0) {
651 for (i = 0; i < export->n_ranges; i++) {
652 if (export->ranges[i].start < first_page)
653 first_page = export->ranges[i].start;
654 if (export->ranges[i].end > last_page)
655 last_page = export->ranges[i].end;
658 *first = MAX (0, first_page);
659 *last = MIN (max_page, last_page);
663 export_print_inc_page (EvPrintOperationExport *export)
666 export->page += export->inc;
667 if (export->page == export->end) {
668 export->range += export->inc;
669 if (export->range == -1 || export->range == export->n_ranges) {
670 export->uncollated++;
671 if (export->uncollated == export->uncollated_copies)
674 export->range = export->inc < 0 ? export->n_ranges - 1 : 0;
677 export->page = export->start;
679 } while ((export->page_set == GTK_PAGE_SET_EVEN && export->page % 2 == 0) ||
680 (export->page_set == GTK_PAGE_SET_ODD && export->page % 2 == 1));
686 ev_print_operation_export_clear_temp_file (EvPrintOperationExport *export)
688 if (!export->temp_file)
691 g_unlink (export->temp_file);
692 g_free (export->temp_file);
693 export->temp_file = NULL;
697 ev_print_operation_export_run_next (EvPrintOperationExport *export)
699 EvPrintOperation *op = EV_PRINT_OPERATION (export);
700 EvPrintOperation *next;
701 EvDocument *document;
703 /* First pop the current job */
704 document = op->document;
705 ev_print_queue_pop (document);
707 next = ev_print_queue_peek (document);
709 ev_print_operation_export_begin (EV_PRINT_OPERATION_EXPORT (next));
713 print_job_finished (GtkPrintJob *print_job,
714 EvPrintOperationExport *export,
717 EvPrintOperation *op = EV_PRINT_OPERATION (export);
720 g_set_error_literal (&export->error,
722 GTK_PRINT_ERROR_GENERAL,
724 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
726 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
729 ev_print_operation_export_clear_temp_file (export);
730 g_object_unref (print_job);
732 ev_print_operation_export_run_next (export);
736 export_print_done (EvPrintOperationExport *export)
738 EvPrintOperation *op = EV_PRINT_OPERATION (export);
739 GtkPrintSettings *settings;
740 EvFileExporterCapabilities capabilities;
741 GError *error = NULL;
743 g_assert (export->temp_file != NULL);
745 /* Some printers take into account some print settings,
746 * and others don't. However we have exported the document
747 * to a ps or pdf file according to such print settings. So,
748 * we want to send the exported file to printer with those
749 * settings set to default values.
751 settings = gtk_print_settings_copy (export->print_settings);
752 capabilities = ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
754 gtk_print_settings_set_page_ranges (settings, NULL, 0);
755 gtk_print_settings_set_print_pages (settings, GTK_PRINT_PAGES_ALL);
756 if (capabilities & EV_FILE_EXPORTER_CAN_COPIES)
757 gtk_print_settings_set_n_copies (settings, 1);
758 if (capabilities & EV_FILE_EXPORTER_CAN_PAGE_SET)
759 gtk_print_settings_set_page_set (settings, GTK_PAGE_SET_ALL);
760 if (capabilities & EV_FILE_EXPORTER_CAN_SCALE)
761 gtk_print_settings_set_scale (settings, 1.0);
762 if (capabilities & EV_FILE_EXPORTER_CAN_COLLATE)
763 gtk_print_settings_set_collate (settings, FALSE);
764 if (capabilities & EV_FILE_EXPORTER_CAN_REVERSE)
765 gtk_print_settings_set_reverse (settings, FALSE);
766 if (capabilities & EV_FILE_EXPORTER_CAN_NUMBER_UP) {
767 gtk_print_settings_set_number_up (settings, 1);
768 gtk_print_settings_set_int (settings, "cups-"GTK_PRINT_SETTINGS_NUMBER_UP, 1);
771 if (export->print_preview) {
775 gchar *print_settings_file = NULL;
777 key_file = g_key_file_new ();
779 gtk_print_settings_to_key_file (settings, key_file, NULL);
780 gtk_page_setup_to_key_file (export->page_setup, key_file, NULL);
781 g_key_file_set_string (key_file, "Print Job", "title", export->job_name);
783 data = g_key_file_to_data (key_file, &data_len, &error);
787 fd = g_file_open_tmp ("print-settingsXXXXXX", &print_settings_file, &error);
789 g_file_set_contents (print_settings_file, data, data_len, &error);
795 g_key_file_free (key_file);
801 gchar *quoted_filename;
802 gchar *quoted_settings_filename;
804 quoted_filename = g_shell_quote (export->temp_file);
805 quoted_settings_filename = g_shell_quote (print_settings_file);
806 cmd = g_strdup_printf ("evince-previewer --unlink-tempfile --print-settings %s %s",
807 quoted_settings_filename, quoted_filename);
809 g_shell_parse_argv (cmd, &argc, &argv, &error);
811 g_free (quoted_filename);
812 g_free (quoted_settings_filename);
816 gdk_spawn_on_screen (gtk_window_get_screen (export->parent_window),
827 if (print_settings_file)
828 g_unlink (print_settings_file);
829 g_free (print_settings_file);
831 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
832 /* temp_file will be deleted by the previewer */
834 ev_print_operation_export_run_next (export);
839 job = gtk_print_job_new (export->job_name,
843 gtk_print_job_set_source_file (job, export->temp_file, &error);
845 gtk_print_job_send (job,
846 (GtkPrintJobCompleteFunc)print_job_finished,
847 g_object_ref (export),
848 (GDestroyNotify)g_object_unref);
851 g_object_unref (settings);
854 g_set_error_literal (&export->error,
856 GTK_PRINT_ERROR_GENERAL,
858 g_error_free (error);
859 ev_print_operation_export_clear_temp_file (export);
860 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
862 ev_print_operation_export_run_next (export);
867 export_print_page_idle_finished (EvPrintOperationExport *export)
873 export_job_finished (EvJobExport *job,
874 EvPrintOperationExport *export)
876 EvPrintOperation *op = EV_PRINT_OPERATION (export);
878 if (export->pages_per_sheet == 1 || export->total % export->pages_per_sheet == 0) {
879 ev_document_doc_mutex_lock ();
880 ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
881 ev_document_doc_mutex_unlock ();
885 export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
886 (GSourceFunc)export_print_page,
888 (GDestroyNotify)export_print_page_idle_finished);
892 export_job_cancelled (EvJobExport *job,
893 EvPrintOperationExport *export)
895 export_cancel (export);
899 export_cancel (EvPrintOperationExport *export)
901 EvPrintOperation *op = EV_PRINT_OPERATION (export);
903 if (export->idle_id > 0)
904 g_source_remove (export->idle_id);
907 if (export->job_export) {
908 g_signal_handlers_disconnect_by_func (export->job_export,
911 g_signal_handlers_disconnect_by_func (export->job_export,
912 export_job_cancelled,
914 g_object_unref (export->job_export);
915 export->job_export = NULL;
918 if (export->fd != -1) {
923 ev_print_operation_export_clear_temp_file (export);
925 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
927 ev_print_operation_export_run_next (export);
931 update_progress (EvPrintOperationExport *export)
933 EvPrintOperation *op = EV_PRINT_OPERATION (export);
935 ev_print_operation_update_status (op, export->total,
936 export->n_pages_to_print,
937 export->total / (gdouble)export->n_pages_to_print);
941 export_print_page (EvPrintOperationExport *export)
943 EvPrintOperation *op = EV_PRINT_OPERATION (export);
945 if (!export->temp_file)
946 return FALSE; /* cancelled */
951 if (export->collated == export->collated_copies) {
952 export->collated = 0;
953 if (!export_print_inc_page (export)) {
954 ev_document_doc_mutex_lock ();
955 if (export->pages_per_sheet > 1 &&
956 export->total - 1 % export->pages_per_sheet == 0)
957 ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
958 ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
959 ev_document_doc_mutex_unlock ();
964 update_progress (export);
966 export_print_done (export);
972 if (export->pages_per_sheet == 1 || export->total % export->pages_per_sheet == 1) {
973 ev_document_doc_mutex_lock ();
974 ev_file_exporter_begin_page (EV_FILE_EXPORTER (op->document));
975 ev_document_doc_mutex_unlock ();
978 if (!export->job_export) {
979 export->job_export = ev_job_export_new (op->document);
980 g_signal_connect (export->job_export, "finished",
981 G_CALLBACK (export_job_finished),
983 g_signal_connect (export->job_export, "cancelled",
984 G_CALLBACK (export_job_cancelled),
988 ev_job_export_set_page (EV_JOB_EXPORT (export->job_export), export->page);
989 ev_job_scheduler_push_job (export->job_export, EV_JOB_PRIORITY_NONE);
991 update_progress (export);
997 ev_print_operation_export_begin (EvPrintOperationExport *export)
999 EvPrintOperation *op = EV_PRINT_OPERATION (export);
1001 if (!export->temp_file)
1002 return; /* cancelled */
1004 ev_document_doc_mutex_lock ();
1005 ev_file_exporter_begin (EV_FILE_EXPORTER (op->document), &export->fc);
1006 ev_document_doc_mutex_unlock ();
1008 export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
1009 (GSourceFunc)export_print_page,
1011 (GDestroyNotify)export_print_page_idle_finished);
1015 ev_print_operation_export_print_dialog_response_cb (GtkDialog *dialog,
1017 EvPrintOperationExport *export)
1019 GtkPrintPages print_pages;
1020 GtkPrintSettings *print_settings;
1021 GtkPageSetup *page_setup;
1022 GtkPrinter *printer;
1028 const gchar *file_format;
1030 GError *error = NULL;
1031 EvPrintOperation *op = EV_PRINT_OPERATION (export);
1033 if (response != GTK_RESPONSE_OK &&
1034 response != GTK_RESPONSE_APPLY) {
1035 gtk_widget_destroy (GTK_WIDGET (dialog));
1036 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
1041 export->print_preview = (response == GTK_RESPONSE_APPLY);
1043 printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog));
1044 ev_print_operation_export_set_printer (export, printer);
1046 print_settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog));
1047 ev_print_operation_export_set_print_settings (op, print_settings);
1049 page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog));
1050 ev_print_operation_export_set_default_page_setup (op, page_setup);
1052 if (!gtk_printer_accepts_ps (export->printer)) {
1053 gtk_widget_destroy (GTK_WIDGET (dialog));
1055 g_set_error_literal (&export->error,
1057 GTK_PRINT_ERROR_GENERAL,
1058 _("Printing is not supported on this printer."));
1059 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1064 file_format = gtk_print_settings_get (print_settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
1066 filename = g_strdup_printf ("evince_print.%s.XXXXXX", file_format);
1067 export->fd = g_file_open_tmp (filename, &export->temp_file, &error);
1069 if (export->fd <= -1) {
1070 gtk_widget_destroy (GTK_WIDGET (dialog));
1072 g_set_error_literal (&export->error,
1074 GTK_PRINT_ERROR_GENERAL,
1076 g_error_free (error);
1077 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1082 export->current_page = gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog));
1083 export->page_set = gtk_print_settings_get_page_set (print_settings);
1084 print_pages = gtk_print_settings_get_print_pages (print_settings);
1086 switch (print_pages) {
1087 case GTK_PRINT_PAGES_CURRENT:
1088 export->ranges = &export->one_range;
1090 export->ranges[0].start = export->current_page;
1091 export->ranges[0].end = export->current_page;
1092 export->n_ranges = 1;
1095 case GTK_PRINT_PAGES_RANGES: {
1098 export->ranges = gtk_print_settings_get_page_ranges (print_settings, &export->n_ranges);
1099 for (i = 0; i < export->n_ranges; i++)
1100 if (export->ranges[i].end == -1 || export->ranges[i].end >= export->n_pages)
1101 export->ranges[i].end = export->n_pages - 1;
1104 case GTK_PRINT_PAGES_ALL:
1105 export->ranges = &export->one_range;
1107 export->ranges[0].start = 0;
1108 export->ranges[0].end = export->n_pages - 1;
1109 export->n_ranges = 1;
1113 if (!clamp_ranges (export)) {
1114 GtkWidget *message_dialog;
1116 message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
1118 GTK_MESSAGE_WARNING,
1120 "%s", _("Invalid page selection"));
1121 gtk_window_set_title (GTK_WINDOW (message_dialog), _("Warning"));
1122 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
1123 "%s", _("Your print range selection does not include any page"));
1124 g_signal_connect (message_dialog, "response",
1125 G_CALLBACK (gtk_widget_destroy),
1127 gtk_widget_show (message_dialog);
1130 } else ev_print_operation_update_status (op, -1, -1, 0.0);
1132 width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1133 height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1134 scale = gtk_print_settings_get_scale (print_settings) * 0.01;
1140 export->pages_per_sheet = MAX (1, gtk_print_settings_get_number_up (print_settings));
1142 export->copies = gtk_print_settings_get_n_copies (print_settings);
1143 export->collate = gtk_print_settings_get_collate (print_settings);
1144 export->reverse = gtk_print_settings_get_reverse (print_settings);
1146 if (export->collate) {
1147 export->uncollated_copies = export->copies;
1148 export->collated_copies = 1;
1150 export->uncollated_copies = 1;
1151 export->collated_copies = export->copies;
1154 if (export->reverse) {
1155 export->range = export->n_ranges - 1;
1161 find_range (export);
1163 export->page = export->start - export->inc;
1164 export->collated = export->collated_copies - 1;
1166 get_first_and_last_page (export, &first_page, &last_page);
1168 export->fc.format = file_format && g_ascii_strcasecmp (file_format, "pdf") == 0 ?
1169 EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
1170 export->fc.filename = export->temp_file;
1171 export->fc.first_page = MIN (first_page, last_page);
1172 export->fc.last_page = MAX (first_page, last_page);
1173 export->fc.paper_width = width;
1174 export->fc.paper_height = height;
1175 export->fc.duplex = FALSE;
1176 export->fc.pages_per_sheet = export->pages_per_sheet;
1178 if (ev_print_queue_is_empty (op->document))
1179 ev_print_operation_export_begin (export);
1181 ev_print_queue_push (op);
1183 g_signal_emit (op, signals[BEGIN_PRINT], 0);
1185 gtk_widget_destroy (GTK_WIDGET (dialog));
1189 ev_print_operation_export_run (EvPrintOperation *op,
1192 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1194 GtkPrintCapabilities capabilities;
1196 ev_print_queue_init ();
1198 export->parent_window = parent;
1199 export->error = NULL;
1201 dialog = gtk_print_unix_dialog_new (_("Print"), parent);
1202 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1204 capabilities = GTK_PRINT_CAPABILITY_PREVIEW |
1205 ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
1206 gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog),
1209 gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog),
1210 export->current_page);
1212 gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog),
1213 export->print_settings);
1215 if (export->page_setup)
1216 gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1217 export->page_setup);
1219 g_signal_connect (dialog, "response",
1220 G_CALLBACK (ev_print_operation_export_print_dialog_response_cb),
1223 gtk_window_present (GTK_WINDOW (dialog));
1227 ev_print_operation_export_cancel (EvPrintOperation *op)
1229 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1231 if (export->job_export &&
1232 !ev_job_is_finished (export->job_export)) {
1233 ev_job_cancel (export->job_export);
1235 export_cancel (export);
1240 ev_print_operation_export_get_error (EvPrintOperation *op,
1243 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1245 g_propagate_error (error, export->error);
1246 export->error = NULL;
1250 ev_print_operation_export_finalize (GObject *object)
1252 EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (object);
1254 if (export->idle_id > 0) {
1255 g_source_remove (export->idle_id);
1256 export->idle_id = 0;
1259 if (export->fd != -1) {
1264 if (export->ranges) {
1265 if (export->ranges != &export->one_range)
1266 g_free (export->ranges);
1267 export->ranges = NULL;
1268 export->n_ranges = 0;
1271 if (export->temp_file) {
1272 g_free (export->temp_file);
1273 export->temp_file = NULL;
1276 if (export->job_name) {
1277 g_free (export->job_name);
1278 export->job_name = NULL;
1281 if (export->job_export) {
1282 if (!ev_job_is_finished (export->job_export))
1283 ev_job_cancel (export->job_export);
1284 g_signal_handlers_disconnect_by_func (export->job_export,
1285 export_job_finished,
1287 g_signal_handlers_disconnect_by_func (export->job_export,
1288 export_job_cancelled,
1290 g_object_unref (export->job_export);
1291 export->job_export = NULL;
1294 if (export->error) {
1295 g_error_free (export->error);
1296 export->error = NULL;
1299 if (export->print_settings) {
1300 g_object_unref (export->print_settings);
1301 export->print_settings = NULL;
1304 if (export->page_setup) {
1305 g_object_unref (export->page_setup);
1306 export->page_setup = NULL;
1309 if (export->printer) {
1310 g_object_unref (export->printer);
1311 export->printer = NULL;
1314 (* G_OBJECT_CLASS (ev_print_operation_export_parent_class)->finalize) (object);
1318 ev_print_operation_export_init (EvPrintOperationExport *export)
1323 ev_print_operation_export_constructor (GType type,
1324 guint n_construct_properties,
1325 GObjectConstructParam *construct_params)
1328 EvPrintOperationExport *export;
1329 EvPrintOperation *op;
1331 object = G_OBJECT_CLASS (ev_print_operation_export_parent_class)->constructor (type,
1332 n_construct_properties,
1334 export = EV_PRINT_OPERATION_EXPORT (object);
1335 op = EV_PRINT_OPERATION (object);
1336 export->n_pages = ev_page_cache_get_n_pages (ev_page_cache_get (op->document));
1342 ev_print_operation_export_class_init (EvPrintOperationExportClass *klass)
1344 GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
1345 EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
1347 ev_print_op_class->set_current_page = ev_print_operation_export_set_current_page;
1348 ev_print_op_class->set_print_settings = ev_print_operation_export_set_print_settings;
1349 ev_print_op_class->get_print_settings = ev_print_operation_export_get_print_settings;
1350 ev_print_op_class->set_default_page_setup = ev_print_operation_export_set_default_page_setup;
1351 ev_print_op_class->get_default_page_setup = ev_print_operation_export_get_default_page_setup;
1352 ev_print_op_class->set_job_name = ev_print_operation_export_set_job_name;
1353 ev_print_op_class->get_job_name = ev_print_operation_export_get_job_name;
1354 ev_print_op_class->run = ev_print_operation_export_run;
1355 ev_print_op_class->cancel = ev_print_operation_export_cancel;
1356 ev_print_op_class->get_error = ev_print_operation_export_get_error;
1358 g_object_class->constructor = ev_print_operation_export_constructor;
1359 g_object_class->finalize = ev_print_operation_export_finalize;
1362 /* Factory method */
1364 ev_print_operation_new (EvDocument *document)
1366 /* TODO: EvPrintOperationPrint */
1368 return EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_EXPORT,
1369 "document", document, NULL));