]> Pileus Git - ~andy/gtk/blob - gtk/gtkpagesetup.c
0ba69d33fa3e491bb6f0a8692a528e733daf48b9
[~andy/gtk] / gtk / gtkpagesetup.c
1 /* GTK - The GIMP Toolkit
2  * gtkpagesetup.c: Page Setup
3  * Copyright (C) 2006, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include "gtkpagesetup.h"
24 #include "gtkprintutils.h"
25 #include "gtkprintoperation.h" /* for GtkPrintError */
26 #include "gtkintl.h"
27 #include "gtktypebuiltins.h"
28
29 /**
30  * SECTION:gtkpagesetup
31  * @Short_description: Stores page setup information
32  * @Title: GtkPageSetup
33  *
34  * A GtkPageSetup object stores the page size, orientation and margins.
35  * The idea is that you can get one of these from the page setup dialog
36  * and then pass it to the #GtkPrintOperation when printing.
37  * The benefit of splitting this out of the #GtkPrintSettings is that
38  * these affect the actual layout of the page, and thus need to be set
39  * long before user prints.
40  *
41  * <para id="print-margins">
42  * The margins specified in this object are the "print margins", i.e. the
43  * parts of the page that the printer cannot print on. These are different
44  * from the layout margins that a word processor uses; they are typically
45  * used to determine the <emphasis>minimal</emphasis> size for the layout
46  * margins.
47  * </para>
48  *
49  * To obtain a #GtkPageSetup use gtk_page_setup_new() to get the defaults,
50  * or use gtk_print_run_page_setup_dialog() to show the page setup dialog
51  * and receive the resulting page setup.
52  *
53  * <example>
54  * <title>A page setup dialog</title>
55  * <programlisting>
56  * static GtkPrintSettings *settings = NULL;
57  * static GtkPageSetup *page_setup = NULL;
58  *
59  * static void
60  * do_page_setup (void)
61  * {
62  *   GtkPageSetup *new_page_setup;
63  *
64  *   if (settings == NULL)
65  *     settings = gtk_print_settings_new (<!-- -->);
66  *
67  *   new_page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (main_window),
68  *                                                     page_setup, settings);
69  *
70  *   if (page_setup)
71  *     g_object_unref (page_setup);
72  *
73  *   page_setup = new_page_setup;
74  * }
75  * </programlisting>
76  * </example>
77  *
78  * Printing support was added in GTK+ 2.10.
79  */
80
81 #define KEYFILE_GROUP_NAME "Page Setup"
82
83 typedef struct _GtkPageSetupClass GtkPageSetupClass;
84
85 #define GTK_IS_PAGE_SETUP_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PAGE_SETUP))
86 #define GTK_PAGE_SETUP_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PAGE_SETUP, GtkPageSetupClass))
87 #define GTK_PAGE_SETUP_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PAGE_SETUP, GtkPageSetupClass))
88
89 struct _GtkPageSetup
90 {
91   GObject parent_instance;
92
93   GtkPageOrientation orientation;
94   GtkPaperSize *paper_size;
95   /* These are stored in mm */
96   double top_margin, bottom_margin, left_margin, right_margin;
97 };
98
99 struct _GtkPageSetupClass
100 {
101   GObjectClass parent_class;
102 };
103
104 G_DEFINE_TYPE (GtkPageSetup, gtk_page_setup, G_TYPE_OBJECT)
105
106 static void
107 gtk_page_setup_finalize (GObject *object)
108 {
109   GtkPageSetup *setup = GTK_PAGE_SETUP (object);
110   
111   gtk_paper_size_free (setup->paper_size);
112   
113   G_OBJECT_CLASS (gtk_page_setup_parent_class)->finalize (object);
114 }
115
116 static void
117 gtk_page_setup_init (GtkPageSetup *setup)
118 {
119   setup->paper_size = gtk_paper_size_new (NULL);
120   setup->orientation = GTK_PAGE_ORIENTATION_PORTRAIT;
121   setup->top_margin = gtk_paper_size_get_default_top_margin (setup->paper_size, GTK_UNIT_MM);
122   setup->bottom_margin = gtk_paper_size_get_default_bottom_margin (setup->paper_size, GTK_UNIT_MM);
123   setup->left_margin = gtk_paper_size_get_default_left_margin (setup->paper_size, GTK_UNIT_MM);
124   setup->right_margin = gtk_paper_size_get_default_right_margin (setup->paper_size, GTK_UNIT_MM);
125 }
126
127 static void
128 gtk_page_setup_class_init (GtkPageSetupClass *class)
129 {
130   GObjectClass *gobject_class = (GObjectClass *)class;
131
132   gobject_class->finalize = gtk_page_setup_finalize;
133 }
134
135 /**
136  * gtk_page_setup_new:
137  *
138  * Creates a new #GtkPageSetup. 
139  * 
140  * Return value: a new #GtkPageSetup.
141  *
142  * Since: 2.10
143  */
144 GtkPageSetup *
145 gtk_page_setup_new (void)
146 {
147   return g_object_new (GTK_TYPE_PAGE_SETUP, NULL);
148 }
149
150 /**
151  * gtk_page_setup_copy:
152  * @other: the #GtkPageSetup to copy
153  *
154  * Copies a #GtkPageSetup.
155  *
156  * Return value: (transfer full): a copy of @other
157  *
158  * Since: 2.10
159  */
160 GtkPageSetup *
161 gtk_page_setup_copy (GtkPageSetup *other)
162 {
163   GtkPageSetup *copy;
164
165   copy = gtk_page_setup_new ();
166   copy->orientation = other->orientation;
167   gtk_paper_size_free (copy->paper_size);
168   copy->paper_size = gtk_paper_size_copy (other->paper_size);
169   copy->top_margin = other->top_margin;
170   copy->bottom_margin = other->bottom_margin;
171   copy->left_margin = other->left_margin;
172   copy->right_margin = other->right_margin;
173
174   return copy;
175 }
176
177 /**
178  * gtk_page_setup_get_orientation:
179  * @setup: a #GtkPageSetup
180  * 
181  * Gets the page orientation of the #GtkPageSetup.
182  * 
183  * Return value: the page orientation
184  *
185  * Since: 2.10
186  */
187 GtkPageOrientation
188 gtk_page_setup_get_orientation (GtkPageSetup *setup)
189 {
190   return setup->orientation;
191 }
192
193 /**
194  * gtk_page_setup_set_orientation:
195  * @setup: a #GtkPageSetup
196  * @orientation: a #GtkPageOrientation value
197  * 
198  * Sets the page orientation of the #GtkPageSetup.
199  *
200  * Since: 2.10
201  */
202 void
203 gtk_page_setup_set_orientation (GtkPageSetup       *setup,
204                                 GtkPageOrientation  orientation)
205 {
206   setup->orientation = orientation;
207 }
208
209 /**
210  * gtk_page_setup_get_paper_size:
211  * @setup: a #GtkPageSetup
212  * 
213  * Gets the paper size of the #GtkPageSetup.
214  * 
215  * Return value: the paper size
216  *
217  * Since: 2.10
218  */
219 GtkPaperSize *
220 gtk_page_setup_get_paper_size (GtkPageSetup *setup)
221 {
222   g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), NULL);
223
224   return setup->paper_size;
225 }
226
227 /**
228  * gtk_page_setup_set_paper_size:
229  * @setup: a #GtkPageSetup
230  * @size: a #GtkPaperSize 
231  * 
232  * Sets the paper size of the #GtkPageSetup without
233  * changing the margins. See 
234  * gtk_page_setup_set_paper_size_and_default_margins().
235  *
236  * Since: 2.10
237  */
238 void
239 gtk_page_setup_set_paper_size (GtkPageSetup *setup,
240                                GtkPaperSize *size)
241 {
242   GtkPaperSize *old_size;
243
244   g_return_if_fail (GTK_IS_PAGE_SETUP (setup));
245   g_return_if_fail (size != NULL);
246
247   old_size = setup->paper_size;
248
249   setup->paper_size = gtk_paper_size_copy (size);
250
251   if (old_size)
252     gtk_paper_size_free (old_size);
253 }
254
255 /**
256  * gtk_page_setup_set_paper_size_and_default_margins:
257  * @setup: a #GtkPageSetup
258  * @size: a #GtkPaperSize 
259  * 
260  * Sets the paper size of the #GtkPageSetup and modifies
261  * the margins according to the new paper size.
262  *
263  * Since: 2.10
264  */
265 void
266 gtk_page_setup_set_paper_size_and_default_margins (GtkPageSetup *setup,
267                                                    GtkPaperSize *size)
268 {
269   gtk_page_setup_set_paper_size (setup, size);
270   setup->top_margin = gtk_paper_size_get_default_top_margin (setup->paper_size, GTK_UNIT_MM);
271   setup->bottom_margin = gtk_paper_size_get_default_bottom_margin (setup->paper_size, GTK_UNIT_MM);
272   setup->left_margin = gtk_paper_size_get_default_left_margin (setup->paper_size, GTK_UNIT_MM);
273   setup->right_margin = gtk_paper_size_get_default_right_margin (setup->paper_size, GTK_UNIT_MM);
274 }
275
276 /**
277  * gtk_page_setup_get_top_margin:
278  * @setup: a #GtkPageSetup
279  * @unit: the unit for the return value
280  * 
281  * Gets the top margin in units of @unit.
282  * 
283  * Return value: the top margin
284  *
285  * Since: 2.10
286  */
287 gdouble
288 gtk_page_setup_get_top_margin (GtkPageSetup *setup,
289                                GtkUnit       unit)
290 {
291   return _gtk_print_convert_from_mm (setup->top_margin, unit);
292 }
293
294 /**
295  * gtk_page_setup_set_top_margin:
296  * @setup: a #GtkPageSetup
297  * @margin: the new top margin in units of @unit
298  * @unit: the units for @margin
299  * 
300  * Sets the top margin of the #GtkPageSetup.
301  *
302  * Since: 2.10
303  */
304 void
305 gtk_page_setup_set_top_margin (GtkPageSetup *setup,
306                                gdouble       margin,
307                                GtkUnit       unit)
308 {
309   setup->top_margin = _gtk_print_convert_to_mm (margin, unit);
310 }
311
312 /**
313  * gtk_page_setup_get_bottom_margin:
314  * @setup: a #GtkPageSetup
315  * @unit: the unit for the return value
316  * 
317  * Gets the bottom margin in units of @unit.
318  * 
319  * Return value: the bottom margin
320  *
321  * Since: 2.10
322  */
323 gdouble
324 gtk_page_setup_get_bottom_margin (GtkPageSetup *setup,
325                                   GtkUnit       unit)
326 {
327   return _gtk_print_convert_from_mm (setup->bottom_margin, unit);
328 }
329
330 /**
331  * gtk_page_setup_set_bottom_margin:
332  * @setup: a #GtkPageSetup
333  * @margin: the new bottom margin in units of @unit
334  * @unit: the units for @margin
335  * 
336  * Sets the bottom margin of the #GtkPageSetup.
337  *
338  * Since: 2.10
339  */
340 void
341 gtk_page_setup_set_bottom_margin (GtkPageSetup *setup,
342                                   gdouble       margin,
343                                   GtkUnit       unit)
344 {
345   setup->bottom_margin = _gtk_print_convert_to_mm (margin, unit);
346 }
347
348 /**
349  * gtk_page_setup_get_left_margin:
350  * @setup: a #GtkPageSetup
351  * @unit: the unit for the return value
352  * 
353  * Gets the left margin in units of @unit.
354  * 
355  * Return value: the left margin
356  *
357  * Since: 2.10
358  */
359 gdouble
360 gtk_page_setup_get_left_margin (GtkPageSetup *setup,
361                                 GtkUnit       unit)
362 {
363   return _gtk_print_convert_from_mm (setup->left_margin, unit);
364 }
365
366 /**
367  * gtk_page_setup_set_left_margin:
368  * @setup: a #GtkPageSetup
369  * @margin: the new left margin in units of @unit
370  * @unit: the units for @margin
371  * 
372  * Sets the left margin of the #GtkPageSetup.
373  *
374  * Since: 2.10
375  */
376 void
377 gtk_page_setup_set_left_margin (GtkPageSetup *setup,
378                                 gdouble       margin,
379                                 GtkUnit       unit)
380 {
381   setup->left_margin = _gtk_print_convert_to_mm (margin, unit);
382 }
383
384 /**
385  * gtk_page_setup_get_right_margin:
386  * @setup: a #GtkPageSetup
387  * @unit: the unit for the return value
388  * 
389  * Gets the right margin in units of @unit.
390  * 
391  * Return value: the right margin
392  *
393  * Since: 2.10
394  */
395 gdouble
396 gtk_page_setup_get_right_margin (GtkPageSetup *setup,
397                                  GtkUnit       unit)
398 {
399   return _gtk_print_convert_from_mm (setup->right_margin, unit);
400 }
401
402 /**
403  * gtk_page_setup_set_right_margin:
404  * @setup: a #GtkPageSetup
405  * @margin: the new right margin in units of @unit
406  * @unit: the units for @margin
407  * 
408  * Sets the right margin of the #GtkPageSetup.
409  *
410  * Since: 2.10
411  */
412 void
413 gtk_page_setup_set_right_margin (GtkPageSetup *setup,
414                                  gdouble       margin,
415                                  GtkUnit       unit)
416 {
417   setup->right_margin = _gtk_print_convert_to_mm (margin, unit);
418 }
419
420 /**
421  * gtk_page_setup_get_paper_width:
422  * @setup: a #GtkPageSetup
423  * @unit: the unit for the return value
424  * 
425  * Returns the paper width in units of @unit.
426  * 
427  * Note that this function takes orientation, but 
428  * not margins into consideration. 
429  * See gtk_page_setup_get_page_width().
430  *
431  * Return value: the paper width.
432  *
433  * Since: 2.10
434  */
435 gdouble
436 gtk_page_setup_get_paper_width (GtkPageSetup *setup,
437                                 GtkUnit       unit)
438 {
439   if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
440       setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
441     return gtk_paper_size_get_width (setup->paper_size, unit);
442   else
443     return gtk_paper_size_get_height (setup->paper_size, unit);
444 }
445
446 /**
447  * gtk_page_setup_get_paper_height:
448  * @setup: a #GtkPageSetup
449  * @unit: the unit for the return value
450  * 
451  * Returns the paper height in units of @unit.
452  * 
453  * Note that this function takes orientation, but 
454  * not margins into consideration.
455  * See gtk_page_setup_get_page_height().
456  *
457  * Return value: the paper height.
458  *
459  * Since: 2.10
460  */
461 gdouble
462 gtk_page_setup_get_paper_height (GtkPageSetup *setup,
463                                  GtkUnit       unit)
464 {
465   if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
466       setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
467     return gtk_paper_size_get_height (setup->paper_size, unit);
468   else
469     return gtk_paper_size_get_width (setup->paper_size, unit);
470 }
471
472 /**
473  * gtk_page_setup_get_page_width:
474  * @setup: a #GtkPageSetup
475  * @unit: the unit for the return value
476  * 
477  * Returns the page width in units of @unit.
478  * 
479  * Note that this function takes orientation and
480  * margins into consideration. 
481  * See gtk_page_setup_get_paper_width().
482  *
483  * Return value: the page width.
484  *
485  * Since: 2.10
486  */
487 gdouble
488 gtk_page_setup_get_page_width (GtkPageSetup *setup,
489                                GtkUnit       unit)
490 {
491   gdouble width;
492   
493   width = gtk_page_setup_get_paper_width (setup, GTK_UNIT_MM);
494   width -= setup->left_margin + setup->right_margin;
495   
496   return _gtk_print_convert_from_mm (width, unit);
497 }
498
499 /**
500  * gtk_page_setup_get_page_height:
501  * @setup: a #GtkPageSetup
502  * @unit: the unit for the return value
503  * 
504  * Returns the page height in units of @unit.
505  * 
506  * Note that this function takes orientation and
507  * margins into consideration. 
508  * See gtk_page_setup_get_paper_height().
509  *
510  * Return value: the page height.
511  *
512  * Since: 2.10
513  */
514 gdouble
515 gtk_page_setup_get_page_height (GtkPageSetup *setup,
516                                 GtkUnit       unit)
517 {
518   gdouble height;
519   
520   height = gtk_page_setup_get_paper_height (setup, GTK_UNIT_MM);
521   height -= setup->top_margin + setup->bottom_margin;
522   
523   return _gtk_print_convert_from_mm (height, unit);
524 }
525
526 /**
527  * gtk_page_setup_load_file:
528  * @setup: a #GtkPageSetup
529  * @file_name: (type filename): the filename to read the page setup from
530  * @error: (allow-none): return location for an error, or %NULL
531  *
532  * Reads the page setup from the file @file_name.
533  * See gtk_page_setup_to_file().
534  *
535  * Return value: %TRUE on success
536  *
537  * Since: 2.14
538  */
539 gboolean
540 gtk_page_setup_load_file (GtkPageSetup *setup,
541                           const gchar  *file_name,
542                           GError      **error)
543 {
544   gboolean retval = FALSE;
545   GKeyFile *key_file;
546
547   g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), FALSE);
548   g_return_val_if_fail (file_name != NULL, FALSE);
549
550   key_file = g_key_file_new ();
551
552   if (g_key_file_load_from_file (key_file, file_name, 0, error) &&
553       gtk_page_setup_load_key_file (setup, key_file, NULL, error))
554     retval = TRUE;
555
556   g_key_file_free (key_file);
557
558   return retval;
559 }
560
561 /**
562  * gtk_page_setup_new_from_file:
563  * @file_name: (type filename): the filename to read the page setup from
564  * @error: (allow-none): return location for an error, or %NULL
565  * 
566  * Reads the page setup from the file @file_name. Returns a 
567  * new #GtkPageSetup object with the restored page setup, 
568  * or %NULL if an error occurred. See gtk_page_setup_to_file().
569  *
570  * Return value: the restored #GtkPageSetup
571  * 
572  * Since: 2.12
573  */
574 GtkPageSetup *
575 gtk_page_setup_new_from_file (const gchar  *file_name,
576                               GError      **error)
577 {
578   GtkPageSetup *setup = gtk_page_setup_new ();
579
580   if (!gtk_page_setup_load_file (setup, file_name, error))
581     {
582       g_object_unref (setup);
583       setup = NULL;
584     }
585
586   return setup;
587 }
588
589 /* something like this should really be in gobject! */
590 static guint
591 string_to_enum (GType type,
592                 const char *enum_string)
593 {
594   GEnumClass *enum_class;
595   const GEnumValue *value;
596   guint retval = 0;
597
598   g_return_val_if_fail (enum_string != NULL, 0);
599
600   enum_class = g_type_class_ref (type);
601   value = g_enum_get_value_by_nick (enum_class, enum_string);
602   if (value)
603     retval = value->value;
604
605   g_type_class_unref (enum_class);
606
607   return retval;
608 }
609
610 /**
611  * gtk_page_setup_load_key_file:
612  * @setup: a #GtkPageSetup
613  * @key_file: the #GKeyFile to retrieve the page_setup from
614  * @group_name: (allow-none): the name of the group in the key_file to read, or %NULL
615  *              to use the default name "Page Setup"
616  * @error: (allow-none): return location for an error, or %NULL
617  * 
618  * Reads the page setup from the group @group_name in the key file
619  * @key_file.
620  * 
621  * Return value: %TRUE on success
622  *
623  * Since: 2.14
624  */
625 gboolean
626 gtk_page_setup_load_key_file (GtkPageSetup *setup,
627                               GKeyFile     *key_file,
628                               const gchar  *group_name,
629                               GError      **error)
630 {
631   GtkPaperSize *paper_size;
632   gdouble top, bottom, left, right;
633   char *orientation = NULL, *freeme = NULL;
634   gboolean retval = FALSE;
635   GError *err = NULL;
636
637   g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), FALSE);
638   g_return_val_if_fail (key_file != NULL, FALSE);
639
640   if (!group_name)
641     group_name = KEYFILE_GROUP_NAME;
642
643   if (!g_key_file_has_group (key_file, group_name))
644     {
645       g_set_error_literal (error,
646                            GTK_PRINT_ERROR,
647                            GTK_PRINT_ERROR_INVALID_FILE,
648                            _("Not a valid page setup file"));
649       goto out;
650     }
651
652 #define GET_DOUBLE(kf, group, name, v) \
653   v = g_key_file_get_double (kf, group, name, &err); \
654   if (err != NULL) \
655     { \
656       g_propagate_error (error, err);\
657       goto out;\
658     }
659
660   GET_DOUBLE (key_file, group_name, "MarginTop", top);
661   GET_DOUBLE (key_file, group_name, "MarginBottom", bottom);
662   GET_DOUBLE (key_file, group_name, "MarginLeft", left);
663   GET_DOUBLE (key_file, group_name, "MarginRight", right);
664
665 #undef GET_DOUBLE
666
667   paper_size = gtk_paper_size_new_from_key_file (key_file, group_name, &err);
668   if (!paper_size)
669     {
670       g_propagate_error (error, err);
671       goto out;
672     }
673
674   gtk_page_setup_set_paper_size (setup, paper_size);
675   gtk_paper_size_free (paper_size);
676
677   gtk_page_setup_set_top_margin (setup, top, GTK_UNIT_MM);
678   gtk_page_setup_set_bottom_margin (setup, bottom, GTK_UNIT_MM);
679   gtk_page_setup_set_left_margin (setup, left, GTK_UNIT_MM);
680   gtk_page_setup_set_right_margin (setup, right, GTK_UNIT_MM);
681
682   orientation = g_key_file_get_string (key_file, group_name,
683                                        "Orientation", NULL);
684   if (orientation)
685     {
686       gtk_page_setup_set_orientation (setup,
687                                       string_to_enum (GTK_TYPE_PAGE_ORIENTATION,
688                                                       orientation));
689       g_free (orientation);
690     }
691
692   retval = TRUE;
693
694 out:
695   g_free (freeme);
696   return retval;
697 }
698
699 /**
700  * gtk_page_setup_new_from_key_file:
701  * @key_file: the #GKeyFile to retrieve the page_setup from
702  * @group_name: (allow-none): the name of the group in the key_file to read, or %NULL
703  *              to use the default name "Page Setup"
704  * @error: (allow-none): return location for an error, or %NULL
705  *
706  * Reads the page setup from the group @group_name in the key file
707  * @key_file. Returns a new #GtkPageSetup object with the restored
708  * page setup, or %NULL if an error occurred.
709  *
710  * Return value: the restored #GtkPageSetup
711  *
712  * Since: 2.12
713  */
714 GtkPageSetup *
715 gtk_page_setup_new_from_key_file (GKeyFile     *key_file,
716                                   const gchar  *group_name,
717                                   GError      **error)
718 {
719   GtkPageSetup *setup = gtk_page_setup_new ();
720
721   if (!gtk_page_setup_load_key_file (setup, key_file, group_name, error))
722     {
723       g_object_unref (setup);
724       setup = NULL;
725     }
726
727   return setup;
728 }
729
730 /**
731  * gtk_page_setup_to_file:
732  * @setup: a #GtkPageSetup
733  * @file_name: (type filename): the file to save to
734  * @error: (allow-none): return location for errors, or %NULL
735  * 
736  * This function saves the information from @setup to @file_name.
737  * 
738  * Return value: %TRUE on success
739  *
740  * Since: 2.12
741  */
742 gboolean
743 gtk_page_setup_to_file (GtkPageSetup  *setup,
744                         const char    *file_name,
745                         GError       **error)
746 {
747   GKeyFile *key_file;
748   gboolean retval = FALSE;
749   char *data = NULL;
750   gsize len;
751
752   g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), FALSE);
753   g_return_val_if_fail (file_name != NULL, FALSE);
754
755   key_file = g_key_file_new ();
756   gtk_page_setup_to_key_file (setup, key_file, NULL);
757
758   data = g_key_file_to_data (key_file, &len, error);
759   if (!data)
760     goto out;
761
762   retval = g_file_set_contents (file_name, data, len, error);
763
764 out:
765   g_key_file_free (key_file);
766   g_free (data);
767
768   return retval;
769 }
770
771 /* something like this should really be in gobject! */
772 static char *
773 enum_to_string (GType type,
774                 guint enum_value)
775 {
776   GEnumClass *enum_class;
777   GEnumValue *value;
778   char *retval = NULL;
779
780   enum_class = g_type_class_ref (type);
781
782   value = g_enum_get_value (enum_class, enum_value);
783   if (value)
784     retval = g_strdup (value->value_nick);
785
786   g_type_class_unref (enum_class);
787
788   return retval;
789 }
790
791 /**
792  * gtk_page_setup_to_key_file:
793  * @setup: a #GtkPageSetup
794  * @key_file: the #GKeyFile to save the page setup to
795  * @group_name: the group to add the settings to in @key_file, 
796  *      or %NULL to use the default name "Page Setup"
797  * 
798  * This function adds the page setup from @setup to @key_file.
799  * 
800  * Since: 2.12
801  */
802 void
803 gtk_page_setup_to_key_file (GtkPageSetup *setup,
804                             GKeyFile     *key_file,
805                             const gchar  *group_name)
806 {
807   GtkPaperSize *paper_size;
808   char *orientation;
809
810   g_return_if_fail (GTK_IS_PAGE_SETUP (setup));
811   g_return_if_fail (key_file != NULL);
812
813   if (!group_name)
814     group_name = KEYFILE_GROUP_NAME;
815
816   paper_size = gtk_page_setup_get_paper_size (setup);
817   g_assert (paper_size != NULL);
818
819   gtk_paper_size_to_key_file (paper_size, key_file, group_name);
820
821   g_key_file_set_double (key_file, group_name,
822                          "MarginTop", gtk_page_setup_get_top_margin (setup, GTK_UNIT_MM));
823   g_key_file_set_double (key_file, group_name,
824                          "MarginBottom", gtk_page_setup_get_bottom_margin (setup, GTK_UNIT_MM));
825   g_key_file_set_double (key_file, group_name,
826                          "MarginLeft", gtk_page_setup_get_left_margin (setup, GTK_UNIT_MM));
827   g_key_file_set_double (key_file, group_name,
828                          "MarginRight", gtk_page_setup_get_right_margin (setup, GTK_UNIT_MM));
829
830   orientation = enum_to_string (GTK_TYPE_PAGE_ORIENTATION,
831                                 gtk_page_setup_get_orientation (setup));
832   g_key_file_set_string (key_file, group_name,
833                          "Orientation", orientation);
834   g_free (orientation);
835 }