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