]> Pileus Git - ~andy/gtk/blob - gtk/gtkprintoperation.c
Update windows to build with new APIs and first cut at preview work.
[~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_PDF_TARGET,
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->pdf_target);
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->pdf_target = 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_PDF_TARGET:
299       gtk_print_operation_set_pdf_target (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_PDF_TARGET:
352       g_value_set_string (value, priv->pdf_target);
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,
422                                                           cr);
423   
424   /* TODO: print out sheets not pages and follow ranges */
425   pop->page_nr++;
426   if (op->priv->nr_of_pages <= pop->page_nr)
427     retval = FALSE;
428
429   GDK_THREADS_LEAVE ();
430
431   return retval;
432 }
433
434 static void
435 preview_got_page_size (GtkPrintOperationPreview *preview, 
436                        GtkPrintContext          *context,
437                        GtkPageSetup             *page_setup,
438                        PreviewOp                *pop)
439 {
440   GtkPrintOperation *op = GTK_PRINT_OPERATION (preview);
441   cairo_t *cr;
442
443   _gtk_print_operation_platform_backend_resize_preview_surface (op, page_setup, pop->surface);
444
445   cr = gtk_print_context_get_cairo_context (pop->print_context);
446   _gtk_print_operation_platform_backend_preview_start_page (op, pop->surface,
447                                                             cr);
448
449 }
450
451 static void
452 preview_ready (GtkPrintOperationPreview *preview,
453                GtkPrintContext          *context,
454                PreviewOp                *pop)
455 {
456   pop->page_nr = 0;
457   pop->print_context = context;
458
459   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
460                    preview_print_idle,
461                    pop,
462                    preview_print_idle_done);
463 }
464
465
466 static gboolean
467 gtk_print_operation_preview_handler (GtkPrintOperation        *op,
468                                      GtkPrintOperationPreview *preview, 
469                                      GtkPrintContext          *context,
470                                      GtkWindow                *parent)
471 {
472   gdouble dpi_x, dpi_y;
473   PreviewOp *pop;
474   GtkPageSetup *page_setup;
475   cairo_t *cr;
476
477   pop = g_new0 (PreviewOp, 1);
478   pop->filename = NULL;
479   pop->preview = preview;
480   pop->parent = parent;
481
482   page_setup = gtk_print_context_get_page_setup (context);
483
484   pop->surface =
485     _gtk_print_operation_platform_backend_create_preview_surface (op,
486                                                                   page_setup,
487                                                                   &dpi_x, &dpi_y,
488                                                                   &pop->filename);
489
490   cr = cairo_create (pop->surface);
491   gtk_print_context_set_cairo_context (op->priv->print_context, cr,
492                                        dpi_x, dpi_y);
493   cairo_destroy (cr);
494
495   g_signal_connect (preview, "ready", (GCallback) preview_ready, pop);
496   g_signal_connect (preview, "got-page-size", (GCallback) preview_got_page_size, pop);
497   
498   return TRUE;
499 }
500
501 static GtkWidget *
502 gtk_print_operation_create_custom_widget (GtkPrintOperation *operation)
503 {
504   return NULL;
505 }
506
507 static gboolean
508 custom_widget_accumulator (GSignalInvocationHint *ihint,
509                            GValue                *return_accu,
510                            const GValue          *handler_return,
511                            gpointer               dummy)
512 {
513   gboolean continue_emission;
514   GtkWidget *widget;
515   
516   widget = g_value_get_pointer (handler_return);
517   if (widget != NULL)
518     g_value_set_pointer (return_accu, widget);
519   continue_emission = (widget == NULL);
520   
521   return continue_emission;
522 }
523
524 static void
525 gtk_print_operation_class_init (GtkPrintOperationClass *class)
526 {
527   GObjectClass *gobject_class = (GObjectClass *)class;
528
529   gobject_class->set_property = gtk_print_operation_set_property;
530   gobject_class->get_property = gtk_print_operation_get_property;
531   gobject_class->finalize = gtk_print_operation_finalize;
532  
533   class->preview = gtk_print_operation_preview_handler; 
534   class->create_custom_widget = gtk_print_operation_create_custom_widget;
535   
536   g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
537
538   /**
539    * GtkPrintOperation::done:
540    * @operation: the #GtkPrintOperation on which the signal was emitted
541    * @result: the result of the print operation
542    *
543    * Emitted when the print operation run has finished doing
544    * everything required for printing. @result gives you information
545    * about what happened during the run. If @result is
546    * %GTK_PRINT_OPERATION_RESULT_ERROR then you can call
547    * gtk_print_operation_get_error() for more information.
548    *
549    * If you enabled print status tracking then 
550    * gtk_print_operation_is_finished() may still return %FALSE 
551    * after this was emitted.
552    *
553    * Since: 2.10
554    */
555   signals[DONE] =
556     g_signal_new (I_("done"),
557                   G_TYPE_FROM_CLASS (gobject_class),
558                   G_SIGNAL_RUN_LAST,
559                   G_STRUCT_OFFSET (GtkPrintOperationClass, done),
560                   NULL, NULL,
561                   g_cclosure_marshal_VOID__INT,
562                   G_TYPE_NONE, 1, G_TYPE_INT);
563
564   /**
565    * GtkPrintOperation::begin-print:
566    * @operation: the #GtkPrintOperation on which the signal was emitted
567    * @context: the #GtkPrintContext for the current operation
568    *
569    * Emitted after the user has finished changing print settings
570    * in the dialog, before the actual rendering starts. 
571    *
572    * A typical use for this signal is to use the parameters from the
573    * #GtkPrintContext and paginate the document accordingly, and then
574    * set the number of pages with gtk_print_operation_set_n_pages().
575    *
576    * Since: 2.10
577    */
578   signals[BEGIN_PRINT] =
579     g_signal_new (I_("begin-print"),
580                   G_TYPE_FROM_CLASS (gobject_class),
581                   G_SIGNAL_RUN_LAST,
582                   G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
583                   NULL, NULL,
584                   g_cclosure_marshal_VOID__OBJECT,
585                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
586
587    /**
588    * Gtkprintoperation::paginate:
589    * @operation: the #GtkPrintOperation on which the signal was emitted
590    * @context: the #GtkPrintContext for the current operation
591    *
592    * Emitted after the begin-print signal, but before the actual 
593    * rendering starts. It keeps getting emitted until it returns %FALSE. 
594    *
595    * This signal is intended to be used for paginating the document
596    * in small chunks, to avoid blocking the user interface for a long
597    * time. The signal handler should update the number of pages using
598    * gtk_print_operation_set_n_pages(), and return %TRUE if the document
599    * has been completely paginated.
600    *
601    * If you don't need to do pagination in chunks, you can simply do
602    * it all in the begin-print handler, and set the number of pages
603    * from there.
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_POINTER__VOID,
779                   G_TYPE_POINTER, 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_USE_FULL_PAGE,
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:pdf-target:
1034    *
1035    * The name of a PDF file to generate instead of showing 
1036    * the print dialog. 
1037    *
1038    * The intended use of this property is for implementing 
1039    * "Export to PDF" actions.
1040    *
1041    * "Print to PDF" support is independent of this and is done
1042    * by letting the user pick the "Print to PDF" item from the 
1043    * list of printers in the print dialog.
1044    *
1045    * Since: 2.10
1046    */
1047   g_object_class_install_property (gobject_class,
1048                                    PROP_JOB_NAME,
1049                                    g_param_spec_string ("pdf-target",
1050                                                         P_("PDF target filename"),
1051                                                         P_("PDF target filename"),
1052                                                         NULL,
1053                                                         GTK_PARAM_READWRITE));
1054   
1055   /**
1056    * GtkPrintOperation:status:
1057    *
1058    * The status of the print operation.
1059    * 
1060    * Since: 2.10
1061    */
1062   g_object_class_install_property (gobject_class,
1063                                    PROP_STATUS,
1064                                    g_param_spec_enum ("status",
1065                                                       P_("Status"),
1066                                                       P_("The status of the print operation"),
1067                                                       GTK_TYPE_PRINT_STATUS,
1068                                                       GTK_PRINT_STATUS_INITIAL,
1069                                                       GTK_PARAM_READABLE));
1070   
1071   /**
1072    * GtkPrintOperation:status-string:
1073    *
1074    * A string representation of the status of the print operation. 
1075    * The string is translated and suitable for displaying the print 
1076    * status e.g. in a #GtkStatusbar.
1077    *
1078    * See the ::status property for a status value that is suitable 
1079    * for programmatic use. 
1080    *
1081    * Since: 2.10
1082    */
1083   g_object_class_install_property (gobject_class,
1084                                    PROP_STATUS_STRING,
1085                                    g_param_spec_string ("status-string",
1086                                                         P_("Status String"),
1087                                                         P_("A human-readable description of the status"),
1088                                                         "",
1089                                                         GTK_PARAM_READABLE));
1090   
1091
1092   /**
1093    * GtkPrintOperation:custom-tab-label:
1094    *
1095    * Used as the label of the tab containing custom widgets.
1096    * Note that this property may be ignored on some platforms.
1097    * 
1098    * If this is %NULL, GTK+ uses a default label.
1099    *
1100    * Since: 2.10
1101    */
1102   g_object_class_install_property (gobject_class,
1103                                    PROP_CUSTOM_TAB_LABEL,
1104                                    g_param_spec_string ("custom-tab-label",
1105                                                         P_("Custom tab label"),
1106                                                         P_("Label for the tab containing custom widgets."),
1107                                                         NULL,
1108                                                         GTK_PARAM_READWRITE));
1109
1110 }
1111
1112 /**
1113  * gtk_print_operation_new:
1114  *
1115  * Creates a new #GtkPrintOperation. 
1116  *
1117  * Returns: a new #GtkPrintOperation
1118  *
1119  * Since: 2.10
1120  */
1121 GtkPrintOperation *
1122 gtk_print_operation_new (void)
1123 {
1124   GtkPrintOperation *print_operation;
1125
1126   print_operation = g_object_new (GTK_TYPE_PRINT_OPERATION, NULL);
1127   
1128   return print_operation;
1129 }
1130
1131 /**
1132  * gtk_print_operation_set_default_page_setup:
1133  * @op: a #GtkPrintOperation
1134  * @default_page_setup: a #GtkPageSetup, or %NULL
1135  * 
1136  * Makes @default_page_setup the default page setup for @op.
1137  *
1138  * This page setup will be used by gtk_print_operation_run(),
1139  * but it can be overridden on a per-page basis by connecting
1140  * to the ::request-page-setup signal.
1141  *
1142  * Since: 2.10
1143  **/
1144 void
1145 gtk_print_operation_set_default_page_setup (GtkPrintOperation *op,
1146                                             GtkPageSetup      *default_page_setup)
1147 {
1148   GtkPrintOperationPrivate *priv;
1149
1150   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1151   g_return_if_fail (default_page_setup == NULL || 
1152                     GTK_IS_PAGE_SETUP (default_page_setup));
1153
1154   priv = op->priv;
1155
1156   if (default_page_setup != priv->default_page_setup)
1157     {
1158       if (default_page_setup)
1159         g_object_ref (default_page_setup);
1160       
1161       if (priv->default_page_setup)
1162         g_object_unref (priv->default_page_setup);
1163       
1164       priv->default_page_setup = default_page_setup;
1165      
1166       g_object_notify (G_OBJECT (op), "default-page-setup");
1167     }
1168 }
1169
1170 /**
1171  * gtk_print_operation_get_default_page_setup:
1172  * @op: a #GtkPrintOperation
1173  *
1174  * Returns the default page setup, see 
1175  * gtk_print_operation_set_default_page_setup().
1176  *
1177  * Returns: the default page setup 
1178  *
1179  * Since: 2.10
1180  */
1181 GtkPageSetup *
1182 gtk_print_operation_get_default_page_setup (GtkPrintOperation *op)
1183 {
1184   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1185
1186   return op->priv->default_page_setup;
1187 }
1188
1189
1190 /**
1191  * gtk_print_operation_set_print_settings:
1192  * @op: a #GtkPrintOperation
1193  * @print_settings: #GtkPrintSettings, or %NULL
1194  * 
1195  * Sets the print settings for @op. This is typically used to
1196  * re-establish print settings from a previous print operation,
1197  * see gtk_print_operation_run().
1198  *
1199  * Since: 2.10
1200  **/
1201 void
1202 gtk_print_operation_set_print_settings (GtkPrintOperation *op,
1203                                         GtkPrintSettings  *print_settings)
1204 {
1205   GtkPrintOperationPrivate *priv;
1206
1207   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1208   g_return_if_fail (print_settings == NULL || 
1209                     GTK_IS_PRINT_SETTINGS (print_settings));
1210
1211   priv = op->priv;
1212
1213   if (print_settings != priv->print_settings)
1214     {
1215       if (print_settings)
1216         g_object_ref (print_settings);
1217
1218       if (priv->print_settings)
1219         g_object_unref (priv->print_settings);
1220   
1221       priv->print_settings = print_settings;
1222
1223       g_object_notify (G_OBJECT (op), "print-settings");
1224     }
1225 }
1226
1227 /**
1228  * gtk_print_operation_get_print_settings:
1229  * @op: a #GtkPrintOperation
1230  * 
1231  * Returns the current print settings. 
1232  *
1233  * Note that the return value is %NULL until either 
1234  * gtk_print_operation_set_print_settings() or 
1235  * gtk_print_operation_run() have been called.
1236  * 
1237  * Return value: the current print settings of @op.
1238  * 
1239  * Since: 2.10
1240  **/
1241 GtkPrintSettings *
1242 gtk_print_operation_get_print_settings (GtkPrintOperation *op)
1243 {
1244   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
1245
1246   return op->priv->print_settings;
1247 }
1248
1249 /**
1250  * gtk_print_operation_set_job_name:
1251  * @op: a #GtkPrintOperation
1252  * @job_name: a string that identifies the print job
1253  * 
1254  * Sets the name of the print job. The name is used to identify 
1255  * the job (e.g. in monitoring applications like eggcups). 
1256  * 
1257  * If you don't set a job name, GTK+ picks a default one by 
1258  * numbering successive print jobs.
1259  *
1260  * Since: 2.10
1261  **/
1262 void
1263 gtk_print_operation_set_job_name (GtkPrintOperation *op,
1264                                   const gchar       *job_name)
1265 {
1266   GtkPrintOperationPrivate *priv;
1267
1268   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1269   g_return_if_fail (g_utf8_validate (job_name, -1, NULL));
1270
1271   priv = op->priv;
1272
1273   g_free (priv->job_name);
1274   priv->job_name = g_strdup (job_name);
1275
1276   g_object_notify (G_OBJECT (op), "job-name");
1277 }
1278
1279 /**
1280  * gtk_print_operation_set_n_pages:
1281  * @op: a #GtkPrintOperation
1282  * @n_pages: the number of pages
1283  * 
1284  * Sets the number of pages in the document. 
1285  *
1286  * This <emphasis>must</emphasis> be set to a positive number
1287  * before the rendering starts. It may be set in a ::begin-print 
1288  * signal hander.
1289  *
1290  * Note that the page numbers passed to the ::request-page-setup 
1291  * and ::draw-page signals are 0-based, i.e. if the user chooses
1292  * to print all pages, the last ::draw-page signal will be
1293  * for page @n_pages - 1.
1294  *
1295  * Since: 2.10
1296  **/
1297 void
1298 gtk_print_operation_set_n_pages (GtkPrintOperation *op,
1299                                  gint               n_pages)
1300 {
1301   GtkPrintOperationPrivate *priv;
1302
1303   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1304   g_return_if_fail (n_pages > 0);
1305
1306   priv = op->priv;
1307   g_return_if_fail (priv->current_page == -1 || 
1308                     priv->current_page < n_pages);
1309
1310   if (priv->nr_of_pages != n_pages)
1311     {
1312       priv->nr_of_pages = n_pages;
1313
1314       g_object_notify (G_OBJECT (op), "n-pages");
1315     }
1316 }
1317
1318 /**
1319  * gtk_print_operation_set_current_page:
1320  * @op: a #GtkPrintOperation
1321  * @current_page: the current page, 0-based
1322  *
1323  * Sets the current page.
1324  *
1325  * If this is called before gtk_print_operation_run(), 
1326  * the user will be able to select to print only the current page.
1327  *
1328  * Note that this only makes sense for pre-paginated documents.
1329  * 
1330  * Since: 2.10
1331  **/
1332 void
1333 gtk_print_operation_set_current_page (GtkPrintOperation *op,
1334                                       gint               current_page)
1335 {
1336   GtkPrintOperationPrivate *priv;
1337
1338   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1339   g_return_if_fail (current_page >= 0);
1340
1341   priv = op->priv;
1342   g_return_if_fail (priv->nr_of_pages == -1 || 
1343                     current_page < priv->nr_of_pages);
1344
1345   if (priv->current_page != current_page)
1346     {
1347       priv->current_page = current_page;
1348
1349       g_object_notify (G_OBJECT (op), "current-page");
1350     }
1351 }
1352
1353 /**
1354  * gtk_print_operation_set_use_full_page:
1355  * @op: a #GtkPrintOperation
1356  * @full_page: %TRUE to set up the #GtkPrintContext for the full page
1357  * 
1358  * If @full_page is %TRUE, the transformation for the cairo context 
1359  * obtained from #GtkPrintContext puts the origin at the top left 
1360  * corner of the page (which may not be the top left corner of the 
1361  * sheet, depending on page orientation and the number of pages per 
1362  * sheet). Otherwise, the origin is at the top left corner of the
1363  * imageable area (i.e. inside the margins).
1364  * 
1365  * Since: 2.10 
1366  */
1367 void
1368 gtk_print_operation_set_use_full_page (GtkPrintOperation *op,
1369                                        gboolean           full_page)
1370 {
1371   GtkPrintOperationPrivate *priv;
1372
1373   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1374
1375   full_page = full_page != FALSE;
1376  
1377   priv = op->priv;
1378         
1379   if (priv->use_full_page != full_page)
1380     {
1381       priv->use_full_page = full_page;
1382    
1383       g_object_notify (G_OBJECT (op), "use-full-page");
1384     }
1385 }
1386
1387 /**
1388  * gtk_print_operation_set_unit:
1389  * @op: a #GtkPrintOperation
1390  * @unit: the unit to use
1391  * 
1392  * Sets up the transformation for the cairo context obtained from
1393  * #GtkPrintContext in such a way that distances are measured in 
1394  * units of @unit.
1395  *
1396  * Since: 2.10
1397  */
1398 void
1399 gtk_print_operation_set_unit (GtkPrintOperation *op,
1400                               GtkUnit            unit)
1401 {
1402   GtkPrintOperationPrivate *priv;
1403
1404   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1405
1406   priv = op->priv;
1407
1408   if (priv->unit != unit)
1409     {
1410       priv->unit = unit;
1411
1412       g_object_notify (G_OBJECT (op), "unit");
1413     }
1414 }
1415
1416 /**
1417  * gtk_print_operation_set_track_print_status:
1418  * @op: a #GtkPrintOperation
1419  * @track_status: %TRUE to track status after printing
1420  * 
1421  * If track_status is %TRUE, the print operation will try to continue report
1422  * on the status of the print job in the printer queues and printer. This
1423  * can allow your application to show things like "out of paper" issues,
1424  * and when the print job actually reaches the printer.
1425  * 
1426  * This function is often implemented using some form of polling, so it should
1427  * not be enabled unless needed.
1428  *
1429  * Since: 2.10
1430  */
1431 void
1432 gtk_print_operation_set_track_print_status (GtkPrintOperation  *op,
1433                                             gboolean            track_status)
1434 {
1435   GtkPrintOperationPrivate *priv;
1436
1437   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1438
1439   priv = op->priv;
1440
1441   if (priv->track_print_status != track_status)
1442     {
1443       priv->track_print_status = track_status;
1444
1445       g_object_notify (G_OBJECT (op), "track-print-status");
1446     }
1447 }
1448
1449 void
1450 _gtk_print_operation_set_status (GtkPrintOperation *op,
1451                                  GtkPrintStatus     status,
1452                                  const gchar       *string)
1453 {
1454   GtkPrintOperationPrivate *priv = op->priv;
1455   static const gchar *status_strs[] = {
1456     /* translators, strip the prefix up to and including the first | */
1457     N_("print operation status|Initial state"),
1458     /* translators, strip the prefix up to and including the first | */
1459     N_("print operation status|Preparing to print"),
1460     /* translators, strip the prefix up to and including the first | */
1461     N_("print operation status|Generating data"),
1462     /* translators, strip the prefix up to and including the first | */
1463     N_("print operation status|Sending data"),
1464     /* translators, strip the prefix up to and including the first | */
1465     N_("print operation status|Waiting"),
1466     /* translators, strip the prefix up to and including the first | */
1467     N_("print operation status|Blocking on issue"),
1468     /* translators, strip the prefix up to and including the first | */
1469     N_("print operation status|Printing"),
1470     /* translators, strip the prefix up to and including the first | */
1471     N_("print operation status|Finished"),
1472     /* translators, strip the prefix up to and including the first | */
1473     N_("print operation status|Finished with error")
1474   };
1475
1476   if (status < 0 || status > GTK_PRINT_STATUS_FINISHED_ABORTED)
1477     status = GTK_PRINT_STATUS_FINISHED_ABORTED;
1478
1479   if (string == NULL)
1480     string = g_strip_context (status_strs[status],
1481                               gettext (status_strs[status]));
1482   
1483   if (priv->status == status &&
1484       strcmp (string, priv->status_string) == 0)
1485     return;
1486   
1487   g_free (priv->status_string);
1488   priv->status_string = g_strdup (string);
1489   priv->status = status;
1490
1491   g_object_notify (G_OBJECT (op), "status");
1492   g_object_notify (G_OBJECT (op), "status-string");
1493
1494   g_signal_emit (op, signals[STATUS_CHANGED], 0);
1495 }
1496
1497
1498 /**
1499  * gtk_print_operation_get_status:
1500  * @op: a #GtkPrintOperation
1501  * 
1502  * Returns the status of the print operation. 
1503  * Also see gtk_print_operation_get_status_string().
1504  * 
1505  * Return value: the status of the print operation
1506  *
1507  * Since: 2.10
1508  **/
1509 GtkPrintStatus
1510 gtk_print_operation_get_status (GtkPrintOperation *op)
1511 {
1512   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
1513                         GTK_PRINT_STATUS_FINISHED_ABORTED);
1514
1515   return op->priv->status;
1516 }
1517
1518 /**
1519  * gtk_print_operation_get_status_string:
1520  * @op: a #GtkPrintOperation
1521  * 
1522  * Returns a string representation of the status of the 
1523  * print operation. The string is translated and suitable
1524  * for displaying the print status e.g. in a #GtkStatusbar.
1525  *
1526  * Use gtk_print_operation_get_status() to obtain a status
1527  * value that is suitable for programmatic use. 
1528  * 
1529  * Return value: a string representation of the status
1530  *    of the print operation
1531  *
1532  * Since: 2.10
1533  **/
1534 G_CONST_RETURN gchar *
1535 gtk_print_operation_get_status_string (GtkPrintOperation *op)
1536 {
1537   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), "");
1538
1539   return op->priv->status_string;
1540 }
1541
1542 /**
1543  * gtk_print_operation_is_finished:
1544  * @op: a #GtkPrintOperation
1545  * 
1546  * A convenience function to find out if the print operation
1547  * is finished, either successfully (%GTK_PRINT_STATUS_FINISHED)
1548  * or unsuccessfully (%GTK_PRINT_STATUS_FINISHED_ABORTED).
1549  * 
1550  * Note: when you enable print status tracking the print operation
1551  * can be in a non-finished state even after done has been called, as
1552  * the operation status then tracks the print job status on the printer.
1553  * 
1554  * Return value: %TRUE, if the print operation is finished.
1555  *
1556  * Since: 2.10
1557  **/
1558 gboolean
1559 gtk_print_operation_is_finished (GtkPrintOperation *op)
1560 {
1561   GtkPrintOperationPrivate *priv;
1562
1563   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), TRUE);
1564
1565   priv = op->priv;
1566   return
1567     priv->status == GTK_PRINT_STATUS_FINISHED_ABORTED ||
1568     priv->status == GTK_PRINT_STATUS_FINISHED;
1569 }
1570
1571 /**
1572  * gtk_print_operation_set_show_progress:
1573  * @op: a #GtkPrintOperation
1574  * @show_progress: %TRUE to show a progress dialog
1575  * 
1576  * If @show_progress is %TRUE, the print operation will show a 
1577  * progress dialog during the print operation.
1578  * 
1579  * Since: 2.10
1580  */
1581 void
1582 gtk_print_operation_set_show_progress (GtkPrintOperation  *op,
1583                                        gboolean            show_progress)
1584 {
1585   GtkPrintOperationPrivate *priv;
1586
1587   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1588
1589   priv = op->priv;
1590
1591   show_progress = show_progress != FALSE;
1592
1593   if (priv->show_progress != show_progress)
1594     {
1595       priv->show_progress = show_progress;
1596
1597       g_object_notify (G_OBJECT (op), "show-progress");
1598     }
1599 }
1600
1601 /**
1602  * gtk_print_operation_set_allow_async:
1603  * @op: a #GtkPrintOperation
1604  * @allow_async: %TRUE to allow asynchronous operation
1605  *
1606  * Sets whether the gtk_print_operation_run() may return
1607  * before the print operation is completed. Note that
1608  * some platforms may not allow asynchronous operation.
1609  *
1610  * Since: 2.10
1611  */
1612 void
1613 gtk_print_operation_set_allow_async (GtkPrintOperation  *op,
1614                                      gboolean            allow_async)
1615 {
1616   GtkPrintOperationPrivate *priv;
1617
1618   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1619
1620   priv = op->priv;
1621
1622   allow_async = allow_async != FALSE;
1623
1624   if (priv->allow_async != allow_async)
1625     {
1626       priv->allow_async = allow_async;
1627
1628       g_object_notify (G_OBJECT (op), "allow-async");
1629     }
1630 }
1631
1632
1633 /**
1634  * gtk_print_operation_set_custom_tag_label:
1635  * @op: a #GtkPrintOperation
1636  * @label: the label to use, or %NULL to use the default label
1637  *
1638  * Sets the label for the tab holding custom widgets.
1639  *
1640  * Since: 2.10
1641  */
1642 void
1643 gtk_print_operation_set_custom_tab_label (GtkPrintOperation  *op,
1644                                           const gchar        *label)
1645 {
1646   GtkPrintOperationPrivate *priv;
1647
1648   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1649
1650   priv = op->priv;
1651
1652   g_free (priv->custom_tab_label);
1653   priv->custom_tab_label = g_strdup (label);
1654
1655   g_object_notify (G_OBJECT (op), "custom-tab-label");
1656 }
1657
1658
1659 /**
1660  * gtk_print_operation_set_pdf_target:
1661  * @op: a #GtkPrintOperation
1662  * @filename: the filename for the PDF file
1663  * 
1664  * Sets up the #GtkPrintOperation to generate a PDF file instead
1665  * of showing the print dialog. The indended use of this function
1666  * is for implementing "Export to PDF" actions.
1667  *
1668  * "Print to PDF" support is independent of this and is done
1669  * by letting the user pick the "Print to PDF" item from the list
1670  * of printers in the print dialog.
1671  *
1672  * Since: 2.10
1673  */
1674 void
1675 gtk_print_operation_set_pdf_target (GtkPrintOperation *op,
1676                                     const gchar       *filename)
1677 {
1678   GtkPrintOperationPrivate *priv;
1679
1680   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1681
1682   priv = op->priv;
1683
1684   g_free (priv->pdf_target);
1685   priv->pdf_target = g_strdup (filename);
1686
1687   g_object_notify (G_OBJECT (op), "pdf-target");
1688 }
1689
1690 /* Creates the initial page setup used for printing unless the
1691  * app overrides this on a per-page basis using request_page_setup.
1692  *
1693  * Data is taken from, in order, if existing:
1694  *
1695  * PrintSettings returned from the print dialog
1696  *  (initial dialog values are set from default_page_setup
1697  *   if unset in app specified print_settings)
1698  * default_page_setup
1699  * per-locale default setup
1700  */
1701 static GtkPageSetup *
1702 create_page_setup (GtkPrintOperation *op)
1703 {
1704   GtkPrintOperationPrivate *priv = op->priv;
1705   GtkPageSetup *page_setup;
1706   GtkPrintSettings *settings;
1707   
1708   if (priv->default_page_setup)
1709     page_setup = gtk_page_setup_copy (priv->default_page_setup);
1710   else
1711     page_setup = gtk_page_setup_new ();
1712
1713   settings = priv->print_settings;
1714   if (settings)
1715     {
1716       GtkPaperSize *paper_size;
1717       
1718       if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
1719         gtk_page_setup_set_orientation (page_setup,
1720                                         gtk_print_settings_get_orientation (settings));
1721
1722
1723       paper_size = gtk_print_settings_get_paper_size (settings);
1724       if (paper_size)
1725         {
1726           gtk_page_setup_set_paper_size (page_setup, paper_size);
1727           gtk_paper_size_free (paper_size);
1728         }
1729
1730       /* TODO: Margins? */
1731     }
1732   
1733   return page_setup;
1734 }
1735
1736 static void 
1737 pdf_start_page (GtkPrintOperation *op,
1738                 GtkPrintContext   *print_context,
1739                 GtkPageSetup      *page_setup)
1740 {
1741   GtkPaperSize *paper_size;
1742   cairo_surface_t *surface = op->priv->platform_data;
1743   gdouble w, h;
1744
1745   paper_size = gtk_page_setup_get_paper_size (page_setup);
1746
1747   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
1748   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
1749   
1750   cairo_pdf_surface_set_size (surface, w, h);
1751 }
1752
1753 static void
1754 pdf_end_page (GtkPrintOperation *op,
1755               GtkPrintContext   *print_context)
1756 {
1757   cairo_t *cr;
1758
1759   cr = gtk_print_context_get_cairo_context (print_context);
1760   cairo_show_page (cr);
1761 }
1762
1763 static void
1764 pdf_end_run (GtkPrintOperation *op,
1765              gboolean           wait,
1766              gboolean           cancelled)
1767 {
1768   GtkPrintOperationPrivate *priv = op->priv;
1769   cairo_surface_t *surface = priv->platform_data;
1770
1771   cairo_surface_finish (surface);
1772   cairo_surface_destroy (surface);
1773 }
1774
1775 static GtkPrintOperationResult
1776 run_pdf (GtkPrintOperation  *op,
1777          GtkWindow          *parent,
1778          gboolean           *do_print)
1779 {
1780   GtkPrintOperationPrivate *priv = op->priv;
1781   GtkPageSetup *page_setup;
1782   cairo_surface_t *surface;
1783   cairo_t *cr;
1784   gdouble width, height;
1785   
1786   priv->print_context = _gtk_print_context_new (op);
1787   
1788   page_setup = create_page_setup (op);
1789   _gtk_print_context_set_page_setup (priv->print_context, page_setup);
1790
1791   /* This will be overwritten later by the non-default size, but
1792      we need to pass some size: */
1793   width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1794   height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1795   g_object_unref (page_setup);
1796   
1797   surface = cairo_pdf_surface_create (priv->pdf_target,
1798                                       width, height);
1799   cairo_pdf_surface_set_dpi (surface, 300, 300);
1800
1801   priv->platform_data = surface;
1802   priv->free_platform_data = (GDestroyNotify) cairo_surface_destroy;
1803
1804   cr = cairo_create (surface);
1805   gtk_print_context_set_cairo_context (op->priv->print_context,
1806                                        cr, 72, 72);
1807   cairo_destroy (cr);
1808
1809   
1810   priv->print_pages = GTK_PRINT_PAGES_ALL;
1811   priv->page_ranges = NULL;
1812   priv->num_page_ranges = 0;
1813
1814   priv->manual_num_copies = 1;
1815   priv->manual_collation = FALSE;
1816   priv->manual_reverse = FALSE;
1817   priv->manual_page_set = GTK_PAGE_SET_ALL;
1818   priv->manual_scale = 1.0;
1819   priv->manual_orientation = TRUE;
1820   
1821   *do_print = TRUE;
1822   
1823   priv->start_page = pdf_start_page;
1824   priv->end_page = pdf_end_page;
1825   priv->end_run = pdf_end_run;
1826   
1827   return GTK_PRINT_OPERATION_RESULT_APPLY; 
1828 }
1829
1830 typedef struct
1831 {
1832   GtkPrintOperation *op;
1833   gint uncollated_copies;
1834   gint collated_copies;
1835   gint uncollated, collated, total;
1836
1837   gint range, num_ranges;
1838   GtkPageRange *ranges;
1839   GtkPageRange one_range;
1840
1841   gint page, start, end, inc;
1842
1843   gboolean initialized;
1844
1845   GtkWidget *progress;
1846  
1847   gboolean is_preview; 
1848 } PrintPagesData;
1849
1850 static void
1851 find_range (PrintPagesData *data)
1852 {
1853   GtkPageRange *range;
1854
1855   range = &data->ranges[data->range];
1856
1857   if (data->inc < 0)
1858     {
1859       data->start = range->end;
1860       data->end = range->start - 1;
1861     }
1862   else
1863     {
1864       data->start = range->start;
1865       data->end = range->end + 1;
1866     }
1867 }
1868
1869 static gboolean 
1870 increment_page_sequence (PrintPagesData *data)
1871 {
1872   GtkPrintOperationPrivate *priv = data->op->priv;
1873
1874   do {
1875     data->page += data->inc;
1876     if (data->page == data->end)
1877       {
1878         data->range += data->inc;
1879         if (data->range == -1 || data->range == data->num_ranges)
1880           {
1881             data->uncollated++;
1882             if (data->uncollated == data->uncollated_copies)
1883               return FALSE;
1884
1885             data->range = data->inc < 0 ? data->num_ranges - 1 : 0;
1886           }
1887         find_range (data);
1888         data->page = data->start;
1889       }
1890   }
1891   while ((priv->manual_page_set == GTK_PAGE_SET_EVEN && data->page % 2 == 0) ||
1892          (priv->manual_page_set == GTK_PAGE_SET_ODD && data->page % 2 == 1));
1893
1894   return TRUE;
1895 }
1896
1897 static void
1898 print_pages_idle_done (gpointer user_data)
1899 {
1900   PrintPagesData *data;
1901   GtkPrintOperationPrivate *priv;
1902
1903   GDK_THREADS_ENTER ();
1904
1905   data = (PrintPagesData*)user_data;
1906   priv = data->op->priv;
1907
1908   priv->print_pages_idle_id = 0;
1909
1910   if (priv->show_progress_timeout_id > 0)
1911     {
1912       g_source_remove (priv->show_progress_timeout_id);
1913       priv->show_progress_timeout_id = 0;
1914     }
1915  
1916   if (data->progress)
1917     gtk_widget_destroy (data->progress);
1918
1919   if (priv->rloop && !data->is_preview) 
1920     g_main_loop_quit (priv->rloop);
1921
1922   if (!data->is_preview)
1923     g_signal_emit (data->op, signals[DONE], 0,
1924                    priv->cancelled ?
1925                    GTK_PRINT_OPERATION_RESULT_CANCEL :
1926                    GTK_PRINT_OPERATION_RESULT_APPLY);
1927   
1928   g_object_unref (data->op);
1929
1930   g_free (data);
1931
1932   GDK_THREADS_LEAVE ();
1933 }
1934
1935 static void
1936 update_progress (PrintPagesData *data)
1937 {
1938   GtkPrintOperationPrivate *priv; 
1939   gchar *text = NULL;
1940   
1941   priv = data->op->priv;
1942  
1943   if (data->progress)
1944     {
1945       if (priv->status == GTK_PRINT_STATUS_PREPARING)
1946         {
1947           if (priv->nr_of_pages > 0)
1948             text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages);
1949           else
1950             text = g_strdup (_("Preparing"));
1951         }
1952       else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA)
1953         text = g_strdup_printf (_("Printing %d"), data->total);
1954       
1955       if (text)
1956         {
1957           g_object_set (data->progress, "text", text, NULL);
1958           g_free (text);
1959         }
1960     }
1961  }
1962
1963 static void
1964 common_render_page (GtkPrintOperation *op,
1965                     gint               page_nr)
1966 {
1967   GtkPrintOperationPrivate *priv = op->priv;
1968   GtkPageSetup *page_setup;
1969   GtkPrintContext *print_context;
1970   cairo_t *cr;
1971
1972   print_context = priv->print_context;
1973   
1974   page_setup = create_page_setup (op);
1975   
1976   g_signal_emit (op, signals[REQUEST_PAGE_SETUP], 0, 
1977                  print_context, page_nr, page_setup);
1978   
1979   _gtk_print_context_set_page_setup (print_context, page_setup);
1980   
1981   priv->start_page (op, print_context, page_setup);
1982   
1983   cr = gtk_print_context_get_cairo_context (print_context);
1984   
1985   cairo_save (cr);
1986   if (priv->manual_scale != 1.0)
1987     cairo_scale (cr,
1988                  priv->manual_scale,
1989                  priv->manual_scale);
1990   
1991   if (priv->manual_orientation)
1992     _gtk_print_context_rotate_according_to_orientation (print_context);
1993   
1994   if (!priv->use_full_page)
1995     _gtk_print_context_translate_into_margin (print_context);
1996   
1997   g_signal_emit (op, signals[DRAW_PAGE], 0, 
1998                  print_context, page_nr);
1999
2000   priv->end_page (op, print_context);
2001   
2002   cairo_restore (cr);
2003
2004   g_object_unref (page_setup);
2005 }
2006
2007 static gboolean
2008 print_pages_idle (gpointer user_data)
2009 {
2010   PrintPagesData *data; 
2011   GtkPrintOperationPrivate *priv; 
2012   GtkPageSetup *page_setup;
2013   gboolean done = FALSE;
2014
2015   GDK_THREADS_ENTER ();
2016
2017   data = (PrintPagesData*)user_data;
2018   priv = data->op->priv;
2019
2020   if (priv->status == GTK_PRINT_STATUS_PREPARING)
2021     {
2022       if (!data->initialized)
2023         {
2024           data->initialized = TRUE;
2025           page_setup = create_page_setup (data->op);
2026           _gtk_print_context_set_page_setup (priv->print_context, 
2027                                              page_setup);
2028           g_object_unref (page_setup);
2029       
2030           g_signal_emit (data->op, signals[BEGIN_PRINT], 0, priv->print_context);
2031       
2032           if (priv->manual_collation)
2033             {
2034               data->uncollated_copies = priv->manual_num_copies;
2035               data->collated_copies = 1;
2036             }
2037           else
2038             {
2039               data->uncollated_copies = 1;
2040               data->collated_copies = priv->manual_num_copies;
2041             }
2042
2043           goto out;
2044         }
2045       
2046       if (g_signal_has_handler_pending (data->op, signals[PAGINATE], 0, FALSE))
2047         {
2048           gboolean paginated = FALSE;
2049
2050           g_signal_emit (data->op, signals[PAGINATE], 0, priv->print_context, &paginated);
2051           if (!paginated)
2052             goto out;
2053         }
2054
2055       /* FIXME handle this better */
2056       if (priv->nr_of_pages == 0)
2057         g_warning ("no pages to print");
2058       
2059       /* Initialize parts of PrintPagesData that depend on nr_of_pages
2060        */
2061       if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
2062         {
2063           data->ranges = priv->page_ranges;
2064           data->num_ranges = priv->num_page_ranges;
2065         }
2066       else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
2067                priv->current_page != -1)
2068         {
2069           data->ranges = &data->one_range;
2070           data->num_ranges = 1;
2071           data->ranges[0].start = priv->current_page;
2072           data->ranges[0].end = priv->current_page;
2073         }
2074       else
2075         {
2076           data->ranges = &data->one_range;
2077           data->num_ranges = 1;
2078           data->ranges[0].start = 0;
2079           data->ranges[0].end = priv->nr_of_pages - 1;
2080         }
2081       
2082       if (priv->manual_reverse)
2083         {
2084           data->range = data->num_ranges - 1;
2085           data->inc = -1;      
2086         }
2087       else
2088         {
2089           data->range = 0;
2090           data->inc = 1;      
2091         }
2092       find_range (data);
2093      
2094       /* go back one page, since we preincrement below */
2095       data->page = data->start - data->inc;
2096       data->collated = data->collated_copies - 1;
2097
2098       _gtk_print_operation_set_status (data->op, 
2099                                        GTK_PRINT_STATUS_GENERATING_DATA, 
2100                                        NULL);
2101
2102       goto out;
2103     }
2104
2105   data->total++;
2106   data->collated++;
2107   if (data->collated == data->collated_copies)
2108     {
2109       data->collated = 0;
2110       if (!increment_page_sequence (data))
2111         {
2112           done = TRUE;
2113
2114           goto out;
2115         }
2116     }
2117  
2118   if (data->is_preview)
2119     {
2120       done = TRUE;
2121
2122       g_object_ref (data->op);
2123       
2124       g_signal_emit_by_name (data->op, "ready", priv->print_context);
2125       goto out;
2126     }
2127
2128   common_render_page (data->op, data->page);
2129
2130  out:
2131
2132   if (priv->cancelled)
2133     {
2134       _gtk_print_operation_set_status (data->op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2135       
2136       done = TRUE;
2137     }
2138
2139   if (done && !data->is_preview)
2140     {
2141       g_signal_emit (data->op, signals[END_PRINT], 0, priv->print_context);
2142       priv->end_run (data->op, priv->is_sync, priv->cancelled);
2143     }
2144
2145   update_progress (data);
2146
2147   GDK_THREADS_LEAVE ();
2148
2149   return !done;
2150 }
2151   
2152 static void
2153 handle_progress_response (GtkWidget *dialog, 
2154                           gint       response,
2155                           gpointer   data)
2156 {
2157   GtkPrintOperation *op = (GtkPrintOperation *)data;
2158
2159   gtk_widget_hide (dialog);
2160   gtk_print_operation_cancel (op);
2161 }
2162
2163 static gboolean
2164 show_progress_timeout (PrintPagesData *data)
2165 {
2166   GDK_THREADS_ENTER ();
2167
2168   gtk_window_present (GTK_WINDOW (data->progress));
2169
2170   data->op->priv->show_progress_timeout_id = 0;
2171
2172   GDK_THREADS_LEAVE ();
2173
2174   return FALSE;
2175 }
2176
2177 static void
2178 print_pages (GtkPrintOperation       *op,
2179              GtkWindow               *parent,
2180              gboolean                 do_print,
2181              GtkPrintOperationResult  result)
2182 {
2183   GtkPrintOperationPrivate *priv = op->priv;
2184   PrintPagesData *data;
2185  
2186   if (!do_print) 
2187     {
2188       _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2189       g_signal_emit (op, signals[DONE], 0, result);
2190       return;
2191   }
2192   
2193   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);  
2194
2195   data = g_new0 (PrintPagesData, 1);
2196   data->op = g_object_ref (op);
2197   data->is_preview = (result == GTK_PRINT_OPERATION_RESULT_PREVIEW);
2198
2199   if (priv->show_progress)
2200     {
2201       GtkWidget *progress;
2202
2203       progress = gtk_message_dialog_new (parent, 0, 
2204                                          GTK_MESSAGE_OTHER,
2205                                          GTK_BUTTONS_CANCEL,
2206                                          _("Preparing"));
2207       g_signal_connect (progress, "response", 
2208                         G_CALLBACK (handle_progress_response), op);
2209
2210       priv->show_progress_timeout_id = 
2211         g_timeout_add (SHOW_PROGRESS_TIME, 
2212                        (GSourceFunc)show_progress_timeout,
2213                        data);
2214
2215       data->progress = progress;
2216     }
2217
2218   if (data->is_preview)
2219     {
2220       gboolean handled;
2221       
2222       g_signal_emit_by_name (op, "preview",
2223                              GTK_PRINT_OPERATION_PREVIEW (op),
2224                              op->priv->print_context,
2225                              parent,
2226                              &handled);
2227       
2228       if (!handled ||
2229           gtk_print_context_get_cairo_context (priv->print_context) == NULL) 
2230         {
2231           /* Programmer error */
2232           g_error ("You must set a cairo context on the print context");
2233         }
2234       
2235       priv->start_page = preview_start_page;
2236       priv->end_page = preview_end_page;
2237       priv->end_run = preview_end_run;
2238
2239       priv->print_pages = gtk_print_settings_get_print_pages (priv->print_settings);
2240       priv->page_ranges = gtk_print_settings_get_page_ranges (priv->print_settings,
2241                                                               &priv->num_page_ranges);
2242       priv->manual_num_copies = 1;
2243       priv->manual_collation = FALSE;
2244       priv->manual_reverse = FALSE;
2245       priv->manual_page_set = GTK_PAGE_SET_ALL;
2246       priv->manual_scale = 1.0;
2247       priv->manual_orientation = TRUE;
2248     }
2249   
2250   priv->print_pages_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2251                                                print_pages_idle, 
2252                                                data, 
2253                                                print_pages_idle_done);
2254   
2255   /* Recursive main loop to make sure we don't exit  on sync operations  */
2256   if (priv->is_sync)
2257     {
2258       priv->rloop = g_main_loop_new (NULL, FALSE);
2259
2260       GDK_THREADS_LEAVE ();
2261       g_main_loop_run (priv->rloop);
2262       GDK_THREADS_ENTER ();
2263       
2264       g_main_loop_unref (priv->rloop);
2265       priv->rloop = NULL;
2266     }
2267 }
2268
2269 /**
2270  * gtk_print_operation_get_error:
2271  * @op: a #GtkPrintOperation
2272  * 
2273  * Call this when the result of a print operation is
2274  * %GTK_PRINT_OPERATION_RESULT_ERROR, either as returned by 
2275  * gtk_print_operation_run(), or in the ::done signal handler. 
2276  * The returned #GError will contain more details on what went wrong.
2277  *
2278  * Return value: a #GError representing the error, or #NULL
2279  *
2280  * Since: 2.10
2281  **/
2282 GError *
2283 gtk_print_operation_get_error (GtkPrintOperation *op)
2284 {
2285   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
2286   
2287   return op->priv->error;
2288 }
2289
2290
2291 /**
2292  * gtk_print_operation_run:
2293  * @op: a #GtkPrintOperation
2294  * @action: the action to start
2295  * @parent: Transient parent of the dialog, or %NULL
2296  * @error: Return location for errors, or %NULL
2297  * 
2298  * Runs the print operation, by first letting the user modify
2299  * print settings in the print dialog, and then print the
2300  * document.
2301  *
2302  * Normally that this function does not return until the rendering of all 
2303  * pages is complete. You can connect to the ::status-changed signal on
2304  * @op to obtain some information about the progress of the print operation. 
2305  * Furthermore, it may use a recursive mainloop to show the print dialog.
2306  *
2307  * If you call gtk_print_operation_set_allow_async() or set the allow-async
2308  * property the operation will run asyncronously if this is supported on the
2309  * platform. The ::done signal will be emitted with the operation results when
2310  * the operation is done (i.e. when the dialog is canceled, or when the print
2311  * succeeds or fails).
2312  *
2313  * <informalexample><programlisting>
2314  * if (settings != NULL)
2315  *   gtk_print_operation_set_print_settings (print, settings);
2316  *   
2317  * if (page_setup != NULL)
2318  *   gtk_print_operation_set_default_page_setup (print, page_setup);
2319  *   
2320  * g_signal_connect (print, "begin-print", 
2321  *                   G_CALLBACK (begin_print), &amp;data);
2322  * g_signal_connect (print, "draw-page", 
2323  *                   G_CALLBACK (draw_page), &amp;data);
2324  *  
2325  * res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, parent, &amp;error);
2326  *  
2327  * if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
2328  *  {
2329  *    error_dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
2330  *                                           GTK_DIALOG_DESTROY_WITH_PARENT,
2331  *                                           GTK_MESSAGE_ERROR,
2332  *                                           GTK_BUTTONS_CLOSE,
2333  *                                           "Error printing file:\n%s",
2334  *                                           error->message);
2335  *    g_signal_connect (error_dialog, "response", 
2336  *                      G_CALLBACK (gtk_widget_destroy), NULL);
2337  *    gtk_widget_show (error_dialog);
2338  *    g_error_free (error);
2339  *  }
2340  * else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
2341  *  {
2342  *    if (settings != NULL)
2343  *      g_object_unref (settings);
2344  *    settings = g_object_ref (gtk_print_operation_get_print_settings (print));
2345  *  }
2346  * </programlisting></informalexample>
2347  *
2348  * Return value: the result of the print operation. A return value of 
2349  *   %GTK_PRINT_OPERATION_RESULT_APPLY indicates that the printing was
2350  *   completed successfully. In this case, it is a good idea to obtain 
2351  *   the used print settings with gtk_print_operation_get_print_settings() 
2352  *   and store them for reuse with the next print operation. A value of
2353  *   %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS means the operation is running
2354  *   asynchronously, and will emit the ::done signal when done.
2355  *
2356  * Since: 2.10
2357  **/
2358 GtkPrintOperationResult
2359 gtk_print_operation_run (GtkPrintOperation        *op,
2360                          GtkPrintOperationAction   action,
2361                          GtkWindow                *parent,
2362                          GError                  **error)
2363 {
2364   GtkPrintOperationPrivate *priv;
2365   GtkPrintOperationResult result;
2366   GtkPageSetup *page_setup;
2367   gboolean do_print;
2368   
2369   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
2370                         GTK_PRINT_OPERATION_RESULT_ERROR);
2371
2372   priv = op->priv;
2373
2374   do_print = FALSE;
2375   priv->error = NULL;
2376   priv->action = action;
2377
2378   if (priv->print_settings == NULL)
2379     priv->print_settings = gtk_print_settings_new ();
2380   
2381   if (action == GTK_PRINT_OPERATION_ACTION_EXPORT)
2382     {
2383       priv->is_sync = TRUE;
2384       g_return_val_if_fail (priv->pdf_target != NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
2385       result = run_pdf (op, parent, &do_print);
2386     }
2387   else if (action == GTK_PRINT_OPERATION_ACTION_PREVIEW)
2388     {
2389       priv->print_context = _gtk_print_context_new (op);
2390       page_setup = create_page_setup (op);
2391       _gtk_print_context_set_page_setup (priv->print_context, page_setup);
2392       g_object_unref (page_setup);
2393       do_print = TRUE;
2394       result = GTK_PRINT_OPERATION_RESULT_PREVIEW;
2395
2396       priv->is_sync = !priv->allow_async;
2397     }
2398 #ifndef G_OS_WIN32
2399   else if (priv->allow_async)
2400     {
2401       priv->is_sync = FALSE;
2402       _gtk_print_operation_platform_backend_run_dialog_async (op,
2403                                                               action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
2404                                                               parent,
2405                                                               print_pages);
2406       result = GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
2407     }
2408 #endif
2409   else
2410     {
2411       priv->is_sync = TRUE;
2412       result = _gtk_print_operation_platform_backend_run_dialog (op, 
2413                                                                  action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
2414                                                                  parent,
2415                                                                  &do_print);
2416     }
2417
2418   if (result != GTK_PRINT_OPERATION_RESULT_IN_PROGRESS)
2419     print_pages (op, parent, do_print, result);
2420
2421   if (priv->error && error)
2422     *error = g_error_copy (priv->error);
2423   
2424   return result;
2425 }
2426
2427 /**
2428  * gtk_print_operation_cancel:
2429  * @op: a #GtkPrintOperation
2430  *
2431  * Cancels a running print operation. This function may
2432  * be called from a begin-print, paginate or draw-page
2433  * signal handler to stop the currently running print 
2434  * operation.
2435  *
2436  * Since: 2.10
2437  */
2438 void
2439 gtk_print_operation_cancel (GtkPrintOperation *op)
2440 {
2441   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
2442   
2443   op->priv->cancelled = TRUE;
2444 }
2445
2446
2447
2448 #define __GTK_PRINT_OPERATION_C__
2449 #include "gtkaliasdef.c"