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