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