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

source code of gtk/gtk/gtkpagesetup.c