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