]> www.fi.muni.cz Git - evince.git/blob - shell/ev-print-operation.c
8d4df9f81dd41cfeed5fa84a6cd486293c5f1785
[evince.git] / shell / ev-print-operation.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
4  *
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.
9  *
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.
14  *
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.
18  */
19
20 #include <config.h>
21
22 #include "ev-print-operation.h"
23
24 #if GTKUNIXPRINT_ENABLED
25 #include <gtk/gtkunixprint.h>
26 #endif
27 #include <glib/gi18n.h>
28 #include <glib/gstdio.h>
29 #include <unistd.h>
30
31 #include "ev-file-exporter.h"
32 #include "ev-jobs.h"
33 #include "ev-job-scheduler.h"
34 #include "ev-application.h"
35 #include "ev-file-helpers.h"
36 #include "ev-document-print.h"
37
38 enum {
39         PROP_0,
40         PROP_DOCUMENT
41 };
42
43 enum {
44         DONE,
45         BEGIN_PRINT,
46         STATUS_CHANGED,
47         LAST_SIGNAL
48 };
49
50 static guint signals[LAST_SIGNAL] = { 0 };
51
52 struct _EvPrintOperation {
53         GObject parent;
54
55         EvDocument *document;
56
57         /* Progress */
58         gchar      *status;
59         gdouble     progress;
60 };
61
62 struct _EvPrintOperationClass {
63         GObjectClass parent_class;
64
65         void              (* set_current_page)       (EvPrintOperation       *op,
66                                                       gint                    current_page);
67         void              (* set_print_settings)     (EvPrintOperation       *op,
68                                                       GtkPrintSettings       *print_settings);
69         GtkPrintSettings *(* get_print_settings)     (EvPrintOperation       *op);
70         void              (* set_default_page_setup) (EvPrintOperation       *op,
71                                                       GtkPageSetup           *page_setup);
72         GtkPageSetup     *(* get_default_page_setup) (EvPrintOperation       *op);
73         void              (* set_job_name)           (EvPrintOperation       *op,
74                                                       const gchar            *job_name);
75         const gchar      *(* get_job_name)           (EvPrintOperation       *op);
76         void              (* run)                    (EvPrintOperation       *op,
77                                                       GtkWindow              *parent);
78         void              (* cancel)                 (EvPrintOperation       *op);
79         void              (* get_error)              (EvPrintOperation       *op,
80                                                       GError                **error);
81         void              (* set_embed_page_setup)   (EvPrintOperation       *op,
82                                                       gboolean                embed);
83         gboolean          (* get_embed_page_setup)   (EvPrintOperation       *op);
84
85         /* signals */
86         void              (* done)                   (EvPrintOperation       *op,
87                                                       GtkPrintOperationResult result);
88         void              (* begin_print)            (EvPrintOperation       *op);
89         void              (* status_changed)         (EvPrintOperation       *op);
90 };
91
92 G_DEFINE_ABSTRACT_TYPE (EvPrintOperation, ev_print_operation, G_TYPE_OBJECT)
93
94 static void
95 ev_print_operation_finalize (GObject *object)
96 {
97         EvPrintOperation *op = EV_PRINT_OPERATION (object);
98
99         if (op->document) {
100                 g_object_unref (op->document);
101                 op->document = NULL;
102         }
103
104         if (op->status) {
105                 g_free (op->status);
106                 op->status = NULL;
107         }
108
109         (* G_OBJECT_CLASS (ev_print_operation_parent_class)->finalize) (object);
110 }
111
112 static void
113 ev_print_operation_set_property (GObject      *object,
114                                  guint         prop_id,
115                                  const GValue *value,
116                                  GParamSpec   *pspec)
117 {
118         EvPrintOperation *op = EV_PRINT_OPERATION (object);
119
120         switch (prop_id) {
121         case PROP_DOCUMENT:
122                 op->document = g_value_dup_object (value);
123                 break;
124         default:
125                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126         }
127 }
128
129 static void
130 ev_print_operation_init (EvPrintOperation *op)
131 {
132 }
133
134 static void
135 ev_print_operation_class_init (EvPrintOperationClass *klass)
136 {
137         GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
138
139         g_object_class->set_property = ev_print_operation_set_property;
140         g_object_class->finalize = ev_print_operation_finalize;
141
142         g_object_class_install_property (g_object_class,
143                                          PROP_DOCUMENT,
144                                          g_param_spec_object ("document",
145                                                               "Document",
146                                                               "The document to print",
147                                                               EV_TYPE_DOCUMENT,
148                                                               G_PARAM_WRITABLE |
149                                                               G_PARAM_CONSTRUCT_ONLY));
150         signals[DONE] =
151                 g_signal_new ("done",
152                               G_TYPE_FROM_CLASS (g_object_class),
153                               G_SIGNAL_RUN_LAST,
154                               G_STRUCT_OFFSET (EvPrintOperationClass, done),
155                               NULL, NULL,
156                               g_cclosure_marshal_VOID__ENUM,
157                               G_TYPE_NONE, 1,
158                               GTK_TYPE_PRINT_OPERATION_RESULT);
159         signals[BEGIN_PRINT] =
160                 g_signal_new ("begin_print",
161                               G_TYPE_FROM_CLASS (g_object_class),
162                               G_SIGNAL_RUN_LAST,
163                               G_STRUCT_OFFSET (EvPrintOperationClass, begin_print),
164                               NULL, NULL,
165                               g_cclosure_marshal_VOID__VOID,
166                               G_TYPE_NONE, 0);
167         signals[STATUS_CHANGED] =
168                 g_signal_new ("status_changed",
169                               G_TYPE_FROM_CLASS (g_object_class),
170                               G_SIGNAL_RUN_LAST,
171                               G_STRUCT_OFFSET (EvPrintOperationClass, status_changed),
172                               NULL, NULL,
173                               g_cclosure_marshal_VOID__VOID,
174                               G_TYPE_NONE, 0);
175 }
176
177 /* Public methods */
178 void
179 ev_print_operation_set_current_page (EvPrintOperation *op,
180                                      gint              current_page)
181 {
182         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
183
184         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
185         g_return_if_fail (current_page >= 0);
186
187         class->set_current_page (op, current_page);
188 }
189
190 void
191 ev_print_operation_set_print_settings (EvPrintOperation *op,
192                                        GtkPrintSettings *print_settings)
193 {
194         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
195
196         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
197         g_return_if_fail (GTK_IS_PRINT_SETTINGS (print_settings));
198
199         class->set_print_settings (op, print_settings);
200 }
201
202 GtkPrintSettings *
203 ev_print_operation_get_print_settings (EvPrintOperation *op)
204 {
205         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
206
207         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
208
209         return class->get_print_settings (op);
210 }
211
212 void
213 ev_print_operation_set_default_page_setup (EvPrintOperation *op,
214                                            GtkPageSetup     *page_setup)
215 {
216         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
217
218         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
219         g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup));
220
221         class->set_default_page_setup (op, page_setup);
222 }
223
224 GtkPageSetup *
225 ev_print_operation_get_default_page_setup (EvPrintOperation *op)
226 {
227         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
228
229         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
230
231         return class->get_default_page_setup (op);
232 }
233
234 void
235 ev_print_operation_set_job_name (EvPrintOperation *op,
236                                  const gchar      *job_name)
237 {
238         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
239
240         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
241         g_return_if_fail (job_name != NULL);
242
243         class->set_job_name (op, job_name);
244 }
245
246 const gchar *
247 ev_print_operation_get_job_name (EvPrintOperation *op)
248 {
249         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
250
251         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
252
253         return class->get_job_name (op);
254 }
255
256 void
257 ev_print_operation_run (EvPrintOperation *op,
258                         GtkWindow        *parent)
259 {
260         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
261
262         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
263
264         class->run (op, parent);
265 }
266
267 void
268 ev_print_operation_cancel (EvPrintOperation *op)
269 {
270         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
271
272         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
273
274         class->cancel (op);
275 }
276
277 void
278 ev_print_operation_get_error (EvPrintOperation *op,
279                               GError          **error)
280 {
281         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
282
283         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
284
285         class->get_error (op, error);
286 }
287
288 void
289 ev_print_operation_set_embed_page_setup (EvPrintOperation *op,
290                                          gboolean          embed)
291 {
292 #if GTK_CHECK_VERSION (2, 17, 4)
293         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
294
295         g_return_if_fail (EV_IS_PRINT_OPERATION (op));
296
297         class->set_embed_page_setup (op, embed);
298 #endif
299 }
300
301 gboolean
302 ev_print_operation_get_embed_page_setup (EvPrintOperation *op)
303 {
304 #if GTK_CHECK_VERSION (2, 17, 4)
305         EvPrintOperationClass *class = EV_PRINT_OPERATION_GET_CLASS (op);
306
307         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), FALSE);
308
309         return class->get_embed_page_setup (op);
310 #else
311         return FALSE;
312 #endif
313 }
314
315 const gchar *
316 ev_print_operation_get_status (EvPrintOperation *op)
317 {
318         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
319
320         return op->status ? op->status : "";
321 }
322
323 gdouble
324 ev_print_operation_get_progress (EvPrintOperation *op)
325 {
326         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), 0.0);
327
328         return op->progress;
329 }
330
331 #if GTK_CHECK_VERSION (2, 17, 1) | GTKUNIXPRINT_ENABLED
332 static void
333 ev_print_operation_update_status (EvPrintOperation *op,
334                                   gint              page,
335                                   gint              n_pages,
336                                   gdouble           progress)
337 {
338         if (op->status && op->progress == progress)
339                 return;
340
341         g_free (op->status);
342
343         if (page == -1) {
344                 /* Initial state */
345                 op->status = g_strdup (_("Preparing to print ..."));
346         } else if (page > n_pages) {
347                 op->status = g_strdup (_("Finishing..."));
348         } else {
349                 op->status = g_strdup_printf (_("Printing page %d of %d..."),
350                                               page, n_pages);
351         }
352
353         op->progress = MIN (1.0, progress);
354
355         g_signal_emit (op, signals[STATUS_CHANGED], 0);
356 }
357 #endif
358
359 #if GTKUNIXPRINT_ENABLED
360
361 /* Export interface */
362 #define EV_TYPE_PRINT_OPERATION_EXPORT         (ev_print_operation_export_get_type())
363 #define EV_PRINT_OPERATION_EXPORT(object)      (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_EXPORT, EvPrintOperationExport))
364 #define EV_PRINT_OPERATION_EXPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PRINT_OPERATION_EXPORT, EvPrintOperationExportClass))
365 #define EV_IS_PRINT_OPERATION_EXPORT(object)   (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PRINT_OPERATION_EXPORT))
366
367 typedef struct _EvPrintOperationExport      EvPrintOperationExport;
368 typedef struct _EvPrintOperationExportClass EvPrintOperationExportClass;
369
370 static GType    ev_print_operation_export_get_type (void) G_GNUC_CONST;
371
372 static void     ev_print_operation_export_begin    (EvPrintOperationExport *export);
373 static gboolean export_print_page                  (EvPrintOperationExport *export);
374 static void     export_cancel                      (EvPrintOperationExport *export);
375
376 struct _EvPrintOperationExport {
377         EvPrintOperation parent;
378
379         GtkWindow *parent_window;
380         EvJob *job_export;
381         GError *error;
382
383         gboolean print_preview;
384         gint n_pages;
385         gint current_page;
386         GtkPrinter *printer;
387         GtkPageSetup *page_setup;
388         GtkPrintSettings *print_settings;
389         GtkPageSet page_set;
390         gint copies;
391         guint collate     : 1;
392         guint reverse     : 1;
393         gint pages_per_sheet;
394         gint fd;
395         gchar *temp_file;
396         gchar *job_name;
397         gboolean embed_page_setup;
398
399         guint idle_id;
400         
401         /* Context */
402         EvFileExporterContext fc;
403         gint n_pages_to_print;
404         gint uncollated_copies;
405         gint collated_copies;
406         gint uncollated, collated, total;
407
408         gint sheet, page_count;
409
410         gint range, n_ranges;
411         GtkPageRange *ranges;
412         GtkPageRange one_range;
413
414         gint page, start, end, inc;
415 };
416
417 struct _EvPrintOperationExportClass {
418         EvPrintOperationClass parent_class;
419 };
420
421 G_DEFINE_TYPE (EvPrintOperationExport, ev_print_operation_export, EV_TYPE_PRINT_OPERATION)
422
423 /* Internal print queue */
424 static GHashTable *print_queue = NULL;
425
426 static void
427 queue_free (GQueue *queue)
428 {
429         g_queue_foreach (queue, (GFunc)g_object_unref, NULL);
430         g_queue_free (queue);
431 }
432
433 static void
434 ev_print_queue_init (void)
435 {
436         if (G_UNLIKELY (print_queue == NULL)) {
437                 print_queue = g_hash_table_new_full (g_direct_hash,
438                                                      g_direct_equal,
439                                                      NULL,
440                                                      (GDestroyNotify)queue_free);
441         }
442 }
443
444 static void
445 remove_document_queue (gpointer data,
446                        GObject *document)
447 {
448         if (print_queue)
449                 g_hash_table_remove (print_queue, document);
450 }
451
452 static gboolean
453 ev_print_queue_is_empty (EvDocument *document)
454 {
455         GQueue *queue;
456
457         queue = g_hash_table_lookup (print_queue, document);
458         return (!queue || g_queue_is_empty (queue));
459 }
460
461 static void
462 ev_print_queue_push (EvPrintOperation *op)
463 {
464         GQueue *queue;
465
466         queue = g_hash_table_lookup (print_queue, op->document);
467         if (!queue) {
468                 queue = g_queue_new ();
469                 g_hash_table_insert (print_queue,
470                                      op->document,
471                                      queue);
472                 g_object_weak_ref (G_OBJECT (op->document),
473                                    (GWeakNotify)remove_document_queue,
474                                    NULL);
475         }
476
477         g_queue_push_head (queue, g_object_ref (op));
478 }
479
480 static EvPrintOperation *
481 ev_print_queue_pop (EvDocument *document)
482 {
483         EvPrintOperation *op;
484         GQueue           *queue;
485
486         queue = g_hash_table_lookup (print_queue, document);
487         if (!queue || g_queue_is_empty (queue))
488                 return NULL;
489         
490         op = g_queue_pop_tail (queue);
491         g_object_unref (op);
492
493         return op;
494 }
495
496 static EvPrintOperation *
497 ev_print_queue_peek (EvDocument *document)
498 {
499         GQueue *queue;
500
501         queue = g_hash_table_lookup (print_queue, document);
502         if (!queue || g_queue_is_empty (queue))
503                 return NULL;
504
505         return g_queue_peek_tail (queue);
506 }
507
508 static void
509 ev_print_operation_export_set_current_page (EvPrintOperation *op,
510                                             gint              current_page)
511 {
512         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
513
514         g_return_if_fail (current_page < export->n_pages);
515         
516         export->current_page = current_page;
517 }
518
519 static void
520 ev_print_operation_export_set_print_settings (EvPrintOperation *op,
521                                               GtkPrintSettings *print_settings)
522 {
523         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
524
525         if (print_settings == export->print_settings)
526                 return;
527
528         g_object_ref (print_settings);
529         if (export->print_settings)
530                 g_object_unref (export->print_settings);
531         export->print_settings = print_settings;
532 }
533
534 static GtkPrintSettings *
535 ev_print_operation_export_get_print_settings (EvPrintOperation *op)
536 {
537         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
538
539         return export->print_settings;
540 }
541
542 static void
543 ev_print_operation_export_set_default_page_setup (EvPrintOperation *op,
544                                                   GtkPageSetup     *page_setup)
545 {
546         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
547
548         if (page_setup == export->page_setup)
549                 return;
550
551         g_object_ref (page_setup);
552         if (export->page_setup)
553                 g_object_unref (export->page_setup);
554         export->page_setup = page_setup;
555 }
556
557 static GtkPageSetup *
558 ev_print_operation_export_get_default_page_setup (EvPrintOperation *op)
559 {
560         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
561
562         return export->page_setup;
563 }
564
565 static void
566 ev_print_operation_export_set_job_name (EvPrintOperation *op,
567                                         const gchar      *job_name)
568 {
569         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
570
571         g_free (export->job_name);
572         export->job_name = g_strdup (job_name);
573 }
574
575 static const gchar *
576 ev_print_operation_export_get_job_name (EvPrintOperation *op)
577 {
578         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
579
580         return export->job_name;
581 }
582
583 static void
584 ev_print_operation_export_set_printer (EvPrintOperationExport *export,
585                                        GtkPrinter             *printer)
586 {
587         if (printer == export->printer)
588                 return;
589
590         g_object_ref (printer);
591         if (export->printer)
592                 g_object_unref (export->printer);
593         export->printer = printer;
594 }
595
596 static void
597 find_range (EvPrintOperationExport *export)
598 {
599         GtkPageRange *range;
600
601         range = &export->ranges[export->range];
602
603         if (export->inc < 0) {
604                 export->start = range->end;
605                 export->end = range->start - 1;
606         } else {
607                 export->start = range->start;
608                 export->end = range->end + 1;
609         }
610 }
611
612 static gboolean
613 clamp_ranges (EvPrintOperationExport *export)
614 {
615         gint num_of_correct_ranges = 0;
616         gint n_pages_to_print = 0;
617         gint i;
618         gboolean null_flag = FALSE;
619
620         for (i = 0; i < export->n_ranges; i++) {
621                 gint n_pages;
622                 
623                 if ((export->ranges[i].start >= 0) &&
624                     (export->ranges[i].start < export->n_pages) &&
625                     (export->ranges[i].end >= 0) &&
626                     (export->ranges[i].end < export->n_pages)) {
627                         export->ranges[num_of_correct_ranges] = export->ranges[i];
628                         num_of_correct_ranges++;
629                 } else if ((export->ranges[i].start >= 0) &&
630                            (export->ranges[i].start < export->n_pages) &&
631                            (export->ranges[i].end >= export->n_pages)) {
632                         export->ranges[i].end = export->n_pages - 1;
633                         export->ranges[num_of_correct_ranges] = export->ranges[i];
634                         num_of_correct_ranges++;
635                 } else if ((export->ranges[i].end >= 0) &&
636                            (export->ranges[i].end < export->n_pages) &&
637                            (export->ranges[i].start < 0)) {
638                         export->ranges[i].start = 0;
639                         export->ranges[num_of_correct_ranges] = export->ranges[i];
640                         num_of_correct_ranges++;
641                 }
642                 
643                 n_pages = export->ranges[i].end - export->ranges[i].start + 1;
644                 if (export->page_set == GTK_PAGE_SET_ALL) {
645                         n_pages_to_print += n_pages;
646                 } else if (n_pages % 2 == 0) {
647                         n_pages_to_print += n_pages / 2;
648                 } else if (export->page_set == GTK_PAGE_SET_EVEN) {
649                         if (n_pages==1 && export->ranges[i].start % 2 == 0)
650                                 null_flag = TRUE;
651                         else 
652                                 n_pages_to_print += export->ranges[i].start % 2 == 0 ?
653                                 n_pages / 2 : (n_pages / 2) + 1;
654                 } else if (export->page_set == GTK_PAGE_SET_ODD) {
655                         if (n_pages==1 && export->ranges[i].start % 2 != 0) 
656                                 null_flag = TRUE;
657                         else 
658                                 n_pages_to_print += export->ranges[i].start % 2 == 0 ?
659                                 (n_pages / 2) + 1 : n_pages / 2;
660                 }
661         }
662
663         if (null_flag && !n_pages_to_print) {
664                 return FALSE;
665         } else {
666                 export->n_ranges = num_of_correct_ranges;
667                 export->n_pages_to_print = n_pages_to_print;
668                 return TRUE;
669         }
670 }
671
672 static void
673 get_first_and_last_page (EvPrintOperationExport *export,
674                          gint                   *first,
675                          gint                   *last)
676 {
677         gint i;
678         gint first_page = G_MAXINT;
679         gint last_page = G_MININT;
680         gint max_page = export->n_pages - 1;
681
682         if (export->n_ranges == 0) {
683                 *first = 0;
684                 *last = max_page;
685
686                 return;
687         }
688
689         for (i = 0; i < export->n_ranges; i++) {
690                 if (export->ranges[i].start < first_page)
691                         first_page = export->ranges[i].start;
692                 if (export->ranges[i].end > last_page)
693                         last_page = export->ranges[i].end;
694         }
695
696         *first = MAX (0, first_page);
697         *last = MIN (max_page, last_page);
698 }
699
700 static gboolean
701 export_print_inc_page (EvPrintOperationExport *export)
702 {
703         do {
704                 export->page += export->inc;
705
706                 /* note: when NOT collating, page_count is increased in export_print_page */
707                 if (export->collate) {
708                         export->page_count++;
709                         export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
710                 }
711
712                 if (export->page == export->end) {
713                         export->range += export->inc;
714                         if (export->range == -1 || export->range == export->n_ranges) {
715                                 export->uncollated++;
716
717                                 /* when printing multiple collated copies & multiple pages per sheet we want to
718                                  * prevent the next copy bleeding into the last sheet of the previous one
719                                  * we've reached the last range to be printed now, so this is the time to do it */
720                                 if (export->pages_per_sheet > 1 && export->collate == 1 &&
721                                     (export->page_count - 1) % export->pages_per_sheet != 0) {
722
723                                         EvPrintOperation *op = EV_PRINT_OPERATION (export);
724                                         ev_document_doc_mutex_lock ();
725
726                                         /* keep track of all blanks but only actualise those
727                                          * which are in the current odd / even sheet set */
728
729                                         export->page_count += export->pages_per_sheet - (export->page_count - 1) % export->pages_per_sheet;
730                                         if (export->page_set == GTK_PAGE_SET_ALL ||
731                                                 (export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0) ||
732                                                 (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1) ) {
733                                                 ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
734                                         }
735                                         ev_document_doc_mutex_unlock ();
736                                         export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
737                                 }
738
739                                 if (export->uncollated == export->uncollated_copies)
740                                         return FALSE;
741
742                                 export->range = export->inc < 0 ? export->n_ranges - 1 : 0;
743                         }
744                         find_range (export);
745                         export->page = export->start;
746                 }
747
748         /* in/decrement the page number until we reach the first page on the next EVEN or ODD sheet
749          * if we're not collating, we have to make sure that this is done only once! */
750         } while ( export->collate == 1 &&
751                 ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 1) ||
752                 (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 0)));
753
754         return TRUE;
755 }
756
757 static void
758 ev_print_operation_export_clear_temp_file (EvPrintOperationExport *export)
759 {
760         if (!export->temp_file)
761                 return;
762
763         g_unlink (export->temp_file);
764         g_free (export->temp_file);
765         export->temp_file = NULL;
766 }
767
768 static void
769 ev_print_operation_export_run_next (EvPrintOperationExport *export)
770 {
771         EvPrintOperation *op = EV_PRINT_OPERATION (export);
772         EvPrintOperation *next;
773         EvDocument       *document;
774
775         /* First pop the current job */
776         document = op->document;
777         ev_print_queue_pop (document);
778         
779         next = ev_print_queue_peek (document);
780         if (next)
781                 ev_print_operation_export_begin (EV_PRINT_OPERATION_EXPORT (next));
782 }
783
784 static void
785 gtk_print_job_finished (GtkPrintJob            *print_job,
786                         EvPrintOperationExport *export,
787                         GError                 *error)
788 {
789         EvPrintOperation *op = EV_PRINT_OPERATION (export);
790
791         if (error) {
792                 g_set_error_literal (&export->error,
793                                      GTK_PRINT_ERROR,
794                                      GTK_PRINT_ERROR_GENERAL,
795                                      error->message);
796                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
797         } else {
798                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
799         }
800
801         ev_print_operation_export_clear_temp_file (export);
802         g_object_unref (print_job);
803
804         ev_print_operation_export_run_next (export);
805 }
806
807 static void
808 export_print_done (EvPrintOperationExport *export)
809 {
810         EvPrintOperation *op = EV_PRINT_OPERATION (export);
811         GtkPrintSettings *settings;
812         EvFileExporterCapabilities capabilities;
813         GError *error = NULL;
814
815         g_assert (export->temp_file != NULL);
816         
817         /* Some printers take into account some print settings,
818          * and others don't. However we have exported the document
819          * to a ps or pdf file according to such print settings. So,
820          * we want to send the exported file to printer with those
821          * settings set to default values.
822          */
823         settings = gtk_print_settings_copy (export->print_settings);
824         capabilities = ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
825
826         gtk_print_settings_set_page_ranges (settings, NULL, 0);
827         gtk_print_settings_set_print_pages (settings, GTK_PRINT_PAGES_ALL);
828         if (capabilities & EV_FILE_EXPORTER_CAN_COPIES)
829                 gtk_print_settings_set_n_copies (settings, 1);
830         if (capabilities & EV_FILE_EXPORTER_CAN_PAGE_SET)
831                 gtk_print_settings_set_page_set (settings, GTK_PAGE_SET_ALL);
832         if (capabilities & EV_FILE_EXPORTER_CAN_SCALE)
833                 gtk_print_settings_set_scale (settings, 1.0);
834         if (capabilities & EV_FILE_EXPORTER_CAN_COLLATE)
835                 gtk_print_settings_set_collate (settings, FALSE);
836         if (capabilities & EV_FILE_EXPORTER_CAN_REVERSE)
837                 gtk_print_settings_set_reverse (settings, FALSE);
838         if (capabilities & EV_FILE_EXPORTER_CAN_NUMBER_UP) {
839                 gtk_print_settings_set_number_up (settings, 1);
840                 gtk_print_settings_set_int (settings, "cups-"GTK_PRINT_SETTINGS_NUMBER_UP, 1);
841         }
842
843         if (export->print_preview) {
844                 GKeyFile *key_file;
845                 gchar    *data = NULL;
846                 gsize     data_len;
847                 gchar    *print_settings_file = NULL;
848
849                 key_file = g_key_file_new ();
850
851                 gtk_print_settings_to_key_file (settings, key_file, NULL);
852                 gtk_page_setup_to_key_file (export->page_setup, key_file, NULL);
853                 g_key_file_set_string (key_file, "Print Job", "title", export->job_name);
854
855                 data = g_key_file_to_data (key_file, &data_len, &error);
856                 if (data) {
857                         gint fd;
858                         
859                         fd = g_file_open_tmp ("print-settingsXXXXXX", &print_settings_file, &error);
860                         if (!error)
861                                 g_file_set_contents (print_settings_file, data, data_len, &error);
862                         close (fd);
863                         
864                         g_free (data);
865                 }
866
867                 g_key_file_free (key_file);
868
869                 if (!error) {
870                         gint    argc;
871                         gchar **argv;
872                         gchar  *cmd;
873                         gchar  *quoted_filename;
874                         gchar  *quoted_settings_filename;
875
876                         quoted_filename = g_shell_quote (export->temp_file);
877                         quoted_settings_filename = g_shell_quote (print_settings_file);
878                         cmd = g_strdup_printf ("evince-previewer --unlink-tempfile --print-settings %s %s",
879                                                quoted_settings_filename, quoted_filename);
880
881                         g_shell_parse_argv (cmd, &argc, &argv, &error);
882
883                         g_free (quoted_filename);
884                         g_free (quoted_settings_filename);
885                         g_free (cmd);
886
887                         if (!error) {
888                                 gdk_spawn_on_screen (gtk_window_get_screen (export->parent_window),
889                                                      NULL, argv, NULL,
890                                                      G_SPAWN_SEARCH_PATH,
891                                                      NULL, NULL, NULL,
892                                                      &error);
893                         }
894
895                         g_strfreev (argv);
896                 }
897
898                 if (error) {
899                         if (print_settings_file)
900                                 g_unlink (print_settings_file);
901                         g_free (print_settings_file);
902                 } else {
903                         g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
904                         /* temp_file will be deleted by the previewer */
905
906                         ev_print_operation_export_run_next (export);
907                 }
908         } else {
909                 GtkPrintJob *job;
910                 
911                 job = gtk_print_job_new (export->job_name,
912                                          export->printer,
913                                          settings,
914                                          export->page_setup);
915                 gtk_print_job_set_source_file (job, export->temp_file, &error);
916                 if (!error){
917                         gtk_print_job_send (job,
918                                             (GtkPrintJobCompleteFunc)gtk_print_job_finished,
919                                             g_object_ref (export),
920                                             (GDestroyNotify)g_object_unref);
921                 }
922         }
923         g_object_unref (settings);
924
925         if (error) {
926                 g_set_error_literal (&export->error,
927                                      GTK_PRINT_ERROR,
928                                      GTK_PRINT_ERROR_GENERAL,
929                                      error->message);
930                 g_error_free (error);
931                 ev_print_operation_export_clear_temp_file (export);
932                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
933
934                 ev_print_operation_export_run_next (export);
935         }
936 }
937
938 static void
939 export_print_page_idle_finished (EvPrintOperationExport *export)
940 {
941         export->idle_id = 0;
942 }
943
944 static void
945 export_job_finished (EvJobExport            *job,
946                      EvPrintOperationExport *export)
947 {
948         EvPrintOperation *op = EV_PRINT_OPERATION (export);
949
950         if (export->pages_per_sheet == 1 ||
951            ( export->page_count % export->pages_per_sheet == 0 &&
952            ( export->page_set == GTK_PAGE_SET_ALL ||
953            ( export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0 ) ||
954            ( export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1 ) ) ) ) {
955
956                 ev_document_doc_mutex_lock ();
957                 ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
958                 ev_document_doc_mutex_unlock ();
959         }
960
961         /* Reschedule */
962         export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
963                                            (GSourceFunc)export_print_page,
964                                            export,
965                                            (GDestroyNotify)export_print_page_idle_finished);
966 }
967
968 static void
969 export_job_cancelled (EvJobExport            *job,
970                       EvPrintOperationExport *export)
971 {
972         export_cancel (export);
973 }
974
975 static void
976 export_cancel (EvPrintOperationExport *export)
977 {
978         EvPrintOperation *op = EV_PRINT_OPERATION (export);
979
980         if (export->idle_id > 0)
981                 g_source_remove (export->idle_id);
982         export->idle_id = 0;
983
984         if (export->job_export) {
985                 g_signal_handlers_disconnect_by_func (export->job_export,
986                                                       export_job_finished,
987                                                       export);
988                 g_signal_handlers_disconnect_by_func (export->job_export,
989                                                       export_job_cancelled,
990                                                       export);
991                 g_object_unref (export->job_export);
992                 export->job_export = NULL;
993         }
994         
995         if (export->fd != -1) {
996                 close (export->fd);
997                 export->fd = -1;
998         }
999
1000         ev_print_operation_export_clear_temp_file (export);
1001
1002         g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
1003
1004         ev_print_operation_export_run_next (export);
1005 }
1006
1007 static void
1008 update_progress (EvPrintOperationExport *export)
1009 {
1010         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1011
1012         ev_print_operation_update_status (op, export->total,
1013                                           export->n_pages_to_print,
1014                                           export->total / (gdouble)export->n_pages_to_print);
1015 }
1016
1017 static gboolean
1018 export_print_page (EvPrintOperationExport *export)
1019 {
1020         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1021
1022         if (!export->temp_file)
1023                 return FALSE; /* cancelled */
1024
1025         export->total++;
1026         export->collated++;
1027
1028         /* note: when collating, page_count is increased in export_print_inc_page */
1029         if (!export->collate) {
1030                 export->page_count++;
1031                 export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
1032         }
1033
1034         if (export->collated == export->collated_copies) {
1035                 export->collated = 0;
1036                 if (!export_print_inc_page (export)) {
1037                         ev_document_doc_mutex_lock ();
1038                         ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
1039                         ev_document_doc_mutex_unlock ();
1040
1041                         close (export->fd);
1042                         export->fd = -1;
1043                         update_progress (export);
1044                         export_print_done (export);
1045
1046                         return FALSE;
1047                 }
1048         }
1049
1050         /* we're not collating and we've reached a sheet from the wrong sheet set */
1051         if (!export->collate &&
1052             ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
1053             (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1))) {
1054
1055                 do {
1056                         export->page_count++;
1057                         export->collated++;
1058                         export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
1059
1060                         if (export->collated == export->collated_copies) {
1061                                 export->collated = 0;
1062
1063                                 if (!export_print_inc_page (export)) {
1064                                         ev_document_doc_mutex_lock ();
1065                                         ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
1066                                         ev_document_doc_mutex_unlock ();
1067
1068                                         close (export->fd);
1069                                         export->fd = -1;
1070
1071                                         update_progress (export);
1072
1073                                         export_print_done (export);
1074                                         return FALSE;
1075                                 }
1076                         }
1077
1078                 } while ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
1079                           (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1));
1080
1081         }
1082
1083         if (export->pages_per_sheet == 1 ||
1084             (export->page_count % export->pages_per_sheet == 1 &&
1085             (export->page_set == GTK_PAGE_SET_ALL ||
1086             (export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0) ||
1087             (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1)))) {
1088                 ev_document_doc_mutex_lock ();
1089                 ev_file_exporter_begin_page (EV_FILE_EXPORTER (op->document));
1090                 ev_document_doc_mutex_unlock ();
1091         }
1092
1093         if (!export->job_export) {
1094                 export->job_export = ev_job_export_new (op->document);
1095                 g_signal_connect (export->job_export, "finished",
1096                                   G_CALLBACK (export_job_finished),
1097                                   (gpointer)export);
1098                 g_signal_connect (export->job_export, "cancelled",
1099                                   G_CALLBACK (export_job_cancelled),
1100                                   (gpointer)export);
1101         }
1102
1103         ev_job_export_set_page (EV_JOB_EXPORT (export->job_export), export->page);
1104         ev_job_scheduler_push_job (export->job_export, EV_JOB_PRIORITY_NONE);
1105
1106         update_progress (export);
1107         
1108         return FALSE;
1109 }
1110
1111 static void
1112 ev_print_operation_export_begin (EvPrintOperationExport *export)
1113 {
1114         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1115
1116         if (!export->temp_file)
1117                 return; /* cancelled */
1118         
1119         ev_document_doc_mutex_lock ();
1120         ev_file_exporter_begin (EV_FILE_EXPORTER (op->document), &export->fc);
1121         ev_document_doc_mutex_unlock ();
1122
1123         export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
1124                                            (GSourceFunc)export_print_page,
1125                                            export,
1126                                            (GDestroyNotify)export_print_page_idle_finished);    
1127 }
1128
1129 static void
1130 ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dialog,
1131                                                     gint                    response,
1132                                                     EvPrintOperationExport *export)
1133 {
1134         GtkPrintPages     print_pages;
1135         GtkPrintSettings *print_settings;
1136         GtkPageSetup     *page_setup;
1137         GtkPrinter       *printer;
1138         gdouble           scale;
1139         gdouble           width;
1140         gdouble           height;
1141         gint              first_page;
1142         gint              last_page;
1143         const gchar      *file_format;
1144         gchar            *filename;
1145         GError           *error = NULL;
1146         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1147         
1148         if (response != GTK_RESPONSE_OK &&
1149             response != GTK_RESPONSE_APPLY) {
1150                 gtk_widget_destroy (GTK_WIDGET (dialog));
1151                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
1152
1153                 return;
1154         }
1155
1156         export->print_preview = (response == GTK_RESPONSE_APPLY);
1157         
1158         printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog));
1159         ev_print_operation_export_set_printer (export, printer);
1160
1161         print_settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog));
1162         ev_print_operation_export_set_print_settings (op, print_settings);
1163
1164         page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog));
1165         ev_print_operation_export_set_default_page_setup (op, page_setup);
1166
1167         if (!gtk_printer_accepts_ps (export->printer)) {
1168                 gtk_widget_destroy (GTK_WIDGET (dialog));
1169                 
1170                 g_set_error_literal (&export->error,
1171                                      GTK_PRINT_ERROR,
1172                                      GTK_PRINT_ERROR_GENERAL,
1173                                      _("Printing is not supported on this printer."));
1174                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1175                 
1176                 return;
1177         }
1178
1179         file_format = gtk_print_settings_get (print_settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
1180         
1181         filename = g_strdup_printf ("evince_print.%s.XXXXXX", file_format != NULL ? file_format : "");
1182         export->fd = g_file_open_tmp (filename, &export->temp_file, &error);
1183         g_free (filename);
1184         if (export->fd <= -1) {
1185                 gtk_widget_destroy (GTK_WIDGET (dialog));
1186                 
1187                 g_set_error_literal (&export->error,
1188                                      GTK_PRINT_ERROR,
1189                                      GTK_PRINT_ERROR_GENERAL,
1190                                      error->message);
1191                 g_error_free (error);
1192                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1193
1194                 return;
1195         }
1196
1197         export->current_page = gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog));
1198         export->page_set = gtk_print_settings_get_page_set (print_settings);
1199         print_pages = gtk_print_settings_get_print_pages (print_settings);
1200         
1201         switch (print_pages) {
1202         case GTK_PRINT_PAGES_CURRENT:
1203                 export->ranges = &export->one_range;
1204                 
1205                 export->ranges[0].start = export->current_page;
1206                 export->ranges[0].end = export->current_page;
1207                 export->n_ranges = 1;
1208                                 
1209                 break;
1210         case GTK_PRINT_PAGES_RANGES: {
1211                 gint i;
1212                 
1213                 export->ranges = gtk_print_settings_get_page_ranges (print_settings, &export->n_ranges);
1214                 for (i = 0; i < export->n_ranges; i++)
1215                         if (export->ranges[i].end == -1 || export->ranges[i].end >= export->n_pages)
1216                                 export->ranges[i].end = export->n_pages - 1;
1217         }
1218                 break;
1219         default:
1220                 g_warning ("Unsupported print pages setting\n");
1221         case GTK_PRINT_PAGES_ALL:
1222                 export->ranges = &export->one_range;
1223
1224                 export->ranges[0].start = 0;
1225                 export->ranges[0].end = export->n_pages - 1;
1226                 export->n_ranges = 1;
1227                 
1228                 break;
1229         }
1230
1231         if (export->n_ranges < 1 || !clamp_ranges (export)) {
1232                 GtkWidget *message_dialog;
1233
1234                 message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
1235                                                  GTK_DIALOG_MODAL,
1236                                                  GTK_MESSAGE_WARNING,
1237                                                  GTK_BUTTONS_CLOSE,
1238                                                  "%s", _("Invalid page selection"));
1239                 gtk_window_set_title (GTK_WINDOW (message_dialog), _("Warning"));
1240                 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
1241                                                           "%s", _("Your print range selection does not include any page"));
1242                 g_signal_connect (message_dialog, "response",
1243                                   G_CALLBACK (gtk_widget_destroy),
1244                                   NULL);
1245                 gtk_widget_show (message_dialog);
1246
1247                 return;
1248         } else  ev_print_operation_update_status (op, -1, -1, 0.0);
1249  
1250         width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1251         height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1252         scale = gtk_print_settings_get_scale (print_settings) * 0.01;
1253         if (scale != 1.0) {
1254                 width *= scale;
1255                 height *= scale;
1256         }
1257
1258         export->pages_per_sheet = MAX (1, gtk_print_settings_get_number_up (print_settings));
1259         
1260         export->copies = gtk_print_settings_get_n_copies (print_settings);
1261         export->collate = gtk_print_settings_get_collate (print_settings);
1262         export->reverse = gtk_print_settings_get_reverse (print_settings);
1263
1264         if (export->collate) {
1265                 export->uncollated_copies = export->copies;
1266                 export->collated_copies = 1;
1267         } else {
1268                 export->uncollated_copies = 1;
1269                 export->collated_copies = export->copies;
1270         }
1271
1272         if (export->reverse) {
1273                 export->range = export->n_ranges - 1;
1274                 export->inc = -1;
1275         } else {
1276                 export->range = 0;
1277                 export->inc = 1;
1278         }
1279         find_range (export);
1280
1281         export->page = export->start - export->inc;
1282         export->collated = export->collated_copies - 1;
1283
1284         get_first_and_last_page (export, &first_page, &last_page);
1285
1286         export->fc.format = file_format && g_ascii_strcasecmp (file_format, "pdf") == 0 ?
1287                 EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
1288         export->fc.filename = export->temp_file;
1289         export->fc.first_page = MIN (first_page, last_page);
1290         export->fc.last_page = MAX (first_page, last_page);
1291         export->fc.paper_width = width;
1292         export->fc.paper_height = height;
1293         export->fc.duplex = FALSE;
1294         export->fc.pages_per_sheet = export->pages_per_sheet;
1295
1296         if (ev_print_queue_is_empty (op->document))
1297                 ev_print_operation_export_begin (export);
1298
1299         ev_print_queue_push (op);
1300
1301         g_signal_emit (op, signals[BEGIN_PRINT], 0);
1302         
1303         gtk_widget_destroy (GTK_WIDGET (dialog));
1304 }
1305
1306 static void
1307 ev_print_operation_export_run (EvPrintOperation *op,
1308                                GtkWindow        *parent)
1309 {
1310         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1311         GtkWidget              *dialog;
1312         GtkPrintCapabilities    capabilities;
1313
1314         ev_print_queue_init ();
1315
1316         export->parent_window = parent;
1317         export->error = NULL;
1318         
1319         dialog = gtk_print_unix_dialog_new (_("Print"), parent);
1320         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1321         
1322         capabilities = GTK_PRINT_CAPABILITY_PREVIEW |
1323                 ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
1324         gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog),
1325                                                        capabilities);
1326 #if GTK_CHECK_VERSION (2, 17, 4)
1327         gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1328                                                     export->embed_page_setup);
1329 #endif
1330
1331         gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog),
1332                                                 export->current_page);
1333         
1334         gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog),
1335                                             export->print_settings);
1336         
1337         if (export->page_setup)
1338                 gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1339                                                       export->page_setup);
1340
1341         g_signal_connect (dialog, "response",
1342                           G_CALLBACK (ev_print_operation_export_print_dialog_response_cb),
1343                           export);
1344
1345         gtk_window_present (GTK_WINDOW (dialog));
1346 }
1347
1348 static void
1349 ev_print_operation_export_cancel (EvPrintOperation *op)
1350 {
1351         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1352
1353         if (export->job_export &&
1354             !ev_job_is_finished (export->job_export)) {
1355                 ev_job_cancel (export->job_export);
1356         } else {
1357                 export_cancel (export);
1358         }
1359 }
1360
1361 static void
1362 ev_print_operation_export_get_error (EvPrintOperation *op,
1363                                      GError          **error)
1364 {
1365         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1366
1367         g_propagate_error (error, export->error);
1368         export->error = NULL;
1369 }
1370
1371 static void
1372 ev_print_operation_export_set_embed_page_setup (EvPrintOperation *op,
1373                                                 gboolean          embed)
1374 {
1375 #if GTK_CHECK_VERSION (2, 17, 4)
1376         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1377
1378         export->embed_page_setup = embed;
1379 #endif
1380 }
1381
1382 static gboolean
1383 ev_print_operation_export_get_embed_page_setup (EvPrintOperation *op)
1384 {
1385         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1386
1387         return export->embed_page_setup;
1388 }
1389
1390 static void
1391 ev_print_operation_export_finalize (GObject *object)
1392 {
1393         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (object);
1394
1395         if (export->idle_id > 0) {
1396                 g_source_remove (export->idle_id);
1397                 export->idle_id = 0;
1398         }
1399
1400         if (export->fd != -1) {
1401                 close (export->fd);
1402                 export->fd = -1;
1403         }
1404         
1405         if (export->ranges) {
1406                 if (export->ranges != &export->one_range)
1407                         g_free (export->ranges);
1408                 export->ranges = NULL;
1409                 export->n_ranges = 0;
1410         }
1411
1412         if (export->temp_file) {
1413                 g_free (export->temp_file);
1414                 export->temp_file = NULL;
1415         }
1416
1417         if (export->job_name) {
1418                 g_free (export->job_name);
1419                 export->job_name = NULL;
1420         }
1421
1422         if (export->job_export) {
1423                 if (!ev_job_is_finished (export->job_export))
1424                         ev_job_cancel (export->job_export);
1425                 g_signal_handlers_disconnect_by_func (export->job_export,
1426                                                       export_job_finished,
1427                                                       export);
1428                 g_signal_handlers_disconnect_by_func (export->job_export,
1429                                                       export_job_cancelled,
1430                                                       export);
1431                 g_object_unref (export->job_export);
1432                 export->job_export = NULL;
1433         }
1434
1435         if (export->error) {
1436                 g_error_free (export->error);
1437                 export->error = NULL;
1438         }
1439
1440         if (export->print_settings) {
1441                 g_object_unref (export->print_settings);
1442                 export->print_settings = NULL;
1443         }
1444
1445         if (export->page_setup) {
1446                 g_object_unref (export->page_setup);
1447                 export->page_setup = NULL;
1448         }
1449
1450         if (export->printer) {
1451                 g_object_unref (export->printer);
1452                 export->printer = NULL;
1453         }
1454
1455         (* G_OBJECT_CLASS (ev_print_operation_export_parent_class)->finalize) (object);
1456 }
1457
1458 static void
1459 ev_print_operation_export_init (EvPrintOperationExport *export)
1460 {
1461         /* sheets are counted from 1 to be physical */
1462         export->sheet = 1;
1463 }
1464
1465 static GObject *
1466 ev_print_operation_export_constructor (GType                  type,
1467                                        guint                  n_construct_properties,
1468                                        GObjectConstructParam *construct_params)
1469 {
1470         GObject                *object;
1471         EvPrintOperationExport *export;
1472         EvPrintOperation       *op;
1473         
1474         object = G_OBJECT_CLASS (ev_print_operation_export_parent_class)->constructor (type,
1475                                                                                        n_construct_properties,
1476                                                                                        construct_params);
1477         export = EV_PRINT_OPERATION_EXPORT (object);
1478         op = EV_PRINT_OPERATION (object);
1479         export->n_pages = ev_document_get_n_pages (op->document);
1480
1481         return object;
1482 }
1483
1484 static void
1485 ev_print_operation_export_class_init (EvPrintOperationExportClass *klass)
1486 {
1487         GObjectClass          *g_object_class = G_OBJECT_CLASS (klass);
1488         EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
1489
1490         ev_print_op_class->set_current_page = ev_print_operation_export_set_current_page;
1491         ev_print_op_class->set_print_settings = ev_print_operation_export_set_print_settings;
1492         ev_print_op_class->get_print_settings = ev_print_operation_export_get_print_settings;
1493         ev_print_op_class->set_default_page_setup = ev_print_operation_export_set_default_page_setup;
1494         ev_print_op_class->get_default_page_setup = ev_print_operation_export_get_default_page_setup;
1495         ev_print_op_class->set_job_name = ev_print_operation_export_set_job_name;
1496         ev_print_op_class->get_job_name = ev_print_operation_export_get_job_name;
1497         ev_print_op_class->run = ev_print_operation_export_run;
1498         ev_print_op_class->cancel = ev_print_operation_export_cancel;
1499         ev_print_op_class->get_error = ev_print_operation_export_get_error;
1500         ev_print_op_class->set_embed_page_setup = ev_print_operation_export_set_embed_page_setup;
1501         ev_print_op_class->get_embed_page_setup = ev_print_operation_export_get_embed_page_setup;
1502
1503         g_object_class->constructor = ev_print_operation_export_constructor;
1504         g_object_class->finalize = ev_print_operation_export_finalize;
1505 }
1506
1507 #endif /* GTKUNIXPRINT_ENABLED */
1508
1509 #if GTK_CHECK_VERSION (2, 17, 1)
1510 /* Print to cairo interface */
1511 #define EV_TYPE_PRINT_OPERATION_PRINT         (ev_print_operation_print_get_type())
1512 #define EV_PRINT_OPERATION_PRINT(object)      (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_PRINT, EvPrintOperationPrint))
1513 #define EV_PRINT_OPERATION_PRINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PRINT_OPERATION_PRINT, EvPrintOperationPrintClass))
1514 #define EV_IS_PRINT_OPERATION_PRINT(object)   (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PRINT_OPERATION_PRINT))
1515
1516 typedef struct _EvPrintOperationPrint      EvPrintOperationPrint;
1517 typedef struct _EvPrintOperationPrintClass EvPrintOperationPrintClass;
1518
1519 static GType ev_print_operation_print_get_type (void) G_GNUC_CONST;
1520
1521 struct _EvPrintOperationPrint {
1522         EvPrintOperation parent;
1523
1524         GtkPrintOperation *op;
1525         gint               n_pages_to_print;
1526         gint               total;
1527         EvJob             *job_print;
1528         gchar             *job_name;
1529 };
1530
1531 struct _EvPrintOperationPrintClass {
1532         EvPrintOperationClass parent_class;
1533 };
1534
1535 G_DEFINE_TYPE (EvPrintOperationPrint, ev_print_operation_print, EV_TYPE_PRINT_OPERATION)
1536
1537 static void
1538 ev_print_operation_print_set_current_page (EvPrintOperation *op,
1539                                            gint              current_page)
1540 {
1541         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1542
1543         gtk_print_operation_set_current_page (print->op, current_page);
1544 }
1545
1546 static void
1547 ev_print_operation_print_set_print_settings (EvPrintOperation *op,
1548                                              GtkPrintSettings *print_settings)
1549 {
1550         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1551
1552         gtk_print_operation_set_print_settings (print->op, print_settings);
1553 }
1554
1555 static GtkPrintSettings *
1556 ev_print_operation_print_get_print_settings (EvPrintOperation *op)
1557 {
1558         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1559
1560         return gtk_print_operation_get_print_settings (print->op);
1561 }
1562
1563 static void
1564 ev_print_operation_print_set_default_page_setup (EvPrintOperation *op,
1565                                                  GtkPageSetup     *page_setup)
1566 {
1567         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1568
1569         gtk_print_operation_set_default_page_setup (print->op, page_setup);
1570 }
1571
1572 static GtkPageSetup *
1573 ev_print_operation_print_get_default_page_setup (EvPrintOperation *op)
1574 {
1575         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1576
1577         return gtk_print_operation_get_default_page_setup (print->op);
1578 }
1579
1580 static void
1581 ev_print_operation_print_set_job_name (EvPrintOperation *op,
1582                                        const gchar      *job_name)
1583 {
1584         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1585
1586         g_free (print->job_name);
1587         print->job_name = g_strdup (job_name);
1588
1589         gtk_print_operation_set_job_name (print->op, print->job_name);
1590 }
1591
1592 static const gchar *
1593 ev_print_operation_print_get_job_name (EvPrintOperation *op)
1594 {
1595         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1596
1597         if (!print->job_name) {
1598                 gchar *name;
1599
1600                 g_object_get (print->op, "job_name", &name, NULL);
1601                 print->job_name = name;
1602         }
1603
1604         return print->job_name;
1605 }
1606
1607 static void
1608 ev_print_operation_print_run (EvPrintOperation *op,
1609                               GtkWindow        *parent)
1610 {
1611         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1612
1613         gtk_print_operation_run (print->op,
1614                                  GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
1615                                  parent, NULL);
1616 }
1617
1618 static void
1619 ev_print_operation_print_cancel (EvPrintOperation *op)
1620 {
1621         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1622
1623         gtk_print_operation_cancel (print->op);
1624 }
1625
1626 static void
1627 ev_print_operation_print_get_error (EvPrintOperation *op,
1628                                     GError          **error)
1629 {
1630         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1631
1632         gtk_print_operation_get_error (print->op, error);
1633 }
1634
1635 static void
1636 ev_print_operation_print_set_embed_page_setup (EvPrintOperation *op,
1637                                                gboolean          embed)
1638 {
1639 #if GTK_CHECK_VERSION (2, 17, 4)
1640         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1641
1642         gtk_print_operation_set_embed_page_setup (print->op, embed);
1643 #endif
1644 }
1645
1646 static gboolean
1647 ev_print_operation_print_get_embed_page_setup (EvPrintOperation *op)
1648 {
1649 #if GTK_CHECK_VERSION (2, 17, 4)
1650         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1651
1652         return gtk_print_operation_get_embed_page_setup (print->op);
1653 #else
1654         return FALSE;
1655 #endif
1656 }
1657
1658 static void
1659 ev_print_operation_print_begin_print (EvPrintOperationPrint *print,
1660                                       GtkPrintContext       *context)
1661 {
1662         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1663         gint              n_pages;
1664
1665         n_pages = ev_document_get_n_pages (op->document);
1666         gtk_print_operation_set_n_pages (print->op, n_pages);
1667         ev_print_operation_update_status (op, -1, n_pages, 0);
1668
1669         g_signal_emit (op, signals[BEGIN_PRINT], 0);
1670 }
1671
1672 static void
1673 ev_print_operation_print_done (EvPrintOperationPrint  *print,
1674                                GtkPrintOperationResult result)
1675 {
1676         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1677
1678         ev_print_operation_update_status (op, 0, print->n_pages_to_print, 1.0);
1679
1680         g_signal_emit (op, signals[DONE], 0, result);
1681 }
1682
1683 static void
1684 ev_print_operation_print_status_changed (EvPrintOperationPrint *print)
1685 {
1686 #ifdef HAVE_GTK_PRINT_OPERATION_GET_N_PAGES_TO_PRINT
1687         GtkPrintStatus status;
1688
1689         status = gtk_print_operation_get_status (print->op);
1690         if (status == GTK_PRINT_STATUS_GENERATING_DATA)
1691                 print->n_pages_to_print = gtk_print_operation_get_n_pages_to_print (print->op);
1692 #endif
1693 }
1694
1695 static void
1696 print_job_finished (EvJobPrint            *job,
1697                     EvPrintOperationPrint *print)
1698 {
1699         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1700
1701         gtk_print_operation_draw_page_finish (print->op);
1702 #ifdef HAVE_GTK_PRINT_OPERATION_GET_N_PAGES_TO_PRINT
1703         print->total++;
1704         ev_print_operation_update_status (op, print->total,
1705                                           print->n_pages_to_print,
1706                                           print->total / (gdouble)print->n_pages_to_print);
1707 #endif
1708         ev_job_print_set_cairo (job, NULL);
1709 }
1710
1711 static void
1712 print_job_cancelled (EvJobPrint            *job,
1713                      EvPrintOperationPrint *print)
1714 {
1715         gtk_print_operation_cancel (print->op);
1716 }
1717
1718 static void
1719 ev_print_operation_print_request_page_setup (EvPrintOperationPrint *print,
1720                                              GtkPrintContext       *context,
1721                                              gint                   page_nr,
1722                                              GtkPageSetup          *setup)
1723 {
1724         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1725         gdouble           width, height;
1726
1727         ev_document_get_page_size (op->document, page_nr,
1728                                    &width, &height);
1729         if (width > height)
1730                 gtk_page_setup_set_orientation (setup, GTK_PAGE_ORIENTATION_LANDSCAPE);
1731         else
1732                 gtk_page_setup_set_orientation (setup, GTK_PAGE_ORIENTATION_PORTRAIT);
1733 }
1734
1735 static void
1736 ev_print_operation_print_draw_page (EvPrintOperationPrint *print,
1737                                     GtkPrintContext       *context,
1738                                     gint                   page)
1739 {
1740         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1741         cairo_t          *cr;
1742         gdouble           cr_width, cr_height;
1743         gdouble           width, height, scale;
1744
1745         gtk_print_operation_set_defer_drawing (print->op);
1746
1747         if (!print->job_print) {
1748                 print->job_print = ev_job_print_new (op->document);
1749                 g_signal_connect (G_OBJECT (print->job_print), "finished",
1750                                   G_CALLBACK (print_job_finished),
1751                                   (gpointer)print);
1752                 g_signal_connect (G_OBJECT (print->job_print), "cancelled",
1753                                   G_CALLBACK (print_job_cancelled),
1754                                   (gpointer)print);
1755         }
1756
1757         ev_job_print_set_page (EV_JOB_PRINT (print->job_print), page);
1758
1759         cr = gtk_print_context_get_cairo_context (context);
1760         cr_width = gtk_print_context_get_width (context);
1761         cr_height = gtk_print_context_get_height (context);
1762         ev_document_get_page_size (op->document, page,
1763                                    &width, &height);
1764         if (cr_width / width < cr_height / height)
1765                 scale = cr_width / width;
1766         else
1767                 scale = cr_height / height;
1768         cairo_scale (cr, scale, scale);
1769
1770         ev_job_print_set_cairo (EV_JOB_PRINT (print->job_print), cr);
1771         ev_job_scheduler_push_job (print->job_print, EV_JOB_PRIORITY_NONE);
1772 }
1773
1774 static void
1775 ev_print_operation_print_finalize (GObject *object)
1776 {
1777         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (object);
1778
1779         if (print->op) {
1780                 g_object_unref (print->op);
1781                 print->op = NULL;
1782         }
1783
1784         if (print->job_name) {
1785                 g_free (print->job_name);
1786                 print->job_name = NULL;
1787         }
1788
1789         if (print->job_print) {
1790                 if (!ev_job_is_finished (print->job_print))
1791                         ev_job_cancel (print->job_print);
1792                 g_signal_handlers_disconnect_by_func (print->job_print,
1793                                                       print_job_finished,
1794                                                       print);
1795                 g_signal_handlers_disconnect_by_func (print->job_print,
1796                                                       print_job_cancelled,
1797                                                       print);
1798                 g_object_unref (print->job_print);
1799                 print->job_print = NULL;
1800         }
1801
1802         (* G_OBJECT_CLASS (ev_print_operation_print_parent_class)->finalize) (object);
1803 }
1804
1805 static void
1806 ev_print_operation_print_init (EvPrintOperationPrint *print)
1807 {
1808         print->op = gtk_print_operation_new ();
1809         g_signal_connect_swapped (print->op, "begin_print",
1810                                   G_CALLBACK (ev_print_operation_print_begin_print),
1811                                   print);
1812         g_signal_connect_swapped (print->op, "done",
1813                                   G_CALLBACK (ev_print_operation_print_done),
1814                                   print);
1815         g_signal_connect_swapped (print->op, "draw_page",
1816                                   G_CALLBACK (ev_print_operation_print_draw_page),
1817                                   print);
1818         g_signal_connect_swapped (print->op, "status_changed",
1819                                   G_CALLBACK (ev_print_operation_print_status_changed),
1820                                   print);
1821         g_signal_connect_swapped (print->op, "request_page_setup",
1822                                   G_CALLBACK (ev_print_operation_print_request_page_setup),
1823                                   print);
1824         gtk_print_operation_set_allow_async (print->op, TRUE);
1825 }
1826
1827 static void
1828 ev_print_operation_print_class_init (EvPrintOperationPrintClass *klass)
1829 {
1830         GObjectClass          *g_object_class = G_OBJECT_CLASS (klass);
1831         EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
1832
1833         ev_print_op_class->set_current_page = ev_print_operation_print_set_current_page;
1834         ev_print_op_class->set_print_settings = ev_print_operation_print_set_print_settings;
1835         ev_print_op_class->get_print_settings = ev_print_operation_print_get_print_settings;
1836         ev_print_op_class->set_default_page_setup = ev_print_operation_print_set_default_page_setup;
1837         ev_print_op_class->get_default_page_setup = ev_print_operation_print_get_default_page_setup;
1838         ev_print_op_class->set_job_name = ev_print_operation_print_set_job_name;
1839         ev_print_op_class->get_job_name = ev_print_operation_print_get_job_name;
1840         ev_print_op_class->run = ev_print_operation_print_run;
1841         ev_print_op_class->cancel = ev_print_operation_print_cancel;
1842         ev_print_op_class->get_error = ev_print_operation_print_get_error;
1843         ev_print_op_class->set_embed_page_setup = ev_print_operation_print_set_embed_page_setup;
1844         ev_print_op_class->get_embed_page_setup = ev_print_operation_print_get_embed_page_setup;
1845
1846         g_object_class->finalize = ev_print_operation_print_finalize;
1847 }
1848 #endif /* GTK_CHECK_VERSION (2, 17, 1) */
1849
1850 gboolean ev_print_operation_exists_for_document (EvDocument *document)
1851 {
1852 #if GTKUNIXPRINT_ENABLED
1853 #if GTK_CHECK_VERSION (2, 17, 1)
1854         return (EV_IS_FILE_EXPORTER(document) || EV_IS_DOCUMENT_PRINT(document));
1855 #else
1856         return EV_IS_FILE_EXPORTER(document);
1857 #endif
1858 #else /* ! GTKUNIXPRINT_ENABLED */
1859 #if GTK_CHECK_VERSION (2, 17, 1)
1860         return EV_IS_DOCUMENT_PRINT(document);
1861 #else
1862         return FALSE;
1863 #endif
1864 #endif /* GTKUNIXPRINT_ENABLED */
1865 }
1866
1867 /* Factory method */
1868 EvPrintOperation *
1869 ev_print_operation_new (EvDocument *document)
1870 {
1871         EvPrintOperation *op = NULL;
1872
1873         g_return_val_if_fail (ev_print_operation_exists_for_document (document), NULL);
1874
1875 #if GTK_CHECK_VERSION (2, 17, 1)
1876         if (EV_IS_DOCUMENT_PRINT (document))
1877                 op = EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_PRINT,
1878                                                        "document", document, NULL));
1879         else
1880 #endif
1881 #if GTKUNIXPRINT_ENABLED
1882                 op = EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_EXPORT,
1883                                                        "document", document, NULL));
1884 #endif
1885         return op;
1886 }