]> Pileus Git - ~andy/gtk/blob - gtk/gtkprintoperation.c
8cb69d3be2b947bad0f54be9db7770037036d1ab
[~andy/gtk] / gtk / gtkprintoperation.c
1 /* GTK - The GIMP Toolkit
2  * gtkprintoperation.c: Print Operation
3  * Copyright (C) 2006, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "config.h"
20
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <math.h>
24 #include <string.h>
25
26 #include <cairo-pdf.h>
27
28 #include "gtkprintoperation-private.h"
29 #include "gtkmarshalers.h"
30 #include "gtkintl.h"
31 #include "gtkprivate.h"
32 #include "gtkmessagedialog.h"
33 #include "gtktypebuiltins.h"
34
35 /**
36  * SECTION:gtkprintoperation
37  * @Title: GtkPrintOperation
38  * @Short_description: High-level Printing API
39  * @See_also: #GtkPrintContext, #GtkPrintUnixDialog
40  *
41  * GtkPrintOperation is the high-level, portable printing API.
42  * It looks a bit different than other GTK+ dialogs such as the
43  * #GtkFileChooser, since some platforms don't expose enough
44  * infrastructure to implement a good print dialog. On such
45  * platforms, GtkPrintOperation uses the native print dialog.
46  * On platforms which do not provide a native print dialog, GTK+
47  * uses its own, see #GtkPrintUnixDialog.
48  *
49  * The typical way to use the high-level printing API is to create
50  * a GtkPrintOperation object with gtk_print_operation_new() when
51  * the user selects to print. Then you set some properties on it,
52  * e.g. the page size, any #GtkPrintSettings from previous print
53  * operations, the number of pages, the current page, etc.
54  *
55  * Then you start the print operation by calling gtk_print_operation_run().
56  * It will then show a dialog, let the user select a printer and
57  * options. When the user finished the dialog various signals will
58  * be emitted on the #GtkPrintOperation, the main one being
59  * #GtkPrintOperation::draw-page, which you are supposed to catch
60  * and render the page on the provided #GtkPrintContext using Cairo.
61  *
62  * <example>
63  * <title>The high-level printing API</title>
64  * <programlisting>
65  * static GtkPrintSettings *settings = NULL;
66  *
67  * static void
68  * do_print (void)
69  * {
70  *   GtkPrintOperation *print;
71  *   GtkPrintOperationResult res;
72  *
73  *   print = gtk_print_operation_new ();
74  *
75  *   if (settings != NULL)
76  *     gtk_print_operation_set_print_settings (print, settings);
77  *
78  *   g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), NULL);
79  *   g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), NULL);
80  *
81  *   res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
82  *                                  GTK_WINDOW (main_window), NULL);
83  *
84  *   if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
85  *     {
86  *       if (settings != NULL)
87  *         g_object_unref (settings);
88  *       settings = g_object_ref (gtk_print_operation_get_print_settings (print));
89  *     }
90  *
91  *   g_object_unref (print);
92  * }
93  * </programlisting>
94  * </example>
95  *
96  * By default GtkPrintOperation uses an external application to do
97  * print preview. To implement a custom print preview, an application
98  * must connect to the preview signal. The functions
99  * gtk_print_operation_preview_render_page(),
100  * gtk_print_operation_preview_end_preview() and
101  * gtk_print_operation_preview_is_selected()
102  * are useful when implementing a print preview.
103  */
104
105 #define SHOW_PROGRESS_TIME 1200
106
107
108 enum
109 {
110   DONE,
111   BEGIN_PRINT,
112   PAGINATE,
113   REQUEST_PAGE_SETUP,
114   DRAW_PAGE,
115   END_PRINT,
116   STATUS_CHANGED,
117   CREATE_CUSTOM_WIDGET,
118   CUSTOM_WIDGET_APPLY,
119   PREVIEW,
120   UPDATE_CUSTOM_WIDGET,
121   LAST_SIGNAL
122 };
123
124 enum 
125 {
126   PROP_0,
127   PROP_DEFAULT_PAGE_SETUP,
128   PROP_PRINT_SETTINGS,
129   PROP_JOB_NAME,
130   PROP_N_PAGES,
131   PROP_CURRENT_PAGE,
132   PROP_USE_FULL_PAGE,
133   PROP_TRACK_PRINT_STATUS,
134   PROP_UNIT,
135   PROP_SHOW_PROGRESS,
136   PROP_ALLOW_ASYNC,
137   PROP_EXPORT_FILENAME,
138   PROP_STATUS,
139   PROP_STATUS_STRING,
140   PROP_CUSTOM_TAB_LABEL,
141   PROP_EMBED_PAGE_SETUP,
142   PROP_HAS_SELECTION,
143   PROP_SUPPORT_SELECTION,
144   PROP_N_PAGES_TO_PRINT
145 };
146
147 static guint signals[LAST_SIGNAL] = { 0 };
148 static int job_nr = 0;
149 typedef struct _PrintPagesData PrintPagesData;
150
151 static void          preview_iface_init      (GtkPrintOperationPreviewIface *iface);
152 static GtkPageSetup *create_page_setup       (GtkPrintOperation             *op);
153 static void          common_render_page      (GtkPrintOperation             *op,
154                                               gint                           page_nr);
155 static void          increment_page_sequence (PrintPagesData *data);
156 static void          prepare_data            (PrintPagesData *data);
157 static void          clamp_page_ranges       (PrintPagesData *data);
158
159
160 G_DEFINE_TYPE_WITH_CODE (GtkPrintOperation, gtk_print_operation, G_TYPE_OBJECT,
161                          G_IMPLEMENT_INTERFACE (GTK_TYPE_PRINT_OPERATION_PREVIEW,
162                                                 preview_iface_init))
163
164 /**
165  * gtk_print_error_quark:
166  *
167  * Registers an error quark for #GtkPrintOperation if necessary.
168  * 
169  * Return value: The error quark used for #GtkPrintOperation errors.
170  *
171  * Since: 2.10
172  **/
173 GQuark     
174 gtk_print_error_quark (void)
175 {
176   static GQuark quark = 0;
177   if (quark == 0)
178     quark = g_quark_from_static_string ("gtk-print-error-quark");
179   return quark;
180 }
181      
182 static void
183 gtk_print_operation_finalize (GObject *object)
184 {
185   GtkPrintOperation *print_operation = GTK_PRINT_OPERATION (object);
186   GtkPrintOperationPrivate *priv = print_operation->priv;
187
188   if (priv->free_platform_data &&
189       priv->platform_data)
190     {
191       priv->free_platform_data (priv->platform_data);
192       priv->free_platform_data = NULL;
193     }
194
195   if (priv->default_page_setup)
196     g_object_unref (priv->default_page_setup);
197   
198   if (priv->print_settings)
199     g_object_unref (priv->print_settings);
200   
201   if (priv->print_context)
202     g_object_unref (priv->print_context);
203
204   g_free (priv->export_filename);
205   g_free (priv->job_name);
206   g_free (priv->custom_tab_label);
207   g_free (priv->status_string);
208
209   if (priv->print_pages_idle_id > 0)
210     g_source_remove (priv->print_pages_idle_id);
211
212   if (priv->show_progress_timeout_id > 0)
213     g_source_remove (priv->show_progress_timeout_id);
214
215   if (priv->error)
216     g_error_free (priv->error);
217   
218   G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object);
219 }
220
221 static void
222 gtk_print_operation_init (GtkPrintOperation *operation)
223 {
224   GtkPrintOperationPrivate *priv;
225   const char *appname;
226
227   priv = operation->priv = G_TYPE_INSTANCE_GET_PRIVATE (operation,
228                                                         GTK_TYPE_PRINT_OPERATION,
229                                                         GtkPrintOperationPrivate);
230
231   priv->status = GTK_PRINT_STATUS_INITIAL;
232   priv->status_string = g_strdup ("");
233   priv->default_page_setup = NULL;
234   priv->print_settings = NULL;
235   priv->nr_of_pages = -1;
236   priv->nr_of_pages_to_print = -1;
237   priv->page_position = -1;
238   priv->current_page = -1;
239   priv->use_full_page = FALSE;
240   priv->show_progress = FALSE;
241   priv->export_filename = NULL;
242   priv->track_print_status = FALSE;
243   priv->is_sync = FALSE;
244   priv->support_selection = FALSE;
245   priv->has_selection = FALSE;
246   priv->embed_page_setup = FALSE;
247
248   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY;
249
250   priv->rloop = NULL;
251   priv->unit = GTK_UNIT_NONE;
252
253   appname = g_get_application_name ();
254   if (appname == NULL)
255     appname = "";
256   /* translators: this string is the default job title for print
257    * jobs. %s gets replaced by the application name, %d gets replaced
258    * by the job number.
259    */
260   priv->job_name = g_strdup_printf (_("%s job #%d"), appname, ++job_nr);
261 }
262
263 static void
264 preview_iface_render_page (GtkPrintOperationPreview *preview,
265                            gint                      page_nr)
266 {
267
268   GtkPrintOperation *op;
269
270   op = GTK_PRINT_OPERATION (preview);
271   common_render_page (op, page_nr);
272 }
273
274 static void
275 preview_iface_end_preview (GtkPrintOperationPreview *preview)
276 {
277   GtkPrintOperation *op;
278   GtkPrintOperationResult result;
279   
280   op = GTK_PRINT_OPERATION (preview);
281
282   g_signal_emit (op, signals[END_PRINT], 0, op->priv->print_context);
283
284   if (op->priv->rloop)
285     g_main_loop_quit (op->priv->rloop);
286   
287   if (op->priv->end_run)
288     op->priv->end_run (op, op->priv->is_sync, TRUE);
289   
290   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
291
292   if (op->priv->error)
293     result = GTK_PRINT_OPERATION_RESULT_ERROR;
294   else if (op->priv->cancelled)
295     result = GTK_PRINT_OPERATION_RESULT_CANCEL;
296   else
297     result = GTK_PRINT_OPERATION_RESULT_APPLY;
298
299   g_signal_emit (op, signals[DONE], 0, result);
300 }
301
302 static gboolean
303 preview_iface_is_selected (GtkPrintOperationPreview *preview,
304                            gint                      page_nr)
305 {
306   GtkPrintOperation *op;
307   GtkPrintOperationPrivate *priv;
308   int i;
309   
310   op = GTK_PRINT_OPERATION (preview);
311   priv = op->priv;
312   
313   switch (priv->print_pages)
314     {
315     case GTK_PRINT_PAGES_SELECTION:
316     case GTK_PRINT_PAGES_ALL:
317       return (page_nr >= 0) && (page_nr < priv->nr_of_pages);
318     case GTK_PRINT_PAGES_CURRENT:
319       return page_nr == priv->current_page;
320     case GTK_PRINT_PAGES_RANGES:
321       for (i = 0; i < priv->num_page_ranges; i++)
322         {
323           if (page_nr >= priv->page_ranges[i].start &&
324               (page_nr <= priv->page_ranges[i].end || priv->page_ranges[i].end == -1))
325             return TRUE;
326         }
327       return FALSE;
328     }
329   return FALSE;
330 }
331
332 static void
333 preview_iface_init (GtkPrintOperationPreviewIface *iface)
334 {
335   iface->render_page = preview_iface_render_page;
336   iface->end_preview = preview_iface_end_preview;
337   iface->is_selected = preview_iface_is_selected;
338 }
339
340 static void
341 preview_start_page (GtkPrintOperation *op,
342                     GtkPrintContext   *print_context,
343                     GtkPageSetup      *page_setup)
344 {
345   if ((op->priv->manual_number_up < 2) ||
346       (op->priv->page_position % op->priv->manual_number_up == 0))
347     g_signal_emit_by_name (op, "got-page-size", print_context, page_setup);
348 }
349
350 static void
351 preview_end_page (GtkPrintOperation *op,
352                   GtkPrintContext   *print_context)
353 {
354   cairo_t *cr;
355
356   cr = gtk_print_context_get_cairo_context (print_context);
357
358   if ((op->priv->manual_number_up < 2) ||
359       ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
360       (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
361     cairo_show_page (cr);
362 }
363
364 static void
365 preview_end_run (GtkPrintOperation *op,
366                  gboolean           wait,
367                  gboolean           cancelled)
368 {
369   g_free (op->priv->page_ranges);
370   op->priv->page_ranges = NULL;
371 }
372
373
374 static void
375 gtk_print_operation_set_property (GObject      *object,
376                                   guint         prop_id,
377                                   const GValue *value,
378                                   GParamSpec   *pspec)
379 {
380   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
381   
382   switch (prop_id)
383     {
384     case PROP_DEFAULT_PAGE_SETUP:
385       gtk_print_operation_set_default_page_setup (op, g_value_get_object (value));
386       break;
387     case PROP_PRINT_SETTINGS:
388       gtk_print_operation_set_print_settings (op, g_value_get_object (value));
389       break;
390     case PROP_JOB_NAME:
391       gtk_print_operation_set_job_name (op, g_value_get_string (value));
392       break;
393     case PROP_N_PAGES:
394       gtk_print_operation_set_n_pages (op, g_value_get_int (value));
395       break;
396     case PROP_CURRENT_PAGE:
397       gtk_print_operation_set_current_page (op, g_value_get_int (value));
398       break;
399     case PROP_USE_FULL_PAGE:
400       gtk_print_operation_set_use_full_page (op, g_value_get_boolean (value));
401       break;
402     case PROP_TRACK_PRINT_STATUS:
403       gtk_print_operation_set_track_print_status (op, g_value_get_boolean (value));
404       break;
405     case PROP_UNIT:
406       gtk_print_operation_set_unit (op, g_value_get_enum (value));
407       break;
408     case PROP_ALLOW_ASYNC:
409       gtk_print_operation_set_allow_async (op, g_value_get_boolean (value));
410       break;
411     case PROP_SHOW_PROGRESS:
412       gtk_print_operation_set_show_progress (op, g_value_get_boolean (value));
413       break;
414     case PROP_EXPORT_FILENAME:
415       gtk_print_operation_set_export_filename (op, g_value_get_string (value));
416       break;
417     case PROP_CUSTOM_TAB_LABEL:
418       gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value));
419       break;
420     case PROP_EMBED_PAGE_SETUP:
421       gtk_print_operation_set_embed_page_setup (op, g_value_get_boolean (value));
422       break;
423     case PROP_HAS_SELECTION:
424       gtk_print_operation_set_has_selection (op, g_value_get_boolean (value));
425       break;
426     case PROP_SUPPORT_SELECTION:
427       gtk_print_operation_set_support_selection (op, g_value_get_boolean (value));
428       break;
429     default:
430       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
431       break;
432     }
433 }
434
435 static void
436 gtk_print_operation_get_property (GObject    *object,
437                                   guint       prop_id,
438                                   GValue     *value,
439                                   GParamSpec *pspec)
440 {
441   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
442   GtkPrintOperationPrivate *priv = op->priv;
443
444   switch (prop_id)
445     {
446     case PROP_DEFAULT_PAGE_SETUP:
447       g_value_set_object (value, priv->default_page_setup);
448       break;
449     case PROP_PRINT_SETTINGS:
450       g_value_set_object (value, priv->print_settings);
451       break;
452     case PROP_JOB_NAME:
453       g_value_set_string (value, priv->job_name);
454       break;
455     case PROP_N_PAGES:
456       g_value_set_int (value, priv->nr_of_pages);
457       break;
458     case PROP_CURRENT_PAGE:
459       g_value_set_int (value, priv->current_page);
460       break;      
461     case PROP_USE_FULL_PAGE:
462       g_value_set_boolean (value, priv->use_full_page);
463       break;
464     case PROP_TRACK_PRINT_STATUS:
465       g_value_set_boolean (value, priv->track_print_status);
466       break;
467     case PROP_UNIT:
468       g_value_set_enum (value, priv->unit);
469       break;
470     case PROP_ALLOW_ASYNC:
471       g_value_set_boolean (value, priv->allow_async);
472       break;
473     case PROP_SHOW_PROGRESS:
474       g_value_set_boolean (value, priv->show_progress);
475       break;
476     case PROP_EXPORT_FILENAME:
477       g_value_set_string (value, priv->export_filename);
478       break;
479     case PROP_STATUS:
480       g_value_set_enum (value, priv->status);
481       break;
482     case PROP_STATUS_STRING:
483       g_value_set_string (value, priv->status_string);
484       break;
485     case PROP_CUSTOM_TAB_LABEL:
486       g_value_set_string (value, priv->custom_tab_label);
487       break;
488     case PROP_EMBED_PAGE_SETUP:
489       g_value_set_boolean (value, priv->embed_page_setup);
490       break;
491     case PROP_HAS_SELECTION:
492       g_value_set_boolean (value, priv->has_selection);
493       break;
494     case PROP_SUPPORT_SELECTION:
495       g_value_set_boolean (value, priv->support_selection);
496       break;
497     case PROP_N_PAGES_TO_PRINT:
498       g_value_set_int (value, priv->nr_of_pages_to_print);
499       break;
500     default:
501       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
502       break;
503     }
504 }
505
506 struct _PrintPagesData
507 {
508   GtkPrintOperation *op;
509   gint uncollated_copies;
510   gint collated_copies;
511   gint uncollated, collated, total;
512
513   gint range, num_ranges;
514   GtkPageRange *ranges;
515   GtkPageRange one_range;
516
517   gint page;
518   gint sheet;
519   gint first_position, last_position;
520   gint first_sheet;
521   gint num_of_sheets;
522   gint *pages;
523
524   GtkWidget *progress;
525  
526   gboolean initialized;
527   gboolean is_preview;
528   gboolean done;
529 };
530
531 typedef struct
532 {
533   GtkPrintOperationPreview *preview;
534   GtkPrintContext *print_context;
535   GtkWindow *parent;
536   cairo_surface_t *surface;
537   gchar *filename;
538   gboolean wait;
539   PrintPagesData *pages_data;
540 } PreviewOp;
541
542 static void
543 preview_print_idle_done (gpointer data)
544 {
545   GtkPrintOperation *op;
546   PreviewOp *pop = (PreviewOp *) data;
547
548   op = GTK_PRINT_OPERATION (pop->preview);
549
550   cairo_surface_finish (pop->surface);
551
552   if (op->priv->status == GTK_PRINT_STATUS_FINISHED_ABORTED)
553     {
554       cairo_surface_destroy (pop->surface);
555     }
556   else
557     {
558       /* Surface is destroyed in launch_preview */
559       _gtk_print_operation_platform_backend_launch_preview (op,
560                                                             pop->surface,
561                                                             pop->parent,
562                                                             pop->filename);
563     }
564
565   g_free (pop->filename);
566
567   gtk_print_operation_preview_end_preview (pop->preview);
568
569   g_object_unref (pop->pages_data->op);
570   g_free (pop->pages_data->pages);
571   g_free (pop->pages_data);
572
573   g_object_unref (op);
574   g_free (pop);
575 }
576
577 static gboolean
578 preview_print_idle (gpointer data)
579 {
580   PreviewOp *pop;
581   GtkPrintOperation *op;
582   GtkPrintOperationPrivate *priv; 
583   gboolean done = FALSE;
584
585   pop = (PreviewOp *) data;
586   op = GTK_PRINT_OPERATION (pop->preview);
587   priv = op->priv;
588
589   if (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY)
590     {
591       if (priv->cancelled)
592         {
593           done = TRUE;
594           _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
595         }
596       else if (!pop->pages_data->initialized)
597         {
598           pop->pages_data->initialized = TRUE;
599           prepare_data (pop->pages_data);
600         }
601       else
602         {
603           increment_page_sequence (pop->pages_data);
604
605           if (!pop->pages_data->done)
606             gtk_print_operation_preview_render_page (pop->preview, pop->pages_data->page);
607           else
608             done = priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY;
609         }
610     }
611
612   return !done;
613 }
614
615 static void
616 preview_got_page_size (GtkPrintOperationPreview *preview, 
617                        GtkPrintContext          *context,
618                        GtkPageSetup             *page_setup,
619                        PreviewOp                *pop)
620 {
621   GtkPrintOperation *op = GTK_PRINT_OPERATION (preview);
622   cairo_t *cr;
623
624   _gtk_print_operation_platform_backend_resize_preview_surface (op, page_setup, pop->surface);
625
626   cr = gtk_print_context_get_cairo_context (pop->print_context);
627   _gtk_print_operation_platform_backend_preview_start_page (op, pop->surface, cr);
628
629 }
630
631 static void
632 preview_ready (GtkPrintOperationPreview *preview,
633                GtkPrintContext          *context,
634                PreviewOp                *pop)
635 {
636   pop->print_context = context;
637
638   g_object_ref (preview);
639       
640   gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
641                              preview_print_idle,
642                              pop,
643                              preview_print_idle_done);
644 }
645
646
647 static gboolean
648 gtk_print_operation_preview_handler (GtkPrintOperation        *op,
649                                      GtkPrintOperationPreview *preview, 
650                                      GtkPrintContext          *context,
651                                      GtkWindow                *parent)
652 {
653   gdouble dpi_x, dpi_y;
654   PreviewOp *pop;
655   GtkPageSetup *page_setup;
656   cairo_t *cr;
657
658   pop = g_new0 (PreviewOp, 1);
659   pop->filename = NULL;
660   pop->preview = preview;
661   pop->parent = parent;
662   pop->pages_data = g_new0 (PrintPagesData, 1);
663   pop->pages_data->op = g_object_ref (GTK_PRINT_OPERATION (preview));
664   pop->pages_data->is_preview = TRUE;
665
666   page_setup = gtk_print_context_get_page_setup (context);
667
668   pop->surface =
669     _gtk_print_operation_platform_backend_create_preview_surface (op,
670                                                                   page_setup,
671                                                                   &dpi_x, &dpi_y,
672                                                                   &pop->filename);
673
674   if (pop->surface == NULL)
675     {
676       g_free (pop);
677       return FALSE;
678     }
679
680   cr = cairo_create (pop->surface);
681   gtk_print_context_set_cairo_context (op->priv->print_context, cr,
682                                        dpi_x, dpi_y);
683   cairo_destroy (cr);
684
685   g_signal_connect (preview, "ready", (GCallback) preview_ready, pop);
686   g_signal_connect (preview, "got-page-size", (GCallback) preview_got_page_size, pop);
687   
688   return TRUE;
689 }
690
691 static GtkWidget *
692 gtk_print_operation_create_custom_widget (GtkPrintOperation *operation)
693 {
694   return NULL;
695 }
696
697 static void
698 gtk_print_operation_done (GtkPrintOperation       *operation,
699                           GtkPrintOperationResult  result)
700 {
701   GtkPrintOperationPrivate *priv = operation->priv;
702
703   if (priv->print_context)
704     {
705       g_object_unref (priv->print_context);
706       priv->print_context = NULL;
707     } 
708 }
709
710 static gboolean
711 custom_widget_accumulator (GSignalInvocationHint *ihint,
712                            GValue                *return_accu,
713                            const GValue          *handler_return,
714                            gpointer               dummy)
715 {
716   gboolean continue_emission;
717   GtkWidget *widget;
718   
719   widget = g_value_get_object (handler_return);
720   if (widget != NULL)
721     g_value_set_object (return_accu, widget);
722   continue_emission = (widget == NULL);
723   
724   return continue_emission;
725 }
726
727 static void
728 gtk_print_operation_class_init (GtkPrintOperationClass *class)
729 {
730   GObjectClass *gobject_class = (GObjectClass *)class;
731
732   gobject_class->set_property = gtk_print_operation_set_property;
733   gobject_class->get_property = gtk_print_operation_get_property;
734   gobject_class->finalize = gtk_print_operation_finalize;
735  
736   class->preview = gtk_print_operation_preview_handler; 
737   class->create_custom_widget = gtk_print_operation_create_custom_widget;
738   class->done = gtk_print_operation_done;
739   
740   g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
741
742   /**
743    * GtkPrintOperation::done:
744    * @operation: the #GtkPrintOperation on which the signal was emitted
745    * @result: the result of the print operation
746    *
747    * Emitted when the print operation run has finished doing
748    * everything required for printing. 
749    *
750    * @result gives you information about what happened during the run. 
751    * If @result is %GTK_PRINT_OPERATION_RESULT_ERROR then you can call
752    * gtk_print_operation_get_error() for more information.
753    *
754    * If you enabled print status tracking then 
755    * gtk_print_operation_is_finished() may still return %FALSE 
756    * after #GtkPrintOperation::done was emitted.
757    *
758    * Since: 2.10
759    */
760   signals[DONE] =
761     g_signal_new (I_("done"),
762                   G_TYPE_FROM_CLASS (gobject_class),
763                   G_SIGNAL_RUN_LAST,
764                   G_STRUCT_OFFSET (GtkPrintOperationClass, done),
765                   NULL, NULL,
766                   g_cclosure_marshal_VOID__ENUM,
767                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_OPERATION_RESULT);
768
769   /**
770    * GtkPrintOperation::begin-print:
771    * @operation: the #GtkPrintOperation on which the signal was emitted
772    * @context: the #GtkPrintContext for the current operation
773    *
774    * Emitted after the user has finished changing print settings
775    * in the dialog, before the actual rendering starts. 
776    *
777    * A typical use for ::begin-print is to use the parameters from the
778    * #GtkPrintContext and paginate the document accordingly, and then
779    * set the number of pages with gtk_print_operation_set_n_pages().
780    *
781    * Since: 2.10
782    */
783   signals[BEGIN_PRINT] =
784     g_signal_new (I_("begin-print"),
785                   G_TYPE_FROM_CLASS (gobject_class),
786                   G_SIGNAL_RUN_LAST,
787                   G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
788                   NULL, NULL,
789                   g_cclosure_marshal_VOID__OBJECT,
790                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
791
792    /**
793    * GtkPrintOperation::paginate:
794    * @operation: the #GtkPrintOperation on which the signal was emitted
795    * @context: the #GtkPrintContext for the current operation
796    *
797    * Emitted after the #GtkPrintOperation::begin-print signal, but before 
798    * the actual rendering starts. It keeps getting emitted until a connected 
799    * signal handler returns %TRUE.
800    *
801    * The ::paginate signal is intended to be used for paginating a document
802    * in small chunks, to avoid blocking the user interface for a long
803    * time. The signal handler should update the number of pages using
804    * gtk_print_operation_set_n_pages(), and return %TRUE if the document
805    * has been completely paginated.
806    *
807    * If you don't need to do pagination in chunks, you can simply do
808    * it all in the ::begin-print handler, and set the number of pages
809    * from there.
810    *
811    * Return value: %TRUE if pagination is complete
812    *
813    * Since: 2.10
814    */
815   signals[PAGINATE] =
816     g_signal_new (I_("paginate"),
817                   G_TYPE_FROM_CLASS (gobject_class),
818                   G_SIGNAL_RUN_LAST,
819                   G_STRUCT_OFFSET (GtkPrintOperationClass, paginate),
820                   _gtk_boolean_handled_accumulator, NULL,
821                   _gtk_marshal_BOOLEAN__OBJECT,
822                   G_TYPE_BOOLEAN, 1, GTK_TYPE_PRINT_CONTEXT);
823
824
825   /**
826    * GtkPrintOperation::request-page-setup:
827    * @operation: the #GtkPrintOperation on which the signal was emitted
828    * @context: the #GtkPrintContext for the current operation
829    * @page_nr: the number of the currently printed page (0-based)
830    * @setup: the #GtkPageSetup 
831    * 
832    * Emitted once for every page that is printed, to give
833    * the application a chance to modify the page setup. Any changes 
834    * done to @setup will be in force only for printing this page.
835    *
836    * Since: 2.10
837    */
838   signals[REQUEST_PAGE_SETUP] =
839     g_signal_new (I_("request-page-setup"),
840                   G_TYPE_FROM_CLASS (gobject_class),
841                   G_SIGNAL_RUN_LAST,
842                   G_STRUCT_OFFSET (GtkPrintOperationClass, request_page_setup),
843                   NULL, NULL,
844                   _gtk_marshal_VOID__OBJECT_INT_OBJECT,
845                   G_TYPE_NONE, 3,
846                   GTK_TYPE_PRINT_CONTEXT,
847                   G_TYPE_INT,
848                   GTK_TYPE_PAGE_SETUP);
849
850   /**
851    * GtkPrintOperation::draw-page:
852    * @operation: the #GtkPrintOperation on which the signal was emitted
853    * @context: the #GtkPrintContext for the current operation
854    * @page_nr: the number of the currently printed page (0-based)
855    *
856    * Emitted for every page that is printed. The signal handler
857    * must render the @page_nr's page onto the cairo context obtained
858    * from @context using gtk_print_context_get_cairo_context().
859    * |[
860    * static void
861    * draw_page (GtkPrintOperation *operation,
862    *            GtkPrintContext   *context,
863    *            gint               page_nr,
864    *            gpointer           user_data)
865    * {
866    *   cairo_t *cr;
867    *   PangoLayout *layout;
868    *   gdouble width, text_height;
869    *   gint layout_height;
870    *   PangoFontDescription *desc;
871    *   
872    *   cr = gtk_print_context_get_cairo_context (context);
873    *   width = gtk_print_context_get_width (context);
874    *   
875    *   cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT);
876    *   
877    *   cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
878    *   cairo_fill (cr);
879    *   
880    *   layout = gtk_print_context_create_pango_layout (context);
881    *   
882    *   desc = pango_font_description_from_string ("sans 14");
883    *   pango_layout_set_font_description (layout, desc);
884    *   pango_font_description_free (desc);
885    *   
886    *   pango_layout_set_text (layout, "some text", -1);
887    *   pango_layout_set_width (layout, width * PANGO_SCALE);
888    *   pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
889    *                          
890    *   pango_layout_get_size (layout, NULL, &layout_height);
891    *   text_height = (gdouble)layout_height / PANGO_SCALE;
892    *   
893    *   cairo_move_to (cr, width / 2,  (HEADER_HEIGHT - text_height) / 2);
894    *   pango_cairo_show_layout (cr, layout);
895    *   
896    *   g_object_unref (layout);
897    * }
898    * ]|
899    *
900    * Use gtk_print_operation_set_use_full_page() and 
901    * gtk_print_operation_set_unit() before starting the print operation
902    * to set up the transformation of the cairo context according to your
903    * needs.
904    * 
905    * Since: 2.10
906    */
907   signals[DRAW_PAGE] =
908     g_signal_new (I_("draw-page"),
909                   G_TYPE_FROM_CLASS (gobject_class),
910                   G_SIGNAL_RUN_LAST,
911                   G_STRUCT_OFFSET (GtkPrintOperationClass, draw_page),
912                   NULL, NULL,
913                   _gtk_marshal_VOID__OBJECT_INT,
914                   G_TYPE_NONE, 2,
915                   GTK_TYPE_PRINT_CONTEXT,
916                   G_TYPE_INT);
917
918   /**
919    * GtkPrintOperation::end-print:
920    * @operation: the #GtkPrintOperation on which the signal was emitted
921    * @context: the #GtkPrintContext for the current operation
922    *
923    * Emitted after all pages have been rendered. 
924    * A handler for this signal can clean up any resources that have
925    * been allocated in the #GtkPrintOperation::begin-print handler.
926    * 
927    * Since: 2.10
928    */
929   signals[END_PRINT] =
930     g_signal_new (I_("end-print"),
931                   G_TYPE_FROM_CLASS (gobject_class),
932                   G_SIGNAL_RUN_LAST,
933                   G_STRUCT_OFFSET (GtkPrintOperationClass, end_print),
934                   NULL, NULL,
935                   g_cclosure_marshal_VOID__OBJECT,
936                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
937
938   /**
939    * GtkPrintOperation::status-changed:
940    * @operation: the #GtkPrintOperation on which the signal was emitted
941    *
942    * Emitted at between the various phases of the print operation.
943    * See #GtkPrintStatus for the phases that are being discriminated.
944    * Use gtk_print_operation_get_status() to find out the current
945    * status.
946    *
947    * Since: 2.10
948    */
949   signals[STATUS_CHANGED] =
950     g_signal_new (I_("status-changed"),
951                   G_TYPE_FROM_CLASS (class),
952                   G_SIGNAL_RUN_LAST,
953                   G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
954                   NULL, NULL,
955                   g_cclosure_marshal_VOID__VOID,
956                   G_TYPE_NONE, 0);
957
958
959   /**
960    * GtkPrintOperation::create-custom-widget:
961    * @operation: the #GtkPrintOperation on which the signal was emitted
962    *
963    * Emitted when displaying the print dialog. If you return a
964    * widget in a handler for this signal it will be added to a custom
965    * tab in the print dialog. You typically return a container widget
966    * with multiple widgets in it.
967    *
968    * The print dialog owns the returned widget, and its lifetime is not 
969    * controlled by the application. However, the widget is guaranteed 
970    * to stay around until the #GtkPrintOperation::custom-widget-apply 
971    * signal is emitted on the operation. Then you can read out any 
972    * information you need from the widgets.
973    *
974    * Returns: (transfer none): A custom widget that gets embedded in
975    *          the print dialog, or %NULL
976    *
977    * Since: 2.10
978    */
979   signals[CREATE_CUSTOM_WIDGET] =
980     g_signal_new (I_("create-custom-widget"),
981                   G_TYPE_FROM_CLASS (class),
982                   G_SIGNAL_RUN_LAST,
983                   G_STRUCT_OFFSET (GtkPrintOperationClass, create_custom_widget),
984                   custom_widget_accumulator, NULL,
985                   _gtk_marshal_OBJECT__VOID,
986                   G_TYPE_OBJECT, 0);
987
988   /**
989    * GtkPrintOperation::update-custom-widget:
990    * @operation: the #GtkPrintOperation on which the signal was emitted
991    * @widget: the custom widget added in create-custom-widget
992    * @setup: actual page setup
993    * @settings: actual print settings
994    *
995    * Emitted after change of selected printer. The actual page setup and
996    * print settings are passed to the custom widget, which can actualize
997    * itself according to this change.
998    *
999    * Since: 2.18
1000    */
1001   signals[UPDATE_CUSTOM_WIDGET] =
1002     g_signal_new (I_("update-custom-widget"),
1003                   G_TYPE_FROM_CLASS (class),
1004                   G_SIGNAL_RUN_LAST,
1005                   G_STRUCT_OFFSET (GtkPrintOperationClass, update_custom_widget),
1006                   NULL, NULL,
1007                   _gtk_marshal_VOID__OBJECT_OBJECT_OBJECT,
1008                   G_TYPE_NONE, 3, GTK_TYPE_WIDGET, GTK_TYPE_PAGE_SETUP, GTK_TYPE_PRINT_SETTINGS);
1009
1010   /**
1011    * GtkPrintOperation::custom-widget-apply:
1012    * @operation: the #GtkPrintOperation on which the signal was emitted
1013    * @widget: the custom widget added in create-custom-widget
1014    *
1015    * Emitted right before #GtkPrintOperation::begin-print if you added
1016    * a custom widget in the #GtkPrintOperation::create-custom-widget handler. 
1017    * When you get this signal you should read the information from the 
1018    * custom widgets, as the widgets are not guaraneed to be around at a 
1019    * later time.
1020    *
1021    * Since: 2.10
1022    */
1023   signals[CUSTOM_WIDGET_APPLY] =
1024     g_signal_new (I_("custom-widget-apply"),
1025                   G_TYPE_FROM_CLASS (class),
1026                   G_SIGNAL_RUN_LAST,
1027                   G_STRUCT_OFFSET (GtkPrintOperationClass, custom_widget_apply),
1028                   NULL, NULL,
1029                   g_cclosure_marshal_VOID__OBJECT,
1030                   G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
1031
1032    /**
1033    * GtkPrintOperation::preview:
1034    * @operation: the #GtkPrintOperation on which the signal was emitted
1035    * @preview: the #GtkPrintOperationPreview for the current operation
1036    * @context: the #GtkPrintContext that will be used
1037    * @parent: (allow-none): the #GtkWindow to use as window parent, or %NULL
1038    *
1039    * Gets emitted when a preview is requested from the native dialog.
1040    *
1041    * The default handler for this signal uses an external viewer 
1042    * application to preview.
1043    *
1044    * To implement a custom print preview, an application must return
1045    * %TRUE from its handler for this signal. In order to use the
1046    * provided @context for the preview implementation, it must be
1047    * given a suitable cairo context with gtk_print_context_set_cairo_context().
1048    * 
1049    * The custom preview implementation can use 
1050    * gtk_print_operation_preview_is_selected() and 
1051    * gtk_print_operation_preview_render_page() to find pages which
1052    * are selected for print and render them. The preview must be
1053    * finished by calling gtk_print_operation_preview_end_preview()
1054    * (typically in response to the user clicking a close button).
1055    *
1056    * Returns: %TRUE if the listener wants to take over control of the preview
1057    * 
1058    * Since: 2.10
1059    */
1060   signals[PREVIEW] =
1061     g_signal_new (I_("preview"),
1062                   G_TYPE_FROM_CLASS (gobject_class),
1063                   G_SIGNAL_RUN_LAST,
1064                   G_STRUCT_OFFSET (GtkPrintOperationClass, preview),
1065                   _gtk_boolean_handled_accumulator, NULL,
1066                   _gtk_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT,
1067                   G_TYPE_BOOLEAN, 3,
1068                   GTK_TYPE_PRINT_OPERATION_PREVIEW,
1069                   GTK_TYPE_PRINT_CONTEXT,
1070                   GTK_TYPE_WINDOW);
1071
1072   
1073   /**
1074    * GtkPrintOperation:default-page-setup:
1075    *
1076    * The #GtkPageSetup used by default.
1077    * 
1078    * This page setup will be used by gtk_print_operation_run(),
1079    * but it can be overridden on a per-page basis by connecting
1080    * to the #GtkPrintOperation::request-page-setup signal.
1081    *
1082    * Since: 2.10
1083    */
1084   g_object_class_install_property (gobject_class,
1085                                    PROP_DEFAULT_PAGE_SETUP,
1086                                    g_param_spec_object ("default-page-setup",
1087                                                         P_("Default Page Setup"),
1088                                                         P_("The GtkPageSetup used by default"),
1089                                                         GTK_TYPE_PAGE_SETUP,
1090                                                         GTK_PARAM_READWRITE));
1091
1092   /**
1093    * GtkPrintOperation:print-settings:
1094    *
1095    * The #GtkPrintSettings used for initializing the dialog.
1096    *
1097    * Setting this property is typically used to re-establish 
1098    * print settings from a previous print operation, see 
1099    * gtk_print_operation_run().
1100    *
1101    * Since: 2.10
1102    */
1103   g_object_class_install_property (gobject_class,
1104                                    PROP_PRINT_SETTINGS,
1105                                    g_param_spec_object ("print-settings",
1106                                                         P_("Print Settings"),
1107                                                         P_("The GtkPrintSettings used for initializing the dialog"),
1108                                                         GTK_TYPE_PRINT_SETTINGS,
1109                                                         GTK_PARAM_READWRITE));
1110   
1111   /**
1112    * GtkPrintOperation:job-name:
1113    *
1114    * A string used to identify the job (e.g. in monitoring 
1115    * applications like eggcups). 
1116    * 
1117    * If you don't set a job name, GTK+ picks a default one 
1118    * by numbering successive print jobs.
1119    *
1120    * Since: 2.10
1121    */
1122   g_object_class_install_property (gobject_class,
1123                                    PROP_JOB_NAME,
1124                                    g_param_spec_string ("job-name",
1125                                                         P_("Job Name"),
1126                                                         P_("A string used for identifying the print job."),
1127                                                         "",
1128                                                         GTK_PARAM_READWRITE));
1129
1130   /**
1131    * GtkPrintOperation:n-pages:
1132    *
1133    * The number of pages in the document. 
1134    *
1135    * This <emphasis>must</emphasis> be set to a positive number
1136    * before the rendering starts. It may be set in a 
1137    * #GtkPrintOperation::begin-print signal hander.
1138    *
1139    * Note that the page numbers passed to the 
1140    * #GtkPrintOperation::request-page-setup and 
1141    * #GtkPrintOperation::draw-page signals are 0-based, i.e. if 
1142    * the user chooses to print all pages, the last ::draw-page signal 
1143    * will be for page @n_pages - 1.
1144    *
1145    * Since: 2.10
1146    */
1147   g_object_class_install_property (gobject_class,
1148                                    PROP_N_PAGES,
1149                                    g_param_spec_int ("n-pages",
1150                                                      P_("Number of Pages"),
1151                                                      P_("The number of pages in the document."),
1152                                                      -1,
1153                                                      G_MAXINT,
1154                                                      -1,
1155                                                      GTK_PARAM_READWRITE));
1156
1157   /**
1158    * GtkPrintOperation:current-page:
1159    *
1160    * The current page in the document.
1161    *
1162    * If this is set before gtk_print_operation_run(), 
1163    * the user will be able to select to print only the current page.
1164    *
1165    * Note that this only makes sense for pre-paginated documents.
1166    *
1167    * Since: 2.10
1168    */
1169   g_object_class_install_property (gobject_class,
1170                                    PROP_CURRENT_PAGE,
1171                                    g_param_spec_int ("current-page",
1172                                                      P_("Current Page"),
1173                                                      P_("The current page in the document"),
1174                                                      -1,
1175                                                      G_MAXINT,
1176                                                      -1,
1177                                                      GTK_PARAM_READWRITE));
1178   
1179   /**
1180    * GtkPrintOperation:use-full-page:
1181    *
1182    * If %TRUE, the transformation for the cairo context obtained 
1183    * from #GtkPrintContext puts the origin at the top left corner 
1184    * of the page (which may not be the top left corner of the sheet, 
1185    * depending on page orientation and the number of pages per sheet). 
1186    * Otherwise, the origin is at the top left corner of the imageable 
1187    * area (i.e. inside the margins).
1188    * 
1189    * Since: 2.10
1190    */
1191   g_object_class_install_property (gobject_class,
1192                                    PROP_USE_FULL_PAGE,
1193                                    g_param_spec_boolean ("use-full-page",
1194                                                          P_("Use full page"),
1195                                                          P_("TRUE if the origin of the context should be at the corner of the page and not the corner of the imageable area"),
1196                                                          FALSE,
1197                                                          GTK_PARAM_READWRITE));
1198   
1199
1200   /**
1201    * GtkPrintOperation:track-print-status:
1202    *
1203    * If %TRUE, the print operation will try to continue report on 
1204    * the status of the print job in the printer queues and printer. 
1205    * This can allow your application to show things like "out of paper" 
1206    * issues, and when the print job actually reaches the printer. 
1207    * However, this is often implemented using polling, and should 
1208    * not be enabled unless needed.
1209    * 
1210    * Since: 2.10
1211    */
1212   g_object_class_install_property (gobject_class,
1213                                    PROP_TRACK_PRINT_STATUS,
1214                                    g_param_spec_boolean ("track-print-status",
1215                                                          P_("Track Print Status"),
1216                                                          P_("TRUE if the print operation will continue to report on the print job status after the print data has been sent to the printer or print server."),
1217                                                          FALSE,
1218                                                          GTK_PARAM_READWRITE));
1219   
1220
1221   /**
1222    * GtkPrintOperation:unit:
1223    *
1224    * The transformation for the cairo context obtained from
1225    * #GtkPrintContext is set up in such a way that distances 
1226    * are measured in units of @unit.
1227    *
1228    * Since: 2.10
1229    */
1230   g_object_class_install_property (gobject_class,
1231                                    PROP_UNIT,
1232                                    g_param_spec_enum ("unit",
1233                                                       P_("Unit"),
1234                                                       P_("The unit in which distances can be measured in the context"),
1235                                                       GTK_TYPE_UNIT,
1236                                                       GTK_UNIT_NONE,
1237                                                       GTK_PARAM_READWRITE));
1238   
1239   
1240   /**
1241    * GtkPrintOperation:show-progress:
1242    *
1243    * Determines whether to show a progress dialog during the 
1244    * print operation.
1245    *
1246    * Since: 2.10
1247    */
1248   g_object_class_install_property (gobject_class,
1249                                    PROP_SHOW_PROGRESS,
1250                                    g_param_spec_boolean ("show-progress",
1251                                                          P_("Show Dialog"),
1252                                                          P_("TRUE if a progress dialog is shown while printing."),
1253                                                          FALSE,
1254                                                          GTK_PARAM_READWRITE));
1255
1256   /**
1257    * GtkPrintOperation:allow-async:
1258    *
1259    * Determines whether the print operation may run asynchronously or not.
1260    *
1261    * Some systems don't support asynchronous printing, but those that do
1262    * will return %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS as the status, and
1263    * emit the #GtkPrintOperation::done signal when the operation is actually 
1264    * done.
1265    *
1266    * The Windows port does not support asynchronous operation at all (this 
1267    * is unlikely to change). On other platforms, all actions except for 
1268    * %GTK_PRINT_OPERATION_ACTION_EXPORT support asynchronous operation.
1269    *
1270    * Since: 2.10
1271    */
1272   g_object_class_install_property (gobject_class,
1273                                    PROP_ALLOW_ASYNC,
1274                                    g_param_spec_boolean ("allow-async",
1275                                                          P_("Allow Async"),
1276                                                          P_("TRUE if print process may run asynchronous."),
1277                                                          FALSE,
1278                                                          GTK_PARAM_READWRITE));
1279   
1280   /**
1281    * GtkPrintOperation:export-filename:
1282    *
1283    * The name of a file to generate instead of showing the print dialog. 
1284    * Currently, PDF is the only supported format.
1285    *
1286    * The intended use of this property is for implementing 
1287    * "Export to PDF" actions.
1288    *
1289    * "Print to PDF" support is independent of this and is done
1290    * by letting the user pick the "Print to PDF" item from the 
1291    * list of printers in the print dialog.
1292    *
1293    * Since: 2.10
1294    */
1295   g_object_class_install_property (gobject_class,
1296                                    PROP_EXPORT_FILENAME,
1297                                    g_param_spec_string ("export-filename",
1298                                                         P_("Export filename"),
1299                                                         P_("Export filename"),
1300                                                         NULL,
1301                                                         GTK_PARAM_READWRITE));
1302   
1303   /**
1304    * GtkPrintOperation:status:
1305    *
1306    * The status of the print operation.
1307    * 
1308    * Since: 2.10
1309    */
1310   g_object_class_install_property (gobject_class,
1311                                    PROP_STATUS,
1312                                    g_param_spec_enum ("status",
1313                                                       P_("Status"),
1314                                                       P_("The status of the print operation"),
1315                                                       GTK_TYPE_PRINT_STATUS,
1316                                                       GTK_PRINT_STATUS_INITIAL,
1317                                                       GTK_PARAM_READABLE));
1318   
1319   /**
1320    * GtkPrintOperation:status-string:
1321    *
1322    * A string representation of the status of the print operation. 
1323    * The string is translated and suitable for displaying the print 
1324    * status e.g. in a #GtkStatusbar.
1325    *
1326    * See the #GtkPrintOperation:status property for a status value that 
1327    * is suitable for programmatic use. 
1328    *
1329    * Since: 2.10
1330    */
1331   g_object_class_install_property (gobject_class,
1332                                    PROP_STATUS_STRING,
1333                                    g_param_spec_string ("status-string",
1334                                                         P_("Status String"),
1335                                                         P_("A human-readable description of the status"),
1336                                                         "",
1337                                                         GTK_PARAM_READABLE));
1338   
1339
1340   /**
1341    * GtkPrintOperation:custom-tab-label:
1342    *
1343    * Used as the label of the tab containing custom widgets.
1344    * Note that this property may be ignored on some platforms.
1345    * 
1346    * If this is %NULL, GTK+ uses a default label.
1347    *
1348    * Since: 2.10
1349    */
1350   g_object_class_install_property (gobject_class,
1351                                    PROP_CUSTOM_TAB_LABEL,
1352                                    g_param_spec_string ("custom-tab-label",
1353                                                         P_("Custom tab label"),
1354                                                         P_("Label for the tab containing custom widgets."),
1355                                                         NULL,
1356                                                         GTK_PARAM_READWRITE));
1357
1358   /**
1359    * GtkPrintOperation:support-selection:
1360    *
1361    * If %TRUE, the print operation will support print of selection.
1362    * This allows the print dialog to show a "Selection" button.
1363    * 
1364    * Since: 2.18
1365    */
1366   g_object_class_install_property (gobject_class,
1367                                    PROP_SUPPORT_SELECTION,
1368                                    g_param_spec_boolean ("support-selection",
1369                                                          P_("Support Selection"),
1370                                                          P_("TRUE if the print operation will support print of selection."),
1371                                                          FALSE,
1372                                                          GTK_PARAM_READWRITE));
1373
1374   /**
1375    * GtkPrintOperation:has-selection:
1376    *
1377    * Determines whether there is a selection in your application.
1378    * This can allow your application to print the selection.
1379    * This is typically used to make a "Selection" button sensitive.
1380    * 
1381    * Since: 2.18
1382    */
1383   g_object_class_install_property (gobject_class,
1384                                    PROP_HAS_SELECTION,
1385                                    g_param_spec_boolean ("has-selection",
1386                                                          P_("Has Selection"),
1387                                                          P_("TRUE if a selection exists."),
1388                                                          FALSE,
1389                                                          GTK_PARAM_READWRITE));
1390
1391
1392   /**
1393    * GtkPrintOperation:embed-page-setup:
1394    *
1395    * If %TRUE, page size combo box and orientation combo box are embedded into page setup page.
1396    * 
1397    * Since: 2.18
1398    */
1399   g_object_class_install_property (gobject_class,
1400                                    PROP_EMBED_PAGE_SETUP,
1401                                    g_param_spec_boolean ("embed-page-setup",
1402                                                          P_("Embed Page Setup"),
1403                                                          P_("TRUE if page setup combos are embedded in GtkPrintUnixDialog"),
1404                                                          FALSE,
1405                                                          GTK_PARAM_READWRITE));
1406   /**
1407    * GtkPrintOperation:n-pages-to-print:
1408    *
1409    * The number of pages that will be printed.
1410    *
1411    * Note that this value is set during print preparation phase
1412    * (%GTK_PRINT_STATUS_PREPARING), so this value should never be
1413    * get before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA).
1414    * You can connect to the #GtkPrintOperation::status-changed signal
1415    * and call gtk_print_operation_get_n_pages_to_print() when
1416    * print status is %GTK_PRINT_STATUS_GENERATING_DATA.
1417    * This is typically used to track the progress of print operation.
1418    *
1419    * Since: 2.18
1420    */
1421   g_object_class_install_property (gobject_class,
1422                                    PROP_N_PAGES_TO_PRINT,
1423                                    g_param_spec_int ("n-pages-to-print",
1424                                                      P_("Number of Pages To Print"),
1425                                                      P_("The number of pages that will be printed."),
1426                                                      -1,
1427                                                      G_MAXINT,
1428                                                      -1,
1429                                                      GTK_PARAM_READABLE));
1430 }
1431
1432 /**
1433  * gtk_print_operation_new:
1434  *
1435  * Creates a new #GtkPrintOperation. 
1436  *
1437  * Returns: a new #GtkPrintOperation
1438  *
1439  * Since: 2.10
1440  */
1441 GtkPrintOperation *
1442 gtk_print_operation_new (void)
1443 {
1444   GtkPrintOperation *print_operation;
1445
1446   print_operation = g_object_new (GTK_TYPE_PRINT_OPERATION, NULL);
1447   
1448   return print_operation;
1449 }
1450
1451 /**
1452  * gtk_print_operation_set_default_page_setup:
1453  * @op: a #GtkPrintOperation
1454  * @default_page_setup: (allow-none): a #GtkPageSetup, or %NULL
1455  *
1456  * Makes @default_page_setup the default page setup for @op.
1457  *
1458  * This page setup will be used by gtk_print_operation_run(),
1459  * but it can be overridden on a per-page basis by connecting
1460  * to the #GtkPrintOperation::request-page-setup signal.
1461  *
1462  * Since: 2.10
1463  **/
1464 void
1465 gtk_print_operation_set_default_page_setup (GtkPrintOperation *op,
1466                                             GtkPageSetup      *default_page_setup)
1467 {
1468   GtkPrintOperationPrivate *priv;
1469
1470   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1471   g_return_if_fail (default_page_setup == NULL || 
1472                     GTK_IS_PAGE_SETUP (default_page_setup));
1473
1474   priv = op->priv;
1475
1476   if (default_page_setup != priv->default_page_setup)
1477     {
1478       if (default_page_setup)
1479         g_object_ref (default_page_setup);
1480       
1481       if (priv->default_page_setup)
1482         g_object_unref (priv->default_page_setup);
1483       
1484       priv->default_page_setup = default_page_setup;
1485      
1486       g_object_notify (G_OBJECT (op), "default-page-setup");
1487     }
1488 }
1489
1490 /**
1491  * gtk_print_operation_get_default_page_setup:
1492  * @op: a #GtkPrintOperation
1493  *
1494  * Returns the default page setup, see
1495  * gtk_print_operation_set_default_page_setup().
1496  *
1497  * Returns: (transfer none): the default page setup
1498  *
1499  * Since: 2.10
1500  */
1501 GtkPageSetup *
1502 gtk_print_operation_get_default_page_setup (GtkPrintOperation *op)
1503 {
1504   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1505
1506   return op->priv->default_page_setup;
1507 }
1508
1509
1510 /**
1511  * gtk_print_operation_set_print_settings:
1512  * @op: a #GtkPrintOperation
1513  * @print_settings: (allow-none): #GtkPrintSettings
1514  *
1515  * Sets the print settings for @op. This is typically used to
1516  * re-establish print settings from a previous print operation,
1517  * see gtk_print_operation_run().
1518  *
1519  * Since: 2.10
1520  **/
1521 void
1522 gtk_print_operation_set_print_settings (GtkPrintOperation *op,
1523                                         GtkPrintSettings  *print_settings)
1524 {
1525   GtkPrintOperationPrivate *priv;
1526
1527   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1528   g_return_if_fail (print_settings == NULL || 
1529                     GTK_IS_PRINT_SETTINGS (print_settings));
1530
1531   priv = op->priv;
1532
1533   if (print_settings != priv->print_settings)
1534     {
1535       if (print_settings)
1536         g_object_ref (print_settings);
1537
1538       if (priv->print_settings)
1539         g_object_unref (priv->print_settings);
1540   
1541       priv->print_settings = print_settings;
1542
1543       g_object_notify (G_OBJECT (op), "print-settings");
1544     }
1545 }
1546
1547 /**
1548  * gtk_print_operation_get_print_settings:
1549  * @op: a #GtkPrintOperation
1550  *
1551  * Returns the current print settings.
1552  *
1553  * Note that the return value is %NULL until either
1554  * gtk_print_operation_set_print_settings() or
1555  * gtk_print_operation_run() have been called.
1556  *
1557  * Return value: (transfer none): the current print settings of @op.
1558  *
1559  * Since: 2.10
1560  **/
1561 GtkPrintSettings *
1562 gtk_print_operation_get_print_settings (GtkPrintOperation *op)
1563 {
1564   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1565
1566   return op->priv->print_settings;
1567 }
1568
1569 /**
1570  * gtk_print_operation_set_job_name:
1571  * @op: a #GtkPrintOperation
1572  * @job_name: a string that identifies the print job
1573  * 
1574  * Sets the name of the print job. The name is used to identify 
1575  * the job (e.g. in monitoring applications like eggcups). 
1576  * 
1577  * If you don't set a job name, GTK+ picks a default one by 
1578  * numbering successive print jobs.
1579  *
1580  * Since: 2.10
1581  **/
1582 void
1583 gtk_print_operation_set_job_name (GtkPrintOperation *op,
1584                                   const gchar       *job_name)
1585 {
1586   GtkPrintOperationPrivate *priv;
1587
1588   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1589   g_return_if_fail (job_name != NULL);
1590
1591   priv = op->priv;
1592
1593   g_free (priv->job_name);
1594   priv->job_name = g_strdup (job_name);
1595
1596   g_object_notify (G_OBJECT (op), "job-name");
1597 }
1598
1599 /**
1600  * gtk_print_operation_set_n_pages:
1601  * @op: a #GtkPrintOperation
1602  * @n_pages: the number of pages
1603  * 
1604  * Sets the number of pages in the document. 
1605  *
1606  * This <emphasis>must</emphasis> be set to a positive number
1607  * before the rendering starts. It may be set in a 
1608  * #GtkPrintOperation::begin-print signal hander.
1609  *
1610  * Note that the page numbers passed to the 
1611  * #GtkPrintOperation::request-page-setup 
1612  * and #GtkPrintOperation::draw-page signals are 0-based, i.e. if 
1613  * the user chooses to print all pages, the last ::draw-page signal 
1614  * will be for page @n_pages - 1.
1615  *
1616  * Since: 2.10
1617  **/
1618 void
1619 gtk_print_operation_set_n_pages (GtkPrintOperation *op,
1620                                  gint               n_pages)
1621 {
1622   GtkPrintOperationPrivate *priv;
1623
1624   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1625   g_return_if_fail (n_pages > 0);
1626
1627   priv = op->priv;
1628   g_return_if_fail (priv->current_page == -1 || 
1629                     priv->current_page < n_pages);
1630
1631   if (priv->nr_of_pages != n_pages)
1632     {
1633       priv->nr_of_pages = n_pages;
1634
1635       g_object_notify (G_OBJECT (op), "n-pages");
1636     }
1637 }
1638
1639 /**
1640  * gtk_print_operation_set_current_page:
1641  * @op: a #GtkPrintOperation
1642  * @current_page: the current page, 0-based
1643  *
1644  * Sets the current page.
1645  *
1646  * If this is called before gtk_print_operation_run(), 
1647  * the user will be able to select to print only the current page.
1648  *
1649  * Note that this only makes sense for pre-paginated documents.
1650  * 
1651  * Since: 2.10
1652  **/
1653 void
1654 gtk_print_operation_set_current_page (GtkPrintOperation *op,
1655                                       gint               current_page)
1656 {
1657   GtkPrintOperationPrivate *priv;
1658
1659   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1660   g_return_if_fail (current_page >= 0);
1661
1662   priv = op->priv;
1663   g_return_if_fail (priv->nr_of_pages == -1 || 
1664                     current_page < priv->nr_of_pages);
1665
1666   if (priv->current_page != current_page)
1667     {
1668       priv->current_page = current_page;
1669
1670       g_object_notify (G_OBJECT (op), "current-page");
1671     }
1672 }
1673
1674 /**
1675  * gtk_print_operation_set_use_full_page:
1676  * @op: a #GtkPrintOperation
1677  * @full_page: %TRUE to set up the #GtkPrintContext for the full page
1678  * 
1679  * If @full_page is %TRUE, the transformation for the cairo context 
1680  * obtained from #GtkPrintContext puts the origin at the top left 
1681  * corner of the page (which may not be the top left corner of the 
1682  * sheet, depending on page orientation and the number of pages per 
1683  * sheet). Otherwise, the origin is at the top left corner of the
1684  * imageable area (i.e. inside the margins).
1685  * 
1686  * Since: 2.10 
1687  */
1688 void
1689 gtk_print_operation_set_use_full_page (GtkPrintOperation *op,
1690                                        gboolean           full_page)
1691 {
1692   GtkPrintOperationPrivate *priv;
1693
1694   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1695
1696   full_page = full_page != FALSE;
1697  
1698   priv = op->priv;
1699         
1700   if (priv->use_full_page != full_page)
1701     {
1702       priv->use_full_page = full_page;
1703    
1704       g_object_notify (G_OBJECT (op), "use-full-page");
1705     }
1706 }
1707
1708 /**
1709  * gtk_print_operation_set_unit:
1710  * @op: a #GtkPrintOperation
1711  * @unit: the unit to use
1712  * 
1713  * Sets up the transformation for the cairo context obtained from
1714  * #GtkPrintContext in such a way that distances are measured in 
1715  * units of @unit.
1716  *
1717  * Since: 2.10
1718  */
1719 void
1720 gtk_print_operation_set_unit (GtkPrintOperation *op,
1721                               GtkUnit            unit)
1722 {
1723   GtkPrintOperationPrivate *priv;
1724
1725   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1726
1727   priv = op->priv;
1728
1729   if (priv->unit != unit)
1730     {
1731       priv->unit = unit;
1732
1733       g_object_notify (G_OBJECT (op), "unit");
1734     }
1735 }
1736
1737 /**
1738  * gtk_print_operation_set_track_print_status:
1739  * @op: a #GtkPrintOperation
1740  * @track_status: %TRUE to track status after printing
1741  * 
1742  * If track_status is %TRUE, the print operation will try to continue report
1743  * on the status of the print job in the printer queues and printer. This
1744  * can allow your application to show things like "out of paper" issues,
1745  * and when the print job actually reaches the printer.
1746  * 
1747  * This function is often implemented using some form of polling, so it should
1748  * not be enabled unless needed.
1749  *
1750  * Since: 2.10
1751  */
1752 void
1753 gtk_print_operation_set_track_print_status (GtkPrintOperation  *op,
1754                                             gboolean            track_status)
1755 {
1756   GtkPrintOperationPrivate *priv;
1757
1758   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1759
1760   priv = op->priv;
1761
1762   if (priv->track_print_status != track_status)
1763     {
1764       priv->track_print_status = track_status;
1765
1766       g_object_notify (G_OBJECT (op), "track-print-status");
1767     }
1768 }
1769
1770 void
1771 _gtk_print_operation_set_status (GtkPrintOperation *op,
1772                                  GtkPrintStatus     status,
1773                                  const gchar       *string)
1774 {
1775   GtkPrintOperationPrivate *priv = op->priv;
1776   static const gchar *status_strs[] = {
1777     NC_("print operation status", "Initial state"),
1778     NC_("print operation status", "Preparing to print"),
1779     NC_("print operation status", "Generating data"),
1780     NC_("print operation status", "Sending data"),
1781     NC_("print operation status", "Waiting"),
1782     NC_("print operation status", "Blocking on issue"),
1783     NC_("print operation status", "Printing"),
1784     NC_("print operation status", "Finished"),
1785     NC_("print operation status", "Finished with error")
1786   };
1787
1788   if (status < 0 || status > GTK_PRINT_STATUS_FINISHED_ABORTED)
1789     status = GTK_PRINT_STATUS_FINISHED_ABORTED;
1790
1791   if (string == NULL)
1792     string = g_dpgettext2 (GETTEXT_PACKAGE, "print operation status", status_strs[status]);
1793   
1794   if (priv->status == status &&
1795       strcmp (string, priv->status_string) == 0)
1796     return;
1797   
1798   g_free (priv->status_string);
1799   priv->status_string = g_strdup (string);
1800   priv->status = status;
1801
1802   g_object_notify (G_OBJECT (op), "status");
1803   g_object_notify (G_OBJECT (op), "status-string");
1804
1805   g_signal_emit (op, signals[STATUS_CHANGED], 0);
1806 }
1807
1808
1809 /**
1810  * gtk_print_operation_get_status:
1811  * @op: a #GtkPrintOperation
1812  * 
1813  * Returns the status of the print operation. 
1814  * Also see gtk_print_operation_get_status_string().
1815  * 
1816  * Return value: the status of the print operation
1817  *
1818  * Since: 2.10
1819  **/
1820 GtkPrintStatus
1821 gtk_print_operation_get_status (GtkPrintOperation *op)
1822 {
1823   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
1824                         GTK_PRINT_STATUS_FINISHED_ABORTED);
1825
1826   return op->priv->status;
1827 }
1828
1829 /**
1830  * gtk_print_operation_get_status_string:
1831  * @op: a #GtkPrintOperation
1832  * 
1833  * Returns a string representation of the status of the 
1834  * print operation. The string is translated and suitable
1835  * for displaying the print status e.g. in a #GtkStatusbar.
1836  *
1837  * Use gtk_print_operation_get_status() to obtain a status
1838  * value that is suitable for programmatic use. 
1839  * 
1840  * Return value: a string representation of the status
1841  *    of the print operation
1842  *
1843  * Since: 2.10
1844  **/
1845 const gchar *
1846 gtk_print_operation_get_status_string (GtkPrintOperation *op)
1847 {
1848   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), "");
1849
1850   return op->priv->status_string;
1851 }
1852
1853 /**
1854  * gtk_print_operation_is_finished:
1855  * @op: a #GtkPrintOperation
1856  * 
1857  * A convenience function to find out if the print operation
1858  * is finished, either successfully (%GTK_PRINT_STATUS_FINISHED)
1859  * or unsuccessfully (%GTK_PRINT_STATUS_FINISHED_ABORTED).
1860  * 
1861  * Note: when you enable print status tracking the print operation
1862  * can be in a non-finished state even after done has been called, as
1863  * the operation status then tracks the print job status on the printer.
1864  * 
1865  * Return value: %TRUE, if the print operation is finished.
1866  *
1867  * Since: 2.10
1868  **/
1869 gboolean
1870 gtk_print_operation_is_finished (GtkPrintOperation *op)
1871 {
1872   GtkPrintOperationPrivate *priv;
1873
1874   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), TRUE);
1875
1876   priv = op->priv;
1877   return
1878     priv->status == GTK_PRINT_STATUS_FINISHED_ABORTED ||
1879     priv->status == GTK_PRINT_STATUS_FINISHED;
1880 }
1881
1882 /**
1883  * gtk_print_operation_set_show_progress:
1884  * @op: a #GtkPrintOperation
1885  * @show_progress: %TRUE to show a progress dialog
1886  * 
1887  * If @show_progress is %TRUE, the print operation will show a 
1888  * progress dialog during the print operation.
1889  * 
1890  * Since: 2.10
1891  */
1892 void
1893 gtk_print_operation_set_show_progress (GtkPrintOperation  *op,
1894                                        gboolean            show_progress)
1895 {
1896   GtkPrintOperationPrivate *priv;
1897
1898   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1899
1900   priv = op->priv;
1901
1902   show_progress = show_progress != FALSE;
1903
1904   if (priv->show_progress != show_progress)
1905     {
1906       priv->show_progress = show_progress;
1907
1908       g_object_notify (G_OBJECT (op), "show-progress");
1909     }
1910 }
1911
1912 /**
1913  * gtk_print_operation_set_allow_async:
1914  * @op: a #GtkPrintOperation
1915  * @allow_async: %TRUE to allow asynchronous operation
1916  *
1917  * Sets whether the gtk_print_operation_run() may return
1918  * before the print operation is completed. Note that
1919  * some platforms may not allow asynchronous operation.
1920  *
1921  * Since: 2.10
1922  */
1923 void
1924 gtk_print_operation_set_allow_async (GtkPrintOperation  *op,
1925                                      gboolean            allow_async)
1926 {
1927   GtkPrintOperationPrivate *priv;
1928
1929   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1930
1931   priv = op->priv;
1932
1933   allow_async = allow_async != FALSE;
1934
1935   if (priv->allow_async != allow_async)
1936     {
1937       priv->allow_async = allow_async;
1938
1939       g_object_notify (G_OBJECT (op), "allow-async");
1940     }
1941 }
1942
1943
1944 /**
1945  * gtk_print_operation_set_custom_tab_label:
1946  * @op: a #GtkPrintOperation
1947  * @label: (allow-none): the label to use, or %NULL to use the default label
1948  *
1949  * Sets the label for the tab holding custom widgets.
1950  *
1951  * Since: 2.10
1952  */
1953 void
1954 gtk_print_operation_set_custom_tab_label (GtkPrintOperation  *op,
1955                                           const gchar        *label)
1956 {
1957   GtkPrintOperationPrivate *priv;
1958
1959   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1960
1961   priv = op->priv;
1962
1963   g_free (priv->custom_tab_label);
1964   priv->custom_tab_label = g_strdup (label);
1965
1966   g_object_notify (G_OBJECT (op), "custom-tab-label");
1967 }
1968
1969
1970 /**
1971  * gtk_print_operation_set_export_filename:
1972  * @op: a #GtkPrintOperation
1973  * @filename: (type filename): the filename for the exported file
1974  * 
1975  * Sets up the #GtkPrintOperation to generate a file instead
1976  * of showing the print dialog. The indended use of this function
1977  * is for implementing "Export to PDF" actions. Currently, PDF
1978  * is the only supported format.
1979  *
1980  * "Print to PDF" support is independent of this and is done
1981  * by letting the user pick the "Print to PDF" item from the list
1982  * of printers in the print dialog.
1983  *
1984  * Since: 2.10
1985  */
1986 void
1987 gtk_print_operation_set_export_filename (GtkPrintOperation *op,
1988                                          const gchar       *filename)
1989 {
1990   GtkPrintOperationPrivate *priv;
1991
1992   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1993
1994   priv = op->priv;
1995
1996   g_free (priv->export_filename);
1997   priv->export_filename = g_strdup (filename);
1998
1999   g_object_notify (G_OBJECT (op), "export-filename");
2000 }
2001
2002 /* Creates the initial page setup used for printing unless the
2003  * app overrides this on a per-page basis using request_page_setup.
2004  *
2005  * Data is taken from, in order, if existing:
2006  *
2007  * PrintSettings returned from the print dialog
2008  *  (initial dialog values are set from default_page_setup
2009  *   if unset in app specified print_settings)
2010  * default_page_setup
2011  * per-locale default setup
2012  */
2013 static GtkPageSetup *
2014 create_page_setup (GtkPrintOperation *op)
2015 {
2016   GtkPrintOperationPrivate *priv = op->priv;
2017   GtkPageSetup *page_setup;
2018   GtkPrintSettings *settings;
2019   
2020   if (priv->default_page_setup)
2021     page_setup = gtk_page_setup_copy (priv->default_page_setup);
2022   else
2023     page_setup = gtk_page_setup_new ();
2024
2025   settings = priv->print_settings;
2026   if (settings)
2027     {
2028       GtkPaperSize *paper_size;
2029       
2030       if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
2031         gtk_page_setup_set_orientation (page_setup,
2032                                         gtk_print_settings_get_orientation (settings));
2033
2034
2035       paper_size = gtk_print_settings_get_paper_size (settings);
2036       if (paper_size)
2037         {
2038           gtk_page_setup_set_paper_size (page_setup, paper_size);
2039           gtk_paper_size_free (paper_size);
2040         }
2041
2042       /* TODO: Margins? */
2043     }
2044   
2045   return page_setup;
2046 }
2047
2048 static void 
2049 pdf_start_page (GtkPrintOperation *op,
2050                 GtkPrintContext   *print_context,
2051                 GtkPageSetup      *page_setup)
2052 {
2053   GtkPaperSize *paper_size;
2054   cairo_surface_t *surface = op->priv->platform_data;
2055   gdouble w, h;
2056
2057   paper_size = gtk_page_setup_get_paper_size (page_setup);
2058
2059   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
2060   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
2061   
2062   cairo_pdf_surface_set_size (surface, w, h);
2063 }
2064
2065 static void
2066 pdf_end_page (GtkPrintOperation *op,
2067               GtkPrintContext   *print_context)
2068 {
2069   cairo_t *cr;
2070
2071   cr = gtk_print_context_get_cairo_context (print_context);
2072
2073   if ((op->priv->manual_number_up < 2) ||
2074       ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) ||
2075       (op->priv->page_position == op->priv->nr_of_pages_to_print - 1))
2076     cairo_show_page (cr);
2077 }
2078
2079 static void
2080 pdf_end_run (GtkPrintOperation *op,
2081              gboolean           wait,
2082              gboolean           cancelled)
2083 {
2084   GtkPrintOperationPrivate *priv = op->priv;
2085   cairo_surface_t *surface = priv->platform_data;
2086
2087   cairo_surface_finish (surface);
2088   cairo_surface_destroy (surface);
2089
2090   priv->platform_data = NULL;
2091   priv->free_platform_data = NULL;
2092 }
2093
2094 static GtkPrintOperationResult
2095 run_pdf (GtkPrintOperation  *op,
2096          GtkWindow          *parent,
2097          gboolean           *do_print)
2098 {
2099   GtkPrintOperationPrivate *priv = op->priv;
2100   GtkPageSetup *page_setup;
2101   cairo_surface_t *surface;
2102   cairo_t *cr;
2103   gdouble width, height;
2104   
2105   priv->print_context = _gtk_print_context_new (op);
2106   
2107   page_setup = create_page_setup (op);
2108   _gtk_print_context_set_page_setup (priv->print_context, page_setup);
2109
2110   /* This will be overwritten later by the non-default size, but
2111      we need to pass some size: */
2112   width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
2113   height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
2114   g_object_unref (page_setup);
2115   
2116   surface = cairo_pdf_surface_create (priv->export_filename,
2117                                       width, height);
2118   if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
2119     {
2120       g_set_error_literal (&priv->error,
2121                            GTK_PRINT_ERROR,
2122                            GTK_PRINT_ERROR_GENERAL,
2123                            cairo_status_to_string (cairo_surface_status (surface)));
2124       *do_print = FALSE;
2125       return GTK_PRINT_OPERATION_RESULT_ERROR;
2126     }
2127
2128   /* this would crash on a nil surface */
2129   cairo_surface_set_fallback_resolution (surface, 300, 300);
2130
2131   priv->platform_data = surface;
2132   priv->free_platform_data = (GDestroyNotify) cairo_surface_destroy;
2133
2134   cr = cairo_create (surface);
2135   gtk_print_context_set_cairo_context (op->priv->print_context,
2136                                        cr, 72, 72);
2137   cairo_destroy (cr);
2138
2139   
2140   priv->print_pages = GTK_PRINT_PAGES_ALL;
2141   priv->page_ranges = NULL;
2142   priv->num_page_ranges = 0;
2143
2144   priv->manual_num_copies = 1;
2145   priv->manual_collation = FALSE;
2146   priv->manual_reverse = FALSE;
2147   priv->manual_page_set = GTK_PAGE_SET_ALL;
2148   priv->manual_scale = 1.0;
2149   priv->manual_orientation = TRUE;
2150   priv->manual_number_up = 1;
2151   priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
2152   
2153   *do_print = TRUE;
2154   
2155   priv->start_page = pdf_start_page;
2156   priv->end_page = pdf_end_page;
2157   priv->end_run = pdf_end_run;
2158   
2159   return GTK_PRINT_OPERATION_RESULT_APPLY; 
2160 }
2161
2162
2163 static void
2164 clamp_page_ranges (PrintPagesData *data)
2165 {
2166   GtkPrintOperationPrivate *priv; 
2167   gint                      num_of_correct_ranges;
2168   gint                      i;
2169
2170   priv = data->op->priv;
2171
2172   num_of_correct_ranges = 0;
2173
2174   for (i = 0; i < data->num_ranges; i++)
2175     if ((data->ranges[i].start >= 0) &&
2176         (data->ranges[i].start < priv->nr_of_pages) &&
2177         (data->ranges[i].end >= 0) &&
2178         (data->ranges[i].end < priv->nr_of_pages))
2179       {
2180         data->ranges[num_of_correct_ranges] = data->ranges[i];
2181         num_of_correct_ranges++;
2182       }
2183     else if ((data->ranges[i].start >= 0) &&
2184              (data->ranges[i].start < priv->nr_of_pages) &&
2185              (data->ranges[i].end >= priv->nr_of_pages))
2186       {
2187         data->ranges[i].end = priv->nr_of_pages - 1;
2188         data->ranges[num_of_correct_ranges] = data->ranges[i];
2189         num_of_correct_ranges++;
2190       }
2191     else if ((data->ranges[i].end >= 0) &&
2192              (data->ranges[i].end < priv->nr_of_pages) &&
2193              (data->ranges[i].start < 0))
2194       {
2195         data->ranges[i].start = 0;
2196         data->ranges[num_of_correct_ranges] = data->ranges[i];
2197         num_of_correct_ranges++;
2198       }
2199
2200   data->num_ranges = num_of_correct_ranges;
2201 }
2202
2203 static void
2204 increment_page_sequence (PrintPagesData *data)
2205 {
2206   GtkPrintOperationPrivate *priv = data->op->priv;
2207   gint inc;
2208
2209   if (data->total == -1)
2210     {
2211       data->total = 0;
2212       return;
2213     }
2214
2215   /* check whether we reached last position */
2216   if (priv->page_position == data->last_position &&
2217       !(data->collated_copies > 1 && data->collated < (data->collated_copies - 1)))
2218     {
2219       if (data->uncollated_copies > 1 && data->uncollated < (data->uncollated_copies - 1))
2220         {
2221           priv->page_position = data->first_position;
2222           data->sheet = data->first_sheet;
2223           data->uncollated++;
2224         }
2225       else
2226         {
2227           data->done = TRUE;
2228           return;
2229         }
2230     }
2231   else
2232     {
2233       if (priv->manual_reverse)
2234         inc = -1;
2235       else
2236         inc = 1;
2237
2238       /* changing sheet */
2239       if (priv->manual_number_up < 2 ||
2240           (priv->page_position + 1) % priv->manual_number_up == 0 ||
2241           priv->page_position == data->last_position ||
2242           priv->page_position == priv->nr_of_pages_to_print - 1)
2243         {
2244           /* check whether to print the same sheet again */
2245           if (data->collated_copies > 1)
2246             {
2247               if (data->collated < (data->collated_copies - 1))
2248                 {
2249                   data->collated++;
2250                   data->total++;
2251                   priv->page_position = data->sheet * priv->manual_number_up;
2252
2253                   if (priv->page_position < 0 ||
2254                       priv->page_position >= priv->nr_of_pages_to_print ||
2255                       data->sheet < 0 ||
2256                       data->sheet >= data->num_of_sheets)
2257                     {
2258                       data->done = TRUE;
2259                       return;
2260                     }
2261                   else
2262                     data->page = data->pages[priv->page_position];
2263
2264                   return;
2265                 }
2266               else
2267                 data->collated = 0;
2268             }
2269
2270           if (priv->manual_page_set == GTK_PAGE_SET_ODD ||
2271               priv->manual_page_set == GTK_PAGE_SET_EVEN)
2272             data->sheet += 2 * inc;
2273           else
2274             data->sheet += inc;
2275
2276           priv->page_position = data->sheet * priv->manual_number_up;
2277         }
2278       else
2279         priv->page_position += 1;
2280     }
2281
2282   /* general check */
2283   if (priv->page_position < 0 ||
2284       priv->page_position >= priv->nr_of_pages_to_print ||
2285       data->sheet < 0 ||
2286       data->sheet >= data->num_of_sheets)
2287     {
2288       data->done = TRUE;
2289       return;
2290     }
2291   else
2292     data->page = data->pages[priv->page_position];
2293
2294   data->total++;
2295 }
2296
2297 static void
2298 print_pages_idle_done (gpointer user_data)
2299 {
2300   PrintPagesData *data;
2301   GtkPrintOperationPrivate *priv;
2302
2303   data = (PrintPagesData*)user_data;
2304   priv = data->op->priv;
2305
2306   priv->print_pages_idle_id = 0;
2307
2308   if (priv->show_progress_timeout_id > 0)
2309     {
2310       g_source_remove (priv->show_progress_timeout_id);
2311       priv->show_progress_timeout_id = 0;
2312     }
2313  
2314   if (data->progress)
2315     gtk_widget_destroy (data->progress);
2316
2317   if (priv->rloop && !data->is_preview) 
2318     g_main_loop_quit (priv->rloop);
2319
2320   if (!data->is_preview)
2321     {
2322       GtkPrintOperationResult result;
2323
2324       if (priv->error)
2325         result = GTK_PRINT_OPERATION_RESULT_ERROR;
2326       else if (priv->cancelled)
2327         result = GTK_PRINT_OPERATION_RESULT_CANCEL;
2328       else
2329         result = GTK_PRINT_OPERATION_RESULT_APPLY;
2330
2331       g_signal_emit (data->op, signals[DONE], 0, result);
2332     }
2333   
2334   g_object_unref (data->op);
2335   g_free (data->pages);
2336   g_free (data);
2337 }
2338
2339 static void
2340 update_progress (PrintPagesData *data)
2341 {
2342   GtkPrintOperationPrivate *priv; 
2343   gchar *text = NULL;
2344   
2345   priv = data->op->priv;
2346  
2347   if (data->progress)
2348     {
2349       if (priv->status == GTK_PRINT_STATUS_PREPARING)
2350         {
2351           if (priv->nr_of_pages_to_print > 0)
2352             text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages_to_print);
2353           else
2354             text = g_strdup (_("Preparing"));
2355         }
2356       else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA)
2357         text = g_strdup_printf (_("Printing %d"), data->total);
2358       
2359       if (text)
2360         {
2361           g_object_set (data->progress, "text", text, NULL);
2362           g_free (text);
2363         }
2364     }
2365  }
2366
2367 /**
2368  * gtk_print_operation_set_defer_drawing:
2369  * @op: a #GtkPrintOperation
2370  * 
2371  * Sets up the #GtkPrintOperation to wait for calling of
2372  * gtk_print_operation_draw_page_finish() from application. It can
2373  * be used for drawing page in another thread.
2374  *
2375  * This function must be called in the callback of "draw-page" signal.
2376  *
2377  * Since: 2.16
2378  **/
2379 void
2380 gtk_print_operation_set_defer_drawing (GtkPrintOperation *op)
2381 {
2382   GtkPrintOperationPrivate *priv = op->priv;
2383
2384   g_return_if_fail (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_DRAWING);
2385
2386   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_DEFERRED_DRAWING;
2387 }
2388
2389 /**
2390  * gtk_print_operation_set_embed_page_setup:
2391  * @op: a #GtkPrintOperation
2392  * @embed: %TRUE to embed page setup selection in the #GtkPrintUnixDialog
2393  *
2394  * Embed page size combo box and orientation combo box into page setup page.
2395  * Selected page setup is stored as default page setup in #GtkPrintOperation.
2396  *
2397  * Since: 2.18
2398  **/
2399 void
2400 gtk_print_operation_set_embed_page_setup (GtkPrintOperation  *op,
2401                                           gboolean            embed)
2402 {
2403   GtkPrintOperationPrivate *priv;
2404
2405   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
2406
2407   priv = op->priv;
2408
2409   embed = embed != FALSE;
2410   if (priv->embed_page_setup != embed)
2411     {
2412       priv->embed_page_setup = embed;
2413       g_object_notify (G_OBJECT (op), "embed-page-setup");
2414     }
2415 }
2416
2417 /**
2418  * gtk_print_operation_get_embed_page_setup:
2419  * @op: a #GtkPrintOperation
2420  *
2421  * Gets the value of #GtkPrintOperation:embed-page-setup property.
2422  * 
2423  * Returns: whether page setup selection combos are embedded
2424  *
2425  * Since: 2.18
2426  */
2427 gboolean
2428 gtk_print_operation_get_embed_page_setup (GtkPrintOperation *op)
2429 {
2430   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
2431
2432   return op->priv->embed_page_setup;
2433 }
2434
2435 /**
2436  * gtk_print_operation_draw_page_finish:
2437  * @op: a #GtkPrintOperation
2438  * 
2439  * Signalize that drawing of particular page is complete.
2440  *
2441  * It is called after completion of page drawing (e.g. drawing in another
2442  * thread).
2443  * If gtk_print_operation_set_defer_drawing() was called before, then this function
2444  * has to be called by application. In another case it is called by the library
2445  * itself.
2446  *
2447  * Since: 2.16
2448  **/
2449 void
2450 gtk_print_operation_draw_page_finish (GtkPrintOperation *op)
2451 {
2452   GtkPrintOperationPrivate *priv = op->priv;
2453   GtkPageSetup *page_setup;
2454   GtkPrintContext *print_context;
2455   cairo_t *cr;
2456   
2457   print_context = priv->print_context;
2458   page_setup = gtk_print_context_get_page_setup (print_context);
2459
2460   cr = gtk_print_context_get_cairo_context (print_context);
2461
2462   priv->end_page (op, print_context);
2463   
2464   cairo_restore (cr);
2465
2466   g_object_unref (page_setup);
2467
2468   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY;
2469 }
2470
2471 static void
2472 common_render_page (GtkPrintOperation *op,
2473                     gint               page_nr)
2474 {
2475   GtkPrintOperationPrivate *priv = op->priv;
2476   GtkPageSetup *page_setup;
2477   GtkPrintContext *print_context;
2478   cairo_t *cr;
2479
2480   print_context = priv->print_context;
2481   
2482   page_setup = create_page_setup (op);
2483   
2484   g_signal_emit (op, signals[REQUEST_PAGE_SETUP], 0, 
2485                  print_context, page_nr, page_setup);
2486   
2487   _gtk_print_context_set_page_setup (print_context, page_setup);
2488   
2489   priv->start_page (op, print_context, page_setup);
2490   
2491   cr = gtk_print_context_get_cairo_context (print_context);
2492   
2493   cairo_save (cr);
2494   if (priv->manual_scale != 1.0 && priv->manual_number_up <= 1)
2495     cairo_scale (cr,
2496                  priv->manual_scale,
2497                  priv->manual_scale);
2498   
2499   if (priv->manual_orientation)
2500     _gtk_print_context_rotate_according_to_orientation (print_context);
2501
2502   if (priv->manual_number_up > 1)
2503     {
2504       GtkPageOrientation  orientation;
2505       GtkPageSetup       *page_setup;
2506       gdouble             paper_width, paper_height;
2507       gdouble             page_width, page_height;
2508       gdouble             context_width, context_height;
2509       gdouble             bottom_margin, top_margin, left_margin, right_margin;
2510       gdouble             x_step, y_step;
2511       gdouble             x_scale, y_scale, scale;
2512       gdouble             horizontal_offset = 0.0, vertical_offset = 0.0;
2513       gint                columns, rows, x, y, tmp_length;
2514
2515       page_setup = gtk_print_context_get_page_setup (print_context);
2516       orientation = gtk_page_setup_get_orientation (page_setup);
2517
2518       top_margin = gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_POINTS);
2519       bottom_margin = gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_POINTS);
2520       left_margin = gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_POINTS);
2521       right_margin = gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_POINTS);
2522
2523       paper_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
2524       paper_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
2525
2526       context_width = gtk_print_context_get_width (print_context);
2527       context_height = gtk_print_context_get_height (print_context);
2528
2529       if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
2530           orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
2531         {
2532           page_width = paper_width - (left_margin + right_margin);
2533           page_height = paper_height - (top_margin + bottom_margin);
2534         }
2535       else
2536         {
2537           page_width = paper_width - (top_margin + bottom_margin);
2538           page_height = paper_height - (left_margin + right_margin);
2539         }
2540
2541       if (orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
2542           orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
2543         cairo_translate (cr, left_margin, top_margin);
2544       else
2545         cairo_translate (cr, top_margin, left_margin);
2546
2547       switch (priv->manual_number_up)
2548         {
2549           default:
2550             columns = 1;
2551             rows = 1;
2552             break;
2553           case 2:
2554             columns = 2;
2555             rows = 1;
2556             break;
2557           case 4:
2558             columns = 2;
2559             rows = 2;
2560             break;
2561           case 6:
2562             columns = 3;
2563             rows = 2;
2564             break;
2565           case 9:
2566             columns = 3;
2567             rows = 3;
2568             break;
2569           case 16:
2570             columns = 4;
2571             rows = 4;
2572             break;
2573         }
2574
2575       if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
2576           orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
2577         {
2578           tmp_length = columns;
2579           columns = rows;
2580           rows = tmp_length;
2581         }
2582
2583       switch (priv->manual_number_up_layout)
2584         {
2585           case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM:
2586             x = priv->page_position % columns;
2587             y = (priv->page_position / columns) % rows;
2588             break;
2589           case GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_BOTTOM_TO_TOP:
2590             x = priv->page_position % columns;
2591             y = rows - 1 - (priv->page_position / columns) % rows;
2592             break;
2593           case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_TOP_TO_BOTTOM:
2594             x = columns - 1 - priv->page_position % columns;
2595             y = (priv->page_position / columns) % rows;
2596             break;
2597           case GTK_NUMBER_UP_LAYOUT_RIGHT_TO_LEFT_BOTTOM_TO_TOP:
2598             x = columns - 1 - priv->page_position % columns;
2599             y = rows - 1 - (priv->page_position / columns) % rows;
2600             break;
2601           case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_LEFT_TO_RIGHT:
2602             x = (priv->page_position / rows) % columns;
2603             y = priv->page_position % rows;
2604             break;
2605           case GTK_NUMBER_UP_LAYOUT_TOP_TO_BOTTOM_RIGHT_TO_LEFT:
2606             x = columns - 1 - (priv->page_position / rows) % columns;
2607             y = priv->page_position % rows;
2608             break;
2609           case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_LEFT_TO_RIGHT:
2610             x = (priv->page_position / rows) % columns;
2611             y = rows - 1 - priv->page_position % rows;
2612             break;
2613           case GTK_NUMBER_UP_LAYOUT_BOTTOM_TO_TOP_RIGHT_TO_LEFT:
2614             x = columns - 1 - (priv->page_position / rows) % columns;
2615             y = rows - 1 - priv->page_position % rows;
2616             break;
2617           default:
2618             g_assert_not_reached();
2619             x = 0;
2620             y = 0;
2621         }
2622
2623       if (priv->manual_number_up == 4 || priv->manual_number_up == 9 || priv->manual_number_up == 16)
2624         {
2625           x_scale = page_width / (columns * paper_width);
2626           y_scale = page_height / (rows * paper_height);
2627
2628           scale = x_scale < y_scale ? x_scale : y_scale;
2629
2630           x_step = paper_width * (x_scale / scale);
2631           y_step = paper_height * (y_scale / scale);
2632
2633           if ((left_margin + right_margin) > 0)
2634             {
2635               horizontal_offset = left_margin * (x_step - context_width) / (left_margin + right_margin);
2636               vertical_offset = top_margin * (y_step - context_height) / (top_margin + bottom_margin);
2637             }
2638           else
2639             {
2640               horizontal_offset = (x_step - context_width) / 2.0;
2641               vertical_offset = (y_step - context_height) / 2.0;
2642             }
2643
2644           cairo_scale (cr, scale, scale);
2645
2646           cairo_translate (cr,
2647                            x * x_step + horizontal_offset,
2648                            y * y_step + vertical_offset);
2649
2650           if (priv->manual_scale != 1.0)
2651             cairo_scale (cr, priv->manual_scale, priv->manual_scale);
2652         }
2653
2654       if (priv->manual_number_up == 2 || priv->manual_number_up == 6)
2655         {
2656           x_scale = page_height / (columns * paper_width);
2657           y_scale = page_width / (rows * paper_height);
2658
2659           scale = x_scale < y_scale ? x_scale : y_scale;
2660
2661           horizontal_offset = (paper_width * (x_scale / scale) - paper_width) / 2.0 * columns;
2662           vertical_offset = (paper_height * (y_scale / scale) - paper_height) / 2.0 * rows;
2663
2664           if (!priv->use_full_page)
2665             {
2666               horizontal_offset -= right_margin;
2667               vertical_offset += top_margin;
2668             }
2669
2670           cairo_scale (cr, scale, scale);
2671
2672           cairo_translate (cr,
2673                            y * paper_height + vertical_offset,
2674                            (columns - x) * paper_width + horizontal_offset);
2675
2676           if (priv->manual_scale != 1.0)
2677             cairo_scale (cr, priv->manual_scale, priv->manual_scale);
2678
2679           cairo_rotate (cr, - G_PI / 2);
2680         }
2681     }
2682   else
2683     if (!priv->use_full_page)
2684       _gtk_print_context_translate_into_margin (print_context);
2685   
2686   priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_DRAWING;
2687
2688   g_signal_emit (op, signals[DRAW_PAGE], 0, 
2689                  print_context, page_nr);
2690
2691   if (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_DRAWING)
2692     gtk_print_operation_draw_page_finish (op);
2693 }
2694
2695 static void
2696 prepare_data (PrintPagesData *data)
2697 {
2698   GtkPrintOperationPrivate *priv;
2699   GtkPageSetup             *page_setup;
2700   gint                      i, j, counter;
2701
2702   priv = data->op->priv;
2703
2704   if (priv->manual_collation)
2705     {
2706       data->uncollated_copies = priv->manual_num_copies;
2707       data->collated_copies = 1;
2708     }
2709   else
2710     {
2711       data->uncollated_copies = 1;
2712       data->collated_copies = priv->manual_num_copies;
2713     }
2714
2715   if (!data->initialized)
2716     {
2717       data->initialized = TRUE;
2718       page_setup = create_page_setup (data->op);
2719       _gtk_print_context_set_page_setup (priv->print_context,
2720                                          page_setup);
2721       g_object_unref (page_setup);
2722
2723       g_signal_emit (data->op, signals[BEGIN_PRINT], 0, priv->print_context);
2724
2725       return;
2726     }
2727
2728   if (g_signal_has_handler_pending (data->op, signals[PAGINATE], 0, FALSE))
2729     {
2730       gboolean paginated = FALSE;
2731
2732       g_signal_emit (data->op, signals[PAGINATE], 0, priv->print_context, &paginated);
2733       if (!paginated)
2734         return;
2735     }
2736
2737   /* Initialize parts of PrintPagesData that depend on nr_of_pages
2738    */
2739   if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
2740     {
2741       if (priv->page_ranges == NULL) 
2742         {
2743           g_warning ("no pages to print");
2744           priv->cancelled = TRUE;
2745           return;
2746         }
2747       data->ranges = priv->page_ranges;
2748       data->num_ranges = priv->num_page_ranges;
2749       for (i = 0; i < data->num_ranges; i++)
2750         if (data->ranges[i].end == -1 || 
2751             data->ranges[i].end >= priv->nr_of_pages)
2752           data->ranges[i].end = priv->nr_of_pages - 1;
2753     }
2754   else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
2755    priv->current_page != -1)
2756     {
2757       data->ranges = &data->one_range;
2758       data->num_ranges = 1;
2759       data->ranges[0].start = priv->current_page;
2760       data->ranges[0].end = priv->current_page;
2761     }
2762   else
2763     {
2764       data->ranges = &data->one_range;
2765       data->num_ranges = 1;
2766       data->ranges[0].start = 0;
2767       data->ranges[0].end = priv->nr_of_pages - 1;
2768     }
2769
2770   clamp_page_ranges (data);
2771
2772   if (data->num_ranges < 1) 
2773     {
2774       priv->cancelled = TRUE;
2775       return;
2776     }
2777
2778   priv->nr_of_pages_to_print = 0;
2779   for (i = 0; i < data->num_ranges; i++)
2780     priv->nr_of_pages_to_print += data->ranges[i].end - data->ranges[i].start + 1;
2781
2782   data->pages = g_new (gint, priv->nr_of_pages_to_print);
2783   counter = 0;
2784   for (i = 0; i < data->num_ranges; i++)
2785     for (j = data->ranges[i].start; j <= data->ranges[i].end; j++)
2786       {
2787         data->pages[counter] = j;
2788         counter++;
2789       }
2790
2791   data->total = -1;
2792   data->collated = 0;
2793   data->uncollated = 0;
2794
2795   if (priv->manual_number_up > 1)
2796     {
2797       if (priv->nr_of_pages_to_print % priv->manual_number_up == 0)
2798         data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up;
2799       else
2800         data->num_of_sheets = priv->nr_of_pages_to_print / priv->manual_number_up + 1;
2801     }
2802   else
2803     data->num_of_sheets = priv->nr_of_pages_to_print;
2804
2805   if (priv->manual_reverse)
2806     {
2807       /* data->sheet is 0-based */
2808       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2809         data->sheet = (data->num_of_sheets - 1) - (data->num_of_sheets - 1) % 2;
2810       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2811         data->sheet = (data->num_of_sheets - 1) - (1 - (data->num_of_sheets - 1) % 2);
2812       else
2813         data->sheet = data->num_of_sheets - 1;
2814     }
2815   else
2816     {
2817       /* data->sheet is 0-based */
2818       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2819         data->sheet = 0;
2820       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2821         {
2822           if (data->num_of_sheets > 1)
2823             data->sheet = 1;
2824           else
2825             data->sheet = -1;
2826         }
2827       else
2828         data->sheet = 0;
2829     }
2830
2831   priv->page_position = data->sheet * priv->manual_number_up;
2832
2833   if (priv->page_position < 0 || priv->page_position >= priv->nr_of_pages_to_print)
2834     {
2835       priv->cancelled = TRUE;
2836       return;
2837     }
2838
2839   data->page = data->pages[priv->page_position];
2840   data->first_position = priv->page_position;
2841   data->first_sheet = data->sheet;
2842
2843   if (priv->manual_reverse)
2844     {
2845       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2846         data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2847       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2848         data->last_position = MIN (2 * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2849       else
2850         data->last_position = MIN (priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2851     }
2852   else
2853     {
2854       if (priv->manual_page_set == GTK_PAGE_SET_ODD)
2855         data->last_position = MIN (((data->num_of_sheets - 1) - ((data->num_of_sheets - 1) % 2)) * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2856       else if (priv->manual_page_set == GTK_PAGE_SET_EVEN)
2857         data->last_position = MIN (((data->num_of_sheets - 1) - (1 - (data->num_of_sheets - 1) % 2)) * priv->manual_number_up - 1, priv->nr_of_pages_to_print - 1);
2858       else
2859         data->last_position = priv->nr_of_pages_to_print - 1;
2860     }
2861
2862
2863   _gtk_print_operation_set_status (data->op, 
2864                                    GTK_PRINT_STATUS_GENERATING_DATA, 
2865                                    NULL);
2866 }
2867
2868 static gboolean
2869 print_pages_idle (gpointer user_data)
2870 {
2871   PrintPagesData *data; 
2872   GtkPrintOperationPrivate *priv;
2873   gboolean done = FALSE;
2874
2875   data = (PrintPagesData*)user_data;
2876   priv = data->op->priv;
2877
2878   if (priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY)
2879     {
2880       if (priv->status == GTK_PRINT_STATUS_PREPARING)
2881         {
2882           prepare_data (data);
2883           goto out;
2884         }
2885
2886       if (data->is_preview && !priv->cancelled)
2887         {
2888           done = TRUE;
2889
2890           g_signal_emit_by_name (data->op, "ready", priv->print_context);
2891           goto out;
2892         }
2893
2894       increment_page_sequence (data);
2895
2896       if (!data->done)
2897         common_render_page (data->op, data->page);
2898       else
2899         done = priv->page_drawing_state == GTK_PAGE_DRAWING_STATE_READY;
2900
2901  out:
2902
2903       if (priv->cancelled)
2904         {
2905           _gtk_print_operation_set_status (data->op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2906
2907           data->is_preview = FALSE;
2908           done = TRUE;
2909         }
2910
2911       if (done && !data->is_preview)
2912         {
2913           g_signal_emit (data->op, signals[END_PRINT], 0, priv->print_context);
2914           priv->end_run (data->op, priv->is_sync, priv->cancelled);
2915         }
2916
2917       update_progress (data);
2918     }
2919
2920   return !done;
2921 }
2922   
2923 static void
2924 handle_progress_response (GtkWidget *dialog, 
2925                           gint       response,
2926                           gpointer   data)
2927 {
2928   GtkPrintOperation *op = (GtkPrintOperation *)data;
2929
2930   gtk_widget_hide (dialog);
2931   gtk_print_operation_cancel (op);
2932 }
2933
2934 static gboolean
2935 show_progress_timeout (PrintPagesData *data)
2936 {
2937   gtk_window_present (GTK_WINDOW (data->progress));
2938
2939   data->op->priv->show_progress_timeout_id = 0;
2940
2941   return FALSE;
2942 }
2943
2944 static void
2945 print_pages (GtkPrintOperation       *op,
2946              GtkWindow               *parent,
2947              gboolean                 do_print,
2948              GtkPrintOperationResult  result)
2949 {
2950   GtkPrintOperationPrivate *priv = op->priv;
2951   PrintPagesData *data;
2952  
2953   if (!do_print) 
2954     {
2955       GtkPrintOperationResult tmp_result;
2956
2957       _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2958
2959       if (priv->error)
2960         tmp_result = GTK_PRINT_OPERATION_RESULT_ERROR;
2961       else if (priv->cancelled)
2962         tmp_result = GTK_PRINT_OPERATION_RESULT_CANCEL;
2963       else
2964         tmp_result = result;
2965
2966       g_signal_emit (op, signals[DONE], 0, tmp_result);
2967
2968       return;
2969   }
2970   
2971   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);  
2972
2973   data = g_new0 (PrintPagesData, 1);
2974   data->op = g_object_ref (op);
2975   data->is_preview = (priv->action == GTK_PRINT_OPERATION_ACTION_PREVIEW);
2976
2977   if (priv->show_progress)
2978     {
2979       GtkWidget *progress;
2980
2981       progress = gtk_message_dialog_new (parent, 0, 
2982                                          GTK_MESSAGE_OTHER,
2983                                          GTK_BUTTONS_CANCEL,
2984                                          _("Preparing"));
2985       g_signal_connect (progress, "response", 
2986                         G_CALLBACK (handle_progress_response), op);
2987
2988       priv->show_progress_timeout_id = 
2989         gdk_threads_add_timeout (SHOW_PROGRESS_TIME, 
2990                        (GSourceFunc)show_progress_timeout,
2991                        data);
2992
2993       data->progress = progress;
2994     }
2995
2996   if (data->is_preview)
2997     {
2998       gboolean handled;
2999       
3000       g_signal_emit_by_name (op, "preview",
3001                              GTK_PRINT_OPERATION_PREVIEW (op),
3002                              priv->print_context,
3003                              parent,
3004                              &handled);
3005
3006       if (!handled)
3007         {
3008           GtkWidget *error_dialog;
3009
3010           error_dialog = gtk_message_dialog_new (parent,
3011                                                  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
3012                                                  GTK_MESSAGE_ERROR,
3013                                                  GTK_BUTTONS_OK,
3014                                                  _("Error creating print preview"));
3015
3016           gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (error_dialog),
3017                                                     _("The most probable reason is that a temporary file could not be created."));
3018
3019           if (parent && gtk_window_has_group (parent))
3020             gtk_window_group_add_window (gtk_window_get_group (parent),
3021                                          GTK_WINDOW (error_dialog));
3022
3023           g_signal_connect (error_dialog, "response",
3024                             G_CALLBACK (gtk_widget_destroy), NULL);
3025
3026           gtk_widget_show (error_dialog);
3027
3028           print_pages_idle_done (data);
3029
3030           return;
3031         }
3032
3033       if (gtk_print_context_get_cairo_context (priv->print_context) == NULL)
3034         {
3035           /* Programmer error */
3036           g_error ("You must set a cairo context on the print context");
3037         }
3038       
3039       priv->start_page = preview_start_page;
3040       priv->end_page = preview_end_page;
3041       priv->end_run = preview_end_run;
3042
3043       priv->print_pages = gtk_print_settings_get_print_pages (priv->print_settings);
3044       priv->page_ranges = gtk_print_settings_get_page_ranges (priv->print_settings,
3045                                                               &priv->num_page_ranges);
3046       priv->manual_num_copies = 1;
3047       priv->manual_collation = FALSE;
3048       priv->manual_reverse = gtk_print_settings_get_reverse (priv->print_settings);
3049       priv->manual_page_set = gtk_print_settings_get_page_set (priv->print_settings);
3050       priv->manual_scale = gtk_print_settings_get_scale (priv->print_settings) / 100.0;
3051       priv->manual_orientation = TRUE;
3052       priv->manual_number_up = gtk_print_settings_get_number_up (priv->print_settings);
3053       priv->manual_number_up_layout = gtk_print_settings_get_number_up_layout (priv->print_settings);
3054     }
3055   
3056   priv->print_pages_idle_id = gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
3057                                                          print_pages_idle, 
3058                                                          data, 
3059                                                          print_pages_idle_done);
3060   
3061   /* Recursive main loop to make sure we don't exit  on sync operations  */
3062   if (priv->is_sync)
3063     {
3064       priv->rloop = g_main_loop_new (NULL, FALSE);
3065
3066       g_object_ref (op);
3067       gdk_threads_leave ();
3068       g_main_loop_run (priv->rloop);
3069       gdk_threads_enter ();
3070       
3071       g_main_loop_unref (priv->rloop);
3072       priv->rloop = NULL;
3073       g_object_unref (op);
3074     }
3075 }
3076
3077 /**
3078  * gtk_print_operation_get_error:
3079  * @op: a #GtkPrintOperation
3080  * @error: return location for the error
3081  * 
3082  * Call this when the result of a print operation is
3083  * %GTK_PRINT_OPERATION_RESULT_ERROR, either as returned by 
3084  * gtk_print_operation_run(), or in the #GtkPrintOperation::done signal 
3085  * handler. The returned #GError will contain more details on what went wrong.
3086  *
3087  * Since: 2.10
3088  **/
3089 void
3090 gtk_print_operation_get_error (GtkPrintOperation  *op,
3091                                GError            **error)
3092 {
3093   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3094   
3095   g_propagate_error (error, op->priv->error);
3096
3097   op->priv->error = NULL;
3098 }
3099
3100
3101 /**
3102  * gtk_print_operation_run:
3103  * @op: a #GtkPrintOperation
3104  * @action: the action to start
3105  * @parent: (allow-none): Transient parent of the dialog
3106  * @error: (allow-none): Return location for errors, or %NULL
3107  *
3108  * Runs the print operation, by first letting the user modify
3109  * print settings in the print dialog, and then print the document.
3110  *
3111  * Normally that this function does not return until the rendering of all 
3112  * pages is complete. You can connect to the 
3113  * #GtkPrintOperation::status-changed signal on @op to obtain some 
3114  * information about the progress of the print operation. 
3115  * Furthermore, it may use a recursive mainloop to show the print dialog.
3116  *
3117  * If you call gtk_print_operation_set_allow_async() or set the 
3118  * #GtkPrintOperation:allow-async property the operation will run 
3119  * asynchronously if this is supported on the platform. The 
3120  * #GtkPrintOperation::done signal will be emitted with the result of the 
3121  * operation when the it is done (i.e. when the dialog is canceled, or when 
3122  * the print succeeds or fails).
3123  * |[
3124  * if (settings != NULL)
3125  *   gtk_print_operation_set_print_settings (print, settings);
3126  *   
3127  * if (page_setup != NULL)
3128  *   gtk_print_operation_set_default_page_setup (print, page_setup);
3129  *   
3130  * g_signal_connect (print, "begin-print", 
3131  *                   G_CALLBACK (begin_print), &data);
3132  * g_signal_connect (print, "draw-page", 
3133  *                   G_CALLBACK (draw_page), &data);
3134  *  
3135  * res = gtk_print_operation_run (print, 
3136  *                                GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, 
3137  *                                parent, 
3138  *                                &error);
3139  *  
3140  * if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
3141  *  {
3142  *    error_dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
3143  *                                           GTK_DIALOG_DESTROY_WITH_PARENT,
3144  *                                           GTK_MESSAGE_ERROR,
3145  *                                           GTK_BUTTONS_CLOSE,
3146  *                                           "Error printing file:\n%s",
3147  *                                           error->message);
3148  *    g_signal_connect (error_dialog, "response", 
3149  *                      G_CALLBACK (gtk_widget_destroy), NULL);
3150  *    gtk_widget_show (error_dialog);
3151  *    g_error_free (error);
3152  *  }
3153  * else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
3154  *  {
3155  *    if (settings != NULL)
3156  *      g_object_unref (settings);
3157  *    settings = g_object_ref (gtk_print_operation_get_print_settings (print));
3158  *  }
3159  * ]|
3160  *
3161  * Note that gtk_print_operation_run() can only be called once on a
3162  * given #GtkPrintOperation.
3163  *
3164  * Return value: the result of the print operation. A return value of 
3165  *   %GTK_PRINT_OPERATION_RESULT_APPLY indicates that the printing was
3166  *   completed successfully. In this case, it is a good idea to obtain 
3167  *   the used print settings with gtk_print_operation_get_print_settings() 
3168  *   and store them for reuse with the next print operation. A value of
3169  *   %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS means the operation is running
3170  *   asynchronously, and will emit the #GtkPrintOperation::done signal when 
3171  *   done.
3172  *
3173  * Since: 2.10
3174  **/
3175 GtkPrintOperationResult
3176 gtk_print_operation_run (GtkPrintOperation        *op,
3177                          GtkPrintOperationAction   action,
3178                          GtkWindow                *parent,
3179                          GError                  **error)
3180 {
3181   GtkPrintOperationPrivate *priv;
3182   GtkPrintOperationResult result;
3183   GtkPageSetup *page_setup;
3184   gboolean do_print;
3185   gboolean run_print_pages;
3186   
3187   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
3188                         GTK_PRINT_OPERATION_RESULT_ERROR);
3189   g_return_val_if_fail (op->priv->status == GTK_PRINT_STATUS_INITIAL,
3190                         GTK_PRINT_OPERATION_RESULT_ERROR);
3191   priv = op->priv;
3192   
3193   run_print_pages = TRUE;
3194   do_print = FALSE;
3195   priv->error = NULL;
3196   priv->action = action;
3197
3198   if (priv->print_settings == NULL)
3199     priv->print_settings = gtk_print_settings_new ();
3200   
3201   if (action == GTK_PRINT_OPERATION_ACTION_EXPORT)
3202     {
3203       /* note: if you implement async EXPORT, update the docs
3204        * docs for the allow-async property.
3205        */
3206       priv->is_sync = TRUE;
3207       g_return_val_if_fail (priv->export_filename != NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
3208       result = run_pdf (op, parent, &do_print);
3209     }
3210   else if (action == GTK_PRINT_OPERATION_ACTION_PREVIEW)
3211     {
3212       priv->is_sync = !priv->allow_async;
3213       priv->print_context = _gtk_print_context_new (op);
3214       page_setup = create_page_setup (op);
3215       _gtk_print_context_set_page_setup (priv->print_context, page_setup);
3216       g_object_unref (page_setup);
3217       do_print = TRUE;
3218       result = priv->is_sync ? GTK_PRINT_OPERATION_RESULT_APPLY : GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
3219     }
3220 #ifndef G_OS_WIN32
3221   else if (priv->allow_async)
3222     {
3223       priv->is_sync = FALSE;
3224       _gtk_print_operation_platform_backend_run_dialog_async (op,
3225                                                               action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
3226                                                               parent,
3227                                                               print_pages);
3228       result = GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
3229       run_print_pages = FALSE; /* print_pages is called asynchronously from dialog */
3230     }
3231 #endif
3232   else
3233     {
3234       priv->is_sync = TRUE;
3235       result = _gtk_print_operation_platform_backend_run_dialog (op, 
3236                                                                  action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
3237                                                                  parent,
3238                                                                  &do_print);
3239     }
3240
3241   if (run_print_pages)
3242     print_pages (op, parent, do_print, result);
3243
3244   if (priv->error && error)
3245     {
3246       *error = g_error_copy (priv->error);
3247       result = GTK_PRINT_OPERATION_RESULT_ERROR;
3248     }
3249   else if (priv->cancelled)
3250     result = GTK_PRINT_OPERATION_RESULT_CANCEL;
3251  
3252   return result;
3253 }
3254
3255 /**
3256  * gtk_print_operation_cancel:
3257  * @op: a #GtkPrintOperation
3258  *
3259  * Cancels a running print operation. This function may
3260  * be called from a #GtkPrintOperation::begin-print, 
3261  * #GtkPrintOperation::paginate or #GtkPrintOperation::draw-page
3262  * signal handler to stop the currently running print 
3263  * operation.
3264  *
3265  * Since: 2.10
3266  */
3267 void
3268 gtk_print_operation_cancel (GtkPrintOperation *op)
3269 {
3270   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3271   
3272   op->priv->cancelled = TRUE;
3273 }
3274
3275 /**
3276  * gtk_print_operation_set_support_selection:
3277  * @op: a #GtkPrintOperation
3278  * @support_selection: %TRUE to support selection
3279  *
3280  * Sets whether selection is supported by #GtkPrintOperation.
3281  *
3282  * Since: 2.18
3283  */
3284 void
3285 gtk_print_operation_set_support_selection (GtkPrintOperation  *op,
3286                                            gboolean            support_selection)
3287 {
3288   GtkPrintOperationPrivate *priv;
3289
3290   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3291
3292   priv = op->priv;
3293
3294   support_selection = support_selection != FALSE;
3295   if (priv->support_selection != support_selection)
3296     {
3297       priv->support_selection = support_selection;
3298       g_object_notify (G_OBJECT (op), "support-selection");
3299     }
3300 }
3301
3302 /**
3303  * gtk_print_operation_get_support_selection:
3304  * @op: a #GtkPrintOperation
3305  *
3306  * Gets the value of #GtkPrintOperation:support-selection property.
3307  * 
3308  * Returns: whether the application supports print of selection
3309  *
3310  * Since: 2.18
3311  */
3312 gboolean
3313 gtk_print_operation_get_support_selection (GtkPrintOperation *op)
3314 {
3315   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
3316
3317   return op->priv->support_selection;
3318 }
3319
3320 /**
3321  * gtk_print_operation_set_has_selection:
3322  * @op: a #GtkPrintOperation
3323  * @has_selection: %TRUE indicates that a selection exists
3324  *
3325  * Sets whether there is a selection to print.
3326  *
3327  * Application has to set number of pages to which the selection
3328  * will draw by gtk_print_operation_set_n_pages() in a callback of
3329  * #GtkPrintOperation::begin-print.
3330  *
3331  * Since: 2.18
3332  */
3333 void
3334 gtk_print_operation_set_has_selection (GtkPrintOperation  *op,
3335                                        gboolean            has_selection)
3336 {
3337   GtkPrintOperationPrivate *priv;
3338
3339   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
3340
3341   priv = op->priv;
3342
3343   has_selection = has_selection != FALSE;
3344   if (priv->has_selection != has_selection)
3345     {
3346       priv->has_selection = has_selection;
3347       g_object_notify (G_OBJECT (op), "has-selection");
3348     }
3349 }
3350
3351 /**
3352  * gtk_print_operation_get_has_selection:
3353  * @op: a #GtkPrintOperation
3354  *
3355  * Gets the value of #GtkPrintOperation:has-selection property.
3356  * 
3357  * Returns: whether there is a selection
3358  *
3359  * Since: 2.18
3360  */
3361 gboolean
3362 gtk_print_operation_get_has_selection (GtkPrintOperation *op)
3363 {
3364   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
3365
3366   return op->priv->has_selection;
3367 }
3368
3369 /**
3370  * gtk_print_operation_get_n_pages_to_print:
3371  * @op: a #GtkPrintOperation
3372  *
3373  * Returns the number of pages that will be printed.
3374  *
3375  * Note that this value is set during print preparation phase
3376  * (%GTK_PRINT_STATUS_PREPARING), so this function should never be
3377  * called before the data generation phase (%GTK_PRINT_STATUS_GENERATING_DATA).
3378  * You can connect to the #GtkPrintOperation::status-changed signal
3379  * and call gtk_print_operation_get_n_pages_to_print() when
3380  * print status is %GTK_PRINT_STATUS_GENERATING_DATA.
3381  * This is typically used to track the progress of print operation.
3382  *
3383  * Returns: the number of pages that will be printed
3384  *
3385  * Since: 2.18
3386  **/
3387 gint
3388 gtk_print_operation_get_n_pages_to_print (GtkPrintOperation *op)
3389 {
3390   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), -1);
3391
3392   return op->priv->nr_of_pages_to_print;
3393 }