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