gtkpagesetup.c 23.7 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 * gtkpagesetup.c: Page Setup
 * Copyright (C) 2006, Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
16
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17
18
19
20
21
 */

#include "config.h"

#include "gtkpagesetup.h"
Matthias Clasen's avatar
Matthias Clasen committed
22
#include "gtkprintutils.h"
Matthias Clasen's avatar
Matthias Clasen committed
23
24
25
#include "gtkprintoperation.h" /* for GtkPrintError */
#include "gtkintl.h"
#include "gtktypebuiltins.h"
26

27
/**
Matthias Clasen's avatar
Matthias Clasen committed
28
29
30
 * GtkPageSetup:
 *
 * 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
Matthias Clasen's avatar
Matthias Clasen committed
33
34
 * and then pass it to the `GtkPrintOperation` when printing.
 * The benefit of splitting this out of the `GtkPrintSettings` is that
35
36
37
 * these affect the actual layout of the page, and thus need to be set
 * long before user prints.
 *
Matthias Clasen's avatar
Matthias Clasen committed
38
39
 * ## Margins
 *
William Jon McCann's avatar
William Jon McCann committed
40
 * The margins specified in this object are the “print margins”, i.e. the
41
42
 * parts of the page that the printer cannot print on. These are different
 * from the layout margins that a word processor uses; they are typically
Matthias Clasen's avatar
Matthias Clasen committed
43
 * used to determine the minimal size for the layout margins.
44
 *
Matthias Clasen's avatar
Matthias Clasen committed
45
46
 * To obtain a `GtkPageSetup` use [ctor@Gtk.PageSetup.new] to get the defaults,
 * or use [func@Gtk.print_run_page_setup_dialog] to show the page setup dialog
47
48
 * and receive the resulting page setup.
 *
49
50
 * ## A page setup dialog
 *
Matthias Clasen's avatar
Matthias Clasen committed
51
 * ```c
52
53
54
55
56
57
58
59
60
 * static GtkPrintSettings *settings = NULL;
 * static GtkPageSetup *page_setup = NULL;
 *
 * static void
 * do_page_setup (void)
 * {
 *   GtkPageSetup *new_page_setup;
 *
 *   if (settings == NULL)
61
 *     settings = gtk_print_settings_new ();
62
63
64
65
66
67
68
69
70
 *
 *   new_page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (main_window),
 *                                                     page_setup, settings);
 *
 *   if (page_setup)
 *     g_object_unref (page_setup);
 *
 *   page_setup = new_page_setup;
 * }
Matthias Clasen's avatar
Matthias Clasen committed
71
 * ```
72
73
 */

Matthias Clasen's avatar
Matthias Clasen committed
74
#define KEYFILE_GROUP_NAME "Page Setup"
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

typedef struct _GtkPageSetupClass GtkPageSetupClass;

#define GTK_IS_PAGE_SETUP_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PAGE_SETUP))
#define GTK_PAGE_SETUP_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PAGE_SETUP, GtkPageSetupClass))
#define GTK_PAGE_SETUP_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PAGE_SETUP, GtkPageSetupClass))

struct _GtkPageSetup
{
  GObject parent_instance;

  GtkPageOrientation orientation;
  GtkPaperSize *paper_size;
  /* These are stored in mm */
  double top_margin, bottom_margin, left_margin, right_margin;
};

struct _GtkPageSetupClass
{
  GObjectClass parent_class;
};

G_DEFINE_TYPE (GtkPageSetup, gtk_page_setup, G_TYPE_OBJECT)

static void
gtk_page_setup_finalize (GObject *object)
{
  GtkPageSetup *setup = GTK_PAGE_SETUP (object);
  
  gtk_paper_size_free (setup->paper_size);
  
  G_OBJECT_CLASS (gtk_page_setup_parent_class)->finalize (object);
}

static void
gtk_page_setup_init (GtkPageSetup *setup)
{
  setup->paper_size = gtk_paper_size_new (NULL);
  setup->orientation = GTK_PAGE_ORIENTATION_PORTRAIT;
  setup->top_margin = gtk_paper_size_get_default_top_margin (setup->paper_size, GTK_UNIT_MM);
  setup->bottom_margin = gtk_paper_size_get_default_bottom_margin (setup->paper_size, GTK_UNIT_MM);
  setup->left_margin = gtk_paper_size_get_default_left_margin (setup->paper_size, GTK_UNIT_MM);
  setup->right_margin = gtk_paper_size_get_default_right_margin (setup->paper_size, GTK_UNIT_MM);
}

static void
gtk_page_setup_class_init (GtkPageSetupClass *class)
{
  GObjectClass *gobject_class = (GObjectClass *)class;

  gobject_class->finalize = gtk_page_setup_finalize;
}
Matthias Clasen's avatar
Matthias Clasen committed
127
128
129
130

/**
 * gtk_page_setup_new:
 *
Matthias Clasen's avatar
Matthias Clasen committed
131
132
133
 * Creates a new `GtkPageSetup`.
 *
 * Returns: a new `GtkPageSetup`.
Matthias Clasen's avatar
Matthias Clasen committed
134
 */
