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 | |
76 | typedef 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 | |
82 | struct _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 | |
92 | struct _GtkPageSetupClass |
93 | { |
94 | GObjectClass parent_class; |
95 | }; |
96 | |
97 | G_DEFINE_TYPE (GtkPageSetup, gtk_page_setup, G_TYPE_OBJECT) |
98 | |
99 | static void |
100 | gtk_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 | |
109 | static void |
110 | gtk_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 | |
120 | static void |
121 | gtk_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 | */ |
135 | GtkPageSetup * |
136 | gtk_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 | */ |
149 | GtkPageSetup * |
150 | gtk_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 | */ |
174 | GtkPageOrientation |
175 | gtk_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 | */ |
187 | void |
188 | gtk_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 | */ |
202 | GtkPaperSize * |
203 | gtk_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 | */ |
220 | void |
221 | gtk_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 | */ |
245 | void |
246 | gtk_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 | */ |
265 | double |
266 | gtk_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 | */ |
280 | void |
281 | gtk_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 | */ |
297 | double |
298 | gtk_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 | */ |
312 | void |
313 | gtk_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 | */ |
329 | double |
330 | gtk_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 | */ |
344 | void |
345 | gtk_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 | */ |
361 | double |
362 | gtk_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 | */ |
376 | void |
377 | gtk_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 | */ |
397 | double |
398 | gtk_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 | */ |
421 | double |
422 | gtk_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 | */ |
445 | double |
446 | gtk_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 | */ |
474 | double |
475 | gtk_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 | */ |
502 | gboolean |
503 | gtk_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 | */ |
537 | GtkPageSetup * |
538 | gtk_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! */ |
553 | static guint |
554 | string_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 | */ |
586 | gboolean |
587 | gtk_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 | |
655 | out: |
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 | */ |
675 | GtkPageSetup * |
676 | gtk_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 | */ |
701 | gboolean |
702 | gtk_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 | |
723 | out: |
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! */ |
731 | static char * |
732 | enum_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 | */ |
759 | void |
760 | gtk_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 | */ |
802 | GVariant * |
803 | gtk_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 | */ |
843 | GtkPageSetup * |
844 | gtk_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 | |