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