135
136
137
138
139
140
GtkPageSetup *
gtk_page_setup_new (void)
{
  return g_object_new (GTK_TYPE_PAGE_SETUP, NULL);
}

Matthias Clasen's avatar
Matthias Clasen committed
141
142
/**
 * gtk_page_setup_copy:
Matthias Clasen's avatar
Matthias Clasen committed
143
 * @other: the `GtkPageSetup` to copy
Matthias Clasen's avatar
Matthias Clasen committed
144
 *
Matthias Clasen's avatar
Matthias Clasen committed
145
 * Copies a `GtkPageSetup`.
Matthias Clasen's avatar
Matthias Clasen committed
146
 *
147
 * Returns: (transfer full): a copy of @other
Matthias Clasen's avatar
Matthias Clasen committed
148
 */
149
150
151
152
153
154
155
GtkPageSetup *
gtk_page_setup_copy (GtkPageSetup *other)
{
  GtkPageSetup *copy;

  copy = gtk_page_setup_new ();
  copy->orientation = other->orientation;
156
  gtk_paper_size_free (copy->paper_size);
157
158
159
160
161
162
163
164
165
  copy->paper_size = gtk_paper_size_copy (other->paper_size);
  copy->top_margin = other->top_margin;
  copy->bottom_margin = other->bottom_margin;
  copy->left_margin = other->left_margin;
  copy->right_margin = other->right_margin;

  return copy;
}

Matthias Clasen's avatar
Matthias Clasen committed
166
167
/**
 * gtk_page_setup_get_orientation:
Matthias Clasen's avatar
Matthias Clasen committed
168
169
170
171
 * @setup: a `GtkPageSetup`
 *
 * Gets the page orientation of the `GtkPageSetup`.
 *
172
 * Returns: the page orientation
Matthias Clasen's avatar
Matthias Clasen committed
173
 */
174
175
176
177
178
179
GtkPageOrientation
gtk_page_setup_get_orientation (GtkPageSetup *setup)
{
  return setup->orientation;
}

Matthias Clasen's avatar
Matthias Clasen committed
180
181
/**
 * gtk_page_setup_set_orientation:
Matthias Clasen's avatar
Matthias Clasen committed
182
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
183
 * @orientation: a `GtkPageOrientation` value
Matthias Clasen's avatar
Matthias Clasen committed
184
185
 *
 * Sets the page orientation of the `GtkPageSetup`.
Matthias Clasen's avatar
Matthias Clasen committed
186
 */
187
void
Matthias Clasen's avatar
Matthias Clasen committed
188
189
gtk_page_setup_set_orientation (GtkPageSetup       *setup,
				GtkPageOrientation  orientation)
190
191
192
193
{
  setup->orientation = orientation;
}

Matthias Clasen's avatar
Matthias Clasen committed
194
195
/**
 * gtk_page_setup_get_paper_size:
Matthias Clasen's avatar
Matthias Clasen committed
196
197
198
199
 * @setup: a `GtkPageSetup`
 *
 * Gets the paper size of the `GtkPageSetup`.
 *
200
 * Returns: (transfer none): the paper size
Matthias Clasen's avatar
Matthias Clasen committed
201
 */
202
203
204
GtkPaperSize *
gtk_page_setup_get_paper_size (GtkPageSetup *setup)
{
205
206
  g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), NULL);

207
208
209
  return setup->paper_size;
}

Matthias Clasen's avatar
Matthias Clasen committed
210
211
/**
 * gtk_page_setup_set_paper_size:
Matthias Clasen's avatar
Matthias Clasen committed
212
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
213
 * @size: a `GtkPaperSize`
Matthias Clasen's avatar
Matthias Clasen committed
214
215
216
217
218
 *
 * Sets the paper size of the `GtkPageSetup` without
 * changing the margins.
 *
 * See [method@Gtk.PageSetup.set_paper_size_and_default_margins].
Matthias Clasen's avatar
Matthias Clasen committed
219
 */
220
221
222
223
void
gtk_page_setup_set_paper_size (GtkPageSetup *setup,
			       GtkPaperSize *size)
{
224
225
226
227
228
229
230
  GtkPaperSize *old_size;

  g_return_if_fail (GTK_IS_PAGE_SETUP (setup));
  g_return_if_fail (size != NULL);

  old_size = setup->paper_size;

231
  setup->paper_size = gtk_paper_size_copy (size);
232
233
234

  if (old_size)
    gtk_paper_size_free (old_size);
235
236
}

Matthias Clasen's avatar
Matthias Clasen committed
237
238
/**
 * gtk_page_setup_set_paper_size_and_default_margins:
Matthias Clasen's avatar
Matthias Clasen committed
239
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
240
 * @size: a `GtkPaperSize`
Matthias Clasen's avatar
Matthias Clasen committed
241
242
 *
 * Sets the paper size of the `GtkPageSetup` and modifies
Matthias Clasen's avatar
Matthias Clasen committed
243
244
 * the margins according to the new paper size.
 */
