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