]> www.fi.muni.cz Git - evince.git/blob - libview/ev-print-operation.c
libview: make sure gtk_print_operation_cancel() is called from draw-page callback
[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                         gint    argc;
859                         gchar **argv;
860                         gchar  *cmd;
861                         gchar  *quoted_filename;
862                         gchar  *quoted_settings_filename;
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_shell_parse_argv (cmd, &argc, &argv, &error);
870
871                         g_free (quoted_filename);
872                         g_free (quoted_settings_filename);
873                         g_free (cmd);
874
875                         if (!error) {
876                                 gdk_spawn_on_screen (gtk_window_get_screen (export->parent_window),
877                                                      NULL, argv, NULL,
878                                                      G_SPAWN_SEARCH_PATH,
879                                                      NULL, NULL, NULL,
880                                                      &error);
881                         }
882
883                         g_strfreev (argv);
884                 }
885
886                 if (error) {
887                         if (print_settings_file)
888                                 g_unlink (print_settings_file);
889                         g_free (print_settings_file);
890                 } else {
891                         g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
892                         /* temp_file will be deleted by the previewer */
893
894                         ev_print_operation_export_run_next (export);
895                 }
896         } else {
897                 GtkPrintJob *job;
898                 
899                 job = gtk_print_job_new (export->job_name,
900                                          export->printer,
901                                          settings,
902                                          export->page_setup);
903                 gtk_print_job_set_source_file (job, export->temp_file, &error);
904                 if (!error){
905                         gtk_print_job_send (job,
906                                             (GtkPrintJobCompleteFunc)gtk_print_job_finished,
907                                             g_object_ref (export),
908                                             (GDestroyNotify)g_object_unref);
909                 }
910         }
911         g_object_unref (settings);
912
913         if (error) {
914                 g_set_error_literal (&export->error,
915                                      GTK_PRINT_ERROR,
916                                      GTK_PRINT_ERROR_GENERAL,
917                                      error->message);
918                 g_error_free (error);
919                 ev_print_operation_export_clear_temp_file (export);
920                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
921
922                 ev_print_operation_export_run_next (export);
923         }
924 }
925
926 static void
927 export_print_page_idle_finished (EvPrintOperationExport *export)
928 {
929         export->idle_id = 0;
930 }
931
932 static void
933 export_job_finished (EvJobExport            *job,
934                      EvPrintOperationExport *export)
935 {
936         EvPrintOperation *op = EV_PRINT_OPERATION (export);
937
938         if (export->pages_per_sheet == 1 ||
939            ( export->page_count % export->pages_per_sheet == 0 &&
940            ( export->page_set == GTK_PAGE_SET_ALL ||
941            ( export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0 ) ||
942            ( export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1 ) ) ) ) {
943
944                 ev_document_doc_mutex_lock ();
945                 ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
946                 ev_document_doc_mutex_unlock ();
947         }
948
949         /* Reschedule */
950         export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
951                                            (GSourceFunc)export_print_page,
952                                            export,
953                                            (GDestroyNotify)export_print_page_idle_finished);
954 }
955
956 static void
957 export_job_cancelled (EvJobExport            *job,
958                       EvPrintOperationExport *export)
959 {
960         export_cancel (export);
961 }
962
963 static void
964 export_cancel (EvPrintOperationExport *export)
965 {
966         EvPrintOperation *op = EV_PRINT_OPERATION (export);
967
968         if (export->idle_id > 0)
969                 g_source_remove (export->idle_id);
970         export->idle_id = 0;
971
972         if (export->job_export) {
973                 g_signal_handlers_disconnect_by_func (export->job_export,
974                                                       export_job_finished,
975                                                       export);
976                 g_signal_handlers_disconnect_by_func (export->job_export,
977                                                       export_job_cancelled,
978                                                       export);
979                 g_object_unref (export->job_export);
980                 export->job_export = NULL;
981         }
982         
983         if (export->fd != -1) {
984                 close (export->fd);
985                 export->fd = -1;
986         }
987
988         ev_print_operation_export_clear_temp_file (export);
989
990         g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
991
992         ev_print_operation_export_run_next (export);
993 }
994
995 static void
996 update_progress (EvPrintOperationExport *export)
997 {
998         EvPrintOperation *op = EV_PRINT_OPERATION (export);
999
1000         ev_print_operation_update_status (op, export->total,
1001                                           export->n_pages_to_print,
1002                                           export->total / (gdouble)export->n_pages_to_print);
1003 }
1004
1005 static gboolean
1006 export_print_page (EvPrintOperationExport *export)
1007 {
1008         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1009
1010         if (!export->temp_file)
1011                 return FALSE; /* cancelled */
1012
1013         export->total++;
1014         export->collated++;
1015
1016         /* note: when collating, page_count is increased in export_print_inc_page */
1017         if (!export->collate) {
1018                 export->page_count++;
1019                 export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
1020         }
1021
1022         if (export->collated == export->collated_copies) {
1023                 export->collated = 0;
1024                 if (!export_print_inc_page (export)) {
1025                         ev_document_doc_mutex_lock ();
1026                         ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
1027                         ev_document_doc_mutex_unlock ();
1028
1029                         close (export->fd);
1030                         export->fd = -1;
1031                         update_progress (export);
1032                         export_print_done (export);
1033
1034                         return FALSE;
1035                 }
1036         }
1037
1038         /* we're not collating and we've reached a sheet from the wrong sheet set */
1039         if (!export->collate &&
1040             ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
1041             (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1))) {
1042
1043                 do {
1044                         export->page_count++;
1045                         export->collated++;
1046                         export->sheet = 1 + (export->page_count - 1) / export->pages_per_sheet;
1047
1048                         if (export->collated == export->collated_copies) {
1049                                 export->collated = 0;
1050
1051                                 if (!export_print_inc_page (export)) {
1052                                         ev_document_doc_mutex_lock ();
1053                                         ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
1054                                         ev_document_doc_mutex_unlock ();
1055
1056                                         close (export->fd);
1057                                         export->fd = -1;
1058
1059                                         update_progress (export);
1060
1061                                         export_print_done (export);
1062                                         return FALSE;
1063                                 }
1064                         }
1065
1066                 } while ((export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 != 0) ||
1067                           (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 != 1));
1068
1069         }
1070
1071         if (export->pages_per_sheet == 1 ||
1072             (export->page_count % export->pages_per_sheet == 1 &&
1073             (export->page_set == GTK_PAGE_SET_ALL ||
1074             (export->page_set == GTK_PAGE_SET_EVEN && export->sheet % 2 == 0) ||
1075             (export->page_set == GTK_PAGE_SET_ODD && export->sheet % 2 == 1)))) {
1076                 ev_document_doc_mutex_lock ();
1077                 ev_file_exporter_begin_page (EV_FILE_EXPORTER (op->document));
1078                 ev_document_doc_mutex_unlock ();
1079         }
1080
1081         if (!export->job_export) {
1082                 export->job_export = ev_job_export_new (op->document);
1083                 g_signal_connect (export->job_export, "finished",
1084                                   G_CALLBACK (export_job_finished),
1085                                   (gpointer)export);
1086                 g_signal_connect (export->job_export, "cancelled",
1087                                   G_CALLBACK (export_job_cancelled),
1088                                   (gpointer)export);
1089         }
1090
1091         ev_job_export_set_page (EV_JOB_EXPORT (export->job_export), export->page);
1092         ev_job_scheduler_push_job (export->job_export, EV_JOB_PRIORITY_NONE);
1093
1094         update_progress (export);
1095         
1096         return FALSE;
1097 }
1098
1099 static void
1100 ev_print_operation_export_begin (EvPrintOperationExport *export)
1101 {
1102         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1103
1104         if (!export->temp_file)
1105                 return; /* cancelled */
1106         
1107         ev_document_doc_mutex_lock ();
1108         ev_file_exporter_begin (EV_FILE_EXPORTER (op->document), &export->fc);
1109         ev_document_doc_mutex_unlock ();
1110
1111         export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
1112                                            (GSourceFunc)export_print_page,
1113                                            export,
1114                                            (GDestroyNotify)export_print_page_idle_finished);    
1115 }
1116
1117 static void
1118 ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dialog,
1119                                                     gint                    response,
1120                                                     EvPrintOperationExport *export)
1121 {
1122         GtkPrintPages     print_pages;
1123         GtkPrintSettings *print_settings;
1124         GtkPageSetup     *page_setup;
1125         GtkPrinter       *printer;
1126         gdouble           scale;
1127         gdouble           width;
1128         gdouble           height;
1129         gint              first_page;
1130         gint              last_page;
1131         const gchar      *file_format;
1132         gchar            *filename;
1133         GError           *error = NULL;
1134         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1135         
1136         if (response != GTK_RESPONSE_OK &&
1137             response != GTK_RESPONSE_APPLY) {
1138                 gtk_widget_destroy (GTK_WIDGET (dialog));
1139                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
1140
1141                 return;
1142         }
1143
1144         export->print_preview = (response == GTK_RESPONSE_APPLY);
1145         
1146         printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog));
1147         ev_print_operation_export_set_printer (export, printer);
1148
1149         print_settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog));
1150         ev_print_operation_export_set_print_settings (op, print_settings);
1151
1152         page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog));
1153         ev_print_operation_export_set_default_page_setup (op, page_setup);
1154
1155         if (!gtk_printer_accepts_ps (export->printer)) {
1156                 gtk_widget_destroy (GTK_WIDGET (dialog));
1157                 
1158                 g_set_error_literal (&export->error,
1159                                      GTK_PRINT_ERROR,
1160                                      GTK_PRINT_ERROR_GENERAL,
1161                                      _("Printing is not supported on this printer."));
1162                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1163                 
1164                 return;
1165         }
1166
1167         file_format = gtk_print_settings_get (print_settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
1168         
1169         filename = g_strdup_printf ("evince_print.%s.XXXXXX", file_format != NULL ? file_format : "");
1170         export->fd = g_file_open_tmp (filename, &export->temp_file, &error);
1171         g_free (filename);
1172         if (export->fd <= -1) {
1173                 gtk_widget_destroy (GTK_WIDGET (dialog));
1174                 
1175                 g_set_error_literal (&export->error,
1176                                      GTK_PRINT_ERROR,
1177                                      GTK_PRINT_ERROR_GENERAL,
1178                                      error->message);
1179                 g_error_free (error);
1180                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1181
1182                 return;
1183         }
1184
1185         export->current_page = gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog));
1186         export->page_set = gtk_print_settings_get_page_set (print_settings);
1187         print_pages = gtk_print_settings_get_print_pages (print_settings);
1188         
1189         switch (print_pages) {
1190         case GTK_PRINT_PAGES_CURRENT:
1191                 export->ranges = &export->one_range;
1192                 
1193                 export->ranges[0].start = export->current_page;
1194                 export->ranges[0].end = export->current_page;
1195                 export->n_ranges = 1;
1196                                 
1197                 break;
1198         case GTK_PRINT_PAGES_RANGES: {
1199                 gint i;
1200                 
1201                 export->ranges = gtk_print_settings_get_page_ranges (print_settings, &export->n_ranges);
1202                 for (i = 0; i < export->n_ranges; i++)
1203                         if (export->ranges[i].end == -1 || export->ranges[i].end >= export->n_pages)
1204                                 export->ranges[i].end = export->n_pages - 1;
1205         }
1206                 break;
1207         default:
1208                 g_warning ("Unsupported print pages setting\n");
1209         case GTK_PRINT_PAGES_ALL:
1210                 export->ranges = &export->one_range;
1211
1212                 export->ranges[0].start = 0;
1213                 export->ranges[0].end = export->n_pages - 1;
1214                 export->n_ranges = 1;
1215                 
1216                 break;
1217         }
1218
1219         if (export->n_ranges < 1 || !clamp_ranges (export)) {
1220                 GtkWidget *message_dialog;
1221
1222                 message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
1223                                                  GTK_DIALOG_MODAL,
1224                                                  GTK_MESSAGE_WARNING,
1225                                                  GTK_BUTTONS_CLOSE,
1226                                                  "%s", _("Invalid page selection"));
1227                 gtk_window_set_title (GTK_WINDOW (message_dialog), _("Warning"));
1228                 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
1229                                                           "%s", _("Your print range selection does not include any pages"));
1230                 g_signal_connect (message_dialog, "response",
1231                                   G_CALLBACK (gtk_widget_destroy),
1232                                   NULL);
1233                 gtk_widget_show (message_dialog);
1234
1235                 return;
1236         } else  ev_print_operation_update_status (op, -1, -1, 0.0);
1237  
1238         width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1239         height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1240         scale = gtk_print_settings_get_scale (print_settings) * 0.01;
1241         if (scale != 1.0) {
1242                 width *= scale;
1243                 height *= scale;
1244         }
1245
1246         export->pages_per_sheet = MAX (1, gtk_print_settings_get_number_up (print_settings));
1247         
1248         export->copies = gtk_print_settings_get_n_copies (print_settings);
1249         export->collate = gtk_print_settings_get_collate (print_settings);
1250         export->reverse = gtk_print_settings_get_reverse (print_settings);
1251
1252         if (export->collate) {
1253                 export->uncollated_copies = export->copies;
1254                 export->collated_copies = 1;
1255         } else {
1256                 export->uncollated_copies = 1;
1257                 export->collated_copies = export->copies;
1258         }
1259
1260         if (export->reverse) {
1261                 export->range = export->n_ranges - 1;
1262                 export->inc = -1;
1263         } else {
1264                 export->range = 0;
1265                 export->inc = 1;
1266         }
1267         find_range (export);
1268
1269         export->page = export->start - export->inc;
1270         export->collated = export->collated_copies - 1;
1271
1272         get_first_and_last_page (export, &first_page, &last_page);
1273
1274         export->fc.format = file_format && g_ascii_strcasecmp (file_format, "pdf") == 0 ?
1275                 EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
1276         export->fc.filename = export->temp_file;
1277         export->fc.first_page = MIN (first_page, last_page);
1278         export->fc.last_page = MAX (first_page, last_page);
1279         export->fc.paper_width = width;
1280         export->fc.paper_height = height;
1281         export->fc.duplex = FALSE;
1282         export->fc.pages_per_sheet = export->pages_per_sheet;
1283
1284         if (ev_print_queue_is_empty (op->document))
1285                 ev_print_operation_export_begin (export);
1286
1287         ev_print_queue_push (op);
1288
1289         g_signal_emit (op, signals[BEGIN_PRINT], 0);
1290         
1291         gtk_widget_destroy (GTK_WIDGET (dialog));
1292 }
1293
1294 static void
1295 ev_print_operation_export_run (EvPrintOperation *op,
1296                                GtkWindow        *parent)
1297 {
1298         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1299         GtkWidget              *dialog;
1300         GtkPrintCapabilities    capabilities;
1301
1302         ev_print_queue_init ();
1303
1304         export->parent_window = parent;
1305         export->error = NULL;
1306         
1307         dialog = gtk_print_unix_dialog_new (_("Print"), parent);
1308         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1309         
1310         capabilities = GTK_PRINT_CAPABILITY_PREVIEW |
1311                 ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
1312         gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog),
1313                                                        capabilities);
1314
1315         gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1316                                                     export->embed_page_setup);
1317
1318         gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog),
1319                                                 export->current_page);
1320         
1321         gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog),
1322                                             export->print_settings);
1323         
1324         if (export->page_setup)
1325                 gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1326                                                       export->page_setup);
1327
1328         g_signal_connect (dialog, "response",
1329                           G_CALLBACK (ev_print_operation_export_print_dialog_response_cb),
1330                           export);
1331
1332         gtk_window_present (GTK_WINDOW (dialog));
1333 }
1334
1335 static void
1336 ev_print_operation_export_cancel (EvPrintOperation *op)
1337 {
1338         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1339
1340         if (export->job_export &&
1341             !ev_job_is_finished (export->job_export)) {
1342                 ev_job_cancel (export->job_export);
1343         } else {
1344                 export_cancel (export);
1345         }
1346 }
1347
1348 static void
1349 ev_print_operation_export_get_error (EvPrintOperation *op,
1350                                      GError          **error)
1351 {
1352         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1353
1354         g_propagate_error (error, export->error);
1355         export->error = NULL;
1356 }
1357
1358 static void
1359 ev_print_operation_export_set_embed_page_setup (EvPrintOperation *op,
1360                                                 gboolean          embed)
1361 {
1362         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1363
1364         export->embed_page_setup = embed;
1365 }
1366
1367 static gboolean
1368 ev_print_operation_export_get_embed_page_setup (EvPrintOperation *op)
1369 {
1370         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1371
1372         return export->embed_page_setup;
1373 }
1374
1375 static void
1376 ev_print_operation_export_finalize (GObject *object)
1377 {
1378         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (object);
1379
1380         if (export->idle_id > 0) {
1381                 g_source_remove (export->idle_id);
1382                 export->idle_id = 0;
1383         }
1384
1385         if (export->fd != -1) {
1386                 close (export->fd);
1387                 export->fd = -1;
1388         }
1389         
1390         if (export->ranges) {
1391                 if (export->ranges != &export->one_range)
1392                         g_free (export->ranges);
1393                 export->ranges = NULL;
1394                 export->n_ranges = 0;
1395         }
1396
1397         if (export->temp_file) {
1398                 g_free (export->temp_file);
1399                 export->temp_file = NULL;
1400         }
1401
1402         if (export->job_name) {
1403                 g_free (export->job_name);
1404                 export->job_name = NULL;
1405         }
1406
1407         if (export->job_export) {
1408                 if (!ev_job_is_finished (export->job_export))
1409                         ev_job_cancel (export->job_export);
1410                 g_signal_handlers_disconnect_by_func (export->job_export,
1411                                                       export_job_finished,
1412                                                       export);
1413                 g_signal_handlers_disconnect_by_func (export->job_export,
1414                                                       export_job_cancelled,
1415                                                       export);
1416                 g_object_unref (export->job_export);
1417                 export->job_export = NULL;
1418         }
1419
1420         if (export->error) {
1421                 g_error_free (export->error);
1422                 export->error = NULL;
1423         }
1424
1425         if (export->print_settings) {
1426                 g_object_unref (export->print_settings);
1427                 export->print_settings = NULL;
1428         }
1429
1430         if (export->page_setup) {
1431                 g_object_unref (export->page_setup);
1432                 export->page_setup = NULL;
1433         }
1434
1435         if (export->printer) {
1436                 g_object_unref (export->printer);
1437                 export->printer = NULL;
1438         }
1439
1440         (* G_OBJECT_CLASS (ev_print_operation_export_parent_class)->finalize) (object);
1441 }
1442
1443 static void
1444 ev_print_operation_export_init (EvPrintOperationExport *export)
1445 {
1446         /* sheets are counted from 1 to be physical */
1447         export->sheet = 1;
1448 }
1449
1450 static GObject *
1451 ev_print_operation_export_constructor (GType                  type,
1452                                        guint                  n_construct_properties,
1453                                        GObjectConstructParam *construct_params)
1454 {
1455         GObject                *object;
1456         EvPrintOperationExport *export;
1457         EvPrintOperation       *op;
1458         
1459         object = G_OBJECT_CLASS (ev_print_operation_export_parent_class)->constructor (type,
1460                                                                                        n_construct_properties,
1461                                                                                        construct_params);
1462         export = EV_PRINT_OPERATION_EXPORT (object);
1463         op = EV_PRINT_OPERATION (object);
1464         export->n_pages = ev_document_get_n_pages (op->document);
1465
1466         return object;
1467 }
1468
1469 static void
1470 ev_print_operation_export_class_init (EvPrintOperationExportClass *klass)
1471 {
1472         GObjectClass          *g_object_class = G_OBJECT_CLASS (klass);
1473         EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
1474
1475         ev_print_op_class->set_current_page = ev_print_operation_export_set_current_page;
1476         ev_print_op_class->set_print_settings = ev_print_operation_export_set_print_settings;
1477         ev_print_op_class->get_print_settings = ev_print_operation_export_get_print_settings;
1478         ev_print_op_class->set_default_page_setup = ev_print_operation_export_set_default_page_setup;
1479         ev_print_op_class->get_default_page_setup = ev_print_operation_export_get_default_page_setup;
1480         ev_print_op_class->set_job_name = ev_print_operation_export_set_job_name;
1481         ev_print_op_class->get_job_name = ev_print_operation_export_get_job_name;
1482         ev_print_op_class->run = ev_print_operation_export_run;
1483         ev_print_op_class->cancel = ev_print_operation_export_cancel;
1484         ev_print_op_class->get_error = ev_print_operation_export_get_error;
1485         ev_print_op_class->set_embed_page_setup = ev_print_operation_export_set_embed_page_setup;
1486         ev_print_op_class->get_embed_page_setup = ev_print_operation_export_get_embed_page_setup;
1487
1488         g_object_class->constructor = ev_print_operation_export_constructor;
1489         g_object_class->finalize = ev_print_operation_export_finalize;
1490 }
1491
1492 #endif /* GTKUNIXPRINT_ENABLED */
1493
1494 /* Print to cairo interface */
1495 #define EV_TYPE_PRINT_OPERATION_PRINT         (ev_print_operation_print_get_type())
1496 #define EV_PRINT_OPERATION_PRINT(object)      (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_PRINT, EvPrintOperationPrint))
1497 #define EV_PRINT_OPERATION_PRINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PRINT_OPERATION_PRINT, EvPrintOperationPrintClass))
1498 #define EV_IS_PRINT_OPERATION_PRINT(object)   (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PRINT_OPERATION_PRINT))
1499
1500 typedef struct _EvPrintOperationPrint      EvPrintOperationPrint;
1501 typedef struct _EvPrintOperationPrintClass EvPrintOperationPrintClass;
1502
1503 static GType ev_print_operation_print_get_type (void) G_GNUC_CONST;
1504
1505 typedef enum {
1506         EV_SCALE_NONE,
1507         EV_SCALE_SHRINK_TO_PRINTABLE_AREA,
1508         EV_SCALE_FIT_TO_PRINTABLE_AREA
1509 } EvPrintScale;
1510
1511 #define EV_PRINT_SETTING_PAGE_SCALE "evince-print-setting-page-scale"
1512 #define EV_PRINT_SETTING_AUTOROTATE "evince-print-setting-page-autorotate"
1513 #define EV_PRINT_SETTING_PAGE_SIZE  "evince-print-setting-page-size"
1514
1515 struct _EvPrintOperationPrint {
1516         EvPrintOperation parent;
1517
1518         GtkPrintOperation *op;
1519         gint               n_pages_to_print;
1520         gint               total;
1521         EvJob             *job_print;
1522         gchar             *job_name;
1523
1524         /* Page handling tab */
1525         GtkWidget   *scale_combo;
1526         EvPrintScale page_scale;
1527         GtkWidget   *autorotate_button;
1528         gboolean     autorotate;
1529         GtkWidget   *source_button;
1530         gboolean     use_source_size;
1531 };
1532
1533 struct _EvPrintOperationPrintClass {
1534         EvPrintOperationClass parent_class;
1535 };
1536
1537 G_DEFINE_TYPE (EvPrintOperationPrint, ev_print_operation_print, EV_TYPE_PRINT_OPERATION)
1538
1539 static void
1540 ev_print_operation_print_set_current_page (EvPrintOperation *op,
1541                                            gint              current_page)
1542 {
1543         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1544
1545         gtk_print_operation_set_current_page (print->op, current_page);
1546 }
1547
1548 static void
1549 ev_print_operation_print_set_print_settings (EvPrintOperation *op,
1550                                              GtkPrintSettings *print_settings)
1551 {
1552         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1553
1554         gtk_print_operation_set_print_settings (print->op, print_settings);
1555 }
1556
1557 static GtkPrintSettings *
1558 ev_print_operation_print_get_print_settings (EvPrintOperation *op)
1559 {
1560         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1561
1562         return gtk_print_operation_get_print_settings (print->op);
1563 }
1564
1565 static void
1566 ev_print_operation_print_set_default_page_setup (EvPrintOperation *op,
1567                                                  GtkPageSetup     *page_setup)
1568 {
1569         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1570
1571         gtk_print_operation_set_default_page_setup (print->op, page_setup);
1572 }
1573
1574 static GtkPageSetup *
1575 ev_print_operation_print_get_default_page_setup (EvPrintOperation *op)
1576 {
1577         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1578
1579         return gtk_print_operation_get_default_page_setup (print->op);
1580 }
1581
1582 static void
1583 ev_print_operation_print_set_job_name (EvPrintOperation *op,
1584                                        const gchar      *job_name)
1585 {
1586         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1587
1588         g_free (print->job_name);
1589         print->job_name = g_strdup (job_name);
1590
1591         gtk_print_operation_set_job_name (print->op, print->job_name);
1592 }
1593
1594 static const gchar *
1595 ev_print_operation_print_get_job_name (EvPrintOperation *op)
1596 {
1597         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1598
1599         if (!print->job_name) {
1600                 gchar *name;
1601
1602                 g_object_get (print->op, "job_name", &name, NULL);
1603                 print->job_name = name;
1604         }
1605
1606         return print->job_name;
1607 }
1608
1609 static void
1610 ev_print_operation_print_run (EvPrintOperation *op,
1611                               GtkWindow        *parent)
1612 {
1613         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1614
1615         gtk_print_operation_run (print->op,
1616                                  GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
1617                                  parent, NULL);
1618 }
1619
1620 static void
1621 ev_print_operation_print_cancel (EvPrintOperation *op)
1622 {
1623         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1624
1625         if (print->job_print)
1626                 ev_job_cancel (print->job_print);
1627         else
1628                 gtk_print_operation_cancel (print->op);
1629 }
1630
1631 static void
1632 ev_print_operation_print_get_error (EvPrintOperation *op,
1633                                     GError          **error)
1634 {
1635         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1636
1637         gtk_print_operation_get_error (print->op, error);
1638 }
1639
1640 static void
1641 ev_print_operation_print_set_embed_page_setup (EvPrintOperation *op,
1642                                                gboolean          embed)
1643 {
1644         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1645
1646         gtk_print_operation_set_embed_page_setup (print->op, embed);
1647 }
1648
1649 static gboolean
1650 ev_print_operation_print_get_embed_page_setup (EvPrintOperation *op)
1651 {
1652         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (op);
1653
1654         return gtk_print_operation_get_embed_page_setup (print->op);
1655 }
1656
1657 static void
1658 ev_print_operation_print_begin_print (EvPrintOperationPrint *print,
1659                                       GtkPrintContext       *context)
1660 {
1661         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1662         gint              n_pages;
1663
1664         n_pages = ev_document_get_n_pages (op->document);
1665         gtk_print_operation_set_n_pages (print->op, n_pages);
1666         ev_print_operation_update_status (op, -1, n_pages, 0);
1667
1668         g_signal_emit (op, signals[BEGIN_PRINT], 0);
1669 }
1670
1671 static void
1672 ev_print_operation_print_done (EvPrintOperationPrint  *print,
1673                                GtkPrintOperationResult result)
1674 {
1675         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1676
1677         ev_print_operation_update_status (op, 0, print->n_pages_to_print, 1.0);
1678
1679         g_signal_emit (op, signals[DONE], 0, result);
1680 }
1681
1682 static void
1683 ev_print_operation_print_status_changed (EvPrintOperationPrint *print)
1684 {
1685         GtkPrintStatus status;
1686
1687         status = gtk_print_operation_get_status (print->op);
1688         if (status == GTK_PRINT_STATUS_GENERATING_DATA)
1689                 print->n_pages_to_print = gtk_print_operation_get_n_pages_to_print (print->op);
1690 }
1691
1692 static void
1693 print_job_finished (EvJobPrint            *job,
1694                     EvPrintOperationPrint *print)
1695 {
1696         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1697
1698         gtk_print_operation_draw_page_finish (print->op);
1699
1700         print->total++;
1701         ev_print_operation_update_status (op, print->total,
1702                                           print->n_pages_to_print,
1703                                           print->total / (gdouble)print->n_pages_to_print);
1704         ev_job_print_set_cairo (job, NULL);
1705 }
1706
1707 static gboolean
1708 draw_page_finish_idle (EvPrintOperationPrint *print)
1709 {
1710         if (ev_job_scheduler_get_running_thread_job () == print->job_print)
1711                 return TRUE;
1712
1713         gtk_print_operation_draw_page_finish (print->op);
1714
1715         return FALSE;
1716 }
1717
1718 static void
1719 print_job_cancelled (EvJobPrint            *job,
1720                      EvPrintOperationPrint *print)
1721 {
1722         /* Finish the current page, so that draw-page
1723          * is emitted again and it will cancel the
1724          * print operation. If the job is still
1725          * running, wait until it finishes.
1726          */
1727         if (ev_job_scheduler_get_running_thread_job () == print->job_print)
1728                 g_idle_add ((GSourceFunc)draw_page_finish_idle, print);
1729         else
1730                 gtk_print_operation_draw_page_finish (print->op);
1731 }
1732
1733 static void
1734 ev_print_operation_print_request_page_setup (EvPrintOperationPrint *print,
1735                                              GtkPrintContext       *context,
1736                                              gint                   page_nr,
1737                                              GtkPageSetup          *setup)
1738 {
1739         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1740         gdouble           width, height;
1741         GtkPaperSize     *paper_size;
1742
1743         ev_document_get_page_size (op->document, page_nr,
1744                                    &width, &height);
1745
1746         if (print->use_source_size) {
1747                 paper_size = gtk_paper_size_new_custom ("custom", "custom",
1748                                                         width, height, GTK_UNIT_POINTS);
1749                 gtk_page_setup_set_paper_size_and_default_margins (setup, paper_size);
1750                 gtk_paper_size_free (paper_size);
1751         }
1752
1753         if (print->autorotate) {
1754                 if (width > height)
1755                         gtk_page_setup_set_orientation (setup, GTK_PAGE_ORIENTATION_LANDSCAPE);
1756                 else
1757                         gtk_page_setup_set_orientation (setup, GTK_PAGE_ORIENTATION_PORTRAIT);
1758         }
1759 }
1760
1761 static void
1762 _print_context_get_hard_margins (GtkPrintContext *context,
1763                                  gdouble         *top,
1764                                  gdouble         *bottom,
1765                                  gdouble         *left,
1766                                  gdouble         *right)
1767 {
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 }
1775
1776 static void
1777 ev_print_operation_print_draw_page (EvPrintOperationPrint *print,
1778                                     GtkPrintContext       *context,
1779                                     gint                   page)
1780 {
1781         EvPrintOperation *op = EV_PRINT_OPERATION (print);
1782         cairo_t          *cr;
1783         gdouble           cr_width, cr_height;
1784         gdouble           width, height, scale;
1785         gdouble           x_scale, y_scale;
1786         gdouble           top, bottom, left, right;
1787
1788         gtk_print_operation_set_defer_drawing (print->op);
1789
1790         if (!print->job_print) {
1791                 print->job_print = ev_job_print_new (op->document);
1792                 g_signal_connect (G_OBJECT (print->job_print), "finished",
1793                                   G_CALLBACK (print_job_finished),
1794                                   (gpointer)print);
1795                 g_signal_connect (G_OBJECT (print->job_print), "cancelled",
1796                                   G_CALLBACK (print_job_cancelled),
1797                                   (gpointer)print);
1798         } else if (g_cancellable_is_cancelled (print->job_print->cancellable)) {
1799                 gtk_print_operation_cancel (print->op);
1800                 ev_job_print_set_cairo (EV_JOB_PRINT (print->job_print), NULL);
1801                 return;
1802         }
1803
1804         ev_job_print_set_page (EV_JOB_PRINT (print->job_print), page);
1805
1806         cr = gtk_print_context_get_cairo_context (context);
1807         cr_width = gtk_print_context_get_width (context);
1808         cr_height = gtk_print_context_get_height (context);
1809         ev_document_get_page_size (op->document, page, &width, &height);
1810
1811         if (print->page_scale == EV_SCALE_NONE) {
1812                 /* Center document page on the printed page */
1813                 if (print->autorotate)
1814                         cairo_translate (cr, (cr_width - width) / 2, (cr_height - height) / 2);
1815         } else {
1816                 _print_context_get_hard_margins (context, &top, &bottom, &left, &right);
1817
1818                 x_scale = (cr_width - left - right) / width;
1819                 y_scale = (cr_height - top - bottom) / height;
1820
1821                 if (x_scale < y_scale)
1822                         scale = x_scale;
1823                 else
1824                         scale = y_scale;
1825
1826                 if (print->autorotate) {
1827                         double left_right_sides, top_bottom_sides;
1828
1829                         cairo_translate (cr, (cr_width - scale * width) / 2,
1830                                          (cr_height - scale * height) / 2);
1831
1832                         /* Ensure document page is within the margins. The
1833                          * scale guarantees the document will fit in the
1834                          * margins so we just need to check each side and
1835                          * if it overhangs the margin, translate it to the
1836                          * margin. */
1837                         left_right_sides = (cr_width - width*scale)/2;
1838                         top_bottom_sides = (cr_height - height*scale)/2;
1839                         if (left_right_sides < left)
1840                                 cairo_translate (cr, left - left_right_sides, 0);
1841
1842                         if (left_right_sides < right)
1843                                 cairo_translate (cr, -(right - left_right_sides), 0);
1844
1845                         if (top_bottom_sides < top)
1846                                 cairo_translate (cr, 0, top - top_bottom_sides);
1847
1848                         if (top_bottom_sides < bottom)
1849                                 cairo_translate (cr, 0, -(bottom - top_bottom_sides));
1850                 } else {
1851                         cairo_translate (cr, left, top);
1852                 }
1853
1854                 if (print->page_scale == EV_SCALE_FIT_TO_PRINTABLE_AREA || scale < 1.0) {
1855                         cairo_scale (cr, scale, scale);
1856                 }
1857         }
1858
1859         ev_job_print_set_cairo (EV_JOB_PRINT (print->job_print), cr);
1860         ev_job_scheduler_push_job (print->job_print, EV_JOB_PRIORITY_NONE);
1861 }
1862
1863 static GObject *
1864 ev_print_operation_print_create_custom_widget (EvPrintOperationPrint *print,
1865                                                GtkPrintContext       *context)
1866 {
1867         GtkPrintSettings *settings;
1868         GtkWidget        *label;
1869         GtkWidget        *table;
1870         EvPrintScale      page_scale;
1871         gboolean          autorotate;
1872         gboolean          use_source_size;
1873
1874         settings = gtk_print_operation_get_print_settings (print->op);
1875         page_scale = gtk_print_settings_get_int_with_default (settings, EV_PRINT_SETTING_PAGE_SCALE, 1);
1876         autorotate = gtk_print_settings_has_key (settings, EV_PRINT_SETTING_AUTOROTATE) ?
1877                 gtk_print_settings_get_bool (settings, EV_PRINT_SETTING_AUTOROTATE) :
1878                 TRUE;
1879         use_source_size = gtk_print_settings_get_bool (settings, EV_PRINT_SETTING_PAGE_SIZE);
1880
1881         table = gtk_table_new (3, 2, FALSE);
1882         gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1883         gtk_table_set_col_spacings (GTK_TABLE (table), 12);
1884         gtk_container_set_border_width (GTK_CONTAINER (table), 12);
1885
1886         label =  gtk_label_new (_("Page Scaling:"));
1887         gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1888         gtk_widget_show (label);
1889
1890         print->scale_combo = gtk_combo_box_text_new ();
1891         gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (print->scale_combo), _("None"));
1892         gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (print->scale_combo), _("Shrink to Printable Area"));
1893         gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (print->scale_combo), _("Fit to Printable Area"));
1894         gtk_combo_box_set_active (GTK_COMBO_BOX (print->scale_combo), page_scale);
1895         gtk_widget_set_tooltip_text (print->scale_combo,
1896                 _("Scale document pages to fit the selected printer page. Select from one of the following:\n"
1897                   "\n"
1898                   "• \"None\": No page scaling is performed.\n"
1899                   "\n"
1900                   "• \"Shrink to Printable Area\": Document pages larger than the printable area"
1901                   " are reduced to fit the printable area of the printer page.\n"
1902                   "\n"
1903                   "• \"Fit to Printable Area\": Document pages are enlarged or reduced as"
1904                   " required to fit the printable area of the printer page.\n"));
1905         gtk_table_attach (GTK_TABLE (table), print->scale_combo, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
1906         gtk_widget_show (print->scale_combo);
1907
1908         print->autorotate_button = gtk_check_button_new_with_label (_("Auto Rotate and Center"));
1909         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (print->autorotate_button), autorotate);
1910         gtk_widget_set_tooltip_text (print->autorotate_button,
1911                 _("Rotate printer page orientation of each page to match orientation of each document page. "
1912                   "Document pages will be centered within the printer page."));
1913         gtk_table_attach (GTK_TABLE (table), print->autorotate_button, 0, 2, 1, 2, GTK_FILL, 0, 0, 0);
1914         gtk_widget_show (print->autorotate_button);
1915
1916         print->source_button = gtk_check_button_new_with_label (_("Select page size using document page size"));
1917         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (print->source_button), use_source_size);
1918         gtk_widget_set_tooltip_text (print->source_button, _("When enabled, each page will be printed on "
1919                                                              "the same size paper as the document page."));
1920         gtk_table_attach (GTK_TABLE (table), print->source_button, 0, 2, 2, 3, GTK_FILL, 0, 0, 0);
1921         gtk_widget_show (print->source_button);
1922
1923         return G_OBJECT (table);
1924 }
1925
1926 static void
1927 ev_print_operation_print_custom_widget_apply (EvPrintOperationPrint *print,
1928                                               GtkPrintContext       *context)
1929 {
1930         GtkPrintSettings *settings;
1931
1932         print->page_scale = gtk_combo_box_get_active (GTK_COMBO_BOX (print->scale_combo));
1933         print->autorotate = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (print->autorotate_button));
1934         print->use_source_size = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (print->source_button));
1935         settings = gtk_print_operation_get_print_settings (print->op);
1936         gtk_print_settings_set_int (settings, EV_PRINT_SETTING_PAGE_SCALE, print->page_scale);
1937         gtk_print_settings_set_bool (settings, EV_PRINT_SETTING_AUTOROTATE, print->autorotate);
1938         gtk_print_settings_set_bool (settings, EV_PRINT_SETTING_PAGE_SIZE, print->use_source_size);
1939 }
1940
1941 static void
1942 ev_print_operation_print_finalize (GObject *object)
1943 {
1944         EvPrintOperationPrint *print = EV_PRINT_OPERATION_PRINT (object);
1945
1946         if (print->op) {
1947                 g_object_unref (print->op);
1948                 print->op = NULL;
1949         }
1950
1951         if (print->job_name) {
1952                 g_free (print->job_name);
1953                 print->job_name = NULL;
1954         }
1955
1956         if (print->job_print) {
1957                 if (!ev_job_is_finished (print->job_print))
1958                         ev_job_cancel (print->job_print);
1959                 g_signal_handlers_disconnect_by_func (print->job_print,
1960                                                       print_job_finished,
1961                                                       print);
1962                 g_signal_handlers_disconnect_by_func (print->job_print,
1963                                                       print_job_cancelled,
1964                                                       print);
1965                 g_object_unref (print->job_print);
1966                 print->job_print = NULL;
1967         }
1968
1969         (* G_OBJECT_CLASS (ev_print_operation_print_parent_class)->finalize) (object);
1970 }
1971
1972 static void
1973 ev_print_operation_print_init (EvPrintOperationPrint *print)
1974 {
1975         print->op = gtk_print_operation_new ();
1976         g_signal_connect_swapped (print->op, "begin_print",
1977                                   G_CALLBACK (ev_print_operation_print_begin_print),
1978                                   print);
1979         g_signal_connect_swapped (print->op, "done",
1980                                   G_CALLBACK (ev_print_operation_print_done),
1981                                   print);
1982         g_signal_connect_swapped (print->op, "draw_page",
1983                                   G_CALLBACK (ev_print_operation_print_draw_page),
1984                                   print);
1985         g_signal_connect_swapped (print->op, "status_changed",
1986                                   G_CALLBACK (ev_print_operation_print_status_changed),
1987                                   print);
1988         g_signal_connect_swapped (print->op, "request_page_setup",
1989                                   G_CALLBACK (ev_print_operation_print_request_page_setup),
1990                                   print);
1991         g_signal_connect_swapped (print->op, "create_custom_widget",
1992                                   G_CALLBACK (ev_print_operation_print_create_custom_widget),
1993                                   print);
1994         g_signal_connect_swapped (print->op, "custom_widget_apply",
1995                                   G_CALLBACK (ev_print_operation_print_custom_widget_apply),
1996                                   print);
1997         gtk_print_operation_set_allow_async (print->op, TRUE);
1998         gtk_print_operation_set_use_full_page (print->op, TRUE);
1999         gtk_print_operation_set_unit (print->op, GTK_UNIT_POINTS);
2000         gtk_print_operation_set_custom_tab_label (print->op, _("Page Handling"));
2001 }
2002
2003 static void
2004 ev_print_operation_print_class_init (EvPrintOperationPrintClass *klass)
2005 {
2006         GObjectClass          *g_object_class = G_OBJECT_CLASS (klass);
2007         EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
2008
2009         ev_print_op_class->set_current_page = ev_print_operation_print_set_current_page;
2010         ev_print_op_class->set_print_settings = ev_print_operation_print_set_print_settings;
2011         ev_print_op_class->get_print_settings = ev_print_operation_print_get_print_settings;
2012         ev_print_op_class->set_default_page_setup = ev_print_operation_print_set_default_page_setup;
2013         ev_print_op_class->get_default_page_setup = ev_print_operation_print_get_default_page_setup;
2014         ev_print_op_class->set_job_name = ev_print_operation_print_set_job_name;
2015         ev_print_op_class->get_job_name = ev_print_operation_print_get_job_name;
2016         ev_print_op_class->run = ev_print_operation_print_run;
2017         ev_print_op_class->cancel = ev_print_operation_print_cancel;
2018         ev_print_op_class->get_error = ev_print_operation_print_get_error;
2019         ev_print_op_class->set_embed_page_setup = ev_print_operation_print_set_embed_page_setup;
2020         ev_print_op_class->get_embed_page_setup = ev_print_operation_print_get_embed_page_setup;
2021
2022         g_object_class->finalize = ev_print_operation_print_finalize;
2023 }
2024
2025 gboolean
2026 ev_print_operation_exists_for_document (EvDocument *document)
2027 {
2028 #if GTKUNIXPRINT_ENABLED
2029         return (EV_IS_FILE_EXPORTER(document) || EV_IS_DOCUMENT_PRINT(document));
2030 #else
2031         return EV_IS_DOCUMENT_PRINT(document);
2032 #endif /* GTKUNIXPRINT_ENABLED */
2033 }
2034
2035 /* Factory method */
2036 EvPrintOperation *
2037 ev_print_operation_new (EvDocument *document)
2038 {
2039         EvPrintOperation *op = NULL;
2040
2041         g_return_val_if_fail (ev_print_operation_exists_for_document (document), NULL);
2042
2043         if (EV_IS_DOCUMENT_PRINT (document))
2044                 op = EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_PRINT,
2045                                                        "document", document, NULL));
2046         else
2047 #if GTKUNIXPRINT_ENABLED
2048                 op = EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_EXPORT,
2049                                                        "document", document, NULL));
2050 #else
2051                 op = NULL;
2052 #endif
2053         return op;
2054 }