]> Pileus Git - ~andy/gtk/blob - gtk/gtkprintoperation.c
bits from the preview patch
[~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 #include <string.h>
23 #include "gtkprintoperation-private.h"
24 #include "gtkmarshalers.h"
25 #include <cairo-pdf.h>
26 #include "gtkintl.h"
27 #include "gtkprivate.h"
28 #include "gtkmessagedialog.h"
29 #include "gtkalias.h"
30
31 #define SHOW_PROGRESS_TIME 1200
32
33 #define GTK_PRINT_OPERATION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_PRINT_OPERATION, GtkPrintOperationPrivate))
34
35 enum {
36   BEGIN_PRINT,
37   PAGINATE,
38   REQUEST_PAGE_SETUP,
39   DRAW_PAGE,
40   END_PRINT,
41   STATUS_CHANGED,
42   CREATE_CUSTOM_WIDGET,
43   CUSTOM_WIDGET_APPLY,
44   LAST_SIGNAL
45 };
46
47 enum {
48   PROP_0,
49   PROP_DEFAULT_PAGE_SETUP,
50   PROP_PRINT_SETTINGS,
51   PROP_JOB_NAME,
52   PROP_N_PAGES,
53   PROP_CURRENT_PAGE,
54   PROP_USE_FULL_PAGE,
55   PROP_TRACK_PRINT_STATUS,
56   PROP_UNIT,
57   PROP_SHOW_DIALOG,
58   PROP_SHOW_PROGRESS,
59   PROP_PDF_TARGET,
60   PROP_STATUS,
61   PROP_STATUS_STRING,
62   PROP_CUSTOM_TAB_LABEL
63 };
64
65 static guint signals[LAST_SIGNAL] = { 0 };
66 static int job_nr = 0;
67
68 G_DEFINE_TYPE (GtkPrintOperation, gtk_print_operation, G_TYPE_OBJECT)
69
70 /**
71  * gtk_print_error_quark:
72  *
73  * Registers an error quark for #GtkPrintOperation if necessary.
74  * 
75  * Return value: The error quark used for #GtkPrintOperation errors.
76  *
77  * Since: 2.10
78  **/
79 GQuark     
80 gtk_print_error_quark (void)
81 {
82   static GQuark quark = 0;
83   if (quark == 0)
84     quark = g_quark_from_static_string ("gtk-print-error-quark");
85   return quark;
86 }
87      
88 static void
89 gtk_print_operation_finalize (GObject *object)
90 {
91   GtkPrintOperation *print_operation = GTK_PRINT_OPERATION (object);
92   GtkPrintOperationPrivate *priv = print_operation->priv;
93
94   if (priv->free_platform_data &&
95       priv->platform_data)
96     {
97       priv->free_platform_data (priv->platform_data);
98       priv->free_platform_data = NULL;
99     }
100
101   if (priv->default_page_setup)
102     g_object_unref (priv->default_page_setup);
103   
104   if (priv->print_settings)
105     g_object_unref (priv->print_settings);
106   
107   g_free (priv->pdf_target);
108   g_free (priv->job_name);
109   g_free (priv->custom_tab_label);
110
111   if (priv->print_pages_idle_id > 0)
112     g_source_remove (priv->print_pages_idle_id);
113
114   if (priv->show_progress_timeout_id > 0)
115     g_source_remove (priv->show_progress_timeout_id);
116
117   G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object);
118 }
119
120 static void
121 gtk_print_operation_init (GtkPrintOperation *operation)
122 {
123   GtkPrintOperationPrivate *priv;
124   const char *appname;
125
126   priv = operation->priv = GTK_PRINT_OPERATION_GET_PRIVATE (operation);
127
128   priv->status = GTK_PRINT_STATUS_INITIAL;
129   priv->status_string = g_strdup ("");
130   priv->default_page_setup = NULL;
131   priv->print_settings = NULL;
132   priv->nr_of_pages = -1;
133   priv->current_page = -1;
134   priv->use_full_page = FALSE;
135   priv->show_dialog = TRUE;
136   priv->show_progress = FALSE;
137   priv->pdf_target = NULL;
138   priv->track_print_status = FALSE;
139   priv->is_sync = FALSE;
140
141   priv->rloop = NULL;
142   priv->unit = GTK_UNIT_PIXEL;
143
144   appname = g_get_application_name ();
145   priv->job_name = g_strdup_printf ("%s job #%d", appname, ++job_nr);
146 }
147
148 static void
149 gtk_print_operation_set_property (GObject      *object,
150                                   guint         prop_id,
151                                   const GValue *value,
152                                   GParamSpec   *pspec)
153 {
154   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
155   
156   switch (prop_id)
157     {
158     case PROP_DEFAULT_PAGE_SETUP:
159       gtk_print_operation_set_default_page_setup (op, g_value_get_object (value));
160       break;
161     case PROP_PRINT_SETTINGS:
162       gtk_print_operation_set_print_settings (op, g_value_get_object (value));
163       break;
164     case PROP_JOB_NAME:
165       gtk_print_operation_set_job_name (op, g_value_get_string (value));
166       break;
167     case PROP_N_PAGES:
168       gtk_print_operation_set_n_pages (op, g_value_get_int (value));
169       break;
170     case PROP_CURRENT_PAGE:
171       gtk_print_operation_set_current_page (op, g_value_get_int (value));
172       break;
173     case PROP_USE_FULL_PAGE:
174       gtk_print_operation_set_use_full_page (op, g_value_get_boolean (value));
175       break;
176     case PROP_TRACK_PRINT_STATUS:
177       gtk_print_operation_set_track_print_status (op, g_value_get_boolean (value));
178       break;
179     case PROP_UNIT:
180       gtk_print_operation_set_unit (op, g_value_get_enum (value));
181       break;
182     case PROP_SHOW_DIALOG:
183       gtk_print_operation_set_show_dialog (op, g_value_get_boolean (value));
184       break;
185     case PROP_SHOW_PROGRESS:
186       gtk_print_operation_set_show_progress (op, g_value_get_boolean (value));
187       break;
188     case PROP_PDF_TARGET:
189       gtk_print_operation_set_pdf_target (op, g_value_get_string (value));
190       break;
191     case PROP_CUSTOM_TAB_LABEL:
192       gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value));
193       break;
194     default:
195       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
196       break;
197     }
198 }
199
200 static void
201 gtk_print_operation_get_property (GObject    *object,
202                                   guint       prop_id,
203                                   GValue     *value,
204                                   GParamSpec *pspec)
205 {
206   GtkPrintOperation *op = GTK_PRINT_OPERATION (object);
207   GtkPrintOperationPrivate *priv = op->priv;
208
209   switch (prop_id)
210     {
211     case PROP_DEFAULT_PAGE_SETUP:
212       g_value_set_object (value, priv->default_page_setup);
213       break;
214     case PROP_PRINT_SETTINGS:
215       g_value_set_object (value, priv->print_settings);
216       break;
217     case PROP_JOB_NAME:
218       g_value_set_string (value, priv->job_name);
219       break;
220     case PROP_N_PAGES:
221       g_value_set_int (value, priv->nr_of_pages);
222       break;
223     case PROP_CURRENT_PAGE:
224       g_value_set_int (value, priv->current_page);
225       break;      
226     case PROP_USE_FULL_PAGE:
227       g_value_set_boolean (value, priv->use_full_page);
228       break;
229     case PROP_TRACK_PRINT_STATUS:
230       g_value_set_boolean (value, priv->track_print_status);
231       break;
232     case PROP_UNIT:
233       g_value_set_enum (value, priv->unit);
234       break;
235     case PROP_SHOW_DIALOG:
236       g_value_set_boolean (value, priv->show_dialog);
237       break;
238     case PROP_SHOW_PROGRESS:
239       g_value_set_boolean (value, priv->show_progress);
240       break;
241     case PROP_PDF_TARGET:
242       g_value_set_string (value, priv->pdf_target);
243       break;
244     case PROP_STATUS:
245       g_value_set_enum (value, priv->status);
246       break;
247     case PROP_STATUS_STRING:
248       g_value_set_string (value, priv->status_string);
249       break;
250     case PROP_CUSTOM_TAB_LABEL:
251       g_value_set_string (value, priv->custom_tab_label);
252       break;
253     default:
254       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
255       break;
256     }
257 }
258
259 static GtkWidget *
260 gtk_print_operation_create_custom_widget (GtkPrintOperation *operation)
261 {
262   return NULL;
263 }
264
265 static gboolean
266 custom_widget_accumulator (GSignalInvocationHint *ihint,
267                            GValue                *return_accu,
268                            const GValue          *handler_return,
269                            gpointer               dummy)
270 {
271   gboolean continue_emission;
272   GtkWidget *widget;
273   
274   widget = g_value_get_pointer (handler_return);
275   if (widget != NULL)
276     g_value_set_pointer (return_accu, widget);
277   continue_emission = (widget == NULL);
278   
279   return continue_emission;
280 }
281
282 static void
283 gtk_print_operation_class_init (GtkPrintOperationClass *class)
284 {
285   GObjectClass *gobject_class = (GObjectClass *)class;
286
287   gobject_class->set_property = gtk_print_operation_set_property;
288   gobject_class->get_property = gtk_print_operation_get_property;
289   gobject_class->finalize = gtk_print_operation_finalize;
290
291   class->create_custom_widget = gtk_print_operation_create_custom_widget;
292   
293   g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
294
295   /**
296    * GtkPrintOperation::begin-print:
297    * @operation: the #GtkPrintOperation on which the signal was emitted
298    * @context: the #GtkPrintContext for the current operation
299    *
300    * Gets emitted after the user has finished changing print settings
301    * in the dialog, before the actual rendering starts. 
302    *
303    * A typical use for this signal is to use the parameters from the
304    * #GtkPrintContext and paginate the document accordingly, and then
305    * set the number of pages with gtk_print_operation_set_n_pages().
306    *
307    * Since: 2.10
308    */
309   signals[BEGIN_PRINT] =
310     g_signal_new (I_("begin-print"),
311                   G_TYPE_FROM_CLASS (gobject_class),
312                   G_SIGNAL_RUN_LAST,
313                   G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
314                   NULL, NULL,
315                   g_cclosure_marshal_VOID__OBJECT,
316                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
317
318    /**
319    * Gtkprintoperation::paginate:
320    * @operation: the #GtkPrintOperation on which the signal was emitted
321    * @context: the #GtkPrintContext for the current operation
322    *
323    * Gets emitted after the begin-print signal, but before the actual 
324    * rendering starts. It keeps getting emitted until it returns %FALSE. 
325    *
326    * This signal is intended to be used for paginating the document
327    * in small chunks, to avoid blocking the user interface for a long
328    * time. The signal handler should update the number of pages using
329    * gtk_print_operation_set_n_pages(), and return %TRUE if the document
330    * has been completely paginated.
331    *
332    * If you don't need to do pagination in chunks, you can simply do
333    * it all in the begin-print handler, and set the number of pages
334    * from there.
335    *
336    * Since: 2.10
337    */
338   signals[PAGINATE] =
339     g_signal_new (I_("paginate"),
340                   G_TYPE_FROM_CLASS (gobject_class),
341                   G_SIGNAL_RUN_LAST,
342                   G_STRUCT_OFFSET (GtkPrintOperationClass, paginate),
343                   _gtk_boolean_handled_accumulator, NULL,
344                   _gtk_marshal_BOOLEAN__OBJECT,
345                   G_TYPE_BOOLEAN, 1, GTK_TYPE_PRINT_CONTEXT);
346
347
348   /**
349    * GtkPrintOperation::request-page-setup:
350    * @operation: the #GtkPrintOperation on which the signal was emitted
351    * @context: the #GtkPrintContext for the current operation
352    * @page_nr: the number of the currently printed page
353    * @setup: the #GtkPageSetup 
354    * 
355    * Gets emitted once for every page that is printed, to give
356    * the application a chance to modify the page setup. Any changes 
357    * done to @setup will be in force only for printing this page.
358    *
359    * Since: 2.10
360    */
361   signals[REQUEST_PAGE_SETUP] =
362     g_signal_new (I_("request-page-setup"),
363                   G_TYPE_FROM_CLASS (gobject_class),
364                   G_SIGNAL_RUN_LAST,
365                   G_STRUCT_OFFSET (GtkPrintOperationClass, request_page_setup),
366                   NULL, NULL,
367                   _gtk_marshal_VOID__OBJECT_INT_OBJECT,
368                   G_TYPE_NONE, 3,
369                   GTK_TYPE_PRINT_CONTEXT,
370                   G_TYPE_INT,
371                   GTK_TYPE_PAGE_SETUP);
372
373   /**
374    * GtkPrintOperation::draw-page:
375    * @operation: the #GtkPrintOperation on which the signal was emitted
376    * @context: the #GtkPrintContext for the current operation
377    * @page_nr: the number of the currently printed page
378    *
379    * Gets emitted for every page that is printed. The signal handler
380    * must render the @page_nr's page onto the cairo context obtained
381    * from @context using gtk_print_context_get_cairo_context().
382    *
383    * <informalexample><programlisting>
384    * static void
385    * draw_page (GtkPrintOperation *operation,
386    *            GtkPrintContext   *context,
387    *            gint               page_nr,
388    *            gpointer           user_data)
389    * {
390    *   cairo_t *cr;
391    *   PangoLayout *layout;
392    *   gdouble width, text_height;
393    *   gint layout_height;
394    *   PangoFontDescription *desc;
395    *   
396    *   cr = gtk_print_context_get_cairo_context (context);
397    *   width = gtk_print_context_get_width (context);
398    *   
399    *   cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT);
400    *   
401    *   cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
402    *   cairo_fill (cr);
403    *   
404    *   layout = gtk_print_context_create_pango_layout (context);
405    *   
406    *   desc = pango_font_description_from_string ("sans 14");
407    *   pango_layout_set_font_description (layout, desc);
408    *   pango_font_description_free (desc);
409    *   
410    *   pango_layout_set_text (layout, "some text", -1);
411    *   pango_layout_set_width (layout, width);
412    *   pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
413    *                  
414    *   pango_layout_get_size (layout, NULL, &amp;layout_height);
415    *   text_height = (gdouble)layout_height / PANGO_SCALE;
416    *   
417    *   cairo_move_to (cr, width / 2,  (HEADER_HEIGHT - text_height) / 2);
418    *   pango_cairo_show_layout (cr, layout);
419    *
420    *   g_object_unref (layout);
421    * }
422    * </programlisting></informalexample>
423    *
424    * Use gtk_print_operation_set_use_full_page() and 
425    * gtk_print_operation_set_unit() before starting the print operation
426    * to set up the transformation of the cairo context according to your
427    * needs.
428    * 
429    * Since: 2.10
430    */
431   signals[DRAW_PAGE] =
432     g_signal_new (I_("draw-page"),
433                   G_TYPE_FROM_CLASS (gobject_class),
434                   G_SIGNAL_RUN_LAST,
435                   G_STRUCT_OFFSET (GtkPrintOperationClass, draw_page),
436                   NULL, NULL,
437                   _gtk_marshal_VOID__OBJECT_INT,
438                   G_TYPE_NONE, 2,
439                   GTK_TYPE_PRINT_CONTEXT,
440                   G_TYPE_INT);
441
442   /**
443    * GtkPrintOperation::end-print:
444    * @operation: the #GtkPrintOperation on which the signal was emitted
445    * @context: the #GtkPrintContext for the current operation
446    *
447    * Gets emitted after all pages have been rendered. 
448    * A handler for this signal can clean up any resources that have
449    * been allocated in the ::begin-print handler.
450    * 
451    * Since: 2.10
452    */
453   signals[END_PRINT] =
454     g_signal_new (I_("end-print"),
455                   G_TYPE_FROM_CLASS (gobject_class),
456                   G_SIGNAL_RUN_LAST,
457                   G_STRUCT_OFFSET (GtkPrintOperationClass, end_print),
458                   NULL, NULL,
459                   g_cclosure_marshal_VOID__OBJECT,
460                   G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
461
462   /**
463    * GtkPrintOperation::status-changed:
464    * @operation: the #GtkPrintOperation on which the signal was emitted
465    *
466    * Gets emitted at between the various phases of the print operation.
467    * See #GtkPrintStatus for the phases that are being discriminated.
468    * Use gtk_print_operation_get_status() to find out the current
469    * status.
470    *
471    * Since: 2.10
472    */
473   signals[STATUS_CHANGED] =
474     g_signal_new (I_("status-changed"),
475                   G_TYPE_FROM_CLASS (class),
476                   G_SIGNAL_RUN_LAST,
477                   G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
478                   NULL, NULL,
479                   g_cclosure_marshal_VOID__VOID,
480                   G_TYPE_NONE, 0);
481
482
483   /**
484    * GtkPrintOperation::create-custom-widget:
485    * @operation: the #GtkPrintOperation on which the signal was emitted
486    *
487    * Gets emitted when displaying the print dialog. If you return a
488    * widget in a handler for this signal it will be added to a custom
489    * tab in the print dialog. You typically return a container widget
490    * with multiple widgets in it.
491    *
492    * The print dialog owns the returned widget, and its lifetime
493    * isn't controlled by the app. However, the widget is guaranteed
494    * to stay around until the custom-widget-apply signal is emitted
495    * on the operation. Then you can read out any information you need
496    * from the widgets.
497    *
498    * Returns: A custom widget that gets embedded in the print dialog,
499    *          or %NULL
500    *
501    * Since: 2.10
502    */
503   signals[CREATE_CUSTOM_WIDGET] =
504     g_signal_new (I_("create-custom-widget"),
505                   G_TYPE_FROM_CLASS (class),
506                   G_SIGNAL_RUN_LAST,
507                   G_STRUCT_OFFSET (GtkPrintOperationClass, create_custom_widget),
508                   custom_widget_accumulator, NULL,
509                   _gtk_marshal_POINTER__VOID,
510                   G_TYPE_POINTER, 0);
511
512   /**
513    * GtkPrintOperation::custom-widget-apply:
514    * @operation: the #GtkPrintOperation on which the signal was emitted
515    * @widget: the custom widget added in create-custom-widget
516    *
517    * This signal gets emitted right before begin-print if you added
518    * a custom widget in the create-custom-widget handler. When you get
519    * this signal you should read the information from the custom widgets,
520    * as the widgets are not guaraneed to be around at a later time.
521    *
522    * Since: 2.10
523    */
524   signals[CUSTOM_WIDGET_APPLY] =
525     g_signal_new (I_("custom-widget-apply"),
526                   G_TYPE_FROM_CLASS (class),
527                   G_SIGNAL_RUN_LAST,
528                   G_STRUCT_OFFSET (GtkPrintOperationClass, custom_widget_apply),
529                   NULL, NULL,
530                   g_cclosure_marshal_VOID__OBJECT,
531                   G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
532
533   /**
534    * GtkPrintOperation:default-page-setup:
535    *
536    * The #GtkPageSetup used by default.
537    * 
538    * This page setup will be used by gtk_print_operation_run(),
539    * but it can be overridden on a per-page basis by connecting
540    * to the ::request-page-setup signal.
541    *
542    * Since: 2.10
543    */
544   g_object_class_install_property (gobject_class,
545                                    PROP_DEFAULT_PAGE_SETUP,
546                                    g_param_spec_object ("default-page-setup",
547                                                         P_("Default Page Setup"),
548                                                         P_("The GtkPageSetup used by default"),
549                                                         GTK_TYPE_PAGE_SETUP,
550                                                         GTK_PARAM_READWRITE));
551
552   /**
553    * GtkPrintOperation:print-settings:
554    *
555    * The #GtkPrintSettings used for initializing the dialog.
556    *
557    * Setting this property is typically used to re-establish 
558    * print settings from a previous print operation, see 
559    * gtk_print_operation_run().
560    *
561    * Since: 2.10
562    */
563   g_object_class_install_property (gobject_class,
564                                    PROP_PRINT_SETTINGS,
565                                    g_param_spec_object ("print-settings",
566                                                         P_("Print Settings"),
567                                                         P_("The GtkPrintSettings used for initializing the dialog"),
568                                                         GTK_TYPE_PRINT_SETTINGS,
569                                                         GTK_PARAM_READWRITE));
570   
571   /**
572    * GtkPrintOperation:job-name:
573    *
574    * A string used to identify the job (e.g. in monitoring 
575    * applications like eggcups). 
576    * 
577    * If you don't set a job name, GTK+ picks a default one 
578    * by numbering successive print jobs.
579    *
580    * Since: 2.10
581    */
582   g_object_class_install_property (gobject_class,
583                                    PROP_JOB_NAME,
584                                    g_param_spec_string ("job-name",
585                                                         P_("Job Name"),
586                                                         P_("A string used for identifying the print job."),
587                                                         "",
588                                                         GTK_PARAM_READWRITE));
589
590   /**
591    * GtkPrintOperation:n-pages:
592    *
593    * The number of pages in the document. 
594    *
595    * This <emphasis>must</emphasis> be set to a positive number
596    * before the rendering starts. It may be set in a ::begin-print 
597    * signal hander.
598    *
599    * Note that the page numbers passed to the ::request-page-setup 
600    * and ::draw-page signals are 0-based, i.e. if the user chooses 
601    * to print all pages, the last ::draw-page signal will be for 
602    * page @n_pages - 1.
603    *
604    * Since: 2.10
605    */
606   g_object_class_install_property (gobject_class,
607                                    PROP_N_PAGES,
608                                    g_param_spec_int ("n-pages",
609                                                      P_("Number of Pages"),
610                                                      P_("The number of pages in the document."),
611                                                      -1,
612                                                      G_MAXINT,
613                                                      -1,
614                                                      GTK_PARAM_READWRITE));
615
616   /**
617    * GtkPrintOperation:current-page:
618    *
619    * The current page in the document.
620    *
621    * If this is set before gtk_print_operation_run(), 
622    * the user will be able to select to print only the current page.
623    *
624    * Note that this only makes sense for pre-paginated documents.
625    *
626    * Since: 2.10
627    */
628   g_object_class_install_property (gobject_class,
629                                    PROP_CURRENT_PAGE,
630                                    g_param_spec_int ("current-page",
631                                                      P_("Current Page"),
632                                                      P_("The current page in the document."),
633                                                      -1,
634                                                      G_MAXINT,
635                                                      -1,
636                                                      GTK_PARAM_READWRITE));
637   
638   /**
639    * GtkPrintOperation:use-full-page:
640    *
641    * If %TRUE, the transformation for the cairo context obtained 
642    * from #GtkPrintContext puts the origin at the top left corner 
643    * of the page (which may not be the top left corner of the sheet, 
644    * depending on page orientation and the number of pages per sheet). 
645    * Otherwise, the origin is at the top left corner of the imageable 
646    * area (i.e. inside the margins).
647    * 
648    * Since: 2.10
649    */
650   g_object_class_install_property (gobject_class,
651                                    PROP_USE_FULL_PAGE,
652                                    g_param_spec_boolean ("use-full-page",
653                                                          P_("Use full page"),
654                                                          P_("TRUE if the the origin of the context should be at the corner of the page and not the corner of the imageable area"),
655                                                          FALSE,
656                                                          GTK_PARAM_READWRITE));
657   
658
659   /**
660    * GtkPrintOperation:track-print-status:
661    *
662    * If %TRUE, the print operation will try to continue report on 
663    * the status of the print job in the printer queues and printer. 
664    * This can allow your application to show things like "out of paper" 
665    * issues, and when the print job actually reaches the printer. 
666    * However, this is often implemented using polling, and should 
667    * not be enabled unless needed.
668    * 
669    * Since: 2.10
670    */
671   g_object_class_install_property (gobject_class,
672                                    PROP_USE_FULL_PAGE,
673                                    g_param_spec_boolean ("track-print-status",
674                                                          P_("Track Print Status"),
675                                                          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."),
676                                                          FALSE,
677                                                          GTK_PARAM_READWRITE));
678   
679
680   /**
681    * GtkPrintOperation:unit:
682    *
683    * The transformation for the cairo context obtained from
684    * #GtkPrintContext is set up in such a way that distances 
685    * are measured in units of @unit.
686    *
687    * Since: 2.10
688    */
689   g_object_class_install_property (gobject_class,
690                                    PROP_UNIT,
691                                    g_param_spec_enum ("unit",
692                                                       P_("Unit"),
693                                                       P_("The unit in which distances can be measured in the context"),
694                                                       GTK_TYPE_UNIT,
695                                                       GTK_UNIT_PIXEL,
696                                                       GTK_PARAM_READWRITE));
697   
698
699   /**
700    * GtkPrintOperation:show-dialog:
701    *
702    * Determines whether calling gtk_print_operation_run() will present
703    * a print dialog to the user, or just print to the default printer.
704    *
705    * Since: 2.10
706    */
707   g_object_class_install_property (gobject_class,
708                                    PROP_SHOW_DIALOG,
709                                    g_param_spec_boolean ("show-dialog",
710                                                          P_("Show Dialog"),
711                                                          P_("TRUE if gtk_print_operation_run() should show the print dialog."),
712                                                          TRUE,
713                                                          GTK_PARAM_READWRITE));
714   
715
716   /**
717    * GtkPrintOperation:show-progress:
718    *
719    * Determines whether to show a progress dialog during the 
720    * print operation.
721    *
722    * Since: 2.10
723    */
724   g_object_class_install_property (gobject_class,
725                                    PROP_SHOW_PROGRESS,
726                                    g_param_spec_boolean ("show-progress",
727                                                          P_("Show Dialog"),
728                                                          P_("TRUE if a progress dialog is shown while printing."),
729                                                          FALSE,
730                                                          GTK_PARAM_READWRITE));
731   
732   
733   /**
734    * GtkPrintOperation:pdf-target:
735    *
736    * The name of a PDF file to generate instead of showing 
737    * the print dialog. 
738    *
739    * The intended use of this property is for implementing 
740    * "Export to PDF" actions.
741    *
742    * "Print to PDF" support is independent of this and is done
743    * by letting the user pick the "Print to PDF" item from the 
744    * list of printers in the print dialog.
745    *
746    * Since: 2.10
747    */
748   g_object_class_install_property (gobject_class,
749                                    PROP_JOB_NAME,
750                                    g_param_spec_string ("pdf-target",
751                                                         P_("PDF target filename"),
752                                                         P_("PDF target filename"),
753                                                         NULL,
754                                                         GTK_PARAM_READWRITE));
755   
756   /**
757    * GtkPrintOperation:status:
758    *
759    * The status of the print operation.
760    * 
761    * Since: 2.10
762    */
763   g_object_class_install_property (gobject_class,
764                                    PROP_STATUS,
765                                    g_param_spec_enum ("status",
766                                                       P_("Status"),
767                                                       P_("The status of the print operation"),
768                                                       GTK_TYPE_PRINT_STATUS,
769                                                       GTK_PRINT_STATUS_INITIAL,
770                                                       GTK_PARAM_READABLE));
771   
772   /**
773    * GtkPrintOperation:status-string:
774    *
775    * A string representation of the status of the print operation. 
776    * The string is translated and suitable for displaying the print 
777    * status e.g. in a #GtkStatusbar.
778    *
779    * See the ::status property for a status value that is suitable 
780    * for programmatic use. 
781    *
782    * Since: 2.10
783    */
784   g_object_class_install_property (gobject_class,
785                                    PROP_STATUS_STRING,
786                                    g_param_spec_string ("status-string",
787                                                         P_("Status String"),
788                                                         P_("A human-readable description of the status"),
789                                                         "",
790                                                         GTK_PARAM_READABLE));
791   
792
793   /**
794    * GtkPrintOperation:custom-tab-label:
795    *
796    * Used as the label of the tab containing custom widgets.
797    * Note that this property may be ignored on some platforms.
798    * 
799    * If this is %NULL, GTK+ uses a default label.
800    *
801    * Since: 2.10
802    */
803   g_object_class_install_property (gobject_class,
804                                    PROP_CUSTOM_TAB_LABEL,
805                                    g_param_spec_string ("custom-tab-label",
806                                                         P_("Custom tab label"),
807                                                         P_("Label for the tab containing custom widgets."),
808                                                         NULL,
809                                                         GTK_PARAM_READWRITE));
810
811 }
812
813 /**
814  * gtk_print_operation_new:
815  *
816  * Creates a new #GtkPrintOperation. 
817  *
818  * Returns: a new #GtkPrintOperation
819  *
820  * Since: 2.10
821  */
822 GtkPrintOperation *
823 gtk_print_operation_new (void)
824 {
825   GtkPrintOperation *print_operation;
826
827   print_operation = g_object_new (GTK_TYPE_PRINT_OPERATION, NULL);
828   
829   return print_operation;
830 }
831
832 /**
833  * gtk_print_operation_set_default_page_setup:
834  * @op: a #GtkPrintOperation
835  * @default_page_setup: a #GtkPageSetup, or %NULL
836  * 
837  * Makes @default_page_setup the default page setup for @op.
838  *
839  * This page setup will be used by gtk_print_operation_run(),
840  * but it can be overridden on a per-page basis by connecting
841  * to the ::request-page-setup signal.
842  *
843  * Since: 2.10
844  **/
845 void
846 gtk_print_operation_set_default_page_setup (GtkPrintOperation *op,
847                                             GtkPageSetup      *default_page_setup)
848 {
849   GtkPrintOperationPrivate *priv;
850
851   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
852   g_return_if_fail (default_page_setup == NULL || 
853                     GTK_IS_PAGE_SETUP (default_page_setup));
854
855   priv = op->priv;
856
857   if (default_page_setup != priv->default_page_setup)
858     {
859       if (default_page_setup)
860         g_object_ref (default_page_setup);
861       
862       if (priv->default_page_setup)
863         g_object_unref (priv->default_page_setup);
864       
865       priv->default_page_setup = default_page_setup;
866      
867       g_object_notify (G_OBJECT (op), "default-page-setup");
868     }
869 }
870
871 /**
872  * gtk_print_operation_get_default_page_setup:
873  * @op: a #GtkPrintOperation
874  *
875  * Returns the default page setup, see 
876  * gtk_print_operation_set_default_page_setup().
877  *
878  * Returns: the default page setup 
879  *
880  * Since: 2.10
881  */
882 GtkPageSetup *
883 gtk_print_operation_get_default_page_setup (GtkPrintOperation *op)
884 {
885   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
886
887   return op->priv->default_page_setup;
888 }
889
890
891 /**
892  * gtk_print_operation_set_print_settings:
893  * @op: a #GtkPrintOperation
894  * @print_settings: #GtkPrintSettings, or %NULL
895  * 
896  * Sets the print settings for @op. This is typically used to
897  * re-establish print settings from a previous print operation,
898  * see gtk_print_operation_run().
899  *
900  * Since: 2.10
901  **/
902 void
903 gtk_print_operation_set_print_settings (GtkPrintOperation *op,
904                                         GtkPrintSettings  *print_settings)
905 {
906   GtkPrintOperationPrivate *priv;
907
908   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
909   g_return_if_fail (print_settings == NULL || 
910                     GTK_IS_PRINT_SETTINGS (print_settings));
911
912   priv = op->priv;
913
914   if (print_settings != priv->print_settings)
915     {
916       if (print_settings)
917         g_object_ref (print_settings);
918
919       if (priv->print_settings)
920         g_object_unref (priv->print_settings);
921   
922       priv->print_settings = print_settings;
923
924       g_object_notify (G_OBJECT (op), "print-settings");
925     }
926 }
927
928 /**
929  * gtk_print_operation_get_print_settings:
930  * @op: a #GtkPrintOperation
931  * 
932  * Returns the current print settings. 
933  *
934  * Note that the return value is %NULL until either 
935  * gtk_print_operation_set_print_settings() or 
936  * gtk_print_operation_run() have been called.
937  * 
938  * Return value: the current print settings of @op.
939  * 
940  * Since: 2.10
941  **/
942 GtkPrintSettings *
943 gtk_print_operation_get_print_settings (GtkPrintOperation *op)
944 {
945   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
946
947   return op->priv->print_settings;
948 }
949
950 /**
951  * gtk_print_operation_set_job_name:
952  * @op: a #GtkPrintOperation
953  * @job_name: a string that identifies the print job
954  * 
955  * Sets the name of the print job. The name is used to identify 
956  * the job (e.g. in monitoring applications like eggcups). 
957  * 
958  * If you don't set a job name, GTK+ picks a default one by 
959  * numbering successive print jobs.
960  *
961  * Since: 2.10
962  **/
963 void
964 gtk_print_operation_set_job_name (GtkPrintOperation *op,
965                                   const gchar       *job_name)
966 {
967   GtkPrintOperationPrivate *priv;
968
969   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
970   g_return_if_fail (g_utf8_validate (job_name, -1, NULL));
971
972   priv = op->priv;
973
974   g_free (priv->job_name);
975   priv->job_name = g_strdup (job_name);
976
977   g_object_notify (G_OBJECT (op), "job-name");
978 }
979
980 /**
981  * gtk_print_operation_set_n_pages:
982  * @op: a #GtkPrintOperation
983  * @n_pages: the number of pages
984  * 
985  * Sets the number of pages in the document. 
986  *
987  * This <emphasis>must</emphasis> be set to a positive number
988  * before the rendering starts. It may be set in a ::begin-print 
989  * signal hander.
990  *
991  * Note that the page numbers passed to the ::request-page-setup 
992  * and ::draw-page signals are 0-based, i.e. if the user chooses
993  * to print all pages, the last ::draw-page signal will be
994  * for page @n_pages - 1.
995  *
996  * Since: 2.10
997  **/
998 void
999 gtk_print_operation_set_n_pages (GtkPrintOperation *op,
1000                                  gint               n_pages)
1001 {
1002   GtkPrintOperationPrivate *priv;
1003
1004   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1005   g_return_if_fail (n_pages > 0);
1006
1007   priv = op->priv;
1008   g_return_if_fail (priv->current_page == -1 || 
1009                     priv->current_page < n_pages);
1010
1011   if (priv->nr_of_pages != n_pages)
1012     {
1013       priv->nr_of_pages = n_pages;
1014
1015       g_object_notify (G_OBJECT (op), "n-pages");
1016     }
1017 }
1018
1019 /**
1020  * gtk_print_operation_set_current_page:
1021  * @op: a #GtkPrintOperation
1022  * @current_page: the current page, 0-based
1023  *
1024  * Sets the current page.
1025  *
1026  * If this is called before gtk_print_operation_run(), 
1027  * the user will be able to select to print only the current page.
1028  *
1029  * Note that this only makes sense for pre-paginated documents.
1030  * 
1031  * Since: 2.10
1032  **/
1033 void
1034 gtk_print_operation_set_current_page (GtkPrintOperation *op,
1035                                       gint               current_page)
1036 {
1037   GtkPrintOperationPrivate *priv;
1038
1039   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1040   g_return_if_fail (current_page >= 0);
1041
1042   priv = op->priv;
1043   g_return_if_fail (priv->nr_of_pages == -1 || 
1044                     current_page < priv->nr_of_pages);
1045
1046   if (priv->current_page != current_page)
1047     {
1048       priv->current_page = current_page;
1049
1050       g_object_notify (G_OBJECT (op), "current-page");
1051     }
1052 }
1053
1054 /**
1055  * gtk_print_operation_set_use_full_page:
1056  * @op: a #GtkPrintOperation
1057  * @full_page: %TRUE to set up the #GtkPrintContext for the full page
1058  * 
1059  * If @full_page is %TRUE, the transformation for the cairo context 
1060  * obtained from #GtkPrintContext puts the origin at the top left 
1061  * corner of the page (which may not be the top left corner of the 
1062  * sheet, depending on page orientation and the number of pages per 
1063  * sheet). Otherwise, the origin is at the top left corner of the
1064  * imageable area (i.e. inside the margins).
1065  * 
1066  * Since: 2.10 
1067  */
1068 void
1069 gtk_print_operation_set_use_full_page (GtkPrintOperation *op,
1070                                        gboolean           full_page)
1071 {
1072   GtkPrintOperationPrivate *priv;
1073
1074   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1075
1076   full_page = full_page != FALSE;
1077  
1078   priv = op->priv;
1079         
1080   if (priv->use_full_page != full_page)
1081     {
1082       priv->use_full_page = full_page;
1083    
1084       g_object_notify (G_OBJECT (op), "use-full-page");
1085     }
1086 }
1087
1088 /**
1089  * gtk_print_operation_set_unit:
1090  * @op: a #GtkPrintOperation
1091  * @unit: the unit to use
1092  * 
1093  * Sets up the transformation for the cairo context obtained from
1094  * #GtkPrintContext in such a way that distances are measured in 
1095  * units of @unit.
1096  *
1097  * Since: 2.10
1098  */
1099 void
1100 gtk_print_operation_set_unit (GtkPrintOperation *op,
1101                               GtkUnit            unit)
1102 {
1103   GtkPrintOperationPrivate *priv;
1104
1105   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1106
1107   priv = op->priv;
1108
1109   if (priv->unit != unit)
1110     {
1111       priv->unit = unit;
1112
1113       g_object_notify (G_OBJECT (op), "unit");
1114     }
1115 }
1116
1117 /**
1118  * gtk_print_operation_set_track_print_status:
1119  * @op: a #GtkPrintOperation
1120  * @track_status: %TRUE to track status after printing
1121  * 
1122  * If track_status is %TRUE, the print operation will try to continue report
1123  * on the status of the print job in the printer queues and printer. This
1124  * can allow your application to show things like "out of paper" issues,
1125  * and when the print job actually reaches the printer.
1126  * 
1127  * This function is often implemented using some form of polling, so it should
1128  * not be enabled unless needed.
1129  *
1130  * Since: 2.10
1131  */
1132 void
1133 gtk_print_operation_set_track_print_status (GtkPrintOperation  *op,
1134                                             gboolean            track_status)
1135 {
1136   GtkPrintOperationPrivate *priv;
1137
1138   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1139
1140   priv = op->priv;
1141
1142   if (priv->track_print_status != track_status)
1143     {
1144       priv->track_print_status = track_status;
1145
1146       g_object_notify (G_OBJECT (op), "track-print-status");
1147     }
1148 }
1149
1150 void
1151 _gtk_print_operation_set_status (GtkPrintOperation *op,
1152                                  GtkPrintStatus     status,
1153                                  const gchar       *string)
1154 {
1155   GtkPrintOperationPrivate *priv = op->priv;
1156   static const gchar *status_strs[] = {
1157     /* translators, strip the prefix up to and including the first | */
1158     N_("print operation status|Initial state"),
1159     /* translators, strip the prefix up to and including the first | */
1160     N_("print operation status|Preparing to print"),
1161     /* translators, strip the prefix up to and including the first | */
1162     N_("print operation status|Generating data"),
1163     /* translators, strip the prefix up to and including the first | */
1164     N_("print operation status|Sending data"),
1165     /* translators, strip the prefix up to and including the first | */
1166     N_("print operation status|Waiting"),
1167     /* translators, strip the prefix up to and including the first | */
1168     N_("print operation status|Blocking on issue"),
1169     /* translators, strip the prefix up to and including the first | */
1170     N_("print operation status|Printing"),
1171     /* translators, strip the prefix up to and including the first | */
1172     N_("print operation status|Finished"),
1173     /* translators, strip the prefix up to and including the first | */
1174     N_("print operation status|Finished with error")
1175   };
1176
1177   if (status < 0 || status > GTK_PRINT_STATUS_FINISHED_ABORTED)
1178     status = GTK_PRINT_STATUS_FINISHED_ABORTED;
1179
1180   if (string == NULL)
1181     string = g_strip_context (status_strs[status],
1182                               gettext (status_strs[status]));
1183   
1184   if (priv->status == status &&
1185       strcmp (string, priv->status_string) == 0)
1186     return;
1187   
1188   g_free (priv->status_string);
1189   priv->status_string = g_strdup (string);
1190   priv->status = status;
1191
1192   g_object_notify (G_OBJECT (op), "status");
1193   g_object_notify (G_OBJECT (op), "status-string");
1194
1195   g_signal_emit (op, signals[STATUS_CHANGED], 0);
1196 }
1197
1198
1199 /**
1200  * gtk_print_operation_get_status:
1201  * @op: a #GtkPrintOperation
1202  * 
1203  * Returns the status of the print operation. 
1204  * Also see gtk_print_operation_get_status_string().
1205  * 
1206  * Return value: the status of the print operation
1207  *
1208  * Since: 2.10
1209  **/
1210 GtkPrintStatus
1211 gtk_print_operation_get_status (GtkPrintOperation *op)
1212 {
1213   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
1214                         GTK_PRINT_STATUS_FINISHED_ABORTED);
1215
1216   return op->priv->status;
1217 }
1218
1219 /**
1220  * gtk_print_operation_get_status_string:
1221  * @op: a #GtkPrintOperation
1222  * 
1223  * Returns a string representation of the status of the 
1224  * print operation. The string is translated and suitable
1225  * for displaying the print status e.g. in a #GtkStatusbar.
1226  *
1227  * Use gtk_print_operation_get_status() to obtain a status
1228  * value that is suitable for programmatic use. 
1229  * 
1230  * Return value: a string representation of the status
1231  *    of the print operation
1232  *
1233  * Since: 2.10
1234  **/
1235 G_CONST_RETURN gchar *
1236 gtk_print_operation_get_status_string (GtkPrintOperation *op)
1237 {
1238   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), "");
1239
1240   return op->priv->status_string;
1241 }
1242
1243 /**
1244  * gtk_print_operation_is_finished:
1245  * @op: a #GtkPrintOperation
1246  * 
1247  * A convenience function to find out if the print operation
1248  * is finished, either successfully (%GTK_PRINT_STATUS_FINISHED)
1249  * or unsuccessfully (%GTK_PRINT_STATUS_FINISHED_ABORTED).
1250  * 
1251  * Return value: %TRUE, if the print operation is finished.
1252  *
1253  * Since: 2.10
1254  **/
1255 gboolean
1256 gtk_print_operation_is_finished (GtkPrintOperation *op)
1257 {
1258   GtkPrintOperationPrivate *priv;
1259
1260   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), TRUE);
1261
1262   priv = op->priv;
1263   return
1264     priv->status == GTK_PRINT_STATUS_FINISHED_ABORTED ||
1265     priv->status == GTK_PRINT_STATUS_FINISHED;
1266 }
1267
1268
1269 /**
1270  * gtk_print_operation_set_show_dialog:
1271  * @op: a #GtkPrintOperation
1272  * @show_dialog: %TRUE to show the print dialog
1273  * 
1274  * Sets whether calling gtk_print_operation_run() will present
1275  * a print dialog to the user, or just print to the default printer.
1276  *
1277  * Since: 2.10
1278  */
1279 void
1280 gtk_print_operation_set_show_dialog (GtkPrintOperation *op,
1281                                      gboolean           show_dialog)
1282 {
1283   GtkPrintOperationPrivate *priv;
1284
1285   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1286
1287   priv = op->priv;
1288
1289   show_dialog = show_dialog != FALSE;
1290
1291   if (priv->show_dialog != show_dialog)
1292     {
1293       priv->show_dialog = show_dialog;
1294
1295       g_object_notify (G_OBJECT (op), "show-dialog");
1296     }
1297 }
1298
1299
1300 /**
1301  * gtk_print_operation_set_show_progress:
1302  * @op: a #GtkPrintOperation
1303  * @show_progress: %TRUE to show a progress dialog
1304  * 
1305  * If @show_progress is %TRUE, the print operation will show a 
1306  * progress dialog during the print operation.
1307  * 
1308  * Since: 2.10
1309  */
1310 void
1311 gtk_print_operation_set_show_progress (GtkPrintOperation  *op,
1312                                        gboolean            show_progress)
1313 {
1314   GtkPrintOperationPrivate *priv;
1315
1316   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1317
1318   priv = op->priv;
1319
1320   show_progress = show_progress != FALSE;
1321
1322   if (priv->show_progress != show_progress)
1323     {
1324       priv->show_progress = show_progress;
1325
1326       g_object_notify (G_OBJECT (op), "show-progress");
1327     }
1328 }
1329
1330 /**
1331  * gtk_print_operation_set_custom_tag_label:
1332  * @op: a #GtkPrintOperation
1333  * @label: the label to use, or %NULL to use the default label
1334  *
1335  * Sets the label for the tab holding custom widgets.
1336  *
1337  * Since: 2.10
1338  */
1339 void
1340 gtk_print_operation_set_custom_tab_label (GtkPrintOperation  *op,
1341                                           const gchar        *label)
1342 {
1343   GtkPrintOperationPrivate *priv;
1344
1345   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1346
1347   priv = op->priv;
1348
1349   g_free (priv->custom_tab_label);
1350   priv->custom_tab_label = g_strdup (label);
1351
1352   g_object_notify (G_OBJECT (op), "custom-tab-label");
1353 }
1354
1355
1356 /**
1357  * gtk_print_operation_set_pdf_target:
1358  * @op: a #GtkPrintOperation
1359  * @filename: the filename for the PDF file
1360  * 
1361  * Sets up the #GtkPrintOperation to generate a PDF file instead
1362  * of showing the print dialog. The indended use of this function
1363  * is for implementing "Export to PDF" actions.
1364  *
1365  * "Print to PDF" support is independent of this and is done
1366  * by letting the user pick the "Print to PDF" item from the list
1367  * of printers in the print dialog.
1368  *
1369  * Since: 2.10
1370  */
1371 void
1372 gtk_print_operation_set_pdf_target (GtkPrintOperation *op,
1373                                     const gchar       *filename)
1374 {
1375   GtkPrintOperationPrivate *priv;
1376
1377   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
1378
1379   priv = op->priv;
1380
1381   g_free (priv->pdf_target);
1382   priv->pdf_target = g_strdup (filename);
1383
1384   g_object_notify (G_OBJECT (op), "pdf-target");
1385 }
1386
1387 /* Creates the initial page setup used for printing unless the
1388  * app overrides this on a per-page basis using request_page_setup.
1389  *
1390  * Data is taken from, in order, if existing:
1391  *
1392  * PrintSettings returned from the print dialog
1393  *  (initial dialog values are set from default_page_setup
1394  *   if unset in app specified print_settings)
1395  * default_page_setup
1396  * per-locale default setup
1397  */
1398 static GtkPageSetup *
1399 create_page_setup (GtkPrintOperation *op)
1400 {
1401   GtkPrintOperationPrivate *priv = op->priv;
1402   GtkPageSetup *page_setup;
1403   GtkPrintSettings *settings;
1404   
1405   if (priv->default_page_setup)
1406     page_setup = gtk_page_setup_copy (priv->default_page_setup);
1407   else
1408     page_setup = gtk_page_setup_new ();
1409
1410   settings = priv->print_settings;
1411   if (settings)
1412     {
1413       GtkPaperSize *paper_size;
1414       
1415       if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
1416         gtk_page_setup_set_orientation (page_setup,
1417                                         gtk_print_settings_get_orientation (settings));
1418
1419
1420       paper_size = gtk_print_settings_get_paper_size (settings);
1421       if (paper_size)
1422         {
1423           gtk_page_setup_set_paper_size (page_setup, paper_size);
1424           gtk_paper_size_free (paper_size);
1425         }
1426
1427       /* TODO: Margins? */
1428     }
1429   
1430   return page_setup;
1431 }
1432
1433 static void 
1434 pdf_start_page (GtkPrintOperation *op,
1435                 GtkPrintContext   *print_context,
1436                 GtkPageSetup      *page_setup)
1437 {
1438   GtkPaperSize *paper_size;
1439   double w, h;
1440
1441   paper_size = gtk_page_setup_get_paper_size (page_setup);
1442
1443   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
1444   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
1445   
1446   cairo_pdf_surface_set_size (op->priv->surface, w, h);
1447 }
1448
1449 static void
1450 pdf_end_page (GtkPrintOperation *op,
1451               GtkPrintContext   *print_context)
1452 {
1453   cairo_t *cr;
1454
1455   cr = gtk_print_context_get_cairo_context (print_context);
1456   cairo_show_page (cr);
1457 }
1458
1459 static void
1460 pdf_end_run (GtkPrintOperation *op,
1461              gboolean           wait,
1462              gboolean           cancelled)
1463 {
1464   GtkPrintOperationPrivate *priv = op->priv;
1465
1466   cairo_surface_destroy (priv->surface);
1467   priv->surface = NULL;
1468 }
1469
1470 static GtkPrintOperationResult
1471 run_pdf (GtkPrintOperation  *op,
1472          GtkWindow          *parent,
1473          gboolean           *do_print,
1474          GError            **error)
1475 {
1476   GtkPrintOperationPrivate *priv = op->priv;
1477   GtkPageSetup *page_setup;
1478   double width, height;
1479   /* This will be overwritten later by the non-default size, but
1480      we need to pass some size: */
1481   
1482   page_setup = create_page_setup (op);
1483   width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
1484   height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
1485   g_object_unref (page_setup);
1486   
1487   priv->surface = cairo_pdf_surface_create (priv->pdf_target,
1488                                             width, height);
1489   cairo_pdf_surface_set_dpi (priv->surface, 300, 300);
1490   
1491   priv->dpi_x = 72;
1492   priv->dpi_y = 72;
1493
1494   priv->print_pages = GTK_PRINT_PAGES_ALL;
1495   priv->page_ranges = NULL;
1496   priv->num_page_ranges = 0;
1497
1498   priv->manual_num_copies = 1;
1499   priv->manual_collation = FALSE;
1500   priv->manual_reverse = FALSE;
1501   priv->manual_page_set = GTK_PAGE_SET_ALL;
1502   priv->manual_scale = 1.0;
1503   priv->manual_orientation = TRUE;
1504   
1505   *do_print = TRUE;
1506   
1507   priv->start_page = pdf_start_page;
1508   priv->end_page = pdf_end_page;
1509   priv->end_run = pdf_end_run;
1510   
1511   return GTK_PRINT_OPERATION_RESULT_APPLY; 
1512 }
1513
1514 typedef struct
1515 {
1516   GtkPrintOperation *op;
1517   gint uncollated_copies;
1518   gint collated_copies;
1519   gint uncollated, collated, total;
1520
1521   gint range, num_ranges;
1522   GtkPageRange *ranges;
1523   GtkPageRange one_range;
1524
1525   gint page, start, end, inc;
1526
1527   GtkPageSetup *initial_page_setup;
1528   GtkPrintContext *print_context;  
1529
1530   GtkWidget *progress;
1531 } PrintPagesData;
1532
1533 static void
1534 find_range (PrintPagesData *data)
1535 {
1536   GtkPageRange *range;
1537
1538   range = &data->ranges[data->range];
1539
1540   if (data->inc < 0)
1541     {
1542       data->start = range->end;
1543       data->end = range->start - 1;
1544     }
1545   else
1546     {
1547       data->start = range->start;
1548       data->end = range->end + 1;
1549     }
1550 }
1551
1552 static gboolean 
1553 increment_page_sequence (PrintPagesData *data)
1554 {
1555   GtkPrintOperationPrivate *priv = data->op->priv;
1556
1557   do {
1558     data->page += data->inc;
1559     if (data->page == data->end)
1560       {
1561         data->range += data->inc;
1562         if (data->range == -1 || data->range == data->num_ranges)
1563           {
1564             data->uncollated++;
1565             if (data->uncollated == data->uncollated_copies)
1566               return FALSE;
1567
1568             data->range = data->inc < 0 ? data->num_ranges - 1 : 0;
1569           }
1570         find_range (data);
1571         data->page = data->start;
1572       }
1573   }
1574   while ((priv->manual_page_set == GTK_PAGE_SET_EVEN && data->page % 2 == 0) ||
1575          (priv->manual_page_set == GTK_PAGE_SET_ODD && data->page % 2 == 1));
1576
1577   return TRUE;
1578 }
1579
1580 static void
1581 print_pages_idle_done (gpointer user_data)
1582 {
1583   PrintPagesData *data;
1584   GtkPrintOperationPrivate *priv;
1585
1586   GDK_THREADS_ENTER ();
1587
1588   data = (PrintPagesData*)user_data;
1589   priv = data->op->priv;
1590
1591   priv->print_pages_idle_id = 0;
1592
1593   if (priv->show_progress_timeout_id > 0)
1594     {
1595       g_source_remove (priv->show_progress_timeout_id);
1596       priv->show_progress_timeout_id = 0;
1597     }
1598  
1599   if (data->progress)
1600     gtk_widget_destroy (data->progress);
1601
1602   g_object_unref (data->print_context);
1603   g_object_unref (data->initial_page_setup);
1604
1605   g_object_unref (data->op);
1606
1607   if (priv->rloop)
1608     g_main_loop_quit (priv->rloop);
1609
1610   g_free (data);
1611
1612   GDK_THREADS_LEAVE ();
1613 }
1614
1615 static void
1616 update_progress (PrintPagesData *data)
1617 {
1618   GtkPrintOperationPrivate *priv; 
1619   gchar *text = NULL;
1620   
1621   priv = data->op->priv;
1622  
1623   if (data->progress)
1624     {
1625       if (priv->status == GTK_PRINT_STATUS_PREPARING)
1626         {
1627           if (priv->nr_of_pages > 0)
1628             text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages);
1629           else
1630             text = g_strdup (_("Preparing"));
1631         }
1632       else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA)
1633         text = g_strdup_printf (_("Printing %d"), data->total);
1634       
1635       if (text)
1636         {
1637           g_object_set (data->progress, "text", text, NULL);
1638           g_free (text);
1639         }
1640     }
1641  }
1642
1643 static gboolean
1644 print_pages_idle (gpointer user_data)
1645 {
1646   PrintPagesData *data; 
1647   GtkPrintOperationPrivate *priv; 
1648   GtkPageSetup *page_setup;
1649   cairo_t *cr;
1650   gboolean done = FALSE;
1651
1652   GDK_THREADS_ENTER ();
1653
1654   data = (PrintPagesData*)user_data;
1655   priv = data->op->priv;
1656
1657   if (priv->status == GTK_PRINT_STATUS_PREPARING)
1658     {
1659       if (!data->print_context)
1660         {
1661           data->print_context = _gtk_print_context_new (data->op);
1662           data->initial_page_setup = create_page_setup (data->op);
1663
1664           _gtk_print_context_set_page_setup (data->print_context, 
1665                                              data->initial_page_setup);
1666       
1667           g_signal_emit (data->op, signals[BEGIN_PRINT], 0, data->print_context);
1668       
1669           if (priv->manual_collation)
1670             {
1671               data->uncollated_copies = priv->manual_num_copies;
1672               data->collated_copies = 1;
1673             }
1674           else
1675             {
1676               data->uncollated_copies = 1;
1677               data->collated_copies = priv->manual_num_copies;
1678             }
1679
1680           goto out;
1681         }
1682       
1683       if (g_signal_has_handler_pending (data->op, signals[PAGINATE], 0, FALSE))
1684         {
1685           gboolean paginated = FALSE;
1686
1687           g_signal_emit (data->op, signals[PAGINATE], 0, data->print_context, &paginated);
1688           if (!paginated)
1689             goto out;
1690         }
1691
1692       /* FIXME handle this better */
1693       if (priv->nr_of_pages == 0)
1694         g_warning ("no pages to print");
1695       
1696       /* Initialize parts of PrintPagesData that depend on nr_of_pages
1697        */
1698       if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
1699         {
1700           data->ranges = priv->page_ranges;
1701           data->num_ranges = priv->num_page_ranges;
1702         }
1703       else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
1704                priv->current_page != -1)
1705         {
1706           data->ranges = &data->one_range;
1707           data->num_ranges = 1;
1708           data->ranges[0].start = priv->current_page;
1709           data->ranges[0].end = priv->current_page;
1710         }
1711       else
1712         {
1713           data->ranges = &data->one_range;
1714           data->num_ranges = 1;
1715           data->ranges[0].start = 0;
1716           data->ranges[0].end = priv->nr_of_pages - 1;
1717         }
1718       
1719       if (priv->manual_reverse)
1720         {
1721           data->range = data->num_ranges - 1;
1722           data->inc = -1;      
1723         }
1724       else
1725         {
1726           data->range = 0;
1727           data->inc = 1;      
1728         }
1729       find_range (data);
1730      
1731       /* go back one page, since we preincrement below */
1732       data->page = data->start - data->inc;
1733       data->collated = data->collated_copies - 1;
1734
1735       _gtk_print_operation_set_status (data->op, 
1736                                        GTK_PRINT_STATUS_GENERATING_DATA, 
1737                                        NULL);
1738
1739       goto out;
1740     }
1741
1742   data->total++;
1743   data->collated++;
1744   if (data->collated == data->collated_copies)
1745     {
1746       data->collated = 0;
1747       if (!increment_page_sequence (data))
1748         {
1749           done = TRUE;
1750
1751           goto out;
1752         }
1753     }
1754
1755   page_setup = gtk_page_setup_copy (data->initial_page_setup);
1756   g_signal_emit (data->op, signals[REQUEST_PAGE_SETUP], 0, 
1757                  data->print_context, data->page, page_setup);
1758   
1759   _gtk_print_context_set_page_setup (data->print_context, page_setup);
1760   priv->start_page (data->op, data->print_context, page_setup);
1761   
1762   cr = gtk_print_context_get_cairo_context (data->print_context);
1763   
1764   cairo_save (cr);
1765   if (priv->manual_scale != 1.0)
1766     cairo_scale (cr,
1767                  priv->manual_scale,
1768                  priv->manual_scale);
1769   
1770   if (priv->manual_orientation)
1771     _gtk_print_context_rotate_according_to_orientation (data->print_context);
1772   
1773   if (!priv->use_full_page)
1774     _gtk_print_context_translate_into_margin (data->print_context);
1775   
1776   g_signal_emit (data->op, signals[DRAW_PAGE], 0, 
1777                  data->print_context, data->page);
1778   
1779   priv->end_page (data->op, data->print_context);
1780   
1781   cairo_restore (cr);
1782   
1783   g_object_unref (page_setup);
1784
1785  out:
1786
1787   if (priv->cancelled)
1788     {
1789       _gtk_print_operation_set_status (data->op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
1790       
1791       done = TRUE;
1792     }
1793
1794   if (done)
1795     {
1796       g_signal_emit (data->op, signals[END_PRINT], 0, data->print_context);
1797       
1798       cairo_surface_finish (priv->surface);
1799       priv->end_run (data->op, priv->is_sync, priv->cancelled);
1800     }
1801
1802   update_progress (data);
1803
1804   GDK_THREADS_LEAVE ();
1805
1806   return !done;
1807 }
1808   
1809 static void
1810 handle_progress_response (GtkWidget *dialog, 
1811                           gint       response,
1812                           gpointer   data)
1813 {
1814   GtkPrintOperation *op = (GtkPrintOperation *)data;
1815
1816   gtk_widget_hide (dialog);
1817   gtk_print_operation_cancel (op);
1818 }
1819
1820 static gboolean
1821 show_progress_timeout (PrintPagesData *data)
1822 {
1823   GDK_THREADS_ENTER ();
1824
1825   gtk_window_present (GTK_WINDOW (data->progress));
1826
1827   data->op->priv->show_progress_timeout_id = 0;
1828
1829   GDK_THREADS_LEAVE ();
1830
1831   return FALSE;
1832 }
1833
1834 static void
1835 print_pages (GtkPrintOperation *op,
1836              GtkWindow         *parent)
1837 {
1838   GtkPrintOperationPrivate *priv = op->priv;
1839   PrintPagesData *data;
1840  
1841   _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);  
1842
1843   data = g_new0 (PrintPagesData, 1);
1844   data->op = g_object_ref (op);
1845
1846   if (priv->show_progress)
1847     {
1848       GtkWidget *progress;
1849
1850       progress = gtk_message_dialog_new (parent, 0, 
1851                                          GTK_MESSAGE_OTHER,
1852                                          GTK_BUTTONS_CANCEL,
1853                                          _("Preparing"));
1854       g_signal_connect (progress, "response", 
1855                         G_CALLBACK (handle_progress_response), op);
1856
1857       priv->show_progress_timeout_id = 
1858         g_timeout_add (SHOW_PROGRESS_TIME, 
1859                        (GSourceFunc)show_progress_timeout,
1860                        data);
1861
1862       data->progress = progress;
1863     }
1864
1865   priv->print_pages_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
1866                                                print_pages_idle, 
1867                                                data, 
1868                                                print_pages_idle_done);
1869
1870   /* Recursive main loop to make sure we don't exit 
1871    * on sync operations 
1872    */
1873   if (priv->is_sync)
1874     {
1875       priv->rloop = g_main_loop_new (NULL, FALSE);
1876
1877       GDK_THREADS_LEAVE ();
1878       g_main_loop_run (priv->rloop);
1879       GDK_THREADS_ENTER ();
1880     }
1881   g_main_loop_unref (priv->rloop);
1882   priv->rloop = NULL;
1883 }
1884
1885 /**
1886  * gtk_print_operation_run:
1887  * @op: a #GtkPrintOperation
1888  * @parent: Transient parent of the dialog, or %NULL
1889  * @error: Return location for errors, or %NULL
1890  * 
1891  * Runs the print operation, by first letting the user modify
1892  * print settings in the print dialog, and then print the
1893  * document.
1894  *
1895  * Note that this function does not return until the rendering of all 
1896  * pages is complete. You can connect to the ::status-changed signal on
1897  * @op to obtain some information about the progress of the print operation. 
1898  * Furthermore, it may use a recursive mainloop to show the print dialog.
1899  * See gtk_print_operation_run_async() if this is a problem.
1900  *
1901  * <informalexample><programlisting>
1902  * if (settings != NULL)
1903  *   gtk_print_operation_set_print_settings (print, settings);
1904  *   
1905  * if (page_setup != NULL)
1906  *   gtk_print_operation_set_default_page_setup (print, page_setup);
1907  *  
1908  * g_signal_connect (print, "begin-print", 
1909  *                   G_CALLBACK (begin_print), &amp;data);
1910  * g_signal_connect (print, "draw-page", 
1911  *                   G_CALLBACK (draw_page), &amp;data);
1912  * 
1913  * res = gtk_print_operation_run (print, parent, &amp;error);
1914  * 
1915  * if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
1916  *  {
1917  *    error_dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
1918  *                                           GTK_DIALOG_DESTROY_WITH_PARENT,
1919  *                                           GTK_MESSAGE_ERROR,
1920  *                                           GTK_BUTTONS_CLOSE,
1921  *                                           "Error printing file:\n%s",
1922  *                                           error->message);
1923  *    g_signal_connect (error_dialog, "response", 
1924  *                      G_CALLBACK (gtk_widget_destroy), NULL);
1925  *    gtk_widget_show (error_dialog);
1926  *    g_error_free (error);
1927  *  }
1928  * else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
1929  *  {
1930  *    if (settings != NULL)
1931  *      g_object_unref (settings);
1932  *    settings = g_object_ref (gtk_print_operation_get_print_settings (print));
1933  *  }
1934  * </programlisting></informalexample>
1935  *
1936  * Return value: the result of the print operation. A return value of 
1937  *   %GTK_PRINT_OPERATION_RESULT_APPLY indicates that the printing was
1938  *   completed successfully. In this case, it is a good idea to obtain 
1939  *   the used print settings with gtk_print_operation_get_print_settings() 
1940  *   and store them for reuse with the next print operation.
1941  *
1942  * Since: 2.10
1943  **/
1944 GtkPrintOperationResult
1945 gtk_print_operation_run (GtkPrintOperation  *op,
1946                          GtkWindow          *parent,
1947                          GError            **error)
1948 {
1949   GtkPrintOperationPrivate *priv;
1950   GtkPrintOperationResult result;
1951   gboolean do_print;
1952   
1953   g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), 
1954                         GTK_PRINT_OPERATION_RESULT_ERROR);
1955
1956   priv = op->priv;
1957   priv->is_sync = TRUE;
1958
1959   if (priv->pdf_target != NULL)
1960     result = run_pdf (op, parent, &do_print, error);
1961   else
1962     result = _gtk_print_operation_platform_backend_run_dialog (op, 
1963                                                                parent,
1964                                                                &do_print,
1965                                                                error);
1966   if (do_print)
1967     print_pages (op, parent);
1968   else 
1969     _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
1970
1971   return result;
1972 }
1973
1974 /**
1975  * gtk_print_operation_run_async:
1976  * @op: a #GtkPrintOperation
1977  * @parent: Transient parent of the dialog, or %NULL
1978  * 
1979  * Runs the print operation, by first letting the user modify
1980  * print settings in the print dialog, and then print the
1981  * document.
1982  *
1983  * In contrast to gtk_print_operation_run(), this function returns after 
1984  * showing the print dialog on platforms that support this, and handles 
1985  * the printing by connecting a signal handler to the ::response signal 
1986  * of the dialog. 
1987  * 
1988  * If you use this function, it is recommended that you store the modified
1989  * #GtkPrintSettings in a ::begin-print or ::end-print signal handler.
1990  * 
1991  * Since: 2.10
1992  **/
1993 void
1994 gtk_print_operation_run_async (GtkPrintOperation *op,
1995                                GtkWindow         *parent)
1996 {
1997   GtkPrintOperationPrivate *priv;
1998   gboolean do_print;
1999
2000   g_return_if_fail (GTK_IS_PRINT_OPERATION (op)); 
2001
2002   priv = op->priv;
2003   priv->is_sync = FALSE;
2004
2005   if (priv->pdf_target != NULL)
2006     {
2007       run_pdf (op, parent, &do_print, NULL);
2008       if (do_print)
2009         print_pages (op, parent);
2010       else 
2011         _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
2012     }
2013   else
2014     _gtk_print_operation_platform_backend_run_dialog_async (op, 
2015                                                             parent,
2016                                                             print_pages);
2017 }
2018
2019
2020 /**
2021  * gtk_print_operation_cancel:
2022  * @op: a #GtkPrintOperation
2023  *
2024  * Cancels a running print operation. This function may
2025  * be called from a begin-print, paginate or draw-page
2026  * signal handler to stop the currently running print 
2027  * operation.
2028  *
2029  * Since: 2.10
2030  */
2031 void
2032 gtk_print_operation_cancel (GtkPrintOperation *op)
2033 {
2034   g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
2035   
2036   op->priv->cancelled = TRUE;
2037 }
2038
2039
2040
2041 #define __GTK_PRINT_OPERATION_C__
2042 #include "gtkaliasdef.c"