245
246
247
248
void
gtk_page_setup_set_paper_size_and_default_margins (GtkPageSetup *setup,
						   GtkPaperSize *size)
{
249
  gtk_page_setup_set_paper_size (setup, size);
250
251
252
253
254
255
  setup->top_margin = gtk_paper_size_get_default_top_margin (setup->paper_size, GTK_UNIT_MM);
  setup->bottom_margin = gtk_paper_size_get_default_bottom_margin (setup->paper_size, GTK_UNIT_MM);
  setup->left_margin = gtk_paper_size_get_default_left_margin (setup->paper_size, GTK_UNIT_MM);
  setup->right_margin = gtk_paper_size_get_default_right_margin (setup->paper_size, GTK_UNIT_MM);
}

Matthias Clasen's avatar
Matthias Clasen committed
256
257
/**
 * gtk_page_setup_get_top_margin:
Matthias Clasen's avatar
Matthias Clasen committed
258
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
259
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
260
 *
Matthias Clasen's avatar
Matthias Clasen committed
261
 * Gets the top margin in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
262
 *
263
 * Returns: the top margin
Matthias Clasen's avatar
Matthias Clasen committed
264
 */
265
double
266
267
268
gtk_page_setup_get_top_margin (GtkPageSetup *setup,
			       GtkUnit       unit)
{
Matthias Clasen's avatar
Matthias Clasen committed
269
  return _gtk_print_convert_from_mm (setup->top_margin, unit);
270
271
}

Matthias Clasen's avatar
Matthias Clasen committed
272
273
/**
 * gtk_page_setup_set_top_margin:
Matthias Clasen's avatar
Matthias Clasen committed
274
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
275
276
 * @margin: the new top margin in units of @unit
 * @unit: the units for @margin
Matthias Clasen's avatar
Matthias Clasen committed
277
278
 *
 * Sets the top margin of the `GtkPageSetup`.
Matthias Clasen's avatar
Matthias Clasen committed
279
 */
280
281
void
gtk_page_setup_set_top_margin (GtkPageSetup *setup,
282
			       double        margin,
283
284
			       GtkUnit       unit)
{
Matthias Clasen's avatar
Matthias Clasen committed
285
  setup->top_margin = _gtk_print_convert_to_mm (margin, unit);
286
287
}

Matthias Clasen's avatar
Matthias Clasen committed
288
289
/**
 * gtk_page_setup_get_bottom_margin:
Matthias Clasen's avatar
Matthias Clasen committed
290
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
291
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
292
 *
Matthias Clasen's avatar
Matthias Clasen committed
293
 * Gets the bottom margin in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
294
 *
295
 * Returns: the bottom margin
Matthias Clasen's avatar
Matthias Clasen committed
296
 */
297
double
298
299
300
gtk_page_setup_get_bottom_margin (GtkPageSetup *setup,
				  GtkUnit       unit)
{
Matthias Clasen's avatar
Matthias Clasen committed
301
  return _gtk_print_convert_from_mm (setup->bottom_margin, unit);
302
303
}

Matthias Clasen's avatar
Matthias Clasen committed
304
305
/**
 * gtk_page_setup_set_bottom_margin:
Matthias Clasen's avatar
Matthias Clasen committed
306
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
307
308
 * @margin: the new bottom margin in units of @unit
 * @unit: the units for @margin
Matthias Clasen's avatar
Matthias Clasen committed
309
310
 *
 * Sets the bottom margin of the `GtkPageSetup`.
Matthias Clasen's avatar
Matthias Clasen committed
311
 */
312
313
void
gtk_page_setup_set_bottom_margin (GtkPageSetup *setup,
314
				  double        margin,
315
316
				  GtkUnit       unit)
{
Matthias Clasen's avatar
Matthias Clasen committed
317
  setup->bottom_margin = _gtk_print_convert_to_mm (margin, unit);
318
319
}

Matthias Clasen's avatar
Matthias Clasen committed
320
321
/**
 * gtk_page_setup_get_left_margin:
Matthias Clasen's avatar
Matthias Clasen committed
322
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
323
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
324
 *
Matthias Clasen's avatar
Matthias Clasen committed
325
 * Gets the left margin in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
326
 *
327
 * Returns: the left margin
Matthias Clasen's avatar
Matthias Clasen committed
328
 */
329
double
Matthias Clasen's avatar
Matthias Clasen committed
330
331
gtk_page_setup_get_left_margin (GtkPageSetup *setup,
				GtkUnit       unit)
332
{
Matthias Clasen's avatar
Matthias Clasen committed
333
  return _gtk_print_convert_from_mm (setup->left_margin, unit);
334
335
}

Matthias Clasen's avatar
Matthias Clasen committed
336
337
/**
 * gtk_page_setup_set_left_margin:
Matthias Clasen's avatar
Matthias Clasen committed
338
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
339
340
 * @margin: the new left margin in units of @unit
 * @unit: the units for @margin
Matthias Clasen's avatar
Matthias Clasen committed
341
342
 *
 * Sets the left margin of the `GtkPageSetup`.
Matthias Clasen's avatar
Matthias Clasen committed
343
 */
344
void
Matthias Clasen's avatar
Matthias Clasen committed
345
gtk_page_setup_set_left_margin (GtkPageSetup *setup,
346
				double        margin,
Matthias Clasen's avatar
Matthias Clasen committed
347
				GtkUnit       unit)
