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