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