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