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