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