+ return _gtk_print_convert_from_mm (height, unit);
+}
+
+/**
+ * gtk_page_setup_load_file:
+ * @setup: a #GtkPageSetup
+ * @file_name: (type filename): the filename to read the page setup from
+ * @error: (allow-none): return location for an error, or %NULL
+ *
+ * Reads the page setup from the file @file_name.
+ * See gtk_page_setup_to_file().
+ *
+ * Return value: %TRUE on success
+ *
+ * Since: 2.14
+ */
+gboolean
+gtk_page_setup_load_file (GtkPageSetup *setup,
+ const gchar *file_name,
+ 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;
+}
+
+/**
+ * gtk_page_setup_new_from_file:
+ * @file_name: (type filename): the filename to read the page setup from
+ * @error: (allow-none): return location for an error, or %NULL
+ *
+ * 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 gtk_page_setup_to_file().
+ *
+ * Return value: the restored #GtkPageSetup
+ *
+ * Since: 2.12
+ */
+GtkPageSetup *
+gtk_page_setup_new_from_file (const gchar *file_name,
+ GError **error)
+{
+ GtkPageSetup *setup = gtk_page_setup_new ();
+
+ if (!gtk_page_setup_load_file (setup, file_name, error))
+ {
+ g_object_unref (setup);
+ setup = NULL;
+ }
+
+ return setup;
+}
+
+/* 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;
+}
+
+/**
+ * gtk_page_setup_load_key_file:
+ * @setup: a #GtkPageSetup
+ * @key_file: the #GKeyFile to retrieve the page_setup from
+ * @group_name: (allow-none): the name of the group in the key_file to read, or %NULL
+ * to use the default name "Page Setup"
+ * @error: (allow-none): return location for an error, or %NULL
+ *
+ * Reads the page setup from the group @group_name in the key file
+ * @key_file.
+ *
+ * Return value: %TRUE on success
+ *
+ * Since: 2.14
+ */
+gboolean
+gtk_page_setup_load_key_file (GtkPageSetup *setup,
+ GKeyFile *key_file,
+ const gchar *group_name,
+ GError **error)
+{
+ GtkPaperSize *paper_size;
+ gdouble top, bottom, left, right;
+ char *orientation = NULL, *freeme = NULL;
+ gboolean retval = FALSE;
+ GError *err = NULL;
+
+ g_return_val_if_fail (GTK_IS_PAGE_SETUP (setup), FALSE);
+ g_return_val_if_fail (key_file != NULL, FALSE);
+
+ if (!group_name)
+ group_name = KEYFILE_GROUP_NAME;
+
+ if (!g_key_file_has_group (key_file, group_name))
+ {
+ g_set_error_literal (error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_INVALID_FILE,
+ _("Not a valid page setup file"));
+ 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;
+ }
+
+ gtk_page_setup_set_paper_size (setup, paper_size);
+ gtk_paper_size_free (paper_size);
+
+ 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);
+
+ orientation = g_key_file_get_string (key_file, group_name,
+ "Orientation", NULL);
+ if (orientation)
+ {
+ gtk_page_setup_set_orientation (setup,
+ string_to_enum (GTK_TYPE_PAGE_ORIENTATION,
+ orientation));
+ g_free (orientation);
+ }
+
+ retval = TRUE;
+
+out:
+ g_free (freeme);
+ return retval;
+}
+
+/**
+ * gtk_page_setup_new_from_key_file:
+ * @key_file: the #GKeyFile to retrieve the page_setup from
+ * @group_name: (allow-none): the name of the group in the key_file to read, or %NULL
+ * to use the default name "Page Setup"
+ * @error: (allow-none): return location for an error, or %NULL
+ *
+ * Reads the page setup from the group @group_name in the key file
+ * @key_file. Returns a new #GtkPageSetup object with the restored
+ * page setup, or %NULL if an error occurred.
+ *
+ * Return value: the restored #GtkPageSetup
+ *
+ * Since: 2.12
+ */
+GtkPageSetup *
+gtk_page_setup_new_from_key_file (GKeyFile *key_file,
+ const gchar *group_name,
+ 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;
+ }
+
+ return setup;