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