348
{
Matthias Clasen's avatar
Matthias Clasen committed
349
  setup->left_margin = _gtk_print_convert_to_mm (margin, unit);
350
351
}

Matthias Clasen's avatar
Matthias Clasen committed
352
353
/**
 * gtk_page_setup_get_right_margin:
Matthias Clasen's avatar
Matthias Clasen committed
354
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
355
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
356
 *
Matthias Clasen's avatar
Matthias Clasen committed
357
 * Gets the right margin in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
358
 *
359
 * Returns: the right margin
Matthias Clasen's avatar
Matthias Clasen committed
360
 */
361
double
Matthias Clasen's avatar
Matthias Clasen committed
362
363
gtk_page_setup_get_right_margin (GtkPageSetup *setup,
				 GtkUnit       unit)
364
{
Matthias Clasen's avatar
Matthias Clasen committed
365
  return _gtk_print_convert_from_mm (setup->right_margin, unit);
366
367
}

Matthias Clasen's avatar
Matthias Clasen committed
368
369
/**
 * gtk_page_setup_set_right_margin:
Matthias Clasen's avatar
Matthias Clasen committed
370
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
371
372
 * @margin: the new right margin in units of @unit
 * @unit: the units for @margin
Matthias Clasen's avatar
Matthias Clasen committed
373
374
 *
 * Sets the right margin of the `GtkPageSetup`.
Matthias Clasen's avatar
Matthias Clasen committed
375
 */
376
void
Matthias Clasen's avatar
Matthias Clasen committed
377
gtk_page_setup_set_right_margin (GtkPageSetup *setup,
378
				 double        margin,
Matthias Clasen's avatar
Matthias Clasen committed
379
				 GtkUnit       unit)
380
{
Matthias Clasen's avatar
Matthias Clasen committed
381
  setup->right_margin = _gtk_print_convert_to_mm (margin, unit);
382
383
}

Matthias Clasen's avatar
Matthias Clasen committed
384
385
/**
 * gtk_page_setup_get_paper_width:
Matthias Clasen's avatar
Matthias Clasen committed
386
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
387
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
388
 *
Matthias Clasen's avatar
Matthias Clasen committed
389
 * Returns the paper width in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
390
391
392
393
 *
 * Note that this function takes orientation,
 * but not margins into consideration.
 * See [method@Gtk.PageSetup.get_page_width].
Matthias Clasen's avatar
Matthias Clasen committed
394
 *
395
 * Returns: the paper width.
Matthias Clasen's avatar
Matthias Clasen committed
396
 */
397
double
398
399
400
401
402
403
404
405
406
407
gtk_page_setup_get_paper_width (GtkPageSetup *setup,
				GtkUnit       unit)
{
  if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
      setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
    return gtk_paper_size_get_width (setup->paper_size, unit);
  else
    return gtk_paper_size_get_height (setup->paper_size, unit);
}

Matthias Clasen's avatar
Matthias Clasen committed
408
409
/**
 * gtk_page_setup_get_paper_height:
Matthias Clasen's avatar
Matthias Clasen committed
410
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
411
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
412
 *
Matthias Clasen's avatar
Matthias Clasen committed
413
 * Returns the paper height in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
414
415
416
417
 *
 * Note that this function takes orientation,
 * but not margins into consideration.
 * See [method@Gtk.PageSetup.get_page_height].
Matthias Clasen's avatar
Matthias Clasen committed
418
 *
419
 * Returns: the paper height.
Matthias Clasen's avatar
Matthias Clasen committed
420
 */
421
double
Matthias Clasen's avatar
Matthias Clasen committed
422
423
gtk_page_setup_get_paper_height (GtkPageSetup *setup,
				 GtkUnit       unit)
424
425
426
427
428
429
430
431
{
  if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
      setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
    return gtk_paper_size_get_height (setup->paper_size, unit);
  else
    return gtk_paper_size_get_width (setup->paper_size, unit);
}

Matthias Clasen's avatar
Matthias Clasen committed
432
433
/**
 * gtk_page_setup_get_page_width:
Matthias Clasen's avatar
Matthias Clasen committed
434
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
435
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
436
 *
Matthias Clasen's avatar
Matthias Clasen committed
437
 * Returns the page width in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
438
439
440
441
 *
 * Note that this function takes orientation
 * and margins into consideration.
 * See [method@Gtk.PageSetup.get_paper_width].
Matthias Clasen's avatar
Matthias Clasen committed
442
 *
443
 * Returns: the page width.
Matthias Clasen's avatar
Matthias Clasen committed
444
 */
445
double
Matthias Clasen's avatar
Matthias Clasen committed
446
447
gtk_page_setup_get_page_width (GtkPageSetup *setup,
			       GtkUnit       unit)
448
{
449
  double width;
450

451
  width = gtk_page_setup_get_paper_width (setup, GTK_UNIT_MM);
452
453
454
455
456
457
  if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
      setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
    width -= setup->left_margin + setup->right_margin;
  else
    width -= setup->top_margin + setup->bottom_margin;

Matthias Clasen's avatar
Matthias Clasen committed
458
  return _gtk_print_convert_from_mm (width, unit);
459
460
}

