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