]> Pileus Git - ~andy/gtk/blob - gtk/gtkprintoperation.c
Documentation additions and fixes.
[~andy/gtk] / gtk / gtkprintoperation.c
1 /* GTK - The GIMP Toolkit
2  * gtkprintoperation.c: Print Operation
3  * Copyright (C) 2006, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include <errno.h>
24 #include <stdlib.h>       
25
26 #include <string.h>
27 #include "gtkprintoperation-private.h"
28 #include "gtkmarshalers.h"
29 #include <cairo-pdf.h>
30 #include "gtkintl.h"
31 #include "gtkprivate.h"
32 #include "gtkmessagedialog.h"
33 #include "gtkalias.h"
34
35 #define SHOW_PROGRESS_TIME 1200
36
37 #define GTK_PRINT_OPERATION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_PRINT_OPERATION, GtkPrintOperationPrivate))
38
39 enum 
40 {
41   DONE,
42   BEGIN_PRINT,
43   PAGINATE,
44   REQUEST_PAGE_SETUP,
45   DRAW_PAGE,
46   END_PRINT,
47   STATUS_CHANGED,
48   CREATE_CUSTOM_WIDGET,
49   CUSTOM_WIDGET_APPLY,
50   PREVIEW,
51   LAST_SIGNAL
52 };
53
54 enum 
55 {
56   PROP_0,
57   PROP_DEFAULT_PAGE_SETUP,
58   PROP_PRINT_SETTINGS,
59   PROP_JOB_NAME,
60   PROP_N_PAGES,
61   PROP_CURRENT_PAGE,
62   PROP_USE_FULL_PAGE,
63   PROP_TRACK_PRINT_STATUS,
64   PROP_UNIT,
65   PROP_SHOW_PROGRESS,
66   PROP_ALLOW_ASYNC,
67   PROP_EXPORT_FILENAME,
68   PROP_STATUS,
69   PROP_STATUS_STRING,
70   PROP_CUSTOM_TAB_LABEL
71 };
72
73 static guint signals[LAST_SIGNAL] = { 0 };
74 static int job_nr = 0;
75
76 static void          preview_iface_init (GtkPrintOperationPreviewIface *iface);
77 static GtkPageSetup *create_page_setup  (GtkPrintOperation             *op);
78 static void          common_render_page (GtkPrintOperation             *op,
79                                          gint                           page_nr);
80
81
82 G_DEFINE_TYPE_WITH_CODE (GtkPrintOperation, gtk_print_operation, G_TYPE_OBJECT,
83                          G_IMPLEMENT_INTERFACE (GTK_TYPE_PRINT_OPERATION_PREVIEW,
84                                                 preview_iface_init))
85
86 /**
87  * gtk_print_error_quark:
88  *
89  * Registers an error quark for #GtkPrintOperation if necessary.
90  * 
91  * Return value: The error quark used for #GtkPrintOperation errors.
92  *
93  * Since: 2.10
94  **/
95 GQuark     
96 gtk_print_error_quark (void)
97 {
98   static GQuark quark = 0;
99   if (quark == 0)
100     quark = g_quark_from_static_string ("gtk-print-error-quark");
101   return quark;
102 }
103      
104 static void
105 gtk_print_operation_finalize (GObject *object)
106 {
107   GtkPrintOperation *print_operation = GTK_PRINT_OPERATION (object);
108   GtkPrintOperationPrivate *priv = print_operation->priv;
109
110   if (priv->free_platform_data &&
111       priv->platform_data)
112     {
113       priv->free_platform_data (priv->platform_data);
114       priv->free_platform_data = NULL;
115     }
116
117   if (priv->default_page_setup)
118     g_object_unref (priv->default_page_setup);
119   
120   if (priv->print_settings)
121     g_object_unref (priv->print_settings);
122   
123   g_free (priv->export_filename);
124   g_free (priv->job_name);
125   g_free (priv->custom_tab_label);
126
127   if (priv->print_pages_idle_id > 0)
128     g_source_remove (priv->print_pages_idle_id);
129
130   if (priv->show_progress_timeout_id > 0)
131     g_source_remove (priv->show_progress_timeout_id);
132
133   if (priv->error)
134     g_error_free (priv->error);
135   
136   G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object);
137 }
138
139 static void
140 gtk_print_operation_init (GtkPrintOperation *operation)
141 {
142   GtkPrintOperationPrivate *priv;
143   const char *appname;
144
145   priv = operation->priv = GTK_PRINT_OPERATION_GET_PRIVATE (operation);
146
147   priv->status = GTK_PRINT_STATUS_INITIAL;
148   priv->status_string = g_strdup ("");
149   priv->default_page_setup = NULL;
150   priv->print_settings = NULL;
151   priv->nr_of_pages = -1;
152   priv->current_page = -1;
153   priv->use_full_page = FALSE;
154   priv->show_progress = FALSE;
155   priv->export_filename = NULL;
156   priv->track_print_status = FALSE;
157   priv->is_sync = FALSE;
158
159   priv->rloop = NULL;
160   priv->unit = GTK_UNIT_PIXEL;
161
162   appname = g_get_application_name ();
163   priv->job_name = g_strdup_printf ("%s job #%d", appname, ++job_nr);
164 }
165
166 static void
167 preview_iface_render_page (GtkPrintOperationPreview *preview,
168                            gint                      page_nr)
169 {
170
171   GtkPrintOperation *op;
172
173   op = GTK_PRINT_OPERATION (preview);
174   common_render_page (op, page_nr);
175 }
176
177 static void
178 preview_iface_end_preview (GtkPrintOperationPreview *preview)
179 {
180   GtkPrintOperation *op;
181   
182   op = GTK_PRINT_OPERATION (preview);
183
184   g_signal_emit (op, signals[END_PRINT], 0, op->priv->print_context);
185
186   if (op->priv->rloop)
187     g_main_loop_quit (op->priv->rloop);
188
189   op->priv->end_run (op, op->priv->is_sync, TRUE);
190   
191   g_signal_emit (op, signals[DONE], 0,
192                  GTK_PRINT_OPERATION_RESULT_APPLY);
193 }
194
195 static gboolean
196 preview_iface_is_selected (GtkPrintOperationPreview *preview,
197                            gint                      page_nr)
198 {
199   GtkPrintOperation *op;
200   GtkPrintOperationPrivate *priv;
201   int i;
202   
203   op = GTK_PRINT_OPERATION (preview);
204   priv = op->priv;
205   
206   switch (priv->print_pages)
207     {
208     case GTK_PRINT_PAGES_ALL:
209       return (page_nr >= 0) && (page_nr < priv->nr_of_pages);
210     case GTK_PRINT_PAGES_CURRENT:
211       return page_nr == priv->current_page;
212     case GTK_PRINT_PAGES_RANGES:
213       for (i = 0; i < priv->num_page_ranges; i++)
214         {
215           if (page_nr >= priv->page_ranges[i].start &&
216               page_nr <= priv->page_ranges[i].end)
217             return TRUE;
218         }
219       return FALSE;
220     }
221   return FALSE;
222 }
223
224 static void
225 preview_iface_init (GtkPrintOperationPreviewIface *iface)
226 {
227   iface->render_page = preview_iface_render_page;
228   iface->end_preview = preview_iface_end_preview;
229   iface->is_selected = preview_iface_is_selected;
230 }
231
232 static void
233 preview_start_page (GtkPrintOperation *op,
234                     GtkPrintContext   *print_context,
235                     GtkPageSetup      *page_setup)
236 {
237   g_signal_emit_by_name (op, "got-page-size", print_context, page_setup);
238 }
239
240 static void
241 preview_end_page (GtkPrintOperation *op,
242                   GtkPrintContext   *print_context)
243 {
244 }
245
246 static void
247 preview_end_run (GtkPrintOperation *op,
248                  gboolean           wait,
249                  gboolean           cancelled)
250 {
251   g_free (op->priv->page_ranges);
252   op->priv->page_ranges = NULL;
253
254   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
255 }
256
257
258 static void
259 gtk_print_operation_set_property (GObject      *object,
260                                   guint         prop_id,
261                                   const GValue *value,
262                                   GParamSpec   *pspec)
263 {
264   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
265   
266   switch (prop_id)
267     {
268     case PROP_DEFAULT_PAGE_SETUP:
269       gtk_print_operation_set_default_page_setup (op, g_value_get_object (value));
270       break;
271     case PROP_PRINT_SETTINGS:
272       gtk_print_operation_set_print_settings (op, g_value_get_object (value));
273       break;
274     case PROP_JOB_NAME:
275       gtk_print_operation_set_job_name (op, g_value_get_string (value));
276       break;
277     case PROP_N_PAGES:
278       gtk_print_operation_set_n_pages (op, g_value_get_int (value));
279       break;
280     case PROP_CURRENT_PAGE:
281       gtk_print_operation_set_current_page (op, g_value_get_int (value));
282       break;
283     case PROP_USE_FULL_PAGE:
284       gtk_print_operation_set_use_full_page (op, g_value_get_boolean (value));
285       break;
286     case PROP_TRACK_PRINT_STATUS:
287       gtk_print_operation_set_track_print_status (op, g_value_get_boolean (value));
288       break;
289     case PROP_UNIT:
290       gtk_print_operation_set_unit (op, g_value_get_enum (value));
291       break;
292     case PROP_ALLOW_ASYNC:
293       gtk_print_operation_set_allow_async (op, g_value_get_boolean (value));
294       break;
295     case PROP_SHOW_PROGRESS:
296       gtk_print_operation_set_show_progress (op, g_value_get_boolean (value));
297       break;
298     case PROP_EXPORT_FILENAME:
299       gtk_print_operation_set_export_filename (op, g_value_get_string (value));
300       break;
301     case PROP_CUSTOM_TAB_LABEL:
302       gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value));
303       break;
304     default:
305       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
306       break;
307     }
308 }
309
310 static void
311 gtk_print_operation_get_property (GObject    *object,
312                                   guint       prop_id,
313                                   GValue     *value,
314                                   GParamSpec *pspec)
315 {
316   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
317   GtkPrintOperationPrivate *priv = op->priv;
318
319   switch (prop_id)
320     {
321     case PROP_DEFAULT_PAGE_SETUP:
322       g_value_set_object (value, priv->default_page_setup);
323       break;
324     case PROP_PRINT_SETTINGS:
325       g_value_set_object (value, priv->print_settings);
326       break;
327     case PROP_JOB_NAME:
328       g_value_set_string (value, priv->job_name);
329       break;
330     case PROP_N_PAGES:
331       g_value_set_int (value, priv->nr_of_pages);
332       break;
333     case PROP_CURRENT_PAGE:
334       g_value_set_int (value, priv->current_page);
335       break;      
336     case PROP_USE_FULL_PAGE:
337       g_value_set_boolean (value, priv->use_full_page);
338       break;
339     case PROP_TRACK_PRINT_STATUS:
340       g_value_set_boolean (value, priv->track_print_status);
341       break;
342     case PROP_UNIT:
343       g_value_set_enum (value, priv->unit);
344       break;
345     case PROP_ALLOW_ASYNC:
346       g_value_set_boolean (value, priv->allow_async);
347       break;
348     case PROP_SHOW_PROGRESS:
349       g_value_set_boolean (value, priv->show_progress);
350       break;
351     case PROP_EXPORT_FILENAME:
352       g_value_set_string (value, priv->export_filename);
353       break;
354     case PROP_STATUS:
355       g_value_set_enum (value, priv->status);
356       break;
357     case PROP_STATUS_STRING:
358       g_value_set_string (value, priv->status_string);
359       break;
360     case PROP_CUSTOM_TAB_LABEL:
361       g_value_set_string (value, priv->custom_tab_label);
362       break;
363     default:
364       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
365       break;
366     }
367 }
368
369 typedef struct
370 {
371   GtkPrintOperationPreview *preview;
372   GtkPrintContext *print_context;
373   GtkWindow *parent;
374   cairo_surface_t *surface;
375   gchar *filename;
376   guint page_nr;
377   gboolean wait;
378 } PreviewOp;
379
380 static void
381 preview_print_idle_done (gpointer data)
382 {
383   GtkPrintOperation *op;
384   PreviewOp *pop = (PreviewOp *) data;
385
386   GDK_THREADS_ENTER ();
387   
388   op = GTK_PRINT_OPERATION (pop->preview);
389
390   cairo_surface_finish (pop->surface);
391   /* Surface is destroyed in launch_preview */
392   _gtk_print_operation_platform_backend_launch_preview (op,
393                                                         pop->surface,
394                                                         pop->parent,
395                                                         pop->filename);
396
397   g_free (pop->filename);
398
399   gtk_print_operation_preview_end_preview (pop->preview);
400   g_free (pop);
401   
402   GDK_THREADS_LEAVE ();
403 }
404
405 static gboolean
406 preview_print_idle (gpointer data)
407 {
408   PreviewOp *pop;
409   GtkPrintOperation *op;
410   gboolean retval = TRUE;
411   cairo_t *cr;
412
413   GDK_THREADS_ENTER ();
414
415   pop = (PreviewOp *) data;
416   op = GTK_PRINT_OPERATION (pop->preview);
417
418   gtk_print_operation_preview_render_page (pop->preview, pop->page_nr);
419   
420   cr = gtk_print_context_get_cairo_context (pop->print_context);
421   _gtk_print_operation_platform_backend_preview_end_page (op, pop->surface, cr);
422   
423   /* TODO: print out sheets not pages and follow ranges */
424   pop->page_nr++;
425   if (op->priv->nr_of_pages <= pop->page_nr)
426     retval = FALSE;
427
428   GDK_THREADS_LEAVE ();
429
430   return retval;
431 }
432
433 static void
434 preview_got_page_size (GtkPrintOperationPreview *preview, 
435                        GtkPrintContext          *context,
436                        GtkPageSetup             *page_setup,
437                        PreviewOp                *pop)
438 {
439   GtkPrintOperation *op = GTK_PRINT_OPERATION (preview);
440   cairo_t *cr;
441
442   _gtk_print_operation_platform_backend_resize_preview_surface (op, page_setup, pop->surface);
443
444   cr = gtk_print_context_get_cairo_context (pop->print_context);
445   _gtk_print_operation_platform_backend_preview_start_page (op, pop->surface, cr);
446
447 }
448
449 static void
450 preview_ready (GtkPrintOperationPreview *preview,
451                GtkPrintContext          *context,
452                PreviewOp                *pop)
453 {
454   pop->page_nr = 0;
455   pop->print_context = context;
456
457   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
458                    preview_print_idle,
459                    pop,
460                    preview_print_idle_done);
461 }
462
463
464 static gboolean
465 gtk_print_operation_preview_handler (GtkPrintOperation        *op,
466                                      GtkPrintOperationPreview *preview, 
467                                      GtkPrintContext          *context,
468                                      GtkWindow                *parent)
469 {
470   gdouble dpi_x, dpi_y;
471   PreviewOp *pop;
472   GtkPageSetup *page_setup;
473   cairo_t *cr;
474
475   pop = g_new0 (PreviewOp, 1);
476   pop->filename = NULL;
477   pop->preview = preview;
478   pop->parent = parent;
479
480   page_setup = gtk_print_context_get_page_setup (context);
481
482   pop->surface =
483     _gtk_print_operation_platform_backend_create_preview_surface (op,
484                                                                   page_setup,
485                                                                   &dpi_x, &dpi_y,
486                                                                   &pop->filename);
487
488   cr = cairo_create (pop->surface);
489   gtk_print_context_set_cairo_context (op->priv->print_context, cr,
490                                        dpi_x, dpi_y);
491   cairo_destroy (cr);
492
493   g_signal_connect (preview, "ready", (GCallback) preview_ready, pop);
494   g_signal_connect (preview, "got-page-size", (GCallback) preview_got_page_size, pop);
495   
496   return TRUE;
497 }
498
499 static GtkWidget *
500 gtk_print_operation_create_custom_widget (GtkPrintOperation *operation)
501 {
502   return NULL;
503 }
504
505 static gboolean
506 custom_widget_accumulator (GSignalInvocationHint *ihint,
507                            GValue                *return_accu,
508                            const GValue          *handler_return,
509                            gpointer               dummy)
510 {
511   gboolean continue_emission;
512   GtkWidget *widget;
513   
514   widget = g_value_get_object (handler_return);
515   if (widget != NULL)
516     g_value_set_object (return_accu, widget);
517   continue_emission = (widget == NULL);
518   
519   return continue_emission;
520 }
521
522 static void
523 gtk_print_operation_class_init (GtkPrintOperationClass *class)
524 {
525   GObjectClass *gobject_class = (GObjectClass *)class;
526
527   gobject_class->set_property = gtk_print_operation_set_property;
528   gobject_class->get_property = gtk_print_operation_get_property;
529   gobject_class->finalize = gtk_print_operation_finalize;
530  
531   class->preview = gtk_print_operation_preview_handler; 
532   class->create_custom_widget = gtk_print_operation_create_custom_widget;
533   
534   g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
535
536   /**
537    * GtkPrintOperation::done:
538    * @operation: the #GtkPrintOperation on which the signal was emitted
539    * @result: the result of the print operation
540    *
541    * Emitted when the print operation run has finished doing
542    * everything required for printing. @result gives you information
543    * about what happened during the run. If @result is
544    * %GTK_PRINT_OPERATION_RESULT_ERROR then you can call
545    * gtk_print_operation_get_error() for more information.
546    *
547    * If you enabled print status tracking then 
548    * gtk_print_operation_is_finished() may still return %FALSE 
549    * after this was emitted.
550    *
551    * Since: 2.10
552    */
553   signals[DONE] =
554     g_signal_new (I_("done"),
555                   G_TYPE_FROM_CLASS (gobject_class),
556                   G_SIGNAL_RUN_LAST,
557                   G_STRUCT_OFFSET (GtkPrintOperationClass, done),
558                   NULL, NULL,
559                   g_cclosure_marshal_VOID__ENUM,
560                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_OPERATION_RESULT);
561
562   /**
563    * GtkPrintOperation::begin-print:
564    * @operation: the #GtkPrintOperation on which the signal was emitted
565    * @context: the #GtkPrintContext for the current operation
566    *
567    * Emitted after the user has finished changing print settings
568    * in the dialog, before the actual rendering starts. 
569    *
570    * A typical use for this signal is to use the parameters from the
571    * #GtkPrintContext and paginate the document accordingly, and then
572    * set the number of pages with gtk_print_operation_set_n_pages().
573    *
574    * Since: 2.10
575    */
576   signals[BEGIN_PRINT] =
577     g_signal_new (I_("begin-print"),
578                   G_TYPE_FROM_CLASS (gobject_class),
579                   G_SIGNAL_RUN_LAST,
580                   G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
581                   NULL, NULL,
582                   g_cclosure_marshal_VOID__OBJECT,
583                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
584
585    /**
586    * GtkPrintOperation::paginate:
587    * @operation: the #GtkPrintOperation on which the signal was emitted
588    * @context: the #GtkPrintContext for the current operation
589    *
590    * Emitted after the begin-print signal, but before the actual 
591    * rendering starts. It keeps getting emitted until it returns %FALSE. 
592    *
593    * This signal is intended to be used for paginating the document
594    * in small chunks, to avoid blocking the user interface for a long
595    * time. The signal handler should update the number of pages using
596    * gtk_print_operation_set_n_pages(), and return %TRUE if the document
597    * has been completely paginated.
598    *
599    * If you don't need to do pagination in chunks, you can simply do
600    * it all in the begin-print handler, and set the number of pages
601    * from there.
602    *
603    * Return value: %TRUE if pagination is complete
604    *
605    * Since: 2.10
606    */
607   signals[PAGINATE] =
608     g_signal_new (I_("paginate"),
609                   G_TYPE_FROM_CLASS (gobject_class),
610                   G_SIGNAL_RUN_LAST,
611                   G_STRUCT_OFFSET (GtkPrintOperationClass, paginate),
612                   _gtk_boolean_handled_accumulator, NULL,
613                   _gtk_marshal_BOOLEAN__OBJECT,
614                   G_TYPE_BOOLEAN, 1, GTK_TYPE_PRINT_CONTEXT);
615
616
617   /**
618    * GtkPrintOperation::request-page-setup:
619    * @operation: the #GtkPrintOperation on which the signal was emitted
620    * @context: the #GtkPrintContext for the current operation
621    * @page_nr: the number of the currently printed page
622    * @setup: the #GtkPageSetup 
623    * 
624    * Emitted once for every page that is printed, to give
625    * the application a chance to modify the page setup. Any changes 
626    * done to @setup will be in force only for printing this page.
627    *
628    * Since: 2.10
629    */
630   signals[REQUEST_PAGE_SETUP] =
631     g_signal_new (I_("request-page-setup"),
632                   G_TYPE_FROM_CLASS (gobject_class),
633                   G_SIGNAL_RUN_LAST,
634                   G_STRUCT_OFFSET (GtkPrintOperationClass, request_page_setup),
635                   NULL, NULL,
636                   _gtk_marshal_VOID__OBJECT_INT_OBJECT,
637                   G_TYPE_NONE, 3,
638                   GTK_TYPE_PRINT_CONTEXT,
639                   G_TYPE_INT,
640                   GTK_TYPE_PAGE_SETUP);
641
642   /**
643    * GtkPrintOperation::draw-page:
644    * @operation: the #GtkPrintOperation on which the signal was emitted
645    * @context: the #GtkPrintContext for the current operation
646    * @page_nr: the number of the currently printed page
647    *
648    * Emitted for every page that is printed. The signal handler
649    * must render the @page_nr's page onto the cairo context obtained
650    * from @context using gtk_print_context_get_cairo_context().
651    *
652    * <informalexample><programlisting>
653    * static void
654    * draw_page (GtkPrintOperation *operation,
655    *            GtkPrintContext   *context,
656    *            gint               page_nr,
657    *            gpointer           user_data)
658    * {
659    *   cairo_t *cr;
660    *   PangoLayout *layout;
661    *   gdouble width, text_height;
662    *   gint layout_height;
663    *   PangoFontDescription *desc;
664    *   
665    *   cr = gtk_print_context_get_cairo_context (context);
666    *   width = gtk_print_context_get_width (context);
667    *   
668    *   cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT);
669    *   
670    *   cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
671    *   cairo_fill (cr);
672    *   
673    *   layout = gtk_print_context_create_pango_layout (context);
674    *   
675    *   desc = pango_font_description_from_string ("sans 14");
676    *   pango_layout_set_font_description (layout, desc);
677    *   pango_font_description_free (desc);
678    *   
679    *   pango_layout_set_text (layout, "some text", -1);
680    *   pango_layout_set_width (layout, width);
681    *   pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
682    *                          
683    *   pango_layout_get_size (layout, NULL, &amp;layout_height);
684    *   text_height = (gdouble)layout_height / PANGO_SCALE;
685    *   
686    *   cairo_move_to (cr, width / 2,  (HEADER_HEIGHT - text_height) / 2);
687    *   pango_cairo_show_layout (cr, layout);
688    *   
689    *   g_object_unref (layout);
690    * }
691    * </programlisting></informalexample>
692    *
693    * Use gtk_print_operation_set_use_full_page() and 
694    * gtk_print_operation_set_unit() before starting the print operation
695    * to set up the transformation of the cairo context according to your
696    * needs.
697    * 
698    * Since: 2.10
699    */
700   signals[DRAW_PAGE] =
701     g_signal_new (I_("draw-page"),
702                   G_TYPE_FROM_CLASS (gobject_class),
703                   G_SIGNAL_RUN_LAST,
704                   G_STRUCT_OFFSET (GtkPrintOperationClass, draw_page),
705                   NULL, NULL,
706                   _gtk_marshal_VOID__OBJECT_INT,
707                   G_TYPE_NONE, 2,
708                   GTK_TYPE_PRINT_CONTEXT,
709                   G_TYPE_INT);
710
711   /**
712    * GtkPrintOperation::end-print:
713    * @operation: the #GtkPrintOperation on which the signal was emitted
714    * @context: the #GtkPrintContext for the current operation
715    *
716    * Emitted after all pages have been rendered. 
717    * A handler for this signal can clean up any resources that have
718    * been allocated in the ::begin-print handler.
719    * 
720    * Since: 2.10
721    */
722   signals[END_PRINT] =
723     g_signal_new (I_("end-print"),
724                   G_TYPE_FROM_CLASS (gobject_class),
725                   G_SIGNAL_RUN_LAST,
726                   G_STRUCT_OFFSET (GtkPrintOperationClass, end_print),
727                   NULL, NULL,
728                   g_cclosure_marshal_VOID__OBJECT,
729                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
730
731   /**
732    * GtkPrintOperation::status-changed:
733    * @operation: the #GtkPrintOperation on which the signal was emitted
734    *
735    * Emitted at between the various phases of the print operation.
736    * See #GtkPrintStatus for the phases that are being discriminated.
737    * Use gtk_print_operation_get_status() to find out the current
738    * status.
739    *
740    * Since: 2.10
741    */
742   signals[STATUS_CHANGED] =
743     g_signal_new (I_("status-changed"),
744                   G_TYPE_FROM_CLASS (class),
745                   G_SIGNAL_RUN_LAST,
746                   G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
747                   NULL, NULL,
748                   g_cclosure_marshal_VOID__VOID,
749                   G_TYPE_NONE, 0);
750
751
752   /**
753    * GtkPrintOperation::create-custom-widget:
754    * @operation: the #GtkPrintOperation on which the signal was emitted
755    *
756    * Emitted when displaying the print dialog. If you return a
757    * widget in a handler for this signal it will be added to a custom
758    * tab in the print dialog. You typically return a container widget
759    * with multiple widgets in it.
760    *
761    * The print dialog owns the returned widget, and its lifetime
762    * isn't controlled by the app. However, the widget is guaranteed
763    * to stay around until the custom-widget-apply signal is emitted
764    * on the operation. Then you can read out any information you need
765    * from the widgets.
766    *
767    * Returns: A custom widget that gets embedded in the print dialog,
768    *          or %NULL
769    *
770    * Since: 2.10
771    */
772   signals[CREATE_CUSTOM_WIDGET] =
773     g_signal_new (I_("create-custom-widget"),
774                   G_TYPE_FROM_CLASS (class),
775                   G_SIGNAL_RUN_LAST,
776                   G_STRUCT_OFFSET (GtkPrintOperationClass, create_custom_widget),
777                   custom_widget_accumulator, NULL,
778                   _gtk_marshal_OBJECT__VOID,
779                   G_TYPE_OBJECT, 0);
780
781   /**
782    * GtkPrintOperation::custom-widget-apply:
783    * @operation: the #GtkPrintOperation on which the signal was emitted
784    * @widget: the custom widget added in create-custom-widget
785    *
786    * Emitted right before begin-print if you added
787    * a custom widget in the create-custom-widget handler. When you get
788    * this signal you should read the information from the custom widgets,
789    * as the widgets are not guaraneed to be around at a later time.
790    *
791    * Since: 2.10
792    */
793   signals[CUSTOM_WIDGET_APPLY] =
794     g_signal_new (I_("custom-widget-apply"),
795                   G_TYPE_FROM_CLASS (class),
796                   G_SIGNAL_RUN_LAST,
797                   G_STRUCT_OFFSET (GtkPrintOperationClass, custom_widget_apply),
798                   NULL, NULL,
799                   g_cclosure_marshal_VOID__OBJECT,
800                   G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
801
802    /**
803    * GtkPrintOperation::preview:
804    * @operation: the #GtkPrintOperation on which the signal was emitted
805    * @preview: the #GtkPrintPreviewOperation for the current operation
806    * @context: the #GtkPrintContext that will be used
807    * @parent: the #GtkWindow to use as window parent, or %NULL
808    *
809    * Gets emitted when a preview is requested from the native dialog.
810    * If you handle this you must set the cairo context on the printing context.
811    *
812    * If you don't override this a default implementation using an external
813    * viewer will be used.
814    *
815    * Returns: %TRUE if the listener wants to take over control of the preview
816    * 
817    * Since: 2.10
818    */
819   signals[PREVIEW] =
820     g_signal_new (I_("preview"),
821                   G_TYPE_FROM_CLASS (gobject_class),
822                   G_SIGNAL_RUN_LAST,
823                   G_STRUCT_OFFSET (GtkPrintOperationClass, preview),
824                   _gtk_boolean_handled_accumulator, NULL,
825                   _gtk_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT,
826                   G_TYPE_BOOLEAN, 3,
827                   GTK_TYPE_PRINT_OPERATION_PREVIEW,
828                   GTK_TYPE_PRINT_CONTEXT,
829                   GTK_TYPE_WINDOW);
830
831   
832   /**
833    * GtkPrintOperation:default-page-setup:
834    *
835    * The #GtkPageSetup used by default.
836    * 
837    * This page setup will be used by gtk_print_operation_run(),
838    * but it can be overridden on a per-page basis by connecting
839    * to the ::request-page-setup signal.
840    *
841    * Since: 2.10
842    */
843   g_object_class_install_property (gobject_class,
844                                    PROP_DEFAULT_PAGE_SETUP,
845                                    g_param_spec_object ("default-page-setup",
846                                                         P_("Default Page Setup"),
847                                                         P_("The GtkPageSetup used by default"),
848                                                         GTK_TYPE_PAGE_SETUP,
849                                                         GTK_PARAM_READWRITE));
850
851   /**
852    * GtkPrintOperation:print-settings:
853    *
854    * The #GtkPrintSettings used for initializing the dialog.
855    *
856    * Setting this property is typically used to re-establish 
857    * print settings from a previous print operation, see 
858    * gtk_print_operation_run().
859    *
860    * Since: 2.10
861    */
862   g_object_class_install_property (gobject_class,
863                                    PROP_PRINT_SETTINGS,
864                                    g_param_spec_object ("print-settings",
865                                                         P_("Print Settings"),
866                                                         P_("The GtkPrintSettings used for initializing the dialog"),
867                                                         GTK_TYPE_PRINT_SETTINGS,
868                                                         GTK_PARAM_READWRITE));
869   
870   /**
871    * GtkPrintOperation:job-name:
872    *
873    * A string used to identify the job (e.g. in monitoring 
874    * applications like eggcups). 
875    * 
876    * If you don't set a job name, GTK+ picks a default one 
877    * by numbering successive print jobs.
878    *
879    * Since: 2.10
880    */
881   g_object_class_install_property (gobject_class,
882                                    PROP_JOB_NAME,
883                                    g_param_spec_string ("job-name",
884                                                         P_("Job Name"),
885                                                         P_("A string used for identifying the print job."),
886                                                         "",
887                                                         GTK_PARAM_READWRITE));
888
889   /**
890    * GtkPrintOperation:n-pages:
891    *
892    * The number of pages in the document. 
893    *
894    * This <emphasis>must</emphasis> be set to a positive number
895    * before the rendering starts. It may be set in a ::begin-print 
896    * signal hander.
897    *
898    * Note that the page numbers passed to the ::request-page-setup 
899    * and ::draw-page signals are 0-based, i.e. if the user chooses 
900    * to print all pages, the last ::draw-page signal will be for 
901    * page @n_pages - 1.
902    *
903    * Since: 2.10
904    */
905   g_object_class_install_property (gobject_class,
906                                    PROP_N_PAGES,
907                                    g_param_spec_int ("n-pages",
908                                                      P_("Number of Pages"),
909                                                      P_("The number of pages in the document."),
910                                                      -1,
911                                                      G_MAXINT,
912                                                      -1,
913                                                      GTK_PARAM_READWRITE));
914
915   /**
916    * GtkPrintOperation:current-page:
917    *
918    * The current page in the document.
919    *
920    * If this is set before gtk_print_operation_run(), 
921    * the user will be able to select to print only the current page.
922    *
923    * Note that this only makes sense for pre-paginated documents.
924    *
925    * Since: 2.10
926    */
927   g_object_class_install_property (gobject_class,
928                                    PROP_CURRENT_PAGE,
929                                    g_param_spec_int ("current-page",
930                                                      P_("Current Page"),
931                                                      P_("The current page in the document."),
932                                                      -1,
933                                                      G_MAXINT,
934                                                      -1,
935                                                      GTK_PARAM_READWRITE));
936   
937   /**
938    * GtkPrintOperation:use-full-page:
939    *
940    * If %TRUE, the transformation for the cairo context obtained 
941    * from #GtkPrintContext puts the origin at the top left corner 
942    * of the page (which may not be the top left corner of the sheet, 
943    * depending on page orientation and the number of pages per sheet). 
944    * Otherwise, the origin is at the top left corner of the imageable 
945    * area (i.e. inside the margins).
946    * 
947    * Since: 2.10
948    */
949   g_object_class_install_property (gobject_class,
950                                    PROP_USE_FULL_PAGE,
951                                    g_param_spec_boolean ("use-full-page",
952                                                          P_("Use full page"),
953                                                          P_("TRUE if the the origin of the context should be at the corner of the page and not the corner of the imageable area"),
954                                                          FALSE,
955                                                          GTK_PARAM_READWRITE));
956   
957
958   /**
959    * GtkPrintOperation:track-print-status:
960    *
961    * If %TRUE, the print operation will try to continue report on 
962    * the status of the print job in the printer queues and printer. 
963    * This can allow your application to show things like "out of paper" 
964    * issues, and when the print job actually reaches the printer. 
965    * However, this is often implemented using polling, and should 
966    * not be enabled unless needed.
967    * 
968    * Since: 2.10
969    */
970   g_object_class_install_property (gobject_class,
971                                    PROP_TRACK_PRINT_STATUS,
972                                    g_param_spec_boolean ("track-print-status",
973                                                          P_("Track Print Status"),
974                                                          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."),
975                                                          FALSE,
976                                                          GTK_PARAM_READWRITE));
977   
978
979   /**
980    * GtkPrintOperation:unit:
981    *
982    * The transformation for the cairo context obtained from
983    * #GtkPrintContext is set up in such a way that distances 
984    * are measured in units of @unit.
985    *
986    * Since: 2.10
987    */
988   g_object_class_install_property (gobject_class,
989                                    PROP_UNIT,
990                                    g_param_spec_enum ("unit",
991                                                       P_("Unit"),
992                                                       P_("The unit in which distances can be measured in the context"),
993                                                       GTK_TYPE_UNIT,
994                                                       GTK_UNIT_PIXEL,
995                                                       GTK_PARAM_READWRITE));
996   
997   
998   /**
999    * GtkPrintOperation:show-progress:
1000    *
1001    * Determines whether to show a progress dialog during the 
1002    * print operation.
1003    *
1004    * Since: 2.10
1005    */
1006   g_object_class_install_property (gobject_class,
1007                                    PROP_SHOW_PROGRESS,
1008                                    g_param_spec_boolean ("show-progress",
1009                                                          P_("Show Dialog"),
1010                                                          P_("TRUE if a progress dialog is shown while printing."),
1011                                                          FALSE,
1012                                                          GTK_PARAM_READWRITE));
1013
1014   /**
1015    * GtkPrintOperation:allow-async:
1016    *
1017    * Determines whether the print operation may run asynchronously or not.
1018    * Some systems don't support asynchronous printing, but those that do
1019    * will return %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS as the status, and
1020    * emit the done signal when the operation is actually done.
1021    *
1022    * Since: 2.10
1023    */
1024   g_object_class_install_property (gobject_class,
1025                                    PROP_ALLOW_ASYNC,
1026                                    g_param_spec_boolean ("allow-async",
1027                                                          P_("Allow Async"),
1028                                                          P_("TRUE if print process may run asynchronous."),
1029                                                          FALSE,
1030                                                          GTK_PARAM_READWRITE));
1031   
1032   /**
1033    * GtkPrintOperation:export-filename:
1034    *
1035    * The name of a file file to generate instead of showing 
1036    * the print dialog. Currently, PDF is the only supported
1037    * format.
1038    *
1039    * The intended use of this property is for implementing 
1040    * "Export to PDF" actions.
1041    *
1042    * "Print to PDF" support is independent of this and is done
1043    * by letting the user pick the "Print to PDF" item from the 
1044    * list of printers in the print dialog.
1045    *
1046    * Since: 2.10
1047    */
1048   g_object_class_install_property (gobject_class,
1049                                    PROP_EXPORT_FILENAME,
1050                                    g_param_spec_string ("export-filename",
1051                                                         P_("Export filename"),
1052                                                         P_("Export filename"),
1053                                                         NULL,
1054                                                         GTK_PARAM_READWRITE));
1055   
1056   /**
1057    * GtkPrintOperation:status:
1058    *
1059    * The status of the print operation.
1060    * 
1061    * Since: 2.10
1062    */
1063   g_object_class_install_property (gobject_class,
1064                                    PROP_STATUS,
1065                                    g_param_spec_enum ("status",
1066                                                       P_("Status"),
1067                                                       P_("The status of the print operation"),
1068                                                       GTK_TYPE_PRINT_STATUS,
1069                                                       GTK_PRINT_STATUS_INITIAL,
1070                                                       GTK_PARAM_READABLE));
1071   
1072   /**
1073    * GtkPrintOperation:status-string:
1074    *
1075    * A string representation of the status of the print operation. 
1076    * The string is translated and suitable for displaying the print 
1077    * status e.g. in a #GtkStatusbar.
1078    *
1079    * See the ::status property for a status value that is suitable 
1080    * for programmatic use. 
1081    *
1082    * Since: 2.10
1083    */
1084   g_object_class_install_property (gobject_class,
1085                                    PROP_STATUS_STRING,
1086                                    g_param_spec_string ("status-string",
1087                                                         P_("Status String"),
1088                                                         P_("A human-readable description of the status"),
1089                                                         "",
1090                                                         GTK_PARAM_READABLE));
1091   
1092
1093   /**
1094    * GtkPrintOperation:custom-tab-label:
1095    *
1096    * Used as the label of the tab containing custom widgets.
1097    * Note that this property may be ignored on some platforms.
1098    * 
1099    * If this is %NULL, GTK+ uses a default label.
1100    *
1101    * Since: 2.10
1102    */
1103   g_object_class_install_property (gobject_class,
1104                                    PROP_CUSTOM_TAB_LABEL,
1105                                    g_param_spec_string ("custom-tab-label",
1106                                                         P_("Custom tab label"),
1107                                                         P_("Label for the tab containing custom widgets."),
1108                                                         NULL,
1109                                                         GTK_PARAM_READWRITE));
1110
1111 }
1112
1113 /**
1114  * gtk_print_operation_new:
1115  *
1116  * Creates a new #GtkPrintOperation. 
1117  *
1118  * Returns: a new #GtkPrintOperation
1119  *
1120  * Since: 2.10
1121  */
1122 GtkPrintOperation *
1123 gtk_print_operation_new (void)
1124 {
1125   GtkPrintOperation *print_operation;
1126
1127   print_operation = g_object_new (GTK_TYPE_PRINT_OPERATION, NULL);
1128   
1129   return print_operation;
1130 }
1131
1132 /**
1133  * gtk_print_operation_set_default_page_setup:
1134  * @op: a #GtkPrintOperation
1135  * @default_page_setup: a #GtkPageSetup, or %NULL
1136  * 
1137  * Makes @default_page_setup the default page setup for @op.
1138  *
1139  * This page setup will be used by gtk_print_operation_run(),
1140  * but it can be overridden on a per-page basis by connecting
1141  * to the ::request-page-setup signal.
1142  *
1143  * Since: 2.10
1144  **/
1145 void
1146 gtk_print_operation_set_default_page_setup (GtkPrintOperation *op,
1147                                             GtkPageSetup      *default_page_setup)
1148 {
1149   GtkPrintOperationPrivate *priv;
1150
1151   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1152   g_return_if_fail (default_page_setup == NULL || 
1153                     GTK_IS_PAGE_SETUP (default_page_setup));
1154
1155   priv = op->priv;
1156
1157   if (default_page_setup != priv->default_page_setup)
1158     {
1159       if (default_page_setup)
1160         g_object_ref (default_page_setup);
1161       
1162       if (priv->default_page_setup)
1163         g_object_unref (priv->default_page_setup);
1164       
1165       priv->default_page_setup = default_page_setup;
1166      
1167       g_object_notify (G_OBJECT (op), "default-page-setup");
1168     }
1169 }
1170
1171 /**
1172  * gtk_print_operation_get_default_page_setup:
1173  * @op: a #GtkPrintOperation
1174  *
1175  * Returns the default page setup, see 
1176  * gtk_print_operation_set_default_page_setup().
1177  *
1178  * Returns: the default page setup 
1179  *
1180  * Since: 2.10
1181  */
1182 GtkPageSetup *
1183 gtk_print_operation_get_default_page_setup (GtkPrintOperation *op)
1184 {
1185   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1186
1187   return op->priv->default_page_setup;
1188 }
1189
1190
1191 /**
1192  * gtk_print_operation_set_print_settings:
1193  * @op: a #GtkPrintOperation
1194  * @print_settings: #GtkPrintSettings, or %NULL
1195  * 
1196  * Sets the print settings for @op. This is typically used to
1197  * re-establish print settings from a previous print operation,
1198  * see gtk_print_operation_run().
1199  *
1200  * Since: 2.10
1201  **/
1202 void
1203 gtk_print_operation_set_print_settings (GtkPrintOperation *op,
1204                                         GtkPrintSettings  *print_settings)
1205 {
1206   GtkPrintOperationPrivate *priv;
1207
1208   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1209   g_return_if_fail (print_settings == NULL || 
1210                     GTK_IS_PRINT_SETTINGS (print_settings));
1211
1212   priv = op->priv;
1213
1214   if (print_settings != priv->print_settings)
1215     {
1216       if (print_settings)
1217         g_object_ref (print_settings);
1218
1219       if (priv->print_settings)
1220         g_object_unref (priv->print_settings);
1221   
1222       priv->print_settings = print_settings;
1223
1224       g_object_notify (G_OBJECT (op), "print-settings");
1225     }
1226 }
1227
1228 /**
1229  * gtk_print_operation_get_print_settings:
1230  * @op: a #GtkPrintOperation
1231  * 
1232  * Returns the current print settings. 
1233  *
1234  * Note that the return value is %NULL until either 
1235  * gtk_print_operation_set_print_settings() or 
1236  * gtk_print_operation_run() have been called.
1237  * 
1238  * Return value: the current print settings of @op.
1239  * 
1240  * Since: 2.10
1241  **/
1242 GtkPrintSettings *
1243 gtk_print_operation_get_print_settings (GtkPrintOperation *op)
1244 {
1245   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1246
1247   return op->priv->print_settings;
1248 }
1249
1250 /**
1251  * gtk_print_operation_set_job_name:
1252  * @op: a #GtkPrintOperation
1253  * @job_name: a string that identifies the print job
1254  * 
1255  * Sets the name of the print job. The name is used to identify 
1256  * the job (e.g. in monitoring applications like eggcups). 
1257  * 
1258  * If you don't set a job name, GTK+ picks a default one by 
1259  * numbering successive print jobs.
1260  *
1261  * Since: 2.10
1262  **/
1263 void
1264 gtk_print_operation_set_job_name (GtkPrintOperation *op,
1265                                   const gchar       *job_name)
1266 {
1267   GtkPrintOperationPrivate *priv;
1268
1269   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1270   g_return_if_fail (g_utf8_validate (job_name, -1, NULL));
1271
1272   priv = op->priv;
1273
1274   g_free (priv->job_name);
1275   priv->job_name = g_strdup (job_name);
1276
1277   g_object_notify (G_OBJECT (op), "job-name");
1278 }
1279
1280 /**
1281  * gtk_print_operation_set_n_pages:
1282  * @op: a #GtkPrintOperation
1283  * @n_pages: the number of pages
1284  * 
1285  * Sets the number of pages in the document. 
1286  *
1287  * This <emphasis>must</emphasis> be set to a positive number
1288  * before the rendering starts. It may be set in a ::begin-print 
1289  * signal hander.
1290  *
1291  * Note that the page numbers passed to the ::request-page-setup 
1292  * and ::draw-page signals are 0-based, i.e. if the user chooses
1293  * to print all pages, the last ::draw-page signal will be
1294  * for page @n_pages - 1.
1295  *
1296  * Since: 2.10
1297  **/
1298 void
1299 gtk_print_operation_set_n_pages (GtkPrintOperation *op,
1300                                  gint               n_pages)
1301 {
1302   GtkPrintOperationPrivate *priv;
1303
1304   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1305   g_return_if_fail (n_pages > 0);
1306
1307   priv = op->priv;
1308   g_return_if_fail (priv->current_page == -1 || 
1309                     priv->current_page < n_pages);
1310
1311   if (priv->nr_of_pages != n_pages)
1312     {
1313       priv->nr_of_pages = n_pages;
1314
1315       g_object_notify (G_OBJECT (op), "n-pages");
1316     }
1317 }
1318
1319 /**
1320  * gtk_print_operation_set_current_page:
1321  * @op: a #GtkPrintOperation
1322  * @current_page: the current page, 0-based
1323  *
1324  * Sets the current page.
1325  *
1326  * If this is called before gtk_print_operation_run(), 
1327  * the user will be able to select to print only the current page.
1328  *
1329  * Note that this only makes sense for pre-paginated documents.
1330  * 
1331  * Since: 2.10
1332  **/
1333 void
1334 gtk_print_operation_set_current_page (GtkPrintOperation *op,
1335                                       gint               current_page)
1336 {
1337   GtkPrintOperationPrivate *priv;
1338
1339   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1340   g_return_if_fail (current_page >= 0);
1341
1342   priv = op->priv;
1343   g_return_if_fail (priv->nr_of_pages == -1 || 
1344                     current_page < priv->nr_of_pages);
1345
1346   if (priv->current_page != current_page)
1347     {
1348       priv->current_page = current_page;
1349
1350       g_object_notify (G_OBJECT (op), "current-page");
1351     }
1352 }
1353
1354 /**
1355  * gtk_print_operation_set_use_full_page:
1356  * @op: a #GtkPrintOperation
1357  * @full_page: %TRUE to set up the #GtkPrintContext for the full page
1358  * 
1359  * If @full_page is %TRUE, the transformation for the cairo context 
1360  * obtained from #GtkPrintContext puts the origin at the top left 
1361  * corner of the page (which may not be the top left corner of the 
1362  * sheet, depending on page orientation and the number of pages per 
1363  * sheet). Otherwise, the origin is at the top left corner of the
1364  * imageable area (i.e. inside the margins).
1365  * 
1366  * Since: 2.10 
1367  */
1368 void
1369 gtk_print_operation_set_use_full_page (GtkPrintOperation *op,
1370                                        gboolean           full_page)
1371 {
1372   GtkPrintOperationPrivate *priv;
1373
1374   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1375
1376   full_page = full_page != FALSE;
1377  
1378   priv = op->priv;
1379         
1380   if (priv->use_full_page != full_page)
1381     {
1382       priv->use_full_page = full_page;
1383    
1384       g_object_notify (G_OBJECT (op), "use-full-page");
1385     }
1386 }
1387
1388 /**
1389  * gtk_print_operation_set_unit:
1390  * @op: a #GtkPrintOperation
1391  * @unit: the unit to use
1392  * 
1393  * Sets up the transformation for the cairo context obtained from
1394  * #GtkPrintContext in such a way that distances are measured in 
1395  * units of @unit.
1396  *
1397  * Since: 2.10
1398  */
1399 void
1400 gtk_print_operation_set_unit (GtkPrintOperation *op,
1401                               GtkUnit            unit)
1402 {
1403   GtkPrintOperationPrivate *priv;
1404
1405   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1406
1407   priv = op->priv;
1408
1409   if (priv->unit != unit)
1410     {
1411       priv->unit = unit;
1412
1413       g_object_notify (G_OBJECT (op), "unit");
1414     }
1415 }
1416
1417 /**
1418  * gtk_print_operation_set_track_print_status:
1419  * @op: a #GtkPrintOperation
1420  * @track_status: %TRUE to track status after printing
1421  * 
1422  * If track_status is %TRUE, the print operation will try to continue report
1423  * on the status of the print job in the printer queues and printer. This
1424  * can allow your application to show things like "out of paper" issues,
1425  * and when the print job actually reaches the printer.
1426  * 
1427  * This function is often implemented using some form of polling, so it should
1428  * not be enabled unless needed.
1429  *
1430  * Since: 2.10
1431  */
1432 void
1433 gtk_print_operation_set_track_print_status (GtkPrintOperation  *op,
1434                                             gboolean            track_status)
1435 {
1436   GtkPrintOperationPrivate *priv;
1437
1438   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1439
1440   priv = op->priv;
1441
1442   if (priv->track_print_status != track_status)
1443     {
1444       priv->track_print_status = track_status;
1445
1446       g_object_notify (G_OBJECT (op), "track-print-status");
1447     }
1448 }
1449
1450 void
1451 _gtk_print_operation_set_status (GtkPrintOperation *op,
1452                                  GtkPrintStatus     status,
1453                                  const gchar       *string)
1454 {
1455   GtkPrintOperationPrivate *priv = op->priv;
1456   static const gchar *status_strs[] = {
1457     /* translators, strip the prefix up to and including the first | */
1458     N_("print operation status|Initial state"),
1459     /* translators, strip the prefix up to and including the first | */
1460     N_("print operation status|Preparing to print"),
1461     /* translators, strip the prefix up to and including the first | */
1462     N_("print operation status|Generating data"),
1463     /* translators, strip the prefix up to and including the first | */
1464     N_("print operation status|Sending data"),
1465     /* translators, strip the prefix up to and including the first | */
1466     N_("print operation status|Waiting"),
1467     /* translators, strip the prefix up to and including the first | */
1468     N_("print operation status|Blocking on issue"),
1469     /* translators, strip the prefix up to and including the first | */
1470     N_("print operation status|Printing"),
1471     /* translators, strip the prefix up to and including the first | */
1472     N_("print operation status|Finished"),
1473     /* translators, strip the prefix up to and including the first | */
1474     N_("print operation status|Finished with error")
1475   };
1476
1477   if (status < 0 || status > GTK_PRINT_STATUS_FINISHED_ABORTED)
1478     status = GTK_PRINT_STATUS_FINISHED_ABORTED;
1479
1480   if (string == NULL)
1481     string = g_strip_context (status_strs[status],
1482                               gettext (status_strs[status]));
1483   
1484   if (priv->status == status &&
1485       strcmp (string, priv->status_string) == 0)
1486     return;
1487   
1488   g_free (priv->status_string);
1489   priv->status_string = g_strdup (string);
1490   priv->status = status;
1491
1492   g_object_notify (G_OBJECT (op), "status");
1493   g_object_notify (G_OBJECT (op), "status-string");
1494
1495   g_signal_emit (op, signals[STATUS_CHANGED], 0);
1496 }
1497
1498
1499 /**
1500  * gtk_print_operation_get_status:
1501  * @op: a #GtkPrintOperation
1502  * 
1503  * Returns the status of the print operation. 
1504  * Also see gtk_print_operation_get_status_string().
1505  * 
1506  * Return value: the status of the print operation
1507  *
1508  * Since: 2.10
1509  **/
1510 GtkPrintStatus
1511 gtk_print_operation_get_status (GtkPrintOperation *op)
1512 {
1513   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
1514                         GTK_PRINT_STATUS_FINISHED_ABORTED);
1515
1516   return op->priv->status;
1517 }
1518
1519 /**
1520  * gtk_print_operation_get_status_string:
1521  * @op: a #GtkPrintOperation
1522  * 
1523  * Returns a string representation of the status of the 
1524  * print operation. The string is translated and suitable
1525  * for displaying the print status e.g. in a #GtkStatusbar.
1526  *
1527  * Use gtk_print_operation_get_status() to obtain a status
1528  * value that is suitable for programmatic use. 
1529  * 
1530  * Return value: a string representation of the status
1531  *    of the print operation
1532  *
1533  * Since: 2.10
1534  **/
1535 G_CONST_RETURN gchar *
1536 gtk_print_operation_get_status_string (GtkPrintOperation *op)
1537 {
1538   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), "");
1539
1540   return op->priv->status_string;
1541 }
1542
1543 /**
1544  * gtk_print_operation_is_finished:
1545  * @op: a #GtkPrintOperation
1546  * 
1547  * A convenience function to find out if the print operation
1548  * is finished, either successfully (%GTK_PRINT_STATUS_FINISHED)
1549  * or unsuccessfully (%GTK_PRINT_STATUS_FINISHED_ABORTED).
1550  * 
1551  * Note: when you enable print status tracking the print operation
1552  * can be in a non-finished state even after done has been called, as
1553  * the operation status then tracks the print job status on the printer.
1554  * 
1555  * Return value: %TRUE, if the print operation is finished.
1556  *
1557  * Since: 2.10
1558  **/
1559 gboolean
1560 gtk_print_operation_is_finished (GtkPrintOperation *op)
1561 {
1562   GtkPrintOperationPrivate *priv;
1563
1564   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), TRUE);
1565
1566   priv = op->priv;
1567   return
1568     priv->status == GTK_PRINT_STATUS_FINISHED_ABORTED ||
1569     priv->status == GTK_PRINT_STATUS_FINISHED;
1570 }
1571
1572 /**
1573  * gtk_print_operation_set_show_progress:
1574  * @op: a #GtkPrintOperation
1575  * @show_progress: %TRUE to show a progress dialog
1576  * 
1577  * If @show_progress is %TRUE, the print operation will show a 
1578  * progress dialog during the print operation.
1579  * 
1580  * Since: 2.10
1581  */
1582 void
1583 gtk_print_operation_set_show_progress (GtkPrintOperation  *op,
1584                                        gboolean            show_progress)
1585 {
1586   GtkPrintOperationPrivate *priv;
1587
1588   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1589
1590   priv = op->priv;
1591
1592   show_progress = show_progress != FALSE;
1593
1594   if (priv->show_progress != show_progress)
1595     {
1596       priv->show_progress = show_progress;
1597
1598       g_object_notify (G_OBJECT (op), "show-progress");
1599     }
1600 }
1601
1602 /**
1603  * gtk_print_operation_set_allow_async:
1604  * @op: a #GtkPrintOperation
1605  * @allow_async: %TRUE to allow asynchronous operation
1606  *
1607  * Sets whether the gtk_print_operation_run() may return
1608  * before the print operation is completed. Note that
1609  * some platforms may not allow asynchronous operation.
1610  *
1611  * Since: 2.10
1612  */
1613 void
1614 gtk_print_operation_set_allow_async (GtkPrintOperation  *op,
1615                                      gboolean            allow_async)
1616 {
1617   GtkPrintOperationPrivate *priv;
1618
1619   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1620
1621   priv = op->priv;
1622
1623   allow_async = allow_async != FALSE;
1624
1625   if (priv->allow_async != allow_async)
1626     {
1627       priv->allow_async = allow_async;
1628
1629       g_object_notify (G_OBJECT (op), "allow-async");
1630     }
1631 }
1632
1633
1634 /**
1635  * gtk_print_operation_set_custom_tab_label:
1636  * @op: a #GtkPrintOperation
1637  * @label: the label to use, or %NULL to use the default label
1638  *
1639  * Sets the label for the tab holding custom widgets.
1640  *
1641  * Since: 2.10
1642  */
1643 void
1644 gtk_print_operation_set_custom_tab_label (GtkPrintOperation  *op,
1645                                           const gchar        *label)
1646 {
1647   GtkPrintOperationPrivate *priv;
1648
1649   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1650
1651   priv = op->priv;
1652
1653   g_free (priv->custom_tab_label);
1654   priv->custom_tab_label = g_strdup (label);
1655
1656   g_object_notify (G_OBJECT (op), "custom-tab-label");
1657 }
1658
1659
1660 /**
1661  * gtk_print_operation_set_export_filename:
1662  * @op: a #GtkPrintOperation
1663  * @filename: the filename for the exported file
1664  * 
1665  * Sets up the #GtkPrintOperation to generate a file instead
1666  * of showing the print dialog. The indended use of this function
1667  * is for implementing "Export to PDF" actions. Currently, PDF
1668  * is the only supported format.
1669  *
1670  * "Print to PDF" support is independent of this and is done
1671  * by letting the user pick the "Print to PDF" item from the list
1672  * of printers in the print dialog.
1673  *
1674  * Since: 2.10
1675  */
1676 void
1677 gtk_print_operation_set_export_filename (GtkPrintOperation *op,
1678                                          const gchar       *filename)
1679 {
1680   GtkPrintOperationPrivate *priv;
1681
1682   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1683
1684   priv = op->priv;
1685
1686   g_free (priv->export_filename);
1687   priv->export_filename = g_strdup (filename);
1688
1689   g_object_notify (G_OBJECT (op), "export_filename");
1690 }
1691
1692 /* Creates the initial page setup used for printing unless the
1693  * app overrides this on a per-page basis using request_page_setup.
1694  *
1695  * Data is taken from, in order, if existing:
1696  *
1697  * PrintSettings returned from the print dialog
1698  *  (initial dialog values are set from default_page_setup
1699  *   if unset in app specified print_settings)
1700  * default_page_setup
1701  * per-locale default setup
1702  */
1703 static GtkPageSetup *
1704 create_page_setup (GtkPrintOperation *op)
1705 {
1706   GtkPrintOperationPrivate *priv = op->priv;
1707   GtkPageSetup *page_setup;
1708   GtkPrintSettings *settings;
1709   
1710   if (priv->default_page_setup)
1711     page_setup = gtk_page_setup_copy (priv->default_page_setup);
1712   else
1713     page_setup = gtk_page_setup_new ();
1714
1715   settings = priv->print_settings;
1716   if (settings)
1717     {
1718       GtkPaperSize *paper_size;
1719       
1720       if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
1721         gtk_page_setup_set_orientation (page_setup,
1722                                         gtk_print_settings_get_orientation (settings));
1723
1724
1725       paper_size = gtk_print_settings_get_paper_size (settings);
1726       if (paper_size)
1727         {
1728           gtk_page_setup_set_paper_size (page_setup, paper_size);
1729           gtk_paper_size_free (paper_size);
1730         }
1731
1732       /* TODO: Margins? */
1733     }
1734   
1735   return page_setup;
1736 }
1737
1738 static void 
1739 pdf_start_page (GtkPrintOperation *op,
1740                 GtkPrintContext   *print_context,
1741                 GtkPageSetup      *page_setup)
1742 {
1743   GtkPaperSize *paper_size;
1744   cairo_surface_t *surface = op->priv->platform_data;
1745   gdouble w, h;
1746
1747   paper_size = gtk_page_setup_get_paper_size (page_setup);
1748
1749   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
1750   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
1751   
1752   cairo_pdf_surface_set_size (surface, w, h);
1753 }
1754
1755 static void
1756 pdf_end_page (GtkPrintOperation *op,
1757               GtkPrintContext   *print_context)
1758 {
1759   cairo_t *cr;
1760
1761   cr = gtk_print_context_get_cairo_context (print_context);
1762   cairo_show_page (cr);
1763 }
1764
1765 static void
1766 pdf_end_run (GtkPrintOperation *op,
1767              gboolean           wait,
1768              gboolean           cancelled)
1769 {
1770   GtkPrintOperationPrivate *priv = op->priv;
1771   cairo_surface_t *surface = priv->platform_data;
1772
1773   cairo_surface_finish (surface);
1774   cairo_surface_destroy (surface);
1775 }
1776
1777 static GtkPrintOperationResult
1778 run_pdf (GtkPrintOperation  *op,
1779          GtkWindow          *parent,
1780          gboolean           *do_print)
1781 {
1782   GtkPrintOperationPrivate *priv = op->priv;
1783   GtkPageSetup *page_setup;
1784   cairo_surface_t *surface;
1785   cairo_t *cr;
1786   gdouble width, height;
1787   
1788   priv->print_context = _gtk_print_context_new (op);
1789   
1790   page_setup = create_page_setup (op);
1791   _gtk_print_context_set_page_setup (priv->print_context, page_setup);
1792
1793   /* This will be overwritten later by the non-default size, but
1794      we need to pass some size: */
1795   width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1796   height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1797   g_object_unref (page_setup);
1798   
1799   surface = cairo_pdf_surface_create (priv->export_filename,
1800                                       width, height);
1801   cairo_surface_set_fallback_resolution (surface, 300, 300);
1802
1803   priv->platform_data = surface;
1804   priv->free_platform_data = (GDestroyNotify) cairo_surface_destroy;
1805
1806   cr = cairo_create (surface);
1807   gtk_print_context_set_cairo_context (op->priv->print_context,
1808                                        cr, 72, 72);
1809   cairo_destroy (cr);
1810
1811   
1812   priv->print_pages = GTK_PRINT_PAGES_ALL;
1813   priv->page_ranges = NULL;
1814   priv->num_page_ranges = 0;
1815
1816   priv->manual_num_copies = 1;
1817   priv->manual_collation = FALSE;
1818   priv->manual_reverse = FALSE;
1819   priv->manual_page_set = GTK_PAGE_SET_ALL;
1820   priv->manual_scale = 1.0;
1821   priv->manual_orientation = TRUE;
1822   
1823   *do_print = TRUE;
1824   
1825   priv->start_page = pdf_start_page;
1826   priv->end_page = pdf_end_page;
1827   priv->end_run = pdf_end_run;
1828   
1829   return GTK_PRINT_OPERATION_RESULT_APPLY; 
1830 }
1831
1832 typedef struct
1833 {
1834   GtkPrintOperation *op;
1835   gint uncollated_copies;
1836   gint collated_copies;
1837   gint uncollated, collated, total;
1838
1839   gint range, num_ranges;
1840   GtkPageRange *ranges;
1841   GtkPageRange one_range;
1842
1843   gint page, start, end, inc;
1844
1845   GtkWidget *progress;
1846  
1847   gboolean initialized;
1848   gboolean is_preview; 
1849 } PrintPagesData;
1850
1851 static void
1852 find_range (PrintPagesData *data)
1853 {
1854   GtkPageRange *range;
1855
1856   range = &data->ranges[data->range];
1857
1858   if (data->inc < 0)
1859     {
1860       data->start = range->end;
1861       data->end = range->start - 1;
1862     }
1863   else
1864     {
1865       data->start = range->start;
1866       data->end = range->end + 1;
1867     }
1868 }
1869
1870 static gboolean 
1871 increment_page_sequence (PrintPagesData *data)
1872 {
1873   GtkPrintOperationPrivate *priv = data->op->priv;
1874
1875   do {
1876     data->page += data->inc;
1877     if (data->page == data->end)
1878       {
1879         data->range += data->inc;
1880         if (data->range == -1 || data->range == data->num_ranges)
1881           {
1882             data->uncollated++;
1883             if (data->uncollated == data->uncollated_copies)
1884               return FALSE;
1885
1886             data->range = data->inc < 0 ? data->num_ranges - 1 : 0;
1887           }
1888         find_range (data);
1889         data->page = data->start;
1890       }
1891   }
1892   while ((priv->manual_page_set == GTK_PAGE_SET_EVEN && data->page % 2 == 0) ||
1893          (priv->manual_page_set == GTK_PAGE_SET_ODD && data->page % 2 == 1));
1894
1895   return TRUE;
1896 }
1897
1898 static void
1899 print_pages_idle_done (gpointer user_data)
1900 {
1901   PrintPagesData *data;
1902   GtkPrintOperationPrivate *priv;
1903
1904   GDK_THREADS_ENTER ();
1905
1906   data = (PrintPagesData*)user_data;
1907   priv = data->op->priv;
1908
1909   priv->print_pages_idle_id = 0;
1910
1911   if (priv->show_progress_timeout_id > 0)
1912     {
1913       g_source_remove (priv->show_progress_timeout_id);
1914       priv->show_progress_timeout_id = 0;
1915     }
1916  
1917   if (data->progress)
1918     gtk_widget_destroy (data->progress);
1919
1920   if (priv->rloop && !data->is_preview) 
1921     g_main_loop_quit (priv->rloop);
1922
1923   if (!data->is_preview)
1924     g_signal_emit (data->op, signals[DONE], 0,
1925                    priv->cancelled ?
1926                    GTK_PRINT_OPERATION_RESULT_CANCEL :
1927                    GTK_PRINT_OPERATION_RESULT_APPLY);
1928   
1929   g_object_unref (data->op);
1930
1931   g_free (data);
1932
1933   GDK_THREADS_LEAVE ();
1934 }
1935
1936 static void
1937 update_progress (PrintPagesData *data)
1938 {
1939   GtkPrintOperationPrivate *priv; 
1940   gchar *text = NULL;
1941   
1942   priv = data->op->priv;
1943  
1944   if (data->progress)
1945     {
1946       if (priv->status == GTK_PRINT_STATUS_PREPARING)
1947         {
1948           if (priv->nr_of_pages > 0)
1949             text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages);
1950           else
1951             text = g_strdup (_("Preparing"));
1952         }
1953       else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA)
1954         text = g_strdup_printf (_("Printing %d"), data->total);
1955       
1956       if (text)
1957         {
1958           g_object_set (data->progress, "text", text, NULL);
1959           g_free (text);
1960         }
1961     }
1962  }
1963
1964 static void
1965 common_render_page (GtkPrintOperation *op,
1966                     gint               page_nr)
1967 {
1968   GtkPrintOperationPrivate *priv = op->priv;
1969   GtkPageSetup *page_setup;
1970   GtkPrintContext *print_context;
1971   cairo_t *cr;
1972
1973   print_context = priv->print_context;
1974   
1975   page_setup = create_page_setup (op);
1976   
1977   g_signal_emit (op, signals[REQUEST_PAGE_SETUP], 0, 
1978                  print_context, page_nr, page_setup);
1979   
1980   _gtk_print_context_set_page_setup (print_context, page_setup);
1981   
1982   priv->start_page (op, print_context, page_setup);
1983   
1984   cr = gtk_print_context_get_cairo_context (print_context);
1985   
1986   cairo_save (cr);
1987   if (priv->manual_scale != 1.0)
1988     cairo_scale (cr,
1989                  priv->manual_scale,
1990                  priv->manual_scale);
1991   
1992   if (priv->manual_orientation)
1993     _gtk_print_context_rotate_according_to_orientation (print_context);
1994   
1995   if (!priv->use_full_page)
1996     _gtk_print_context_translate_into_margin (print_context);
1997   
1998   g_signal_emit (op, signals[DRAW_PAGE], 0, 
1999                  print_context, page_nr);
2000
2001   priv->end_page (op, print_context);
2002   
2003   cairo_restore (cr);
2004
2005   g_object_unref (page_setup);
2006 }
2007
2008 static gboolean
2009 print_pages_idle (gpointer user_data)
2010 {
2011   PrintPagesData *data; 
2012   GtkPrintOperationPrivate *priv; 
2013   GtkPageSetup *page_setup;
2014   gboolean done = FALSE;
2015
2016   GDK_THREADS_ENTER ();
2017
2018   data = (PrintPagesData*)user_data;
2019   priv = data->op->priv;
2020
2021   if (priv->status == GTK_PRINT_STATUS_PREPARING)
2022     {
2023       if (!data->initialized)
2024         {
2025           data->initialized = TRUE;
2026           page_setup = create_page_setup (data->op);
2027           _gtk_print_context_set_page_setup (priv->print_context, 
2028                                              page_setup);
2029           g_object_unref (page_setup);
2030       
2031           g_signal_emit (data->op, signals[BEGIN_PRINT], 0, priv->print_context);
2032       
2033           if (priv->manual_collation)
2034             {
2035               data->uncollated_copies = priv->manual_num_copies;
2036               data->collated_copies = 1;
2037             }
2038           else
2039             {
2040               data->uncollated_copies = 1;
2041               data->collated_copies = priv->manual_num_copies;
2042             }
2043
2044           goto out;
2045         }
2046       
2047       if (g_signal_has_handler_pending (data->op, signals[PAGINATE], 0, FALSE))
2048         {
2049           gboolean paginated = FALSE;
2050
2051           g_signal_emit (data->op, signals[PAGINATE], 0, priv->print_context, &paginated);
2052           if (!paginated)
2053             goto out;
2054         }
2055
2056       /* FIXME handle this better */
2057       if (priv->nr_of_pages == 0)
2058         g_warning ("no pages to print");
2059       
2060       /* Initialize parts of PrintPagesData that depend on nr_of_pages
2061        */
2062       if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
2063         {
2064           data->ranges = priv->page_ranges;
2065           data->num_ranges = priv->num_page_ranges;
2066         }
2067       else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
2068                priv->current_page != -1)
2069         {
2070           data->ranges = &data->one_range;
2071           data->num_ranges = 1;
2072           data->ranges[0].start = priv->current_page;
2073           data->ranges[0].end = priv->current_page;
2074         }
2075       else
2076         {
2077           data->ranges = &data->one_range;
2078           data->num_ranges = 1;
2079           data->ranges[0].start = 0;
2080           data->ranges[0].end = priv->nr_of_pages - 1;
2081         }
2082       
2083       if (priv->manual_reverse)
2084         {
2085           data->range = data->num_ranges - 1;
2086           data->inc = -1;      
2087         }
2088       else
2089         {
2090           data->range = 0;
2091           data->inc = 1;      
2092         }
2093       find_range (data);
2094      
2095       /* go back one page, since we preincrement below */
2096       data->page = data->start - data->inc;
2097       data->collated = data->collated_copies - 1;
2098
2099       _gtk_print_operation_set_status (data->op, 
2100                                        GTK_PRINT_STATUS_GENERATING_DATA, 
2101                                        NULL);
2102
2103       goto out;
2104     }
2105
2106   data->total++;
2107   data->collated++;
2108   if (data->collated == data->collated_copies)
2109     {
2110       data->collated = 0;
2111       if (!increment_page_sequence (data))
2112         {
2113           done = TRUE;
2114
2115           goto out;
2116         }
2117     }
2118  
2119   if (data->is_preview)
2120     {
2121       done = TRUE;
2122
2123       g_object_ref (data->op);
2124       
2125       g_signal_emit_by_name (data->op, "ready", priv->print_context);
2126       goto out;
2127     }
2128
2129   common_render_page (data->op, data->page);
2130
2131  out:
2132
2133   if (priv->cancelled)
2134     {
2135       _gtk_print_operation_set_status (data->op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2136       
2137       done = TRUE;
2138     }
2139
2140   if (done && !data->is_preview)
2141     {
2142       g_signal_emit (data->op, signals[END_PRINT], 0, priv->print_context);
2143       priv->end_run (data->op, priv->is_sync, priv->cancelled);
2144     }
2145
2146   update_progress (data);
2147
2148   GDK_THREADS_LEAVE ();
2149
2150   return !done;
2151 }
2152   
2153 static void
2154 handle_progress_response (GtkWidget *dialog, 
2155                           gint       response,
2156                           gpointer   data)
2157 {
2158   GtkPrintOperation *op = (GtkPrintOperation *)data;
2159
2160   gtk_widget_hide (dialog);
2161   gtk_print_operation_cancel (op);
2162 }
2163
2164 static gboolean
2165 show_progress_timeout (PrintPagesData *data)
2166 {
2167   GDK_THREADS_ENTER ();
2168
2169   gtk_window_present (GTK_WINDOW (data->progress));
2170
2171   data->op->priv->show_progress_timeout_id = 0;
2172
2173   GDK_THREADS_LEAVE ();
2174
2175   return FALSE;
2176 }
2177
2178 static void
2179 print_pages (GtkPrintOperation       *op,
2180              GtkWindow               *parent,
2181              gboolean                 do_print,
2182              GtkPrintOperationResult  result)
2183 {
2184   GtkPrintOperationPrivate *priv = op->priv;
2185   PrintPagesData *data;
2186  
2187   if (!do_print) 
2188     {
2189       _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2190       g_signal_emit (op, signals[DONE], 0, result);
2191       return;
2192   }
2193   
2194   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);  
2195
2196   data = g_new0 (PrintPagesData, 1);
2197   data->op = g_object_ref (op);
2198   data->is_preview = (priv->action == GTK_PRINT_OPERATION_ACTION_PREVIEW);
2199
2200   if (priv->show_progress)
2201     {
2202       GtkWidget *progress;
2203
2204       progress = gtk_message_dialog_new (parent, 0, 
2205                                          GTK_MESSAGE_OTHER,
2206                                          GTK_BUTTONS_CANCEL,
2207                                          _("Preparing"));
2208       g_signal_connect (progress, "response", 
2209                         G_CALLBACK (handle_progress_response), op);
2210
2211       priv->show_progress_timeout_id = 
2212         g_timeout_add (SHOW_PROGRESS_TIME, 
2213                        (GSourceFunc)show_progress_timeout,
2214                        data);
2215
2216       data->progress = progress;
2217     }
2218
2219   if (data->is_preview)
2220     {
2221       gboolean handled;
2222       
2223       g_signal_emit_by_name (op, "preview",
2224                              GTK_PRINT_OPERATION_PREVIEW (op),
2225                              priv->print_context,
2226                              parent,
2227                              &handled);
2228       
2229       if (!handled ||
2230           gtk_print_context_get_cairo_context (priv->print_context) == NULL) 
2231         {
2232           /* Programmer error */
2233           g_error ("You must set a cairo context on the print context");
2234         }
2235       
2236       priv->start_page = preview_start_page;
2237       priv->end_page = preview_end_page;
2238       priv->end_run = preview_end_run;
2239
2240       priv->print_pages = gtk_print_settings_get_print_pages (priv->print_settings);
2241       priv->page_ranges = gtk_print_settings_get_page_ranges (priv->print_settings,
2242                                                               &priv->num_page_ranges);
2243       priv->manual_num_copies = 1;
2244       priv->manual_collation = FALSE;
2245       priv->manual_reverse = FALSE;
2246       priv->manual_page_set = GTK_PAGE_SET_ALL;
2247       priv->manual_scale = 1.0;
2248       priv->manual_orientation = TRUE;
2249     }
2250   
2251   priv->print_pages_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2252                                                print_pages_idle, 
2253                                                data, 
2254                                                print_pages_idle_done);
2255   
2256   /* Recursive main loop to make sure we don't exit  on sync operations  */
2257   if (priv->is_sync)
2258     {
2259       priv->rloop = g_main_loop_new (NULL, FALSE);
2260
2261       GDK_THREADS_LEAVE ();
2262       g_main_loop_run (priv->rloop);
2263       GDK_THREADS_ENTER ();
2264       
2265       g_main_loop_unref (priv->rloop);
2266       priv->rloop = NULL;
2267     }
2268 }
2269
2270 /**
2271  * gtk_print_operation_get_error:
2272  * @op: a #GtkPrintOperation
2273  * @error: return location for the error
2274  * 
2275  * Call this when the result of a print operation is
2276  * %GTK_PRINT_OPERATION_RESULT_ERROR, either as returned by 
2277  * gtk_print_operation_run(), or in the ::done signal handler. 
2278  * The returned #GError will contain more details on what went wrong.
2279  *
2280  * Since: 2.10
2281  **/
2282 void
2283 gtk_print_operation_get_error (GtkPrintOperation  *op,
2284                                GError            **error)
2285 {
2286   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
2287   
2288   g_propagate_error (error, op->priv->error);
2289
2290   op->priv->error = NULL;
2291 }
2292
2293
2294 /**
2295  * gtk_print_operation_run:
2296  * @op: a #GtkPrintOperation
2297  * @action: the action to start
2298  * @parent: Transient parent of the dialog, or %NULL
2299  * @error: Return location for errors, or %NULL
2300  * 
2301  * Runs the print operation, by first letting the user modify
2302  * print settings in the print dialog, and then print the
2303  * document.
2304  *
2305  * Normally that this function does not return until the rendering of all 
2306  * pages is complete. You can connect to the ::status-changed signal on
2307  * @op to obtain some information about the progress of the print operation. 
2308  * Furthermore, it may use a recursive mainloop to show the print dialog.
2309  *
2310  * If you call gtk_print_operation_set_allow_async() or set the allow-async
2311  * property the operation will run asyncronously if this is supported on the
2312  * platform. The ::done signal will be emitted with the operation results when
2313  * the operation is done (i.e. when the dialog is canceled, or when the print
2314  * succeeds or fails).
2315  *
2316  * <informalexample><programlisting>
2317  * if (settings != NULL)
2318  *   gtk_print_operation_set_print_settings (print, settings);
2319  *   
2320  * if (page_setup != NULL)
2321  *   gtk_print_operation_set_default_page_setup (print, page_setup);
2322  *   
2323  * g_signal_connect (print, "begin-print", 
2324  *                   G_CALLBACK (begin_print), &amp;data);
2325  * g_signal_connect (print, "draw-page", 
2326  *                   G_CALLBACK (draw_page), &amp;data);
2327  *  
2328  * res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, parent, &amp;error);
2329  *  
2330  * if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
2331  *  {
2332  *    error_dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
2333  *                                           GTK_DIALOG_DESTROY_WITH_PARENT,
2334  *                                           GTK_MESSAGE_ERROR,
2335  *                                           GTK_BUTTONS_CLOSE,
2336  *                                           "Error printing file:\n%s",
2337  *                                           error->message);
2338  *    g_signal_connect (error_dialog, "response", 
2339  *                      G_CALLBACK (gtk_widget_destroy), NULL);
2340  *    gtk_widget_show (error_dialog);
2341  *    g_error_free (error);
2342  *  }
2343  * else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
2344  *  {
2345  *    if (settings != NULL)
2346  *      g_object_unref (settings);
2347  *    settings = g_object_ref (gtk_print_operation_get_print_settings (print));
2348  *  }
2349  * </programlisting></informalexample>
2350  *
2351  * Return value: the result of the print operation. A return value of 
2352  *   %GTK_PRINT_OPERATION_RESULT_APPLY indicates that the printing was
2353  *   completed successfully. In this case, it is a good idea to obtain 
2354  *   the used print settings with gtk_print_operation_get_print_settings() 
2355  *   and store them for reuse with the next print operation. A value of
2356  *   %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS means the operation is running
2357  *   asynchronously, and will emit the ::done signal when done.
2358  *
2359  * Since: 2.10
2360  **/
2361 GtkPrintOperationResult
2362 gtk_print_operation_run (GtkPrintOperation        *op,
2363                          GtkPrintOperationAction   action,
2364                          GtkWindow                *parent,
2365                          GError                  **error)
2366 {
2367   GtkPrintOperationPrivate *priv;
2368   GtkPrintOperationResult result;
2369   GtkPageSetup *page_setup;
2370   gboolean do_print;
2371   
2372   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
2373                         GTK_PRINT_OPERATION_RESULT_ERROR);
2374
2375   priv = op->priv;
2376
2377   do_print = FALSE;
2378   priv->error = NULL;
2379   priv->action = action;
2380
2381   if (priv->print_settings == NULL)
2382     priv->print_settings = gtk_print_settings_new ();
2383   
2384   if (action == GTK_PRINT_OPERATION_ACTION_EXPORT)
2385     {
2386       priv->is_sync = TRUE;
2387       g_return_val_if_fail (priv->export_filename != NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
2388       result = run_pdf (op, parent, &do_print);
2389     }
2390   else if (action == GTK_PRINT_OPERATION_ACTION_PREVIEW)
2391     {
2392       priv->is_sync = !priv->allow_async;
2393       priv->print_context = _gtk_print_context_new (op);
2394       page_setup = create_page_setup (op);
2395       _gtk_print_context_set_page_setup (priv->print_context, page_setup);
2396       g_object_unref (page_setup);
2397       do_print = TRUE;
2398       result = priv->is_sync ? GTK_PRINT_OPERATION_RESULT_APPLY : GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
2399     }
2400 #ifndef G_OS_WIN32
2401   else if (priv->allow_async)
2402     {
2403       priv->is_sync = FALSE;
2404       _gtk_print_operation_platform_backend_run_dialog_async (op,
2405                                                               action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
2406                                                               parent,
2407                                                               print_pages);
2408       result = GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
2409     }
2410 #endif
2411   else
2412     {
2413       priv->is_sync = TRUE;
2414       result = _gtk_print_operation_platform_backend_run_dialog (op, 
2415                                                                  action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
2416                                                                  parent,
2417                                                                  &do_print);
2418     }
2419
2420   if (result != GTK_PRINT_OPERATION_RESULT_IN_PROGRESS)
2421     print_pages (op, parent, do_print, result);
2422
2423   if (priv->error && error)
2424     *error = g_error_copy (priv->error);
2425   
2426   return result;
2427 }
2428
2429 /**
2430  * gtk_print_operation_cancel:
2431  * @op: a #GtkPrintOperation
2432  *
2433  * Cancels a running print operation. This function may
2434  * be called from a begin-print, paginate or draw-page
2435  * signal handler to stop the currently running print 
2436  * operation.
2437  *
2438  * Since: 2.10
2439  */
2440 void
2441 gtk_print_operation_cancel (GtkPrintOperation *op)
2442 {
2443   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
2444   
2445   op->priv->cancelled = TRUE;
2446 }
2447
2448
2449
2450 #define __GTK_PRINT_OPERATION_C__
2451 #include "gtkaliasdef.c"