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