Matthias Clasen's avatar
Matthias Clasen committed
461
462
/**
 * gtk_page_setup_get_page_height:
Matthias Clasen's avatar
Matthias Clasen committed
463
 * @setup: a `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
464
 * @unit: the unit for the return value
Matthias Clasen's avatar
Matthias Clasen committed
465
 *
Matthias Clasen's avatar
Matthias Clasen committed
466
 * Returns the page height in units of @unit.
Matthias Clasen's avatar
Matthias Clasen committed
467
468
469
470
 *
 * Note that this function takes orientation
 * and margins into consideration.
 * See [method@Gtk.PageSetup.get_paper_height].
Matthias Clasen's avatar
Matthias Clasen committed
471
 *
472
 * Returns: the page height.
Matthias Clasen's avatar
Matthias Clasen committed
473
 */
474
double
Matthias Clasen's avatar
Matthias Clasen committed
475
476
gtk_page_setup_get_page_height (GtkPageSetup *setup,
				GtkUnit       unit)
477
{
478
  double height;
479

480
  height = gtk_page_setup_get_paper_height (setup, GTK_UNIT_MM);
481
482
483
484
485
486
  if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
      setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
    height -= setup->top_margin + setup->bottom_margin;
  else
    height -= setup->left_margin + setup->right_margin;

Matthias Clasen's avatar
Matthias Clasen committed
487
  return _gtk_print_convert_from_mm (height, unit);
488
489
}

490
491
/**
 * gtk_page_setup_load_file:
Matthias Clasen's avatar
Matthias Clasen committed
492
 * @setup: a `GtkPageSetup`
493
 * @file_name: (type filename): the filename to read the page setup from
Matthias Clasen's avatar
Matthias Clasen committed
494
 * @error: (nullable): return location for an error
495
496
 *
 * Reads the page setup from the file @file_name.
Matthias Clasen's avatar
Matthias Clasen committed
497
498
 *
 * See [method@Gtk.PageSetup.to_file].
499
 *
500
 * Returns: %TRUE on success
501
502
503
 */
gboolean
gtk_page_setup_load_file (GtkPageSetup *setup,
Benjamin Otte's avatar
Benjamin Otte committed
504
                          const char   *file_name,
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
			  GError      **error)
{
  gboolean retval = FALSE;
  GKeyFile *key_file;

  g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), FALSE);
  g_return_val_if_fail (file_name != NULL, FALSE);

  key_file = g_key_file_new ();

  if (g_key_file_load_from_file (key_file, file_name, 0, error) &&
      gtk_page_setup_load_key_file (setup, key_file, NULL, error))
    retval = TRUE;

  g_key_file_free (key_file);

  return retval;
}
523

Matthias Clasen's avatar
Matthias Clasen committed
524
525
/**
 * gtk_page_setup_new_from_file:
526
 * @file_name: (type filename): the filename to read the page setup from
Matthias Clasen's avatar
Matthias Clasen committed
527
 * @error: (nullable): return location for an error
Matthias Clasen's avatar
Matthias Clasen committed
528
 *
Matthias Clasen's avatar
Matthias Clasen committed
529
530
531
532
533
534
535
 * Reads the page setup from the file @file_name.
 *
 * Returns a new `GtkPageSetup` object with the restored
 * page setup, or %NULL if an error occurred.
 * See [method@Gtk.PageSetup.to_file].
 *
 * Returns: the restored `GtkPageSetup`
Matthias Clasen's avatar
Matthias Clasen committed
536
537
 */
GtkPageSetup *
Benjamin Otte's avatar
Benjamin Otte committed
538
gtk_page_setup_new_from_file (const char   *file_name,
Matthias Clasen's avatar
Matthias Clasen committed
539
540
			      GError      **error)
{
541
  GtkPageSetup *setup = gtk_page_setup_new ();
Matthias Clasen's avatar
Matthias Clasen committed
542

543
  if (!gtk_page_setup_load_file (setup, file_name, error))
Matthias Clasen's avatar
Matthias Clasen committed
544
    {
545
546
      g_object_unref (setup);
      setup = NULL;
Matthias Clasen's avatar
Matthias Clasen committed
547
548
    }

549
  return setup;
Matthias Clasen's avatar
Matthias Clasen committed
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
}

/* something like this should really be in gobject! */
static guint
string_to_enum (GType type,
                const char *enum_string)
{
  GEnumClass *enum_class;
  const GEnumValue *value;
  guint retval = 0;

  g_return_val_if_fail (enum_string != NULL, 0);

  enum_class = g_type_class_ref (type);
  value = g_enum_get_value_by_nick (enum_class, enum_string);
  if (value)
    retval = value->value;

  g_type_class_unref (enum_class);

  return retval;
}

