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