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