/**
574
 * gtk_page_setup_load_key_file:
Matthias Clasen's avatar
Matthias Clasen committed
575
576
 * @setup: a `GtkPageSetup`
 * @key_file: the `GKeyFile` to retrieve the page_setup from
Matthias Clasen's avatar
Matthias Clasen committed
577
 * @group_name: (nullable): the name of the group in the key_file to read
Matthias Clasen's avatar
Matthias Clasen committed
578
 *   to use the default name “Page Setup”
Matthias Clasen's avatar
Matthias Clasen committed
579
 * @error: (nullable): return location for an error
Matthias Clasen's avatar
Matthias Clasen committed
580
 *
Matthias Clasen's avatar
Matthias Clasen committed
581
 * Reads the page setup from the group @group_name in the key file
582
 * @key_file.
Matthias Clasen's avatar
Matthias Clasen committed
583
 *
584
 * Returns: %TRUE on success
Matthias Clasen's avatar
Matthias Clasen committed
585
 */
586
587
588
gboolean
gtk_page_setup_load_key_file (GtkPageSetup *setup,
                              GKeyFile     *key_file,
Benjamin Otte's avatar
Benjamin Otte committed
589
                              const char   *group_name,
590
                              GError      **error)
Matthias Clasen's avatar
Matthias Clasen committed
591
592
{
  GtkPaperSize *paper_size;
593
  double top, bottom, left, right;
Matthias Clasen's avatar
Matthias Clasen committed
594
  char *orientation = NULL, *freeme = NULL;
595
  gboolean retval = FALSE;
Matthias Clasen's avatar
Matthias Clasen committed
596
597
  GError *err = NULL;

598
599
  g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), FALSE);
  g_return_val_if_fail (key_file != NULL, FALSE);
Matthias Clasen's avatar
Matthias Clasen committed
600
601
602
603
604
605

  if (!group_name)
    group_name = KEYFILE_GROUP_NAME;

  if (!g_key_file_has_group (key_file, group_name))
    {
606
607
608
609
      g_set_error_literal (error,
                           GTK_PRINT_ERROR,
                           GTK_PRINT_ERROR_INVALID_FILE,
                           _("Not a valid page setup file"));
Matthias Clasen's avatar
Matthias Clasen committed
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
      goto out;
    }

#define GET_DOUBLE(kf, group, name, v) \
  v = g_key_file_get_double (kf, group, name, &err); \
  if (err != NULL) \
    { \
      g_propagate_error (error, err);\
      goto out;\
    }

  GET_DOUBLE (key_file, group_name, "MarginTop", top);
  GET_DOUBLE (key_file, group_name, "MarginBottom", bottom);
  GET_DOUBLE (key_file, group_name, "MarginLeft", left);
  GET_DOUBLE (key_file, group_name, "MarginRight", right);

#undef GET_DOUBLE

  paper_size = gtk_paper_size_new_from_key_file (key_file, group_name, &err);
  if (!paper_size)
    {
      g_propagate_error (error, err);
      goto out;
    }

635
  gtk_page_setup_set_paper_size (setup, paper_size);
Matthias Clasen's avatar
Matthias Clasen committed
636
637
  gtk_paper_size_free (paper_size);

638
639
640
641
  gtk_page_setup_set_top_margin (setup, top, GTK_UNIT_MM);
  gtk_page_setup_set_bottom_margin (setup, bottom, GTK_UNIT_MM);
  gtk_page_setup_set_left_margin (setup, left, GTK_UNIT_MM);
  gtk_page_setup_set_right_margin (setup, right, GTK_UNIT_MM);
Matthias Clasen's avatar
Matthias Clasen committed
642
643
644
645
646

  orientation = g_key_file_get_string (key_file, group_name,
				       "Orientation", NULL);
  if (orientation)
    {
647
      gtk_page_setup_set_orientation (setup,
Matthias Clasen's avatar
Matthias Clasen committed
648
649
650
651
652
				      string_to_enum (GTK_TYPE_PAGE_ORIENTATION,
						      orientation));
      g_free (orientation);
    }

653
654
  retval = TRUE;

Matthias Clasen's avatar
Matthias Clasen committed
655
656
out:
  g_free (freeme);
657
658
659
660
661
  return retval;
}

/**
 * gtk_page_setup_new_from_key_file:
Matthias Clasen's avatar
Matthias Clasen committed
662
 * @key_file: the `GKeyFile` to retrieve the page_setup from
Matthias Clasen's avatar
Matthias Clasen committed
663
 * @group_name: (nullable): the name of the group in the key_file to read
Matthias Clasen's avatar
Matthias Clasen committed
664
 *    to use the default name “Page Setup”
Matthias Clasen's avatar
Matthias Clasen committed
665
 * @error: (nullable): return location for an error
666
667
 *
 * Reads the page setup from the group @group_name in the key file
Matthias Clasen's avatar
Matthias Clasen committed
668
669
670
 * @key_file.
 *
 * Returns a new `GtkPageSetup` object with the restored
671
672
 * page setup, or %NULL if an error occurred.
 *
Matthias Clasen's avatar
Matthias Clasen committed
673
 * Returns: the restored `GtkPageSetup`
674
675
676
 */
