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