/* * camel-settings.c * * 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. * * 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 License * along with this library. If not, see . * */ #include "camel-settings.h" #include /* Needed for CamelSettings <--> CamelURL conversions. */ #include "camel-local-settings.h" #include "camel-network-settings.h" G_DEFINE_TYPE (CamelSettings, camel_settings, G_TYPE_OBJECT) static GParamSpec ** settings_list_settings (CamelSettingsClass *class, guint *n_settings) { GObjectClass *object_class = G_OBJECT_CLASS (class); return g_object_class_list_properties (object_class, n_settings); } static CamelSettings * settings_clone (CamelSettings *settings) { CamelSettingsClass *class; GParamSpec **properties; GParameter *parameters; CamelSettings *clone; guint ii, n_properties; class = CAMEL_SETTINGS_GET_CLASS (settings); properties = camel_settings_class_list_settings (class, &n_properties); parameters = g_new0 (GParameter, n_properties); for (ii = 0; ii < n_properties; ii++) { parameters[ii].name = properties[ii]->name; g_value_init ( ¶meters[ii].value, properties[ii]->value_type); g_object_get_property ( G_OBJECT (settings), parameters[ii].name, ¶meters[ii].value); } clone = g_object_newv ( G_OBJECT_TYPE (settings), n_properties, parameters); for (ii = 0; ii < n_properties; ii++) g_value_unset (¶meters[ii].value); g_free (parameters); g_free (properties); return clone; } static gboolean settings_equal (CamelSettings *settings_a, CamelSettings *settings_b) { CamelSettingsClass *class; GParamSpec **properties; GValue *value_a; GValue *value_b; guint ii, n_properties; gboolean equal = TRUE; /* Make sure both instances are of the same type. */ if (G_OBJECT_TYPE (settings_a) != G_OBJECT_TYPE (settings_b)) return FALSE; value_a = g_slice_new0 (GValue); value_b = g_slice_new0 (GValue); class = CAMEL_SETTINGS_GET_CLASS (settings_a); properties = camel_settings_class_list_settings (class, &n_properties); for (ii = 0; equal && ii < n_properties; ii++) { GParamSpec *pspec = properties[ii]; g_value_init (value_a, pspec->value_type); g_value_init (value_b, pspec->value_type); g_object_get_property ( G_OBJECT (settings_a), pspec->name, value_a); g_object_get_property ( G_OBJECT (settings_b), pspec->name, value_b); equal = (g_param_values_cmp (pspec, value_a, value_b) == 0); g_value_unset (value_a); g_value_unset (value_b); } g_free (properties); g_slice_free (GValue, value_a); g_slice_free (GValue, value_b); return equal; } static void camel_settings_class_init (CamelSettingsClass *class) { class->list_settings = settings_list_settings; class->clone = settings_clone; class->equal = settings_equal; } static void camel_settings_init (CamelSettings *settings) { } /** * camel_settings_class_list_settings: * @settings_class: a #CamelSettingsClass * @n_settings: return location for the length of the returned array * * Returns an array of #GParamSpec for properties of @class which are * considered to be settings. By default all properties are considered * to be settings, but subclasses may wish to exclude certain properties. * Free the returned array with g_free(). * * Returns: an array of #GParamSpec which should be freed after use * * Since: 3.2 **/ GParamSpec ** camel_settings_class_list_settings (CamelSettingsClass *settings_class, guint *n_settings) { g_return_val_if_fail (CAMEL_IS_SETTINGS_CLASS (settings_class), NULL); g_return_val_if_fail (settings_class->list_settings != NULL, NULL); return settings_class->list_settings (settings_class, n_settings); } /** * camel_settings_clone: * @settings: a #CamelSettings * * Creates an copy of @settings, such that passing @settings and the * copied instance to camel_settings_equal() would return %TRUE. * * By default, this creates a new settings instance with the same #GType * as @settings, and copies all #GObject property values from @settings * to the new instance. * * Returns: a newly-created copy of @settings * * Since: 3.2 **/ CamelSettings * camel_settings_clone (CamelSettings *settings) { CamelSettingsClass *class; CamelSettings *clone; g_return_val_if_fail (CAMEL_IS_SETTINGS (settings), NULL); class = CAMEL_SETTINGS_GET_CLASS (settings); g_return_val_if_fail (class->clone != NULL, NULL); clone = class->clone (settings); /* Make sure the documented invariant is satisfied. */ g_warn_if_fail (camel_settings_equal (settings, clone)); return clone; } /** * camel_settings_equal: * @settings_a: a #CamelSettings * @settings_b: another #CamelSettings * * Returns %TRUE if @settings_a and @settings_b are equal. * * By default, equality requires both instances to have the same #GType * with the same set of #GObject properties, and each property value in * @settings_a is equal to the corresponding value in @settings_b. * * Returns: %TRUE if @settings_a and @settings_b are equal * * Since: 3.2 **/ gboolean camel_settings_equal (CamelSettings *settings_a, CamelSettings *settings_b) { CamelSettingsClass *class; g_return_val_if_fail (CAMEL_IS_SETTINGS (settings_a), FALSE); g_return_val_if_fail (CAMEL_IS_SETTINGS (settings_b), FALSE); class = CAMEL_SETTINGS_GET_CLASS (settings_a); g_return_val_if_fail (class->equal != NULL, FALSE); return class->equal (settings_a, settings_b); }