GtkPageSetup *
gtk_page_setup_new_from_key_file (GKeyFile     *key_file,
Benjamin Otte's avatar
Benjamin Otte committed
677
				  const char   *group_name,
678
679
680
681
682
683
684
685
686
				  GError      **error)
{
  GtkPageSetup *setup = gtk_page_setup_new ();

  if (!gtk_page_setup_load_key_file (setup, key_file, group_name, error))
    {
      g_object_unref (setup);
      setup = NULL;
    }
Matthias Clasen's avatar
Matthias Clasen committed
687

688
  return setup;
Matthias Clasen's avatar
Matthias Clasen committed
689
690
691
692
}

/**
 * gtk_page_setup_to_file:
Matthias Clasen's avatar
Matthias Clasen committed
693
 * @setup: a `GtkPageSetup`
694
 * @file_name: (type filename): the file to save to
Matthias Clasen's avatar
Matthias Clasen committed
695
 * @error: (nullable): return location for errors
Matthias Clasen's avatar
Matthias Clasen committed
696
 *
Matthias Clasen's avatar
Matthias Clasen committed
697
 * This function saves the information from @setup to @file_name.
Matthias Clasen's avatar
Matthias Clasen committed
698
 *
699
 * Returns: %TRUE on success
Matthias Clasen's avatar
Matthias Clasen committed
700
701
 */
gboolean
Matthias Clasen's avatar
Matthias Clasen committed
702
gtk_page_setup_to_file (GtkPageSetup  *setup,
Matthias Clasen's avatar
Matthias Clasen committed
703
704
705
706
707
708
709
710
		        const char    *file_name,
			GError       **error)
{
  GKeyFile *key_file;
  gboolean retval = FALSE;
  char *data = NULL;
  gsize len;

Matthias Clasen's avatar
Matthias Clasen committed
711
  g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), FALSE);
Matthias Clasen's avatar
Matthias Clasen committed
712
713
714
  g_return_val_if_fail (file_name != NULL, FALSE);

  key_file = g_key_file_new ();
Matthias Clasen's avatar
Matthias Clasen committed
715
  gtk_page_setup_to_key_file (setup, key_file, NULL);
Matthias Clasen's avatar
Matthias Clasen committed
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751

  data = g_key_file_to_data (key_file, &len, error);
  if (!data)
    goto out;

  retval = g_file_set_contents (file_name, data, len, error);

out:
  g_key_file_free (key_file);
  g_free (data);

  return retval;
}

/* something like this should really be in gobject! */
static char *
enum_to_string (GType type,
                guint enum_value)
{
  GEnumClass *enum_class;
  GEnumValue *value;
  char *retval = NULL;

  enum_class = g_type_class_ref (type);

  value = g_enum_get_value (enum_class, enum_value);
  if (value)
    retval = g_strdup (value->value_nick);

  g_type_class_unref (enum_class);

  return retval;
}

/**
 * gtk_page_setup_to_key_file:
Matthias Clasen's avatar
Matthias Clasen committed
752
753
 * @setup: a `GtkPageSetup`
 * @key_file: the `GKeyFile` to save the page setup to
754
 * @group_name: (nullable): the group to add the settings to in @key_file,
Matthias Clasen's avatar
Matthias Clasen committed
755
 *   or %NULL to use the default name “Page Setup”
Matthias Clasen's avatar
Matthias Clasen committed
756
 *
Matthias Clasen's avatar
Matthias Clasen committed
757
 * This function adds the page setup from @setup to @key_file.
Matthias Clasen's avatar
Matthias Clasen committed
758
759
 */
void
Matthias Clasen's avatar
Matthias Clasen committed
760
gtk_page_setup_to_key_file (GtkPageSetup *setup,
Matthias Clasen's avatar
Matthias Clasen committed
761
			    GKeyFile     *key_file,
Benjamin Otte's avatar
Benjamin Otte committed
762
			    const char   *group_name)
Matthias Clasen's avatar
Matthias Clasen committed
763
764
765
766
{
  GtkPaperSize *paper_size;
  char *orientation;

Matthias Clasen's avatar
Matthias Clasen committed
767
  g_return_if_fail (GTK_IS_PAGE_SETUP (setup));
Matthias Clasen's avatar
Matthias Clasen committed
768
769
770
771
772
  g_return_if_fail (key_file != NULL);

  if (!group_name)
    group_name = KEYFILE_GROUP_NAME;

Matthias Clasen's avatar
Matthias Clasen committed
773
  paper_size = gtk_page_setup_get_paper_size (setup);
Matthias Clasen's avatar
Matthias Clasen committed
774
775
776
777
778
  g_assert (paper_size != NULL);

  gtk_paper_size_to_key_file (paper_size, key_file, group_name);

  g_key_file_set_double (key_file, group_name,
Matthias Clasen's avatar
Matthias Clasen committed
779
			 "MarginTop", gtk_page_setup_get_top_margin (setup, GTK_UNIT_MM));
Matthias Clasen's avatar
Matthias Clasen committed
780
  g_key_file_set_double (key_file, group_name,
Matthias Clasen's avatar
Matthias Clasen committed
781
			 "MarginBottom", gtk_page_setup_get_bottom_margin (setup, GTK_UNIT_MM));
Matthias Clasen's avatar
Matthias Clasen committed
782
  g_key_file_set_double (key_file, group_name,
Matthias Clasen's avatar
Matthias Clasen committed
783
			 "MarginLeft", gtk_page_setup_get_left_margin (setup, GTK_UNIT_MM));
Matthias Clasen's avatar
Matthias Clasen committed
784
  g_key_file_set_double (key_file, group_name,
Matthias Clasen's avatar
Matthias Clasen committed
785
			 "MarginRight", gtk_page_setup_get_right_margin (setup, GTK_UNIT_MM));
Matthias Clasen's avatar
Matthias Clasen committed
786
787

  orientation = enum_to_string (GTK_TYPE_PAGE_ORIENTATION,
Matthias Clasen's avatar
Matthias Clasen committed
788
				gtk_page_setup_get_orientation (setup));
Matthias Clasen's avatar
Matthias Clasen committed
789
790
791
792
  g_key_file_set_string (key_file, group_name,
			 "Orientation", orientation);
  g_free (orientation);
}
793
794
795

