]> www.fi.muni.cz Git - evince.git/blob - shell/ev-print-operation.c
Removed
[evince.git] / shell / ev-print-operation.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
4  *
5  * Evince is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Evince is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include <config.h>
21
22 #include "ev-print-operation.h"
23
24 #include <gtk/gtkunixprint.h>
25 #include <glib/gi18n.h>
26 #include <glib/gstdio.h>
27 #include <unistd.h>
28
29 #include "ev-page-cache.h"
30 #include "ev-file-exporter.h"
31 #include "ev-jobs.h"
32 #include "ev-job-scheduler.h"
33 #include "ev-application.h"
34 #include "ev-file-helpers.h"
35
36 enum {
37         PROP_0,
38         PROP_DOCUMENT
39 };
40
41 enum {
42         DONE,
43         BEGIN_PRINT,
44         STATUS_CHANGED,
45         LAST_SIGNAL
46 };
47
48 static guint signals[LAST_SIGNAL] = { 0 };
49
50 struct _EvPrintOperation {
51         GObject parent;
52
53         EvDocument *document;
54
55         /* Progress */
56         gchar      *status;
57         gdouble     progress;
58 };
59
60 struct _EvPrintOperationClass {
61         GObjectClass parent_class;
62
63         void              (* set_current_page)       (EvPrintOperation       *op,
64                                                       gint                    current_page);
65         void              (* set_print_settings)     (EvPrintOperation       *op,
66                                                       GtkPrintSettings       *print_settings);
67         GtkPrintSettings *(* get_print_settings)     (EvPrintOperation       *op);
68         void              (* set_default_page_setup) (EvPrintOperation       *op,
69                                                       GtkPageSetup           *page_setup);
70         GtkPageSetup     *(* get_default_page_setup) (EvPrintOperation       *op);
71         void              (* set_job_name)           (EvPrintOperation       *op,
72                                                       const gchar            *job_name);
73         const gchar      *(* get_job_name)           (EvPrintOperation       *op);
74         void              (* run)                    (EvPrintOperation       *op,
75                                                       GtkWindow              *parent);
76         void              (* cancel)                 (EvPrintOperation       *op);
77         void              (* get_error)              (EvPrintOperation       *op,
78                                                       GError                **error);
79
80         /* signals */
81         void              (* done)                   (EvPrintOperation       *op,
82                                                       GtkPrintOperationResult result);
83         void              (* begin_print)            (EvPrintOperation       *op);
84         void              (* status_changed)         (EvPrintOperation       *op);
85                                                       
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 const gchar *
285 ev_print_operation_get_status (EvPrintOperation *op)
286 {
287         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), NULL);
288
289         return op->status ? op->status : "";
290 }
291
292 gdouble
293 ev_print_operation_get_progress (EvPrintOperation *op)
294 {
295         g_return_val_if_fail (EV_IS_PRINT_OPERATION (op), 0.0);
296
297         return op->progress;
298 }
299
300 static void
301 ev_print_operation_update_status (EvPrintOperation *op,
302                                   gint              page,
303                                   gint              n_pages,
304                                   gdouble           progress)
305 {
306         if (op->status && op->progress == progress)
307                 return;
308
309         g_free (op->status);
310
311         if (page == -1) {
312                 /* Initial state */
313                 op->status = g_strdup (_("Preparing to print ..."));
314         } else if (page > n_pages) {
315                 op->status = g_strdup (_("Finishing..."));
316         } else {
317                 op->status = g_strdup_printf (_("Printing page %d of %d..."),
318                                               page, n_pages);
319         }
320
321         op->progress = MIN (1.0, progress);
322
323         g_signal_emit (op, signals[STATUS_CHANGED], 0);
324 }
325
326 /* Export interface */
327 #define EV_TYPE_PRINT_OPERATION_EXPORT         (ev_print_operation_export_get_type())
328 #define EV_PRINT_OPERATION_EXPORT(object)      (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PRINT_OPERATION_EXPORT, EvPrintOperationExport))
329 #define EV_PRINT_OPERATION_EXPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PRINT_OPERATION_EXPORT, EvPrintOperationExportClass))
330 #define EV_IS_PRINT_OPERATION_EXPORT(object)   (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PRINT_OPERATION_EXPORT))
331
332 typedef struct _EvPrintOperationExport      EvPrintOperationExport;
333 typedef struct _EvPrintOperationExportClass EvPrintOperationExportClass;
334
335 GType           ev_print_operation_export_get_type (void) G_GNUC_CONST;
336
337 static void     ev_print_operation_export_begin    (EvPrintOperationExport *export);
338 static gboolean export_print_page                  (EvPrintOperationExport *export);
339 static void     export_cancel                      (EvPrintOperationExport *export);
340
341 struct _EvPrintOperationExport {
342         EvPrintOperation parent;
343
344         GtkWindow *parent_window;
345         EvJob *job_export;
346         GError *error;
347
348         gboolean print_preview;
349         gint n_pages;
350         gint current_page;
351         GtkPrinter *printer;
352         GtkPageSetup *page_setup;
353         GtkPrintSettings *print_settings;
354         GtkPageSet page_set;
355         gint copies;
356         guint collate     : 1;
357         guint reverse     : 1;
358         gint pages_per_sheet;
359         gint fd;
360         gchar *temp_file;
361         gchar *job_name;
362         
363         guint idle_id;
364         
365         /* Context */
366         EvFileExporterContext fc;
367         gint n_pages_to_print;
368         gint uncollated_copies;
369         gint collated_copies;
370         gint uncollated, collated, total;
371
372         gint range, n_ranges;
373         GtkPageRange *ranges;
374         GtkPageRange one_range;
375
376         gint page, start, end, inc;
377 };
378
379 struct _EvPrintOperationExportClass {
380         EvPrintOperationClass parent_class;
381 };
382
383 G_DEFINE_TYPE (EvPrintOperationExport, ev_print_operation_export, EV_TYPE_PRINT_OPERATION)
384
385 /* Internal print queue */
386 static GHashTable *print_queue = NULL;
387
388 static void
389 queue_free (GQueue *queue)
390 {
391         g_queue_foreach (queue, (GFunc)g_object_unref, NULL);
392         g_queue_free (queue);
393 }
394
395 static void
396 ev_print_queue_init (void)
397 {
398         if (G_UNLIKELY (print_queue == NULL)) {
399                 print_queue = g_hash_table_new_full (g_direct_hash,
400                                                      g_direct_equal,
401                                                      NULL,
402                                                      (GDestroyNotify)queue_free);
403         }
404 }
405
406 static void
407 remove_document_queue (gpointer data,
408                        GObject *document)
409 {
410         if (print_queue)
411                 g_hash_table_remove (print_queue, document);
412 }
413
414 static gboolean
415 ev_print_queue_is_empty (EvDocument *document)
416 {
417         GQueue *queue;
418
419         queue = g_hash_table_lookup (print_queue, document);
420         return (!queue || g_queue_is_empty (queue));
421 }
422
423 static void
424 ev_print_queue_push (EvPrintOperation *op)
425 {
426         GQueue *queue;
427
428         queue = g_hash_table_lookup (print_queue, op->document);
429         if (!queue) {
430                 queue = g_queue_new ();
431                 g_hash_table_insert (print_queue,
432                                      op->document,
433                                      queue);
434                 g_object_weak_ref (G_OBJECT (op->document),
435                                    (GWeakNotify)remove_document_queue,
436                                    NULL);
437         }
438
439         g_queue_push_head (queue, g_object_ref (op));
440 }
441
442 static EvPrintOperation *
443 ev_print_queue_pop (EvDocument *document)
444 {
445         EvPrintOperation *op;
446         GQueue           *queue;
447
448         queue = g_hash_table_lookup (print_queue, document);
449         if (!queue || g_queue_is_empty (queue))
450                 return NULL;
451         
452         op = g_queue_pop_tail (queue);
453         g_object_unref (op);
454
455         return op;
456 }
457
458 static EvPrintOperation *
459 ev_print_queue_peek (EvDocument *document)
460 {
461         GQueue *queue;
462
463         queue = g_hash_table_lookup (print_queue, document);
464         if (!queue || g_queue_is_empty (queue))
465                 return NULL;
466
467         return g_queue_peek_tail (queue);
468 }
469
470 static void
471 ev_print_operation_export_set_current_page (EvPrintOperation *op,
472                                             gint              current_page)
473 {
474         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
475
476         g_return_if_fail (current_page < export->n_pages);
477         
478         export->current_page = current_page;
479 }
480
481 static void
482 ev_print_operation_export_set_print_settings (EvPrintOperation *op,
483                                               GtkPrintSettings *print_settings)
484 {
485         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
486
487         if (print_settings == export->print_settings)
488                 return;
489
490         g_object_ref (print_settings);
491         if (export->print_settings)
492                 g_object_unref (export->print_settings);
493         export->print_settings = print_settings;
494 }
495
496 static GtkPrintSettings *
497 ev_print_operation_export_get_print_settings (EvPrintOperation *op)
498 {
499         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
500
501         return export->print_settings;
502 }
503
504 static void
505 ev_print_operation_export_set_default_page_setup (EvPrintOperation *op,
506                                                   GtkPageSetup     *page_setup)
507 {
508         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
509
510         if (page_setup == export->page_setup)
511                 return;
512
513         g_object_ref (page_setup);
514         if (export->page_setup)
515                 g_object_unref (export->page_setup);
516         export->page_setup = page_setup;
517 }
518
519 static GtkPageSetup *
520 ev_print_operation_export_get_default_page_setup (EvPrintOperation *op)
521 {
522         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
523
524         return export->page_setup;
525 }
526
527 static void
528 ev_print_operation_export_set_job_name (EvPrintOperation *op,
529                                         const gchar      *job_name)
530 {
531         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
532
533         g_free (export->job_name);
534         export->job_name = g_strdup (job_name);
535 }
536
537 static const gchar *
538 ev_print_operation_export_get_job_name (EvPrintOperation *op)
539 {
540         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
541
542         return export->job_name;
543 }
544
545 static void
546 ev_print_operation_export_set_printer (EvPrintOperationExport *export,
547                                        GtkPrinter             *printer)
548 {
549         if (printer == export->printer)
550                 return;
551
552         g_object_ref (printer);
553         if (export->printer)
554                 g_object_unref (export->printer);
555         export->printer = printer;
556 }
557
558 static void
559 find_range (EvPrintOperationExport *export)
560 {
561         GtkPageRange *range;
562
563         range = &export->ranges[export->range];
564
565         if (export->inc < 0) {
566                 export->start = range->end;
567                 export->end = range->start - 1;
568         } else {
569                 export->start = range->start;
570                 export->end = range->end + 1;
571         }
572 }
573
574 static gboolean
575 clamp_ranges (EvPrintOperationExport *export)
576 {
577         gint num_of_correct_ranges = 0;
578         gint n_pages_to_print = 0;
579         gint i;
580         gboolean null_flag = FALSE;
581
582         for (i = 0; i < export->n_ranges; i++) {
583                 gint n_pages;
584                 
585                 if ((export->ranges[i].start >= 0) &&
586                     (export->ranges[i].start < export->n_pages) &&
587                     (export->ranges[i].end >= 0) &&
588                     (export->ranges[i].end < export->n_pages)) {
589                         export->ranges[num_of_correct_ranges] = export->ranges[i];
590                         num_of_correct_ranges++;
591                 } else if ((export->ranges[i].start >= 0) &&
592                            (export->ranges[i].start < export->n_pages) &&
593                            (export->ranges[i].end >= export->n_pages)) {
594                         export->ranges[i].end = export->n_pages - 1;
595                         export->ranges[num_of_correct_ranges] = export->ranges[i];
596                         num_of_correct_ranges++;
597                 } else if ((export->ranges[i].end >= 0) &&
598                            (export->ranges[i].end < export->n_pages) &&
599                            (export->ranges[i].start < 0)) {
600                         export->ranges[i].start = 0;
601                         export->ranges[num_of_correct_ranges] = export->ranges[i];
602                         num_of_correct_ranges++;
603                 }
604                 
605                 n_pages = export->ranges[i].end - export->ranges[i].start + 1;
606                 if (export->page_set == GTK_PAGE_SET_ALL) {
607                         n_pages_to_print += n_pages;
608                 } else if (n_pages % 2 == 0) {
609                         n_pages_to_print += n_pages / 2;
610                 } else if (export->page_set == GTK_PAGE_SET_EVEN) {
611                         if (n_pages==1 && export->ranges[i].start % 2 == 0)
612                                 null_flag = TRUE;
613                         else 
614                                 n_pages_to_print += export->ranges[i].start % 2 == 0 ?
615                                 n_pages / 2 : (n_pages / 2) + 1;
616                 } else if (export->page_set == GTK_PAGE_SET_ODD) {
617                         if (n_pages==1 && export->ranges[i].start % 2 != 0) 
618                                 null_flag = TRUE;
619                         else 
620                                 n_pages_to_print += export->ranges[i].start % 2 == 0 ?
621                                 (n_pages / 2) + 1 : n_pages / 2;
622                 }
623         }
624
625         if (null_flag && !n_pages_to_print) {
626                 return FALSE;
627         } else {
628                 export->n_ranges = num_of_correct_ranges;
629                 export->n_pages_to_print = n_pages_to_print;
630                 return TRUE;
631         }
632 }
633
634 static void
635 get_first_and_last_page (EvPrintOperationExport *export,
636                          gint                   *first,
637                          gint                   *last)
638 {
639         gint i;
640         gint first_page = G_MAXINT;
641         gint last_page = G_MININT;
642         gint max_page = export->n_pages - 1;
643
644         if (export->n_ranges == 0) {
645                 *first = 0;
646                 *last = max_page;
647
648                 return;
649         }
650
651         for (i = 0; i < export->n_ranges; i++) {
652                 if (export->ranges[i].start < first_page)
653                         first_page = export->ranges[i].start;
654                 if (export->ranges[i].end > last_page)
655                         last_page = export->ranges[i].end;
656         }
657
658         *first = MAX (0, first_page);
659         *last = MIN (max_page, last_page);
660 }
661
662 static gboolean
663 export_print_inc_page (EvPrintOperationExport *export)
664 {
665         do {
666                 export->page += export->inc;
667                 if (export->page == export->end) {
668                         export->range += export->inc;
669                         if (export->range == -1 || export->range == export->n_ranges) {
670                                 export->uncollated++;
671                                 if (export->uncollated == export->uncollated_copies)
672                                         return FALSE;
673
674                                 export->range = export->inc < 0 ? export->n_ranges - 1 : 0;
675                         }
676                         find_range (export);
677                         export->page = export->start;
678                 }
679         } while ((export->page_set == GTK_PAGE_SET_EVEN && export->page % 2 == 0) ||
680                  (export->page_set == GTK_PAGE_SET_ODD && export->page % 2 == 1));
681
682         return TRUE;
683 }
684
685 static void
686 ev_print_operation_export_clear_temp_file (EvPrintOperationExport *export)
687 {
688         if (!export->temp_file)
689                 return;
690
691         g_unlink (export->temp_file);
692         g_free (export->temp_file);
693         export->temp_file = NULL;
694 }
695
696 static void
697 ev_print_operation_export_run_next (EvPrintOperationExport *export)
698 {
699         EvPrintOperation *op = EV_PRINT_OPERATION (export);
700         EvPrintOperation *next;
701         EvDocument       *document;
702
703         /* First pop the current job */
704         document = op->document;
705         ev_print_queue_pop (document);
706         
707         next = ev_print_queue_peek (document);
708         if (next)
709                 ev_print_operation_export_begin (EV_PRINT_OPERATION_EXPORT (next));
710 }
711
712 static void
713 print_job_finished (GtkPrintJob            *print_job,
714                     EvPrintOperationExport *export,
715                     GError                 *error)
716 {
717         EvPrintOperation *op = EV_PRINT_OPERATION (export);
718
719         if (error) {
720                 g_set_error_literal (&export->error,
721                                      GTK_PRINT_ERROR,
722                                      GTK_PRINT_ERROR_GENERAL,
723                                      error->message);
724                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
725         } else {
726                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
727         }
728
729         ev_print_operation_export_clear_temp_file (export);
730         g_object_unref (print_job);
731
732         ev_print_operation_export_run_next (export);
733 }
734
735 static void
736 export_print_done (EvPrintOperationExport *export)
737 {
738         EvPrintOperation *op = EV_PRINT_OPERATION (export);
739         GtkPrintSettings *settings;
740         EvFileExporterCapabilities capabilities;
741         GError *error = NULL;
742
743         g_assert (export->temp_file != NULL);
744         
745         /* Some printers take into account some print settings,
746          * and others don't. However we have exported the document
747          * to a ps or pdf file according to such print settings. So,
748          * we want to send the exported file to printer with those
749          * settings set to default values.
750          */
751         settings = gtk_print_settings_copy (export->print_settings);
752         capabilities = ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
753
754         gtk_print_settings_set_page_ranges (settings, NULL, 0);
755         gtk_print_settings_set_print_pages (settings, GTK_PRINT_PAGES_ALL);
756         if (capabilities & EV_FILE_EXPORTER_CAN_COPIES)
757                 gtk_print_settings_set_n_copies (settings, 1);
758         if (capabilities & EV_FILE_EXPORTER_CAN_PAGE_SET)
759                 gtk_print_settings_set_page_set (settings, GTK_PAGE_SET_ALL);
760         if (capabilities & EV_FILE_EXPORTER_CAN_SCALE)
761                 gtk_print_settings_set_scale (settings, 1.0);
762         if (capabilities & EV_FILE_EXPORTER_CAN_COLLATE)
763                 gtk_print_settings_set_collate (settings, FALSE);
764         if (capabilities & EV_FILE_EXPORTER_CAN_REVERSE)
765                 gtk_print_settings_set_reverse (settings, FALSE);
766         if (capabilities & EV_FILE_EXPORTER_CAN_NUMBER_UP) {
767                 gtk_print_settings_set_number_up (settings, 1);
768                 gtk_print_settings_set_int (settings, "cups-"GTK_PRINT_SETTINGS_NUMBER_UP, 1);
769         }
770
771         if (export->print_preview) {
772                 GKeyFile *key_file;
773                 gchar    *data = NULL;
774                 gsize     data_len;
775                 gchar    *print_settings_file = NULL;
776
777                 key_file = g_key_file_new ();
778
779                 gtk_print_settings_to_key_file (settings, key_file, NULL);
780                 gtk_page_setup_to_key_file (export->page_setup, key_file, NULL);
781                 g_key_file_set_string (key_file, "Print Job", "title", export->job_name);
782
783                 data = g_key_file_to_data (key_file, &data_len, &error);
784                 if (data) {
785                         gint fd;
786                         
787                         fd = g_file_open_tmp ("print-settingsXXXXXX", &print_settings_file, &error);
788                         if (!error)
789                                 g_file_set_contents (print_settings_file, data, data_len, &error);
790                         close (fd);
791                         
792                         g_free (data);
793                 }
794
795                 g_key_file_free (key_file);
796
797                 if (!error) {
798                         gint    argc;
799                         gchar **argv;
800                         gchar  *cmd;
801                         gchar  *quoted_filename;
802                         gchar  *quoted_settings_filename;
803
804                         quoted_filename = g_shell_quote (export->temp_file);
805                         quoted_settings_filename = g_shell_quote (print_settings_file);
806                         cmd = g_strdup_printf ("evince-previewer --unlink-tempfile --print-settings %s %s",
807                                                quoted_settings_filename, quoted_filename);
808
809                         g_shell_parse_argv (cmd, &argc, &argv, &error);
810
811                         g_free (quoted_filename);
812                         g_free (quoted_settings_filename);
813                         g_free (cmd);
814
815                         if (!error) {
816                                 gdk_spawn_on_screen (gtk_window_get_screen (export->parent_window),
817                                                      NULL, argv, NULL,
818                                                      G_SPAWN_SEARCH_PATH,
819                                                      NULL, NULL, NULL,
820                                                      &error);
821                         }
822
823                         g_strfreev (argv);
824                 }
825
826                 if (error) {
827                         if (print_settings_file)
828                                 g_unlink (print_settings_file);
829                         g_free (print_settings_file);
830                 } else {
831                         g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
832                         /* temp_file will be deleted by the previewer */
833
834                         ev_print_operation_export_run_next (export);
835                 }
836         } else {
837                 GtkPrintJob *job;
838                 
839                 job = gtk_print_job_new (export->job_name,
840                                          export->printer,
841                                          settings,
842                                          export->page_setup);
843                 gtk_print_job_set_source_file (job, export->temp_file, &error);
844                 if (!error){
845                         gtk_print_job_send (job,
846                                             (GtkPrintJobCompleteFunc)print_job_finished,
847                                             g_object_ref (export),
848                                             (GDestroyNotify)g_object_unref);
849                 }
850         }
851         g_object_unref (settings);
852
853         if (error) {
854                 g_set_error_literal (&export->error,
855                                      GTK_PRINT_ERROR,
856                                      GTK_PRINT_ERROR_GENERAL,
857                                      error->message);
858                 g_error_free (error);
859                 ev_print_operation_export_clear_temp_file (export);
860                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
861
862                 ev_print_operation_export_run_next (export);
863         }
864 }
865
866 static void
867 export_print_page_idle_finished (EvPrintOperationExport *export)
868 {
869         export->idle_id = 0;
870 }
871
872 static void
873 export_job_finished (EvJobExport            *job,
874                      EvPrintOperationExport *export)
875 {
876         EvPrintOperation *op = EV_PRINT_OPERATION (export);
877
878         if (export->pages_per_sheet == 1 || export->total % export->pages_per_sheet == 0) {
879                 ev_document_doc_mutex_lock ();
880                 ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
881                 ev_document_doc_mutex_unlock ();
882         }
883
884         /* Reschedule */
885         export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
886                                            (GSourceFunc)export_print_page,
887                                            export,
888                                            (GDestroyNotify)export_print_page_idle_finished);
889 }
890
891 static void
892 export_job_cancelled (EvJobExport            *job,
893                       EvPrintOperationExport *export)
894 {
895         export_cancel (export);
896 }
897
898 static void
899 export_cancel (EvPrintOperationExport *export)
900 {
901         EvPrintOperation *op = EV_PRINT_OPERATION (export);
902
903         if (export->idle_id > 0)
904                 g_source_remove (export->idle_id);
905         export->idle_id = 0;
906
907         if (export->job_export) {
908                 g_signal_handlers_disconnect_by_func (export->job_export,
909                                                       export_job_finished,
910                                                       export);
911                 g_signal_handlers_disconnect_by_func (export->job_export,
912                                                       export_job_cancelled,
913                                                       export);
914                 g_object_unref (export->job_export);
915                 export->job_export = NULL;
916         }
917         
918         if (export->fd != -1) {
919                 close (export->fd);
920                 export->fd = -1;
921         }
922
923         ev_print_operation_export_clear_temp_file (export);
924
925         g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
926
927         ev_print_operation_export_run_next (export);
928 }
929
930 static void
931 update_progress (EvPrintOperationExport *export)
932 {
933         EvPrintOperation *op = EV_PRINT_OPERATION (export);
934
935         ev_print_operation_update_status (op, export->total,
936                                           export->n_pages_to_print,
937                                           export->total / (gdouble)export->n_pages_to_print);
938 }
939
940 static gboolean
941 export_print_page (EvPrintOperationExport *export)
942 {
943         EvPrintOperation *op = EV_PRINT_OPERATION (export);
944
945         if (!export->temp_file)
946                 return FALSE; /* cancelled */
947         
948         export->total++;
949         export->collated++;
950
951         if (export->collated == export->collated_copies) {
952                 export->collated = 0;
953                 if (!export_print_inc_page (export)) {
954                         ev_document_doc_mutex_lock ();
955                         if (export->pages_per_sheet > 1 &&
956                             export->total - 1 % export->pages_per_sheet == 0)
957                                 ev_file_exporter_end_page (EV_FILE_EXPORTER (op->document));
958                         ev_file_exporter_end (EV_FILE_EXPORTER (op->document));
959                         ev_document_doc_mutex_unlock ();
960
961                         close (export->fd);
962                         export->fd = -1;
963
964                         update_progress (export);
965                         
966                         export_print_done (export);
967
968                         return FALSE;
969                 }
970         }
971
972         if (export->pages_per_sheet == 1 || export->total % export->pages_per_sheet == 1) {
973                 ev_document_doc_mutex_lock ();
974                 ev_file_exporter_begin_page (EV_FILE_EXPORTER (op->document));
975                 ev_document_doc_mutex_unlock ();
976         }
977         
978         if (!export->job_export) {
979                 export->job_export = ev_job_export_new (op->document);
980                 g_signal_connect (export->job_export, "finished",
981                                   G_CALLBACK (export_job_finished),
982                                   (gpointer)export);
983                 g_signal_connect (export->job_export, "cancelled",
984                                   G_CALLBACK (export_job_cancelled),
985                                   (gpointer)export);
986         }
987
988         ev_job_export_set_page (EV_JOB_EXPORT (export->job_export), export->page);
989         ev_job_scheduler_push_job (export->job_export, EV_JOB_PRIORITY_NONE);
990
991         update_progress (export);
992         
993         return FALSE;
994 }
995
996 static void
997 ev_print_operation_export_begin (EvPrintOperationExport *export)
998 {
999         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1000
1001         if (!export->temp_file)
1002                 return; /* cancelled */
1003         
1004         ev_document_doc_mutex_lock ();
1005         ev_file_exporter_begin (EV_FILE_EXPORTER (op->document), &export->fc);
1006         ev_document_doc_mutex_unlock ();
1007
1008         export->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
1009                                            (GSourceFunc)export_print_page,
1010                                            export,
1011                                            (GDestroyNotify)export_print_page_idle_finished);    
1012 }
1013
1014 static void
1015 ev_print_operation_export_print_dialog_response_cb (GtkDialog              *dialog,
1016                                                     gint                    response,
1017                                                     EvPrintOperationExport *export)
1018 {
1019         GtkPrintPages     print_pages;
1020         GtkPrintSettings *print_settings;
1021         GtkPageSetup     *page_setup;
1022         GtkPrinter       *printer;
1023         gdouble           scale;
1024         gdouble           width;
1025         gdouble           height;
1026         gint              first_page;
1027         gint              last_page;
1028         const gchar      *file_format;
1029         gchar            *filename;
1030         GError           *error = NULL;
1031         EvPrintOperation *op = EV_PRINT_OPERATION (export);
1032         
1033         if (response != GTK_RESPONSE_OK &&
1034             response != GTK_RESPONSE_APPLY) {
1035                 gtk_widget_destroy (GTK_WIDGET (dialog));
1036                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_CANCEL);
1037
1038                 return;
1039         }
1040
1041         export->print_preview = (response == GTK_RESPONSE_APPLY);
1042         
1043         printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (dialog));
1044         ev_print_operation_export_set_printer (export, printer);
1045
1046         print_settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog));
1047         ev_print_operation_export_set_print_settings (op, print_settings);
1048
1049         page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (dialog));
1050         ev_print_operation_export_set_default_page_setup (op, page_setup);
1051
1052         if (!gtk_printer_accepts_ps (export->printer)) {
1053                 gtk_widget_destroy (GTK_WIDGET (dialog));
1054                 
1055                 g_set_error_literal (&export->error,
1056                                      GTK_PRINT_ERROR,
1057                                      GTK_PRINT_ERROR_GENERAL,
1058                                      _("Printing is not supported on this printer."));
1059                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1060                 
1061                 return;
1062         }
1063
1064         file_format = gtk_print_settings_get (print_settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
1065         
1066         filename = g_strdup_printf ("evince_print.%s.XXXXXX", file_format);
1067         export->fd = g_file_open_tmp (filename, &export->temp_file, &error);
1068         g_free (filename);
1069         if (export->fd <= -1) {
1070                 gtk_widget_destroy (GTK_WIDGET (dialog));
1071                 
1072                 g_set_error_literal (&export->error,
1073                                      GTK_PRINT_ERROR,
1074                                      GTK_PRINT_ERROR_GENERAL,
1075                                      error->message);
1076                 g_error_free (error);
1077                 g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_ERROR);
1078
1079                 return;
1080         }
1081
1082         export->current_page = gtk_print_unix_dialog_get_current_page (GTK_PRINT_UNIX_DIALOG (dialog));
1083         export->page_set = gtk_print_settings_get_page_set (print_settings);
1084         print_pages = gtk_print_settings_get_print_pages (print_settings);
1085         
1086         switch (print_pages) {
1087         case GTK_PRINT_PAGES_CURRENT:
1088                 export->ranges = &export->one_range;
1089                 
1090                 export->ranges[0].start = export->current_page;
1091                 export->ranges[0].end = export->current_page;
1092                 export->n_ranges = 1;
1093                                 
1094                 break;
1095         case GTK_PRINT_PAGES_RANGES: {
1096                 gint i;
1097                 
1098                 export->ranges = gtk_print_settings_get_page_ranges (print_settings, &export->n_ranges);
1099                 for (i = 0; i < export->n_ranges; i++)
1100                         if (export->ranges[i].end == -1 || export->ranges[i].end >= export->n_pages)
1101                                 export->ranges[i].end = export->n_pages - 1;
1102         }
1103                 break;
1104         case GTK_PRINT_PAGES_ALL:
1105                 export->ranges = &export->one_range;
1106
1107                 export->ranges[0].start = 0;
1108                 export->ranges[0].end = export->n_pages - 1;
1109                 export->n_ranges = 1;
1110                 
1111                 break;
1112         }
1113         if (!clamp_ranges (export)) {
1114                 GtkWidget *message_dialog;
1115
1116                 message_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
1117                                                  GTK_DIALOG_MODAL,
1118                                                  GTK_MESSAGE_WARNING,
1119                                                  GTK_BUTTONS_CLOSE,
1120                                                  "%s", _("Invalid page selection"));
1121                 gtk_window_set_title (GTK_WINDOW (message_dialog), _("Warning"));
1122                 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message_dialog),
1123                                                           "%s", _("Your print range selection does not include any page"));
1124                 g_signal_connect (message_dialog, "response",
1125                                   G_CALLBACK (gtk_widget_destroy),
1126                                   NULL);
1127                 gtk_widget_show (message_dialog);
1128
1129                 return;
1130         } else  ev_print_operation_update_status (op, -1, -1, 0.0);
1131  
1132         width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1133         height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1134         scale = gtk_print_settings_get_scale (print_settings) * 0.01;
1135         if (scale != 1.0) {
1136                 width *= scale;
1137                 height *= scale;
1138         }
1139
1140         export->pages_per_sheet = MAX (1, gtk_print_settings_get_number_up (print_settings));
1141         
1142         export->copies = gtk_print_settings_get_n_copies (print_settings);
1143         export->collate = gtk_print_settings_get_collate (print_settings);
1144         export->reverse = gtk_print_settings_get_reverse (print_settings);
1145
1146         if (export->collate) {
1147                 export->uncollated_copies = export->copies;
1148                 export->collated_copies = 1;
1149         } else {
1150                 export->uncollated_copies = 1;
1151                 export->collated_copies = export->copies;
1152         }
1153
1154         if (export->reverse) {
1155                 export->range = export->n_ranges - 1;
1156                 export->inc = -1;
1157         } else {
1158                 export->range = 0;
1159                 export->inc = 1;
1160         }
1161         find_range (export);
1162
1163         export->page = export->start - export->inc;
1164         export->collated = export->collated_copies - 1;
1165
1166         get_first_and_last_page (export, &first_page, &last_page);
1167
1168         export->fc.format = file_format && g_ascii_strcasecmp (file_format, "pdf") == 0 ?
1169                 EV_FILE_FORMAT_PDF : EV_FILE_FORMAT_PS;
1170         export->fc.filename = export->temp_file;
1171         export->fc.first_page = MIN (first_page, last_page);
1172         export->fc.last_page = MAX (first_page, last_page);
1173         export->fc.paper_width = width;
1174         export->fc.paper_height = height;
1175         export->fc.duplex = FALSE;
1176         export->fc.pages_per_sheet = export->pages_per_sheet;
1177
1178         if (ev_print_queue_is_empty (op->document))
1179                 ev_print_operation_export_begin (export);
1180
1181         ev_print_queue_push (op);
1182
1183         g_signal_emit (op, signals[BEGIN_PRINT], 0);
1184         
1185         gtk_widget_destroy (GTK_WIDGET (dialog));
1186 }
1187
1188 static void
1189 ev_print_operation_export_run (EvPrintOperation *op,
1190                                GtkWindow        *parent)
1191 {
1192         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1193         GtkWidget              *dialog;
1194         GtkPrintCapabilities    capabilities;
1195
1196         ev_print_queue_init ();
1197
1198         export->parent_window = parent;
1199         export->error = NULL;
1200         
1201         dialog = gtk_print_unix_dialog_new (_("Print"), parent);
1202         gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1203         
1204         capabilities = GTK_PRINT_CAPABILITY_PREVIEW |
1205                 ev_file_exporter_get_capabilities (EV_FILE_EXPORTER (op->document));
1206         gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog),
1207                                                        capabilities);
1208
1209         gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (dialog),
1210                                                 export->current_page);
1211         
1212         gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog),
1213                                             export->print_settings);
1214         
1215         if (export->page_setup)
1216                 gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (dialog),
1217                                                       export->page_setup);
1218         
1219         g_signal_connect (dialog, "response",
1220                           G_CALLBACK (ev_print_operation_export_print_dialog_response_cb),
1221                           export);
1222
1223         gtk_window_present (GTK_WINDOW (dialog));
1224 }
1225
1226 static void
1227 ev_print_operation_export_cancel (EvPrintOperation *op)
1228 {
1229         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1230
1231         if (export->job_export &&
1232             !ev_job_is_finished (export->job_export)) {
1233                 ev_job_cancel (export->job_export);
1234         } else {
1235                 export_cancel (export);
1236         }
1237 }
1238
1239 static void
1240 ev_print_operation_export_get_error (EvPrintOperation *op,
1241                                      GError          **error)
1242 {
1243         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (op);
1244
1245         g_propagate_error (error, export->error);
1246         export->error = NULL;
1247 }
1248
1249 static void
1250 ev_print_operation_export_finalize (GObject *object)
1251 {
1252         EvPrintOperationExport *export = EV_PRINT_OPERATION_EXPORT (object);
1253
1254         if (export->idle_id > 0) {
1255                 g_source_remove (export->idle_id);
1256                 export->idle_id = 0;
1257         }
1258
1259         if (export->fd != -1) {
1260                 close (export->fd);
1261                 export->fd = -1;
1262         }
1263         
1264         if (export->ranges) {
1265                 if (export->ranges != &export->one_range)
1266                         g_free (export->ranges);
1267                 export->ranges = NULL;
1268                 export->n_ranges = 0;
1269         }
1270
1271         if (export->temp_file) {
1272                 g_free (export->temp_file);
1273                 export->temp_file = NULL;
1274         }
1275
1276         if (export->job_name) {
1277                 g_free (export->job_name);
1278                 export->job_name = NULL;
1279         }
1280
1281         if (export->job_export) {
1282                 if (!ev_job_is_finished (export->job_export))
1283                         ev_job_cancel (export->job_export);
1284                 g_signal_handlers_disconnect_by_func (export->job_export,
1285                                                       export_job_finished,
1286                                                       export);
1287                 g_signal_handlers_disconnect_by_func (export->job_export,
1288                                                       export_job_cancelled,
1289                                                       export);
1290                 g_object_unref (export->job_export);
1291                 export->job_export = NULL;
1292         }
1293
1294         if (export->error) {
1295                 g_error_free (export->error);
1296                 export->error = NULL;
1297         }
1298
1299         if (export->print_settings) {
1300                 g_object_unref (export->print_settings);
1301                 export->print_settings = NULL;
1302         }
1303
1304         if (export->page_setup) {
1305                 g_object_unref (export->page_setup);
1306                 export->page_setup = NULL;
1307         }
1308
1309         if (export->printer) {
1310                 g_object_unref (export->printer);
1311                 export->printer = NULL;
1312         }
1313
1314         (* G_OBJECT_CLASS (ev_print_operation_export_parent_class)->finalize) (object);
1315 }
1316
1317 static void
1318 ev_print_operation_export_init (EvPrintOperationExport *export)
1319 {
1320 }
1321
1322 static GObject *
1323 ev_print_operation_export_constructor (GType                  type,
1324                                        guint                  n_construct_properties,
1325                                        GObjectConstructParam *construct_params)
1326 {
1327         GObject                *object;
1328         EvPrintOperationExport *export;
1329         EvPrintOperation       *op;
1330         
1331         object = G_OBJECT_CLASS (ev_print_operation_export_parent_class)->constructor (type,
1332                                                                                        n_construct_properties,
1333                                                                                        construct_params);
1334         export = EV_PRINT_OPERATION_EXPORT (object);
1335         op = EV_PRINT_OPERATION (object);
1336         export->n_pages = ev_page_cache_get_n_pages (ev_page_cache_get (op->document));
1337
1338         return object;
1339 }
1340
1341 static void
1342 ev_print_operation_export_class_init (EvPrintOperationExportClass *klass)
1343 {
1344         GObjectClass          *g_object_class = G_OBJECT_CLASS (klass);
1345         EvPrintOperationClass *ev_print_op_class = EV_PRINT_OPERATION_CLASS (klass);
1346
1347         ev_print_op_class->set_current_page = ev_print_operation_export_set_current_page;
1348         ev_print_op_class->set_print_settings = ev_print_operation_export_set_print_settings;
1349         ev_print_op_class->get_print_settings = ev_print_operation_export_get_print_settings;
1350         ev_print_op_class->set_default_page_setup = ev_print_operation_export_set_default_page_setup;
1351         ev_print_op_class->get_default_page_setup = ev_print_operation_export_get_default_page_setup;
1352         ev_print_op_class->set_job_name = ev_print_operation_export_set_job_name;
1353         ev_print_op_class->get_job_name = ev_print_operation_export_get_job_name;
1354         ev_print_op_class->run = ev_print_operation_export_run;
1355         ev_print_op_class->cancel = ev_print_operation_export_cancel;
1356         ev_print_op_class->get_error = ev_print_operation_export_get_error;
1357
1358         g_object_class->constructor = ev_print_operation_export_constructor;
1359         g_object_class->finalize = ev_print_operation_export_finalize;
1360 }
1361
1362 /* Factory method */
1363 EvPrintOperation *
1364 ev_print_operation_new (EvDocument *document)
1365 {
1366         /* TODO: EvPrintOperationPrint */
1367
1368         return EV_PRINT_OPERATION (g_object_new (EV_TYPE_PRINT_OPERATION_EXPORT,
1369                                                  "document", document, NULL));
1370 }