/**
 * gtk_page_setup_to_gvariant:
Matthias Clasen's avatar
Matthias Clasen committed
796
 * @setup: a `GtkPageSetup`
797
798
799
 *
 * Serialize page setup to an a{sv} variant.
 *
Matthias Clasen's avatar
Matthias Clasen committed
800
 * Return: (transfer none): a new, floating, `GVariant`
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
 */
GVariant *
gtk_page_setup_to_gvariant (GtkPageSetup *setup)
{
  GtkPaperSize *paper_size;
  GVariant *variant;
  int i;
  GVariantBuilder builder;
  char *orientation;

  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);

  paper_size = gtk_page_setup_get_paper_size (setup);

  variant = g_variant_ref_sink (gtk_paper_size_to_gvariant (paper_size));
  for (i = 0; i < g_variant_n_children (variant); i++)
    g_variant_builder_add_value (&builder, g_variant_get_child_value (variant, i));
  g_variant_unref (variant);

  g_variant_builder_add (&builder, "{sv}", "MarginTop", g_variant_new_double (gtk_page_setup_get_top_margin (setup, GTK_UNIT_MM)));
  g_variant_builder_add (&builder, "{sv}", "MarginBottom", g_variant_new_double (gtk_page_setup_get_bottom_margin (setup, GTK_UNIT_MM)));
  g_variant_builder_add (&builder, "{sv}", "MarginLeft", g_variant_new_double (gtk_page_setup_get_left_margin (setup, GTK_UNIT_MM)));
  g_variant_builder_add (&builder, "{sv}", "MarginRight", g_variant_new_double (gtk_page_setup_get_right_margin (setup, GTK_UNIT_MM)));

  orientation = enum_to_string (GTK_TYPE_PAGE_ORIENTATION,
                                gtk_page_setup_get_orientation (setup));
  g_variant_builder_add (&builder, "{sv}", "Orientation", g_variant_new_take_string (orientation));

  return g_variant_builder_end (&builder);
}

/**
 * gtk_page_setup_new_from_gvariant:
Matthias Clasen's avatar
Matthias Clasen committed
834
835
836
 * @variant: an a{sv} `GVariant`
 *
 * Desrialize a page setup from an a{sv} variant.
837
 *
Matthias Clasen's avatar
Matthias Clasen committed
838
839
 * The variant must be in the format produced by
 * [method@Gtk.PageSetup.to_gvariant].
840
 *
Matthias Clasen's avatar
Matthias Clasen committed
841
 * Returns: (transfer full): a new `GtkPageSetup` object
842
843
844
845
846
847
 */
GtkPageSetup *
gtk_page_setup_new_from_gvariant (GVariant *variant)
{
  GtkPageSetup *setup;
  const char *orientation;
848
  double margin;
849
850
851
852
853
854
855
  GtkPaperSize *paper_size;

  g_return_val_if_fail (g_variant_is_of_type (variant, G_VARIANT_TYPE_VARDICT), NULL);

  setup = gtk_page_setup_new ();

  paper_size = gtk_paper_size_new_from_gvariant (variant);
856
857
858
859
860
  if (paper_size)
    {
      gtk_page_setup_set_paper_size (setup, paper_size);
      gtk_paper_size_free (paper_size);
    }
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876

  if (g_variant_lookup (variant, "MarginTop", "d", &margin))
    gtk_page_setup_set_top_margin (setup, margin, GTK_UNIT_MM);
  if (g_variant_lookup (variant, "MarginBottom", "d", &margin))
    gtk_page_setup_set_bottom_margin (setup, margin, GTK_UNIT_MM);
  if (g_variant_lookup (variant, "MarginLeft", "d", &margin))
    gtk_page_setup_set_left_margin (setup, margin, GTK_UNIT_MM);
  if (g_variant_lookup (variant, "MarginRight", "d", &margin))
    gtk_page_setup_set_right_margin (setup, margin, GTK_UNIT_MM);

  if (g_variant_lookup (variant, "Orientation", "&s", &orientation))
    gtk_page_setup_set_orientation (setup, string_to_enum (GTK_TYPE_PAGE_ORIENTATION,
                                                           orientation));

  return setup;
}